scsi-generic: Handle canceled request in scsi_command_complete
[qemu/ar7.git] / hw / scsi / scsi-generic.c
blob2a73a43d1d3ba6e99ce92ffd408e26d21d9642a6
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/blockdev.h"
19 #ifdef __linux__
21 //#define DEBUG_SCSI
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
30 #define BADF(fmt, ...) \
31 do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
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 "block/scsi.h"
40 #define SG_ERR_DRIVER_TIMEOUT 0x06
41 #define SG_ERR_DRIVER_SENSE 0x08
43 #define SG_ERR_DID_OK 0x00
44 #define SG_ERR_DID_NO_CONNECT 0x01
45 #define SG_ERR_DID_BUS_BUSY 0x02
46 #define SG_ERR_DID_TIME_OUT 0x03
48 #ifndef MAX_UINT
49 #define MAX_UINT ((unsigned int)-1)
50 #endif
52 typedef struct SCSIGenericReq {
53 SCSIRequest req;
54 uint8_t *buf;
55 int buflen;
56 int len;
57 sg_io_hdr_t io_header;
58 } SCSIGenericReq;
60 static void scsi_generic_save_request(QEMUFile *f, SCSIRequest *req)
62 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
64 qemu_put_sbe32s(f, &r->buflen);
65 if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
66 assert(!r->req.sg);
67 qemu_put_buffer(f, r->buf, r->req.cmd.xfer);
71 static void scsi_generic_load_request(QEMUFile *f, SCSIRequest *req)
73 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
75 qemu_get_sbe32s(f, &r->buflen);
76 if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
77 assert(!r->req.sg);
78 qemu_get_buffer(f, r->buf, r->req.cmd.xfer);
82 static void scsi_free_request(SCSIRequest *req)
84 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
86 g_free(r->buf);
89 /* Helper function for command completion. */
90 static void scsi_command_complete(void *opaque, int ret)
92 int status;
93 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
95 r->req.aiocb = NULL;
96 if (r->req.io_canceled) {
97 goto done;
99 if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
100 r->req.sense_len = r->io_header.sb_len_wr;
103 if (ret != 0) {
104 switch (ret) {
105 case -EDOM:
106 status = TASK_SET_FULL;
107 break;
108 case -ENOMEM:
109 status = CHECK_CONDITION;
110 scsi_req_build_sense(&r->req, SENSE_CODE(TARGET_FAILURE));
111 break;
112 default:
113 status = CHECK_CONDITION;
114 scsi_req_build_sense(&r->req, SENSE_CODE(IO_ERROR));
115 break;
117 } else {
118 if (r->io_header.host_status == SG_ERR_DID_NO_CONNECT ||
119 r->io_header.host_status == SG_ERR_DID_BUS_BUSY ||
120 r->io_header.host_status == SG_ERR_DID_TIME_OUT ||
121 (r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT)) {
122 status = BUSY;
123 BADF("Driver Timeout\n");
124 } else if (r->io_header.host_status) {
125 status = CHECK_CONDITION;
126 scsi_req_build_sense(&r->req, SENSE_CODE(I_T_NEXUS_LOSS));
127 } else if (r->io_header.status) {
128 status = r->io_header.status;
129 } else if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
130 status = CHECK_CONDITION;
131 } else {
132 status = GOOD;
135 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
136 r, r->req.tag, status);
138 scsi_req_complete(&r->req, status);
139 done:
140 if (!r->req.io_canceled) {
141 scsi_req_unref(&r->req);
145 /* Cancel a pending data transfer. */
146 static void scsi_cancel_io(SCSIRequest *req)
148 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
150 DPRINTF("Cancel tag=0x%x\n", req->tag);
151 if (r->req.aiocb) {
152 bdrv_aio_cancel(r->req.aiocb);
154 /* This reference was left in by scsi_*_data. We take ownership of
155 * it independent of whether bdrv_aio_cancel completes the request
156 * or not. */
157 scsi_req_unref(&r->req);
159 r->req.aiocb = NULL;
162 static int execute_command(BlockDriverState *bdrv,
163 SCSIGenericReq *r, int direction,
164 BlockDriverCompletionFunc *complete)
166 r->io_header.interface_id = 'S';
167 r->io_header.dxfer_direction = direction;
168 r->io_header.dxferp = r->buf;
169 r->io_header.dxfer_len = r->buflen;
170 r->io_header.cmdp = r->req.cmd.buf;
171 r->io_header.cmd_len = r->req.cmd.len;
172 r->io_header.mx_sb_len = sizeof(r->req.sense);
173 r->io_header.sbp = r->req.sense;
174 r->io_header.timeout = MAX_UINT;
175 r->io_header.usr_ptr = r;
176 r->io_header.flags |= SG_FLAG_DIRECT_IO;
178 r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
179 if (r->req.aiocb == NULL) {
180 return -EIO;
183 return 0;
186 static void scsi_read_complete(void * opaque, int ret)
188 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
189 SCSIDevice *s = r->req.dev;
190 int len;
192 r->req.aiocb = NULL;
193 if (ret || r->req.io_canceled) {
194 scsi_command_complete(r, ret);
195 return;
197 len = r->io_header.dxfer_len - r->io_header.resid;
198 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
200 r->len = -1;
201 if (len == 0) {
202 scsi_command_complete(r, 0);
203 } else {
204 /* Snoop READ CAPACITY output to set the blocksize. */
205 if (r->req.cmd.buf[0] == READ_CAPACITY_10 &&
206 (ldl_be_p(&r->buf[0]) != 0xffffffffU || s->max_lba == 0)) {
207 s->blocksize = ldl_be_p(&r->buf[4]);
208 s->max_lba = ldl_be_p(&r->buf[0]) & 0xffffffffULL;
209 } else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 &&
210 (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
211 s->blocksize = ldl_be_p(&r->buf[8]);
212 s->max_lba = ldq_be_p(&r->buf[0]);
214 bdrv_set_guest_block_size(s->conf.bs, s->blocksize);
216 scsi_req_data(&r->req, len);
217 if (!r->req.io_canceled) {
218 scsi_req_unref(&r->req);
223 /* Read more data from scsi device into buffer. */
224 static void scsi_read_data(SCSIRequest *req)
226 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
227 SCSIDevice *s = r->req.dev;
228 int ret;
230 DPRINTF("scsi_read_data 0x%x\n", req->tag);
232 /* The request is used as the AIO opaque value, so add a ref. */
233 scsi_req_ref(&r->req);
234 if (r->len == -1) {
235 scsi_command_complete(r, 0);
236 return;
239 ret = execute_command(s->conf.bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
240 if (ret < 0) {
241 scsi_command_complete(r, ret);
245 static void scsi_write_complete(void * opaque, int ret)
247 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
248 SCSIDevice *s = r->req.dev;
250 DPRINTF("scsi_write_complete() ret = %d\n", ret);
251 r->req.aiocb = NULL;
252 if (ret || r->req.io_canceled) {
253 scsi_command_complete(r, ret);
254 return;
257 if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
258 s->type == TYPE_TAPE) {
259 s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
260 DPRINTF("block size %d\n", s->blocksize);
263 scsi_command_complete(r, ret);
266 /* Write data to a scsi device. Returns nonzero on failure.
267 The transfer may complete asynchronously. */
268 static void scsi_write_data(SCSIRequest *req)
270 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
271 SCSIDevice *s = r->req.dev;
272 int ret;
274 DPRINTF("scsi_write_data 0x%x\n", req->tag);
275 if (r->len == 0) {
276 r->len = r->buflen;
277 scsi_req_data(&r->req, r->len);
278 return;
281 /* The request is used as the AIO opaque value, so add a ref. */
282 scsi_req_ref(&r->req);
283 ret = execute_command(s->conf.bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
284 if (ret < 0) {
285 scsi_command_complete(r, ret);
289 /* Return a pointer to the data buffer. */
290 static uint8_t *scsi_get_buf(SCSIRequest *req)
292 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
294 return r->buf;
297 /* Execute a scsi command. Returns the length of the data expected by the
298 command. This will be Positive for data transfers from the device
299 (eg. disk reads), negative for transfers to the device (eg. disk writes),
300 and zero if the command does not transfer any data. */
302 static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
304 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
305 SCSIDevice *s = r->req.dev;
306 int ret;
308 #ifdef DEBUG_SCSI
310 int i;
311 for (i = 1; i < r->req.cmd.len; i++) {
312 printf(" 0x%02x", cmd[i]);
314 printf("\n");
316 #endif
318 if (r->req.cmd.xfer == 0) {
319 if (r->buf != NULL)
320 g_free(r->buf);
321 r->buflen = 0;
322 r->buf = NULL;
323 /* The request is used as the AIO opaque value, so add a ref. */
324 scsi_req_ref(&r->req);
325 ret = execute_command(s->conf.bs, r, SG_DXFER_NONE, scsi_command_complete);
326 if (ret < 0) {
327 scsi_command_complete(r, ret);
328 return 0;
330 return 0;
333 if (r->buflen != r->req.cmd.xfer) {
334 if (r->buf != NULL)
335 g_free(r->buf);
336 r->buf = g_malloc(r->req.cmd.xfer);
337 r->buflen = r->req.cmd.xfer;
340 memset(r->buf, 0, r->buflen);
341 r->len = r->req.cmd.xfer;
342 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
343 r->len = 0;
344 return -r->req.cmd.xfer;
345 } else {
346 return r->req.cmd.xfer;
350 static int get_stream_blocksize(BlockDriverState *bdrv)
352 uint8_t cmd[6];
353 uint8_t buf[12];
354 uint8_t sensebuf[8];
355 sg_io_hdr_t io_header;
356 int ret;
358 memset(cmd, 0, sizeof(cmd));
359 memset(buf, 0, sizeof(buf));
360 cmd[0] = MODE_SENSE;
361 cmd[4] = sizeof(buf);
363 memset(&io_header, 0, sizeof(io_header));
364 io_header.interface_id = 'S';
365 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
366 io_header.dxfer_len = sizeof(buf);
367 io_header.dxferp = buf;
368 io_header.cmdp = cmd;
369 io_header.cmd_len = sizeof(cmd);
370 io_header.mx_sb_len = sizeof(sensebuf);
371 io_header.sbp = sensebuf;
372 io_header.timeout = 6000; /* XXX */
374 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
375 if (ret < 0 || io_header.driver_status || io_header.host_status) {
376 return -1;
378 return (buf[9] << 16) | (buf[10] << 8) | buf[11];
381 static void scsi_generic_reset(DeviceState *dev)
383 SCSIDevice *s = SCSI_DEVICE(dev);
385 scsi_device_purge_requests(s, SENSE_CODE(RESET));
388 static void scsi_unrealize(SCSIDevice *s, Error **errp)
390 scsi_device_purge_requests(s, SENSE_CODE(NO_SENSE));
391 blockdev_mark_auto_del(s->conf.bs);
394 static void scsi_generic_realize(SCSIDevice *s, Error **errp)
396 int rc;
397 int sg_version;
398 struct sg_scsi_id scsiid;
400 if (!s->conf.bs) {
401 error_setg(errp, "drive property not set");
402 return;
405 if (bdrv_get_on_error(s->conf.bs, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
406 error_setg(errp, "Device doesn't support drive option werror");
407 return;
409 if (bdrv_get_on_error(s->conf.bs, 1) != BLOCKDEV_ON_ERROR_REPORT) {
410 error_setg(errp, "Device doesn't support drive option rerror");
411 return;
414 /* check we are using a driver managing SG_IO (version 3 and after */
415 rc = bdrv_ioctl(s->conf.bs, SG_GET_VERSION_NUM, &sg_version);
416 if (rc < 0) {
417 error_setg(errp, "cannot get SG_IO version number: %s. "
418 "Is this a SCSI device?",
419 strerror(-rc));
420 return;
422 if (sg_version < 30000) {
423 error_setg(errp, "scsi generic interface too old");
424 return;
427 /* get LUN of the /dev/sg? */
428 if (bdrv_ioctl(s->conf.bs, SG_GET_SCSI_ID, &scsiid)) {
429 error_setg(errp, "SG_GET_SCSI_ID ioctl failed");
430 return;
433 /* define device state */
434 s->type = scsiid.scsi_type;
435 DPRINTF("device type %d\n", s->type);
436 if (s->type == TYPE_DISK || s->type == TYPE_ROM) {
437 add_boot_device_path(s->conf.bootindex, &s->qdev, NULL);
440 switch (s->type) {
441 case TYPE_TAPE:
442 s->blocksize = get_stream_blocksize(s->conf.bs);
443 if (s->blocksize == -1) {
444 s->blocksize = 0;
446 break;
448 /* Make a guess for block devices, we'll fix it when the guest sends.
449 * READ CAPACITY. If they don't, they likely would assume these sizes
450 * anyway. (TODO: they could also send MODE SENSE).
452 case TYPE_ROM:
453 case TYPE_WORM:
454 s->blocksize = 2048;
455 break;
456 default:
457 s->blocksize = 512;
458 break;
461 DPRINTF("block size %d\n", s->blocksize);
464 const SCSIReqOps scsi_generic_req_ops = {
465 .size = sizeof(SCSIGenericReq),
466 .free_req = scsi_free_request,
467 .send_command = scsi_send_command,
468 .read_data = scsi_read_data,
469 .write_data = scsi_write_data,
470 .cancel_io = scsi_cancel_io,
471 .get_buf = scsi_get_buf,
472 .load_request = scsi_generic_load_request,
473 .save_request = scsi_generic_save_request,
476 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
477 uint8_t *buf, void *hba_private)
479 SCSIRequest *req;
481 req = scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
482 return req;
485 static Property scsi_generic_properties[] = {
486 DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.bs),
487 DEFINE_PROP_INT32("bootindex", SCSIDevice, conf.bootindex, -1),
488 DEFINE_PROP_END_OF_LIST(),
491 static int scsi_generic_parse_cdb(SCSIDevice *dev, SCSICommand *cmd,
492 uint8_t *buf, void *hba_private)
494 return scsi_bus_parse_cdb(dev, cmd, buf, hba_private);
497 static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
499 DeviceClass *dc = DEVICE_CLASS(klass);
500 SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
502 sc->realize = scsi_generic_realize;
503 sc->unrealize = scsi_unrealize;
504 sc->alloc_req = scsi_new_request;
505 sc->parse_cdb = scsi_generic_parse_cdb;
506 dc->fw_name = "disk";
507 dc->desc = "pass through generic scsi device (/dev/sg*)";
508 dc->reset = scsi_generic_reset;
509 dc->props = scsi_generic_properties;
510 dc->vmsd = &vmstate_scsi_device;
513 static const TypeInfo scsi_generic_info = {
514 .name = "scsi-generic",
515 .parent = TYPE_SCSI_DEVICE,
516 .instance_size = sizeof(SCSIDevice),
517 .class_init = scsi_generic_class_initfn,
520 static void scsi_generic_register_types(void)
522 type_register_static(&scsi_generic_info);
525 type_init(scsi_generic_register_types)
527 #endif /* __linux__ */