diff options
author | Holger Schurig <h.schurig@mn-solutions.de> | 2007-12-05 19:58:11 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-29 02:06:04 +0300 |
commit | 675787e29fd97d08bf7e6253c89ab6de23bf7089 (patch) | |
tree | 81a51dd6696e5ba67a87e6b4bf2ee368854f23b7 /drivers/net/wireless/libertas/cmdresp.c | |
parent | 0d61d04210b617963c202a3c4dcbcd26a024d5d3 (diff) | |
download | linux-675787e29fd97d08bf7e6253c89ab6de23bf7089.tar.xz |
libertas: handy function to call firmware commands
Using an arbitrary firmware command was actually very painful. One
had to change big switch() statements in cmd.c, cmdresp.c, add
structs to the big union in "struct cmd_ds_command" and add the
define for the CMD_802_11_xxx to the proper place.
With this function, this is now much easier. For now, it implements
a blocking (a.k.a. CMD_OPTION_WAITFORRSP) way where one deals directly
with command requests and response buffers. You can do everything in
one place:
Signed-off-by: Holger Schurig <hs4233@mail.mn-solutions.de>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas/cmdresp.c')
-rw-r--r-- | drivers/net/wireless/libertas/cmdresp.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index cbd28ee7c5b8..6a43de772aa0 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -799,7 +799,7 @@ int lbs_process_rx_command(struct lbs_private *priv) } /* Store the response code to cur_cmd_retcode. */ - adapter->cur_cmd_retcode = result;; + adapter->cur_cmd_retcode = result; if (respcmd == CMD_RET(CMD_802_11_PS_MODE)) { struct cmd_ds_802_11_ps_mode *psmode = &resp->params.psmode; @@ -880,11 +880,22 @@ int lbs_process_rx_command(struct lbs_private *priv) goto done; } - spin_unlock_irqrestore(&adapter->driver_lock, flags); - - ret = handle_cmd_response(respcmd, resp, priv); - - spin_lock_irqsave(&adapter->driver_lock, flags); + if (adapter->cur_cmd->pdata_size) { + struct cmd_ds_gen *r = (struct cmd_ds_gen *)resp; + u16 sz = cpu_to_le16(resp->size); + if (sz > *adapter->cur_cmd->pdata_size) { + lbs_pr_err("response 0x%04x doesn't fit into " + "buffer (%d > %d)\n", respcmd, + sz, *adapter->cur_cmd->pdata_size); + sz = *adapter->cur_cmd->pdata_size; + } + memcpy(adapter->cur_cmd->pdata_buf, r->cmdresp, sz); + *adapter->cur_cmd->pdata_size = sz; + } else { + spin_unlock_irqrestore(&adapter->driver_lock, flags); + ret = handle_cmd_response(respcmd, resp, priv); + spin_lock_irqsave(&adapter->driver_lock, flags); + } if (adapter->cur_cmd) { /* Clean up and Put current command back to cmdfreeq */ __lbs_cleanup_and_insert_cmd(priv, adapter->cur_cmd); |