]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/commitdiff
wimax/i2400m: Ensure boot mode cmd and ack buffers are alloc'd before first message
authorDirk Brandewie <dirk.j.brandewie@intel.com>
Tue, 18 Aug 2009 15:51:52 +0000 (08:51 -0700)
committerInaky Perez-Gonzalez <inaky@linux.intel.com>
Mon, 19 Oct 2009 06:55:39 +0000 (15:55 +0900)
The change to the SDIO boot mode RX chain could try to use the cmd and
ack buffers befor they were allocated.  USB does not have the problem
but both were changed for consistency's sake.

Signed-off-by: Dirk Brandewie <dirk.j.brandewie@intel.com>
Signed-off-by: Inaky Perez-Gonzalez <inaky@linux.intel.com>
drivers/net/wimax/i2400m/driver.c
drivers/net/wimax/i2400m/i2400m.h
drivers/net/wimax/i2400m/sdio.c
drivers/net/wimax/i2400m/usb.c

index 304f0443ca4bc7e739b7ad567557686c77987d8d..20d574ca918388b957d72f9dd8d9c25a94f31055 100644 (file)
@@ -618,6 +618,46 @@ int i2400m_dev_reset_handle(struct i2400m *i2400m)
 EXPORT_SYMBOL_GPL(i2400m_dev_reset_handle);
 
 
+/**
+ * i2400m_bm_buf_alloc - Alloc the command and ack buffers for boot mode
+ *
+ * Get the buffers needed to deal with boot mode messages.  These
+ * buffers need to be allocated before the sdio recieve irq is setup.
+ */
+int i2400m_bm_buf_alloc(struct i2400m *i2400m)
+{
+       int result;
+
+       result = -ENOMEM;
+       i2400m->bm_cmd_buf = kzalloc(I2400M_BM_CMD_BUF_SIZE, GFP_KERNEL);
+       if (i2400m->bm_cmd_buf == NULL)
+               goto error_bm_cmd_kzalloc;
+       i2400m->bm_ack_buf = kzalloc(I2400M_BM_ACK_BUF_SIZE, GFP_KERNEL);
+       if (i2400m->bm_ack_buf == NULL)
+               goto error_bm_ack_buf_kzalloc;
+       return 0;
+
+error_bm_ack_buf_kzalloc:
+       kfree(i2400m->bm_cmd_buf);
+error_bm_cmd_kzalloc:
+       return result;
+}
+EXPORT_SYMBOL_GPL(i2400m_bm_buf_alloc);
+
+/**
+ * i2400m_bm_buf_free - Free boot mode command and ack buffers.
+ *
+ * Free the command and ack buffers
+ *
+ */
+void i2400m_bm_buf_free(struct i2400m *i2400m)
+{
+       kfree(i2400m->bm_ack_buf);
+       kfree(i2400m->bm_cmd_buf);
+       return;
+}
+EXPORT_SYMBOL_GPL(i2400m_bm_buf_free
+);
 /**
  * i2400m_setup - bus-generic setup function for the i2400m device
  *
@@ -645,16 +685,6 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags)
        snprintf(wimax_dev->name, sizeof(wimax_dev->name),
                 "i2400m-%s:%s", dev->bus->name, dev_name(dev));
 
-       i2400m->bm_cmd_buf = kzalloc(I2400M_BM_CMD_BUF_SIZE, GFP_KERNEL);
-       if (i2400m->bm_cmd_buf == NULL) {
-               dev_err(dev, "cannot allocate USB command buffer\n");
-               goto error_bm_cmd_kzalloc;
-       }
-       i2400m->bm_ack_buf = kzalloc(I2400M_BM_ACK_BUF_SIZE, GFP_KERNEL);
-       if (i2400m->bm_ack_buf == NULL) {
-               dev_err(dev, "cannot allocate USB ack buffer\n");
-               goto error_bm_ack_buf_kzalloc;
-       }
        result = i2400m_bootrom_init(i2400m, bm_flags);
        if (result < 0) {
                dev_err(dev, "read mac addr: bootrom init "
@@ -713,10 +743,6 @@ error_dev_start:
 error_register_netdev:
 error_read_mac_addr:
 error_bootrom_init:
-       kfree(i2400m->bm_ack_buf);
-error_bm_ack_buf_kzalloc:
-       kfree(i2400m->bm_cmd_buf);
-error_bm_cmd_kzalloc:
        d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result);
        return result;
 }
index 60330f313f2781ea65630a484564ef7750011487..a6e59f1c881dcc1dd90f2da32d5d236986229d23 100644 (file)
@@ -725,6 +725,8 @@ void i2400m_put(struct i2400m *i2400m)
 }
 
 extern int i2400m_dev_reset_handle(struct i2400m *);
+extern int i2400m_bm_buf_alloc(struct i2400m *i2400m);
+extern void i2400m_bm_buf_free(struct i2400m *i2400m);
 
 /*
  * _setup()/_release() are called by the probe/disconnect functions of
index c67b0264a2825fe97f1c08df32533b06343583b9..a68232aa29151ae174fa6170a739d8ae944cb068 100644 (file)
@@ -451,6 +451,18 @@ int i2400ms_probe(struct sdio_func *func,
                goto error_func_enable;
        }
 
+       /*
+        * Before we are enabling the device interrupt register, make
+        * sure the buffer used during bootmode operation is setup so
+        * when the first D2H data interrupt comes, the memory is
+        * available for copying the D2H data.
+        */
+       result = i2400m_bm_buf_alloc(i2400m);
+       if (result < 0) {
+               dev_err(dev, "cannot allocate SDIO bootmode buffer\n");
+               goto error_bootmode_buf_setup;
+       }
+
        result = i2400ms_rx_setup(i2400ms);
        if (result < 0)
                goto error_rx_setup;
@@ -474,6 +486,8 @@ error_debugfs_add:
 error_setup:
        i2400ms_rx_release(i2400ms);
 error_rx_setup:
+       i2400m_bm_buf_free(i2400m);
+error_bootmode_buf_setup:
        sdio_claim_host(func);
        sdio_disable_func(func);
        sdio_release_host(func);
index bfa45f5713415cdcb73deb9c028fcb375c3f8610..49d7554ad7071fd14219864989376e86cccab598 100644 (file)
@@ -419,6 +419,12 @@ int i2400mu_probe(struct usb_interface *iface,
        usb_dev->autosuspend_disabled = 0;
 #endif
 
+       result = i2400m_bm_buf_alloc(i2400m);
+       if (result < 0) {
+               dev_err(dev, "cannot allocate USB bootmode buffer\n");
+               goto error_bm_buf_alloc;
+       }
+
        result = i2400m_setup(i2400m, I2400M_BRI_MAC_REINIT);
        if (result < 0) {
                dev_err(dev, "cannot setup device: %d\n", result);
@@ -434,6 +440,8 @@ int i2400mu_probe(struct usb_interface *iface,
 error_debugfs_add:
        i2400m_release(i2400m);
 error_setup:
+       i2400m_bm_buf_free(i2400m);
+error_bm_buf_alloc:
        usb_set_intfdata(iface, NULL);
        usb_put_dev(i2400mu->usb_dev);
        free_netdev(net_dev);