1 | /* |
2 | * Virtio SCSI HBA |
3 | * |
4 | * Copyright IBM, Corp. 2010 |
5 | * |
6 | * Authors: |
7 | * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com> |
8 | * |
9 | * This work is licensed under the terms of the GNU GPL, version 2. See |
10 | * the COPYING file in the top-level directory. |
11 | * |
12 | */ |
13 | |
14 | #ifndef QEMU_VIRTIO_SCSI_H |
15 | #define QEMU_VIRTIO_SCSI_H |
16 | |
17 | /* Override CDB/sense data size: they are dynamic (guest controlled) in QEMU */ |
18 | #define VIRTIO_SCSI_CDB_SIZE 0 |
19 | #define VIRTIO_SCSI_SENSE_SIZE 0 |
20 | #include "standard-headers/linux/virtio_scsi.h" |
21 | #include "hw/virtio/virtio.h" |
22 | #include "hw/pci/pci.h" |
23 | #include "hw/scsi/scsi.h" |
24 | #include "chardev/char-fe.h" |
25 | #include "sysemu/iothread.h" |
26 | |
27 | #define TYPE_VIRTIO_SCSI_COMMON "virtio-scsi-common" |
28 | #define VIRTIO_SCSI_COMMON(obj) \ |
29 | OBJECT_CHECK(VirtIOSCSICommon, (obj), TYPE_VIRTIO_SCSI_COMMON) |
30 | |
31 | #define TYPE_VIRTIO_SCSI "virtio-scsi-device" |
32 | #define VIRTIO_SCSI(obj) \ |
33 | OBJECT_CHECK(VirtIOSCSI, (obj), TYPE_VIRTIO_SCSI) |
34 | |
35 | #define VIRTIO_SCSI_MAX_CHANNEL 0 |
36 | #define VIRTIO_SCSI_MAX_TARGET 255 |
37 | #define VIRTIO_SCSI_MAX_LUN 16383 |
38 | |
39 | typedef struct virtio_scsi_cmd_req VirtIOSCSICmdReq; |
40 | typedef struct virtio_scsi_cmd_resp VirtIOSCSICmdResp; |
41 | typedef struct virtio_scsi_ctrl_tmf_req VirtIOSCSICtrlTMFReq; |
42 | typedef struct virtio_scsi_ctrl_tmf_resp VirtIOSCSICtrlTMFResp; |
43 | typedef struct virtio_scsi_ctrl_an_req VirtIOSCSICtrlANReq; |
44 | typedef struct virtio_scsi_ctrl_an_resp VirtIOSCSICtrlANResp; |
45 | typedef struct virtio_scsi_event VirtIOSCSIEvent; |
46 | typedef struct virtio_scsi_config VirtIOSCSIConfig; |
47 | |
48 | struct VirtIOSCSIConf { |
49 | uint32_t num_queues; |
50 | uint32_t virtqueue_size; |
51 | uint32_t max_sectors; |
52 | uint32_t cmd_per_lun; |
53 | #ifdef CONFIG_VHOST_SCSI |
54 | char *vhostfd; |
55 | char *wwpn; |
56 | #endif |
57 | CharBackend chardev; |
58 | uint32_t boot_tpgt; |
59 | IOThread *iothread; |
60 | }; |
61 | |
62 | struct VirtIOSCSI; |
63 | |
64 | typedef struct VirtIOSCSICommon { |
65 | VirtIODevice parent_obj; |
66 | VirtIOSCSIConf conf; |
67 | |
68 | uint32_t sense_size; |
69 | uint32_t cdb_size; |
70 | VirtQueue *ctrl_vq; |
71 | VirtQueue *event_vq; |
72 | VirtQueue **cmd_vqs; |
73 | } VirtIOSCSICommon; |
74 | |
75 | typedef struct VirtIOSCSI { |
76 | VirtIOSCSICommon parent_obj; |
77 | |
78 | SCSIBus bus; |
79 | int resetting; |
80 | bool events_dropped; |
81 | |
82 | /* Fields for dataplane below */ |
83 | AioContext *ctx; /* one iothread per virtio-scsi-pci for now */ |
84 | |
85 | bool dataplane_started; |
86 | bool dataplane_starting; |
87 | bool dataplane_stopping; |
88 | bool dataplane_fenced; |
89 | uint32_t host_features; |
90 | } VirtIOSCSI; |
91 | |
92 | typedef struct VirtIOSCSIReq { |
93 | /* Note: |
94 | * - fields up to resp_iov are initialized by virtio_scsi_init_req; |
95 | * - fields starting at vring are zeroed by virtio_scsi_init_req. |
96 | * */ |
97 | VirtQueueElement elem; |
98 | |
99 | VirtIOSCSI *dev; |
100 | VirtQueue *vq; |
101 | QEMUSGList qsgl; |
102 | QEMUIOVector resp_iov; |
103 | |
104 | union { |
105 | /* Used for two-stage request submission */ |
106 | QTAILQ_ENTRY(VirtIOSCSIReq) next; |
107 | |
108 | /* Used for cancellation of request during TMFs */ |
109 | int remaining; |
110 | }; |
111 | |
112 | SCSIRequest *sreq; |
113 | size_t resp_size; |
114 | enum SCSIXferMode mode; |
115 | union { |
116 | VirtIOSCSICmdResp cmd; |
117 | VirtIOSCSICtrlTMFResp tmf; |
118 | VirtIOSCSICtrlANResp an; |
119 | VirtIOSCSIEvent event; |
120 | } resp; |
121 | union { |
122 | VirtIOSCSICmdReq cmd; |
123 | VirtIOSCSICtrlTMFReq tmf; |
124 | VirtIOSCSICtrlANReq an; |
125 | } req; |
126 | } VirtIOSCSIReq; |
127 | |
128 | static inline void virtio_scsi_acquire(VirtIOSCSI *s) |
129 | { |
130 | if (s->ctx) { |
131 | aio_context_acquire(s->ctx); |
132 | } |
133 | } |
134 | |
135 | static inline void virtio_scsi_release(VirtIOSCSI *s) |
136 | { |
137 | if (s->ctx) { |
138 | aio_context_release(s->ctx); |
139 | } |
140 | } |
141 | |
142 | void virtio_scsi_common_realize(DeviceState *dev, |
143 | VirtIOHandleOutput ctrl, |
144 | VirtIOHandleOutput evt, |
145 | VirtIOHandleOutput cmd, |
146 | Error **errp); |
147 | |
148 | void virtio_scsi_common_unrealize(DeviceState *dev); |
149 | bool virtio_scsi_handle_event_vq(VirtIOSCSI *s, VirtQueue *vq); |
150 | bool virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq); |
151 | bool virtio_scsi_handle_ctrl_vq(VirtIOSCSI *s, VirtQueue *vq); |
152 | void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, VirtIOSCSIReq *req); |
153 | void virtio_scsi_free_req(VirtIOSCSIReq *req); |
154 | void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev, |
155 | uint32_t event, uint32_t reason); |
156 | |
157 | void virtio_scsi_dataplane_setup(VirtIOSCSI *s, Error **errp); |
158 | int virtio_scsi_dataplane_start(VirtIODevice *s); |
159 | void virtio_scsi_dataplane_stop(VirtIODevice *s); |
160 | |
161 | #endif /* QEMU_VIRTIO_SCSI_H */ |
162 | |