debuggers.hg

view tools/ioemu/hw/scsi-disk.c @ 0:7d21f7218375

Exact replica of unstable on 051908 + README-this
author Mukesh Rathor
date Mon May 19 15:34:57 2008 -0700 (2008-05-19)
parents
children
line source
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.
10 *
11 * Note that this file only handles the SCSI architecture model and device
12 * commands. Emultion of interface/link layer protocols is handled by
13 * the host adapter emulation.
14 */
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 "vl.h"
29 #include <malloc.h>
31 #define SENSE_NO_SENSE 0
32 #define SENSE_NOT_READY 2
33 #define SENSE_HARDWARE_ERROR 4
34 #define SENSE_ILLEGAL_REQUEST 5
36 #ifdef CONFIG_STUBDOM
37 #include <xen/io/blkif.h>
38 #define SCSI_DMA_BUF_SIZE (BLKIF_MAX_SEGMENTS_PER_REQUEST * TARGET_PAGE_SIZE)
39 #else
40 #define SCSI_DMA_BUF_SIZE 131072
41 #endif
43 typedef struct SCSIRequest {
44 SCSIDevice *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 SCSIDevice
59 {
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;
71 };
73 /* Global pool of SCSIRequest structures. */
74 static SCSIRequest *free_requests = NULL;
76 static SCSIRequest *scsi_new_request(SCSIDevice *s, uint32_t tag)
77 {
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(getpagesize(), SCSI_DMA_BUF_SIZE);
86 }
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;
96 }
98 static void scsi_remove_request(SCSIRequest *r)
99 {
100 SCSIRequest *last;
101 SCSIDevice *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");
113 }
114 }
115 r->next = free_requests;
116 free_requests = r;
117 }
119 static SCSIRequest *scsi_find_request(SCSIDevice *s, uint32_t tag)
120 {
121 SCSIRequest *r;
123 r = s->requests;
124 while (r && r->tag != tag)
125 r = r->next;
127 return r;
128 }
130 /* Helper function for command completion. */
131 static void scsi_command_complete(SCSIRequest *r, int sense)
132 {
133 SCSIDevice *s = r->dev;
134 uint32_t tag;
135 DPRINTF("Command complete tag=0x%x sense=%d\n", r->tag, sense);
136 s->sense = sense;
137 tag = r->tag;
138 scsi_remove_request(r);
139 s->completion(s->opaque, SCSI_REASON_DONE, tag, sense);
140 }
142 /* Cancel a pending data transfer. */
143 void scsi_cancel_io(SCSIDevice *s, uint32_t tag)
144 {
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);
153 }
154 }
156 static void scsi_read_complete(void * opaque, int ret)
157 {
158 SCSIRequest *r = (SCSIRequest *)opaque;
159 SCSIDevice *s = r->dev;
161 if (ret) {
162 DPRINTF("IO error\n");
163 scsi_command_complete(r, SENSE_HARDWARE_ERROR);
164 return;
165 }
166 DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, r->buf_len);
168 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->buf_len);
169 }
171 /* Read more data from scsi device into buffer. */
172 void scsi_read_data(SCSIDevice *s, uint32_t tag)
173 {
174 SCSIRequest *r;
175 uint32_t n;
177 r = scsi_find_request(s, tag);
178 if (!r) {
179 BADF("Bad read tag 0x%x\n", tag);
180 /* ??? This is the wrong error. */
181 scsi_command_complete(r, SENSE_HARDWARE_ERROR);
182 return;
183 }
184 if (r->sector_count == (uint32_t)-1) {
185 DPRINTF("Read buf_len=%d\n", r->buf_len);
186 r->sector_count = 0;
187 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->buf_len);
188 return;
189 }
190 DPRINTF("Read sector_count=%d\n", r->sector_count);
191 if (r->sector_count == 0) {
192 scsi_command_complete(r, SENSE_NO_SENSE);
193 return;
194 }
196 n = r->sector_count;
197 if (n > SCSI_DMA_BUF_SIZE / 512)
198 n = SCSI_DMA_BUF_SIZE / 512;
200 r->buf_len = n * 512;
201 r->aiocb = bdrv_aio_read(s->bdrv, r->sector, r->dma_buf, n,
202 scsi_read_complete, r);
203 if (r->aiocb == NULL)
204 scsi_command_complete(r, SENSE_HARDWARE_ERROR);
205 r->sector += n;
206 r->sector_count -= n;
207 }
209 static void scsi_write_complete(void * opaque, int ret)
210 {
211 SCSIRequest *r = (SCSIRequest *)opaque;
212 SCSIDevice *s = r->dev;
213 uint32_t len;
215 if (ret) {
216 fprintf(stderr, "scsi-disc: IO write error\n");
217 exit(1);
218 }
220 r->aiocb = NULL;
221 if (r->sector_count == 0) {
222 scsi_command_complete(r, SENSE_NO_SENSE);
223 } else {
224 len = r->sector_count * 512;
225 if (len > SCSI_DMA_BUF_SIZE) {
226 len = SCSI_DMA_BUF_SIZE;
227 }
228 r->buf_len = len;
229 DPRINTF("Write complete tag=0x%x more=%d\n", r->tag, len);
230 s->completion(s->opaque, SCSI_REASON_DATA, r->tag, len);
231 }
232 }
234 /* Write data to a scsi device. Returns nonzero on failure.
235 The transfer may complete asynchronously. */
236 int scsi_write_data(SCSIDevice *s, uint32_t tag)
237 {
238 SCSIRequest *r;
239 uint32_t n;
241 DPRINTF("Write data tag=0x%x\n", tag);
242 r = scsi_find_request(s, tag);
243 if (!r) {
244 BADF("Bad write tag 0x%x\n", tag);
245 scsi_command_complete(r, SENSE_HARDWARE_ERROR);
246 return 1;
247 }
248 if (r->aiocb)
249 BADF("Data transfer already in progress\n");
250 n = r->buf_len / 512;
251 if (n) {
252 r->aiocb = bdrv_aio_write(s->bdrv, r->sector, r->dma_buf, n,
253 scsi_write_complete, r);
254 if (r->aiocb == NULL)
255 scsi_command_complete(r, SENSE_HARDWARE_ERROR);
256 r->sector += n;
257 r->sector_count -= n;
258 } else {
259 /* Invoke completion routine to fetch data from host. */
260 scsi_write_complete(r, 0);
261 }
263 return 0;
264 }
266 /* Return a pointer to the data buffer. */
267 uint8_t *scsi_get_buf(SCSIDevice *s, uint32_t tag)
268 {
269 SCSIRequest *r;
271 r = scsi_find_request(s, tag);
272 if (!r) {
273 BADF("Bad buffer tag 0x%x\n", tag);
274 return NULL;
275 }
276 return r->dma_buf;
277 }
279 /* Execute a scsi command. Returns the length of the data expected by the
280 command. This will be Positive for data transfers from the device
281 (eg. disk reads), negative for transfers to the device (eg. disk writes),
282 and zero if the command does not transfer any data. */
284 int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun)
285 {
286 int64_t nb_sectors;
287 uint32_t lba;
288 uint32_t len;
289 int cmdlen;
290 int is_write;
291 uint8_t command;
292 uint8_t *outbuf;
293 SCSIRequest *r;
294 int ret;
296 command = buf[0];
297 r = scsi_find_request(s, tag);
298 if (r) {
299 BADF("Tag 0x%x already in use\n", tag);
300 scsi_cancel_io(s, tag);
301 }
302 /* ??? Tags are not unique for different luns. We only implement a
303 single lun, so this should not matter. */
304 r = scsi_new_request(s, tag);
305 outbuf = r->dma_buf;
306 is_write = 0;
307 DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
308 switch (command >> 5) {
309 case 0:
310 lba = buf[3] | (buf[2] << 8) | ((buf[1] & 0x1f) << 16);
311 len = buf[4];
312 cmdlen = 6;
313 break;
314 case 1:
315 case 2:
316 lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
317 len = buf[8] | (buf[7] << 8);
318 cmdlen = 10;
319 break;
320 case 4:
321 lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
322 len = buf[13] | (buf[12] << 8) | (buf[11] << 16) | (buf[10] << 24);
323 cmdlen = 16;
324 break;
325 case 5:
326 lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
327 len = buf[9] | (buf[8] << 8) | (buf[7] << 16) | (buf[6] << 24);
328 cmdlen = 12;
329 break;
330 default:
331 BADF("Unsupported command length, command %x\n", command);
332 goto fail;
333 }
334 #ifdef DEBUG_SCSI
335 {
336 int i;
337 for (i = 1; i < cmdlen; i++) {
338 printf(" 0x%02x", buf[i]);
339 }
340 printf("\n");
341 }
342 #endif
343 if (lun || buf[1] >> 5) {
344 /* Only LUN 0 supported. */
345 DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5);
346 goto fail;
347 }
348 switch (command) {
349 case 0x0:
350 DPRINTF("Test Unit Ready\n");
351 break;
352 case 0x03:
353 DPRINTF("Request Sense (len %d)\n", len);
354 if (len < 4)
355 goto fail;
356 memset(buf, 0, 4);
357 outbuf[0] = 0xf0;
358 outbuf[1] = 0;
359 outbuf[2] = s->sense;
360 r->buf_len = 4;
361 break;
362 case 0x12:
363 DPRINTF("Inquiry (len %d)\n", len);
364 if (len < 36) {
365 BADF("Inquiry buffer too small (%d)\n", len);
366 }
367 memset(outbuf, 0, 36);
368 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
369 outbuf[0] = 5;
370 outbuf[1] = 0x80;
371 memcpy(&outbuf[16], "QEMU CD-ROM ", 16);
372 } else {
373 outbuf[0] = 0;
374 memcpy(&outbuf[16], "QEMU HARDDISK ", 16);
375 }
376 memcpy(&outbuf[8], "QEMU ", 8);
377 memcpy(&outbuf[32], QEMU_VERSION, 4);
378 /* Identify device as SCSI-3 rev 1.
379 Some later commands are also implemented. */
380 outbuf[2] = 3;
381 outbuf[3] = 2; /* Format 2 */
382 outbuf[4] = 32;
383 /* Sync data transfer and TCQ. */
384 outbuf[7] = 0x10 | (s->tcq ? 0x02 : 0);
385 r->buf_len = 36;
386 break;
387 case 0x16:
388 DPRINTF("Reserve(6)\n");
389 if (buf[1] & 1)
390 goto fail;
391 break;
392 case 0x17:
393 DPRINTF("Release(6)\n");
394 if (buf[1] & 1)
395 goto fail;
396 break;
397 case 0x1a:
398 case 0x5a:
399 {
400 uint8_t *p;
401 int page;
403 page = buf[2] & 0x3f;
404 DPRINTF("Mode Sense (page %d, len %d)\n", page, len);
405 p = outbuf;
406 memset(p, 0, 4);
407 outbuf[1] = 0; /* Default media type. */
408 outbuf[3] = 0; /* Block descriptor length. */
409 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
410 outbuf[2] = 0x80; /* Readonly. */
411 }
412 p += 4;
413 if ((page == 8 || page == 0x3f)) {
414 /* Caching page. */
415 p[0] = 8;
416 p[1] = 0x12;
417 p[2] = 4; /* WCE */
418 p += 19;
419 }
420 if ((page == 0x3f || page == 0x2a)
421 && (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM)) {
422 /* CD Capabilities and Mechanical Status page. */
423 p[0] = 0x2a;
424 p[1] = 0x14;
425 p[2] = 3; // CD-R & CD-RW read
426 p[3] = 0; // Writing not supported
427 p[4] = 0x7f; /* Audio, composite, digital out,
428 mode 2 form 1&2, multi session */
429 p[5] = 0xff; /* CD DA, DA accurate, RW supported,
430 RW corrected, C2 errors, ISRC,
431 UPC, Bar code */
432 p[6] = 0x2d | (bdrv_is_locked(s->bdrv)? 2 : 0);
433 /* Locking supported, jumper present, eject, tray */
434 p[7] = 0; /* no volume & mute control, no
435 changer */
436 p[8] = (50 * 176) >> 8; // 50x read speed
437 p[9] = (50 * 176) & 0xff;
438 p[10] = 0 >> 8; // No volume
439 p[11] = 0 & 0xff;
440 p[12] = 2048 >> 8; // 2M buffer
441 p[13] = 2048 & 0xff;
442 p[14] = (16 * 176) >> 8; // 16x read speed current
443 p[15] = (16 * 176) & 0xff;
444 p[18] = (16 * 176) >> 8; // 16x write speed
445 p[19] = (16 * 176) & 0xff;
446 p[20] = (16 * 176) >> 8; // 16x write speed current
447 p[21] = (16 * 176) & 0xff;
448 p += 21;
449 }
450 r->buf_len = p - outbuf;
451 outbuf[0] = r->buf_len - 4;
452 if (r->buf_len > len)
453 r->buf_len = len;
454 }
455 break;
456 case 0x1b:
457 DPRINTF("Start Stop Unit\n");
458 break;
459 case 0x1e:
460 DPRINTF("Prevent Allow Medium Removal (prevent = %d)\n", buf[4] & 3);
461 bdrv_set_locked(s->bdrv, buf[4] & 1);
462 break;
463 case 0x25:
464 DPRINTF("Read Capacity\n");
465 /* The normal LEN field for this command is zero. */
466 memset(outbuf, 0, 8);
467 bdrv_get_geometry(s->bdrv, &nb_sectors);
468 /* Returned value is the address of the last sector. */
469 if (nb_sectors) {
470 nb_sectors--;
471 outbuf[0] = (nb_sectors >> 24) & 0xff;
472 outbuf[1] = (nb_sectors >> 16) & 0xff;
473 outbuf[2] = (nb_sectors >> 8) & 0xff;
474 outbuf[3] = nb_sectors & 0xff;
475 outbuf[4] = 0;
476 outbuf[5] = 0;
477 outbuf[6] = s->cluster_size * 2;
478 outbuf[7] = 0;
479 r->buf_len = 8;
480 } else {
481 scsi_command_complete(r, SENSE_NOT_READY);
482 return 0;
483 }
484 break;
485 case 0x08:
486 case 0x28:
487 DPRINTF("Read (sector %d, count %d)\n", lba, len);
488 r->sector = lba * s->cluster_size;
489 r->sector_count = len * s->cluster_size;
490 break;
491 case 0x0a:
492 case 0x2a:
493 DPRINTF("Write (sector %d, count %d)\n", lba, len);
494 r->sector = lba * s->cluster_size;
495 r->sector_count = len * s->cluster_size;
496 is_write = 1;
497 break;
498 case 0x35:
499 DPRINTF("Syncronise cache (sector %d, count %d)\n", lba, len);
500 ret = bdrv_flush(s->bdrv);
501 if (ret) {
502 DPRINTF("IO error on bdrv_flush\n");
503 scsi_command_complete(r, SENSE_HARDWARE_ERROR);
504 return 0;
505 }
506 break;
507 case 0x43:
508 {
509 int start_track, format, msf, toclen;
511 msf = buf[1] & 2;
512 format = buf[2] & 0xf;
513 start_track = buf[6];
514 bdrv_get_geometry(s->bdrv, &nb_sectors);
515 DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
516 switch(format) {
517 case 0:
518 toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
519 break;
520 case 1:
521 /* multi session : only a single session defined */
522 toclen = 12;
523 memset(outbuf, 0, 12);
524 outbuf[1] = 0x0a;
525 outbuf[2] = 0x01;
526 outbuf[3] = 0x01;
527 break;
528 case 2:
529 toclen = cdrom_read_toc_raw(nb_sectors, outbuf, msf, start_track);
530 break;
531 default:
532 goto error_cmd;
533 }
534 if (toclen > 0) {
535 if (len > toclen)
536 len = toclen;
537 r->buf_len = len;
538 break;
539 }
540 error_cmd:
541 DPRINTF("Read TOC error\n");
542 goto fail;
543 }
544 case 0x46:
545 DPRINTF("Get Configuration (rt %d, maxlen %d)\n", buf[1] & 3, len);
546 memset(outbuf, 0, 8);
547 /* ??? This shoud probably return much more information. For now
548 just return the basic header indicating the CD-ROM profile. */
549 outbuf[7] = 8; // CD-ROM
550 r->buf_len = 8;
551 break;
552 case 0x56:
553 DPRINTF("Reserve(10)\n");
554 if (buf[1] & 3)
555 goto fail;
556 break;
557 case 0x57:
558 DPRINTF("Release(10)\n");
559 if (buf[1] & 3)
560 goto fail;
561 break;
562 case 0xa0:
563 DPRINTF("Report LUNs (len %d)\n", len);
564 if (len < 16)
565 goto fail;
566 memset(outbuf, 0, 16);
567 outbuf[3] = 8;
568 r->buf_len = 16;
569 break;
570 default:
571 DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
572 fail:
573 scsi_command_complete(r, SENSE_ILLEGAL_REQUEST);
574 return 0;
575 }
576 if (r->sector_count == 0 && r->buf_len == 0) {
577 scsi_command_complete(r, SENSE_NO_SENSE);
578 }
579 len = r->sector_count * 512 + r->buf_len;
580 if (is_write) {
581 return -len;
582 } else {
583 if (!r->sector_count)
584 r->sector_count = -1;
585 return len;
586 }
587 }
589 void scsi_disk_destroy(SCSIDevice *s)
590 {
591 qemu_free(s);
592 }
594 SCSIDevice *scsi_disk_init(BlockDriverState *bdrv,
595 int tcq,
596 scsi_completionfn completion,
597 void *opaque)
598 {
599 SCSIDevice *s;
601 s = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
602 s->bdrv = bdrv;
603 s->tcq = tcq;
604 s->completion = completion;
605 s->opaque = opaque;
606 if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
607 s->cluster_size = 4;
608 } else {
609 s->cluster_size = 1;
610 }
612 return s;
613 }