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-report.h"
16 #include "hw/scsi/scsi.h"
17 #include "sysemu/block-backend.h"
18 #include "sysemu/blockdev.h"
25 #define DPRINTF(fmt, ...) \
26 do { printf("scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
28 #define DPRINTF(fmt, ...) do {} while(0)
31 #define BADF(fmt, ...) \
32 do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
35 #include <sys/types.h>
39 #include "block/scsi.h"
41 #define SG_ERR_DRIVER_TIMEOUT 0x06
42 #define SG_ERR_DRIVER_SENSE 0x08
44 #define SG_ERR_DID_OK 0x00
45 #define SG_ERR_DID_NO_CONNECT 0x01
46 #define SG_ERR_DID_BUS_BUSY 0x02
47 #define SG_ERR_DID_TIME_OUT 0x03
50 #define MAX_UINT ((unsigned int)-1)
53 typedef struct SCSIGenericReq
{
58 sg_io_hdr_t io_header
;
61 static void scsi_generic_save_request(QEMUFile
*f
, SCSIRequest
*req
)
63 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
65 qemu_put_sbe32s(f
, &r
->buflen
);
66 if (r
->buflen
&& r
->req
.cmd
.mode
== SCSI_XFER_TO_DEV
) {
68 qemu_put_buffer(f
, r
->buf
, r
->req
.cmd
.xfer
);
72 static void scsi_generic_load_request(QEMUFile
*f
, SCSIRequest
*req
)
74 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
76 qemu_get_sbe32s(f
, &r
->buflen
);
77 if (r
->buflen
&& r
->req
.cmd
.mode
== SCSI_XFER_TO_DEV
) {
79 qemu_get_buffer(f
, r
->buf
, r
->req
.cmd
.xfer
);
83 static void scsi_free_request(SCSIRequest
*req
)
85 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
90 /* Helper function for command completion. */
91 static void scsi_command_complete_noio(SCSIGenericReq
*r
, int ret
)
95 assert(r
->req
.aiocb
== NULL
);
97 if (r
->req
.io_canceled
) {
98 scsi_req_cancel_complete(&r
->req
);
101 if (r
->io_header
.driver_status
& SG_ERR_DRIVER_SENSE
) {
102 r
->req
.sense_len
= r
->io_header
.sb_len_wr
;
108 status
= TASK_SET_FULL
;
111 status
= CHECK_CONDITION
;
112 scsi_req_build_sense(&r
->req
, SENSE_CODE(TARGET_FAILURE
));
115 status
= CHECK_CONDITION
;
116 scsi_req_build_sense(&r
->req
, SENSE_CODE(IO_ERROR
));
120 if (r
->io_header
.host_status
== SG_ERR_DID_NO_CONNECT
||
121 r
->io_header
.host_status
== SG_ERR_DID_BUS_BUSY
||
122 r
->io_header
.host_status
== SG_ERR_DID_TIME_OUT
||
123 (r
->io_header
.driver_status
& SG_ERR_DRIVER_TIMEOUT
)) {
125 BADF("Driver Timeout\n");
126 } else if (r
->io_header
.host_status
) {
127 status
= CHECK_CONDITION
;
128 scsi_req_build_sense(&r
->req
, SENSE_CODE(I_T_NEXUS_LOSS
));
129 } else if (r
->io_header
.status
) {
130 status
= r
->io_header
.status
;
131 } else if (r
->io_header
.driver_status
& SG_ERR_DRIVER_SENSE
) {
132 status
= CHECK_CONDITION
;
137 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
138 r
, r
->req
.tag
, status
);
140 scsi_req_complete(&r
->req
, status
);
142 scsi_req_unref(&r
->req
);
145 static void scsi_command_complete(void *opaque
, int ret
)
147 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
149 assert(r
->req
.aiocb
!= NULL
);
151 scsi_command_complete_noio(r
, ret
);
154 static int execute_command(BlockBackend
*blk
,
155 SCSIGenericReq
*r
, int direction
,
156 BlockCompletionFunc
*complete
)
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(r
->req
.sense
);
165 r
->io_header
.sbp
= r
->req
.sense
;
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
= blk_aio_ioctl(blk
, SG_IO
, &r
->io_header
, complete
, r
);
171 if (r
->req
.aiocb
== NULL
) {
178 static void scsi_read_complete(void * opaque
, int ret
)
180 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
181 SCSIDevice
*s
= r
->req
.dev
;
184 assert(r
->req
.aiocb
!= NULL
);
187 if (ret
|| r
->req
.io_canceled
) {
188 scsi_command_complete_noio(r
, ret
);
192 len
= r
->io_header
.dxfer_len
- r
->io_header
.resid
;
193 DPRINTF("Data ready tag=0x%x len=%d\n", r
->req
.tag
, len
);
197 scsi_command_complete_noio(r
, 0);
201 /* Snoop READ CAPACITY output to set the blocksize. */
202 if (r
->req
.cmd
.buf
[0] == READ_CAPACITY_10
&&
203 (ldl_be_p(&r
->buf
[0]) != 0xffffffffU
|| s
->max_lba
== 0)) {
204 s
->blocksize
= ldl_be_p(&r
->buf
[4]);
205 s
->max_lba
= ldl_be_p(&r
->buf
[0]) & 0xffffffffULL
;
206 } else if (r
->req
.cmd
.buf
[0] == SERVICE_ACTION_IN_16
&&
207 (r
->req
.cmd
.buf
[1] & 31) == SAI_READ_CAPACITY_16
) {
208 s
->blocksize
= ldl_be_p(&r
->buf
[8]);
209 s
->max_lba
= ldq_be_p(&r
->buf
[0]);
211 blk_set_guest_block_size(s
->conf
.blk
, s
->blocksize
);
213 /* Patch MODE SENSE device specific parameters if the BDS is opened
216 if ((s
->type
== TYPE_DISK
|| s
->type
== TYPE_TAPE
) &&
217 blk_is_read_only(s
->conf
.blk
) &&
218 (r
->req
.cmd
.buf
[0] == MODE_SENSE
||
219 r
->req
.cmd
.buf
[0] == MODE_SENSE_10
) &&
220 (r
->req
.cmd
.buf
[1] & 0x8) == 0) {
221 if (r
->req
.cmd
.buf
[0] == MODE_SENSE
) {
227 scsi_req_data(&r
->req
, len
);
228 scsi_req_unref(&r
->req
);
231 /* Read more data from scsi device into buffer. */
232 static void scsi_read_data(SCSIRequest
*req
)
234 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
235 SCSIDevice
*s
= r
->req
.dev
;
238 DPRINTF("scsi_read_data 0x%x\n", req
->tag
);
240 /* The request is used as the AIO opaque value, so add a ref. */
241 scsi_req_ref(&r
->req
);
243 scsi_command_complete_noio(r
, 0);
247 ret
= execute_command(s
->conf
.blk
, r
, SG_DXFER_FROM_DEV
,
250 scsi_command_complete_noio(r
, ret
);
254 static void scsi_write_complete(void * opaque
, int ret
)
256 SCSIGenericReq
*r
= (SCSIGenericReq
*)opaque
;
257 SCSIDevice
*s
= r
->req
.dev
;
259 DPRINTF("scsi_write_complete() ret = %d\n", ret
);
261 assert(r
->req
.aiocb
!= NULL
);
264 if (ret
|| r
->req
.io_canceled
) {
265 scsi_command_complete_noio(r
, ret
);
269 if (r
->req
.cmd
.buf
[0] == MODE_SELECT
&& r
->req
.cmd
.buf
[4] == 12 &&
270 s
->type
== TYPE_TAPE
) {
271 s
->blocksize
= (r
->buf
[9] << 16) | (r
->buf
[10] << 8) | r
->buf
[11];
272 DPRINTF("block size %d\n", s
->blocksize
);
275 scsi_command_complete_noio(r
, ret
);
278 /* Write data to a scsi device. Returns nonzero on failure.
279 The transfer may complete asynchronously. */
280 static void scsi_write_data(SCSIRequest
*req
)
282 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
283 SCSIDevice
*s
= r
->req
.dev
;
286 DPRINTF("scsi_write_data 0x%x\n", req
->tag
);
289 scsi_req_data(&r
->req
, r
->len
);
293 /* The request is used as the AIO opaque value, so add a ref. */
294 scsi_req_ref(&r
->req
);
295 ret
= execute_command(s
->conf
.blk
, r
, SG_DXFER_TO_DEV
, scsi_write_complete
);
297 scsi_command_complete_noio(r
, ret
);
301 /* Return a pointer to the data buffer. */
302 static uint8_t *scsi_get_buf(SCSIRequest
*req
)
304 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
309 /* Execute a scsi command. Returns the length of the data expected by the
310 command. This will be Positive for data transfers from the device
311 (eg. disk reads), negative for transfers to the device (eg. disk writes),
312 and zero if the command does not transfer any data. */
314 static int32_t scsi_send_command(SCSIRequest
*req
, uint8_t *cmd
)
316 SCSIGenericReq
*r
= DO_UPCAST(SCSIGenericReq
, req
, req
);
317 SCSIDevice
*s
= r
->req
.dev
;
323 for (i
= 1; i
< r
->req
.cmd
.len
; i
++) {
324 printf(" 0x%02x", cmd
[i
]);
330 if (r
->req
.cmd
.xfer
== 0) {
334 /* The request is used as the AIO opaque value, so add a ref. */
335 scsi_req_ref(&r
->req
);
336 ret
= execute_command(s
->conf
.blk
, r
, SG_DXFER_NONE
,
337 scsi_command_complete
);
339 scsi_command_complete_noio(r
, ret
);
345 if (r
->buflen
!= r
->req
.cmd
.xfer
) {
347 r
->buf
= g_malloc(r
->req
.cmd
.xfer
);
348 r
->buflen
= r
->req
.cmd
.xfer
;
351 memset(r
->buf
, 0, r
->buflen
);
352 r
->len
= r
->req
.cmd
.xfer
;
353 if (r
->req
.cmd
.mode
== SCSI_XFER_TO_DEV
) {
355 return -r
->req
.cmd
.xfer
;
357 return r
->req
.cmd
.xfer
;
361 static int get_stream_blocksize(BlockBackend
*blk
)
366 sg_io_hdr_t io_header
;
369 memset(cmd
, 0, sizeof(cmd
));
370 memset(buf
, 0, sizeof(buf
));
372 cmd
[4] = sizeof(buf
);
374 memset(&io_header
, 0, sizeof(io_header
));
375 io_header
.interface_id
= 'S';
376 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
377 io_header
.dxfer_len
= sizeof(buf
);
378 io_header
.dxferp
= buf
;
379 io_header
.cmdp
= cmd
;
380 io_header
.cmd_len
= sizeof(cmd
);
381 io_header
.mx_sb_len
= sizeof(sensebuf
);
382 io_header
.sbp
= sensebuf
;
383 io_header
.timeout
= 6000; /* XXX */
385 ret
= blk_ioctl(blk
, SG_IO
, &io_header
);
386 if (ret
< 0 || io_header
.driver_status
|| io_header
.host_status
) {
389 return (buf
[9] << 16) | (buf
[10] << 8) | buf
[11];
392 static void scsi_generic_reset(DeviceState
*dev
)
394 SCSIDevice
*s
= SCSI_DEVICE(dev
);
396 scsi_device_purge_requests(s
, SENSE_CODE(RESET
));
399 static void scsi_generic_realize(SCSIDevice
*s
, Error
**errp
)
403 struct sg_scsi_id scsiid
;
406 error_setg(errp
, "drive property not set");
410 if (blk_get_on_error(s
->conf
.blk
, 0) != BLOCKDEV_ON_ERROR_ENOSPC
) {
411 error_setg(errp
, "Device doesn't support drive option werror");
414 if (blk_get_on_error(s
->conf
.blk
, 1) != BLOCKDEV_ON_ERROR_REPORT
) {
415 error_setg(errp
, "Device doesn't support drive option rerror");
419 /* check we are using a driver managing SG_IO (version 3 and after */
420 rc
= blk_ioctl(s
->conf
.blk
, SG_GET_VERSION_NUM
, &sg_version
);
422 error_setg(errp
, "cannot get SG_IO version number: %s. "
423 "Is this a SCSI device?",
427 if (sg_version
< 30000) {
428 error_setg(errp
, "scsi generic interface too old");
432 /* get LUN of the /dev/sg? */
433 if (blk_ioctl(s
->conf
.blk
, SG_GET_SCSI_ID
, &scsiid
)) {
434 error_setg(errp
, "SG_GET_SCSI_ID ioctl failed");
438 /* define device state */
439 s
->type
= scsiid
.scsi_type
;
440 DPRINTF("device type %d\n", s
->type
);
444 s
->blocksize
= get_stream_blocksize(s
->conf
.blk
);
445 if (s
->blocksize
== -1) {
450 /* Make a guess for block devices, we'll fix it when the guest sends.
451 * READ CAPACITY. If they don't, they likely would assume these sizes
452 * anyway. (TODO: they could also send MODE SENSE).
463 DPRINTF("block size %d\n", s
->blocksize
);
466 const SCSIReqOps scsi_generic_req_ops
= {
467 .size
= sizeof(SCSIGenericReq
),
468 .free_req
= scsi_free_request
,
469 .send_command
= scsi_send_command
,
470 .read_data
= scsi_read_data
,
471 .write_data
= scsi_write_data
,
472 .get_buf
= scsi_get_buf
,
473 .load_request
= scsi_generic_load_request
,
474 .save_request
= scsi_generic_save_request
,
477 static SCSIRequest
*scsi_new_request(SCSIDevice
*d
, uint32_t tag
, uint32_t lun
,
478 uint8_t *buf
, void *hba_private
)
482 req
= scsi_req_alloc(&scsi_generic_req_ops
, d
, tag
, lun
, hba_private
);
486 static Property scsi_generic_properties
[] = {
487 DEFINE_PROP_DRIVE("drive", SCSIDevice
, conf
.blk
),
488 DEFINE_PROP_END_OF_LIST(),
491 static int scsi_generic_parse_cdb(SCSIDevice
*dev
, SCSICommand
*cmd
,
492 uint8_t *buf
, void *hba_private
)
494 return scsi_bus_parse_cdb(dev
, cmd
, buf
, hba_private
);
497 static void scsi_generic_class_initfn(ObjectClass
*klass
, void *data
)
499 DeviceClass
*dc
= DEVICE_CLASS(klass
);
500 SCSIDeviceClass
*sc
= SCSI_DEVICE_CLASS(klass
);
502 sc
->realize
= scsi_generic_realize
;
503 sc
->alloc_req
= scsi_new_request
;
504 sc
->parse_cdb
= scsi_generic_parse_cdb
;
505 dc
->fw_name
= "disk";
506 dc
->desc
= "pass through generic scsi device (/dev/sg*)";
507 dc
->reset
= scsi_generic_reset
;
508 dc
->props
= scsi_generic_properties
;
509 dc
->vmsd
= &vmstate_scsi_device
;
512 static const TypeInfo scsi_generic_info
= {
513 .name
= "scsi-generic",
514 .parent
= TYPE_SCSI_DEVICE
,
515 .instance_size
= sizeof(SCSIDevice
),
516 .class_init
= scsi_generic_class_initfn
,
519 static void scsi_generic_register_types(void)
521 type_register_static(&scsi_generic_info
);
524 type_init(scsi_generic_register_types
)
526 #endif /* __linux__ */