Annotation of coherent/d/286_KERNEL/USRSRC/ldrv/ldmain.c, revision 1.1.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.