3 #include "hca_driver.h"
7 #if defined(EVENT_TRACING)
11 #include "mt_reset_tavor.tmh"
15 #pragma warning(disable : 4996)
18 #define N_BUSES 16 /* max number of PCI buses */
19 #define N_DEVICES 32 /* max number of devices on one bus */
20 #define N_FUNCTIONS 8 /* max number of functions on one device */
21 #define N_CARDS 8 /* max number of HCA cards */
23 /*----------------------------------------------------------------*/
27 IN PWCHAR pi_BufStart,
29 IN WCHAR pi_FromPattern,
35 Converts wide-character string into ASCII
39 pi_BufStart.......... start of the source string
40 pi_BufEnd............ end of the source string
41 pi_FromPattern....... start of pattern range to find
42 pi_ToPattern......... end of pattern range to find
46 pointer to the first pattern found or NULL (when reached the end)
51 PWCHAR l_pResult = pi_BufStart;
53 while (l_pResult < pi_BufEnd )
55 if (*l_pResult >= pi_FromPattern && *l_pResult <= pi_ToPattern)
65 /*----------------------------------------------------------------*/
68 * Function: MdGetDevLocation
71 * IN pi_pPdo - PDO of a device in question
72 * OUT po_pBus - pointer to the bus number of the device in question
73 * OUT po_pDevFunc - pointer to dev/func of the device, if found
76 * not STATUS_SUCCESS - the device location was not found
77 * STATUS_SUCCESS - the device location was found and returned in OUT parameters
80 * The function uses IoGetDeviceProperty to get the location of a device with given PDO
85 IN PDEVICE_OBJECT pi_pPdo,
87 OUT ULONG * po_pDevFunc
90 ULONG l_BusNumber, l_DevNumber, l_Function, l_ResultLength = 0;
91 WCHAR l_Buffer[40], *l_pEnd, *l_pBuf = l_Buffer, *l_pBufEnd = l_Buffer + sizeof(l_Buffer);
93 UNICODE_STRING l_UnicodeNumber;
97 RtlZeroMemory( l_Buffer, sizeof(l_Buffer) );
99 /* Get the device number */
100 l_Status = IoGetDeviceProperty(pi_pPdo,
101 DevicePropertyLocationInformation, sizeof(l_Buffer), l_Buffer, &l_ResultLength);
103 /* Verify if the function was successful */
104 if ( !NT_SUCCESS(l_Status) || !l_ResultLength ) {
105 HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,("(MdGetDevLocation) Unable to get device number: Status 0x%x, ResultSize %d \n",
106 l_Status, l_ResultLength ));
110 // ALL THE BELOW CRAP WE DO INSTEAD OF
111 // sscanf(l_Buffer, "PCI bus %d, device %d, function %d", &l_BusNumber, &l_DevNumber, &l_Function );
113 /* take bus number */
114 l_pBuf = WcharFindChar( l_pBuf, l_pBufEnd, L'0', L'9' );
115 if (l_pBuf == NULL) goto err;
116 l_pEnd = WcharFindChar( l_pBuf, l_pBufEnd, L',', L',' );
117 if (l_pEnd == NULL) goto err;
118 l_UnicodeNumber.Length = l_UnicodeNumber.MaximumLength = (USHORT)((PCHAR)l_pEnd - (PCHAR)l_pBuf);
119 l_UnicodeNumber.Buffer = l_pBuf; l_pBuf = l_pEnd;
120 RtlUnicodeStringToInteger( &l_UnicodeNumber, 10, &l_BusNumber);
122 /* take slot number */
123 l_pBuf = WcharFindChar( l_pBuf, l_pBufEnd, L'0', L'9' );
124 if (l_pBuf == NULL) goto err;
125 l_pEnd = WcharFindChar( l_pBuf, l_pBufEnd, L',', L',' );
126 if (l_pEnd == NULL) goto err;
127 l_UnicodeNumber.Length = l_UnicodeNumber.MaximumLength = (USHORT)((PCHAR)l_pEnd - (PCHAR)l_pBuf);
128 l_UnicodeNumber.Buffer = l_pBuf; l_pBuf = l_pEnd;
129 RtlUnicodeStringToInteger( &l_UnicodeNumber, 10, &l_DevNumber);
131 /* take function number */
132 *(l_Buffer + (l_ResultLength>>1)) = 0; /* set end of string */
133 l_pBuf = WcharFindChar( l_pBuf, l_pBufEnd, L'0', L'9' );
134 if (l_pBuf == NULL) goto err;
135 l_pEnd = WcharFindChar( l_pBuf, l_pBufEnd, 0, 0 );
136 if (l_pEnd == NULL) goto err;
137 l_UnicodeNumber.Length = l_UnicodeNumber.MaximumLength = (USHORT)((PCHAR)l_pEnd - (PCHAR)l_pBuf);
138 l_UnicodeNumber.Buffer = l_pBuf; l_pBuf = l_pEnd;
139 RtlUnicodeStringToInteger( &l_UnicodeNumber, 10, &l_Function);
141 /* return the results */
142 *po_pBus = l_BusNumber;
143 *po_pDevFunc = (l_DevNumber & 0x01f) | ((l_Function & 7) << 5);
148 l_Status = STATUS_UNSUCCESSFUL;
154 /*----------------------------------------------------------------*/
157 * Function: PciFindDeviceByBusAndId
160 * IN pi_Bus - a bus, to start the scan
161 * IN pi_DevId - Device Id to search
162 * INOUT po_pDevFunc - pointer to dev/func, from which to start the search
165 * FALSE - device not found
166 * TRUE - a device was found; *po_pDevFunc contains its location
169 * The function is intended for iterative search on one bus.
170 * It looks for the device of pi_DevId id, starting from device with
171 * *po_pDevFunc location. When it finds the next device of that id, it updates
172 * *po_pDevFunc with the found device' location
175 BOOLEAN PciFindDeviceByBusAndId(
178 IN OUT PULONG po_pDevFunc )
185 // calculate, where to start the search
186 l_Device = *po_pDevFunc & 0x01f;
187 l_Function = (*po_pDevFunc >> 5) & 7;
188 for (; l_Device < N_DEVICES; l_Device++, l_Function = 0 ) {
189 for (; l_Function < N_FUNCTIONS; l_Function++ ) {
190 l_Bytes = HalGetBusDataByOffset(
193 l_Device |(l_Function<<5),
198 if (l_Bytes != sizeof(ULONG))
199 continue; /* as if - "not found" */
200 if (l_DevId == pi_DevId)
207 *po_pDevFunc = l_Device |(l_Function<<5);
211 /*----------------------------------------------------------------*/
214 * Function: PciFindDeviceById
217 * IN pi_DevId - Device Id to search
218 * INOUT po_pBus - pointer to bus number, from which to start the search
219 * INOUT po_pDevFunc - pointer to dev/func, from which to start the search
222 * FALSE - device was not found
223 * TRUE - a device was found; *po_pBus/*po_pDevFunc contain its location
226 * The function is intended for an iterative search.
227 * It looks for the device of pi_DevId id, starting from device with *po_pBus and
228 * *po_pDevFunc location. When it finds the next device of that id, updates *po_pBus
229 * and *po_pDevFunc with the found device' location
233 BOOLEAN PciFindDeviceById(
235 IN OUT PULONG po_pBus,
236 IN OUT PULONG po_pDevFunc )
239 ULONG l_DevFunc = *po_pDevFunc;
241 for (l_Bus= *po_pBus; l_Bus < N_BUSES; l_Bus++, l_DevFunc=0) {
242 if (PciFindDeviceByBusAndId(l_Bus, pi_DevId, &l_DevFunc))
245 if (l_Bus >= N_BUSES)
250 *po_pDevFunc = l_DevFunc;
254 /*----------------------------------------------------------------*/
257 * Function: PciFindBridgeByBus
260 * IN pi_SecBus - bus number of an HCA in question
261 * OUT po_pBus - pointer to bus number of the bridge of the HCA, if found
262 * OUT po_pDevFunc - pointer to dev/func of the bridge of the HCA, if found
265 * FALSE - the bridge not found
266 * TRUE - a device was found; *po_pBus/*po_pDevFunc contain its location
269 * The function scans all the buses to find the Bridge of an HCA device, found on bus pi_SecBus.
270 * The appropiate bridge must have its PrimaryBus field in PCI cfg header equal to pi_SecBus.
273 static BOOLEAN PciFindBridgeByBus(
276 OUT PULONG po_pDevFunc )
278 ULONG l_DevFunc=0, l_Bus=0;
279 ULONG l_DevId = ((int)(23110) << 16) | PCI_VENDOR_ID_MELLANOX;
280 ULONG l_SecBus, l_tmp, l_Bytes;
286 /* look for a bridge */
287 if (!PciFindDeviceById(l_DevId, &l_Bus, &l_DevFunc))
288 return FALSE; /* bridge not found */
290 /* found a bridge -check, whether it is ours */
291 l_Bytes = HalGetBusDataByOffset(
296 24, /* 24 - PrimaryBus, 25 - SecondaryBus, 26 - SubordinateBus */
299 if (l_Bytes != sizeof(ULONG))
300 goto NextDevice; /* as if - "not found" */
302 l_SecBus = (l_tmp >> 16) & 255;
303 if ( l_SecBus == pi_SecBus )
304 break; /* found !!! */
307 // calculate, where to continue the search
308 l_Device = l_DevFunc & 0x01f;
309 l_Function = (l_DevFunc >> 5) & 7;
311 if (l_Function >= N_FUNCTIONS) {
314 if (l_Device >= N_DEVICES) {
318 if (l_Bus >= N_BUSES)
321 l_DevFunc = l_Device |(l_Function<<5);;
325 *po_pDevFunc = l_DevFunc;
330 /*------------------------------------------------------------------------------------------------------*/
333 * Function: PciFindPdoByPdoAndLocation
336 * IN pi_pPdo - PDO of HCA's bus device
337 * IN pi_Bus, pi_DevFunc - bridge location
338 * OUT po_pPdo - pointer to PDO of the bridge, when found
341 * FALSE - the bridge was not found
342 * TRUE - a device was found; *po_pPdo contains its PDO
345 * The function finds PDO of a Tavor bridge device by scanning through all the
346 * devices of the PCI.SYS driver
349 * It is a "hack" algorithm. It uses some fields of system structures and some
350 * optimistic assumptions - see more below
352 static BOOLEAN PciFindPdoByPdoAndLocation(
353 IN PDEVICE_OBJECT pi_pPdo,
356 OUT PDEVICE_OBJECT * po_pPdo )
358 PDRIVER_OBJECT l_pDrv;
359 PDEVICE_OBJECT l_pPdo;
361 ULONG l_Bus, l_DevFunc;
362 // suppose that there is no more than N_PCI_DEVICES, belonging to PCI.SYS
363 #define N_PCI_DEVICES 256
364 // suppose that the PDO objects, once created, never get moved
371 pdo = (PDEVICE_OBJECT *)ExAllocatePoolWithTag(
373 N_PCI_DEVICES * sizeof(PDEVICE_OBJECT),
378 // suppose, that PDOs are added only at PASSIVE_LEVEL
379 irql = KeRaiseIrqlToDpcLevel();
381 // get to the PCI.SYS driver
382 l_pDrv = pi_pPdo->DriverObject;
384 // find and store all bus PDO s (because the bridge is a bus enumerated device)
385 for ( l_pPdo = l_pDrv->DeviceObject; l_pPdo; l_pPdo = l_pPdo->NextDevice ) {
387 if ( l_pPdo->Flags & DO_BUS_ENUMERATED_DEVICE ) {
388 pdo[n_pdos] = l_pPdo;
389 if (++n_pdos >= N_PCI_DEVICES)
394 // return to previous level
396 //TBD: change TRACE_LEVEL_ERROR to TRACE_LEVEL_INFORMATION
397 HCA_PRINT(TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,("Found %d PCI.SYS's PDOs (from %d)\n", n_pdos, l_all_pdos ));
399 // loop over all the PCI driver devices
400 l_pPdo = NULL; /* mark, that we didn't find PDO */
401 for ( i = 0; i < n_pdos; ++i ) {
402 // get the location of the device of that PDO
403 l_Status = MdGetDevLocation( pdo[i], &l_Bus, &l_DevFunc );
404 if (l_Status != STATUS_SUCCESS)
406 // check, whether it's our device
407 if (l_Bus == pi_Bus && l_DevFunc == pi_DevFunc) {
415 return (BOOLEAN)!!*po_pPdo;
419 /*------------------------------------------------------------------------------------------------------*/
422 * Function: FindBridgeIf
425 * IN pi_ext - device extension
426 * OUT pi_pInterface - bus interface to work with the bridge
429 * FALSE - the bridge was not found
430 * TRUE - a device was found; *po_pPdo contains its PDO
433 * The function finds PDO of the bridge by HCA's bus number
438 IN hca_dev_ext_t *pi_ext,
439 IN PBUS_INTERFACE_STANDARD pi_pInterface
443 IO_STACK_LOCATION l_Iosl;
444 PDEVICE_RELATIONS l_pDr;
445 PDEVICE_OBJECT l_pPdo;
446 ULONG l_DevFunc, l_Bus;
447 // parameter buffer for the request
448 IO_STACK_LOCATION l_Stack;
450 // find bridge location
451 if (!PciFindBridgeByBus( pi_ext->bus_number, &l_Bus, &l_DevFunc ))
454 // find PDO of our bus driver (bypassing possible low filter drivers)
455 RtlZeroMemory( &l_Iosl, sizeof(l_Iosl) );
456 l_Iosl.Parameters.QueryDeviceRelations.Type = TargetDeviceRelation;
458 pi_ext->cl_ext.p_self_do,
459 pi_ext->cl_ext.p_next_do,
461 IRP_MN_QUERY_DEVICE_RELATIONS,
463 sizeof(l_Iosl.Parameters.QueryDeviceRelations),
467 if (!NT_SUCCESS (rc)) {
468 HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,("IRP_MN_QUERY_DEVICE_RELATIONS failed (%#x);: Fdo %p, Ldo %p \n",
469 rc, pi_ext->cl_ext.p_self_do, pi_ext->cl_ext.p_next_do ));
473 //TBD: change TRACE_LEVEL_ERROR to TRACE_LEVEL_INFORMATION
474 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",
475 pi_ext->cl_ext.p_self_do, pi_ext->cl_ext.p_next_do, l_pDr->Count, l_pDr->Objects[0] ));
477 /* get the PDO of Bridge */
478 if (!PciFindPdoByPdoAndLocation( l_pDr->Objects[0],
479 l_Bus, l_DevFunc, &l_pPdo )) {
480 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",
481 l_Bus, l_DevFunc, l_pDr->Objects[0] ));
484 //TBD: change TRACE_LEVEL_ERROR to TRACE_LEVEL_INFORMATION
485 HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,("Found bridge's PDO %p (bus %d, dev/func %x. HcaPdo %p) \n",
486 l_pPdo, l_Bus, l_DevFunc, l_pDr->Objects[0] ));
488 // clean interface data
489 RtlZeroMemory( (PCHAR)pi_pInterface, sizeof(BUS_INTERFACE_STANDARD) );
491 // fill request parameters
492 l_Stack.Parameters.QueryInterface.InterfaceType = (LPGUID) &GUID_BUS_INTERFACE_STANDARD;
493 l_Stack.Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
494 l_Stack.Parameters.QueryInterface.Version = 1;
495 l_Stack.Parameters.QueryInterface.Interface = (PINTERFACE)pi_pInterface;
496 l_Stack.Parameters.QueryInterface.InterfaceSpecificData = NULL;
498 rc =SendAwaitIrp( pi_ext->cl_ext.p_self_do, l_pPdo, IRP_MJ_PNP,
499 IRP_MN_QUERY_INTERFACE, &l_Stack.Parameters, sizeof(l_Stack.Parameters), NULL);
500 if (!NT_SUCCESS (rc))
508 /*----------------------------------------------------------------*/
510 /* Function: SendAwaitIrpCompletion
515 * IRP completion routine
518 * pointer to the entry on SUCCESS
524 SendAwaitIrpCompletion (
525 IN PDEVICE_OBJECT DeviceObject,
530 UNREFERENCED_PARAMETER (DeviceObject);
531 UNREFERENCED_PARAMETER (Irp);
532 KeSetEvent ((PKEVENT) Context, IO_NO_INCREMENT, FALSE);
533 return STATUS_MORE_PROCESSING_REQUIRED; // Keep this IRP
536 /*------------------------------------------------------------------------------------------------------*/
539 * Function: SendAwaitIrp
542 * Create and send IRP stack down the stack and wait for the response (Blocking Mode)
545 * pi_pDeviceExt.......... ointer to USB device extension
546 * pi_MajorCode........... IRP major code
547 * pi_MinorCode........... IRP minor code
548 * pi_pBuffer............. parameter buffer
549 * pi_nSize............... size of the buffer
550 * po_pInfo.............. returned field Information from IoStatus block
553 * pointer to the entry on SUCCESS
560 IN PDEVICE_OBJECT pi_pFdo,
561 IN PDEVICE_OBJECT pi_pLdo,
562 IN ULONG pi_MajorCode,
563 IN ULONG pi_MinorCode,
572 Create and send IRP stack down the stack and wait for the response (
577 pi_pFdo................ our device
578 pi_pLdo................ lower device
579 pi_MajorCode........... IRP major code
580 pi_MinorCode........... IRP minor code
581 pi_pBuffer............. parameter buffer
582 pi_nSize............... size of the buffer
586 standard NTSTATUS return codes.
597 PIO_STACK_LOCATION l_pStackLocation;
601 BOOLEAN InvokeAlways = TRUE;
604 if(KeGetCurrentIrql() != PASSIVE_LEVEL)
605 return STATUS_SUCCESS;
608 KeInitializeEvent(&l_hEvent, NotificationEvent, FALSE);
610 // build IRP request to USBD driver
611 l_pIrp = IoAllocateIrp( pi_pFdo->StackSize, FALSE );
616 //MdKdPrint( DBGLVL_MAXIMUM, ("(SendAwaitIrp) Unable to allocate IRP !\n"));
617 return STATUS_INSUFFICIENT_RESOURCES;
621 l_pIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
623 // set completion routine
624 IoSetCompletionRoutine(l_pIrp,SendAwaitIrpCompletion, &l_hEvent, InvokeAlways, InvokeAlways, InvokeAlways);
626 // fill stack location
627 l_pStackLocation = IoGetNextIrpStackLocation(l_pIrp);
628 l_pStackLocation->MajorFunction= (UCHAR)pi_MajorCode;
629 l_pStackLocation->MinorFunction= (UCHAR)pi_MinorCode;
630 RtlCopyMemory( &l_pStackLocation->Parameters, pi_pBuffer, pi_nSize );
632 // Call lower driver perform request
633 l_Status = IoCallDriver( pi_pLdo, l_pIrp );
635 // if the request not performed --> wait
636 if (l_Status == STATUS_PENDING)
638 // Wait until the IRP will be complete
639 KeWaitForSingleObject(
640 &l_hEvent, // event to wait for
641 Executive, // thread type (to wait into its context)
642 KernelMode, // mode of work
646 l_Status = l_pIrp->IoStatus.Status;
650 *po_pInfo = (PVOID)l_pIrp->IoStatus.Information;
658 /*------------------------------------------------------------------------------------------------------*/
661 * Function: FindBridgeIf_new
664 * IN pi_pPdo - PDO of HCA's bus device
665 * IN pi_Bus, pi_DevFunc - bridge location
666 * OUT po_pPdo - pointer to PDO of the bridge, when found
669 * FALSE - the bridge was not found
670 * TRUE - a device was found; *po_pPdo contains its PDO
673 * The function finds and opens the bus interface for Tavor HCA
676 * 1. find all PDOs of PCI.SYS driver and save it into an array;
677 * 2. For each PDO open its bus i/f and check whether it is our bridge;
680 * 1. It is a "hack" algorithm. It uses some fields of system structures and some
681 * optimistic assumptions - see more below
682 * 2. We dangerously assume, that during part to of the algoritm no PDO will removed or added !
686 IN hca_dev_ext_t *pi_ext,
687 OUT PBUS_INTERFACE_STANDARD pi_pInterface
691 int rc = FALSE; /* result - "not found" by default */
692 int n_pdos = 0; /* number of PCI.SYS's PDOs */
693 PDEVICE_OBJECT *pdo; /* an array of PCI.SYS's PDOs */
694 PDEVICE_OBJECT l_pHcaPdo;
696 { // get HCA's bus PDO
697 IO_STACK_LOCATION l_Iosl;
698 PDEVICE_RELATIONS l_pDr;
700 // find PDO of our bus driver (bypassing possible low filter drivers)
701 RtlZeroMemory( &l_Iosl, sizeof(l_Iosl) );
702 l_Iosl.Parameters.QueryDeviceRelations.Type = TargetDeviceRelation;
703 l_Status = SendAwaitIrp(
704 pi_ext->cl_ext.p_self_do,
705 pi_ext->cl_ext.p_next_do,
707 IRP_MN_QUERY_DEVICE_RELATIONS,
709 sizeof(l_Iosl.Parameters.QueryDeviceRelations),
713 if (!NT_SUCCESS (l_Status)) {
714 HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,("IRP_MN_QUERY_DEVICE_RELATIONS for TargetDeviceRelation failed (%#x);: Fdo %p, Ldo %p \n",
715 l_Status, pi_ext->cl_ext.p_self_do, pi_ext->cl_ext.p_next_do ));
719 //TBD: change TRACE_LEVEL_ERROR to TRACE_LEVEL_INFORMATION
720 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",
721 pi_ext->cl_ext.p_self_do, pi_ext->cl_ext.p_next_do, l_pDr->Count, l_pDr->Objects[0] ));
722 l_pHcaPdo = l_pDr->Objects[0];
725 { // allocate and fill an array with all PCI.SYS PDO devices
726 // suppose that there is no more than N_PCI_DEVICES, belonging to PCI.SYS
727 #define N_PCI_DEVICES 256
729 PDRIVER_OBJECT l_pDrv;
730 PDEVICE_OBJECT l_pPdo;
733 pdo = (PDEVICE_OBJECT *)ExAllocatePoolWithTag(
735 N_PCI_DEVICES * sizeof(PDEVICE_OBJECT),
740 // suppose, that PDOs are added only at PASSIVE_LEVEL
741 irql = KeRaiseIrqlToDpcLevel();
743 // get to the PCI.SYS driver
744 l_pDrv = l_pHcaPdo->DriverObject;
746 // find and store all bus PDO s (because the bridge is a bus enumerated device)
747 for ( l_pPdo = l_pDrv->DeviceObject; l_pPdo; l_pPdo = l_pPdo->NextDevice ) {
749 if ( l_pPdo->Flags & DO_BUS_ENUMERATED_DEVICE ) {
750 pdo[n_pdos] = l_pPdo;
751 if (++n_pdos >= N_PCI_DEVICES) {
752 HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,
753 ("There are more than %d children of PCI.SYS. Skipping the rest \n", N_PCI_DEVICES ));
759 // return to previous level
761 //TBD: change TRACE_LEVEL_ERROR to TRACE_LEVEL_INFORMATION
762 HCA_PRINT(TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,("Found %d PCI.SYS's PDOs (from %d) \n", n_pdos, l_all_pdos ));
765 { // Find PDO of the Bridge of our HCA and return open bus interface to it
767 ULONG data, l_SecBus;
768 IO_STACK_LOCATION l_Stack; // parameter buffer for the request
769 ULONG l_DevId = ((int)(23110) << 16) | PCI_VENDOR_ID_MELLANOX;
771 // loop over all the PCI driver devices
772 for ( i = 0; i < n_pdos; ++i ) {
774 // clean interface data
775 RtlZeroMemory( (PCHAR)pi_pInterface, sizeof(BUS_INTERFACE_STANDARD) );
777 // get Bus Interface for the current PDO
778 l_Stack.Parameters.QueryInterface.InterfaceType = (LPGUID) &GUID_BUS_INTERFACE_STANDARD;
779 l_Stack.Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
780 l_Stack.Parameters.QueryInterface.Version = 1;
781 l_Stack.Parameters.QueryInterface.Interface = (PINTERFACE)pi_pInterface;
782 l_Stack.Parameters.QueryInterface.InterfaceSpecificData = NULL;
784 l_Status =SendAwaitIrp( pi_ext->cl_ext.p_self_do, pdo[i], IRP_MJ_PNP,
785 IRP_MN_QUERY_INTERFACE, &l_Stack.Parameters, sizeof(l_Stack.Parameters), NULL);
786 if (!NT_SUCCESS (l_Status)) {
787 //TBD: change TRACE_LEVEL_ERROR to TRACE_LEVEL_WARNING
788 HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,
789 ("Failed to get bus interface for pdo[%d] %p, error %#x \n", i, pdo[i], l_Status ));
795 if (4 != pi_pInterface->GetBusData( pi_pInterface->Context,
796 PCI_WHICHSPACE_CONFIG, &data, 0, 4)) {
797 //TBD: change TRACE_LEVEL_ERROR to TRACE_LEVEL_WARNING
798 HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP,
799 ("Failed to read DevID for pdo[%d] %p, data %#x \n", i, pdo[i], data ));
803 if (data != l_DevId) {
804 //TBD: change TRACE_LEVEL_ERROR to TRACE_LEVEL_INFORMATION
805 HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP,
806 ("Not Tavor bridge: pdo[%d] %p, data %#x \n", i, pdo[i], data ));
810 // Found Tavor Bridge - read its SecondaryBus
812 if (4 != pi_pInterface->GetBusData( pi_pInterface->Context,
813 PCI_WHICHSPACE_CONFIG, &data, 24, 4)) { /* 24 - PrimaryBus, 25 - SecondaryBus, 26 - SubordinateBus */
814 //TBD: change TRACE_LEVEL_ERROR to TRACE_LEVEL_WARNING
815 HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP,
816 ("Failed to read SecondaryBus for pdo[%d] %p, data %#x \n", i, pdo[i], data ));
820 l_SecBus = (data >> 16) & 255;
821 if (l_SecBus != pi_ext->bus_number) {
822 //TBD: change TRACE_LEVEL_ERROR to TRACE_LEVEL_INFORMATION
823 HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP,
824 ("Wrong bridge for our HCA: pdo[%d] %p, SecBus %d, HcaBus %d \n", i, pdo[i], l_SecBus, pi_ext->bus_number ));
828 ULONG l_DevFunc, l_Bus;
829 l_Status = MdGetDevLocation( pdo[i], &l_Bus, &l_DevFunc );
830 //TBD: change TRACE_LEVEL_ERROR to TRACE_LEVEL_WARNING
831 HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP,
832 ("Found bridge for our HCA: pdo[%d] %p (bus %d, dev/func %d, HcaPdo %p), SecBus %d, HcaBus %d \n",
833 i, pdo[i], l_Bus, l_DevFunc, l_pHcaPdo, l_SecBus, pi_ext->bus_number ));
838 pi_pInterface->InterfaceDereference( pi_pInterface->Context );
847 /*----------------------------------------------------------------*/
851 IN hca_dev_ext_t *pi_ext,
852 IN PBUS_INTERFACE_STANDARD pi_pInterface
859 rc = FindBridgeIf_old(pi_ext,pi_pInterface);
861 HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, ("Old way works !\n"));
864 HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, ("Old way fails !\n"));
869 rc = FindBridgeIf_new(pi_ext,pi_pInterface);
871 HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, ("New way works !\n"));
874 HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, ("New way fails !\n"));