From: Christoph Hellwig <hch@lst.de>
To: jgarzik@pobox.com
Cc: netdev@oss.sgi.com
Subject: [PATCH] switch sb1000 to new style net init & pnp
Date: Sat, 10 May 2003 12:47:10 +0200 [thread overview]
Message-ID: <20030510124710.A16201@lst.de> (raw)
This cleans up the driver big time and gets rid of a big ugly wart
in setup.c. Note that I don't have the hardware so this is only
compile-tested.
--- 1.25/drivers/net/Kconfig Mon Apr 28 00:05:07 2003
+++ edited/drivers/net/Kconfig Sat May 10 07:07:56 2003
@@ -158,7 +158,7 @@
config NET_SB1000
tristate "General Instruments Surfboard 1000"
- depends on NETDEVICES && ISAPNP
+ depends on NETDEVICES && PNP
---help---
This is a driver for the General Instrument (also known as
NextLevel) SURFboard 1000 internal
--- 1.16/drivers/net/sb1000.c Sun Apr 27 23:36:20 2003
+++ edited/drivers/net/sb1000.c Sat May 10 07:34:43 2003
@@ -49,7 +49,7 @@
#include <linux/skbuff.h>
#include <linux/delay.h> /* for udelay() */
#include <linux/etherdevice.h>
-#include <linux/isapnp.h>
+#include <linux/pnp.h>
#include <asm/bitops.h>
#include <asm/io.h>
@@ -131,146 +131,122 @@
static inline int sb1000_rx(struct net_device *dev);
static inline void sb1000_error_dpc(struct net_device *dev);
-static struct isapnp_device_id id_table[] = {
- { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
- ISAPNP_VENDOR('G','I','C'), ISAPNP_FUNCTION(0x1000), 0 },
- {0}
+static const struct pnp_device_id sb1000_pnp_ids[] = {
+ { "GIC1000", 0 },
+ { "", 0 }
};
+MODULE_DEVICE_TABLE(pnp, sb1000_pnp_ids);
-MODULE_DEVICE_TABLE(isapnp, id_table);
-
-/* probe for SB1000 using Plug-n-Play mechanism */
-int
-sb1000_probe(struct net_device *dev)
+static void
+sb1000_setup(struct net_device *dev)
{
+ dev->type = ARPHRD_ETHER;
+ dev->mtu = 1500;
+ dev->addr_len = ETH_ALEN;
+
+ /* New-style flags. */
+ dev->flags = IFF_POINTOPOINT|IFF_NOARP;
+}
+static int
+sb1000_probe_one(struct pnp_dev *pdev, const struct pnp_device_id *id)
+{
+ struct net_device *dev;
unsigned short ioaddr[2], irq;
- struct pnp_dev *idev=NULL;
unsigned int serial_number;
+ int error = -ENODEV;
- while(1)
- {
- /*
- * Find the card
- */
-
- idev=pnp_find_dev(NULL, ISAPNP_VENDOR('G','I','C'),
- ISAPNP_FUNCTION(0x1000), idev);
-
- /*
- * No card
- */
-
- if(idev==NULL || idev->card == NULL)
- return -ENODEV;
-
- /*
- * Bring it online
- */
-
- if (pnp_device_attach(idev) < 0)
- continue;
- if (pnp_activate_dev(idev) < 0) {
- __again:
- pnp_device_detach(idev);
- continue;
- }
-
- /*
- * Ports free ?
- */
-
- if(!pnp_port_valid(idev, 0) || !pnp_port_valid(idev, 1) || !pnp_irq_valid(idev, 0))
- goto __again;
+ if (pnp_device_attach(pdev) < 0)
+ return -ENODEV;
+ if (pnp_activate_dev(pdev) < 0)
+ goto out_detach;
+
+ if (!pnp_port_valid(pdev, 0) || !pnp_port_valid(pdev, 1))
+ goto out_disable;
+ if (!pnp_irq_valid(pdev, 0))
+ goto out_disable;
- serial_number = idev->card->serial;
+ serial_number = pdev->card->serial;
- ioaddr[0]=pnp_port_start(idev, 0);
- ioaddr[1]=pnp_port_start(idev, 0);
+ ioaddr[0] = pnp_port_start(pdev, 0);
+ ioaddr[1] = pnp_port_start(pdev, 0);
- irq = pnp_irq(idev, 0);
+ irq = pnp_irq(pdev, 0);
- /* check I/O base and IRQ */
- if (dev->base_addr != 0 && dev->base_addr != ioaddr[0])
- goto __again;
- if (dev->mem_start != 0 && dev->mem_start != ioaddr[1])
- goto __again;
- if (dev->irq != 0 && dev->irq != irq)
- goto __again;
-
- /*
- * Ok set it up.
- */
- if (!request_region(ioaddr[0], 16, dev->name))
- goto __again;
- if (!request_region(ioaddr[1], 16, dev->name)) {
- release_region(ioaddr[0], 16);
- goto __again;
- }
+ if (!request_region(ioaddr[0], 16, dev->name))
+ goto out_disable;
+ if (!request_region(ioaddr[1], 16, dev->name))
+ goto out_release_region0;
- dev->base_addr = ioaddr[0];
- /* mem_start holds the second I/O address */
- dev->mem_start = 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->mem_start, serial_number, dev->irq);
-
- dev = init_etherdev(dev, 0);
- if (!dev) {
- pnp_device_detach(idev);
- release_region(ioaddr[1], 16);
- release_region(ioaddr[0], 16);
- return -ENOMEM;
- }
- SET_MODULE_OWNER(dev);
-
- /* 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;
+ dev->base_addr = ioaddr[0];
+ /* mem_start holds the second I/O address */
+ dev->mem_start = ioaddr[1];
+ dev->irq = irq;
- /* Lock resources */
+ 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->mem_start, serial_number, dev->irq);
+
+ dev = alloc_netdev(sizeof(struct sb1000_private), "cm%d", sb1000_setup);
+ if (!dev) {
+ error = -ENOMEM;
+ goto out_release_regions;
+ }
+ SET_MODULE_OWNER(dev);
+
+ 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;
+
+ /* hardware address is 0:0:serial_number */
+ 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;
+
+ pnp_set_drvdata(pdev, dev);
+
+ error = register_netdev(dev);
+ if (error)
+ goto out_unregister;
+ return 0;
- return 0;
- }
-}
+ out_unregister:
+ unregister_netdev(dev);
+ out_release_regions:
+ release_region(ioaddr[1], 16);
+ out_release_region0:
+ release_region(ioaddr[0], 16);
+ out_disable:
+ pnp_disable_dev(pdev);
+ out_detach:
+ pnp_device_detach(pdev);
+ return error;
+}
+
+static void
+sb1000_remove_one(struct pnp_dev *pdev)
+{
+ struct net_device *dev = pnp_get_drvdata(pdev);
+
+ unregister_netdev(dev);
+ release_region(dev->base_addr, 16);
+ release_region(dev->mem_start, 16);
+}
+
+static struct pnp_driver sb1000_driver = {
+ .name = "sb1000",
+ .id_table = sb1000_pnp_ids,
+ .probe = sb1000_probe_one,
+ .remove = sb1000_remove_one,
+};
\f
/*
@@ -1207,60 +1183,21 @@
return 0;
}
-#ifdef MODULE
MODULE_AUTHOR("Franco Venturi <fventuri@mediaone.net>");
MODULE_DESCRIPTION("General Instruments SB1000 driver");
MODULE_LICENSE("GPL");
-MODULE_PARM(io, "1-2i");
-MODULE_PARM(irq, "i");
-MODULE_PARM_DESC(io, "SB1000 I/O base addresses");
-MODULE_PARM_DESC(irq, "SB1000 IRQ number");
-
-static struct net_device dev_sb1000;
-static int io[2];
-static int irq;
-
-int
-init_module(void)
+static int __init
+sb1000_init(void)
{
- int i;
- for (i = 0; i < 100; i++) {
- sprintf(dev_sb1000.name, "cm%d", i);
- if (dev_get(dev_sb1000.name) == 0) break;
- }
- if (i == 100) {
- printk(KERN_ERR "sb1000: can't register any device cm<n>\n");
- return -ENFILE;
- }
- dev_sb1000.init = sb1000_probe;
- dev_sb1000.base_addr = io[0];
- /* mem_start holds the second I/O address */
- dev_sb1000.mem_start = io[1];
- dev_sb1000.irq = irq;
- if (register_netdev(&dev_sb1000) != 0) {
- printk(KERN_ERR "sb1000: failed to register device (io: %03x,%03x "
- "irq: %d)\n", io[0], io[1], irq);
- return -EIO;
- }
- return 0;
+ return pnp_register_driver(&sb1000_driver);
}
-void cleanup_module(void)
+static void __exit
+sb1000_exit(void)
{
- unregister_netdev(&dev_sb1000);
- release_region(dev_sb1000.base_addr, 16);
- release_region(dev_sb1000.mem_start, 16);
- kfree(dev_sb1000.priv);
- dev_sb1000.priv = NULL;
+ pnp_unregister_driver(&sb1000_driver);
}
-#endif /* MODULE */
-\f
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -DMODULE -Wall -Wstrict-prototypes -O -m486 -c sb1000.c"
- * version-control: t
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- */
+
+module_init(sb1000_init);
+module_exit(sb1000_exit);
===== drivers/net/setup.c 1.9 vs edited =====
--- 1.9/drivers/net/setup.c Fri May 9 12:35:53 2003
+++ edited/drivers/net/setup.c Sat May 10 07:07:26 2003
@@ -21,14 +21,6 @@
extern int madgemc_probe(void);
-/* Pad device name to IFNAMSIZ=16. F.e. __PAD6 is string of 9 zeros. */
-#define __PAD6 "\0\0\0\0\0\0\0\0\0"
-#define __PAD5 __PAD6 "\0"
-#define __PAD4 __PAD5 "\0"
-#define __PAD3 __PAD4 "\0"
-#define __PAD2 __PAD3 "\0"
-
-
/*
* Devices in this list must do new style probing. That is they must
* allocate their own device objects and do their own bus scans.
@@ -84,7 +76,7 @@
* into them.
*/
-static void __init network_probe(void)
+void __init net_device_init(void)
{
struct net_probe *p = pci_probes;
@@ -93,29 +85,4 @@
p->status = p->probe();
p++;
}
-}
-
-static void __init special_device_init(void)
-{
-#ifdef CONFIG_NET_SB1000
- extern int sb1000_probe(struct net_device *dev);
-
- static struct net_device sb1000_dev = {
- .name = "cm0" __PAD3,
- .init = sb1000_probe,
- };
- register_netdev(&sb1000_dev);
-#endif
-}
-
-/*
- * Initialise network devices
- */
-
-void __init net_device_init(void)
-{
- /* Devices supporting the new^H^H^Hold probing API */
- network_probe();
- /* Special devices */
- special_device_init();
}
reply other threads:[~2003-05-10 10:47 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20030510124710.A16201@lst.de \
--to=hch@lst.de \
--cc=jgarzik@pobox.com \
--cc=netdev@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.