2 * SCSI Device emulation
4 * Copyright (c) 2006 CodeSourcery.
5 * Based on code by Fabrice Bellard
7 * Written by Paul Brook
9 * 2009-Dec-12 Artyom Tarasenko : implemented stamdard inquiry for the case
10 * when the allocation length of CDB is smaller
12 * 2009-Oct-13 Artyom Tarasenko : implemented the block descriptor in the
13 * MODE SENSE response.
15 * This code is licenced under the LGPL.
17 * Note that this file only handles the SCSI architecture model and device
18 * commands. Emulation of interface/link layer protocols is handled by
19 * the host adapter emulator.
22 #include <qemu-common.h>
27 #define DPRINTF(fmt, ...) \
28 do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
30 #define DPRINTF(fmt, ...) do {} while(0)
33 #define BADF(fmt, ...) \
34 do { fprintf(stderr, "scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
36 #include "qemu-common.h"
39 #include "scsi-defs.h"
41 #define SCSI_DMA_BUF_SIZE 131072
42 #define SCSI_MAX_INQUIRY_LEN 256
44 #define SCSI_REQ_STATUS_RETRY 0x01
46 typedef struct SCSIDiskState SCSIDiskState
;
48 typedef struct SCSIDiskReq
{
50 /* ??? We should probably keep track of whether the data transfer is
51 a read or a write. Currently we rely on the host getting it right. */
52 /* Both sector and sector_count are in terms of qemu 512 byte blocks. */
54 uint32_t sector_count
;
63 /* The qemu block layer uses a fixed 512 byte sector size.
64 This is the number of 512 byte blocks in a single scsi sector. */
71 static SCSIDiskReq
*scsi_new_request(SCSIDevice
*d
, uint32_t tag
, uint32_t lun
)
76 req
= scsi_req_alloc(sizeof(SCSIDiskReq
), d
, tag
, lun
);
77 r
= DO_UPCAST(SCSIDiskReq
, req
, req
);
78 r
->iov
.iov_base
= qemu_memalign(512, SCSI_DMA_BUF_SIZE
);
82 static void scsi_remove_request(SCSIDiskReq
*r
)
84 qemu_free(r
->iov
.iov_base
);
85 scsi_req_free(&r
->req
);
88 static SCSIDiskReq
*scsi_find_request(SCSIDiskState
*s
, uint32_t tag
)
90 return DO_UPCAST(SCSIDiskReq
, req
, scsi_req_find(&s
->qdev
, tag
));
93 static void scsi_req_set_status(SCSIRequest
*req
, int status
, int sense_code
)
96 scsi_dev_set_sense(req
->dev
, sense_code
);
99 /* Helper function for command completion. */
100 static void scsi_command_complete(SCSIDiskReq
*r
, int status
, int sense
)
102 DPRINTF("Command complete tag=0x%x status=%d sense=%d\n",
103 r
->req
.tag
, status
, sense
);
104 scsi_req_set_status(&r
->req
, status
, sense
);
105 scsi_req_complete(&r
->req
);
106 scsi_remove_request(r
);
109 /* Cancel a pending data transfer. */
110 static void scsi_cancel_io(SCSIDevice
*d
, uint32_t tag
)
112 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, d
);
114 DPRINTF("Cancel tag=0x%x\n", tag
);
115 r
= scsi_find_request(s
, tag
);
118 bdrv_aio_cancel(r
->req
.aiocb
);
120 scsi_remove_request(r
);
124 static void scsi_read_complete(void * opaque
, int ret
)
126 SCSIDiskReq
*r
= (SCSIDiskReq
*)opaque
;
129 DPRINTF("IO error\n");
130 r
->req
.bus
->complete(r
->req
.bus
, SCSI_REASON_DATA
, r
->req
.tag
, 0);
131 scsi_command_complete(r
, CHECK_CONDITION
, NO_SENSE
);
134 DPRINTF("Data ready tag=0x%x len=%" PRId64
"\n", r
->req
.tag
, r
->iov
.iov_len
);
136 r
->req
.bus
->complete(r
->req
.bus
, SCSI_REASON_DATA
, r
->req
.tag
, r
->iov
.iov_len
);
139 /* Read more data from scsi device into buffer. */
140 static void scsi_read_data(SCSIDevice
*d
, uint32_t tag
)
142 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, d
);
146 r
= scsi_find_request(s
, tag
);
148 BADF("Bad read tag 0x%x\n", tag
);
149 /* ??? This is the wrong error. */
150 scsi_command_complete(r
, CHECK_CONDITION
, HARDWARE_ERROR
);
153 if (r
->sector_count
== (uint32_t)-1) {
154 DPRINTF("Read buf_len=%" PRId64
"\n", r
->iov
.iov_len
);
156 r
->req
.bus
->complete(r
->req
.bus
, SCSI_REASON_DATA
, r
->req
.tag
, r
->iov
.iov_len
);
159 DPRINTF("Read sector_count=%d\n", r
->sector_count
);
160 if (r
->sector_count
== 0) {
161 scsi_command_complete(r
, GOOD
, NO_SENSE
);
166 if (n
> SCSI_DMA_BUF_SIZE
/ 512)
167 n
= SCSI_DMA_BUF_SIZE
/ 512;
169 r
->iov
.iov_len
= n
* 512;
170 qemu_iovec_init_external(&r
->qiov
, &r
->iov
, 1);
171 r
->req
.aiocb
= bdrv_aio_readv(s
->qdev
.dinfo
->bdrv
, r
->sector
, &r
->qiov
, n
,
172 scsi_read_complete
, r
);
173 if (r
->req
.aiocb
== NULL
)
174 scsi_command_complete(r
, CHECK_CONDITION
, HARDWARE_ERROR
);
176 r
->sector_count
-= n
;
179 static int scsi_handle_write_error(SCSIDiskReq
*r
, int error
)
181 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, r
->req
.dev
);
182 BlockInterfaceErrorAction action
=
183 drive_get_on_error(s
->qdev
.dinfo
->bdrv
, 0);
185 if (action
== BLOCK_ERR_IGNORE
)
188 if ((error
== ENOSPC
&& action
== BLOCK_ERR_STOP_ENOSPC
)
189 || action
== BLOCK_ERR_STOP_ANY
) {
190 r
->status
|= SCSI_REQ_STATUS_RETRY
;
193 scsi_command_complete(r
, CHECK_CONDITION
,
200 static void scsi_write_complete(void * opaque
, int ret
)
202 SCSIDiskReq
*r
= (SCSIDiskReq
*)opaque
;
209 if (scsi_handle_write_error(r
, -ret
))
213 n
= r
->iov
.iov_len
/ 512;
215 r
->sector_count
-= n
;
216 if (r
->sector_count
== 0) {
217 scsi_command_complete(r
, GOOD
, NO_SENSE
);
219 len
= r
->sector_count
* 512;
220 if (len
> SCSI_DMA_BUF_SIZE
) {
221 len
= SCSI_DMA_BUF_SIZE
;
223 r
->iov
.iov_len
= len
;
224 DPRINTF("Write complete tag=0x%x more=%d\n", r
->req
.tag
, len
);
225 r
->req
.bus
->complete(r
->req
.bus
, SCSI_REASON_DATA
, r
->req
.tag
, len
);
229 static void scsi_write_request(SCSIDiskReq
*r
)
231 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, r
->req
.dev
);
234 n
= r
->iov
.iov_len
/ 512;
236 qemu_iovec_init_external(&r
->qiov
, &r
->iov
, 1);
237 r
->req
.aiocb
= bdrv_aio_writev(s
->qdev
.dinfo
->bdrv
, r
->sector
, &r
->qiov
, n
,
238 scsi_write_complete
, r
);
239 if (r
->req
.aiocb
== NULL
)
240 scsi_command_complete(r
, CHECK_CONDITION
,
243 /* Invoke completion routine to fetch data from host. */
244 scsi_write_complete(r
, 0);
248 /* Write data to a scsi device. Returns nonzero on failure.
249 The transfer may complete asynchronously. */
250 static int scsi_write_data(SCSIDevice
*d
, uint32_t tag
)
252 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, d
);
255 DPRINTF("Write data tag=0x%x\n", tag
);
256 r
= scsi_find_request(s
, tag
);
258 BADF("Bad write tag 0x%x\n", tag
);
259 scsi_command_complete(r
, CHECK_CONDITION
, HARDWARE_ERROR
);
264 BADF("Data transfer already in progress\n");
266 scsi_write_request(r
);
271 static void scsi_dma_restart_bh(void *opaque
)
273 SCSIDiskState
*s
= opaque
;
277 qemu_bh_delete(s
->bh
);
280 QTAILQ_FOREACH(req
, &s
->qdev
.requests
, next
) {
281 r
= DO_UPCAST(SCSIDiskReq
, req
, req
);
282 if (r
->status
& SCSI_REQ_STATUS_RETRY
) {
283 r
->status
&= ~SCSI_REQ_STATUS_RETRY
;
284 scsi_write_request(r
);
289 static void scsi_dma_restart_cb(void *opaque
, int running
, int reason
)
291 SCSIDiskState
*s
= opaque
;
297 s
->bh
= qemu_bh_new(scsi_dma_restart_bh
, s
);
298 qemu_bh_schedule(s
->bh
);
302 /* Return a pointer to the data buffer. */
303 static uint8_t *scsi_get_buf(SCSIDevice
*d
, uint32_t tag
)
305 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, d
);
308 r
= scsi_find_request(s
, tag
);
310 BADF("Bad buffer tag 0x%x\n", tag
);
313 return (uint8_t *)r
->iov
.iov_base
;
316 static int scsi_disk_emulate_inquiry(SCSIRequest
*req
, uint8_t *outbuf
)
318 BlockDriverState
*bdrv
= req
->dev
->dinfo
->bdrv
;
319 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, req
->dev
);
322 if (req
->cmd
.buf
[1] & 0x2) {
323 /* Command support data - optional, not implemented */
324 BADF("optional INQUIRY command support request not implemented\n");
328 if (req
->cmd
.buf
[1] & 0x1) {
329 /* Vital product data */
330 uint8_t page_code
= req
->cmd
.buf
[2];
331 if (req
->cmd
.xfer
< 4) {
332 BADF("Error: Inquiry (EVPD[%02X]) buffer size %zd is "
333 "less than 4\n", page_code
, req
->cmd
.xfer
);
337 if (bdrv_get_type_hint(bdrv
) == BDRV_TYPE_CDROM
) {
338 outbuf
[buflen
++] = 5;
340 outbuf
[buflen
++] = 0;
342 outbuf
[buflen
++] = page_code
; // this page
343 outbuf
[buflen
++] = 0x00;
346 case 0x00: /* Supported page codes, mandatory */
347 DPRINTF("Inquiry EVPD[Supported pages] "
348 "buffer size %zd\n", req
->cmd
.xfer
);
349 outbuf
[buflen
++] = 3; // number of pages
350 outbuf
[buflen
++] = 0x00; // list of supported pages (this page)
351 outbuf
[buflen
++] = 0x80; // unit serial number
352 outbuf
[buflen
++] = 0x83; // device identification
355 case 0x80: /* Device serial number, optional */
357 const char *serial
= req
->dev
->dinfo
->serial
?
358 req
->dev
->dinfo
->serial
: "0";
359 int l
= strlen(serial
);
361 if (l
> req
->cmd
.xfer
)
366 DPRINTF("Inquiry EVPD[Serial number] "
367 "buffer size %zd\n", req
->cmd
.xfer
);
368 outbuf
[buflen
++] = l
;
369 memcpy(outbuf
+buflen
, serial
, l
);
374 case 0x83: /* Device identification page, mandatory */
376 int max_len
= 255 - 8;
377 int id_len
= strlen(bdrv_get_device_name(bdrv
));
379 if (id_len
> max_len
)
381 DPRINTF("Inquiry EVPD[Device identification] "
382 "buffer size %zd\n", req
->cmd
.xfer
);
384 outbuf
[buflen
++] = 3 + id_len
;
385 outbuf
[buflen
++] = 0x2; // ASCII
386 outbuf
[buflen
++] = 0; // not officially assigned
387 outbuf
[buflen
++] = 0; // reserved
388 outbuf
[buflen
++] = id_len
; // length of data following
390 memcpy(outbuf
+buflen
, bdrv_get_device_name(bdrv
), id_len
);
395 BADF("Error: unsupported Inquiry (EVPD[%02X]) "
396 "buffer size %zd\n", page_code
, req
->cmd
.xfer
);
403 /* Standard INQUIRY data */
404 if (req
->cmd
.buf
[2] != 0) {
405 BADF("Error: Inquiry (STANDARD) page or code "
406 "is non-zero [%02X]\n", req
->cmd
.buf
[2]);
411 if (req
->cmd
.xfer
< 5) {
412 BADF("Error: Inquiry (STANDARD) buffer size %zd "
413 "is less than 5\n", req
->cmd
.xfer
);
417 buflen
= req
->cmd
.xfer
;
418 if (buflen
> SCSI_MAX_INQUIRY_LEN
)
419 buflen
= SCSI_MAX_INQUIRY_LEN
;
421 memset(outbuf
, 0, buflen
);
423 if (req
->lun
|| req
->cmd
.buf
[1] >> 5) {
424 outbuf
[0] = 0x7f; /* LUN not supported */
428 if (bdrv_get_type_hint(bdrv
) == BDRV_TYPE_CDROM
) {
431 memcpy(&outbuf
[16], "QEMU CD-ROM ", 16);
434 memcpy(&outbuf
[16], "QEMU HARDDISK ", 16);
436 memcpy(&outbuf
[8], "QEMU ", 8);
437 memcpy(&outbuf
[32], s
->version
? s
->version
: QEMU_VERSION
, 4);
438 /* Identify device as SCSI-3 rev 1.
439 Some later commands are also implemented. */
441 outbuf
[3] = 2; /* Format 2 */
444 outbuf
[4] = buflen
- 5; /* Additional Length = (Len - 1) - 4 */
446 /* If the allocation length of CDB is too small,
447 the additional length is not adjusted */
451 /* Sync data transfer and TCQ. */
452 outbuf
[7] = 0x10 | (req
->bus
->tcq
? 0x02 : 0);
456 static int mode_sense_page(SCSIRequest
*req
, int page
, uint8_t *p
)
458 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, req
->dev
);
459 BlockDriverState
*bdrv
= req
->dev
->dinfo
->bdrv
;
460 int cylinders
, heads
, secs
;
463 case 4: /* Rigid disk device geometry page. */
466 /* if a geometry hint is available, use it */
467 bdrv_get_geometry_hint(bdrv
, &cylinders
, &heads
, &secs
);
468 p
[2] = (cylinders
>> 16) & 0xff;
469 p
[3] = (cylinders
>> 8) & 0xff;
470 p
[4] = cylinders
& 0xff;
472 /* Write precomp start cylinder, disabled */
473 p
[6] = (cylinders
>> 16) & 0xff;
474 p
[7] = (cylinders
>> 8) & 0xff;
475 p
[8] = cylinders
& 0xff;
476 /* Reduced current start cylinder, disabled */
477 p
[9] = (cylinders
>> 16) & 0xff;
478 p
[10] = (cylinders
>> 8) & 0xff;
479 p
[11] = cylinders
& 0xff;
480 /* Device step rate [ns], 200ns */
483 /* Landing zone cylinder */
487 /* Medium rotation rate [rpm], 5400 rpm */
488 p
[20] = (5400 >> 8) & 0xff;
492 case 5: /* Flexible disk device geometry page. */
495 /* Transfer rate [kbit/s], 5Mbit/s */
498 /* if a geometry hint is available, use it */
499 bdrv_get_geometry_hint(bdrv
, &cylinders
, &heads
, &secs
);
502 p
[6] = s
->cluster_size
* 2;
503 p
[8] = (cylinders
>> 8) & 0xff;
504 p
[9] = cylinders
& 0xff;
505 /* Write precomp start cylinder, disabled */
506 p
[10] = (cylinders
>> 8) & 0xff;
507 p
[11] = cylinders
& 0xff;
508 /* Reduced current start cylinder, disabled */
509 p
[12] = (cylinders
>> 8) & 0xff;
510 p
[13] = cylinders
& 0xff;
511 /* Device step rate [100us], 100us */
514 /* Device step pulse width [us], 1us */
516 /* Device head settle delay [100us], 100us */
519 /* Motor on delay [0.1s], 0.1s */
521 /* Motor off delay [0.1s], 0.1s */
523 /* Medium rotation rate [rpm], 5400 rpm */
524 p
[28] = (5400 >> 8) & 0xff;
528 case 8: /* Caching page. */
531 if (bdrv_enable_write_cache(s
->qdev
.dinfo
->bdrv
)) {
536 case 0x2a: /* CD Capabilities and Mechanical Status page. */
537 if (bdrv_get_type_hint(bdrv
) != BDRV_TYPE_CDROM
)
541 p
[2] = 3; // CD-R & CD-RW read
542 p
[3] = 0; // Writing not supported
543 p
[4] = 0x7f; /* Audio, composite, digital out,
544 mode 2 form 1&2, multi session */
545 p
[5] = 0xff; /* CD DA, DA accurate, RW supported,
546 RW corrected, C2 errors, ISRC,
548 p
[6] = 0x2d | (bdrv_is_locked(s
->qdev
.dinfo
->bdrv
)? 2 : 0);
549 /* Locking supported, jumper present, eject, tray */
550 p
[7] = 0; /* no volume & mute control, no
552 p
[8] = (50 * 176) >> 8; // 50x read speed
553 p
[9] = (50 * 176) & 0xff;
554 p
[10] = 0 >> 8; // No volume
556 p
[12] = 2048 >> 8; // 2M buffer
558 p
[14] = (16 * 176) >> 8; // 16x read speed current
559 p
[15] = (16 * 176) & 0xff;
560 p
[18] = (16 * 176) >> 8; // 16x write speed
561 p
[19] = (16 * 176) & 0xff;
562 p
[20] = (16 * 176) >> 8; // 16x write speed current
563 p
[21] = (16 * 176) & 0xff;
571 static int scsi_disk_emulate_mode_sense(SCSIRequest
*req
, uint8_t *outbuf
)
573 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, req
->dev
);
574 BlockDriverState
*bdrv
= req
->dev
->dinfo
->bdrv
;
576 int page
, dbd
, buflen
;
579 dbd
= req
->cmd
.buf
[1] & 0x8;
580 page
= req
->cmd
.buf
[2] & 0x3f;
581 DPRINTF("Mode Sense (page %d, len %zd)\n", page
, req
->cmd
.xfer
);
582 memset(outbuf
, 0, req
->cmd
.xfer
);
585 p
[1] = 0; /* Default media type. */
586 p
[3] = 0; /* Block descriptor length. */
587 if (bdrv_get_type_hint(bdrv
) == BDRV_TYPE_CDROM
||
588 bdrv_is_read_only(bdrv
)) {
589 p
[2] = 0x80; /* Readonly. */
593 bdrv_get_geometry(bdrv
, &nb_sectors
);
594 if ((~dbd
) & nb_sectors
) {
595 outbuf
[3] = 8; /* Block descriptor length */
596 nb_sectors
/= s
->cluster_size
;
598 if (nb_sectors
> 0xffffff)
599 nb_sectors
= 0xffffff;
600 p
[0] = 0; /* media density code */
601 p
[1] = (nb_sectors
>> 16) & 0xff;
602 p
[2] = (nb_sectors
>> 8) & 0xff;
603 p
[3] = nb_sectors
& 0xff;
604 p
[4] = 0; /* reserved */
605 p
[5] = 0; /* bytes 5-7 are the sector size in bytes */
606 p
[6] = s
->cluster_size
* 2;
616 p
+= mode_sense_page(req
, page
, p
);
619 p
+= mode_sense_page(req
, 0x08, p
);
620 p
+= mode_sense_page(req
, 0x2a, p
);
625 outbuf
[0] = buflen
- 4;
626 if (buflen
> req
->cmd
.xfer
)
627 buflen
= req
->cmd
.xfer
;
631 static int scsi_disk_emulate_read_toc(SCSIRequest
*req
, uint8_t *outbuf
)
633 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, req
->dev
);
634 BlockDriverState
*bdrv
= req
->dev
->dinfo
->bdrv
;
635 int start_track
, format
, msf
, toclen
;
638 msf
= req
->cmd
.buf
[1] & 2;
639 format
= req
->cmd
.buf
[2] & 0xf;
640 start_track
= req
->cmd
.buf
[6];
641 bdrv_get_geometry(bdrv
, &nb_sectors
);
642 DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track
, format
, msf
>> 1);
643 nb_sectors
/= s
->cluster_size
;
646 toclen
= cdrom_read_toc(nb_sectors
, outbuf
, msf
, start_track
);
649 /* multi session : only a single session defined */
651 memset(outbuf
, 0, 12);
657 toclen
= cdrom_read_toc_raw(nb_sectors
, outbuf
, msf
, start_track
);
662 if (toclen
> req
->cmd
.xfer
)
663 toclen
= req
->cmd
.xfer
;
667 static int scsi_disk_emulate_command(SCSIRequest
*req
, uint8_t *outbuf
)
669 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, req
->dev
);
670 BlockDriverState
*bdrv
= req
->dev
->dinfo
->bdrv
;
674 switch (req
->cmd
.buf
[0]) {
675 case TEST_UNIT_READY
:
676 if (!bdrv_is_inserted(bdrv
))
680 if (req
->cmd
.xfer
< 4)
681 goto illegal_request
;
682 memset(outbuf
, 0, 4);
684 if (req
->dev
->sense
.key
== NOT_READY
&& req
->cmd
.xfer
>= 18) {
685 memset(outbuf
, 0, 18);
688 /* asc 0x3a, ascq 0: Medium not present */
694 outbuf
[2] = req
->dev
->sense
.key
;
695 scsi_dev_clear_sense(req
->dev
);
698 buflen
= scsi_disk_emulate_inquiry(req
, outbuf
);
700 goto illegal_request
;
704 buflen
= scsi_disk_emulate_mode_sense(req
, outbuf
);
706 goto illegal_request
;
709 buflen
= scsi_disk_emulate_read_toc(req
, outbuf
);
711 goto illegal_request
;
714 if (req
->cmd
.buf
[1] & 1)
715 goto illegal_request
;
718 if (req
->cmd
.buf
[1] & 3)
719 goto illegal_request
;
722 if (req
->cmd
.buf
[1] & 1)
723 goto illegal_request
;
726 if (req
->cmd
.buf
[1] & 3)
727 goto illegal_request
;
730 if (bdrv_get_type_hint(bdrv
) == BDRV_TYPE_CDROM
&& (req
->cmd
.buf
[4] & 2)) {
731 /* load/eject medium */
732 bdrv_eject(bdrv
, !(req
->cmd
.buf
[4] & 1));
735 case ALLOW_MEDIUM_REMOVAL
:
736 bdrv_set_locked(bdrv
, req
->cmd
.buf
[4] & 1);
739 /* The normal LEN field for this command is zero. */
740 memset(outbuf
, 0, 8);
741 bdrv_get_geometry(bdrv
, &nb_sectors
);
744 nb_sectors
/= s
->cluster_size
;
745 /* Returned value is the address of the last sector. */
747 /* Remember the new size for read/write sanity checking. */
748 s
->max_lba
= nb_sectors
;
749 /* Clip to 2TB, instead of returning capacity modulo 2TB. */
750 if (nb_sectors
> UINT32_MAX
)
751 nb_sectors
= UINT32_MAX
;
752 outbuf
[0] = (nb_sectors
>> 24) & 0xff;
753 outbuf
[1] = (nb_sectors
>> 16) & 0xff;
754 outbuf
[2] = (nb_sectors
>> 8) & 0xff;
755 outbuf
[3] = nb_sectors
& 0xff;
758 outbuf
[6] = s
->cluster_size
* 2;
762 case SYNCHRONIZE_CACHE
:
765 case GET_CONFIGURATION
:
766 memset(outbuf
, 0, 8);
767 /* ??? This should probably return much more information. For now
768 just return the basic header indicating the CD-ROM profile. */
769 outbuf
[7] = 8; // CD-ROM
772 case SERVICE_ACTION_IN
:
773 /* Service Action In subcommands. */
774 if ((req
->cmd
.buf
[1] & 31) == 0x10) {
775 DPRINTF("SAI READ CAPACITY(16)\n");
776 memset(outbuf
, 0, req
->cmd
.xfer
);
777 bdrv_get_geometry(bdrv
, &nb_sectors
);
780 nb_sectors
/= s
->cluster_size
;
781 /* Returned value is the address of the last sector. */
783 /* Remember the new size for read/write sanity checking. */
784 s
->max_lba
= nb_sectors
;
785 outbuf
[0] = (nb_sectors
>> 56) & 0xff;
786 outbuf
[1] = (nb_sectors
>> 48) & 0xff;
787 outbuf
[2] = (nb_sectors
>> 40) & 0xff;
788 outbuf
[3] = (nb_sectors
>> 32) & 0xff;
789 outbuf
[4] = (nb_sectors
>> 24) & 0xff;
790 outbuf
[5] = (nb_sectors
>> 16) & 0xff;
791 outbuf
[6] = (nb_sectors
>> 8) & 0xff;
792 outbuf
[7] = nb_sectors
& 0xff;
795 outbuf
[10] = s
->cluster_size
* 2;
797 /* Protection, exponent and lowest lba field left blank. */
798 buflen
= req
->cmd
.xfer
;
801 DPRINTF("Unsupported Service Action In\n");
802 goto illegal_request
;
804 if (req
->cmd
.xfer
< 16)
805 goto illegal_request
;
806 memset(outbuf
, 0, 16);
813 goto illegal_request
;
815 scsi_req_set_status(req
, GOOD
, NO_SENSE
);
819 scsi_req_set_status(req
, CHECK_CONDITION
, NOT_READY
);
823 scsi_req_set_status(req
, CHECK_CONDITION
, ILLEGAL_REQUEST
);
827 /* Execute a scsi command. Returns the length of the data expected by the
828 command. This will be Positive for data transfers from the device
829 (eg. disk reads), negative for transfers to the device (eg. disk writes),
830 and zero if the command does not transfer any data. */
832 static int32_t scsi_send_command(SCSIDevice
*d
, uint32_t tag
,
833 uint8_t *buf
, int lun
)
835 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, d
);
846 r
= scsi_find_request(s
, tag
);
848 BADF("Tag 0x%x already in use\n", tag
);
849 scsi_cancel_io(d
, tag
);
851 /* ??? Tags are not unique for different luns. We only implement a
852 single lun, so this should not matter. */
853 r
= scsi_new_request(d
, tag
, lun
);
854 outbuf
= (uint8_t *)r
->iov
.iov_base
;
856 DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun
, tag
, buf
[0]);
857 switch (command
>> 5) {
859 lba
= (uint64_t) buf
[3] | ((uint64_t) buf
[2] << 8) |
860 (((uint64_t) buf
[1] & 0x1f) << 16);
866 lba
= (uint64_t) buf
[5] | ((uint64_t) buf
[4] << 8) |
867 ((uint64_t) buf
[3] << 16) | ((uint64_t) buf
[2] << 24);
868 len
= buf
[8] | (buf
[7] << 8);
872 lba
= (uint64_t) buf
[9] | ((uint64_t) buf
[8] << 8) |
873 ((uint64_t) buf
[7] << 16) | ((uint64_t) buf
[6] << 24) |
874 ((uint64_t) buf
[5] << 32) | ((uint64_t) buf
[4] << 40) |
875 ((uint64_t) buf
[3] << 48) | ((uint64_t) buf
[2] << 56);
876 len
= buf
[13] | (buf
[12] << 8) | (buf
[11] << 16) | (buf
[10] << 24);
880 lba
= (uint64_t) buf
[5] | ((uint64_t) buf
[4] << 8) |
881 ((uint64_t) buf
[3] << 16) | ((uint64_t) buf
[2] << 24);
882 len
= buf
[9] | (buf
[8] << 8) | (buf
[7] << 16) | (buf
[6] << 24);
886 BADF("Unsupported command length, command %x\n", command
);
892 for (i
= 1; i
< cmdlen
; i
++) {
893 printf(" 0x%02x", buf
[i
]);
899 if (scsi_req_parse(&r
->req
, buf
) != 0) {
900 BADF("Unsupported command length, command %x\n", command
);
903 assert(r
->req
.cmd
.len
== cmdlen
);
904 assert(r
->req
.cmd
.lba
== lba
);
906 if (lun
|| buf
[1] >> 5) {
907 /* Only LUN 0 supported. */
908 DPRINTF("Unimplemented LUN %d\n", lun
? lun
: buf
[1] >> 5);
909 if (command
!= REQUEST_SENSE
&& command
!= INQUIRY
)
913 case TEST_UNIT_READY
:
923 case ALLOW_MEDIUM_REMOVAL
:
925 case SYNCHRONIZE_CACHE
:
927 case GET_CONFIGURATION
:
928 case SERVICE_ACTION_IN
:
931 rc
= scsi_disk_emulate_command(&r
->req
, outbuf
);
935 scsi_req_complete(&r
->req
);
936 scsi_remove_request(r
);
944 DPRINTF("Read (sector %" PRId64
", count %d)\n", lba
, len
);
945 if (lba
> s
->max_lba
)
947 r
->sector
= lba
* s
->cluster_size
;
948 r
->sector_count
= len
* s
->cluster_size
;
954 DPRINTF("Write (sector %" PRId64
", count %d)\n", lba
, len
);
955 if (lba
> s
->max_lba
)
957 r
->sector
= lba
* s
->cluster_size
;
958 r
->sector_count
= len
* s
->cluster_size
;
962 DPRINTF("Unknown SCSI command (%2.2x)\n", buf
[0]);
964 scsi_command_complete(r
, CHECK_CONDITION
, ILLEGAL_REQUEST
);
967 scsi_command_complete(r
, CHECK_CONDITION
, HARDWARE_ERROR
);
970 if (r
->sector_count
== 0 && r
->iov
.iov_len
== 0) {
971 scsi_command_complete(r
, GOOD
, NO_SENSE
);
973 len
= r
->sector_count
* 512 + r
->iov
.iov_len
;
977 if (!r
->sector_count
)
978 r
->sector_count
= -1;
983 static void scsi_destroy(SCSIDevice
*dev
)
985 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, dev
);
988 while (!QTAILQ_EMPTY(&s
->qdev
.requests
)) {
989 r
= DO_UPCAST(SCSIDiskReq
, req
, QTAILQ_FIRST(&s
->qdev
.requests
));
990 scsi_remove_request(r
);
992 drive_uninit(s
->qdev
.dinfo
);
995 static int scsi_disk_initfn(SCSIDevice
*dev
)
997 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, dev
);
1000 if (!s
->qdev
.dinfo
|| !s
->qdev
.dinfo
->bdrv
) {
1001 qemu_error("scsi-disk: drive property not set\n");
1005 if (bdrv_get_type_hint(s
->qdev
.dinfo
->bdrv
) == BDRV_TYPE_CDROM
) {
1006 s
->cluster_size
= 4;
1008 s
->cluster_size
= 1;
1010 s
->qdev
.blocksize
= 512 * s
->cluster_size
;
1011 s
->qdev
.type
= TYPE_DISK
;
1012 bdrv_get_geometry(s
->qdev
.dinfo
->bdrv
, &nb_sectors
);
1013 nb_sectors
/= s
->cluster_size
;
1016 s
->max_lba
= nb_sectors
;
1017 qemu_add_vm_change_state_handler(scsi_dma_restart_cb
, s
);
1021 static SCSIDeviceInfo scsi_disk_info
= {
1022 .qdev
.name
= "scsi-disk",
1023 .qdev
.desc
= "virtual scsi disk or cdrom",
1024 .qdev
.size
= sizeof(SCSIDiskState
),
1025 .init
= scsi_disk_initfn
,
1026 .destroy
= scsi_destroy
,
1027 .send_command
= scsi_send_command
,
1028 .read_data
= scsi_read_data
,
1029 .write_data
= scsi_write_data
,
1030 .cancel_io
= scsi_cancel_io
,
1031 .get_buf
= scsi_get_buf
,
1032 .qdev
.props
= (Property
[]) {
1033 DEFINE_PROP_DRIVE("drive", SCSIDiskState
, qdev
.dinfo
),
1034 DEFINE_PROP_STRING("ver", SCSIDiskState
, version
),
1035 DEFINE_PROP_END_OF_LIST(),
1039 static void scsi_disk_register_devices(void)
1041 scsi_qdev_register(&scsi_disk_info
);
1043 device_init(scsi_disk_register_devices
)