Annotation of coherent/d/PS2_KERNEL/io.286/rp.c, revision 1.1.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.