4 * Copyright IBM, Corp. 2010
5 * Copyright Red Hat, Inc. 2011
8 * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
9 * Paolo Bonzini <pbonzini@redhat.com>
11 * This work is licensed under the terms of the GNU GPL, version 2 or later.
12 * See the COPYING file in the top-level directory.
16 #include "hw/virtio-scsi.h"
17 #include "qemu/error-report.h"
19 #include <hw/scsi-defs.h>
20 #include "hw/virtio-bus.h"
22 #define VIRTIO_SCSI_VQ_SIZE 128
23 #define VIRTIO_SCSI_CDB_SIZE 32
24 #define VIRTIO_SCSI_SENSE_SIZE 96
25 #define VIRTIO_SCSI_MAX_CHANNEL 0
26 #define VIRTIO_SCSI_MAX_TARGET 255
27 #define VIRTIO_SCSI_MAX_LUN 16383
30 #define VIRTIO_SCSI_S_OK 0
31 #define VIRTIO_SCSI_S_OVERRUN 1
32 #define VIRTIO_SCSI_S_ABORTED 2
33 #define VIRTIO_SCSI_S_BAD_TARGET 3
34 #define VIRTIO_SCSI_S_RESET 4
35 #define VIRTIO_SCSI_S_BUSY 5
36 #define VIRTIO_SCSI_S_TRANSPORT_FAILURE 6
37 #define VIRTIO_SCSI_S_TARGET_FAILURE 7
38 #define VIRTIO_SCSI_S_NEXUS_FAILURE 8
39 #define VIRTIO_SCSI_S_FAILURE 9
40 #define VIRTIO_SCSI_S_FUNCTION_SUCCEEDED 10
41 #define VIRTIO_SCSI_S_FUNCTION_REJECTED 11
42 #define VIRTIO_SCSI_S_INCORRECT_LUN 12
44 /* Controlq type codes. */
45 #define VIRTIO_SCSI_T_TMF 0
46 #define VIRTIO_SCSI_T_AN_QUERY 1
47 #define VIRTIO_SCSI_T_AN_SUBSCRIBE 2
49 /* Valid TMF subtypes. */
50 #define VIRTIO_SCSI_T_TMF_ABORT_TASK 0
51 #define VIRTIO_SCSI_T_TMF_ABORT_TASK_SET 1
52 #define VIRTIO_SCSI_T_TMF_CLEAR_ACA 2
53 #define VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET 3
54 #define VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET 4
55 #define VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET 5
56 #define VIRTIO_SCSI_T_TMF_QUERY_TASK 6
57 #define VIRTIO_SCSI_T_TMF_QUERY_TASK_SET 7
60 #define VIRTIO_SCSI_T_EVENTS_MISSED 0x80000000
61 #define VIRTIO_SCSI_T_NO_EVENT 0
62 #define VIRTIO_SCSI_T_TRANSPORT_RESET 1
63 #define VIRTIO_SCSI_T_ASYNC_NOTIFY 2
64 #define VIRTIO_SCSI_T_PARAM_CHANGE 3
66 /* Reasons for transport reset event */
67 #define VIRTIO_SCSI_EVT_RESET_HARD 0
68 #define VIRTIO_SCSI_EVT_RESET_RESCAN 1
69 #define VIRTIO_SCSI_EVT_RESET_REMOVED 2
71 /* SCSI command request, followed by data-out */
73 uint8_t lun
[8]; /* Logical Unit Number */
74 uint64_t tag
; /* Command identifier */
75 uint8_t task_attr
; /* Task attribute */
79 } QEMU_PACKED VirtIOSCSICmdReq
;
81 /* Response, followed by sense data and data-in */
83 uint32_t sense_len
; /* Sense data length */
84 uint32_t resid
; /* Residual bytes in data buffer */
85 uint16_t status_qualifier
; /* Status qualifier */
86 uint8_t status
; /* Command completion status */
87 uint8_t response
; /* Response values */
89 } QEMU_PACKED VirtIOSCSICmdResp
;
91 /* Task Management Request */
97 } QEMU_PACKED VirtIOSCSICtrlTMFReq
;
101 } QEMU_PACKED VirtIOSCSICtrlTMFResp
;
103 /* Asynchronous notification query/subscription */
107 uint32_t event_requested
;
108 } QEMU_PACKED VirtIOSCSICtrlANReq
;
111 uint32_t event_actual
;
113 } QEMU_PACKED VirtIOSCSICtrlANResp
;
119 } QEMU_PACKED VirtIOSCSIEvent
;
124 uint32_t max_sectors
;
125 uint32_t cmd_per_lun
;
126 uint32_t event_info_size
;
129 uint16_t max_channel
;
132 } QEMU_PACKED VirtIOSCSIConfig
;
134 typedef struct VirtIOSCSIReq
{
137 VirtQueueElement elem
;
142 VirtIOSCSICmdReq
*cmd
;
143 VirtIOSCSICtrlTMFReq
*tmf
;
144 VirtIOSCSICtrlANReq
*an
;
148 VirtIOSCSICmdResp
*cmd
;
149 VirtIOSCSICtrlTMFResp
*tmf
;
150 VirtIOSCSICtrlANResp
*an
;
151 VirtIOSCSIEvent
*event
;
155 static inline int virtio_scsi_get_lun(uint8_t *lun
)
157 return ((lun
[2] << 8) | lun
[3]) & 0x3FFF;
160 static inline SCSIDevice
*virtio_scsi_device_find(VirtIOSCSI
*s
, uint8_t *lun
)
165 if (lun
[2] != 0 && !(lun
[2] >= 0x40 && lun
[2] < 0x80)) {
168 return scsi_device_find(&s
->bus
, 0, lun
[1], virtio_scsi_get_lun(lun
));
171 static void virtio_scsi_complete_req(VirtIOSCSIReq
*req
)
173 VirtIOSCSI
*s
= req
->dev
;
174 VirtQueue
*vq
= req
->vq
;
175 VirtIODevice
*vdev
= VIRTIO_DEVICE(s
);
176 virtqueue_push(vq
, &req
->elem
, req
->qsgl
.size
+ req
->elem
.in_sg
[0].iov_len
);
177 qemu_sglist_destroy(&req
->qsgl
);
179 req
->sreq
->hba_private
= NULL
;
180 scsi_req_unref(req
->sreq
);
183 virtio_notify(vdev
, vq
);
186 static void virtio_scsi_bad_req(void)
188 error_report("wrong size for virtio-scsi headers");
192 static void qemu_sgl_init_external(QEMUSGList
*qsgl
, struct iovec
*sg
,
193 hwaddr
*addr
, int num
)
195 qemu_sglist_init(qsgl
, num
, &dma_context_memory
);
197 qemu_sglist_add(qsgl
, *(addr
++), (sg
++)->iov_len
);
201 static void virtio_scsi_parse_req(VirtIOSCSI
*s
, VirtQueue
*vq
,
204 assert(req
->elem
.in_num
);
208 if (req
->elem
.out_num
) {
209 req
->req
.buf
= req
->elem
.out_sg
[0].iov_base
;
211 req
->resp
.buf
= req
->elem
.in_sg
[0].iov_base
;
213 if (req
->elem
.out_num
> 1) {
214 qemu_sgl_init_external(&req
->qsgl
, &req
->elem
.out_sg
[1],
215 &req
->elem
.out_addr
[1],
216 req
->elem
.out_num
- 1);
218 qemu_sgl_init_external(&req
->qsgl
, &req
->elem
.in_sg
[1],
219 &req
->elem
.in_addr
[1],
220 req
->elem
.in_num
- 1);
224 static VirtIOSCSIReq
*virtio_scsi_pop_req(VirtIOSCSI
*s
, VirtQueue
*vq
)
227 req
= g_malloc(sizeof(*req
));
228 if (!virtqueue_pop(vq
, &req
->elem
)) {
233 virtio_scsi_parse_req(s
, vq
, req
);
237 static void virtio_scsi_save_request(QEMUFile
*f
, SCSIRequest
*sreq
)
239 VirtIOSCSIReq
*req
= sreq
->hba_private
;
240 uint32_t n
= virtio_queue_get_id(req
->vq
) - 2;
242 assert(n
< req
->dev
->conf
.num_queues
);
243 qemu_put_be32s(f
, &n
);
244 qemu_put_buffer(f
, (unsigned char *)&req
->elem
, sizeof(req
->elem
));
247 static void *virtio_scsi_load_request(QEMUFile
*f
, SCSIRequest
*sreq
)
249 SCSIBus
*bus
= sreq
->bus
;
250 VirtIOSCSI
*s
= container_of(bus
, VirtIOSCSI
, bus
);
254 req
= g_malloc(sizeof(*req
));
255 qemu_get_be32s(f
, &n
);
256 assert(n
< s
->conf
.num_queues
);
257 qemu_get_buffer(f
, (unsigned char *)&req
->elem
, sizeof(req
->elem
));
258 virtio_scsi_parse_req(s
, s
->cmd_vqs
[n
], req
);
262 if (req
->sreq
->cmd
.mode
!= SCSI_XFER_NONE
) {
264 (req
->elem
.in_num
> 1 ? SCSI_XFER_FROM_DEV
: SCSI_XFER_TO_DEV
);
266 assert(req
->sreq
->cmd
.mode
== req_mode
);
271 static void virtio_scsi_do_tmf(VirtIOSCSI
*s
, VirtIOSCSIReq
*req
)
273 SCSIDevice
*d
= virtio_scsi_device_find(s
, req
->req
.tmf
->lun
);
274 SCSIRequest
*r
, *next
;
278 /* Here VIRTIO_SCSI_S_OK means "FUNCTION COMPLETE". */
279 req
->resp
.tmf
->response
= VIRTIO_SCSI_S_OK
;
281 switch (req
->req
.tmf
->subtype
) {
282 case VIRTIO_SCSI_T_TMF_ABORT_TASK
:
283 case VIRTIO_SCSI_T_TMF_QUERY_TASK
:
287 if (d
->lun
!= virtio_scsi_get_lun(req
->req
.tmf
->lun
)) {
290 QTAILQ_FOREACH_SAFE(r
, &d
->requests
, next
, next
) {
291 VirtIOSCSIReq
*cmd_req
= r
->hba_private
;
292 if (cmd_req
&& cmd_req
->req
.cmd
->tag
== req
->req
.tmf
->tag
) {
298 * Assert that the request has not been completed yet, we
299 * check for it in the loop above.
301 assert(r
->hba_private
);
302 if (req
->req
.tmf
->subtype
== VIRTIO_SCSI_T_TMF_QUERY_TASK
) {
303 /* "If the specified command is present in the task set, then
304 * return a service response set to FUNCTION SUCCEEDED".
306 req
->resp
.tmf
->response
= VIRTIO_SCSI_S_FUNCTION_SUCCEEDED
;
313 case VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET
:
317 if (d
->lun
!= virtio_scsi_get_lun(req
->req
.tmf
->lun
)) {
321 qdev_reset_all(&d
->qdev
);
325 case VIRTIO_SCSI_T_TMF_ABORT_TASK_SET
:
326 case VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET
:
327 case VIRTIO_SCSI_T_TMF_QUERY_TASK_SET
:
331 if (d
->lun
!= virtio_scsi_get_lun(req
->req
.tmf
->lun
)) {
334 QTAILQ_FOREACH_SAFE(r
, &d
->requests
, next
, next
) {
335 if (r
->hba_private
) {
336 if (req
->req
.tmf
->subtype
== VIRTIO_SCSI_T_TMF_QUERY_TASK_SET
) {
337 /* "If there is any command present in the task set, then
338 * return a service response set to FUNCTION SUCCEEDED".
340 req
->resp
.tmf
->response
= VIRTIO_SCSI_S_FUNCTION_SUCCEEDED
;
349 case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET
:
350 target
= req
->req
.tmf
->lun
[1];
352 QTAILQ_FOREACH(kid
, &s
->bus
.qbus
.children
, sibling
) {
353 d
= DO_UPCAST(SCSIDevice
, qdev
, kid
->child
);
354 if (d
->channel
== 0 && d
->id
== target
) {
355 qdev_reset_all(&d
->qdev
);
361 case VIRTIO_SCSI_T_TMF_CLEAR_ACA
:
363 req
->resp
.tmf
->response
= VIRTIO_SCSI_S_FUNCTION_REJECTED
;
370 req
->resp
.tmf
->response
= VIRTIO_SCSI_S_INCORRECT_LUN
;
374 req
->resp
.tmf
->response
= VIRTIO_SCSI_S_BAD_TARGET
;
377 static void virtio_scsi_handle_ctrl(VirtIODevice
*vdev
, VirtQueue
*vq
)
379 VirtIOSCSI
*s
= (VirtIOSCSI
*)vdev
;
382 while ((req
= virtio_scsi_pop_req(s
, vq
))) {
383 int out_size
, in_size
;
384 if (req
->elem
.out_num
< 1 || req
->elem
.in_num
< 1) {
385 virtio_scsi_bad_req();
389 out_size
= req
->elem
.out_sg
[0].iov_len
;
390 in_size
= req
->elem
.in_sg
[0].iov_len
;
391 if (req
->req
.tmf
->type
== VIRTIO_SCSI_T_TMF
) {
392 if (out_size
< sizeof(VirtIOSCSICtrlTMFReq
) ||
393 in_size
< sizeof(VirtIOSCSICtrlTMFResp
)) {
394 virtio_scsi_bad_req();
396 virtio_scsi_do_tmf(s
, req
);
398 } else if (req
->req
.tmf
->type
== VIRTIO_SCSI_T_AN_QUERY
||
399 req
->req
.tmf
->type
== VIRTIO_SCSI_T_AN_SUBSCRIBE
) {
400 if (out_size
< sizeof(VirtIOSCSICtrlANReq
) ||
401 in_size
< sizeof(VirtIOSCSICtrlANResp
)) {
402 virtio_scsi_bad_req();
404 req
->resp
.an
->event_actual
= 0;
405 req
->resp
.an
->response
= VIRTIO_SCSI_S_OK
;
407 virtio_scsi_complete_req(req
);
411 static void virtio_scsi_command_complete(SCSIRequest
*r
, uint32_t status
,
414 VirtIOSCSIReq
*req
= r
->hba_private
;
417 req
->resp
.cmd
->response
= VIRTIO_SCSI_S_OK
;
418 req
->resp
.cmd
->status
= status
;
419 if (req
->resp
.cmd
->status
== GOOD
) {
420 req
->resp
.cmd
->resid
= tswap32(resid
);
422 req
->resp
.cmd
->resid
= 0;
423 sense_len
= scsi_req_get_sense(r
, req
->resp
.cmd
->sense
,
424 VIRTIO_SCSI_SENSE_SIZE
);
425 req
->resp
.cmd
->sense_len
= tswap32(sense_len
);
427 virtio_scsi_complete_req(req
);
430 static QEMUSGList
*virtio_scsi_get_sg_list(SCSIRequest
*r
)
432 VirtIOSCSIReq
*req
= r
->hba_private
;
437 static void virtio_scsi_request_cancelled(SCSIRequest
*r
)
439 VirtIOSCSIReq
*req
= r
->hba_private
;
444 if (req
->dev
->resetting
) {
445 req
->resp
.cmd
->response
= VIRTIO_SCSI_S_RESET
;
447 req
->resp
.cmd
->response
= VIRTIO_SCSI_S_ABORTED
;
449 virtio_scsi_complete_req(req
);
452 static void virtio_scsi_fail_cmd_req(VirtIOSCSIReq
*req
)
454 req
->resp
.cmd
->response
= VIRTIO_SCSI_S_FAILURE
;
455 virtio_scsi_complete_req(req
);
458 static void virtio_scsi_handle_cmd(VirtIODevice
*vdev
, VirtQueue
*vq
)
460 VirtIOSCSI
*s
= (VirtIOSCSI
*)vdev
;
464 while ((req
= virtio_scsi_pop_req(s
, vq
))) {
466 int out_size
, in_size
;
467 if (req
->elem
.out_num
< 1 || req
->elem
.in_num
< 1) {
468 virtio_scsi_bad_req();
471 out_size
= req
->elem
.out_sg
[0].iov_len
;
472 in_size
= req
->elem
.in_sg
[0].iov_len
;
473 if (out_size
< sizeof(VirtIOSCSICmdReq
) + s
->cdb_size
||
474 in_size
< sizeof(VirtIOSCSICmdResp
) + s
->sense_size
) {
475 virtio_scsi_bad_req();
478 if (req
->elem
.out_num
> 1 && req
->elem
.in_num
> 1) {
479 virtio_scsi_fail_cmd_req(req
);
483 d
= virtio_scsi_device_find(s
, req
->req
.cmd
->lun
);
485 req
->resp
.cmd
->response
= VIRTIO_SCSI_S_BAD_TARGET
;
486 virtio_scsi_complete_req(req
);
489 req
->sreq
= scsi_req_new(d
, req
->req
.cmd
->tag
,
490 virtio_scsi_get_lun(req
->req
.cmd
->lun
),
491 req
->req
.cmd
->cdb
, req
);
493 if (req
->sreq
->cmd
.mode
!= SCSI_XFER_NONE
) {
495 (req
->elem
.in_num
> 1 ? SCSI_XFER_FROM_DEV
: SCSI_XFER_TO_DEV
);
497 if (req
->sreq
->cmd
.mode
!= req_mode
||
498 req
->sreq
->cmd
.xfer
> req
->qsgl
.size
) {
499 req
->resp
.cmd
->response
= VIRTIO_SCSI_S_OVERRUN
;
500 virtio_scsi_complete_req(req
);
505 n
= scsi_req_enqueue(req
->sreq
);
507 scsi_req_continue(req
->sreq
);
512 static void virtio_scsi_get_config(VirtIODevice
*vdev
,
515 VirtIOSCSIConfig
*scsiconf
= (VirtIOSCSIConfig
*)config
;
516 VirtIOSCSI
*s
= (VirtIOSCSI
*)vdev
;
518 stl_raw(&scsiconf
->num_queues
, s
->conf
.num_queues
);
519 stl_raw(&scsiconf
->seg_max
, 128 - 2);
520 stl_raw(&scsiconf
->max_sectors
, s
->conf
.max_sectors
);
521 stl_raw(&scsiconf
->cmd_per_lun
, s
->conf
.cmd_per_lun
);
522 stl_raw(&scsiconf
->event_info_size
, sizeof(VirtIOSCSIEvent
));
523 stl_raw(&scsiconf
->sense_size
, s
->sense_size
);
524 stl_raw(&scsiconf
->cdb_size
, s
->cdb_size
);
525 stw_raw(&scsiconf
->max_channel
, VIRTIO_SCSI_MAX_CHANNEL
);
526 stw_raw(&scsiconf
->max_target
, VIRTIO_SCSI_MAX_TARGET
);
527 stl_raw(&scsiconf
->max_lun
, VIRTIO_SCSI_MAX_LUN
);
530 static void virtio_scsi_set_config(VirtIODevice
*vdev
,
531 const uint8_t *config
)
533 VirtIOSCSIConfig
*scsiconf
= (VirtIOSCSIConfig
*)config
;
534 VirtIOSCSI
*s
= (VirtIOSCSI
*)vdev
;
536 if ((uint32_t) ldl_raw(&scsiconf
->sense_size
) >= 65536 ||
537 (uint32_t) ldl_raw(&scsiconf
->cdb_size
) >= 256) {
538 error_report("bad data written to virtio-scsi configuration space");
542 s
->sense_size
= ldl_raw(&scsiconf
->sense_size
);
543 s
->cdb_size
= ldl_raw(&scsiconf
->cdb_size
);
546 static uint32_t virtio_scsi_get_features(VirtIODevice
*vdev
,
547 uint32_t requested_features
)
549 return requested_features
;
552 static void virtio_scsi_reset(VirtIODevice
*vdev
)
554 VirtIOSCSI
*s
= (VirtIOSCSI
*)vdev
;
557 qbus_reset_all(&s
->bus
.qbus
);
560 s
->sense_size
= VIRTIO_SCSI_SENSE_SIZE
;
561 s
->cdb_size
= VIRTIO_SCSI_CDB_SIZE
;
562 s
->events_dropped
= false;
565 /* The device does not have anything to save beyond the virtio data.
566 * Request data is saved with callbacks from SCSI devices.
568 static void virtio_scsi_save(QEMUFile
*f
, void *opaque
)
570 VirtIODevice
*vdev
= VIRTIO_DEVICE(opaque
);
571 virtio_save(vdev
, f
);
574 static int virtio_scsi_load(QEMUFile
*f
, void *opaque
, int version_id
)
576 VirtIODevice
*vdev
= VIRTIO_DEVICE(opaque
);
579 ret
= virtio_load(vdev
, f
);
586 static void virtio_scsi_push_event(VirtIOSCSI
*s
, SCSIDevice
*dev
,
587 uint32_t event
, uint32_t reason
)
589 VirtIOSCSIReq
*req
= virtio_scsi_pop_req(s
, s
->event_vq
);
590 VirtIOSCSIEvent
*evt
;
591 VirtIODevice
*vdev
= VIRTIO_DEVICE(s
);
594 if (!(vdev
->status
& VIRTIO_CONFIG_S_DRIVER_OK
)) {
599 s
->events_dropped
= true;
603 if (req
->elem
.out_num
|| req
->elem
.in_num
!= 1) {
604 virtio_scsi_bad_req();
607 if (s
->events_dropped
) {
608 event
|= VIRTIO_SCSI_T_EVENTS_MISSED
;
609 s
->events_dropped
= false;
612 in_size
= req
->elem
.in_sg
[0].iov_len
;
613 if (in_size
< sizeof(VirtIOSCSIEvent
)) {
614 virtio_scsi_bad_req();
617 evt
= req
->resp
.event
;
618 memset(evt
, 0, sizeof(VirtIOSCSIEvent
));
620 evt
->reason
= reason
;
622 assert(event
== VIRTIO_SCSI_T_NO_EVENT
);
625 evt
->lun
[1] = dev
->id
;
627 /* Linux wants us to keep the same encoding we use for REPORT LUNS. */
628 if (dev
->lun
>= 256) {
629 evt
->lun
[2] = (dev
->lun
>> 8) | 0x40;
631 evt
->lun
[3] = dev
->lun
& 0xFF;
633 virtio_scsi_complete_req(req
);
636 static void virtio_scsi_handle_event(VirtIODevice
*vdev
, VirtQueue
*vq
)
638 VirtIOSCSI
*s
= VIRTIO_SCSI(vdev
);
640 if (s
->events_dropped
) {
641 virtio_scsi_push_event(s
, NULL
, VIRTIO_SCSI_T_NO_EVENT
, 0);
645 static void virtio_scsi_change(SCSIBus
*bus
, SCSIDevice
*dev
, SCSISense sense
)
647 VirtIOSCSI
*s
= container_of(bus
, VirtIOSCSI
, bus
);
648 VirtIODevice
*vdev
= VIRTIO_DEVICE(s
);
650 if (((vdev
->guest_features
>> VIRTIO_SCSI_F_CHANGE
) & 1) &&
651 dev
->type
!= TYPE_ROM
) {
652 virtio_scsi_push_event(s
, dev
, VIRTIO_SCSI_T_PARAM_CHANGE
,
653 sense
.asc
| (sense
.ascq
<< 8));
657 static void virtio_scsi_hotplug(SCSIBus
*bus
, SCSIDevice
*dev
)
659 VirtIOSCSI
*s
= container_of(bus
, VirtIOSCSI
, bus
);
660 VirtIODevice
*vdev
= VIRTIO_DEVICE(s
);
662 if ((vdev
->guest_features
>> VIRTIO_SCSI_F_HOTPLUG
) & 1) {
663 virtio_scsi_push_event(s
, dev
, VIRTIO_SCSI_T_TRANSPORT_RESET
,
664 VIRTIO_SCSI_EVT_RESET_RESCAN
);
668 static void virtio_scsi_hot_unplug(SCSIBus
*bus
, SCSIDevice
*dev
)
670 VirtIOSCSI
*s
= container_of(bus
, VirtIOSCSI
, bus
);
671 VirtIODevice
*vdev
= VIRTIO_DEVICE(s
);
673 if ((vdev
->guest_features
>> VIRTIO_SCSI_F_HOTPLUG
) & 1) {
674 virtio_scsi_push_event(s
, dev
, VIRTIO_SCSI_T_TRANSPORT_RESET
,
675 VIRTIO_SCSI_EVT_RESET_REMOVED
);
679 static struct SCSIBusInfo virtio_scsi_scsi_info
= {
681 .max_channel
= VIRTIO_SCSI_MAX_CHANNEL
,
682 .max_target
= VIRTIO_SCSI_MAX_TARGET
,
683 .max_lun
= VIRTIO_SCSI_MAX_LUN
,
685 .complete
= virtio_scsi_command_complete
,
686 .cancel
= virtio_scsi_request_cancelled
,
687 .change
= virtio_scsi_change
,
688 .hotplug
= virtio_scsi_hotplug
,
689 .hot_unplug
= virtio_scsi_hot_unplug
,
690 .get_sg_list
= virtio_scsi_get_sg_list
,
691 .save_request
= virtio_scsi_save_request
,
692 .load_request
= virtio_scsi_load_request
,
695 static int virtio_scsi_device_init(VirtIODevice
*vdev
)
697 DeviceState
*qdev
= DEVICE(vdev
);
698 VirtIOSCSI
*s
= VIRTIO_SCSI(vdev
);
699 static int virtio_scsi_id
;
702 virtio_init(VIRTIO_DEVICE(s
), "virtio-scsi", VIRTIO_ID_SCSI
,
703 sizeof(VirtIOSCSIConfig
));
705 s
->cmd_vqs
= g_malloc0(s
->conf
.num_queues
* sizeof(VirtQueue
*));
707 /* TODO set up vdev function pointers */
708 vdev
->get_config
= virtio_scsi_get_config
;
709 vdev
->set_config
= virtio_scsi_set_config
;
710 vdev
->get_features
= virtio_scsi_get_features
;
711 vdev
->reset
= virtio_scsi_reset
;
713 s
->ctrl_vq
= virtio_add_queue(vdev
, VIRTIO_SCSI_VQ_SIZE
,
714 virtio_scsi_handle_ctrl
);
715 s
->event_vq
= virtio_add_queue(vdev
, VIRTIO_SCSI_VQ_SIZE
,
716 virtio_scsi_handle_event
);
717 for (i
= 0; i
< s
->conf
.num_queues
; i
++) {
718 s
->cmd_vqs
[i
] = virtio_add_queue(vdev
, VIRTIO_SCSI_VQ_SIZE
,
719 virtio_scsi_handle_cmd
);
722 scsi_bus_new(&s
->bus
, qdev
, &virtio_scsi_scsi_info
);
723 if (!qdev
->hotplugged
) {
724 scsi_bus_legacy_handle_cmdline(&s
->bus
);
727 register_savevm(qdev
, "virtio-scsi", virtio_scsi_id
++, 1,
728 virtio_scsi_save
, virtio_scsi_load
, s
);
733 static int virtio_scsi_device_exit(DeviceState
*qdev
)
735 VirtIOSCSI
*s
= VIRTIO_SCSI(qdev
);
736 VirtIODevice
*vdev
= VIRTIO_DEVICE(qdev
);
738 unregister_savevm(qdev
, "virtio-scsi", s
);
740 virtio_common_cleanup(vdev
);
744 static Property virtio_scsi_properties
[] = {
745 DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSI
, conf
),
746 DEFINE_PROP_END_OF_LIST(),
749 static void virtio_scsi_class_init(ObjectClass
*klass
, void *data
)
751 DeviceClass
*dc
= DEVICE_CLASS(klass
);
752 VirtioDeviceClass
*vdc
= VIRTIO_DEVICE_CLASS(klass
);
753 dc
->exit
= virtio_scsi_device_exit
;
754 dc
->props
= virtio_scsi_properties
;
755 vdc
->init
= virtio_scsi_device_init
;
756 vdc
->get_config
= virtio_scsi_get_config
;
757 vdc
->set_config
= virtio_scsi_set_config
;
758 vdc
->get_features
= virtio_scsi_get_features
;
759 vdc
->reset
= virtio_scsi_reset
;
762 static const TypeInfo virtio_scsi_info
= {
763 .name
= TYPE_VIRTIO_SCSI
,
764 .parent
= TYPE_VIRTIO_DEVICE
,
765 .instance_size
= sizeof(VirtIOSCSI
),
766 .class_init
= virtio_scsi_class_init
,
769 static void virtio_register_types(void)
771 type_register_static(&virtio_scsi_info
);
774 type_init(virtio_register_types
)