aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-class-uwb_rc14
-rw-r--r--Documentation/usb/wusb-cbaf9
-rw-r--r--drivers/usb/host/hwa-hc.c104
-rw-r--r--drivers/usb/host/whci/hcd.c3
-rw-r--r--drivers/usb/host/whci/hw.c8
-rw-r--r--drivers/usb/host/whci/int.c1
-rw-r--r--drivers/usb/host/whci/whcd.h2
-rw-r--r--drivers/usb/host/whci/whci-hc.h2
-rw-r--r--drivers/usb/host/whci/wusb.c16
-rw-r--r--drivers/usb/wusbcore/cbaf.c1
-rw-r--r--drivers/usb/wusbcore/crypto.c15
-rw-r--r--drivers/usb/wusbcore/devconnect.c105
-rw-r--r--drivers/usb/wusbcore/mmc.c83
-rw-r--r--drivers/usb/wusbcore/pal.c16
-rw-r--r--drivers/usb/wusbcore/reservation.c7
-rw-r--r--drivers/usb/wusbcore/rh.c40
-rw-r--r--drivers/usb/wusbcore/security.c3
-rw-r--r--drivers/usb/wusbcore/wusbhc.h36
-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.c20
-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.c66
-rw-r--r--drivers/uwb/uwb-internal.h43
-rw-r--r--drivers/uwb/uwbd.c102
-rw-r--r--drivers/uwb/whc-rc.c31
-rw-r--r--drivers/uwb/whci.c2
-rw-r--r--drivers/uwb/wlp/wlp-internal.h4
-rw-r--r--drivers/uwb/wlp/wlp-lc.c19
-rw-r--r--include/linux/usb/wusb-wa.h1
-rw-r--r--include/linux/uwb.h73
-rw-r--r--include/linux/uwb/debug-cmd.h11
-rw-r--r--include/linux/uwb/debug.h2
-rw-r--r--include/linux/uwb/spec.h28
-rw-r--r--include/linux/uwb/umc.h2
-rw-r--r--include/linux/wlp.h3
52 files changed, 1101 insertions, 1027 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-uwb_rc b/Documentation/ABI/testing/sysfs-class-uwb_rc
index a0d18dbeb7a..6a5fd072849 100644
--- a/Documentation/ABI/testing/sysfs-class-uwb_rc
+++ b/Documentation/ABI/testing/sysfs-class-uwb_rc
@@ -32,14 +32,16 @@ Contact: linux-usb@vger.kernel.org
32Description: 32Description:
33 Write: 33 Write:
34 34
35 <channel> [<bpst offset>] 35 <channel>
36 36
37 to start beaconing on a specific channel, or stop 37 to force a specific channel to be used when beaconing,
38 beaconing if <channel> is -1. Valid channels depends 38 or, if <channel> is -1, to prohibit beaconing. If
39 on the radio controller's supported band groups. 39 <channel> is 0, then the default channel selection
40 algorithm will be used. Valid channels depends on the
41 radio controller's supported band groups.
40 42
41 <bpst offset> may be used to try and join a specific 43 Reading returns the currently active channel, or -1 if
42 beacon group if more than one was found during a scan. 44 the radio controller is not beaconing.
43 45
44What: /sys/class/uwb_rc/uwbN/scan 46What: /sys/class/uwb_rc/uwbN/scan
45Date: July 2008 47Date: July 2008
diff --git a/Documentation/usb/wusb-cbaf b/Documentation/usb/wusb-cbaf
index 2e78b70f3ad..426ddaaef96 100644
--- a/Documentation/usb/wusb-cbaf
+++ b/Documentation/usb/wusb-cbaf
@@ -80,12 +80,6 @@ case $1 in
80 start) 80 start)
81 for dev in ${2:-$hdevs} 81 for dev in ${2:-$hdevs}
82 do 82 do
83 uwb_rc=$(readlink -f $dev/uwb_rc)
84 if cat $uwb_rc/beacon | grep -q -- "-1"
85 then
86 echo 13 0 > $uwb_rc/beacon
87 echo I: started beaconing on ch 13 on $(basename $uwb_rc) >&2
88 fi
89 echo $host_CHID > $dev/wusb_chid 83 echo $host_CHID > $dev/wusb_chid
90 echo I: started host $(basename $dev) >&2 84 echo I: started host $(basename $dev) >&2
91 done 85 done
@@ -95,9 +89,6 @@ case $1 in
95 do 89 do
96 echo 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > $dev/wusb_chid 90 echo 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > $dev/wusb_chid
97 echo I: stopped host $(basename $dev) >&2 91 echo I: stopped host $(basename $dev) >&2
98 uwb_rc=$(readlink -f $dev/uwb_rc)
99 echo -1 | cat > $uwb_rc/beacon
100 echo I: stopped beaconing on $(basename $uwb_rc) >&2
101 done 92 done
102 ;; 93 ;;
103 set-chid) 94 set-chid)
diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c
index 64be4d88df1..2a4d36fa70b 100644
--- a/drivers/usb/host/hwa-hc.c
+++ b/drivers/usb/host/hwa-hc.c
@@ -54,7 +54,6 @@
54 * DWA). 54 * DWA).
55 */ 55 */
56#include <linux/kernel.h> 56#include <linux/kernel.h>
57#include <linux/version.h>
58#include <linux/init.h> 57#include <linux/init.h>
59#include <linux/module.h> 58#include <linux/module.h>
60#include <linux/workqueue.h> 59#include <linux/workqueue.h>
@@ -171,11 +170,6 @@ static int hwahc_op_start(struct usb_hcd *usb_hcd)
171 if (result < 0) 170 if (result < 0)
172 goto error_set_cluster_id; 171 goto error_set_cluster_id;
173 172
174 result = wa_nep_arm(&hwahc->wa, GFP_KERNEL);
175 if (result < 0) {
176 dev_err(dev, "cannot listen to notifications: %d\n", result);
177 goto error_stop;
178 }
179 usb_hcd->uses_new_polling = 1; 173 usb_hcd->uses_new_polling = 1;
180 usb_hcd->poll_rh = 1; 174 usb_hcd->poll_rh = 1;
181 usb_hcd->state = HC_STATE_RUNNING; 175 usb_hcd->state = HC_STATE_RUNNING;
@@ -185,8 +179,6 @@ out:
185 d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result); 179 d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result);
186 return result; 180 return result;
187 181
188error_stop:
189 __wa_stop(&hwahc->wa);
190error_set_cluster_id: 182error_set_cluster_id:
191 wusb_cluster_id_put(wusbhc->cluster_id); 183 wusb_cluster_id_put(wusbhc->cluster_id);
192error_cluster_id_get: 184error_cluster_id_get:
@@ -194,39 +186,6 @@ error_cluster_id_get:
194 186
195} 187}
196 188
197/*
198 * FIXME: break this function up
199 */
200static int __hwahc_op_wusbhc_start(struct wusbhc *wusbhc)
201{
202 int result;
203 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
204 struct device *dev = &hwahc->wa.usb_iface->dev;
205
206 /* Set up a Host Info WUSB Information Element */
207 d_fnstart(4, dev, "(hwahc %p)\n", hwahc);
208 result = -ENOSPC;
209
210 result = __wa_set_feature(&hwahc->wa, WA_ENABLE);
211 if (result < 0) {
212 dev_err(dev, "error commanding HC to start: %d\n", result);
213 goto error_stop;
214 }
215 result = __wa_wait_status(&hwahc->wa, WA_ENABLE, WA_ENABLE);
216 if (result < 0) {
217 dev_err(dev, "error waiting for HC to start: %d\n", result);
218 goto error_stop;
219 }
220 result = 0;
221out:
222 d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result);
223 return result;
224
225error_stop:
226 result = __wa_clear_feature(&hwahc->wa, WA_ENABLE);
227 goto out;
228}
229
230static int hwahc_op_suspend(struct usb_hcd *usb_hcd, pm_message_t msg) 189static int hwahc_op_suspend(struct usb_hcd *usb_hcd, pm_message_t msg)
231{ 190{
232 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); 191 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
@@ -246,18 +205,6 @@ static int hwahc_op_resume(struct usb_hcd *usb_hcd)
246 return -ENOSYS; 205 return -ENOSYS;
247} 206}
248 207
249static void __hwahc_op_wusbhc_stop(struct wusbhc *wusbhc)
250{
251 int result;
252 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
253 struct device *dev = &hwahc->wa.usb_iface->dev;
254
255 d_fnstart(4, dev, "(hwahc %p)\n", hwahc);
256 /* Nothing for now */
257 d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result);
258 return;
259}
260
261/* 208/*
262 * No need to abort pipes, as when this is called, all the children 209 * No need to abort pipes, as when this is called, all the children
263 * has been disconnected and that has done it [through 210 * has been disconnected and that has done it [through
@@ -274,9 +221,6 @@ static void hwahc_op_stop(struct usb_hcd *usb_hcd)
274 221
275 d_fnstart(4, dev, "(hwahc %p)\n", hwahc); 222 d_fnstart(4, dev, "(hwahc %p)\n", hwahc);
276 mutex_lock(&wusbhc->mutex); 223 mutex_lock(&wusbhc->mutex);
277 wusbhc_stop(wusbhc);
278 wa_nep_disarm(&hwahc->wa);
279 result = __wa_stop(&hwahc->wa);
280 wusb_cluster_id_put(wusbhc->cluster_id); 224 wusb_cluster_id_put(wusbhc->cluster_id);
281 mutex_unlock(&wusbhc->mutex); 225 mutex_unlock(&wusbhc->mutex);
282 d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result); 226 d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result);
@@ -325,6 +269,54 @@ static void hwahc_op_endpoint_disable(struct usb_hcd *usb_hcd,
325 rpipe_ep_disable(&hwahc->wa, ep); 269 rpipe_ep_disable(&hwahc->wa, ep);
326} 270}
327 271
272static int __hwahc_op_wusbhc_start(struct wusbhc *wusbhc)
273{
274 int result;
275 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
276 struct device *dev = &hwahc->wa.usb_iface->dev;
277
278 result = __wa_set_feature(&hwahc->wa, WA_ENABLE);
279 if (result < 0) {
280 dev_err(dev, "error commanding HC to start: %d\n", result);
281 goto error_stop;
282 }
283 result = __wa_wait_status(&hwahc->wa, WA_ENABLE, WA_ENABLE);
284 if (result < 0) {
285 dev_err(dev, "error waiting for HC to start: %d\n", result);
286 goto error_stop;
287 }
288 result = wa_nep_arm(&hwahc->wa, GFP_KERNEL);
289 if (result < 0) {
290 dev_err(dev, "cannot listen to notifications: %d\n", result);
291 goto error_stop;
292 }
293 return result;
294
295error_stop:
296 __wa_clear_feature(&hwahc->wa, WA_ENABLE);
297 return result;
298}
299
300static void __hwahc_op_wusbhc_stop(struct wusbhc *wusbhc, int delay)
301{
302 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
303 struct wahc *wa = &hwahc->wa;
304 u8 iface_no = wa->usb_iface->cur_altsetting->desc.bInterfaceNumber;
305 int ret;
306
307 ret = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
308 WUSB_REQ_CHAN_STOP,
309 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
310 delay * 1000,
311 iface_no,
312 NULL, 0, 1000 /* FIXME: arbitrary */);
313 if (ret == 0)
314 msleep(delay);
315
316 wa_nep_disarm(&hwahc->wa);
317 __wa_stop(&hwahc->wa);
318}
319
328/* 320/*
329 * Set the UWB MAS allocation for the WUSB cluster 321 * Set the UWB MAS allocation for the WUSB cluster
330 * 322 *
diff --git a/drivers/usb/host/whci/hcd.c b/drivers/usb/host/whci/hcd.c
index ef3ad4dca94..f599f89d3be 100644
--- a/drivers/usb/host/whci/hcd.c
+++ b/drivers/usb/host/whci/hcd.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/init.h> 19#include <linux/init.h>
21#include <linux/uwb/umc.h> 20#include <linux/uwb/umc.h>
@@ -92,8 +91,6 @@ static void whc_stop(struct usb_hcd *usb_hcd)
92 91
93 mutex_lock(&wusbhc->mutex); 92 mutex_lock(&wusbhc->mutex);
94 93
95 wusbhc_stop(wusbhc);
96
97 /* stop HC */ 94 /* stop HC */
98 le_writel(0, whc->base + WUSBINTR); 95 le_writel(0, whc->base + WUSBINTR);
99 whc_write_wusbcmd(whc, WUSBCMD_RUN, 0); 96 whc_write_wusbcmd(whc, WUSBCMD_RUN, 0);
diff --git a/drivers/usb/host/whci/hw.c b/drivers/usb/host/whci/hw.c
index ac86e59c122..d498e720321 100644
--- a/drivers/usb/host/whci/hw.c
+++ b/drivers/usb/host/whci/hw.c
@@ -50,6 +50,7 @@ int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len)
50 unsigned long flags; 50 unsigned long flags;
51 dma_addr_t dma_addr; 51 dma_addr_t dma_addr;
52 int t; 52 int t;
53 int ret = 0;
53 54
54 mutex_lock(&whc->mutex); 55 mutex_lock(&whc->mutex);
55 56
@@ -61,7 +62,8 @@ int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len)
61 dev_err(&whc->umc->dev, "generic command timeout (%04x/%04x)\n", 62 dev_err(&whc->umc->dev, "generic command timeout (%04x/%04x)\n",
62 le_readl(whc->base + WUSBGENCMDSTS), 63 le_readl(whc->base + WUSBGENCMDSTS),
63 le_readl(whc->base + WUSBGENCMDPARAMS)); 64 le_readl(whc->base + WUSBGENCMDPARAMS));
64 return -ETIMEDOUT; 65 ret = -ETIMEDOUT;
66 goto out;
65 } 67 }
66 68
67 if (addr) { 69 if (addr) {
@@ -80,8 +82,8 @@ int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len)
80 whc->base + WUSBGENCMDSTS); 82 whc->base + WUSBGENCMDSTS);
81 83
82 spin_unlock_irqrestore(&whc->lock, flags); 84 spin_unlock_irqrestore(&whc->lock, flags);
83 85out:
84 mutex_unlock(&whc->mutex); 86 mutex_unlock(&whc->mutex);
85 87
86 return 0; 88 return ret;
87} 89}
diff --git a/drivers/usb/host/whci/int.c b/drivers/usb/host/whci/int.c
index fce01174aa9..6aae7002810 100644
--- a/drivers/usb/host/whci/int.c
+++ b/drivers/usb/host/whci/int.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/init.h> 19#include <linux/init.h>
21#include <linux/uwb/umc.h> 20#include <linux/uwb/umc.h>
diff --git a/drivers/usb/host/whci/whcd.h b/drivers/usb/host/whci/whcd.h
index 1d2a53bd39f..1bbb8cb6bf8 100644
--- a/drivers/usb/host/whci/whcd.h
+++ b/drivers/usb/host/whci/whcd.h
@@ -136,7 +136,7 @@ int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len);
136 136
137/* wusb.c */ 137/* wusb.c */
138int whc_wusbhc_start(struct wusbhc *wusbhc); 138int whc_wusbhc_start(struct wusbhc *wusbhc);
139void whc_wusbhc_stop(struct wusbhc *wusbhc); 139void whc_wusbhc_stop(struct wusbhc *wusbhc, int delay);
140int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt, 140int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt,
141 u8 handle, struct wuie_hdr *wuie); 141 u8 handle, struct wuie_hdr *wuie);
142int whc_mmcie_rm(struct wusbhc *wusbhc, u8 handle); 142int whc_mmcie_rm(struct wusbhc *wusbhc, u8 handle);
diff --git a/drivers/usb/host/whci/whci-hc.h b/drivers/usb/host/whci/whci-hc.h
index bff1eb7a35c..51df7e313b3 100644
--- a/drivers/usb/host/whci/whci-hc.h
+++ b/drivers/usb/host/whci/whci-hc.h
@@ -410,6 +410,8 @@ struct dn_buf_entry {
410# define WUSBDNTSCTRL_SLOTS(s) ((s) << 0) 410# define WUSBDNTSCTRL_SLOTS(s) ((s) << 0)
411 411
412#define WUSBTIME 0x68 412#define WUSBTIME 0x68
413# define WUSBTIME_CHANNEL_TIME_MASK 0x00ffffff
414
413#define WUSBBPST 0x6c 415#define WUSBBPST 0x6c
414#define WUSBDIBUPDATED 0x70 416#define WUSBDIBUPDATED 0x70
415 417
diff --git a/drivers/usb/host/whci/wusb.c b/drivers/usb/host/whci/wusb.c
index 66e4ddcd961..540021a0971 100644
--- a/drivers/usb/host/whci/wusb.c
+++ b/drivers/usb/host/whci/wusb.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/init.h> 19#include <linux/init.h>
21#include <linux/uwb/umc.h> 20#include <linux/uwb/umc.h>
@@ -64,8 +63,9 @@ static int whc_update_di(struct whc *whc, int idx)
64} 63}
65 64
66/* 65/*
67 * WHCI starts and stops MMCs based on there being a valid GTK so 66 * WHCI starts MMCs based on there being a valid GTK so these need
68 * these need only start/stop the asynchronous and periodic schedules. 67 * only start/stop the asynchronous and periodic schedules and send a
68 * channel stop command.
69 */ 69 */
70 70
71int whc_wusbhc_start(struct wusbhc *wusbhc) 71int whc_wusbhc_start(struct wusbhc *wusbhc)
@@ -78,12 +78,20 @@ int whc_wusbhc_start(struct wusbhc *wusbhc)
78 return 0; 78 return 0;
79} 79}
80 80
81void whc_wusbhc_stop(struct wusbhc *wusbhc) 81void whc_wusbhc_stop(struct wusbhc *wusbhc, int delay)
82{ 82{
83 struct whc *whc = wusbhc_to_whc(wusbhc); 83 struct whc *whc = wusbhc_to_whc(wusbhc);
84 u32 stop_time, now_time;
85 int ret;
84 86
85 pzl_stop(whc); 87 pzl_stop(whc);
86 asl_stop(whc); 88 asl_stop(whc);
89
90 now_time = le_readl(whc->base + WUSBTIME) & WUSBTIME_CHANNEL_TIME_MASK;
91 stop_time = (now_time + ((delay * 8) << 7)) & 0x00ffffff;
92 ret = whc_do_gencmd(whc, WUSBGENCMDSTS_CHAN_STOP, stop_time, NULL, 0);
93 if (ret == 0)
94 msleep(delay);
87} 95}
88 96
89int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt, 97int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt,
diff --git a/drivers/usb/wusbcore/cbaf.c b/drivers/usb/wusbcore/cbaf.c
index ab4788d1785..1335cbe1191 100644
--- a/drivers/usb/wusbcore/cbaf.c
+++ b/drivers/usb/wusbcore/cbaf.c
@@ -88,7 +88,6 @@
88 */ 88 */
89#include <linux/module.h> 89#include <linux/module.h>
90#include <linux/ctype.h> 90#include <linux/ctype.h>
91#include <linux/version.h>
92#include <linux/usb.h> 91#include <linux/usb.h>
93#include <linux/interrupt.h> 92#include <linux/interrupt.h>
94#include <linux/delay.h> 93#include <linux/delay.h>
diff --git a/drivers/usb/wusbcore/crypto.c b/drivers/usb/wusbcore/crypto.c
index c36c4389baa..0ca860305fe 100644
--- a/drivers/usb/wusbcore/crypto.c
+++ b/drivers/usb/wusbcore/crypto.c
@@ -54,6 +54,10 @@
54#define D_LOCAL 0 54#define D_LOCAL 0
55#include <linux/uwb/debug.h> 55#include <linux/uwb/debug.h>
56 56
57static int debug_crypto_verify = 0;
58
59module_param(debug_crypto_verify, int, 0);
60MODULE_PARM_DESC(debug_crypto_verify, "verify the key generation algorithms");
57 61
58/* 62/*
59 * Block of data, as understood by AES-CCM 63 * Block of data, as understood by AES-CCM
@@ -526,10 +530,13 @@ int wusb_crypto_init(void)
526{ 530{
527 int result; 531 int result;
528 532
529 result = wusb_key_derive_verify(); 533 if (debug_crypto_verify) {
530 if (result < 0) 534 result = wusb_key_derive_verify();
531 return result; 535 if (result < 0)
532 return wusb_oob_mic_verify(); 536 return result;
537 return wusb_oob_mic_verify();
538 }
539 return 0;
533} 540}
534 541
535void wusb_crypto_exit(void) 542void wusb_crypto_exit(void)
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c
index f45d777bef3..08a1ec90386 100644
--- a/drivers/usb/wusbcore/devconnect.c
+++ b/drivers/usb/wusbcore/devconnect.c
@@ -57,9 +57,6 @@
57 * Called by notif.c:wusb_handle_dn_connect() 57 * Called by notif.c:wusb_handle_dn_connect()
58 * when a DN_Connect is received. 58 * when a DN_Connect is received.
59 * 59 *
60 * wusbhc_devconnect_auth() Called by rh.c:wusbhc_rh_port_reset() when
61 * doing the device connect sequence.
62 *
63 * wusb_devconnect_acked() Ack done, release resources. 60 * wusb_devconnect_acked() Ack done, release resources.
64 * 61 *
65 * wusb_handle_dn_alive() Called by notif.c:wusb_handle_dn() 62 * wusb_handle_dn_alive() Called by notif.c:wusb_handle_dn()
@@ -69,9 +66,6 @@
69 * process a disconenct request from a 66 * process a disconenct request from a
70 * device. 67 * device.
71 * 68 *
72 * wusb_dev_reset() Called by rh.c:wusbhc_rh_port_reset() when
73 * resetting a device.
74 *
75 * __wusb_dev_disable() Called by rh.c:wusbhc_rh_clear_port_feat() when 69 * __wusb_dev_disable() Called by rh.c:wusbhc_rh_clear_port_feat() when
76 * disabling a port. 70 * disabling a port.
77 * 71 *
@@ -366,12 +360,10 @@ void wusbhc_devconnect_ack(struct wusbhc *wusbhc, struct wusb_dn_connect *dnc,
366 port->wusb_dev = wusb_dev; 360 port->wusb_dev = wusb_dev;
367 port->status |= USB_PORT_STAT_CONNECTION; 361 port->status |= USB_PORT_STAT_CONNECTION;
368 port->change |= USB_PORT_STAT_C_CONNECTION; 362 port->change |= USB_PORT_STAT_C_CONNECTION;
369 port->reset_count = 0;
370 /* Now the port status changed to connected; khubd will 363 /* Now the port status changed to connected; khubd will
371 * pick the change up and try to reset the port to bring it to 364 * pick the change up and try to reset the port to bring it to
372 * the enabled state--so this process returns up to the stack 365 * the enabled state--so this process returns up to the stack
373 * and it calls back into wusbhc_rh_port_reset() who will call 366 * and it calls back into wusbhc_rh_port_reset().
374 * devconnect_auth().
375 */ 367 */
376error_unlock: 368error_unlock:
377 mutex_unlock(&wusbhc->mutex); 369 mutex_unlock(&wusbhc->mutex);
@@ -413,9 +405,6 @@ static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc,
413 wusb_dev_put(wusb_dev); 405 wusb_dev_put(wusb_dev);
414 } 406 }
415 port->wusb_dev = NULL; 407 port->wusb_dev = NULL;
416 /* don't reset the reset_count to zero or wusbhc_rh_port_reset will get
417 * confused! We only reset to zero when we connect a new device.
418 */
419 408
420 /* After a device disconnects, change the GTK (see [WUSB] 409 /* After a device disconnects, change the GTK (see [WUSB]
421 * section 6.2.11.2). */ 410 * section 6.2.11.2). */
@@ -429,39 +418,6 @@ static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc,
429} 418}
430 419
431/* 420/*
432 * Authenticate a device into the WUSB Cluster
433 *
434 * Called from the Root Hub code (rh.c:wusbhc_rh_port_reset()) when
435 * asking for a reset on a port that is not enabled (ie: first connect
436 * on the port).
437 *
438 * Performs the 4way handshake to allow the device to comunicate w/ the
439 * WUSB Cluster securely; once done, issue a request to the device for
440 * it to change to address 0.
441 *
442 * This mimics the reset step of Wired USB that once resetting a
443 * device, leaves the port in enabled state and the dev with the
444 * default address (0).
445 *
446 * WUSB1.0[7.1.2]
447 *
448 * @port_idx: port where the change happened--This is the index into
449 * the wusbhc port array, not the USB port number.
450 */
451int wusbhc_devconnect_auth(struct wusbhc *wusbhc, u8 port_idx)
452{
453 struct device *dev = wusbhc->dev;
454 struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx);
455
456 d_fnstart(3, dev, "(%p, %u)\n", wusbhc, port_idx);
457 port->status &= ~USB_PORT_STAT_RESET;
458 port->status |= USB_PORT_STAT_ENABLE;
459 port->change |= USB_PORT_STAT_C_RESET | USB_PORT_STAT_C_ENABLE;
460 d_fnend(3, dev, "(%p, %u) = 0\n", wusbhc, port_idx);
461 return 0;
462}
463
464/*
465 * Refresh the list of keep alives to emit in the MMC 421 * Refresh the list of keep alives to emit in the MMC
466 * 422 *
467 * Some devices don't respond to keep alives unless they've been 423 * Some devices don't respond to keep alives unless they've been
@@ -662,60 +618,6 @@ static void wusbhc_handle_dn_disconnect(struct wusbhc *wusbhc, struct wusb_dev *
662} 618}
663 619
664/* 620/*
665 * Reset a WUSB device on a HWA
666 *
667 * @wusbhc
668 * @port_idx Index of the port where the device is
669 *
670 * In Wireless USB, a reset is more or less equivalent to a full
671 * disconnect; so we just do a full disconnect and send the device a
672 * Device Reset IE (WUSB1.0[7.5.11]) giving it a few millisecs (6 MMCs).
673 *
674 * @wusbhc should be refcounted and unlocked
675 */
676int wusbhc_dev_reset(struct wusbhc *wusbhc, u8 port_idx)
677{
678 int result;
679 struct device *dev = wusbhc->dev;
680 struct wusb_dev *wusb_dev;
681 struct wuie_reset *ie;
682
683 d_fnstart(3, dev, "(%p, %u)\n", wusbhc, port_idx);
684 mutex_lock(&wusbhc->mutex);
685 result = 0;
686 wusb_dev = wusb_port_by_idx(wusbhc, port_idx)->wusb_dev;
687 if (wusb_dev == NULL) {
688 /* reset no device? ignore */
689 dev_dbg(dev, "RESET: no device at port %u, ignoring\n",
690 port_idx);
691 goto error_unlock;
692 }
693 result = -ENOMEM;
694 ie = kzalloc(sizeof(*ie), GFP_KERNEL);
695 if (ie == NULL)
696 goto error_unlock;
697 ie->hdr.bLength = sizeof(ie->hdr) + sizeof(ie->CDID);
698 ie->hdr.bIEIdentifier = WUIE_ID_RESET_DEVICE;
699 ie->CDID = wusb_dev->cdid;
700 result = wusbhc_mmcie_set(wusbhc, 0xff, 6, &ie->hdr);
701 if (result < 0) {
702 dev_err(dev, "RESET: cant's set MMC: %d\n", result);
703 goto error_kfree;
704 }
705 __wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, port_idx));
706
707 /* 120ms, hopefully 6 MMCs (FIXME) */
708 msleep(120);
709 wusbhc_mmcie_rm(wusbhc, &ie->hdr);
710error_kfree:
711 kfree(ie);
712error_unlock:
713 mutex_unlock(&wusbhc->mutex);
714 d_fnend(3, dev, "(%p, %u) = %d\n", wusbhc, port_idx, result);
715 return result;
716}
717
718/*
719 * Handle a Device Notification coming a host 621 * Handle a Device Notification coming a host
720 * 622 *
721 * The Device Notification comes from a host (HWA, DWA or WHCI) 623 * The Device Notification comes from a host (HWA, DWA or WHCI)
@@ -1222,8 +1124,7 @@ void wusbhc_devconnect_destroy(struct wusbhc *wusbhc)
1222 * FIXME: This also enables the keep alives but this is not necessary 1124 * FIXME: This also enables the keep alives but this is not necessary
1223 * until there are connected and authenticated devices. 1125 * until there are connected and authenticated devices.
1224 */ 1126 */
1225int wusbhc_devconnect_start(struct wusbhc *wusbhc, 1127int wusbhc_devconnect_start(struct wusbhc *wusbhc)
1226 const struct wusb_ckhdid *chid)
1227{ 1128{
1228 struct device *dev = wusbhc->dev; 1129 struct device *dev = wusbhc->dev;
1229 struct wuie_host_info *hi; 1130 struct wuie_host_info *hi;
@@ -1236,7 +1137,7 @@ int wusbhc_devconnect_start(struct wusbhc *wusbhc,
1236 hi->hdr.bLength = sizeof(*hi); 1137 hi->hdr.bLength = sizeof(*hi);
1237 hi->hdr.bIEIdentifier = WUIE_ID_HOST_INFO; 1138 hi->hdr.bIEIdentifier = WUIE_ID_HOST_INFO;
1238 hi->attributes = cpu_to_le16((wusbhc->rsv->stream << 3) | WUIE_HI_CAP_ALL); 1139 hi->attributes = cpu_to_le16((wusbhc->rsv->stream << 3) | WUIE_HI_CAP_ALL);
1239 hi->CHID = *chid; 1140 hi->CHID = wusbhc->chid;
1240 result = wusbhc_mmcie_set(wusbhc, 0, 0, &hi->hdr); 1141 result = wusbhc_mmcie_set(wusbhc, 0, 0, &hi->hdr);
1241 if (result < 0) { 1142 if (result < 0) {
1242 dev_err(dev, "Cannot add Host Info MMCIE: %d\n", result); 1143 dev_err(dev, "Cannot add Host Info MMCIE: %d\n", result);
diff --git a/drivers/usb/wusbcore/mmc.c b/drivers/usb/wusbcore/mmc.c
index cfa77a01ceb..5463ecebafd 100644
--- a/drivers/usb/wusbcore/mmc.c
+++ b/drivers/usb/wusbcore/mmc.c
@@ -162,12 +162,11 @@ EXPORT_SYMBOL_GPL(wusbhc_mmcie_rm);
162/* 162/*
163 * wusbhc_start - start transmitting MMCs and accepting connections 163 * wusbhc_start - start transmitting MMCs and accepting connections
164 * @wusbhc: the HC to start 164 * @wusbhc: the HC to start
165 * @chid: the CHID to use for this host
166 * 165 *
167 * Establishes a cluster reservation, enables device connections, and 166 * Establishes a cluster reservation, enables device connections, and
168 * starts MMCs with appropriate DNTS parameters. 167 * starts MMCs with appropriate DNTS parameters.
169 */ 168 */
170int wusbhc_start(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid) 169int wusbhc_start(struct wusbhc *wusbhc)
171{ 170{
172 int result; 171 int result;
173 struct device *dev = wusbhc->dev; 172 struct device *dev = wusbhc->dev;
@@ -181,7 +180,7 @@ int wusbhc_start(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid)
181 goto error_rsv_establish; 180 goto error_rsv_establish;
182 } 181 }
183 182
184 result = wusbhc_devconnect_start(wusbhc, chid); 183 result = wusbhc_devconnect_start(wusbhc);
185 if (result < 0) { 184 if (result < 0) {
186 dev_err(dev, "error enabling device connections: %d\n", result); 185 dev_err(dev, "error enabling device connections: %d\n", result);
187 goto error_devconnect_start; 186 goto error_devconnect_start;
@@ -219,49 +218,17 @@ error_rsv_establish:
219} 218}
220 219
221/* 220/*
222 * Disconnect all from the WUSB Channel
223 *
224 * Send a Host Disconnect IE in the MMC, wait, don't send it any more
225 */
226static int __wusbhc_host_disconnect_ie(struct wusbhc *wusbhc)
227{
228 int result = -ENOMEM;
229 struct wuie_host_disconnect *host_disconnect_ie;
230 might_sleep();
231 host_disconnect_ie = kmalloc(sizeof(*host_disconnect_ie), GFP_KERNEL);
232 if (host_disconnect_ie == NULL)
233 goto error_alloc;
234 host_disconnect_ie->hdr.bLength = sizeof(*host_disconnect_ie);
235 host_disconnect_ie->hdr.bIEIdentifier = WUIE_ID_HOST_DISCONNECT;
236 result = wusbhc_mmcie_set(wusbhc, 0, 0, &host_disconnect_ie->hdr);
237 if (result < 0)
238 goto error_mmcie_set;
239
240 /* WUSB1.0[8.5.3.1 & 7.5.2] */
241 msleep(100);
242 wusbhc_mmcie_rm(wusbhc, &host_disconnect_ie->hdr);
243error_mmcie_set:
244 kfree(host_disconnect_ie);
245error_alloc:
246 return result;
247}
248
249/*
250 * wusbhc_stop - stop transmitting MMCs 221 * wusbhc_stop - stop transmitting MMCs
251 * @wusbhc: the HC to stop 222 * @wusbhc: the HC to stop
252 * 223 *
253 * Send a Host Disconnect IE, wait, remove all the MMCs (stop sending MMCs). 224 * Stops the WUSB channel and removes the cluster reservation.
254 *
255 * If we can't allocate a Host Stop IE, screw it, we don't notify the
256 * devices we are disconnecting...
257 */ 225 */
258void wusbhc_stop(struct wusbhc *wusbhc) 226void wusbhc_stop(struct wusbhc *wusbhc)
259{ 227{
260 if (wusbhc->active) { 228 if (wusbhc->active) {
261 wusbhc->active = 0; 229 wusbhc->active = 0;
262 wusbhc->stop(wusbhc); 230 wusbhc->stop(wusbhc, WUSB_CHANNEL_STOP_DELAY_MS);
263 wusbhc_sec_stop(wusbhc); 231 wusbhc_sec_stop(wusbhc);
264 __wusbhc_host_disconnect_ie(wusbhc);
265 wusbhc_devconnect_stop(wusbhc); 232 wusbhc_devconnect_stop(wusbhc);
266 wusbhc_rsv_terminate(wusbhc); 233 wusbhc_rsv_terminate(wusbhc);
267 } 234 }
@@ -269,29 +236,6 @@ void wusbhc_stop(struct wusbhc *wusbhc)
269EXPORT_SYMBOL_GPL(wusbhc_stop); 236EXPORT_SYMBOL_GPL(wusbhc_stop);
270 237
271/* 238/*
272 * Change the CHID in a WUSB Channel
273 *
274 * If it is just a new CHID, send a Host Disconnect IE and then change
275 * the CHID IE.
276 */
277static int __wusbhc_chid_change(struct wusbhc *wusbhc,
278 const struct wusb_ckhdid *chid)
279{
280 int result = -ENOSYS;
281 struct device *dev = wusbhc->dev;
282 dev_err(dev, "%s() not implemented yet\n", __func__);
283 return result;
284
285 BUG_ON(wusbhc->wuie_host_info == NULL);
286 __wusbhc_host_disconnect_ie(wusbhc);
287 wusbhc->wuie_host_info->CHID = *chid;
288 result = wusbhc_mmcie_set(wusbhc, 0, 0, &wusbhc->wuie_host_info->hdr);
289 if (result < 0)
290 dev_err(dev, "Can't update Host Info WUSB IE: %d\n", result);
291 return result;
292}
293
294/*
295 * Set/reset/update a new CHID 239 * Set/reset/update a new CHID
296 * 240 *
297 * Depending on the previous state of the MMCs, start, stop or change 241 * Depending on the previous state of the MMCs, start, stop or change
@@ -306,16 +250,19 @@ int wusbhc_chid_set(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid)
306 chid = NULL; 250 chid = NULL;
307 251
308 mutex_lock(&wusbhc->mutex); 252 mutex_lock(&wusbhc->mutex);
309 if (wusbhc->active) { 253 if (chid) {
310 if (chid) 254 if (wusbhc->active) {
311 result = __wusbhc_chid_change(wusbhc, chid); 255 mutex_unlock(&wusbhc->mutex);
312 else 256 return -EBUSY;
313 wusbhc_stop(wusbhc); 257 }
314 } else { 258 wusbhc->chid = *chid;
315 if (chid)
316 wusbhc_start(wusbhc, chid);
317 } 259 }
318 mutex_unlock(&wusbhc->mutex); 260 mutex_unlock(&wusbhc->mutex);
261
262 if (chid)
263 result = uwb_radio_start(&wusbhc->pal);
264 else
265 uwb_radio_stop(&wusbhc->pal);
319 return result; 266 return result;
320} 267}
321EXPORT_SYMBOL_GPL(wusbhc_chid_set); 268EXPORT_SYMBOL_GPL(wusbhc_chid_set);
diff --git a/drivers/usb/wusbcore/pal.c b/drivers/usb/wusbcore/pal.c
index 7cc51e9905c..d0b172c5ecc 100644
--- a/drivers/usb/wusbcore/pal.c
+++ b/drivers/usb/wusbcore/pal.c
@@ -18,6 +18,16 @@
18 */ 18 */
19#include "wusbhc.h" 19#include "wusbhc.h"
20 20
21static void wusbhc_channel_changed(struct uwb_pal *pal, int channel)
22{
23 struct wusbhc *wusbhc = container_of(pal, struct wusbhc, pal);
24
25 if (channel < 0)
26 wusbhc_stop(wusbhc);
27 else
28 wusbhc_start(wusbhc);
29}
30
21/** 31/**
22 * wusbhc_pal_register - register the WUSB HC as a UWB PAL 32 * wusbhc_pal_register - register the WUSB HC as a UWB PAL
23 * @wusbhc: the WUSB HC 33 * @wusbhc: the WUSB HC
@@ -28,8 +38,10 @@ int wusbhc_pal_register(struct wusbhc *wusbhc)
28 38
29 wusbhc->pal.name = "wusbhc"; 39 wusbhc->pal.name = "wusbhc";
30 wusbhc->pal.device = wusbhc->usb_hcd.self.controller; 40 wusbhc->pal.device = wusbhc->usb_hcd.self.controller;
41 wusbhc->pal.rc = wusbhc->uwb_rc;
42 wusbhc->pal.channel_changed = wusbhc_channel_changed;
31 43
32 return uwb_pal_register(wusbhc->uwb_rc, &wusbhc->pal); 44 return uwb_pal_register(&wusbhc->pal);
33} 45}
34 46
35/** 47/**
@@ -38,5 +50,5 @@ int wusbhc_pal_register(struct wusbhc *wusbhc)
38 */ 50 */
39void wusbhc_pal_unregister(struct wusbhc *wusbhc) 51void wusbhc_pal_unregister(struct wusbhc *wusbhc)
40{ 52{
41 uwb_pal_unregister(wusbhc->uwb_rc, &wusbhc->pal); 53 uwb_pal_unregister(&wusbhc->pal);
42} 54}
diff --git a/drivers/usb/wusbcore/reservation.c b/drivers/usb/wusbcore/reservation.c
index fc63e77ded2..7b6525dac2f 100644
--- a/drivers/usb/wusbcore/reservation.c
+++ b/drivers/usb/wusbcore/reservation.c
@@ -59,7 +59,6 @@ static void wusbhc_rsv_complete_cb(struct uwb_rsv *rsv)
59 case UWB_RSV_STATE_NONE: 59 case UWB_RSV_STATE_NONE:
60 dev_dbg(dev, "removed reservation\n"); 60 dev_dbg(dev, "removed reservation\n");
61 wusbhc_bwa_set(wusbhc, 0, NULL); 61 wusbhc_bwa_set(wusbhc, 0, NULL);
62 wusbhc->rsv = NULL;
63 break; 62 break;
64 default: 63 default:
65 dev_dbg(dev, "unexpected reservation state: %d\n", rsv->state); 64 dev_dbg(dev, "unexpected reservation state: %d\n", rsv->state);
@@ -105,11 +104,11 @@ int wusbhc_rsv_establish(struct wusbhc *wusbhc)
105 104
106 105
107/** 106/**
108 * wusbhc_rsv_terminate - terminate any cluster reservation 107 * wusbhc_rsv_terminate - terminate the cluster reservation
109 * @wusbhc: the WUSB host whose reservation is to be terminated 108 * @wusbhc: the WUSB host whose reservation is to be terminated
110 */ 109 */
111void wusbhc_rsv_terminate(struct wusbhc *wusbhc) 110void wusbhc_rsv_terminate(struct wusbhc *wusbhc)
112{ 111{
113 if (wusbhc->rsv) 112 uwb_rsv_terminate(wusbhc->rsv);
114 uwb_rsv_terminate(wusbhc->rsv); 113 uwb_rsv_destroy(wusbhc->rsv);
115} 114}
diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c
index 267a6432510..1c733192ec2 100644
--- a/drivers/usb/wusbcore/rh.c
+++ b/drivers/usb/wusbcore/rh.c
@@ -77,13 +77,17 @@
77/* 77/*
78 * Reset a fake port 78 * Reset a fake port
79 * 79 *
80 * This can be called to reset a port from any other state or to reset 80 * Using a Reset Device IE is too heavyweight as it causes the device
81 * it when connecting. In Wireless USB they are different; when doing 81 * to enter the UnConnected state and leave the cluster, this can mean
82 * a new connect that involves going over the authentication. When 82 * that when the device reconnects it is connected to a different fake
83 * just reseting, its a different story. 83 * port.
84 * 84 *
85 * The Linux USB stack resets a port twice before it considers it 85 * Instead, reset authenticated devices with a SetAddress(0), followed
86 * enabled, so we have to detect and ignore that. 86 * by a SetAddresss(AuthAddr).
87 *
88 * For unauthenticated devices just pretend to reset but do nothing.
89 * If the device initialization continues to fail it will eventually
90 * time out after TrustTimeout and enter the UnConnected state.
87 * 91 *
88 * @wusbhc is assumed referenced and @wusbhc->mutex unlocked. 92 * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
89 * 93 *
@@ -97,20 +101,20 @@ static int wusbhc_rh_port_reset(struct wusbhc *wusbhc, u8 port_idx)
97{ 101{
98 int result = 0; 102 int result = 0;
99 struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx); 103 struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx);
104 struct wusb_dev *wusb_dev = port->wusb_dev;
105
106 port->status |= USB_PORT_STAT_RESET;
107 port->change |= USB_PORT_STAT_C_RESET;
100 108
101 d_fnstart(3, wusbhc->dev, "(wusbhc %p port_idx %u)\n", 109 if (wusb_dev->addr & WUSB_DEV_ADDR_UNAUTH)
102 wusbhc, port_idx); 110 result = 0;
103 if (port->reset_count == 0) {
104 wusbhc_devconnect_auth(wusbhc, port_idx);
105 port->reset_count++;
106 } else if (port->reset_count == 1)
107 /* see header */
108 d_printf(2, wusbhc->dev, "Ignoring second reset on port_idx "
109 "%u\n", port_idx);
110 else 111 else
111 result = wusbhc_dev_reset(wusbhc, port_idx); 112 result = wusb_dev_update_address(wusbhc, wusb_dev);
112 d_fnend(3, wusbhc->dev, "(wusbhc %p port_idx %u) = %d\n", 113
113 wusbhc, port_idx, result); 114 port->status &= ~USB_PORT_STAT_RESET;
115 port->status |= USB_PORT_STAT_ENABLE;
116 port->change |= USB_PORT_STAT_C_RESET | USB_PORT_STAT_C_ENABLE;
117
114 return result; 118 return result;
115} 119}
116 120
diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c
index a101cad6a8d..ac00640bba6 100644
--- a/drivers/usb/wusbcore/security.c
+++ b/drivers/usb/wusbcore/security.c
@@ -338,8 +338,7 @@ static void hs_printk(unsigned level, struct device *dev,
338 * Before the device's address (as known by it) was usb_dev->devnum | 338 * Before the device's address (as known by it) was usb_dev->devnum |
339 * 0x80 (unauthenticated address). With this we update it to usb_dev->devnum. 339 * 0x80 (unauthenticated address). With this we update it to usb_dev->devnum.
340 */ 340 */
341static int wusb_dev_update_address(struct wusbhc *wusbhc, 341int wusb_dev_update_address(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
342 struct wusb_dev *wusb_dev)
343{ 342{
344 int result = -ENOMEM; 343 int result = -ENOMEM;
345 struct usb_device *usb_dev = wusb_dev->usb_dev; 344 struct usb_device *usb_dev = wusb_dev->usb_dev;
diff --git a/drivers/usb/wusbcore/wusbhc.h b/drivers/usb/wusbcore/wusbhc.h
index d0c132434f1..797c2453a35 100644
--- a/drivers/usb/wusbcore/wusbhc.h
+++ b/drivers/usb/wusbcore/wusbhc.h
@@ -64,6 +64,13 @@
64#include <linux/uwb.h> 64#include <linux/uwb.h>
65#include <linux/usb/wusb.h> 65#include <linux/usb/wusb.h>
66 66
67/*
68 * Time from a WUSB channel stop request to the last transmitted MMC.
69 *
70 * This needs to be > 4.096 ms in case no MMCs can be transmitted in
71 * zone 0.
72 */
73#define WUSB_CHANNEL_STOP_DELAY_MS 8
67 74
68/** 75/**
69 * Wireless USB device 76 * Wireless USB device
@@ -147,7 +154,6 @@ struct wusb_port {
147 u16 status; 154 u16 status;
148 u16 change; 155 u16 change;
149 struct wusb_dev *wusb_dev; /* connected device's info */ 156 struct wusb_dev *wusb_dev; /* connected device's info */
150 unsigned reset_count;
151 u32 ptk_tkid; 157 u32 ptk_tkid;
152}; 158};
153 159
@@ -198,21 +204,18 @@ struct wusb_port {
198 * @mmcies_max Max number of Information Elements this HC can send 204 * @mmcies_max Max number of Information Elements this HC can send
199 * in its MMC. Read-only. 205 * in its MMC. Read-only.
200 * 206 *
207 * @start Start the WUSB channel.
208 *
209 * @stop Stop the WUSB channel after the specified number of
210 * milliseconds. Channel Stop IEs should be transmitted
211 * as required by [WUSB] 4.16.2.1.
212 *
201 * @mmcie_add HC specific operation (WHCI or HWA) for adding an 213 * @mmcie_add HC specific operation (WHCI or HWA) for adding an
202 * MMCIE. 214 * MMCIE.
203 * 215 *
204 * @mmcie_rm HC specific operation (WHCI or HWA) for removing an 216 * @mmcie_rm HC specific operation (WHCI or HWA) for removing an
205 * MMCIE. 217 * MMCIE.
206 * 218 *
207 * @enc_types Array which describes the encryptions methods
208 * supported by the host as described in WUSB1.0 --
209 * one entry per supported method. As of WUSB1.0 there
210 * is only four methods, we make space for eight just in
211 * case they decide to add some more (and pray they do
212 * it in sequential order). if 'enc_types[enc_method]
213 * != 0', then it is supported by the host. enc_method
214 * is USB_ENC_TYPE*.
215 *
216 * @set_ptk: Set the PTK and enable encryption for a device. Or, if 219 * @set_ptk: Set the PTK and enable encryption for a device. Or, if
217 * the supplied key is NULL, disable encryption for that 220 * the supplied key is NULL, disable encryption for that
218 * device. 221 * device.
@@ -249,7 +252,8 @@ struct wusbhc {
249 struct uwb_pal pal; 252 struct uwb_pal pal;
250 253
251 unsigned trust_timeout; /* in jiffies */ 254 unsigned trust_timeout; /* in jiffies */
252 struct wuie_host_info *wuie_host_info; /* Includes CHID */ 255 struct wusb_ckhdid chid;
256 struct wuie_host_info *wuie_host_info;
253 257
254 struct mutex mutex; /* locks everything else */ 258 struct mutex mutex; /* locks everything else */
255 u16 cluster_id; /* Wireless USB Cluster ID */ 259 u16 cluster_id; /* Wireless USB Cluster ID */
@@ -269,7 +273,7 @@ struct wusbhc {
269 u8 mmcies_max; 273 u8 mmcies_max;
270 /* FIXME: make wusbhc_ops? */ 274 /* FIXME: make wusbhc_ops? */
271 int (*start)(struct wusbhc *wusbhc); 275 int (*start)(struct wusbhc *wusbhc);
272 void (*stop)(struct wusbhc *wusbhc); 276 void (*stop)(struct wusbhc *wusbhc, int delay);
273 int (*mmcie_add)(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt, 277 int (*mmcie_add)(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt,
274 u8 handle, struct wuie_hdr *wuie); 278 u8 handle, struct wuie_hdr *wuie);
275 int (*mmcie_rm)(struct wusbhc *wusbhc, u8 handle); 279 int (*mmcie_rm)(struct wusbhc *wusbhc, u8 handle);
@@ -373,20 +377,17 @@ static inline void wusbhc_put(struct wusbhc *wusbhc)
373 usb_put_hcd(&wusbhc->usb_hcd); 377 usb_put_hcd(&wusbhc->usb_hcd);
374} 378}
375 379
376int wusbhc_start(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid); 380int wusbhc_start(struct wusbhc *wusbhc);
377void wusbhc_stop(struct wusbhc *wusbhc); 381void wusbhc_stop(struct wusbhc *wusbhc);
378extern int wusbhc_chid_set(struct wusbhc *, const struct wusb_ckhdid *); 382extern int wusbhc_chid_set(struct wusbhc *, const struct wusb_ckhdid *);
379 383
380/* Device connect handling */ 384/* Device connect handling */
381extern int wusbhc_devconnect_create(struct wusbhc *); 385extern int wusbhc_devconnect_create(struct wusbhc *);
382extern void wusbhc_devconnect_destroy(struct wusbhc *); 386extern void wusbhc_devconnect_destroy(struct wusbhc *);
383extern int wusbhc_devconnect_start(struct wusbhc *wusbhc, 387extern int wusbhc_devconnect_start(struct wusbhc *wusbhc);
384 const struct wusb_ckhdid *chid);
385extern void wusbhc_devconnect_stop(struct wusbhc *wusbhc); 388extern void wusbhc_devconnect_stop(struct wusbhc *wusbhc);
386extern int wusbhc_devconnect_auth(struct wusbhc *, u8);
387extern void wusbhc_handle_dn(struct wusbhc *, u8 srcaddr, 389extern void wusbhc_handle_dn(struct wusbhc *, u8 srcaddr,
388 struct wusb_dn_hdr *dn_hdr, size_t size); 390 struct wusb_dn_hdr *dn_hdr, size_t size);
389extern int wusbhc_dev_reset(struct wusbhc *wusbhc, u8 port);
390extern void __wusbhc_dev_disable(struct wusbhc *wusbhc, u8 port); 391extern void __wusbhc_dev_disable(struct wusbhc *wusbhc, u8 port);
391extern int wusb_usb_ncb(struct notifier_block *nb, unsigned long val, 392extern int wusb_usb_ncb(struct notifier_block *nb, unsigned long val,
392 void *priv); 393 void *priv);
@@ -432,6 +433,7 @@ extern void wusb_dev_sec_rm(struct wusb_dev *) ;
432extern int wusb_dev_4way_handshake(struct wusbhc *, struct wusb_dev *, 433extern int wusb_dev_4way_handshake(struct wusbhc *, struct wusb_dev *,
433 struct wusb_ckhdid *ck); 434 struct wusb_ckhdid *ck);
434void wusbhc_gtk_rekey(struct wusbhc *wusbhc); 435void wusbhc_gtk_rekey(struct wusbhc *wusbhc);
436int wusb_dev_update_address(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev);
435 437
436 438
437/* WUSB Cluster ID handling */ 439/* WUSB Cluster ID handling */
diff --git a/drivers/uwb/Makefile b/drivers/uwb/Makefile
index 257e6908304..ce21a95da04 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 46b18eec502..d9c60cb9499 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 521cdeb8497..f57c26580de 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 882724c5f12..75491d47806 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 c0b1e5e2bd0..fe328146adb 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 3d26fa0f8ae..158e98d08af 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 98eeeff051a..b7ea525fc06 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 737d60cd5b7..488b2e30a0a 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 8802ac43d87..2eafb973cd0 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 a1d8ca6ac93..a92a787725f 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 00000000000..917e6d78a79
--- /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 cf6f3d152b9..ab976686175 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 ee5772f00d4..9cf21e6bb62 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 9b4eb64327a..48b4ece1a62 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 1afb38eacb9..605765124f5 100644
--- a/drivers/uwb/pal.c
+++ b/drivers/uwb/pal.c
@@ -32,13 +32,13 @@ EXPORT_SYMBOL_GPL(uwb_pal_init);
32 32
33/** 33/**
34 * uwb_pal_register - register a UWB PAL 34 * uwb_pal_register - register a UWB PAL
35 * @rc: the radio controller the PAL will be using
36 * @pal: the PAL 35 * @pal: the PAL
37 * 36 *
38 * The PAL must be initialized with uwb_pal_init(). 37 * The PAL must be initialized with uwb_pal_init().
39 */ 38 */
40int uwb_pal_register(struct uwb_rc *rc, struct uwb_pal *pal) 39int uwb_pal_register(struct uwb_pal *pal)
41{ 40{
41 struct uwb_rc *rc = pal->rc;
42 int ret; 42 int ret;
43 43
44 if (pal->device) { 44 if (pal->device) {
@@ -54,9 +54,9 @@ int uwb_pal_register(struct uwb_rc *rc, struct uwb_pal *pal)
54 } 54 }
55 } 55 }
56 56
57 spin_lock(&rc->pal_lock); 57 mutex_lock(&rc->uwb_dev.mutex);
58 list_add(&pal->node, &rc->pals); 58 list_add(&pal->node, &rc->pals);
59 spin_unlock(&rc->pal_lock); 59 mutex_unlock(&rc->uwb_dev.mutex);
60 60
61 return 0; 61 return 0;
62} 62}
@@ -64,14 +64,17 @@ EXPORT_SYMBOL_GPL(uwb_pal_register);
64 64
65/** 65/**
66 * uwb_pal_register - unregister a UWB PAL 66 * uwb_pal_register - unregister a UWB PAL
67 * @rc: the radio controller the PAL was using
68 * @pal: the PAL 67 * @pal: the PAL
69 */ 68 */
70void uwb_pal_unregister(struct uwb_rc *rc, struct uwb_pal *pal) 69void uwb_pal_unregister(struct uwb_pal *pal)
71{ 70{
72 spin_lock(&rc->pal_lock); 71 struct uwb_rc *rc = pal->rc;
72
73 uwb_radio_stop(pal);
74
75 mutex_lock(&rc->uwb_dev.mutex);
73 list_del(&pal->node); 76 list_del(&pal->node);
74 spin_unlock(&rc->pal_lock); 77 mutex_unlock(&rc->uwb_dev.mutex);
75 78
76 if (pal->device) { 79 if (pal->device) {
77 sysfs_remove_link(&rc->uwb_dev.dev.kobj, pal->name); 80 sysfs_remove_link(&rc->uwb_dev.dev.kobj, pal->name);
@@ -86,6 +89,5 @@ EXPORT_SYMBOL_GPL(uwb_pal_unregister);
86 */ 89 */
87void uwb_rc_pal_init(struct uwb_rc *rc) 90void uwb_rc_pal_init(struct uwb_rc *rc)
88{ 91{
89 spin_lock_init(&rc->pal_lock);
90 INIT_LIST_HEAD(&rc->pals); 92 INIT_LIST_HEAD(&rc->pals);
91} 93}
diff --git a/drivers/uwb/radio.c b/drivers/uwb/radio.c
new file mode 100644
index 00000000000..f0d55495f5e
--- /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 8de856fa795..ce8283cc809 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 bae16204576..1cd84f92754 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 2d8d62d9f53..5ad36164c13 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 aa44e1c1a10..53207e14cd8 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 6d232c35d07..e02fb83469d 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,
@@ -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);
diff --git a/drivers/uwb/uwb-internal.h b/drivers/uwb/uwb-internal.h
index 2ad307d1296..9c0cdb4ded0 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);
diff --git a/drivers/uwb/uwbd.c b/drivers/uwb/uwbd.c
index 78908416e42..ec42ce92dbc 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 1711deadb11..e0d66938ccd 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>
@@ -395,7 +394,7 @@ void whcrc_stop_rc(struct uwb_rc *rc)
395 394
396 le_writel(0, whcrc->rc_base + URCCMD); 395 le_writel(0, whcrc->rc_base + URCCMD);
397 whci_wait_for(&umc_dev->dev, whcrc->rc_base + URCSTS, 396 whci_wait_for(&umc_dev->dev, whcrc->rc_base + URCSTS,
398 URCSTS_HALTED, 0, 40, "URCSTS.HALTED"); 397 URCSTS_HALTED, URCSTS_HALTED, 100, "URCSTS.HALTED");
399} 398}
400 399
401static void whcrc_init(struct whcrc *whcrc) 400static void whcrc_init(struct whcrc *whcrc)
@@ -489,6 +488,24 @@ static void whcrc_remove(struct umc_dev *umc_dev)
489 d_printf(1, &umc_dev->dev, "freed whcrc %p\n", whcrc); 488 d_printf(1, &umc_dev->dev, "freed whcrc %p\n", whcrc);
490} 489}
491 490
491static int whcrc_pre_reset(struct umc_dev *umc)
492{
493 struct whcrc *whcrc = umc_get_drvdata(umc);
494 struct uwb_rc *uwb_rc = whcrc->uwb_rc;
495
496 uwb_rc_pre_reset(uwb_rc);
497 return 0;
498}
499
500static int whcrc_post_reset(struct umc_dev *umc)
501{
502 struct whcrc *whcrc = umc_get_drvdata(umc);
503 struct uwb_rc *uwb_rc = whcrc->uwb_rc;
504
505 uwb_rc_post_reset(uwb_rc);
506 return 0;
507}
508
492/* PCI device ID's that we handle [so it gets loaded] */ 509/* PCI device ID's that we handle [so it gets loaded] */
493static struct pci_device_id whcrc_id_table[] = { 510static struct pci_device_id whcrc_id_table[] = {
494 { PCI_DEVICE_CLASS(PCI_CLASS_WIRELESS_WHCI, ~0) }, 511 { PCI_DEVICE_CLASS(PCI_CLASS_WIRELESS_WHCI, ~0) },
@@ -497,10 +514,12 @@ static struct pci_device_id whcrc_id_table[] = {
497MODULE_DEVICE_TABLE(pci, whcrc_id_table); 514MODULE_DEVICE_TABLE(pci, whcrc_id_table);
498 515
499static struct umc_driver whcrc_driver = { 516static struct umc_driver whcrc_driver = {
500 .name = "whc-rc", 517 .name = "whc-rc",
501 .cap_id = UMC_CAP_ID_WHCI_RC, 518 .cap_id = UMC_CAP_ID_WHCI_RC,
502 .probe = whcrc_probe, 519 .probe = whcrc_probe,
503 .remove = whcrc_remove, 520 .remove = whcrc_remove,
521 .pre_reset = whcrc_pre_reset,
522 .post_reset = whcrc_post_reset,
504}; 523};
505 524
506static int __init whcrc_driver_init(void) 525static int __init whcrc_driver_init(void)
diff --git a/drivers/uwb/whci.c b/drivers/uwb/whci.c
index 3df2388f908..e626467f95e 100644
--- a/drivers/uwb/whci.c
+++ b/drivers/uwb/whci.c
@@ -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 1c94fabfb1a..3e8d5de7c5b 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 0799402e73f..e531093c416 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);
diff --git a/include/linux/usb/wusb-wa.h b/include/linux/usb/wusb-wa.h
index a102561e702..fb7c359bdfb 100644
--- a/include/linux/usb/wusb-wa.h
+++ b/include/linux/usb/wusb-wa.h
@@ -51,6 +51,7 @@ enum {
51 WUSB_REQ_GET_TIME = 25, 51 WUSB_REQ_GET_TIME = 25,
52 WUSB_REQ_SET_STREAM_IDX = 26, 52 WUSB_REQ_SET_STREAM_IDX = 26,
53 WUSB_REQ_SET_WUSB_MAS = 27, 53 WUSB_REQ_SET_WUSB_MAS = 27,
54 WUSB_REQ_CHAN_STOP = 28,
54}; 55};
55 56
56 57
diff --git a/include/linux/uwb.h b/include/linux/uwb.h
index f9ccbd9a2ce..1719709d60c 100644
--- a/include/linux/uwb.h
+++ b/include/linux/uwb.h
@@ -30,6 +30,7 @@
30#include <linux/device.h> 30#include <linux/device.h>
31#include <linux/mutex.h> 31#include <linux/mutex.h>
32#include <linux/timer.h> 32#include <linux/timer.h>
33#include <linux/wait.h>
33#include <linux/workqueue.h> 34#include <linux/workqueue.h>
34#include <linux/uwb/spec.h> 35#include <linux/uwb/spec.h>
35 36
@@ -86,6 +87,22 @@ struct uwb_notifs_chain {
86 struct mutex mutex; 87 struct mutex mutex;
87}; 88};
88 89
90/* Beacon cache list */
91struct uwb_beca {
92 struct list_head list;
93 size_t entries;
94 struct mutex mutex;
95};
96
97/* Event handling thread. */
98struct uwbd {
99 int pid;
100 struct task_struct *task;
101 wait_queue_head_t wq;
102 struct list_head event_list;
103 spinlock_t event_list_lock;
104};
105
89/** 106/**
90 * struct uwb_mas_bm - a bitmap of all MAS in a superframe 107 * struct uwb_mas_bm - a bitmap of all MAS in a superframe
91 * @bm: a bitmap of length #UWB_NUM_MAS 108 * @bm: a bitmap of length #UWB_NUM_MAS
@@ -201,6 +218,7 @@ struct uwb_rsv {
201 struct uwb_rc *rc; 218 struct uwb_rc *rc;
202 struct list_head rc_node; 219 struct list_head rc_node;
203 struct list_head pal_node; 220 struct list_head pal_node;
221 struct kref kref;
204 222
205 struct uwb_dev *owner; 223 struct uwb_dev *owner;
206 struct uwb_rsv_target target; 224 struct uwb_rsv_target target;
@@ -337,10 +355,14 @@ struct uwb_rc {
337 u8 ctx_roll; 355 u8 ctx_roll;
338 356
339 int beaconing; /* Beaconing state [channel number] */ 357 int beaconing; /* Beaconing state [channel number] */
358 int beaconing_forced;
340 int scanning; 359 int scanning;
341 enum uwb_scan_type scan_type:3; 360 enum uwb_scan_type scan_type:3;
342 unsigned ready:1; 361 unsigned ready:1;
343 struct uwb_notifs_chain notifs_chain; 362 struct uwb_notifs_chain notifs_chain;
363 struct uwb_beca uwb_beca;
364
365 struct uwbd uwbd;
344 366
345 struct uwb_drp_avail drp_avail; 367 struct uwb_drp_avail drp_avail;
346 struct list_head reservations; 368 struct list_head reservations;
@@ -352,8 +374,8 @@ struct uwb_rc {
352 struct uwb_rc_cmd_set_ie *ies; 374 struct uwb_rc_cmd_set_ie *ies;
353 size_t ies_capacity; 375 size_t ies_capacity;
354 376
355 spinlock_t pal_lock;
356 struct list_head pals; 377 struct list_head pals;
378 int active_pals;
357 379
358 struct uwb_dbg *dbg; 380 struct uwb_dbg *dbg;
359}; 381};
@@ -361,11 +383,17 @@ struct uwb_rc {
361 383
362/** 384/**
363 * struct uwb_pal - a UWB PAL 385 * struct uwb_pal - a UWB PAL
364 * @name: descriptive name for this PAL (wushc, wlp, etc.). 386 * @name: descriptive name for this PAL (wusbhc, wlp, etc.).
365 * @device: a device for the PAL. Used to link the PAL and the radio 387 * @device: a device for the PAL. Used to link the PAL and the radio
366 * controller in sysfs. 388 * controller in sysfs.
389 * @rc: the radio controller the PAL uses.
390 * @channel_changed: called when the channel used by the radio changes.
391 * A channel of -1 means the channel has been stopped.
367 * @new_rsv: called when a peer requests a reservation (may be NULL if 392 * @new_rsv: called when a peer requests a reservation (may be NULL if
368 * the PAL cannot accept reservation requests). 393 * the PAL cannot accept reservation requests).
394 * @channel: channel being used by the PAL; 0 if the PAL isn't using
395 * the radio; -1 if the PAL wishes to use the radio but
396 * cannot.
369 * 397 *
370 * A Protocol Adaptation Layer (PAL) is a user of the WiMedia UWB 398 * A Protocol Adaptation Layer (PAL) is a user of the WiMedia UWB
371 * radio platform (e.g., WUSB, WLP or Bluetooth UWB AMP). 399 * radio platform (e.g., WUSB, WLP or Bluetooth UWB AMP).
@@ -384,12 +412,20 @@ struct uwb_pal {
384 struct list_head node; 412 struct list_head node;
385 const char *name; 413 const char *name;
386 struct device *device; 414 struct device *device;
387 void (*new_rsv)(struct uwb_rsv *rsv); 415 struct uwb_rc *rc;
416
417 void (*channel_changed)(struct uwb_pal *pal, int channel);
418 void (*new_rsv)(struct uwb_pal *pal, struct uwb_rsv *rsv);
419
420 int channel;
388}; 421};
389 422
390void uwb_pal_init(struct uwb_pal *pal); 423void uwb_pal_init(struct uwb_pal *pal);
391int uwb_pal_register(struct uwb_rc *rc, struct uwb_pal *pal); 424int uwb_pal_register(struct uwb_pal *pal);
392void uwb_pal_unregister(struct uwb_rc *rc, struct uwb_pal *pal); 425void uwb_pal_unregister(struct uwb_pal *pal);
426
427int uwb_radio_start(struct uwb_pal *pal);
428void uwb_radio_stop(struct uwb_pal *pal);
393 429
394/* 430/*
395 * General public API 431 * General public API
@@ -443,8 +479,6 @@ ssize_t uwb_rc_vcmd(struct uwb_rc *rc, const char *cmd_name,
443 struct uwb_rccb *cmd, size_t cmd_size, 479 struct uwb_rccb *cmd, size_t cmd_size,
444 u8 expected_type, u16 expected_event, 480 u8 expected_type, u16 expected_event,
445 struct uwb_rceb **preply); 481 struct uwb_rceb **preply);
446ssize_t uwb_rc_get_ie(struct uwb_rc *, struct uwb_rc_evt_get_ie **);
447int uwb_bg_joined(struct uwb_rc *rc);
448 482
449size_t __uwb_addr_print(char *, size_t, const unsigned char *, int); 483size_t __uwb_addr_print(char *, size_t, const unsigned char *, int);
450 484
@@ -520,6 +554,8 @@ void uwb_rc_rm(struct uwb_rc *);
520void uwb_rc_neh_grok(struct uwb_rc *, void *, size_t); 554void uwb_rc_neh_grok(struct uwb_rc *, void *, size_t);
521void uwb_rc_neh_error(struct uwb_rc *, int); 555void uwb_rc_neh_error(struct uwb_rc *, int);
522void uwb_rc_reset_all(struct uwb_rc *rc); 556void uwb_rc_reset_all(struct uwb_rc *rc);
557void uwb_rc_pre_reset(struct uwb_rc *rc);
558void uwb_rc_post_reset(struct uwb_rc *rc);
523 559
524/** 560/**
525 * uwb_rsv_is_owner - is the owner of this reservation the RC? 561 * uwb_rsv_is_owner - is the owner of this reservation the RC?
@@ -531,7 +567,9 @@ static inline bool uwb_rsv_is_owner(struct uwb_rsv *rsv)
531} 567}
532 568
533/** 569/**
534 * Events generated by UWB that can be passed to any listeners 570 * enum uwb_notifs - UWB events that can be passed to any listeners
571 * @UWB_NOTIF_ONAIR: a new neighbour has joined the beacon group.
572 * @UWB_NOTIF_OFFAIR: a neighbour has left the beacon group.
535 * 573 *
536 * Higher layers can register callback functions with the radio 574 * Higher layers can register callback functions with the radio
537 * controller using uwb_notifs_register(). The radio controller 575 * controller using uwb_notifs_register(). The radio controller
@@ -539,8 +577,6 @@ static inline bool uwb_rsv_is_owner(struct uwb_rsv *rsv)
539 * nodes when an event occurs. 577 * nodes when an event occurs.
540 */ 578 */
541enum uwb_notifs { 579enum uwb_notifs {
542 UWB_NOTIF_BG_JOIN = 0, /* radio controller joined a beacon group */
543 UWB_NOTIF_BG_LEAVE = 1, /* radio controller left a beacon group */
544 UWB_NOTIF_ONAIR, 580 UWB_NOTIF_ONAIR,
545 UWB_NOTIF_OFFAIR, 581 UWB_NOTIF_OFFAIR,
546}; 582};
@@ -652,22 +688,9 @@ static inline int edc_inc(struct edc *err_hist, u16 max_err, u16 timeframe)
652 688
653/* Information Element handling */ 689/* Information Element handling */
654 690
655/* For representing the state of writing to a buffer when iterating */
656struct uwb_buf_ctx {
657 char *buf;
658 size_t bytes, size;
659};
660
661typedef int (*uwb_ie_f)(struct uwb_dev *, const struct uwb_ie_hdr *,
662 size_t, void *);
663struct uwb_ie_hdr *uwb_ie_next(void **ptr, size_t *len);
664ssize_t uwb_ie_for_each(struct uwb_dev *uwb_dev, uwb_ie_f fn, void *data,
665 const void *buf, size_t size);
666int uwb_ie_dump_hex(struct uwb_dev *, const struct uwb_ie_hdr *,
667 size_t, void *);
668int uwb_rc_set_ie(struct uwb_rc *, struct uwb_rc_cmd_set_ie *);
669struct uwb_ie_hdr *uwb_ie_next(void **ptr, size_t *len); 691struct uwb_ie_hdr *uwb_ie_next(void **ptr, size_t *len);
670 692int uwb_rc_ie_add(struct uwb_rc *uwb_rc, const struct uwb_ie_hdr *ies, size_t size);
693int uwb_rc_ie_rm(struct uwb_rc *uwb_rc, enum uwb_ie element_id);
671 694
672/* 695/*
673 * Transmission statistics 696 * Transmission statistics
diff --git a/include/linux/uwb/debug-cmd.h b/include/linux/uwb/debug-cmd.h
index 1141f41bab5..07efbe17db5 100644
--- a/include/linux/uwb/debug-cmd.h
+++ b/include/linux/uwb/debug-cmd.h
@@ -32,6 +32,10 @@
32enum uwb_dbg_cmd_type { 32enum uwb_dbg_cmd_type {
33 UWB_DBG_CMD_RSV_ESTABLISH = 1, 33 UWB_DBG_CMD_RSV_ESTABLISH = 1,
34 UWB_DBG_CMD_RSV_TERMINATE = 2, 34 UWB_DBG_CMD_RSV_TERMINATE = 2,
35 UWB_DBG_CMD_IE_ADD = 3,
36 UWB_DBG_CMD_IE_RM = 4,
37 UWB_DBG_CMD_RADIO_START = 5,
38 UWB_DBG_CMD_RADIO_STOP = 6,
35}; 39};
36 40
37struct uwb_dbg_cmd_rsv_establish { 41struct uwb_dbg_cmd_rsv_establish {
@@ -46,11 +50,18 @@ struct uwb_dbg_cmd_rsv_terminate {
46 int index; 50 int index;
47}; 51};
48 52
53struct uwb_dbg_cmd_ie {
54 __u8 data[128];
55 int len;
56};
57
49struct uwb_dbg_cmd { 58struct uwb_dbg_cmd {
50 __u32 type; 59 __u32 type;
51 union { 60 union {
52 struct uwb_dbg_cmd_rsv_establish rsv_establish; 61 struct uwb_dbg_cmd_rsv_establish rsv_establish;
53 struct uwb_dbg_cmd_rsv_terminate rsv_terminate; 62 struct uwb_dbg_cmd_rsv_terminate rsv_terminate;
63 struct uwb_dbg_cmd_ie ie_add;
64 struct uwb_dbg_cmd_ie ie_rm;
54 }; 65 };
55}; 66};
56 67
diff --git a/include/linux/uwb/debug.h b/include/linux/uwb/debug.h
index a86a73fe303..67a24052714 100644
--- a/include/linux/uwb/debug.h
+++ b/include/linux/uwb/debug.h
@@ -60,7 +60,7 @@ do { \
60 snprintf(__head, sizeof(__head), \ 60 snprintf(__head, sizeof(__head), \
61 "%s %s: ", \ 61 "%s %s: ", \
62 dev_driver_string(__dev), \ 62 dev_driver_string(__dev), \
63 __dev->bus_id); \ 63 dev_name(__dev)); \
64 } \ 64 } \
65 printk(KERN_ERR "%s%s" _tag ": " f, __head, \ 65 printk(KERN_ERR "%s%s" _tag ": " f, __head, \
66 __func__, ## a); \ 66 __func__, ## a); \
diff --git a/include/linux/uwb/spec.h b/include/linux/uwb/spec.h
index 198c15f8e25..a30436ea53a 100644
--- a/include/linux/uwb/spec.h
+++ b/include/linux/uwb/spec.h
@@ -200,6 +200,12 @@ enum uwb_drp_reason {
200 UWB_DRP_REASON_MODIFIED, 200 UWB_DRP_REASON_MODIFIED,
201}; 201};
202 202
203/** Relinquish Request Reason Codes ([ECMA-368] table 113) */
204enum uwb_relinquish_req_reason {
205 UWB_RELINQUISH_REQ_REASON_NON_SPECIFIC = 0,
206 UWB_RELINQUISH_REQ_REASON_OVER_ALLOCATION,
207};
208
203/** 209/**
204 * DRP Notification Reason Codes (WHCI 0.95 [3.1.4.9]) 210 * DRP Notification Reason Codes (WHCI 0.95 [3.1.4.9])
205 */ 211 */
@@ -252,6 +258,7 @@ enum uwb_ie {
252 UWB_APP_SPEC_PROBE_IE = 15, 258 UWB_APP_SPEC_PROBE_IE = 15,
253 UWB_IDENTIFICATION_IE = 19, 259 UWB_IDENTIFICATION_IE = 19,
254 UWB_MASTER_KEY_ID_IE = 20, 260 UWB_MASTER_KEY_ID_IE = 20,
261 UWB_RELINQUISH_REQUEST_IE = 21,
255 UWB_IE_WLP = 250, /* WiMedia Logical Link Control Protocol WLP 0.99 */ 262 UWB_IE_WLP = 250, /* WiMedia Logical Link Control Protocol WLP 0.99 */
256 UWB_APP_SPEC_IE = 255, 263 UWB_APP_SPEC_IE = 255,
257}; 264};
@@ -365,6 +372,27 @@ struct uwb_ie_drp_avail {
365 DECLARE_BITMAP(bmp, UWB_NUM_MAS); 372 DECLARE_BITMAP(bmp, UWB_NUM_MAS);
366} __attribute__((packed)); 373} __attribute__((packed));
367 374
375/* Relinqish Request IE ([ECMA-368] section 16.8.19). */
376struct uwb_relinquish_request_ie {
377 struct uwb_ie_hdr hdr;
378 __le16 relinquish_req_control;
379 struct uwb_dev_addr dev_addr;
380 struct uwb_drp_alloc allocs[];
381} __attribute__((packed));
382
383static inline int uwb_ie_relinquish_req_reason_code(struct uwb_relinquish_request_ie *ie)
384{
385 return (le16_to_cpu(ie->relinquish_req_control) >> 0) & 0xf;
386}
387
388static inline void uwb_ie_relinquish_req_set_reason_code(struct uwb_relinquish_request_ie *ie,
389 int reason_code)
390{
391 u16 ctrl = le16_to_cpu(ie->relinquish_req_control);
392 ctrl = (ctrl & ~(0xf << 0)) | (reason_code << 0);
393 ie->relinquish_req_control = cpu_to_le16(ctrl);
394}
395
368/** 396/**
369 * The Vendor ID is set to an OUI that indicates the vendor of the device. 397 * The Vendor ID is set to an OUI that indicates the vendor of the device.
370 * ECMA-368 [16.8.10] 398 * ECMA-368 [16.8.10]
diff --git a/include/linux/uwb/umc.h b/include/linux/uwb/umc.h
index 36a39e34f8d..4b4fc0f4385 100644
--- a/include/linux/uwb/umc.h
+++ b/include/linux/uwb/umc.h
@@ -89,6 +89,8 @@ struct umc_driver {
89 void (*remove)(struct umc_dev *); 89 void (*remove)(struct umc_dev *);
90 int (*suspend)(struct umc_dev *, pm_message_t state); 90 int (*suspend)(struct umc_dev *, pm_message_t state);
91 int (*resume)(struct umc_dev *); 91 int (*resume)(struct umc_dev *);
92 int (*pre_reset)(struct umc_dev *);
93 int (*post_reset)(struct umc_dev *);
92 94
93 struct device_driver driver; 95 struct device_driver driver;
94}; 96};
diff --git a/include/linux/wlp.h b/include/linux/wlp.h
index 033545e145c..ac95ce6606a 100644
--- a/include/linux/wlp.h
+++ b/include/linux/wlp.h
@@ -646,6 +646,7 @@ struct wlp_wss {
646struct wlp { 646struct wlp {
647 struct mutex mutex; 647 struct mutex mutex;
648 struct uwb_rc *rc; /* UWB radio controller */ 648 struct uwb_rc *rc; /* UWB radio controller */
649 struct net_device *ndev;
649 struct uwb_pal pal; 650 struct uwb_pal pal;
650 struct wlp_eda eda; 651 struct wlp_eda eda;
651 struct wlp_uuid uuid; 652 struct wlp_uuid uuid;
@@ -675,7 +676,7 @@ struct wlp_wss_attribute {
675static struct wlp_wss_attribute wss_attr_##_name = __ATTR(_name, _mode, \ 676static struct wlp_wss_attribute wss_attr_##_name = __ATTR(_name, _mode, \
676 _show, _store) 677 _show, _store)
677 678
678extern int wlp_setup(struct wlp *, struct uwb_rc *); 679extern int wlp_setup(struct wlp *, struct uwb_rc *, struct net_device *ndev);
679extern void wlp_remove(struct wlp *); 680extern void wlp_remove(struct wlp *);
680extern ssize_t wlp_neighborhood_show(struct wlp *, char *); 681extern ssize_t wlp_neighborhood_show(struct wlp *, char *);
681extern int wlp_wss_setup(struct net_device *, struct wlp_wss *); 682extern int wlp_wss_setup(struct net_device *, struct wlp_wss *);