diff options
author | Christian Lamparter <chunkeey@googlemail.com> | 2010-10-16 14:47:50 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-10-25 14:43:14 -0400 |
commit | 3d2f2cd066e9e2b7e43d516d92e66dac2fc46aa0 (patch) | |
tree | 3b5ffe5a631cbb0b22eb8f6381c0c9bb4a1e69d3 /drivers/net/wireless/ath/carl9170 | |
parent | 5f4e6b2d3c74c1adda1cbfd9d9d30da22c7484fc (diff) |
carl9170: fix memory leak issue in async cmd macro wrappers
This patch continues where the previous commit:
"carl9170: fix async command buffer leak"
left off.
Similar to carl9170_reboot/carl9170_powersave, the
carl9170_async_regwrite* macros would leak the
temporary command buffer, if __carl9170_exec_cmd
fails to upload the command to the device.
Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/carl9170')
-rw-r--r-- | drivers/net/wireless/ath/carl9170/cmd.h | 51 |
1 files changed, 28 insertions, 23 deletions
diff --git a/drivers/net/wireless/ath/carl9170/cmd.h b/drivers/net/wireless/ath/carl9170/cmd.h index f78728c3829..568174c71b9 100644 --- a/drivers/net/wireless/ath/carl9170/cmd.h +++ b/drivers/net/wireless/ath/carl9170/cmd.h | |||
@@ -116,8 +116,9 @@ __regwrite_out : \ | |||
116 | } while (0); | 116 | } while (0); |
117 | 117 | ||
118 | 118 | ||
119 | #define carl9170_async_get_buf() \ | 119 | #define carl9170_async_regwrite_get_buf() \ |
120 | do { \ | 120 | do { \ |
121 | __nreg = 0; \ | ||
121 | __cmd = carl9170_cmd_buf(__carl, CARL9170_CMD_WREG_ASYNC, \ | 122 | __cmd = carl9170_cmd_buf(__carl, CARL9170_CMD_WREG_ASYNC, \ |
122 | CARL9170_MAX_CMD_PAYLOAD_LEN); \ | 123 | CARL9170_MAX_CMD_PAYLOAD_LEN); \ |
123 | if (__cmd == NULL) { \ | 124 | if (__cmd == NULL) { \ |
@@ -128,38 +129,42 @@ do { \ | |||
128 | 129 | ||
129 | #define carl9170_async_regwrite_begin(carl) \ | 130 | #define carl9170_async_regwrite_begin(carl) \ |
130 | do { \ | 131 | do { \ |
131 | int __nreg = 0, __err = 0; \ | ||
132 | struct ar9170 *__carl = carl; \ | 132 | struct ar9170 *__carl = carl; \ |
133 | struct carl9170_cmd *__cmd; \ | 133 | struct carl9170_cmd *__cmd; \ |
134 | carl9170_async_get_buf(); \ | 134 | unsigned int __nreg; \ |
135 | int __err = 0; \ | ||
136 | carl9170_async_regwrite_get_buf(); \ | ||
137 | |||
138 | #define carl9170_async_regwrite_flush() \ | ||
139 | do { \ | ||
140 | if (__cmd == NULL || __nreg == 0) \ | ||
141 | break; \ | ||
142 | \ | ||
143 | if (IS_ACCEPTING_CMD(__carl) && __nreg) { \ | ||
144 | __cmd->hdr.len = 8 * __nreg; \ | ||
145 | __err = __carl9170_exec_cmd(__carl, __cmd, true); \ | ||
146 | __cmd = NULL; \ | ||
147 | break; \ | ||
148 | } \ | ||
149 | goto __async_regwrite_out; \ | ||
150 | } while (0) | ||
135 | 151 | ||
136 | #define carl9170_async_regwrite(r, v) do { \ | 152 | #define carl9170_async_regwrite(r, v) do { \ |
153 | if (__cmd == NULL) \ | ||
154 | carl9170_async_regwrite_get_buf(); \ | ||
137 | __cmd->wreg.regs[__nreg].addr = cpu_to_le32(r); \ | 155 | __cmd->wreg.regs[__nreg].addr = cpu_to_le32(r); \ |
138 | __cmd->wreg.regs[__nreg].val = cpu_to_le32(v); \ | 156 | __cmd->wreg.regs[__nreg].val = cpu_to_le32(v); \ |
139 | __nreg++; \ | 157 | __nreg++; \ |
140 | if ((__nreg >= PAYLOAD_MAX/2)) { \ | 158 | if ((__nreg >= PAYLOAD_MAX / 2)) \ |
141 | if (IS_ACCEPTING_CMD(__carl)) { \ | 159 | carl9170_async_regwrite_flush(); \ |
142 | __cmd->hdr.len = 8 * __nreg; \ | ||
143 | __err = __carl9170_exec_cmd(__carl, __cmd, true);\ | ||
144 | __cmd = NULL; \ | ||
145 | carl9170_async_get_buf(); \ | ||
146 | } else { \ | ||
147 | goto __async_regwrite_out; \ | ||
148 | } \ | ||
149 | __nreg = 0; \ | ||
150 | if (__err) \ | ||
151 | goto __async_regwrite_out; \ | ||
152 | } \ | ||
153 | } while (0) | 160 | } while (0) |
154 | 161 | ||
155 | #define carl9170_async_regwrite_finish() \ | 162 | #define carl9170_async_regwrite_finish() do { \ |
156 | __async_regwrite_out : \ | 163 | __async_regwrite_out : \ |
157 | if (__err == 0 && __nreg) { \ | 164 | if (__cmd != NULL && __err == 0) \ |
158 | __cmd->hdr.len = 8 * __nreg; \ | 165 | carl9170_async_regwrite_flush(); \ |
159 | if (IS_ACCEPTING_CMD(__carl)) \ | 166 | kfree(__cmd); \ |
160 | __err = __carl9170_exec_cmd(__carl, __cmd, true);\ | 167 | } while (0) \ |
161 | __nreg = 0; \ | ||
162 | } | ||
163 | 168 | ||
164 | #define carl9170_async_regwrite_result() \ | 169 | #define carl9170_async_regwrite_result() \ |
165 | __err; \ | 170 | __err; \ |