5 #include "hw/block/block.h"
6 #include "hw/qdev-core.h"
7 #include "scsi/utils.h"
8 #include "qemu/notify.h"
10 #define MAX_SCSI_DEVS 255
12 typedef struct SCSIBus SCSIBus
;
13 typedef struct SCSIBusInfo SCSIBusInfo
;
14 typedef struct SCSIDevice SCSIDevice
;
15 typedef struct SCSIRequest SCSIRequest
;
16 typedef struct SCSIReqOps SCSIReqOps
;
18 #define SCSI_SENSE_BUF_SIZE_OLD 96
19 #define SCSI_SENSE_BUF_SIZE 252
24 const SCSIReqOps
*ops
;
32 NotifierList cancel_notifiers
;
35 * - fields before sense are initialized by scsi_req_alloc;
36 * - sense[] is uninitialized;
37 * - fields after sense are memset to 0 by scsi_req_alloc.
40 uint8_t sense
[SCSI_SENSE_BUF_SIZE
];
48 QTAILQ_ENTRY(SCSIRequest
) next
;
51 #define TYPE_SCSI_DEVICE "scsi-device"
52 #define SCSI_DEVICE(obj) \
53 OBJECT_CHECK(SCSIDevice, (obj), TYPE_SCSI_DEVICE)
54 #define SCSI_DEVICE_CLASS(klass) \
55 OBJECT_CLASS_CHECK(SCSIDeviceClass, (klass), TYPE_SCSI_DEVICE)
56 #define SCSI_DEVICE_GET_CLASS(obj) \
57 OBJECT_GET_CLASS(SCSIDeviceClass, (obj), TYPE_SCSI_DEVICE)
59 typedef struct SCSIDeviceClass
{
60 DeviceClass parent_class
;
61 void (*realize
)(SCSIDevice
*dev
, Error
**errp
);
62 int (*parse_cdb
)(SCSIDevice
*dev
, SCSICommand
*cmd
, uint8_t *buf
,
64 SCSIRequest
*(*alloc_req
)(SCSIDevice
*s
, uint32_t tag
, uint32_t lun
,
65 uint8_t *buf
, void *hba_private
);
66 void (*unit_attention_reported
)(SCSIDevice
*s
);
72 VMChangeStateEntry
*vmsentry
;
76 SCSISense unit_attention
;
78 uint8_t sense
[SCSI_SENSE_BUF_SIZE
];
80 QTAILQ_HEAD(, SCSIRequest
) requests
;
89 int default_scsi_version
;
90 bool needs_vpd_bl_emulation
;
91 bool hba_supports_iothread
;
94 extern const VMStateDescription vmstate_scsi_device
;
96 #define VMSTATE_SCSI_DEVICE(_field, _state) { \
97 .name = (stringify(_field)), \
98 .size = sizeof(SCSIDevice), \
99 .vmsd = &vmstate_scsi_device, \
100 .flags = VMS_STRUCT, \
101 .offset = vmstate_offset_value(_state, _field, SCSIDevice), \
105 int cdrom_read_toc(int nb_sectors
, uint8_t *buf
, int msf
, int start_track
);
106 int cdrom_read_toc_raw(int nb_sectors
, uint8_t *buf
, int msf
, int session_num
);
111 void (*free_req
)(SCSIRequest
*req
);
112 int32_t (*send_command
)(SCSIRequest
*req
, uint8_t *buf
);
113 void (*read_data
)(SCSIRequest
*req
);
114 void (*write_data
)(SCSIRequest
*req
);
115 uint8_t *(*get_buf
)(SCSIRequest
*req
);
117 void (*save_request
)(QEMUFile
*f
, SCSIRequest
*req
);
118 void (*load_request
)(QEMUFile
*f
, SCSIRequest
*req
);
123 int max_channel
, max_target
, max_lun
;
124 int (*parse_cdb
)(SCSIDevice
*dev
, SCSICommand
*cmd
, uint8_t *buf
,
126 void (*transfer_data
)(SCSIRequest
*req
, uint32_t arg
);
127 void (*complete
)(SCSIRequest
*req
, uint32_t arg
, size_t resid
);
128 void (*cancel
)(SCSIRequest
*req
);
129 void (*change
)(SCSIBus
*bus
, SCSIDevice
*dev
, SCSISense sense
);
130 QEMUSGList
*(*get_sg_list
)(SCSIRequest
*req
);
132 void (*save_request
)(QEMUFile
*f
, SCSIRequest
*req
);
133 void *(*load_request
)(QEMUFile
*f
, SCSIRequest
*req
);
134 void (*free_request
)(SCSIBus
*bus
, void *priv
);
137 #define TYPE_SCSI_BUS "SCSI"
138 #define SCSI_BUS(obj) OBJECT_CHECK(SCSIBus, (obj), TYPE_SCSI_BUS)
144 SCSISense unit_attention
;
145 const SCSIBusInfo
*info
;
148 void scsi_bus_new(SCSIBus
*bus
, size_t bus_size
, DeviceState
*host
,
149 const SCSIBusInfo
*info
, const char *bus_name
);
151 static inline SCSIBus
*scsi_bus_from_device(SCSIDevice
*d
)
153 return DO_UPCAST(SCSIBus
, qbus
, d
->qdev
.parent_bus
);
156 SCSIDevice
*scsi_bus_legacy_add_drive(SCSIBus
*bus
, BlockBackend
*blk
,
157 int unit
, bool removable
, int bootindex
,
159 BlockdevOnError rerror
,
160 BlockdevOnError werror
,
161 const char *serial
, Error
**errp
);
162 void scsi_bus_legacy_handle_cmdline(SCSIBus
*bus
);
163 void scsi_legacy_handle_cmdline(void);
165 SCSIRequest
*scsi_req_alloc(const SCSIReqOps
*reqops
, SCSIDevice
*d
,
166 uint32_t tag
, uint32_t lun
, void *hba_private
);
167 SCSIRequest
*scsi_req_new(SCSIDevice
*d
, uint32_t tag
, uint32_t lun
,
168 uint8_t *buf
, void *hba_private
);
169 int32_t scsi_req_enqueue(SCSIRequest
*req
);
170 SCSIRequest
*scsi_req_ref(SCSIRequest
*req
);
171 void scsi_req_unref(SCSIRequest
*req
);
173 int scsi_bus_parse_cdb(SCSIDevice
*dev
, SCSICommand
*cmd
, uint8_t *buf
,
175 int scsi_req_parse_cdb(SCSIDevice
*dev
, SCSICommand
*cmd
, uint8_t *buf
);
176 void scsi_req_build_sense(SCSIRequest
*req
, SCSISense sense
);
177 void scsi_req_print(SCSIRequest
*req
);
178 void scsi_req_continue(SCSIRequest
*req
);
179 void scsi_req_data(SCSIRequest
*req
, int len
);
180 void scsi_req_complete(SCSIRequest
*req
, int status
);
181 uint8_t *scsi_req_get_buf(SCSIRequest
*req
);
182 int scsi_req_get_sense(SCSIRequest
*req
, uint8_t *buf
, int len
);
183 void scsi_req_cancel_complete(SCSIRequest
*req
);
184 void scsi_req_cancel(SCSIRequest
*req
);
185 void scsi_req_cancel_async(SCSIRequest
*req
, Notifier
*notifier
);
186 void scsi_req_retry(SCSIRequest
*req
);
187 void scsi_device_purge_requests(SCSIDevice
*sdev
, SCSISense sense
);
188 void scsi_device_set_ua(SCSIDevice
*sdev
, SCSISense sense
);
189 void scsi_device_report_change(SCSIDevice
*dev
, SCSISense sense
);
190 void scsi_device_unit_attention_reported(SCSIDevice
*dev
);
191 void scsi_generic_read_device_inquiry(SCSIDevice
*dev
);
192 int scsi_device_get_sense(SCSIDevice
*dev
, uint8_t *buf
, int len
, bool fixed
);
193 int scsi_SG_IO_FROM_DEV(BlockBackend
*blk
, uint8_t *cmd
, uint8_t cmd_size
,
194 uint8_t *buf
, uint8_t buf_size
);
195 SCSIDevice
*scsi_device_find(SCSIBus
*bus
, int channel
, int target
, int lun
);
197 /* scsi-generic.c. */
198 extern const SCSIReqOps scsi_generic_req_ops
;