1
2
3
4
5
6
7
8
9
10
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
27
28
29
30#ifdef DEBUG_SCSI
31#define DPRINTF(fmt, ...) \
32do { printf("scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
33#else
34#define DPRINTF(fmt, ...) do {} while(0)
35#endif
36
37#define BADF(fmt, ...) \
38do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_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
47#define REWIND 0x01
48#define REPORT_DENSITY_SUPPORT 0x44
49#define LOAD_UNLOAD 0xa6
50#define SET_CD_SPEED 0xbb
51#define BLANK 0xa1
52
53#define SCSI_CMD_BUF_SIZE 16
54#define SCSI_SENSE_BUF_SIZE 96
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;
80 int type;
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 uint8_t senselen;
88};
89
90
91static SCSIRequest *free_requests = NULL;
92
93static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag)
94{
95 SCSIRequest *r;
96
97 if (free_requests) {
98 r = free_requests;
99 free_requests = r->next;
100 } else {
101 r = qemu_malloc(sizeof(SCSIRequest));
102 r->buf = NULL;
103 r->buflen = 0;
104 }
105 r->dev = s;
106 r->tag = tag;
107 memset(r->cmd, 0, sizeof(r->cmd));
108 memset(&r->io_header, 0, sizeof(r->io_header));
109 r->cmdlen = 0;
110 r->len = 0;
111 r->aiocb = NULL;
112
113
114
115 r->next = s->requests;
116 s->requests = r;
117 return r;
118}
119
120static void scsi_remove_request(SCSIRequest *r)
121{
122 SCSIRequest *last;
123 SCSIDeviceState *s = r->dev;
124
125 if (s->requests == r) {
126 s->requests = r->next;
127 } else {
128 last = s->requests;
129 while (last && last->next != r)
130 last = last->next;
131 if (last) {
132 last->next = r->next;
133 } else {
134 BADF("Orphaned request\n");
135 }
136 }
137 r->next = free_requests;
138 free_requests = r;
139}
140
141static SCSIRequest *scsi_find_request(SCSIDeviceState *s, uint32_t tag)
142{
143 SCSIRequest *r;
144
145 r = s->requests;
146 while (r && r->tag != tag)
147 r = r->next;
148
149 return r;
150}
151
152
153static void scsi_command_complete(void *opaque, int ret)
154{
155 SCSIRequest *r = (SCSIRequest *)opaque;
156 SCSIDeviceState *s = r->dev;
157 uint32_t tag;
158 int status;
159
160 s->driver_status = r->io_header.driver_status;
161 if (s->driver_status & SG_ERR_DRIVER_SENSE)
162 s->senselen = r->io_header.sb_len_wr;
163
164 if (ret != 0)
165 status = BUSY << 1;
166 else {
167 if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
168 status = BUSY << 1;
169 BADF("Driver Timeout\n");
170 } else if (r->io_header.status)
171 status = r->io_header.status;
172 else if (s->driver_status & SG_ERR_DRIVER_SENSE)
173 status = CHECK_CONDITION << 1;
174 else
175 status = GOOD << 1;
176 }
177 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
178 r, r->tag, status);
179 tag = r->tag;
180 scsi_remove_request(r);
181 s->completion(s->opaque, SCSI_REASON_DONE, tag, status);
182}
183
184
185static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
186{
187 DPRINTF("scsi_cancel_io 0x%x\n", tag);
188 SCSIDeviceState *s = d->state;
189 SCSIRequest *r;
190 DPRINTF("Cancel tag=0x%x\n", tag);
191 r = scsi_find_request(s, tag);
192 if (r) {
193 if (r->aiocb)
194 bdrv_aio_cancel(r->aiocb);
195 r->aiocb = NULL;
196 scsi_remove_request(r);
197 }
198}
199
200static int execute_command(BlockDriverState *bdrv,
201 SCSIRequest *r, int direction,
202 BlockDriverCompletionFunc *complete)
203{
204 r->io_header.interface_id = 'S';
205 r->io_header.dxfer_direction = direction;
206 r->io_header.dxferp = r->buf;
207 r->io_header.dxfer_len = r->buflen;
208 r->io_header.cmdp = r->cmd;
209 r->io_header.cmd_len = r->cmdlen;
210 r->io_header.mx_sb_len = sizeof(r->dev->sensebuf);
211 r->io_header.sbp = r->dev->sensebuf;
212 r->io_header.timeout = MAX_UINT;
213 r->io_header.usr_ptr = r;
214 r->io_header.flags |= SG_FLAG_DIRECT_IO;
215
216 r->aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
217 if (r->aiocb == NULL) {
218 BADF("execute_command: read failed !\n");
219 return -1;
220 }
221
222 return 0;
223}
224
225static void scsi_read_complete(void * opaque, int ret)
226{
227 SCSIRequest *r = (SCSIRequest *)opaque;
228 SCSIDeviceState *s = r->dev;
229 int len;
230
231 if (ret) {
232 DPRINTF("IO error\n");
233 scsi_command_complete(r, ret);
234 return;
235 }
236 len = r->io_header.dxfer_len - r->io_header.resid;
237 DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, len);
238
239 r->len = -1;
240 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, len);
241 if (len == 0)
242 scsi_command_complete(r, 0);
243}
244
245
246static void scsi_read_data(SCSIDevice *d, uint32_t tag)
247{
248 SCSIDeviceState *s = d->state;
249 SCSIRequest *r;
250 int ret;
251
252 DPRINTF("scsi_read_data 0x%x\n", tag);
253 r = scsi_find_request(s, tag);
254 if (!r) {
255 BADF("Bad read tag 0x%x\n", tag);
256
257 scsi_command_complete(r, -EINVAL);
258 return;
259 }
260
261 if (r->len == -1) {
262 scsi_command_complete(r, 0);
263 return;
264 }
265
266 if (r->cmd[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
267 {
268 s->senselen = MIN(r->len, s->senselen);
269 memcpy(r->buf, s->sensebuf, s->senselen);
270 r->io_header.driver_status = 0;
271 r->io_header.status = 0;
272 r->io_header.dxfer_len = s->senselen;
273 r->len = -1;
274 DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, s->senselen);
275 DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
276 r->buf[0], r->buf[1], r->buf[2], r->buf[3],
277 r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
278 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, s->senselen);
279 return;
280 }
281
282 ret = execute_command(s->bdrv, r, SG_DXFER_FROM_DEV, scsi_read_complete);
283 if (ret == -1) {
284 scsi_command_complete(r, -EINVAL);
285 return;
286 }
287}
288
289static void scsi_write_complete(void * opaque, int ret)
290{
291 SCSIRequest *r = (SCSIRequest *)opaque;
292
293 DPRINTF("scsi_write_complete() ret = %d\n", ret);
294 if (ret) {
295 DPRINTF("IO error\n");
296 scsi_command_complete(r, ret);
297 return;
298 }
299
300 if (r->cmd[0] == MODE_SELECT && r->cmd[4] == 12 &&
301 r->dev->type == TYPE_TAPE) {
302 r->dev->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
303 DPRINTF("block size %d\n", r->dev->blocksize);
304 }
305
306 scsi_command_complete(r, ret);
307}
308
309
310
311static int scsi_write_data(SCSIDevice *d, uint32_t tag)
312{
313 SCSIDeviceState *s = d->state;
314 SCSIRequest *r;
315 int ret;
316
317 DPRINTF("scsi_write_data 0x%x\n", tag);
318 r = scsi_find_request(s, tag);
319 if (!r) {
320 BADF("Bad write tag 0x%x\n", tag);
321
322 scsi_command_complete(r, -EINVAL);
323 return 0;
324 }
325
326 if (r->len == 0) {
327 r->len = r->buflen;
328 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->len);
329 return 0;
330 }
331
332 ret = execute_command(s->bdrv, r, SG_DXFER_TO_DEV, scsi_write_complete);
333 if (ret == -1) {
334 scsi_command_complete(r, -EINVAL);
335 return 1;
336 }
337
338 return 0;
339}
340
341
342static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
343{
344 SCSIDeviceState *s = d->state;
345 SCSIRequest *r;
346 r = scsi_find_request(s, tag);
347 if (!r) {
348 BADF("Bad buffer tag 0x%x\n", tag);
349 return NULL;
350 }
351 return r->buf;
352}
353
354static int scsi_length(uint8_t *cmd, int blocksize, int *cmdlen, uint32_t *len)
355{
356 switch (cmd[0] >> 5) {
357 case 0:
358 *len = cmd[4];
359 *cmdlen = 6;
360
361 if (*len == 0)
362 *len = 256;
363 break;
364 case 1:
365 case 2:
366 *len = cmd[8] | (cmd[7] << 8);
367 *cmdlen = 10;
368 break;
369 case 4:
370 *len = cmd[13] | (cmd[12] << 8) | (cmd[11] << 16) | (cmd[10] << 24);
371 *cmdlen = 16;
372 break;
373 case 5:
374 *len = cmd[9] | (cmd[8] << 8) | (cmd[7] << 16) | (cmd[6] << 24);
375 *cmdlen = 12;
376 break;
377 default:
378 return -1;
379 }
380
381 switch(cmd[0]) {
382 case TEST_UNIT_READY:
383 case REZERO_UNIT:
384 case START_STOP:
385 case SEEK_6:
386 case WRITE_FILEMARKS:
387 case SPACE:
388 case ERASE:
389 case ALLOW_MEDIUM_REMOVAL:
390 case VERIFY:
391 case SEEK_10:
392 case SYNCHRONIZE_CACHE:
393 case LOCK_UNLOCK_CACHE:
394 case LOAD_UNLOAD:
395 case SET_CD_SPEED:
396 case SET_LIMITS:
397 case WRITE_LONG:
398 case MOVE_MEDIUM:
399 case UPDATE_BLOCK:
400 *len = 0;
401 break;
402 case MODE_SENSE:
403 break;
404 case WRITE_SAME:
405 *len = 1;
406 break;
407 case READ_CAPACITY:
408 *len = 8;
409 break;
410 case READ_BLOCK_LIMITS:
411 *len = 6;
412 break;
413 case READ_POSITION:
414 *len = 20;
415 break;
416 case SEND_VOLUME_TAG:
417 *len *= 40;
418 break;
419 case MEDIUM_SCAN:
420 *len *= 8;
421 break;
422 case WRITE_10:
423 cmd[1] &= ~0x08;
424 case WRITE_VERIFY:
425 case WRITE_6:
426 case WRITE_12:
427 case WRITE_VERIFY_12:
428 *len *= blocksize;
429 break;
430 case READ_10:
431 cmd[1] &= ~0x08;
432 case READ_6:
433 case READ_REVERSE:
434 case RECOVER_BUFFERED_DATA:
435 case READ_12:
436 *len *= blocksize;
437 break;
438 case INQUIRY:
439 *len = cmd[4] | (cmd[3] << 8);
440 break;
441 }
442 return 0;
443}
444
445static int scsi_stream_length(uint8_t *cmd, int blocksize, int *cmdlen, uint32_t *len)
446{
447 switch(cmd[0]) {
448
449 case READ_6:
450 case READ_REVERSE:
451 case RECOVER_BUFFERED_DATA:
452 case WRITE_6:
453 *cmdlen = 6;
454 *len = cmd[4] | (cmd[3] << 8) | (cmd[2] << 16);
455 if (cmd[1] & 0x01)
456 *len *= blocksize;
457 break;
458 case REWIND:
459 case START_STOP:
460 *cmdlen = 6;
461 *len = 0;
462 cmd[1] = 0x01;
463 break;
464
465 default:
466 return scsi_length(cmd, blocksize, cmdlen, len);
467 }
468 return 0;
469}
470
471static int is_write(int command)
472{
473 switch (command) {
474 case COPY:
475 case COPY_VERIFY:
476 case COMPARE:
477 case CHANGE_DEFINITION:
478 case LOG_SELECT:
479 case MODE_SELECT:
480 case MODE_SELECT_10:
481 case SEND_DIAGNOSTIC:
482 case WRITE_BUFFER:
483 case FORMAT_UNIT:
484 case REASSIGN_BLOCKS:
485 case RESERVE:
486 case SEARCH_EQUAL:
487 case SEARCH_HIGH:
488 case SEARCH_LOW:
489 case WRITE_6:
490 case WRITE_10:
491 case WRITE_VERIFY:
492 case UPDATE_BLOCK:
493 case WRITE_LONG:
494 case WRITE_SAME:
495 case SEARCH_HIGH_12:
496 case SEARCH_EQUAL_12:
497 case SEARCH_LOW_12:
498 case WRITE_12:
499 case WRITE_VERIFY_12:
500 case SET_WINDOW:
501 case MEDIUM_SCAN:
502 case SEND_VOLUME_TAG:
503 case WRITE_LONG_2:
504 return 1;
505 }
506 return 0;
507}
508
509
510
511
512
513
514static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
515 uint8_t *cmd, int lun)
516{
517 SCSIDeviceState *s = d->state;
518 uint32_t len=0;
519 int cmdlen=0;
520 SCSIRequest *r;
521 int ret;
522
523 if (s->type == TYPE_TAPE) {
524 if (scsi_stream_length(cmd, s->blocksize, &cmdlen, &len) == -1) {
525 BADF("Unsupported command length, command %x\n", cmd[0]);
526 return 0;
527 }
528 } else {
529 if (scsi_length(cmd, s->blocksize, &cmdlen, &len) == -1) {
530 BADF("Unsupported command length, command %x\n", cmd[0]);
531 return 0;
532 }
533 }
534
535 DPRINTF("Command: lun=%d tag=0x%x data=0x%02x len %d\n", lun, tag,
536 cmd[0], len);
537
538 if (cmd[0] != REQUEST_SENSE &&
539 (lun != s->lun || (cmd[1] >> 5) != s->lun)) {
540 DPRINTF("Unimplemented LUN %d\n", lun ? lun : cmd[1] >> 5);
541
542 s->sensebuf[0] = 0x70;
543 s->sensebuf[1] = 0x00;
544 s->sensebuf[2] = ILLEGAL_REQUEST;
545 s->sensebuf[3] = 0x00;
546 s->sensebuf[4] = 0x00;
547 s->sensebuf[5] = 0x00;
548 s->sensebuf[6] = 0x00;
549 s->senselen = 7;
550 s->driver_status = SG_ERR_DRIVER_SENSE;
551 s->completion(s->opaque, SCSI_REASON_DONE, tag, CHECK_CONDITION << 1);
552 return 0;
553 }
554
555 r = scsi_find_request(s, tag);
556 if (r) {
557 BADF("Tag 0x%x already in use %p\n", tag, r);
558 scsi_cancel_io(d, tag);
559 }
560 r = scsi_new_request(s, tag);
561
562 memcpy(r->cmd, cmd, cmdlen);
563 r->cmdlen = cmdlen;
564
565 if (len == 0) {
566 if (r->buf != NULL)
567 free(r->buf);
568 r->buflen = 0;
569 r->buf = NULL;
570 ret = execute_command(s->bdrv, r, SG_DXFER_NONE, scsi_command_complete);
571 if (ret == -1) {
572 scsi_command_complete(r, -EINVAL);
573 return 0;
574 }
575 return 0;
576 }
577
578 if (r->buflen != len) {
579 if (r->buf != NULL)
580 free(r->buf);
581 r->buf = qemu_malloc(len);
582 r->buflen = len;
583 }
584
585 memset(r->buf, 0, r->buflen);
586 r->len = len;
587 if (is_write(cmd[0])) {
588 r->len = 0;
589 return -len;
590 }
591
592 return len;
593}
594
595static int get_blocksize(BlockDriverState *bdrv)
596{
597 uint8_t cmd[10];
598 uint8_t buf[8];
599 uint8_t sensebuf[8];
600 sg_io_hdr_t io_header;
601 int ret;
602
603 memset(cmd, 0, sizeof(cmd));
604 memset(buf, 0, sizeof(buf));
605 cmd[0] = READ_CAPACITY;
606
607 memset(&io_header, 0, sizeof(io_header));
608 io_header.interface_id = 'S';
609 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
610 io_header.dxfer_len = sizeof(buf);
611 io_header.dxferp = buf;
612 io_header.cmdp = cmd;
613 io_header.cmd_len = sizeof(cmd);
614 io_header.mx_sb_len = sizeof(sensebuf);
615 io_header.sbp = sensebuf;
616 io_header.timeout = 6000;
617
618 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
619 if (ret < 0)
620 return -1;
621
622 return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
623}
624
625static int get_stream_blocksize(BlockDriverState *bdrv)
626{
627 uint8_t cmd[6];
628 uint8_t buf[12];
629 uint8_t sensebuf[8];
630 sg_io_hdr_t io_header;
631 int ret;
632
633 memset(cmd, 0, sizeof(cmd));
634 memset(buf, 0, sizeof(buf));
635 cmd[0] = MODE_SENSE;
636 cmd[4] = sizeof(buf);
637
638 memset(&io_header, 0, sizeof(io_header));
639 io_header.interface_id = 'S';
640 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
641 io_header.dxfer_len = sizeof(buf);
642 io_header.dxferp = buf;
643 io_header.cmdp = cmd;
644 io_header.cmd_len = sizeof(cmd);
645 io_header.mx_sb_len = sizeof(sensebuf);
646 io_header.sbp = sensebuf;
647 io_header.timeout = 6000;
648
649 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
650 if (ret < 0)
651 return -1;
652
653 return (buf[9] << 16) | (buf[10] << 8) | buf[11];
654}
655
656static void scsi_destroy(SCSIDevice *d)
657{
658 SCSIRequest *r, *n;
659
660 r = d->state->requests;
661 while (r) {
662 n = r->next;
663 qemu_free(r);
664 r = n;
665 }
666
667 r = free_requests;
668 while (r) {
669 n = r->next;
670 qemu_free(r);
671 r = n;
672 }
673
674 qemu_free(d->state);
675 qemu_free(d);
676}
677
678SCSIDevice *scsi_generic_init(BlockDriverState *bdrv, int tcq,
679 scsi_completionfn completion, void *opaque)
680{
681 int sg_version;
682 SCSIDevice *d;
683 SCSIDeviceState *s;
684 struct sg_scsi_id scsiid;
685
686
687
688 if (!bdrv_is_sg(bdrv))
689 return NULL;
690
691
692
693 if (bdrv_ioctl(bdrv, SG_GET_VERSION_NUM, &sg_version) < 0 ||
694 sg_version < 30000)
695 return NULL;
696
697
698
699 if (bdrv_ioctl(bdrv, SG_GET_SCSI_ID, &scsiid))
700 return NULL;
701
702
703
704 s = (SCSIDeviceState *)qemu_mallocz(sizeof(SCSIDeviceState));
705 s->bdrv = bdrv;
706 s->requests = NULL;
707 s->completion = completion;
708 s->opaque = opaque;
709 s->lun = scsiid.lun;
710 DPRINTF("LUN %d\n", s->lun);
711 s->type = scsiid.scsi_type;
712 DPRINTF("device type %d\n", s->type);
713 if (s->type == TYPE_TAPE) {
714 s->blocksize = get_stream_blocksize(s->bdrv);
715 if (s->blocksize == -1)
716 s->blocksize = 0;
717 } else {
718 s->blocksize = get_blocksize(s->bdrv);
719
720 if (s->blocksize <= 0) {
721 if (s->type == TYPE_ROM || s->type == TYPE_WORM)
722 s->blocksize = 2048;
723 else
724 s->blocksize = 512;
725 }
726 }
727 DPRINTF("block size %d\n", s->blocksize);
728 s->driver_status = 0;
729 memset(s->sensebuf, 0, sizeof(s->sensebuf));
730
731
732
733 d = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
734 d->state = s;
735 d->destroy = scsi_destroy;
736 d->send_command = scsi_send_command;
737 d->read_data = scsi_read_data;
738 d->write_data = scsi_write_data;
739 d->cancel_io = scsi_cancel_io;
740 d->get_buf = scsi_get_buf;
741
742 return d;
743}
744#endif
745