diff options
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.patch | 100 |
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 @@ | |||
1 | From c23a13703fb00384d49a00875fc12a5e00f1946a Mon Sep 17 00:00:00 2001 | ||
2 | From: Dan Williams <dcbw@redhat.com> | ||
3 | Date: Sun, 19 Dec 2010 08:17:50 +0000 | ||
4 | Subject: [PATCH 13/65] ueagle-atm: fix PHY signal initialization race | ||
5 | |||
6 | A race exists when initializing ueagle-atm devices where the generic atm | ||
7 | device may not yet be created before the driver attempts to initialize | ||
8 | it's PHY signal state, which checks whether the atm device has been | ||
9 | created or not. This often causes the sysfs 'carrier' attribute to be | ||
10 | '1' even though no signal has actually been found. | ||
11 | |||
12 | uea_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 | |||
20 | UPDATE_ATM_SIGNAL checks whether the ATM device has been created and if | ||
21 | not, will not update the PHY signal state. Because of the race that | ||
22 | does not always happen in time, and the PHY signal state remains | ||
23 | ATM_PHY_SIG_FOUND even though no signal exists. | ||
24 | |||
25 | To fix the race, just create the kthread during initialization, and only | ||
26 | after initialization is complete, start the thread that reboots the | ||
27 | device 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 | |||
45 | Signed-off-by: Dan Williams <dcbw@redhat.com> | ||
46 | Signed-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 | |||
51 | diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c | ||
52 | index 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 | -- | ||
99 | 1.6.6.1 | ||
100 | |||