2 * UAS (USB Attached SCSI) emulation
4 * Copyright Red Hat, Inc. 2012
6 * Author: Gerd Hoffmann <kraxel@redhat.com>
8 * This work is licensed under the terms of the GNU GPL, version 2 or later.
9 * See the COPYING file in the top-level directory.
12 #include "qemu-common.h"
13 #include "qemu/option.h"
14 #include "qemu/config-file.h"
18 #include "hw/usb/desc.h"
19 #include "hw/scsi/scsi.h"
20 #include "block/scsi.h"
22 /* --------------------------------------------------------------------- */
24 #define UAS_UI_COMMAND 0x01
25 #define UAS_UI_SENSE 0x03
26 #define UAS_UI_RESPONSE 0x04
27 #define UAS_UI_TASK_MGMT 0x05
28 #define UAS_UI_READ_READY 0x06
29 #define UAS_UI_WRITE_READY 0x07
31 #define UAS_RC_TMF_COMPLETE 0x00
32 #define UAS_RC_INVALID_INFO_UNIT 0x02
33 #define UAS_RC_TMF_NOT_SUPPORTED 0x04
34 #define UAS_RC_TMF_FAILED 0x05
35 #define UAS_RC_TMF_SUCCEEDED 0x08
36 #define UAS_RC_INCORRECT_LUN 0x09
37 #define UAS_RC_OVERLAPPED_TAG 0x0a
39 #define UAS_TMF_ABORT_TASK 0x01
40 #define UAS_TMF_ABORT_TASK_SET 0x02
41 #define UAS_TMF_CLEAR_TASK_SET 0x04
42 #define UAS_TMF_LOGICAL_UNIT_RESET 0x08
43 #define UAS_TMF_I_T_NEXUS_RESET 0x10
44 #define UAS_TMF_CLEAR_ACA 0x40
45 #define UAS_TMF_QUERY_TASK 0x80
46 #define UAS_TMF_QUERY_TASK_SET 0x81
47 #define UAS_TMF_QUERY_ASYNC_EVENT 0x82
49 #define UAS_PIPE_ID_COMMAND 0x01
50 #define UAS_PIPE_ID_STATUS 0x02
51 #define UAS_PIPE_ID_DATA_IN 0x03
52 #define UAS_PIPE_ID_DATA_OUT 0x04
58 } QEMU_PACKED uas_ui_header
;
61 uint8_t prio_taskattr
; /* 6:3 priority, 2:0 task attribute */
63 uint8_t add_cdb_length
; /* 7:2 additional adb length (dwords) */
68 } QEMU_PACKED uas_ui_command
;
71 uint16_t status_qualifier
;
74 uint16_t sense_length
;
75 uint8_t sense_data
[18];
76 } QEMU_PACKED uas_ui_sense
;
79 uint16_t add_response_info
;
80 uint8_t response_code
;
81 } QEMU_PACKED uas_ui_response
;
88 } QEMU_PACKED uas_ui_task_mgmt
;
93 uas_ui_command command
;
95 uas_ui_task_mgmt task
;
96 uas_ui_response response
;
100 /* --------------------------------------------------------------------- */
102 #define UAS_STREAM_BM_ATTR 4
103 #define UAS_MAX_STREAMS (1 << UAS_STREAM_BM_ATTR)
105 typedef struct UASDevice UASDevice
;
106 typedef struct UASRequest UASRequest
;
107 typedef struct UASStatus UASStatus
;
113 QTAILQ_HEAD(, UASStatus
) results
;
114 QTAILQ_HEAD(, UASRequest
) requests
;
122 UASRequest
*dataout2
;
125 USBPacket
*data3
[UAS_MAX_STREAMS
];
126 USBPacket
*status3
[UAS_MAX_STREAMS
];
143 QTAILQ_ENTRY(UASRequest
) next
;
150 QTAILQ_ENTRY(UASStatus
) next
;
153 /* --------------------------------------------------------------------- */
156 STR_MANUFACTURER
= 1,
163 static const USBDescStrings desc_strings
= {
164 [STR_MANUFACTURER
] = "QEMU",
165 [STR_PRODUCT
] = "USB Attached SCSI HBA",
166 [STR_SERIALNUMBER
] = "27842",
167 [STR_CONFIG_HIGH
] = "High speed config (usb 2.0)",
168 [STR_CONFIG_SUPER
] = "Super speed config (usb 3.0)",
171 static const USBDescIface desc_iface_high
= {
172 .bInterfaceNumber
= 0,
174 .bInterfaceClass
= USB_CLASS_MASS_STORAGE
,
175 .bInterfaceSubClass
= 0x06, /* SCSI */
176 .bInterfaceProtocol
= 0x62, /* UAS */
177 .eps
= (USBDescEndpoint
[]) {
179 .bEndpointAddress
= USB_DIR_OUT
| UAS_PIPE_ID_COMMAND
,
180 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
181 .wMaxPacketSize
= 512,
182 .extra
= (uint8_t[]) {
183 0x04, /* u8 bLength */
184 0x24, /* u8 bDescriptorType */
186 0x00, /* u8 bReserved */
189 .bEndpointAddress
= USB_DIR_IN
| UAS_PIPE_ID_STATUS
,
190 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
191 .wMaxPacketSize
= 512,
192 .extra
= (uint8_t[]) {
193 0x04, /* u8 bLength */
194 0x24, /* u8 bDescriptorType */
196 0x00, /* u8 bReserved */
199 .bEndpointAddress
= USB_DIR_IN
| UAS_PIPE_ID_DATA_IN
,
200 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
201 .wMaxPacketSize
= 512,
202 .extra
= (uint8_t[]) {
203 0x04, /* u8 bLength */
204 0x24, /* u8 bDescriptorType */
206 0x00, /* u8 bReserved */
209 .bEndpointAddress
= USB_DIR_OUT
| UAS_PIPE_ID_DATA_OUT
,
210 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
211 .wMaxPacketSize
= 512,
212 .extra
= (uint8_t[]) {
213 0x04, /* u8 bLength */
214 0x24, /* u8 bDescriptorType */
215 UAS_PIPE_ID_DATA_OUT
,
216 0x00, /* u8 bReserved */
222 static const USBDescIface desc_iface_super
= {
223 .bInterfaceNumber
= 0,
225 .bInterfaceClass
= USB_CLASS_MASS_STORAGE
,
226 .bInterfaceSubClass
= 0x06, /* SCSI */
227 .bInterfaceProtocol
= 0x62, /* UAS */
228 .eps
= (USBDescEndpoint
[]) {
230 .bEndpointAddress
= USB_DIR_OUT
| UAS_PIPE_ID_COMMAND
,
231 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
232 .wMaxPacketSize
= 1024,
234 .extra
= (uint8_t[]) {
235 0x04, /* u8 bLength */
236 0x24, /* u8 bDescriptorType */
238 0x00, /* u8 bReserved */
241 .bEndpointAddress
= USB_DIR_IN
| UAS_PIPE_ID_STATUS
,
242 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
243 .wMaxPacketSize
= 1024,
245 .bmAttributes_super
= UAS_STREAM_BM_ATTR
,
246 .extra
= (uint8_t[]) {
247 0x04, /* u8 bLength */
248 0x24, /* u8 bDescriptorType */
250 0x00, /* u8 bReserved */
253 .bEndpointAddress
= USB_DIR_IN
| UAS_PIPE_ID_DATA_IN
,
254 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
255 .wMaxPacketSize
= 1024,
257 .bmAttributes_super
= UAS_STREAM_BM_ATTR
,
258 .extra
= (uint8_t[]) {
259 0x04, /* u8 bLength */
260 0x24, /* u8 bDescriptorType */
262 0x00, /* u8 bReserved */
265 .bEndpointAddress
= USB_DIR_OUT
| UAS_PIPE_ID_DATA_OUT
,
266 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
267 .wMaxPacketSize
= 1024,
269 .bmAttributes_super
= UAS_STREAM_BM_ATTR
,
270 .extra
= (uint8_t[]) {
271 0x04, /* u8 bLength */
272 0x24, /* u8 bDescriptorType */
273 UAS_PIPE_ID_DATA_OUT
,
274 0x00, /* u8 bReserved */
280 static const USBDescDevice desc_device_high
= {
282 .bMaxPacketSize0
= 64,
283 .bNumConfigurations
= 1,
284 .confs
= (USBDescConfig
[]) {
287 .bConfigurationValue
= 1,
288 .iConfiguration
= STR_CONFIG_HIGH
,
289 .bmAttributes
= 0xc0,
291 .ifs
= &desc_iface_high
,
296 static const USBDescDevice desc_device_super
= {
298 .bMaxPacketSize0
= 64,
299 .bNumConfigurations
= 1,
300 .confs
= (USBDescConfig
[]) {
303 .bConfigurationValue
= 1,
304 .iConfiguration
= STR_CONFIG_SUPER
,
305 .bmAttributes
= 0xc0,
307 .ifs
= &desc_iface_super
,
312 static const USBDesc desc
= {
314 .idVendor
= 0x46f4, /* CRC16() of "QEMU" */
317 .iManufacturer
= STR_MANUFACTURER
,
318 .iProduct
= STR_PRODUCT
,
319 .iSerialNumber
= STR_SERIALNUMBER
,
321 .high
= &desc_device_high
,
322 .super
= &desc_device_super
,
326 /* --------------------------------------------------------------------- */
328 static bool uas_using_streams(UASDevice
*uas
)
330 return uas
->dev
.speed
== USB_SPEED_SUPER
;
333 /* --------------------------------------------------------------------- */
335 static UASStatus
*usb_uas_alloc_status(UASDevice
*uas
, uint8_t id
, uint16_t tag
)
337 UASStatus
*st
= g_new0(UASStatus
, 1);
339 st
->status
.hdr
.id
= id
;
340 st
->status
.hdr
.tag
= cpu_to_be16(tag
);
341 st
->length
= sizeof(uas_ui_header
);
342 if (uas_using_streams(uas
)) {
348 static void usb_uas_send_status_bh(void *opaque
)
350 UASDevice
*uas
= opaque
;
354 while ((st
= QTAILQ_FIRST(&uas
->results
)) != NULL
) {
355 if (uas_using_streams(uas
)) {
356 p
= uas
->status3
[st
->stream
];
357 uas
->status3
[st
->stream
] = NULL
;
366 usb_packet_copy(p
, &st
->status
, st
->length
);
367 QTAILQ_REMOVE(&uas
->results
, st
, next
);
370 p
->status
= USB_RET_SUCCESS
; /* Clear previous ASYNC status */
371 usb_packet_complete(&uas
->dev
, p
);
375 static void usb_uas_queue_status(UASDevice
*uas
, UASStatus
*st
, int length
)
377 USBPacket
*p
= uas_using_streams(uas
) ?
378 uas
->status3
[st
->stream
] : uas
->status2
;
380 st
->length
+= length
;
381 QTAILQ_INSERT_TAIL(&uas
->results
, st
, next
);
384 * Just schedule bh make sure any in-flight data transaction
385 * is finished before completing (sending) the status packet.
387 qemu_bh_schedule(uas
->status_bh
);
389 USBEndpoint
*ep
= usb_ep_get(&uas
->dev
, USB_TOKEN_IN
,
391 usb_wakeup(ep
, st
->stream
);
395 static void usb_uas_queue_response(UASDevice
*uas
, uint16_t tag
,
396 uint8_t code
, uint16_t add_info
)
398 UASStatus
*st
= usb_uas_alloc_status(uas
, UAS_UI_RESPONSE
, tag
);
400 trace_usb_uas_response(uas
->dev
.addr
, tag
, code
);
401 st
->status
.response
.response_code
= code
;
402 st
->status
.response
.add_response_info
= cpu_to_be16(add_info
);
403 usb_uas_queue_status(uas
, st
, sizeof(uas_ui_response
));
406 static void usb_uas_queue_sense(UASRequest
*req
, uint8_t status
)
408 UASStatus
*st
= usb_uas_alloc_status(req
->uas
, UAS_UI_SENSE
, req
->tag
);
411 trace_usb_uas_sense(req
->uas
->dev
.addr
, req
->tag
, status
);
412 st
->status
.sense
.status
= status
;
413 st
->status
.sense
.status_qualifier
= cpu_to_be16(0);
414 if (status
!= GOOD
) {
415 slen
= scsi_req_get_sense(req
->req
, st
->status
.sense
.sense_data
,
416 sizeof(st
->status
.sense
.sense_data
));
417 st
->status
.sense
.sense_length
= cpu_to_be16(slen
);
419 len
= sizeof(uas_ui_sense
) - sizeof(st
->status
.sense
.sense_data
) + slen
;
420 usb_uas_queue_status(req
->uas
, st
, len
);
423 static void usb_uas_queue_read_ready(UASRequest
*req
)
425 UASStatus
*st
= usb_uas_alloc_status(req
->uas
, UAS_UI_READ_READY
,
428 trace_usb_uas_read_ready(req
->uas
->dev
.addr
, req
->tag
);
429 usb_uas_queue_status(req
->uas
, st
, 0);
432 static void usb_uas_queue_write_ready(UASRequest
*req
)
434 UASStatus
*st
= usb_uas_alloc_status(req
->uas
, UAS_UI_WRITE_READY
,
437 trace_usb_uas_write_ready(req
->uas
->dev
.addr
, req
->tag
);
438 usb_uas_queue_status(req
->uas
, st
, 0);
441 /* --------------------------------------------------------------------- */
443 static int usb_uas_get_lun(uint64_t lun64
)
445 return (lun64
>> 48) & 0xff;
448 static SCSIDevice
*usb_uas_get_dev(UASDevice
*uas
, uint64_t lun64
)
450 if ((lun64
>> 56) != 0x00) {
453 return scsi_device_find(&uas
->bus
, 0, 0, usb_uas_get_lun(lun64
));
456 static void usb_uas_complete_data_packet(UASRequest
*req
)
460 if (!req
->data_async
) {
465 req
->data_async
= false;
466 p
->status
= USB_RET_SUCCESS
; /* Clear previous ASYNC status */
467 usb_packet_complete(&req
->uas
->dev
, p
);
470 static void usb_uas_copy_data(UASRequest
*req
)
474 length
= MIN(req
->buf_size
- req
->buf_off
,
475 req
->data
->iov
.size
- req
->data
->actual_length
);
476 trace_usb_uas_xfer_data(req
->uas
->dev
.addr
, req
->tag
, length
,
477 req
->data
->actual_length
, req
->data
->iov
.size
,
478 req
->buf_off
, req
->buf_size
);
479 usb_packet_copy(req
->data
, scsi_req_get_buf(req
->req
) + req
->buf_off
,
481 req
->buf_off
+= length
;
482 req
->data_off
+= length
;
484 if (req
->data
->actual_length
== req
->data
->iov
.size
) {
485 usb_uas_complete_data_packet(req
);
487 if (req
->buf_size
&& req
->buf_off
== req
->buf_size
) {
490 scsi_req_continue(req
->req
);
494 static void usb_uas_start_next_transfer(UASDevice
*uas
)
498 if (uas_using_streams(uas
)) {
502 QTAILQ_FOREACH(req
, &uas
->requests
, next
) {
503 if (req
->active
|| req
->complete
) {
506 if (req
->req
->cmd
.mode
== SCSI_XFER_FROM_DEV
&& uas
->datain2
== NULL
) {
508 usb_uas_queue_read_ready(req
);
512 if (req
->req
->cmd
.mode
== SCSI_XFER_TO_DEV
&& uas
->dataout2
== NULL
) {
514 usb_uas_queue_write_ready(req
);
521 static UASRequest
*usb_uas_alloc_request(UASDevice
*uas
, uas_ui
*ui
)
525 req
= g_new0(UASRequest
, 1);
527 req
->tag
= be16_to_cpu(ui
->hdr
.tag
);
528 req
->lun
= be64_to_cpu(ui
->command
.lun
);
529 req
->dev
= usb_uas_get_dev(req
->uas
, req
->lun
);
533 static void usb_uas_scsi_free_request(SCSIBus
*bus
, void *priv
)
535 UASRequest
*req
= priv
;
536 UASDevice
*uas
= req
->uas
;
538 if (req
== uas
->datain2
) {
541 if (req
== uas
->dataout2
) {
542 uas
->dataout2
= NULL
;
544 QTAILQ_REMOVE(&uas
->requests
, req
, next
);
546 usb_uas_start_next_transfer(uas
);
549 static UASRequest
*usb_uas_find_request(UASDevice
*uas
, uint16_t tag
)
553 QTAILQ_FOREACH(req
, &uas
->requests
, next
) {
554 if (req
->tag
== tag
) {
561 static void usb_uas_scsi_transfer_data(SCSIRequest
*r
, uint32_t len
)
563 UASRequest
*req
= r
->hba_private
;
565 trace_usb_uas_scsi_data(req
->uas
->dev
.addr
, req
->tag
, len
);
569 usb_uas_copy_data(req
);
571 usb_uas_start_next_transfer(req
->uas
);
575 static void usb_uas_scsi_command_complete(SCSIRequest
*r
,
576 uint32_t status
, size_t resid
)
578 UASRequest
*req
= r
->hba_private
;
580 trace_usb_uas_scsi_complete(req
->uas
->dev
.addr
, req
->tag
, status
, resid
);
581 req
->complete
= true;
583 usb_uas_complete_data_packet(req
);
585 usb_uas_queue_sense(req
, status
);
586 scsi_req_unref(req
->req
);
589 static void usb_uas_scsi_request_cancelled(SCSIRequest
*r
)
591 UASRequest
*req
= r
->hba_private
;
593 /* FIXME: queue notification to status pipe? */
594 scsi_req_unref(req
->req
);
597 static const struct SCSIBusInfo usb_uas_scsi_info
= {
602 .transfer_data
= usb_uas_scsi_transfer_data
,
603 .complete
= usb_uas_scsi_command_complete
,
604 .cancel
= usb_uas_scsi_request_cancelled
,
605 .free_request
= usb_uas_scsi_free_request
,
608 /* --------------------------------------------------------------------- */
610 static void usb_uas_handle_reset(USBDevice
*dev
)
612 UASDevice
*uas
= DO_UPCAST(UASDevice
, dev
, dev
);
613 UASRequest
*req
, *nreq
;
616 trace_usb_uas_reset(dev
->addr
);
617 QTAILQ_FOREACH_SAFE(req
, &uas
->requests
, next
, nreq
) {
618 scsi_req_cancel(req
->req
);
620 QTAILQ_FOREACH_SAFE(st
, &uas
->results
, next
, nst
) {
621 QTAILQ_REMOVE(&uas
->results
, st
, next
);
626 static void usb_uas_handle_control(USBDevice
*dev
, USBPacket
*p
,
627 int request
, int value
, int index
, int length
, uint8_t *data
)
631 ret
= usb_desc_handle_control(dev
, p
, request
, value
, index
, length
, data
);
635 fprintf(stderr
, "%s: unhandled control request\n", __func__
);
636 p
->status
= USB_RET_STALL
;
639 static void usb_uas_cancel_io(USBDevice
*dev
, USBPacket
*p
)
641 UASDevice
*uas
= DO_UPCAST(UASDevice
, dev
, dev
);
642 UASRequest
*req
, *nreq
;
645 if (uas
->status2
== p
) {
647 qemu_bh_cancel(uas
->status_bh
);
650 if (uas_using_streams(uas
)) {
651 for (i
= 0; i
< UAS_MAX_STREAMS
; i
++) {
652 if (uas
->status3
[i
] == p
) {
653 uas
->status3
[i
] = NULL
;
656 if (uas
->data3
[i
] == p
) {
657 uas
->data3
[i
] = NULL
;
662 QTAILQ_FOREACH_SAFE(req
, &uas
->requests
, next
, nreq
) {
663 if (req
->data
== p
) {
668 assert(!"canceled usb packet not found");
671 static void usb_uas_command(UASDevice
*uas
, uas_ui
*ui
)
676 req
= usb_uas_find_request(uas
, be16_to_cpu(ui
->hdr
.tag
));
680 req
= usb_uas_alloc_request(uas
, ui
);
681 if (req
->dev
== NULL
) {
685 trace_usb_uas_command(uas
->dev
.addr
, req
->tag
,
686 usb_uas_get_lun(req
->lun
),
687 req
->lun
>> 32, req
->lun
& 0xffffffff);
688 QTAILQ_INSERT_TAIL(&uas
->requests
, req
, next
);
689 if (uas_using_streams(uas
) && uas
->data3
[req
->tag
] != NULL
) {
690 req
->data
= uas
->data3
[req
->tag
];
691 req
->data_async
= true;
692 uas
->data3
[req
->tag
] = NULL
;
695 req
->req
= scsi_req_new(req
->dev
, req
->tag
,
696 usb_uas_get_lun(req
->lun
),
697 ui
->command
.cdb
, req
);
698 if (uas
->requestlog
) {
699 scsi_req_print(req
->req
);
701 len
= scsi_req_enqueue(req
->req
);
703 req
->data_size
= len
;
704 scsi_req_continue(req
->req
);
709 usb_uas_queue_response(uas
, req
->tag
, UAS_RC_OVERLAPPED_TAG
, 0);
714 * FIXME: Seems to upset linux, is this wrong?
715 * NOTE: Happens only with no scsi devices at the bus, not sure
716 * this is a valid UAS setup in the first place.
718 usb_uas_queue_response(uas
, req
->tag
, UAS_RC_INVALID_INFO_UNIT
, 0);
722 static void usb_uas_task(UASDevice
*uas
, uas_ui
*ui
)
724 uint16_t tag
= be16_to_cpu(ui
->hdr
.tag
);
725 uint64_t lun64
= be64_to_cpu(ui
->task
.lun
);
726 SCSIDevice
*dev
= usb_uas_get_dev(uas
, lun64
);
727 int lun
= usb_uas_get_lun(lun64
);
731 req
= usb_uas_find_request(uas
, be16_to_cpu(ui
->hdr
.tag
));
736 switch (ui
->task
.function
) {
737 case UAS_TMF_ABORT_TASK
:
738 task_tag
= be16_to_cpu(ui
->task
.task_tag
);
739 trace_usb_uas_tmf_abort_task(uas
->dev
.addr
, tag
, task_tag
);
743 if (dev
->lun
!= lun
) {
746 req
= usb_uas_find_request(uas
, task_tag
);
747 if (req
&& req
->dev
== dev
) {
748 scsi_req_cancel(req
->req
);
750 usb_uas_queue_response(uas
, tag
, UAS_RC_TMF_COMPLETE
, 0);
753 case UAS_TMF_LOGICAL_UNIT_RESET
:
754 trace_usb_uas_tmf_logical_unit_reset(uas
->dev
.addr
, tag
, lun
);
758 if (dev
->lun
!= lun
) {
761 qdev_reset_all(&dev
->qdev
);
762 usb_uas_queue_response(uas
, tag
, UAS_RC_TMF_COMPLETE
, 0);
766 trace_usb_uas_tmf_unsupported(uas
->dev
.addr
, tag
, ui
->task
.function
);
767 usb_uas_queue_response(uas
, tag
, UAS_RC_TMF_NOT_SUPPORTED
, 0);
773 usb_uas_queue_response(uas
, req
->tag
, UAS_RC_OVERLAPPED_TAG
, 0);
777 /* FIXME: correct? [see long comment in usb_uas_command()] */
778 usb_uas_queue_response(uas
, tag
, UAS_RC_INVALID_INFO_UNIT
, 0);
782 usb_uas_queue_response(uas
, tag
, UAS_RC_INCORRECT_LUN
, 0);
785 static void usb_uas_handle_data(USBDevice
*dev
, USBPacket
*p
)
787 UASDevice
*uas
= DO_UPCAST(UASDevice
, dev
, dev
);
794 case UAS_PIPE_ID_COMMAND
:
795 length
= MIN(sizeof(ui
), p
->iov
.size
);
796 usb_packet_copy(p
, &ui
, length
);
799 usb_uas_command(uas
, &ui
);
801 case UAS_UI_TASK_MGMT
:
802 usb_uas_task(uas
, &ui
);
805 fprintf(stderr
, "%s: unknown command ui: id 0x%x\n",
806 __func__
, ui
.hdr
.id
);
807 p
->status
= USB_RET_STALL
;
811 case UAS_PIPE_ID_STATUS
:
813 QTAILQ_FOREACH(st
, &uas
->results
, next
) {
814 if (st
->stream
== p
->stream
) {
819 assert(uas
->status3
[p
->stream
] == NULL
);
820 uas
->status3
[p
->stream
] = p
;
821 p
->status
= USB_RET_ASYNC
;
825 st
= QTAILQ_FIRST(&uas
->results
);
827 assert(uas
->status2
== NULL
);
829 p
->status
= USB_RET_ASYNC
;
833 usb_packet_copy(p
, &st
->status
, st
->length
);
834 QTAILQ_REMOVE(&uas
->results
, st
, next
);
837 case UAS_PIPE_ID_DATA_IN
:
838 case UAS_PIPE_ID_DATA_OUT
:
840 req
= usb_uas_find_request(uas
, p
->stream
);
842 req
= (p
->ep
->nr
== UAS_PIPE_ID_DATA_IN
)
843 ? uas
->datain2
: uas
->dataout2
;
847 assert(uas
->data3
[p
->stream
] == NULL
);
848 uas
->data3
[p
->stream
] = p
;
849 p
->status
= USB_RET_ASYNC
;
852 fprintf(stderr
, "%s: no inflight request\n", __func__
);
853 p
->status
= USB_RET_STALL
;
857 scsi_req_ref(req
->req
);
859 usb_uas_copy_data(req
);
860 if (p
->actual_length
== p
->iov
.size
|| req
->complete
) {
863 req
->data_async
= true;
864 p
->status
= USB_RET_ASYNC
;
866 scsi_req_unref(req
->req
);
867 usb_uas_start_next_transfer(uas
);
870 fprintf(stderr
, "%s: invalid endpoint %d\n", __func__
, p
->ep
->nr
);
871 p
->status
= USB_RET_STALL
;
876 static void usb_uas_handle_destroy(USBDevice
*dev
)
878 UASDevice
*uas
= DO_UPCAST(UASDevice
, dev
, dev
);
880 qemu_bh_delete(uas
->status_bh
);
883 static int usb_uas_init(USBDevice
*dev
)
885 UASDevice
*uas
= DO_UPCAST(UASDevice
, dev
, dev
);
887 usb_desc_create_serial(dev
);
890 QTAILQ_INIT(&uas
->results
);
891 QTAILQ_INIT(&uas
->requests
);
892 uas
->status_bh
= qemu_bh_new(usb_uas_send_status_bh
, uas
);
894 scsi_bus_new(&uas
->bus
, sizeof(uas
->bus
), DEVICE(dev
),
895 &usb_uas_scsi_info
, NULL
);
900 static const VMStateDescription vmstate_usb_uas
= {
903 .fields
= (VMStateField
[]) {
904 VMSTATE_USB_DEVICE(dev
, UASDevice
),
905 VMSTATE_END_OF_LIST()
909 static Property uas_properties
[] = {
910 DEFINE_PROP_UINT32("log-scsi-req", UASDevice
, requestlog
, 0),
911 DEFINE_PROP_END_OF_LIST(),
914 static void usb_uas_class_initfn(ObjectClass
*klass
, void *data
)
916 DeviceClass
*dc
= DEVICE_CLASS(klass
);
917 USBDeviceClass
*uc
= USB_DEVICE_CLASS(klass
);
919 uc
->init
= usb_uas_init
;
920 uc
->product_desc
= desc_strings
[STR_PRODUCT
];
921 uc
->usb_desc
= &desc
;
922 uc
->cancel_packet
= usb_uas_cancel_io
;
923 uc
->handle_attach
= usb_desc_attach
;
924 uc
->handle_reset
= usb_uas_handle_reset
;
925 uc
->handle_control
= usb_uas_handle_control
;
926 uc
->handle_data
= usb_uas_handle_data
;
927 uc
->handle_destroy
= usb_uas_handle_destroy
;
928 set_bit(DEVICE_CATEGORY_STORAGE
, dc
->categories
);
929 dc
->fw_name
= "storage";
930 dc
->vmsd
= &vmstate_usb_uas
;
931 dc
->props
= uas_properties
;
934 static const TypeInfo uas_info
= {
936 .parent
= TYPE_USB_DEVICE
,
937 .instance_size
= sizeof(UASDevice
),
938 .class_init
= usb_uas_class_initfn
,
941 static void usb_uas_register_types(void)
943 type_register_static(&uas_info
);
946 type_init(usb_uas_register_types
)