aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/cmd.c
diff options
context:
space:
mode:
authorHolger Schurig <hs4233@mail.mn-solutions.de>2008-04-01 08:50:43 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-04-16 15:59:56 -0400
commit7919b89c8276d657976d4d4d6b7cb58ea1aa08c3 (patch)
tree31fc24e2f8b7d8eeee67347333e078591796d4b7 /drivers/net/wireless/libertas/cmd.c
parent98dd6a575928ed9c42130d208e6bfb0f7a914d5a (diff)
libertas: convert libertas driver to use an event/cmdresp queue
This patch (co-developed by Dan Williams and Holger Schurig) uses a kfifo object for events and a swapping buffer scheme for the command response to preserve the zero-copy semantics of the CF driver and keep memory usage low. The main thread should only ever touch the buffer indexed by priv->resp_idx, while the interface code is free to write to the second buffer, then swap priv->resp_idx under the driver spinlock. The firmware specs only permit one in-flight command, so there will only ever be one command response to process at a time. Signed-off-by: Holger Schurig <hs4233@mail.mn-solutions.de> Signed-off-by: Dan Williams <dcbw@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas/cmd.c')
-rw-r--r--drivers/net/wireless/libertas/cmd.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 4a82f5114ca0..49267ed7cea3 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -4,6 +4,7 @@
4 */ 4 */
5 5
6#include <net/iw_handler.h> 6#include <net/iw_handler.h>
7#include <linux/kfifo.h>
7#include "host.h" 8#include "host.h"
8#include "hostcmd.h" 9#include "hostcmd.h"
9#include "decl.h" 10#include "decl.h"
@@ -1829,15 +1830,20 @@ static void lbs_send_confirmsleep(struct lbs_private *priv)
1829 1830
1830 ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) &confirm_sleep, 1831 ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) &confirm_sleep,
1831 sizeof(confirm_sleep)); 1832 sizeof(confirm_sleep));
1832
1833 if (ret) { 1833 if (ret) {
1834 lbs_pr_alert("confirm_sleep failed\n"); 1834 lbs_pr_alert("confirm_sleep failed\n");
1835 } else { 1835 goto out;
1836 spin_lock_irqsave(&priv->driver_lock, flags);
1837 if (!priv->intcounter)
1838 priv->psstate = PS_STATE_SLEEP;
1839 spin_unlock_irqrestore(&priv->driver_lock, flags);
1840 } 1836 }
1837
1838 spin_lock_irqsave(&priv->driver_lock, flags);
1839
1840 /* If nothing to do, go back to sleep (?) */
1841 if (!__kfifo_len(priv->event_fifo) && !priv->resp_len[priv->resp_idx])
1842 priv->psstate = PS_STATE_SLEEP;
1843
1844 spin_unlock_irqrestore(&priv->driver_lock, flags);
1845
1846out:
1841 lbs_deb_leave(LBS_DEB_HOST); 1847 lbs_deb_leave(LBS_DEB_HOST);
1842} 1848}
1843 1849
@@ -1899,13 +1905,16 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv)
1899 } 1905 }
1900 1906
1901 spin_lock_irqsave(&priv->driver_lock, flags); 1907 spin_lock_irqsave(&priv->driver_lock, flags);
1908 /* In-progress command? */
1902 if (priv->cur_cmd) { 1909 if (priv->cur_cmd) {
1903 allowed = 0; 1910 allowed = 0;
1904 lbs_deb_host("cur_cmd was set\n"); 1911 lbs_deb_host("cur_cmd was set\n");
1905 } 1912 }
1906 if (priv->intcounter > 0) { 1913
1914 /* Pending events or command responses? */
1915 if (__kfifo_len(priv->event_fifo) || priv->resp_len[priv->resp_idx]) {
1907 allowed = 0; 1916 allowed = 0;
1908 lbs_deb_host("intcounter %d\n", priv->intcounter); 1917 lbs_deb_host("pending events or command responses\n");
1909 } 1918 }
1910 spin_unlock_irqrestore(&priv->driver_lock, flags); 1919 spin_unlock_irqrestore(&priv->driver_lock, flags);
1911 1920