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