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 STDCALL 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 STDCALL 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,