Annotation of coherent/b/STREAMS/conf/streams/src/drv_ddi.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.