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/blockdev.h"
24 #define DPRINTF(fmt, ...) \
25 do { printf("scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
27 #define DPRINTF(fmt, ...) do {} while(0)
30 #define BADF(fmt, ...) \
31 do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
34 #include <sys/types.h>
38 #include "block/scsi.h"
40 #define SG_ERR_DRIVER_TIMEOUT 0x06
41 #define SG_ERR_DRIVER_SENSE 0x08
43 #define SG_ERR_DID_OK 0x00
44 #define SG_ERR_DID_NO_CONNECT 0x01
45 #define SG_ERR_DID_BUS_BUSY 0x02
46 #define SG_ERR_DID_TIME_OUT 0x03
49 #define MAX_UINT ((unsigned int)-1)
52 typedef struct SCSIGenericReq
{
57 sg_io_hdr_t io_header
;
60 static void scsi_generic_save_request(QEMUFile
*f
, SCSIRequest
*req
)
62 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
64 qemu_put_sbe32s(f
, &r
->buflen
);
65 if (r
->buflen
&& r
->req
.cmd
.mode
== SCSI_XFER_TO_DEV
) {
67 qemu_put_buffer(f
, r
->buf
, r
->req
.cmd
.xfer
);
71 static void scsi_generic_load_request(QEMUFile
*f
, SCSIRequest
*req
)
73 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
75 qemu_get_sbe32s(f
, &r
->buflen
);
76 if (r
->buflen
&& r
->req
.cmd
.mode
== SCSI_XFER_TO_DEV
) {
78 qemu_get_buffer(f
, r
->buf
, r
->req
.cmd
.xfer
);
82 static void scsi_free_request(SCSIRequest
*req
)
84 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
89 /* Helper function for command completion. */
90 static void scsi_command_complete(void *opaque
, int ret
)
93 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
96 if (r
->req
.io_canceled
) {
97 scsi_req_cancel_complete(&r
->req
);
100 if (r
->io_header
.driver_status
& SG_ERR_DRIVER_SENSE
) {
101 r
->req
.sense_len
= r
->io_header
.sb_len_wr
;
107 status
= TASK_SET_FULL
;
110 status
= CHECK_CONDITION
;
111 scsi_req_build_sense(&r
->req
, SENSE_CODE(TARGET_FAILURE
));
114 status
= CHECK_CONDITION
;
115 scsi_req_build_sense(&r
->req
, SENSE_CODE(IO_ERROR
));
119 if (r
->io_header
.host_status
== SG_ERR_DID_NO_CONNECT
||
120 r
->io_header
.host_status
== SG_ERR_DID_BUS_BUSY
||
121 r
->io_header
.host_status
== SG_ERR_DID_TIME_OUT
||
122 (r
->io_header
.driver_status
& SG_ERR_DRIVER_TIMEOUT
)) {
124 BADF("Driver Timeout\n");
125 } else if (r
->io_header
.host_status
) {
126 status
= CHECK_CONDITION
;
127 scsi_req_build_sense(&r
->req
, SENSE_CODE(I_T_NEXUS_LOSS
));
128 } else if (r
->io_header
.status
) {
129 status
= r
->io_header
.status
;
130 } else if (r
->io_header
.driver_status
& SG_ERR_DRIVER_SENSE
) {
131 status
= CHECK_CONDITION
;
136 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
137 r
, r
->req
.tag
, status
);
139 scsi_req_complete(&r
->req
, status
);
141 scsi_req_unref(&r
->req
);
144 static int execute_command(BlockDriverState
*bdrv
,
145 SCSIGenericReq
*r
, int direction
,
146 BlockDriverCompletionFunc
*complete
)
148 r
->io_header
.interface_id
= 'S';
149 r
->io_header
.dxfer_direction
= direction
;
150 r
->io_header
.dxferp
= r
->buf
;
151 r
->io_header
.dxfer_len
= r
->buflen
;
152 r
->io_header
.cmdp
= r
->req
.cmd
.buf
;
153 r
->io_header
.cmd_len
= r
->req
.cmd
.len
;
154 r
->io_header
.mx_sb_len
= sizeof(r
->req
.sense
);
155 r
->io_header
.sbp
= r
->req
.sense
;
156 r
->io_header
.timeout
= MAX_UINT
;
157 r
->io_header
.usr_ptr
= r
;
158 r
->io_header
.flags
|= SG_FLAG_DIRECT_IO
;
160 r
->req
.aiocb
= bdrv_aio_ioctl(bdrv
, SG_IO
, &r
->io_header
, complete
, r
);
161 if (r
->req
.aiocb
== NULL
) {
168 static void scsi_read_complete(void * opaque
, int ret
)
170 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
171 SCSIDevice
*s
= r
->req
.dev
;
175 if (ret
|| r
->req
.io_canceled
) {
176 scsi_command_complete(r
, ret
);
179 len
= r
->io_header
.dxfer_len
- r
->io_header
.resid
;
180 DPRINTF("Data ready tag=0x%x len=%d\n", r
->req
.tag
, len
);
184 scsi_command_complete(r
, 0);
186 /* Snoop READ CAPACITY output to set the blocksize. */
187 if (r
->req
.cmd
.buf
[0] == READ_CAPACITY_10
&&
188 (ldl_be_p(&r
->buf
[0]) != 0xffffffffU
|| s
->max_lba
== 0)) {
189 s
->blocksize
= ldl_be_p(&r
->buf
[4]);
190 s
->max_lba
= ldl_be_p(&r
->buf
[0]) & 0xffffffffULL
;
191 } else if (r
->req
.cmd
.buf
[0] == SERVICE_ACTION_IN_16
&&
192 (r
->req
.cmd
.buf
[1] & 31) == SAI_READ_CAPACITY_16
) {
193 s
->blocksize
= ldl_be_p(&r
->buf
[8]);
194 s
->max_lba
= ldq_be_p(&r
->buf
[0]);
196 bdrv_set_guest_block_size(s
->conf
.bs
, s
->blocksize
);
198 scsi_req_data(&r
->req
, len
);
199 scsi_req_unref(&r
->req
);
203 /* Read more data from scsi device into buffer. */
204 static void scsi_read_data(SCSIRequest
*req
)
206 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
207 SCSIDevice
*s
= r
->req
.dev
;
210 DPRINTF("scsi_read_data 0x%x\n", req
->tag
);
212 /* The request is used as the AIO opaque value, so add a ref. */
213 scsi_req_ref(&r
->req
);
215 scsi_command_complete(r
, 0);
219 ret
= execute_command(s
->conf
.bs
, r
, SG_DXFER_FROM_DEV
, scsi_read_complete
);
221 scsi_command_complete(r
, ret
);
225 static void scsi_write_complete(void * opaque
, int ret
)
227 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
228 SCSIDevice
*s
= r
->req
.dev
;
230 DPRINTF("scsi_write_complete() ret = %d\n", ret
);
232 if (ret
|| r
->req
.io_canceled
) {
233 scsi_command_complete(r
, ret
);
237 if (r
->req
.cmd
.buf
[0] == MODE_SELECT
&& r
->req
.cmd
.buf
[4] == 12 &&
238 s
->type
== TYPE_TAPE
) {
239 s
->blocksize
= (r
->buf
[9] << 16) | (r
->buf
[10] << 8) | r
->buf
[11];
240 DPRINTF("block size %d\n", s
->blocksize
);
243 scsi_command_complete(r
, ret
);
246 /* Write data to a scsi device. Returns nonzero on failure.
247 The transfer may complete asynchronously. */
248 static void scsi_write_data(SCSIRequest
*req
)
250 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
251 SCSIDevice
*s
= r
->req
.dev
;
254 DPRINTF("scsi_write_data 0x%x\n", req
->tag
);
257 scsi_req_data(&r
->req
, r
->len
);
261 /* The request is used as the AIO opaque value, so add a ref. */
262 scsi_req_ref(&r
->req
);
263 ret
= execute_command(s
->conf
.bs
, r
, SG_DXFER_TO_DEV
, scsi_write_complete
);
265 scsi_command_complete(r
, ret
);
269 /* Return a pointer to the data buffer. */
270 static uint8_t *scsi_get_buf(SCSIRequest
*req
)
272 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
277 /* Execute a scsi command. Returns the length of the data expected by the
278 command. This will be Positive for data transfers from the device
279 (eg. disk reads), negative for transfers to the device (eg. disk writes),
280 and zero if the command does not transfer any data. */
282 static int32_t scsi_send_command(SCSIRequest
*req
, uint8_t *cmd
)
284 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
285 SCSIDevice
*s
= r
->req
.dev
;
291 for (i
= 1; i
< r
->req
.cmd
.len
; i
++) {
292 printf(" 0x%02x", cmd
[i
]);
298 if (r
->req
.cmd
.xfer
== 0) {
303 /* The request is used as the AIO opaque value, so add a ref. */
304 scsi_req_ref(&r
->req
);
305 ret
= execute_command(s
->conf
.bs
, r
, SG_DXFER_NONE
, scsi_command_complete
);
307 scsi_command_complete(r
, ret
);
313 if (r
->buflen
!= r
->req
.cmd
.xfer
) {
316 r
->buf
= g_malloc(r
->req
.cmd
.xfer
);
317 r
->buflen
= r
->req
.cmd
.xfer
;
320 memset(r
->buf
, 0, r
->buflen
);
321 r
->len
= r
->req
.cmd
.xfer
;
322 if (r
->req
.cmd
.mode
== SCSI_XFER_TO_DEV
) {
324 return -r
->req
.cmd
.xfer
;
326 return r
->req
.cmd
.xfer
;
330 static int get_stream_blocksize(BlockDriverState
*bdrv
)
335 sg_io_hdr_t io_header
;
338 memset(cmd
, 0, sizeof(cmd
));
339 memset(buf
, 0, sizeof(buf
));
341 cmd
[4] = sizeof(buf
);
343 memset(&io_header
, 0, sizeof(io_header
));
344 io_header
.interface_id
= 'S';
345 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
346 io_header
.dxfer_len
= sizeof(buf
);
347 io_header
.dxferp
= buf
;
348 io_header
.cmdp
= cmd
;
349 io_header
.cmd_len
= sizeof(cmd
);
350 io_header
.mx_sb_len
= sizeof(sensebuf
);
351 io_header
.sbp
= sensebuf
;
352 io_header
.timeout
= 6000; /* XXX */
354 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
355 if (ret
< 0 || io_header
.driver_status
|| io_header
.host_status
) {
358 return (buf
[9] << 16) | (buf
[10] << 8) | buf
[11];
361 static void scsi_generic_reset(DeviceState
*dev
)
363 SCSIDevice
*s
= SCSI_DEVICE(dev
);
365 scsi_device_purge_requests(s
, SENSE_CODE(RESET
));
368 static void scsi_unrealize(SCSIDevice
*s
, Error
**errp
)
370 scsi_device_purge_requests(s
, SENSE_CODE(NO_SENSE
));
371 blockdev_mark_auto_del(s
->conf
.bs
);
374 static void scsi_generic_realize(SCSIDevice
*s
, Error
**errp
)
378 struct sg_scsi_id scsiid
;
381 error_setg(errp
, "drive property not set");
385 if (bdrv_get_on_error(s
->conf
.bs
, 0) != BLOCKDEV_ON_ERROR_ENOSPC
) {
386 error_setg(errp
, "Device doesn't support drive option werror");
389 if (bdrv_get_on_error(s
->conf
.bs
, 1) != BLOCKDEV_ON_ERROR_REPORT
) {
390 error_setg(errp
, "Device doesn't support drive option rerror");
394 /* check we are using a driver managing SG_IO (version 3 and after */
395 rc
= bdrv_ioctl(s
->conf
.bs
, SG_GET_VERSION_NUM
, &sg_version
);
397 error_setg(errp
, "cannot get SG_IO version number: %s. "
398 "Is this a SCSI device?",
402 if (sg_version
< 30000) {
403 error_setg(errp
, "scsi generic interface too old");
407 /* get LUN of the /dev/sg? */
408 if (bdrv_ioctl(s
->conf
.bs
, SG_GET_SCSI_ID
, &scsiid
)) {
409 error_setg(errp
, "SG_GET_SCSI_ID ioctl failed");
413 /* define device state */
414 s
->type
= scsiid
.scsi_type
;
415 DPRINTF("device type %d\n", s
->type
);
419 s
->blocksize
= get_stream_blocksize(s
->conf
.bs
);
420 if (s
->blocksize
== -1) {
425 /* Make a guess for block devices, we'll fix it when the guest sends.
426 * READ CAPACITY. If they don't, they likely would assume these sizes
427 * anyway. (TODO: they could also send MODE SENSE).
438 DPRINTF("block size %d\n", s
->blocksize
);
441 const SCSIReqOps scsi_generic_req_ops
= {
442 .size
= sizeof(SCSIGenericReq
),
443 .free_req
= scsi_free_request
,
444 .send_command
= scsi_send_command
,
445 .read_data
= scsi_read_data
,
446 .write_data
= scsi_write_data
,
447 .get_buf
= scsi_get_buf
,
448 .load_request
= scsi_generic_load_request
,
449 .save_request
= scsi_generic_save_request
,
452 static SCSIRequest
*scsi_new_request(SCSIDevice
*d
, uint32_t tag
, uint32_t lun
,
453 uint8_t *buf
, void *hba_private
)
457 req
= scsi_req_alloc(&scsi_generic_req_ops
, d
, tag
, lun
, hba_private
);
461 static Property scsi_generic_properties
[] = {
462 DEFINE_PROP_DRIVE("drive", SCSIDevice
, conf
.bs
),
463 DEFINE_PROP_END_OF_LIST(),
466 static int scsi_generic_parse_cdb(SCSIDevice
*dev
, SCSICommand
*cmd
,
467 uint8_t *buf
, void *hba_private
)
469 return scsi_bus_parse_cdb(dev
, cmd
, buf
, hba_private
);
472 static void scsi_generic_class_initfn(ObjectClass
*klass
, void *data
)
474 DeviceClass
*dc
= DEVICE_CLASS(klass
);
475 SCSIDeviceClass
*sc
= SCSI_DEVICE_CLASS(klass
);
477 sc
->realize
= scsi_generic_realize
;
478 sc
->unrealize
= scsi_unrealize
;
479 sc
->alloc_req
= scsi_new_request
;
480 sc
->parse_cdb
= scsi_generic_parse_cdb
;
481 dc
->fw_name
= "disk";
482 dc
->desc
= "pass through generic scsi device (/dev/sg*)";
483 dc
->reset
= scsi_generic_reset
;
484 dc
->props
= scsi_generic_properties
;
485 dc
->vmsd
= &vmstate_scsi_device
;
488 static const TypeInfo scsi_generic_info
= {
489 .name
= "scsi-generic",
490 .parent
= TYPE_SCSI_DEVICE
,
491 .instance_size
= sizeof(SCSIDevice
),
492 .class_init
= scsi_generic_class_initfn
,
495 static void scsi_generic_register_types(void)
497 type_register_static(&scsi_generic_info
);
500 type_init(scsi_generic_register_types
)
502 #endif /* __linux__ */