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
&& req
->lun
!= s
->lun
) {
341 DPRINTF("Unimplemented LUN %d\n", req
->lun
);
342 scsi_set_sense(s
, SENSE_CODE(LUN_NOT_SUPPORTED
));
343 r
->req
.status
= CHECK_CONDITION
;
344 scsi_req_complete(&r
->req
);
348 if (-1 == scsi_req_parse(&r
->req
, cmd
)) {
349 BADF("Unsupported command length, command %x\n", cmd
[0]);
350 scsi_command_complete(r
, -EINVAL
);
353 scsi_req_fixup(&r
->req
);
355 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun
, tag
,
356 r
->req
.cmd
.xfer
, cmd
[0]);
361 for (i
= 1; i
< r
->req
.cmd
.len
; i
++) {
362 printf(" 0x%02x", cmd
[i
]);
368 if (r
->req
.cmd
.xfer
== 0) {
373 ret
= execute_command(s
->bs
, r
, SG_DXFER_NONE
, scsi_command_complete
);
375 scsi_command_complete(r
, ret
);
381 if (r
->buflen
!= r
->req
.cmd
.xfer
) {
384 r
->buf
= qemu_malloc(r
->req
.cmd
.xfer
);
385 r
->buflen
= r
->req
.cmd
.xfer
;
388 memset(r
->buf
, 0, r
->buflen
);
389 r
->len
= r
->req
.cmd
.xfer
;
390 if (r
->req
.cmd
.mode
== SCSI_XFER_TO_DEV
) {
392 return -r
->req
.cmd
.xfer
;
394 return r
->req
.cmd
.xfer
;
398 static int get_blocksize(BlockDriverState
*bdrv
)
403 sg_io_hdr_t io_header
;
406 memset(cmd
, 0, sizeof(cmd
));
407 memset(buf
, 0, sizeof(buf
));
408 cmd
[0] = READ_CAPACITY
;
410 memset(&io_header
, 0, sizeof(io_header
));
411 io_header
.interface_id
= 'S';
412 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
413 io_header
.dxfer_len
= sizeof(buf
);
414 io_header
.dxferp
= buf
;
415 io_header
.cmdp
= cmd
;
416 io_header
.cmd_len
= sizeof(cmd
);
417 io_header
.mx_sb_len
= sizeof(sensebuf
);
418 io_header
.sbp
= sensebuf
;
419 io_header
.timeout
= 6000; /* XXX */
421 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
425 return (buf
[4] << 24) | (buf
[5] << 16) | (buf
[6] << 8) | buf
[7];
428 static int get_stream_blocksize(BlockDriverState
*bdrv
)
433 sg_io_hdr_t io_header
;
436 memset(cmd
, 0, sizeof(cmd
));
437 memset(buf
, 0, sizeof(buf
));
439 cmd
[4] = sizeof(buf
);
441 memset(&io_header
, 0, sizeof(io_header
));
442 io_header
.interface_id
= 'S';
443 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
444 io_header
.dxfer_len
= sizeof(buf
);
445 io_header
.dxferp
= buf
;
446 io_header
.cmdp
= cmd
;
447 io_header
.cmd_len
= sizeof(cmd
);
448 io_header
.mx_sb_len
= sizeof(sensebuf
);
449 io_header
.sbp
= sensebuf
;
450 io_header
.timeout
= 6000; /* XXX */
452 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
456 return (buf
[9] << 16) | (buf
[10] << 8) | buf
[11];
459 static void scsi_generic_reset(DeviceState
*dev
)
461 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
.qdev
, dev
);
463 scsi_device_purge_requests(&s
->qdev
);
466 static void scsi_destroy(SCSIDevice
*d
)
468 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
470 scsi_device_purge_requests(&s
->qdev
);
471 blockdev_mark_auto_del(s
->qdev
.conf
.bs
);
474 static int scsi_generic_initfn(SCSIDevice
*dev
)
476 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, dev
);
478 struct sg_scsi_id scsiid
;
480 if (!s
->qdev
.conf
.bs
) {
481 error_report("scsi-generic: drive property not set");
484 s
->bs
= s
->qdev
.conf
.bs
;
486 /* check we are really using a /dev/sg* file */
487 if (!bdrv_is_sg(s
->bs
)) {
488 error_report("scsi-generic: not /dev/sg*");
492 if (bdrv_get_on_error(s
->bs
, 0) != BLOCK_ERR_STOP_ENOSPC
) {
493 error_report("Device doesn't support drive option werror");
496 if (bdrv_get_on_error(s
->bs
, 1) != BLOCK_ERR_REPORT
) {
497 error_report("Device doesn't support drive option rerror");
501 /* check we are using a driver managing SG_IO (version 3 and after */
502 if (bdrv_ioctl(s
->bs
, SG_GET_VERSION_NUM
, &sg_version
) < 0 ||
503 sg_version
< 30000) {
504 error_report("scsi-generic: scsi generic interface too old");
508 /* get LUN of the /dev/sg? */
509 if (bdrv_ioctl(s
->bs
, SG_GET_SCSI_ID
, &scsiid
)) {
510 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
514 /* define device state */
516 DPRINTF("LUN %d\n", s
->lun
);
517 s
->qdev
.type
= scsiid
.scsi_type
;
518 DPRINTF("device type %d\n", s
->qdev
.type
);
519 if (s
->qdev
.type
== TYPE_TAPE
) {
520 s
->qdev
.blocksize
= get_stream_blocksize(s
->bs
);
521 if (s
->qdev
.blocksize
== -1)
522 s
->qdev
.blocksize
= 0;
524 s
->qdev
.blocksize
= get_blocksize(s
->bs
);
525 /* removable media returns 0 if not present */
526 if (s
->qdev
.blocksize
<= 0) {
527 if (s
->qdev
.type
== TYPE_ROM
|| s
->qdev
.type
== TYPE_WORM
)
528 s
->qdev
.blocksize
= 2048;
530 s
->qdev
.blocksize
= 512;
533 DPRINTF("block size %d\n", s
->qdev
.blocksize
);
534 s
->driver_status
= 0;
535 memset(s
->sensebuf
, 0, sizeof(s
->sensebuf
));
536 bdrv_set_removable(s
->bs
, 0);
540 static SCSIDeviceInfo scsi_generic_info
= {
541 .qdev
.name
= "scsi-generic",
542 .qdev
.desc
= "pass through generic scsi device (/dev/sg*)",
543 .qdev
.size
= sizeof(SCSIGenericState
),
544 .qdev
.reset
= scsi_generic_reset
,
545 .init
= scsi_generic_initfn
,
546 .destroy
= scsi_destroy
,
547 .alloc_req
= scsi_new_request
,
548 .free_req
= scsi_free_request
,
549 .send_command
= scsi_send_command
,
550 .read_data
= scsi_read_data
,
551 .write_data
= scsi_write_data
,
552 .cancel_io
= scsi_cancel_io
,
553 .get_buf
= scsi_get_buf
,
554 .get_sense
= scsi_get_sense
,
555 .qdev
.props
= (Property
[]) {
556 DEFINE_BLOCK_PROPERTIES(SCSIGenericState
, qdev
.conf
),
557 DEFINE_PROP_END_OF_LIST(),
561 static void scsi_generic_register_devices(void)
563 scsi_qdev_register(&scsi_generic_info
);
565 device_init(scsi_generic_register_devices
)
567 #endif /* __linux__ */