Annotation of coherent/d/286_KERNEL/USRSRC/ldrv/ldmain.c, revision 1.1

1.1     ! root        1: /* $Header: /usr/src/sys/ldrv/RCS/ldmain.c,v 1.2 89/03/31 16:19:36 src Exp $ */
        !             2: /*
        !             3:  *     The  information  contained herein  is a trade secret  of INETCO
        !             4:  *     Systems, and is confidential information.   It is provided under
        !             5:  *     a license agreement,  and may be copied or disclosed  only under
        !             6:  *     the terms of that agreement.   Any reproduction or disclosure of
        !             7:  *     this  material  without  the express  written  authorization  of
        !             8:  *     INETCO Systems or persuant to the license agreement is unlawful.
        !             9:  *
        !            10:  *     Copyright (c) 1987
        !            11:  *     An unpublished work by INETCO Systems, Ltd.
        !            12:  *     All rights reserved.
        !            13:  */
        !            14: 
        !            15: /*
        !            16:  * Loadable Driver - Process Handler.
        !            17:  *
        !            18:  * $Log:       /usr/src/sys/ldrv/RCS/ldmain.c,v $
        !            19:  * Revision 1.2        89/03/31  16:19:36      src
        !            20:  * Bug:        Did not cancel either attached timed functions or deferred functions
        !            21:  *     during an unload.  As a result, if a driver did not explicitly do
        !            22:  *     this, then unloading the driver could cause a system panic.
        !            23:  * Fix:        Now cancels the functions. (ABC)
        !            24:  * 
        !            25:  * Revision 1.1        88/03/24  08:30:44      src
        !            26:  * Initial revision
        !            27:  * 
        !            28:  * 87/12/03    Allan Cornish           /usr/src/sys/ldrv/ldmain.c
        !            29:  * Initial version.
        !            30:  */
        !            31: #include <sys/coherent.h>
        !            32: #include <sys/proc.h>
        !            33: #include <sys/sched.h>
        !            34: #include <sys/con.h>
        !            35: #include <sys/seg.h>
        !            36: #include <sys/stat.h>
        !            37: #include <sys/uproc.h>
        !            38: 
        !            39: extern CON con;
        !            40: 
        !            41: extern saddr_t ldrvsel[NDRV];
        !            42: extern saddr_t ldrvics[16];
        !            43: extern void  (*ldrvipc[16])();
        !            44: extern CON *   ldrvcon[NDRV];
        !            45: extern CON     ldrvpsy;
        !            46: extern saddr_t ucs;
        !            47: 
        !            48: /*
        !            49:  * Local variable - keeps track of the number of opens.
        !            50:  * The loadable driver can't terminate until after the last close.
        !            51:  * Openf is the loadable driver open routine.
        !            52:  * Closef points to the driver's close routine.
        !            53:  * The configuration table entries are taken over
        !            54:  */
        !            55: static int     nopen = 0;
        !            56: static void    (*openf)() = NULL;
        !            57: static void    (*closef)() = NULL;
        !            58: 
        !            59: main()
        !            60: {
        !            61:        register int mind = con.c_mind;
        !            62:        register int level;
        !            63:        extern  void myopen();
        !            64:        extern  void myclose();
        !            65:        extern  void Kdefend();
        !            66: 
        !            67:        /*
        !            68:         * Loadable devices must identify the desired major device.
        !            69:         */
        !            70:        if ( (mind == 0) || (mind >= drvn) ) {
        !            71:                printf("ldrv:%d: bad dev\n", mind );
        !            72:                uexit( 1 );
        !            73:        }
        !            74: 
        !            75:        /*
        !            76:         * Loadable devices must use a unique [not in use] major device.
        !            77:         */
        !            78:        if ( (drvl[mind].d_conp != NULL) || (ldrvcon[mind] != NULL) ) {
        !            79:                printf("ldrv:%d: dev bsy\n", mind );
        !            80:                uexit( 0 );
        !            81:        }
        !            82: 
        !            83:        /*
        !            84:         * Intercept driver open/close requests.
        !            85:         * This allows the driver process to terminate after the last close,
        !            86:         *      if one or more signals have been received.
        !            87:         */
        !            88:        openf           = con.c_open;
        !            89:        closef          = con.c_close;
        !            90:        con.c_open      = myopen;
        !            91:        con.c_close     = myclose;
        !            92: 
        !            93:        /*
        !            94:         * Install the loadable driver pseudo device interface.
        !            95:         * The O/S will call the pseudo-device, which will call us.
        !            96:         * Record our driver configuration and code segment.
        !            97:         */
        !            98:        drvl[mind].d_conp = &ldrvpsy;
        !            99:        ldrvcon[mind] = &con;
        !           100:        ldrvsel[mind] = ucs;
        !           101: 
        !           102:        /*
        !           103:         * Load the device driver.
        !           104:         */
        !           105:        if ( con.c_load != NULL )
        !           106:                (*con.c_load)( makedev(mind,0) );
        !           107: 
        !           108:        /*
        !           109:         * Sleep until a kill signal has arrived, and no device is open.
        !           110:         */
        !           111:        do {
        !           112:                sleep( (char *)&nopen, CVSWAP, IVSWAP, SVSWAP );
        !           113: 
        !           114:        } while ( ((SELF->p_ssig & 0x0100) == 0) || (nopen != 0) );
        !           115: 
        !           116:        /*
        !           117:         * Unload the device driver.
        !           118:         */
        !           119:        if ( con.c_uload != NULL )
        !           120:                (*con.c_uload)( makedev(mind,0) );
        !           121: 
        !           122:        /*
        !           123:         * Erase references to our kernel process.
        !           124:         */
        !           125:        drvl[mind].d_conp = NULL;
        !           126:        ldrvcon[mind] = NULL;
        !           127:        ldrvsel[mind] = 0;
        !           128: 
        !           129:        /*
        !           130:         * Scan looking for attached interrupts.
        !           131:         * NOTE: This is to prevent dangling interrupt vectors.
        !           132:         */
        !           133:        for ( level = 0; level < 16; level++ ) {
        !           134: 
        !           135:                /*
        !           136:                 * Interrupt is not attached to us.
        !           137:                 */
        !           138:                if ( ldrvics[level] != ucs )
        !           139:                        continue;
        !           140: 
        !           141:                /*
        !           142:                 * Disable interrupt.
        !           143:                 */
        !           144:                clrivec( level );
        !           145: 
        !           146:                /*
        !           147:                 * Release loadable driver interrupt.
        !           148:                 */
        !           149:                ldrvics[level] = 0;
        !           150:                ldrvipc[level] = NULL;
        !           151:        }
        !           152: 
        !           153:        /*
        !           154:         * Service deferred functions BEFORE scanning for timed functions.
        !           155:         * This is in case a deferred function schedules a timed function.
        !           156:         */
        !           157:        kcall( Kdefend );
        !           158: 
        !           159:        /*
        !           160:         * Scan for attached timed functions which have to be terminated.
        !           161:         */
        !           162:        for ( level = 0; level < nel(timq); level++ ) {
        !           163:                register TIM * tp;
        !           164: 
        !           165:                /*
        !           166:                 * Access a specific timing queue.
        !           167:                 */
        !           168:                for ( tp = timq[level]; tp != NULL; ) {
        !           169: 
        !           170:                        /*
        !           171:                         * Timed function is in our loadable driver.
        !           172:                         * Restart search at start of timing queue.
        !           173:                         */
        !           174:                        if ( FP_SEL(tp->t_ldrv) == getcs() ) {
        !           175:                                timeout( tp, 0, NULL, 0 );
        !           176:                                tp = timq[ level ];
        !           177:                        }
        !           178: 
        !           179:                        /*
        !           180:                         * Not one of our timed functions.
        !           181:                         * Advance to next function in queue.
        !           182:                         */
        !           183:                        else
        !           184:                                tp = tp->t_next;
        !           185:                }
        !           186:        }
        !           187: 
        !           188:        /*
        !           189:         * Terminate with extreme prejudice.
        !           190:         */
        !           191:        uexit( 0 );
        !           192: }
        !           193: 
        !           194: static void
        !           195: myopen( dev, mode )
        !           196: dev_t dev;
        !           197: int mode;
        !           198: {
        !           199:        /*
        !           200:         * Invoke the true open routine for the loadable driver.
        !           201:         */
        !           202:        if ( openf != NULL )
        !           203:                (*openf)(dev, mode );
        !           204: 
        !           205:        /*
        !           206:         * Adjust reference count if open succeeded.
        !           207:         */
        !           208:        if ( u.u_error == 0 )
        !           209:                nopen++;
        !           210: }
        !           211: 
        !           212: static void
        !           213: myclose( dev )
        !           214: dev_t dev;
        !           215: {
        !           216:        /*
        !           217:         * Invoke the true close routine for the loadable driver.
        !           218:         */
        !           219:        if ( closef != NULL )
        !           220:                (*closef)( dev );
        !           221: 
        !           222:        /*
        !           223:         * Wakeup driver process after last close.
        !           224:         * This allows it to terminate if appropriate.
        !           225:         */
        !           226:        if ( --nopen == 0 )
        !           227:                wakeup( (char*) &nopen );
        !           228: }

unix.superglobalmegacorp.com

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