2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NDIS library
5 * PURPOSE: I/O related routines
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * CSH 01/08-2000 Created
14 VOID
HandleDeferredProcessing(
16 IN PVOID DeferredContext
,
17 IN PVOID SystemArgument1
,
18 IN PVOID SystemArgument2
)
20 * FUNCTION: Deferred interrupt processing routine
22 * Dpc = Pointer to DPC object
23 * DeferredContext = Pointer to context information (LOGICAL_ADAPTER)
24 * SystemArgument1 = Unused
25 * SystemArgument2 = Unused
29 PLOGICAL_ADAPTER Adapter
= GET_LOGICAL_ADAPTER(DeferredContext
);
31 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
33 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
34 WasBusy
= Adapter
->MiniportBusy
;
35 Adapter
->MiniportBusy
= TRUE
;
36 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
38 /* Call the deferred interrupt service handler for this adapter */
39 (*Adapter
->Miniport
->Chars
.HandleInterruptHandler
)(
40 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
);
42 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
43 if ((!WasBusy
) && (Adapter
->WorkQueueHead
)) {
44 KeInsertQueueDpc(&Adapter
->MiniportDpc
, NULL
, NULL
);
46 Adapter
->MiniportBusy
= WasBusy
;
48 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
50 NDIS_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
54 BOOLEAN
ServiceRoutine(
55 IN PKINTERRUPT Interrupt
,
56 IN PVOID ServiceContext
)
58 * FUNCTION: Interrupt service routine
60 * Interrupt = Pointer to interrupt object
61 * ServiceContext = Pointer to context information (LOGICAL_ADAPTER)
63 * TRUE if a miniport controlled device generated the interrupt
66 BOOLEAN InterruptRecognized
;
67 BOOLEAN QueueMiniportHandleInterrupt
;
68 PLOGICAL_ADAPTER Adapter
= GET_LOGICAL_ADAPTER(ServiceContext
);
70 NDIS_DbgPrint(MAX_TRACE
, ("Called. Adapter (0x%X)\n", Adapter
));
72 (*Adapter
->Miniport
->Chars
.ISRHandler
)(&InterruptRecognized
,
73 &QueueMiniportHandleInterrupt
,
74 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
);
76 if (QueueMiniportHandleInterrupt
) {
77 NDIS_DbgPrint(MAX_TRACE
, ("Queueing DPC.\n"));
78 KeInsertQueueDpc(&Adapter
->NdisMiniportBlock
.Interrupt
->InterruptDpc
, NULL
, NULL
);
81 NDIS_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
83 return InterruptRecognized
;
89 NdisCompleteDmaTransfer(
90 OUT PNDIS_STATUS Status
,
91 IN PNDIS_HANDLE NdisDmaHandle
,
92 IN PNDIS_BUFFER Buffer
,
95 IN BOOLEAN WriteToDevice
)
104 IN PNDIS_BUFFER Buffer
,
105 IN BOOLEAN WriteToDevice
)
113 NdisGetCacheFillSize(
124 NdisImmediateReadPortUchar(
125 IN NDIS_HANDLE WrapperConfigurationContext
,
135 NdisImmediateReadPortUlong(
136 IN NDIS_HANDLE WrapperConfigurationContext
,
146 NdisImmediateReadPortUshort(
147 IN NDIS_HANDLE WrapperConfigurationContext
,
157 NdisImmediateWritePortUchar(
158 IN NDIS_HANDLE WrapperConfigurationContext
,
168 NdisImmediateWritePortUlong(
169 IN NDIS_HANDLE WrapperConfigurationContext
,
179 NdisImmediateWritePortUshort(
180 IN NDIS_HANDLE WrapperConfigurationContext
,
190 NdisMAllocateMapRegisters(
191 IN NDIS_HANDLE MiniportAdapterHandle
,
193 IN BOOLEAN Dma32BitAddresses
,
194 IN ULONG PhysicalMapRegistersNeeded
,
195 IN ULONG MaximumPhysicalMapping
)
199 return NDIS_STATUS_FAILURE
;
205 NdisMCompleteDmaTransfer(
206 OUT PNDIS_STATUS Status
,
207 IN PNDIS_HANDLE MiniportDmaHandle
,
208 IN PNDIS_BUFFER Buffer
,
211 IN BOOLEAN WriteToDevice
)
219 NdisMDeregisterDmaChannel(
220 IN PNDIS_HANDLE MiniportDmaHandle
)
228 NdisMDeregisterInterrupt(
229 IN PNDIS_MINIPORT_INTERRUPT Interrupt
)
231 * FUNCTION: Releases an interrupt vector
233 * Interrupt = Pointer to interrupt object
236 IoDisconnectInterrupt(Interrupt
->InterruptObject
);
242 NdisMDeregisterIoPortRange(
243 IN NDIS_HANDLE MiniportAdapterHandle
,
245 IN UINT NumberOfPorts
,
248 * FUNCTION: Releases a register mapping to I/O ports
250 * MiniportAdapterHandle = Specifies handle input to MiniportInitialize
251 * InitialPort = Bus-relative base port address of a range to be mapped
252 * NumberOfPorts = Specifies number of ports to be mapped
253 * PortOffset = Pointer to mapped base port address
256 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
264 NdisMFreeMapRegisters(
265 IN NDIS_HANDLE MiniportAdapterHandle
)
274 OUT PVOID
*VirtualAddress
,
275 IN NDIS_HANDLE MiniportAdapterHandle
,
276 IN NDIS_PHYSICAL_ADDRESS PhysicalAddress
,
281 return NDIS_STATUS_FAILURE
;
288 IN NDIS_HANDLE MiniportDmaHandle
)
298 NdisMRegisterDmaChannel(
299 OUT PNDIS_HANDLE MiniportDmaHandle
,
300 IN NDIS_HANDLE MiniportAdapterHandle
,
302 IN BOOLEAN Dma32BitAddresses
,
303 IN PNDIS_DMA_DESCRIPTION DmaDescription
,
304 IN ULONG MaximumLength
)
308 return NDIS_STATUS_FAILURE
;
314 NdisMRegisterInterrupt(
315 OUT PNDIS_MINIPORT_INTERRUPT Interrupt
,
316 IN NDIS_HANDLE MiniportAdapterHandle
,
317 IN UINT InterruptVector
,
318 IN UINT InterruptLevel
,
319 IN BOOLEAN RequestIsr
,
320 IN BOOLEAN SharedInterrupt
,
321 IN NDIS_INTERRUPT_MODE InterruptMode
)
323 * FUNCTION: Claims access to an interrupt vector
325 * Interrupt = Address of interrupt object to initialize
326 * MiniportAdapterHandle = Specifies handle input to MiniportInitialize
327 * InterruptVector = Specifies bus-relative vector to register
328 * InterruptLevel = Specifies bus-relative DIRQL vector for interrupt
329 * RequestIsr = TRUE if MiniportISR should always be called
330 * SharedInterrupt = TRUE if other devices may use the same interrupt
331 * InterruptMode = Specifies type of interrupt
333 * Status of operation
340 PLOGICAL_ADAPTER Adapter
= GET_LOGICAL_ADAPTER(MiniportAdapterHandle
);
342 NDIS_DbgPrint(MAX_TRACE
, ("Called. InterruptVector (0x%X) InterruptLevel (0x%X) "
343 "SharedInterrupt (%d) InterruptMode (0x%X)\n",
344 InterruptVector
, InterruptLevel
, SharedInterrupt
, InterruptMode
));
346 RtlZeroMemory(Interrupt
, sizeof(NDIS_MINIPORT_INTERRUPT
));
348 KeInitializeSpinLock(&Interrupt
->DpcCountLock
);
350 KeInitializeDpc(&Interrupt
->InterruptDpc
,
351 HandleDeferredProcessing
,
354 KeInitializeEvent(&Interrupt
->DpcsCompletedEvent
,
358 Interrupt
->SharedInterrupt
= SharedInterrupt
;
360 Adapter
->NdisMiniportBlock
.Interrupt
= Interrupt
;
362 MappedIRQ
= HalGetInterruptVector(Internal
, /* Adapter->AdapterType, */
369 NDIS_DbgPrint(MAX_TRACE
, ("Connecting to interrupt vector (0x%X) Affinity (0x%X).\n", MappedIRQ
, Affinity
));
371 Status
= IoConnectInterrupt(&Interrupt
->InterruptObject
,
374 &Interrupt
->DpcCountLock
,
383 NDIS_DbgPrint(MAX_TRACE
, ("Leaving. Status (0x%X).\n", Status
));
385 if (NT_SUCCESS(Status
))
386 return NDIS_STATUS_SUCCESS
;
388 if (Status
== STATUS_INSUFFICIENT_RESOURCES
) {
389 /* FIXME: Log error */
390 return NDIS_STATUS_RESOURCE_CONFLICT
;
393 return NDIS_STATUS_FAILURE
;
399 NdisMRegisterIoPortRange(
400 OUT PVOID
*PortOffset
,
401 IN NDIS_HANDLE MiniportAdapterHandle
,
403 IN UINT NumberOfPorts
)
405 * FUNCTION: Sets up driver access to device I/O ports
407 * PortOffset = Address of buffer to place mapped base port address
408 * MiniportAdapterHandle = Specifies handle input to MiniportInitialize
409 * InitialPort = Bus-relative base port address of a range to be mapped
410 * NumberOfPorts = Specifies number of ports to be mapped
412 * Status of operation
417 BOOLEAN ConflictDetected
;
418 PLOGICAL_ADAPTER Adapter
= GET_LOGICAL_ADAPTER(MiniportAdapterHandle
);
419 PMINIPORT_DRIVER Miniport
= Adapter
->Miniport
;
421 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
423 /* Non-PnP hardware. NT5 function */
424 Status
= IoReportResourceForDetection(Miniport
->DriverObject
,
431 return NDIS_STATUS_FAILURE
;
433 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
436 *PortOffset
= (PVOID
)InitialPort
;
438 return NDIS_STATUS_SUCCESS
;
445 NdisMSetupDmaTransfer(
446 OUT PNDIS_STATUS Status
,
447 IN PNDIS_HANDLE MiniportDmaHandle
,
448 IN PNDIS_BUFFER Buffer
,
451 IN BOOLEAN WriteToDevice
)
460 IN NDIS_HANDLE MiniportAdapterHandle
,
461 IN PVOID VirtualAddress
,