patch-2.0.37 linux/drivers/net/epic100.c
Next file: linux/drivers/net/eql.c
Previous file: linux/drivers/net/eepro100.c
Back to the patch index
Back to the overall index
- Lines: 280
- Date:
Sun Jun 13 10:21:01 1999
- Orig file:
v2.0.36/linux/drivers/net/epic100.c
- Orig date:
Sun Nov 15 21:51:46 1998
diff -u --recursive --new-file v2.0.36/linux/drivers/net/epic100.c linux/drivers/net/epic100.c
@@ -1,6 +1,6 @@
/* epic100.c: A SMC 83c170 EPIC/100 Fast Ethernet driver for Linux. */
/*
- Written 1997-1998 by Donald Becker.
+ Written/copyright 1997-1998 by Donald Becker.
This software may be used and distributed according to the terms
of the GNU Public License, incorporated herein by reference.
@@ -10,15 +10,15 @@
SMC EtherPower II 9432 PCI adapter, and several CardBus cards.
The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
- Center of Excellence in Space Data and Information Sciences
+ USRA Center of Excellence in Space Data and Information Sciences
Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
- Support and updates available at
+ Information and updates available at
http://cesdis.gsfc.nasa.gov/linux/drivers/epic100.html
*/
static const char *version =
-"epic100.c:v1.03 8/7/98 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/epic100.html\n";
+"epic100.c:v1.04 8/23/98 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/epic100.html\n";
/* A few user-configurable values. */
@@ -118,6 +118,7 @@
/* The I/O extent. */
#define EPIC_TOTAL_SIZE 0x100
+#define epic_debug debug
static int epic_debug = 1;
/*
@@ -155,7 +156,8 @@
/* The rest of these values should never change. */
static struct device *epic_probe1(int pci_bus, int pci_devfn,
- struct device *dev, int card_idx);
+ struct device *dev, long ioaddr, int irq,
+ int chip_id, int card_idx);
enum pci_flags_bit {
PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
@@ -166,9 +168,11 @@
u16 vendor_id, device_id, device_id_mask, pci_flags;
int io_size, min_latency;
struct device *(*probe1)(int pci_bus, int pci_devfn, struct device *dev,
- int chip_idx);
+ long ioaddr, int irq, int chip_idx, int fnd_cnt);
} chip_tbl[] = {
- {"SMSC EPIC/100", 0x10B8, 0x0005, 0x7fff,
+ {"SMSC EPIC/100 83c170", 0x10B8, 0x0005, 0x7fff,
+ PCI_USES_IO|PCI_USES_MASTER|PCI_ADDR0, EPIC_TOTAL_SIZE, 32, epic_probe1},
+ {"SMSC EPIC/C 83c175", 0x10B8, 0x0006, 0x7fff,
PCI_USES_IO|PCI_USES_MASTER|PCI_ADDR0, EPIC_TOTAL_SIZE, 32, epic_probe1},
{0,},
};
@@ -276,7 +280,7 @@
int epic100_probe(struct device *dev)
{
int cards_found = 0;
- int chip_idx;
+ int chip_idx, irq;
u16 pci_command, new_command;
unsigned char pci_bus, pci_device_fn;
@@ -298,6 +302,7 @@
continue;
pci_bus = pcidev->bus->number;
pci_device_fn = pcidev->devfn;
+ irq = pcidev->irq;
#else
int pci_index;
@@ -305,6 +310,7 @@
return -ENODEV;
for (pci_index = 0; pci_index < 0xff; pci_index++) {
+ u8 pci_irq_line;
u16 vendor, device;
u32 pci_ioaddr;
@@ -327,8 +333,11 @@
pcibios_read_config_dword(pci_bus, pci_device_fn,
PCI_BASE_ADDRESS_0, &pci_ioaddr);
+ pcibios_read_config_byte(pci_bus, pci_device_fn,
+ PCI_INTERRUPT_LINE, &pci_irq_line);
/* Remove I/O space marker in bit 0. */
pci_ioaddr &= ~3;
+ irq = pci_irq_line;
if (check_region(pci_ioaddr, chip_tbl[chip_idx].io_size))
continue;
@@ -350,8 +359,8 @@
PCI_COMMAND, new_command);
}
- dev = chip_tbl[chip_idx].probe1(pci_bus, pci_device_fn,
- dev, cards_found);
+ dev = chip_tbl[chip_idx].probe1(pci_bus, pci_device_fn, dev, pci_ioaddr,
+ irq, chip_idx, cards_found);
/* Check the latency timer. */
if (dev) {
@@ -375,17 +384,12 @@
}
#endif /* not CARDBUS */
-static struct device *epic_probe1(int bus, int devfn, struct device *dev,
- int card_idx)
+static struct device *epic_probe1(int pci_bus, int pci_devfn,
+ struct device *dev, long ioaddr, int irq,
+ int chip_idx, int card_idx)
{
- static int did_version = 0; /* Already printed version info. */
struct epic_private *ep;
int i, option = 0, duplex = 0;
- u16 chip_id;
- u32 ioaddr;
-
- if (epic_debug > 0 && did_version++ == 0)
- printk(KERN_INFO "%s", version);
if (dev && dev->mem_start) {
option = dev->mem_start;
@@ -399,26 +403,10 @@
dev = init_etherdev(dev, 0);
- { /* Grrrr, badly consider interface change. */
-#if defined(PCI_SUPPORT_VER2)
- struct pci_dev *pdev = pci_find_slot(bus, devfn);
- ioaddr = pdev->base_address[0] & ~3;
- dev->irq = pdev->irq;
- chip_id = pdev->device;
-#else
- u8 irq;
- u32 ioaddr0;
- pcibios_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0, &ioaddr0);
- pcibios_read_config_byte(bus, devfn, PCI_INTERRUPT_LINE, &irq);
- pcibios_read_config_word(bus, devfn, PCI_DEVICE_ID, &chip_id);
- ioaddr = ioaddr0 & ~3;
- dev->irq = irq;
-#endif
- }
-
dev->base_addr = ioaddr;
- printk(KERN_INFO "%s: SMC EPIC/100 (chip ID %4.4x) at %#3x, IRQ %d, ",
- dev->name, chip_id, ioaddr, dev->irq);
+ dev->irq = irq;
+ printk(KERN_INFO "%s: SMC EPIC/100 at %#lx, IRQ %d, ",
+ dev->name, ioaddr, dev->irq);
/* Bring the chip out of low-power mode. */
outl(0x4200, ioaddr + GENCTL);
@@ -427,7 +415,7 @@
/* Turn on the MII transceiver. */
outl(0x12, ioaddr + MIICfg);
- if (chip_id == 6)
+ if (chip_idx == 1)
outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL);
outl(0x0200, ioaddr + GENCTL);
@@ -447,7 +435,7 @@
}
/* We do a request_region() to register /proc/ioports info. */
- request_region(ioaddr, EPIC_TOTAL_SIZE, "SMC EPIC/100");
+ request_region(ioaddr, EPIC_TOTAL_SIZE, dev->name);
/* The data structures must be quadword aligned. */
ep = kmalloc(sizeof(*ep), GFP_KERNEL | GFP_DMA);
@@ -457,9 +445,13 @@
ep->next_module = root_epic_dev;
root_epic_dev = dev;
- ep->pci_bus = bus;
- ep->pci_dev_fn = devfn;
- ep->chip_id = chip_id;
+ ep->pci_bus = pci_bus;
+ ep->pci_dev_fn = pci_devfn;
+#if defined(PCI_SUPPORT_VER2)
+ ep->chip_id = pci_find_slot(pci_bus, pci_devfn)->device;
+#else
+ ep->chip_id = chip_tbl[chip_idx].device_id;
+#endif
/* Find the connected MII xcvrs.
Doing this in open() would allow detecting external xcvrs later, but
@@ -545,7 +537,6 @@
int read_cmd = location |
(inl(ee_addr) & 0x40) ? EE_READ64_CMD : EE_READ256_CMD;
- printk("EEctrl is %x.\n", inl(ee_addr));
outl(EE_ENB & ~EE_CS, ee_addr);
outl(EE_ENB, ee_addr);
@@ -930,11 +921,9 @@
static void epic_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
{
struct device *dev = (struct device *)dev_instance;
- struct epic_private *ep;
- int status, ioaddr, boguscnt = max_interrupt_work;
-
- ioaddr = dev->base_addr;
- ep = (struct epic_private *)dev->priv;
+ struct epic_private *ep = (struct epic_private *)dev->priv;
+ long ioaddr = dev->base_addr;
+ int status, boguscnt = max_interrupt_work;
#if defined(__i386__)
/* A lock to prevent simultaneous entry bug on Intel SMP machines. */
@@ -1340,12 +1329,18 @@
if (loc->bus != LOC_PCI) return NULL;
bus = loc->b.pci.bus; devfn = loc->b.pci.devfn;
- printk(KERN_INFO "epic_attach(bus %d, function %d)\n", bus, devfn);
+ printk(KERN_DEBUG "epic_attach(bus %d, function %d)\n", bus, devfn);
pcibios_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0, &io);
pcibios_read_config_byte(bus, devfn, PCI_INTERRUPT_LINE, &irq);
pcibios_read_config_word(bus, devfn, PCI_DEVICE_ID, &dev_id);
io &= ~3;
- dev = epic_probe1(bus, devfn, NULL, -1);
+ if (io == 0 || irq == 0) {
+ printk(KERN_ERR "The EPIC/C CardBus Ethernet interface was not "
+ "assigned an %s.\n" KERN_ERR " It will not be activated.\n",
+ io == 0 ? "I/O address" : "IRQ");
+ return NULL;
+ }
+ dev = epic_probe1(bus, devfn, NULL, io, irq, 2, -1);
if (dev) {
dev_node_t *node = kmalloc(sizeof(dev_node_t), GFP_KERNEL);
strcpy(node->dev_name, dev->name);
@@ -1410,14 +1405,10 @@
#ifdef MODULE
-/* An additional parameter that may be passed in... */
-static int debug = -1;
-
-int
-init_module(void)
+int init_module(void)
{
- if (debug >= 0)
- epic_debug = debug;
+ if (epic_debug)
+ printk(KERN_INFO "%s", version);
#ifdef CARDBUS
register_driver(&epic_ops);
@@ -1427,8 +1418,7 @@
#endif
}
-void
-cleanup_module(void)
+void cleanup_module(void)
{
struct device *next_dev;
@@ -1438,11 +1428,13 @@
/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
while (root_epic_dev) {
- next_dev = ((struct epic_private *)root_epic_dev->priv)->next_module;
+ struct epic_private *ep = (struct epic_private *)root_epic_dev->priv;
+ next_dev = ep->next_module;
unregister_netdev(root_epic_dev);
release_region(root_epic_dev->base_addr, EPIC_TOTAL_SIZE);
kfree(root_epic_dev);
root_epic_dev = next_dev;
+ kfree(ep);
}
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov