Annotation of qemu/hw/lance.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * QEMU Lance emulation
        !             3:  * 
        !             4:  * Copyright (c) 2003-2005 Fabrice Bellard
        !             5:  * 
        !             6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
        !             7:  * of this software and associated documentation files (the "Software"), to deal
        !             8:  * in the Software without restriction, including without limitation the rights
        !             9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        !            10:  * copies of the Software, and to permit persons to whom the Software is
        !            11:  * furnished to do so, subject to the following conditions:
        !            12:  *
        !            13:  * The above copyright notice and this permission notice shall be included in
        !            14:  * all copies or substantial portions of the Software.
        !            15:  *
        !            16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        !            17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
        !            19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        !            20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        !            21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
        !            22:  * THE SOFTWARE.
        !            23:  */
        !            24: #include "vl.h"
        !            25: 
        !            26: /* debug LANCE card */
        !            27: //#define DEBUG_LANCE
        !            28: 
        !            29: #ifdef DEBUG_LANCE
        !            30: #define DPRINTF(fmt, args...) \
        !            31: do { printf("LANCE: " fmt , ##args); } while (0)
        !            32: #else
        !            33: #define DPRINTF(fmt, args...)
        !            34: #endif
        !            35: 
        !            36: #ifndef LANCE_LOG_TX_BUFFERS
        !            37: #define LANCE_LOG_TX_BUFFERS 4
        !            38: #define LANCE_LOG_RX_BUFFERS 4
        !            39: #endif
        !            40: 
        !            41: #define LE_CSR0 0
        !            42: #define LE_CSR1 1
        !            43: #define LE_CSR2 2
        !            44: #define LE_CSR3 3
        !            45: #define LE_NREGS (LE_CSR3 + 1)
        !            46: #define LE_MAXREG LE_CSR3
        !            47: 
        !            48: #define LE_RDP  0
        !            49: #define LE_RAP  1
        !            50: 
        !            51: #define LE_MO_PROM      0x8000  /* Enable promiscuous mode */
        !            52: 
        !            53: #define        LE_C0_ERR       0x8000  /* Error: set if BAB, SQE, MISS or ME is set */
        !            54: #define        LE_C0_BABL      0x4000  /* BAB:  Babble: tx timeout. */
        !            55: #define        LE_C0_CERR      0x2000  /* SQE:  Signal quality error */
        !            56: #define        LE_C0_MISS      0x1000  /* MISS: Missed a packet */
        !            57: #define        LE_C0_MERR      0x0800  /* ME:   Memory error */
        !            58: #define        LE_C0_RINT      0x0400  /* Received interrupt */
        !            59: #define        LE_C0_TINT      0x0200  /* Transmitter Interrupt */
        !            60: #define        LE_C0_IDON      0x0100  /* IFIN: Init finished. */
        !            61: #define        LE_C0_INTR      0x0080  /* Interrupt or error */
        !            62: #define        LE_C0_INEA      0x0040  /* Interrupt enable */
        !            63: #define        LE_C0_RXON      0x0020  /* Receiver on */
        !            64: #define        LE_C0_TXON      0x0010  /* Transmitter on */
        !            65: #define        LE_C0_TDMD      0x0008  /* Transmitter demand */
        !            66: #define        LE_C0_STOP      0x0004  /* Stop the card */
        !            67: #define        LE_C0_STRT      0x0002  /* Start the card */
        !            68: #define        LE_C0_INIT      0x0001  /* Init the card */
        !            69: 
        !            70: #define        LE_C3_BSWP      0x4     /* SWAP */
        !            71: #define        LE_C3_ACON      0x2     /* ALE Control */
        !            72: #define        LE_C3_BCON      0x1     /* Byte control */
        !            73: 
        !            74: /* Receive message descriptor 1 */
        !            75: #define LE_R1_OWN       0x80    /* Who owns the entry */
        !            76: #define LE_R1_ERR       0x40    /* Error: if FRA, OFL, CRC or BUF is set */
        !            77: #define LE_R1_FRA       0x20    /* FRA: Frame error */
        !            78: #define LE_R1_OFL       0x10    /* OFL: Frame overflow */
        !            79: #define LE_R1_CRC       0x08    /* CRC error */
        !            80: #define LE_R1_BUF       0x04    /* BUF: Buffer error */
        !            81: #define LE_R1_SOP       0x02    /* Start of packet */
        !            82: #define LE_R1_EOP       0x01    /* End of packet */
        !            83: #define LE_R1_POK       0x03    /* Packet is complete: SOP + EOP */
        !            84: 
        !            85: #define LE_T1_OWN       0x80    /* Lance owns the packet */
        !            86: #define LE_T1_ERR       0x40    /* Error summary */
        !            87: #define LE_T1_EMORE     0x10    /* Error: more than one retry needed */
        !            88: #define LE_T1_EONE      0x08    /* Error: one retry needed */
        !            89: #define LE_T1_EDEF      0x04    /* Error: deferred */
        !            90: #define LE_T1_SOP       0x02    /* Start of packet */
        !            91: #define LE_T1_EOP       0x01    /* End of packet */
        !            92: #define LE_T1_POK      0x03    /* Packet is complete: SOP + EOP */
        !            93: 
        !            94: #define LE_T3_BUF       0x8000  /* Buffer error */
        !            95: #define LE_T3_UFL       0x4000  /* Error underflow */
        !            96: #define LE_T3_LCOL      0x1000  /* Error late collision */
        !            97: #define LE_T3_CLOS      0x0800  /* Error carrier loss */
        !            98: #define LE_T3_RTY       0x0400  /* Error retry */
        !            99: #define LE_T3_TDR       0x03ff  /* Time Domain Reflectometry counter */
        !           100: 
        !           101: #define TX_RING_SIZE                   (1 << (LANCE_LOG_TX_BUFFERS))
        !           102: #define TX_RING_MOD_MASK               (TX_RING_SIZE - 1)
        !           103: #define TX_RING_LEN_BITS               ((LANCE_LOG_TX_BUFFERS) << 29)
        !           104: 
        !           105: #define RX_RING_SIZE                   (1 << (LANCE_LOG_RX_BUFFERS))
        !           106: #define RX_RING_MOD_MASK               (RX_RING_SIZE - 1)
        !           107: #define RX_RING_LEN_BITS               ((LANCE_LOG_RX_BUFFERS) << 29)
        !           108: 
        !           109: #define PKT_BUF_SZ             1544
        !           110: #define RX_BUFF_SIZE            PKT_BUF_SZ
        !           111: #define TX_BUFF_SIZE            PKT_BUF_SZ
        !           112: 
        !           113: struct lance_rx_desc {
        !           114:        unsigned short rmd0;        /* low address of packet */
        !           115:        unsigned char  rmd1_bits;   /* descriptor bits */
        !           116:        unsigned char  rmd1_hadr;   /* high address of packet */
        !           117:        short    length;            /* This length is 2s complement (negative)!
        !           118:                                     * Buffer length
        !           119:                                     */
        !           120:        unsigned short mblength;    /* This is the actual number of bytes received */
        !           121: };
        !           122: 
        !           123: struct lance_tx_desc {
        !           124:        unsigned short tmd0;        /* low address of packet */
        !           125:        unsigned char  tmd1_bits;   /* descriptor bits */
        !           126:        unsigned char  tmd1_hadr;   /* high address of packet */
        !           127:        short length;               /* Length is 2s complement (negative)! */
        !           128:        unsigned short misc;
        !           129: };
        !           130: 
        !           131: /* The LANCE initialization block, described in databook. */
        !           132: /* On the Sparc, this block should be on a DMA region     */
        !           133: struct lance_init_block {
        !           134:        unsigned short mode;            /* Pre-set mode (reg. 15) */
        !           135:        unsigned char phys_addr[6];     /* Physical ethernet address */
        !           136:        unsigned filter[2];             /* Multicast filter. */
        !           137: 
        !           138:        /* Receive and transmit ring base, along with extra bits. */
        !           139:        unsigned short rx_ptr;          /* receive descriptor addr */
        !           140:        unsigned short rx_len;          /* receive len and high addr */
        !           141:        unsigned short tx_ptr;          /* transmit descriptor addr */
        !           142:        unsigned short tx_len;          /* transmit len and high addr */
        !           143:     
        !           144:        /* The Tx and Rx ring entries must aligned on 8-byte boundaries. */
        !           145:        struct lance_rx_desc brx_ring[RX_RING_SIZE];
        !           146:        struct lance_tx_desc btx_ring[TX_RING_SIZE];
        !           147:     
        !           148:        char   tx_buf [TX_RING_SIZE][TX_BUFF_SIZE];
        !           149:        char   pad[2];                  /* align rx_buf for copy_and_sum(). */
        !           150:        char   rx_buf [RX_RING_SIZE][RX_BUFF_SIZE];
        !           151: };
        !           152: 
        !           153: #define LEDMA_REGS 4
        !           154: #define LEDMA_MAXADDR (LEDMA_REGS * 4 - 1)
        !           155: 
        !           156: typedef struct LANCEState {
        !           157:     NetDriverState *nd;
        !           158:     uint32_t leptr;
        !           159:     uint16_t addr;
        !           160:     uint16_t regs[LE_NREGS];
        !           161:     uint8_t phys[6]; /* mac address */
        !           162:     int irq;
        !           163:     unsigned int rxptr, txptr;
        !           164:     uint32_t ledmaregs[LEDMA_REGS];
        !           165: } LANCEState;
        !           166: 
        !           167: static void lance_send(void *opaque);
        !           168: 
        !           169: static void lance_reset(void *opaque)
        !           170: {
        !           171:     LANCEState *s = opaque;
        !           172:     memcpy(s->phys, s->nd->macaddr, 6);
        !           173:     s->rxptr = 0;
        !           174:     s->txptr = 0;
        !           175:     memset(s->regs, 0, LE_NREGS * 2);
        !           176:     s->regs[LE_CSR0] = LE_C0_STOP;
        !           177:     memset(s->ledmaregs, 0, LEDMA_REGS * 4);
        !           178: }
        !           179: 
        !           180: static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
        !           181: {
        !           182:     LANCEState *s = opaque;
        !           183:     uint32_t saddr;
        !           184: 
        !           185:     saddr = addr & LE_MAXREG;
        !           186:     switch (saddr >> 1) {
        !           187:     case LE_RDP:
        !           188:        DPRINTF("read dreg[%d] = %4.4x\n", s->addr, s->regs[s->addr]);
        !           189:        return s->regs[s->addr];
        !           190:     case LE_RAP:
        !           191:        DPRINTF("read areg = %4.4x\n", s->addr);
        !           192:        return s->addr;
        !           193:     default:
        !           194:        DPRINTF("read unknown(%d)\n", saddr>>1);
        !           195:        break;
        !           196:     }
        !           197:     return 0;
        !           198: }
        !           199: 
        !           200: static void lance_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
        !           201: {
        !           202:     LANCEState *s = opaque;
        !           203:     uint32_t saddr;
        !           204:     uint16_t reg;
        !           205: 
        !           206:     saddr = addr & LE_MAXREG;
        !           207:     switch (saddr >> 1) {
        !           208:     case LE_RDP:
        !           209:        DPRINTF("write dreg[%d] = %4.4x\n", s->addr, val);
        !           210:        switch(s->addr) {
        !           211:        case LE_CSR0:
        !           212:            if (val & LE_C0_STOP) {
        !           213:                s->regs[LE_CSR0] = LE_C0_STOP;
        !           214:                break;
        !           215:            }
        !           216: 
        !           217:            reg = s->regs[LE_CSR0];
        !           218: 
        !           219:            // 1 = clear for some bits
        !           220:            reg &= ~(val & 0x7f00);
        !           221: 
        !           222:            // generated bits
        !           223:            reg &= ~(LE_C0_ERR | LE_C0_INTR);
        !           224:            if (reg & 0x7100)
        !           225:                reg |= LE_C0_ERR;
        !           226:            if (reg & 0x7f00)
        !           227:                reg |= LE_C0_INTR;
        !           228: 
        !           229:            // direct bit
        !           230:            reg &= ~LE_C0_INEA;
        !           231:            reg |= val & LE_C0_INEA;
        !           232: 
        !           233:            // exclusive bits
        !           234:            if (val & LE_C0_INIT) {
        !           235:                reg |= LE_C0_IDON | LE_C0_INIT;
        !           236:                reg &= ~LE_C0_STOP;
        !           237:            }
        !           238:            else if (val & LE_C0_STRT) {
        !           239:                reg |= LE_C0_STRT | LE_C0_RXON | LE_C0_TXON;
        !           240:                reg &= ~LE_C0_STOP;
        !           241:            }
        !           242: 
        !           243:            s->regs[LE_CSR0] = reg;
        !           244:            break;
        !           245:        case LE_CSR1:
        !           246:            s->leptr = (s->leptr & 0xffff0000) | (val & 0xffff);
        !           247:            s->regs[s->addr] = val;
        !           248:            break;
        !           249:        case LE_CSR2:
        !           250:            s->leptr = (s->leptr & 0xffff) | ((val & 0xffff) << 16);
        !           251:            s->regs[s->addr] = val;
        !           252:            break;
        !           253:        case LE_CSR3:
        !           254:            s->regs[s->addr] = val;
        !           255:            break;
        !           256:        }
        !           257:        break;
        !           258:     case LE_RAP:
        !           259:        DPRINTF("write areg = %4.4x\n", val);
        !           260:        if (val < LE_NREGS)
        !           261:            s->addr = val;
        !           262:        break;
        !           263:     default:
        !           264:        DPRINTF("write unknown(%d) = %4.4x\n", saddr>>1, val);
        !           265:        break;
        !           266:     }
        !           267:     lance_send(s);
        !           268: }
        !           269: 
        !           270: static CPUReadMemoryFunc *lance_mem_read[3] = {
        !           271:     lance_mem_readw,
        !           272:     lance_mem_readw,
        !           273:     lance_mem_readw,
        !           274: };
        !           275: 
        !           276: static CPUWriteMemoryFunc *lance_mem_write[3] = {
        !           277:     lance_mem_writew,
        !           278:     lance_mem_writew,
        !           279:     lance_mem_writew,
        !           280: };
        !           281: 
        !           282: 
        !           283: /* return the max buffer size if the LANCE can receive more data */
        !           284: static int lance_can_receive(void *opaque)
        !           285: {
        !           286:     LANCEState *s = opaque;
        !           287:     uint32_t dmaptr = s->leptr + s->ledmaregs[3];
        !           288:     struct lance_init_block *ib;
        !           289:     int i;
        !           290:     uint8_t temp8;
        !           291: 
        !           292:     if ((s->regs[LE_CSR0] & LE_C0_STOP) == LE_C0_STOP)
        !           293:        return 0;
        !           294: 
        !           295:     ib = (void *) iommu_translate(dmaptr);
        !           296: 
        !           297:     for (i = 0; i < RX_RING_SIZE; i++) {
        !           298:        cpu_physical_memory_read((uint32_t)&ib->brx_ring[i].rmd1_bits, (void *) &temp8, 1);
        !           299:        if (temp8 == (LE_R1_OWN)) {
        !           300:            DPRINTF("can receive %d\n", RX_BUFF_SIZE);
        !           301:            return RX_BUFF_SIZE;
        !           302:        }
        !           303:     }
        !           304:     DPRINTF("cannot receive\n");
        !           305:     return 0;
        !           306: }
        !           307: 
        !           308: #define MIN_BUF_SIZE 60
        !           309: 
        !           310: static void lance_receive(void *opaque, const uint8_t *buf, int size)
        !           311: {
        !           312:     LANCEState *s = opaque;
        !           313:     uint32_t dmaptr = s->leptr + s->ledmaregs[3];
        !           314:     struct lance_init_block *ib;
        !           315:     unsigned int i, old_rxptr;
        !           316:     uint16_t temp16;
        !           317:     uint8_t temp8;
        !           318: 
        !           319:     DPRINTF("receive size %d\n", size);
        !           320:     if ((s->regs[LE_CSR0] & LE_C0_STOP) == LE_C0_STOP)
        !           321:        return;
        !           322: 
        !           323:     ib = (void *) iommu_translate(dmaptr);
        !           324: 
        !           325:     old_rxptr = s->rxptr;
        !           326:     for (i = s->rxptr; i != ((old_rxptr - 1) & RX_RING_MOD_MASK); i = (i + 1) & RX_RING_MOD_MASK) {
        !           327:        cpu_physical_memory_read((uint32_t)&ib->brx_ring[i].rmd1_bits, (void *) &temp8, 1);
        !           328:        if (temp8 == (LE_R1_OWN)) {
        !           329:            s->rxptr = (s->rxptr + 1) & RX_RING_MOD_MASK;
        !           330:            temp16 = size + 4;
        !           331:            bswap16s(&temp16);
        !           332:            cpu_physical_memory_write((uint32_t)&ib->brx_ring[i].mblength, (void *) &temp16, 2);
        !           333:            cpu_physical_memory_write((uint32_t)&ib->rx_buf[i], buf, size);
        !           334:            temp8 = LE_R1_POK;
        !           335:            cpu_physical_memory_write((uint32_t)&ib->brx_ring[i].rmd1_bits, (void *) &temp8, 1);
        !           336:            s->regs[LE_CSR0] |= LE_C0_RINT | LE_C0_INTR;
        !           337:            if (s->regs[LE_CSR0] & LE_C0_INEA)
        !           338:                pic_set_irq(s->irq, 1);
        !           339:            DPRINTF("got packet, len %d\n", size);
        !           340:            return;
        !           341:        }
        !           342:     }
        !           343: }
        !           344: 
        !           345: static void lance_send(void *opaque)
        !           346: {
        !           347:     LANCEState *s = opaque;
        !           348:     uint32_t dmaptr = s->leptr + s->ledmaregs[3];
        !           349:     struct lance_init_block *ib;
        !           350:     unsigned int i, old_txptr;
        !           351:     uint16_t temp16;
        !           352:     uint8_t temp8;
        !           353:     char pkt_buf[PKT_BUF_SZ];
        !           354: 
        !           355:     DPRINTF("sending packet? (csr0 %4.4x)\n", s->regs[LE_CSR0]);
        !           356:     if ((s->regs[LE_CSR0] & LE_C0_STOP) == LE_C0_STOP)
        !           357:        return;
        !           358: 
        !           359:     ib = (void *) iommu_translate(dmaptr);
        !           360: 
        !           361:     DPRINTF("sending packet? (dmaptr %8.8x) (ib %p) (btx_ring %p)\n", dmaptr, ib, &ib->btx_ring);
        !           362:     old_txptr = s->txptr;
        !           363:     for (i = s->txptr; i != ((old_txptr - 1) & TX_RING_MOD_MASK); i = (i + 1) & TX_RING_MOD_MASK) {
        !           364:        cpu_physical_memory_read((uint32_t)&ib->btx_ring[i].tmd1_bits, (void *) &temp8, 1);
        !           365:        if (temp8 == (LE_T1_POK|LE_T1_OWN)) {
        !           366:            cpu_physical_memory_read((uint32_t)&ib->btx_ring[i].length, (void *) &temp16, 2);
        !           367:            bswap16s(&temp16);
        !           368:            temp16 = (~temp16) + 1;
        !           369:            cpu_physical_memory_read((uint32_t)&ib->tx_buf[i], pkt_buf, temp16);
        !           370:            DPRINTF("sending packet, len %d\n", temp16);
        !           371:            qemu_send_packet(s->nd, pkt_buf, temp16);
        !           372:            temp8 = LE_T1_POK;
        !           373:            cpu_physical_memory_write((uint32_t)&ib->btx_ring[i].tmd1_bits, (void *) &temp8, 1);
        !           374:            s->txptr = (s->txptr + 1) & TX_RING_MOD_MASK;
        !           375:            s->regs[LE_CSR0] |= LE_C0_TINT | LE_C0_INTR;
        !           376:        }
        !           377:     }
        !           378:     if ((s->regs[LE_CSR0] & LE_C0_INTR) && (s->regs[LE_CSR0] & LE_C0_INEA))
        !           379:        pic_set_irq(s->irq, 1);
        !           380: }
        !           381: 
        !           382: static uint32_t ledma_mem_readl(void *opaque, target_phys_addr_t addr)
        !           383: {
        !           384:     LANCEState *s = opaque;
        !           385:     uint32_t saddr;
        !           386: 
        !           387:     saddr = (addr & LEDMA_MAXADDR) >> 2;
        !           388:     return s->ledmaregs[saddr];
        !           389: }
        !           390: 
        !           391: static void ledma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
        !           392: {
        !           393:     LANCEState *s = opaque;
        !           394:     uint32_t saddr;
        !           395: 
        !           396:     saddr = (addr & LEDMA_MAXADDR) >> 2;
        !           397:     s->ledmaregs[saddr] = val;
        !           398: }
        !           399: 
        !           400: static CPUReadMemoryFunc *ledma_mem_read[3] = {
        !           401:     ledma_mem_readl,
        !           402:     ledma_mem_readl,
        !           403:     ledma_mem_readl,
        !           404: };
        !           405: 
        !           406: static CPUWriteMemoryFunc *ledma_mem_write[3] = {
        !           407:     ledma_mem_writel,
        !           408:     ledma_mem_writel,
        !           409:     ledma_mem_writel,
        !           410: };
        !           411: 
        !           412: static void lance_save(QEMUFile *f, void *opaque)
        !           413: {
        !           414:     LANCEState *s = opaque;
        !           415:     int i;
        !           416:     
        !           417:     qemu_put_be32s(f, &s->leptr);
        !           418:     qemu_put_be16s(f, &s->addr);
        !           419:     for (i = 0; i < LE_NREGS; i ++)
        !           420:        qemu_put_be16s(f, &s->regs[i]);
        !           421:     qemu_put_buffer(f, s->phys, 6);
        !           422:     qemu_put_be32s(f, &s->irq);
        !           423:     for (i = 0; i < LEDMA_REGS; i ++)
        !           424:        qemu_put_be32s(f, &s->ledmaregs[i]);
        !           425: }
        !           426: 
        !           427: static int lance_load(QEMUFile *f, void *opaque, int version_id)
        !           428: {
        !           429:     LANCEState *s = opaque;
        !           430:     int i;
        !           431:     
        !           432:     if (version_id != 1)
        !           433:         return -EINVAL;
        !           434: 
        !           435:     qemu_get_be32s(f, &s->leptr);
        !           436:     qemu_get_be16s(f, &s->addr);
        !           437:     for (i = 0; i < LE_NREGS; i ++)
        !           438:        qemu_get_be16s(f, &s->regs[i]);
        !           439:     qemu_get_buffer(f, s->phys, 6);
        !           440:     qemu_get_be32s(f, &s->irq);
        !           441:     for (i = 0; i < LEDMA_REGS; i ++)
        !           442:        qemu_get_be32s(f, &s->ledmaregs[i]);
        !           443:     return 0;
        !           444: }
        !           445: 
        !           446: void lance_init(NetDriverState *nd, int irq, uint32_t leaddr, uint32_t ledaddr)
        !           447: {
        !           448:     LANCEState *s;
        !           449:     int lance_io_memory, ledma_io_memory;
        !           450: 
        !           451:     s = qemu_mallocz(sizeof(LANCEState));
        !           452:     if (!s)
        !           453:         return;
        !           454: 
        !           455:     s->nd = nd;
        !           456:     s->irq = irq;
        !           457: 
        !           458:     lance_io_memory = cpu_register_io_memory(0, lance_mem_read, lance_mem_write, s);
        !           459:     cpu_register_physical_memory(leaddr, 4, lance_io_memory);
        !           460: 
        !           461:     ledma_io_memory = cpu_register_io_memory(0, ledma_mem_read, ledma_mem_write, s);
        !           462:     cpu_register_physical_memory(ledaddr, 16, ledma_io_memory);
        !           463: 
        !           464:     lance_reset(s);
        !           465:     qemu_add_read_packet(nd, lance_can_receive, lance_receive, s);
        !           466:     register_savevm("lance", leaddr, 1, lance_save, lance_load, s);
        !           467:     qemu_register_reset(lance_reset, s);
        !           468: }
        !           469: 

unix.superglobalmegacorp.com

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