Annotation of coherent/b/STREAMS/conf/patch/src/patch.c, revision 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.