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
= drive_get_onerror(s
->qdev
.dinfo
->bdrv
);
177 if (action
== BLOCK_ERR_IGNORE
)
180 if ((error
== ENOSPC
&& action
== BLOCK_ERR_STOP_ENOSPC
)
181 || action
== BLOCK_ERR_STOP_ANY
) {
182 r
->status
|= SCSI_REQ_STATUS_RETRY
;
185 scsi_command_complete(r
, CHECK_CONDITION
,
192 static void scsi_write_complete(void * opaque
, int ret
)
194 SCSIDiskReq
*r
= (SCSIDiskReq
*)opaque
;
201 if (scsi_handle_write_error(r
, -ret
))
205 n
= r
->iov
.iov_len
/ 512;
207 r
->sector_count
-= n
;
208 if (r
->sector_count
== 0) {
209 scsi_command_complete(r
, GOOD
, NO_SENSE
);
211 len
= r
->sector_count
* 512;
212 if (len
> SCSI_DMA_BUF_SIZE
) {
213 len
= SCSI_DMA_BUF_SIZE
;
215 r
->iov
.iov_len
= len
;
216 DPRINTF("Write complete tag=0x%x more=%d\n", r
->req
.tag
, len
);
217 r
->req
.bus
->complete(r
->req
.bus
, SCSI_REASON_DATA
, r
->req
.tag
, len
);
221 static void scsi_write_request(SCSIDiskReq
*r
)
223 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, r
->req
.dev
);
226 n
= r
->iov
.iov_len
/ 512;
228 qemu_iovec_init_external(&r
->qiov
, &r
->iov
, 1);
229 r
->req
.aiocb
= bdrv_aio_writev(s
->qdev
.dinfo
->bdrv
, r
->sector
, &r
->qiov
, n
,
230 scsi_write_complete
, r
);
231 if (r
->req
.aiocb
== NULL
)
232 scsi_command_complete(r
, CHECK_CONDITION
,
235 /* Invoke completion routine to fetch data from host. */
236 scsi_write_complete(r
, 0);
240 /* Write data to a scsi device. Returns nonzero on failure.
241 The transfer may complete asynchronously. */
242 static int scsi_write_data(SCSIDevice
*d
, uint32_t tag
)
244 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, d
);
247 DPRINTF("Write data tag=0x%x\n", tag
);
248 r
= scsi_find_request(s
, tag
);
250 BADF("Bad write tag 0x%x\n", tag
);
251 scsi_command_complete(r
, CHECK_CONDITION
, HARDWARE_ERROR
);
256 BADF("Data transfer already in progress\n");
258 scsi_write_request(r
);
263 static void scsi_dma_restart_bh(void *opaque
)
265 SCSIDiskState
*s
= opaque
;
269 qemu_bh_delete(s
->bh
);
272 QTAILQ_FOREACH(req
, &s
->qdev
.requests
, next
) {
273 r
= DO_UPCAST(SCSIDiskReq
, req
, req
);
274 if (r
->status
& SCSI_REQ_STATUS_RETRY
) {
275 r
->status
&= ~SCSI_REQ_STATUS_RETRY
;
276 scsi_write_request(r
);
281 static void scsi_dma_restart_cb(void *opaque
, int running
, int reason
)
283 SCSIDiskState
*s
= opaque
;
289 s
->bh
= qemu_bh_new(scsi_dma_restart_bh
, s
);
290 qemu_bh_schedule(s
->bh
);
294 /* Return a pointer to the data buffer. */
295 static uint8_t *scsi_get_buf(SCSIDevice
*d
, uint32_t tag
)
297 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, d
);
300 r
= scsi_find_request(s
, tag
);
302 BADF("Bad buffer tag 0x%x\n", tag
);
305 return (uint8_t *)r
->iov
.iov_base
;
308 static int scsi_disk_emulate_inquiry(SCSIRequest
*req
, uint8_t *outbuf
)
310 BlockDriverState
*bdrv
= req
->dev
->dinfo
->bdrv
;
313 if (req
->cmd
.buf
[1] & 0x2) {
314 /* Command support data - optional, not implemented */
315 BADF("optional INQUIRY command support request not implemented\n");
319 if (req
->cmd
.buf
[1] & 0x1) {
320 /* Vital product data */
321 uint8_t page_code
= req
->cmd
.buf
[2];
322 if (req
->cmd
.xfer
< 4) {
323 BADF("Error: Inquiry (EVPD[%02X]) buffer size %zd is "
324 "less than 4\n", page_code
, req
->cmd
.xfer
);
328 if (bdrv_get_type_hint(bdrv
) == BDRV_TYPE_CDROM
) {
329 outbuf
[buflen
++] = 5;
331 outbuf
[buflen
++] = 0;
333 outbuf
[buflen
++] = page_code
; // this page
334 outbuf
[buflen
++] = 0x00;
337 case 0x00: /* Supported page codes, mandatory */
338 DPRINTF("Inquiry EVPD[Supported pages] "
339 "buffer size %zd\n", req
->cmd
.xfer
);
340 outbuf
[buflen
++] = 3; // number of pages
341 outbuf
[buflen
++] = 0x00; // list of supported pages (this page)
342 outbuf
[buflen
++] = 0x80; // unit serial number
343 outbuf
[buflen
++] = 0x83; // device identification
346 case 0x80: /* Device serial number, optional */
348 const char *serial
= req
->dev
->dinfo
->serial
?: "0";
349 int l
= strlen(serial
);
351 if (l
> req
->cmd
.xfer
)
356 DPRINTF("Inquiry EVPD[Serial number] "
357 "buffer size %zd\n", req
->cmd
.xfer
);
358 outbuf
[buflen
++] = l
;
359 memcpy(outbuf
+buflen
, serial
, l
);
364 case 0x83: /* Device identification page, mandatory */
366 int max_len
= 255 - 8;
367 int id_len
= strlen(bdrv_get_device_name(bdrv
));
369 if (id_len
> max_len
)
371 DPRINTF("Inquiry EVPD[Device identification] "
372 "buffer size %zd\n", req
->cmd
.xfer
);
374 outbuf
[buflen
++] = 3 + id_len
;
375 outbuf
[buflen
++] = 0x2; // ASCII
376 outbuf
[buflen
++] = 0; // not officially assigned
377 outbuf
[buflen
++] = 0; // reserved
378 outbuf
[buflen
++] = id_len
; // length of data following
380 memcpy(outbuf
+buflen
, bdrv_get_device_name(bdrv
), id_len
);
385 BADF("Error: unsupported Inquiry (EVPD[%02X]) "
386 "buffer size %zd\n", page_code
, req
->cmd
.xfer
);
393 /* Standard INQUIRY data */
394 if (req
->cmd
.buf
[2] != 0) {
395 BADF("Error: Inquiry (STANDARD) page or code "
396 "is non-zero [%02X]\n", req
->cmd
.buf
[2]);
401 if (req
->cmd
.xfer
< 5) {
402 BADF("Error: Inquiry (STANDARD) buffer size %zd "
403 "is less than 5\n", req
->cmd
.xfer
);
407 if (req
->cmd
.xfer
< 36) {
408 BADF("Error: Inquiry (STANDARD) buffer size %zd "
409 "is less than 36 (TODO: only 5 required)\n", req
->cmd
.xfer
);
412 buflen
= req
->cmd
.xfer
;
413 if (buflen
> SCSI_MAX_INQUIRY_LEN
)
414 buflen
= SCSI_MAX_INQUIRY_LEN
;
416 memset(outbuf
, 0, buflen
);
418 if (req
->lun
|| req
->cmd
.buf
[1] >> 5) {
419 outbuf
[0] = 0x7f; /* LUN not supported */
423 if (bdrv_get_type_hint(bdrv
) == BDRV_TYPE_CDROM
) {
426 memcpy(&outbuf
[16], "QEMU CD-ROM ", 16);
429 memcpy(&outbuf
[16], "QEMU HARDDISK ", 16);
431 memcpy(&outbuf
[8], "QEMU ", 8);
432 memcpy(&outbuf
[32], QEMU_VERSION
, 4);
433 /* Identify device as SCSI-3 rev 1.
434 Some later commands are also implemented. */
436 outbuf
[3] = 2; /* Format 2 */
437 outbuf
[4] = buflen
- 5; /* Additional Length = (Len - 1) - 4 */
438 /* Sync data transfer and TCQ. */
439 outbuf
[7] = 0x10 | (req
->bus
->tcq
? 0x02 : 0);
443 static int mode_sense_page(SCSIRequest
*req
, int page
, uint8_t *p
)
445 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, req
->dev
);
446 BlockDriverState
*bdrv
= req
->dev
->dinfo
->bdrv
;
447 int cylinders
, heads
, secs
;
450 case 4: /* Rigid disk device geometry page. */
453 /* if a geometry hint is available, use it */
454 bdrv_get_geometry_hint(bdrv
, &cylinders
, &heads
, &secs
);
455 p
[2] = (cylinders
>> 16) & 0xff;
456 p
[3] = (cylinders
>> 8) & 0xff;
457 p
[4] = cylinders
& 0xff;
459 /* Write precomp start cylinder, disabled */
460 p
[6] = (cylinders
>> 16) & 0xff;
461 p
[7] = (cylinders
>> 8) & 0xff;
462 p
[8] = cylinders
& 0xff;
463 /* Reduced current start cylinder, disabled */
464 p
[9] = (cylinders
>> 16) & 0xff;
465 p
[10] = (cylinders
>> 8) & 0xff;
466 p
[11] = cylinders
& 0xff;
467 /* Device step rate [ns], 200ns */
470 /* Landing zone cylinder */
474 /* Medium rotation rate [rpm], 5400 rpm */
475 p
[20] = (5400 >> 8) & 0xff;
479 case 5: /* Flexible disk device geometry page. */
482 /* Transfer rate [kbit/s], 5Mbit/s */
485 /* if a geometry hint is available, use it */
486 bdrv_get_geometry_hint(bdrv
, &cylinders
, &heads
, &secs
);
489 p
[6] = s
->cluster_size
* 2;
490 p
[8] = (cylinders
>> 8) & 0xff;
491 p
[9] = cylinders
& 0xff;
492 /* Write precomp start cylinder, disabled */
493 p
[10] = (cylinders
>> 8) & 0xff;
494 p
[11] = cylinders
& 0xff;
495 /* Reduced current start cylinder, disabled */
496 p
[12] = (cylinders
>> 8) & 0xff;
497 p
[13] = cylinders
& 0xff;
498 /* Device step rate [100us], 100us */
501 /* Device step pulse width [us], 1us */
503 /* Device head settle delay [100us], 100us */
506 /* Motor on delay [0.1s], 0.1s */
508 /* Motor off delay [0.1s], 0.1s */
510 /* Medium rotation rate [rpm], 5400 rpm */
511 p
[28] = (5400 >> 8) & 0xff;
515 case 8: /* Caching page. */
518 if (bdrv_enable_write_cache(s
->qdev
.dinfo
->bdrv
)) {
523 case 0x2a: /* CD Capabilities and Mechanical Status page. */
524 if (bdrv_get_type_hint(bdrv
) != BDRV_TYPE_CDROM
)
528 p
[2] = 3; // CD-R & CD-RW read
529 p
[3] = 0; // Writing not supported
530 p
[4] = 0x7f; /* Audio, composite, digital out,
531 mode 2 form 1&2, multi session */
532 p
[5] = 0xff; /* CD DA, DA accurate, RW supported,
533 RW corrected, C2 errors, ISRC,
535 p
[6] = 0x2d | (bdrv_is_locked(s
->qdev
.dinfo
->bdrv
)? 2 : 0);
536 /* Locking supported, jumper present, eject, tray */
537 p
[7] = 0; /* no volume & mute control, no
539 p
[8] = (50 * 176) >> 8; // 50x read speed
540 p
[9] = (50 * 176) & 0xff;
541 p
[10] = 0 >> 8; // No volume
543 p
[12] = 2048 >> 8; // 2M buffer
545 p
[14] = (16 * 176) >> 8; // 16x read speed current
546 p
[15] = (16 * 176) & 0xff;
547 p
[18] = (16 * 176) >> 8; // 16x write speed
548 p
[19] = (16 * 176) & 0xff;
549 p
[20] = (16 * 176) >> 8; // 16x write speed current
550 p
[21] = (16 * 176) & 0xff;
558 static int scsi_disk_emulate_mode_sense(SCSIRequest
*req
, uint8_t *outbuf
)
560 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, req
->dev
);
561 BlockDriverState
*bdrv
= req
->dev
->dinfo
->bdrv
;
563 int page
, dbd
, buflen
;
566 dbd
= req
->cmd
.buf
[1] & 0x8;
567 page
= req
->cmd
.buf
[2] & 0x3f;
568 DPRINTF("Mode Sense (page %d, len %zd)\n", page
, req
->cmd
.xfer
);
569 memset(outbuf
, 0, req
->cmd
.xfer
);
572 p
[1] = 0; /* Default media type. */
573 p
[3] = 0; /* Block descriptor length. */
574 if (bdrv_get_type_hint(bdrv
) == BDRV_TYPE_CDROM
||
575 bdrv_is_read_only(bdrv
)) {
576 p
[2] = 0x80; /* Readonly. */
580 bdrv_get_geometry(bdrv
, &nb_sectors
);
581 if ((~dbd
) & nb_sectors
) {
582 outbuf
[3] = 8; /* Block descriptor length */
583 nb_sectors
/= s
->cluster_size
;
585 if (nb_sectors
> 0xffffff)
586 nb_sectors
= 0xffffff;
587 p
[0] = 0; /* media density code */
588 p
[1] = (nb_sectors
>> 16) & 0xff;
589 p
[2] = (nb_sectors
>> 8) & 0xff;
590 p
[3] = nb_sectors
& 0xff;
591 p
[4] = 0; /* reserved */
592 p
[5] = 0; /* bytes 5-7 are the sector size in bytes */
593 p
[6] = s
->cluster_size
* 2;
603 p
+= mode_sense_page(req
, page
, p
);
606 p
+= mode_sense_page(req
, 0x08, p
);
607 p
+= mode_sense_page(req
, 0x2a, p
);
612 outbuf
[0] = buflen
- 4;
613 if (buflen
> req
->cmd
.xfer
)
614 buflen
= req
->cmd
.xfer
;
618 static int scsi_disk_emulate_read_toc(SCSIRequest
*req
, uint8_t *outbuf
)
620 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, req
->dev
);
621 BlockDriverState
*bdrv
= req
->dev
->dinfo
->bdrv
;
622 int start_track
, format
, msf
, toclen
;
625 msf
= req
->cmd
.buf
[1] & 2;
626 format
= req
->cmd
.buf
[2] & 0xf;
627 start_track
= req
->cmd
.buf
[6];
628 bdrv_get_geometry(bdrv
, &nb_sectors
);
629 DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track
, format
, msf
>> 1);
630 nb_sectors
/= s
->cluster_size
;
633 toclen
= cdrom_read_toc(nb_sectors
, outbuf
, msf
, start_track
);
636 /* multi session : only a single session defined */
638 memset(outbuf
, 0, 12);
644 toclen
= cdrom_read_toc_raw(nb_sectors
, outbuf
, msf
, start_track
);
649 if (toclen
> req
->cmd
.xfer
)
650 toclen
= req
->cmd
.xfer
;
654 static int scsi_disk_emulate_command(SCSIRequest
*req
, uint8_t *outbuf
)
656 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, req
->dev
);
657 BlockDriverState
*bdrv
= req
->dev
->dinfo
->bdrv
;
661 switch (req
->cmd
.buf
[0]) {
662 case TEST_UNIT_READY
:
663 if (!bdrv_is_inserted(bdrv
))
667 if (req
->cmd
.xfer
< 4)
668 goto illegal_request
;
669 memset(outbuf
, 0, 4);
671 if (req
->dev
->sense
.key
== NOT_READY
&& req
->cmd
.xfer
>= 18) {
672 memset(outbuf
, 0, 18);
675 /* asc 0x3a, ascq 0: Medium not present */
681 outbuf
[2] = req
->dev
->sense
.key
;
682 scsi_dev_clear_sense(req
->dev
);
685 buflen
= scsi_disk_emulate_inquiry(req
, outbuf
);
687 goto illegal_request
;
691 buflen
= scsi_disk_emulate_mode_sense(req
, outbuf
);
693 goto illegal_request
;
696 buflen
= scsi_disk_emulate_read_toc(req
, outbuf
);
698 goto illegal_request
;
701 if (req
->cmd
.buf
[1] & 1)
702 goto illegal_request
;
705 if (req
->cmd
.buf
[1] & 3)
706 goto illegal_request
;
709 if (req
->cmd
.buf
[1] & 1)
710 goto illegal_request
;
713 if (req
->cmd
.buf
[1] & 3)
714 goto illegal_request
;
717 if (bdrv_get_type_hint(bdrv
) == BDRV_TYPE_CDROM
&& (req
->cmd
.buf
[4] & 2)) {
718 /* load/eject medium */
719 bdrv_eject(bdrv
, !(req
->cmd
.buf
[4] & 1));
722 case ALLOW_MEDIUM_REMOVAL
:
723 bdrv_set_locked(bdrv
, req
->cmd
.buf
[4] & 1);
726 /* The normal LEN field for this command is zero. */
727 memset(outbuf
, 0, 8);
728 bdrv_get_geometry(bdrv
, &nb_sectors
);
731 nb_sectors
/= s
->cluster_size
;
732 /* Returned value is the address of the last sector. */
734 /* Remember the new size for read/write sanity checking. */
735 s
->max_lba
= nb_sectors
;
736 /* Clip to 2TB, instead of returning capacity modulo 2TB. */
737 if (nb_sectors
> UINT32_MAX
)
738 nb_sectors
= UINT32_MAX
;
739 outbuf
[0] = (nb_sectors
>> 24) & 0xff;
740 outbuf
[1] = (nb_sectors
>> 16) & 0xff;
741 outbuf
[2] = (nb_sectors
>> 8) & 0xff;
742 outbuf
[3] = nb_sectors
& 0xff;
745 outbuf
[6] = s
->cluster_size
* 2;
749 case SYNCHRONIZE_CACHE
:
752 case GET_CONFIGURATION
:
753 memset(outbuf
, 0, 8);
754 /* ??? This should probably return much more information. For now
755 just return the basic header indicating the CD-ROM profile. */
756 outbuf
[7] = 8; // CD-ROM
759 case SERVICE_ACTION_IN
:
760 /* Service Action In subcommands. */
761 if ((req
->cmd
.buf
[1] & 31) == 0x10) {
762 DPRINTF("SAI READ CAPACITY(16)\n");
763 memset(outbuf
, 0, req
->cmd
.xfer
);
764 bdrv_get_geometry(bdrv
, &nb_sectors
);
767 nb_sectors
/= s
->cluster_size
;
768 /* Returned value is the address of the last sector. */
770 /* Remember the new size for read/write sanity checking. */
771 s
->max_lba
= nb_sectors
;
772 outbuf
[0] = (nb_sectors
>> 56) & 0xff;
773 outbuf
[1] = (nb_sectors
>> 48) & 0xff;
774 outbuf
[2] = (nb_sectors
>> 40) & 0xff;
775 outbuf
[3] = (nb_sectors
>> 32) & 0xff;
776 outbuf
[4] = (nb_sectors
>> 24) & 0xff;
777 outbuf
[5] = (nb_sectors
>> 16) & 0xff;
778 outbuf
[6] = (nb_sectors
>> 8) & 0xff;
779 outbuf
[7] = nb_sectors
& 0xff;
782 outbuf
[10] = s
->cluster_size
* 2;
784 /* Protection, exponent and lowest lba field left blank. */
785 buflen
= req
->cmd
.xfer
;
788 DPRINTF("Unsupported Service Action In\n");
789 goto illegal_request
;
791 if (req
->cmd
.xfer
< 16)
792 goto illegal_request
;
793 memset(outbuf
, 0, 16);
798 goto illegal_request
;
800 scsi_req_set_status(req
, GOOD
, NO_SENSE
);
804 scsi_req_set_status(req
, CHECK_CONDITION
, NOT_READY
);
808 scsi_req_set_status(req
, CHECK_CONDITION
, ILLEGAL_REQUEST
);
812 /* Execute a scsi command. Returns the length of the data expected by the
813 command. This will be Positive for data transfers from the device
814 (eg. disk reads), negative for transfers to the device (eg. disk writes),
815 and zero if the command does not transfer any data. */
817 static int32_t scsi_send_command(SCSIDevice
*d
, uint32_t tag
,
818 uint8_t *buf
, int lun
)
820 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, d
);
831 r
= scsi_find_request(s
, tag
);
833 BADF("Tag 0x%x already in use\n", tag
);
834 scsi_cancel_io(d
, tag
);
836 /* ??? Tags are not unique for different luns. We only implement a
837 single lun, so this should not matter. */
838 r
= scsi_new_request(d
, tag
, lun
);
839 outbuf
= (uint8_t *)r
->iov
.iov_base
;
841 DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun
, tag
, buf
[0]);
842 switch (command
>> 5) {
844 lba
= (uint64_t) buf
[3] | ((uint64_t) buf
[2] << 8) |
845 (((uint64_t) buf
[1] & 0x1f) << 16);
851 lba
= (uint64_t) buf
[5] | ((uint64_t) buf
[4] << 8) |
852 ((uint64_t) buf
[3] << 16) | ((uint64_t) buf
[2] << 24);
853 len
= buf
[8] | (buf
[7] << 8);
857 lba
= (uint64_t) buf
[9] | ((uint64_t) buf
[8] << 8) |
858 ((uint64_t) buf
[7] << 16) | ((uint64_t) buf
[6] << 24) |
859 ((uint64_t) buf
[5] << 32) | ((uint64_t) buf
[4] << 40) |
860 ((uint64_t) buf
[3] << 48) | ((uint64_t) buf
[2] << 56);
861 len
= buf
[13] | (buf
[12] << 8) | (buf
[11] << 16) | (buf
[10] << 24);
865 lba
= (uint64_t) buf
[5] | ((uint64_t) buf
[4] << 8) |
866 ((uint64_t) buf
[3] << 16) | ((uint64_t) buf
[2] << 24);
867 len
= buf
[9] | (buf
[8] << 8) | (buf
[7] << 16) | (buf
[6] << 24);
871 BADF("Unsupported command length, command %x\n", command
);
877 for (i
= 1; i
< cmdlen
; i
++) {
878 printf(" 0x%02x", buf
[i
]);
884 if (scsi_req_parse(&r
->req
, buf
) != 0) {
885 BADF("Unsupported command length, command %x\n", command
);
888 assert(r
->req
.cmd
.len
== cmdlen
);
889 assert(r
->req
.cmd
.lba
== lba
);
891 if (lun
|| buf
[1] >> 5) {
892 /* Only LUN 0 supported. */
893 DPRINTF("Unimplemented LUN %d\n", lun
? lun
: buf
[1] >> 5);
894 if (command
!= REQUEST_SENSE
&& command
!= INQUIRY
)
898 case TEST_UNIT_READY
:
908 case ALLOW_MEDIUM_REMOVAL
:
910 case SYNCHRONIZE_CACHE
:
912 case GET_CONFIGURATION
:
913 case SERVICE_ACTION_IN
:
915 rc
= scsi_disk_emulate_command(&r
->req
, outbuf
);
919 scsi_req_complete(&r
->req
);
920 scsi_remove_request(r
);
927 DPRINTF("Read (sector %" PRId64
", count %d)\n", lba
, len
);
928 if (lba
> s
->max_lba
)
930 r
->sector
= lba
* s
->cluster_size
;
931 r
->sector_count
= len
* s
->cluster_size
;
936 DPRINTF("Write (sector %" PRId64
", count %d)\n", lba
, len
);
937 if (lba
> s
->max_lba
)
939 r
->sector
= lba
* s
->cluster_size
;
940 r
->sector_count
= len
* s
->cluster_size
;
944 DPRINTF("Verify (sector %" PRId64
", count %d)\n", lba
, len
);
947 DPRINTF("Unknown SCSI command (%2.2x)\n", buf
[0]);
949 scsi_command_complete(r
, CHECK_CONDITION
, ILLEGAL_REQUEST
);
952 scsi_command_complete(r
, CHECK_CONDITION
, HARDWARE_ERROR
);
955 if (r
->sector_count
== 0 && r
->iov
.iov_len
== 0) {
956 scsi_command_complete(r
, GOOD
, NO_SENSE
);
958 len
= r
->sector_count
* 512 + r
->iov
.iov_len
;
962 if (!r
->sector_count
)
963 r
->sector_count
= -1;
968 static void scsi_destroy(SCSIDevice
*dev
)
970 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, dev
);
973 while (!QTAILQ_EMPTY(&s
->qdev
.requests
)) {
974 r
= DO_UPCAST(SCSIDiskReq
, req
, QTAILQ_FIRST(&s
->qdev
.requests
));
975 scsi_remove_request(r
);
977 drive_uninit(s
->qdev
.dinfo
);
980 static int scsi_disk_initfn(SCSIDevice
*dev
)
982 SCSIDiskState
*s
= DO_UPCAST(SCSIDiskState
, qdev
, dev
);
985 if (!s
->qdev
.dinfo
|| !s
->qdev
.dinfo
->bdrv
) {
986 qemu_error("scsi-disk: drive property not set\n");
990 if (bdrv_get_type_hint(s
->qdev
.dinfo
->bdrv
) == BDRV_TYPE_CDROM
) {
995 s
->qdev
.blocksize
= 512 * s
->cluster_size
;
996 s
->qdev
.type
= TYPE_DISK
;
997 bdrv_get_geometry(s
->qdev
.dinfo
->bdrv
, &nb_sectors
);
998 nb_sectors
/= s
->cluster_size
;
1001 s
->max_lba
= nb_sectors
;
1002 qemu_add_vm_change_state_handler(scsi_dma_restart_cb
, s
);
1006 static SCSIDeviceInfo scsi_disk_info
= {
1007 .qdev
.name
= "scsi-disk",
1008 .qdev
.desc
= "virtual scsi disk or cdrom",
1009 .qdev
.size
= sizeof(SCSIDiskState
),
1010 .init
= scsi_disk_initfn
,
1011 .destroy
= scsi_destroy
,
1012 .send_command
= scsi_send_command
,
1013 .read_data
= scsi_read_data
,
1014 .write_data
= scsi_write_data
,
1015 .cancel_io
= scsi_cancel_io
,
1016 .get_buf
= scsi_get_buf
,
1017 .qdev
.props
= (Property
[]) {
1018 DEFINE_PROP_DRIVE("drive", SCSIDiskState
, qdev
.dinfo
),
1019 DEFINE_PROP_END_OF_LIST(),
1023 static void scsi_disk_register_devices(void)
1025 scsi_qdev_register(&scsi_disk_info
);
1027 device_init(scsi_disk_register_devices
)