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\n");
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
->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 data=0x%02x len %d\n", lun
, tag
,
355 cmd
[0], r
->req
.cmd
.xfer
);
357 if (r
->req
.cmd
.xfer
== 0) {
362 ret
= execute_command(s
->bs
, r
, SG_DXFER_NONE
, scsi_command_complete
);
364 scsi_command_complete(r
, -EINVAL
);
370 if (r
->buflen
!= r
->req
.cmd
.xfer
) {
373 r
->buf
= qemu_malloc(r
->req
.cmd
.xfer
);
374 r
->buflen
= r
->req
.cmd
.xfer
;
377 memset(r
->buf
, 0, r
->buflen
);
378 r
->len
= r
->req
.cmd
.xfer
;
379 if (r
->req
.cmd
.mode
== SCSI_XFER_TO_DEV
) {
381 return -r
->req
.cmd
.xfer
;
384 return r
->req
.cmd
.xfer
;
387 static int get_blocksize(BlockDriverState
*bdrv
)
392 sg_io_hdr_t io_header
;
395 memset(cmd
, 0, sizeof(cmd
));
396 memset(buf
, 0, sizeof(buf
));
397 cmd
[0] = READ_CAPACITY
;
399 memset(&io_header
, 0, sizeof(io_header
));
400 io_header
.interface_id
= 'S';
401 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
402 io_header
.dxfer_len
= sizeof(buf
);
403 io_header
.dxferp
= buf
;
404 io_header
.cmdp
= cmd
;
405 io_header
.cmd_len
= sizeof(cmd
);
406 io_header
.mx_sb_len
= sizeof(sensebuf
);
407 io_header
.sbp
= sensebuf
;
408 io_header
.timeout
= 6000; /* XXX */
410 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
414 return (buf
[4] << 24) | (buf
[5] << 16) | (buf
[6] << 8) | buf
[7];
417 static int get_stream_blocksize(BlockDriverState
*bdrv
)
422 sg_io_hdr_t io_header
;
425 memset(cmd
, 0, sizeof(cmd
));
426 memset(buf
, 0, sizeof(buf
));
428 cmd
[4] = sizeof(buf
);
430 memset(&io_header
, 0, sizeof(io_header
));
431 io_header
.interface_id
= 'S';
432 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
433 io_header
.dxfer_len
= sizeof(buf
);
434 io_header
.dxferp
= buf
;
435 io_header
.cmdp
= cmd
;
436 io_header
.cmd_len
= sizeof(cmd
);
437 io_header
.mx_sb_len
= sizeof(sensebuf
);
438 io_header
.sbp
= sensebuf
;
439 io_header
.timeout
= 6000; /* XXX */
441 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
445 return (buf
[9] << 16) | (buf
[10] << 8) | buf
[11];
448 static void scsi_destroy(SCSIDevice
*d
)
450 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
453 while (!QTAILQ_EMPTY(&s
->qdev
.requests
)) {
454 r
= DO_UPCAST(SCSIGenericReq
, req
, QTAILQ_FIRST(&s
->qdev
.requests
));
455 scsi_remove_request(r
);
457 blockdev_mark_auto_del(s
->qdev
.conf
.bs
);
460 static int scsi_generic_initfn(SCSIDevice
*dev
)
462 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, dev
);
464 struct sg_scsi_id scsiid
;
466 if (!s
->qdev
.conf
.bs
) {
467 error_report("scsi-generic: drive property not set");
470 s
->bs
= s
->qdev
.conf
.bs
;
472 /* check we are really using a /dev/sg* file */
473 if (!bdrv_is_sg(s
->bs
)) {
474 error_report("scsi-generic: not /dev/sg*");
478 if (bdrv_get_on_error(s
->bs
, 0) != BLOCK_ERR_STOP_ENOSPC
) {
479 error_report("Device doesn't support drive option werror");
482 if (bdrv_get_on_error(s
->bs
, 1) != BLOCK_ERR_REPORT
) {
483 error_report("Device doesn't support drive option rerror");
487 /* check we are using a driver managing SG_IO (version 3 and after */
488 if (bdrv_ioctl(s
->bs
, SG_GET_VERSION_NUM
, &sg_version
) < 0 ||
489 sg_version
< 30000) {
490 error_report("scsi-generic: scsi generic interface too old");
494 /* get LUN of the /dev/sg? */
495 if (bdrv_ioctl(s
->bs
, SG_GET_SCSI_ID
, &scsiid
)) {
496 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
500 /* define device state */
502 DPRINTF("LUN %d\n", s
->lun
);
503 s
->qdev
.type
= scsiid
.scsi_type
;
504 DPRINTF("device type %d\n", s
->qdev
.type
);
505 if (s
->qdev
.type
== TYPE_TAPE
) {
506 s
->qdev
.blocksize
= get_stream_blocksize(s
->bs
);
507 if (s
->qdev
.blocksize
== -1)
508 s
->qdev
.blocksize
= 0;
510 s
->qdev
.blocksize
= get_blocksize(s
->bs
);
511 /* removable media returns 0 if not present */
512 if (s
->qdev
.blocksize
<= 0) {
513 if (s
->qdev
.type
== TYPE_ROM
|| s
->qdev
.type
== TYPE_WORM
)
514 s
->qdev
.blocksize
= 2048;
516 s
->qdev
.blocksize
= 512;
519 DPRINTF("block size %d\n", s
->qdev
.blocksize
);
520 s
->driver_status
= 0;
521 memset(s
->sensebuf
, 0, sizeof(s
->sensebuf
));
522 bdrv_set_removable(s
->bs
, 0);
526 static SCSIDeviceInfo scsi_generic_info
= {
527 .qdev
.name
= "scsi-generic",
528 .qdev
.desc
= "pass through generic scsi device (/dev/sg*)",
529 .qdev
.size
= sizeof(SCSIGenericState
),
530 .init
= scsi_generic_initfn
,
531 .destroy
= scsi_destroy
,
532 .send_command
= scsi_send_command
,
533 .read_data
= scsi_read_data
,
534 .write_data
= scsi_write_data
,
535 .cancel_io
= scsi_cancel_io
,
536 .get_buf
= scsi_get_buf
,
537 .qdev
.props
= (Property
[]) {
538 DEFINE_BLOCK_PROPERTIES(SCSIGenericState
, qdev
.conf
),
539 DEFINE_PROP_END_OF_LIST(),
543 static void scsi_generic_register_devices(void)
545 scsi_qdev_register(&scsi_generic_info
);
547 device_init(scsi_generic_register_devices
)
549 #endif /* __linux__ */