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

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

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