master
h 267 lines 9.37 KB
Raw
1 #ifndef QEMU_HW_SCSI_H
2 #define QEMU_HW_SCSI_H
3
4 #include "qemu/aiocb.h"
5 #include "qemu/aio.h"
6 #include "hw/block/block.h"
7 #include "hw/core/qdev.h"
8 #include "scsi/utils.h"
9 #include "qemu/notify.h"
10 #include "qom/object.h"
11
12 #define MAX_SCSI_DEVS 255
13
14 #define TYPE_SCSI_BUS "SCSI"
15 OBJECT_DECLARE_SIMPLE_TYPE(SCSIBus, SCSI_BUS)
16
17 typedef struct SCSIBusInfo SCSIBusInfo;
18 typedef struct SCSIDevice SCSIDevice;
19 typedef struct SCSIRequest SCSIRequest;
20 typedef struct SCSIReqOps SCSIReqOps;
21
22 #define SCSI_SENSE_BUF_SIZE_OLD 96
23 #define SCSI_SENSE_BUF_SIZE 252
24 #define DEFAULT_IO_TIMEOUT 30
25
26 struct SCSIRequest {
27 SCSIBus *bus;
28 SCSIDevice *dev;
29 const SCSIReqOps *ops;
30 AioContext *ctx;
31 uint32_t refcount;
32 uint32_t tag;
33 uint32_t lun;
34 int16_t status;
35 int16_t host_status;
36 void *hba_private;
37 uint64_t residual;
38 SCSICommand cmd;
39 NotifierList cancel_notifiers;
40
41 /* Note:
42 * - fields before sense are initialized by scsi_req_alloc;
43 * - sense[] is uninitialized;
44 * - fields after sense are memset to 0 by scsi_req_alloc.
45 * */
46
47 uint8_t sense[SCSI_SENSE_BUF_SIZE];
48 uint32_t sense_len;
49 bool enqueued;
50 bool io_canceled;
51 bool retry;
52 bool dma_started;
53 BlockAIOCB *aiocb;
54 QEMUSGList *sg;
55
56 /* Protected by SCSIDevice->requests_lock */
57 QTAILQ_ENTRY(SCSIRequest) next;
58 };
59
60 /* Per-SCSIDevice Persistent Reservation state */
61 typedef struct {
62 QemuMutex mutex; /* protects all fields (e.g. from multiple IOThreads) */
63 uint64_t key; /* 0 if no registered key */
64 uint8_t resv_type; /* 0 if no reservation */
65 } SCSIPRState;
66
67 #define TYPE_SCSI_DEVICE "scsi-device"
68 OBJECT_DECLARE_TYPE(SCSIDevice, SCSIDeviceClass, SCSI_DEVICE)
69
70 struct SCSIDeviceClass {
71 DeviceClass parent_class;
72 void (*realize)(SCSIDevice *dev, Error **errp);
73 void (*unrealize)(SCSIDevice *dev);
74 int (*parse_cdb)(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
75 size_t buf_len, void *hba_private);
76 SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
77 uint8_t *buf, void *hba_private);
78 void (*unit_attention_reported)(SCSIDevice *s);
79 };
80
81 struct SCSIDevice
82 {
83 DeviceState qdev;
84 VMChangeStateEntry *vmsentry;
85 uint32_t id;
86 BlockConf conf;
87 SCSISense unit_attention;
88 bool sense_is_ua;
89 uint8_t sense[SCSI_SENSE_BUF_SIZE];
90 uint32_t sense_len;
91
92 QemuMutex requests_lock; /* protects the requests list */
93 QTAILQ_HEAD(, SCSIRequest) requests;
94
95 uint32_t channel;
96 uint32_t lun;
97 int blocksize;
98 int type;
99 uint64_t max_lba;
100 uint64_t wwn;
101 uint64_t port_wwn;
102 int scsi_version;
103 int default_scsi_version;
104 uint32_t io_timeout;
105 bool needs_vpd_bl_emulation;
106 bool hba_supports_iothread;
107
108 bool migrate_pr;
109 SCSIPRState pr_state;
110 };
111
112 extern const VMStateDescription vmstate_scsi_device;
113
114 #define VMSTATE_SCSI_DEVICE(_field, _state) { \
115 .name = (stringify(_field)), \
116 .size = sizeof(SCSIDevice), \
117 .vmsd = &vmstate_scsi_device, \
118 .flags = VMS_STRUCT, \
119 .offset = vmstate_offset_value(_state, _field, SCSIDevice), \
120 }
121
122 /* cdrom.c */
123 int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
124 int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num);
125
126 /* scsi-bus.c */
127 struct SCSIReqOps {
128 size_t size;
129 void (*init_req)(SCSIRequest *req);
130 void (*free_req)(SCSIRequest *req);
131 int32_t (*send_command)(SCSIRequest *req, uint8_t *buf);
132 void (*read_data)(SCSIRequest *req);
133 void (*write_data)(SCSIRequest *req);
134 uint8_t *(*get_buf)(SCSIRequest *req);
135
136 void (*save_request)(QEMUFile *f, SCSIRequest *req);
137 void (*load_request)(QEMUFile *f, SCSIRequest *req);
138 };
139
140 struct SCSIBusInfo {
141 int tcq;
142 int max_channel, max_target, max_lun;
143 int (*parse_cdb)(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
144 size_t buf_len, void *hba_private);
145 void (*transfer_data)(SCSIRequest *req, uint32_t arg);
146 void (*fail)(SCSIRequest *req);
147 void (*complete)(SCSIRequest *req, size_t residual);
148 void (*cancel)(SCSIRequest *req);
149 void (*change)(SCSIBus *bus, SCSIDevice *dev, SCSISense sense);
150 QEMUSGList *(*get_sg_list)(SCSIRequest *req);
151
152 void (*save_request)(QEMUFile *f, SCSIRequest *req);
153 void *(*load_request)(QEMUFile *f, SCSIRequest *req);
154 void (*free_request)(SCSIBus *bus, void *priv);
155
156 /*
157 * Temporarily stop submitting new requests between drained_begin() and
158 * drained_end(). Called from the main loop thread with the BQL held.
159 *
160 * Implement these callbacks if request processing is triggered by a file
161 * descriptor like an EventNotifier. Otherwise set them to NULL.
162 */
163 void (*drained_begin)(SCSIBus *bus);
164 void (*drained_end)(SCSIBus *bus);
165 };
166
167 struct SCSIBus {
168 BusState qbus;
169 int busnr;
170
171 SCSISense unit_attention;
172 const SCSIBusInfo *info;
173
174 int drain_count; /* protected by BQL */
175 };
176
177 /**
178 * scsi_bus_init_named: Initialize a SCSI bus with the specified name
179 * @bus: SCSIBus object to initialize
180 * @bus_size: size of @bus object
181 * @host: Device which owns the bus (generally the SCSI controller)
182 * @info: structure defining callbacks etc for the controller
183 * @bus_name: Name to use for this bus
184 *
185 * This in-place initializes @bus as a new SCSI bus with a name
186 * provided by the caller. It is the caller's responsibility to make
187 * sure that name does not clash with the name of any other bus in the
188 * system. Unless you need the new bus to have a specific name, you
189 * should use scsi_bus_init() instead.
190 */
191 void scsi_bus_init_named(SCSIBus *bus, size_t bus_size, DeviceState *host,
192 const SCSIBusInfo *info, const char *bus_name);
193
194 /**
195 * scsi_bus_init: Initialize a SCSI bus
196 *
197 * This in-place-initializes @bus as a new SCSI bus and gives it
198 * an automatically generated unique name.
199 */
200 static inline void scsi_bus_init(SCSIBus *bus, size_t bus_size,
201 DeviceState *host, const SCSIBusInfo *info)
202 {
203 scsi_bus_init_named(bus, bus_size, host, info, NULL);
204 }
205
206 static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
207 {
208 return DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus);
209 }
210
211 SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
212 int unit, bool removable, BlockConf *conf,
213 const char *serial, Error **errp);
214 void scsi_bus_set_ua(SCSIBus *bus, SCSISense sense);
215 void scsi_bus_legacy_handle_cmdline(SCSIBus *bus);
216
217 SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d,
218 uint32_t tag, uint32_t lun, void *hba_private);
219 SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
220 uint8_t *buf, size_t buf_len, void *hba_private);
221 int32_t scsi_req_enqueue(SCSIRequest *req);
222 SCSIRequest *scsi_req_ref(SCSIRequest *req);
223 void scsi_req_unref(SCSIRequest *req);
224 void scsi_req_unref_detach_hba(SCSIRequest *req);
225
226 int scsi_bus_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
227 size_t buf_len, void *hba_private);
228 int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
229 size_t buf_len);
230 void scsi_req_build_sense(SCSIRequest *req, SCSISense sense);
231 void scsi_req_print(SCSIRequest *req);
232 void scsi_req_continue(SCSIRequest *req);
233 void scsi_req_data(SCSIRequest *req, int len);
234 void scsi_req_complete(SCSIRequest *req, int status);
235 void scsi_req_complete_failed(SCSIRequest *req, int host_status);
236 uint8_t *scsi_req_get_buf(SCSIRequest *req);
237 int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len);
238 void scsi_req_cancel_complete(SCSIRequest *req);
239 void scsi_req_cancel(SCSIRequest *req);
240 void scsi_req_cancel_async(SCSIRequest *req, Notifier *notifier);
241 void scsi_req_retry(SCSIRequest *req);
242 void scsi_device_drained_begin(SCSIDevice *sdev);
243 void scsi_device_drained_end(SCSIDevice *sdev);
244 void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense);
245 void scsi_device_set_ua(SCSIDevice *sdev, SCSISense sense);
246 void scsi_device_report_change(SCSIDevice *dev, SCSISense sense);
247 void scsi_device_unit_attention_reported(SCSIDevice *dev);
248 void scsi_generic_read_device_inquiry(SCSIDevice *dev);
249 int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed);
250 int scsi_SG_IO(BlockBackend *blk, int direction, uint8_t *cmd, uint8_t cmd_size,
251 uint8_t *buf, unsigned int buf_size, uint32_t timeout,
252 Error **errp);
253 SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int target, int lun);
254 SCSIDevice *scsi_device_get(SCSIBus *bus, int channel, int target, int lun);
255
256 /* scsi-generic.c. */
257 extern const SCSIReqOps scsi_generic_req_ops;
258 bool scsi_generic_pr_state_preempt(SCSIDevice *s, Error **errp);
259
260 /* scsi-disk.c */
261 #define SCSI_DISK_QUIRK_MODE_PAGE_APPLE_VENDOR 0
262 #define SCSI_DISK_QUIRK_MODE_SENSE_ROM_USE_DBD 1
263 #define SCSI_DISK_QUIRK_MODE_PAGE_VENDOR_SPECIFIC_APPLE 2
264 #define SCSI_DISK_QUIRK_MODE_PAGE_TRUNCATED 3
265 #define SCSI_DISK_QUIRK_MODE_PAGE_SET_BLOCK_SIZE 4
266
267 #endif