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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).