diff --git a/origin/base.c b/origin/base.c
index c9cca33..f227fdf 100644
--- a/origin/base.c
+++ b/origin/base.c
@@ -1060,8 +1060,10 @@ static int ipw_send_cmd(struct ipw_priv *priv, struct ipw_host_cmd *cmd)
/* When the SKB is provided in the tasklet, it needs
* a backpointer to the originating caller so it can
* actually copy the skb there */
- if (cmd->meta.flags & CMD_WANT_SKB)
- cmd->meta.u.source = &cmd->meta;
+ if (cmd->meta.flags & CMD_WANT_SKB) {
+ cmd->meta.source = &cmd->meta;
+ cmd->meta.magic = CMD_VAR_MAGIC;
+ }
cmd->meta.len = cmd->len;
@@ -1108,6 +1110,7 @@ static int ipw_send_cmd(struct ipw_priv *priv, struct ipw_host_cmd *cmd)
if (cmd_needs_lock(cmd))
spin_unlock_irqrestore(&priv->
lock, flags);
+ cmd->meta.magic = 0;
return -ETIMEDOUT;
}
@@ -8030,8 +8033,18 @@ static void ipw_tx_complete(struct ipw_priv *priv,
cmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
/* Input error checking is done when commands are added to queue. */
if (cmd->meta.flags & CMD_WANT_SKB) {
- cmd->meta.u.source->u.skb = rxb->skb;
- rxb->skb = NULL;
+ /* FIXME: we use cmd->meta.magic to indicate the
+ * memory cmd->meta.source points to is still valid or
+ * not at this point since caller may pass a local
+ * variable to us and returned before we get here.
+ * In this case, caller must ensure the ->magic field
+ * is set correctly to indicate the availability of the
+ * pointer cmd->meta.source. */
+ if (cmd->meta.source->magic == CMD_VAR_MAGIC) {
+ cmd->meta.source->u.skb = rxb->skb;
+ cmd->meta.source->magic = 0;
+ rxb->skb = NULL;
+ }
} else if (cmd->meta.u.callback &&
!cmd->meta.u.callback(priv, cmd, rxb->skb))
rxb->skb = NULL;
diff --git a/origin/iwlwifi.h b/origin/iwlwifi.h
index bfb2a7f..e54a61f 100644
--- a/origin/iwlwifi.h
+++ b/origin/iwlwifi.h
@@ -161,9 +161,11 @@ struct ipw_priv;
typedef int (*IPW_CALLBACK_FUNC) (struct ipw_priv * priv,
struct ipw_cmd * cmd, struct sk_buff * skb);
+#define CMD_VAR_MAGIC 0xa987
+
struct ipw_cmd_meta {
+ struct ipw_cmd_meta *source;
union {
- struct ipw_cmd_meta *source;
struct sk_buff *skb;
IPW_CALLBACK_FUNC callback;
} __attribute__ ((packed)) u;
@@ -175,6 +177,7 @@ struct ipw_cmd_meta {
u8 flags;
u8 token;
+ u16 magic;
} __attribute__ ((packed));
struct ipw_cmd {