|
|
1.1 root 1: #define _DDI_DKI 1
2: #define _SYSV4 1
3:
4: /*
5: * This file implements many of the drv_... () functions defined in the System
6: * V DDI/DKI.
7: */
8:
9: /*
10: *-IMPORTS:
11: * <common/ccompat.h>
12: * __USE_PROTO__
13: * __ARGS ()
14: * <common/__clock.h>
15: * __clock_t
16: * <sys/debug.h>
17: * ASSERT ()
18: * <sys/types.h>
19: * cred_t
20: * ulong_t
21: * <stddef.h>
22: * NULL
23: * <limits.h>
24: * CHAR_BIT
25: */
26:
27: #include <common/ccompat.h>
28: #include <sys/debug.h>
29: #include <sys/types.h>
30: #include <stddef.h>
31: #include <limits.h>
32:
33: #include <sys/types.h>
34:
35:
36: #if __COHERENT__
37:
38: #include <sys/coherent.h>
39: #include <sys/param.h>
40:
41: __LOCAL__ cred_t _cred = {
42: 1, 0, 0, 0, 0, 0, NULL
43: };
44:
45: #define PRIVELEGED(credp) (super ())
46: #define SYSTEM_LBOLT() (lbolt)
47: #define SYSTEM_UPROCP() (cprocp)
48: #define SYSTEM_UCRED() (& _cred)
49: #define SYSTEM_TIME() (timer.t_time)
50:
51:
52: /*
53: * Converting between ticks and microseconds accurately is a nightmare in the
54: * general case. I've make the routine that does this system-specific so that
55: * it's easy to do; for Coherent, there are 1000 microseconds per tick (in
56: * theory), so we can just multiply and/or divide.
57: */
58:
59: #if (1000000L % HZ) != 0
60: #error These routines tuned for an even number of microseconds per tick
61: #endif
62:
63: #define U_PER_TICK (1000000L / HZ)
64:
65: #elif __BORLANDC__ || defined (GNUDOS)
66:
67: #include <time.h>
68:
69: __LOCAL__ __clock_t _lbolt;
70: __LOCAL__ cred_t _cred = {
71: 1, 0, 0, 0, 0, 0, NULL
72: };
73:
74: #define PRIVELEGED(credp) 0
75: #define SYSTEM_LBOLT() (_lbolt ++)
76: #define SYSTEM_UPROCP() (1)
77: #define SYSTEM_UCRED() (& _cred)
78: #define SYSTEM_TIME() (time (NULL))
79:
80: /*
81: * Under MSDOS, just use the 18.2Hz minimum.
82: */
83:
84: #define U_PER_TICK 54945
85:
86: #endif
87:
88: #if U_PER_TICK >= 1000
89:
90: /*
91: * Routines for time processing basic on microseconds per tick... these won't
92: * work when the tick and microseconds times are too close or ticks are in
93: * fact smaller than microseconds.
94: */
95:
96:
97: #if __USE_PROTO__
98: __clock_t (USEC_TO_HZ) (__clock_t usec)
99: #else
100: __clock_t
101: USEC_TO_HZ __ARGS ((usec))
102: __clock_t usec;
103: #endif
104: {
105: ulong_t ticks = usec / U_PER_TICK;
106:
107: if ((usec % U_PER_TICK) != 0)
108: ticks ++;
109:
110: return ticks;
111: }
112:
113: #if __USE_PROTO__
114: __clock_t (HZ_TO_USEC) (__clock_t ticks)
115: #else
116: __clock_t
117: HZ_TO_USEC __ARGS ((ticks))
118: __clock_t ticks;
119: #endif
120: {
121: ASSERT ((__clock_t) -1 > 0);
122:
123: if (ticks >= (__clock_t) -1 / U_PER_TICK)
124: return (__clock_t) -1;
125:
126: return ticks * U_PER_TICK;
127: }
128:
129: #endif
130:
131:
132: /*
133: *-STATUS:
134: * DDI/DKI
135: *
136: *-NAME:
137: * drv_getparm Retrieve kernel state information.
138: *
139: *-SYNOPSIS:
140: * #include <sys/types.h>
141: * #include <sys/ddi.h>
142: *
143: * int drv_getparm (ulong_t parm, ulong_t * value_p);
144: *
145: *-ARGUMENTS:
146: * parm The kernel parameter to be obtained. Possible values
147: * are:
148: * LBOLT Read the number of clock ticks since the last
149: * kernel reboot. The difference between the
150: * values returned from successive calls to
151: * retrieve this parameter provides an indication
152: * of the elapsed time between the calls in units
153: * of clock ticks. The length of a clock tick can
154: * vary across different implementations, and
155: * therefore drivers should not include any hard-
156: * coded assumptions about the length of a tick.
157: * The drv_hztousec () and drv_usectohz ()
158: * functions can be used to convert between clock
159: * ticks and microseconds.
160: *
161: * UPROCP Retrieve a pointer to the process structure
162: * for the current process. The value returned in
163: * "* value_p" is of type "(proc_t *)" and the
164: * only valid use of the value is as an argument
165: * to vtop (). Since this value is associated
166: * with the current process, the caller must have
167: * process context (that is, must be at base
168: * level) when attempting to retrieve this value.
169: * Also, this value should only be used in the
170: * context of the process in which it was
171: * retrieved.
172: *
173: * UCRED Retrieve a pointer to the credential structure
174: * describing the current user credentials for
175: * the current process. The value returned in
176: * "* value_p" is of type "(cred_t *)" and the
177: * only valid use of the value is an an argument
178: * to drv_priv (). Since this value is associated
179: * with the current process, the caller must have
180: * process context (ie, must be at base level)
181: * when attempting to retrieve this value. Also,
182: * this value should only be used in the context
183: * of the process in which it was retrieved.
184: *
185: * TIME Read the time in seconds. This is the same
186: * time value that is returned by the time ()
187: * system call. The value is defined as the time
188: * in seconds since "00:00:00 GMT, January 1,
189: * 1970". This definition presupposes that the
190: * administrator has set the correct system time
191: * and date.
192: *
193: * value_p A pointer to the data space into which the value of
194: * the parameter is to be copied.
195: *
196: *-DESCRIPTION:
197: * drv_getparm () returns the value of the parameter specified by "parm"
198: * in the location pointed to by "value_p".
199: *
200: * drv_getparm () does not explicitly check to see whether the driver has
201: * the appropriate context when the function is called. It is the
202: * responsibility of the driver to use this function only when it is
203: * appropriate to do so and to correctly declare the data space needed.
204: *
205: *-RETURN VALUE:
206: * If the function is successful, 0 is returned. Otherwise, -1 is
207: * returned to indicate that "parm" specified an invalid parameter.
208: *
209: *-LEVEL:
210: * Base only when using the UPROCP or UCRED argument values.
211: *
212: * Base or interrupt when using the LBOLT or TIME argument values.
213: *
214: *-NOTES:
215: * Does not sleep.
216: *
217: * Driver-defined basic locks, read/write locks, and sleep locks may be
218: * held across calls to this function.
219: *
220: *-SEE ALSO:
221: * drv_hztousec (), drv_priv (), drv_usectohz (), vtop ()
222: */
223:
224: #if __USE_PROTO__
225: int (drv_getparm) (ulong_t parm, ulong_t * value_p)
226: #else
227: int
228: drv_getparm __ARGS ((parm, value_p))
229: ulong_t parm;
230: ulong_t * value_p;
231: #endif
232: {
233: ASSERT (value_p != NULL);
234:
235: switch (parm) {
236:
237: case LBOLT:
238: * value_p = SYSTEM_LBOLT ();
239: break;
240:
241: case UPROCP:
242: * value_p = (ulong_t) SYSTEM_UPROCP ();
243: break;
244:
245: case UCRED:
246: * value_p = (ulong_t) SYSTEM_UCRED ();
247: break;
248:
249: case TIME:
250: * value_p = SYSTEM_TIME ();
251: break;
252:
253: default:
254: return -1;
255: }
256:
257: return 0;
258: }
259:
260:
261: /*
262: *-STATUS:
263: * DDI/DKI
264: *
265: *-NAME:
266: * drv_hztousec Convert clock ticks to microseconds.
267: *
268: *-SYNOPSIS:
269: * #include <sys/types.h>
270: * #include <sys/ddi.h>
271: *
272: * clock_t drv_hztousec (clock_t ticks);
273: *
274: *-ARGUMENTS:
275: * ticks The number of clock ticks to convert to equivalent
276: * microseconds.
277: *
278: *-DESCRIPTION:
279: * drv_hztousec () converts the length of time expressed by "ticks",
280: * which is in units of clock ticks, into units of microseconds.
281: *
282: * Several functions either take time values expressed in clock ticks as
283: * arguments [itimeout (), delay ()] or return time values expressed in
284: * clock ticks [drv_getparm ()]. The length of a clock tick can vary
285: * across different implementations and therefore drivers should not
286: * include any hard-coded assumptions about the length of a tick.
287: * drv_hztousec () and the complementary function drv_usectohz () can be
288: * used as necessary to convert between clock ticks and microseconds.
289: *
290: *-RETURN VALUE:
291: * The number of microseconds equivalent to the "ticks" argument. No
292: * error value is returned. If the microsecond equivalent to "ticks" is
293: * too large to be represented as a "clock_t", then the maximum "clock_t"
294: * value will be returned.
295: *
296: *-LEVEL:
297: * Base or interrupt.
298: *
299: *-NOTES:
300: * Does not sleep.
301: *
302: * Driver-defined basic locks, read/write locks, and sleep locks may be
303: * held across calls to this function.
304: *
305: * The time value returned by drv_getparm () with an "LBOLT" argument
306: * will frequently be too large to represent in microseconds as a
307: * "clock_t". When using drv_getparm () together with drv_hztousec () to
308: * time operations, drivers can help avoid overflow by converting the
309: * difference between return values from successive calls to
310: * drv_getparm () instead of trying to convert the return values
311: * themselves.
312: *
313: *-SEE ALSO:
314: * delay (), drv_getparm (), drv_usectohz (), dtimeout (), itimeout ()
315: */
316:
317: #if __USE_PROTO__
318: __clock_t (drv_hztousec) (__clock_t ticks)
319: #else
320: __clock_t
321: drv_hztousec __ARGS ((ticks))
322: __clock_t ticks;
323: #endif
324: {
325: return HZ_TO_USEC (ticks);
326: }
327:
328:
329: /*
330: *-STATUS:
331: * DDI/DKI
332: *
333: *-NAME:
334: * drv_priv Determine whether credentials are priveleged.
335: *
336: *-SYNOPSIS:
337: * #include <sys/types.h>
338: * #include <sys/ddi.h>
339: *
340: * int drv_priv (cred_t * crp);
341: *
342: *-ARGUMENTS:
343: * crp Pointer to the user credential structure.
344: *
345: *-DESCRIPTION:
346: * The drv_priv () function determines whether the credentials specified
347: * by the credential structure pointer to by "crp" identify a priveleged
348: * process. This function should only be used when file access modes and
349: * special minor device numbers are insufficient to provide the necessary
350: * protection for the driver operation being performed. Calls to
351: * drv_priv () should replace all calls to suser () and any explicit
352: * checks for effective user ID equal to zero in driver code.
353: *
354: * A credential structure pointer is passed into various driver entry
355: * point functions [open (), close (), read () and ioctl ()] and can also
356: * be obtained by calling drv_getparm () from base level driver code.
357: *
358: *-RETURN VALUE:
359: * This routine returns 0 is the specified credentials identify a
360: * priveleged process and EPERM otherwise.
361: *
362: *-LEVEL:
363: * Base or interrupt.
364: *
365: *-NOTES:
366: * Does not sleep.
367: *
368: * Driver-defined basic locks, read/write locks, and sleep locks may be
369: * held across calls to this function.
370: *
371: * The only valid use for a credential structure pointer is an an
372: * argument to drv_priv (). The contents of a credential structure are
373: * not defined by the DDI/DKI and a driver may not examine the contents
374: * of the structure directly.
375: *
376: *-SEE ALSO:
377: * drv_getparm ()
378: */
379:
380: #if __USE_PROTO__
381: int (drv_priv) (cred_t * crp)
382: #else
383: int
384: drv_priv __ARGS ((crp))
385: cred_t * crp;
386: #endif
387: {
388: ASSERT (crp != NULL);
389:
390: return PRIVELEGED (crp);
391: }
392:
393:
394: /*
395: *-STATUS:
396: * DDI/DKI
397: *
398: *-NAME:
399: * drv_setparm Set kernel state information.
400: *
401: *-SYNOPSIS:
402: * #include <sys/types.h>
403: * #include <sys/ddi.h>
404: *
405: * int drv_setparm (ulong_t parm, ulong_t value);
406: *
407: *-ARGUMENTS:
408: * parm The kernel parameter to be updated. Possible values
409: * are:
410: * SYSCANC Add "value" to the count of the number of
411: * characters received from a terminal device
412: * after the characters have been processed to
413: * remove special characters such as "break" or
414: * "backspace".
415: *
416: * SYSMINT Add "value" to the count of the number of
417: * modem interrupts received.
418: *
419: * SYSOUTC Add "value" to the count of the number of
420: * characters output to a terminal device.
421: *
422: * SYSRAWC Add "value" to the count of the number of
423: * characters received from a terminal device,
424: * before canonical processing has occurred.
425: *
426: * SYSRINT Add "value" to the count of the number of
427: * interrupts generated by data ready to be
428: * received from a terminal device.
429: *
430: * SYSXINT Add "value" to the count of the number of
431: * interrupts generated by data ready to be
432: * transmitted to a terminal device.
433: *
434: * value The value to be added to the parameter.
435: *
436: *-DESCRIPTION:
437: * drv_setparm () verifies that "parm" corresponds to a kernel parameter
438: * that may be modified. If the value of "parm" correspoonds to a
439: * parameter that may not be modified, -1 is returned. Otherwise, the
440: * parameter is incremented by "value".
441: *
442: * No checking is performed to determine the validity of "value". It is
443: * the driver's reponsibility to guarantee the correctness of "value".
444: *
445: *-RETURN VALUE:
446: * If the function is successful, 0 is returned. Otherwise, -1 is
447: * returned to indicate that "parm" specified an invalid parameter.
448: *
449: *-LEVEL:
450: * Base or interrupt.
451: *
452: *-NOTES:
453: * Does not sleep.
454: *
455: * Driver-defined basic locks, read/write locks, and sleep locks may be
456: * held across calls to this function.
457: *
458: *-SEE ALSO:
459: * drv_getparm ()
460: */
461:
462: #if __USE_PROTO__
463: int (drv_setparm) (ulong_t parm, ulong_t value)
464: #else
465: int
466: drv_setparm __ARGS ((parm, value))
467: ulong_t parm;
468: ulong_t value;
469: #endif
470: {
471: switch (parm) {
472:
473: case SYSCANC:
474: case SYSMINT:
475: case SYSOUTC:
476: case SYSRAWC:
477: case SYSRINT:
478: case SYSXINT:
479: break;
480:
481: default:
482: return -1;
483: }
484:
485: return 0;
486: }
487:
488:
489: /*
490: *-STATUS:
491: * DDI/DKI
492: *
493: *-NAME:
494: * drv_usectohz Convert microseconds to clock ticks.
495: *
496: *-SYNOPSIS:
497: * #include <sys/types.h>
498: * #include <sys/ddi.h>
499: *
500: * clock_t drv_usectohz (clock_t microsecs);
501: *
502: *-ARGUMENTS:
503: * microsecs The number of microseconds to convert to equivalent
504: * clock ticks.
505: *
506: *-DESCRIPTION:
507: * drv_usectohz () converts the length of time expressed by "microsecs",
508: * which is in units of microseconds, into units of clock ticks.
509: *
510: * Several functions either take time values expressed in clock ticks as
511: * arguments [itimeout (), delay ()] or return time values expressed in
512: * clock ticks [drv_getparm ()]. The length of a clock tick can vary
513: * across different implementations, and therefore drivers should not
514: * include any hard-coded assumptions about the length of a tick.
515: * drv_usectohz () and the complementary function drv_hztousec () can be
516: * used as necessary to convert between microseconds and clock ticks.
517: *
518: *-RETURN VALUE:
519: * The value returned is the smallest number of clock ticks that
520: * represent a time interval equal to or greater than the "microsecs"
521: * argument. No error value is returned. If the number of ticks
522: * equivalent to the "microsecs" argument is too large to be represented
523: * as a "clock_t", then the maximum "clock_t" value will be returned.
524: *
525: *-LEVEL:
526: * Base or interrupt.
527: *
528: *-NOTES:
529: * Does not sleep.
530: *
531: * Driver-defined basic locks, read/write locks, and sleep locks may be
532: * held across calls to this function.
533: *
534: *-SEE ALSO:
535: * delay (), drv_getparm (), drv_hztousec (), dtimeout (), itimeout ()
536: */
537:
538: #if __USE_PROTO__
539: __clock_t (drv_usectohz) (__clock_t microsecs)
540: #else
541: __clock_t
542: drv_usectohz __ARGS ((microsecs))
543: __clock_t microsecs;
544: #endif
545: {
546: return USEC_TO_HZ (microsecs);
547: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.