]> git.proxmox.com Git - qemu.git/blame - hw/scsi-generic.c
Optional "precise" VGA retrace support
[qemu.git] / hw / scsi-generic.c
CommitLineData
2cc977e2
TS
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 "block.h"
16#include "scsi-disk.h"
17
18#ifndef __linux__
19
20SCSIDevice *scsi_generic_init(BlockDriverState *bdrv, int tcq,
21 scsi_completionfn completion, void *opaque)
22{
23 return NULL;
24}
25
26#else /* __linux__ */
27
28//#define DEBUG_SCSI
29
30#ifdef DEBUG_SCSI
31#define DPRINTF(fmt, args...) \
32do { printf("scsi-generic: " fmt , ##args); } while (0)
33#else
34#define DPRINTF(fmt, args...) do {} while(0)
35#endif
36
37#define BADF(fmt, args...) \
38do { fprintf(stderr, "scsi-generic: " fmt , ##args); } while (0)
39
40#include <stdio.h>
41#include <sys/types.h>
42#include <sys/stat.h>
43#include <unistd.h>
44#include <scsi/sg.h>
45#include <scsi/scsi.h>
46
a9dd6843
AL
47#define REWIND 0x01
48#define REPORT_DENSITY_SUPPORT 0x44
2cc977e2
TS
49#define LOAD_UNLOAD 0xa6
50#define SET_CD_SPEED 0xbb
51#define BLANK 0xa1
52
53#define SCSI_CMD_BUF_SIZE 16
a9dd6843 54#define SCSI_SENSE_BUF_SIZE 96
2cc977e2
TS
55
56#define SG_ERR_DRIVER_TIMEOUT 0x06
57#define SG_ERR_DRIVER_SENSE 0x08
58
59#ifndef MAX_UINT
60#define MAX_UINT ((unsigned int)-1)
61#endif
62
63typedef struct SCSIRequest {
64 BlockDriverAIOCB *aiocb;
65 struct SCSIRequest *next;
66 SCSIDeviceState *dev;
67 uint32_t tag;
68 uint8_t cmd[SCSI_CMD_BUF_SIZE];
69 int cmdlen;
70 uint8_t *buf;
71 int buflen;
72 int len;
73 sg_io_hdr_t io_header;
74} SCSIRequest;
75
76struct SCSIDeviceState
77{
78 SCSIRequest *requests;
79 BlockDriverState *bdrv;
a9dd6843 80 int type;
2cc977e2
TS
81 int blocksize;
82 int lun;
83 scsi_completionfn completion;
84 void *opaque;
85 int driver_status;
86 uint8_t sensebuf[SCSI_SENSE_BUF_SIZE];
87};
88
89/* Global pool of SCSIRequest structures. */
90static SCSIRequest *free_requests = NULL;
91
92static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag)
93{
94 SCSIRequest *r;
95
96 if (free_requests) {
97 r = free_requests;
98 free_requests = r->next;
99 } else {
100 r = qemu_malloc(sizeof(SCSIRequest));
101 r->buf = NULL;
102 r->buflen = 0;
103 }
104 r->dev = s;
105 r->tag = tag;
106 memset(r->cmd, 0, sizeof(r->cmd));
107 memset(&r->io_header, 0, sizeof(r->io_header));
108 r->cmdlen = 0;
109 r->len = 0;
110 r->aiocb = NULL;
111
112 /* link */
113
114 r->next = s->requests;
115 s->requests = r;
116 return r;
117}
118
119static void scsi_remove_request(SCSIRequest *r)
120{
121 SCSIRequest *last;
122 SCSIDeviceState *s = r->dev;
123
124 if (s->requests == r) {
125 s->requests = r->next;
126 } else {
127 last = s->requests;
128 while (last && last->next != r)
129 last = last->next;
130 if (last) {
131 last->next = r->next;
132 } else {
133 BADF("Orphaned request\n");
134 }
135 }
136 r->next = free_requests;
137 free_requests = r;
138}
139
140static SCSIRequest *scsi_find_request(SCSIDeviceState *s, uint32_t tag)
141{
142 SCSIRequest *r;
143
144 r = s->requests;
145 while (r && r->tag != tag)
146 r = r->next;
147
148 return r;
149}
150
151/* Helper function for command completion. */
152static void scsi_command_complete(void *opaque, int ret)
153{
154 SCSIRequest *r = (SCSIRequest *)opaque;
155 SCSIDeviceState *s = r->dev;
156 uint32_t tag;
157 int sense;
158
159 s->driver_status = r->io_header.driver_status;
160 if (ret != 0)
161 sense = HARDWARE_ERROR;
162 else {
163 if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
164 sense = HARDWARE_ERROR;
165 BADF("Driver Timeout\n");
166 } else if ((s->driver_status & SG_ERR_DRIVER_SENSE) == 0)
167 sense = NO_SENSE;
168 else
a9dd6843 169 sense = s->sensebuf[2];
2cc977e2
TS
170 }
171
172 DPRINTF("Command complete 0x%p tag=0x%x sense=%d\n", r, r->tag, sense);
173 tag = r->tag;
174 scsi_remove_request(r);
175 s->completion(s->opaque, SCSI_REASON_DONE, tag, sense);
176}
177
178/* Cancel a pending data transfer. */
179static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
180{
181 DPRINTF("scsi_cancel_io 0x%x\n", tag);
182 SCSIDeviceState *s = d->state;
183 SCSIRequest *r;
184 DPRINTF("Cancel tag=0x%x\n", tag);
185 r = scsi_find_request(s, tag);
186 if (r) {
187 if (r->aiocb)
188 bdrv_aio_cancel(r->aiocb);
189 r->aiocb = NULL;
190 scsi_remove_request(r);
191 }
192}
193
194static int execute_command(BlockDriverState *bdrv,
195 SCSIRequest *r, int direction,
196 BlockDriverCompletionFunc *complete)
197{
198
199 r->io_header.interface_id = 'S';
200 r->io_header.dxfer_direction = direction;
201 r->io_header.dxferp = r->buf;
202 r->io_header.dxfer_len = r->buflen;
203 r->io_header.cmdp = r->cmd;
204 r->io_header.cmd_len = r->cmdlen;
205 r->io_header.mx_sb_len = sizeof(r->dev->sensebuf);
206 r->io_header.sbp = r->dev->sensebuf;
207 r->io_header.timeout = MAX_UINT;
208 r->io_header.usr_ptr = r;
209 r->io_header.flags |= SG_FLAG_DIRECT_IO;
210
211 if (bdrv_pwrite(bdrv, -1, &r->io_header, sizeof(r->io_header)) == -1) {
212 BADF("execute_command: write failed ! (%d)\n", errno);
213 return -1;
214 }
215 if (complete == NULL) {
216 int ret;
217 r->aiocb = NULL;
218 while ((ret = bdrv_pread(bdrv, -1, &r->io_header,
219 sizeof(r->io_header))) == -1 &&
220 errno == EINTR);
221 if (ret == -1) {
222 BADF("execute_command: read failed !\n");
223 return -1;
224 }
225 return 0;
226 }
227
228 r->aiocb = bdrv_aio_read(bdrv, 0, (uint8_t*)&r->io_header,
229 -(int64_t)sizeof(r->io_header), complete, r);
230 if (r->aiocb == NULL) {
231 BADF("execute_command: read failed !\n");
232 return -1;
233 }
234
235 return 0;
236}
237
238static void scsi_read_complete(void * opaque, int ret)
239{
240 SCSIRequest *r = (SCSIRequest *)opaque;
241 SCSIDeviceState *s = r->dev;
242 int len;
243
244 if (ret) {
245 DPRINTF("IO error\n");
246 scsi_command_complete(r, ret);
247 return;
248 }
249 len = r->io_header.dxfer_len - r->io_header.resid;
250 DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, len);
251
252 r->len = -1;
253 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, len);
254}
255
256/* Read more data from scsi device into buffer. */
257static void scsi_read_data(SCSIDevice *d, uint32_t tag)
258{
259 SCSIDeviceState *s = d->state;
260 SCSIRequest *r;
261 int ret;
262
263 DPRINTF("scsi_read_data 0x%x\n", tag);
264 r = scsi_find_request(s, tag);
265 if (!r) {
266 BADF("Bad read tag 0x%x\n", tag);
267 /* ??? This is the wrong error. */
268 scsi_command_complete(r, -EINVAL);
269 return;
270 }
271
272 if (r->len == -1) {
273 scsi_command_complete(r, 0);
274 return;
275 }
276
277 if (r->cmd[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
278 {
a9dd6843
AL
279 int len = MIN(r->len, SCSI_SENSE_BUF_SIZE);
280 memcpy(r->buf, s->sensebuf, len);
2cc977e2
TS
281 r->io_header.driver_status = 0;
282 r->len = -1;
a9dd6843
AL
283 DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
284 r->buf[0], r->buf[1], r->buf[2], r->buf[3],
285 r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
286 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, len);
2cc977e2
TS
287 return;
288 }
289
290 ret = execute_command(s->bdrv, r, SG_DXFER_FROM_DEV, scsi_read_complete);
291 if (ret == -1) {
292 scsi_command_complete(r, -EINVAL);
293 return;
294 }
295}
296
297static void scsi_write_complete(void * opaque, int ret)
298{
299 SCSIRequest *r = (SCSIRequest *)opaque;
300
301 DPRINTF("scsi_write_complete() ret = %d\n", ret);
302 if (ret) {
303 DPRINTF("IO error\n");
304 scsi_command_complete(r, ret);
305 return;
306 }
307
308 scsi_command_complete(r, ret);
309}
310
311/* Write data to a scsi device. Returns nonzero on failure.
312 The transfer may complete asynchronously. */
313static int scsi_write_data(SCSIDevice *d, uint32_t tag)
314{
315 SCSIDeviceState *s = d->state;
316 SCSIRequest *r;
317 int ret;
318
319 DPRINTF("scsi_write_data 0x%x\n", tag);
320 r = scsi_find_request(s, tag);
321 if (!r) {
322 BADF("Bad write tag 0x%x\n", tag);
323 /* ??? This is the wrong error. */
324 scsi_command_complete(r, -EINVAL);
325 return 0;
326 }
327
328 if (r->len == 0) {
329 r->len = r->buflen;
330 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->len);
331 return 0;
332 }
333
334 ret = execute_command(s->bdrv, r, SG_DXFER_TO_DEV, scsi_write_complete);
335 if (ret == -1) {
336 scsi_command_complete(r, -EINVAL);
337 return 1;
338 }
339
340 return 0;
341}
342
343/* Return a pointer to the data buffer. */
344static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
345{
346 SCSIDeviceState *s = d->state;
347 SCSIRequest *r;
348 r = scsi_find_request(s, tag);
349 if (!r) {
350 BADF("Bad buffer tag 0x%x\n", tag);
351 return NULL;
352 }
353 return r->buf;
354}
355
356static int scsi_length(uint8_t *cmd, int blocksize, int *cmdlen, uint32_t *len)
357{
358 switch (cmd[0] >> 5) {
359 case 0:
360 *len = cmd[4];
361 *cmdlen = 6;
72ecb8d9
AL
362 /* length 0 means 256 blocks */
363 if (*len == 0)
364 *len = 256;
2cc977e2
TS
365 break;
366 case 1:
367 case 2:
368 *len = cmd[8] | (cmd[7] << 8);
369 *cmdlen = 10;
370 break;
371 case 4:
372 *len = cmd[13] | (cmd[12] << 8) | (cmd[11] << 16) | (cmd[10] << 24);
373 *cmdlen = 16;
374 break;
375 case 5:
376 *len = cmd[9] | (cmd[8] << 8) | (cmd[7] << 16) | (cmd[6] << 24);
377 *cmdlen = 12;
378 break;
379 default:
380 return -1;
381 }
382
383 switch(cmd[0]) {
384 case TEST_UNIT_READY:
385 case REZERO_UNIT:
386 case START_STOP:
387 case SEEK_6:
388 case WRITE_FILEMARKS:
389 case SPACE:
390 case ERASE:
391 case ALLOW_MEDIUM_REMOVAL:
392 case VERIFY:
393 case SEEK_10:
394 case SYNCHRONIZE_CACHE:
395 case LOCK_UNLOCK_CACHE:
396 case LOAD_UNLOAD:
397 case SET_CD_SPEED:
398 case SET_LIMITS:
399 case WRITE_LONG:
400 case MOVE_MEDIUM:
401 case UPDATE_BLOCK:
402 *len = 0;
403 break;
404 case MODE_SENSE:
405 break;
406 case WRITE_SAME:
407 *len = 1;
408 break;
409 case READ_CAPACITY:
410 *len = 8;
411 break;
412 case READ_BLOCK_LIMITS:
413 *len = 6;
414 break;
415 case READ_POSITION:
416 *len = 20;
417 break;
418 case SEND_VOLUME_TAG:
419 *len *= 40;
420 break;
421 case MEDIUM_SCAN:
422 *len *= 8;
423 break;
424 case WRITE_10:
425 cmd[1] &= ~0x08; /* disable FUA */
426 case WRITE_VERIFY:
427 case WRITE_6:
428 case WRITE_12:
429 case WRITE_VERIFY_12:
430 *len *= blocksize;
431 break;
432 case READ_10:
433 cmd[1] &= ~0x08; /* disable FUA */
434 case READ_6:
435 case READ_REVERSE:
436 case RECOVER_BUFFERED_DATA:
437 case READ_12:
438 *len *= blocksize;
439 break;
440 }
441 return 0;
442}
443
a9dd6843
AL
444static int scsi_stream_length(uint8_t *cmd, int blocksize, int *cmdlen, uint32_t *len)
445{
446 switch(cmd[0]) {
447 /* stream commands */
448 case READ_6:
449 case READ_REVERSE:
450 case RECOVER_BUFFERED_DATA:
451 case WRITE_6:
452 *cmdlen = 6;
453 *len = cmd[4] | (cmd[3] << 8) | (cmd[2] << 16);
454 if (cmd[1] & 0x01) /* fixed */
455 *len *= blocksize;
456 break;
457 case REWIND:
458 case START_STOP:
459 *cmdlen = 6;
460 *len = 0;
461 cmd[1] = 0x01; /* force IMMED, otherwise qemu waits end of command */
462 break;
463 /* generic commands */
464 default:
465 return scsi_length(cmd, blocksize, cmdlen, len);
466 }
467 return 0;
468}
469
2cc977e2
TS
470static int is_write(int command)
471{
472 switch (command) {
473 case COPY:
474 case COPY_VERIFY:
475 case COMPARE:
476 case CHANGE_DEFINITION:
477 case LOG_SELECT:
478 case MODE_SELECT:
479 case MODE_SELECT_10:
480 case SEND_DIAGNOSTIC:
481 case WRITE_BUFFER:
482 case FORMAT_UNIT:
483 case REASSIGN_BLOCKS:
484 case RESERVE:
485 case SEARCH_EQUAL:
486 case SEARCH_HIGH:
487 case SEARCH_LOW:
488 case WRITE_6:
489 case WRITE_10:
490 case WRITE_VERIFY:
491 case UPDATE_BLOCK:
492 case WRITE_LONG:
493 case WRITE_SAME:
494 case SEARCH_HIGH_12:
495 case SEARCH_EQUAL_12:
496 case SEARCH_LOW_12:
497 case WRITE_12:
498 case WRITE_VERIFY_12:
499 case SET_WINDOW:
500 case MEDIUM_SCAN:
501 case SEND_VOLUME_TAG:
502 case WRITE_LONG_2:
503 return 1;
504 }
505 return 0;
506}
507
508/* Execute a scsi command. Returns the length of the data expected by the
509 command. This will be Positive for data transfers from the device
510 (eg. disk reads), negative for transfers to the device (eg. disk writes),
511 and zero if the command does not transfer any data. */
512
513static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
514 uint8_t *cmd, int lun)
515{
516 SCSIDeviceState *s = d->state;
37e828b4
AJ
517 uint32_t len=0;
518 int cmdlen=0;
2cc977e2
TS
519 SCSIRequest *r;
520 int ret;
521
522 /* ??? Tags are not unique for different luns. We only implement a
523 single lun, so this should not matter. */
524
525 if (lun != s->lun || (cmd[1] >> 5) != s->lun) {
526 DPRINTF("Unimplemented LUN %d\n", lun ? lun : cmd[1] >> 5);
527 s->completion(s->opaque, SCSI_REASON_DONE, tag, ILLEGAL_REQUEST);
528 return 0;
529 }
530
a9dd6843
AL
531 if (s->type == TYPE_TAPE) {
532 if (scsi_stream_length(cmd, s->blocksize, &cmdlen, &len) == -1) {
533 BADF("Unsupported command length, command %x\n", cmd[0]);
534 return 0;
535 }
536 } else {
537 if (scsi_length(cmd, s->blocksize, &cmdlen, &len) == -1) {
538 BADF("Unsupported command length, command %x\n", cmd[0]);
539 return 0;
540 }
2cc977e2
TS
541 }
542
543 DPRINTF("Command: lun=%d tag=0x%x data=0x%02x len %d\n", lun, tag,
544 cmd[0], len);
545
546 r = scsi_find_request(s, tag);
547 if (r) {
548 BADF("Tag 0x%x already in use %p\n", tag, r);
549 scsi_cancel_io(d, tag);
550 }
551 r = scsi_new_request(s, tag);
552
553 memcpy(r->cmd, cmd, cmdlen);
554 r->cmdlen = cmdlen;
555
556 if (len == 0) {
557 if (r->buf != NULL)
558 free(r->buf);
559 r->buflen = 0;
560 r->buf = NULL;
561 ret = execute_command(s->bdrv, r, SG_DXFER_NONE, scsi_command_complete);
562 if (ret == -1) {
563 scsi_command_complete(r, -EINVAL);
564 return 0;
565 }
566 return 0;
567 }
568
569 if (r->buflen != len) {
570 if (r->buf != NULL)
571 free(r->buf);
572 r->buf = qemu_malloc(len);
573 r->buflen = len;
574 }
575
576 memset(r->buf, 0, r->buflen);
577 r->len = len;
578 if (is_write(cmd[0])) {
579 r->len = 0;
580 return -len;
581 }
582
583 return len;
584}
585
586static int get_blocksize(BlockDriverState *bdrv)
587{
588 uint8_t cmd[10];
589 uint8_t buf[8];
590 uint8_t sensebuf[8];
591 sg_io_hdr_t io_header;
592 int ret;
593
4f26a486
AL
594 memset(cmd, 0, sizeof(cmd));
595 memset(buf, 0, sizeof(buf));
2cc977e2
TS
596 cmd[0] = READ_CAPACITY;
597
598 memset(&io_header, 0, sizeof(io_header));
599 io_header.interface_id = 'S';
600 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
601 io_header.dxfer_len = sizeof(buf);
602 io_header.dxferp = buf;
603 io_header.cmdp = cmd;
604 io_header.cmd_len = sizeof(cmd);
605 io_header.mx_sb_len = sizeof(sensebuf);
606 io_header.sbp = sensebuf;
607 io_header.timeout = 6000; /* XXX */
608
609 ret = bdrv_pwrite(bdrv, -1, &io_header, sizeof(io_header));
610 if (ret == -1)
611 return -1;
612
613 while ((ret = bdrv_pread(bdrv, -1, &io_header, sizeof(io_header))) == -1 &&
614 errno == EINTR);
615
616 if (ret == -1)
617 return -1;
618
619 return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
620}
621
622static void scsi_destroy(SCSIDevice *d)
623{
624 SCSIRequest *r, *n;
625
626 r = d->state->requests;
627 while (r) {
628 n = r->next;
629 qemu_free(r);
630 r = n;
631 }
632
633 r = free_requests;
634 while (r) {
635 n = r->next;
636 qemu_free(r);
637 r = n;
638 }
639
640 qemu_free(d->state);
641 qemu_free(d);
642}
643
644SCSIDevice *scsi_generic_init(BlockDriverState *bdrv, int tcq,
645 scsi_completionfn completion, void *opaque)
646{
647 int sg_version;
648 SCSIDevice *d;
649 SCSIDeviceState *s;
650 struct sg_scsi_id scsiid;
651
652 /* check we are really using a /dev/sg* file */
653
654 if (!bdrv_is_sg(bdrv))
655 return NULL;
656
657 /* check we are using a driver managing SG_IO (version 3 and after */
658
659 if (bdrv_ioctl(bdrv, SG_GET_VERSION_NUM, &sg_version) < 0 ||
660 sg_version < 30000)
661 return NULL;
662
663 /* get LUN of the /dev/sg? */
664
665 if (bdrv_ioctl(bdrv, SG_GET_SCSI_ID, &scsiid))
666 return NULL;
667
668 /* define device state */
669
670 s = (SCSIDeviceState *)qemu_mallocz(sizeof(SCSIDeviceState));
671 s->bdrv = bdrv;
672 s->requests = NULL;
673 s->completion = completion;
674 s->opaque = opaque;
675 s->lun = scsiid.lun;
a9dd6843 676 s->type = scsiid.scsi_type;
2cc977e2
TS
677 s->blocksize = get_blocksize(s->bdrv);
678 s->driver_status = 0;
679 memset(s->sensebuf, 0, sizeof(s->sensebuf));
680 /* removable media returns 0 if not present */
a9dd6843
AL
681 if (s->blocksize <= 0) {
682 if (s->type == TYPE_ROM || s->type == TYPE_WORM)
683 s->blocksize = 2048;
684 else
685 s->blocksize = 512;
686 }
2cc977e2
TS
687
688 /* define function to manage device */
689
690 d = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
691 d->state = s;
692 d->destroy = scsi_destroy;
693 d->send_command = scsi_send_command;
694 d->read_data = scsi_read_data;
695 d->write_data = scsi_write_data;
696 d->cancel_io = scsi_cancel_io;
697 d->get_buf = scsi_get_buf;
698
699 return d;
700}
701#endif /* __linux__ */