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 void (*unrealize
)(SCSIDevice
*dev
);
63 int (*parse_cdb
)(SCSIDevice
*dev
, SCSICommand
*cmd
, uint8_t *buf
,
65 SCSIRequest
*(*alloc_req
)(SCSIDevice
*s
, uint32_t tag
, uint32_t lun
,
66 uint8_t *buf
, void *hba_private
);
67 void (*unit_attention_reported
)(SCSIDevice
*s
);
73 VMChangeStateEntry
*vmsentry
;
77 SCSISense unit_attention
;
79 uint8_t sense
[SCSI_SENSE_BUF_SIZE
];
81 QTAILQ_HEAD(, SCSIRequest
) requests
;
90 int default_scsi_version
;
91 bool needs_vpd_bl_emulation
;
92 bool hba_supports_iothread
;
95 extern const VMStateDescription vmstate_scsi_device
;
97 #define VMSTATE_SCSI_DEVICE(_field, _state) { \
98 .name = (stringify(_field)), \
99 .size = sizeof(SCSIDevice), \
100 .vmsd = &vmstate_scsi_device, \
101 .flags = VMS_STRUCT, \
102 .offset = vmstate_offset_value(_state, _field, SCSIDevice), \
106 int cdrom_read_toc(int nb_sectors
, uint8_t *buf
, int msf
, int start_track
);
107 int cdrom_read_toc_raw(int nb_sectors
, uint8_t *buf
, int msf
, int session_num
);
112 void (*free_req
)(SCSIRequest
*req
);
113 int32_t (*send_command
)(SCSIRequest
*req
, uint8_t *buf
);
114 void (*read_data
)(SCSIRequest
*req
);
115 void (*write_data
)(SCSIRequest
*req
);
116 uint8_t *(*get_buf
)(SCSIRequest
*req
);
118 void (*save_request
)(QEMUFile
*f
, SCSIRequest
*req
);
119 void (*load_request
)(QEMUFile
*f
, SCSIRequest
*req
);
124 int max_channel
, max_target
, max_lun
;
125 int (*parse_cdb
)(SCSIDevice
*dev
, SCSICommand
*cmd
, uint8_t *buf
,
127 void (*transfer_data
)(SCSIRequest
*req
, uint32_t arg
);
128 void (*complete
)(SCSIRequest
*req
, uint32_t arg
, size_t resid
);
129 void (*cancel
)(SCSIRequest
*req
);
130 void (*change
)(SCSIBus
*bus
, SCSIDevice
*dev
, SCSISense sense
);
131 QEMUSGList
*(*get_sg_list
)(SCSIRequest
*req
);
133 void (*save_request
)(QEMUFile
*f
, SCSIRequest
*req
);
134 void *(*load_request
)(QEMUFile
*f
, SCSIRequest
*req
);
135 void (*free_request
)(SCSIBus
*bus
, void *priv
);
138 #define TYPE_SCSI_BUS "SCSI"
139 #define SCSI_BUS(obj) OBJECT_CHECK(SCSIBus, (obj), TYPE_SCSI_BUS)
145 SCSISense unit_attention
;
146 const SCSIBusInfo
*info
;
149 void scsi_bus_new(SCSIBus
*bus
, size_t bus_size
, DeviceState
*host
,
150 const SCSIBusInfo
*info
, const char *bus_name
);
152 static inline SCSIBus
*scsi_bus_from_device(SCSIDevice
*d
)
154 return DO_UPCAST(SCSIBus
, qbus
, d
->qdev
.parent_bus
);
157 SCSIDevice
*scsi_bus_legacy_add_drive(SCSIBus
*bus
, BlockBackend
*blk
,
158 int unit
, bool removable
, int bootindex
,
160 BlockdevOnError rerror
,
161 BlockdevOnError werror
,
162 const char *serial
, Error
**errp
);
163 void scsi_bus_legacy_handle_cmdline(SCSIBus
*bus
);
164 void scsi_legacy_handle_cmdline(void);
166 SCSIRequest
*scsi_req_alloc(const SCSIReqOps
*reqops
, SCSIDevice
*d
,
167 uint32_t tag
, uint32_t lun
, void *hba_private
);
168 SCSIRequest
*scsi_req_new(SCSIDevice
*d
, uint32_t tag
, uint32_t lun
,
169 uint8_t *buf
, void *hba_private
);
170 int32_t scsi_req_enqueue(SCSIRequest
*req
);
171 SCSIRequest
*scsi_req_ref(SCSIRequest
*req
);
172 void scsi_req_unref(SCSIRequest
*req
);
174 int scsi_bus_parse_cdb(SCSIDevice
*dev
, SCSICommand
*cmd
, uint8_t *buf
,
176 int scsi_req_parse_cdb(SCSIDevice
*dev
, SCSICommand
*cmd
, uint8_t *buf
);
177 void scsi_req_build_sense(SCSIRequest
*req
, SCSISense sense
);
178 void scsi_req_print(SCSIRequest
*req
);
179 void scsi_req_continue(SCSIRequest
*req
);
180 void scsi_req_data(SCSIRequest
*req
, int len
);
181 void scsi_req_complete(SCSIRequest
*req
, int status
);
182 uint8_t *scsi_req_get_buf(SCSIRequest
*req
);
183 int scsi_req_get_sense(SCSIRequest
*req
, uint8_t *buf
, int len
);
184 void scsi_req_cancel_complete(SCSIRequest
*req
);
185 void scsi_req_cancel(SCSIRequest
*req
);
186 void scsi_req_cancel_async(SCSIRequest
*req
, Notifier
*notifier
);
187 void scsi_req_retry(SCSIRequest
*req
);
188 void scsi_device_purge_requests(SCSIDevice
*sdev
, SCSISense sense
);
189 void scsi_device_set_ua(SCSIDevice
*sdev
, SCSISense sense
);
190 void scsi_device_report_change(SCSIDevice
*dev
, SCSISense sense
);
191 void scsi_device_unit_attention_reported(SCSIDevice
*dev
);
192 void scsi_generic_read_device_inquiry(SCSIDevice
*dev
);
193 int scsi_device_get_sense(SCSIDevice
*dev
, uint8_t *buf
, int len
, bool fixed
);
194 int scsi_SG_IO_FROM_DEV(BlockBackend
*blk
, uint8_t *cmd
, uint8_t cmd_size
,
195 uint8_t *buf
, uint8_t buf_size
);
196 SCSIDevice
*scsi_device_find(SCSIBus
*bus
, int channel
, int target
, int lun
);
198 /* scsi-generic.c. */
199 extern const SCSIReqOps scsi_generic_req_ops
;