Support PCI based option rom loading
[qemu/aliguori-queue.git] / hw / scsi-generic.c
blobf60ad96d7924530f62b9016d54dcd4b8b2d40ede
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 "block.h"
16 #include "scsi.h"
18 #ifdef __linux__
20 //#define DEBUG_SCSI
22 #ifdef DEBUG_SCSI
23 #define DPRINTF(fmt, ...) \
24 do { printf("scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
25 #else
26 #define DPRINTF(fmt, ...) do {} while(0)
27 #endif
29 #define BADF(fmt, ...) \
30 do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
32 #include <stdio.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <unistd.h>
36 #include <scsi/sg.h>
37 #include "scsi-defs.h"
39 #define SCSI_SENSE_BUF_SIZE 96
41 #define SG_ERR_DRIVER_TIMEOUT 0x06
42 #define SG_ERR_DRIVER_SENSE 0x08
44 #ifndef MAX_UINT
45 #define MAX_UINT ((unsigned int)-1)
46 #endif
48 typedef struct SCSIGenericState SCSIGenericState;
50 typedef struct SCSIGenericReq {
51 SCSIRequest req;
52 uint8_t *buf;
53 int buflen;
54 int len;
55 sg_io_hdr_t io_header;
56 } SCSIGenericReq;
58 struct SCSIGenericState
60 SCSIDevice qdev;
61 int lun;
62 int driver_status;
63 uint8_t sensebuf[SCSI_SENSE_BUF_SIZE];
64 uint8_t senselen;
67 static SCSIGenericReq *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
69 SCSIRequest *req;
71 req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun);
72 return DO_UPCAST(SCSIGenericReq, req, req);
75 static void scsi_remove_request(SCSIGenericReq *r)
77 qemu_free(r->buf);
78 scsi_req_free(&r->req);
81 static SCSIGenericReq *scsi_find_request(SCSIGenericState *s, uint32_t tag)
83 return DO_UPCAST(SCSIGenericReq, req, scsi_req_find(&s->qdev, tag));
86 /* Helper function for command completion. */
87 static void scsi_command_complete(void *opaque, int ret)
89 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
90 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
92 s->driver_status = r->io_header.driver_status;
93 if (s->driver_status & SG_ERR_DRIVER_SENSE)
94 s->senselen = r->io_header.sb_len_wr;
96 if (ret != 0)
97 r->req.status = BUSY << 1;
98 else {
99 if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
100 r->req.status = BUSY << 1;
101 BADF("Driver Timeout\n");
102 } else if (r->io_header.status)
103 r->req.status = r->io_header.status;
104 else if (s->driver_status & SG_ERR_DRIVER_SENSE)
105 r->req.status = CHECK_CONDITION << 1;
106 else
107 r->req.status = GOOD << 1;
109 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
110 r, r->req.tag, r->req.status);
112 scsi_req_complete(&r->req);
113 scsi_remove_request(r);
116 /* Cancel a pending data transfer. */
117 static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
119 DPRINTF("scsi_cancel_io 0x%x\n", tag);
120 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
121 SCSIGenericReq *r;
122 DPRINTF("Cancel tag=0x%x\n", tag);
123 r = scsi_find_request(s, tag);
124 if (r) {
125 if (r->req.aiocb)
126 bdrv_aio_cancel(r->req.aiocb);
127 r->req.aiocb = NULL;
128 scsi_remove_request(r);
132 static int execute_command(BlockDriverState *bdrv,
133 SCSIGenericReq *r, int direction,
134 BlockDriverCompletionFunc *complete)
136 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
138 r->io_header.interface_id = 'S';
139 r->io_header.dxfer_direction = direction;
140 r->io_header.dxferp = r->buf;
141 r->io_header.dxfer_len = r->buflen;
142 r->io_header.cmdp = r->req.cmd.buf;
143 r->io_header.cmd_len = r->req.cmd.len;
144 r->io_header.mx_sb_len = sizeof(s->sensebuf);
145 r->io_header.sbp = s->sensebuf;
146 r->io_header.timeout = MAX_UINT;
147 r->io_header.usr_ptr = r;
148 r->io_header.flags |= SG_FLAG_DIRECT_IO;
150 r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
151 if (r->req.aiocb == NULL) {
152 BADF("execute_command: read failed !\n");
153 return -1;
156 return 0;
159 static void scsi_read_complete(void * opaque, int ret)
161 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
162 int len;
164 if (ret) {
165 DPRINTF("IO error\n");
166 scsi_command_complete(r, ret);
167 return;
169 len = r->io_header.dxfer_len - r->io_header.resid;
170 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
172 r->len = -1;
173 r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, len);
174 if (len == 0)
175 scsi_command_complete(r, 0);
178 /* Read more data from scsi device into buffer. */
179 static void scsi_read_data(SCSIDevice *d, uint32_t tag)
181 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
182 SCSIGenericReq *r;
183 int ret;
185 DPRINTF("scsi_read_data 0x%x\n", tag);
186 r = scsi_find_request(s, tag);
187 if (!r) {
188 BADF("Bad read tag 0x%x\n", tag);
189 /* ??? This is the wrong error. */
190 scsi_command_complete(r, -EINVAL);
191 return;
194 if (r->len == -1) {
195 scsi_command_complete(r, 0);
196 return;
199 if (r->req.cmd.buf[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
201 s->senselen = MIN(r->len, s->senselen);
202 memcpy(r->buf, s->sensebuf, s->senselen);
203 r->io_header.driver_status = 0;
204 r->io_header.status = 0;
205 r->io_header.dxfer_len = s->senselen;
206 r->len = -1;
207 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, s->senselen);
208 DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
209 r->buf[0], r->buf[1], r->buf[2], r->buf[3],
210 r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
211 r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, s->senselen);
212 return;
215 ret = execute_command(s->qdev.dinfo->bdrv, r, SG_DXFER_FROM_DEV, scsi_read_complete);
216 if (ret == -1) {
217 scsi_command_complete(r, -EINVAL);
218 return;
222 static void scsi_write_complete(void * opaque, int ret)
224 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
225 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
227 DPRINTF("scsi_write_complete() ret = %d\n", ret);
228 if (ret) {
229 DPRINTF("IO error\n");
230 scsi_command_complete(r, ret);
231 return;
234 if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
235 s->qdev.type == TYPE_TAPE) {
236 s->qdev.blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
237 DPRINTF("block size %d\n", s->blocksize);
240 scsi_command_complete(r, ret);
243 /* Write data to a scsi device. Returns nonzero on failure.
244 The transfer may complete asynchronously. */
245 static int scsi_write_data(SCSIDevice *d, uint32_t tag)
247 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
248 SCSIGenericReq *r;
249 int ret;
251 DPRINTF("scsi_write_data 0x%x\n", tag);
252 r = scsi_find_request(s, tag);
253 if (!r) {
254 BADF("Bad write tag 0x%x\n", tag);
255 /* ??? This is the wrong error. */
256 scsi_command_complete(r, -EINVAL);
257 return 0;
260 if (r->len == 0) {
261 r->len = r->buflen;
262 r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, r->len);
263 return 0;
266 ret = execute_command(s->qdev.dinfo->bdrv, r, SG_DXFER_TO_DEV, scsi_write_complete);
267 if (ret == -1) {
268 scsi_command_complete(r, -EINVAL);
269 return 1;
272 return 0;
275 /* Return a pointer to the data buffer. */
276 static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
278 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
279 SCSIGenericReq *r;
280 r = scsi_find_request(s, tag);
281 if (!r) {
282 BADF("Bad buffer tag 0x%x\n", tag);
283 return NULL;
285 return r->buf;
288 static void scsi_req_fixup(SCSIRequest *req)
290 switch(req->cmd.buf[0]) {
291 case WRITE_10:
292 req->cmd.buf[1] &= ~0x08; /* disable FUA */
293 break;
294 case READ_10:
295 req->cmd.buf[1] &= ~0x08; /* disable FUA */
296 break;
297 case REWIND:
298 case START_STOP:
299 if (req->dev->type == TYPE_TAPE) {
300 /* force IMMED, otherwise qemu waits end of command */
301 req->cmd.buf[1] = 0x01;
303 break;
307 /* Execute a scsi command. Returns the length of the data expected by the
308 command. This will be Positive for data transfers from the device
309 (eg. disk reads), negative for transfers to the device (eg. disk writes),
310 and zero if the command does not transfer any data. */
312 static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
313 uint8_t *cmd, int lun)
315 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
316 SCSIGenericReq *r;
317 SCSIBus *bus;
318 int ret;
320 if (cmd[0] != REQUEST_SENSE &&
321 (lun != s->lun || (cmd[1] >> 5) != s->lun)) {
322 DPRINTF("Unimplemented LUN %d\n", lun ? lun : cmd[1] >> 5);
324 s->sensebuf[0] = 0x70;
325 s->sensebuf[1] = 0x00;
326 s->sensebuf[2] = ILLEGAL_REQUEST;
327 s->sensebuf[3] = 0x00;
328 s->sensebuf[4] = 0x00;
329 s->sensebuf[5] = 0x00;
330 s->sensebuf[6] = 0x00;
331 s->senselen = 7;
332 s->driver_status = SG_ERR_DRIVER_SENSE;
333 bus = scsi_bus_from_device(d);
334 bus->complete(bus, SCSI_REASON_DONE, tag, CHECK_CONDITION << 1);
335 return 0;
338 r = scsi_find_request(s, tag);
339 if (r) {
340 BADF("Tag 0x%x already in use %p\n", tag, r);
341 scsi_cancel_io(d, tag);
343 r = scsi_new_request(d, tag, lun);
345 if (-1 == scsi_req_parse(&r->req, cmd)) {
346 BADF("Unsupported command length, command %x\n", cmd[0]);
347 scsi_remove_request(r);
348 return 0;
350 scsi_req_fixup(&r->req);
352 DPRINTF("Command: lun=%d tag=0x%x data=0x%02x len %d\n", lun, tag,
353 cmd[0], r->req.cmd.xfer);
355 if (r->req.cmd.xfer == 0) {
356 if (r->buf != NULL)
357 qemu_free(r->buf);
358 r->buflen = 0;
359 r->buf = NULL;
360 ret = execute_command(s->qdev.dinfo->bdrv, r, SG_DXFER_NONE, scsi_command_complete);
361 if (ret == -1) {
362 scsi_command_complete(r, -EINVAL);
363 return 0;
365 return 0;
368 if (r->buflen != r->req.cmd.xfer) {
369 if (r->buf != NULL)
370 qemu_free(r->buf);
371 r->buf = qemu_malloc(r->req.cmd.xfer);
372 r->buflen = r->req.cmd.xfer;
375 memset(r->buf, 0, r->buflen);
376 r->len = r->req.cmd.xfer;
377 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
378 r->len = 0;
379 return -r->req.cmd.xfer;
382 return r->req.cmd.xfer;
385 static int get_blocksize(BlockDriverState *bdrv)
387 uint8_t cmd[10];
388 uint8_t buf[8];
389 uint8_t sensebuf[8];
390 sg_io_hdr_t io_header;
391 int ret;
393 memset(cmd, 0, sizeof(cmd));
394 memset(buf, 0, sizeof(buf));
395 cmd[0] = READ_CAPACITY;
397 memset(&io_header, 0, sizeof(io_header));
398 io_header.interface_id = 'S';
399 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
400 io_header.dxfer_len = sizeof(buf);
401 io_header.dxferp = buf;
402 io_header.cmdp = cmd;
403 io_header.cmd_len = sizeof(cmd);
404 io_header.mx_sb_len = sizeof(sensebuf);
405 io_header.sbp = sensebuf;
406 io_header.timeout = 6000; /* XXX */
408 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
409 if (ret < 0)
410 return -1;
412 return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
415 static int get_stream_blocksize(BlockDriverState *bdrv)
417 uint8_t cmd[6];
418 uint8_t buf[12];
419 uint8_t sensebuf[8];
420 sg_io_hdr_t io_header;
421 int ret;
423 memset(cmd, 0, sizeof(cmd));
424 memset(buf, 0, sizeof(buf));
425 cmd[0] = MODE_SENSE;
426 cmd[4] = sizeof(buf);
428 memset(&io_header, 0, sizeof(io_header));
429 io_header.interface_id = 'S';
430 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
431 io_header.dxfer_len = sizeof(buf);
432 io_header.dxferp = buf;
433 io_header.cmdp = cmd;
434 io_header.cmd_len = sizeof(cmd);
435 io_header.mx_sb_len = sizeof(sensebuf);
436 io_header.sbp = sensebuf;
437 io_header.timeout = 6000; /* XXX */
439 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
440 if (ret < 0)
441 return -1;
443 return (buf[9] << 16) | (buf[10] << 8) | buf[11];
446 static void scsi_destroy(SCSIDevice *d)
448 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
449 SCSIGenericReq *r;
451 while (!QTAILQ_EMPTY(&s->qdev.requests)) {
452 r = DO_UPCAST(SCSIGenericReq, req, QTAILQ_FIRST(&s->qdev.requests));
453 scsi_remove_request(r);
455 drive_uninit(s->qdev.dinfo);
458 static int scsi_generic_initfn(SCSIDevice *dev)
460 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
461 int sg_version;
462 struct sg_scsi_id scsiid;
464 if (!s->qdev.dinfo || !s->qdev.dinfo->bdrv) {
465 qemu_error("scsi-generic: drive property not set\n");
466 return -1;
469 /* check we are really using a /dev/sg* file */
470 if (!bdrv_is_sg(s->qdev.dinfo->bdrv)) {
471 qemu_error("scsi-generic: not /dev/sg*\n");
472 return -1;
475 /* check we are using a driver managing SG_IO (version 3 and after */
476 if (bdrv_ioctl(s->qdev.dinfo->bdrv, SG_GET_VERSION_NUM, &sg_version) < 0 ||
477 sg_version < 30000) {
478 qemu_error("scsi-generic: scsi generic interface too old\n");
479 return -1;
482 /* get LUN of the /dev/sg? */
483 if (bdrv_ioctl(s->qdev.dinfo->bdrv, SG_GET_SCSI_ID, &scsiid)) {
484 qemu_error("scsi-generic: SG_GET_SCSI_ID ioctl failed\n");
485 return -1;
488 /* define device state */
489 s->lun = scsiid.lun;
490 DPRINTF("LUN %d\n", s->lun);
491 s->qdev.type = scsiid.scsi_type;
492 DPRINTF("device type %d\n", s->qdev.type);
493 if (s->qdev.type == TYPE_TAPE) {
494 s->qdev.blocksize = get_stream_blocksize(s->qdev.dinfo->bdrv);
495 if (s->qdev.blocksize == -1)
496 s->qdev.blocksize = 0;
497 } else {
498 s->qdev.blocksize = get_blocksize(s->qdev.dinfo->bdrv);
499 /* removable media returns 0 if not present */
500 if (s->qdev.blocksize <= 0) {
501 if (s->qdev.type == TYPE_ROM || s->qdev.type == TYPE_WORM)
502 s->qdev.blocksize = 2048;
503 else
504 s->qdev.blocksize = 512;
507 DPRINTF("block size %d\n", s->qdev.blocksize);
508 s->driver_status = 0;
509 memset(s->sensebuf, 0, sizeof(s->sensebuf));
510 return 0;
513 static SCSIDeviceInfo scsi_generic_info = {
514 .qdev.name = "scsi-generic",
515 .qdev.desc = "pass through generic scsi device (/dev/sg*)",
516 .qdev.size = sizeof(SCSIGenericState),
517 .init = scsi_generic_initfn,
518 .destroy = scsi_destroy,
519 .send_command = scsi_send_command,
520 .read_data = scsi_read_data,
521 .write_data = scsi_write_data,
522 .cancel_io = scsi_cancel_io,
523 .get_buf = scsi_get_buf,
524 .qdev.props = (Property[]) {
525 DEFINE_PROP_DRIVE("drive", SCSIGenericState, qdev.dinfo),
526 DEFINE_PROP_END_OF_LIST(),
530 static void scsi_generic_register_devices(void)
532 scsi_qdev_register(&scsi_generic_info);
534 device_init(scsi_generic_register_devices)
536 #endif /* __linux__ */