summaryrefslogtreecommitdiffstats
path: root/drivers/net/sb1000.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-02-04 07:40:19 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-02-04 07:40:19 +0000
commit33263fc5f9ac8e8cb2b22d06af3ce5ac1dd815e4 (patch)
tree2d1b86a40bef0958a68cf1a2eafbeb0667a70543 /drivers/net/sb1000.c
parent216f5f51aa02f8b113aa620ebc14a9631a217a00 (diff)
Merge with Linux 2.3.32.
Diffstat (limited to 'drivers/net/sb1000.c')
-rw-r--r--drivers/net/sb1000.c252
1 files changed, 113 insertions, 139 deletions
diff --git a/drivers/net/sb1000.c b/drivers/net/sb1000.c
index b0d8a9ad4..ad425f91b 100644
--- a/drivers/net/sb1000.c
+++ b/drivers/net/sb1000.c
@@ -56,8 +56,10 @@ static char version[] = "sb1000.c:v1.1.2 6/01/98 (fventuri@mediaone.net)\n";
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/etherdevice.h>
+#include <linux/isapnp.h>
/* for SIOGCM/SIOSCM stuff */
+
#include <linux/if_cablemodem.h>
#ifdef SB1000_DEBUG
@@ -93,8 +95,6 @@ static void sb1000_interrupt(int irq, void *dev_id, struct pt_regs *regs);
static struct enet_statistics *sb1000_stats(struct net_device *dev);
static int sb1000_close(struct net_device *dev);
-/* Plug-n-Play routine */
-static inline unsigned char read_resource_data(void);
/* SB1000 hardware routines to be used during open/configuration phases */
static inline void nicedelay(unsigned long usecs);
@@ -138,160 +138,132 @@ static inline int sb1000_set_PIDs(const int ioaddr[], const char* name,
static inline int sb1000_rx(struct net_device *dev);
static inline void sb1000_error_dpc(struct net_device *dev);
-
-/* Plug-n-Play constants */
-static const int READ_DATA_PORT = 0x203; /* This port number may change!!! */
-static const int ADDRESS_PORT = 0x279;
-static const int WRITE_DATA_PORT = 0xa79;
-
-/* Plug-n-Play read resource mechanism */
-static inline unsigned char
-read_resource_data(void) {
- /* poll */
- outb(0x05, ADDRESS_PORT); /* Select PnP status register. */
- while (!(inb(READ_DATA_PORT) & 0x1)) ;
- /* read resource data */
- outb(0x04, ADDRESS_PORT); /* Select PnP resource data register. */
- return inb(READ_DATA_PORT);
-}
-
/* probe for SB1000 using Plug-n-Play mechanism */
int
sb1000_probe(struct net_device *dev)
{
unsigned short ioaddr[2], irq;
- short i, csn;
+ struct pci_dev *idev=NULL;
unsigned int serial_number;
+
+ while(1)
+ {
+ /*
+ * Find the card
+ */
+
+ idev=isapnp_find_dev(NULL, ISAPNP_VENDOR('G','I','C'),
+ ISAPNP_FUNCTION(0x1000), idev);
+
+ /*
+ * No card
+ */
+
+ if(idev==NULL)
+ return -ENODEV;
+
+ /*
+ * Bring it online
+ */
+
+ idev->prepare(idev);
+ idev->activate(idev);
+
+ /*
+ * Ports free ?
+ */
+
+ if(!idev->resource[0].start || check_region(idev->resource[0].start, 16))
+ continue;
+ if(!idev->resource[1].start || check_region(idev->resource[1].start, 16))
+ continue;
+
+ serial_number = idev->bus->serial;
+
+ ioaddr[0]=idev->resource[0].start;
+ ioaddr[1]=idev->resource[1].start;
+
+ irq = idev->irq;
+
+ /* check I/O base and IRQ */
+ if (dev->base_addr != 0 && dev->base_addr != ioaddr[0])
+ continue;
+ if (dev->rmem_end != 0 && dev->rmem_end != ioaddr[1])
+ continue;
+ if (dev->irq != 0 && dev->irq != irq)
+ continue;
+
+ /*
+ * Ok set it up.
+ */
+
+
+ dev->base_addr = ioaddr[0];
+ /* rmem_end holds the second I/O address - fv */
+ dev->rmem_end = ioaddr[1];
+ dev->irq = irq;
+
+ if (sb1000_debug > 0)
+ printk(KERN_NOTICE "%s: sb1000 at (%#3.3lx,%#3.3lx), "
+ "S/N %#8.8x, IRQ %d.\n", dev->name, dev->base_addr,
+ dev->rmem_end, serial_number, dev->irq);
+
+ dev = init_etherdev(dev, 0);
+
+ /* Make up a SB1000-specific-data structure. */
+ dev->priv = kmalloc(sizeof(struct sb1000_private), GFP_KERNEL);
+ if (dev->priv == NULL)
+ return -ENOMEM;
+ memset(dev->priv, 0, sizeof(struct sb1000_private));
+
+ if (sb1000_debug > 0)
+ printk(KERN_NOTICE "%s", version);
+
+ /* The SB1000-specific entries in the device structure. */
+ dev->open = sb1000_open;
+ dev->do_ioctl = sb1000_dev_ioctl;
+ dev->hard_start_xmit = sb1000_start_xmit;
+ dev->stop = sb1000_close;
+ dev->get_stats = sb1000_stats;
+
+ /* Fill in the generic fields of the device structure. */
+ dev->change_mtu = NULL;
+ dev->hard_header = NULL;
+ dev->rebuild_header = NULL;
+ dev->set_mac_address = NULL;
+ dev->header_cache_update= NULL;
+
+ dev->type = ARPHRD_ETHER;
+ dev->hard_header_len = 0;
+ dev->mtu = 1500;
+ dev->addr_len = ETH_ALEN;
+ /* hardware address is 0:0:serial_number */
+ dev->dev_addr[0] = 0;
+ dev->dev_addr[1] = 0;
+ dev->dev_addr[2] = serial_number >> 24 & 0xff;
+ dev->dev_addr[3] = serial_number >> 16 & 0xff;
+ dev->dev_addr[4] = serial_number >> 8 & 0xff;
+ dev->dev_addr[5] = serial_number >> 0 & 0xff;
+ dev->tx_queue_len = 0;
+
+ /* New-style flags. */
+ dev->flags = IFF_POINTOPOINT|IFF_NOARP;
- const unsigned char initiation_key[] = { 0x00, 0x00, 0x6a, 0xb5, 0xda,
- 0xed, 0xf6, 0xfb, 0x7d, 0xbe, 0xdf, 0x6f, 0x37, 0x1b, 0x0d,
- 0x86, 0xc3, 0x61, 0xb0, 0x58, 0x2c, 0x16, 0x8b, 0x45, 0xa2,
- 0xd1, 0xe8, 0x74, 0x3a, 0x9d, 0xce, 0xe7, 0x73, 0x39 };
- const unsigned char sb1000_vendor_ID[] = {
- 0x1d, 0x23, 0x10, 0x00 }; /* "GIC1000" */
-
- /* Reset the ISA PnP mechanism */
- outb(0x02, ADDRESS_PORT); /* Select PnP config control register. */
- outb(0x02, WRITE_DATA_PORT); /* Return to WaitForKey state. */
-
- /* send initiation key */
- for (i = 0; i < sizeof(initiation_key) / sizeof(initiation_key[0]); i++) {
- outb(initiation_key[i], ADDRESS_PORT);
- }
-
- /* set card CSN into configuration mode */
- for (csn = 1; csn <= 255; csn++) {
- outb(0x03, ADDRESS_PORT); /* Select PnP wake[CSN] register. */
- outb(csn, WRITE_DATA_PORT); /* Wake[CSN] */
- /* check card ID */
- for (i = 0; i < 4; i++) {
- if (read_resource_data() != sb1000_vendor_ID[i]) break;
- }
- if (i == 4) break;
- }
+ /* Lock resources */
- /* SB1000 not found */
- if (csn > 255) {
- /* return to WaitForKey state */
- outb(0x02, ADDRESS_PORT); /* Select PnP config control register. */
- outb(0x02, WRITE_DATA_PORT);/* Return to WaitForKey state. */
- return -ENODEV;
- }
+ request_region(ioaddr[0], 16, dev->name);
+ request_region(ioaddr[1], 16, dev->name);
- /* found: get serial number and skip checksum */
- serial_number = 0;
- for (i = 0; i < 4; i++) {
- serial_number |= read_resource_data() << (8 * i);
- }
- read_resource_data();
-
- /* get I/O port base address */
- outb(0x60, ADDRESS_PORT); /* Select PnP I/O port base address 0. */
- ioaddr[0] = inb(READ_DATA_PORT) << 8;
- outb(0x61, ADDRESS_PORT);
- ioaddr[0] |= inb(READ_DATA_PORT);
- outb(0x62, ADDRESS_PORT); /* Select PnP I/O port base address 1. */
- ioaddr[1] = inb(READ_DATA_PORT) << 8;
- outb(0x63, ADDRESS_PORT);
- ioaddr[1] |= inb(READ_DATA_PORT);
-
- /* get IRQ */
- outb(0x70, ADDRESS_PORT); /* Select PnP IRQ level select 0. */
- irq = inb(READ_DATA_PORT);
-
- /* return to WaitForKey state */
- outb(0x02, ADDRESS_PORT); /* Select PnP config control register. */
- outb(0x02, WRITE_DATA_PORT); /* Return to WaitForKey state. */
-
- /* check I/O base and IRQ */
- if (dev->base_addr != 0 && dev->base_addr != ioaddr[0]) {
- return -ENODEV;
- }
- if (dev->rmem_end != 0 && dev->rmem_end != ioaddr[1]) {
- return -ENODEV;
- }
- if (dev->irq != 0 && dev->irq != irq) {
- return -ENODEV;
+ return 0;
}
-
- dev->base_addr = ioaddr[0];
- /* rmem_end holds the second I/O address - fv */
- dev->rmem_end = ioaddr[1];
- dev->irq = irq;
-
- if (sb1000_debug > 0)
- printk(KERN_NOTICE "%s: sb1000 at (%#3.3lx,%#3.3lx), csn %d, "
- "S/N %#8.8x, IRQ %d.\n", dev->name, dev->base_addr,
- dev->rmem_end, csn, serial_number, dev->irq);
-
- dev = init_etherdev(dev, 0);
-
- /* Make up a SB1000-specific-data structure. */
- dev->priv = kmalloc(sizeof(struct sb1000_private), GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOMEM;
- memset(dev->priv, 0, sizeof(struct sb1000_private));
-
- if (sb1000_debug > 0)
- printk(KERN_NOTICE "%s", version);
-
- /* The SB1000-specific entries in the device structure. */
- dev->open = sb1000_open;
- dev->do_ioctl = sb1000_dev_ioctl;
- dev->hard_start_xmit = sb1000_start_xmit;
- dev->stop = sb1000_close;
- dev->get_stats = sb1000_stats;
-
- /* Fill in the generic fields of the device structure. */
- dev->change_mtu = NULL;
- dev->hard_header = NULL;
- dev->rebuild_header = NULL;
- dev->set_mac_address = NULL;
- dev->header_cache_update= NULL;
-
- dev->type = ARPHRD_ETHER;
- dev->hard_header_len = 0;
- dev->mtu = 1500;
- dev->addr_len = ETH_ALEN;
- /* hardware address is 0:0:serial_number */
- dev->dev_addr[0] = 0;
- dev->dev_addr[1] = 0;
- dev->dev_addr[2] = serial_number >> 24 & 0xff;
- dev->dev_addr[3] = serial_number >> 16 & 0xff;
- dev->dev_addr[4] = serial_number >> 8 & 0xff;
- dev->dev_addr[5] = serial_number >> 0 & 0xff;
- dev->tx_queue_len = 0;
-
- /* New-style flags. */
- dev->flags = IFF_POINTOPOINT|IFF_NOARP;
- return 0;
}
/*
* SB1000 hardware routines to be used during open/configuration phases
*/
+
const int TimeOutJiffies = (int)(8.75 * HZ);
static inline void nicedelay(unsigned long usecs)
@@ -1279,6 +1251,8 @@ init_module(void)
void cleanup_module(void)
{
unregister_netdev(&dev_sb1000);
+ release_region(&dev_sb1000.base_addr, 16);
+ release_region(&dev_sb1000.rmem_end, 16);
kfree_s(dev_sb1000.priv, sizeof(struct sb1000_private));
dev_sb1000.priv = NULL;
}