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 void scsi_set_sense(SCSIGenericState
*s
, SCSISense sense
)
71 s
->senselen
= scsi_build_sense(sense
, s
->sensebuf
, SCSI_SENSE_BUF_SIZE
, 0);
72 s
->driver_status
= SG_ERR_DRIVER_SENSE
;
75 static void scsi_clear_sense(SCSIGenericState
*s
)
77 memset(s
->sensebuf
, 0, SCSI_SENSE_BUF_SIZE
);
82 static SCSIRequest
*scsi_new_request(SCSIDevice
*d
, uint32_t tag
, uint32_t lun
)
86 req
= scsi_req_alloc(sizeof(SCSIGenericReq
), d
, tag
, lun
);
90 static void scsi_free_request(SCSIRequest
*req
)
92 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
97 /* Helper function for command completion. */
98 static void scsi_command_complete(void *opaque
, int ret
)
100 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
101 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
104 s
->driver_status
= r
->io_header
.driver_status
;
105 if (s
->driver_status
& SG_ERR_DRIVER_SENSE
)
106 s
->senselen
= r
->io_header
.sb_len_wr
;
111 r
->req
.status
= CHECK_CONDITION
;
112 scsi_set_sense(s
, SENSE_CODE(INVALID_FIELD
));
115 r
->req
.status
= CHECK_CONDITION
;
116 scsi_set_sense(s
, SENSE_CODE(TARGET_FAILURE
));
119 r
->req
.status
= CHECK_CONDITION
;
120 scsi_set_sense(s
, SENSE_CODE(IO_ERROR
));
124 if (s
->driver_status
& SG_ERR_DRIVER_TIMEOUT
) {
125 r
->req
.status
= BUSY
;
126 BADF("Driver Timeout\n");
127 } else if (r
->io_header
.status
)
128 r
->req
.status
= r
->io_header
.status
;
129 else if (s
->driver_status
& SG_ERR_DRIVER_SENSE
)
130 r
->req
.status
= CHECK_CONDITION
;
132 r
->req
.status
= GOOD
;
134 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
135 r
, r
->req
.tag
, r
->req
.status
);
137 scsi_req_complete(&r
->req
);
140 /* Cancel a pending data transfer. */
141 static void scsi_cancel_io(SCSIRequest
*req
)
143 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
145 DPRINTF("Cancel tag=0x%x\n", req
->tag
);
147 bdrv_aio_cancel(r
->req
.aiocb
);
152 static int execute_command(BlockDriverState
*bdrv
,
153 SCSIGenericReq
*r
, int direction
,
154 BlockDriverCompletionFunc
*complete
)
156 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
158 r
->io_header
.interface_id
= 'S';
159 r
->io_header
.dxfer_direction
= direction
;
160 r
->io_header
.dxferp
= r
->buf
;
161 r
->io_header
.dxfer_len
= r
->buflen
;
162 r
->io_header
.cmdp
= r
->req
.cmd
.buf
;
163 r
->io_header
.cmd_len
= r
->req
.cmd
.len
;
164 r
->io_header
.mx_sb_len
= sizeof(s
->sensebuf
);
165 r
->io_header
.sbp
= s
->sensebuf
;
166 r
->io_header
.timeout
= MAX_UINT
;
167 r
->io_header
.usr_ptr
= r
;
168 r
->io_header
.flags
|= SG_FLAG_DIRECT_IO
;
170 r
->req
.aiocb
= bdrv_aio_ioctl(bdrv
, SG_IO
, &r
->io_header
, complete
, r
);
171 if (r
->req
.aiocb
== NULL
) {
172 BADF("execute_command: read failed !\n");
179 static void scsi_read_complete(void * opaque
, int ret
)
181 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
186 DPRINTF("IO error ret %d\n", ret
);
187 scsi_command_complete(r
, ret
);
190 len
= r
->io_header
.dxfer_len
- r
->io_header
.resid
;
191 DPRINTF("Data ready tag=0x%x len=%d\n", r
->req
.tag
, len
);
195 scsi_command_complete(r
, 0);
197 scsi_req_data(&r
->req
, len
);
201 /* Read more data from scsi device into buffer. */
202 static void scsi_read_data(SCSIRequest
*req
)
204 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
205 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
208 DPRINTF("scsi_read_data 0x%x\n", req
->tag
);
210 scsi_command_complete(r
, 0);
214 if (r
->req
.cmd
.buf
[0] == REQUEST_SENSE
&& s
->driver_status
& SG_ERR_DRIVER_SENSE
)
216 s
->senselen
= MIN(r
->len
, s
->senselen
);
217 memcpy(r
->buf
, s
->sensebuf
, s
->senselen
);
218 r
->io_header
.driver_status
= 0;
219 r
->io_header
.status
= 0;
220 r
->io_header
.dxfer_len
= s
->senselen
;
222 DPRINTF("Data ready tag=0x%x len=%d\n", r
->req
.tag
, s
->senselen
);
223 DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
224 r
->buf
[0], r
->buf
[1], r
->buf
[2], r
->buf
[3],
225 r
->buf
[4], r
->buf
[5], r
->buf
[6], r
->buf
[7]);
226 scsi_req_data(&r
->req
, s
->senselen
);
227 /* Clear sensebuf after REQUEST_SENSE */
232 ret
= execute_command(s
->bs
, r
, SG_DXFER_FROM_DEV
, scsi_read_complete
);
234 scsi_command_complete(r
, ret
);
239 static void scsi_write_complete(void * opaque
, int ret
)
241 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
242 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
244 DPRINTF("scsi_write_complete() ret = %d\n", ret
);
247 DPRINTF("IO error\n");
248 scsi_command_complete(r
, ret
);
252 if (r
->req
.cmd
.buf
[0] == MODE_SELECT
&& r
->req
.cmd
.buf
[4] == 12 &&
253 s
->qdev
.type
== TYPE_TAPE
) {
254 s
->qdev
.blocksize
= (r
->buf
[9] << 16) | (r
->buf
[10] << 8) | r
->buf
[11];
255 DPRINTF("block size %d\n", s
->qdev
.blocksize
);
258 scsi_command_complete(r
, ret
);
261 /* Write data to a scsi device. Returns nonzero on failure.
262 The transfer may complete asynchronously. */
263 static int scsi_write_data(SCSIRequest
*req
)
265 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, req
->dev
);
266 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
269 DPRINTF("scsi_write_data 0x%x\n", req
->tag
);
272 scsi_req_data(&r
->req
, r
->len
);
276 ret
= execute_command(s
->bs
, r
, SG_DXFER_TO_DEV
, scsi_write_complete
);
278 scsi_command_complete(r
, ret
);
285 /* Return a pointer to the data buffer. */
286 static uint8_t *scsi_get_buf(SCSIRequest
*req
)
288 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
293 static void scsi_req_fixup(SCSIRequest
*req
)
295 switch(req
->cmd
.buf
[0]) {
297 req
->cmd
.buf
[1] &= ~0x08; /* disable FUA */
300 req
->cmd
.buf
[1] &= ~0x08; /* disable FUA */
304 if (req
->dev
->type
== TYPE_TAPE
) {
305 /* force IMMED, otherwise qemu waits end of command */
306 req
->cmd
.buf
[1] = 0x01;
312 /* Execute a scsi command. Returns the length of the data expected by the
313 command. This will be Positive for data transfers from the device
314 (eg. disk reads), negative for transfers to the device (eg. disk writes),
315 and zero if the command does not transfer any data. */
317 static int32_t scsi_send_command(SCSIRequest
*req
, uint8_t *cmd
)
319 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, req
->dev
);
320 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
323 if (cmd
[0] != REQUEST_SENSE
&&
324 (req
->lun
!= s
->lun
|| (cmd
[1] >> 5) != s
->lun
)) {
325 DPRINTF("Unimplemented LUN %d\n", req
->lun
? req
->lun
: cmd
[1] >> 5);
326 scsi_set_sense(s
, SENSE_CODE(LUN_NOT_SUPPORTED
));
327 r
->req
.status
= CHECK_CONDITION
;
328 scsi_req_complete(&r
->req
);
332 if (-1 == scsi_req_parse(&r
->req
, cmd
)) {
333 BADF("Unsupported command length, command %x\n", cmd
[0]);
334 scsi_command_complete(r
, -EINVAL
);
337 scsi_req_fixup(&r
->req
);
339 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun
, tag
,
340 r
->req
.cmd
.xfer
, cmd
[0]);
345 for (i
= 1; i
< r
->req
.cmd
.len
; i
++) {
346 printf(" 0x%02x", cmd
[i
]);
352 if (r
->req
.cmd
.xfer
== 0) {
357 ret
= execute_command(s
->bs
, r
, SG_DXFER_NONE
, scsi_command_complete
);
359 scsi_command_complete(r
, ret
);
365 if (r
->buflen
!= r
->req
.cmd
.xfer
) {
368 r
->buf
= qemu_malloc(r
->req
.cmd
.xfer
);
369 r
->buflen
= r
->req
.cmd
.xfer
;
372 memset(r
->buf
, 0, r
->buflen
);
373 r
->len
= r
->req
.cmd
.xfer
;
374 if (r
->req
.cmd
.mode
== SCSI_XFER_TO_DEV
) {
376 return -r
->req
.cmd
.xfer
;
378 return r
->req
.cmd
.xfer
;
382 static int get_blocksize(BlockDriverState
*bdrv
)
387 sg_io_hdr_t io_header
;
390 memset(cmd
, 0, sizeof(cmd
));
391 memset(buf
, 0, sizeof(buf
));
392 cmd
[0] = READ_CAPACITY
;
394 memset(&io_header
, 0, sizeof(io_header
));
395 io_header
.interface_id
= 'S';
396 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
397 io_header
.dxfer_len
= sizeof(buf
);
398 io_header
.dxferp
= buf
;
399 io_header
.cmdp
= cmd
;
400 io_header
.cmd_len
= sizeof(cmd
);
401 io_header
.mx_sb_len
= sizeof(sensebuf
);
402 io_header
.sbp
= sensebuf
;
403 io_header
.timeout
= 6000; /* XXX */
405 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
409 return (buf
[4] << 24) | (buf
[5] << 16) | (buf
[6] << 8) | buf
[7];
412 static int get_stream_blocksize(BlockDriverState
*bdrv
)
417 sg_io_hdr_t io_header
;
420 memset(cmd
, 0, sizeof(cmd
));
421 memset(buf
, 0, sizeof(buf
));
423 cmd
[4] = sizeof(buf
);
425 memset(&io_header
, 0, sizeof(io_header
));
426 io_header
.interface_id
= 'S';
427 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
428 io_header
.dxfer_len
= sizeof(buf
);
429 io_header
.dxferp
= buf
;
430 io_header
.cmdp
= cmd
;
431 io_header
.cmd_len
= sizeof(cmd
);
432 io_header
.mx_sb_len
= sizeof(sensebuf
);
433 io_header
.sbp
= sensebuf
;
434 io_header
.timeout
= 6000; /* XXX */
436 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
440 return (buf
[9] << 16) | (buf
[10] << 8) | buf
[11];
443 static void scsi_generic_reset(DeviceState
*dev
)
445 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
.qdev
, dev
);
447 scsi_device_purge_requests(&s
->qdev
);
450 static void scsi_destroy(SCSIDevice
*d
)
452 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
454 scsi_device_purge_requests(&s
->qdev
);
455 blockdev_mark_auto_del(s
->qdev
.conf
.bs
);
458 static int scsi_generic_initfn(SCSIDevice
*dev
)
460 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, dev
);
462 struct sg_scsi_id scsiid
;
464 if (!s
->qdev
.conf
.bs
) {
465 error_report("scsi-generic: drive property not set");
468 s
->bs
= s
->qdev
.conf
.bs
;
470 /* check we are really using a /dev/sg* file */
471 if (!bdrv_is_sg(s
->bs
)) {
472 error_report("scsi-generic: not /dev/sg*");
476 if (bdrv_get_on_error(s
->bs
, 0) != BLOCK_ERR_STOP_ENOSPC
) {
477 error_report("Device doesn't support drive option werror");
480 if (bdrv_get_on_error(s
->bs
, 1) != BLOCK_ERR_REPORT
) {
481 error_report("Device doesn't support drive option rerror");
485 /* check we are using a driver managing SG_IO (version 3 and after */
486 if (bdrv_ioctl(s
->bs
, SG_GET_VERSION_NUM
, &sg_version
) < 0 ||
487 sg_version
< 30000) {
488 error_report("scsi-generic: scsi generic interface too old");
492 /* get LUN of the /dev/sg? */
493 if (bdrv_ioctl(s
->bs
, SG_GET_SCSI_ID
, &scsiid
)) {
494 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
498 /* define device state */
500 DPRINTF("LUN %d\n", s
->lun
);
501 s
->qdev
.type
= scsiid
.scsi_type
;
502 DPRINTF("device type %d\n", s
->qdev
.type
);
503 if (s
->qdev
.type
== TYPE_TAPE
) {
504 s
->qdev
.blocksize
= get_stream_blocksize(s
->bs
);
505 if (s
->qdev
.blocksize
== -1)
506 s
->qdev
.blocksize
= 0;
508 s
->qdev
.blocksize
= get_blocksize(s
->bs
);
509 /* removable media returns 0 if not present */
510 if (s
->qdev
.blocksize
<= 0) {
511 if (s
->qdev
.type
== TYPE_ROM
|| s
->qdev
.type
== TYPE_WORM
)
512 s
->qdev
.blocksize
= 2048;
514 s
->qdev
.blocksize
= 512;
517 DPRINTF("block size %d\n", s
->qdev
.blocksize
);
518 s
->driver_status
= 0;
519 memset(s
->sensebuf
, 0, sizeof(s
->sensebuf
));
520 bdrv_set_removable(s
->bs
, 0);
524 static SCSIDeviceInfo scsi_generic_info
= {
525 .qdev
.name
= "scsi-generic",
526 .qdev
.desc
= "pass through generic scsi device (/dev/sg*)",
527 .qdev
.size
= sizeof(SCSIGenericState
),
528 .qdev
.reset
= scsi_generic_reset
,
529 .init
= scsi_generic_initfn
,
530 .destroy
= scsi_destroy
,
531 .alloc_req
= scsi_new_request
,
532 .free_req
= scsi_free_request
,
533 .send_command
= scsi_send_command
,
534 .read_data
= scsi_read_data
,
535 .write_data
= scsi_write_data
,
536 .cancel_io
= scsi_cancel_io
,
537 .get_buf
= scsi_get_buf
,
538 .qdev
.props
= (Property
[]) {
539 DEFINE_BLOCK_PROPERTIES(SCSIGenericState
, qdev
.conf
),
540 DEFINE_PROP_END_OF_LIST(),
544 static void scsi_generic_register_devices(void)
546 scsi_qdev_register(&scsi_generic_info
);
548 device_init(scsi_generic_register_devices
)
550 #endif /* __linux__ */