2ee4f526861a86f2ab6db6bef9b7488be0e047e3
[reactos.git] / reactos / 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 * REVISIONS:
8 * CSH 01/08-2000 Created
9 */
10 #include <ndissys.h>
11 #include <miniport.h>
12
13
14 VOID STDCALL HandleDeferredProcessing(
15 IN PKDPC Dpc,
16 IN PVOID DeferredContext,
17 IN PVOID SystemArgument1,
18 IN PVOID SystemArgument2)
19 /*
20 * FUNCTION: Deferred interrupt processing routine
21 * ARGUMENTS:
22 * Dpc = Pointer to DPC object
23 * DeferredContext = Pointer to context information (LOGICAL_ADAPTER)
24 * SystemArgument1 = Unused
25 * SystemArgument2 = Unused
26 */
27 {
28 BOOLEAN WasBusy;
29 PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(DeferredContext);
30
31 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
32
33 KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock);
34 WasBusy = Adapter->MiniportBusy;
35 Adapter->MiniportBusy = TRUE;
36 KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock);
37
38 /* Call the deferred interrupt service handler for this adapter */
39 (*Adapter->Miniport->Chars.HandleInterruptHandler)(
40 Adapter->NdisMiniportBlock.MiniportAdapterContext);
41
42 KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock);
43 if ((!WasBusy) && (Adapter->WorkQueueHead)) {
44 KeInsertQueueDpc(&Adapter->MiniportDpc, NULL, NULL);
45 } else {
46 Adapter->MiniportBusy = WasBusy;
47 }
48 KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock);
49
50 NDIS_DbgPrint(MAX_TRACE, ("Leaving.\n"));
51 }
52
53
54 BOOLEAN STDCALL ServiceRoutine(
55 IN PKINTERRUPT Interrupt,
56 IN PVOID ServiceContext)
57 /*
58 * FUNCTION: Interrupt service routine
59 * ARGUMENTS:
60 * Interrupt = Pointer to interrupt object
61 * ServiceContext = Pointer to context information (LOGICAL_ADAPTER)
62 * RETURNS
63 * TRUE if a miniport controlled device generated the interrupt
64 */
65 {
66 BOOLEAN InterruptRecognized;
67 BOOLEAN QueueMiniportHandleInterrupt;
68 PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(ServiceContext);
69
70 NDIS_DbgPrint(MAX_TRACE, ("Called. Adapter (0x%X)\n", Adapter));
71
72 (*Adapter->Miniport->Chars.ISRHandler)(&InterruptRecognized,
73 &QueueMiniportHandleInterrupt,
74 Adapter->NdisMiniportBlock.MiniportAdapterContext);
75
76 if (QueueMiniportHandleInterrupt) {
77 NDIS_DbgPrint(MAX_TRACE, ("Queueing DPC.\n"));
78 KeInsertQueueDpc(&Adapter->NdisMiniportBlock.Interrupt->InterruptDpc, NULL, NULL);
79 }
80
81 NDIS_DbgPrint(MAX_TRACE, ("Leaving.\n"));
82
83 return InterruptRecognized;
84 }
85
86
87 /*
88 * @unimplemented
89 */
90 VOID
91 EXPORT
92 NdisCompleteDmaTransfer(
93 OUT PNDIS_STATUS Status,
94 IN PNDIS_HANDLE NdisDmaHandle,
95 IN PNDIS_BUFFER Buffer,
96 IN ULONG Offset,
97 IN ULONG Length,
98 IN BOOLEAN WriteToDevice)
99 {
100 UNIMPLEMENTED
101 }
102
103
104 /*
105 * @unimplemented
106 */
107 VOID
108 EXPORT
109 NdisFlushBuffer(
110 IN PNDIS_BUFFER Buffer,
111 IN BOOLEAN WriteToDevice)
112 {
113 UNIMPLEMENTED
114 }
115
116
117 /*
118 * @unimplemented
119 */
120 ULONG
121 EXPORT
122 NdisGetCacheFillSize(
123 VOID)
124 {
125 UNIMPLEMENTED
126
127 return 0;
128 }
129
130
131 /*
132 * @implemented
133 */
134 VOID
135 EXPORT
136 NdisImmediateReadPortUchar(
137 IN NDIS_HANDLE WrapperConfigurationContext,
138 IN ULONG Port,
139 OUT PUCHAR Data)
140 {
141 *Data = READ_PORT_UCHAR((PUCHAR)Port); // FIXME: What to do with WrapperConfigurationContext?
142 }
143
144
145 /*
146 * @implemented
147 */
148 VOID
149 EXPORT
150 NdisImmediateReadPortUlong(
151 IN NDIS_HANDLE WrapperConfigurationContext,
152 IN ULONG Port,
153 OUT PULONG Data)
154 {
155 *Data = READ_PORT_ULONG((PULONG)Port); // FIXME: What to do with WrapperConfigurationContext?
156 }
157
158
159 /*
160 * @implemented
161 */
162 VOID
163 EXPORT
164 NdisImmediateReadPortUshort(
165 IN NDIS_HANDLE WrapperConfigurationContext,
166 IN ULONG Port,
167 OUT PUSHORT Data)
168 {
169 *Data = READ_PORT_USHORT((PUSHORT)Port); // FIXME: What to do with WrapperConfigurationContext?
170 }
171
172
173 /*
174 * @implemented
175 */
176 VOID
177 EXPORT
178 NdisImmediateWritePortUchar(
179 IN NDIS_HANDLE WrapperConfigurationContext,
180 IN ULONG Port,
181 IN UCHAR Data)
182 {
183 WRITE_PORT_UCHAR((PUCHAR)Port, Data); // FIXME: What to do with WrapperConfigurationContext?
184 }
185
186
187 /*
188 * @implemented
189 */
190 VOID
191 EXPORT
192 NdisImmediateWritePortUlong(
193 IN NDIS_HANDLE WrapperConfigurationContext,
194 IN ULONG Port,
195 IN ULONG Data)
196 {
197 WRITE_PORT_ULONG((PULONG)Port, Data); // FIXME: What to do with WrapperConfigurationContext?
198 }
199
200
201 /*
202 * @unimplemented
203 */
204 VOID
205 EXPORT
206 NdisImmediateWritePortUshort(
207 IN NDIS_HANDLE WrapperConfigurationContext,
208 IN ULONG Port,
209 IN USHORT Data)
210 {
211 WRITE_PORT_USHORT((PUSHORT)Port, Data); // FIXME: What to do with WrapperConfigurationContext?
212 }
213
214
215 /*
216 * @unimplemented
217 */
218 NDIS_STATUS
219 EXPORT
220 NdisMAllocateMapRegisters(
221 IN NDIS_HANDLE MiniportAdapterHandle,
222 IN UINT DmaChannel,
223 IN BOOLEAN Dma32BitAddresses,
224 IN ULONG PhysicalMapRegistersNeeded,
225 IN ULONG MaximumPhysicalMapping)
226 {
227 UNIMPLEMENTED
228
229 return NDIS_STATUS_FAILURE;
230 }
231
232
233 /*
234 * @unimplemented
235 */
236 VOID
237 EXPORT
238 NdisMCompleteDmaTransfer(
239 OUT PNDIS_STATUS Status,
240 IN PNDIS_HANDLE MiniportDmaHandle,
241 IN PNDIS_BUFFER Buffer,
242 IN ULONG Offset,
243 IN ULONG Length,
244 IN BOOLEAN WriteToDevice)
245 {
246 UNIMPLEMENTED
247 }
248
249
250 /*
251 * @unimplemented
252 */
253 VOID
254 EXPORT
255 NdisMDeregisterDmaChannel(
256 IN PNDIS_HANDLE MiniportDmaHandle)
257 {
258 UNIMPLEMENTED
259 }
260
261
262 /*
263 * @implemented
264 */
265 VOID
266 EXPORT
267 NdisMDeregisterInterrupt(
268 IN PNDIS_MINIPORT_INTERRUPT Interrupt)
269 /*
270 * FUNCTION: Releases an interrupt vector
271 * ARGUMENTS:
272 * Interrupt = Pointer to interrupt object
273 */
274 {
275 IoDisconnectInterrupt(Interrupt->InterruptObject);
276 }
277
278
279 /*
280 * @unimplemented
281 */
282 VOID
283 EXPORT
284 NdisMDeregisterIoPortRange(
285 IN NDIS_HANDLE MiniportAdapterHandle,
286 IN UINT InitialPort,
287 IN UINT NumberOfPorts,
288 IN PVOID PortOffset)
289 /*
290 * FUNCTION: Releases a register mapping to I/O ports
291 * ARGUMENTS:
292 * MiniportAdapterHandle = Specifies handle input to MiniportInitialize
293 * InitialPort = Bus-relative base port address of a range to be mapped
294 * NumberOfPorts = Specifies number of ports to be mapped
295 * PortOffset = Pointer to mapped base port address
296 */
297 {
298 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
299
300 /* Thank you */
301 }
302
303
304 /*
305 * @unimplemented
306 */
307 VOID
308 EXPORT
309 NdisMFreeMapRegisters(
310 IN NDIS_HANDLE MiniportAdapterHandle)
311 {
312 UNIMPLEMENTED
313 }
314
315
316 /*
317 * @unimplemented
318 */
319 NDIS_STATUS
320 EXPORT
321 NdisMMapIoSpace(
322 OUT PVOID *VirtualAddress,
323 IN NDIS_HANDLE MiniportAdapterHandle,
324 IN NDIS_PHYSICAL_ADDRESS PhysicalAddress,
325 IN UINT Length)
326 {
327 UNIMPLEMENTED
328
329 return NDIS_STATUS_FAILURE;
330 }
331
332
333 /*
334 * @unimplemented
335 */
336 ULONG
337 EXPORT
338 NdisMReadDmaCounter(
339 IN NDIS_HANDLE MiniportDmaHandle)
340 {
341 UNIMPLEMENTED
342
343 return 0;
344 }
345
346
347 /*
348 * @unimplemented
349 */
350 NDIS_STATUS
351 EXPORT
352 NdisMRegisterDmaChannel(
353 OUT PNDIS_HANDLE MiniportDmaHandle,
354 IN NDIS_HANDLE MiniportAdapterHandle,
355 IN UINT DmaChannel,
356 IN BOOLEAN Dma32BitAddresses,
357 IN PNDIS_DMA_DESCRIPTION DmaDescription,
358 IN ULONG MaximumLength)
359 {
360 UNIMPLEMENTED
361
362 return NDIS_STATUS_FAILURE;
363 }
364
365
366 /*
367 * @implemented
368 */
369 NDIS_STATUS
370 EXPORT
371 NdisMRegisterInterrupt(
372 OUT PNDIS_MINIPORT_INTERRUPT Interrupt,
373 IN NDIS_HANDLE MiniportAdapterHandle,
374 IN UINT InterruptVector,
375 IN UINT InterruptLevel,
376 IN BOOLEAN RequestIsr,
377 IN BOOLEAN SharedInterrupt,
378 IN NDIS_INTERRUPT_MODE InterruptMode)
379 /*
380 * FUNCTION: Claims access to an interrupt vector
381 * ARGUMENTS:
382 * Interrupt = Address of interrupt object to initialize
383 * MiniportAdapterHandle = Specifies handle input to MiniportInitialize
384 * InterruptVector = Specifies bus-relative vector to register
385 * InterruptLevel = Specifies bus-relative DIRQL vector for interrupt
386 * RequestIsr = TRUE if MiniportISR should always be called
387 * SharedInterrupt = TRUE if other devices may use the same interrupt
388 * InterruptMode = Specifies type of interrupt
389 * RETURNS:
390 * Status of operation
391 */
392 {
393 NTSTATUS Status;
394 ULONG MappedIRQ;
395 KIRQL DIrql;
396 KAFFINITY Affinity;
397 PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(MiniportAdapterHandle);
398
399 NDIS_DbgPrint(MAX_TRACE, ("Called. InterruptVector (0x%X) InterruptLevel (0x%X) "
400 "SharedInterrupt (%d) InterruptMode (0x%X)\n",
401 InterruptVector, InterruptLevel, SharedInterrupt, InterruptMode));
402
403 RtlZeroMemory(Interrupt, sizeof(NDIS_MINIPORT_INTERRUPT));
404
405 KeInitializeSpinLock(&Interrupt->DpcCountLock);
406
407 KeInitializeDpc(&Interrupt->InterruptDpc,
408 HandleDeferredProcessing,
409 Adapter);
410
411 KeInitializeEvent(&Interrupt->DpcsCompletedEvent,
412 NotificationEvent,
413 FALSE);
414
415 Interrupt->SharedInterrupt = SharedInterrupt;
416
417 Adapter->NdisMiniportBlock.Interrupt = Interrupt;
418
419 MappedIRQ = HalGetInterruptVector(Internal, /* Adapter->AdapterType, */
420 0,
421 InterruptLevel,
422 InterruptVector,
423 &DIrql,
424 &Affinity);
425
426 NDIS_DbgPrint(MAX_TRACE, ("Connecting to interrupt vector (0x%X) Affinity (0x%X).\n", MappedIRQ, Affinity));
427
428 Status = IoConnectInterrupt(&Interrupt->InterruptObject,
429 ServiceRoutine,
430 Adapter,
431 &Interrupt->DpcCountLock,
432 MappedIRQ,
433 DIrql,
434 DIrql,
435 InterruptMode,
436 SharedInterrupt,
437 Affinity,
438 FALSE);
439
440 NDIS_DbgPrint(MAX_TRACE, ("Leaving. Status (0x%X).\n", Status));
441
442 if (NT_SUCCESS(Status))
443 return NDIS_STATUS_SUCCESS;
444
445 if (Status == STATUS_INSUFFICIENT_RESOURCES) {
446 /* FIXME: Log error */
447 return NDIS_STATUS_RESOURCE_CONFLICT;
448 }
449
450 return NDIS_STATUS_FAILURE;
451 }
452
453
454 /*
455 * @unimplemented
456 */
457 NDIS_STATUS
458 EXPORT
459 NdisMRegisterIoPortRange(
460 OUT PVOID *PortOffset,
461 IN NDIS_HANDLE MiniportAdapterHandle,
462 IN UINT InitialPort,
463 IN UINT NumberOfPorts)
464 /*
465 * FUNCTION: Sets up driver access to device I/O ports
466 * ARGUMENTS:
467 * PortOffset = Address of buffer to place mapped base port address
468 * MiniportAdapterHandle = Specifies handle input to MiniportInitialize
469 * InitialPort = Bus-relative base port address of a range to be mapped
470 * NumberOfPorts = Specifies number of ports to be mapped
471 * RETURNS:
472 * Status of operation
473 */
474 {
475 #if 0
476 NTSTATUS Status;
477 BOOLEAN ConflictDetected;
478 PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(MiniportAdapterHandle);
479 PMINIPORT_DRIVER Miniport = Adapter->Miniport;
480
481 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
482
483 /* Non-PnP hardware. NT5 function */
484 Status = IoReportResourceForDetection(Miniport->DriverObject,
485 NULL,
486 0,
487 NULL,
488 NULL,
489 0,
490 &ConflictDetected);
491 return NDIS_STATUS_FAILURE;
492 #else
493 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
494
495 /* It's yours! */
496 *PortOffset = (PVOID)InitialPort;
497
498 return NDIS_STATUS_SUCCESS;
499 #endif
500 }
501
502
503 /*
504 * @unimplemented
505 */
506 VOID
507 EXPORT
508 NdisMSetupDmaTransfer(
509 OUT PNDIS_STATUS Status,
510 IN PNDIS_HANDLE MiniportDmaHandle,
511 IN PNDIS_BUFFER Buffer,
512 IN ULONG Offset,
513 IN ULONG Length,
514 IN BOOLEAN WriteToDevice)
515 {
516 UNIMPLEMENTED
517 }
518
519
520 /*
521 * @unimplemented
522 */
523 VOID
524 EXPORT
525 NdisMUnmapIoSpace(
526 IN NDIS_HANDLE MiniportAdapterHandle,
527 IN PVOID VirtualAddress,
528 IN UINT Length)
529 {
530 UNIMPLEMENTED
531 }
532
533 /* EOF */