xref: /openbmc/qemu/hw/scsi/scsi-generic.c (revision d21de4d9)
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         if (r->buf != NULL)
302             g_free(r->buf);
303         r->buflen = 0;
304         r->buf = NULL;
305         /* The request is used as the AIO opaque value, so add a ref.  */
306         scsi_req_ref(&r->req);
307         ret = execute_command(s->conf.blk, r, SG_DXFER_NONE,
308                               scsi_command_complete);
309         if (ret < 0) {
310             scsi_command_complete(r, ret);
311             return 0;
312         }
313         return 0;
314     }
315 
316     if (r->buflen != r->req.cmd.xfer) {
317         if (r->buf != NULL)
318             g_free(r->buf);
319         r->buf = g_malloc(r->req.cmd.xfer);
320         r->buflen = r->req.cmd.xfer;
321     }
322 
323     memset(r->buf, 0, r->buflen);
324     r->len = r->req.cmd.xfer;
325     if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
326         r->len = 0;
327         return -r->req.cmd.xfer;
328     } else {
329         return r->req.cmd.xfer;
330     }
331 }
332 
333 static int get_stream_blocksize(BlockBackend *blk)
334 {
335     uint8_t cmd[6];
336     uint8_t buf[12];
337     uint8_t sensebuf[8];
338     sg_io_hdr_t io_header;
339     int ret;
340 
341     memset(cmd, 0, sizeof(cmd));
342     memset(buf, 0, sizeof(buf));
343     cmd[0] = MODE_SENSE;
344     cmd[4] = sizeof(buf);
345 
346     memset(&io_header, 0, sizeof(io_header));
347     io_header.interface_id = 'S';
348     io_header.dxfer_direction = SG_DXFER_FROM_DEV;
349     io_header.dxfer_len = sizeof(buf);
350     io_header.dxferp = buf;
351     io_header.cmdp = cmd;
352     io_header.cmd_len = sizeof(cmd);
353     io_header.mx_sb_len = sizeof(sensebuf);
354     io_header.sbp = sensebuf;
355     io_header.timeout = 6000; /* XXX */
356 
357     ret = blk_ioctl(blk, SG_IO, &io_header);
358     if (ret < 0 || io_header.driver_status || io_header.host_status) {
359         return -1;
360     }
361     return (buf[9] << 16) | (buf[10] << 8) | buf[11];
362 }
363 
364 static void scsi_generic_reset(DeviceState *dev)
365 {
366     SCSIDevice *s = SCSI_DEVICE(dev);
367 
368     scsi_device_purge_requests(s, SENSE_CODE(RESET));
369 }
370 
371 static void scsi_generic_realize(SCSIDevice *s, Error **errp)
372 {
373     int rc;
374     int sg_version;
375     struct sg_scsi_id scsiid;
376 
377     if (!s->conf.blk) {
378         error_setg(errp, "drive property not set");
379         return;
380     }
381 
382     if (blk_get_on_error(s->conf.blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
383         error_setg(errp, "Device doesn't support drive option werror");
384         return;
385     }
386     if (blk_get_on_error(s->conf.blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
387         error_setg(errp, "Device doesn't support drive option rerror");
388         return;
389     }
390 
391     /* check we are using a driver managing SG_IO (version 3 and after */
392     rc = blk_ioctl(s->conf.blk, SG_GET_VERSION_NUM, &sg_version);
393     if (rc < 0) {
394         error_setg(errp, "cannot get SG_IO version number: %s.  "
395                          "Is this a SCSI device?",
396                          strerror(-rc));
397         return;
398     }
399     if (sg_version < 30000) {
400         error_setg(errp, "scsi generic interface too old");
401         return;
402     }
403 
404     /* get LUN of the /dev/sg? */
405     if (blk_ioctl(s->conf.blk, SG_GET_SCSI_ID, &scsiid)) {
406         error_setg(errp, "SG_GET_SCSI_ID ioctl failed");
407         return;
408     }
409 
410     /* define device state */
411     s->type = scsiid.scsi_type;
412     DPRINTF("device type %d\n", s->type);
413 
414     switch (s->type) {
415     case TYPE_TAPE:
416         s->blocksize = get_stream_blocksize(s->conf.blk);
417         if (s->blocksize == -1) {
418             s->blocksize = 0;
419         }
420         break;
421 
422         /* Make a guess for block devices, we'll fix it when the guest sends.
423          * READ CAPACITY.  If they don't, they likely would assume these sizes
424          * anyway. (TODO: they could also send MODE SENSE).
425          */
426     case TYPE_ROM:
427     case TYPE_WORM:
428         s->blocksize = 2048;
429         break;
430     default:
431         s->blocksize = 512;
432         break;
433     }
434 
435     DPRINTF("block size %d\n", s->blocksize);
436 }
437 
438 const SCSIReqOps scsi_generic_req_ops = {
439     .size         = sizeof(SCSIGenericReq),
440     .free_req     = scsi_free_request,
441     .send_command = scsi_send_command,
442     .read_data    = scsi_read_data,
443     .write_data   = scsi_write_data,
444     .get_buf      = scsi_get_buf,
445     .load_request = scsi_generic_load_request,
446     .save_request = scsi_generic_save_request,
447 };
448 
449 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
450                                      uint8_t *buf, void *hba_private)
451 {
452     SCSIRequest *req;
453 
454     req = scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
455     return req;
456 }
457 
458 static Property scsi_generic_properties[] = {
459     DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.blk),
460     DEFINE_PROP_END_OF_LIST(),
461 };
462 
463 static int scsi_generic_parse_cdb(SCSIDevice *dev, SCSICommand *cmd,
464                                   uint8_t *buf, void *hba_private)
465 {
466     return scsi_bus_parse_cdb(dev, cmd, buf, hba_private);
467 }
468 
469 static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
470 {
471     DeviceClass *dc = DEVICE_CLASS(klass);
472     SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
473 
474     sc->realize      = scsi_generic_realize;
475     sc->alloc_req    = scsi_new_request;
476     sc->parse_cdb    = scsi_generic_parse_cdb;
477     dc->fw_name = "disk";
478     dc->desc = "pass through generic scsi device (/dev/sg*)";
479     dc->reset = scsi_generic_reset;
480     dc->props = scsi_generic_properties;
481     dc->vmsd  = &vmstate_scsi_device;
482 }
483 
484 static const TypeInfo scsi_generic_info = {
485     .name          = "scsi-generic",
486     .parent        = TYPE_SCSI_DEVICE,
487     .instance_size = sizeof(SCSIDevice),
488     .class_init    = scsi_generic_class_initfn,
489 };
490 
491 static void scsi_generic_register_types(void)
492 {
493     type_register_static(&scsi_generic_info);
494 }
495 
496 type_init(scsi_generic_register_types)
497 
498 #endif /* __linux__ */
499