state of CF suspend / resume
Holger Schurig
hs4233 at mail.mn-solutions.de
Tue Apr 29 10:13:24 EDT 2008
Forgot the actual state:
# lbsdebug +host +cmd +main +thread
# pccardctl suspend
libertas_cs enter: if_cs_suspend()
libertas enter: __lbs_cmd()
libertas enter: __lbs_cmd_async()
libertas enter: lbs_get_cmd_ctrl_node()
libertas host: PREP_CMD: command 0x0045
libertas enter: lbs_queue_cmd()
libertas host: QUEUE_CMD: inserted command 0x0045 into cmdpendingq
libertas thread: 2: currenttxskb 00000000, dnld_send 0
libertas thread: 3: currenttxskb 00000000, dnld_sent 0
libertas thread: 4: currenttxskb 00000000, dnld_sent 0
libertas enter: lbs_execute_next_command()
libertas host: EXEC_NEXT_CMD: sending command 0x0045
libertas enter: lbs_submit_command()
libertas cmd: DNLD_CMD: command 0x0045, seq 7, size 8
libertas DNLD_CMD: 45 00 08 00 07 00 00 00
libertas_cs enter: if_cs_host_to_card(type 1, bytes 8)
libertas_cs enter: if_cs_send_cmd()
libertas thread: 1: currenttxskb 00000000, dnld_sent 2
libertas thread: sleeping, connect_status 1, ps_mode 0, ps_state 0
libertas enter (INT): command_timer_fn()
libertas: Command 45 timed out
libertas thread: 2: currenttxskb 00000000, dnld_send 2
libertas thread: 3: currenttxskb 00000000, dnld_sent 2
libertas thread: 4: currenttxskb 00000000, dnld_sent 2
libertas: requeueing command 45 due to timeout (#1)
libertas thread: 1: currenttxskb 00000000, dnld_sent 2
libertas thread: sleeping, connect_status 1, ps_mode 0, ps_state 0
So it seems that the card immediately goes to sleep, without
even responding with the command result ...
[WIP] libertas: support suspend/resume on CF
Doesn't work at all, but still ... (if someone can continue)
Signed-off-by: Holger Schurig <hs4233 at mail.mn-solutions.de>
Index: wireless-testing/drivers/net/wireless/libertas/if_cs.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/libertas/if_cs.c 2008-04-29 15:04:15.000000000 +0200
+++ wireless-testing/drivers/net/wireless/libertas/if_cs.c 2008-04-29 15:04:27.000000000 +0200
@@ -39,6 +39,8 @@
#include "decl.h"
#include "defs.h"
#include "dev.h"
+#include "cmd.h" /* for lbs_suspend, lbs_resume */
+#include "host.h" /* for CMD_ACT_GET etc */
/********************************************************************/
@@ -635,6 +637,28 @@ done:
+static void if_cs_setup_firmware(struct lbs_private *priv)
+{
+ struct cmd_ds_802_11_fw_wake_method wake_method;
+
+ lbs_deb_enter(LBS_DEB_CS)
+
+ /* define wake-on-lan data for CMD_801_11_HOST_SLEEP_CFG */
+ priv->wol_gpio = 2; /* don't use a GPIO for wake up */
+ priv->wol_gap = 20; /* delay this 20 ms */
+ lbs_host_sleep_cfg(priv, EHS_WAKE_ON_MAC_EVENT);
+
+ wake_method.hdr.size = cpu_to_le16(sizeof(wake_method));
+ wake_method.action = cpu_to_le16(CMD_ACT_SET);
+ wake_method.method = cpu_to_le16(CMD_WAKE_METHOD_GPIO);
+ lbs_cmd_with_response(priv, CMD_802_11_FW_WAKE_METHOD, &wake_method);
+
+ /* The firmware for the CF card supports powersave */
+ priv->ps_supported = 1;
+ lbs_deb_leave(LBS_DEB_CS)
+}
+
+
/********************************************************************/
/* Callback functions for libertas.ko */
/********************************************************************/
@@ -845,8 +869,7 @@ static int if_cs_probe(struct pcmcia_dev
goto out3;
}
- /* The firmware for the CF card supports powersave */
- priv->ps_supported = 1;
+ if_cs_setup_firmware(priv);
ret = 0;
goto out;
@@ -887,6 +910,57 @@ static void if_cs_detach(struct pcmcia_d
/********************************************************************/
+/* Suspend/resume */
+/********************************************************************/
+
+#ifdef CONFIG_PM
+static int if_cs_suspend(struct pcmcia_device *p_dev)
+{
+ struct if_cs_card *card = p_dev->priv;
+ struct lbs_private *priv = card->priv;
+ int ret;
+
+ lbs_deb_enter(LBS_DEB_CS);
+
+ if (priv->psstate != PS_STATE_FULL_POWER) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = lbs_suspend(priv);
+ if (ret)
+ goto out;
+
+ /* TODO: do local stuff
+ * if_usb: usb_kill_urb(cardp->tx_urb) */
+out:
+ lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
+ return ret;
+}
+
+
+static int if_cs_resume(struct pcmcia_device *p_dev)
+{
+ struct if_cs_card *card = p_dev->priv;
+ struct lbs_private *priv = card->priv;
+
+ lbs_deb_enter(LBS_DEB_CS);
+
+ /* TODO: do local stuff
+ * if_usb: if_usb_submit_rx_urb(cardp); */
+
+ lbs_resume(priv);
+
+ lbs_deb_leave(LBS_DEB_CS);
+ return 0;
+}
+#else
+#define if_cs_suspend NULL
+#define if_cs_resume NULL
+#endif
+
+
+/********************************************************************/
/* Module initialization */
/********************************************************************/
@@ -905,6 +979,8 @@ static struct pcmcia_driver lbs_driver =
.probe = if_cs_probe,
.remove = if_cs_detach,
.id_table = if_cs_ids,
+ .suspend = if_cs_suspend,
+ .resume = if_cs_resume,
};
Index: wireless-testing/drivers/net/wireless/libertas/main.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/libertas/main.c 2008-04-29 15:04:15.000000000 +0200
+++ wireless-testing/drivers/net/wireless/libertas/main.c 2008-04-29 15:04:27.000000000 +0200
@@ -702,7 +702,7 @@ static int lbs_thread(void *data)
if (shouldsleep) {
lbs_deb_thread("sleeping, connect_status %d, "
- "ps_mode %d, ps_state %d\n",
+ "psmode %d, psstate %d\n",
priv->connect_status,
priv->psmode, priv->psstate);
spin_unlock_irq(&priv->driver_lock);
More information about the libertas-dev
mailing list