From: leonidk Date: Mon, 10 Apr 2006 09:34:51 +0000 (+0000) Subject: [MTHCA] fixed card reset X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=66d5dcdc17b5457783fad40ec4f7805e53a211bc;p=~shefty%2Frdma-win.git [MTHCA] fixed card reset git-svn-id: svn://openib.tc.cornell.edu/gen1@299 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- diff --git a/trunk/hw/mthca/kernel/hca_pci.c b/trunk/hw/mthca/kernel/hca_pci.c index 083b9db0..9efa74fa 100644 --- a/trunk/hw/mthca/kernel/hca_pci.c +++ b/trunk/hw/mthca/kernel/hca_pci.c @@ -273,19 +273,6 @@ __fixup_pci_capabilities( } -#define PCI_CONFIG_OFFSET( field ) \ - offsetof( PCI_COMMON_CONFIG, field ) - -#define PCI_CONFIG_LEN( fromField, toField ) \ - offsetof( PCI_COMMON_CONFIG, toField ) - \ - offsetof( PCI_COMMON_CONFIG, fromField ) + \ - sizeof( ((PCI_COMMON_CONFIG*)NULL)->##toField ) - -#define PCI_CONFIG_WRITE( fromField, toField ) \ - pBusIfc->SetBusData( pBusIfc->Context, PCI_WHICHSPACE_CONFIG, \ - &pConfig->##fromField, PCI_CONFIG_OFFSET( fromField ), \ - PCI_CONFIG_LEN( fromField, toField ) ) - /* * Restore saved PCI configuration, skipping registers 22 and 23, as well * as any registers where writing will have side effects such as the flags @@ -298,84 +285,36 @@ __restore_pci_config( IN BUS_INTERFACE_STANDARD *pBusIfc, IN PCI_COMMON_CONFIG* const pConfig ) { - ULONG len; - UCHAR *pBuf; + NTSTATUS status = STATUS_SUCCESS; + int i, *pci_hdr = (int*)pConfig; HCA_ENTER( HCA_DBG_PNP ); - pBuf = (UCHAR*)pConfig; - - /* Fixup the capabilities as needed. */ - __fixup_pci_capabilities( pConfig ); - - /* Restore the vendor/device IDs */ - len = PCI_CONFIG_WRITE( VendorID, DeviceID ); - if( len != PCI_CONFIG_LEN( VendorID, DeviceID ) ) - { - HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_PNP ,("Failed to write vendor/device IDs.\n")); - return STATUS_DEVICE_NOT_READY; - } - - /* - * Skip the command register and write the rest (except the bridge - * control if this is a bridge). - */ - if( pConfig->HeaderType == PCI_DEVICE_TYPE ) - { - len = PCI_CONFIG_WRITE( Status, u.type0.MaximumLatency ); - if( len != PCI_CONFIG_LEN( Status, u.type0.MaximumLatency ) ) - { - HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_PNP ,("Failed to write type 0 common header.\n")); - return STATUS_DEVICE_NOT_READY; - } - } - else - { - ASSERT( pConfig->HeaderType == PCI_BRIDGE_TYPE ); - len = PCI_CONFIG_WRITE( Status, u.type1.InterruptPin ); - if( len != PCI_CONFIG_LEN( Status, u.type1.InterruptPin ) ) - { - HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_PNP ,("Failed to write type 1 common header.\n")); - return STATUS_DEVICE_NOT_READY; + for (i = 0; i < 16; ++i) { + if (i == 1) + continue; + + if (4 != pBusIfc->SetBusData( pBusIfc->Context, + PCI_WHICHSPACE_CONFIG, &pci_hdr[i], i * 4, 4 )) { + HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_PNP , + ("Couldn't restore PCI cfg reg %x, aborting.\n", i)); + status = STATUS_DEVICE_NOT_READY; + goto out; } } - /* Write the capabilities back. */ - len = pBusIfc->SetBusData( pBusIfc->Context, PCI_WHICHSPACE_CONFIG, - pConfig->DeviceSpecific, PCI_CONFIG_OFFSET( DeviceSpecific ), 192 ); - if( len != 192 ) - { - HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_PNP ,("Failed to write capabilites.\n")); - return STATUS_DEVICE_NOT_READY; - } - /* Write the command register. */ - len = PCI_CONFIG_WRITE( Command, Command ); - if( len != PCI_CONFIG_LEN( Command, Command ) ) - { - HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,("Failed to write command register.\n")); - return STATUS_DEVICE_NOT_READY; - } - - /* Write the bridge control register if a bridge. */ - if( pConfig->HeaderType == PCI_BRIDGE_TYPE ) - { - len = - PCI_CONFIG_WRITE( u.type1.BridgeControl, u.type1.BridgeControl ); - if( len != - PCI_CONFIG_LEN( u.type1.BridgeControl, u.type1.BridgeControl ) ) - { - HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, - ("Failed to write bridge control register.\n")); - return STATUS_DEVICE_NOT_READY; - } + if (4 != pBusIfc->SetBusData( pBusIfc->Context, + PCI_WHICHSPACE_CONFIG, &pci_hdr[1], 4, 4 )) { + HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_PNP ,("Couldn't restore COMMAND.\n")); + status = STATUS_DEVICE_NOT_READY; } +out: HCA_EXIT( HCA_DBG_PNP ); - return STATUS_SUCCESS; + return status; } - NTSTATUS hca_reset( DEVICE_OBJECT* const pDevObj, int is_tavor ) { @@ -384,165 +323,118 @@ hca_reset( DEVICE_OBJECT* const pDevObj, int is_tavor ) BUS_INTERFACE_STANDARD hcaBusIfc; BUS_INTERFACE_STANDARD brBusIfc = {0}; // to bypass C4701 hca_dev_ext_t *pExt = (hca_dev_ext_t*)pDevObj->DeviceExtension; - ULONG data, i; - PULONG reset_p; - PHYSICAL_ADDRESS pa; - static int skip = 1; HCA_ENTER( HCA_DBG_PNP ); - if (skip) goto resetErr1; - /* Get the HCA's bus interface. */ - status = __get_bus_ifc( pDevObj, &GUID_BUS_INTERFACE_STANDARD, &hcaBusIfc ); - if( !NT_SUCCESS( status ) ) + /* get the resources */ { - HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,("Failed to get HCA bus interface.\n")); - goto resetErr1; - } + /* Get the HCA's bus interface. */ + status = __get_bus_ifc( pDevObj, &GUID_BUS_INTERFACE_STANDARD, &hcaBusIfc ); + if( !NT_SUCCESS( status ) ) { + HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,("Failed to get HCA bus interface.\n")); + goto resetErr1; + } - if (is_tavor) { -#ifdef WIN_TO_BE_REMOVED - /* Get the HCA Bridge's bus interface. */ - status = __get_bus_ifc( pDevObj, &GUID_HCA_BRIDGE_INTERFACE, &brBusIfc ); - if( !NT_SUCCESS( status ) ) - { - HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, - ("Failed to get HCA bridge bus interface.\n")); - goto resetErr2; + /* Get the HCA Bridge's bus interface, if any */ + if (is_tavor) { + if (!FindBridgeIf( pExt, &brBusIfc )) + goto resetErr2; } -#else - if (!FindBridgeIf( pExt, &brBusIfc )) - goto resetErr2; -#endif } - /* Save the HCA's configuration. */ - status = __save_pci_config( &hcaBusIfc, &hcaConfig ); - if( !NT_SUCCESS( status ) ) + /* Save the HCA's PCI configuration headers */ { - HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, - ("Failed to save HCA config.\n")); - goto resetErr3; - } - - if (is_tavor) { - /* Save the HCA bridge's configuration. */ - status = __save_pci_config( &brBusIfc, &brConfig ); - if( !NT_SUCCESS( status ) ) - { + status = __save_pci_config( &hcaBusIfc, &hcaConfig ); + if( !NT_SUCCESS( status ) ) { HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, - ("Failed to save bridge config.\n")); + ("Failed to save HCA config.\n")); goto resetErr3; } + + /* Save the HCA bridge's configuration, if any */ + if (is_tavor) { + status = __save_pci_config( &brBusIfc, &brConfig ); + if( !NT_SUCCESS( status ) ) { + HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, + ("Failed to save bridge config.\n")); + goto resetErr3; + } + } } - /* map reset register */ - pa.QuadPart = pExt->bar[HCA_BAR_TYPE_HCR].phys + HCA_RESET_HCR_OFFSET; - HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_PNP ,("Mapping reset register with address 0x%I64x\n", pa.QuadPart)); - reset_p = MmMapIoSpace( pa, 4, MmNonCached ); - if( !reset_p ) + /* reset the card */ { - HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_PNP ,("Failed to map reset register with address 0x%I64x\n", pa.QuadPart)); - status = STATUS_UNSUCCESSFUL; - goto resetErr3; - } - - /* Issue the reset. */ - HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_PNP ,("Resetting the chip ...\n")); - WRITE_REGISTER_ULONG( reset_p, HCA_RESET_TOKEN ); + PULONG reset_p; + PHYSICAL_ADDRESS pa; + /* map reset register */ + pa.QuadPart = pExt->bar[HCA_BAR_TYPE_HCR].phys + (uint64_t)HCA_RESET_HCR_OFFSET; + HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_PNP ,("Mapping reset register with address 0x%I64x\n", pa.QuadPart)); + reset_p = MmMapIoSpace( pa, 4, MmNonCached ); + if( !reset_p ) { + HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_PNP ,("Failed to map reset register with address 0x%I64x\n", pa.QuadPart)); + status = STATUS_UNSUCCESSFUL; + goto resetErr3; + } + + /* Issue the reset. */ + HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_PNP ,("Resetting the chip ...\n")); + WRITE_REGISTER_ULONG( reset_p, HCA_RESET_TOKEN ); - /* Wait a second. */ - cl_thread_suspend( 1000 ); + /* unmap the reset register */ + HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_PNP ,("Unmapping reset register \n")); + MmUnmapIoSpace( reset_p, 4 ); - /* unmap the reset register */ - HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_PNP ,("Unmapping reset register \n")); - MmUnmapIoSpace( reset_p, 4 ); + /* Wait a second. */ + cl_thread_suspend( 1000 ); + } - - if (is_tavor) { - /* - * Now read the bridge's configuration register until it doesn't - * return 0xFFFFFFFF. Give it 10 seconds for good measure. - */ - HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_PNP ,("Read the Bridge's configuration register \n")); - for( i = 0; i < 10; i++ ) - { - if( brBusIfc.GetBusData( brBusIfc.Context, PCI_WHICHSPACE_CONFIG, - &data, 0, sizeof(ULONG) ) != sizeof(ULONG) ) - { + /* Read the configuration register until it doesn't return 0xFFFFFFFF */ + { + ULONG data, i; + BUS_INTERFACE_STANDARD *p_ifc = (is_tavor) ? &brBusIfc : &hcaBusIfc; + HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_PNP ,("Read the configuration register \n")); + for( i = 0; i < 100; i++ ) { + if (4 != p_ifc->GetBusData( p_ifc->Context, + PCI_WHICHSPACE_CONFIG, &data, 0, 4)) { HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, - ("Failed to read bridge configuration data.\n")); + ("Failed to read device configuration data.\n")); status = STATUS_UNSUCCESSFUL; goto resetErr3; } /* See if we got valid data. */ if( data != 0xFFFFFFFF ) - break; - - cl_thread_suspend( 1000 ); + goto good; + + cl_thread_suspend( 100 ); } - if( i == 10 ) - { - /* Darn, timed out. :( */ - HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, - ("Doh! HCA Bridge never came back from reset!\n")); - status = STATUS_UNSUCCESSFUL; - goto resetErr3; - } - } - - else { - /* - * Now read the HCA's configuration register until it doesn't - * return 0xFFFFFFFF. Give it 10 seconds for good measure. - */ - HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_PNP ,("Read the HCA's configuration register \n")); - for( i = 0; i < 100; i++ ) - { - if( hcaBusIfc.GetBusData( hcaBusIfc.Context, PCI_WHICHSPACE_CONFIG, - &data, 0, sizeof(ULONG) ) != sizeof(ULONG) ) - { + + HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, + ("Doh! PCI device did not come back after reset!\n")); + status = STATUS_UNSUCCESSFUL; + goto resetErr3; + } + +good: /* restore the HCA's PCI configuration headers */ + { + if (is_tavor) { + /* Restore the HCA's bridge configuration. */ + HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_PNP ,("Restoring bridge PCI configuration \n")); + status = __restore_pci_config( &brBusIfc, &brConfig ); + if( !NT_SUCCESS( status ) ) { HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, - ("Failed to read HCA configuration data.\n")); - status = STATUS_UNSUCCESSFUL; + ("Failed to restore bridge config.\n")); goto resetErr3; } - /* See if we got valid data. */ - if( data != 0xFFFFFFFF ) - break; - - cl_thread_suspend( 100 ); - } - if( i >= 100 ) - { - /* Darn, timed out. :( */ - HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, - ("Doh! HCA Bridge never came back from reset!\n")); - status = STATUS_UNSUCCESSFUL; - goto resetErr3; } - } - - if (is_tavor) { - /* Restore the HCA's bridge configuration. */ - HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_PNP ,("Restoring bridge PCI configuration \n")); - status = __restore_pci_config( &brBusIfc, &brConfig ); - if( !NT_SUCCESS( status ) ) - { + + /* Restore the HCA's configuration. */ + HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_PNP ,("Restoring HCA PCI configuration \n")); + status = __restore_pci_config( &hcaBusIfc, &hcaConfig ); + if( !NT_SUCCESS( status ) ) { HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, - ("Failed to restore bridge config.\n")); - goto resetErr3; + ("Failed to restore HCA config.\n")); } } - - /* Restore the HCA's configuration. */ - HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_PNP ,("Restoring HCA PCI configuration \n")); - status = __restore_pci_config( &hcaBusIfc, &hcaConfig ); - if( !NT_SUCCESS( status ) ) - { - HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, - ("Failed to restore HCA config.\n")); - } resetErr3: if (is_tavor)