2 * Generic SCSI Device support
4 * Copyright (c) 2007 Bull S.A.S.
5 * Based on code by Paul Brook
6 * Based on code by Fabrice Bellard
8 * Written by Laurent Vivier <Laurent.Vivier@bull.net>
10 * This code is licensed under the LGPL.
14 #include "qemu-common.h"
15 #include "qemu/error-report.h"
16 #include "hw/scsi/scsi.h"
17 #include "sysemu/block-backend.h"
18 #include "sysemu/blockdev.h"
25 #define DPRINTF(fmt, ...) \
26 do { printf("scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
28 #define DPRINTF(fmt, ...) do {} while(0)
31 #define BADF(fmt, ...) \
32 do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
35 #include <sys/types.h>
39 #include "block/scsi.h"
41 #define SG_ERR_DRIVER_TIMEOUT 0x06
42 #define SG_ERR_DRIVER_SENSE 0x08
44 #define SG_ERR_DID_OK 0x00
45 #define SG_ERR_DID_NO_CONNECT 0x01
46 #define SG_ERR_DID_BUS_BUSY 0x02
47 #define SG_ERR_DID_TIME_OUT 0x03
50 #define MAX_UINT ((unsigned int)-1)
53 typedef struct SCSIGenericReq
{
58 sg_io_hdr_t io_header
;
61 static void scsi_generic_save_request(QEMUFile
*f
, SCSIRequest
*req
)
63 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
65 qemu_put_sbe32s(f
, &r
->buflen
);
66 if (r
->buflen
&& r
->req
.cmd
.mode
== SCSI_XFER_TO_DEV
) {
68 qemu_put_buffer(f
, r
->buf
, r
->req
.cmd
.xfer
);
72 static void scsi_generic_load_request(QEMUFile
*f
, SCSIRequest
*req
)
74 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
76 qemu_get_sbe32s(f
, &r
->buflen
);
77 if (r
->buflen
&& r
->req
.cmd
.mode
== SCSI_XFER_TO_DEV
) {
79 qemu_get_buffer(f
, r
->buf
, r
->req
.cmd
.xfer
);
83 static void scsi_free_request(SCSIRequest
*req
)
85 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
90 /* Helper function for command completion. */
91 static void scsi_command_complete(void *opaque
, int ret
)
94 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
97 if (r
->req
.io_canceled
) {
98 scsi_req_cancel_complete(&r
->req
);
101 if (r
->io_header
.driver_status
& SG_ERR_DRIVER_SENSE
) {
102 r
->req
.sense_len
= r
->io_header
.sb_len_wr
;
108 status
= TASK_SET_FULL
;
111 status
= CHECK_CONDITION
;
112 scsi_req_build_sense(&r
->req
, SENSE_CODE(TARGET_FAILURE
));
115 status
= CHECK_CONDITION
;
116 scsi_req_build_sense(&r
->req
, SENSE_CODE(IO_ERROR
));
120 if (r
->io_header
.host_status
== SG_ERR_DID_NO_CONNECT
||
121 r
->io_header
.host_status
== SG_ERR_DID_BUS_BUSY
||
122 r
->io_header
.host_status
== SG_ERR_DID_TIME_OUT
||
123 (r
->io_header
.driver_status
& SG_ERR_DRIVER_TIMEOUT
)) {
125 BADF("Driver Timeout\n");
126 } else if (r
->io_header
.host_status
) {
127 status
= CHECK_CONDITION
;
128 scsi_req_build_sense(&r
->req
, SENSE_CODE(I_T_NEXUS_LOSS
));
129 } else if (r
->io_header
.status
) {
130 status
= r
->io_header
.status
;
131 } else if (r
->io_header
.driver_status
& SG_ERR_DRIVER_SENSE
) {
132 status
= CHECK_CONDITION
;
137 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
138 r
, r
->req
.tag
, status
);
140 scsi_req_complete(&r
->req
, status
);
142 scsi_req_unref(&r
->req
);
145 static int execute_command(BlockBackend
*blk
,
146 SCSIGenericReq
*r
, int direction
,
147 BlockCompletionFunc
*complete
)
149 r
->io_header
.interface_id
= 'S';
150 r
->io_header
.dxfer_direction
= direction
;
151 r
->io_header
.dxferp
= r
->buf
;
152 r
->io_header
.dxfer_len
= r
->buflen
;
153 r
->io_header
.cmdp
= r
->req
.cmd
.buf
;
154 r
->io_header
.cmd_len
= r
->req
.cmd
.len
;
155 r
->io_header
.mx_sb_len
= sizeof(r
->req
.sense
);
156 r
->io_header
.sbp
= r
->req
.sense
;
157 r
->io_header
.timeout
= MAX_UINT
;
158 r
->io_header
.usr_ptr
= r
;
159 r
->io_header
.flags
|= SG_FLAG_DIRECT_IO
;
161 r
->req
.aiocb
= blk_aio_ioctl(blk
, SG_IO
, &r
->io_header
, complete
, r
);
162 if (r
->req
.aiocb
== NULL
) {
169 static void scsi_read_complete(void * opaque
, int ret
)
171 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
172 SCSIDevice
*s
= r
->req
.dev
;
176 if (ret
|| r
->req
.io_canceled
) {
177 scsi_command_complete(r
, ret
);
180 len
= r
->io_header
.dxfer_len
- r
->io_header
.resid
;
181 DPRINTF("Data ready tag=0x%x len=%d\n", r
->req
.tag
, len
);
185 scsi_command_complete(r
, 0);
187 /* Snoop READ CAPACITY output to set the blocksize. */
188 if (r
->req
.cmd
.buf
[0] == READ_CAPACITY_10
&&
189 (ldl_be_p(&r
->buf
[0]) != 0xffffffffU
|| s
->max_lba
== 0)) {
190 s
->blocksize
= ldl_be_p(&r
->buf
[4]);
191 s
->max_lba
= ldl_be_p(&r
->buf
[0]) & 0xffffffffULL
;
192 } else if (r
->req
.cmd
.buf
[0] == SERVICE_ACTION_IN_16
&&
193 (r
->req
.cmd
.buf
[1] & 31) == SAI_READ_CAPACITY_16
) {
194 s
->blocksize
= ldl_be_p(&r
->buf
[8]);
195 s
->max_lba
= ldq_be_p(&r
->buf
[0]);
197 blk_set_guest_block_size(s
->conf
.blk
, s
->blocksize
);
199 scsi_req_data(&r
->req
, len
);
200 scsi_req_unref(&r
->req
);
204 /* Read more data from scsi device into buffer. */
205 static void scsi_read_data(SCSIRequest
*req
)
207 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
208 SCSIDevice
*s
= r
->req
.dev
;
211 DPRINTF("scsi_read_data 0x%x\n", req
->tag
);
213 /* The request is used as the AIO opaque value, so add a ref. */
214 scsi_req_ref(&r
->req
);
216 scsi_command_complete(r
, 0);
220 ret
= execute_command(s
->conf
.blk
, r
, SG_DXFER_FROM_DEV
,
223 scsi_command_complete(r
, ret
);
227 static void scsi_write_complete(void * opaque
, int ret
)
229 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
230 SCSIDevice
*s
= r
->req
.dev
;
232 DPRINTF("scsi_write_complete() ret = %d\n", ret
);
234 if (ret
|| r
->req
.io_canceled
) {
235 scsi_command_complete(r
, ret
);
239 if (r
->req
.cmd
.buf
[0] == MODE_SELECT
&& r
->req
.cmd
.buf
[4] == 12 &&
240 s
->type
== TYPE_TAPE
) {
241 s
->blocksize
= (r
->buf
[9] << 16) | (r
->buf
[10] << 8) | r
->buf
[11];
242 DPRINTF("block size %d\n", s
->blocksize
);
245 scsi_command_complete(r
, ret
);
248 /* Write data to a scsi device. Returns nonzero on failure.
249 The transfer may complete asynchronously. */
250 static void scsi_write_data(SCSIRequest
*req
)
252 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
253 SCSIDevice
*s
= r
->req
.dev
;
256 DPRINTF("scsi_write_data 0x%x\n", req
->tag
);
259 scsi_req_data(&r
->req
, r
->len
);
263 /* The request is used as the AIO opaque value, so add a ref. */
264 scsi_req_ref(&r
->req
);
265 ret
= execute_command(s
->conf
.blk
, r
, SG_DXFER_TO_DEV
, scsi_write_complete
);
267 scsi_command_complete(r
, ret
);
271 /* Return a pointer to the data buffer. */
272 static uint8_t *scsi_get_buf(SCSIRequest
*req
)
274 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
279 /* Execute a scsi command. Returns the length of the data expected by the
280 command. This will be Positive for data transfers from the device
281 (eg. disk reads), negative for transfers to the device (eg. disk writes),
282 and zero if the command does not transfer any data. */
284 static int32_t scsi_send_command(SCSIRequest
*req
, uint8_t *cmd
)
286 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
287 SCSIDevice
*s
= r
->req
.dev
;
293 for (i
= 1; i
< r
->req
.cmd
.len
; i
++) {
294 printf(" 0x%02x", cmd
[i
]);
300 if (r
->req
.cmd
.xfer
== 0) {
305 /* The request is used as the AIO opaque value, so add a ref. */
306 scsi_req_ref(&r
->req
);
307 ret
= execute_command(s
->conf
.blk
, r
, SG_DXFER_NONE
,
308 scsi_command_complete
);
310 scsi_command_complete(r
, ret
);
316 if (r
->buflen
!= r
->req
.cmd
.xfer
) {
319 r
->buf
= g_malloc(r
->req
.cmd
.xfer
);
320 r
->buflen
= r
->req
.cmd
.xfer
;
323 memset(r
->buf
, 0, r
->buflen
);
324 r
->len
= r
->req
.cmd
.xfer
;
325 if (r
->req
.cmd
.mode
== SCSI_XFER_TO_DEV
) {
327 return -r
->req
.cmd
.xfer
;
329 return r
->req
.cmd
.xfer
;
333 static int get_stream_blocksize(BlockBackend
*blk
)
338 sg_io_hdr_t io_header
;
341 memset(cmd
, 0, sizeof(cmd
));
342 memset(buf
, 0, sizeof(buf
));
344 cmd
[4] = sizeof(buf
);
346 memset(&io_header
, 0, sizeof(io_header
));
347 io_header
.interface_id
= 'S';
348 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
349 io_header
.dxfer_len
= sizeof(buf
);
350 io_header
.dxferp
= buf
;
351 io_header
.cmdp
= cmd
;
352 io_header
.cmd_len
= sizeof(cmd
);
353 io_header
.mx_sb_len
= sizeof(sensebuf
);
354 io_header
.sbp
= sensebuf
;
355 io_header
.timeout
= 6000; /* XXX */
357 ret
= blk_ioctl(blk
, SG_IO
, &io_header
);
358 if (ret
< 0 || io_header
.driver_status
|| io_header
.host_status
) {
361 return (buf
[9] << 16) | (buf
[10] << 8) | buf
[11];
364 static void scsi_generic_reset(DeviceState
*dev
)
366 SCSIDevice
*s
= SCSI_DEVICE(dev
);
368 scsi_device_purge_requests(s
, SENSE_CODE(RESET
));
371 static void scsi_generic_realize(SCSIDevice
*s
, Error
**errp
)
375 struct sg_scsi_id scsiid
;
378 error_setg(errp
, "drive property not set");
382 if (blk_get_on_error(s
->conf
.blk
, 0) != BLOCKDEV_ON_ERROR_ENOSPC
) {
383 error_setg(errp
, "Device doesn't support drive option werror");
386 if (blk_get_on_error(s
->conf
.blk
, 1) != BLOCKDEV_ON_ERROR_REPORT
) {
387 error_setg(errp
, "Device doesn't support drive option rerror");
391 /* check we are using a driver managing SG_IO (version 3 and after */
392 rc
= blk_ioctl(s
->conf
.blk
, SG_GET_VERSION_NUM
, &sg_version
);
394 error_setg(errp
, "cannot get SG_IO version number: %s. "
395 "Is this a SCSI device?",
399 if (sg_version
< 30000) {
400 error_setg(errp
, "scsi generic interface too old");
404 /* get LUN of the /dev/sg? */
405 if (blk_ioctl(s
->conf
.blk
, SG_GET_SCSI_ID
, &scsiid
)) {
406 error_setg(errp
, "SG_GET_SCSI_ID ioctl failed");
410 /* define device state */
411 s
->type
= scsiid
.scsi_type
;
412 DPRINTF("device type %d\n", s
->type
);
416 s
->blocksize
= get_stream_blocksize(s
->conf
.blk
);
417 if (s
->blocksize
== -1) {
422 /* Make a guess for block devices, we'll fix it when the guest sends.
423 * READ CAPACITY. If they don't, they likely would assume these sizes
424 * anyway. (TODO: they could also send MODE SENSE).
435 DPRINTF("block size %d\n", s
->blocksize
);
438 const SCSIReqOps scsi_generic_req_ops
= {
439 .size
= sizeof(SCSIGenericReq
),
440 .free_req
= scsi_free_request
,
441 .send_command
= scsi_send_command
,
442 .read_data
= scsi_read_data
,
443 .write_data
= scsi_write_data
,
444 .get_buf
= scsi_get_buf
,
445 .load_request
= scsi_generic_load_request
,
446 .save_request
= scsi_generic_save_request
,
449 static SCSIRequest
*scsi_new_request(SCSIDevice
*d
, uint32_t tag
, uint32_t lun
,
450 uint8_t *buf
, void *hba_private
)
454 req
= scsi_req_alloc(&scsi_generic_req_ops
, d
, tag
, lun
, hba_private
);
458 static Property scsi_generic_properties
[] = {
459 DEFINE_PROP_DRIVE("drive", SCSIDevice
, conf
.blk
),
460 DEFINE_PROP_END_OF_LIST(),
463 static int scsi_generic_parse_cdb(SCSIDevice
*dev
, SCSICommand
*cmd
,
464 uint8_t *buf
, void *hba_private
)
466 return scsi_bus_parse_cdb(dev
, cmd
, buf
, hba_private
);
469 static void scsi_generic_class_initfn(ObjectClass
*klass
, void *data
)
471 DeviceClass
*dc
= DEVICE_CLASS(klass
);
472 SCSIDeviceClass
*sc
= SCSI_DEVICE_CLASS(klass
);
474 sc
->realize
= scsi_generic_realize
;
475 sc
->alloc_req
= scsi_new_request
;
476 sc
->parse_cdb
= scsi_generic_parse_cdb
;
477 dc
->fw_name
= "disk";
478 dc
->desc
= "pass through generic scsi device (/dev/sg*)";
479 dc
->reset
= scsi_generic_reset
;
480 dc
->props
= scsi_generic_properties
;
481 dc
->vmsd
= &vmstate_scsi_device
;
484 static const TypeInfo scsi_generic_info
= {
485 .name
= "scsi-generic",
486 .parent
= TYPE_SCSI_DEVICE
,
487 .instance_size
= sizeof(SCSIDevice
),
488 .class_init
= scsi_generic_class_initfn
,
491 static void scsi_generic_register_types(void)
493 type_register_static(&scsi_generic_info
);
496 type_init(scsi_generic_register_types
)
498 #endif /* __linux__ */