]> git.openfabrics.org - ~shefty/rdma-win.git/commitdiff
[MTHCA] (trial fix) reset Tavor without using HAL functions. for WHQL tests.
authorsleybo <sleybo@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Thu, 8 Mar 2007 09:05:14 +0000 (09:05 +0000)
committersleybo <sleybo@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Thu, 8 Mar 2007 09:05:14 +0000 (09:05 +0000)
git-svn-id: svn://openib.tc.cornell.edu/gen1@609 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

trunk/hw/mthca/kernel/mt_reset_tavor.c

index 23dbea53763bdbab30e37e2e157f7d543143586c..3c2f8289171035c32ed38b19d3162457931407d7 100644 (file)
@@ -61,6 +61,96 @@ Return Value:
 
 } /* WcharFindChar */
 
+
+/*----------------------------------------------------------------*/
+
+/*
+ * Function: MdGetDevLocation
+ *
+ * Parameters:
+ *             IN              pi_pPdo                 - PDO of a device in question
+ *             OUT     po_pBus                 - pointer to the bus number of the device in question
+ *             OUT     po_pDevFunc     - pointer to dev/func of the device, if found
+ * 
+ * Returns:
+ *             not STATUS_SUCCESS      - the device location was not found
+ *     STATUS_SUCCESS          - the device location was found and returned in OUT parameters
+ *
+ * Description:
+ *             The function uses IoGetDeviceProperty to get the location of a device with given PDO
+ *                     
+ */
+static NTSTATUS 
+MdGetDevLocation(
+       IN      PDEVICE_OBJECT  pi_pPdo,
+       OUT     ULONG *                 po_pBus,
+       OUT ULONG        *                      po_pDevFunc 
+       )
+{
+       ULONG   l_BusNumber, l_DevNumber, l_Function, l_ResultLength = 0;
+       WCHAR   l_Buffer[40], *l_pEnd, *l_pBuf = l_Buffer, *l_pBufEnd = l_Buffer + sizeof(l_Buffer);
+       NTSTATUS        l_Status;
+       UNICODE_STRING  l_UnicodeNumber;
+
+       /* prepare */
+       l_ResultLength = 0;
+       RtlZeroMemory( l_Buffer, sizeof(l_Buffer) );
+
+       /* Get the device number  */
+       l_Status = IoGetDeviceProperty(pi_pPdo,
+               DevicePropertyLocationInformation, sizeof(l_Buffer), l_Buffer, &l_ResultLength);
+
+       /* Verify if the function was successful */
+       if ( !NT_SUCCESS(l_Status) || !l_ResultLength ) {
+               HCA_PRINT( TRACE_LEVEL_ERROR  ,HCA_DBG_SHIM  ,("(MdGetDevLocation) Unable to get device number: Status 0x%x, ResultSize %d \n", 
+                       l_Status, l_ResultLength  ));
+               goto exit;      
+       }
+
+       // ALL THE BELOW CRAP WE DO INSTEAD OF 
+       // sscanf(l_Buffer, "PCI bus %d, device %d, function %d", &l_BusNumber, &l_DevNumber, &l_Function );
+
+       /* take bus number */
+       l_pBuf  = WcharFindChar( l_pBuf, l_pBufEnd, L'0', L'9' );
+       if (l_pBuf == NULL) goto err;
+       l_pEnd  = WcharFindChar( l_pBuf, l_pBufEnd, L',', L',' );
+       if (l_pEnd == NULL) goto err;
+       l_UnicodeNumber.Length = l_UnicodeNumber.MaximumLength = (USHORT)((PCHAR)l_pEnd - (PCHAR)l_pBuf);
+       l_UnicodeNumber.Buffer = l_pBuf; l_pBuf = l_pEnd;
+       RtlUnicodeStringToInteger( &l_UnicodeNumber, 10, &l_BusNumber);
+
+       /* take slot number */
+       l_pBuf  = WcharFindChar( l_pBuf, l_pBufEnd, L'0', L'9' );
+       if (l_pBuf == NULL) goto err;
+       l_pEnd  = WcharFindChar( l_pBuf, l_pBufEnd, L',', L',' );
+       if (l_pEnd == NULL) goto err;
+       l_UnicodeNumber.Length = l_UnicodeNumber.MaximumLength = (USHORT)((PCHAR)l_pEnd - (PCHAR)l_pBuf);
+       l_UnicodeNumber.Buffer = l_pBuf; l_pBuf = l_pEnd;
+       RtlUnicodeStringToInteger( &l_UnicodeNumber, 10, &l_DevNumber);
+
+       /* take function number */
+       *(l_Buffer + (l_ResultLength>>1)) = 0;  /* set end of string */
+       l_pBuf  = WcharFindChar( l_pBuf, l_pBufEnd, L'0', L'9' );
+       if (l_pBuf == NULL) goto err;
+       l_pEnd  = WcharFindChar( l_pBuf, l_pBufEnd, 0, 0 );
+       if (l_pEnd == NULL) goto err;
+       l_UnicodeNumber.Length = l_UnicodeNumber.MaximumLength = (USHORT)((PCHAR)l_pEnd - (PCHAR)l_pBuf);
+       l_UnicodeNumber.Buffer = l_pBuf; l_pBuf = l_pEnd;
+       RtlUnicodeStringToInteger( &l_UnicodeNumber, 10, &l_Function);
+
+       /* return the results */
+       *po_pBus                = l_BusNumber;
+       *po_pDevFunc = (l_DevNumber & 0x01f) | ((l_Function & 7) << 5);
+
+       goto exit;
+
+err:
+       l_Status = STATUS_UNSUCCESSFUL;
+exit:
+       return l_Status;
+}
+
+#ifdef USE_HAL
 /*----------------------------------------------------------------*/
 
 /*
@@ -236,94 +326,6 @@ NextDevice:
        return TRUE;
 }
 
-/*----------------------------------------------------------------*/
-
-/*
- * Function: MdGetDevLocation
- *
- * Parameters:
- *             IN              pi_pPdo                 - PDO of a device in question
- *             OUT     po_pBus                 - pointer to the bus number of the device in question
- *             OUT     po_pDevFunc     - pointer to dev/func of the device, if found
- * 
- * Returns:
- *             not STATUS_SUCCESS      - the device location was not found
- *     STATUS_SUCCESS          - the device location was found and returned in OUT parameters
- *
- * Description:
- *             The function uses IoGetDeviceProperty to get the location of a device with given PDO
- *                     
- */
-static NTSTATUS 
-MdGetDevLocation(
-       IN      PDEVICE_OBJECT  pi_pPdo,
-       OUT     ULONG *                 po_pBus,
-       OUT ULONG        *                      po_pDevFunc 
-       )
-{
-       ULONG   l_BusNumber, l_DevNumber, l_Function, l_ResultLength = 0;
-       WCHAR   l_Buffer[40], *l_pEnd, *l_pBuf = l_Buffer, *l_pBufEnd = l_Buffer + sizeof(l_Buffer);
-       NTSTATUS        l_Status;
-       UNICODE_STRING  l_UnicodeNumber;
-
-       /* prepare */
-       l_ResultLength = 0;
-       RtlZeroMemory( l_Buffer, sizeof(l_Buffer) );
-
-       /* Get the device number  */
-       l_Status = IoGetDeviceProperty(pi_pPdo,
-               DevicePropertyLocationInformation, sizeof(l_Buffer), l_Buffer, &l_ResultLength);
-
-       /* Verify if the function was successful */
-       if ( !NT_SUCCESS(l_Status) || !l_ResultLength ) {
-               HCA_PRINT( TRACE_LEVEL_ERROR  ,HCA_DBG_SHIM  ,("(MdGetDevLocation) Unable to get device number: Status 0x%x, ResultSize %d \n", 
-                       l_Status, l_ResultLength  ));
-               goto exit;      
-       }
-
-       // ALL THE BELOW CRAP WE DO INSTEAD OF 
-       // sscanf(l_Buffer, "PCI bus %d, device %d, function %d", &l_BusNumber, &l_DevNumber, &l_Function );
-
-       /* take bus number */
-       l_pBuf  = WcharFindChar( l_pBuf, l_pBufEnd, L'0', L'9' );
-       if (l_pBuf == NULL) goto err;
-       l_pEnd  = WcharFindChar( l_pBuf, l_pBufEnd, L',', L',' );
-       if (l_pEnd == NULL) goto err;
-       l_UnicodeNumber.Length = l_UnicodeNumber.MaximumLength = (USHORT)((PCHAR)l_pEnd - (PCHAR)l_pBuf);
-       l_UnicodeNumber.Buffer = l_pBuf; l_pBuf = l_pEnd;
-       RtlUnicodeStringToInteger( &l_UnicodeNumber, 10, &l_BusNumber);
-
-       /* take slot number */
-       l_pBuf  = WcharFindChar( l_pBuf, l_pBufEnd, L'0', L'9' );
-       if (l_pBuf == NULL) goto err;
-       l_pEnd  = WcharFindChar( l_pBuf, l_pBufEnd, L',', L',' );
-       if (l_pEnd == NULL) goto err;
-       l_UnicodeNumber.Length = l_UnicodeNumber.MaximumLength = (USHORT)((PCHAR)l_pEnd - (PCHAR)l_pBuf);
-       l_UnicodeNumber.Buffer = l_pBuf; l_pBuf = l_pEnd;
-       RtlUnicodeStringToInteger( &l_UnicodeNumber, 10, &l_DevNumber);
-
-       /* take function number */
-       *(l_Buffer + (l_ResultLength>>1)) = 0;  /* set end of string */
-       l_pBuf  = WcharFindChar( l_pBuf, l_pBufEnd, L'0', L'9' );
-       if (l_pBuf == NULL) goto err;
-       l_pEnd  = WcharFindChar( l_pBuf, l_pBufEnd, 0, 0 );
-       if (l_pEnd == NULL) goto err;
-       l_UnicodeNumber.Length = l_UnicodeNumber.MaximumLength = (USHORT)((PCHAR)l_pEnd - (PCHAR)l_pBuf);
-       l_UnicodeNumber.Buffer = l_pBuf; l_pBuf = l_pEnd;
-       RtlUnicodeStringToInteger( &l_UnicodeNumber, 10, &l_Function);
-
-       /* return the results */
-       *po_pBus                = l_BusNumber;
-       *po_pDevFunc = (l_DevNumber & 0x01f) | ((l_Function & 7) << 5);
-
-       goto exit;
-
-err:
-       l_Status = STATUS_UNSUCCESSFUL;
-exit:
-       return l_Status;
-}
-
 
 /*------------------------------------------------------------------------------------------------------*/
 
