ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

interrupt.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.