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 SCSIGenericReq
{
54 sg_io_hdr_t io_header
;
57 static void scsi_free_request(SCSIRequest
*req
)
59 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
64 /* Helper function for command completion. */
65 static void scsi_command_complete(void *opaque
, int ret
)
68 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
71 if (r
->io_header
.driver_status
& SG_ERR_DRIVER_SENSE
)
72 r
->req
.sense_len
= r
->io_header
.sb_len_wr
;
77 status
= TASK_SET_FULL
;
80 status
= CHECK_CONDITION
;
81 scsi_req_build_sense(&r
->req
, SENSE_CODE(TARGET_FAILURE
));
84 status
= CHECK_CONDITION
;
85 scsi_req_build_sense(&r
->req
, SENSE_CODE(IO_ERROR
));
89 if (r
->io_header
.driver_status
& SG_ERR_DRIVER_TIMEOUT
) {
91 BADF("Driver Timeout\n");
92 } else if (r
->io_header
.status
) {
93 status
= r
->io_header
.status
;
94 } else if (r
->io_header
.driver_status
& SG_ERR_DRIVER_SENSE
) {
95 status
= CHECK_CONDITION
;
100 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
101 r
, r
->req
.tag
, status
);
103 scsi_req_complete(&r
->req
, status
);
106 /* Cancel a pending data transfer. */
107 static void scsi_cancel_io(SCSIRequest
*req
)
109 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
111 DPRINTF("Cancel tag=0x%x\n", req
->tag
);
113 bdrv_aio_cancel(r
->req
.aiocb
);
118 static int execute_command(BlockDriverState
*bdrv
,
119 SCSIGenericReq
*r
, int direction
,
120 BlockDriverCompletionFunc
*complete
)
122 r
->io_header
.interface_id
= 'S';
123 r
->io_header
.dxfer_direction
= direction
;
124 r
->io_header
.dxferp
= r
->buf
;
125 r
->io_header
.dxfer_len
= r
->buflen
;
126 r
->io_header
.cmdp
= r
->req
.cmd
.buf
;
127 r
->io_header
.cmd_len
= r
->req
.cmd
.len
;
128 r
->io_header
.mx_sb_len
= sizeof(r
->req
.sense
);
129 r
->io_header
.sbp
= r
->req
.sense
;
130 r
->io_header
.timeout
= MAX_UINT
;
131 r
->io_header
.usr_ptr
= r
;
132 r
->io_header
.flags
|= SG_FLAG_DIRECT_IO
;
134 r
->req
.aiocb
= bdrv_aio_ioctl(bdrv
, SG_IO
, &r
->io_header
, complete
, r
);
135 if (r
->req
.aiocb
== NULL
) {
136 BADF("execute_command: read failed !\n");
143 static void scsi_read_complete(void * opaque
, int ret
)
145 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
150 DPRINTF("IO error ret %d\n", ret
);
151 scsi_command_complete(r
, ret
);
154 len
= r
->io_header
.dxfer_len
- r
->io_header
.resid
;
155 DPRINTF("Data ready tag=0x%x len=%d\n", r
->req
.tag
, len
);
159 scsi_command_complete(r
, 0);
161 scsi_req_data(&r
->req
, len
);
165 /* Read more data from scsi device into buffer. */
166 static void scsi_read_data(SCSIRequest
*req
)
168 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
169 SCSIDevice
*s
= r
->req
.dev
;
172 DPRINTF("scsi_read_data 0x%x\n", req
->tag
);
174 scsi_command_complete(r
, 0);
178 ret
= execute_command(s
->conf
.bs
, r
, SG_DXFER_FROM_DEV
, scsi_read_complete
);
180 scsi_command_complete(r
, ret
);
184 static void scsi_write_complete(void * opaque
, int ret
)
186 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
187 SCSIDevice
*s
= r
->req
.dev
;
189 DPRINTF("scsi_write_complete() ret = %d\n", ret
);
192 DPRINTF("IO error\n");
193 scsi_command_complete(r
, ret
);
197 if (r
->req
.cmd
.buf
[0] == MODE_SELECT
&& r
->req
.cmd
.buf
[4] == 12 &&
198 s
->type
== TYPE_TAPE
) {
199 s
->blocksize
= (r
->buf
[9] << 16) | (r
->buf
[10] << 8) | r
->buf
[11];
200 DPRINTF("block size %d\n", s
->blocksize
);
203 scsi_command_complete(r
, ret
);
206 /* Write data to a scsi device. Returns nonzero on failure.
207 The transfer may complete asynchronously. */
208 static void scsi_write_data(SCSIRequest
*req
)
210 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
211 SCSIDevice
*s
= r
->req
.dev
;
214 DPRINTF("scsi_write_data 0x%x\n", req
->tag
);
217 scsi_req_data(&r
->req
, r
->len
);
221 ret
= execute_command(s
->conf
.bs
, r
, SG_DXFER_TO_DEV
, scsi_write_complete
);
223 scsi_command_complete(r
, ret
);
227 /* Return a pointer to the data buffer. */
228 static uint8_t *scsi_get_buf(SCSIRequest
*req
)
230 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
235 static void scsi_req_fixup(SCSIRequest
*req
)
237 switch(req
->cmd
.buf
[0]) {
240 if (req
->dev
->type
== TYPE_TAPE
) {
241 /* force IMMED, otherwise qemu waits end of command */
242 req
->cmd
.buf
[1] = 0x01;
248 /* Execute a scsi command. Returns the length of the data expected by the
249 command. This will be Positive for data transfers from the device
250 (eg. disk reads), negative for transfers to the device (eg. disk writes),
251 and zero if the command does not transfer any data. */
253 static int32_t scsi_send_command(SCSIRequest
*req
, uint8_t *cmd
)
255 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
256 SCSIDevice
*s
= r
->req
.dev
;
259 scsi_req_fixup(&r
->req
);
261 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun
, tag
,
262 r
->req
.cmd
.xfer
, cmd
[0]);
267 for (i
= 1; i
< r
->req
.cmd
.len
; i
++) {
268 printf(" 0x%02x", cmd
[i
]);
274 if (r
->req
.cmd
.xfer
== 0) {
279 ret
= execute_command(s
->conf
.bs
, r
, SG_DXFER_NONE
, scsi_command_complete
);
281 scsi_command_complete(r
, ret
);
287 if (r
->buflen
!= r
->req
.cmd
.xfer
) {
290 r
->buf
= g_malloc(r
->req
.cmd
.xfer
);
291 r
->buflen
= r
->req
.cmd
.xfer
;
294 memset(r
->buf
, 0, r
->buflen
);
295 r
->len
= r
->req
.cmd
.xfer
;
296 if (r
->req
.cmd
.mode
== SCSI_XFER_TO_DEV
) {
298 return -r
->req
.cmd
.xfer
;
300 return r
->req
.cmd
.xfer
;
304 static int get_blocksize(BlockDriverState
*bdrv
)
309 sg_io_hdr_t io_header
;
312 memset(cmd
, 0, sizeof(cmd
));
313 memset(buf
, 0, sizeof(buf
));
314 cmd
[0] = READ_CAPACITY_10
;
316 memset(&io_header
, 0, sizeof(io_header
));
317 io_header
.interface_id
= 'S';
318 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
319 io_header
.dxfer_len
= sizeof(buf
);
320 io_header
.dxferp
= buf
;
321 io_header
.cmdp
= cmd
;
322 io_header
.cmd_len
= sizeof(cmd
);
323 io_header
.mx_sb_len
= sizeof(sensebuf
);
324 io_header
.sbp
= sensebuf
;
325 io_header
.timeout
= 6000; /* XXX */
327 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
331 return (buf
[4] << 24) | (buf
[5] << 16) | (buf
[6] << 8) | buf
[7];
334 static int get_stream_blocksize(BlockDriverState
*bdrv
)
339 sg_io_hdr_t io_header
;
342 memset(cmd
, 0, sizeof(cmd
));
343 memset(buf
, 0, sizeof(buf
));
345 cmd
[4] = sizeof(buf
);
347 memset(&io_header
, 0, sizeof(io_header
));
348 io_header
.interface_id
= 'S';
349 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
350 io_header
.dxfer_len
= sizeof(buf
);
351 io_header
.dxferp
= buf
;
352 io_header
.cmdp
= cmd
;
353 io_header
.cmd_len
= sizeof(cmd
);
354 io_header
.mx_sb_len
= sizeof(sensebuf
);
355 io_header
.sbp
= sensebuf
;
356 io_header
.timeout
= 6000; /* XXX */
358 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
362 return (buf
[9] << 16) | (buf
[10] << 8) | buf
[11];
365 static void scsi_generic_reset(DeviceState
*dev
)
367 SCSIDevice
*s
= DO_UPCAST(SCSIDevice
, qdev
, dev
);
369 scsi_device_purge_requests(s
, SENSE_CODE(RESET
));
372 static void scsi_destroy(SCSIDevice
*s
)
374 scsi_device_purge_requests(s
, SENSE_CODE(NO_SENSE
));
375 blockdev_mark_auto_del(s
->conf
.bs
);
378 static int scsi_generic_initfn(SCSIDevice
*s
)
381 struct sg_scsi_id scsiid
;
384 error_report("scsi-generic: drive property not set");
388 /* check we are really using a /dev/sg* file */
389 if (!bdrv_is_sg(s
->conf
.bs
)) {
390 error_report("scsi-generic: not /dev/sg*");
394 if (bdrv_get_on_error(s
->conf
.bs
, 0) != BLOCK_ERR_STOP_ENOSPC
) {
395 error_report("Device doesn't support drive option werror");
398 if (bdrv_get_on_error(s
->conf
.bs
, 1) != BLOCK_ERR_REPORT
) {
399 error_report("Device doesn't support drive option rerror");
403 /* check we are using a driver managing SG_IO (version 3 and after */
404 if (bdrv_ioctl(s
->conf
.bs
, SG_GET_VERSION_NUM
, &sg_version
) < 0 ||
405 sg_version
< 30000) {
406 error_report("scsi-generic: scsi generic interface too old");
410 /* get LUN of the /dev/sg? */
411 if (bdrv_ioctl(s
->conf
.bs
, SG_GET_SCSI_ID
, &scsiid
)) {
412 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
416 /* define device state */
417 s
->type
= scsiid
.scsi_type
;
418 DPRINTF("device type %d\n", s
->type
);
419 if (s
->type
== TYPE_TAPE
) {
420 s
->blocksize
= get_stream_blocksize(s
->conf
.bs
);
421 if (s
->blocksize
== -1) {
425 s
->blocksize
= get_blocksize(s
->conf
.bs
);
426 /* removable media returns 0 if not present */
427 if (s
->blocksize
<= 0) {
428 if (s
->type
== TYPE_ROM
|| s
->type
== TYPE_WORM
) {
436 DPRINTF("block size %d\n", s
->blocksize
);
440 static SCSIReqOps scsi_generic_req_ops
= {
441 .size
= sizeof(SCSIGenericReq
),
442 .free_req
= scsi_free_request
,
443 .send_command
= scsi_send_command
,
444 .read_data
= scsi_read_data
,
445 .write_data
= scsi_write_data
,
446 .cancel_io
= scsi_cancel_io
,
447 .get_buf
= scsi_get_buf
,
450 static SCSIRequest
*scsi_new_request(SCSIDevice
*d
, uint32_t tag
, uint32_t lun
,
455 req
= scsi_req_alloc(&scsi_generic_req_ops
, d
, tag
, lun
, hba_private
);
459 static SCSIDeviceInfo scsi_generic_info
= {
460 .qdev
.name
= "scsi-generic",
461 .qdev
.desc
= "pass through generic scsi device (/dev/sg*)",
462 .qdev
.size
= sizeof(SCSIDevice
),
463 .qdev
.reset
= scsi_generic_reset
,
464 .init
= scsi_generic_initfn
,
465 .destroy
= scsi_destroy
,
466 .alloc_req
= scsi_new_request
,
467 .qdev
.props
= (Property
[]) {
468 DEFINE_BLOCK_PROPERTIES(SCSIDevice
, conf
),
469 DEFINE_PROP_END_OF_LIST(),
473 static void scsi_generic_register_devices(void)
475 scsi_qdev_register(&scsi_generic_info
);
477 device_init(scsi_generic_register_devices
)
479 #endif /* __linux__ */