aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2014-02-26 06:01:52 -0500
committerDavid S. Miller <davem@davemloft.net>2014-02-26 16:06:12 -0500
commite5b3fa1547283b25d5e68ad2563b7e7dd8cb1209 (patch)
treea8c1d220dd2e18c085541e6978cbccc0e0e2c180 /drivers/isdn
parentc73b1f6a049d3dd0ba9d65da483483515282a5f0 (diff)
isdn: pcbit: fix interruptible_sleep_on race
interruptible_sleep_on is racy and going away. In case of pcbit, the driver would run into a timeout if the card is initialized before we start waiting for it. This uses wait_event to fix the race. In order to do this, the state machine handling for the timeout case has to get trivially reorganized so we actually know whether the timeout has occorred or not. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Cc: Karsten Keil <isdn@linux-pingi.de> Cc: netdev@vger.kernel.org Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/isdn')
-rw-r--r--drivers/isdn/pcbit/drv.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/isdn/pcbit/drv.c b/drivers/isdn/pcbit/drv.c
index 1eaf62273903..f02cc506fbfa 100644
--- a/drivers/isdn/pcbit/drv.c
+++ b/drivers/isdn/pcbit/drv.c
@@ -796,6 +796,7 @@ static void set_running_timeout(unsigned long ptr)
796#endif 796#endif
797 dev = (struct pcbit_dev *) ptr; 797 dev = (struct pcbit_dev *) ptr;
798 798
799 dev->l2_state = L2_DOWN;
799 wake_up_interruptible(&dev->set_running_wq); 800 wake_up_interruptible(&dev->set_running_wq);
800} 801}
801 802
@@ -818,7 +819,8 @@ static int set_protocol_running(struct pcbit_dev *dev)
818 819
819 add_timer(&dev->set_running_timer); 820 add_timer(&dev->set_running_timer);
820 821
821 interruptible_sleep_on(&dev->set_running_wq); 822 wait_event(dev->set_running_wq, dev->l2_state == L2_RUNNING ||
823 dev->l2_state == L2_DOWN);
822 824
823 del_timer(&dev->set_running_timer); 825 del_timer(&dev->set_running_timer);
824 826
@@ -842,8 +844,6 @@ static int set_protocol_running(struct pcbit_dev *dev)
842 printk(KERN_DEBUG "pcbit: initialization failed\n"); 844 printk(KERN_DEBUG "pcbit: initialization failed\n");
843 printk(KERN_DEBUG "pcbit: firmware not loaded\n"); 845 printk(KERN_DEBUG "pcbit: firmware not loaded\n");
844 846
845 dev->l2_state = L2_DOWN;
846
847#ifdef DEBUG 847#ifdef DEBUG
848 printk(KERN_DEBUG "Bank3 = %02x\n", 848 printk(KERN_DEBUG "Bank3 = %02x\n",
849 readb(dev->sh_mem + BANK3)); 849 readb(dev->sh_mem + BANK3));