Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 256458
b: refs/heads/master
c: df90d84
h: refs/heads/master
v: v3
  • Loading branch information
Daniel Drake authored and John W. Linville committed Jul 11, 2011
1 parent 79a23da commit 98abdc0
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 18 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 55d990592f83cbfabfefde6e32bf27d4e7493d0c
refs/heads/master: df90d84382b03faf81637db31b6be14f477482c7
42 changes: 30 additions & 12 deletions trunk/drivers/net/wireless/libertas/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1069,16 +1069,34 @@ static void lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
spin_unlock_irqrestore(&priv->driver_lock, flags);
}

void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
int result)
void __lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
int result)
{
/*
* Normally, commands are removed from cmdpendingq before being
* submitted. However, we can arrive here on alternative codepaths
* where the command is still pending. Make sure the command really
* isn't part of a list at this point.
*/
list_del_init(&cmd->list);

cmd->result = result;
cmd->cmdwaitqwoken = 1;
wake_up_interruptible(&cmd->cmdwait_q);
wake_up(&cmd->cmdwait_q);

if (!cmd->callback || cmd->callback == lbs_cmd_async_callback)
__lbs_cleanup_and_insert_cmd(priv, cmd);
priv->cur_cmd = NULL;
wake_up_interruptible(&priv->waitq);
}

void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
int result)
{
unsigned long flags;
spin_lock_irqsave(&priv->driver_lock, flags);
__lbs_complete_command(priv, cmd, result);
spin_unlock_irqrestore(&priv->driver_lock, flags);
}

int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on)
Expand Down Expand Up @@ -1250,7 +1268,7 @@ static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv)
if (!list_empty(&priv->cmdfreeq)) {
tempnode = list_first_entry(&priv->cmdfreeq,
struct cmd_ctrl_node, list);
list_del(&tempnode->list);
list_del_init(&tempnode->list);
} else {
lbs_deb_host("GET_CMD_NODE: cmd_ctrl_node is not available\n");
tempnode = NULL;
Expand Down Expand Up @@ -1358,10 +1376,7 @@ int lbs_execute_next_command(struct lbs_private *priv)
cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) {
lbs_deb_host(
"EXEC_NEXT_CMD: ignore ENTER_PS cmd\n");
spin_lock_irqsave(&priv->driver_lock, flags);
list_del(&cmdnode->list);
lbs_complete_command(priv, cmdnode, 0);
spin_unlock_irqrestore(&priv->driver_lock, flags);

ret = 0;
goto done;
Expand All @@ -1371,10 +1386,7 @@ int lbs_execute_next_command(struct lbs_private *priv)
(priv->psstate == PS_STATE_PRE_SLEEP)) {
lbs_deb_host(
"EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep\n");
spin_lock_irqsave(&priv->driver_lock, flags);
list_del(&cmdnode->list);
lbs_complete_command(priv, cmdnode, 0);
spin_unlock_irqrestore(&priv->driver_lock, flags);
priv->needtowakeup = 1;

ret = 0;
Expand All @@ -1386,7 +1398,7 @@ int lbs_execute_next_command(struct lbs_private *priv)
}
}
spin_lock_irqsave(&priv->driver_lock, flags);
list_del(&cmdnode->list);
list_del_init(&cmdnode->list);
spin_unlock_irqrestore(&priv->driver_lock, flags);
lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n",
le16_to_cpu(cmd->command));
Expand Down Expand Up @@ -1669,7 +1681,13 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command,
}

might_sleep();
wait_event_interruptible(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken);

/*
* Be careful with signals here. A signal may be received as the system
* goes into suspend or resume. We do not want this to interrupt the
* command, so we perform an uninterruptible sleep.
*/
wait_event(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken);

spin_lock_irqsave(&priv->driver_lock, flags);
ret = cmdnode->result;
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/net/wireless/libertas/cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ int lbs_allocate_cmd_buffer(struct lbs_private *priv);
int lbs_free_cmd_buffer(struct lbs_private *priv);

int lbs_execute_next_command(struct lbs_private *priv);
void __lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
int result);
void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
int result);
int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len);
Expand Down
6 changes: 3 additions & 3 deletions trunk/drivers/net/wireless/libertas/cmdresp.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
lbs_deb_host("CMD_RESP: PS action 0x%X\n", action);
}

lbs_complete_command(priv, priv->cur_cmd, result);
__lbs_complete_command(priv, priv->cur_cmd, result);
spin_unlock_irqrestore(&priv->driver_lock, flags);

ret = 0;
Expand All @@ -186,7 +186,7 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
break;

}
lbs_complete_command(priv, priv->cur_cmd, result);
__lbs_complete_command(priv, priv->cur_cmd, result);
spin_unlock_irqrestore(&priv->driver_lock, flags);

ret = -1;
Expand All @@ -204,7 +204,7 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)

if (priv->cur_cmd) {
/* Clean up and Put current command back to cmdfreeq */
lbs_complete_command(priv, priv->cur_cmd, result);
__lbs_complete_command(priv, priv->cur_cmd, result);
}
spin_unlock_irqrestore(&priv->driver_lock, flags);

Expand Down
12 changes: 10 additions & 2 deletions trunk/drivers/net/wireless/libertas/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,14 @@ static void lbs_cmd_timeout_handler(unsigned long data)
le16_to_cpu(priv->cur_cmd->cmdbuf->command));

priv->cmd_timed_out = 1;

/*
* If the device didn't even acknowledge the command, reset the state
* so that we don't block all future commands due to this one timeout.
*/
if (priv->dnld_sent == DNLD_CMD_SENT)
priv->dnld_sent = DNLD_RES_RECEIVED;

wake_up_interruptible(&priv->waitq);
out:
spin_unlock_irqrestore(&priv->driver_lock, flags);
Expand Down Expand Up @@ -994,15 +1002,15 @@ void lbs_stop_card(struct lbs_private *priv)
list_for_each_entry(cmdnode, &priv->cmdpendingq, list) {
cmdnode->result = -ENOENT;
cmdnode->cmdwaitqwoken = 1;
wake_up_interruptible(&cmdnode->cmdwait_q);
wake_up(&cmdnode->cmdwait_q);
}

/* Flush the command the card is currently processing */
if (priv->cur_cmd) {
lbs_deb_main("clearing current command\n");
priv->cur_cmd->result = -ENOENT;
priv->cur_cmd->cmdwaitqwoken = 1;
wake_up_interruptible(&priv->cur_cmd->cmdwait_q);
wake_up(&priv->cur_cmd->cmdwait_q);
}
lbs_deb_main("done clearing commands\n");
spin_unlock_irqrestore(&priv->driver_lock, flags);
Expand Down

0 comments on commit 98abdc0

Please sign in to comment.