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