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
);
94 s
->driver_status
= r
->io_header
.driver_status
;
95 if (s
->driver_status
& SG_ERR_DRIVER_SENSE
)
96 s
->senselen
= r
->io_header
.sb_len_wr
;
101 if (s
->driver_status
& SG_ERR_DRIVER_TIMEOUT
) {
102 r
->req
.status
= BUSY
;
103 BADF("Driver Timeout\n");
104 } else if (r
->io_header
.status
)
105 r
->req
.status
= r
->io_header
.status
;
106 else if (s
->driver_status
& SG_ERR_DRIVER_SENSE
)
107 r
->req
.status
= CHECK_CONDITION
;
109 r
->req
.status
= GOOD
;
111 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
112 r
, r
->req
.tag
, r
->req
.status
);
114 scsi_req_complete(&r
->req
);
115 scsi_remove_request(r
);
118 /* Cancel a pending data transfer. */
119 static void scsi_cancel_io(SCSIDevice
*d
, uint32_t tag
)
121 DPRINTF("scsi_cancel_io 0x%x\n", tag
);
122 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
124 DPRINTF("Cancel tag=0x%x\n", tag
);
125 r
= scsi_find_request(s
, tag
);
128 bdrv_aio_cancel(r
->req
.aiocb
);
130 scsi_remove_request(r
);
134 static int execute_command(BlockDriverState
*bdrv
,
135 SCSIGenericReq
*r
, int direction
,
136 BlockDriverCompletionFunc
*complete
)
138 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
140 r
->io_header
.interface_id
= 'S';
141 r
->io_header
.dxfer_direction
= direction
;
142 r
->io_header
.dxferp
= r
->buf
;
143 r
->io_header
.dxfer_len
= r
->buflen
;
144 r
->io_header
.cmdp
= r
->req
.cmd
.buf
;
145 r
->io_header
.cmd_len
= r
->req
.cmd
.len
;
146 r
->io_header
.mx_sb_len
= sizeof(s
->sensebuf
);
147 r
->io_header
.sbp
= s
->sensebuf
;
148 r
->io_header
.timeout
= MAX_UINT
;
149 r
->io_header
.usr_ptr
= r
;
150 r
->io_header
.flags
|= SG_FLAG_DIRECT_IO
;
152 r
->req
.aiocb
= bdrv_aio_ioctl(bdrv
, SG_IO
, &r
->io_header
, complete
, r
);
153 if (r
->req
.aiocb
== NULL
) {
154 BADF("execute_command: read failed !\n");
161 static void scsi_read_complete(void * opaque
, int ret
)
163 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
167 DPRINTF("IO error ret %d\n", ret
);
168 scsi_command_complete(r
, ret
);
171 len
= r
->io_header
.dxfer_len
- r
->io_header
.resid
;
172 DPRINTF("Data ready tag=0x%x len=%d\n", r
->req
.tag
, len
);
176 scsi_command_complete(r
, 0);
178 scsi_req_data(&r
->req
, len
);
182 /* Read more data from scsi device into buffer. */
183 static void scsi_read_data(SCSIDevice
*d
, uint32_t tag
)
185 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
189 DPRINTF("scsi_read_data 0x%x\n", tag
);
190 r
= scsi_find_request(s
, tag
);
192 BADF("Bad read tag 0x%x\n", tag
);
193 /* ??? This is the wrong error. */
194 scsi_command_complete(r
, -EINVAL
);
199 scsi_command_complete(r
, 0);
203 if (r
->req
.cmd
.buf
[0] == REQUEST_SENSE
&& s
->driver_status
& SG_ERR_DRIVER_SENSE
)
205 s
->senselen
= MIN(r
->len
, s
->senselen
);
206 memcpy(r
->buf
, s
->sensebuf
, s
->senselen
);
207 r
->io_header
.driver_status
= 0;
208 r
->io_header
.status
= 0;
209 r
->io_header
.dxfer_len
= s
->senselen
;
211 DPRINTF("Data ready tag=0x%x len=%d\n", r
->req
.tag
, s
->senselen
);
212 DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
213 r
->buf
[0], r
->buf
[1], r
->buf
[2], r
->buf
[3],
214 r
->buf
[4], r
->buf
[5], r
->buf
[6], r
->buf
[7]);
215 scsi_req_data(&r
->req
, s
->senselen
);
219 ret
= execute_command(s
->bs
, r
, SG_DXFER_FROM_DEV
, scsi_read_complete
);
221 scsi_command_complete(r
, -EINVAL
);
226 static void scsi_write_complete(void * opaque
, int ret
)
228 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
229 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
231 DPRINTF("scsi_write_complete() ret = %d\n", ret
);
233 DPRINTF("IO error\n");
234 scsi_command_complete(r
, ret
);
238 if (r
->req
.cmd
.buf
[0] == MODE_SELECT
&& r
->req
.cmd
.buf
[4] == 12 &&
239 s
->qdev
.type
== TYPE_TAPE
) {
240 s
->qdev
.blocksize
= (r
->buf
[9] << 16) | (r
->buf
[10] << 8) | r
->buf
[11];
241 DPRINTF("block size %d\n", s
->qdev
.blocksize
);
244 scsi_command_complete(r
, ret
);
247 /* Write data to a scsi device. Returns nonzero on failure.
248 The transfer may complete asynchronously. */
249 static int scsi_write_data(SCSIDevice
*d
, uint32_t tag
)
251 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
255 DPRINTF("scsi_write_data 0x%x\n", tag
);
256 r
= scsi_find_request(s
, tag
);
258 BADF("Bad write tag 0x%x\n", tag
);
259 /* ??? This is the wrong error. */
260 scsi_command_complete(r
, -EINVAL
);
266 scsi_req_data(&r
->req
, r
->len
);
270 ret
= execute_command(s
->bs
, r
, SG_DXFER_TO_DEV
, scsi_write_complete
);
272 scsi_command_complete(r
, -EINVAL
);
279 /* Return a pointer to the data buffer. */
280 static uint8_t *scsi_get_buf(SCSIDevice
*d
, uint32_t tag
)
282 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
284 r
= scsi_find_request(s
, tag
);
286 BADF("Bad buffer tag 0x%x\n", tag
);
292 static void scsi_req_fixup(SCSIRequest
*req
)
294 switch(req
->cmd
.buf
[0]) {
296 req
->cmd
.buf
[1] &= ~0x08; /* disable FUA */
299 req
->cmd
.buf
[1] &= ~0x08; /* disable FUA */
303 if (req
->dev
->type
== TYPE_TAPE
) {
304 /* force IMMED, otherwise qemu waits end of command */
305 req
->cmd
.buf
[1] = 0x01;
311 /* Execute a scsi command. Returns the length of the data expected by the
312 command. This will be Positive for data transfers from the device
313 (eg. disk reads), negative for transfers to the device (eg. disk writes),
314 and zero if the command does not transfer any data. */
316 static int32_t scsi_send_command(SCSIDevice
*d
, uint32_t tag
,
317 uint8_t *cmd
, int lun
)
319 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
324 if (cmd
[0] != REQUEST_SENSE
&&
325 (lun
!= s
->lun
|| (cmd
[1] >> 5) != s
->lun
)) {
326 DPRINTF("Unimplemented LUN %d\n", lun
? lun
: cmd
[1] >> 5);
328 s
->sensebuf
[0] = 0x70;
329 s
->sensebuf
[1] = 0x00;
330 s
->sensebuf
[2] = ILLEGAL_REQUEST
;
331 s
->sensebuf
[3] = 0x00;
332 s
->sensebuf
[4] = 0x00;
333 s
->sensebuf
[5] = 0x00;
334 s
->sensebuf
[6] = 0x00;
336 s
->driver_status
= SG_ERR_DRIVER_SENSE
;
337 bus
= scsi_bus_from_device(d
);
338 bus
->complete(bus
, SCSI_REASON_DONE
, tag
, CHECK_CONDITION
);
342 r
= scsi_find_request(s
, tag
);
344 BADF("Tag 0x%x already in use %p\n", tag
, r
);
345 scsi_cancel_io(d
, tag
);
347 r
= scsi_new_request(d
, tag
, lun
);
349 if (-1 == scsi_req_parse(&r
->req
, cmd
)) {
350 BADF("Unsupported command length, command %x\n", cmd
[0]);
351 scsi_remove_request(r
);
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
, -EINVAL
);
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
;
396 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_purge_requests(SCSIGenericState
*s
)
464 while (!QTAILQ_EMPTY(&s
->qdev
.requests
)) {
465 r
= DO_UPCAST(SCSIGenericReq
, req
, QTAILQ_FIRST(&s
->qdev
.requests
));
467 bdrv_aio_cancel(r
->req
.aiocb
);
469 scsi_remove_request(r
);
473 static void scsi_generic_reset(DeviceState
*dev
)
475 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
.qdev
, dev
);
477 scsi_generic_purge_requests(s
);
480 static void scsi_destroy(SCSIDevice
*d
)
482 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
484 scsi_generic_purge_requests(s
);
485 blockdev_mark_auto_del(s
->qdev
.conf
.bs
);
488 static int scsi_generic_initfn(SCSIDevice
*dev
)
490 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, dev
);
492 struct sg_scsi_id scsiid
;
494 if (!s
->qdev
.conf
.bs
) {
495 error_report("scsi-generic: drive property not set");
498 s
->bs
= s
->qdev
.conf
.bs
;
500 /* check we are really using a /dev/sg* file */
501 if (!bdrv_is_sg(s
->bs
)) {
502 error_report("scsi-generic: not /dev/sg*");
506 if (bdrv_get_on_error(s
->bs
, 0) != BLOCK_ERR_STOP_ENOSPC
) {
507 error_report("Device doesn't support drive option werror");
510 if (bdrv_get_on_error(s
->bs
, 1) != BLOCK_ERR_REPORT
) {
511 error_report("Device doesn't support drive option rerror");
515 /* check we are using a driver managing SG_IO (version 3 and after */
516 if (bdrv_ioctl(s
->bs
, SG_GET_VERSION_NUM
, &sg_version
) < 0 ||
517 sg_version
< 30000) {
518 error_report("scsi-generic: scsi generic interface too old");
522 /* get LUN of the /dev/sg? */
523 if (bdrv_ioctl(s
->bs
, SG_GET_SCSI_ID
, &scsiid
)) {
524 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
528 /* define device state */
530 DPRINTF("LUN %d\n", s
->lun
);
531 s
->qdev
.type
= scsiid
.scsi_type
;
532 DPRINTF("device type %d\n", s
->qdev
.type
);
533 if (s
->qdev
.type
== TYPE_TAPE
) {
534 s
->qdev
.blocksize
= get_stream_blocksize(s
->bs
);
535 if (s
->qdev
.blocksize
== -1)
536 s
->qdev
.blocksize
= 0;
538 s
->qdev
.blocksize
= get_blocksize(s
->bs
);
539 /* removable media returns 0 if not present */
540 if (s
->qdev
.blocksize
<= 0) {
541 if (s
->qdev
.type
== TYPE_ROM
|| s
->qdev
.type
== TYPE_WORM
)
542 s
->qdev
.blocksize
= 2048;
544 s
->qdev
.blocksize
= 512;
547 DPRINTF("block size %d\n", s
->qdev
.blocksize
);
548 s
->driver_status
= 0;
549 memset(s
->sensebuf
, 0, sizeof(s
->sensebuf
));
550 bdrv_set_removable(s
->bs
, 0);
554 static SCSIDeviceInfo scsi_generic_info
= {
555 .qdev
.name
= "scsi-generic",
556 .qdev
.desc
= "pass through generic scsi device (/dev/sg*)",
557 .qdev
.size
= sizeof(SCSIGenericState
),
558 .qdev
.reset
= scsi_generic_reset
,
559 .init
= scsi_generic_initfn
,
560 .destroy
= scsi_destroy
,
561 .send_command
= scsi_send_command
,
562 .read_data
= scsi_read_data
,
563 .write_data
= scsi_write_data
,
564 .cancel_io
= scsi_cancel_io
,
565 .get_buf
= scsi_get_buf
,
566 .qdev
.props
= (Property
[]) {
567 DEFINE_BLOCK_PROPERTIES(SCSIGenericState
, qdev
.conf
),
568 DEFINE_PROP_END_OF_LIST(),
572 static void scsi_generic_register_devices(void)
574 scsi_qdev_register(&scsi_generic_info
);
576 device_init(scsi_generic_register_devices
)
578 #endif /* __linux__ */