Changeset 39100 in vbox
- Timestamp:
- Oct 24, 2011 9:12:07 PM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 74532
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevATA.cpp
r39036 r39100 1894 1894 PSTAMPROFILEADV pProf = NULL; 1895 1895 1896 cbTransfer = s->cbElementaryTransfer;1896 cbTransfer = RT_MIN(s->cbElementaryTransfer, s->cbIOBuffer); 1897 1897 1898 1898 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE) … … 1918 1918 1919 1919 if (pProf) { STAM_PROFILE_ADV_START(pProf, b); } 1920 if (cbTransfer > SCSI_MAX_BUFFER_SIZE) 1920 if ( cbTransfer > SCSI_MAX_BUFFER_SIZE 1921 || s->cbElementaryTransfer > s->cbIOBuffer) 1921 1922 { 1922 1923 /* Linux accepts commands with up to 100KB of data, but expects … … 1926 1927 uint32_t iATAPILBA, cSectors, cReqSectors, cbCurrTX; 1927 1928 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer); 1929 uint32_t cSectorsMax; /**< Maximum amount of sectors to read without exceeding the I/O buffer. */ 1930 1931 Assert(s->cbATAPISector); 1932 cSectorsMax = cbTransfer / s->cbATAPISector; 1933 Assert(cSectorsMax * s->cbATAPISector <= s->cbIOBuffer); 1928 1934 1929 1935 switch (s->aATAPICmd[0]) … … 1960 1966 return false; 1961 1967 } 1968 cSectorsMax = RT_MIN(cSectorsMax, cSectors); 1962 1969 memcpy(aATAPICmd, s->aATAPICmd, ATAPI_PACKET_SIZE); 1963 1970 cReqSectors = 0; 1964 for (uint32_t i = cSectors ; i > 0; i -= cReqSectors)1971 for (uint32_t i = cSectorsMax; i > 0; i -= cReqSectors) 1965 1972 { 1966 1973 if (i * s->cbATAPISector > SCSI_MAX_BUFFER_SIZE) … … 1997 2004 pbBuf += s->cbATAPISector * cReqSectors; 1998 2005 } 2006 2007 if (RT_SUCCESS(rc)) 2008 { 2009 /* Adjust ATAPI command for the next call. */ 2010 switch (s->aATAPICmd[0]) 2011 { 2012 case SCSI_READ_10: 2013 case SCSI_WRITE_10: 2014 case SCSI_WRITE_AND_VERIFY_10: 2015 ataH2BE_U32(s->aATAPICmd + 2, iATAPILBA); 2016 ataH2BE_U16(s->aATAPICmd + 7, cSectors - cSectorsMax); 2017 break; 2018 case SCSI_READ_12: 2019 case SCSI_WRITE_12: 2020 ataH2BE_U32(s->aATAPICmd + 2, iATAPILBA); 2021 ataH2BE_U32(s->aATAPICmd + 6, cSectors - cSectorsMax); 2022 break; 2023 case SCSI_READ_CD: 2024 ataH2BE_U32(s->aATAPICmd + 2, iATAPILBA); 2025 ataH2BE_U24(s->aATAPICmd + 6, cSectors - cSectorsMax); 2026 break; 2027 case SCSI_READ_CD_MSF: 2028 ataLBA2MSF(s->aATAPICmd + 3, iATAPILBA); 2029 ataLBA2MSF(s->aATAPICmd + 6, iATAPILBA + cSectors - cSectorsMax); 2030 break; 2031 default: 2032 AssertMsgFailed(("Don't know how to split command %#04x\n", s->aATAPICmd[0])); 2033 if (s->cErrors++ < MAX_LOG_REL_ERRORS) 2034 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM passthrough split error\n", s->iLUN)); 2035 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE); 2036 return false; 2037 } 2038 } 1999 2039 } 2000 2040 else … … 2026 2066 { 2027 2067 Assert(cbTransfer <= s->cbTotalTransfer); 2028 /* Reply with the same amount of data as the real drive. */ 2029 s->cbTotalTransfer = cbTransfer; 2030 /* The initial buffer end value has been set up based on the total 2031 * transfer size. But the I/O buffer size limits what can actually be 2032 * done in one transfer, so set the actual value of the buffer end. */ 2033 s->cbElementaryTransfer = cbTransfer; 2068 /* 2069 * Reply with the same amount of data as the real drive 2070 * but only if the command wasn't splitted. 2071 */ 2072 if (s->cbElementaryTransfer < s->cbIOBuffer) 2073 s->cbTotalTransfer = cbTransfer; 2074 2034 2075 if (s->aATAPICmd[0] == SCSI_INQUIRY) 2035 2076 { … … 2074 2115 Log3(("ATAPI PT data read (%d): %.*Rhxs\n", cbTransfer, cbTransfer, s->CTX_SUFF(pbIOBuffer))); 2075 2116 } 2076 s->iSourceSink = ATAFN_SS_NULL; 2077 atapiCmdOK(s); 2117 2118 /* The initial buffer end value has been set up based on the total 2119 * transfer size. But the I/O buffer size limits what can actually be 2120 * done in one transfer, so set the actual value of the buffer end. */ 2121 s->cbElementaryTransfer = cbTransfer; 2122 if (cbTransfer >= s->cbTotalTransfer) 2123 { 2124 s->iSourceSink = ATAFN_SS_NULL; 2125 atapiCmdOK(s); 2126 } 2078 2127 } 2079 2128 else … … 3582 3631 break; 3583 3632 sendcmd: 3584 /* Send a command to the drive, passing data in/out as required. */ 3633 /* 3634 * Send a command to the drive, passing data in/out as required. 3635 * Commands which exceed the I/O buffer size are splitted below 3636 * or aborted if splitting is not implemented. 3637 */ 3585 3638 Log2(("ATAPI PT: max size %d\n", cbTransfer)); 3586 if (cbTransfer > s->cbIOBuffer) 3587 { 3588 /* Rate limited logging, one log line every 5 seconds. */ 3589 static uint64_t uLastLogTS = 0; 3590 if (RTTimeMilliTS() >= uLastLogTS + 5000) 3591 { 3592 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM passthrough command attempted to exceed buffer size, blocked\n", s->iLUN)); 3593 uLastLogTS = RTTimeMilliTS(); 3594 } 3595 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET); 3596 } 3597 else 3598 { 3599 if (cbTransfer == 0) 3600 uTxDir = PDMBLOCKTXDIR_NONE; 3601 ataStartTransfer(s, cbTransfer, uTxDir, ATAFN_BT_ATAPI_PASSTHROUGH_CMD, ATAFN_SS_ATAPI_PASSTHROUGH, true); 3602 } 3639 if (cbTransfer == 0) 3640 uTxDir = PDMBLOCKTXDIR_NONE; 3641 ataStartTransfer(s, cbTransfer, uTxDir, ATAFN_BT_ATAPI_PASSTHROUGH_CMD, ATAFN_SS_ATAPI_PASSTHROUGH, true); 3603 3642 } 3604 3643 }
Note:
See TracChangeset
for help on using the changeset viewer.