diff options
author | Juuso Oikarinen <juuso.oikarinen@nokia.com> | 2009-10-13 05:47:57 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-10-27 16:48:16 -0400 |
commit | ed317788b925cfd896506ee775acca7392470b9b (patch) | |
tree | 21c5d53b6f9ff602343e1f9b7ae998822abea9a1 | |
parent | a163acce485a9629418659ff74737b89ba2c1751 (diff) |
wl1271: Correct memory handling for FW boot
Several memory allocation related failure cases were not properly
handled by the driver - the result was that in low memory conditions
booting of a corrupted FW could be attempted - and user space would not
get proper failure code.
Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Reviewed-by: Luciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_boot.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c index b8a37a84842f..41a3050afae1 100644 --- a/drivers/net/wireless/wl12xx/wl1271_boot.c +++ b/drivers/net/wireless/wl12xx/wl1271_boot.c | |||
@@ -134,7 +134,7 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, | |||
134 | } | 134 | } |
135 | 135 | ||
136 | chunk = kmalloc(CHUNK_SIZE, GFP_KERNEL); | 136 | chunk = kmalloc(CHUNK_SIZE, GFP_KERNEL); |
137 | if (!buf) { | 137 | if (!chunk) { |
138 | wl1271_error("allocation for firmware upload chunk failed"); | 138 | wl1271_error("allocation for firmware upload chunk failed"); |
139 | return -ENOMEM; | 139 | return -ENOMEM; |
140 | } | 140 | } |
@@ -184,6 +184,7 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, | |||
184 | static int wl1271_boot_upload_firmware(struct wl1271 *wl) | 184 | static int wl1271_boot_upload_firmware(struct wl1271 *wl) |
185 | { | 185 | { |
186 | u32 chunks, addr, len; | 186 | u32 chunks, addr, len; |
187 | int ret = 0; | ||
187 | u8 *fw; | 188 | u8 *fw; |
188 | 189 | ||
189 | fw = wl->fw; | 190 | fw = wl->fw; |
@@ -204,11 +205,13 @@ static int wl1271_boot_upload_firmware(struct wl1271 *wl) | |||
204 | } | 205 | } |
205 | wl1271_debug(DEBUG_BOOT, "chunk %d addr 0x%x len %u", | 206 | wl1271_debug(DEBUG_BOOT, "chunk %d addr 0x%x len %u", |
206 | chunks, addr, len); | 207 | chunks, addr, len); |
207 | wl1271_boot_upload_firmware_chunk(wl, fw, len, addr); | 208 | ret = wl1271_boot_upload_firmware_chunk(wl, fw, len, addr); |
209 | if (ret != 0) | ||
210 | break; | ||
208 | fw += len; | 211 | fw += len; |
209 | } | 212 | } |
210 | 213 | ||
211 | return 0; | 214 | return ret; |
212 | } | 215 | } |
213 | 216 | ||
214 | static int wl1271_boot_upload_nvs(struct wl1271 *wl) | 217 | static int wl1271_boot_upload_nvs(struct wl1271 *wl) |
@@ -284,6 +287,8 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl) | |||
284 | 287 | ||
285 | /* Copy the NVS tables to a new block to ensure alignment */ | 288 | /* Copy the NVS tables to a new block to ensure alignment */ |
286 | nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL); | 289 | nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL); |
290 | if (!nvs_aligned) | ||
291 | return -ENOMEM; | ||
287 | 292 | ||
288 | /* And finally we upload the NVS tables */ | 293 | /* And finally we upload the NVS tables */ |
289 | /* FIXME: In wl1271, we upload everything at once. | 294 | /* FIXME: In wl1271, we upload everything at once. |