scsi: make write_data return void
[qemu.git] / hw / scsi-generic.c
blob579bab9e7cb2c513d2cbd983863d03dd946d1532
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 void scsi_set_sense(SCSIGenericState *s, SCSISense sense)
71 s->senselen = scsi_build_sense(sense, s->sensebuf, SCSI_SENSE_BUF_SIZE, 0);
72 s->driver_status = SG_ERR_DRIVER_SENSE;
75 static void scsi_clear_sense(SCSIGenericState *s)
77 memset(s->sensebuf, 0, SCSI_SENSE_BUF_SIZE);
78 s->senselen = 0;
79 s->driver_status = 0;
82 static int scsi_get_sense(SCSIRequest *req, uint8_t *outbuf, int len)
84 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
85 int size = SCSI_SENSE_BUF_SIZE;
87 if (!(s->driver_status & SG_ERR_DRIVER_SENSE)) {
88 size = scsi_build_sense(SENSE_CODE(NO_SENSE), s->sensebuf,
89 SCSI_SENSE_BUF_SIZE, 0);
91 if (size > len) {
92 size = len;
94 memcpy(outbuf, s->sensebuf, size);
96 return size;
99 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
101 SCSIRequest *req;
103 req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun);
104 return req;
107 static void scsi_free_request(SCSIRequest *req)
109 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
111 qemu_free(r->buf);
114 /* Helper function for command completion. */
115 static void scsi_command_complete(void *opaque, int ret)
117 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
118 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
120 r->req.aiocb = NULL;
121 s->driver_status = r->io_header.driver_status;
122 if (s->driver_status & SG_ERR_DRIVER_SENSE)
123 s->senselen = r->io_header.sb_len_wr;
125 if (ret != 0) {
126 switch (ret) {
127 case -EINVAL:
128 r->req.status = CHECK_CONDITION;
129 scsi_set_sense(s, SENSE_CODE(INVALID_FIELD));
130 break;
131 case -ENOMEM:
132 r->req.status = CHECK_CONDITION;
133 scsi_set_sense(s, SENSE_CODE(TARGET_FAILURE));
134 break;
135 default:
136 r->req.status = CHECK_CONDITION;
137 scsi_set_sense(s, SENSE_CODE(IO_ERROR));
138 break;
140 } else {
141 if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
142 r->req.status = BUSY;
143 BADF("Driver Timeout\n");
144 } else if (r->io_header.status)
145 r->req.status = r->io_header.status;
146 else if (s->driver_status & SG_ERR_DRIVER_SENSE)
147 r->req.status = CHECK_CONDITION;
148 else
149 r->req.status = GOOD;
151 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
152 r, r->req.tag, r->req.status);
154 scsi_req_complete(&r->req);
157 /* Cancel a pending data transfer. */
158 static void scsi_cancel_io(SCSIRequest *req)
160 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
162 DPRINTF("Cancel tag=0x%x\n", req->tag);
163 if (r->req.aiocb) {
164 bdrv_aio_cancel(r->req.aiocb);
166 r->req.aiocb = NULL;
169 static int execute_command(BlockDriverState *bdrv,
170 SCSIGenericReq *r, int direction,
171 BlockDriverCompletionFunc *complete)
173 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
175 r->io_header.interface_id = 'S';
176 r->io_header.dxfer_direction = direction;
177 r->io_header.dxferp = r->buf;
178 r->io_header.dxfer_len = r->buflen;
179 r->io_header.cmdp = r->req.cmd.buf;
180 r->io_header.cmd_len = r->req.cmd.len;
181 r->io_header.mx_sb_len = sizeof(s->sensebuf);
182 r->io_header.sbp = s->sensebuf;
183 r->io_header.timeout = MAX_UINT;
184 r->io_header.usr_ptr = r;
185 r->io_header.flags |= SG_FLAG_DIRECT_IO;
187 r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
188 if (r->req.aiocb == NULL) {
189 BADF("execute_command: read failed !\n");
190 return -ENOMEM;
193 return 0;
196 static void scsi_read_complete(void * opaque, int ret)
198 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
199 int len;
201 r->req.aiocb = NULL;
202 if (ret) {
203 DPRINTF("IO error ret %d\n", ret);
204 scsi_command_complete(r, ret);
205 return;
207 len = r->io_header.dxfer_len - r->io_header.resid;
208 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
210 r->len = -1;
211 if (len == 0) {
212 scsi_command_complete(r, 0);
213 } else {
214 scsi_req_data(&r->req, len);
218 /* Read more data from scsi device into buffer. */
219 static void scsi_read_data(SCSIRequest *req)
221 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
222 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
223 int ret;
225 DPRINTF("scsi_read_data 0x%x\n", req->tag);
226 if (r->len == -1) {
227 scsi_command_complete(r, 0);
228 return;
231 if (r->req.cmd.buf[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
233 s->senselen = MIN(r->len, s->senselen);
234 memcpy(r->buf, s->sensebuf, s->senselen);
235 r->io_header.driver_status = 0;
236 r->io_header.status = 0;
237 r->io_header.dxfer_len = s->senselen;
238 r->len = -1;
239 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, s->senselen);
240 DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
241 r->buf[0], r->buf[1], r->buf[2], r->buf[3],
242 r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
243 scsi_req_data(&r->req, s->senselen);
244 /* Clear sensebuf after REQUEST_SENSE */
245 scsi_clear_sense(s);
246 return;
249 ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
250 if (ret < 0) {
251 scsi_command_complete(r, ret);
252 return;
256 static void scsi_write_complete(void * opaque, int ret)
258 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
259 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
261 DPRINTF("scsi_write_complete() ret = %d\n", ret);
262 r->req.aiocb = NULL;
263 if (ret) {
264 DPRINTF("IO error\n");
265 scsi_command_complete(r, ret);
266 return;
269 if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
270 s->qdev.type == TYPE_TAPE) {
271 s->qdev.blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
272 DPRINTF("block size %d\n", s->qdev.blocksize);
275 scsi_command_complete(r, ret);
278 /* Write data to a scsi device. Returns nonzero on failure.
279 The transfer may complete asynchronously. */
280 static void scsi_write_data(SCSIRequest *req)
282 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
283 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
284 int ret;
286 DPRINTF("scsi_write_data 0x%x\n", req->tag);
287 if (r->len == 0) {
288 r->len = r->buflen;
289 scsi_req_data(&r->req, r->len);
290 return;
293 ret = execute_command(s->bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
294 if (ret < 0) {
295 scsi_command_complete(r, ret);
299 /* Return a pointer to the data buffer. */
300 static uint8_t *scsi_get_buf(SCSIRequest *req)
302 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
304 return r->buf;
307 static void scsi_req_fixup(SCSIRequest *req)
309 switch(req->cmd.buf[0]) {
310 case WRITE_10:
311 req->cmd.buf[1] &= ~0x08; /* disable FUA */
312 break;
313 case READ_10:
314 req->cmd.buf[1] &= ~0x08; /* disable FUA */
315 break;
316 case REWIND:
317 case START_STOP:
318 if (req->dev->type == TYPE_TAPE) {
319 /* force IMMED, otherwise qemu waits end of command */
320 req->cmd.buf[1] = 0x01;
322 break;
326 /* Execute a scsi command. Returns the length of the data expected by the
327 command. This will be Positive for data transfers from the device
328 (eg. disk reads), negative for transfers to the device (eg. disk writes),
329 and zero if the command does not transfer any data. */
331 static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
333 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
334 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
335 int ret;
337 if (cmd[0] != REQUEST_SENSE &&
338 (req->lun != s->lun || (cmd[1] >> 5) != s->lun)) {
339 DPRINTF("Unimplemented LUN %d\n", req->lun ? req->lun : cmd[1] >> 5);
340 scsi_set_sense(s, SENSE_CODE(LUN_NOT_SUPPORTED));
341 r->req.status = CHECK_CONDITION;
342 scsi_req_complete(&r->req);
343 return 0;
346 if (-1 == scsi_req_parse(&r->req, cmd)) {
347 BADF("Unsupported command length, command %x\n", cmd[0]);
348 scsi_command_complete(r, -EINVAL);
349 return 0;
351 scsi_req_fixup(&r->req);
353 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun, tag,
354 r->req.cmd.xfer, cmd[0]);
356 #ifdef DEBUG_SCSI
358 int i;
359 for (i = 1; i < r->req.cmd.len; i++) {
360 printf(" 0x%02x", cmd[i]);
362 printf("\n");
364 #endif
366 if (r->req.cmd.xfer == 0) {
367 if (r->buf != NULL)
368 qemu_free(r->buf);
369 r->buflen = 0;
370 r->buf = NULL;
371 ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);
372 if (ret < 0) {
373 scsi_command_complete(r, ret);
374 return 0;
376 return 0;
379 if (r->buflen != r->req.cmd.xfer) {
380 if (r->buf != NULL)
381 qemu_free(r->buf);
382 r->buf = qemu_malloc(r->req.cmd.xfer);
383 r->buflen = r->req.cmd.xfer;
386 memset(r->buf, 0, r->buflen);
387 r->len = r->req.cmd.xfer;
388 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
389 r->len = 0;
390 return -r->req.cmd.xfer;
391 } else {
392 return r->req.cmd.xfer;
396 static int get_blocksize(BlockDriverState *bdrv)
398 uint8_t cmd[10];
399 uint8_t buf[8];
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] = READ_CAPACITY;
408 memset(&io_header, 0, sizeof(io_header));
409 io_header.interface_id = 'S';
410 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
411 io_header.dxfer_len = sizeof(buf);
412 io_header.dxferp = buf;
413 io_header.cmdp = cmd;
414 io_header.cmd_len = sizeof(cmd);
415 io_header.mx_sb_len = sizeof(sensebuf);
416 io_header.sbp = sensebuf;
417 io_header.timeout = 6000; /* XXX */
419 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
420 if (ret < 0)
421 return -1;
423 return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
426 static int get_stream_blocksize(BlockDriverState *bdrv)
428 uint8_t cmd[6];
429 uint8_t buf[12];
430 uint8_t sensebuf[8];
431 sg_io_hdr_t io_header;
432 int ret;
434 memset(cmd, 0, sizeof(cmd));
435 memset(buf, 0, sizeof(buf));
436 cmd[0] = MODE_SENSE;
437 cmd[4] = sizeof(buf);
439 memset(&io_header, 0, sizeof(io_header));
440 io_header.interface_id = 'S';
441 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
442 io_header.dxfer_len = sizeof(buf);
443 io_header.dxferp = buf;
444 io_header.cmdp = cmd;
445 io_header.cmd_len = sizeof(cmd);
446 io_header.mx_sb_len = sizeof(sensebuf);
447 io_header.sbp = sensebuf;
448 io_header.timeout = 6000; /* XXX */
450 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
451 if (ret < 0)
452 return -1;
454 return (buf[9] << 16) | (buf[10] << 8) | buf[11];
457 static void scsi_generic_reset(DeviceState *dev)
459 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev.qdev, dev);
461 scsi_device_purge_requests(&s->qdev);
464 static void scsi_destroy(SCSIDevice *d)
466 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
468 scsi_device_purge_requests(&s->qdev);
469 blockdev_mark_auto_del(s->qdev.conf.bs);
472 static int scsi_generic_initfn(SCSIDevice *dev)
474 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
475 int sg_version;
476 struct sg_scsi_id scsiid;
478 if (!s->qdev.conf.bs) {
479 error_report("scsi-generic: drive property not set");
480 return -1;
482 s->bs = s->qdev.conf.bs;
484 /* check we are really using a /dev/sg* file */
485 if (!bdrv_is_sg(s->bs)) {
486 error_report("scsi-generic: not /dev/sg*");
487 return -1;
490 if (bdrv_get_on_error(s->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
491 error_report("Device doesn't support drive option werror");
492 return -1;
494 if (bdrv_get_on_error(s->bs, 1) != BLOCK_ERR_REPORT) {
495 error_report("Device doesn't support drive option rerror");
496 return -1;
499 /* check we are using a driver managing SG_IO (version 3 and after */
500 if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
501 sg_version < 30000) {
502 error_report("scsi-generic: scsi generic interface too old");
503 return -1;
506 /* get LUN of the /dev/sg? */
507 if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
508 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
509 return -1;
512 /* define device state */
513 s->lun = scsiid.lun;
514 DPRINTF("LUN %d\n", s->lun);
515 s->qdev.type = scsiid.scsi_type;
516 DPRINTF("device type %d\n", s->qdev.type);
517 if (s->qdev.type == TYPE_TAPE) {
518 s->qdev.blocksize = get_stream_blocksize(s->bs);
519 if (s->qdev.blocksize == -1)
520 s->qdev.blocksize = 0;
521 } else {
522 s->qdev.blocksize = get_blocksize(s->bs);
523 /* removable media returns 0 if not present */
524 if (s->qdev.blocksize <= 0) {
525 if (s->qdev.type == TYPE_ROM || s->qdev.type == TYPE_WORM)
526 s->qdev.blocksize = 2048;
527 else
528 s->qdev.blocksize = 512;
531 DPRINTF("block size %d\n", s->qdev.blocksize);
532 s->driver_status = 0;
533 memset(s->sensebuf, 0, sizeof(s->sensebuf));
534 bdrv_set_removable(s->bs, 0);
535 return 0;
538 static SCSIDeviceInfo scsi_generic_info = {
539 .qdev.name = "scsi-generic",
540 .qdev.desc = "pass through generic scsi device (/dev/sg*)",
541 .qdev.size = sizeof(SCSIGenericState),
542 .qdev.reset = scsi_generic_reset,
543 .init = scsi_generic_initfn,
544 .destroy = scsi_destroy,
545 .alloc_req = scsi_new_request,
546 .free_req = scsi_free_request,
547 .send_command = scsi_send_command,
548 .read_data = scsi_read_data,
549 .write_data = scsi_write_data,
550 .cancel_io = scsi_cancel_io,
551 .get_buf = scsi_get_buf,
552 .get_sense = scsi_get_sense,
553 .qdev.props = (Property[]) {
554 DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf),
555 DEFINE_PROP_END_OF_LIST(),
559 static void scsi_generic_register_devices(void)
561 scsi_qdev_register(&scsi_generic_info);
563 device_init(scsi_generic_register_devices)
565 #endif /* __linux__ */