aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2010-08-12 01:04:33 -0400
committerRusty Russell <rusty@rustcorp.com.au>2010-08-11 09:34:37 -0400
commit886275ce41a9751117367fb387ed171049eb6148 (patch)
tree0e712d9902ab3c2c23dffb1c3565369fac72d2fa
parent7d3510356b066bcfa9898ec3f90c9c7810ba6ed7 (diff)
param: lock if_sdio's lbs_helper_name and lbs_fw_name against sysfs changes.
Since it can be changed via sysfs, we need to make a copy. This most generic way of doing this is to keep a flag so we know when to free it. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Reviewed-by: Takashi Iwai <tiwai@suse.de> Cc: Dan Williams <dcbw@redhat.com> Cc: John W. Linville <linville@tuxdriver.com> Cc: libertas-dev@lists.infradead.org Cc: linux-wireless@vger.kernel.org Cc: netdev@vger.kernel.org
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 6e71346a7550..ba854c70ab94 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -125,6 +125,8 @@ struct if_sdio_card {
125 125
126 const char *helper; 126 const char *helper;
127 const char *firmware; 127 const char *firmware;
128 bool helper_allocated;
129 bool firmware_allocated;
128 130
129 u8 buffer[65536]; 131 u8 buffer[65536];
130 132
@@ -984,16 +986,34 @@ static int if_sdio_probe(struct sdio_func *func,
984 card->helper = if_sdio_models[i].helper; 986 card->helper = if_sdio_models[i].helper;
985 card->firmware = if_sdio_models[i].firmware; 987 card->firmware = if_sdio_models[i].firmware;
986 988
989 kparam_block_sysfs_write(helper_name);
987 if (lbs_helper_name) { 990 if (lbs_helper_name) {
991 char *helper = kstrdup(lbs_helper_name, GFP_KERNEL);
992 if (!helper) {
993 kparam_unblock_sysfs_write(helper_name);
994 ret = -ENOMEM;
995 goto free;
996 }
988 lbs_deb_sdio("overriding helper firmware: %s\n", 997 lbs_deb_sdio("overriding helper firmware: %s\n",
989 lbs_helper_name); 998 lbs_helper_name);
990 card->helper = lbs_helper_name; 999 card->helper = helper;
1000 card->helper_allocated = true;
991 } 1001 }
1002 kparam_unblock_sysfs_write(helper_name);
992 1003
1004 kparam_block_sysfs_write(fw_name);
993 if (lbs_fw_name) { 1005 if (lbs_fw_name) {
1006 char *fw_name = kstrdup(lbs_fw_name, GFP_KERNEL);
1007 if (!fw_name) {
1008 kparam_unblock_sysfs_write(fw_name);
1009 ret = -ENOMEM;
1010 goto free;
1011 }
994 lbs_deb_sdio("overriding firmware: %s\n", lbs_fw_name); 1012 lbs_deb_sdio("overriding firmware: %s\n", lbs_fw_name);
995 card->firmware = lbs_fw_name; 1013 card->firmware = fw_name;
1014 card->firmware_allocated = true;
996 } 1015 }
1016 kparam_unblock_sysfs_write(fw_name);
997 1017
998 sdio_claim_host(func); 1018 sdio_claim_host(func);
999 1019
@@ -1127,6 +1147,10 @@ free:
1127 kfree(packet); 1147 kfree(packet);
1128 } 1148 }
1129 1149
1150 if (card->helper_allocated)
1151 kfree(card->helper);
1152 if (card->firmware_allocated)
1153 kfree(card->firmware);
1130 kfree(card); 1154 kfree(card);
1131 1155
1132 goto out; 1156 goto out;
@@ -1177,6 +1201,10 @@ static void if_sdio_remove(struct sdio_func *func)
1177 kfree(packet); 1201 kfree(packet);
1178 } 1202 }
1179 1203
1204 if (card->helper_allocated)
1205 kfree(card->helper);
1206 if (card->firmware_allocated)
1207 kfree(card->firmware);
1180 kfree(card); 1208 kfree(card);
1181 1209
1182 lbs_deb_leave(LBS_DEB_SDIO); 1210 lbs_deb_leave(LBS_DEB_SDIO);