brcmfmac: avoid usage of func->card->dev in sdio probe.
authorHante Meuleman <meuleman@broadcom.com>
Thu, 15 Nov 2012 02:46:20 +0000 (18:46 -0800)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 16 Nov 2012 19:29:02 +0000 (14:29 -0500)
brcmf_ops_sdio_probe used the private_date func->card->dev to
store device data of brcmfmac sdio. This is not a good place to
store the data. Use dev of func and use func->card->sdio_func
to group the functions the driver is using.

Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Franky Lin <frankyl@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c

index b924ed7d3e012d68998262264cbb288fb8392354..4c3315ce9683e75faffd8b795b323792d39cfb8d 100644 (file)
@@ -42,7 +42,8 @@
 #ifdef CONFIG_BRCMFMAC_SDIO_OOB
 static irqreturn_t brcmf_sdio_irqhandler(int irq, void *dev_id)
 {
-       struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(dev_id);
+       struct brcmf_bus *bus_if = dev_get_drvdata(dev_id);
+       struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
 
        brcmf_dbg(INTR, "oob intr triggered\n");
 
@@ -71,7 +72,7 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
        brcmf_dbg(ERROR, "requesting irq %d\n", sdiodev->irq);
        ret = request_irq(sdiodev->irq, brcmf_sdio_irqhandler,
                          sdiodev->irq_flags, "brcmf_oob_intr",
-                         &sdiodev->func[1]->card->dev);
+                         &sdiodev->func[1]->dev);
        if (ret != 0)
                return ret;
        spin_lock_init(&sdiodev->irq_en_lock);
@@ -115,7 +116,7 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
                disable_irq_wake(sdiodev->irq);
                sdiodev->irq_wake = false;
        }
-       free_irq(sdiodev->irq, &sdiodev->func[1]->card->dev);
+       free_irq(sdiodev->irq, &sdiodev->func[1]->dev);
        sdiodev->irq_en = false;
 
        return 0;
@@ -123,7 +124,8 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
 #else          /* CONFIG_BRCMFMAC_SDIO_OOB */
 static void brcmf_sdio_irqhandler(struct sdio_func *func)
 {
-       struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev);
+       struct brcmf_bus *bus_if = dev_get_drvdata(&func->dev);
+       struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
 
        brcmf_dbg(INTR, "ib intr triggered\n");
 
index 854573386f236fbf665bc7c27a8a35a847db85a9..6dd75ccd23993c3b9ea89cd61c99e7d7609e3cb5 100644 (file)
@@ -456,101 +456,107 @@ static inline int brcmf_sdio_getintrcfg(struct brcmf_sdio_dev *sdiodev)
 #endif         /* CONFIG_BRCMFMAC_SDIO_OOB */
 
 static int brcmf_ops_sdio_probe(struct sdio_func *func,
-                             const struct sdio_device_id *id)
+                               const struct sdio_device_id *id)
 {
-       int ret = 0;
+       int err;
        struct brcmf_sdio_dev *sdiodev;
        struct brcmf_bus *bus_if;
 
        brcmf_dbg(TRACE, "Enter\n");
-       brcmf_dbg(TRACE, "func->class=%x\n", func->class);
-       brcmf_dbg(TRACE, "sdio_vendor: 0x%04x\n", func->vendor);
-       brcmf_dbg(TRACE, "sdio_device: 0x%04x\n", func->device);
-       brcmf_dbg(TRACE, "Function#: 0x%04x\n", func->num);
-
-       if (func->num == 1) {
-               if (dev_get_drvdata(&func->card->dev)) {
-                       brcmf_dbg(ERROR, "card private drvdata occupied\n");
-                       return -ENXIO;
-               }
-               bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL);
-               if (!bus_if)
-                       return -ENOMEM;
-               sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL);
-               if (!sdiodev) {
-                       kfree(bus_if);
-                       return -ENOMEM;
-               }
-               sdiodev->func[0] = func;
-               sdiodev->func[1] = func;
-               sdiodev->bus_if = bus_if;
-               bus_if->bus_priv.sdio = sdiodev;
-               bus_if->type = SDIO_BUS;
-               bus_if->align = BRCMF_SDALIGN;
-               dev_set_drvdata(&func->card->dev, sdiodev);
-
-               atomic_set(&sdiodev->suspend, false);
-               init_waitqueue_head(&sdiodev->request_byte_wait);
-               init_waitqueue_head(&sdiodev->request_word_wait);
-               init_waitqueue_head(&sdiodev->request_chain_wait);
-               init_waitqueue_head(&sdiodev->request_buffer_wait);
+       brcmf_dbg(TRACE, "Class=%x\n", func->class);
+       brcmf_dbg(TRACE, "sdio vendor ID: 0x%04x\n", func->vendor);
+       brcmf_dbg(TRACE, "sdio device ID: 0x%04x\n", func->device);
+       brcmf_dbg(TRACE, "Function#: %d\n", func->num);
+
+       /* Consume func num 1 but dont do anything with it. */
+       if (func->num == 1)
+               return 0;
+
+       /* Ignore anything but func 2 */
+       if (func->num != 2)
+               return -ENODEV;
+
+       bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL);
+       if (!bus_if)
+               return -ENOMEM;
+       sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL);
+       if (!sdiodev) {
+               kfree(bus_if);
+               return -ENOMEM;
        }
 
