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_free_request(SCSIRequest
*req
)
79 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
84 static SCSIGenericReq
*scsi_find_request(SCSIGenericState
*s
, uint32_t tag
)
86 return DO_UPCAST(SCSIGenericReq
, req
, scsi_req_find(&s
->qdev
, tag
));
89 /* Helper function for command completion. */
90 static void scsi_command_complete(void *opaque
, int ret
)
92 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
93 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
96 s
->driver_status
= r
->io_header
.driver_status
;
97 if (s
->driver_status
& SG_ERR_DRIVER_SENSE
)
98 s
->senselen
= r
->io_header
.sb_len_wr
;
101 r
->req
.status
= BUSY
;
103 if (s
->driver_status
& SG_ERR_DRIVER_TIMEOUT
) {
104 r
->req
.status
= BUSY
;
105 BADF("Driver Timeout\n");
106 } else if (r
->io_header
.status
)
107 r
->req
.status
= r
->io_header
.status
;
108 else if (s
->driver_status
& SG_ERR_DRIVER_SENSE
)
109 r
->req
.status
= CHECK_CONDITION
;
111 r
->req
.status
= GOOD
;
113 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
114 r
, r
->req
.tag
, r
->req
.status
);
116 scsi_req_complete(&r
->req
);
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_req_dequeue(&r
->req
);
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
);
328 if (cmd
[0] != REQUEST_SENSE
&&
329 (lun
!= s
->lun
|| (cmd
[1] >> 5) != s
->lun
)) {
330 DPRINTF("Unimplemented LUN %d\n", lun
? lun
: cmd
[1] >> 5);
332 s
->sensebuf
[0] = 0x70;
333 s
->sensebuf
[1] = 0x00;
334 s
->sensebuf
[2] = ILLEGAL_REQUEST
;
335 s
->sensebuf
[3] = 0x00;
336 s
->sensebuf
[4] = 0x00;
337 s
->sensebuf
[5] = 0x00;
338 s
->sensebuf
[6] = 0x00;
340 s
->driver_status
= SG_ERR_DRIVER_SENSE
;
341 bus
= scsi_bus_from_device(d
);
342 bus
->ops
->complete(bus
, SCSI_REASON_DONE
, tag
, CHECK_CONDITION
);
346 r
= scsi_find_request(s
, tag
);
348 BADF("Tag 0x%x already in use %p\n", tag
, r
);
349 scsi_cancel_io(d
, tag
);
351 r
= scsi_new_request(d
, tag
, lun
);
353 if (-1 == scsi_req_parse(&r
->req
, cmd
)) {
354 BADF("Unsupported command length, command %x\n", cmd
[0]);
355 scsi_req_dequeue(&r
->req
);
356 scsi_req_unref(&r
->req
);
359 scsi_req_fixup(&r
->req
);
361 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun
, tag
,
362 r
->req
.cmd
.xfer
, cmd
[0]);
367 for (i
= 1; i
< r
->req
.cmd
.len
; i
++) {
368 printf(" 0x%02x", cmd
[i
]);
374 if (r
->req
.cmd
.xfer
== 0) {
379 ret
= execute_command(s
->bs
, r
, SG_DXFER_NONE
, scsi_command_complete
);
381 scsi_command_complete(r
, -EINVAL
);
382 scsi_req_unref(&r
->req
);
385 scsi_req_unref(&r
->req
);
389 if (r
->buflen
!= r
->req
.cmd
.xfer
) {
392 r
->buf
= qemu_malloc(r
->req
.cmd
.xfer
);
393 r
->buflen
= r
->req
.cmd
.xfer
;
396 memset(r
->buf
, 0, r
->buflen
);
397 r
->len
= r
->req
.cmd
.xfer
;
398 if (r
->req
.cmd
.mode
== SCSI_XFER_TO_DEV
) {
400 len
= -r
->req
.cmd
.xfer
;
402 len
= r
->req
.cmd
.xfer
;
405 scsi_req_unref(&r
->req
);
409 static int get_blocksize(BlockDriverState
*bdrv
)
414 sg_io_hdr_t io_header
;
417 memset(cmd
, 0, sizeof(cmd
));
418 memset(buf
, 0, sizeof(buf
));
419 cmd
[0] = READ_CAPACITY
;
421 memset(&io_header
, 0, sizeof(io_header
));
422 io_header
.interface_id
= 'S';
423 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
424 io_header
.dxfer_len
= sizeof(buf
);
425 io_header
.dxferp
= buf
;
426 io_header
.cmdp
= cmd
;
427 io_header
.cmd_len
= sizeof(cmd
);
428 io_header
.mx_sb_len
= sizeof(sensebuf
);
429 io_header
.sbp
= sensebuf
;
430 io_header
.timeout
= 6000; /* XXX */
432 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
436 return (buf
[4] << 24) | (buf
[5] << 16) | (buf
[6] << 8) | buf
[7];
439 static int get_stream_blocksize(BlockDriverState
*bdrv
)
444 sg_io_hdr_t io_header
;
447 memset(cmd
, 0, sizeof(cmd
));
448 memset(buf
, 0, sizeof(buf
));
450 cmd
[4] = sizeof(buf
);
452 memset(&io_header
, 0, sizeof(io_header
));
453 io_header
.interface_id
= 'S';
454 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
455 io_header
.dxfer_len
= sizeof(buf
);
456 io_header
.dxferp
= buf
;
457 io_header
.cmdp
= cmd
;
458 io_header
.cmd_len
= sizeof(cmd
);
459 io_header
.mx_sb_len
= sizeof(sensebuf
);
460 io_header
.sbp
= sensebuf
;
461 io_header
.timeout
= 6000; /* XXX */
463 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
467 return (buf
[9] << 16) | (buf
[10] << 8) | buf
[11];
470 static void scsi_generic_purge_requests(SCSIGenericState
*s
)
474 while (!QTAILQ_EMPTY(&s
->qdev
.requests
)) {
475 r
= DO_UPCAST(SCSIGenericReq
, req
, QTAILQ_FIRST(&s
->qdev
.requests
));
477 bdrv_aio_cancel(r
->req
.aiocb
);
479 scsi_req_dequeue(&r
->req
);
483 static void scsi_generic_reset(DeviceState
*dev
)
485 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
.qdev
, dev
);
487 scsi_generic_purge_requests(s
);
490 static void scsi_destroy(SCSIDevice
*d
)
492 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
494 scsi_generic_purge_requests(s
);
495 blockdev_mark_auto_del(s
->qdev
.conf
.bs
);
498 static int scsi_generic_initfn(SCSIDevice
*dev
)
500 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, dev
);
502 struct sg_scsi_id scsiid
;
504 if (!s
->qdev
.conf
.bs
) {
505 error_report("scsi-generic: drive property not set");
508 s
->bs
= s
->qdev
.conf
.bs
;
510 /* check we are really using a /dev/sg* file */
511 if (!bdrv_is_sg(s
->bs
)) {
512 error_report("scsi-generic: not /dev/sg*");
516 if (bdrv_get_on_error(s
->bs
, 0) != BLOCK_ERR_STOP_ENOSPC
) {
517 error_report("Device doesn't support drive option werror");
520 if (bdrv_get_on_error(s
->bs
, 1) != BLOCK_ERR_REPORT
) {
521 error_report("Device doesn't support drive option rerror");
525 /* check we are using a driver managing SG_IO (version 3 and after */
526 if (bdrv_ioctl(s
->bs
, SG_GET_VERSION_NUM
, &sg_version
) < 0 ||
527 sg_version
< 30000) {
528 error_report("scsi-generic: scsi generic interface too old");
532 /* get LUN of the /dev/sg? */
533 if (bdrv_ioctl(s
->bs
, SG_GET_SCSI_ID
, &scsiid
)) {
534 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
538 /* define device state */
540 DPRINTF("LUN %d\n", s
->lun
);
541 s
->qdev
.type
= scsiid
.scsi_type
;
542 DPRINTF("device type %d\n", s
->qdev
.type
);
543 if (s
->qdev
.type
== TYPE_TAPE
) {
544 s
->qdev
.blocksize
= get_stream_blocksize(s
->bs
);
545 if (s
->qdev
.blocksize
== -1)
546 s
->qdev
.blocksize
= 0;
548 s
->qdev
.blocksize
= get_blocksize(s
->bs
);
549 /* removable media returns 0 if not present */
550 if (s
->qdev
.blocksize
<= 0) {
551 if (s
->qdev
.type
== TYPE_ROM
|| s
->qdev
.type
== TYPE_WORM
)
552 s
->qdev
.blocksize
= 2048;
554 s
->qdev
.blocksize
= 512;
557 DPRINTF("block size %d\n", s
->qdev
.blocksize
);
558 s
->driver_status
= 0;
559 memset(s
->sensebuf
, 0, sizeof(s
->sensebuf
));
560 bdrv_set_removable(s
->bs
, 0);
564 static SCSIDeviceInfo scsi_generic_info
= {
565 .qdev
.name
= "scsi-generic",
566 .qdev
.desc
= "pass through generic scsi device (/dev/sg*)",
567 .qdev
.size
= sizeof(SCSIGenericState
),
568 .qdev
.reset
= scsi_generic_reset
,
569 .init
= scsi_generic_initfn
,
570 .destroy
= scsi_destroy
,
571 .free_req
= scsi_free_request
,
572 .send_command
= scsi_send_command
,
573 .read_data
= scsi_read_data
,
574 .write_data
= scsi_write_data
,
575 .cancel_io
= scsi_cancel_io
,
576 .get_buf
= scsi_get_buf
,
577 .qdev
.props
= (Property
[]) {
578 DEFINE_BLOCK_PROPERTIES(SCSIGenericState
, qdev
.conf
),
579 DEFINE_PROP_END_OF_LIST(),
583 static void scsi_generic_register_devices(void)
585 scsi_qdev_register(&scsi_generic_info
);
587 device_init(scsi_generic_register_devices
)
589 #endif /* __linux__ */