xref: /illumos-kvm-cmd/hw/scsi-generic.c (revision 68396ea9)
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 <Laurent.Vivier@bull.net>
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 
scsi_new_request(SCSIDevice * d,uint32_t tag,uint32_t lun)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 
scsi_remove_request(SCSIGenericReq * r)77 static void scsi_remove_request(SCSIGenericReq *r)
78 {
79     qemu_free(r->buf);
80     scsi_req_free(&r->req);
81 }
82 
scsi_find_request(SCSIGenericState * s,uint32_t tag)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.  */
scsi_command_complete(void * opaque,int ret)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.  */
scsi_cancel_io(SCSIDevice * d,uint32_t tag)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 
execute_command(BlockDriverState * bdrv,SCSIGenericReq * r,int direction,BlockDriverCompletionFunc * complete)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 
scsi_read_complete(void * opaque,int ret)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.  */
scsi_read_data(SCSIDevice * d,uint32_t tag)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 
scsi_write_complete(void * opaque,int ret)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.  */
scsi_write_data(SCSIDevice * d,uint32_t tag)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.  */
scsi_get_buf(SCSIDevice * d,uint32_t tag)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 
scsi_req_fixup(SCSIRequest * req)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 
scsi_send_command(SCSIDevice * d,uint32_t tag,uint8_t * cmd,int lun)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 
get_blocksize(BlockDriverState * bdrv)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 
get_stream_blocksize(BlockDriverState * bdrv)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 
scsi_generic_purge_requests(SCSIGenericState * s)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 
scsi_generic_reset(DeviceState * dev)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 
scsi_destroy(SCSIDevice * d)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 
scsi_generic_initfn(SCSIDevice * dev)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 
scsi_generic_register_devices(void)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__ */
577