Annotation of coherent/f/etc/conf/streams/src/drv_ddi.c, revision 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.