aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2007-12-15 03:09:33 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:07:36 -0500
commit3399ea5f239d49522212db179bca4de9e84b09df (patch)
tree8a56d5a18319b4e74afc22346821296c9d21c8ce /drivers/net
parentae125bf8278249b8c44168c5183f551c3ed28b84 (diff)
libertas: add __lbs_cmd_async() for asynchronous command submission
Signed-off-by: David Woodhouse <dwmw2@infradead.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/libertas/cmd.c60
-rw-r--r--drivers/net/wireless/libertas/cmd.h6
2 files changed, 36 insertions, 30 deletions
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index c8f1bd583594..3079b3f24764 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -2139,42 +2139,18 @@ int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
2139} 2139}
2140EXPORT_SYMBOL_GPL(lbs_cmd_copyback); 2140EXPORT_SYMBOL_GPL(lbs_cmd_copyback);
2141 2141
2142/** 2142struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, uint16_t command,
2143 * @brief Simple way to call firmware functions 2143 struct cmd_header *in_cmd, int in_cmd_size,
2144 * 2144 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
2145 * @param priv A pointer to struct lbs_private structure 2145 unsigned long callback_arg)
2146 * @param psmode one of the many CMD_802_11_xxxx
2147 * @param cmd pointer to the parameters structure for above command
2148 * (this should not include the command, size, sequence
2149 * and result fields from struct cmd_ds_gen)
2150 * @param cmd_size size structure pointed to by cmd
2151 * @param rsp pointer to an area where the result should be placed
2152 * @param rsp_size pointer to the size of the rsp area. If the firmware
2153 * returns fewer bytes, then this *rsp_size will be
2154 * changed to the actual size.
2155 * @return -1 in case of a higher level error, otherwise
2156 * the result code from the firmware
2157 */
2158int __lbs_cmd(struct lbs_private *priv, uint16_t command,
2159 struct cmd_header *in_cmd, int in_cmd_size,
2160 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
2161 unsigned long callback_arg)
2162{ 2146{
2163 struct cmd_ctrl_node *cmdnode; 2147 struct cmd_ctrl_node *cmdnode;
2164 unsigned long flags;
2165 int ret = 0;
2166 2148
2167 lbs_deb_enter(LBS_DEB_HOST); 2149 lbs_deb_enter(LBS_DEB_HOST);
2168 2150
2169 if (!priv) {
2170 lbs_deb_host("PREP_CMD: priv is NULL\n");
2171 ret = -1;
2172 goto done;
2173 }
2174
2175 if (priv->surpriseremoved) { 2151 if (priv->surpriseremoved) {
2176 lbs_deb_host("PREP_CMD: card removed\n"); 2152 lbs_deb_host("PREP_CMD: card removed\n");
2177 ret = -1; 2153 cmdnode = ERR_PTR(-ENOENT);
2178 goto done; 2154 goto done;
2179 } 2155 }
2180 2156
@@ -2184,7 +2160,7 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command,
2184 2160
2185 /* Wake up main thread to execute next command */ 2161 /* Wake up main thread to execute next command */
2186 wake_up_interruptible(&priv->waitq); 2162 wake_up_interruptible(&priv->waitq);
2187 ret = -1; 2163 cmdnode = ERR_PTR(-ENOBUFS);
2188 goto done; 2164 goto done;
2189 } 2165 }
2190 2166
@@ -2210,6 +2186,29 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command,
2210 lbs_queue_cmd(priv, cmdnode, 1); 2186 lbs_queue_cmd(priv, cmdnode, 1);
2211 wake_up_interruptible(&priv->waitq); 2187 wake_up_interruptible(&priv->waitq);
2212 2188
2189 done:
2190 lbs_deb_leave_args(LBS_DEB_HOST, "ret %p", cmdnode);
2191 return cmdnode;
2192}
2193
2194int __lbs_cmd(struct lbs_private *priv, uint16_t command,
2195 struct cmd_header *in_cmd, int in_cmd_size,
2196 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
2197 unsigned long callback_arg)
2198{
2199 struct cmd_ctrl_node *cmdnode;
2200 unsigned long flags;
2201 int ret = 0;
2202
2203 lbs_deb_enter(LBS_DEB_HOST);
2204
2205 cmdnode = __lbs_cmd_async(priv, command, in_cmd, in_cmd_size,
2206 callback, callback_arg);
2207 if (IS_ERR(cmdnode)) {
2208 ret = PTR_ERR(cmdnode);
2209 goto done;
2210 }
2211
2213 might_sleep(); 2212 might_sleep();
2214 wait_event_interruptible(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken); 2213 wait_event_interruptible(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken);
2215 2214
@@ -2218,6 +2217,7 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command,
2218 if (ret) 2217 if (ret)
2219 lbs_pr_info("PREP_CMD: command 0x%04x failed: %d\n", 2218 lbs_pr_info("PREP_CMD: command 0x%04x failed: %d\n",
2220 command, ret); 2219 command, ret);
2220
2221 __lbs_cleanup_and_insert_cmd(priv, cmdnode); 2221 __lbs_cleanup_and_insert_cmd(priv, cmdnode);
2222 spin_unlock_irqrestore(&priv->driver_lock, flags); 2222 spin_unlock_irqrestore(&priv->driver_lock, flags);
2223 2223
diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h
index 999fabe5964b..2f4c1ec50392 100644
--- a/drivers/net/wireless/libertas/cmd.h
+++ b/drivers/net/wireless/libertas/cmd.h
@@ -12,6 +12,12 @@
12#define lbs_cmd_with_response(priv, cmdnr, cmd) \ 12#define lbs_cmd_with_response(priv, cmdnr, cmd) \
13 lbs_cmd(priv, cmdnr, cmd, lbs_cmd_copyback, (unsigned long) (cmd)) 13 lbs_cmd(priv, cmdnr, cmd, lbs_cmd_copyback, (unsigned long) (cmd))
14 14
15/* __lbs_cmd() will free the cmdnode and return success/failure.
16 __lbs_cmd_async() requires that the callback free the cmdnode */
17struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, uint16_t command,
18 struct cmd_header *in_cmd, int in_cmd_size,
19 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
20 unsigned long callback_arg);
15int __lbs_cmd(struct lbs_private *priv, uint16_t command, 21int __lbs_cmd(struct lbs_private *priv, uint16_t command,
16 struct cmd_header *in_cmd, int in_cmd_size, 22 struct cmd_header *in_cmd, int in_cmd_size,
17 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *), 23 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),