scsi-generic: do not use a stale aiocb
[qemu.git] / hw / scsi-generic.c
blobbd099835f4e621ffaa451c0c1800b05e4ba56eb7
1 /*
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 licenced under the LGPL.
14 #include "qemu-common.h"
15 #include "qemu-error.h"
16 #include "scsi.h"
17 #include "blockdev.h"
19 #ifdef __linux__
21 //#define DEBUG_SCSI
23 #ifdef DEBUG_SCSI
24 #define DPRINTF(fmt, ...) \
25 do { printf("scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
26 #else
27 #define DPRINTF(fmt, ...) do {} while(0)
28 #endif
30 #define BADF(fmt, ...) \
31 do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
33 #include <stdio.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <unistd.h>
37 #include <scsi/sg.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 #ifndef MAX_UINT
46 #define MAX_UINT ((unsigned int)-1)
47 #endif
49 typedef struct SCSIGenericState SCSIGenericState;
51 typedef struct SCSIGenericReq {
52 SCSIRequest req;
53 uint8_t *buf;
54 int buflen;
55 int len;
56 sg_io_hdr_t io_header;
57 } SCSIGenericReq;
59 struct SCSIGenericState
61 SCSIDevice qdev;
62 BlockDriverState *bs;
63 int lun;
64 int driver_status;
65 uint8_t sensebuf[SCSI_SENSE_BUF_SIZE];
66 uint8_t senselen;
69 static SCSIGenericReq *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
71 SCSIRequest *req;
73 req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun);
74 return DO_UPCAST(SCSIGenericReq, req, req);
77 static void scsi_remove_request(SCSIGenericReq *r)
79 qemu_free(r->buf);
80 scsi_req_free(&r->req);
83 static SCSIGenericReq *scsi_find_request(SCSIGenericState *s, uint32_t tag)
85 return DO_UPCAST(SCSIGenericReq, req, scsi_req_find(&s->qdev, tag));
88 /* Helper function for command completion. */
89 static void scsi_command_complete(void *opaque, int ret)
91 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
92 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
94 r->req.aiocb = NULL;
95 s->driver_status = r->io_header.driver_status;
96 if (s->driver_status & SG_ERR_DRIVER_SENSE)
97 s->senselen = r->io_header.sb_len_wr;
99 if (ret != 0)
100 r->req.status = BUSY;
101 else {
102 if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
103 r->req.status = BUSY;
104 BADF("Driver Timeout\n");
105 } else if (r->io_header.status)
106 r->req.status = r->io_header.status;
107 else if (s->driver_status & SG_ERR_DRIVER_SENSE)
108 r->req.status = CHECK_CONDITION;
109 else
110 r->req.status = GOOD;
112 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
113 r, r->req.tag, r->req.status);
115 scsi_req_complete(&r->req);
116 scsi_remove_request(r);
119 /* Cancel a pending data transfer. */
120 static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
122 DPRINTF("scsi_cancel_io 0x%x\n", tag);
123 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
124 SCSIGenericReq *r;
125 DPRINTF("Cancel tag=0x%x\n", tag);
126 r = scsi_find_request(s, tag);
127 if (r) {
128 if (r->req.aiocb)
129 bdrv_aio_cancel(r->req.aiocb);
130 r->req.aiocb = NULL;
131 scsi_remove_request(r);
135 static int execute_command(BlockDriverState *bdrv,
136 SCSIGenericReq *r, int direction,
137 BlockDriverCompletionFunc *complete)
139 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
141 r->io_header.interface_id = 'S';
142 r->io_header.dxfer_direction = direction;
143 r->io_header.dxferp = r->buf;
144 r->io_header.dxfer_len = r->buflen;
145 r->io_header.cmdp = r->req.cmd.buf;
146 r->io_header.cmd_len = r->req.cmd.len;
147 r->io_header.mx_sb_len = sizeof(s->sensebuf);
148 r->io_header.sbp = s->sensebuf;
149 r->io_header.timeout = MAX_UINT;
150 r->io_header.usr_ptr = r;
151 r->io_header.flags |= SG_FLAG_DIRECT_IO;
153 r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
154 if (r->req.aiocb == NULL) {
155 BADF("execute_command: read failed !\n");
156 return -1;
159 return 0;
162 static void scsi_read_complete(void * opaque, int ret)
164 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
165 int len;
167 r->req.aiocb = NULL;
168 if (ret) {
169 DPRINTF("IO error ret %d\n", ret);
170 scsi_command_complete(r, ret);
171 return;
173 len = r->io_header.dxfer_len - r->io_header.resid;
174 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
176 r->len = -1;
177 if (len == 0) {
178 scsi_command_complete(r, 0);
179 } else {
180 scsi_req_data(&r->req, len);
184 /* Read more data from scsi device into buffer. */
185 static void scsi_read_data(SCSIDevice *d, uint32_t tag)
187 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
188 SCSIGenericReq *r;
189 int ret;
191 DPRINTF("scsi_read_data 0x%x\n", tag);
192 r = scsi_find_request(s, tag);
193 if (!r) {
194 BADF("Bad read tag 0x%x\n", tag);
195 /* ??? This is the wrong error. */
196 scsi_command_complete(r, -EINVAL);
197 return;
200 if (r->len == -1) {
201 scsi_command_complete(r, 0);
202 return;
205 if (r->req.cmd.buf[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
207 s->senselen = MIN(r->len, s->senselen);
208 memcpy(r->buf, s->sensebuf, s->senselen);
209 r->io_header.driver_status = 0;
210 r->io_header.status = 0;
211 r->io_header.dxfer_len = s->senselen;
212 r->len = -1;
213 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, s->senselen);
214 DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
215 r->buf[0], r->buf[1], r->buf[2], r->buf[3],
216 r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
217 scsi_req_data(&r->req, s->senselen);
218 return;
221 ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
222 if (ret == -1) {
223 scsi_command_complete(r, -EINVAL);
224 return;
228 static void scsi_write_complete(void * opaque, int ret)
230 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
231 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
233 DPRINTF("scsi_write_complete() ret = %d\n", ret);
234 r->req.aiocb = NULL;
235 if (ret) {
236 DPRINTF("IO error\n");
237 scsi_command_complete(r, ret);
238 return;
241 if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
242 s->qdev.type == TYPE_TAPE) {
243 s->qdev.blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
244 DPRINTF("block size %d\n", s->qdev.blocksize);
247 scsi_command_complete(r, ret);
250 /* Write data to a scsi device. Returns nonzero on failure.
251 The transfer may complete asynchronously. */
252 static int scsi_write_data(SCSIDevice *d, uint32_t tag)
254 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
255 SCSIGenericReq *r;
256 int ret;
258 DPRINTF("scsi_write_data 0x%x\n", tag);
259 r = scsi_find_request(s, tag);
260 if (!r) {
261 BADF("Bad write tag 0x%x\n", tag);
262 /* ??? This is the wrong error. */
263 scsi_command_complete(r, -EINVAL);
264 return 0;
267 if (r->len == 0) {
268 r->len = r->buflen;
269 scsi_req_data(&r->req, r->len);
270 return 0;
273 ret = execute_command(s->bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
274 if (ret == -1) {
275 scsi_command_complete(r, -EINVAL);
276 return 1;
279 return 0;
282 /* Return a pointer to the data buffer. */
283 static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
285 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
286 SCSIGenericReq *r;
287 r = scsi_find_request(s, tag);
288 if (!r) {
289 BADF("Bad buffer tag 0x%x\n", tag);
290 return NULL;
292 return r->buf;
295 static void scsi_req_fixup(SCSIRequest *req)
297 switch(req->cmd.buf[0]) {
298 case WRITE_10:
299 req->cmd.buf[1] &= ~0x08; /* disable FUA */
300 break;
301 case READ_10:
302 req->cmd.buf[1] &= ~0x08; /* disable FUA */
303 break;
304 case REWIND:
305 case START_STOP:
306 if (req->dev->type == TYPE_TAPE) {
307 /* force IMMED, otherwise qemu waits end of command */
308 req->cmd.buf[1] = 0x01;
310 break;
314 /* Execute a scsi command. Returns the length of the data expected by the
315 command. This will be Positive for data transfers from the device
316 (eg. disk reads), negative for transfers to the device (eg. disk writes),
317 and zero if the command does not transfer any data. */
319 static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
320 uint8_t *cmd, int lun)
322 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
323 SCSIGenericReq *r;
324 SCSIBus *bus;
325 int ret;
327 if (cmd[0] != REQUEST_SENSE &&
328 (lun != s->lun || (cmd[1] >> 5) != s->lun)) {
329 DPRINTF("Unimplemented LUN %d\n", lun ? lun : cmd[1] >> 5);
331 s->sensebuf[0] = 0x70;
332 s->sensebuf[1] = 0x00;
333 s->sensebuf[2] = ILLEGAL_REQUEST;
334 s->sensebuf[3] = 0x00;
335 s->sensebuf[4] = 0x00;
336 s->sensebuf[5] = 0x00;
337 s->sensebuf[6] = 0x00;
338 s->senselen = 7;
339 s->driver_status = SG_ERR_DRIVER_SENSE;
340 bus = scsi_bus_from_device(d);
341 bus->ops->complete(bus, SCSI_REASON_DONE, tag, CHECK_CONDITION);
342 return 0;
345 r = scsi_find_request(s, tag);
346 if (r) {
347 BADF("Tag 0x%x already in use %p\n", tag, r);
348 scsi_cancel_io(d, tag);
350 r = scsi_new_request(d, tag, lun);
352 if (-1 == scsi_req_parse(&r->req, cmd)) {
353 BADF("Unsupported command length, command %x\n", cmd[0]);
354 scsi_remove_request(r);
355 return 0;
357 scsi_req_fixup(&r->req);
359 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun, tag,
360 r->req.cmd.xfer, cmd[0]);
362 #ifdef DEBUG_SCSI
364 int i;
365 for (i = 1; i < r->req.cmd.len; i++) {
366 printf(" 0x%02x", cmd[i]);
368 printf("\n");
370 #endif
372 if (r->req.cmd.xfer == 0) {
373 if (r->buf != NULL)
374 qemu_free(r->buf);
375 r->buflen = 0;
376 r->buf = NULL;
377 ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);
378 if (ret == -1) {
379 scsi_command_complete(r, -EINVAL);
380 return 0;
382 return 0;
385 if (r->buflen != r->req.cmd.xfer) {
386 if (r->buf != NULL)
387 qemu_free(r->buf);
388 r->buf = qemu_malloc(r->req.cmd.xfer);
389 r->buflen = r->req.cmd.xfer;
392 memset(r->buf, 0, r->buflen);
393 r->len = r->req.cmd.xfer;
394 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
395 r->len = 0;
396 return -r->req.cmd.xfer;
399 return r->req.cmd.xfer;
402 static int get_blocksize(BlockDriverState *bdrv)
404 uint8_t cmd[10];
405 uint8_t buf[8];
406 uint8_t sensebuf[8];
407 sg_io_hdr_t io_header;
408 int ret;
410 memset(cmd, 0, sizeof(cmd));
411 memset(buf, 0, sizeof(buf));
412 cmd[0] = READ_CAPACITY;
414 memset(&io_header, 0, sizeof(io_header));
415 io_header.interface_id = 'S';
416 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
417 io_header.dxfer_len = sizeof(buf);
418 io_header.dxferp = buf;
419 io_header.cmdp = cmd;
420 io_header.cmd_len = sizeof(cmd);
421 io_header.mx_sb_len = sizeof(sensebuf);
422 io_header.sbp = sensebuf;
423 io_header.timeout = 6000; /* XXX */
425 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
426 if (ret < 0)
427 return -1;
429 return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
432 static int get_stream_blocksize(BlockDriverState *bdrv)
434 uint8_t cmd[6];
435 uint8_t buf[12];
436 uint8_t sensebuf[8];
437 sg_io_hdr_t io_header;
438 int ret;
440 memset(cmd, 0, sizeof(cmd));
441 memset(buf, 0, sizeof(buf));
442 cmd[0] = MODE_SENSE;
443 cmd[4] = sizeof(buf);
445 memset(&io_header, 0, sizeof(io_header));
446 io_header.interface_id = 'S';
447 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
448 io_header.dxfer_len = sizeof(buf);
449 io_header.dxferp = buf;
450 io_header.cmdp = cmd;
451 io_header.cmd_len = sizeof(cmd);
452 io_header.mx_sb_len = sizeof(sensebuf);
453 io_header.sbp = sensebuf;
454 io_header.timeout = 6000; /* XXX */
456 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
457 if (ret < 0)
458 return -1;
460 return (buf[9] << 16) | (buf[10] << 8) | buf[11];
463 static void scsi_generic_purge_requests(SCSIGenericState *s)
465 SCSIGenericReq *r;
467 while (!QTAILQ_EMPTY(&s->qdev.requests)) {
468 r = DO_UPCAST(SCSIGenericReq, req, QTAILQ_FIRST(&s->qdev.requests));
469 if (r->req.aiocb) {
470 bdrv_aio_cancel(r->req.aiocb);
472 scsi_remove_request(r);
476 static void scsi_generic_reset(DeviceState *dev)
478 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev.qdev, dev);
480 scsi_generic_purge_requests(s);
483 static void scsi_destroy(SCSIDevice *d)
485 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
487 scsi_generic_purge_requests(s);
488 blockdev_mark_auto_del(s->qdev.conf.bs);
491 static int scsi_generic_initfn(SCSIDevice *dev)
493 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
494 int sg_version;
495 struct sg_scsi_id scsiid;
497 if (!s->qdev.conf.bs) {
498 error_report("scsi-generic: drive property not set");
499 return -1;
501 s->bs = s->qdev.conf.bs;
503 /* check we are really using a /dev/sg* file */
504 if (!bdrv_is_sg(s->bs)) {
505 error_report("scsi-generic: not /dev/sg*");
506 return -1;
509 if (bdrv_get_on_error(s->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
510 error_report("Device doesn't support drive option werror");
511 return -1;
513 if (bdrv_get_on_error(s->bs, 1) != BLOCK_ERR_REPORT) {
514 error_report("Device doesn't support drive option rerror");
515 return -1;
518 /* check we are using a driver managing SG_IO (version 3 and after */
519 if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
520 sg_version < 30000) {
521 error_report("scsi-generic: scsi generic interface too old");
522 return -1;
525 /* get LUN of the /dev/sg? */
526 if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
527 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
528 return -1;
531 /* define device state */
532 s->lun = scsiid.lun;
533 DPRINTF("LUN %d\n", s->lun);
534 s->qdev.type = scsiid.scsi_type;
535 DPRINTF("device type %d\n", s->qdev.type);
536 if (s->qdev.type == TYPE_TAPE) {
537 s->qdev.blocksize = get_stream_blocksize(s->bs);
538 if (s->qdev.blocksize == -1)
539 s->qdev.blocksize = 0;
540 } else {
541 s->qdev.blocksize = get_blocksize(s->bs);
542 /* removable media returns 0 if not present */
543 if (s->qdev.blocksize <= 0) {
544 if (s->qdev.type == TYPE_ROM || s->qdev.type == TYPE_WORM)
545 s->qdev.blocksize = 2048;
546 else
547 s->qdev.blocksize = 512;
550 DPRINTF("block size %d\n", s->qdev.blocksize);
551 s->driver_status = 0;
552 memset(s->sensebuf, 0, sizeof(s->sensebuf));
553 bdrv_set_removable(s->bs, 0);
554 return 0;
557 static SCSIDeviceInfo scsi_generic_info = {
558 .qdev.name = "scsi-generic",
559 .qdev.desc = "pass through generic scsi device (/dev/sg*)",
560 .qdev.size = sizeof(SCSIGenericState),
561 .qdev.reset = scsi_generic_reset,
562 .init = scsi_generic_initfn,
563 .destroy = scsi_destroy,
564 .send_command = scsi_send_command,
565 .read_data = scsi_read_data,
566 .write_data = scsi_write_data,
567 .cancel_io = scsi_cancel_io,
568 .get_buf = scsi_get_buf,
569 .qdev.props = (Property[]) {
570 DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf),
571 DEFINE_PROP_END_OF_LIST(),
575 static void scsi_generic_register_devices(void)
577 scsi_qdev_register(&scsi_generic_info);
579 device_init(scsi_generic_register_devices)
581 #endif /* __linux__ */