update for HEAD-2003091401
[reactos.git] / drivers / net / ndis / ndis / io.c
1 /*
2  * COPYRIGHT:   See COPYING in the top level directory
3  * PROJECT:     ReactOS NDIS library
4  * FILE:        ndis/io.c
5  * PURPOSE:     I/O related routines
6  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7  *              Vizzini (vizzini@plasmic.com)
8  * REVISIONS:
9  *   CSH 01/08-2000 Created
10  *   8-20-2003 Vizzini - DMA support
11  */
12 #include <ndissys.h>
13 #include <miniport.h>
14
15 VOID STDCALL HandleDeferredProcessing(
16     IN  PKDPC   Dpc,
17     IN  PVOID   DeferredContext,
18     IN  PVOID   SystemArgument1,
19     IN  PVOID   SystemArgument2)
20 /*
21  * FUNCTION: Deferred interrupt processing routine
22  * ARGUMENTS:
23  *     Dpc             = Pointer to DPC object
24  *     DeferredContext = Pointer to context information (LOGICAL_ADAPTER)
25  *     SystemArgument1 = Unused
26  *     SystemArgument2 = Unused
27  */
28 {
29     BOOLEAN WasBusy;
30     PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(DeferredContext);
31
32     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
33
34     KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock);
35     WasBusy = Adapter->MiniportBusy;
36     Adapter->MiniportBusy = TRUE;
37     KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock);
38
39     /* Call the deferred interrupt service handler for this adapter */
40     (*Adapter->Miniport->Chars.HandleInterruptHandler)(
41         Adapter->NdisMiniportBlock.MiniportAdapterContext);
42
43     KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock);
44     if ((!WasBusy) && (Adapter->WorkQueueHead)) {
45         KeInsertQueueDpc(&Adapter->MiniportDpc, NULL, NULL);
46     } else {
47         Adapter->MiniportBusy = WasBusy;
48     }
49     KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock);
50
51     NDIS_DbgPrint(MAX_TRACE, ("Leaving.\n"));
52 }
53
54
55 BOOLEAN STDCALL ServiceRoutine(
56     IN  PKINTERRUPT Interrupt,
57     IN  PVOID       ServiceContext)
58 /*
59  * FUNCTION: Interrupt service routine
60  * ARGUMENTS:
61  *     Interrupt      = Pointer to interrupt object
62  *     ServiceContext = Pointer to context information (LOGICAL_ADAPTER)
63  * RETURNS
64  *     TRUE if a miniport controlled device generated the interrupt
65  */
66 {
67     BOOLEAN InterruptRecognized;
68     BOOLEAN QueueMiniportHandleInterrupt;
69     PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(ServiceContext);
70
71     NDIS_DbgPrint(MAX_TRACE, ("Called. Adapter (0x%X)\n", Adapter));
72
73     (*Adapter->Miniport->Chars.ISRHandler)(&InterruptRecognized,
74                                            &QueueMiniportHandleInterrupt,
75                                            Adapter->NdisMiniportBlock.MiniportAdapterContext);
76
77     if (QueueMiniportHandleInterrupt) {
78         NDIS_DbgPrint(MAX_TRACE, ("Queueing DPC.\n"));
79         KeInsertQueueDpc(&Adapter->NdisMiniportBlock.Interrupt->InterruptDpc, NULL, NULL);
80     }
81
82     NDIS_DbgPrint(MAX_TRACE, ("Leaving.\n"));
83
84     return InterruptRecognized;
85 }
86
87
88 /*
89  * @unimplemented
90  */
91 VOID
92 EXPORT
93 NdisCompleteDmaTransfer(
94     OUT PNDIS_STATUS    Status,
95     IN  PNDIS_HANDLE    NdisDmaHandle,
96     IN  PNDIS_BUFFER    Buffer,
97     IN  ULONG           Offset,
98     IN  ULONG           Length,
99     IN  BOOLEAN         WriteToDevice)
100 {
101     UNIMPLEMENTED
102 }
103
104
105 /*
106  * @unimplemented
107  */
108 VOID
109 EXPORT
110 NdisFlushBuffer(
111     IN  PNDIS_BUFFER    Buffer,
112     IN  BOOLEAN         WriteToDevice)
113 {
114     UNIMPLEMENTED
115 }
116
117
118 /*
119  * @unimplemented
120  */
121 ULONG
122 EXPORT
123 NdisGetCacheFillSize(
124     VOID)
125 {
126     UNIMPLEMENTED
127
128         return 0;
129 }
130
131
132 /*
133  * @implemented
134  */
135 VOID
136 EXPORT
137 NdisImmediateReadPortUchar(
138     IN  NDIS_HANDLE WrapperConfigurationContext,
139     IN  ULONG       Port,
140     OUT PUCHAR      Data)
141 {
142     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
143     *Data = READ_PORT_UCHAR((PUCHAR)Port); // FIXME: What to do with WrapperConfigurationContext?
144 }
145
146
147 /*
148  * @implemented
149  */
150 VOID
151 EXPORT
152 NdisImmediateReadPortUlong(
153     IN  NDIS_HANDLE WrapperConfigurationContext,
154     IN  ULONG       Port,
155     OUT PULONG      Data)
156 {
157     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
158     *Data = READ_PORT_ULONG((PULONG)Port); // FIXME: What to do with WrapperConfigurationContext?
159 }
160
161
162 /*
163  * @implemented
164  */
165 VOID
166 EXPORT
167 NdisImmediateReadPortUshort(
168     IN  NDIS_HANDLE WrapperConfigurationContext,
169     IN  ULONG       Port,
170     OUT PUSHORT     Data)
171 {
172     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
173     *Data = READ_PORT_USHORT((PUSHORT)Port); // FIXME: What to do with WrapperConfigurationContext?
174 }
175
176
177 /*
178  * @implemented
179  */
180 VOID
181 EXPORT
182 NdisImmediateWritePortUchar(
183     IN  NDIS_HANDLE WrapperConfigurationContext,
184     IN  ULONG       Port,
185     IN  UCHAR       Data)
186 {
187     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
188     WRITE_PORT_UCHAR((PUCHAR)Port, Data); // FIXME: What to do with WrapperConfigurationContext?
189 }
190
191
192 /*
193  * @implemented
194  */
195 VOID
196 EXPORT
197 NdisImmediateWritePortUlong(
198     IN  NDIS_HANDLE WrapperConfigurationContext,
199     IN  ULONG       Port,
200     IN  ULONG       Data)
201 {
202     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
203     WRITE_PORT_ULONG((PULONG)Port, Data); // FIXME: What to do with WrapperConfigurationContext?
204 }
205
206
207 /*
208  * @unimplemented
209  */
210 VOID
211 EXPORT
212 NdisImmediateWritePortUshort(
213     IN  NDIS_HANDLE WrapperConfigurationContext,
214     IN  ULONG       Port,
215     IN  USHORT      Data)
216 {
217     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
218     WRITE_PORT_USHORT((PUSHORT)Port, Data); // FIXME: What to do with WrapperConfigurationContext?
219 }
220
221
222 IO_ALLOCATION_ACTION NdisMapRegisterCallback (
223     IN PDEVICE_OBJECT  DeviceObject,
224     IN PIRP            Irp,
225     IN PVOID           MapRegisterBase,
226     IN PVOID           Context)
227 /*
228  * FUNCTION: Called back during reservation of map registers
229  */
230 {
231   PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)Context;
232   PADAPTER_MAP_REGISTER_LIST Register = ExAllocatePool(NonPagedPool, sizeof(ADAPTER_MAP_REGISTER_LIST));
233
234    NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
235
236   if(!Register)
237     {
238       NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n"));
239       KeSetEvent(&Adapter->DmaEvent, 0, FALSE);
240       return DeallocateObject;
241     }
242
243   Register->MapRegister = MapRegisterBase;
244   Register->NumRegisters = Adapter->MapRegistersRequested;
245
246   ExInterlockedInsertTailList(&Adapter->MapRegisterList.ListEntry, &Register->ListEntry, &Adapter->DmaLock);
247
248   KeSetEvent(&Adapter->DmaEvent, 0, FALSE);
249
250   /* XXX this is only the thing to do for busmaster NICs */
251   return DeallocateObjectKeepRegisters;
252 }
253
254 /*
255  * @implemented
256  */
257 NDIS_STATUS
258 EXPORT
259 NdisMAllocateMapRegisters(
260     IN  NDIS_HANDLE MiniportAdapterHandle,
261     IN  UINT        DmaChannel,
262     IN  BOOLEAN     DmaSize,
263     IN  ULONG       BaseMapRegistersNeeded,
264     IN  ULONG       MaximumBufferSize)
265 /*
266  * FUNCTION: Allocate map registers for use in DMA transfers
267  * ARGUMENTS:
268  *     MiniportAdapterHandle: Passed in to MiniportInitialize
269  *     DmaChannel: DMA channel to use
270  *     DmaSize: bit width of DMA transfers
271  *     BaseMapRegistersNeeded: number of map registers requested
272  *     MaximumBufferSize: largest single buffer transferred
273  * RETURNS:
274  *     NDIS_STATUS_SUCCESS on success
275  *     NDIS_STATUS_RESOURCES on failure
276  * NOTES: 
277  *     - the win2k ddk and the nt4 ddk have conflicting prototypes for this.
278  *       I'm implementing the 2k one.
279  */
280 {
281   DEVICE_DESCRIPTION Description;
282   PADAPTER_OBJECT    AdapterObject = 0;
283   UINT               MapRegistersRequired = 0;
284   UINT               MapRegistersPerBaseRegister = 0;
285   ULONG              AvailableMapRegisters;
286   NTSTATUS           NtStatus;
287   PLOGICAL_ADAPTER   Adapter = 0;
288   PDEVICE_OBJECT     DeviceObject = 0;
289   KIRQL              OldIrql;
290
291   NDIS_DbgPrint(MAX_TRACE, ("called: Handle 0x%x, DmaChannel 0x%x, DmaSize 0x%x, BaseMapRegsNeeded: 0x%x, MaxBuffer: 0x%x.\n",
292                             MiniportAdapterHandle, DmaChannel, DmaSize, BaseMapRegistersNeeded, MaximumBufferSize));
293
294   memset(&Description,0,sizeof(Description));
295
296   Adapter = (PLOGICAL_ADAPTER)MiniportAdapterHandle;
297   DeviceObject = Adapter->NdisMiniportBlock.DeviceObject;
298
299   InitializeListHead(&Adapter->MapRegisterList.ListEntry);
300   KeInitializeEvent(&Adapter->DmaEvent, NotificationEvent, FALSE);
301   KeInitializeSpinLock(&Adapter->DmaLock);
302
303   /*
304   * map registers correlate to physical pages.  ndis documents a
305   * maximum of 64 map registers that it will return.  
306   * at 4k pages, a 1514-byte buffer can span not more than 2 pages.
307   *
308   * the number of registers required for a given physical mapping
309   * is (first register + last register + one per page size), 
310   * given that physical mapping is > 2.
311   */
312
313   /* unhandled corner case: 1-byte max buffer size */
314   MapRegistersPerBaseRegister = 2 + MaximumBufferSize / PAGE_SIZE;
315   MapRegistersRequired = BaseMapRegistersNeeded * MapRegistersPerBaseRegister;
316
317   if(MapRegistersRequired > 64)
318     {
319       NDIS_DbgPrint(MID_TRACE, ("Request for too many map registers: %d\n", MapRegistersRequired));
320       return NDIS_STATUS_RESOURCES;
321     }
322
323   Description.Version = DEVICE_DESCRIPTION_VERSION;
324   Description.Master = TRUE;                         /* implied by calling this function */
325   Description.ScatterGather = FALSE;                 /* implied by calling this function */
326   Description.DemandMode = 0;                        /* unused due to bus master */
327   Description.AutoInitialize = 0;                    /* unused due to bus master */
328   Description.Dma32BitAddresses = DmaSize;          
329   Description.IgnoreCount = 0;                       /* unused due to bus master */
330   Description.Reserved1 = 0;
331   Description.Reserved2 = 0;
332   Description.BusNumber = Adapter->BusNumber;
333   Description.DmaChannel = 0;                        /* unused due to bus master */
334   Description.InterfaceType = Adapter->BusType;
335   Description.DmaChannel = 0;                        /* unused due to bus master */
336   Description.DmaWidth = 0;                          /* unused (i think) due to bus master */
337   Description.DmaSpeed = 0;                          /* unused (i think) due to bus master */
338   Description.MaximumLength = 0;                     /* unused (i think) due to bus master */
339   Description.DmaPort = 0;                           /* unused due to bus type */
340
341   AvailableMapRegisters = MapRegistersRequired;
342   AdapterObject = HalGetAdapter(&Description, &AvailableMapRegisters);
343
344   if(!AdapterObject)
345     {
346       NDIS_DbgPrint(MIN_TRACE, ("Unable to allocate an adapter object; bailing out\n"));
347       return NDIS_STATUS_RESOURCES;
348     }
349
350   Adapter->AdapterObject = AdapterObject;
351
352   if(AvailableMapRegisters < MapRegistersRequired)
353     {
354       NDIS_DbgPrint(MIN_TRACE, ("Didn't get enough map registers from hal - requested 0x%x, got 0x%x\n", 
355                                 MapRegistersRequired, AvailableMapRegisters));
356       return NDIS_STATUS_RESOURCES;
357     }
358
359   KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
360
361   Adapter->MapRegistersRequested = MapRegistersRequired;
362
363   NtStatus = IoAllocateAdapterChannel(AdapterObject, DeviceObject, 
364       MapRegistersRequired, NdisMapRegisterCallback, Adapter);
365
366   KeLowerIrql(OldIrql);
367
368   if(!NT_SUCCESS(NtStatus))
369     {
370       NDIS_DbgPrint(MIN_TRACE, ("IoAllocateAdapterChannel failed: 0x%x\n", NtStatus));
371       return NDIS_STATUS_RESOURCES;
372     }
373
374   NtStatus = KeWaitForSingleObject(&Adapter->DmaEvent, Executive, KernelMode, FALSE, 0);
375
376   if(!NT_SUCCESS(NtStatus))
377     {
378       NDIS_DbgPrint(MIN_TRACE, ("KeWaitForSingleObject failed: 0x%x\n", NtStatus));
379       return NDIS_STATUS_RESOURCES;
380     }
381
382   NDIS_DbgPrint(MAX_TRACE, ("returning success\n"));
383   return NDIS_STATUS_SUCCESS;
384 }
385
386
387 /*
388  * @unimplemented
389  */
390 VOID
391 EXPORT
392 NdisMCompleteDmaTransfer(
393     OUT PNDIS_STATUS    Status,
394     IN  PNDIS_HANDLE    MiniportDmaHandle,
395     IN  PNDIS_BUFFER    Buffer,
396     IN  ULONG           Offset,
397     IN  ULONG           Length,
398     IN  BOOLEAN         WriteToDevice)
399 {
400     UNIMPLEMENTED
401 }
402
403
404 /*
405  * @unimplemented
406  */
407 VOID
408 EXPORT
409 NdisMDeregisterDmaChannel(
410     IN  PNDIS_HANDLE    MiniportDmaHandle)
411 {
412     UNIMPLEMENTED
413 }
414
415
416 /*
417  * @implemented
418  */
419 VOID
420 EXPORT
421 NdisMDeregisterInterrupt(
422     IN  PNDIS_MINIPORT_INTERRUPT    Interrupt)
423 /*
424  * FUNCTION: Releases an interrupt vector
425  * ARGUMENTS:
426  *     Interrupt = Pointer to interrupt object
427  */
428 {
429     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
430     IoDisconnectInterrupt(Interrupt->InterruptObject);
431 }
432
433
434 /*
435  * @unimplemented
436  */
437 VOID
438 EXPORT
439 NdisMDeregisterIoPortRange(
440     IN  NDIS_HANDLE MiniportAdapterHandle,
441     IN  UINT        InitialPort,
442     IN  UINT        NumberOfPorts,
443     IN  PVOID       PortOffset)
444 /*
445  * FUNCTION: Releases a register mapping to I/O ports
446  * ARGUMENTS:
447  *     MiniportAdapterHandle = Specifies handle input to MiniportInitialize
448  *     InitialPort           = Bus-relative base port address of a range to be mapped
449  *     NumberOfPorts         = Specifies number of ports to be mapped
450  *     PortOffset            = Pointer to mapped base port address
451  */
452 {
453     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
454 }
455
456
457 /*
458  * @implemented
459  */
460 VOID
461 EXPORT
462 NdisMFreeMapRegisters(
463     IN  NDIS_HANDLE MiniportAdapterHandle)
464 /*
465  * FUNCTION: Free previously allocated map registers
466  * ARGUMENTS:
467  *     MiniportAdapterHandle:  Handle originally passed in to MiniportInitialize
468  * NOTES:
469  */
470 {
471   KIRQL            OldIrql;
472   PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)MiniportAdapterHandle;
473   PADAPTER_OBJECT  AdapterObject = Adapter->AdapterObject;
474
475   NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
476
477   KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
478
479   while(!IsListEmpty(&Adapter->MapRegisterList.ListEntry))
480     {
481       PADAPTER_MAP_REGISTER_LIST Register = (PADAPTER_MAP_REGISTER_LIST)RemoveTailList(&Adapter->MapRegisterList.ListEntry);
482       if(Register)
483         {
484           IoFreeMapRegisters(AdapterObject, Register->MapRegister, Register->NumRegisters);
485           ExFreePool(Register);
486         }
487       else
488         NDIS_DbgPrint(MIN_TRACE,("Internal NDIS error - Register is 0\n"));
489     }
490
491  KeLowerIrql(OldIrql);
492 }
493
494
495 /*
496  * @unimplemented
497  */
498 NDIS_STATUS
499 EXPORT
500 NdisMMapIoSpace(
501     OUT PVOID                   *VirtualAddress,
502     IN  NDIS_HANDLE             MiniportAdapterHandle,
503     IN  NDIS_PHYSICAL_ADDRESS   PhysicalAddress,
504     IN  UINT                    Length)
505 {
506     UNIMPLEMENTED
507
508         return NDIS_STATUS_FAILURE;
509 }
510
511
512 /*
513  * @unimplemented
514  */
515 ULONG
516 EXPORT
517 NdisMReadDmaCounter(
518     IN  NDIS_HANDLE MiniportDmaHandle)
519 {
520     UNIMPLEMENTED
521
522         return 0;
523 }
524
525
526 /*
527  * @unimplemented
528  */
529 NDIS_STATUS
530 EXPORT
531 NdisMRegisterDmaChannel(
532     OUT PNDIS_HANDLE            MiniportDmaHandle,
533     IN  NDIS_HANDLE             MiniportAdapterHandle,
534     IN  UINT                    DmaChannel,
535     IN  BOOLEAN                 Dma32BitAddresses,
536     IN  PNDIS_DMA_DESCRIPTION   DmaDescription,
537     IN  ULONG                   MaximumLength)
538 {
539     UNIMPLEMENTED
540
541         return NDIS_STATUS_FAILURE;
542 }
543
544 /*
545  * @implemented
546  */
547 NDIS_STATUS
548 EXPORT
549 NdisMRegisterInterrupt(
550     OUT PNDIS_MINIPORT_INTERRUPT    Interrupt,
551     IN  NDIS_HANDLE                 MiniportAdapterHandle,
552     IN  UINT                        InterruptVector,
553     IN  UINT                        InterruptLevel,
554     IN  BOOLEAN                     RequestIsr,
555     IN  BOOLEAN                     SharedInterrupt,
556     IN  NDIS_INTERRUPT_MODE         InterruptMode)
557 /*
558  * FUNCTION: Claims access to an interrupt vector
559  * ARGUMENTS:
560  *     Interrupt             = Address of interrupt object to initialize
561  *     MiniportAdapterHandle = Specifies handle input to MiniportInitialize
562  *     InterruptVector       = Specifies bus-relative vector to register
563  *     InterruptLevel        = Specifies bus-relative DIRQL vector for interrupt
564  *     RequestIsr            = TRUE if MiniportISR should always be called
565  *     SharedInterrupt       = TRUE if other devices may use the same interrupt
566  *     InterruptMode         = Specifies type of interrupt
567  * RETURNS:
568  *     Status of operation
569  */
570 {
571     NTSTATUS Status;
572     ULONG MappedIRQ;
573     KIRQL DIrql;
574     KAFFINITY Affinity;
575     PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(MiniportAdapterHandle);
576
577     NDIS_DbgPrint(MAX_TRACE, ("Called. InterruptVector (0x%X)  InterruptLevel (0x%X)  "
578         "SharedInterrupt (%d)  InterruptMode (0x%X)\n",
579         InterruptVector, InterruptLevel, SharedInterrupt, InterruptMode));
580
581     RtlZeroMemory(Interrupt, sizeof(NDIS_MINIPORT_INTERRUPT));
582
583     KeInitializeSpinLock(&Interrupt->DpcCountLock);
584
585     KeInitializeDpc(&Interrupt->InterruptDpc,
586                     HandleDeferredProcessing,
587                     Adapter);
588
589     KeInitializeEvent(&Interrupt->DpcsCompletedEvent,
590                       NotificationEvent,
591                       FALSE);
592
593     Interrupt->SharedInterrupt = SharedInterrupt;
594
595     Adapter->NdisMiniportBlock.Interrupt = Interrupt;
596
597     MappedIRQ = HalGetInterruptVector(Adapter->BusType,
598                                       Adapter->BusNumber,
599                                       InterruptLevel,
600                                       InterruptVector,
601                                       &DIrql,
602                                       &Affinity);
603
604     NDIS_DbgPrint(MAX_TRACE, ("Connecting to interrupt vector (0x%X)  Affinity (0x%X).\n", MappedIRQ, Affinity));
605
606     Status = IoConnectInterrupt(&Interrupt->InterruptObject,
607                                 ServiceRoutine,
608                                 Adapter,
609                                 &Interrupt->DpcCountLock,
610                                 MappedIRQ,
611                                 DIrql,
612                                 DIrql,
613                                 InterruptMode,
614                                 SharedInterrupt,
615                                 Affinity,
616                                 FALSE);
617
618     NDIS_DbgPrint(MAX_TRACE, ("Leaving. Status (0x%X).\n", Status));
619
620     if (NT_SUCCESS(Status))
621         return NDIS_STATUS_SUCCESS;
622
623     if (Status == STATUS_INSUFFICIENT_RESOURCES) {
624         /* FIXME: Log error */
625         return NDIS_STATUS_RESOURCE_CONFLICT;
626     }
627
628     return NDIS_STATUS_FAILURE;
629 }
630
631
632 /*
633  * @unimplemented
634  */
635 NDIS_STATUS
636 EXPORT
637 NdisMRegisterIoPortRange(
638     OUT PVOID       *PortOffset,
639     IN  NDIS_HANDLE MiniportAdapterHandle,
640     IN  UINT        InitialPort,
641     IN  UINT        NumberOfPorts)
642 /*
643  * FUNCTION: Sets up driver access to device I/O ports
644  * ARGUMENTS:
645  *     PortOffset            = Address of buffer to place mapped base port address
646  *     MiniportAdapterHandle = Specifies handle input to MiniportInitialize
647  *     InitialPort           = Bus-relative base port address of a range to be mapped
648  *     NumberOfPorts         = Specifies number of ports to be mapped
649  * RETURNS:
650  *     Status of operation
651  */
652 {
653   PHYSICAL_ADDRESS PortAddress, TranslatedAddress;
654   PLOGICAL_ADAPTER Adapter  = GET_LOGICAL_ADAPTER(MiniportAdapterHandle);
655   ULONG            AddressSpace = 1;    /* FIXME The HAL handles this wrong atm */
656
657   NDIS_DbgPrint(MAX_TRACE, ("Called - InitialPort 0x%x, NumberOfPorts 0x%x\n", InitialPort, NumberOfPorts));
658
659   memset(&PortAddress, 0, sizeof(PortAddress));
660
661   /* this might be a hack - ndis5 miniports seem to specify 0 */
662   if(InitialPort)
663       PortAddress = RtlConvertUlongToLargeInteger(InitialPort);
664   else
665       PortAddress = Adapter->BaseIoAddress;
666
667   NDIS_DbgPrint(MAX_TRACE, ("Translating address 0x%x 0x%x\n", PortAddress.u.HighPart, PortAddress.u.LowPart));
668
669   /* FIXME: hard-coded bus number */
670   if(!HalTranslateBusAddress(Adapter->BusType, 0, PortAddress, &AddressSpace, &TranslatedAddress))
671     {
672       NDIS_DbgPrint(MIN_TRACE, ("Unable to translate address\n"));
673       return NDIS_STATUS_RESOURCES;
674     }
675
676   NDIS_DbgPrint(MAX_TRACE, ("Hal returned AddressSpace=0x%x TranslatedAddress=0x%x 0x%x\n",
677                             AddressSpace, TranslatedAddress.u.HighPart, TranslatedAddress.u.LowPart));
678
679   if(AddressSpace)
680     {
681       ASSERT(TranslatedAddress.u.HighPart == 0);
682       *PortOffset = (PVOID) TranslatedAddress.u.LowPart;
683       NDIS_DbgPrint(MAX_TRACE, ("Returning 0x%x\n", *PortOffset));
684       return NDIS_STATUS_SUCCESS;
685     }
686
687   NDIS_DbgPrint(MAX_TRACE, ("calling MmMapIoSpace\n"));
688
689   *PortOffset = 0;
690   *PortOffset = MmMapIoSpace(TranslatedAddress, NumberOfPorts, 0);
691   NDIS_DbgPrint(MAX_TRACE, ("Returning 0x%x for port range\n", *PortOffset));
692
693   if(!*PortOffset)
694     return NDIS_STATUS_RESOURCES;
695
696   return NDIS_STATUS_SUCCESS;
697 }
698
699 /*
700  * @unimplemented
701  */
702 VOID
703 EXPORT
704 NdisMSetupDmaTransfer(
705     OUT PNDIS_STATUS    Status,
706     IN  PNDIS_HANDLE    MiniportDmaHandle,
707     IN  PNDIS_BUFFER    Buffer,
708     IN  ULONG           Offset,
709     IN  ULONG           Length,
710     IN  BOOLEAN         WriteToDevice)
711 {
712     UNIMPLEMENTED
713 }
714
715
716 /*
717  * @unimplemented
718  */
719 VOID
720 EXPORT
721 NdisMUnmapIoSpace(
722     IN  NDIS_HANDLE MiniportAdapterHandle,
723     IN  PVOID       VirtualAddress,
724     IN  UINT        Length)
725 {
726     UNIMPLEMENTED
727 }
728
729 /* EOF */