summaryrefslogtreecommitdiffstats
path: root/extras/recipes-kernel/linux/linux-omap/linus/0013-ueagle-atm-fix-PHY-signal-initialization-race.patch
diff options
context:
space:
mode:
Diffstat (limited to 'extras/recipes-kernel/linux/linux-omap/linus/0013-ueagle-atm-fix-PHY-signal-initialization-race.patch')
-rw-r--r--extras/recipes-kernel/linux/linux-omap/linus/0013-ueagle-atm-fix-PHY-signal-initialization-race.patch100
1 files changed, 100 insertions, 0 deletions
diff --git a/extras/recipes-kernel/linux/linux-omap/linus/0013-ueagle-atm-fix-PHY-signal-initialization-race.patch b/extras/recipes-kernel/linux/linux-omap/linus/0013-ueagle-atm-fix-PHY-signal-initialization-race.patch
new file mode 100644
index 00000000..e62a9d8c
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap/linus/0013-ueagle-atm-fix-PHY-signal-initialization-race.patch
@@ -0,0 +1,100 @@
1From c23a13703fb00384d49a00875fc12a5e00f1946a Mon Sep 17 00:00:00 2001
2From: Dan Williams <dcbw@redhat.com>
3Date: Sun, 19 Dec 2010 08:17:50 +0000
4Subject: [PATCH 13/65] ueagle-atm: fix PHY signal initialization race
5
6A race exists when initializing ueagle-atm devices where the generic atm
7device may not yet be created before the driver attempts to initialize
8it's PHY signal state, which checks whether the atm device has been
9created or not. This often causes the sysfs 'carrier' attribute to be
10'1' even though no signal has actually been found.
11
12uea_probe
13 usbatm_usb_probe
14 driver->bind (uea_bind)
15 uea_boot
16 kthread_run(uea_kthread) uea_kthread
17 usbatm_atm_init uea_start_reset
18 atm_dev_register UPDATE_ATM_SIGNAL
19
20UPDATE_ATM_SIGNAL checks whether the ATM device has been created and if
21not, will not update the PHY signal state. Because of the race that
22does not always happen in time, and the PHY signal state remains
23ATM_PHY_SIG_FOUND even though no signal exists.
24
25To fix the race, just create the kthread during initialization, and only
26after initialization is complete, start the thread that reboots the
27device and initializes PHY state.
28
29[ 3030.490931] uea_probe: calling usbatm_usb_probe
30[ 3030.490946] ueagle-atm 8-2:1.0: usbatm_usb_probe: trying driver ueagle-atm with vendor=1110, product=9031, ifnum 0
31[ 3030.493691] uea_bind: setting usbatm
32[ 3030.496932] usb 8-2: [ueagle-atm] using iso mode
33[ 3030.497283] ueagle-atm 8-2:1.0: usbatm_usb_probe: using 3021 byte buffer for rx channel 0xffff880125953508
34 <kthread already started before usbatm_usb_probe() has returned>
35[ 3030.497292] usb 8-2: [ueagle-atm] (re)booting started
36 <UPDATE_ATM_SIGNAL checks whether ATM device has been created yet before setting PHY state>
37[ 3030.497298] uea_start_reset: atm dev (null)
38 <and since it hasn't been created yet PHY state is not set>
39[ 3030.497306] ueagle-atm 8-2:1.0: usbatm_usb_probe: using 3392 byte buffer for tx channel 0xffff8801259535b8
40[ 3030.497374] usbatm_usb_probe: about to init
41[ 3030.497379] usbatm_usb_probe: calling usbatm_atm_init
42 <atm device finally gets created>
43[ 3030.497384] usbatm_atm_init: creating atm device!
44
45Signed-off-by: Dan Williams <dcbw@redhat.com>
46Signed-off-by: David S. Miller <davem@davemloft.net>
47---
48 drivers/usb/atm/ueagle-atm.c | 22 +++++++++++++++++++---
49 1 files changed, 19 insertions(+), 3 deletions(-)
50
51diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
52index 44447f5..99ac70e 100644
53--- a/drivers/usb/atm/ueagle-atm.c
54+++ b/drivers/usb/atm/ueagle-atm.c
55@@ -2206,8 +2206,11 @@ static int uea_boot(struct uea_softc *sc)
56 goto err1;
57 }
58
59- sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm");
60- if (sc->kthread == ERR_PTR(-ENOMEM)) {
61+ /* Create worker thread, but don't start it here. Start it after
62+ * all usbatm generic initialization is done.
63+ */
64+ sc->kthread = kthread_create(uea_kthread, sc, "ueagle-atm");
65+ if (IS_ERR(sc->kthread)) {
66 uea_err(INS_TO_USBDEV(sc), "failed to create thread\n");
67 goto err2;
68 }
69@@ -2624,6 +2627,7 @@ static struct usbatm_driver uea_usbatm_driver = {
70 static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)
71 {
72 struct usb_device *usb = interface_to_usbdev(intf);
73+ int ret;
74
75 uea_enters(usb);
76 uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) Rev (%#X): %s\n",
77@@ -2637,7 +2641,19 @@ static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)
78 if (UEA_IS_PREFIRM(id))
79 return uea_load_firmware(usb, UEA_CHIP_VERSION(id));
80
81- return usbatm_usb_probe(intf, id, &uea_usbatm_driver);
82+ ret = usbatm_usb_probe(intf, id, &uea_usbatm_driver);
83+ if (ret == 0) {
84+ struct usbatm_data *usbatm = usb_get_intfdata(intf);
85+ struct uea_softc *sc = usbatm->driver_data;
86+
87+ /* Ensure carrier is initialized to off as early as possible */
88+ UPDATE_ATM_SIGNAL(ATM_PHY_SIG_LOST);
89+
90+ /* Only start the worker thread when all init is done */
91+ wake_up_process(sc->kthread);
92+ }
93+
94+ return ret;
95 }
96
97 static void uea_disconnect(struct usb_interface *intf)
98--
991.6.6.1
100