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 SCSIGenericReq
*scsi_new_request(SCSIDevice
*d
, uint32_t tag
, uint32_t lun
)
73 req
= scsi_req_alloc(sizeof(SCSIGenericReq
), d
, tag
, lun
);
74 return DO_UPCAST(SCSIGenericReq
, req
, req
);
77 static void scsi_remove_request(SCSIGenericReq
*r
)
80 scsi_req_free(&r
->req
);
83 static SCSIGenericReq
*scsi_find_request(SCSIGenericState
*s
, uint32_t tag
)
85 return DO_UPCAST(SCSIGenericReq
, req
, scsi_req_find(&s
->qdev
, tag
));
88 /* Helper function for command completion. */
89 static void scsi_command_complete(void *opaque
, int ret
)
91 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
92 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
95 s
->driver_status
= r
->io_header
.driver_status
;
96 if (s
->driver_status
& SG_ERR_DRIVER_SENSE
)
97 s
->senselen
= r
->io_header
.sb_len_wr
;
100 r
->req
.status
= BUSY
;
102 if (s
->driver_status
& SG_ERR_DRIVER_TIMEOUT
) {
103 r
->req
.status
= BUSY
;
104 BADF("Driver Timeout\n");
105 } else if (r
->io_header
.status
)
106 r
->req
.status
= r
->io_header
.status
;
107 else if (s
->driver_status
& SG_ERR_DRIVER_SENSE
)
108 r
->req
.status
= CHECK_CONDITION
;
110 r
->req
.status
= GOOD
;
112 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
113 r
, r
->req
.tag
, r
->req
.status
);
115 scsi_req_complete(&r
->req
);
116 scsi_remove_request(r
);
119 /* Cancel a pending data transfer. */
120 static void scsi_cancel_io(SCSIDevice
*d
, uint32_t tag
)
122 DPRINTF("scsi_cancel_io 0x%x\n", tag
);
123 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
125 DPRINTF("Cancel tag=0x%x\n", tag
);
126 r
= scsi_find_request(s
, tag
);
129 bdrv_aio_cancel(r
->req
.aiocb
);
131 scsi_remove_request(r
);
135 static int execute_command(BlockDriverState
*bdrv
,
136 SCSIGenericReq
*r
, int direction
,
137 BlockDriverCompletionFunc
*complete
)
139 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
141 r
->io_header
.interface_id
= 'S';
142 r
->io_header
.dxfer_direction
= direction
;
143 r
->io_header
.dxferp
= r
->buf
;
144 r
->io_header
.dxfer_len
= r
->buflen
;
145 r
->io_header
.cmdp
= r
->req
.cmd
.buf
;
146 r
->io_header
.cmd_len
= r
->req
.cmd
.len
;
147 r
->io_header
.mx_sb_len
= sizeof(s
->sensebuf
);
148 r
->io_header
.sbp
= s
->sensebuf
;
149 r
->io_header
.timeout
= MAX_UINT
;
150 r
->io_header
.usr_ptr
= r
;
151 r
->io_header
.flags
|= SG_FLAG_DIRECT_IO
;
153 r
->req
.aiocb
= bdrv_aio_ioctl(bdrv
, SG_IO
, &r
->io_header
, complete
, r
);
154 if (r
->req
.aiocb
== NULL
) {
155 BADF("execute_command: read failed !\n");
162 static void scsi_read_complete(void * opaque
, int ret
)
164 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
169 DPRINTF("IO error ret %d\n", ret
);
170 scsi_command_complete(r
, ret
);
173 len
= r
->io_header
.dxfer_len
- r
->io_header
.resid
;
174 DPRINTF("Data ready tag=0x%x len=%d\n", r
->req
.tag
, len
);
178 scsi_command_complete(r
, 0);
180 scsi_req_data(&r
->req
, len
);
184 /* Read more data from scsi device into buffer. */
185 static void scsi_read_data(SCSIDevice
*d
, uint32_t tag
)
187 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
191 DPRINTF("scsi_read_data 0x%x\n", tag
);
192 r
= scsi_find_request(s
, tag
);
194 BADF("Bad read tag 0x%x\n", tag
);
195 /* ??? This is the wrong error. */
196 scsi_command_complete(r
, -EINVAL
);
201 scsi_command_complete(r
, 0);
205 if (r
->req
.cmd
.buf
[0] == REQUEST_SENSE
&& s
->driver_status
& SG_ERR_DRIVER_SENSE
)
207 s
->senselen
= MIN(r
->len
, s
->senselen
);
208 memcpy(r
->buf
, s
->sensebuf
, s
->senselen
);
209 r
->io_header
.driver_status
= 0;
210 r
->io_header
.status
= 0;
211 r
->io_header
.dxfer_len
= s
->senselen
;
213 DPRINTF("Data ready tag=0x%x len=%d\n", r
->req
.tag
, s
->senselen
);
214 DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
215 r
->buf
[0], r
->buf
[1], r
->buf
[2], r
->buf
[3],
216 r
->buf
[4], r
->buf
[5], r
->buf
[6], r
->buf
[7]);
217 scsi_req_data(&r
->req
, s
->senselen
);
221 ret
= execute_command(s
->bs
, r
, SG_DXFER_FROM_DEV
, scsi_read_complete
);
223 scsi_command_complete(r
, -EINVAL
);
228 static void scsi_write_complete(void * opaque
, int ret
)
230 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
231 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
233 DPRINTF("scsi_write_complete() ret = %d\n", ret
);
236 DPRINTF("IO error\n");
237 scsi_command_complete(r
, ret
);
241 if (r
->req
.cmd
.buf
[0] == MODE_SELECT
&& r
->req
.cmd
.buf
[4] == 12 &&
242 s
->qdev
.type
== TYPE_TAPE
) {
243 s
->qdev
.blocksize
= (r
->buf
[9] << 16) | (r
->buf
[10] << 8) | r
->buf
[11];
244 DPRINTF("block size %d\n", s
->qdev
.blocksize
);
247 scsi_command_complete(r
, ret
);
250 /* Write data to a scsi device. Returns nonzero on failure.
251 The transfer may complete asynchronously. */
252 static int scsi_write_data(SCSIDevice
*d
, uint32_t tag
)
254 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
258 DPRINTF("scsi_write_data 0x%x\n", tag
);
259 r
= scsi_find_request(s
, tag
);
261 BADF("Bad write tag 0x%x\n", tag
);
262 /* ??? This is the wrong error. */
263 scsi_command_complete(r
, -EINVAL
);
269 scsi_req_data(&r
->req
, r
->len
);
273 ret
= execute_command(s
->bs
, r
, SG_DXFER_TO_DEV
, scsi_write_complete
);
275 scsi_command_complete(r
, -EINVAL
);
282 /* Return a pointer to the data buffer. */
283 static uint8_t *scsi_get_buf(SCSIDevice
*d
, uint32_t tag
)
285 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
287 r
= scsi_find_request(s
, tag
);
289 BADF("Bad buffer tag 0x%x\n", tag
);
295 static void scsi_req_fixup(SCSIRequest
*req
)
297 switch(req
->cmd
.buf
[0]) {
299 req
->cmd
.buf
[1] &= ~0x08; /* disable FUA */
302 req
->cmd
.buf
[1] &= ~0x08; /* disable FUA */
306 if (req
->dev
->type
== TYPE_TAPE
) {
307 /* force IMMED, otherwise qemu waits end of command */
308 req
->cmd
.buf
[1] = 0x01;
314 /* Execute a scsi command. Returns the length of the data expected by the
315 command. This will be Positive for data transfers from the device
316 (eg. disk reads), negative for transfers to the device (eg. disk writes),
317 and zero if the command does not transfer any data. */
319 static int32_t scsi_send_command(SCSIDevice
*d
, uint32_t tag
,
320 uint8_t *cmd
, int lun
)
322 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
327 if (cmd
[0] != REQUEST_SENSE
&&
328 (lun
!= s
->lun
|| (cmd
[1] >> 5) != s
->lun
)) {
329 DPRINTF("Unimplemented LUN %d\n", lun
? lun
: cmd
[1] >> 5);
331 s
->sensebuf
[0] = 0x70;
332 s
->sensebuf
[1] = 0x00;
333 s
->sensebuf
[2] = ILLEGAL_REQUEST
;
334 s
->sensebuf
[3] = 0x00;
335 s
->sensebuf
[4] = 0x00;
336 s
->sensebuf
[5] = 0x00;
337 s
->sensebuf
[6] = 0x00;
339 s
->driver_status
= SG_ERR_DRIVER_SENSE
;
340 bus
= scsi_bus_from_device(d
);
341 bus
->ops
->complete(bus
, SCSI_REASON_DONE
, tag
, CHECK_CONDITION
);
345 r
= scsi_find_request(s
, tag
);
347 BADF("Tag 0x%x already in use %p\n", tag
, r
);
348 scsi_cancel_io(d
, tag
);
350 r
= scsi_new_request(d
, tag
, lun
);
352 if (-1 == scsi_req_parse(&r
->req
, cmd
)) {
353 BADF("Unsupported command length, command %x\n", cmd
[0]);
354 scsi_remove_request(r
);
357 scsi_req_fixup(&r
->req
);
359 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun
, tag
,
360 r
->req
.cmd
.xfer
, cmd
[0]);
365 for (i
= 1; i
< r
->req
.cmd
.len
; i
++) {
366 printf(" 0x%02x", cmd
[i
]);
372 if (r
->req
.cmd
.xfer
== 0) {
377 ret
= execute_command(s
->bs
, r
, SG_DXFER_NONE
, scsi_command_complete
);
379 scsi_command_complete(r
, -EINVAL
);
385 if (r
->buflen
!= r
->req
.cmd
.xfer
) {
388 r
->buf
= qemu_malloc(r
->req
.cmd
.xfer
);
389 r
->buflen
= r
->req
.cmd
.xfer
;
392 memset(r
->buf
, 0, r
->buflen
);
393 r
->len
= r
->req
.cmd
.xfer
;
394 if (r
->req
.cmd
.mode
== SCSI_XFER_TO_DEV
) {
396 return -r
->req
.cmd
.xfer
;
399 return r
->req
.cmd
.xfer
;
402 static int get_blocksize(BlockDriverState
*bdrv
)
407 sg_io_hdr_t io_header
;
410 memset(cmd
, 0, sizeof(cmd
));
411 memset(buf
, 0, sizeof(buf
));
412 cmd
[0] = READ_CAPACITY
;
414 memset(&io_header
, 0, sizeof(io_header
));
415 io_header
.interface_id
= 'S';
416 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
417 io_header
.dxfer_len
= sizeof(buf
);
418 io_header
.dxferp
= buf
;
419 io_header
.cmdp
= cmd
;
420 io_header
.cmd_len
= sizeof(cmd
);
421 io_header
.mx_sb_len
= sizeof(sensebuf
);
422 io_header
.sbp
= sensebuf
;
423 io_header
.timeout
= 6000; /* XXX */
425 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
429 return (buf
[4] << 24) | (buf
[5] << 16) | (buf
[6] << 8) | buf
[7];
432 static int get_stream_blocksize(BlockDriverState
*bdrv
)
437 sg_io_hdr_t io_header
;
440 memset(cmd
, 0, sizeof(cmd
));
441 memset(buf
, 0, sizeof(buf
));
443 cmd
[4] = sizeof(buf
);
445 memset(&io_header
, 0, sizeof(io_header
));
446 io_header
.interface_id
= 'S';
447 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
448 io_header
.dxfer_len
= sizeof(buf
);
449 io_header
.dxferp
= buf
;
450 io_header
.cmdp
= cmd
;
451 io_header
.cmd_len
= sizeof(cmd
);
452 io_header
.mx_sb_len
= sizeof(sensebuf
);
453 io_header
.sbp
= sensebuf
;
454 io_header
.timeout
= 6000; /* XXX */
456 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
460 return (buf
[9] << 16) | (buf
[10] << 8) | buf
[11];
463 static void scsi_generic_purge_requests(SCSIGenericState
*s
)
467 while (!QTAILQ_EMPTY(&s
->qdev
.requests
)) {
468 r
= DO_UPCAST(SCSIGenericReq
, req
, QTAILQ_FIRST(&s
->qdev
.requests
));
470 bdrv_aio_cancel(r
->req
.aiocb
);
472 scsi_remove_request(r
);
476 static void scsi_generic_reset(DeviceState
*dev
)
478 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
.qdev
, dev
);
480 scsi_generic_purge_requests(s
);
483 static void scsi_destroy(SCSIDevice
*d
)
485 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
487 scsi_generic_purge_requests(s
);
488 blockdev_mark_auto_del(s
->qdev
.conf
.bs
);
491 static int scsi_generic_initfn(SCSIDevice
*dev
)
493 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, dev
);
495 struct sg_scsi_id scsiid
;
497 if (!s
->qdev
.conf
.bs
) {
498 error_report("scsi-generic: drive property not set");
501 s
->bs
= s
->qdev
.conf
.bs
;
503 /* check we are really using a /dev/sg* file */
504 if (!bdrv_is_sg(s
->bs
)) {
505 error_report("scsi-generic: not /dev/sg*");
509 if (bdrv_get_on_error(s
->bs
, 0) != BLOCK_ERR_STOP_ENOSPC
) {
510 error_report("Device doesn't support drive option werror");
513 if (bdrv_get_on_error(s
->bs
, 1) != BLOCK_ERR_REPORT
) {
514 error_report("Device doesn't support drive option rerror");
518 /* check we are using a driver managing SG_IO (version 3 and after */
519 if (bdrv_ioctl(s
->bs
, SG_GET_VERSION_NUM
, &sg_version
) < 0 ||
520 sg_version
< 30000) {
521 error_report("scsi-generic: scsi generic interface too old");
525 /* get LUN of the /dev/sg? */
526 if (bdrv_ioctl(s
->bs
, SG_GET_SCSI_ID
, &scsiid
)) {
527 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
531 /* define device state */
533 DPRINTF("LUN %d\n", s
->lun
);
534 s
->qdev
.type
= scsiid
.scsi_type
;
535 DPRINTF("device type %d\n", s
->qdev
.type
);
536 if (s
->qdev
.type
== TYPE_TAPE
) {
537 s
->qdev
.blocksize
= get_stream_blocksize(s
->bs
);
538 if (s
->qdev
.blocksize
== -1)
539 s
->qdev
.blocksize
= 0;
541 s
->qdev
.blocksize
= get_blocksize(s
->bs
);
542 /* removable media returns 0 if not present */
543 if (s
->qdev
.blocksize
<= 0) {
544 if (s
->qdev
.type
== TYPE_ROM
|| s
->qdev
.type
== TYPE_WORM
)
545 s
->qdev
.blocksize
= 2048;
547 s
->qdev
.blocksize
= 512;
550 DPRINTF("block size %d\n", s
->qdev
.blocksize
);
551 s
->driver_status
= 0;
552 memset(s
->sensebuf
, 0, sizeof(s
->sensebuf
));
553 bdrv_set_removable(s
->bs
, 0);
557 static SCSIDeviceInfo scsi_generic_info
= {
558 .qdev
.name
= "scsi-generic",
559 .qdev
.desc
= "pass through generic scsi device (/dev/sg*)",
560 .qdev
.size
= sizeof(SCSIGenericState
),
561 .qdev
.reset
= scsi_generic_reset
,
562 .init
= scsi_generic_initfn
,
563 .destroy
= scsi_destroy
,
564 .send_command
= scsi_send_command
,
565 .read_data
= scsi_read_data
,
566 .write_data
= scsi_write_data
,
567 .cancel_io
= scsi_cancel_io
,
568 .get_buf
= scsi_get_buf
,
569 .qdev
.props
= (Property
[]) {
570 DEFINE_BLOCK_PROPERTIES(SCSIGenericState
, qdev
.conf
),
571 DEFINE_PROP_END_OF_LIST(),
575 static void scsi_generic_register_devices(void)
577 scsi_qdev_register(&scsi_generic_info
);
579 device_init(scsi_generic_register_devices
)
581 #endif /* __linux__ */