|
|
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.