Merge remote-tracking branch 'remotes/mjt/tags/pull-trivial-patches-2015-04-04' into...
[qemu.git] / hw / scsi / scsi-generic.c
blobe53470f85ef2189dadce2c206cb5a7a3623fa9d4
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-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"
20 #ifdef __linux__
22 //#define DEBUG_SCSI
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
31 #define BADF(fmt, ...) \
32 do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
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"
41 #define SG_ERR_DRIVER_TIMEOUT 0x06
42 #define SG_ERR_DRIVER_SENSE 0x08
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
49 #ifndef MAX_UINT
50 #define MAX_UINT ((unsigned int)-1)
51 #endif
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;
61 static void scsi_generic_save_request(QEMUFile *f, SCSIRequest *req)
63 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
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);
72 static void scsi_generic_load_request(QEMUFile *f, SCSIRequest *req)
74 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
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);
83 static void scsi_free_request(SCSIRequest *req)
85 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
87 g_free(r->buf);
90 /* Helper function for command completion. */
91 static void scsi_command_complete(void *opaque, int ret)
93 int status;
94 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
96 r->req.aiocb = NULL;
97 if (r->req.io_canceled) {
98 scsi_req_cancel_complete(&r->req);
99 goto done;
101 if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
102 r->req.sense_len = r->io_header.sb_len_wr;
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;
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;
137 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
138 r, r->req.tag, status);
140 scsi_req_complete(&r->req, status);
141 done:
142 scsi_req_unref(&r->req);
145 static int execute_command(BlockBackend *blk,
146 SCSIGenericReq *r, int direction,
147 BlockCompletionFunc *complete)
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;
161 r->req.aiocb = blk_aio_ioctl(blk, SG_IO, &r->io_header, complete, r);
162 if (r->req.aiocb == NULL) {
163 return -EIO;
166 return 0;
169 static void scsi_read_complete(void * opaque, int ret)
171 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
172 SCSIDevice *s = r->req.dev;
173 int len;
175 r->req.aiocb = NULL;
176 if (ret || r->req.io_canceled) {
177 scsi_command_complete(r, ret);
178 return;
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);
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]);
197 blk_set_guest_block_size(s->conf.blk, s->blocksize);
199 scsi_req_data(&r->req, len);
200 scsi_req_unref(&r->req);
204 /* Read more data from scsi device into buffer. */
205 static void scsi_read_data(SCSIRequest *req)
207 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
208 SCSIDevice *s = r->req.dev;
209 int ret;
211 DPRINTF("scsi_read_data 0x%x\n", req->tag);
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;
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);
227 static void scsi_write_complete(void * opaque, int ret)
229 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
230 SCSIDevice *s = r->req.dev;
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;
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);
245 scsi_command_complete(r, ret);
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)
252 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
253 SCSIDevice *s = r->req.dev;
254 int ret;
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;
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);
271 /* Return a pointer to the data buffer. */
272 static uint8_t *scsi_get_buf(SCSIRequest *req)
274 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
276 return r->buf;
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. */
284 static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
286 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
287 SCSIDevice *s = r->req.dev;
288 int ret;
290 #ifdef DEBUG_SCSI
292 int i;
293 for (i = 1; i < r->req.cmd.len; i++) {
294 printf(" 0x%02x", cmd[i]);
296 printf("\n");
298 #endif
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;
312 return 0;
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;
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;
331 static int get_stream_blocksize(BlockBackend *blk)
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;
339 memset(cmd, 0, sizeof(cmd));
340 memset(buf, 0, sizeof(buf));
341 cmd[0] = MODE_SENSE;
342 cmd[4] = sizeof(buf);
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 */
355 ret = blk_ioctl(blk, SG_IO, &io_header);
356 if (ret < 0 || io_header.driver_status || io_header.host_status) {
357 return -1;
359 return (buf[9] << 16) | (buf[10] << 8) | buf[11];
362 static void scsi_generic_reset(DeviceState *dev)
364 SCSIDevice *s = SCSI_DEVICE(dev);
366 scsi_device_purge_requests(s, SENSE_CODE(RESET));
369 static void scsi_generic_realize(SCSIDevice *s, Error **errp)
371 int rc;
372 int sg_version;
373 struct sg_scsi_id scsiid;
375 if (!s->conf.blk) {
376 error_setg(errp, "drive property not set");
377 return;
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;
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;
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;
397 if (sg_version < 30000) {
398 error_setg(errp, "scsi generic interface too old");
399 return;
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;
408 /* define device state */
409 s->type = scsiid.scsi_type;
410 DPRINTF("device type %d\n", s->type);
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;
418 break;
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).
424 case TYPE_ROM:
425 case TYPE_WORM:
426 s->blocksize = 2048;
427 break;
428 default:
429 s->blocksize = 512;
430 break;
433 DPRINTF("block size %d\n", s->blocksize);
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,
447 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
448 uint8_t *buf, void *hba_private)
450 SCSIRequest *req;
452 req = scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
453 return req;
456 static Property scsi_generic_properties[] = {
457 DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.blk),
458 DEFINE_PROP_END_OF_LIST(),
461 static int scsi_generic_parse_cdb(SCSIDevice *dev, SCSICommand *cmd,
462 uint8_t *buf, void *hba_private)
464 return scsi_bus_parse_cdb(dev, cmd, buf, hba_private);
467 static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
469 DeviceClass *dc = DEVICE_CLASS(klass);
470 SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
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;
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,
489 static void scsi_generic_register_types(void)
491 type_register_static(&scsi_generic_info);
494 type_init(scsi_generic_register_types)
496 #endif /* __linux__ */