virtio-serial: Turn props any virtio-serial-bus device must have into bus props
[qemu.git] / hw / scsi-generic.c
blob90345a714f923503fcbbd9867c2e121075d0b15f
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,
100 void *hba_private)
102 SCSIRequest *req;
104 req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun, hba_private);
105 return req;
108 static void scsi_free_request(SCSIRequest *req)
110 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
112 qemu_free(r->buf);
115 /* Helper function for command completion. */
116 static void scsi_command_complete(void *opaque, int ret)
118 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
119 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
121 r->req.aiocb = NULL;
122 s->driver_status = r->io_header.driver_status;
123 if (s->driver_status & SG_ERR_DRIVER_SENSE)
124 s->senselen = r->io_header.sb_len_wr;
126 if (ret != 0) {
127 switch (ret) {
128 case -EDOM:
129 r->req.status = TASK_SET_FULL;
130 break;
131 case -EINVAL:
132 r->req.status = CHECK_CONDITION;
133 scsi_set_sense(s, SENSE_CODE(INVALID_FIELD));
134 break;
135 case -ENOMEM:
136 r->req.status = CHECK_CONDITION;
137 scsi_set_sense(s, SENSE_CODE(TARGET_FAILURE));
138 break;
139 default:
140 r->req.status = CHECK_CONDITION;
141 scsi_set_sense(s, SENSE_CODE(IO_ERROR));
142 break;
144 } else {
145 if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
146 r->req.status = BUSY;
147 BADF("Driver Timeout\n");
148 } else if (r->io_header.status)
149 r->req.status = r->io_header.status;
150 else if (s->driver_status & SG_ERR_DRIVER_SENSE)
151 r->req.status = CHECK_CONDITION;
152 else
153 r->req.status = GOOD;
155 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
156 r, r->req.tag, r->req.status);
158 scsi_req_complete(&r->req);
161 /* Cancel a pending data transfer. */
162 static void scsi_cancel_io(SCSIRequest *req)
164 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
166 DPRINTF("Cancel tag=0x%x\n", req->tag);
167 if (r->req.aiocb) {
168 bdrv_aio_cancel(r->req.aiocb);
170 r->req.aiocb = NULL;
173 static int execute_command(BlockDriverState *bdrv,
174 SCSIGenericReq *r, int direction,
175 BlockDriverCompletionFunc *complete)
177 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
179 r->io_header.interface_id = 'S';
180 r->io_header.dxfer_direction = direction;
181 r->io_header.dxferp = r->buf;
182 r->io_header.dxfer_len = r->buflen;
183 r->io_header.cmdp = r->req.cmd.buf;
184 r->io_header.cmd_len = r->req.cmd.len;
185 r->io_header.mx_sb_len = sizeof(s->sensebuf);
186 r->io_header.sbp = s->sensebuf;
187 r->io_header.timeout = MAX_UINT;
188 r->io_header.usr_ptr = r;
189 r->io_header.flags |= SG_FLAG_DIRECT_IO;
191 r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
192 if (r->req.aiocb == NULL) {
193 BADF("execute_command: read failed !\n");
194 return -ENOMEM;
197 return 0;
200 static void scsi_read_complete(void * opaque, int ret)
202 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
203 int len;
205 r->req.aiocb = NULL;
206 if (ret) {
207 DPRINTF("IO error ret %d\n", ret);
208 scsi_command_complete(r, ret);
209 return;
211 len = r->io_header.dxfer_len - r->io_header.resid;
212 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
214 r->len = -1;
215 if (len == 0) {
216 scsi_command_complete(r, 0);
217 } else {
218 scsi_req_data(&r->req, len);
222 /* Read more data from scsi device into buffer. */
223 static void scsi_read_data(SCSIRequest *req)
225 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
226 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
227 int ret;
229 DPRINTF("scsi_read_data 0x%x\n", req->tag);
230 if (r->len == -1) {
231 scsi_command_complete(r, 0);
232 return;
235 if (r->req.cmd.buf[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
237 s->senselen = MIN(r->len, s->senselen);
238 memcpy(r->buf, s->sensebuf, s->senselen);
239 r->io_header.driver_status = 0;
240 r->io_header.status = 0;
241 r->io_header.dxfer_len = s->senselen;
242 r->len = -1;
243 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, s->senselen);
244 DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
245 r->buf[0], r->buf[1], r->buf[2], r->buf[3],
246 r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
247 scsi_req_data(&r->req, s->senselen);
248 /* Clear sensebuf after REQUEST_SENSE */
249 scsi_clear_sense(s);
250 return;
253 ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
254 if (ret < 0) {
255 scsi_command_complete(r, ret);
256 return;
260 static void scsi_write_complete(void * opaque, int ret)
262 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
263 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
265 DPRINTF("scsi_write_complete() ret = %d\n", ret);
266 r->req.aiocb = NULL;
267 if (ret) {
268 DPRINTF("IO error\n");
269 scsi_command_complete(r, ret);
270 return;
273 if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
274 s->qdev.type == TYPE_TAPE) {
275 s->qdev.blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
276 DPRINTF("block size %d\n", s->qdev.blocksize);
279 scsi_command_complete(r, ret);
282 /* Write data to a scsi device. Returns nonzero on failure.
283 The transfer may complete asynchronously. */
284 static void scsi_write_data(SCSIRequest *req)
286 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
287 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
288 int ret;
290 DPRINTF("scsi_write_data 0x%x\n", req->tag);
291 if (r->len == 0) {
292 r->len = r->buflen;
293 scsi_req_data(&r->req, r->len);
294 return;
297 ret = execute_command(s->bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
298 if (ret < 0) {
299 scsi_command_complete(r, ret);
303 /* Return a pointer to the data buffer. */
304 static uint8_t *scsi_get_buf(SCSIRequest *req)
306 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
308 return r->buf;
311 static void scsi_req_fixup(SCSIRequest *req)
313 switch(req->cmd.buf[0]) {
314 case WRITE_10:
315 req->cmd.buf[1] &= ~0x08; /* disable FUA */
316 break;
317 case READ_10:
318 req->cmd.buf[1] &= ~0x08; /* disable FUA */
319 break;
320 case REWIND:
321 case START_STOP:
322 if (req->dev->type == TYPE_TAPE) {
323 /* force IMMED, otherwise qemu waits end of command */
324 req->cmd.buf[1] = 0x01;
326 break;
330 /* Execute a scsi command. Returns the length of the data expected by the
331 command. This will be Positive for data transfers from the device
332 (eg. disk reads), negative for transfers to the device (eg. disk writes),
333 and zero if the command does not transfer any data. */
335 static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
337 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
338 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
339 int ret;
341 if (cmd[0] != REQUEST_SENSE && req->lun != s->lun) {
342 DPRINTF("Unimplemented LUN %d\n", req->lun);
343 scsi_set_sense(s, SENSE_CODE(LUN_NOT_SUPPORTED));
344 r->req.status = CHECK_CONDITION;
345 scsi_req_complete(&r->req);
346 return 0;
349 if (-1 == scsi_req_parse(&r->req, cmd)) {
350 BADF("Unsupported command length, command %x\n", cmd[0]);
351 scsi_command_complete(r, -EINVAL);
352 return 0;
354 scsi_req_fixup(&r->req);
356 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun, tag,
357 r->req.cmd.xfer, cmd[0]);
359 #ifdef DEBUG_SCSI
361 int i;
362 for (i = 1; i < r->req.cmd.len; i++) {
363 printf(" 0x%02x", cmd[i]);
365 printf("\n");
367 #endif
369 if (r->req.cmd.xfer == 0) {
370 if (r->buf != NULL)
371 qemu_free(r->buf);
372 r->buflen = 0;
373 r->buf = NULL;
374 ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);
375 if (ret < 0) {
376 scsi_command_complete(r, ret);
377 return 0;
379 return 0;
382 if (r->buflen != r->req.cmd.xfer) {
383 if (r->buf != NULL)
384 qemu_free(r->buf);
385 r->buf = qemu_malloc(r->req.cmd.xfer);
386 r->buflen = r->req.cmd.xfer;
389 memset(r->buf, 0, r->buflen);
390 r->len = r->req.cmd.xfer;
391 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
392 r->len = 0;
393 return -r->req.cmd.xfer;
394 } else {
395 return r->req.cmd.xfer;
399 static int get_blocksize(BlockDriverState *bdrv)
401 uint8_t cmd[10];
402 uint8_t buf[8];
403 uint8_t sensebuf[8];
404 sg_io_hdr_t io_header;
405 int ret;
407 memset(cmd, 0, sizeof(cmd));
408 memset(buf, 0, sizeof(buf));
409 cmd[0] = READ_CAPACITY;
411 memset(&io_header, 0, sizeof(io_header));
412 io_header.interface_id = 'S';
413 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
414 io_header.dxfer_len = sizeof(buf);
415 io_header.dxferp = buf;
416 io_header.cmdp = cmd;
417 io_header.cmd_len = sizeof(cmd);
418 io_header.mx_sb_len = sizeof(sensebuf);
419 io_header.sbp = sensebuf;
420 io_header.timeout = 6000; /* XXX */
422 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
423 if (ret < 0)
424 return -1;
426 return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
429 static int get_stream_blocksize(BlockDriverState *bdrv)
431 uint8_t cmd[6];
432 uint8_t buf[12];
433 uint8_t sensebuf[8];
434 sg_io_hdr_t io_header;
435 int ret;
437 memset(cmd, 0, sizeof(cmd));
438 memset(buf, 0, sizeof(buf));
439 cmd[0] = MODE_SENSE;
440 cmd[4] = sizeof(buf);
442 memset(&io_header, 0, sizeof(io_header));
443 io_header.interface_id = 'S';
444 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
445 io_header.dxfer_len = sizeof(buf);
446 io_header.dxferp = buf;
447 io_header.cmdp = cmd;
448 io_header.cmd_len = sizeof(cmd);
449 io_header.mx_sb_len = sizeof(sensebuf);
450 io_header.sbp = sensebuf;
451 io_header.timeout = 6000; /* XXX */
453 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
454 if (ret < 0)
455 return -1;
457 return (buf[9] << 16) | (buf[10] << 8) | buf[11];
460 static void scsi_generic_reset(DeviceState *dev)
462 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev.qdev, dev);
464 scsi_device_purge_requests(&s->qdev);
467 static void scsi_destroy(SCSIDevice *d)
469 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
471 scsi_device_purge_requests(&s->qdev);
472 blockdev_mark_auto_del(s->qdev.conf.bs);
475 static int scsi_generic_initfn(SCSIDevice *dev)
477 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
478 int sg_version;
479 struct sg_scsi_id scsiid;
481 if (!s->qdev.conf.bs) {
482 error_report("scsi-generic: drive property not set");
483 return -1;
485 s->bs = s->qdev.conf.bs;
487 /* check we are really using a /dev/sg* file */
488 if (!bdrv_is_sg(s->bs)) {
489 error_report("scsi-generic: not /dev/sg*");
490 return -1;
493 if (bdrv_get_on_error(s->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
494 error_report("Device doesn't support drive option werror");
495 return -1;
497 if (bdrv_get_on_error(s->bs, 1) != BLOCK_ERR_REPORT) {
498 error_report("Device doesn't support drive option rerror");
499 return -1;
502 /* check we are using a driver managing SG_IO (version 3 and after */
503 if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
504 sg_version < 30000) {
505 error_report("scsi-generic: scsi generic interface too old");
506 return -1;
509 /* get LUN of the /dev/sg? */
510 if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
511 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
512 return -1;
515 /* define device state */
516 s->lun = scsiid.lun;
517 DPRINTF("LUN %d\n", s->lun);
518 s->qdev.type = scsiid.scsi_type;
519 DPRINTF("device type %d\n", s->qdev.type);
520 if (s->qdev.type == TYPE_TAPE) {
521 s->qdev.blocksize = get_stream_blocksize(s->bs);
522 if (s->qdev.blocksize == -1)
523 s->qdev.blocksize = 0;
524 } else {
525 s->qdev.blocksize = get_blocksize(s->bs);
526 /* removable media returns 0 if not present */
527 if (s->qdev.blocksize <= 0) {
528 if (s->qdev.type == TYPE_ROM || s->qdev.type == TYPE_WORM)
529 s->qdev.blocksize = 2048;
530 else
531 s->qdev.blocksize = 512;
534 DPRINTF("block size %d\n", s->qdev.blocksize);
535 s->driver_status = 0;
536 memset(s->sensebuf, 0, sizeof(s->sensebuf));
537 bdrv_set_removable(s->bs, 0);
538 return 0;
541 static SCSIDeviceInfo scsi_generic_info = {
542 .qdev.name = "scsi-generic",
543 .qdev.desc = "pass through generic scsi device (/dev/sg*)",
544 .qdev.size = sizeof(SCSIGenericState),
545 .qdev.reset = scsi_generic_reset,
546 .init = scsi_generic_initfn,
547 .destroy = scsi_destroy,
548 .alloc_req = scsi_new_request,
549 .free_req = scsi_free_request,
550 .send_command = scsi_send_command,
551 .read_data = scsi_read_data,
552 .write_data = scsi_write_data,
553 .cancel_io = scsi_cancel_io,
554 .get_buf = scsi_get_buf,
555 .get_sense = scsi_get_sense,
556 .qdev.props = (Property[]) {
557 DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf),
558 DEFINE_PROP_END_OF_LIST(),
562 static void scsi_generic_register_devices(void)
564 scsi_qdev_register(&scsi_generic_info);
566 device_init(scsi_generic_register_devices)
568 #endif /* __linux__ */