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
;
99 r
->req
.status
= BUSY
<< 1;
101 if (s
->driver_status
& SG_ERR_DRIVER_TIMEOUT
) {
102 r
->req
.status
= BUSY
<< 1;
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
<< 1;
109 r
->req
.status
= GOOD
<< 1;
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
);
175 r
->req
.bus
->complete(r
->req
.bus
, SCSI_REASON_DATA
, r
->req
.tag
, len
);
177 scsi_command_complete(r
, 0);
180 /* Read more data from scsi device into buffer. */
181 static void scsi_read_data(SCSIDevice
*d
, uint32_t tag
)
183 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
187 DPRINTF("scsi_read_data 0x%x\n", tag
);
188 r
= scsi_find_request(s
, tag
);
190 BADF("Bad read tag 0x%x\n", tag
);
191 /* ??? This is the wrong error. */
192 scsi_command_complete(r
, -EINVAL
);
197 scsi_command_complete(r
, 0);
201 if (r
->req
.cmd
.buf
[0] == REQUEST_SENSE
&& s
->driver_status
& SG_ERR_DRIVER_SENSE
)
203 s
->senselen
= MIN(r
->len
, s
->senselen
);
204 memcpy(r
->buf
, s
->sensebuf
, s
->senselen
);
205 r
->io_header
.driver_status
= 0;
206 r
->io_header
.status
= 0;
207 r
->io_header
.dxfer_len
= s
->senselen
;
209 DPRINTF("Data ready tag=0x%x len=%d\n", r
->req
.tag
, s
->senselen
);
210 DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
211 r
->buf
[0], r
->buf
[1], r
->buf
[2], r
->buf
[3],
212 r
->buf
[4], r
->buf
[5], r
->buf
[6], r
->buf
[7]);
213 r
->req
.bus
->complete(r
->req
.bus
, SCSI_REASON_DATA
, r
->req
.tag
, s
->senselen
);
217 ret
= execute_command(s
->bs
, r
, SG_DXFER_FROM_DEV
, scsi_read_complete
);
219 scsi_command_complete(r
, -EINVAL
);
224 static void scsi_write_complete(void * opaque
, int ret
)
226 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
227 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
229 DPRINTF("scsi_write_complete() ret = %d\n", ret
);
231 DPRINTF("IO error\n");
232 scsi_command_complete(r
, ret
);
236 if (r
->req
.cmd
.buf
[0] == MODE_SELECT
&& r
->req
.cmd
.buf
[4] == 12 &&
237 s
->qdev
.type
== TYPE_TAPE
) {
238 s
->qdev
.blocksize
= (r
->buf
[9] << 16) | (r
->buf
[10] << 8) | r
->buf
[11];
239 DPRINTF("block size %d\n", s
->qdev
.blocksize
);
242 scsi_command_complete(r
, ret
);
245 /* Write data to a scsi device. Returns nonzero on failure.
246 The transfer may complete asynchronously. */
247 static int scsi_write_data(SCSIDevice
*d
, uint32_t tag
)
249 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
253 DPRINTF("scsi_write_data 0x%x\n", tag
);
254 r
= scsi_find_request(s
, tag
);
256 BADF("Bad write tag 0x%x\n", tag
);
257 /* ??? This is the wrong error. */
258 scsi_command_complete(r
, -EINVAL
);
264 r
->req
.bus
->complete(r
->req
.bus
, SCSI_REASON_DATA
, r
->req
.tag
, r
->len
);
268 ret
= execute_command(s
->bs
, r
, SG_DXFER_TO_DEV
, scsi_write_complete
);
270 scsi_command_complete(r
, -EINVAL
);
277 /* Return a pointer to the data buffer. */
278 static uint8_t *scsi_get_buf(SCSIDevice
*d
, uint32_t tag
)
280 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
282 r
= scsi_find_request(s
, tag
);
284 BADF("Bad buffer tag 0x%x\n", tag
);
290 static void scsi_req_fixup(SCSIRequest
*req
)
292 switch(req
->cmd
.buf
[0]) {
294 req
->cmd
.buf
[1] &= ~0x08; /* disable FUA */
297 req
->cmd
.buf
[1] &= ~0x08; /* disable FUA */
301 if (req
->dev
->type
== TYPE_TAPE
) {
302 /* force IMMED, otherwise qemu waits end of command */
303 req
->cmd
.buf
[1] = 0x01;
309 /* Execute a scsi command. Returns the length of the data expected by the
310 command. This will be Positive for data transfers from the device
311 (eg. disk reads), negative for transfers to the device (eg. disk writes),
312 and zero if the command does not transfer any data. */
314 static int32_t scsi_send_command(SCSIDevice
*d
, uint32_t tag
,
315 uint8_t *cmd
, int lun
)
317 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
322 if (cmd
[0] != REQUEST_SENSE
&&
323 (lun
!= s
->lun
|| (cmd
[1] >> 5) != s
->lun
)) {
324 DPRINTF("Unimplemented LUN %d\n", lun
? lun
: cmd
[1] >> 5);
326 s
->sensebuf
[0] = 0x70;
327 s
->sensebuf
[1] = 0x00;
328 s
->sensebuf
[2] = ILLEGAL_REQUEST
;
329 s
->sensebuf
[3] = 0x00;
330 s
->sensebuf
[4] = 0x00;
331 s
->sensebuf
[5] = 0x00;
332 s
->sensebuf
[6] = 0x00;
334 s
->driver_status
= SG_ERR_DRIVER_SENSE
;
335 bus
= scsi_bus_from_device(d
);
336 bus
->complete(bus
, SCSI_REASON_DONE
, tag
, CHECK_CONDITION
<< 1);
340 r
= scsi_find_request(s
, tag
);
342 BADF("Tag 0x%x already in use %p\n", tag
, r
);
343 scsi_cancel_io(d
, tag
);
345 r
= scsi_new_request(d
, tag
, lun
);
347 if (-1 == scsi_req_parse(&r
->req
, cmd
)) {
348 BADF("Unsupported command length, command %x\n", cmd
[0]);
349 scsi_remove_request(r
);
352 scsi_req_fixup(&r
->req
);
354 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun
, tag
,
355 r
->req
.cmd
.xfer
, cmd
[0]);
360 for (i
= 1; i
< r
->req
.cmd
.len
; i
++) {
361 printf(" 0x%02x", cmd
[i
]);
367 if (r
->req
.cmd
.xfer
== 0) {
372 ret
= execute_command(s
->bs
, r
, SG_DXFER_NONE
, scsi_command_complete
);
374 scsi_command_complete(r
, -EINVAL
);
380 if (r
->buflen
!= r
->req
.cmd
.xfer
) {
383 r
->buf
= qemu_malloc(r
->req
.cmd
.xfer
);
384 r
->buflen
= r
->req
.cmd
.xfer
;
387 memset(r
->buf
, 0, r
->buflen
);
388 r
->len
= r
->req
.cmd
.xfer
;
389 if (r
->req
.cmd
.mode
== SCSI_XFER_TO_DEV
) {
391 return -r
->req
.cmd
.xfer
;
394 return r
->req
.cmd
.xfer
;
397 static int get_blocksize(BlockDriverState
*bdrv
)
402 sg_io_hdr_t io_header
;
405 memset(cmd
, 0, sizeof(cmd
));
406 memset(buf
, 0, sizeof(buf
));
407 cmd
[0] = READ_CAPACITY
;
409 memset(&io_header
, 0, sizeof(io_header
));
410 io_header
.interface_id
= 'S';
411 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
412 io_header
.dxfer_len
= sizeof(buf
);
413 io_header
.dxferp
= buf
;
414 io_header
.cmdp
= cmd
;
415 io_header
.cmd_len
= sizeof(cmd
);
416 io_header
.mx_sb_len
= sizeof(sensebuf
);
417 io_header
.sbp
= sensebuf
;
418 io_header
.timeout
= 6000; /* XXX */
420 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
424 return (buf
[4] << 24) | (buf
[5] << 16) | (buf
[6] << 8) | buf
[7];
427 static int get_stream_blocksize(BlockDriverState
*bdrv
)
432 sg_io_hdr_t io_header
;
435 memset(cmd
, 0, sizeof(cmd
));
436 memset(buf
, 0, sizeof(buf
));
438 cmd
[4] = sizeof(buf
);
440 memset(&io_header
, 0, sizeof(io_header
));
441 io_header
.interface_id
= 'S';
442 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
443 io_header
.dxfer_len
= sizeof(buf
);
444 io_header
.dxferp
= buf
;
445 io_header
.cmdp
= cmd
;
446 io_header
.cmd_len
= sizeof(cmd
);
447 io_header
.mx_sb_len
= sizeof(sensebuf
);
448 io_header
.sbp
= sensebuf
;
449 io_header
.timeout
= 6000; /* XXX */
451 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
455 return (buf
[9] << 16) | (buf
[10] << 8) | buf
[11];
458 static void scsi_destroy(SCSIDevice
*d
)
460 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
463 while (!QTAILQ_EMPTY(&s
->qdev
.requests
)) {
464 r
= DO_UPCAST(SCSIGenericReq
, req
, QTAILQ_FIRST(&s
->qdev
.requests
));
465 scsi_remove_request(r
);
467 blockdev_mark_auto_del(s
->qdev
.conf
.bs
);
470 static int scsi_generic_initfn(SCSIDevice
*dev
)
472 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, dev
);
474 struct sg_scsi_id scsiid
;
476 if (!s
->qdev
.conf
.bs
) {
477 error_report("scsi-generic: drive property not set");
480 s
->bs
= s
->qdev
.conf
.bs
;
482 /* check we are really using a /dev/sg* file */
483 if (!bdrv_is_sg(s
->bs
)) {
484 error_report("scsi-generic: not /dev/sg*");
488 if (bdrv_get_on_error(s
->bs
, 0) != BLOCK_ERR_STOP_ENOSPC
) {
489 error_report("Device doesn't support drive option werror");
492 if (bdrv_get_on_error(s
->bs
, 1) != BLOCK_ERR_REPORT
) {
493 error_report("Device doesn't support drive option rerror");
497 /* check we are using a driver managing SG_IO (version 3 and after */
498 if (bdrv_ioctl(s
->bs
, SG_GET_VERSION_NUM
, &sg_version
) < 0 ||
499 sg_version
< 30000) {
500 error_report("scsi-generic: scsi generic interface too old");
504 /* get LUN of the /dev/sg? */
505 if (bdrv_ioctl(s
->bs
, SG_GET_SCSI_ID
, &scsiid
)) {
506 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
510 /* define device state */
512 DPRINTF("LUN %d\n", s
->lun
);
513 s
->qdev
.type
= scsiid
.scsi_type
;
514 DPRINTF("device type %d\n", s
->qdev
.type
);
515 if (s
->qdev
.type
== TYPE_TAPE
) {
516 s
->qdev
.blocksize
= get_stream_blocksize(s
->bs
);
517 if (s
->qdev
.blocksize
== -1)
518 s
->qdev
.blocksize
= 0;
520 s
->qdev
.blocksize
= get_blocksize(s
->bs
);
521 /* removable media returns 0 if not present */
522 if (s
->qdev
.blocksize
<= 0) {
523 if (s
->qdev
.type
== TYPE_ROM
|| s
->qdev
.type
== TYPE_WORM
)
524 s
->qdev
.blocksize
= 2048;
526 s
->qdev
.blocksize
= 512;
529 DPRINTF("block size %d\n", s
->qdev
.blocksize
);
530 s
->driver_status
= 0;
531 memset(s
->sensebuf
, 0, sizeof(s
->sensebuf
));
532 bdrv_set_removable(s
->bs
, 0);
536 static SCSIDeviceInfo scsi_generic_info
= {
537 .qdev
.name
= "scsi-generic",
538 .qdev
.desc
= "pass through generic scsi device (/dev/sg*)",
539 .qdev
.size
= sizeof(SCSIGenericState
),
540 .init
= scsi_generic_initfn
,
541 .destroy
= scsi_destroy
,
542 .send_command
= scsi_send_command
,
543 .read_data
= scsi_read_data
,
544 .write_data
= scsi_write_data
,
545 .cancel_io
= scsi_cancel_io
,
546 .get_buf
= scsi_get_buf
,
547 .qdev
.props
= (Property
[]) {
548 DEFINE_BLOCK_PROPERTIES(SCSIGenericState
, qdev
.conf
),
549 DEFINE_PROP_END_OF_LIST(),
553 static void scsi_generic_register_devices(void)
555 scsi_qdev_register(&scsi_generic_info
);
557 device_init(scsi_generic_register_devices
)
559 #endif /* __linux__ */