@@ -347,7 +349,7 @@ exit:
  *             It is a "hack" algorithm. It uses some fields of system structures and some
  *             optimistic assumptions - see more below
  */
-static BOOLEAN PciFindPdoByPdoAndLocation( 
+static BOOLEAN PciFindPdoByPdoAndLocation(
        IN PDEVICE_OBJECT pi_pPdo,
        IN ULONG                pi_Bus, 
        IN ULONG                pi_DevFunc,
@@ -363,6 +365,7 @@ static BOOLEAN PciFindPdoByPdoAndLocation(
        PDEVICE_OBJECT *pdo;
        int i, n_pdos = 0;
        KIRQL irql;
+       int l_all_pdos = 0;
 
        
        pdo = (PDEVICE_OBJECT *)ExAllocatePoolWithTag(
@@ -380,6 +383,7 @@ static BOOLEAN PciFindPdoByPdoAndLocation(
 
        // find and store all bus PDO   s (because the bridge is a bus enumerated device)
        for ( l_pPdo = l_pDrv->DeviceObject; l_pPdo; l_pPdo = l_pPdo->NextDevice ) {
+               l_all_pdos++;
                if ( l_pPdo->Flags & DO_BUS_ENUMERATED_DEVICE ) {
                        pdo[n_pdos] = l_pPdo;
                        if (++n_pdos >= N_PCI_DEVICES)
@@ -389,6 +393,8 @@ static BOOLEAN PciFindPdoByPdoAndLocation(
 
        // return to previous level
        KeLowerIrql(irql);
+       //TBD: change TRACE_LEVEL_ERROR to TRACE_LEVEL_INFORMATION      
+       HCA_PRINT(TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,("Found %d PCI.SYS's PDOs (from %d)\n", n_pdos, l_all_pdos ));
        
        //  loop over all the PCI driver devices
        l_pPdo = NULL;  /* mark, that we didn't find PDO */
@@ -409,6 +415,96 @@ static BOOLEAN PciFindPdoByPdoAndLocation(
        return (BOOLEAN)!!*po_pPdo;     
 }
 
+
+/*------------------------------------------------------------------------------------------------------*/
+
+/*
+ * Function: FindBridgeIf
+ *
+ * Parameters:
+ *             IN              pi_ext                          - device extension
+ *             OUT     pi_pInterface   - bus interface to work with the bridge
+ * 
+ * Returns:
+ *             FALSE   - the bridge was not found
+ *     TRUE    - a device was found;  *po_pPdo contains its PDO
+ *
+ * Description:
+ *             The function finds PDO of the bridge by HCA's bus number
+ *                     
+ */
+int
+FindBridgeIf_old(
+       IN hca_dev_ext_t                *pi_ext,
+       IN      PBUS_INTERFACE_STANDARD pi_pInterface
+       )
+{
+       NTSTATUS rc;
+       IO_STACK_LOCATION l_Iosl;
+       PDEVICE_RELATIONS l_pDr;
+       PDEVICE_OBJECT                  l_pPdo;
+       ULONG l_DevFunc, l_Bus;
+       // parameter buffer for the request
+       IO_STACK_LOCATION l_Stack;
+
+       // find bridge location
+       if (!PciFindBridgeByBus( pi_ext->bus_number,  &l_Bus, &l_DevFunc ))
+               return FALSE;
+       
+       // find PDO of our bus driver (bypassing possible low filter drivers)
+       RtlZeroMemory( &l_Iosl, sizeof(l_Iosl) );
+       l_Iosl.Parameters.QueryDeviceRelations.Type = TargetDeviceRelation;
+       rc = SendAwaitIrp(
+               pi_ext->cl_ext.p_self_do,
+               pi_ext->cl_ext.p_next_do,
+               IRP_MJ_PNP,
+               IRP_MN_QUERY_DEVICE_RELATIONS,
+               &l_Iosl.Parameters,
+               sizeof(l_Iosl.Parameters.QueryDeviceRelations),
+               &l_pDr
+                );
+       
+       if (!NT_SUCCESS (rc)) {
+               HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,("IRP_MN_QUERY_DEVICE_RELATIONS failed (%#x);: Fdo %p, Ldo %p \n",
+                       rc, pi_ext->cl_ext.p_self_do, pi_ext->cl_ext.p_next_do ));
+               return FALSE;
+       }
+               
+       //TBD: change TRACE_LEVEL_ERROR to TRACE_LEVEL_INFORMATION      
+       HCA_PRINT(TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,("IRP_MN_QUERY_DEVICE_RELATIONS for Fdo %p, Ldo %p: num_of_PDOs %d, PDO %p \n",
+               pi_ext->cl_ext.p_self_do, pi_ext->cl_ext.p_next_do, l_pDr->Count, l_pDr->Objects[0] ));
+       
+       /* get the PDO of Bridge */
+       if (!PciFindPdoByPdoAndLocation( l_pDr->Objects[0], 
+               l_Bus, l_DevFunc, &l_pPdo )) {
+               HCA_PRINT( TRACE_LEVEL_ERROR  ,HCA_DBG_SHIM  ,("Not found bridge's (bus %d, dev/func %x. pdo %p) PDO - can't restore the PCI header \n",
+                               l_Bus, l_DevFunc, l_pDr->Objects[0] ));
+               return FALSE;
+       } 
+       //TBD: change TRACE_LEVEL_ERROR to TRACE_LEVEL_INFORMATION      
+       HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,("Found bridge's PDO %p (bus %d, dev/func %x. HcaPdo %p) \n",
+               l_pPdo, l_Bus, l_DevFunc, l_pDr->Objects[0] ));
+               
+       // clean interface data
+       RtlZeroMemory( (PCHAR)pi_pInterface, sizeof(BUS_INTERFACE_STANDARD) );
+       
+       // fill request parameters
+       l_Stack.Parameters.QueryInterface.InterfaceType                 = (LPGUID) &GUID_BUS_INTERFACE_STANDARD;
+       l_Stack.Parameters.QueryInterface.Size                                  = sizeof(BUS_INTERFACE_STANDARD);
+       l_Stack.Parameters.QueryInterface.Version                               = 1;
+       l_Stack.Parameters.QueryInterface.Interface                     = (PINTERFACE)pi_pInterface;
+       l_Stack.Parameters.QueryInterface.InterfaceSpecificData = NULL;
+       
+       rc =SendAwaitIrp( pi_ext->cl_ext.p_self_do, l_pPdo, IRP_MJ_PNP, 
+               IRP_MN_QUERY_INTERFACE, &l_Stack.Parameters, sizeof(l_Stack.Parameters), NULL);
+       if (!NT_SUCCESS (rc)) 
+               return FALSE;
+
+       return TRUE;
+}
+
+#endif
+
 /*----------------------------------------------------------------*/
 
 /* Function: SendAwaitIrpCompletion
@@ -558,92 +654,227 @@ Blocking Mode)
 
 } /* SendAwaitIrp */
 
+
 /*------------------------------------------------------------------------------------------------------*/
 
 /*
- * Function: FindBridgeIf
+ * Function: FindBridgeIf_new
  *
  * Parameters:
- *             IN              pi_ext                          - device extension
- *             OUT     pi_pInterface   - bus interface to work with the bridge
+ *             IN              pi_pPdo                 - PDO of HCA's bus device
+ *             IN      pi_Bus, pi_DevFunc      - bridge location
+ *             OUT     po_pPdo                 - pointer to PDO of the bridge, when found
  * 
  * Returns:
  *             FALSE   - the bridge was not found
  *     TRUE    - a device was found;  *po_pPdo contains its PDO
  *
  * Description:
- *             The function finds PDO of the bridge by HCA's bus number
- *                     
+ *             The function finds and opens the bus interface for Tavor HCA
+ *
+ * Algorithm:
+ *     1. find all PDOs of PCI.SYS driver and save it into an array;
+ *     2. For each PDO open its bus i/f and check whether it is our bridge;
+ *
+ *     Note:
+ *             1. It is a "hack" algorithm. It uses some fields of system structures and some
+ *             optimistic assumptions - see more below
+ *             2. We dangerously assume, that during part to of the algoritm no PDO will removed or added !
  */
 int
-FindBridgeIf(
+FindBridgeIf_new(
        IN hca_dev_ext_t                *pi_ext,
-       IN      PBUS_INTERFACE_STANDARD pi_pInterface
+       OUT PBUS_INTERFACE_STANDARD     pi_pInterface
        )
 {
-       NTSTATUS rc;
-       IO_STACK_LOCATION l_Iosl;
-       PDEVICE_RELATIONS l_pDr;
-       PDEVICE_OBJECT                  l_pPdo;
-       ULONG l_DevFunc, l_Bus;
-       // parameter buffer for the request
-       IO_STACK_LOCATION l_Stack;
+       NTSTATUS l_Status;
+       int rc = FALSE; /* result - "not found" by default */
+       int n_pdos = 0;                 /* number of PCI.SYS's PDOs */
+       PDEVICE_OBJECT *pdo;    /* an array of PCI.SYS's PDOs */
+       PDEVICE_OBJECT l_pHcaPdo;
+
+       { // get HCA's bus PDO
+               IO_STACK_LOCATION l_Iosl;
+               PDEVICE_RELATIONS l_pDr;
+
+               // find PDO of our bus driver (bypassing possible low filter drivers)
+               RtlZeroMemory( &l_Iosl, sizeof(l_Iosl) );
+               l_Iosl.Parameters.QueryDeviceRelations.Type = TargetDeviceRelation;
+               l_Status = SendAwaitIrp(
+                       pi_ext->cl_ext.p_self_do,
+                       pi_ext->cl_ext.p_next_do,
+                       IRP_MJ_PNP,
+                       IRP_MN_QUERY_DEVICE_RELATIONS,
+                       &l_Iosl.Parameters,
+                       sizeof(l_Iosl.Parameters.QueryDeviceRelations),
+                       &l_pDr
+                        );
+               
+               if (!NT_SUCCESS (l_Status)) {
+                       HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,("IRP_MN_QUERY_DEVICE_RELATIONS for TargetDeviceRelation failed (%#x);: Fdo %p, Ldo %p \n",
+                               l_Status, pi_ext->cl_ext.p_self_do, pi_ext->cl_ext.p_next_do ));
+                       goto exit;
+               }
 
-       // find bridge location
-       if (!PciFindBridgeByBus( pi_ext->bus_number,  &l_Bus, &l_DevFunc ))
-               return FALSE;
-       
-       // find PDO of our bus driver (bypassing possible low filter drivers)
-       RtlZeroMemory( &l_Iosl, sizeof(l_Iosl) );
-       l_Iosl.Parameters.QueryDeviceRelations.Type = TargetDeviceRelation;
-       rc = SendAwaitIrp(
-               pi_ext->cl_ext.p_self_do,
-               pi_ext->cl_ext.p_next_do,
-               IRP_MJ_PNP,
-               IRP_MN_QUERY_DEVICE_RELATIONS,
-               &l_Iosl.Parameters,
-               sizeof(l_Iosl.Parameters.QueryDeviceRelations),
-               &l_pDr
-                );
-       
-       if (!NT_SUCCESS (rc)) {
-               HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,("IRP_MN_QUERY_DEVICE_RELATIONS failed (%#x);: Fdo %p, Ldo %p \n",
-                       rc, pi_ext->cl_ext.p_self_do, pi_ext->cl_ext.p_next_do ));
-               return FALSE;
+               //TBD: change TRACE_LEVEL_ERROR to TRACE_LEVEL_INFORMATION      
+               HCA_PRINT(TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,("IRP_MN_QUERY_DEVICE_RELATIONS for TargetDeviceRelation for Fdo %p, Ldo %p: num_of_PDOs %d, PDO %p \n",
+                       pi_ext->cl_ext.p_self_do, pi_ext->cl_ext.p_next_do, l_pDr->Count, l_pDr->Objects[0] ));
+               l_pHcaPdo = l_pDr->Objects[0];
        }
-               
-       HCA_PRINT(TRACE_LEVEL_INFORMATION ,HCA_DBG_SHIM ,("IRP_MN_QUERY_DEVICE_RELATIONS for Fdo %p, Ldo %p: num_of_PDOs %d, PDO %p \n",
-               pi_ext->cl_ext.p_self_do, pi_ext->cl_ext.p_next_do, l_pDr->Count, l_pDr->Objects[0] ));
+
+       { // allocate and fill an array with all PCI.SYS PDO devices
+               // suppose that there is no more than N_PCI_DEVICES, belonging to PCI.SYS
+               #define N_PCI_DEVICES   256
+               KIRQL irql;
+               PDRIVER_OBJECT l_pDrv;
+               PDEVICE_OBJECT l_pPdo;
+               int l_all_pdos = 0;
        
-       /* get the PDO of Bridge */
-       if (!PciFindPdoByPdoAndLocation( l_pDr->Objects[0], 
-               l_Bus, l_DevFunc, &l_pPdo )) {
-               HCA_PRINT( TRACE_LEVEL_ERROR  ,HCA_DBG_SHIM  ,("Not found bridge's (bus %d, dev/func %x. pdo %p) PDO - can't restore the PCI header \n",
-                               l_Bus, l_DevFunc, l_pDr->Objects[0] ));
-               return FALSE;
-       } 
-       HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_SHIM ,("Found bridge's PDO %p (bus %d, dev/func %x. pdo %p) \n",
-               l_pPdo, l_Bus, l_DevFunc, l_pDr->Objects[0] ));
+               pdo = (PDEVICE_OBJECT *)ExAllocatePoolWithTag(
+                       NonPagedPool,
+                       N_PCI_DEVICES * sizeof(PDEVICE_OBJECT),
+                       MT_TAG_KERNEL );
+               if (!pdo)
+                       goto exit;
                
-       // clean interface data
-       RtlZeroMemory( (PCHAR)pi_pInterface, sizeof(BUS_INTERFACE_STANDARD) );
-       
-       // fill request parameters
-       l_Stack.Parameters.QueryInterface.InterfaceType                 = (LPGUID) &GUID_BUS_INTERFACE_STANDARD;
-       l_Stack.Parameters.QueryInterface.Size                                  = sizeof(BUS_INTERFACE_STANDARD);
-       l_Stack.Parameters.QueryInterface.Version                               = 1;
-       l_Stack.Parameters.QueryInterface.Interface                     = (PINTERFACE)pi_pInterface;
-       l_Stack.Parameters.QueryInterface.InterfaceSpecificData = NULL;
-       
-       rc =SendAwaitIrp( pi_ext->cl_ext.p_self_do, l_pPdo, IRP_MJ_PNP, 
-               IRP_MN_QUERY_INTERFACE, &l_Stack.Parameters, sizeof(l_Stack.Parameters), NULL);
-       if (!NT_SUCCESS (rc)) 
-               return FALSE;
+               // suppose, that PDOs are added only at PASSIVE_LEVEL
+               irql = KeRaiseIrqlToDpcLevel();
+                       
+               // get to the PCI.SYS driver
+               l_pDrv = l_pHcaPdo->DriverObject;
+
+               // find and store all bus PDO   s (because the bridge is a bus enumerated device)
+               for ( l_pPdo = l_pDrv->DeviceObject; l_pPdo; l_pPdo = l_pPdo->NextDevice ) {
+                       l_all_pdos++;
+                       if ( l_pPdo->Flags & DO_BUS_ENUMERATED_DEVICE ) {
+                               pdo[n_pdos] = l_pPdo;
+                               if (++n_pdos >= N_PCI_DEVICES) {
+                                       HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,
+                                               ("There are more than %d children of PCI.SYS. Skipping the rest \n", N_PCI_DEVICES ));
+                                       break;
+                               }
+                       }
+               }
 
-       return TRUE;
-}
+               // return to previous level
+               KeLowerIrql(irql);
+               //TBD: change TRACE_LEVEL_ERROR to TRACE_LEVEL_INFORMATION      
+               HCA_PRINT(TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,("Found %d PCI.SYS's PDOs (from %d) \n", n_pdos, l_all_pdos ));
+       }
+
+       { // Find PDO of the Bridge of our HCA and return open bus interface to it
+               int i;
+               ULONG data, l_SecBus;
+               IO_STACK_LOCATION l_Stack; // parameter buffer for the request
+               ULONG l_DevId = ((int)(23110) << 16) | PCI_VENDOR_ID_MELLANOX;  
+
+               //  loop over all the PCI driver devices
+               for ( i = 0; i < n_pdos; ++i ) {
+
+                       // clean interface data
+                       RtlZeroMemory( (PCHAR)pi_pInterface, sizeof(BUS_INTERFACE_STANDARD) );
+                       
+                       // get Bus Interface for the current PDO
+                       l_Stack.Parameters.QueryInterface.InterfaceType                 = (LPGUID) &GUID_BUS_INTERFACE_STANDARD;
+                       l_Stack.Parameters.QueryInterface.Size                                  = sizeof(BUS_INTERFACE_STANDARD);
+                       l_Stack.Parameters.QueryInterface.Version                               = 1;
+                       l_Stack.Parameters.QueryInterface.Interface                     = (PINTERFACE)pi_pInterface;
+                       l_Stack.Parameters.QueryInterface.InterfaceSpecificData = NULL;
+                       
+                       l_Status =SendAwaitIrp( pi_ext->cl_ext.p_self_do, pdo[i], IRP_MJ_PNP, 
+                               IRP_MN_QUERY_INTERFACE, &l_Stack.Parameters, sizeof(l_Stack.Parameters), NULL);
+                       if (!NT_SUCCESS (l_Status)) {
+                               //TBD: change TRACE_LEVEL_ERROR to TRACE_LEVEL_WARNING  
+                               HCA_PRINT( TRACE_LEVEL_ERROR  ,HCA_DBG_SHIM  ,
+                                       ("Failed to get bus interface for pdo[%d] %p, error %#x \n", i, pdo[i], l_Status ));
+                               continue;
+                       }
+
+                       // Read DevID
+                       data = 0;
+                       if (4 != pi_pInterface->GetBusData( pi_pInterface->Context,
+                               PCI_WHICHSPACE_CONFIG, &data, 0, 4)) {
+                               //TBD: change TRACE_LEVEL_ERROR to TRACE_LEVEL_WARNING  
+                               HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, 
+                                       ("Failed to read DevID for pdo[%d] %p, data %#x \n", i, pdo[i], data ));
+                               goto next_loop;
+                       }
+
+                       if (data != l_DevId) {
+                               //TBD: change TRACE_LEVEL_ERROR to TRACE_LEVEL_INFORMATION      
+                               HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, 
+                                       ("Not Tavor bridge: pdo[%d] %p, data %#x \n", i, pdo[i], data ));
+                               goto next_loop;
+                       }
+
+                       // Found Tavor Bridge - read its SecondaryBus
+                       data = 0;
+                       if (4 != pi_pInterface->GetBusData( pi_pInterface->Context,
+                               PCI_WHICHSPACE_CONFIG, &data, 24, 4)) { /* 24 - PrimaryBus, 25 - SecondaryBus, 26 - SubordinateBus */
+                               //TBD: change TRACE_LEVEL_ERROR to TRACE_LEVEL_WARNING  
+                               HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, 
+                                       ("Failed to read SecondaryBus for pdo[%d] %p, data %#x \n", i, pdo[i], data ));
+                               goto next_loop;
+                       }
+
+                       l_SecBus = (data >> 16) & 255;
+                       if (l_SecBus != pi_ext->bus_number) {
+                               //TBD: change TRACE_LEVEL_ERROR to TRACE_LEVEL_INFORMATION      
+                               HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, 
+                                       ("Wrong bridge for our HCA: pdo[%d] %p, SecBus %d, HcaBus %d \n", i, pdo[i], l_SecBus, pi_ext->bus_number ));
+                               goto next_loop;
+                       }
+                       else {
+                               ULONG l_DevFunc, l_Bus;
+                               l_Status = MdGetDevLocation( pdo[i], &l_Bus, &l_DevFunc );
+                               //TBD: change TRACE_LEVEL_ERROR to TRACE_LEVEL_WARNING  
+                               HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, 
+                                       ("Found bridge for our HCA: pdo[%d] %p (bus %d, dev/func %d, HcaPdo %p), SecBus %d, HcaBus %d \n", 
+                                       i, pdo[i], l_Bus, l_DevFunc, l_pHcaPdo, l_SecBus, pi_ext->bus_number ));
+                               rc = TRUE;
+                               break;
+                       }
+               next_loop:      
+                       pi_pInterface->InterfaceDereference( pi_pInterface->Context );
+               }
+       }
 
+       ExFreePool(pdo);
+exit:  
+       return rc;      
+}
 
 /*----------------------------------------------------------------*/
 
+int
+FindBridgeIf(
+       IN hca_dev_ext_t                *pi_ext,
+       IN      PBUS_INTERFACE_STANDARD pi_pInterface
+       )
+{
+       int rc;
+
+#ifdef USE_HAL
+
+       rc = FindBridgeIf_old(pi_ext,pi_pInterface);
+       if (rc) {
+               HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, ("Old way works !\n"));
+       }
+       else {
+               HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, ("Old way fails !\n"));
+       }
+
+#else
 
+       rc = FindBridgeIf_new(pi_ext,pi_pInterface);
+       if (rc) {
+               HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, ("New way works !\n"));
+       }
+       else {
+               HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, ("New way fails !\n"));
+       }
+
+#endif 
+
+       return rc;
+}