]> git.proxmox.com Git - qemu.git/blob - hw/scsi-generic.c
scsi: introduce scsi_req_data
[qemu.git] / hw / scsi-generic.c
1 /*
2 * Generic SCSI Device support
3 *
4 * Copyright (c) 2007 Bull S.A.S.
5 * Based on code by Paul Brook
6 * Based on code by Fabrice Bellard
7 *
8 * Written by Laurent Vivier <Laurent.Vivier@bull.net>
9 *
10 * This code is licenced under the LGPL.
11 *
12 */
13
14 #include "qemu-common.h"
15 #include "qemu-error.h"
16 #include "scsi.h"
17 #include "blockdev.h"
18
19 #ifdef __linux__
20
21 //#define DEBUG_SCSI
22
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
29
30 #define BADF(fmt, ...) \
31 do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
32
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"
39
40 #define SCSI_SENSE_BUF_SIZE 96
41
42 #define SG_ERR_DRIVER_TIMEOUT 0x06
43 #define SG_ERR_DRIVER_SENSE 0x08
44
45 #ifndef MAX_UINT
46 #define MAX_UINT ((unsigned int)-1)
47 #endif
48
49 typedef struct SCSIGenericState SCSIGenericState;
50
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;
58
59 struct SCSIGenericState
60 {
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;
67 };
68
69 static SCSIGenericReq *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
70 {
71 SCSIRequest *req;
72
73 req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun);
74 return DO_UPCAST(SCSIGenericReq, req, req);
75 }
76
77 static void scsi_remove_request(SCSIGenericReq *r)
78 {
79 qemu_free(r->buf);
80 scsi_req_free(&r->req);
81 }
82
83 static SCSIGenericReq *scsi_find_request(SCSIGenericState *s, uint32_t tag)
84 {
85 return DO_UPCAST(SCSIGenericReq, req, scsi_req_find(&s->qdev, tag));
86 }
87
88 /* Helper function for command completion. */
89 static void scsi_command_complete(void *opaque, int ret)
90 {
91 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
92 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
93
94 s->driver_status = r->io_header.driver_status;
95 if (s->driver_status & SG_ERR_DRIVER_SENSE)
96 s->senselen = r->io_header.sb_len_wr;
97
98 if (ret != 0)
99 r->req.status = BUSY;
100 else {
101 if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
102 r->req.status = BUSY;
103 BADF("Driver Timeout\n");
104 } else if (r->io_header.status)
105 r->req.status = r->io_header.status;
106 else if (s->driver_status & SG_ERR_DRIVER_SENSE)
107 r->req.status = CHECK_CONDITION;
108 else
109 r->req.status = GOOD;
110 }
111 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
112 r, r->req.tag, r->req.status);
113
114 scsi_req_complete(&r->req);
115 scsi_remove_request(r);
116 }
117
118 /* Cancel a pending data transfer. */
119 static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
120 {
121 DPRINTF("scsi_cancel_io 0x%x\n", tag);
122 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
123 SCSIGenericReq *r;
124 DPRINTF("Cancel tag=0x%x\n", tag);
125 r = scsi_find_request(s, tag);
126 if (r) {
127 if (r->req.aiocb)
128 bdrv_aio_cancel(r->req.aiocb);
129 r->req.aiocb = NULL;
130 scsi_remove_request(r);
131 }
132 }
133
134 static int execute_command(BlockDriverState *bdrv,
135 SCSIGenericReq *r, int direction,
136 BlockDriverCompletionFunc *complete)
137 {
138 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
139
140 r->io_header.interface_id = 'S';
141 r->io_header.dxfer_direction = direction;
142 r->io_header.dxferp = r->buf;
143 r->io_header.dxfer_len = r->buflen;
144 r->io_header.cmdp = r->req.cmd.buf;
145 r->io_header.cmd_len = r->req.cmd.len;
146 r->io_header.mx_sb_len = sizeof(s->sensebuf);
147 r->io_header.sbp = s->sensebuf;
148 r->io_header.timeout = MAX_UINT;
149 r->io_header.usr_ptr = r;
150 r->io_header.flags |= SG_FLAG_DIRECT_IO;
151
152 r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
153 if (r->req.aiocb == NULL) {
154 BADF("execute_command: read failed !\n");
155 return -1;
156 }
157
158 return 0;
159 }
160
161 static void scsi_read_complete(void * opaque, int ret)
162 {
163 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
164 int len;
165
166 if (ret) {
167 DPRINTF("IO error ret %d\n", ret);
168 scsi_command_complete(r, ret);
169 return;
170 }
171 len = r->io_header.dxfer_len - r->io_header.resid;
172 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
173
174 r->len = -1;
175 if (len == 0) {
176 scsi_command_complete(r, 0);
177 } else {
178 scsi_req_data(&r->req, len);
179 }
180 }
181
182 /* Read more data from scsi device into buffer. */
183 static void scsi_read_data(SCSIDevice *d, uint32_t tag)
184 {
185 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
186 SCSIGenericReq *r;
187 int ret;
188
189 DPRINTF("scsi_read_data 0x%x\n", tag);
190 r = scsi_find_request(s, tag);
191 if (!r) {
192 BADF("Bad read tag 0x%x\n", tag);
193 /* ??? This is the wrong error. */
194 scsi_command_complete(r, -EINVAL);
195 return;
196 }
197
198 if (r->len == -1) {
199 scsi_command_complete(r, 0);
200 return;
201 }
202
203 if (r->req.cmd.buf[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
204 {
205 s->senselen = MIN(r->len, s->senselen);
206 memcpy(r->buf, s->sensebuf, s->senselen);
207 r->io_header.driver_status = 0;
208 r->io_header.status = 0;
209 r->io_header.dxfer_len = s->senselen;
210 r->len = -1;
211 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, s->senselen);
212 DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
213 r->buf[0], r->buf[1], r->buf[2], r->buf[3],
214 r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
215 scsi_req_data(&r->req, s->senselen);
216 return;
217 }
218
219 ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
220 if (ret == -1) {
221 scsi_command_complete(r, -EINVAL);
222 return;
223 }
224 }
225
226 static void scsi_write_complete(void * opaque, int ret)
227 {
228 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
229 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
230
231 DPRINTF("scsi_write_complete() ret = %d\n", ret);
232 if (ret) {
233 DPRINTF("IO error\n");
234 scsi_command_complete(r, ret);
235 return;
236 }
237
238 if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
239 s->qdev.type == TYPE_TAPE) {
240 s->qdev.blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
241 DPRINTF("block size %d\n", s->qdev.blocksize);
242 }
243
244 scsi_command_complete(r, ret);
245 }
246
247 /* Write data to a scsi device. Returns nonzero on failure.
248 The transfer may complete asynchronously. */
249 static int scsi_write_data(SCSIDevice *d, uint32_t tag)
250 {
251 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
252 SCSIGenericReq *r;
253 int ret;
254
255 DPRINTF("scsi_write_data 0x%x\n", tag);
256 r = scsi_find_request(s, tag);
257 if (!r) {
258 BADF("Bad write tag 0x%x\n", tag);
259 /* ??? This is the wrong error. */
260 scsi_command_complete(r, -EINVAL);
261 return 0;
262 }
263
264 if (r->len == 0) {
265 r->len = r->buflen;
266 scsi_req_data(&r->req, r->len);
267 return 0;
268 }
269
270 ret = execute_command(s->bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
271 if (ret == -1) {
272 scsi_command_complete(r, -EINVAL);
273 return 1;
274 }
275
276 return 0;
277 }
278
279 /* Return a pointer to the data buffer. */
280 static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
281 {
282 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
283 SCSIGenericReq *r;
284 r = scsi_find_request(s, tag);
285 if (!r) {
286 BADF("Bad buffer tag 0x%x\n", tag);
287 return NULL;
288 }
289 return r->buf;
290 }
291
292 static void scsi_req_fixup(SCSIRequest *req)
293 {
294 switch(req->cmd.buf[0]) {
295 case WRITE_10:
296 req->cmd.buf[1] &= ~0x08; /* disable FUA */
297 break;
298 case READ_10:
299 req->cmd.buf[1] &= ~0x08; /* disable FUA */
300 break;
301 case REWIND:
302 case START_STOP:
303 if (req->dev->type == TYPE_TAPE) {
304 /* force IMMED, otherwise qemu waits end of command */
305 req->cmd.buf[1] = 0x01;
306 }
307 break;
308 }
309 }
310
311 /* Execute a scsi command. Returns the length of the data expected by the
312 command. This will be Positive for data transfers from the device
313 (eg. disk reads), negative for transfers to the device (eg. disk writes),
314 and zero if the command does not transfer any data. */
315
316 static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
317 uint8_t *cmd, int lun)
318 {
319 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
320 SCSIGenericReq *r;
321 SCSIBus *bus;
322 int ret;
323
324 if (cmd[0] != REQUEST_SENSE &&
325 (lun != s->lun || (cmd[1] >> 5) != s->lun)) {
326 DPRINTF("Unimplemented LUN %d\n", lun ? lun : cmd[1] >> 5);
327
328 s->sensebuf[0] = 0x70;
329 s->sensebuf[1] = 0x00;
330 s->sensebuf[2] = ILLEGAL_REQUEST;
331 s->sensebuf[3] = 0x00;
332 s->sensebuf[4] = 0x00;
333 s->sensebuf[5] = 0x00;
334 s->sensebuf[6] = 0x00;
335 s->senselen = 7;
336 s->driver_status = SG_ERR_DRIVER_SENSE;
337 bus = scsi_bus_from_device(d);
338 bus->complete(bus, SCSI_REASON_DONE, tag, CHECK_CONDITION);
339 return 0;
340 }
341
342 r = scsi_find_request(s, tag);
343 if (r) {
344 BADF("Tag 0x%x already in use %p\n", tag, r);
345 scsi_cancel_io(d, tag);
346 }
347 r = scsi_new_request(d, tag, lun);
348
349 if (-1 == scsi_req_parse(&r->req, cmd)) {
350 BADF("Unsupported command length, command %x\n", cmd[0]);
351 scsi_remove_request(r);
352 return 0;
353 }
354 scsi_req_fixup(&r->req);
355
356 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun, tag,
357 r->req.cmd.xfer, cmd[0]);
358
359 #ifdef DEBUG_SCSI
360 {
361 int i;
362 for (i = 1; i < r->req.cmd.len; i++) {
363 printf(" 0x%02x", cmd[i]);
364 }
365 printf("\n");
366 }
367 #endif
368
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 == -1) {
376 scsi_command_complete(r, -EINVAL);
377 return 0;
378 }
379 return 0;
380 }
381
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;
387 }
388
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 }
395
396 return r->req.cmd.xfer;
397 }
398
399 static int get_blocksize(BlockDriverState *bdrv)
400 {
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;
406
407 memset(cmd, 0, sizeof(cmd));
408 memset(buf, 0, sizeof(buf));
409 cmd[0] = READ_CAPACITY;
410
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 */
421
422 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
423 if (ret < 0)
424 return -1;
425
426 return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
427 }
428
429 static int get_stream_blocksize(BlockDriverState *bdrv)
430 {
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;
436
437 memset(cmd, 0, sizeof(cmd));
438 memset(buf, 0, sizeof(buf));
439 cmd[0] = MODE_SENSE;
440 cmd[4] = sizeof(buf);
441
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 */
452
453 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
454 if (ret < 0)
455 return -1;
456
457 return (buf[9] << 16) | (buf[10] << 8) | buf[11];
458 }
459
460 static void scsi_generic_purge_requests(SCSIGenericState *s)
461 {
462 SCSIGenericReq *r;
463
464 while (!QTAILQ_EMPTY(&s->qdev.requests)) {
465 r = DO_UPCAST(SCSIGenericReq, req, QTAILQ_FIRST(&s->qdev.requests));
466 if (r->req.aiocb) {
467 bdrv_aio_cancel(r->req.aiocb);
468 }
469 scsi_remove_request(r);
470 }
471 }
472
473 static void scsi_generic_reset(DeviceState *dev)
474 {
475 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev.qdev, dev);
476
477 scsi_generic_purge_requests(s);
478 }
479
480 static void scsi_destroy(SCSIDevice *d)
481 {
482 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
483
484 scsi_generic_purge_requests(s);
485 blockdev_mark_auto_del(s->qdev.conf.bs);
486 }
487
488 static int scsi_generic_initfn(SCSIDevice *dev)
489 {
490 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
491 int sg_version;
492 struct sg_scsi_id scsiid;
493
494 if (!s->qdev.conf.bs) {
495 error_report("scsi-generic: drive property not set");
496 return -1;
497 }
498 s->bs = s->qdev.conf.bs;
499
500 /* check we are really using a /dev/sg* file */
501 if (!bdrv_is_sg(s->bs)) {
502 error_report("scsi-generic: not /dev/sg*");
503 return -1;
504 }
505
506 if (bdrv_get_on_error(s->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
507 error_report("Device doesn't support drive option werror");
508 return -1;
509 }
510 if (bdrv_get_on_error(s->bs, 1) != BLOCK_ERR_REPORT) {
511 error_report("Device doesn't support drive option rerror");
512 return -1;
513 }
514
515 /* check we are using a driver managing SG_IO (version 3 and after */
516 if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
517 sg_version < 30000) {
518 error_report("scsi-generic: scsi generic interface too old");
519 return -1;
520 }
521
522 /* get LUN of the /dev/sg? */
523 if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
524 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
525 return -1;
526 }
527
528 /* define device state */
529 s->lun = scsiid.lun;
530 DPRINTF("LUN %d\n", s->lun);
531 s->qdev.type = scsiid.scsi_type;
532 DPRINTF("device type %d\n", s->qdev.type);
533 if (s->qdev.type == TYPE_TAPE) {
534 s->qdev.blocksize = get_stream_blocksize(s->bs);
535 if (s->qdev.blocksize == -1)
536 s->qdev.blocksize = 0;
537 } else {
538 s->qdev.blocksize = get_blocksize(s->bs);
539 /* removable media returns 0 if not present */
540 if (s->qdev.blocksize <= 0) {
541 if (s->qdev.type == TYPE_ROM || s->qdev.type == TYPE_WORM)
542 s->qdev.blocksize = 2048;
543 else
544 s->qdev.blocksize = 512;
545 }
546 }
547 DPRINTF("block size %d\n", s->qdev.blocksize);
548 s->driver_status = 0;
549 memset(s->sensebuf, 0, sizeof(s->sensebuf));
550 bdrv_set_removable(s->bs, 0);
551 return 0;
552 }
553
554 static SCSIDeviceInfo scsi_generic_info = {
555 .qdev.name = "scsi-generic",
556 .qdev.desc = "pass through generic scsi device (/dev/sg*)",
557 .qdev.size = sizeof(SCSIGenericState),
558 .qdev.reset = scsi_generic_reset,
559 .init = scsi_generic_initfn,
560 .destroy = scsi_destroy,
561 .send_command = scsi_send_command,
562 .read_data = scsi_read_data,
563 .write_data = scsi_write_data,
564 .cancel_io = scsi_cancel_io,
565 .get_buf = scsi_get_buf,
566 .qdev.props = (Property[]) {
567 DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf),
568 DEFINE_PROP_END_OF_LIST(),
569 },
570 };
571
572 static void scsi_generic_register_devices(void)
573 {
574 scsi_qdev_register(&scsi_generic_info);
575 }
576 device_init(scsi_generic_register_devices)
577
578 #endif /* __linux__ */