Fix warning about unused shm_regions
[qemu/mini2440.git] / hw / scsi-disk.c
blob9a0841156b11ab6325f39bfb550236eeb5cb824b
1 /*
2 * SCSI Device emulation
4 * Copyright (c) 2006 CodeSourcery.
5 * Based on code by Fabrice Bellard
7 * Written by Paul Brook
9 * This code is licenced under the LGPL.
11 * Note that this file only handles the SCSI architecture model and device
12 * commands. Emulation of interface/link layer protocols is handled by
13 * the host adapter emulator.
16 //#define DEBUG_SCSI
18 #ifdef DEBUG_SCSI
19 #define DPRINTF(fmt, args...) \
20 do { printf("scsi-disk: " fmt , ##args); } while (0)
21 #else
22 #define DPRINTF(fmt, args...) do {} while(0)
23 #endif
25 #define BADF(fmt, args...) \
26 do { fprintf(stderr, "scsi-disk: " fmt , ##args); } while (0)
28 #include "qemu-common.h"
29 #include "block.h"
30 #include "scsi-disk.h"
32 #define SENSE_NO_SENSE 0
33 #define SENSE_NOT_READY 2
34 #define SENSE_HARDWARE_ERROR 4
35 #define SENSE_ILLEGAL_REQUEST 5
37 #define STATUS_GOOD 0
38 #define STATUS_CHECK_CONDITION 2
40 #define SCSI_DMA_BUF_SIZE 131072
41 #define SCSI_MAX_INQUIRY_LEN 256
43 typedef struct SCSIRequest {
44 SCSIDeviceState *dev;
45 uint32_t tag;
46 /* ??? We should probably keep track of whether the data trasfer is
47 a read or a write. Currently we rely on the host getting it right. */
48 /* Both sector and sector_count are in terms of qemu 512 byte blocks. */
49 int sector;
50 int sector_count;
51 /* The amounnt of data in the buffer. */
52 int buf_len;
53 uint8_t *dma_buf;
54 BlockDriverAIOCB *aiocb;
55 struct SCSIRequest *next;
56 } SCSIRequest;
58 struct SCSIDeviceState
60 BlockDriverState *bdrv;
61 SCSIRequest *requests;
62 /* The qemu block layer uses a fixed 512 byte sector size.
63 This is the number of 512 byte blocks in a single scsi sector. */
64 int cluster_size;
65 int sense;
66 int tcq;
67 /* Completion functions may be called from either scsi_{read,write}_data
68 or from the AIO completion routines. */
69 scsi_completionfn completion;
70 void *opaque;
73 /* Global pool of SCSIRequest structures. */
74 static SCSIRequest *free_requests = NULL;
76 static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag)
78 SCSIRequest *r;
80 if (free_requests) {
81 r = free_requests;
82 free_requests = r->next;
83 } else {
84 r = qemu_malloc(sizeof(SCSIRequest));
85 r->dma_buf = qemu_memalign(512, SCSI_DMA_BUF_SIZE);
87 r->dev = s;
88 r->tag = tag;
89 r->sector_count = 0;
90 r->buf_len = 0;
91 r->aiocb = NULL;
93 r->next = s->requests;
94 s->requests = r;
95 return r;
98 static void scsi_remove_request(SCSIRequest *r)
100 SCSIRequest *last;
101 SCSIDeviceState *s = r->dev;
103 if (s->requests == r) {
104 s->requests = r->next;
105 } else {
106 last = s->requests;
107 while (last && last->next != r)
108 last = last->next;
109 if (last) {
110 last->next = r->next;
111 } else {
112 BADF("Orphaned request\n");
115 r->next = free_requests;
116 free_requests = r;
119 static SCSIRequest *scsi_find_request(SCSIDeviceState *s, uint32_t tag)
121 SCSIRequest *r;
123 r = s->requests;
124 while (r && r->tag != tag)
125 r = r->next;
127 return r;
130 /* Helper function for command completion. */
131 static void scsi_command_complete(SCSIRequest *r, int status, int sense)
133 SCSIDeviceState *s = r->dev;
134 uint32_t tag;
135 DPRINTF("Command complete tag=0x%x status=%d sense=%d\n", r->tag, status, sense);
136 s->sense = sense;
137 tag = r->tag;
138 scsi_remove_request(r);
139 s->completion(s->opaque, SCSI_REASON_DONE, tag, status);
142 /* Cancel a pending data transfer. */
143 static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
145 SCSIDeviceState *s = d->state;
146 SCSIRequest *r;
147 DPRINTF("Cancel tag=0x%x\n", tag);
148 r = scsi_find_request(s, tag);
149 if (r) {
150 if (r->aiocb)
151 bdrv_aio_cancel(r->aiocb);
152 r->aiocb = NULL;
153 scsi_remove_request(r);
157 static void scsi_read_complete(void * opaque, int ret)
159 SCSIRequest *r = (SCSIRequest *)opaque;
160 SCSIDeviceState *s = r->dev;
162 if (ret) {
163 DPRINTF("IO error\n");
164 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, 0);
165 scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_NO_SENSE);
166 return;
168 DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, r->buf_len);
170 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->buf_len);
173 /* Read more data from scsi device into buffer. */
174 static void scsi_read_data(SCSIDevice *d, uint32_t tag)
176 SCSIDeviceState *s = d->state;
177 SCSIRequest *r;
178 uint32_t n;
180 r = scsi_find_request(s, tag);
181 if (!r) {
182 BADF("Bad read tag 0x%x\n", tag);
183 /* ??? This is the wrong error. */
184 scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR);
185 return;
187 if (r->sector_count == (uint32_t)-1) {
188 DPRINTF("Read buf_len=%d\n", r->buf_len);
189 r->sector_count = 0;
190 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->buf_len);
191 return;
193 DPRINTF("Read sector_count=%d\n", r->sector_count);
194 if (r->sector_count == 0) {
195 scsi_command_complete(r, STATUS_GOOD, SENSE_NO_SENSE);
196 return;
199 n = r->sector_count;
200 if (n > SCSI_DMA_BUF_SIZE / 512)
201 n = SCSI_DMA_BUF_SIZE / 512;
203 r->buf_len = n * 512;
204 r->aiocb = bdrv_aio_read(s->bdrv, r->sector, r->dma_buf, n,
205 scsi_read_complete, r);
206 if (r->aiocb == NULL)
207 scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR);
208 r->sector += n;
209 r->sector_count -= n;
212 static void scsi_write_complete(void * opaque, int ret)
214 SCSIRequest *r = (SCSIRequest *)opaque;
215 SCSIDeviceState *s = r->dev;
216 uint32_t len;
218 if (ret) {
219 fprintf(stderr, "scsi-disc: IO write error\n");
220 exit(1);
223 r->aiocb = NULL;
224 if (r->sector_count == 0) {
225 scsi_command_complete(r, STATUS_GOOD, SENSE_NO_SENSE);
226 } else {
227 len = r->sector_count * 512;
228 if (len > SCSI_DMA_BUF_SIZE) {
229 len = SCSI_DMA_BUF_SIZE;
231 r->buf_len = len;
232 DPRINTF("Write complete tag=0x%x more=%d\n", r->tag, len);
233 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, len);
237 /* Write data to a scsi device. Returns nonzero on failure.
238 The transfer may complete asynchronously. */
239 static int scsi_write_data(SCSIDevice *d, uint32_t tag)
241 SCSIDeviceState *s = d->state;
242 SCSIRequest *r;
243 uint32_t n;
245 DPRINTF("Write data tag=0x%x\n", tag);
246 r = scsi_find_request(s, tag);
247 if (!r) {
248 BADF("Bad write tag 0x%x\n", tag);
249 scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR);
250 return 1;
252 if (r->aiocb)
253 BADF("Data transfer already in progress\n");
254 n = r->buf_len / 512;
255 if (n) {
256 r->aiocb = bdrv_aio_write(s->bdrv, r->sector, r->dma_buf, n,
257 scsi_write_complete, r);
258 if (r->aiocb == NULL)
259 scsi_command_complete(r, STATUS_CHECK_CONDITION,
260 SENSE_HARDWARE_ERROR);
261 r->sector += n;
262 r->sector_count -= n;
263 } else {
264 /* Invoke completion routine to fetch data from host. */
265 scsi_write_complete(r, 0);
268 return 0;
271 /* Return a pointer to the data buffer. */
272 static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
274 SCSIDeviceState *s = d->state;
275 SCSIRequest *r;
277 r = scsi_find_request(s, tag);
278 if (!r) {
279 BADF("Bad buffer tag 0x%x\n", tag);
280 return NULL;
282 return r->dma_buf;
285 /* Execute a scsi command. Returns the length of the data expected by the
286 command. This will be Positive for data transfers from the device
287 (eg. disk reads), negative for transfers to the device (eg. disk writes),
288 and zero if the command does not transfer any data. */
290 static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
291 uint8_t *buf, int lun)
293 SCSIDeviceState *s = d->state;
294 uint64_t nb_sectors;
295 uint32_t lba;
296 uint32_t len;
297 int cmdlen;
298 int is_write;
299 uint8_t command;
300 uint8_t *outbuf;
301 SCSIRequest *r;
303 command = buf[0];
304 r = scsi_find_request(s, tag);
305 if (r) {
306 BADF("Tag 0x%x already in use\n", tag);
307 scsi_cancel_io(d, tag);
309 /* ??? Tags are not unique for different luns. We only implement a
310 single lun, so this should not matter. */
311 r = scsi_new_request(s, tag);
312 outbuf = r->dma_buf;
313 is_write = 0;
314 DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
315 switch (command >> 5) {
316 case 0:
317 lba = buf[3] | (buf[2] << 8) | ((buf[1] & 0x1f) << 16);
318 len = buf[4];
319 cmdlen = 6;
320 break;
321 case 1:
322 case 2:
323 lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
324 len = buf[8] | (buf[7] << 8);
325 cmdlen = 10;
326 break;
327 case 4:
328 lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
329 len = buf[13] | (buf[12] << 8) | (buf[11] << 16) | (buf[10] << 24);
330 cmdlen = 16;
331 break;
332 case 5:
333 lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
334 len = buf[9] | (buf[8] << 8) | (buf[7] << 16) | (buf[6] << 24);
335 cmdlen = 12;
336 break;
337 default:
338 BADF("Unsupported command length, command %x\n", command);
339 goto fail;
341 #ifdef DEBUG_SCSI
343 int i;
344 for (i = 1; i < cmdlen; i++) {
345 printf(" 0x%02x", buf[i]);
347 printf("\n");
349 #endif
350 if (lun || buf[1] >> 5) {
351 /* Only LUN 0 supported. */
352 DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5);
353 if (command != 0x03 && command != 0x12) /* REQUEST SENSE and INQUIRY */
354 goto fail;
356 switch (command) {
357 case 0x0:
358 DPRINTF("Test Unit Ready\n");
359 break;
360 case 0x03:
361 DPRINTF("Request Sense (len %d)\n", len);
362 if (len < 4)
363 goto fail;
364 memset(outbuf, 0, 4);
365 outbuf[0] = 0xf0;
366 outbuf[1] = 0;
367 outbuf[2] = s->sense;
368 r->buf_len = 4;
369 break;
370 case 0x12:
371 DPRINTF("Inquiry (len %d)\n", len);
372 if (buf[1] & 0x2) {
373 /* Command support data - optional, not implemented */
374 BADF("optional INQUIRY command support request not implemented\n");
375 goto fail;
377 else if (buf[1] & 0x1) {
378 /* Vital product data */
379 uint8_t page_code = buf[2];
380 if (len < 4) {
381 BADF("Error: Inquiry (EVPD[%02X]) buffer size %d is "
382 "less than 4\n", page_code, len);
383 goto fail;
386 switch (page_code) {
387 case 0x00:
389 /* Supported page codes, mandatory */
390 DPRINTF("Inquiry EVPD[Supported pages] "
391 "buffer size %d\n", len);
393 r->buf_len = 0;
395 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
396 outbuf[r->buf_len++] = 5;
397 } else {
398 outbuf[r->buf_len++] = 0;
401 outbuf[r->buf_len++] = 0x00; // this page
402 outbuf[r->buf_len++] = 0x00;
403 outbuf[r->buf_len++] = 3; // number of pages
404 outbuf[r->buf_len++] = 0x00; // list of supported pages (this page)
405 outbuf[r->buf_len++] = 0x80; // unit serial number
406 outbuf[r->buf_len++] = 0x83; // device identification
408 break;
409 case 0x80:
411 /* Device serial number, optional */
412 if (len < 4) {
413 BADF("Error: EVPD[Serial number] Inquiry buffer "
414 "size %d too small, %d needed\n", len, 4);
415 goto fail;
418 DPRINTF("Inquiry EVPD[Serial number] buffer size %d\n", len);
420 r->buf_len = 0;
422 /* Supported page codes */
423 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
424 outbuf[r->buf_len++] = 5;
425 } else {
426 outbuf[r->buf_len++] = 0;
429 outbuf[r->buf_len++] = 0x80; // this page
430 outbuf[r->buf_len++] = 0x00;
431 outbuf[r->buf_len++] = 0x01; // 1 byte data follow
433 outbuf[r->buf_len++] = '0'; // 1 byte data follow
436 break;
437 case 0x83:
439 /* Device identification page, mandatory */
440 int max_len = 255 - 8;
441 int id_len = strlen(bdrv_get_device_name(s->bdrv));
442 if (id_len > max_len)
443 id_len = max_len;
445 DPRINTF("Inquiry EVPD[Device identification] "
446 "buffer size %d\n", len);
447 r->buf_len = 0;
448 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
449 outbuf[r->buf_len++] = 5;
450 } else {
451 outbuf[r->buf_len++] = 0;
454 outbuf[r->buf_len++] = 0x83; // this page
455 outbuf[r->buf_len++] = 0x00;
456 outbuf[r->buf_len++] = 3 + id_len;
458 outbuf[r->buf_len++] = 0x2; // ASCII
459 outbuf[r->buf_len++] = 0; // not officially assigned
460 outbuf[r->buf_len++] = 0; // reserved
461 outbuf[r->buf_len++] = id_len; // length of data following
463 memcpy(&outbuf[r->buf_len],
464 bdrv_get_device_name(s->bdrv), id_len);
465 r->buf_len += id_len;
467 break;
468 default:
469 BADF("Error: unsupported Inquiry (EVPD[%02X]) "
470 "buffer size %d\n", page_code, len);
471 goto fail;
473 /* done with EVPD */
474 break;
476 else {
477 /* Standard INQUIRY data */
478 if (buf[2] != 0) {
479 BADF("Error: Inquiry (STANDARD) page or code "
480 "is non-zero [%02X]\n", buf[2]);
481 goto fail;
484 /* PAGE CODE == 0 */
485 if (len < 5) {
486 BADF("Error: Inquiry (STANDARD) buffer size %d "
487 "is less than 5\n", len);
488 goto fail;
491 if (len < 36) {
492 BADF("Error: Inquiry (STANDARD) buffer size %d "
493 "is less than 36 (TODO: only 5 required)\n", len);
497 if(len > SCSI_MAX_INQUIRY_LEN)
498 len = SCSI_MAX_INQUIRY_LEN;
500 memset(outbuf, 0, len);
502 if (lun || buf[1] >> 5) {
503 outbuf[0] = 0x7f; /* LUN not supported */
504 } else if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
505 outbuf[0] = 5;
506 outbuf[1] = 0x80;
507 memcpy(&outbuf[16], "QEMU CD-ROM ", 16);
508 } else {
509 outbuf[0] = 0;
510 memcpy(&outbuf[16], "QEMU HARDDISK ", 16);
512 memcpy(&outbuf[8], "QEMU ", 8);
513 memcpy(&outbuf[32], QEMU_VERSION, 4);
514 /* Identify device as SCSI-3 rev 1.
515 Some later commands are also implemented. */
516 outbuf[2] = 3;
517 outbuf[3] = 2; /* Format 2 */
518 outbuf[4] = len - 5; /* Additional Length = (Len - 1) - 4 */
519 /* Sync data transfer and TCQ. */
520 outbuf[7] = 0x10 | (s->tcq ? 0x02 : 0);
521 r->buf_len = len;
522 break;
523 case 0x16:
524 DPRINTF("Reserve(6)\n");
525 if (buf[1] & 1)
526 goto fail;
527 break;
528 case 0x17:
529 DPRINTF("Release(6)\n");
530 if (buf[1] & 1)
531 goto fail;
532 break;
533 case 0x1a:
534 case 0x5a:
536 uint8_t *p;
537 int page;
539 page = buf[2] & 0x3f;
540 DPRINTF("Mode Sense (page %d, len %d)\n", page, len);
541 p = outbuf;
542 memset(p, 0, 4);
543 outbuf[1] = 0; /* Default media type. */
544 outbuf[3] = 0; /* Block descriptor length. */
545 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
546 outbuf[2] = 0x80; /* Readonly. */
548 p += 4;
549 if (page == 4) {
550 int cylinders, heads, secs;
552 /* Rigid disk device geometry page. */
553 p[0] = 4;
554 p[1] = 0x16;
555 /* if a geometry hint is available, use it */
556 bdrv_get_geometry_hint(s->bdrv, &cylinders, &heads, &secs);
557 p[2] = (cylinders >> 16) & 0xff;
558 p[3] = (cylinders >> 8) & 0xff;
559 p[4] = cylinders & 0xff;
560 p[5] = heads & 0xff;
561 /* Write precomp start cylinder, disabled */
562 p[6] = (cylinders >> 16) & 0xff;
563 p[7] = (cylinders >> 8) & 0xff;
564 p[8] = cylinders & 0xff;
565 /* Reduced current start cylinder, disabled */
566 p[9] = (cylinders >> 16) & 0xff;
567 p[10] = (cylinders >> 8) & 0xff;
568 p[11] = cylinders & 0xff;
569 /* Device step rate [ns], 200ns */
570 p[12] = 0;
571 p[13] = 200;
572 /* Landing zone cylinder */
573 p[14] = 0xff;
574 p[15] = 0xff;
575 p[16] = 0xff;
576 /* Medium rotation rate [rpm], 5400 rpm */
577 p[20] = (5400 >> 8) & 0xff;
578 p[21] = 5400 & 0xff;
579 p += 0x16;
580 } else if (page == 5) {
581 int cylinders, heads, secs;
583 /* Flexible disk device geometry page. */
584 p[0] = 5;
585 p[1] = 0x1e;
586 /* Transfer rate [kbit/s], 5Mbit/s */
587 p[2] = 5000 >> 8;
588 p[3] = 5000 & 0xff;
589 /* if a geometry hint is available, use it */
590 bdrv_get_geometry_hint(s->bdrv, &cylinders, &heads, &secs);
591 p[4] = heads & 0xff;
592 p[5] = secs & 0xff;
593 p[6] = s->cluster_size * 2;
594 p[8] = (cylinders >> 8) & 0xff;
595 p[9] = cylinders & 0xff;
596 /* Write precomp start cylinder, disabled */
597 p[10] = (cylinders >> 8) & 0xff;
598 p[11] = cylinders & 0xff;
599 /* Reduced current start cylinder, disabled */
600 p[12] = (cylinders >> 8) & 0xff;
601 p[13] = cylinders & 0xff;
602 /* Device step rate [100us], 100us */
603 p[14] = 0;
604 p[15] = 1;
605 /* Device step pulse width [us], 1us */
606 p[16] = 1;
607 /* Device head settle delay [100us], 100us */
608 p[17] = 0;
609 p[18] = 1;
610 /* Motor on delay [0.1s], 0.1s */
611 p[19] = 1;
612 /* Motor off delay [0.1s], 0.1s */
613 p[20] = 1;
614 /* Medium rotation rate [rpm], 5400 rpm */
615 p[28] = (5400 >> 8) & 0xff;
616 p[29] = 5400 & 0xff;
617 p += 0x1e;
618 } else if ((page == 8 || page == 0x3f)) {
619 /* Caching page. */
620 memset(p,0,20);
621 p[0] = 8;
622 p[1] = 0x12;
623 p[2] = 4; /* WCE */
624 p += 20;
626 if ((page == 0x3f || page == 0x2a)
627 && (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM)) {
628 /* CD Capabilities and Mechanical Status page. */
629 p[0] = 0x2a;
630 p[1] = 0x14;
631 p[2] = 3; // CD-R & CD-RW read
632 p[3] = 0; // Writing not supported
633 p[4] = 0x7f; /* Audio, composite, digital out,
634 mode 2 form 1&2, multi session */
635 p[5] = 0xff; /* CD DA, DA accurate, RW supported,
636 RW corrected, C2 errors, ISRC,
637 UPC, Bar code */
638 p[6] = 0x2d | (bdrv_is_locked(s->bdrv)? 2 : 0);
639 /* Locking supported, jumper present, eject, tray */
640 p[7] = 0; /* no volume & mute control, no
641 changer */
642 p[8] = (50 * 176) >> 8; // 50x read speed
643 p[9] = (50 * 176) & 0xff;
644 p[10] = 0 >> 8; // No volume
645 p[11] = 0 & 0xff;
646 p[12] = 2048 >> 8; // 2M buffer
647 p[13] = 2048 & 0xff;
648 p[14] = (16 * 176) >> 8; // 16x read speed current
649 p[15] = (16 * 176) & 0xff;
650 p[18] = (16 * 176) >> 8; // 16x write speed
651 p[19] = (16 * 176) & 0xff;
652 p[20] = (16 * 176) >> 8; // 16x write speed current
653 p[21] = (16 * 176) & 0xff;
654 p += 22;
656 r->buf_len = p - outbuf;
657 outbuf[0] = r->buf_len - 4;
658 if (r->buf_len > len)
659 r->buf_len = len;
661 break;
662 case 0x1b:
663 DPRINTF("Start Stop Unit\n");
664 break;
665 case 0x1e:
666 DPRINTF("Prevent Allow Medium Removal (prevent = %d)\n", buf[4] & 3);
667 bdrv_set_locked(s->bdrv, buf[4] & 1);
668 break;
669 case 0x25:
670 DPRINTF("Read Capacity\n");
671 /* The normal LEN field for this command is zero. */
672 memset(outbuf, 0, 8);
673 bdrv_get_geometry(s->bdrv, &nb_sectors);
674 /* Returned value is the address of the last sector. */
675 if (nb_sectors) {
676 nb_sectors--;
677 outbuf[0] = (nb_sectors >> 24) & 0xff;
678 outbuf[1] = (nb_sectors >> 16) & 0xff;
679 outbuf[2] = (nb_sectors >> 8) & 0xff;
680 outbuf[3] = nb_sectors & 0xff;
681 outbuf[4] = 0;
682 outbuf[5] = 0;
683 outbuf[6] = s->cluster_size * 2;
684 outbuf[7] = 0;
685 r->buf_len = 8;
686 } else {
687 scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_NOT_READY);
688 return 0;
690 break;
691 case 0x08:
692 case 0x28:
693 DPRINTF("Read (sector %d, count %d)\n", lba, len);
694 r->sector = lba * s->cluster_size;
695 r->sector_count = len * s->cluster_size;
696 break;
697 case 0x0a:
698 case 0x2a:
699 DPRINTF("Write (sector %d, count %d)\n", lba, len);
700 r->sector = lba * s->cluster_size;
701 r->sector_count = len * s->cluster_size;
702 is_write = 1;
703 break;
704 case 0x35:
705 DPRINTF("Synchronise cache (sector %d, count %d)\n", lba, len);
706 bdrv_flush(s->bdrv);
707 break;
708 case 0x43:
710 int start_track, format, msf, toclen;
712 msf = buf[1] & 2;
713 format = buf[2] & 0xf;
714 start_track = buf[6];
715 bdrv_get_geometry(s->bdrv, &nb_sectors);
716 DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
717 switch(format) {
718 case 0:
719 toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
720 break;
721 case 1:
722 /* multi session : only a single session defined */
723 toclen = 12;
724 memset(outbuf, 0, 12);
725 outbuf[1] = 0x0a;
726 outbuf[2] = 0x01;
727 outbuf[3] = 0x01;
728 break;
729 case 2:
730 toclen = cdrom_read_toc_raw(nb_sectors, outbuf, msf, start_track);
731 break;
732 default:
733 goto error_cmd;
735 if (toclen > 0) {
736 if (len > toclen)
737 len = toclen;
738 r->buf_len = len;
739 break;
741 error_cmd:
742 DPRINTF("Read TOC error\n");
743 goto fail;
745 case 0x46:
746 DPRINTF("Get Configuration (rt %d, maxlen %d)\n", buf[1] & 3, len);
747 memset(outbuf, 0, 8);
748 /* ??? This should probably return much more information. For now
749 just return the basic header indicating the CD-ROM profile. */
750 outbuf[7] = 8; // CD-ROM
751 r->buf_len = 8;
752 break;
753 case 0x56:
754 DPRINTF("Reserve(10)\n");
755 if (buf[1] & 3)
756 goto fail;
757 break;
758 case 0x57:
759 DPRINTF("Release(10)\n");
760 if (buf[1] & 3)
761 goto fail;
762 break;
763 case 0xa0:
764 DPRINTF("Report LUNs (len %d)\n", len);
765 if (len < 16)
766 goto fail;
767 memset(outbuf, 0, 16);
768 outbuf[3] = 8;
769 r->buf_len = 16;
770 break;
771 case 0x2f:
772 DPRINTF("Verify (sector %d, count %d)\n", lba, len);
773 break;
774 default:
775 DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
776 fail:
777 scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_ILLEGAL_REQUEST);
778 return 0;
780 if (r->sector_count == 0 && r->buf_len == 0) {
781 scsi_command_complete(r, STATUS_GOOD, SENSE_NO_SENSE);
783 len = r->sector_count * 512 + r->buf_len;
784 if (is_write) {
785 return -len;
786 } else {
787 if (!r->sector_count)
788 r->sector_count = -1;
789 return len;
793 static void scsi_destroy(SCSIDevice *d)
795 qemu_free(d->state);
796 qemu_free(d);
799 SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, int tcq,
800 scsi_completionfn completion, void *opaque)
802 SCSIDevice *d;
803 SCSIDeviceState *s;
805 s = (SCSIDeviceState *)qemu_mallocz(sizeof(SCSIDeviceState));
806 s->bdrv = bdrv;
807 s->tcq = tcq;
808 s->completion = completion;
809 s->opaque = opaque;
810 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
811 s->cluster_size = 4;
812 } else {
813 s->cluster_size = 1;
816 d = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
817 d->state = s;
818 d->destroy = scsi_destroy;
819 d->send_command = scsi_send_command;
820 d->read_data = scsi_read_data;
821 d->write_data = scsi_write_data;
822 d->cancel_io = scsi_cancel_io;
823 d->get_buf = scsi_get_buf;
825 return d;