All pastes #491561 Raw Edit

Unnamed

public text v1 · immutable
·published 2007-05-16 18:56 UTC
rendered paste body
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 {