Revision 5dd90e2a

b/hw/scsi-bus.c
441 441
        [ REWIND                   ] = "REWIND",
442 442
        [ REPORT_DENSITY_SUPPORT   ] = "REPORT_DENSITY_SUPPORT",
443 443
        [ GET_CONFIGURATION        ] = "GET_CONFIGURATION",
444
        [ SERVICE_ACTION_IN        ] = "SERVICE_ACTION_IN",
444 445
        [ LOAD_UNLOAD              ] = "LOAD_UNLOAD",
445 446
        [ SET_CD_SPEED             ] = "SET_CD_SPEED",
446 447
        [ BLANK                    ] = "BLANK",
b/hw/scsi-defs.h
100 100
#define REWIND 0x01
101 101
#define REPORT_DENSITY_SUPPORT 0x44
102 102
#define GET_CONFIGURATION 0x46
103
#define SERVICE_ACTION_IN 0x9e
103 104
#define LOAD_UNLOAD 0xa6
104 105
#define SET_CD_SPEED 0xbb
105 106
#define BLANK 0xa1
b/hw/scsi-disk.c
756 756
        outbuf[7] = 8; // CD-ROM
757 757
        buflen = 8;
758 758
        break;
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);
765
            if (!nb_sectors)
766
                goto not_ready;
767
            nb_sectors /= s->cluster_size;
768
            /* Returned value is the address of the last sector.  */
769
            nb_sectors--;
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;
780
            outbuf[8] = 0;
781
            outbuf[9] = 0;
782
            outbuf[10] = s->cluster_size * 2;
783
            outbuf[11] = 0;
784
            /* Protection, exponent and lowest lba field left blank. */
785
            buflen = req->cmd.xfer;
786
            break;
787
        }
788
        DPRINTF("Unsupported Service Action In\n");
789
        goto illegal_request;
759 790
    default:
760 791
        goto illegal_request;
761 792
    }
......
780 811
                                 uint8_t *buf, int lun)
781 812
{
782 813
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
783
    uint64_t nb_sectors;
784 814
    uint64_t lba;
785 815
    uint32_t len;
786 816
    int cmdlen;
......
873 903
    case SYNCHRONIZE_CACHE:
874 904
    case READ_TOC:
875 905
    case GET_CONFIGURATION:
906
    case SERVICE_ACTION_IN:
876 907
        rc = scsi_disk_emulate_command(&r->req, outbuf);
877 908
        if (rc > 0) {
878 909
            r->iov.iov_len = rc;
......
901 932
        r->sector_count = len * s->cluster_size;
902 933
        is_write = 1;
903 934
        break;
904
    case 0x9e:
905
        /* Service Action In subcommands. */
906
        if ((buf[1] & 31) == 0x10) {
907
            DPRINTF("SAI READ CAPACITY(16)\n");
908
            memset(outbuf, 0, len);
909
            bdrv_get_geometry(s->qdev.dinfo->bdrv, &nb_sectors);
910
            nb_sectors /= s->cluster_size;
911
            /* Returned value is the address of the last sector.  */
912
            if (nb_sectors) {
913
                nb_sectors--;
914
                /* Remember the new size for read/write sanity checking. */
915
                s->max_lba = nb_sectors;
916
                outbuf[0] = (nb_sectors >> 56) & 0xff;
917
                outbuf[1] = (nb_sectors >> 48) & 0xff;
918
                outbuf[2] = (nb_sectors >> 40) & 0xff;
919
                outbuf[3] = (nb_sectors >> 32) & 0xff;
920
                outbuf[4] = (nb_sectors >> 24) & 0xff;
921
                outbuf[5] = (nb_sectors >> 16) & 0xff;
922
                outbuf[6] = (nb_sectors >> 8) & 0xff;
923
                outbuf[7] = nb_sectors & 0xff;
924
                outbuf[8] = 0;
925
                outbuf[9] = 0;
926
                outbuf[10] = s->cluster_size * 2;
927
                outbuf[11] = 0;
928
                /* Protection, exponent and lowest lba field left blank. */
929
                r->iov.iov_len = len;
930
            } else {
931
                scsi_command_complete(r, CHECK_CONDITION, NOT_READY);
932
                return 0;
933
            }
934
            break;
935
        }
936
        DPRINTF("Unsupported Service Action In\n");
937
        goto fail;
938 935
    case 0xa0:
939 936
        DPRINTF("Report LUNs (len %d)\n", len);
940 937
        if (len < 16)

Also available in: Unified diff