aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2007-09-15 19:29:07 -0400
committerJeff Garzik <jeff@garzik.org>2007-09-15 19:29:07 -0400
commita2ca44c30dd351cd386f4fb9f8590b999030274a (patch)
tree53cef142e48ca8453b3277a3b7452c53cdb54793
parenta041fe2e8d0bd749b2416ef79adc416e24af7c63 (diff)
parent53c5725581cce8a29925afd4eae71fa8c7ce551f (diff)
Merge branch 'fixes-jgarzik' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6 into upstream-fixes
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c28
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.h2
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c2
-rw-r--r--fs/compat_ioctl.c22
4 files changed, 40 insertions, 14 deletions
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index c5d6753a55ea..dfbd01eaaf34 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -3183,6 +3183,9 @@ static void bcm43xx_periodic_work_handler(struct work_struct *work)
3183 unsigned long orig_trans_start = 0; 3183 unsigned long orig_trans_start = 0;
3184 3184
3185 mutex_lock(&bcm->mutex); 3185 mutex_lock(&bcm->mutex);
3186 /* keep from doing and rearming periodic work if shutting down */
3187 if (bcm43xx_status(bcm) == BCM43xx_STAT_UNINIT)
3188 goto unlock_mutex;
3186 if (unlikely(bcm->periodic_state % 60 == 0)) { 3189 if (unlikely(bcm->periodic_state % 60 == 0)) {
3187 /* Periodic work will take a long time, so we want it to 3190 /* Periodic work will take a long time, so we want it to
3188 * be preemtible. 3191 * be preemtible.
@@ -3228,14 +3231,10 @@ static void bcm43xx_periodic_work_handler(struct work_struct *work)
3228 mmiowb(); 3231 mmiowb();
3229 bcm->periodic_state++; 3232 bcm->periodic_state++;
3230 spin_unlock_irqrestore(&bcm->irq_lock, flags); 3233 spin_unlock_irqrestore(&bcm->irq_lock, flags);
3234unlock_mutex:
3231 mutex_unlock(&bcm->mutex); 3235 mutex_unlock(&bcm->mutex);
3232} 3236}
3233 3237
3234void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
3235{
3236 cancel_rearming_delayed_work(&bcm->periodic_work);
3237}
3238
3239void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm) 3238void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm)
3240{ 3239{
3241 struct delayed_work *work = &bcm->periodic_work; 3240 struct delayed_work *work = &bcm->periodic_work;
@@ -3285,6 +3284,14 @@ static int bcm43xx_rng_init(struct bcm43xx_private *bcm)
3285 return err; 3284 return err;
3286} 3285}
3287 3286
3287void bcm43xx_cancel_work(struct bcm43xx_private *bcm)
3288{
3289 /* The system must be unlocked when this routine is entered.
3290 * If not, the next 2 steps may deadlock */
3291 cancel_work_sync(&bcm->restart_work);
3292 cancel_delayed_work_sync(&bcm->periodic_work);
3293}
3294
3288static int bcm43xx_shutdown_all_wireless_cores(struct bcm43xx_private *bcm) 3295static int bcm43xx_shutdown_all_wireless_cores(struct bcm43xx_private *bcm)
3289{ 3296{
3290 int ret = 0; 3297 int ret = 0;
@@ -3321,7 +3328,12 @@ static void bcm43xx_free_board(struct bcm43xx_private *bcm)
3321{ 3328{
3322 bcm43xx_rng_exit(bcm); 3329 bcm43xx_rng_exit(bcm);
3323 bcm43xx_sysfs_unregister(bcm); 3330 bcm43xx_sysfs_unregister(bcm);
3324 bcm43xx_periodic_tasks_delete(bcm); 3331
3332 mutex_lock(&(bcm)->mutex);
3333 bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
3334 mutex_unlock(&(bcm)->mutex);
3335
3336 bcm43xx_cancel_work(bcm);
3325 3337
3326 mutex_lock(&(bcm)->mutex); 3338 mutex_lock(&(bcm)->mutex);
3327 bcm43xx_shutdown_all_wireless_cores(bcm); 3339 bcm43xx_shutdown_all_wireless_cores(bcm);
@@ -4016,7 +4028,7 @@ static int bcm43xx_net_stop(struct net_device *net_dev)
4016 err = bcm43xx_disable_interrupts_sync(bcm); 4028 err = bcm43xx_disable_interrupts_sync(bcm);
4017 assert(!err); 4029 assert(!err);
4018 bcm43xx_free_board(bcm); 4030 bcm43xx_free_board(bcm);
4019 flush_scheduled_work(); 4031 bcm43xx_cancel_work(bcm);
4020 4032
4021 return 0; 4033 return 0;
4022} 4034}
@@ -4148,9 +4160,9 @@ static void bcm43xx_chip_reset(struct work_struct *work)
4148 struct bcm43xx_phyinfo *phy; 4160 struct bcm43xx_phyinfo *phy;
4149 int err = -ENODEV; 4161 int err = -ENODEV;
4150 4162
4163 bcm43xx_cancel_work(bcm);
4151 mutex_lock(&(bcm)->mutex); 4164 mutex_lock(&(bcm)->mutex);
4152 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { 4165 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
4153 bcm43xx_periodic_tasks_delete(bcm);
4154 phy = bcm43xx_current_phy(bcm); 4166 phy = bcm43xx_current_phy(bcm);
4155 err = bcm43xx_select_wireless_core(bcm, phy->type); 4167 err = bcm43xx_select_wireless_core(bcm, phy->type);
4156 if (!err) 4168 if (!err)
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.h b/drivers/net/wireless/bcm43xx/bcm43xx_main.h
index c8f3c532bab5..14cfbeb582ef 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.h
@@ -122,7 +122,7 @@ void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy);
122void bcm43xx_mac_suspend(struct bcm43xx_private *bcm); 122void bcm43xx_mac_suspend(struct bcm43xx_private *bcm);
123void bcm43xx_mac_enable(struct bcm43xx_private *bcm); 123void bcm43xx_mac_enable(struct bcm43xx_private *bcm);
124 124
125void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm); 125void bcm43xx_cancel_work(struct bcm43xx_private *bcm);
126void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm); 126void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm);
127 127
128void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason); 128void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
index c71b998a3694..8ab5f93d192a 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
@@ -327,7 +327,7 @@ static ssize_t bcm43xx_attr_phymode_store(struct device *dev,
327 goto out; 327 goto out;
328 } 328 }
329 329
330 bcm43xx_periodic_tasks_delete(bcm); 330 bcm43xx_cancel_work(bcm);
331 mutex_lock(&(bcm)->mutex); 331 mutex_lock(&(bcm)->mutex);
332 err = bcm43xx_select_wireless_core(bcm, phytype); 332 err = bcm43xx_select_wireless_core(bcm, phytype);
333 if (!err) 333 if (!err)
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index a6c9078af124..5a5b7116cefb 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -2311,8 +2311,10 @@ static int do_wireless_ioctl(unsigned int fd, unsigned int cmd, unsigned long ar
2311 struct iwreq __user *iwr_u; 2311 struct iwreq __user *iwr_u;
2312 struct iw_point __user *iwp; 2312 struct iw_point __user *iwp;
2313 struct compat_iw_point __user *iwp_u; 2313 struct compat_iw_point __user *iwp_u;
2314 compat_caddr_t pointer; 2314 compat_caddr_t pointer_u;
2315 void __user *pointer;
2315 __u16 length, flags; 2316 __u16 length, flags;
2317 int ret;
2316 2318
2317 iwr_u = compat_ptr(arg); 2319 iwr_u = compat_ptr(arg);
2318 iwp_u = (struct compat_iw_point __user *) &iwr_u->u.data; 2320 iwp_u = (struct compat_iw_point __user *) &iwr_u->u.data;
@@ -2330,17 +2332,29 @@ static int do_wireless_ioctl(unsigned int fd, unsigned int cmd, unsigned long ar
2330 sizeof(iwr->ifr_ifrn.ifrn_name))) 2332 sizeof(iwr->ifr_ifrn.ifrn_name)))
2331 return -EFAULT; 2333 return -EFAULT;
2332 2334
2333 if (__get_user(pointer, &iwp_u->pointer) || 2335 if (__get_user(pointer_u, &iwp_u->pointer) ||
2334 __get_user(length, &iwp_u->length) || 2336 __get_user(length, &iwp_u->length) ||
2335 __get_user(flags, &iwp_u->flags)) 2337 __get_user(flags, &iwp_u->flags))
2336 return -EFAULT; 2338 return -EFAULT;
2337 2339
2338 if (__put_user(compat_ptr(pointer), &iwp->pointer) || 2340 if (__put_user(compat_ptr(pointer_u), &iwp->pointer) ||
2339 __put_user(length, &iwp->length) || 2341 __put_user(length, &iwp->length) ||
2340 __put_user(flags, &iwp->flags)) 2342 __put_user(flags, &iwp->flags))
2341 return -EFAULT; 2343 return -EFAULT;
2342 2344
2343 return sys_ioctl(fd, cmd, (unsigned long) iwr); 2345 ret = sys_ioctl(fd, cmd, (unsigned long) iwr);
2346
2347 if (__get_user(pointer, &iwp->pointer) ||
2348 __get_user(length, &iwp->length) ||
2349 __get_user(flags, &iwp->flags))
2350 return -EFAULT;
2351
2352 if (__put_user(ptr_to_compat(pointer), &iwp_u->pointer) ||
2353 __put_user(length, &iwp_u->length) ||
2354 __put_user(flags, &iwp_u->flags))
2355 return -EFAULT;
2356
2357 return ret;
2344} 2358}
2345 2359
2346/* Since old style bridge ioctl's endup using SIOCDEVPRIVATE 2360/* Since old style bridge ioctl's endup using SIOCDEVPRIVATE