patch-2.4.3 linux/drivers/net/ioc3-eth.c

Next file: linux/drivers/net/irda/irport.c
Previous file: linux/drivers/net/ibmlana.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.2/linux/drivers/net/ioc3-eth.c linux/drivers/net/ioc3-eth.c
@@ -67,11 +67,16 @@
 #include <asm/sn/sn0/ip27.h>
 #include <asm/pci/bridge.h>
 
-/* 32 RX buffers.  This is tunable in the range of 16 <= x < 512.  */
+/*
+ * 32 RX buffers.  This is tunable in the range of 16 <= x < 512.  The
+ * value must be a power of two.
+ */
 #define RX_BUFFS 64
 
-/* Private ioctls that de facto are well known and used for examply
-   by mii-tool.  */
+/*
+ * Private ioctls that de facto are well known and used for examply
+ * by mii-tool.
+ */
 #define SIOCGMIIPHY (SIOCDEVPRIVATE)	/* Read from current PHY */
 #define SIOCGMIIREG (SIOCDEVPRIVATE+1)	/* Read any PHY register */
 #define SIOCSMIIREG (SIOCDEVPRIVATE+2)	/* Write any PHY register */
@@ -707,8 +712,10 @@
 
 	if (ip->rxr == NULL) {
 		/* Allocate and initialize rx ring.  4kb = 512 entries  */
-		ip->rxr = (unsigned long *) get_free_page(GFP_KERNEL|GFP_ATOMIC);
+		ip->rxr = (unsigned long *) get_free_page(GFP_ATOMIC);
 		rxr = (unsigned long *) ip->rxr;
+		if (!rxr)
+			printk("ioc3_alloc_rings(): get_free_page() failed!\n");
 
 		/* Now the rx buffers.  The RX ring may be larger but
 		   we only allocate 16 buffers for now.  Need to tune
@@ -738,7 +745,9 @@
 
 	if (ip->txr == NULL) {
 		/* Allocate and initialize tx rings.  16kb = 128 bufs.  */
-		ip->txr = (struct ioc3_etxd *)__get_free_pages(GFP_KERNEL|GFP_ATOMIC, 2);
+		ip->txr = (struct ioc3_etxd *)__get_free_pages(GFP_KERNEL, 2);
+		if (!ip->txr)
+			printk("ioc3_alloc_rings(): get_free_page() failed!\n");
 		ip->tx_pi = 0;
 		ip->tx_ci = 0;
 	}
@@ -862,9 +871,6 @@
 	ioc3_init(dev);
 
 	netif_start_queue(dev);
-
-	MOD_INC_USE_COUNT;
-
 	return 0;
 }
 
@@ -880,27 +886,26 @@
 	free_irq(dev->irq, dev);
 
 	ioc3_free_rings(ip);
-
-	MOD_DEC_USE_COUNT;
-
 	return 0;
 }
 
-static int ioc3_pci_init(struct pci_dev *pdev)
+static int __devinit ioc3_probe(struct pci_dev *pdev,
+	                        const struct pci_device_id *ent)
 {
 	u16 mii0, mii_status, mii2, mii3, mii4;
-	struct net_device *dev = NULL;	// XXX
+	struct net_device *dev = NULL;
 	struct ioc3_private *ip;
 	struct ioc3 *ioc3;
 	unsigned long ioc3_base, ioc3_size;
 	u32 vendor, model, rev;
-	int phy;
+	int phy, err;
 
 	dev = init_etherdev(0, sizeof(struct ioc3_private));
 
 	if (!dev)
 		return -ENOMEM;
 
+	SET_MODULE_OWNER(dev);
 	ip = dev->priv;
 	memset(ip, 0, sizeof(*ip));
 
@@ -916,6 +921,11 @@
 	ioc3_base = pdev->resource[0].start;
 	ioc3_size = pdev->resource[0].end - ioc3_base;
 	ioc3 = (struct ioc3 *) ioremap(ioc3_base, ioc3_size);
+	if (!ioc3) {
+		printk(KERN_CRIT"%s: Unable to map device I/O.\n", dev->name);
+		err = -ENOMEM;
+		goto out_free;
+	}
 	ip->regs = ioc3;
 
 	spin_lock_init(&ip->ioc3_lock);
@@ -930,11 +940,8 @@
 	phy = ip->phy;
 	if (phy == -1) {
 		printk(KERN_CRIT"%s: Didn't find a PHY, goodbye.\n", dev->name);
-		ioc3_stop(dev);
-		free_irq(dev->irq, dev);
-		ioc3_free_rings(ip);
-
-		return -ENODEV;
+		err = -ENODEV;
+		goto out_stop;
 	}
 
 	mii0 = mii_read(ioc3, phy, 0);
@@ -967,34 +974,42 @@
 	dev->set_multicast_list	= ioc3_set_multicast_list;
 
 	return 0;
+
+out_stop:
+	ioc3_stop(dev);
+	free_irq(dev->irq, dev);
+	ioc3_free_rings(ip);
+out_free:
+	kfree(dev);
+	return err;
 }
 
-static int __init ioc3_probe(void)
+static void __devexit eepro100_remove_one (struct pci_dev *pdev)
 {
-	static int called = 0;
-	int cards = 0;
-
-	if (called)
-		return -ENODEV;
-	called = 1;
+	/* Later ... */
+}
 
-	if (pci_present()) {
-		struct pci_dev *pdev = NULL;
+static struct pci_device_id ioc3_pci_tbl[] __devinitdata = {
+	{ PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3, PCI_ANY_ID, PCI_ANY_ID },
+	{ 0 }
+};
+MODULE_DEVICE_TABLE(pci, ioc3_pci_tbl);
 
-		while ((pdev = pci_find_device(PCI_VENDOR_ID_SGI,
-		                               PCI_DEVICE_ID_SGI_IOC3, pdev))) {
-			if (ioc3_pci_init(pdev))
-				return -ENOMEM;
-			cards++;
-		}
-	}
+static struct pci_driver ioc3_driver = {
+	name:		"ioc3-eth",
+	id_table:	ioc3_pci_tbl,
+	probe:		ioc3_probe,
+	/* remove:		ioc3_remove_one, */
+};
 
-	return cards ? -ENODEV : 0;
+static int __init ioc3_init_module(void)
+{
+	return pci_module_init(&ioc3_driver);
 }
 
 static void __exit ioc3_cleanup_module(void)
 {
-	/* Later, when we really support modules.  */
+	pci_unregister_driver(&ioc3_driver);
 }
 
 static int
@@ -1192,10 +1207,8 @@
 	}
 }
 
-#ifdef MODULE
 MODULE_AUTHOR("Ralf Baechle <ralf@oss.sgi.com>");
 MODULE_DESCRIPTION("SGI IOC3 Ethernet driver");
-#endif /* MODULE */
 
-module_init(ioc3_probe);
+module_init(ioc3_init_module);
 module_exit(ioc3_cleanup_module);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)