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/blockdev.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 "block/scsi.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_generic_save_request(QEMUFile *f, SCSIRequest *req)
64
SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
66
qemu_put_sbe32s(f, &r->buflen);
67
if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
69
qemu_put_buffer(f, r->buf, r->req.cmd.xfer);
73
static void scsi_generic_load_request(QEMUFile *f, SCSIRequest *req)
75
SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
77
qemu_get_sbe32s(f, &r->buflen);
78
if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
80
qemu_get_buffer(f, r->buf, r->req.cmd.xfer);
84
static void scsi_free_request(SCSIRequest *req)
86
SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
91
/* Helper function for command completion. */
92
static void scsi_command_complete(void *opaque, int ret)
95
SCSIGenericReq *r = (SCSIGenericReq *)opaque;
98
if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
99
r->req.sense_len = r->io_header.sb_len_wr;
105
status = TASK_SET_FULL;
108
status = CHECK_CONDITION;
109
scsi_req_build_sense(&r->req, SENSE_CODE(TARGET_FAILURE));
112
status = CHECK_CONDITION;
113
scsi_req_build_sense(&r->req, SENSE_CODE(IO_ERROR));
117
if (r->io_header.host_status == SG_ERR_DID_NO_CONNECT ||
118
r->io_header.host_status == SG_ERR_DID_BUS_BUSY ||
119
r->io_header.host_status == SG_ERR_DID_TIME_OUT ||
120
(r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT)) {
122
BADF("Driver Timeout\n");
123
} else if (r->io_header.host_status) {
124
status = CHECK_CONDITION;
125
scsi_req_build_sense(&r->req, SENSE_CODE(I_T_NEXUS_LOSS));
126
} else if (r->io_header.status) {
127
status = r->io_header.status;
128
} else if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
129
status = CHECK_CONDITION;
134
DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
135
r, r->req.tag, status);
137
scsi_req_complete(&r->req, status);
138
if (!r->req.io_canceled) {
139
scsi_req_unref(&r->req);
143
/* Cancel a pending data transfer. */
144
static void scsi_cancel_io(SCSIRequest *req)
146
SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
148
DPRINTF("Cancel tag=0x%x\n", req->tag);
150
bdrv_aio_cancel(r->req.aiocb);
152
/* This reference was left in by scsi_*_data. We take ownership of
153
* it independent of whether bdrv_aio_cancel completes the request
155
scsi_req_unref(&r->req);
160
static int execute_command(BlockDriverState *bdrv,
161
SCSIGenericReq *r, int direction,
162
BlockDriverCompletionFunc *complete)
164
r->io_header.interface_id = 'S';
165
r->io_header.dxfer_direction = direction;
166
r->io_header.dxferp = r->buf;
167
r->io_header.dxfer_len = r->buflen;
168
r->io_header.cmdp = r->req.cmd.buf;
169
r->io_header.cmd_len = r->req.cmd.len;
170
r->io_header.mx_sb_len = sizeof(r->req.sense);
171
r->io_header.sbp = r->req.sense;
172
r->io_header.timeout = MAX_UINT;
173
r->io_header.usr_ptr = r;
174
r->io_header.flags |= SG_FLAG_DIRECT_IO;
176
r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
181
static void scsi_read_complete(void * opaque, int ret)
183
SCSIGenericReq *r = (SCSIGenericReq *)opaque;
184
SCSIDevice *s = r->req.dev;
189
DPRINTF("IO error ret %d\n", ret);
190
scsi_command_complete(r, ret);
193
len = r->io_header.dxfer_len - r->io_header.resid;
194
DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
198
scsi_command_complete(r, 0);
200
/* Snoop READ CAPACITY output to set the blocksize. */
201
if (r->req.cmd.buf[0] == READ_CAPACITY_10) {
202
s->blocksize = ldl_be_p(&r->buf[4]);
203
s->max_lba = ldl_be_p(&r->buf[0]);
204
} else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 &&
205
(r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
206
s->blocksize = ldl_be_p(&r->buf[8]);
207
s->max_lba = ldq_be_p(&r->buf[0]);
209
bdrv_set_buffer_alignment(s->conf.bs, s->blocksize);
211
scsi_req_data(&r->req, len);
212
if (!r->req.io_canceled) {
213
scsi_req_unref(&r->req);
218
/* Read more data from scsi device into buffer. */
219
static void scsi_read_data(SCSIRequest *req)
221
SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
222
SCSIDevice *s = r->req.dev;
225
DPRINTF("scsi_read_data 0x%x\n", req->tag);
227
/* The request is used as the AIO opaque value, so add a ref. */
228
scsi_req_ref(&r->req);
230
scsi_command_complete(r, 0);
234
ret = execute_command(s->conf.bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
236
scsi_command_complete(r, ret);
240
static void scsi_write_complete(void * opaque, int ret)
242
SCSIGenericReq *r = (SCSIGenericReq *)opaque;
243
SCSIDevice *s = r->req.dev;
245
DPRINTF("scsi_write_complete() ret = %d\n", ret);
248
DPRINTF("IO error\n");
249
scsi_command_complete(r, ret);
253
if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
254
s->type == TYPE_TAPE) {
255
s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
256
DPRINTF("block size %d\n", s->blocksize);
259
scsi_command_complete(r, ret);
262
/* Write data to a scsi device. Returns nonzero on failure.
263
The transfer may complete asynchronously. */
264
static void scsi_write_data(SCSIRequest *req)
266
SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
267
SCSIDevice *s = r->req.dev;
270
DPRINTF("scsi_write_data 0x%x\n", req->tag);
273
scsi_req_data(&r->req, r->len);
277
/* The request is used as the AIO opaque value, so add a ref. */
278
scsi_req_ref(&r->req);
279
ret = execute_command(s->conf.bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
281
scsi_command_complete(r, ret);
285
/* Return a pointer to the data buffer. */
286
static uint8_t *scsi_get_buf(SCSIRequest *req)
288
SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
293
/* Execute a scsi command. Returns the length of the data expected by the
294
command. This will be Positive for data transfers from the device
295
(eg. disk reads), negative for transfers to the device (eg. disk writes),
296
and zero if the command does not transfer any data. */
298
static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
300
SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
301
SCSIDevice *s = r->req.dev;
304
DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun, tag,
305
r->req.cmd.xfer, cmd[0]);
310
for (i = 1; i < r->req.cmd.len; i++) {
311
printf(" 0x%02x", cmd[i]);
317
if (r->req.cmd.xfer == 0) {
322
/* The request is used as the AIO opaque value, so add a ref. */
323
scsi_req_ref(&r->req);
324
ret = execute_command(s->conf.bs, r, SG_DXFER_NONE, scsi_command_complete);
326
scsi_command_complete(r, ret);
332
if (r->buflen != r->req.cmd.xfer) {
335
r->buf = g_malloc(r->req.cmd.xfer);
336
r->buflen = r->req.cmd.xfer;
339
memset(r->buf, 0, r->buflen);
340
r->len = r->req.cmd.xfer;
341
if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
343
return -r->req.cmd.xfer;
345
return r->req.cmd.xfer;
349
static int get_stream_blocksize(BlockDriverState *bdrv)
354
sg_io_hdr_t io_header;
357
memset(cmd, 0, sizeof(cmd));
358
memset(buf, 0, sizeof(buf));
360
cmd[4] = sizeof(buf);
362
memset(&io_header, 0, sizeof(io_header));
363
io_header.interface_id = 'S';
364
io_header.dxfer_direction = SG_DXFER_FROM_DEV;
365
io_header.dxfer_len = sizeof(buf);
366
io_header.dxferp = buf;
367
io_header.cmdp = cmd;
368
io_header.cmd_len = sizeof(cmd);
369
io_header.mx_sb_len = sizeof(sensebuf);
370
io_header.sbp = sensebuf;
371
io_header.timeout = 6000; /* XXX */
373
ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
374
if (ret < 0 || io_header.driver_status || io_header.host_status) {
377
return (buf[9] << 16) | (buf[10] << 8) | buf[11];
380
static void scsi_generic_reset(DeviceState *dev)
382
SCSIDevice *s = SCSI_DEVICE(dev);
384
scsi_device_purge_requests(s, SENSE_CODE(RESET));
387
static void scsi_destroy(SCSIDevice *s)
389
scsi_device_purge_requests(s, SENSE_CODE(NO_SENSE));
390
blockdev_mark_auto_del(s->conf.bs);
393
static int scsi_generic_initfn(SCSIDevice *s)
396
struct sg_scsi_id scsiid;
399
error_report("drive property not set");
403
if (bdrv_get_on_error(s->conf.bs, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
404
error_report("Device doesn't support drive option werror");
407
if (bdrv_get_on_error(s->conf.bs, 1) != BLOCKDEV_ON_ERROR_REPORT) {
408
error_report("Device doesn't support drive option rerror");
412
/* check we are using a driver managing SG_IO (version 3 and after */
413
if (bdrv_ioctl(s->conf.bs, SG_GET_VERSION_NUM, &sg_version) < 0) {
414
error_report("scsi generic interface not supported");
417
if (sg_version < 30000) {
418
error_report("scsi generic interface too old");
422
/* get LUN of the /dev/sg? */
423
if (bdrv_ioctl(s->conf.bs, SG_GET_SCSI_ID, &scsiid)) {
424
error_report("SG_GET_SCSI_ID ioctl failed");
428
/* define device state */
429
s->type = scsiid.scsi_type;
430
DPRINTF("device type %d\n", s->type);
431
if (s->type == TYPE_DISK || s->type == TYPE_ROM) {
432
add_boot_device_path(s->conf.bootindex, &s->qdev, NULL);
437
s->blocksize = get_stream_blocksize(s->conf.bs);
438
if (s->blocksize == -1) {
443
/* Make a guess for block devices, we'll fix it when the guest sends.
444
* READ CAPACITY. If they don't, they likely would assume these sizes
445
* anyway. (TODO: they could also send MODE SENSE).
456
DPRINTF("block size %d\n", s->blocksize);
460
const SCSIReqOps scsi_generic_req_ops = {
461
.size = sizeof(SCSIGenericReq),
462
.free_req = scsi_free_request,
463
.send_command = scsi_send_command,
464
.read_data = scsi_read_data,
465
.write_data = scsi_write_data,
466
.cancel_io = scsi_cancel_io,
467
.get_buf = scsi_get_buf,
468
.load_request = scsi_generic_load_request,
469
.save_request = scsi_generic_save_request,
472
static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
473
uint8_t *buf, void *hba_private)
477
req = scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
481
static Property scsi_generic_properties[] = {
482
DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.bs),
483
DEFINE_PROP_INT32("bootindex", SCSIDevice, conf.bootindex, -1),
484
DEFINE_PROP_END_OF_LIST(),
487
static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
489
DeviceClass *dc = DEVICE_CLASS(klass);
490
SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
492
sc->init = scsi_generic_initfn;
493
sc->destroy = scsi_destroy;
494
sc->alloc_req = scsi_new_request;
495
dc->fw_name = "disk";
496
dc->desc = "pass through generic scsi device (/dev/sg*)";
497
dc->reset = scsi_generic_reset;
498
dc->props = scsi_generic_properties;
499
dc->vmsd = &vmstate_scsi_device;
502
static const TypeInfo scsi_generic_info = {
503
.name = "scsi-generic",
504
.parent = TYPE_SCSI_DEVICE,
505
.instance_size = sizeof(SCSIDevice),
506
.class_init = scsi_generic_class_initfn,
509
static void scsi_generic_register_types(void)
511
type_register_static(&scsi_generic_info);
514
type_init(scsi_generic_register_types)
516
#endif /* __linux__ */