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 OBJECT_DECLARE_TYPE(SCSIDevice
, SCSIDeviceClass
, SCSI_DEVICE
)
55 struct SCSIDeviceClass
{
56 DeviceClass parent_class
;
57 void (*realize
)(SCSIDevice
*dev
, Error
**errp
);
58 void (*unrealize
)(SCSIDevice
*dev
);
59 int (*parse_cdb
)(SCSIDevice
*dev
, SCSICommand
*cmd
, uint8_t *buf
,
61 SCSIRequest
*(*alloc_req
)(SCSIDevice
*s
, uint32_t tag
, uint32_t lun
,
62 uint8_t *buf
, void *hba_private
);
63 void (*unit_attention_reported
)(SCSIDevice
*s
);
69 VMChangeStateEntry
*vmsentry
;
73 SCSISense unit_attention
;
75 uint8_t sense
[SCSI_SENSE_BUF_SIZE
];
77 QTAILQ_HEAD(, SCSIRequest
) requests
;
86 int default_scsi_version
;
87 bool needs_vpd_bl_emulation
;
88 bool hba_supports_iothread
;
91 extern const VMStateDescription vmstate_scsi_device
;
93 #define VMSTATE_SCSI_DEVICE(_field, _state) { \
94 .name = (stringify(_field)), \
95 .size = sizeof(SCSIDevice), \
96 .vmsd = &vmstate_scsi_device, \
97 .flags = VMS_STRUCT, \
98 .offset = vmstate_offset_value(_state, _field, SCSIDevice), \
102 int cdrom_read_toc(int nb_sectors
, uint8_t *buf
, int msf
, int start_track
);
103 int cdrom_read_toc_raw(int nb_sectors
, uint8_t *buf
, int msf
, int session_num
);
108 void (*free_req
)(SCSIRequest
*req
);
109 int32_t (*send_command
)(SCSIRequest
*req
, uint8_t *buf
);
110 void (*read_data
)(SCSIRequest
*req
);
111 void (*write_data
)(SCSIRequest
*req
);
112 uint8_t *(*get_buf
)(SCSIRequest
*req
);
114 void (*save_request
)(QEMUFile
*f
, SCSIRequest
*req
);
115 void (*load_request
)(QEMUFile
*f
, SCSIRequest
*req
);
120 int max_channel
, max_target
, max_lun
;
121 int (*parse_cdb
)(SCSIDevice
*dev
, SCSICommand
*cmd
, uint8_t *buf
,
123 void (*transfer_data
)(SCSIRequest
*req
, uint32_t arg
);
124 void (*complete
)(SCSIRequest
*req
, uint32_t arg
, size_t resid
);
125 void (*cancel
)(SCSIRequest
*req
);
126 void (*change
)(SCSIBus
*bus
, SCSIDevice
*dev
, SCSISense sense
);
127 QEMUSGList
*(*get_sg_list
)(SCSIRequest
*req
);
129 void (*save_request
)(QEMUFile
*f
, SCSIRequest
*req
);
130 void *(*load_request
)(QEMUFile
*f
, SCSIRequest
*req
);
131 void (*free_request
)(SCSIBus
*bus
, void *priv
);
134 #define TYPE_SCSI_BUS "SCSI"
135 OBJECT_DECLARE_SIMPLE_TYPE(SCSIBus
, SCSI_BUS
)
141 SCSISense unit_attention
;
142 const SCSIBusInfo
*info
;
145 void scsi_bus_new(SCSIBus
*bus
, size_t bus_size
, DeviceState
*host
,
146 const SCSIBusInfo
*info
, const char *bus_name
);
148 static inline SCSIBus
*scsi_bus_from_device(SCSIDevice
*d
)
150 return DO_UPCAST(SCSIBus
, qbus
, d
->qdev
.parent_bus
);
153 SCSIDevice
*scsi_bus_legacy_add_drive(SCSIBus
*bus
, BlockBackend
*blk
,
154 int unit
, bool removable
, int bootindex
,
156 BlockdevOnError rerror
,
157 BlockdevOnError werror
,
158 const char *serial
, Error
**errp
);
159 void scsi_bus_legacy_handle_cmdline(SCSIBus
*bus
);
160 void scsi_legacy_handle_cmdline(void);
162 SCSIRequest
*scsi_req_alloc(const SCSIReqOps
*reqops
, SCSIDevice
*d
,
163 uint32_t tag
, uint32_t lun
, void *hba_private
);
164 SCSIRequest
*scsi_req_new(SCSIDevice
*d
, uint32_t tag
, uint32_t lun
,
165 uint8_t *buf
, void *hba_private
);
166 int32_t scsi_req_enqueue(SCSIRequest
*req
);
167 SCSIRequest
*scsi_req_ref(SCSIRequest
*req
);
168 void scsi_req_unref(SCSIRequest
*req
);
170 int scsi_bus_parse_cdb(SCSIDevice
*dev
, SCSICommand
*cmd
, uint8_t *buf
,
172 int scsi_req_parse_cdb(SCSIDevice
*dev
, SCSICommand
*cmd
, uint8_t *buf
);
173 void scsi_req_build_sense(SCSIRequest
*req
, SCSISense sense
);
174 void scsi_req_print(SCSIRequest
*req
);
175 void scsi_req_continue(SCSIRequest
*req
);
176 void scsi_req_data(SCSIRequest
*req
, int len
);
177 void scsi_req_complete(SCSIRequest
*req
, int status
);
178 uint8_t *scsi_req_get_buf(SCSIRequest
*req
);
179 int scsi_req_get_sense(SCSIRequest
*req
, uint8_t *buf
, int len
);
180 void scsi_req_cancel_complete(SCSIRequest
*req
);
181 void scsi_req_cancel(SCSIRequest
*req
);
182 void scsi_req_cancel_async(SCSIRequest
*req
, Notifier
*notifier
);
183 void scsi_req_retry(SCSIRequest
*req
);
184 void scsi_device_purge_requests(SCSIDevice
*sdev
, SCSISense sense
);
185 void scsi_device_set_ua(SCSIDevice
*sdev
, SCSISense sense
);
186 void scsi_device_report_change(SCSIDevice
*dev
, SCSISense sense
);
187 void scsi_device_unit_attention_reported(SCSIDevice
*dev
);
188 void scsi_generic_read_device_inquiry(SCSIDevice
*dev
);
189 int scsi_device_get_sense(SCSIDevice
*dev
, uint8_t *buf
, int len
, bool fixed
);
190 int scsi_SG_IO_FROM_DEV(BlockBackend
*blk
, uint8_t *cmd
, uint8_t cmd_size
,
191 uint8_t *buf
, uint8_t buf_size
);
192 SCSIDevice
*scsi_device_find(SCSIBus
*bus
, int channel
, int target
, int lun
);
193 SCSIDevice
*scsi_device_get(SCSIBus
*bus
, int channel
, int target
, int lun
);
195 /* scsi-generic.c. */
196 extern const SCSIReqOps scsi_generic_req_ops
;