5 #include "hw/block/block.h"
6 #include "sysemu/sysemu.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
;
90 extern const VMStateDescription vmstate_scsi_device
;
92 #define VMSTATE_SCSI_DEVICE(_field, _state) { \
93 .name = (stringify(_field)), \
94 .size = sizeof(SCSIDevice), \
95 .vmsd = &vmstate_scsi_device, \
96 .flags = VMS_STRUCT, \
97 .offset = vmstate_offset_value(_state, _field, SCSIDevice), \
101 int cdrom_read_toc(int nb_sectors
, uint8_t *buf
, int msf
, int start_track
);
102 int cdrom_read_toc_raw(int nb_sectors
, uint8_t *buf
, int msf
, int session_num
);
107 void (*free_req
)(SCSIRequest
*req
);
108 int32_t (*send_command
)(SCSIRequest
*req
, uint8_t *buf
);
109 void (*read_data
)(SCSIRequest
*req
);
110 void (*write_data
)(SCSIRequest
*req
);
111 uint8_t *(*get_buf
)(SCSIRequest
*req
);
113 void (*save_request
)(QEMUFile
*f
, SCSIRequest
*req
);
114 void (*load_request
)(QEMUFile
*f
, SCSIRequest
*req
);
119 int max_channel
, max_target
, max_lun
;
120 int (*parse_cdb
)(SCSIDevice
*dev
, SCSICommand
*cmd
, uint8_t *buf
,
122 void (*transfer_data
)(SCSIRequest
*req
, uint32_t arg
);
123 void (*complete
)(SCSIRequest
*req
, uint32_t arg
, size_t resid
);
124 void (*cancel
)(SCSIRequest
*req
);
125 void (*change
)(SCSIBus
*bus
, SCSIDevice
*dev
, SCSISense sense
);
126 QEMUSGList
*(*get_sg_list
)(SCSIRequest
*req
);
128 void (*save_request
)(QEMUFile
*f
, SCSIRequest
*req
);
129 void *(*load_request
)(QEMUFile
*f
, SCSIRequest
*req
);
130 void (*free_request
)(SCSIBus
*bus
, void *priv
);
133 #define TYPE_SCSI_BUS "SCSI"
134 #define SCSI_BUS(obj) OBJECT_CHECK(SCSIBus, (obj), TYPE_SCSI_BUS)
140 SCSISense unit_attention
;
141 const SCSIBusInfo
*info
;
144 void scsi_bus_new(SCSIBus
*bus
, size_t bus_size
, DeviceState
*host
,
145 const SCSIBusInfo
*info
, const char *bus_name
);
147 static inline SCSIBus
*scsi_bus_from_device(SCSIDevice
*d
)
149 return DO_UPCAST(SCSIBus
, qbus
, d
->qdev
.parent_bus
);
152 SCSIDevice
*scsi_bus_legacy_add_drive(SCSIBus
*bus
, BlockBackend
*blk
,
153 int unit
, bool removable
, int bootindex
,
155 const char *serial
, Error
**errp
);
156 void scsi_bus_legacy_handle_cmdline(SCSIBus
*bus
);
157 void scsi_legacy_handle_cmdline(void);
159 SCSIRequest
*scsi_req_alloc(const SCSIReqOps
*reqops
, SCSIDevice
*d
,
160 uint32_t tag
, uint32_t lun
, void *hba_private
);
161 SCSIRequest
*scsi_req_new(SCSIDevice
*d
, uint32_t tag
, uint32_t lun
,
162 uint8_t *buf
, void *hba_private
);
163 int32_t scsi_req_enqueue(SCSIRequest
*req
);
164 SCSIRequest
*scsi_req_ref(SCSIRequest
*req
);
165 void scsi_req_unref(SCSIRequest
*req
);
167 int scsi_bus_parse_cdb(SCSIDevice
*dev
, SCSICommand
*cmd
, uint8_t *buf
,
169 int scsi_req_parse_cdb(SCSIDevice
*dev
, SCSICommand
*cmd
, uint8_t *buf
);
170 void scsi_req_build_sense(SCSIRequest
*req
, SCSISense sense
);
171 void scsi_req_print(SCSIRequest
*req
);
172 void scsi_req_continue(SCSIRequest
*req
);
173 void scsi_req_data(SCSIRequest
*req
, int len
);
174 void scsi_req_complete(SCSIRequest
*req
, int status
);
175 uint8_t *scsi_req_get_buf(SCSIRequest
*req
);
176 int scsi_req_get_sense(SCSIRequest
*req
, uint8_t *buf
, int len
);
177 void scsi_req_cancel_complete(SCSIRequest
*req
);
178 void scsi_req_cancel(SCSIRequest
*req
);
179 void scsi_req_cancel_async(SCSIRequest
*req
, Notifier
*notifier
);
180 void scsi_req_retry(SCSIRequest
*req
);
181 void scsi_device_purge_requests(SCSIDevice
*sdev
, SCSISense sense
);
182 void scsi_device_set_ua(SCSIDevice
*sdev
, SCSISense sense
);
183 void scsi_device_report_change(SCSIDevice
*dev
, SCSISense sense
);
184 void scsi_device_unit_attention_reported(SCSIDevice
*dev
);
185 void scsi_generic_read_device_identification(SCSIDevice
*dev
);
186 int scsi_device_get_sense(SCSIDevice
*dev
, uint8_t *buf
, int len
, bool fixed
);
187 SCSIDevice
*scsi_device_find(SCSIBus
*bus
, int channel
, int target
, int lun
);
189 /* scsi-generic.c. */
190 extern const SCSIReqOps scsi_generic_req_ops
;