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 {