fix MSI injection on Xen
[qemu.git] / hw / scsi / scsi-generic.c
blob75a4127d3a688c98e5d034ff0403afbcc03e6b4d
1 /*
2 * Generic SCSI Device support
4 * Copyright (c) 2007 Bull S.A.S.
5 * Based on code by Paul Brook
6 * Based on code by Fabrice Bellard
8 * Written by Laurent Vivier <Laurent.Vivier@bull.net>
10 * This code is licensed under the LGPL.
14 #include "qemu/osdep.h"
15 #include "qemu-common.h"
16 #include "qemu/error-report.h"
17 #include "hw/scsi/scsi.h"
18 #include "sysemu/block-backend.h"
19 #include "sysemu/blockdev.h"
21 #ifdef __linux__
23 //#define DEBUG_SCSI
25 #ifdef DEBUG_SCSI
26 #define DPRINTF(fmt, ...) \
27 do { printf("scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
28 #else
29 #define DPRINTF(fmt, ...) do {} while(0)
30 #endif
32 #define BADF(fmt, ...) \
33 do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
35 #include <scsi/sg.h>
36 #include "block/scsi.h"
38 #define SG_ERR_DRIVER_TIMEOUT 0x06
39 #define SG_ERR_DRIVER_SENSE 0x08
41 #define SG_ERR_DID_OK 0x00
42 #define SG_ERR_DID_NO_CONNECT 0x01
43 #define SG_ERR_DID_BUS_BUSY 0x02
44 #define SG_ERR_DID_TIME_OUT 0x03
46 #ifndef MAX_UINT
47 #define MAX_UINT ((unsigned int)-1)
48 #endif
50 typedef struct SCSIGenericReq {
51 SCSIRequest req;
52 uint8_t *buf;
53 int buflen;
54 int len;
55 sg_io_hdr_t io_header;
56 } SCSIGenericReq;
58 static void scsi_generic_save_request(QEMUFile *f, SCSIRequest *req)
60 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
62 qemu_put_sbe32s(f, &r->buflen);
63 if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
64 assert(!r->req.sg);
65 qemu_put_buffer(f, r->buf, r->req.cmd.xfer);
69 static void scsi_generic_load_request(QEMUFile *f, SCSIRequest *req)
71 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
73 qemu_get_sbe32s(f, &r->buflen);
74 if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
75 assert(!r->req.sg);
76 qemu_get_buffer(f, r->buf, r->req.cmd.xfer);
80 static void scsi_free_request(SCSIRequest *req)
82 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
84 g_free(r->buf);
87 /* Helper function for command completion. */
88 static void scsi_command_complete_noio(SCSIGenericReq *r, int ret)
90 int status;
92 assert(r->req.aiocb == NULL);
94 if (r->req.io_canceled) {
95 scsi_req_cancel_complete(&r->req);
96 goto done;
98 if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
99 r->req.sense_len = r->io_header.sb_len_wr;
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;
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;
134 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
135 r, r->req.tag, status);
137 scsi_req_complete(&r->req, status);
138 done:
139 scsi_req_unref(&r->req);
142 static void scsi_command_complete(void *opaque, int ret)
144 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
146 assert(r->req.aiocb != NULL);
147 r->req.aiocb = NULL;
148 scsi_command_complete_noio(r, ret);
151 static int execute_command(BlockBackend *blk,
152 SCSIGenericReq *r, int direction,
153 BlockCompletionFunc *complete)
155 r->io_header.interface_id = 'S';
156 r->io_header.dxfer_direction = direction;
157 r->io_header.dxferp = r->buf;
158 r->io_header.dxfer_len = r->buflen;
159 r->io_header.cmdp = r->req.cmd.buf;
160 r->io_header.cmd_len = r->req.cmd.len;
161 r->io_header.mx_sb_len = sizeof(r->req.sense);
162 r->io_header.sbp = r->req.sense;
163 r->io_header.timeout = MAX_UINT;
164 r->io_header.usr_ptr = r;
165 r->io_header.flags |= SG_FLAG_DIRECT_IO;
167 r->req.aiocb = blk_aio_ioctl(blk, SG_IO, &r->io_header, complete, r);
168 if (r->req.aiocb == NULL) {
169 return -EIO;
172 return 0;
175 static void scsi_read_complete(void * opaque, int ret)
177 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
178 SCSIDevice *s = r->req.dev;
179 int len;
181 assert(r->req.aiocb != NULL);
182 r->req.aiocb = NULL;
184 if (ret || r->req.io_canceled) {
185 scsi_command_complete_noio(r, ret);
186 return;
189 len = r->io_header.dxfer_len - r->io_header.resid;
190 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
192 r->len = -1;
193 if (len == 0) {
194 scsi_command_complete_noio(r, 0);
195 return;
198 /* Snoop READ CAPACITY output to set the blocksize. */
199 if (r->req.cmd.buf[0] == READ_CAPACITY_10 &&
200 (ldl_be_p(&r->buf[0]) != 0xffffffffU || s->max_lba == 0)) {
201 s->blocksize = ldl_be_p(&r->buf[4]);
202 s->max_lba = ldl_be_p(&r->buf[0]) & 0xffffffffULL;
203 } else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 &&
204 (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
205 s->blocksize = ldl_be_p(&r->buf[8]);
206 s->max_lba = ldq_be_p(&r->buf[0]);
208 blk_set_guest_block_size(s->conf.blk, s->blocksize);
210 /* Patch MODE SENSE device specific parameters if the BDS is opened
211 * readonly.
213 if ((s->type == TYPE_DISK || s->type == TYPE_TAPE) &&
214 blk_is_read_only(s->conf.blk) &&
215 (r->req.cmd.buf[0] == MODE_SENSE ||
216 r->req.cmd.buf[0] == MODE_SENSE_10) &&
217 (r->req.cmd.buf[1] & 0x8) == 0) {
218 if (r->req.cmd.buf[0] == MODE_SENSE) {
219 r->buf[2] |= 0x80;
220 } else {
221 r->buf[3] |= 0x80;
224 scsi_req_data(&r->req, len);
225 scsi_req_unref(&r->req);
228 /* Read more data from scsi device into buffer. */
229 static void scsi_read_data(SCSIRequest *req)
231 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
232 SCSIDevice *s = r->req.dev;
233 int ret;
235 DPRINTF("scsi_read_data 0x%x\n", req->tag);
237 /* The request is used as the AIO opaque value, so add a ref. */
238 scsi_req_ref(&r->req);
239 if (r->len == -1) {
240 scsi_command_complete_noio(r, 0);
241 return;
244 ret = execute_command(s->conf.blk, r, SG_DXFER_FROM_DEV,
245 scsi_read_complete);
246 if (ret < 0) {
247 scsi_command_complete_noio(r, ret);
251 static void scsi_write_complete(void * opaque, int ret)
253 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
254 SCSIDevice *s = r->req.dev;
256 DPRINTF("scsi_write_complete() ret = %d\n", ret);
258 assert(r->req.aiocb != NULL);
259 r->req.aiocb = NULL;
261 if (ret || r->req.io_canceled) {
262 scsi_command_complete_noio(r, ret);
263 return;
266 if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
267 s->type == TYPE_TAPE) {
268 s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
269 DPRINTF("block size %d\n", s->blocksize);
272 scsi_command_complete_noio(r, ret);
275 /* Write data to a scsi device. Returns nonzero on failure.
276 The transfer may complete asynchronously. */
277 static void scsi_write_data(SCSIRequest *req)
279 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
280 SCSIDevice *s = r->req.dev;
281 int ret;
283 DPRINTF("scsi_write_data 0x%x\n", req->tag);
284 if (r->len == 0) {
285 r->len = r->buflen;
286 scsi_req_data(&r->req, r->len);
287 return;
290 /* The request is used as the AIO opaque value, so add a ref. */
291 scsi_req_ref(&r->req);
292 ret = execute_command(s->conf.blk, r, SG_DXFER_TO_DEV, scsi_write_complete);
293 if (ret < 0) {
294 scsi_command_complete_noio(r, ret);
298 /* Return a pointer to the data buffer. */
299 static uint8_t *scsi_get_buf(SCSIRequest *req)
301 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
303 return r->buf;
306 /* Execute a scsi command. Returns the length of the data expected by the
307 command. This will be Positive for data transfers from the device
308 (eg. disk reads), negative for transfers to the device (eg. disk writes),
309 and zero if the command does not transfer any data. */
311 static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
313 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
314 SCSIDevice *s = r->req.dev;
315 int ret;
317 #ifdef DEBUG_SCSI
319 int i;
320 for (i = 1; i < r->req.cmd.len; i++) {
321 printf(" 0x%02x", cmd[i]);
323 printf("\n");
325 #endif
327 if (r->req.cmd.xfer == 0) {
328 g_free(r->buf);
329 r->buflen = 0;
330 r->buf = NULL;
331 /* The request is used as the AIO opaque value, so add a ref. */
332 scsi_req_ref(&r->req);
333 ret = execute_command(s->conf.blk, r, SG_DXFER_NONE,
334 scsi_command_complete);
335 if (ret < 0) {
336 scsi_command_complete_noio(r, ret);
337 return 0;
339 return 0;
342 if (r->buflen != r->req.cmd.xfer) {
343 g_free(r->buf);
344 r->buf = g_malloc(r->req.cmd.xfer);
345 r->buflen = r->req.cmd.xfer;
348 memset(r->buf, 0, r->buflen);
349 r->len = r->req.cmd.xfer;
350 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
351 r->len = 0;
352 return -r->req.cmd.xfer;
353 } else {
354 return r->req.cmd.xfer;
358 static int get_stream_blocksize(BlockBackend *blk)
360 uint8_t cmd[6];
361 uint8_t buf[12];
362 uint8_t sensebuf[8];
363 sg_io_hdr_t io_header;
364 int ret;
366 memset(cmd, 0, sizeof(cmd));
367 memset(buf, 0, sizeof(buf));
368 cmd[0] = MODE_SENSE;
369 cmd[4] = sizeof(buf);
371 memset(&io_header, 0, sizeof(io_header));
372 io_header.interface_id = 'S';
373 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
374 io_header.dxfer_len = sizeof(buf);
375 io_header.dxferp = buf;
376 io_header.cmdp = cmd;
377 io_header.cmd_len = sizeof(cmd);
378 io_header.mx_sb_len = sizeof(sensebuf);
379 io_header.sbp = sensebuf;
380 io_header.timeout = 6000; /* XXX */
382 ret = blk_ioctl(blk, SG_IO, &io_header);
383 if (ret < 0 || io_header.driver_status || io_header.host_status) {
384 return -1;
386 return (buf[9] << 16) | (buf[10] << 8) | buf[11];
389 static void scsi_generic_reset(DeviceState *dev)
391 SCSIDevice *s = SCSI_DEVICE(dev);
393 scsi_device_purge_requests(s, SENSE_CODE(RESET));
396 static void scsi_generic_realize(SCSIDevice *s, Error **errp)
398 int rc;
399 int sg_version;
400 struct sg_scsi_id scsiid;
402 if (!s->conf.blk) {
403 error_setg(errp, "drive property not set");
404 return;
407 if (blk_get_on_error(s->conf.blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
408 error_setg(errp, "Device doesn't support drive option werror");
409 return;
411 if (blk_get_on_error(s->conf.blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
412 error_setg(errp, "Device doesn't support drive option rerror");
413 return;
416 /* check we are using a driver managing SG_IO (version 3 and after */
417 rc = blk_ioctl(s->conf.blk, SG_GET_VERSION_NUM, &sg_version);
418 if (rc < 0) {
419 error_setg(errp, "cannot get SG_IO version number: %s. "
420 "Is this a SCSI device?",
421 strerror(-rc));
422 return;
424 if (sg_version < 30000) {
425 error_setg(errp, "scsi generic interface too old");
426 return;
429 /* get LUN of the /dev/sg? */
430 if (blk_ioctl(s->conf.blk, SG_GET_SCSI_ID, &scsiid)) {
431 error_setg(errp, "SG_GET_SCSI_ID ioctl failed");
432 return;
435 /* define device state */
436 s->type = scsiid.scsi_type;
437 DPRINTF("device type %d\n", s->type);
439 switch (s->type) {
440 case TYPE_TAPE:
441 s->blocksize = get_stream_blocksize(s->conf.blk);
442 if (s->blocksize == -1) {
443 s->blocksize = 0;
445 break;
447 /* Make a guess for block devices, we'll fix it when the guest sends.
448 * READ CAPACITY. If they don't, they likely would assume these sizes
449 * anyway. (TODO: they could also send MODE SENSE).
451 case TYPE_ROM:
452 case TYPE_WORM:
453 s->blocksize = 2048;
454 break;
455 default:
456 s->blocksize = 512;
457 break;
460 DPRINTF("block size %d\n", s->blocksize);
463 const SCSIReqOps scsi_generic_req_ops = {
464 .size = sizeof(SCSIGenericReq),
465 .free_req = scsi_free_request,
466 .send_command = scsi_send_command,
467 .read_data = scsi_read_data,
468 .write_data = scsi_write_data,
469 .get_buf = scsi_get_buf,
470 .load_request = scsi_generic_load_request,
471 .save_request = scsi_generic_save_request,
474 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
475 uint8_t *buf, void *hba_private)
477 SCSIRequest *req;
479 req = scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
480 return req;
483 static Property scsi_generic_properties[] = {
484 DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.blk),
485 DEFINE_PROP_END_OF_LIST(),
488 static int scsi_generic_parse_cdb(SCSIDevice *dev, SCSICommand *cmd,
489 uint8_t *buf, void *hba_private)
491 return scsi_bus_parse_cdb(dev, cmd, buf, hba_private);
494 static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
496 DeviceClass *dc = DEVICE_CLASS(klass);
497 SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
499 sc->realize = scsi_generic_realize;
500 sc->alloc_req = scsi_new_request;
501 sc->parse_cdb = scsi_generic_parse_cdb;
502 dc->fw_name = "disk";
503 dc->desc = "pass through generic scsi device (/dev/sg*)";
504 dc->reset = scsi_generic_reset;
505 dc->props = scsi_generic_properties;
506 dc->vmsd = &vmstate_scsi_device;
509 static const TypeInfo scsi_generic_info = {
510 .name = "scsi-generic",
511 .parent = TYPE_SCSI_DEVICE,
512 .instance_size = sizeof(SCSIDevice),
513 .class_init = scsi_generic_class_initfn,
516 static void scsi_generic_register_types(void)
518 type_register_static(&scsi_generic_info);
521 type_init(scsi_generic_register_types)
523 #endif /* __linux__ */