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

unix.superglobalmegacorp.com

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