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