]> git.proxmox.com Git - mirror_qemu.git/blame - hw/scsi-disk.c
Describe the format= option in the --help output. List the accepted
[mirror_qemu.git] / hw / scsi-disk.c
CommitLineData
2e5d83bb
PB
1/*
2 * SCSI Device emulation
3 *
4 * Copyright (c) 2006 CodeSourcery.
5 * Based on code by Fabrice Bellard
6 *
7 * Written by Paul Brook
8 *
9 * This code is licenced under the LGPL.
a917d384
PB
10 *
11 * Note that this file only handles the SCSI architecture model and device
1d4db89c
AZ
12 * commands. Emulation of interface/link layer protocols is handled by
13 * the host adapter emulator.
2e5d83bb
PB
14 */
15
16//#define DEBUG_SCSI
17
18#ifdef DEBUG_SCSI
19#define DPRINTF(fmt, args...) \
20do { printf("scsi-disk: " fmt , ##args); } while (0)
21#else
22#define DPRINTF(fmt, args...) do {} while(0)
23#endif
24
25#define BADF(fmt, args...) \
26do { fprintf(stderr, "scsi-disk: " fmt , ##args); } while (0)
27
87ecb68b
PB
28#include "qemu-common.h"
29#include "block.h"
30#include "scsi-disk.h"
2e5d83bb
PB
31
32#define SENSE_NO_SENSE 0
1aacf348 33#define SENSE_NOT_READY 2
4d611c9a 34#define SENSE_HARDWARE_ERROR 4
2e5d83bb
PB
35#define SENSE_ILLEGAL_REQUEST 5
36
47e4ca5a
AZ
37#define SCSI_OK 0
38#define SCSI_CHECK_COND 0x2
39#define SCSI_COND_MET 0x4
40#define SCSI_BUSY 0x8
41#define SCSI_INTERMEDIATE 0x10
42#define SCSI_INTER_MET 0x14
43#define SCSI_RES_CONFLICT 0x18
44#define SCSI_CMD_TERMINATED 0x22
45#define SCSI_QUEUE_FULL 0x28
46#define SCSI_ACA_ACTIVE 0x30
47#define SCSI_TASK_ABORTED 0x40
48
a917d384
PB
49#define SCSI_DMA_BUF_SIZE 65536
50
51typedef struct SCSIRequest {
8ccc2ace 52 SCSIDeviceState *dev;
2e5d83bb 53 uint32_t tag;
2e5d83bb
PB
54 /* ??? We should probably keep track of whether the data trasfer is
55 a read or a write. Currently we rely on the host getting it right. */
a917d384 56 /* Both sector and sector_count are in terms of qemu 512 byte blocks. */
2e5d83bb
PB
57 int sector;
58 int sector_count;
a917d384 59 /* The amounnt of data in the buffer. */
2e5d83bb 60 int buf_len;
33f00271 61 uint8_t *dma_buf;
4d611c9a 62 BlockDriverAIOCB *aiocb;
a917d384
PB
63 struct SCSIRequest *next;
64} SCSIRequest;
65
8ccc2ace 66struct SCSIDeviceState
a917d384
PB
67{
68 BlockDriverState *bdrv;
69 SCSIRequest *requests;
70 /* The qemu block layer uses a fixed 512 byte sector size.
71 This is the number of 512 byte blocks in a single scsi sector. */
72 int cluster_size;
73 int sense;
74 int tcq;
4d611c9a
PB
75 /* Completion functions may be called from either scsi_{read,write}_data
76 or from the AIO completion routines. */
2e5d83bb
PB
77 scsi_completionfn completion;
78 void *opaque;
79};
80
a917d384
PB
81/* Global pool of SCSIRequest structures. */
82static SCSIRequest *free_requests = NULL;
83
8ccc2ace 84static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag)
2e5d83bb 85{
a917d384
PB
86 SCSIRequest *r;
87
88 if (free_requests) {
89 r = free_requests;
90 free_requests = r->next;
91 } else {
92 r = qemu_malloc(sizeof(SCSIRequest));
33f00271 93 r->dma_buf = qemu_memalign(512, SCSI_DMA_BUF_SIZE);
a917d384
PB
94 }
95 r->dev = s;
96 r->tag = tag;
97 r->sector_count = 0;
98 r->buf_len = 0;
99 r->aiocb = NULL;
100
101 r->next = s->requests;
102 s->requests = r;
103 return r;
2e5d83bb
PB
104}
105
a917d384 106static void scsi_remove_request(SCSIRequest *r)
4d611c9a 107{
a917d384 108 SCSIRequest *last;
8ccc2ace 109 SCSIDeviceState *s = r->dev;
a917d384
PB
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;
4d611c9a
PB
125}
126
8ccc2ace 127static SCSIRequest *scsi_find_request(SCSIDeviceState *s, uint32_t tag)
4d611c9a 128{
a917d384 129 SCSIRequest *r;
4d611c9a 130
a917d384
PB
131 r = s->requests;
132 while (r && r->tag != tag)
133 r = r->next;
4d611c9a 134
a917d384
PB
135 return r;
136}
137
138/* Helper function for command completion. */
47e4ca5a 139static void scsi_command_complete(SCSIRequest *r, int status, int sense)
a917d384 140{
8ccc2ace 141 SCSIDeviceState *s = r->dev;
a917d384
PB
142 uint32_t tag;
143 DPRINTF("Command complete tag=0x%x sense=%d\n", r->tag, sense);
144 s->sense = sense;
145 tag = r->tag;
146 scsi_remove_request(r);
47e4ca5a 147 s->completion(s->opaque, SCSI_REASON_DONE, tag, status);
4d611c9a
PB
148}
149
150/* Cancel a pending data transfer. */
8ccc2ace 151static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
4d611c9a 152{
8ccc2ace 153 SCSIDeviceState *s = d->state;
a917d384
PB
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;
8ccc2ace 168 SCSIDeviceState *s = r->dev;
a917d384
PB
169
170 if (ret) {
171 DPRINTF("IO error\n");
47e4ca5a 172 scsi_command_complete(r, SCSI_CHECK_COND, SENSE_HARDWARE_ERROR);
4d611c9a
PB
173 return;
174 }
a917d384
PB
175 DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, r->buf_len);
176
177 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->buf_len);
4d611c9a
PB
178}
179
a917d384 180/* Read more data from scsi device into buffer. */
8ccc2ace 181static void scsi_read_data(SCSIDevice *d, uint32_t tag)
2e5d83bb 182{
8ccc2ace 183 SCSIDeviceState *s = d->state;
a917d384 184 SCSIRequest *r;
2e5d83bb
PB
185 uint32_t n;
186
a917d384
PB
187 r = scsi_find_request(s, tag);
188 if (!r) {
189 BADF("Bad read tag 0x%x\n", tag);
47e4ca5a 190 scsi_command_complete(r, SCSI_CHECK_COND, SENSE_HARDWARE_ERROR);
a917d384 191 return;
2e5d83bb 192 }
a917d384
PB
193 if (r->sector_count == (uint32_t)-1) {
194 DPRINTF("Read buf_len=%d\n", r->buf_len);
195 r->sector_count = 0;
196 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->buf_len);
197 return;
2e5d83bb 198 }
a917d384
PB
199 DPRINTF("Read sector_count=%d\n", r->sector_count);
200 if (r->sector_count == 0) {
47e4ca5a 201 scsi_command_complete(r, SCSI_OK, SENSE_NO_SENSE);
a917d384 202 return;
2e5d83bb
PB
203 }
204
a917d384
PB
205 n = r->sector_count;
206 if (n > SCSI_DMA_BUF_SIZE / 512)
207 n = SCSI_DMA_BUF_SIZE / 512;
208
209 r->buf_len = n * 512;
210 r->aiocb = bdrv_aio_read(s->bdrv, r->sector, r->dma_buf, n,
211 scsi_read_complete, r);
212 if (r->aiocb == NULL)
47e4ca5a 213 scsi_command_complete(r, SCSI_CHECK_COND, SENSE_HARDWARE_ERROR);
a917d384
PB
214 r->sector += n;
215 r->sector_count -= n;
2e5d83bb
PB
216}
217
4d611c9a
PB
218static void scsi_write_complete(void * opaque, int ret)
219{
a917d384 220 SCSIRequest *r = (SCSIRequest *)opaque;
8ccc2ace 221 SCSIDeviceState *s = r->dev;
a917d384 222 uint32_t len;
4d611c9a
PB
223
224 if (ret) {
225 fprintf(stderr, "scsi-disc: IO write error\n");
226 exit(1);
227 }
228
a917d384
PB
229 r->aiocb = NULL;
230 if (r->sector_count == 0) {
47e4ca5a 231 scsi_command_complete(r, SCSI_OK, SENSE_NO_SENSE);
a917d384
PB
232 } else {
233 len = r->sector_count * 512;
234 if (len > SCSI_DMA_BUF_SIZE) {
235 len = SCSI_DMA_BUF_SIZE;
236 }
237 r->buf_len = len;
238 DPRINTF("Write complete tag=0x%x more=%d\n", r->tag, len);
239 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, len);
4d611c9a 240 }
4d611c9a
PB
241}
242
243/* Write data to a scsi device. Returns nonzero on failure.
244 The transfer may complete asynchronously. */
8ccc2ace 245static int scsi_write_data(SCSIDevice *d, uint32_t tag)
2e5d83bb 246{
8ccc2ace 247 SCSIDeviceState *s = d->state;
a917d384 248 SCSIRequest *r;
2e5d83bb
PB
249 uint32_t n;
250
a917d384
PB
251 DPRINTF("Write data tag=0x%x\n", tag);
252 r = scsi_find_request(s, tag);
253 if (!r) {
254 BADF("Bad write tag 0x%x\n", tag);
47e4ca5a 255 scsi_command_complete(r, SCSI_CHECK_COND, SENSE_HARDWARE_ERROR);
2e5d83bb
PB
256 return 1;
257 }
a917d384
PB
258 if (r->aiocb)
259 BADF("Data transfer already in progress\n");
260 n = r->buf_len / 512;
261 if (n) {
262 r->aiocb = bdrv_aio_write(s->bdrv, r->sector, r->dma_buf, n,
263 scsi_write_complete, r);
264 if (r->aiocb == NULL)
47e4ca5a 265 scsi_command_complete(r, SCSI_CHECK_COND, SENSE_HARDWARE_ERROR);
a917d384
PB
266 r->sector += n;
267 r->sector_count -= n;
268 } else {
269 /* Invoke completion routine to fetch data from host. */
270 scsi_write_complete(r, 0);
2e5d83bb
PB
271 }
272
a917d384
PB
273 return 0;
274}
2e5d83bb 275
a917d384 276/* Return a pointer to the data buffer. */
8ccc2ace 277static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
a917d384 278{
8ccc2ace 279 SCSIDeviceState *s = d->state;
a917d384 280 SCSIRequest *r;
2e5d83bb 281
a917d384
PB
282 r = scsi_find_request(s, tag);
283 if (!r) {
284 BADF("Bad buffer tag 0x%x\n", tag);
285 return NULL;
4d611c9a 286 }
a917d384 287 return r->dma_buf;
2e5d83bb
PB
288}
289
290/* Execute a scsi command. Returns the length of the data expected by the
291 command. This will be Positive for data transfers from the device
292 (eg. disk reads), negative for transfers to the device (eg. disk writes),
293 and zero if the command does not transfer any data. */
294
8ccc2ace
TS
295static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
296 uint8_t *buf, int lun)
2e5d83bb 297{
8ccc2ace 298 SCSIDeviceState *s = d->state;
96b8f136 299 uint64_t nb_sectors;
2e5d83bb
PB
300 uint32_t lba;
301 uint32_t len;
302 int cmdlen;
303 int is_write;
a917d384
PB
304 uint8_t command;
305 uint8_t *outbuf;
306 SCSIRequest *r;
307
308 command = buf[0];
309 r = scsi_find_request(s, tag);
310 if (r) {
311 BADF("Tag 0x%x already in use\n", tag);
8ccc2ace 312 scsi_cancel_io(d, tag);
a917d384
PB
313 }
314 /* ??? Tags are not unique for different luns. We only implement a
315 single lun, so this should not matter. */
316 r = scsi_new_request(s, tag);
317 outbuf = r->dma_buf;
2e5d83bb 318 is_write = 0;
a917d384
PB
319 DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
320 switch (command >> 5) {
2e5d83bb
PB
321 case 0:
322 lba = buf[3] | (buf[2] << 8) | ((buf[1] & 0x1f) << 16);
323 len = buf[4];
324 cmdlen = 6;
325 break;
326 case 1:
327 case 2:
328 lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
329 len = buf[8] | (buf[7] << 8);
330 cmdlen = 10;
331 break;
332 case 4:
333 lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
334 len = buf[13] | (buf[12] << 8) | (buf[11] << 16) | (buf[10] << 24);
335 cmdlen = 16;
336 break;
337 case 5:
338 lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
339 len = buf[9] | (buf[8] << 8) | (buf[7] << 16) | (buf[6] << 24);
340 cmdlen = 12;
341 break;
342 default:
a917d384 343 BADF("Unsupported command length, command %x\n", command);
2e5d83bb
PB
344 goto fail;
345 }
346#ifdef DEBUG_SCSI
347 {
348 int i;
349 for (i = 1; i < cmdlen; i++) {
350 printf(" 0x%02x", buf[i]);
351 }
352 printf("\n");
353 }
354#endif
0fc5c15a 355 if (lun || buf[1] >> 5) {
2e5d83bb 356 /* Only LUN 0 supported. */
0fc5c15a 357 DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5);
2e5d83bb
PB
358 goto fail;
359 }
a917d384 360 switch (command) {
2e5d83bb
PB
361 case 0x0:
362 DPRINTF("Test Unit Ready\n");
363 break;
364 case 0x03:
365 DPRINTF("Request Sense (len %d)\n", len);
366 if (len < 4)
367 goto fail;
67cd24a8 368 memset(outbuf, 0, 4);
a917d384
PB
369 outbuf[0] = 0xf0;
370 outbuf[1] = 0;
371 outbuf[2] = s->sense;
372 r->buf_len = 4;
2e5d83bb
PB
373 break;
374 case 0x12:
7d8406be 375 DPRINTF("Inquiry (len %d)\n", len);
1d4db89c
AZ
376 if (buf[1] & 0x2) {
377 /* Command support data - optional, not implemented */
378 BADF("optional INQUIRY command support request not implemented\n");
379 goto fail;
380 }
381 else if (buf[1] & 0x1) {
382 /* Vital product data */
383 uint8_t page_code = buf[2];
384 if (len < 4) {
385 BADF("Error: Inquiry (EVPD[%02X]) buffer size %d is "
386 "less than 4\n", page_code, len);
387 goto fail;
388 }
389
390 switch (page_code) {
391 case 0x00:
392 {
393 /* Supported page codes, mandatory */
394 DPRINTF("Inquiry EVPD[Supported pages] "
395 "buffer size %d\n", len);
396
397 r->buf_len = 0;
398
399 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
400 outbuf[r->buf_len++] = 5;
401 } else {
402 outbuf[r->buf_len++] = 0;
403 }
404
405 outbuf[r->buf_len++] = 0x00; // this page
406 outbuf[r->buf_len++] = 0x00;
407 outbuf[r->buf_len++] = 3; // number of pages
408 outbuf[r->buf_len++] = 0x00; // list of supported pages (this page)
409 outbuf[r->buf_len++] = 0x80; // unit serial number
410 outbuf[r->buf_len++] = 0x83; // device identification
411 }
412 break;
413 case 0x80:
414 {
415 /* Device serial number, optional */
416 if (len < 4) {
417 BADF("Error: EVPD[Serial number] Inquiry buffer "
418 "size %d too small, %d needed\n", len, 4);
419 goto fail;
420 }
421
422 DPRINTF("Inquiry EVPD[Serial number] buffer size %d\n", len);
423
424 r->buf_len = 0;
425
426 /* Supported page codes */
427 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
428 outbuf[r->buf_len++] = 5;
429 } else {
430 outbuf[r->buf_len++] = 0;
431 }
432
433 outbuf[r->buf_len++] = 0x80; // this page
434 outbuf[r->buf_len++] = 0x00;
435 outbuf[r->buf_len++] = 0x01; // 1 byte data follow
436
437 outbuf[r->buf_len++] = '0'; // 1 byte data follow
438 }
439
440 break;
441 case 0x83:
442 {
443 /* Device identification page, mandatory */
444 int max_len = 255 - 8;
445 int id_len = strlen(bdrv_get_device_name(s->bdrv));
446 if (id_len > max_len)
447 id_len = max_len;
448
449 DPRINTF("Inquiry EVPD[Device identification] "
450 "buffer size %d\n", len);
451 r->buf_len = 0;
452 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
453 outbuf[r->buf_len++] = 5;
454 } else {
455 outbuf[r->buf_len++] = 0;
456 }
457
458 outbuf[r->buf_len++] = 0x83; // this page
459 outbuf[r->buf_len++] = 0x00;
460 outbuf[r->buf_len++] = 3 + id_len;
461
462 outbuf[r->buf_len++] = 0x2; // ASCII
463 outbuf[r->buf_len++] = 0; // not officially assigned
464 outbuf[r->buf_len++] = 0; // reserved
465 outbuf[r->buf_len++] = id_len; // length of data following
466
467 memcpy(&outbuf[r->buf_len],
468 bdrv_get_device_name(s->bdrv), id_len);
469 r->buf_len += id_len;
470 }
471 break;
472 default:
473 BADF("Error: unsupported Inquiry (EVPD[%02X]) "
474 "buffer size %d\n", page_code, len);
475 goto fail;
476 }
477 /* done with EVPD */
478 break;
479 }
480 else {
481 /* Standard INQUIRY data */
482 if (buf[2] != 0) {
483 BADF("Error: Inquiry (STANDARD) page or code "
484 "is non-zero [%02X]\n", buf[2]);
485 goto fail;
486 }
487
488 /* PAGE CODE == 0 */
489 if (len < 5) {
490 BADF("Error: Inquiry (STANDARD) buffer size %d "
491 "is less than 5\n", len);
492 goto fail;
493 }
494
495 if (len < 36) {
496 BADF("Error: Inquiry (STANDARD) buffer size %d "
497 "is less than 36 (TODO: only 5 required)\n", len);
498 }
2e5d83bb 499 }
a917d384 500 memset(outbuf, 0, 36);
2e5d83bb 501 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
a917d384
PB
502 outbuf[0] = 5;
503 outbuf[1] = 0x80;
504 memcpy(&outbuf[16], "QEMU CD-ROM ", 16);
2e5d83bb 505 } else {
a917d384
PB
506 outbuf[0] = 0;
507 memcpy(&outbuf[16], "QEMU HARDDISK ", 16);
2e5d83bb 508 }
a917d384
PB
509 memcpy(&outbuf[8], "QEMU ", 8);
510 memcpy(&outbuf[32], QEMU_VERSION, 4);
17acfe32
PB
511 /* Identify device as SCSI-3 rev 1.
512 Some later commands are also implemented. */
a917d384
PB
513 outbuf[2] = 3;
514 outbuf[3] = 2; /* Format 2 */
67cd24a8 515 outbuf[4] = 31;
a917d384
PB
516 /* Sync data transfer and TCQ. */
517 outbuf[7] = 0x10 | (s->tcq ? 0x02 : 0);
518 r->buf_len = 36;
2e5d83bb
PB
519 break;
520 case 0x16:
521 DPRINTF("Reserve(6)\n");
522 if (buf[1] & 1)
523 goto fail;
524 break;
525 case 0x17:
526 DPRINTF("Release(6)\n");
527 if (buf[1] & 1)
528 goto fail;
529 break;
530 case 0x1a:
7d8406be 531 case 0x5a:
17acfe32 532 {
a917d384 533 uint8_t *p;
17acfe32
PB
534 int page;
535
536 page = buf[2] & 0x3f;
537 DPRINTF("Mode Sense (page %d, len %d)\n", page, len);
a917d384 538 p = outbuf;
17acfe32 539 memset(p, 0, 4);
a917d384
PB
540 outbuf[1] = 0; /* Default media type. */
541 outbuf[3] = 0; /* Block descriptor length. */
17acfe32 542 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
a917d384 543 outbuf[2] = 0x80; /* Readonly. */
17acfe32
PB
544 }
545 p += 4;
546 if ((page == 8 || page == 0x3f)) {
547 /* Caching page. */
67cd24a8 548 memset(p,0,20);
17acfe32
PB
549 p[0] = 8;
550 p[1] = 0x12;
551 p[2] = 4; /* WCE */
67cd24a8 552 p += 20;
17acfe32
PB
553 }
554 if ((page == 0x3f || page == 0x2a)
555 && (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM)) {
556 /* CD Capabilities and Mechanical Status page. */
557 p[0] = 0x2a;
558 p[1] = 0x14;
559 p[2] = 3; // CD-R & CD-RW read
560 p[3] = 0; // Writing not supported
561 p[4] = 0x7f; /* Audio, composite, digital out,
562 mode 2 form 1&2, multi session */
563 p[5] = 0xff; /* CD DA, DA accurate, RW supported,
564 RW corrected, C2 errors, ISRC,
565 UPC, Bar code */
566 p[6] = 0x2d | (bdrv_is_locked(s->bdrv)? 2 : 0);
567 /* Locking supported, jumper present, eject, tray */
568 p[7] = 0; /* no volume & mute control, no
569 changer */
570 p[8] = (50 * 176) >> 8; // 50x read speed
571 p[9] = (50 * 176) & 0xff;
572 p[10] = 0 >> 8; // No volume
573 p[11] = 0 & 0xff;
574 p[12] = 2048 >> 8; // 2M buffer
575 p[13] = 2048 & 0xff;
576 p[14] = (16 * 176) >> 8; // 16x read speed current
577 p[15] = (16 * 176) & 0xff;
578 p[18] = (16 * 176) >> 8; // 16x write speed
579 p[19] = (16 * 176) & 0xff;
580 p[20] = (16 * 176) >> 8; // 16x write speed current
581 p[21] = (16 * 176) & 0xff;
67cd24a8 582 p += 22;
17acfe32 583 }
a917d384
PB
584 r->buf_len = p - outbuf;
585 outbuf[0] = r->buf_len - 4;
586 if (r->buf_len > len)
587 r->buf_len = len;
7d8406be 588 }
17acfe32
PB
589 break;
590 case 0x1b:
591 DPRINTF("Start Stop Unit\n");
592 break;
593 case 0x1e:
594 DPRINTF("Prevent Allow Medium Removal (prevent = %d)\n", buf[4] & 3);
595 bdrv_set_locked(s->bdrv, buf[4] & 1);
2e5d83bb
PB
596 break;
597 case 0x25:
598 DPRINTF("Read Capacity\n");
599 /* The normal LEN field for this command is zero. */
a917d384 600 memset(outbuf, 0, 8);
2e5d83bb 601 bdrv_get_geometry(s->bdrv, &nb_sectors);
51c1ebb1
PB
602 /* Returned value is the address of the last sector. */
603 if (nb_sectors) {
604 nb_sectors--;
a917d384
PB
605 outbuf[0] = (nb_sectors >> 24) & 0xff;
606 outbuf[1] = (nb_sectors >> 16) & 0xff;
607 outbuf[2] = (nb_sectors >> 8) & 0xff;
608 outbuf[3] = nb_sectors & 0xff;
609 outbuf[4] = 0;
610 outbuf[5] = 0;
611 outbuf[6] = s->cluster_size * 2;
612 outbuf[7] = 0;
613 r->buf_len = 8;
51c1ebb1 614 } else {
47e4ca5a 615 scsi_command_complete(r, SCSI_CHECK_COND, SENSE_NOT_READY);
35f1df84 616 return 0;
51c1ebb1 617 }
2e5d83bb
PB
618 break;
619 case 0x08:
620 case 0x28:
621 DPRINTF("Read (sector %d, count %d)\n", lba, len);
a917d384
PB
622 r->sector = lba * s->cluster_size;
623 r->sector_count = len * s->cluster_size;
2e5d83bb
PB
624 break;
625 case 0x0a:
626 case 0x2a:
627 DPRINTF("Write (sector %d, count %d)\n", lba, len);
a917d384
PB
628 r->sector = lba * s->cluster_size;
629 r->sector_count = len * s->cluster_size;
2e5d83bb
PB
630 is_write = 1;
631 break;
7d8406be 632 case 0x35:
e91c8a77 633 DPRINTF("Synchronise cache (sector %d, count %d)\n", lba, len);
7a6cba61 634 bdrv_flush(s->bdrv);
7d8406be 635 break;
2e5d83bb
PB
636 case 0x43:
637 {
7c22dd52 638 int start_track, format, msf, toclen;
2e5d83bb
PB
639
640 msf = buf[1] & 2;
641 format = buf[2] & 0xf;
642 start_track = buf[6];
643 bdrv_get_geometry(s->bdrv, &nb_sectors);
644 DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
645 switch(format) {
646 case 0:
a917d384 647 toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
2e5d83bb
PB
648 break;
649 case 1:
650 /* multi session : only a single session defined */
7c22dd52 651 toclen = 12;
a917d384
PB
652 memset(outbuf, 0, 12);
653 outbuf[1] = 0x0a;
654 outbuf[2] = 0x01;
655 outbuf[3] = 0x01;
2e5d83bb
PB
656 break;
657 case 2:
a917d384 658 toclen = cdrom_read_toc_raw(nb_sectors, outbuf, msf, start_track);
2e5d83bb
PB
659 break;
660 default:
7c22dd52
PB
661 goto error_cmd;
662 }
663 if (toclen > 0) {
664 if (len > toclen)
665 len = toclen;
a917d384 666 r->buf_len = len;
7c22dd52 667 break;
2e5d83bb 668 }
7c22dd52
PB
669 error_cmd:
670 DPRINTF("Read TOC error\n");
671 goto fail;
2e5d83bb 672 }
17acfe32
PB
673 case 0x46:
674 DPRINTF("Get Configuration (rt %d, maxlen %d)\n", buf[1] & 3, len);
a917d384 675 memset(outbuf, 0, 8);
17acfe32
PB
676 /* ??? This shoud probably return much more information. For now
677 just return the basic header indicating the CD-ROM profile. */
a917d384
PB
678 outbuf[7] = 8; // CD-ROM
679 r->buf_len = 8;
17acfe32 680 break;
2e5d83bb
PB
681 case 0x56:
682 DPRINTF("Reserve(10)\n");
683 if (buf[1] & 3)
684 goto fail;
685 break;
686 case 0x57:
687 DPRINTF("Release(10)\n");
688 if (buf[1] & 3)
689 goto fail;
690 break;
691 case 0xa0:
692 DPRINTF("Report LUNs (len %d)\n", len);
693 if (len < 16)
694 goto fail;
a917d384
PB
695 memset(outbuf, 0, 16);
696 outbuf[3] = 8;
697 r->buf_len = 16;
2e5d83bb
PB
698 break;
699 default:
700 DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
701 fail:
47e4ca5a 702 scsi_command_complete(r, SCSI_CHECK_COND, SENSE_ILLEGAL_REQUEST);
2e5d83bb
PB
703 return 0;
704 }
a917d384 705 if (r->sector_count == 0 && r->buf_len == 0) {
47e4ca5a 706 scsi_command_complete(r, SCSI_OK, SENSE_NO_SENSE);
a917d384
PB
707 }
708 len = r->sector_count * 512 + r->buf_len;
709 if (is_write) {
710 return -len;
711 } else {
712 if (!r->sector_count)
713 r->sector_count = -1;
714 return len;
2e5d83bb 715 }
2e5d83bb
PB
716}
717
8ccc2ace 718static void scsi_destroy(SCSIDevice *d)
2e5d83bb 719{
8ccc2ace
TS
720 qemu_free(d->state);
721 qemu_free(d);
2e5d83bb
PB
722}
723
8ccc2ace
TS
724SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, int tcq,
725 scsi_completionfn completion, void *opaque)
2e5d83bb 726{
8ccc2ace
TS
727 SCSIDevice *d;
728 SCSIDeviceState *s;
2e5d83bb 729
8ccc2ace 730 s = (SCSIDeviceState *)qemu_mallocz(sizeof(SCSIDeviceState));
2e5d83bb 731 s->bdrv = bdrv;
a917d384 732 s->tcq = tcq;
2e5d83bb
PB
733 s->completion = completion;
734 s->opaque = opaque;
735 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
7c22dd52 736 s->cluster_size = 4;
2e5d83bb 737 } else {
7c22dd52 738 s->cluster_size = 1;
2e5d83bb
PB
739 }
740
8ccc2ace
TS
741 d = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
742 d->state = s;
743 d->destroy = scsi_destroy;
744 d->send_command = scsi_send_command;
745 d->read_data = scsi_read_data;
746 d->write_data = scsi_write_data;
747 d->cancel_io = scsi_cancel_io;
748 d->get_buf = scsi_get_buf;
2e5d83bb 749
8ccc2ace
TS
750 return d;
751}