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 int scsi_get_sense(SCSIRequest
*req
, uint8_t *outbuf
, int len
)
84 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, req
->dev
);
85 int size
= SCSI_SENSE_BUF_SIZE
;
87 if (!(s
->driver_status
& SG_ERR_DRIVER_SENSE
)) {
88 size
= scsi_build_sense(SENSE_CODE(NO_SENSE
), s
->sensebuf
,
89 SCSI_SENSE_BUF_SIZE
, 0);
94 memcpy(outbuf
, s
->sensebuf
, size
);
99 static SCSIRequest
*scsi_new_request(SCSIDevice
*d
, uint32_t tag
, uint32_t lun
)
103 req
= scsi_req_alloc(sizeof(SCSIGenericReq
), d
, tag
, lun
);
107 static void scsi_free_request(SCSIRequest
*req
)
109 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
114 /* Helper function for command completion. */
115 static void scsi_command_complete(void *opaque
, int ret
)
117 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
118 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
121 s
->driver_status
= r
->io_header
.driver_status
;
122 if (s
->driver_status
& SG_ERR_DRIVER_SENSE
)
123 s
->senselen
= r
->io_header
.sb_len_wr
;
128 r
->req
.status
= TASK_SET_FULL
;
131 r
->req
.status
= CHECK_CONDITION
;
132 scsi_set_sense(s
, SENSE_CODE(INVALID_FIELD
));
135 r
->req
.status
= CHECK_CONDITION
;
136 scsi_set_sense(s
, SENSE_CODE(TARGET_FAILURE
));
139 r
->req
.status
= CHECK_CONDITION
;
140 scsi_set_sense(s
, SENSE_CODE(IO_ERROR
));
144 if (s
->driver_status
& SG_ERR_DRIVER_TIMEOUT
) {
145 r
->req
.status
= BUSY
;
146 BADF("Driver Timeout\n");
147 } else if (r
->io_header
.status
)
148 r
->req
.status
= r
->io_header
.status
;
149 else if (s
->driver_status
& SG_ERR_DRIVER_SENSE
)
150 r
->req
.status
= CHECK_CONDITION
;
152 r
->req
.status
= GOOD
;
154 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
155 r
, r
->req
.tag
, r
->req
.status
);
157 scsi_req_complete(&r
->req
);
160 /* Cancel a pending data transfer. */
161 static void scsi_cancel_io(SCSIRequest
*req
)
163 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
165 DPRINTF("Cancel tag=0x%x\n", req
->tag
);
167 bdrv_aio_cancel(r
->req
.aiocb
);
172 static int execute_command(BlockDriverState
*bdrv
,
173 SCSIGenericReq
*r
, int direction
,
174 BlockDriverCompletionFunc
*complete
)
176 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
178 r
->io_header
.interface_id
= 'S';
179 r
->io_header
.dxfer_direction
= direction
;
180 r
->io_header
.dxferp
= r
->buf
;
181 r
->io_header
.dxfer_len
= r
->buflen
;
182 r
->io_header
.cmdp
= r
->req
.cmd
.buf
;
183 r
->io_header
.cmd_len
= r
->req
.cmd
.len
;
184 r
->io_header
.mx_sb_len
= sizeof(s
->sensebuf
);
185 r
->io_header
.sbp
= s
->sensebuf
;
186 r
->io_header
.timeout
= MAX_UINT
;
187 r
->io_header
.usr_ptr
= r
;
188 r
->io_header
.flags
|= SG_FLAG_DIRECT_IO
;
190 r
->req
.aiocb
= bdrv_aio_ioctl(bdrv
, SG_IO
, &r
->io_header
, complete
, r
);
191 if (r
->req
.aiocb
== NULL
) {
192 BADF("execute_command: read failed !\n");
199 static void scsi_read_complete(void * opaque
, int ret
)
201 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
206 DPRINTF("IO error ret %d\n", ret
);
207 scsi_command_complete(r
, ret
);
210 len
= r
->io_header
.dxfer_len
- r
->io_header
.resid
;
211 DPRINTF("Data ready tag=0x%x len=%d\n", r
->req
.tag
, len
);
215 scsi_command_complete(r
, 0);
217 scsi_req_data(&r
->req
, len
);
221 /* Read more data from scsi device into buffer. */
222 static void scsi_read_data(SCSIRequest
*req
)
224 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
225 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
228 DPRINTF("scsi_read_data 0x%x\n", req
->tag
);
230 scsi_command_complete(r
, 0);
234 if (r
->req
.cmd
.buf
[0] == REQUEST_SENSE
&& s
->driver_status
& SG_ERR_DRIVER_SENSE
)
236 s
->senselen
= MIN(r
->len
, s
->senselen
);
237 memcpy(r
->buf
, s
->sensebuf
, s
->senselen
);
238 r
->io_header
.driver_status
= 0;
239 r
->io_header
.status
= 0;
240 r
->io_header
.dxfer_len
= s
->senselen
;
242 DPRINTF("Data ready tag=0x%x len=%d\n", r
->req
.tag
, s
->senselen
);
243 DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
244 r
->buf
[0], r
->buf
[1], r
->buf
[2], r
->buf
[3],
245 r
->buf
[4], r
->buf
[5], r
->buf
[6], r
->buf
[7]);
246 scsi_req_data(&r
->req
, s
->senselen
);
247 /* Clear sensebuf after REQUEST_SENSE */
252 ret
= execute_command(s
->bs
, r
, SG_DXFER_FROM_DEV
, scsi_read_complete
);
254 scsi_command_complete(r
, ret
);
259 static void scsi_write_complete(void * opaque
, int ret
)
261 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
262 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
264 DPRINTF("scsi_write_complete() ret = %d\n", ret
);
267 DPRINTF("IO error\n");
268 scsi_command_complete(r
, ret
);
272 if (r
->req
.cmd
.buf
[0] == MODE_SELECT
&& r
->req
.cmd
.buf
[4] == 12 &&
273 s
->qdev
.type
== TYPE_TAPE
) {
274 s
->qdev
.blocksize
= (r
->buf
[9] << 16) | (r
->buf
[10] << 8) | r
->buf
[11];
275 DPRINTF("block size %d\n", s
->qdev
.blocksize
);
278 scsi_command_complete(r
, ret
);
281 /* Write data to a scsi device. Returns nonzero on failure.
282 The transfer may complete asynchronously. */
283 static void scsi_write_data(SCSIRequest
*req
)
285 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, req
->dev
);
286 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
289 DPRINTF("scsi_write_data 0x%x\n", req
->tag
);
292 scsi_req_data(&r
->req
, r
->len
);
296 ret
= execute_command(s
->bs
, r
, SG_DXFER_TO_DEV
, scsi_write_complete
);
298 scsi_command_complete(r
, ret
);
302 /* Return a pointer to the data buffer. */
303 static uint8_t *scsi_get_buf(SCSIRequest
*req
)
305 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
310 static void scsi_req_fixup(SCSIRequest
*req
)
312 switch(req
->cmd
.buf
[0]) {
314 req
->cmd
.buf
[1] &= ~0x08; /* disable FUA */
317 req
->cmd
.buf
[1] &= ~0x08; /* disable FUA */
321 if (req
->dev
->type
== TYPE_TAPE
) {
322 /* force IMMED, otherwise qemu waits end of command */
323 req
->cmd
.buf
[1] = 0x01;
329 /* Execute a scsi command. Returns the length of the data expected by the
330 command. This will be Positive for data transfers from the device
331 (eg. disk reads), negative for transfers to the device (eg. disk writes),
332 and zero if the command does not transfer any data. */
334 static int32_t scsi_send_command(SCSIRequest
*req
, uint8_t *cmd
)
336 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, req
->dev
);
337 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
340 if (cmd
[0] != REQUEST_SENSE
&&
341 (req
->lun
!= s
->lun
|| (cmd
[1] >> 5) != s
->lun
)) {
342 DPRINTF("Unimplemented LUN %d\n", req
->lun
? req
->lun
: cmd
[1] >> 5);
343 scsi_set_sense(s
, SENSE_CODE(LUN_NOT_SUPPORTED
));
344 r
->req
.status
= CHECK_CONDITION
;
345 scsi_req_complete(&r
->req
);
349 if (-1 == scsi_req_parse(&r
->req
, cmd
)) {
350 BADF("Unsupported command length, command %x\n", cmd
[0]);
351 scsi_command_complete(r
, -EINVAL
);
354 scsi_req_fixup(&r
->req
);
356 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun
, tag
,
357 r
->req
.cmd
.xfer
, cmd
[0]);
362 for (i
= 1; i
< r
->req
.cmd
.len
; i
++) {
363 printf(" 0x%02x", cmd
[i
]);
369 if (r
->req
.cmd
.xfer
== 0) {
374 ret
= execute_command(s
->bs
, r
, SG_DXFER_NONE
, scsi_command_complete
);
376 scsi_command_complete(r
, ret
);
382 if (r
->buflen
!= r
->req
.cmd
.xfer
) {
385 r
->buf
= qemu_malloc(r
->req
.cmd
.xfer
);
386 r
->buflen
= r
->req
.cmd
.xfer
;
389 memset(r
->buf
, 0, r
->buflen
);
390 r
->len
= r
->req
.cmd
.xfer
;
391 if (r
->req
.cmd
.mode
== SCSI_XFER_TO_DEV
) {
393 return -r
->req
.cmd
.xfer
;
395 return r
->req
.cmd
.xfer
;
399 static int get_blocksize(BlockDriverState
*bdrv
)
404 sg_io_hdr_t io_header
;
407 memset(cmd
, 0, sizeof(cmd
));
408 memset(buf
, 0, sizeof(buf
));
409 cmd
[0] = READ_CAPACITY
;
411 memset(&io_header
, 0, sizeof(io_header
));
412 io_header
.interface_id
= 'S';
413 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
414 io_header
.dxfer_len
= sizeof(buf
);
415 io_header
.dxferp
= buf
;
416 io_header
.cmdp
= cmd
;
417 io_header
.cmd_len
= sizeof(cmd
);
418 io_header
.mx_sb_len
= sizeof(sensebuf
);
419 io_header
.sbp
= sensebuf
;
420 io_header
.timeout
= 6000; /* XXX */
422 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
426 return (buf
[4] << 24) | (buf
[5] << 16) | (buf
[6] << 8) | buf
[7];
429 static int get_stream_blocksize(BlockDriverState
*bdrv
)
434 sg_io_hdr_t io_header
;
437 memset(cmd
, 0, sizeof(cmd
));
438 memset(buf
, 0, sizeof(buf
));
440 cmd
[4] = sizeof(buf
);
442 memset(&io_header
, 0, sizeof(io_header
));
443 io_header
.interface_id
= 'S';
444 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
445 io_header
.dxfer_len
= sizeof(buf
);
446 io_header
.dxferp
= buf
;
447 io_header
.cmdp
= cmd
;
448 io_header
.cmd_len
= sizeof(cmd
);
449 io_header
.mx_sb_len
= sizeof(sensebuf
);
450 io_header
.sbp
= sensebuf
;
451 io_header
.timeout
= 6000; /* XXX */
453 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
457 return (buf
[9] << 16) | (buf
[10] << 8) | buf
[11];
460 static void scsi_generic_reset(DeviceState
*dev
)
462 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
.qdev
, dev
);
464 scsi_device_purge_requests(&s
->qdev
);
467 static void scsi_destroy(SCSIDevice
*d
)
469 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
471 scsi_device_purge_requests(&s
->qdev
);
472 blockdev_mark_auto_del(s
->qdev
.conf
.bs
);
475 static int scsi_generic_initfn(SCSIDevice
*dev
)
477 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, dev
);
479 struct sg_scsi_id scsiid
;
481 if (!s
->qdev
.conf
.bs
) {
482 error_report("scsi-generic: drive property not set");
485 s
->bs
= s
->qdev
.conf
.bs
;
487 /* check we are really using a /dev/sg* file */
488 if (!bdrv_is_sg(s
->bs
)) {
489 error_report("scsi-generic: not /dev/sg*");
493 if (bdrv_get_on_error(s
->bs
, 0) != BLOCK_ERR_STOP_ENOSPC
) {
494 error_report("Device doesn't support drive option werror");
497 if (bdrv_get_on_error(s
->bs
, 1) != BLOCK_ERR_REPORT
) {
498 error_report("Device doesn't support drive option rerror");
502 /* check we are using a driver managing SG_IO (version 3 and after */
503 if (bdrv_ioctl(s
->bs
, SG_GET_VERSION_NUM
, &sg_version
) < 0 ||
504 sg_version
< 30000) {
505 error_report("scsi-generic: scsi generic interface too old");
509 /* get LUN of the /dev/sg? */
510 if (bdrv_ioctl(s
->bs
, SG_GET_SCSI_ID
, &scsiid
)) {
511 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
515 /* define device state */
517 DPRINTF("LUN %d\n", s
->lun
);
518 s
->qdev
.type
= scsiid
.scsi_type
;
519 DPRINTF("device type %d\n", s
->qdev
.type
);
520 if (s
->qdev
.type
== TYPE_TAPE
) {
521 s
->qdev
.blocksize
= get_stream_blocksize(s
->bs
);
522 if (s
->qdev
.blocksize
== -1)
523 s
->qdev
.blocksize
= 0;
525 s
->qdev
.blocksize
= get_blocksize(s
->bs
);
526 /* removable media returns 0 if not present */
527 if (s
->qdev
.blocksize
<= 0) {
528 if (s
->qdev
.type
== TYPE_ROM
|| s
->qdev
.type
== TYPE_WORM
)
529 s
->qdev
.blocksize
= 2048;
531 s
->qdev
.blocksize
= 512;
534 DPRINTF("block size %d\n", s
->qdev
.blocksize
);
535 s
->driver_status
= 0;
536 memset(s
->sensebuf
, 0, sizeof(s
->sensebuf
));
537 bdrv_set_removable(s
->bs
, 0);
541 static SCSIDeviceInfo scsi_generic_info
= {
542 .qdev
.name
= "scsi-generic",
543 .qdev
.desc
= "pass through generic scsi device (/dev/sg*)",
544 .qdev
.size
= sizeof(SCSIGenericState
),
545 .qdev
.reset
= scsi_generic_reset
,
546 .init
= scsi_generic_initfn
,
547 .destroy
= scsi_destroy
,
548 .alloc_req
= scsi_new_request
,
549 .free_req
= scsi_free_request
,
550 .send_command
= scsi_send_command
,
551 .read_data
= scsi_read_data
,
552 .write_data
= scsi_write_data
,
553 .cancel_io
= scsi_cancel_io
,
554 .get_buf
= scsi_get_buf
,
555 .get_sense
= scsi_get_sense
,
556 .qdev
.props
= (Property
[]) {
557 DEFINE_BLOCK_PROPERTIES(SCSIGenericState
, qdev
.conf
),
558 DEFINE_PROP_END_OF_LIST(),
562 static void scsi_generic_register_devices(void)
564 scsi_qdev_register(&scsi_generic_info
);
566 device_init(scsi_generic_register_devices
)
568 #endif /* __linux__ */