|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.