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