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/osdep.h"
13 #include "qemu/option.h"
14 #include "qemu/config-file.h"
16 #include "qemu/error-report.h"
17 #include "qemu/main-loop.h"
18 #include "qemu/module.h"
22 #include "migration/vmstate.h"
24 #include "hw/qdev-properties.h"
25 #include "hw/scsi/scsi.h"
26 #include "scsi/constants.h"
27 #include "qom/object.h"
29 /* --------------------------------------------------------------------- */
31 #define UAS_UI_COMMAND 0x01
32 #define UAS_UI_SENSE 0x03
33 #define UAS_UI_RESPONSE 0x04
34 #define UAS_UI_TASK_MGMT 0x05
35 #define UAS_UI_READ_READY 0x06
36 #define UAS_UI_WRITE_READY 0x07
38 #define UAS_RC_TMF_COMPLETE 0x00
39 #define UAS_RC_INVALID_INFO_UNIT 0x02
40 #define UAS_RC_TMF_NOT_SUPPORTED 0x04
41 #define UAS_RC_TMF_FAILED 0x05
42 #define UAS_RC_TMF_SUCCEEDED 0x08
43 #define UAS_RC_INCORRECT_LUN 0x09
44 #define UAS_RC_OVERLAPPED_TAG 0x0a
46 #define UAS_TMF_ABORT_TASK 0x01
47 #define UAS_TMF_ABORT_TASK_SET 0x02
48 #define UAS_TMF_CLEAR_TASK_SET 0x04
49 #define UAS_TMF_LOGICAL_UNIT_RESET 0x08
50 #define UAS_TMF_I_T_NEXUS_RESET 0x10
51 #define UAS_TMF_CLEAR_ACA 0x40
52 #define UAS_TMF_QUERY_TASK 0x80
53 #define UAS_TMF_QUERY_TASK_SET 0x81
54 #define UAS_TMF_QUERY_ASYNC_EVENT 0x82
56 #define UAS_PIPE_ID_COMMAND 0x01
57 #define UAS_PIPE_ID_STATUS 0x02
58 #define UAS_PIPE_ID_DATA_IN 0x03
59 #define UAS_PIPE_ID_DATA_OUT 0x04
65 } QEMU_PACKED uas_iu_header
;
68 uint8_t prio_taskattr
; /* 6:3 priority, 2:0 task attribute */
70 uint8_t add_cdb_length
; /* 7:2 additional adb length (dwords) */
74 uint8_t add_cdb
[1]; /* not supported by QEMU */
75 } QEMU_PACKED uas_iu_command
;
78 uint16_t status_qualifier
;
81 uint16_t sense_length
;
82 uint8_t sense_data
[18];
83 } QEMU_PACKED uas_iu_sense
;
86 uint8_t add_response_info
[3];
87 uint8_t response_code
;
88 } QEMU_PACKED uas_iu_response
;
95 } QEMU_PACKED uas_iu_task_mgmt
;
100 uas_iu_command command
;
102 uas_iu_task_mgmt task
;
103 uas_iu_response response
;
105 } QEMU_PACKED uas_iu
;
107 /* --------------------------------------------------------------------- */
109 #define UAS_STREAM_BM_ATTR 4
110 #define UAS_MAX_STREAMS (1 << UAS_STREAM_BM_ATTR)
112 typedef struct UASDevice UASDevice
;
113 typedef struct UASRequest UASRequest
;
114 typedef struct UASStatus UASStatus
;
120 QTAILQ_HEAD(, UASStatus
) results
;
121 QTAILQ_HEAD(, UASRequest
) requests
;
129 UASRequest
*dataout2
;
132 USBPacket
*data3
[UAS_MAX_STREAMS
+ 1];
133 USBPacket
*status3
[UAS_MAX_STREAMS
+ 1];
136 #define TYPE_USB_UAS "usb-uas"
137 OBJECT_DECLARE_SIMPLE_TYPE(UASDevice
, USB_UAS
)
153 QTAILQ_ENTRY(UASRequest
) next
;
160 QTAILQ_ENTRY(UASStatus
) next
;
163 /* --------------------------------------------------------------------- */
166 STR_MANUFACTURER
= 1,
173 static const USBDescStrings desc_strings
= {
174 [STR_MANUFACTURER
] = "QEMU",
175 [STR_PRODUCT
] = "USB Attached SCSI HBA",
176 [STR_SERIALNUMBER
] = "27842",
177 [STR_CONFIG_HIGH
] = "High speed config (usb 2.0)",
178 [STR_CONFIG_SUPER
] = "Super speed config (usb 3.0)",
181 static const USBDescIface desc_iface_high
= {
182 .bInterfaceNumber
= 0,
184 .bInterfaceClass
= USB_CLASS_MASS_STORAGE
,
185 .bInterfaceSubClass
= 0x06, /* SCSI */
186 .bInterfaceProtocol
= 0x62, /* UAS */
187 .eps
= (USBDescEndpoint
[]) {
189 .bEndpointAddress
= USB_DIR_OUT
| UAS_PIPE_ID_COMMAND
,
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_STATUS
,
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_IN
| UAS_PIPE_ID_DATA_IN
,
210 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
211 .wMaxPacketSize
= 512,
212 .extra
= (uint8_t[]) {
213 0x04, /* u8 bLength */
214 0x24, /* u8 bDescriptorType */
216 0x00, /* u8 bReserved */
219 .bEndpointAddress
= USB_DIR_OUT
| UAS_PIPE_ID_DATA_OUT
,
220 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
221 .wMaxPacketSize
= 512,
222 .extra
= (uint8_t[]) {
223 0x04, /* u8 bLength */
224 0x24, /* u8 bDescriptorType */
225 UAS_PIPE_ID_DATA_OUT
,
226 0x00, /* u8 bReserved */
232 static const USBDescIface desc_iface_super
= {
233 .bInterfaceNumber
= 0,
235 .bInterfaceClass
= USB_CLASS_MASS_STORAGE
,
236 .bInterfaceSubClass
= 0x06, /* SCSI */
237 .bInterfaceProtocol
= 0x62, /* UAS */
238 .eps
= (USBDescEndpoint
[]) {
240 .bEndpointAddress
= USB_DIR_OUT
| UAS_PIPE_ID_COMMAND
,
241 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
242 .wMaxPacketSize
= 1024,
244 .extra
= (uint8_t[]) {
245 0x04, /* u8 bLength */
246 0x24, /* u8 bDescriptorType */
248 0x00, /* u8 bReserved */
251 .bEndpointAddress
= USB_DIR_IN
| UAS_PIPE_ID_STATUS
,
252 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
253 .wMaxPacketSize
= 1024,
255 .bmAttributes_super
= UAS_STREAM_BM_ATTR
,
256 .extra
= (uint8_t[]) {
257 0x04, /* u8 bLength */
258 0x24, /* u8 bDescriptorType */
260 0x00, /* u8 bReserved */
263 .bEndpointAddress
= USB_DIR_IN
| UAS_PIPE_ID_DATA_IN
,
264 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
265 .wMaxPacketSize
= 1024,
267 .bmAttributes_super
= UAS_STREAM_BM_ATTR
,
268 .extra
= (uint8_t[]) {
269 0x04, /* u8 bLength */
270 0x24, /* u8 bDescriptorType */
272 0x00, /* u8 bReserved */
275 .bEndpointAddress
= USB_DIR_OUT
| UAS_PIPE_ID_DATA_OUT
,
276 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
277 .wMaxPacketSize
= 1024,
279 .bmAttributes_super
= UAS_STREAM_BM_ATTR
,
280 .extra
= (uint8_t[]) {
281 0x04, /* u8 bLength */
282 0x24, /* u8 bDescriptorType */
283 UAS_PIPE_ID_DATA_OUT
,
284 0x00, /* u8 bReserved */
290 static const USBDescDevice desc_device_high
= {
292 .bMaxPacketSize0
= 64,
293 .bNumConfigurations
= 1,
294 .confs
= (USBDescConfig
[]) {
297 .bConfigurationValue
= 1,
298 .iConfiguration
= STR_CONFIG_HIGH
,
299 .bmAttributes
= USB_CFG_ATT_ONE
| USB_CFG_ATT_SELFPOWER
,
301 .ifs
= &desc_iface_high
,
306 static const USBDescDevice desc_device_super
= {
308 .bMaxPacketSize0
= 9,
309 .bNumConfigurations
= 1,
310 .confs
= (USBDescConfig
[]) {
313 .bConfigurationValue
= 1,
314 .iConfiguration
= STR_CONFIG_SUPER
,
315 .bmAttributes
= USB_CFG_ATT_ONE
| USB_CFG_ATT_SELFPOWER
,
317 .ifs
= &desc_iface_super
,
322 static const USBDesc desc
= {
324 .idVendor
= 0x46f4, /* CRC16() of "QEMU" */
327 .iManufacturer
= STR_MANUFACTURER
,
328 .iProduct
= STR_PRODUCT
,
329 .iSerialNumber
= STR_SERIALNUMBER
,
331 .high
= &desc_device_high
,
332 .super
= &desc_device_super
,
336 /* --------------------------------------------------------------------- */
338 static bool uas_using_streams(UASDevice
*uas
)
340 return uas
->dev
.speed
== USB_SPEED_SUPER
;
343 /* --------------------------------------------------------------------- */
345 static UASStatus
*usb_uas_alloc_status(UASDevice
*uas
, uint8_t id
, uint16_t tag
)
347 UASStatus
*st
= g_new0(UASStatus
, 1);
349 st
->status
.hdr
.id
= id
;
350 st
->status
.hdr
.tag
= cpu_to_be16(tag
);
351 st
->length
= sizeof(uas_iu_header
);
352 if (uas_using_streams(uas
)) {
358 static void usb_uas_send_status_bh(void *opaque
)
360 UASDevice
*uas
= opaque
;
364 while ((st
= QTAILQ_FIRST(&uas
->results
)) != NULL
) {
365 if (uas_using_streams(uas
)) {
366 p
= uas
->status3
[st
->stream
];
367 uas
->status3
[st
->stream
] = NULL
;
376 usb_packet_copy(p
, &st
->status
, st
->length
);
377 QTAILQ_REMOVE(&uas
->results
, st
, next
);
380 p
->status
= USB_RET_SUCCESS
; /* Clear previous ASYNC status */
381 usb_packet_complete(&uas
->dev
, p
);
385 static void usb_uas_queue_status(UASDevice
*uas
, UASStatus
*st
, int length
)
387 USBPacket
*p
= uas_using_streams(uas
) ?
388 uas
->status3
[st
->stream
] : uas
->status2
;
390 st
->length
+= length
;
391 QTAILQ_INSERT_TAIL(&uas
->results
, st
, next
);
394 * Just schedule bh make sure any in-flight data transaction
395 * is finished before completing (sending) the status packet.
397 qemu_bh_schedule(uas
->status_bh
);
399 USBEndpoint
*ep
= usb_ep_get(&uas
->dev
, USB_TOKEN_IN
,
401 usb_wakeup(ep
, st
->stream
);
405 static void usb_uas_queue_response(UASDevice
*uas
, uint16_t tag
, uint8_t code
)
407 UASStatus
*st
= usb_uas_alloc_status(uas
, UAS_UI_RESPONSE
, tag
);
409 trace_usb_uas_response(uas
->dev
.addr
, tag
, code
);
410 st
->status
.response
.response_code
= code
;
411 usb_uas_queue_status(uas
, st
, sizeof(uas_iu_response
));
414 static void usb_uas_queue_sense(UASRequest
*req
, uint8_t status
)
416 UASStatus
*st
= usb_uas_alloc_status(req
->uas
, UAS_UI_SENSE
, req
->tag
);
419 trace_usb_uas_sense(req
->uas
->dev
.addr
, req
->tag
, status
);
420 st
->status
.sense
.status
= status
;
421 st
->status
.sense
.status_qualifier
= cpu_to_be16(0);
422 if (status
!= GOOD
) {
423 slen
= scsi_req_get_sense(req
->req
, st
->status
.sense
.sense_data
,
424 sizeof(st
->status
.sense
.sense_data
));
425 st
->status
.sense
.sense_length
= cpu_to_be16(slen
);
427 len
= sizeof(uas_iu_sense
) - sizeof(st
->status
.sense
.sense_data
) + slen
;
428 usb_uas_queue_status(req
->uas
, st
, len
);
431 static void usb_uas_queue_fake_sense(UASDevice
*uas
, uint16_t tag
,
432 struct SCSISense sense
)
434 UASStatus
*st
= usb_uas_alloc_status(uas
, UAS_UI_SENSE
, tag
);
437 st
->status
.sense
.status
= CHECK_CONDITION
;
438 st
->status
.sense
.status_qualifier
= cpu_to_be16(0);
439 st
->status
.sense
.sense_data
[0] = 0x70;
440 st
->status
.sense
.sense_data
[2] = sense
.key
;
441 st
->status
.sense
.sense_data
[7] = 10;
442 st
->status
.sense
.sense_data
[12] = sense
.asc
;
443 st
->status
.sense
.sense_data
[13] = sense
.ascq
;
445 len
= sizeof(uas_iu_sense
) - sizeof(st
->status
.sense
.sense_data
) + slen
;
446 usb_uas_queue_status(uas
, st
, len
);
449 static void usb_uas_queue_read_ready(UASRequest
*req
)
451 UASStatus
*st
= usb_uas_alloc_status(req
->uas
, UAS_UI_READ_READY
,
454 trace_usb_uas_read_ready(req
->uas
->dev
.addr
, req
->tag
);
455 usb_uas_queue_status(req
->uas
, st
, 0);
458 static void usb_uas_queue_write_ready(UASRequest
*req
)
460 UASStatus
*st
= usb_uas_alloc_status(req
->uas
, UAS_UI_WRITE_READY
,
463 trace_usb_uas_write_ready(req
->uas
->dev
.addr
, req
->tag
);
464 usb_uas_queue_status(req
->uas
, st
, 0);
467 /* --------------------------------------------------------------------- */
469 static int usb_uas_get_lun(uint64_t lun64
)
471 return (lun64
>> 48) & 0xff;
474 static SCSIDevice
*usb_uas_get_dev(UASDevice
*uas
, uint64_t lun64
)
476 if ((lun64
>> 56) != 0x00) {
479 return scsi_device_find(&uas
->bus
, 0, 0, usb_uas_get_lun(lun64
));
482 static void usb_uas_complete_data_packet(UASRequest
*req
)
486 if (!req
->data_async
) {
491 req
->data_async
= false;
492 p
->status
= USB_RET_SUCCESS
; /* Clear previous ASYNC status */
493 usb_packet_complete(&req
->uas
->dev
, p
);
496 static void usb_uas_copy_data(UASRequest
*req
)
500 length
= MIN(req
->buf_size
- req
->buf_off
,
501 req
->data
->iov
.size
- req
->data
->actual_length
);
502 trace_usb_uas_xfer_data(req
->uas
->dev
.addr
, req
->tag
, length
,
503 req
->data
->actual_length
, req
->data
->iov
.size
,
504 req
->buf_off
, req
->buf_size
);
505 usb_packet_copy(req
->data
, scsi_req_get_buf(req
->req
) + req
->buf_off
,
507 req
->buf_off
+= length
;
508 req
->data_off
+= length
;
510 if (req
->data
->actual_length
== req
->data
->iov
.size
) {
511 usb_uas_complete_data_packet(req
);
513 if (req
->buf_size
&& req
->buf_off
== req
->buf_size
) {
516 scsi_req_continue(req
->req
);
520 static void usb_uas_start_next_transfer(UASDevice
*uas
)
524 if (uas_using_streams(uas
)) {
528 QTAILQ_FOREACH(req
, &uas
->requests
, next
) {
529 if (req
->active
|| req
->complete
) {
532 if (req
->req
->cmd
.mode
== SCSI_XFER_FROM_DEV
&& uas
->datain2
== NULL
) {
534 usb_uas_queue_read_ready(req
);
538 if (req
->req
->cmd
.mode
== SCSI_XFER_TO_DEV
&& uas
->dataout2
== NULL
) {
540 usb_uas_queue_write_ready(req
);
547 static UASRequest
*usb_uas_alloc_request(UASDevice
*uas
, uas_iu
*iu
)
551 req
= g_new0(UASRequest
, 1);
553 req
->tag
= be16_to_cpu(iu
->hdr
.tag
);
554 req
->lun
= be64_to_cpu(iu
->command
.lun
);
555 req
->dev
= usb_uas_get_dev(req
->uas
, req
->lun
);
559 static void usb_uas_scsi_free_request(SCSIBus
*bus
, void *priv
)
561 UASRequest
*req
= priv
;
562 UASDevice
*uas
= req
->uas
;
564 if (req
== uas
->datain2
) {
567 if (req
== uas
->dataout2
) {
568 uas
->dataout2
= NULL
;
570 QTAILQ_REMOVE(&uas
->requests
, req
, next
);
572 usb_uas_start_next_transfer(uas
);
575 static UASRequest
*usb_uas_find_request(UASDevice
*uas
, uint16_t tag
)
579 QTAILQ_FOREACH(req
, &uas
->requests
, next
) {
580 if (req
->tag
== tag
) {
587 static void usb_uas_scsi_transfer_data(SCSIRequest
*r
, uint32_t len
)
589 UASRequest
*req
= r
->hba_private
;
591 trace_usb_uas_scsi_data(req
->uas
->dev
.addr
, req
->tag
, len
);
595 usb_uas_copy_data(req
);
597 usb_uas_start_next_transfer(req
->uas
);
601 static void usb_uas_scsi_command_complete(SCSIRequest
*r
, size_t resid
)
603 UASRequest
*req
= r
->hba_private
;
605 trace_usb_uas_scsi_complete(req
->uas
->dev
.addr
, req
->tag
, r
->status
, resid
);
606 req
->complete
= true;
608 usb_uas_complete_data_packet(req
);
610 usb_uas_queue_sense(req
, r
->status
);
611 scsi_req_unref(req
->req
);
614 static void usb_uas_scsi_request_cancelled(SCSIRequest
*r
)
616 UASRequest
*req
= r
->hba_private
;
618 /* FIXME: queue notification to status pipe? */
619 scsi_req_unref(req
->req
);
622 static const struct SCSIBusInfo usb_uas_scsi_info
= {
627 .transfer_data
= usb_uas_scsi_transfer_data
,
628 .complete
= usb_uas_scsi_command_complete
,
629 .cancel
= usb_uas_scsi_request_cancelled
,
630 .free_request
= usb_uas_scsi_free_request
,
633 /* --------------------------------------------------------------------- */
635 static void usb_uas_handle_reset(USBDevice
*dev
)
637 UASDevice
*uas
= USB_UAS(dev
);
638 UASRequest
*req
, *nreq
;
641 trace_usb_uas_reset(dev
->addr
);
642 QTAILQ_FOREACH_SAFE(req
, &uas
->requests
, next
, nreq
) {
643 scsi_req_cancel(req
->req
);
645 QTAILQ_FOREACH_SAFE(st
, &uas
->results
, next
, nst
) {
646 QTAILQ_REMOVE(&uas
->results
, st
, next
);
651 static void usb_uas_handle_control(USBDevice
*dev
, USBPacket
*p
,
652 int request
, int value
, int index
, int length
, uint8_t *data
)
656 ret
= usb_desc_handle_control(dev
, p
, request
, value
, index
, length
, data
);
660 error_report("%s: unhandled control request (req 0x%x, val 0x%x, idx 0x%x",
661 __func__
, request
, value
, index
);
662 p
->status
= USB_RET_STALL
;
665 static void usb_uas_cancel_io(USBDevice
*dev
, USBPacket
*p
)
667 UASDevice
*uas
= USB_UAS(dev
);
668 UASRequest
*req
, *nreq
;
671 if (uas
->status2
== p
) {
673 qemu_bh_cancel(uas
->status_bh
);
676 if (uas_using_streams(uas
)) {
677 for (i
= 0; i
<= UAS_MAX_STREAMS
; i
++) {
678 if (uas
->status3
[i
] == p
) {
679 uas
->status3
[i
] = NULL
;
682 if (uas
->data3
[i
] == p
) {
683 uas
->data3
[i
] = NULL
;
688 QTAILQ_FOREACH_SAFE(req
, &uas
->requests
, next
, nreq
) {
689 if (req
->data
== p
) {
694 assert(!"canceled usb packet not found");
697 static void usb_uas_command(UASDevice
*uas
, uas_iu
*iu
)
701 uint16_t tag
= be16_to_cpu(iu
->hdr
.tag
);
703 if (iu
->command
.add_cdb_length
> 0) {
704 qemu_log_mask(LOG_UNIMP
, "additional adb length not yet supported\n");
705 goto unsupported_len
;
708 if (uas_using_streams(uas
) && tag
> UAS_MAX_STREAMS
) {
711 req
= usb_uas_find_request(uas
, tag
);
715 req
= usb_uas_alloc_request(uas
, iu
);
716 if (req
->dev
== NULL
) {
720 trace_usb_uas_command(uas
->dev
.addr
, req
->tag
,
721 usb_uas_get_lun(req
->lun
),
722 req
->lun
>> 32, req
->lun
& 0xffffffff);
723 QTAILQ_INSERT_TAIL(&uas
->requests
, req
, next
);
724 if (uas_using_streams(uas
) && uas
->data3
[req
->tag
] != NULL
) {
725 req
->data
= uas
->data3
[req
->tag
];
726 req
->data_async
= true;
727 uas
->data3
[req
->tag
] = NULL
;
730 req
->req
= scsi_req_new(req
->dev
, req
->tag
,
731 usb_uas_get_lun(req
->lun
),
732 iu
->command
.cdb
, req
);
733 if (uas
->requestlog
) {
734 scsi_req_print(req
->req
);
736 len
= scsi_req_enqueue(req
->req
);
738 req
->data_size
= len
;
739 scsi_req_continue(req
->req
);
744 usb_uas_queue_fake_sense(uas
, tag
, sense_code_INVALID_PARAM_VALUE
);
748 usb_uas_queue_fake_sense(uas
, tag
, sense_code_INVALID_TAG
);
752 usb_uas_queue_fake_sense(uas
, tag
, sense_code_OVERLAPPED_COMMANDS
);
756 usb_uas_queue_fake_sense(uas
, tag
, sense_code_LUN_NOT_SUPPORTED
);
760 static void usb_uas_task(UASDevice
*uas
, uas_iu
*iu
)
762 uint16_t tag
= be16_to_cpu(iu
->hdr
.tag
);
763 uint64_t lun64
= be64_to_cpu(iu
->task
.lun
);
764 SCSIDevice
*dev
= usb_uas_get_dev(uas
, lun64
);
765 int lun
= usb_uas_get_lun(lun64
);
769 if (uas_using_streams(uas
) && tag
> UAS_MAX_STREAMS
) {
772 req
= usb_uas_find_request(uas
, be16_to_cpu(iu
->hdr
.tag
));
780 switch (iu
->task
.function
) {
781 case UAS_TMF_ABORT_TASK
:
782 task_tag
= be16_to_cpu(iu
->task
.task_tag
);
783 trace_usb_uas_tmf_abort_task(uas
->dev
.addr
, tag
, task_tag
);
784 req
= usb_uas_find_request(uas
, task_tag
);
785 if (req
&& req
->dev
== dev
) {
786 scsi_req_cancel(req
->req
);
788 usb_uas_queue_response(uas
, tag
, UAS_RC_TMF_COMPLETE
);
791 case UAS_TMF_LOGICAL_UNIT_RESET
:
792 trace_usb_uas_tmf_logical_unit_reset(uas
->dev
.addr
, tag
, lun
);
793 qdev_reset_all(&dev
->qdev
);
794 usb_uas_queue_response(uas
, tag
, UAS_RC_TMF_COMPLETE
);
798 trace_usb_uas_tmf_unsupported(uas
->dev
.addr
, tag
, iu
->task
.function
);
799 usb_uas_queue_response(uas
, tag
, UAS_RC_TMF_NOT_SUPPORTED
);
805 usb_uas_queue_response(uas
, tag
, UAS_RC_INVALID_INFO_UNIT
);
809 usb_uas_queue_response(uas
, req
->tag
, UAS_RC_OVERLAPPED_TAG
);
813 usb_uas_queue_response(uas
, tag
, UAS_RC_INCORRECT_LUN
);
816 static void usb_uas_handle_data(USBDevice
*dev
, USBPacket
*p
)
818 UASDevice
*uas
= USB_UAS(dev
);
825 case UAS_PIPE_ID_COMMAND
:
826 length
= MIN(sizeof(iu
), p
->iov
.size
);
827 usb_packet_copy(p
, &iu
, length
);
830 usb_uas_command(uas
, &iu
);
832 case UAS_UI_TASK_MGMT
:
833 usb_uas_task(uas
, &iu
);
836 error_report("%s: unknown command iu: id 0x%x",
837 __func__
, iu
.hdr
.id
);
838 p
->status
= USB_RET_STALL
;
842 case UAS_PIPE_ID_STATUS
:
843 if (p
->stream
> UAS_MAX_STREAMS
) {
847 QTAILQ_FOREACH(st
, &uas
->results
, next
) {
848 if (st
->stream
== p
->stream
) {
853 assert(uas
->status3
[p
->stream
] == NULL
);
854 uas
->status3
[p
->stream
] = p
;
855 p
->status
= USB_RET_ASYNC
;
859 st
= QTAILQ_FIRST(&uas
->results
);
861 assert(uas
->status2
== NULL
);
863 p
->status
= USB_RET_ASYNC
;
867 usb_packet_copy(p
, &st
->status
, st
->length
);
868 QTAILQ_REMOVE(&uas
->results
, st
, next
);
871 case UAS_PIPE_ID_DATA_IN
:
872 case UAS_PIPE_ID_DATA_OUT
:
873 if (p
->stream
> UAS_MAX_STREAMS
) {
877 req
= usb_uas_find_request(uas
, p
->stream
);
879 req
= (p
->ep
->nr
== UAS_PIPE_ID_DATA_IN
)
880 ? uas
->datain2
: uas
->dataout2
;
884 assert(uas
->data3
[p
->stream
] == NULL
);
885 uas
->data3
[p
->stream
] = p
;
886 p
->status
= USB_RET_ASYNC
;
889 error_report("%s: no inflight request", __func__
);
890 p
->status
= USB_RET_STALL
;
894 scsi_req_ref(req
->req
);
896 usb_uas_copy_data(req
);
897 if (p
->actual_length
== p
->iov
.size
|| req
->complete
) {
900 req
->data_async
= true;
901 p
->status
= USB_RET_ASYNC
;
903 scsi_req_unref(req
->req
);
904 usb_uas_start_next_transfer(uas
);
907 error_report("%s: invalid endpoint %d", __func__
, p
->ep
->nr
);
908 p
->status
= USB_RET_STALL
;
913 error_report("%s: invalid stream %d", __func__
, p
->stream
);
914 p
->status
= USB_RET_STALL
;
918 static void usb_uas_unrealize(USBDevice
*dev
)
920 UASDevice
*uas
= USB_UAS(dev
);
922 qemu_bh_delete(uas
->status_bh
);
925 static void usb_uas_realize(USBDevice
*dev
, Error
**errp
)
927 UASDevice
*uas
= USB_UAS(dev
);
928 DeviceState
*d
= DEVICE(dev
);
930 usb_desc_create_serial(dev
);
933 uas
->dev
.auto_attach
= 0;
936 QTAILQ_INIT(&uas
->results
);
937 QTAILQ_INIT(&uas
->requests
);
938 uas
->status_bh
= qemu_bh_new(usb_uas_send_status_bh
, uas
);
940 dev
->flags
|= (1 << USB_DEV_FLAG_IS_SCSI_STORAGE
);
941 scsi_bus_init(&uas
->bus
, sizeof(uas
->bus
), DEVICE(dev
), &usb_uas_scsi_info
);
944 static const VMStateDescription vmstate_usb_uas
= {
947 .fields
= (VMStateField
[]) {
948 VMSTATE_USB_DEVICE(dev
, UASDevice
),
949 VMSTATE_END_OF_LIST()
953 static Property uas_properties
[] = {
954 DEFINE_PROP_UINT32("log-scsi-req", UASDevice
, requestlog
, 0),
955 DEFINE_PROP_END_OF_LIST(),
958 static void usb_uas_class_initfn(ObjectClass
*klass
, void *data
)
960 DeviceClass
*dc
= DEVICE_CLASS(klass
);
961 USBDeviceClass
*uc
= USB_DEVICE_CLASS(klass
);
963 uc
->realize
= usb_uas_realize
;
964 uc
->product_desc
= desc_strings
[STR_PRODUCT
];
965 uc
->usb_desc
= &desc
;
966 uc
->cancel_packet
= usb_uas_cancel_io
;
967 uc
->handle_attach
= usb_desc_attach
;
968 uc
->handle_reset
= usb_uas_handle_reset
;
969 uc
->handle_control
= usb_uas_handle_control
;
970 uc
->handle_data
= usb_uas_handle_data
;
971 uc
->unrealize
= usb_uas_unrealize
;
972 uc
->attached_settable
= true;
973 set_bit(DEVICE_CATEGORY_STORAGE
, dc
->categories
);
974 dc
->fw_name
= "storage";
975 dc
->vmsd
= &vmstate_usb_uas
;
976 device_class_set_props(dc
, uas_properties
);
979 static const TypeInfo uas_info
= {
980 .name
= TYPE_USB_UAS
,
981 .parent
= TYPE_USB_DEVICE
,
982 .instance_size
= sizeof(UASDevice
),
983 .class_init
= usb_uas_class_initfn
,
986 static void usb_uas_register_types(void)
988 type_register_static(&uas_info
);
991 type_init(usb_uas_register_types
)