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