Changeset 43642 in vbox
- Timestamp:
- Oct 15, 2012 1:35:04 PM (12 years ago)
- File:
-
- 1 edited
-
trunk/src/VBox/Devices/Storage/DevBusLogic.cpp (modified) (38 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevBusLogic.cpp
r43472 r43642 16 16 */ 17 17 18 /* Implemented looking at the driver source in the linux kernel (drivers/scsi/BusLogic.[ch]). 19 * See also: http://www.drdobbs.com/184410111 20 */ 18 /* Based on the Multi-Master Ultra SCSI Systems Technical Reference Manual */ 21 19 22 20 /******************************************************************************* 23 21 * Header Files * 24 22 *******************************************************************************/ 25 //#define DEBUG 23 26 24 #define LOG_GROUP LOG_GROUP_DEV_BUSLOGIC 27 25 #include <VBox/vmm/pdmdev.h> … … 69 67 #define BUSLOGIC_SAVED_STATE_MINOR_PRE_ERROR_HANDLING 1 70 68 71 /** The duration of software-initiated reset. Not documented, set to 500 us. */72 #define BUSLOGIC_RESET_DURATION_NS ( 500*1000)69 /** The duration of software-initiated reset. Not documented, set to 2 ms. */ 70 #define BUSLOGIC_RESET_DURATION_NS (2000*1000) 73 71 74 72 /** … … 270 268 AssertCompileSize(HostAdapterLocalRam, 256); 271 269 270 /* Compatible ISA base I/O port addresses. Disabled if zero. */ 271 #define NUM_ISA_BASES 8 272 #define MAX_ISA_BASE (NUM_ISA_BASES - 1) 273 #define ISA_BASE_DISABLED 6 274 275 static uint16_t aISABases[NUM_ISA_BASES] = { 276 0x330, 0x334, 0x230, 0x234, 0x130, 0x134, 0, 0 277 }; 278 272 279 /** Pointer to a task state structure. */ 273 280 typedef struct BUSLOGICTASKSTATE *PBUSLOGICTASKSTATE; … … 338 345 bool fIRQEnabled; 339 346 /** Flag whether the ISA I/O port range is disabled 340 * to prevent the BIO s to access the device. */341 bool fISAEnabled; 347 * to prevent the BIOS to access the device. */ 348 bool fISAEnabled; //@todo: unused, to be removed 342 349 /** Flag whether 24-bit mailboxes are in use (default is 32-bit). */ 343 350 bool fMbxIs24Bit; //@todo: save? 344 351 /** ISA I/O port base (encoded in FW-compatible format). */ 345 uint8_t uISABaseCode; //@todo: save? 346 352 uint8_t uISABaseCode; 353 354 /** ISA I/O port base (disabled if zero). */ 355 RTIOPORT IOISABase; //@todo: recalculate when restoring state 347 356 /** Default ISA I/O port base in FW-compatible format. */ 348 357 uint8_t uDefaultISABaseCode; 349 350 /** ISA I/O port base (disabled if zero). */351 uint16_t uISABase; //@todo: recalculate when restoring state352 358 353 359 /** Number of mailboxes the guest set up. */ … … 795 801 #define PDMILEDPORTS_2_PBUSLOGIC(pInterface) ( (PBUSLOGIC)((uintptr_t)(pInterface) - RT_OFFSETOF(BUSLOGIC, ILeds)) ) 796 802 803 static int buslogicRegisterISARange(PBUSLOGIC pBusLogic, uint8_t uBaseCode); 804 797 805 /** 798 806 * Assert IRQ line of the BusLogic adapter. … … 899 907 * @returns VBox status code. 900 908 * @param pBusLogic Pointer to the BusLogic device instance. 901 */ 902 static int buslogicHwReset(PBUSLOGIC pBusLogic) 909 * @param fResetIO Flag determining whether ISA I/O should be reset. 910 */ 911 static int buslogicHwReset(PBUSLOGIC pBusLogic, bool fResetIO) 903 912 { 904 913 LogFlowFunc(("pBusLogic=%#p\n", pBusLogic)); … … 913 922 pBusLogic->cbCommandParametersLeft = 0; 914 923 pBusLogic->fIRQEnabled = true; 915 pBusLogic->fISAEnabled = true;916 924 pBusLogic->uMailboxOutgoingPositionCurrent = 0; 917 925 pBusLogic->uMailboxIncomingPositionCurrent = 0; 918 926 927 /* Guest-initiated HBA reset does not affect ISA port I/O. */ 928 if (fResetIO) 929 { 930 buslogicRegisterISARange(pBusLogic, pBusLogic->uDefaultISABaseCode); 931 } 919 932 buslogicInitializeLocalRam(pBusLogic); 920 933 vboxscsiInitialize(&pBusLogic->VBoxSCSI); … … 965 978 pBusLogic->u64ResetTime = PDMDevHlpTMTimeVirtGetNano(pBusLogic->CTX_SUFF(pDevIns)); 966 979 967 buslogicHwReset(pBusLogic );980 buslogicHwReset(pBusLogic, false); 968 981 969 982 /* We set the diagnostic active in the status register. */ … … 1361 1374 /* It seems VMware does not provide valid information here too, lets do the same :) */ 1362 1375 pReply->InformationIsValid = 0; 1363 pReply->IsaIOPort = 0xff; /* Make it invalid. */1376 pReply->IsaIOPort = pBusLogic->uISABaseCode; 1364 1377 pReply->IRQ = PCIDevGetInterruptLine(&pBusLogic->dev); 1365 1378 pBusLogic->cbReplyParametersLeft = sizeof(ReplyInquirePCIHostAdapterInformation); … … 1368 1381 case BUSLOGICCOMMAND_MODIFY_IO_ADDRESS: 1369 1382 { 1383 /* Modify the ISA-compatible I/O port base. Note that this technically 1384 * violates the PCI spec, as this address is not reported through PCI. 1385 * However, it is required for compatibility with old drivers. 1386 */ 1387 #ifdef IN_RING3 1388 Log(("ISA I/O for PCI (code %x)\n", pBusLogic->aCommandBuffer[0])); 1389 buslogicRegisterISARange(pBusLogic, pBusLogic->aCommandBuffer[0]); 1370 1390 pBusLogic->cbReplyParametersLeft = 0; 1371 if (pBusLogic->aCommandBuffer[0] == 0x06)1372 {1373 Log(("Disabling ISA I/O ports.\n"));1374 pBusLogic->fISAEnabled = false;1375 }1376 1391 fSuppressIrq = true; 1377 1392 break; 1393 #else 1394 AssertMsgFailed(("Must never get here!\n")); 1395 #endif 1378 1396 } 1379 1397 case BUSLOGICCOMMAND_INQUIRE_BOARD_ID: … … 1410 1428 /* First pass - set the number of following parameter bytes. */ 1411 1429 pBusLogic->cbCommandParametersLeft = pBusLogic->aCommandBuffer[0]; 1412 Log(("Set HA options: %u bytes follow\n", pBusLogic-> aCommandBuffer[0]));1430 Log(("Set HA options: %u bytes follow\n", pBusLogic->cbCommandParametersLeft)); 1413 1431 } 1414 1432 else … … 1447 1465 //@todo: What should the DMA channel be? 1448 1466 pReply->fDmaChannel6 = 1; 1449 /* The IRQ is not necessarily representable in this structure. */ 1467 /* The PCI IRQ is not necessarily representable in this structure. 1468 * If that is the case, the guest likely won't function correctly, 1469 * therefore we log a warning. 1470 */ 1450 1471 switch (uPciIrq) { 1451 1472 case 9: pReply->fIrqChannel9 = 1; break; … … 1456 1477 case 15: pReply->fIrqChannel15 = 1; break; 1457 1478 default: 1458 Log (("Inquire configuration: PCI IRQ %d cannot be represented\n", uPciIrq));1479 LogRel(("Warning: PCI IRQ %d cannot be represented as ISA!\n", uPciIrq)); 1459 1480 break; 1460 1481 } … … 1463 1484 case BUSLOGICCOMMAND_INQUIRE_EXTENDED_SETUP_INFORMATION: 1464 1485 { 1486 /* Some Adaptec AHA-154x drivers (e.g. OS/2) execute this command and expect 1487 * it to fail. If it succeeds, the drivers refuse to load. However, some newer 1488 * Adaptec 154x models supposedly support it too?? 1489 */ 1490 1465 1491 /* The reply length is set by the guest and is found in the first byte of the command buffer. */ 1466 1492 pBusLogic->cbReplyParametersLeft = pBusLogic->aCommandBuffer[0]; … … 1486 1512 PReplyInquireSetupInformation pReply = (PReplyInquireSetupInformation)pBusLogic->aReplyBuffer; 1487 1513 memset(pReply, 0, sizeof(ReplyInquireSetupInformation)); 1514 pReply->cMailbox = pBusLogic->cMailbox; 1515 pReply->uSignature = 'B'; 1516 /* The 'D' signature prevents Adaptec's OS/2 drivers from getting too 1517 * friendly with BusLogic hardware and upsetting the HBA state. 1518 */ 1519 pReply->uCharacterD = 'D'; /* BusLogic model. */ 1520 pReply->uHostBusType = 'F'; /* PCI bus. */ 1488 1521 break; 1489 1522 } … … 1556 1589 pBusLogic->cbReplyParametersLeft = 8; 1557 1590 break; 1591 case BUSLOGICCOMMAND_INQUIRE_INSTALLED_DEVICES_ID_8_TO_15: 1592 /* See note about cheating above. */ 1593 memset(pBusLogic->aReplyBuffer, 0, 8); 1594 for (int i = 0; i < 8; ++i) 1595 { 1596 if (pBusLogic->aDeviceStates[i + 8].fPresent) 1597 pBusLogic->aReplyBuffer[i] = 1; 1598 } 1599 pBusLogic->cbReplyParametersLeft = 8; 1600 break; 1558 1601 case BUSLOGICCOMMAND_INQUIRE_TARGET_DEVICES: 1559 1602 { … … 1608 1651 pBusLogic->LocalRam.structured.autoSCSIData.uBusOffDelay = pBusLogic->aCommandBuffer[0]; 1609 1652 Log(("Bus-off time: %d\n", pBusLogic->aCommandBuffer[0])); 1653 break; 1654 } 1655 case BUSLOGICCOMMAND_SET_BUS_TRANSFER_RATE: 1656 { 1657 pBusLogic->cbReplyParametersLeft = 0; 1658 pBusLogic->LocalRam.structured.autoSCSIData.uDMATransferRate = pBusLogic->aCommandBuffer[0]; 1659 Log(("Bus transfer rate: %02X\n", pBusLogic->aCommandBuffer[0])); 1610 1660 break; 1611 1661 } … … 1817 1867 case BUSLOGICCOMMAND_SET_PREEMPT_TIME_ON_BUS: 1818 1868 case BUSLOGICCOMMAND_SET_TIME_OFF_BUS: 1869 case BUSLOGICCOMMAND_SET_BUS_TRANSFER_RATE: 1819 1870 pBusLogic->cbCommandParametersLeft = 1; 1820 1871 break; … … 1841 1892 else 1842 1893 { 1894 #ifndef IN_RING3 1895 /* This command must be executed in R3 as it rehooks the ISA I/O port. */ 1896 if (pBusLogic->uOperationCode == BUSLOGICCOMMAND_MODIFY_IO_ADDRESS) 1897 { 1898 rc = VINF_IOM_R3_IOPORT_WRITE; 1899 break; 1900 } 1901 #endif 1843 1902 /* 1844 1903 * The real adapter would set the Command register busy bit in the status register. … … 1932 1991 RTIOPORT Port, uint32_t *pu32, unsigned cb) 1933 1992 { 1934 PBUSLOGIC pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC); ;1993 PBUSLOGIC pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC); 1935 1994 unsigned iRegister = Port % 4; 1936 1995 … … 1970 2029 1971 2030 #ifdef IN_RING3 1972 /** 1973 * Port I/O Handler for IN operations - legacy port. 2031 2032 static int buslogicPrepareBIOSSCSIRequest(PBUSLOGIC pBusLogic) 2033 { 2034 int rc; 2035 PBUSLOGICTASKSTATE pTaskState; 2036 uint32_t uTargetDevice; 2037 2038 rc = RTMemCacheAllocEx(pBusLogic->hTaskCache, (void **)&pTaskState); 2039 AssertMsgRCReturn(rc, ("Getting task from cache failed rc=%Rrc\n", rc), rc); 2040 2041 pTaskState->fBIOS = true; 2042 2043 rc = vboxscsiSetupRequest(&pBusLogic->VBoxSCSI, &pTaskState->PDMScsiRequest, &uTargetDevice); 2044 AssertMsgRCReturn(rc, ("Setting up SCSI request failed rc=%Rrc\n", rc), rc); 2045 2046 pTaskState->PDMScsiRequest.pvUser = pTaskState; 2047 2048 pTaskState->CTX_SUFF(pTargetDevice) = &pBusLogic->aDeviceStates[uTargetDevice]; 2049 2050 if (!pTaskState->CTX_SUFF(pTargetDevice)->fPresent) 2051 { 2052 /* Device is not present. */ 2053 AssertMsg(pTaskState->PDMScsiRequest.pbCDB[0] == SCSI_INQUIRY, 2054 ("Device is not present but command is not inquiry\n")); 2055 2056 SCSIINQUIRYDATA ScsiInquiryData; 2057 2058 memset(&ScsiInquiryData, 0, sizeof(SCSIINQUIRYDATA)); 2059 ScsiInquiryData.u5PeripheralDeviceType = SCSI_INQUIRY_DATA_PERIPHERAL_DEVICE_TYPE_UNKNOWN; 2060 ScsiInquiryData.u3PeripheralQualifier = SCSI_INQUIRY_DATA_PERIPHERAL_QUALIFIER_NOT_CONNECTED_NOT_SUPPORTED; 2061 2062 memcpy(pBusLogic->VBoxSCSI.pBuf, &ScsiInquiryData, 5); 2063 2064 rc = vboxscsiRequestFinished(&pBusLogic->VBoxSCSI, &pTaskState->PDMScsiRequest); 2065 AssertMsgRCReturn(rc, ("Finishing BIOS SCSI request failed rc=%Rrc\n", rc), rc); 2066 2067 RTMemCacheFree(pBusLogic->hTaskCache, pTaskState); 2068 } 2069 else 2070 { 2071 LogFlowFunc(("before increment %u\n", pTaskState->CTX_SUFF(pTargetDevice)->cOutstandingRequests)); 2072 ASMAtomicIncU32(&pTaskState->CTX_SUFF(pTargetDevice)->cOutstandingRequests); 2073 LogFlowFunc(("after increment %u\n", pTaskState->CTX_SUFF(pTargetDevice)->cOutstandingRequests)); 2074 2075 rc = pTaskState->CTX_SUFF(pTargetDevice)->pDrvSCSIConnector->pfnSCSIRequestSend(pTaskState->CTX_SUFF(pTargetDevice)->pDrvSCSIConnector, 2076 &pTaskState->PDMScsiRequest); 2077 AssertMsgRC(rc, ("Sending request to SCSI layer failed rc=%Rrc\n", rc)); 2078 } 2079 2080 return rc; 2081 } 2082 2083 2084 /** 2085 * Port I/O Handler for IN operations - BIOS port. 1974 2086 * 1975 2087 * @returns VBox status code. … … 1981 2093 * @param cb Number of bytes read. 1982 2094 */ 1983 static int buslogicBIOSIOPortRead (PPDMDEVINS pDevIns, void *pvUser,2095 static int buslogicBIOSIOPortRead(PPDMDEVINS pDevIns, void *pvUser, 1984 2096 RTIOPORT Port, uint32_t *pu32, unsigned cb) 1985 2097 { … … 1989 2101 Assert(cb == 1); 1990 2102 1991 if (!pBusLogic->fISAEnabled)1992 return VINF_SUCCESS;1993 1994 2103 rc = vboxscsiReadRegister(&pBusLogic->VBoxSCSI, (Port - BUSLOGIC_BIOS_IO_PORT), pu32); 1995 2104 … … 1997 2106 // __FUNCTION__, pu32, 1, pu32, (Port - BUSLOGIC_BIOS_IO_PORT), rc)); 1998 2107 2108 return rc; 2109 } 2110 2111 /** 2112 * Port I/O Handler for OUT operations - BIOS port. 2113 * 2114 * @returns VBox status code. 2115 * 2116 * @param pDevIns The device instance. 2117 * @param pvUser User argument. 2118 * @param uPort Port number used for the IN operation. 2119 * @param u32 The value to output. 2120 * @param cb The value size in bytes. 2121 */ 2122 static int buslogicBIOSIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, 2123 RTIOPORT Port, uint32_t u32, unsigned cb) 2124 { 2125 int rc; 2126 PBUSLOGIC pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC); 2127 2128 Log2(("#%d %s: pvUser=%#p cb=%d u32=%#x Port=%#x\n", 2129 pDevIns->iInstance, __FUNCTION__, pvUser, cb, u32, Port)); 2130 2131 Assert(cb == 1); 2132 2133 rc = vboxscsiWriteRegister(&pBusLogic->VBoxSCSI, (Port - BUSLOGIC_BIOS_IO_PORT), (uint8_t)u32); 2134 if (rc == VERR_MORE_DATA) 2135 { 2136 rc = buslogicPrepareBIOSSCSIRequest(pBusLogic); 2137 AssertRC(rc); 2138 } 2139 else if (RT_FAILURE(rc)) 2140 AssertMsgFailed(("Writing BIOS register failed %Rrc\n", rc)); 2141 2142 return VINF_SUCCESS; 2143 } 2144 2145 /** 2146 * Port I/O Handler for primary port range OUT string operations. 2147 * @see FNIOMIOPORTOUTSTRING for details. 2148 */ 2149 static DECLCALLBACK(int) buslogicBIOSIOPortWriteStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc, PRTGCUINTREG pcTransfer, unsigned cb) 2150 { 2151 PBUSLOGIC pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC); 2152 int rc; 2153 2154 Log2(("#%d %s: pvUser=%#p cb=%d Port=%#x\n", 2155 pDevIns->iInstance, __FUNCTION__, pvUser, cb, Port)); 2156 2157 rc = vboxscsiWriteString(pDevIns, &pBusLogic->VBoxSCSI, (Port - BUSLOGIC_BIOS_IO_PORT), 2158 pGCPtrSrc, pcTransfer, cb); 2159 if (rc == VERR_MORE_DATA) 2160 { 2161 rc = buslogicPrepareBIOSSCSIRequest(pBusLogic); 2162 AssertRC(rc); 2163 } 2164 else if (RT_FAILURE(rc)) 2165 AssertMsgFailed(("Writing BIOS register failed %Rrc\n", rc)); 2166 2167 return rc; 2168 } 2169 2170 /** 2171 * Port I/O Handler for primary port range IN string operations. 2172 * @see FNIOMIOPORTINSTRING for details. 2173 */ 2174 static DECLCALLBACK(int) buslogicBIOSIOPortReadStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst, PRTGCUINTREG pcTransfer, unsigned cb) 2175 { 2176 PBUSLOGIC pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC); 2177 2178 LogFlowFunc(("#%d %s: pvUser=%#p cb=%d Port=%#x\n", 2179 pDevIns->iInstance, __FUNCTION__, pvUser, cb, Port)); 2180 2181 return vboxscsiReadString(pDevIns, &pBusLogic->VBoxSCSI, (Port - BUSLOGIC_BIOS_IO_PORT), 2182 pGCPtrDst, pcTransfer, cb); 2183 } 2184 2185 /** 2186 * Update the ISA I/O range. 2187 * 2188 * @returns nothing. 2189 * @param pBusLogic Pointer to the BusLogic device instance. 2190 * @param uBaseCode Encoded ISA I/O base; only low 3 bits are used. 2191 */ 2192 static int buslogicRegisterISARange(PBUSLOGIC pBusLogic, uint8_t uBaseCode) 2193 { 2194 uint8_t uCode = uBaseCode & MAX_ISA_BASE; 2195 uint16_t uNewBase = aISABases[uCode]; 2196 int rc = VINF_SUCCESS; 2197 2198 LogFlowFunc(("ISA I/O code %02X, new base %X\n", uBaseCode, uNewBase)); 2199 2200 /* Check if the same port range is already registered. */ 2201 if (uNewBase != pBusLogic->IOISABase) 2202 { 2203 /* Unregister the old range, if any. */ 2204 if (pBusLogic->IOISABase) 2205 rc = PDMDevHlpIOPortDeregister(pBusLogic->CTX_SUFF(pDevIns), pBusLogic->IOISABase, 4); 2206 2207 if (RT_SUCCESS(rc)) 2208 { 2209 pBusLogic->IOISABase = 0; /* First mark as unregistered. */ 2210 pBusLogic->uISABaseCode = ISA_BASE_DISABLED; 2211 2212 if (uNewBase) 2213 { 2214 /* Register the new range if requested. */ 2215 rc = PDMDevHlpIOPortRegister(pBusLogic->CTX_SUFF(pDevIns), uNewBase, 4, NULL, 2216 buslogicIOPortWrite, buslogicIOPortRead, 2217 NULL, NULL, 2218 "BusLogic ISA"); 2219 if (RT_SUCCESS(rc)) 2220 { 2221 pBusLogic->IOISABase = uNewBase; 2222 pBusLogic->uISABaseCode = uCode; 2223 } 2224 } 2225 } 2226 if (RT_SUCCESS(rc)) 2227 { 2228 if (uNewBase) 2229 { 2230 Log(("ISA I/O base: %x\n", uNewBase)); 2231 LogRel(("buslogic: ISA I/O base: %x\n", uNewBase)); 2232 } 2233 else 2234 { 2235 Log(("Disabling ISA I/O ports.\n")); 2236 LogRel(("buslogic: ISA I/O disabled\n")); 2237 } 2238 } 2239 2240 } 1999 2241 return rc; 2000 2242 } … … 2052 2294 } 2053 2295 2054 2055 static int buslogicPrepareBIOSSCSIRequest(PBUSLOGIC pBusLogic)2056 {2057 int rc;2058 PBUSLOGICTASKSTATE pTaskState;2059 uint32_t uTargetDevice;2060 2061 rc = RTMemCacheAllocEx(pBusLogic->hTaskCache, (void **)&pTaskState);2062 AssertMsgRCReturn(rc, ("Getting task from cache failed rc=%Rrc\n", rc), rc);2063 2064 pTaskState->fBIOS = true;2065 2066 rc = vboxscsiSetupRequest(&pBusLogic->VBoxSCSI, &pTaskState->PDMScsiRequest, &uTargetDevice);2067 AssertMsgRCReturn(rc, ("Setting up SCSI request failed rc=%Rrc\n", rc), rc);2068 2069 pTaskState->PDMScsiRequest.pvUser = pTaskState;2070 2071 pTaskState->CTX_SUFF(pTargetDevice) = &pBusLogic->aDeviceStates[uTargetDevice];2072 2073 if (!pTaskState->CTX_SUFF(pTargetDevice)->fPresent)2074 {2075 /* Device is not present. */2076 AssertMsg(pTaskState->PDMScsiRequest.pbCDB[0] == SCSI_INQUIRY,2077 ("Device is not present but command is not inquiry\n"));2078 2079 SCSIINQUIRYDATA ScsiInquiryData;2080 2081 memset(&ScsiInquiryData, 0, sizeof(SCSIINQUIRYDATA));2082 ScsiInquiryData.u5PeripheralDeviceType = SCSI_INQUIRY_DATA_PERIPHERAL_DEVICE_TYPE_UNKNOWN;2083 ScsiInquiryData.u3PeripheralQualifier = SCSI_INQUIRY_DATA_PERIPHERAL_QUALIFIER_NOT_CONNECTED_NOT_SUPPORTED;2084 2085 memcpy(pBusLogic->VBoxSCSI.pBuf, &ScsiInquiryData, 5);2086 2087 rc = vboxscsiRequestFinished(&pBusLogic->VBoxSCSI, &pTaskState->PDMScsiRequest);2088 AssertMsgRCReturn(rc, ("Finishing BIOS SCSI request failed rc=%Rrc\n", rc), rc);2089 2090 RTMemCacheFree(pBusLogic->hTaskCache, pTaskState);2091 }2092 else2093 {2094 LogFlowFunc(("before increment %u\n", pTaskState->CTX_SUFF(pTargetDevice)->cOutstandingRequests));2095 ASMAtomicIncU32(&pTaskState->CTX_SUFF(pTargetDevice)->cOutstandingRequests);2096 LogFlowFunc(("after increment %u\n", pTaskState->CTX_SUFF(pTargetDevice)->cOutstandingRequests));2097 2098 rc = pTaskState->CTX_SUFF(pTargetDevice)->pDrvSCSIConnector->pfnSCSIRequestSend(pTaskState->CTX_SUFF(pTargetDevice)->pDrvSCSIConnector,2099 &pTaskState->PDMScsiRequest);2100 AssertMsgRC(rc, ("Sending request to SCSI layer failed rc=%Rrc\n", rc));2101 }2102 2103 return rc;2104 }2105 2106 /**2107 * Port I/O Handler for OUT operations - legacy port.2108 *2109 * @returns VBox status code.2110 *2111 * @param pDevIns The device instance.2112 * @param pvUser User argument.2113 * @param uPort Port number used for the IN operation.2114 * @param u32 The value to output.2115 * @param cb The value size in bytes.2116 */2117 static int buslogicBIOSIOPortWrite (PPDMDEVINS pDevIns, void *pvUser,2118 RTIOPORT Port, uint32_t u32, unsigned cb)2119 {2120 int rc;2121 PBUSLOGIC pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC);2122 2123 Log2(("#%d %s: pvUser=%#p cb=%d u32=%#x Port=%#x\n",2124 pDevIns->iInstance, __FUNCTION__, pvUser, cb, u32, Port));2125 2126 Assert(cb == 1);2127 2128 if (!pBusLogic->fISAEnabled)2129 return VINF_SUCCESS;2130 2131 rc = vboxscsiWriteRegister(&pBusLogic->VBoxSCSI, (Port - BUSLOGIC_BIOS_IO_PORT), (uint8_t)u32);2132 if (rc == VERR_MORE_DATA)2133 {2134 rc = buslogicPrepareBIOSSCSIRequest(pBusLogic);2135 AssertRC(rc);2136 }2137 else if (RT_FAILURE(rc))2138 AssertMsgFailed(("Writing BIOS register failed %Rrc\n", rc));2139 2140 return VINF_SUCCESS;2141 }2142 2143 /**2144 * Port I/O Handler for primary port range OUT string operations.2145 * @see FNIOMIOPORTOUTSTRING for details.2146 */2147 static DECLCALLBACK(int) buslogicBIOSIOPortWriteStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc, PRTGCUINTREG pcTransfer, unsigned cb)2148 {2149 PBUSLOGIC pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC);2150 int rc;2151 2152 Log2(("#%d %s: pvUser=%#p cb=%d Port=%#x\n",2153 pDevIns->iInstance, __FUNCTION__, pvUser, cb, Port));2154 2155 rc = vboxscsiWriteString(pDevIns, &pBusLogic->VBoxSCSI, (Port - BUSLOGIC_BIOS_IO_PORT),2156 pGCPtrSrc, pcTransfer, cb);2157 if (rc == VERR_MORE_DATA)2158 {2159 rc = buslogicPrepareBIOSSCSIRequest(pBusLogic);2160 AssertRC(rc);2161 }2162 else if (RT_FAILURE(rc))2163 AssertMsgFailed(("Writing BIOS register failed %Rrc\n", rc));2164 2165 return rc;2166 }2167 2168 /**2169 * Port I/O Handler for primary port range IN string operations.2170 * @see FNIOMIOPORTINSTRING for details.2171 */2172 static DECLCALLBACK(int) buslogicBIOSIOPortReadStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst, PRTGCUINTREG pcTransfer, unsigned cb)2173 {2174 PBUSLOGIC pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC);2175 2176 LogFlowFunc(("#%d %s: pvUser=%#p cb=%d Port=%#x\n",2177 pDevIns->iInstance, __FUNCTION__, pvUser, cb, Port));2178 2179 return vboxscsiReadString(pDevIns, &pBusLogic->VBoxSCSI, (Port - BUSLOGIC_BIOS_IO_PORT),2180 pGCPtrDst, pcTransfer, cb);2181 }2182 2296 2183 2297 static DECLCALLBACK(int) buslogicMMIOMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, … … 2611 2725 SSMR3PutU8 (pSSM, pBusLogic->cbReplyParametersLeft); 2612 2726 SSMR3PutBool (pSSM, pBusLogic->fIRQEnabled); 2613 SSMR3Put Bool (pSSM, pBusLogic->fISAEnabled);2727 SSMR3PutU8 (pSSM, pBusLogic->uISABaseCode); 2614 2728 SSMR3PutU32 (pSSM, pBusLogic->cMailbox); 2615 2729 SSMR3PutGCPhys(pSSM, pBusLogic->GCPhysAddrMailboxOutgoingBase); … … 2669 2783 PBUSLOGIC pThis = PDMINS_2_DATA(pDevIns, PBUSLOGIC); 2670 2784 2785 buslogicRegisterISARange(pThis, pThis->uISABaseCode); 2671 2786 buslogicKick(pThis); 2672 2787 return VINF_SUCCESS; … … 2716 2831 SSMR3GetU8 (pSSM, &pBusLogic->cbReplyParametersLeft); 2717 2832 SSMR3GetBool (pSSM, &pBusLogic->fIRQEnabled); 2718 SSMR3Get Bool (pSSM, &pBusLogic->fISAEnabled);2833 SSMR3GetU8 (pSSM, &pBusLogic->uISABaseCode); 2719 2834 SSMR3GetU32 (pSSM, &pBusLogic->cMailbox); 2720 2835 SSMR3GetGCPhys(pSSM, &pBusLogic->GCPhysAddrMailboxOutgoingBase); … … 3065 3180 ASMAtomicWriteBool(&pThis->fSignalIdle, false); 3066 3181 3067 buslogicHwReset(pThis );3182 buslogicHwReset(pThis, true); 3068 3183 return true; 3069 3184 } … … 3082 3197 { 3083 3198 ASMAtomicWriteBool(&pThis->fSignalIdle, false); 3084 buslogicHwReset(pThis );3199 buslogicHwReset(pThis, true); 3085 3200 } 3086 3201 } … … 3166 3281 int rc = VINF_SUCCESS; 3167 3282 bool fBootable = true; 3283 char achISACompat[16]; 3168 3284 PDMDEV_CHECK_VERSIONS_RETURN(pDevIns); 3169 3285 … … 3174 3290 "GCEnabled\0" 3175 3291 "R0Enabled\0" 3176 "Bootable\0")) 3292 "Bootable\0" 3293 "ISACompat\0")) 3177 3294 return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES, 3178 3295 N_("BusLogic configuration error: unknown option specified")); … … 3194 3311 N_("BusLogic configuration error: failed to read Bootable as boolean")); 3195 3312 Log(("%s: fBootable=%RTbool\n", __FUNCTION__, fBootable)); 3313 rc = CFGMR3QueryStringDef(pCfg, "ISACompat", achISACompat, sizeof(achISACompat), "Alternate"); 3314 if (RT_FAILURE(rc)) 3315 return PDMDEV_SET_ERROR(pDevIns, rc, 3316 N_("BusLogic configuration error: failed to read ISACompat as string")); 3317 Log(("%s: ISACompat=%s\n", __FUNCTION__, achISACompat)); 3318 3319 /* Grok the ISACompat setting. */ 3320 if (!strcmp(achISACompat, "Disabled")) 3321 pThis->uDefaultISABaseCode = ISA_BASE_DISABLED; 3322 else if (!strcmp(achISACompat, "Primary")) 3323 pThis->uDefaultISABaseCode = 0; /* I/O base at 330h. */ 3324 else if (!strcmp(achISACompat, "Alternate")) 3325 pThis->uDefaultISABaseCode = 1; /* I/O base at 334h. */ 3326 else 3327 return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES, 3328 N_("BusLogic configuration error: invalid ISACompat setting")); 3196 3329 3197 3330 pThis->pDevInsR3 = pDevIns; … … 3216 3349 3217 3350 /* 3218 * Register the PCI device , it's I/O regions.3351 * Register the PCI device and its I/O regions. 3219 3352 */ 3220 3353 rc = PDMDevHlpPCIRegister (pDevIns, &pThis->dev); … … 3232 3365 if (fBootable) 3233 3366 { 3234 /* Register I/O port space in ISA regionfor BIOS access. */3367 /* Register I/O port space for BIOS access. */ 3235 3368 rc = PDMDevHlpIOPortRegister(pDevIns, BUSLOGIC_BIOS_IO_PORT, 3, NULL, 3236 3369 buslogicBIOSIOPortWrite, buslogicBIOSIOPortRead, … … 3238 3371 "BusLogic BIOS"); 3239 3372 if (RT_FAILURE(rc)) 3240 return PDMDEV_SET_ERROR(pDevIns, rc, N_("BusLogic cannot register legacy I/O handlers")); 3241 } 3373 return PDMDEV_SET_ERROR(pDevIns, rc, N_("BusLogic cannot register BIOS I/O handlers")); 3374 } 3375 3376 /* Set up the compatibility I/O range. */ 3377 rc = buslogicRegisterISARange(pThis, pThis->uDefaultISABaseCode); 3378 if (RT_FAILURE(rc)) 3379 return PDMDEV_SET_ERROR(pDevIns, rc, N_("BusLogic cannot register ISA I/O handlers")); 3242 3380 3243 3381 /* Initialize task cache. */ … … 3324 3462 return PDMDEV_SET_ERROR(pDevIns, rc, N_("BusLogic cannot register save state handlers")); 3325 3463 3326 rc = buslogicHwReset(pThis );3464 rc = buslogicHwReset(pThis, true); 3327 3465 AssertMsgRC(rc, ("hardware reset of BusLogic host adapter failed rc=%Rrc\n", rc)); 3328 3466 … … 3389 3527 #endif /* IN_RING3 */ 3390 3528 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */ 3391
Note:
See TracChangeset
for help on using the changeset viewer.

