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. Emultion of interface/link layer protocols is handled by
13 * the host adapter emulation.
19 #define DPRINTF(fmt, args...) \
20 do { printf("scsi-disk: " fmt , ##args); } while (0)
22 #define DPRINTF(fmt, args...) do {} while(0)
25 #define BADF(fmt, args...) \
26 do { fprintf(stderr, "scsi-disk: " fmt , ##args); } while (0)
30 #define SENSE_NO_SENSE 0
31 #define SENSE_NOT_READY 2
32 #define SENSE_HARDWARE_ERROR 4
33 #define SENSE_ILLEGAL_REQUEST 5
35 #define SCSI_DMA_BUF_SIZE 65536
37 typedef struct SCSIRequest
{
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. */
42 /* Both sector and sector_count are in terms of qemu 512 byte blocks. */
45 /* The amounnt of data in the buffer. */
47 uint8_t dma_buf
[SCSI_DMA_BUF_SIZE
];
48 BlockDriverAIOCB
*aiocb
;
49 struct SCSIRequest
*next
;
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. */
61 /* Completion functions may be called from either scsi_{read,write}_data
62 or from the AIO completion routines. */
63 scsi_completionfn completion
;
67 /* Global pool of SCSIRequest structures. */
68 static SCSIRequest
*free_requests
= NULL
;
70 static SCSIRequest
*scsi_new_request(SCSIDevice
*s
, uint32_t tag
)
76 free_requests
= r
->next
;
78 r
= qemu_malloc(sizeof(SCSIRequest
));
86 r
->next
= s
->requests
;
91 static void scsi_remove_request(SCSIRequest
*r
)
94 SCSIDevice
*s
= r
->dev
;
96 if (s
->requests
== r
) {
97 s
->requests
= r
->next
;
100 while (last
&& last
->next
!= r
)
103 last
->next
= r
->next
;
105 BADF("Orphaned request\n");
108 r
->next
= free_requests
;
112 static SCSIRequest
*scsi_find_request(SCSIDevice
*s
, uint32_t tag
)
117 while (r
&& r
->tag
!= tag
)
123 /* Helper function for command completion. */
124 static void scsi_command_complete(SCSIRequest
*r
, int sense
)
126 SCSIDevice
*s
= r
->dev
;
128 DPRINTF("Command complete tag=0x%x sense=%d\n", r
->tag
, sense
);
131 scsi_remove_request(r
);
132 s
->completion(s
->opaque
, SCSI_REASON_DONE
, tag
, sense
);
135 /* Cancel a pending data transfer. */
136 void scsi_cancel_io(SCSIDevice
*s
, uint32_t tag
)
139 DPRINTF("Cancel tag=0x%x\n", tag
);
140 r
= scsi_find_request(s
, tag
);
143 bdrv_aio_cancel(r
->aiocb
);
145 scsi_remove_request(r
);
149 static void scsi_read_complete(void * opaque
, int ret
)
151 SCSIRequest
*r
= (SCSIRequest
*)opaque
;
152 SCSIDevice
*s
= r
->dev
;
155 DPRINTF("IO error\n");
156 scsi_command_complete(r
, SENSE_HARDWARE_ERROR
);
159 DPRINTF("Data ready tag=0x%x len=%d\n", r
->tag
, r
->buf_len
);
161 s
->completion(s
->opaque
, SCSI_REASON_DATA
, r
->tag
, r
->buf_len
);
164 /* Read more data from scsi device into buffer. */
165 void scsi_read_data(SCSIDevice
*s
, uint32_t tag
)
170 r
= scsi_find_request(s
, tag
);
172 BADF("Bad read tag 0x%x\n", tag
);
173 /* ??? This is the wrong error. */
174 scsi_command_complete(r
, SENSE_HARDWARE_ERROR
);
177 if (r
->sector_count
== (uint32_t)-1) {
178 DPRINTF("Read buf_len=%d\n", r
->buf_len
);
180 s
->completion(s
->opaque
, SCSI_REASON_DATA
, r
->tag
, r
->buf_len
);
183 DPRINTF("Read sector_count=%d\n", r
->sector_count
);
184 if (r
->sector_count
== 0) {
185 scsi_command_complete(r
, SENSE_NO_SENSE
);
190 if (n
> SCSI_DMA_BUF_SIZE
/ 512)
191 n
= SCSI_DMA_BUF_SIZE
/ 512;
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
);
199 r
->sector_count
-= n
;
202 static void scsi_write_complete(void * opaque
, int ret
)
204 SCSIRequest
*r
= (SCSIRequest
*)opaque
;
205 SCSIDevice
*s
= r
->dev
;
209 fprintf(stderr
, "scsi-disc: IO write error\n");
214 if (r
->sector_count
== 0) {
215 scsi_command_complete(r
, SENSE_NO_SENSE
);
217 len
= r
->sector_count
* 512;
218 if (len
> SCSI_DMA_BUF_SIZE
) {
219 len
= SCSI_DMA_BUF_SIZE
;
222 DPRINTF("Write complete tag=0x%x more=%d\n", r
->tag
, len
);
223 s
->completion(s
->opaque
, SCSI_REASON_DATA
, r
->tag
, len
);
227 /* Write data to a scsi device. Returns nonzero on failure.
228 The transfer may complete asynchronously. */
229 int scsi_write_data(SCSIDevice
*s
, uint32_t tag
)
234 DPRINTF("Write data tag=0x%x\n", tag
);
235 r
= scsi_find_request(s
, tag
);
237 BADF("Bad write tag 0x%x\n", tag
);
238 scsi_command_complete(r
, SENSE_HARDWARE_ERROR
);
242 BADF("Data transfer already in progress\n");
243 n
= r
->buf_len
/ 512;
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
);
250 r
->sector_count
-= n
;
252 /* Invoke completion routine to fetch data from host. */
253 scsi_write_complete(r
, 0);
259 /* Return a pointer to the data buffer. */
260 uint8_t *scsi_get_buf(SCSIDevice
*s
, uint32_t tag
)
264 r
= scsi_find_request(s
, tag
);
266 BADF("Bad buffer tag 0x%x\n", tag
);
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. */
277 int32_t scsi_send_command(SCSIDevice
*s
, uint32_t tag
, uint8_t *buf
, int lun
)
289 r
= scsi_find_request(s
, tag
);
291 BADF("Tag 0x%x already in use\n", tag
);
292 scsi_cancel_io(s
, tag
);
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
);
299 DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun
, tag
, buf
[0]);
300 switch (command
>> 5) {
302 lba
= buf
[3] | (buf
[2] << 8) | ((buf
[1] & 0x1f) << 16);
308 lba
= buf
[5] | (buf
[4] << 8) | (buf
[3] << 16) | (buf
[2] << 24);
309 len
= buf
[8] | (buf
[7] << 8);
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);
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);
323 BADF("Unsupported command length, command %x\n", command
);
329 for (i
= 1; i
< cmdlen
; i
++) {
330 printf(" 0x%02x", buf
[i
]);
335 if (lun
|| buf
[1] >> 5) {
336 /* Only LUN 0 supported. */
337 DPRINTF("Unimplemented LUN %d\n", lun
? lun
: buf
[1] >> 5);
342 DPRINTF("Test Unit Ready\n");
345 DPRINTF("Request Sense (len %d)\n", len
);
351 outbuf
[2] = s
->sense
;
355 DPRINTF("Inquiry (len %d)\n", len
);
357 BADF("Inquiry buffer too small (%d)\n", len
);
359 memset(outbuf
, 0, 36);
360 if (bdrv_get_type_hint(s
->bdrv
) == BDRV_TYPE_CDROM
) {
363 memcpy(&outbuf
[16], "QEMU CD-ROM ", 16);
366 memcpy(&outbuf
[16], "QEMU HARDDISK ", 16);
368 memcpy(&outbuf
[8], "QEMU ", 8);
369 memcpy(&outbuf
[32], QEMU_VERSION
, 4);
370 /* Identify device as SCSI-3 rev 1.
371 Some later commands are also implemented. */
373 outbuf
[3] = 2; /* Format 2 */
375 /* Sync data transfer and TCQ. */
376 outbuf
[7] = 0x10 | (s
->tcq
? 0x02 : 0);
380 DPRINTF("Reserve(6)\n");
385 DPRINTF("Release(6)\n");
395 page
= buf
[2] & 0x3f;
396 DPRINTF("Mode Sense (page %d, len %d)\n", page
, len
);
399 outbuf
[1] = 0; /* Default media type. */
400 outbuf
[3] = 0; /* Block descriptor length. */
401 if (bdrv_get_type_hint(s
->bdrv
) == BDRV_TYPE_CDROM
) {
402 outbuf
[2] = 0x80; /* Readonly. */
405 if ((page
== 8 || page
== 0x3f)) {
412 if ((page
== 0x3f || page
== 0x2a)
413 && (bdrv_get_type_hint(s
->bdrv
) == BDRV_TYPE_CDROM
)) {
414 /* CD Capabilities and Mechanical Status page. */
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,
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
428 p
[8] = (50 * 176) >> 8; // 50x read speed
429 p
[9] = (50 * 176) & 0xff;
430 p
[10] = 0 >> 8; // No volume
432 p
[12] = 2048 >> 8; // 2M buffer
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;
442 r
->buf_len
= p
- outbuf
;
443 outbuf
[0] = r
->buf_len
- 4;
444 if (r
->buf_len
> len
)
449 DPRINTF("Start Stop Unit\n");
452 DPRINTF("Prevent Allow Medium Removal (prevent = %d)\n", buf
[4] & 3);
453 bdrv_set_locked(s
->bdrv
, buf
[4] & 1);
456 DPRINTF("Read Capacity\n");
457 /* The normal LEN field for this command is zero. */
458 memset(outbuf
, 0, 8);
459 bdrv_get_geometry(s
->bdrv
, &nb_sectors
);
460 /* Returned value is the address of the last sector. */
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;
469 outbuf
[6] = s
->cluster_size
* 2;
473 scsi_command_complete(r
, SENSE_NOT_READY
);
479 DPRINTF("Read (sector %d, count %d)\n", lba
, len
);
480 r
->sector
= lba
* s
->cluster_size
;
481 r
->sector_count
= len
* s
->cluster_size
;
485 DPRINTF("Write (sector %d, count %d)\n", lba
, len
);
486 r
->sector
= lba
* s
->cluster_size
;
487 r
->sector_count
= len
* s
->cluster_size
;
491 DPRINTF("Syncronise cache (sector %d, count %d)\n", lba
, len
);
496 int start_track
, format
, msf
, toclen
;
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);
505 toclen
= cdrom_read_toc(nb_sectors
, outbuf
, msf
, start_track
);
508 /* multi session : only a single session defined */
510 memset(outbuf
, 0, 12);
516 toclen
= cdrom_read_toc_raw(nb_sectors
, outbuf
, msf
, start_track
);
528 DPRINTF("Read TOC error\n");
532 DPRINTF("Get Configuration (rt %d, maxlen %d)\n", buf
[1] & 3, len
);
533 memset(outbuf
, 0, 8);
534 /* ??? This shoud probably return much more information. For now
535 just return the basic header indicating the CD-ROM profile. */
536 outbuf
[7] = 8; // CD-ROM
540 DPRINTF("Reserve(10)\n");
545 DPRINTF("Release(10)\n");
550 DPRINTF("Report LUNs (len %d)\n", len
);
553 memset(outbuf
, 0, 16);
558 DPRINTF("Unknown SCSI command (%2.2x)\n", buf
[0]);
560 scsi_command_complete(r
, SENSE_ILLEGAL_REQUEST
);
563 if (r
->sector_count
== 0 && r
->buf_len
== 0) {
564 scsi_command_complete(r
, SENSE_NO_SENSE
);
566 len
= r
->sector_count
* 512 + r
->buf_len
;
570 if (!r
->sector_count
)
571 r
->sector_count
= -1;
576 void scsi_disk_destroy(SCSIDevice
*s
)
581 SCSIDevice
*scsi_disk_init(BlockDriverState
*bdrv
,
583 scsi_completionfn completion
,
588 s
= (SCSIDevice
*)qemu_mallocz(sizeof(SCSIDevice
));
591 s
->completion
= completion
;
593 if (bdrv_get_type_hint(s
->bdrv
) == BDRV_TYPE_CDROM
) {