diff options
author | Hans de Goede <hdegoede@redhat.com> | 2013-10-24 18:15:50 +0100 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2013-11-26 09:21:17 +0100 |
commit | d4bfc7b9f35da7dcc28ae87de503b28bd7ff56ee (patch) | |
tree | 7620210b19b7ccfb44517074046b44507c64c515 /hw/usb | |
parent | 9ec557bd53031fb50cc0cd426a2d529624d3d515 (diff) | |
download | qemu-d4bfc7b9f35da7dcc28ae87de503b28bd7ff56ee.tar.gz qemu-d4bfc7b9f35da7dcc28ae87de503b28bd7ff56ee.tar.bz2 qemu-d4bfc7b9f35da7dcc28ae87de503b28bd7ff56ee.zip |
uas: Only use report iu-s for task_mgmt status reporting
Regular scsi cmds should always report their status using a sense-iu, using
the sense code to report any errors.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'hw/usb')
-rw-r--r-- | hw/usb/dev-uas.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c index 70ed2d1dbd..36a75b2f49 100644 --- a/hw/usb/dev-uas.c +++ b/hw/usb/dev-uas.c @@ -420,6 +420,24 @@ static void usb_uas_queue_sense(UASRequest *req, uint8_t status) usb_uas_queue_status(req->uas, st, len); } +static void usb_uas_queue_fake_sense(UASDevice *uas, uint16_t tag, + struct SCSISense sense) +{ + UASStatus *st = usb_uas_alloc_status(uas, UAS_UI_SENSE, tag); + int len, slen = 0; + + st->status.sense.status = CHECK_CONDITION; + st->status.sense.status_qualifier = cpu_to_be16(0); + st->status.sense.sense_data[0] = 0x70; + st->status.sense.sense_data[2] = sense.key; + st->status.sense.sense_data[7] = 10; + st->status.sense.sense_data[12] = sense.asc; + st->status.sense.sense_data[13] = sense.ascq; + slen = 18; + len = sizeof(uas_ui_sense) - sizeof(st->status.sense.sense_data) + slen; + usb_uas_queue_status(uas, st, len); +} + static void usb_uas_queue_read_ready(UASRequest *req) { UASStatus *st = usb_uas_alloc_status(req->uas, UAS_UI_READ_READY, @@ -672,8 +690,9 @@ static void usb_uas_command(UASDevice *uas, uas_ui *ui) { UASRequest *req; uint32_t len; + uint16_t tag = be16_to_cpu(ui->hdr.tag); - req = usb_uas_find_request(uas, be16_to_cpu(ui->hdr.tag)); + req = usb_uas_find_request(uas, tag); if (req) { goto overlapped_tag; } @@ -706,16 +725,11 @@ static void usb_uas_command(UASDevice *uas, uas_ui *ui) return; overlapped_tag: - usb_uas_queue_response(uas, req->tag, UAS_RC_OVERLAPPED_TAG, 0); + usb_uas_queue_fake_sense(uas, tag, sense_code_OVERLAPPED_COMMANDS); return; bad_target: - /* - * FIXME: Seems to upset linux, is this wrong? - * NOTE: Happens only with no scsi devices at the bus, not sure - * this is a valid UAS setup in the first place. - */ - usb_uas_queue_response(uas, req->tag, UAS_RC_INVALID_INFO_UNIT, 0); + usb_uas_queue_fake_sense(uas, tag, sense_code_LUN_NOT_SUPPORTED); g_free(req); } |