return l_Status;
}
-#ifdef USE_HAL
-/*----------------------------------------------------------------*/
-
-/*
- * Function: PciFindDeviceByBusAndId
- *
- * Parameters:
- * IN pi_Bus - a bus, to start the scan
- * IN pi_DevId - Device Id to search
- * INOUT po_pDevFunc - pointer to dev/func, from which to start the search
- *
- * Returns:
- * FALSE - device not found
- * TRUE - a device was found; *po_pDevFunc contains its location
- *
- * Description:
- * The function is intended for iterative search on one bus.
- * It looks for the device of pi_DevId id, starting from device with
- * *po_pDevFunc location. When it finds the next device of that id, it updates
- * *po_pDevFunc with the found device' location
- *
- */
-BOOLEAN PciFindDeviceByBusAndId(
- IN ULONG pi_Bus,
- IN ULONG pi_DevId,
- IN OUT PULONG po_pDevFunc )
-{
- ULONG l_DevId;
- ULONG l_Bytes;
- ULONG l_Device;
- ULONG l_Function;
-
- // calculate, where to start the search
- l_Device = *po_pDevFunc & 0x01f;
- l_Function = (*po_pDevFunc >> 5) & 7;
- for (; l_Device < N_DEVICES; l_Device++, l_Function = 0 ) {
- for (; l_Function < N_FUNCTIONS; l_Function++ ) {
- l_Bytes = HalGetBusDataByOffset(
- PCIConfiguration,
- pi_Bus,
- l_Device |(l_Function<<5),
- (PVOID)&l_DevId,
- 0,
- sizeof(ULONG)
- );
- if (l_Bytes != sizeof(ULONG))
- continue; /* as if - "not found" */
- if (l_DevId == pi_DevId)
- goto ExitFound;
- }
- }
- return FALSE;
-
-ExitFound:
- *po_pDevFunc = l_Device |(l_Function<<5);
- return TRUE;
-}
-
-/*----------------------------------------------------------------*/
-
-/*
- * Function: PciFindDeviceById
- *
- * Parameters:
- * IN pi_DevId - Device Id to search
- * INOUT po_pBus - pointer to bus number, from which to start the search
- * INOUT po_pDevFunc - pointer to dev/func, from which to start the search
- *
- * Returns:
- * FALSE - device was not found
- * TRUE - a device was found; *po_pBus/*po_pDevFunc contain its location
- *
- * Description:
- * The function is intended for an iterative search.
- * It looks for the device of pi_DevId id, starting from device with *po_pBus and
- * *po_pDevFunc location. When it finds the next device of that id, updates *po_pBus
- * and *po_pDevFunc with the found device' location
- *
- */
-static
-BOOLEAN PciFindDeviceById(
- IN ULONG pi_DevId,
- IN OUT PULONG po_pBus,
- IN OUT PULONG po_pDevFunc )
-{
- ULONG l_Bus;
- ULONG l_DevFunc = *po_pDevFunc;
-
- for (l_Bus= *po_pBus; l_Bus < N_BUSES; l_Bus++, l_DevFunc=0) {
- if (PciFindDeviceByBusAndId(l_Bus, pi_DevId, &l_DevFunc))
- break;
- }
- if (l_Bus >= N_BUSES)
- return FALSE;
-
- // found
- *po_pBus = l_Bus;
- *po_pDevFunc = l_DevFunc;
- return TRUE;
-}
-
-/*----------------------------------------------------------------*/
-
-/*
- * Function: PciFindBridgeByBus
- *
- * Parameters:
- * IN pi_SecBus - bus number of an HCA in question
- * OUT po_pBus - pointer to bus number of the bridge of the HCA, if found
- * OUT po_pDevFunc - pointer to dev/func of the bridge of the HCA, if found
- *
- * Returns:
- * FALSE - the bridge not found
- * TRUE - a device was found; *po_pBus/*po_pDevFunc contain its location
- *
- * Description:
- * The function scans all the buses to find the Bridge of an HCA device, found on bus pi_SecBus.
- * The appropiate bridge must have its PrimaryBus field in PCI cfg header equal to pi_SecBus.
- *
- */
-static BOOLEAN PciFindBridgeByBus(
- IN ULONG pi_SecBus,
- OUT PULONG po_pBus,
- OUT PULONG po_pDevFunc )
-{
- ULONG l_DevFunc=0, l_Bus=0;
- ULONG l_DevId = ((int)(23110) << 16) | PCI_VENDOR_ID_MELLANOX;
- ULONG l_SecBus, l_tmp, l_Bytes;
- ULONG l_Device;
- ULONG l_Function;
- int searching =1;
-
- while (searching) {
- /* look for a bridge */
- if (!PciFindDeviceById(l_DevId, &l_Bus, &l_DevFunc))
- return FALSE; /* bridge not found */
-
- /* found a bridge -check, whether it is ours */
- l_Bytes = HalGetBusDataByOffset(
- PCIConfiguration,
- l_Bus,
- l_DevFunc,
- (PVOID)&l_tmp,
- 24, /* 24 - PrimaryBus, 25 - SecondaryBus, 26 - SubordinateBus */
- sizeof(ULONG)
- );
- if (l_Bytes != sizeof(ULONG))
- goto NextDevice; /* as if - "not found" */
-
- l_SecBus = (l_tmp >> 16) & 255;
- if ( l_SecBus == pi_SecBus )
- break; /* found !!! */
-
-NextDevice:
- // calculate, where to continue the search
- l_Device = l_DevFunc & 0x01f;
- l_Function = (l_DevFunc >> 5) & 7;
- l_Function++;
- if (l_Function >= N_FUNCTIONS) {
- l_Function = 0;
- l_Device++;
- if (l_Device >= N_DEVICES) {
- l_Device = 0;
- l_Bus++;
- }
- if (l_Bus >= N_BUSES)
- return FALSE;
- }
- l_DevFunc = l_Device |(l_Function<<5);;
- }
-
- *po_pBus = l_Bus;
- *po_pDevFunc = l_DevFunc;
- return TRUE;
-}
-
-
-/*------------------------------------------------------------------------------------------------------*/
-
-/*
- * Function: PciFindPdoByPdoAndLocation
- *
- * Parameters:
- * 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 a Tavor bridge device by scanning through all the
- * devices of the PCI.SYS driver
- *
- * Note:
- * It is a "hack" algorithm. It uses some fields of system structures and some
- * optimistic assumptions - see more below
- */
-static BOOLEAN PciFindPdoByPdoAndLocation(
- IN PDEVICE_OBJECT pi_pPdo,
- IN ULONG pi_Bus,
- IN ULONG pi_DevFunc,
- OUT PDEVICE_OBJECT * po_pPdo )
-{
- PDRIVER_OBJECT l_pDrv;
- PDEVICE_OBJECT l_pPdo;
- NTSTATUS l_Status;
- ULONG l_Bus, l_DevFunc;
- // suppose that there is no more than N_PCI_DEVICES, belonging to PCI.SYS
- #define N_PCI_DEVICES 256
- // suppose that the PDO objects, once created, never get moved
- PDEVICE_OBJECT *pdo;
- int i, n_pdos = 0;
- KIRQL irql;
- int l_all_pdos = 0;
-
-
- pdo = (PDEVICE_OBJECT *)ExAllocatePoolWithTag(
- NonPagedPool,
- N_PCI_DEVICES * sizeof(PDEVICE_OBJECT),
- MT_TAG_KERNEL );
- if (!pdo)
- return FALSE;
-
- // suppose, that PDOs are added only at PASSIVE_LEVEL
- irql = KeRaiseIrqlToDpcLevel();
-
- // get to the PCI.SYS driver
- l_pDrv = pi_pPdo->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)
- break;
- }
- }
-
- // 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 */
- for ( i = 0; i < n_pdos; ++i ) {
- // get the location of the device of that PDO
- l_Status = MdGetDevLocation( pdo[i], &l_Bus, &l_DevFunc );
- if (l_Status != STATUS_SUCCESS)
- continue;
- // check, whether it's our device
- if (l_Bus == pi_Bus && l_DevFunc == pi_DevFunc) {
- l_pPdo = pdo[i];
- break;
- }
- }
-
- *po_pPdo = l_pPdo;
- ExFreePool(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
* 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 !
+ * 3. PCI.SYS gives to its child devices names like \Device\NTPNP_PCI00nn. I tried to get Bridge's
+ * PDO by calling IoGetDeviceObjectPointer with all such names, but it returns STATUS_NO_SUCH_DEVICE
+ * for the *right* name of Bridge device !(IoGetDeviceObjectPointer really opens the device. Maybe Bridge is in exclusive use)
*/
int
-FindBridgeIf_new(
+FindBridgeIf(
IN hca_dev_ext_t *pi_ext,
OUT PBUS_INTERFACE_STANDARD pi_pInterface
)
goto exit;
}
- //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",
+ HCA_PRINT(TRACE_LEVEL_INFORMATION ,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];
}
// 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 ));
+ HCA_PRINT(TRACE_LEVEL_INFORMATION ,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
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 ,
+ HCA_PRINT( TRACE_LEVEL_WARNING ,HCA_DBG_SHIM ,
("Failed to get bus interface for pdo[%d] %p, error %#x \n", i, pdo[i], l_Status ));
continue;
}
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,
+ HCA_PRINT( TRACE_LEVEL_WARNING, 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,
+ HCA_PRINT( TRACE_LEVEL_INFORMATION, HCA_DBG_PNP,
("Not Tavor bridge: pdo[%d] %p, data %#x \n", i, pdo[i], data ));
goto next_loop;
}
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,
+ HCA_PRINT( TRACE_LEVEL_WARNING, 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,
+ HCA_PRINT( TRACE_LEVEL_INFORMATION, 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,
+ HCA_PRINT( TRACE_LEVEL_INFORMATION, 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;
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;
-}