Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeninterrupt.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/ke/i386/irq.c 00005 * PURPOSE: Manages the Kernel's IRQ support for external drivers, 00006 * for the purpopses of connecting, disconnecting and setting 00007 * up ISRs for drivers. The backend behind the Io* Interrupt 00008 * routines. 00009 * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org) 00010 * Alex Ionescu (alex.ionescu@reactos.org) 00011 */ 00012 00013 /* INCLUDES *****************************************************************/ 00014 00015 #include <ntoskrnl.h> 00016 #define NDEBUG 00017 #include <debug.h> 00018 00019 extern UCHAR KiInterruptDispatchTemplate[16]; 00020 extern UCHAR KiUnexpectedRange[]; 00021 extern UCHAR KiUnexpectedRangeEnd[]; 00022 void KiInterruptDispatch(void); 00023 00024 00025 /* FUNCTIONS ****************************************************************/ 00026 00027 VOID 00028 NTAPI 00029 KeInitializeInterrupt( 00030 IN PKINTERRUPT Interrupt, 00031 IN PKSERVICE_ROUTINE ServiceRoutine, 00032 IN PVOID ServiceContext, 00033 IN PKSPIN_LOCK SpinLock, 00034 IN ULONG Vector, 00035 IN KIRQL Irql, 00036 IN KIRQL SynchronizeIrql, 00037 IN KINTERRUPT_MODE InterruptMode, 00038 IN BOOLEAN ShareVector, 00039 IN CHAR ProcessorNumber, 00040 IN BOOLEAN FloatingSave) 00041 { 00042 00043 /* Initialize the header */ 00044 Interrupt->Type = InterruptObject; 00045 Interrupt->Size = sizeof(KINTERRUPT); 00046 00047 /* If no Spinlock is given, use the internal */ 00048 if (!SpinLock) SpinLock = &Interrupt->SpinLock; 00049 KeInitializeSpinLock(&Interrupt->SpinLock); 00050 00051 /* Set the given parameters */ 00052 Interrupt->ServiceRoutine = ServiceRoutine; 00053 Interrupt->ServiceContext = ServiceContext; 00054 Interrupt->ActualLock = SpinLock; 00055 Interrupt->Vector = Vector; 00056 Interrupt->Irql = Irql; 00057 Interrupt->SynchronizeIrql = SynchronizeIrql; 00058 Interrupt->Mode = InterruptMode; 00059 Interrupt->ShareVector = ShareVector; 00060 Interrupt->Number = ProcessorNumber; 00061 Interrupt->FloatingSave = FloatingSave; 00062 00063 /* Set initial values */ 00064 Interrupt->TickCount = 0; 00065 Interrupt->Connected = FALSE; 00066 Interrupt->ServiceCount = 0; 00067 Interrupt->DispatchCount = 0; 00068 Interrupt->TrapFrame = NULL; 00069 Interrupt->Reserved = 0; 00070 00071 /* Copy the dispatch code (its location independent, no need to patch it) */ 00072 RtlCopyMemory(Interrupt->DispatchCode, 00073 KiInterruptDispatchTemplate, 00074 sizeof(Interrupt->DispatchCode)); 00075 00076 Interrupt->DispatchAddress = 0; 00077 } 00078 00079 BOOLEAN 00080 NTAPI 00081 KeConnectInterrupt(IN PKINTERRUPT Interrupt) 00082 { 00083 PVOID CurrentHandler; 00084 00085 ASSERT(Interrupt->Vector <= MAXIMUM_IDTVECTOR); 00086 ASSERT(Interrupt->Number < KeNumberProcessors); 00087 ASSERT(Interrupt->Irql <= HIGH_LEVEL); 00088 00089 /* Check if its already connected */ 00090 if (Interrupt->Connected) return TRUE; 00091 00092 /* Query the current handler */ 00093 CurrentHandler = KeQueryInterruptHandler(Interrupt->Vector); 00094 00095 /* Check if the vector is already unused */ 00096 if ((CurrentHandler >= (PVOID)KiUnexpectedRange) && 00097 (CurrentHandler <= (PVOID)KiUnexpectedRangeEnd)) 00098 { 00099 /* Initialize the list for chained interrupts */ 00100 InitializeListHead(&Interrupt->InterruptListEntry); 00101 00102 /* Set normal dispatch address */ 00103 Interrupt->DispatchAddress = KiInterruptDispatch; 00104 00105 /* Set the new handler */ 00106 KeRegisterInterruptHandler(Interrupt->Vector, 00107 Interrupt->DispatchCode); 00108 00109 if (!HalEnableSystemInterrupt(Interrupt->Vector, 00110 Interrupt->Irql, 00111 Interrupt->Mode)) 00112 { 00113 /* Didn't work, restore old handler */ 00114 DPRINT1("HalEnableSystemInterrupt failed\n"); 00115 KeRegisterInterruptHandler(Interrupt->Vector, CurrentHandler); 00116 return FALSE; 00117 } 00118 00119 /* Mark as connected */ 00120 Interrupt->Connected = TRUE; 00121 } 00122 else 00123 { 00124 // later 00125 __debugbreak(); 00126 } 00127 00128 return TRUE; 00129 } 00130 00131 BOOLEAN 00132 NTAPI 00133 KeDisconnectInterrupt(IN PKINTERRUPT Interrupt) 00134 { 00135 UNIMPLEMENTED; 00136 __debugbreak(); 00137 return FALSE; 00138 } 00139 00140 BOOLEAN 00141 NTAPI 00142 KeSynchronizeExecution(IN OUT PKINTERRUPT Interrupt, 00143 IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, 00144 IN PVOID SynchronizeContext OPTIONAL) 00145 { 00146 BOOLEAN Success; 00147 KIRQL OldIrql; 00148 00149 /* Raise IRQL */ 00150 OldIrql = KfRaiseIrql(Interrupt->SynchronizeIrql); 00151 00152 /* Acquire interrupt spinlock */ 00153 KeAcquireSpinLockAtDpcLevel(Interrupt->ActualLock); 00154 00155 /* Call the routine */ 00156 Success = SynchronizeRoutine(SynchronizeContext); 00157 00158 /* Release lock */ 00159 KeReleaseSpinLockFromDpcLevel(Interrupt->ActualLock); 00160 00161 /* Lower IRQL */ 00162 KeLowerIrql(OldIrql); 00163 00164 /* Return status */ 00165 return Success; 00166 } Generated on Sun May 27 2012 04:27:59 for ReactOS by
1.7.6.1
|