wlcore: Always pass DMA-able buffers to mmc functions
authorIdo Yariv <ido@wizery.com>
Wed, 28 Nov 2012 09:42:49 +0000 (11:42 +0200)
committerLuciano Coelho <coelho@ti.com>
Tue, 11 Dec 2012 10:37:24 +0000 (12:37 +0200)
Some of the mmc drivers initiate DMA transfers with buffers passed from
higher layers. This means that the driver shouldn't ever pass non
DMA-able buffers, such as ones that are unaligned, allocated on the
stack or static.

Fix a couple of calls to the mmc layer in which buffers which weren't
necessarily DMA-able were passed.

[Use sizeof(*wl->buffer_32) instead of sizeof(u32) -- Luca]

Signed-off-by: Ido Yariv <ido@wizery.com>
Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
drivers/net/wireless/ti/wl12xx/main.c
drivers/net/wireless/ti/wl12xx/wl12xx.h
drivers/net/wireless/ti/wlcore/io.h
drivers/net/wireless/ti/wlcore/main.c
drivers/net/wireless/ti/wlcore/wlcore.h

index 6d4a02171abc039e5c7a41bf7a31c83e082615fc..5b023a5bcc099ed5dde752a1a4931179d6abfe8e 100644 (file)
@@ -613,7 +613,7 @@ static int wl127x_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len)
 
        if (wl->chip.id != CHIP_ID_128X_PG20) {
                struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map;
-               struct wl127x_rx_mem_pool_addr rx_mem_addr;
+               struct wl12xx_priv *priv = wl->priv;
 
                /*
                 * Choose the block we want to read
@@ -622,13 +622,13 @@ static int wl127x_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len)
                 */
                u32 mem_block = rx_desc & RX_MEM_BLOCK_MASK;
 
-               rx_mem_addr.addr = (mem_block << 8) +
+               priv->rx_mem_addr->addr = (mem_block << 8) +
                        le32_to_cpu(wl_mem_map->packet_memory_pool_start);
 
-               rx_mem_addr.addr_extra = rx_mem_addr.addr + 4;
+               priv->rx_mem_addr->addr_extra = priv->rx_mem_addr->addr + 4;
 
-               ret = wlcore_write(wl, WL1271_SLV_REG_DATA, &rx_mem_addr,
-                                  sizeof(rx_mem_addr), false);
+               ret = wlcore_write(wl, WL1271_SLV_REG_DATA, priv->rx_mem_addr,
+                                  sizeof(*priv->rx_mem_addr), false);
                if (ret < 0)
                        return ret;
        }
@@ -1761,6 +1761,10 @@ static int wl12xx_setup(struct wl1271 *wl)
                        wl1271_error("Invalid tcxo parameter %s", tcxo_param);
        }
 
+       priv->rx_mem_addr = kmalloc(sizeof(*priv->rx_mem_addr), GFP_KERNEL);
+       if (!priv->rx_mem_addr)
+               return -ENOMEM;
+
        return 0;
 }
 
@@ -1794,6 +1798,21 @@ out:
        return ret;
 }
 
+static int __devexit wl12xx_remove(struct platform_device *pdev)
+{
+       struct wl1271 *wl = platform_get_drvdata(pdev);
+       struct wl12xx_priv *priv;
+
+       if (!wl)
+               goto out;
+       priv = wl->priv;
+
+       kfree(priv->rx_mem_addr);
+
+out:
+       return wlcore_remove(pdev);
+}
+
 static const struct platform_device_id wl12xx_id_table[] __devinitconst = {
        { "wl12xx", 0 },
        {  } /* Terminating Entry */
@@ -1802,7 +1821,7 @@ MODULE_DEVICE_TABLE(platform, wl12xx_id_table);
 
 static struct platform_driver wl12xx_driver = {
        .probe          = wl12xx_probe,
-       .remove         = __devexit_p(wlcore_remove),
+       .remove         = __devexit_p(wl12xx_remove),
        .id_table       = wl12xx_id_table,
        .driver = {
                .name   = "wl12xx_driver",
index a07be5e022fbe88827d77a8ce2a505ae15bbe9b5..d4552857480ca92d6c72461067ec54c813c421d8 100644 (file)
@@ -73,6 +73,8 @@ struct wl12xx_priv {
 
        int ref_clock;
        int tcxo_clock;
+
+       struct wl127x_rx_mem_pool_addr *rx_mem_addr;
 };
 
 #endif /* __WL12XX_PRIV_H__ */
index f48530fec14fb3ba9563e1763c2c38fa46b9488d..af7d9f9b3b4db2140006fb0639af3ff028af79e5 100644 (file)
@@ -105,13 +105,13 @@ static inline int __must_check wlcore_raw_read32(struct wl1271 *wl, int addr,
 {
        int ret;
 
-       ret = wlcore_raw_read(wl, addr, &wl->buffer_32,
-                             sizeof(wl->buffer_32), false);
+       ret = wlcore_raw_read(wl, addr, wl->buffer_32,
+                             sizeof(*wl->buffer_32), false);
        if (ret < 0)
                return ret;
 
        if (val)
-               *val = le32_to_cpu(wl->buffer_32);
+               *val = le32_to_cpu(*wl->buffer_32);
 
        return 0;
 }
@@ -119,9 +119,9 @@ static inline int __must_check wlcore_raw_read32(struct wl1271 *wl, int addr,
 static inline int __must_check wlcore_raw_write32(struct wl1271 *wl, int addr,
                                                  u32 val)
 {
-       wl->buffer_32 = cpu_to_le32(val);
-       return wlcore_raw_write(wl, addr, &wl->buffer_32,
-                               sizeof(wl->buffer_32), false);
+       *wl->buffer_32 = cpu_to_le32(val);
+       return wlcore_raw_write(wl, addr, wl->buffer_32,
+                               sizeof(*wl->buffer_32), false);
 }
 
 static inline int __must_check wlcore_read(struct wl1271 *wl, int addr,
index 227c571a26904e33183dda0e9b39de014dc247d5..0e599c92a071e9c359218387c878a02b461c1103 100644 (file)
@@ -5860,8 +5860,17 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size,
                goto err_fwlog;
        }
 
+       wl->buffer_32 = kmalloc(sizeof(*wl->buffer_32), GFP_KERNEL);
+       if (!wl->buffer_32) {
+               ret = -ENOMEM;
+               goto err_mbox;
+       }
+
        return hw;
 
+err_mbox:
+       kfree(wl->mbox);
+
 err_fwlog:
        free_page((unsigned long)wl->fwlog);
 
@@ -5900,6 +5909,7 @@ int wlcore_free_hw(struct wl1271 *wl)
        device_remove_file(wl->dev, &dev_attr_hw_pg_ver);
 
        device_remove_file(wl->dev, &dev_attr_bt_coex_state);
+       kfree(wl->buffer_32);
        kfree(wl->mbox);
        free_page((unsigned long)wl->fwlog);
        dev_kfree_skb(wl->dummy_packet);
index 6c2fd0398e9dca662beba39dd70f1126c6415516..118208a8e9970891f70d8603b20c8663faa7ef61 100644 (file)
@@ -334,7 +334,7 @@ struct wl1271 {
 
        struct wl1271_stats stats;
 
-       __le32 buffer_32;
+       __le32 *buffer_32;
        u32 buffer_cmd;
        u32 buffer_busyword[WL1271_BUSY_WORD_CNT];