diff options
author | Larry Finger <Larry.Finger@lwfinger.net> | 2011-05-06 14:56:18 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-05-10 15:54:46 -0400 |
commit | c84aa5af996a306c8ce66aac2cc4d5f4a74e27ca (patch) | |
tree | 7b0068632907346172d48570058aa7905f9766aa | |
parent | 054ec924944912413e4ee927b8cf02f476d08783 (diff) |
rtlwifi: Move 2 large arrays off stack
In driver rtlwifi, efuse_read() places two relatively large arrays on the
stack - a 1D u8 array of size 128, and a 2D array of u16 with 128 * 4 elements.
With driver rtl8192de, the sizes will be 256 and 256 * 4 respectively. As that
will make the 2D array be 2048 bytes, I have changed the code to use kmalloc to
allocate the space.
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/rtlwifi/efuse.c | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index 510d42edb8ca..50de6f5d8a56 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c | |||
@@ -235,7 +235,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) | |||
235 | { | 235 | { |
236 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 236 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
237 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | 237 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); |
238 | u8 efuse_tbl[HWSET_MAX_SIZE]; | 238 | u8 *efuse_tbl; |
239 | u8 rtemp8[1]; | 239 | u8 rtemp8[1]; |
240 | u16 efuse_addr = 0; | 240 | u16 efuse_addr = 0; |
241 | u8 offset, wren; | 241 | u8 offset, wren; |
@@ -245,7 +245,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) | |||
245 | rtlpriv->cfg->maps[EFUSE_MAX_SECTION_MAP]; | 245 | rtlpriv->cfg->maps[EFUSE_MAX_SECTION_MAP]; |
246 | const u32 efuse_len = | 246 | const u32 efuse_len = |
247 | rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE]; | 247 | rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE]; |
248 | u16 efuse_word[EFUSE_MAX_SECTION][EFUSE_MAX_WORD_UNIT]; | 248 | u16 **efuse_word; |
249 | u16 efuse_utilized = 0; | 249 | u16 efuse_utilized = 0; |
250 | u8 efuse_usage; | 250 | u8 efuse_usage; |
251 | 251 | ||
@@ -256,9 +256,24 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) | |||
256 | return; | 256 | return; |
257 | } | 257 | } |
258 | 258 | ||
259 | /* allocate memory for efuse_tbl and efuse_word */ | ||
260 | efuse_tbl = kmalloc(rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE] * | ||
261 | sizeof(u8), GFP_ATOMIC); | ||
262 | if (!efuse_tbl) | ||
263 | return; | ||
264 | efuse_word = kmalloc(EFUSE_MAX_WORD_UNIT * sizeof(u16 *), GFP_ATOMIC); | ||
265 | if (!efuse_word) | ||
266 | goto done; | ||
267 | for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { | ||
268 | efuse_word[i] = kmalloc(efuse_max_section * sizeof(u16), | ||
269 | GFP_ATOMIC); | ||
270 | if (!efuse_word[i]) | ||
271 | goto done; | ||
272 | } | ||
273 | |||
259 | for (i = 0; i < efuse_max_section; i++) | 274 | for (i = 0; i < efuse_max_section; i++) |
260 | for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) | 275 | for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) |
261 | efuse_word[i][j] = 0xFFFF; | 276 | efuse_word[j][i] = 0xFFFF; |
262 | 277 | ||
263 | read_efuse_byte(hw, efuse_addr, rtemp8); | 278 | read_efuse_byte(hw, efuse_addr, rtemp8); |
264 | if (*rtemp8 != 0xFF) { | 279 | if (*rtemp8 != 0xFF) { |
@@ -285,7 +300,8 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) | |||
285 | read_efuse_byte(hw, efuse_addr, rtemp8); | 300 | read_efuse_byte(hw, efuse_addr, rtemp8); |
286 | efuse_addr++; | 301 | efuse_addr++; |
287 | efuse_utilized++; | 302 | efuse_utilized++; |
288 | efuse_word[offset][i] = (*rtemp8 & 0xff); | 303 | efuse_word[i][offset] = |
304 | (*rtemp8 & 0xff); | ||
289 | 305 | ||
290 | if (efuse_addr >= efuse_len) | 306 | if (efuse_addr >= efuse_len) |
291 | break; | 307 | break; |
@@ -297,7 +313,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) | |||
297 | read_efuse_byte(hw, efuse_addr, rtemp8); | 313 | read_efuse_byte(hw, efuse_addr, rtemp8); |
298 | efuse_addr++; | 314 | efuse_addr++; |
299 | efuse_utilized++; | 315 | efuse_utilized++; |
300 | efuse_word[offset][i] |= | 316 | efuse_word[i][offset] |= |
301 | (((u16)*rtemp8 << 8) & 0xff00); | 317 | (((u16)*rtemp8 << 8) & 0xff00); |
302 | 318 | ||
303 | if (efuse_addr >= efuse_len) | 319 | if (efuse_addr >= efuse_len) |
@@ -320,9 +336,9 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) | |||
320 | for (i = 0; i < efuse_max_section; i++) { | 336 | for (i = 0; i < efuse_max_section; i++) { |
321 | for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) { | 337 | for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) { |
322 | efuse_tbl[(i * 8) + (j * 2)] = | 338 | efuse_tbl[(i * 8) + (j * 2)] = |
323 | (efuse_word[i][j] & 0xff); | 339 | (efuse_word[j][i] & 0xff); |
324 | efuse_tbl[(i * 8) + ((j * 2) + 1)] = | 340 | efuse_tbl[(i * 8) + ((j * 2) + 1)] = |
325 | ((efuse_word[i][j] >> 8) & 0xff); | 341 | ((efuse_word[j][i] >> 8) & 0xff); |
326 | } | 342 | } |
327 | } | 343 | } |
328 | 344 | ||
@@ -336,6 +352,11 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) | |||
336 | (u8 *)&efuse_utilized); | 352 | (u8 *)&efuse_utilized); |
337 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_USAGE, | 353 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_USAGE, |
338 | (u8 *)&efuse_usage); | 354 | (u8 *)&efuse_usage); |
355 | done: | ||
356 | for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) | ||
357 | kfree(efuse_word[i]); | ||
358 | kfree(efuse_word); | ||
359 | kfree(efuse_tbl); | ||
339 | } | 360 | } |
340 | 361 | ||
341 | bool efuse_shadow_update_chk(struct ieee80211_hw *hw) | 362 | bool efuse_shadow_update_chk(struct ieee80211_hw *hw) |