Annotation of coherent/b/STREAMS/conf/patch/src/patch.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * conf/patch.c
                      3:  *
                      4:  * patch device
                      5:  *     Used for inspecting and altering the value of kernel
                      6:  *     variables, and enabling device drivers, after the kernel
                      7:  *     has started running.
                      8:  *
                      9:  * NOTICE:  This driver is a massive kluge (just ask Nigel).  It is
                     10:  *     intended for use ONLY with the bootstrap kernel shipped on
                     11:  *     the first diskette of the installation set.  Otherwise,
                     12:  *     kernel variables can be patched using mtune/stune, and
                     13:  *     drivers enabled using mdevice/sdevice.
                     14:  *
                     15:  * Revised: Thu Jul 22 16:25:23 1993 CDT
                     16:  */
                     17: 
                     18: /*
                     19:  * -----------------------------------------------------------------
                     20:  * Includes.
                     21:  */
                     22: #define __KERNEL__ 1
                     23: 
                     24: #include <string.h>
                     25: #include <sys/coherent.h>
                     26: #include <sys/con.h>
                     27: #include <sys/errno.h>
                     28: #include <sys/patch.h>
                     29: #include <kernel/v_types.h>
                     30: 
                     31: /*
                     32:  * -----------------------------------------------------------------
                     33:  * Definitions.
                     34:  *     Constants.
                     35:  *     Macros with argument lists.
                     36:  *     Typedefs.
                     37:  *     Enums.
                     38:  */
                     39: 
                     40: /*
                     41:  * -----------------------------------------------------------------
                     42:  * Functions.
                     43:  *     Import Functions.
                     44:  *     Export Functions.
                     45:  *     Local Functions.
                     46:  */
                     47: int nulldev();
                     48: 
                     49: /*
                     50:  * Configuration functions (local functions).
                     51:  */
                     52: struct patch;
                     53: static int patchioctl  __PROTO((dev_t dev, int com, struct patch * vec));
                     54: 
                     55: /*
                     56:  * Support functions (local functions).
                     57:  */
                     58: static int copyinEfault  __PROTO((_VOID * userBuf, _VOID * driverBuf,
                     59:                                size_t byteCount));
                     60: static int copyoutEfault  __PROTO((_VOID * driverBuf, _VOID * userBuf,
                     61:                                size_t byteCount));
                     62: 
                     63: static struct patchVarInternal * patchVarLookup();
                     64: static struct patchConInternal * patchConLookup();
                     65: 
                     66: static int matchMajor();
                     67: static int validMajor();
                     68: 
                     69: /*
                     70:  * -----------------------------------------------------------------
                     71:  * Global Data.
                     72:  *     Import Variables.
                     73:  *     Export Variables.
                     74:  *     Local Variables.
                     75:  */
                     76: 
                     77: /*
                     78:  * Configuration table (export data).
                     79:  */
                     80: CON patchcon ={
                     81:        DFCHR,                          /* Flags */
                     82:        0,                              /* Major index */
                     83:        nulldev,                        /* Open */
                     84:        nulldev,                        /* Close */
                     85:        nulldev,                        /* Block */
                     86:        nulldev,                        /* Read */
                     87:        nulldev,                        /* Write */
                     88:        patchioctl,                     /* Ioctl */
                     89:        nulldev,                        /* Powerfail */
                     90:        nulldev,                        /* Timeout */
                     91:        nulldev,                        /* Load */
                     92:        nulldev,                        /* Unload */
                     93:        nulldev                         /* Poll */
                     94: };
                     95: 
                     96: /*
                     97:  * -----------------------------------------------------------------
                     98:  * Code.
                     99:  */
                    100: 
                    101: /*******************************************************************
                    102:  * matchMajor()
                    103:  *
                    104:  * See if drvl entry at the given major number matches the given
                    105:  * address.
                    106:  * Return 0 if there is a match.
                    107:  * Return -1 and set EINVAL if no match.
                    108:  ******************************************************************/
                    109: static int
                    110: matchMajor(major, addr)
                    111: int major;
                    112: CON * addr;
                    113: {
                    114:        if (drvl[major].d_conp == addr)
                    115:                return 0;
                    116:        else {
                    117:                u.u_error = EINVAL;
                    118:                return -1;
                    119:        }
                    120: }
                    121: 
                    122: /*******************************************************************
                    123:  * validMajor()
                    124:  *
                    125:  * See if the given major number is within the allowable range.
                    126:  * Return 0 if valid.
                    127:  * Return -1 and set EINVAL if not valid.
                    128:  ******************************************************************/
                    129: static int
                    130: validMajor(major)
                    131: unsigned int major;
                    132: {
                    133:        if (major < NDRV)
                    134:                return 0;
                    135:        else {
                    136:                u.u_error = EINVAL;
                    137:                return -1;
                    138:        }
                    139: }
                    140: 
                    141: /*******************************************************************
                    142:  * patchVarLookup()
                    143:  *
                    144:  * Given a variable name, look for a matching record in the table
                    145:  * of kernel patchable variables.
                    146:  *
                    147:  * Return a pointer to the matching record if there is a match.
                    148:  * Return 0 and set EINVAL if no match.
                    149:  ******************************************************************/
                    150: static struct patchVarInternal *
                    151: patchVarLookup(vname)
                    152: char * vname;
                    153: {
                    154:        int i;
                    155:        struct patchVarInternal * match = NULL;
                    156: 
                    157:        for (i = 0;  i < patchVarCount && ! match;  i++)
                    158:                if (strncmp(vname, patchVarTable[i].patch_vname,
                    159:                  PATCH_VAR_NAME_LENGTH) == 0)
                    160:                        match = patchVarTable + i;
                    161: 
                    162:        if (!match)
                    163:                u.u_error = EINVAL;
                    164:        return match;
                    165: }
                    166: 
                    167: /*******************************************************************
                    168:  * patchConLookup()
                    169:  *
                    170:  * Given a CON structure name, look for a matching record in the
                    171:  * table of deferred-load devices.
                    172:  *
                    173:  * Return a pointer to the matching record if there is a match.
                    174:  * Return 0 and set EINVAL if no match.
                    175:  ******************************************************************/
                    176: static struct patchConInternal *
                    177: patchConLookup(vname)
                    178: char * vname;
                    179: {
                    180:        int i;
                    181:        struct patchConInternal * match = NULL;
                    182: 
                    183:        for (i = 0;  i < patchConCount && ! match;  i++)
                    184:                if (strncmp(vname, patchConTable[i].patch_vname,
                    185:                  PATCH_VAR_NAME_LENGTH) == 0)
                    186:                        match = patchConTable + i;
                    187: 
                    188:        if (!match)
                    189:                u.u_error = EINVAL;
                    190:        return match;
                    191: }
                    192: 
                    193: /*******************************************************************
                    194:  * copyinEfault()
                    195:  *
                    196:  * Do a copy from user data to kernel data.
                    197:  * Set EFAULT if there is a problem.
                    198:  * Return 0 on success, -1 on failure.
                    199:  ******************************************************************/
                    200: #if __USE_PROTO___
                    201: static int copyinEfault  (_VOID * userBuf, _VOID * driverBuf,
                    202:                                size_t byteCount)
                    203: #else
                    204: static int
                    205: copyinEfault(userBuf, driverBuf, byteCount)
                    206: _VOID * userBuf;
                    207: _VOID * driverBuf;
                    208: size_t byteCount;
                    209: #endif
                    210: {
                    211:        size_t result;
                    212: 
                    213:        result = copyin(userBuf, driverBuf, byteCount);
                    214:        if (result)
                    215:                u.u_error = EFAULT;
                    216:        return result;
                    217: }
                    218: 
                    219: /*******************************************************************
                    220:  * copyoutEfault()
                    221:  *
                    222:  * Do a copy from user data to kernel data.
                    223:  * Set EFAULT if there is a problem.
                    224:  * Return 0 on success, -1 on failure.
                    225:  ******************************************************************/
                    226: #if __USE_PROTO__
                    227: static int copyoutEfault  (_VOID * driverBuf, _VOID * userBuf,
                    228:                                size_t byteCount)
                    229: #else
                    230: static int
                    231: copyoutEfault(driverBuf, userBuf, byteCount)
                    232: _VOID * driverBuf;
                    233: _VOID * userBuf;
                    234: size_t byteCount;
                    235: #endif
                    236: {
                    237:        size_t result;
                    238: 
                    239:        result = copyout(driverBuf, userBuf, byteCount);
                    240:        if (result)
                    241:                u.u_error = EFAULT;
                    242:        return result;
                    243: }
                    244: 
                    245: /*******************************************************************
                    246:  * patchioctl()
                    247:  *
                    248:  * Although the type returned is int according to con.h, the
                    249:  * return value is discarded by bio.c !!!
                    250:  ******************************************************************/
                    251: #if __USE_PROTO__
                    252: static int patchioctl(dev_t __NOTUSED(dev), int com, struct patch * vec)
                    253: #else
                    254: static int
                    255: patchioctl(dev, com, vec)
                    256: dev_t  dev;
                    257: int    com;
                    258: struct patch *vec;
                    259: #endif
                    260: {
                    261:        int result;     /* ignored */
                    262: 
                    263:        struct patchVar pvar;
                    264:        struct patchCon pcon;
                    265: 
                    266:        struct patchVarInternal * pvarintp;
                    267:        struct patchConInternal * pconintp;
                    268: 
                    269:        switch (com) {
                    270:        case PATCH_WR:
                    271:                /*
                    272:                 * Write a new value to a patchable variable.
                    273:                 *      Fetch patch record from user data.
                    274:                 *      Look for variable in patch table.
                    275:                 *      Copy value from user data to kernel data.
                    276:                 */
                    277:                if (copyinEfault(vec, &pvar, sizeof(pvar)) ||
                    278:                  !(pvarintp = patchVarLookup(pvar.patch_vname)) ||
                    279:                  copyinEfault(pvar.patch_data, pvarintp->patch_addr,
                    280:                  pvarintp->patch_size))
                    281:                        result = -1;
                    282:                else
                    283:                        result = pvarintp->patch_size;
                    284:                break;
                    285:        case PATCH_RD:
                    286:                /*
                    287:                 * Read value of a patchable variable.
                    288:                 *      Fetch patch record from user data.
                    289:                 *      Look for variable in patch table.
                    290:                 *      Copy value from kernel data to user data.
                    291:                 */
                    292:                if (copyinEfault(vec, &pvar, sizeof(pvar)) ||
                    293:                  !(pvarintp = patchVarLookup(pvar.patch_vname)) ||
                    294:                  copyoutEfault(pvarintp->patch_addr, pvar.patch_data,
                    295:                  pvarintp->patch_size))
                    296:                        result = -1;
                    297:                else
                    298:                        result = pvarintp->patch_size;
                    299:                break;
                    300:        case PATCH_CON_IN:
                    301:                /*
                    302:                 * Delayed activation of a device driver.
                    303:                 *      Fetch patch record from user data.
                    304:                 *      Look for variable in patch table.
                    305:                 *      Make sure major number is valid.
                    306:                 *      Make sure user-specified major number is free.
                    307:                 *      Enter the device into the drvl table.
                    308:                 *      Call the device load routine.
                    309:                 */
                    310:                if (copyinEfault(vec, &pcon, sizeof(pcon)) ||
                    311:                  !(pconintp = patchConLookup(pcon.patch_vname)) ||
                    312:                  validMajor(pcon.patch_maj) ||
                    313:                  matchMajor(pcon.patch_maj, NULL))
                    314:                        result = -1;
                    315:                else {
                    316:                        drvl[pcon.patch_maj].d_conp =
                    317:                          (CON *)(pconintp->patch_addr);
                    318:                        (*drvl[pcon.patch_maj].d_conp->c_load)();
                    319:                        result = 0;
                    320:                }
                    321:                break;
                    322:        case PATCH_CON_OUT:
                    323:                /*
                    324:                 * Deactivation of a device driver.
                    325:                 *      Fetch patch record from user data.
                    326:                 *      Look for variable in patch table.
                    327:                 *      Make sure major number is valid.
                    328:                 *      Make sure specified device is at specified major number.
                    329:                 *      Call the device unload routine.
                    330:                 *      Delete the device from the drvl table.
                    331:                 */
                    332:                if (copyinEfault(vec, &pcon, sizeof(pcon)) ||
                    333:                  !(pconintp = patchConLookup(pcon.patch_vname)) ||
                    334:                  validMajor(pcon.patch_maj) ||
                    335:                  matchMajor(pcon.patch_maj, pconintp->patch_addr))
                    336:                        result = -1;
                    337:                else {
                    338:                        (*drvl[pcon.patch_maj].d_conp->c_uload)();
                    339:                        drvl[pcon.patch_maj].d_conp = NULL;
                    340:                        result = 0;
                    341:                }
                    342:                break;
                    343:        default:
                    344:                u.u_error = EINVAL;
                    345:                result = -1;
                    346:        }
                    347: 
                    348:        return result;  /* ignored */
                    349: }

unix.superglobalmegacorp.com

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