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