1 | /* $Id: irq.hpp 205 2007-06-14 01:33:51Z stevenhl $ */
|
---|
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 | // clude <stddef.h> //### NULL? to be removed
|
---|
50 |
|
---|
51 | // ###IHV: IRQ sharing flag. Set this to "0" for ISA bus, "1" for PCI
|
---|
52 | // PCI and Microchannel environments (where hardware can share an IRQ level.
|
---|
53 | const IRQ_HW_Sharing = 1; // 13 Jun 07 MF
|
---|
54 |
|
---|
55 | // Max num of int handlers per IRQ level.
|
---|
56 | const MAX_HandlersPerIRQLevel = 3;
|
---|
57 |
|
---|
58 | // PFN_InterruptHandler: Pointer to an interrupt handler. This is a near
|
---|
59 | // function which returns TRUE if it handled the interrupt, FALSE otherwise.
|
---|
60 | typedef BOOL __far __loadds __saveregs (*PFN_InterruptHandler) ( int irqnr );
|
---|
61 |
|
---|
62 | class ISR_Entry {
|
---|
63 | public:
|
---|
64 | BOOL bEnabled; // true <=> this handler is enabled.
|
---|
65 | PFN_InterruptHandler pfnHandler; // Handler within this driver.
|
---|
66 | };
|
---|
67 |
|
---|
68 |
|
---|
69 | class IRQ {
|
---|
70 |
|
---|
71 | // Use this globally scoped function to create an IRQ object
|
---|
72 | // rather than calling a constructor. This function ensures that
|
---|
73 | // no more than one IRQ object is constructed per level.
|
---|
74 | friend IRQ* pMakeIRQ( unsigned irq_level );
|
---|
75 | friend IRQ* getIRQ( unsigned irq_level );
|
---|
76 |
|
---|
77 | public:
|
---|
78 |
|
---|
79 | // Add an interrupt handler to the list.
|
---|
80 | BOOL bAddHandler ( PFN_InterruptHandler pfn );
|
---|
81 |
|
---|
82 | // Enable the named handler.
|
---|
83 | BOOL bEnableHandler ( PFN_InterruptHandler pfn );
|
---|
84 |
|
---|
85 | // Disables the named handler.
|
---|
86 | BOOL bDisableHandler ( PFN_InterruptHandler pfn );
|
---|
87 |
|
---|
88 | // Removes the interrupt handler from the list.
|
---|
89 | BOOL bRemoveHandler ( PFN_InterruptHandler pfn );
|
---|
90 |
|
---|
91 | // Receives interrupt from kernel, then calls out to registered handlers.
|
---|
92 | // Runs in interrupt context.
|
---|
93 | void CallHandlers (void);
|
---|
94 |
|
---|
95 | private:
|
---|
96 | // Data:
|
---|
97 |
|
---|
98 | ISR_Entry _handlerList[ MAX_HandlersPerIRQLevel + 1 ];
|
---|
99 | // List of handlers associated with this interrupt.
|
---|
100 | // Used slots are always contiguous starting from
|
---|
101 | // slot 0. Null PFN entry inidicates free slot and end
|
---|
102 | // of list. The last slot in the array is an extra slot,
|
---|
103 | // guaranteed to be NULL.
|
---|
104 | USHORT _nEnabled; // Number of handlers currently enabled.
|
---|
105 | USHORT _usIRQLevel; // The IRQ level itself
|
---|
106 |
|
---|
107 | // Methods:
|
---|
108 |
|
---|
109 | // Constructor. Note that this is private; a client should use the
|
---|
110 | // pMakeIRQ() friend function to obtain a pointer to an IRQ object.
|
---|
111 | IRQ ( unsigned irq_level );
|
---|
112 |
|
---|
113 | // Destructor.
|
---|
114 | ~IRQ ( void );
|
---|
115 |
|
---|
116 | // Find named handler in _handlerList[].
|
---|
117 | ISR_Entry* _pFindHandler( PFN_InterruptHandler pfn );
|
---|
118 |
|
---|
119 |
|
---|
120 | };
|
---|
121 |
|
---|
122 | /* Note: do not call AddHandler, RemoveHandler, in an interrupt thread.
|
---|
123 | do not create or delete an IRQ object (or any object) in an interrupt thread
|
---|
124 | */
|
---|
125 |
|
---|
126 | #endif
|
---|