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/virtio-scsi.h"
17 #include "qemu/error-report.h"
19 #include <hw/scsi/scsi.h>
20 #include <block/scsi.h>
21 #include <hw/virtio/virtio-bus.h>
23 typedef struct VirtIOSCSIReq
{
26 VirtQueueElement elem
;
32 VirtIOSCSICmdResp
*cmd
;
33 VirtIOSCSICtrlTMFResp
*tmf
;
34 VirtIOSCSICtrlANResp
*an
;
35 VirtIOSCSIEvent
*event
;
39 VirtIOSCSICmdReq
*cmd
;
40 VirtIOSCSICtrlTMFReq
*tmf
;
41 VirtIOSCSICtrlANReq
*an
;
45 static inline int virtio_scsi_get_lun(uint8_t *lun
)
47 return ((lun
[2] << 8) | lun
[3]) & 0x3FFF;
50 static inline SCSIDevice
*virtio_scsi_device_find(VirtIOSCSI
*s
, uint8_t *lun
)
55 if (lun
[2] != 0 && !(lun
[2] >= 0x40 && lun
[2] < 0x80)) {
58 return scsi_device_find(&s
->bus
, 0, lun
[1], virtio_scsi_get_lun(lun
));
61 static VirtIOSCSIReq
*virtio_scsi_init_req(VirtIOSCSI
*s
, VirtQueue
*vq
)
64 req
= g_malloc(sizeof(*req
));
69 qemu_sglist_init(&req
->qsgl
, DEVICE(s
), 8, &address_space_memory
);
73 static void virtio_scsi_free_req(VirtIOSCSIReq
*req
)
75 qemu_sglist_destroy(&req
->qsgl
);
79 static void virtio_scsi_complete_req(VirtIOSCSIReq
*req
)
81 VirtIOSCSI
*s
= req
->dev
;
82 VirtQueue
*vq
= req
->vq
;
83 VirtIODevice
*vdev
= VIRTIO_DEVICE(s
);
84 virtqueue_push(vq
, &req
->elem
, req
->qsgl
.size
+ req
->elem
.in_sg
[0].iov_len
);
86 req
->sreq
->hba_private
= NULL
;
87 scsi_req_unref(req
->sreq
);
89 virtio_scsi_free_req(req
);
90 virtio_notify(vdev
, vq
);
93 static void virtio_scsi_bad_req(void)
95 error_report("wrong size for virtio-scsi headers");
99 static size_t qemu_sgl_concat(VirtIOSCSIReq
*req
, struct iovec
*iov
,
100 hwaddr
*addr
, int num
, size_t skip
)
102 QEMUSGList
*qsgl
= &req
->qsgl
;
106 if (skip
>= iov
->iov_len
) {
107 skip
-= iov
->iov_len
;
109 qemu_sglist_add(qsgl
, *addr
+ skip
, iov
->iov_len
- skip
);
110 copied
+= iov
->iov_len
- skip
;
122 static int virtio_scsi_parse_req(VirtIOSCSIReq
*req
,
123 unsigned req_size
, unsigned resp_size
)
125 if (req
->elem
.in_num
== 0) {
129 if (req
->elem
.out_sg
[0].iov_len
< req_size
) {
132 if (req
->elem
.out_num
) {
133 req
->req
.buf
= req
->elem
.out_sg
[0].iov_base
;
136 if (req
->elem
.in_sg
[0].iov_len
< resp_size
) {
139 req
->resp
.buf
= req
->elem
.in_sg
[0].iov_base
;
140 req
->resp_size
= resp_size
;
142 if (req
->elem
.out_num
> 1) {
143 qemu_sgl_concat(req
, &req
->elem
.out_sg
[1],
144 &req
->elem
.out_addr
[1],
145 req
->elem
.out_num
- 1, 0);
147 qemu_sgl_concat(req
, &req
->elem
.in_sg
[1],
148 &req
->elem
.in_addr
[1],
149 req
->elem
.in_num
- 1, 0);
155 static VirtIOSCSIReq
*virtio_scsi_pop_req(VirtIOSCSI
*s
, VirtQueue
*vq
)
157 VirtIOSCSIReq
*req
= virtio_scsi_init_req(s
, vq
);
158 if (!virtqueue_pop(vq
, &req
->elem
)) {
159 virtio_scsi_free_req(req
);
165 static void virtio_scsi_save_request(QEMUFile
*f
, SCSIRequest
*sreq
)
167 VirtIOSCSIReq
*req
= sreq
->hba_private
;
168 VirtIOSCSICommon
*vs
= VIRTIO_SCSI_COMMON(req
->dev
);
169 uint32_t n
= virtio_queue_get_id(req
->vq
) - 2;
171 assert(n
< vs
->conf
.num_queues
);
172 qemu_put_be32s(f
, &n
);
173 qemu_put_buffer(f
, (unsigned char *)&req
->elem
, sizeof(req
->elem
));
176 static void *virtio_scsi_load_request(QEMUFile
*f
, SCSIRequest
*sreq
)
178 SCSIBus
*bus
= sreq
->bus
;
179 VirtIOSCSI
*s
= container_of(bus
, VirtIOSCSI
, bus
);
180 VirtIOSCSICommon
*vs
= VIRTIO_SCSI_COMMON(s
);
184 qemu_get_be32s(f
, &n
);
185 assert(n
< vs
->conf
.num_queues
);
186 req
= virtio_scsi_init_req(s
, vs
->cmd_vqs
[n
]);
187 qemu_get_buffer(f
, (unsigned char *)&req
->elem
, sizeof(req
->elem
));
188 /* TODO: add a way for SCSIBusInfo's load_request to fail,
189 * and fail migration instead of asserting here.
190 * When we do, we might be able to re-enable NDEBUG below.
193 #error building with NDEBUG is not supported
195 assert(req
->elem
.in_num
<= ARRAY_SIZE(req
->elem
.in_sg
));
196 assert(req
->elem
.out_num
<= ARRAY_SIZE(req
->elem
.out_sg
));
198 if (virtio_scsi_parse_req(req
, sizeof(VirtIOSCSICmdReq
) + vs
->cdb_size
,
199 sizeof(VirtIOSCSICmdResp
) + vs
->sense_size
) < 0) {
200 error_report("invalid SCSI request migration data");
206 if (req
->sreq
->cmd
.mode
!= SCSI_XFER_NONE
) {
208 (req
->elem
.in_num
> 1 ? SCSI_XFER_FROM_DEV
: SCSI_XFER_TO_DEV
);
210 assert(req
->sreq
->cmd
.mode
== req_mode
);
215 static void virtio_scsi_do_tmf(VirtIOSCSI
*s
, VirtIOSCSIReq
*req
)
217 SCSIDevice
*d
= virtio_scsi_device_find(s
, req
->req
.tmf
->lun
);
218 SCSIRequest
*r
, *next
;
222 /* Here VIRTIO_SCSI_S_OK means "FUNCTION COMPLETE". */
223 req
->resp
.tmf
->response
= VIRTIO_SCSI_S_OK
;
225 tswap32s(&req
->req
.tmf
->subtype
);
226 switch (req
->req
.tmf
->subtype
) {
227 case VIRTIO_SCSI_T_TMF_ABORT_TASK
:
228 case VIRTIO_SCSI_T_TMF_QUERY_TASK
:
232 if (d
->lun
!= virtio_scsi_get_lun(req
->req
.tmf
->lun
)) {
235 QTAILQ_FOREACH_SAFE(r
, &d
->requests
, next
, next
) {
236 VirtIOSCSIReq
*cmd_req
= r
->hba_private
;
237 if (cmd_req
&& cmd_req
->req
.cmd
->tag
== req
->req
.tmf
->tag
) {
243 * Assert that the request has not been completed yet, we
244 * check for it in the loop above.
246 assert(r
->hba_private
);
247 if (req
->req
.tmf
->subtype
== VIRTIO_SCSI_T_TMF_QUERY_TASK
) {
248 /* "If the specified command is present in the task set, then
249 * return a service response set to FUNCTION SUCCEEDED".
251 req
->resp
.tmf
->response
= VIRTIO_SCSI_S_FUNCTION_SUCCEEDED
;
258 case VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET
:
262 if (d
->lun
!= virtio_scsi_get_lun(req
->req
.tmf
->lun
)) {
266 qdev_reset_all(&d
->qdev
);
270 case VIRTIO_SCSI_T_TMF_ABORT_TASK_SET
:
271 case VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET
:
272 case VIRTIO_SCSI_T_TMF_QUERY_TASK_SET
:
276 if (d
->lun
!= virtio_scsi_get_lun(req
->req
.tmf
->lun
)) {
279 QTAILQ_FOREACH_SAFE(r
, &d
->requests
, next
, next
) {
280 if (r
->hba_private
) {
281 if (req
->req
.tmf
->subtype
== VIRTIO_SCSI_T_TMF_QUERY_TASK_SET
) {
282 /* "If there is any command present in the task set, then
283 * return a service response set to FUNCTION SUCCEEDED".
285 req
->resp
.tmf
->response
= VIRTIO_SCSI_S_FUNCTION_SUCCEEDED
;
294 case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET
:
295 target
= req
->req
.tmf
->lun
[1];
297 QTAILQ_FOREACH(kid
, &s
->bus
.qbus
.children
, sibling
) {
298 d
= DO_UPCAST(SCSIDevice
, qdev
, kid
->child
);
299 if (d
->channel
== 0 && d
->id
== target
) {
300 qdev_reset_all(&d
->qdev
);
306 case VIRTIO_SCSI_T_TMF_CLEAR_ACA
:
308 req
->resp
.tmf
->response
= VIRTIO_SCSI_S_FUNCTION_REJECTED
;
315 req
->resp
.tmf
->response
= VIRTIO_SCSI_S_INCORRECT_LUN
;
319 req
->resp
.tmf
->response
= VIRTIO_SCSI_S_BAD_TARGET
;
322 static void virtio_scsi_handle_ctrl(VirtIODevice
*vdev
, VirtQueue
*vq
)
324 VirtIOSCSI
*s
= (VirtIOSCSI
*)vdev
;
327 while ((req
= virtio_scsi_pop_req(s
, vq
))) {
330 if (iov_to_buf(req
->elem
.out_sg
, req
->elem
.out_num
, 0,
331 &type
, sizeof(type
)) < sizeof(type
)) {
332 virtio_scsi_bad_req();
336 tswap32s(&req
->req
.tmf
->type
);
337 if (req
->req
.tmf
->type
== VIRTIO_SCSI_T_TMF
) {
338 if (virtio_scsi_parse_req(req
, sizeof(VirtIOSCSICtrlTMFReq
),
339 sizeof(VirtIOSCSICtrlTMFResp
)) < 0) {
340 virtio_scsi_bad_req();
342 virtio_scsi_do_tmf(s
, req
);
345 } else if (req
->req
.tmf
->type
== VIRTIO_SCSI_T_AN_QUERY
||
346 req
->req
.tmf
->type
== VIRTIO_SCSI_T_AN_SUBSCRIBE
) {
347 if (virtio_scsi_parse_req(req
, sizeof(VirtIOSCSICtrlANReq
),
348 sizeof(VirtIOSCSICtrlANResp
)) < 0) {
349 virtio_scsi_bad_req();
351 req
->resp
.an
->event_actual
= 0;
352 req
->resp
.an
->response
= VIRTIO_SCSI_S_OK
;
355 virtio_scsi_complete_req(req
);
359 static void virtio_scsi_command_complete(SCSIRequest
*r
, uint32_t status
,
362 VirtIOSCSIReq
*req
= r
->hba_private
;
363 uint8_t sense
[SCSI_SENSE_BUF_SIZE
];
366 if (r
->io_canceled
) {
370 req
->resp
.cmd
->response
= VIRTIO_SCSI_S_OK
;
371 req
->resp
.cmd
->status
= status
;
372 if (req
->resp
.cmd
->status
== GOOD
) {
373 req
->resp
.cmd
->resid
= tswap32(resid
);
375 req
->resp
.cmd
->resid
= 0;
376 sense_len
= scsi_req_get_sense(r
, sense
, sizeof(sense
));
377 sense_len
= MIN(sense_len
, req
->resp_size
- sizeof(req
->resp
.cmd
));
378 memcpy(req
->resp
.cmd
->sense
, sense
, sense_len
);
379 req
->resp
.cmd
->sense_len
= tswap32(sense_len
);
381 virtio_scsi_complete_req(req
);
384 static QEMUSGList
*virtio_scsi_get_sg_list(SCSIRequest
*r
)
386 VirtIOSCSIReq
*req
= r
->hba_private
;
391 static void virtio_scsi_request_cancelled(SCSIRequest
*r
)
393 VirtIOSCSIReq
*req
= r
->hba_private
;
398 if (req
->dev
->resetting
) {
399 req
->resp
.cmd
->response
= VIRTIO_SCSI_S_RESET
;
401 req
->resp
.cmd
->response
= VIRTIO_SCSI_S_ABORTED
;
403 virtio_scsi_complete_req(req
);
406 static void virtio_scsi_fail_cmd_req(VirtIOSCSIReq
*req
)
408 req
->resp
.cmd
->response
= VIRTIO_SCSI_S_FAILURE
;
409 virtio_scsi_complete_req(req
);
412 static void virtio_scsi_handle_cmd(VirtIODevice
*vdev
, VirtQueue
*vq
)
414 /* use non-QOM casts in the data path */
415 VirtIOSCSI
*s
= (VirtIOSCSI
*)vdev
;
416 VirtIOSCSICommon
*vs
= &s
->parent_obj
;
421 while ((req
= virtio_scsi_pop_req(s
, vq
))) {
424 if (req
->elem
.out_num
> 1 && req
->elem
.in_num
> 1) {
425 virtio_scsi_fail_cmd_req(req
);
429 rc
= virtio_scsi_parse_req(req
, sizeof(VirtIOSCSICmdReq
) + vs
->cdb_size
,
430 sizeof(VirtIOSCSICmdResp
) + vs
->sense_size
);
432 virtio_scsi_bad_req();
435 d
= virtio_scsi_device_find(s
, req
->req
.cmd
->lun
);
437 req
->resp
.cmd
->response
= VIRTIO_SCSI_S_BAD_TARGET
;
438 virtio_scsi_complete_req(req
);
441 req
->sreq
= scsi_req_new(d
, req
->req
.cmd
->tag
,
442 virtio_scsi_get_lun(req
->req
.cmd
->lun
),
443 req
->req
.cmd
->cdb
, req
);
445 if (req
->sreq
->cmd
.mode
!= SCSI_XFER_NONE
) {
447 (req
->elem
.in_num
> 1 ? SCSI_XFER_FROM_DEV
: SCSI_XFER_TO_DEV
);
449 if (req
->sreq
->cmd
.mode
!= req_mode
||
450 req
->sreq
->cmd
.xfer
> req
->qsgl
.size
) {
451 req
->resp
.cmd
->response
= VIRTIO_SCSI_S_OVERRUN
;
452 virtio_scsi_complete_req(req
);
457 n
= scsi_req_enqueue(req
->sreq
);
459 scsi_req_continue(req
->sreq
);
464 static void virtio_scsi_get_config(VirtIODevice
*vdev
,
467 VirtIOSCSIConfig
*scsiconf
= (VirtIOSCSIConfig
*)config
;
468 VirtIOSCSICommon
*s
= VIRTIO_SCSI_COMMON(vdev
);
470 stl_p(&scsiconf
->num_queues
, s
->conf
.num_queues
);
471 stl_p(&scsiconf
->seg_max
, 128 - 2);
472 stl_p(&scsiconf
->max_sectors
, s
->conf
.max_sectors
);
473 stl_p(&scsiconf
->cmd_per_lun
, s
->conf
.cmd_per_lun
);
474 stl_p(&scsiconf
->event_info_size
, sizeof(VirtIOSCSIEvent
));
475 stl_p(&scsiconf
->sense_size
, s
->sense_size
);
476 stl_p(&scsiconf
->cdb_size
, s
->cdb_size
);
477 stw_p(&scsiconf
->max_channel
, VIRTIO_SCSI_MAX_CHANNEL
);
478 stw_p(&scsiconf
->max_target
, VIRTIO_SCSI_MAX_TARGET
);
479 stl_p(&scsiconf
->max_lun
, VIRTIO_SCSI_MAX_LUN
);
482 static void virtio_scsi_set_config(VirtIODevice
*vdev
,
483 const uint8_t *config
)
485 VirtIOSCSIConfig
*scsiconf
= (VirtIOSCSIConfig
*)config
;
486 VirtIOSCSICommon
*vs
= VIRTIO_SCSI_COMMON(vdev
);
488 if ((uint32_t) ldl_p(&scsiconf
->sense_size
) >= 65536 ||
489 (uint32_t) ldl_p(&scsiconf
->cdb_size
) >= 256) {
490 error_report("bad data written to virtio-scsi configuration space");
494 vs
->sense_size
= ldl_p(&scsiconf
->sense_size
);
495 vs
->cdb_size
= ldl_p(&scsiconf
->cdb_size
);
498 static uint32_t virtio_scsi_get_features(VirtIODevice
*vdev
,
499 uint32_t requested_features
)
501 return requested_features
;
504 static void virtio_scsi_reset(VirtIODevice
*vdev
)
506 VirtIOSCSI
*s
= VIRTIO_SCSI(vdev
);
507 VirtIOSCSICommon
*vs
= VIRTIO_SCSI_COMMON(vdev
);
510 qbus_reset_all(&s
->bus
.qbus
);
513 vs
->sense_size
= VIRTIO_SCSI_SENSE_SIZE
;
514 vs
->cdb_size
= VIRTIO_SCSI_CDB_SIZE
;
515 s
->events_dropped
= false;
518 /* The device does not have anything to save beyond the virtio data.
519 * Request data is saved with callbacks from SCSI devices.
521 static void virtio_scsi_save(QEMUFile
*f
, void *opaque
)
523 VirtIODevice
*vdev
= VIRTIO_DEVICE(opaque
);
524 virtio_save(vdev
, f
);
527 static int virtio_scsi_load(QEMUFile
*f
, void *opaque
, int version_id
)
529 VirtIODevice
*vdev
= VIRTIO_DEVICE(opaque
);
532 ret
= virtio_load(vdev
, f
);
539 static void virtio_scsi_push_event(VirtIOSCSI
*s
, SCSIDevice
*dev
,
540 uint32_t event
, uint32_t reason
)
542 VirtIOSCSICommon
*vs
= VIRTIO_SCSI_COMMON(s
);
544 VirtIOSCSIEvent
*evt
;
545 VirtIODevice
*vdev
= VIRTIO_DEVICE(s
);
548 if (!(vdev
->status
& VIRTIO_CONFIG_S_DRIVER_OK
)) {
552 req
= virtio_scsi_pop_req(s
, vs
->event_vq
);
554 s
->events_dropped
= true;
558 if (req
->elem
.out_num
|| req
->elem
.in_num
!= 1) {
559 virtio_scsi_bad_req();
562 if (s
->events_dropped
) {
563 event
|= VIRTIO_SCSI_T_EVENTS_MISSED
;
564 s
->events_dropped
= false;
567 in_size
= req
->elem
.in_sg
[0].iov_len
;
568 if (in_size
< sizeof(VirtIOSCSIEvent
)) {
569 virtio_scsi_bad_req();
572 evt
= req
->resp
.event
;
573 memset(evt
, 0, sizeof(VirtIOSCSIEvent
));
575 evt
->reason
= reason
;
577 assert(event
== VIRTIO_SCSI_T_EVENTS_MISSED
);
580 evt
->lun
[1] = dev
->id
;
582 /* Linux wants us to keep the same encoding we use for REPORT LUNS. */
583 if (dev
->lun
>= 256) {
584 evt
->lun
[2] = (dev
->lun
>> 8) | 0x40;
586 evt
->lun
[3] = dev
->lun
& 0xFF;
588 virtio_scsi_complete_req(req
);
591 static void virtio_scsi_handle_event(VirtIODevice
*vdev
, VirtQueue
*vq
)
593 VirtIOSCSI
*s
= VIRTIO_SCSI(vdev
);
595 if (s
->events_dropped
) {
596 virtio_scsi_push_event(s
, NULL
, VIRTIO_SCSI_T_NO_EVENT
, 0);
600 static void virtio_scsi_change(SCSIBus
*bus
, SCSIDevice
*dev
, SCSISense sense
)
602 VirtIOSCSI
*s
= container_of(bus
, VirtIOSCSI
, bus
);
603 VirtIODevice
*vdev
= VIRTIO_DEVICE(s
);
605 if (((vdev
->guest_features
>> VIRTIO_SCSI_F_CHANGE
) & 1) &&
606 dev
->type
!= TYPE_ROM
) {
607 virtio_scsi_push_event(s
, dev
, VIRTIO_SCSI_T_PARAM_CHANGE
,
608 sense
.asc
| (sense
.ascq
<< 8));
612 static void virtio_scsi_hotplug(SCSIBus
*bus
, SCSIDevice
*dev
)
614 VirtIOSCSI
*s
= container_of(bus
, VirtIOSCSI
, bus
);
615 VirtIODevice
*vdev
= VIRTIO_DEVICE(s
);
617 if ((vdev
->guest_features
>> VIRTIO_SCSI_F_HOTPLUG
) & 1) {
618 virtio_scsi_push_event(s
, dev
, VIRTIO_SCSI_T_TRANSPORT_RESET
,
619 VIRTIO_SCSI_EVT_RESET_RESCAN
);
623 static void virtio_scsi_hot_unplug(SCSIBus
*bus
, SCSIDevice
*dev
)
625 VirtIOSCSI
*s
= container_of(bus
, VirtIOSCSI
, bus
);
626 VirtIODevice
*vdev
= VIRTIO_DEVICE(s
);
628 if ((vdev
->guest_features
>> VIRTIO_SCSI_F_HOTPLUG
) & 1) {
629 virtio_scsi_push_event(s
, dev
, VIRTIO_SCSI_T_TRANSPORT_RESET
,
630 VIRTIO_SCSI_EVT_RESET_REMOVED
);
634 static struct SCSIBusInfo virtio_scsi_scsi_info
= {
636 .max_channel
= VIRTIO_SCSI_MAX_CHANNEL
,
637 .max_target
= VIRTIO_SCSI_MAX_TARGET
,
638 .max_lun
= VIRTIO_SCSI_MAX_LUN
,
640 .complete
= virtio_scsi_command_complete
,
641 .cancel
= virtio_scsi_request_cancelled
,
642 .change
= virtio_scsi_change
,
643 .hotplug
= virtio_scsi_hotplug
,
644 .hot_unplug
= virtio_scsi_hot_unplug
,
645 .get_sg_list
= virtio_scsi_get_sg_list
,
646 .save_request
= virtio_scsi_save_request
,
647 .load_request
= virtio_scsi_load_request
,
650 void virtio_scsi_common_realize(DeviceState
*dev
, Error
**errp
)
652 VirtIODevice
*vdev
= VIRTIO_DEVICE(dev
);
653 VirtIOSCSICommon
*s
= VIRTIO_SCSI_COMMON(dev
);
656 virtio_init(vdev
, "virtio-scsi", VIRTIO_ID_SCSI
,
657 sizeof(VirtIOSCSIConfig
));
659 s
->cmd_vqs
= g_malloc0(s
->conf
.num_queues
* sizeof(VirtQueue
*));
660 s
->sense_size
= VIRTIO_SCSI_SENSE_SIZE
;
661 s
->cdb_size
= VIRTIO_SCSI_CDB_SIZE
;
663 s
->ctrl_vq
= virtio_add_queue(vdev
, VIRTIO_SCSI_VQ_SIZE
,
664 virtio_scsi_handle_ctrl
);
665 s
->event_vq
= virtio_add_queue(vdev
, VIRTIO_SCSI_VQ_SIZE
,
666 virtio_scsi_handle_event
);
667 for (i
= 0; i
< s
->conf
.num_queues
; i
++) {
668 s
->cmd_vqs
[i
] = virtio_add_queue(vdev
, VIRTIO_SCSI_VQ_SIZE
,
669 virtio_scsi_handle_cmd
);
673 static void virtio_scsi_device_realize(DeviceState
*dev
, Error
**errp
)
675 VirtIODevice
*vdev
= VIRTIO_DEVICE(dev
);
676 VirtIOSCSI
*s
= VIRTIO_SCSI(dev
);
677 static int virtio_scsi_id
;
680 virtio_scsi_common_realize(dev
, &err
);
682 error_propagate(errp
, err
);
686 scsi_bus_new(&s
->bus
, sizeof(s
->bus
), dev
,
687 &virtio_scsi_scsi_info
, vdev
->bus_name
);
689 if (!dev
->hotplugged
) {
690 scsi_bus_legacy_handle_cmdline(&s
->bus
, &err
);
692 error_propagate(errp
, err
);
697 register_savevm(dev
, "virtio-scsi", virtio_scsi_id
++, 1,
698 virtio_scsi_save
, virtio_scsi_load
, s
);
701 void virtio_scsi_common_unrealize(DeviceState
*dev
, Error
**errp
)
703 VirtIODevice
*vdev
= VIRTIO_DEVICE(dev
);
704 VirtIOSCSICommon
*vs
= VIRTIO_SCSI_COMMON(dev
);
707 virtio_cleanup(vdev
);
710 static void virtio_scsi_device_unrealize(DeviceState
*dev
, Error
**errp
)
712 VirtIOSCSI
*s
= VIRTIO_SCSI(dev
);
714 unregister_savevm(dev
, "virtio-scsi", s
);
716 virtio_scsi_common_unrealize(dev
, errp
);
719 static Property virtio_scsi_properties
[] = {
720 DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSI
, parent_obj
.conf
),
721 DEFINE_PROP_END_OF_LIST(),
724 static void virtio_scsi_common_class_init(ObjectClass
*klass
, void *data
)
726 VirtioDeviceClass
*vdc
= VIRTIO_DEVICE_CLASS(klass
);
727 DeviceClass
*dc
= DEVICE_CLASS(klass
);
729 vdc
->get_config
= virtio_scsi_get_config
;
730 set_bit(DEVICE_CATEGORY_STORAGE
, dc
->categories
);
733 static void virtio_scsi_class_init(ObjectClass
*klass
, void *data
)
735 DeviceClass
*dc
= DEVICE_CLASS(klass
);
736 VirtioDeviceClass
*vdc
= VIRTIO_DEVICE_CLASS(klass
);
738 dc
->props
= virtio_scsi_properties
;
739 set_bit(DEVICE_CATEGORY_STORAGE
, dc
->categories
);
740 vdc
->realize
= virtio_scsi_device_realize
;
741 vdc
->unrealize
= virtio_scsi_device_unrealize
;
742 vdc
->set_config
= virtio_scsi_set_config
;
743 vdc
->get_features
= virtio_scsi_get_features
;
744 vdc
->reset
= virtio_scsi_reset
;
747 static const TypeInfo virtio_scsi_common_info
= {
748 .name
= TYPE_VIRTIO_SCSI_COMMON
,
749 .parent
= TYPE_VIRTIO_DEVICE
,
750 .instance_size
= sizeof(VirtIOSCSICommon
),
752 .class_init
= virtio_scsi_common_class_init
,
755 static const TypeInfo virtio_scsi_info
= {
756 .name
= TYPE_VIRTIO_SCSI
,
757 .parent
= TYPE_VIRTIO_SCSI_COMMON
,
758 .instance_size
= sizeof(VirtIOSCSI
),
759 .class_init
= virtio_scsi_class_init
,
762 static void virtio_register_types(void)
764 type_register_static(&virtio_scsi_common_info
);
765 type_register_static(&virtio_scsi_info
);
768 type_init(virtio_register_types
)