Annotation of lucent/sys/src/boot/pc/ether509.c, revision 1.1.1.1

1.1       root        1: #include "u.h"
                      2: #include "lib.h"
                      3: #include "mem.h"
                      4: #include "dat.h"
                      5: #include "fns.h"
                      6: #include "io.h"
                      7: 
                      8: #include "ether.h"
                      9: 
                     10: enum {
                     11:        IDport          = 0x0110,       /* anywhere between 0x0100 and 0x01F0 */
                     12:                                        /* CommandRs */
                     13:        GlobalReset     = 0x00,         /* Global Reset */
                     14:        SelectWindow    = 0x01,         /* SelectWindow command */
                     15:        StartCoax       = 0x02,         /* Start Coaxial Transceiver */
                     16:        RxDisable       = 0x03,         /* RX Disable */
                     17:        RxEnable        = 0x04,         /* RX Enable */
                     18:        RxReset         = 0x05,         /* RX Reset */
                     19:        RxDiscard       = 0x08,         /* RX Discard Top Packet */
                     20:        TxEnable        = 0x09,         /* TX Enable */
                     21:        TxDisable       = 0x0A,         /* TX Disable */
                     22:        TxReset         = 0x0B,         /* TX Reset */
                     23:        AckIntr         = 0x0D,         /* Acknowledge Interrupt */
                     24:        SetIntrMask     = 0x0E,         /* Set Interrupt Mask */
                     25:        SetReadZeroMask = 0x0F,         /* Set Read Zero Mask */
                     26:        SetRxFilter     = 0x10,         /* Set RX Filter */
                     27:        SetTxAvailable  = 0x12,         /* Set TX Available Threshold */
                     28: 
                     29:                                        /* RX Filter CommandR Bits */
                     30:        MyEtherAddr     = 0x01,         /* Individual address */
                     31:        Multicast       = 0x02,         /* Group (multicast) addresses */
                     32:        Broadcast       = 0x04,         /* Broadcast address */
                     33:        Promiscuous     = 0x08,         /* All addresses (promiscuous mode */
                     34: 
                     35:                                        /* Window Register Offsets */
                     36:        CommandR        = 0x0E,         /* all windows */
                     37:        Status          = 0x0E,
                     38: 
                     39:        ManufacturerID  = 0x00,         /* window 0 */
                     40:        ProductID       = 0x02,
                     41:        ConfigControl   = 0x04,
                     42:        AddressConfig   = 0x06,
                     43:        ResourceConfig  = 0x08,
                     44:        EEPROMcmd       = 0x0A,
                     45:        EEPROMdata      = 0x0C,
                     46: 
                     47:                                        /* AddressConfig Bits */
                     48:        XcvrTypeMask    = 0xC000,       /* Transceiver Type Select */
                     49:        Xcvr10BaseT     = 0x0000,
                     50:        XcvrAUI         = 0x4000,
                     51:        XcvrBNC         = 0xC000,
                     52: 
                     53:                                        /* ConfigControl */
                     54:        Rst             = 0x04,         /* Reset Adapter */
                     55:        Ena             = 0x01,         /* Enable Adapter */
                     56: 
                     57:        TxFreeBytes     = 0x0C,         /* window 1 */
                     58:        TxStatus        = 0x0B,
                     59:        Timer           = 0x0A,
                     60:        RxStatus        = 0x08,
                     61:        Fifo            = 0x00,
                     62: 
                     63:                                        /* Status/Interrupt Bits */
                     64:        Latch           = 0x0001,       /* Interrupt Latch */
                     65:        Failure         = 0x0002,       /* Adapter Failure */
                     66:        TxComplete      = 0x0004,       /* TX Complete */
                     67:        TxAvailable     = 0x0008,       /* TX Available */
                     68:        RxComplete      = 0x0010,       /* RX Complete */
                     69:        AllIntr         = 0x00FE,       /* All Interrupt Bits */
                     70:        CmdInProgress   = 0x1000,       /* CommandR In Progress */
                     71: 
                     72:                                        /* TxStatus Bits */
                     73:        TxJabber        = 0x20,         /* Jabber Error */
                     74:        TxUnderrun      = 0x10,         /* Underrun */
                     75:        TxMaxColl       = 0x08,         /* Maximum Collisions */
                     76: 
                     77:                                        /* RxStatus Bits */
                     78:        RxByteMask      = 0x07FF,       /* RX Bytes (0-1514) */
                     79:        RxErrMask       = 0x3800,       /* Type of Error: */
                     80:        RxErrOverrun    = 0x0000,       /*   Overrrun */
                     81:        RxErrOversize   = 0x0800,       /*   Oversize Packet (>1514) */
                     82:        RxErrDribble    = 0x1000,       /*   Dribble Bit(s) */
                     83:        RxErrRunt       = 0x1800,       /*   Runt Packet */
                     84:        RxErrFraming    = 0x2000,       /*   Alignment (Framing) */
                     85:        RxErrCRC        = 0x2800,       /*   CRC */
                     86:        RxError         = 0x4000,       /* Error */
                     87:        RxEmpty         = 0x8000,       /* Incomplete or FIFO empty */
                     88: 
                     89:        FIFOdiag        = 0x04,         /* window 4 */
                     90:        MediaStatus     = 0x0A,
                     91: 
                     92:                                        /* FIFOdiag bits */
                     93:        TxOverrun       = 0x0400,       /* TX Overrrun */
                     94:        RxOverrun       = 0x0800,       /* RX Overrun */
                     95:        RxStatusOverrun = 0x1000,       /* RX Status Overrun */
                     96:        RxUnderrun      = 0x2000,       /* RX Underrun */
                     97:        RxReceiving     = 0x8000,       /* RX Receiving */
                     98: 
                     99:                                        /* MediaStatus bits */
                    100:        JabberEna       = 0x0040,       /* Jabber Enabled (writeable) */
                    101:        LinkBeatEna     = 0x0080,       /* Link Beat Enabled (writeable) */
                    102: };
                    103: 
                    104: #define COMMAND(port, cmd, a)  outs(port+CommandR, ((cmd)<<11)|(a))
                    105: 
                    106: static void
                    107: attach(Ctlr *ctlr)
                    108: {
                    109:        ulong port;
                    110: 
                    111:        port = ctlr->card.port;
                    112:        /*
                    113:         * Set the receiver packet filter for our own and
                    114:         * and broadcast addresses, set the interrupt masks
                    115:         * for all interrupts, and enable the receiver and transmitter.
                    116:         * The only interrupt we should see under normal conditions
                    117:         * is the receiver interrupt. If the transmit FIFO fills up,
                    118:         * we will also see TxAvailable interrupts.
                    119:         */
                    120:        COMMAND(port, SetRxFilter, Broadcast|MyEtherAddr);
                    121:        COMMAND(port, SetReadZeroMask, AllIntr|Latch);
                    122:        COMMAND(port, SetIntrMask, AllIntr|Latch);
                    123:        COMMAND(port, RxEnable, 0);
                    124:        COMMAND(port, TxEnable, 0);
                    125: }
                    126: 
                    127: static void
                    128: receive(Ctlr *ctlr)
                    129: {
                    130:        ushort status;
                    131:        RingBuf *rb;
                    132:        int len;
                    133:        ulong port;
                    134: 
                    135:        port = ctlr->card.port;
                    136:        while(((status = ins(port+RxStatus)) & RxEmpty) == 0){
                    137:                /*
                    138:                 * If we had an error, log it and continue
                    139:                 * without updating the ring.
                    140:                 */
                    141:                if(status & RxError){
                    142:                        switch(status & RxErrMask){
                    143: 
                    144:                        case RxErrOverrun:      /* Overrrun */
                    145:                        case RxErrOversize:     /* Oversize Packet (>1514) */
                    146:                        case RxErrRunt:         /* Runt Packet */
                    147:                        case RxErrFraming:      /* Alignment (Framing) */
                    148:                                ctlr->frames++;
                    149:                                break;
                    150: 
                    151:                        case RxErrCRC:          /* CRC */
                    152:                                ctlr->crcs++;
                    153:                                break;
                    154:                        }
                    155:                }
                    156:                else {
                    157:                        /*
                    158:                         * We have a packet. Read it into the next
                    159:                         * free ring buffer, if any.
                    160:                         * The CRC is already stripped off.
                    161:                         */
                    162:                        rb = &ctlr->rb[ctlr->ri];
                    163:                        if(rb->owner == Interface){
                    164:                                len = (status & RxByteMask);
                    165:                                rb->len = len;
                    166:        
                    167:                                /*
                    168:                                 * Must read len bytes padded to a
                    169:                                 * doubleword. We can pick them out 32-bits
                    170:                                 * at a time .
                    171:                                 */
                    172:                                insl(port+Fifo, rb->pkt, HOWMANY(len, 4));
                    173: 
                    174:                                /*
                    175:                                 * Update the ring.
                    176:                                 */
                    177:                                rb->owner = Host;
                    178:                                ctlr->ri = NEXT(ctlr->ri, ctlr->nrb);
                    179:                        }
                    180:                }
                    181: 
                    182:                /*
                    183:                 * Discard the packet as we're done with it.
                    184:                 * Wait for discard to complete.
                    185:                 */
                    186:                COMMAND(port, RxDiscard, 0);
                    187:                while(ins(port+Status) & CmdInProgress)
                    188:                        ;
                    189:        }
                    190: }
                    191: 
                    192: static void
                    193: transmit(Ctlr *ctlr)
                    194: {
                    195:        RingBuf *tb;
                    196:        ushort len;
                    197:        ulong port;
                    198: 
                    199:        port = ctlr->card.port;
                    200:        for(tb = &ctlr->tb[ctlr->ti]; tb->owner == Interface; tb = &ctlr->tb[ctlr->ti]){
                    201:                /*
                    202:                 * If there's no room in the FIFO for this packet,
                    203:                 * set up an interrupt for when space becomes available.
                    204:                 * Output packet must be a multiple of 4 in length and
                    205:                 * we need 4 bytes for the preamble.
                    206:                 */
                    207:                len = ROUNDUP(tb->len, 4);
                    208:                if(len+4 > ins(port+TxFreeBytes)){
                    209:                        COMMAND(port, SetTxAvailable, len);
                    210:                        break;
                    211:                }
                    212: 
                    213:                /*
                    214:                 * There's room, copy the packet to the FIFO and free
                    215:                 * the buffer back to the host.
                    216:                 */
                    217:                outs(port+Fifo, tb->len);
                    218:                outs(port+Fifo, 0);
                    219:                outsl(port+Fifo, tb->pkt, len/4);
                    220:                tb->owner = Host;
                    221:                ctlr->ti = NEXT(ctlr->ti, ctlr->ntb);
                    222:        }
                    223: }
                    224: 
                    225: static ushort
                    226: getdiag(Ctlr *ctlr)
                    227: {
                    228:        ushort bytes;
                    229:        ulong port;
                    230: 
                    231:        port = ctlr->card.port;
                    232:        COMMAND(port, SelectWindow, 4);
                    233:        bytes = ins(port+FIFOdiag);
                    234:        COMMAND(port, SelectWindow, 1);
                    235:        return bytes & 0xFFFF;
                    236: }
                    237: 
                    238: static void
                    239: interrupt(Ureg*, Ctlr *ctlr)
                    240: {
                    241:        ushort status, diag;
                    242:        uchar txstatus, x;
                    243:        ulong port;
                    244: 
                    245:        port = ctlr->card.port;
                    246:        status = ins(port+Status);
                    247: 
                    248:        if(status & Failure){
                    249:                /*
                    250:                 * Adapter failure, try to find out why.
                    251:                 * Reset if necessary.
                    252:                 * What happens if Tx is active and we reset,
                    253:                 * need to retransmit?
                    254:                 * This probably isn't right.
                    255:                 */
                    256:                diag = getdiag(ctlr);
                    257:                print("ether%d: status #%ux, diag #%ux\n", ctlr->ctlrno, status, diag);
                    258: 
                    259:                if(diag & TxOverrun){
                    260:                        COMMAND(port, TxReset, 0);
                    261:                        COMMAND(port, TxEnable, 0);
                    262:                }
                    263: 
                    264:                if(diag & RxUnderrun){
                    265:                        COMMAND(port, RxReset, 0);
                    266:                        attach(ctlr);
                    267:                }
                    268: 
                    269:                if(diag & TxOverrun)
                    270:                        transmit(ctlr);
                    271: 
                    272:                return;
                    273:        }
                    274: 
                    275:        if(status & RxComplete){
                    276:                receive(ctlr);
                    277:                status &= ~RxComplete;
                    278:        }
                    279: 
                    280:        if(status & TxComplete){
                    281:                /*
                    282:                 * Pop the TX Status stack, accumulating errors.
                    283:                 * If there was a Jabber or Underrun error, reset
                    284:                 * the transmitter. For all conditions enable
                    285:                 * the transmitter.
                    286:                 */
                    287:                txstatus = 0;
                    288:                do{
                    289:                        if(x = inb(port+TxStatus))
                    290:                                outb(port+TxStatus, 0);
                    291:                        txstatus |= x;
                    292:                }while(ins(port+Status) & TxComplete);
                    293: 
                    294:                if(txstatus & (TxJabber|TxUnderrun))
                    295:                        COMMAND(port, TxReset, 0);
                    296:                COMMAND(port, TxEnable, 0);
                    297:                ctlr->oerrs++;
                    298:        }
                    299: 
                    300:        if(status & (TxAvailable|TxComplete)){
                    301:                /*
                    302:                 * Reset the Tx FIFO threshold.
                    303:                 */
                    304:                if(status & TxAvailable)
                    305:                        COMMAND(port, AckIntr, TxAvailable);
                    306:                transmit(ctlr);
                    307:                status &= ~(TxAvailable|TxComplete);
                    308:        }
                    309: 
                    310:        /*
                    311:         * Panic if there are any interrupt bits on we haven't
                    312:         * dealt with other than Latch.
                    313:         * Otherwise, acknowledge the interrupt.
                    314:         */
                    315:        if(status & AllIntr)
                    316:                panic("ether%d interrupt: #%lux, #%ux\n",
                    317:                        ctlr->ctlrno, status, getdiag(ctlr));
                    318: 
                    319:        COMMAND(port, AckIntr, Latch);
                    320: }
                    321: 
                    322: typedef struct Adapter Adapter;
                    323: struct Adapter {
                    324:        Adapter *next;
                    325:        ulong   port;
                    326: };
                    327: static Adapter *adapter;
                    328: 
                    329: /*
                    330:  * Write two 0 bytes to identify the IDport and then reset the
                    331:  * ID sequence. Then send the ID sequence to the card to get
                    332:  * the card into command state.
                    333:  */
                    334: static void
                    335: idseq(void)
                    336: {
                    337:        int i;
                    338:        uchar al;
                    339: 
                    340:        outb(IDport, 0);
                    341:        outb(IDport, 0);
                    342:        for(al = 0xFF, i = 0; i < 255; i++){
                    343:                outb(IDport, al);
                    344:                if(al & 0x80){
                    345:                        al <<= 1;
                    346:                        al ^= 0xCF;
                    347:                }
                    348:                else
                    349:                        al <<= 1;
                    350:        }
                    351: }
                    352: 
                    353: static ulong
                    354: activate(int tag)
                    355: {
                    356:        int i;
                    357:        ushort x, acr;
                    358:        ulong port;
                    359: 
                    360:        /*
                    361:         * Do the little configuration dance:
                    362:         *
                    363:         * 2. write the ID sequence to get to command state.
                    364:         */
                    365:        idseq();
                    366: 
                    367:        /*
                    368:         * 3. Read the Manufacturer ID from the EEPROM.
                    369:         *    This is done by writing the IDPort with 0x87 (0x80
                    370:         *    is the 'read EEPROM' command, 0x07 is the offset of
                    371:         *    the Manufacturer ID field in the EEPROM).
                    372:         *    The data comes back 1 bit at a time.
                    373:         *    We seem to need a delay here between reading the bits.
                    374:         *
                    375:         * If the ID doesn't match, there are no more adapters.
                    376:         */
                    377:        outb(IDport, 0x87);
                    378:        for(x = 0, i = 0; i < 16; i++){
                    379:                delay(5);
                    380:                x <<= 1;
                    381:                x |= inb(IDport) & 0x01;
                    382:        }
                    383:        if(x != 0x6D50)
                    384:                return 0;
                    385: 
                    386:        /*
                    387:         * 3. Read the Address Configuration from the EEPROM.
                    388:         *    The Address Configuration field is at offset 0x08 in the EEPROM).
                    389:         */
                    390:        outb(IDport, 0x88);
                    391:        for(acr = 0, i = 0; i < 16; i++){
                    392:                delay(20);
                    393:                acr <<= 1;
                    394:                acr |= inb(IDport) & 0x01;
                    395:        }
                    396:        port = (acr & 0x1F)*0x10 + 0x200;
                    397: 
                    398:        if(tag){
                    399:                /*
                    400:                 * 6. Tag the adapter so it won't respond in future.
                    401:                 * 6. Activate the adapter by writing the Activate command
                    402:                 *    (0xFF).
                    403:                 */
                    404:                outb(IDport, 0xD1);
                    405:                outb(IDport, 0xFF);
                    406: 
                    407:                /*
                    408:                 * 8. Now we can talk to the adapter's I/O base addresses.
                    409:                 *    We get the I/O base address from the acr just read.
                    410:                 *
                    411:                 *    Enable the adapter.
                    412:                 */
                    413:                outs(port+ConfigControl, Ena);
                    414:        }
                    415: 
                    416:        return port;
                    417: }
                    418: 
                    419: static ulong
                    420: tcm509(ISAConf *isa)
                    421: {
                    422:        static int untag;
                    423:        ulong port;
                    424:        Adapter *ap;
                    425: 
                    426:        /*
                    427:         * One time only:
                    428:         *      write ID sequence to get the attention of all adapters;
                    429:         *      untag all adapters.
                    430:         * If we do a global reset here on all adapters we'll confuse any
                    431:         * ISA cards configured for EISA mode.
                    432:         */
                    433:        if(untag == 0){
                    434:                idseq();
                    435:                outb(IDport, 0xD0);
                    436:                untag = 1;
                    437:        }
                    438: 
                    439:        /*
                    440:         * Attempt to activate adapters until one matches our
                    441:         * address criteria. If adapter is set for EISA mode,
                    442:         * tag it and ignore. Otherwise, reset the adapter and
                    443:         * activate it fully.
                    444:         */
                    445:        while(port = activate(0)){
                    446:                if(port == 0x3F0){
                    447:                        outb(IDport, 0xD1);
                    448:                        continue;
                    449:                }
                    450:                outb(IDport, 0xC0);
                    451:                delay(2);
                    452:                if(activate(1) != port)
                    453:                        print("tcm509: activate\n");
                    454:                
                    455:                if(isa->port == 0 || isa->port == port)
                    456:                        return port;
                    457: 
                    458:                ap = ialloc(sizeof(Adapter), 0);
                    459:                ap->port = port;
                    460:                ap->next = adapter;
                    461:                adapter = ap;
                    462:        }
                    463: 
                    464:        return 0;
                    465: }
                    466: 
                    467: static ulong
                    468: tcm579(ISAConf *isa)
                    469: {
                    470:        static int slot = 1;
                    471:        ushort x;
                    472:        ulong port;
                    473:        Adapter *ap;
                    474: 
                    475:        /*
                    476:         * First time through, check if this is an EISA machine.
                    477:         * If not, nothing to do.
                    478:         */
                    479:        if(slot == 1 && strncmp((char*)(KZERO|0xFFFD9), "EISA", 4))
                    480:                return 0;
                    481: 
                    482:        /*
                    483:         * Continue through the EISA slots looking for a match on both
                    484:         * 3COM as the manufacturer and 3C579 or 3C579-TP as the product.
                    485:         * If we find an adapter, select window 0, enable it and clear
                    486:         * out any lingering status and interrupts.
                    487:         * Trying to do a GlobalReset here to re-init the card (as in the
                    488:         * 509 code) doesn't seem to work.
                    489:         */
                    490:        while(slot < MaxEISA){
                    491:                port = slot++*0x1000;
                    492:                if(ins(port+EISAconfig+ManufacturerID) != 0x6D50)
                    493:                        continue;
                    494:                x = ins(port+EISAconfig+ProductID);
                    495:                if((x & 0xF0FF) != 0x9050/* || (x != 0x9350 && x != 0x9250)*/)
                    496:                        continue;
                    497: 
                    498:                COMMAND(port, SelectWindow, 0);
                    499:                outs(port+ConfigControl, Ena);
                    500: 
                    501:                COMMAND(port, TxReset, 0);
                    502:                COMMAND(port, RxReset, 0);
                    503:                COMMAND(port, AckIntr, 0xFF);
                    504: 
                    505:                if(isa->port == 0 || isa->port == port)
                    506:                        return port;
                    507: 
                    508:                ap = ialloc(sizeof(Adapter), 0);
                    509:                ap->port = port;
                    510:                ap->next = adapter;
                    511:                adapter = ap;
                    512:        }
                    513: 
                    514:        return 0;
                    515: }
                    516: 
                    517: static ulong
                    518: tcm589(ISAConf*)
                    519: {
                    520:        return 0;
                    521: }
                    522: 
                    523: /*
                    524:  * Get configuration parameters.
                    525:  */
                    526: int
                    527: tcm509reset(Ctlr *ctlr)
                    528: {
                    529:        int i, eax;
                    530:        uchar ea[Eaddrlen];
                    531:        ushort x, acr;
                    532:        ulong port;
                    533:        Adapter *ap, **app;
                    534: 
                    535:        /*
                    536:         * Any adapter matches if no port is supplied,
                    537:         * otherwise the ports must match.
                    538:         * See if we've already found an adapter that fits
                    539:         * the bill.
                    540:         * If no match then try for an EISA card, an ISA card
                    541:         * and finally for a PCMCIA card.
                    542:         */
                    543:        port = 0;
                    544:        for(app = &adapter, ap = *app; ap; app = &ap->next, ap = ap->next){
                    545:                if(ctlr->card.port == 0 || ctlr->card.port == ap->port){
                    546:                        port = ap->port;
                    547:                        *app = ap->next;
                    548:                        /*free(ap);lost*/
                    549:                        break;
                    550:                }
                    551:        }
                    552:        if(port == 0)
                    553:                port = tcm579(&ctlr->card);
                    554:        if(port == 0)
                    555:                port = tcm509(&ctlr->card);
                    556:        if(port == 0)
                    557:                port = tcm589(&ctlr->card);
                    558:        if(port == 0)
                    559:                return -1;
                    560: 
                    561:        /*
                    562:         * Read the IRQ from the Resource Configuration Register,
                    563:         * the ethernet address from the EEPROM, and the address configuration.
                    564:         * The EEPROM command is 8 bits, the lower 6 bits being
                    565:         * the address offset.
                    566:         */
                    567:        ctlr->card.irq = (ins(port+ResourceConfig)>>12) & 0x0F;
                    568:        for(eax = 0, i = 0; i < 3; i++, eax += 2){
                    569:                while(ins(port+EEPROMcmd) & 0x8000)
                    570:                        ;
                    571:                outs(port+EEPROMcmd, (2<<6)|i);
                    572:                while(ins(port+EEPROMcmd) & 0x8000)
                    573:                        ;
                    574:                x = ins(port+EEPROMdata);
                    575:                ea[eax] = (x>>8) & 0xFF;
                    576:                ea[eax+1] = x & 0xFF;
                    577:        }
                    578:        acr = ins(port+AddressConfig);
                    579: 
                    580:        /*
                    581:         * Finished with window 0. Now set the ethernet address
                    582:         * in window 2.
                    583:         * CommandRs have the format 'CCCCCAAAAAAAAAAA' where C
                    584:         * is a bit in the command and A is a bit in the argument.
                    585:         */
                    586:        if((ctlr->card.ea[0]|ctlr->card.ea[1]|ctlr->card.ea[2]|ctlr->card.ea[3]|ctlr->card.ea[4]|ctlr->card.ea[5]) == 0)
                    587:                memmove(ctlr->card.ea, ea, Eaddrlen);
                    588:        COMMAND(port, SelectWindow, 2);
                    589:        for(i = 0; i < Eaddrlen; i++)
                    590:                outb(port+i, ctlr->card.ea[i]);
                    591: 
                    592:        /*
                    593:         * Enable the transceiver if necessary.
                    594:         */
                    595:        switch(acr & XcvrTypeMask){
                    596: 
                    597:        case Xcvr10BaseT:
                    598:                /*
                    599:                 * Enable Link Beat and Jabber to start the
                    600:                 * transceiver.
                    601:                 */
                    602:                COMMAND(port, SelectWindow, 4);
                    603:                outb(port+MediaStatus, LinkBeatEna|JabberEna);
                    604:                break;
                    605: 
                    606:        case XcvrBNC:
                    607:                /*
                    608:                 * Start the DC-DC converter.
                    609:                 * Wait > 800 microseconds.
                    610:                 */
                    611:                COMMAND(port, StartCoax, 0);
                    612:                delay(1);
                    613:                break;
                    614:        }
                    615: 
                    616:        /*
                    617:         * Set window 1 for normal operation.
                    618:         * Clear out any lingering Tx status.
                    619:         */
                    620:        COMMAND(port, SelectWindow, 1);
                    621:        while(inb(port+TxStatus))
                    622:                outb(port+TxStatus, 0);
                    623: 
                    624:        ctlr->card.port = port;
                    625: 
                    626:        /*
                    627:         * Set up the software configuration.
                    628:         */
                    629:        ctlr->card.reset = tcm509reset;
                    630:        ctlr->card.attach = attach;
                    631:        ctlr->card.transmit = transmit;
                    632:        ctlr->card.intr = interrupt;
                    633:        ctlr->card.bit16 = 1;
                    634: 
                    635:        return 0;
                    636: }

unix.superglobalmegacorp.com

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