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"
33 #include "scsi-defs.h"
35 #define SCSI_DMA_BUF_SIZE 131072
36 #define SCSI_MAX_INQUIRY_LEN 256
38 #define SCSI_REQ_STATUS_RETRY 0x01
40 typedef struct SCSIDiskState SCSIDiskState
;
42 typedef struct SCSIDiskReq
{
44 /* ??? We should probably keep track of whether the data transfer is
45 a read or a write. Currently we rely on the host getting it right. */
46 /* Both sector and sector_count are in terms of qemu 512 byte blocks. */
48 uint32_t sector_count
;
57 /* The qemu block layer uses a fixed 512 byte sector size.
58 This is the number of 512 byte blocks in a single scsi sector. */
64 static SCSIDiskReq
*scsi_new_request(SCSIDevice
*d
, uint32_t tag
, uint32_t lun
)
69 req
= scsi_req_alloc(sizeof(SCSIDiskReq
), d
, tag
, lun
);
70 r
= DO_UPCAST(SCSIDiskReq
, req
, req
);
71 r
->iov
.iov_base
= qemu_memalign(512, SCSI_DMA_BUF_SIZE
);
75 static void scsi_remove_request(SCSIDiskReq
*r
)
77 qemu_free(r
->iov
.iov_base
);
78 scsi_req_free(&r
->req
);
81 static SCSIDiskReq
*scsi_find_request(SCSIDiskState
*s
, uint32_t tag
)
83 return DO_UPCAST(SCSIDiskReq
, req
, scsi_req_find(&s
->qdev
, tag
));
86 static void scsi_req_set_status(SCSIRequest
*req
, int status
, int sense_code
)
89 scsi_dev_set_sense(req
->dev
, sense_code
);
92 /* Helper function for command completion. */
93 static void scsi_command_complete(SCSIDiskReq
*r
, int status
, int sense
)
95 DPRINTF("Command complete tag=0x%x status=%d sense=%d\n",
96 r
->req
.tag
, status
, sense
);
97 scsi_req_set_status(&r
->req
, status
, sense
);
98 scsi_req_complete(&r
->req
);
99 scsi_remove_request(r
);
102 /* Cancel a pending data transfer. */
103 static void scsi_cancel_io(SCSIDevice
*d
, uint32_t tag
)
105 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, d
);
107 DPRINTF("Cancel tag=0x%x\n", tag
);
108 r
= scsi_find_request(s
, tag
);
111 bdrv_aio_cancel(r
->req
.aiocb
);
113 scsi_remove_request(r
);
117 static void scsi_read_complete(void * opaque
, int ret
)
119 SCSIDiskReq
*r
= (SCSIDiskReq
*)opaque
;
122 DPRINTF("IO error\n");
123 r
->req
.bus
->complete(r
->req
.bus
, SCSI_REASON_DATA
, r
->req
.tag
, 0);
124 scsi_command_complete(r
, CHECK_CONDITION
, NO_SENSE
);
127 DPRINTF("Data ready tag=0x%x len=%" PRId64
"\n", r
->req
.tag
, r
->iov
.iov_len
);
129 r
->req
.bus
->complete(r
->req
.bus
, SCSI_REASON_DATA
, r
->req
.tag
, r
->iov
.iov_len
);
132 /* Read more data from scsi device into buffer. */
133 static void scsi_read_data(SCSIDevice
*d
, uint32_t tag
)
135 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, d
);
139 r
= scsi_find_request(s
, tag
);
141 BADF("Bad read tag 0x%x\n", tag
);
142 /* ??? This is the wrong error. */
143 scsi_command_complete(r
, CHECK_CONDITION
, HARDWARE_ERROR
);
146 if (r
->sector_count
== (uint32_t)-1) {
147 DPRINTF("Read buf_len=%" PRId64
"\n", r
->iov
.iov_len
);
149 r
->req
.bus
->complete(r
->req
.bus
, SCSI_REASON_DATA
, r
->req
.tag
, r
->iov
.iov_len
);
152 DPRINTF("Read sector_count=%d\n", r
->sector_count
);
153 if (r
->sector_count
== 0) {
154 scsi_command_complete(r
, GOOD
, NO_SENSE
);
159 if (n
> SCSI_DMA_BUF_SIZE
/ 512)
160 n
= SCSI_DMA_BUF_SIZE
/ 512;
162 r
->iov
.iov_len
= n
* 512;
163 qemu_iovec_init_external(&r
->qiov
, &r
->iov
, 1);
164 r
->req
.aiocb
= bdrv_aio_readv(s
->qdev
.dinfo
->bdrv
, r
->sector
, &r
->qiov
, n
,
165 scsi_read_complete
, r
);
166 if (r
->req
.aiocb
== NULL
)
167 scsi_command_complete(r
, CHECK_CONDITION
, HARDWARE_ERROR
);
169 r
->sector_count
-= n
;
172 static int scsi_handle_write_error(SCSIDiskReq
*r
, int error
)
174 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, r
->req
.dev
);
175 BlockInterfaceErrorAction action
=
176 drive_get_on_error(s
->qdev
.dinfo
->bdrv
, 0);
178 if (action
== BLOCK_ERR_IGNORE
)
181 if ((error
== ENOSPC
&& action
== BLOCK_ERR_STOP_ENOSPC
)
182 || action
== BLOCK_ERR_STOP_ANY
) {
183 r
->status
|= SCSI_REQ_STATUS_RETRY
;
186 scsi_command_complete(r
, CHECK_CONDITION
,
193 static void scsi_write_complete(void * opaque
, int ret
)
195 SCSIDiskReq
*r
= (SCSIDiskReq
*)opaque
;
202 if (scsi_handle_write_error(r
, -ret
))
206 n
= r
->iov
.iov_len
/ 512;
208 r
->sector_count
-= n
;
209 if (r
->sector_count
== 0) {
210 scsi_command_complete(r
, GOOD
, NO_SENSE
);
212 len
= r
->sector_count
* 512;
213 if (len
> SCSI_DMA_BUF_SIZE
) {
214 len
= SCSI_DMA_BUF_SIZE
;
216 r
->iov
.iov_len
= len
;
217 DPRINTF("Write complete tag=0x%x more=%d\n", r
->req
.tag
, len
);
218 r
->req
.bus
->complete(r
->req
.bus
, SCSI_REASON_DATA
, r
->req
.tag
, len
);
222 static void scsi_write_request(SCSIDiskReq
*r
)
224 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, r
->req
.dev
);
227 n
= r
->iov
.iov_len
/ 512;
229 qemu_iovec_init_external(&r
->qiov
, &r
->iov
, 1);
230 r
->req
.aiocb
= bdrv_aio_writev(s
->qdev
.dinfo
->bdrv
, r
->sector
, &r
->qiov
, n
,
231 scsi_write_complete
, r
);
232 if (r
->req
.aiocb
== NULL
)
233 scsi_command_complete(r
, CHECK_CONDITION
,
236 /* Invoke completion routine to fetch data from host. */
237 scsi_write_complete(r
, 0);
241 /* Write data to a scsi device. Returns nonzero on failure.
242 The transfer may complete asynchronously. */
243 static int scsi_write_data(SCSIDevice
*d
, uint32_t tag
)
245 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, d
);
248 DPRINTF("Write data tag=0x%x\n", tag
);
249 r
= scsi_find_request(s
, tag
);
251 BADF("Bad write tag 0x%x\n", tag
);
252 scsi_command_complete(r
, CHECK_CONDITION
, HARDWARE_ERROR
);
257 BADF("Data transfer already in progress\n");
259 scsi_write_request(r
);
264 static void scsi_dma_restart_bh(void *opaque
)
266 SCSIDiskState
*s
= opaque
;
270 qemu_bh_delete(s
->bh
);
273 QTAILQ_FOREACH(req
, &s
->qdev
.requests
, next
) {
274 r
= DO_UPCAST(SCSIDiskReq
, req
, req
);
275 if (r
->status
& SCSI_REQ_STATUS_RETRY
) {
276 r
->status
&= ~SCSI_REQ_STATUS_RETRY
;
277 scsi_write_request(r
);
282 static void scsi_dma_restart_cb(void *opaque
, int running
, int reason
)
284 SCSIDiskState
*s
= opaque
;
290 s
->bh
= qemu_bh_new(scsi_dma_restart_bh
, s
);
291 qemu_bh_schedule(s
->bh
);
295 /* Return a pointer to the data buffer. */
296 static uint8_t *scsi_get_buf(SCSIDevice
*d
, uint32_t tag
)
298 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, d
);
301 r
= scsi_find_request(s
, tag
);
303 BADF("Bad buffer tag 0x%x\n", tag
);
306 return (uint8_t *)r
->iov
.iov_base
;
309 static int scsi_disk_emulate_inquiry(SCSIRequest
*req
, uint8_t *outbuf
)
311 BlockDriverState
*bdrv
= req
->dev
->dinfo
->bdrv
;
314 if (req
->cmd
.buf
[1] & 0x2) {
315 /* Command support data - optional, not implemented */
316 BADF("optional INQUIRY command support request not implemented\n");
320 if (req
->cmd
.buf
[1] & 0x1) {
321 /* Vital product data */
322 uint8_t page_code
= req
->cmd
.buf
[2];
323 if (req
->cmd
.xfer
< 4) {
324 BADF("Error: Inquiry (EVPD[%02X]) buffer size %zd is "
325 "less than 4\n", page_code
, req
->cmd
.xfer
);
329 if (bdrv_get_type_hint(bdrv
) == BDRV_TYPE_CDROM
) {
330 outbuf
[buflen
++] = 5;
332 outbuf
[buflen
++] = 0;
334 outbuf
[buflen
++] = page_code
; // this page
335 outbuf
[buflen
++] = 0x00;
338 case 0x00: /* Supported page codes, mandatory */
339 DPRINTF("Inquiry EVPD[Supported pages] "
340 "buffer size %zd\n", req
->cmd
.xfer
);
341 outbuf
[buflen
++] = 3; // number of pages
342 outbuf
[buflen
++] = 0x00; // list of supported pages (this page)
343 outbuf
[buflen
++] = 0x80; // unit serial number
344 outbuf
[buflen
++] = 0x83; // device identification
347 case 0x80: /* Device serial number, optional */
349 const char *serial
= req
->dev
->dinfo
->serial
?
350 req
->dev
->dinfo
->serial
: "0";
351 int l
= strlen(serial
);
353 if (l
> req
->cmd
.xfer
)
358 DPRINTF("Inquiry EVPD[Serial number] "
359 "buffer size %zd\n", req
->cmd
.xfer
);
360 outbuf
[buflen
++] = l
;
361 memcpy(outbuf
+buflen
, serial
, l
);
366 case 0x83: /* Device identification page, mandatory */
368 int max_len
= 255 - 8;
369 int id_len
= strlen(bdrv_get_device_name(bdrv
));
371 if (id_len
> max_len
)
373 DPRINTF("Inquiry EVPD[Device identification] "
374 "buffer size %zd\n", req
->cmd
.xfer
);
376 outbuf
[buflen
++] = 3 + id_len
;
377 outbuf
[buflen
++] = 0x2; // ASCII
378 outbuf
[buflen
++] = 0; // not officially assigned
379 outbuf
[buflen
++] = 0; // reserved
380 outbuf
[buflen
++] = id_len
; // length of data following
382 memcpy(outbuf
+buflen
, bdrv_get_device_name(bdrv
), id_len
);
387 BADF("Error: unsupported Inquiry (EVPD[%02X]) "
388 "buffer size %zd\n", page_code
, req
->cmd
.xfer
);
395 /* Standard INQUIRY data */
396 if (req
->cmd
.buf
[2] != 0) {
397 BADF("Error: Inquiry (STANDARD) page or code "
398 "is non-zero [%02X]\n", req
->cmd
.buf
[2]);
403 if (req
->cmd
.xfer
< 5) {
404 BADF("Error: Inquiry (STANDARD) buffer size %zd "
405 "is less than 5\n", req
->cmd
.xfer
);
409 if (req
->cmd
.xfer
< 36) {
410 BADF("Error: Inquiry (STANDARD) buffer size %zd "
411 "is less than 36 (TODO: only 5 required)\n", req
->cmd
.xfer
);
414 buflen
= req
->cmd
.xfer
;
415 if (buflen
> SCSI_MAX_INQUIRY_LEN
)
416 buflen
= SCSI_MAX_INQUIRY_LEN
;
418 memset(outbuf
, 0, buflen
);
420 if (req
->lun
|| req
->cmd
.buf
[1] >> 5) {
421 outbuf
[0] = 0x7f; /* LUN not supported */
425 if (bdrv_get_type_hint(bdrv
) == BDRV_TYPE_CDROM
) {
428 memcpy(&outbuf
[16], "QEMU CD-ROM ", 16);
431 memcpy(&outbuf
[16], "QEMU HARDDISK ", 16);
433 memcpy(&outbuf
[8], "QEMU ", 8);
434 memcpy(&outbuf
[32], QEMU_VERSION
, 4);
435 /* Identify device as SCSI-3 rev 1.
436 Some later commands are also implemented. */
438 outbuf
[3] = 2; /* Format 2 */
439 outbuf
[4] = buflen
- 5; /* Additional Length = (Len - 1) - 4 */
440 /* Sync data transfer and TCQ. */
441 outbuf
[7] = 0x10 | (req
->bus
->tcq
? 0x02 : 0);
445 static int mode_sense_page(SCSIRequest
*req
, int page
, uint8_t *p
)
447 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, req
->dev
);
448 BlockDriverState
*bdrv
= req
->dev
->dinfo
->bdrv
;
449 int cylinders
, heads
, secs
;
452 case 4: /* Rigid disk device geometry page. */
455 /* if a geometry hint is available, use it */
456 bdrv_get_geometry_hint(bdrv
, &cylinders
, &heads
, &secs
);
457 p
[2] = (cylinders
>> 16) & 0xff;
458 p
[3] = (cylinders
>> 8) & 0xff;
459 p
[4] = cylinders
& 0xff;
461 /* Write precomp start cylinder, disabled */
462 p
[6] = (cylinders
>> 16) & 0xff;
463 p
[7] = (cylinders
>> 8) & 0xff;
464 p
[8] = cylinders
& 0xff;
465 /* Reduced current start cylinder, disabled */
466 p
[9] = (cylinders
>> 16) & 0xff;
467 p
[10] = (cylinders
>> 8) & 0xff;
468 p
[11] = cylinders
& 0xff;
469 /* Device step rate [ns], 200ns */
472 /* Landing zone cylinder */
476 /* Medium rotation rate [rpm], 5400 rpm */
477 p
[20] = (5400 >> 8) & 0xff;
481 case 5: /* Flexible disk device geometry page. */
484 /* Transfer rate [kbit/s], 5Mbit/s */
487 /* if a geometry hint is available, use it */
488 bdrv_get_geometry_hint(bdrv
, &cylinders
, &heads
, &secs
);
491 p
[6] = s
->cluster_size
* 2;
492 p
[8] = (cylinders
>> 8) & 0xff;
493 p
[9] = cylinders
& 0xff;
494 /* Write precomp start cylinder, disabled */
495 p
[10] = (cylinders
>> 8) & 0xff;
496 p
[11] = cylinders
& 0xff;
497 /* Reduced current start cylinder, disabled */
498 p
[12] = (cylinders
>> 8) & 0xff;
499 p
[13] = cylinders
& 0xff;
500 /* Device step rate [100us], 100us */
503 /* Device step pulse width [us], 1us */
505 /* Device head settle delay [100us], 100us */
508 /* Motor on delay [0.1s], 0.1s */
510 /* Motor off delay [0.1s], 0.1s */
512 /* Medium rotation rate [rpm], 5400 rpm */
513 p
[28] = (5400 >> 8) & 0xff;
517 case 8: /* Caching page. */
520 if (bdrv_enable_write_cache(s
->qdev
.dinfo
->bdrv
)) {
525 case 0x2a: /* CD Capabilities and Mechanical Status page. */
526 if (bdrv_get_type_hint(bdrv
) != BDRV_TYPE_CDROM
)
530 p
[2] = 3; // CD-R & CD-RW read
531 p
[3] = 0; // Writing not supported
532 p
[4] = 0x7f; /* Audio, composite, digital out,
533 mode 2 form 1&2, multi session */
534 p
[5] = 0xff; /* CD DA, DA accurate, RW supported,
535 RW corrected, C2 errors, ISRC,
537 p
[6] = 0x2d | (bdrv_is_locked(s
->qdev
.dinfo
->bdrv
)? 2 : 0);
538 /* Locking supported, jumper present, eject, tray */
539 p
[7] = 0; /* no volume & mute control, no
541 p
[8] = (50 * 176) >> 8; // 50x read speed
542 p
[9] = (50 * 176) & 0xff;
543 p
[10] = 0 >> 8; // No volume
545 p
[12] = 2048 >> 8; // 2M buffer
547 p
[14] = (16 * 176) >> 8; // 16x read speed current
548 p
[15] = (16 * 176) & 0xff;
549 p
[18] = (16 * 176) >> 8; // 16x write speed
550 p
[19] = (16 * 176) & 0xff;
551 p
[20] = (16 * 176) >> 8; // 16x write speed current
552 p
[21] = (16 * 176) & 0xff;
560 static int scsi_disk_emulate_mode_sense(SCSIRequest
*req
, uint8_t *outbuf
)
562 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, req
->dev
);
563 BlockDriverState
*bdrv
= req
->dev
->dinfo
->bdrv
;
565 int page
, dbd
, buflen
;
568 dbd
= req
->cmd
.buf
[1] & 0x8;
569 page
= req
->cmd
.buf
[2] & 0x3f;
570 DPRINTF("Mode Sense (page %d, len %zd)\n", page
, req
->cmd
.xfer
);
571 memset(outbuf
, 0, req
->cmd
.xfer
);
574 p
[1] = 0; /* Default media type. */
575 p
[3] = 0; /* Block descriptor length. */
576 if (bdrv_get_type_hint(bdrv
) == BDRV_TYPE_CDROM
||
577 bdrv_is_read_only(bdrv
)) {
578 p
[2] = 0x80; /* Readonly. */
582 bdrv_get_geometry(bdrv
, &nb_sectors
);
583 if ((~dbd
) & nb_sectors
) {
584 outbuf
[3] = 8; /* Block descriptor length */
585 nb_sectors
/= s
->cluster_size
;
587 if (nb_sectors
> 0xffffff)
588 nb_sectors
= 0xffffff;
589 p
[0] = 0; /* media density code */
590 p
[1] = (nb_sectors
>> 16) & 0xff;
591 p
[2] = (nb_sectors
>> 8) & 0xff;
592 p
[3] = nb_sectors
& 0xff;
593 p
[4] = 0; /* reserved */
594 p
[5] = 0; /* bytes 5-7 are the sector size in bytes */
595 p
[6] = s
->cluster_size
* 2;
605 p
+= mode_sense_page(req
, page
, p
);
608 p
+= mode_sense_page(req
, 0x08, p
);
609 p
+= mode_sense_page(req
, 0x2a, p
);
614 outbuf
[0] = buflen
- 4;
615 if (buflen
> req
->cmd
.xfer
)
616 buflen
= req
->cmd
.xfer
;
620 static int scsi_disk_emulate_read_toc(SCSIRequest
*req
, uint8_t *outbuf
)
622 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, req
->dev
);
623 BlockDriverState
*bdrv
= req
->dev
->dinfo
->bdrv
;
624 int start_track
, format
, msf
, toclen
;
627 msf
= req
->cmd
.buf
[1] & 2;
628 format
= req
->cmd
.buf
[2] & 0xf;
629 start_track
= req
->cmd
.buf
[6];
630 bdrv_get_geometry(bdrv
, &nb_sectors
);
631 DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track
, format
, msf
>> 1);
632 nb_sectors
/= s
->cluster_size
;
635 toclen
= cdrom_read_toc(nb_sectors
, outbuf
, msf
, start_track
);
638 /* multi session : only a single session defined */
640 memset(outbuf
, 0, 12);
646 toclen
= cdrom_read_toc_raw(nb_sectors
, outbuf
, msf
, start_track
);
651 if (toclen
> req
->cmd
.xfer
)
652 toclen
= req
->cmd
.xfer
;
656 static int scsi_disk_emulate_command(SCSIRequest
*req
, uint8_t *outbuf
)
658 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, req
->dev
);
659 BlockDriverState
*bdrv
= req
->dev
->dinfo
->bdrv
;
663 switch (req
->cmd
.buf
[0]) {
664 case TEST_UNIT_READY
:
665 if (!bdrv_is_inserted(bdrv
))
669 if (req
->cmd
.xfer
< 4)
670 goto illegal_request
;
671 memset(outbuf
, 0, 4);
673 if (req
->dev
->sense
.key
== NOT_READY
&& req
->cmd
.xfer
>= 18) {
674 memset(outbuf
, 0, 18);
677 /* asc 0x3a, ascq 0: Medium not present */
683 outbuf
[2] = req
->dev
->sense
.key
;
684 scsi_dev_clear_sense(req
->dev
);
687 buflen
= scsi_disk_emulate_inquiry(req
, outbuf
);
689 goto illegal_request
;
693 buflen
= scsi_disk_emulate_mode_sense(req
, outbuf
);
695 goto illegal_request
;
698 buflen
= scsi_disk_emulate_read_toc(req
, outbuf
);
700 goto illegal_request
;
703 if (req
->cmd
.buf
[1] & 1)
704 goto illegal_request
;
707 if (req
->cmd
.buf
[1] & 3)
708 goto illegal_request
;
711 if (req
->cmd
.buf
[1] & 1)
712 goto illegal_request
;
715 if (req
->cmd
.buf
[1] & 3)
716 goto illegal_request
;
719 if (bdrv_get_type_hint(bdrv
) == BDRV_TYPE_CDROM
&& (req
->cmd
.buf
[4] & 2)) {
720 /* load/eject medium */
721 bdrv_eject(bdrv
, !(req
->cmd
.buf
[4] & 1));
724 case ALLOW_MEDIUM_REMOVAL
:
725 bdrv_set_locked(bdrv
, req
->cmd
.buf
[4] & 1);
728 /* The normal LEN field for this command is zero. */
729 memset(outbuf
, 0, 8);
730 bdrv_get_geometry(bdrv
, &nb_sectors
);
733 nb_sectors
/= s
->cluster_size
;
734 /* Returned value is the address of the last sector. */
736 /* Remember the new size for read/write sanity checking. */
737 s
->max_lba
= nb_sectors
;
738 /* Clip to 2TB, instead of returning capacity modulo 2TB. */
739 if (nb_sectors
> UINT32_MAX
)
740 nb_sectors
= UINT32_MAX
;
741 outbuf
[0] = (nb_sectors
>> 24) & 0xff;
742 outbuf
[1] = (nb_sectors
>> 16) & 0xff;
743 outbuf
[2] = (nb_sectors
>> 8) & 0xff;
744 outbuf
[3] = nb_sectors
& 0xff;
747 outbuf
[6] = s
->cluster_size
* 2;
751 case SYNCHRONIZE_CACHE
:
754 case GET_CONFIGURATION
:
755 memset(outbuf
, 0, 8);
756 /* ??? This should probably return much more information. For now
757 just return the basic header indicating the CD-ROM profile. */
758 outbuf
[7] = 8; // CD-ROM
761 case SERVICE_ACTION_IN
:
762 /* Service Action In subcommands. */
763 if ((req
->cmd
.buf
[1] & 31) == 0x10) {
764 DPRINTF("SAI READ CAPACITY(16)\n");
765 memset(outbuf
, 0, req
->cmd
.xfer
);
766 bdrv_get_geometry(bdrv
, &nb_sectors
);
769 nb_sectors
/= s
->cluster_size
;
770 /* Returned value is the address of the last sector. */
772 /* Remember the new size for read/write sanity checking. */
773 s
->max_lba
= nb_sectors
;
774 outbuf
[0] = (nb_sectors
>> 56) & 0xff;
775 outbuf
[1] = (nb_sectors
>> 48) & 0xff;
776 outbuf
[2] = (nb_sectors
>> 40) & 0xff;
777 outbuf
[3] = (nb_sectors
>> 32) & 0xff;
778 outbuf
[4] = (nb_sectors
>> 24) & 0xff;
779 outbuf
[5] = (nb_sectors
>> 16) & 0xff;
780 outbuf
[6] = (nb_sectors
>> 8) & 0xff;
781 outbuf
[7] = nb_sectors
& 0xff;
784 outbuf
[10] = s
->cluster_size
* 2;
786 /* Protection, exponent and lowest lba field left blank. */
787 buflen
= req
->cmd
.xfer
;
790 DPRINTF("Unsupported Service Action In\n");
791 goto illegal_request
;
793 if (req
->cmd
.xfer
< 16)
794 goto illegal_request
;
795 memset(outbuf
, 0, 16);
802 goto illegal_request
;
804 scsi_req_set_status(req
, GOOD
, NO_SENSE
);
808 scsi_req_set_status(req
, CHECK_CONDITION
, NOT_READY
);
812 scsi_req_set_status(req
, CHECK_CONDITION
, ILLEGAL_REQUEST
);
816 /* Execute a scsi command. Returns the length of the data expected by the
817 command. This will be Positive for data transfers from the device
818 (eg. disk reads), negative for transfers to the device (eg. disk writes),
819 and zero if the command does not transfer any data. */
821 static int32_t scsi_send_command(SCSIDevice
*d
, uint32_t tag
,
822 uint8_t *buf
, int lun
)
824 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, d
);
835 r
= scsi_find_request(s
, tag
);
837 BADF("Tag 0x%x already in use\n", tag
);
838 scsi_cancel_io(d
, tag
);
840 /* ??? Tags are not unique for different luns. We only implement a
841 single lun, so this should not matter. */
842 r
= scsi_new_request(d
, tag
, lun
);
843 outbuf
= (uint8_t *)r
->iov
.iov_base
;
845 DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun
, tag
, buf
[0]);
846 switch (command
>> 5) {
848 lba
= (uint64_t) buf
[3] | ((uint64_t) buf
[2] << 8) |
849 (((uint64_t) buf
[1] & 0x1f) << 16);
855 lba
= (uint64_t) buf
[5] | ((uint64_t) buf
[4] << 8) |
856 ((uint64_t) buf
[3] << 16) | ((uint64_t) buf
[2] << 24);
857 len
= buf
[8] | (buf
[7] << 8);
861 lba
= (uint64_t) buf
[9] | ((uint64_t) buf
[8] << 8) |
862 ((uint64_t) buf
[7] << 16) | ((uint64_t) buf
[6] << 24) |
863 ((uint64_t) buf
[5] << 32) | ((uint64_t) buf
[4] << 40) |
864 ((uint64_t) buf
[3] << 48) | ((uint64_t) buf
[2] << 56);
865 len
= buf
[13] | (buf
[12] << 8) | (buf
[11] << 16) | (buf
[10] << 24);
869 lba
= (uint64_t) buf
[5] | ((uint64_t) buf
[4] << 8) |
870 ((uint64_t) buf
[3] << 16) | ((uint64_t) buf
[2] << 24);
871 len
= buf
[9] | (buf
[8] << 8) | (buf
[7] << 16) | (buf
[6] << 24);
875 BADF("Unsupported command length, command %x\n", command
);
881 for (i
= 1; i
< cmdlen
; i
++) {
882 printf(" 0x%02x", buf
[i
]);
888 if (scsi_req_parse(&r
->req
, buf
) != 0) {
889 BADF("Unsupported command length, command %x\n", command
);
892 assert(r
->req
.cmd
.len
== cmdlen
);
893 assert(r
->req
.cmd
.lba
== lba
);
895 if (lun
|| buf
[1] >> 5) {
896 /* Only LUN 0 supported. */
897 DPRINTF("Unimplemented LUN %d\n", lun
? lun
: buf
[1] >> 5);
898 if (command
!= REQUEST_SENSE
&& command
!= INQUIRY
)
902 case TEST_UNIT_READY
:
912 case ALLOW_MEDIUM_REMOVAL
:
914 case SYNCHRONIZE_CACHE
:
916 case GET_CONFIGURATION
:
917 case SERVICE_ACTION_IN
:
920 rc
= scsi_disk_emulate_command(&r
->req
, outbuf
);
924 scsi_req_complete(&r
->req
);
925 scsi_remove_request(r
);
933 DPRINTF("Read (sector %" PRId64
", count %d)\n", lba
, len
);
934 if (lba
> s
->max_lba
)
936 r
->sector
= lba
* s
->cluster_size
;
937 r
->sector_count
= len
* s
->cluster_size
;
943 DPRINTF("Write (sector %" PRId64
", count %d)\n", lba
, len
);
944 if (lba
> s
->max_lba
)
946 r
->sector
= lba
* s
->cluster_size
;
947 r
->sector_count
= len
* s
->cluster_size
;
951 DPRINTF("Unknown SCSI command (%2.2x)\n", buf
[0]);
953 scsi_command_complete(r
, CHECK_CONDITION
, ILLEGAL_REQUEST
);
956 scsi_command_complete(r
, CHECK_CONDITION
, HARDWARE_ERROR
);
959 if (r
->sector_count
== 0 && r
->iov
.iov_len
== 0) {
960 scsi_command_complete(r
, GOOD
, NO_SENSE
);
962 len
= r
->sector_count
* 512 + r
->iov
.iov_len
;
966 if (!r
->sector_count
)
967 r
->sector_count
= -1;
972 static void scsi_destroy(SCSIDevice
*dev
)
974 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, dev
);
977 while (!QTAILQ_EMPTY(&s
->qdev
.requests
)) {
978 r
= DO_UPCAST(SCSIDiskReq
, req
, QTAILQ_FIRST(&s
->qdev
.requests
));
979 scsi_remove_request(r
);
981 drive_uninit(s
->qdev
.dinfo
);
984 static int scsi_disk_initfn(SCSIDevice
*dev
)
986 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, dev
);
989 if (!s
->qdev
.dinfo
|| !s
->qdev
.dinfo
->bdrv
) {
990 qemu_error("scsi-disk: drive property not set\n");
994 if (bdrv_get_type_hint(s
->qdev
.dinfo
->bdrv
) == BDRV_TYPE_CDROM
) {
999 s
->qdev
.blocksize
= 512 * s
->cluster_size
;
1000 s
->qdev
.type
= TYPE_DISK
;
1001 bdrv_get_geometry(s
->qdev
.dinfo
->bdrv
, &nb_sectors
);
1002 nb_sectors
/= s
->cluster_size
;
1005 s
->max_lba
= nb_sectors
;
1006 qemu_add_vm_change_state_handler(scsi_dma_restart_cb
, s
);
1010 static SCSIDeviceInfo scsi_disk_info
= {
1011 .qdev
.name
= "scsi-disk",
1012 .qdev
.desc
= "virtual scsi disk or cdrom",
1013 .qdev
.size
= sizeof(SCSIDiskState
),
1014 .init
= scsi_disk_initfn
,
1015 .destroy
= scsi_destroy
,
1016 .send_command
= scsi_send_command
,
1017 .read_data
= scsi_read_data
,
1018 .write_data
= scsi_write_data
,
1019 .cancel_io
= scsi_cancel_io
,
1020 .get_buf
= scsi_get_buf
,
1021 .qdev
.props
= (Property
[]) {
1022 DEFINE_PROP_DRIVE("drive", SCSIDiskState
, qdev
.dinfo
),
1023 DEFINE_PROP_END_OF_LIST(),
1027 static void scsi_disk_register_devices(void)
1029 scsi_qdev_register(&scsi_disk_info
);
1031 device_init(scsi_disk_register_devices
)