Annotation of coherent/d/286_KERNEL/USRSRC/io/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 <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.