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