scsi: introduce scsi_req_abort
[qemu/cris-port.git] / hw / scsi-generic.c
blob72c4cc702df90aa8f48503755922cf10eb04f512
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 licenced under the LGPL.
14 #include "qemu-common.h"
15 #include "qemu-error.h"
16 #include "scsi.h"
17 #include "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 "scsi-defs.h"
40 #define SCSI_SENSE_BUF_SIZE 96
42 #define SG_ERR_DRIVER_TIMEOUT 0x06
43 #define SG_ERR_DRIVER_SENSE 0x08
45 #ifndef MAX_UINT
46 #define MAX_UINT ((unsigned int)-1)
47 #endif
49 typedef struct SCSIGenericState SCSIGenericState;
51 typedef struct SCSIGenericReq {
52 SCSIRequest req;
53 uint8_t *buf;
54 int buflen;
55 int len;
56 sg_io_hdr_t io_header;
57 } SCSIGenericReq;
59 struct SCSIGenericState
61 SCSIDevice qdev;
62 BlockDriverState *bs;
63 int lun;
64 int driver_status;
65 uint8_t sensebuf[SCSI_SENSE_BUF_SIZE];
66 uint8_t senselen;
69 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
71 SCSIRequest *req;
73 req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun);
74 return req;
77 static void scsi_free_request(SCSIRequest *req)
79 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
81 qemu_free(r->buf);
84 /* Helper function for command completion. */
85 static void scsi_command_complete(void *opaque, int ret)
87 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
88 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
90 r->req.aiocb = NULL;
91 s->driver_status = r->io_header.driver_status;
92 if (s->driver_status & SG_ERR_DRIVER_SENSE)
93 s->senselen = r->io_header.sb_len_wr;
95 if (ret != 0)
96 r->req.status = BUSY;
97 else {
98 if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
99 r->req.status = BUSY;
100 BADF("Driver Timeout\n");
101 } else if (r->io_header.status)
102 r->req.status = r->io_header.status;
103 else if (s->driver_status & SG_ERR_DRIVER_SENSE)
104 r->req.status = CHECK_CONDITION;
105 else
106 r->req.status = GOOD;
108 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
109 r, r->req.tag, r->req.status);
111 scsi_req_complete(&r->req);
114 /* Cancel a pending data transfer. */
115 static void scsi_cancel_io(SCSIRequest *req)
117 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
119 DPRINTF("Cancel tag=0x%x\n", req->tag);
120 if (r->req.aiocb) {
121 bdrv_aio_cancel(r->req.aiocb);
123 r->req.aiocb = NULL;
124 scsi_req_dequeue(&r->req);
127 static int execute_command(BlockDriverState *bdrv,
128 SCSIGenericReq *r, int direction,
129 BlockDriverCompletionFunc *complete)
131 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
133 r->io_header.interface_id = 'S';
134 r->io_header.dxfer_direction = direction;
135 r->io_header.dxferp = r->buf;
136 r->io_header.dxfer_len = r->buflen;
137 r->io_header.cmdp = r->req.cmd.buf;
138 r->io_header.cmd_len = r->req.cmd.len;
139 r->io_header.mx_sb_len = sizeof(s->sensebuf);
140 r->io_header.sbp = s->sensebuf;
141 r->io_header.timeout = MAX_UINT;
142 r->io_header.usr_ptr = r;
143 r->io_header.flags |= SG_FLAG_DIRECT_IO;
145 r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
146 if (r->req.aiocb == NULL) {
147 BADF("execute_command: read failed !\n");
148 return -1;
151 return 0;
154 static void scsi_read_complete(void * opaque, int ret)
156 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
157 int len;
159 r->req.aiocb = NULL;
160 if (ret) {
161 DPRINTF("IO error ret %d\n", ret);
162 scsi_command_complete(r, ret);
163 return;
165 len = r->io_header.dxfer_len - r->io_header.resid;
166 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
168 r->len = -1;
169 if (len == 0) {
170 scsi_command_complete(r, 0);
171 } else {
172 scsi_req_data(&r->req, len);
176 /* Read more data from scsi device into buffer. */
177 static void scsi_read_data(SCSIRequest *req)
179 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
180 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
181 int ret;
183 DPRINTF("scsi_read_data 0x%x\n", req->tag);
184 if (r->len == -1) {
185 scsi_command_complete(r, 0);
186 return;
189 if (r->req.cmd.buf[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
191 s->senselen = MIN(r->len, s->senselen);
192 memcpy(r->buf, s->sensebuf, s->senselen);
193 r->io_header.driver_status = 0;
194 r->io_header.status = 0;
195 r->io_header.dxfer_len = s->senselen;
196 r->len = -1;
197 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, s->senselen);
198 DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
199 r->buf[0], r->buf[1], r->buf[2], r->buf[3],
200 r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
201 scsi_req_data(&r->req, s->senselen);
202 return;
205 ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
206 if (ret == -1) {
207 scsi_command_complete(r, -EINVAL);
208 return;
212 static void scsi_write_complete(void * opaque, int ret)
214 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
215 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
217 DPRINTF("scsi_write_complete() ret = %d\n", ret);
218 r->req.aiocb = NULL;
219 if (ret) {
220 DPRINTF("IO error\n");
221 scsi_command_complete(r, ret);
222 return;
225 if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
226 s->qdev.type == TYPE_TAPE) {
227 s->qdev.blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
228 DPRINTF("block size %d\n", s->qdev.blocksize);
231 scsi_command_complete(r, ret);
234 /* Write data to a scsi device. Returns nonzero on failure.
235 The transfer may complete asynchronously. */
236 static int scsi_write_data(SCSIRequest *req)
238 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
239 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
240 int ret;
242 DPRINTF("scsi_write_data 0x%x\n", req->tag);
243 if (r->len == 0) {
244 r->len = r->buflen;
245 scsi_req_data(&r->req, r->len);
246 return 0;
249 ret = execute_command(s->bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
250 if (ret == -1) {
251 scsi_command_complete(r, -EINVAL);
252 return 1;
255 return 0;
258 /* Return a pointer to the data buffer. */
259 static uint8_t *scsi_get_buf(SCSIRequest *req)
261 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
263 return r->buf;
266 static void scsi_req_fixup(SCSIRequest *req)
268 switch(req->cmd.buf[0]) {
269 case WRITE_10:
270 req->cmd.buf[1] &= ~0x08; /* disable FUA */
271 break;
272 case READ_10:
273 req->cmd.buf[1] &= ~0x08; /* disable FUA */
274 break;
275 case REWIND:
276 case START_STOP:
277 if (req->dev->type == TYPE_TAPE) {
278 /* force IMMED, otherwise qemu waits end of command */
279 req->cmd.buf[1] = 0x01;
281 break;
285 /* Execute a scsi command. Returns the length of the data expected by the
286 command. This will be Positive for data transfers from the device
287 (eg. disk reads), negative for transfers to the device (eg. disk writes),
288 and zero if the command does not transfer any data. */
290 static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
292 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
293 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
294 SCSIBus *bus;
295 int ret;
297 scsi_req_enqueue(req);
298 if (cmd[0] != REQUEST_SENSE &&
299 (req->lun != s->lun || (cmd[1] >> 5) != s->lun)) {
300 DPRINTF("Unimplemented LUN %d\n", req->lun ? req->lun : cmd[1] >> 5);
302 s->sensebuf[0] = 0x70;
303 s->sensebuf[1] = 0x00;
304 s->sensebuf[2] = ILLEGAL_REQUEST;
305 s->sensebuf[3] = 0x00;
306 s->sensebuf[4] = 0x00;
307 s->sensebuf[5] = 0x00;
308 s->sensebuf[6] = 0x00;
309 s->senselen = 7;
310 s->driver_status = SG_ERR_DRIVER_SENSE;
311 bus = scsi_bus_from_device(&s->qdev);
312 bus->ops->complete(req, SCSI_REASON_DONE, CHECK_CONDITION);
313 return 0;
316 if (-1 == scsi_req_parse(&r->req, cmd)) {
317 BADF("Unsupported command length, command %x\n", cmd[0]);
318 scsi_req_dequeue(&r->req);
319 scsi_req_unref(&r->req);
320 return 0;
322 scsi_req_fixup(&r->req);
324 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun, tag,
325 r->req.cmd.xfer, cmd[0]);
327 #ifdef DEBUG_SCSI
329 int i;
330 for (i = 1; i < r->req.cmd.len; i++) {
331 printf(" 0x%02x", cmd[i]);
333 printf("\n");
335 #endif
337 if (r->req.cmd.xfer == 0) {
338 if (r->buf != NULL)
339 qemu_free(r->buf);
340 r->buflen = 0;
341 r->buf = NULL;
342 ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);
343 if (ret == -1) {
344 scsi_command_complete(r, -EINVAL);
346 return 0;
349 if (r->buflen != r->req.cmd.xfer) {
350 if (r->buf != NULL)
351 qemu_free(r->buf);
352 r->buf = qemu_malloc(r->req.cmd.xfer);
353 r->buflen = r->req.cmd.xfer;
356 memset(r->buf, 0, r->buflen);
357 r->len = r->req.cmd.xfer;
358 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
359 r->len = 0;
360 return -r->req.cmd.xfer;
361 } else {
362 return r->req.cmd.xfer;
366 static int get_blocksize(BlockDriverState *bdrv)
368 uint8_t cmd[10];
369 uint8_t buf[8];
370 uint8_t sensebuf[8];
371 sg_io_hdr_t io_header;
372 int ret;
374 memset(cmd, 0, sizeof(cmd));
375 memset(buf, 0, sizeof(buf));
376 cmd[0] = READ_CAPACITY;
378 memset(&io_header, 0, sizeof(io_header));
379 io_header.interface_id = 'S';
380 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
381 io_header.dxfer_len = sizeof(buf);
382 io_header.dxferp = buf;
383 io_header.cmdp = cmd;
384 io_header.cmd_len = sizeof(cmd);
385 io_header.mx_sb_len = sizeof(sensebuf);
386 io_header.sbp = sensebuf;
387 io_header.timeout = 6000; /* XXX */
389 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
390 if (ret < 0)
391 return -1;
393 return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
396 static int get_stream_blocksize(BlockDriverState *bdrv)
398 uint8_t cmd[6];
399 uint8_t buf[12];
400 uint8_t sensebuf[8];
401 sg_io_hdr_t io_header;
402 int ret;
404 memset(cmd, 0, sizeof(cmd));
405 memset(buf, 0, sizeof(buf));
406 cmd[0] = MODE_SENSE;
407 cmd[4] = sizeof(buf);
409 memset(&io_header, 0, sizeof(io_header));
410 io_header.interface_id = 'S';
411 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
412 io_header.dxfer_len = sizeof(buf);
413 io_header.dxferp = buf;
414 io_header.cmdp = cmd;
415 io_header.cmd_len = sizeof(cmd);
416 io_header.mx_sb_len = sizeof(sensebuf);
417 io_header.sbp = sensebuf;
418 io_header.timeout = 6000; /* XXX */
420 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
421 if (ret < 0)
422 return -1;
424 return (buf[9] << 16) | (buf[10] << 8) | buf[11];
427 static void scsi_generic_reset(DeviceState *dev)
429 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev.qdev, dev);
431 scsi_device_purge_requests(&s->qdev);
434 static void scsi_destroy(SCSIDevice *d)
436 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
438 scsi_device_purge_requests(&s->qdev);
439 blockdev_mark_auto_del(s->qdev.conf.bs);
442 static int scsi_generic_initfn(SCSIDevice *dev)
444 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
445 int sg_version;
446 struct sg_scsi_id scsiid;
448 if (!s->qdev.conf.bs) {
449 error_report("scsi-generic: drive property not set");
450 return -1;
452 s->bs = s->qdev.conf.bs;
454 /* check we are really using a /dev/sg* file */
455 if (!bdrv_is_sg(s->bs)) {
456 error_report("scsi-generic: not /dev/sg*");
457 return -1;
460 if (bdrv_get_on_error(s->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
461 error_report("Device doesn't support drive option werror");
462 return -1;
464 if (bdrv_get_on_error(s->bs, 1) != BLOCK_ERR_REPORT) {
465 error_report("Device doesn't support drive option rerror");
466 return -1;
469 /* check we are using a driver managing SG_IO (version 3 and after */
470 if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
471 sg_version < 30000) {
472 error_report("scsi-generic: scsi generic interface too old");
473 return -1;
476 /* get LUN of the /dev/sg? */
477 if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
478 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
479 return -1;
482 /* define device state */
483 s->lun = scsiid.lun;
484 DPRINTF("LUN %d\n", s->lun);
485 s->qdev.type = scsiid.scsi_type;
486 DPRINTF("device type %d\n", s->qdev.type);
487 if (s->qdev.type == TYPE_TAPE) {
488 s->qdev.blocksize = get_stream_blocksize(s->bs);
489 if (s->qdev.blocksize == -1)
490 s->qdev.blocksize = 0;
491 } else {
492 s->qdev.blocksize = get_blocksize(s->bs);
493 /* removable media returns 0 if not present */
494 if (s->qdev.blocksize <= 0) {
495 if (s->qdev.type == TYPE_ROM || s->qdev.type == TYPE_WORM)
496 s->qdev.blocksize = 2048;
497 else
498 s->qdev.blocksize = 512;
501 DPRINTF("block size %d\n", s->qdev.blocksize);
502 s->driver_status = 0;
503 memset(s->sensebuf, 0, sizeof(s->sensebuf));
504 bdrv_set_removable(s->bs, 0);
505 return 0;
508 static SCSIDeviceInfo scsi_generic_info = {
509 .qdev.name = "scsi-generic",
510 .qdev.desc = "pass through generic scsi device (/dev/sg*)",
511 .qdev.size = sizeof(SCSIGenericState),
512 .qdev.reset = scsi_generic_reset,
513 .init = scsi_generic_initfn,
514 .destroy = scsi_destroy,
515 .alloc_req = scsi_new_request,
516 .free_req = scsi_free_request,
517 .send_command = scsi_send_command,
518 .read_data = scsi_read_data,
519 .write_data = scsi_write_data,
520 .cancel_io = scsi_cancel_io,
521 .get_buf = scsi_get_buf,
522 .qdev.props = (Property[]) {
523 DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf),
524 DEFINE_PROP_END_OF_LIST(),
528 static void scsi_generic_register_devices(void)
530 scsi_qdev_register(&scsi_generic_info);
532 device_init(scsi_generic_register_devices)
534 #endif /* __linux__ */