hw: Convert from BlockDriverState to BlockBackend, mostly
[qemu.git] / hw / scsi / 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 <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_unrealize(SCSIDevice *s, Error **errp)
372 {
373     scsi_device_purge_requests(s, SENSE_CODE(NO_SENSE));
374     blockdev_mark_auto_del(s->conf.blk);
375 }
376
377 static void scsi_generic_realize(SCSIDevice *s, Error **errp)
378 {
379     int rc;
380     int sg_version;
381     struct sg_scsi_id scsiid;
382
383     if (!s->conf.blk) {
384         error_setg(errp, "drive property not set");
385         return;
386     }
387
388     if (blk_get_on_error(s->conf.blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
389         error_setg(errp, "Device doesn't support drive option werror");
390         return;
391     }
392     if (blk_get_on_error(s->conf.blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
393         error_setg(errp, "Device doesn't support drive option rerror");
394         return;
395     }
396
397     /* check we are using a driver managing SG_IO (version 3 and after */
398     rc = blk_ioctl(s->conf.blk, SG_GET_VERSION_NUM, &sg_version);
399     if (rc < 0) {
400         error_setg(errp, "cannot get SG_IO version number: %s.  "
401                          "Is this a SCSI device?",
402                          strerror(-rc));
403         return;
404     }
405     if (sg_version < 30000) {
406         error_setg(errp, "scsi generic interface too old");
407         return;
408     }
409
410     /* get LUN of the /dev/sg? */
411     if (blk_ioctl(s->conf.blk, SG_GET_SCSI_ID, &scsiid)) {
412         error_setg(errp, "SG_GET_SCSI_ID ioctl failed");
413         return;
414     }
415
416     /* define device state */
417     s->type = scsiid.scsi_type;
418     DPRINTF("device type %d\n", s->type);
419
420     switch (s->type) {
421     case TYPE_TAPE:
422         s->blocksize = get_stream_blocksize(s->conf.blk);
423         if (s->blocksize == -1) {
424             s->blocksize = 0;
425         }
426         break;
427
428         /* Make a guess for block devices, we'll fix it when the guest sends.
429          * READ CAPACITY.  If they don't, they likely would assume these sizes
430          * anyway. (TODO: they could also send MODE SENSE).
431          */
432     case TYPE_ROM:
433     case TYPE_WORM:
434         s->blocksize = 2048;
435         break;
436     default:
437         s->blocksize = 512;
438         break;
439     }
440
441     DPRINTF("block size %d\n", s->blocksize);
442 }
443
444 const SCSIReqOps scsi_generic_req_ops = {
445     .size         = sizeof(SCSIGenericReq),
446     .free_req     = scsi_free_request,
447     .send_command = scsi_send_command,
448     .read_data    = scsi_read_data,
449     .write_data   = scsi_write_data,
450     .get_buf      = scsi_get_buf,
451     .load_request = scsi_generic_load_request,
452     .save_request = scsi_generic_save_request,
453 };
454
455 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
456                                      uint8_t *buf, void *hba_private)
457 {
458     SCSIRequest *req;
459
460     req = scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
461     return req;
462 }
463
464 static Property scsi_generic_properties[] = {
465     DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.blk),
466     DEFINE_PROP_END_OF_LIST(),
467 };
468
469 static int scsi_generic_parse_cdb(SCSIDevice *dev, SCSICommand *cmd,
470                                   uint8_t *buf, void *hba_private)
471 {
472     return scsi_bus_parse_cdb(dev, cmd, buf, hba_private);
473 }
474
475 static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
476 {
477     DeviceClass *dc = DEVICE_CLASS(klass);
478     SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
479
480     sc->realize      = scsi_generic_realize;
481     sc->unrealize    = scsi_unrealize;
482     sc->alloc_req    = scsi_new_request;
483     sc->parse_cdb    = scsi_generic_parse_cdb;
484     dc->fw_name = "disk";
485     dc->desc = "pass through generic scsi device (/dev/sg*)";
486     dc->reset = scsi_generic_reset;
487     dc->props = scsi_generic_properties;
488     dc->vmsd  = &vmstate_scsi_device;
489 }
490
491 static const TypeInfo scsi_generic_info = {
492     .name          = "scsi-generic",
493     .parent        = TYPE_SCSI_DEVICE,
494     .instance_size = sizeof(SCSIDevice),
495     .class_init    = scsi_generic_class_initfn,
496 };
497
498 static void scsi_generic_register_types(void)
499 {
500     type_register_static(&scsi_generic_info);
501 }
502
503 type_init(scsi_generic_register_types)
504
505 #endif /* __linux__ */
This page took 0.050736 seconds and 4 git commands to generate.