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