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
?: "0";
350 int l
= strlen(serial
);
352 if (l
> req
->cmd
.xfer
)
357 DPRINTF("Inquiry EVPD[Serial number] "
358 "buffer size %zd\n", req
->cmd
.xfer
);
359 outbuf
[buflen
++] = l
;
360 memcpy(outbuf
+buflen
, serial
, l
);
365 case 0x83: /* Device identification page, mandatory */
367 int max_len
= 255 - 8;
368 int id_len
= strlen(bdrv_get_device_name(bdrv
));
370 if (id_len
> max_len
)
372 DPRINTF("Inquiry EVPD[Device identification] "
373 "buffer size %zd\n", req
->cmd
.xfer
);
375 outbuf
[buflen
++] = 3 + id_len
;
376 outbuf
[buflen
++] = 0x2; // ASCII
377 outbuf
[buflen
++] = 0; // not officially assigned
378 outbuf
[buflen
++] = 0; // reserved
379 outbuf
[buflen
++] = id_len
; // length of data following
381 memcpy(outbuf
+buflen
, bdrv_get_device_name(bdrv
), id_len
);
386 BADF("Error: unsupported Inquiry (EVPD[%02X]) "
387 "buffer size %zd\n", page_code
, req
->cmd
.xfer
);
394 /* Standard INQUIRY data */
395 if (req
->cmd
.buf
[2] != 0) {
396 BADF("Error: Inquiry (STANDARD) page or code "
397 "is non-zero [%02X]\n", req
->cmd
.buf
[2]);
402 if (req
->cmd
.xfer
< 5) {
403 BADF("Error: Inquiry (STANDARD) buffer size %zd "
404 "is less than 5\n", req
->cmd
.xfer
);
408 if (req
->cmd
.xfer
< 36) {
409 BADF("Error: Inquiry (STANDARD) buffer size %zd "
410 "is less than 36 (TODO: only 5 required)\n", req
->cmd
.xfer
);
413 buflen
= req
->cmd
.xfer
;
414 if (buflen
> SCSI_MAX_INQUIRY_LEN
)
415 buflen
= SCSI_MAX_INQUIRY_LEN
;
417 memset(outbuf
, 0, buflen
);
419 if (req
->lun
|| req
->cmd
.buf
[1] >> 5) {
420 outbuf
[0] = 0x7f; /* LUN not supported */
424 if (bdrv_get_type_hint(bdrv
) == BDRV_TYPE_CDROM
) {
427 memcpy(&outbuf
[16], "QEMU CD-ROM ", 16);
430 memcpy(&outbuf
[16], "QEMU HARDDISK ", 16);
432 memcpy(&outbuf
[8], "QEMU ", 8);
433 memcpy(&outbuf
[32], QEMU_VERSION
, 4);
434 /* Identify device as SCSI-3 rev 1.
435 Some later commands are also implemented. */
437 outbuf
[3] = 2; /* Format 2 */
438 outbuf
[4] = buflen
- 5; /* Additional Length = (Len - 1) - 4 */
439 /* Sync data transfer and TCQ. */
440 outbuf
[7] = 0x10 | (req
->bus
->tcq
? 0x02 : 0);
444 static int mode_sense_page(SCSIRequest
*req
, int page
, uint8_t *p
)
446 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, req
->dev
);
447 BlockDriverState
*bdrv
= req
->dev
->dinfo
->bdrv
;
448 int cylinders
, heads
, secs
;
451 case 4: /* Rigid disk device geometry page. */
454 /* if a geometry hint is available, use it */
455 bdrv_get_geometry_hint(bdrv
, &cylinders
, &heads
, &secs
);
456 p
[2] = (cylinders
>> 16) & 0xff;
457 p
[3] = (cylinders
>> 8) & 0xff;
458 p
[4] = cylinders
& 0xff;
460 /* Write precomp start cylinder, disabled */
461 p
[6] = (cylinders
>> 16) & 0xff;
462 p
[7] = (cylinders
>> 8) & 0xff;
463 p
[8] = cylinders
& 0xff;
464 /* Reduced current start cylinder, disabled */
465 p
[9] = (cylinders
>> 16) & 0xff;
466 p
[10] = (cylinders
>> 8) & 0xff;
467 p
[11] = cylinders
& 0xff;
468 /* Device step rate [ns], 200ns */
471 /* Landing zone cylinder */
475 /* Medium rotation rate [rpm], 5400 rpm */
476 p
[20] = (5400 >> 8) & 0xff;
480 case 5: /* Flexible disk device geometry page. */
483 /* Transfer rate [kbit/s], 5Mbit/s */
486 /* if a geometry hint is available, use it */
487 bdrv_get_geometry_hint(bdrv
, &cylinders
, &heads
, &secs
);
490 p
[6] = s
->cluster_size
* 2;
491 p
[8] = (cylinders
>> 8) & 0xff;
492 p
[9] = cylinders
& 0xff;
493 /* Write precomp start cylinder, disabled */
494 p
[10] = (cylinders
>> 8) & 0xff;
495 p
[11] = cylinders
& 0xff;
496 /* Reduced current start cylinder, disabled */
497 p
[12] = (cylinders
>> 8) & 0xff;
498 p
[13] = cylinders
& 0xff;
499 /* Device step rate [100us], 100us */
502 /* Device step pulse width [us], 1us */
504 /* Device head settle delay [100us], 100us */
507 /* Motor on delay [0.1s], 0.1s */
509 /* Motor off delay [0.1s], 0.1s */
511 /* Medium rotation rate [rpm], 5400 rpm */
512 p
[28] = (5400 >> 8) & 0xff;
516 case 8: /* Caching page. */
519 if (bdrv_enable_write_cache(s
->qdev
.dinfo
->bdrv
)) {
524 case 0x2a: /* CD Capabilities and Mechanical Status page. */
525 if (bdrv_get_type_hint(bdrv
) != BDRV_TYPE_CDROM
)
529 p
[2] = 3; // CD-R & CD-RW read
530 p
[3] = 0; // Writing not supported
531 p
[4] = 0x7f; /* Audio, composite, digital out,
532 mode 2 form 1&2, multi session */
533 p
[5] = 0xff; /* CD DA, DA accurate, RW supported,
534 RW corrected, C2 errors, ISRC,
536 p
[6] = 0x2d | (bdrv_is_locked(s
->qdev
.dinfo
->bdrv
)? 2 : 0);
537 /* Locking supported, jumper present, eject, tray */
538 p
[7] = 0; /* no volume & mute control, no
540 p
[8] = (50 * 176) >> 8; // 50x read speed
541 p
[9] = (50 * 176) & 0xff;
542 p
[10] = 0 >> 8; // No volume
544 p
[12] = 2048 >> 8; // 2M buffer
546 p
[14] = (16 * 176) >> 8; // 16x read speed current
547 p
[15] = (16 * 176) & 0xff;
548 p
[18] = (16 * 176) >> 8; // 16x write speed
549 p
[19] = (16 * 176) & 0xff;
550 p
[20] = (16 * 176) >> 8; // 16x write speed current
551 p
[21] = (16 * 176) & 0xff;
559 static int scsi_disk_emulate_mode_sense(SCSIRequest
*req
, uint8_t *outbuf
)
561 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, req
->dev
);
562 BlockDriverState
*bdrv
= req
->dev
->dinfo
->bdrv
;
564 int page
, dbd
, buflen
;
567 dbd
= req
->cmd
.buf
[1] & 0x8;
568 page
= req
->cmd
.buf
[2] & 0x3f;
569 DPRINTF("Mode Sense (page %d, len %zd)\n", page
, req
->cmd
.xfer
);
570 memset(outbuf
, 0, req
->cmd
.xfer
);
573 p
[1] = 0; /* Default media type. */
574 p
[3] = 0; /* Block descriptor length. */
575 if (bdrv_get_type_hint(bdrv
) == BDRV_TYPE_CDROM
||
576 bdrv_is_read_only(bdrv
)) {
577 p
[2] = 0x80; /* Readonly. */
581 bdrv_get_geometry(bdrv
, &nb_sectors
);
582 if ((~dbd
) & nb_sectors
) {
583 outbuf
[3] = 8; /* Block descriptor length */
584 nb_sectors
/= s
->cluster_size
;
586 if (nb_sectors
> 0xffffff)
587 nb_sectors
= 0xffffff;
588 p
[0] = 0; /* media density code */
589 p
[1] = (nb_sectors
>> 16) & 0xff;
590 p
[2] = (nb_sectors
>> 8) & 0xff;
591 p
[3] = nb_sectors
& 0xff;
592 p
[4] = 0; /* reserved */
593 p
[5] = 0; /* bytes 5-7 are the sector size in bytes */
594 p
[6] = s
->cluster_size
* 2;
604 p
+= mode_sense_page(req
, page
, p
);
607 p
+= mode_sense_page(req
, 0x08, p
);
608 p
+= mode_sense_page(req
, 0x2a, p
);
613 outbuf
[0] = buflen
- 4;
614 if (buflen
> req
->cmd
.xfer
)
615 buflen
= req
->cmd
.xfer
;
619 static int scsi_disk_emulate_read_toc(SCSIRequest
*req
, uint8_t *outbuf
)
621 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, req
->dev
);
622 BlockDriverState
*bdrv
= req
->dev
->dinfo
->bdrv
;
623 int start_track
, format
, msf
, toclen
;
626 msf
= req
->cmd
.buf
[1] & 2;
627 format
= req
->cmd
.buf
[2] & 0xf;
628 start_track
= req
->cmd
.buf
[6];
629 bdrv_get_geometry(bdrv
, &nb_sectors
);
630 DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track
, format
, msf
>> 1);
631 nb_sectors
/= s
->cluster_size
;
634 toclen
= cdrom_read_toc(nb_sectors
, outbuf
, msf
, start_track
);
637 /* multi session : only a single session defined */
639 memset(outbuf
, 0, 12);
645 toclen
= cdrom_read_toc_raw(nb_sectors
, outbuf
, msf
, start_track
);
650 if (toclen
> req
->cmd
.xfer
)
651 toclen
= req
->cmd
.xfer
;
655 static int scsi_disk_emulate_command(SCSIRequest
*req
, uint8_t *outbuf
)
657 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, req
->dev
);
658 BlockDriverState
*bdrv
= req
->dev
->dinfo
->bdrv
;
662 switch (req
->cmd
.buf
[0]) {
663 case TEST_UNIT_READY
:
664 if (!bdrv_is_inserted(bdrv
))
668 if (req
->cmd
.xfer
< 4)
669 goto illegal_request
;
670 memset(outbuf
, 0, 4);
672 if (req
->dev
->sense
.key
== NOT_READY
&& req
->cmd
.xfer
>= 18) {
673 memset(outbuf
, 0, 18);
676 /* asc 0x3a, ascq 0: Medium not present */
682 outbuf
[2] = req
->dev
->sense
.key
;
683 scsi_dev_clear_sense(req
->dev
);
686 buflen
= scsi_disk_emulate_inquiry(req
, outbuf
);
688 goto illegal_request
;
692 buflen
= scsi_disk_emulate_mode_sense(req
, outbuf
);
694 goto illegal_request
;
697 buflen
= scsi_disk_emulate_read_toc(req
, outbuf
);
699 goto illegal_request
;
702 if (req
->cmd
.buf
[1] & 1)
703 goto illegal_request
;
706 if (req
->cmd
.buf
[1] & 3)
707 goto illegal_request
;
710 if (req
->cmd
.buf
[1] & 1)
711 goto illegal_request
;
714 if (req
->cmd
.buf
[1] & 3)
715 goto illegal_request
;
718 if (bdrv_get_type_hint(bdrv
) == BDRV_TYPE_CDROM
&& (req
->cmd
.buf
[4] & 2)) {
719 /* load/eject medium */
720 bdrv_eject(bdrv
, !(req
->cmd
.buf
[4] & 1));
723 case ALLOW_MEDIUM_REMOVAL
:
724 bdrv_set_locked(bdrv
, req
->cmd
.buf
[4] & 1);
727 /* The normal LEN field for this command is zero. */
728 memset(outbuf
, 0, 8);
729 bdrv_get_geometry(bdrv
, &nb_sectors
);
732 nb_sectors
/= s
->cluster_size
;
733 /* Returned value is the address of the last sector. */
735 /* Remember the new size for read/write sanity checking. */
736 s
->max_lba
= nb_sectors
;
737 /* Clip to 2TB, instead of returning capacity modulo 2TB. */
738 if (nb_sectors
> UINT32_MAX
)
739 nb_sectors
= UINT32_MAX
;
740 outbuf
[0] = (nb_sectors
>> 24) & 0xff;
741 outbuf
[1] = (nb_sectors
>> 16) & 0xff;
742 outbuf
[2] = (nb_sectors
>> 8) & 0xff;
743 outbuf
[3] = nb_sectors
& 0xff;
746 outbuf
[6] = s
->cluster_size
* 2;
750 case SYNCHRONIZE_CACHE
:
753 case GET_CONFIGURATION
:
754 memset(outbuf
, 0, 8);
755 /* ??? This should probably return much more information. For now
756 just return the basic header indicating the CD-ROM profile. */
757 outbuf
[7] = 8; // CD-ROM
760 case SERVICE_ACTION_IN
:
761 /* Service Action In subcommands. */
762 if ((req
->cmd
.buf
[1] & 31) == 0x10) {
763 DPRINTF("SAI READ CAPACITY(16)\n");
764 memset(outbuf
, 0, req
->cmd
.xfer
);
765 bdrv_get_geometry(bdrv
, &nb_sectors
);
768 nb_sectors
/= s
->cluster_size
;
769 /* Returned value is the address of the last sector. */
771 /* Remember the new size for read/write sanity checking. */
772 s
->max_lba
= nb_sectors
;
773 outbuf
[0] = (nb_sectors
>> 56) & 0xff;
774 outbuf
[1] = (nb_sectors
>> 48) & 0xff;
775 outbuf
[2] = (nb_sectors
>> 40) & 0xff;
776 outbuf
[3] = (nb_sectors
>> 32) & 0xff;
777 outbuf
[4] = (nb_sectors
>> 24) & 0xff;
778 outbuf
[5] = (nb_sectors
>> 16) & 0xff;
779 outbuf
[6] = (nb_sectors
>> 8) & 0xff;
780 outbuf
[7] = nb_sectors
& 0xff;
783 outbuf
[10] = s
->cluster_size
* 2;
785 /* Protection, exponent and lowest lba field left blank. */
786 buflen
= req
->cmd
.xfer
;
789 DPRINTF("Unsupported Service Action In\n");
790 goto illegal_request
;
792 if (req
->cmd
.xfer
< 16)
793 goto illegal_request
;
794 memset(outbuf
, 0, 16);
801 goto illegal_request
;
803 scsi_req_set_status(req
, GOOD
, NO_SENSE
);
807 scsi_req_set_status(req
, CHECK_CONDITION
, NOT_READY
);
811 scsi_req_set_status(req
, CHECK_CONDITION
, ILLEGAL_REQUEST
);
815 /* Execute a scsi command. Returns the length of the data expected by the
816 command. This will be Positive for data transfers from the device
817 (eg. disk reads), negative for transfers to the device (eg. disk writes),
818 and zero if the command does not transfer any data. */
820 static int32_t scsi_send_command(SCSIDevice
*d
, uint32_t tag
,
821 uint8_t *buf
, int lun
)
823 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, d
);
834 r
= scsi_find_request(s
, tag
);
836 BADF("Tag 0x%x already in use\n", tag
);
837 scsi_cancel_io(d
, tag
);
839 /* ??? Tags are not unique for different luns. We only implement a
840 single lun, so this should not matter. */
841 r
= scsi_new_request(d
, tag
, lun
);
842 outbuf
= (uint8_t *)r
->iov
.iov_base
;
844 DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun
, tag
, buf
[0]);
845 switch (command
>> 5) {
847 lba
= (uint64_t) buf
[3] | ((uint64_t) buf
[2] << 8) |
848 (((uint64_t) buf
[1] & 0x1f) << 16);
854 lba
= (uint64_t) buf
[5] | ((uint64_t) buf
[4] << 8) |
855 ((uint64_t) buf
[3] << 16) | ((uint64_t) buf
[2] << 24);
856 len
= buf
[8] | (buf
[7] << 8);
860 lba
= (uint64_t) buf
[9] | ((uint64_t) buf
[8] << 8) |
861 ((uint64_t) buf
[7] << 16) | ((uint64_t) buf
[6] << 24) |
862 ((uint64_t) buf
[5] << 32) | ((uint64_t) buf
[4] << 40) |
863 ((uint64_t) buf
[3] << 48) | ((uint64_t) buf
[2] << 56);
864 len
= buf
[13] | (buf
[12] << 8) | (buf
[11] << 16) | (buf
[10] << 24);
868 lba
= (uint64_t) buf
[5] | ((uint64_t) buf
[4] << 8) |
869 ((uint64_t) buf
[3] << 16) | ((uint64_t) buf
[2] << 24);
870 len
= buf
[9] | (buf
[8] << 8) | (buf
[7] << 16) | (buf
[6] << 24);
874 BADF("Unsupported command length, command %x\n", command
);
880 for (i
= 1; i
< cmdlen
; i
++) {
881 printf(" 0x%02x", buf
[i
]);
887 if (scsi_req_parse(&r
->req
, buf
) != 0) {
888 BADF("Unsupported command length, command %x\n", command
);
891 assert(r
->req
.cmd
.len
== cmdlen
);
892 assert(r
->req
.cmd
.lba
== lba
);
894 if (lun
|| buf
[1] >> 5) {
895 /* Only LUN 0 supported. */
896 DPRINTF("Unimplemented LUN %d\n", lun
? lun
: buf
[1] >> 5);
897 if (command
!= REQUEST_SENSE
&& command
!= INQUIRY
)
901 case TEST_UNIT_READY
:
911 case ALLOW_MEDIUM_REMOVAL
:
913 case SYNCHRONIZE_CACHE
:
915 case GET_CONFIGURATION
:
916 case SERVICE_ACTION_IN
:
919 rc
= scsi_disk_emulate_command(&r
->req
, outbuf
);
923 scsi_req_complete(&r
->req
);
924 scsi_remove_request(r
);
932 DPRINTF("Read (sector %" PRId64
", count %d)\n", lba
, len
);
933 if (lba
> s
->max_lba
)
935 r
->sector
= lba
* s
->cluster_size
;
936 r
->sector_count
= len
* s
->cluster_size
;
942 DPRINTF("Write (sector %" PRId64
", count %d)\n", lba
, len
);
943 if (lba
> s
->max_lba
)
945 r
->sector
= lba
* s
->cluster_size
;
946 r
->sector_count
= len
* s
->cluster_size
;
950 DPRINTF("Unknown SCSI command (%2.2x)\n", buf
[0]);
952 scsi_command_complete(r
, CHECK_CONDITION
, ILLEGAL_REQUEST
);
955 scsi_command_complete(r
, CHECK_CONDITION
, HARDWARE_ERROR
);
958 if (r
->sector_count
== 0 && r
->iov
.iov_len
== 0) {
959 scsi_command_complete(r
, GOOD
, NO_SENSE
);
961 len
= r
->sector_count
* 512 + r
->iov
.iov_len
;
965 if (!r
->sector_count
)
966 r
->sector_count
= -1;
971 static void scsi_destroy(SCSIDevice
*dev
)
973 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, dev
);
976 while (!QTAILQ_EMPTY(&s
->qdev
.requests
)) {
977 r
= DO_UPCAST(SCSIDiskReq
, req
, QTAILQ_FIRST(&s
->qdev
.requests
));
978 scsi_remove_request(r
);
980 drive_uninit(s
->qdev
.dinfo
);
983 static int scsi_disk_initfn(SCSIDevice
*dev
)
985 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, dev
);
988 if (!s
->qdev
.dinfo
|| !s
->qdev
.dinfo
->bdrv
) {
989 qemu_error("scsi-disk: drive property not set\n");
993 if (bdrv_get_type_hint(s
->qdev
.dinfo
->bdrv
) == BDRV_TYPE_CDROM
) {
998 s
->qdev
.blocksize
= 512 * s
->cluster_size
;
999 s
->qdev
.type
= TYPE_DISK
;
1000 bdrv_get_geometry(s
->qdev
.dinfo
->bdrv
, &nb_sectors
);
1001 nb_sectors
/= s
->cluster_size
;
1004 s
->max_lba
= nb_sectors
;
1005 qemu_add_vm_change_state_handler(scsi_dma_restart_cb
, s
);
1009 static SCSIDeviceInfo scsi_disk_info
= {
1010 .qdev
.name
= "scsi-disk",
1011 .qdev
.desc
= "virtual scsi disk or cdrom",
1012 .qdev
.size
= sizeof(SCSIDiskState
),
1013 .init
= scsi_disk_initfn
,
1014 .destroy
= scsi_destroy
,
1015 .send_command
= scsi_send_command
,
1016 .read_data
= scsi_read_data
,
1017 .write_data
= scsi_write_data
,
1018 .cancel_io
= scsi_cancel_io
,
1019 .get_buf
= scsi_get_buf
,
1020 .qdev
.props
= (Property
[]) {
1021 DEFINE_PROP_DRIVE("drive", SCSIDiskState
, qdev
.dinfo
),
1022 DEFINE_PROP_END_OF_LIST(),
1026 static void scsi_disk_register_devices(void)
1028 scsi_qdev_register(&scsi_disk_info
);
1030 device_init(scsi_disk_register_devices
)