diff options
author | David Woodhouse <dwmw2@infradead.org> | 2007-12-15 03:09:33 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:07:36 -0500 |
commit | 3399ea5f239d49522212db179bca4de9e84b09df (patch) | |
tree | 8a56d5a18319b4e74afc22346821296c9d21c8ce /drivers/net | |
parent | ae125bf8278249b8c44168c5183f551c3ed28b84 (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.c | 60 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/cmd.h | 6 |
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 | } |
2140 | EXPORT_SYMBOL_GPL(lbs_cmd_copyback); | 2140 | EXPORT_SYMBOL_GPL(lbs_cmd_copyback); |
2141 | 2141 | ||
2142 | /** | 2142 | struct 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 | */ | ||
2158 | int __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 | |||
2194 | int __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 */ | ||
17 | struct 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); | ||
15 | int __lbs_cmd(struct lbs_private *priv, uint16_t command, | 21 | int __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 *), |