Changeset 304 in vbox for trunk/src/VBox
- Timestamp:
- Jan 25, 2007 3:36:19 PM (18 years ago)
- svn:sync-xref-src-repo-rev:
- 17853
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevATA.cpp
r262 r304 435 435 static void ataExecuteDeviceDiagnosticSS(ATADevState *); 436 436 static void ataPacketSS(ATADevState *); 437 static void atapiGetConfigurationSS(ATADevState *); 437 438 static void atapiIdentifySS(ATADevState *); 438 439 static void atapiInquirySS(ATADevState *); … … 442 443 static void atapiReadSS(ATADevState *); 443 444 static void atapiReadCapacitySS(ATADevState *); 445 static void atapiReadDiscInformationSS(ATADevState *); 444 446 static void atapiReadTOCNormalSS(ATADevState *); 445 447 static void atapiReadTOCMultiSS(ATADevState *); 446 448 static void atapiReadTOCRawSS(ATADevState *); 449 static void atapiReadTrackInformationSS(ATADevState *); 447 450 static void atapiRequestSenseSS(ATADevState *); 448 451 static void atapiPassthroughSS(ATADevState *); … … 486 489 ATAFN_SS_EXECUTE_DEVICE_DIAGNOSTIC, 487 490 ATAFN_SS_PACKET, 491 ATAFN_SS_ATAPI_GET_CONFIGURATION, 488 492 ATAFN_SS_ATAPI_IDENTIFY, 489 493 ATAFN_SS_ATAPI_INQUIRY, … … 493 497 ATAFN_SS_ATAPI_READ, 494 498 ATAFN_SS_ATAPI_READ_CAPACITY, 499 ATAFN_SS_ATAPI_READ_DISC_INFORMATION, 495 500 ATAFN_SS_ATAPI_READ_TOC_NORMAL, 496 501 ATAFN_SS_ATAPI_READ_TOC_MULTI, 497 502 ATAFN_SS_ATAPI_READ_TOC_RAW, 503 ATAFN_SS_ATAPI_READ_TRACK_INFORMATION, 498 504 ATAFN_SS_ATAPI_REQUEST_SENSE, 499 505 ATAFN_SS_ATAPI_PASSTHROUGH, … … 514 520 ataExecuteDeviceDiagnosticSS, 515 521 ataPacketSS, 522 atapiGetConfigurationSS, 516 523 atapiIdentifySS, 517 524 atapiInquirySS, … … 521 528 atapiReadSS, 522 529 atapiReadCapacitySS, 530 atapiReadDiscInformationSS, 523 531 atapiReadTOCNormalSS, 524 532 atapiReadTOCMultiSS, 525 533 atapiReadTOCRawSS, 534 atapiReadTrackInformationSS, 526 535 atapiRequestSenseSS, 527 536 atapiPassthroughSS … … 1760 1769 1761 1770 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE); 1762 Assert(s->cbElementaryTransfer <= 36);1771 Assert(s->cbElementaryTransfer <= 8); 1763 1772 ataH2BE_U32(pbBuf, s->cTotalSectors - 1); 1764 1773 ataH2BE_U32(pbBuf + 4, 2048); 1774 s->iSourceSink = ATAFN_SS_NULL; 1775 atapiCmdOK(s); 1776 } 1777 1778 1779 static void atapiReadDiscInformationSS(ATADevState *s) 1780 { 1781 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer); 1782 1783 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE); 1784 Assert(s->cbElementaryTransfer <= 34); 1785 memset(pbBuf, '\0', 34); 1786 ataH2BE_U16(pbBuf, 32); 1787 pbBuf[2] = (0 << 4) | (3 << 2) | (2 << 0); /* not erasable, complete session, complete disc */ 1788 pbBuf[3] = 1; /* number of first track */ 1789 pbBuf[4] = 1; /* number of sessions (LSB) */ 1790 pbBuf[5] = 1; /* first track number in last session (LSB) */ 1791 pbBuf[6] = 1; /* last track number in last session (LSB) */ 1792 pbBuf[7] = (0 << 7) | (0 << 6) | (1 << 5) | (0 << 2) | (0 << 0); /* disc id not valid, disc bar code not valid, unrestricted use, not dirty, not RW medium */ 1793 pbBuf[8] = 0; /* disc type = CD-ROM */ 1794 pbBuf[9] = 0; /* number of sessions (MSB) */ 1795 pbBuf[10] = 0; /* number of sessions (MSB) */ 1796 pbBuf[11] = 0; /* number of sessions (MSB) */ 1797 ataH2BE_U32(pbBuf + 16, 0x00ffffff); /* last session lead-in start time is not available */ 1798 ataH2BE_U32(pbBuf + 20, 0x00ffffff); /* last possible start time for lead-out is not available */ 1799 s->iSourceSink = ATAFN_SS_NULL; 1800 atapiCmdOK(s); 1801 } 1802 1803 1804 static void atapiReadTrackInformationSS(ATADevState *s) 1805 { 1806 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer); 1807 1808 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE); 1809 Assert(s->cbElementaryTransfer <= 36); 1810 /* Accept address/number type of 1 only, and only track 1 exists. */ 1811 if ((s->aATAPICmd[1] & 0x03) != 1 || ataBE2H_U32(&s->aATAPICmd[2]) != 1) 1812 { 1813 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET); 1814 return; 1815 } 1816 memset(pbBuf, '\0', 36); 1817 ataH2BE_U16(pbBuf, 34); 1818 pbBuf[2] = 1; /* track number (LSB) */ 1819 pbBuf[3] = 1; /* session number (LSB) */ 1820 pbBuf[5] = (0 << 5) | (0 << 4) | (4 << 0); /* not damaged, primary copy, data track */ 1821 pbBuf[6] = (0 << 7) | (0 << 6) | (0 << 5) | (0 << 6) | (1 << 0); /* not reserved track, not blank, not packet writing, not fixed packet, data mode 1 */ 1822 pbBuf[7] = (0 << 1) | (0 << 0); /* last recorded address not valid, next recordable address not valid */ 1823 ataH2BE_U32(pbBuf + 8, 0); /* track start address is 0 */ 1824 ataH2BE_U32(pbBuf + 24, s->cTotalSectors); /* track size */ 1825 pbBuf[32] = 0; /* track number (MSB) */ 1826 pbBuf[33] = 0; /* session number (MSB) */ 1827 s->iSourceSink = ATAFN_SS_NULL; 1828 atapiCmdOK(s); 1829 } 1830 1831 1832 static void atapiGetConfigurationSS(ATADevState *s) 1833 { 1834 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer); 1835 1836 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE); 1837 Assert(s->cbElementaryTransfer <= 32); 1838 /* Accept request type of 0 or 1 only, and only starting feature 0. */ 1839 if (((s->aATAPICmd[1] & 0x03) != 0 && (s->aATAPICmd[1] & 0x03) != 1) || ataBE2H_U16(&s->aATAPICmd[2]) != 0) 1840 { 1841 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET); 1842 return; 1843 } 1844 memset(pbBuf, '\0', 32); 1845 ataH2BE_U32(pbBuf, 12); 1846 ataH2BE_U16(pbBuf + 6, 8); /* current profile: cd-rom read-only */ 1847 1848 ataH2BE_U16(pbBuf + 8, 0); /* feature 0: list of profiles supported */ 1849 pbBuf[10] = (0 << 2) | (1 << 1) | (1 || 0); /* version 0, persistent, current */ 1850 pbBuf[11] = 4; /* additional bytes for profiles */ 1851 ataH2BE_U16(pbBuf + 12, 8); /* profile: cd-rom read-only */ 1852 pbBuf[14] = (1 << 0); /* current profile */ 1765 1853 s->iSourceSink = ATAFN_SS_NULL; 1766 1854 atapiCmdOK(s); … … 1827 1915 1828 1916 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE); 1829 Assert(s->cbElementaryTransfer <= 28);1830 ataH2BE_U16(&pbBuf[0], 28 + 6);1917 Assert(s->cbElementaryTransfer <= 40); 1918 ataH2BE_U16(&pbBuf[0], 38); 1831 1919 pbBuf[2] = 0x70; 1832 1920 pbBuf[3] = 0; … … 1837 1925 1838 1926 pbBuf[8] = 0x2a; 1839 pbBuf[9] = 0x12; 1840 pbBuf[10] = 0x00; 1841 pbBuf[11] = 0x00; 1842 1843 pbBuf[12] = 0x70; 1844 pbBuf[13] = 3 << 5; 1845 pbBuf[14] = (1 << 0) | (1 << 3) | (1 << 5); 1927 pbBuf[9] = 30; /* page length */ 1928 pbBuf[10] = 0x08; /* DVD-ROM read support */ 1929 pbBuf[11] = 0x00; /* no write support */ 1930 /* The following claims we support audio play. This is obviously false, 1931 * but the Linux generic CDROM support makes many features depend on this 1932 * capability. If it's not set, this causes many things to be disabled. */ 1933 pbBuf[12] = 0x71; /* multisession support, mode 2 form 1/2 support, audio play */ 1934 pbBuf[13] = 0x00; /* no subchannel reads supported */ 1935 pbBuf[14] = (1 << 0) | (1 << 3) | (1 << 5); /* lock supported, eject supported, tray type loading mechanism */ 1846 1936 if (s->pDrvMount->pfnIsLocked(s->pDrvMount)) 1847 pbBuf[6] |= 1 << 1; 1848 pbBuf[15] = 0x00; 1849 ataH2BE_U16(&pbBuf[16], 706); 1850 pbBuf[18] = 0; 1851 pbBuf[19] = 2; 1852 ataH2BE_U16(&pbBuf[20], 512); 1853 ataH2BE_U16(&pbBuf[22], 706); 1854 pbBuf[24] = 0; 1855 pbBuf[25] = 0; 1856 pbBuf[26] = 0; 1857 pbBuf[27] = 0; 1937 pbBuf[14] |= 1 << 1; /* report lock state */ 1938 pbBuf[15] = 0; /* no subchannel reads supported, no separate audio volume control, no changer etc. */ 1939 ataH2BE_U16(&pbBuf[16], 5632); /* (obsolete) claim 32x speed support */ 1940 ataH2BE_U16(&pbBuf[18], 2); /* number of audio volume levels */ 1941 ataH2BE_U16(&pbBuf[20], s->cbIOBuffer / _1K); /* buffer size supported in Kbyte */ 1942 ataH2BE_U16(&pbBuf[22], 5632); /* (obsolete) current read speed 32x */ 1943 pbBuf[24] = 0; /* reserved */ 1944 pbBuf[25] = 0; /* reserved for digital audio (see idx 15) */ 1945 ataH2BE_U16(&pbBuf[26], 0); /* (obsolete) maximum write speed */ 1946 ataH2BE_U16(&pbBuf[28], 0); /* (obsolete) current write speed */ 1947 ataH2BE_U16(&pbBuf[30], 0); /* copy management revision supported 0=no CSS */ 1948 pbBuf[32] = 0; /* reserved */ 1949 pbBuf[33] = 0; /* reserved */ 1950 pbBuf[34] = 0; /* reserved */ 1951 pbBuf[35] = 1; /* rotation control CAV */ 1952 ataH2BE_U16(&pbBuf[36], 0); /* current write speed */ 1953 ataH2BE_U16(&pbBuf[38], 0); /* number of write speed performance descriptors */ 1858 1954 s->iSourceSink = ATAFN_SS_NULL; 1859 1955 atapiCmdOK(s); … … 1921 2017 { 1922 2018 *q++ = 0; /* reserved */ 1923 *q++ = 0; /* minute */ 1924 *q++ = 2; /* second */ 1925 *q++ = 0; /* frame */ 2019 ataLBA2MSF(q, 0); 2020 q += 3; 1926 2021 } 1927 2022 else … … 1934 2029 /* lead out track */ 1935 2030 *q++ = 0; /* reserved */ 1936 *q++ = 0x1 6; /* ADR, control */2031 *q++ = 0x14; /* ADR, control */ 1937 2032 *q++ = 0xaa; /* track number */ 1938 2033 *q++ = 0; /* reserved */ … … 1960 2055 { 1961 2056 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer); 2057 bool fMSF; 1962 2058 1963 2059 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE); 1964 2060 Assert(s->cbElementaryTransfer <= 12); 2061 fMSF = (s->aATAPICmd[1] >> 1) & 1; 1965 2062 /* multi session: only a single session defined */ 2063 /** @todo double-check this stuff against what a real drive says for a CD-ROM (not a CD-R) with only a single data session. Maybe solve the problem with "cdrdao read-toc" not being able to figure out whether numbers are in BCD or hex. */ 1966 2064 memset(pbBuf, 0, 12); 1967 2065 pbBuf[1] = 0x0a; 1968 2066 pbBuf[2] = 0x01; 1969 2067 pbBuf[3] = 0x01; 2068 pbBuf[5] = 0x14; /* ADR, control */ 2069 pbBuf[6] = 1; /* first track in last complete session */ 2070 if (fMSF) 2071 { 2072 pbBuf[8] = 0; /* reserved */ 2073 ataLBA2MSF(&pbBuf[9], 0); 2074 } 2075 else 2076 { 2077 /* sector 0 */ 2078 ataH2BE_U32(pbBuf + 8, 0); 2079 } 1970 2080 s->iSourceSink = ATAFN_SS_NULL; 1971 2081 atapiCmdOK(s); … … 1990 2100 *q++ = 0x14; /* data track */ 1991 2101 *q++ = 0; /* track number */ 1992 *q++ = 0xa0; /* lead-in*/2102 *q++ = 0xa0; /* first track in program area */ 1993 2103 *q++ = 0; /* min */ 1994 2104 *q++ = 0; /* sec */ … … 1996 2106 *q++ = 0; 1997 2107 *q++ = 1; /* first track */ 1998 *q++ = 0x00; /* disk type */1999 *q++ = 0 x00;2108 *q++ = 0x00; /* disk type CD-DA or CD data */ 2109 *q++ = 0; 2000 2110 2001 2111 *q++ = 1; /* session number */ 2002 2112 *q++ = 0x14; /* data track */ 2003 2113 *q++ = 0; /* track number */ 2004 *q++ = 0xa1; 2114 *q++ = 0xa1; /* last track in program area */ 2005 2115 *q++ = 0; /* min */ 2006 2116 *q++ = 0; /* sec */ … … 2008 2118 *q++ = 0; 2009 2119 *q++ = 1; /* last track */ 2010 *q++ = 0 x00;2011 *q++ = 0 x00;2120 *q++ = 0; 2121 *q++ = 0; 2012 2122 2013 2123 *q++ = 1; /* session number */ … … 2037 2147 *q++ = 0; /* sec */ 2038 2148 *q++ = 0; /* frame */ 2039 *q++ = 0; 2040 *q++ = 0; 2041 *q++ = 0; 2042 *q++ = 0; 2149 if (fMSF) 2150 { 2151 *q++ = 0; /* reserved */ 2152 ataLBA2MSF(q, 0); 2153 q += 3; 2154 } 2155 else 2156 { 2157 /* sector 0 */ 2158 ataH2BE_U32(q, 0); 2159 q += 4; 2160 } 2043 2161 2044 2162 cbSize = q - pbBuf; … … 2089 2207 break; 2090 2208 case SCSI_MODEPAGE_CD_STATUS: 2091 ataStartTransfer(s, RT_MIN(cbMax, 28), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_MODE_SENSE_CD_STATUS, true);2209 ataStartTransfer(s, RT_MIN(cbMax, 40), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_MODE_SENSE_CD_STATUS, true); 2092 2210 break; 2093 2211 default: … … 2312 2430 } 2313 2431 cbMax = ataBE2H_U16(pbPacket + 7); 2314 format = pbPacket[9] >> 6; 2432 /* SCSI MMC-3 spec says format is at offset 2 (lower 4 bits), 2433 * but Linux kernel uses offset 9 (topmost 2 bits). Hope that 2434 * the other field is clear... */ 2435 format = (pbPacket[2] & 0xf) | (pbPacket[9] >> 6); 2315 2436 switch (format) 2316 2437 { … … 2344 2465 } 2345 2466 ataStartTransfer(s, 8, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_CAPACITY, true); 2467 break; 2468 case SCSI_READ_DISC_INFORMATION: 2469 if (s->cNotifiedMediaChange > 0) 2470 { 2471 s->cNotifiedMediaChange-- ; 2472 atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */ 2473 break; 2474 } 2475 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount)) 2476 { 2477 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT); 2478 break; 2479 } 2480 cbMax = ataBE2H_U16(pbPacket + 7); 2481 ataStartTransfer(s, RT_MIN(cbMax, 34), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_DISC_INFORMATION, true); 2482 break; 2483 case SCSI_READ_TRACK_INFORMATION: 2484 if (s->cNotifiedMediaChange > 0) 2485 { 2486 s->cNotifiedMediaChange-- ; 2487 atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */ 2488 break; 2489 } 2490 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount)) 2491 { 2492 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT); 2493 break; 2494 } 2495 cbMax = ataBE2H_U16(pbPacket + 7); 2496 ataStartTransfer(s, RT_MIN(cbMax, 36), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TRACK_INFORMATION, true); 2497 break; 2498 case SCSI_GET_CONFIGURATION: 2499 if (s->cNotifiedMediaChange > 0) 2500 { 2501 s->cNotifiedMediaChange-- ; 2502 atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */ 2503 break; 2504 } 2505 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount)) 2506 { 2507 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT); 2508 break; 2509 } 2510 cbMax = ataBE2H_U16(pbPacket + 7); 2511 ataStartTransfer(s, RT_MIN(cbMax, 32), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_GET_CONFIGURATION, true); 2346 2512 break; 2347 2513 case SCSI_INQUIRY: … … 4418 4584 #endif /* IN_GC */ 4419 4585 4586 if (cbTransfer) 4587 Log3(("%s: addr=%#x val=%.*Vhxs\n", __FUNCTION__, Port, cbTransfer, s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart)); 4420 4588 s->iIOBufferPIODataStart += cbTransfer; 4421 4589 *pGCPtrDst = (RTGCPTR)((RTGCUINTPTR)GCDst + cbTransfer); … … 4473 4641 #endif /* IN_GC */ 4474 4642 4643 if (cbTransfer) 4644 Log3(("%s: addr=%#x val=%.*Vhxs\n", __FUNCTION__, Port, cbTransfer, s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart)); 4475 4645 s->iIOBufferPIODataStart += cbTransfer; 4476 4646 *pGCPtrSrc = (RTGCPTR)((RTGCUINTPTR)GCSrc + cbTransfer);
Note:
See TracChangeset
for help on using the changeset viewer.