diff options
author | Pavel Roskin <proski@gnu.org> | 2006-04-07 04:10:57 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2006-04-24 16:15:52 -0400 |
commit | b884c872fa1917614b42a39020ffcca7fa9302b1 (patch) | |
tree | 82f5ba67f6b38c96804fb449e018d83fbdce65a1 | |
parent | c6fb2e9abef894efc4870e4c1e3aa4365b830a11 (diff) | |
download | kernel_samsung_tuna-b884c872fa1917614b42a39020ffcca7fa9302b1.zip kernel_samsung_tuna-b884c872fa1917614b42a39020ffcca7fa9302b1.tar.gz kernel_samsung_tuna-b884c872fa1917614b42a39020ffcca7fa9302b1.tar.bz2 |
[PATCH] orinoco: reduce differences between PCI drivers, create orinoco_pci.h
Make all Orinoco PCI drivers (orinoco_pci, orinoco_plx, orinoco_tmd and
orinoco_nortel) as similar as possible. Use the best implementation of
error handling, the best error messages, the best comments.
Put common code to orinoco_pci.h. For now, it's suspend and resume
functions and function for registering the network device.
Signed-off-by: Pavel Roskin <proski@gnu.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/orinoco_nortel.c | 240 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco_pci.c | 144 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco_pci.h | 125 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco_plx.c | 259 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco_tmd.c | 165 |
5 files changed, 368 insertions, 565 deletions
diff --git a/drivers/net/wireless/orinoco_nortel.c b/drivers/net/wireless/orinoco_nortel.c index 3fff013..deb22fb 100644 --- a/drivers/net/wireless/orinoco_nortel.c +++ b/drivers/net/wireless/orinoco_nortel.c @@ -1,5 +1,5 @@ /* orinoco_nortel.c - * + * * Driver for Prism II devices which would usually be driven by orinoco_cs, * but are connected to the PCI bus by a PCI-to-PCMCIA adapter used in * Nortel emobility, Symbol LA-4113 and Symbol LA-4123. @@ -50,17 +50,12 @@ #include <pcmcia/cisreg.h> #include "orinoco.h" +#include "orinoco_pci.h" #define COR_OFFSET (0xe0) /* COR attribute offset of Prism2 PC card */ #define COR_VALUE (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */ -/* Nortel specific data */ -struct nortel_pci_card { - unsigned long iobase1; - unsigned long iobase2; -}; - /* * Do a soft reset of the PCI card using the Configuration Option Register * We need this to get going... @@ -69,48 +64,48 @@ struct nortel_pci_card { * Note bis : Don't try to access HERMES_CMD during the reset phase. * It just won't work ! */ -static int nortel_pci_cor_reset(struct orinoco_private *priv) +static int orinoco_nortel_cor_reset(struct orinoco_private *priv) { - struct nortel_pci_card *card = priv->card; + struct orinoco_pci_card *card = priv->card; /* Assert the reset until the card notice */ - outw_p(8, card->iobase1 + 2); - inw(card->iobase2 + COR_OFFSET); - outw_p(0x80, card->iobase2 + COR_OFFSET); + iowrite16(8, card->bridge_io + 2); + ioread16(card->attr_io + COR_OFFSET); + iowrite16(0x80, card->attr_io + COR_OFFSET); mdelay(1); /* Give time for the card to recover from this hard effort */ - outw_p(0, card->iobase2 + COR_OFFSET); - outw_p(0, card->iobase2 + COR_OFFSET); + iowrite16(0, card->attr_io + COR_OFFSET); + iowrite16(0, card->attr_io + COR_OFFSET); mdelay(1); - /* set COR as usual */ - outw_p(COR_VALUE, card->iobase2 + COR_OFFSET); - outw_p(COR_VALUE, card->iobase2 + COR_OFFSET); + /* Set COR as usual */ + iowrite16(COR_VALUE, card->attr_io + COR_OFFSET); + iowrite16(COR_VALUE, card->attr_io + COR_OFFSET); mdelay(1); - outw_p(0x228, card->iobase1 + 2); + iowrite16(0x228, card->bridge_io + 2); return 0; } -static int nortel_pci_hw_init(struct nortel_pci_card *card) +static int orinoco_nortel_hw_init(struct orinoco_pci_card *card) { int i; u32 reg; - /* setup bridge */ - if (inw(card->iobase1) & 1) { + /* Setup bridge */ + if (ioread16(card->bridge_io) & 1) { printk(KERN_ERR PFX "brg1 answer1 wrong\n"); return -EBUSY; } - outw_p(0x118, card->iobase1 + 2); - outw_p(0x108, card->iobase1 + 2); + iowrite16(0x118, card->bridge_io + 2); + iowrite16(0x108, card->bridge_io + 2); mdelay(30); - outw_p(0x8, card->iobase1 + 2); + iowrite16(0x8, card->bridge_io + 2); for (i = 0; i < 30; i++) { mdelay(30); - if (inw(card->iobase1) & 0x10) { + if (ioread16(card->bridge_io) & 0x10) { break; } } @@ -118,42 +113,42 @@ static int nortel_pci_hw_init(struct nortel_pci_card *card) printk(KERN_ERR PFX "brg1 timed out\n"); return -EBUSY; } - if (inw(card->iobase2 + 0xe0) & 1) { + if (ioread16(card->attr_io + COR_OFFSET) & 1) { printk(KERN_ERR PFX "brg2 answer1 wrong\n"); return -EBUSY; } - if (inw(card->iobase2 + 0xe2) & 1) { + if (ioread16(card->attr_io + COR_OFFSET + 2) & 1) { printk(KERN_ERR PFX "brg2 answer2 wrong\n"); return -EBUSY; } - if (inw(card->iobase2 + 0xe4) & 1) { + if (ioread16(card->attr_io + COR_OFFSET + 4) & 1) { printk(KERN_ERR PFX "brg2 answer3 wrong\n"); return -EBUSY; } - /* set the PCMCIA COR-Register */ - outw_p(COR_VALUE, card->iobase2 + COR_OFFSET); + /* Set the PCMCIA COR-Register */ + iowrite16(COR_VALUE, card->attr_io + COR_OFFSET); mdelay(1); - reg = inw(card->iobase2 + COR_OFFSET); + reg = ioread16(card->attr_io + COR_OFFSET); if (reg != COR_VALUE) { printk(KERN_ERR PFX "Error setting COR value (reg=%x)\n", reg); return -EBUSY; } - /* set leds */ - outw_p(1, card->iobase1 + 10); + /* Set LEDs */ + iowrite16(1, card->bridge_io + 10); return 0; } -static int nortel_pci_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) +static int orinoco_nortel_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) { int err; struct orinoco_private *priv; - struct nortel_pci_card *card; + struct orinoco_pci_card *card; struct net_device *dev; - void __iomem *iomem; + void __iomem *hermes_io, *bridge_io, *attr_io; err = pci_enable_device(pdev); if (err) { @@ -162,19 +157,34 @@ static int nortel_pci_init_one(struct pci_dev *pdev, } err = pci_request_regions(pdev, DRIVER_NAME); - if (err != 0) { + if (err) { printk(KERN_ERR PFX "Cannot obtain PCI resources\n"); goto fail_resources; } - iomem = pci_iomap(pdev, 2, 0); - if (!iomem) { - err = -ENOMEM; - goto fail_map_io; + bridge_io = pci_iomap(pdev, 0, 0); + if (!bridge_io) { + printk(KERN_ERR PFX "Cannot map bridge registers\n"); + err = -EIO; + goto fail_map_bridge; + } + + attr_io = pci_iomap(pdev, 1, 0); + if (!attr_io) { + printk(KERN_ERR PFX "Cannot map PCMCIA attributes\n"); + err = -EIO; + goto fail_map_attr; + } + + hermes_io = pci_iomap(pdev, 2, 0); + if (!hermes_io) { + printk(KERN_ERR PFX "Cannot map chipset registers\n"); + err = -EIO; + goto fail_map_hermes; } /* Allocate network device */ - dev = alloc_orinocodev(sizeof(*card), nortel_pci_cor_reset); + dev = alloc_orinocodev(sizeof(*card), orinoco_nortel_cor_reset); if (!dev) { printk(KERN_ERR PFX "Cannot allocate network device\n"); err = -ENOMEM; @@ -183,16 +193,12 @@ static int nortel_pci_init_one(struct pci_dev *pdev, priv = netdev_priv(dev); card = priv->card; - card->iobase1 = pci_resource_start(pdev, 0); - card->iobase2 = pci_resource_start(pdev, 1); - dev->base_addr = pci_resource_start(pdev, 2); + card->bridge_io = bridge_io; + card->attr_io = attr_io; SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); - hermes_struct_init(&priv->hw, iomem, HERMES_16BIT_REGSPACING); - - printk(KERN_DEBUG PFX "Detected Nortel PCI device at %s irq:%d, " - "io addr:0x%lx\n", pci_name(pdev), pdev->irq, dev->base_addr); + hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING); err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, dev->name, dev); @@ -201,21 +207,20 @@ static int nortel_pci_init_one(struct pci_dev *pdev, err = -EBUSY; goto fail_irq; } - dev->irq = pdev->irq; + orinoco_pci_setup_netdev(dev, pdev, 2); - err = nortel_pci_hw_init(card); + err = orinoco_nortel_hw_init(card); if (err) { printk(KERN_ERR PFX "Hardware initialization failed\n"); goto fail; } - err = nortel_pci_cor_reset(priv); + err = orinoco_nortel_cor_reset(priv); if (err) { printk(KERN_ERR PFX "Initial reset failed\n"); goto fail; } - err = register_netdev(dev); if (err) { printk(KERN_ERR PFX "Cannot register network device\n"); @@ -234,9 +239,15 @@ static int nortel_pci_init_one(struct pci_dev *pdev, free_orinocodev(dev); fail_alloc: - pci_iounmap(pdev, iomem); + pci_iounmap(pdev, hermes_io); + + fail_map_hermes: + pci_iounmap(pdev, attr_io); + + fail_map_attr: + pci_iounmap(pdev, bridge_io); - fail_map_io: + fail_map_bridge: pci_release_regions(pdev); fail_resources: @@ -245,103 +256,27 @@ static int nortel_pci_init_one(struct pci_dev *pdev, return err; } -static void __devexit nortel_pci_remove_one(struct pci_dev *pdev) +static void __devexit orinoco_nortel_remove_one(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct orinoco_private *priv = netdev_priv(dev); - struct nortel_pci_card *card = priv->card; + struct orinoco_pci_card *card = priv->card; - /* clear leds */ - outw_p(0, card->iobase1 + 10); + /* Clear LEDs */ + iowrite16(0, card->bridge_io + 10); unregister_netdev(dev); free_irq(dev->irq, dev); pci_set_drvdata(pdev, NULL); free_orinocodev(dev); pci_iounmap(pdev, priv->hw.iobase); + pci_iounmap(pdev, card->attr_io); + pci_iounmap(pdev, card->bridge_io); pci_release_regions(pdev); pci_disable_device(pdev); } -static int orinoco_nortel_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct net_device *dev = pci_get_drvdata(pdev); - struct orinoco_private *priv = netdev_priv(dev); - unsigned long flags; - int err; - - err = orinoco_lock(priv, &flags); - if (err) { - printk(KERN_ERR "%s: cannot lock hardware for suspend\n", - dev->name); - return err; - } - - err = __orinoco_down(dev); - if (err) - printk(KERN_WARNING "%s: error %d bringing interface down " - "for suspend\n", dev->name, err); - - netif_device_detach(dev); - - priv->hw_unavailable++; - - orinoco_unlock(priv, &flags); - - free_irq(pdev->irq, dev); - pci_save_state(pdev); - pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); - - return 0; -} - -static int orinoco_nortel_resume(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - struct orinoco_private *priv = netdev_priv(dev); - unsigned long flags; - int err; - - pci_set_power_state(pdev, 0); - pci_enable_device(pdev); - pci_restore_state(pdev); - - err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, - dev->name, dev); - if (err) { - printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n", - dev->name); - pci_disable_device(pdev); - return -EBUSY; - } - - err = orinoco_reinit_firmware(dev); - if (err) { - printk(KERN_ERR "%s: error %d re-initializing firmware " - "on resume\n", dev->name, err); - return err; - } - - spin_lock_irqsave(&priv->lock, flags); - - netif_device_attach(dev); - - priv->hw_unavailable--; - - if (priv->open && (! priv->hw_unavailable)) { - err = __orinoco_up(dev); - if (err) - printk(KERN_ERR "%s: Error %d restarting card on resume\n", - dev->name, err); - } - - spin_unlock_irqrestore(&priv->lock, flags); - - return 0; -} - -static struct pci_device_id nortel_pci_id_table[] = { +static struct pci_device_id orinoco_nortel_id_table[] = { /* Nortel emobility PCI */ {0x126c, 0x8030, PCI_ANY_ID, PCI_ANY_ID,}, /* Symbol LA-4123 PCI */ @@ -349,15 +284,15 @@ static struct pci_device_id nortel_pci_id_table[] = { {0,}, }; -MODULE_DEVICE_TABLE(pci, nortel_pci_id_table); +MODULE_DEVICE_TABLE(pci, orinoco_nortel_id_table); -static struct pci_driver nortel_pci_driver = { +static struct pci_driver orinoco_nortel_driver = { .name = DRIVER_NAME, - .id_table = nortel_pci_id_table, - .probe = nortel_pci_init_one, - .remove = __devexit_p(nortel_pci_remove_one), - .suspend = orinoco_nortel_suspend, - .resume = orinoco_nortel_resume, + .id_table = orinoco_nortel_id_table, + .probe = orinoco_nortel_init_one, + .remove = __devexit_p(orinoco_nortel_remove_one), + .suspend = orinoco_pci_suspend, + .resume = orinoco_pci_resume, }; static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION @@ -367,20 +302,19 @@ MODULE_DESCRIPTION ("Driver for wireless LAN cards using the Nortel PCI bridge"); MODULE_LICENSE("Dual MPL/GPL"); -static int __init nortel_pci_init(void) +static int __init orinoco_nortel_init(void) { printk(KERN_DEBUG "%s\n", version); - return pci_module_init(&nortel_pci_driver); + return pci_module_init(&orinoco_nortel_driver); } -static void __exit nortel_pci_exit(void) +static void __exit orinoco_nortel_exit(void) { - pci_unregister_driver(&nortel_pci_driver); - ssleep(1); + pci_unregister_driver(&orinoco_nortel_driver); } -module_init(nortel_pci_init); -module_exit(nortel_pci_exit); +module_init(orinoco_nortel_init); +module_exit(orinoco_nortel_exit); /* * Local variables: diff --git a/drivers/net/wireless/orinoco_pci.c b/drivers/net/wireless/orinoco_pci.c index 75df90f..41efac2 100644 --- a/drivers/net/wireless/orinoco_pci.c +++ b/drivers/net/wireless/orinoco_pci.c @@ -100,6 +100,7 @@ #include <linux/pci.h> #include "orinoco.h" +#include "orinoco_pci.h" /* All the magic there is from wlan-ng */ /* Magic offset of the reset register of the PCI card */ @@ -113,11 +114,6 @@ #define HERMES_PCI_COR_OFFT (500) /* ms */ #define HERMES_PCI_COR_BUSYT (500) /* ms */ -/* Orinoco PCI specific data */ -struct orinoco_pci_card { - void __iomem *pci_ioaddr; -}; - /* * Do a soft reset of the PCI card using the Configuration Option Register * We need this to get going... @@ -131,12 +127,11 @@ struct orinoco_pci_card { * Note bis : Don't try to access HERMES_CMD during the reset phase. * It just won't work ! */ -static int -orinoco_pci_cor_reset(struct orinoco_private *priv) +static int orinoco_pci_cor_reset(struct orinoco_private *priv) { hermes_t *hw = &priv->hw; - unsigned long timeout; - u16 reg; + unsigned long timeout; + u16 reg; /* Assert the reset until the card notice */ hermes_write_regn(hw, PCI_COR, HERMES_PCI_COR_MASK); @@ -163,17 +158,14 @@ orinoco_pci_cor_reset(struct orinoco_private *priv) return 0; } -/* - * Initialise a card. Mostly similar to PLX code. - */ static int orinoco_pci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { - int err = 0; - void __iomem *pci_ioaddr = NULL; - struct orinoco_private *priv = NULL; + int err; + struct orinoco_private *priv; struct orinoco_pci_card *card; - struct net_device *dev = NULL; + struct net_device *dev; + void __iomem *hermes_io; err = pci_enable_device(pdev); if (err) { @@ -182,38 +174,32 @@ static int orinoco_pci_init_one(struct pci_dev *pdev, } err = pci_request_regions(pdev, DRIVER_NAME); - if (err != 0) { + if (err) { printk(KERN_ERR PFX "Cannot obtain PCI resources\n"); goto fail_resources; } - /* Resource 0 is mapped to the hermes registers */ - pci_ioaddr = pci_iomap(pdev, 0, 0); - if (!pci_ioaddr) { + hermes_io = pci_iomap(pdev, 0, 0); + if (!hermes_io) { + printk(KERN_ERR PFX "Cannot remap chipset registers\n"); err = -EIO; - printk(KERN_ERR PFX "Cannot remap hardware registers\n"); - goto fail_map; + goto fail_map_hermes; } /* Allocate network device */ dev = alloc_orinocodev(sizeof(*card), orinoco_pci_cor_reset); - if (! dev) { + if (!dev) { + printk(KERN_ERR PFX "Cannot allocate network device\n"); err = -ENOMEM; goto fail_alloc; } priv = netdev_priv(dev); card = priv->card; - card->pci_ioaddr = pci_ioaddr; - dev->mem_start = pci_resource_start(pdev, 0); - dev->mem_end = dev->mem_start + pci_resource_len(pdev, 0) - 1; SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); - hermes_struct_init(&priv->hw, pci_ioaddr, HERMES_32BIT_REGSPACING); - - printk(KERN_DEBUG PFX "Detected device %s, mem:0x%lx-0x%lx, irq %d\n", - pci_name(pdev), dev->mem_start, dev->mem_end, pdev->irq); + hermes_struct_init(&priv->hw, hermes_io, HERMES_32BIT_REGSPACING); err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, dev->name, dev); @@ -222,9 +208,8 @@ static int orinoco_pci_init_one(struct pci_dev *pdev, err = -EBUSY; goto fail_irq; } - dev->irq = pdev->irq; + orinoco_pci_setup_netdev(dev, pdev, 0); - /* Perform a COR reset to start the card */ err = orinoco_pci_cor_reset(priv); if (err) { printk(KERN_ERR PFX "Initial reset failed\n"); @@ -233,7 +218,7 @@ static int orinoco_pci_init_one(struct pci_dev *pdev, err = register_netdev(dev); if (err) { - printk(KERN_ERR PFX "Failed to register net device\n"); + printk(KERN_ERR PFX "Cannot register network device\n"); goto fail; } @@ -249,9 +234,9 @@ static int orinoco_pci_init_one(struct pci_dev *pdev, free_orinocodev(dev); fail_alloc: - iounmap(pci_ioaddr); + pci_iounmap(pdev, hermes_io); - fail_map: + fail_map_hermes: pci_release_regions(pdev); fail_resources: @@ -264,98 +249,17 @@ static void __devexit orinoco_pci_remove_one(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct orinoco_private *priv = netdev_priv(dev); - struct orinoco_pci_card *card = priv->card; unregister_netdev(dev); free_irq(dev->irq, dev); pci_set_drvdata(pdev, NULL); free_orinocodev(dev); - iounmap(card->pci_ioaddr); + pci_iounmap(pdev, priv->hw.iobase); pci_release_regions(pdev); pci_disable_device(pdev); } -static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct net_device *dev = pci_get_drvdata(pdev); - struct orinoco_private *priv = netdev_priv(dev); - unsigned long flags; - int err; - - - err = orinoco_lock(priv, &flags); - if (err) { - printk(KERN_ERR "%s: hw_unavailable on orinoco_pci_suspend\n", - dev->name); - return err; - } - - err = __orinoco_down(dev); - if (err) - printk(KERN_WARNING "%s: orinoco_pci_suspend(): Error %d downing interface\n", - dev->name, err); - - netif_device_detach(dev); - - priv->hw_unavailable++; - - orinoco_unlock(priv, &flags); - - free_irq(pdev->irq, dev); - pci_save_state(pdev); - pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); - - return 0; -} - -static int orinoco_pci_resume(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - struct orinoco_private *priv = netdev_priv(dev); - unsigned long flags; - int err; - - printk(KERN_DEBUG "%s: Orinoco-PCI waking up\n", dev->name); - - pci_set_power_state(pdev, 0); - pci_enable_device(pdev); - pci_restore_state(pdev); - - err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, - dev->name, dev); - if (err) { - printk(KERN_ERR "%s: Cannot re-allocate IRQ\n", dev->name); - pci_disable_device(pdev); - return -EBUSY; - } - - err = orinoco_reinit_firmware(dev); - if (err) { - printk(KERN_ERR "%s: Error %d re-initializing firmware on orinoco_pci_resume()\n", - dev->name, err); - return err; - } - - spin_lock_irqsave(&priv->lock, flags); - - netif_device_attach(dev); - - priv->hw_unavailable--; - - if (priv->open && (! priv->hw_unavailable)) { - err = __orinoco_up(dev); - if (err) - printk(KERN_ERR "%s: Error %d restarting card on orinoco_pci_resume()\n", - dev->name, err); - } - - spin_unlock_irqrestore(&priv->lock, flags); - - return 0; -} - -static struct pci_device_id orinoco_pci_pci_id_table[] = { +static struct pci_device_id orinoco_pci_id_table[] = { /* Intersil Prism 3 */ {0x1260, 0x3872, PCI_ANY_ID, PCI_ANY_ID,}, /* Intersil Prism 2.5 */ @@ -365,11 +269,11 @@ static struct pci_device_id orinoco_pci_pci_id_table[] = { {0,}, }; -MODULE_DEVICE_TABLE(pci, orinoco_pci_pci_id_table); +MODULE_DEVICE_TABLE(pci, orinoco_pci_id_table); static struct pci_driver orinoco_pci_driver = { .name = DRIVER_NAME, - .id_table = orinoco_pci_pci_id_table, + .id_table = orinoco_pci_id_table, .probe = orinoco_pci_init_one, .remove = __devexit_p(orinoco_pci_remove_one), .suspend = orinoco_pci_suspend, diff --git a/drivers/net/wireless/orinoco_pci.h b/drivers/net/wireless/orinoco_pci.h new file mode 100644 index 0000000..b05a9a5 --- /dev/null +++ b/drivers/net/wireless/orinoco_pci.h @@ -0,0 +1,125 @@ +/* orinoco_pci.h + * + * Common code for all Orinoco drivers for PCI devices, including + * both native PCI and PCMCIA-to-PCI bridges. + * + * Copyright (C) 2005, Pavel Roskin. + * See orinoco.c for license. + */ + +#ifndef _ORINOCO_PCI_H +#define _ORINOCO_PCI_H + +#include <linux/netdevice.h> + +/* Driver specific data */ +struct orinoco_pci_card { + void __iomem *bridge_io; + void __iomem *attr_io; +}; + +/* Set base address or memory range of the network device based on + * the PCI device it's using. Specify BAR of the "main" resource. + * To be used after request_irq(). */ +static inline void orinoco_pci_setup_netdev(struct net_device *dev, + struct pci_dev *pdev, int bar) +{ + char *range_type; + unsigned long start = pci_resource_start(pdev, bar); + unsigned long len = pci_resource_len(pdev, bar); + unsigned long flags = pci_resource_flags(pdev, bar); + unsigned long end = start + len - 1; + + dev->irq = pdev->irq; + if (flags & IORESOURCE_IO) { + dev->base_addr = start; + range_type = "ports"; + } else { + dev->mem_start = start; + dev->mem_end = end; + range_type = "memory"; + } + + printk(KERN_DEBUG PFX "%s: irq %d, %s 0x%lx-0x%lx\n", + pci_name(pdev), pdev->irq, range_type, start, end); +} + +static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct orinoco_private *priv = netdev_priv(dev); + unsigned long flags; + int err; + + err = orinoco_lock(priv, &flags); + if (err) { + printk(KERN_ERR "%s: cannot lock hardware for suspend\n", + dev->name); + return err; + } + + err = __orinoco_down(dev); + if (err) + printk(KERN_WARNING "%s: error %d bringing interface down " + "for suspend\n", dev->name, err); + + netif_device_detach(dev); + + priv->hw_unavailable++; + + orinoco_unlock(priv, &flags); + + free_irq(pdev->irq, dev); + pci_save_state(pdev); + pci_disable_device(pdev); + pci_set_power_state(pdev, PCI_D3hot); + + return 0; +} + +static int orinoco_pci_resume(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct orinoco_private *priv = netdev_priv(dev); + unsigned long flags; + int err; + + pci_set_power_state(pdev, 0); + pci_enable_device(pdev); + pci_restore_state(pdev); + + err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, + dev->name, dev); + if (err) { + printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n", + dev->name); + pci_disable_device(pdev); + return -EBUSY; + } + + err = orinoco_reinit_firmware(dev); + if (err) { + printk(KERN_ERR "%s: error %d re-initializing firmware " + "on resume\n", dev->name, err); + return err; + } + + spin_lock_irqsave(&priv->lock, flags); + + netif_device_attach(dev); + + priv->hw_unavailable--; + + if (priv->open && (! priv->hw_unavailable)) { + err = __orinoco_up(dev); + if (err) + printk(KERN_ERR "%s: Error %d restarting card on resume\n", + dev->name, err); + } + + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + +#endif /* _ORINOCO_PCI_H */ diff --git a/drivers/net/wireless/orinoco_plx.c b/drivers/net/wireless/orinoco_plx.c index 3fe7a2f..c00388e 100644 --- a/drivers/net/wireless/orinoco_plx.c +++ b/drivers/net/wireless/orinoco_plx.c @@ -33,7 +33,7 @@ * Caution: this is experimental and probably buggy. For success and * failure reports for different cards and adaptors, see - * orinoco_plx_pci_id_table near the end of the file. If you have a + * orinoco_plx_id_table near the end of the file. If you have a * card we don't have the PCI id for, and looks like it should work, * drop me mail with the id and "it works"/"it doesn't work". * @@ -125,6 +125,7 @@ #include <pcmcia/cisreg.h> #include "orinoco.h" +#include "orinoco_pci.h" #define COR_OFFSET (0x3e0) /* COR attribute offset of Prism2 PC card */ #define COR_VALUE (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */ @@ -134,30 +135,20 @@ #define PLX_INTCSR 0x4c /* Interrupt Control & Status Register */ #define PLX_INTCSR_INTEN (1<<6) /* Interrupt Enable bit */ -static const u8 cis_magic[] = { - 0x01, 0x03, 0x00, 0x00, 0xff, 0x17, 0x04, 0x67 -}; - -/* Orinoco PLX specific data */ -struct orinoco_plx_card { - void __iomem *attr_mem; -}; - /* * Do a soft reset of the card using the Configuration Option Register */ static int orinoco_plx_cor_reset(struct orinoco_private *priv) { hermes_t *hw = &priv->hw; - struct orinoco_plx_card *card = priv->card; - u8 __iomem *attr_mem = card->attr_mem; + struct orinoco_pci_card *card = priv->card; unsigned long timeout; u16 reg; - writeb(COR_VALUE | COR_RESET, attr_mem + COR_OFFSET); + iowrite8(COR_VALUE | COR_RESET, card->attr_io + COR_OFFSET); mdelay(1); - writeb(COR_VALUE, attr_mem + COR_OFFSET); + iowrite8(COR_VALUE, card->attr_io + COR_OFFSET); mdelay(1); /* Just in case, wait more until the card is no longer busy */ @@ -168,7 +159,7 @@ static int orinoco_plx_cor_reset(struct orinoco_private *priv) reg = hermes_read_regn(hw, CMD); } - /* Did we timeout ? */ + /* Still busy? */ if (reg & HERMES_CMD_BUSY) { printk(KERN_ERR PFX "Busy timeout\n"); return -ETIMEDOUT; @@ -177,20 +168,55 @@ static int orinoco_plx_cor_reset(struct orinoco_private *priv) return 0; } +static int orinoco_plx_hw_init(struct orinoco_pci_card *card) +{ + int i; + u32 csr_reg; + static const u8 cis_magic[] = { + 0x01, 0x03, 0x00, 0x00, 0xff, 0x17, 0x04, 0x67 + }; + + printk(KERN_DEBUG PFX "CIS: "); + for (i = 0; i < 16; i++) { + printk("%02X:", ioread8(card->attr_io + (i << 1))); + } + printk("\n"); + + /* Verify whether a supported PC card is present */ + /* FIXME: we probably need to be smarted about this */ + for (i = 0; i < sizeof(cis_magic); i++) { + if (cis_magic[i] != ioread8(card->attr_io + (i << 1))) { + printk(KERN_ERR PFX "The CIS value of Prism2 PC " + "card is unexpected\n"); + return -ENODEV; + } + } + + /* bjoern: We need to tell the card to enable interrupts, in + case the serial eprom didn't do this already. See the + PLX9052 data book, p8-1 and 8-24 for reference. */ + csr_reg = ioread32(card->bridge_io + PLX_INTCSR); + if (!(csr_reg & PLX_INTCSR_INTEN)) { + csr_reg |= PLX_INTCSR_INTEN; + iowrite32(csr_reg, card->bridge_io + PLX_INTCSR); + csr_reg = ioread32(card->bridge_io + PLX_INTCSR); + if (!(csr_reg & PLX_INTCSR_INTEN)) { + printk(KERN_ERR PFX "Cannot enable interrupts\n"); + return -EIO; + } + } + + return 0; +} static int orinoco_plx_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { - int err = 0; - u8 __iomem *attr_mem = NULL; - u32 csr_reg, plx_addr; - struct orinoco_private *priv = NULL; - struct orinoco_plx_card *card; - unsigned long pccard_ioaddr = 0; - unsigned long pccard_iolen = 0; - struct net_device *dev = NULL; - void __iomem *mem; - int i; + int err; + struct orinoco_private *priv; + struct orinoco_pci_card *card; + struct net_device *dev; + void __iomem *hermes_io, *attr_io, *bridge_io; err = pci_enable_device(pdev); if (err) { @@ -199,30 +225,30 @@ static int orinoco_plx_init_one(struct pci_dev *pdev, } err = pci_request_regions(pdev, DRIVER_NAME); - if (err != 0) { + if (err) { printk(KERN_ERR PFX "Cannot obtain PCI resources\n"); goto fail_resources; } - /* Resource 1 is mapped to PLX-specific registers */ - plx_addr = pci_resource_start(pdev, 1); + bridge_io = pci_iomap(pdev, 1, 0); + if (!bridge_io) { + printk(KERN_ERR PFX "Cannot map bridge registers\n"); + err = -EIO; + goto fail_map_bridge; + } - /* Resource 2 is mapped to the PCMCIA attribute memory */ - attr_mem = ioremap(pci_resource_start(pdev, 2), - pci_resource_len(pdev, 2)); - if (!attr_mem) { - printk(KERN_ERR PFX "Cannot remap PCMCIA space\n"); + attr_io = pci_iomap(pdev, 2, 0); + if (!attr_io) { + printk(KERN_ERR PFX "Cannot map PCMCIA attributes\n"); + err = -EIO; goto fail_map_attr; } - /* Resource 3 is mapped to the PCMCIA I/O address space */ - pccard_ioaddr = pci_resource_start(pdev, 3); - pccard_iolen = pci_resource_len(pdev, 3); - - mem = pci_iomap(pdev, 3, 0); - if (!mem) { - err = -ENOMEM; - goto fail_map_io; + hermes_io = pci_iomap(pdev, 3, 0); + if (!hermes_io) { + printk(KERN_ERR PFX "Cannot map chipset registers\n"); + err = -EIO; + goto fail_map_hermes; } /* Allocate network device */ @@ -235,16 +261,12 @@ static int orinoco_plx_init_one(struct pci_dev *pdev, priv = netdev_priv(dev); card = priv->card; - card->attr_mem = attr_mem; - dev->base_addr = pccard_ioaddr; + card->bridge_io = bridge_io; + card->attr_io = attr_io; SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); - hermes_struct_init(&priv->hw, mem, HERMES_16BIT_REGSPACING); - - printk(KERN_DEBUG PFX "Detected Orinoco/Prism2 PLX device " - "at %s irq:%d, io addr:0x%lx\n", pci_name(pdev), pdev->irq, - pccard_ioaddr); + hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING); err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, dev->name, dev); @@ -253,20 +275,12 @@ static int orinoco_plx_init_one(struct pci_dev *pdev, err = -EBUSY; goto fail_irq; } - dev->irq = pdev->irq; + orinoco_pci_setup_netdev(dev, pdev, 2); - /* bjoern: We need to tell the card to enable interrupts, in - case the serial eprom didn't do this already. See the - PLX9052 data book, p8-1 and 8-24 for reference. */ - csr_reg = inl(plx_addr + PLX_INTCSR); - if (!(csr_reg & PLX_INTCSR_INTEN)) { - csr_reg |= PLX_INTCSR_INTEN; - outl(csr_reg, plx_addr + PLX_INTCSR); - csr_reg = inl(plx_addr + PLX_INTCSR); - if (!(csr_reg & PLX_INTCSR_INTEN)) { - printk(KERN_ERR PFX "Cannot enable interrupts\n"); - goto fail; - } + err = orinoco_plx_hw_init(card); + if (err) { + printk(KERN_ERR PFX "Hardware initialization failed\n"); + goto fail; } err = orinoco_plx_cor_reset(priv); @@ -275,23 +289,6 @@ static int orinoco_plx_init_one(struct pci_dev *pdev, goto fail; } - printk(KERN_DEBUG PFX "CIS: "); - for (i = 0; i < 16; i++) { - printk("%02X:", readb(attr_mem + 2*i)); - } - printk("\n"); - - /* Verify whether a supported PC card is present */ - /* FIXME: we probably need to be smarted about this */ - for (i = 0; i < sizeof(cis_magic); i++) { - if (cis_magic[i] != readb(attr_mem +2*i)) { - printk(KERN_ERR PFX "The CIS value of Prism2 PC " - "card is unexpected\n"); - err = -EIO; - goto fail; - } - } - err = register_netdev(dev); if (err) { printk(KERN_ERR PFX "Cannot register network device\n"); @@ -310,12 +307,15 @@ static int orinoco_plx_init_one(struct pci_dev *pdev, free_orinocodev(dev); fail_alloc: - pci_iounmap(pdev, mem); + pci_iounmap(pdev, hermes_io); - fail_map_io: - iounmap(attr_mem); + fail_map_hermes: + pci_iounmap(pdev, attr_io); fail_map_attr: + pci_iounmap(pdev, bridge_io); + + fail_map_bridge: pci_release_regions(pdev); fail_resources: @@ -328,100 +328,20 @@ static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct orinoco_private *priv = netdev_priv(dev); - struct orinoco_plx_card *card = priv->card; - u8 __iomem *attr_mem = card->attr_mem; - - BUG_ON(! dev); + struct orinoco_pci_card *card = priv->card; unregister_netdev(dev); free_irq(dev->irq, dev); pci_set_drvdata(pdev, NULL); free_orinocodev(dev); pci_iounmap(pdev, priv->hw.iobase); - iounmap(attr_mem); + pci_iounmap(pdev, card->attr_io); + pci_iounmap(pdev, card->bridge_io); pci_release_regions(pdev); pci_disable_device(pdev); } -static int orinoco_plx_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct net_device *dev = pci_get_drvdata(pdev); - struct orinoco_private *priv = netdev_priv(dev); - unsigned long flags; - int err; - - err = orinoco_lock(priv, &flags); - if (err) { - printk(KERN_ERR "%s: cannot lock hardware for suspend\n", - dev->name); - return err; - } - - err = __orinoco_down(dev); - if (err) - printk(KERN_WARNING "%s: error %d bringing interface down " - "for suspend\n", dev->name, err); - - netif_device_detach(dev); - - priv->hw_unavailable++; - - orinoco_unlock(priv, &flags); - - free_irq(pdev->irq, dev); - pci_save_state(pdev); - pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); - - return 0; -} - -static int orinoco_plx_resume(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - struct orinoco_private *priv = netdev_priv(dev); - unsigned long flags; - int err; - - pci_set_power_state(pdev, 0); - pci_enable_device(pdev); - pci_restore_state(pdev); - - err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, - dev->name, dev); - if (err) { - printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n", - dev->name); - pci_disable_device(pdev); - return -EBUSY; - } - - err = orinoco_reinit_firmware(dev); - if (err) { - printk(KERN_ERR "%s: error %d re-initializing firmware " - "on resume\n", dev->name, err); - return err; - } - - spin_lock_irqsave(&priv->lock, flags); - - netif_device_attach(dev); - - priv->hw_unavailable--; - - if (priv->open && (! priv->hw_unavailable)) { - err = __orinoco_up(dev); - if (err) - printk(KERN_ERR "%s: Error %d restarting card on resume\n", - dev->name, err); - } - - spin_unlock_irqrestore(&priv->lock, flags); - - return 0; -} - -static struct pci_device_id orinoco_plx_pci_id_table[] = { +static struct pci_device_id orinoco_plx_id_table[] = { {0x111a, 0x1023, PCI_ANY_ID, PCI_ANY_ID,}, /* Siemens SpeedStream SS1023 */ {0x1385, 0x4100, PCI_ANY_ID, PCI_ANY_ID,}, /* Netgear MA301 */ {0x15e8, 0x0130, PCI_ANY_ID, PCI_ANY_ID,}, /* Correga - does this work? */ @@ -439,15 +359,15 @@ static struct pci_device_id orinoco_plx_pci_id_table[] = { {0,}, }; -MODULE_DEVICE_TABLE(pci, orinoco_plx_pci_id_table); +MODULE_DEVICE_TABLE(pci, orinoco_plx_id_table); static struct pci_driver orinoco_plx_driver = { .name = DRIVER_NAME, - .id_table = orinoco_plx_pci_id_table, + .id_table = orinoco_plx_id_table, .probe = orinoco_plx_init_one, .remove = __devexit_p(orinoco_plx_remove_one), - .suspend = orinoco_plx_suspend, - .resume = orinoco_plx_resume, + .suspend = orinoco_pci_suspend, + .resume = orinoco_pci_resume, }; static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION @@ -467,7 +387,6 @@ static int __init orinoco_plx_init(void) static void __exit orinoco_plx_exit(void) { pci_unregister_driver(&orinoco_plx_driver); - ssleep(1); } module_init(orinoco_plx_init); diff --git a/drivers/net/wireless/orinoco_tmd.c b/drivers/net/wireless/orinoco_tmd.c index b74807d..438fe54 100644 --- a/drivers/net/wireless/orinoco_tmd.c +++ b/drivers/net/wireless/orinoco_tmd.c @@ -1,5 +1,5 @@ /* orinoco_tmd.c - * + * * Driver for Prism II devices which would usually be driven by orinoco_cs, * but are connected to the PCI bus by a TMD7160. * @@ -29,14 +29,14 @@ * Caution: this is experimental and probably buggy. For success and * failure reports for different cards and adaptors, see - * orinoco_tmd_pci_id_table near the end of the file. If you have a + * orinoco_tmd_id_table near the end of the file. If you have a * card we don't have the PCI id for, and looks like it should work, * drop me mail with the id and "it works"/"it doesn't work". * * Note: if everything gets detected fine but it doesn't actually send - * or receive packets, your first port of call should probably be to + * or receive packets, your first port of call should probably be to * try newer firmware in the card. Especially if you're doing Ad-Hoc - * modes + * modes. * * The actual driving is done by orinoco.c, this is just resource * allocation stuff. @@ -61,32 +61,26 @@ #include <pcmcia/cisreg.h> #include "orinoco.h" +#include "orinoco_pci.h" #define COR_VALUE (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */ #define COR_RESET (0x80) /* reset bit in the COR register */ #define TMD_RESET_TIME (500) /* milliseconds */ -/* Orinoco TMD specific data */ -struct orinoco_tmd_card { - u32 tmd_io; -}; - - /* * Do a soft reset of the card using the Configuration Option Register */ static int orinoco_tmd_cor_reset(struct orinoco_private *priv) { hermes_t *hw = &priv->hw; - struct orinoco_tmd_card *card = priv->card; - u32 addr = card->tmd_io; + struct orinoco_pci_card *card = priv->card; unsigned long timeout; u16 reg; - outb(COR_VALUE | COR_RESET, addr); + iowrite8(COR_VALUE | COR_RESET, card->bridge_io); mdelay(1); - outb(COR_VALUE, addr); + iowrite8(COR_VALUE, card->bridge_io); mdelay(1); /* Just in case, wait more until the card is no longer busy */ @@ -97,7 +91,7 @@ static int orinoco_tmd_cor_reset(struct orinoco_private *priv) reg = hermes_read_regn(hw, CMD); } - /* Did we timeout ? */ + /* Still busy? */ if (reg & HERMES_CMD_BUSY) { printk(KERN_ERR PFX "Busy timeout\n"); return -ETIMEDOUT; @@ -110,11 +104,11 @@ static int orinoco_tmd_cor_reset(struct orinoco_private *priv) static int orinoco_tmd_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { - int err = 0; - struct orinoco_private *priv = NULL; - struct orinoco_tmd_card *card; - struct net_device *dev = NULL; - void __iomem *mem; + int err; + struct orinoco_private *priv; + struct orinoco_pci_card *card; + struct net_device *dev; + void __iomem *hermes_io, *bridge_io; err = pci_enable_device(pdev); if (err) { @@ -123,20 +117,28 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev, } err = pci_request_regions(pdev, DRIVER_NAME); - if (err != 0) { + if (err) { printk(KERN_ERR PFX "Cannot obtain PCI resources\n"); goto fail_resources; } - mem = pci_iomap(pdev, 2, 0); - if (! mem) { - err = -ENOMEM; - goto fail_iomap; + bridge_io = pci_iomap(pdev, 1, 0); + if (!bridge_io) { + printk(KERN_ERR PFX "Cannot map bridge registers\n"); + err = -EIO; + goto fail_map_bridge; + } + + hermes_io = pci_iomap(pdev, 2, 0); + if (!hermes_io) { + printk(KERN_ERR PFX "Cannot map chipset registers\n"); + err = -EIO; + goto fail_map_hermes; } /* Allocate network device */ dev = alloc_orinocodev(sizeof(*card), orinoco_tmd_cor_reset); - if (! dev) { + if (!dev) { printk(KERN_ERR PFX "Cannot allocate network device\n"); err = -ENOMEM; goto fail_alloc; @@ -144,16 +146,11 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev, priv = netdev_priv(dev); card = priv->card; - card->tmd_io = pci_resource_start(pdev, 1); - dev->base_addr = pci_resource_start(pdev, 2); + card->bridge_io = bridge_io; SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); - hermes_struct_init(&priv->hw, mem, HERMES_16BIT_REGSPACING); - - printk(KERN_DEBUG PFX "Detected Orinoco/Prism2 TMD device " - "at %s irq:%d, io addr:0x%lx\n", pci_name(pdev), pdev->irq, - dev->base_addr); + hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING); err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, dev->name, dev); @@ -162,7 +159,7 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev, err = -EBUSY; goto fail_irq; } - dev->irq = pdev->irq; + orinoco_pci_setup_netdev(dev, pdev, 2); err = orinoco_tmd_cor_reset(priv); if (err) { @@ -188,9 +185,12 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev, free_orinocodev(dev); fail_alloc: - pci_iounmap(pdev, mem); + pci_iounmap(pdev, hermes_io); - fail_iomap: + fail_map_hermes: + pci_iounmap(pdev, bridge_io); + + fail_map_bridge: pci_release_regions(pdev); fail_resources: @@ -203,110 +203,32 @@ static void __devexit orinoco_tmd_remove_one(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct orinoco_private *priv = dev->priv; - - BUG_ON(! dev); + struct orinoco_pci_card *card = priv->card; unregister_netdev(dev); free_irq(dev->irq, dev); pci_set_drvdata(pdev, NULL); free_orinocodev(dev); pci_iounmap(pdev, priv->hw.iobase); + pci_iounmap(pdev, card->bridge_io); pci_release_regions(pdev); pci_disable_device(pdev); } -static int orinoco_tmd_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct net_device *dev = pci_get_drvdata(pdev); - struct orinoco_private *priv = netdev_priv(dev); - unsigned long flags; - int err; - - err = orinoco_lock(priv, &flags); - if (err) { - printk(KERN_ERR "%s: cannot lock hardware for suspend\n", - dev->name); - return err; - } - - err = __orinoco_down(dev); - if (err) - printk(KERN_WARNING "%s: error %d bringing interface down " - "for suspend\n", dev->name, err); - - netif_device_detach(dev); - - priv->hw_unavailable++; - - orinoco_unlock(priv, &flags); - - free_irq(pdev->irq, dev); - pci_save_state(pdev); - pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); - - return 0; -} - -static int orinoco_tmd_resume(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - struct orinoco_private *priv = netdev_priv(dev); - unsigned long flags; - int err; - - pci_set_power_state(pdev, 0); - pci_enable_device(pdev); - pci_restore_state(pdev); - - err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, - dev->name, dev); - if (err) { - printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n", - dev->name); - pci_disable_device(pdev); - return -EBUSY; - } - - err = orinoco_reinit_firmware(dev); - if (err) { - printk(KERN_ERR "%s: error %d re-initializing firmware " - "on resume\n", dev->name, err); - return err; - } - - spin_lock_irqsave(&priv->lock, flags); - - netif_device_attach(dev); - - priv->hw_unavailable--; - - if (priv->open && (! priv->hw_unavailable)) { - err = __orinoco_up(dev); - if (err) - printk(KERN_ERR "%s: Error %d restarting card on resume\n", - dev->name, err); - } - - spin_unlock_irqrestore(&priv->lock, flags); - - return 0; -} - -static struct pci_device_id orinoco_tmd_pci_id_table[] = { +static struct pci_device_id orinoco_tmd_id_table[] = { {0x15e8, 0x0131, PCI_ANY_ID, PCI_ANY_ID,}, /* NDC and OEMs, e.g. pheecom */ {0,}, }; -MODULE_DEVICE_TABLE(pci, orinoco_tmd_pci_id_table); +MODULE_DEVICE_TABLE(pci, orinoco_tmd_id_table); static struct pci_driver orinoco_tmd_driver = { .name = DRIVER_NAME, - .id_table = orinoco_tmd_pci_id_table, + .id_table = orinoco_tmd_id_table, .probe = orinoco_tmd_init_one, .remove = __devexit_p(orinoco_tmd_remove_one), - .suspend = orinoco_tmd_suspend, - .resume = orinoco_tmd_resume, + .suspend = orinoco_pci_suspend, + .resume = orinoco_pci_resume, }; static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION @@ -324,7 +246,6 @@ static int __init orinoco_tmd_init(void) static void __exit orinoco_tmd_exit(void) { pci_unregister_driver(&orinoco_tmd_driver); - ssleep(1); } module_init(orinoco_tmd_init); |