]> Git Repo - qemu.git/blob - hw/scsi-generic.c
block/vdi: Allow disk images of size 0
[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 "block.h"
17 #include "scsi.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 << 1;
100     else {
101         if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
102             r->req.status = BUSY << 1;
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 << 1;
108         else
109             r->req.status = GOOD << 1;
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\n");
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->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 << 1);
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 data=0x%02x len %d\n", lun, tag,
355             cmd[0], r->req.cmd.xfer);
356
357     if (r->req.cmd.xfer == 0) {
358         if (r->buf != NULL)
359             qemu_free(r->buf);
360         r->buflen = 0;
361         r->buf = NULL;
362         ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);
363         if (ret == -1) {
364             scsi_command_complete(r, -EINVAL);
365             return 0;
366         }
367         return 0;
368     }
369
370     if (r->buflen != r->req.cmd.xfer) {
371         if (r->buf != NULL)
372             qemu_free(r->buf);
373         r->buf = qemu_malloc(r->req.cmd.xfer);
374         r->buflen = r->req.cmd.xfer;
375     }
376
377     memset(r->buf, 0, r->buflen);
378     r->len = r->req.cmd.xfer;
379     if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
380         r->len = 0;
381         return -r->req.cmd.xfer;
382     }
383
384     return r->req.cmd.xfer;
385 }
386
387 static int get_blocksize(BlockDriverState *bdrv)
388 {
389     uint8_t cmd[10];
390     uint8_t buf[8];
391     uint8_t sensebuf[8];
392     sg_io_hdr_t io_header;
393     int ret;
394
395     memset(cmd, 0, sizeof(cmd));
396     memset(buf, 0, sizeof(buf));
397     cmd[0] = READ_CAPACITY;
398
399     memset(&io_header, 0, sizeof(io_header));
400     io_header.interface_id = 'S';
401     io_header.dxfer_direction = SG_DXFER_FROM_DEV;
402     io_header.dxfer_len = sizeof(buf);
403     io_header.dxferp = buf;
404     io_header.cmdp = cmd;
405     io_header.cmd_len = sizeof(cmd);
406     io_header.mx_sb_len = sizeof(sensebuf);
407     io_header.sbp = sensebuf;
408     io_header.timeout = 6000; /* XXX */
409
410     ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
411     if (ret < 0)
412         return -1;
413
414     return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
415 }
416
417 static int get_stream_blocksize(BlockDriverState *bdrv)
418 {
419     uint8_t cmd[6];
420     uint8_t buf[12];
421     uint8_t sensebuf[8];
422     sg_io_hdr_t io_header;
423     int ret;
424
425     memset(cmd, 0, sizeof(cmd));
426     memset(buf, 0, sizeof(buf));
427     cmd[0] = MODE_SENSE;
428     cmd[4] = sizeof(buf);
429
430     memset(&io_header, 0, sizeof(io_header));
431     io_header.interface_id = 'S';
432     io_header.dxfer_direction = SG_DXFER_FROM_DEV;
433     io_header.dxfer_len = sizeof(buf);
434     io_header.dxferp = buf;
435     io_header.cmdp = cmd;
436     io_header.cmd_len = sizeof(cmd);
437     io_header.mx_sb_len = sizeof(sensebuf);
438     io_header.sbp = sensebuf;
439     io_header.timeout = 6000; /* XXX */
440
441     ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
442     if (ret < 0)
443         return -1;
444
445     return (buf[9] << 16) | (buf[10] << 8) | buf[11];
446 }
447
448 static void scsi_destroy(SCSIDevice *d)
449 {
450     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
451     SCSIGenericReq *r;
452
453     while (!QTAILQ_EMPTY(&s->qdev.requests)) {
454         r = DO_UPCAST(SCSIGenericReq, req, QTAILQ_FIRST(&s->qdev.requests));
455         scsi_remove_request(r);
456     }
457     drive_uninit(s->qdev.conf.dinfo);
458 }
459
460 static int scsi_generic_initfn(SCSIDevice *dev)
461 {
462     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
463     int sg_version;
464     struct sg_scsi_id scsiid;
465
466     if (!s->qdev.conf.dinfo || !s->qdev.conf.dinfo->bdrv) {
467         error_report("scsi-generic: drive property not set");
468         return -1;
469     }
470     s->bs = s->qdev.conf.dinfo->bdrv;
471
472     /* check we are really using a /dev/sg* file */
473     if (!bdrv_is_sg(s->bs)) {
474         error_report("scsi-generic: not /dev/sg*");
475         return -1;
476     }
477
478     /* check we are using a driver managing SG_IO (version 3 and after */
479     if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
480         sg_version < 30000) {
481         error_report("scsi-generic: scsi generic interface too old");
482         return -1;
483     }
484
485     /* get LUN of the /dev/sg? */
486     if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
487         error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
488         return -1;
489     }
490
491     /* define device state */
492     s->lun = scsiid.lun;
493     DPRINTF("LUN %d\n", s->lun);
494     s->qdev.type = scsiid.scsi_type;
495     DPRINTF("device type %d\n", s->qdev.type);
496     if (s->qdev.type == TYPE_TAPE) {
497         s->qdev.blocksize = get_stream_blocksize(s->bs);
498         if (s->qdev.blocksize == -1)
499             s->qdev.blocksize = 0;
500     } else {
501         s->qdev.blocksize = get_blocksize(s->bs);
502         /* removable media returns 0 if not present */
503         if (s->qdev.blocksize <= 0) {
504             if (s->qdev.type == TYPE_ROM || s->qdev.type  == TYPE_WORM)
505                 s->qdev.blocksize = 2048;
506             else
507                 s->qdev.blocksize = 512;
508         }
509     }
510     DPRINTF("block size %d\n", s->qdev.blocksize);
511     s->driver_status = 0;
512     memset(s->sensebuf, 0, sizeof(s->sensebuf));
513     return 0;
514 }
515
516 static SCSIDeviceInfo scsi_generic_info = {
517     .qdev.name    = "scsi-generic",
518     .qdev.desc    = "pass through generic scsi device (/dev/sg*)",
519     .qdev.size    = sizeof(SCSIGenericState),
520     .init         = scsi_generic_initfn,
521     .destroy      = scsi_destroy,
522     .send_command = scsi_send_command,
523     .read_data    = scsi_read_data,
524     .write_data   = scsi_write_data,
525     .cancel_io    = scsi_cancel_io,
526     .get_buf      = scsi_get_buf,
527     .qdev.props   = (Property[]) {
528         DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf),
529         DEFINE_PROP_END_OF_LIST(),
530     },
531 };
532
533 static void scsi_generic_register_devices(void)
534 {
535     scsi_qdev_register(&scsi_generic_info);
536 }
537 device_init(scsi_generic_register_devices)
538
539 #endif /* __linux__ */
This page took 0.055668 seconds and 4 git commands to generate.