Annotation of coherent/d/286_KERNEL/USRSRC/io/ms.c, revision 1.1

1.1     ! root        1: /* (-lgl
        !             2:  *     COHERENT Driver Kit Version 1.1.0
        !             3:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
        !             4:  *     All rights reserved. May not be copied without permission.
        !             5:  -lgl) */
        !             6: /*
        !             7:  *     Microsoft bus mouse (rodent) driver.
        !             8:  */
        !             9: 
        !            10: #include <sys/coherent.h>
        !            11: #include <sys/uproc.h>
        !            12: #include <sys/con.h>
        !            13: #include <sys/devices.h>
        !            14: #include <sys/ms.h>
        !            15: #include <errno.h>
        !            16: 
        !            17: #define Help(fmt, p)           printf(fmt, p)
        !            18: #define Help2(fmt, p, q)       printf(fmt, p, q)
        !            19: #define Diag(fmt, p)           /* Help(fmt, p) */
        !            20: #define Diag2(fmt, p, q)       /* Help2(fmt, p, q) */
        !            21: 
        !            22: /*
        !            23:  *     global patchable definitions
        !            24:  */
        !            25: unsigned MSPORT  = 0x23C;      /* mouse 8255A registers: */
        !            26:                                /* modified mouse is 0x23C */
        !            27:                                /* Geac modified mouse is 0x230 */
        !            28: unsigned MSIRQ   = 2;          /* mouse interrupt # */
        !            29: 
        !            30: /*
        !            31:  *     driver function definitions
        !            32:  */
        !            33: int    msload();
        !            34: int    msunload();
        !            35: int    msopen();
        !            36: int    msclose();
        !            37: int    msioctl();
        !            38: int    mspoll();
        !            39: int    msintr();
        !            40: int    nulldev();
        !            41: int    nonedev();
        !            42: 
        !            43: /*
        !            44:  *     configuration table
        !            45:  */
        !            46: CON mscon = {
        !            47:        DFCHR|DFPOL,                    /* flags        */
        !            48:        MS_MAJOR,                       /* major index  */
        !            49:        msopen,                         /* open         */
        !            50:        msclose,                        /* close        */
        !            51:        nonedev,                        /* block        */
        !            52:        nonedev,                        /* read         */
        !            53:        nonedev,                        /* write        */
        !            54:        msioctl,                        /* ioctl        */
        !            55:        nulldev,                        /* power fail   */
        !            56:        nulldev,                        /* timeout      */
        !            57:        msload,                         /* load         */
        !            58:        msunload,                       /* unload       */
        !            59:        mspoll                          /* poll         */
        !            60: };
        !            61: 
        !            62: /*
        !            63:  *     ioctl function definitions
        !            64:  */
        !            65: 
        !            66: int    ms_setup();
        !            67: int    ms_setcrs();
        !            68: int    ms_readcrs();
        !            69: int    ms_setmick();
        !            70: int    ms_readmick();
        !            71: int    ms_readbtns();
        !            72: int    ms_readstat();
        !            73: int    ms_wait();
        !            74: 
        !            75: int (*ioctls[])() = {
        !            76:   /*      0         1           2           3            4             */
        !            77:        ms_setup, ms_setcrs, ms_readcrs, ms_setmick, ms_readmick,
        !            78: 
        !            79:   /*        5           6         7                                    */
        !            80:        ms_readbtns, ms_readstat, ms_wait
        !            81: };
        !            82: 
        !            83: /*
        !            84:  *     hardware constants
        !            85:  */
        !            86: static int     porta;                  /*      port A (read/write) */
        !            87: static int     portb;                  /*      port B (read/write) */
        !            88: static int     portc;                  /*      port C (read/write) */
        !            89: static int     portcm;                 /*      control port (write only) */
        !            90: 
        !            91: static int     u_stts  =  0;           /* changed-status flags */
        !            92: static int     u_mask  =  0;           /* user condition mask */
        !            93: 
        !            94: static event_t ipolls;
        !            95: 
        !            96: static struct msparms parms, initparm = {
        !            97:        2, -16, 655, -16, 215, 8, 16
        !            98: };
        !            99: 
        !           100: static struct mspos crsr, csav, initcrsr = { 320, 100 };
        !           101: 
        !           102: static struct msmick mick, initmick = { 0, 0 };
        !           103: 
        !           104: static struct msbuts buttons, initbuttons = {
        !           105:        0,
        !           106:        {       {0, {320, 100}},
        !           107:                {0, {320, 100}},
        !           108:                {0, {320, 100}},
        !           109:                {0, {320, 100}}
        !           110:        }
        !           111: };
        !           112: 
        !           113: static int     ms_inuse = 0;           /* is mouse in use ? */
        !           114: 
        !           115: msload()
        !           116: {
        !           117:        int s;
        !           118: 
        !           119:        porta  = MSPORT;
        !           120:        portb  = MSPORT + 1;
        !           121:        portc  = MSPORT + 2;
        !           122:        portcm = MSPORT + 3;
        !           123: 
        !           124:        s = sphi();
        !           125:        outb( portcm, 0x91 );           /* set 8255A mode 9 */
        !           126:        outb( portc,  0x10 );           /* disable interrupt */
        !           127:        setivec( MSIRQ, msintr );       /* set up irq vector */
        !           128:        spl(s);
        !           129: 
        !           130:        return 0;
        !           131: }
        !           132: 
        !           133: /*
        !           134:  * Unload function.
        !           135:  */
        !           136: msunload()
        !           137: {
        !           138:        clrivec( MSIRQ );               /* release irq vector */
        !           139:        outb( portcm, 0x91 );           /* set 8255A mode 9 */
        !           140:        outb( portc,  0x10 );           /* disable interrupt */
        !           141: }
        !           142: 
        !           143: msopen(dev, mode)
        !           144: dev_t  dev;
        !           145: {
        !           146:        int     s;
        !           147: 
        !           148:        s = sphi(s);
        !           149:        if (ms_inuse) {
        !           150:                u.u_error = EDBUSY;
        !           151:                spl(s);
        !           152:                return( -1 );
        !           153:        }
        !           154: 
        !           155:        outb( portcm, 0x91 );                   /* set 8255A mode 9 */
        !           156:        outb( portb,  0x5a );
        !           157: 
        !           158:        if( inb( portb ) != 0x5a) {             /* hardware installed? */
        !           159:                u.u_error = ENXIO;
        !           160:                spl(s);
        !           161:                return( -1 );
        !           162:        }
        !           163: 
        !           164:        outb( portc, 0x90 );
        !           165:        inb( porta );
        !           166:        outb( portc, 0xb0 );
        !           167:        inb( porta );
        !           168:        outb( portc, 0xd0 );
        !           169:        inb( porta );
        !           170:        outb( portc, 0xf0 );
        !           171:        inb( porta );
        !           172:        outb( portc, 0 );               /* clear all mouse registers */
        !           173: 
        !           174: /* set things */
        !           175:        parms = initparm;
        !           176:        crsr = csav = initcrsr;
        !           177:        mick = initmick;
        !           178:        buttons = initbuttons;
        !           179:        u_stts = u.u_error = 0;
        !           180:        ms_inuse = 1;
        !           181:        spl(s);
        !           182: 
        !           183:        return( 0 );
        !           184: }
        !           185: 
        !           186: msclose()
        !           187: {
        !           188:        int s;
        !           189: 
        !           190:        s = sphi();
        !           191:        outb( portc, 0x10 );                    /* disable interrupt */
        !           192:        ms_inuse = u.u_error = 0;
        !           193:        spl(s);
        !           194:        return( 0 );
        !           195: }
        !           196: 
        !           197: msioctl( dev, com, vec )
        !           198: dev_t  dev;
        !           199: int    com;
        !           200: char   *vec;
        !           201: {
        !           202:        int s;
        !           203: 
        !           204:        s = sphi();
        !           205:        if (com >= 0 && com < sizeof(ioctls)/sizeof(ioctls[0])) {
        !           206:                (*ioctls[com])(vec);    /* indirect func call */
        !           207:                u.u_error = 0;
        !           208:        } else
        !           209:                u.u_error = EINVAL;
        !           210:        spl(s);
        !           211:        if (u.u_error)
        !           212:                return( -1 );
        !           213: 
        !           214:        return( 0 );
        !           215: }
        !           216: 
        !           217: /*
        !           218:  * Polling routine.
        !           219:  * [System V.3 Compatible].
        !           220:  */
        !           221: mspoll( dev, ev, msec )
        !           222: dev_t dev;
        !           223: int ev;
        !           224: int msec;
        !           225: {
        !           226:        ev &= ~POLLPRI;
        !           227:        ev &= ~POLLOUT;
        !           228: 
        !           229:        /*
        !           230:         * No input.
        !           231:         */
        !           232:        if ( (u_stts & u_mask) == 0 ) {
        !           233:                /*
        !           234:                 * Enable monitor if blocking poll.
        !           235:                 */
        !           236:                if ( msec != 0 ) 
        !           237:                        pollopen( &ipolls );
        !           238:                /*
        !           239:                 * Look again to avoid interrupt race.
        !           240:                 */
        !           241:                if ( (u_stts & u_mask) == 0 )
        !           242:                        ev &= ~POLLIN;
        !           243:        }
        !           244: 
        !           245:        return ev;
        !           246: }
        !           247: 
        !           248: /*
        !           249:  *     write setup structure
        !           250:  */
        !           251: ms_setup( newparm )
        !           252: struct msparms *newparm;
        !           253: {
        !           254:        ukcopy(newparm, &parms, sizeof(struct msparms));
        !           255:        if (parms.h_mpr == 0)
        !           256:                parms.h_mpr = 1;
        !           257:        if (parms.v_mpr == 0)
        !           258:                parms.v_mpr = 1;
        !           259: }
        !           260: 
        !           261: /*
        !           262:  *     write cursor position
        !           263:  */
        !           264: ms_setcrs( pos )
        !           265: struct mspos *pos;
        !           266: {
        !           267:        ukcopy(pos, &crsr, sizeof(struct mspos));
        !           268:        u_stts &= ~MS_S_MOVE;           /* clear u_stts pos bit */
        !           269: }
        !           270: 
        !           271: /*
        !           272:  *     read cursor postion
        !           273:  */
        !           274: ms_readcrs( pos )
        !           275: struct mspos *pos;
        !           276: {
        !           277:        kucopy(&crsr, pos, sizeof(struct mspos));
        !           278:        u_stts &= ~MS_S_MOVE;           /* clear u_stts pos bit */
        !           279: }
        !           280: 
        !           281: /*
        !           282:  *     write mickey postion
        !           283:  */
        !           284: ms_setmick( pos )
        !           285: struct msmick *pos;
        !           286: {
        !           287:        ukcopy(pos, &mick, sizeof(struct msmick));
        !           288: }
        !           289: 
        !           290: /*
        !           291:  *     read mickey postion
        !           292:  */
        !           293: ms_readmick( pos )
        !           294: struct msmick *pos;
        !           295: {
        !           296:        kucopy(&mick, pos, sizeof(struct msmick));
        !           297: }
        !           298: 
        !           299: /*
        !           300:  *     read button status
        !           301:  */
        !           302: ms_readbtns( btns )
        !           303: struct msbuts *btns;
        !           304: {
        !           305:        kucopy(&buttons, btns, sizeof(struct msbuts));
        !           306:        u_stts &= ~MS_S_BUTTONS;                /* clear u_stts button bits */
        !           307: }
        !           308: 
        !           309: /*
        !           310:  *     read "changed status" mask
        !           311:  */
        !           312: ms_readstat( stat )
        !           313: int *stat;
        !           314: {
        !           315:        kucopy(&u_stts, stat, sizeof(int));
        !           316: }
        !           317: 
        !           318: /*
        !           319:  *     wait on "changed status" mask
        !           320:  */
        !           321: ms_wait( flag )
        !           322: int *flag;
        !           323: {
        !           324:        ukcopy(flag, &u_mask, sizeof(int));
        !           325:        while ((u_mask & u_stts) == 0)  /* wait until any bit is on */
        !           326:                sleep(&u_stts, 0x7fff, 0x7fff, 0);
        !           327:        u_mask = 0;
        !           328: }
        !           329: 
        !           330: /*
        !           331:  *     mouse interrupt service routine
        !           332:  */
        !           333: msintr()
        !           334: {
        !           335:        static  int h_fpix =  0;                        /* fractional pixel */
        !           336:        static  int v_fpix = 0;                         /* ditto */
        !           337:        int     s, n_l, n_h, h_diff, v_diff, tmp, left, right;
        !           338: 
        !           339:        if (!ms_inuse)                  /* dev not open - ignore interrupts */
        !           340:                return;
        !           341:        
        !           342:        s = sphi();
        !           343:        outb( portc, 0x90 );            /* get horizontal change */
        !           344:        n_l = inb( porta );
        !           345:        outb( portc, 0xb0 );
        !           346:        n_h = inb( porta );
        !           347:        h_diff = (char) ((n_l & 0x0f) | (n_h << 4));
        !           348: 
        !           349:        outb( portc, 0xd0 );            /* get vertical change */
        !           350:        n_l = inb( porta );
        !           351:        outb( portc, 0xf0 );
        !           352:        n_h = inb( porta );
        !           353:        v_diff = (char) ((n_l & 0x0f) | (n_h << 4));
        !           354: 
        !           355:        outb( portc, 0 );
        !           356:        left = right = 0;                               /* set button status */
        !           357:        if (!(n_h & 0x80)) left = MS_L_DOWN;            /* left button.. */
        !           358:        if ((buttons.bbstat & MS_L_DOWN) ^ left) {
        !           359:                if (left)
        !           360:                        button(MS_B_L_PRESS,   MS_S_L_PRESS);
        !           361:                else
        !           362:                        button(MS_B_L_RELEASE, MS_S_L_RELEASE);
        !           363:        }
        !           364:        if (!(n_h & 0x20))                              /* right button.. */
        !           365:                right = MS_R_DOWN;
        !           366:        if ((buttons.bbstat & MS_R_DOWN) ^ right) {
        !           367:                if (right)
        !           368:                        button(MS_B_R_PRESS,   MS_S_R_PRESS);
        !           369:                else
        !           370:                        button(MS_B_R_RELEASE, MS_S_R_RELEASE);
        !           371:        }
        !           372: 
        !           373:        buttons.bbstat = left | right;          /* set new button status */
        !           374: 
        !           375:        if (h_diff || v_diff) {                 /* any motion? */
        !           376:                mick.h_mick += h_diff;          /* yes - update positions */
        !           377:                mick.v_mick += v_diff;
        !           378:                if ((abs(h_diff) > parms.accel_t) || (abs(v_diff) > parms.accel_t)) {
        !           379:                        h_diff *= 2;
        !           380:                        v_diff *= 2;
        !           381:                }
        !           382: 
        !           383:                if (h_diff) {                   /* horizontal change */
        !           384:                        tmp   = h_fpix + 8 * h_diff;
        !           385:                        h_fpix = tmp % parms.h_mpr;
        !           386:                        tmp    = crsr.h_crsr + tmp / parms.h_mpr;
        !           387:                        crsr.h_crsr = c_range(tmp, parms.h_cmin, parms.h_cmax);
        !           388:                }
        !           389: 
        !           390:                if (v_diff) {                   /* vertical change */                                                                                                                                                                                           
        !           391:                        tmp   = v_fpix + 8 * v_diff;
        !           392:                        v_fpix = tmp % parms.v_mpr;
        !           393:                        tmp    = crsr.v_crsr + tmp / parms.v_mpr;
        !           394:                        crsr.v_crsr = c_range(tmp, parms.v_cmin, parms.v_cmax);
        !           395:                }
        !           396: 
        !           397:                if ((crsr.h_crsr != csav.h_crsr) || (crsr.v_crsr != csav.v_crsr)) {
        !           398:                        u_stts |= MS_S_MOVE;
        !           399:                        csav = crsr;
        !           400:                }
        !           401:        }
        !           402: 
        !           403:        if (u_stts & u_mask) {
        !           404:                wakeup(&u_stts);
        !           405:                if ( ipolls.e_procp )
        !           406:                        pollwake( &ipolls );
        !           407:        }
        !           408: 
        !           409:        spl(s);
        !           410: }
        !           411: 
        !           412: /*
        !           413:  *     update button-press/release data
        !           414:  */
        !           415: button( bp, sbit )
        !           416: int bp;
        !           417: unsigned sbit;
        !           418: {
        !           419:        ++buttons.buts[bp].cnt;
        !           420:        buttons.buts[bp].bpos = crsr;
        !           421:        u_stts |= sbit;
        !           422: }
        !           423: 
        !           424: /*
        !           425:  *     force return value to be within specified range
        !           426:  */
        !           427: c_range(c, cmin, cmax)
        !           428: int    c, cmin, cmax;
        !           429: {
        !           430:        if( c < cmin )
        !           431:                c = cmin;
        !           432:        else if( c > cmax )
        !           433:                c = cmax;
        !           434:        return( c );
        !           435: }
        !           436: 
        !           437: abs(i)
        !           438: int i;
        !           439: {
        !           440:        if (i < 0)
        !           441:                return (-i);
        !           442:        return i;
        !           443: }

unix.superglobalmegacorp.com

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