scsi: reference-count requests
[qemu/aliguori.git] / hw / scsi-generic.c
blob06e9dfea8b803f7593dabfe899d5a2eafadd2c99
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_free_request(SCSIRequest *req)
79 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
81 qemu_free(r->buf);
84 static SCSIGenericReq *scsi_find_request(SCSIGenericState *s, uint32_t tag)
86 return DO_UPCAST(SCSIGenericReq, req, scsi_req_find(&s->qdev, tag));
89 /* Helper function for command completion. */
90 static void scsi_command_complete(void *opaque, int ret)
92 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
93 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
95 r->req.aiocb = NULL;
96 s->driver_status = r->io_header.driver_status;
97 if (s->driver_status & SG_ERR_DRIVER_SENSE)
98 s->senselen = r->io_header.sb_len_wr;
100 if (ret != 0)
101 r->req.status = BUSY;
102 else {
103 if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
104 r->req.status = BUSY;
105 BADF("Driver Timeout\n");
106 } else if (r->io_header.status)
107 r->req.status = r->io_header.status;
108 else if (s->driver_status & SG_ERR_DRIVER_SENSE)
109 r->req.status = CHECK_CONDITION;
110 else
111 r->req.status = GOOD;
113 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
114 r, r->req.tag, r->req.status);
116 scsi_req_complete(&r->req);
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_req_dequeue(&r->req);
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;
326 int32_t len;
328 if (cmd[0] != REQUEST_SENSE &&
329 (lun != s->lun || (cmd[1] >> 5) != s->lun)) {
330 DPRINTF("Unimplemented LUN %d\n", lun ? lun : cmd[1] >> 5);
332 s->sensebuf[0] = 0x70;
333 s->sensebuf[1] = 0x00;
334 s->sensebuf[2] = ILLEGAL_REQUEST;
335 s->sensebuf[3] = 0x00;
336 s->sensebuf[4] = 0x00;
337 s->sensebuf[5] = 0x00;
338 s->sensebuf[6] = 0x00;
339 s->senselen = 7;
340 s->driver_status = SG_ERR_DRIVER_SENSE;
341 bus = scsi_bus_from_device(d);
342 bus->ops->complete(bus, SCSI_REASON_DONE, tag, CHECK_CONDITION);
343 return 0;
346 r = scsi_find_request(s, tag);
347 if (r) {
348 BADF("Tag 0x%x already in use %p\n", tag, r);
349 scsi_cancel_io(d, tag);
351 r = scsi_new_request(d, tag, lun);
353 if (-1 == scsi_req_parse(&r->req, cmd)) {
354 BADF("Unsupported command length, command %x\n", cmd[0]);
355 scsi_req_dequeue(&r->req);
356 scsi_req_unref(&r->req);
357 return 0;
359 scsi_req_fixup(&r->req);
361 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun, tag,
362 r->req.cmd.xfer, cmd[0]);
364 #ifdef DEBUG_SCSI
366 int i;
367 for (i = 1; i < r->req.cmd.len; i++) {
368 printf(" 0x%02x", cmd[i]);
370 printf("\n");
372 #endif
374 if (r->req.cmd.xfer == 0) {
375 if (r->buf != NULL)
376 qemu_free(r->buf);
377 r->buflen = 0;
378 r->buf = NULL;
379 ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);
380 if (ret == -1) {
381 scsi_command_complete(r, -EINVAL);
382 scsi_req_unref(&r->req);
383 return 0;
385 scsi_req_unref(&r->req);
386 return 0;
389 if (r->buflen != r->req.cmd.xfer) {
390 if (r->buf != NULL)
391 qemu_free(r->buf);
392 r->buf = qemu_malloc(r->req.cmd.xfer);
393 r->buflen = r->req.cmd.xfer;
396 memset(r->buf, 0, r->buflen);
397 r->len = r->req.cmd.xfer;
398 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
399 r->len = 0;
400 len = -r->req.cmd.xfer;
401 } else {
402 len = r->req.cmd.xfer;
405 scsi_req_unref(&r->req);
406 return len;
409 static int get_blocksize(BlockDriverState *bdrv)
411 uint8_t cmd[10];
412 uint8_t buf[8];
413 uint8_t sensebuf[8];
414 sg_io_hdr_t io_header;
415 int ret;
417 memset(cmd, 0, sizeof(cmd));
418 memset(buf, 0, sizeof(buf));
419 cmd[0] = READ_CAPACITY;
421 memset(&io_header, 0, sizeof(io_header));
422 io_header.interface_id = 'S';
423 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
424 io_header.dxfer_len = sizeof(buf);
425 io_header.dxferp = buf;
426 io_header.cmdp = cmd;
427 io_header.cmd_len = sizeof(cmd);
428 io_header.mx_sb_len = sizeof(sensebuf);
429 io_header.sbp = sensebuf;
430 io_header.timeout = 6000; /* XXX */
432 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
433 if (ret < 0)
434 return -1;
436 return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
439 static int get_stream_blocksize(BlockDriverState *bdrv)
441 uint8_t cmd[6];
442 uint8_t buf[12];
443 uint8_t sensebuf[8];
444 sg_io_hdr_t io_header;
445 int ret;
447 memset(cmd, 0, sizeof(cmd));
448 memset(buf, 0, sizeof(buf));
449 cmd[0] = MODE_SENSE;
450 cmd[4] = sizeof(buf);
452 memset(&io_header, 0, sizeof(io_header));
453 io_header.interface_id = 'S';
454 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
455 io_header.dxfer_len = sizeof(buf);
456 io_header.dxferp = buf;
457 io_header.cmdp = cmd;
458 io_header.cmd_len = sizeof(cmd);
459 io_header.mx_sb_len = sizeof(sensebuf);
460 io_header.sbp = sensebuf;
461 io_header.timeout = 6000; /* XXX */
463 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
464 if (ret < 0)
465 return -1;
467 return (buf[9] << 16) | (buf[10] << 8) | buf[11];
470 static void scsi_generic_purge_requests(SCSIGenericState *s)
472 SCSIGenericReq *r;
474 while (!QTAILQ_EMPTY(&s->qdev.requests)) {
475 r = DO_UPCAST(SCSIGenericReq, req, QTAILQ_FIRST(&s->qdev.requests));
476 if (r->req.aiocb) {
477 bdrv_aio_cancel(r->req.aiocb);
479 scsi_req_dequeue(&r->req);
483 static void scsi_generic_reset(DeviceState *dev)
485 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev.qdev, dev);
487 scsi_generic_purge_requests(s);
490 static void scsi_destroy(SCSIDevice *d)
492 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
494 scsi_generic_purge_requests(s);
495 blockdev_mark_auto_del(s->qdev.conf.bs);
498 static int scsi_generic_initfn(SCSIDevice *dev)
500 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
501 int sg_version;
502 struct sg_scsi_id scsiid;
504 if (!s->qdev.conf.bs) {
505 error_report("scsi-generic: drive property not set");
506 return -1;
508 s->bs = s->qdev.conf.bs;
510 /* check we are really using a /dev/sg* file */
511 if (!bdrv_is_sg(s->bs)) {
512 error_report("scsi-generic: not /dev/sg*");
513 return -1;
516 if (bdrv_get_on_error(s->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
517 error_report("Device doesn't support drive option werror");
518 return -1;
520 if (bdrv_get_on_error(s->bs, 1) != BLOCK_ERR_REPORT) {
521 error_report("Device doesn't support drive option rerror");
522 return -1;
525 /* check we are using a driver managing SG_IO (version 3 and after */
526 if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
527 sg_version < 30000) {
528 error_report("scsi-generic: scsi generic interface too old");
529 return -1;
532 /* get LUN of the /dev/sg? */
533 if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
534 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
535 return -1;
538 /* define device state */
539 s->lun = scsiid.lun;
540 DPRINTF("LUN %d\n", s->lun);
541 s->qdev.type = scsiid.scsi_type;
542 DPRINTF("device type %d\n", s->qdev.type);
543 if (s->qdev.type == TYPE_TAPE) {
544 s->qdev.blocksize = get_stream_blocksize(s->bs);
545 if (s->qdev.blocksize == -1)
546 s->qdev.blocksize = 0;
547 } else {
548 s->qdev.blocksize = get_blocksize(s->bs);
549 /* removable media returns 0 if not present */
550 if (s->qdev.blocksize <= 0) {
551 if (s->qdev.type == TYPE_ROM || s->qdev.type == TYPE_WORM)
552 s->qdev.blocksize = 2048;
553 else
554 s->qdev.blocksize = 512;
557 DPRINTF("block size %d\n", s->qdev.blocksize);
558 s->driver_status = 0;
559 memset(s->sensebuf, 0, sizeof(s->sensebuf));
560 bdrv_set_removable(s->bs, 0);
561 return 0;
564 static SCSIDeviceInfo scsi_generic_info = {
565 .qdev.name = "scsi-generic",
566 .qdev.desc = "pass through generic scsi device (/dev/sg*)",
567 .qdev.size = sizeof(SCSIGenericState),
568 .qdev.reset = scsi_generic_reset,
569 .init = scsi_generic_initfn,
570 .destroy = scsi_destroy,
571 .free_req = scsi_free_request,
572 .send_command = scsi_send_command,
573 .read_data = scsi_read_data,
574 .write_data = scsi_write_data,
575 .cancel_io = scsi_cancel_io,
576 .get_buf = scsi_get_buf,
577 .qdev.props = (Property[]) {
578 DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf),
579 DEFINE_PROP_END_OF_LIST(),
583 static void scsi_generic_register_devices(void)
585 scsi_qdev_register(&scsi_generic_info);
587 device_init(scsi_generic_register_devices)
589 #endif /* __linux__ */