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 licenced under the LGPL.
14 #include "qemu-common.h"
15 #include "qemu-error.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 "scsi-defs.h"
40 #define SCSI_SENSE_BUF_SIZE 96
42 #define SG_ERR_DRIVER_TIMEOUT 0x06
43 #define SG_ERR_DRIVER_SENSE 0x08
46 #define MAX_UINT ((unsigned int)-1)
49 typedef struct SCSIGenericState SCSIGenericState
;
51 typedef struct SCSIGenericReq
{
56 sg_io_hdr_t io_header
;
59 struct SCSIGenericState
65 uint8_t sensebuf
[SCSI_SENSE_BUF_SIZE
];
69 static void scsi_set_sense(SCSIGenericState
*s
, SCSISense sense
)
71 s
->senselen
= scsi_build_sense(sense
, s
->sensebuf
, SCSI_SENSE_BUF_SIZE
, 0);
72 s
->driver_status
= SG_ERR_DRIVER_SENSE
;
75 static void scsi_clear_sense(SCSIGenericState
*s
)
77 memset(s
->sensebuf
, 0, SCSI_SENSE_BUF_SIZE
);
82 static SCSIRequest
*scsi_new_request(SCSIDevice
*d
, uint32_t tag
, uint32_t lun
)
86 req
= scsi_req_alloc(sizeof(SCSIGenericReq
), d
, tag
, lun
);
90 static void scsi_free_request(SCSIRequest
*req
)
92 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
97 /* Helper function for command completion. */
98 static void scsi_command_complete(void *opaque
, int ret
)
100 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
101 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
104 s
->driver_status
= r
->io_header
.driver_status
;
105 if (s
->driver_status
& SG_ERR_DRIVER_SENSE
)
106 s
->senselen
= r
->io_header
.sb_len_wr
;
111 r
->req
.status
= CHECK_CONDITION
;
112 scsi_set_sense(s
, SENSE_CODE(INVALID_FIELD
));
115 r
->req
.status
= CHECK_CONDITION
;
116 scsi_set_sense(s
, SENSE_CODE(TARGET_FAILURE
));
119 r
->req
.status
= CHECK_CONDITION
;
120 scsi_set_sense(s
, SENSE_CODE(IO_ERROR
));
124 if (s
->driver_status
& SG_ERR_DRIVER_TIMEOUT
) {
125 r
->req
.status
= BUSY
;
126 BADF("Driver Timeout\n");
127 } else if (r
->io_header
.status
)
128 r
->req
.status
= r
->io_header
.status
;
129 else if (s
->driver_status
& SG_ERR_DRIVER_SENSE
)
130 r
->req
.status
= CHECK_CONDITION
;
132 r
->req
.status
= GOOD
;
134 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
135 r
, r
->req
.tag
, r
->req
.status
);
137 scsi_req_complete(&r
->req
);
140 /* Cancel a pending data transfer. */
141 static void scsi_cancel_io(SCSIRequest
*req
)
143 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
145 DPRINTF("Cancel tag=0x%x\n", req
->tag
);
147 bdrv_aio_cancel(r
->req
.aiocb
);
152 static int execute_command(BlockDriverState
*bdrv
,
153 SCSIGenericReq
*r
, int direction
,
154 BlockDriverCompletionFunc
*complete
)
156 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
158 r
->io_header
.interface_id
= 'S';
159 r
->io_header
.dxfer_direction
= direction
;
160 r
->io_header
.dxferp
= r
->buf
;
161 r
->io_header
.dxfer_len
= r
->buflen
;
162 r
->io_header
.cmdp
= r
->req
.cmd
.buf
;
163 r
->io_header
.cmd_len
= r
->req
.cmd
.len
;
164 r
->io_header
.mx_sb_len
= sizeof(s
->sensebuf
);
165 r
->io_header
.sbp
= s
->sensebuf
;
166 r
->io_header
.timeout
= MAX_UINT
;
167 r
->io_header
.usr_ptr
= r
;
168 r
->io_header
.flags
|= SG_FLAG_DIRECT_IO
;
170 r
->req
.aiocb
= bdrv_aio_ioctl(bdrv
, SG_IO
, &r
->io_header
, complete
, r
);
171 if (r
->req
.aiocb
== NULL
) {
172 BADF("execute_command: read failed !\n");
179 static void scsi_read_complete(void * opaque
, int ret
)
181 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
186 DPRINTF("IO error ret %d\n", ret
);
187 scsi_command_complete(r
, ret
);
190 len
= r
->io_header
.dxfer_len
- r
->io_header
.resid
;
191 DPRINTF("Data ready tag=0x%x len=%d\n", r
->req
.tag
, len
);
195 scsi_command_complete(r
, 0);
197 scsi_req_data(&r
->req
, len
);
201 /* Read more data from scsi device into buffer. */
202 static void scsi_read_data(SCSIRequest
*req
)
204 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
205 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
208 DPRINTF("scsi_read_data 0x%x\n", req
->tag
);
210 scsi_command_complete(r
, 0);
214 if (r
->req
.cmd
.buf
[0] == REQUEST_SENSE
&& s
->driver_status
& SG_ERR_DRIVER_SENSE
)
216 s
->senselen
= MIN(r
->len
, s
->senselen
);
217 memcpy(r
->buf
, s
->sensebuf
, s
->senselen
);
218 r
->io_header
.driver_status
= 0;
219 r
->io_header
.status
= 0;
220 r
->io_header
.dxfer_len
= s
->senselen
;
222 DPRINTF("Data ready tag=0x%x len=%d\n", r
->req
.tag
, s
->senselen
);
223 DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
224 r
->buf
[0], r
->buf
[1], r
->buf
[2], r
->buf
[3],
225 r
->buf
[4], r
->buf
[5], r
->buf
[6], r
->buf
[7]);
226 scsi_req_data(&r
->req
, s
->senselen
);
227 /* Clear sensebuf after REQUEST_SENSE */
232 ret
= execute_command(s
->bs
, r
, SG_DXFER_FROM_DEV
, scsi_read_complete
);
234 scsi_command_complete(r
, ret
);
239 static void scsi_write_complete(void * opaque
, int ret
)
241 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
242 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
244 DPRINTF("scsi_write_complete() ret = %d\n", ret
);
247 DPRINTF("IO error\n");
248 scsi_command_complete(r
, ret
);
252 if (r
->req
.cmd
.buf
[0] == MODE_SELECT
&& r
->req
.cmd
.buf
[4] == 12 &&
253 s
->qdev
.type
== TYPE_TAPE
) {
254 s
->qdev
.blocksize
= (r
->buf
[9] << 16) | (r
->buf
[10] << 8) | r
->buf
[11];
255 DPRINTF("block size %d\n", s
->qdev
.blocksize
);
258 scsi_command_complete(r
, ret
);
261 /* Write data to a scsi device. Returns nonzero on failure.
262 The transfer may complete asynchronously. */
263 static int scsi_write_data(SCSIRequest
*req
)
265 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, req
->dev
);
266 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
269 DPRINTF("scsi_write_data 0x%x\n", req
->tag
);
272 scsi_req_data(&r
->req
, r
->len
);
276 ret
= execute_command(s
->bs
, r
, SG_DXFER_TO_DEV
, scsi_write_complete
);
278 scsi_command_complete(r
, ret
);
285 /* Return a pointer to the data buffer. */
286 static uint8_t *scsi_get_buf(SCSIRequest
*req
)
288 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
293 static void scsi_req_fixup(SCSIRequest
*req
)
295 switch(req
->cmd
.buf
[0]) {
297 req
->cmd
.buf
[1] &= ~0x08; /* disable FUA */
300 req
->cmd
.buf
[1] &= ~0x08; /* disable FUA */
304 if (req
->dev
->type
== TYPE_TAPE
) {
305 /* force IMMED, otherwise qemu waits end of command */
306 req
->cmd
.buf
[1] = 0x01;
312 /* Execute a scsi command. Returns the length of the data expected by the
313 command. This will be Positive for data transfers from the device
314 (eg. disk reads), negative for transfers to the device (eg. disk writes),
315 and zero if the command does not transfer any data. */
317 static int32_t scsi_send_command(SCSIRequest
*req
, uint8_t *cmd
)
319 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, req
->dev
);
320 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
323 scsi_req_enqueue(req
);
324 if (cmd
[0] != REQUEST_SENSE
&&
325 (req
->lun
!= s
->lun
|| (cmd
[1] >> 5) != s
->lun
)) {
326 DPRINTF("Unimplemented LUN %d\n", req
->lun
? req
->lun
: cmd
[1] >> 5);
327 scsi_set_sense(s
, SENSE_CODE(LUN_NOT_SUPPORTED
));
328 r
->req
.status
= CHECK_CONDITION
;
329 scsi_req_complete(&r
->req
);
333 if (-1 == scsi_req_parse(&r
->req
, cmd
)) {
334 BADF("Unsupported command length, command %x\n", cmd
[0]);
335 scsi_command_complete(r
, -EINVAL
);
338 scsi_req_fixup(&r
->req
);
340 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun
, tag
,
341 r
->req
.cmd
.xfer
, cmd
[0]);
346 for (i
= 1; i
< r
->req
.cmd
.len
; i
++) {
347 printf(" 0x%02x", cmd
[i
]);
353 if (r
->req
.cmd
.xfer
== 0) {
358 ret
= execute_command(s
->bs
, r
, SG_DXFER_NONE
, scsi_command_complete
);
360 scsi_command_complete(r
, ret
);
366 if (r
->buflen
!= r
->req
.cmd
.xfer
) {
369 r
->buf
= qemu_malloc(r
->req
.cmd
.xfer
);
370 r
->buflen
= r
->req
.cmd
.xfer
;
373 memset(r
->buf
, 0, r
->buflen
);
374 r
->len
= r
->req
.cmd
.xfer
;
375 if (r
->req
.cmd
.mode
== SCSI_XFER_TO_DEV
) {
377 return -r
->req
.cmd
.xfer
;
379 return r
->req
.cmd
.xfer
;
383 static int get_blocksize(BlockDriverState
*bdrv
)
388 sg_io_hdr_t io_header
;
391 memset(cmd
, 0, sizeof(cmd
));
392 memset(buf
, 0, sizeof(buf
));
393 cmd
[0] = READ_CAPACITY
;
395 memset(&io_header
, 0, sizeof(io_header
));
396 io_header
.interface_id
= 'S';
397 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
398 io_header
.dxfer_len
= sizeof(buf
);
399 io_header
.dxferp
= buf
;
400 io_header
.cmdp
= cmd
;
401 io_header
.cmd_len
= sizeof(cmd
);
402 io_header
.mx_sb_len
= sizeof(sensebuf
);
403 io_header
.sbp
= sensebuf
;
404 io_header
.timeout
= 6000; /* XXX */
406 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
410 return (buf
[4] << 24) | (buf
[5] << 16) | (buf
[6] << 8) | buf
[7];
413 static int get_stream_blocksize(BlockDriverState
*bdrv
)
418 sg_io_hdr_t io_header
;
421 memset(cmd
, 0, sizeof(cmd
));
422 memset(buf
, 0, sizeof(buf
));
424 cmd
[4] = sizeof(buf
);
426 memset(&io_header
, 0, sizeof(io_header
));
427 io_header
.interface_id
= 'S';
428 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
429 io_header
.dxfer_len
= sizeof(buf
);
430 io_header
.dxferp
= buf
;
431 io_header
.cmdp
= cmd
;
432 io_header
.cmd_len
= sizeof(cmd
);
433 io_header
.mx_sb_len
= sizeof(sensebuf
);
434 io_header
.sbp
= sensebuf
;
435 io_header
.timeout
= 6000; /* XXX */
437 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
441 return (buf
[9] << 16) | (buf
[10] << 8) | buf
[11];
444 static void scsi_generic_reset(DeviceState
*dev
)
446 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
.qdev
, dev
);
448 scsi_device_purge_requests(&s
->qdev
);
451 static void scsi_destroy(SCSIDevice
*d
)
453 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
455 scsi_device_purge_requests(&s
->qdev
);
456 blockdev_mark_auto_del(s
->qdev
.conf
.bs
);
459 static int scsi_generic_initfn(SCSIDevice
*dev
)
461 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, dev
);
463 struct sg_scsi_id scsiid
;
465 if (!s
->qdev
.conf
.bs
) {
466 error_report("scsi-generic: drive property not set");
469 s
->bs
= s
->qdev
.conf
.bs
;
471 /* check we are really using a /dev/sg* file */
472 if (!bdrv_is_sg(s
->bs
)) {
473 error_report("scsi-generic: not /dev/sg*");
477 if (bdrv_get_on_error(s
->bs
, 0) != BLOCK_ERR_STOP_ENOSPC
) {
478 error_report("Device doesn't support drive option werror");
481 if (bdrv_get_on_error(s
->bs
, 1) != BLOCK_ERR_REPORT
) {
482 error_report("Device doesn't support drive option rerror");
486 /* check we are using a driver managing SG_IO (version 3 and after */
487 if (bdrv_ioctl(s
->bs
, SG_GET_VERSION_NUM
, &sg_version
) < 0 ||
488 sg_version
< 30000) {
489 error_report("scsi-generic: scsi generic interface too old");
493 /* get LUN of the /dev/sg? */
494 if (bdrv_ioctl(s
->bs
, SG_GET_SCSI_ID
, &scsiid
)) {
495 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
499 /* define device state */
501 DPRINTF("LUN %d\n", s
->lun
);
502 s
->qdev
.type
= scsiid
.scsi_type
;
503 DPRINTF("device type %d\n", s
->qdev
.type
);
504 if (s
->qdev
.type
== TYPE_TAPE
) {
505 s
->qdev
.blocksize
= get_stream_blocksize(s
->bs
);
506 if (s
->qdev
.blocksize
== -1)
507 s
->qdev
.blocksize
= 0;
509 s
->qdev
.blocksize
= get_blocksize(s
->bs
);
510 /* removable media returns 0 if not present */
511 if (s
->qdev
.blocksize
<= 0) {
512 if (s
->qdev
.type
== TYPE_ROM
|| s
->qdev
.type
== TYPE_WORM
)
513 s
->qdev
.blocksize
= 2048;
515 s
->qdev
.blocksize
= 512;
518 DPRINTF("block size %d\n", s
->qdev
.blocksize
);
519 s
->driver_status
= 0;
520 memset(s
->sensebuf
, 0, sizeof(s
->sensebuf
));
521 bdrv_set_removable(s
->bs
, 0);
525 static SCSIDeviceInfo scsi_generic_info
= {
526 .qdev
.name
= "scsi-generic",
527 .qdev
.desc
= "pass through generic scsi device (/dev/sg*)",
528 .qdev
.size
= sizeof(SCSIGenericState
),
529 .qdev
.reset
= scsi_generic_reset
,
530 .init
= scsi_generic_initfn
,
531 .destroy
= scsi_destroy
,
532 .alloc_req
= scsi_new_request
,
533 .free_req
= scsi_free_request
,
534 .send_command
= scsi_send_command
,
535 .read_data
= scsi_read_data
,
536 .write_data
= scsi_write_data
,
537 .cancel_io
= scsi_cancel_io
,
538 .get_buf
= scsi_get_buf
,
539 .qdev
.props
= (Property
[]) {
540 DEFINE_BLOCK_PROPERTIES(SCSIGenericState
, qdev
.conf
),
541 DEFINE_PROP_END_OF_LIST(),
545 static void scsi_generic_register_devices(void)
547 scsi_qdev_register(&scsi_generic_info
);
549 device_init(scsi_generic_register_devices
)
551 #endif /* __linux__ */