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"
23 #define DPRINTF(fmt, ...) \
24 do { printf("scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
26 #define DPRINTF(fmt, ...) do {} while(0)
29 #define BADF(fmt, ...) \
30 do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
33 #include <sys/types.h>
37 #include "scsi-defs.h"
39 #define SCSI_SENSE_BUF_SIZE 96
41 #define SG_ERR_DRIVER_TIMEOUT 0x06
42 #define SG_ERR_DRIVER_SENSE 0x08
45 #define MAX_UINT ((unsigned int)-1)
48 typedef struct SCSIGenericState SCSIGenericState
;
50 typedef struct SCSIGenericReq
{
55 sg_io_hdr_t io_header
;
58 struct SCSIGenericState
63 uint8_t sensebuf
[SCSI_SENSE_BUF_SIZE
];
67 static SCSIGenericReq
*scsi_new_request(SCSIDevice
*d
, uint32_t tag
, uint32_t lun
)
71 req
= scsi_req_alloc(sizeof(SCSIGenericReq
), d
, tag
, lun
);
72 return DO_UPCAST(SCSIGenericReq
, req
, req
);
75 static void scsi_remove_request(SCSIGenericReq
*r
)
78 scsi_req_free(&r
->req
);
81 static SCSIGenericReq
*scsi_find_request(SCSIGenericState
*s
, uint32_t tag
)
83 return DO_UPCAST(SCSIGenericReq
, req
, scsi_req_find(&s
->qdev
, tag
));
86 /* Helper function for command completion. */
87 static void scsi_command_complete(void *opaque
, int ret
)
89 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
90 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
92 s
->driver_status
= r
->io_header
.driver_status
;
93 if (s
->driver_status
& SG_ERR_DRIVER_SENSE
)
94 s
->senselen
= r
->io_header
.sb_len_wr
;
97 r
->req
.status
= BUSY
<< 1;
99 if (s
->driver_status
& SG_ERR_DRIVER_TIMEOUT
) {
100 r
->req
.status
= BUSY
<< 1;
101 BADF("Driver Timeout\n");
102 } else if (r
->io_header
.status
)
103 r
->req
.status
= r
->io_header
.status
;
104 else if (s
->driver_status
& SG_ERR_DRIVER_SENSE
)
105 r
->req
.status
= CHECK_CONDITION
<< 1;
107 r
->req
.status
= GOOD
<< 1;
109 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
110 r
, r
->req
.tag
, r
->req
.status
);
112 scsi_req_complete(&r
->req
);
113 scsi_remove_request(r
);
116 /* Cancel a pending data transfer. */
117 static void scsi_cancel_io(SCSIDevice
*d
, uint32_t tag
)
119 DPRINTF("scsi_cancel_io 0x%x\n", tag
);
120 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
122 DPRINTF("Cancel tag=0x%x\n", tag
);
123 r
= scsi_find_request(s
, tag
);
126 bdrv_aio_cancel(r
->req
.aiocb
);
128 scsi_remove_request(r
);
132 static int execute_command(BlockDriverState
*bdrv
,
133 SCSIGenericReq
*r
, int direction
,
134 BlockDriverCompletionFunc
*complete
)
136 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
138 r
->io_header
.interface_id
= 'S';
139 r
->io_header
.dxfer_direction
= direction
;
140 r
->io_header
.dxferp
= r
->buf
;
141 r
->io_header
.dxfer_len
= r
->buflen
;
142 r
->io_header
.cmdp
= r
->req
.cmd
.buf
;
143 r
->io_header
.cmd_len
= r
->req
.cmd
.len
;
144 r
->io_header
.mx_sb_len
= sizeof(s
->sensebuf
);
145 r
->io_header
.sbp
= s
->sensebuf
;
146 r
->io_header
.timeout
= MAX_UINT
;
147 r
->io_header
.usr_ptr
= r
;
148 r
->io_header
.flags
|= SG_FLAG_DIRECT_IO
;
150 r
->req
.aiocb
= bdrv_aio_ioctl(bdrv
, SG_IO
, &r
->io_header
, complete
, r
);
151 if (r
->req
.aiocb
== NULL
) {
152 BADF("execute_command: read failed !\n");
159 static void scsi_read_complete(void * opaque
, int ret
)
161 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
165 DPRINTF("IO error\n");
166 scsi_command_complete(r
, ret
);
169 len
= r
->io_header
.dxfer_len
- r
->io_header
.resid
;
170 DPRINTF("Data ready tag=0x%x len=%d\n", r
->req
.tag
, len
);
173 r
->req
.bus
->complete(r
->req
.bus
, SCSI_REASON_DATA
, r
->req
.tag
, len
);
175 scsi_command_complete(r
, 0);
178 /* Read more data from scsi device into buffer. */
179 static void scsi_read_data(SCSIDevice
*d
, uint32_t tag
)
181 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
185 DPRINTF("scsi_read_data 0x%x\n", tag
);
186 r
= scsi_find_request(s
, tag
);
188 BADF("Bad read tag 0x%x\n", tag
);
189 /* ??? This is the wrong error. */
190 scsi_command_complete(r
, -EINVAL
);
195 scsi_command_complete(r
, 0);
199 if (r
->req
.cmd
.buf
[0] == REQUEST_SENSE
&& s
->driver_status
& SG_ERR_DRIVER_SENSE
)
201 s
->senselen
= MIN(r
->len
, s
->senselen
);
202 memcpy(r
->buf
, s
->sensebuf
, s
->senselen
);
203 r
->io_header
.driver_status
= 0;
204 r
->io_header
.status
= 0;
205 r
->io_header
.dxfer_len
= s
->senselen
;
207 DPRINTF("Data ready tag=0x%x len=%d\n", r
->req
.tag
, s
->senselen
);
208 DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
209 r
->buf
[0], r
->buf
[1], r
->buf
[2], r
->buf
[3],
210 r
->buf
[4], r
->buf
[5], r
->buf
[6], r
->buf
[7]);
211 r
->req
.bus
->complete(r
->req
.bus
, SCSI_REASON_DATA
, r
->req
.tag
, s
->senselen
);
215 ret
= execute_command(s
->qdev
.dinfo
->bdrv
, r
, SG_DXFER_FROM_DEV
, scsi_read_complete
);
217 scsi_command_complete(r
, -EINVAL
);
222 static void scsi_write_complete(void * opaque
, int ret
)
224 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
225 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
227 DPRINTF("scsi_write_complete() ret = %d\n", ret
);
229 DPRINTF("IO error\n");
230 scsi_command_complete(r
, ret
);
234 if (r
->req
.cmd
.buf
[0] == MODE_SELECT
&& r
->req
.cmd
.buf
[4] == 12 &&
235 s
->qdev
.type
== TYPE_TAPE
) {
236 s
->qdev
.blocksize
= (r
->buf
[9] << 16) | (r
->buf
[10] << 8) | r
->buf
[11];
237 DPRINTF("block size %d\n", s
->blocksize
);
240 scsi_command_complete(r
, ret
);
243 /* Write data to a scsi device. Returns nonzero on failure.
244 The transfer may complete asynchronously. */
245 static int scsi_write_data(SCSIDevice
*d
, uint32_t tag
)
247 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
251 DPRINTF("scsi_write_data 0x%x\n", tag
);
252 r
= scsi_find_request(s
, tag
);
254 BADF("Bad write tag 0x%x\n", tag
);
255 /* ??? This is the wrong error. */
256 scsi_command_complete(r
, -EINVAL
);
262 r
->req
.bus
->complete(r
->req
.bus
, SCSI_REASON_DATA
, r
->req
.tag
, r
->len
);
266 ret
= execute_command(s
->qdev
.dinfo
->bdrv
, r
, SG_DXFER_TO_DEV
, scsi_write_complete
);
268 scsi_command_complete(r
, -EINVAL
);
275 /* Return a pointer to the data buffer. */
276 static uint8_t *scsi_get_buf(SCSIDevice
*d
, uint32_t tag
)
278 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
280 r
= scsi_find_request(s
, tag
);
282 BADF("Bad buffer tag 0x%x\n", tag
);
288 static void scsi_req_fixup(SCSIRequest
*req
)
290 switch(req
->cmd
.buf
[0]) {
292 req
->cmd
.buf
[1] &= ~0x08; /* disable FUA */
295 req
->cmd
.buf
[1] &= ~0x08; /* disable FUA */
299 if (req
->dev
->type
== TYPE_TAPE
) {
300 /* force IMMED, otherwise qemu waits end of command */
301 req
->cmd
.buf
[1] = 0x01;
307 /* Execute a scsi command. Returns the length of the data expected by the
308 command. This will be Positive for data transfers from the device
309 (eg. disk reads), negative for transfers to the device (eg. disk writes),
310 and zero if the command does not transfer any data. */
312 static int32_t scsi_send_command(SCSIDevice
*d
, uint32_t tag
,
313 uint8_t *cmd
, int lun
)
315 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
320 if (cmd
[0] != REQUEST_SENSE
&&
321 (lun
!= s
->lun
|| (cmd
[1] >> 5) != s
->lun
)) {
322 DPRINTF("Unimplemented LUN %d\n", lun
? lun
: cmd
[1] >> 5);
324 s
->sensebuf
[0] = 0x70;
325 s
->sensebuf
[1] = 0x00;
326 s
->sensebuf
[2] = ILLEGAL_REQUEST
;
327 s
->sensebuf
[3] = 0x00;
328 s
->sensebuf
[4] = 0x00;
329 s
->sensebuf
[5] = 0x00;
330 s
->sensebuf
[6] = 0x00;
332 s
->driver_status
= SG_ERR_DRIVER_SENSE
;
333 bus
= scsi_bus_from_device(d
);
334 bus
->complete(bus
, SCSI_REASON_DONE
, tag
, CHECK_CONDITION
<< 1);
338 r
= scsi_find_request(s
, tag
);
340 BADF("Tag 0x%x already in use %p\n", tag
, r
);
341 scsi_cancel_io(d
, tag
);
343 r
= scsi_new_request(d
, tag
, lun
);
345 if (-1 == scsi_req_parse(&r
->req
, cmd
)) {
346 BADF("Unsupported command length, command %x\n", cmd
[0]);
347 scsi_remove_request(r
);
350 scsi_req_fixup(&r
->req
);
352 DPRINTF("Command: lun=%d tag=0x%x data=0x%02x len %d\n", lun
, tag
,
353 cmd
[0], r
->req
.cmd
.xfer
);
355 if (r
->req
.cmd
.xfer
== 0) {
360 ret
= execute_command(s
->qdev
.dinfo
->bdrv
, r
, SG_DXFER_NONE
, scsi_command_complete
);
362 scsi_command_complete(r
, -EINVAL
);
368 if (r
->buflen
!= r
->req
.cmd
.xfer
) {
371 r
->buf
= qemu_malloc(r
->req
.cmd
.xfer
);
372 r
->buflen
= r
->req
.cmd
.xfer
;
375 memset(r
->buf
, 0, r
->buflen
);
376 r
->len
= r
->req
.cmd
.xfer
;
377 if (r
->req
.cmd
.mode
== SCSI_XFER_TO_DEV
) {
379 return -r
->req
.cmd
.xfer
;
382 return r
->req
.cmd
.xfer
;
385 static int get_blocksize(BlockDriverState
*bdrv
)
390 sg_io_hdr_t io_header
;
393 memset(cmd
, 0, sizeof(cmd
));
394 memset(buf
, 0, sizeof(buf
));
395 cmd
[0] = READ_CAPACITY
;
397 memset(&io_header
, 0, sizeof(io_header
));
398 io_header
.interface_id
= 'S';
399 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
400 io_header
.dxfer_len
= sizeof(buf
);
401 io_header
.dxferp
= buf
;
402 io_header
.cmdp
= cmd
;
403 io_header
.cmd_len
= sizeof(cmd
);
404 io_header
.mx_sb_len
= sizeof(sensebuf
);
405 io_header
.sbp
= sensebuf
;
406 io_header
.timeout
= 6000; /* XXX */
408 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
412 return (buf
[4] << 24) | (buf
[5] << 16) | (buf
[6] << 8) | buf
[7];
415 static int get_stream_blocksize(BlockDriverState
*bdrv
)
420 sg_io_hdr_t io_header
;
423 memset(cmd
, 0, sizeof(cmd
));
424 memset(buf
, 0, sizeof(buf
));
426 cmd
[4] = sizeof(buf
);
428 memset(&io_header
, 0, sizeof(io_header
));
429 io_header
.interface_id
= 'S';
430 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
431 io_header
.dxfer_len
= sizeof(buf
);
432 io_header
.dxferp
= buf
;
433 io_header
.cmdp
= cmd
;
434 io_header
.cmd_len
= sizeof(cmd
);
435 io_header
.mx_sb_len
= sizeof(sensebuf
);
436 io_header
.sbp
= sensebuf
;
437 io_header
.timeout
= 6000; /* XXX */
439 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
443 return (buf
[9] << 16) | (buf
[10] << 8) | buf
[11];
446 static void scsi_destroy(SCSIDevice
*d
)
448 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
451 while (!QTAILQ_EMPTY(&s
->qdev
.requests
)) {
452 r
= DO_UPCAST(SCSIGenericReq
, req
, QTAILQ_FIRST(&s
->qdev
.requests
));
453 scsi_remove_request(r
);
455 drive_uninit(s
->qdev
.dinfo
);
458 static int scsi_generic_initfn(SCSIDevice
*dev
)
460 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, dev
);
462 struct sg_scsi_id scsiid
;
464 if (!s
->qdev
.dinfo
|| !s
->qdev
.dinfo
->bdrv
) {
465 qemu_error("scsi-generic: drive property not set\n");
469 /* check we are really using a /dev/sg* file */
470 if (!bdrv_is_sg(s
->qdev
.dinfo
->bdrv
)) {
471 qemu_error("scsi-generic: not /dev/sg*\n");
475 /* check we are using a driver managing SG_IO (version 3 and after */
476 if (bdrv_ioctl(s
->qdev
.dinfo
->bdrv
, SG_GET_VERSION_NUM
, &sg_version
) < 0 ||
477 sg_version
< 30000) {
478 qemu_error("scsi-generic: scsi generic interface too old\n");
482 /* get LUN of the /dev/sg? */
483 if (bdrv_ioctl(s
->qdev
.dinfo
->bdrv
, SG_GET_SCSI_ID
, &scsiid
)) {
484 qemu_error("scsi-generic: SG_GET_SCSI_ID ioctl failed\n");
488 /* define device state */
490 DPRINTF("LUN %d\n", s
->lun
);
491 s
->qdev
.type
= scsiid
.scsi_type
;
492 DPRINTF("device type %d\n", s
->qdev
.type
);
493 if (s
->qdev
.type
== TYPE_TAPE
) {
494 s
->qdev
.blocksize
= get_stream_blocksize(s
->qdev
.dinfo
->bdrv
);
495 if (s
->qdev
.blocksize
== -1)
496 s
->qdev
.blocksize
= 0;
498 s
->qdev
.blocksize
= get_blocksize(s
->qdev
.dinfo
->bdrv
);
499 /* removable media returns 0 if not present */
500 if (s
->qdev
.blocksize
<= 0) {
501 if (s
->qdev
.type
== TYPE_ROM
|| s
->qdev
.type
== TYPE_WORM
)
502 s
->qdev
.blocksize
= 2048;
504 s
->qdev
.blocksize
= 512;
507 DPRINTF("block size %d\n", s
->qdev
.blocksize
);
508 s
->driver_status
= 0;
509 memset(s
->sensebuf
, 0, sizeof(s
->sensebuf
));
513 static SCSIDeviceInfo scsi_generic_info
= {
514 .qdev
.name
= "scsi-generic",
515 .qdev
.desc
= "pass through generic scsi device (/dev/sg*)",
516 .qdev
.size
= sizeof(SCSIGenericState
),
517 .init
= scsi_generic_initfn
,
518 .destroy
= scsi_destroy
,
519 .send_command
= scsi_send_command
,
520 .read_data
= scsi_read_data
,
521 .write_data
= scsi_write_data
,
522 .cancel_io
= scsi_cancel_io
,
523 .get_buf
= scsi_get_buf
,
524 .qdev
.props
= (Property
[]) {
525 DEFINE_PROP_DRIVE("drive", SCSIGenericState
, qdev
.dinfo
),
526 DEFINE_PROP_END_OF_LIST(),
530 static void scsi_generic_register_devices(void)
532 scsi_qdev_register(&scsi_generic_info
);
534 device_init(scsi_generic_register_devices
)
536 #endif /* __linux__ */