[HCA] Distinguish between Tavor and Arbel HCAs, report correct device ID
[mirror/winof/.git] / hw / mt23108 / vapi / mlxsys / os_dep / win / tdriver / MdConf.c
1 /*\r
2  * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
3  * Copyright (c) 2004-2005 Mellanox Technologies Ltd.  All rights reserved.\r
4  *\r
5  * This software is available to you under the OpenIB.org BSD license\r
6  * below:\r
7  *\r
8  *     Redistribution and use in source and binary forms, with or\r
9  *     without modification, are permitted provided that the following\r
10  *     conditions are met:\r
11  *\r
12  *      - Redistributions of source code must retain the above\r
13  *        copyright notice, this list of conditions and the following\r
14  *        disclaimer.\r
15  *\r
16  *      - Redistributions in binary form must reproduce the above\r
17  *        copyright notice, this list of conditions and the following\r
18  *        disclaimer in the documentation and/or other materials\r
19  *        provided with the distribution.\r
20  *\r
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
22  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
24  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
25  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
26  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
27  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
28  * SOFTWARE.\r
29  *\r
30  * $Id$\r
31  */\r
32 \r
33 #include "MdGen.h"\r
34 #include "MdConfPriv.h"\r
35 #include "MdIoctlSpec.h"\r
36 #include <initguid.h>\r
37 #include <wdmguid.h>  \r
38 \r
39 // select implementation of PciHdrWrite\r
40 //#define USE_HalSetBusData                     1\r
41 //#define USE_HalSetBusDataByOffset     1\r
42 #define USE_ReadWritePciConfig          1\r
43 \r
44 \r
45 #define NOT_USE_MDNTDDK         1\r
46 //#ifdef NOT_USE_MDNTDDK \r
47 ///* from ntddk.h */\r
48 ////\r
49 //// Define types of bus information.\r
50 ////\r
51 //\r
52 //typedef enum _BUS_DATA_TYPE {\r
53 //    ConfigurationSpaceUndefined = -1,\r
54 //    Cmos,\r
55 //    EisaConfiguration,\r
56 //    Pos,\r
57 //    CbusConfiguration,\r
58 //    PCIConfiguration,\r
59 //    VMEConfiguration,\r
60 //    NuBusConfiguration,\r
61 //    PCMCIAConfiguration,\r
62 //    MPIConfiguration,\r
63 //    MPSAConfiguration,\r
64 //    PNPISAConfiguration,\r
65 //    SgiInternalConfiguration,\r
66 //    MaximumBusDataType\r
67 //} BUS_DATA_TYPE, *PBUS_DATA_TYPE;\r
68 //#ifdef __i386__\r
69 //NTHALAPI\r
70 //ULONG \r
71 //HalGetBusData(\r
72 //    IN BUS_DATA_TYPE BusDataType,\r
73 //    IN ULONG BusNumber,\r
74 //    IN ULONG SlotNumber,\r
75 //    IN PVOID Buffer,\r
76 //    IN ULONG Length\r
77 //    );\r
78 //\r
79 //NTHALAPI\r
80 //ULONG\r
81 //HalGetBusDataByOffset(\r
82 //    IN BUS_DATA_TYPE BusDataType,\r
83 //    IN ULONG BusNumber,\r
84 //    IN ULONG SlotNumber,\r
85 //    IN PVOID Buffer,\r
86 //    IN ULONG Offset,\r
87 //    IN ULONG Length\r
88 //    );\r
89 //    \r
90 //NTHALAPI\r
91 //ULONG\r
92 //HalSetBusData(\r
93 //    IN BUS_DATA_TYPE BusDataType,\r
94 //    IN ULONG BusNumber,\r
95 //    IN ULONG SlotNumber,\r
96 //    IN PVOID Buffer,\r
97 //    IN ULONG Length\r
98 //    );\r
99 //\r
100 //NTHALAPI\r
101 //ULONG\r
102 //HalSetBusDataByOffset(\r
103 //    IN BUS_DATA_TYPE BusDataType,\r
104 //    IN ULONG BusNumber,\r
105 //    IN ULONG SlotNumber,\r
106 //    IN PVOID Buffer,\r
107 //    IN ULONG Offset,\r
108 //    IN ULONG Length\r
109 //    );\r
110 //#endif\r
111 //#endif\r
112 \r
113 #ifndef USE_MOSAL\r
114 /******************************************************************************\r
115  *  Function:\r
116  *              SendAwaitIrpCompletion\r
117  *\r
118  *  Description:\r
119  *              IRP completion routine \r
120  *\r
121  *  Parameters:\r
122  *\r
123  *  Returns:\r
124  *              pointer to the entry on SUCCESS\r
125  *              NULL - otherwise\r
126  *\r
127  ******************************************************************************/\r
128 NTSTATUS\r
129 SendAwaitIrpCompletion (\r
130     IN PDEVICE_OBJECT   DeviceObject,\r
131     IN PIRP             Irp,\r
132     IN PVOID            Context\r
133     )\r
134 {\r
135     UNREFERENCED_PARAMETER (DeviceObject);    \r
136     KeSetEvent ((PKEVENT) Context, IO_NO_INCREMENT, FALSE);\r
137     return STATUS_MORE_PROCESSING_REQUIRED; // Keep this IRP\r
138 }\r
139 \r
140 /******************************************************************************\r
141  *  Function:\r
142  *              SendAwaitIrp\r
143  *\r
144  *  Description:\r
145  *              Create and send IRP stack down the stack and wait for the response (Blocking Mode)\r
146  *\r
147  *  Parameters:\r
148  *              pi_pDeviceExt.......... ointer to USB device extension\r
149  *              pi_MajorCode........... IRP major code\r
150  *              pi_MinorCode........... IRP minor code\r
151  *              pi_pBuffer............. parameter buffer\r
152  *              pi_nSize............... size of the buffer\r
153  *\r
154  *  Returns:\r
155  *              pointer to the entry on SUCCESS\r
156  *              NULL - otherwise\r
157  *\r
158  ******************************************************************************/\r
159 NTSTATUS \r
160 SendAwaitIrp(\r
161         IN  PDEVICE_OBJECT              pi_pFdo,\r
162         IN  PDEVICE_OBJECT              pi_pLdo,\r
163         IN  ULONG                               pi_MajorCode,\r
164         IN  ULONG                               pi_MinorCode,\r
165         IN      PVOID                           pi_pBuffer,\r
166         IN      int                                     pi_nSize\r
167    )\r
168 /*++\r
169 \r
170  Routine Description: \r
171 \r
172         Create and send IRP stack down the stack and wait for the response (\r
173 Blocking Mode)\r
174 \r
175  Arguments: \r
176  \r
177         pi_pFdo................ our device\r
178         pi_pLdo................ lower device\r
179         pi_MajorCode........... IRP major code\r
180         pi_MinorCode........... IRP minor code\r
181         pi_pBuffer............. parameter buffer\r
182         pi_nSize............... size of the buffer\r
183 \r
184  Returns: \r
185  \r
186         standard NTSTATUS return codes.\r
187 \r
188  Notes:\r
189 \r
190 --*/\r
191 { /* SendAwaitIrp */\r
192         // Event\r
193         KEVENT                          l_hEvent;\r
194         // Pointer to IRP\r
195         PIRP                            l_pIrp;\r
196         // Stack location\r
197         PIO_STACK_LOCATION      l_pStackLocation;\r
198         // Returned status\r
199         NTSTATUS                        l_Status;\r
200 \r
201         // call validation\r
202         if(KeGetCurrentIrql() != PASSIVE_LEVEL)\r
203                 return STATUS_SUCCESS;\r
204 \r
205         // create event\r
206         KeInitializeEvent(&l_hEvent, NotificationEvent, FALSE);\r
207 \r
208         // build IRP request to USBD driver\r
209         l_pIrp = IoAllocateIrp( pi_pFdo->StackSize, FALSE );\r
210 \r
211         // validate request\r
212         if (!l_pIrp)\r
213         {\r
214             //MdKdPrint( DBGLVL_MAXIMUM, ("(SendAwaitIrp) Unable to allocate IRP !\n"));\r
215                 return STATUS_INSUFFICIENT_RESOURCES;\r
216         }\r
217 \r
218         // fill IRP\r
219         l_pIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;\r
220 \r
221         // set completion routine\r
222     IoSetCompletionRoutine(l_pIrp,SendAwaitIrpCompletion, &l_hEvent, TRUE, TRUE, TRUE);\r
223 \r
224         // fill stack location\r
225     l_pStackLocation = IoGetNextIrpStackLocation(l_pIrp);\r
226     l_pStackLocation->MajorFunction= (UCHAR)pi_MajorCode;\r
227     l_pStackLocation->MinorFunction= (UCHAR)pi_MinorCode;\r
228         RtlCopyMemory( &l_pStackLocation->Parameters, pi_pBuffer, pi_nSize );\r
229 \r
230         // Call lower driver perform request\r
231         l_Status = IoCallDriver( pi_pLdo, l_pIrp ); \r
232 \r
233         // if the request not performed --> wait\r
234         if (l_Status == STATUS_PENDING)\r
235         {\r
236                 // Wait until the IRP  will be complete\r
237                 KeWaitForSingleObject(\r
238                         &l_hEvent,                                                              // event to wait for\r
239                         Executive,                                                              // thread type (to wait into its context)\r
240                         KernelMode,                                                     // mode of work\r
241                         FALSE,                                                                  // alertable\r
242                         NULL                                                                    // timeout\r
243                 );\r
244                 l_Status = l_pIrp->IoStatus.Status;\r
245         }\r
246 \r
247     IoFreeIrp(l_pIrp);\r
248 \r
249         return l_Status;\r
250 \r
251 } /* SendAwaitIrp */\r
252 \r
253 \r
254 #endif\r
255 \r
256 /******************************************************************************\r
257  *  Function:\r
258  *              DrvReadWritePciConfig\r
259  *\r
260  *  Description:\r
261  *              Create and send IRP stack down the stack and wait for the response (Blocking Mode)\r
262  *\r
263  *  Parameters:\r
264  *\r
265  *  Returns:\r
266  *              pointer to the entry on SUCCESS\r
267  *              NULL - otherwise\r
268  *\r
269  ******************************************************************************/\r
270 NTSTATUS\r
271 DrvReadWritePciConfig(\r
272         IN      PMD_DEV_CONTEXT_T       pi_pMdDevContext,\r
273         IN      PVOID                           pi_pDataBuffer,\r
274     IN  ULONG                           pi_nPciSpaceOffset,\r
275     IN  ULONG                           pi_nDataLength,\r
276     IN  BOOLEAN                         pi_fReadConfig\r
277         )\r
278 \r
279 { /* DrvReadWritePciConfig */ \r
280 \r
281         // parameter buffer for the request\r
282         DrvReadWriteConfig_t    l_RwParams;\r
283         ULONG                           l_nBytes;\r
284 \r
285         // parameter validation\r
286     //MDASSERT(pi_pDataBuffer);\r
287     //MDASSERT(pi_nDataLength);\r
288 \r
289         // try to do it directly\r
290         if (pi_fReadConfig && pi_pMdDevContext->m_Interface.GetBusData) {\r
291                 l_nBytes = pi_pMdDevContext->m_Interface.GetBusData(\r
292                         pi_pMdDevContext->m_Interface.Context,\r
293             PCI_WHICHSPACE_CONFIG,\r
294             pi_pDataBuffer,\r
295             pi_nPciSpaceOffset,\r
296             pi_nDataLength\r
297             ); \r
298         return (l_nBytes != pi_nDataLength) ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS;\r
299     }\r
300     else\r
301     if (!pi_fReadConfig && pi_pMdDevContext->m_Interface.SetBusData) {\r
302                 pi_pMdDevContext->m_Interface.SetBusData(\r
303                         pi_pMdDevContext->m_Interface.Context,\r
304             PCI_WHICHSPACE_CONFIG,\r
305             pi_pDataBuffer,\r
306             pi_nPciSpaceOffset,\r
307             pi_nDataLength\r
308             ); \r
309         return STATUS_SUCCESS;\r
310     }\r
311         else { \r
312                 // fill request parameters\r
313                 l_RwParams.Buffer               = pi_pDataBuffer;\r
314                 l_RwParams.Length               = pi_nDataLength;\r
315                 l_RwParams.Offset               = pi_nPciSpaceOffset;\r
316                 l_RwParams.WhichSpace   = PCI_WHICHSPACE_CONFIG;\r
317                 \r
318                 return SendAwaitIrp( pi_pMdDevContext->m_pFdo, pi_pMdDevContext->m_pLdo, IRP_MJ_PNP, \r
319                         pi_fReadConfig ? IRP_MN_READ_CONFIG : IRP_MN_WRITE_CONFIG, &l_RwParams, sizeof(DrvReadWriteConfig_t));\r
320         }\r
321 \r
322 } /* DrvReadWritePciConfig */ \r
323 /*------------------------------------------------------------------------------------------------------*/\r
324 \r
325 NTSTATUS\r
326 PciIfOpen(\r
327         IN      PDEVICE_OBJECT  pi_pFdo,\r
328         IN      PDEVICE_OBJECT  pi_pLdo,\r
329         IN      PBUS_INTERFACE_STANDARD pi_pInterface\r
330         )\r
331 \r
332 { /* GetDirectPciInterface */ \r
333 \r
334         // parameter buffer for the request\r
335         IO_STACK_LOCATION       l_Stack;\r
336 \r
337         // clean interface data\r
338         RtlZeroMemory( (PCHAR)pi_pInterface, sizeof(BUS_INTERFACE_STANDARD) );\r
339 \r
340         // fill request parameters\r
341         l_Stack.Parameters.QueryInterface.InterfaceType                 = (LPGUID) &GUID_BUS_INTERFACE_STANDARD;\r
342         l_Stack.Parameters.QueryInterface.Size                                  = sizeof(BUS_INTERFACE_STANDARD);\r
343         l_Stack.Parameters.QueryInterface.Version                                       = 1;\r
344         l_Stack.Parameters.QueryInterface.Interface                             = (PINTERFACE)pi_pInterface;\r
345         l_Stack.Parameters.QueryInterface.InterfaceSpecificData = NULL;\r
346  \r
347         return SendAwaitIrp( pi_pFdo, pi_pLdo, IRP_MJ_PNP, \r
348                 IRP_MN_QUERY_INTERFACE, &l_Stack.Parameters, sizeof(l_Stack.Parameters));\r
349 \r
350 } /* GetDirectPciInterface */ \r
351 \r
352 PciIfClose(\r
353         IN      PBUS_INTERFACE_STANDARD pi_pInterface\r
354         )\r
355 {\r
356         if (pi_pInterface->InterfaceDereference)\r
357                 pi_pInterface->InterfaceDereference((PVOID)pi_pInterface->Context);\r
358 }\r
359 \r
360 #ifdef NOT_USE_MDNTDDK \r
361 \r
362 /*------------------------------------------------------------------------------------------------------*/\r
363 \r
364 /* from wdm.h\r
365 typedef struct _PCI_SLOT_NUMBER {\r
366     union {\r
367         struct {\r
368             ULONG   DeviceNumber:5;\r
369             ULONG   FunctionNumber:3;\r
370             ULONG   Reserved:24;\r
371         } bits;\r
372         ULONG   AsULONG;\r
373     } u;\r
374 } PCI_SLOT_NUMBER, *PPCI_SLOT_NUMBER;\r
375 */\r
376 \r
377 #ifdef __i386__\r
378 BOOLEAN PciFindDeviceByBusAndId( \r
379         IN      ULONG           pi_MyBus, \r
380         IN      ULONG           pi_DevId, \r
381         IN OUT PULONG   po_pSlot )\r
382 {\r
383 #define N_SLOTS         32\r
384         ULONG   l_Slot;\r
385         ULONG   l_DevId;\r
386         ULONG   l_Bytes;\r
387 \r
388         for (l_Slot = *po_pSlot; l_Slot < N_SLOTS; l_Slot++ ) {\r
389 #pragma warning( push )\r
390 #pragma warning( disable:4996 )\r
391         l_Bytes = HalGetBusDataByOffset(\r
392                 PCIConfiguration,\r
393                 pi_MyBus,\r
394                 l_Slot,\r
395                 (PVOID)&l_DevId,\r
396                 0,\r
397                 sizeof(ULONG)\r
398                 );\r
399 #pragma warning( pop )\r
400         if (l_Bytes != sizeof(ULONG)) \r
401                         continue;       /* as if - "not found" */\r
402                 if (l_DevId == pi_DevId)\r
403                         break;\r
404         }\r
405         \r
406         if (l_DevId == pi_DevId) {\r
407                 *po_pSlot = l_Slot;\r
408                 return TRUE;\r
409         }\r
410         else\r
411                 return FALSE;\r
412 }\r
413 \r
414 BOOLEAN PciFindDeviceById( \r
415         IN      ULONG           pi_DevId, \r
416         IN OUT PULONG           po_pBus, \r
417         IN OUT PULONG           po_pSlot )\r
418 {\r
419 #define N_BUSES         16\r
420         ULONG l_Bus;\r
421         ULONG   l_Slot = *po_pSlot;\r
422         \r
423         for (l_Bus= *po_pBus; l_Bus < N_BUSES; l_Bus++, l_Slot=0) {\r
424                 if (PciFindDeviceByBusAndId(l_Bus, pi_DevId, &l_Slot))\r
425                         break;\r
426         }\r
427         if (l_Bus >= N_BUSES)\r
428                 return FALSE;\r
429         *po_pBus = l_Bus;\r
430         *po_pSlot = l_Slot;\r
431         return TRUE;\r
432 }\r
433 \r
434 BOOLEAN PciFindBridgeByBus( \r
435         IN ULONG                pi_SecBus, \r
436         OUT PULONG              po_pBus, \r
437         OUT PULONG              po_pSlot )\r
438 {\r
439 #define N_CARDS         8\r
440         ULONG l_CardNo;\r
441         ULONG   l_Slot=0, l_Bus=0;\r
442         ULONG l_DevId = ((int)(23110) << 16) | MLX_VENDOR_ID;   \r
443         ULONG l_SecBus, l_tmp, l_Bytes;\r
444         \r
445         for (l_CardNo= 0; l_CardNo < N_CARDS; l_CardNo++, l_Slot=0, l_Bus++) {\r
446                 if (PciFindDeviceById(l_DevId, &l_Bus, &l_Slot)) {\r
447                         /* found a bridge */\r
448 #pragma warning( push )\r
449 #pragma warning( disable:4996 )\r
450                        l_Bytes = HalGetBusDataByOffset(\r
451                                 PCIConfiguration,\r
452                         l_Bus,\r
453                                 l_Slot,\r
454                                 (PVOID)&l_tmp,\r
455                                 24,     /* 24 - PrimaryBus, 25 - SecondaryBus, 26 - SubordinateBus */\r
456                         sizeof(ULONG)\r
457                                 );\r
458 #pragma warning( pop )\r
459                        if (l_Bytes != sizeof(ULONG)) \r
460                                 continue;       /* as if - "not found" */\r
461                         l_SecBus = (l_tmp >> 16) & 255;\r
462                         if ( l_SecBus == pi_SecBus )\r
463                                 break; /* found !!! */\r
464                 }\r
465         }\r
466         if (l_CardNo >= N_CARDS)\r
467                 return FALSE;\r
468         *po_pBus = l_Bus;\r
469         *po_pSlot = l_Slot;\r
470         return TRUE;\r
471 }\r
472 #endif\r
473 \r
474 BOOLEAN PciFindPdoByPdoAndLocation( \r
475         IN PDEVICE_OBJECT pi_pPdo,\r
476         IN ULONG                pi_Bus, \r
477         IN ULONG                pi_Slot,\r
478         IN ULONG                pi_Function,\r
479         OUT PDEVICE_OBJECT * po_pPdo )\r
480 {\r
481         PDRIVER_OBJECT l_pDrv;\r
482         PDEVICE_OBJECT l_pPdo;\r
483         NTSTATUS l_Status;\r
484         ULONG   l_Slot, l_Bus, l_Function;\r
485         \r
486         // get to the PCI driver\r
487         l_pDrv = pi_pPdo->DriverObject;\r
488         \r
489         //  loop over all the PCI driver devices\r
490         for ( l_pPdo = l_pDrv->DeviceObject; l_pPdo; l_pPdo = l_pPdo->NextDevice ) {\r
491                 // if it's not PDO - skip it\r
492                 if (!(l_pPdo->Flags & DO_BUS_ENUMERATED_DEVICE))\r
493                         continue;\r
494                 // get the location of the device of that PDO\r
495                 l_Status = MdGetDevLocation( l_pPdo, &l_Bus, &l_Slot, &l_Function );\r
496                 if (l_Status != STATUS_SUCCESS)\r
497                         continue;\r
498                 // check, whether it's our device\r
499                 if (l_Bus == pi_Bus && l_Slot == pi_Slot && l_Function == pi_Function)\r
500                         break;\r
501         }\r
502 \r
503         // check whether we found the PDO\r
504         if (!l_pPdo)\r
505                 return FALSE;\r
506         *po_pPdo = l_pPdo;\r
507         return TRUE;    \r
508 }\r
509 \r
510 /*------------------------------------------------------------------------------------------------------*/\r
511 #ifdef __i386__\r
512 \r
513 NTSTATUS\r
514 PciHdrRead(\r
515         IN      PVOID                           pi_pBuffer,\r
516         IN      ULONG                           pi_Bus,\r
517         IN      ULONG                           pi_Slot\r
518         )\r
519 {\r
520         int                     l_Bytes;\r
521         \r
522 #pragma warning( push )\r
523 #pragma warning( disable:4996 )\r
524         l_Bytes = HalGetBusData(\r
525                 PCIConfiguration,\r
526                 pi_Bus,\r
527                 pi_Slot,\r
528                 pi_pBuffer,\r
529                 PCI_HDR_SIZE<<2\r
530         );\r
531 #pragma warning( pop )\r
532         if (l_Bytes != PCI_HDR_SIZE<<2) {\r
533                         return STATUS_UNSUCCESSFUL;\r
534                 }\r
535 \r
536         return STATUS_SUCCESS;\r
537 }\r
538 #endif\r
539 /*------------------------------------------------------------------------------------------------------*/\r
540 NTSTATUS\r
541 PciFixCmdReg(\r
542         IN      PMD_DEV_CONTEXT_T       pi_pMdDevContext\r
543         )\r
544 {\r
545         PDEVICE_OBJECT                  l_pLdo = pi_pMdDevContext->m_pLdo;      /* Shrimp's PDO */\r
546         BUS_INTERFACE_STANDARD  l_Interface, *l_pInterface = &l_Interface;\r
547         ULONG                                   l_Value, l_NewValue;\r
548         NTSTATUS                                l_Status = STATUS_SUCCESS;\r
549         PDEVICE_OBJECT                  l_pFdo;\r
550 \r
551         if (pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR_SD) \r
552         { /* fix HCA command register from SHRIMP */\r
553         \r
554                 /* get the PDO of Bridge */\r
555                 if (!PciFindPdoByPdoAndLocation( l_pLdo, \r
556                         pi_pMdDevContext->m_BridgeHdr.m_Bus,\r
557                         pi_pMdDevContext->m_BridgeHdr.m_Slot,\r
558                         0, &l_pLdo )) {\r
559                         MdKdPrint( DBGLVL_LOW,("(PciHdrWrite) Not found bridge PDO - can't restore the PCI header \n"  ));\r
560                         return STATUS_UNSUCCESSFUL;\r
561                 }\r
562                 l_pFdo = l_pLdo->AttachedDevice;\r
563 \r
564                 // open interface to PCI driver\r
565                 l_Status = PciIfOpen( l_pFdo, l_pLdo, l_pInterface );\r
566                 if (!NT_SUCCESS(l_Status))  {\r
567                     MdKdPrint( DBGLVL_LOW,("(PciFixCmdReg) PciIfOpen failed (0x%x) \n", l_Status  ));\r
568                         return l_Status;\r
569                 }\r
570         \r
571                 // read reg\r
572             if (l_pInterface->GetBusData) \r
573                         l_pInterface->GetBusData( l_pInterface->Context, PCI_WHICHSPACE_CONFIG,\r
574                     (PVOID)&l_Value, 4, sizeof(ULONG) ); \r
575 \r
576                 // fix\r
577                 l_NewValue = l_Value | 7;\r
578         \r
579                 // write reg\r
580             if (l_pInterface->SetBusData) \r
581                         l_pInterface->SetBusData( l_pInterface->Context, PCI_WHICHSPACE_CONFIG,\r
582                     (PVOID)&l_NewValue, 4, sizeof(ULONG) ); \r
583 \r
584                 // close interface\r
585                 PciIfClose( l_pInterface );\r
586 \r
587         } /* fix HCA command register from SHRIMP */\r
588 \r
589         if (pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR \r
590                 || pi_pMdDevContext->m_eDevType ==MD_DEV_IX_ARBEL_TM) \r
591         { /* fix command register for TAVOR */\r
592 \r
593                 l_pInterface = &pi_pMdDevContext->m_Interface;\r
594                 // read reg\r
595             if (l_pInterface->GetBusData) \r
596                         l_pInterface->GetBusData( l_pInterface->Context, PCI_WHICHSPACE_CONFIG,\r
597                     (PVOID)&l_Value, 4, sizeof(ULONG) ); \r
598 \r
599                 // fix\r
600                 l_NewValue = l_Value | 7;\r
601         \r
602                 // write reg\r
603             if (l_pInterface->SetBusData) \r
604                         l_pInterface->SetBusData( l_pInterface->Context, PCI_WHICHSPACE_CONFIG,\r
605                     (PVOID)&l_NewValue, 4, sizeof(ULONG) ); \r
606                     \r
607         } /*  fix command register for TAVOR */\r
608     \r
609     MdKdPrint( DBGLVL_LOW,("(PciFixCmdReg) Cmd register: Old 0x%x New 0x%x \n", \r
610                 l_Value, l_NewValue  ));\r
611 \r
612         return STATUS_SUCCESS;\r
613 }\r
614 \r
615 /*------------------------------------------------------------------------------------------------------*/\r
616 \r
617 #ifdef __i386__\r
618 typedef enum { WRITE_WITH_SET_BUS, WRITE_WITH_SET_BUS_BY_OFFSET, WRITE_WITH_PCI_CONFIG } PCI_WRITE_T;\r
619 \r
620 NTSTATUS\r
621 PciHdrWrite(\r
622         IN      PMD_DEV_CONTEXT_T       pi_pMdDevContext,\r
623         IN      PCHAR                           pi_pBuffer,\r
624         IN      ULONG                           pi_Bus,\r
625         IN      ULONG                           pi_Slot,\r
626         IN  PCI_WRITE_T                 pi_Technique\r
627         )\r
628 {\r
629         if (pi_Technique == WRITE_WITH_PCI_CONFIG) {\r
630                 NTSTATUS                                l_Status = STATUS_SUCCESS;\r
631                 PDEVICE_OBJECT                  l_pLdo = pi_pMdDevContext->m_pLdo;      /* Shrimp's PDO */\r
632                 BUS_INTERFACE_STANDARD  l_Interface;\r
633                 PDEVICE_OBJECT                  l_pFdo;\r
634 \r
635                 /* the following algorithm sutes only for SD */\r
636                 if (pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR_SD) {\r
637 \r
638                         /* protect */\r
639                         KSEM_ACQ(&pi_pMdDevContext->m_Sem);\r
640 \r
641                         /* get the PDO of Bridge */\r
642                         if (!PciFindPdoByPdoAndLocation( l_pLdo, \r
643                                 pi_pMdDevContext->m_BridgeHdr.m_Bus,\r
644                                 pi_pMdDevContext->m_BridgeHdr.m_Slot,\r
645                                 0, &l_pLdo )) {\r
646                                 MdKdPrint( DBGLVL_LOW,("(PciHdrWrite) Not found bridge PDO - can't restore the PCI header \n"  ));\r
647                                 return STATUS_UNSUCCESSFUL;\r
648                         }\r
649                         l_pFdo = l_pLdo->AttachedDevice;\r
650 \r
651                         // open interface to PCI driver\r
652                 l_Status = PciIfOpen( l_pFdo, l_pLdo, &l_Interface );\r
653                         if (!NT_SUCCESS(l_Status))  {\r
654                             MdKdPrint( DBGLVL_LOW,("(PciHdrWrite) PciIfOpen failed (0x%x) \n", l_Status  ));\r
655                                 return l_Status;\r
656                         }\r
657 \r
658                         // write header\r
659                         if (l_Interface.SetBusData) {\r
660                                 l_Interface.SetBusData( l_Interface.Context, PCI_WHICHSPACE_CONFIG,\r
661                                         pi_pBuffer + 0x08, 0x08, PCI_HDR_SIZE - 0x08 );\r
662                         }\r
663                             \r
664                         // write some fields once more\r
665                         if (l_Interface.SetBusData) {\r
666                                 /* Bridge Control Register */    \r
667                                 l_Interface.SetBusData( l_Interface.Context, PCI_WHICHSPACE_CONFIG,\r
668                                         pi_pBuffer + 0x3c, 0x3c, 4 );           \r
669                                 /* The rest of header, including PCIX command register */    \r
670                                 l_Interface.SetBusData( l_Interface.Context, PCI_WHICHSPACE_CONFIG,\r
671                                         pi_pBuffer + PCI_HDR_SIZE, PCI_HDR_SIZE, (PCI_HDR_SIZE<<2) - PCI_HDR_SIZE );\r
672                                 /* Command Register */\r
673                                 l_Interface.SetBusData( l_Interface.Context, PCI_WHICHSPACE_CONFIG,\r
674                                         pi_pBuffer + 0x04, 0x04, 4 );           \r
675                         }           \r
676          \r
677                         // close interface\r
678                         PciIfClose( &l_Interface );\r
679 \r
680                         KSEM_REL(&pi_pMdDevContext->m_Sem);\r
681                         return l_Status;\r
682                 }       \r
683                 else\r
684                 if (pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR || \r
685                         pi_pMdDevContext->m_eDevType == MD_DEV_IX_ARBEL_TM) {\r
686 \r
687                         /* protect */\r
688                         KSEM_ACQ(&pi_pMdDevContext->m_Sem);\r
689 \r
690                         /* get the PDO of Bridge */\r
691                         if (!PciFindPdoByPdoAndLocation( l_pLdo, \r
692                                 pi_pMdDevContext->m_BridgeHdr.m_Bus,\r
693                                 pi_pMdDevContext->m_BridgeHdr.m_Slot,\r
694                                 0, &l_pLdo )) {\r
695                                 MdKdPrint( DBGLVL_LOW,("(PciHdrWrite) Not found bridge PDO - can't restore the PCI header \n"  ));\r
696                                 return STATUS_UNSUCCESSFUL;\r
697                         }\r
698                         l_pFdo = l_pLdo->AttachedDevice;\r
699 \r
700                         // open interface to PCI driver\r
701                 l_Status = PciIfOpen( l_pFdo, l_pLdo, &l_Interface );\r
702                         if (!NT_SUCCESS(l_Status))  {\r
703                             MdKdPrint( DBGLVL_LOW,("(PciHdrWrite) PciIfOpen failed (0x%x) \n", l_Status  ));\r
704                                 return l_Status;\r
705                         }\r
706 \r
707                         // write header\r
708                         if (l_Interface.SetBusData) {\r
709                                 l_Interface.SetBusData( l_Interface.Context, PCI_WHICHSPACE_CONFIG,\r
710                                         pi_pBuffer + 0x08, 0x08, PCI_HDR_SIZE - 0x08 );\r
711                         }\r
712                     \r
713                         // write some fields once more\r
714                         if (l_Interface.SetBusData) {\r
715                                 /* Bridge Control Register */    \r
716                                 l_Interface.SetBusData( l_Interface.Context, PCI_WHICHSPACE_CONFIG,\r
717                                         pi_pBuffer + 0x3c, 0x3c, 4 );           \r
718                                 /* The rest of header, including PCIX command register */    \r
719                                 l_Interface.SetBusData( l_Interface.Context, PCI_WHICHSPACE_CONFIG,\r
720                                         pi_pBuffer + PCI_HDR_SIZE, PCI_HDR_SIZE, (PCI_HDR_SIZE<<2) - PCI_HDR_SIZE );\r
721                                 /* Command Register */\r
722                                 l_Interface.SetBusData( l_Interface.Context, PCI_WHICHSPACE_CONFIG,\r
723                                         pi_pBuffer + 0x04, 0x04, 4 );           \r
724                         }           \r
725  \r
726                         // close interface\r
727                         PciIfClose( &l_Interface );\r
728                         KSEM_REL(&pi_pMdDevContext->m_Sem);\r
729                         return l_Status;\r
730                 }\r
731                 else\r
732                         return STATUS_UNSUCCESSFUL;\r
733 \r
734         }       \r
735         \r
736         else    \r
737         \r
738         if (pi_Technique == WRITE_WITH_SET_BUS) {\r
739                 int l_Bytes;\r
740 \r
741 #pragma warning( push )\r
742 #pragma warning( disable:4996 )\r
743         l_Bytes = HalSetBusData(\r
744                 PCIConfiguration,\r
745                 pi_Bus,\r
746                 pi_Slot,\r
747                 pi_pBuffer,\r
748                 PCI_HDR_SIZE<<2\r
749         );\r
750 #pragma warning( pop )\r
751                 return STATUS_SUCCESS;\r
752         }       \r
753         \r
754         else\r
755         \r
756         if (pi_Technique == WRITE_WITH_SET_BUS_BY_OFFSET) {\r
757                 int l_Bytes;\r
758                 int i;\r
759                 \r
760                 PULONG l_pBuf = (PULONG)pi_pBuffer;\r
761         \r
762                 for (i = 0; i < PCI_HDR_SIZE; i++) {\r
763 #pragma warning( push )\r
764 #pragma warning( disable:4996 )\r
765                 l_Bytes = HalSetBusDataByOffset(\r
766                         PCIConfiguration,\r
767                         pi_Bus,\r
768                         pi_Slot,\r
769                         &l_pBuf[i],\r
770                         i<<2,\r
771                         sizeof(ULONG)\r
772                         );\r
773 #pragma warning( pop )\r
774                 }\r
775                 return STATUS_SUCCESS;\r
776         }\r
777 \r
778         else\r
779                 return STATUS_UNSUCCESSFUL;\r
780 }\r
781 /*------------------------------------------------------------------------------------------------------*/\r
782 \r
783 NTSTATUS\r
784 PciHdrSave(\r
785         IN      PMD_DEV_CONTEXT_T       pi_pMdDevContext\r
786         )\r
787 {\r
788         ULONG           l_MyBus = pi_pMdDevContext->m_BusNumber;\r
789         ULONG           l_Slot, l_SecBus;\r
790         ULONG           l_DevId;\r
791         NTSTATUS        l_Status = STATUS_SUCCESS;\r
792 \r
793          /* prevent RESET if header not saved */\r
794          pi_pMdDevContext->m_fMayReset = FALSE;\r
795 \r
796         /* NB: functionality supported only for MD_DEV_IX_TAVOR_SD and MD_DEV_IX_TAVOR_BD */\r
797         if ((pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR_SD) || \r
798               (pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR_BD)) {\r
799                 \r
800         /* \r
801          * My device\r
802          */\r
803         l_DevId = (pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR_BD)  ?        \r
804                 (((int)(MD_DEV_ID_TAVOR_BD) << 16) | MLX_VENDOR_ID)                     :\r
805                 (((int)(MD_DEV_ID_TAVOR_SD) << 16) | MLX_VENDOR_ID);    \r
806         l_Slot = 0;\r
807         if (PciFindDeviceByBusAndId( l_MyBus, l_DevId, &l_Slot )) {\r
808                 l_Status = PciHdrRead( &pi_pMdDevContext->m_MyHdr.m_Hdr[0], l_MyBus, l_Slot);  \r
809                 if (l_Status != STATUS_SUCCESS)\r
810                         return l_Status;\r
811         }\r
812         else { /* not found my device */\r
813                 return STATUS_UNSUCCESSFUL;\r
814         }\r
815         pi_pMdDevContext->m_MyHdr.m_Bus = l_MyBus;\r
816         pi_pMdDevContext->m_MyHdr.m_Slot = l_Slot;\r
817         \r
818  \r
819         /* \r
820          * HCA device\r
821          */\r
822         l_DevId = ((int)(MD_DEV_ID_TAVOR) << 16) | MLX_VENDOR_ID;       \r
823         l_Slot = 0;\r
824         if (PciFindDeviceByBusAndId( l_MyBus, l_DevId, &l_Slot )) {\r
825                 l_Status = PciHdrRead( &pi_pMdDevContext->m_HcaHdr.m_Hdr[0], l_MyBus, l_Slot);  \r
826                 if (l_Status != STATUS_SUCCESS)\r
827                         return l_Status;\r
828         }\r
829         else { /* not found HCA device */\r
830                 if (pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR_SD) \r
831                         return STATUS_UNSUCCESSFUL;\r
832                 pi_pMdDevContext->m_HcaHdr.m_Hdr[0] = 0;        /* mark, that PCI header was not saved */\r
833         }\r
834         pi_pMdDevContext->m_HcaHdr.m_Bus = l_MyBus;\r
835         pi_pMdDevContext->m_HcaHdr.m_Slot = l_Slot;\r
836  \r
837         /* \r
838          * Bridge device\r
839          */\r
840         l_SecBus =  l_MyBus;\r
841         if (PciFindBridgeByBus( l_SecBus, &l_MyBus, &l_Slot )) {\r
842                 l_Status = PciHdrRead( &pi_pMdDevContext->m_BridgeHdr.m_Hdr[0], l_MyBus, l_Slot);  \r
843                 if (l_Status != STATUS_SUCCESS)\r
844                         return l_Status;\r
845         }\r
846         else { /* not found Bridge device */\r
847                 return STATUS_UNSUCCESSFUL;\r
848         }\r
849         pi_pMdDevContext->m_BridgeHdr.m_Bus = l_MyBus;\r
850         pi_pMdDevContext->m_BridgeHdr.m_Slot = l_Slot;\r
851 \r
852         }\r
853         else\r
854         if (pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR ||\r
855                 pi_pMdDevContext->m_eDevType == MD_DEV_IX_ARBEL_TM) {\r
856         \r
857                 /* \r
858                  * HCA device\r
859                  */\r
860                 l_DevId = ((int)(MD_DEV_ID_TAVOR) << 16) | MLX_VENDOR_ID;        \r
861                 pi_pMdDevContext->m_HcaHdr.m_Hdr[0] = 0;        /* mark, that PCI header was not saved */\r
862                 l_Slot = 0;\r
863                 if (PciFindDeviceByBusAndId( l_MyBus, l_DevId, &l_Slot )) {\r
864                         l_Status = PciHdrRead(  &pi_pMdDevContext->m_HcaHdr.m_Hdr[0], l_MyBus, l_Slot);  \r
865                         if (l_Status != STATUS_SUCCESS)\r
866                                 return l_Status;\r
867                 }\r
868                 else { /* not found HCA device */\r
869                         return STATUS_UNSUCCESSFUL;\r
870                 }\r
871                 pi_pMdDevContext->m_HcaHdr.m_Bus = l_MyBus;\r
872                 pi_pMdDevContext->m_HcaHdr.m_Slot = l_Slot;\r
873 \r
874                 /* \r
875                  * Bridge device\r
876                  */\r
877                 l_SecBus =  l_MyBus;\r
878                 if (PciFindBridgeByBus( l_SecBus, &l_MyBus, &l_Slot )) {\r
879                         l_Status = PciHdrRead( &pi_pMdDevContext->m_BridgeHdr.m_Hdr[0], l_MyBus, l_Slot);  \r
880                         if (l_Status != STATUS_SUCCESS)\r
881                                 return l_Status;\r
882                 }\r
883                 else { /* not found Bridge device */\r
884                         return STATUS_UNSUCCESSFUL;\r
885                 }\r
886                 pi_pMdDevContext->m_BridgeHdr.m_Bus = l_MyBus;\r
887                 pi_pMdDevContext->m_BridgeHdr.m_Slot = l_Slot;\r
888         }\r
889         else\r
890                 return STATUS_UNSUCCESSFUL;\r
891 \r
892          /* enable Reset */\r
893          pi_pMdDevContext->m_fMayReset = TRUE;\r
894 \r
895          return STATUS_SUCCESS;\r
896 }\r
897 \r
898 /*------------------------------------------------------------------------------------------------------*/\r
899 \r
900 NTSTATUS\r
901 PciHdrRestore(\r
902         IN      PMD_DEV_CONTEXT_T       pi_pMdDevContext\r
903         )\r
904 {\r
905 \r
906         if (((pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR_SD) || \r
907               (pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR_BD))) {\r
908                 /* \r
909                  * Bridge device\r
910                  */\r
911                 if (pi_pMdDevContext->m_BridgeHdr.m_Hdr[0]) {\r
912                         PciHdrWrite( pi_pMdDevContext, \r
913                                 (PCHAR)&pi_pMdDevContext->m_BridgeHdr.m_Hdr[0], \r
914                                 pi_pMdDevContext->m_BridgeHdr.m_Bus, \r
915                                 pi_pMdDevContext->m_BridgeHdr.m_Slot,\r
916                                 WRITE_WITH_PCI_CONFIG);  \r
917                 }\r
918         \r
919                 /* \r
920                  * My device\r
921                  */\r
922                 if (pi_pMdDevContext->m_MyHdr.m_Hdr[0]) {\r
923                         PciHdrWrite( pi_pMdDevContext, \r
924                                 (PCHAR)&pi_pMdDevContext->m_MyHdr.m_Hdr[0], \r
925                                 pi_pMdDevContext->m_MyHdr.m_Bus, \r
926                                 pi_pMdDevContext->m_MyHdr.m_Slot,\r
927                                 WRITE_WITH_SET_BUS);  \r
928                 }\r
929  \r
930                 /* \r
931                  * HCA device\r
932                  */\r
933                 if (pi_pMdDevContext->m_HcaHdr.m_Hdr[0]) {\r
934                         PciHdrWrite( pi_pMdDevContext, \r
935                                 (PCHAR)&pi_pMdDevContext->m_HcaHdr.m_Hdr[0], \r
936                                 pi_pMdDevContext->m_HcaHdr.m_Bus, \r
937                                 pi_pMdDevContext->m_HcaHdr.m_Slot,\r
938                                 WRITE_WITH_SET_BUS);  \r
939                 }\r
940         }\r
941         else\r
942         if (pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR ||\r
943                 pi_pMdDevContext->m_eDevType == MD_DEV_IX_ARBEL_TM) {\r
944         \r
945                 /* \r
946                  * Bridge device\r
947                  */\r
948                 if (pi_pMdDevContext->m_BridgeHdr.m_Hdr[0]) {\r
949                         PciHdrWrite( pi_pMdDevContext, \r
950                                 (PCHAR)&pi_pMdDevContext->m_BridgeHdr.m_Hdr[0], \r
951                                 pi_pMdDevContext->m_BridgeHdr.m_Bus, \r
952                                 pi_pMdDevContext->m_BridgeHdr.m_Slot,\r
953                                 WRITE_WITH_PCI_CONFIG);  \r
954                 }\r
955         \r
956                 /* \r
957                  * HCA device\r
958                  */\r
959                 if (pi_pMdDevContext->m_HcaHdr.m_Hdr[0]) {\r
960                         PciHdrWrite( pi_pMdDevContext, \r
961                                 (PCHAR)&pi_pMdDevContext->m_HcaHdr.m_Hdr[0], \r
962                                 pi_pMdDevContext->m_HcaHdr.m_Bus, \r
963                                 pi_pMdDevContext->m_HcaHdr.m_Slot,\r
964                                 WRITE_WITH_SET_BUS);  \r
965                 }\r
966         }\r
967         else\r
968                 return STATUS_UNSUCCESSFUL;\r
969                 \r
970         return STATUS_SUCCESS;\r
971 }\r
972 \r
973 /*------------------------------------------------------------------------------------------------------*/\r
974 \r
975 NTSTATUS\r
976 PciReset(\r
977         IN      PMD_DEV_CONTEXT_T       pi_pMdDevContext\r
978         )\r
979 {\r
980         ULONG           l_ResetOffset   = 0x0f0010;\r
981         ULONG           l_ResetValue    = 0x01000000;   /* 1 in BigEndian */\r
982         NTSTATUS        l_Status;\r
983         \r
984         /* \r
985          * RESET\r
986          */\r
987         if (pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR_BD) { /* we are burner device */\r
988                 PCICONF_WRITE( pi_pMdDevContext, \r
989                         l_ResetOffset, \r
990                         l_ResetValue, \r
991                         l_Status );\r
992         }\r
993         else \r
994         if (pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR ||\r
995                 pi_pMdDevContext->m_eDevType == MD_DEV_IX_ARBEL_TM) { /* we are Tavor device */\r
996                 l_Status = PciDevReset(pi_pMdDevContext, l_ResetOffset, l_ResetValue );\r
997         }\r
998         else\r
999         if (pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR_SD) { /* we are service device */\r
1000                 l_Status = PciDevReset(pi_pMdDevContext, l_ResetOffset, l_ResetValue );\r
1001         }\r
1002         else { /* other devices not supported */\r
1003                 l_Status = STATUS_UNSUCCESSFUL;\r
1004         }\r
1005 \r
1006         /* \r
1007          * wait for RESET end\r
1008          */\r
1009         {\r
1010                 #define TIMEOUT_IN_USECS        1500000         /* 1.5 sec */\r
1011                 LARGE_INTEGER  timeout;\r
1012                 timeout.QuadPart = - 10 * TIMEOUT_IN_USECS;\r
1013                 KeDelayExecutionThread( KernelMode, FALSE, &timeout );\r
1014         }\r
1015          \r
1016         /* \r
1017          * Restore\r
1018          */\r
1019         l_Status = PciHdrRestore( pi_pMdDevContext );\r
1020 \r
1021         return l_Status;\r
1022 \r
1023 }\r
1024 \r
1025 #endif\r
1026 #endif\r
1027 \r
1028 /*------------------------------------------------------------------------------------------------------*/\r
1029 \r
1030 NTSTATUS ReadBarInfo( \r
1031         PMD_DEV_CONTEXT_T               pi_pMdDevContext, \r
1032         ULONG                                   pi_LowOffset,\r
1033         ULONG                                   pi_HighOffset,\r
1034         ULONG                                   pi_SizeOffset,\r
1035         PMD_BAR_T                               pi_pBar,\r
1036         PCHAR                                   pi_BarName,\r
1037         ULONG                                   pi_BarNum\r
1038         )\r
1039 /*++\r
1040 \r
1041 Routine Description:\r
1042 \r
1043     This routine reads BAR inforamtion from CR-space and stores it to device context\r
1044 \r
1045 Arguments:\r
1046 \r
1047         pi_pMdDevContext....... My device context\r
1048         pi_LowOffset........... offset of low part of BAR address\r
1049         pi_HighOffset.......... offset of high part of BAR address\r
1050         pi_SizeOffset.......... offset of BAR size\r
1051         pi_pBar ............... pointer to BAR descriptor\r
1052         pi_BarName............. BAR name for debug print \r
1053         pi_BarNum.............. BAR number\r
1054         \r
1055 Return Value:\r
1056 \r
1057     ERROR code.\r
1058 \r
1059 --*/\r
1060 { /* ReadBarInfo */\r
1061 \r
1062         ULONG           l_LowPart, l_HighPart, l_Size;\r
1063         NTSTATUS        l_Status;\r
1064         LARGE_INTEGER   l_Offset = { 0,0 };\r
1065         \r
1066         //\r
1067         // read BAR0 \r
1068         //\r
1069         \r
1070         /* read CR-space */\r
1071         PCICONF_READ( pi_pMdDevContext, pi_LowOffset, &l_LowPart, l_Status );\r
1072         if (!NT_SUCCESS(l_Status))\r
1073                 return l_Status;\r
1074         PCICONF_READ( pi_pMdDevContext, pi_HighOffset, &l_HighPart, l_Status  );\r
1075         if (!NT_SUCCESS(l_Status))\r
1076                 return l_Status;\r
1077         PCICONF_READ( pi_pMdDevContext, pi_SizeOffset, &l_Size, l_Status  );\r
1078         if (!NT_SUCCESS(l_Status))\r
1079                 return l_Status;\r
1080                 \r
1081         /* store BAR parameters */\r
1082         pi_pBar->m_MemPhysAddr.LowPart  = l_LowPart & 0xfff00000;\r
1083         pi_pBar->m_MemPhysAddr.HighPart = l_HighPart;\r
1084         pi_pBar->m_ulMemSize                    = 1 << ((l_Size & 63) + 20);    /* l_size is 6 bit field */\r
1085         pi_pBar->m_usMemFlags                   = 0;\r
1086         pi_pBar->m_ulKernelSize                 = pi_pBar->m_ulMemSize;\r
1087         pi_pBar->m_ulKernelOffset               = 0;\r
1088         \r
1089         /* recalculate boudaries of mapped memory for DDR */\r
1090         if (pi_BarNum == 2 && pi_pMdDevContext->m_ulDdrMapSize != -1) {\r
1091                 pi_pBar->m_ulKernelSize = pi_pMdDevContext->m_ulDdrMapSize;\r
1092                 pi_pBar->m_ulKernelOffset = pi_pMdDevContext->m_ulDdrMapOffset;\r
1093                 l_Offset.LowPart = pi_pMdDevContext->m_ulDdrMapOffset;\r
1094         } /* for DDR - map some subset of memory */\r
1095         \r
1096         /* map physical address into virtual kernel one */\r
1097         l_Offset.QuadPart += pi_pBar->m_MemPhysAddr.QuadPart;\r
1098         pi_pBar->m_pKernelAddr = (PUCHAR) MmMapIoSpace(\r
1099                 l_Offset, pi_pBar->m_ulKernelSize, MmNonCached);\r
1100         if (!pi_pBar->m_pKernelAddr)    return STATUS_NO_MEMORY;\r
1101         \r
1102         /* debug print */\r
1103         MdKdPrint( DBGLVL_LOW ,("(ReadBarInfo) Dev %d %s: Phys 0x%I64x Size 0x%x, Virt 0x%x Size 0x%x \n", \r
1104                 g_DevParams[pi_pMdDevContext->m_eDevType].m_DevId,  \r
1105                 pi_BarName, pi_pBar->m_MemPhysAddr, pi_pBar->m_ulMemSize, \r
1106                 pi_pBar->m_pKernelAddr, pi_pBar->m_ulKernelSize ));\r
1107            \r
1108         return STATUS_SUCCESS;\r
1109 }\r
1110 \r
1111 NTSTATUS ReadBars(PMD_DEV_CONTEXT_T pi_pMdDevContext)\r
1112 {\r
1113         NTSTATUS l_Status;\r
1114         PMD_BAR_T       l_pBar;                                         \r
1115         \r
1116         /* BAR0 */\r
1117         l_pBar = &pi_pMdDevContext->m_Cr;\r
1118         l_Status = ReadBarInfo( pi_pMdDevContext, \r
1119                 BYTE_OFFSET_A(Tavor->pcu0.pcu_address_decoder.hca_bar_0_lsbs),\r
1120                 BYTE_OFFSET_A(Tavor->pcu0.pcu_address_decoder.hca_bar_0_msbs),\r
1121                 BYTE_OFFSET_A(Tavor->pcu0.pcu_address_decoder.hca_bar_size_0),\r
1122                 l_pBar, "CR", 0 );\r
1123     if (!NT_SUCCESS(l_Status))\r
1124         return l_Status;\r
1125                 \r
1126         /* BAR1 */\r
1127         l_pBar = &pi_pMdDevContext->m_Uar;\r
1128         l_Status = ReadBarInfo( pi_pMdDevContext, \r
1129                 BYTE_OFFSET_A(Tavor->pcu0.pcu_address_decoder.hca_bar_1_lsbs),\r
1130                 BYTE_OFFSET_A(Tavor->pcu0.pcu_address_decoder.hca_bar_1_msbs),\r
1131                 BYTE_OFFSET_A(Tavor->pcu0.pcu_address_decoder.hca_bar_size_1),\r
1132                 l_pBar, "UAR", 1 );\r
1133     if (!NT_SUCCESS(l_Status))\r
1134         return l_Status;\r
1135                 \r
1136         /* BAR2 */\r
1137         l_pBar = &pi_pMdDevContext->m_Ddr;\r
1138         l_Status = ReadBarInfo( pi_pMdDevContext, \r
1139                 BYTE_OFFSET_A(Tavor->pcu0.pcu_address_decoder.dmu_bar_0_lsbs),\r
1140                 BYTE_OFFSET_A(Tavor->pcu0.pcu_address_decoder.dmu_bar_0_msbs),\r
1141                 BYTE_OFFSET_A(Tavor->pcu0.pcu_address_decoder.dmu_bar_size_0),\r
1142                 l_pBar, "DDR", 2 );\r
1143     if (!NT_SUCCESS(l_Status))\r
1144         return l_Status;\r
1145 \r
1146     return STATUS_SUCCESS;      \r
1147 }               \r
1148                 \r
1149 NTSTATUS ConfIoctl( \r
1150         IN      PMD_DEV_CONTEXT_T       pi_pMdDevContext, \r
1151         IN      PMD_PCS_CONTEXT_T       pi_pPcsContext,\r
1152         IN      ULONG                           pi_nIoControlCode, \r
1153         IN      PVOID                           pi_pInBuffer, \r
1154         IN      ULONG                           pi_nInBufLength,\r
1155         IN      PVOID                           pi_pOutBuffer, \r
1156         IN      ULONG                           pi_nOutBufLength, \r
1157         OUT     PULONG                          po_pnBytes \r
1158         )\r
1159 {\r
1160         NTSTATUS        l_Status;\r
1161         PULONG          l_pOffset;\r
1162         PULONG          l_pData, l_Data;\r
1163         PPCICONF_MODIFY_T pm;\r
1164         PPCICONF_WRITE4_T pw;\r
1165 \r
1166         *po_pnBytes = 0;\r
1167         \r
1168         switch (pi_nIoControlCode)\r
1169         { /* handle Ioctls */\r
1170         \r
1171                 case UDLL_MAKE_IOCTL(WIN_PCICONF_READ4):\r
1172                         /* call_result_t PciConfRead4( HANDLE h, DWORD offset, DWORD * p_data ) */\r
1173                         l_pOffset       = (PULONG)pi_pInBuffer;\r
1174                         l_pData         = (PULONG)pi_pOutBuffer;\r
1175                         PCICONF_READ( pi_pMdDevContext, *l_pOffset, l_pData, l_Status );\r
1176                         if (!NT_SUCCESS(l_Status)) *po_pnBytes = sizeof(ULONG);\r
1177                         break;\r
1178                 \r
1179                 case UDLL_MAKE_IOCTL(WIN_PCICONF_WRITE4):\r
1180                         /* call_result_t PciConfWrite4( HANDLE h, PPCICONF_WRITE4_T params ) */\r
1181                         pw =(PPCICONF_WRITE4_T)pi_pInBuffer;\r
1182                         PCICONF_WRITE( pi_pMdDevContext, pw->offset, pw->data, l_Status );\r
1183                         break;\r
1184                 \r
1185                 case UDLL_MAKE_IOCTL(WIN_PCICONF_MODIFY):\r
1186                         /* call_result_t PciConfModify( HANDLE h, PPCICONF_MODIFY_T params, DWORD * p_old_data ) */\r
1187                         pm = (PPCICONF_MODIFY_T)pi_pInBuffer;\r
1188                         l_pData         = (PULONG)pi_pOutBuffer;\r
1189 \r
1190                         PCICONF_READ( pi_pMdDevContext, pm->offset, &l_Data, l_Status );\r
1191                         if (!NT_SUCCESS(l_Status)) break;\r
1192                         *l_Data = (*l_Data & ~pm->mask) | (pm->data & pm->mask);\r
1193                         l_Status = PCICONF_DATA_WRITE(pi_pMdDevContext, l_Data );\r
1194                         if (!NT_SUCCESS(l_Status)) *po_pnBytes = sizeof(ULONG);\r
1195                         break;\r
1196 \r
1197                 case UDLL_MAKE_IOCTL(WIN_SOFT_RESET):\r
1198                 #ifdef __i386__\r
1199                         l_Status = PciReset( pi_pMdDevContext );\r
1200                 #endif\r
1201                         break;\r
1202                         \r
1203                 default:\r
1204                         MdKdPrint( DBGLVL_DEFAULT,("(ConfIoctl) Unsupported Ioctl 0x%x\n", pi_nIoControlCode));\r
1205                         l_Status = STATUS_NOT_IMPLEMENTED;\r
1206                         break;\r
1207 \r
1208         } /* handle Ioctls */\r
1209 \r
1210         return l_Status;\r
1211 }\r
1212 \r
1213 NTSTATUS\r
1214 ConfIoctlFast(\r
1215     IN PMD_DEV_CONTEXT_T        pi_pMdDevContext,\r
1216     IN PIRP                                     pi_pIrp\r
1217     )\r
1218 {\r
1219         NTSTATUS        l_Status;\r
1220         PIO_STACK_LOCATION              l_pIrpStack;\r
1221         \r
1222         /* get pointer to IRP stack */\r
1223     l_pIrpStack         = IoGetCurrentIrpStackLocation (pi_pIrp);\r
1224         \r
1225         switch (l_pIrpStack->Parameters.DeviceIoControl.IoControlCode)\r
1226         { /* handle Ioctls */\r
1227         \r
1228                 case UDLL_MAKE_IOCTL_BUF(WIN_PCICONF_READ4):\r
1229                         /* call_result_t PciConfRead4( HANDLE h, DWORD offset, DWORD * p_data ) */\r
1230                         PCICONF_READ( pi_pMdDevContext, \r
1231                                 *(PULONG)pi_pIrp->AssociatedIrp.SystemBuffer, \r
1232                                 (PULONG)pi_pIrp->AssociatedIrp.SystemBuffer, \r
1233                                 l_Status );\r
1234                         if (NT_SUCCESS(l_Status)) \r
1235                                 pi_pIrp->IoStatus.Information = sizeof(ULONG);\r
1236                         else    \r
1237                                 pi_pIrp->IoStatus.Information = 0;\r
1238                         break;\r
1239                 \r
1240                 case UDLL_MAKE_IOCTL_BUF(WIN_PCICONF_WRITE4):\r
1241                         /* call_result_t PciConfWrite4( HANDLE h, PPCICONF_WRITE4_T params ) */\r
1242                         PCICONF_WRITE( pi_pMdDevContext, \r
1243                                 *((PULONG)pi_pIrp->AssociatedIrp.SystemBuffer + 0), \r
1244                                 *((PULONG)pi_pIrp->AssociatedIrp.SystemBuffer + 1), \r
1245                                 l_Status );\r
1246                         pi_pIrp->IoStatus.Information = 0;\r
1247                         break;\r
1248                 \r
1249                 case UDLL_MAKE_IOCTL(WIN_SOFT_RESET):\r
1250                 #ifdef __i386__\r
1251                         l_Status = PciReset( pi_pMdDevContext );\r
1252                 #endif\r
1253                         pi_pIrp->IoStatus.Information = 0;\r
1254                         break;\r
1255                         \r
1256                 default:\r
1257                         MdKdPrint( DBGLVL_DEFAULT,("(ConfIoctl) Unsupported Ioctl 0x%x\n", \r
1258                                 l_pIrpStack->Parameters.DeviceIoControl.IoControlCode));\r
1259                         pi_pIrp->IoStatus.Information = 0;\r
1260                         l_Status = STATUS_NOT_IMPLEMENTED;\r
1261                         break;\r
1262 \r
1263         } /* handle Ioctls */\r
1264 \r
1265         return l_Status;\r
1266 }\r
1267 \r
1268 void SetPciMasterBit(\r
1269     IN PMD_DEV_CONTEXT_T        pi_pMdDevContext\r
1270 )\r
1271 {\r
1272         ULONG           l_Data;\r
1273         ULONG           l_Offset = 4;\r
1274         \r
1275         PCICONF_DWORD_READ( pi_pMdDevContext, &l_Data, l_Offset );\r
1276         MdKdPrint( DBGLVL_LOW,("(SetPciMasterBit) CmdStatus Reg 0x%x\n",l_Data)); \r
1277         l_Data |= 4;\r
1278         PCICONF_DWORD_WRITE( pi_pMdDevContext, l_Data, l_Offset );\r
1279         PCICONF_DWORD_READ( pi_pMdDevContext, &l_Data, l_Offset );\r
1280         MdKdPrint( DBGLVL_LOW,("(SetPciMasterBit) CmdStatus Reg 0x%x\n",l_Data)); \r
1281 }\r
1282 \r
1283 NTSTATUS MdMosalHelper( \r
1284     IN PMD_DEV_CONTEXT_T        pi_pMdDevContext,\r
1285     IN int cmd\r
1286 )\r
1287 {\r
1288         NTSTATUS l_Status = STATUS_NOT_IMPLEMENTED; \r
1289         switch (cmd) {\r
1290                 case MD_HELPER_CARD_RESET:\r
1291 #ifdef __i386__\r
1292                         //l_Status = PciReset( pi_pMdDevContext );\r
1293 #endif\r
1294                         break;\r
1295                 default:\r
1296                         break;\r
1297         }\r
1298         return l_Status;\r
1299 }\r
1300         \r