]> git.proxmox.com Git - qemu.git/blob - hw/scsi-generic.c
Rearrange block headers
[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 << 1;
100 else {
101 if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
102 r->req.status = BUSY << 1;
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 << 1;
108 else
109 r->req.status = GOOD << 1;
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\n");
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 r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, len);
176 if (len == 0)
177 scsi_command_complete(r, 0);
178 }
179
180 /* Read more data from scsi device into buffer. */
181 static void scsi_read_data(SCSIDevice *d, uint32_t tag)
182 {
183 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
184 SCSIGenericReq *r;
185 int ret;
186
187 DPRINTF("scsi_read_data 0x%x\n", tag);
188 r = scsi_find_request(s, tag);
189 if (!r) {
190 BADF("Bad read tag 0x%x\n", tag);
191 /* ??? This is the wrong error. */
192 scsi_command_complete(r, -EINVAL);
193 return;
194 }
195
196 if (r->len == -1) {
197 scsi_command_complete(r, 0);
198 return;
199 }
200
201 if (r->req.cmd.buf[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
202 {
203 s->senselen = MIN(r->len, s->senselen);
204 memcpy(r->buf, s->sensebuf, s->senselen);
205 r->io_header.driver_status = 0;
206 r->io_header.status = 0;
207 r->io_header.dxfer_len = s->senselen;
208 r->len = -1;
209 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, s->senselen);
210 DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
211 r->buf[0], r->buf[1], r->buf[2], r->buf[3],
212 r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
213 r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, s->senselen);
214 return;
215 }
216
217 ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
218 if (ret == -1) {
219 scsi_command_complete(r, -EINVAL);
220 return;
221 }
222 }
223
224 static void scsi_write_complete(void * opaque, int ret)
225 {
226 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
227 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
228
229 DPRINTF("scsi_write_complete() ret = %d\n", ret);
230 if (ret) {
231 DPRINTF("IO error\n");
232 scsi_command_complete(r, ret);
233 return;
234 }
235
236 if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
237 s->qdev.type == TYPE_TAPE) {
238 s->qdev.blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
239 DPRINTF("block size %d\n", s->blocksize);
240 }
241
242 scsi_command_complete(r, ret);
243 }
244
245 /* Write data to a scsi device. Returns nonzero on failure.
246 The transfer may complete asynchronously. */
247 static int scsi_write_data(SCSIDevice *d, uint32_t tag)
248 {
249 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
250 SCSIGenericReq *r;
251 int ret;
252
253 DPRINTF("scsi_write_data 0x%x\n", tag);
254 r = scsi_find_request(s, tag);
255 if (!r) {
256 BADF("Bad write tag 0x%x\n", tag);
257 /* ??? This is the wrong error. */
258 scsi_command_complete(r, -EINVAL);
259 return 0;
260 }
261
262 if (r->len == 0) {
263 r->len = r->buflen;
264 r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, r->len);
265 return 0;
266 }
267
268 ret = execute_command(s->bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
269 if (ret == -1) {
270 scsi_command_complete(r, -EINVAL);
271 return 1;
272 }
273
274 return 0;
275 }
276
277 /* Return a pointer to the data buffer. */
278 static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
279 {
280 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
281 SCSIGenericReq *r;
282 r = scsi_find_request(s, tag);
283 if (!r) {
284 BADF("Bad buffer tag 0x%x\n", tag);
285 return NULL;
286 }
287 return r->buf;
288 }
289
290 static void scsi_req_fixup(SCSIRequest *req)
291 {
292 switch(req->cmd.buf[0]) {
293 case WRITE_10:
294 req->cmd.buf[1] &= ~0x08; /* disable FUA */
295 break;
296 case READ_10:
297 req->cmd.buf[1] &= ~0x08; /* disable FUA */
298 break;
299 case REWIND:
300 case START_STOP:
301 if (req->dev->type == TYPE_TAPE) {
302 /* force IMMED, otherwise qemu waits end of command */
303 req->cmd.buf[1] = 0x01;
304 }
305 break;
306 }
307 }
308
309 /* Execute a scsi command. Returns the length of the data expected by the
310 command. This will be Positive for data transfers from the device
311 (eg. disk reads), negative for transfers to the device (eg. disk writes),
312 and zero if the command does not transfer any data. */
313
314 static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
315 uint8_t *cmd, int lun)
316 {
317 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
318 SCSIGenericReq *r;
319 SCSIBus *bus;
320 int ret;
321
322 if (cmd[0] != REQUEST_SENSE &&
323 (lun != s->lun || (cmd[1] >> 5) != s->lun)) {
324 DPRINTF("Unimplemented LUN %d\n", lun ? lun : cmd[1] >> 5);
325
326 s->sensebuf[0] = 0x70;
327 s->sensebuf[1] = 0x00;
328 s->sensebuf[2] = ILLEGAL_REQUEST;
329 s->sensebuf[3] = 0x00;
330 s->sensebuf[4] = 0x00;
331 s->sensebuf[5] = 0x00;
332 s->sensebuf[6] = 0x00;
333 s->senselen = 7;
334 s->driver_status = SG_ERR_DRIVER_SENSE;
335 bus = scsi_bus_from_device(d);
336 bus->complete(bus, SCSI_REASON_DONE, tag, CHECK_CONDITION << 1);
337 return 0;
338 }
339
340 r = scsi_find_request(s, tag);
341 if (r) {
342 BADF("Tag 0x%x already in use %p\n", tag, r);
343 scsi_cancel_io(d, tag);
344 }
345 r = scsi_new_request(d, tag, lun);
346
347 if (-1 == scsi_req_parse(&r->req, cmd)) {
348 BADF("Unsupported command length, command %x\n", cmd[0]);
349 scsi_remove_request(r);
350 return 0;
351 }
352 scsi_req_fixup(&r->req);
353
354 DPRINTF("Command: lun=%d tag=0x%x data=0x%02x len %d\n", lun, tag,
355 cmd[0], r->req.cmd.xfer);
356
357 if (r->req.cmd.xfer == 0) {
358 if (r->buf != NULL)
359 qemu_free(r->buf);
360 r->buflen = 0;
361 r->buf = NULL;
362 ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);
363 if (ret == -1) {
364 scsi_command_complete(r, -EINVAL);
365 return 0;
366 }
367 return 0;
368 }
369
370 if (r->buflen != r->req.cmd.xfer) {
371 if (r->buf != NULL)
372 qemu_free(r->buf);
373 r->buf = qemu_malloc(r->req.cmd.xfer);
374 r->buflen = r->req.cmd.xfer;
375 }
376
377 memset(r->buf, 0, r->buflen);
378 r->len = r->req.cmd.xfer;
379 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
380 r->len = 0;
381 return -r->req.cmd.xfer;
382 }
383
384 return r->req.cmd.xfer;
385 }
386
387 static int get_blocksize(BlockDriverState *bdrv)
388 {
389 uint8_t cmd[10];
390 uint8_t buf[8];
391 uint8_t sensebuf[8];
392 sg_io_hdr_t io_header;
393 int ret;
394
395 memset(cmd, 0, sizeof(cmd));
396 memset(buf, 0, sizeof(buf));
397 cmd[0] = READ_CAPACITY;
398
399 memset(&io_header, 0, sizeof(io_header));
400 io_header.interface_id = 'S';
401 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
402 io_header.dxfer_len = sizeof(buf);
403 io_header.dxferp = buf;
404 io_header.cmdp = cmd;
405 io_header.cmd_len = sizeof(cmd);
406 io_header.mx_sb_len = sizeof(sensebuf);
407 io_header.sbp = sensebuf;
408 io_header.timeout = 6000; /* XXX */
409
410 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
411 if (ret < 0)
412 return -1;
413
414 return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
415 }
416
417 static int get_stream_blocksize(BlockDriverState *bdrv)
418 {
419 uint8_t cmd[6];
420 uint8_t buf[12];
421 uint8_t sensebuf[8];
422 sg_io_hdr_t io_header;
423 int ret;
424
425 memset(cmd, 0, sizeof(cmd));
426 memset(buf, 0, sizeof(buf));
427 cmd[0] = MODE_SENSE;
428 cmd[4] = sizeof(buf);
429
430 memset(&io_header, 0, sizeof(io_header));
431 io_header.interface_id = 'S';
432 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
433 io_header.dxfer_len = sizeof(buf);
434 io_header.dxferp = buf;
435 io_header.cmdp = cmd;
436 io_header.cmd_len = sizeof(cmd);
437 io_header.mx_sb_len = sizeof(sensebuf);
438 io_header.sbp = sensebuf;
439 io_header.timeout = 6000; /* XXX */
440
441 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
442 if (ret < 0)
443 return -1;
444
445 return (buf[9] << 16) | (buf[10] << 8) | buf[11];
446 }
447
448 static void scsi_destroy(SCSIDevice *d)
449 {
450 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
451 SCSIGenericReq *r;
452
453 while (!QTAILQ_EMPTY(&s->qdev.requests)) {
454 r = DO_UPCAST(SCSIGenericReq, req, QTAILQ_FIRST(&s->qdev.requests));
455 scsi_remove_request(r);
456 }
457 blockdev_mark_auto_del(s->qdev.conf.bs);
458 }
459
460 static int scsi_generic_initfn(SCSIDevice *dev)
461 {
462 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
463 int sg_version;
464 struct sg_scsi_id scsiid;
465
466 if (!s->qdev.conf.bs) {
467 error_report("scsi-generic: drive property not set");
468 return -1;
469 }
470 s->bs = s->qdev.conf.bs;
471
472 /* check we are really using a /dev/sg* file */
473 if (!bdrv_is_sg(s->bs)) {
474 error_report("scsi-generic: not /dev/sg*");
475 return -1;
476 }
477
478 if (bdrv_get_on_error(s->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
479 error_report("Device doesn't support drive option werror");
480 return -1;
481 }
482 if (bdrv_get_on_error(s->bs, 1) != BLOCK_ERR_REPORT) {
483 error_report("Device doesn't support drive option rerror");
484 return -1;
485 }
486
487 /* check we are using a driver managing SG_IO (version 3 and after */
488 if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
489 sg_version < 30000) {
490 error_report("scsi-generic: scsi generic interface too old");
491 return -1;
492 }
493
494 /* get LUN of the /dev/sg? */
495 if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
496 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
497 return -1;
498 }
499
500 /* define device state */
501 s->lun = scsiid.lun;
502 DPRINTF("LUN %d\n", s->lun);
503 s->qdev.type = scsiid.scsi_type;
504 DPRINTF("device type %d\n", s->qdev.type);
505 if (s->qdev.type == TYPE_TAPE) {
506 s->qdev.blocksize = get_stream_blocksize(s->bs);
507 if (s->qdev.blocksize == -1)
508 s->qdev.blocksize = 0;
509 } else {
510 s->qdev.blocksize = get_blocksize(s->bs);
511 /* removable media returns 0 if not present */
512 if (s->qdev.blocksize <= 0) {
513 if (s->qdev.type == TYPE_ROM || s->qdev.type == TYPE_WORM)
514 s->qdev.blocksize = 2048;
515 else
516 s->qdev.blocksize = 512;
517 }
518 }
519 DPRINTF("block size %d\n", s->qdev.blocksize);
520 s->driver_status = 0;
521 memset(s->sensebuf, 0, sizeof(s->sensebuf));
522 bdrv_set_removable(s->bs, 0);
523 return 0;
524 }
525
526 static SCSIDeviceInfo scsi_generic_info = {
527 .qdev.name = "scsi-generic",
528 .qdev.desc = "pass through generic scsi device (/dev/sg*)",
529 .qdev.size = sizeof(SCSIGenericState),
530 .init = scsi_generic_initfn,
531 .destroy = scsi_destroy,
532 .send_command = scsi_send_command,
533 .read_data = scsi_read_data,
534 .write_data = scsi_write_data,
535 .cancel_io = scsi_cancel_io,
536 .get_buf = scsi_get_buf,
537 .qdev.props = (Property[]) {
538 DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf),
539 DEFINE_PROP_END_OF_LIST(),
540 },
541 };
542
543 static void scsi_generic_register_devices(void)
544 {
545 scsi_qdev_register(&scsi_generic_info);
546 }
547 device_init(scsi_generic_register_devices)
548
549 #endif /* __linux__ */