Annotation of researchv10no/sys/io/bda.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * DSA port driver for KDB50 (aka BDA)
                      3:  * called by, e.g., ra.c
                      4:  */
                      5: 
                      6: #include "sys/param.h"
                      7: #include "sys/buf.h"
                      8: #include "sys/biic.h"
                      9: #include "sys/biaddr.h"
                     10: #include "sys/map.h"
                     11: #include "sys/bda.h"
                     12: #include "sys/mscp.h"
                     13: #include "sys/pte.h"
                     14: 
                     15: #define        hiword(x)       (((long)(x)>>16)&0177777)
                     16: #define        loword(x)       ((long)(x)&0177777)
                     17: 
                     18: extern struct biaddr bdaddr[];
                     19: extern struct bd bd[];
                     20: extern int bdcnt;
                     21: struct ctab {
                     22:        int (*c_seql)();
                     23:        int (*c_dg)();
                     24:        int c_ctype;
                     25: } bdctab[MSMAXID];
                     26: 
                     27: /*
                     28:  * bd_flags
                     29:  */
                     30: 
                     31: #define        UINIT   01              /* already did trivial init */
                     32: #define        UIDONE  02              /* initialization all done */
                     33: #define        UPWAIT  04              /* waiting for command packet */
                     34: #define        UFIRST  010             /* let first packet go even if no credits */
                     35: #define        UTIMER  020             /* timer will kick on next go */
                     36: #define        UCWAIT  040             /* waiting for credits */
                     37: #define        UPMWAIT 0100            /* waiting for map */
                     38: 
                     39: #define        NOBACK  (-1)
                     40: 
                     41: /*
                     42:  * bd_cbusy
                     43:  */
                     44: 
                     45: #define        FREE    0
                     46: #define        NABBED  01
                     47: #define        SENT    02
                     48: #define        MAPPED  04
                     49: 
                     50: /*
                     51:  * bdip is really bigpr0 in struct biic
                     52:  */
                     53: 
                     54: struct device {
                     55:        short   bdxx;   /* unused */
                     56:        short   bdip;
                     57:        short   bdsar;
                     58:        short   bdsaw;
                     59: };
                     60: 
                     61: #define        bdaregs(p) ((struct device *)&((p)->bigpr0))
                     62: 
                     63: /*
                     64:  * bits in bdsa (variously read and write half)
                     65:  */
                     66: 
                     67: #define        ERR     0100000
                     68: #define        STEP4   040000
                     69: #define        STEP3   020000
                     70: #define        STEP2   010000
                     71: #define        STEP1   04000
                     72: #define        STEPS   (STEP1|STEP2|STEP3|STEP4)
                     73: 
                     74: #define        IE      0200            /* step1 interrupt enable */
                     75: #define        PI      01              /* step2 purge intr enab */
                     76: #define        GO      01              /* step4 ok */
                     77: 
                     78: /*
                     79:  * bda communication area
                     80:  * ring sizes are chosen so that,
                     81:  * with 4K byte buffers,
                     82:  * one bdcomm + CSIZE-sized command packets will
                     83:  * fit in one buffer;
                     84:  * RSIZE-sized response packets
                     85:  * will fit in another
                     86:  *
                     87:  * ring sizes must be powers of 2
                     88:  * (they are passed as such to the port)
                     89:  *
                     90:  * a delicacy:
                     91:  * command packets should not cross 64Kb boundaries.
                     92:  * it is believed that the KDB50 gets it wrong if they do.
                     93:  * hence, make CSIZE+4 evenly divide a page,
                     94:  * and get it aligned sensibly in bdreset
                     95:  */
                     96: 
                     97: #define        NCP2    5
                     98: #define        NRP2    5
                     99: #define        NCMD    (1<<NCP2)
                    100: #define        NRSP    (1<<NRP2)
                    101: 
                    102: struct bdcomm {
                    103:        short   bd__r0;         /* reserved (ugh) */
                    104:        char    bd__r1;
                    105:        char    bd_bdp;         /* path to purge */
                    106:        short   bd_cmdint;      /* flag for command interrupt */
                    107:        short   bd_rspint;      /* flag for response interrupt */
                    108:        long    bd_rsp[NRSP];   /* response pointer ring */
                    109:        long    bd_cmd[NCMD];   /* command pointer ring */
                    110: };
                    111: 
                    112: /*
                    113:  * bits in ring pointers
                    114:  */
                    115: 
                    116: #define        DPOWN   0x80000000      /* port owns descriptor */
                    117: #define        DIE     0x40000000      /* ring transition intr enab */
                    118: 
                    119: #define        BDAVIRT 0x80000000      /* in m_buff: mapped transfer */
                    120: #define        V       0x80000000      /* valid bit in page map */
                    121: 
                    122: #define        CSIZE   60      /* max size of command packet */
                    123: #define        RSIZE   60      /* max size of response packet */
                    124: #define        HDRSIZE 4       /* size of the header */
                    125: 
                    126: struct bdcmd {
                    127:        short   uc_len;         /* length of message */
                    128:        char    uc_tc;          /* type, credits */
                    129:        char    uc_cid;         /* connection id */
                    130:        char    uc_data[CSIZE];
                    131: };
                    132: 
                    133: struct bdrsp {
                    134:        short   ur_len;         /* length of message */
                    135:        char    ur_tc;          /* type, credits */
                    136:        char    ur_cid;         /* connection id */
                    137:        char    ur_data[RSIZE];
                    138: };
                    139: 
                    140: /*
                    141:  * message types
                    142:  */
                    143: 
                    144: #define        MTYPE   0xf0            /* where type lives */
                    145: #define        MTSEQL  0x00            /* sequential message */
                    146: #define        MTDG    0x10            /* datagram */
                    147: #define        MTCR    0x20            /* credit notification */
                    148: 
                    149: #define        MTNC    0xf             /* credits in tc */
                    150: 
                    151: /*
                    152:  * etc
                    153:  */
                    154: 
                    155: #define        PRIINI  (PZERO-3)
                    156: #define        PRIPKT  (PZERO-2)
                    157: #define        PRICRED (PZERO-1)
                    158: 
                    159: /*
                    160:  * command packet to index
                    161:  */
                    162: #define        bdmptoi(up, mp) ((struct bdcmd *)((char *)(mp) - HDRSIZE) - (up)->bd_cpkt)
                    163: 
                    164: #define        TIMEOUT 10              /* time between checks */
                    165: 
                    166: int bdinit(), bdsend(), bdmap(), bdunmap();
                    167: struct mscmd *bdgpkt();
                    168: struct msportsw bdport = {
                    169:        bdinit, bdgpkt, bdmap, bdsend, bdunmap
                    170: };
                    171: 
                    172: /*
                    173:  * init the port
                    174:  * called once only
                    175:  * returns nonzero if probably ok
                    176:  * allowed to sleep
                    177:  */
                    178: 
                    179: bdinit(dev, type, force, cid, seql, dg)
                    180: unsigned int dev;
                    181: unsigned int cid;
                    182: int force;
                    183: int (*seql)(), (*dg)();
                    184: {
                    185:        register struct bd *up;
                    186:        struct buf *geteblk();
                    187:        extern bdtimer();
                    188: 
                    189:        if (dev >= bdcnt)
                    190:                return (0);
                    191:        if (cid >= MSMAXID)
                    192:                return (0);
                    193:        bdctab[cid].c_seql = seql;
                    194:        bdctab[cid].c_dg = dg;
                    195:        bdctab[cid].c_ctype = type;
                    196:        up = &bd[dev];
                    197:        if (up->bd_flags & UINIT && force == 0)
                    198:                return (1);
                    199:        if ((up->bd_addr = (struct biic *)biaddr(&bdaddr[dev])) == 0) {
                    200:                printf("bd%d absent\n", dev);
                    201:                return (0);
                    202:        }
                    203:        bdrundown(dev);
                    204:        if ((up->bd_flags & UINIT) == 0) {
                    205:                up->bd_cbuf = geteblk();
                    206:                clrbuf(up->bd_cbuf);
                    207:                up->bd_rbuf = geteblk();
                    208:                clrbuf(up->bd_rbuf);
                    209:                up->bd_mbuf = geteblk();
                    210:                clrbuf(up->bd_mbuf);
                    211:                up->bd_comm = (struct bdcomm *)up->bd_cbuf->b_un.b_addr;
                    212: #define        BDCOFF  (((sizeof(struct bdcomm)/sizeof(struct bdcmd))+1)*sizeof(struct bdcmd))
                    213:                up->bd_cpkt = (struct bdcmd *)(up->bd_cbuf->b_un.b_addr + BDCOFF);
                    214:                up->bd_rpkt = (struct bdrsp *)up->bd_rbuf->b_un.b_addr;
                    215:                up->bd_pmap = (long *)up->bd_mbuf->b_un.b_addr;
                    216:                up->bd_flags |= UINIT;
                    217:                timeout(bdtimer, (caddr_t)dev, TIMEOUT * HZ);
                    218:        }
                    219:        bdreset(dev);
                    220:        return (1);
                    221: }
                    222: 
                    223: /*
                    224:  * reset device
                    225:  * initially or after error or power fail
                    226:  *
                    227:  * just kick the device here;
                    228:  * ideally we would get an interrupt when self-test finishes
                    229:  * (step 1 starts) but we don't, so let the timer routine catch it
                    230:  */
                    231: 
                    232: bdreset(dev)
                    233: register int dev;
                    234: {
                    235:        register struct bd *up;
                    236: 
                    237:        up = &bd[dev];
                    238:        up->bd_flags &=~ UIDONE;
                    239:        up->bd_addr->bicsr |= BINRST;   /* hard reset */
                    240: }
                    241: 
                    242: /*
                    243:  * finish up init, step by step
                    244:  * called from interrupt code
                    245:  */
                    246: 
                    247: bdinintr(dev)
                    248: register int dev;
                    249: {
                    250:        register struct bd *up;
                    251:        register struct device *rp;
                    252:        register struct biic *bi;
                    253: 
                    254:        up = &bd[dev];
                    255:        rp = bdaregs(up->bd_addr);
                    256:        if (up->bd_flags & UIDONE)
                    257:                printf("bd%d: unexpected init: sa %o\n", dev, rp->bdsar);
                    258:        switch (rp->bdsar & STEPS) {
                    259:        case STEP1:
                    260:                up->bd_cnext = 0;
                    261:                up->bd_rnext = 0;
                    262:                up->bd_credits = 0;
                    263:                bi = up->bd_addr;
                    264:                biinit(&bdaddr[dev], 0);
                    265:                bi->biuir = bdaddr[dev].vec;
                    266:                bi->bieir = (bdaddr[dev].vec + sizeof(long))|EIBR5;
                    267:                rp->bdsaw = ERR | IE | (NCP2<<11) | (NRP2<<8);
                    268:                return;
                    269: 
                    270:        case STEP2:
                    271:                rp->bdsaw = PI | loword(physadr(up->bd_comm->bd_rsp));
                    272:                return;
                    273: 
                    274:        case STEP3:
                    275:                rp->bdsaw = hiword(physadr(up->bd_comm->bd_rsp));
                    276:                return;
                    277: 
                    278:        case STEP4:
                    279:                rp->bdsaw = GO;
                    280:                for (dev = 0; dev < NCMD; dev++) {
                    281:                        up->bd_comm->bd_cmd[dev] = 0;   /* unnecessary */
                    282:                        up->bd_cpkt[dev].uc_len = CSIZE;
                    283:                        up->bd_back[dev] = NOBACK;
                    284:                }
                    285:                for (dev = 0; dev < NRSP; dev++) {
                    286:                        up->bd_rpkt[dev].ur_len = RSIZE;
                    287:                        up->bd_comm->bd_rsp[dev] = physadr(up->bd_rpkt[dev].ur_data) | DIE | DPOWN;
                    288:                }
                    289:                up->bd_flags |= UIDONE | UFIRST;
                    290:                rminit(up->bd_map, BDANMAP, (up->bd_mbuf->b_bcount/sizeof(long))-1, 1);
                    291:                wakeup((caddr_t)up);
                    292:                return;
                    293: 
                    294:        default:
                    295:                printf("bd%d init bad: sar %o\n", dev, rp->bdsar);
                    296:                return;
                    297:        }
                    298: }
                    299: 
                    300: /*
                    301:  * tell the class drivers that the controller was reset
                    302:  * so they can clean up
                    303:  * called after controller is stopped (so it's safe to unmap things)
                    304:  */
                    305: bdrundown(dev)
                    306: int dev;
                    307: {
                    308:        static struct msend me;
                    309:        register int i;
                    310: 
                    311:        me.m_sts = STRST;       /* magic */
                    312:        for (i = 0; i < MSMAXID; i++)
                    313:                if (bdctab[i].c_seql)
                    314:                        (*bdctab[i].c_seql)(dev, bdctab[i].c_ctype, &me);
                    315: }
                    316: 
                    317: /*
                    318:  * allocate a packet
                    319:  * and sufficient resources to send it
                    320:  * eg credits
                    321:  * may sleep
                    322:  *
                    323:  * somewhat silly assumption:
                    324:  * class driver will allocate a packet, and send it right away or nearly so
                    325:  */
                    326: 
                    327: struct mscmd *
                    328: bdgpkt(dev)
                    329: int dev;
                    330: {
                    331:        register struct bd *up;
                    332:        register int i;
                    333:        int s;
                    334: 
                    335:        up = &bd[dev];
                    336:        s = spl6();
                    337:        while ((up->bd_flags & UIDONE) == 0)
                    338:                sleep((caddr_t)up, PRIINI);
                    339:        while (up->bd_credits < 2 && (up->bd_flags & UFIRST) == 0) {
                    340:                if (bdpkscan(dev, 1))
                    341:                        continue;
                    342:                up->bd_flags |= UCWAIT;
                    343:                sleep((caddr_t)&up->bd_credits, PRICRED);
                    344:        }
                    345:        if ((up->bd_flags & UFIRST) == 0)
                    346:                up->bd_credits--;
                    347:        for (;;) {
                    348:                for (i = 0; i < NCMD; i++)
                    349:                        if (up->bd_cbusy[i] == FREE)
                    350:                                break;
                    351:                if (i < NCMD)
                    352:                        break;
                    353:                if (bdpkscan(dev, 1) == 0 && bdcmdscan(dev) == 0) {     /* kludge for hung controller */
                    354:                        up->bd_flags |= UPWAIT;
                    355:                        sleep((caddr_t)up->bd_cbusy, PRIPKT);
                    356:                }
                    357:        }
                    358:        up->bd_cbusy[i] = NABBED;
                    359:        splx(s);
                    360:        return ((struct mscmd *)up->bd_cpkt[i].uc_data);
                    361: }
                    362: 
                    363: /*
                    364:  * map a transfer if need be
                    365:  * and record in the buffer descriptor of a packet
                    366:  * may sleep
                    367:  *
                    368:  * BDA use of m_buff:
                    369:  *     first longword is buffer address;
                    370:  *             if BDAVIRT clear, physical addr, else virtual
                    371:  *     second longword is phys addr of base of page table if virtual
                    372:  *
                    373:  * subtlety: pretend we mapped it even if we didn't,
                    374:  * so it won't be unmapped until someone calls bdunmap
                    375:  * else they may be confused when they call it anyway
                    376:  */
                    377: 
                    378: bdmap(dev, mp, bp)
                    379: int dev;
                    380: struct mscmd *mp;
                    381: register struct buf *bp;
                    382: {
                    383:        register int i;
                    384:        register long *b;
                    385:        register struct pte *pt;
                    386:        int s;
                    387:        int base;
                    388:        register int size;
                    389:        register struct bd *up;
                    390: 
                    391:        up = &bd[dev];
                    392:        i = bdmptoi(up, mp);
                    393:        up->bd_cbusy[i] |= MAPPED;
                    394:        if ((bp->b_flags & (B_PHYS|B_UAREA|B_PAGET|B_DIRTY)) == 0) {
                    395:                b = (long *)&mp->m_buff;
                    396:                *b++ = (long)bp->b_un.b_addr|BDAVIRT;
                    397:                *b++ = physadr(Sysmap);
                    398:                *b = 0;
                    399:                return;
                    400:        }
                    401:        size = btoc(bp->b_bcount);
                    402:        if ((long)bp->b_un.b_addr & PGOFSET)
                    403:                size++;                 /* unaligned */
                    404:        s = spl6();
                    405:        while ((base = rmalloc(up->bd_map, size)) == 0) {
                    406:                up->bd_flags |= UPMWAIT;
                    407:                sleep((caddr_t)up->bd_map, PRIPKT);
                    408:        }
                    409:        splx(s);
                    410:        up->bd_mbase[i] = base;
                    411:        up->bd_msize[i] = size;
                    412:        b = &up->bd_pmap[base];
                    413:        pt = btopte(bp);
                    414:        while (--size >= 0)
                    415:                *b++ = pt++->pg_pfnum | V;
                    416:        b = (long *)&mp->m_buff;
                    417:        *b++ = ctob(base)|((long)bp->b_un.b_addr&PGOFSET)|BDAVIRT;
                    418:        *b++ = physadr(up->bd_pmap);
                    419:        *b = 0;
                    420: }
                    421: 
                    422: /*
                    423:  * free a mapped packet
                    424:  */
                    425: 
                    426: bdunmap(dev, mp)
                    427: int dev;
                    428: struct mscmd *mp;
                    429: {
                    430:        register struct bd *up;
                    431:        register int i;
                    432: 
                    433:        up = &bd[dev];
                    434:        i = bdmptoi(up, mp);
                    435:        if (up->bd_cbusy[i] == FREE)
                    436:                return;         /* wasn't mapped, and already freed */
                    437:        if (up->bd_msize[i]) {
                    438:                rmfree(up->bd_map, up->bd_msize[i], up->bd_mbase[i]);
                    439:                up->bd_msize[i] = 0;
                    440:                if (up->bd_flags & UPMWAIT) {
                    441:                        up->bd_flags &=~ UPMWAIT;
                    442:                        wakeup((caddr_t)up->bd_map);
                    443:                }
                    444:        }
                    445:        up->bd_cbusy[i] = FREE;
                    446:        if (up->bd_flags & UPWAIT) {
                    447:                up->bd_flags &=~ UPWAIT;
                    448:                wakeup((caddr_t)up->bd_cbusy);
                    449:        }
                    450: }
                    451: 
                    452: /*
                    453:  * send a packet
                    454:  * may not sleep
                    455:  * call at spl5
                    456:  */
                    457: 
                    458: bdsend(dev, cid, mp)
                    459: int dev;
                    460: int cid;
                    461: struct mscmd *mp;
                    462: {
                    463:        register struct bd *up;
                    464:        register int i;
                    465:        register int j;
                    466: 
                    467:        up = &bd[dev];
                    468:        up->bd_flags &=~ UFIRST;
                    469:        i = bdmptoi(up, mp);
                    470:        up->bd_cpkt[i].uc_cid = cid;
                    471:        j = up->bd_cnext++;
                    472:        if (up->bd_cnext >= NCMD)
                    473:                up->bd_cnext = 0;
                    474:        if (up->bd_comm->bd_cmd[j] & DPOWN)
                    475:                panic("bdsend");
                    476:        if (up->bd_back[j] >= 0) {      /* ran for a while with no free */
                    477:                bdcmdscan(dev);
                    478:                if (up->bd_back[j] >= 0)
                    479:                        panic("bdsend");
                    480:        }
                    481:        up->bd_back[j] = i;
                    482:        up->bd_comm->bd_cmd[j] = DPOWN | DIE | physadr(mp);
                    483:        up->bd_cbusy[i] |= SENT;
                    484:        up->bd_cbusy[i] &=~ NABBED;
                    485:        i = bdaregs(up->bd_addr)->bdip;         /* initiate polling */
                    486: }
                    487: 
                    488: /*
                    489:  * interrupt routine
                    490:  */
                    491: 
                    492: long bd_spur;
                    493: int bdspl;
                    494: 
                    495: bd0int(dev)
                    496: int dev;
                    497: {
                    498:        register struct bd *up;
                    499:        register struct device *rp;
                    500: 
                    501:        bdspl = mfpr(0x12);
                    502:        up = &bd[dev];
                    503:        if (dev >= bdcnt || (up->bd_flags & UINIT) == 0) {
                    504:                printf("bd%d: stray intr\n", dev);
                    505:                return;
                    506:        }
                    507:        rp = bdaregs(up->bd_addr);
                    508:        if (rp->bdsar & ERR) {
                    509:                printf("bd%d: hard error %o\n", dev, rp->bdsar & 0177777);
                    510:                bdreset(dev);
                    511:                return;
                    512:        }
                    513:        if (rp->bdsar & STEPS) {
                    514:                bdinintr(dev);
                    515:                return;
                    516:        }
                    517:        if (up->bd_comm->bd_cmdint == 0
                    518:        &&  up->bd_comm->bd_rspint == 0)
                    519:                bd_spur++;
                    520:        while (up->bd_comm->bd_cmdint) {
                    521:                up->bd_comm->bd_cmdint = 0;
                    522:                bdcmdscan(dev);
                    523:        }
                    524:        while (up->bd_comm->bd_rspint) {
                    525:                up->bd_comm->bd_rspint = 0;
                    526:                if (bdpkscan(dev, 0))
                    527:                        up->bd_flags &=~ UTIMER;
                    528:        }
                    529: }
                    530: 
                    531: bd1int(dev)
                    532: int dev;
                    533: {
                    534:        printf("bd%d: error intr\n", dev);
                    535: }
                    536: 
                    537: /*
                    538:  * free packets which are completely sent
                    539:  * (and which don't have associated map)
                    540:  */
                    541: 
                    542: bdcmdscan(dev)
                    543: int dev;
                    544: {
                    545:        register struct bd *up;
                    546:        register int i, j;
                    547:        register int freed;
                    548:        register struct bdcomm *bdc;
                    549: 
                    550:        up = &bd[dev];
                    551:        bdc = up->bd_comm;
                    552:        freed = 0;
                    553:        for (j = 0; j < NCMD; j++)
                    554:                if (up->bd_back[j] >= 0
                    555:                &&  (bdc->bd_cmd[j] & DPOWN) == 0) {
                    556:                        i = up->bd_back[j];
                    557:                        if ((up->bd_cbusy[i] & (SENT|MAPPED)) == SENT) {
                    558:                                up->bd_cbusy[i] = FREE;
                    559:                                freed++;
                    560:                        }
                    561:                        up->bd_back[j] = NOBACK;
                    562:                }
                    563:        if (freed && up->bd_flags & UPWAIT)
                    564:                wakeup((caddr_t)up->bd_cbusy);
                    565:        return (freed);
                    566: }
                    567: 
                    568: /*
                    569:  * check for responses from the controller
                    570:  * and deal with them
                    571:  * return a count for debugging purposes
                    572:  */
                    573: 
                    574: int
                    575: bdpkscan(dev, doall)
                    576: int dev;
                    577: int doall;
                    578: {
                    579:        register struct bd *up;
                    580:        register int i;
                    581:        int nf;
                    582:        register struct bdrsp *pk;
                    583:        register struct ctab *cp;
                    584:        register struct bdcomm *bdc;    /* speed */
                    585:        int s;
                    586: 
                    587:        up = &bd[dev];
                    588:        bdc = up->bd_comm;
                    589:        nf = 0;
                    590:        s = spl6();
                    591:        for (i = up->bd_rnext; ; i < NRSP-1 ? i++ : (i = 0)) {
                    592:                if (bdc->bd_rsp[i] & DPOWN) {
                    593:                        up->bd_rnext = i;
                    594:                        /* don't stop if doall? */
                    595:                        break;
                    596:                }
                    597:                nf++;
                    598:                pk = &up->bd_rpkt[i];
                    599:                up->bd_credits += pk->ur_tc & MTNC;
                    600:                if (up->bd_flags & UCWAIT) {
                    601:                        wakeup((caddr_t)&up->bd_credits);
                    602:                        up->bd_flags &=~ UCWAIT;
                    603:                }
                    604:                if (pk->ur_cid > MSMAXID)
                    605:                        printf("bd%d msg id %d\n", dev, pk->ur_cid);
                    606:                else {
                    607:                        cp = &bdctab[pk->ur_cid];
                    608:                        switch (pk->ur_tc & MTYPE) {
                    609:                        case MTSEQL:
                    610:                                if (cp->c_seql)
                    611:                                        (*cp->c_seql)(dev, cp->c_ctype, (struct msend *)pk->ur_data);
                    612:                                break;
                    613:                
                    614:                        case MTDG:
                    615:                                if (cp->c_dg)
                    616:                                        (*cp->c_dg)(dev, cp->c_ctype, pk->ur_data);
                    617:                                break;
                    618:                
                    619:                        /* default: ignore */
                    620:                        }
                    621:                }
                    622:                pk->ur_len = RSIZE;
                    623:                bdc->bd_rsp[i] |= DPOWN | DIE;
                    624:        }
                    625:        splx(s);
                    626:        return (nf);
                    627: }
                    628: 
                    629: /*
                    630:  * timeout routine
                    631:  * return any waiting packets
                    632:  * -- callout routines don't necessarily run at high priority.
                    633:  * hence the spl6, so bdpkscan won't be reentered
                    634:  */
                    635: 
                    636: int bd_kicked;
                    637: 
                    638: bdtimer(i)
                    639: int i;
                    640: {
                    641:        register struct bd *up;
                    642:        register int s;
                    643: 
                    644:        up = &bd[i];
                    645:        if ((up->bd_flags & UINIT) == 0)
                    646:                return;
                    647:        if ((up->bd_flags & UIDONE) == 0) {
                    648:                if ((bdaregs(up->bd_addr)->bdsar & STEPS) == STEP1)
                    649:                        bdinintr(i);
                    650:        }
                    651:        else if ((up->bd_flags & UTIMER) == 0)
                    652:                up->bd_flags |= UTIMER;
                    653:        else {
                    654:                s = spl6();
                    655:                if (bdpkscan(i, 1) && up->bd_flags & UPWAIT) {
                    656:                        wakeup((caddr_t)up->bd_cbusy);
                    657:                        bd_kicked++;
                    658:                }
                    659:                splx(s);
                    660:                up->bd_flags &=~ UTIMER;
                    661:        }
                    662:        timeout(bdtimer, (caddr_t)i, TIMEOUT * HZ);
                    663: }

unix.superglobalmegacorp.com

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