xref: /openbmc/qemu/hw/scsi/scsi-generic.c (revision 461a2753)
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 licensed under the LGPL.
11  *
12  */
13 
14 #include "qemu-common.h"
15 #include "qemu/error-report.h"
16 #include "hw/scsi/scsi.h"
17 #include "sysemu/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 "block/scsi.h"
39 
40 #define SG_ERR_DRIVER_TIMEOUT  0x06
41 #define SG_ERR_DRIVER_SENSE    0x08
42 
43 #define SG_ERR_DID_OK          0x00
44 #define SG_ERR_DID_NO_CONNECT  0x01
45 #define SG_ERR_DID_BUS_BUSY    0x02
46 #define SG_ERR_DID_TIME_OUT    0x03
47 
48 #ifndef MAX_UINT
49 #define MAX_UINT ((unsigned int)-1)
50 #endif
51 
52 typedef struct SCSIGenericReq {
53     SCSIRequest req;
54     uint8_t *buf;
55     int buflen;
56     int len;
57     sg_io_hdr_t io_header;
58 } SCSIGenericReq;
59 
60 static void scsi_generic_save_request(QEMUFile *f, SCSIRequest *req)
61 {
62     SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
63 
64     qemu_put_sbe32s(f, &r->buflen);
65     if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
66         assert(!r->req.sg);
67         qemu_put_buffer(f, r->buf, r->req.cmd.xfer);
68     }
69 }
70 
71 static void scsi_generic_load_request(QEMUFile *f, SCSIRequest *req)
72 {
73     SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
74 
75     qemu_get_sbe32s(f, &r->buflen);
76     if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
77         assert(!r->req.sg);
78         qemu_get_buffer(f, r->buf, r->req.cmd.xfer);
79     }
80 }
81 
82 static void scsi_free_request(SCSIRequest *req)
83 {
84     SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
85 
86     g_free(r->buf);
87 }
88 
89 /* Helper function for command completion.  */
90 static void scsi_command_complete(void *opaque, int ret)
91 {
92     int status;
93     SCSIGenericReq *r = (SCSIGenericReq *)opaque;
94 
95     r->req.aiocb = NULL;
96     if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
97         r->req.sense_len = r->io_header.sb_len_wr;
98     }
99 
100     if (ret != 0) {
101         switch (ret) {
102         case -EDOM:
103             status = TASK_SET_FULL;
104             break;
105         case -ENOMEM:
106             status = CHECK_CONDITION;
107             scsi_req_build_sense(&r->req, SENSE_CODE(TARGET_FAILURE));
108             break;
109         default:
110             status = CHECK_CONDITION;
111             scsi_req_build_sense(&r->req, SENSE_CODE(IO_ERROR));
112             break;
113         }
114     } else {
115         if (r->io_header.host_status == SG_ERR_DID_NO_CONNECT ||
116             r->io_header.host_status == SG_ERR_DID_BUS_BUSY ||
117             r->io_header.host_status == SG_ERR_DID_TIME_OUT ||
118             (r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT)) {
119             status = BUSY;
120             BADF("Driver Timeout\n");
121         } else if (r->io_header.host_status) {
122             status = CHECK_CONDITION;
123             scsi_req_build_sense(&r->req, SENSE_CODE(I_T_NEXUS_LOSS));
124         } else if (r->io_header.status) {
125             status = r->io_header.status;
126         } else if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
127             status = CHECK_CONDITION;
128         } else {
129             status = GOOD;
130         }
131     }
132     DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
133             r, r->req.tag, status);
134 
135     scsi_req_complete(&r->req, status);
136     if (!r->req.io_canceled) {
137         scsi_req_unref(&r->req);
138     }
139 }
140 
141 /* Cancel a pending data transfer.  */
142 static void scsi_cancel_io(SCSIRequest *req)
143 {
144     SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
145 
146     DPRINTF("Cancel tag=0x%x\n", req->tag);
147     if (r->req.aiocb) {
148         bdrv_aio_cancel(r->req.aiocb);
149 
150         /* This reference was left in by scsi_*_data.  We take ownership of
151          * it independent of whether bdrv_aio_cancel completes the request
152          * or not.  */
153         scsi_req_unref(&r->req);
154     }
155     r->req.aiocb = NULL;
156 }
157 
158 static int execute_command(BlockDriverState *bdrv,
159                            SCSIGenericReq *r, int direction,
160 			   BlockDriverCompletionFunc *complete)
161 {
162     r->io_header.interface_id = 'S';
163     r->io_header.dxfer_direction = direction;
164     r->io_header.dxferp = r->buf;
165     r->io_header.dxfer_len = r->buflen;
166     r->io_header.cmdp = r->req.cmd.buf;
167     r->io_header.cmd_len = r->req.cmd.len;
168     r->io_header.mx_sb_len = sizeof(r->req.sense);
169     r->io_header.sbp = r->req.sense;
170     r->io_header.timeout = MAX_UINT;
171     r->io_header.usr_ptr = r;
172     r->io_header.flags |= SG_FLAG_DIRECT_IO;
173 
174     r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
175     if (r->req.aiocb == NULL) {
176         return -EIO;
177     }
178 
179     return 0;
180 }
181 
182 static void scsi_read_complete(void * opaque, int ret)
183 {
184     SCSIGenericReq *r = (SCSIGenericReq *)opaque;
185     SCSIDevice *s = r->req.dev;
186     int len;
187 
188     r->req.aiocb = NULL;
189     if (ret) {
190         DPRINTF("IO error ret %d\n", ret);
191         scsi_command_complete(r, ret);
192         return;
193     }
194     len = r->io_header.dxfer_len - r->io_header.resid;
195     DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
196 
197     r->len = -1;
198     if (len == 0) {
199         scsi_command_complete(r, 0);
200     } else {
201         /* Snoop READ CAPACITY output to set the blocksize.  */
202         if (r->req.cmd.buf[0] == READ_CAPACITY_10 &&
203             (ldl_be_p(&r->buf[0]) != 0xffffffffU || s->max_lba == 0)) {
204             s->blocksize = ldl_be_p(&r->buf[4]);
205             s->max_lba = ldl_be_p(&r->buf[0]) & 0xffffffffULL;
206         } else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 &&
207                    (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
208             s->blocksize = ldl_be_p(&r->buf[8]);
209             s->max_lba = ldq_be_p(&r->buf[0]);
210         }
211         bdrv_set_guest_block_size(s->conf.bs, s->blocksize);
212 
213         scsi_req_data(&r->req, len);
214         if (!r->req.io_canceled) {
215             scsi_req_unref(&r->req);
216         }
217     }
218 }
219 
220 /* Read more data from scsi device into buffer.  */
221 static void scsi_read_data(SCSIRequest *req)
222 {
223     SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
224     SCSIDevice *s = r->req.dev;
225     int ret;
226 
227     DPRINTF("scsi_read_data 0x%x\n", req->tag);
228 
229     /* The request is used as the AIO opaque value, so add a ref.  */
230     scsi_req_ref(&r->req);
231     if (r->len == -1) {
232         scsi_command_complete(r, 0);
233         return;
234     }
235 
236     ret = execute_command(s->conf.bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
237     if (ret < 0) {
238         scsi_command_complete(r, ret);
239     }
240 }
241 
242 static void scsi_write_complete(void * opaque, int ret)
243 {
244     SCSIGenericReq *r = (SCSIGenericReq *)opaque;
245     SCSIDevice *s = r->req.dev;
246 
247     DPRINTF("scsi_write_complete() ret = %d\n", ret);
248     r->req.aiocb = NULL;
249     if (ret) {
250         DPRINTF("IO error\n");
251         scsi_command_complete(r, ret);
252         return;
253     }
254 
255     if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
256         s->type == TYPE_TAPE) {
257         s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
258         DPRINTF("block size %d\n", s->blocksize);
259     }
260 
261     scsi_command_complete(r, ret);
262 }
263 
264 /* Write data to a scsi device.  Returns nonzero on failure.
265    The transfer may complete asynchronously.  */
266 static void scsi_write_data(SCSIRequest *req)
267 {
268     SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
269     SCSIDevice *s = r->req.dev;
270     int ret;
271 
272     DPRINTF("scsi_write_data 0x%x\n", req->tag);
273     if (r->len == 0) {
274         r->len = r->buflen;
275         scsi_req_data(&r->req, r->len);
276         return;
277     }
278 
279     /* The request is used as the AIO opaque value, so add a ref.  */
280     scsi_req_ref(&r->req);
281     ret = execute_command(s->conf.bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
282     if (ret < 0) {
283         scsi_command_complete(r, ret);
284     }
285 }
286 
287 /* Return a pointer to the data buffer.  */
288 static uint8_t *scsi_get_buf(SCSIRequest *req)
289 {
290     SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
291 
292     return r->buf;
293 }
294 
295 /* Execute a scsi command.  Returns the length of the data expected by the
296    command.  This will be Positive for data transfers from the device
297    (eg. disk reads), negative for transfers to the device (eg. disk writes),
298    and zero if the command does not transfer any data.  */
299 
300 static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
301 {
302     SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
303     SCSIDevice *s = r->req.dev;
304     int ret;
305 
306 #ifdef DEBUG_SCSI
307     {
308         int i;
309         for (i = 1; i < r->req.cmd.len; i++) {
310             printf(" 0x%02x", cmd[i]);
311         }
312         printf("\n");
313     }
314 #endif
315 
316     if (r->req.cmd.xfer == 0) {
317         if (r->buf != NULL)
318             g_free(r->buf);
319         r->buflen = 0;
320         r->buf = NULL;
321         /* The request is used as the AIO opaque value, so add a ref.  */
322         scsi_req_ref(&r->req);
323         ret = execute_command(s->conf.bs, r, SG_DXFER_NONE, scsi_command_complete);
324         if (ret < 0) {
325             scsi_command_complete(r, ret);
326             return 0;
327         }
328         return 0;
329     }
330 
331     if (r->buflen != r->req.cmd.xfer) {
332         if (r->buf != NULL)
333             g_free(r->buf);
334         r->buf = g_malloc(r->req.cmd.xfer);
335         r->buflen = r->req.cmd.xfer;
336     }
337 
338     memset(r->buf, 0, r->buflen);
339     r->len = r->req.cmd.xfer;
340     if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
341         r->len = 0;
342         return -r->req.cmd.xfer;
343     } else {
344         return r->req.cmd.xfer;
345     }
346 }
347 
348 static int get_stream_blocksize(BlockDriverState *bdrv)
349 {
350     uint8_t cmd[6];
351     uint8_t buf[12];
352     uint8_t sensebuf[8];
353     sg_io_hdr_t io_header;
354     int ret;
355 
356     memset(cmd, 0, sizeof(cmd));
357     memset(buf, 0, sizeof(buf));
358     cmd[0] = MODE_SENSE;
359     cmd[4] = sizeof(buf);
360 
361     memset(&io_header, 0, sizeof(io_header));
362     io_header.interface_id = 'S';
363     io_header.dxfer_direction = SG_DXFER_FROM_DEV;
364     io_header.dxfer_len = sizeof(buf);
365     io_header.dxferp = buf;
366     io_header.cmdp = cmd;
367     io_header.cmd_len = sizeof(cmd);
368     io_header.mx_sb_len = sizeof(sensebuf);
369     io_header.sbp = sensebuf;
370     io_header.timeout = 6000; /* XXX */
371 
372     ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
373     if (ret < 0 || io_header.driver_status || io_header.host_status) {
374         return -1;
375     }
376     return (buf[9] << 16) | (buf[10] << 8) | buf[11];
377 }
378 
379 static void scsi_generic_reset(DeviceState *dev)
380 {
381     SCSIDevice *s = SCSI_DEVICE(dev);
382 
383     scsi_device_purge_requests(s, SENSE_CODE(RESET));
384 }
385 
386 static void scsi_unrealize(SCSIDevice *s, Error **errp)
387 {
388     scsi_device_purge_requests(s, SENSE_CODE(NO_SENSE));
389     blockdev_mark_auto_del(s->conf.bs);
390 }
391 
392 static void scsi_generic_realize(SCSIDevice *s, Error **errp)
393 {
394     int rc;
395     int sg_version;
396     struct sg_scsi_id scsiid;
397 
398     if (!s->conf.bs) {
399         error_setg(errp, "drive property not set");
400         return;
401     }
402 
403     if (bdrv_get_on_error(s->conf.bs, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
404         error_setg(errp, "Device doesn't support drive option werror");
405         return;
406     }
407     if (bdrv_get_on_error(s->conf.bs, 1) != BLOCKDEV_ON_ERROR_REPORT) {
408         error_setg(errp, "Device doesn't support drive option rerror");
409         return;
410     }
411 
412     /* check we are using a driver managing SG_IO (version 3 and after */
413     rc = bdrv_ioctl(s->conf.bs, SG_GET_VERSION_NUM, &sg_version);
414     if (rc < 0) {
415         error_setg(errp, "cannot get SG_IO version number: %s.  "
416                          "Is this a SCSI device?",
417                          strerror(-rc));
418         return;
419     }
420     if (sg_version < 30000) {
421         error_setg(errp, "scsi generic interface too old");
422         return;
423     }
424 
425     /* get LUN of the /dev/sg? */
426     if (bdrv_ioctl(s->conf.bs, SG_GET_SCSI_ID, &scsiid)) {
427         error_setg(errp, "SG_GET_SCSI_ID ioctl failed");
428         return;
429     }
430 
431     /* define device state */
432     s->type = scsiid.scsi_type;
433     DPRINTF("device type %d\n", s->type);
434     if (s->type == TYPE_DISK || s->type == TYPE_ROM) {
435         add_boot_device_path(s->conf.bootindex, &s->qdev, NULL);
436     }
437 
438     switch (s->type) {
439     case TYPE_TAPE:
440         s->blocksize = get_stream_blocksize(s->conf.bs);
441         if (s->blocksize == -1) {
442             s->blocksize = 0;
443         }
444         break;
445 
446         /* Make a guess for block devices, we'll fix it when the guest sends.
447          * READ CAPACITY.  If they don't, they likely would assume these sizes
448          * anyway. (TODO: they could also send MODE SENSE).
449          */
450     case TYPE_ROM:
451     case TYPE_WORM:
452         s->blocksize = 2048;
453         break;
454     default:
455         s->blocksize = 512;
456         break;
457     }
458 
459     DPRINTF("block size %d\n", s->blocksize);
460 }
461 
462 const SCSIReqOps scsi_generic_req_ops = {
463     .size         = sizeof(SCSIGenericReq),
464     .free_req     = scsi_free_request,
465     .send_command = scsi_send_command,
466     .read_data    = scsi_read_data,
467     .write_data   = scsi_write_data,
468     .cancel_io    = scsi_cancel_io,
469     .get_buf      = scsi_get_buf,
470     .load_request = scsi_generic_load_request,
471     .save_request = scsi_generic_save_request,
472 };
473 
474 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
475                                      uint8_t *buf, void *hba_private)
476 {
477     SCSIRequest *req;
478 
479     req = scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
480     return req;
481 }
482 
483 static Property scsi_generic_properties[] = {
484     DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.bs),
485     DEFINE_PROP_INT32("bootindex", SCSIDevice, conf.bootindex, -1),
486     DEFINE_PROP_END_OF_LIST(),
487 };
488 
489 static int scsi_generic_parse_cdb(SCSIDevice *dev, SCSICommand *cmd,
490                                   uint8_t *buf, void *hba_private)
491 {
492     return scsi_bus_parse_cdb(dev, cmd, buf, hba_private);
493 }
494 
495 static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
496 {
497     DeviceClass *dc = DEVICE_CLASS(klass);
498     SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
499 
500     sc->realize      = scsi_generic_realize;
501     sc->unrealize    = scsi_unrealize;
502     sc->alloc_req    = scsi_new_request;
503     sc->parse_cdb    = scsi_generic_parse_cdb;
504     dc->fw_name = "disk";
505     dc->desc = "pass through generic scsi device (/dev/sg*)";
506     dc->reset = scsi_generic_reset;
507     dc->props = scsi_generic_properties;
508     dc->vmsd  = &vmstate_scsi_device;
509 }
510 
511 static const TypeInfo scsi_generic_info = {
512     .name          = "scsi-generic",
513     .parent        = TYPE_SCSI_DEVICE,
514     .instance_size = sizeof(SCSIDevice),
515     .class_init    = scsi_generic_class_initfn,
516 };
517 
518 static void scsi_generic_register_types(void)
519 {
520     type_register_static(&scsi_generic_info);
521 }
522 
523 type_init(scsi_generic_register_types)
524 
525 #endif /* __linux__ */
526