5 #include "hw/block/block.h"
6 #include "hw/qdev-core.h"
7 #include "scsi/utils.h"
8 #include "qemu/notify.h"
9 #include "qom/object.h"
11 #define MAX_SCSI_DEVS 255
13 typedef struct SCSIBus SCSIBus
;
14 typedef struct SCSIBusInfo SCSIBusInfo
;
15 typedef struct SCSIDevice SCSIDevice
;
16 typedef struct SCSIRequest SCSIRequest
;
17 typedef struct SCSIReqOps SCSIReqOps
;
19 #define SCSI_SENSE_BUF_SIZE_OLD 96
20 #define SCSI_SENSE_BUF_SIZE 252
21 #define DEFAULT_IO_TIMEOUT 30
26 const SCSIReqOps
*ops
;
35 NotifierList cancel_notifiers
;
38 * - fields before sense are initialized by scsi_req_alloc;
39 * - sense[] is uninitialized;
40 * - fields after sense are memset to 0 by scsi_req_alloc.
43 uint8_t sense
[SCSI_SENSE_BUF_SIZE
];
51 QTAILQ_ENTRY(SCSIRequest
) next
;
54 #define TYPE_SCSI_DEVICE "scsi-device"
55 OBJECT_DECLARE_TYPE(SCSIDevice
, SCSIDeviceClass
, SCSI_DEVICE
)
57 struct SCSIDeviceClass
{
58 DeviceClass parent_class
;
59 void (*realize
)(SCSIDevice
*dev
, Error
**errp
);
60 void (*unrealize
)(SCSIDevice
*dev
);
61 int (*parse_cdb
)(SCSIDevice
*dev
, SCSICommand
*cmd
, uint8_t *buf
,
62 size_t buf_len
, void *hba_private
);
63 SCSIRequest
*(*alloc_req
)(SCSIDevice
*s
, uint32_t tag
, uint32_t lun
,
64 uint8_t *buf
, void *hba_private
);
65 void (*unit_attention_reported
)(SCSIDevice
*s
);
71 VMChangeStateEntry
*vmsentry
;
74 SCSISense unit_attention
;
76 uint8_t sense
[SCSI_SENSE_BUF_SIZE
];
80 * The requests list is only accessed from the AioContext that executes
81 * requests or from the main loop when IOThread processing is stopped.
83 QTAILQ_HEAD(, SCSIRequest
) requests
;
93 int default_scsi_version
;
95 bool needs_vpd_bl_emulation
;
96 bool hba_supports_iothread
;
99 extern const VMStateDescription vmstate_scsi_device
;
101 #define VMSTATE_SCSI_DEVICE(_field, _state) { \
102 .name = (stringify(_field)), \
103 .size = sizeof(SCSIDevice), \
104 .vmsd = &vmstate_scsi_device, \
105 .flags = VMS_STRUCT, \
106 .offset = vmstate_offset_value(_state, _field, SCSIDevice), \
110 int cdrom_read_toc(int nb_sectors
, uint8_t *buf
, int msf
, int start_track
);
111 int cdrom_read_toc_raw(int nb_sectors
, uint8_t *buf
, int msf
, int session_num
);
116 void (*init_req
)(SCSIRequest
*req
);
117 void (*free_req
)(SCSIRequest
*req
);
118 int32_t (*send_command
)(SCSIRequest
*req
, uint8_t *buf
);
119 void (*read_data
)(SCSIRequest
*req
);
120 void (*write_data
)(SCSIRequest
*req
);
121 uint8_t *(*get_buf
)(SCSIRequest
*req
);
123 void (*save_request
)(QEMUFile
*f
, SCSIRequest
*req
);
124 void (*load_request
)(QEMUFile
*f
, SCSIRequest
*req
);
129 int max_channel
, max_target
, max_lun
;
130 int (*parse_cdb
)(SCSIDevice
*dev
, SCSICommand
*cmd
, uint8_t *buf
,
131 size_t buf_len
, void *hba_private
);
132 void (*transfer_data
)(SCSIRequest
*req
, uint32_t arg
);
133 void (*fail
)(SCSIRequest
*req
);
134 void (*complete
)(SCSIRequest
*req
, size_t residual
);
135 void (*cancel
)(SCSIRequest
*req
);
136 void (*change
)(SCSIBus
*bus
, SCSIDevice
*dev
, SCSISense sense
);
137 QEMUSGList
*(*get_sg_list
)(SCSIRequest
*req
);
139 void (*save_request
)(QEMUFile
*f
, SCSIRequest
*req
);
140 void *(*load_request
)(QEMUFile
*f
, SCSIRequest
*req
);
141 void (*free_request
)(SCSIBus
*bus
, void *priv
);
144 * Temporarily stop submitting new requests between drained_begin() and
145 * drained_end(). Called from the main loop thread with the BQL held.
147 * Implement these callbacks if request processing is triggered by a file
148 * descriptor like an EventNotifier. Otherwise set them to NULL.
150 void (*drained_begin
)(SCSIBus
*bus
);
151 void (*drained_end
)(SCSIBus
*bus
);
154 #define TYPE_SCSI_BUS "SCSI"
155 OBJECT_DECLARE_SIMPLE_TYPE(SCSIBus
, SCSI_BUS
)
161 SCSISense unit_attention
;
162 const SCSIBusInfo
*info
;
164 int drain_count
; /* protected by BQL */
168 * scsi_bus_init_named: Initialize a SCSI bus with the specified name
169 * @bus: SCSIBus object to initialize
170 * @bus_size: size of @bus object
171 * @host: Device which owns the bus (generally the SCSI controller)
172 * @info: structure defining callbacks etc for the controller
173 * @bus_name: Name to use for this bus
175 * This in-place initializes @bus as a new SCSI bus with a name
176 * provided by the caller. It is the caller's responsibility to make
177 * sure that name does not clash with the name of any other bus in the
178 * system. Unless you need the new bus to have a specific name, you
179 * should use scsi_bus_init() instead.
181 void scsi_bus_init_named(SCSIBus
*bus
, size_t bus_size
, DeviceState
*host
,
182 const SCSIBusInfo
*info
, const char *bus_name
);
185 * scsi_bus_init: Initialize a SCSI bus
187 * This in-place-initializes @bus as a new SCSI bus and gives it
188 * an automatically generated unique name.
190 static inline void scsi_bus_init(SCSIBus
*bus
, size_t bus_size
,
191 DeviceState
*host
, const SCSIBusInfo
*info
)
193 scsi_bus_init_named(bus
, bus_size
, host
, info
, NULL
);
196 static inline SCSIBus
*scsi_bus_from_device(SCSIDevice
*d
)
198 return DO_UPCAST(SCSIBus
, qbus
, d
->qdev
.parent_bus
);
201 SCSIDevice
*scsi_bus_legacy_add_drive(SCSIBus
*bus
, BlockBackend
*blk
,
202 int unit
, bool removable
, BlockConf
*conf
,
203 const char *serial
, Error
**errp
);
204 void scsi_bus_set_ua(SCSIBus
*bus
, SCSISense sense
);
205 void scsi_bus_legacy_handle_cmdline(SCSIBus
*bus
);
207 SCSIRequest
*scsi_req_alloc(const SCSIReqOps
*reqops
, SCSIDevice
*d
,
208 uint32_t tag
, uint32_t lun
, void *hba_private
);
209 SCSIRequest
*scsi_req_new(SCSIDevice
*d
, uint32_t tag
, uint32_t lun
,
210 uint8_t *buf
, size_t buf_len
, void *hba_private
);
211 int32_t scsi_req_enqueue(SCSIRequest
*req
);
212 SCSIRequest
*scsi_req_ref(SCSIRequest
*req
);
213 void scsi_req_unref(SCSIRequest
*req
);
215 int scsi_bus_parse_cdb(SCSIDevice
*dev
, SCSICommand
*cmd
, uint8_t *buf
,
216 size_t buf_len
, void *hba_private
);
217 int scsi_req_parse_cdb(SCSIDevice
*dev
, SCSICommand
*cmd
, uint8_t *buf
,
219 void scsi_req_build_sense(SCSIRequest
*req
, SCSISense sense
);
220 void scsi_req_print(SCSIRequest
*req
);
221 void scsi_req_continue(SCSIRequest
*req
);
222 void scsi_req_data(SCSIRequest
*req
, int len
);
223 void scsi_req_complete(SCSIRequest
*req
, int status
);
224 void scsi_req_complete_failed(SCSIRequest
*req
, int host_status
);
225 uint8_t *scsi_req_get_buf(SCSIRequest
*req
);
226 int scsi_req_get_sense(SCSIRequest
*req
, uint8_t *buf
, int len
);
227 void scsi_req_cancel_complete(SCSIRequest
*req
);
228 void scsi_req_cancel(SCSIRequest
*req
);
229 void scsi_req_cancel_async(SCSIRequest
*req
, Notifier
*notifier
);
230 void scsi_req_retry(SCSIRequest
*req
);
231 void scsi_device_drained_begin(SCSIDevice
*sdev
);
232 void scsi_device_drained_end(SCSIDevice
*sdev
);
233 void scsi_device_purge_requests(SCSIDevice
*sdev
, SCSISense sense
);
234 void scsi_device_set_ua(SCSIDevice
*sdev
, SCSISense sense
);
235 void scsi_device_report_change(SCSIDevice
*dev
, SCSISense sense
);
236 void scsi_device_unit_attention_reported(SCSIDevice
*dev
);
237 void scsi_generic_read_device_inquiry(SCSIDevice
*dev
);
238 int scsi_device_get_sense(SCSIDevice
*dev
, uint8_t *buf
, int len
, bool fixed
);
239 int scsi_SG_IO_FROM_DEV(BlockBackend
*blk
, uint8_t *cmd
, uint8_t cmd_size
,
240 uint8_t *buf
, uint8_t buf_size
, uint32_t timeout
);
241 SCSIDevice
*scsi_device_find(SCSIBus
*bus
, int channel
, int target
, int lun
);
242 SCSIDevice
*scsi_device_get(SCSIBus
*bus
, int channel
, int target
, int lun
);
244 /* scsi-generic.c. */
245 extern const SCSIReqOps scsi_generic_req_ops
;
248 #define SCSI_DISK_QUIRK_MODE_PAGE_APPLE_VENDOR 0
249 #define SCSI_DISK_QUIRK_MODE_SENSE_ROM_USE_DBD 1
250 #define SCSI_DISK_QUIRK_MODE_PAGE_VENDOR_SPECIFIC_APPLE 2
251 #define SCSI_DISK_QUIRK_MODE_PAGE_TRUNCATED 3