Annotation of coherent/d/PS2_KERNEL/io.286/rp.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *     Ram Pipe Device Driver
        !             3:  */
        !             4: 
        !             5: #include <coherent.h>
        !             6: #include <con.h>
        !             7: #include <seg.h>
        !             8: #include <stat.h>
        !             9: #include <sched.h>
        !            10: #include <termio.h>
        !            11: #include <v7sgtty.h>
        !            12: #include <errno.h>
        !            13: 
        !            14: #define        MAXNRP  30              /* Maximum number of ram pipes (must be < 32) */
        !            15: #define        NCPQ    2048            /* Size of pipe in bytes */
        !            16: #define        RPMAJOR 22              /* Major device for ram pipes  */
        !            17: 
        !            18: /*
        !            19:  *     function definitions
        !            20:  */
        !            21: int    rpopen();
        !            22: int    rpread();
        !            23: int    rpwrite();
        !            24: int    rpioctl();
        !            25: int    rppoll();
        !            26: void   rpuload();
        !            27: int    nulldev();
        !            28: int    nonedev();
        !            29: 
        !            30: 
        !            31: /*
        !            32:  *     configuration table
        !            33:  */
        !            34: CON rpcon = {
        !            35:        DFCHR|DFPOL,                    /* flags        */
        !            36:        RPMAJOR,                        /* major index  */
        !            37:        rpopen,                         /* open         */
        !            38:        nulldev,                        /* close        */
        !            39:        nonedev,                        /* block        */
        !            40:        rpread,                         /* read         */
        !            41:        rpwrite,                        /* write        */
        !            42:        rpioctl,                        /* ioctl        */
        !            43:        nulldev,                        /* power fail   */
        !            44:        nulldev,                        /* timeout      */
        !            45:        nulldev,                        /* load         */
        !            46:        rpuload,                        /* unload       */
        !            47:        rppoll                          /* poll         */
        !            48: };
        !            49: 
        !            50: /*
        !            51:  *     Ram Pipe Headers
        !            52:  */
        !            53: static
        !            54: struct ring {
        !            55:        unsigned short  q_size;         /* Number of characters in queue    */
        !            56:        unsigned short  q_mask;         /* Ring buffer Mask: NCPQ-1         */
        !            57:        faddr_t         q_ifaddr;       /* Input virtual address            */
        !            58:        faddr_t         q_ofaddr;       /* Output virtual address           */
        !            59:        GATE            q_igate;        /* Read lock                        */
        !            60:        GATE            q_ogate;        /* Write lock                       */
        !            61:        event_t         q_ipoll;        /* Input polls                      */
        !            62:        event_t         q_opoll;        /* Output polls                     */
        !            63: 
        !            64: } rpq[MAXNRP];
        !            65: 
        !            66: static SEG * rpsegp;
        !            67: unsigned NRP = MAXNRP;
        !            68: 
        !            69: /*
        !            70:  * Initialization Routine
        !            71:  */
        !            72: static
        !            73: rpinit()
        !            74: {
        !            75:        register struct ring *rp;
        !            76:        faddr_t faddr;
        !            77:        paddr_t paddr;
        !            78: 
        !            79:        /*
        !            80:         * Ensure valid number of ram pipes
        !            81:         */
        !            82:        if ( NRP > MAXNRP )
        !            83:                NRP = MAXNRP;
        !            84:                
        !            85:        /*
        !            86:         * Allocate ram pipe segment, initialize ram pipe queues
        !            87:         */
        !            88:         if ( NRP != 0 ) {
        !            89:                rpsegp = salloc((fsize_t)NRP*NCPQ, SFSYST|SFHIGH|SFNSWP|SFNCLR);
        !            90: 
        !            91:                if ( rpsegp == NULL )
        !            92:                        return -1;
        !            93: 
        !            94:                paddr = rpsegp->s_paddr;
        !            95: 
        !            96:                for ( rp = &rpq[0]; rp < &rpq[NRP]; rp++, paddr += NCPQ ) {
        !            97: 
        !            98:                        faddr = ptov( paddr, (fsize_t)NCPQ );
        !            99:                        rp->q_size = 0;
        !           100:                        rp->q_mask = NCPQ - 1;
        !           101: 
        !           102:                        rp->q_ifaddr = faddr;
        !           103:                        rp->q_ofaddr = faddr;
        !           104:                }
        !           105:        }
        !           106:        return 0;
        !           107: }
        !           108: 
        !           109: /*
        !           110:  * Unload Routine.
        !           111:  */
        !           112: static void
        !           113: rpuload()
        !           114: {
        !           115:        register struct ring *rp;
        !           116: 
        !           117:        /*
        !           118:         * Release virtual address mappers.
        !           119:         */
        !           120:        for ( rp = &rpq[0]; rp < &rpq[NRP]; rp++ ) {
        !           121:                if ( rp->q_ifaddr )
        !           122:                        vrelse( rp->q_ifaddr );
        !           123:        }
        !           124: 
        !           125:        /*
        !           126:         * Release ring buffer storage.
        !           127:         */
        !           128:        if ( rpsegp != NULL ) {
        !           129:                sfree( rpsegp );
        !           130:                rpsegp = NULL;
        !           131:        }
        !           132: 
        !           133:        /*
        !           134:         * Erase private data.
        !           135:         */
        !           136:        memset( &rpq[0], 0, sizeof(rpq) );
        !           137: }
        !           138: 
        !           139: /*
        !           140:  * Open Routine
        !           141:  */
        !           142: static
        !           143: rpopen( dev, mode )
        !           144: dev_t dev;
        !           145: {
        !           146:        int s;
        !           147: 
        !           148:        s = sphi();
        !           149:        if ( rpq[0].q_mask == 0 )
        !           150:                if ( rpinit() < 0 )
        !           151:                        u.u_error = ENOSPC;
        !           152:        spl( s );
        !           153:        if ( minor(dev) >= NRP )
        !           154:                u.u_error = ENXIO;
        !           155: }
        !           156: 
        !           157: /*
        !           158:  * Ioctl Routine
        !           159:  */
        !           160: static
        !           161: rpioctl( dev, com, vec )
        !           162: dev_t dev;
        !           163: {
        !           164:        switch ( com ) {
        !           165: 
        !           166:        case TIOCQUERY:
        !           167:                putuwd( vec, rpq[ minor(dev) ].q_size );
        !           168:                return;
        !           169: 
        !           170:        case TIOCOUTQ:
        !           171:                putuwd( vec, rpq[ minor(dev) ].q_size );
        !           172:                return;
        !           173: 
        !           174:        case TIOCFLUSH:
        !           175:        case TCFLSH:
        !           176:                rpflush( &rpq[minor(dev)] );
        !           177:                return;
        !           178: 
        !           179:        default:
        !           180:                u.u_error = EINVAL;
        !           181:                return;
        !           182:        }
        !           183: }
        !           184: 
        !           185: /*
        !           186:  * Read Routine
        !           187:  */
        !           188: static
        !           189: rpread( dev, iop )
        !           190: dev_t dev;
        !           191: register IO *iop;
        !           192: {
        !           193:        register struct ring *rp;
        !           194:        unsigned n;
        !           195:        int s;
        !           196: 
        !           197:        rp = &rpq[ minor(dev) ];
        !           198:        s  = sphi();
        !           199: 
        !           200:        /*
        !           201:         * Wait until read is unlocked, and there is data to read
        !           202:         */
        !           203:        while ( (rp->q_igate[0] != 0) || ((n = rp->q_size) == 0) ) {
        !           204: 
        !           205:                /*
        !           206:                 * Non-blocking reads.
        !           207:                 */
        !           208:                if ( iop->io_flag & IONDLY ) {
        !           209:                        u.u_error = EAGAIN;
        !           210:                        return;
        !           211:                }
        !           212: 
        !           213:                ++rp->q_igate[1];
        !           214:                sleep( rp->q_igate, CVTTOUT, IVTTOUT, SVTTOUT );
        !           215:                --rp->q_igate[1];
        !           216: 
        !           217:                if ( SELF->p_ssig && nondsig() ) {      /* signal received */
        !           218: 
        !           219:                        spl( s );
        !           220:                        u.u_error = EINTR;
        !           221:                        return;
        !           222:                }
        !           223:        }
        !           224:        rp->q_igate[0] = 1;                     /* lock read gate           */
        !           225:        spl( s );
        !           226: 
        !           227:        if ( n > iop->io_ioc )                  /* more data than requested */
        !           228:                n = iop->io_ioc;
        !           229: 
        !           230:        rucopy( rp, iop->io_base, n );          /* copy data to user space  */
        !           231:        iop->io_base += n;
        !           232:        iop->io_ioc  -= n;
        !           233: 
        !           234:        if ( rp->q_ogate[1] != 0 )              /* someone waiting to write */
        !           235:                wakeup( rp->q_ogate );
        !           236:        if ( rp->q_opoll.e_procp )              /* someone polling to write */
        !           237:                pollwake( &rp->q_opoll );
        !           238: 
        !           239:        rp->q_igate[0] = 0;                     /* unlock read gate         */
        !           240: 
        !           241:        if ( rp->q_igate[1] != 0 )              /* others waiting to read   */
        !           242:                wakeup( rp->q_igate );
        !           243: }
        !           244: 
        !           245: /*
        !           246:  * Write Routine
        !           247:  */
        !           248: static
        !           249: rpwrite( dev, iop )
        !           250: dev_t dev;
        !           251: register IO *iop;
        !           252: {
        !           253:        register struct ring *rp;
        !           254:        unsigned n;
        !           255:        int s;
        !           256: 
        !           257:        rp = &rpq[ minor(dev) ];
        !           258: 
        !           259:        do {
        !           260:                s  = sphi();
        !           261:                /*
        !           262:                 * Wait until write is unlocked and 512 free slots exist
        !           263:                 */
        !           264: 
        !           265:                while ((rp->q_ogate[0] != 0) || ((n = NCPQ-rp->q_size) < 512)) {
        !           266: 
        !           267:                        /*
        !           268:                         * Non-blocking writes.
        !           269:                         */
        !           270:                        if ( iop->io_flag & IONDLY ) {
        !           271:                                u.u_error = EAGAIN;
        !           272:                                return;
        !           273:                        }
        !           274: 
        !           275:                        ++rp->q_ogate[1];
        !           276:                        sleep( rp->q_ogate, CVTTOUT, IVTTOUT, SVTTOUT );
        !           277:                        --rp->q_ogate[1];
        !           278: 
        !           279:                        if (SELF->p_ssig && nondsig()) { /* received signal */
        !           280: 
        !           281:                                spl( s );
        !           282:                                u.u_error = EINTR;
        !           283:                                return;
        !           284:                        }
        !           285:                }
        !           286:                rp->q_ogate[0] = 1;             /* lock write gate           */
        !           287:                spl( s );
        !           288: 
        !           289:                if ( n > iop->io_ioc )
        !           290:                        n = iop->io_ioc;
        !           291: 
        !           292:                urcopy( iop->io_base, rp, n );  /* copy data from user space */
        !           293:                iop->io_base += n;
        !           294:                iop->io_ioc  -= n;
        !           295: 
        !           296:                rp->q_ogate[0] = 0;             /* unlock write gate         */
        !           297: 
        !           298:                if ( rp->q_igate[1] != 0 )      /* someone waiting to read   */
        !           299:                        wakeup( rp->q_igate );
        !           300: 
        !           301:                if ( rp->q_ipoll.e_procp )      /* someone polling to read */
        !           302:                        pollwake( &rp->q_ipoll );
        !           303: 
        !           304:        } while ( iop->io_ioc != 0 );           /* until all data copied     */
        !           305: 
        !           306:        if (rp->q_ogate[1] != 0)                /* someone waiting to write  */
        !           307:                wakeup( rp->q_ogate );
        !           308: }
        !           309: 
        !           310: /*
        !           311:  * Poll.
        !           312:  */
        !           313: rppoll( dev, ev, msec )
        !           314: dev_t dev;
        !           315: int ev;
        !           316: int msec;
        !           317: {
        !           318:        register struct ring *rp = &rpq[ minor(dev) ];
        !           319: 
        !           320:        ev &= ~POLLPRI;
        !           321: 
        !           322:        /*
        !           323:         * Input poll.
        !           324:         */
        !           325:        if ( ev & POLLIN ) {
        !           326: 
        !           327:                /*
        !           328:                 * Pipe empty.
        !           329:                 */
        !           330:                if ( FP_OFF(rp->q_ifaddr) == FP_OFF(rp->q_ofaddr) ) {
        !           331:                        if ( msec != 0 )
        !           332:                                pollopen( &rp->q_ipoll );
        !           333:                        ev &= ~POLLIN;
        !           334:                }
        !           335:        }
        !           336: 
        !           337:        /*
        !           338:         * Output poll.
        !           339:         */
        !           340:        if ( ev & POLLOUT ) {
        !           341: 
        !           342:                /*
        !           343:                 * Pipe not empty.
        !           344:                 */
        !           345:                if ( FP_OFF(rp->q_ifaddr) != FP_OFF(rp->q_ofaddr) ) {
        !           346:                        if ( msec != 0 )
        !           347:                                pollopen( &rp->q_opoll );
        !           348:                        ev &= ~POLLOUT;
        !           349:                }
        !           350:        }
        !           351: 
        !           352:        return ev;
        !           353: }
        !           354: 
        !           355: /*
        !           356:  * Flush queue
        !           357:  */
        !           358: static
        !           359: rpflush( rp )
        !           360: register struct ring *rp;
        !           361: {
        !           362:        register int s;
        !           363: 
        !           364:        s = sphi();
        !           365: 
        !           366:        /*
        !           367:         * Wait until read is unlocked, or nothing in queue
        !           368:         */
        !           369: 
        !           370:        while ((rp->q_size != 0) && (rp->q_igate[0] != 0) ) {
        !           371: 
        !           372:                ++rp->q_igate[1];
        !           373:                sleep( rp->q_igate, CVTTOUT, IVTTOUT, SVTTOUT );
        !           374:                --rp->q_igate[1];
        !           375: 
        !           376:                if (SELF->p_ssig && nondsig()) { /* received signal        */
        !           377: 
        !           378:                        spl( s );
        !           379:                        u.u_error = EINTR;
        !           380:                        return;
        !           381:                }
        !           382:        }
        !           383: 
        !           384:        if (rp->q_size != 0) {                  /* flush ram pipe          */
        !           385: 
        !           386:                rp->q_ofaddr = rp->q_ifaddr;
        !           387:                rp->q_size = 0;
        !           388:        }
        !           389:        spl( s );
        !           390: 
        !           391:        if (rp->q_ogate[1] != 0)                /* someone waiting to write */
        !           392:                wakeup( rp->q_ogate );
        !           393: 
        !           394:        if ( rp->q_opoll.e_procp )              /* someone polling to write */
        !           395:                pollwake( &rp->q_opoll );
        !           396: }

unix.superglobalmegacorp.com

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