From 13a9a0d3e253e272744b523e39642c9b6d564f4d Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 16 Dec 2010 17:03:44 +0100 Subject: usb: move complete callback to port ops --- hw/usb-msd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'hw/usb-msd.c') diff --git a/hw/usb-msd.c b/hw/usb-msd.c index 947fd3f..93f4b78 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -241,7 +241,7 @@ static void usb_msd_command_complete(SCSIBus *bus, int reason, uint32_t tag, s->mode = USB_MSDM_CSW; } s->packet = NULL; - usb_packet_complete(p); + usb_packet_complete(&s->dev, p); } else if (s->data_len == 0) { s->mode = USB_MSDM_CSW; } @@ -257,7 +257,7 @@ static void usb_msd_command_complete(SCSIBus *bus, int reason, uint32_t tag, usb_packet_complete returns. */ DPRINTF("Packet complete %p\n", p); s->packet = NULL; - usb_packet_complete(p); + usb_packet_complete(&s->dev, p); } } } -- cgit v1.1 From ef0bdf77d7070494692cbccd80c4c8f08c85c240 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 4 May 2011 16:49:56 +0200 Subject: usb: mass storage fix Initialize scsi_len with zero when starting a new request, so any stuff leftover from the previous request is cleared out. This may happen in case the data returned by the scsi command doesn't fit into the buffer provided by the guest. Signed-off-by: Gerd Hoffmann --- hw/usb-msd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'hw/usb-msd.c') diff --git a/hw/usb-msd.c b/hw/usb-msd.c index 93f4b78..bd1c3a4 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -364,6 +364,7 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) DPRINTF("Command tag 0x%x flags %08x len %d data %d\n", s->tag, cbw.flags, cbw.cmd_len, s->data_len); s->residue = 0; + s->scsi_len = 0; s->scsi_dev->info->send_command(s->scsi_dev, s->tag, cbw.cmd, 0); /* ??? Should check that USB and SCSI data transfer directions match. */ -- cgit v1.1 From add750882f327db813af0795727efe5e4579ca5c Mon Sep 17 00:00:00 2001 From: Brad Hards Date: Sun, 3 Apr 2011 15:33:19 +1000 Subject: usb: update config descriptors to identify number of interfaces Previously we relied on the .bNumInterfaces, but that won't always be accurate after the introduction of grouped interfaces. Signed-off-by: Brad Hards Signed-off-by: Gerd Hoffmann --- hw/usb-msd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'hw/usb-msd.c') diff --git a/hw/usb-msd.c b/hw/usb-msd.c index bd1c3a4..040ea7a 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -119,6 +119,7 @@ static const USBDescDevice desc_device_full = { .bConfigurationValue = 1, .iConfiguration = STR_CONFIG_FULL, .bmAttributes = 0xc0, + .nif = 1, .ifs = &desc_iface_full, }, }, @@ -153,6 +154,7 @@ static const USBDescDevice desc_device_high = { .bConfigurationValue = 1, .iConfiguration = STR_CONFIG_HIGH, .bmAttributes = 0xc0, + .nif = 1, .ifs = &desc_iface_high, }, }, -- cgit v1.1 From 007fd62f4d3959f2a61abe61a34a54c9f99560b0 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 2 Feb 2011 16:33:13 +0100 Subject: usb: Pass the packet to the device's handle_control callback This allows using the generic usb_generic_handle_packet function from device code which does ASYNC control requests (such as the linux host pass through code). Signed-off-by: Hans de Goede --- hw/usb-msd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'hw/usb-msd.c') diff --git a/hw/usb-msd.c b/hw/usb-msd.c index 040ea7a..c3a197a 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -272,13 +272,13 @@ static void usb_msd_handle_reset(USBDevice *dev) s->mode = USB_MSDM_CBW; } -static int usb_msd_handle_control(USBDevice *dev, int request, int value, - int index, int length, uint8_t *data) +static int usb_msd_handle_control(USBDevice *dev, USBPacket *p, + int request, int value, int index, int length, uint8_t *data) { MSDState *s = (MSDState *)dev; int ret; - ret = usb_desc_handle_control(dev, request, value, index, length, data); + ret = usb_desc_handle_control(dev, p, request, value, index, length, data); if (ret >= 0) { return ret; } -- cgit v1.1 From ebd669a19f00d0ff8370e1edfb6232f50e42110d Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Mon, 16 May 2011 14:25:59 +0200 Subject: usb-storage: don't call usb_packet_complete twice usb_msd_copy_data() may cause a recursive call to usb_msd_command_complete() which in turn may complete the packet, setting s->packet to NULL in case it does. Recheck s->packet before calling usb_packet_complete() to fix the double call. Signed-off-by: Gerd Hoffmann --- hw/usb-msd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hw/usb-msd.c') diff --git a/hw/usb-msd.c b/hw/usb-msd.c index c3a197a..1064920 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -253,7 +253,7 @@ static void usb_msd_command_complete(SCSIBus *bus, int reason, uint32_t tag, s->scsi_buf = s->scsi_dev->info->get_buf(s->scsi_dev, tag); if (p) { usb_msd_copy_data(s); - if (s->usb_len == 0) { + if (s->packet && s->usb_len == 0) { /* Set s->packet to NULL before calling usb_packet_complete because another request may be issued before usb_packet_complete returns. */ -- cgit v1.1 From eb5e680ae5a72b999946e5618c501648367734a8 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Mon, 16 May 2011 10:34:53 +0200 Subject: usb: move cancel callback to USBDeviceInfo Remove the cancel callback from the USBPacket struct, move it over to USBDeviceInfo. Zap usb_defer_packet() which is obsolete now. Signed-off-by: Gerd Hoffmann --- hw/usb-msd.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'hw/usb-msd.c') diff --git a/hw/usb-msd.c b/hw/usb-msd.c index 1064920..141da2c 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -315,9 +315,9 @@ static int usb_msd_handle_control(USBDevice *dev, USBPacket *p, return ret; } -static void usb_msd_cancel_io(USBPacket *p, void *opaque) +static void usb_msd_cancel_io(USBDevice *dev, USBPacket *p) { - MSDState *s = opaque; + MSDState *s = DO_UPCAST(MSDState, dev, dev); s->scsi_dev->info->cancel_io(s->scsi_dev, s->tag); s->packet = NULL; s->scsi_len = 0; @@ -398,7 +398,6 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) } if (s->usb_len) { DPRINTF("Deferring packet %p\n", p); - usb_defer_packet(p, usb_msd_cancel_io, s); s->packet = p; ret = USB_RET_ASYNC; } else { @@ -421,7 +420,6 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) if (s->data_len != 0 || len < 13) goto fail; /* Waiting for SCSI write to complete. */ - usb_defer_packet(p, usb_msd_cancel_io, s); s->packet = p; ret = USB_RET_ASYNC; break; @@ -455,7 +453,6 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) } if (s->usb_len) { DPRINTF("Deferring packet %p\n", p); - usb_defer_packet(p, usb_msd_cancel_io, s); s->packet = p; ret = USB_RET_ASYNC; } else { @@ -604,6 +601,7 @@ static struct USBDeviceInfo msd_info = { .usb_desc = &desc, .init = usb_msd_initfn, .handle_packet = usb_generic_handle_packet, + .cancel_packet = usb_msd_cancel_io, .handle_attach = usb_desc_attach, .handle_reset = usb_msd_handle_reset, .handle_control = usb_msd_handle_control, -- cgit v1.1 From cfdc1bb06ee4cd3a7e4aa0ebf14b00c0ce3a5e94 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 18 Apr 2011 17:11:14 +0200 Subject: scsi: introduce SCSIBusOps There are more operations than a SCSI bus can handle, besides completing commands. One example, which this series will introduce, is cleaning up after a request is cancelled. More long term, a "SCSI bus" can represent the LUNs attached to a target; in this case, while all commands will ultimately reach a logical unit, it is the target who is in charge of answering REPORT LUNs. Signed-off-by: Paolo Bonzini Cc: Christoph Hellwig --- hw/usb-msd.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'hw/usb-msd.c') diff --git a/hw/usb-msd.c b/hw/usb-msd.c index bd1c3a4..c0a381a 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -487,6 +487,10 @@ static void usb_msd_password_cb(void *opaque, int err) qdev_unplug(&s->dev.qdev); } +static const struct SCSIBusOps usb_msd_scsi_ops = { + .complete = usb_msd_command_complete +}; + static int usb_msd_initfn(USBDevice *dev) { MSDState *s = DO_UPCAST(MSDState, dev, dev); @@ -516,7 +520,7 @@ static int usb_msd_initfn(USBDevice *dev) } usb_desc_init(dev); - scsi_bus_new(&s->bus, &s->dev.qdev, 0, 1, usb_msd_command_complete); + scsi_bus_new(&s->bus, &s->dev.qdev, 0, 1, &usb_msd_scsi_ops); s->scsi_dev = scsi_bus_legacy_add_drive(&s->bus, bs, 0, !!s->removable); if (!s->scsi_dev) { return -1; -- cgit v1.1 From 5c6c0e513600ba57c3e73b7151d3c0664438f7b5 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 18 Apr 2011 12:35:39 +0200 Subject: scsi: Use 'SCSIRequest' directly Currently the SCSIRequest structure is abstracted away and cannot accessed directly from the driver. This requires the handler to do a lookup on an abstract 'tag' which identifies the SCSIRequest structure. With this patch the SCSIRequest structure is exposed to the driver. This allows use to use it directly as an argument to the SCSIDeviceInfo callback functions and remove the lookup. A new callback function 'alloc_req' is introduced matching 'free req'; unref'ing to free up resources after use is moved into the scsi_command_complete callbacks. This temporarily introduces a leak of requests that are cancelled, when they are removed from the queue and not from the driver. This is fixed later by introducing scsi_req_cancel. That patch in turn depends on this one, because the argument to scsi_req_cancel is a SCSIRequest. Signed-off-by: Hannes Reinecke Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/usb-msd.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'hw/usb-msd.c') diff --git a/hw/usb-msd.c b/hw/usb-msd.c index c0a381a..8e6d48b 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -48,6 +48,7 @@ typedef struct { uint32_t data_len; uint32_t residue; uint32_t tag; + SCSIRequest *req; SCSIBus bus; BlockConf conf; SCSIDevice *scsi_dev; @@ -190,9 +191,9 @@ static void usb_msd_copy_data(MSDState *s) s->data_len -= len; if (s->scsi_len == 0 || s->data_len == 0) { if (s->mode == USB_MSDM_DATAIN) { - s->scsi_dev->info->read_data(s->scsi_dev, s->tag); + s->scsi_dev->info->read_data(s->req); } else if (s->mode == USB_MSDM_DATAOUT) { - s->scsi_dev->info->write_data(s->scsi_dev, s->tag); + s->scsi_dev->info->write_data(s->req); } } } @@ -211,14 +212,13 @@ static void usb_msd_send_status(MSDState *s, USBPacket *p) memcpy(p->data, &csw, len); } -static void usb_msd_command_complete(SCSIBus *bus, int reason, uint32_t tag, - uint32_t arg) +static void usb_msd_command_complete(SCSIRequest *req, int reason, uint32_t arg) { - MSDState *s = DO_UPCAST(MSDState, dev.qdev, bus->qbus.parent); + MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); USBPacket *p = s->packet; - if (tag != s->tag) { - fprintf(stderr, "usb-msd: Unexpected SCSI Tag 0x%x\n", tag); + if (req->tag != s->tag) { + fprintf(stderr, "usb-msd: Unexpected SCSI Tag 0x%x\n", req->tag); } if (reason == SCSI_REASON_DONE) { DPRINTF("Command complete %d\n", arg); @@ -245,10 +245,12 @@ static void usb_msd_command_complete(SCSIBus *bus, int reason, uint32_t tag, } else if (s->data_len == 0) { s->mode = USB_MSDM_CSW; } + scsi_req_unref(req); + s->req = NULL; return; } s->scsi_len = arg; - s->scsi_buf = s->scsi_dev->info->get_buf(s->scsi_dev, tag); + s->scsi_buf = s->scsi_dev->info->get_buf(req); if (p) { usb_msd_copy_data(s); if (s->usb_len == 0) { @@ -316,7 +318,7 @@ static int usb_msd_handle_control(USBDevice *dev, int request, int value, static void usb_msd_cancel_io(USBPacket *p, void *opaque) { MSDState *s = opaque; - s->scsi_dev->info->cancel_io(s->scsi_dev, s->tag); + s->scsi_dev->info->cancel_io(s->req); s->packet = NULL; s->scsi_len = 0; } @@ -365,14 +367,15 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) s->tag, cbw.flags, cbw.cmd_len, s->data_len); s->residue = 0; s->scsi_len = 0; - s->scsi_dev->info->send_command(s->scsi_dev, s->tag, cbw.cmd, 0); + s->req = s->scsi_dev->info->alloc_req(s->scsi_dev, s->tag, 0); + s->scsi_dev->info->send_command(s->req, cbw.cmd); /* ??? Should check that USB and SCSI data transfer directions match. */ if (s->residue == 0) { if (s->mode == USB_MSDM_DATAIN) { - s->scsi_dev->info->read_data(s->scsi_dev, s->tag); + s->scsi_dev->info->read_data(s->req); } else if (s->mode == USB_MSDM_DATAOUT) { - s->scsi_dev->info->write_data(s->scsi_dev, s->tag); + s->scsi_dev->info->write_data(s->req); } } ret = len; -- cgit v1.1 From 94d3f98a3f3caddd7875f9a11776daeb84962a7b Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 18 Apr 2011 22:53:08 +0200 Subject: scsi: introduce scsi_req_cancel This is for when the request must be dropped in the void, but still memory should be freed. To this end, the devices register a second callback in SCSIBusOps. Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/usb-msd.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'hw/usb-msd.c') diff --git a/hw/usb-msd.c b/hw/usb-msd.c index 8e6d48b..ce92682 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -264,6 +264,18 @@ static void usb_msd_command_complete(SCSIRequest *req, int reason, uint32_t arg) } } +static void usb_msd_request_cancelled(SCSIRequest *req) +{ + MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); + + if (req == s->req) { + scsi_req_unref(s->req); + s->req = NULL; + s->packet = NULL; + s->scsi_len = 0; + } +} + static void usb_msd_handle_reset(USBDevice *dev) { MSDState *s = (MSDState *)dev; @@ -318,9 +330,7 @@ static int usb_msd_handle_control(USBDevice *dev, int request, int value, static void usb_msd_cancel_io(USBPacket *p, void *opaque) { MSDState *s = opaque; - s->scsi_dev->info->cancel_io(s->req); - s->packet = NULL; - s->scsi_len = 0; + scsi_req_cancel(s->req); } static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) @@ -491,7 +501,8 @@ static void usb_msd_password_cb(void *opaque, int err) } static const struct SCSIBusOps usb_msd_scsi_ops = { - .complete = usb_msd_command_complete + .complete = usb_msd_command_complete, + .cancel = usb_msd_request_cancelled }; static int usb_msd_initfn(USBDevice *dev) -- cgit v1.1 From fc4f0754c775d4b5e0fb90e503f7e505f62fb8ed Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 18 Apr 2011 19:07:23 +0200 Subject: scsi: do not call send_command directly Move the common part of scsi-disk.c and scsi-generic.c to the SCSI layer. Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/usb-msd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hw/usb-msd.c') diff --git a/hw/usb-msd.c b/hw/usb-msd.c index ce92682..ccfae61 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -378,7 +378,7 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) s->residue = 0; s->scsi_len = 0; s->req = s->scsi_dev->info->alloc_req(s->scsi_dev, s->tag, 0); - s->scsi_dev->info->send_command(s->req, cbw.cmd); + scsi_req_enqueue(s->req, cbw.cmd); /* ??? Should check that USB and SCSI data transfer directions match. */ if (s->residue == 0) { -- cgit v1.1 From 43a2b33957697347e4e6d00557221538231bfe4d Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 18 Apr 2011 19:09:55 +0200 Subject: scsi: introduce scsi_req_new Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/usb-msd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hw/usb-msd.c') diff --git a/hw/usb-msd.c b/hw/usb-msd.c index ccfae61..efb15b0 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -377,7 +377,7 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) s->tag, cbw.flags, cbw.cmd_len, s->data_len); s->residue = 0; s->scsi_len = 0; - s->req = s->scsi_dev->info->alloc_req(s->scsi_dev, s->tag, 0); + s->req = scsi_req_new(s->scsi_dev, s->tag, 0); scsi_req_enqueue(s->req, cbw.cmd); /* ??? Should check that USB and SCSI data transfer directions match. */ -- cgit v1.1 From ad3376cc558f69606ac25ab6d597db71c969d8b6 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 18 Apr 2011 15:28:11 +0200 Subject: scsi: introduce scsi_req_continue Signed-off-by: Paolo Bonzini Cc: Christoph Hellwig --- hw/usb-msd.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'hw/usb-msd.c') diff --git a/hw/usb-msd.c b/hw/usb-msd.c index efb15b0..d4c2234 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -190,11 +190,7 @@ static void usb_msd_copy_data(MSDState *s) s->scsi_buf += len; s->data_len -= len; if (s->scsi_len == 0 || s->data_len == 0) { - if (s->mode == USB_MSDM_DATAIN) { - s->scsi_dev->info->read_data(s->req); - } else if (s->mode == USB_MSDM_DATAOUT) { - s->scsi_dev->info->write_data(s->req); - } + scsi_req_continue(s->req); } } @@ -249,6 +245,7 @@ static void usb_msd_command_complete(SCSIRequest *req, int reason, uint32_t arg) s->req = NULL; return; } + assert((s->mode == USB_MSDM_DATAOUT) == (req->cmd.mode == SCSI_XFER_TO_DEV)); s->scsi_len = arg; s->scsi_buf = s->scsi_dev->info->get_buf(req); if (p) { @@ -381,12 +378,8 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) scsi_req_enqueue(s->req, cbw.cmd); /* ??? Should check that USB and SCSI data transfer directions match. */ - if (s->residue == 0) { - if (s->mode == USB_MSDM_DATAIN) { - s->scsi_dev->info->read_data(s->req); - } else if (s->mode == USB_MSDM_DATAOUT) { - s->scsi_dev->info->write_data(s->req); - } + if (s->mode != USB_MSDM_CSW && s->residue == 0) { + scsi_req_continue(s->req); } ret = len; break; -- cgit v1.1 From 0c34459b6af1b7ed2f000995b9bcb1c722646fbb Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 21 Apr 2011 13:21:02 +0200 Subject: scsi: introduce scsi_req_get_buf ... and remove some SCSIDevice variables or fields that now become unused. Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/usb-msd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hw/usb-msd.c') diff --git a/hw/usb-msd.c b/hw/usb-msd.c index d4c2234..78b57a6 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -247,7 +247,7 @@ static void usb_msd_command_complete(SCSIRequest *req, int reason, uint32_t arg) } assert((s->mode == USB_MSDM_DATAOUT) == (req->cmd.mode == SCSI_XFER_TO_DEV)); s->scsi_len = arg; - s->scsi_buf = s->scsi_dev->info->get_buf(req); + s->scsi_buf = scsi_req_get_buf(req); if (p) { usb_msd_copy_data(s); if (s->usb_len == 0) { -- cgit v1.1 From c6df7102f5ebf3c9008718d044b78f1ae57aa627 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 22 Apr 2011 12:27:30 +0200 Subject: scsi: split command_complete callback in two Signed-off-by: Paolo Bonzini Cc: Christoph Hellwig --- hw/usb-msd.c | 71 +++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 30 deletions(-) (limited to 'hw/usb-msd.c') diff --git a/hw/usb-msd.c b/hw/usb-msd.c index 78b57a6..4ebf6eb 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -208,7 +208,7 @@ static void usb_msd_send_status(MSDState *s, USBPacket *p) memcpy(p->data, &csw, len); } -static void usb_msd_command_complete(SCSIRequest *req, int reason, uint32_t arg) +static void usb_msd_transfer_data(SCSIRequest *req, uint32_t arg) { MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); USBPacket *p = s->packet; @@ -216,35 +216,7 @@ static void usb_msd_command_complete(SCSIRequest *req, int reason, uint32_t arg) if (req->tag != s->tag) { fprintf(stderr, "usb-msd: Unexpected SCSI Tag 0x%x\n", req->tag); } - if (reason == SCSI_REASON_DONE) { - DPRINTF("Command complete %d\n", arg); - s->residue = s->data_len; - s->result = arg != 0; - if (s->packet) { - if (s->data_len == 0 && s->mode == USB_MSDM_DATAOUT) { - /* A deferred packet with no write data remaining must be - the status read packet. */ - usb_msd_send_status(s, p); - s->mode = USB_MSDM_CBW; - } else { - if (s->data_len) { - s->data_len -= s->usb_len; - if (s->mode == USB_MSDM_DATAIN) - memset(s->usb_buf, 0, s->usb_len); - s->usb_len = 0; - } - if (s->data_len == 0) - s->mode = USB_MSDM_CSW; - } - s->packet = NULL; - usb_packet_complete(&s->dev, p); - } else if (s->data_len == 0) { - s->mode = USB_MSDM_CSW; - } - scsi_req_unref(req); - s->req = NULL; - return; - } + assert((s->mode == USB_MSDM_DATAOUT) == (req->cmd.mode == SCSI_XFER_TO_DEV)); s->scsi_len = arg; s->scsi_buf = scsi_req_get_buf(req); @@ -261,6 +233,44 @@ static void usb_msd_command_complete(SCSIRequest *req, int reason, uint32_t arg) } } +static void usb_msd_command_complete(SCSIRequest *req, uint32_t arg) +{ + MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); + USBPacket *p = s->packet; + + if (req->tag != s->tag) { + fprintf(stderr, "usb-msd: Unexpected SCSI Tag 0x%x\n", req->tag); + } + DPRINTF("Command complete %d\n", arg); + s->residue = s->data_len; + s->result = arg != 0; + if (s->packet) { + if (s->data_len == 0 && s->mode == USB_MSDM_DATAOUT) { + /* A deferred packet with no write data remaining must be + the status read packet. */ + usb_msd_send_status(s, p); + s->mode = USB_MSDM_CBW; + } else { + if (s->data_len) { + s->data_len -= s->usb_len; + if (s->mode == USB_MSDM_DATAIN) { + memset(s->usb_buf, 0, s->usb_len); + } + s->usb_len = 0; + } + if (s->data_len == 0) { + s->mode = USB_MSDM_CSW; + } + } + s->packet = NULL; + usb_packet_complete(&s->dev, p); + } else if (s->data_len == 0) { + s->mode = USB_MSDM_CSW; + } + scsi_req_unref(req); + s->req = NULL; +} + static void usb_msd_request_cancelled(SCSIRequest *req) { MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); @@ -494,6 +504,7 @@ static void usb_msd_password_cb(void *opaque, int err) } static const struct SCSIBusOps usb_msd_scsi_ops = { + .transfer_data = usb_msd_transfer_data, .complete = usb_msd_command_complete, .cancel = usb_msd_request_cancelled }; -- cgit v1.1 From aba1f023630146bd7150dd13e8786d1c3e5b2afb Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 20 May 2011 20:18:07 +0200 Subject: scsi: rename arguments to the new callbacks Signed-off-by: Paolo Bonzini Cc: Christoph Hellwig --- hw/usb-msd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'hw/usb-msd.c') diff --git a/hw/usb-msd.c b/hw/usb-msd.c index 4ebf6eb..6ec2255 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -208,7 +208,7 @@ static void usb_msd_send_status(MSDState *s, USBPacket *p) memcpy(p->data, &csw, len); } -static void usb_msd_transfer_data(SCSIRequest *req, uint32_t arg) +static void usb_msd_transfer_data(SCSIRequest *req, uint32_t len) { MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); USBPacket *p = s->packet; @@ -218,7 +218,7 @@ static void usb_msd_transfer_data(SCSIRequest *req, uint32_t arg) } assert((s->mode == USB_MSDM_DATAOUT) == (req->cmd.mode == SCSI_XFER_TO_DEV)); - s->scsi_len = arg; + s->scsi_len = len; s->scsi_buf = scsi_req_get_buf(req); if (p) { usb_msd_copy_data(s); @@ -233,7 +233,7 @@ static void usb_msd_transfer_data(SCSIRequest *req, uint32_t arg) } } -static void usb_msd_command_complete(SCSIRequest *req, uint32_t arg) +static void usb_msd_command_complete(SCSIRequest *req, uint32_t status) { MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); USBPacket *p = s->packet; @@ -241,9 +241,9 @@ static void usb_msd_command_complete(SCSIRequest *req, uint32_t arg) if (req->tag != s->tag) { fprintf(stderr, "usb-msd: Unexpected SCSI Tag 0x%x\n", req->tag); } - DPRINTF("Command complete %d\n", arg); + DPRINTF("Command complete %d\n", status); s->residue = s->data_len; - s->result = arg != 0; + s->result = status != 0; if (s->packet) { if (s->data_len == 0 && s->mode == USB_MSDM_DATAOUT) { /* A deferred packet with no write data remaining must be -- cgit v1.1