Revision c6df7102 hw/usb-msd.c
b/hw/usb-msd.c | ||
---|---|---|
208 | 208 |
memcpy(p->data, &csw, len); |
209 | 209 |
} |
210 | 210 |
|
211 |
static void usb_msd_command_complete(SCSIRequest *req, int reason, uint32_t arg)
|
|
211 |
static void usb_msd_transfer_data(SCSIRequest *req, uint32_t arg)
|
|
212 | 212 |
{ |
213 | 213 |
MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); |
214 | 214 |
USBPacket *p = s->packet; |
... | ... | |
216 | 216 |
if (req->tag != s->tag) { |
217 | 217 |
fprintf(stderr, "usb-msd: Unexpected SCSI Tag 0x%x\n", req->tag); |
218 | 218 |
} |
219 |
if (reason == SCSI_REASON_DONE) { |
|
220 |
DPRINTF("Command complete %d\n", arg); |
|
221 |
s->residue = s->data_len; |
|
222 |
s->result = arg != 0; |
|
223 |
if (s->packet) { |
|
224 |
if (s->data_len == 0 && s->mode == USB_MSDM_DATAOUT) { |
|
225 |
/* A deferred packet with no write data remaining must be |
|
226 |
the status read packet. */ |
|
227 |
usb_msd_send_status(s, p); |
|
228 |
s->mode = USB_MSDM_CBW; |
|
229 |
} else { |
|
230 |
if (s->data_len) { |
|
231 |
s->data_len -= s->usb_len; |
|
232 |
if (s->mode == USB_MSDM_DATAIN) |
|
233 |
memset(s->usb_buf, 0, s->usb_len); |
|
234 |
s->usb_len = 0; |
|
235 |
} |
|
236 |
if (s->data_len == 0) |
|
237 |
s->mode = USB_MSDM_CSW; |
|
238 |
} |
|
239 |
s->packet = NULL; |
|
240 |
usb_packet_complete(&s->dev, p); |
|
241 |
} else if (s->data_len == 0) { |
|
242 |
s->mode = USB_MSDM_CSW; |
|
243 |
} |
|
244 |
scsi_req_unref(req); |
|
245 |
s->req = NULL; |
|
246 |
return; |
|
247 |
} |
|
219 |
|
|
248 | 220 |
assert((s->mode == USB_MSDM_DATAOUT) == (req->cmd.mode == SCSI_XFER_TO_DEV)); |
249 | 221 |
s->scsi_len = arg; |
250 | 222 |
s->scsi_buf = scsi_req_get_buf(req); |
... | ... | |
261 | 233 |
} |
262 | 234 |
} |
263 | 235 |
|
236 |
static void usb_msd_command_complete(SCSIRequest *req, uint32_t arg) |
|
237 |
{ |
|
238 |
MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); |
|
239 |
USBPacket *p = s->packet; |
|
240 |
|
|
241 |
if (req->tag != s->tag) { |
|
242 |
fprintf(stderr, "usb-msd: Unexpected SCSI Tag 0x%x\n", req->tag); |
|
243 |
} |
|
244 |
DPRINTF("Command complete %d\n", arg); |
|
245 |
s->residue = s->data_len; |
|
246 |
s->result = arg != 0; |
|
247 |
if (s->packet) { |
|
248 |
if (s->data_len == 0 && s->mode == USB_MSDM_DATAOUT) { |
|
249 |
/* A deferred packet with no write data remaining must be |
|
250 |
the status read packet. */ |
|
251 |
usb_msd_send_status(s, p); |
|
252 |
s->mode = USB_MSDM_CBW; |
|
253 |
} else { |
|
254 |
if (s->data_len) { |
|
255 |
s->data_len -= s->usb_len; |
|
256 |
if (s->mode == USB_MSDM_DATAIN) { |
|
257 |
memset(s->usb_buf, 0, s->usb_len); |
|
258 |
} |
|
259 |
s->usb_len = 0; |
|
260 |
} |
|
261 |
if (s->data_len == 0) { |
|
262 |
s->mode = USB_MSDM_CSW; |
|
263 |
} |
|
264 |
} |
|
265 |
s->packet = NULL; |
|
266 |
usb_packet_complete(&s->dev, p); |
|
267 |
} else if (s->data_len == 0) { |
|
268 |
s->mode = USB_MSDM_CSW; |
|
269 |
} |
|
270 |
scsi_req_unref(req); |
|
271 |
s->req = NULL; |
|
272 |
} |
|
273 |
|
|
264 | 274 |
static void usb_msd_request_cancelled(SCSIRequest *req) |
265 | 275 |
{ |
266 | 276 |
MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); |
... | ... | |
494 | 504 |
} |
495 | 505 |
|
496 | 506 |
static const struct SCSIBusOps usb_msd_scsi_ops = { |
507 |
.transfer_data = usb_msd_transfer_data, |
|
497 | 508 |
.complete = usb_msd_command_complete, |
498 | 509 |
.cancel = usb_msd_request_cancelled |
499 | 510 |
}; |
Also available in: Unified diff