diff options
author | Thomas Pugliese <thomas.pugliese@gmail.com> | 2013-06-24 15:26:35 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-06-24 19:20:43 -0400 |
commit | a899575191ba85a71401f2c8f36bec7b14487043 (patch) | |
tree | 74070049b20ec44cf625db68ac62751e4b33cab0 /drivers/uwb | |
parent | 6e6581e0a94758a4e69fab82407d39312eeff5c4 (diff) |
USB: HWA: fix device probe failure
This patch fixes a race condition that caused the HWA_HC interface probe
function to occasionally fail. The HWA_HC would attempt to register
itself with the HWA_RC by searching for a uwb_rc class device with the
same parent device ptr. If the probe function for the HWA_RC interface
had yet to run, the uwb_rc class device would not have been created
causing the look up to fail and the HWA_HC probe function to return an
error causing the device to be unusable.
The fix is for the HWA to delay registering with the HWA_RC until
receiving the command from userspace to start the wireless channel. It
is the responsibility of userspace to ensure that the uwb_rc class
device has been created before starting the HWA channel.
Signed-off-by: Thomas Pugliese <thomas.pugliese@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/uwb')
-rw-r--r-- | drivers/uwb/pal.c | 2 | ||||
-rw-r--r-- | drivers/uwb/uwb-internal.h | 3 |
2 files changed, 4 insertions, 1 deletions
diff --git a/drivers/uwb/pal.c b/drivers/uwb/pal.c index 8ee7d90a8c68..690577d2a35b 100644 --- a/drivers/uwb/pal.c +++ b/drivers/uwb/pal.c | |||
@@ -44,10 +44,12 @@ int uwb_pal_register(struct uwb_pal *pal) | |||
44 | int ret; | 44 | int ret; |
45 | 45 | ||
46 | if (pal->device) { | 46 | if (pal->device) { |
47 | /* create a link to the uwb_rc in the PAL device's directory. */ | ||
47 | ret = sysfs_create_link(&pal->device->kobj, | 48 | ret = sysfs_create_link(&pal->device->kobj, |
48 | &rc->uwb_dev.dev.kobj, "uwb_rc"); | 49 | &rc->uwb_dev.dev.kobj, "uwb_rc"); |
49 | if (ret < 0) | 50 | if (ret < 0) |
50 | return ret; | 51 | return ret; |
52 | /* create a link to the PAL in the UWB device's directory. */ | ||
51 | ret = sysfs_create_link(&rc->uwb_dev.dev.kobj, | 53 | ret = sysfs_create_link(&rc->uwb_dev.dev.kobj, |
52 | &pal->device->kobj, pal->name); | 54 | &pal->device->kobj, pal->name); |
53 | if (ret < 0) { | 55 | if (ret < 0) { |
diff --git a/drivers/uwb/uwb-internal.h b/drivers/uwb/uwb-internal.h index a7494bf10081..9a103b100f1e 100644 --- a/drivers/uwb/uwb-internal.h +++ b/drivers/uwb/uwb-internal.h | |||
@@ -55,7 +55,8 @@ static inline struct uwb_rc *__uwb_rc_get(struct uwb_rc *rc) | |||
55 | 55 | ||
56 | static inline void __uwb_rc_put(struct uwb_rc *rc) | 56 | static inline void __uwb_rc_put(struct uwb_rc *rc) |
57 | { | 57 | { |
58 | uwb_dev_put(&rc->uwb_dev); | 58 | if (rc) |
59 | uwb_dev_put(&rc->uwb_dev); | ||
59 | } | 60 | } |
60 | 61 | ||
61 | extern int uwb_rc_reset(struct uwb_rc *rc); | 62 | extern int uwb_rc_reset(struct uwb_rc *rc); |