1 | /* $Id: irq.hpp 561 2011-07-28 09:16:56Z rudi $ */
|
---|
2 |
|
---|
3 | /* SCCSID = %W% %E% */
|
---|
4 | /****************************************************************************
|
---|
5 | * *
|
---|
6 | * Copyright (c) IBM Corporation 1994 - 1997. *
|
---|
7 | * *
|
---|
8 | * The following IBM OS/2 source code is provided to you solely for the *
|
---|
9 | * the purpose of assisting you in your development of OS/2 device drivers. *
|
---|
10 | * You may use this code in accordance with the IBM License Agreement *
|
---|
11 | * provided in the IBM Device Driver Source Kit for OS/2. *
|
---|
12 | * *
|
---|
13 | ****************************************************************************/
|
---|
14 | /**@internal %W%
|
---|
15 | * IRQ object definition.
|
---|
16 | * @version %I%
|
---|
17 | * @context
|
---|
18 | * Unless otherwise noted, all interfaces are Ring-0, 16-bit, kernel stack.
|
---|
19 | *
|
---|
20 | * @notes The IRQ object permits multiple interrupt handlers, all located
|
---|
21 | * within this driver, to share an interrupt level. The IRQ object also
|
---|
22 | * handles the bookkeeping and handshaking associated with the kernel and
|
---|
23 | * with the PIC. EOI is not issued to the PIC until a handler is found
|
---|
24 | * which services the interrupt. If no handler indicates that the hardware
|
---|
25 | * interrupt has been serviced, then no EOI is issued and the return code
|
---|
26 | * back to the kernel indicates that the interrupt has not been serviced.
|
---|
27 | *
|
---|
28 | * @notes No public constructor is provided for this object. Use the
|
---|
29 | * pMakeIRQ( irq_level ) friend function to obtain a pointer to the IRQ object
|
---|
30 | * of interest.
|
---|
31 | *
|
---|
32 | * @notes A client of this object should register its interrupt service
|
---|
33 | * routine by the AddHandler() method, and then enable the handler via
|
---|
34 | * EnableHandler. The service routine must conform to the definition of a
|
---|
35 | * PFN_InterruptHandler, returning True if the interrupt was handled and
|
---|
36 | * False otherwise. Reference PFN_InterruptHandler definition below.
|
---|
37 | *
|
---|
38 | * @history
|
---|
39 | */
|
---|
40 |
|
---|
41 | #ifndef IRQ_INCLUDED
|
---|
42 | #define IRQ_INCLUDED
|
---|
43 |
|
---|
44 | #ifndef OS2_INCLUDED
|
---|
45 | #define INCL_NOPMAPI
|
---|
46 | #include <os2.h>
|
---|
47 | #endif
|
---|
48 |
|
---|
49 | // Max num of int handlers per IRQ level.
|
---|
50 | const int MAX_HandlersPerIRQLevel = 3;
|
---|
51 |
|
---|
52 | // PFN_InterruptHandler: Pointer to an interrupt handler. This is a near
|
---|
53 | // function which returns TRUE if it handled the interrupt, FALSE otherwise.
|
---|
54 | typedef BOOL __far __loadds __saveregs (*PFN_InterruptHandler) ( int irqnr );
|
---|
55 |
|
---|
56 | class ISR_Entry {
|
---|
57 | public:
|
---|
58 | BOOL bEnabled; // true <=> this handler is enabled.
|
---|
59 | PFN_InterruptHandler pfnHandler; // Handler within this driver.
|
---|
60 | };
|
---|
61 |
|
---|
62 |
|
---|
63 | class IRQ {
|
---|
64 |
|
---|
65 | // Use this globally scoped function to create an IRQ object
|
---|
66 | // rather than calling a constructor. This function ensures that
|
---|
67 | // no more than one IRQ object is constructed per level.
|
---|
68 | friend IRQ* pMakeIRQ( unsigned irq_level );
|
---|
69 | friend IRQ* getIRQ( unsigned irq_level );
|
---|
70 |
|
---|
71 | public:
|
---|
72 |
|
---|
73 | // Add an interrupt handler to the list.
|
---|
74 | BOOL bAddHandler ( PFN_InterruptHandler pfn );
|
---|
75 |
|
---|
76 | // Enable the named handler.
|
---|
77 | BOOL bEnableHandler ( PFN_InterruptHandler pfn );
|
---|
78 |
|
---|
79 | // Disables the named handler.
|
---|
80 | BOOL bDisableHandler ( PFN_InterruptHandler pfn );
|
---|
81 |
|
---|
82 | // Removes the interrupt handler from the list.
|
---|
83 | BOOL bRemoveHandler ( PFN_InterruptHandler pfn );
|
---|
84 |
|
---|
85 | // Receives interrupt from kernel, then calls out to registered handlers.
|
---|
86 | // Runs in interrupt context.
|
---|
87 | void CallHandlers (void);
|
---|
88 |
|
---|
89 | private:
|
---|
90 | // Data:
|
---|
91 |
|
---|
92 | ISR_Entry _handlerList[ MAX_HandlersPerIRQLevel + 1 ];
|
---|
93 | // List of handlers associated with this interrupt.
|
---|
94 | // Used slots are always contiguous starting from
|
---|
95 | // slot 0. Null PFN entry inidicates free slot and end
|
---|
96 | // of list. The last slot in the array is an extra slot,
|
---|
97 | // guaranteed to be NULL.
|
---|
98 | USHORT _nEnabled; // Number of handlers currently enabled.
|
---|
99 | USHORT _usIRQLevel; // The IRQ level itself
|
---|
100 |
|
---|
101 | // Methods:
|
---|
102 |
|
---|
103 | // Constructor. Note that this is private; a client should use the
|
---|
104 | // pMakeIRQ() friend function to obtain a pointer to an IRQ object.
|
---|
105 | IRQ ( unsigned irq_level );
|
---|
106 |
|
---|
107 | // Destructor.
|
---|
108 | ~IRQ ( void );
|
---|
109 |
|
---|
110 | // Find named handler in _handlerList[].
|
---|
111 | ISR_Entry* _pFindHandler( PFN_InterruptHandler pfn );
|
---|
112 |
|
---|
113 |
|
---|
114 | };
|
---|
115 |
|
---|
116 | /* Note: do not call AddHandler, RemoveHandler, in an interrupt thread.
|
---|
117 | do not create or delete an IRQ object (or any object) in an interrupt thread
|
---|
118 | */
|
---|
119 |
|
---|
120 | #endif
|
---|