} /* 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
/*----------------------------------------------------------------*/
/*
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;
-}
-
/*------------------------------------------------------------------------------------------------------*/
* 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,
PDEVICE_OBJECT *pdo;
int i, n_pdos = 0;
KIRQL irql;
+ int l_all_pdos = 0;
pdo = (PDEVICE_OBJECT *)ExAllocatePoolWithTag(
// 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)
// 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 */
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
} /* 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;
+}