-       if (func->num == 2) {
-               sdiodev = dev_get_drvdata(&func->card->dev);
-               if ((!sdiodev) || (sdiodev->func[1]->card != func->card))
-                       return -ENODEV;
-
-               ret = brcmf_sdio_getintrcfg(sdiodev);
-               if (ret)
-                       return ret;
-               sdiodev->func[2] = func;
+       sdiodev->func[0] = func->card->sdio_func[0];
+       sdiodev->func[1] = func->card->sdio_func[0];
+       sdiodev->func[2] = func;
 
-               bus_if = sdiodev->bus_if;
-               sdiodev->dev = &func->dev;
-               dev_set_drvdata(&func->dev, bus_if);
+       sdiodev->bus_if = bus_if;
+       bus_if->bus_priv.sdio = sdiodev;
+       bus_if->type = SDIO_BUS;
+       bus_if->align = BRCMF_SDALIGN;
+       dev_set_drvdata(&func->dev, bus_if);
+       dev_set_drvdata(&sdiodev->func[1]->dev, bus_if);
+       sdiodev->dev = &sdiodev->func[1]->dev;
 
-               brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n");
-               ret = brcmf_sdio_probe(sdiodev);
-               if (ret)
-                       dev_set_drvdata(&func->dev, NULL);
+       atomic_set(&sdiodev->suspend, false);
+       init_waitqueue_head(&sdiodev->request_byte_wait);
+       init_waitqueue_head(&sdiodev->request_word_wait);
+       init_waitqueue_head(&sdiodev->request_chain_wait);
+       init_waitqueue_head(&sdiodev->request_buffer_wait);
+       err = brcmf_sdio_getintrcfg(sdiodev);
+       if (err)
+               goto fail;
+
+       brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n");
+       err = brcmf_sdio_probe(sdiodev);
+       if (err) {
+               brcmf_dbg(ERROR, "F2 error, probe failed %d...\n", err);
+               goto fail;
        }
+       brcmf_dbg(TRACE, "F2 init completed...\n");
+       return 0;
 
-       return ret;
+fail:
+       dev_set_drvdata(&func->dev, NULL);
+       dev_set_drvdata(&sdiodev->func[1]->dev, NULL);
+       kfree(sdiodev);
+       kfree(bus_if);
+       return err;
 }
 
 static void brcmf_ops_sdio_remove(struct sdio_func *func)
 {
        struct brcmf_bus *bus_if;
        struct brcmf_sdio_dev *sdiodev;
+
        brcmf_dbg(TRACE, "Enter\n");
-       brcmf_dbg(INFO, "func->class=%x\n", func->class);
-       brcmf_dbg(INFO, "sdio_vendor: 0x%04x\n", func->vendor);
-       brcmf_dbg(INFO, "sdio_device: 0x%04x\n", func->device);
-       brcmf_dbg(INFO, "Function#: 0x%04x\n", func->num);
+       brcmf_dbg(TRACE, "sdio vendor ID: 0x%04x\n", func->vendor);
+       brcmf_dbg(TRACE, "sdio device ID: 0x%04x\n", func->device);
+       brcmf_dbg(TRACE, "Function: %d\n", func->num);
 
-       if (func->num == 2) {
-               bus_if = dev_get_drvdata(&func->dev);
+       if (func->num != 1 && func->num != 2)
+               return;
+
+       bus_if = dev_get_drvdata(&func->dev);
+       if (bus_if) {
                sdiodev = bus_if->bus_priv.sdio;
-               brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_remove...\n");
                brcmf_sdio_remove(sdiodev);
-               dev_set_drvdata(&func->dev, NULL);
-       }
-       if (func->num == 1) {
-               sdiodev = dev_get_drvdata(&func->card->dev);
-               bus_if = sdiodev->bus_if;
-               dev_set_drvdata(&func->card->dev, NULL);
+
+               dev_set_drvdata(&sdiodev->func[1]->dev, NULL);
+               dev_set_drvdata(&sdiodev->func[2]->dev, NULL);
+
                kfree(bus_if);
                kfree(sdiodev);
        }
+
+       brcmf_dbg(TRACE, "Exit\n");
 }
 
 #ifdef CONFIG_PM_SLEEP
 static int brcmf_sdio_suspend(struct device *dev)
 {
        mmc_pm_flag_t sdio_flags;
-       struct sdio_func *func = dev_to_sdio_func(dev);
-       struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev);
+       struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+       struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
        int ret = 0;
 
        brcmf_dbg(TRACE, "\n");
@@ -576,8 +582,8 @@ static int brcmf_sdio_suspend(struct device *dev)
 
 static int brcmf_sdio_resume(struct device *dev)
 {
-       struct sdio_func *func = dev_to_sdio_func(dev);
-       struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev);
+       struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+       struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
 
        brcmf_sdio_wdtmr_enable(sdiodev, true);
        atomic_set(&sdiodev->suspend, false);