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
45 #define SG_ERR_DID_OK 0x00
46 #define SG_ERR_DID_NO_CONNECT 0x01
47 #define SG_ERR_DID_BUS_BUSY 0x02
48 #define SG_ERR_DID_TIME_OUT 0x03
51 #define MAX_UINT ((unsigned int)-1)
54 typedef struct SCSIGenericReq
{
59 sg_io_hdr_t io_header
;
62 static void scsi_free_request(SCSIRequest
*req
)
64 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
69 /* Helper function for command completion. */
70 static void scsi_command_complete(void *opaque
, int ret
)
73 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
76 if (r
->io_header
.driver_status
& SG_ERR_DRIVER_SENSE
) {
77 r
->req
.sense_len
= r
->io_header
.sb_len_wr
;
83 status
= TASK_SET_FULL
;
86 status
= CHECK_CONDITION
;
87 scsi_req_build_sense(&r
->req
, SENSE_CODE(TARGET_FAILURE
));
90 status
= CHECK_CONDITION
;
91 scsi_req_build_sense(&r
->req
, SENSE_CODE(IO_ERROR
));
95 if (r
->io_header
.host_status
== SG_ERR_DID_NO_CONNECT
||
96 r
->io_header
.host_status
== SG_ERR_DID_BUS_BUSY
||
97 r
->io_header
.host_status
== SG_ERR_DID_TIME_OUT
||
98 (r
->io_header
.driver_status
& SG_ERR_DRIVER_TIMEOUT
)) {
100 BADF("Driver Timeout\n");
101 } else if (r
->io_header
.host_status
) {
102 status
= CHECK_CONDITION
;
103 scsi_req_build_sense(&r
->req
, SENSE_CODE(I_T_NEXUS_LOSS
));
104 } else if (r
->io_header
.status
) {
105 status
= r
->io_header
.status
;
106 } else if (r
->io_header
.driver_status
& SG_ERR_DRIVER_SENSE
) {
107 status
= CHECK_CONDITION
;
112 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
113 r
, r
->req
.tag
, status
);
115 scsi_req_complete(&r
->req
, status
);
116 if (!r
->req
.io_canceled
) {
117 scsi_req_unref(&r
->req
);
121 /* Cancel a pending data transfer. */
122 static void scsi_cancel_io(SCSIRequest
*req
)
124 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
126 DPRINTF("Cancel tag=0x%x\n", req
->tag
);
128 bdrv_aio_cancel(r
->req
.aiocb
);
130 /* This reference was left in by scsi_*_data. We take ownership of
131 * it independent of whether bdrv_aio_cancel completes the request
133 scsi_req_unref(&r
->req
);
138 static int execute_command(BlockDriverState
*bdrv
,
139 SCSIGenericReq
*r
, int direction
,
140 BlockDriverCompletionFunc
*complete
)
142 r
->io_header
.interface_id
= 'S';
143 r
->io_header
.dxfer_direction
= direction
;
144 r
->io_header
.dxferp
= r
->buf
;
145 r
->io_header
.dxfer_len
= r
->buflen
;
146 r
->io_header
.cmdp
= r
->req
.cmd
.buf
;
147 r
->io_header
.cmd_len
= r
->req
.cmd
.len
;
148 r
->io_header
.mx_sb_len
= sizeof(r
->req
.sense
);
149 r
->io_header
.sbp
= r
->req
.sense
;
150 r
->io_header
.timeout
= MAX_UINT
;
151 r
->io_header
.usr_ptr
= r
;
152 r
->io_header
.flags
|= SG_FLAG_DIRECT_IO
;
154 r
->req
.aiocb
= bdrv_aio_ioctl(bdrv
, SG_IO
, &r
->io_header
, complete
, r
);
155 if (r
->req
.aiocb
== NULL
) {
156 BADF("execute_command: read failed !\n");
163 static void scsi_read_complete(void * opaque
, int ret
)
165 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
166 SCSIDevice
*s
= r
->req
.dev
;
171 DPRINTF("IO error ret %d\n", ret
);
172 scsi_command_complete(r
, ret
);
175 len
= r
->io_header
.dxfer_len
- r
->io_header
.resid
;
176 DPRINTF("Data ready tag=0x%x len=%d\n", r
->req
.tag
, len
);
180 scsi_command_complete(r
, 0);
182 /* Snoop READ CAPACITY output to set the blocksize. */
183 if (r
->req
.cmd
.buf
[0] == READ_CAPACITY_10
) {
184 s
->blocksize
= ldl_be_p(&r
->buf
[4]);
185 s
->max_lba
= ldl_be_p(&r
->buf
[0]);
186 } else if (r
->req
.cmd
.buf
[0] == SERVICE_ACTION_IN_16
&&
187 (r
->req
.cmd
.buf
[1] & 31) == SAI_READ_CAPACITY_16
) {
188 s
->blocksize
= ldl_be_p(&r
->buf
[8]);
189 s
->max_lba
= ldq_be_p(&r
->buf
[0]);
191 bdrv_set_buffer_alignment(s
->conf
.bs
, s
->blocksize
);
193 scsi_req_data(&r
->req
, len
);
194 if (!r
->req
.io_canceled
) {
195 scsi_req_unref(&r
->req
);
200 /* Read more data from scsi device into buffer. */
201 static void scsi_read_data(SCSIRequest
*req
)
203 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
204 SCSIDevice
*s
= r
->req
.dev
;
207 DPRINTF("scsi_read_data 0x%x\n", req
->tag
);
209 /* The request is used as the AIO opaque value, so add a ref. */
210 scsi_req_ref(&r
->req
);
212 scsi_command_complete(r
, 0);
216 ret
= execute_command(s
->conf
.bs
, r
, SG_DXFER_FROM_DEV
, scsi_read_complete
);
218 scsi_command_complete(r
, ret
);
222 static void scsi_write_complete(void * opaque
, int ret
)
224 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
225 SCSIDevice
*s
= r
->req
.dev
;
227 DPRINTF("scsi_write_complete() ret = %d\n", ret
);
230 DPRINTF("IO error\n");
231 scsi_command_complete(r
, ret
);
235 if (r
->req
.cmd
.buf
[0] == MODE_SELECT
&& r
->req
.cmd
.buf
[4] == 12 &&
236 s
->type
== TYPE_TAPE
) {
237 s
->blocksize
= (r
->buf
[9] << 16) | (r
->buf
[10] << 8) | r
->buf
[11];
238 DPRINTF("block size %d\n", s
->blocksize
);
241 scsi_command_complete(r
, ret
);
244 /* Write data to a scsi device. Returns nonzero on failure.
245 The transfer may complete asynchronously. */
246 static void scsi_write_data(SCSIRequest
*req
)
248 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
249 SCSIDevice
*s
= r
->req
.dev
;
252 DPRINTF("scsi_write_data 0x%x\n", req
->tag
);
255 scsi_req_data(&r
->req
, r
->len
);
259 /* The request is used as the AIO opaque value, so add a ref. */
260 scsi_req_ref(&r
->req
);
261 ret
= execute_command(s
->conf
.bs
, r
, SG_DXFER_TO_DEV
, scsi_write_complete
);
263 scsi_command_complete(r
, ret
);
267 /* Return a pointer to the data buffer. */
268 static uint8_t *scsi_get_buf(SCSIRequest
*req
)
270 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
275 /* Execute a scsi command. Returns the length of the data expected by the
276 command. This will be Positive for data transfers from the device
277 (eg. disk reads), negative for transfers to the device (eg. disk writes),
278 and zero if the command does not transfer any data. */
280 static int32_t scsi_send_command(SCSIRequest
*req
, uint8_t *cmd
)
282 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
283 SCSIDevice
*s
= r
->req
.dev
;
286 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun
, tag
,
287 r
->req
.cmd
.xfer
, cmd
[0]);
292 for (i
= 1; i
< r
->req
.cmd
.len
; i
++) {
293 printf(" 0x%02x", cmd
[i
]);
299 if (r
->req
.cmd
.xfer
== 0) {
304 /* The request is used as the AIO opaque value, so add a ref. */
305 scsi_req_ref(&r
->req
);
306 ret
= execute_command(s
->conf
.bs
, r
, SG_DXFER_NONE
, scsi_command_complete
);
308 scsi_command_complete(r
, ret
);
314 if (r
->buflen
!= r
->req
.cmd
.xfer
) {
317 r
->buf
= g_malloc(r
->req
.cmd
.xfer
);
318 r
->buflen
= r
->req
.cmd
.xfer
;
321 memset(r
->buf
, 0, r
->buflen
);
322 r
->len
= r
->req
.cmd
.xfer
;
323 if (r
->req
.cmd
.mode
== SCSI_XFER_TO_DEV
) {
325 return -r
->req
.cmd
.xfer
;
327 return r
->req
.cmd
.xfer
;
331 static int get_stream_blocksize(BlockDriverState
*bdrv
)
336 sg_io_hdr_t io_header
;
339 memset(cmd
, 0, sizeof(cmd
));
340 memset(buf
, 0, sizeof(buf
));
342 cmd
[4] = sizeof(buf
);
344 memset(&io_header
, 0, sizeof(io_header
));
345 io_header
.interface_id
= 'S';
346 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
347 io_header
.dxfer_len
= sizeof(buf
);
348 io_header
.dxferp
= buf
;
349 io_header
.cmdp
= cmd
;
350 io_header
.cmd_len
= sizeof(cmd
);
351 io_header
.mx_sb_len
= sizeof(sensebuf
);
352 io_header
.sbp
= sensebuf
;
353 io_header
.timeout
= 6000; /* XXX */
355 ret
= bdrv_ioctl(bdrv
, SG_IO
, &io_header
);
356 if (ret
< 0 || io_header
.driver_status
|| io_header
.host_status
) {
359 return (buf
[9] << 16) | (buf
[10] << 8) | buf
[11];
362 static void scsi_generic_reset(DeviceState
*dev
)
364 SCSIDevice
*s
= DO_UPCAST(SCSIDevice
, qdev
, dev
);
366 scsi_device_purge_requests(s
, SENSE_CODE(RESET
));
369 static void scsi_destroy(SCSIDevice
*s
)
371 scsi_device_purge_requests(s
, SENSE_CODE(NO_SENSE
));
372 blockdev_mark_auto_del(s
->conf
.bs
);
375 static int scsi_generic_initfn(SCSIDevice
*s
)
378 struct sg_scsi_id scsiid
;
381 error_report("scsi-generic: drive property not set");
385 /* check we are really using a /dev/sg* file */
386 if (!bdrv_is_sg(s
->conf
.bs
)) {
387 error_report("scsi-generic: not /dev/sg*");
391 if (bdrv_get_on_error(s
->conf
.bs
, 0) != BLOCK_ERR_STOP_ENOSPC
) {
392 error_report("Device doesn't support drive option werror");
395 if (bdrv_get_on_error(s
->conf
.bs
, 1) != BLOCK_ERR_REPORT
) {
396 error_report("Device doesn't support drive option rerror");
400 /* check we are using a driver managing SG_IO (version 3 and after */
401 if (bdrv_ioctl(s
->conf
.bs
, SG_GET_VERSION_NUM
, &sg_version
) < 0 ||
402 sg_version
< 30000) {
403 error_report("scsi-generic: scsi generic interface too old");
407 /* get LUN of the /dev/sg? */
408 if (bdrv_ioctl(s
->conf
.bs
, SG_GET_SCSI_ID
, &scsiid
)) {
409 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
413 /* define device state */
414 s
->type
= scsiid
.scsi_type
;
415 DPRINTF("device type %d\n", s
->type
);
418 s
->blocksize
= get_stream_blocksize(s
->conf
.bs
);
419 if (s
->blocksize
== -1) {
424 /* Make a guess for block devices, we'll fix it when the guest sends.
425 * READ CAPACITY. If they don't, they likely would assume these sizes
426 * anyway. (TODO: they could also send MODE SENSE).
437 DPRINTF("block size %d\n", s
->blocksize
);
441 const SCSIReqOps scsi_generic_req_ops
= {
442 .size
= sizeof(SCSIGenericReq
),
443 .free_req
= scsi_free_request
,
444 .send_command
= scsi_send_command
,
445 .read_data
= scsi_read_data
,
446 .write_data
= scsi_write_data
,
447 .cancel_io
= scsi_cancel_io
,
448 .get_buf
= scsi_get_buf
,
451 static SCSIRequest
*scsi_new_request(SCSIDevice
*d
, uint32_t tag
, uint32_t lun
,
452 uint8_t *buf
, void *hba_private
)
456 req
= scsi_req_alloc(&scsi_generic_req_ops
, d
, tag
, lun
, hba_private
);
460 static SCSIDeviceInfo scsi_generic_info
= {
461 .qdev
.name
= "scsi-generic",
462 .qdev
.desc
= "pass through generic scsi device (/dev/sg*)",
463 .qdev
.size
= sizeof(SCSIDevice
),
464 .qdev
.reset
= scsi_generic_reset
,
465 .init
= scsi_generic_initfn
,
466 .destroy
= scsi_destroy
,
467 .alloc_req
= scsi_new_request
,
468 .qdev
.props
= (Property
[]) {
469 DEFINE_BLOCK_PROPERTIES(SCSIDevice
, conf
),
470 DEFINE_PROP_END_OF_LIST(),
474 static void scsi_generic_register_devices(void)
476 scsi_qdev_register(&scsi_generic_info
);
478 device_init(scsi_generic_register_devices
)
480 #endif /* __linux__ */