orinoco: Do not call wiphy_unregister() from free_orinocodev()
authorJes Sorensen <Jes.Sorensen@redhat.com>
Thu, 6 Aug 2015 16:46:31 +0000 (12:46 -0400)
committerKalle Valo <kvalo@codeaurora.org>
Thu, 13 Aug 2015 12:36:47 +0000 (15:36 +0300)
alloc_orinocodev() would allocate the wiphy entry, but it would only get
registered much later in orinoco_init(). If something failed in the init
process inbetween the call to alloc_orinocodev() and the completion
of orinoco_init(), the drivers would end up calling wiphy_unregister()
with a NULL pointer causing beautiful OOPS fireworks.

Explicitly call wiphy_unregister() instead in the right places.

Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/orinoco/main.c
drivers/net/wireless/orinoco/orinoco_cs.c
drivers/net/wireless/orinoco/orinoco_nortel.c
drivers/net/wireless/orinoco/orinoco_pci.c
drivers/net/wireless/orinoco/orinoco_plx.c
drivers/net/wireless/orinoco/orinoco_usb.c

index c410180479e694880f6a3c73561fd9ce4b670658..7b5c554323c73ab40caddb47ca965560d787d127 100644 (file)
@@ -2321,8 +2321,6 @@ void free_orinocodev(struct orinoco_private *priv)
        struct orinoco_rx_data *rx_data, *temp;
        struct orinoco_scan_data *sd, *sdtemp;
 
-       wiphy_unregister(wiphy);
-
        /* If the tasklet is scheduled when we call tasklet_kill it
         * will run one final time. However the tasklet will only
         * drain priv->rx_list if the hw is still available. */
index c0a27377d9e26306ea7dc32b44efc6749723bcda..a956f965a1e5ec77e19c03e86ec87dc810461315 100644 (file)
@@ -118,6 +118,7 @@ static void orinoco_cs_detach(struct pcmcia_device *link)
 
        orinoco_cs_release(link);
 
+       wiphy_unregister(priv_to_wiphy(priv));
        free_orinocodev(priv);
 }                              /* orinoco_cs_detach */
 
index 1b543e30eff7b5fe4dafaa9cd904ecec1a4ef5db..048693b6c6c24f06e701a2fa5856484c228065a6 100644 (file)
@@ -223,13 +223,15 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev,
        err = orinoco_if_add(priv, 0, 0, NULL);
        if (err) {
                printk(KERN_ERR PFX "orinoco_if_add() failed\n");
-               goto fail;
+               goto fail_wiphy;
        }
 
        pci_set_drvdata(pdev, priv);
 
        return 0;
 
+ fail_wiphy:
+       wiphy_unregister(priv_to_wiphy(priv));
  fail:
        free_irq(pdev->irq, priv);
 
@@ -263,6 +265,7 @@ static void orinoco_nortel_remove_one(struct pci_dev *pdev)
        iowrite16(0, card->bridge_io + 10);
 
        orinoco_if_del(priv);
+       wiphy_unregister(priv_to_wiphy(priv));
        free_irq(pdev->irq, priv);
        free_orinocodev(priv);
        pci_iounmap(pdev, priv->hw.iobase);
index 74219d59d7e1e5d7d918b42acac99b913157a499..4938a2208a37ce72371f245c78cf9de7d3c90345 100644 (file)
@@ -173,13 +173,15 @@ static int orinoco_pci_init_one(struct pci_dev *pdev,
        err = orinoco_if_add(priv, 0, 0, NULL);
        if (err) {
                printk(KERN_ERR PFX "orinoco_if_add() failed\n");
-               goto fail;
+               goto fail_wiphy;
        }
 
        pci_set_drvdata(pdev, priv);
 
        return 0;
 
+ fail_wiphy:
+       wiphy_unregister(priv_to_wiphy(priv));
  fail:
        free_irq(pdev->irq, priv);
 
@@ -203,6 +205,7 @@ static void orinoco_pci_remove_one(struct pci_dev *pdev)
        struct orinoco_private *priv = pci_get_drvdata(pdev);
 
        orinoco_if_del(priv);
+       wiphy_unregister(priv_to_wiphy(priv));
        free_irq(pdev->irq, priv);
        free_orinocodev(priv);
        pci_iounmap(pdev, priv->hw.iobase);
index 8b045236b6e0111b8661b0df0b8e5d428710f11d..221352027779f75c5ceb0e605b15297e53b70c2f 100644 (file)
@@ -262,13 +262,15 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
        err = orinoco_if_add(priv, 0, 0, NULL);
        if (err) {
                printk(KERN_ERR PFX "orinoco_if_add() failed\n");
-               goto fail;
+               goto fail_wiphy;
        }
 
        pci_set_drvdata(pdev, priv);
 
        return 0;
 
+ fail_wiphy:
+       wiphy_unregister(priv_to_wiphy(priv));
  fail:
        free_irq(pdev->irq, priv);
 
@@ -299,6 +301,7 @@ static void orinoco_plx_remove_one(struct pci_dev *pdev)
        struct orinoco_pci_card *card = priv->card;
 
        orinoco_if_del(priv);
+       wiphy_unregister(priv_to_wiphy(priv));
        free_irq(pdev->irq, priv);
        free_orinocodev(priv);
        pci_iounmap(pdev, priv->hw.iobase);
index 91f05442de28809a662290b66c26ac42be488144..26a57d773d3031147e5985cc004b3d80937d4081 100644 (file)
@@ -1502,6 +1502,7 @@ static inline void ezusb_delete(struct ezusb_priv *upriv)
        if (upriv->dev) {
                struct orinoco_private *priv = ndev_priv(upriv->dev);
                orinoco_if_del(priv);
+               wiphy_unregister(priv_to_wiphy(upriv));
                free_orinocodev(priv);
        }
 }
@@ -1695,6 +1696,7 @@ static int ezusb_probe(struct usb_interface *interface,
        if (orinoco_if_add(priv, 0, 0, &ezusb_netdev_ops) != 0) {
                upriv->dev = NULL;
                err("%s: orinoco_if_add() failed", __func__);
+               wiphy_unregister(priv_to_wiphy(priv));
                goto error;
        }
        upriv->dev = priv->ndev;