|
|
1.1 root 1: #define _DDI_DKI 1
2: #define _SYSV4 1
3:
4: /*
5: * Code to manage the processor interrupt-priority level.
6: *
7: * This module exists to define external-linkage versions of the macros given
8: * in <sys/inline.h>, and to give a manual-page entry.
9: */
10:
11: /*
12: *-IMPORTS:
13: * <common/ccompat.h>
14: * __USE_PROTO__
15: * __ARGS ()
16: */
17:
18: #include <common/ccompat.h>
19: #include <sys/inline.h>
20:
21:
22: #if __COHERENT__
23: #error This file is not for the Coherent version of STREAMS
24: #endif
25:
26: /*
27: *-STATUS:
28: * DDI/DKI
29: *
30: *-NAME:
31: * spl... () Block/allow interrupts on a processor.
32: *
33: *-SYNOPSIS:
34: * #include <sys/inline.h>
35: *
36: * pl_t splbase ();
37: * pl_t spltimeout ();
38: * pl_t spldisk ();
39: * pl_t splstr ();
40: * pl_t splhi ();
41: * pl_t splx (pl_t oldlevel);
42: *
43: *-ARGUMENTS:
44: * oldlevel Last set priority value (only splx () has an input
45: * argument)
46: *
47: *-DESCRIPTION:
48: * The spl... () functions block or allow servicing of interrupts on the
49: * processor on which the function is called. Hardware devices are
50: * assigned to interrupt priority levels depending on the type of device.
51: * Each spl... () function which blocks interrupts is associated with
52: * with some machine-dependent interrupt priority level and will prevent
53: * interrupts occurring at or below this priority level from being
54: * serviced on the processor on which the spl... () function is called.
55: *
56: * On a multiprocessor system, interrupts may be serviced by more than
57: * one processor, and therefore use of an spl... () function alone is not
58: * sufficient to prevent interrupt code from executing and manipulating
59: * driver data structures during a critical section. Drivers that must
60: * prevent execution of interrupt-level code in order to protect the
61: * integrity of their should use basic locks or read/write locks for
62: * this purpose [see LOCK_ALLOC () or RW_ALLOC ()].
63: *
64: * Calling a given spl... () function will block interrupts specified for
65: * that function as well as all interrupts at equal an lower levels. The
66: * notion of low vs. high levels assumes a defined order of priority
67: * level. The following partial order is defined:
68: * splbase <= spltimeout <= spldisk, splstr <= splhi
69: *
70: * The ordering of spldisk () and splstr () relative to each other is not
71: * defined.
72: *
73: *-RETURN VALUE:
74: * All spl... () functions return the previous priority level.
75: *
76: *-LEVEL:
77: * Base or Interrupt.
78: *
79: *-NOTES:
80: * All spl... () functions do not sleep.
81: *
82: * Driver-defined basic locks and read/write locks may be held across
83: * calls to these functions, but the spl... () call must not cause the
84: * priority level to be lowered below the level associated with the
85: * lock.
86: *
87: * Driver-defined sleep locks may be held across calls to these
88: * functions.
89: *
90: * When setting a given priority level, the previous level returned
91: * should be saved and splx (), UNLOCK () or RW_UNLOCK () should be
92: * used as appropriate to restore this level.
93: *
94: * Interrupt-level code must never lower the interrupt priority level
95: * below the level at which the interrupt handler was entered. For
96: * example, is an interrupt handler is entered at the priority level
97: * associated with spldisk (), the handler must not call spltimeout ().
98: */
99:
100: #if __USE_PROTO__
101: pl_t (splbase) (void)
102: #else
103: pl_t
104: splbase __ARGS (())
105: #endif
106: {
107: #ifdef splbase
108: return splbase ();
109: #else
110: return splx (plbase);
111: #endif
112: }
113:
114:
115: #if __USE_PROTO__
116: pl_t (spltimeout) (void)
117: #else
118: pl_t
119: spltimeout __ARGS (())
120: #endif
121: {
122: #ifdef spltimeout
123: return spltimeout ();
124: #else
125: return splx (pltimeout);
126: #endif
127: }
128:
129:
130: #if __USE_PROTO__
131: pl_t (spldisk) (void)
132: #else
133: pl_t
134: spldisk __ARGS (())
135: #endif
136: {
137: #ifdef spldisk
138: return spldisk ();
139: #else
140: return splx (pldisk);
141: #endif
142: }
143:
144:
145: #if __USE_PROTO__
146: pl_t (splstr) (void)
147: #else
148: pl_t
149: splstr __ARGS (())
150: #endif
151: {
152: #ifdef splstr
153: return splstr ();
154: #else
155: return splx (plstr);
156: #endif
157: }
158:
159:
160: #if __USE_PROTO__
161: pl_t (splhi) (void)
162: #else
163: pl_t
164: splhi __ARGS (())
165: #endif
166: {
167: #ifdef splhi
168: return splhi ();
169: #else
170: return splx (plhi);
171: #endif
172: }
173:
174: #if __USE_PROTO__
175: pl_t (splx) (pl_t newpl)
176: #else
177: pl_t
178: splx __ARGS ((newpl))
179: pl_t newpl;
180: #endif
181: {
182: #ifdef splx
183: return splx (newpl);
184: #else
185: pl_t prev_pl;
186: intmask_t mask = __GET_BASE_MASK () | _masktab [newpl];
187:
188: __OUT_IPL_MASK (mask);
189:
190: prev_pl = (pl_t) ddi_cpu_data ()->dc_ipl;
191: ddi_cpu_data ()->dc_ipl = newpl;
192:
193: return prev_pl;
194: #endif
195: }
196:
197:
198: /*
199: *-STATUS:
200: * Private internal (used by various assertions)
201: *
202: *-NAME:
203: * splcmp Compare processor priority levels
204: *
205: *-ARGUMENTS:
206: * l Processor priority level considered to be on the LHS
207: * of the l < r relational comparison.
208: * r Processor priority that "l" is to be compared with
209: *
210: *-DESCRIPTION:
211: * This functions performs a relational comparison of processor priority
212: * levels which can be used to test assertions about the relative order
213: * in which priority levels are set. It is guaranteed that this function
214: * will return values consistent with the partial order defined by the
215: * DDI/DKI.
216: *
217: * Note that attempting to compare the values "plstr" and "pldisk" is not
218: * valid. In a system where processor priorities are implemented using
219: * masks, "pldisk" and "plstr" may be genuinely unordered in that the
220: * resulting masks may be disjoint. An implementation is free to diagnose
221: * such a comparison by causing a kernel panic.
222: *
223: * This function is intended for use in ASSERT () statements only. If it
224: * is desired to set the processor priority level to the maximum of two
225: * values, use splraise () instead so that in an implementation which
226: * uses masks the logical union or intersection of the masks can be
227: * taken.
228: *
229: *-RETURNS:
230: * -1 if the level "l" compares less than "r"
231: * 0 if "l" and "r" specify the same actual priority level
232: * 1 if the level "l" compares greater that "r"
233: *
234: *-LEVEL:
235: * Base or Interrupt.
236: *
237: *-NOTES:
238: * This function does not sleep.
239: *
240: * Driver-defined basic locks, read/write locks and sleep locks may be
241: * held across calls to this function.
242: */
243:
244: #if __USE_PROTO__
245: int (splcmp) (pl_t l, pl_t r)
246: #else
247: int
248: splcmp __ARGS ((l, r))
249: pl_t l;
250: pl_t r;
251: #endif
252: {
253: return (l < r) ? -1 : l != r;
254: }
255:
256:
257: /*
258: *-STATUS:
259: * Private internal (used by freezestr ())
260: *
261: *-NAME:
262: * splraise Raise processor priority level.
263: *
264: *-ARGUMENTS:
265: * pl Processor interrupt priority level to raise to.
266: *
267: *-DESCRIPTION:
268: * splraise () changes the processor interrupt priority level to the
269: * maximum value defined by the previous level and the current level.
270: *
271: * If the previous and requested priority levels are "pldisk" and "plstr"
272: * (in either order) this function does the appropriate action given that
273: * the "maximum" level in a mask-based system is in the fact the union or
274: * intersection of the two masks.
275: *
276: *-RETURNS:
277: * The previous processor interrupt priority level.
278: *
279: *-LEVEL:
280: * Base or Interrupt.
281: *
282: *-NOTES:
283: * This function does not sleep.
284: *
285: * Driver-defined basic locks, read/write locks and sleep locks may be
286: * held across calls to this function.
287: */
288:
289: #if __USE_PROTO__
290: pl_t (splraise) (pl_t newpl)
291: #else
292: pl_t
293: splraise __ARGS ((newpl))
294: pl_t newpl;
295: #endif
296: {
297: #ifdef splraise
298: return splraise (newpl);
299: #else
300: pl_t prev_pl;
301:
302: if (newpl > (prev_pl = (pl_t) ddi_cpu_data ()->dc_ipl)) {
303: intmask_t mask = __GET_BASE_MASK () | _masktab [newpl];
304:
305: __OUT_IPL_MASK (mask);
306: ddi_cpu_data ()->dc_ipl = newpl;
307: }
308:
309: return prev_pl;
310: #endif
311: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.