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 SCSIRequest
*scsi_new_request(SCSIDevice
*d
, uint32_t tag
, uint32_t lun
)
73 req
= scsi_req_alloc(sizeof(SCSIGenericReq
), d
, tag
, lun
);
77 static void scsi_free_request(SCSIRequest
*req
)
79 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
84 /* Helper function for command completion. */
85 static void scsi_command_complete(void *opaque
, int ret
)
87 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
88 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
91 s
->driver_status
= r
->io_header
.driver_status
;
92 if (s
->driver_status
& SG_ERR_DRIVER_SENSE
)
93 s
->senselen
= r
->io_header
.sb_len_wr
;
98 if (s
->driver_status
& SG_ERR_DRIVER_TIMEOUT
) {
100 BADF("Driver Timeout\n");
101 } else if (r
->io_header
.status
)
102 r
->req
.status
= r
->io_header
.status
;
103 else if (s
->driver_status
& SG_ERR_DRIVER_SENSE
)
104 r
->req
.status
= CHECK_CONDITION
;
106 r
->req
.status
= GOOD
;
108 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
109 r
, r
->req
.tag
, r
->req
.status
);
111 scsi_req_complete(&r
->req
);
114 /* Cancel a pending data transfer. */
115 static void scsi_cancel_io(SCSIRequest
*req
)
117 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
119 DPRINTF("Cancel tag=0x%x\n", req
->tag
);
121 bdrv_aio_cancel(r
->req
.aiocb
);
126 static int execute_command(BlockDriverState
*bdrv
,
127 SCSIGenericReq
*r
, int direction
,
128 BlockDriverCompletionFunc
*complete
)
130 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
132 r
->io_header
.interface_id
= 'S';
133 r
->io_header
.dxfer_direction
= direction
;
134 r
->io_header
.dxferp
= r
->buf
;
135 r
->io_header
.dxfer_len
= r
->buflen
;
136 r
->io_header
.cmdp
= r
->req
.cmd
.buf
;
137 r
->io_header
.cmd_len
= r
->req
.cmd
.len
;
138 r
->io_header
.mx_sb_len
= sizeof(s
->sensebuf
);
139 r
->io_header
.sbp
= s
->sensebuf
;
140 r
->io_header
.timeout
= MAX_UINT
;
141 r
->io_header
.usr_ptr
= r
;
142 r
->io_header
.flags
|= SG_FLAG_DIRECT_IO
;
144 r
->req
.aiocb
= bdrv_aio_ioctl(bdrv
, SG_IO
, &r
->io_header
, complete
, r
);
145 if (r
->req
.aiocb
== NULL
) {
146 BADF("execute_command: read failed !\n");
153 static void scsi_read_complete(void * opaque
, int ret
)
155 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
160 DPRINTF("IO error ret %d\n", ret
);
161 scsi_command_complete(r
, ret
);
164 len
= r
->io_header
.dxfer_len
- r
->io_header
.resid
;
165 DPRINTF("Data ready tag=0x%x len=%d\n", r
->req
.tag
, len
);
169 scsi_command_complete(r
, 0);
171 scsi_req_data(&r
->req
, len
);
175 /* Read more data from scsi device into buffer. */
176 static void scsi_read_data(SCSIRequest
*req
)
178 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
179 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
182 DPRINTF("scsi_read_data 0x%x\n", req
->tag
);
184 scsi_command_complete(r
, 0);
188 if (r
->req
.cmd
.buf
[0] == REQUEST_SENSE
&& s
->driver_status
& SG_ERR_DRIVER_SENSE
)
190 s
->senselen
= MIN(r
->len
, s
->senselen
);
191 memcpy(r
->buf
, s
->sensebuf
, s
->senselen
);
192 r
->io_header
.driver_status
= 0;
193 r
->io_header
.status
= 0;
194 r
->io_header
.dxfer_len
= s
->senselen
;
196 DPRINTF("Data ready tag=0x%x len=%d\n", r
->req
.tag
, s
->senselen
);
197 DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
198 r
->buf
[0], r
->buf
[1], r
->buf
[2], r
->buf
[3],
199 r
->buf
[4], r
->buf
[5], r
->buf
[6], r
->buf
[7]);
200 scsi_req_data(&r
->req
, s
->senselen
);
204 ret
= execute_command(s
->bs
, r
, SG_DXFER_FROM_DEV
, scsi_read_complete
);
206 scsi_command_complete(r
, -EINVAL
);
211 static void scsi_write_complete(void * opaque
, int ret
)
213 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
214 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
216 DPRINTF("scsi_write_complete() ret = %d\n", ret
);
219 DPRINTF("IO error\n");
220 scsi_command_complete(r
, ret
);
224 if (r
->req
.cmd
.buf
[0] == MODE_SELECT
&& r
->req
.cmd
.buf
[4] == 12 &&
225 s
->qdev
.type
== TYPE_TAPE
) {
226 s
->qdev
.blocksize
= (r
->buf
[9] << 16) | (r
->buf
[10] << 8) | r
->buf
[11];
227 DPRINTF("block size %d\n", s
->qdev
.blocksize
);
230 scsi_command_complete(r
, ret
);
233 /* Write data to a scsi device. Returns nonzero on failure.
234 The transfer may complete asynchronously. */
235 static int scsi_write_data(SCSIRequest
*req
)
237 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, req
->dev
);
238 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
241 DPRINTF("scsi_write_data 0x%x\n", req
->tag
);
244 scsi_req_data(&r
->req
, r
->len
);
248 ret
= execute_command(s
->bs
, r
, SG_DXFER_TO_DEV
, scsi_write_complete
);
250 scsi_command_complete(r
, -EINVAL
);
257 /* Return a pointer to the data buffer. */
258 static uint8_t *scsi_get_buf(SCSIRequest
*req
)
260 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
265 static void scsi_req_fixup(SCSIRequest
*req
)
267 switch(req
->cmd
.buf
[0]) {
269 req
->cmd
.buf
[1] &= ~0x08; /* disable FUA */
272 req
->cmd
.buf
[1] &= ~0x08; /* disable FUA */
276 if (req
->dev
->type
== TYPE_TAPE
) {
277 /* force IMMED, otherwise qemu waits end of command */
278 req
->cmd
.buf
[1] = 0x01;
284 /* Execute a scsi command. Returns the length of the data expected by the
285 command. This will be Positive for data transfers from the device
286 (eg. disk reads), negative for transfers to the device (eg. disk writes),
287 and zero if the command does not transfer any data. */
289 static int32_t scsi_send_command(SCSIRequest
*req
, uint8_t *cmd
)
291 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, req
->dev
);
292 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
296 scsi_req_enqueue(req
);
297 if (cmd
[0] != REQUEST_SENSE
&&
298 (req
->lun
!= s
->lun
|| (cmd
[1] >> 5) != s
->lun
)) {
299 DPRINTF("Unimplemented LUN %d\n", req
->lun
? req
->lun
: cmd
[1] >> 5);
301 s
->sensebuf
[0] = 0x70;
302 s
->sensebuf
[1] = 0x00;
303 s
->sensebuf
[2] = ILLEGAL_REQUEST
;
304 s
->sensebuf
[3] = 0x00;
305 s
->sensebuf
[4] = 0x00;
306 s
->sensebuf
[5] = 0x00;
307 s
->sensebuf
[6] = 0x00;
309 s
->driver_status
= SG_ERR_DRIVER_SENSE
;
310 bus
= scsi_bus_from_device(&s
->qdev
);
311 bus
->ops
->complete(req
, SCSI_REASON_DONE
, CHECK_CONDITION
);
315 if (-1 == scsi_req_parse(&r
->req
, cmd
)) {
316 BADF("Unsupported command length, command %x\n", cmd
[0]);
317 scsi_req_dequeue(&r
->req
);
318 scsi_req_unref(&r
->req
);
321 scsi_req_fixup(&r
->req
);
323 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun
, tag
,
324 r
->req
.cmd
.xfer
, cmd
[0]);
329 for (i
= 1; i
< r
->req
.cmd
.len
; i
++) {
330 printf(" 0x%02x", cmd
[i
]);
336 if (r
->req
.cmd
.xfer
== 0) {
341 ret
= execute_command(s
->bs
, r
, SG_DXFER_NONE
, scsi_command_complete
);
343 scsi_command_complete(r
, -EINVAL
);
348 if (r
->buflen
!= r
->req
.cmd
.xfer
) {
351 r
->buf
= qemu_malloc(r
->req
.cmd
.xfer
);
352 r
->buflen
= r
->req
.cmd
.xfer
;
355 memset(r
->buf
, 0, r
->buflen
);
356 r
->len
= r
->req
.cmd
.xfer
;
357 if (r
->req
.cmd
.mode
== SCSI_XFER_TO_DEV
) {
359 return -r
->req
.cmd
.xfer
;
361 return r
->req
.cmd
.xfer
;
365 static int get_blocksize(BlockDriverState
*bdrv
)
370 sg_io_hdr_t io_header
;
373 memset(cmd
, 0, sizeof(cmd
));
374 memset(buf
, 0, sizeof(buf
));
375 cmd
[0] = READ_CAPACITY
;
377 memset(&io_header
, 0, sizeof(io_header
));
378 io_header
.interface_id
= 'S';
379 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
380 io_header
.dxfer_len
= sizeof(buf
);
381 io_header
.dxferp
= buf
;
382 io_header
.cmdp
= cmd
;
383 io_header
.cmd_len
= sizeof(cmd
);
384 io_header
.mx_sb_len
= sizeof(sensebuf
);
385 io_header
.sbp
= sensebuf
;
386 io_header
.timeout
= 6000; /* XXX */
388 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
392 return (buf
[4] << 24) | (buf
[5] << 16) | (buf
[6] << 8) | buf
[7];
395 static int get_stream_blocksize(BlockDriverState
*bdrv
)
400 sg_io_hdr_t io_header
;
403 memset(cmd
, 0, sizeof(cmd
));
404 memset(buf
, 0, sizeof(buf
));
406 cmd
[4] = sizeof(buf
);
408 memset(&io_header
, 0, sizeof(io_header
));
409 io_header
.interface_id
= 'S';
410 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
411 io_header
.dxfer_len
= sizeof(buf
);
412 io_header
.dxferp
= buf
;
413 io_header
.cmdp
= cmd
;
414 io_header
.cmd_len
= sizeof(cmd
);
415 io_header
.mx_sb_len
= sizeof(sensebuf
);
416 io_header
.sbp
= sensebuf
;
417 io_header
.timeout
= 6000; /* XXX */
419 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
423 return (buf
[9] << 16) | (buf
[10] << 8) | buf
[11];
426 static void scsi_generic_reset(DeviceState
*dev
)
428 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
.qdev
, dev
);
430 scsi_device_purge_requests(&s
->qdev
);
433 static void scsi_destroy(SCSIDevice
*d
)
435 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
437 scsi_device_purge_requests(&s
->qdev
);
438 blockdev_mark_auto_del(s
->qdev
.conf
.bs
);
441 static int scsi_generic_initfn(SCSIDevice
*dev
)
443 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, dev
);
445 struct sg_scsi_id scsiid
;
447 if (!s
->qdev
.conf
.bs
) {
448 error_report("scsi-generic: drive property not set");
451 s
->bs
= s
->qdev
.conf
.bs
;
453 /* check we are really using a /dev/sg* file */
454 if (!bdrv_is_sg(s
->bs
)) {
455 error_report("scsi-generic: not /dev/sg*");
459 if (bdrv_get_on_error(s
->bs
, 0) != BLOCK_ERR_STOP_ENOSPC
) {
460 error_report("Device doesn't support drive option werror");
463 if (bdrv_get_on_error(s
->bs
, 1) != BLOCK_ERR_REPORT
) {
464 error_report("Device doesn't support drive option rerror");
468 /* check we are using a driver managing SG_IO (version 3 and after */
469 if (bdrv_ioctl(s
->bs
, SG_GET_VERSION_NUM
, &sg_version
) < 0 ||
470 sg_version
< 30000) {
471 error_report("scsi-generic: scsi generic interface too old");
475 /* get LUN of the /dev/sg? */
476 if (bdrv_ioctl(s
->bs
, SG_GET_SCSI_ID
, &scsiid
)) {
477 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
481 /* define device state */
483 DPRINTF("LUN %d\n", s
->lun
);
484 s
->qdev
.type
= scsiid
.scsi_type
;
485 DPRINTF("device type %d\n", s
->qdev
.type
);
486 if (s
->qdev
.type
== TYPE_TAPE
) {
487 s
->qdev
.blocksize
= get_stream_blocksize(s
->bs
);
488 if (s
->qdev
.blocksize
== -1)
489 s
->qdev
.blocksize
= 0;
491 s
->qdev
.blocksize
= get_blocksize(s
->bs
);
492 /* removable media returns 0 if not present */
493 if (s
->qdev
.blocksize
<= 0) {
494 if (s
->qdev
.type
== TYPE_ROM
|| s
->qdev
.type
== TYPE_WORM
)
495 s
->qdev
.blocksize
= 2048;
497 s
->qdev
.blocksize
= 512;
500 DPRINTF("block size %d\n", s
->qdev
.blocksize
);
501 s
->driver_status
= 0;
502 memset(s
->sensebuf
, 0, sizeof(s
->sensebuf
));
503 bdrv_set_removable(s
->bs
, 0);
507 static SCSIDeviceInfo scsi_generic_info
= {
508 .qdev
.name
= "scsi-generic",
509 .qdev
.desc
= "pass through generic scsi device (/dev/sg*)",
510 .qdev
.size
= sizeof(SCSIGenericState
),
511 .qdev
.reset
= scsi_generic_reset
,
512 .init
= scsi_generic_initfn
,
513 .destroy
= scsi_destroy
,
514 .alloc_req
= scsi_new_request
,
515 .free_req
= scsi_free_request
,
516 .send_command
= scsi_send_command
,
517 .read_data
= scsi_read_data
,
518 .write_data
= scsi_write_data
,
519 .cancel_io
= scsi_cancel_io
,
520 .get_buf
= scsi_get_buf
,
521 .qdev
.props
= (Property
[]) {
522 DEFINE_BLOCK_PROPERTIES(SCSIGenericState
, qdev
.conf
),
523 DEFINE_PROP_END_OF_LIST(),
527 static void scsi_generic_register_devices(void)
529 scsi_qdev_register(&scsi_generic_info
);
531 device_init(scsi_generic_register_devices
)
533 #endif /* __linux__ */