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 licensed 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
66 static void scsi_free_request(SCSIRequest
*req
)
68 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
73 /* Helper function for command completion. */
74 static void scsi_command_complete(void *opaque
, int ret
)
77 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
80 if (r
->io_header
.driver_status
& SG_ERR_DRIVER_SENSE
)
81 r
->req
.sense_len
= r
->io_header
.sb_len_wr
;
86 status
= TASK_SET_FULL
;
89 status
= CHECK_CONDITION
;
90 scsi_req_build_sense(&r
->req
, SENSE_CODE(INVALID_FIELD
));
93 status
= CHECK_CONDITION
;
94 scsi_req_build_sense(&r
->req
, SENSE_CODE(TARGET_FAILURE
));
97 status
= CHECK_CONDITION
;
98 scsi_req_build_sense(&r
->req
, SENSE_CODE(IO_ERROR
));
102 if (r
->io_header
.driver_status
& SG_ERR_DRIVER_TIMEOUT
) {
104 BADF("Driver Timeout\n");
105 } else if (r
->io_header
.status
) {
106 status
= r
->io_header
.status
;
107 } else if (r
->io_header
.driver_status
& SG_ERR_DRIVER_SENSE
) {
108 status
= CHECK_CONDITION
;
113 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
114 r
, r
->req
.tag
, status
);
116 scsi_req_complete(&r
->req
, status
);
119 /* Cancel a pending data transfer. */
120 static void scsi_cancel_io(SCSIRequest
*req
)
122 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
124 DPRINTF("Cancel tag=0x%x\n", req
->tag
);
126 bdrv_aio_cancel(r
->req
.aiocb
);
131 static int execute_command(BlockDriverState
*bdrv
,
132 SCSIGenericReq
*r
, int direction
,
133 BlockDriverCompletionFunc
*complete
)
135 r
->io_header
.interface_id
= 'S';
136 r
->io_header
.dxfer_direction
= direction
;
137 r
->io_header
.dxferp
= r
->buf
;
138 r
->io_header
.dxfer_len
= r
->buflen
;
139 r
->io_header
.cmdp
= r
->req
.cmd
.buf
;
140 r
->io_header
.cmd_len
= r
->req
.cmd
.len
;
141 r
->io_header
.mx_sb_len
= sizeof(r
->req
.sense
);
142 r
->io_header
.sbp
= r
->req
.sense
;
143 r
->io_header
.timeout
= MAX_UINT
;
144 r
->io_header
.usr_ptr
= r
;
145 r
->io_header
.flags
|= SG_FLAG_DIRECT_IO
;
147 r
->req
.aiocb
= bdrv_aio_ioctl(bdrv
, SG_IO
, &r
->io_header
, complete
, r
);
148 if (r
->req
.aiocb
== NULL
) {
149 BADF("execute_command: read failed !\n");
156 static void scsi_read_complete(void * opaque
, int ret
)
158 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
163 DPRINTF("IO error ret %d\n", ret
);
164 scsi_command_complete(r
, ret
);
167 len
= r
->io_header
.dxfer_len
- r
->io_header
.resid
;
168 DPRINTF("Data ready tag=0x%x len=%d\n", r
->req
.tag
, len
);
172 scsi_command_complete(r
, 0);
174 scsi_req_data(&r
->req
, len
);
178 /* Read more data from scsi device into buffer. */
179 static void scsi_read_data(SCSIRequest
*req
)
181 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
182 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
185 DPRINTF("scsi_read_data 0x%x\n", req
->tag
);
187 scsi_command_complete(r
, 0);
191 if (r
->req
.cmd
.buf
[0] == REQUEST_SENSE
) {
192 r
->io_header
.driver_status
= 0;
193 r
->io_header
.status
= 0;
194 r
->io_header
.dxfer_len
=
195 scsi_device_get_sense(&s
->qdev
, r
->buf
, r
->req
.cmd
.xfer
,
196 (r
->req
.cmd
.buf
[1] & 1) == 0);
198 DPRINTF("Data ready tag=0x%x len=%d\n", r
->req
.tag
, r
->io_header
.dxfer_len
);
199 DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
200 r
->buf
[0], r
->buf
[1], r
->buf
[2], r
->buf
[3],
201 r
->buf
[4], r
->buf
[5], r
->buf
[6], r
->buf
[7]);
202 scsi_req_data(&r
->req
, r
->io_header
.dxfer_len
);
203 /* The sense buffer is cleared when we return GOOD */
207 ret
= execute_command(s
->bs
, r
, SG_DXFER_FROM_DEV
, scsi_read_complete
);
209 scsi_command_complete(r
, ret
);
214 static void scsi_write_complete(void * opaque
, int ret
)
216 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
217 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, r
->req
.dev
);
219 DPRINTF("scsi_write_complete() ret = %d\n", ret
);
222 DPRINTF("IO error\n");
223 scsi_command_complete(r
, ret
);
227 if (r
->req
.cmd
.buf
[0] == MODE_SELECT
&& r
->req
.cmd
.buf
[4] == 12 &&
228 s
->qdev
.type
== TYPE_TAPE
) {
229 s
->qdev
.blocksize
= (r
->buf
[9] << 16) | (r
->buf
[10] << 8) | r
->buf
[11];
230 DPRINTF("block size %d\n", s
->qdev
.blocksize
);
233 scsi_command_complete(r
, ret
);
236 /* Write data to a scsi device. Returns nonzero on failure.
237 The transfer may complete asynchronously. */
238 static void scsi_write_data(SCSIRequest
*req
)
240 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, req
->dev
);
241 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
244 DPRINTF("scsi_write_data 0x%x\n", req
->tag
);
247 scsi_req_data(&r
->req
, r
->len
);
251 ret
= execute_command(s
->bs
, r
, SG_DXFER_TO_DEV
, scsi_write_complete
);
253 scsi_command_complete(r
, ret
);
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
);
295 if (cmd
[0] != REQUEST_SENSE
&& req
->lun
!= s
->lun
) {
296 DPRINTF("Unimplemented LUN %d\n", req
->lun
);
297 scsi_req_build_sense(&r
->req
, SENSE_CODE(LUN_NOT_SUPPORTED
));
298 scsi_req_complete(&r
->req
, CHECK_CONDITION
);
302 if (-1 == scsi_req_parse(&r
->req
, cmd
)) {
303 BADF("Unsupported command length, command %x\n", cmd
[0]);
304 scsi_command_complete(r
, -EINVAL
);
307 scsi_req_fixup(&r
->req
);
309 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun
, tag
,
310 r
->req
.cmd
.xfer
, cmd
[0]);
315 for (i
= 1; i
< r
->req
.cmd
.len
; i
++) {
316 printf(" 0x%02x", cmd
[i
]);
322 if (r
->req
.cmd
.xfer
== 0) {
327 ret
= execute_command(s
->bs
, r
, SG_DXFER_NONE
, scsi_command_complete
);
329 scsi_command_complete(r
, ret
);
335 if (r
->buflen
!= r
->req
.cmd
.xfer
) {
338 r
->buf
= qemu_malloc(r
->req
.cmd
.xfer
);
339 r
->buflen
= r
->req
.cmd
.xfer
;
342 memset(r
->buf
, 0, r
->buflen
);
343 r
->len
= r
->req
.cmd
.xfer
;
344 if (r
->req
.cmd
.mode
== SCSI_XFER_TO_DEV
) {
346 return -r
->req
.cmd
.xfer
;
348 return r
->req
.cmd
.xfer
;
352 static int get_blocksize(BlockDriverState
*bdrv
)
357 sg_io_hdr_t io_header
;
360 memset(cmd
, 0, sizeof(cmd
));
361 memset(buf
, 0, sizeof(buf
));
362 cmd
[0] = READ_CAPACITY_10
;
364 memset(&io_header
, 0, sizeof(io_header
));
365 io_header
.interface_id
= 'S';
366 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
367 io_header
.dxfer_len
= sizeof(buf
);
368 io_header
.dxferp
= buf
;
369 io_header
.cmdp
= cmd
;
370 io_header
.cmd_len
= sizeof(cmd
);
371 io_header
.mx_sb_len
= sizeof(sensebuf
);
372 io_header
.sbp
= sensebuf
;
373 io_header
.timeout
= 6000; /* XXX */
375 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
379 return (buf
[4] << 24) | (buf
[5] << 16) | (buf
[6] << 8) | buf
[7];
382 static int get_stream_blocksize(BlockDriverState
*bdrv
)
387 sg_io_hdr_t io_header
;
390 memset(cmd
, 0, sizeof(cmd
));
391 memset(buf
, 0, sizeof(buf
));
393 cmd
[4] = sizeof(buf
);
395 memset(&io_header
, 0, sizeof(io_header
));
396 io_header
.interface_id
= 'S';
397 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
398 io_header
.dxfer_len
= sizeof(buf
);
399 io_header
.dxferp
= buf
;
400 io_header
.cmdp
= cmd
;
401 io_header
.cmd_len
= sizeof(cmd
);
402 io_header
.mx_sb_len
= sizeof(sensebuf
);
403 io_header
.sbp
= sensebuf
;
404 io_header
.timeout
= 6000; /* XXX */
406 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
410 return (buf
[9] << 16) | (buf
[10] << 8) | buf
[11];
413 static void scsi_generic_reset(DeviceState
*dev
)
415 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
.qdev
, dev
);
417 scsi_device_purge_requests(&s
->qdev
);
420 static void scsi_destroy(SCSIDevice
*d
)
422 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, d
);
424 scsi_device_purge_requests(&s
->qdev
);
425 blockdev_mark_auto_del(s
->qdev
.conf
.bs
);
428 static int scsi_generic_initfn(SCSIDevice
*dev
)
430 SCSIGenericState
*s
= DO_UPCAST(SCSIGenericState
, qdev
, dev
);
432 struct sg_scsi_id scsiid
;
434 if (!s
->qdev
.conf
.bs
) {
435 error_report("scsi-generic: drive property not set");
438 s
->bs
= s
->qdev
.conf
.bs
;
440 /* check we are really using a /dev/sg* file */
441 if (!bdrv_is_sg(s
->bs
)) {
442 error_report("scsi-generic: not /dev/sg*");
446 if (bdrv_get_on_error(s
->bs
, 0) != BLOCK_ERR_STOP_ENOSPC
) {
447 error_report("Device doesn't support drive option werror");
450 if (bdrv_get_on_error(s
->bs
, 1) != BLOCK_ERR_REPORT
) {
451 error_report("Device doesn't support drive option rerror");
455 /* check we are using a driver managing SG_IO (version 3 and after */
456 if (bdrv_ioctl(s
->bs
, SG_GET_VERSION_NUM
, &sg_version
) < 0 ||
457 sg_version
< 30000) {
458 error_report("scsi-generic: scsi generic interface too old");
462 /* get LUN of the /dev/sg? */
463 if (bdrv_ioctl(s
->bs
, SG_GET_SCSI_ID
, &scsiid
)) {
464 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
468 /* define device state */
470 DPRINTF("LUN %d\n", s
->lun
);
471 s
->qdev
.type
= scsiid
.scsi_type
;
472 DPRINTF("device type %d\n", s
->qdev
.type
);
473 if (s
->qdev
.type
== TYPE_TAPE
) {
474 s
->qdev
.blocksize
= get_stream_blocksize(s
->bs
);
475 if (s
->qdev
.blocksize
== -1)
476 s
->qdev
.blocksize
= 0;
478 s
->qdev
.blocksize
= get_blocksize(s
->bs
);
479 /* removable media returns 0 if not present */
480 if (s
->qdev
.blocksize
<= 0) {
481 if (s
->qdev
.type
== TYPE_ROM
|| s
->qdev
.type
== TYPE_WORM
)
482 s
->qdev
.blocksize
= 2048;
484 s
->qdev
.blocksize
= 512;
487 DPRINTF("block size %d\n", s
->qdev
.blocksize
);
488 bdrv_set_removable(s
->bs
, 0);
492 static SCSIReqOps scsi_generic_req_ops
= {
493 .size
= sizeof(SCSIGenericReq
),
496 static SCSIRequest
*scsi_new_request(SCSIDevice
*d
, uint32_t tag
, uint32_t lun
,
501 req
= scsi_req_alloc(&scsi_generic_req_ops
, d
, tag
, lun
, hba_private
);
505 static SCSIDeviceInfo scsi_generic_info
= {
506 .qdev
.name
= "scsi-generic",
507 .qdev
.desc
= "pass through generic scsi device (/dev/sg*)",
508 .qdev
.size
= sizeof(SCSIGenericState
),
509 .qdev
.reset
= scsi_generic_reset
,
510 .init
= scsi_generic_initfn
,
511 .destroy
= scsi_destroy
,
512 .alloc_req
= scsi_new_request
,
513 .free_req
= scsi_free_request
,
514 .send_command
= scsi_send_command
,
515 .read_data
= scsi_read_data
,
516 .write_data
= scsi_write_data
,
517 .cancel_io
= scsi_cancel_io
,
518 .get_buf
= scsi_get_buf
,
519 .qdev
.props
= (Property
[]) {
520 DEFINE_BLOCK_PROPERTIES(SCSIGenericState
, qdev
.conf
),
521 DEFINE_PROP_END_OF_LIST(),
525 static void scsi_generic_register_devices(void)
527 scsi_qdev_register(&scsi_generic_info
);
529 device_init(scsi_generic_register_devices
)
531 #endif /* __linux__ */