Misc fixes (Herve Poussineau)
[qemu/mini2440/sniper_sniper_test.git] / hw / scsi-disk.c
blobf7aa6d7a4333bdad80d7e81f7865ec6bc224c7b4
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
42 typedef struct SCSIRequest {
43 SCSIDeviceState *dev;
44 uint32_t tag;
45 /* ??? We should probably keep track of whether the data trasfer is
46 a read or a write. Currently we rely on the host getting it right. */
47 /* Both sector and sector_count are in terms of qemu 512 byte blocks. */
48 int sector;
49 int sector_count;
50 /* The amounnt of data in the buffer. */
51 int buf_len;
52 uint8_t *dma_buf;
53 BlockDriverAIOCB *aiocb;
54 struct SCSIRequest *next;
55 } SCSIRequest;
57 struct SCSIDeviceState
59 BlockDriverState *bdrv;
60 SCSIRequest *requests;
61 /* The qemu block layer uses a fixed 512 byte sector size.
62 This is the number of 512 byte blocks in a single scsi sector. */
63 int cluster_size;
64 int sense;
65 int tcq;
66 /* Completion functions may be called from either scsi_{read,write}_data
67 or from the AIO completion routines. */
68 scsi_completionfn completion;
69 void *opaque;
72 /* Global pool of SCSIRequest structures. */
73 static SCSIRequest *free_requests = NULL;
75 static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag)
77 SCSIRequest *r;
79 if (free_requests) {
80 r = free_requests;
81 free_requests = r->next;
82 } else {
83 r = qemu_malloc(sizeof(SCSIRequest));
84 r->dma_buf = qemu_memalign(512, SCSI_DMA_BUF_SIZE);
86 r->dev = s;
87 r->tag = tag;
88 r->sector_count = 0;
89 r->buf_len = 0;
90 r->aiocb = NULL;
92 r->next = s->requests;
93 s->requests = r;
94 return r;
97 static void scsi_remove_request(SCSIRequest *r)
99 SCSIRequest *last;
100 SCSIDeviceState *s = r->dev;
102 if (s->requests == r) {
103 s->requests = r->next;
104 } else {
105 last = s->requests;
106 while (last && last->next != r)
107 last = last->next;
108 if (last) {
109 last->next = r->next;
110 } else {
111 BADF("Orphaned request\n");
114 r->next = free_requests;
115 free_requests = r;
118 static SCSIRequest *scsi_find_request(SCSIDeviceState *s, uint32_t tag)
120 SCSIRequest *r;
122 r = s->requests;
123 while (r && r->tag != tag)
124 r = r->next;
126 return r;
129 /* Helper function for command completion. */
130 static void scsi_command_complete(SCSIRequest *r, int status, int sense)
132 SCSIDeviceState *s = r->dev;
133 uint32_t tag;
134 DPRINTF("Command complete tag=0x%x status=%d sense=%d\n", r->tag, status, sense);
135 s->sense = sense;
136 tag = r->tag;
137 scsi_remove_request(r);
138 s->completion(s->opaque, SCSI_REASON_DONE, tag, status);
141 /* Cancel a pending data transfer. */
142 static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
144 SCSIDeviceState *s = d->state;
145 SCSIRequest *r;
146 DPRINTF("Cancel tag=0x%x\n", tag);
147 r = scsi_find_request(s, tag);
148 if (r) {
149 if (r->aiocb)
150 bdrv_aio_cancel(r->aiocb);
151 r->aiocb = NULL;
152 scsi_remove_request(r);
156 static void scsi_read_complete(void * opaque, int ret)
158 SCSIRequest *r = (SCSIRequest *)opaque;
159 SCSIDeviceState *s = r->dev;
161 if (ret) {
162 DPRINTF("IO error\n");
163 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, 0);
164 scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_NO_SENSE);
165 return;
167 DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, r->buf_len);
169 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->buf_len);
172 /* Read more data from scsi device into buffer. */
173 static void scsi_read_data(SCSIDevice *d, uint32_t tag)
175 SCSIDeviceState *s = d->state;
176 SCSIRequest *r;
177 uint32_t n;
179 r = scsi_find_request(s, tag);
180 if (!r) {
181 BADF("Bad read tag 0x%x\n", tag);
182 /* ??? This is the wrong error. */
183 scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR);
184 return;
186 if (r->sector_count == (uint32_t)-1) {
187 DPRINTF("Read buf_len=%d\n", r->buf_len);
188 r->sector_count = 0;
189 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->buf_len);
190 return;
192 DPRINTF("Read sector_count=%d\n", r->sector_count);
193 if (r->sector_count == 0) {
194 scsi_command_complete(r, STATUS_GOOD, SENSE_NO_SENSE);
195 return;
198 n = r->sector_count;
199 if (n > SCSI_DMA_BUF_SIZE / 512)
200 n = SCSI_DMA_BUF_SIZE / 512;
202 r->buf_len = n * 512;
203 r->aiocb = bdrv_aio_read(s->bdrv, r->sector, r->dma_buf, n,
204 scsi_read_complete, r);
205 if (r->aiocb == NULL)
206 scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR);
207 r->sector += n;
208 r->sector_count -= n;
211 static void scsi_write_complete(void * opaque, int ret)
213 SCSIRequest *r = (SCSIRequest *)opaque;
214 SCSIDeviceState *s = r->dev;
215 uint32_t len;
217 if (ret) {
218 fprintf(stderr, "scsi-disc: IO write error\n");
219 exit(1);
222 r->aiocb = NULL;
223 if (r->sector_count == 0) {
224 scsi_command_complete(r, STATUS_GOOD, SENSE_NO_SENSE);
225 } else {
226 len = r->sector_count * 512;
227 if (len > SCSI_DMA_BUF_SIZE) {
228 len = SCSI_DMA_BUF_SIZE;
230 r->buf_len = len;
231 DPRINTF("Write complete tag=0x%x more=%d\n", r->tag, len);
232 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, len);
236 /* Write data to a scsi device. Returns nonzero on failure.
237 The transfer may complete asynchronously. */
238 static int scsi_write_data(SCSIDevice *d, uint32_t tag)
240 SCSIDeviceState *s = d->state;
241 SCSIRequest *r;
242 uint32_t n;
244 DPRINTF("Write data tag=0x%x\n", tag);
245 r = scsi_find_request(s, tag);
246 if (!r) {
247 BADF("Bad write tag 0x%x\n", tag);
248 scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR);
249 return 1;
251 if (r->aiocb)
252 BADF("Data transfer already in progress\n");
253 n = r->buf_len / 512;
254 if (n) {
255 r->aiocb = bdrv_aio_write(s->bdrv, r->sector, r->dma_buf, n,
256 scsi_write_complete, r);
257 if (r->aiocb == NULL)
258 scsi_command_complete(r, STATUS_CHECK_CONDITION,
259 SENSE_HARDWARE_ERROR);
260 r->sector += n;
261 r->sector_count -= n;
262 } else {
263 /* Invoke completion routine to fetch data from host. */
264 scsi_write_complete(r, 0);
267 return 0;
270 /* Return a pointer to the data buffer. */
271 static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
273 SCSIDeviceState *s = d->state;
274 SCSIRequest *r;
276 r = scsi_find_request(s, tag);
277 if (!r) {
278 BADF("Bad buffer tag 0x%x\n", tag);
279 return NULL;
281 return r->dma_buf;
284 /* Execute a scsi command. Returns the length of the data expected by the
285 command. This will be Positive for data transfers from the device
286 (eg. disk reads), negative for transfers to the device (eg. disk writes),
287 and zero if the command does not transfer any data. */
289 static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
290 uint8_t *buf, int lun)
292 SCSIDeviceState *s = d->state;
293 uint64_t nb_sectors;
294 uint32_t lba;
295 uint32_t len;
296 int cmdlen;
297 int is_write;
298 uint8_t command;
299 uint8_t *outbuf;
300 SCSIRequest *r;
302 command = buf[0];
303 r = scsi_find_request(s, tag);
304 if (r) {
305 BADF("Tag 0x%x already in use\n", tag);
306 scsi_cancel_io(d, tag);
308 /* ??? Tags are not unique for different luns. We only implement a
309 single lun, so this should not matter. */
310 r = scsi_new_request(s, tag);
311 outbuf = r->dma_buf;
312 is_write = 0;
313 DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
314 switch (command >> 5) {
315 case 0:
316 lba = buf[3] | (buf[2] << 8) | ((buf[1] & 0x1f) << 16);
317 len = buf[4];
318 cmdlen = 6;
319 break;
320 case 1:
321 case 2:
322 lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
323 len = buf[8] | (buf[7] << 8);
324 cmdlen = 10;
325 break;
326 case 4:
327 lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
328 len = buf[13] | (buf[12] << 8) | (buf[11] << 16) | (buf[10] << 24);
329 cmdlen = 16;
330 break;
331 case 5:
332 lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
333 len = buf[9] | (buf[8] << 8) | (buf[7] << 16) | (buf[6] << 24);
334 cmdlen = 12;
335 break;
336 default:
337 BADF("Unsupported command length, command %x\n", command);
338 goto fail;
340 #ifdef DEBUG_SCSI
342 int i;
343 for (i = 1; i < cmdlen; i++) {
344 printf(" 0x%02x", buf[i]);
346 printf("\n");
348 #endif
349 if (lun || buf[1] >> 5) {
350 /* Only LUN 0 supported. */
351 DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5);
352 if (command != 0x03 && command != 0x12) /* REQUEST SENSE and INQUIRY */
353 goto fail;
355 switch (command) {
356 case 0x0:
357 DPRINTF("Test Unit Ready\n");
358 break;
359 case 0x03:
360 DPRINTF("Request Sense (len %d)\n", len);
361 if (len < 4)
362 goto fail;
363 memset(outbuf, 0, 4);
364 outbuf[0] = 0xf0;
365 outbuf[1] = 0;
366 outbuf[2] = s->sense;
367 r->buf_len = 4;
368 break;
369 case 0x12:
370 DPRINTF("Inquiry (len %d)\n", len);
371 if (buf[1] & 0x2) {
372 /* Command support data - optional, not implemented */
373 BADF("optional INQUIRY command support request not implemented\n");
374 goto fail;
376 else if (buf[1] & 0x1) {
377 /* Vital product data */
378 uint8_t page_code = buf[2];
379 if (len < 4) {
380 BADF("Error: Inquiry (EVPD[%02X]) buffer size %d is "
381 "less than 4\n", page_code, len);
382 goto fail;
385 switch (page_code) {
386 case 0x00:
388 /* Supported page codes, mandatory */
389 DPRINTF("Inquiry EVPD[Supported pages] "
390 "buffer size %d\n", len);
392 r->buf_len = 0;
394 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
395 outbuf[r->buf_len++] = 5;
396 } else {
397 outbuf[r->buf_len++] = 0;
400 outbuf[r->buf_len++] = 0x00; // this page
401 outbuf[r->buf_len++] = 0x00;
402 outbuf[r->buf_len++] = 3; // number of pages
403 outbuf[r->buf_len++] = 0x00; // list of supported pages (this page)
404 outbuf[r->buf_len++] = 0x80; // unit serial number
405 outbuf[r->buf_len++] = 0x83; // device identification
407 break;
408 case 0x80:
410 /* Device serial number, optional */
411 if (len < 4) {
412 BADF("Error: EVPD[Serial number] Inquiry buffer "
413 "size %d too small, %d needed\n", len, 4);
414 goto fail;
417 DPRINTF("Inquiry EVPD[Serial number] buffer size %d\n", len);
419 r->buf_len = 0;
421 /* Supported page codes */
422 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
423 outbuf[r->buf_len++] = 5;
424 } else {
425 outbuf[r->buf_len++] = 0;
428 outbuf[r->buf_len++] = 0x80; // this page
429 outbuf[r->buf_len++] = 0x00;
430 outbuf[r->buf_len++] = 0x01; // 1 byte data follow
432 outbuf[r->buf_len++] = '0'; // 1 byte data follow
435 break;
436 case 0x83:
438 /* Device identification page, mandatory */
439 int max_len = 255 - 8;
440 int id_len = strlen(bdrv_get_device_name(s->bdrv));
441 if (id_len > max_len)
442 id_len = max_len;
444 DPRINTF("Inquiry EVPD[Device identification] "
445 "buffer size %d\n", len);
446 r->buf_len = 0;
447 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
448 outbuf[r->buf_len++] = 5;
449 } else {
450 outbuf[r->buf_len++] = 0;
453 outbuf[r->buf_len++] = 0x83; // this page
454 outbuf[r->buf_len++] = 0x00;
455 outbuf[r->buf_len++] = 3 + id_len;
457 outbuf[r->buf_len++] = 0x2; // ASCII
458 outbuf[r->buf_len++] = 0; // not officially assigned
459 outbuf[r->buf_len++] = 0; // reserved
460 outbuf[r->buf_len++] = id_len; // length of data following
462 memcpy(&outbuf[r->buf_len],
463 bdrv_get_device_name(s->bdrv), id_len);
464 r->buf_len += id_len;
466 break;
467 default:
468 BADF("Error: unsupported Inquiry (EVPD[%02X]) "
469 "buffer size %d\n", page_code, len);
470 goto fail;
472 /* done with EVPD */
473 break;
475 else {
476 /* Standard INQUIRY data */
477 if (buf[2] != 0) {
478 BADF("Error: Inquiry (STANDARD) page or code "
479 "is non-zero [%02X]\n", buf[2]);
480 goto fail;
483 /* PAGE CODE == 0 */
484 if (len < 5) {
485 BADF("Error: Inquiry (STANDARD) buffer size %d "
486 "is less than 5\n", len);
487 goto fail;
490 if (len < 36) {
491 BADF("Error: Inquiry (STANDARD) buffer size %d "
492 "is less than 36 (TODO: only 5 required)\n", len);
495 memset(outbuf, 0, 36);
497 if (lun || buf[1] >> 5) {
498 outbuf[0] = 0x7f; /* LUN not supported */
499 } else if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
500 outbuf[0] = 5;
501 outbuf[1] = 0x80;
502 memcpy(&outbuf[16], "QEMU CD-ROM ", 16);
503 } else {
504 outbuf[0] = 0;
505 memcpy(&outbuf[16], "QEMU HARDDISK ", 16);
507 memcpy(&outbuf[8], "QEMU ", 8);
508 memcpy(&outbuf[32], QEMU_VERSION, 4);
509 /* Identify device as SCSI-3 rev 1.
510 Some later commands are also implemented. */
511 outbuf[2] = 3;
512 outbuf[3] = 2; /* Format 2 */
513 outbuf[4] = 31;
514 /* Sync data transfer and TCQ. */
515 outbuf[7] = 0x10 | (s->tcq ? 0x02 : 0);
516 r->buf_len = 36;
517 break;
518 case 0x16:
519 DPRINTF("Reserve(6)\n");
520 if (buf[1] & 1)
521 goto fail;
522 break;
523 case 0x17:
524 DPRINTF("Release(6)\n");
525 if (buf[1] & 1)
526 goto fail;
527 break;
528 case 0x1a:
529 case 0x5a:
531 uint8_t *p;
532 int page;
534 page = buf[2] & 0x3f;
535 DPRINTF("Mode Sense (page %d, len %d)\n", page, len);
536 p = outbuf;
537 memset(p, 0, 4);
538 outbuf[1] = 0; /* Default media type. */
539 outbuf[3] = 0; /* Block descriptor length. */
540 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
541 outbuf[2] = 0x80; /* Readonly. */
543 p += 4;
544 if (page == 4) {
545 int cylinders, heads, secs;
547 /* Rigid disk device geometry page. */
548 p[0] = 4;
549 p[1] = 0x16;
550 /* if a geometry hint is available, use it */
551 bdrv_get_geometry_hint(s->bdrv, &cylinders, &heads, &secs);
552 p[2] = (cylinders >> 16) & 0xff;
553 p[3] = (cylinders >> 8) & 0xff;
554 p[4] = cylinders & 0xff;
555 p[5] = heads & 0xff;
556 /* Write precomp start cylinder, disabled */
557 p[6] = (cylinders >> 16) & 0xff;
558 p[7] = (cylinders >> 8) & 0xff;
559 p[8] = cylinders & 0xff;
560 /* Reduced current start cylinder, disabled */
561 p[9] = (cylinders >> 16) & 0xff;
562 p[10] = (cylinders >> 8) & 0xff;
563 p[11] = cylinders & 0xff;
564 /* Device step rate [ns], 200ns */
565 p[12] = 0;
566 p[13] = 200;
567 /* Landing zone cylinder */
568 p[14] = 0xff;
569 p[15] = 0xff;
570 p[16] = 0xff;
571 /* Medium rotation rate [rpm], 5400 rpm */
572 p[20] = (5400 >> 8) & 0xff;
573 p[21] = 5400 & 0xff;
574 p += 0x16;
575 } else if (page == 5) {
576 int cylinders, heads, secs;
578 /* Flexible disk device geometry page. */
579 p[0] = 5;
580 p[1] = 0x1e;
581 /* Transfer rate [kbit/s], 5Mbit/s */
582 p[2] = 5000 >> 8;
583 p[3] = 5000 & 0xff;
584 /* if a geometry hint is available, use it */
585 bdrv_get_geometry_hint(s->bdrv, &cylinders, &heads, &secs);
586 p[4] = heads & 0xff;
587 p[5] = secs & 0xff;
588 p[6] = s->cluster_size * 2;
589 p[8] = (cylinders >> 8) & 0xff;
590 p[9] = cylinders & 0xff;
591 /* Write precomp start cylinder, disabled */
592 p[10] = (cylinders >> 8) & 0xff;
593 p[11] = cylinders & 0xff;
594 /* Reduced current start cylinder, disabled */
595 p[12] = (cylinders >> 8) & 0xff;
596 p[13] = cylinders & 0xff;
597 /* Device step rate [100us], 100us */
598 p[14] = 0;
599 p[15] = 1;
600 /* Device step pulse width [us], 1us */
601 p[16] = 1;
602 /* Device head settle delay [100us], 100us */
603 p[17] = 0;
604 p[18] = 1;
605 /* Motor on delay [0.1s], 0.1s */
606 p[19] = 1;
607 /* Motor off delay [0.1s], 0.1s */
608 p[20] = 1;
609 /* Medium rotation rate [rpm], 5400 rpm */
610 p[28] = (5400 >> 8) & 0xff;
611 p[29] = 5400 & 0xff;
612 p += 0x1e;
613 } else if ((page == 8 || page == 0x3f)) {
614 /* Caching page. */
615 memset(p,0,20);
616 p[0] = 8;
617 p[1] = 0x12;
618 p[2] = 4; /* WCE */
619 p += 20;
621 if ((page == 0x3f || page == 0x2a)
622 && (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM)) {
623 /* CD Capabilities and Mechanical Status page. */
624 p[0] = 0x2a;
625 p[1] = 0x14;
626 p[2] = 3; // CD-R & CD-RW read
627 p[3] = 0; // Writing not supported
628 p[4] = 0x7f; /* Audio, composite, digital out,
629 mode 2 form 1&2, multi session */
630 p[5] = 0xff; /* CD DA, DA accurate, RW supported,
631 RW corrected, C2 errors, ISRC,
632 UPC, Bar code */
633 p[6] = 0x2d | (bdrv_is_locked(s->bdrv)? 2 : 0);
634 /* Locking supported, jumper present, eject, tray */
635 p[7] = 0; /* no volume & mute control, no
636 changer */
637 p[8] = (50 * 176) >> 8; // 50x read speed
638 p[9] = (50 * 176) & 0xff;
639 p[10] = 0 >> 8; // No volume
640 p[11] = 0 & 0xff;
641 p[12] = 2048 >> 8; // 2M buffer
642 p[13] = 2048 & 0xff;
643 p[14] = (16 * 176) >> 8; // 16x read speed current
644 p[15] = (16 * 176) & 0xff;
645 p[18] = (16 * 176) >> 8; // 16x write speed
646 p[19] = (16 * 176) & 0xff;
647 p[20] = (16 * 176) >> 8; // 16x write speed current
648 p[21] = (16 * 176) & 0xff;
649 p += 22;
651 r->buf_len = p - outbuf;
652 outbuf[0] = r->buf_len - 4;
653 if (r->buf_len > len)
654 r->buf_len = len;
656 break;
657 case 0x1b:
658 DPRINTF("Start Stop Unit\n");
659 break;
660 case 0x1e:
661 DPRINTF("Prevent Allow Medium Removal (prevent = %d)\n", buf[4] & 3);
662 bdrv_set_locked(s->bdrv, buf[4] & 1);
663 break;
664 case 0x25:
665 DPRINTF("Read Capacity\n");
666 /* The normal LEN field for this command is zero. */
667 memset(outbuf, 0, 8);
668 bdrv_get_geometry(s->bdrv, &nb_sectors);
669 /* Returned value is the address of the last sector. */
670 if (nb_sectors) {
671 nb_sectors--;
672 outbuf[0] = (nb_sectors >> 24) & 0xff;
673 outbuf[1] = (nb_sectors >> 16) & 0xff;
674 outbuf[2] = (nb_sectors >> 8) & 0xff;
675 outbuf[3] = nb_sectors & 0xff;
676 outbuf[4] = 0;
677 outbuf[5] = 0;
678 outbuf[6] = s->cluster_size * 2;
679 outbuf[7] = 0;
680 r->buf_len = 8;
681 } else {
682 scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_NOT_READY);
683 return 0;
685 break;
686 case 0x08:
687 case 0x28:
688 DPRINTF("Read (sector %d, count %d)\n", lba, len);
689 r->sector = lba * s->cluster_size;
690 r->sector_count = len * s->cluster_size;
691 break;
692 case 0x0a:
693 case 0x2a:
694 DPRINTF("Write (sector %d, count %d)\n", lba, len);
695 r->sector = lba * s->cluster_size;
696 r->sector_count = len * s->cluster_size;
697 is_write = 1;
698 break;
699 case 0x35:
700 DPRINTF("Synchronise cache (sector %d, count %d)\n", lba, len);
701 bdrv_flush(s->bdrv);
702 break;
703 case 0x43:
705 int start_track, format, msf, toclen;
707 msf = buf[1] & 2;
708 format = buf[2] & 0xf;
709 start_track = buf[6];
710 bdrv_get_geometry(s->bdrv, &nb_sectors);
711 DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
712 switch(format) {
713 case 0:
714 toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
715 break;
716 case 1:
717 /* multi session : only a single session defined */
718 toclen = 12;
719 memset(outbuf, 0, 12);
720 outbuf[1] = 0x0a;
721 outbuf[2] = 0x01;
722 outbuf[3] = 0x01;
723 break;
724 case 2:
725 toclen = cdrom_read_toc_raw(nb_sectors, outbuf, msf, start_track);
726 break;
727 default:
728 goto error_cmd;
730 if (toclen > 0) {
731 if (len > toclen)
732 len = toclen;
733 r->buf_len = len;
734 break;
736 error_cmd:
737 DPRINTF("Read TOC error\n");
738 goto fail;
740 case 0x46:
741 DPRINTF("Get Configuration (rt %d, maxlen %d)\n", buf[1] & 3, len);
742 memset(outbuf, 0, 8);
743 /* ??? This should probably return much more information. For now
744 just return the basic header indicating the CD-ROM profile. */
745 outbuf[7] = 8; // CD-ROM
746 r->buf_len = 8;
747 break;
748 case 0x56:
749 DPRINTF("Reserve(10)\n");
750 if (buf[1] & 3)
751 goto fail;
752 break;
753 case 0x57:
754 DPRINTF("Release(10)\n");
755 if (buf[1] & 3)
756 goto fail;
757 break;
758 case 0xa0:
759 DPRINTF("Report LUNs (len %d)\n", len);
760 if (len < 16)
761 goto fail;
762 memset(outbuf, 0, 16);
763 outbuf[3] = 8;
764 r->buf_len = 16;
765 break;
766 case 0x2f:
767 DPRINTF("Verify (sector %d, count %d)\n", lba, len);
768 break;
769 default:
770 DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
771 fail:
772 scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_ILLEGAL_REQUEST);
773 return 0;
775 if (r->sector_count == 0 && r->buf_len == 0) {
776 scsi_command_complete(r, STATUS_GOOD, SENSE_NO_SENSE);
778 len = r->sector_count * 512 + r->buf_len;
779 if (is_write) {
780 return -len;
781 } else {
782 if (!r->sector_count)
783 r->sector_count = -1;
784 return len;
788 static void scsi_destroy(SCSIDevice *d)
790 qemu_free(d->state);
791 qemu_free(d);
794 SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, int tcq,
795 scsi_completionfn completion, void *opaque)
797 SCSIDevice *d;
798 SCSIDeviceState *s;
800 s = (SCSIDeviceState *)qemu_mallocz(sizeof(SCSIDeviceState));
801 s->bdrv = bdrv;
802 s->tcq = tcq;
803 s->completion = completion;
804 s->opaque = opaque;
805 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
806 s->cluster_size = 4;
807 } else {
808 s->cluster_size = 1;
811 d = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
812 d->state = s;
813 d->destroy = scsi_destroy;
814 d->send_command = scsi_send_command;
815 d->read_data = scsi_read_data;
816 d->write_data = scsi_write_data;
817 d->cancel_io = scsi_cancel_io;
818 d->get_buf = scsi_get_buf;
820 return d;