Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenirq.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: ntoskrnl/io/irq.c 00005 * PURPOSE: I/O Wrappers (called Completion Ports) for Kernel Queues 00006 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 00007 */ 00008 00009 /* INCLUDES *****************************************************************/ 00010 00011 #include <ntoskrnl.h> 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 /* FUNCTIONS *****************************************************************/ 00016 00017 /* 00018 * @implemented 00019 */ 00020 NTSTATUS 00021 NTAPI 00022 IoConnectInterrupt(OUT PKINTERRUPT *InterruptObject, 00023 IN PKSERVICE_ROUTINE ServiceRoutine, 00024 IN PVOID ServiceContext, 00025 IN PKSPIN_LOCK SpinLock, 00026 IN ULONG Vector, 00027 IN KIRQL Irql, 00028 IN KIRQL SynchronizeIrql, 00029 IN KINTERRUPT_MODE InterruptMode, 00030 IN BOOLEAN ShareVector, 00031 IN KAFFINITY ProcessorEnableMask, 00032 IN BOOLEAN FloatingSave) 00033 { 00034 PKINTERRUPT Interrupt; 00035 PKINTERRUPT InterruptUsed; 00036 PIO_INTERRUPT IoInterrupt; 00037 PKSPIN_LOCK SpinLockUsed; 00038 BOOLEAN FirstRun; 00039 CCHAR Count = 0; 00040 KAFFINITY Affinity; 00041 PAGED_CODE(); 00042 00043 /* Assume failure */ 00044 *InterruptObject = NULL; 00045 00046 /* Get the affinity */ 00047 Affinity = ProcessorEnableMask & KeActiveProcessors; 00048 while (Affinity) 00049 { 00050 /* Increase count */ 00051 if (Affinity & 1) Count++; 00052 Affinity >>= 1; 00053 } 00054 00055 /* Make sure we have a valid CPU count */ 00056 if (!Count) return STATUS_INVALID_PARAMETER; 00057 00058 /* Allocate the array of I/O Interrupts */ 00059 IoInterrupt = ExAllocatePoolWithTag(NonPagedPool, 00060 (Count - 1) * sizeof(KINTERRUPT) + 00061 sizeof(IO_INTERRUPT), 00062 TAG_KINTERRUPT); 00063 if (!IoInterrupt) return STATUS_INSUFFICIENT_RESOURCES; 00064 00065 /* Select which Spinlock to use */ 00066 SpinLockUsed = SpinLock ? SpinLock : &IoInterrupt->SpinLock; 00067 00068 /* We first start with a built-in Interrupt inside the I/O Structure */ 00069 *InterruptObject = &IoInterrupt->FirstInterrupt; 00070 Interrupt = (PKINTERRUPT)(IoInterrupt + 1); 00071 FirstRun = TRUE; 00072 00073 /* Start with a fresh structure */ 00074 RtlZeroMemory(IoInterrupt, sizeof(IO_INTERRUPT)); 00075 00076 /* Now create all the interrupts */ 00077 Affinity = ProcessorEnableMask & KeActiveProcessors; 00078 for (Count = 0; Affinity; Count++, Affinity >>= 1) 00079 { 00080 /* Check if it's enabled for this CPU */ 00081 if (Affinity & 1) 00082 { 00083 /* Check which one we will use */ 00084 InterruptUsed = FirstRun ? &IoInterrupt->FirstInterrupt : Interrupt; 00085 00086 /* Initialize it */ 00087 KeInitializeInterrupt(InterruptUsed, 00088 ServiceRoutine, 00089 ServiceContext, 00090 SpinLockUsed, 00091 Vector, 00092 Irql, 00093 SynchronizeIrql, 00094 InterruptMode, 00095 ShareVector, 00096 Count, 00097 FloatingSave); 00098 00099 /* Connect it */ 00100 if (!KeConnectInterrupt(InterruptUsed)) 00101 { 00102 /* Check how far we got */ 00103 if (FirstRun) 00104 { 00105 /* We failed early so just free this */ 00106 ExFreePool(IoInterrupt); 00107 } 00108 else 00109 { 00110 /* Far enough, so disconnect everything */ 00111 IoDisconnectInterrupt(&IoInterrupt->FirstInterrupt); 00112 } 00113 00114 /* And fail */ 00115 return STATUS_INVALID_PARAMETER; 00116 } 00117 00118 /* Now we've used up our First Run */ 00119 if (FirstRun) 00120 { 00121 FirstRun = FALSE; 00122 } 00123 else 00124 { 00125 /* Move on to the next one */ 00126 IoInterrupt->Interrupt[(UCHAR)Count] = Interrupt++; 00127 } 00128 } 00129 } 00130 00131 /* Return Success */ 00132 return STATUS_SUCCESS; 00133 } 00134 00135 /* 00136 * @implemented 00137 */ 00138 VOID 00139 NTAPI 00140 IoDisconnectInterrupt(PKINTERRUPT InterruptObject) 00141 { 00142 LONG i; 00143 PIO_INTERRUPT IoInterrupt; 00144 PAGED_CODE(); 00145 00146 /* Get the I/O Interrupt */ 00147 IoInterrupt = CONTAINING_RECORD(InterruptObject, 00148 IO_INTERRUPT, 00149 FirstInterrupt); 00150 00151 /* Disconnect the first one */ 00152 KeDisconnectInterrupt(&IoInterrupt->FirstInterrupt); 00153 00154 /* Now disconnect the others */ 00155 for (i = 0; i < KeNumberProcessors; i++) 00156 { 00157 /* Make sure one was registered */ 00158 if (IoInterrupt->Interrupt[i]) 00159 { 00160 /* Disconnect it */ 00161 KeDisconnectInterrupt(&InterruptObject[i]); 00162 } 00163 } 00164 00165 /* Free the I/O Interrupt */ 00166 ExFreePool(IoInterrupt); 00167 } 00168 00169 /* EOF */ Generated on Sat May 26 2012 04:26:35 for ReactOS by
1.7.6.1
|