aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/uwb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/uwb')
-rw-r--r--drivers/uwb/Makefile2
-rw-r--r--drivers/uwb/beacon.c122
-rw-r--r--drivers/uwb/driver.c2
-rw-r--r--drivers/uwb/drp-ie.c1
-rw-r--r--drivers/uwb/drp.c24
-rw-r--r--drivers/uwb/hwa-rc.c23
-rw-r--r--drivers/uwb/i1480/dfu/usb.c1
-rw-r--r--drivers/uwb/i1480/i1480u-wlp/lc.c3
-rw-r--r--drivers/uwb/i1480/i1480u-wlp/netdev.c51
-rw-r--r--drivers/uwb/i1480/i1480u-wlp/sysfs.c1
-rw-r--r--drivers/uwb/ie-rcv.c55
-rw-r--r--drivers/uwb/ie.c463
-rw-r--r--drivers/uwb/lc-rc.c62
-rw-r--r--drivers/uwb/neh.c46
-rw-r--r--drivers/uwb/pal.c25
-rw-r--r--drivers/uwb/radio.c202
-rw-r--r--drivers/uwb/reset.c45
-rw-r--r--drivers/uwb/rsv.c88
-rw-r--r--drivers/uwb/umc-bus.c62
-rw-r--r--drivers/uwb/umc-dev.c3
-rw-r--r--drivers/uwb/uwb-debug.c81
-rw-r--r--drivers/uwb/uwb-internal.h46
-rw-r--r--drivers/uwb/uwbd.c102
-rw-r--r--drivers/uwb/whc-rc.c65
-rw-r--r--drivers/uwb/whci.c6
-rw-r--r--drivers/uwb/wlp/wlp-internal.h4
-rw-r--r--drivers/uwb/wlp/wlp-lc.c19
27 files changed, 871 insertions, 733 deletions
diff --git a/drivers/uwb/Makefile b/drivers/uwb/Makefile
index 257e6908304c..ce21a95da04a 100644
--- a/drivers/uwb/Makefile
+++ b/drivers/uwb/Makefile
@@ -13,10 +13,12 @@ uwb-objs := \
13 drp-ie.o \ 13 drp-ie.o \
14 est.o \ 14 est.o \
15 ie.o \ 15 ie.o \
16 ie-rcv.o \
16 lc-dev.o \ 17 lc-dev.o \
17 lc-rc.o \ 18 lc-rc.o \
18 neh.o \ 19 neh.o \
19 pal.o \ 20 pal.o \
21 radio.o \
20 reset.o \ 22 reset.o \
21 rsv.o \ 23 rsv.o \
22 scan.o \ 24 scan.o \
diff --git a/drivers/uwb/beacon.c b/drivers/uwb/beacon.c
index 46b18eec5026..d9c60cb94993 100644
--- a/drivers/uwb/beacon.c
+++ b/drivers/uwb/beacon.c
@@ -119,7 +119,6 @@ int uwb_rc_beacon(struct uwb_rc *rc, int channel, unsigned bpst_offset)
119 int result; 119 int result;
120 struct device *dev = &rc->uwb_dev.dev; 120 struct device *dev = &rc->uwb_dev.dev;
121 121
122 mutex_lock(&rc->uwb_dev.mutex);
123 if (channel < 0) 122 if (channel < 0)
124 channel = -1; 123 channel = -1;
125 if (channel == -1) 124 if (channel == -1)
@@ -128,7 +127,7 @@ int uwb_rc_beacon(struct uwb_rc *rc, int channel, unsigned bpst_offset)
128 /* channel >= 0...dah */ 127 /* channel >= 0...dah */
129 result = uwb_rc_start_beacon(rc, bpst_offset, channel); 128 result = uwb_rc_start_beacon(rc, bpst_offset, channel);
130 if (result < 0) 129 if (result < 0)
131 goto out_up; 130 return result;
132 if (le16_to_cpu(rc->ies->wIELength) > 0) { 131 if (le16_to_cpu(rc->ies->wIELength) > 0) {
133 result = uwb_rc_set_ie(rc, rc->ies); 132 result = uwb_rc_set_ie(rc, rc->ies);
134 if (result < 0) { 133 if (result < 0) {
@@ -137,19 +136,12 @@ int uwb_rc_beacon(struct uwb_rc *rc, int channel, unsigned bpst_offset)
137 result = uwb_rc_stop_beacon(rc); 136 result = uwb_rc_stop_beacon(rc);
138 channel = -1; 137 channel = -1;
139 bpst_offset = 0; 138 bpst_offset = 0;
140 } else 139 }
141 result = 0;
142 } 140 }
143 } 141 }
144 142
145 if (result < 0) 143 if (result >= 0)
146 goto out_up; 144 rc->beaconing = channel;
147 rc->beaconing = channel;
148
149 uwb_notify(rc, NULL, uwb_bg_joined(rc) ? UWB_NOTIF_BG_JOIN : UWB_NOTIF_BG_LEAVE);
150
151out_up:
152 mutex_unlock(&rc->uwb_dev.mutex);
153 return result; 145 return result;
154} 146}
155 147
@@ -168,12 +160,6 @@ out_up:
168 * FIXME: use something faster for search than a list 160 * FIXME: use something faster for search than a list
169 */ 161 */
170 162
171struct uwb_beca uwb_beca = {
172 .list = LIST_HEAD_INIT(uwb_beca.list),
173 .mutex = __MUTEX_INITIALIZER(uwb_beca.mutex)
174};
175
176
177void uwb_bce_kfree(struct kref *_bce) 163void uwb_bce_kfree(struct kref *_bce)
178{ 164{
179 struct uwb_beca_e *bce = container_of(_bce, struct uwb_beca_e, refcnt); 165 struct uwb_beca_e *bce = container_of(_bce, struct uwb_beca_e, refcnt);
@@ -185,10 +171,11 @@ void uwb_bce_kfree(struct kref *_bce)
185 171
186/* Find a beacon by dev addr in the cache */ 172/* Find a beacon by dev addr in the cache */
187static 173static
188struct uwb_beca_e *__uwb_beca_find_bydev(const struct uwb_dev_addr *dev_addr) 174struct uwb_beca_e *__uwb_beca_find_bydev(struct uwb_rc *rc,
175 const struct uwb_dev_addr *dev_addr)
189{ 176{
190 struct uwb_beca_e *bce, *next; 177 struct uwb_beca_e *bce, *next;
191 list_for_each_entry_safe(bce, next, &uwb_beca.list, node) { 178 list_for_each_entry_safe(bce, next, &rc->uwb_beca.list, node) {
192 d_printf(6, NULL, "looking for addr %02x:%02x in %02x:%02x\n", 179 d_printf(6, NULL, "looking for addr %02x:%02x in %02x:%02x\n",
193 dev_addr->data[0], dev_addr->data[1], 180 dev_addr->data[0], dev_addr->data[1],
194 bce->dev_addr.data[0], bce->dev_addr.data[1]); 181 bce->dev_addr.data[0], bce->dev_addr.data[1]);
@@ -202,10 +189,11 @@ out:
202 189
203/* Find a beacon by dev addr in the cache */ 190/* Find a beacon by dev addr in the cache */
204static 191static
205struct uwb_beca_e *__uwb_beca_find_bymac(const struct uwb_mac_addr *mac_addr) 192struct uwb_beca_e *__uwb_beca_find_bymac(struct uwb_rc *rc,
193 const struct uwb_mac_addr *mac_addr)
206{ 194{
207 struct uwb_beca_e *bce, *next; 195 struct uwb_beca_e *bce, *next;
208 list_for_each_entry_safe(bce, next, &uwb_beca.list, node) { 196 list_for_each_entry_safe(bce, next, &rc->uwb_beca.list, node) {
209 if (!memcmp(bce->mac_addr, mac_addr->data, 197 if (!memcmp(bce->mac_addr, mac_addr->data,
210 sizeof(struct uwb_mac_addr))) 198 sizeof(struct uwb_mac_addr)))
211 goto out; 199 goto out;
@@ -229,11 +217,11 @@ struct uwb_dev *uwb_dev_get_by_devaddr(struct uwb_rc *rc,
229 struct uwb_dev *found = NULL; 217 struct uwb_dev *found = NULL;
230 struct uwb_beca_e *bce; 218 struct uwb_beca_e *bce;
231 219
232 mutex_lock(&uwb_beca.mutex); 220 mutex_lock(&rc->uwb_beca.mutex);
233 bce = __uwb_beca_find_bydev(devaddr); 221 bce = __uwb_beca_find_bydev(rc, devaddr);
234 if (bce) 222 if (bce)
235 found = uwb_dev_try_get(rc, bce->uwb_dev); 223 found = uwb_dev_try_get(rc, bce->uwb_dev);
236 mutex_unlock(&uwb_beca.mutex); 224 mutex_unlock(&rc->uwb_beca.mutex);
237 225
238 return found; 226 return found;
239} 227}
@@ -249,11 +237,11 @@ struct uwb_dev *uwb_dev_get_by_macaddr(struct uwb_rc *rc,
249 struct uwb_dev *found = NULL; 237 struct uwb_dev *found = NULL;
250 struct uwb_beca_e *bce; 238 struct uwb_beca_e *bce;
251 239
252 mutex_lock(&uwb_beca.mutex); 240 mutex_lock(&rc->uwb_beca.mutex);
253 bce = __uwb_beca_find_bymac(macaddr); 241 bce = __uwb_beca_find_bymac(rc, macaddr);
254 if (bce) 242 if (bce)
255 found = uwb_dev_try_get(rc, bce->uwb_dev); 243 found = uwb_dev_try_get(rc, bce->uwb_dev);
256 mutex_unlock(&uwb_beca.mutex); 244 mutex_unlock(&rc->uwb_beca.mutex);
257 245
258 return found; 246 return found;
259} 247}
@@ -274,7 +262,9 @@ static void uwb_beca_e_init(struct uwb_beca_e *bce)
274 * @bf: Beacon frame (part of b, really) 262 * @bf: Beacon frame (part of b, really)
275 * @ts_jiffies: Timestamp (in jiffies) when the beacon was received 263 * @ts_jiffies: Timestamp (in jiffies) when the beacon was received
276 */ 264 */
277struct uwb_beca_e *__uwb_beca_add(struct uwb_rc_evt_beacon *be, 265static
266struct uwb_beca_e *__uwb_beca_add(struct uwb_rc *rc,
267 struct uwb_rc_evt_beacon *be,
278 struct uwb_beacon_frame *bf, 268 struct uwb_beacon_frame *bf,
279 unsigned long ts_jiffies) 269 unsigned long ts_jiffies)
280{ 270{
@@ -286,7 +276,7 @@ struct uwb_beca_e *__uwb_beca_add(struct uwb_rc_evt_beacon *be,
286 uwb_beca_e_init(bce); 276 uwb_beca_e_init(bce);
287 bce->ts_jiffies = ts_jiffies; 277 bce->ts_jiffies = ts_jiffies;
288 bce->uwb_dev = NULL; 278 bce->uwb_dev = NULL;
289 list_add(&bce->node, &uwb_beca.list); 279 list_add(&bce->node, &rc->uwb_beca.list);
290 return bce; 280 return bce;
291} 281}
292 282
@@ -295,13 +285,13 @@ struct uwb_beca_e *__uwb_beca_add(struct uwb_rc_evt_beacon *be,
295 * 285 *
296 * Remove associated devicest too. 286 * Remove associated devicest too.
297 */ 287 */
298void uwb_beca_purge(void) 288void uwb_beca_purge(struct uwb_rc *rc)
299{ 289{
300 struct uwb_beca_e *bce, *next; 290 struct uwb_beca_e *bce, *next;
301 unsigned long expires; 291 unsigned long expires;
302 292
303 mutex_lock(&uwb_beca.mutex); 293 mutex_lock(&rc->uwb_beca.mutex);
304 list_for_each_entry_safe(bce, next, &uwb_beca.list, node) { 294 list_for_each_entry_safe(bce, next, &rc->uwb_beca.list, node) {
305 expires = bce->ts_jiffies + msecs_to_jiffies(beacon_timeout_ms); 295 expires = bce->ts_jiffies + msecs_to_jiffies(beacon_timeout_ms);
306 if (time_after(jiffies, expires)) { 296 if (time_after(jiffies, expires)) {
307 uwbd_dev_offair(bce); 297 uwbd_dev_offair(bce);
@@ -309,19 +299,20 @@ void uwb_beca_purge(void)
309 uwb_bce_put(bce); 299 uwb_bce_put(bce);
310 } 300 }
311 } 301 }
312 mutex_unlock(&uwb_beca.mutex); 302 mutex_unlock(&rc->uwb_beca.mutex);
313} 303}
314 304
315/* Clean up the whole beacon cache. Called on shutdown */ 305/* Clean up the whole beacon cache. Called on shutdown */
316void uwb_beca_release(void) 306void uwb_beca_release(struct uwb_rc *rc)
317{ 307{
318 struct uwb_beca_e *bce, *next; 308 struct uwb_beca_e *bce, *next;
319 mutex_lock(&uwb_beca.mutex); 309
320 list_for_each_entry_safe(bce, next, &uwb_beca.list, node) { 310 mutex_lock(&rc->uwb_beca.mutex);
311 list_for_each_entry_safe(bce, next, &rc->uwb_beca.list, node) {
321 list_del(&bce->node); 312 list_del(&bce->node);
322 uwb_bce_put(bce); 313 uwb_bce_put(bce);
323 } 314 }
324 mutex_unlock(&uwb_beca.mutex); 315 mutex_unlock(&rc->uwb_beca.mutex);
325} 316}
326 317
327static void uwb_beacon_print(struct uwb_rc *rc, struct uwb_rc_evt_beacon *be, 318static void uwb_beacon_print(struct uwb_rc *rc, struct uwb_rc_evt_beacon *be,
@@ -349,22 +340,22 @@ ssize_t uwb_bce_print_IEs(struct uwb_dev *uwb_dev, struct uwb_beca_e *bce,
349 ssize_t result = 0; 340 ssize_t result = 0;
350 struct uwb_rc_evt_beacon *be; 341 struct uwb_rc_evt_beacon *be;
351 struct uwb_beacon_frame *bf; 342 struct uwb_beacon_frame *bf;
352 struct uwb_buf_ctx ctx = { 343 int ies_len;
353 .buf = buf, 344 struct uwb_ie_hdr *ies;
354 .bytes = 0,
355 .size = size
356 };
357 345
358 mutex_lock(&bce->mutex); 346 mutex_lock(&bce->mutex);
347
359 be = bce->be; 348 be = bce->be;
360 if (be == NULL) 349 if (be) {
361 goto out; 350 bf = (struct uwb_beacon_frame *)bce->be->BeaconInfo;
362 bf = (void *) be->BeaconInfo; 351 ies_len = be->wBeaconInfoLength - sizeof(struct uwb_beacon_frame);
363 uwb_ie_for_each(uwb_dev, uwb_ie_dump_hex, &ctx, 352 ies = (struct uwb_ie_hdr *)bf->IEData;
364 bf->IEData, be->wBeaconInfoLength - sizeof(*bf)); 353
365 result = ctx.bytes; 354 result = uwb_ie_dump_hex(ies, ies_len, buf, size);
366out: 355 }
356
367 mutex_unlock(&bce->mutex); 357 mutex_unlock(&bce->mutex);
358
368 return result; 359 return result;
369} 360}
370 361
@@ -437,18 +428,18 @@ int uwbd_evt_handle_rc_beacon(struct uwb_event *evt)
437 if (uwb_mac_addr_bcast(&bf->Device_Identifier)) 428 if (uwb_mac_addr_bcast(&bf->Device_Identifier))
438 return 0; 429 return 0;
439 430
440 mutex_lock(&uwb_beca.mutex); 431 mutex_lock(&rc->uwb_beca.mutex);
441 bce = __uwb_beca_find_bymac(&bf->Device_Identifier); 432 bce = __uwb_beca_find_bymac(rc, &bf->Device_Identifier);
442 if (bce == NULL) { 433 if (bce == NULL) {
443 /* Not in there, a new device is pinging */ 434 /* Not in there, a new device is pinging */
444 uwb_beacon_print(evt->rc, be, bf); 435 uwb_beacon_print(evt->rc, be, bf);
445 bce = __uwb_beca_add(be, bf, evt->ts_jiffies); 436 bce = __uwb_beca_add(rc, be, bf, evt->ts_jiffies);
446 if (bce == NULL) { 437 if (bce == NULL) {
447 mutex_unlock(&uwb_beca.mutex); 438 mutex_unlock(&rc->uwb_beca.mutex);
448 return -ENOMEM; 439 return -ENOMEM;
449 } 440 }
450 } 441 }
451 mutex_unlock(&uwb_beca.mutex); 442 mutex_unlock(&rc->uwb_beca.mutex);
452 443
453 mutex_lock(&bce->mutex); 444 mutex_lock(&bce->mutex);
454 /* purge old beacon data */ 445 /* purge old beacon data */
@@ -588,19 +579,6 @@ error:
588 return result; 579 return result;
589} 580}
590 581
591/**
592 * uwb_bg_joined - is the RC in a beacon group?
593 * @rc: the radio controller
594 *
595 * Returns true if the radio controller is in a beacon group (even if
596 * it's the sole member).
597 */
598int uwb_bg_joined(struct uwb_rc *rc)
599{
600 return rc->beaconing != -1;
601}
602EXPORT_SYMBOL_GPL(uwb_bg_joined);
603
604/* 582/*
605 * Print beaconing state. 583 * Print beaconing state.
606 */ 584 */
@@ -619,9 +597,6 @@ static ssize_t uwb_rc_beacon_show(struct device *dev,
619 597
620/* 598/*
621 * Start beaconing on the specified channel, or stop beaconing. 599 * Start beaconing on the specified channel, or stop beaconing.
622 *
623 * The BPST offset of when to start searching for a beacon group to
624 * join may be specified.
625 */ 600 */
626static ssize_t uwb_rc_beacon_store(struct device *dev, 601static ssize_t uwb_rc_beacon_store(struct device *dev,
627 struct device_attribute *attr, 602 struct device_attribute *attr,
@@ -630,12 +605,11 @@ static ssize_t uwb_rc_beacon_store(struct device *dev,
630 struct uwb_dev *uwb_dev = to_uwb_dev(dev); 605 struct uwb_dev *uwb_dev = to_uwb_dev(dev);
631 struct uwb_rc *rc = uwb_dev->rc; 606 struct uwb_rc *rc = uwb_dev->rc;
632 int channel; 607 int channel;
633 unsigned bpst_offset = 0;
634 ssize_t result = -EINVAL; 608 ssize_t result = -EINVAL;
635 609
636 result = sscanf(buf, "%d %u\n", &channel, &bpst_offset); 610 result = sscanf(buf, "%d", &channel);
637 if (result >= 1) 611 if (result >= 1)
638 result = uwb_rc_beacon(rc, channel, bpst_offset); 612 result = uwb_radio_force_channel(rc, channel);
639 613
640 return result < 0 ? result : size; 614 return result < 0 ? result : size;
641} 615}
diff --git a/drivers/uwb/driver.c b/drivers/uwb/driver.c
index 521cdeb84971..f57c26580de2 100644
--- a/drivers/uwb/driver.c
+++ b/drivers/uwb/driver.c
@@ -118,7 +118,6 @@ static int __init uwb_subsys_init(void)
118 result = class_register(&uwb_rc_class); 118 result = class_register(&uwb_rc_class);
119 if (result < 0) 119 if (result < 0)
120 goto error_uwb_rc_class_register; 120 goto error_uwb_rc_class_register;
121 uwbd_start();
122 uwb_dbg_init(); 121 uwb_dbg_init();
123 return 0; 122 return 0;
124 123
@@ -132,7 +131,6 @@ module_init(uwb_subsys_init);
132static void __exit uwb_subsys_exit(void) 131static void __exit uwb_subsys_exit(void)
133{ 132{
134 uwb_dbg_exit(); 133 uwb_dbg_exit();
135 uwbd_stop();
136 class_unregister(&uwb_rc_class); 134 class_unregister(&uwb_rc_class);
137 uwb_est_destroy(); 135 uwb_est_destroy();
138 return; 136 return;
diff --git a/drivers/uwb/drp-ie.c b/drivers/uwb/drp-ie.c
index 882724c5f126..75491d47806b 100644
--- a/drivers/uwb/drp-ie.c
+++ b/drivers/uwb/drp-ie.c
@@ -16,7 +16,6 @@
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */ 18 */
19#include <linux/version.h>
20#include <linux/kernel.h> 19#include <linux/kernel.h>
21#include <linux/random.h> 20#include <linux/random.h>
22#include <linux/uwb.h> 21#include <linux/uwb.h>
diff --git a/drivers/uwb/drp.c b/drivers/uwb/drp.c
index c0b1e5e2bd08..fe328146adb7 100644
--- a/drivers/uwb/drp.c
+++ b/drivers/uwb/drp.c
@@ -37,14 +37,13 @@
37 * 37 *
38 * A DRP Availability IE is appended. 38 * A DRP Availability IE is appended.
39 * 39 *
40 * rc->uwb_dev.mutex is held 40 * rc->rsvs_mutex is held
41 * 41 *
42 * FIXME We currently ignore the returned value indicating the remaining space 42 * FIXME We currently ignore the returned value indicating the remaining space
43 * in beacon. This could be used to deny reservation requests earlier if 43 * in beacon. This could be used to deny reservation requests earlier if
44 * determined that they would cause the beacon space to be exceeded. 44 * determined that they would cause the beacon space to be exceeded.
45 */ 45 */
46static 46int uwb_rc_send_all_drp_ie(struct uwb_rc *rc)
47int uwb_rc_gen_send_drp_ie(struct uwb_rc *rc)
48{ 47{
49 int result; 48 int result;
50 struct device *dev = &rc->uwb_dev.dev; 49 struct device *dev = &rc->uwb_dev.dev;
@@ -102,25 +101,6 @@ error_cmd:
102 kfree(cmd); 101 kfree(cmd);
103error: 102error:
104 return result; 103 return result;
105
106}
107/**
108 * Send all DRP IEs associated with this host
109 *
110 * @returns: >= 0 number of bytes still available in the beacon
111 * < 0 errno code on error.
112 *
113 * As per the protocol we obtain the host controller device lock to access
114 * bandwidth structures.
115 */
116int uwb_rc_send_all_drp_ie(struct uwb_rc *rc)
117{
118 int result;
119
120 mutex_lock(&rc->uwb_dev.mutex);
121 result = uwb_rc_gen_send_drp_ie(rc);
122 mutex_unlock(&rc->uwb_dev.mutex);
123 return result;
124} 104}
125 105
126void uwb_drp_handle_timeout(struct uwb_rsv *rsv) 106void uwb_drp_handle_timeout(struct uwb_rsv *rsv)
diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c
index 3d26fa0f8ae1..158e98d08af9 100644
--- a/drivers/uwb/hwa-rc.c
+++ b/drivers/uwb/hwa-rc.c
@@ -51,7 +51,6 @@
51 * 51 *
52 * 52 *
53 */ 53 */
54#include <linux/version.h>
55#include <linux/init.h> 54#include <linux/init.h>
56#include <linux/module.h> 55#include <linux/module.h>
57#include <linux/usb.h> 56#include <linux/usb.h>
@@ -882,6 +881,24 @@ static void hwarc_disconnect(struct usb_interface *iface)
882 uwb_rc_put(uwb_rc); /* when creating the device, refcount = 1 */ 881 uwb_rc_put(uwb_rc); /* when creating the device, refcount = 1 */
883} 882}
884 883
884static int hwarc_pre_reset(struct usb_interface *iface)
885{
886 struct hwarc *hwarc = usb_get_intfdata(iface);
887 struct uwb_rc *uwb_rc = hwarc->uwb_rc;
888
889 uwb_rc_pre_reset(uwb_rc);
890 return 0;
891}
892
893static int hwarc_post_reset(struct usb_interface *iface)
894{
895 struct hwarc *hwarc = usb_get_intfdata(iface);
896 struct uwb_rc *uwb_rc = hwarc->uwb_rc;
897
898 uwb_rc_post_reset(uwb_rc);
899 return 0;
900}
901
885/** USB device ID's that we handle */ 902/** USB device ID's that we handle */
886static struct usb_device_id hwarc_id_table[] = { 903static struct usb_device_id hwarc_id_table[] = {
887 /* D-Link DUB-1210 */ 904 /* D-Link DUB-1210 */
@@ -898,9 +915,11 @@ MODULE_DEVICE_TABLE(usb, hwarc_id_table);
898 915
899static struct usb_driver hwarc_driver = { 916static struct usb_driver hwarc_driver = {
900 .name = "hwa-rc", 917 .name = "hwa-rc",
918 .id_table = hwarc_id_table,
901 .probe = hwarc_probe, 919 .probe = hwarc_probe,
902 .disconnect = hwarc_disconnect, 920 .disconnect = hwarc_disconnect,
903 .id_table = hwarc_id_table, 921 .pre_reset = hwarc_pre_reset,
922 .post_reset = hwarc_post_reset,
904}; 923};
905 924
906static int __init hwarc_driver_init(void) 925static int __init hwarc_driver_init(void)
diff --git a/drivers/uwb/i1480/dfu/usb.c b/drivers/uwb/i1480/dfu/usb.c
index 98eeeff051aa..b7ea525fc06a 100644
--- a/drivers/uwb/i1480/dfu/usb.c
+++ b/drivers/uwb/i1480/dfu/usb.c
@@ -35,7 +35,6 @@
35 * the functions are i1480_usb_NAME(). 35 * the functions are i1480_usb_NAME().
36 */ 36 */
37#include <linux/module.h> 37#include <linux/module.h>
38#include <linux/version.h>
39#include <linux/usb.h> 38#include <linux/usb.h>
40#include <linux/interrupt.h> 39#include <linux/interrupt.h>
41#include <linux/delay.h> 40#include <linux/delay.h>
diff --git a/drivers/uwb/i1480/i1480u-wlp/lc.c b/drivers/uwb/i1480/i1480u-wlp/lc.c
index 737d60cd5b73..488b2e30a0a8 100644
--- a/drivers/uwb/i1480/i1480u-wlp/lc.c
+++ b/drivers/uwb/i1480/i1480u-wlp/lc.c
@@ -55,7 +55,6 @@
55 * is being removed. 55 * is being removed.
56 * i1480u_rm() 56 * i1480u_rm()
57 */ 57 */
58#include <linux/version.h>
59#include <linux/if_arp.h> 58#include <linux/if_arp.h>
60#include <linux/etherdevice.h> 59#include <linux/etherdevice.h>
61#include <linux/uwb/debug.h> 60#include <linux/uwb/debug.h>
@@ -207,7 +206,7 @@ int i1480u_add(struct i1480u *i1480u, struct usb_interface *iface)
207 wlp->fill_device_info = i1480u_fill_device_info; 206 wlp->fill_device_info = i1480u_fill_device_info;
208 wlp->stop_queue = i1480u_stop_queue; 207 wlp->stop_queue = i1480u_stop_queue;
209 wlp->start_queue = i1480u_start_queue; 208 wlp->start_queue = i1480u_start_queue;
210 result = wlp_setup(wlp, rc); 209 result = wlp_setup(wlp, rc, net_dev);
211 if (result < 0) { 210 if (result < 0) {
212 dev_err(&iface->dev, "Cannot setup WLP\n"); 211 dev_err(&iface->dev, "Cannot setup WLP\n");
213 goto error_wlp_setup; 212 goto error_wlp_setup;
diff --git a/drivers/uwb/i1480/i1480u-wlp/netdev.c b/drivers/uwb/i1480/i1480u-wlp/netdev.c
index 8802ac43d872..2eafb973cd05 100644
--- a/drivers/uwb/i1480/i1480u-wlp/netdev.c
+++ b/drivers/uwb/i1480/i1480u-wlp/netdev.c
@@ -207,6 +207,11 @@ int i1480u_open(struct net_device *net_dev)
207 result = i1480u_rx_setup(i1480u); /* Alloc RX stuff */ 207 result = i1480u_rx_setup(i1480u); /* Alloc RX stuff */
208 if (result < 0) 208 if (result < 0)
209 goto error_rx_setup; 209 goto error_rx_setup;
210
211 result = uwb_radio_start(&wlp->pal);
212 if (result < 0)
213 goto error_radio_start;
214
210 netif_wake_queue(net_dev); 215 netif_wake_queue(net_dev);
211#ifdef i1480u_FLOW_CONTROL 216#ifdef i1480u_FLOW_CONTROL
212 result = usb_submit_urb(i1480u->notif_urb, GFP_KERNEL);; 217 result = usb_submit_urb(i1480u->notif_urb, GFP_KERNEL);;
@@ -215,25 +220,20 @@ int i1480u_open(struct net_device *net_dev)
215 goto error_notif_urb_submit; 220 goto error_notif_urb_submit;
216 } 221 }
217#endif 222#endif
218 i1480u->uwb_notifs_handler.cb = i1480u_uwb_notifs_cb;
219 i1480u->uwb_notifs_handler.data = i1480u;
220 if (uwb_bg_joined(rc))
221 netif_carrier_on(net_dev);
222 else
223 netif_carrier_off(net_dev);
224 uwb_notifs_register(rc, &i1480u->uwb_notifs_handler);
225 /* Interface is up with an address, now we can create WSS */ 223 /* Interface is up with an address, now we can create WSS */
226 result = wlp_wss_setup(net_dev, &wlp->wss); 224 result = wlp_wss_setup(net_dev, &wlp->wss);
227 if (result < 0) { 225 if (result < 0) {
228 dev_err(dev, "Can't create WSS: %d. \n", result); 226 dev_err(dev, "Can't create WSS: %d. \n", result);
229 goto error_notif_deregister; 227 goto error_wss_setup;
230 } 228 }
231 return 0; 229 return 0;
232error_notif_deregister: 230error_wss_setup:
233 uwb_notifs_deregister(rc, &i1480u->uwb_notifs_handler);
234#ifdef i1480u_FLOW_CONTROL 231#ifdef i1480u_FLOW_CONTROL
232 usb_kill_urb(i1480u->notif_urb);
235error_notif_urb_submit: 233error_notif_urb_submit:
236#endif 234#endif
235 uwb_radio_stop(&wlp->pal);
236error_radio_start:
237 netif_stop_queue(net_dev); 237 netif_stop_queue(net_dev);
238 i1480u_rx_release(i1480u); 238 i1480u_rx_release(i1480u);
239error_rx_setup: 239error_rx_setup:
@@ -248,16 +248,15 @@ int i1480u_stop(struct net_device *net_dev)
248{ 248{
249 struct i1480u *i1480u = netdev_priv(net_dev); 249 struct i1480u *i1480u = netdev_priv(net_dev);
250 struct wlp *wlp = &i1480u->wlp; 250 struct wlp *wlp = &i1480u->wlp;
251 struct uwb_rc *rc = wlp->rc;
252 251
253 BUG_ON(wlp->rc == NULL); 252 BUG_ON(wlp->rc == NULL);
254 wlp_wss_remove(&wlp->wss); 253 wlp_wss_remove(&wlp->wss);
255 uwb_notifs_deregister(rc, &i1480u->uwb_notifs_handler);
256 netif_carrier_off(net_dev); 254 netif_carrier_off(net_dev);
257#ifdef i1480u_FLOW_CONTROL 255#ifdef i1480u_FLOW_CONTROL
258 usb_kill_urb(i1480u->notif_urb); 256 usb_kill_urb(i1480u->notif_urb);
259#endif 257#endif
260 netif_stop_queue(net_dev); 258 netif_stop_queue(net_dev);
259 uwb_radio_stop(&wlp->pal);
261 i1480u_rx_release(i1480u); 260 i1480u_rx_release(i1480u);
262 i1480u_tx_release(i1480u); 261 i1480u_tx_release(i1480u);
263 return 0; 262 return 0;
@@ -303,34 +302,6 @@ int i1480u_change_mtu(struct net_device *net_dev, int mtu)
303 return 0; 302 return 0;
304} 303}
305 304
306
307/**
308 * Callback function to handle events from UWB
309 * When we see other devices we know the carrier is ok,
310 * if we are the only device in the beacon group we set the carrier
311 * state to off.
312 * */
313void i1480u_uwb_notifs_cb(void *data, struct uwb_dev *uwb_dev,
314 enum uwb_notifs event)
315{
316 struct i1480u *i1480u = data;
317 struct net_device *net_dev = i1480u->net_dev;
318 struct device *dev = &i1480u->usb_iface->dev;
319 switch (event) {
320 case UWB_NOTIF_BG_JOIN:
321 netif_carrier_on(net_dev);
322 dev_info(dev, "Link is up\n");
323 break;
324 case UWB_NOTIF_BG_LEAVE:
325 netif_carrier_off(net_dev);
326 dev_info(dev, "Link is down\n");
327 break;
328 default:
329 dev_err(dev, "don't know how to handle event %d from uwb\n",
330 event);
331 }
332}
333
334/** 305/**
335 * Stop the network queue 306 * Stop the network queue
336 * 307 *
diff --git a/drivers/uwb/i1480/i1480u-wlp/sysfs.c b/drivers/uwb/i1480/i1480u-wlp/sysfs.c
index a1d8ca6ac935..a92a787725fc 100644
--- a/drivers/uwb/i1480/i1480u-wlp/sysfs.c
+++ b/drivers/uwb/i1480/i1480u-wlp/sysfs.c
@@ -226,7 +226,6 @@ ssize_t wlp_tx_inflight_store(struct i1480u_tx_inflight *inflight,
226 * (CLASS_DEVICE_ATTR or DEVICE_ATTR) and i1480u_ATTR_NAME produces a 226 * (CLASS_DEVICE_ATTR or DEVICE_ATTR) and i1480u_ATTR_NAME produces a
227 * class_device_attr_NAME or device_attr_NAME (for group registration). 227 * class_device_attr_NAME or device_attr_NAME (for group registration).
228 */ 228 */
229#include <linux/version.h>
230 229
231#define i1480u_SHOW(name, fn, param) \ 230#define i1480u_SHOW(name, fn, param) \
232static ssize_t i1480u_show_##name(struct device *dev, \ 231static ssize_t i1480u_show_##name(struct device *dev, \
diff --git a/drivers/uwb/ie-rcv.c b/drivers/uwb/ie-rcv.c
new file mode 100644
index 000000000000..917e6d78a798
--- /dev/null
+++ b/drivers/uwb/ie-rcv.c
@@ -0,0 +1,55 @@
1/*
2 * Ultra Wide Band
3 * IE Received notification handling.
4 *
5 * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License version
9 * 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/errno.h>
21#include <linux/module.h>
22#include <linux/device.h>
23#include <linux/bitmap.h>
24#include "uwb-internal.h"
25
26/*
27 * Process an incoming IE Received notification.
28 */
29int uwbd_evt_handle_rc_ie_rcv(struct uwb_event *evt)
30{
31 int result = -EINVAL;
32 struct device *dev = &evt->rc->uwb_dev.dev;
33 struct uwb_rc_evt_ie_rcv *iercv;
34 size_t iesize;
35
36 /* Is there enough data to decode it? */
37 if (evt->notif.size < sizeof(*iercv)) {
38 dev_err(dev, "IE Received notification: Not enough data to "
39 "decode (%zu vs %zu bytes needed)\n",
40 evt->notif.size, sizeof(*iercv));
41 goto error;
42 }
43 iercv = container_of(evt->notif.rceb, struct uwb_rc_evt_ie_rcv, rceb);
44 iesize = le16_to_cpu(iercv->wIELength);
45
46 dev_dbg(dev, "IE received, element ID=%d\n", iercv->IEData[0]);
47
48 if (iercv->IEData[0] == UWB_RELINQUISH_REQUEST_IE) {
49 dev_warn(dev, "unhandled Relinquish Request IE\n");
50 }
51
52 return 0;
53error:
54 return result;
55}
diff --git a/drivers/uwb/ie.c b/drivers/uwb/ie.c
index cf6f3d152b9d..ab976686175b 100644
--- a/drivers/uwb/ie.c
+++ b/drivers/uwb/ie.c
@@ -25,8 +25,6 @@
25 */ 25 */
26 26
27#include "uwb-internal.h" 27#include "uwb-internal.h"
28#define D_LOCAL 0
29#include <linux/uwb/debug.h>
30 28
31/** 29/**
32 * uwb_ie_next - get the next IE in a buffer 30 * uwb_ie_next - get the next IE in a buffer
@@ -61,6 +59,42 @@ struct uwb_ie_hdr *uwb_ie_next(void **ptr, size_t *len)
61EXPORT_SYMBOL_GPL(uwb_ie_next); 59EXPORT_SYMBOL_GPL(uwb_ie_next);
62 60
63/** 61/**
62 * uwb_ie_dump_hex - print IEs to a character buffer
63 * @ies: the IEs to print.
64 * @len: length of all the IEs.
65 * @buf: the destination buffer.
66 * @size: size of @buf.
67 *
68 * Returns the number of characters written.
69 */
70int uwb_ie_dump_hex(const struct uwb_ie_hdr *ies, size_t len,
71 char *buf, size_t size)
72{
73 void *ptr;
74 const struct uwb_ie_hdr *ie;
75 int r = 0;
76 u8 *d;
77
78 ptr = (void *)ies;
79 for (;;) {
80 ie = uwb_ie_next(&ptr, &len);
81 if (!ie)
82 break;
83
84 r += scnprintf(buf + r, size - r, "%02x %02x",
85 (unsigned)ie->element_id,
86 (unsigned)ie->length);
87 d = (uint8_t *)ie + sizeof(struct uwb_ie_hdr);
88 while (d != ptr && r < size)
89 r += scnprintf(buf + r, size - r, " %02x", (unsigned)*d++);
90 if (r < size)
91 buf[r++] = '\n';
92 };
93
94 return r;
95}
96
97/**
64 * Get the IEs that a radio controller is sending in its beacon 98 * Get the IEs that a radio controller is sending in its beacon
65 * 99 *
66 * @uwb_rc: UWB Radio Controller 100 * @uwb_rc: UWB Radio Controller
@@ -70,6 +104,7 @@ EXPORT_SYMBOL_GPL(uwb_ie_next);
70 * anything. Once done with the iedata buffer, call 104 * anything. Once done with the iedata buffer, call
71 * uwb_rc_ie_release(iedata). Don't call kfree on it. 105 * uwb_rc_ie_release(iedata). Don't call kfree on it.
72 */ 106 */
107static
73ssize_t uwb_rc_get_ie(struct uwb_rc *uwb_rc, struct uwb_rc_evt_get_ie **pget_ie) 108ssize_t uwb_rc_get_ie(struct uwb_rc *uwb_rc, struct uwb_rc_evt_get_ie **pget_ie)
74{ 109{
75 ssize_t result; 110 ssize_t result;
@@ -78,148 +113,35 @@ ssize_t uwb_rc_get_ie(struct uwb_rc *uwb_rc, struct uwb_rc_evt_get_ie **pget_ie)
78 struct uwb_rceb *reply = NULL; 113 struct uwb_rceb *reply = NULL;
79 struct uwb_rc_evt_get_ie *get_ie; 114 struct uwb_rc_evt_get_ie *get_ie;
80 115
81 d_fnstart(3, dev, "(%p, %p)\n", uwb_rc, pget_ie);
82 result = -ENOMEM;
83 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 116 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
84 if (cmd == NULL) 117 if (cmd == NULL)
85 goto error_kzalloc; 118 return -ENOMEM;
119
86 cmd->bCommandType = UWB_RC_CET_GENERAL; 120 cmd->bCommandType = UWB_RC_CET_GENERAL;
87 cmd->wCommand = cpu_to_le16(UWB_RC_CMD_GET_IE); 121 cmd->wCommand = cpu_to_le16(UWB_RC_CMD_GET_IE);
88 result = uwb_rc_vcmd(uwb_rc, "GET_IE", cmd, sizeof(*cmd), 122 result = uwb_rc_vcmd(uwb_rc, "GET_IE", cmd, sizeof(*cmd),
89 UWB_RC_CET_GENERAL, UWB_RC_CMD_GET_IE, 123 UWB_RC_CET_GENERAL, UWB_RC_CMD_GET_IE,
90 &reply); 124 &reply);
125 kfree(cmd);
91 if (result < 0) 126 if (result < 0)
92 goto error_cmd; 127 return result;
128
93 get_ie = container_of(reply, struct uwb_rc_evt_get_ie, rceb); 129 get_ie = container_of(reply, struct uwb_rc_evt_get_ie, rceb);
94 if (result < sizeof(*get_ie)) { 130 if (result < sizeof(*get_ie)) {
95 dev_err(dev, "not enough data returned for decoding GET IE " 131 dev_err(dev, "not enough data returned for decoding GET IE "
96 "(%zu bytes received vs %zu needed)\n", 132 "(%zu bytes received vs %zu needed)\n",
97 result, sizeof(*get_ie)); 133 result, sizeof(*get_ie));
98 result = -EINVAL; 134 return -EINVAL;
99 } else if (result < sizeof(*get_ie) + le16_to_cpu(get_ie->wIELength)) { 135 } else if (result < sizeof(*get_ie) + le16_to_cpu(get_ie->wIELength)) {
100 dev_err(dev, "not enough data returned for decoding GET IE " 136 dev_err(dev, "not enough data returned for decoding GET IE "
101 "payload (%zu bytes received vs %zu needed)\n", result, 137 "payload (%zu bytes received vs %zu needed)\n", result,
102 sizeof(*get_ie) + le16_to_cpu(get_ie->wIELength)); 138 sizeof(*get_ie) + le16_to_cpu(get_ie->wIELength));
103 result = -EINVAL;
104 } else
105 *pget_ie = get_ie;
106error_cmd:
107 kfree(cmd);
108error_kzalloc:
109 d_fnend(3, dev, "(%p, %p) = %d\n", uwb_rc, pget_ie, (int)result);
110 return result;
111}
112EXPORT_SYMBOL_GPL(uwb_rc_get_ie);
113
114
115/*
116 * Given a pointer to an IE, print it in ASCII/hex followed by a new line
117 *
118 * @ie_hdr: pointer to the IE header. Length is in there, and it is
119 * guaranteed that the ie_hdr->length bytes following it are
120 * safely accesible.
121 *
122 * @_data: context data passed from uwb_ie_for_each(), an struct output_ctx
123 */
124int uwb_ie_dump_hex(struct uwb_dev *uwb_dev, const struct uwb_ie_hdr *ie_hdr,
125 size_t offset, void *_ctx)
126{
127 struct uwb_buf_ctx *ctx = _ctx;
128 const u8 *pl = (void *)(ie_hdr + 1);
129 u8 pl_itr;
130
131 ctx->bytes += scnprintf(ctx->buf + ctx->bytes, ctx->size - ctx->bytes,
132 "%02x %02x ", (unsigned) ie_hdr->element_id,
133 (unsigned) ie_hdr->length);
134 pl_itr = 0;
135 while (pl_itr < ie_hdr->length && ctx->bytes < ctx->size)
136 ctx->bytes += scnprintf(ctx->buf + ctx->bytes,
137 ctx->size - ctx->bytes,
138 "%02x ", (unsigned) pl[pl_itr++]);
139 if (ctx->bytes < ctx->size)
140 ctx->buf[ctx->bytes++] = '\n';
141 return 0;
142}
143EXPORT_SYMBOL_GPL(uwb_ie_dump_hex);
144
145
146/**
147 * Verify that a pointer in a buffer points to valid IE
148 *
149 * @start: pointer to start of buffer in which IE appears
150 * @itr: pointer to IE inside buffer that will be verified
151 * @top: pointer to end of buffer
152 *
153 * @returns: 0 if IE is valid, <0 otherwise
154 *
155 * Verification involves checking that the buffer can contain a
156 * header and the amount of data reported in the IE header can be found in
157 * the buffer.
158 */
159static
160int uwb_rc_ie_verify(struct uwb_dev *uwb_dev, const void *start,
161 const void *itr, const void *top)
162{
163 struct device *dev = &uwb_dev->dev;
164 const struct uwb_ie_hdr *ie_hdr;
165
166 if (top - itr < sizeof(*ie_hdr)) {
167 dev_err(dev, "Bad IE: no data to decode header "
168 "(%zu bytes left vs %zu needed) at offset %zu\n",
169 top - itr, sizeof(*ie_hdr), itr - start);
170 return -EINVAL;
171 }
172 ie_hdr = itr;
173 itr += sizeof(*ie_hdr);
174 if (top - itr < ie_hdr->length) {
175 dev_err(dev, "Bad IE: not enough data for payload "
176 "(%zu bytes left vs %zu needed) at offset %zu\n",
177 top - itr, (size_t)ie_hdr->length,
178 (void *)ie_hdr - start);
179 return -EINVAL; 139 return -EINVAL;
180 } 140 }
181 return 0;
182}
183 141
184 142 *pget_ie = get_ie;
185/**
186 * Walk a buffer filled with consecutive IE's a buffer
187 *
188 * @uwb_dev: UWB device this IEs belong to (for err messages mainly)
189 *
190 * @fn: function to call with each IE; if it returns 0, we keep
191 * traversing the buffer. If it returns !0, we'll stop and return
192 * that value.
193 *
194 * @data: pointer passed to @fn
195 *
196 * @buf: buffer where the consecutive IEs are located
197 *
198 * @size: size of @buf
199 *
200 * Each IE is checked for basic correctness (there is space left for
201 * the header and the payload). If that test is failed, we stop
202 * processing. For every good IE, @fn is called.
203 */
204ssize_t uwb_ie_for_each(struct uwb_dev *uwb_dev, uwb_ie_f fn, void *data,
205 const void *buf, size_t size)
206{
207 ssize_t result = 0;
208 const struct uwb_ie_hdr *ie_hdr;
209 const void *itr = buf, *top = itr + size;
210
211 while (itr < top) {
212 if (uwb_rc_ie_verify(uwb_dev, buf, itr, top) != 0)
213 break;
214 ie_hdr = itr;
215 itr += sizeof(*ie_hdr) + ie_hdr->length;
216 result = fn(uwb_dev, ie_hdr, itr - buf, data);
217 if (result != 0)
218 break;
219 }
220 return result; 143 return result;
221} 144}
222EXPORT_SYMBOL_GPL(uwb_ie_for_each);
223 145
224 146
225/** 147/**
@@ -256,70 +178,6 @@ error_cmd:
256 return result; 178 return result;
257} 179}
258 180
259/**
260 * Determine by IE id if IE is host settable
261 * WUSB 1.0 [8.6.2.8 Table 8.85]
262 *
263 * EXCEPTION:
264 * All but UWB_IE_WLP appears in Table 8.85 from WUSB 1.0. Setting this IE
265 * is required for the WLP substack to perform association with its WSS so
266 * we hope that the WUSB spec will be changed to reflect this.
267 */
268static
269int uwb_rc_ie_is_host_settable(enum uwb_ie element_id)
270{
271 if (element_id == UWB_PCA_AVAILABILITY ||
272 element_id == UWB_BP_SWITCH_IE ||
273 element_id == UWB_MAC_CAPABILITIES_IE ||
274 element_id == UWB_PHY_CAPABILITIES_IE ||
275 element_id == UWB_APP_SPEC_PROBE_IE ||
276 element_id == UWB_IDENTIFICATION_IE ||
277 element_id == UWB_MASTER_KEY_ID_IE ||
278 element_id == UWB_IE_WLP ||
279 element_id == UWB_APP_SPEC_IE)
280 return 1;
281 return 0;
282}
283
284
285/**
286 * Extract Host Settable IEs from IE
287 *
288 * @ie_data: pointer to buffer containing all IEs
289 * @size: size of buffer
290 *
291 * @returns: length of buffer that only includes host settable IEs
292 *
293 * Given a buffer of IEs we move all Host Settable IEs to front of buffer
294 * by overwriting the IEs that are not Host Settable.
295 * Buffer length is adjusted accordingly.
296 */
297static
298ssize_t uwb_rc_parse_host_settable_ie(struct uwb_dev *uwb_dev,
299 void *ie_data, size_t size)
300{
301 size_t new_len = size;
302 struct uwb_ie_hdr *ie_hdr;
303 size_t ie_length;
304 void *itr = ie_data, *top = itr + size;
305
306 while (itr < top) {
307 if (uwb_rc_ie_verify(uwb_dev, ie_data, itr, top) != 0)
308 break;
309 ie_hdr = itr;
310 ie_length = sizeof(*ie_hdr) + ie_hdr->length;
311 if (uwb_rc_ie_is_host_settable(ie_hdr->element_id)) {
312 itr += ie_length;
313 } else {
314 memmove(itr, itr + ie_length, top - (itr + ie_length));
315 new_len -= ie_length;
316 top -= ie_length;
317 }
318 }
319 return new_len;
320}
321
322
323/* Cleanup the whole IE management subsystem */ 181/* Cleanup the whole IE management subsystem */
324void uwb_rc_ie_init(struct uwb_rc *uwb_rc) 182void uwb_rc_ie_init(struct uwb_rc *uwb_rc)
325{ 183{
@@ -328,49 +186,34 @@ void uwb_rc_ie_init(struct uwb_rc *uwb_rc)
328 186
329 187
330/** 188/**
331 * Set up cache for host settable IEs currently being transmitted 189 * uwb_rc_ie_setup - setup a radio controller's IE manager
190 * @uwb_rc: the radio controller.
332 * 191 *
333 * First we just call GET-IE to get the current IEs being transmitted 192 * The current set of IEs are obtained from the hardware with a GET-IE
334 * (or we workaround and pretend we did) and (because the format is 193 * command (since the radio controller is not yet beaconing this will
335 * the same) reuse that as the IE cache (with the command prefix, as 194 * be just the hardware's MAC and PHY Capability IEs).
336 * explained in 'struct uwb_rc').
337 * 195 *
338 * @returns: size of cache created 196 * Returns 0 on success; -ve on an error.
339 */ 197 */
340ssize_t uwb_rc_ie_setup(struct uwb_rc *uwb_rc) 198int uwb_rc_ie_setup(struct uwb_rc *uwb_rc)
341{ 199{
342 struct device *dev = &uwb_rc->uwb_dev.dev; 200 struct uwb_rc_evt_get_ie *ie_info = NULL;
343 ssize_t result; 201 int capacity;
344 size_t capacity; 202
345 struct uwb_rc_evt_get_ie *ie_info; 203 capacity = uwb_rc_get_ie(uwb_rc, &ie_info);
204 if (capacity < 0)
205 return capacity;
346 206
347 d_fnstart(3, dev, "(%p)\n", uwb_rc);
348 mutex_lock(&uwb_rc->ies_mutex); 207 mutex_lock(&uwb_rc->ies_mutex);
349 result = uwb_rc_get_ie(uwb_rc, &ie_info); 208
350 if (result < 0) 209 uwb_rc->ies = (struct uwb_rc_cmd_set_ie *)ie_info;
351 goto error_get_ie;
352 capacity = result;
353 d_printf(5, dev, "Got IEs %zu bytes (%zu long at %p)\n", result,
354 (size_t)le16_to_cpu(ie_info->wIELength), ie_info);
355
356 /* Remove IEs that host should not set. */
357 result = uwb_rc_parse_host_settable_ie(&uwb_rc->uwb_dev,
358 ie_info->IEData, le16_to_cpu(ie_info->wIELength));
359 if (result < 0)
360 goto error_parse;
361 d_printf(5, dev, "purged non-settable IEs to %zu bytes\n", result);
362 uwb_rc->ies = (void *) ie_info;
363 uwb_rc->ies->rccb.bCommandType = UWB_RC_CET_GENERAL; 210 uwb_rc->ies->rccb.bCommandType = UWB_RC_CET_GENERAL;
364 uwb_rc->ies->rccb.wCommand = cpu_to_le16(UWB_RC_CMD_SET_IE); 211 uwb_rc->ies->rccb.wCommand = cpu_to_le16(UWB_RC_CMD_SET_IE);
365 uwb_rc->ies_capacity = capacity; 212 uwb_rc->ies_capacity = capacity;
366 d_printf(5, dev, "IE cache at %p %zu bytes, %zu capacity\n", 213
367 ie_info, result, capacity);
368 result = 0;
369error_parse:
370error_get_ie:
371 mutex_unlock(&uwb_rc->ies_mutex); 214 mutex_unlock(&uwb_rc->ies_mutex);
372 d_fnend(3, dev, "(%p) = %zu\n", uwb_rc, result); 215
373 return result; 216 return 0;
374} 217}
375 218
376 219
@@ -383,26 +226,47 @@ void uwb_rc_ie_release(struct uwb_rc *uwb_rc)
383} 226}
384 227
385 228
386static 229static int uwb_rc_ie_add_one(struct uwb_rc *rc, const struct uwb_ie_hdr *new_ie)
387int __acc_size(struct uwb_dev *uwb_dev, const struct uwb_ie_hdr *ie_hdr,
388 size_t offset, void *_ctx)
389{ 230{
390 size_t *acc_size = _ctx; 231 struct uwb_rc_cmd_set_ie *new_ies;
391 *acc_size += sizeof(*ie_hdr) + ie_hdr->length; 232 void *ptr, *prev_ie;
392 d_printf(6, &uwb_dev->dev, "new acc size %zu\n", *acc_size); 233 struct uwb_ie_hdr *ie;
234 size_t length, new_ie_len, new_capacity, size, prev_size;
235
236 length = le16_to_cpu(rc->ies->wIELength);
237 new_ie_len = sizeof(struct uwb_ie_hdr) + new_ie->length;
238 new_capacity = sizeof(struct uwb_rc_cmd_set_ie) + length + new_ie_len;
239
240 if (new_capacity > rc->ies_capacity) {
241 new_ies = krealloc(rc->ies, new_capacity, GFP_KERNEL);
242 if (!new_ies)
243 return -ENOMEM;
244 rc->ies = new_ies;
245 }
246
247 ptr = rc->ies->IEData;
248 size = length;
249 for (;;) {
250 prev_ie = ptr;
251 prev_size = size;
252 ie = uwb_ie_next(&ptr, &size);
253 if (!ie || ie->element_id > new_ie->element_id)
254 break;
255 }
256
257 memmove(prev_ie + new_ie_len, prev_ie, prev_size);
258 memcpy(prev_ie, new_ie, new_ie_len);
259 rc->ies->wIELength = cpu_to_le16(length + new_ie_len);
260
393 return 0; 261 return 0;
394} 262}
395 263
396
397/** 264/**
398 * Add a new IE to IEs currently being transmitted by device 265 * uwb_rc_ie_add - add new IEs to the radio controller's beacon
399 * 266 * @uwb_rc: the radio controller.
400 * @ies: the buffer containing the new IE or IEs to be added to 267 * @ies: the buffer containing the new IE or IEs to be added to
401 * the device's beacon. The buffer will be verified for 268 * the device's beacon.
402 * consistence (meaning the headers should be right) and 269 * @size: length of all the IEs.
403 * consistent with the buffer size.
404 * @size: size of @ies (in bytes, total buffer size)
405 * @returns: 0 if ok, <0 errno code on error
406 * 270 *
407 * According to WHCI 0.95 [4.13.6] the driver will only receive the RCEB 271 * According to WHCI 0.95 [4.13.6] the driver will only receive the RCEB
408 * after the device sent the first beacon that includes the IEs specified 272 * after the device sent the first beacon that includes the IEs specified
@@ -411,66 +275,40 @@ int __acc_size(struct uwb_dev *uwb_dev, const struct uwb_ie_hdr *ie_hdr,
411 * we start beaconing. 275 * we start beaconing.
412 * 276 *
413 * Setting an IE on the device will overwrite all current IEs in device. So 277 * Setting an IE on the device will overwrite all current IEs in device. So
414 * we take the current IEs being transmitted by the device, append the 278 * we take the current IEs being transmitted by the device, insert the
415 * new one, and call SET IE with all the IEs needed. 279 * new one, and call SET IE with all the IEs needed.
416 * 280 *
417 * The local IE cache will only be updated with the new IE if SET IE 281 * Returns 0 on success; or -ENOMEM.
418 * completed successfully.
419 */ 282 */
420int uwb_rc_ie_add(struct uwb_rc *uwb_rc, 283int uwb_rc_ie_add(struct uwb_rc *uwb_rc,
421 const struct uwb_ie_hdr *ies, size_t size) 284 const struct uwb_ie_hdr *ies, size_t size)
422{ 285{
423 int result = 0; 286 int result = 0;
424 struct device *dev = &uwb_rc->uwb_dev.dev; 287 void *ptr;
425 struct uwb_rc_cmd_set_ie *new_ies; 288 const struct uwb_ie_hdr *ie;
426 size_t ies_size, total_size, acc_size = 0; 289
427
428 if (uwb_rc->ies == NULL)
429 return -ESHUTDOWN;
430 uwb_ie_for_each(&uwb_rc->uwb_dev, __acc_size, &acc_size, ies, size);
431 if (acc_size != size) {
432 dev_err(dev, "BUG: bad IEs, misconstructed headers "
433 "[%zu bytes reported vs %zu calculated]\n",
434 size, acc_size);
435 WARN_ON(1);
436 return -EINVAL;
437 }
438 mutex_lock(&uwb_rc->ies_mutex); 290 mutex_lock(&uwb_rc->ies_mutex);
439 ies_size = le16_to_cpu(uwb_rc->ies->wIELength); 291
440 total_size = sizeof(*uwb_rc->ies) + ies_size; 292 ptr = (void *)ies;
441 if (total_size + size > uwb_rc->ies_capacity) { 293 for (;;) {
442 d_printf(4, dev, "Reallocating IE cache from %p capacity %zu " 294 ie = uwb_ie_next(&ptr, &size);
443 "to capacity %zu\n", uwb_rc->ies, uwb_rc->ies_capacity, 295 if (!ie)
444 total_size + size); 296 break;
445 new_ies = kzalloc(total_size + size, GFP_KERNEL); 297
446 if (new_ies == NULL) { 298 result = uwb_rc_ie_add_one(uwb_rc, ie);
447 dev_err(dev, "No memory for adding new IE\n"); 299 if (result < 0)
448 result = -ENOMEM; 300 break;
449 goto error_alloc;
450 }
451 memcpy(new_ies, uwb_rc->ies, total_size);
452 uwb_rc->ies_capacity = total_size + size;
453 kfree(uwb_rc->ies);
454 uwb_rc->ies = new_ies;
455 d_printf(4, dev, "New IE cache at %p capacity %zu\n",
456 uwb_rc->ies, uwb_rc->ies_capacity);
457 } 301 }
458 memcpy((void *)uwb_rc->ies + total_size, ies, size); 302 if (result >= 0) {
459 uwb_rc->ies->wIELength = cpu_to_le16(ies_size + size); 303 if (size == 0) {
460 if (uwb_rc->beaconing != -1) { 304 if (uwb_rc->beaconing != -1)
461 result = uwb_rc_set_ie(uwb_rc, uwb_rc->ies); 305 result = uwb_rc_set_ie(uwb_rc, uwb_rc->ies);
462 if (result < 0) {
463 dev_err(dev, "Cannot set new IE on device: %d\n",
464 result);
465 uwb_rc->ies->wIELength = cpu_to_le16(ies_size);
466 } else 306 } else
467 result = 0; 307 result = -EINVAL;
468 } 308 }
469 d_printf(4, dev, "IEs now occupy %hu bytes of %zu capacity at %p\n", 309
470 le16_to_cpu(uwb_rc->ies->wIELength), uwb_rc->ies_capacity,
471 uwb_rc->ies);
472error_alloc:
473 mutex_unlock(&uwb_rc->ies_mutex); 310 mutex_unlock(&uwb_rc->ies_mutex);
311
474 return result; 312 return result;
475} 313}
476EXPORT_SYMBOL_GPL(uwb_rc_ie_add); 314EXPORT_SYMBOL_GPL(uwb_rc_ie_add);
@@ -489,53 +327,52 @@ EXPORT_SYMBOL_GPL(uwb_rc_ie_add);
489 * beacon. We don't reallocate, we just mark the size smaller. 327 * beacon. We don't reallocate, we just mark the size smaller.
490 */ 328 */
491static 329static
492int uwb_rc_ie_cache_rm(struct uwb_rc *uwb_rc, enum uwb_ie to_remove) 330void uwb_rc_ie_cache_rm(struct uwb_rc *uwb_rc, enum uwb_ie to_remove)
493{ 331{
494 struct uwb_ie_hdr *ie_hdr; 332 struct uwb_ie_hdr *ie;
495 size_t new_len = le16_to_cpu(uwb_rc->ies->wIELength); 333 size_t len = le16_to_cpu(uwb_rc->ies->wIELength);
496 void *itr = uwb_rc->ies->IEData; 334 void *ptr;
497 void *top = itr + new_len; 335 size_t size;
498 336
499 while (itr < top) { 337 ptr = uwb_rc->ies->IEData;
500 ie_hdr = itr; 338 size = len;
501 if (ie_hdr->element_id != to_remove) { 339 for (;;) {
502 itr += sizeof(*ie_hdr) + ie_hdr->length; 340 ie = uwb_ie_next(&ptr, &size);
503 } else { 341 if (!ie)
504 int ie_length; 342 break;
505 ie_length = sizeof(*ie_hdr) + ie_hdr->length; 343 if (ie->element_id == to_remove) {
506 if (top - itr != ie_length) 344 len -= sizeof(struct uwb_ie_hdr) + ie->length;
507 memmove(itr, itr + ie_length, top - itr + ie_length); 345 memmove(ie, ptr, size);
508 top -= ie_length; 346 ptr = ie;
509 new_len -= ie_length;
510 } 347 }
511 } 348 }
512 uwb_rc->ies->wIELength = cpu_to_le16(new_len); 349 uwb_rc->ies->wIELength = cpu_to_le16(len);
513 return 0;
514} 350}
515 351
516 352
517/** 353/**
518 * Remove an IE currently being transmitted by device 354 * uwb_rc_ie_rm - remove an IE from the radio controller's beacon
355 * @uwb_rc: the radio controller.
356 * @element_id: the element ID of the IE to remove.
519 * 357 *
520 * @element_id: id of IE to be removed from device's beacon 358 * Only IEs previously added with uwb_rc_ie_add() may be removed.
359 *
360 * Returns 0 on success; or -ve the SET-IE command to the radio
361 * controller failed.
521 */ 362 */
522int uwb_rc_ie_rm(struct uwb_rc *uwb_rc, enum uwb_ie element_id) 363int uwb_rc_ie_rm(struct uwb_rc *uwb_rc, enum uwb_ie element_id)
523{ 364{
524 struct device *dev = &uwb_rc->uwb_dev.dev; 365 int result = 0;
525 int result;
526 366
527 if (uwb_rc->ies == NULL)
528 return -ESHUTDOWN;
529 mutex_lock(&uwb_rc->ies_mutex); 367 mutex_lock(&uwb_rc->ies_mutex);
530 result = uwb_rc_ie_cache_rm(uwb_rc, element_id); 368
531 if (result < 0) 369 uwb_rc_ie_cache_rm(uwb_rc, element_id);
532 dev_err(dev, "Cannot remove IE from cache.\n"); 370
533 if (uwb_rc->beaconing != -1) { 371 if (uwb_rc->beaconing != -1)
534 result = uwb_rc_set_ie(uwb_rc, uwb_rc->ies); 372 result = uwb_rc_set_ie(uwb_rc, uwb_rc->ies);
535 if (result < 0) 373
536 dev_err(dev, "Cannot set new IE on device.\n");
537 }
538 mutex_unlock(&uwb_rc->ies_mutex); 374 mutex_unlock(&uwb_rc->ies_mutex);
375
539 return result; 376 return result;
540} 377}
541EXPORT_SYMBOL_GPL(uwb_rc_ie_rm); 378EXPORT_SYMBOL_GPL(uwb_rc_ie_rm);
diff --git a/drivers/uwb/lc-rc.c b/drivers/uwb/lc-rc.c
index ee5772f00d42..9cf21e6bb624 100644
--- a/drivers/uwb/lc-rc.c
+++ b/drivers/uwb/lc-rc.c
@@ -36,8 +36,6 @@
36#include <linux/etherdevice.h> 36#include <linux/etherdevice.h>
37#include <linux/usb.h> 37#include <linux/usb.h>
38 38
39#define D_LOCAL 1
40#include <linux/uwb/debug.h>
41#include "uwb-internal.h" 39#include "uwb-internal.h"
42 40
43static int uwb_rc_index_match(struct device *dev, void *data) 41static int uwb_rc_index_match(struct device *dev, void *data)
@@ -81,9 +79,7 @@ static void uwb_rc_sys_release(struct device *dev)
81 struct uwb_dev *uwb_dev = container_of(dev, struct uwb_dev, dev); 79 struct uwb_dev *uwb_dev = container_of(dev, struct uwb_dev, dev);
82 struct uwb_rc *rc = container_of(uwb_dev, struct uwb_rc, uwb_dev); 80 struct uwb_rc *rc = container_of(uwb_dev, struct uwb_rc, uwb_dev);
83 81
84 uwb_rc_neh_destroy(rc);
85 uwb_rc_ie_release(rc); 82 uwb_rc_ie_release(rc);
86 d_printf(1, dev, "freed uwb_rc %p\n", rc);
87 kfree(rc); 83 kfree(rc);
88} 84}
89 85
@@ -100,6 +96,8 @@ void uwb_rc_init(struct uwb_rc *rc)
100 rc->scan_type = UWB_SCAN_DISABLED; 96 rc->scan_type = UWB_SCAN_DISABLED;
101 INIT_LIST_HEAD(&rc->notifs_chain.list); 97 INIT_LIST_HEAD(&rc->notifs_chain.list);
102 mutex_init(&rc->notifs_chain.mutex); 98 mutex_init(&rc->notifs_chain.mutex);
99 INIT_LIST_HEAD(&rc->uwb_beca.list);
100 mutex_init(&rc->uwb_beca.mutex);
103 uwb_drp_avail_init(rc); 101 uwb_drp_avail_init(rc);
104 uwb_rc_ie_init(rc); 102 uwb_rc_ie_init(rc);
105 uwb_rsv_init(rc); 103 uwb_rsv_init(rc);
@@ -191,9 +189,9 @@ static int uwb_rc_setup(struct uwb_rc *rc)
191 int result; 189 int result;
192 struct device *dev = &rc->uwb_dev.dev; 190 struct device *dev = &rc->uwb_dev.dev;
193 191
194 result = uwb_rc_reset(rc); 192 result = uwb_radio_setup(rc);
195 if (result < 0) { 193 if (result < 0) {
196 dev_err(dev, "cannot reset UWB radio: %d\n", result); 194 dev_err(dev, "cannot setup UWB radio: %d\n", result);
197 goto error; 195 goto error;
198 } 196 }
199 result = uwb_rc_mac_addr_setup(rc); 197 result = uwb_rc_mac_addr_setup(rc);
@@ -250,6 +248,12 @@ int uwb_rc_add(struct uwb_rc *rc, struct device *parent_dev, void *priv)
250 248
251 rc->priv = priv; 249 rc->priv = priv;
252 250
251 init_waitqueue_head(&rc->uwbd.wq);
252 INIT_LIST_HEAD(&rc->uwbd.event_list);
253 spin_lock_init(&rc->uwbd.event_list_lock);
254
255 uwbd_start(rc);
256
253 result = rc->start(rc); 257 result = rc->start(rc);
254 if (result < 0) 258 if (result < 0)
255 goto error_rc_start; 259 goto error_rc_start;
@@ -284,7 +288,7 @@ error_sys_add:
284error_dev_add: 288error_dev_add:
285error_rc_setup: 289error_rc_setup:
286 rc->stop(rc); 290 rc->stop(rc);
287 uwbd_flush(rc); 291 uwbd_stop(rc);
288error_rc_start: 292error_rc_start:
289 return result; 293 return result;
290} 294}
@@ -306,25 +310,24 @@ void uwb_rc_rm(struct uwb_rc *rc)
306 rc->ready = 0; 310 rc->ready = 0;
307 311
308 uwb_dbg_del_rc(rc); 312 uwb_dbg_del_rc(rc);
309 uwb_rsv_cleanup(rc); 313 uwb_rsv_remove_all(rc);
310 uwb_rc_ie_rm(rc, UWB_IDENTIFICATION_IE); 314 uwb_radio_shutdown(rc);
311 if (rc->beaconing >= 0)
312 uwb_rc_beacon(rc, -1, 0);
313 if (rc->scan_type != UWB_SCAN_DISABLED)
314 uwb_rc_scan(rc, rc->scanning, UWB_SCAN_DISABLED, 0);
315 uwb_rc_reset(rc);
316 315
317 rc->stop(rc); 316 rc->stop(rc);
318 uwbd_flush(rc); 317
318 uwbd_stop(rc);
319 uwb_rc_neh_destroy(rc);
319 320
320 uwb_dev_lock(&rc->uwb_dev); 321 uwb_dev_lock(&rc->uwb_dev);
321 rc->priv = NULL; 322 rc->priv = NULL;
322 rc->cmd = NULL; 323 rc->cmd = NULL;
323 uwb_dev_unlock(&rc->uwb_dev); 324 uwb_dev_unlock(&rc->uwb_dev);
324 mutex_lock(&uwb_beca.mutex); 325 mutex_lock(&rc->uwb_beca.mutex);
325 uwb_dev_for_each(rc, uwb_dev_offair_helper, NULL); 326 uwb_dev_for_each(rc, uwb_dev_offair_helper, NULL);
326 __uwb_rc_sys_rm(rc); 327 __uwb_rc_sys_rm(rc);
327 mutex_unlock(&uwb_beca.mutex); 328 mutex_unlock(&rc->uwb_beca.mutex);
329 uwb_rsv_cleanup(rc);
330 uwb_beca_release(rc);
328 uwb_dev_rm(&rc->uwb_dev); 331 uwb_dev_rm(&rc->uwb_dev);
329} 332}
330EXPORT_SYMBOL_GPL(uwb_rc_rm); 333EXPORT_SYMBOL_GPL(uwb_rc_rm);
@@ -468,28 +471,3 @@ void uwb_rc_put(struct uwb_rc *rc)
468 __uwb_rc_put(rc); 471 __uwb_rc_put(rc);
469} 472}
470EXPORT_SYMBOL_GPL(uwb_rc_put); 473EXPORT_SYMBOL_GPL(uwb_rc_put);
471
472/*
473 *
474 *
475 */
476ssize_t uwb_rc_print_IEs(struct uwb_rc *uwb_rc, char *buf, size_t size)
477{
478 ssize_t result;
479 struct uwb_rc_evt_get_ie *ie_info;
480 struct uwb_buf_ctx ctx;
481
482 result = uwb_rc_get_ie(uwb_rc, &ie_info);
483 if (result < 0)
484 goto error_get_ie;
485 ctx.buf = buf;
486 ctx.size = size;
487 ctx.bytes = 0;
488 uwb_ie_for_each(&uwb_rc->uwb_dev, uwb_ie_dump_hex, &ctx,
489 ie_info->IEData, result - sizeof(*ie_info));
490 result = ctx.bytes;
491 kfree(ie_info);
492error_get_ie:
493 return result;
494}
495
diff --git a/drivers/uwb/neh.c b/drivers/uwb/neh.c
index 9b4eb64327ac..48b4ece1a627 100644
--- a/drivers/uwb/neh.c
+++ b/drivers/uwb/neh.c
@@ -254,7 +254,6 @@ error_kzalloc:
254 254
255static void __uwb_rc_neh_rm(struct uwb_rc *rc, struct uwb_rc_neh *neh) 255static void __uwb_rc_neh_rm(struct uwb_rc *rc, struct uwb_rc_neh *neh)
256{ 256{
257 del_timer(&neh->timer);
258 __uwb_rc_ctx_put(rc, neh); 257 __uwb_rc_ctx_put(rc, neh);
259 list_del(&neh->list_node); 258 list_del(&neh->list_node);
260} 259}
@@ -275,6 +274,7 @@ void uwb_rc_neh_rm(struct uwb_rc *rc, struct uwb_rc_neh *neh)
275 __uwb_rc_neh_rm(rc, neh); 274 __uwb_rc_neh_rm(rc, neh);
276 spin_unlock_irqrestore(&rc->neh_lock, flags); 275 spin_unlock_irqrestore(&rc->neh_lock, flags);
277 276
277 del_timer_sync(&neh->timer);
278 uwb_rc_neh_put(neh); 278 uwb_rc_neh_put(neh);
279} 279}
280 280
@@ -438,9 +438,10 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size
438 rceb->bEventContext, size); 438 rceb->bEventContext, size);
439 } else { 439 } else {
440 neh = uwb_rc_neh_lookup(rc, rceb); 440 neh = uwb_rc_neh_lookup(rc, rceb);
441 if (neh) 441 if (neh) {
442 del_timer_sync(&neh->timer);
442 uwb_rc_neh_cb(neh, rceb, size); 443 uwb_rc_neh_cb(neh, rceb, size);
443 else 444 } else
444 dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n", 445 dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n",
445 rceb->bEventType, le16_to_cpu(rceb->wEvent), 446 rceb->bEventType, le16_to_cpu(rceb->wEvent),
446 rceb->bEventContext, size); 447 rceb->bEventContext, size);
@@ -562,16 +563,22 @@ EXPORT_SYMBOL_GPL(uwb_rc_neh_grok);
562 */ 563 */
563void uwb_rc_neh_error(struct uwb_rc *rc, int error) 564void uwb_rc_neh_error(struct uwb_rc *rc, int error)
564{ 565{
565 struct uwb_rc_neh *neh, *next; 566 struct uwb_rc_neh *neh;
566 unsigned long flags; 567 unsigned long flags;
567 568
568 BUG_ON(error >= 0); 569 for (;;) {
569 spin_lock_irqsave(&rc->neh_lock, flags); 570 spin_lock_irqsave(&rc->neh_lock, flags);
570 list_for_each_entry_safe(neh, next, &rc->neh_list, list_node) { 571 if (list_empty(&rc->neh_list)) {
572 spin_unlock_irqrestore(&rc->neh_lock, flags);
573 break;
574 }
575 neh = list_first_entry(&rc->neh_list, struct uwb_rc_neh, list_node);
571 __uwb_rc_neh_rm(rc, neh); 576 __uwb_rc_neh_rm(rc, neh);
577 spin_unlock_irqrestore(&rc->neh_lock, flags);
578
579 del_timer_sync(&neh->timer);
572 uwb_rc_neh_cb(neh, NULL, error); 580 uwb_rc_neh_cb(neh, NULL, error);
573 } 581 }
574 spin_unlock_irqrestore(&rc->neh_lock, flags);
575} 582}
576EXPORT_SYMBOL_GPL(uwb_rc_neh_error); 583EXPORT_SYMBOL_GPL(uwb_rc_neh_error);
577 584
@@ -583,10 +590,14 @@ static void uwb_rc_neh_timer(unsigned long arg)
583 unsigned long flags; 590 unsigned long flags;
584 591
585 spin_lock_irqsave(&rc->neh_lock, flags); 592 spin_lock_irqsave(&rc->neh_lock, flags);
586 __uwb_rc_neh_rm(rc, neh); 593 if (neh->context)
594 __uwb_rc_neh_rm(rc, neh);
595 else
596 neh = NULL;
587 spin_unlock_irqrestore(&rc->neh_lock, flags); 597 spin_unlock_irqrestore(&rc->neh_lock, flags);
588 598
589 uwb_rc_neh_cb(neh, NULL, -ETIMEDOUT); 599 if (neh)
600 uwb_rc_neh_cb(neh, NULL, -ETIMEDOUT);
590} 601}
591 602
592/** Initializes the @rc's neh subsystem 603/** Initializes the @rc's neh subsystem
@@ -605,12 +616,19 @@ void uwb_rc_neh_create(struct uwb_rc *rc)
605void uwb_rc_neh_destroy(struct uwb_rc *rc) 616void uwb_rc_neh_destroy(struct uwb_rc *rc)
606{ 617{
607 unsigned long flags; 618 unsigned long flags;
608 struct uwb_rc_neh *neh, *next; 619 struct uwb_rc_neh *neh;
609 620
610 spin_lock_irqsave(&rc->neh_lock, flags); 621 for (;;) {
611 list_for_each_entry_safe(neh, next, &rc->neh_list, list_node) { 622 spin_lock_irqsave(&rc->neh_lock, flags);
623 if (list_empty(&rc->neh_list)) {
624 spin_unlock_irqrestore(&rc->neh_lock, flags);
625 break;
626 }
627 neh = list_first_entry(&rc->neh_list, struct uwb_rc_neh, list_node);
612 __uwb_rc_neh_rm(rc, neh); 628 __uwb_rc_neh_rm(rc, neh);
629 spin_unlock_irqrestore(&rc->neh_lock, flags);
630
631 del_timer_sync(&neh->timer);
613 uwb_rc_neh_put(neh); 632 uwb_rc_neh_put(neh);
614 } 633 }
615 spin_unlock_irqrestore(&rc->neh_lock, flags);
616} 634}
diff --git a/drivers/uwb/pal.c b/drivers/uwb/pal.c
index 1afb38eacb9a..99a19c199095 100644
--- a/drivers/uwb/pal.c
+++ b/drivers/uwb/pal.c
@@ -16,6 +16,7 @@
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/debugfs.h>
19#include <linux/uwb.h> 20#include <linux/uwb.h>
20 21
21#include "uwb-internal.h" 22#include "uwb-internal.h"
@@ -32,13 +33,13 @@ EXPORT_SYMBOL_GPL(uwb_pal_init);
32 33
33/** 34/**
34 * uwb_pal_register - register a UWB PAL 35 * uwb_pal_register - register a UWB PAL
35 * @rc: the radio controller the PAL will be using
36 * @pal: the PAL 36 * @pal: the PAL
37 * 37 *
38 * The PAL must be initialized with uwb_pal_init(). 38 * The PAL must be initialized with uwb_pal_init().
39 */ 39 */
40int uwb_pal_register(struct uwb_rc *rc, struct uwb_pal *pal) 40int uwb_pal_register(struct uwb_pal *pal)
41{ 41{
42 struct uwb_rc *rc = pal->rc;
42 int ret; 43 int ret;
43 44
44 if (pal->device) { 45 if (pal->device) {
@@ -54,9 +55,11 @@ int uwb_pal_register(struct uwb_rc *rc, struct uwb_pal *pal)
54 } 55 }
55 } 56 }
56 57
57 spin_lock(&rc->pal_lock); 58 pal->debugfs_dir = uwb_dbg_create_pal_dir(pal);
59
60 mutex_lock(&rc->uwb_dev.mutex);
58 list_add(&pal->node, &rc->pals); 61 list_add(&pal->node, &rc->pals);
59 spin_unlock(&rc->pal_lock); 62 mutex_unlock(&rc->uwb_dev.mutex);
60 63
61 return 0; 64 return 0;
62} 65}
@@ -64,14 +67,19 @@ EXPORT_SYMBOL_GPL(uwb_pal_register);
64 67
65/** 68/**
66 * uwb_pal_register - unregister a UWB PAL 69 * uwb_pal_register - unregister a UWB PAL
67 * @rc: the radio controller the PAL was using
68 * @pal: the PAL 70 * @pal: the PAL
69 */ 71 */
70void uwb_pal_unregister(struct uwb_rc *rc, struct uwb_pal *pal) 72void uwb_pal_unregister(struct uwb_pal *pal)
71{ 73{
72 spin_lock(&rc->pal_lock); 74 struct uwb_rc *rc = pal->rc;
75
76 uwb_radio_stop(pal);
77
78 mutex_lock(&rc->uwb_dev.mutex);
73 list_del(&pal->node); 79 list_del(&pal->node);
74 spin_unlock(&rc->pal_lock); 80 mutex_unlock(&rc->uwb_dev.mutex);
81
82 debugfs_remove(pal->debugfs_dir);
75 83
76 if (pal->device) { 84 if (pal->device) {
77 sysfs_remove_link(&rc->uwb_dev.dev.kobj, pal->name); 85 sysfs_remove_link(&rc->uwb_dev.dev.kobj, pal->name);
@@ -86,6 +94,5 @@ EXPORT_SYMBOL_GPL(uwb_pal_unregister);
86 */ 94 */
87void uwb_rc_pal_init(struct uwb_rc *rc) 95void uwb_rc_pal_init(struct uwb_rc *rc)
88{ 96{
89 spin_lock_init(&rc->pal_lock);
90 INIT_LIST_HEAD(&rc->pals); 97 INIT_LIST_HEAD(&rc->pals);
91} 98}
diff --git a/drivers/uwb/radio.c b/drivers/uwb/radio.c
new file mode 100644
index 000000000000..f0d55495f5e9
--- /dev/null
+++ b/drivers/uwb/radio.c
@@ -0,0 +1,202 @@
1/*
2 * UWB radio (channel) management.
3 *
4 * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#include <linux/kernel.h>
19#include <linux/uwb.h>
20
21#include "uwb-internal.h"
22
23
24static int uwb_radio_select_channel(struct uwb_rc *rc)
25{
26 /*
27 * Default to channel 9 (BG1, TFC1) unless the user has
28 * selected a specific channel or there are no active PALs.
29 */
30 if (rc->active_pals == 0)
31 return -1;
32 if (rc->beaconing_forced)
33 return rc->beaconing_forced;
34 return 9;
35}
36
37
38/*
39 * Notify all active PALs that the channel has changed.
40 */
41static void uwb_radio_channel_changed(struct uwb_rc *rc, int channel)
42{
43 struct uwb_pal *pal;
44
45 list_for_each_entry(pal, &rc->pals, node) {
46 if (pal->channel && channel != pal->channel) {
47 pal->channel = channel;
48 if (pal->channel_changed)
49 pal->channel_changed(pal, pal->channel);
50 }
51 }
52}
53
54/*
55 * Change to a new channel and notify any active PALs of the new
56 * channel.
57 *
58 * When stopping the radio, PALs need to be notified first so they can
59 * terminate any active reservations.
60 */
61static int uwb_radio_change_channel(struct uwb_rc *rc, int channel)
62{
63 int ret = 0;
64
65 if (channel == -1)
66 uwb_radio_channel_changed(rc, channel);
67
68 if (channel != rc->beaconing) {
69 if (rc->beaconing != -1 && channel != -1) {
70 /*
71 * FIXME: should signal the channel change
72 * with a Channel Change IE.
73 */
74 ret = uwb_radio_change_channel(rc, -1);
75 if (ret < 0)
76 return ret;
77 }
78 ret = uwb_rc_beacon(rc, channel, 0);
79 }
80
81 if (channel != -1)
82 uwb_radio_channel_changed(rc, rc->beaconing);
83
84 return ret;
85}
86
87/**
88 * uwb_radio_start - request that the radio be started
89 * @pal: the PAL making the request.
90 *
91 * If the radio is not already active, aa suitable channel is selected
92 * and beacons are started.
93 */
94int uwb_radio_start(struct uwb_pal *pal)
95{
96 struct uwb_rc *rc = pal->rc;
97 int ret = 0;
98
99 mutex_lock(&rc->uwb_dev.mutex);
100
101 if (!pal->channel) {
102 pal->channel = -1;
103 rc->active_pals++;
104 ret = uwb_radio_change_channel(rc, uwb_radio_select_channel(rc));
105 }
106
107 mutex_unlock(&rc->uwb_dev.mutex);
108 return ret;
109}
110EXPORT_SYMBOL_GPL(uwb_radio_start);
111
112/**
113 * uwb_radio_stop - request tha the radio be stopped.
114 * @pal: the PAL making the request.
115 *
116 * Stops the radio if no other PAL is making use of it.
117 */
118void uwb_radio_stop(struct uwb_pal *pal)
119{
120 struct uwb_rc *rc = pal->rc;
121
122 mutex_lock(&rc->uwb_dev.mutex);
123
124 if (pal->channel) {
125 rc->active_pals--;
126 uwb_radio_change_channel(rc, uwb_radio_select_channel(rc));
127 pal->channel = 0;
128 }
129
130 mutex_unlock(&rc->uwb_dev.mutex);
131}
132EXPORT_SYMBOL_GPL(uwb_radio_stop);
133
134/*
135 * uwb_radio_force_channel - force a specific channel to be used
136 * @rc: the radio controller.
137 * @channel: the channel to use; -1 to force the radio to stop; 0 to
138 * use the default channel selection algorithm.
139 */
140int uwb_radio_force_channel(struct uwb_rc *rc, int channel)
141{
142 int ret = 0;
143
144 mutex_lock(&rc->uwb_dev.mutex);
145
146 rc->beaconing_forced = channel;
147 ret = uwb_radio_change_channel(rc, uwb_radio_select_channel(rc));
148
149 mutex_unlock(&rc->uwb_dev.mutex);
150 return ret;
151}
152
153/*
154 * uwb_radio_setup - setup the radio manager
155 * @rc: the radio controller.
156 *
157 * The radio controller is reset to ensure it's in a known state
158 * before it's used.
159 */
160int uwb_radio_setup(struct uwb_rc *rc)
161{
162 return uwb_rc_reset(rc);
163}
164
165/*
166 * uwb_radio_reset_state - reset any radio manager state
167 * @rc: the radio controller.
168 *
169 * All internal radio manager state is reset to values corresponding
170 * to a reset radio controller.
171 */
172void uwb_radio_reset_state(struct uwb_rc *rc)
173{
174 struct uwb_pal *pal;
175
176 mutex_lock(&rc->uwb_dev.mutex);
177
178 list_for_each_entry(pal, &rc->pals, node) {
179 if (pal->channel) {
180 pal->channel = -1;
181 if (pal->channel_changed)
182 pal->channel_changed(pal, -1);
183 }
184 }
185
186 rc->beaconing = -1;
187 rc->scanning = -1;
188
189 mutex_unlock(&rc->uwb_dev.mutex);
190}
191
192/*
193 * uwb_radio_shutdown - shutdown the radio manager
194 * @rc: the radio controller.
195 *
196 * The radio controller is reset.
197 */
198void uwb_radio_shutdown(struct uwb_rc *rc)
199{
200 uwb_radio_reset_state(rc);
201 uwb_rc_reset(rc);
202}
diff --git a/drivers/uwb/reset.c b/drivers/uwb/reset.c
index 8de856fa7958..ce8283cc8098 100644
--- a/drivers/uwb/reset.c
+++ b/drivers/uwb/reset.c
@@ -323,17 +323,16 @@ int uwbd_msg_handle_reset(struct uwb_event *evt)
323 struct uwb_rc *rc = evt->rc; 323 struct uwb_rc *rc = evt->rc;
324 int ret; 324 int ret;
325 325
326 /* Need to prevent the RC hardware module going away while in
327 the rc->reset() call. */
328 if (!try_module_get(rc->owner))
329 return 0;
330
331 dev_info(&rc->uwb_dev.dev, "resetting radio controller\n"); 326 dev_info(&rc->uwb_dev.dev, "resetting radio controller\n");
332 ret = rc->reset(rc); 327 ret = rc->reset(rc);
333 if (ret) 328 if (ret) {
334 dev_err(&rc->uwb_dev.dev, "failed to reset hardware: %d\n", ret); 329 dev_err(&rc->uwb_dev.dev, "failed to reset hardware: %d\n", ret);
335 330 goto error;
336 module_put(rc->owner); 331 }
332 return 0;
333error:
334 /* Nothing can be done except try the reset again. */
335 uwb_rc_reset_all(rc);
337 return ret; 336 return ret;
338} 337}
339 338
@@ -360,3 +359,33 @@ void uwb_rc_reset_all(struct uwb_rc *rc)
360 uwbd_event_queue(evt); 359 uwbd_event_queue(evt);
361} 360}
362EXPORT_SYMBOL_GPL(uwb_rc_reset_all); 361EXPORT_SYMBOL_GPL(uwb_rc_reset_all);
362
363void uwb_rc_pre_reset(struct uwb_rc *rc)
364{
365 rc->stop(rc);
366 uwbd_flush(rc);
367
368 uwb_radio_reset_state(rc);
369 uwb_rsv_remove_all(rc);
370}
371EXPORT_SYMBOL_GPL(uwb_rc_pre_reset);
372
373void uwb_rc_post_reset(struct uwb_rc *rc)
374{
375 int ret;
376
377 ret = rc->start(rc);
378 if (ret)
379 goto error;
380 ret = uwb_rc_mac_addr_set(rc, &rc->uwb_dev.mac_addr);
381 if (ret)
382 goto error;
383 ret = uwb_rc_dev_addr_set(rc, &rc->uwb_dev.dev_addr);
384 if (ret)
385 goto error;
386 return;
387error:
388 /* Nothing can be done except try the reset again. */
389 uwb_rc_reset_all(rc);
390}
391EXPORT_SYMBOL_GPL(uwb_rc_post_reset);
diff --git a/drivers/uwb/rsv.c b/drivers/uwb/rsv.c
index bae16204576d..1cd84f927540 100644
--- a/drivers/uwb/rsv.c
+++ b/drivers/uwb/rsv.c
@@ -15,7 +15,6 @@
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18#include <linux/version.h>
19#include <linux/kernel.h> 18#include <linux/kernel.h>
20#include <linux/uwb.h> 19#include <linux/uwb.h>
21 20
@@ -82,6 +81,23 @@ static void uwb_rsv_dump(struct uwb_rsv *rsv)
82 dev_dbg(dev, "rsv %s -> %s: %s\n", owner, target, uwb_rsv_state_str(rsv->state)); 81 dev_dbg(dev, "rsv %s -> %s: %s\n", owner, target, uwb_rsv_state_str(rsv->state));
83} 82}
84 83
84static void uwb_rsv_release(struct kref *kref)
85{
86 struct uwb_rsv *rsv = container_of(kref, struct uwb_rsv, kref);
87
88 kfree(rsv);
89}
90
91static void uwb_rsv_get(struct uwb_rsv *rsv)
92{
93 kref_get(&rsv->kref);
94}
95
96static void uwb_rsv_put(struct uwb_rsv *rsv)
97{
98 kref_put(&rsv->kref, uwb_rsv_release);
99}
100
85/* 101/*
86 * Get a free stream index for a reservation. 102 * Get a free stream index for a reservation.
87 * 103 *
@@ -285,7 +301,8 @@ void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state)
285 switch (new_state) { 301 switch (new_state) {
286 case UWB_RSV_STATE_NONE: 302 case UWB_RSV_STATE_NONE:
287 uwb_drp_avail_release(rsv->rc, &rsv->mas); 303 uwb_drp_avail_release(rsv->rc, &rsv->mas);
288 uwb_rsv_put_stream(rsv); 304 if (uwb_rsv_is_owner(rsv))
305 uwb_rsv_put_stream(rsv);
289 uwb_rsv_state_update(rsv, UWB_RSV_STATE_NONE); 306 uwb_rsv_state_update(rsv, UWB_RSV_STATE_NONE);
290 uwb_rsv_callback(rsv); 307 uwb_rsv_callback(rsv);
291 break; 308 break;
@@ -324,6 +341,7 @@ static struct uwb_rsv *uwb_rsv_alloc(struct uwb_rc *rc)
324 341
325 INIT_LIST_HEAD(&rsv->rc_node); 342 INIT_LIST_HEAD(&rsv->rc_node);
326 INIT_LIST_HEAD(&rsv->pal_node); 343 INIT_LIST_HEAD(&rsv->pal_node);
344 kref_init(&rsv->kref);
327 init_timer(&rsv->timer); 345 init_timer(&rsv->timer);
328 rsv->timer.function = uwb_rsv_timer; 346 rsv->timer.function = uwb_rsv_timer;
329 rsv->timer.data = (unsigned long)rsv; 347 rsv->timer.data = (unsigned long)rsv;
@@ -333,14 +351,6 @@ static struct uwb_rsv *uwb_rsv_alloc(struct uwb_rc *rc)
333 return rsv; 351 return rsv;
334} 352}
335 353
336static void uwb_rsv_free(struct uwb_rsv *rsv)
337{
338 uwb_dev_put(rsv->owner);
339 if (rsv->target.type == UWB_RSV_TARGET_DEV)
340 uwb_dev_put(rsv->target.dev);
341 kfree(rsv);
342}
343
344/** 354/**
345 * uwb_rsv_create - allocate and initialize a UWB reservation structure 355 * uwb_rsv_create - allocate and initialize a UWB reservation structure
346 * @rc: the radio controller 356 * @rc: the radio controller
@@ -374,23 +384,23 @@ void uwb_rsv_remove(struct uwb_rsv *rsv)
374 if (rsv->state != UWB_RSV_STATE_NONE) 384 if (rsv->state != UWB_RSV_STATE_NONE)
375 uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE); 385 uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE);
376 del_timer_sync(&rsv->timer); 386 del_timer_sync(&rsv->timer);
377 list_del(&rsv->rc_node); 387 uwb_dev_put(rsv->owner);
378 uwb_rsv_free(rsv); 388 if (rsv->target.type == UWB_RSV_TARGET_DEV)
389 uwb_dev_put(rsv->target.dev);
390
391 list_del_init(&rsv->rc_node);
392 uwb_rsv_put(rsv);
379} 393}
380 394
381/** 395/**
382 * uwb_rsv_destroy - free a UWB reservation structure 396 * uwb_rsv_destroy - free a UWB reservation structure
383 * @rsv: the reservation to free 397 * @rsv: the reservation to free
384 * 398 *
385 * The reservation will be terminated if it is pending or established. 399 * The reservation must already be terminated.
386 */ 400 */
387void uwb_rsv_destroy(struct uwb_rsv *rsv) 401void uwb_rsv_destroy(struct uwb_rsv *rsv)
388{ 402{
389 struct uwb_rc *rc = rsv->rc; 403 uwb_rsv_put(rsv);
390
391 mutex_lock(&rc->rsvs_mutex);
392 uwb_rsv_remove(rsv);
393 mutex_unlock(&rc->rsvs_mutex);
394} 404}
395EXPORT_SYMBOL_GPL(uwb_rsv_destroy); 405EXPORT_SYMBOL_GPL(uwb_rsv_destroy);
396 406
@@ -422,6 +432,7 @@ int uwb_rsv_establish(struct uwb_rsv *rsv)
422 goto out; 432 goto out;
423 } 433 }
424 434
435 uwb_rsv_get(rsv);
425 list_add_tail(&rsv->rc_node, &rc->reservations); 436 list_add_tail(&rsv->rc_node, &rc->reservations);
426 rsv->owner = &rc->uwb_dev; 437 rsv->owner = &rc->uwb_dev;
427 uwb_dev_get(rsv->owner); 438 uwb_dev_get(rsv->owner);
@@ -477,9 +488,14 @@ EXPORT_SYMBOL_GPL(uwb_rsv_terminate);
477 * 488 *
478 * Reservation requests from peers are denied unless a PAL accepts it 489 * Reservation requests from peers are denied unless a PAL accepts it
479 * by calling this function. 490 * by calling this function.
491 *
492 * The PAL call uwb_rsv_destroy() for all accepted reservations before
493 * calling uwb_pal_unregister().
480 */ 494 */
481void uwb_rsv_accept(struct uwb_rsv *rsv, uwb_rsv_cb_f cb, void *pal_priv) 495void uwb_rsv_accept(struct uwb_rsv *rsv, uwb_rsv_cb_f cb, void *pal_priv)
482{ 496{
497 uwb_rsv_get(rsv);
498
483 rsv->callback = cb; 499 rsv->callback = cb;
484 rsv->pal_priv = pal_priv; 500 rsv->pal_priv = pal_priv;
485 rsv->state = UWB_RSV_STATE_T_ACCEPTED; 501 rsv->state = UWB_RSV_STATE_T_ACCEPTED;
@@ -532,7 +548,6 @@ static struct uwb_rsv *uwb_rsv_new_target(struct uwb_rc *rc,
532 rsv->target.dev = &rc->uwb_dev; 548 rsv->target.dev = &rc->uwb_dev;
533 rsv->type = uwb_ie_drp_type(drp_ie); 549 rsv->type = uwb_ie_drp_type(drp_ie);
534 rsv->stream = uwb_ie_drp_stream_index(drp_ie); 550 rsv->stream = uwb_ie_drp_stream_index(drp_ie);
535 set_bit(rsv->stream, rsv->owner->streams);
536 uwb_drp_ie_to_bm(&rsv->mas, drp_ie); 551 uwb_drp_ie_to_bm(&rsv->mas, drp_ie);
537 552
538 /* 553 /*
@@ -540,14 +555,14 @@ static struct uwb_rsv *uwb_rsv_new_target(struct uwb_rc *rc,
540 * deny the request. 555 * deny the request.
541 */ 556 */
542 rsv->state = UWB_RSV_STATE_T_DENIED; 557 rsv->state = UWB_RSV_STATE_T_DENIED;
543 spin_lock(&rc->pal_lock); 558 mutex_lock(&rc->uwb_dev.mutex);
544 list_for_each_entry(pal, &rc->pals, node) { 559 list_for_each_entry(pal, &rc->pals, node) {
545 if (pal->new_rsv) 560 if (pal->new_rsv)
546 pal->new_rsv(rsv); 561 pal->new_rsv(pal, rsv);
547 if (rsv->state == UWB_RSV_STATE_T_ACCEPTED) 562 if (rsv->state == UWB_RSV_STATE_T_ACCEPTED)
548 break; 563 break;
549 } 564 }
550 spin_unlock(&rc->pal_lock); 565 mutex_unlock(&rc->uwb_dev.mutex);
551 566
552 list_add_tail(&rsv->rc_node, &rc->reservations); 567 list_add_tail(&rsv->rc_node, &rc->reservations);
553 state = rsv->state; 568 state = rsv->state;
@@ -644,6 +659,25 @@ static void uwb_rsv_timer(unsigned long arg)
644 uwb_rsv_sched_update(rsv->rc); 659 uwb_rsv_sched_update(rsv->rc);
645} 660}
646 661
662/**
663 * uwb_rsv_remove_all - remove all reservations
664 * @rc: the radio controller
665 *
666 * A DRP IE update is not done.
667 */
668void uwb_rsv_remove_all(struct uwb_rc *rc)
669{
670 struct uwb_rsv *rsv, *t;
671
672 mutex_lock(&rc->rsvs_mutex);
673 list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) {
674 uwb_rsv_remove(rsv);
675 }
676 mutex_unlock(&rc->rsvs_mutex);
677
678 cancel_work_sync(&rc->rsv_update_work);
679}
680
647void uwb_rsv_init(struct uwb_rc *rc) 681void uwb_rsv_init(struct uwb_rc *rc)
648{ 682{
649 INIT_LIST_HEAD(&rc->reservations); 683 INIT_LIST_HEAD(&rc->reservations);
@@ -667,14 +701,6 @@ int uwb_rsv_setup(struct uwb_rc *rc)
667 701
668void uwb_rsv_cleanup(struct uwb_rc *rc) 702void uwb_rsv_cleanup(struct uwb_rc *rc)
669{ 703{
670 struct uwb_rsv *rsv, *t; 704 uwb_rsv_remove_all(rc);
671
672 mutex_lock(&rc->rsvs_mutex);
673 list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) {
674 uwb_rsv_remove(rsv);
675 }
676 mutex_unlock(&rc->rsvs_mutex);
677
678 cancel_work_sync(&rc->rsv_update_work);
679 destroy_workqueue(rc->rsv_workq); 705 destroy_workqueue(rc->rsv_workq);
680} 706}
diff --git a/drivers/uwb/umc-bus.c b/drivers/uwb/umc-bus.c
index 2d8d62d9f53e..5ad36164c13b 100644
--- a/drivers/uwb/umc-bus.c
+++ b/drivers/uwb/umc-bus.c
@@ -11,23 +11,48 @@
11#include <linux/uwb/umc.h> 11#include <linux/uwb/umc.h>
12#include <linux/pci.h> 12#include <linux/pci.h>
13 13
14static int umc_bus_unbind_helper(struct device *dev, void *data) 14static int umc_bus_pre_reset_helper(struct device *dev, void *data)
15{ 15{
16 struct device *parent = data; 16 int ret = 0;
17 17
18 if (dev->parent == parent && dev->driver) 18 if (dev->driver) {
19 device_release_driver(dev); 19 struct umc_dev *umc = to_umc_dev(dev);
20 return 0; 20 struct umc_driver *umc_drv = to_umc_driver(dev->driver);
21
22 if (umc_drv->pre_reset)
23 ret = umc_drv->pre_reset(umc);
24 else
25 device_release_driver(dev);
26 }
27 return ret;
28}
29
30static int umc_bus_post_reset_helper(struct device *dev, void *data)
31{
32 int ret = 0;
33
34 if (dev->driver) {
35 struct umc_dev *umc = to_umc_dev(dev);
36 struct umc_driver *umc_drv = to_umc_driver(dev->driver);
37
38 if (umc_drv->post_reset)
39 ret = umc_drv->post_reset(umc);
40 } else
41 ret = device_attach(dev);
42
43 return ret;
21} 44}
22 45
23/** 46/**
24 * umc_controller_reset - reset the whole UMC controller 47 * umc_controller_reset - reset the whole UMC controller
25 * @umc: the UMC device for the radio controller. 48 * @umc: the UMC device for the radio controller.
26 * 49 *
27 * Drivers will be unbound from all UMC devices belonging to the 50 * Drivers or all capabilities of the controller will have their
28 * controller and then the radio controller will be rebound. The 51 * pre_reset methods called or be unbound from their device. Then all
29 * radio controller is expected to do a full hardware reset when it is 52 * post_reset methods will be called or the drivers will be rebound.
30 * probed. 53 *
54 * Radio controllers must provide pre_reset and post_reset methods and
55 * reset the hardware in their start method.
31 * 56 *
32 * If this is called while a probe() or remove() is in progress it 57 * If this is called while a probe() or remove() is in progress it
33 * will return -EAGAIN and not perform the reset. 58 * will return -EAGAIN and not perform the reset.
@@ -35,14 +60,13 @@ static int umc_bus_unbind_helper(struct device *dev, void *data)
35int umc_controller_reset(struct umc_dev *umc) 60int umc_controller_reset(struct umc_dev *umc)
36{ 61{
37 struct device *parent = umc->dev.parent; 62 struct device *parent = umc->dev.parent;
38 int ret; 63 int ret = 0;
39 64
40 if (down_trylock(&parent->sem)) 65 if(down_trylock(&parent->sem))
41 return -EAGAIN; 66 return -EAGAIN;
42 bus_for_each_dev(&umc_bus_type, NULL, parent, umc_bus_unbind_helper); 67 ret = device_for_each_child(parent, parent, umc_bus_pre_reset_helper);
43 ret = device_attach(&umc->dev); 68 if (ret >= 0)
44 if (ret == 1) 69 device_for_each_child(parent, parent, umc_bus_post_reset_helper);
45 ret = 0;
46 up(&parent->sem); 70 up(&parent->sem);
47 71
48 return ret; 72 return ret;
@@ -75,10 +99,10 @@ static int umc_bus_rescan_helper(struct device *dev, void *data)
75 if (!dev->driver) 99 if (!dev->driver)
76 ret = device_attach(dev); 100 ret = device_attach(dev);
77 101
78 return ret < 0 ? ret : 0; 102 return ret;
79} 103}
80 104
81static void umc_bus_rescan(void) 105static void umc_bus_rescan(struct device *parent)
82{ 106{
83 int err; 107 int err;
84 108
@@ -86,7 +110,7 @@ static void umc_bus_rescan(void)
86 * We can't use bus_rescan_devices() here as it deadlocks when 110 * We can't use bus_rescan_devices() here as it deadlocks when
87 * it tries to retake the dev->parent semaphore. 111 * it tries to retake the dev->parent semaphore.
88 */ 112 */
89 err = bus_for_each_dev(&umc_bus_type, NULL, NULL, umc_bus_rescan_helper); 113 err = device_for_each_child(parent, NULL, umc_bus_rescan_helper);
90 if (err < 0) 114 if (err < 0)
91 printk(KERN_WARNING "%s: rescan of bus failed: %d\n", 115 printk(KERN_WARNING "%s: rescan of bus failed: %d\n",
92 KBUILD_MODNAME, err); 116 KBUILD_MODNAME, err);
@@ -120,7 +144,7 @@ static int umc_device_probe(struct device *dev)
120 if (err) 144 if (err)
121 put_device(dev); 145 put_device(dev);
122 else 146 else
123 umc_bus_rescan(); 147 umc_bus_rescan(dev->parent);
124 148
125 return err; 149 return err;
126} 150}
diff --git a/drivers/uwb/umc-dev.c b/drivers/uwb/umc-dev.c
index aa44e1c1a102..53207e14cd8f 100644
--- a/drivers/uwb/umc-dev.c
+++ b/drivers/uwb/umc-dev.c
@@ -31,8 +31,7 @@ struct umc_dev *umc_device_create(struct device *parent, int n)
31 31
32 umc = kzalloc(sizeof(struct umc_dev), GFP_KERNEL); 32 umc = kzalloc(sizeof(struct umc_dev), GFP_KERNEL);
33 if (umc) { 33 if (umc) {
34 snprintf(umc->dev.bus_id, sizeof(umc->dev.bus_id), "%s-%d", 34 dev_set_name(&umc->dev, "%s-%d", dev_name(parent), n);
35 parent->bus_id, n);
36 umc->dev.parent = parent; 35 umc->dev.parent = parent;
37 umc->dev.bus = &umc_bus_type; 36 umc->dev.bus = &umc_bus_type;
38 umc->dev.release = umc_device_release; 37 umc->dev.release = umc_device_release;
diff --git a/drivers/uwb/uwb-debug.c b/drivers/uwb/uwb-debug.c
index 6d232c35d07d..a6debb9baf38 100644
--- a/drivers/uwb/uwb-debug.c
+++ b/drivers/uwb/uwb-debug.c
@@ -33,8 +33,6 @@
33#include <linux/seq_file.h> 33#include <linux/seq_file.h>
34 34
35#include <linux/uwb/debug-cmd.h> 35#include <linux/uwb/debug-cmd.h>
36#define D_LOCAL 0
37#include <linux/uwb/debug.h>
38 36
39#include "uwb-internal.h" 37#include "uwb-internal.h"
40 38
@@ -104,6 +102,11 @@ static void uwb_dbg_rsv_cb(struct uwb_rsv *rsv)
104 102
105 dev_dbg(dev, "debug: rsv %s -> %s: %s\n", 103 dev_dbg(dev, "debug: rsv %s -> %s: %s\n",
106 owner, target, uwb_rsv_state_str(rsv->state)); 104 owner, target, uwb_rsv_state_str(rsv->state));
105
106 if (rsv->state == UWB_RSV_STATE_NONE) {
107 list_del(&rsv->pal_node);
108 uwb_rsv_destroy(rsv);
109 }
107} 110}
108 111
109static int cmd_rsv_establish(struct uwb_rc *rc, 112static int cmd_rsv_establish(struct uwb_rc *rc,
@@ -119,7 +122,7 @@ static int cmd_rsv_establish(struct uwb_rc *rc,
119 if (target == NULL) 122 if (target == NULL)
120 return -ENODEV; 123 return -ENODEV;
121 124
122 rsv = uwb_rsv_create(rc, uwb_dbg_rsv_cb, NULL); 125 rsv = uwb_rsv_create(rc, uwb_dbg_rsv_cb, rc->dbg);
123 if (rsv == NULL) { 126 if (rsv == NULL) {
124 uwb_dev_put(target); 127 uwb_dev_put(target);
125 return -ENOMEM; 128 return -ENOMEM;
@@ -153,16 +156,28 @@ static int cmd_rsv_terminate(struct uwb_rc *rc,
153 found = rsv; 156 found = rsv;
154 break; 157 break;
155 } 158 }
159 i++;
156 } 160 }
157 if (!found) 161 if (!found)
158 return -EINVAL; 162 return -EINVAL;
159 163
160 list_del(&found->pal_node);
161 uwb_rsv_terminate(found); 164 uwb_rsv_terminate(found);
162 165
163 return 0; 166 return 0;
164} 167}
165 168
169static int cmd_ie_add(struct uwb_rc *rc, struct uwb_dbg_cmd_ie *ie_to_add)
170{
171 return uwb_rc_ie_add(rc,
172 (const struct uwb_ie_hdr *) ie_to_add->data,
173 ie_to_add->len);
174}
175
176static int cmd_ie_rm(struct uwb_rc *rc, struct uwb_dbg_cmd_ie *ie_to_rm)
177{
178 return uwb_rc_ie_rm(rc, ie_to_rm->data[0]);
179}
180
166static int command_open(struct inode *inode, struct file *file) 181static int command_open(struct inode *inode, struct file *file)
167{ 182{
168 file->private_data = inode->i_private; 183 file->private_data = inode->i_private;
@@ -175,7 +190,7 @@ static ssize_t command_write(struct file *file, const char __user *buf,
175{ 190{
176 struct uwb_rc *rc = file->private_data; 191 struct uwb_rc *rc = file->private_data;
177 struct uwb_dbg_cmd cmd; 192 struct uwb_dbg_cmd cmd;
178 int ret; 193 int ret = 0;
179 194
180 if (len != sizeof(struct uwb_dbg_cmd)) 195 if (len != sizeof(struct uwb_dbg_cmd))
181 return -EINVAL; 196 return -EINVAL;
@@ -190,6 +205,18 @@ static ssize_t command_write(struct file *file, const char __user *buf,
190 case UWB_DBG_CMD_RSV_TERMINATE: 205 case UWB_DBG_CMD_RSV_TERMINATE:
191 ret = cmd_rsv_terminate(rc, &cmd.rsv_terminate); 206 ret = cmd_rsv_terminate(rc, &cmd.rsv_terminate);
192 break; 207 break;
208 case UWB_DBG_CMD_IE_ADD:
209 ret = cmd_ie_add(rc, &cmd.ie_add);
210 break;
211 case UWB_DBG_CMD_IE_RM:
212 ret = cmd_ie_rm(rc, &cmd.ie_rm);
213 break;
214 case UWB_DBG_CMD_RADIO_START:
215 ret = uwb_radio_start(&rc->dbg->pal);
216 break;
217 case UWB_DBG_CMD_RADIO_STOP:
218 uwb_radio_stop(&rc->dbg->pal);
219 break;
193 default: 220 default:
194 return -EINVAL; 221 return -EINVAL;
195 } 222 }
@@ -283,12 +310,24 @@ static struct file_operations drp_avail_fops = {
283 .owner = THIS_MODULE, 310 .owner = THIS_MODULE,
284}; 311};
285 312
286static void uwb_dbg_new_rsv(struct uwb_rsv *rsv) 313static void uwb_dbg_channel_changed(struct uwb_pal *pal, int channel)
287{ 314{
288 struct uwb_rc *rc = rsv->rc; 315 struct device *dev = &pal->rc->uwb_dev.dev;
289 316
290 if (rc->dbg->accept) 317 if (channel > 0)
291 uwb_rsv_accept(rsv, uwb_dbg_rsv_cb, NULL); 318 dev_info(dev, "debug: channel %d started\n", channel);
319 else
320 dev_info(dev, "debug: channel stopped\n");
321}
322
323static void uwb_dbg_new_rsv(struct uwb_pal *pal, struct uwb_rsv *rsv)
324{
325 struct uwb_dbg *dbg = container_of(pal, struct uwb_dbg, pal);
326
327 if (dbg->accept) {
328 list_add_tail(&rsv->pal_node, &dbg->rsvs);
329 uwb_rsv_accept(rsv, uwb_dbg_rsv_cb, dbg);
330 }
292} 331}
293 332
294/** 333/**
@@ -304,8 +343,11 @@ void uwb_dbg_add_rc(struct uwb_rc *rc)
304 INIT_LIST_HEAD(&rc->dbg->rsvs); 343 INIT_LIST_HEAD(&rc->dbg->rsvs);
305 344
306 uwb_pal_init(&rc->dbg->pal); 345 uwb_pal_init(&rc->dbg->pal);
346 rc->dbg->pal.rc = rc;
347 rc->dbg->pal.channel_changed = uwb_dbg_channel_changed;
307 rc->dbg->pal.new_rsv = uwb_dbg_new_rsv; 348 rc->dbg->pal.new_rsv = uwb_dbg_new_rsv;
308 uwb_pal_register(rc, &rc->dbg->pal); 349 uwb_pal_register(&rc->dbg->pal);
350
309 if (root_dir) { 351 if (root_dir) {
310 rc->dbg->root_d = debugfs_create_dir(dev_name(&rc->uwb_dev.dev), 352 rc->dbg->root_d = debugfs_create_dir(dev_name(&rc->uwb_dev.dev),
311 root_dir); 353 root_dir);
@@ -325,7 +367,7 @@ void uwb_dbg_add_rc(struct uwb_rc *rc)
325} 367}
326 368
327/** 369/**
328 * uwb_dbg_add_rc - remove a radio controller's debug interface 370 * uwb_dbg_del_rc - remove a radio controller's debug interface
329 * @rc: the radio controller 371 * @rc: the radio controller
330 */ 372 */
331void uwb_dbg_del_rc(struct uwb_rc *rc) 373void uwb_dbg_del_rc(struct uwb_rc *rc)
@@ -336,10 +378,10 @@ void uwb_dbg_del_rc(struct uwb_rc *rc)
336 return; 378 return;
337 379
338 list_for_each_entry_safe(rsv, t, &rc->dbg->rsvs, pal_node) { 380 list_for_each_entry_safe(rsv, t, &rc->dbg->rsvs, pal_node) {
339 uwb_rsv_destroy(rsv); 381 uwb_rsv_terminate(rsv);
340 } 382 }
341 383
342 uwb_pal_unregister(rc, &rc->dbg->pal); 384 uwb_pal_unregister(&rc->dbg->pal);
343 385
344 if (root_dir) { 386 if (root_dir) {
345 debugfs_remove(rc->dbg->drp_avail_f); 387 debugfs_remove(rc->dbg->drp_avail_f);
@@ -365,3 +407,16 @@ void uwb_dbg_exit(void)
365{ 407{
366 debugfs_remove(root_dir); 408 debugfs_remove(root_dir);
367} 409}
410
411/**
412 * uwb_dbg_create_pal_dir - create a debugfs directory for a PAL
413 * @pal: The PAL.
414 */
415struct dentry *uwb_dbg_create_pal_dir(struct uwb_pal *pal)
416{
417 struct uwb_rc *rc = pal->rc;
418
419 if (root_dir && rc->dbg && rc->dbg->root_d && pal->name)
420 return debugfs_create_dir(pal->name, rc->dbg->root_d);
421 return NULL;
422}
diff --git a/drivers/uwb/uwb-internal.h b/drivers/uwb/uwb-internal.h
index 2ad307d12961..f0f21f406bf0 100644
--- a/drivers/uwb/uwb-internal.h
+++ b/drivers/uwb/uwb-internal.h
@@ -66,14 +66,14 @@ extern int uwb_rc_scan(struct uwb_rc *rc,
66 unsigned channel, enum uwb_scan_type type, 66 unsigned channel, enum uwb_scan_type type,
67 unsigned bpst_offset); 67 unsigned bpst_offset);
68extern int uwb_rc_send_all_drp_ie(struct uwb_rc *rc); 68extern int uwb_rc_send_all_drp_ie(struct uwb_rc *rc);
69extern ssize_t uwb_rc_print_IEs(struct uwb_rc *rc, char *, size_t); 69
70extern void uwb_rc_ie_init(struct uwb_rc *); 70void uwb_rc_ie_init(struct uwb_rc *);
71extern void uwb_rc_ie_init(struct uwb_rc *); 71int uwb_rc_ie_setup(struct uwb_rc *);
72extern ssize_t uwb_rc_ie_setup(struct uwb_rc *); 72void uwb_rc_ie_release(struct uwb_rc *);
73extern void uwb_rc_ie_release(struct uwb_rc *); 73int uwb_ie_dump_hex(const struct uwb_ie_hdr *ies, size_t len,
74extern int uwb_rc_ie_add(struct uwb_rc *, 74 char *buf, size_t size);
75 const struct uwb_ie_hdr *, size_t); 75int uwb_rc_set_ie(struct uwb_rc *, struct uwb_rc_cmd_set_ie *);
76extern int uwb_rc_ie_rm(struct uwb_rc *, enum uwb_ie); 76
77 77
78extern const char *uwb_rc_strerror(unsigned code); 78extern const char *uwb_rc_strerror(unsigned code);
79 79
@@ -160,13 +160,14 @@ struct uwb_event {
160 }; 160 };
161}; 161};
162 162
163extern void uwbd_start(void); 163extern void uwbd_start(struct uwb_rc *rc);
164extern void uwbd_stop(void); 164extern void uwbd_stop(struct uwb_rc *rc);
165extern struct uwb_event *uwb_event_alloc(size_t, gfp_t gfp_mask); 165extern struct uwb_event *uwb_event_alloc(size_t, gfp_t gfp_mask);
166extern void uwbd_event_queue(struct uwb_event *); 166extern void uwbd_event_queue(struct uwb_event *);
167void uwbd_flush(struct uwb_rc *rc); 167void uwbd_flush(struct uwb_rc *rc);
168 168
169/* UWB event handlers */ 169/* UWB event handlers */
170extern int uwbd_evt_handle_rc_ie_rcv(struct uwb_event *);
170extern int uwbd_evt_handle_rc_beacon(struct uwb_event *); 171extern int uwbd_evt_handle_rc_beacon(struct uwb_event *);
171extern int uwbd_evt_handle_rc_beacon_size(struct uwb_event *); 172extern int uwbd_evt_handle_rc_beacon_size(struct uwb_event *);
172extern int uwbd_evt_handle_rc_bpoie_change(struct uwb_event *); 173extern int uwbd_evt_handle_rc_bpoie_change(struct uwb_event *);
@@ -193,15 +194,6 @@ int uwbd_evt_handle_rc_dev_addr_conflict(struct uwb_event *evt);
193 194
194extern unsigned long beacon_timeout_ms; 195extern unsigned long beacon_timeout_ms;
195 196
196/** Beacon cache list */
197struct uwb_beca {
198 struct list_head list;
199 size_t entries;
200 struct mutex mutex;
201};
202
203extern struct uwb_beca uwb_beca;
204
205/** 197/**
206 * Beacon cache entry 198 * Beacon cache entry
207 * 199 *
@@ -228,9 +220,6 @@ struct uwb_beca_e {
228struct uwb_beacon_frame; 220struct uwb_beacon_frame;
229extern ssize_t uwb_bce_print_IEs(struct uwb_dev *, struct uwb_beca_e *, 221extern ssize_t uwb_bce_print_IEs(struct uwb_dev *, struct uwb_beca_e *,
230 char *, size_t); 222 char *, size_t);
231extern struct uwb_beca_e *__uwb_beca_add(struct uwb_rc_evt_beacon *,
232 struct uwb_beacon_frame *,
233 unsigned long);
234 223
235extern void uwb_bce_kfree(struct kref *_bce); 224extern void uwb_bce_kfree(struct kref *_bce);
236static inline void uwb_bce_get(struct uwb_beca_e *bce) 225static inline void uwb_bce_get(struct uwb_beca_e *bce)
@@ -241,14 +230,19 @@ static inline void uwb_bce_put(struct uwb_beca_e *bce)
241{ 230{
242 kref_put(&bce->refcnt, uwb_bce_kfree); 231 kref_put(&bce->refcnt, uwb_bce_kfree);
243} 232}
244extern void uwb_beca_purge(void); 233extern void uwb_beca_purge(struct uwb_rc *rc);
245extern void uwb_beca_release(void); 234extern void uwb_beca_release(struct uwb_rc *rc);
246 235
247struct uwb_dev *uwb_dev_get_by_devaddr(struct uwb_rc *rc, 236struct uwb_dev *uwb_dev_get_by_devaddr(struct uwb_rc *rc,
248 const struct uwb_dev_addr *devaddr); 237 const struct uwb_dev_addr *devaddr);
249struct uwb_dev *uwb_dev_get_by_macaddr(struct uwb_rc *rc, 238struct uwb_dev *uwb_dev_get_by_macaddr(struct uwb_rc *rc,
250 const struct uwb_mac_addr *macaddr); 239 const struct uwb_mac_addr *macaddr);
251 240
241int uwb_radio_setup(struct uwb_rc *rc);
242void uwb_radio_reset_state(struct uwb_rc *rc);
243void uwb_radio_shutdown(struct uwb_rc *rc);
244int uwb_radio_force_channel(struct uwb_rc *rc, int channel);
245
252/* -- UWB Sysfs representation */ 246/* -- UWB Sysfs representation */
253extern struct class uwb_rc_class; 247extern struct class uwb_rc_class;
254extern struct device_attribute dev_attr_mac_address; 248extern struct device_attribute dev_attr_mac_address;
@@ -259,6 +253,7 @@ extern struct device_attribute dev_attr_scan;
259void uwb_rsv_init(struct uwb_rc *rc); 253void uwb_rsv_init(struct uwb_rc *rc);
260int uwb_rsv_setup(struct uwb_rc *rc); 254int uwb_rsv_setup(struct uwb_rc *rc);
261void uwb_rsv_cleanup(struct uwb_rc *rc); 255void uwb_rsv_cleanup(struct uwb_rc *rc);
256void uwb_rsv_remove_all(struct uwb_rc *rc);
262 257
263void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state); 258void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state);
264void uwb_rsv_remove(struct uwb_rsv *rsv); 259void uwb_rsv_remove(struct uwb_rsv *rsv);
@@ -289,8 +284,7 @@ void uwb_dbg_init(void);
289void uwb_dbg_exit(void); 284void uwb_dbg_exit(void);
290void uwb_dbg_add_rc(struct uwb_rc *rc); 285void uwb_dbg_add_rc(struct uwb_rc *rc);
291void uwb_dbg_del_rc(struct uwb_rc *rc); 286void uwb_dbg_del_rc(struct uwb_rc *rc);
292 287struct dentry *uwb_dbg_create_pal_dir(struct uwb_pal *pal);
293/* Workarounds for version specific stuff */
294 288
295static inline void uwb_dev_lock(struct uwb_dev *uwb_dev) 289static inline void uwb_dev_lock(struct uwb_dev *uwb_dev)
296{ 290{
diff --git a/drivers/uwb/uwbd.c b/drivers/uwb/uwbd.c
index 78908416e42c..ec42ce92dbce 100644
--- a/drivers/uwb/uwbd.c
+++ b/drivers/uwb/uwbd.c
@@ -104,6 +104,10 @@ struct uwbd_event {
104/** Table of handlers for and properties of the UWBD Radio Control Events */ 104/** Table of handlers for and properties of the UWBD Radio Control Events */
105static 105static
106struct uwbd_event uwbd_events[] = { 106struct uwbd_event uwbd_events[] = {
107 [UWB_RC_EVT_IE_RCV] = {
108 .handler = uwbd_evt_handle_rc_ie_rcv,
109 .name = "IE_RECEIVED"
110 },
107 [UWB_RC_EVT_BEACON] = { 111 [UWB_RC_EVT_BEACON] = {
108 .handler = uwbd_evt_handle_rc_beacon, 112 .handler = uwbd_evt_handle_rc_beacon,
109 .name = "BEACON_RECEIVED" 113 .name = "BEACON_RECEIVED"
@@ -166,8 +170,6 @@ static const struct uwbd_event uwbd_message_handlers[] = {
166 }, 170 },
167}; 171};
168 172
169static DEFINE_MUTEX(uwbd_event_mutex);
170
171/** 173/**
172 * Handle an URC event passed to the UWB Daemon 174 * Handle an URC event passed to the UWB Daemon
173 * 175 *
@@ -231,19 +233,10 @@ static void uwbd_event_handle_message(struct uwb_event *evt)
231 return; 233 return;
232 } 234 }
233 235
234 /* If this is a reset event we need to drop the
235 * uwbd_event_mutex or it deadlocks when the reset handler
236 * attempts to flush the uwbd events. */
237 if (evt->message == UWB_EVT_MSG_RESET)
238 mutex_unlock(&uwbd_event_mutex);
239
240 result = uwbd_message_handlers[evt->message].handler(evt); 236 result = uwbd_message_handlers[evt->message].handler(evt);
241 if (result < 0) 237 if (result < 0)
242 dev_err(&rc->uwb_dev.dev, "UWBD: '%s' message failed: %d\n", 238 dev_err(&rc->uwb_dev.dev, "UWBD: '%s' message failed: %d\n",
243 uwbd_message_handlers[evt->message].name, result); 239 uwbd_message_handlers[evt->message].name, result);
244
245 if (evt->message == UWB_EVT_MSG_RESET)
246 mutex_lock(&uwbd_event_mutex);
247} 240}
248 241
249static void uwbd_event_handle(struct uwb_event *evt) 242static void uwbd_event_handle(struct uwb_event *evt)
@@ -271,20 +264,6 @@ static void uwbd_event_handle(struct uwb_event *evt)
271 264
272 __uwb_rc_put(rc); /* for the __uwb_rc_get() in uwb_rc_notif_cb() */ 265 __uwb_rc_put(rc); /* for the __uwb_rc_get() in uwb_rc_notif_cb() */
273} 266}
274/* The UWB Daemon */
275
276
277/** Daemon's PID: used to decide if we can queue or not */
278static int uwbd_pid;
279/** Daemon's task struct for managing the kthread */
280static struct task_struct *uwbd_task;
281/** Daemon's waitqueue for waiting for new events */
282static DECLARE_WAIT_QUEUE_HEAD(uwbd_wq);
283/** Daemon's list of events; we queue/dequeue here */
284static struct list_head uwbd_event_list = LIST_HEAD_INIT(uwbd_event_list);
285/** Daemon's list lock to protect concurent access */
286static DEFINE_SPINLOCK(uwbd_event_list_lock);
287
288 267
289/** 268/**
290 * UWB Daemon 269 * UWB Daemon
@@ -298,65 +277,58 @@ static DEFINE_SPINLOCK(uwbd_event_list_lock);
298 * FIXME: should change so we don't have a 1HZ timer all the time, but 277 * FIXME: should change so we don't have a 1HZ timer all the time, but
299 * only if there are devices. 278 * only if there are devices.
300 */ 279 */
301static int uwbd(void *unused) 280static int uwbd(void *param)
302{ 281{
282 struct uwb_rc *rc = param;
303 unsigned long flags; 283 unsigned long flags;
304 struct list_head list = LIST_HEAD_INIT(list); 284 struct uwb_event *evt;
305 struct uwb_event *evt, *nxt;
306 int should_stop = 0; 285 int should_stop = 0;
286
307 while (1) { 287 while (1) {
308 wait_event_interruptible_timeout( 288 wait_event_interruptible_timeout(
309 uwbd_wq, 289 rc->uwbd.wq,
310 !list_empty(&uwbd_event_list) 290 !list_empty(&rc->uwbd.event_list)
311 || (should_stop = kthread_should_stop()), 291 || (should_stop = kthread_should_stop()),
312 HZ); 292 HZ);
313 if (should_stop) 293 if (should_stop)
314 break; 294 break;
315 try_to_freeze(); 295 try_to_freeze();
316 296
317 mutex_lock(&uwbd_event_mutex); 297 spin_lock_irqsave(&rc->uwbd.event_list_lock, flags);
318 spin_lock_irqsave(&uwbd_event_list_lock, flags); 298 if (!list_empty(&rc->uwbd.event_list)) {
319 list_splice_init(&uwbd_event_list, &list); 299 evt = list_first_entry(&rc->uwbd.event_list, struct uwb_event, list_node);
320 spin_unlock_irqrestore(&uwbd_event_list_lock, flags);
321 list_for_each_entry_safe(evt, nxt, &list, list_node) {
322 list_del(&evt->list_node); 300 list_del(&evt->list_node);
301 } else
302 evt = NULL;
303 spin_unlock_irqrestore(&rc->uwbd.event_list_lock, flags);
304
305 if (evt) {
323 uwbd_event_handle(evt); 306 uwbd_event_handle(evt);
324 kfree(evt); 307 kfree(evt);
325 } 308 }
326 mutex_unlock(&uwbd_event_mutex);
327 309
328 uwb_beca_purge(); /* Purge devices that left */ 310 uwb_beca_purge(rc); /* Purge devices that left */
329 } 311 }
330 return 0; 312 return 0;
331} 313}
332 314
333 315
334/** Start the UWB daemon */ 316/** Start the UWB daemon */
335void uwbd_start(void) 317void uwbd_start(struct uwb_rc *rc)
336{ 318{
337 uwbd_task = kthread_run(uwbd, NULL, "uwbd"); 319 rc->uwbd.task = kthread_run(uwbd, rc, "uwbd");
338 if (uwbd_task == NULL) 320 if (rc->uwbd.task == NULL)
339 printk(KERN_ERR "UWB: Cannot start management daemon; " 321 printk(KERN_ERR "UWB: Cannot start management daemon; "
340 "UWB won't work\n"); 322 "UWB won't work\n");
341 else 323 else
342 uwbd_pid = uwbd_task->pid; 324 rc->uwbd.pid = rc->uwbd.task->pid;
343} 325}
344 326
345/* Stop the UWB daemon and free any unprocessed events */ 327/* Stop the UWB daemon and free any unprocessed events */
346void uwbd_stop(void) 328void uwbd_stop(struct uwb_rc *rc)
347{ 329{
348 unsigned long flags; 330 kthread_stop(rc->uwbd.task);
349 struct uwb_event *evt, *nxt; 331 uwbd_flush(rc);
350 kthread_stop(uwbd_task);
351 spin_lock_irqsave(&uwbd_event_list_lock, flags);
352 uwbd_pid = 0;
353 list_for_each_entry_safe(evt, nxt, &uwbd_event_list, list_node) {
354 if (evt->type == UWB_EVT_TYPE_NOTIF)
355 kfree(evt->notif.rceb);
356 kfree(evt);
357 }
358 spin_unlock_irqrestore(&uwbd_event_list_lock, flags);
359 uwb_beca_release();
360} 332}
361 333
362/* 334/*
@@ -373,18 +345,20 @@ void uwbd_stop(void)
373 */ 345 */
374void uwbd_event_queue(struct uwb_event *evt) 346void uwbd_event_queue(struct uwb_event *evt)
375{ 347{
348 struct uwb_rc *rc = evt->rc;
376 unsigned long flags; 349 unsigned long flags;
377 spin_lock_irqsave(&uwbd_event_list_lock, flags); 350
378 if (uwbd_pid != 0) { 351 spin_lock_irqsave(&rc->uwbd.event_list_lock, flags);
379 list_add(&evt->list_node, &uwbd_event_list); 352 if (rc->uwbd.pid != 0) {
380 wake_up_all(&uwbd_wq); 353 list_add(&evt->list_node, &rc->uwbd.event_list);
354 wake_up_all(&rc->uwbd.wq);
381 } else { 355 } else {
382 __uwb_rc_put(evt->rc); 356 __uwb_rc_put(evt->rc);
383 if (evt->type == UWB_EVT_TYPE_NOTIF) 357 if (evt->type == UWB_EVT_TYPE_NOTIF)
384 kfree(evt->notif.rceb); 358 kfree(evt->notif.rceb);
385 kfree(evt); 359 kfree(evt);
386 } 360 }
387 spin_unlock_irqrestore(&uwbd_event_list_lock, flags); 361 spin_unlock_irqrestore(&rc->uwbd.event_list_lock, flags);
388 return; 362 return;
389} 363}
390 364
@@ -392,10 +366,8 @@ void uwbd_flush(struct uwb_rc *rc)
392{ 366{
393 struct uwb_event *evt, *nxt; 367 struct uwb_event *evt, *nxt;
394 368
395 mutex_lock(&uwbd_event_mutex); 369 spin_lock_irq(&rc->uwbd.event_list_lock);
396 370 list_for_each_entry_safe(evt, nxt, &rc->uwbd.event_list, list_node) {
397 spin_lock_irq(&uwbd_event_list_lock);
398 list_for_each_entry_safe(evt, nxt, &uwbd_event_list, list_node) {
399 if (evt->rc == rc) { 371 if (evt->rc == rc) {
400 __uwb_rc_put(rc); 372 __uwb_rc_put(rc);
401 list_del(&evt->list_node); 373 list_del(&evt->list_node);
@@ -404,7 +376,5 @@ void uwbd_flush(struct uwb_rc *rc)
404 kfree(evt); 376 kfree(evt);
405 } 377 }
406 } 378 }
407 spin_unlock_irq(&uwbd_event_list_lock); 379 spin_unlock_irq(&rc->uwbd.event_list_lock);
408
409 mutex_unlock(&uwbd_event_mutex);
410} 380}
diff --git a/drivers/uwb/whc-rc.c b/drivers/uwb/whc-rc.c
index 1711deadb114..5f00386e26c7 100644
--- a/drivers/uwb/whc-rc.c
+++ b/drivers/uwb/whc-rc.c
@@ -39,7 +39,6 @@
39 * them to the hw and transfer the replies/notifications back to the 39 * them to the hw and transfer the replies/notifications back to the
40 * UWB stack through the UWB daemon (UWBD). 40 * UWB stack through the UWB daemon (UWBD).
41 */ 41 */
42#include <linux/version.h>
43#include <linux/init.h> 42#include <linux/init.h>
44#include <linux/module.h> 43#include <linux/module.h>
45#include <linux/pci.h> 44#include <linux/pci.h>
@@ -333,47 +332,23 @@ void whcrc_release_rc_umc(struct whcrc *whcrc)
333static int whcrc_start_rc(struct uwb_rc *rc) 332static int whcrc_start_rc(struct uwb_rc *rc)
334{ 333{
335 struct whcrc *whcrc = rc->priv; 334 struct whcrc *whcrc = rc->priv;
336 int result = 0;
337 struct device *dev = &whcrc->umc_dev->dev; 335 struct device *dev = &whcrc->umc_dev->dev;
338 unsigned long start, duration;
339 336
340 /* Reset the thing */ 337 /* Reset the thing */
341 le_writel(URCCMD_RESET, whcrc->rc_base + URCCMD); 338 le_writel(URCCMD_RESET, whcrc->rc_base + URCCMD);
342 if (d_test(3))
343 start = jiffies;
344 if (whci_wait_for(dev, whcrc->rc_base + URCCMD, URCCMD_RESET, 0, 339 if (whci_wait_for(dev, whcrc->rc_base + URCCMD, URCCMD_RESET, 0,
345 5000, "device to reset at init") < 0) { 340 5000, "hardware reset") < 0)
346 result = -EBUSY; 341 return -EBUSY;
347 goto error;
348 } else if (d_test(3)) {
349 duration = jiffies - start;
350 if (duration > msecs_to_jiffies(40))
351 dev_err(dev, "Device took %ums to "
352 "reset. MAX expected: 40ms\n",
353 jiffies_to_msecs(duration));
354 }
355 342
356 /* Set the event buffer, start the controller (enable IRQs later) */ 343 /* Set the event buffer, start the controller (enable IRQs later) */
357 le_writel(0, whcrc->rc_base + URCINTR); 344 le_writel(0, whcrc->rc_base + URCINTR);
358 le_writel(URCCMD_RS, whcrc->rc_base + URCCMD); 345 le_writel(URCCMD_RS, whcrc->rc_base + URCCMD);
359 result = -ETIMEDOUT;
360 if (d_test(3))
361 start = jiffies;
362 if (whci_wait_for(dev, whcrc->rc_base + URCSTS, URCSTS_HALTED, 0, 346 if (whci_wait_for(dev, whcrc->rc_base + URCSTS, URCSTS_HALTED, 0,
363 5000, "device to start") < 0) 347 5000, "radio controller start") < 0)
364 goto error; 348 return -ETIMEDOUT;
365 if (d_test(3)) {
366 duration = jiffies - start;
367 if (duration > msecs_to_jiffies(40))
368 dev_err(dev, "Device took %ums to start. "
369 "MAX expected: 40ms\n",
370 jiffies_to_msecs(duration));
371 }
372 whcrc_enable_events(whcrc); 349 whcrc_enable_events(whcrc);
373 result = 0;
374 le_writel(URCINTR_EN_ALL, whcrc->rc_base + URCINTR); 350 le_writel(URCINTR_EN_ALL, whcrc->rc_base + URCINTR);
375error: 351 return 0;
376 return result;
377} 352}
378 353
379 354
@@ -395,7 +370,7 @@ void whcrc_stop_rc(struct uwb_rc *rc)
395 370
396 le_writel(0, whcrc->rc_base + URCCMD); 371 le_writel(0, whcrc->rc_base + URCCMD);
397 whci_wait_for(&umc_dev->dev, whcrc->rc_base + URCSTS, 372 whci_wait_for(&umc_dev->dev, whcrc->rc_base + URCSTS,
398 URCSTS_HALTED, 0, 40, "URCSTS.HALTED"); 373 URCSTS_HALTED, URCSTS_HALTED, 100, "radio controller stop");
399} 374}
400 375
401static void whcrc_init(struct whcrc *whcrc) 376static void whcrc_init(struct whcrc *whcrc)
@@ -489,6 +464,24 @@ static void whcrc_remove(struct umc_dev *umc_dev)
489 d_printf(1, &umc_dev->dev, "freed whcrc %p\n", whcrc); 464 d_printf(1, &umc_dev->dev, "freed whcrc %p\n", whcrc);
490} 465}
491 466
467static int whcrc_pre_reset(struct umc_dev *umc)
468{
469 struct whcrc *whcrc = umc_get_drvdata(umc);
470 struct uwb_rc *uwb_rc = whcrc->uwb_rc;
471
472 uwb_rc_pre_reset(uwb_rc);
473 return 0;
474}
475
476static int whcrc_post_reset(struct umc_dev *umc)
477{
478 struct whcrc *whcrc = umc_get_drvdata(umc);
479 struct uwb_rc *uwb_rc = whcrc->uwb_rc;
480
481 uwb_rc_post_reset(uwb_rc);
482 return 0;
483}
484
492/* PCI device ID's that we handle [so it gets loaded] */ 485/* PCI device ID's that we handle [so it gets loaded] */
493static struct pci_device_id whcrc_id_table[] = { 486static struct pci_device_id whcrc_id_table[] = {
494 { PCI_DEVICE_CLASS(PCI_CLASS_WIRELESS_WHCI, ~0) }, 487 { PCI_DEVICE_CLASS(PCI_CLASS_WIRELESS_WHCI, ~0) },
@@ -497,10 +490,12 @@ static struct pci_device_id whcrc_id_table[] = {
497MODULE_DEVICE_TABLE(pci, whcrc_id_table); 490MODULE_DEVICE_TABLE(pci, whcrc_id_table);
498 491
499static struct umc_driver whcrc_driver = { 492static struct umc_driver whcrc_driver = {
500 .name = "whc-rc", 493 .name = "whc-rc",
501 .cap_id = UMC_CAP_ID_WHCI_RC, 494 .cap_id = UMC_CAP_ID_WHCI_RC,
502 .probe = whcrc_probe, 495 .probe = whcrc_probe,
503 .remove = whcrc_remove, 496 .remove = whcrc_remove,
497 .pre_reset = whcrc_pre_reset,
498 .post_reset = whcrc_post_reset,
504}; 499};
505 500
506static int __init whcrc_driver_init(void) 501static int __init whcrc_driver_init(void)
diff --git a/drivers/uwb/whci.c b/drivers/uwb/whci.c
index 3df2388f908f..1f8964ed9882 100644
--- a/drivers/uwb/whci.c
+++ b/drivers/uwb/whci.c
@@ -67,11 +67,11 @@ int whci_wait_for(struct device *dev, u32 __iomem *reg, u32 mask, u32 result,
67 val = le_readl(reg); 67 val = le_readl(reg);
68 if ((val & mask) == result) 68 if ((val & mask) == result)
69 break; 69 break;
70 msleep(10);
71 if (t >= max_ms) { 70 if (t >= max_ms) {
72 dev_err(dev, "timed out waiting for %s ", tag); 71 dev_err(dev, "%s timed out\n", tag);
73 return -ETIMEDOUT; 72 return -ETIMEDOUT;
74 } 73 }
74 msleep(10);
75 t += 10; 75 t += 10;
76 } 76 }
77 return 0; 77 return 0;
@@ -111,7 +111,7 @@ static int whci_add_cap(struct whci_card *card, int n)
111 + UWBCAPDATA_TO_OFFSET(capdata); 111 + UWBCAPDATA_TO_OFFSET(capdata);
112 umc->resource.end = umc->resource.start 112 umc->resource.end = umc->resource.start
113 + (n == 0 ? 0x20 : UWBCAPDATA_TO_SIZE(capdata)) - 1; 113 + (n == 0 ? 0x20 : UWBCAPDATA_TO_SIZE(capdata)) - 1;
114 umc->resource.name = umc->dev.bus_id; 114 umc->resource.name = dev_name(&umc->dev);
115 umc->resource.flags = card->pci->resource[bar].flags; 115 umc->resource.flags = card->pci->resource[bar].flags;
116 umc->resource.parent = &card->pci->resource[bar]; 116 umc->resource.parent = &card->pci->resource[bar];
117 umc->irq = card->pci->irq; 117 umc->irq = card->pci->irq;
diff --git a/drivers/uwb/wlp/wlp-internal.h b/drivers/uwb/wlp/wlp-internal.h
index 1c94fabfb1a7..3e8d5de7c5b9 100644
--- a/drivers/uwb/wlp/wlp-internal.h
+++ b/drivers/uwb/wlp/wlp-internal.h
@@ -42,10 +42,6 @@ enum wlp_wss_connect {
42extern struct kobj_type wss_ktype; 42extern struct kobj_type wss_ktype;
43extern struct attribute_group wss_attr_group; 43extern struct attribute_group wss_attr_group;
44 44
45extern int uwb_rc_ie_add(struct uwb_rc *, const struct uwb_ie_hdr *, size_t);
46extern int uwb_rc_ie_rm(struct uwb_rc *, enum uwb_ie);
47
48
49/* This should be changed to a dynamic array where entries are sorted 45/* This should be changed to a dynamic array where entries are sorted
50 * by eth_addr and search is done in a binary form 46 * by eth_addr and search is done in a binary form
51 * 47 *
diff --git a/drivers/uwb/wlp/wlp-lc.c b/drivers/uwb/wlp/wlp-lc.c
index 0799402e73fb..e531093c4162 100644
--- a/drivers/uwb/wlp/wlp-lc.c
+++ b/drivers/uwb/wlp/wlp-lc.c
@@ -526,7 +526,17 @@ void wlp_uwb_notifs_cb(void *_wlp, struct uwb_dev *uwb_dev,
526 } 526 }
527} 527}
528 528
529int wlp_setup(struct wlp *wlp, struct uwb_rc *rc) 529static void wlp_channel_changed(struct uwb_pal *pal, int channel)
530{
531 struct wlp *wlp = container_of(pal, struct wlp, pal);
532
533 if (channel < 0)
534 netif_carrier_off(wlp->ndev);
535 else
536 netif_carrier_on(wlp->ndev);
537}
538
539int wlp_setup(struct wlp *wlp, struct uwb_rc *rc, struct net_device *ndev)
530{ 540{
531 struct device *dev = &rc->uwb_dev.dev; 541 struct device *dev = &rc->uwb_dev.dev;
532 int result; 542 int result;
@@ -537,13 +547,16 @@ int wlp_setup(struct wlp *wlp, struct uwb_rc *rc)
537 BUG_ON(wlp->stop_queue == NULL); 547 BUG_ON(wlp->stop_queue == NULL);
538 BUG_ON(wlp->start_queue == NULL); 548 BUG_ON(wlp->start_queue == NULL);
539 wlp->rc = rc; 549 wlp->rc = rc;
550 wlp->ndev = ndev;
540 wlp_eda_init(&wlp->eda);/* Set up address cache */ 551 wlp_eda_init(&wlp->eda);/* Set up address cache */
541 wlp->uwb_notifs_handler.cb = wlp_uwb_notifs_cb; 552 wlp->uwb_notifs_handler.cb = wlp_uwb_notifs_cb;
542 wlp->uwb_notifs_handler.data = wlp; 553 wlp->uwb_notifs_handler.data = wlp;
543 uwb_notifs_register(rc, &wlp->uwb_notifs_handler); 554 uwb_notifs_register(rc, &wlp->uwb_notifs_handler);
544 555
545 uwb_pal_init(&wlp->pal); 556 uwb_pal_init(&wlp->pal);
546 result = uwb_pal_register(rc, &wlp->pal); 557 wlp->pal.rc = rc;
558 wlp->pal.channel_changed = wlp_channel_changed;
559 result = uwb_pal_register(&wlp->pal);
547 if (result < 0) 560 if (result < 0)
548 uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler); 561 uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler);
549 562
@@ -557,7 +570,7 @@ void wlp_remove(struct wlp *wlp)
557 struct device *dev = &wlp->rc->uwb_dev.dev; 570 struct device *dev = &wlp->rc->uwb_dev.dev;
558 d_fnstart(6, dev, "wlp %p\n", wlp); 571 d_fnstart(6, dev, "wlp %p\n", wlp);
559 wlp_neighbors_release(wlp); 572 wlp_neighbors_release(wlp);
560 uwb_pal_unregister(wlp->rc, &wlp->pal); 573 uwb_pal_unregister(&wlp->pal);
561 uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler); 574 uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler);
562 wlp_eda_release(&wlp->eda); 575 wlp_eda_release(&wlp->eda);
563 mutex_lock(&wlp->mutex); 576 mutex_lock(&wlp->mutex);