]> Git Repo - qemu.git/blob - hw/scsi-generic.c
libcacard: add correct subdirectory dependencies
[qemu.git] / hw / scsi-generic.c
1 /*
2  * Generic SCSI Device support
3  *
4  * Copyright (c) 2007 Bull S.A.S.
5  * Based on code by Paul Brook
6  * Based on code by Fabrice Bellard
7  *
8  * Written by Laurent Vivier <[email protected]>
9  *
10  * This code is licenced under the LGPL.
11  *
12  */
13
14 #include "qemu-common.h"
15 #include "qemu-error.h"
16 #include "scsi.h"
17 #include "blockdev.h"
18
19 #ifdef __linux__
20
21 //#define DEBUG_SCSI
22
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
29
30 #define BADF(fmt, ...) \
31 do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
32
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"
39
40 #define SCSI_SENSE_BUF_SIZE 96
41
42 #define SG_ERR_DRIVER_TIMEOUT 0x06
43 #define SG_ERR_DRIVER_SENSE 0x08
44
45 #ifndef MAX_UINT
46 #define MAX_UINT ((unsigned int)-1)
47 #endif
48
49 typedef struct SCSIGenericState SCSIGenericState;
50
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;
58
59 struct SCSIGenericState
60 {
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;
67 };
68
69 static SCSIGenericReq *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
70 {
71     SCSIRequest *req;
72
73     req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun);
74     return DO_UPCAST(SCSIGenericReq, req, req);
75 }
76
77 static void scsi_remove_request(SCSIGenericReq *r)
78 {
79     qemu_free(r->buf);
80     scsi_req_free(&r->req);
81 }
82
83 static SCSIGenericReq *scsi_find_request(SCSIGenericState *s, uint32_t tag)
84 {
85     return DO_UPCAST(SCSIGenericReq, req, scsi_req_find(&s->qdev, tag));
86 }
87
88 /* Helper function for command completion.  */
89 static void scsi_command_complete(void *opaque, int ret)
90 {
91     SCSIGenericReq *r = (SCSIGenericReq *)opaque;
92     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
93
94     s->driver_status = r->io_header.driver_status;
95     if (s->driver_status & SG_ERR_DRIVER_SENSE)
96         s->senselen = r->io_header.sb_len_wr;
97
98     if (ret != 0)
99         r->req.status = BUSY;
100     else {
101         if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
102             r->req.status = BUSY;
103             BADF("Driver Timeout\n");
104         } else if (r->io_header.status)
105             r->req.status = r->io_header.status;
106         else if (s->driver_status & SG_ERR_DRIVER_SENSE)
107             r->req.status = CHECK_CONDITION;
108         else
109             r->req.status = GOOD;
110     }
111     DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
112             r, r->req.tag, r->req.status);
113
114     scsi_req_complete(&r->req);
115     scsi_remove_request(r);
116 }
117
118 /* Cancel a pending data transfer.  */
119 static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
120 {
121     DPRINTF("scsi_cancel_io 0x%x\n", tag);
122     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
123     SCSIGenericReq *r;
124     DPRINTF("Cancel tag=0x%x\n", tag);
125     r = scsi_find_request(s, tag);
126     if (r) {
127         if (r->req.aiocb)
128             bdrv_aio_cancel(r->req.aiocb);
129         r->req.aiocb = NULL;
130         scsi_remove_request(r);
131     }
132 }
133
134 static int execute_command(BlockDriverState *bdrv,
135                            SCSIGenericReq *r, int direction,
136                            BlockDriverCompletionFunc *complete)
137 {
138     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
139
140     r->io_header.interface_id = 'S';
141     r->io_header.dxfer_direction = direction;
142     r->io_header.dxferp = r->buf;
143     r->io_header.dxfer_len = r->buflen;
144     r->io_header.cmdp = r->req.cmd.buf;
145     r->io_header.cmd_len = r->req.cmd.len;
146     r->io_header.mx_sb_len = sizeof(s->sensebuf);
147     r->io_header.sbp = s->sensebuf;
148     r->io_header.timeout = MAX_UINT;
149     r->io_header.usr_ptr = r;
150     r->io_header.flags |= SG_FLAG_DIRECT_IO;
151
152     r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
153     if (r->req.aiocb == NULL) {
154         BADF("execute_command: read failed !\n");
155         return -1;
156     }
157
158     return 0;
159 }
160
161 static void scsi_read_complete(void * opaque, int ret)
162 {
163     SCSIGenericReq *r = (SCSIGenericReq *)opaque;
164     int len;
165
166     if (ret) {
167         DPRINTF("IO error ret %d\n", ret);
168         scsi_command_complete(r, ret);
169         return;
170     }
171     len = r->io_header.dxfer_len - r->io_header.resid;
172     DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
173
174     r->len = -1;
175     r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, len);
176     if (len == 0)
177         scsi_command_complete(r, 0);
178 }
179
180 /* Read more data from scsi device into buffer.  */
181 static void scsi_read_data(SCSIDevice *d, uint32_t tag)
182 {
183     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
184     SCSIGenericReq *r;
185     int ret;
186
187     DPRINTF("scsi_read_data 0x%x\n", tag);
188     r = scsi_find_request(s, tag);
189     if (!r) {
190         BADF("Bad read tag 0x%x\n", tag);
191         /* ??? This is the wrong error.  */
192         scsi_command_complete(r, -EINVAL);
193         return;
194     }
195
196     if (r->len == -1) {
197         scsi_command_complete(r, 0);
198         return;
199     }
200
201     if (r->req.cmd.buf[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
202     {
203         s->senselen = MIN(r->len, s->senselen);
204         memcpy(r->buf, s->sensebuf, s->senselen);
205         r->io_header.driver_status = 0;
206         r->io_header.status = 0;
207         r->io_header.dxfer_len  = s->senselen;
208         r->len = -1;
209         DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, s->senselen);
210         DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
211                 r->buf[0], r->buf[1], r->buf[2], r->buf[3],
212                 r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
213         r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, s->senselen);
214         return;
215     }
216
217     ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
218     if (ret == -1) {
219         scsi_command_complete(r, -EINVAL);
220         return;
221     }
222 }
223
224 static void scsi_write_complete(void * opaque, int ret)
225 {
226     SCSIGenericReq *r = (SCSIGenericReq *)opaque;
227     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
228
229     DPRINTF("scsi_write_complete() ret = %d\n", ret);
230     if (ret) {
231         DPRINTF("IO error\n");
232         scsi_command_complete(r, ret);
233         return;
234     }
235
236     if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
237         s->qdev.type == TYPE_TAPE) {
238         s->qdev.blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
239         DPRINTF("block size %d\n", s->qdev.blocksize);
240     }
241
242     scsi_command_complete(r, ret);
243 }
244
245 /* Write data to a scsi device.  Returns nonzero on failure.
246    The transfer may complete asynchronously.  */
247 static int scsi_write_data(SCSIDevice *d, uint32_t tag)
248 {
249     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
250     SCSIGenericReq *r;
251     int ret;
252
253     DPRINTF("scsi_write_data 0x%x\n", tag);
254     r = scsi_find_request(s, tag);
255     if (!r) {
256         BADF("Bad write tag 0x%x\n", tag);
257         /* ??? This is the wrong error.  */
258         scsi_command_complete(r, -EINVAL);
259         return 0;
260     }
261
262     if (r->len == 0) {
263         r->len = r->buflen;
264         r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, r->len);
265         return 0;
266     }
267
268     ret = execute_command(s->bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
269     if (ret == -1) {
270         scsi_command_complete(r, -EINVAL);
271         return 1;
272     }
273
274     return 0;
275 }
276
277 /* Return a pointer to the data buffer.  */
278 static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
279 {
280     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
281     SCSIGenericReq *r;
282     r = scsi_find_request(s, tag);
283     if (!r) {
284         BADF("Bad buffer tag 0x%x\n", tag);
285         return NULL;
286     }
287     return r->buf;
288 }
289
290 static void scsi_req_fixup(SCSIRequest *req)
291 {
292     switch(req->cmd.buf[0]) {
293     case WRITE_10:
294         req->cmd.buf[1] &= ~0x08;       /* disable FUA */
295         break;
296     case READ_10:
297         req->cmd.buf[1] &= ~0x08;       /* disable FUA */
298         break;
299     case REWIND:
300     case START_STOP:
301         if (req->dev->type == TYPE_TAPE) {
302             /* force IMMED, otherwise qemu waits end of command */
303             req->cmd.buf[1] = 0x01;
304         }
305         break;
306     }
307 }
308
309 /* Execute a scsi command.  Returns the length of the data expected by the
310    command.  This will be Positive for data transfers from the device
311    (eg. disk reads), negative for transfers to the device (eg. disk writes),
312    and zero if the command does not transfer any data.  */
313
314 static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
315                                  uint8_t *cmd, int lun)
316 {
317     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
318     SCSIGenericReq *r;
319     SCSIBus *bus;
320     int ret;
321
322     if (cmd[0] != REQUEST_SENSE &&
323         (lun != s->lun || (cmd[1] >> 5) != s->lun)) {
324         DPRINTF("Unimplemented LUN %d\n", lun ? lun : cmd[1] >> 5);
325
326         s->sensebuf[0] = 0x70;
327         s->sensebuf[1] = 0x00;
328         s->sensebuf[2] = ILLEGAL_REQUEST;
329         s->sensebuf[3] = 0x00;
330         s->sensebuf[4] = 0x00;
331         s->sensebuf[5] = 0x00;
332         s->sensebuf[6] = 0x00;
333         s->senselen = 7;
334         s->driver_status = SG_ERR_DRIVER_SENSE;
335         bus = scsi_bus_from_device(d);
336         bus->complete(bus, SCSI_REASON_DONE, tag, CHECK_CONDITION);
337         return 0;
338     }
339
340     r = scsi_find_request(s, tag);
341     if (r) {
342         BADF("Tag 0x%x already in use %p\n", tag, r);
343         scsi_cancel_io(d, tag);
344     }
345     r = scsi_new_request(d, tag, lun);
346
347     if (-1 == scsi_req_parse(&r->req, cmd)) {
348         BADF("Unsupported command length, command %x\n", cmd[0]);
349         scsi_remove_request(r);
350         return 0;
351     }
352     scsi_req_fixup(&r->req);
353
354     DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun, tag,
355             r->req.cmd.xfer, cmd[0]);
356
357 #ifdef DEBUG_SCSI
358     {
359         int i;
360         for (i = 1; i < r->req.cmd.len; i++) {
361             printf(" 0x%02x", cmd[i]);
362         }
363         printf("\n");
364     }
365 #endif
366
367     if (r->req.cmd.xfer == 0) {
368         if (r->buf != NULL)
369             qemu_free(r->buf);
370         r->buflen = 0;
371         r->buf = NULL;
372         ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);
373         if (ret == -1) {
374             scsi_command_complete(r, -EINVAL);
375             return 0;
376         }
377         return 0;
378     }
379
380     if (r->buflen != r->req.cmd.xfer) {
381         if (r->buf != NULL)
382             qemu_free(r->buf);
383         r->buf = qemu_malloc(r->req.cmd.xfer);
384         r->buflen = r->req.cmd.xfer;
385     }
386
387     memset(r->buf, 0, r->buflen);
388     r->len = r->req.cmd.xfer;
389     if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
390         r->len = 0;
391         return -r->req.cmd.xfer;
392     }
393
394     return r->req.cmd.xfer;
395 }
396
397 static int get_blocksize(BlockDriverState *bdrv)
398 {
399     uint8_t cmd[10];
400     uint8_t buf[8];
401     uint8_t sensebuf[8];
402     sg_io_hdr_t io_header;
403     int ret;
404
405     memset(cmd, 0, sizeof(cmd));
406     memset(buf, 0, sizeof(buf));
407     cmd[0] = READ_CAPACITY;
408
409     memset(&io_header, 0, sizeof(io_header));
410     io_header.interface_id = 'S';
411     io_header.dxfer_direction = SG_DXFER_FROM_DEV;
412     io_header.dxfer_len = sizeof(buf);
413     io_header.dxferp = buf;
414     io_header.cmdp = cmd;
415     io_header.cmd_len = sizeof(cmd);
416     io_header.mx_sb_len = sizeof(sensebuf);
417     io_header.sbp = sensebuf;
418     io_header.timeout = 6000; /* XXX */
419
420     ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
421     if (ret < 0)
422         return -1;
423
424     return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
425 }
426
427 static int get_stream_blocksize(BlockDriverState *bdrv)
428 {
429     uint8_t cmd[6];
430     uint8_t buf[12];
431     uint8_t sensebuf[8];
432     sg_io_hdr_t io_header;
433     int ret;
434
435     memset(cmd, 0, sizeof(cmd));
436     memset(buf, 0, sizeof(buf));
437     cmd[0] = MODE_SENSE;
438     cmd[4] = sizeof(buf);
439
440     memset(&io_header, 0, sizeof(io_header));
441     io_header.interface_id = 'S';
442     io_header.dxfer_direction = SG_DXFER_FROM_DEV;
443     io_header.dxfer_len = sizeof(buf);
444     io_header.dxferp = buf;
445     io_header.cmdp = cmd;
446     io_header.cmd_len = sizeof(cmd);
447     io_header.mx_sb_len = sizeof(sensebuf);
448     io_header.sbp = sensebuf;
449     io_header.timeout = 6000; /* XXX */
450
451     ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
452     if (ret < 0)
453         return -1;
454
455     return (buf[9] << 16) | (buf[10] << 8) | buf[11];
456 }
457
458 static void scsi_generic_purge_requests(SCSIGenericState *s)
459 {
460     SCSIGenericReq *r;
461
462     while (!QTAILQ_EMPTY(&s->qdev.requests)) {
463         r = DO_UPCAST(SCSIGenericReq, req, QTAILQ_FIRST(&s->qdev.requests));
464         if (r->req.aiocb) {
465             bdrv_aio_cancel(r->req.aiocb);
466         }
467         scsi_remove_request(r);
468     }
469 }
470
471 static void scsi_generic_reset(DeviceState *dev)
472 {
473     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev.qdev, dev);
474
475     scsi_generic_purge_requests(s);
476 }
477
478 static void scsi_destroy(SCSIDevice *d)
479 {
480     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
481
482     scsi_generic_purge_requests(s);
483     blockdev_mark_auto_del(s->qdev.conf.bs);
484 }
485
486 static int scsi_generic_initfn(SCSIDevice *dev)
487 {
488     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
489     int sg_version;
490     struct sg_scsi_id scsiid;
491
492     if (!s->qdev.conf.bs) {
493         error_report("scsi-generic: drive property not set");
494         return -1;
495     }
496     s->bs = s->qdev.conf.bs;
497
498     /* check we are really using a /dev/sg* file */
499     if (!bdrv_is_sg(s->bs)) {
500         error_report("scsi-generic: not /dev/sg*");
501         return -1;
502     }
503
504     if (bdrv_get_on_error(s->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
505         error_report("Device doesn't support drive option werror");
506         return -1;
507     }
508     if (bdrv_get_on_error(s->bs, 1) != BLOCK_ERR_REPORT) {
509         error_report("Device doesn't support drive option rerror");
510         return -1;
511     }
512
513     /* check we are using a driver managing SG_IO (version 3 and after */
514     if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
515         sg_version < 30000) {
516         error_report("scsi-generic: scsi generic interface too old");
517         return -1;
518     }
519
520     /* get LUN of the /dev/sg? */
521     if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
522         error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
523         return -1;
524     }
525
526     /* define device state */
527     s->lun = scsiid.lun;
528     DPRINTF("LUN %d\n", s->lun);
529     s->qdev.type = scsiid.scsi_type;
530     DPRINTF("device type %d\n", s->qdev.type);
531     if (s->qdev.type == TYPE_TAPE) {
532         s->qdev.blocksize = get_stream_blocksize(s->bs);
533         if (s->qdev.blocksize == -1)
534             s->qdev.blocksize = 0;
535     } else {
536         s->qdev.blocksize = get_blocksize(s->bs);
537         /* removable media returns 0 if not present */
538         if (s->qdev.blocksize <= 0) {
539             if (s->qdev.type == TYPE_ROM || s->qdev.type  == TYPE_WORM)
540                 s->qdev.blocksize = 2048;
541             else
542                 s->qdev.blocksize = 512;
543         }
544     }
545     DPRINTF("block size %d\n", s->qdev.blocksize);
546     s->driver_status = 0;
547     memset(s->sensebuf, 0, sizeof(s->sensebuf));
548     bdrv_set_removable(s->bs, 0);
549     return 0;
550 }
551
552 static SCSIDeviceInfo scsi_generic_info = {
553     .qdev.name    = "scsi-generic",
554     .qdev.desc    = "pass through generic scsi device (/dev/sg*)",
555     .qdev.size    = sizeof(SCSIGenericState),
556     .qdev.reset   = scsi_generic_reset,
557     .init         = scsi_generic_initfn,
558     .destroy      = scsi_destroy,
559     .send_command = scsi_send_command,
560     .read_data    = scsi_read_data,
561     .write_data   = scsi_write_data,
562     .cancel_io    = scsi_cancel_io,
563     .get_buf      = scsi_get_buf,
564     .qdev.props   = (Property[]) {
565         DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf),
566         DEFINE_PROP_END_OF_LIST(),
567     },
568 };
569
570 static void scsi_generic_register_devices(void)
571 {
572     scsi_qdev_register(&scsi_generic_info);
573 }
574 device_init(scsi_generic_register_devices)
575
576 #endif /* __linux__ */
This page took 0.057705 seconds and 4 git commands to generate.