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 #include <qemu-common.h>
21 #define DPRINTF(fmt, ...) \
22 do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
24 #define DPRINTF(fmt, ...) do {} while(0)
27 #define BADF(fmt, ...) \
28 do { fprintf(stderr, "scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
30 #include "qemu-common.h"
34 #define SENSE_NO_SENSE 0
35 #define SENSE_NOT_READY 2
36 #define SENSE_HARDWARE_ERROR 4
37 #define SENSE_ILLEGAL_REQUEST 5
40 #define STATUS_CHECK_CONDITION 2
42 #define SCSI_DMA_BUF_SIZE 131072
43 #define SCSI_MAX_INQUIRY_LEN 256
45 #define SCSI_REQ_STATUS_RETRY 0x01
47 typedef struct SCSIDiskState SCSIDiskState
;
49 typedef struct SCSIRequest
{
53 /* ??? We should probably keep track of whether the data transfer is
54 a read or a write. Currently we rely on the host getting it right. */
55 /* Both sector and sector_count are in terms of qemu 512 byte blocks. */
57 uint32_t sector_count
;
60 BlockDriverAIOCB
*aiocb
;
61 struct SCSIRequest
*next
;
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. */
75 char drive_serial_str
[21];
79 /* Global pool of SCSIRequest structures. */
80 static SCSIRequest
*free_requests
= NULL
;
82 static SCSIRequest
*scsi_new_request(SCSIDevice
*d
, uint32_t tag
)
84 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, d
);
89 free_requests
= r
->next
;
91 r
= qemu_malloc(sizeof(SCSIRequest
));
92 r
->iov
.iov_base
= qemu_memalign(512, SCSI_DMA_BUF_SIZE
);
94 r
->bus
= scsi_bus_from_device(d
);
102 r
->next
= s
->requests
;
107 static void scsi_remove_request(SCSIRequest
*r
)
110 SCSIDiskState
*s
= r
->dev
;
112 if (s
->requests
== r
) {
113 s
->requests
= r
->next
;
116 while (last
&& last
->next
!= r
)
119 last
->next
= r
->next
;
121 BADF("Orphaned request\n");
124 r
->next
= free_requests
;
128 static SCSIRequest
*scsi_find_request(SCSIDiskState
*s
, uint32_t tag
)
133 while (r
&& r
->tag
!= tag
)
139 /* Helper function for command completion. */
140 static void scsi_command_complete(SCSIRequest
*r
, int status
, int sense
)
142 SCSIDiskState
*s
= r
->dev
;
144 DPRINTF("Command complete tag=0x%x status=%d sense=%d\n", r
->tag
, status
, sense
);
147 scsi_remove_request(r
);
148 r
->bus
->complete(r
->bus
, SCSI_REASON_DONE
, tag
, status
);
151 /* Cancel a pending data transfer. */
152 static void scsi_cancel_io(SCSIDevice
*d
, uint32_t tag
)
154 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, d
);
156 DPRINTF("Cancel tag=0x%x\n", tag
);
157 r
= scsi_find_request(s
, tag
);
160 bdrv_aio_cancel(r
->aiocb
);
162 scsi_remove_request(r
);
166 static void scsi_read_complete(void * opaque
, int ret
)
168 SCSIRequest
*r
= (SCSIRequest
*)opaque
;
171 DPRINTF("IO error\n");
172 r
->bus
->complete(r
->bus
, SCSI_REASON_DATA
, r
->tag
, 0);
173 scsi_command_complete(r
, STATUS_CHECK_CONDITION
, SENSE_NO_SENSE
);
176 DPRINTF("Data ready tag=0x%x len=%" PRId64
"\n", r
->tag
, r
->iov
.iov_len
);
178 r
->bus
->complete(r
->bus
, SCSI_REASON_DATA
, r
->tag
, r
->iov
.iov_len
);
181 /* Read more data from scsi device into buffer. */
182 static void scsi_read_data(SCSIDevice
*d
, uint32_t tag
)
184 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, d
);
188 r
= scsi_find_request(s
, tag
);
190 BADF("Bad read tag 0x%x\n", tag
);
191 /* ??? This is the wrong error. */
192 scsi_command_complete(r
, STATUS_CHECK_CONDITION
, SENSE_HARDWARE_ERROR
);
195 if (r
->sector_count
== (uint32_t)-1) {
196 DPRINTF("Read buf_len=%" PRId64
"\n", r
->iov
.iov_len
);
198 r
->bus
->complete(r
->bus
, SCSI_REASON_DATA
, r
->tag
, r
->iov
.iov_len
);
201 DPRINTF("Read sector_count=%d\n", r
->sector_count
);
202 if (r
->sector_count
== 0) {
203 scsi_command_complete(r
, STATUS_GOOD
, SENSE_NO_SENSE
);
208 if (n
> SCSI_DMA_BUF_SIZE
/ 512)
209 n
= SCSI_DMA_BUF_SIZE
/ 512;
211 r
->iov
.iov_len
= n
* 512;
212 qemu_iovec_init_external(&r
->qiov
, &r
->iov
, 1);
213 r
->aiocb
= bdrv_aio_readv(s
->dinfo
->bdrv
, r
->sector
, &r
->qiov
, n
,
214 scsi_read_complete
, r
);
215 if (r
->aiocb
== NULL
)
216 scsi_command_complete(r
, STATUS_CHECK_CONDITION
, SENSE_HARDWARE_ERROR
);
218 r
->sector_count
-= n
;
221 static int scsi_handle_write_error(SCSIRequest
*r
, int error
)
223 BlockInterfaceErrorAction action
= drive_get_onerror(r
->dev
->dinfo
->bdrv
);
225 if (action
== BLOCK_ERR_IGNORE
)
228 if ((error
== ENOSPC
&& action
== BLOCK_ERR_STOP_ENOSPC
)
229 || action
== BLOCK_ERR_STOP_ANY
) {
230 r
->status
|= SCSI_REQ_STATUS_RETRY
;
233 scsi_command_complete(r
, STATUS_CHECK_CONDITION
,
234 SENSE_HARDWARE_ERROR
);
240 static void scsi_write_complete(void * opaque
, int ret
)
242 SCSIRequest
*r
= (SCSIRequest
*)opaque
;
249 if (scsi_handle_write_error(r
, -ret
))
253 n
= r
->iov
.iov_len
/ 512;
255 r
->sector_count
-= n
;
256 if (r
->sector_count
== 0) {
257 scsi_command_complete(r
, STATUS_GOOD
, SENSE_NO_SENSE
);
259 len
= r
->sector_count
* 512;
260 if (len
> SCSI_DMA_BUF_SIZE
) {
261 len
= SCSI_DMA_BUF_SIZE
;
263 r
->iov
.iov_len
= len
;
264 DPRINTF("Write complete tag=0x%x more=%d\n", r
->tag
, len
);
265 r
->bus
->complete(r
->bus
, SCSI_REASON_DATA
, r
->tag
, len
);
269 static void scsi_write_request(SCSIRequest
*r
)
271 SCSIDiskState
*s
= r
->dev
;
274 n
= r
->iov
.iov_len
/ 512;
276 qemu_iovec_init_external(&r
->qiov
, &r
->iov
, 1);
277 r
->aiocb
= bdrv_aio_writev(s
->dinfo
->bdrv
, r
->sector
, &r
->qiov
, n
,
278 scsi_write_complete
, r
);
279 if (r
->aiocb
== NULL
)
280 scsi_command_complete(r
, STATUS_CHECK_CONDITION
,
281 SENSE_HARDWARE_ERROR
);
283 /* Invoke completion routine to fetch data from host. */
284 scsi_write_complete(r
, 0);
288 /* Write data to a scsi device. Returns nonzero on failure.
289 The transfer may complete asynchronously. */
290 static int scsi_write_data(SCSIDevice
*d
, uint32_t tag
)
292 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, d
);
295 DPRINTF("Write data tag=0x%x\n", tag
);
296 r
= scsi_find_request(s
, tag
);
298 BADF("Bad write tag 0x%x\n", tag
);
299 scsi_command_complete(r
, STATUS_CHECK_CONDITION
, SENSE_HARDWARE_ERROR
);
304 BADF("Data transfer already in progress\n");
306 scsi_write_request(r
);
311 static void scsi_dma_restart_bh(void *opaque
)
313 SCSIDiskState
*s
= opaque
;
314 SCSIRequest
*r
= s
->requests
;
316 qemu_bh_delete(s
->bh
);
320 if (r
->status
& SCSI_REQ_STATUS_RETRY
) {
321 r
->status
&= ~SCSI_REQ_STATUS_RETRY
;
322 scsi_write_request(r
);
328 static void scsi_dma_restart_cb(void *opaque
, int running
, int reason
)
330 SCSIDiskState
*s
= opaque
;
336 s
->bh
= qemu_bh_new(scsi_dma_restart_bh
, s
);
337 qemu_bh_schedule(s
->bh
);
341 /* Return a pointer to the data buffer. */
342 static uint8_t *scsi_get_buf(SCSIDevice
*d
, uint32_t tag
)
344 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, d
);
347 r
= scsi_find_request(s
, tag
);
349 BADF("Bad buffer tag 0x%x\n", tag
);
352 return (uint8_t *)r
->iov
.iov_base
;
355 /* Execute a scsi command. Returns the length of the data expected by the
356 command. This will be Positive for data transfers from the device
357 (eg. disk reads), negative for transfers to the device (eg. disk writes),
358 and zero if the command does not transfer any data. */
360 static int32_t scsi_send_command(SCSIDevice
*d
, uint32_t tag
,
361 uint8_t *buf
, int lun
)
363 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, d
);
374 r
= scsi_find_request(s
, tag
);
376 BADF("Tag 0x%x already in use\n", tag
);
377 scsi_cancel_io(d
, tag
);
379 /* ??? Tags are not unique for different luns. We only implement a
380 single lun, so this should not matter. */
381 r
= scsi_new_request(d
, tag
);
382 outbuf
= (uint8_t *)r
->iov
.iov_base
;
384 DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun
, tag
, buf
[0]);
385 switch (command
>> 5) {
387 lba
= (uint64_t) buf
[3] | ((uint64_t) buf
[2] << 8) |
388 (((uint64_t) buf
[1] & 0x1f) << 16);
394 lba
= (uint64_t) buf
[5] | ((uint64_t) buf
[4] << 8) |
395 ((uint64_t) buf
[3] << 16) | ((uint64_t) buf
[2] << 24);
396 len
= buf
[8] | (buf
[7] << 8);
400 lba
= (uint64_t) buf
[9] | ((uint64_t) buf
[8] << 8) |
401 ((uint64_t) buf
[7] << 16) | ((uint64_t) buf
[6] << 24) |
402 ((uint64_t) buf
[5] << 32) | ((uint64_t) buf
[4] << 40) |
403 ((uint64_t) buf
[3] << 48) | ((uint64_t) buf
[2] << 56);
404 len
= buf
[13] | (buf
[12] << 8) | (buf
[11] << 16) | (buf
[10] << 24);
408 lba
= (uint64_t) buf
[5] | ((uint64_t) buf
[4] << 8) |
409 ((uint64_t) buf
[3] << 16) | ((uint64_t) buf
[2] << 24);
410 len
= buf
[9] | (buf
[8] << 8) | (buf
[7] << 16) | (buf
[6] << 24);
414 BADF("Unsupported command length, command %x\n", command
);
420 for (i
= 1; i
< cmdlen
; i
++) {
421 printf(" 0x%02x", buf
[i
]);
426 if (lun
|| buf
[1] >> 5) {
427 /* Only LUN 0 supported. */
428 DPRINTF("Unimplemented LUN %d\n", lun
? lun
: buf
[1] >> 5);
429 if (command
!= 0x03 && command
!= 0x12) /* REQUEST SENSE and INQUIRY */
434 DPRINTF("Test Unit Ready\n");
435 if (!bdrv_is_inserted(s
->dinfo
->bdrv
))
439 DPRINTF("Request Sense (len %d)\n", len
);
442 memset(outbuf
, 0, 4);
444 if (s
->sense
== SENSE_NOT_READY
&& len
>= 18) {
445 memset(outbuf
, 0, 18);
448 /* asc 0x3a, ascq 0: Medium not present */
454 outbuf
[2] = s
->sense
;
457 DPRINTF("Inquiry (len %d)\n", len
);
459 /* Command support data - optional, not implemented */
460 BADF("optional INQUIRY command support request not implemented\n");
463 else if (buf
[1] & 0x1) {
464 /* Vital product data */
465 uint8_t page_code
= buf
[2];
467 BADF("Error: Inquiry (EVPD[%02X]) buffer size %d is "
468 "less than 4\n", page_code
, len
);
475 /* Supported page codes, mandatory */
476 DPRINTF("Inquiry EVPD[Supported pages] "
477 "buffer size %d\n", len
);
481 if (bdrv_get_type_hint(s
->dinfo
->bdrv
) == BDRV_TYPE_CDROM
) {
482 outbuf
[r
->iov
.iov_len
++] = 5;
484 outbuf
[r
->iov
.iov_len
++] = 0;
487 outbuf
[r
->iov
.iov_len
++] = 0x00; // this page
488 outbuf
[r
->iov
.iov_len
++] = 0x00;
489 outbuf
[r
->iov
.iov_len
++] = 3; // number of pages
490 outbuf
[r
->iov
.iov_len
++] = 0x00; // list of supported pages (this page)
491 outbuf
[r
->iov
.iov_len
++] = 0x80; // unit serial number
492 outbuf
[r
->iov
.iov_len
++] = 0x83; // device identification
499 /* Device serial number, optional */
501 BADF("Error: EVPD[Serial number] Inquiry buffer "
502 "size %d too small, %d needed\n", len
, 4);
506 DPRINTF("Inquiry EVPD[Serial number] buffer size %d\n", len
);
507 l
= MIN(len
, strlen(s
->drive_serial_str
));
511 /* Supported page codes */
512 if (bdrv_get_type_hint(s
->dinfo
->bdrv
) == BDRV_TYPE_CDROM
) {
513 outbuf
[r
->iov
.iov_len
++] = 5;
515 outbuf
[r
->iov
.iov_len
++] = 0;
518 outbuf
[r
->iov
.iov_len
++] = 0x80; // this page
519 outbuf
[r
->iov
.iov_len
++] = 0x00;
520 outbuf
[r
->iov
.iov_len
++] = l
;
521 memcpy(&outbuf
[r
->iov
.iov_len
], s
->drive_serial_str
, l
);
528 /* Device identification page, mandatory */
529 int max_len
= 255 - 8;
530 int id_len
= strlen(bdrv_get_device_name(s
->dinfo
->bdrv
));
531 if (id_len
> max_len
)
534 DPRINTF("Inquiry EVPD[Device identification] "
535 "buffer size %d\n", len
);
537 if (bdrv_get_type_hint(s
->dinfo
->bdrv
) == BDRV_TYPE_CDROM
) {
538 outbuf
[r
->iov
.iov_len
++] = 5;
540 outbuf
[r
->iov
.iov_len
++] = 0;
543 outbuf
[r
->iov
.iov_len
++] = 0x83; // this page
544 outbuf
[r
->iov
.iov_len
++] = 0x00;
545 outbuf
[r
->iov
.iov_len
++] = 3 + id_len
;
547 outbuf
[r
->iov
.iov_len
++] = 0x2; // ASCII
548 outbuf
[r
->iov
.iov_len
++] = 0; // not officially assigned
549 outbuf
[r
->iov
.iov_len
++] = 0; // reserved
550 outbuf
[r
->iov
.iov_len
++] = id_len
; // length of data following
552 memcpy(&outbuf
[r
->iov
.iov_len
],
553 bdrv_get_device_name(s
->dinfo
->bdrv
), id_len
);
554 r
->iov
.iov_len
+= id_len
;
558 BADF("Error: unsupported Inquiry (EVPD[%02X]) "
559 "buffer size %d\n", page_code
, len
);
566 /* Standard INQUIRY data */
568 BADF("Error: Inquiry (STANDARD) page or code "
569 "is non-zero [%02X]\n", buf
[2]);
575 BADF("Error: Inquiry (STANDARD) buffer size %d "
576 "is less than 5\n", len
);
581 BADF("Error: Inquiry (STANDARD) buffer size %d "
582 "is less than 36 (TODO: only 5 required)\n", len
);
586 if(len
> SCSI_MAX_INQUIRY_LEN
)
587 len
= SCSI_MAX_INQUIRY_LEN
;
589 memset(outbuf
, 0, len
);
591 if (lun
|| buf
[1] >> 5) {
592 outbuf
[0] = 0x7f; /* LUN not supported */
593 } else if (bdrv_get_type_hint(s
->dinfo
->bdrv
) == BDRV_TYPE_CDROM
) {
596 memcpy(&outbuf
[16], "QEMU CD-ROM ", 16);
599 memcpy(&outbuf
[16], "QEMU HARDDISK ", 16);
601 memcpy(&outbuf
[8], "QEMU ", 8);
602 memcpy(&outbuf
[32], QEMU_VERSION
, 4);
603 /* Identify device as SCSI-3 rev 1.
604 Some later commands are also implemented. */
606 outbuf
[3] = 2; /* Format 2 */
607 outbuf
[4] = len
- 5; /* Additional Length = (Len - 1) - 4 */
608 /* Sync data transfer and TCQ. */
609 outbuf
[7] = 0x10 | (r
->bus
->tcq
? 0x02 : 0);
610 r
->iov
.iov_len
= len
;
613 DPRINTF("Reserve(6)\n");
618 DPRINTF("Release(6)\n");
630 page
= buf
[2] & 0x3f;
631 DPRINTF("Mode Sense (page %d, len %d)\n", page
, len
);
634 outbuf
[1] = 0; /* Default media type. */
635 outbuf
[3] = 0; /* Block descriptor length. */
636 if (bdrv_get_type_hint(s
->dinfo
->bdrv
) == BDRV_TYPE_CDROM
||
637 bdrv_is_read_only(s
->dinfo
->bdrv
)) {
638 outbuf
[2] = 0x80; /* Readonly. */
641 bdrv_get_geometry(s
->dinfo
->bdrv
, &nb_sectors
);
642 if ((~dbd
) & nb_sectors
) {
643 nb_sectors
/= s
->cluster_size
;
645 if (nb_sectors
> 0xffffff)
646 nb_sectors
= 0xffffff;
647 outbuf
[3] = 8; /* Block descriptor length */
648 p
[0] = 0; /* media density code */
649 p
[1] = (nb_sectors
>> 16) & 0xff;
650 p
[2] = (nb_sectors
>> 8) & 0xff;
651 p
[3] = nb_sectors
& 0xff;
652 p
[4] = 0; /* reserved */
653 p
[5] = 0; /* bytes 5-7 are the sector size in bytes */
654 p
[6] = s
->cluster_size
* 2;
660 int cylinders
, heads
, secs
;
662 /* Rigid disk device geometry page. */
665 /* if a geometry hint is available, use it */
666 bdrv_get_geometry_hint(s
->dinfo
->bdrv
, &cylinders
, &heads
, &secs
);
667 p
[2] = (cylinders
>> 16) & 0xff;
668 p
[3] = (cylinders
>> 8) & 0xff;
669 p
[4] = cylinders
& 0xff;
671 /* Write precomp start cylinder, disabled */
672 p
[6] = (cylinders
>> 16) & 0xff;
673 p
[7] = (cylinders
>> 8) & 0xff;
674 p
[8] = cylinders
& 0xff;
675 /* Reduced current start cylinder, disabled */
676 p
[9] = (cylinders
>> 16) & 0xff;
677 p
[10] = (cylinders
>> 8) & 0xff;
678 p
[11] = cylinders
& 0xff;
679 /* Device step rate [ns], 200ns */
682 /* Landing zone cylinder */
686 /* Medium rotation rate [rpm], 5400 rpm */
687 p
[20] = (5400 >> 8) & 0xff;
690 } else if (page
== 5) {
691 int cylinders
, heads
, secs
;
693 /* Flexible disk device geometry page. */
696 /* Transfer rate [kbit/s], 5Mbit/s */
699 /* if a geometry hint is available, use it */
700 bdrv_get_geometry_hint(s
->dinfo
->bdrv
, &cylinders
, &heads
, &secs
);
703 p
[6] = s
->cluster_size
* 2;
704 p
[8] = (cylinders
>> 8) & 0xff;
705 p
[9] = cylinders
& 0xff;
706 /* Write precomp start cylinder, disabled */
707 p
[10] = (cylinders
>> 8) & 0xff;
708 p
[11] = cylinders
& 0xff;
709 /* Reduced current start cylinder, disabled */
710 p
[12] = (cylinders
>> 8) & 0xff;
711 p
[13] = cylinders
& 0xff;
712 /* Device step rate [100us], 100us */
715 /* Device step pulse width [us], 1us */
717 /* Device head settle delay [100us], 100us */
720 /* Motor on delay [0.1s], 0.1s */
722 /* Motor off delay [0.1s], 0.1s */
724 /* Medium rotation rate [rpm], 5400 rpm */
725 p
[28] = (5400 >> 8) & 0xff;
728 } else if ((page
== 8 || page
== 0x3f)) {
733 if (bdrv_enable_write_cache(s
->dinfo
->bdrv
)) {
738 if ((page
== 0x3f || page
== 0x2a)
739 && (bdrv_get_type_hint(s
->dinfo
->bdrv
) == BDRV_TYPE_CDROM
)) {
740 /* CD Capabilities and Mechanical Status page. */
743 p
[2] = 3; // CD-R & CD-RW read
744 p
[3] = 0; // Writing not supported
745 p
[4] = 0x7f; /* Audio, composite, digital out,
746 mode 2 form 1&2, multi session */
747 p
[5] = 0xff; /* CD DA, DA accurate, RW supported,
748 RW corrected, C2 errors, ISRC,
750 p
[6] = 0x2d | (bdrv_is_locked(s
->dinfo
->bdrv
)? 2 : 0);
751 /* Locking supported, jumper present, eject, tray */
752 p
[7] = 0; /* no volume & mute control, no
754 p
[8] = (50 * 176) >> 8; // 50x read speed
755 p
[9] = (50 * 176) & 0xff;
756 p
[10] = 0 >> 8; // No volume
758 p
[12] = 2048 >> 8; // 2M buffer
760 p
[14] = (16 * 176) >> 8; // 16x read speed current
761 p
[15] = (16 * 176) & 0xff;
762 p
[18] = (16 * 176) >> 8; // 16x write speed
763 p
[19] = (16 * 176) & 0xff;
764 p
[20] = (16 * 176) >> 8; // 16x write speed current
765 p
[21] = (16 * 176) & 0xff;
768 r
->iov
.iov_len
= p
- outbuf
;
769 outbuf
[0] = r
->iov
.iov_len
- 4;
770 if (r
->iov
.iov_len
> len
)
771 r
->iov
.iov_len
= len
;
775 DPRINTF("Start Stop Unit\n");
776 if (bdrv_get_type_hint(s
->dinfo
->bdrv
) == BDRV_TYPE_CDROM
&&
778 /* load/eject medium */
779 bdrv_eject(s
->dinfo
->bdrv
, !(buf
[4] & 1));
782 DPRINTF("Prevent Allow Medium Removal (prevent = %d)\n", buf
[4] & 3);
783 bdrv_set_locked(s
->dinfo
->bdrv
, buf
[4] & 1);
786 DPRINTF("Read Capacity\n");
787 /* The normal LEN field for this command is zero. */
788 memset(outbuf
, 0, 8);
789 bdrv_get_geometry(s
->dinfo
->bdrv
, &nb_sectors
);
790 nb_sectors
/= s
->cluster_size
;
791 /* Returned value is the address of the last sector. */
794 /* Remember the new size for read/write sanity checking. */
795 s
->max_lba
= nb_sectors
;
796 /* Clip to 2TB, instead of returning capacity modulo 2TB. */
797 if (nb_sectors
> UINT32_MAX
)
798 nb_sectors
= UINT32_MAX
;
799 outbuf
[0] = (nb_sectors
>> 24) & 0xff;
800 outbuf
[1] = (nb_sectors
>> 16) & 0xff;
801 outbuf
[2] = (nb_sectors
>> 8) & 0xff;
802 outbuf
[3] = nb_sectors
& 0xff;
805 outbuf
[6] = s
->cluster_size
* 2;
810 scsi_command_complete(r
, STATUS_CHECK_CONDITION
, SENSE_NOT_READY
);
817 DPRINTF("Read (sector %" PRId64
", count %d)\n", lba
, len
);
818 if (lba
> s
->max_lba
)
820 r
->sector
= lba
* s
->cluster_size
;
821 r
->sector_count
= len
* s
->cluster_size
;
826 DPRINTF("Write (sector %" PRId64
", count %d)\n", lba
, len
);
827 if (lba
> s
->max_lba
)
829 r
->sector
= lba
* s
->cluster_size
;
830 r
->sector_count
= len
* s
->cluster_size
;
834 DPRINTF("Synchronise cache (sector %" PRId64
", count %d)\n", lba
, len
);
835 bdrv_flush(s
->dinfo
->bdrv
);
839 int start_track
, format
, msf
, toclen
;
842 format
= buf
[2] & 0xf;
843 start_track
= buf
[6];
844 bdrv_get_geometry(s
->dinfo
->bdrv
, &nb_sectors
);
845 DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track
, format
, msf
>> 1);
846 nb_sectors
/= s
->cluster_size
;
849 toclen
= cdrom_read_toc(nb_sectors
, outbuf
, msf
, start_track
);
852 /* multi session : only a single session defined */
854 memset(outbuf
, 0, 12);
860 toclen
= cdrom_read_toc_raw(nb_sectors
, outbuf
, msf
, start_track
);
868 r
->iov
.iov_len
= len
;
872 DPRINTF("Read TOC error\n");
876 DPRINTF("Get Configuration (rt %d, maxlen %d)\n", buf
[1] & 3, len
);
877 memset(outbuf
, 0, 8);
878 /* ??? This should probably return much more information. For now
879 just return the basic header indicating the CD-ROM profile. */
880 outbuf
[7] = 8; // CD-ROM
884 DPRINTF("Reserve(10)\n");
889 DPRINTF("Release(10)\n");
894 /* Service Action In subcommands. */
895 if ((buf
[1] & 31) == 0x10) {
896 DPRINTF("SAI READ CAPACITY(16)\n");
897 memset(outbuf
, 0, len
);
898 bdrv_get_geometry(s
->dinfo
->bdrv
, &nb_sectors
);
899 nb_sectors
/= s
->cluster_size
;
900 /* Returned value is the address of the last sector. */
903 /* Remember the new size for read/write sanity checking. */
904 s
->max_lba
= nb_sectors
;
905 outbuf
[0] = (nb_sectors
>> 56) & 0xff;
906 outbuf
[1] = (nb_sectors
>> 48) & 0xff;
907 outbuf
[2] = (nb_sectors
>> 40) & 0xff;
908 outbuf
[3] = (nb_sectors
>> 32) & 0xff;
909 outbuf
[4] = (nb_sectors
>> 24) & 0xff;
910 outbuf
[5] = (nb_sectors
>> 16) & 0xff;
911 outbuf
[6] = (nb_sectors
>> 8) & 0xff;
912 outbuf
[7] = nb_sectors
& 0xff;
915 outbuf
[10] = s
->cluster_size
* 2;
917 /* Protection, exponent and lowest lba field left blank. */
918 r
->iov
.iov_len
= len
;
920 scsi_command_complete(r
, STATUS_CHECK_CONDITION
, SENSE_NOT_READY
);
925 DPRINTF("Unsupported Service Action In\n");
928 DPRINTF("Report LUNs (len %d)\n", len
);
931 memset(outbuf
, 0, 16);
936 DPRINTF("Verify (sector %" PRId64
", count %d)\n", lba
, len
);
939 DPRINTF("Unknown SCSI command (%2.2x)\n", buf
[0]);
941 scsi_command_complete(r
, STATUS_CHECK_CONDITION
, SENSE_ILLEGAL_REQUEST
);
944 scsi_command_complete(r
, STATUS_CHECK_CONDITION
, SENSE_HARDWARE_ERROR
);
947 if (r
->sector_count
== 0 && r
->iov
.iov_len
== 0) {
948 scsi_command_complete(r
, STATUS_GOOD
, SENSE_NO_SENSE
);
950 len
= r
->sector_count
* 512 + r
->iov
.iov_len
;
954 if (!r
->sector_count
)
955 r
->sector_count
= -1;
960 static void scsi_destroy(SCSIDevice
*dev
)
962 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, dev
);
964 drive_uninit(s
->dinfo
);
967 static int scsi_disk_initfn(SCSIDevice
*dev
)
969 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, dev
);
972 if (!s
->dinfo
|| !s
->dinfo
->bdrv
) {
973 qemu_error("scsi-disk: drive property not set\n");
977 if (bdrv_get_type_hint(s
->dinfo
->bdrv
) == BDRV_TYPE_CDROM
) {
982 bdrv_get_geometry(s
->dinfo
->bdrv
, &nb_sectors
);
983 nb_sectors
/= s
->cluster_size
;
986 s
->max_lba
= nb_sectors
;
987 strncpy(s
->drive_serial_str
, drive_get_serial(s
->dinfo
->bdrv
),
988 sizeof(s
->drive_serial_str
));
989 if (strlen(s
->drive_serial_str
) == 0)
990 pstrcpy(s
->drive_serial_str
, sizeof(s
->drive_serial_str
), "0");
991 qemu_add_vm_change_state_handler(scsi_dma_restart_cb
, s
);
995 static SCSIDeviceInfo scsi_disk_info
= {
996 .qdev
.name
= "scsi-disk",
997 .qdev
.desc
= "virtual scsi disk or cdrom",
998 .qdev
.size
= sizeof(SCSIDiskState
),
999 .init
= scsi_disk_initfn
,
1000 .destroy
= scsi_destroy
,
1001 .send_command
= scsi_send_command
,
1002 .read_data
= scsi_read_data
,
1003 .write_data
= scsi_write_data
,
1004 .cancel_io
= scsi_cancel_io
,
1005 .get_buf
= scsi_get_buf
,
1006 .qdev
.props
= (Property
[]) {
1007 DEFINE_PROP_DRIVE("drive", SCSIDiskState
, dinfo
),
1008 DEFINE_PROP_END_OF_LIST(),
1012 static void scsi_disk_register_devices(void)
1014 scsi_qdev_register(&scsi_disk_info
);
1016 device_init(scsi_disk_register_devices
)