Revision 5dd90e2a hw/scsi-disk.c
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