1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <qemu-common.h>
17#include <sysemu.h>
18
19
20#ifdef DEBUG_SCSI
21#define DPRINTF(fmt, args...) \
22do { printf("scsi-disk: " fmt , ##args); } while (0)
23#else
24#define DPRINTF(fmt, args...) do {} while(0)
25#endif
26
27#define BADF(fmt, args...) \
28do { fprintf(stderr, "scsi-disk: " fmt , ##args); } while (0)
29
30#include "qemu-common.h"
31#include "block.h"
32#include "scsi-disk.h"
33
34#define SENSE_NO_SENSE 0
35#define SENSE_NOT_READY 2
36#define SENSE_HARDWARE_ERROR 4
37#define SENSE_ILLEGAL_REQUEST 5
38
39#define STATUS_GOOD 0
40#define STATUS_CHECK_CONDITION 2
41
42#define SCSI_DMA_BUF_SIZE 131072
43#define SCSI_MAX_INQUIRY_LEN 256
44
45#define SCSI_REQ_STATUS_RETRY 0x01
46
47typedef struct SCSIRequest {
48 SCSIDeviceState *dev;
49 uint32_t tag;
50
51
52
53 uint64_t sector;
54 uint32_t sector_count;
55
56 int buf_len;
57 uint8_t *dma_buf;
58 BlockDriverAIOCB *aiocb;
59 struct SCSIRequest *next;
60 uint32_t status;
61} SCSIRequest;
62
63struct SCSIDeviceState
64{
65 BlockDriverState *bdrv;
66 SCSIRequest *requests;
67
68
69 int cluster_size;
70 uint64_t max_lba;
71 int sense;
72 int tcq;
73
74
75 scsi_completionfn completion;
76 void *opaque;
77 char drive_serial_str[21];
78};
79
80
81static SCSIRequest *free_requests = NULL;
82
83static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag)
84{
85 SCSIRequest *r;
86
87 if (free_requests) {
88 r = free_requests;
89 free_requests = r->next;
90 } else {
91 r = qemu_malloc(sizeof(SCSIRequest));
92 r->dma_buf = qemu_memalign(512, SCSI_DMA_BUF_SIZE);
93 }
94 r->dev = s;
95 r->tag = tag;
96 r->sector_count = 0;
97 r->buf_len = 0;
98 r->aiocb = NULL;
99 r->status = 0;
100
101 r->next = s->requests;
102 s->requests = r;
103 return r;
104}
105
106static void scsi_remove_request(SCSIRequest *r)
107{
108 SCSIRequest *last;
109 SCSIDeviceState *s = r->dev;
110
111 if (s->requests == r) {
112 s->requests = r->next;
113 } else {
114 last = s->requests;
115 while (last && last->next != r)
116 last = last->next;
117 if (last) {
118 last->next = r->next;
119 } else {
120 BADF("Orphaned request\n");
121 }
122 }
123 r->next = free_requests;
124 free_requests = r;
125}
126
127static SCSIRequest *scsi_find_request(SCSIDeviceState *s, uint32_t tag)
128{
129 SCSIRequest *r;
130
131 r = s->requests;
132 while (r && r->tag != tag)
133 r = r->next;
134
135 return r;
136}
137
138
139static void scsi_command_complete(SCSIRequest *r, int status, int sense)
140{
141 SCSIDeviceState *s = r->dev;
142 uint32_t tag;
143 DPRINTF("Command complete tag=0x%x status=%d sense=%d\n", r->tag, status, sense);
144 s->sense = sense;
145 tag = r->tag;
146 scsi_remove_request(r);
147 s->completion(s->opaque, SCSI_REASON_DONE, tag, status);
148}
149
150
151static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
152{
153 SCSIDeviceState *s = d->state;
154 SCSIRequest *r;
155 DPRINTF("Cancel tag=0x%x\n", tag);
156 r = scsi_find_request(s, tag);
157 if (r) {
158 if (r->aiocb)
159 bdrv_aio_cancel(r->aiocb);
160 r->aiocb = NULL;
161 scsi_remove_request(r);
162 }
163}
164
165static void scsi_read_complete(void * opaque, int ret)
166{
167 SCSIRequest *r = (SCSIRequest *)opaque;
168 SCSIDeviceState *s = r->dev;
169
170 if (ret) {
171 DPRINTF("IO error\n");
172 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, 0);
173 scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_NO_SENSE);
174 return;
175 }
176 DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, r->buf_len);
177
178 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->buf_len);
179}
180
181
182static void scsi_read_data(SCSIDevice *d, uint32_t tag)
183{
184 SCSIDeviceState *s = d->state;
185 SCSIRequest *r;
186 uint32_t n;
187
188 r = scsi_find_request(s, tag);
189 if (!r) {
190 BADF("Bad read tag 0x%x\n", tag);
191
192 scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR);
193 return;
194 }
195 if (r->sector_count == (uint32_t)-1) {
196 DPRINTF("Read buf_len=%d\n", r->buf_len);
197 r->sector_count = 0;
198 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->buf_len);
199 return;
200 }
201 DPRINTF("Read sector_count=%d\n", r->sector_count);
202 if (r->sector_count == 0) {
203 scsi_command_complete(r, STATUS_GOOD, SENSE_NO_SENSE);
204 return;
205 }
206
207 n = r->sector_count;
208 if (n > SCSI_DMA_BUF_SIZE / 512)
209 n = SCSI_DMA_BUF_SIZE / 512;
210
211 r->buf_len = n * 512;
212 r->aiocb = bdrv_aio_read(s->bdrv, r->sector, r->dma_buf, n,
213 scsi_read_complete, r);
214 if (r->aiocb == NULL)
215 scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR);
216 r->sector += n;
217 r->sector_count -= n;
218}
219
220static int scsi_handle_write_error(SCSIRequest *r, int error)
221{
222 BlockInterfaceErrorAction action = drive_get_onerror(r->dev->bdrv);
223
224 if (action == BLOCK_ERR_IGNORE)
225 return 0;
226
227 if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC)
228 || action == BLOCK_ERR_STOP_ANY) {
229 r->status |= SCSI_REQ_STATUS_RETRY;
230 vm_stop(0);
231 } else {
232 scsi_command_complete(r, STATUS_CHECK_CONDITION,
233 SENSE_HARDWARE_ERROR);
234 }
235
236 return 1;
237}
238
239static void scsi_write_complete(void * opaque, int ret)
240{
241 SCSIRequest *r = (SCSIRequest *)opaque;
242 SCSIDeviceState *s = r->dev;
243 uint32_t len;
244 uint32_t n;
245
246 r->aiocb = NULL;
247
248 if (ret) {
249 if (scsi_handle_write_error(r, -ret))
250 return;
251 }
252
253 n = r->buf_len / 512;
254 r->sector += n;
255 r->sector_count -= n;
256 if (r->sector_count == 0) {
257 scsi_command_complete(r, STATUS_GOOD, SENSE_NO_SENSE);
258 } else {
259 len = r->sector_count * 512;
260 if (len > SCSI_DMA_BUF_SIZE) {
261 len = SCSI_DMA_BUF_SIZE;
262 }
263 r->buf_len = len;
264 DPRINTF("Write complete tag=0x%x more=%d\n", r->tag, len);
265 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, len);
266 }
267}
268
269static void scsi_write_request(SCSIRequest *r)
270{
271 SCSIDeviceState *s = r->dev;
272 uint32_t n;
273
274 n = r->buf_len / 512;
275 if (n) {
276 r->aiocb = bdrv_aio_write(s->bdrv, r->sector, r->dma_buf, n,
277 scsi_write_complete, r);
278 if (r->aiocb == NULL)
279 scsi_command_complete(r, STATUS_CHECK_CONDITION,
280 SENSE_HARDWARE_ERROR);
281 } else {
282
283 scsi_write_complete(r, 0);
284 }
285}
286
287
288
289static int scsi_write_data(SCSIDevice *d, uint32_t tag)
290{
291 SCSIDeviceState *s = d->state;
292 SCSIRequest *r;
293
294 DPRINTF("Write data tag=0x%x\n", tag);
295 r = scsi_find_request(s, tag);
296 if (!r) {
297 BADF("Bad write tag 0x%x\n", tag);
298 scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR);
299 return 1;
300 }
301
302 if (r->aiocb)
303 BADF("Data transfer already in progress\n");
304
305 scsi_write_request(r);
306
307 return 0;
308}
309
310static void scsi_dma_restart_cb(void *opaque, int running, int reason)
311{
312 SCSIDeviceState *s = opaque;
313 SCSIRequest *r = s->requests;
314 if (!running)
315 return;
316
317 while (r) {
318 if (r->status & SCSI_REQ_STATUS_RETRY) {
319 r->status &= ~SCSI_REQ_STATUS_RETRY;
320 scsi_write_request(r);
321 }
322 r = r->next;
323 }
324}
325
326
327static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
328{
329 SCSIDeviceState *s = d->state;
330 SCSIRequest *r;
331
332 r = scsi_find_request(s, tag);
333 if (!r) {
334 BADF("Bad buffer tag 0x%x\n", tag);
335 return NULL;
336 }
337 return r->dma_buf;
338}
339
340
341
342
343
344
345static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
346 uint8_t *buf, int lun)
347{
348 SCSIDeviceState *s = d->state;
349 uint64_t nb_sectors;
350 uint64_t lba;
351 uint32_t len;
352 int cmdlen;
353 int is_write;
354 uint8_t command;
355 uint8_t *outbuf;
356 SCSIRequest *r;
357
358 command = buf[0];
359 r = scsi_find_request(s, tag);
360 if (r) {
361 BADF("Tag 0x%x already in use\n", tag);
362 scsi_cancel_io(d, tag);
363 }
364
365
366 r = scsi_new_request(s, tag);
367 outbuf = r->dma_buf;
368 is_write = 0;
369 DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
370 switch (command >> 5) {
371 case 0:
372 lba = (uint64_t) buf[3] | ((uint64_t) buf[2] << 8) |
373 (((uint64_t) buf[1] & 0x1f) << 16);
374 len = buf[4];
375 cmdlen = 6;
376 break;
377 case 1:
378 case 2:
379 lba = (uint64_t) buf[5] | ((uint64_t) buf[4] << 8) |
380 ((uint64_t) buf[3] << 16) | ((uint64_t) buf[2] << 24);
381 len = buf[8] | (buf[7] << 8);
382 cmdlen = 10;
383 break;
384 case 4:
385 lba = (uint64_t) buf[9] | ((uint64_t) buf[8] << 8) |
386 ((uint64_t) buf[7] << 16) | ((uint64_t) buf[6] << 24) |
387 ((uint64_t) buf[5] << 32) | ((uint64_t) buf[4] << 40) |
388 ((uint64_t) buf[3] << 48) | ((uint64_t) buf[2] << 56);
389 len = buf[13] | (buf[12] << 8) | (buf[11] << 16) | (buf[10] << 24);
390 cmdlen = 16;
391 break;
392 case 5:
393 lba = (uint64_t) buf[5] | ((uint64_t) buf[4] << 8) |
394 ((uint64_t) buf[3] << 16) | ((uint64_t) buf[2] << 24);
395 len = buf[9] | (buf[8] << 8) | (buf[7] << 16) | (buf[6] << 24);
396 cmdlen = 12;
397 break;
398 default:
399 BADF("Unsupported command length, command %x\n", command);
400 goto fail;
401 }
402#ifdef DEBUG_SCSI
403 {
404 int i;
405 for (i = 1; i < cmdlen; i++) {
406 printf(" 0x%02x", buf[i]);
407 }
408 printf("\n");
409 }
410#endif
411 if (lun || buf[1] >> 5) {
412
413 DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5);
414 if (command != 0x03 && command != 0x12)
415 goto fail;
416 }
417 switch (command) {
418 case 0x0:
419 DPRINTF("Test Unit Ready\n");
420 break;
421 case 0x03:
422 DPRINTF("Request Sense (len %d)\n", len);
423 if (len < 4)
424 goto fail;
425 memset(outbuf, 0, 4);
426 outbuf[0] = 0xf0;
427 outbuf[1] = 0;
428 outbuf[2] = s->sense;
429 r->buf_len = 4;
430 break;
431 case 0x12:
432 DPRINTF("Inquiry (len %d)\n", len);
433 if (buf[1] & 0x2) {
434
435 BADF("optional INQUIRY command support request not implemented\n");
436 goto fail;
437 }
438 else if (buf[1] & 0x1) {
439
440 uint8_t page_code = buf[2];
441 if (len < 4) {
442 BADF("Error: Inquiry (EVPD[%02X]) buffer size %d is "
443 "less than 4\n", page_code, len);
444 goto fail;
445 }
446
447 switch (page_code) {
448 case 0x00:
449 {
450
451 DPRINTF("Inquiry EVPD[Supported pages] "
452 "buffer size %d\n", len);
453
454 r->buf_len = 0;
455
456 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
457 outbuf[r->buf_len++] = 5;
458 } else {
459 outbuf[r->buf_len++] = 0;
460 }
461
462 outbuf[r->buf_len++] = 0x00;
463 outbuf[r->buf_len++] = 0x00;
464 outbuf[r->buf_len++] = 3;
465 outbuf[r->buf_len++] = 0x00;
466 outbuf[r->buf_len++] = 0x80;
467 outbuf[r->buf_len++] = 0x83;
468 }
469 break;
470 case 0x80:
471 {
472 int l;
473
474
475 if (len < 4) {
476 BADF("Error: EVPD[Serial number] Inquiry buffer "
477 "size %d too small, %d needed\n", len, 4);
478 goto fail;
479 }
480
481 DPRINTF("Inquiry EVPD[Serial number] buffer size %d\n", len);
482 l = MIN(len, strlen(s->drive_serial_str));
483
484 r->buf_len = 0;
485
486
487 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
488 outbuf[r->buf_len++] = 5;
489 } else {
490 outbuf[r->buf_len++] = 0;
491 }
492
493 outbuf[r->buf_len++] = 0x80;
494 outbuf[r->buf_len++] = 0x00;
495 outbuf[r->buf_len++] = l;
496 memcpy(&outbuf[r->buf_len], s->drive_serial_str, l);
497 r->buf_len += l;
498 }
499
500 break;
501 case 0x83:
502 {
503
504 int max_len = 255 - 8;
505 int id_len = strlen(bdrv_get_device_name(s->bdrv));
506 if (id_len > max_len)
507 id_len = max_len;
508
509 DPRINTF("Inquiry EVPD[Device identification] "
510 "buffer size %d\n", len);
511 r->buf_len = 0;
512 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
513 outbuf[r->buf_len++] = 5;
514 } else {
515 outbuf[r->buf_len++] = 0;
516 }
517
518 outbuf[r->buf_len++] = 0x83;
519 outbuf[r->buf_len++] = 0x00;
520 outbuf[r->buf_len++] = 3 + id_len;
521
522 outbuf[r->buf_len++] = 0x2;
523 outbuf[r->buf_len++] = 0;
524 outbuf[r->buf_len++] = 0;
525 outbuf[r->buf_len++] = id_len;
526
527 memcpy(&outbuf[r->buf_len],
528 bdrv_get_device_name(s->bdrv), id_len);
529 r->buf_len += id_len;
530 }
531 break;
532 default:
533 BADF("Error: unsupported Inquiry (EVPD[%02X]) "
534 "buffer size %d\n", page_code, len);
535 goto fail;
536 }
537
538 break;
539 }
540 else {
541
542 if (buf[2] != 0) {
543 BADF("Error: Inquiry (STANDARD) page or code "
544 "is non-zero [%02X]\n", buf[2]);
545 goto fail;
546 }
547
548
549 if (len < 5) {
550 BADF("Error: Inquiry (STANDARD) buffer size %d "
551 "is less than 5\n", len);
552 goto fail;
553 }
554
555 if (len < 36) {
556 BADF("Error: Inquiry (STANDARD) buffer size %d "
557 "is less than 36 (TODO: only 5 required)\n", len);
558 }
559 }
560
561 if(len > SCSI_MAX_INQUIRY_LEN)
562 len = SCSI_MAX_INQUIRY_LEN;
563
564 memset(outbuf, 0, len);
565
566 if (lun || buf[1] >> 5) {
567 outbuf[0] = 0x7f;
568 } else if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
569 outbuf[0] = 5;
570 outbuf[1] = 0x80;
571 memcpy(&outbuf[16], "QEMU CD-ROM ", 16);
572 } else {
573 outbuf[0] = 0;
574 memcpy(&outbuf[16], "QEMU HARDDISK ", 16);
575 }
576 memcpy(&outbuf[8], "QEMU ", 8);
577 memcpy(&outbuf[32], QEMU_VERSION, 4);
578
579
580 outbuf[2] = 3;
581 outbuf[3] = 2;
582 outbuf[4] = len - 5;
583
584 outbuf[7] = 0x10 | (s->tcq ? 0x02 : 0);
585 r->buf_len = len;
586 break;
587 case 0x16:
588 DPRINTF("Reserve(6)\n");
589 if (buf[1] & 1)
590 goto fail;
591 break;
592 case 0x17:
593 DPRINTF("Release(6)\n");
594 if (buf[1] & 1)
595 goto fail;
596 break;
597 case 0x1a:
598 case 0x5a:
599 {
600 uint8_t *p;
601 int page;
602
603 page = buf[2] & 0x3f;
604 DPRINTF("Mode Sense (page %d, len %d)\n", page, len);
605 p = outbuf;
606 memset(p, 0, 4);
607 outbuf[1] = 0;
608 outbuf[3] = 0;
609 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
610 outbuf[2] = 0x80;
611 }
612 p += 4;
613 if (page == 4) {
614 int cylinders, heads, secs;
615
616
617 p[0] = 4;
618 p[1] = 0x16;
619
620 bdrv_get_geometry_hint(s->bdrv, &cylinders, &heads, &secs);
621 p[2] = (cylinders >> 16) & 0xff;
622 p[3] = (cylinders >> 8) & 0xff;
623 p[4] = cylinders & 0xff;
624 p[5] = heads & 0xff;
625
626 p[6] = (cylinders >> 16) & 0xff;
627 p[7] = (cylinders >> 8) & 0xff;
628 p[8] = cylinders & 0xff;
629
630 p[9] = (cylinders >> 16) & 0xff;
631 p[10] = (cylinders >> 8) & 0xff;
632 p[11] = cylinders & 0xff;
633
634 p[12] = 0;
635 p[13] = 200;
636
637 p[14] = 0xff;
638 p[15] = 0xff;
639 p[16] = 0xff;
640
641 p[20] = (5400 >> 8) & 0xff;
642 p[21] = 5400 & 0xff;
643 p += 0x16;
644 } else if (page == 5) {
645 int cylinders, heads, secs;
646
647
648 p[0] = 5;
649 p[1] = 0x1e;
650
651 p[2] = 5000 >> 8;
652 p[3] = 5000 & 0xff;
653
654 bdrv_get_geometry_hint(s->bdrv, &cylinders, &heads, &secs);
655 p[4] = heads & 0xff;
656 p[5] = secs & 0xff;
657 p[6] = s->cluster_size * 2;
658 p[8] = (cylinders >> 8) & 0xff;
659 p[9] = cylinders & 0xff;
660
661 p[10] = (cylinders >> 8) & 0xff;
662 p[11] = cylinders & 0xff;
663
664 p[12] = (cylinders >> 8) & 0xff;
665 p[13] = cylinders & 0xff;
666
667 p[14] = 0;
668 p[15] = 1;
669
670 p[16] = 1;
671
672 p[17] = 0;
673 p[18] = 1;
674
675 p[19] = 1;
676
677 p[20] = 1;
678
679 p[28] = (5400 >> 8) & 0xff;
680 p[29] = 5400 & 0xff;
681 p += 0x1e;
682 } else if ((page == 8 || page == 0x3f)) {
683
684 memset(p,0,20);
685 p[0] = 8;
686 p[1] = 0x12;
687 p[2] = 4;
688 p += 20;
689 }
690 if ((page == 0x3f || page == 0x2a)
691 && (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM)) {
692
693 p[0] = 0x2a;
694 p[1] = 0x14;
695 p[2] = 3;
696 p[3] = 0;
697 p[4] = 0x7f;
698
699 p[5] = 0xff;
700
701
702 p[6] = 0x2d | (bdrv_is_locked(s->bdrv)? 2 : 0);
703
704 p[7] = 0;
705
706 p[8] = (50 * 176) >> 8;
707 p[9] = (50 * 176) & 0xff;
708 p[10] = 0 >> 8;
709 p[11] = 0 & 0xff;
710 p[12] = 2048 >> 8;
711 p[13] = 2048 & 0xff;
712 p[14] = (16 * 176) >> 8;
713 p[15] = (16 * 176) & 0xff;
714 p[18] = (16 * 176) >> 8;
715 p[19] = (16 * 176) & 0xff;
716 p[20] = (16 * 176) >> 8;
717 p[21] = (16 * 176) & 0xff;
718 p += 22;
719 }
720 r->buf_len = p - outbuf;
721 outbuf[0] = r->buf_len - 4;
722 if (r->buf_len > len)
723 r->buf_len = len;
724 }
725 break;
726 case 0x1b:
727 DPRINTF("Start Stop Unit\n");
728 break;
729 case 0x1e:
730 DPRINTF("Prevent Allow Medium Removal (prevent = %d)\n", buf[4] & 3);
731 bdrv_set_locked(s->bdrv, buf[4] & 1);
732 break;
733 case 0x25:
734 DPRINTF("Read Capacity\n");
735
736 memset(outbuf, 0, 8);
737 bdrv_get_geometry(s->bdrv, &nb_sectors);
738 nb_sectors /= s->cluster_size;
739
740 if (nb_sectors) {
741 nb_sectors--;
742
743 s->max_lba = nb_sectors;
744
745 if (nb_sectors > UINT32_MAX)
746 nb_sectors = UINT32_MAX;
747 outbuf[0] = (nb_sectors >> 24) & 0xff;
748 outbuf[1] = (nb_sectors >> 16) & 0xff;
749 outbuf[2] = (nb_sectors >> 8) & 0xff;
750 outbuf[3] = nb_sectors & 0xff;
751 outbuf[4] = 0;
752 outbuf[5] = 0;
753 outbuf[6] = s->cluster_size * 2;
754 outbuf[7] = 0;
755 r->buf_len = 8;
756 } else {
757 scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_NOT_READY);
758 return 0;
759 }
760 break;
761 case 0x08:
762 case 0x28:
763 case 0x88:
764 DPRINTF("Read (sector %lld, count %d)\n", lba, len);
765 if (lba > s->max_lba)
766 goto illegal_lba;
767 r->sector = lba * s->cluster_size;
768 r->sector_count = len * s->cluster_size;
769 break;
770 case 0x0a:
771 case 0x2a:
772 case 0x8a:
773 DPRINTF("Write (sector %lld, count %d)\n", lba, len);
774 if (lba > s->max_lba)
775 goto illegal_lba;
776 r->sector = lba * s->cluster_size;
777 r->sector_count = len * s->cluster_size;
778 is_write = 1;
779 break;
780 case 0x35:
781 DPRINTF("Synchronise cache (sector %d, count %d)\n", lba, len);
782 bdrv_flush(s->bdrv);
783 break;
784 case 0x43:
785 {
786 int start_track, format, msf, toclen;
787
788 msf = buf[1] & 2;
789 format = buf[2] & 0xf;
790 start_track = buf[6];
791 bdrv_get_geometry(s->bdrv, &nb_sectors);
792 DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
793 switch(format) {
794 case 0:
795 toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
796 break;
797 case 1:
798
799 toclen = 12;
800 memset(outbuf, 0, 12);
801 outbuf[1] = 0x0a;
802 outbuf[2] = 0x01;
803 outbuf[3] = 0x01;
804 break;
805 case 2:
806 toclen = cdrom_read_toc_raw(nb_sectors, outbuf, msf, start_track);
807 break;
808 default:
809 goto error_cmd;
810 }
811 if (toclen > 0) {
812 if (len > toclen)
813 len = toclen;
814 r->buf_len = len;
815 break;
816 }
817 error_cmd:
818 DPRINTF("Read TOC error\n");
819 goto fail;
820 }
821 case 0x46:
822 DPRINTF("Get Configuration (rt %d, maxlen %d)\n", buf[1] & 3, len);
823 memset(outbuf, 0, 8);
824
825
826 outbuf[7] = 8;
827 r->buf_len = 8;
828 break;
829 case 0x56:
830 DPRINTF("Reserve(10)\n");
831 if (buf[1] & 3)
832 goto fail;
833 break;
834 case 0x57:
835 DPRINTF("Release(10)\n");
836 if (buf[1] & 3)
837 goto fail;
838 break;
839 case 0x9e:
840
841 if ((buf[1] & 31) == 0x10) {
842 DPRINTF("SAI READ CAPACITY(16)\n");
843 memset(outbuf, 0, len);
844 bdrv_get_geometry(s->bdrv, &nb_sectors);
845 nb_sectors /= s->cluster_size;
846
847 if (nb_sectors) {
848 nb_sectors--;
849
850 s->max_lba = nb_sectors;
851 outbuf[0] = (nb_sectors >> 56) & 0xff;
852 outbuf[1] = (nb_sectors >> 48) & 0xff;
853 outbuf[2] = (nb_sectors >> 40) & 0xff;
854 outbuf[3] = (nb_sectors >> 32) & 0xff;
855 outbuf[4] = (nb_sectors >> 24) & 0xff;
856 outbuf[5] = (nb_sectors >> 16) & 0xff;
857 outbuf[6] = (nb_sectors >> 8) & 0xff;
858 outbuf[7] = nb_sectors & 0xff;
859 outbuf[8] = 0;
860 outbuf[9] = 0;
861 outbuf[10] = s->cluster_size * 2;
862 outbuf[11] = 0;
863
864 r->buf_len = len;
865 } else {
866 scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_NOT_READY);
867 return 0;
868 }
869 break;
870 }
871 DPRINTF("Unsupported Service Action In\n");
872 goto fail;
873 case 0xa0:
874 DPRINTF("Report LUNs (len %d)\n", len);
875 if (len < 16)
876 goto fail;
877 memset(outbuf, 0, 16);
878 outbuf[3] = 8;
879 r->buf_len = 16;
880 break;
881 case 0x2f:
882 DPRINTF("Verify (sector %d, count %d)\n", lba, len);
883 break;
884 default:
885 DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
886 fail:
887 scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_ILLEGAL_REQUEST);
888 return 0;
889 illegal_lba:
890 scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR);
891 return 0;
892 }
893 if (r->sector_count == 0 && r->buf_len == 0) {
894 scsi_command_complete(r, STATUS_GOOD, SENSE_NO_SENSE);
895 }
896 len = r->sector_count * 512 + r->buf_len;
897 if (is_write) {
898 return -len;
899 } else {
900 if (!r->sector_count)
901 r->sector_count = -1;
902 return len;
903 }
904}
905
906static void scsi_destroy(SCSIDevice *d)
907{
908 qemu_free(d->state);
909 qemu_free(d);
910}
911
912SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, int tcq,
913 scsi_completionfn completion, void *opaque)
914{
915 SCSIDevice *d;
916 SCSIDeviceState *s;
917 uint64_t nb_sectors;
918
919 s = (SCSIDeviceState *)qemu_mallocz(sizeof(SCSIDeviceState));
920 s->bdrv = bdrv;
921 s->tcq = tcq;
922 s->completion = completion;
923 s->opaque = opaque;
924 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
925 s->cluster_size = 4;
926 } else {
927 s->cluster_size = 1;
928 }
929 bdrv_get_geometry(s->bdrv, &nb_sectors);
930 nb_sectors /= s->cluster_size;
931 if (nb_sectors)
932 nb_sectors--;
933 s->max_lba = nb_sectors;
934 strncpy(s->drive_serial_str, drive_get_serial(s->bdrv),
935 sizeof(s->drive_serial_str));
936 if (strlen(s->drive_serial_str) == 0)
937 pstrcpy(s->drive_serial_str, sizeof(s->drive_serial_str), "0");
938 qemu_add_vm_change_state_handler(scsi_dma_restart_cb, s);
939 d = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
940 d->state = s;
941 d->destroy = scsi_destroy;
942 d->send_command = scsi_send_command;
943 d->read_data = scsi_read_data;
944 d->write_data = scsi_write_data;
945 d->cancel_io = scsi_cancel_io;
946 d->get_buf = scsi_get_buf;
947
948 return d;
949}
950