diff options
author | Daniel Drake <dsd@laptop.org> | 2011-05-26 16:31:08 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-05-31 14:47:23 -0400 |
commit | 71005be40a7fc95edda3cc462361ce0243e4f5fa (patch) | |
tree | d2787b9d02c8a77cffa1028e079856b7fbae50cd /drivers | |
parent | 11ad2f52826ac6d58d6780d3d8a3e098c88d9142 (diff) |
libertas: Set command sequence number later to ensure consistency
Before this patch, the command sequence number is being set before
lbs_queue_cmd() adds the command to the queue. However, lbs_queue_cmd()
sometimes forces commands to queue-jump (e.g. CMD_802_11_WAKEUP_CONFIRM).
It currently does this without considering that sequence numbers might need
adjusting to keep things running in order.
Fix this by setting the sequence number at a later stage, just before
we're actually submitting the command to the hardware. Also fixes a
possible race where seqnum was being modified outside of the driver
lock.
Signed-off-by: Daniel Drake <dsd@laptop.org>
Acked-by: Dan Williams <dcbw@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/libertas/cmd.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 84566db486d2..71c8f3fccfa1 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c | |||
@@ -994,6 +994,8 @@ static void lbs_submit_command(struct lbs_private *priv, | |||
994 | cmd = cmdnode->cmdbuf; | 994 | cmd = cmdnode->cmdbuf; |
995 | 995 | ||
996 | spin_lock_irqsave(&priv->driver_lock, flags); | 996 | spin_lock_irqsave(&priv->driver_lock, flags); |
997 | priv->seqnum++; | ||
998 | cmd->seqnum = cpu_to_le16(priv->seqnum); | ||
997 | priv->cur_cmd = cmdnode; | 999 | priv->cur_cmd = cmdnode; |
998 | spin_unlock_irqrestore(&priv->driver_lock, flags); | 1000 | spin_unlock_irqrestore(&priv->driver_lock, flags); |
999 | 1001 | ||
@@ -1621,11 +1623,9 @@ struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, | |||
1621 | /* Copy the incoming command to the buffer */ | 1623 | /* Copy the incoming command to the buffer */ |
1622 | memcpy(cmdnode->cmdbuf, in_cmd, in_cmd_size); | 1624 | memcpy(cmdnode->cmdbuf, in_cmd, in_cmd_size); |
1623 | 1625 | ||
1624 | /* Set sequence number, clean result, move to buffer */ | 1626 | /* Set command, clean result, move to buffer */ |
1625 | priv->seqnum++; | ||
1626 | cmdnode->cmdbuf->command = cpu_to_le16(command); | 1627 | cmdnode->cmdbuf->command = cpu_to_le16(command); |
1627 | cmdnode->cmdbuf->size = cpu_to_le16(in_cmd_size); | 1628 | cmdnode->cmdbuf->size = cpu_to_le16(in_cmd_size); |
1628 | cmdnode->cmdbuf->seqnum = cpu_to_le16(priv->seqnum); | ||
1629 | cmdnode->cmdbuf->result = 0; | 1629 | cmdnode->cmdbuf->result = 0; |
1630 | 1630 | ||
1631 | lbs_deb_host("PREP_CMD: command 0x%04x\n", command); | 1631 | lbs_deb_host("PREP_CMD: command 0x%04x\n", command); |