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