/* A zero-terminated list of I/O addresses to be probed. */ staticunsignedint ultra_portlist[] __initdata =
{0x200, 0x220, 0x240, 0x280, 0x300, 0x340, 0x380, 0};
staticint ultra_probe1(struct net_device *dev, int ioaddr);
#define START_PG 0x00 /* First page of TX buffer */
#define ULTRA_CMDREG 0/* Offset to ASIC command register. */ #define ULTRA_RESET 0x80 /* Board reset, in ULTRA_CMDREG. */ #define ULTRA_MEMENB 0x40 /* Enable the shared memory. */ #define IOPD 0x02 /* I/O Pipe Data (16 bits), PIO operation. */ #define IOPA 0x07 /* I/O Pipe Address for PIO operation. */ #define ULTRA_NIC_OFFSET 16/* NIC register offset from the base_addr. */ #define ULTRA_IO_EXTENT 32 #define EN0_ERWCNT 0x08 /* Early receive warning count. */
#ifdef CONFIG_NET_POLL_CONTROLLER staticvoid ultra_poll(struct net_device *dev)
{
disable_irq(dev->irq);
ei_interrupt(dev->irq, dev);
enable_irq(dev->irq);
} #endif /* Probe for the Ultra. This looks like a 8013 with the station addressPROMatI/Oports<base>+8to<base>+13,withachecksum following.
*/
staticint __init do_ultra_probe(struct net_device *dev)
{ int i; int base_addr = dev->base_addr; int irq = dev->irq;
if (base_addr > 0x1ff) /* Check a single specified location. */ return ultra_probe1(dev, base_addr); elseif (base_addr != 0) /* Don't probe at all. */ return -ENXIO;
#ifdef __ISAPNP__ /* Look for any installed ISAPnP cards */ if (isapnp_present() && (ultra_probe_isapnp(dev) == 0)) return0; #endif
for (i = 0; ultra_portlist[i]; i++) {
dev->irq = irq; if (ultra_probe1(dev, ultra_portlist[i]) == 0) return0;
}
outb(0x00, cmd_port); /* Disable shared memory for safety. */
outb(0x80, cmd_port + 5); if (ei_status.block_input == &ultra_pio_input)
outb(0x11, cmd_port + 6); /* Enable interrupts and PIO. */ else
outb(0x01, cmd_port + 6); /* Enable interrupts and memory. */
netif_dbg(ei_local, hw, dev, "reset done\n");
}
/* Grab the 8390 specific header. Similar to the block_input routine, but wedon'tneedtobeconcernedwithringwrapastheheaderwillbeat
the start of a page, so we optimize accordingly. */
outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET); /* shmem on */ #ifdef __BIG_ENDIAN /* Officially this is what we are doing, but the readl() is faster */ /* unfortunately it isn't endian aware of the struct */
memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
hdr->count = le16_to_cpu(hdr->count); #else
((unsignedint*)hdr)[0] = readl(hdr_start); #endif
outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* shmem off */
}
/* Block input and output are easy on shared memory ethercards, the only
complication is when the ring buffer wraps. */
/* The identical operations for programmed I/O cards. ThePIOmodelistrivialtouse:the16bitstartaddressiswritten byte-sequentiallytoIOPA,withnointerveningI/Ooperations,andthe dataisreadorwrittentotheIOPDdataport. Theonlypotentialcomplicationisthattheaddressregisterisshared andmustbealwaysberewrittenbetweeneachread/writedirectionchange. Thisisnoproblemforus,asthe8390codeensuresthatwearesingle
threaded. */ staticvoid ultra_pio_get_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
{ int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
outb(0x00, ioaddr + IOPA); /* Set the address, LSB first. */
outb(ring_page, ioaddr + IOPA);
insw(ioaddr + IOPD, hdr, sizeof(struct e8390_pkt_hdr)>>1);
}
staticvoid ultra_pio_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
{ int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ char *buf = skb->data;
/* For now set the address again, although it should already be correct. */
outb(ring_offset, ioaddr + IOPA); /* Set the address, LSB first. */
outb(ring_offset >> 8, ioaddr + IOPA); /* We know skbuffs are padded to at least word alignment. */
insw(ioaddr + IOPD, buf, (count+1)>>1);
} staticvoid ultra_pio_output(struct net_device *dev, int count, constunsignedchar *buf, constint start_page)
{ int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
outb(0x00, ioaddr + IOPA); /* Set the address, LSB first. */
outb(start_page, ioaddr + IOPA); /* An extra odd byte is OK here as well. */
outsw(ioaddr + IOPD, buf, (count+1)>>1);
}
/* We should someday disable shared memory and change to 8-bit mode
"just in case"... */
return0;
}
#ifdef MODULE #define MAX_ULTRA_CARDS 4/* Max number of Ultra cards per module */ staticstruct net_device *dev_ultra[MAX_ULTRA_CARDS]; staticint io[MAX_ULTRA_CARDS]; staticint irq[MAX_ULTRA_CARDS];
/* This is set up so that only a single autoprobe takes place per call.
ISA device autoprobes on a running machine are not recommended. */ staticint __init ultra_init_module(void)
{ struct net_device *dev; int this_dev, found = 0;
for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) { if (io[this_dev] == 0) { if (this_dev != 0) break; /* only autoprobe 1st one */
printk(KERN_NOTICE "smc-ultra.c: Presently autoprobing (not recommended) for a single card.\n");
}
dev = alloc_ei_netdev(); if (!dev) break;
dev->irq = irq[this_dev];
dev->base_addr = io[this_dev]; if (do_ultra_probe(dev) == 0) {
dev_ultra[found++] = dev; continue;
}
free_netdev(dev);
printk(KERN_WARNING "smc-ultra.c: No SMC Ultra card found (i/o = 0x%x).\n", io[this_dev]); break;
} if (found) return0; return -ENXIO;
}
module_init(ultra_init_module);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.