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
25 const SCSIReqOps
*ops
;
33 NotifierList cancel_notifiers
;
36 * - fields before sense are initialized by scsi_req_alloc;
37 * - sense[] is uninitialized;
38 * - fields after sense are memset to 0 by scsi_req_alloc.
41 uint8_t sense
[SCSI_SENSE_BUF_SIZE
];
49 QTAILQ_ENTRY(SCSIRequest
) next
;
52 #define TYPE_SCSI_DEVICE "scsi-device"
53 typedef struct SCSIDeviceClass SCSIDeviceClass
;
54 DECLARE_OBJ_CHECKERS(SCSIDevice
, SCSIDeviceClass
,
55 SCSI_DEVICE
, TYPE_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
,
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
;
75 SCSISense unit_attention
;
77 uint8_t sense
[SCSI_SENSE_BUF_SIZE
];
79 QTAILQ_HEAD(, SCSIRequest
) requests
;
88 int default_scsi_version
;
89 bool needs_vpd_bl_emulation
;
90 bool hba_supports_iothread
;
93 extern const VMStateDescription vmstate_scsi_device
;
95 #define VMSTATE_SCSI_DEVICE(_field, _state) { \
96 .name = (stringify(_field)), \
97 .size = sizeof(SCSIDevice), \
98 .vmsd = &vmstate_scsi_device, \
99 .flags = VMS_STRUCT, \
100 .offset = vmstate_offset_value(_state, _field, SCSIDevice), \
104 int cdrom_read_toc(int nb_sectors
, uint8_t *buf
, int msf
, int start_track
);
105 int cdrom_read_toc_raw(int nb_sectors
, uint8_t *buf
, int msf
, int session_num
);
110 void (*free_req
)(SCSIRequest
*req
);
111 int32_t (*send_command
)(SCSIRequest
*req
, uint8_t *buf
);
112 void (*read_data
)(SCSIRequest
*req
);
113 void (*write_data
)(SCSIRequest
*req
);
114 uint8_t *(*get_buf
)(SCSIRequest
*req
);
116 void (*save_request
)(QEMUFile
*f
, SCSIRequest
*req
);
117 void (*load_request
)(QEMUFile
*f
, SCSIRequest
*req
);
122 int max_channel
, max_target
, max_lun
;
123 int (*parse_cdb
)(SCSIDevice
*dev
, SCSICommand
*cmd
, uint8_t *buf
,
125 void (*transfer_data
)(SCSIRequest
*req
, uint32_t arg
);
126 void (*complete
)(SCSIRequest
*req
, uint32_t arg
, size_t resid
);
127 void (*cancel
)(SCSIRequest
*req
);
128 void (*change
)(SCSIBus
*bus
, SCSIDevice
*dev
, SCSISense sense
);
129 QEMUSGList
*(*get_sg_list
)(SCSIRequest
*req
);
131 void (*save_request
)(QEMUFile
*f
, SCSIRequest
*req
);
132 void *(*load_request
)(QEMUFile
*f
, SCSIRequest
*req
);
133 void (*free_request
)(SCSIBus
*bus
, void *priv
);
136 #define TYPE_SCSI_BUS "SCSI"
137 DECLARE_INSTANCE_CHECKER(SCSIBus
, 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
;