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
10 * This code is licenced 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
65 uint8_t sensebuf[SCSI_SENSE_BUF_SIZE];
69 static void scsi_set_sense(SCSIGenericState *s, SCSISense sense)
71 s->senselen = scsi_build_sense(sense, s->sensebuf, SCSI_SENSE_BUF_SIZE, 0);
72 s->driver_status = SG_ERR_DRIVER_SENSE;
75 static void scsi_clear_sense(SCSIGenericState *s)
77 memset(s->sensebuf, 0, SCSI_SENSE_BUF_SIZE);
82 static int scsi_get_sense(SCSIRequest *req, uint8_t *outbuf, int len)
84 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
85 int size = SCSI_SENSE_BUF_SIZE;
87 if (!(s->driver_status & SG_ERR_DRIVER_SENSE)) {
88 size = scsi_build_sense(SENSE_CODE(NO_SENSE), s->sensebuf,
89 SCSI_SENSE_BUF_SIZE, 0);
94 memcpy(outbuf, s->sensebuf, size);
99 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
103 req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun);
107 static void scsi_free_request(SCSIRequest *req)
109 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
114 /* Helper function for command completion. */
115 static void scsi_command_complete(void *opaque, int ret)
117 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
118 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
121 s->driver_status = r->io_header.driver_status;
122 if (s->driver_status & SG_ERR_DRIVER_SENSE)
123 s->senselen = r->io_header.sb_len_wr;
128 r->req.status = CHECK_CONDITION;
129 scsi_set_sense(s, SENSE_CODE(INVALID_FIELD));
132 r->req.status = CHECK_CONDITION;
133 scsi_set_sense(s, SENSE_CODE(TARGET_FAILURE));
136 r->req.status = CHECK_CONDITION;
137 scsi_set_sense(s, SENSE_CODE(IO_ERROR));
141 if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
142 r->req.status = BUSY;
143 BADF("Driver Timeout\n");
144 } else if (r->io_header.status)
145 r->req.status = r->io_header.status;
146 else if (s->driver_status & SG_ERR_DRIVER_SENSE)
147 r->req.status = CHECK_CONDITION;
149 r->req.status = GOOD;
151 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
152 r, r->req.tag, r->req.status);
154 scsi_req_complete(&r->req);
157 /* Cancel a pending data transfer. */
158 static void scsi_cancel_io(SCSIRequest *req)
160 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
162 DPRINTF("Cancel tag=0x%x\n", req->tag);
164 bdrv_aio_cancel(r->req.aiocb);
169 static int execute_command(BlockDriverState *bdrv,
170 SCSIGenericReq *r, int direction,
171 BlockDriverCompletionFunc *complete)
173 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
175 r->io_header.interface_id = 'S';
176 r->io_header.dxfer_direction = direction;
177 r->io_header.dxferp = r->buf;
178 r->io_header.dxfer_len = r->buflen;
179 r->io_header.cmdp = r->req.cmd.buf;
180 r->io_header.cmd_len = r->req.cmd.len;
181 r->io_header.mx_sb_len = sizeof(s->sensebuf);
182 r->io_header.sbp = s->sensebuf;
183 r->io_header.timeout = MAX_UINT;
184 r->io_header.usr_ptr = r;
185 r->io_header.flags |= SG_FLAG_DIRECT_IO;
187 r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
188 if (r->req.aiocb == NULL) {
189 BADF("execute_command: read failed !\n");
196 static void scsi_read_complete(void * opaque, int ret)
198 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
203 DPRINTF("IO error ret %d\n", ret);
204 scsi_command_complete(r, ret);
207 len = r->io_header.dxfer_len - r->io_header.resid;
208 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
212 scsi_command_complete(r, 0);
214 scsi_req_data(&r->req, len);
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 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
225 DPRINTF("scsi_read_data 0x%x\n", req->tag);
227 scsi_command_complete(r, 0);
231 if (r->req.cmd.buf[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
233 s->senselen = MIN(r->len, s->senselen);
234 memcpy(r->buf, s->sensebuf, s->senselen);
235 r->io_header.driver_status = 0;
236 r->io_header.status = 0;
237 r->io_header.dxfer_len = s->senselen;
239 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, s->senselen);
240 DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
241 r->buf[0], r->buf[1], r->buf[2], r->buf[3],
242 r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
243 scsi_req_data(&r->req, s->senselen);
244 /* Clear sensebuf after REQUEST_SENSE */
249 ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
251 scsi_command_complete(r, ret);
256 static void scsi_write_complete(void * opaque, int ret)
258 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
259 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
261 DPRINTF("scsi_write_complete() ret = %d\n", ret);
264 DPRINTF("IO error\n");
265 scsi_command_complete(r, ret);
269 if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
270 s->qdev.type == TYPE_TAPE) {
271 s->qdev.blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
272 DPRINTF("block size %d\n", s->qdev.blocksize);
275 scsi_command_complete(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 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
283 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
286 DPRINTF("scsi_write_data 0x%x\n", req->tag);
289 scsi_req_data(&r->req, r->len);
293 ret = execute_command(s->bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
295 scsi_command_complete(r, ret);
299 /* Return a pointer to the data buffer. */
300 static uint8_t *scsi_get_buf(SCSIRequest *req)
302 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
307 static void scsi_req_fixup(SCSIRequest *req)
309 switch(req->cmd.buf[0]) {
311 req->cmd.buf[1] &= ~0x08; /* disable FUA */
314 req->cmd.buf[1] &= ~0x08; /* disable FUA */
318 if (req->dev->type == TYPE_TAPE) {
319 /* force IMMED, otherwise qemu waits end of command */
320 req->cmd.buf[1] = 0x01;
326 /* Execute a scsi command. Returns the length of the data expected by the
327 command. This will be Positive for data transfers from the device
328 (eg. disk reads), negative for transfers to the device (eg. disk writes),
329 and zero if the command does not transfer any data. */
331 static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
333 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
334 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
337 if (cmd[0] != REQUEST_SENSE &&
338 (req->lun != s->lun || (cmd[1] >> 5) != s->lun)) {
339 DPRINTF("Unimplemented LUN %d\n", req->lun ? req->lun : cmd[1] >> 5);
340 scsi_set_sense(s, SENSE_CODE(LUN_NOT_SUPPORTED));
341 r->req.status = CHECK_CONDITION;
342 scsi_req_complete(&r->req);
346 if (-1 == scsi_req_parse(&r->req, cmd)) {
347 BADF("Unsupported command length, command %x\n", cmd[0]);
348 scsi_command_complete(r, -EINVAL);
351 scsi_req_fixup(&r->req);
353 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun, tag,
354 r->req.cmd.xfer, cmd[0]);
359 for (i = 1; i < r->req.cmd.len; i++) {
360 printf(" 0x%02x", cmd[i]);
366 if (r->req.cmd.xfer == 0) {
371 ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);
373 scsi_command_complete(r, ret);
379 if (r->buflen != r->req.cmd.xfer) {
382 r->buf = qemu_malloc(r->req.cmd.xfer);
383 r->buflen = r->req.cmd.xfer;
386 memset(r->buf, 0, r->buflen);
387 r->len = r->req.cmd.xfer;
388 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
390 return -r->req.cmd.xfer;
392 return r->req.cmd.xfer;
396 static int get_blocksize(BlockDriverState *bdrv)
401 sg_io_hdr_t io_header;
404 memset(cmd, 0, sizeof(cmd));
405 memset(buf, 0, sizeof(buf));
406 cmd[0] = READ_CAPACITY;
408 memset(&io_header, 0, sizeof(io_header));
409 io_header.interface_id = 'S';
410 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
411 io_header.dxfer_len = sizeof(buf);
412 io_header.dxferp = buf;
413 io_header.cmdp = cmd;
414 io_header.cmd_len = sizeof(cmd);
415 io_header.mx_sb_len = sizeof(sensebuf);
416 io_header.sbp = sensebuf;
417 io_header.timeout = 6000; /* XXX */
419 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
423 return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
426 static int get_stream_blocksize(BlockDriverState *bdrv)
431 sg_io_hdr_t io_header;
434 memset(cmd, 0, sizeof(cmd));
435 memset(buf, 0, sizeof(buf));
437 cmd[4] = sizeof(buf);
439 memset(&io_header, 0, sizeof(io_header));
440 io_header.interface_id = 'S';
441 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
442 io_header.dxfer_len = sizeof(buf);
443 io_header.dxferp = buf;
444 io_header.cmdp = cmd;
445 io_header.cmd_len = sizeof(cmd);
446 io_header.mx_sb_len = sizeof(sensebuf);
447 io_header.sbp = sensebuf;
448 io_header.timeout = 6000; /* XXX */
450 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
454 return (buf[9] << 16) | (buf[10] << 8) | buf[11];
457 static void scsi_generic_reset(DeviceState *dev)
459 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev.qdev, dev);
461 scsi_device_purge_requests(&s->qdev);
464 static void scsi_destroy(SCSIDevice *d)
466 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
468 scsi_device_purge_requests(&s->qdev);
469 blockdev_mark_auto_del(s->qdev.conf.bs);
472 static int scsi_generic_initfn(SCSIDevice *dev)
474 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
476 struct sg_scsi_id scsiid;
478 if (!s->qdev.conf.bs) {
479 error_report("scsi-generic: drive property not set");
482 s->bs = s->qdev.conf.bs;
484 /* check we are really using a /dev/sg* file */
485 if (!bdrv_is_sg(s->bs)) {
486 error_report("scsi-generic: not /dev/sg*");
490 if (bdrv_get_on_error(s->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
491 error_report("Device doesn't support drive option werror");
494 if (bdrv_get_on_error(s->bs, 1) != BLOCK_ERR_REPORT) {
495 error_report("Device doesn't support drive option rerror");
499 /* check we are using a driver managing SG_IO (version 3 and after */
500 if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
501 sg_version < 30000) {
502 error_report("scsi-generic: scsi generic interface too old");
506 /* get LUN of the /dev/sg? */
507 if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
508 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
512 /* define device state */
514 DPRINTF("LUN %d\n", s->lun);
515 s->qdev.type = scsiid.scsi_type;
516 DPRINTF("device type %d\n", s->qdev.type);
517 if (s->qdev.type == TYPE_TAPE) {
518 s->qdev.blocksize = get_stream_blocksize(s->bs);
519 if (s->qdev.blocksize == -1)
520 s->qdev.blocksize = 0;
522 s->qdev.blocksize = get_blocksize(s->bs);
523 /* removable media returns 0 if not present */
524 if (s->qdev.blocksize <= 0) {
525 if (s->qdev.type == TYPE_ROM || s->qdev.type == TYPE_WORM)
526 s->qdev.blocksize = 2048;
528 s->qdev.blocksize = 512;
531 DPRINTF("block size %d\n", s->qdev.blocksize);
532 s->driver_status = 0;
533 memset(s->sensebuf, 0, sizeof(s->sensebuf));
534 bdrv_set_removable(s->bs, 0);
538 static SCSIDeviceInfo scsi_generic_info = {
539 .qdev.name = "scsi-generic",
540 .qdev.desc = "pass through generic scsi device (/dev/sg*)",
541 .qdev.size = sizeof(SCSIGenericState),
542 .qdev.reset = scsi_generic_reset,
543 .init = scsi_generic_initfn,
544 .destroy = scsi_destroy,
545 .alloc_req = scsi_new_request,
546 .free_req = scsi_free_request,
547 .send_command = scsi_send_command,
548 .read_data = scsi_read_data,
549 .write_data = scsi_write_data,
550 .cancel_io = scsi_cancel_io,
551 .get_buf = scsi_get_buf,
552 .get_sense = scsi_get_sense,
553 .qdev.props = (Property[]) {
554 DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf),
555 DEFINE_PROP_END_OF_LIST(),
559 static void scsi_generic_register_devices(void)
561 scsi_qdev_register(&scsi_generic_info);
563 device_init(scsi_generic_register_devices)
565 #endif /* __linux__ */