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.c159
-rw-r--r--drivers/usb/host/whci/Kbuild1
-rw-r--r--drivers/usb/host/whci/asl.c46
-rw-r--r--drivers/usb/host/whci/debug.c189
-rw-r--r--drivers/usb/host/whci/hcd.c6
-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/pzl.c49
-rw-r--r--drivers/usb/host/whci/qset.c40
-rw-r--r--drivers/usb/host/whci/whcd.h11
-rw-r--r--drivers/usb/host/whci/whci-hc.h2
-rw-r--r--drivers/usb/host/whci/wusb.c43
-rw-r--r--drivers/usb/wusbcore/cbaf.c1
-rw-r--r--drivers/usb/wusbcore/crypto.c79
-rw-r--r--drivers/usb/wusbcore/dev-sysfs.c4
-rw-r--r--drivers/usb/wusbcore/devconnect.c233
-rw-r--r--drivers/usb/wusbcore/mmc.c118
-rw-r--r--drivers/usb/wusbcore/pal.c16
-rw-r--r--drivers/usb/wusbcore/reservation.c21
-rw-r--r--drivers/usb/wusbcore/rh.c104
-rw-r--r--drivers/usb/wusbcore/security.c78
-rw-r--r--drivers/usb/wusbcore/wa-nep.c16
-rw-r--r--drivers/usb/wusbcore/wa-rpipe.c68
-rw-r--r--drivers/usb/wusbcore/wa-xfer.c180
-rw-r--r--drivers/usb/wusbcore/wusbhc.h36
-rw-r--r--drivers/uwb/Makefile3
-rw-r--r--drivers/uwb/address.c2
-rw-r--r--drivers/uwb/allocator.c386
-rw-r--r--drivers/uwb/beacon.c134
-rw-r--r--drivers/uwb/driver.c4
-rw-r--r--drivers/uwb/drp-avail.c4
-rw-r--r--drivers/uwb/drp-ie.c161
-rw-r--r--drivers/uwb/drp.c695
-rw-r--r--drivers/uwb/est.c14
-rw-r--r--drivers/uwb/hwa-rc.c53
-rw-r--r--drivers/uwb/i1480/dfu/dfu.c10
-rw-r--r--drivers/uwb/i1480/dfu/mac.c18
-rw-r--r--drivers/uwb/i1480/dfu/usb.c27
-rw-r--r--drivers/uwb/i1480/i1480u-wlp/lc.c5
-rw-r--r--drivers/uwb/i1480/i1480u-wlp/netdev.c53
-rw-r--r--drivers/uwb/i1480/i1480u-wlp/rx.c25
-rw-r--r--drivers/uwb/i1480/i1480u-wlp/sysfs.c3
-rw-r--r--drivers/uwb/i1480/i1480u-wlp/tx.c66
-rw-r--r--drivers/uwb/ie-rcv.c55
-rw-r--r--drivers/uwb/ie.c463
-rw-r--r--drivers/uwb/lc-dev.c23
-rw-r--r--drivers/uwb/lc-rc.c62
-rw-r--r--drivers/uwb/neh.c72
-rw-r--r--drivers/uwb/pal.c25
-rw-r--r--drivers/uwb/radio.c202
-rw-r--r--drivers/uwb/reset.c47
-rw-r--r--drivers/uwb/rsv.c565
-rw-r--r--drivers/uwb/umc-bus.c62
-rw-r--r--drivers/uwb/umc-dev.c11
-rw-r--r--drivers/uwb/uwb-debug.c151
-rw-r--r--drivers/uwb/uwb-internal.h126
-rw-r--r--drivers/uwb/uwbd.c176
-rw-r--r--drivers/uwb/whc-rc.c118
-rw-r--r--drivers/uwb/whci.c6
-rw-r--r--drivers/uwb/wlp/eda.c19
-rw-r--r--drivers/uwb/wlp/messages.c181
-rw-r--r--drivers/uwb/wlp/sysfs.c2
-rw-r--r--drivers/uwb/wlp/txrx.c37
-rw-r--r--drivers/uwb/wlp/wlp-internal.h4
-rw-r--r--drivers/uwb/wlp/wlp-lc.c80
-rw-r--r--drivers/uwb/wlp/wss-lc.c130
-rw-r--r--include/linux/usb/wusb-wa.h1
-rw-r--r--include/linux/uwb.h123
-rw-r--r--include/linux/uwb/debug-cmd.h13
-rw-r--r--include/linux/uwb/debug.h82
-rw-r--r--include/linux/uwb/spec.h53
-rw-r--r--include/linux/uwb/umc.h2
-rw-r--r--include/linux/wlp.h3
75 files changed, 3252 insertions, 2837 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-uwb_rc b/Documentation/ABI/testing/sysfs-class-uwb_rc
index a0d18dbeb7a9..6a5fd072849d 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 2e78b70f3adc..426ddaaef96f 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 64be4d88df11..8582236e4cad 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>
@@ -63,16 +62,12 @@
63#include "../wusbcore/wa-hc.h" 62#include "../wusbcore/wa-hc.h"
64#include "../wusbcore/wusbhc.h" 63#include "../wusbcore/wusbhc.h"
65 64
66#define D_LOCAL 0
67#include <linux/uwb/debug.h>
68
69struct hwahc { 65struct hwahc {
70 struct wusbhc wusbhc; /* has to be 1st */ 66 struct wusbhc wusbhc; /* has to be 1st */
71 struct wahc wa; 67 struct wahc wa;
72 u8 buffer[16]; /* for misc usb transactions */
73}; 68};
74 69
75/** 70/*
76 * FIXME should be wusbhc 71 * FIXME should be wusbhc
77 * 72 *
78 * NOTE: we need to cache the Cluster ID because later...there is no 73 * NOTE: we need to cache the Cluster ID because later...there is no
@@ -126,7 +121,6 @@ static int hwahc_op_reset(struct usb_hcd *usb_hcd)
126 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc); 121 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
127 struct device *dev = &hwahc->wa.usb_iface->dev; 122 struct device *dev = &hwahc->wa.usb_iface->dev;
128 123
129 d_fnstart(4, dev, "(hwahc %p)\n", hwahc);
130 mutex_lock(&wusbhc->mutex); 124 mutex_lock(&wusbhc->mutex);
131 wa_nep_disarm(&hwahc->wa); 125 wa_nep_disarm(&hwahc->wa);
132 result = __wa_set_feature(&hwahc->wa, WA_RESET); 126 result = __wa_set_feature(&hwahc->wa, WA_RESET);
@@ -134,7 +128,6 @@ static int hwahc_op_reset(struct usb_hcd *usb_hcd)
134 dev_err(dev, "error commanding HC to reset: %d\n", result); 128 dev_err(dev, "error commanding HC to reset: %d\n", result);
135 goto error_unlock; 129 goto error_unlock;
136 } 130 }
137 d_printf(3, dev, "reset: waiting for device to change state\n");
138 result = __wa_wait_status(&hwahc->wa, WA_STATUS_RESETTING, 0); 131 result = __wa_wait_status(&hwahc->wa, WA_STATUS_RESETTING, 0);
139 if (result < 0) { 132 if (result < 0) {
140 dev_err(dev, "error waiting for HC to reset: %d\n", result); 133 dev_err(dev, "error waiting for HC to reset: %d\n", result);
@@ -142,7 +135,6 @@ static int hwahc_op_reset(struct usb_hcd *usb_hcd)
142 } 135 }
143error_unlock: 136error_unlock:
144 mutex_unlock(&wusbhc->mutex); 137 mutex_unlock(&wusbhc->mutex);
145 d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result);
146 return result; 138 return result;
147} 139}
148 140
@@ -155,15 +147,9 @@ static int hwahc_op_start(struct usb_hcd *usb_hcd)
155 int result; 147 int result;
156 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); 148 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
157 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc); 149 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
158 struct device *dev = &hwahc->wa.usb_iface->dev;
159 150
160 /* Set up a Host Info WUSB Information Element */
161 d_fnstart(4, dev, "(hwahc %p)\n", hwahc);
162 result = -ENOSPC; 151 result = -ENOSPC;
163 mutex_lock(&wusbhc->mutex); 152 mutex_lock(&wusbhc->mutex);
164 /* Start the numbering from the top so that the bottom
165 * range of the unauth addr space is used for devices,
166 * the top for HCs; use 0xfe - RC# */
167 addr = wusb_cluster_id_get(); 153 addr = wusb_cluster_id_get();
168 if (addr == 0) 154 if (addr == 0)
169 goto error_cluster_id_get; 155 goto error_cluster_id_get;
@@ -171,22 +157,14 @@ static int hwahc_op_start(struct usb_hcd *usb_hcd)
171 if (result < 0) 157 if (result < 0)
172 goto error_set_cluster_id; 158 goto error_set_cluster_id;
173 159
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; 160 usb_hcd->uses_new_polling = 1;
180 usb_hcd->poll_rh = 1; 161 usb_hcd->poll_rh = 1;
181 usb_hcd->state = HC_STATE_RUNNING; 162 usb_hcd->state = HC_STATE_RUNNING;
182 result = 0; 163 result = 0;
183out: 164out:
184 mutex_unlock(&wusbhc->mutex); 165 mutex_unlock(&wusbhc->mutex);
185 d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result);
186 return result; 166 return result;
187 167
188error_stop:
189 __wa_stop(&hwahc->wa);
190error_set_cluster_id: 168error_set_cluster_id:
191 wusb_cluster_id_put(wusbhc->cluster_id); 169 wusb_cluster_id_put(wusbhc->cluster_id);
192error_cluster_id_get: 170error_cluster_id_get:
@@ -194,39 +172,6 @@ error_cluster_id_get:
194 172
195} 173}
196 174
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) 175static int hwahc_op_suspend(struct usb_hcd *usb_hcd, pm_message_t msg)
231{ 176{
232 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); 177 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
@@ -246,18 +191,6 @@ static int hwahc_op_resume(struct usb_hcd *usb_hcd)
246 return -ENOSYS; 191 return -ENOSYS;
247} 192}
248 193
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/* 194/*
262 * No need to abort pipes, as when this is called, all the children 195 * No need to abort pipes, as when this is called, all the children
263 * has been disconnected and that has done it [through 196 * has been disconnected and that has done it [through
@@ -266,21 +199,11 @@ static void __hwahc_op_wusbhc_stop(struct wusbhc *wusbhc)
266 */ 199 */
267static void hwahc_op_stop(struct usb_hcd *usb_hcd) 200static void hwahc_op_stop(struct usb_hcd *usb_hcd)
268{ 201{
269 int result;
270 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); 202 struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
271 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
272 struct wahc *wa = &hwahc->wa;
273 struct device *dev = &wa->usb_iface->dev;
274 203
275 d_fnstart(4, dev, "(hwahc %p)\n", hwahc);
276 mutex_lock(&wusbhc->mutex); 204 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); 205 wusb_cluster_id_put(wusbhc->cluster_id);
281 mutex_unlock(&wusbhc->mutex); 206 mutex_unlock(&wusbhc->mutex);
282 d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result);
283 return;
284} 207}
285 208
286static int hwahc_op_get_frame_number(struct usb_hcd *usb_hcd) 209static int hwahc_op_get_frame_number(struct usb_hcd *usb_hcd)
@@ -325,6 +248,54 @@ static void hwahc_op_endpoint_disable(struct usb_hcd *usb_hcd,
325 rpipe_ep_disable(&hwahc->wa, ep); 248 rpipe_ep_disable(&hwahc->wa, ep);
326} 249}
327 250
251static int __hwahc_op_wusbhc_start(struct wusbhc *wusbhc)
252{
253 int result;
254 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
255 struct device *dev = &hwahc->wa.usb_iface->dev;
256
257 result = __wa_set_feature(&hwahc->wa, WA_ENABLE);
258 if (result < 0) {
259 dev_err(dev, "error commanding HC to start: %d\n", result);
260 goto error_stop;
261 }
262 result = __wa_wait_status(&hwahc->wa, WA_ENABLE, WA_ENABLE);
263 if (result < 0) {
264 dev_err(dev, "error waiting for HC to start: %d\n", result);
265 goto error_stop;
266 }
267 result = wa_nep_arm(&hwahc->wa, GFP_KERNEL);
268 if (result < 0) {
269 dev_err(dev, "cannot listen to notifications: %d\n", result);
270 goto error_stop;
271 }
272 return result;
273
274error_stop:
275 __wa_clear_feature(&hwahc->wa, WA_ENABLE);
276 return result;
277}
278
279static void __hwahc_op_wusbhc_stop(struct wusbhc *wusbhc, int delay)
280{
281 struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
282 struct wahc *wa = &hwahc->wa;
283 u8 iface_no = wa->usb_iface->cur_altsetting->desc.bInterfaceNumber;
284 int ret;
285
286 ret = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
287 WUSB_REQ_CHAN_STOP,
288 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
289 delay * 1000,
290 iface_no,
291 NULL, 0, 1000 /* FIXME: arbitrary */);
292 if (ret == 0)
293 msleep(delay);
294
295 wa_nep_disarm(&hwahc->wa);
296 __wa_stop(&hwahc->wa);
297}
298
328/* 299/*
329 * Set the UWB MAS allocation for the WUSB cluster 300 * Set the UWB MAS allocation for the WUSB cluster
330 * 301 *
@@ -581,11 +552,11 @@ static int wa_fill_descr(struct wahc *wa)
581 itr_size = le16_to_cpu(usb_dev->actconfig->desc.wTotalLength); 552 itr_size = le16_to_cpu(usb_dev->actconfig->desc.wTotalLength);
582 while (itr_size >= sizeof(*hdr)) { 553 while (itr_size >= sizeof(*hdr)) {
583 hdr = (struct usb_descriptor_header *) itr; 554 hdr = (struct usb_descriptor_header *) itr;
584 d_printf(3, dev, "Extra device descriptor: " 555 dev_dbg(dev, "Extra device descriptor: "
585 "type %02x/%u bytes @ %zu (%zu left)\n", 556 "type %02x/%u bytes @ %zu (%zu left)\n",
586 hdr->bDescriptorType, hdr->bLength, 557 hdr->bDescriptorType, hdr->bLength,
587 (itr - usb_dev->rawdescriptors[actconfig_idx]), 558 (itr - usb_dev->rawdescriptors[actconfig_idx]),
588 itr_size); 559 itr_size);
589 if (hdr->bDescriptorType == USB_DT_WIRE_ADAPTER) 560 if (hdr->bDescriptorType == USB_DT_WIRE_ADAPTER)
590 goto found; 561 goto found;
591 itr += hdr->bLength; 562 itr += hdr->bLength;
@@ -794,7 +765,6 @@ static void hwahc_destroy(struct hwahc *hwahc)
794{ 765{
795 struct wusbhc *wusbhc = &hwahc->wusbhc; 766 struct wusbhc *wusbhc = &hwahc->wusbhc;
796 767
797 d_fnstart(1, NULL, "(hwahc %p)\n", hwahc);
798 mutex_lock(&wusbhc->mutex); 768 mutex_lock(&wusbhc->mutex);
799 __wa_destroy(&hwahc->wa); 769 __wa_destroy(&hwahc->wa);
800 wusbhc_destroy(&hwahc->wusbhc); 770 wusbhc_destroy(&hwahc->wusbhc);
@@ -804,7 +774,6 @@ static void hwahc_destroy(struct hwahc *hwahc)
804 usb_put_intf(hwahc->wa.usb_iface); 774 usb_put_intf(hwahc->wa.usb_iface);
805 usb_put_dev(hwahc->wa.usb_dev); 775 usb_put_dev(hwahc->wa.usb_dev);
806 mutex_unlock(&wusbhc->mutex); 776 mutex_unlock(&wusbhc->mutex);
807 d_fnend(1, NULL, "(hwahc %p) = void\n", hwahc);
808} 777}
809 778
810static void hwahc_init(struct hwahc *hwahc) 779static void hwahc_init(struct hwahc *hwahc)
@@ -821,7 +790,6 @@ static int hwahc_probe(struct usb_interface *usb_iface,
821 struct hwahc *hwahc; 790 struct hwahc *hwahc;
822 struct device *dev = &usb_iface->dev; 791 struct device *dev = &usb_iface->dev;
823 792
824 d_fnstart(4, dev, "(%p, %p)\n", usb_iface, id);
825 result = -ENOMEM; 793 result = -ENOMEM;
826 usb_hcd = usb_create_hcd(&hwahc_hc_driver, &usb_iface->dev, "wusb-hwa"); 794 usb_hcd = usb_create_hcd(&hwahc_hc_driver, &usb_iface->dev, "wusb-hwa");
827 if (usb_hcd == NULL) { 795 if (usb_hcd == NULL) {
@@ -848,7 +816,6 @@ static int hwahc_probe(struct usb_interface *usb_iface,
848 dev_err(dev, "Cannot setup phase B of WUSBHC: %d\n", result); 816 dev_err(dev, "Cannot setup phase B of WUSBHC: %d\n", result);
849 goto error_wusbhc_b_create; 817 goto error_wusbhc_b_create;
850 } 818 }
851 d_fnend(4, dev, "(%p, %p) = 0\n", usb_iface, id);
852 return 0; 819 return 0;
853 820
854error_wusbhc_b_create: 821error_wusbhc_b_create:
@@ -858,7 +825,6 @@ error_add_hcd:
858error_hwahc_create: 825error_hwahc_create:
859 usb_put_hcd(usb_hcd); 826 usb_put_hcd(usb_hcd);
860error_alloc: 827error_alloc:
861 d_fnend(4, dev, "(%p, %p) = %d\n", usb_iface, id, result);
862 return result; 828 return result;
863} 829}
864 830
@@ -872,16 +838,12 @@ static void hwahc_disconnect(struct usb_interface *usb_iface)
872 wusbhc = usb_hcd_to_wusbhc(usb_hcd); 838 wusbhc = usb_hcd_to_wusbhc(usb_hcd);
873 hwahc = container_of(wusbhc, struct hwahc, wusbhc); 839 hwahc = container_of(wusbhc, struct hwahc, wusbhc);
874 840
875 d_fnstart(1, NULL, "(hwahc %p [usb_iface %p])\n", hwahc, usb_iface);
876 wusbhc_b_destroy(&hwahc->wusbhc); 841 wusbhc_b_destroy(&hwahc->wusbhc);
877 usb_remove_hcd(usb_hcd); 842 usb_remove_hcd(usb_hcd);
878 hwahc_destroy(hwahc); 843 hwahc_destroy(hwahc);
879 usb_put_hcd(usb_hcd); 844 usb_put_hcd(usb_hcd);
880 d_fnend(1, NULL, "(hwahc %p [usb_iface %p]) = void\n", hwahc,
881 usb_iface);
882} 845}
883 846
884/** USB device ID's that we handle */
885static struct usb_device_id hwahc_id_table[] = { 847static struct usb_device_id hwahc_id_table[] = {
886 /* FIXME: use class labels for this */ 848 /* FIXME: use class labels for this */
887 { USB_INTERFACE_INFO(0xe0, 0x02, 0x01), }, 849 { USB_INTERFACE_INFO(0xe0, 0x02, 0x01), },
@@ -898,18 +860,7 @@ static struct usb_driver hwahc_driver = {
898 860
899static int __init hwahc_driver_init(void) 861static int __init hwahc_driver_init(void)
900{ 862{
901 int result; 863 return usb_register(&hwahc_driver);
902 result = usb_register(&hwahc_driver);
903 if (result < 0) {
904 printk(KERN_ERR "WA-CDS: Cannot register USB driver: %d\n",
905 result);
906 goto error_usb_register;
907 }
908 return 0;
909
910error_usb_register:
911 return result;
912
913} 864}
914module_init(hwahc_driver_init); 865module_init(hwahc_driver_init);
915 866
diff --git a/drivers/usb/host/whci/Kbuild b/drivers/usb/host/whci/Kbuild
index 26a3871ea0f9..11e5040b8337 100644
--- a/drivers/usb/host/whci/Kbuild
+++ b/drivers/usb/host/whci/Kbuild
@@ -2,6 +2,7 @@ obj-$(CONFIG_USB_WHCI_HCD) += whci-hcd.o
2 2
3whci-hcd-y := \ 3whci-hcd-y := \
4 asl.o \ 4 asl.o \
5 debug.o \
5 hcd.o \ 6 hcd.o \
6 hw.o \ 7 hw.o \
7 init.o \ 8 init.o \
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c
index 4d7078e50572..577c0d29849d 100644
--- a/drivers/usb/host/whci/asl.c
+++ b/drivers/usb/host/whci/asl.c
@@ -19,32 +19,11 @@
19#include <linux/dma-mapping.h> 19#include <linux/dma-mapping.h>
20#include <linux/uwb/umc.h> 20#include <linux/uwb/umc.h>
21#include <linux/usb.h> 21#include <linux/usb.h>
22#define D_LOCAL 0
23#include <linux/uwb/debug.h>
24 22
25#include "../../wusbcore/wusbhc.h" 23#include "../../wusbcore/wusbhc.h"
26 24
27#include "whcd.h" 25#include "whcd.h"
28 26
29#if D_LOCAL >= 4
30static void dump_asl(struct whc *whc, const char *tag)
31{
32 struct device *dev = &whc->umc->dev;
33 struct whc_qset *qset;
34
35 d_printf(4, dev, "ASL %s\n", tag);
36
37 list_for_each_entry(qset, &whc->async_list, list_node) {
38 dump_qset(qset, dev);
39 }
40}
41#else
42static inline void dump_asl(struct whc *whc, const char *tag)
43{
44}
45#endif
46
47
48static void qset_get_next_prev(struct whc *whc, struct whc_qset *qset, 27static void qset_get_next_prev(struct whc *whc, struct whc_qset *qset,
49 struct whc_qset **next, struct whc_qset **prev) 28 struct whc_qset **next, struct whc_qset **prev)
50{ 29{
@@ -179,11 +158,26 @@ void asl_stop(struct whc *whc)
179 1000, "stop ASL"); 158 1000, "stop ASL");
180} 159}
181 160
161/**
162 * asl_update - request an ASL update and wait for the hardware to be synced
163 * @whc: the WHCI HC
164 * @wusbcmd: WUSBCMD value to start the update.
165 *
166 * If the WUSB HC is inactive (i.e., the ASL is stopped) then the
167 * update must be skipped as the hardware may not respond to update
168 * requests.
169 */
182void asl_update(struct whc *whc, uint32_t wusbcmd) 170void asl_update(struct whc *whc, uint32_t wusbcmd)
183{ 171{
184 whc_write_wusbcmd(whc, wusbcmd, wusbcmd); 172 struct wusbhc *wusbhc = &whc->wusbhc;
185 wait_event(whc->async_list_wq, 173
186 (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0); 174 mutex_lock(&wusbhc->mutex);
175 if (wusbhc->active) {
176 whc_write_wusbcmd(whc, wusbcmd, wusbcmd);
177 wait_event(whc->async_list_wq,
178 (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0);
179 }
180 mutex_unlock(&wusbhc->mutex);
187} 181}
188 182
189/** 183/**
@@ -202,8 +196,6 @@ void scan_async_work(struct work_struct *work)
202 196
203 spin_lock_irq(&whc->lock); 197 spin_lock_irq(&whc->lock);
204 198
205 dump_asl(whc, "before processing");
206
207 /* 199 /*
208 * Transerve the software list backwards so new qsets can be 200 * Transerve the software list backwards so new qsets can be
209 * safely inserted into the ASL without making it non-circular. 201 * safely inserted into the ASL without making it non-circular.
@@ -217,8 +209,6 @@ void scan_async_work(struct work_struct *work)
217 update |= process_qset(whc, qset); 209 update |= process_qset(whc, qset);
218 } 210 }
219 211
220 dump_asl(whc, "after processing");
221
222 spin_unlock_irq(&whc->lock); 212 spin_unlock_irq(&whc->lock);
223 213
224 if (update) { 214 if (update) {
diff --git a/drivers/usb/host/whci/debug.c b/drivers/usb/host/whci/debug.c
new file mode 100644
index 000000000000..cf2d45946c57
--- /dev/null
+++ b/drivers/usb/host/whci/debug.c
@@ -0,0 +1,189 @@
1/*
2 * Wireless Host Controller (WHC) debug.
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/debugfs.h>
20#include <linux/seq_file.h>
21
22#include "../../wusbcore/wusbhc.h"
23
24#include "whcd.h"
25
26struct whc_dbg {
27 struct dentry *di_f;
28 struct dentry *asl_f;
29 struct dentry *pzl_f;
30};
31
32void qset_print(struct seq_file *s, struct whc_qset *qset)
33{
34 struct whc_std *std;
35 struct urb *urb = NULL;
36 int i;
37
38 seq_printf(s, "qset %08x\n", (u32)qset->qset_dma);
39 seq_printf(s, " -> %08x\n", (u32)qset->qh.link);
40 seq_printf(s, " info: %08x %08x %08x\n",
41 qset->qh.info1, qset->qh.info2, qset->qh.info3);
42 seq_printf(s, " sts: %04x errs: %d\n", qset->qh.status, qset->qh.err_count);
43 seq_printf(s, " TD: sts: %08x opts: %08x\n",
44 qset->qh.overlay.qtd.status, qset->qh.overlay.qtd.options);
45
46 for (i = 0; i < WHCI_QSET_TD_MAX; i++) {
47 seq_printf(s, " %c%c TD[%d]: sts: %08x opts: %08x ptr: %08x\n",
48 i == qset->td_start ? 'S' : ' ',
49 i == qset->td_end ? 'E' : ' ',
50 i, qset->qtd[i].status, qset->qtd[i].options,
51 (u32)qset->qtd[i].page_list_ptr);
52 }
53 seq_printf(s, " ntds: %d\n", qset->ntds);
54 list_for_each_entry(std, &qset->stds, list_node) {
55 if (urb != std->urb) {
56 urb = std->urb;
57 seq_printf(s, " urb %p transferred: %d bytes\n", urb,
58 urb->actual_length);
59 }
60 if (std->qtd)
61 seq_printf(s, " sTD[%td]: %zu bytes @ %08x\n",
62 std->qtd - &qset->qtd[0],
63 std->len, std->num_pointers ?
64 (u32)(std->pl_virt[0].buf_ptr) : (u32)std->dma_addr);
65 else
66 seq_printf(s, " sTD[-]: %zd bytes @ %08x\n",
67 std->len, std->num_pointers ?
68 (u32)(std->pl_virt[0].buf_ptr) : (u32)std->dma_addr);
69 }
70}
71
72static int di_print(struct seq_file *s, void *p)
73{
74 struct whc *whc = s->private;
75 char buf[72];
76 int d;
77
78 for (d = 0; d < whc->n_devices; d++) {
79 struct di_buf_entry *di = &whc->di_buf[d];
80
81 bitmap_scnprintf(buf, sizeof(buf),
82 (unsigned long *)di->availability_info, UWB_NUM_MAS);
83
84 seq_printf(s, "DI[%d]\n", d);
85 seq_printf(s, " availability: %s\n", buf);
86 seq_printf(s, " %c%c key idx: %d dev addr: %d\n",
87 (di->addr_sec_info & WHC_DI_SECURE) ? 'S' : ' ',
88 (di->addr_sec_info & WHC_DI_DISABLE) ? 'D' : ' ',
89 (di->addr_sec_info & WHC_DI_KEY_IDX_MASK) >> 8,
90 (di->addr_sec_info & WHC_DI_DEV_ADDR_MASK));
91 }
92 return 0;
93}
94
95static int asl_print(struct seq_file *s, void *p)
96{
97 struct whc *whc = s->private;
98 struct whc_qset *qset;
99
100 list_for_each_entry(qset, &whc->async_list, list_node) {
101 qset_print(s, qset);
102 }
103
104 return 0;
105}
106
107static int pzl_print(struct seq_file *s, void *p)
108{
109 struct whc *whc = s->private;
110 struct whc_qset *qset;
111 int period;
112
113 for (period = 0; period < 5; period++) {
114 seq_printf(s, "Period %d\n", period);
115 list_for_each_entry(qset, &whc->periodic_list[period], list_node) {
116 qset_print(s, qset);
117 }
118 }
119 return 0;
120}
121
122static int di_open(struct inode *inode, struct file *file)
123{
124 return single_open(file, di_print, inode->i_private);
125}
126
127static int asl_open(struct inode *inode, struct file *file)
128{
129 return single_open(file, asl_print, inode->i_private);
130}
131
132static int pzl_open(struct inode *inode, struct file *file)
133{
134 return single_open(file, pzl_print, inode->i_private);
135}
136
137static struct file_operations di_fops = {
138 .open = di_open,
139 .read = seq_read,
140 .llseek = seq_lseek,
141 .release = single_release,
142 .owner = THIS_MODULE,
143};
144
145static struct file_operations asl_fops = {
146 .open = asl_open,
147 .read = seq_read,
148 .llseek = seq_lseek,
149 .release = single_release,
150 .owner = THIS_MODULE,
151};
152
153static struct file_operations pzl_fops = {
154 .open = pzl_open,
155 .read = seq_read,
156 .llseek = seq_lseek,
157 .release = single_release,
158 .owner = THIS_MODULE,
159};
160
161void whc_dbg_init(struct whc *whc)
162{
163 if (whc->wusbhc.pal.debugfs_dir == NULL)
164 return;
165
166 whc->dbg = kzalloc(sizeof(struct whc_dbg), GFP_KERNEL);
167 if (whc->dbg == NULL)
168 return;
169
170 whc->dbg->di_f = debugfs_create_file("di", 0444,
171 whc->wusbhc.pal.debugfs_dir, whc,
172 &di_fops);
173 whc->dbg->asl_f = debugfs_create_file("asl", 0444,
174 whc->wusbhc.pal.debugfs_dir, whc,
175 &asl_fops);
176 whc->dbg->pzl_f = debugfs_create_file("pzl", 0444,
177 whc->wusbhc.pal.debugfs_dir, whc,
178 &pzl_fops);
179}
180
181void whc_dbg_clean_up(struct whc *whc)
182{
183 if (whc->dbg) {
184 debugfs_remove(whc->dbg->pzl_f);
185 debugfs_remove(whc->dbg->asl_f);
186 debugfs_remove(whc->dbg->di_f);
187 kfree(whc->dbg);
188 }
189}
diff --git a/drivers/usb/host/whci/hcd.c b/drivers/usb/host/whci/hcd.c
index ef3ad4dca945..1569afd6245b 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);
@@ -276,6 +273,8 @@ static int whc_probe(struct umc_dev *umc)
276 goto error_wusbhc_b_create; 273 goto error_wusbhc_b_create;
277 } 274 }
278 275
276 whc_dbg_init(whc);
277
279 return 0; 278 return 0;
280 279
281error_wusbhc_b_create: 280error_wusbhc_b_create:
@@ -299,6 +298,7 @@ static void whc_remove(struct umc_dev *umc)
299 struct whc *whc = wusbhc_to_whc(wusbhc); 298 struct whc *whc = wusbhc_to_whc(wusbhc);
300 299
301 if (usb_hcd) { 300 if (usb_hcd) {
301 whc_dbg_clean_up(whc);
302 wusbhc_b_destroy(wusbhc); 302 wusbhc_b_destroy(wusbhc);
303 usb_remove_hcd(usb_hcd); 303 usb_remove_hcd(usb_hcd);
304 wusbhc_destroy(wusbhc); 304 wusbhc_destroy(wusbhc);
diff --git a/drivers/usb/host/whci/hw.c b/drivers/usb/host/whci/hw.c
index ac86e59c1225..d498e7203217 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 fce01174aa9b..6aae70028101 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/pzl.c b/drivers/usb/host/whci/pzl.c
index 8d62df0c330b..2ae5abf69a6a 100644
--- a/drivers/usb/host/whci/pzl.c
+++ b/drivers/usb/host/whci/pzl.c
@@ -19,35 +19,11 @@
19#include <linux/dma-mapping.h> 19#include <linux/dma-mapping.h>
20#include <linux/uwb/umc.h> 20#include <linux/uwb/umc.h>
21#include <linux/usb.h> 21#include <linux/usb.h>
22#define D_LOCAL 0
23#include <linux/uwb/debug.h>
24 22
25#include "../../wusbcore/wusbhc.h" 23#include "../../wusbcore/wusbhc.h"
26 24
27#include "whcd.h" 25#include "whcd.h"
28 26
29#if D_LOCAL >= 4
30static void dump_pzl(struct whc *whc, const char *tag)
31{
32 struct device *dev = &whc->umc->dev;
33 struct whc_qset *qset;
34 int period = 0;
35
36 d_printf(4, dev, "PZL %s\n", tag);
37
38 for (period = 0; period < 5; period++) {
39 d_printf(4, dev, "Period %d\n", period);
40 list_for_each_entry(qset, &whc->periodic_list[period], list_node) {
41 dump_qset(qset, dev);
42 }
43 }
44}
45#else
46static inline void dump_pzl(struct whc *whc, const char *tag)
47{
48}
49#endif
50
51static void update_pzl_pointers(struct whc *whc, int period, u64 addr) 27static void update_pzl_pointers(struct whc *whc, int period, u64 addr)
52{ 28{
53 switch (period) { 29 switch (period) {
@@ -195,11 +171,26 @@ void pzl_stop(struct whc *whc)
195 1000, "stop PZL"); 171 1000, "stop PZL");
196} 172}
197 173
174/**
175 * pzl_update - request a PZL update and wait for the hardware to be synced
176 * @whc: the WHCI HC
177 * @wusbcmd: WUSBCMD value to start the update.
178 *
179 * If the WUSB HC is inactive (i.e., the PZL is stopped) then the
180 * update must be skipped as the hardware may not respond to update
181 * requests.
182 */
198void pzl_update(struct whc *whc, uint32_t wusbcmd) 183void pzl_update(struct whc *whc, uint32_t wusbcmd)
199{ 184{
200 whc_write_wusbcmd(whc, wusbcmd, wusbcmd); 185 struct wusbhc *wusbhc = &whc->wusbhc;
201 wait_event(whc->periodic_list_wq, 186
202 (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0); 187 mutex_lock(&wusbhc->mutex);
188 if (wusbhc->active) {
189 whc_write_wusbcmd(whc, wusbcmd, wusbcmd);
190 wait_event(whc->periodic_list_wq,
191 (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0);
192 }
193 mutex_unlock(&wusbhc->mutex);
203} 194}
204 195
205static void update_pzl_hw_view(struct whc *whc) 196static void update_pzl_hw_view(struct whc *whc)
@@ -235,8 +226,6 @@ void scan_periodic_work(struct work_struct *work)
235 226
236 spin_lock_irq(&whc->lock); 227 spin_lock_irq(&whc->lock);
237 228
238 dump_pzl(whc, "before processing");
239
240 for (period = 4; period >= 0; period--) { 229 for (period = 4; period >= 0; period--) {
241 list_for_each_entry_safe(qset, t, &whc->periodic_list[period], list_node) { 230 list_for_each_entry_safe(qset, t, &whc->periodic_list[period], list_node) {
242 if (!qset->in_hw_list) 231 if (!qset->in_hw_list)
@@ -248,8 +237,6 @@ void scan_periodic_work(struct work_struct *work)
248 if (update & (WHC_UPDATE_ADDED | WHC_UPDATE_REMOVED)) 237 if (update & (WHC_UPDATE_ADDED | WHC_UPDATE_REMOVED))
249 update_pzl_hw_view(whc); 238 update_pzl_hw_view(whc);
250 239
251 dump_pzl(whc, "after processing");
252
253 spin_unlock_irq(&whc->lock); 240 spin_unlock_irq(&whc->lock);
254 241
255 if (update) { 242 if (update) {
diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c
index 0420037d2e18..7be74314ee12 100644
--- a/drivers/usb/host/whci/qset.c
+++ b/drivers/usb/host/whci/qset.c
@@ -24,46 +24,6 @@
24 24
25#include "whcd.h" 25#include "whcd.h"
26 26
27void dump_qset(struct whc_qset *qset, struct device *dev)
28{
29 struct whc_std *std;
30 struct urb *urb = NULL;
31 int i;
32
33 dev_dbg(dev, "qset %08x\n", (u32)qset->qset_dma);
34 dev_dbg(dev, " -> %08x\n", (u32)qset->qh.link);
35 dev_dbg(dev, " info: %08x %08x %08x\n",
36 qset->qh.info1, qset->qh.info2, qset->qh.info3);
37 dev_dbg(dev, " sts: %04x errs: %d\n", qset->qh.status, qset->qh.err_count);
38 dev_dbg(dev, " TD: sts: %08x opts: %08x\n",
39 qset->qh.overlay.qtd.status, qset->qh.overlay.qtd.options);
40
41 for (i = 0; i < WHCI_QSET_TD_MAX; i++) {
42 dev_dbg(dev, " %c%c TD[%d]: sts: %08x opts: %08x ptr: %08x\n",
43 i == qset->td_start ? 'S' : ' ',
44 i == qset->td_end ? 'E' : ' ',
45 i, qset->qtd[i].status, qset->qtd[i].options,
46 (u32)qset->qtd[i].page_list_ptr);
47 }
48 dev_dbg(dev, " ntds: %d\n", qset->ntds);
49 list_for_each_entry(std, &qset->stds, list_node) {
50 if (urb != std->urb) {
51 urb = std->urb;
52 dev_dbg(dev, " urb %p transferred: %d bytes\n", urb,
53 urb->actual_length);
54 }
55 if (std->qtd)
56 dev_dbg(dev, " sTD[%td]: %zu bytes @ %08x\n",
57 std->qtd - &qset->qtd[0],
58 std->len, std->num_pointers ?
59 (u32)(std->pl_virt[0].buf_ptr) : (u32)std->dma_addr);
60 else
61 dev_dbg(dev, " sTD[-]: %zd bytes @ %08x\n",
62 std->len, std->num_pointers ?
63 (u32)(std->pl_virt[0].buf_ptr) : (u32)std->dma_addr);
64 }
65}
66
67struct whc_qset *qset_alloc(struct whc *whc, gfp_t mem_flags) 27struct whc_qset *qset_alloc(struct whc *whc, gfp_t mem_flags)
68{ 28{
69 struct whc_qset *qset; 29 struct whc_qset *qset;
diff --git a/drivers/usb/host/whci/whcd.h b/drivers/usb/host/whci/whcd.h
index 1d2a53bd39fd..0f3540f04f53 100644
--- a/drivers/usb/host/whci/whcd.h
+++ b/drivers/usb/host/whci/whcd.h
@@ -21,6 +21,7 @@
21#define __WHCD_H 21#define __WHCD_H
22 22
23#include <linux/uwb/whci.h> 23#include <linux/uwb/whci.h>
24#include <linux/uwb/umc.h>
24#include <linux/workqueue.h> 25#include <linux/workqueue.h>
25 26
26#include "whci-hc.h" 27#include "whci-hc.h"
@@ -28,6 +29,7 @@
28/* Generic command timeout. */ 29/* Generic command timeout. */
29#define WHC_GENCMD_TIMEOUT_MS 100 30#define WHC_GENCMD_TIMEOUT_MS 100
30 31
32struct whc_dbg;
31 33
32struct whc { 34struct whc {
33 struct wusbhc wusbhc; 35 struct wusbhc wusbhc;
@@ -69,6 +71,8 @@ struct whc {
69 struct list_head periodic_removed_list; 71 struct list_head periodic_removed_list;
70 wait_queue_head_t periodic_list_wq; 72 wait_queue_head_t periodic_list_wq;
71 struct work_struct periodic_work; 73 struct work_struct periodic_work;
74
75 struct whc_dbg *dbg;
72}; 76};
73 77
74#define wusbhc_to_whc(w) (container_of((w), struct whc, wusbhc)) 78#define wusbhc_to_whc(w) (container_of((w), struct whc, wusbhc))
@@ -136,7 +140,7 @@ int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len);
136 140
137/* wusb.c */ 141/* wusb.c */
138int whc_wusbhc_start(struct wusbhc *wusbhc); 142int whc_wusbhc_start(struct wusbhc *wusbhc);
139void whc_wusbhc_stop(struct wusbhc *wusbhc); 143void whc_wusbhc_stop(struct wusbhc *wusbhc, int delay);
140int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt, 144int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt,
141 u8 handle, struct wuie_hdr *wuie); 145 u8 handle, struct wuie_hdr *wuie);
142int whc_mmcie_rm(struct wusbhc *wusbhc, u8 handle); 146int whc_mmcie_rm(struct wusbhc *wusbhc, u8 handle);
@@ -190,8 +194,11 @@ void process_inactive_qtd(struct whc *whc, struct whc_qset *qset,
190 struct whc_qtd *qtd); 194 struct whc_qtd *qtd);
191enum whc_update qset_add_qtds(struct whc *whc, struct whc_qset *qset); 195enum whc_update qset_add_qtds(struct whc *whc, struct whc_qset *qset);
192void qset_remove_complete(struct whc *whc, struct whc_qset *qset); 196void qset_remove_complete(struct whc *whc, struct whc_qset *qset);
193void dump_qset(struct whc_qset *qset, struct device *dev);
194void pzl_update(struct whc *whc, uint32_t wusbcmd); 197void pzl_update(struct whc *whc, uint32_t wusbcmd);
195void asl_update(struct whc *whc, uint32_t wusbcmd); 198void asl_update(struct whc *whc, uint32_t wusbcmd);
196 199
200/* debug.c */
201void whc_dbg_init(struct whc *whc);
202void whc_dbg_clean_up(struct whc *whc);
203
197#endif /* #ifndef __WHCD_H */ 204#endif /* #ifndef __WHCD_H */
diff --git a/drivers/usb/host/whci/whci-hc.h b/drivers/usb/host/whci/whci-hc.h
index bff1eb7a35cf..51df7e313b38 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 66e4ddcd961d..f24efdebad17 100644
--- a/drivers/usb/host/whci/wusb.c
+++ b/drivers/usb/host/whci/wusb.c
@@ -15,47 +15,19 @@
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>
22#define D_LOCAL 1
23#include <linux/uwb/debug.h>
24 21
25#include "../../wusbcore/wusbhc.h" 22#include "../../wusbcore/wusbhc.h"
26 23
27#include "whcd.h" 24#include "whcd.h"
28 25
29#if D_LOCAL >= 1
30static void dump_di(struct whc *whc, int idx)
31{
32 struct di_buf_entry *di = &whc->di_buf[idx];
33 struct device *dev = &whc->umc->dev;
34 char buf[128];
35
36 bitmap_scnprintf(buf, sizeof(buf), (unsigned long *)di->availability_info, UWB_NUM_MAS);
37
38 d_printf(1, dev, "DI[%d]\n", idx);
39 d_printf(1, dev, " availability: %s\n", buf);
40 d_printf(1, dev, " %c%c key idx: %d dev addr: %d\n",
41 (di->addr_sec_info & WHC_DI_SECURE) ? 'S' : ' ',
42 (di->addr_sec_info & WHC_DI_DISABLE) ? 'D' : ' ',
43 (di->addr_sec_info & WHC_DI_KEY_IDX_MASK) >> 8,
44 (di->addr_sec_info & WHC_DI_DEV_ADDR_MASK));
45}
46#else
47static inline void dump_di(struct whc *whc, int idx)
48{
49}
50#endif
51
52static int whc_update_di(struct whc *whc, int idx) 26static int whc_update_di(struct whc *whc, int idx)
53{ 27{
54 int offset = idx / 32; 28 int offset = idx / 32;
55 u32 bit = 1 << (idx % 32); 29 u32 bit = 1 << (idx % 32);
56 30
57 dump_di(whc, idx);
58
59 le_writel(bit, whc->base + WUSBDIBUPDATED + offset); 31 le_writel(bit, whc->base + WUSBDIBUPDATED + offset);
60 32
61 return whci_wait_for(&whc->umc->dev, 33 return whci_wait_for(&whc->umc->dev,
@@ -64,8 +36,9 @@ static int whc_update_di(struct whc *whc, int idx)
64} 36}
65 37
66/* 38/*
67 * WHCI starts and stops MMCs based on there being a valid GTK so 39 * WHCI starts MMCs based on there being a valid GTK so these need
68 * these need only start/stop the asynchronous and periodic schedules. 40 * only start/stop the asynchronous and periodic schedules and send a
41 * channel stop command.
69 */ 42 */
70 43
71int whc_wusbhc_start(struct wusbhc *wusbhc) 44int whc_wusbhc_start(struct wusbhc *wusbhc)
@@ -78,12 +51,20 @@ int whc_wusbhc_start(struct wusbhc *wusbhc)
78 return 0; 51 return 0;
79} 52}
80 53
81void whc_wusbhc_stop(struct wusbhc *wusbhc) 54void whc_wusbhc_stop(struct wusbhc *wusbhc, int delay)
82{ 55{
83 struct whc *whc = wusbhc_to_whc(wusbhc); 56 struct whc *whc = wusbhc_to_whc(wusbhc);
57 u32 stop_time, now_time;
58 int ret;
84 59
85 pzl_stop(whc); 60 pzl_stop(whc);
86 asl_stop(whc); 61 asl_stop(whc);
62
63 now_time = le_readl(whc->base + WUSBTIME) & WUSBTIME_CHANNEL_TIME_MASK;
64 stop_time = (now_time + ((delay * 8) << 7)) & 0x00ffffff;
65 ret = whc_do_gencmd(whc, WUSBGENCMDSTS_CHAN_STOP, stop_time, NULL, 0);
66 if (ret == 0)
67 msleep(delay);
87} 68}
88 69
89int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt, 70int 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 ab4788d1785a..1335cbe1191d 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 c36c4389baae..9ec7fd5da489 100644
--- a/drivers/usb/wusbcore/crypto.c
+++ b/drivers/usb/wusbcore/crypto.c
@@ -51,9 +51,17 @@
51#include <linux/uwb.h> 51#include <linux/uwb.h>
52#include <linux/usb/wusb.h> 52#include <linux/usb/wusb.h>
53#include <linux/scatterlist.h> 53#include <linux/scatterlist.h>
54#define D_LOCAL 0
55#include <linux/uwb/debug.h>
56 54
55static int debug_crypto_verify = 0;
56
57module_param(debug_crypto_verify, int, 0);
58MODULE_PARM_DESC(debug_crypto_verify, "verify the key generation algorithms");
59
60static void wusb_key_dump(const void *buf, size_t len)
61{
62 print_hex_dump(KERN_ERR, " ", DUMP_PREFIX_OFFSET, 16, 1,
63 buf, len, 0);
64}
57 65
58/* 66/*
59 * Block of data, as understood by AES-CCM 67 * Block of data, as understood by AES-CCM
@@ -203,9 +211,6 @@ static int wusb_ccm_mac(struct crypto_blkcipher *tfm_cbc,
203 const u8 bzero[16] = { 0 }; 211 const u8 bzero[16] = { 0 };
204 size_t zero_padding; 212 size_t zero_padding;
205 213
206 d_fnstart(3, NULL, "(tfm_cbc %p, tfm_aes %p, mic %p, "
207 "n %p, a %p, b %p, blen %zu)\n",
208 tfm_cbc, tfm_aes, mic, n, a, b, blen);
209 /* 214 /*
210 * These checks should be compile time optimized out 215 * These checks should be compile time optimized out
211 * ensure @a fills b1's mac_header and following fields 216 * ensure @a fills b1's mac_header and following fields
@@ -247,16 +252,6 @@ static int wusb_ccm_mac(struct crypto_blkcipher *tfm_cbc,
247 b1.la = cpu_to_be16(blen + 14); 252 b1.la = cpu_to_be16(blen + 14);
248 memcpy(&b1.mac_header, a, sizeof(*a)); 253 memcpy(&b1.mac_header, a, sizeof(*a));
249 254
250 d_printf(4, NULL, "I: B0 (%zu bytes)\n", sizeof(b0));
251 d_dump(4, NULL, &b0, sizeof(b0));
252 d_printf(4, NULL, "I: B1 (%zu bytes)\n", sizeof(b1));
253 d_dump(4, NULL, &b1, sizeof(b1));
254 d_printf(4, NULL, "I: B (%zu bytes)\n", blen);
255 d_dump(4, NULL, b, blen);
256 d_printf(4, NULL, "I: B 0-padding (%zu bytes)\n", zero_padding);
257 d_printf(4, NULL, "D: IV before crypto (%zu)\n", ivsize);
258 d_dump(4, NULL, iv, ivsize);
259
260 sg_init_table(sg, ARRAY_SIZE(sg)); 255 sg_init_table(sg, ARRAY_SIZE(sg));
261 sg_set_buf(&sg[0], &b0, sizeof(b0)); 256 sg_set_buf(&sg[0], &b0, sizeof(b0));
262 sg_set_buf(&sg[1], &b1, sizeof(b1)); 257 sg_set_buf(&sg[1], &b1, sizeof(b1));
@@ -273,8 +268,6 @@ static int wusb_ccm_mac(struct crypto_blkcipher *tfm_cbc,
273 result); 268 result);
274 goto error_cbc_crypt; 269 goto error_cbc_crypt;
275 } 270 }
276 d_printf(4, NULL, "D: MIC tag\n");
277 d_dump(4, NULL, iv, ivsize);
278 271
279 /* Now we crypt the MIC Tag (*iv) with Ax -- values per WUSB1.0[6.5] 272 /* Now we crypt the MIC Tag (*iv) with Ax -- values per WUSB1.0[6.5]
280 * The procedure is to AES crypt the A0 block and XOR the MIC 273 * The procedure is to AES crypt the A0 block and XOR the MIC
@@ -289,17 +282,10 @@ static int wusb_ccm_mac(struct crypto_blkcipher *tfm_cbc,
289 ax.counter = 0; 282 ax.counter = 0;
290 crypto_cipher_encrypt_one(tfm_aes, (void *)&ax, (void *)&ax); 283 crypto_cipher_encrypt_one(tfm_aes, (void *)&ax, (void *)&ax);
291 bytewise_xor(mic, &ax, iv, 8); 284 bytewise_xor(mic, &ax, iv, 8);
292 d_printf(4, NULL, "D: CTR[MIC]\n");
293 d_dump(4, NULL, &ax, 8);
294 d_printf(4, NULL, "D: CCM-MIC tag\n");
295 d_dump(4, NULL, mic, 8);
296 result = 8; 285 result = 8;
297error_cbc_crypt: 286error_cbc_crypt:
298 kfree(dst_buf); 287 kfree(dst_buf);
299error_dst_buf: 288error_dst_buf:
300 d_fnend(3, NULL, "(tfm_cbc %p, tfm_aes %p, mic %p, "
301 "n %p, a %p, b %p, blen %zu)\n",
302 tfm_cbc, tfm_aes, mic, n, a, b, blen);
303 return result; 289 return result;
304} 290}
305 291
@@ -321,10 +307,6 @@ ssize_t wusb_prf(void *out, size_t out_size,
321 u64 sfn = 0; 307 u64 sfn = 0;
322 __le64 sfn_le; 308 __le64 sfn_le;
323 309
324 d_fnstart(3, NULL, "(out %p, out_size %zu, key %p, _n %p, "
325 "a %p, b %p, blen %zu, len %zu)\n", out, out_size,
326 key, _n, a, b, blen, len);
327
328 tfm_cbc = crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC); 310 tfm_cbc = crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
329 if (IS_ERR(tfm_cbc)) { 311 if (IS_ERR(tfm_cbc)) {
330 result = PTR_ERR(tfm_cbc); 312 result = PTR_ERR(tfm_cbc);
@@ -366,9 +348,6 @@ error_alloc_aes:
366error_setkey_cbc: 348error_setkey_cbc:
367 crypto_free_blkcipher(tfm_cbc); 349 crypto_free_blkcipher(tfm_cbc);
368error_alloc_cbc: 350error_alloc_cbc:
369 d_fnend(3, NULL, "(out %p, out_size %zu, key %p, _n %p, "
370 "a %p, b %p, blen %zu, len %zu) = %d\n", out, out_size,
371 key, _n, a, b, blen, len, (int)bytes);
372 return result; 351 return result;
373} 352}
374 353
@@ -422,14 +401,14 @@ static int wusb_oob_mic_verify(void)
422 "mismatch between MIC result and WUSB1.0[A2]\n"); 401 "mismatch between MIC result and WUSB1.0[A2]\n");
423 hs_size = sizeof(stv_hsmic_hs) - sizeof(stv_hsmic_hs.MIC); 402 hs_size = sizeof(stv_hsmic_hs) - sizeof(stv_hsmic_hs.MIC);
424 printk(KERN_ERR "E: Handshake2 in: (%zu bytes)\n", hs_size); 403 printk(KERN_ERR "E: Handshake2 in: (%zu bytes)\n", hs_size);
425 dump_bytes(NULL, &stv_hsmic_hs, hs_size); 404 wusb_key_dump(&stv_hsmic_hs, hs_size);
426 printk(KERN_ERR "E: CCM Nonce in: (%zu bytes)\n", 405 printk(KERN_ERR "E: CCM Nonce in: (%zu bytes)\n",
427 sizeof(stv_hsmic_n)); 406 sizeof(stv_hsmic_n));
428 dump_bytes(NULL, &stv_hsmic_n, sizeof(stv_hsmic_n)); 407 wusb_key_dump(&stv_hsmic_n, sizeof(stv_hsmic_n));
429 printk(KERN_ERR "E: MIC out:\n"); 408 printk(KERN_ERR "E: MIC out:\n");
430 dump_bytes(NULL, mic, sizeof(mic)); 409 wusb_key_dump(mic, sizeof(mic));
431 printk(KERN_ERR "E: MIC out (from WUSB1.0[A.2]):\n"); 410 printk(KERN_ERR "E: MIC out (from WUSB1.0[A.2]):\n");
432 dump_bytes(NULL, stv_hsmic_hs.MIC, sizeof(stv_hsmic_hs.MIC)); 411 wusb_key_dump(stv_hsmic_hs.MIC, sizeof(stv_hsmic_hs.MIC));
433 result = -EINVAL; 412 result = -EINVAL;
434 } else 413 } else
435 result = 0; 414 result = 0;
@@ -497,19 +476,16 @@ static int wusb_key_derive_verify(void)
497 printk(KERN_ERR "E: WUSB key derivation test: " 476 printk(KERN_ERR "E: WUSB key derivation test: "
498 "mismatch between key derivation result " 477 "mismatch between key derivation result "
499 "and WUSB1.0[A1] Errata 2006/12\n"); 478 "and WUSB1.0[A1] Errata 2006/12\n");
500 printk(KERN_ERR "E: keydvt in: key (%zu bytes)\n", 479 printk(KERN_ERR "E: keydvt in: key\n");
501 sizeof(stv_key_a1)); 480 wusb_key_dump(stv_key_a1, sizeof(stv_key_a1));
502 dump_bytes(NULL, stv_key_a1, sizeof(stv_key_a1)); 481 printk(KERN_ERR "E: keydvt in: nonce\n");
503 printk(KERN_ERR "E: keydvt in: nonce (%zu bytes)\n", 482 wusb_key_dump( &stv_keydvt_n_a1, sizeof(stv_keydvt_n_a1));
504 sizeof(stv_keydvt_n_a1)); 483 printk(KERN_ERR "E: keydvt in: hnonce & dnonce\n");
505 dump_bytes(NULL, &stv_keydvt_n_a1, sizeof(stv_keydvt_n_a1)); 484 wusb_key_dump(&stv_keydvt_in_a1, sizeof(stv_keydvt_in_a1));
506 printk(KERN_ERR "E: keydvt in: hnonce & dnonce (%zu bytes)\n",
507 sizeof(stv_keydvt_in_a1));
508 dump_bytes(NULL, &stv_keydvt_in_a1, sizeof(stv_keydvt_in_a1));
509 printk(KERN_ERR "E: keydvt out: KCK\n"); 485 printk(KERN_ERR "E: keydvt out: KCK\n");
510 dump_bytes(NULL, &keydvt_out.kck, sizeof(keydvt_out.kck)); 486 wusb_key_dump(&keydvt_out.kck, sizeof(keydvt_out.kck));
511 printk(KERN_ERR "E: keydvt out: PTK\n"); 487 printk(KERN_ERR "E: keydvt out: PTK\n");
512 dump_bytes(NULL, &keydvt_out.ptk, sizeof(keydvt_out.ptk)); 488 wusb_key_dump(&keydvt_out.ptk, sizeof(keydvt_out.ptk));
513 result = -EINVAL; 489 result = -EINVAL;
514 } else 490 } else
515 result = 0; 491 result = 0;
@@ -526,10 +502,13 @@ int wusb_crypto_init(void)
526{ 502{
527 int result; 503 int result;
528 504
529 result = wusb_key_derive_verify(); 505 if (debug_crypto_verify) {
530 if (result < 0) 506 result = wusb_key_derive_verify();
531 return result; 507 if (result < 0)
532 return wusb_oob_mic_verify(); 508 return result;
509 return wusb_oob_mic_verify();
510 }
511 return 0;
533} 512}
534 513
535void wusb_crypto_exit(void) 514void wusb_crypto_exit(void)
diff --git a/drivers/usb/wusbcore/dev-sysfs.c b/drivers/usb/wusbcore/dev-sysfs.c
index 7897a19652e5..101834576236 100644
--- a/drivers/usb/wusbcore/dev-sysfs.c
+++ b/drivers/usb/wusbcore/dev-sysfs.c
@@ -28,10 +28,6 @@
28#include <linux/workqueue.h> 28#include <linux/workqueue.h>
29#include "wusbhc.h" 29#include "wusbhc.h"
30 30
31#undef D_LOCAL
32#define D_LOCAL 4
33#include <linux/uwb/debug.h>
34
35static ssize_t wusb_disconnect_store(struct device *dev, 31static ssize_t wusb_disconnect_store(struct device *dev,
36 struct device_attribute *attr, 32 struct device_attribute *attr,
37 const char *buf, size_t size) 33 const char *buf, size_t size)
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c
index f45d777bef34..e2e7e4bc8463 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 *
@@ -97,10 +91,6 @@
97#include <linux/workqueue.h> 91#include <linux/workqueue.h>
98#include "wusbhc.h" 92#include "wusbhc.h"
99 93
100#undef D_LOCAL
101#define D_LOCAL 1
102#include <linux/uwb/debug.h>
103
104static void wusbhc_devconnect_acked_work(struct work_struct *work); 94static void wusbhc_devconnect_acked_work(struct work_struct *work);
105 95
106static void wusb_dev_free(struct wusb_dev *wusb_dev) 96static void wusb_dev_free(struct wusb_dev *wusb_dev)
@@ -240,6 +230,7 @@ static struct wusb_dev *wusbhc_cack_add(struct wusbhc *wusbhc,
240 list_add_tail(&wusb_dev->cack_node, &wusbhc->cack_list); 230 list_add_tail(&wusb_dev->cack_node, &wusbhc->cack_list);
241 wusbhc->cack_count++; 231 wusbhc->cack_count++;
242 wusbhc_fill_cack_ie(wusbhc); 232 wusbhc_fill_cack_ie(wusbhc);
233
243 return wusb_dev; 234 return wusb_dev;
244} 235}
245 236
@@ -250,12 +241,9 @@ static struct wusb_dev *wusbhc_cack_add(struct wusbhc *wusbhc,
250 */ 241 */
251static void wusbhc_cack_rm(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev) 242static void wusbhc_cack_rm(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
252{ 243{
253 struct device *dev = wusbhc->dev;
254 d_fnstart(3, dev, "(wusbhc %p wusb_dev %p)\n", wusbhc, wusb_dev);
255 list_del_init(&wusb_dev->cack_node); 244 list_del_init(&wusb_dev->cack_node);
256 wusbhc->cack_count--; 245 wusbhc->cack_count--;
257 wusbhc_fill_cack_ie(wusbhc); 246 wusbhc_fill_cack_ie(wusbhc);
258 d_fnend(3, dev, "(wusbhc %p wusb_dev %p) = void\n", wusbhc, wusb_dev);
259} 247}
260 248
261/* 249/*
@@ -263,14 +251,11 @@ static void wusbhc_cack_rm(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
263static 251static
264void wusbhc_devconnect_acked(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev) 252void wusbhc_devconnect_acked(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
265{ 253{
266 struct device *dev = wusbhc->dev;
267 d_fnstart(3, dev, "(wusbhc %p wusb_dev %p)\n", wusbhc, wusb_dev);
268 wusbhc_cack_rm(wusbhc, wusb_dev); 254 wusbhc_cack_rm(wusbhc, wusb_dev);
269 if (wusbhc->cack_count) 255 if (wusbhc->cack_count)
270 wusbhc_mmcie_set(wusbhc, 0, 0, &wusbhc->cack_ie.hdr); 256 wusbhc_mmcie_set(wusbhc, 0, 0, &wusbhc->cack_ie.hdr);
271 else 257 else
272 wusbhc_mmcie_rm(wusbhc, &wusbhc->cack_ie.hdr); 258 wusbhc_mmcie_rm(wusbhc, &wusbhc->cack_ie.hdr);
273 d_fnend(3, dev, "(wusbhc %p wusb_dev %p) = void\n", wusbhc, wusb_dev);
274} 259}
275 260
276static void wusbhc_devconnect_acked_work(struct work_struct *work) 261static void wusbhc_devconnect_acked_work(struct work_struct *work)
@@ -320,7 +305,6 @@ void wusbhc_devconnect_ack(struct wusbhc *wusbhc, struct wusb_dn_connect *dnc,
320 struct wusb_port *port; 305 struct wusb_port *port;
321 unsigned idx, devnum; 306 unsigned idx, devnum;
322 307
323 d_fnstart(3, dev, "(%p, %p, %s)\n", wusbhc, dnc, pr_cdid);
324 mutex_lock(&wusbhc->mutex); 308 mutex_lock(&wusbhc->mutex);
325 309
326 /* Check we are not handling it already */ 310 /* Check we are not handling it already */
@@ -366,16 +350,13 @@ void wusbhc_devconnect_ack(struct wusbhc *wusbhc, struct wusb_dn_connect *dnc,
366 port->wusb_dev = wusb_dev; 350 port->wusb_dev = wusb_dev;
367 port->status |= USB_PORT_STAT_CONNECTION; 351 port->status |= USB_PORT_STAT_CONNECTION;
368 port->change |= USB_PORT_STAT_C_CONNECTION; 352 port->change |= USB_PORT_STAT_C_CONNECTION;
369 port->reset_count = 0;
370 /* Now the port status changed to connected; khubd will 353 /* Now the port status changed to connected; khubd will
371 * pick the change up and try to reset the port to bring it to 354 * 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 355 * the enabled state--so this process returns up to the stack
373 * and it calls back into wusbhc_rh_port_reset() who will call 356 * and it calls back into wusbhc_rh_port_reset().
374 * devconnect_auth().
375 */ 357 */
376error_unlock: 358error_unlock:
377 mutex_unlock(&wusbhc->mutex); 359 mutex_unlock(&wusbhc->mutex);
378 d_fnend(3, dev, "(%p, %p, %s) = void\n", wusbhc, dnc, pr_cdid);
379 return; 360 return;
380 361
381} 362}
@@ -398,10 +379,8 @@ error_unlock:
398static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc, 379static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc,
399 struct wusb_port *port) 380 struct wusb_port *port)
400{ 381{
401 struct device *dev = wusbhc->dev;
402 struct wusb_dev *wusb_dev = port->wusb_dev; 382 struct wusb_dev *wusb_dev = port->wusb_dev;
403 383
404 d_fnstart(3, dev, "(wusbhc %p, port %p)\n", wusbhc, port);
405 port->status &= ~(USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE 384 port->status &= ~(USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE
406 | USB_PORT_STAT_SUSPEND | USB_PORT_STAT_RESET 385 | USB_PORT_STAT_SUSPEND | USB_PORT_STAT_RESET
407 | USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED); 386 | USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED);
@@ -413,15 +392,11 @@ static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc,
413 wusb_dev_put(wusb_dev); 392 wusb_dev_put(wusb_dev);
414 } 393 }
415 port->wusb_dev = NULL; 394 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 395
420 /* After a device disconnects, change the GTK (see [WUSB] 396 /* After a device disconnects, change the GTK (see [WUSB]
421 * section 6.2.11.2). */ 397 * section 6.2.11.2). */
422 wusbhc_gtk_rekey(wusbhc); 398 wusbhc_gtk_rekey(wusbhc);
423 399
424 d_fnend(3, dev, "(wusbhc %p, port %p) = void\n", wusbhc, port);
425 /* The Wireless USB part has forgotten about the device already; now 400 /* The Wireless USB part has forgotten about the device already; now
426 * khubd's timer will pick up the disconnection and remove the USB 401 * khubd's timer will pick up the disconnection and remove the USB
427 * device from the system 402 * device from the system
@@ -429,39 +404,6 @@ static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc,
429} 404}
430 405
431/* 406/*
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 407 * Refresh the list of keep alives to emit in the MMC
466 * 408 *
467 * Some devices don't respond to keep alives unless they've been 409 * Some devices don't respond to keep alives unless they've been
@@ -528,21 +470,15 @@ static void __wusbhc_keep_alive(struct wusbhc *wusbhc)
528 */ 470 */
529static void wusbhc_keep_alive_run(struct work_struct *ws) 471static void wusbhc_keep_alive_run(struct work_struct *ws)
530{ 472{
531 struct delayed_work *dw = 473 struct delayed_work *dw = container_of(ws, struct delayed_work, work);
532 container_of(ws, struct delayed_work, work); 474 struct wusbhc *wusbhc = container_of(dw, struct wusbhc, keep_alive_timer);
533 struct wusbhc *wusbhc = 475
534 container_of(dw, struct wusbhc, keep_alive_timer); 476 mutex_lock(&wusbhc->mutex);
535 477 __wusbhc_keep_alive(wusbhc);
536 d_fnstart(5, wusbhc->dev, "(wusbhc %p)\n", wusbhc); 478 mutex_unlock(&wusbhc->mutex);
537 if (wusbhc->active) { 479
538 mutex_lock(&wusbhc->mutex); 480 queue_delayed_work(wusbd, &wusbhc->keep_alive_timer,
539 __wusbhc_keep_alive(wusbhc); 481 msecs_to_jiffies(wusbhc->trust_timeout / 2));
540 mutex_unlock(&wusbhc->mutex);
541 queue_delayed_work(wusbd, &wusbhc->keep_alive_timer,
542 (wusbhc->trust_timeout * CONFIG_HZ)/1000/2);
543 }
544 d_fnend(5, wusbhc->dev, "(wusbhc %p) = void\n", wusbhc);
545 return;
546} 482}
547 483
548/* 484/*
@@ -585,10 +521,6 @@ static struct wusb_dev *wusbhc_find_dev_by_addr(struct wusbhc *wusbhc, u8 addr)
585 */ 521 */
586static void wusbhc_handle_dn_alive(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev) 522static void wusbhc_handle_dn_alive(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
587{ 523{
588 struct device *dev = wusbhc->dev;
589
590 d_printf(2, dev, "DN ALIVE: device 0x%02x pong\n", wusb_dev->addr);
591
592 mutex_lock(&wusbhc->mutex); 524 mutex_lock(&wusbhc->mutex);
593 wusb_dev->entry_ts = jiffies; 525 wusb_dev->entry_ts = jiffies;
594 __wusbhc_keep_alive(wusbhc); 526 __wusbhc_keep_alive(wusbhc);
@@ -621,11 +553,10 @@ static void wusbhc_handle_dn_connect(struct wusbhc *wusbhc,
621 "no-beacon" 553 "no-beacon"
622 }; 554 };
623 555
624 d_fnstart(3, dev, "(%p, %p, %zu)\n", wusbhc, dn_hdr, size);
625 if (size < sizeof(*dnc)) { 556 if (size < sizeof(*dnc)) {
626 dev_err(dev, "DN CONNECT: short notification (%zu < %zu)\n", 557 dev_err(dev, "DN CONNECT: short notification (%zu < %zu)\n",
627 size, sizeof(*dnc)); 558 size, sizeof(*dnc));
628 goto out; 559 return;
629 } 560 }
630 561
631 dnc = container_of(dn_hdr, struct wusb_dn_connect, hdr); 562 dnc = container_of(dn_hdr, struct wusb_dn_connect, hdr);
@@ -637,10 +568,6 @@ static void wusbhc_handle_dn_connect(struct wusbhc *wusbhc,
637 wusb_dn_connect_new_connection(dnc) ? "connect" : "reconnect"); 568 wusb_dn_connect_new_connection(dnc) ? "connect" : "reconnect");
638 /* ACK the connect */ 569 /* ACK the connect */
639 wusbhc_devconnect_ack(wusbhc, dnc, pr_cdid); 570 wusbhc_devconnect_ack(wusbhc, dnc, pr_cdid);
640out:
641 d_fnend(3, dev, "(%p, %p, %zu) = void\n",
642 wusbhc, dn_hdr, size);
643 return;
644} 571}
645 572
646/* 573/*
@@ -662,60 +589,6 @@ static void wusbhc_handle_dn_disconnect(struct wusbhc *wusbhc, struct wusb_dev *
662} 589}
663 590
664/* 591/*
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 592 * Handle a Device Notification coming a host
720 * 593 *
721 * The Device Notification comes from a host (HWA, DWA or WHCI) 594 * The Device Notification comes from a host (HWA, DWA or WHCI)
@@ -735,19 +608,17 @@ void wusbhc_handle_dn(struct wusbhc *wusbhc, u8 srcaddr,
735 struct device *dev = wusbhc->dev; 608 struct device *dev = wusbhc->dev;
736 struct wusb_dev *wusb_dev; 609 struct wusb_dev *wusb_dev;
737 610
738 d_fnstart(3, dev, "(%p, %p)\n", wusbhc, dn_hdr);
739
740 if (size < sizeof(struct wusb_dn_hdr)) { 611 if (size < sizeof(struct wusb_dn_hdr)) {
741 dev_err(dev, "DN data shorter than DN header (%d < %d)\n", 612 dev_err(dev, "DN data shorter than DN header (%d < %d)\n",
742 (int)size, (int)sizeof(struct wusb_dn_hdr)); 613 (int)size, (int)sizeof(struct wusb_dn_hdr));
743 goto out; 614 return;
744 } 615 }
745 616
746 wusb_dev = wusbhc_find_dev_by_addr(wusbhc, srcaddr); 617 wusb_dev = wusbhc_find_dev_by_addr(wusbhc, srcaddr);
747 if (wusb_dev == NULL && dn_hdr->bType != WUSB_DN_CONNECT) { 618 if (wusb_dev == NULL && dn_hdr->bType != WUSB_DN_CONNECT) {
748 dev_dbg(dev, "ignoring DN %d from unconnected device %02x\n", 619 dev_dbg(dev, "ignoring DN %d from unconnected device %02x\n",
749 dn_hdr->bType, srcaddr); 620 dn_hdr->bType, srcaddr);
750 goto out; 621 return;
751 } 622 }
752 623
753 switch (dn_hdr->bType) { 624 switch (dn_hdr->bType) {
@@ -772,9 +643,6 @@ void wusbhc_handle_dn(struct wusbhc *wusbhc, u8 srcaddr,
772 dev_warn(dev, "unknown DN %u (%d octets) from %u\n", 643 dev_warn(dev, "unknown DN %u (%d octets) from %u\n",
773 dn_hdr->bType, (int)size, srcaddr); 644 dn_hdr->bType, (int)size, srcaddr);
774 } 645 }
775out:
776 d_fnend(3, dev, "(%p, %p) = void\n", wusbhc, dn_hdr);
777 return;
778} 646}
779EXPORT_SYMBOL_GPL(wusbhc_handle_dn); 647EXPORT_SYMBOL_GPL(wusbhc_handle_dn);
780 648
@@ -804,59 +672,30 @@ void __wusbhc_dev_disable(struct wusbhc *wusbhc, u8 port_idx)
804 struct wusb_dev *wusb_dev; 672 struct wusb_dev *wusb_dev;
805 struct wuie_disconnect *ie; 673 struct wuie_disconnect *ie;
806 674
807 d_fnstart(3, dev, "(%p, %u)\n", wusbhc, port_idx);
808 result = 0;
809 wusb_dev = wusb_port_by_idx(wusbhc, port_idx)->wusb_dev; 675 wusb_dev = wusb_port_by_idx(wusbhc, port_idx)->wusb_dev;
810 if (wusb_dev == NULL) { 676 if (wusb_dev == NULL) {
811 /* reset no device? ignore */ 677 /* reset no device? ignore */
812 dev_dbg(dev, "DISCONNECT: no device at port %u, ignoring\n", 678 dev_dbg(dev, "DISCONNECT: no device at port %u, ignoring\n",
813 port_idx); 679 port_idx);
814 goto error; 680 return;
815 } 681 }
816 __wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, port_idx)); 682 __wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, port_idx));
817 683
818 result = -ENOMEM;
819 ie = kzalloc(sizeof(*ie), GFP_KERNEL); 684 ie = kzalloc(sizeof(*ie), GFP_KERNEL);
820 if (ie == NULL) 685 if (ie == NULL)
821 goto error; 686 return;
822 ie->hdr.bLength = sizeof(*ie); 687 ie->hdr.bLength = sizeof(*ie);
823 ie->hdr.bIEIdentifier = WUIE_ID_DEVICE_DISCONNECT; 688 ie->hdr.bIEIdentifier = WUIE_ID_DEVICE_DISCONNECT;
824 ie->bDeviceAddress = wusb_dev->addr; 689 ie->bDeviceAddress = wusb_dev->addr;
825 result = wusbhc_mmcie_set(wusbhc, 0, 0, &ie->hdr); 690 result = wusbhc_mmcie_set(wusbhc, 0, 0, &ie->hdr);
826 if (result < 0) { 691 if (result < 0)
827 dev_err(dev, "DISCONNECT: can't set MMC: %d\n", result); 692 dev_err(dev, "DISCONNECT: can't set MMC: %d\n", result);
828 goto error_kfree; 693 else {
694 /* At least 6 MMCs, assuming at least 1 MMC per zone. */
695 msleep(7*4);
696 wusbhc_mmcie_rm(wusbhc, &ie->hdr);
829 } 697 }
830
831 /* 120ms, hopefully 6 MMCs */
832 msleep(100);
833 wusbhc_mmcie_rm(wusbhc, &ie->hdr);
834error_kfree:
835 kfree(ie); 698 kfree(ie);
836error:
837 d_fnend(3, dev, "(%p, %u) = %d\n", wusbhc, port_idx, result);
838 return;
839}
840
841static void wusb_cap_descr_printf(const unsigned level, struct device *dev,
842 const struct usb_wireless_cap_descriptor *wcd)
843{
844 d_printf(level, dev,
845 "WUSB Capability Descriptor\n"
846 " bDevCapabilityType 0x%02x\n"
847 " bmAttributes 0x%02x\n"
848 " wPhyRates 0x%04x\n"
849 " bmTFITXPowerInfo 0x%02x\n"
850 " bmFFITXPowerInfo 0x%02x\n"
851 " bmBandGroup 0x%04x\n"
852 " bReserved 0x%02x\n",
853 wcd->bDevCapabilityType,
854 wcd->bmAttributes,
855 le16_to_cpu(wcd->wPHYRates),
856 wcd->bmTFITXPowerInfo,
857 wcd->bmFFITXPowerInfo,
858 wcd->bmBandGroup,
859 wcd->bReserved);
860} 699}
861 700
862/* 701/*
@@ -899,8 +738,6 @@ static int wusb_dev_bos_grok(struct usb_device *usb_dev,
899 } 738 }
900 cap_size = cap_hdr->bLength; 739 cap_size = cap_hdr->bLength;
901 cap_type = cap_hdr->bDevCapabilityType; 740 cap_type = cap_hdr->bDevCapabilityType;
902 d_printf(4, dev, "BOS Capability: 0x%02x (%zu bytes)\n",
903 cap_type, cap_size);
904 if (cap_size == 0) 741 if (cap_size == 0)
905 break; 742 break;
906 if (cap_size > top - itr) { 743 if (cap_size > top - itr) {
@@ -912,7 +749,6 @@ static int wusb_dev_bos_grok(struct usb_device *usb_dev,
912 result = -EBADF; 749 result = -EBADF;
913 goto error_bad_cap; 750 goto error_bad_cap;
914 } 751 }
915 d_dump(3, dev, itr, cap_size);
916 switch (cap_type) { 752 switch (cap_type) {
917 case USB_CAP_TYPE_WIRELESS_USB: 753 case USB_CAP_TYPE_WIRELESS_USB:
918 if (cap_size != sizeof(*wusb_dev->wusb_cap_descr)) 754 if (cap_size != sizeof(*wusb_dev->wusb_cap_descr))
@@ -920,10 +756,8 @@ static int wusb_dev_bos_grok(struct usb_device *usb_dev,
920 "descriptor is %zu bytes vs %zu " 756 "descriptor is %zu bytes vs %zu "
921 "needed\n", cap_size, 757 "needed\n", cap_size,
922 sizeof(*wusb_dev->wusb_cap_descr)); 758 sizeof(*wusb_dev->wusb_cap_descr));
923 else { 759 else
924 wusb_dev->wusb_cap_descr = itr; 760 wusb_dev->wusb_cap_descr = itr;
925 wusb_cap_descr_printf(3, dev, itr);
926 }
927 break; 761 break;
928 default: 762 default:
929 dev_err(dev, "BUG? Unknown BOS capability 0x%02x " 763 dev_err(dev, "BUG? Unknown BOS capability 0x%02x "
@@ -988,9 +822,7 @@ static int wusb_dev_bos_add(struct usb_device *usb_dev,
988 "%zu bytes): %zd\n", desc_size, result); 822 "%zu bytes): %zd\n", desc_size, result);
989 goto error_get_descriptor; 823 goto error_get_descriptor;
990 } 824 }
991 d_printf(2, dev, "Got BOS descriptor %zd bytes, %u capabilities\n", 825
992 result, bos->bNumDeviceCaps);
993 d_dump(2, dev, bos, result);
994 result = wusb_dev_bos_grok(usb_dev, wusb_dev, bos, result); 826 result = wusb_dev_bos_grok(usb_dev, wusb_dev, bos, result);
995 if (result < 0) 827 if (result < 0)
996 goto error_bad_bos; 828 goto error_bad_bos;
@@ -1056,8 +888,6 @@ static void wusb_dev_add_ncb(struct usb_device *usb_dev)
1056 if (usb_dev->wusb == 0 || usb_dev->devnum == 1) 888 if (usb_dev->wusb == 0 || usb_dev->devnum == 1)
1057 return; /* skip non wusb and wusb RHs */ 889 return; /* skip non wusb and wusb RHs */
1058 890
1059 d_fnstart(3, dev, "(usb_dev %p)\n", usb_dev);
1060
1061 wusbhc = wusbhc_get_by_usb_dev(usb_dev); 891 wusbhc = wusbhc_get_by_usb_dev(usb_dev);
1062 if (wusbhc == NULL) 892 if (wusbhc == NULL)
1063 goto error_nodev; 893 goto error_nodev;
@@ -1087,7 +917,6 @@ out:
1087 wusb_dev_put(wusb_dev); 917 wusb_dev_put(wusb_dev);
1088 wusbhc_put(wusbhc); 918 wusbhc_put(wusbhc);
1089error_nodev: 919error_nodev:
1090 d_fnend(3, dev, "(usb_dev %p) = void\n", usb_dev);
1091 return; 920 return;
1092 921
1093 wusb_dev_sysfs_rm(wusb_dev); 922 wusb_dev_sysfs_rm(wusb_dev);
@@ -1174,11 +1003,10 @@ EXPORT_SYMBOL_GPL(__wusb_dev_get_by_usb_dev);
1174 1003
1175void wusb_dev_destroy(struct kref *_wusb_dev) 1004void wusb_dev_destroy(struct kref *_wusb_dev)
1176{ 1005{
1177 struct wusb_dev *wusb_dev 1006 struct wusb_dev *wusb_dev = container_of(_wusb_dev, struct wusb_dev, refcnt);
1178 = container_of(_wusb_dev, struct wusb_dev, refcnt); 1007
1179 list_del_init(&wusb_dev->cack_node); 1008 list_del_init(&wusb_dev->cack_node);
1180 wusb_dev_free(wusb_dev); 1009 wusb_dev_free(wusb_dev);
1181 d_fnend(1, NULL, "%s (wusb_dev %p) = void\n", __func__, wusb_dev);
1182} 1010}
1183EXPORT_SYMBOL_GPL(wusb_dev_destroy); 1011EXPORT_SYMBOL_GPL(wusb_dev_destroy);
1184 1012
@@ -1190,8 +1018,6 @@ EXPORT_SYMBOL_GPL(wusb_dev_destroy);
1190 */ 1018 */
1191int wusbhc_devconnect_create(struct wusbhc *wusbhc) 1019int wusbhc_devconnect_create(struct wusbhc *wusbhc)
1192{ 1020{
1193 d_fnstart(3, wusbhc->dev, "(wusbhc %p)\n", wusbhc);
1194
1195 wusbhc->keep_alive_ie.hdr.bIEIdentifier = WUIE_ID_KEEP_ALIVE; 1021 wusbhc->keep_alive_ie.hdr.bIEIdentifier = WUIE_ID_KEEP_ALIVE;
1196 wusbhc->keep_alive_ie.hdr.bLength = sizeof(wusbhc->keep_alive_ie.hdr); 1022 wusbhc->keep_alive_ie.hdr.bLength = sizeof(wusbhc->keep_alive_ie.hdr);
1197 INIT_DELAYED_WORK(&wusbhc->keep_alive_timer, wusbhc_keep_alive_run); 1023 INIT_DELAYED_WORK(&wusbhc->keep_alive_timer, wusbhc_keep_alive_run);
@@ -1200,7 +1026,6 @@ int wusbhc_devconnect_create(struct wusbhc *wusbhc)
1200 wusbhc->cack_ie.hdr.bLength = sizeof(wusbhc->cack_ie.hdr); 1026 wusbhc->cack_ie.hdr.bLength = sizeof(wusbhc->cack_ie.hdr);
1201 INIT_LIST_HEAD(&wusbhc->cack_list); 1027 INIT_LIST_HEAD(&wusbhc->cack_list);
1202 1028
1203 d_fnend(3, wusbhc->dev, "(wusbhc %p) = void\n", wusbhc);
1204 return 0; 1029 return 0;
1205} 1030}
1206 1031
@@ -1209,8 +1034,7 @@ int wusbhc_devconnect_create(struct wusbhc *wusbhc)
1209 */ 1034 */
1210void wusbhc_devconnect_destroy(struct wusbhc *wusbhc) 1035void wusbhc_devconnect_destroy(struct wusbhc *wusbhc)
1211{ 1036{
1212 d_fnstart(3, wusbhc->dev, "(wusbhc %p)\n", wusbhc); 1037 /* no op */
1213 d_fnend(3, wusbhc->dev, "(wusbhc %p) = void\n", wusbhc);
1214} 1038}
1215 1039
1216/* 1040/*
@@ -1222,8 +1046,7 @@ void wusbhc_devconnect_destroy(struct wusbhc *wusbhc)
1222 * FIXME: This also enables the keep alives but this is not necessary 1046 * FIXME: This also enables the keep alives but this is not necessary
1223 * until there are connected and authenticated devices. 1047 * until there are connected and authenticated devices.
1224 */ 1048 */
1225int wusbhc_devconnect_start(struct wusbhc *wusbhc, 1049int wusbhc_devconnect_start(struct wusbhc *wusbhc)
1226 const struct wusb_ckhdid *chid)
1227{ 1050{
1228 struct device *dev = wusbhc->dev; 1051 struct device *dev = wusbhc->dev;
1229 struct wuie_host_info *hi; 1052 struct wuie_host_info *hi;
@@ -1236,7 +1059,7 @@ int wusbhc_devconnect_start(struct wusbhc *wusbhc,
1236 hi->hdr.bLength = sizeof(*hi); 1059 hi->hdr.bLength = sizeof(*hi);
1237 hi->hdr.bIEIdentifier = WUIE_ID_HOST_INFO; 1060 hi->hdr.bIEIdentifier = WUIE_ID_HOST_INFO;
1238 hi->attributes = cpu_to_le16((wusbhc->rsv->stream << 3) | WUIE_HI_CAP_ALL); 1061 hi->attributes = cpu_to_le16((wusbhc->rsv->stream << 3) | WUIE_HI_CAP_ALL);
1239 hi->CHID = *chid; 1062 hi->CHID = wusbhc->chid;
1240 result = wusbhc_mmcie_set(wusbhc, 0, 0, &hi->hdr); 1063 result = wusbhc_mmcie_set(wusbhc, 0, 0, &hi->hdr);
1241 if (result < 0) { 1064 if (result < 0) {
1242 dev_err(dev, "Cannot add Host Info MMCIE: %d\n", result); 1065 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 cfa77a01cebd..3b52161e6e9c 100644
--- a/drivers/usb/wusbcore/mmc.c
+++ b/drivers/usb/wusbcore/mmc.c
@@ -159,15 +159,35 @@ found:
159} 159}
160EXPORT_SYMBOL_GPL(wusbhc_mmcie_rm); 160EXPORT_SYMBOL_GPL(wusbhc_mmcie_rm);
161 161
162static int wusbhc_mmc_start(struct wusbhc *wusbhc)
163{
164 int ret;
165
166 mutex_lock(&wusbhc->mutex);
167 ret = wusbhc->start(wusbhc);
168 if (ret >= 0)
169 wusbhc->active = 1;
170 mutex_unlock(&wusbhc->mutex);
171
172 return ret;
173}
174
175static void wusbhc_mmc_stop(struct wusbhc *wusbhc)
176{
177 mutex_lock(&wusbhc->mutex);
178 wusbhc->active = 0;
179 wusbhc->stop(wusbhc, WUSB_CHANNEL_STOP_DELAY_MS);
180 mutex_unlock(&wusbhc->mutex);
181}
182
162/* 183/*
163 * wusbhc_start - start transmitting MMCs and accepting connections 184 * wusbhc_start - start transmitting MMCs and accepting connections
164 * @wusbhc: the HC to start 185 * @wusbhc: the HC to start
165 * @chid: the CHID to use for this host
166 * 186 *
167 * Establishes a cluster reservation, enables device connections, and 187 * Establishes a cluster reservation, enables device connections, and
168 * starts MMCs with appropriate DNTS parameters. 188 * starts MMCs with appropriate DNTS parameters.
169 */ 189 */
170int wusbhc_start(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid) 190int wusbhc_start(struct wusbhc *wusbhc)
171{ 191{
172 int result; 192 int result;
173 struct device *dev = wusbhc->dev; 193 struct device *dev = wusbhc->dev;
@@ -181,7 +201,7 @@ int wusbhc_start(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid)
181 goto error_rsv_establish; 201 goto error_rsv_establish;
182 } 202 }
183 203
184 result = wusbhc_devconnect_start(wusbhc, chid); 204 result = wusbhc_devconnect_start(wusbhc);
185 if (result < 0) { 205 if (result < 0) {
186 dev_err(dev, "error enabling device connections: %d\n", result); 206 dev_err(dev, "error enabling device connections: %d\n", result);
187 goto error_devconnect_start; 207 goto error_devconnect_start;
@@ -199,12 +219,12 @@ int wusbhc_start(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid)
199 dev_err(dev, "Cannot set DNTS parameters: %d\n", result); 219 dev_err(dev, "Cannot set DNTS parameters: %d\n", result);
200 goto error_set_num_dnts; 220 goto error_set_num_dnts;
201 } 221 }
202 result = wusbhc->start(wusbhc); 222 result = wusbhc_mmc_start(wusbhc);
203 if (result < 0) { 223 if (result < 0) {
204 dev_err(dev, "error starting wusbch: %d\n", result); 224 dev_err(dev, "error starting wusbch: %d\n", result);
205 goto error_wusbhc_start; 225 goto error_wusbhc_start;
206 } 226 }
207 wusbhc->active = 1; 227
208 return 0; 228 return 0;
209 229
210error_wusbhc_start: 230error_wusbhc_start:
@@ -219,76 +239,17 @@ error_rsv_establish:
219} 239}
220 240
221/* 241/*
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 242 * wusbhc_stop - stop transmitting MMCs
251 * @wusbhc: the HC to stop 243 * @wusbhc: the HC to stop
252 * 244 *
253 * Send a Host Disconnect IE, wait, remove all the MMCs (stop sending MMCs). 245 * 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 */ 246 */
258void wusbhc_stop(struct wusbhc *wusbhc) 247void wusbhc_stop(struct wusbhc *wusbhc)
259{ 248{
260 if (wusbhc->active) { 249 wusbhc_mmc_stop(wusbhc);
261 wusbhc->active = 0; 250 wusbhc_sec_stop(wusbhc);
262 wusbhc->stop(wusbhc); 251 wusbhc_devconnect_stop(wusbhc);
263 wusbhc_sec_stop(wusbhc); 252 wusbhc_rsv_terminate(wusbhc);
264 __wusbhc_host_disconnect_ie(wusbhc);
265 wusbhc_devconnect_stop(wusbhc);
266 wusbhc_rsv_terminate(wusbhc);
267 }
268}
269EXPORT_SYMBOL_GPL(wusbhc_stop);
270
271/*
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} 253}
293 254
294/* 255/*
@@ -306,16 +267,19 @@ int wusbhc_chid_set(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid)
306 chid = NULL; 267 chid = NULL;
307 268
308 mutex_lock(&wusbhc->mutex); 269 mutex_lock(&wusbhc->mutex);
309 if (wusbhc->active) { 270 if (chid) {
310 if (chid) 271 if (wusbhc->active) {
311 result = __wusbhc_chid_change(wusbhc, chid); 272 mutex_unlock(&wusbhc->mutex);
312 else 273 return -EBUSY;
313 wusbhc_stop(wusbhc); 274 }
314 } else { 275 wusbhc->chid = *chid;
315 if (chid)
316 wusbhc_start(wusbhc, chid);
317 } 276 }
318 mutex_unlock(&wusbhc->mutex); 277 mutex_unlock(&wusbhc->mutex);
278
279 if (chid)
280 result = uwb_radio_start(&wusbhc->pal);
281 else
282 uwb_radio_stop(&wusbhc->pal);
319 return result; 283 return result;
320} 284}
321EXPORT_SYMBOL_GPL(wusbhc_chid_set); 285EXPORT_SYMBOL_GPL(wusbhc_chid_set);
diff --git a/drivers/usb/wusbcore/pal.c b/drivers/usb/wusbcore/pal.c
index 7cc51e9905cf..d0b172c5ecc7 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 fc63e77ded2d..4ed97360c046 100644
--- a/drivers/usb/wusbcore/reservation.c
+++ b/drivers/usb/wusbcore/reservation.c
@@ -48,18 +48,19 @@ static void wusbhc_rsv_complete_cb(struct uwb_rsv *rsv)
48{ 48{
49 struct wusbhc *wusbhc = rsv->pal_priv; 49 struct wusbhc *wusbhc = rsv->pal_priv;
50 struct device *dev = wusbhc->dev; 50 struct device *dev = wusbhc->dev;
51 struct uwb_mas_bm mas;
51 char buf[72]; 52 char buf[72];
52 53
53 switch (rsv->state) { 54 switch (rsv->state) {
54 case UWB_RSV_STATE_O_ESTABLISHED: 55 case UWB_RSV_STATE_O_ESTABLISHED:
55 bitmap_scnprintf(buf, sizeof(buf), rsv->mas.bm, UWB_NUM_MAS); 56 uwb_rsv_get_usable_mas(rsv, &mas);
57 bitmap_scnprintf(buf, sizeof(buf), mas.bm, UWB_NUM_MAS);
56 dev_dbg(dev, "established reservation: %s\n", buf); 58 dev_dbg(dev, "established reservation: %s\n", buf);
57 wusbhc_bwa_set(wusbhc, rsv->stream, &rsv->mas); 59 wusbhc_bwa_set(wusbhc, rsv->stream, &mas);
58 break; 60 break;
59 case UWB_RSV_STATE_NONE: 61 case UWB_RSV_STATE_NONE:
60 dev_dbg(dev, "removed reservation\n"); 62 dev_dbg(dev, "removed reservation\n");
61 wusbhc_bwa_set(wusbhc, 0, NULL); 63 wusbhc_bwa_set(wusbhc, 0, NULL);
62 wusbhc->rsv = NULL;
63 break; 64 break;
64 default: 65 default:
65 dev_dbg(dev, "unexpected reservation state: %d\n", rsv->state); 66 dev_dbg(dev, "unexpected reservation state: %d\n", rsv->state);
@@ -86,13 +87,12 @@ int wusbhc_rsv_establish(struct wusbhc *wusbhc)
86 bcid.data[0] = wusbhc->cluster_id; 87 bcid.data[0] = wusbhc->cluster_id;
87 bcid.data[1] = 0; 88 bcid.data[1] = 0;
88 89
89 rsv->owner = &rc->uwb_dev;
90 rsv->target.type = UWB_RSV_TARGET_DEVADDR; 90 rsv->target.type = UWB_RSV_TARGET_DEVADDR;
91 rsv->target.devaddr = bcid; 91 rsv->target.devaddr = bcid;
92 rsv->type = UWB_DRP_TYPE_PRIVATE; 92 rsv->type = UWB_DRP_TYPE_PRIVATE;
93 rsv->max_mas = 256; 93 rsv->max_mas = 256; /* try to get as much as possible */
94 rsv->min_mas = 16; /* one MAS per zone? */ 94 rsv->min_mas = 15; /* one MAS per zone */
95 rsv->sparsity = 16; /* at least one MAS in each zone? */ 95 rsv->max_interval = 1; /* max latency is one zone */
96 rsv->is_multicast = true; 96 rsv->is_multicast = true;
97 97
98 ret = uwb_rsv_establish(rsv); 98 ret = uwb_rsv_establish(rsv);
@@ -105,11 +105,14 @@ int wusbhc_rsv_establish(struct wusbhc *wusbhc)
105 105
106 106
107/** 107/**
108 * wusbhc_rsv_terminate - terminate any cluster reservation 108 * wusbhc_rsv_terminate - terminate the cluster reservation
109 * @wusbhc: the WUSB host whose reservation is to be terminated 109 * @wusbhc: the WUSB host whose reservation is to be terminated
110 */ 110 */
111void wusbhc_rsv_terminate(struct wusbhc *wusbhc) 111void wusbhc_rsv_terminate(struct wusbhc *wusbhc)
112{ 112{
113 if (wusbhc->rsv) 113 if (wusbhc->rsv) {
114 uwb_rsv_terminate(wusbhc->rsv); 114 uwb_rsv_terminate(wusbhc->rsv);
115 uwb_rsv_destroy(wusbhc->rsv);
116 wusbhc->rsv = NULL;
117 }
115} 118}
diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c
index 267a64325106..95c6fa3bf6b2 100644
--- a/drivers/usb/wusbcore/rh.c
+++ b/drivers/usb/wusbcore/rh.c
@@ -71,19 +71,20 @@
71 */ 71 */
72#include "wusbhc.h" 72#include "wusbhc.h"
73 73
74#define D_LOCAL 0
75#include <linux/uwb/debug.h>
76
77/* 74/*
78 * Reset a fake port 75 * Reset a fake port
79 * 76 *
80 * This can be called to reset a port from any other state or to reset 77 * 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 78 * to enter the UnConnected state and leave the cluster, this can mean
82 * a new connect that involves going over the authentication. When 79 * that when the device reconnects it is connected to a different fake
83 * just reseting, its a different story. 80 * port.
81 *
82 * Instead, reset authenticated devices with a SetAddress(0), followed
83 * by a SetAddresss(AuthAddr).
84 * 84 *
85 * The Linux USB stack resets a port twice before it considers it 85 * For unauthenticated devices just pretend to reset but do nothing.
86 * enabled, so we have to detect and ignore that. 86 * If the device initialization continues to fail it will eventually
87 * time out after TrustTimeout and enter the UnConnected state.
87 * 88 *
88 * @wusbhc is assumed referenced and @wusbhc->mutex unlocked. 89 * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
89 * 90 *
@@ -97,20 +98,20 @@ static int wusbhc_rh_port_reset(struct wusbhc *wusbhc, u8 port_idx)
97{ 98{
98 int result = 0; 99 int result = 0;
99 struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx); 100 struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx);
101 struct wusb_dev *wusb_dev = port->wusb_dev;
100 102
101 d_fnstart(3, wusbhc->dev, "(wusbhc %p port_idx %u)\n", 103 port->status |= USB_PORT_STAT_RESET;
102 wusbhc, port_idx); 104 port->change |= USB_PORT_STAT_C_RESET;
103 if (port->reset_count == 0) { 105
104 wusbhc_devconnect_auth(wusbhc, port_idx); 106 if (wusb_dev->addr & WUSB_DEV_ADDR_UNAUTH)
105 port->reset_count++; 107 result = 0;
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 108 else
111 result = wusbhc_dev_reset(wusbhc, port_idx); 109 result = wusb_dev_update_address(wusbhc, wusb_dev);
112 d_fnend(3, wusbhc->dev, "(wusbhc %p port_idx %u) = %d\n", 110
113 wusbhc, port_idx, result); 111 port->status &= ~USB_PORT_STAT_RESET;
112 port->status |= USB_PORT_STAT_ENABLE;
113 port->change |= USB_PORT_STAT_C_RESET | USB_PORT_STAT_C_ENABLE;
114
114 return result; 115 return result;
115} 116}
116 117
@@ -138,7 +139,6 @@ int wusbhc_rh_status_data(struct usb_hcd *usb_hcd, char *_buf)
138 size_t cnt, size; 139 size_t cnt, size;
139 unsigned long *buf = (unsigned long *) _buf; 140 unsigned long *buf = (unsigned long *) _buf;
140 141
141 d_fnstart(1, wusbhc->dev, "(wusbhc %p)\n", wusbhc);
142 /* WE DON'T LOCK, see comment */ 142 /* WE DON'T LOCK, see comment */
143 size = wusbhc->ports_max + 1 /* hub bit */; 143 size = wusbhc->ports_max + 1 /* hub bit */;
144 size = (size + 8 - 1) / 8; /* round to bytes */ 144 size = (size + 8 - 1) / 8; /* round to bytes */
@@ -147,8 +147,6 @@ int wusbhc_rh_status_data(struct usb_hcd *usb_hcd, char *_buf)
147 set_bit(cnt + 1, buf); 147 set_bit(cnt + 1, buf);
148 else 148 else
149 clear_bit(cnt + 1, buf); 149 clear_bit(cnt + 1, buf);
150 d_fnend(1, wusbhc->dev, "(wusbhc %p) %u, buffer:\n", wusbhc, (int)size);
151 d_dump(1, wusbhc->dev, _buf, size);
152 return size; 150 return size;
153} 151}
154EXPORT_SYMBOL_GPL(wusbhc_rh_status_data); 152EXPORT_SYMBOL_GPL(wusbhc_rh_status_data);
@@ -197,9 +195,7 @@ static int wusbhc_rh_get_hub_descr(struct wusbhc *wusbhc, u16 wValue,
197static int wusbhc_rh_clear_hub_feat(struct wusbhc *wusbhc, u16 feature) 195static int wusbhc_rh_clear_hub_feat(struct wusbhc *wusbhc, u16 feature)
198{ 196{
199 int result; 197 int result;
200 struct device *dev = wusbhc->dev;
201 198
202 d_fnstart(4, dev, "(%p, feature 0x%04u)\n", wusbhc, feature);
203 switch (feature) { 199 switch (feature) {
204 case C_HUB_LOCAL_POWER: 200 case C_HUB_LOCAL_POWER:
205 /* FIXME: maybe plug bit 0 to the power input status, 201 /* FIXME: maybe plug bit 0 to the power input status,
@@ -211,7 +207,6 @@ static int wusbhc_rh_clear_hub_feat(struct wusbhc *wusbhc, u16 feature)
211 default: 207 default:
212 result = -EPIPE; 208 result = -EPIPE;
213 } 209 }
214 d_fnend(4, dev, "(%p, feature 0x%04u), %d\n", wusbhc, feature, result);
215 return result; 210 return result;
216} 211}
217 212
@@ -238,14 +233,10 @@ static int wusbhc_rh_get_hub_status(struct wusbhc *wusbhc, u32 *buf,
238static int wusbhc_rh_set_port_feat(struct wusbhc *wusbhc, u16 feature, 233static int wusbhc_rh_set_port_feat(struct wusbhc *wusbhc, u16 feature,
239 u8 selector, u8 port_idx) 234 u8 selector, u8 port_idx)
240{ 235{
241 int result = -EINVAL;
242 struct device *dev = wusbhc->dev; 236 struct device *dev = wusbhc->dev;
243 237
244 d_fnstart(4, dev, "(feat 0x%04u, selector 0x%u, port_idx %d)\n",
245 feature, selector, port_idx);
246
247 if (port_idx > wusbhc->ports_max) 238 if (port_idx > wusbhc->ports_max)
248 goto error; 239 return -EINVAL;
249 240
250 switch (feature) { 241 switch (feature) {
251 /* According to USB2.0[11.24.2.13]p2, these features 242 /* According to USB2.0[11.24.2.13]p2, these features
@@ -255,35 +246,27 @@ static int wusbhc_rh_set_port_feat(struct wusbhc *wusbhc, u16 feature,
255 case USB_PORT_FEAT_C_SUSPEND: 246 case USB_PORT_FEAT_C_SUSPEND:
256 case USB_PORT_FEAT_C_CONNECTION: 247 case USB_PORT_FEAT_C_CONNECTION:
257 case USB_PORT_FEAT_C_RESET: 248 case USB_PORT_FEAT_C_RESET:
258 result = 0; 249 return 0;
259 break;
260
261 case USB_PORT_FEAT_POWER: 250 case USB_PORT_FEAT_POWER:
262 /* No such thing, but we fake it works */ 251 /* No such thing, but we fake it works */
263 mutex_lock(&wusbhc->mutex); 252 mutex_lock(&wusbhc->mutex);
264 wusb_port_by_idx(wusbhc, port_idx)->status |= USB_PORT_STAT_POWER; 253 wusb_port_by_idx(wusbhc, port_idx)->status |= USB_PORT_STAT_POWER;
265 mutex_unlock(&wusbhc->mutex); 254 mutex_unlock(&wusbhc->mutex);
266 result = 0; 255 return 0;
267 break;
268 case USB_PORT_FEAT_RESET: 256 case USB_PORT_FEAT_RESET:
269 result = wusbhc_rh_port_reset(wusbhc, port_idx); 257 return wusbhc_rh_port_reset(wusbhc, port_idx);
270 break;
271 case USB_PORT_FEAT_ENABLE: 258 case USB_PORT_FEAT_ENABLE:
272 case USB_PORT_FEAT_SUSPEND: 259 case USB_PORT_FEAT_SUSPEND:
273 dev_err(dev, "(port_idx %d) set feat %d/%d UNIMPLEMENTED\n", 260 dev_err(dev, "(port_idx %d) set feat %d/%d UNIMPLEMENTED\n",
274 port_idx, feature, selector); 261 port_idx, feature, selector);
275 result = -ENOSYS; 262 return -ENOSYS;
276 break;
277 default: 263 default:
278 dev_err(dev, "(port_idx %d) set feat %d/%d UNKNOWN\n", 264 dev_err(dev, "(port_idx %d) set feat %d/%d UNKNOWN\n",
279 port_idx, feature, selector); 265 port_idx, feature, selector);
280 result = -EPIPE; 266 return -EPIPE;
281 break;
282 } 267 }
283error: 268
284 d_fnend(4, dev, "(feat 0x%04u, selector 0x%u, port_idx %d) = %d\n", 269 return 0;
285 feature, selector, port_idx, result);
286 return result;
287} 270}
288 271
289/* 272/*
@@ -294,17 +277,13 @@ error:
294static int wusbhc_rh_clear_port_feat(struct wusbhc *wusbhc, u16 feature, 277static int wusbhc_rh_clear_port_feat(struct wusbhc *wusbhc, u16 feature,
295 u8 selector, u8 port_idx) 278 u8 selector, u8 port_idx)
296{ 279{
297 int result = -EINVAL; 280 int result = 0;
298 struct device *dev = wusbhc->dev; 281 struct device *dev = wusbhc->dev;
299 282
300 d_fnstart(4, dev, "(wusbhc %p feat 0x%04x selector %d port_idx %d)\n",
301 wusbhc, feature, selector, port_idx);
302
303 if (port_idx > wusbhc->ports_max) 283 if (port_idx > wusbhc->ports_max)
304 goto error; 284 return -EINVAL;
305 285
306 mutex_lock(&wusbhc->mutex); 286 mutex_lock(&wusbhc->mutex);
307 result = 0;
308 switch (feature) { 287 switch (feature) {
309 case USB_PORT_FEAT_POWER: /* fake port always on */ 288 case USB_PORT_FEAT_POWER: /* fake port always on */
310 /* According to USB2.0[11.24.2.7.1.4], no need to implement? */ 289 /* According to USB2.0[11.24.2.7.1.4], no need to implement? */
@@ -324,10 +303,8 @@ static int wusbhc_rh_clear_port_feat(struct wusbhc *wusbhc, u16 feature,
324 break; 303 break;
325 case USB_PORT_FEAT_SUSPEND: 304 case USB_PORT_FEAT_SUSPEND:
326 case USB_PORT_FEAT_C_SUSPEND: 305 case USB_PORT_FEAT_C_SUSPEND:
327 case 0xffff: /* ??? FIXME */
328 dev_err(dev, "(port_idx %d) Clear feat %d/%d UNIMPLEMENTED\n", 306 dev_err(dev, "(port_idx %d) Clear feat %d/%d UNIMPLEMENTED\n",
329 port_idx, feature, selector); 307 port_idx, feature, selector);
330 /* dump_stack(); */
331 result = -ENOSYS; 308 result = -ENOSYS;
332 break; 309 break;
333 default: 310 default:
@@ -337,9 +314,7 @@ static int wusbhc_rh_clear_port_feat(struct wusbhc *wusbhc, u16 feature,
337 break; 314 break;
338 } 315 }
339 mutex_unlock(&wusbhc->mutex); 316 mutex_unlock(&wusbhc->mutex);
340error: 317
341 d_fnend(4, dev, "(wusbhc %p feat 0x%04x selector %d port_idx %d) = "
342 "%d\n", wusbhc, feature, selector, port_idx, result);
343 return result; 318 return result;
344} 319}
345 320
@@ -351,22 +326,17 @@ error:
351static int wusbhc_rh_get_port_status(struct wusbhc *wusbhc, u16 port_idx, 326static int wusbhc_rh_get_port_status(struct wusbhc *wusbhc, u16 port_idx,
352 u32 *_buf, u16 wLength) 327 u32 *_buf, u16 wLength)
353{ 328{
354 int result = -EINVAL;
355 u16 *buf = (u16 *) _buf; 329 u16 *buf = (u16 *) _buf;
356 330
357 d_fnstart(1, wusbhc->dev, "(wusbhc %p port_idx %u wLength %u)\n",
358 wusbhc, port_idx, wLength);
359 if (port_idx > wusbhc->ports_max) 331 if (port_idx > wusbhc->ports_max)
360 goto error; 332 return -EINVAL;
333
361 mutex_lock(&wusbhc->mutex); 334 mutex_lock(&wusbhc->mutex);
362 buf[0] = cpu_to_le16(wusb_port_by_idx(wusbhc, port_idx)->status); 335 buf[0] = cpu_to_le16(wusb_port_by_idx(wusbhc, port_idx)->status);
363 buf[1] = cpu_to_le16(wusb_port_by_idx(wusbhc, port_idx)->change); 336 buf[1] = cpu_to_le16(wusb_port_by_idx(wusbhc, port_idx)->change);
364 result = 0;
365 mutex_unlock(&wusbhc->mutex); 337 mutex_unlock(&wusbhc->mutex);
366error: 338
367 d_fnend(1, wusbhc->dev, "(wusbhc %p) = %d, buffer:\n", wusbhc, result); 339 return 0;
368 d_dump(1, wusbhc->dev, _buf, wLength);
369 return result;
370} 340}
371 341
372/* 342/*
diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c
index a101cad6a8d4..f4aa28eca70d 100644
--- a/drivers/usb/wusbcore/security.c
+++ b/drivers/usb/wusbcore/security.c
@@ -27,19 +27,6 @@
27#include <linux/random.h> 27#include <linux/random.h>
28#include "wusbhc.h" 28#include "wusbhc.h"
29 29
30/*
31 * DEBUG & SECURITY WARNING!!!!
32 *
33 * If you enable this past 1, the debug code will weaken the
34 * cryptographic safety of the system (on purpose, for debugging).
35 *
36 * Weaken means:
37 * we print secret keys and intermediate values all the way,
38 */
39#undef D_LOCAL
40#define D_LOCAL 2
41#include <linux/uwb/debug.h>
42
43static void wusbhc_set_gtk_callback(struct urb *urb); 30static void wusbhc_set_gtk_callback(struct urb *urb);
44static void wusbhc_gtk_rekey_done_work(struct work_struct *work); 31static void wusbhc_gtk_rekey_done_work(struct work_struct *work);
45 32
@@ -219,7 +206,6 @@ int wusb_dev_sec_add(struct wusbhc *wusbhc,
219 const void *itr, *top; 206 const void *itr, *top;
220 char buf[64]; 207 char buf[64];
221 208
222 d_fnstart(3, dev, "(usb_dev %p, wusb_dev %p)\n", usb_dev, wusb_dev);
223 result = usb_get_descriptor(usb_dev, USB_DT_SECURITY, 209 result = usb_get_descriptor(usb_dev, USB_DT_SECURITY,
224 0, &secd, sizeof(secd)); 210 0, &secd, sizeof(secd));
225 if (result < sizeof(secd)) { 211 if (result < sizeof(secd)) {
@@ -228,8 +214,6 @@ int wusb_dev_sec_add(struct wusbhc *wusbhc,
228 goto error_secd; 214 goto error_secd;
229 } 215 }
230 secd_size = le16_to_cpu(secd.wTotalLength); 216 secd_size = le16_to_cpu(secd.wTotalLength);
231 d_printf(5, dev, "got %d bytes of sec descriptor, total is %d\n",
232 result, secd_size);
233 secd_buf = kmalloc(secd_size, GFP_KERNEL); 217 secd_buf = kmalloc(secd_size, GFP_KERNEL);
234 if (secd_buf == NULL) { 218 if (secd_buf == NULL) {
235 dev_err(dev, "Can't allocate space for security descriptors\n"); 219 dev_err(dev, "Can't allocate space for security descriptors\n");
@@ -242,7 +226,6 @@ int wusb_dev_sec_add(struct wusbhc *wusbhc,
242 "not enough data: %d\n", result); 226 "not enough data: %d\n", result);
243 goto error_secd_all; 227 goto error_secd_all;
244 } 228 }
245 d_printf(5, dev, "got %d bytes of sec descriptors\n", result);
246 bytes = 0; 229 bytes = 0;
247 itr = secd_buf + sizeof(secd); 230 itr = secd_buf + sizeof(secd);
248 top = secd_buf + result; 231 top = secd_buf + result;
@@ -279,14 +262,12 @@ int wusb_dev_sec_add(struct wusbhc *wusbhc,
279 goto error_no_ccm1; 262 goto error_no_ccm1;
280 } 263 }
281 wusb_dev->ccm1_etd = *ccm1_etd; 264 wusb_dev->ccm1_etd = *ccm1_etd;
282 dev_info(dev, "supported encryption: %s; using %s (0x%02x/%02x)\n", 265 dev_dbg(dev, "supported encryption: %s; using %s (0x%02x/%02x)\n",
283 buf, wusb_et_name(ccm1_etd->bEncryptionType), 266 buf, wusb_et_name(ccm1_etd->bEncryptionType),
284 ccm1_etd->bEncryptionValue, ccm1_etd->bAuthKeyIndex); 267 ccm1_etd->bEncryptionValue, ccm1_etd->bAuthKeyIndex);
285 result = 0; 268 result = 0;
286 kfree(secd_buf); 269 kfree(secd_buf);
287out: 270out:
288 d_fnend(3, dev, "(usb_dev %p, wusb_dev %p) = %d\n",
289 usb_dev, wusb_dev, result);
290 return result; 271 return result;
291 272
292 273
@@ -303,32 +284,6 @@ void wusb_dev_sec_rm(struct wusb_dev *wusb_dev)
303 /* Nothing so far */ 284 /* Nothing so far */
304} 285}
305 286
306static void hs_printk(unsigned level, struct device *dev,
307 struct usb_handshake *hs)
308{
309 d_printf(level, dev,
310 " bMessageNumber: %u\n"
311 " bStatus: %u\n"
312 " tTKID: %02x %02x %02x\n"
313 " CDID: %02x %02x %02x %02x %02x %02x %02x %02x\n"
314 " %02x %02x %02x %02x %02x %02x %02x %02x\n"
315 " nonce: %02x %02x %02x %02x %02x %02x %02x %02x\n"
316 " %02x %02x %02x %02x %02x %02x %02x %02x\n"
317 " MIC: %02x %02x %02x %02x %02x %02x %02x %02x\n",
318 hs->bMessageNumber, hs->bStatus,
319 hs->tTKID[2], hs->tTKID[1], hs->tTKID[0],
320 hs->CDID[0], hs->CDID[1], hs->CDID[2], hs->CDID[3],
321 hs->CDID[4], hs->CDID[5], hs->CDID[6], hs->CDID[7],
322 hs->CDID[8], hs->CDID[9], hs->CDID[10], hs->CDID[11],
323 hs->CDID[12], hs->CDID[13], hs->CDID[14], hs->CDID[15],
324 hs->nonce[0], hs->nonce[1], hs->nonce[2], hs->nonce[3],
325 hs->nonce[4], hs->nonce[5], hs->nonce[6], hs->nonce[7],
326 hs->nonce[8], hs->nonce[9], hs->nonce[10], hs->nonce[11],
327 hs->nonce[12], hs->nonce[13], hs->nonce[14], hs->nonce[15],
328 hs->MIC[0], hs->MIC[1], hs->MIC[2], hs->MIC[3],
329 hs->MIC[4], hs->MIC[5], hs->MIC[6], hs->MIC[7]);
330}
331
332/** 287/**
333 * Update the address of an unauthenticated WUSB device 288 * Update the address of an unauthenticated WUSB device
334 * 289 *
@@ -338,8 +293,7 @@ static void hs_printk(unsigned level, struct device *dev,
338 * Before the device's address (as known by it) was usb_dev->devnum | 293 * 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. 294 * 0x80 (unauthenticated address). With this we update it to usb_dev->devnum.
340 */ 295 */
341static int wusb_dev_update_address(struct wusbhc *wusbhc, 296int wusb_dev_update_address(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
342 struct wusb_dev *wusb_dev)
343{ 297{
344 int result = -ENOMEM; 298 int result = -ENOMEM;
345 struct usb_device *usb_dev = wusb_dev->usb_dev; 299 struct usb_device *usb_dev = wusb_dev->usb_dev;
@@ -422,9 +376,6 @@ int wusb_dev_4way_handshake(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev,
422 get_random_bytes(&hs[0].nonce, sizeof(hs[0].nonce)); 376 get_random_bytes(&hs[0].nonce, sizeof(hs[0].nonce));
423 memset(hs[0].MIC, 0, sizeof(hs[0].MIC)); /* Per WUSB1.0[T7-22] */ 377 memset(hs[0].MIC, 0, sizeof(hs[0].MIC)); /* Per WUSB1.0[T7-22] */
424 378
425 d_printf(1, dev, "I: sending hs1:\n");
426 hs_printk(2, dev, &hs[0]);
427
428 result = usb_control_msg( 379 result = usb_control_msg(
429 usb_dev, usb_sndctrlpipe(usb_dev, 0), 380 usb_dev, usb_sndctrlpipe(usb_dev, 0),
430 USB_REQ_SET_HANDSHAKE, 381 USB_REQ_SET_HANDSHAKE,
@@ -445,8 +396,6 @@ int wusb_dev_4way_handshake(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev,
445 dev_err(dev, "Handshake2: request failed: %d\n", result); 396 dev_err(dev, "Handshake2: request failed: %d\n", result);
446 goto error_hs2; 397 goto error_hs2;
447 } 398 }
448 d_printf(1, dev, "got HS2:\n");
449 hs_printk(2, dev, &hs[1]);
450 399
451 result = -EINVAL; 400 result = -EINVAL;
452 if (hs[1].bMessageNumber != 2) { 401 if (hs[1].bMessageNumber != 2) {
@@ -487,10 +436,6 @@ int wusb_dev_4way_handshake(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev,
487 result); 436 result);
488 goto error_hs2; 437 goto error_hs2;
489 } 438 }
490 d_printf(2, dev, "KCK:\n");
491 d_dump(2, dev, keydvt_out.kck, sizeof(keydvt_out.kck));
492 d_printf(2, dev, "PTK:\n");
493 d_dump(2, dev, keydvt_out.ptk, sizeof(keydvt_out.ptk));
494 439
495 /* Compute MIC and verify it */ 440 /* Compute MIC and verify it */
496 result = wusb_oob_mic(mic, keydvt_out.kck, &ccm_n, &hs[1]); 441 result = wusb_oob_mic(mic, keydvt_out.kck, &ccm_n, &hs[1]);
@@ -500,8 +445,6 @@ int wusb_dev_4way_handshake(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev,
500 goto error_hs2; 445 goto error_hs2;
501 } 446 }
502 447
503 d_printf(2, dev, "MIC:\n");
504 d_dump(2, dev, mic, sizeof(mic));
505 if (memcmp(hs[1].MIC, mic, sizeof(hs[1].MIC))) { 448 if (memcmp(hs[1].MIC, mic, sizeof(hs[1].MIC))) {
506 dev_err(dev, "Handshake2 failed: MIC mismatch\n"); 449 dev_err(dev, "Handshake2 failed: MIC mismatch\n");
507 goto error_hs2; 450 goto error_hs2;
@@ -521,9 +464,6 @@ int wusb_dev_4way_handshake(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev,
521 goto error_hs2; 464 goto error_hs2;
522 } 465 }
523 466
524 d_printf(1, dev, "I: sending hs3:\n");
525 hs_printk(2, dev, &hs[2]);
526
527 result = usb_control_msg( 467 result = usb_control_msg(
528 usb_dev, usb_sndctrlpipe(usb_dev, 0), 468 usb_dev, usb_sndctrlpipe(usb_dev, 0),
529 USB_REQ_SET_HANDSHAKE, 469 USB_REQ_SET_HANDSHAKE,
@@ -534,14 +474,11 @@ int wusb_dev_4way_handshake(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev,
534 goto error_hs3; 474 goto error_hs3;
535 } 475 }
536 476
537 d_printf(1, dev, "I: turning on encryption on host for device\n");
538 d_dump(2, dev, keydvt_out.ptk, sizeof(keydvt_out.ptk));
539 result = wusbhc->set_ptk(wusbhc, wusb_dev->port_idx, tkid, 477 result = wusbhc->set_ptk(wusbhc, wusb_dev->port_idx, tkid,
540 keydvt_out.ptk, sizeof(keydvt_out.ptk)); 478 keydvt_out.ptk, sizeof(keydvt_out.ptk));
541 if (result < 0) 479 if (result < 0)
542 goto error_wusbhc_set_ptk; 480 goto error_wusbhc_set_ptk;
543 481
544 d_printf(1, dev, "I: setting a GTK\n");
545 result = wusb_dev_set_gtk(wusbhc, wusb_dev); 482 result = wusb_dev_set_gtk(wusbhc, wusb_dev);
546 if (result < 0) { 483 if (result < 0) {
547 dev_err(dev, "Set GTK for device: request failed: %d\n", 484 dev_err(dev, "Set GTK for device: request failed: %d\n",
@@ -551,13 +488,12 @@ int wusb_dev_4way_handshake(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev,
551 488
552 /* Update the device's address from unauth to auth */ 489 /* Update the device's address from unauth to auth */
553 if (usb_dev->authenticated == 0) { 490 if (usb_dev->authenticated == 0) {
554 d_printf(1, dev, "I: updating addres to auth from non-auth\n");
555 result = wusb_dev_update_address(wusbhc, wusb_dev); 491 result = wusb_dev_update_address(wusbhc, wusb_dev);
556 if (result < 0) 492 if (result < 0)
557 goto error_dev_update_address; 493 goto error_dev_update_address;
558 } 494 }
559 result = 0; 495 result = 0;
560 d_printf(1, dev, "I: 4way handshke done, device authenticated\n"); 496 dev_info(dev, "device authenticated\n");
561 497
562error_dev_update_address: 498error_dev_update_address:
563error_wusbhc_set_gtk: 499error_wusbhc_set_gtk:
@@ -570,10 +506,8 @@ error_hs1:
570 memset(&keydvt_in, 0, sizeof(keydvt_in)); 506 memset(&keydvt_in, 0, sizeof(keydvt_in));
571 memset(&ccm_n, 0, sizeof(ccm_n)); 507 memset(&ccm_n, 0, sizeof(ccm_n));
572 memset(mic, 0, sizeof(mic)); 508 memset(mic, 0, sizeof(mic));
573 if (result < 0) { 509 if (result < 0)
574 /* error path */
575 wusb_dev_set_encryption(usb_dev, 0); 510 wusb_dev_set_encryption(usb_dev, 0);
576 }
577error_dev_set_encryption: 511error_dev_set_encryption:
578 kfree(hs); 512 kfree(hs);
579error_kzalloc: 513error_kzalloc:
diff --git a/drivers/usb/wusbcore/wa-nep.c b/drivers/usb/wusbcore/wa-nep.c
index 3f542990c73f..17d2626038be 100644
--- a/drivers/usb/wusbcore/wa-nep.c
+++ b/drivers/usb/wusbcore/wa-nep.c
@@ -51,7 +51,7 @@
51 */ 51 */
52#include <linux/workqueue.h> 52#include <linux/workqueue.h>
53#include <linux/ctype.h> 53#include <linux/ctype.h>
54#include <linux/uwb/debug.h> 54
55#include "wa-hc.h" 55#include "wa-hc.h"
56#include "wusbhc.h" 56#include "wusbhc.h"
57 57
@@ -139,13 +139,10 @@ static void wa_notif_dispatch(struct work_struct *ws)
139 /* FIXME: unimplemented WA NOTIFs */ 139 /* FIXME: unimplemented WA NOTIFs */
140 /* fallthru */ 140 /* fallthru */
141 default: 141 default:
142 if (printk_ratelimit()) { 142 dev_err(dev, "HWA: unknown notification 0x%x, "
143 dev_err(dev, "HWA: unknown notification 0x%x, " 143 "%zu bytes; discarding\n",
144 "%zu bytes; discarding\n", 144 notif_hdr->bNotifyType,
145 notif_hdr->bNotifyType, 145 (size_t)notif_hdr->bLength);
146 (size_t)notif_hdr->bLength);
147 dump_bytes(dev, notif_hdr, 16);
148 }
149 break; 146 break;
150 } 147 }
151 } 148 }
@@ -160,12 +157,9 @@ out:
160 * discard the data, as this should not happen. 157 * discard the data, as this should not happen.
161 */ 158 */
162exhausted_buffer: 159exhausted_buffer:
163 if (!printk_ratelimit())
164 goto out;
165 dev_warn(dev, "HWA: device sent short notification, " 160 dev_warn(dev, "HWA: device sent short notification, "
166 "%d bytes missing; discarding %d bytes.\n", 161 "%d bytes missing; discarding %d bytes.\n",
167 missing, (int)size); 162 missing, (int)size);
168 dump_bytes(dev, itr, size);
169 goto out; 163 goto out;
170} 164}
171 165
diff --git a/drivers/usb/wusbcore/wa-rpipe.c b/drivers/usb/wusbcore/wa-rpipe.c
index f18e4aae66e9..7369655f69cd 100644
--- a/drivers/usb/wusbcore/wa-rpipe.c
+++ b/drivers/usb/wusbcore/wa-rpipe.c
@@ -60,13 +60,10 @@
60#include <linux/init.h> 60#include <linux/init.h>
61#include <asm/atomic.h> 61#include <asm/atomic.h>
62#include <linux/bitmap.h> 62#include <linux/bitmap.h>
63
63#include "wusbhc.h" 64#include "wusbhc.h"
64#include "wa-hc.h" 65#include "wa-hc.h"
65 66
66#define D_LOCAL 0
67#include <linux/uwb/debug.h>
68
69
70static int __rpipe_get_descr(struct wahc *wa, 67static int __rpipe_get_descr(struct wahc *wa,
71 struct usb_rpipe_descriptor *descr, u16 index) 68 struct usb_rpipe_descriptor *descr, u16 index)
72{ 69{
@@ -76,7 +73,6 @@ static int __rpipe_get_descr(struct wahc *wa,
76 /* Get the RPIPE descriptor -- we cannot use the usb_get_descriptor() 73 /* Get the RPIPE descriptor -- we cannot use the usb_get_descriptor()
77 * function because the arguments are different. 74 * function because the arguments are different.
78 */ 75 */
79 d_printf(1, dev, "rpipe %u: get descr\n", index);
80 result = usb_control_msg( 76 result = usb_control_msg(
81 wa->usb_dev, usb_rcvctrlpipe(wa->usb_dev, 0), 77 wa->usb_dev, usb_rcvctrlpipe(wa->usb_dev, 0),
82 USB_REQ_GET_DESCRIPTOR, 78 USB_REQ_GET_DESCRIPTOR,
@@ -115,7 +111,6 @@ static int __rpipe_set_descr(struct wahc *wa,
115 /* we cannot use the usb_get_descriptor() function because the 111 /* we cannot use the usb_get_descriptor() function because the
116 * arguments are different. 112 * arguments are different.
117 */ 113 */
118 d_printf(1, dev, "rpipe %u: set descr\n", index);
119 result = usb_control_msg( 114 result = usb_control_msg(
120 wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0), 115 wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
121 USB_REQ_SET_DESCRIPTOR, 116 USB_REQ_SET_DESCRIPTOR,
@@ -174,13 +169,12 @@ void rpipe_destroy(struct kref *_rpipe)
174{ 169{
175 struct wa_rpipe *rpipe = container_of(_rpipe, struct wa_rpipe, refcnt); 170 struct wa_rpipe *rpipe = container_of(_rpipe, struct wa_rpipe, refcnt);
176 u8 index = le16_to_cpu(rpipe->descr.wRPipeIndex); 171 u8 index = le16_to_cpu(rpipe->descr.wRPipeIndex);
177 d_fnstart(1, NULL, "(rpipe %p %u)\n", rpipe, index); 172
178 if (rpipe->ep) 173 if (rpipe->ep)
179 rpipe->ep->hcpriv = NULL; 174 rpipe->ep->hcpriv = NULL;
180 rpipe_put_idx(rpipe->wa, index); 175 rpipe_put_idx(rpipe->wa, index);
181 wa_put(rpipe->wa); 176 wa_put(rpipe->wa);
182 kfree(rpipe); 177 kfree(rpipe);
183 d_fnend(1, NULL, "(rpipe %p %u)\n", rpipe, index);
184} 178}
185EXPORT_SYMBOL_GPL(rpipe_destroy); 179EXPORT_SYMBOL_GPL(rpipe_destroy);
186 180
@@ -202,7 +196,6 @@ static int rpipe_get_idle(struct wa_rpipe **prpipe, struct wahc *wa, u8 crs,
202 struct wa_rpipe *rpipe; 196 struct wa_rpipe *rpipe;
203 struct device *dev = &wa->usb_iface->dev; 197 struct device *dev = &wa->usb_iface->dev;
204 198
205 d_fnstart(3, dev, "(wa %p crs 0x%02x)\n", wa, crs);
206 rpipe = kzalloc(sizeof(*rpipe), gfp); 199 rpipe = kzalloc(sizeof(*rpipe), gfp);
207 if (rpipe == NULL) 200 if (rpipe == NULL)
208 return -ENOMEM; 201 return -ENOMEM;
@@ -223,14 +216,12 @@ static int rpipe_get_idle(struct wa_rpipe **prpipe, struct wahc *wa, u8 crs,
223 } 216 }
224 *prpipe = NULL; 217 *prpipe = NULL;
225 kfree(rpipe); 218 kfree(rpipe);
226 d_fnend(3, dev, "(wa %p crs 0x%02x) = -ENXIO\n", wa, crs);
227 return -ENXIO; 219 return -ENXIO;
228 220
229found: 221found:
230 set_bit(rpipe_idx, wa->rpipe_bm); 222 set_bit(rpipe_idx, wa->rpipe_bm);
231 rpipe->wa = wa_get(wa); 223 rpipe->wa = wa_get(wa);
232 *prpipe = rpipe; 224 *prpipe = rpipe;
233 d_fnstart(3, dev, "(wa %p crs 0x%02x) = 0\n", wa, crs);
234 return 0; 225 return 0;
235} 226}
236 227
@@ -239,7 +230,6 @@ static int __rpipe_reset(struct wahc *wa, unsigned index)
239 int result; 230 int result;
240 struct device *dev = &wa->usb_iface->dev; 231 struct device *dev = &wa->usb_iface->dev;
241 232
242 d_printf(1, dev, "rpipe %u: reset\n", index);
243 result = usb_control_msg( 233 result = usb_control_msg(
244 wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0), 234 wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
245 USB_REQ_RPIPE_RESET, 235 USB_REQ_RPIPE_RESET,
@@ -276,7 +266,6 @@ static struct usb_wireless_ep_comp_descriptor *rpipe_epc_find(
276 struct usb_descriptor_header *hdr; 266 struct usb_descriptor_header *hdr;
277 struct usb_wireless_ep_comp_descriptor *epcd; 267 struct usb_wireless_ep_comp_descriptor *epcd;
278 268
279 d_fnstart(3, dev, "(ep %p)\n", ep);
280 if (ep->desc.bEndpointAddress == 0) { 269 if (ep->desc.bEndpointAddress == 0) {
281 epcd = &epc0; 270 epcd = &epc0;
282 goto out; 271 goto out;
@@ -310,7 +299,6 @@ static struct usb_wireless_ep_comp_descriptor *rpipe_epc_find(
310 itr_size -= hdr->bDescriptorType; 299 itr_size -= hdr->bDescriptorType;
311 } 300 }
312out: 301out:
313 d_fnend(3, dev, "(ep %p) = %p\n", ep, epcd);
314 return epcd; 302 return epcd;
315} 303}
316 304
@@ -329,8 +317,6 @@ static int rpipe_aim(struct wa_rpipe *rpipe, struct wahc *wa,
329 struct usb_wireless_ep_comp_descriptor *epcd; 317 struct usb_wireless_ep_comp_descriptor *epcd;
330 u8 unauth; 318 u8 unauth;
331 319
332 d_fnstart(3, dev, "(rpipe %p wa %p ep %p, urb %p)\n",
333 rpipe, wa, ep, urb);
334 epcd = rpipe_epc_find(dev, ep); 320 epcd = rpipe_epc_find(dev, ep);
335 if (epcd == NULL) { 321 if (epcd == NULL) {
336 dev_err(dev, "ep 0x%02x: can't find companion descriptor\n", 322 dev_err(dev, "ep 0x%02x: can't find companion descriptor\n",
@@ -350,10 +336,12 @@ static int rpipe_aim(struct wa_rpipe *rpipe, struct wahc *wa,
350 /* FIXME: use maximum speed as supported or recommended by device */ 336 /* FIXME: use maximum speed as supported or recommended by device */
351 rpipe->descr.bSpeed = usb_pipeendpoint(urb->pipe) == 0 ? 337 rpipe->descr.bSpeed = usb_pipeendpoint(urb->pipe) == 0 ?
352 UWB_PHY_RATE_53 : UWB_PHY_RATE_200; 338 UWB_PHY_RATE_53 : UWB_PHY_RATE_200;
353 d_printf(2, dev, "addr %u (0x%02x) rpipe #%u ep# %u speed %d\n", 339
354 urb->dev->devnum, urb->dev->devnum | unauth, 340 dev_dbg(dev, "addr %u (0x%02x) rpipe #%u ep# %u speed %d\n",
355 le16_to_cpu(rpipe->descr.wRPipeIndex), 341 urb->dev->devnum, urb->dev->devnum | unauth,
356 usb_pipeendpoint(urb->pipe), rpipe->descr.bSpeed); 342 le16_to_cpu(rpipe->descr.wRPipeIndex),
343 usb_pipeendpoint(urb->pipe), rpipe->descr.bSpeed);
344
357 /* see security.c:wusb_update_address() */ 345 /* see security.c:wusb_update_address() */
358 if (unlikely(urb->dev->devnum == 0x80)) 346 if (unlikely(urb->dev->devnum == 0x80))
359 rpipe->descr.bDeviceAddress = 0; 347 rpipe->descr.bDeviceAddress = 0;
@@ -384,8 +372,6 @@ static int rpipe_aim(struct wa_rpipe *rpipe, struct wahc *wa,
384 } 372 }
385 result = 0; 373 result = 0;
386error: 374error:
387 d_fnend(3, dev, "(rpipe %p wa %p ep %p urb %p) = %d\n",
388 rpipe, wa, ep, urb, result);
389 return result; 375 return result;
390} 376}
391 377
@@ -405,8 +391,6 @@ static int rpipe_check_aim(const struct wa_rpipe *rpipe, const struct wahc *wa,
405 u8 unauth = (usb_dev->wusb && !usb_dev->authenticated) ? 0x80 : 0; 391 u8 unauth = (usb_dev->wusb && !usb_dev->authenticated) ? 0x80 : 0;
406 u8 portnum = wusb_port_no_to_idx(urb->dev->portnum); 392 u8 portnum = wusb_port_no_to_idx(urb->dev->portnum);
407 393
408 d_fnstart(3, dev, "(rpipe %p wa %p ep %p, urb %p)\n",
409 rpipe, wa, ep, urb);
410#define AIM_CHECK(rdf, val, text) \ 394#define AIM_CHECK(rdf, val, text) \
411 do { \ 395 do { \
412 if (rpipe->descr.rdf != (val)) { \ 396 if (rpipe->descr.rdf != (val)) { \
@@ -451,8 +435,6 @@ int rpipe_get_by_ep(struct wahc *wa, struct usb_host_endpoint *ep,
451 struct wa_rpipe *rpipe; 435 struct wa_rpipe *rpipe;
452 u8 eptype; 436 u8 eptype;
453 437
454 d_fnstart(3, dev, "(wa %p ep %p urb %p gfp 0x%08x)\n", wa, ep, urb,
455 gfp);
456 mutex_lock(&wa->rpipe_mutex); 438 mutex_lock(&wa->rpipe_mutex);
457 rpipe = ep->hcpriv; 439 rpipe = ep->hcpriv;
458 if (rpipe != NULL) { 440 if (rpipe != NULL) {
@@ -462,9 +444,9 @@ int rpipe_get_by_ep(struct wahc *wa, struct usb_host_endpoint *ep,
462 goto error; 444 goto error;
463 } 445 }
464 __rpipe_get(rpipe); 446 __rpipe_get(rpipe);
465 d_printf(2, dev, "ep 0x%02x: reusing rpipe %u\n", 447 dev_dbg(dev, "ep 0x%02x: reusing rpipe %u\n",
466 ep->desc.bEndpointAddress, 448 ep->desc.bEndpointAddress,
467 le16_to_cpu(rpipe->descr.wRPipeIndex)); 449 le16_to_cpu(rpipe->descr.wRPipeIndex));
468 } else { 450 } else {
469 /* hmm, assign idle rpipe, aim it */ 451 /* hmm, assign idle rpipe, aim it */
470 result = -ENOBUFS; 452 result = -ENOBUFS;
@@ -480,14 +462,12 @@ int rpipe_get_by_ep(struct wahc *wa, struct usb_host_endpoint *ep,
480 ep->hcpriv = rpipe; 462 ep->hcpriv = rpipe;
481 rpipe->ep = ep; 463 rpipe->ep = ep;
482 __rpipe_get(rpipe); /* for caching into ep->hcpriv */ 464 __rpipe_get(rpipe); /* for caching into ep->hcpriv */
483 d_printf(2, dev, "ep 0x%02x: using rpipe %u\n", 465 dev_dbg(dev, "ep 0x%02x: using rpipe %u\n",
484 ep->desc.bEndpointAddress, 466 ep->desc.bEndpointAddress,
485 le16_to_cpu(rpipe->descr.wRPipeIndex)); 467 le16_to_cpu(rpipe->descr.wRPipeIndex));
486 } 468 }
487 d_dump(4, dev, &rpipe->descr, sizeof(rpipe->descr));
488error: 469error:
489 mutex_unlock(&wa->rpipe_mutex); 470 mutex_unlock(&wa->rpipe_mutex);
490 d_fnend(3, dev, "(wa %p ep %p urb %p gfp 0x%08x)\n", wa, ep, urb, gfp);
491 return result; 471 return result;
492} 472}
493 473
@@ -507,7 +487,7 @@ int wa_rpipes_create(struct wahc *wa)
507void wa_rpipes_destroy(struct wahc *wa) 487void wa_rpipes_destroy(struct wahc *wa)
508{ 488{
509 struct device *dev = &wa->usb_iface->dev; 489 struct device *dev = &wa->usb_iface->dev;
510 d_fnstart(3, dev, "(wa %p)\n", wa); 490
511 if (!bitmap_empty(wa->rpipe_bm, wa->rpipes)) { 491 if (!bitmap_empty(wa->rpipe_bm, wa->rpipes)) {
512 char buf[256]; 492 char buf[256];
513 WARN_ON(1); 493 WARN_ON(1);
@@ -515,7 +495,6 @@ void wa_rpipes_destroy(struct wahc *wa)
515 dev_err(dev, "BUG: pipes not released on exit: %s\n", buf); 495 dev_err(dev, "BUG: pipes not released on exit: %s\n", buf);
516 } 496 }
517 kfree(wa->rpipe_bm); 497 kfree(wa->rpipe_bm);
518 d_fnend(3, dev, "(wa %p)\n", wa);
519} 498}
520 499
521/* 500/*
@@ -530,33 +509,20 @@ void wa_rpipes_destroy(struct wahc *wa)
530 */ 509 */
531void rpipe_ep_disable(struct wahc *wa, struct usb_host_endpoint *ep) 510void rpipe_ep_disable(struct wahc *wa, struct usb_host_endpoint *ep)
532{ 511{
533 struct device *dev = &wa->usb_iface->dev;
534 struct wa_rpipe *rpipe; 512 struct wa_rpipe *rpipe;
535 d_fnstart(2, dev, "(wa %p ep %p)\n", wa, ep); 513
536 mutex_lock(&wa->rpipe_mutex); 514 mutex_lock(&wa->rpipe_mutex);
537 rpipe = ep->hcpriv; 515 rpipe = ep->hcpriv;
538 if (rpipe != NULL) { 516 if (rpipe != NULL) {
539 unsigned rc = atomic_read(&rpipe->refcnt.refcount);
540 int result;
541 u16 index = le16_to_cpu(rpipe->descr.wRPipeIndex); 517 u16 index = le16_to_cpu(rpipe->descr.wRPipeIndex);
542 518
543 if (rc != 1) 519 usb_control_msg(
544 d_printf(1, dev, "(wa %p ep %p) rpipe %p refcnt %u\n",
545 wa, ep, rpipe, rc);
546
547 d_printf(1, dev, "rpipe %u: abort\n", index);
548 result = usb_control_msg(
549 wa->usb_dev, usb_rcvctrlpipe(wa->usb_dev, 0), 520 wa->usb_dev, usb_rcvctrlpipe(wa->usb_dev, 0),
550 USB_REQ_RPIPE_ABORT, 521 USB_REQ_RPIPE_ABORT,
551 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_RPIPE, 522 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_RPIPE,
552 0, index, NULL, 0, 1000 /* FIXME: arbitrary */); 523 0, index, NULL, 0, 1000 /* FIXME: arbitrary */);
553 if (result < 0 && result != -ENODEV /* dev is gone */)
554 d_printf(1, dev, "(wa %p rpipe %u): abort failed: %d\n",
555 wa, index, result);
556 rpipe_put(rpipe); 524 rpipe_put(rpipe);
557 } 525 }
558 mutex_unlock(&wa->rpipe_mutex); 526 mutex_unlock(&wa->rpipe_mutex);
559 d_fnend(2, dev, "(wa %p ep %p)\n", wa, ep);
560 return;
561} 527}
562EXPORT_SYMBOL_GPL(rpipe_ep_disable); 528EXPORT_SYMBOL_GPL(rpipe_ep_disable);
diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c
index c038635d1c64..238a96aee3a1 100644
--- a/drivers/usb/wusbcore/wa-xfer.c
+++ b/drivers/usb/wusbcore/wa-xfer.c
@@ -82,13 +82,10 @@
82#include <linux/init.h> 82#include <linux/init.h>
83#include <linux/spinlock.h> 83#include <linux/spinlock.h>
84#include <linux/hash.h> 84#include <linux/hash.h>
85
85#include "wa-hc.h" 86#include "wa-hc.h"
86#include "wusbhc.h" 87#include "wusbhc.h"
87 88
88#undef D_LOCAL
89#define D_LOCAL 0 /* 0 disabled, > 0 different levels... */
90#include <linux/uwb/debug.h>
91
92enum { 89enum {
93 WA_SEGS_MAX = 255, 90 WA_SEGS_MAX = 255,
94}; 91};
@@ -180,7 +177,6 @@ static void wa_xfer_destroy(struct kref *_xfer)
180 } 177 }
181 } 178 }
182 kfree(xfer); 179 kfree(xfer);
183 d_printf(2, NULL, "xfer %p destroyed\n", xfer);
184} 180}
185 181
186static void wa_xfer_get(struct wa_xfer *xfer) 182static void wa_xfer_get(struct wa_xfer *xfer)
@@ -190,10 +186,7 @@ static void wa_xfer_get(struct wa_xfer *xfer)
190 186
191static void wa_xfer_put(struct wa_xfer *xfer) 187static void wa_xfer_put(struct wa_xfer *xfer)
192{ 188{
193 d_fnstart(3, NULL, "(xfer %p) -- ref count bef put %d\n",
194 xfer, atomic_read(&xfer->refcnt.refcount));
195 kref_put(&xfer->refcnt, wa_xfer_destroy); 189 kref_put(&xfer->refcnt, wa_xfer_destroy);
196 d_fnend(3, NULL, "(xfer %p) = void\n", xfer);
197} 190}
198 191
199/* 192/*
@@ -209,7 +202,7 @@ static void wa_xfer_put(struct wa_xfer *xfer)
209static void wa_xfer_giveback(struct wa_xfer *xfer) 202static void wa_xfer_giveback(struct wa_xfer *xfer)
210{ 203{
211 unsigned long flags; 204 unsigned long flags;
212 d_fnstart(3, NULL, "(xfer %p)\n", xfer); 205
213 spin_lock_irqsave(&xfer->wa->xfer_list_lock, flags); 206 spin_lock_irqsave(&xfer->wa->xfer_list_lock, flags);
214 list_del_init(&xfer->list_node); 207 list_del_init(&xfer->list_node);
215 spin_unlock_irqrestore(&xfer->wa->xfer_list_lock, flags); 208 spin_unlock_irqrestore(&xfer->wa->xfer_list_lock, flags);
@@ -217,7 +210,6 @@ static void wa_xfer_giveback(struct wa_xfer *xfer)
217 wusbhc_giveback_urb(xfer->wa->wusb, xfer->urb, xfer->result); 210 wusbhc_giveback_urb(xfer->wa->wusb, xfer->urb, xfer->result);
218 wa_put(xfer->wa); 211 wa_put(xfer->wa);
219 wa_xfer_put(xfer); 212 wa_xfer_put(xfer);
220 d_fnend(3, NULL, "(xfer %p) = void\n", xfer);
221} 213}
222 214
223/* 215/*
@@ -227,13 +219,10 @@ static void wa_xfer_giveback(struct wa_xfer *xfer)
227 */ 219 */
228static void wa_xfer_completion(struct wa_xfer *xfer) 220static void wa_xfer_completion(struct wa_xfer *xfer)
229{ 221{
230 d_fnstart(3, NULL, "(xfer %p)\n", xfer);
231 if (xfer->wusb_dev) 222 if (xfer->wusb_dev)
232 wusb_dev_put(xfer->wusb_dev); 223 wusb_dev_put(xfer->wusb_dev);
233 rpipe_put(xfer->ep->hcpriv); 224 rpipe_put(xfer->ep->hcpriv);
234 wa_xfer_giveback(xfer); 225 wa_xfer_giveback(xfer);
235 d_fnend(3, NULL, "(xfer %p) = void\n", xfer);
236 return;
237} 226}
238 227
239/* 228/*
@@ -243,12 +232,12 @@ static void wa_xfer_completion(struct wa_xfer *xfer)
243 */ 232 */
244static unsigned __wa_xfer_is_done(struct wa_xfer *xfer) 233static unsigned __wa_xfer_is_done(struct wa_xfer *xfer)
245{ 234{
235 struct device *dev = &xfer->wa->usb_iface->dev;
246 unsigned result, cnt; 236 unsigned result, cnt;
247 struct wa_seg *seg; 237 struct wa_seg *seg;
248 struct urb *urb = xfer->urb; 238 struct urb *urb = xfer->urb;
249 unsigned found_short = 0; 239 unsigned found_short = 0;
250 240
251 d_fnstart(3, NULL, "(xfer %p)\n", xfer);
252 result = xfer->segs_done == xfer->segs_submitted; 241 result = xfer->segs_done == xfer->segs_submitted;
253 if (result == 0) 242 if (result == 0)
254 goto out; 243 goto out;
@@ -258,10 +247,8 @@ static unsigned __wa_xfer_is_done(struct wa_xfer *xfer)
258 switch (seg->status) { 247 switch (seg->status) {
259 case WA_SEG_DONE: 248 case WA_SEG_DONE:
260 if (found_short && seg->result > 0) { 249 if (found_short && seg->result > 0) {
261 if (printk_ratelimit()) 250 dev_dbg(dev, "xfer %p#%u: bad short segments (%zu)\n",
262 printk(KERN_ERR "xfer %p#%u: bad short " 251 xfer, cnt, seg->result);
263 "segments (%zu)\n", xfer, cnt,
264 seg->result);
265 urb->status = -EINVAL; 252 urb->status = -EINVAL;
266 goto out; 253 goto out;
267 } 254 }
@@ -269,36 +256,30 @@ static unsigned __wa_xfer_is_done(struct wa_xfer *xfer)
269 if (seg->result < xfer->seg_size 256 if (seg->result < xfer->seg_size
270 && cnt != xfer->segs-1) 257 && cnt != xfer->segs-1)
271 found_short = 1; 258 found_short = 1;
272 d_printf(2, NULL, "xfer %p#%u: DONE short %d " 259 dev_dbg(dev, "xfer %p#%u: DONE short %d "
273 "result %zu urb->actual_length %d\n", 260 "result %zu urb->actual_length %d\n",
274 xfer, seg->index, found_short, seg->result, 261 xfer, seg->index, found_short, seg->result,
275 urb->actual_length); 262 urb->actual_length);
276 break; 263 break;
277 case WA_SEG_ERROR: 264 case WA_SEG_ERROR:
278 xfer->result = seg->result; 265 xfer->result = seg->result;
279 d_printf(2, NULL, "xfer %p#%u: ERROR result %zu\n", 266 dev_dbg(dev, "xfer %p#%u: ERROR result %zu\n",
280 xfer, seg->index, seg->result); 267 xfer, seg->index, seg->result);
281 goto out; 268 goto out;
282 case WA_SEG_ABORTED: 269 case WA_SEG_ABORTED:
283 WARN_ON(urb->status != -ECONNRESET 270 dev_dbg(dev, "xfer %p#%u ABORTED: result %d\n",
284 && urb->status != -ENOENT); 271 xfer, seg->index, urb->status);
285 d_printf(2, NULL, "xfer %p#%u ABORTED: result %d\n",
286 xfer, seg->index, urb->status);
287 xfer->result = urb->status; 272 xfer->result = urb->status;
288 goto out; 273 goto out;
289 default: 274 default:
290 /* if (printk_ratelimit()) */ 275 dev_warn(dev, "xfer %p#%u: is_done bad state %d\n",
291 printk(KERN_ERR "xfer %p#%u: " 276 xfer, cnt, seg->status);
292 "is_done bad state %d\n",
293 xfer, cnt, seg->status);
294 xfer->result = -EINVAL; 277 xfer->result = -EINVAL;
295 WARN_ON(1);
296 goto out; 278 goto out;
297 } 279 }
298 } 280 }
299 xfer->result = 0; 281 xfer->result = 0;
300out: 282out:
301 d_fnend(3, NULL, "(xfer %p) = void\n", xfer);
302 return result; 283 return result;
303} 284}
304 285
@@ -424,8 +405,6 @@ static ssize_t __wa_xfer_setup_sizes(struct wa_xfer *xfer,
424 struct urb *urb = xfer->urb; 405 struct urb *urb = xfer->urb;
425 struct wa_rpipe *rpipe = xfer->ep->hcpriv; 406 struct wa_rpipe *rpipe = xfer->ep->hcpriv;
426 407
427 d_fnstart(3, dev, "(xfer %p [rpipe %p] urb %p)\n",
428 xfer, rpipe, urb);
429 switch (rpipe->descr.bmAttribute & 0x3) { 408 switch (rpipe->descr.bmAttribute & 0x3) {
430 case USB_ENDPOINT_XFER_CONTROL: 409 case USB_ENDPOINT_XFER_CONTROL:
431 *pxfer_type = WA_XFER_TYPE_CTL; 410 *pxfer_type = WA_XFER_TYPE_CTL;
@@ -472,12 +451,10 @@ static ssize_t __wa_xfer_setup_sizes(struct wa_xfer *xfer,
472 if (xfer->segs == 0 && *pxfer_type == WA_XFER_TYPE_CTL) 451 if (xfer->segs == 0 && *pxfer_type == WA_XFER_TYPE_CTL)
473 xfer->segs = 1; 452 xfer->segs = 1;
474error: 453error:
475 d_fnend(3, dev, "(xfer %p [rpipe %p] urb %p) = %d\n",
476 xfer, rpipe, urb, (int)result);
477 return result; 454 return result;
478} 455}
479 456
480/** Fill in the common request header and xfer-type specific data. */ 457/* Fill in the common request header and xfer-type specific data. */
481static void __wa_xfer_setup_hdr0(struct wa_xfer *xfer, 458static void __wa_xfer_setup_hdr0(struct wa_xfer *xfer,
482 struct wa_xfer_hdr *xfer_hdr0, 459 struct wa_xfer_hdr *xfer_hdr0,
483 enum wa_xfer_type xfer_type, 460 enum wa_xfer_type xfer_type,
@@ -534,14 +511,13 @@ static void wa_seg_dto_cb(struct urb *urb)
534 unsigned rpipe_ready = 0; 511 unsigned rpipe_ready = 0;
535 u8 done = 0; 512 u8 done = 0;
536 513
537 d_fnstart(3, NULL, "(urb %p [%d])\n", urb, urb->status);
538 switch (urb->status) { 514 switch (urb->status) {
539 case 0: 515 case 0:
540 spin_lock_irqsave(&xfer->lock, flags); 516 spin_lock_irqsave(&xfer->lock, flags);
541 wa = xfer->wa; 517 wa = xfer->wa;
542 dev = &wa->usb_iface->dev; 518 dev = &wa->usb_iface->dev;
543 d_printf(2, dev, "xfer %p#%u: data out done (%d bytes)\n", 519 dev_dbg(dev, "xfer %p#%u: data out done (%d bytes)\n",
544 xfer, seg->index, urb->actual_length); 520 xfer, seg->index, urb->actual_length);
545 if (seg->status < WA_SEG_PENDING) 521 if (seg->status < WA_SEG_PENDING)
546 seg->status = WA_SEG_PENDING; 522 seg->status = WA_SEG_PENDING;
547 seg->result = urb->actual_length; 523 seg->result = urb->actual_length;
@@ -555,9 +531,8 @@ static void wa_seg_dto_cb(struct urb *urb)
555 wa = xfer->wa; 531 wa = xfer->wa;
556 dev = &wa->usb_iface->dev; 532 dev = &wa->usb_iface->dev;
557 rpipe = xfer->ep->hcpriv; 533 rpipe = xfer->ep->hcpriv;
558 if (printk_ratelimit()) 534 dev_dbg(dev, "xfer %p#%u: data out error %d\n",
559 dev_err(dev, "xfer %p#%u: data out error %d\n", 535 xfer, seg->index, urb->status);
560 xfer, seg->index, urb->status);
561 if (edc_inc(&wa->nep_edc, EDC_MAX_ERRORS, 536 if (edc_inc(&wa->nep_edc, EDC_MAX_ERRORS,
562 EDC_ERROR_TIMEFRAME)){ 537 EDC_ERROR_TIMEFRAME)){
563 dev_err(dev, "DTO: URB max acceptable errors " 538 dev_err(dev, "DTO: URB max acceptable errors "
@@ -578,7 +553,6 @@ static void wa_seg_dto_cb(struct urb *urb)
578 if (rpipe_ready) 553 if (rpipe_ready)
579 wa_xfer_delayed_run(rpipe); 554 wa_xfer_delayed_run(rpipe);
580 } 555 }
581 d_fnend(3, NULL, "(urb %p [%d]) = void\n", urb, urb->status);
582} 556}
583 557
584/* 558/*
@@ -610,14 +584,12 @@ static void wa_seg_cb(struct urb *urb)
610 unsigned rpipe_ready; 584 unsigned rpipe_ready;
611 u8 done = 0; 585 u8 done = 0;
612 586
613 d_fnstart(3, NULL, "(urb %p [%d])\n", urb, urb->status);
614 switch (urb->status) { 587 switch (urb->status) {
615 case 0: 588 case 0:
616 spin_lock_irqsave(&xfer->lock, flags); 589 spin_lock_irqsave(&xfer->lock, flags);
617 wa = xfer->wa; 590 wa = xfer->wa;
618 dev = &wa->usb_iface->dev; 591 dev = &wa->usb_iface->dev;
619 d_printf(2, dev, "xfer %p#%u: request done\n", 592 dev_dbg(dev, "xfer %p#%u: request done\n", xfer, seg->index);
620 xfer, seg->index);
621 if (xfer->is_inbound && seg->status < WA_SEG_PENDING) 593 if (xfer->is_inbound && seg->status < WA_SEG_PENDING)
622 seg->status = WA_SEG_PENDING; 594 seg->status = WA_SEG_PENDING;
623 spin_unlock_irqrestore(&xfer->lock, flags); 595 spin_unlock_irqrestore(&xfer->lock, flags);
@@ -652,7 +624,6 @@ static void wa_seg_cb(struct urb *urb)
652 if (rpipe_ready) 624 if (rpipe_ready)
653 wa_xfer_delayed_run(rpipe); 625 wa_xfer_delayed_run(rpipe);
654 } 626 }
655 d_fnend(3, NULL, "(urb %p [%d]) = void\n", urb, urb->status);
656} 627}
657 628
658/* 629/*
@@ -750,9 +721,6 @@ static int __wa_xfer_setup(struct wa_xfer *xfer, struct urb *urb)
750 size_t xfer_hdr_size, cnt, transfer_size; 721 size_t xfer_hdr_size, cnt, transfer_size;
751 struct wa_xfer_hdr *xfer_hdr0, *xfer_hdr; 722 struct wa_xfer_hdr *xfer_hdr0, *xfer_hdr;
752 723
753 d_fnstart(3, dev, "(xfer %p [rpipe %p] urb %p)\n",
754 xfer, xfer->ep->hcpriv, urb);
755
756 result = __wa_xfer_setup_sizes(xfer, &xfer_type); 724 result = __wa_xfer_setup_sizes(xfer, &xfer_type);
757 if (result < 0) 725 if (result < 0)
758 goto error_setup_sizes; 726 goto error_setup_sizes;
@@ -788,8 +756,6 @@ static int __wa_xfer_setup(struct wa_xfer *xfer, struct urb *urb)
788 result = 0; 756 result = 0;
789error_setup_segs: 757error_setup_segs:
790error_setup_sizes: 758error_setup_sizes:
791 d_fnend(3, dev, "(xfer %p [rpipe %p] urb %p) = %d\n",
792 xfer, xfer->ep->hcpriv, urb, result);
793 return result; 759 return result;
794} 760}
795 761
@@ -843,9 +809,6 @@ static void wa_xfer_delayed_run(struct wa_rpipe *rpipe)
843 struct wa_xfer *xfer; 809 struct wa_xfer *xfer;
844 unsigned long flags; 810 unsigned long flags;
845 811
846 d_fnstart(1, dev, "(rpipe #%d) %d segments available\n",
847 le16_to_cpu(rpipe->descr.wRPipeIndex),
848 atomic_read(&rpipe->segs_available));
849 spin_lock_irqsave(&rpipe->seg_lock, flags); 812 spin_lock_irqsave(&rpipe->seg_lock, flags);
850 while (atomic_read(&rpipe->segs_available) > 0 813 while (atomic_read(&rpipe->segs_available) > 0
851 && !list_empty(&rpipe->seg_list)) { 814 && !list_empty(&rpipe->seg_list)) {
@@ -854,10 +817,8 @@ static void wa_xfer_delayed_run(struct wa_rpipe *rpipe)
854 list_del(&seg->list_node); 817 list_del(&seg->list_node);
855 xfer = seg->xfer; 818 xfer = seg->xfer;
856 result = __wa_seg_submit(rpipe, xfer, seg); 819 result = __wa_seg_submit(rpipe, xfer, seg);
857 d_printf(1, dev, "xfer %p#%u submitted from delayed " 820 dev_dbg(dev, "xfer %p#%u submitted from delayed [%d segments available] %d\n",
858 "[%d segments available] %d\n", 821 xfer, seg->index, atomic_read(&rpipe->segs_available), result);
859 xfer, seg->index,
860 atomic_read(&rpipe->segs_available), result);
861 if (unlikely(result < 0)) { 822 if (unlikely(result < 0)) {
862 spin_unlock_irqrestore(&rpipe->seg_lock, flags); 823 spin_unlock_irqrestore(&rpipe->seg_lock, flags);
863 spin_lock_irqsave(&xfer->lock, flags); 824 spin_lock_irqsave(&xfer->lock, flags);
@@ -868,10 +829,6 @@ static void wa_xfer_delayed_run(struct wa_rpipe *rpipe)
868 } 829 }
869 } 830 }
870 spin_unlock_irqrestore(&rpipe->seg_lock, flags); 831 spin_unlock_irqrestore(&rpipe->seg_lock, flags);
871 d_fnend(1, dev, "(rpipe #%d) = void, %d segments available\n",
872 le16_to_cpu(rpipe->descr.wRPipeIndex),
873 atomic_read(&rpipe->segs_available));
874
875} 832}
876 833
877/* 834/*
@@ -894,9 +851,6 @@ static int __wa_xfer_submit(struct wa_xfer *xfer)
894 u8 available; 851 u8 available;
895 u8 empty; 852 u8 empty;
896 853
897 d_fnstart(3, dev, "(xfer %p [rpipe %p])\n",
898 xfer, xfer->ep->hcpriv);
899
900 spin_lock_irqsave(&wa->xfer_list_lock, flags); 854 spin_lock_irqsave(&wa->xfer_list_lock, flags);
901 list_add_tail(&xfer->list_node, &wa->xfer_list); 855 list_add_tail(&xfer->list_node, &wa->xfer_list);
902 spin_unlock_irqrestore(&wa->xfer_list_lock, flags); 856 spin_unlock_irqrestore(&wa->xfer_list_lock, flags);
@@ -908,30 +862,24 @@ static int __wa_xfer_submit(struct wa_xfer *xfer)
908 available = atomic_read(&rpipe->segs_available); 862 available = atomic_read(&rpipe->segs_available);
909 empty = list_empty(&rpipe->seg_list); 863 empty = list_empty(&rpipe->seg_list);
910 seg = xfer->seg[cnt]; 864 seg = xfer->seg[cnt];
911 d_printf(2, dev, "xfer %p#%u: available %u empty %u (%s)\n", 865 dev_dbg(dev, "xfer %p#%u: available %u empty %u (%s)\n",
912 xfer, cnt, available, empty, 866 xfer, cnt, available, empty,
913 available == 0 || !empty ? "delayed" : "submitted"); 867 available == 0 || !empty ? "delayed" : "submitted");
914 if (available == 0 || !empty) { 868 if (available == 0 || !empty) {
915 d_printf(1, dev, "xfer %p#%u: delayed\n", xfer, cnt); 869 dev_dbg(dev, "xfer %p#%u: delayed\n", xfer, cnt);
916 seg->status = WA_SEG_DELAYED; 870 seg->status = WA_SEG_DELAYED;
917 list_add_tail(&seg->list_node, &rpipe->seg_list); 871 list_add_tail(&seg->list_node, &rpipe->seg_list);
918 } else { 872 } else {
919 result = __wa_seg_submit(rpipe, xfer, seg); 873 result = __wa_seg_submit(rpipe, xfer, seg);
920 if (result < 0) 874 if (result < 0) {
875 __wa_xfer_abort(xfer);
921 goto error_seg_submit; 876 goto error_seg_submit;
877 }
922 } 878 }
923 xfer->segs_submitted++; 879 xfer->segs_submitted++;
924 } 880 }
925 spin_unlock_irqrestore(&rpipe->seg_lock, flags);
926 d_fnend(3, dev, "(xfer %p [rpipe %p]) = void\n", xfer,
927 xfer->ep->hcpriv);
928 return result;
929
930error_seg_submit: 881error_seg_submit:
931 __wa_xfer_abort(xfer);
932 spin_unlock_irqrestore(&rpipe->seg_lock, flags); 882 spin_unlock_irqrestore(&rpipe->seg_lock, flags);
933 d_fnend(3, dev, "(xfer %p [rpipe %p]) = void\n", xfer,
934 xfer->ep->hcpriv);
935 return result; 883 return result;
936} 884}
937 885
@@ -964,11 +912,9 @@ static void wa_urb_enqueue_b(struct wa_xfer *xfer)
964 struct urb *urb = xfer->urb; 912 struct urb *urb = xfer->urb;
965 struct wahc *wa = xfer->wa; 913 struct wahc *wa = xfer->wa;
966 struct wusbhc *wusbhc = wa->wusb; 914 struct wusbhc *wusbhc = wa->wusb;
967 struct device *dev = &wa->usb_iface->dev;
968 struct wusb_dev *wusb_dev; 915 struct wusb_dev *wusb_dev;
969 unsigned done; 916 unsigned done;
970 917
971 d_fnstart(3, dev, "(wa %p urb %p)\n", wa, urb);
972 result = rpipe_get_by_ep(wa, xfer->ep, urb, xfer->gfp); 918 result = rpipe_get_by_ep(wa, xfer->ep, urb, xfer->gfp);
973 if (result < 0) 919 if (result < 0)
974 goto error_rpipe_get; 920 goto error_rpipe_get;
@@ -997,7 +943,6 @@ static void wa_urb_enqueue_b(struct wa_xfer *xfer)
997 if (result < 0) 943 if (result < 0)
998 goto error_xfer_submit; 944 goto error_xfer_submit;
999 spin_unlock_irqrestore(&xfer->lock, flags); 945 spin_unlock_irqrestore(&xfer->lock, flags);
1000 d_fnend(3, dev, "(wa %p urb %p) = void\n", wa, urb);
1001 return; 946 return;
1002 947
1003 /* this is basically wa_xfer_completion() broken up wa_xfer_giveback() 948 /* this is basically wa_xfer_completion() broken up wa_xfer_giveback()
@@ -1015,7 +960,6 @@ error_dev_gone:
1015error_rpipe_get: 960error_rpipe_get:
1016 xfer->result = result; 961 xfer->result = result;
1017 wa_xfer_giveback(xfer); 962 wa_xfer_giveback(xfer);
1018 d_fnend(3, dev, "(wa %p urb %p) = (void) %d\n", wa, urb, result);
1019 return; 963 return;
1020 964
1021error_xfer_submit: 965error_xfer_submit:
@@ -1024,8 +968,6 @@ error_xfer_submit:
1024 spin_unlock_irqrestore(&xfer->lock, flags); 968 spin_unlock_irqrestore(&xfer->lock, flags);
1025 if (done) 969 if (done)
1026 wa_xfer_completion(xfer); 970 wa_xfer_completion(xfer);
1027 d_fnend(3, dev, "(wa %p urb %p) = (void) %d\n", wa, urb, result);
1028 return;
1029} 971}
1030 972
1031/* 973/*
@@ -1041,11 +983,9 @@ error_xfer_submit:
1041void wa_urb_enqueue_run(struct work_struct *ws) 983void wa_urb_enqueue_run(struct work_struct *ws)
1042{ 984{
1043 struct wahc *wa = container_of(ws, struct wahc, xfer_work); 985 struct wahc *wa = container_of(ws, struct wahc, xfer_work);
1044 struct device *dev = &wa->usb_iface->dev;
1045 struct wa_xfer *xfer, *next; 986 struct wa_xfer *xfer, *next;
1046 struct urb *urb; 987 struct urb *urb;
1047 988
1048 d_fnstart(3, dev, "(wa %p)\n", wa);
1049 spin_lock_irq(&wa->xfer_list_lock); 989 spin_lock_irq(&wa->xfer_list_lock);
1050 list_for_each_entry_safe(xfer, next, &wa->xfer_delayed_list, 990 list_for_each_entry_safe(xfer, next, &wa->xfer_delayed_list,
1051 list_node) { 991 list_node) {
@@ -1059,7 +999,6 @@ void wa_urb_enqueue_run(struct work_struct *ws)
1059 spin_lock_irq(&wa->xfer_list_lock); 999 spin_lock_irq(&wa->xfer_list_lock);
1060 } 1000 }
1061 spin_unlock_irq(&wa->xfer_list_lock); 1001 spin_unlock_irq(&wa->xfer_list_lock);
1062 d_fnend(3, dev, "(wa %p) = void\n", wa);
1063} 1002}
1064EXPORT_SYMBOL_GPL(wa_urb_enqueue_run); 1003EXPORT_SYMBOL_GPL(wa_urb_enqueue_run);
1065 1004
@@ -1084,9 +1023,6 @@ int wa_urb_enqueue(struct wahc *wa, struct usb_host_endpoint *ep,
1084 unsigned long my_flags; 1023 unsigned long my_flags;
1085 unsigned cant_sleep = irqs_disabled() | in_atomic(); 1024 unsigned cant_sleep = irqs_disabled() | in_atomic();
1086 1025
1087 d_fnstart(3, dev, "(wa %p ep %p urb %p [%d] gfp 0x%x)\n",
1088 wa, ep, urb, urb->transfer_buffer_length, gfp);
1089
1090 if (urb->transfer_buffer == NULL 1026 if (urb->transfer_buffer == NULL
1091 && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) 1027 && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
1092 && urb->transfer_buffer_length != 0) { 1028 && urb->transfer_buffer_length != 0) {
@@ -1108,11 +1044,13 @@ int wa_urb_enqueue(struct wahc *wa, struct usb_host_endpoint *ep,
1108 xfer->gfp = gfp; 1044 xfer->gfp = gfp;
1109 xfer->ep = ep; 1045 xfer->ep = ep;
1110 urb->hcpriv = xfer; 1046 urb->hcpriv = xfer;
1111 d_printf(2, dev, "xfer %p urb %p pipe 0x%02x [%d bytes] %s %s %s\n", 1047
1112 xfer, urb, urb->pipe, urb->transfer_buffer_length, 1048 dev_dbg(dev, "xfer %p urb %p pipe 0x%02x [%d bytes] %s %s %s\n",
1113 urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP ? "dma" : "nodma", 1049 xfer, urb, urb->pipe, urb->transfer_buffer_length,
1114 urb->pipe & USB_DIR_IN ? "inbound" : "outbound", 1050 urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP ? "dma" : "nodma",
1115 cant_sleep ? "deferred" : "inline"); 1051 urb->pipe & USB_DIR_IN ? "inbound" : "outbound",
1052 cant_sleep ? "deferred" : "inline");
1053
1116 if (cant_sleep) { 1054 if (cant_sleep) {
1117 usb_get_urb(urb); 1055 usb_get_urb(urb);
1118 spin_lock_irqsave(&wa->xfer_list_lock, my_flags); 1056 spin_lock_irqsave(&wa->xfer_list_lock, my_flags);
@@ -1122,15 +1060,11 @@ int wa_urb_enqueue(struct wahc *wa, struct usb_host_endpoint *ep,
1122 } else { 1060 } else {
1123 wa_urb_enqueue_b(xfer); 1061 wa_urb_enqueue_b(xfer);
1124 } 1062 }
1125 d_fnend(3, dev, "(wa %p ep %p urb %p [%d] gfp 0x%x) = 0\n",
1126 wa, ep, urb, urb->transfer_buffer_length, gfp);
1127 return 0; 1063 return 0;
1128 1064
1129error_dequeued: 1065error_dequeued:
1130 kfree(xfer); 1066 kfree(xfer);
1131error_kmalloc: 1067error_kmalloc:
1132 d_fnend(3, dev, "(wa %p ep %p urb %p [%d] gfp 0x%x) = %d\n",
1133 wa, ep, urb, urb->transfer_buffer_length, gfp, result);
1134 return result; 1068 return result;
1135} 1069}
1136EXPORT_SYMBOL_GPL(wa_urb_enqueue); 1070EXPORT_SYMBOL_GPL(wa_urb_enqueue);
@@ -1155,7 +1089,6 @@ EXPORT_SYMBOL_GPL(wa_urb_enqueue);
1155 */ 1089 */
1156int wa_urb_dequeue(struct wahc *wa, struct urb *urb) 1090int wa_urb_dequeue(struct wahc *wa, struct urb *urb)
1157{ 1091{
1158 struct device *dev = &wa->usb_iface->dev;
1159 unsigned long flags, flags2; 1092 unsigned long flags, flags2;
1160 struct wa_xfer *xfer; 1093 struct wa_xfer *xfer;
1161 struct wa_seg *seg; 1094 struct wa_seg *seg;
@@ -1163,9 +1096,6 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb)
1163 unsigned cnt; 1096 unsigned cnt;
1164 unsigned rpipe_ready = 0; 1097 unsigned rpipe_ready = 0;
1165 1098
1166 d_fnstart(3, dev, "(wa %p, urb %p)\n", wa, urb);
1167
1168 d_printf(1, dev, "xfer %p urb %p: aborting\n", urb->hcpriv, urb);
1169 xfer = urb->hcpriv; 1099 xfer = urb->hcpriv;
1170 if (xfer == NULL) { 1100 if (xfer == NULL) {
1171 /* NOthing setup yet enqueue will see urb->status != 1101 /* NOthing setup yet enqueue will see urb->status !=
@@ -1234,13 +1164,11 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb)
1234 wa_xfer_completion(xfer); 1164 wa_xfer_completion(xfer);
1235 if (rpipe_ready) 1165 if (rpipe_ready)
1236 wa_xfer_delayed_run(rpipe); 1166 wa_xfer_delayed_run(rpipe);
1237 d_fnend(3, dev, "(wa %p, urb %p) = 0\n", wa, urb);
1238 return 0; 1167 return 0;
1239 1168
1240out_unlock: 1169out_unlock:
1241 spin_unlock_irqrestore(&xfer->lock, flags); 1170 spin_unlock_irqrestore(&xfer->lock, flags);
1242out: 1171out:
1243 d_fnend(3, dev, "(wa %p, urb %p) = 0\n", wa, urb);
1244 return 0; 1172 return 0;
1245 1173
1246dequeue_delayed: 1174dequeue_delayed:
@@ -1250,7 +1178,6 @@ dequeue_delayed:
1250 spin_unlock_irqrestore(&xfer->lock, flags); 1178 spin_unlock_irqrestore(&xfer->lock, flags);
1251 wa_xfer_giveback(xfer); 1179 wa_xfer_giveback(xfer);
1252 usb_put_urb(urb); /* we got a ref in enqueue() */ 1180 usb_put_urb(urb); /* we got a ref in enqueue() */
1253 d_fnend(3, dev, "(wa %p, urb %p) = 0\n", wa, urb);
1254 return 0; 1181 return 0;
1255} 1182}
1256EXPORT_SYMBOL_GPL(wa_urb_dequeue); 1183EXPORT_SYMBOL_GPL(wa_urb_dequeue);
@@ -1326,7 +1253,6 @@ static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer)
1326 u8 usb_status; 1253 u8 usb_status;
1327 unsigned rpipe_ready = 0; 1254 unsigned rpipe_ready = 0;
1328 1255
1329 d_fnstart(3, dev, "(wa %p xfer %p)\n", wa, xfer);
1330 spin_lock_irqsave(&xfer->lock, flags); 1256 spin_lock_irqsave(&xfer->lock, flags);
1331 seg_idx = xfer_result->bTransferSegment & 0x7f; 1257 seg_idx = xfer_result->bTransferSegment & 0x7f;
1332 if (unlikely(seg_idx >= xfer->segs)) 1258 if (unlikely(seg_idx >= xfer->segs))
@@ -1334,8 +1260,8 @@ static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer)
1334 seg = xfer->seg[seg_idx]; 1260 seg = xfer->seg[seg_idx];
1335 rpipe = xfer->ep->hcpriv; 1261 rpipe = xfer->ep->hcpriv;
1336 usb_status = xfer_result->bTransferStatus; 1262 usb_status = xfer_result->bTransferStatus;
1337 d_printf(2, dev, "xfer %p#%u: bTransferStatus 0x%02x (seg %u)\n", 1263 dev_dbg(dev, "xfer %p#%u: bTransferStatus 0x%02x (seg %u)\n",
1338 xfer, seg_idx, usb_status, seg->status); 1264 xfer, seg_idx, usb_status, seg->status);
1339 if (seg->status == WA_SEG_ABORTED 1265 if (seg->status == WA_SEG_ABORTED
1340 || seg->status == WA_SEG_ERROR) /* already handled */ 1266 || seg->status == WA_SEG_ERROR) /* already handled */
1341 goto segment_aborted; 1267 goto segment_aborted;
@@ -1391,10 +1317,8 @@ static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer)
1391 wa_xfer_completion(xfer); 1317 wa_xfer_completion(xfer);
1392 if (rpipe_ready) 1318 if (rpipe_ready)
1393 wa_xfer_delayed_run(rpipe); 1319 wa_xfer_delayed_run(rpipe);
1394 d_fnend(3, dev, "(wa %p xfer %p) = void\n", wa, xfer);
1395 return; 1320 return;
1396 1321
1397
1398error_submit_buf_in: 1322error_submit_buf_in:
1399 if (edc_inc(&wa->dti_edc, EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) { 1323 if (edc_inc(&wa->dti_edc, EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) {
1400 dev_err(dev, "DTI: URB max acceptable errors " 1324 dev_err(dev, "DTI: URB max acceptable errors "
@@ -1416,11 +1340,8 @@ error_complete:
1416 wa_xfer_completion(xfer); 1340 wa_xfer_completion(xfer);
1417 if (rpipe_ready) 1341 if (rpipe_ready)
1418 wa_xfer_delayed_run(rpipe); 1342 wa_xfer_delayed_run(rpipe);
1419 d_fnend(3, dev, "(wa %p xfer %p) = void [segment/DTI-submit error]\n",
1420 wa, xfer);
1421 return; 1343 return;
1422 1344
1423
1424error_bad_seg: 1345error_bad_seg:
1425 spin_unlock_irqrestore(&xfer->lock, flags); 1346 spin_unlock_irqrestore(&xfer->lock, flags);
1426 wa_urb_dequeue(wa, xfer->urb); 1347 wa_urb_dequeue(wa, xfer->urb);
@@ -1431,17 +1352,11 @@ error_bad_seg:
1431 "exceeded, resetting device\n"); 1352 "exceeded, resetting device\n");
1432 wa_reset_all(wa); 1353 wa_reset_all(wa);
1433 } 1354 }
1434 d_fnend(3, dev, "(wa %p xfer %p) = void [bad seg]\n", wa, xfer);
1435 return; 1355 return;
1436 1356
1437
1438segment_aborted: 1357segment_aborted:
1439 /* nothing to do, as the aborter did the completion */ 1358 /* nothing to do, as the aborter did the completion */
1440 spin_unlock_irqrestore(&xfer->lock, flags); 1359 spin_unlock_irqrestore(&xfer->lock, flags);
1441 d_fnend(3, dev, "(wa %p xfer %p) = void [segment aborted]\n",
1442 wa, xfer);
1443 return;
1444
1445} 1360}
1446 1361
1447/* 1362/*
@@ -1465,15 +1380,14 @@ static void wa_buf_in_cb(struct urb *urb)
1465 unsigned long flags; 1380 unsigned long flags;
1466 u8 done = 0; 1381 u8 done = 0;
1467 1382
1468 d_fnstart(3, NULL, "(urb %p [%d])\n", urb, urb->status);
1469 switch (urb->status) { 1383 switch (urb->status) {
1470 case 0: 1384 case 0:
1471 spin_lock_irqsave(&xfer->lock, flags); 1385 spin_lock_irqsave(&xfer->lock, flags);
1472 wa = xfer->wa; 1386 wa = xfer->wa;
1473 dev = &wa->usb_iface->dev; 1387 dev = &wa->usb_iface->dev;
1474 rpipe = xfer->ep->hcpriv; 1388 rpipe = xfer->ep->hcpriv;
1475 d_printf(2, dev, "xfer %p#%u: data in done (%zu bytes)\n", 1389 dev_dbg(dev, "xfer %p#%u: data in done (%zu bytes)\n",
1476 xfer, seg->index, (size_t)urb->actual_length); 1390 xfer, seg->index, (size_t)urb->actual_length);
1477 seg->status = WA_SEG_DONE; 1391 seg->status = WA_SEG_DONE;
1478 seg->result = urb->actual_length; 1392 seg->result = urb->actual_length;
1479 xfer->segs_done++; 1393 xfer->segs_done++;
@@ -1514,7 +1428,6 @@ static void wa_buf_in_cb(struct urb *urb)
1514 if (rpipe_ready) 1428 if (rpipe_ready)
1515 wa_xfer_delayed_run(rpipe); 1429 wa_xfer_delayed_run(rpipe);
1516 } 1430 }
1517 d_fnend(3, NULL, "(urb %p [%d]) = void\n", urb, urb->status);
1518} 1431}
1519 1432
1520/* 1433/*
@@ -1553,14 +1466,12 @@ static void wa_xfer_result_cb(struct urb *urb)
1553 struct wa_xfer *xfer; 1466 struct wa_xfer *xfer;
1554 u8 usb_status; 1467 u8 usb_status;
1555 1468
1556 d_fnstart(3, dev, "(%p)\n", wa);
1557 BUG_ON(wa->dti_urb != urb); 1469 BUG_ON(wa->dti_urb != urb);
1558 switch (wa->dti_urb->status) { 1470 switch (wa->dti_urb->status) {
1559 case 0: 1471 case 0:
1560 /* We have a xfer result buffer; check it */ 1472 /* We have a xfer result buffer; check it */
1561 d_printf(2, dev, "DTI: xfer result %d bytes at %p\n", 1473 dev_dbg(dev, "DTI: xfer result %d bytes at %p\n",
1562 urb->actual_length, urb->transfer_buffer); 1474 urb->actual_length, urb->transfer_buffer);
1563 d_dump(3, dev, urb->transfer_buffer, urb->actual_length);
1564 if (wa->dti_urb->actual_length != sizeof(*xfer_result)) { 1475 if (wa->dti_urb->actual_length != sizeof(*xfer_result)) {
1565 dev_err(dev, "DTI Error: xfer result--bad size " 1476 dev_err(dev, "DTI Error: xfer result--bad size "
1566 "xfer result (%d bytes vs %zu needed)\n", 1477 "xfer result (%d bytes vs %zu needed)\n",
@@ -1622,7 +1533,6 @@ static void wa_xfer_result_cb(struct urb *urb)
1622 wa_reset_all(wa); 1533 wa_reset_all(wa);
1623 } 1534 }
1624out: 1535out:
1625 d_fnend(3, dev, "(%p) = void\n", wa);
1626 return; 1536 return;
1627} 1537}
1628 1538
@@ -1653,7 +1563,6 @@ void wa_handle_notif_xfer(struct wahc *wa, struct wa_notif_hdr *notif_hdr)
1653 struct wa_notif_xfer *notif_xfer; 1563 struct wa_notif_xfer *notif_xfer;
1654 const struct usb_endpoint_descriptor *dti_epd = wa->dti_epd; 1564 const struct usb_endpoint_descriptor *dti_epd = wa->dti_epd;
1655 1565
1656 d_fnstart(4, dev, "(%p, %p)\n", wa, notif_hdr);
1657 notif_xfer = container_of(notif_hdr, struct wa_notif_xfer, hdr); 1566 notif_xfer = container_of(notif_hdr, struct wa_notif_xfer, hdr);
1658 BUG_ON(notif_hdr->bNotifyType != WA_NOTIF_TRANSFER); 1567 BUG_ON(notif_hdr->bNotifyType != WA_NOTIF_TRANSFER);
1659 1568
@@ -1693,7 +1602,6 @@ void wa_handle_notif_xfer(struct wahc *wa, struct wa_notif_hdr *notif_hdr)
1693 goto error_dti_urb_submit; 1602 goto error_dti_urb_submit;
1694 } 1603 }
1695out: 1604out:
1696 d_fnend(4, dev, "(%p, %p) = void\n", wa, notif_hdr);
1697 return; 1605 return;
1698 1606
1699error_dti_urb_submit: 1607error_dti_urb_submit:
@@ -1704,6 +1612,4 @@ error_buf_in_urb_alloc:
1704error_dti_urb_alloc: 1612error_dti_urb_alloc:
1705error: 1613error:
1706 wa_reset_all(wa); 1614 wa_reset_all(wa);
1707 d_fnend(4, dev, "(%p, %p) = void\n", wa, notif_hdr);
1708 return;
1709} 1615}
diff --git a/drivers/usb/wusbcore/wusbhc.h b/drivers/usb/wusbcore/wusbhc.h
index d0c132434f1b..797c2453a35b 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 257e6908304c..2f98d080fe78 100644
--- a/drivers/uwb/Makefile
+++ b/drivers/uwb/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_UWB_I1480U) += i1480/
6 6
7uwb-objs := \ 7uwb-objs := \
8 address.o \ 8 address.o \
9 allocator.o \
9 beacon.o \ 10 beacon.o \
10 driver.o \ 11 driver.o \
11 drp.o \ 12 drp.o \
@@ -13,10 +14,12 @@ uwb-objs := \
13 drp-ie.o \ 14 drp-ie.o \
14 est.o \ 15 est.o \
15 ie.o \ 16 ie.o \
17 ie-rcv.o \
16 lc-dev.o \ 18 lc-dev.o \
17 lc-rc.o \ 19 lc-rc.o \
18 neh.o \ 20 neh.o \
19 pal.o \ 21 pal.o \
22 radio.o \
20 reset.o \ 23 reset.o \
21 rsv.o \ 24 rsv.o \
22 scan.o \ 25 scan.o \
diff --git a/drivers/uwb/address.c b/drivers/uwb/address.c
index 1664ae5f1706..ad21b1d7218c 100644
--- a/drivers/uwb/address.c
+++ b/drivers/uwb/address.c
@@ -28,7 +28,7 @@
28#include <linux/device.h> 28#include <linux/device.h>
29#include <linux/random.h> 29#include <linux/random.h>
30#include <linux/etherdevice.h> 30#include <linux/etherdevice.h>
31#include <linux/uwb/debug.h> 31
32#include "uwb-internal.h" 32#include "uwb-internal.h"
33 33
34 34
diff --git a/drivers/uwb/allocator.c b/drivers/uwb/allocator.c
new file mode 100644
index 000000000000..c8185e6b0cd5
--- /dev/null
+++ b/drivers/uwb/allocator.c
@@ -0,0 +1,386 @@
1/*
2 * UWB reservation 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/version.h>
19#include <linux/kernel.h>
20#include <linux/uwb.h>
21
22#include "uwb-internal.h"
23
24static void uwb_rsv_fill_column_alloc(struct uwb_rsv_alloc_info *ai)
25{
26 int col, mas, safe_mas, unsafe_mas;
27 unsigned char *bm = ai->bm;
28 struct uwb_rsv_col_info *ci = ai->ci;
29 unsigned char c;
30
31 for (col = ci->csi.start_col; col < UWB_NUM_ZONES; col += ci->csi.interval) {
32
33 safe_mas = ci->csi.safe_mas_per_col;
34 unsafe_mas = ci->csi.unsafe_mas_per_col;
35
36 for (mas = 0; mas < UWB_MAS_PER_ZONE; mas++ ) {
37 if (bm[col * UWB_MAS_PER_ZONE + mas] == 0) {
38
39 if (safe_mas > 0) {
40 safe_mas--;
41 c = UWB_RSV_MAS_SAFE;
42 } else if (unsafe_mas > 0) {
43 unsafe_mas--;
44 c = UWB_RSV_MAS_UNSAFE;
45 } else {
46 break;
47 }
48 bm[col * UWB_MAS_PER_ZONE + mas] = c;
49 }
50 }
51 }
52}
53
54static void uwb_rsv_fill_row_alloc(struct uwb_rsv_alloc_info *ai)
55{
56 int mas, col, rows;
57 unsigned char *bm = ai->bm;
58 struct uwb_rsv_row_info *ri = &ai->ri;
59 unsigned char c;
60
61 rows = 1;
62 c = UWB_RSV_MAS_SAFE;
63 for (mas = UWB_MAS_PER_ZONE - 1; mas >= 0; mas--) {
64 if (ri->avail[mas] == 1) {
65
66 if (rows > ri->used_rows) {
67 break;
68 } else if (rows > 7) {
69 c = UWB_RSV_MAS_UNSAFE;
70 }
71
72 for (col = 0; col < UWB_NUM_ZONES; col++) {
73 if (bm[col * UWB_NUM_ZONES + mas] != UWB_RSV_MAS_NOT_AVAIL) {
74 bm[col * UWB_NUM_ZONES + mas] = c;
75 if(c == UWB_RSV_MAS_SAFE)
76 ai->safe_allocated_mases++;
77 else
78 ai->unsafe_allocated_mases++;
79 }
80 }
81 rows++;
82 }
83 }
84 ai->total_allocated_mases = ai->safe_allocated_mases + ai->unsafe_allocated_mases;
85}
86
87/*
88 * Find the best column set for a given availability, interval, num safe mas and
89 * num unsafe mas.
90 *
91 * The different sets are tried in order as shown below, depending on the interval.
92 *
93 * interval = 16
94 * deep = 0
95 * set 1 -> { 8 }
96 * deep = 1
97 * set 1 -> { 4 }
98 * set 2 -> { 12 }
99 * deep = 2
100 * set 1 -> { 2 }
101 * set 2 -> { 6 }
102 * set 3 -> { 10 }
103 * set 4 -> { 14 }
104 * deep = 3
105 * set 1 -> { 1 }
106 * set 2 -> { 3 }
107 * set 3 -> { 5 }
108 * set 4 -> { 7 }
109 * set 5 -> { 9 }
110 * set 6 -> { 11 }
111 * set 7 -> { 13 }
112 * set 8 -> { 15 }
113 *
114 * interval = 8
115 * deep = 0
116 * set 1 -> { 4 12 }
117 * deep = 1
118 * set 1 -> { 2 10 }
119 * set 2 -> { 6 14 }
120 * deep = 2
121 * set 1 -> { 1 9 }
122 * set 2 -> { 3 11 }
123 * set 3 -> { 5 13 }
124 * set 4 -> { 7 15 }
125 *
126 * interval = 4
127 * deep = 0
128 * set 1 -> { 2 6 10 14 }
129 * deep = 1
130 * set 1 -> { 1 5 9 13 }
131 * set 2 -> { 3 7 11 15 }
132 *
133 * interval = 2
134 * deep = 0
135 * set 1 -> { 1 3 5 7 9 11 13 15 }
136 */
137static int uwb_rsv_find_best_column_set(struct uwb_rsv_alloc_info *ai, int interval,
138 int num_safe_mas, int num_unsafe_mas)
139{
140 struct uwb_rsv_col_info *ci = ai->ci;
141 struct uwb_rsv_col_set_info *csi = &ci->csi;
142 struct uwb_rsv_col_set_info tmp_csi;
143 int deep, set, col, start_col_deep, col_start_set;
144 int start_col, max_mas_in_set, lowest_max_mas_in_deep;
145 int n_mas;
146 int found = UWB_RSV_ALLOC_NOT_FOUND;
147
148 tmp_csi.start_col = 0;
149 start_col_deep = interval;
150 n_mas = num_unsafe_mas + num_safe_mas;
151
152 for (deep = 0; ((interval >> deep) & 0x1) == 0; deep++) {
153 start_col_deep /= 2;
154 col_start_set = 0;
155 lowest_max_mas_in_deep = UWB_MAS_PER_ZONE;
156
157 for (set = 1; set <= (1 << deep); set++) {
158 max_mas_in_set = 0;
159 start_col = start_col_deep + col_start_set;
160 for (col = start_col; col < UWB_NUM_ZONES; col += interval) {
161
162 if (ci[col].max_avail_safe >= num_safe_mas &&
163 ci[col].max_avail_unsafe >= n_mas) {
164 if (ci[col].highest_mas[n_mas] > max_mas_in_set)
165 max_mas_in_set = ci[col].highest_mas[n_mas];
166 } else {
167 max_mas_in_set = 0;
168 break;
169 }
170 }
171 if ((lowest_max_mas_in_deep > max_mas_in_set) && max_mas_in_set) {
172 lowest_max_mas_in_deep = max_mas_in_set;
173
174 tmp_csi.start_col = start_col;
175 }
176 col_start_set += (interval >> deep);
177 }
178
179 if (lowest_max_mas_in_deep < 8) {
180 csi->start_col = tmp_csi.start_col;
181 found = UWB_RSV_ALLOC_FOUND;
182 break;
183 } else if ((lowest_max_mas_in_deep > 8) &&
184 (lowest_max_mas_in_deep != UWB_MAS_PER_ZONE) &&
185 (found == UWB_RSV_ALLOC_NOT_FOUND)) {
186 csi->start_col = tmp_csi.start_col;
187 found = UWB_RSV_ALLOC_FOUND;
188 }
189 }
190
191 if (found == UWB_RSV_ALLOC_FOUND) {
192 csi->interval = interval;
193 csi->safe_mas_per_col = num_safe_mas;
194 csi->unsafe_mas_per_col = num_unsafe_mas;
195
196 ai->safe_allocated_mases = (UWB_NUM_ZONES / interval) * num_safe_mas;
197 ai->unsafe_allocated_mases = (UWB_NUM_ZONES / interval) * num_unsafe_mas;
198 ai->total_allocated_mases = ai->safe_allocated_mases + ai->unsafe_allocated_mases;
199 ai->interval = interval;
200 }
201 return found;
202}
203
204static void get_row_descriptors(struct uwb_rsv_alloc_info *ai)
205{
206 unsigned char *bm = ai->bm;
207 struct uwb_rsv_row_info *ri = &ai->ri;
208 int col, mas;
209
210 ri->free_rows = 16;
211 for (mas = 0; mas < UWB_MAS_PER_ZONE; mas ++) {
212 ri->avail[mas] = 1;
213 for (col = 1; col < UWB_NUM_ZONES; col++) {
214 if (bm[col * UWB_NUM_ZONES + mas] == UWB_RSV_MAS_NOT_AVAIL) {
215 ri->free_rows--;
216 ri->avail[mas]=0;
217 break;
218 }
219 }
220 }
221}
222
223static void uwb_rsv_fill_column_info(unsigned char *bm, int column, struct uwb_rsv_col_info *rci)
224{
225 int mas;
226 int block_count = 0, start_block = 0;
227 int previous_avail = 0;
228 int available = 0;
229 int safe_mas_in_row[UWB_MAS_PER_ZONE] = {
230 8, 7, 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 2, 1,
231 };
232
233 rci->max_avail_safe = 0;
234
235 for (mas = 0; mas < UWB_MAS_PER_ZONE; mas ++) {
236 if (!bm[column * UWB_NUM_ZONES + mas]) {
237 available++;
238 rci->max_avail_unsafe = available;
239
240 rci->highest_mas[available] = mas;
241
242 if (previous_avail) {
243 block_count++;
244 if ((block_count > safe_mas_in_row[start_block]) &&
245 (!rci->max_avail_safe))
246 rci->max_avail_safe = available - 1;
247 } else {
248 previous_avail = 1;
249 start_block = mas;
250 block_count = 1;
251 }
252 } else {
253 previous_avail = 0;
254 }
255 }
256 if (!rci->max_avail_safe)
257 rci->max_avail_safe = rci->max_avail_unsafe;
258}
259
260static void get_column_descriptors(struct uwb_rsv_alloc_info *ai)
261{
262 unsigned char *bm = ai->bm;
263 struct uwb_rsv_col_info *ci = ai->ci;
264 int col;
265
266 for (col = 1; col < UWB_NUM_ZONES; col++) {
267 uwb_rsv_fill_column_info(bm, col, &ci[col]);
268 }
269}
270
271static int uwb_rsv_find_best_row_alloc(struct uwb_rsv_alloc_info *ai)
272{
273 int n_rows;
274 int max_rows = ai->max_mas / UWB_USABLE_MAS_PER_ROW;
275 int min_rows = ai->min_mas / UWB_USABLE_MAS_PER_ROW;
276 if (ai->min_mas % UWB_USABLE_MAS_PER_ROW)
277 min_rows++;
278 for (n_rows = max_rows; n_rows >= min_rows; n_rows--) {
279 if (n_rows <= ai->ri.free_rows) {
280 ai->ri.used_rows = n_rows;
281 ai->interval = 1; /* row reservation */
282 uwb_rsv_fill_row_alloc(ai);
283 return UWB_RSV_ALLOC_FOUND;
284 }
285 }
286 return UWB_RSV_ALLOC_NOT_FOUND;
287}
288
289static int uwb_rsv_find_best_col_alloc(struct uwb_rsv_alloc_info *ai, int interval)
290{
291 int n_safe, n_unsafe, n_mas;
292 int n_column = UWB_NUM_ZONES / interval;
293 int max_per_zone = ai->max_mas / n_column;
294 int min_per_zone = ai->min_mas / n_column;
295
296 if (ai->min_mas % n_column)
297 min_per_zone++;
298
299 if (min_per_zone > UWB_MAS_PER_ZONE) {
300 return UWB_RSV_ALLOC_NOT_FOUND;
301 }
302
303 if (max_per_zone > UWB_MAS_PER_ZONE) {
304 max_per_zone = UWB_MAS_PER_ZONE;
305 }
306
307 for (n_mas = max_per_zone; n_mas >= min_per_zone; n_mas--) {
308 if (uwb_rsv_find_best_column_set(ai, interval, 0, n_mas) == UWB_RSV_ALLOC_NOT_FOUND)
309 continue;
310 for (n_safe = n_mas; n_safe >= 0; n_safe--) {
311 n_unsafe = n_mas - n_safe;
312 if (uwb_rsv_find_best_column_set(ai, interval, n_safe, n_unsafe) == UWB_RSV_ALLOC_FOUND) {
313 uwb_rsv_fill_column_alloc(ai);
314 return UWB_RSV_ALLOC_FOUND;
315 }
316 }
317 }
318 return UWB_RSV_ALLOC_NOT_FOUND;
319}
320
321int uwb_rsv_find_best_allocation(struct uwb_rsv *rsv, struct uwb_mas_bm *available,
322 struct uwb_mas_bm *result)
323{
324 struct uwb_rsv_alloc_info *ai;
325 int interval;
326 int bit_index;
327
328 ai = kzalloc(sizeof(struct uwb_rsv_alloc_info), GFP_KERNEL);
329
330 ai->min_mas = rsv->min_mas;
331 ai->max_mas = rsv->max_mas;
332 ai->max_interval = rsv->max_interval;
333
334
335 /* fill the not available vector from the available bm */
336 for (bit_index = 0; bit_index < UWB_NUM_MAS; bit_index++) {
337 if (!test_bit(bit_index, available->bm))
338 ai->bm[bit_index] = UWB_RSV_MAS_NOT_AVAIL;
339 }
340
341 if (ai->max_interval == 1) {
342 get_row_descriptors(ai);
343 if (uwb_rsv_find_best_row_alloc(ai) == UWB_RSV_ALLOC_FOUND)
344 goto alloc_found;
345 else
346 goto alloc_not_found;
347 }
348
349 get_column_descriptors(ai);
350
351 for (interval = 16; interval >= 2; interval>>=1) {
352 if (interval > ai->max_interval)
353 continue;
354 if (uwb_rsv_find_best_col_alloc(ai, interval) == UWB_RSV_ALLOC_FOUND)
355 goto alloc_found;
356 }
357
358 /* try row reservation if no column is found */
359 get_row_descriptors(ai);
360 if (uwb_rsv_find_best_row_alloc(ai) == UWB_RSV_ALLOC_FOUND)
361 goto alloc_found;
362 else
363 goto alloc_not_found;
364
365 alloc_found:
366 bitmap_zero(result->bm, UWB_NUM_MAS);
367 bitmap_zero(result->unsafe_bm, UWB_NUM_MAS);
368 /* fill the safe and unsafe bitmaps */
369 for (bit_index = 0; bit_index < UWB_NUM_MAS; bit_index++) {
370 if (ai->bm[bit_index] == UWB_RSV_MAS_SAFE)
371 set_bit(bit_index, result->bm);
372 else if (ai->bm[bit_index] == UWB_RSV_MAS_UNSAFE)
373 set_bit(bit_index, result->unsafe_bm);
374 }
375 bitmap_or(result->bm, result->bm, result->unsafe_bm, UWB_NUM_MAS);
376
377 result->safe = ai->safe_allocated_mases;
378 result->unsafe = ai->unsafe_allocated_mases;
379
380 kfree(ai);
381 return UWB_RSV_ALLOC_FOUND;
382
383 alloc_not_found:
384 kfree(ai);
385 return UWB_RSV_ALLOC_NOT_FOUND;
386}
diff --git a/drivers/uwb/beacon.c b/drivers/uwb/beacon.c
index 46b18eec5026..36bc3158006f 100644
--- a/drivers/uwb/beacon.c
+++ b/drivers/uwb/beacon.c
@@ -22,19 +22,16 @@
22 * 22 *
23 * FIXME: docs 23 * FIXME: docs
24 */ 24 */
25
26#include <linux/kernel.h> 25#include <linux/kernel.h>
27#include <linux/init.h> 26#include <linux/init.h>
28#include <linux/module.h> 27#include <linux/module.h>
29#include <linux/device.h> 28#include <linux/device.h>
30#include <linux/err.h> 29#include <linux/err.h>
31#include <linux/kdev_t.h> 30#include <linux/kdev_t.h>
32#include "uwb-internal.h"
33 31
34#define D_LOCAL 0 32#include "uwb-internal.h"
35#include <linux/uwb/debug.h>
36 33
37/** Start Beaconing command structure */ 34/* Start Beaconing command structure */
38struct uwb_rc_cmd_start_beacon { 35struct uwb_rc_cmd_start_beacon {
39 struct uwb_rccb rccb; 36 struct uwb_rccb rccb;
40 __le16 wBPSTOffset; 37 __le16 wBPSTOffset;
@@ -119,7 +116,6 @@ int uwb_rc_beacon(struct uwb_rc *rc, int channel, unsigned bpst_offset)
119 int result; 116 int result;
120 struct device *dev = &rc->uwb_dev.dev; 117 struct device *dev = &rc->uwb_dev.dev;
121 118
122 mutex_lock(&rc->uwb_dev.mutex);
123 if (channel < 0) 119 if (channel < 0)
124 channel = -1; 120 channel = -1;
125 if (channel == -1) 121 if (channel == -1)
@@ -128,7 +124,7 @@ int uwb_rc_beacon(struct uwb_rc *rc, int channel, unsigned bpst_offset)
128 /* channel >= 0...dah */ 124 /* channel >= 0...dah */
129 result = uwb_rc_start_beacon(rc, bpst_offset, channel); 125 result = uwb_rc_start_beacon(rc, bpst_offset, channel);
130 if (result < 0) 126 if (result < 0)
131 goto out_up; 127 return result;
132 if (le16_to_cpu(rc->ies->wIELength) > 0) { 128 if (le16_to_cpu(rc->ies->wIELength) > 0) {
133 result = uwb_rc_set_ie(rc, rc->ies); 129 result = uwb_rc_set_ie(rc, rc->ies);
134 if (result < 0) { 130 if (result < 0) {
@@ -137,19 +133,12 @@ int uwb_rc_beacon(struct uwb_rc *rc, int channel, unsigned bpst_offset)
137 result = uwb_rc_stop_beacon(rc); 133 result = uwb_rc_stop_beacon(rc);
138 channel = -1; 134 channel = -1;
139 bpst_offset = 0; 135 bpst_offset = 0;
140 } else 136 }
141 result = 0;
142 } 137 }
143 } 138 }
144 139
145 if (result < 0) 140 if (result >= 0)
146 goto out_up; 141 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; 142 return result;
154} 143}
155 144
@@ -168,12 +157,6 @@ out_up:
168 * FIXME: use something faster for search than a list 157 * FIXME: use something faster for search than a list
169 */ 158 */
170 159
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) 160void uwb_bce_kfree(struct kref *_bce)
178{ 161{
179 struct uwb_beca_e *bce = container_of(_bce, struct uwb_beca_e, refcnt); 162 struct uwb_beca_e *bce = container_of(_bce, struct uwb_beca_e, refcnt);
@@ -185,13 +168,11 @@ void uwb_bce_kfree(struct kref *_bce)
185 168
186/* Find a beacon by dev addr in the cache */ 169/* Find a beacon by dev addr in the cache */
187static 170static
188struct uwb_beca_e *__uwb_beca_find_bydev(const struct uwb_dev_addr *dev_addr) 171struct uwb_beca_e *__uwb_beca_find_bydev(struct uwb_rc *rc,
172 const struct uwb_dev_addr *dev_addr)
189{ 173{
190 struct uwb_beca_e *bce, *next; 174 struct uwb_beca_e *bce, *next;
191 list_for_each_entry_safe(bce, next, &uwb_beca.list, node) { 175 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",
193 dev_addr->data[0], dev_addr->data[1],
194 bce->dev_addr.data[0], bce->dev_addr.data[1]);
195 if (!memcmp(&bce->dev_addr, dev_addr, sizeof(bce->dev_addr))) 176 if (!memcmp(&bce->dev_addr, dev_addr, sizeof(bce->dev_addr)))
196 goto out; 177 goto out;
197 } 178 }
@@ -202,10 +183,11 @@ out:
202 183
203/* Find a beacon by dev addr in the cache */ 184/* Find a beacon by dev addr in the cache */
204static 185static
205struct uwb_beca_e *__uwb_beca_find_bymac(const struct uwb_mac_addr *mac_addr) 186struct uwb_beca_e *__uwb_beca_find_bymac(struct uwb_rc *rc,
187 const struct uwb_mac_addr *mac_addr)
206{ 188{
207 struct uwb_beca_e *bce, *next; 189 struct uwb_beca_e *bce, *next;
208 list_for_each_entry_safe(bce, next, &uwb_beca.list, node) { 190 list_for_each_entry_safe(bce, next, &rc->uwb_beca.list, node) {
209 if (!memcmp(bce->mac_addr, mac_addr->data, 191 if (!memcmp(bce->mac_addr, mac_addr->data,
210 sizeof(struct uwb_mac_addr))) 192 sizeof(struct uwb_mac_addr)))
211 goto out; 193 goto out;
@@ -229,11 +211,11 @@ struct uwb_dev *uwb_dev_get_by_devaddr(struct uwb_rc *rc,
229 struct uwb_dev *found = NULL; 211 struct uwb_dev *found = NULL;
230 struct uwb_beca_e *bce; 212 struct uwb_beca_e *bce;
231 213
232 mutex_lock(&uwb_beca.mutex); 214 mutex_lock(&rc->uwb_beca.mutex);
233 bce = __uwb_beca_find_bydev(devaddr); 215 bce = __uwb_beca_find_bydev(rc, devaddr);
234 if (bce) 216 if (bce)
235 found = uwb_dev_try_get(rc, bce->uwb_dev); 217 found = uwb_dev_try_get(rc, bce->uwb_dev);
236 mutex_unlock(&uwb_beca.mutex); 218 mutex_unlock(&rc->uwb_beca.mutex);
237 219
238 return found; 220 return found;
239} 221}
@@ -249,11 +231,11 @@ struct uwb_dev *uwb_dev_get_by_macaddr(struct uwb_rc *rc,
249 struct uwb_dev *found = NULL; 231 struct uwb_dev *found = NULL;
250 struct uwb_beca_e *bce; 232 struct uwb_beca_e *bce;
251 233
252 mutex_lock(&uwb_beca.mutex); 234 mutex_lock(&rc->uwb_beca.mutex);
253 bce = __uwb_beca_find_bymac(macaddr); 235 bce = __uwb_beca_find_bymac(rc, macaddr);
254 if (bce) 236 if (bce)
255 found = uwb_dev_try_get(rc, bce->uwb_dev); 237 found = uwb_dev_try_get(rc, bce->uwb_dev);
256 mutex_unlock(&uwb_beca.mutex); 238 mutex_unlock(&rc->uwb_beca.mutex);
257 239
258 return found; 240 return found;
259} 241}
@@ -274,7 +256,9 @@ static void uwb_beca_e_init(struct uwb_beca_e *bce)
274 * @bf: Beacon frame (part of b, really) 256 * @bf: Beacon frame (part of b, really)
275 * @ts_jiffies: Timestamp (in jiffies) when the beacon was received 257 * @ts_jiffies: Timestamp (in jiffies) when the beacon was received
276 */ 258 */
277struct uwb_beca_e *__uwb_beca_add(struct uwb_rc_evt_beacon *be, 259static
260struct uwb_beca_e *__uwb_beca_add(struct uwb_rc *rc,
261 struct uwb_rc_evt_beacon *be,
278 struct uwb_beacon_frame *bf, 262 struct uwb_beacon_frame *bf,
279 unsigned long ts_jiffies) 263 unsigned long ts_jiffies)
280{ 264{
@@ -286,7 +270,7 @@ struct uwb_beca_e *__uwb_beca_add(struct uwb_rc_evt_beacon *be,
286 uwb_beca_e_init(bce); 270 uwb_beca_e_init(bce);
287 bce->ts_jiffies = ts_jiffies; 271 bce->ts_jiffies = ts_jiffies;
288 bce->uwb_dev = NULL; 272 bce->uwb_dev = NULL;
289 list_add(&bce->node, &uwb_beca.list); 273 list_add(&bce->node, &rc->uwb_beca.list);
290 return bce; 274 return bce;
291} 275}
292 276
@@ -295,33 +279,32 @@ struct uwb_beca_e *__uwb_beca_add(struct uwb_rc_evt_beacon *be,
295 * 279 *
296 * Remove associated devicest too. 280 * Remove associated devicest too.
297 */ 281 */
298void uwb_beca_purge(void) 282void uwb_beca_purge(struct uwb_rc *rc)
299{ 283{
300 struct uwb_beca_e *bce, *next; 284 struct uwb_beca_e *bce, *next;
301 unsigned long expires; 285 unsigned long expires;
302 286
303 mutex_lock(&uwb_beca.mutex); 287 mutex_lock(&rc->uwb_beca.mutex);
304 list_for_each_entry_safe(bce, next, &uwb_beca.list, node) { 288 list_for_each_entry_safe(bce, next, &rc->uwb_beca.list, node) {
305 expires = bce->ts_jiffies + msecs_to_jiffies(beacon_timeout_ms); 289 expires = bce->ts_jiffies + msecs_to_jiffies(beacon_timeout_ms);
306 if (time_after(jiffies, expires)) { 290 if (time_after(jiffies, expires)) {
307 uwbd_dev_offair(bce); 291 uwbd_dev_offair(bce);
308 list_del(&bce->node);
309 uwb_bce_put(bce);
310 } 292 }
311 } 293 }
312 mutex_unlock(&uwb_beca.mutex); 294 mutex_unlock(&rc->uwb_beca.mutex);
313} 295}
314 296
315/* Clean up the whole beacon cache. Called on shutdown */ 297/* Clean up the whole beacon cache. Called on shutdown */
316void uwb_beca_release(void) 298void uwb_beca_release(struct uwb_rc *rc)
317{ 299{
318 struct uwb_beca_e *bce, *next; 300 struct uwb_beca_e *bce, *next;
319 mutex_lock(&uwb_beca.mutex); 301
320 list_for_each_entry_safe(bce, next, &uwb_beca.list, node) { 302 mutex_lock(&rc->uwb_beca.mutex);
303 list_for_each_entry_safe(bce, next, &rc->uwb_beca.list, node) {
321 list_del(&bce->node); 304 list_del(&bce->node);
322 uwb_bce_put(bce); 305 uwb_bce_put(bce);
323 } 306 }
324 mutex_unlock(&uwb_beca.mutex); 307 mutex_unlock(&rc->uwb_beca.mutex);
325} 308}
326 309
327static void uwb_beacon_print(struct uwb_rc *rc, struct uwb_rc_evt_beacon *be, 310static void uwb_beacon_print(struct uwb_rc *rc, struct uwb_rc_evt_beacon *be,
@@ -349,22 +332,22 @@ ssize_t uwb_bce_print_IEs(struct uwb_dev *uwb_dev, struct uwb_beca_e *bce,
349 ssize_t result = 0; 332 ssize_t result = 0;
350 struct uwb_rc_evt_beacon *be; 333 struct uwb_rc_evt_beacon *be;
351 struct uwb_beacon_frame *bf; 334 struct uwb_beacon_frame *bf;
352 struct uwb_buf_ctx ctx = { 335 int ies_len;
353 .buf = buf, 336 struct uwb_ie_hdr *ies;
354 .bytes = 0,
355 .size = size
356 };
357 337
358 mutex_lock(&bce->mutex); 338 mutex_lock(&bce->mutex);
339
359 be = bce->be; 340 be = bce->be;
360 if (be == NULL) 341 if (be) {
361 goto out; 342 bf = (struct uwb_beacon_frame *)bce->be->BeaconInfo;
362 bf = (void *) be->BeaconInfo; 343 ies_len = be->wBeaconInfoLength - sizeof(struct uwb_beacon_frame);
363 uwb_ie_for_each(uwb_dev, uwb_ie_dump_hex, &ctx, 344 ies = (struct uwb_ie_hdr *)bf->IEData;
364 bf->IEData, be->wBeaconInfoLength - sizeof(*bf)); 345
365 result = ctx.bytes; 346 result = uwb_ie_dump_hex(ies, ies_len, buf, size);
366out: 347 }
348
367 mutex_unlock(&bce->mutex); 349 mutex_unlock(&bce->mutex);
350
368 return result; 351 return result;
369} 352}
370 353
@@ -437,18 +420,18 @@ int uwbd_evt_handle_rc_beacon(struct uwb_event *evt)
437 if (uwb_mac_addr_bcast(&bf->Device_Identifier)) 420 if (uwb_mac_addr_bcast(&bf->Device_Identifier))
438 return 0; 421 return 0;
439 422
440 mutex_lock(&uwb_beca.mutex); 423 mutex_lock(&rc->uwb_beca.mutex);
441 bce = __uwb_beca_find_bymac(&bf->Device_Identifier); 424 bce = __uwb_beca_find_bymac(rc, &bf->Device_Identifier);
442 if (bce == NULL) { 425 if (bce == NULL) {
443 /* Not in there, a new device is pinging */ 426 /* Not in there, a new device is pinging */
444 uwb_beacon_print(evt->rc, be, bf); 427 uwb_beacon_print(evt->rc, be, bf);
445 bce = __uwb_beca_add(be, bf, evt->ts_jiffies); 428 bce = __uwb_beca_add(rc, be, bf, evt->ts_jiffies);
446 if (bce == NULL) { 429 if (bce == NULL) {
447 mutex_unlock(&uwb_beca.mutex); 430 mutex_unlock(&rc->uwb_beca.mutex);
448 return -ENOMEM; 431 return -ENOMEM;
449 } 432 }
450 } 433 }
451 mutex_unlock(&uwb_beca.mutex); 434 mutex_unlock(&rc->uwb_beca.mutex);
452 435
453 mutex_lock(&bce->mutex); 436 mutex_lock(&bce->mutex);
454 /* purge old beacon data */ 437 /* purge old beacon data */
@@ -588,19 +571,6 @@ error:
588 return result; 571 return result;
589} 572}
590 573
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/* 574/*
605 * Print beaconing state. 575 * Print beaconing state.
606 */ 576 */
@@ -619,9 +589,6 @@ static ssize_t uwb_rc_beacon_show(struct device *dev,
619 589
620/* 590/*
621 * Start beaconing on the specified channel, or stop beaconing. 591 * 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 */ 592 */
626static ssize_t uwb_rc_beacon_store(struct device *dev, 593static ssize_t uwb_rc_beacon_store(struct device *dev,
627 struct device_attribute *attr, 594 struct device_attribute *attr,
@@ -630,12 +597,11 @@ static ssize_t uwb_rc_beacon_store(struct device *dev,
630 struct uwb_dev *uwb_dev = to_uwb_dev(dev); 597 struct uwb_dev *uwb_dev = to_uwb_dev(dev);
631 struct uwb_rc *rc = uwb_dev->rc; 598 struct uwb_rc *rc = uwb_dev->rc;
632 int channel; 599 int channel;
633 unsigned bpst_offset = 0;
634 ssize_t result = -EINVAL; 600 ssize_t result = -EINVAL;
635 601
636 result = sscanf(buf, "%d %u\n", &channel, &bpst_offset); 602 result = sscanf(buf, "%d", &channel);
637 if (result >= 1) 603 if (result >= 1)
638 result = uwb_rc_beacon(rc, channel, bpst_offset); 604 result = uwb_radio_force_channel(rc, channel);
639 605
640 return result < 0 ? result : size; 606 return result < 0 ? result : size;
641} 607}
diff --git a/drivers/uwb/driver.c b/drivers/uwb/driver.c
index 521cdeb84971..da77e41de990 100644
--- a/drivers/uwb/driver.c
+++ b/drivers/uwb/driver.c
@@ -53,7 +53,7 @@
53#include <linux/err.h> 53#include <linux/err.h>
54#include <linux/kdev_t.h> 54#include <linux/kdev_t.h>
55#include <linux/random.h> 55#include <linux/random.h>
56#include <linux/uwb/debug.h> 56
57#include "uwb-internal.h" 57#include "uwb-internal.h"
58 58
59 59
@@ -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-avail.c b/drivers/uwb/drp-avail.c
index 3febd8552808..40a540a5a72e 100644
--- a/drivers/uwb/drp-avail.c
+++ b/drivers/uwb/drp-avail.c
@@ -58,7 +58,7 @@ void uwb_drp_avail_init(struct uwb_rc *rc)
58 * 58 *
59 * avail = global & local & pending 59 * avail = global & local & pending
60 */ 60 */
61static void uwb_drp_available(struct uwb_rc *rc, struct uwb_mas_bm *avail) 61void uwb_drp_available(struct uwb_rc *rc, struct uwb_mas_bm *avail)
62{ 62{
63 bitmap_and(avail->bm, rc->drp_avail.global, rc->drp_avail.local, UWB_NUM_MAS); 63 bitmap_and(avail->bm, rc->drp_avail.global, rc->drp_avail.local, UWB_NUM_MAS);
64 bitmap_and(avail->bm, avail->bm, rc->drp_avail.pending, UWB_NUM_MAS); 64 bitmap_and(avail->bm, avail->bm, rc->drp_avail.pending, UWB_NUM_MAS);
@@ -105,6 +105,7 @@ void uwb_drp_avail_release(struct uwb_rc *rc, struct uwb_mas_bm *mas)
105 bitmap_or(rc->drp_avail.local, rc->drp_avail.local, mas->bm, UWB_NUM_MAS); 105 bitmap_or(rc->drp_avail.local, rc->drp_avail.local, mas->bm, UWB_NUM_MAS);
106 bitmap_or(rc->drp_avail.pending, rc->drp_avail.pending, mas->bm, UWB_NUM_MAS); 106 bitmap_or(rc->drp_avail.pending, rc->drp_avail.pending, mas->bm, UWB_NUM_MAS);
107 rc->drp_avail.ie_valid = false; 107 rc->drp_avail.ie_valid = false;
108 uwb_rsv_handle_drp_avail_change(rc);
108} 109}
109 110
110/** 111/**
@@ -280,6 +281,7 @@ int uwbd_evt_handle_rc_drp_avail(struct uwb_event *evt)
280 mutex_lock(&rc->rsvs_mutex); 281 mutex_lock(&rc->rsvs_mutex);
281 bitmap_copy(rc->drp_avail.global, bmp, UWB_NUM_MAS); 282 bitmap_copy(rc->drp_avail.global, bmp, UWB_NUM_MAS);
282 rc->drp_avail.ie_valid = false; 283 rc->drp_avail.ie_valid = false;
284 uwb_rsv_handle_drp_avail_change(rc);
283 mutex_unlock(&rc->rsvs_mutex); 285 mutex_unlock(&rc->rsvs_mutex);
284 286
285 uwb_rsv_sched_update(rc); 287 uwb_rsv_sched_update(rc);
diff --git a/drivers/uwb/drp-ie.c b/drivers/uwb/drp-ie.c
index 882724c5f126..2840d7bf9e67 100644
--- a/drivers/uwb/drp-ie.c
+++ b/drivers/uwb/drp-ie.c
@@ -16,13 +16,102 @@
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>
23 22
24#include "uwb-internal.h" 23#include "uwb-internal.h"
25 24
25
26/*
27 * Return the reason code for a reservations's DRP IE.
28 */
29int uwb_rsv_reason_code(struct uwb_rsv *rsv)
30{
31 static const int reason_codes[] = {
32 [UWB_RSV_STATE_O_INITIATED] = UWB_DRP_REASON_ACCEPTED,
33 [UWB_RSV_STATE_O_PENDING] = UWB_DRP_REASON_ACCEPTED,
34 [UWB_RSV_STATE_O_MODIFIED] = UWB_DRP_REASON_MODIFIED,
35 [UWB_RSV_STATE_O_ESTABLISHED] = UWB_DRP_REASON_ACCEPTED,
36 [UWB_RSV_STATE_O_TO_BE_MOVED] = UWB_DRP_REASON_ACCEPTED,
37 [UWB_RSV_STATE_O_MOVE_COMBINING] = UWB_DRP_REASON_MODIFIED,
38 [UWB_RSV_STATE_O_MOVE_REDUCING] = UWB_DRP_REASON_MODIFIED,
39 [UWB_RSV_STATE_O_MOVE_EXPANDING] = UWB_DRP_REASON_ACCEPTED,
40 [UWB_RSV_STATE_T_ACCEPTED] = UWB_DRP_REASON_ACCEPTED,
41 [UWB_RSV_STATE_T_CONFLICT] = UWB_DRP_REASON_CONFLICT,
42 [UWB_RSV_STATE_T_PENDING] = UWB_DRP_REASON_PENDING,
43 [UWB_RSV_STATE_T_DENIED] = UWB_DRP_REASON_DENIED,
44 [UWB_RSV_STATE_T_RESIZED] = UWB_DRP_REASON_ACCEPTED,
45 [UWB_RSV_STATE_T_EXPANDING_ACCEPTED] = UWB_DRP_REASON_ACCEPTED,
46 [UWB_RSV_STATE_T_EXPANDING_CONFLICT] = UWB_DRP_REASON_CONFLICT,
47 [UWB_RSV_STATE_T_EXPANDING_PENDING] = UWB_DRP_REASON_PENDING,
48 [UWB_RSV_STATE_T_EXPANDING_DENIED] = UWB_DRP_REASON_DENIED,
49 };
50
51 return reason_codes[rsv->state];
52}
53
54/*
55 * Return the reason code for a reservations's companion DRP IE .
56 */
57int uwb_rsv_companion_reason_code(struct uwb_rsv *rsv)
58{
59 static const int companion_reason_codes[] = {
60 [UWB_RSV_STATE_O_MOVE_EXPANDING] = UWB_DRP_REASON_ACCEPTED,
61 [UWB_RSV_STATE_T_EXPANDING_ACCEPTED] = UWB_DRP_REASON_ACCEPTED,
62 [UWB_RSV_STATE_T_EXPANDING_CONFLICT] = UWB_DRP_REASON_CONFLICT,
63 [UWB_RSV_STATE_T_EXPANDING_PENDING] = UWB_DRP_REASON_PENDING,
64 [UWB_RSV_STATE_T_EXPANDING_DENIED] = UWB_DRP_REASON_DENIED,
65 };
66
67 return companion_reason_codes[rsv->state];
68}
69
70/*
71 * Return the status bit for a reservations's DRP IE.
72 */
73int uwb_rsv_status(struct uwb_rsv *rsv)
74{
75 static const int statuses[] = {
76 [UWB_RSV_STATE_O_INITIATED] = 0,
77 [UWB_RSV_STATE_O_PENDING] = 0,
78 [UWB_RSV_STATE_O_MODIFIED] = 1,
79 [UWB_RSV_STATE_O_ESTABLISHED] = 1,
80 [UWB_RSV_STATE_O_TO_BE_MOVED] = 0,
81 [UWB_RSV_STATE_O_MOVE_COMBINING] = 1,
82 [UWB_RSV_STATE_O_MOVE_REDUCING] = 1,
83 [UWB_RSV_STATE_O_MOVE_EXPANDING] = 1,
84 [UWB_RSV_STATE_T_ACCEPTED] = 1,
85 [UWB_RSV_STATE_T_CONFLICT] = 0,
86 [UWB_RSV_STATE_T_PENDING] = 0,
87 [UWB_RSV_STATE_T_DENIED] = 0,
88 [UWB_RSV_STATE_T_RESIZED] = 1,
89 [UWB_RSV_STATE_T_EXPANDING_ACCEPTED] = 1,
90 [UWB_RSV_STATE_T_EXPANDING_CONFLICT] = 1,
91 [UWB_RSV_STATE_T_EXPANDING_PENDING] = 1,
92 [UWB_RSV_STATE_T_EXPANDING_DENIED] = 1,
93
94 };
95
96 return statuses[rsv->state];
97}
98
99/*
100 * Return the status bit for a reservations's companion DRP IE .
101 */
102int uwb_rsv_companion_status(struct uwb_rsv *rsv)
103{
104 static const int companion_statuses[] = {
105 [UWB_RSV_STATE_O_MOVE_EXPANDING] = 0,
106 [UWB_RSV_STATE_T_EXPANDING_ACCEPTED] = 1,
107 [UWB_RSV_STATE_T_EXPANDING_CONFLICT] = 0,
108 [UWB_RSV_STATE_T_EXPANDING_PENDING] = 0,
109 [UWB_RSV_STATE_T_EXPANDING_DENIED] = 0,
110 };
111
112 return companion_statuses[rsv->state];
113}
114
26/* 115/*
27 * Allocate a DRP IE. 116 * Allocate a DRP IE.
28 * 117 *
@@ -34,16 +123,12 @@
34static struct uwb_ie_drp *uwb_drp_ie_alloc(void) 123static struct uwb_ie_drp *uwb_drp_ie_alloc(void)
35{ 124{
36 struct uwb_ie_drp *drp_ie; 125 struct uwb_ie_drp *drp_ie;
37 unsigned tiebreaker;
38 126
39 drp_ie = kzalloc(sizeof(struct uwb_ie_drp) + 127 drp_ie = kzalloc(sizeof(struct uwb_ie_drp) +
40 UWB_NUM_ZONES * sizeof(struct uwb_drp_alloc), 128 UWB_NUM_ZONES * sizeof(struct uwb_drp_alloc),
41 GFP_KERNEL); 129 GFP_KERNEL);
42 if (drp_ie) { 130 if (drp_ie) {
43 drp_ie->hdr.element_id = UWB_IE_DRP; 131 drp_ie->hdr.element_id = UWB_IE_DRP;
44
45 get_random_bytes(&tiebreaker, sizeof(unsigned));
46 uwb_ie_drp_set_tiebreaker(drp_ie, tiebreaker & 1);
47 } 132 }
48 return drp_ie; 133 return drp_ie;
49} 134}
@@ -104,43 +189,17 @@ static void uwb_drp_ie_from_bm(struct uwb_ie_drp *drp_ie,
104 */ 189 */
105int uwb_drp_ie_update(struct uwb_rsv *rsv) 190int uwb_drp_ie_update(struct uwb_rsv *rsv)
106{ 191{
107 struct device *dev = &rsv->rc->uwb_dev.dev;
108 struct uwb_ie_drp *drp_ie; 192 struct uwb_ie_drp *drp_ie;
109 int reason_code, status; 193 struct uwb_rsv_move *mv;
194 int unsafe;
110 195
111 switch (rsv->state) { 196 if (rsv->state == UWB_RSV_STATE_NONE) {
112 case UWB_RSV_STATE_NONE:
113 kfree(rsv->drp_ie); 197 kfree(rsv->drp_ie);
114 rsv->drp_ie = NULL; 198 rsv->drp_ie = NULL;
115 return 0; 199 return 0;
116 case UWB_RSV_STATE_O_INITIATED:
117 reason_code = UWB_DRP_REASON_ACCEPTED;
118 status = 0;
119 break;
120 case UWB_RSV_STATE_O_PENDING:
121 reason_code = UWB_DRP_REASON_ACCEPTED;
122 status = 0;
123 break;
124 case UWB_RSV_STATE_O_MODIFIED:
125 reason_code = UWB_DRP_REASON_MODIFIED;
126 status = 1;
127 break;
128 case UWB_RSV_STATE_O_ESTABLISHED:
129 reason_code = UWB_DRP_REASON_ACCEPTED;
130 status = 1;
131 break;
132 case UWB_RSV_STATE_T_ACCEPTED:
133 reason_code = UWB_DRP_REASON_ACCEPTED;
134 status = 1;
135 break;
136 case UWB_RSV_STATE_T_DENIED:
137 reason_code = UWB_DRP_REASON_DENIED;
138 status = 0;
139 break;
140 default:
141 dev_dbg(dev, "rsv with unhandled state (%d)\n", rsv->state);
142 return -EINVAL;
143 } 200 }
201
202 unsafe = rsv->mas.unsafe ? 1 : 0;
144 203
145 if (rsv->drp_ie == NULL) { 204 if (rsv->drp_ie == NULL) {
146 rsv->drp_ie = uwb_drp_ie_alloc(); 205 rsv->drp_ie = uwb_drp_ie_alloc();
@@ -149,9 +208,11 @@ int uwb_drp_ie_update(struct uwb_rsv *rsv)
149 } 208 }
150 drp_ie = rsv->drp_ie; 209 drp_ie = rsv->drp_ie;
151 210
211 uwb_ie_drp_set_unsafe(drp_ie, unsafe);
212 uwb_ie_drp_set_tiebreaker(drp_ie, rsv->tiebreaker);
152 uwb_ie_drp_set_owner(drp_ie, uwb_rsv_is_owner(rsv)); 213 uwb_ie_drp_set_owner(drp_ie, uwb_rsv_is_owner(rsv));
153 uwb_ie_drp_set_status(drp_ie, status); 214 uwb_ie_drp_set_status(drp_ie, uwb_rsv_status(rsv));
154 uwb_ie_drp_set_reason_code(drp_ie, reason_code); 215 uwb_ie_drp_set_reason_code(drp_ie, uwb_rsv_reason_code(rsv));
155 uwb_ie_drp_set_stream_index(drp_ie, rsv->stream); 216 uwb_ie_drp_set_stream_index(drp_ie, rsv->stream);
156 uwb_ie_drp_set_type(drp_ie, rsv->type); 217 uwb_ie_drp_set_type(drp_ie, rsv->type);
157 218
@@ -169,6 +230,27 @@ int uwb_drp_ie_update(struct uwb_rsv *rsv)
169 230
170 uwb_drp_ie_from_bm(drp_ie, &rsv->mas); 231 uwb_drp_ie_from_bm(drp_ie, &rsv->mas);
171 232
233 if (uwb_rsv_has_two_drp_ies(rsv)) {
234 mv = &rsv->mv;
235 if (mv->companion_drp_ie == NULL) {
236 mv->companion_drp_ie = uwb_drp_ie_alloc();
237 if (mv->companion_drp_ie == NULL)
238 return -ENOMEM;
239 }
240 drp_ie = mv->companion_drp_ie;
241
242 /* keep all the same configuration of the main drp_ie */
243 memcpy(drp_ie, rsv->drp_ie, sizeof(struct uwb_ie_drp));
244
245
246 /* FIXME: handle properly the unsafe bit */
247 uwb_ie_drp_set_unsafe(drp_ie, 1);
248 uwb_ie_drp_set_status(drp_ie, uwb_rsv_companion_status(rsv));
249 uwb_ie_drp_set_reason_code(drp_ie, uwb_rsv_companion_reason_code(rsv));
250
251 uwb_drp_ie_from_bm(drp_ie, &mv->companion_mas);
252 }
253
172 rsv->ie_valid = true; 254 rsv->ie_valid = true;
173 return 0; 255 return 0;
174} 256}
@@ -219,6 +301,8 @@ void uwb_drp_ie_to_bm(struct uwb_mas_bm *bm, const struct uwb_ie_drp *drp_ie)
219 u8 zone; 301 u8 zone;
220 u16 zone_mask; 302 u16 zone_mask;
221 303
304 bitmap_zero(bm->bm, UWB_NUM_MAS);
305
222 for (cnt = 0; cnt < numallocs; cnt++) { 306 for (cnt = 0; cnt < numallocs; cnt++) {
223 alloc = &drp_ie->allocs[cnt]; 307 alloc = &drp_ie->allocs[cnt];
224 zone_bm = le16_to_cpu(alloc->zone_bm); 308 zone_bm = le16_to_cpu(alloc->zone_bm);
@@ -230,3 +314,4 @@ void uwb_drp_ie_to_bm(struct uwb_mas_bm *bm, const struct uwb_ie_drp *drp_ie)
230 } 314 }
231 } 315 }
232} 316}
317
diff --git a/drivers/uwb/drp.c b/drivers/uwb/drp.c
index c0b1e5e2bd08..2b4f9406789d 100644
--- a/drivers/uwb/drp.c
+++ b/drivers/uwb/drp.c
@@ -23,6 +23,59 @@
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include "uwb-internal.h" 24#include "uwb-internal.h"
25 25
26
27/* DRP Conflict Actions ([ECMA-368 2nd Edition] 17.4.6) */
28enum uwb_drp_conflict_action {
29 /* Reservation is mantained, no action needed */
30 UWB_DRP_CONFLICT_MANTAIN = 0,
31
32 /* the device shall not transmit frames in conflicting MASs in
33 * the following superframe. If the device is the reservation
34 * target, it shall also set the Reason Code in its DRP IE to
35 * Conflict in its beacon in the following superframe.
36 */
37 UWB_DRP_CONFLICT_ACT1,
38
39 /* the device shall not set the Reservation Status bit to ONE
40 * and shall not transmit frames in conflicting MASs. If the
41 * device is the reservation target, it shall also set the
42 * Reason Code in its DRP IE to Conflict.
43 */
44 UWB_DRP_CONFLICT_ACT2,
45
46 /* the device shall not transmit frames in conflicting MASs in
47 * the following superframe. It shall remove the conflicting
48 * MASs from the reservation or set the Reservation Status to
49 * ZERO in its beacon in the following superframe. If the
50 * device is the reservation target, it shall also set the
51 * Reason Code in its DRP IE to Conflict.
52 */
53 UWB_DRP_CONFLICT_ACT3,
54};
55
56
57static void uwb_rc_set_drp_cmd_done(struct uwb_rc *rc, void *arg,
58 struct uwb_rceb *reply, ssize_t reply_size)
59{
60 struct uwb_rc_evt_set_drp_ie *r = (struct uwb_rc_evt_set_drp_ie *)reply;
61
62 if (r != NULL) {
63 if (r->bResultCode != UWB_RC_RES_SUCCESS)
64 dev_err(&rc->uwb_dev.dev, "SET-DRP-IE failed: %s (%d)\n",
65 uwb_rc_strerror(r->bResultCode), r->bResultCode);
66 } else
67 dev_err(&rc->uwb_dev.dev, "SET-DRP-IE: timeout\n");
68
69 spin_lock(&rc->rsvs_lock);
70 if (rc->set_drp_ie_pending > 1) {
71 rc->set_drp_ie_pending = 0;
72 uwb_rsv_queue_update(rc);
73 } else {
74 rc->set_drp_ie_pending = 0;
75 }
76 spin_unlock(&rc->rsvs_lock);
77}
78
26/** 79/**
27 * Construct and send the SET DRP IE 80 * Construct and send the SET DRP IE
28 * 81 *
@@ -37,28 +90,32 @@
37 * 90 *
38 * A DRP Availability IE is appended. 91 * A DRP Availability IE is appended.
39 * 92 *
40 * rc->uwb_dev.mutex is held 93 * rc->rsvs_mutex is held
41 * 94 *
42 * FIXME We currently ignore the returned value indicating the remaining space 95 * FIXME We currently ignore the returned value indicating the remaining space
43 * in beacon. This could be used to deny reservation requests earlier if 96 * in beacon. This could be used to deny reservation requests earlier if
44 * determined that they would cause the beacon space to be exceeded. 97 * determined that they would cause the beacon space to be exceeded.
45 */ 98 */
46static 99int uwb_rc_send_all_drp_ie(struct uwb_rc *rc)
47int uwb_rc_gen_send_drp_ie(struct uwb_rc *rc)
48{ 100{
49 int result; 101 int result;
50 struct device *dev = &rc->uwb_dev.dev;
51 struct uwb_rc_cmd_set_drp_ie *cmd; 102 struct uwb_rc_cmd_set_drp_ie *cmd;
52 struct uwb_rc_evt_set_drp_ie reply;
53 struct uwb_rsv *rsv; 103 struct uwb_rsv *rsv;
104 struct uwb_rsv_move *mv;
54 int num_bytes = 0; 105 int num_bytes = 0;
55 u8 *IEDataptr; 106 u8 *IEDataptr;
56 107
57 result = -ENOMEM; 108 result = -ENOMEM;
58 /* First traverse all reservations to determine memory needed. */ 109 /* First traverse all reservations to determine memory needed. */
59 list_for_each_entry(rsv, &rc->reservations, rc_node) { 110 list_for_each_entry(rsv, &rc->reservations, rc_node) {
60 if (rsv->drp_ie != NULL) 111 if (rsv->drp_ie != NULL) {
61 num_bytes += rsv->drp_ie->hdr.length + 2; 112 num_bytes += rsv->drp_ie->hdr.length + 2;
113 if (uwb_rsv_has_two_drp_ies(rsv) &&
114 (rsv->mv.companion_drp_ie != NULL)) {
115 mv = &rsv->mv;
116 num_bytes += mv->companion_drp_ie->hdr.length + 2;
117 }
118 }
62 } 119 }
63 num_bytes += sizeof(rc->drp_avail.ie); 120 num_bytes += sizeof(rc->drp_avail.ie);
64 cmd = kzalloc(sizeof(*cmd) + num_bytes, GFP_KERNEL); 121 cmd = kzalloc(sizeof(*cmd) + num_bytes, GFP_KERNEL);
@@ -69,128 +126,322 @@ int uwb_rc_gen_send_drp_ie(struct uwb_rc *rc)
69 cmd->wIELength = num_bytes; 126 cmd->wIELength = num_bytes;
70 IEDataptr = (u8 *)&cmd->IEData[0]; 127 IEDataptr = (u8 *)&cmd->IEData[0];
71 128
129 /* FIXME: DRV avail IE is not always needed */
130 /* put DRP avail IE first */
131 memcpy(IEDataptr, &rc->drp_avail.ie, sizeof(rc->drp_avail.ie));
132 IEDataptr += sizeof(struct uwb_ie_drp_avail);
133
72 /* Next traverse all reservations to place IEs in allocated memory. */ 134 /* Next traverse all reservations to place IEs in allocated memory. */
73 list_for_each_entry(rsv, &rc->reservations, rc_node) { 135 list_for_each_entry(rsv, &rc->reservations, rc_node) {
74 if (rsv->drp_ie != NULL) { 136 if (rsv->drp_ie != NULL) {
75 memcpy(IEDataptr, rsv->drp_ie, 137 memcpy(IEDataptr, rsv->drp_ie,
76 rsv->drp_ie->hdr.length + 2); 138 rsv->drp_ie->hdr.length + 2);
77 IEDataptr += rsv->drp_ie->hdr.length + 2; 139 IEDataptr += rsv->drp_ie->hdr.length + 2;
140
141 if (uwb_rsv_has_two_drp_ies(rsv) &&
142 (rsv->mv.companion_drp_ie != NULL)) {
143 mv = &rsv->mv;
144 memcpy(IEDataptr, mv->companion_drp_ie,
145 mv->companion_drp_ie->hdr.length + 2);
146 IEDataptr += mv->companion_drp_ie->hdr.length + 2;
147 }
78 } 148 }
79 } 149 }
80 memcpy(IEDataptr, &rc->drp_avail.ie, sizeof(rc->drp_avail.ie));
81 150
82 reply.rceb.bEventType = UWB_RC_CET_GENERAL; 151 result = uwb_rc_cmd_async(rc, "SET-DRP-IE", &cmd->rccb, sizeof(*cmd) + num_bytes,
83 reply.rceb.wEvent = UWB_RC_CMD_SET_DRP_IE; 152 UWB_RC_CET_GENERAL, UWB_RC_CMD_SET_DRP_IE,
84 result = uwb_rc_cmd(rc, "SET-DRP-IE", &cmd->rccb, 153 uwb_rc_set_drp_cmd_done, NULL);
85 sizeof(*cmd) + num_bytes, &reply.rceb, 154
86 sizeof(reply)); 155 rc->set_drp_ie_pending = 1;
87 if (result < 0) 156
88 goto error_cmd;
89 result = le16_to_cpu(reply.wRemainingSpace);
90 if (reply.bResultCode != UWB_RC_RES_SUCCESS) {
91 dev_err(&rc->uwb_dev.dev, "SET-DRP-IE: command execution "
92 "failed: %s (%d). RemainingSpace in beacon "
93 "= %d\n", uwb_rc_strerror(reply.bResultCode),
94 reply.bResultCode, result);
95 result = -EIO;
96 } else {
97 dev_dbg(dev, "SET-DRP-IE sent. RemainingSpace in beacon "
98 "= %d.\n", result);
99 result = 0;
100 }
101error_cmd:
102 kfree(cmd); 157 kfree(cmd);
103error: 158error:
104 return result; 159 return result;
105
106} 160}
107/** 161
108 * Send all DRP IEs associated with this host 162/*
109 * 163 * Evaluate the action to perform using conflict resolution rules
110 * @returns: >= 0 number of bytes still available in the beacon
111 * < 0 errno code on error.
112 * 164 *
113 * As per the protocol we obtain the host controller device lock to access 165 * Return a uwb_drp_conflict_action.
114 * bandwidth structures.
115 */ 166 */
116int uwb_rc_send_all_drp_ie(struct uwb_rc *rc) 167static int evaluate_conflict_action(struct uwb_ie_drp *ext_drp_ie, int ext_beacon_slot,
168 struct uwb_rsv *rsv, int our_status)
117{ 169{
118 int result; 170 int our_tie_breaker = rsv->tiebreaker;
171 int our_type = rsv->type;
172 int our_beacon_slot = rsv->rc->uwb_dev.beacon_slot;
173
174 int ext_tie_breaker = uwb_ie_drp_tiebreaker(ext_drp_ie);
175 int ext_status = uwb_ie_drp_status(ext_drp_ie);
176 int ext_type = uwb_ie_drp_type(ext_drp_ie);
177
178
179 /* [ECMA-368 2nd Edition] 17.4.6 */
180 if (ext_type == UWB_DRP_TYPE_PCA && our_type == UWB_DRP_TYPE_PCA) {
181 return UWB_DRP_CONFLICT_MANTAIN;
182 }
119 183
120 mutex_lock(&rc->uwb_dev.mutex); 184 /* [ECMA-368 2nd Edition] 17.4.6-1 */
121 result = uwb_rc_gen_send_drp_ie(rc); 185 if (our_type == UWB_DRP_TYPE_ALIEN_BP) {
122 mutex_unlock(&rc->uwb_dev.mutex); 186 return UWB_DRP_CONFLICT_MANTAIN;
123 return result; 187 }
188
189 /* [ECMA-368 2nd Edition] 17.4.6-2 */
190 if (ext_type == UWB_DRP_TYPE_ALIEN_BP) {
191 /* here we know our_type != UWB_DRP_TYPE_ALIEN_BP */
192 return UWB_DRP_CONFLICT_ACT1;
193 }
194
195 /* [ECMA-368 2nd Edition] 17.4.6-3 */
196 if (our_status == 0 && ext_status == 1) {
197 return UWB_DRP_CONFLICT_ACT2;
198 }
199
200 /* [ECMA-368 2nd Edition] 17.4.6-4 */
201 if (our_status == 1 && ext_status == 0) {
202 return UWB_DRP_CONFLICT_MANTAIN;
203 }
204
205 /* [ECMA-368 2nd Edition] 17.4.6-5a */
206 if (our_tie_breaker == ext_tie_breaker &&
207 our_beacon_slot < ext_beacon_slot) {
208 return UWB_DRP_CONFLICT_MANTAIN;
209 }
210
211 /* [ECMA-368 2nd Edition] 17.4.6-5b */
212 if (our_tie_breaker != ext_tie_breaker &&
213 our_beacon_slot > ext_beacon_slot) {
214 return UWB_DRP_CONFLICT_MANTAIN;
215 }
216
217 if (our_status == 0) {
218 if (our_tie_breaker == ext_tie_breaker) {
219 /* [ECMA-368 2nd Edition] 17.4.6-6a */
220 if (our_beacon_slot > ext_beacon_slot) {
221 return UWB_DRP_CONFLICT_ACT2;
222 }
223 } else {
224 /* [ECMA-368 2nd Edition] 17.4.6-6b */
225 if (our_beacon_slot < ext_beacon_slot) {
226 return UWB_DRP_CONFLICT_ACT2;
227 }
228 }
229 } else {
230 if (our_tie_breaker == ext_tie_breaker) {
231 /* [ECMA-368 2nd Edition] 17.4.6-7a */
232 if (our_beacon_slot > ext_beacon_slot) {
233 return UWB_DRP_CONFLICT_ACT3;
234 }
235 } else {
236 /* [ECMA-368 2nd Edition] 17.4.6-7b */
237 if (our_beacon_slot < ext_beacon_slot) {
238 return UWB_DRP_CONFLICT_ACT3;
239 }
240 }
241 }
242 return UWB_DRP_CONFLICT_MANTAIN;
124} 243}
125 244
126void uwb_drp_handle_timeout(struct uwb_rsv *rsv) 245static void handle_conflict_normal(struct uwb_ie_drp *drp_ie,
246 int ext_beacon_slot,
247 struct uwb_rsv *rsv,
248 struct uwb_mas_bm *conflicting_mas)
127{ 249{
128 struct device *dev = &rsv->rc->uwb_dev.dev; 250 struct uwb_rc *rc = rsv->rc;
251 struct uwb_rsv_move *mv = &rsv->mv;
252 struct uwb_drp_backoff_win *bow = &rc->bow;
253 int action;
254
255 action = evaluate_conflict_action(drp_ie, ext_beacon_slot, rsv, uwb_rsv_status(rsv));
256
257 if (uwb_rsv_is_owner(rsv)) {
258 switch(action) {
259 case UWB_DRP_CONFLICT_ACT2:
260 /* try move */
261 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_TO_BE_MOVED);
262 if (bow->can_reserve_extra_mases == false)
263 uwb_rsv_backoff_win_increment(rc);
264
265 break;
266 case UWB_DRP_CONFLICT_ACT3:
267 uwb_rsv_backoff_win_increment(rc);
268 /* drop some mases with reason modified */
269 /* put in the companion the mases to be dropped */
270 bitmap_and(mv->companion_mas.bm, rsv->mas.bm, conflicting_mas->bm, UWB_NUM_MAS);
271 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MODIFIED);
272 default:
273 break;
274 }
275 } else {
276 switch(action) {
277 case UWB_DRP_CONFLICT_ACT2:
278 case UWB_DRP_CONFLICT_ACT3:
279 uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_CONFLICT);
280 default:
281 break;
282 }
129 283
130 dev_dbg(dev, "reservation timeout in state %s (%d)\n", 284 }
131 uwb_rsv_state_str(rsv->state), rsv->state); 285
286}
132 287
133 switch (rsv->state) { 288static void handle_conflict_expanding(struct uwb_ie_drp *drp_ie, int ext_beacon_slot,
134 case UWB_RSV_STATE_O_INITIATED: 289 struct uwb_rsv *rsv, bool companion_only,
135 if (rsv->is_multicast) { 290 struct uwb_mas_bm *conflicting_mas)
136 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_ESTABLISHED); 291{
137 return; 292 struct uwb_rc *rc = rsv->rc;
293 struct uwb_drp_backoff_win *bow = &rc->bow;
294 struct uwb_rsv_move *mv = &rsv->mv;
295 int action;
296
297 if (companion_only) {
298 /* status of companion is 0 at this point */
299 action = evaluate_conflict_action(drp_ie, ext_beacon_slot, rsv, 0);
300 if (uwb_rsv_is_owner(rsv)) {
301 switch(action) {
302 case UWB_DRP_CONFLICT_ACT2:
303 case UWB_DRP_CONFLICT_ACT3:
304 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_ESTABLISHED);
305 rsv->needs_release_companion_mas = false;
306 if (bow->can_reserve_extra_mases == false)
307 uwb_rsv_backoff_win_increment(rc);
308 uwb_drp_avail_release(rsv->rc, &rsv->mv.companion_mas);
309 }
310 } else { /* rsv is target */
311 switch(action) {
312 case UWB_DRP_CONFLICT_ACT2:
313 case UWB_DRP_CONFLICT_ACT3:
314 uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_EXPANDING_CONFLICT);
315 /* send_drp_avail_ie = true; */
316 }
138 } 317 }
139 break; 318 } else { /* also base part of the reservation is conflicting */
140 case UWB_RSV_STATE_O_ESTABLISHED: 319 if (uwb_rsv_is_owner(rsv)) {
141 if (rsv->is_multicast) 320 uwb_rsv_backoff_win_increment(rc);
142 return; 321 /* remove companion part */
143 break; 322 uwb_drp_avail_release(rsv->rc, &rsv->mv.companion_mas);
144 default: 323
145 break; 324 /* drop some mases with reason modified */
325
326 /* put in the companion the mases to be dropped */
327 bitmap_andnot(mv->companion_mas.bm, rsv->mas.bm, conflicting_mas->bm, UWB_NUM_MAS);
328 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MODIFIED);
329 } else { /* it is a target rsv */
330 uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_CONFLICT);
331 /* send_drp_avail_ie = true; */
332 }
333 }
334}
335
336static void uwb_drp_handle_conflict_rsv(struct uwb_rc *rc, struct uwb_rsv *rsv,
337 struct uwb_rc_evt_drp *drp_evt,
338 struct uwb_ie_drp *drp_ie,
339 struct uwb_mas_bm *conflicting_mas)
340{
341 struct uwb_rsv_move *mv;
342
343 /* check if the conflicting reservation has two drp_ies */
344 if (uwb_rsv_has_two_drp_ies(rsv)) {
345 mv = &rsv->mv;
346 if (bitmap_intersects(rsv->mas.bm, conflicting_mas->bm, UWB_NUM_MAS)) {
347 handle_conflict_expanding(drp_ie, drp_evt->beacon_slot_number,
348 rsv, false, conflicting_mas);
349 } else {
350 if (bitmap_intersects(mv->companion_mas.bm, conflicting_mas->bm, UWB_NUM_MAS)) {
351 handle_conflict_expanding(drp_ie, drp_evt->beacon_slot_number,
352 rsv, true, conflicting_mas);
353 }
354 }
355 } else if (bitmap_intersects(rsv->mas.bm, conflicting_mas->bm, UWB_NUM_MAS)) {
356 handle_conflict_normal(drp_ie, drp_evt->beacon_slot_number, rsv, conflicting_mas);
146 } 357 }
147 uwb_rsv_remove(rsv);
148} 358}
149 359
360static void uwb_drp_handle_all_conflict_rsv(struct uwb_rc *rc,
361 struct uwb_rc_evt_drp *drp_evt,
362 struct uwb_ie_drp *drp_ie,
363 struct uwb_mas_bm *conflicting_mas)
364{
365 struct uwb_rsv *rsv;
366
367 list_for_each_entry(rsv, &rc->reservations, rc_node) {
368 uwb_drp_handle_conflict_rsv(rc, rsv, drp_evt, drp_ie, conflicting_mas);
369 }
370}
371
150/* 372/*
151 * Based on the DRP IE, transition a target reservation to a new 373 * Based on the DRP IE, transition a target reservation to a new
152 * state. 374 * state.
153 */ 375 */
154static void uwb_drp_process_target(struct uwb_rc *rc, struct uwb_rsv *rsv, 376static void uwb_drp_process_target(struct uwb_rc *rc, struct uwb_rsv *rsv,
155 struct uwb_ie_drp *drp_ie) 377 struct uwb_ie_drp *drp_ie, struct uwb_rc_evt_drp *drp_evt)
156{ 378{
157 struct device *dev = &rc->uwb_dev.dev; 379 struct device *dev = &rc->uwb_dev.dev;
380 struct uwb_rsv_move *mv = &rsv->mv;
158 int status; 381 int status;
159 enum uwb_drp_reason reason_code; 382 enum uwb_drp_reason reason_code;
160 383 struct uwb_mas_bm mas;
384
161 status = uwb_ie_drp_status(drp_ie); 385 status = uwb_ie_drp_status(drp_ie);
162 reason_code = uwb_ie_drp_reason_code(drp_ie); 386 reason_code = uwb_ie_drp_reason_code(drp_ie);
387 uwb_drp_ie_to_bm(&mas, drp_ie);
163 388
164 if (status) { 389 switch (reason_code) {
165 switch (reason_code) { 390 case UWB_DRP_REASON_ACCEPTED:
166 case UWB_DRP_REASON_ACCEPTED: 391
167 uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_ACCEPTED); 392 if (rsv->state == UWB_RSV_STATE_T_CONFLICT) {
168 break; 393 uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_CONFLICT);
169 case UWB_DRP_REASON_MODIFIED:
170 dev_err(dev, "FIXME: unhandled reason code (%d/%d)\n",
171 reason_code, status);
172 break; 394 break;
173 default:
174 dev_warn(dev, "ignoring invalid DRP IE state (%d/%d)\n",
175 reason_code, status);
176 } 395 }
177 } else { 396
178 switch (reason_code) { 397 if (rsv->state == UWB_RSV_STATE_T_EXPANDING_ACCEPTED) {
179 case UWB_DRP_REASON_ACCEPTED: 398 /* drp_ie is companion */
180 /* New reservations are handled in uwb_rsv_find(). */ 399 if (!bitmap_equal(rsv->mas.bm, mas.bm, UWB_NUM_MAS))
181 break; 400 /* stroke companion */
182 case UWB_DRP_REASON_DENIED: 401 uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_EXPANDING_ACCEPTED);
183 uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE); 402 } else {
184 break; 403 if (!bitmap_equal(rsv->mas.bm, mas.bm, UWB_NUM_MAS)) {
185 case UWB_DRP_REASON_CONFLICT: 404 if (uwb_drp_avail_reserve_pending(rc, &mas) == -EBUSY) {
186 case UWB_DRP_REASON_MODIFIED: 405 /* FIXME: there is a conflict, find
187 dev_err(dev, "FIXME: unhandled reason code (%d/%d)\n", 406 * the conflicting reservations and
188 reason_code, status); 407 * take a sensible action. Consider
408 * that in drp_ie there is the
409 * "neighbour" */
410 uwb_drp_handle_all_conflict_rsv(rc, drp_evt, drp_ie, &mas);
411 } else {
412 /* accept the extra reservation */
413 bitmap_copy(mv->companion_mas.bm, mas.bm, UWB_NUM_MAS);
414 uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_EXPANDING_ACCEPTED);
415 }
416 } else {
417 if (status) {
418 uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_ACCEPTED);
419 }
420 }
421
422 }
423 break;
424
425 case UWB_DRP_REASON_MODIFIED:
426 /* check to see if we have already modified the reservation */
427 if (bitmap_equal(rsv->mas.bm, mas.bm, UWB_NUM_MAS)) {
428 uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_ACCEPTED);
189 break; 429 break;
190 default:
191 dev_warn(dev, "ignoring invalid DRP IE state (%d/%d)\n",
192 reason_code, status);
193 } 430 }
431
432 /* find if the owner wants to expand or reduce */
433 if (bitmap_subset(mas.bm, rsv->mas.bm, UWB_NUM_MAS)) {
434 /* owner is reducing */
435 bitmap_andnot(mv->companion_mas.bm, rsv->mas.bm, mas.bm, UWB_NUM_MAS);
436 uwb_drp_avail_release(rsv->rc, &mv->companion_mas);
437 }
438
439 bitmap_copy(rsv->mas.bm, mas.bm, UWB_NUM_MAS);
440 uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_RESIZED);
441 break;
442 default:
443 dev_warn(dev, "ignoring invalid DRP IE state (%d/%d)\n",
444 reason_code, status);
194 } 445 }
195} 446}
196 447
@@ -199,23 +450,60 @@ static void uwb_drp_process_target(struct uwb_rc *rc, struct uwb_rsv *rsv,
199 * state. 450 * state.
200 */ 451 */
201static void uwb_drp_process_owner(struct uwb_rc *rc, struct uwb_rsv *rsv, 452static void uwb_drp_process_owner(struct uwb_rc *rc, struct uwb_rsv *rsv,
202 struct uwb_ie_drp *drp_ie) 453 struct uwb_dev *src, struct uwb_ie_drp *drp_ie,
454 struct uwb_rc_evt_drp *drp_evt)
203{ 455{
204 struct device *dev = &rc->uwb_dev.dev; 456 struct device *dev = &rc->uwb_dev.dev;
457 struct uwb_rsv_move *mv = &rsv->mv;
205 int status; 458 int status;
206 enum uwb_drp_reason reason_code; 459 enum uwb_drp_reason reason_code;
460 struct uwb_mas_bm mas;
207 461
208 status = uwb_ie_drp_status(drp_ie); 462 status = uwb_ie_drp_status(drp_ie);
209 reason_code = uwb_ie_drp_reason_code(drp_ie); 463 reason_code = uwb_ie_drp_reason_code(drp_ie);
464 uwb_drp_ie_to_bm(&mas, drp_ie);
210 465
211 if (status) { 466 if (status) {
212 switch (reason_code) { 467 switch (reason_code) {
213 case UWB_DRP_REASON_ACCEPTED: 468 case UWB_DRP_REASON_ACCEPTED:
214 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_ESTABLISHED); 469 switch (rsv->state) {
215 break; 470 case UWB_RSV_STATE_O_PENDING:
216 case UWB_DRP_REASON_MODIFIED: 471 case UWB_RSV_STATE_O_INITIATED:
217 dev_err(dev, "FIXME: unhandled reason code (%d/%d)\n", 472 case UWB_RSV_STATE_O_ESTABLISHED:
218 reason_code, status); 473 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_ESTABLISHED);
474 break;
475 case UWB_RSV_STATE_O_MODIFIED:
476 if (bitmap_equal(mas.bm, rsv->mas.bm, UWB_NUM_MAS)) {
477 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_ESTABLISHED);
478 } else {
479 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MODIFIED);
480 }
481 break;
482
483 case UWB_RSV_STATE_O_MOVE_REDUCING: /* shouldn' t be a problem */
484 if (bitmap_equal(mas.bm, rsv->mas.bm, UWB_NUM_MAS)) {
485 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_ESTABLISHED);
486 } else {
487 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MOVE_REDUCING);
488 }
489 break;
490 case UWB_RSV_STATE_O_MOVE_EXPANDING:
491 if (bitmap_equal(mas.bm, mv->companion_mas.bm, UWB_NUM_MAS)) {
492 /* Companion reservation accepted */
493 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MOVE_COMBINING);
494 } else {
495 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MOVE_EXPANDING);
496 }
497 break;
498 case UWB_RSV_STATE_O_MOVE_COMBINING:
499 if (bitmap_equal(mas.bm, rsv->mas.bm, UWB_NUM_MAS))
500 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MOVE_REDUCING);
501 else
502 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MOVE_COMBINING);
503 break;
504 default:
505 break;
506 }
219 break; 507 break;
220 default: 508 default:
221 dev_warn(dev, "ignoring invalid DRP IE state (%d/%d)\n", 509 dev_warn(dev, "ignoring invalid DRP IE state (%d/%d)\n",
@@ -230,9 +518,10 @@ static void uwb_drp_process_owner(struct uwb_rc *rc, struct uwb_rsv *rsv,
230 uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE); 518 uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE);
231 break; 519 break;
232 case UWB_DRP_REASON_CONFLICT: 520 case UWB_DRP_REASON_CONFLICT:
233 case UWB_DRP_REASON_MODIFIED: 521 /* resolve the conflict */
234 dev_err(dev, "FIXME: unhandled reason code (%d/%d)\n", 522 bitmap_complement(mas.bm, src->last_availability_bm,
235 reason_code, status); 523 UWB_NUM_MAS);
524 uwb_drp_handle_conflict_rsv(rc, rsv, drp_evt, drp_ie, &mas);
236 break; 525 break;
237 default: 526 default:
238 dev_warn(dev, "ignoring invalid DRP IE state (%d/%d)\n", 527 dev_warn(dev, "ignoring invalid DRP IE state (%d/%d)\n",
@@ -241,12 +530,110 @@ static void uwb_drp_process_owner(struct uwb_rc *rc, struct uwb_rsv *rsv,
241 } 530 }
242} 531}
243 532
533static void uwb_cnflt_alien_stroke_timer(struct uwb_cnflt_alien *cnflt)
534{
535 unsigned timeout_us = UWB_MAX_LOST_BEACONS * UWB_SUPERFRAME_LENGTH_US;
536 mod_timer(&cnflt->timer, jiffies + usecs_to_jiffies(timeout_us));
537}
538
539static void uwb_cnflt_update_work(struct work_struct *work)
540{
541 struct uwb_cnflt_alien *cnflt = container_of(work,
542 struct uwb_cnflt_alien,
543 cnflt_update_work);
544 struct uwb_cnflt_alien *c;
545 struct uwb_rc *rc = cnflt->rc;
546
547 unsigned long delay_us = UWB_MAS_LENGTH_US * UWB_MAS_PER_ZONE;
548
549 mutex_lock(&rc->rsvs_mutex);
550
551 list_del(&cnflt->rc_node);
552
553 /* update rc global conflicting alien bitmap */
554 bitmap_zero(rc->cnflt_alien_bitmap.bm, UWB_NUM_MAS);
555
556 list_for_each_entry(c, &rc->cnflt_alien_list, rc_node) {
557 bitmap_or(rc->cnflt_alien_bitmap.bm, rc->cnflt_alien_bitmap.bm, c->mas.bm, UWB_NUM_MAS);
558 }
559
560 queue_delayed_work(rc->rsv_workq, &rc->rsv_alien_bp_work, usecs_to_jiffies(delay_us));
561
562 kfree(cnflt);
563 mutex_unlock(&rc->rsvs_mutex);
564}
565
566static void uwb_cnflt_timer(unsigned long arg)
567{
568 struct uwb_cnflt_alien *cnflt = (struct uwb_cnflt_alien *)arg;
569
570 queue_work(cnflt->rc->rsv_workq, &cnflt->cnflt_update_work);
571}
572
244/* 573/*
245 * Process a received DRP IE, it's either for a reservation owned by 574 * We have received an DRP_IE of type Alien BP and we need to make
246 * the RC or targeted at it (or it's for a WUSB cluster reservation). 575 * sure we do not transmit in conflicting MASs.
247 */ 576 */
248static void uwb_drp_process(struct uwb_rc *rc, struct uwb_dev *src, 577static void uwb_drp_handle_alien_drp(struct uwb_rc *rc, struct uwb_ie_drp *drp_ie)
249 struct uwb_ie_drp *drp_ie) 578{
579 struct device *dev = &rc->uwb_dev.dev;
580 struct uwb_mas_bm mas;
581 struct uwb_cnflt_alien *cnflt;
582 char buf[72];
583 unsigned long delay_us = UWB_MAS_LENGTH_US * UWB_MAS_PER_ZONE;
584
585 uwb_drp_ie_to_bm(&mas, drp_ie);
586 bitmap_scnprintf(buf, sizeof(buf), mas.bm, UWB_NUM_MAS);
587
588 list_for_each_entry(cnflt, &rc->cnflt_alien_list, rc_node) {
589 if (bitmap_equal(cnflt->mas.bm, mas.bm, UWB_NUM_MAS)) {
590 /* Existing alien BP reservation conflicting
591 * bitmap, just reset the timer */
592 uwb_cnflt_alien_stroke_timer(cnflt);
593 return;
594 }
595 }
596
597 /* New alien BP reservation conflicting bitmap */
598
599 /* alloc and initialize new uwb_cnflt_alien */
600 cnflt = kzalloc(sizeof(struct uwb_cnflt_alien), GFP_KERNEL);
601 if (!cnflt)
602 dev_err(dev, "failed to alloc uwb_cnflt_alien struct\n");
603 INIT_LIST_HEAD(&cnflt->rc_node);
604 init_timer(&cnflt->timer);
605 cnflt->timer.function = uwb_cnflt_timer;
606 cnflt->timer.data = (unsigned long)cnflt;
607
608 cnflt->rc = rc;
609 INIT_WORK(&cnflt->cnflt_update_work, uwb_cnflt_update_work);
610
611 bitmap_copy(cnflt->mas.bm, mas.bm, UWB_NUM_MAS);
612
613 list_add_tail(&cnflt->rc_node, &rc->cnflt_alien_list);
614
615 /* update rc global conflicting alien bitmap */
616 bitmap_or(rc->cnflt_alien_bitmap.bm, rc->cnflt_alien_bitmap.bm, mas.bm, UWB_NUM_MAS);
617
618 queue_delayed_work(rc->rsv_workq, &rc->rsv_alien_bp_work, usecs_to_jiffies(delay_us));
619
620 /* start the timer */
621 uwb_cnflt_alien_stroke_timer(cnflt);
622}
623
624static void uwb_drp_process_not_involved(struct uwb_rc *rc,
625 struct uwb_rc_evt_drp *drp_evt,
626 struct uwb_ie_drp *drp_ie)
627{
628 struct uwb_mas_bm mas;
629
630 uwb_drp_ie_to_bm(&mas, drp_ie);
631 uwb_drp_handle_all_conflict_rsv(rc, drp_evt, drp_ie, &mas);
632}
633
634static void uwb_drp_process_involved(struct uwb_rc *rc, struct uwb_dev *src,
635 struct uwb_rc_evt_drp *drp_evt,
636 struct uwb_ie_drp *drp_ie)
250{ 637{
251 struct uwb_rsv *rsv; 638 struct uwb_rsv *rsv;
252 639
@@ -259,7 +646,7 @@ static void uwb_drp_process(struct uwb_rc *rc, struct uwb_dev *src,
259 */ 646 */
260 return; 647 return;
261 } 648 }
262 649
263 /* 650 /*
264 * Do nothing with DRP IEs for reservations that have been 651 * Do nothing with DRP IEs for reservations that have been
265 * terminated. 652 * terminated.
@@ -268,13 +655,43 @@ static void uwb_drp_process(struct uwb_rc *rc, struct uwb_dev *src,
268 uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE); 655 uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE);
269 return; 656 return;
270 } 657 }
271 658
272 if (uwb_ie_drp_owner(drp_ie)) 659 if (uwb_ie_drp_owner(drp_ie))
273 uwb_drp_process_target(rc, rsv, drp_ie); 660 uwb_drp_process_target(rc, rsv, drp_ie, drp_evt);
661 else
662 uwb_drp_process_owner(rc, rsv, src, drp_ie, drp_evt);
663
664}
665
666
667static bool uwb_drp_involves_us(struct uwb_rc *rc, struct uwb_ie_drp *drp_ie)
668{
669 return uwb_dev_addr_cmp(&rc->uwb_dev.dev_addr, &drp_ie->dev_addr) == 0;
670}
671
672/*
673 * Process a received DRP IE.
674 */
675static void uwb_drp_process(struct uwb_rc *rc, struct uwb_rc_evt_drp *drp_evt,
676 struct uwb_dev *src, struct uwb_ie_drp *drp_ie)
677{
678 if (uwb_ie_drp_type(drp_ie) == UWB_DRP_TYPE_ALIEN_BP)
679 uwb_drp_handle_alien_drp(rc, drp_ie);
680 else if (uwb_drp_involves_us(rc, drp_ie))
681 uwb_drp_process_involved(rc, src, drp_evt, drp_ie);
274 else 682 else
275 uwb_drp_process_owner(rc, rsv, drp_ie); 683 uwb_drp_process_not_involved(rc, drp_evt, drp_ie);
276} 684}
277 685
686/*
687 * Process a received DRP Availability IE
688 */
689static void uwb_drp_availability_process(struct uwb_rc *rc, struct uwb_dev *src,
690 struct uwb_ie_drp_avail *drp_availability_ie)
691{
692 bitmap_copy(src->last_availability_bm,
693 drp_availability_ie->bmp, UWB_NUM_MAS);
694}
278 695
279/* 696/*
280 * Process all the DRP IEs (both DRP IEs and the DRP Availability IE) 697 * Process all the DRP IEs (both DRP IEs and the DRP Availability IE)
@@ -296,10 +713,10 @@ void uwb_drp_process_all(struct uwb_rc *rc, struct uwb_rc_evt_drp *drp_evt,
296 713
297 switch (ie_hdr->element_id) { 714 switch (ie_hdr->element_id) {
298 case UWB_IE_DRP_AVAILABILITY: 715 case UWB_IE_DRP_AVAILABILITY:
299 /* FIXME: does something need to be done with this? */ 716 uwb_drp_availability_process(rc, src_dev, (struct uwb_ie_drp_avail *)ie_hdr);
300 break; 717 break;
301 case UWB_IE_DRP: 718 case UWB_IE_DRP:
302 uwb_drp_process(rc, src_dev, (struct uwb_ie_drp *)ie_hdr); 719 uwb_drp_process(rc, drp_evt, src_dev, (struct uwb_ie_drp *)ie_hdr);
303 break; 720 break;
304 default: 721 default:
305 dev_warn(dev, "unexpected IE in DRP notification\n"); 722 dev_warn(dev, "unexpected IE in DRP notification\n");
@@ -312,55 +729,6 @@ void uwb_drp_process_all(struct uwb_rc *rc, struct uwb_rc_evt_drp *drp_evt,
312 (int)ielen); 729 (int)ielen);
313} 730}
314 731
315
316/*
317 * Go through all the DRP IEs and find the ones that conflict with our
318 * reservations.
319 *
320 * FIXME: must resolve the conflict according the the rules in
321 * [ECMA-368].
322 */
323static
324void uwb_drp_process_conflict_all(struct uwb_rc *rc, struct uwb_rc_evt_drp *drp_evt,
325 size_t ielen, struct uwb_dev *src_dev)
326{
327 struct device *dev = &rc->uwb_dev.dev;
328 struct uwb_ie_hdr *ie_hdr;
329 struct uwb_ie_drp *drp_ie;
330 void *ptr;
331
332 ptr = drp_evt->ie_data;
333 for (;;) {
334 ie_hdr = uwb_ie_next(&ptr, &ielen);
335 if (!ie_hdr)
336 break;
337
338 drp_ie = container_of(ie_hdr, struct uwb_ie_drp, hdr);
339
340 /* FIXME: check if this DRP IE conflicts. */
341 }
342
343 if (ielen > 0)
344 dev_warn(dev, "%d octets remaining in DRP notification\n",
345 (int)ielen);
346}
347
348
349/*
350 * Terminate all reservations owned by, or targeted at, 'uwb_dev'.
351 */
352static void uwb_drp_terminate_all(struct uwb_rc *rc, struct uwb_dev *uwb_dev)
353{
354 struct uwb_rsv *rsv;
355
356 list_for_each_entry(rsv, &rc->reservations, rc_node) {
357 if (rsv->owner == uwb_dev
358 || (rsv->target.type == UWB_RSV_TARGET_DEV && rsv->target.dev == uwb_dev))
359 uwb_rsv_remove(rsv);
360 }
361}
362
363
364/** 732/**
365 * uwbd_evt_handle_rc_drp - handle a DRP_IE event 733 * uwbd_evt_handle_rc_drp - handle a DRP_IE event
366 * @evt: the DRP_IE event from the radio controller 734 * @evt: the DRP_IE event from the radio controller
@@ -401,7 +769,6 @@ int uwbd_evt_handle_rc_drp(struct uwb_event *evt)
401 size_t ielength, bytes_left; 769 size_t ielength, bytes_left;
402 struct uwb_dev_addr src_addr; 770 struct uwb_dev_addr src_addr;
403 struct uwb_dev *src_dev; 771 struct uwb_dev *src_dev;
404 int reason;
405 772
406 /* Is there enough data to decode the event (and any IEs in 773 /* Is there enough data to decode the event (and any IEs in
407 its payload)? */ 774 its payload)? */
@@ -437,22 +804,8 @@ int uwbd_evt_handle_rc_drp(struct uwb_event *evt)
437 804
438 mutex_lock(&rc->rsvs_mutex); 805 mutex_lock(&rc->rsvs_mutex);
439 806
440 reason = uwb_rc_evt_drp_reason(drp_evt); 807 /* We do not distinguish from the reason */
441 808 uwb_drp_process_all(rc, drp_evt, ielength, src_dev);
442 switch (reason) {
443 case UWB_DRP_NOTIF_DRP_IE_RCVD:
444 uwb_drp_process_all(rc, drp_evt, ielength, src_dev);
445 break;
446 case UWB_DRP_NOTIF_CONFLICT:
447 uwb_drp_process_conflict_all(rc, drp_evt, ielength, src_dev);
448 break;
449 case UWB_DRP_NOTIF_TERMINATE:
450 uwb_drp_terminate_all(rc, src_dev);
451 break;
452 default:
453 dev_warn(dev, "ignored DRP event with reason code: %d\n", reason);
454 break;
455 }
456 809
457 mutex_unlock(&rc->rsvs_mutex); 810 mutex_unlock(&rc->rsvs_mutex);
458 811
diff --git a/drivers/uwb/est.c b/drivers/uwb/est.c
index 5fe566b7c845..328fcc2b6099 100644
--- a/drivers/uwb/est.c
+++ b/drivers/uwb/est.c
@@ -40,10 +40,8 @@
40 * uwb_est_get_size() 40 * uwb_est_get_size()
41 */ 41 */
42#include <linux/spinlock.h> 42#include <linux/spinlock.h>
43#define D_LOCAL 0
44#include <linux/uwb/debug.h>
45#include "uwb-internal.h"
46 43
44#include "uwb-internal.h"
47 45
48struct uwb_est { 46struct uwb_est {
49 u16 type_event_high; 47 u16 type_event_high;
@@ -52,7 +50,6 @@ struct uwb_est {
52 const struct uwb_est_entry *entry; 50 const struct uwb_est_entry *entry;
53}; 51};
54 52
55
56static struct uwb_est *uwb_est; 53static struct uwb_est *uwb_est;
57static u8 uwb_est_size; 54static u8 uwb_est_size;
58static u8 uwb_est_used; 55static u8 uwb_est_used;
@@ -440,21 +437,12 @@ ssize_t uwb_est_find_size(struct uwb_rc *rc, const struct uwb_rceb *rceb,
440 u8 *ptr = (u8 *) rceb; 437 u8 *ptr = (u8 *) rceb;
441 438
442 read_lock_irqsave(&uwb_est_lock, flags); 439 read_lock_irqsave(&uwb_est_lock, flags);
443 d_printf(2, dev, "Size query for event 0x%02x/%04x/%02x,"
444 " buffer size %ld\n",
445 (unsigned) rceb->bEventType,
446 (unsigned) le16_to_cpu(rceb->wEvent),
447 (unsigned) rceb->bEventContext,
448 (long) rceb_size);
449 size = -ENOSPC; 440 size = -ENOSPC;
450 if (rceb_size < sizeof(*rceb)) 441 if (rceb_size < sizeof(*rceb))
451 goto out; 442 goto out;
452 event = le16_to_cpu(rceb->wEvent); 443 event = le16_to_cpu(rceb->wEvent);
453 type_event_high = rceb->bEventType << 8 | (event & 0xff00) >> 8; 444 type_event_high = rceb->bEventType << 8 | (event & 0xff00) >> 8;
454 for (itr = 0; itr < uwb_est_used; itr++) { 445 for (itr = 0; itr < uwb_est_used; itr++) {
455 d_printf(3, dev, "Checking EST 0x%04x/%04x/%04x\n",
456 uwb_est[itr].type_event_high, uwb_est[itr].vendor,
457 uwb_est[itr].product);
458 if (uwb_est[itr].type_event_high != type_event_high) 446 if (uwb_est[itr].type_event_high != type_event_high)
459 continue; 447 continue;
460 size = uwb_est_get_size(rc, &uwb_est[itr], 448 size = uwb_est_get_size(rc, &uwb_est[itr],
diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c
index 3d26fa0f8ae1..559f8784acf3 100644
--- a/drivers/uwb/hwa-rc.c
+++ b/drivers/uwb/hwa-rc.c
@@ -51,16 +51,14 @@
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>
58#include <linux/usb/wusb.h> 57#include <linux/usb/wusb.h>
59#include <linux/usb/wusb-wa.h> 58#include <linux/usb/wusb-wa.h>
60#include <linux/uwb.h> 59#include <linux/uwb.h>
60
61#include "uwb-internal.h" 61#include "uwb-internal.h"
62#define D_LOCAL 1
63#include <linux/uwb/debug.h>
64 62
65/* The device uses commands and events from the WHCI specification, although 63/* The device uses commands and events from the WHCI specification, although
66 * reporting itself as WUSB compliant. */ 64 * reporting itself as WUSB compliant. */
@@ -631,17 +629,13 @@ void hwarc_neep_cb(struct urb *urb)
631 629
632 switch (result = urb->status) { 630 switch (result = urb->status) {
633 case 0: 631 case 0:
634 d_printf(3, dev, "NEEP: receive stat %d, %zu bytes\n",
635 urb->status, (size_t)urb->actual_length);
636 uwb_rc_neh_grok(hwarc->uwb_rc, urb->transfer_buffer, 632 uwb_rc_neh_grok(hwarc->uwb_rc, urb->transfer_buffer,
637 urb->actual_length); 633 urb->actual_length);
638 break; 634 break;
639 case -ECONNRESET: /* Not an error, but a controlled situation; */ 635 case -ECONNRESET: /* Not an error, but a controlled situation; */
640 case -ENOENT: /* (we killed the URB)...so, no broadcast */ 636 case -ENOENT: /* (we killed the URB)...so, no broadcast */
641 d_printf(2, dev, "NEEP: URB reset/noent %d\n", urb->status);
642 goto out; 637 goto out;
643 case -ESHUTDOWN: /* going away! */ 638 case -ESHUTDOWN: /* going away! */
644 d_printf(2, dev, "NEEP: URB down %d\n", urb->status);
645 goto out; 639 goto out;
646 default: /* On general errors, retry unless it gets ugly */ 640 default: /* On general errors, retry unless it gets ugly */
647 if (edc_inc(&hwarc->neep_edc, EDC_MAX_ERRORS, 641 if (edc_inc(&hwarc->neep_edc, EDC_MAX_ERRORS,
@@ -650,7 +644,6 @@ void hwarc_neep_cb(struct urb *urb)
650 dev_err(dev, "NEEP: URB error %d\n", urb->status); 644 dev_err(dev, "NEEP: URB error %d\n", urb->status);
651 } 645 }
652 result = usb_submit_urb(urb, GFP_ATOMIC); 646 result = usb_submit_urb(urb, GFP_ATOMIC);
653 d_printf(3, dev, "NEEP: submit %d\n", result);
654 if (result < 0) { 647 if (result < 0) {
655 dev_err(dev, "NEEP: Can't resubmit URB (%d) resetting device\n", 648 dev_err(dev, "NEEP: Can't resubmit URB (%d) resetting device\n",
656 result); 649 result);
@@ -759,11 +752,11 @@ static int hwarc_get_version(struct uwb_rc *rc)
759 itr_size = le16_to_cpu(usb_dev->actconfig->desc.wTotalLength); 752 itr_size = le16_to_cpu(usb_dev->actconfig->desc.wTotalLength);
760 while (itr_size >= sizeof(*hdr)) { 753 while (itr_size >= sizeof(*hdr)) {
761 hdr = (struct usb_descriptor_header *) itr; 754 hdr = (struct usb_descriptor_header *) itr;
762 d_printf(3, dev, "Extra device descriptor: " 755 dev_dbg(dev, "Extra device descriptor: "
763 "type %02x/%u bytes @ %zu (%zu left)\n", 756 "type %02x/%u bytes @ %zu (%zu left)\n",
764 hdr->bDescriptorType, hdr->bLength, 757 hdr->bDescriptorType, hdr->bLength,
765 (itr - usb_dev->rawdescriptors[actconfig_idx]), 758 (itr - usb_dev->rawdescriptors[actconfig_idx]),
766 itr_size); 759 itr_size);
767 if (hdr->bDescriptorType == USB_DT_CS_RADIO_CONTROL) 760 if (hdr->bDescriptorType == USB_DT_CS_RADIO_CONTROL)
768 goto found; 761 goto found;
769 itr += hdr->bLength; 762 itr += hdr->bLength;
@@ -795,8 +788,7 @@ found:
795 goto error; 788 goto error;
796 } 789 }
797 rc->version = version; 790 rc->version = version;
798 d_printf(3, dev, "Device supports WUSB protocol version 0x%04x \n", 791 dev_dbg(dev, "Device supports WUSB protocol version 0x%04x \n", rc->version);
799 rc->version);
800 result = 0; 792 result = 0;
801error: 793error:
802 return result; 794 return result;
@@ -877,11 +869,28 @@ static void hwarc_disconnect(struct usb_interface *iface)
877 uwb_rc_rm(uwb_rc); 869 uwb_rc_rm(uwb_rc);
878 usb_put_intf(hwarc->usb_iface); 870 usb_put_intf(hwarc->usb_iface);
879 usb_put_dev(hwarc->usb_dev); 871 usb_put_dev(hwarc->usb_dev);
880 d_printf(1, &hwarc->usb_iface->dev, "freed hwarc %p\n", hwarc);
881 kfree(hwarc); 872 kfree(hwarc);
882 uwb_rc_put(uwb_rc); /* when creating the device, refcount = 1 */ 873 uwb_rc_put(uwb_rc); /* when creating the device, refcount = 1 */
883} 874}
884 875
876static int hwarc_pre_reset(struct usb_interface *iface)
877{
878 struct hwarc *hwarc = usb_get_intfdata(iface);
879 struct uwb_rc *uwb_rc = hwarc->uwb_rc;
880
881 uwb_rc_pre_reset(uwb_rc);
882 return 0;
883}
884
885static int hwarc_post_reset(struct usb_interface *iface)
886{
887 struct hwarc *hwarc = usb_get_intfdata(iface);
888 struct uwb_rc *uwb_rc = hwarc->uwb_rc;
889
890 uwb_rc_post_reset(uwb_rc);
891 return 0;
892}
893
885/** USB device ID's that we handle */ 894/** USB device ID's that we handle */
886static struct usb_device_id hwarc_id_table[] = { 895static struct usb_device_id hwarc_id_table[] = {
887 /* D-Link DUB-1210 */ 896 /* D-Link DUB-1210 */
@@ -898,20 +907,16 @@ MODULE_DEVICE_TABLE(usb, hwarc_id_table);
898 907
899static struct usb_driver hwarc_driver = { 908static struct usb_driver hwarc_driver = {
900 .name = "hwa-rc", 909 .name = "hwa-rc",
910 .id_table = hwarc_id_table,
901 .probe = hwarc_probe, 911 .probe = hwarc_probe,
902 .disconnect = hwarc_disconnect, 912 .disconnect = hwarc_disconnect,
903 .id_table = hwarc_id_table, 913 .pre_reset = hwarc_pre_reset,
914 .post_reset = hwarc_post_reset,
904}; 915};
905 916
906static int __init hwarc_driver_init(void) 917static int __init hwarc_driver_init(void)
907{ 918{
908 int result; 919 return usb_register(&hwarc_driver);
909 result = usb_register(&hwarc_driver);
910 if (result < 0)
911 printk(KERN_ERR "HWA-RC: Cannot register USB driver: %d\n",
912 result);
913 return result;
914
915} 920}
916module_init(hwarc_driver_init); 921module_init(hwarc_driver_init);
917 922
diff --git a/drivers/uwb/i1480/dfu/dfu.c b/drivers/uwb/i1480/dfu/dfu.c
index 9097b3b30385..da7b1d08003c 100644
--- a/drivers/uwb/i1480/dfu/dfu.c
+++ b/drivers/uwb/i1480/dfu/dfu.c
@@ -34,10 +34,7 @@
34#include <linux/uwb.h> 34#include <linux/uwb.h>
35#include <linux/random.h> 35#include <linux/random.h>
36 36
37#define D_LOCAL 0 37/*
38#include <linux/uwb/debug.h>
39
40/**
41 * i1480_rceb_check - Check RCEB for expected field values 38 * i1480_rceb_check - Check RCEB for expected field values
42 * @i1480: pointer to device for which RCEB is being checked 39 * @i1480: pointer to device for which RCEB is being checked
43 * @rceb: RCEB being checked 40 * @rceb: RCEB being checked
@@ -83,7 +80,7 @@ int i1480_rceb_check(const struct i1480 *i1480, const struct uwb_rceb *rceb,
83EXPORT_SYMBOL_GPL(i1480_rceb_check); 80EXPORT_SYMBOL_GPL(i1480_rceb_check);
84 81
85 82
86/** 83/*
87 * Execute a Radio Control Command 84 * Execute a Radio Control Command
88 * 85 *
89 * Command data has to be in i1480->cmd_buf. 86 * Command data has to be in i1480->cmd_buf.
@@ -101,7 +98,6 @@ ssize_t i1480_cmd(struct i1480 *i1480, const char *cmd_name, size_t cmd_size,
101 u8 expected_type = reply->bEventType; 98 u8 expected_type = reply->bEventType;
102 u8 context; 99 u8 context;
103 100
104 d_fnstart(3, i1480->dev, "(%p, %s, %zu)\n", i1480, cmd_name, cmd_size);
105 init_completion(&i1480->evt_complete); 101 init_completion(&i1480->evt_complete);
106 i1480->evt_result = -EINPROGRESS; 102 i1480->evt_result = -EINPROGRESS;
107 do { 103 do {
@@ -150,8 +146,6 @@ ssize_t i1480_cmd(struct i1480 *i1480, const char *cmd_name, size_t cmd_size,
150 result = i1480_rceb_check(i1480, i1480->evt_buf, cmd_name, context, 146 result = i1480_rceb_check(i1480, i1480->evt_buf, cmd_name, context,
151 expected_type, expected_event); 147 expected_type, expected_event);
152error: 148error:
153 d_fnend(3, i1480->dev, "(%p, %s, %zu) = %zd\n",
154 i1480, cmd_name, cmd_size, result);
155 return result; 149 return result;
156} 150}
157EXPORT_SYMBOL_GPL(i1480_cmd); 151EXPORT_SYMBOL_GPL(i1480_cmd);
diff --git a/drivers/uwb/i1480/dfu/mac.c b/drivers/uwb/i1480/dfu/mac.c
index 2e4d8f07c165..694d0daf88ab 100644
--- a/drivers/uwb/i1480/dfu/mac.c
+++ b/drivers/uwb/i1480/dfu/mac.c
@@ -31,9 +31,6 @@
31#include <linux/uwb.h> 31#include <linux/uwb.h>
32#include "i1480-dfu.h" 32#include "i1480-dfu.h"
33 33
34#define D_LOCAL 0
35#include <linux/uwb/debug.h>
36
37/* 34/*
38 * Descriptor for a continuous segment of MAC fw data 35 * Descriptor for a continuous segment of MAC fw data
39 */ 36 */
@@ -184,10 +181,6 @@ ssize_t i1480_fw_cmp(struct i1480 *i1480, struct fw_hdr *hdr)
184 } 181 }
185 if (memcmp(i1480->cmd_buf, bin + src_itr, result)) { 182 if (memcmp(i1480->cmd_buf, bin + src_itr, result)) {
186 u8 *buf = i1480->cmd_buf; 183 u8 *buf = i1480->cmd_buf;
187 d_printf(2, i1480->dev,
188 "original data @ %p + %u, %zu bytes\n",
189 bin, src_itr, result);
190 d_dump(4, i1480->dev, bin + src_itr, result);
191 for (cnt = 0; cnt < result; cnt++) 184 for (cnt = 0; cnt < result; cnt++)
192 if (bin[src_itr + cnt] != buf[cnt]) { 185 if (bin[src_itr + cnt] != buf[cnt]) {
193 dev_err(i1480->dev, "byte failed at " 186 dev_err(i1480->dev, "byte failed at "
@@ -224,7 +217,6 @@ int mac_fw_hdrs_push(struct i1480 *i1480, struct fw_hdr *hdr,
224 struct fw_hdr *hdr_itr; 217 struct fw_hdr *hdr_itr;
225 int verif_retry_count; 218 int verif_retry_count;
226 219
227 d_fnstart(3, dev, "(%p, %p)\n", i1480, hdr);
228 /* Now, header by header, push them to the hw */ 220 /* Now, header by header, push them to the hw */
229 for (hdr_itr = hdr; hdr_itr != NULL; hdr_itr = hdr_itr->next) { 221 for (hdr_itr = hdr; hdr_itr != NULL; hdr_itr = hdr_itr->next) {
230 verif_retry_count = 0; 222 verif_retry_count = 0;
@@ -264,7 +256,6 @@ retry:
264 break; 256 break;
265 } 257 }
266 } 258 }
267 d_fnend(3, dev, "(%zd)\n", result);
268 return result; 259 return result;
269} 260}
270 261
@@ -337,11 +328,9 @@ int __mac_fw_upload(struct i1480 *i1480, const char *fw_name,
337 const struct firmware *fw; 328 const struct firmware *fw;
338 struct fw_hdr *fw_hdrs; 329 struct fw_hdr *fw_hdrs;
339 330
340 d_fnstart(3, i1480->dev, "(%p, %s, %s)\n", i1480, fw_name, fw_tag);
341 result = request_firmware(&fw, fw_name, i1480->dev); 331 result = request_firmware(&fw, fw_name, i1480->dev);
342 if (result < 0) /* Up to caller to complain on -ENOENT */ 332 if (result < 0) /* Up to caller to complain on -ENOENT */
343 goto out; 333 goto out;
344 d_printf(3, i1480->dev, "%s fw '%s': uploading\n", fw_tag, fw_name);
345 result = fw_hdrs_load(i1480, &fw_hdrs, fw->data, fw->size); 334 result = fw_hdrs_load(i1480, &fw_hdrs, fw->data, fw->size);
346 if (result < 0) { 335 if (result < 0) {
347 dev_err(i1480->dev, "%s fw '%s': failed to parse firmware " 336 dev_err(i1480->dev, "%s fw '%s': failed to parse firmware "
@@ -363,8 +352,6 @@ out_hdrs_release:
363out_release: 352out_release:
364 release_firmware(fw); 353 release_firmware(fw);
365out: 354out:
366 d_fnend(3, i1480->dev, "(%p, %s, %s) = %d\n", i1480, fw_name, fw_tag,
367 result);
368 return result; 355 return result;
369} 356}
370 357
@@ -433,7 +420,6 @@ int i1480_fw_is_running_q(struct i1480 *i1480)
433 int result; 420 int result;
434 u32 *val = (u32 *) i1480->cmd_buf; 421 u32 *val = (u32 *) i1480->cmd_buf;
435 422
436 d_fnstart(3, i1480->dev, "(i1480 %p)\n", i1480);
437 for (cnt = 0; cnt < 10; cnt++) { 423 for (cnt = 0; cnt < 10; cnt++) {
438 msleep(100); 424 msleep(100);
439 result = i1480->read(i1480, 0x80080000, 4); 425 result = i1480->read(i1480, 0x80080000, 4);
@@ -447,7 +433,6 @@ int i1480_fw_is_running_q(struct i1480 *i1480)
447 dev_err(i1480->dev, "Timed out waiting for fw to start\n"); 433 dev_err(i1480->dev, "Timed out waiting for fw to start\n");
448 result = -ETIMEDOUT; 434 result = -ETIMEDOUT;
449out: 435out:
450 d_fnend(3, i1480->dev, "(i1480 %p) = %d\n", i1480, result);
451 return result; 436 return result;
452 437
453} 438}
@@ -467,7 +452,6 @@ int i1480_mac_fw_upload(struct i1480 *i1480)
467 int result = 0, deprecated_name = 0; 452 int result = 0, deprecated_name = 0;
468 struct i1480_rceb *rcebe = (void *) i1480->evt_buf; 453 struct i1480_rceb *rcebe = (void *) i1480->evt_buf;
469 454
470 d_fnstart(3, i1480->dev, "(%p)\n", i1480);
471 result = __mac_fw_upload(i1480, i1480->mac_fw_name, "MAC"); 455 result = __mac_fw_upload(i1480, i1480->mac_fw_name, "MAC");
472 if (result == -ENOENT) { 456 if (result == -ENOENT) {
473 result = __mac_fw_upload(i1480, i1480->mac_fw_name_deprecate, 457 result = __mac_fw_upload(i1480, i1480->mac_fw_name_deprecate,
@@ -501,7 +485,6 @@ int i1480_mac_fw_upload(struct i1480 *i1480)
501 dev_err(i1480->dev, "MAC fw '%s': initialization event returns " 485 dev_err(i1480->dev, "MAC fw '%s': initialization event returns "
502 "wrong size (%zu bytes vs %zu needed)\n", 486 "wrong size (%zu bytes vs %zu needed)\n",
503 i1480->mac_fw_name, i1480->evt_result, sizeof(*rcebe)); 487 i1480->mac_fw_name, i1480->evt_result, sizeof(*rcebe));
504 dump_bytes(i1480->dev, rcebe, min(i1480->evt_result, (ssize_t)32));
505 goto error_size; 488 goto error_size;
506 } 489 }
507 result = -EIO; 490 result = -EIO;
@@ -522,6 +505,5 @@ error_fw_not_running:
522error_init_timeout: 505error_init_timeout:
523error_size: 506error_size:
524error_setup: 507error_setup:
525 d_fnend(3, i1480->dev, "(i1480 %p) = %d\n", i1480, result);
526 return result; 508 return result;
527} 509}
diff --git a/drivers/uwb/i1480/dfu/usb.c b/drivers/uwb/i1480/dfu/usb.c
index 98eeeff051aa..686795e97195 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>
@@ -44,10 +43,6 @@
44#include <linux/usb/wusb-wa.h> 43#include <linux/usb/wusb-wa.h>
45#include "i1480-dfu.h" 44#include "i1480-dfu.h"
46 45
47#define D_LOCAL 0
48#include <linux/uwb/debug.h>
49
50
51struct i1480_usb { 46struct i1480_usb {
52 struct i1480 i1480; 47 struct i1480 i1480;
53 struct usb_device *usb_dev; 48 struct usb_device *usb_dev;
@@ -118,8 +113,6 @@ int i1480_usb_write(struct i1480 *i1480, u32 memory_address,
118 struct i1480_usb *i1480_usb = container_of(i1480, struct i1480_usb, i1480); 113 struct i1480_usb *i1480_usb = container_of(i1480, struct i1480_usb, i1480);
119 size_t buffer_size, itr = 0; 114 size_t buffer_size, itr = 0;
120 115
121 d_fnstart(3, i1480->dev, "(%p, 0x%08x, %p, %zu)\n",
122 i1480, memory_address, buffer, size);
123 BUG_ON(size & 0x3); /* Needs to be a multiple of 4 */ 116 BUG_ON(size & 0x3); /* Needs to be a multiple of 4 */
124 while (size > 0) { 117 while (size > 0) {
125 buffer_size = size < i1480->buf_size ? size : i1480->buf_size; 118 buffer_size = size < i1480->buf_size ? size : i1480->buf_size;
@@ -132,16 +125,10 @@ int i1480_usb_write(struct i1480 *i1480, u32 memory_address,
132 i1480->cmd_buf, buffer_size, 100 /* FIXME: arbitrary */); 125 i1480->cmd_buf, buffer_size, 100 /* FIXME: arbitrary */);
133 if (result < 0) 126 if (result < 0)
134 break; 127 break;
135 d_printf(3, i1480->dev,
136 "wrote @ 0x%08x %u bytes (of %zu bytes requested)\n",
137 memory_address, result, buffer_size);
138 d_dump(4, i1480->dev, i1480->cmd_buf, result);
139 itr += result; 128 itr += result;
140 memory_address += result; 129 memory_address += result;
141 size -= result; 130 size -= result;
142 } 131 }
143 d_fnend(3, i1480->dev, "(%p, 0x%08x, %p, %zu) = %d\n",
144 i1480, memory_address, buffer, size, result);
145 return result; 132 return result;
146} 133}
147 134
@@ -166,8 +153,6 @@ int i1480_usb_read(struct i1480 *i1480, u32 addr, size_t size)
166 size_t itr, read_size = i1480->buf_size; 153 size_t itr, read_size = i1480->buf_size;
167 struct i1480_usb *i1480_usb = container_of(i1480, struct i1480_usb, i1480); 154 struct i1480_usb *i1480_usb = container_of(i1480, struct i1480_usb, i1480);
168 155
169 d_fnstart(3, i1480->dev, "(%p, 0x%08x, %zu)\n",
170 i1480, addr, size);
171 BUG_ON(size > i1480->buf_size); 156 BUG_ON(size > i1480->buf_size);
172 BUG_ON(size & 0x3); /* Needs to be a multiple of 4 */ 157 BUG_ON(size & 0x3); /* Needs to be a multiple of 4 */
173 BUG_ON(read_size > 512); 158 BUG_ON(read_size > 512);
@@ -201,10 +186,6 @@ int i1480_usb_read(struct i1480 *i1480, u32 addr, size_t size)
201 } 186 }
202 result = bytes; 187 result = bytes;
203out: 188out:
204 d_fnend(3, i1480->dev, "(%p, 0x%08x, %zu) = %zd\n",
205 i1480, addr, size, result);
206 if (result > 0)
207 d_dump(4, i1480->dev, i1480->cmd_buf, result);
208 return result; 189 return result;
209} 190}
210 191
@@ -260,7 +241,6 @@ int i1480_usb_wait_init_done(struct i1480 *i1480)
260 struct i1480_usb *i1480_usb = container_of(i1480, struct i1480_usb, i1480); 241 struct i1480_usb *i1480_usb = container_of(i1480, struct i1480_usb, i1480);
261 struct usb_endpoint_descriptor *epd; 242 struct usb_endpoint_descriptor *epd;
262 243
263 d_fnstart(3, dev, "(%p)\n", i1480);
264 init_completion(&i1480->evt_complete); 244 init_completion(&i1480->evt_complete);
265 i1480->evt_result = -EINPROGRESS; 245 i1480->evt_result = -EINPROGRESS;
266 epd = &i1480_usb->usb_iface->cur_altsetting->endpoint[0].desc; 246 epd = &i1480_usb->usb_iface->cur_altsetting->endpoint[0].desc;
@@ -282,14 +262,12 @@ int i1480_usb_wait_init_done(struct i1480 *i1480)
282 goto error_wait; 262 goto error_wait;
283 } 263 }
284 usb_kill_urb(i1480_usb->neep_urb); 264 usb_kill_urb(i1480_usb->neep_urb);
285 d_fnend(3, dev, "(%p) = 0\n", i1480);
286 return 0; 265 return 0;
287 266
288error_wait: 267error_wait:
289 usb_kill_urb(i1480_usb->neep_urb); 268 usb_kill_urb(i1480_usb->neep_urb);
290error_submit: 269error_submit:
291 i1480->evt_result = result; 270 i1480->evt_result = result;
292 d_fnend(3, dev, "(%p) = %d\n", i1480, result);
293 return result; 271 return result;
294} 272}
295 273
@@ -320,7 +298,6 @@ int i1480_usb_cmd(struct i1480 *i1480, const char *cmd_name, size_t cmd_size)
320 struct uwb_rccb *cmd = i1480->cmd_buf; 298 struct uwb_rccb *cmd = i1480->cmd_buf;
321 u8 iface_no; 299 u8 iface_no;
322 300
323 d_fnstart(3, dev, "(%p, %s, %zu)\n", i1480, cmd_name, cmd_size);
324 /* Post a read on the notification & event endpoint */ 301 /* Post a read on the notification & event endpoint */
325 iface_no = i1480_usb->usb_iface->cur_altsetting->desc.bInterfaceNumber; 302 iface_no = i1480_usb->usb_iface->cur_altsetting->desc.bInterfaceNumber;
326 epd = &i1480_usb->usb_iface->cur_altsetting->endpoint[0].desc; 303 epd = &i1480_usb->usb_iface->cur_altsetting->endpoint[0].desc;
@@ -348,15 +325,11 @@ int i1480_usb_cmd(struct i1480 *i1480, const char *cmd_name, size_t cmd_size)
348 cmd_name, result); 325 cmd_name, result);
349 goto error_submit_ep0; 326 goto error_submit_ep0;
350 } 327 }
351 d_fnend(3, dev, "(%p, %s, %zu) = %d\n",
352 i1480, cmd_name, cmd_size, result);
353 return result; 328 return result;
354 329
355error_submit_ep0: 330error_submit_ep0:
356 usb_kill_urb(i1480_usb->neep_urb); 331 usb_kill_urb(i1480_usb->neep_urb);
357error_submit_ep1: 332error_submit_ep1:
358 d_fnend(3, dev, "(%p, %s, %zu) = %d\n",
359 i1480, cmd_name, cmd_size, result);
360 return result; 333 return result;
361} 334}
362 335
diff --git a/drivers/uwb/i1480/i1480u-wlp/lc.c b/drivers/uwb/i1480/i1480u-wlp/lc.c
index 737d60cd5b73..049c05d4cc6a 100644
--- a/drivers/uwb/i1480/i1480u-wlp/lc.c
+++ b/drivers/uwb/i1480/i1480u-wlp/lc.c
@@ -55,10 +55,9 @@
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
62#include "i1480u-wlp.h" 61#include "i1480u-wlp.h"
63 62
64 63
@@ -207,7 +206,7 @@ int i1480u_add(struct i1480u *i1480u, struct usb_interface *iface)
207 wlp->fill_device_info = i1480u_fill_device_info; 206 wlp->fill_device_info = i1480u_fill_device_info;
208 wlp->stop_queue = i1480u_stop_queue; 207 wlp->stop_queue = i1480u_stop_queue;
209 wlp->start_queue = i1480u_start_queue; 208 wlp->start_queue = i1480u_start_queue;
210 result = wlp_setup(wlp, rc); 209 result = wlp_setup(wlp, rc, net_dev);
211 if (result < 0) { 210 if (result < 0) {
212 dev_err(&iface->dev, "Cannot setup WLP\n"); 211 dev_err(&iface->dev, "Cannot setup WLP\n");
213 goto error_wlp_setup; 212 goto error_wlp_setup;
diff --git a/drivers/uwb/i1480/i1480u-wlp/netdev.c b/drivers/uwb/i1480/i1480u-wlp/netdev.c
index 8802ac43d872..e3873ffb942c 100644
--- a/drivers/uwb/i1480/i1480u-wlp/netdev.c
+++ b/drivers/uwb/i1480/i1480u-wlp/netdev.c
@@ -41,7 +41,7 @@
41 41
42#include <linux/if_arp.h> 42#include <linux/if_arp.h>
43#include <linux/etherdevice.h> 43#include <linux/etherdevice.h>
44#include <linux/uwb/debug.h> 44
45#include "i1480u-wlp.h" 45#include "i1480u-wlp.h"
46 46
47struct i1480u_cmd_set_ip_mas { 47struct i1480u_cmd_set_ip_mas {
@@ -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/rx.c b/drivers/uwb/i1480/i1480u-wlp/rx.c
index 9fc035354a76..34f4cf9a7d34 100644
--- a/drivers/uwb/i1480/i1480u-wlp/rx.c
+++ b/drivers/uwb/i1480/i1480u-wlp/rx.c
@@ -68,11 +68,7 @@
68#include <linux/etherdevice.h> 68#include <linux/etherdevice.h>
69#include "i1480u-wlp.h" 69#include "i1480u-wlp.h"
70 70
71#define D_LOCAL 0 71/*
72#include <linux/uwb/debug.h>
73
74
75/**
76 * Setup the RX context 72 * Setup the RX context
77 * 73 *
78 * Each URB is provided with a transfer_buffer that is the data field 74 * Each URB is provided with a transfer_buffer that is the data field
@@ -129,7 +125,7 @@ error:
129} 125}
130 126
131 127
132/** Release resources associated to the rx context */ 128/* Release resources associated to the rx context */
133void i1480u_rx_release(struct i1480u *i1480u) 129void i1480u_rx_release(struct i1480u *i1480u)
134{ 130{
135 int cnt; 131 int cnt;
@@ -155,7 +151,7 @@ void i1480u_rx_unlink_urbs(struct i1480u *i1480u)
155 } 151 }
156} 152}
157 153
158/** Fix an out-of-sequence packet */ 154/* Fix an out-of-sequence packet */
159#define i1480u_fix(i1480u, msg...) \ 155#define i1480u_fix(i1480u, msg...) \
160do { \ 156do { \
161 if (printk_ratelimit()) \ 157 if (printk_ratelimit()) \
@@ -166,7 +162,7 @@ do { \
166} while (0) 162} while (0)
167 163
168 164
169/** Drop an out-of-sequence packet */ 165/* Drop an out-of-sequence packet */
170#define i1480u_drop(i1480u, msg...) \ 166#define i1480u_drop(i1480u, msg...) \
171do { \ 167do { \
172 if (printk_ratelimit()) \ 168 if (printk_ratelimit()) \
@@ -177,7 +173,7 @@ do { \
177 173
178 174
179 175
180/** Finalizes setting up the SKB and delivers it 176/* Finalizes setting up the SKB and delivers it
181 * 177 *
182 * We first pass the incoming frame to WLP substack for verification. It 178 * We first pass the incoming frame to WLP substack for verification. It
183 * may also be a WLP association frame in which case WLP will take over the 179 * may also be a WLP association frame in which case WLP will take over the
@@ -192,18 +188,11 @@ void i1480u_skb_deliver(struct i1480u *i1480u)
192 struct net_device *net_dev = i1480u->net_dev; 188 struct net_device *net_dev = i1480u->net_dev;
193 struct device *dev = &i1480u->usb_iface->dev; 189 struct device *dev = &i1480u->usb_iface->dev;
194 190
195 d_printf(6, dev, "RX delivered pre skb(%p), %u bytes\n",
196 i1480u->rx_skb, i1480u->rx_skb->len);
197 d_dump(7, dev, i1480u->rx_skb->data, i1480u->rx_skb->len);
198 should_parse = wlp_receive_frame(dev, &i1480u->wlp, i1480u->rx_skb, 191 should_parse = wlp_receive_frame(dev, &i1480u->wlp, i1480u->rx_skb,
199 &i1480u->rx_srcaddr); 192 &i1480u->rx_srcaddr);
200 if (!should_parse) 193 if (!should_parse)
201 goto out; 194 goto out;
202 i1480u->rx_skb->protocol = eth_type_trans(i1480u->rx_skb, net_dev); 195 i1480u->rx_skb->protocol = eth_type_trans(i1480u->rx_skb, net_dev);
203 d_printf(5, dev, "RX delivered skb(%p), %u bytes\n",
204 i1480u->rx_skb, i1480u->rx_skb->len);
205 d_dump(7, dev, i1480u->rx_skb->data,
206 i1480u->rx_skb->len > 72 ? 72 : i1480u->rx_skb->len);
207 i1480u->stats.rx_packets++; 196 i1480u->stats.rx_packets++;
208 i1480u->stats.rx_bytes += i1480u->rx_untd_pkt_size; 197 i1480u->stats.rx_bytes += i1480u->rx_untd_pkt_size;
209 net_dev->last_rx = jiffies; 198 net_dev->last_rx = jiffies;
@@ -216,7 +205,7 @@ out:
216} 205}
217 206
218 207
219/** 208/*
220 * Process a buffer of data received from the USB RX endpoint 209 * Process a buffer of data received from the USB RX endpoint
221 * 210 *
222 * First fragment arrives with next or last fragment. All other fragments 211 * First fragment arrives with next or last fragment. All other fragments
@@ -404,7 +393,7 @@ out:
404} 393}
405 394
406 395
407/** 396/*
408 * Called when an RX URB has finished receiving or has found some kind 397 * Called when an RX URB has finished receiving or has found some kind
409 * of error condition. 398 * of error condition.
410 * 399 *
diff --git a/drivers/uwb/i1480/i1480u-wlp/sysfs.c b/drivers/uwb/i1480/i1480u-wlp/sysfs.c
index a1d8ca6ac935..4ffaf546cc6c 100644
--- a/drivers/uwb/i1480/i1480u-wlp/sysfs.c
+++ b/drivers/uwb/i1480/i1480u-wlp/sysfs.c
@@ -25,8 +25,8 @@
25 25
26#include <linux/netdevice.h> 26#include <linux/netdevice.h>
27#include <linux/etherdevice.h> 27#include <linux/etherdevice.h>
28#include <linux/uwb/debug.h>
29#include <linux/device.h> 28#include <linux/device.h>
29
30#include "i1480u-wlp.h" 30#include "i1480u-wlp.h"
31 31
32 32
@@ -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/i1480/i1480u-wlp/tx.c b/drivers/uwb/i1480/i1480u-wlp/tx.c
index 3426bfb68240..39032cc3503e 100644
--- a/drivers/uwb/i1480/i1480u-wlp/tx.c
+++ b/drivers/uwb/i1480/i1480u-wlp/tx.c
@@ -55,8 +55,6 @@
55 */ 55 */
56 56
57#include "i1480u-wlp.h" 57#include "i1480u-wlp.h"
58#define D_LOCAL 5
59#include <linux/uwb/debug.h>
60 58
61enum { 59enum {
62 /* This is only for Next and Last TX packets */ 60 /* This is only for Next and Last TX packets */
@@ -64,7 +62,7 @@ enum {
64 - sizeof(struct untd_hdr_rst), 62 - sizeof(struct untd_hdr_rst),
65}; 63};
66 64
67/** Free resources allocated to a i1480u tx context. */ 65/* Free resources allocated to a i1480u tx context. */
68static 66static
69void i1480u_tx_free(struct i1480u_tx *wtx) 67void i1480u_tx_free(struct i1480u_tx *wtx)
70{ 68{
@@ -99,7 +97,7 @@ void i1480u_tx_unlink_urbs(struct i1480u *i1480u)
99} 97}
100 98
101 99
102/** 100/*
103 * Callback for a completed tx USB URB. 101 * Callback for a completed tx USB URB.
104 * 102 *
105 * TODO: 103 * TODO:
@@ -149,8 +147,6 @@ void i1480u_tx_cb(struct urb *urb)
149 <= i1480u->tx_inflight.threshold 147 <= i1480u->tx_inflight.threshold
150 && netif_queue_stopped(net_dev) 148 && netif_queue_stopped(net_dev)
151 && i1480u->tx_inflight.threshold != 0) { 149 && i1480u->tx_inflight.threshold != 0) {
152 if (d_test(2) && printk_ratelimit())
153 d_printf(2, dev, "Restart queue. \n");
154 netif_start_queue(net_dev); 150 netif_start_queue(net_dev);
155 atomic_inc(&i1480u->tx_inflight.restart_count); 151 atomic_inc(&i1480u->tx_inflight.restart_count);
156 } 152 }
@@ -158,7 +154,7 @@ void i1480u_tx_cb(struct urb *urb)
158} 154}
159 155
160 156
161/** 157/*
162 * Given a buffer that doesn't fit in a single fragment, create an 158 * Given a buffer that doesn't fit in a single fragment, create an
163 * scatter/gather structure for delivery to the USB pipe. 159 * scatter/gather structure for delivery to the USB pipe.
164 * 160 *
@@ -253,15 +249,11 @@ int i1480u_tx_create_n(struct i1480u_tx *wtx, struct sk_buff *skb,
253 /* Now do each remaining fragment */ 249 /* Now do each remaining fragment */
254 result = -EINVAL; 250 result = -EINVAL;
255 while (pl_size_left > 0) { 251 while (pl_size_left > 0) {
256 d_printf(5, NULL, "ITR HDR: pl_size_left %zu buf_itr %zu\n",
257 pl_size_left, buf_itr - wtx->buf);
258 if (buf_itr + sizeof(*untd_hdr_rst) - wtx->buf 252 if (buf_itr + sizeof(*untd_hdr_rst) - wtx->buf
259 > wtx->buf_size) { 253 > wtx->buf_size) {
260 printk(KERN_ERR "BUG: no space for header\n"); 254 printk(KERN_ERR "BUG: no space for header\n");
261 goto error_bug; 255 goto error_bug;
262 } 256 }
263 d_printf(5, NULL, "ITR HDR 2: pl_size_left %zu buf_itr %zu\n",
264 pl_size_left, buf_itr - wtx->buf);
265 untd_hdr_rst = buf_itr; 257 untd_hdr_rst = buf_itr;
266 buf_itr += sizeof(*untd_hdr_rst); 258 buf_itr += sizeof(*untd_hdr_rst);
267 if (pl_size_left > i1480u_MAX_PL_SIZE) { 259 if (pl_size_left > i1480u_MAX_PL_SIZE) {
@@ -271,9 +263,6 @@ int i1480u_tx_create_n(struct i1480u_tx *wtx, struct sk_buff *skb,
271 frg_pl_size = pl_size_left; 263 frg_pl_size = pl_size_left;
272 untd_hdr_set_type(&untd_hdr_rst->hdr, i1480u_PKT_FRAG_LST); 264 untd_hdr_set_type(&untd_hdr_rst->hdr, i1480u_PKT_FRAG_LST);
273 } 265 }
274 d_printf(5, NULL,
275 "ITR PL: pl_size_left %zu buf_itr %zu frg_pl_size %zu\n",
276 pl_size_left, buf_itr - wtx->buf, frg_pl_size);
277 untd_hdr_set_rx_tx(&untd_hdr_rst->hdr, 0); 266 untd_hdr_set_rx_tx(&untd_hdr_rst->hdr, 0);
278 untd_hdr_rst->hdr.len = cpu_to_le16(frg_pl_size); 267 untd_hdr_rst->hdr.len = cpu_to_le16(frg_pl_size);
279 untd_hdr_rst->padding = 0; 268 untd_hdr_rst->padding = 0;
@@ -286,9 +275,6 @@ int i1480u_tx_create_n(struct i1480u_tx *wtx, struct sk_buff *skb,
286 buf_itr += frg_pl_size; 275 buf_itr += frg_pl_size;
287 pl_itr += frg_pl_size; 276 pl_itr += frg_pl_size;
288 pl_size_left -= frg_pl_size; 277 pl_size_left -= frg_pl_size;
289 d_printf(5, NULL,
290 "ITR PL 2: pl_size_left %zu buf_itr %zu frg_pl_size %zu\n",
291 pl_size_left, buf_itr - wtx->buf, frg_pl_size);
292 } 278 }
293 dev_kfree_skb_irq(skb); 279 dev_kfree_skb_irq(skb);
294 return 0; 280 return 0;
@@ -308,7 +294,7 @@ error_buf_alloc:
308} 294}
309 295
310 296
311/** 297/*
312 * Given a buffer that fits in a single fragment, fill out a @wtx 298 * Given a buffer that fits in a single fragment, fill out a @wtx
313 * struct for transmitting it down the USB pipe. 299 * struct for transmitting it down the USB pipe.
314 * 300 *
@@ -346,7 +332,7 @@ int i1480u_tx_create_1(struct i1480u_tx *wtx, struct sk_buff *skb,
346} 332}
347 333
348 334
349/** 335/*
350 * Given a skb to transmit, massage it to become palatable for the TX pipe 336 * Given a skb to transmit, massage it to become palatable for the TX pipe
351 * 337 *
352 * This will break the buffer in chunks smaller than 338 * This will break the buffer in chunks smaller than
@@ -425,7 +411,7 @@ error_wtx_alloc:
425 return NULL; 411 return NULL;
426} 412}
427 413
428/** 414/*
429 * Actual fragmentation and transmission of frame 415 * Actual fragmentation and transmission of frame
430 * 416 *
431 * @wlp: WLP substack data structure 417 * @wlp: WLP substack data structure
@@ -447,20 +433,12 @@ int i1480u_xmit_frame(struct wlp *wlp, struct sk_buff *skb,
447 struct i1480u_tx *wtx; 433 struct i1480u_tx *wtx;
448 struct wlp_tx_hdr *wlp_tx_hdr; 434 struct wlp_tx_hdr *wlp_tx_hdr;
449 static unsigned char dev_bcast[2] = { 0xff, 0xff }; 435 static unsigned char dev_bcast[2] = { 0xff, 0xff };
450#if 0
451 int lockup = 50;
452#endif
453 436
454 d_fnstart(6, dev, "(skb %p (%u), net_dev %p)\n", skb, skb->len,
455 net_dev);
456 BUG_ON(i1480u->wlp.rc == NULL); 437 BUG_ON(i1480u->wlp.rc == NULL);
457 if ((net_dev->flags & IFF_UP) == 0) 438 if ((net_dev->flags & IFF_UP) == 0)
458 goto out; 439 goto out;
459 result = -EBUSY; 440 result = -EBUSY;
460 if (atomic_read(&i1480u->tx_inflight.count) >= i1480u->tx_inflight.max) { 441 if (atomic_read(&i1480u->tx_inflight.count) >= i1480u->tx_inflight.max) {
461 if (d_test(2) && printk_ratelimit())
462 d_printf(2, dev, "Max frames in flight "
463 "stopping queue.\n");
464 netif_stop_queue(net_dev); 442 netif_stop_queue(net_dev);
465 goto error_max_inflight; 443 goto error_max_inflight;
466 } 444 }
@@ -489,21 +467,6 @@ int i1480u_xmit_frame(struct wlp *wlp, struct sk_buff *skb,
489 wlp_tx_hdr_set_delivery_id_type(wlp_tx_hdr, i1480u->options.pca_base_priority); 467 wlp_tx_hdr_set_delivery_id_type(wlp_tx_hdr, i1480u->options.pca_base_priority);
490 } 468 }
491 469
492#if 0
493 dev_info(dev, "TX delivering skb -> USB, %zu bytes\n", skb->len);
494 dump_bytes(dev, skb->data, skb->len > 72 ? 72 : skb->len);
495#endif
496#if 0
497 /* simulates a device lockup after every lockup# packets */
498 if (lockup && ((i1480u->stats.tx_packets + 1) % lockup) == 0) {
499 /* Simulate a dropped transmit interrupt */
500 net_dev->trans_start = jiffies;
501 netif_stop_queue(net_dev);
502 dev_err(dev, "Simulate lockup at %ld\n", jiffies);
503 return result;
504 }
505#endif
506
507 result = usb_submit_urb(wtx->urb, GFP_ATOMIC); /* Go baby */ 470 result = usb_submit_urb(wtx->urb, GFP_ATOMIC); /* Go baby */
508 if (result < 0) { 471 if (result < 0) {
509 dev_err(dev, "TX: cannot submit URB: %d\n", result); 472 dev_err(dev, "TX: cannot submit URB: %d\n", result);
@@ -513,8 +476,6 @@ int i1480u_xmit_frame(struct wlp *wlp, struct sk_buff *skb,
513 } 476 }
514 atomic_inc(&i1480u->tx_inflight.count); 477 atomic_inc(&i1480u->tx_inflight.count);
515 net_dev->trans_start = jiffies; 478 net_dev->trans_start = jiffies;
516 d_fnend(6, dev, "(skb %p (%u), net_dev %p) = %d\n", skb, skb->len,
517 net_dev, result);
518 return result; 479 return result;
519 480
520error_tx_urb_submit: 481error_tx_urb_submit:
@@ -522,13 +483,11 @@ error_tx_urb_submit:
522error_wtx_alloc: 483error_wtx_alloc:
523error_max_inflight: 484error_max_inflight:
524out: 485out:
525 d_fnend(6, dev, "(skb %p (%u), net_dev %p) = %d\n", skb, skb->len,
526 net_dev, result);
527 return result; 486 return result;
528} 487}
529 488
530 489
531/** 490/*
532 * Transmit an skb Called when an skbuf has to be transmitted 491 * Transmit an skb Called when an skbuf has to be transmitted
533 * 492 *
534 * The skb is first passed to WLP substack to ensure this is a valid 493 * The skb is first passed to WLP substack to ensure this is a valid
@@ -551,9 +510,6 @@ int i1480u_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
551 struct device *dev = &i1480u->usb_iface->dev; 510 struct device *dev = &i1480u->usb_iface->dev;
552 struct uwb_dev_addr dst; 511 struct uwb_dev_addr dst;
553 512
554 d_fnstart(6, dev, "(skb %p (%u), net_dev %p)\n", skb, skb->len,
555 net_dev);
556 BUG_ON(i1480u->wlp.rc == NULL);
557 if ((net_dev->flags & IFF_UP) == 0) 513 if ((net_dev->flags & IFF_UP) == 0)
558 goto error; 514 goto error;
559 result = wlp_prepare_tx_frame(dev, &i1480u->wlp, skb, &dst); 515 result = wlp_prepare_tx_frame(dev, &i1480u->wlp, skb, &dst);
@@ -562,31 +518,25 @@ int i1480u_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
562 "Dropping packet.\n", result); 518 "Dropping packet.\n", result);
563 goto error; 519 goto error;
564 } else if (result == 1) { 520 } else if (result == 1) {
565 d_printf(6, dev, "WLP will transmit frame. \n");
566 /* trans_start time will be set when WLP actually transmits 521 /* trans_start time will be set when WLP actually transmits
567 * the frame */ 522 * the frame */
568 goto out; 523 goto out;
569 } 524 }
570 d_printf(6, dev, "Transmitting frame. \n");
571 result = i1480u_xmit_frame(&i1480u->wlp, skb, &dst); 525 result = i1480u_xmit_frame(&i1480u->wlp, skb, &dst);
572 if (result < 0) { 526 if (result < 0) {
573 dev_err(dev, "Frame TX failed (%d).\n", result); 527 dev_err(dev, "Frame TX failed (%d).\n", result);
574 goto error; 528 goto error;
575 } 529 }
576 d_fnend(6, dev, "(skb %p (%u), net_dev %p) = %d\n", skb, skb->len,
577 net_dev, result);
578 return NETDEV_TX_OK; 530 return NETDEV_TX_OK;
579error: 531error:
580 dev_kfree_skb_any(skb); 532 dev_kfree_skb_any(skb);
581 i1480u->stats.tx_dropped++; 533 i1480u->stats.tx_dropped++;
582out: 534out:
583 d_fnend(6, dev, "(skb %p (%u), net_dev %p) = %d\n", skb, skb->len,
584 net_dev, result);
585 return NETDEV_TX_OK; 535 return NETDEV_TX_OK;
586} 536}
587 537
588 538
589/** 539/*
590 * Called when a pkt transmission doesn't complete in a reasonable period 540 * Called when a pkt transmission doesn't complete in a reasonable period
591 * Device reset may sleep - do it outside of interrupt context (delayed) 541 * Device reset may sleep - do it outside of interrupt context (delayed)
592 */ 542 */
diff --git a/drivers/uwb/ie-rcv.c b/drivers/uwb/ie-rcv.c
new file mode 100644
index 000000000000..917e6d78a798
--- /dev/null
+++ b/drivers/uwb/ie-rcv.c
@@ -0,0 +1,55 @@
1/*
2 * Ultra Wide Band
3 * IE Received notification handling.
4 *
5 * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License version
9 * 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/errno.h>
21#include <linux/module.h>
22#include <linux/device.h>
23#include <linux/bitmap.h>
24#include "uwb-internal.h"
25
26/*
27 * Process an incoming IE Received notification.
28 */
29int uwbd_evt_handle_rc_ie_rcv(struct uwb_event *evt)
30{
31 int result = -EINVAL;
32 struct device *dev = &evt->rc->uwb_dev.dev;
33 struct uwb_rc_evt_ie_rcv *iercv;
34 size_t iesize;
35
36 /* Is there enough data to decode it? */
37 if (evt->notif.size < sizeof(*iercv)) {
38 dev_err(dev, "IE Received notification: Not enough data to "
39 "decode (%zu vs %zu bytes needed)\n",
40 evt->notif.size, sizeof(*iercv));
41 goto error;
42 }
43 iercv = container_of(evt->notif.rceb, struct uwb_rc_evt_ie_rcv, rceb);
44 iesize = le16_to_cpu(iercv->wIELength);
45
46 dev_dbg(dev, "IE received, element ID=%d\n", iercv->IEData[0]);
47
48 if (iercv->IEData[0] == UWB_RELINQUISH_REQUEST_IE) {
49 dev_warn(dev, "unhandled Relinquish Request IE\n");
50 }
51
52 return 0;
53error:
54 return result;
55}
diff --git a/drivers/uwb/ie.c b/drivers/uwb/ie.c
index cf6f3d152b9d..ab976686175b 100644
--- a/drivers/uwb/ie.c
+++ b/drivers/uwb/ie.c
@@ -25,8 +25,6 @@
25 */ 25 */
26 26
27#include "uwb-internal.h" 27#include "uwb-internal.h"
28#define D_LOCAL 0
29#include <linux/uwb/debug.h>
30 28
31/** 29/**
32 * uwb_ie_next - get the next IE in a buffer 30 * uwb_ie_next - get the next IE in a buffer
@@ -61,6 +59,42 @@ struct uwb_ie_hdr *uwb_ie_next(void **ptr, size_t *len)
61EXPORT_SYMBOL_GPL(uwb_ie_next); 59EXPORT_SYMBOL_GPL(uwb_ie_next);
62 60
63/** 61/**
62 * uwb_ie_dump_hex - print IEs to a character buffer
63 * @ies: the IEs to print.
64 * @len: length of all the IEs.
65 * @buf: the destination buffer.
66 * @size: size of @buf.
67 *
68 * Returns the number of characters written.
69 */
70int uwb_ie_dump_hex(const struct uwb_ie_hdr *ies, size_t len,
71 char *buf, size_t size)
72{
73 void *ptr;
74 const struct uwb_ie_hdr *ie;
75 int r = 0;
76 u8 *d;
77
78 ptr = (void *)ies;
79 for (;;) {
80 ie = uwb_ie_next(&ptr, &len);
81 if (!ie)
82 break;
83
84 r += scnprintf(buf + r, size - r, "%02x %02x",
85 (unsigned)ie->element_id,
86 (unsigned)ie->length);
87 d = (uint8_t *)ie + sizeof(struct uwb_ie_hdr);
88 while (d != ptr && r < size)
89 r += scnprintf(buf + r, size - r, " %02x", (unsigned)*d++);
90 if (r < size)
91 buf[r++] = '\n';
92 };
93
94 return r;
95}
96
97/**
64 * Get the IEs that a radio controller is sending in its beacon 98 * Get the IEs that a radio controller is sending in its beacon
65 * 99 *
66 * @uwb_rc: UWB Radio Controller 100 * @uwb_rc: UWB Radio Controller
@@ -70,6 +104,7 @@ EXPORT_SYMBOL_GPL(uwb_ie_next);
70 * anything. Once done with the iedata buffer, call 104 * anything. Once done with the iedata buffer, call
71 * uwb_rc_ie_release(iedata). Don't call kfree on it. 105 * uwb_rc_ie_release(iedata). Don't call kfree on it.
72 */ 106 */
107static
73ssize_t uwb_rc_get_ie(struct uwb_rc *uwb_rc, struct uwb_rc_evt_get_ie **pget_ie) 108ssize_t uwb_rc_get_ie(struct uwb_rc *uwb_rc, struct uwb_rc_evt_get_ie **pget_ie)
74{ 109{
75 ssize_t result; 110 ssize_t result;
@@ -78,148 +113,35 @@ ssize_t uwb_rc_get_ie(struct uwb_rc *uwb_rc, struct uwb_rc_evt_get_ie **pget_ie)
78 struct uwb_rceb *reply = NULL; 113 struct uwb_rceb *reply = NULL;
79 struct uwb_rc_evt_get_ie *get_ie; 114 struct uwb_rc_evt_get_ie *get_ie;
80 115
81 d_fnstart(3, dev, "(%p, %p)\n", uwb_rc, pget_ie);
82 result = -ENOMEM;
83 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 116 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
84 if (cmd == NULL) 117 if (cmd == NULL)
85 goto error_kzalloc; 118 return -ENOMEM;
119
86 cmd->bCommandType = UWB_RC_CET_GENERAL; 120 cmd->bCommandType = UWB_RC_CET_GENERAL;
87 cmd->wCommand = cpu_to_le16(UWB_RC_CMD_GET_IE); 121 cmd->wCommand = cpu_to_le16(UWB_RC_CMD_GET_IE);
88 result = uwb_rc_vcmd(uwb_rc, "GET_IE", cmd, sizeof(*cmd), 122 result = uwb_rc_vcmd(uwb_rc, "GET_IE", cmd, sizeof(*cmd),
89 UWB_RC_CET_GENERAL, UWB_RC_CMD_GET_IE, 123 UWB_RC_CET_GENERAL, UWB_RC_CMD_GET_IE,
90 &reply); 124 &reply);
125 kfree(cmd);
91 if (result < 0) 126 if (result < 0)
92 goto error_cmd; 127 return result;
128
93 get_ie = container_of(reply, struct uwb_rc_evt_get_ie, rceb); 129 get_ie = container_of(reply, struct uwb_rc_evt_get_ie, rceb);
94 if (result < sizeof(*get_ie)) { 130 if (result < sizeof(*get_ie)) {
95 dev_err(dev, "not enough data returned for decoding GET IE " 131 dev_err(dev, "not enough data returned for decoding GET IE "
96 "(%zu bytes received vs %zu needed)\n", 132 "(%zu bytes received vs %zu needed)\n",
97 result, sizeof(*get_ie)); 133 result, sizeof(*get_ie));
98 result = -EINVAL; 134 return -EINVAL;
99 } else if (result < sizeof(*get_ie) + le16_to_cpu(get_ie->wIELength)) { 135 } else if (result < sizeof(*get_ie) + le16_to_cpu(get_ie->wIELength)) {
100 dev_err(dev, "not enough data returned for decoding GET IE " 136 dev_err(dev, "not enough data returned for decoding GET IE "
101 "payload (%zu bytes received vs %zu needed)\n", result, 137 "payload (%zu bytes received vs %zu needed)\n", result,
102 sizeof(*get_ie) + le16_to_cpu(get_ie->wIELength)); 138 sizeof(*get_ie) + le16_to_cpu(get_ie->wIELength));
103 result = -EINVAL;
104 } else
105 *pget_ie = get_ie;
106error_cmd:
107 kfree(cmd);
108error_kzalloc:
109 d_fnend(3, dev, "(%p, %p) = %d\n", uwb_rc, pget_ie, (int)result);
110 return result;
111}
112EXPORT_SYMBOL_GPL(uwb_rc_get_ie);
113
114
115/*
116 * Given a pointer to an IE, print it in ASCII/hex followed by a new line
117 *
118 * @ie_hdr: pointer to the IE header. Length is in there, and it is
119 * guaranteed that the ie_hdr->length bytes following it are
120 * safely accesible.
121 *
122 * @_data: context data passed from uwb_ie_for_each(), an struct output_ctx
123 */
124int uwb_ie_dump_hex(struct uwb_dev *uwb_dev, const struct uwb_ie_hdr *ie_hdr,
125 size_t offset, void *_ctx)
126{
127 struct uwb_buf_ctx *ctx = _ctx;
128 const u8 *pl = (void *)(ie_hdr + 1);
129 u8 pl_itr;
130
131 ctx->bytes += scnprintf(ctx->buf + ctx->bytes, ctx->size - ctx->bytes,
132 "%02x %02x ", (unsigned) ie_hdr->element_id,
133 (unsigned) ie_hdr->length);
134 pl_itr = 0;
135 while (pl_itr < ie_hdr->length && ctx->bytes < ctx->size)
136 ctx->bytes += scnprintf(ctx->buf + ctx->bytes,
137 ctx->size - ctx->bytes,
138 "%02x ", (unsigned) pl[pl_itr++]);
139 if (ctx->bytes < ctx->size)
140 ctx->buf[ctx->bytes++] = '\n';
141 return 0;
142}
143EXPORT_SYMBOL_GPL(uwb_ie_dump_hex);
144
145
146/**
147 * Verify that a pointer in a buffer points to valid IE
148 *
149 * @start: pointer to start of buffer in which IE appears
150 * @itr: pointer to IE inside buffer that will be verified
151 * @top: pointer to end of buffer
152 *
153 * @returns: 0 if IE is valid, <0 otherwise
154 *
155 * Verification involves checking that the buffer can contain a
156 * header and the amount of data reported in the IE header can be found in
157 * the buffer.
158 */
159static
160int uwb_rc_ie_verify(struct uwb_dev *uwb_dev, const void *start,
161 const void *itr, const void *top)
162{
163 struct device *dev = &uwb_dev->dev;
164 const struct uwb_ie_hdr *ie_hdr;
165
166 if (top - itr < sizeof(*ie_hdr)) {
167 dev_err(dev, "Bad IE: no data to decode header "
168 "(%zu bytes left vs %zu needed) at offset %zu\n",
169 top - itr, sizeof(*ie_hdr), itr - start);
170 return -EINVAL;
171 }
172 ie_hdr = itr;
173 itr += sizeof(*ie_hdr);
174 if (top - itr < ie_hdr->length) {
175 dev_err(dev, "Bad IE: not enough data for payload "
176 "(%zu bytes left vs %zu needed) at offset %zu\n",
177 top - itr, (size_t)ie_hdr->length,
178 (void *)ie_hdr - start);
179 return -EINVAL; 139 return -EINVAL;
180 } 140 }
181 return 0;
182}
183 141
184 142 *pget_ie = get_ie;
185/**
186 * Walk a buffer filled with consecutive IE's a buffer
187 *
188 * @uwb_dev: UWB device this IEs belong to (for err messages mainly)
189 *
190 * @fn: function to call with each IE; if it returns 0, we keep
191 * traversing the buffer. If it returns !0, we'll stop and return
192 * that value.
193 *
194 * @data: pointer passed to @fn
195 *
196 * @buf: buffer where the consecutive IEs are located
197 *
198 * @size: size of @buf
199 *
200 * Each IE is checked for basic correctness (there is space left for
201 * the header and the payload). If that test is failed, we stop
202 * processing. For every good IE, @fn is called.
203 */
204ssize_t uwb_ie_for_each(struct uwb_dev *uwb_dev, uwb_ie_f fn, void *data,
205 const void *buf, size_t size)
206{
207 ssize_t result = 0;
208 const struct uwb_ie_hdr *ie_hdr;
209 const void *itr = buf, *top = itr + size;
210
211 while (itr < top) {
212 if (uwb_rc_ie_verify(uwb_dev, buf, itr, top) != 0)
213 break;
214 ie_hdr = itr;
215 itr += sizeof(*ie_hdr) + ie_hdr->length;
216 result = fn(uwb_dev, ie_hdr, itr - buf, data);
217 if (result != 0)
218 break;
219 }
220 return result; 143 return result;
221} 144}
222EXPORT_SYMBOL_GPL(uwb_ie_for_each);
223 145
224 146
225/** 147/**
@@ -256,70 +178,6 @@ error_cmd:
256 return result; 178 return result;
257} 179}
258 180
259/**
260 * Determine by IE id if IE is host settable
261 * WUSB 1.0 [8.6.2.8 Table 8.85]
262 *
263 * EXCEPTION:
264 * All but UWB_IE_WLP appears in Table 8.85 from WUSB 1.0. Setting this IE
265 * is required for the WLP substack to perform association with its WSS so
266 * we hope that the WUSB spec will be changed to reflect this.
267 */
268static
269int uwb_rc_ie_is_host_settable(enum uwb_ie element_id)
270{
271 if (element_id == UWB_PCA_AVAILABILITY ||
272 element_id == UWB_BP_SWITCH_IE ||
273 element_id == UWB_MAC_CAPABILITIES_IE ||
274 element_id == UWB_PHY_CAPABILITIES_IE ||
275 element_id == UWB_APP_SPEC_PROBE_IE ||
276 element_id == UWB_IDENTIFICATION_IE ||
277 element_id == UWB_MASTER_KEY_ID_IE ||
278 element_id == UWB_IE_WLP ||
279 element_id == UWB_APP_SPEC_IE)
280 return 1;
281 return 0;
282}
283
284
285/**
286 * Extract Host Settable IEs from IE
287 *
288 * @ie_data: pointer to buffer containing all IEs
289 * @size: size of buffer
290 *
291 * @returns: length of buffer that only includes host settable IEs
292 *
293 * Given a buffer of IEs we move all Host Settable IEs to front of buffer
294 * by overwriting the IEs that are not Host Settable.
295 * Buffer length is adjusted accordingly.
296 */
297static
298ssize_t uwb_rc_parse_host_settable_ie(struct uwb_dev *uwb_dev,
299 void *ie_data, size_t size)
300{
301 size_t new_len = size;
302 struct uwb_ie_hdr *ie_hdr;
303 size_t ie_length;
304 void *itr = ie_data, *top = itr + size;
305
306 while (itr < top) {
307 if (uwb_rc_ie_verify(uwb_dev, ie_data, itr, top) != 0)
308 break;
309 ie_hdr = itr;
310 ie_length = sizeof(*ie_hdr) + ie_hdr->length;
311 if (uwb_rc_ie_is_host_settable(ie_hdr->element_id)) {
312 itr += ie_length;
313 } else {
314 memmove(itr, itr + ie_length, top - (itr + ie_length));
315 new_len -= ie_length;
316 top -= ie_length;
317 }
318 }
319 return new_len;
320}
321
322
323/* Cleanup the whole IE management subsystem */ 181/* Cleanup the whole IE management subsystem */
324void uwb_rc_ie_init(struct uwb_rc *uwb_rc) 182void uwb_rc_ie_init(struct uwb_rc *uwb_rc)
325{ 183{
@@ -328,49 +186,34 @@ void uwb_rc_ie_init(struct uwb_rc *uwb_rc)
328 186
329 187
330/** 188/**
331 * Set up cache for host settable IEs currently being transmitted 189 * uwb_rc_ie_setup - setup a radio controller's IE manager
190 * @uwb_rc: the radio controller.
332 * 191 *
333 * First we just call GET-IE to get the current IEs being transmitted 192 * The current set of IEs are obtained from the hardware with a GET-IE
334 * (or we workaround and pretend we did) and (because the format is 193 * command (since the radio controller is not yet beaconing this will
335 * the same) reuse that as the IE cache (with the command prefix, as 194 * be just the hardware's MAC and PHY Capability IEs).
336 * explained in 'struct uwb_rc').
337 * 195 *
338 * @returns: size of cache created 196 * Returns 0 on success; -ve on an error.
339 */ 197 */
340ssize_t uwb_rc_ie_setup(struct uwb_rc *uwb_rc) 198int uwb_rc_ie_setup(struct uwb_rc *uwb_rc)
341{ 199{
342 struct device *dev = &uwb_rc->uwb_dev.dev; 200 struct uwb_rc_evt_get_ie *ie_info = NULL;
343 ssize_t result; 201 int capacity;
344 size_t capacity; 202
345 struct uwb_rc_evt_get_ie *ie_info; 203 capacity = uwb_rc_get_ie(uwb_rc, &ie_info);
204 if (capacity < 0)
205 return capacity;
346 206
347 d_fnstart(3, dev, "(%p)\n", uwb_rc);
348 mutex_lock(&uwb_rc->ies_mutex); 207 mutex_lock(&uwb_rc->ies_mutex);
349 result = uwb_rc_get_ie(uwb_rc, &ie_info); 208
350 if (result < 0) 209 uwb_rc->ies = (struct uwb_rc_cmd_set_ie *)ie_info;
351 goto error_get_ie;
352 capacity = result;
353 d_printf(5, dev, "Got IEs %zu bytes (%zu long at %p)\n", result,
354 (size_t)le16_to_cpu(ie_info->wIELength), ie_info);
355
356 /* Remove IEs that host should not set. */
357 result = uwb_rc_parse_host_settable_ie(&uwb_rc->uwb_dev,
358 ie_info->IEData, le16_to_cpu(ie_info->wIELength));
359 if (result < 0)
360 goto error_parse;
361 d_printf(5, dev, "purged non-settable IEs to %zu bytes\n", result);
362 uwb_rc->ies = (void *) ie_info;
363 uwb_rc->ies->rccb.bCommandType = UWB_RC_CET_GENERAL; 210 uwb_rc->ies->rccb.bCommandType = UWB_RC_CET_GENERAL;
364 uwb_rc->ies->rccb.wCommand = cpu_to_le16(UWB_RC_CMD_SET_IE); 211 uwb_rc->ies->rccb.wCommand = cpu_to_le16(UWB_RC_CMD_SET_IE);
365 uwb_rc->ies_capacity = capacity; 212 uwb_rc->ies_capacity = capacity;
366 d_printf(5, dev, "IE cache at %p %zu bytes, %zu capacity\n", 213
367 ie_info, result, capacity);
368 result = 0;
369error_parse:
370error_get_ie:
371 mutex_unlock(&uwb_rc->ies_mutex); 214 mutex_unlock(&uwb_rc->ies_mutex);
372 d_fnend(3, dev, "(%p) = %zu\n", uwb_rc, result); 215
373 return result; 216 return 0;
374} 217}
375 218
376 219
@@ -383,26 +226,47 @@ void uwb_rc_ie_release(struct uwb_rc *uwb_rc)
383} 226}
384 227
385 228
386static 229static int uwb_rc_ie_add_one(struct uwb_rc *rc, const struct uwb_ie_hdr *new_ie)
387int __acc_size(struct uwb_dev *uwb_dev, const struct uwb_ie_hdr *ie_hdr,
388 size_t offset, void *_ctx)
389{ 230{
390 size_t *acc_size = _ctx; 231 struct uwb_rc_cmd_set_ie *new_ies;
391 *acc_size += sizeof(*ie_hdr) + ie_hdr->length; 232 void *ptr, *prev_ie;
392 d_printf(6, &uwb_dev->dev, "new acc size %zu\n", *acc_size); 233 struct uwb_ie_hdr *ie;
234 size_t length, new_ie_len, new_capacity, size, prev_size;
235
236 length = le16_to_cpu(rc->ies->wIELength);
237 new_ie_len = sizeof(struct uwb_ie_hdr) + new_ie->length;
238 new_capacity = sizeof(struct uwb_rc_cmd_set_ie) + length + new_ie_len;
239
240 if (new_capacity > rc->ies_capacity) {
241 new_ies = krealloc(rc->ies, new_capacity, GFP_KERNEL);
242 if (!new_ies)
243 return -ENOMEM;
244 rc->ies = new_ies;
245 }
246
247 ptr = rc->ies->IEData;
248 size = length;
249 for (;;) {
250 prev_ie = ptr;
251 prev_size = size;
252 ie = uwb_ie_next(&ptr, &size);
253 if (!ie || ie->element_id > new_ie->element_id)
254 break;
255 }
256
257 memmove(prev_ie + new_ie_len, prev_ie, prev_size);
258 memcpy(prev_ie, new_ie, new_ie_len);
259 rc->ies->wIELength = cpu_to_le16(length + new_ie_len);
260
393 return 0; 261 return 0;
394} 262}
395 263
396
397/** 264/**
398 * Add a new IE to IEs currently being transmitted by device 265 * uwb_rc_ie_add - add new IEs to the radio controller's beacon
399 * 266 * @uwb_rc: the radio controller.
400 * @ies: the buffer containing the new IE or IEs to be added to 267 * @ies: the buffer containing the new IE or IEs to be added to
401 * the device's beacon. The buffer will be verified for 268 * the device's beacon.
402 * consistence (meaning the headers should be right) and 269 * @size: length of all the IEs.
403 * consistent with the buffer size.
404 * @size: size of @ies (in bytes, total buffer size)
405 * @returns: 0 if ok, <0 errno code on error
406 * 270 *
407 * According to WHCI 0.95 [4.13.6] the driver will only receive the RCEB 271 * According to WHCI 0.95 [4.13.6] the driver will only receive the RCEB
408 * after the device sent the first beacon that includes the IEs specified 272 * after the device sent the first beacon that includes the IEs specified
@@ -411,66 +275,40 @@ int __acc_size(struct uwb_dev *uwb_dev, const struct uwb_ie_hdr *ie_hdr,
411 * we start beaconing. 275 * we start beaconing.
412 * 276 *
413 * Setting an IE on the device will overwrite all current IEs in device. So 277 * Setting an IE on the device will overwrite all current IEs in device. So
414 * we take the current IEs being transmitted by the device, append the 278 * we take the current IEs being transmitted by the device, insert the
415 * new one, and call SET IE with all the IEs needed. 279 * new one, and call SET IE with all the IEs needed.
416 * 280 *
417 * The local IE cache will only be updated with the new IE if SET IE 281 * Returns 0 on success; or -ENOMEM.
418 * completed successfully.
419 */ 282 */
420int uwb_rc_ie_add(struct uwb_rc *uwb_rc, 283int uwb_rc_ie_add(struct uwb_rc *uwb_rc,
421 const struct uwb_ie_hdr *ies, size_t size) 284 const struct uwb_ie_hdr *ies, size_t size)
422{ 285{
423 int result = 0; 286 int result = 0;
424 struct device *dev = &uwb_rc->uwb_dev.dev; 287 void *ptr;
425 struct uwb_rc_cmd_set_ie *new_ies; 288 const struct uwb_ie_hdr *ie;
426 size_t ies_size, total_size, acc_size = 0; 289
427
428 if (uwb_rc->ies == NULL)
429 return -ESHUTDOWN;
430 uwb_ie_for_each(&uwb_rc->uwb_dev, __acc_size, &acc_size, ies, size);
431 if (acc_size != size) {
432 dev_err(dev, "BUG: bad IEs, misconstructed headers "
433 "[%zu bytes reported vs %zu calculated]\n",
434 size, acc_size);
435 WARN_ON(1);
436 return -EINVAL;
437 }
438 mutex_lock(&uwb_rc->ies_mutex); 290 mutex_lock(&uwb_rc->ies_mutex);
439 ies_size = le16_to_cpu(uwb_rc->ies->wIELength); 291
440 total_size = sizeof(*uwb_rc->ies) + ies_size; 292 ptr = (void *)ies;
441 if (total_size + size > uwb_rc->ies_capacity) { 293 for (;;) {
442 d_printf(4, dev, "Reallocating IE cache from %p capacity %zu " 294 ie = uwb_ie_next(&ptr, &size);
443 "to capacity %zu\n", uwb_rc->ies, uwb_rc->ies_capacity, 295 if (!ie)
444 total_size + size); 296 break;
445 new_ies = kzalloc(total_size + size, GFP_KERNEL); 297
446 if (new_ies == NULL) { 298 result = uwb_rc_ie_add_one(uwb_rc, ie);
447 dev_err(dev, "No memory for adding new IE\n"); 299 if (result < 0)
448 result = -ENOMEM; 300 break;
449 goto error_alloc;
450 }
451 memcpy(new_ies, uwb_rc->ies, total_size);
452 uwb_rc->ies_capacity = total_size + size;
453 kfree(uwb_rc->ies);
454 uwb_rc->ies = new_ies;
455 d_printf(4, dev, "New IE cache at %p capacity %zu\n",
456 uwb_rc->ies, uwb_rc->ies_capacity);
457 } 301 }
458 memcpy((void *)uwb_rc->ies + total_size, ies, size); 302 if (result >= 0) {
459 uwb_rc->ies->wIELength = cpu_to_le16(ies_size + size); 303 if (size == 0) {
460 if (uwb_rc->beaconing != -1) { 304 if (uwb_rc->beaconing != -1)
461 result = uwb_rc_set_ie(uwb_rc, uwb_rc->ies); 305 result = uwb_rc_set_ie(uwb_rc, uwb_rc->ies);
462 if (result < 0) {
463 dev_err(dev, "Cannot set new IE on device: %d\n",
464 result);
465 uwb_rc->ies->wIELength = cpu_to_le16(ies_size);
466 } else 306 } else
467 result = 0; 307 result = -EINVAL;
468 } 308 }
469 d_printf(4, dev, "IEs now occupy %hu bytes of %zu capacity at %p\n", 309
470 le16_to_cpu(uwb_rc->ies->wIELength), uwb_rc->ies_capacity,
471 uwb_rc->ies);
472error_alloc:
473 mutex_unlock(&uwb_rc->ies_mutex); 310 mutex_unlock(&uwb_rc->ies_mutex);
311
474 return result; 312 return result;
475} 313}
476EXPORT_SYMBOL_GPL(uwb_rc_ie_add); 314EXPORT_SYMBOL_GPL(uwb_rc_ie_add);
@@ -489,53 +327,52 @@ EXPORT_SYMBOL_GPL(uwb_rc_ie_add);
489 * beacon. We don't reallocate, we just mark the size smaller. 327 * beacon. We don't reallocate, we just mark the size smaller.
490 */ 328 */
491static 329static
492int uwb_rc_ie_cache_rm(struct uwb_rc *uwb_rc, enum uwb_ie to_remove) 330void uwb_rc_ie_cache_rm(struct uwb_rc *uwb_rc, enum uwb_ie to_remove)
493{ 331{
494 struct uwb_ie_hdr *ie_hdr; 332 struct uwb_ie_hdr *ie;
495 size_t new_len = le16_to_cpu(uwb_rc->ies->wIELength); 333 size_t len = le16_to_cpu(uwb_rc->ies->wIELength);
496 void *itr = uwb_rc->ies->IEData; 334 void *ptr;
497 void *top = itr + new_len; 335 size_t size;
498 336
499 while (itr < top) { 337 ptr = uwb_rc->ies->IEData;
500 ie_hdr = itr; 338 size = len;
501 if (ie_hdr->element_id != to_remove) { 339 for (;;) {
502 itr += sizeof(*ie_hdr) + ie_hdr->length; 340 ie = uwb_ie_next(&ptr, &size);
503 } else { 341 if (!ie)
504 int ie_length; 342 break;
505 ie_length = sizeof(*ie_hdr) + ie_hdr->length; 343 if (ie->element_id == to_remove) {
506 if (top - itr != ie_length) 344 len -= sizeof(struct uwb_ie_hdr) + ie->length;
507 memmove(itr, itr + ie_length, top - itr + ie_length); 345 memmove(ie, ptr, size);
508 top -= ie_length; 346 ptr = ie;
509 new_len -= ie_length;
510 } 347 }
511 } 348 }
512 uwb_rc->ies->wIELength = cpu_to_le16(new_len); 349 uwb_rc->ies->wIELength = cpu_to_le16(len);
513 return 0;
514} 350}
515 351
516 352
517/** 353/**
518 * Remove an IE currently being transmitted by device 354 * uwb_rc_ie_rm - remove an IE from the radio controller's beacon
355 * @uwb_rc: the radio controller.
356 * @element_id: the element ID of the IE to remove.
519 * 357 *
520 * @element_id: id of IE to be removed from device's beacon 358 * Only IEs previously added with uwb_rc_ie_add() may be removed.
359 *
360 * Returns 0 on success; or -ve the SET-IE command to the radio
361 * controller failed.
521 */ 362 */
522int uwb_rc_ie_rm(struct uwb_rc *uwb_rc, enum uwb_ie element_id) 363int uwb_rc_ie_rm(struct uwb_rc *uwb_rc, enum uwb_ie element_id)
523{ 364{
524 struct device *dev = &uwb_rc->uwb_dev.dev; 365 int result = 0;
525 int result;
526 366
527 if (uwb_rc->ies == NULL)
528 return -ESHUTDOWN;
529 mutex_lock(&uwb_rc->ies_mutex); 367 mutex_lock(&uwb_rc->ies_mutex);
530 result = uwb_rc_ie_cache_rm(uwb_rc, element_id); 368
531 if (result < 0) 369 uwb_rc_ie_cache_rm(uwb_rc, element_id);
532 dev_err(dev, "Cannot remove IE from cache.\n"); 370
533 if (uwb_rc->beaconing != -1) { 371 if (uwb_rc->beaconing != -1)
534 result = uwb_rc_set_ie(uwb_rc, uwb_rc->ies); 372 result = uwb_rc_set_ie(uwb_rc, uwb_rc->ies);
535 if (result < 0) 373
536 dev_err(dev, "Cannot set new IE on device.\n");
537 }
538 mutex_unlock(&uwb_rc->ies_mutex); 374 mutex_unlock(&uwb_rc->ies_mutex);
375
539 return result; 376 return result;
540} 377}
541EXPORT_SYMBOL_GPL(uwb_rc_ie_rm); 378EXPORT_SYMBOL_GPL(uwb_rc_ie_rm);
diff --git a/drivers/uwb/lc-dev.c b/drivers/uwb/lc-dev.c
index 15f856c9689a..e9fe1bb7eb23 100644
--- a/drivers/uwb/lc-dev.c
+++ b/drivers/uwb/lc-dev.c
@@ -22,7 +22,6 @@
22 * 22 *
23 * FIXME: docs 23 * FIXME: docs
24 */ 24 */
25
26#include <linux/kernel.h> 25#include <linux/kernel.h>
27#include <linux/device.h> 26#include <linux/device.h>
28#include <linux/err.h> 27#include <linux/err.h>
@@ -30,10 +29,6 @@
30#include <linux/random.h> 29#include <linux/random.h>
31#include "uwb-internal.h" 30#include "uwb-internal.h"
32 31
33#define D_LOCAL 1
34#include <linux/uwb/debug.h>
35
36
37/* We initialize addresses to 0xff (invalid, as it is bcast) */ 32/* We initialize addresses to 0xff (invalid, as it is bcast) */
38static inline void uwb_dev_addr_init(struct uwb_dev_addr *addr) 33static inline void uwb_dev_addr_init(struct uwb_dev_addr *addr)
39{ 34{
@@ -104,12 +99,9 @@ static void uwb_dev_sys_release(struct device *dev)
104{ 99{
105 struct uwb_dev *uwb_dev = to_uwb_dev(dev); 100 struct uwb_dev *uwb_dev = to_uwb_dev(dev);
106 101
107 d_fnstart(4, NULL, "(dev %p uwb_dev %p)\n", dev, uwb_dev);
108 uwb_bce_put(uwb_dev->bce); 102 uwb_bce_put(uwb_dev->bce);
109 d_printf(0, &uwb_dev->dev, "uwb_dev %p freed\n", uwb_dev);
110 memset(uwb_dev, 0x69, sizeof(*uwb_dev)); 103 memset(uwb_dev, 0x69, sizeof(*uwb_dev));
111 kfree(uwb_dev); 104 kfree(uwb_dev);
112 d_fnend(4, NULL, "(dev %p uwb_dev %p) = void\n", dev, uwb_dev);
113} 105}
114 106
115/* 107/*
@@ -275,12 +267,8 @@ static struct attribute_group *groups[] = {
275 */ 267 */
276static int __uwb_dev_sys_add(struct uwb_dev *uwb_dev, struct device *parent_dev) 268static int __uwb_dev_sys_add(struct uwb_dev *uwb_dev, struct device *parent_dev)
277{ 269{
278 int result;
279 struct device *dev; 270 struct device *dev;
280 271
281 d_fnstart(4, NULL, "(uwb_dev %p parent_dev %p)\n", uwb_dev, parent_dev);
282 BUG_ON(parent_dev == NULL);
283
284 dev = &uwb_dev->dev; 272 dev = &uwb_dev->dev;
285 /* Device sysfs files are only useful for neighbor devices not 273 /* Device sysfs files are only useful for neighbor devices not
286 local radio controllers. */ 274 local radio controllers. */
@@ -289,18 +277,14 @@ static int __uwb_dev_sys_add(struct uwb_dev *uwb_dev, struct device *parent_dev)
289 dev->parent = parent_dev; 277 dev->parent = parent_dev;
290 dev_set_drvdata(dev, uwb_dev); 278 dev_set_drvdata(dev, uwb_dev);
291 279
292 result = device_add(dev); 280 return device_add(dev);
293 d_fnend(4, NULL, "(uwb_dev %p parent_dev %p) = %d\n", uwb_dev, parent_dev, result);
294 return result;
295} 281}
296 282
297 283
298static void __uwb_dev_sys_rm(struct uwb_dev *uwb_dev) 284static void __uwb_dev_sys_rm(struct uwb_dev *uwb_dev)
299{ 285{
300 d_fnstart(4, NULL, "(uwb_dev %p)\n", uwb_dev);
301 dev_set_drvdata(&uwb_dev->dev, NULL); 286 dev_set_drvdata(&uwb_dev->dev, NULL);
302 device_del(&uwb_dev->dev); 287 device_del(&uwb_dev->dev);
303 d_fnend(4, NULL, "(uwb_dev %p) = void\n", uwb_dev);
304} 288}
305 289
306 290
@@ -384,7 +368,6 @@ int __uwb_dev_offair(struct uwb_dev *uwb_dev, struct uwb_rc *rc)
384 struct device *dev = &uwb_dev->dev; 368 struct device *dev = &uwb_dev->dev;
385 char macbuf[UWB_ADDR_STRSIZE], devbuf[UWB_ADDR_STRSIZE]; 369 char macbuf[UWB_ADDR_STRSIZE], devbuf[UWB_ADDR_STRSIZE];
386 370
387 d_fnstart(3, NULL, "(dev %p [uwb_dev %p], uwb_rc %p)\n", dev, uwb_dev, rc);
388 uwb_mac_addr_print(macbuf, sizeof(macbuf), &uwb_dev->mac_addr); 371 uwb_mac_addr_print(macbuf, sizeof(macbuf), &uwb_dev->mac_addr);
389 uwb_dev_addr_print(devbuf, sizeof(devbuf), &uwb_dev->dev_addr); 372 uwb_dev_addr_print(devbuf, sizeof(devbuf), &uwb_dev->dev_addr);
390 dev_info(dev, "uwb device (mac %s dev %s) disconnected from %s %s\n", 373 dev_info(dev, "uwb device (mac %s dev %s) disconnected from %s %s\n",
@@ -392,8 +375,10 @@ int __uwb_dev_offair(struct uwb_dev *uwb_dev, struct uwb_rc *rc)
392 rc ? rc->uwb_dev.dev.parent->bus->name : "n/a", 375 rc ? rc->uwb_dev.dev.parent->bus->name : "n/a",
393 rc ? dev_name(rc->uwb_dev.dev.parent) : ""); 376 rc ? dev_name(rc->uwb_dev.dev.parent) : "");
394 uwb_dev_rm(uwb_dev); 377 uwb_dev_rm(uwb_dev);
378 list_del(&uwb_dev->bce->node);
379 uwb_bce_put(uwb_dev->bce);
395 uwb_dev_put(uwb_dev); /* for the creation in _onair() */ 380 uwb_dev_put(uwb_dev); /* for the creation in _onair() */
396 d_fnend(3, NULL, "(dev %p [uwb_dev %p], uwb_rc %p) = 0\n", dev, uwb_dev, rc); 381
397 return 0; 382 return 0;
398} 383}
399 384
diff --git a/drivers/uwb/lc-rc.c b/drivers/uwb/lc-rc.c
index ee5772f00d42..9cf21e6bb624 100644
--- a/drivers/uwb/lc-rc.c
+++ b/drivers/uwb/lc-rc.c
@@ -36,8 +36,6 @@
36#include <linux/etherdevice.h> 36#include <linux/etherdevice.h>
37#include <linux/usb.h> 37#include <linux/usb.h>
38 38
39#define D_LOCAL 1
40#include <linux/uwb/debug.h>
41#include "uwb-internal.h" 39#include "uwb-internal.h"
42 40
43static int uwb_rc_index_match(struct device *dev, void *data) 41static int uwb_rc_index_match(struct device *dev, void *data)
@@ -81,9 +79,7 @@ static void uwb_rc_sys_release(struct device *dev)
81 struct uwb_dev *uwb_dev = container_of(dev, struct uwb_dev, dev); 79 struct uwb_dev *uwb_dev = container_of(dev, struct uwb_dev, dev);
82 struct uwb_rc *rc = container_of(uwb_dev, struct uwb_rc, uwb_dev); 80 struct uwb_rc *rc = container_of(uwb_dev, struct uwb_rc, uwb_dev);
83 81
84 uwb_rc_neh_destroy(rc);
85 uwb_rc_ie_release(rc); 82 uwb_rc_ie_release(rc);
86 d_printf(1, dev, "freed uwb_rc %p\n", rc);
87 kfree(rc); 83 kfree(rc);
88} 84}
89 85
@@ -100,6 +96,8 @@ void uwb_rc_init(struct uwb_rc *rc)
100 rc->scan_type = UWB_SCAN_DISABLED; 96 rc->scan_type = UWB_SCAN_DISABLED;
101 INIT_LIST_HEAD(&rc->notifs_chain.list); 97 INIT_LIST_HEAD(&rc->notifs_chain.list);
102 mutex_init(&rc->notifs_chain.mutex); 98 mutex_init(&rc->notifs_chain.mutex);
99 INIT_LIST_HEAD(&rc->uwb_beca.list);
100 mutex_init(&rc->uwb_beca.mutex);
103 uwb_drp_avail_init(rc); 101 uwb_drp_avail_init(rc);
104 uwb_rc_ie_init(rc); 102 uwb_rc_ie_init(rc);
105 uwb_rsv_init(rc); 103 uwb_rsv_init(rc);
@@ -191,9 +189,9 @@ static int uwb_rc_setup(struct uwb_rc *rc)
191 int result; 189 int result;
192 struct device *dev = &rc->uwb_dev.dev; 190 struct device *dev = &rc->uwb_dev.dev;
193 191
194 result = uwb_rc_reset(rc); 192 result = uwb_radio_setup(rc);
195 if (result < 0) { 193 if (result < 0) {
196 dev_err(dev, "cannot reset UWB radio: %d\n", result); 194 dev_err(dev, "cannot setup UWB radio: %d\n", result);
197 goto error; 195 goto error;
198 } 196 }
199 result = uwb_rc_mac_addr_setup(rc); 197 result = uwb_rc_mac_addr_setup(rc);
@@ -250,6 +248,12 @@ int uwb_rc_add(struct uwb_rc *rc, struct device *parent_dev, void *priv)
250 248
251 rc->priv = priv; 249 rc->priv = priv;
252 250
251 init_waitqueue_head(&rc->uwbd.wq);
252 INIT_LIST_HEAD(&rc->uwbd.event_list);
253 spin_lock_init(&rc->uwbd.event_list_lock);
254
255 uwbd_start(rc);
256
253 result = rc->start(rc); 257 result = rc->start(rc);
254 if (result < 0) 258 if (result < 0)
255 goto error_rc_start; 259 goto error_rc_start;
@@ -284,7 +288,7 @@ error_sys_add:
284error_dev_add: 288error_dev_add:
285error_rc_setup: 289error_rc_setup:
286 rc->stop(rc); 290 rc->stop(rc);
287 uwbd_flush(rc); 291 uwbd_stop(rc);
288error_rc_start: 292error_rc_start:
289 return result; 293 return result;
290} 294}
@@ -306,25 +310,24 @@ void uwb_rc_rm(struct uwb_rc *rc)
306 rc->ready = 0; 310 rc->ready = 0;
307 311
308 uwb_dbg_del_rc(rc); 312 uwb_dbg_del_rc(rc);
309 uwb_rsv_cleanup(rc); 313 uwb_rsv_remove_all(rc);
310 uwb_rc_ie_rm(rc, UWB_IDENTIFICATION_IE); 314 uwb_radio_shutdown(rc);
311 if (rc->beaconing >= 0)
312 uwb_rc_beacon(rc, -1, 0);
313 if (rc->scan_type != UWB_SCAN_DISABLED)
314 uwb_rc_scan(rc, rc->scanning, UWB_SCAN_DISABLED, 0);
315 uwb_rc_reset(rc);
316 315
317 rc->stop(rc); 316 rc->stop(rc);
318 uwbd_flush(rc); 317
318 uwbd_stop(rc);
319 uwb_rc_neh_destroy(rc);
319 320
320 uwb_dev_lock(&rc->uwb_dev); 321 uwb_dev_lock(&rc->uwb_dev);
321 rc->priv = NULL; 322 rc->priv = NULL;
322 rc->cmd = NULL; 323 rc->cmd = NULL;
323 uwb_dev_unlock(&rc->uwb_dev); 324 uwb_dev_unlock(&rc->uwb_dev);
324 mutex_lock(&uwb_beca.mutex); 325 mutex_lock(&rc->uwb_beca.mutex);
325 uwb_dev_for_each(rc, uwb_dev_offair_helper, NULL); 326 uwb_dev_for_each(rc, uwb_dev_offair_helper, NULL);
326 __uwb_rc_sys_rm(rc); 327 __uwb_rc_sys_rm(rc);
327 mutex_unlock(&uwb_beca.mutex); 328 mutex_unlock(&rc->uwb_beca.mutex);
329 uwb_rsv_cleanup(rc);
330 uwb_beca_release(rc);
328 uwb_dev_rm(&rc->uwb_dev); 331 uwb_dev_rm(&rc->uwb_dev);
329} 332}
330EXPORT_SYMBOL_GPL(uwb_rc_rm); 333EXPORT_SYMBOL_GPL(uwb_rc_rm);
@@ -468,28 +471,3 @@ void uwb_rc_put(struct uwb_rc *rc)
468 __uwb_rc_put(rc); 471 __uwb_rc_put(rc);
469} 472}
470EXPORT_SYMBOL_GPL(uwb_rc_put); 473EXPORT_SYMBOL_GPL(uwb_rc_put);
471
472/*
473 *
474 *
475 */
476ssize_t uwb_rc_print_IEs(struct uwb_rc *uwb_rc, char *buf, size_t size)
477{
478 ssize_t result;
479 struct uwb_rc_evt_get_ie *ie_info;
480 struct uwb_buf_ctx ctx;
481
482 result = uwb_rc_get_ie(uwb_rc, &ie_info);
483 if (result < 0)
484 goto error_get_ie;
485 ctx.buf = buf;
486 ctx.size = size;
487 ctx.bytes = 0;
488 uwb_ie_for_each(&uwb_rc->uwb_dev, uwb_ie_dump_hex, &ctx,
489 ie_info->IEData, result - sizeof(*ie_info));
490 result = ctx.bytes;
491 kfree(ie_info);
492error_get_ie:
493 return result;
494}
495
diff --git a/drivers/uwb/neh.c b/drivers/uwb/neh.c
index 9b4eb64327ac..0af8916d9bef 100644
--- a/drivers/uwb/neh.c
+++ b/drivers/uwb/neh.c
@@ -86,8 +86,6 @@
86#include <linux/err.h> 86#include <linux/err.h>
87 87
88#include "uwb-internal.h" 88#include "uwb-internal.h"
89#define D_LOCAL 0
90#include <linux/uwb/debug.h>
91 89
92/* 90/*
93 * UWB Radio Controller Notification/Event Handle 91 * UWB Radio Controller Notification/Event Handle
@@ -254,7 +252,6 @@ error_kzalloc:
254 252
255static void __uwb_rc_neh_rm(struct uwb_rc *rc, struct uwb_rc_neh *neh) 253static void __uwb_rc_neh_rm(struct uwb_rc *rc, struct uwb_rc_neh *neh)
256{ 254{
257 del_timer(&neh->timer);
258 __uwb_rc_ctx_put(rc, neh); 255 __uwb_rc_ctx_put(rc, neh);
259 list_del(&neh->list_node); 256 list_del(&neh->list_node);
260} 257}
@@ -275,6 +272,7 @@ void uwb_rc_neh_rm(struct uwb_rc *rc, struct uwb_rc_neh *neh)
275 __uwb_rc_neh_rm(rc, neh); 272 __uwb_rc_neh_rm(rc, neh);
276 spin_unlock_irqrestore(&rc->neh_lock, flags); 273 spin_unlock_irqrestore(&rc->neh_lock, flags);
277 274
275 del_timer_sync(&neh->timer);
278 uwb_rc_neh_put(neh); 276 uwb_rc_neh_put(neh);
279} 277}
280 278
@@ -349,7 +347,7 @@ struct uwb_rc_neh *uwb_rc_neh_lookup(struct uwb_rc *rc,
349} 347}
350 348
351 349
352/** 350/*
353 * Process notifications coming from the radio control interface 351 * Process notifications coming from the radio control interface
354 * 352 *
355 * @rc: UWB Radio Control Interface descriptor 353 * @rc: UWB Radio Control Interface descriptor
@@ -401,23 +399,6 @@ void uwb_rc_notif(struct uwb_rc *rc, struct uwb_rceb *rceb, ssize_t size)
401 uwb_evt->notif.size = size; 399 uwb_evt->notif.size = size;
402 uwb_evt->notif.rceb = rceb; 400 uwb_evt->notif.rceb = rceb;
403 401
404 switch (le16_to_cpu(rceb->wEvent)) {
405 /* Trap some vendor specific events
406 *
407 * FIXME: move this to handling in ptc-est, where we
408 * register a NULL event handler for these two guys
409 * using the Intel IDs.
410 */
411 case 0x0103:
412 dev_info(dev, "FIXME: DEVICE ADD\n");
413 return;
414 case 0x0104:
415 dev_info(dev, "FIXME: DEVICE RM\n");
416 return;
417 default:
418 break;
419 }
420
421 uwbd_event_queue(uwb_evt); 402 uwbd_event_queue(uwb_evt);
422} 403}
423 404
@@ -438,9 +419,10 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size
438 rceb->bEventContext, size); 419 rceb->bEventContext, size);
439 } else { 420 } else {
440 neh = uwb_rc_neh_lookup(rc, rceb); 421 neh = uwb_rc_neh_lookup(rc, rceb);
441 if (neh) 422 if (neh) {
423 del_timer_sync(&neh->timer);
442 uwb_rc_neh_cb(neh, rceb, size); 424 uwb_rc_neh_cb(neh, rceb, size);
443 else 425 } else
444 dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n", 426 dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n",
445 rceb->bEventType, le16_to_cpu(rceb->wEvent), 427 rceb->bEventType, le16_to_cpu(rceb->wEvent),
446 rceb->bEventContext, size); 428 rceb->bEventContext, size);
@@ -495,8 +477,6 @@ void uwb_rc_neh_grok(struct uwb_rc *rc, void *buf, size_t buf_size)
495 size_t size, real_size, event_size; 477 size_t size, real_size, event_size;
496 int needtofree; 478 int needtofree;
497 479
498 d_fnstart(3, dev, "(rc %p buf %p %zu buf_size)\n", rc, buf, buf_size);
499 d_printf(2, dev, "groking event block: %zu bytes\n", buf_size);
500 itr = buf; 480 itr = buf;
501 size = buf_size; 481 size = buf_size;
502 while (size > 0) { 482 while (size > 0) {
@@ -544,10 +524,7 @@ void uwb_rc_neh_grok(struct uwb_rc *rc, void *buf, size_t buf_size)
544 524
545 itr += real_size; 525 itr += real_size;
546 size -= real_size; 526 size -= real_size;
547 d_printf(2, dev, "consumed %zd bytes, %zu left\n",
548 event_size, size);
549 } 527 }
550 d_fnend(3, dev, "(rc %p buf %p %zu buf_size) = void\n", rc, buf, buf_size);
551} 528}
552EXPORT_SYMBOL_GPL(uwb_rc_neh_grok); 529EXPORT_SYMBOL_GPL(uwb_rc_neh_grok);
553 530
@@ -562,16 +539,22 @@ EXPORT_SYMBOL_GPL(uwb_rc_neh_grok);
562 */ 539 */
563void uwb_rc_neh_error(struct uwb_rc *rc, int error) 540void uwb_rc_neh_error(struct uwb_rc *rc, int error)
564{ 541{
565 struct uwb_rc_neh *neh, *next; 542 struct uwb_rc_neh *neh;
566 unsigned long flags; 543 unsigned long flags;
567 544
568 BUG_ON(error >= 0); 545 for (;;) {
569 spin_lock_irqsave(&rc->neh_lock, flags); 546 spin_lock_irqsave(&rc->neh_lock, flags);
570 list_for_each_entry_safe(neh, next, &rc->neh_list, list_node) { 547 if (list_empty(&rc->neh_list)) {
548 spin_unlock_irqrestore(&rc->neh_lock, flags);
549 break;
550 }
551 neh = list_first_entry(&rc->neh_list, struct uwb_rc_neh, list_node);
571 __uwb_rc_neh_rm(rc, neh); 552 __uwb_rc_neh_rm(rc, neh);
553 spin_unlock_irqrestore(&rc->neh_lock, flags);
554
555 del_timer_sync(&neh->timer);
572 uwb_rc_neh_cb(neh, NULL, error); 556 uwb_rc_neh_cb(neh, NULL, error);
573 } 557 }
574 spin_unlock_irqrestore(&rc->neh_lock, flags);
575} 558}
576EXPORT_SYMBOL_GPL(uwb_rc_neh_error); 559EXPORT_SYMBOL_GPL(uwb_rc_neh_error);
577 560
@@ -583,10 +566,14 @@ static void uwb_rc_neh_timer(unsigned long arg)
583 unsigned long flags; 566 unsigned long flags;
584 567
585 spin_lock_irqsave(&rc->neh_lock, flags); 568 spin_lock_irqsave(&rc->neh_lock, flags);
586 __uwb_rc_neh_rm(rc, neh); 569 if (neh->context)
570 __uwb_rc_neh_rm(rc, neh);
571 else
572 neh = NULL;
587 spin_unlock_irqrestore(&rc->neh_lock, flags); 573 spin_unlock_irqrestore(&rc->neh_lock, flags);
588 574
589 uwb_rc_neh_cb(neh, NULL, -ETIMEDOUT); 575 if (neh)
576 uwb_rc_neh_cb(neh, NULL, -ETIMEDOUT);
590} 577}
591 578
592/** Initializes the @rc's neh subsystem 579/** Initializes the @rc's neh subsystem
@@ -605,12 +592,19 @@ void uwb_rc_neh_create(struct uwb_rc *rc)
605void uwb_rc_neh_destroy(struct uwb_rc *rc) 592void uwb_rc_neh_destroy(struct uwb_rc *rc)
606{ 593{
607 unsigned long flags; 594 unsigned long flags;
608 struct uwb_rc_neh *neh, *next; 595 struct uwb_rc_neh *neh;
609 596
610 spin_lock_irqsave(&rc->neh_lock, flags); 597 for (;;) {
611 list_for_each_entry_safe(neh, next, &rc->neh_list, list_node) { 598 spin_lock_irqsave(&rc->neh_lock, flags);
599 if (list_empty(&rc->neh_list)) {
600 spin_unlock_irqrestore(&rc->neh_lock, flags);
601 break;
602 }
603 neh = list_first_entry(&rc->neh_list, struct uwb_rc_neh, list_node);
612 __uwb_rc_neh_rm(rc, neh); 604 __uwb_rc_neh_rm(rc, neh);
605 spin_unlock_irqrestore(&rc->neh_lock, flags);
606
607 del_timer_sync(&neh->timer);
613 uwb_rc_neh_put(neh); 608 uwb_rc_neh_put(neh);
614 } 609 }
615 spin_unlock_irqrestore(&rc->neh_lock, flags);
616} 610}
diff --git a/drivers/uwb/pal.c b/drivers/uwb/pal.c
index 1afb38eacb9a..99a19c199095 100644
--- a/drivers/uwb/pal.c
+++ b/drivers/uwb/pal.c
@@ -16,6 +16,7 @@
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/debugfs.h>
19#include <linux/uwb.h> 20#include <linux/uwb.h>
20 21
21#include "uwb-internal.h" 22#include "uwb-internal.h"
@@ -32,13 +33,13 @@ EXPORT_SYMBOL_GPL(uwb_pal_init);
32 33
33/** 34/**
34 * uwb_pal_register - register a UWB PAL 35 * uwb_pal_register - register a UWB PAL
35 * @rc: the radio controller the PAL will be using
36 * @pal: the PAL 36 * @pal: the PAL
37 * 37 *
38 * The PAL must be initialized with uwb_pal_init(). 38 * The PAL must be initialized with uwb_pal_init().
39 */ 39 */
40int uwb_pal_register(struct uwb_rc *rc, struct uwb_pal *pal) 40int uwb_pal_register(struct uwb_pal *pal)
41{ 41{
42 struct uwb_rc *rc = pal->rc;
42 int ret; 43 int ret;
43 44
44 if (pal->device) { 45 if (pal->device) {
@@ -54,9 +55,11 @@ int uwb_pal_register(struct uwb_rc *rc, struct uwb_pal *pal)
54 } 55 }
55 } 56 }
56 57
57 spin_lock(&rc->pal_lock); 58 pal->debugfs_dir = uwb_dbg_create_pal_dir(pal);
59
60 mutex_lock(&rc->uwb_dev.mutex);
58 list_add(&pal->node, &rc->pals); 61 list_add(&pal->node, &rc->pals);
59 spin_unlock(&rc->pal_lock); 62 mutex_unlock(&rc->uwb_dev.mutex);
60 63
61 return 0; 64 return 0;
62} 65}
@@ -64,14 +67,19 @@ EXPORT_SYMBOL_GPL(uwb_pal_register);
64 67
65/** 68/**
66 * uwb_pal_register - unregister a UWB PAL 69 * uwb_pal_register - unregister a UWB PAL
67 * @rc: the radio controller the PAL was using
68 * @pal: the PAL 70 * @pal: the PAL
69 */ 71 */
70void uwb_pal_unregister(struct uwb_rc *rc, struct uwb_pal *pal) 72void uwb_pal_unregister(struct uwb_pal *pal)
71{ 73{
72 spin_lock(&rc->pal_lock); 74 struct uwb_rc *rc = pal->rc;
75
76 uwb_radio_stop(pal);
77
78 mutex_lock(&rc->uwb_dev.mutex);
73 list_del(&pal->node); 79 list_del(&pal->node);
74 spin_unlock(&rc->pal_lock); 80 mutex_unlock(&rc->uwb_dev.mutex);
81
82 debugfs_remove(pal->debugfs_dir);
75 83
76 if (pal->device) { 84 if (pal->device) {
77 sysfs_remove_link(&rc->uwb_dev.dev.kobj, pal->name); 85 sysfs_remove_link(&rc->uwb_dev.dev.kobj, pal->name);
@@ -86,6 +94,5 @@ EXPORT_SYMBOL_GPL(uwb_pal_unregister);
86 */ 94 */
87void uwb_rc_pal_init(struct uwb_rc *rc) 95void uwb_rc_pal_init(struct uwb_rc *rc)
88{ 96{
89 spin_lock_init(&rc->pal_lock);
90 INIT_LIST_HEAD(&rc->pals); 97 INIT_LIST_HEAD(&rc->pals);
91} 98}
diff --git a/drivers/uwb/radio.c b/drivers/uwb/radio.c
new file mode 100644
index 000000000000..f0d55495f5e9
--- /dev/null
+++ b/drivers/uwb/radio.c
@@ -0,0 +1,202 @@
1/*
2 * UWB radio (channel) management.
3 *
4 * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#include <linux/kernel.h>
19#include <linux/uwb.h>
20
21#include "uwb-internal.h"
22
23
24static int uwb_radio_select_channel(struct uwb_rc *rc)
25{
26 /*
27 * Default to channel 9 (BG1, TFC1) unless the user has
28 * selected a specific channel or there are no active PALs.
29 */
30 if (rc->active_pals == 0)
31 return -1;
32 if (rc->beaconing_forced)
33 return rc->beaconing_forced;
34 return 9;
35}
36
37
38/*
39 * Notify all active PALs that the channel has changed.
40 */
41static void uwb_radio_channel_changed(struct uwb_rc *rc, int channel)
42{
43 struct uwb_pal *pal;
44
45 list_for_each_entry(pal, &rc->pals, node) {
46 if (pal->channel && channel != pal->channel) {
47 pal->channel = channel;
48 if (pal->channel_changed)
49 pal->channel_changed(pal, pal->channel);
50 }
51 }
52}
53
54/*
55 * Change to a new channel and notify any active PALs of the new
56 * channel.
57 *
58 * When stopping the radio, PALs need to be notified first so they can
59 * terminate any active reservations.
60 */
61static int uwb_radio_change_channel(struct uwb_rc *rc, int channel)
62{
63 int ret = 0;
64
65 if (channel == -1)
66 uwb_radio_channel_changed(rc, channel);
67
68 if (channel != rc->beaconing) {
69 if (rc->beaconing != -1 && channel != -1) {
70 /*
71 * FIXME: should signal the channel change
72 * with a Channel Change IE.
73 */
74 ret = uwb_radio_change_channel(rc, -1);
75 if (ret < 0)
76 return ret;
77 }
78 ret = uwb_rc_beacon(rc, channel, 0);
79 }
80
81 if (channel != -1)
82 uwb_radio_channel_changed(rc, rc->beaconing);
83
84 return ret;
85}
86
87/**
88 * uwb_radio_start - request that the radio be started
89 * @pal: the PAL making the request.
90 *
91 * If the radio is not already active, aa suitable channel is selected
92 * and beacons are started.
93 */
94int uwb_radio_start(struct uwb_pal *pal)
95{
96 struct uwb_rc *rc = pal->rc;
97 int ret = 0;
98
99 mutex_lock(&rc->uwb_dev.mutex);
100
101 if (!pal->channel) {
102 pal->channel = -1;
103 rc->active_pals++;
104 ret = uwb_radio_change_channel(rc, uwb_radio_select_channel(rc));
105 }
106
107 mutex_unlock(&rc->uwb_dev.mutex);
108 return ret;
109}
110EXPORT_SYMBOL_GPL(uwb_radio_start);
111
112/**
113 * uwb_radio_stop - request tha the radio be stopped.
114 * @pal: the PAL making the request.
115 *
116 * Stops the radio if no other PAL is making use of it.
117 */
118void uwb_radio_stop(struct uwb_pal *pal)
119{
120 struct uwb_rc *rc = pal->rc;
121
122 mutex_lock(&rc->uwb_dev.mutex);
123
124 if (pal->channel) {
125 rc->active_pals--;
126 uwb_radio_change_channel(rc, uwb_radio_select_channel(rc));
127 pal->channel = 0;
128 }
129
130 mutex_unlock(&rc->uwb_dev.mutex);
131}
132EXPORT_SYMBOL_GPL(uwb_radio_stop);
133
134/*
135 * uwb_radio_force_channel - force a specific channel to be used
136 * @rc: the radio controller.
137 * @channel: the channel to use; -1 to force the radio to stop; 0 to
138 * use the default channel selection algorithm.
139 */
140int uwb_radio_force_channel(struct uwb_rc *rc, int channel)
141{
142 int ret = 0;
143
144 mutex_lock(&rc->uwb_dev.mutex);
145
146 rc->beaconing_forced = channel;
147 ret = uwb_radio_change_channel(rc, uwb_radio_select_channel(rc));
148
149 mutex_unlock(&rc->uwb_dev.mutex);
150 return ret;
151}
152
153/*
154 * uwb_radio_setup - setup the radio manager
155 * @rc: the radio controller.
156 *
157 * The radio controller is reset to ensure it's in a known state
158 * before it's used.
159 */
160int uwb_radio_setup(struct uwb_rc *rc)
161{
162 return uwb_rc_reset(rc);
163}
164
165/*
166 * uwb_radio_reset_state - reset any radio manager state
167 * @rc: the radio controller.
168 *
169 * All internal radio manager state is reset to values corresponding
170 * to a reset radio controller.
171 */
172void uwb_radio_reset_state(struct uwb_rc *rc)
173{
174 struct uwb_pal *pal;
175
176 mutex_lock(&rc->uwb_dev.mutex);
177
178 list_for_each_entry(pal, &rc->pals, node) {
179 if (pal->channel) {
180 pal->channel = -1;
181 if (pal->channel_changed)
182 pal->channel_changed(pal, -1);
183 }
184 }
185
186 rc->beaconing = -1;
187 rc->scanning = -1;
188
189 mutex_unlock(&rc->uwb_dev.mutex);
190}
191
192/*
193 * uwb_radio_shutdown - shutdown the radio manager
194 * @rc: the radio controller.
195 *
196 * The radio controller is reset.
197 */
198void uwb_radio_shutdown(struct uwb_rc *rc)
199{
200 uwb_radio_reset_state(rc);
201 uwb_rc_reset(rc);
202}
diff --git a/drivers/uwb/reset.c b/drivers/uwb/reset.c
index 8de856fa7958..70f8050221ff 100644
--- a/drivers/uwb/reset.c
+++ b/drivers/uwb/reset.c
@@ -32,8 +32,6 @@
32#include <linux/err.h> 32#include <linux/err.h>
33 33
34#include "uwb-internal.h" 34#include "uwb-internal.h"
35#define D_LOCAL 0
36#include <linux/uwb/debug.h>
37 35
38/** 36/**
39 * Command result codes (WUSB1.0[T8-69]) 37 * Command result codes (WUSB1.0[T8-69])
@@ -323,17 +321,16 @@ int uwbd_msg_handle_reset(struct uwb_event *evt)
323 struct uwb_rc *rc = evt->rc; 321 struct uwb_rc *rc = evt->rc;
324 int ret; 322 int ret;
325 323
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"); 324 dev_info(&rc->uwb_dev.dev, "resetting radio controller\n");
332 ret = rc->reset(rc); 325 ret = rc->reset(rc);
333 if (ret) 326 if (ret) {
334 dev_err(&rc->uwb_dev.dev, "failed to reset hardware: %d\n", ret); 327 dev_err(&rc->uwb_dev.dev, "failed to reset hardware: %d\n", ret);
335 328 goto error;
336 module_put(rc->owner); 329 }
330 return 0;
331error:
332 /* Nothing can be done except try the reset again. */
333 uwb_rc_reset_all(rc);
337 return ret; 334 return ret;
338} 335}
339 336
@@ -360,3 +357,33 @@ void uwb_rc_reset_all(struct uwb_rc *rc)
360 uwbd_event_queue(evt); 357 uwbd_event_queue(evt);
361} 358}
362EXPORT_SYMBOL_GPL(uwb_rc_reset_all); 359EXPORT_SYMBOL_GPL(uwb_rc_reset_all);
360
361void uwb_rc_pre_reset(struct uwb_rc *rc)
362{
363 rc->stop(rc);
364 uwbd_flush(rc);
365
366 uwb_radio_reset_state(rc);
367 uwb_rsv_remove_all(rc);
368}
369EXPORT_SYMBOL_GPL(uwb_rc_pre_reset);
370
371void uwb_rc_post_reset(struct uwb_rc *rc)
372{
373 int ret;
374
375 ret = rc->start(rc);
376 if (ret)
377 goto error;
378 ret = uwb_rc_mac_addr_set(rc, &rc->uwb_dev.mac_addr);
379 if (ret)
380 goto error;
381 ret = uwb_rc_dev_addr_set(rc, &rc->uwb_dev.dev_addr);
382 if (ret)
383 goto error;
384 return;
385error:
386 /* Nothing can be done except try the reset again. */
387 uwb_rc_reset_all(rc);
388}
389EXPORT_SYMBOL_GPL(uwb_rc_post_reset);
diff --git a/drivers/uwb/rsv.c b/drivers/uwb/rsv.c
index bae16204576d..ec6eecb32f30 100644
--- a/drivers/uwb/rsv.c
+++ b/drivers/uwb/rsv.c
@@ -15,23 +15,33 @@
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>
20#include <linux/random.h>
21 21
22#include "uwb-internal.h" 22#include "uwb-internal.h"
23 23
24static void uwb_rsv_timer(unsigned long arg); 24static void uwb_rsv_timer(unsigned long arg);
25 25
26static const char *rsv_states[] = { 26static const char *rsv_states[] = {
27 [UWB_RSV_STATE_NONE] = "none", 27 [UWB_RSV_STATE_NONE] = "none ",
28 [UWB_RSV_STATE_O_INITIATED] = "initiated", 28 [UWB_RSV_STATE_O_INITIATED] = "o initiated ",
29 [UWB_RSV_STATE_O_PENDING] = "pending", 29 [UWB_RSV_STATE_O_PENDING] = "o pending ",
30 [UWB_RSV_STATE_O_MODIFIED] = "modified", 30 [UWB_RSV_STATE_O_MODIFIED] = "o modified ",
31 [UWB_RSV_STATE_O_ESTABLISHED] = "established", 31 [UWB_RSV_STATE_O_ESTABLISHED] = "o established ",
32 [UWB_RSV_STATE_T_ACCEPTED] = "accepted", 32 [UWB_RSV_STATE_O_TO_BE_MOVED] = "o to be moved ",
33 [UWB_RSV_STATE_T_DENIED] = "denied", 33 [UWB_RSV_STATE_O_MOVE_EXPANDING] = "o move expanding",
34 [UWB_RSV_STATE_T_PENDING] = "pending", 34 [UWB_RSV_STATE_O_MOVE_COMBINING] = "o move combining",
35 [UWB_RSV_STATE_O_MOVE_REDUCING] = "o move reducing ",
36 [UWB_RSV_STATE_T_ACCEPTED] = "t accepted ",
37 [UWB_RSV_STATE_T_CONFLICT] = "t conflict ",
38 [UWB_RSV_STATE_T_PENDING] = "t pending ",
39 [UWB_RSV_STATE_T_DENIED] = "t denied ",
40 [UWB_RSV_STATE_T_RESIZED] = "t resized ",
41 [UWB_RSV_STATE_T_EXPANDING_ACCEPTED] = "t expanding acc ",
42 [UWB_RSV_STATE_T_EXPANDING_CONFLICT] = "t expanding conf",
43 [UWB_RSV_STATE_T_EXPANDING_PENDING] = "t expanding pend",
44 [UWB_RSV_STATE_T_EXPANDING_DENIED] = "t expanding den ",
35}; 45};
36 46
37static const char *rsv_types[] = { 47static const char *rsv_types[] = {
@@ -42,6 +52,31 @@ static const char *rsv_types[] = {
42 [UWB_DRP_TYPE_PCA] = "pca", 52 [UWB_DRP_TYPE_PCA] = "pca",
43}; 53};
44 54
55bool uwb_rsv_has_two_drp_ies(struct uwb_rsv *rsv)
56{
57 static const bool has_two_drp_ies[] = {
58 [UWB_RSV_STATE_O_INITIATED] = false,
59 [UWB_RSV_STATE_O_PENDING] = false,
60 [UWB_RSV_STATE_O_MODIFIED] = false,
61 [UWB_RSV_STATE_O_ESTABLISHED] = false,
62 [UWB_RSV_STATE_O_TO_BE_MOVED] = false,
63 [UWB_RSV_STATE_O_MOVE_COMBINING] = false,
64 [UWB_RSV_STATE_O_MOVE_REDUCING] = false,
65 [UWB_RSV_STATE_O_MOVE_EXPANDING] = true,
66 [UWB_RSV_STATE_T_ACCEPTED] = false,
67 [UWB_RSV_STATE_T_CONFLICT] = false,
68 [UWB_RSV_STATE_T_PENDING] = false,
69 [UWB_RSV_STATE_T_DENIED] = false,
70 [UWB_RSV_STATE_T_RESIZED] = false,
71 [UWB_RSV_STATE_T_EXPANDING_ACCEPTED] = true,
72 [UWB_RSV_STATE_T_EXPANDING_CONFLICT] = true,
73 [UWB_RSV_STATE_T_EXPANDING_PENDING] = true,
74 [UWB_RSV_STATE_T_EXPANDING_DENIED] = true,
75 };
76
77 return has_two_drp_ies[rsv->state];
78}
79
45/** 80/**
46 * uwb_rsv_state_str - return a string for a reservation state 81 * uwb_rsv_state_str - return a string for a reservation state
47 * @state: the reservation state. 82 * @state: the reservation state.
@@ -66,7 +101,7 @@ const char *uwb_rsv_type_str(enum uwb_drp_type type)
66} 101}
67EXPORT_SYMBOL_GPL(uwb_rsv_type_str); 102EXPORT_SYMBOL_GPL(uwb_rsv_type_str);
68 103
69static void uwb_rsv_dump(struct uwb_rsv *rsv) 104void uwb_rsv_dump(char *text, struct uwb_rsv *rsv)
70{ 105{
71 struct device *dev = &rsv->rc->uwb_dev.dev; 106 struct device *dev = &rsv->rc->uwb_dev.dev;
72 struct uwb_dev_addr devaddr; 107 struct uwb_dev_addr devaddr;
@@ -82,6 +117,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)); 117 dev_dbg(dev, "rsv %s -> %s: %s\n", owner, target, uwb_rsv_state_str(rsv->state));
83} 118}
84 119
120static void uwb_rsv_release(struct kref *kref)
121{
122 struct uwb_rsv *rsv = container_of(kref, struct uwb_rsv, kref);
123
124 kfree(rsv);
125}
126
127void uwb_rsv_get(struct uwb_rsv *rsv)
128{
129 kref_get(&rsv->kref);
130}
131
132void uwb_rsv_put(struct uwb_rsv *rsv)
133{
134 kref_put(&rsv->kref, uwb_rsv_release);
135}
136
85/* 137/*
86 * Get a free stream index for a reservation. 138 * Get a free stream index for a reservation.
87 * 139 *
@@ -92,6 +144,7 @@ static void uwb_rsv_dump(struct uwb_rsv *rsv)
92static int uwb_rsv_get_stream(struct uwb_rsv *rsv) 144static int uwb_rsv_get_stream(struct uwb_rsv *rsv)
93{ 145{
94 struct uwb_rc *rc = rsv->rc; 146 struct uwb_rc *rc = rsv->rc;
147 struct device *dev = &rc->uwb_dev.dev;
95 unsigned long *streams_bm; 148 unsigned long *streams_bm;
96 int stream; 149 int stream;
97 150
@@ -113,12 +166,15 @@ static int uwb_rsv_get_stream(struct uwb_rsv *rsv)
113 rsv->stream = stream; 166 rsv->stream = stream;
114 set_bit(stream, streams_bm); 167 set_bit(stream, streams_bm);
115 168
169 dev_dbg(dev, "get stream %d\n", rsv->stream);
170
116 return 0; 171 return 0;
117} 172}
118 173
119static void uwb_rsv_put_stream(struct uwb_rsv *rsv) 174static void uwb_rsv_put_stream(struct uwb_rsv *rsv)
120{ 175{
121 struct uwb_rc *rc = rsv->rc; 176 struct uwb_rc *rc = rsv->rc;
177 struct device *dev = &rc->uwb_dev.dev;
122 unsigned long *streams_bm; 178 unsigned long *streams_bm;
123 179
124 switch (rsv->target.type) { 180 switch (rsv->target.type) {
@@ -133,86 +189,52 @@ static void uwb_rsv_put_stream(struct uwb_rsv *rsv)
133 } 189 }
134 190
135 clear_bit(rsv->stream, streams_bm); 191 clear_bit(rsv->stream, streams_bm);
192
193 dev_dbg(dev, "put stream %d\n", rsv->stream);
136} 194}
137 195
138/* 196void uwb_rsv_backoff_win_timer(unsigned long arg)
139 * Generate a MAS allocation with a single row component.
140 */
141static void uwb_rsv_gen_alloc_row(struct uwb_mas_bm *mas,
142 int first_mas, int mas_per_zone,
143 int zs, int ze)
144{ 197{
145 struct uwb_mas_bm col; 198 struct uwb_drp_backoff_win *bow = (struct uwb_drp_backoff_win *)arg;
146 int z; 199 struct uwb_rc *rc = container_of(bow, struct uwb_rc, bow);
147 200 struct device *dev = &rc->uwb_dev.dev;
148 bitmap_zero(mas->bm, UWB_NUM_MAS); 201
149 bitmap_zero(col.bm, UWB_NUM_MAS); 202 bow->can_reserve_extra_mases = true;
150 bitmap_fill(col.bm, mas_per_zone); 203 if (bow->total_expired <= 4) {
151 bitmap_shift_left(col.bm, col.bm, first_mas + zs * UWB_MAS_PER_ZONE, UWB_NUM_MAS); 204 bow->total_expired++;
152 205 } else {
153 for (z = zs; z <= ze; z++) { 206 /* after 4 backoff window has expired we can exit from
154 bitmap_or(mas->bm, mas->bm, col.bm, UWB_NUM_MAS); 207 * the backoff procedure */
155 bitmap_shift_left(col.bm, col.bm, UWB_MAS_PER_ZONE, UWB_NUM_MAS); 208 bow->total_expired = 0;
209 bow->window = UWB_DRP_BACKOFF_WIN_MIN >> 1;
156 } 210 }
211 dev_dbg(dev, "backoff_win_timer total_expired=%d, n=%d\n: ", bow->total_expired, bow->n);
212
213 /* try to relocate all the "to be moved" relocations */
214 uwb_rsv_handle_drp_avail_change(rc);
157} 215}
158 216
159/* 217void uwb_rsv_backoff_win_increment(struct uwb_rc *rc)
160 * Allocate some MAS for this reservation based on current local
161 * availability, the reservation parameters (max_mas, min_mas,
162 * sparsity), and the WiMedia rules for MAS allocations.
163 *
164 * Returns -EBUSY is insufficient free MAS are available.
165 *
166 * FIXME: to simplify this, only safe reservations with a single row
167 * component in zones 1 to 15 are tried (zone 0 is skipped to avoid
168 * problems with the MAS reserved for the BP).
169 *
170 * [ECMA-368] section B.2.
171 */
172static int uwb_rsv_alloc_mas(struct uwb_rsv *rsv)
173{ 218{
174 static const int safe_mas_in_row[UWB_NUM_ZONES] = { 219 struct uwb_drp_backoff_win *bow = &rc->bow;
175 8, 7, 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 2, 1, 220 struct device *dev = &rc->uwb_dev.dev;
176 }; 221 unsigned timeout_us;
177 int n, r;
178 struct uwb_mas_bm mas;
179 bool found = false;
180 222
181 /* 223 dev_dbg(dev, "backoff_win_increment: window=%d\n", bow->window);
182 * Search all valid safe allocations until either: too few MAS
183 * are available; or the smallest allocation with sufficient
184 * MAS is found.
185 *
186 * The top of the zones are preferred, so space for larger
187 * allocations is available in the bottom of the zone (e.g., a
188 * 15 MAS allocation should start in row 14 leaving space for
189 * a 120 MAS allocation at row 0).
190 */
191 for (n = safe_mas_in_row[0]; n >= 1; n--) {
192 int num_mas;
193 224
194 num_mas = n * (UWB_NUM_ZONES - 1); 225 bow->can_reserve_extra_mases = false;
195 if (num_mas < rsv->min_mas)
196 break;
197 if (found && num_mas < rsv->max_mas)
198 break;
199 226
200 for (r = UWB_MAS_PER_ZONE-1; r >= 0; r--) { 227 if((bow->window << 1) == UWB_DRP_BACKOFF_WIN_MAX)
201 if (safe_mas_in_row[r] < n) 228 return;
202 continue;
203 uwb_rsv_gen_alloc_row(&mas, r, n, 1, UWB_NUM_ZONES);
204 if (uwb_drp_avail_reserve_pending(rsv->rc, &mas) == 0) {
205 found = true;
206 break;
207 }
208 }
209 }
210 229
211 if (!found) 230 bow->window <<= 1;
212 return -EBUSY; 231 bow->n = random32() & (bow->window - 1);
232 dev_dbg(dev, "new_window=%d, n=%d\n: ", bow->window, bow->n);
213 233
214 bitmap_copy(rsv->mas.bm, mas.bm, UWB_NUM_MAS); 234 /* reset the timer associated variables */
215 return 0; 235 timeout_us = bow->n * UWB_SUPERFRAME_LENGTH_US;
236 bow->total_expired = 0;
237 mod_timer(&bow->timer, jiffies + usecs_to_jiffies(timeout_us));
216} 238}
217 239
218static void uwb_rsv_stroke_timer(struct uwb_rsv *rsv) 240static void uwb_rsv_stroke_timer(struct uwb_rsv *rsv)
@@ -225,13 +247,16 @@ static void uwb_rsv_stroke_timer(struct uwb_rsv *rsv)
225 * received. 247 * received.
226 */ 248 */
227 if (rsv->is_multicast) { 249 if (rsv->is_multicast) {
228 if (rsv->state == UWB_RSV_STATE_O_INITIATED) 250 if (rsv->state == UWB_RSV_STATE_O_INITIATED
251 || rsv->state == UWB_RSV_STATE_O_MOVE_EXPANDING
252 || rsv->state == UWB_RSV_STATE_O_MOVE_COMBINING
253 || rsv->state == UWB_RSV_STATE_O_MOVE_REDUCING)
229 sframes = 1; 254 sframes = 1;
230 if (rsv->state == UWB_RSV_STATE_O_ESTABLISHED) 255 if (rsv->state == UWB_RSV_STATE_O_ESTABLISHED)
231 sframes = 0; 256 sframes = 0;
257
232 } 258 }
233 259
234 rsv->expired = false;
235 if (sframes > 0) { 260 if (sframes > 0) {
236 /* 261 /*
237 * Add an additional 2 superframes to account for the 262 * Add an additional 2 superframes to account for the
@@ -253,7 +278,7 @@ static void uwb_rsv_state_update(struct uwb_rsv *rsv,
253 rsv->state = new_state; 278 rsv->state = new_state;
254 rsv->ie_valid = false; 279 rsv->ie_valid = false;
255 280
256 uwb_rsv_dump(rsv); 281 uwb_rsv_dump("SU", rsv);
257 282
258 uwb_rsv_stroke_timer(rsv); 283 uwb_rsv_stroke_timer(rsv);
259 uwb_rsv_sched_update(rsv->rc); 284 uwb_rsv_sched_update(rsv->rc);
@@ -267,10 +292,17 @@ static void uwb_rsv_callback(struct uwb_rsv *rsv)
267 292
268void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state) 293void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state)
269{ 294{
295 struct uwb_rsv_move *mv = &rsv->mv;
296
270 if (rsv->state == new_state) { 297 if (rsv->state == new_state) {
271 switch (rsv->state) { 298 switch (rsv->state) {
272 case UWB_RSV_STATE_O_ESTABLISHED: 299 case UWB_RSV_STATE_O_ESTABLISHED:
300 case UWB_RSV_STATE_O_MOVE_EXPANDING:
301 case UWB_RSV_STATE_O_MOVE_COMBINING:
302 case UWB_RSV_STATE_O_MOVE_REDUCING:
273 case UWB_RSV_STATE_T_ACCEPTED: 303 case UWB_RSV_STATE_T_ACCEPTED:
304 case UWB_RSV_STATE_T_EXPANDING_ACCEPTED:
305 case UWB_RSV_STATE_T_RESIZED:
274 case UWB_RSV_STATE_NONE: 306 case UWB_RSV_STATE_NONE:
275 uwb_rsv_stroke_timer(rsv); 307 uwb_rsv_stroke_timer(rsv);
276 break; 308 break;
@@ -282,10 +314,10 @@ void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state)
282 return; 314 return;
283 } 315 }
284 316
317 uwb_rsv_dump("SC", rsv);
318
285 switch (new_state) { 319 switch (new_state) {
286 case UWB_RSV_STATE_NONE: 320 case UWB_RSV_STATE_NONE:
287 uwb_drp_avail_release(rsv->rc, &rsv->mas);
288 uwb_rsv_put_stream(rsv);
289 uwb_rsv_state_update(rsv, UWB_RSV_STATE_NONE); 321 uwb_rsv_state_update(rsv, UWB_RSV_STATE_NONE);
290 uwb_rsv_callback(rsv); 322 uwb_rsv_callback(rsv);
291 break; 323 break;
@@ -295,12 +327,45 @@ void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state)
295 case UWB_RSV_STATE_O_PENDING: 327 case UWB_RSV_STATE_O_PENDING:
296 uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_PENDING); 328 uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_PENDING);
297 break; 329 break;
330 case UWB_RSV_STATE_O_MODIFIED:
331 /* in the companion there are the MASes to drop */
332 bitmap_andnot(rsv->mas.bm, rsv->mas.bm, mv->companion_mas.bm, UWB_NUM_MAS);
333 uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_MODIFIED);
334 break;
298 case UWB_RSV_STATE_O_ESTABLISHED: 335 case UWB_RSV_STATE_O_ESTABLISHED:
336 if (rsv->state == UWB_RSV_STATE_O_MODIFIED
337 || rsv->state == UWB_RSV_STATE_O_MOVE_REDUCING) {
338 uwb_drp_avail_release(rsv->rc, &mv->companion_mas);
339 rsv->needs_release_companion_mas = false;
340 }
299 uwb_drp_avail_reserve(rsv->rc, &rsv->mas); 341 uwb_drp_avail_reserve(rsv->rc, &rsv->mas);
300 uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_ESTABLISHED); 342 uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_ESTABLISHED);
301 uwb_rsv_callback(rsv); 343 uwb_rsv_callback(rsv);
302 break; 344 break;
345 case UWB_RSV_STATE_O_MOVE_EXPANDING:
346 rsv->needs_release_companion_mas = true;
347 uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_MOVE_EXPANDING);
348 break;
349 case UWB_RSV_STATE_O_MOVE_COMBINING:
350 rsv->needs_release_companion_mas = false;
351 uwb_drp_avail_reserve(rsv->rc, &mv->companion_mas);
352 bitmap_or(rsv->mas.bm, rsv->mas.bm, mv->companion_mas.bm, UWB_NUM_MAS);
353 rsv->mas.safe += mv->companion_mas.safe;
354 rsv->mas.unsafe += mv->companion_mas.unsafe;
355 uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_MOVE_COMBINING);
356 break;
357 case UWB_RSV_STATE_O_MOVE_REDUCING:
358 bitmap_andnot(mv->companion_mas.bm, rsv->mas.bm, mv->final_mas.bm, UWB_NUM_MAS);
359 rsv->needs_release_companion_mas = true;
360 rsv->mas.safe = mv->final_mas.safe;
361 rsv->mas.unsafe = mv->final_mas.unsafe;
362 bitmap_copy(rsv->mas.bm, mv->final_mas.bm, UWB_NUM_MAS);
363 bitmap_copy(rsv->mas.unsafe_bm, mv->final_mas.unsafe_bm, UWB_NUM_MAS);
364 uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_MOVE_REDUCING);
365 break;
303 case UWB_RSV_STATE_T_ACCEPTED: 366 case UWB_RSV_STATE_T_ACCEPTED:
367 case UWB_RSV_STATE_T_RESIZED:
368 rsv->needs_release_companion_mas = false;
304 uwb_drp_avail_reserve(rsv->rc, &rsv->mas); 369 uwb_drp_avail_reserve(rsv->rc, &rsv->mas);
305 uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_ACCEPTED); 370 uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_ACCEPTED);
306 uwb_rsv_callback(rsv); 371 uwb_rsv_callback(rsv);
@@ -308,12 +373,82 @@ void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state)
308 case UWB_RSV_STATE_T_DENIED: 373 case UWB_RSV_STATE_T_DENIED:
309 uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_DENIED); 374 uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_DENIED);
310 break; 375 break;
376 case UWB_RSV_STATE_T_CONFLICT:
377 uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_CONFLICT);
378 break;
379 case UWB_RSV_STATE_T_PENDING:
380 uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_PENDING);
381 break;
382 case UWB_RSV_STATE_T_EXPANDING_ACCEPTED:
383 rsv->needs_release_companion_mas = true;
384 uwb_drp_avail_reserve(rsv->rc, &mv->companion_mas);
385 uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_EXPANDING_ACCEPTED);
386 break;
311 default: 387 default:
312 dev_err(&rsv->rc->uwb_dev.dev, "unhandled state: %s (%d)\n", 388 dev_err(&rsv->rc->uwb_dev.dev, "unhandled state: %s (%d)\n",
313 uwb_rsv_state_str(new_state), new_state); 389 uwb_rsv_state_str(new_state), new_state);
314 } 390 }
315} 391}
316 392
393static void uwb_rsv_handle_timeout_work(struct work_struct *work)
394{
395 struct uwb_rsv *rsv = container_of(work, struct uwb_rsv,
396 handle_timeout_work);
397 struct uwb_rc *rc = rsv->rc;
398
399 mutex_lock(&rc->rsvs_mutex);
400
401 uwb_rsv_dump("TO", rsv);
402
403 switch (rsv->state) {
404 case UWB_RSV_STATE_O_INITIATED:
405 if (rsv->is_multicast) {
406 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_ESTABLISHED);
407 goto unlock;
408 }
409 break;
410 case UWB_RSV_STATE_O_MOVE_EXPANDING:
411 if (rsv->is_multicast) {
412 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MOVE_COMBINING);
413 goto unlock;
414 }
415 break;
416 case UWB_RSV_STATE_O_MOVE_COMBINING:
417 if (rsv->is_multicast) {
418 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MOVE_REDUCING);
419 goto unlock;
420 }
421 break;
422 case UWB_RSV_STATE_O_MOVE_REDUCING:
423 if (rsv->is_multicast) {
424 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_ESTABLISHED);
425 goto unlock;
426 }
427 break;
428 case UWB_RSV_STATE_O_ESTABLISHED:
429 if (rsv->is_multicast)
430 goto unlock;
431 break;
432 case UWB_RSV_STATE_T_EXPANDING_ACCEPTED:
433 /*
434 * The time out could be for the main or of the
435 * companion DRP, assume it's for the companion and
436 * drop that first. A further time out is required to
437 * drop the main.
438 */
439 uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_ACCEPTED);
440 uwb_drp_avail_release(rsv->rc, &rsv->mv.companion_mas);
441 goto unlock;
442 default:
443 break;
444 }
445
446 uwb_rsv_remove(rsv);
447
448unlock:
449 mutex_unlock(&rc->rsvs_mutex);
450}
451
317static struct uwb_rsv *uwb_rsv_alloc(struct uwb_rc *rc) 452static struct uwb_rsv *uwb_rsv_alloc(struct uwb_rc *rc)
318{ 453{
319 struct uwb_rsv *rsv; 454 struct uwb_rsv *rsv;
@@ -324,23 +459,17 @@ static struct uwb_rsv *uwb_rsv_alloc(struct uwb_rc *rc)
324 459
325 INIT_LIST_HEAD(&rsv->rc_node); 460 INIT_LIST_HEAD(&rsv->rc_node);
326 INIT_LIST_HEAD(&rsv->pal_node); 461 INIT_LIST_HEAD(&rsv->pal_node);
462 kref_init(&rsv->kref);
327 init_timer(&rsv->timer); 463 init_timer(&rsv->timer);
328 rsv->timer.function = uwb_rsv_timer; 464 rsv->timer.function = uwb_rsv_timer;
329 rsv->timer.data = (unsigned long)rsv; 465 rsv->timer.data = (unsigned long)rsv;
330 466
331 rsv->rc = rc; 467 rsv->rc = rc;
468 INIT_WORK(&rsv->handle_timeout_work, uwb_rsv_handle_timeout_work);
332 469
333 return rsv; 470 return rsv;
334} 471}
335 472
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/** 473/**
345 * uwb_rsv_create - allocate and initialize a UWB reservation structure 474 * uwb_rsv_create - allocate and initialize a UWB reservation structure
346 * @rc: the radio controller 475 * @rc: the radio controller
@@ -371,26 +500,36 @@ EXPORT_SYMBOL_GPL(uwb_rsv_create);
371 500
372void uwb_rsv_remove(struct uwb_rsv *rsv) 501void uwb_rsv_remove(struct uwb_rsv *rsv)
373{ 502{
503 uwb_rsv_dump("RM", rsv);
504
374 if (rsv->state != UWB_RSV_STATE_NONE) 505 if (rsv->state != UWB_RSV_STATE_NONE)
375 uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE); 506 uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE);
507
508 if (rsv->needs_release_companion_mas)
509 uwb_drp_avail_release(rsv->rc, &rsv->mv.companion_mas);
510 uwb_drp_avail_release(rsv->rc, &rsv->mas);
511
512 if (uwb_rsv_is_owner(rsv))
513 uwb_rsv_put_stream(rsv);
514
376 del_timer_sync(&rsv->timer); 515 del_timer_sync(&rsv->timer);
377 list_del(&rsv->rc_node); 516 uwb_dev_put(rsv->owner);
378 uwb_rsv_free(rsv); 517 if (rsv->target.type == UWB_RSV_TARGET_DEV)
518 uwb_dev_put(rsv->target.dev);
519
520 list_del_init(&rsv->rc_node);
521 uwb_rsv_put(rsv);
379} 522}
380 523
381/** 524/**
382 * uwb_rsv_destroy - free a UWB reservation structure 525 * uwb_rsv_destroy - free a UWB reservation structure
383 * @rsv: the reservation to free 526 * @rsv: the reservation to free
384 * 527 *
385 * The reservation will be terminated if it is pending or established. 528 * The reservation must already be terminated.
386 */ 529 */
387void uwb_rsv_destroy(struct uwb_rsv *rsv) 530void uwb_rsv_destroy(struct uwb_rsv *rsv)
388{ 531{
389 struct uwb_rc *rc = rsv->rc; 532 uwb_rsv_put(rsv);
390
391 mutex_lock(&rc->rsvs_mutex);
392 uwb_rsv_remove(rsv);
393 mutex_unlock(&rc->rsvs_mutex);
394} 533}
395EXPORT_SYMBOL_GPL(uwb_rsv_destroy); 534EXPORT_SYMBOL_GPL(uwb_rsv_destroy);
396 535
@@ -399,7 +538,7 @@ EXPORT_SYMBOL_GPL(uwb_rsv_destroy);
399 * @rsv: the reservation 538 * @rsv: the reservation
400 * 539 *
401 * The PAL should fill in @rsv's owner, target, type, max_mas, 540 * The PAL should fill in @rsv's owner, target, type, max_mas,
402 * min_mas, sparsity and is_multicast fields. If the target is a 541 * min_mas, max_interval and is_multicast fields. If the target is a
403 * uwb_dev it must be referenced. 542 * uwb_dev it must be referenced.
404 * 543 *
405 * The reservation's callback will be called when the reservation is 544 * The reservation's callback will be called when the reservation is
@@ -408,20 +547,32 @@ EXPORT_SYMBOL_GPL(uwb_rsv_destroy);
408int uwb_rsv_establish(struct uwb_rsv *rsv) 547int uwb_rsv_establish(struct uwb_rsv *rsv)
409{ 548{
410 struct uwb_rc *rc = rsv->rc; 549 struct uwb_rc *rc = rsv->rc;
550 struct uwb_mas_bm available;
411 int ret; 551 int ret;
412 552
413 mutex_lock(&rc->rsvs_mutex); 553 mutex_lock(&rc->rsvs_mutex);
414
415 ret = uwb_rsv_get_stream(rsv); 554 ret = uwb_rsv_get_stream(rsv);
416 if (ret) 555 if (ret)
417 goto out; 556 goto out;
418 557
419 ret = uwb_rsv_alloc_mas(rsv); 558 rsv->tiebreaker = random32() & 1;
420 if (ret) { 559 /* get available mas bitmap */
560 uwb_drp_available(rc, &available);
561
562 ret = uwb_rsv_find_best_allocation(rsv, &available, &rsv->mas);
563 if (ret == UWB_RSV_ALLOC_NOT_FOUND) {
564 ret = -EBUSY;
565 uwb_rsv_put_stream(rsv);
566 goto out;
567 }
568
569 ret = uwb_drp_avail_reserve_pending(rc, &rsv->mas);
570 if (ret != 0) {
421 uwb_rsv_put_stream(rsv); 571 uwb_rsv_put_stream(rsv);
422 goto out; 572 goto out;
423 } 573 }
424 574
575 uwb_rsv_get(rsv);
425 list_add_tail(&rsv->rc_node, &rc->reservations); 576 list_add_tail(&rsv->rc_node, &rc->reservations);
426 rsv->owner = &rc->uwb_dev; 577 rsv->owner = &rc->uwb_dev;
427 uwb_dev_get(rsv->owner); 578 uwb_dev_get(rsv->owner);
@@ -437,16 +588,71 @@ EXPORT_SYMBOL_GPL(uwb_rsv_establish);
437 * @rsv: the reservation to modify 588 * @rsv: the reservation to modify
438 * @max_mas: new maximum MAS to reserve 589 * @max_mas: new maximum MAS to reserve
439 * @min_mas: new minimum MAS to reserve 590 * @min_mas: new minimum MAS to reserve
440 * @sparsity: new sparsity to use 591 * @max_interval: new max_interval to use
441 * 592 *
442 * FIXME: implement this once there are PALs that use it. 593 * FIXME: implement this once there are PALs that use it.
443 */ 594 */
444int uwb_rsv_modify(struct uwb_rsv *rsv, int max_mas, int min_mas, int sparsity) 595int uwb_rsv_modify(struct uwb_rsv *rsv, int max_mas, int min_mas, int max_interval)
445{ 596{
446 return -ENOSYS; 597 return -ENOSYS;
447} 598}
448EXPORT_SYMBOL_GPL(uwb_rsv_modify); 599EXPORT_SYMBOL_GPL(uwb_rsv_modify);
449 600
601/*
602 * move an already established reservation (rc->rsvs_mutex must to be
603 * taken when tis function is called)
604 */
605int uwb_rsv_try_move(struct uwb_rsv *rsv, struct uwb_mas_bm *available)
606{
607 struct uwb_rc *rc = rsv->rc;
608 struct uwb_drp_backoff_win *bow = &rc->bow;
609 struct device *dev = &rc->uwb_dev.dev;
610 struct uwb_rsv_move *mv;
611 int ret = 0;
612
613 if (bow->can_reserve_extra_mases == false)
614 return -EBUSY;
615
616 mv = &rsv->mv;
617
618 if (uwb_rsv_find_best_allocation(rsv, available, &mv->final_mas) == UWB_RSV_ALLOC_FOUND) {
619
620 if (!bitmap_equal(rsv->mas.bm, mv->final_mas.bm, UWB_NUM_MAS)) {
621 /* We want to move the reservation */
622 bitmap_andnot(mv->companion_mas.bm, mv->final_mas.bm, rsv->mas.bm, UWB_NUM_MAS);
623 uwb_drp_avail_reserve_pending(rc, &mv->companion_mas);
624 uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MOVE_EXPANDING);
625 }
626 } else {
627 dev_dbg(dev, "new allocation not found\n");
628 }
629
630 return ret;
631}
632
633/* It will try to move every reservation in state O_ESTABLISHED giving
634 * to the MAS allocator algorithm an availability that is the real one
635 * plus the allocation already established from the reservation. */
636void uwb_rsv_handle_drp_avail_change(struct uwb_rc *rc)
637{
638 struct uwb_drp_backoff_win *bow = &rc->bow;
639 struct uwb_rsv *rsv;
640 struct uwb_mas_bm mas;
641
642 if (bow->can_reserve_extra_mases == false)
643 return;
644
645 list_for_each_entry(rsv, &rc->reservations, rc_node) {
646 if (rsv->state == UWB_RSV_STATE_O_ESTABLISHED ||
647 rsv->state == UWB_RSV_STATE_O_TO_BE_MOVED) {
648 uwb_drp_available(rc, &mas);
649 bitmap_or(mas.bm, mas.bm, rsv->mas.bm, UWB_NUM_MAS);
650 uwb_rsv_try_move(rsv, &mas);
651 }
652 }
653
654}
655
450/** 656/**
451 * uwb_rsv_terminate - terminate an established reservation 657 * uwb_rsv_terminate - terminate an established reservation
452 * @rsv: the reservation to terminate 658 * @rsv: the reservation to terminate
@@ -463,7 +669,8 @@ void uwb_rsv_terminate(struct uwb_rsv *rsv)
463 669
464 mutex_lock(&rc->rsvs_mutex); 670 mutex_lock(&rc->rsvs_mutex);
465 671
466 uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE); 672 if (rsv->state != UWB_RSV_STATE_NONE)
673 uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE);
467 674
468 mutex_unlock(&rc->rsvs_mutex); 675 mutex_unlock(&rc->rsvs_mutex);
469} 676}
@@ -477,9 +684,14 @@ EXPORT_SYMBOL_GPL(uwb_rsv_terminate);
477 * 684 *
478 * Reservation requests from peers are denied unless a PAL accepts it 685 * Reservation requests from peers are denied unless a PAL accepts it
479 * by calling this function. 686 * by calling this function.
687 *
688 * The PAL call uwb_rsv_destroy() for all accepted reservations before
689 * calling uwb_pal_unregister().
480 */ 690 */
481void uwb_rsv_accept(struct uwb_rsv *rsv, uwb_rsv_cb_f cb, void *pal_priv) 691void uwb_rsv_accept(struct uwb_rsv *rsv, uwb_rsv_cb_f cb, void *pal_priv)
482{ 692{
693 uwb_rsv_get(rsv);
694
483 rsv->callback = cb; 695 rsv->callback = cb;
484 rsv->pal_priv = pal_priv; 696 rsv->pal_priv = pal_priv;
485 rsv->state = UWB_RSV_STATE_T_ACCEPTED; 697 rsv->state = UWB_RSV_STATE_T_ACCEPTED;
@@ -530,9 +742,9 @@ static struct uwb_rsv *uwb_rsv_new_target(struct uwb_rc *rc,
530 uwb_dev_get(rsv->owner); 742 uwb_dev_get(rsv->owner);
531 rsv->target.type = UWB_RSV_TARGET_DEV; 743 rsv->target.type = UWB_RSV_TARGET_DEV;
532 rsv->target.dev = &rc->uwb_dev; 744 rsv->target.dev = &rc->uwb_dev;
745 uwb_dev_get(&rc->uwb_dev);
533 rsv->type = uwb_ie_drp_type(drp_ie); 746 rsv->type = uwb_ie_drp_type(drp_ie);
534 rsv->stream = uwb_ie_drp_stream_index(drp_ie); 747 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); 748 uwb_drp_ie_to_bm(&rsv->mas, drp_ie);
537 749
538 /* 750 /*
@@ -540,24 +752,46 @@ static struct uwb_rsv *uwb_rsv_new_target(struct uwb_rc *rc,
540 * deny the request. 752 * deny the request.
541 */ 753 */
542 rsv->state = UWB_RSV_STATE_T_DENIED; 754 rsv->state = UWB_RSV_STATE_T_DENIED;
543 spin_lock(&rc->pal_lock); 755 mutex_lock(&rc->uwb_dev.mutex);
544 list_for_each_entry(pal, &rc->pals, node) { 756 list_for_each_entry(pal, &rc->pals, node) {
545 if (pal->new_rsv) 757 if (pal->new_rsv)
546 pal->new_rsv(rsv); 758 pal->new_rsv(pal, rsv);
547 if (rsv->state == UWB_RSV_STATE_T_ACCEPTED) 759 if (rsv->state == UWB_RSV_STATE_T_ACCEPTED)
548 break; 760 break;
549 } 761 }
550 spin_unlock(&rc->pal_lock); 762 mutex_unlock(&rc->uwb_dev.mutex);
551 763
552 list_add_tail(&rsv->rc_node, &rc->reservations); 764 list_add_tail(&rsv->rc_node, &rc->reservations);
553 state = rsv->state; 765 state = rsv->state;
554 rsv->state = UWB_RSV_STATE_NONE; 766 rsv->state = UWB_RSV_STATE_NONE;
555 uwb_rsv_set_state(rsv, state); 767
768 /* FIXME: do something sensible here */
769 if (state == UWB_RSV_STATE_T_ACCEPTED
770 && uwb_drp_avail_reserve_pending(rc, &rsv->mas) == -EBUSY) {
771 /* FIXME: do something sensible here */
772 } else {
773 uwb_rsv_set_state(rsv, state);
774 }
556 775
557 return rsv; 776 return rsv;
558} 777}
559 778
560/** 779/**
780 * uwb_rsv_get_usable_mas - get the bitmap of the usable MAS of a reservations
781 * @rsv: the reservation.
782 * @mas: returns the available MAS.
783 *
784 * The usable MAS of a reservation may be less than the negotiated MAS
785 * if alien BPs are present.
786 */
787void uwb_rsv_get_usable_mas(struct uwb_rsv *rsv, struct uwb_mas_bm *mas)
788{
789 bitmap_zero(mas->bm, UWB_NUM_MAS);
790 bitmap_andnot(mas->bm, rsv->mas.bm, rsv->rc->cnflt_alien_bitmap.bm, UWB_NUM_MAS);
791}
792EXPORT_SYMBOL_GPL(uwb_rsv_get_usable_mas);
793
794/**
561 * uwb_rsv_find - find a reservation for a received DRP IE. 795 * uwb_rsv_find - find a reservation for a received DRP IE.
562 * @rc: the radio controller 796 * @rc: the radio controller
563 * @src: source of the DRP IE 797 * @src: source of the DRP IE
@@ -596,8 +830,6 @@ static bool uwb_rsv_update_all(struct uwb_rc *rc)
596 bool ie_updated = false; 830 bool ie_updated = false;
597 831
598 list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) { 832 list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) {
599 if (rsv->expired)
600 uwb_drp_handle_timeout(rsv);
601 if (!rsv->ie_valid) { 833 if (!rsv->ie_valid) {
602 uwb_drp_ie_update(rsv); 834 uwb_drp_ie_update(rsv);
603 ie_updated = true; 835 ie_updated = true;
@@ -607,9 +839,47 @@ static bool uwb_rsv_update_all(struct uwb_rc *rc)
607 return ie_updated; 839 return ie_updated;
608} 840}
609 841
842void uwb_rsv_queue_update(struct uwb_rc *rc)
843{
844 unsigned long delay_us = UWB_MAS_LENGTH_US * UWB_MAS_PER_ZONE;
845
846 queue_delayed_work(rc->rsv_workq, &rc->rsv_update_work, usecs_to_jiffies(delay_us));
847}
848
849/**
850 * uwb_rsv_sched_update - schedule an update of the DRP IEs
851 * @rc: the radio controller.
852 *
853 * To improve performance and ensure correctness with [ECMA-368] the
854 * number of SET-DRP-IE commands that are done are limited.
855 *
856 * DRP IEs update come from two sources: DRP events from the hardware
857 * which all occur at the beginning of the superframe ('syncronous'
858 * events) and reservation establishment/termination requests from
859 * PALs or timers ('asynchronous' events).
860 *
861 * A delayed work ensures that all the synchronous events result in
862 * one SET-DRP-IE command.
863 *
864 * Additional logic (the set_drp_ie_pending and rsv_updated_postponed
865 * flags) will prevent an asynchrous event starting a SET-DRP-IE
866 * command if one is currently awaiting a response.
867 *
868 * FIXME: this does leave a window where an asynchrous event can delay
869 * the SET-DRP-IE for a synchronous event by one superframe.
870 */
610void uwb_rsv_sched_update(struct uwb_rc *rc) 871void uwb_rsv_sched_update(struct uwb_rc *rc)
611{ 872{
612 queue_work(rc->rsv_workq, &rc->rsv_update_work); 873 spin_lock(&rc->rsvs_lock);
874 if (!delayed_work_pending(&rc->rsv_update_work)) {
875 if (rc->set_drp_ie_pending > 0) {
876 rc->set_drp_ie_pending++;
877 goto unlock;
878 }
879 uwb_rsv_queue_update(rc);
880 }
881unlock:
882 spin_unlock(&rc->rsvs_lock);
613} 883}
614 884
615/* 885/*
@@ -618,7 +888,8 @@ void uwb_rsv_sched_update(struct uwb_rc *rc)
618 */ 888 */
619static void uwb_rsv_update_work(struct work_struct *work) 889static void uwb_rsv_update_work(struct work_struct *work)
620{ 890{
621 struct uwb_rc *rc = container_of(work, struct uwb_rc, rsv_update_work); 891 struct uwb_rc *rc = container_of(work, struct uwb_rc,
892 rsv_update_work.work);
622 bool ie_updated; 893 bool ie_updated;
623 894
624 mutex_lock(&rc->rsvs_mutex); 895 mutex_lock(&rc->rsvs_mutex);
@@ -630,25 +901,71 @@ static void uwb_rsv_update_work(struct work_struct *work)
630 ie_updated = true; 901 ie_updated = true;
631 } 902 }
632 903
633 if (ie_updated) 904 if (ie_updated && (rc->set_drp_ie_pending == 0))
634 uwb_rc_send_all_drp_ie(rc); 905 uwb_rc_send_all_drp_ie(rc);
635 906
636 mutex_unlock(&rc->rsvs_mutex); 907 mutex_unlock(&rc->rsvs_mutex);
637} 908}
638 909
910static void uwb_rsv_alien_bp_work(struct work_struct *work)
911{
912 struct uwb_rc *rc = container_of(work, struct uwb_rc,
913 rsv_alien_bp_work.work);
914 struct uwb_rsv *rsv;
915
916 mutex_lock(&rc->rsvs_mutex);
917
918 list_for_each_entry(rsv, &rc->reservations, rc_node) {
919 if (rsv->type != UWB_DRP_TYPE_ALIEN_BP) {
920 rsv->callback(rsv);
921 }
922 }
923
924 mutex_unlock(&rc->rsvs_mutex);
925}
926
639static void uwb_rsv_timer(unsigned long arg) 927static void uwb_rsv_timer(unsigned long arg)
640{ 928{
641 struct uwb_rsv *rsv = (struct uwb_rsv *)arg; 929 struct uwb_rsv *rsv = (struct uwb_rsv *)arg;
642 930
643 rsv->expired = true; 931 queue_work(rsv->rc->rsv_workq, &rsv->handle_timeout_work);
644 uwb_rsv_sched_update(rsv->rc); 932}
933
934/**
935 * uwb_rsv_remove_all - remove all reservations
936 * @rc: the radio controller
937 *
938 * A DRP IE update is not done.
939 */
940void uwb_rsv_remove_all(struct uwb_rc *rc)
941{
942 struct uwb_rsv *rsv, *t;
943
944 mutex_lock(&rc->rsvs_mutex);
945 list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) {
946 uwb_rsv_remove(rsv);
947 }
948 /* Cancel any postponed update. */
949 rc->set_drp_ie_pending = 0;
950 mutex_unlock(&rc->rsvs_mutex);
951
952 cancel_delayed_work_sync(&rc->rsv_update_work);
645} 953}
646 954
647void uwb_rsv_init(struct uwb_rc *rc) 955void uwb_rsv_init(struct uwb_rc *rc)
648{ 956{
649 INIT_LIST_HEAD(&rc->reservations); 957 INIT_LIST_HEAD(&rc->reservations);
958 INIT_LIST_HEAD(&rc->cnflt_alien_list);
650 mutex_init(&rc->rsvs_mutex); 959 mutex_init(&rc->rsvs_mutex);
651 INIT_WORK(&rc->rsv_update_work, uwb_rsv_update_work); 960 spin_lock_init(&rc->rsvs_lock);
961 INIT_DELAYED_WORK(&rc->rsv_update_work, uwb_rsv_update_work);
962 INIT_DELAYED_WORK(&rc->rsv_alien_bp_work, uwb_rsv_alien_bp_work);
963 rc->bow.can_reserve_extra_mases = true;
964 rc->bow.total_expired = 0;
965 rc->bow.window = UWB_DRP_BACKOFF_WIN_MIN >> 1;
966 init_timer(&rc->bow.timer);
967 rc->bow.timer.function = uwb_rsv_backoff_win_timer;
968 rc->bow.timer.data = (unsigned long)&rc->bow;
652 969
653 bitmap_complement(rc->uwb_dev.streams, rc->uwb_dev.streams, UWB_NUM_STREAMS); 970 bitmap_complement(rc->uwb_dev.streams, rc->uwb_dev.streams, UWB_NUM_STREAMS);
654} 971}
@@ -667,14 +984,6 @@ int uwb_rsv_setup(struct uwb_rc *rc)
667 984
668void uwb_rsv_cleanup(struct uwb_rc *rc) 985void uwb_rsv_cleanup(struct uwb_rc *rc)
669{ 986{
670 struct uwb_rsv *rsv, *t; 987 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); 988 destroy_workqueue(rc->rsv_workq);
680} 989}
diff --git a/drivers/uwb/umc-bus.c b/drivers/uwb/umc-bus.c
index 2d8d62d9f53e..5ad36164c13b 100644
--- a/drivers/uwb/umc-bus.c
+++ b/drivers/uwb/umc-bus.c
@@ -11,23 +11,48 @@
11#include <linux/uwb/umc.h> 11#include <linux/uwb/umc.h>
12#include <linux/pci.h> 12#include <linux/pci.h>
13 13
14static int umc_bus_unbind_helper(struct device *dev, void *data) 14static int umc_bus_pre_reset_helper(struct device *dev, void *data)
15{ 15{
16 struct device *parent = data; 16 int ret = 0;
17 17
18 if (dev->parent == parent && dev->driver) 18 if (dev->driver) {
19 device_release_driver(dev); 19 struct umc_dev *umc = to_umc_dev(dev);
20 return 0; 20 struct umc_driver *umc_drv = to_umc_driver(dev->driver);
21
22 if (umc_drv->pre_reset)
23 ret = umc_drv->pre_reset(umc);
24 else
25 device_release_driver(dev);
26 }
27 return ret;
28}
29
30static int umc_bus_post_reset_helper(struct device *dev, void *data)
31{
32 int ret = 0;
33
34 if (dev->driver) {
35 struct umc_dev *umc = to_umc_dev(dev);
36 struct umc_driver *umc_drv = to_umc_driver(dev->driver);
37
38 if (umc_drv->post_reset)
39 ret = umc_drv->post_reset(umc);
40 } else
41 ret = device_attach(dev);
42
43 return ret;
21} 44}
22 45
23/** 46/**
24 * umc_controller_reset - reset the whole UMC controller 47 * umc_controller_reset - reset the whole UMC controller
25 * @umc: the UMC device for the radio controller. 48 * @umc: the UMC device for the radio controller.
26 * 49 *
27 * Drivers will be unbound from all UMC devices belonging to the 50 * Drivers or all capabilities of the controller will have their
28 * controller and then the radio controller will be rebound. The 51 * pre_reset methods called or be unbound from their device. Then all
29 * radio controller is expected to do a full hardware reset when it is 52 * post_reset methods will be called or the drivers will be rebound.
30 * probed. 53 *
54 * Radio controllers must provide pre_reset and post_reset methods and
55 * reset the hardware in their start method.
31 * 56 *
32 * If this is called while a probe() or remove() is in progress it 57 * If this is called while a probe() or remove() is in progress it
33 * will return -EAGAIN and not perform the reset. 58 * will return -EAGAIN and not perform the reset.
@@ -35,14 +60,13 @@ static int umc_bus_unbind_helper(struct device *dev, void *data)
35int umc_controller_reset(struct umc_dev *umc) 60int umc_controller_reset(struct umc_dev *umc)
36{ 61{
37 struct device *parent = umc->dev.parent; 62 struct device *parent = umc->dev.parent;
38 int ret; 63 int ret = 0;
39 64
40 if (down_trylock(&parent->sem)) 65 if(down_trylock(&parent->sem))
41 return -EAGAIN; 66 return -EAGAIN;
42 bus_for_each_dev(&umc_bus_type, NULL, parent, umc_bus_unbind_helper); 67 ret = device_for_each_child(parent, parent, umc_bus_pre_reset_helper);
43 ret = device_attach(&umc->dev); 68 if (ret >= 0)
44 if (ret == 1) 69 device_for_each_child(parent, parent, umc_bus_post_reset_helper);
45 ret = 0;
46 up(&parent->sem); 70 up(&parent->sem);
47 71
48 return ret; 72 return ret;
@@ -75,10 +99,10 @@ static int umc_bus_rescan_helper(struct device *dev, void *data)
75 if (!dev->driver) 99 if (!dev->driver)
76 ret = device_attach(dev); 100 ret = device_attach(dev);
77 101
78 return ret < 0 ? ret : 0; 102 return ret;
79} 103}
80 104
81static void umc_bus_rescan(void) 105static void umc_bus_rescan(struct device *parent)
82{ 106{
83 int err; 107 int err;
84 108
@@ -86,7 +110,7 @@ static void umc_bus_rescan(void)
86 * We can't use bus_rescan_devices() here as it deadlocks when 110 * We can't use bus_rescan_devices() here as it deadlocks when
87 * it tries to retake the dev->parent semaphore. 111 * it tries to retake the dev->parent semaphore.
88 */ 112 */
89 err = bus_for_each_dev(&umc_bus_type, NULL, NULL, umc_bus_rescan_helper); 113 err = device_for_each_child(parent, NULL, umc_bus_rescan_helper);
90 if (err < 0) 114 if (err < 0)
91 printk(KERN_WARNING "%s: rescan of bus failed: %d\n", 115 printk(KERN_WARNING "%s: rescan of bus failed: %d\n",
92 KBUILD_MODNAME, err); 116 KBUILD_MODNAME, err);
@@ -120,7 +144,7 @@ static int umc_device_probe(struct device *dev)
120 if (err) 144 if (err)
121 put_device(dev); 145 put_device(dev);
122 else 146 else
123 umc_bus_rescan(); 147 umc_bus_rescan(dev->parent);
124 148
125 return err; 149 return err;
126} 150}
diff --git a/drivers/uwb/umc-dev.c b/drivers/uwb/umc-dev.c
index aa44e1c1a102..1fc7d8270bb8 100644
--- a/drivers/uwb/umc-dev.c
+++ b/drivers/uwb/umc-dev.c
@@ -7,8 +7,6 @@
7 */ 7 */
8#include <linux/kernel.h> 8#include <linux/kernel.h>
9#include <linux/uwb/umc.h> 9#include <linux/uwb/umc.h>
10#define D_LOCAL 0
11#include <linux/uwb/debug.h>
12 10
13static void umc_device_release(struct device *dev) 11static void umc_device_release(struct device *dev)
14{ 12{
@@ -31,8 +29,7 @@ struct umc_dev *umc_device_create(struct device *parent, int n)
31 29
32 umc = kzalloc(sizeof(struct umc_dev), GFP_KERNEL); 30 umc = kzalloc(sizeof(struct umc_dev), GFP_KERNEL);
33 if (umc) { 31 if (umc) {
34 snprintf(umc->dev.bus_id, sizeof(umc->dev.bus_id), "%s-%d", 32 dev_set_name(&umc->dev, "%s-%d", dev_name(parent), n);
35 parent->bus_id, n);
36 umc->dev.parent = parent; 33 umc->dev.parent = parent;
37 umc->dev.bus = &umc_bus_type; 34 umc->dev.bus = &umc_bus_type;
38 umc->dev.release = umc_device_release; 35 umc->dev.release = umc_device_release;
@@ -54,8 +51,6 @@ int umc_device_register(struct umc_dev *umc)
54{ 51{
55 int err; 52 int err;
56 53
57 d_fnstart(3, &umc->dev, "(umc_dev %p)\n", umc);
58
59 err = request_resource(umc->resource.parent, &umc->resource); 54 err = request_resource(umc->resource.parent, &umc->resource);
60 if (err < 0) { 55 if (err < 0) {
61 dev_err(&umc->dev, "can't allocate resource range " 56 dev_err(&umc->dev, "can't allocate resource range "
@@ -69,13 +64,11 @@ int umc_device_register(struct umc_dev *umc)
69 err = device_register(&umc->dev); 64 err = device_register(&umc->dev);
70 if (err < 0) 65 if (err < 0)
71 goto error_device_register; 66 goto error_device_register;
72 d_fnend(3, &umc->dev, "(umc_dev %p) = 0\n", umc);
73 return 0; 67 return 0;
74 68
75error_device_register: 69error_device_register:
76 release_resource(&umc->resource); 70 release_resource(&umc->resource);
77error_request_resource: 71error_request_resource:
78 d_fnend(3, &umc->dev, "(umc_dev %p) = %d\n", umc, err);
79 return err; 72 return err;
80} 73}
81EXPORT_SYMBOL_GPL(umc_device_register); 74EXPORT_SYMBOL_GPL(umc_device_register);
@@ -95,10 +88,8 @@ void umc_device_unregister(struct umc_dev *umc)
95 if (!umc) 88 if (!umc)
96 return; 89 return;
97 dev = get_device(&umc->dev); 90 dev = get_device(&umc->dev);
98 d_fnstart(3, dev, "(umc_dev %p)\n", umc);
99 device_unregister(&umc->dev); 91 device_unregister(&umc->dev);
100 release_resource(&umc->resource); 92 release_resource(&umc->resource);
101 d_fnend(3, dev, "(umc_dev %p) = void\n", umc);
102 put_device(dev); 93 put_device(dev);
103} 94}
104EXPORT_SYMBOL_GPL(umc_device_unregister); 95EXPORT_SYMBOL_GPL(umc_device_unregister);
diff --git a/drivers/uwb/uwb-debug.c b/drivers/uwb/uwb-debug.c
index 6d232c35d07d..4a42993700c1 100644
--- a/drivers/uwb/uwb-debug.c
+++ b/drivers/uwb/uwb-debug.c
@@ -4,6 +4,7 @@
4 * 4 *
5 * Copyright (C) 2005-2006 Intel Corporation 5 * Copyright (C) 2005-2006 Intel Corporation
6 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> 6 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
7 * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
7 * 8 *
8 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version 10 * modify it under the terms of the GNU General Public License version
@@ -33,31 +34,9 @@
33#include <linux/seq_file.h> 34#include <linux/seq_file.h>
34 35
35#include <linux/uwb/debug-cmd.h> 36#include <linux/uwb/debug-cmd.h>
36#define D_LOCAL 0
37#include <linux/uwb/debug.h>
38 37
39#include "uwb-internal.h" 38#include "uwb-internal.h"
40 39
41void dump_bytes(struct device *dev, const void *_buf, size_t rsize)
42{
43 const char *buf = _buf;
44 char line[32];
45 size_t offset = 0;
46 int cnt, cnt2;
47 for (cnt = 0; cnt < rsize; cnt += 8) {
48 size_t rtop = rsize - cnt < 8 ? rsize - cnt : 8;
49 for (offset = cnt2 = 0; cnt2 < rtop; cnt2++) {
50 offset += scnprintf(line + offset, sizeof(line) - offset,
51 "%02x ", buf[cnt + cnt2] & 0xff);
52 }
53 if (dev)
54 dev_info(dev, "%s\n", line);
55 else
56 printk(KERN_INFO "%s\n", line);
57 }
58}
59EXPORT_SYMBOL_GPL(dump_bytes);
60
61/* 40/*
62 * Debug interface 41 * Debug interface
63 * 42 *
@@ -84,26 +63,23 @@ struct uwb_dbg {
84 struct dentry *reservations_f; 63 struct dentry *reservations_f;
85 struct dentry *accept_f; 64 struct dentry *accept_f;
86 struct dentry *drp_avail_f; 65 struct dentry *drp_avail_f;
66 spinlock_t list_lock;
87}; 67};
88 68
89static struct dentry *root_dir; 69static struct dentry *root_dir;
90 70
91static void uwb_dbg_rsv_cb(struct uwb_rsv *rsv) 71static void uwb_dbg_rsv_cb(struct uwb_rsv *rsv)
92{ 72{
93 struct uwb_rc *rc = rsv->rc; 73 struct uwb_dbg *dbg = rsv->pal_priv;
94 struct device *dev = &rc->uwb_dev.dev;
95 struct uwb_dev_addr devaddr;
96 char owner[UWB_ADDR_STRSIZE], target[UWB_ADDR_STRSIZE];
97
98 uwb_dev_addr_print(owner, sizeof(owner), &rsv->owner->dev_addr);
99 if (rsv->target.type == UWB_RSV_TARGET_DEV)
100 devaddr = rsv->target.dev->dev_addr;
101 else
102 devaddr = rsv->target.devaddr;
103 uwb_dev_addr_print(target, sizeof(target), &devaddr);
104 74
105 dev_dbg(dev, "debug: rsv %s -> %s: %s\n", 75 uwb_rsv_dump("debug", rsv);
106 owner, target, uwb_rsv_state_str(rsv->state)); 76
77 if (rsv->state == UWB_RSV_STATE_NONE) {
78 spin_lock(&dbg->list_lock);
79 list_del(&rsv->pal_node);
80 spin_unlock(&dbg->list_lock);
81 uwb_rsv_destroy(rsv);
82 }
107} 83}
108 84
109static int cmd_rsv_establish(struct uwb_rc *rc, 85static int cmd_rsv_establish(struct uwb_rc *rc,
@@ -119,26 +95,27 @@ static int cmd_rsv_establish(struct uwb_rc *rc,
119 if (target == NULL) 95 if (target == NULL)
120 return -ENODEV; 96 return -ENODEV;
121 97
122 rsv = uwb_rsv_create(rc, uwb_dbg_rsv_cb, NULL); 98 rsv = uwb_rsv_create(rc, uwb_dbg_rsv_cb, rc->dbg);
123 if (rsv == NULL) { 99 if (rsv == NULL) {
124 uwb_dev_put(target); 100 uwb_dev_put(target);
125 return -ENOMEM; 101 return -ENOMEM;
126 } 102 }
127 103
128 rsv->owner = &rc->uwb_dev; 104 rsv->target.type = UWB_RSV_TARGET_DEV;
129 rsv->target.type = UWB_RSV_TARGET_DEV; 105 rsv->target.dev = target;
130 rsv->target.dev = target; 106 rsv->type = cmd->type;
131 rsv->type = cmd->type; 107 rsv->max_mas = cmd->max_mas;
132 rsv->max_mas = cmd->max_mas; 108 rsv->min_mas = cmd->min_mas;
133 rsv->min_mas = cmd->min_mas; 109 rsv->max_interval = cmd->max_interval;
134 rsv->sparsity = cmd->sparsity;
135 110
136 ret = uwb_rsv_establish(rsv); 111 ret = uwb_rsv_establish(rsv);
137 if (ret) 112 if (ret)
138 uwb_rsv_destroy(rsv); 113 uwb_rsv_destroy(rsv);
139 else 114 else {
115 spin_lock(&(rc->dbg)->list_lock);
140 list_add_tail(&rsv->pal_node, &rc->dbg->rsvs); 116 list_add_tail(&rsv->pal_node, &rc->dbg->rsvs);
141 117 spin_unlock(&(rc->dbg)->list_lock);
118 }
142 return ret; 119 return ret;
143} 120}
144 121
@@ -148,21 +125,40 @@ static int cmd_rsv_terminate(struct uwb_rc *rc,
148 struct uwb_rsv *rsv, *found = NULL; 125 struct uwb_rsv *rsv, *found = NULL;
149 int i = 0; 126 int i = 0;
150 127
128 spin_lock(&(rc->dbg)->list_lock);
129
151 list_for_each_entry(rsv, &rc->dbg->rsvs, pal_node) { 130 list_for_each_entry(rsv, &rc->dbg->rsvs, pal_node) {
152 if (i == cmd->index) { 131 if (i == cmd->index) {
153 found = rsv; 132 found = rsv;
133 uwb_rsv_get(found);
154 break; 134 break;
155 } 135 }
136 i++;
156 } 137 }
138
139 spin_unlock(&(rc->dbg)->list_lock);
140
157 if (!found) 141 if (!found)
158 return -EINVAL; 142 return -EINVAL;
159 143
160 list_del(&found->pal_node);
161 uwb_rsv_terminate(found); 144 uwb_rsv_terminate(found);
145 uwb_rsv_put(found);
162 146
163 return 0; 147 return 0;
164} 148}
165 149
150static int cmd_ie_add(struct uwb_rc *rc, struct uwb_dbg_cmd_ie *ie_to_add)
151{
152 return uwb_rc_ie_add(rc,
153 (const struct uwb_ie_hdr *) ie_to_add->data,
154 ie_to_add->len);
155}
156
157static int cmd_ie_rm(struct uwb_rc *rc, struct uwb_dbg_cmd_ie *ie_to_rm)
158{
159 return uwb_rc_ie_rm(rc, ie_to_rm->data[0]);
160}
161
166static int command_open(struct inode *inode, struct file *file) 162static int command_open(struct inode *inode, struct file *file)
167{ 163{
168 file->private_data = inode->i_private; 164 file->private_data = inode->i_private;
@@ -175,8 +171,8 @@ static ssize_t command_write(struct file *file, const char __user *buf,
175{ 171{
176 struct uwb_rc *rc = file->private_data; 172 struct uwb_rc *rc = file->private_data;
177 struct uwb_dbg_cmd cmd; 173 struct uwb_dbg_cmd cmd;
178 int ret; 174 int ret = 0;
179 175
180 if (len != sizeof(struct uwb_dbg_cmd)) 176 if (len != sizeof(struct uwb_dbg_cmd))
181 return -EINVAL; 177 return -EINVAL;
182 178
@@ -190,6 +186,18 @@ static ssize_t command_write(struct file *file, const char __user *buf,
190 case UWB_DBG_CMD_RSV_TERMINATE: 186 case UWB_DBG_CMD_RSV_TERMINATE:
191 ret = cmd_rsv_terminate(rc, &cmd.rsv_terminate); 187 ret = cmd_rsv_terminate(rc, &cmd.rsv_terminate);
192 break; 188 break;
189 case UWB_DBG_CMD_IE_ADD:
190 ret = cmd_ie_add(rc, &cmd.ie_add);
191 break;
192 case UWB_DBG_CMD_IE_RM:
193 ret = cmd_ie_rm(rc, &cmd.ie_rm);
194 break;
195 case UWB_DBG_CMD_RADIO_START:
196 ret = uwb_radio_start(&rc->dbg->pal);
197 break;
198 case UWB_DBG_CMD_RADIO_STOP:
199 uwb_radio_stop(&rc->dbg->pal);
200 break;
193 default: 201 default:
194 return -EINVAL; 202 return -EINVAL;
195 } 203 }
@@ -283,12 +291,26 @@ static struct file_operations drp_avail_fops = {
283 .owner = THIS_MODULE, 291 .owner = THIS_MODULE,
284}; 292};
285 293
286static void uwb_dbg_new_rsv(struct uwb_rsv *rsv) 294static void uwb_dbg_channel_changed(struct uwb_pal *pal, int channel)
295{
296 struct device *dev = &pal->rc->uwb_dev.dev;
297
298 if (channel > 0)
299 dev_info(dev, "debug: channel %d started\n", channel);
300 else
301 dev_info(dev, "debug: channel stopped\n");
302}
303
304static void uwb_dbg_new_rsv(struct uwb_pal *pal, struct uwb_rsv *rsv)
287{ 305{
288 struct uwb_rc *rc = rsv->rc; 306 struct uwb_dbg *dbg = container_of(pal, struct uwb_dbg, pal);
289 307
290 if (rc->dbg->accept) 308 if (dbg->accept) {
291 uwb_rsv_accept(rsv, uwb_dbg_rsv_cb, NULL); 309 spin_lock(&dbg->list_lock);
310 list_add_tail(&rsv->pal_node, &dbg->rsvs);
311 spin_unlock(&dbg->list_lock);
312 uwb_rsv_accept(rsv, uwb_dbg_rsv_cb, dbg);
313 }
292} 314}
293 315
294/** 316/**
@@ -302,10 +324,14 @@ void uwb_dbg_add_rc(struct uwb_rc *rc)
302 return; 324 return;
303 325
304 INIT_LIST_HEAD(&rc->dbg->rsvs); 326 INIT_LIST_HEAD(&rc->dbg->rsvs);
327 spin_lock_init(&(rc->dbg)->list_lock);
305 328
306 uwb_pal_init(&rc->dbg->pal); 329 uwb_pal_init(&rc->dbg->pal);
330 rc->dbg->pal.rc = rc;
331 rc->dbg->pal.channel_changed = uwb_dbg_channel_changed;
307 rc->dbg->pal.new_rsv = uwb_dbg_new_rsv; 332 rc->dbg->pal.new_rsv = uwb_dbg_new_rsv;
308 uwb_pal_register(rc, &rc->dbg->pal); 333 uwb_pal_register(&rc->dbg->pal);
334
309 if (root_dir) { 335 if (root_dir) {
310 rc->dbg->root_d = debugfs_create_dir(dev_name(&rc->uwb_dev.dev), 336 rc->dbg->root_d = debugfs_create_dir(dev_name(&rc->uwb_dev.dev),
311 root_dir); 337 root_dir);
@@ -325,7 +351,7 @@ void uwb_dbg_add_rc(struct uwb_rc *rc)
325} 351}
326 352
327/** 353/**
328 * uwb_dbg_add_rc - remove a radio controller's debug interface 354 * uwb_dbg_del_rc - remove a radio controller's debug interface
329 * @rc: the radio controller 355 * @rc: the radio controller
330 */ 356 */
331void uwb_dbg_del_rc(struct uwb_rc *rc) 357void uwb_dbg_del_rc(struct uwb_rc *rc)
@@ -336,10 +362,10 @@ void uwb_dbg_del_rc(struct uwb_rc *rc)
336 return; 362 return;
337 363
338 list_for_each_entry_safe(rsv, t, &rc->dbg->rsvs, pal_node) { 364 list_for_each_entry_safe(rsv, t, &rc->dbg->rsvs, pal_node) {
339 uwb_rsv_destroy(rsv); 365 uwb_rsv_terminate(rsv);
340 } 366 }
341 367
342 uwb_pal_unregister(rc, &rc->dbg->pal); 368 uwb_pal_unregister(&rc->dbg->pal);
343 369
344 if (root_dir) { 370 if (root_dir) {
345 debugfs_remove(rc->dbg->drp_avail_f); 371 debugfs_remove(rc->dbg->drp_avail_f);
@@ -365,3 +391,16 @@ void uwb_dbg_exit(void)
365{ 391{
366 debugfs_remove(root_dir); 392 debugfs_remove(root_dir);
367} 393}
394
395/**
396 * uwb_dbg_create_pal_dir - create a debugfs directory for a PAL
397 * @pal: The PAL.
398 */
399struct dentry *uwb_dbg_create_pal_dir(struct uwb_pal *pal)
400{
401 struct uwb_rc *rc = pal->rc;
402
403 if (root_dir && rc->dbg && rc->dbg->root_d && pal->name)
404 return debugfs_create_dir(pal->name, rc->dbg->root_d);
405 return NULL;
406}
diff --git a/drivers/uwb/uwb-internal.h b/drivers/uwb/uwb-internal.h
index 2ad307d12961..d5bcfc1c227a 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
@@ -92,6 +92,12 @@ extern const char *uwb_rc_strerror(unsigned code);
92 92
93struct uwb_rc_neh; 93struct uwb_rc_neh;
94 94
95extern int uwb_rc_cmd_async(struct uwb_rc *rc, const char *cmd_name,
96 struct uwb_rccb *cmd, size_t cmd_size,
97 u8 expected_type, u16 expected_event,
98 uwb_rc_cmd_cb_f cb, void *arg);
99
100
95void uwb_rc_neh_create(struct uwb_rc *rc); 101void uwb_rc_neh_create(struct uwb_rc *rc);
96void uwb_rc_neh_destroy(struct uwb_rc *rc); 102void uwb_rc_neh_destroy(struct uwb_rc *rc);
97 103
@@ -106,7 +112,69 @@ void uwb_rc_neh_put(struct uwb_rc_neh *neh);
106extern int uwb_est_create(void); 112extern int uwb_est_create(void);
107extern void uwb_est_destroy(void); 113extern void uwb_est_destroy(void);
108 114
115/*
116 * UWB conflicting alien reservations
117 */
118struct uwb_cnflt_alien {
119 struct uwb_rc *rc;
120 struct list_head rc_node;
121 struct uwb_mas_bm mas;
122 struct timer_list timer;
123 struct work_struct cnflt_update_work;
124};
125
126enum uwb_uwb_rsv_alloc_result {
127 UWB_RSV_ALLOC_FOUND = 0,
128 UWB_RSV_ALLOC_NOT_FOUND,
129};
130
131enum uwb_rsv_mas_status {
132 UWB_RSV_MAS_NOT_AVAIL = 1,
133 UWB_RSV_MAS_SAFE,
134 UWB_RSV_MAS_UNSAFE,
135};
136
137struct uwb_rsv_col_set_info {
138 unsigned char start_col;
139 unsigned char interval;
140 unsigned char safe_mas_per_col;
141 unsigned char unsafe_mas_per_col;
142};
143
144struct uwb_rsv_col_info {
145 unsigned char max_avail_safe;
146 unsigned char max_avail_unsafe;
147 unsigned char highest_mas[UWB_MAS_PER_ZONE];
148 struct uwb_rsv_col_set_info csi;
149};
150
151struct uwb_rsv_row_info {
152 unsigned char avail[UWB_MAS_PER_ZONE];
153 unsigned char free_rows;
154 unsigned char used_rows;
155};
156
157/*
158 * UWB find allocation
159 */
160struct uwb_rsv_alloc_info {
161 unsigned char bm[UWB_MAS_PER_ZONE * UWB_NUM_ZONES];
162 struct uwb_rsv_col_info ci[UWB_NUM_ZONES];
163 struct uwb_rsv_row_info ri;
164 struct uwb_mas_bm *not_available;
165 struct uwb_mas_bm *result;
166 int min_mas;
167 int max_mas;
168 int max_interval;
169 int total_allocated_mases;
170 int safe_allocated_mases;
171 int unsafe_allocated_mases;
172 int interval;
173};
109 174
175int uwb_rsv_find_best_allocation(struct uwb_rsv *rsv, struct uwb_mas_bm *available,
176 struct uwb_mas_bm *result);
177void uwb_rsv_handle_drp_avail_change(struct uwb_rc *rc);
110/* 178/*
111 * UWB Events & management daemon 179 * UWB Events & management daemon
112 */ 180 */
@@ -160,13 +228,14 @@ struct uwb_event {
160 }; 228 };
161}; 229};
162 230
163extern void uwbd_start(void); 231extern void uwbd_start(struct uwb_rc *rc);
164extern void uwbd_stop(void); 232extern void uwbd_stop(struct uwb_rc *rc);
165extern struct uwb_event *uwb_event_alloc(size_t, gfp_t gfp_mask); 233extern struct uwb_event *uwb_event_alloc(size_t, gfp_t gfp_mask);
166extern void uwbd_event_queue(struct uwb_event *); 234extern void uwbd_event_queue(struct uwb_event *);
167void uwbd_flush(struct uwb_rc *rc); 235void uwbd_flush(struct uwb_rc *rc);
168 236
169/* UWB event handlers */ 237/* UWB event handlers */
238extern int uwbd_evt_handle_rc_ie_rcv(struct uwb_event *);
170extern int uwbd_evt_handle_rc_beacon(struct uwb_event *); 239extern int uwbd_evt_handle_rc_beacon(struct uwb_event *);
171extern int uwbd_evt_handle_rc_beacon_size(struct uwb_event *); 240extern int uwbd_evt_handle_rc_beacon_size(struct uwb_event *);
172extern int uwbd_evt_handle_rc_bpoie_change(struct uwb_event *); 241extern int uwbd_evt_handle_rc_bpoie_change(struct uwb_event *);
@@ -193,15 +262,6 @@ int uwbd_evt_handle_rc_dev_addr_conflict(struct uwb_event *evt);
193 262
194extern unsigned long beacon_timeout_ms; 263extern unsigned long beacon_timeout_ms;
195 264
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/** 265/**
206 * Beacon cache entry 266 * Beacon cache entry
207 * 267 *
@@ -228,9 +288,6 @@ struct uwb_beca_e {
228struct uwb_beacon_frame; 288struct uwb_beacon_frame;
229extern ssize_t uwb_bce_print_IEs(struct uwb_dev *, struct uwb_beca_e *, 289extern ssize_t uwb_bce_print_IEs(struct uwb_dev *, struct uwb_beca_e *,
230 char *, size_t); 290 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 291
235extern void uwb_bce_kfree(struct kref *_bce); 292extern void uwb_bce_kfree(struct kref *_bce);
236static inline void uwb_bce_get(struct uwb_beca_e *bce) 293static inline void uwb_bce_get(struct uwb_beca_e *bce)
@@ -241,14 +298,19 @@ static inline void uwb_bce_put(struct uwb_beca_e *bce)
241{ 298{
242 kref_put(&bce->refcnt, uwb_bce_kfree); 299 kref_put(&bce->refcnt, uwb_bce_kfree);
243} 300}
244extern void uwb_beca_purge(void); 301extern void uwb_beca_purge(struct uwb_rc *rc);
245extern void uwb_beca_release(void); 302extern void uwb_beca_release(struct uwb_rc *rc);
246 303
247struct uwb_dev *uwb_dev_get_by_devaddr(struct uwb_rc *rc, 304struct uwb_dev *uwb_dev_get_by_devaddr(struct uwb_rc *rc,
248 const struct uwb_dev_addr *devaddr); 305 const struct uwb_dev_addr *devaddr);
249struct uwb_dev *uwb_dev_get_by_macaddr(struct uwb_rc *rc, 306struct uwb_dev *uwb_dev_get_by_macaddr(struct uwb_rc *rc,
250 const struct uwb_mac_addr *macaddr); 307 const struct uwb_mac_addr *macaddr);
251 308
309int uwb_radio_setup(struct uwb_rc *rc);
310void uwb_radio_reset_state(struct uwb_rc *rc);
311void uwb_radio_shutdown(struct uwb_rc *rc);
312int uwb_radio_force_channel(struct uwb_rc *rc, int channel);
313
252/* -- UWB Sysfs representation */ 314/* -- UWB Sysfs representation */
253extern struct class uwb_rc_class; 315extern struct class uwb_rc_class;
254extern struct device_attribute dev_attr_mac_address; 316extern struct device_attribute dev_attr_mac_address;
@@ -259,18 +321,29 @@ extern struct device_attribute dev_attr_scan;
259void uwb_rsv_init(struct uwb_rc *rc); 321void uwb_rsv_init(struct uwb_rc *rc);
260int uwb_rsv_setup(struct uwb_rc *rc); 322int uwb_rsv_setup(struct uwb_rc *rc);
261void uwb_rsv_cleanup(struct uwb_rc *rc); 323void uwb_rsv_cleanup(struct uwb_rc *rc);
324void uwb_rsv_remove_all(struct uwb_rc *rc);
325void uwb_rsv_get(struct uwb_rsv *rsv);
326void uwb_rsv_put(struct uwb_rsv *rsv);
327bool uwb_rsv_has_two_drp_ies(struct uwb_rsv *rsv);
328void uwb_rsv_dump(char *text, struct uwb_rsv *rsv);
329int uwb_rsv_try_move(struct uwb_rsv *rsv, struct uwb_mas_bm *available);
330void uwb_rsv_backoff_win_timer(unsigned long arg);
331void uwb_rsv_backoff_win_increment(struct uwb_rc *rc);
332int uwb_rsv_status(struct uwb_rsv *rsv);
333int uwb_rsv_companion_status(struct uwb_rsv *rsv);
262 334
263void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state); 335void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state);
264void uwb_rsv_remove(struct uwb_rsv *rsv); 336void uwb_rsv_remove(struct uwb_rsv *rsv);
265struct uwb_rsv *uwb_rsv_find(struct uwb_rc *rc, struct uwb_dev *src, 337struct uwb_rsv *uwb_rsv_find(struct uwb_rc *rc, struct uwb_dev *src,
266 struct uwb_ie_drp *drp_ie); 338 struct uwb_ie_drp *drp_ie);
267void uwb_rsv_sched_update(struct uwb_rc *rc); 339void uwb_rsv_sched_update(struct uwb_rc *rc);
340void uwb_rsv_queue_update(struct uwb_rc *rc);
268 341
269void uwb_drp_handle_timeout(struct uwb_rsv *rsv);
270int uwb_drp_ie_update(struct uwb_rsv *rsv); 342int uwb_drp_ie_update(struct uwb_rsv *rsv);
271void uwb_drp_ie_to_bm(struct uwb_mas_bm *bm, const struct uwb_ie_drp *drp_ie); 343void uwb_drp_ie_to_bm(struct uwb_mas_bm *bm, const struct uwb_ie_drp *drp_ie);
272 344
273void uwb_drp_avail_init(struct uwb_rc *rc); 345void uwb_drp_avail_init(struct uwb_rc *rc);
346void uwb_drp_available(struct uwb_rc *rc, struct uwb_mas_bm *avail);
274int uwb_drp_avail_reserve_pending(struct uwb_rc *rc, struct uwb_mas_bm *mas); 347int uwb_drp_avail_reserve_pending(struct uwb_rc *rc, struct uwb_mas_bm *mas);
275void uwb_drp_avail_reserve(struct uwb_rc *rc, struct uwb_mas_bm *mas); 348void uwb_drp_avail_reserve(struct uwb_rc *rc, struct uwb_mas_bm *mas);
276void uwb_drp_avail_release(struct uwb_rc *rc, struct uwb_mas_bm *mas); 349void uwb_drp_avail_release(struct uwb_rc *rc, struct uwb_mas_bm *mas);
@@ -289,8 +362,7 @@ void uwb_dbg_init(void);
289void uwb_dbg_exit(void); 362void uwb_dbg_exit(void);
290void uwb_dbg_add_rc(struct uwb_rc *rc); 363void uwb_dbg_add_rc(struct uwb_rc *rc);
291void uwb_dbg_del_rc(struct uwb_rc *rc); 364void uwb_dbg_del_rc(struct uwb_rc *rc);
292 365struct dentry *uwb_dbg_create_pal_dir(struct uwb_pal *pal);
293/* Workarounds for version specific stuff */
294 366
295static inline void uwb_dev_lock(struct uwb_dev *uwb_dev) 367static inline void uwb_dev_lock(struct uwb_dev *uwb_dev)
296{ 368{
diff --git a/drivers/uwb/uwbd.c b/drivers/uwb/uwbd.c
index 78908416e42c..57bd6bfef37e 100644
--- a/drivers/uwb/uwbd.c
+++ b/drivers/uwb/uwbd.c
@@ -68,17 +68,13 @@
68 * 68 *
69 * Handler functions are called normally uwbd_evt_handle_*(). 69 * Handler functions are called normally uwbd_evt_handle_*().
70 */ 70 */
71
72#include <linux/kthread.h> 71#include <linux/kthread.h>
73#include <linux/module.h> 72#include <linux/module.h>
74#include <linux/freezer.h> 73#include <linux/freezer.h>
75#include "uwb-internal.h"
76
77#define D_LOCAL 1
78#include <linux/uwb/debug.h>
79 74
75#include "uwb-internal.h"
80 76
81/** 77/*
82 * UWBD Event handler function signature 78 * UWBD Event handler function signature
83 * 79 *
84 * Return !0 if the event needs not to be freed (ie the handler 80 * Return !0 if the event needs not to be freed (ie the handler
@@ -101,9 +97,12 @@ struct uwbd_event {
101 const char *name; 97 const char *name;
102}; 98};
103 99
104/** Table of handlers for and properties of the UWBD Radio Control Events */ 100/* Table of handlers for and properties of the UWBD Radio Control Events */
105static 101static struct uwbd_event uwbd_urc_events[] = {
106struct uwbd_event uwbd_events[] = { 102 [UWB_RC_EVT_IE_RCV] = {
103 .handler = uwbd_evt_handle_rc_ie_rcv,
104 .name = "IE_RECEIVED"
105 },
107 [UWB_RC_EVT_BEACON] = { 106 [UWB_RC_EVT_BEACON] = {
108 .handler = uwbd_evt_handle_rc_beacon, 107 .handler = uwbd_evt_handle_rc_beacon,
109 .name = "BEACON_RECEIVED" 108 .name = "BEACON_RECEIVED"
@@ -142,23 +141,15 @@ struct uwbd_evt_type_handler {
142 size_t size; 141 size_t size;
143}; 142};
144 143
145#define UWBD_EVT_TYPE_HANDLER(n,a) { \ 144/* Table of handlers for each UWBD Event type. */
146 .name = (n), \ 145static struct uwbd_evt_type_handler uwbd_urc_evt_type_handlers[] = {
147 .uwbd_events = (a), \ 146 [UWB_RC_CET_GENERAL] = {
148 .size = sizeof(a)/sizeof((a)[0]) \ 147 .name = "URC",
149} 148 .uwbd_events = uwbd_urc_events,
150 149 .size = ARRAY_SIZE(uwbd_urc_events),
151 150 },
152/** Table of handlers for each UWBD Event type. */
153static
154struct uwbd_evt_type_handler uwbd_evt_type_handlers[] = {
155 [UWB_RC_CET_GENERAL] = UWBD_EVT_TYPE_HANDLER("RC", uwbd_events)
156}; 151};
157 152
158static const
159size_t uwbd_evt_type_handlers_len =
160 sizeof(uwbd_evt_type_handlers) / sizeof(uwbd_evt_type_handlers[0]);
161
162static const struct uwbd_event uwbd_message_handlers[] = { 153static const struct uwbd_event uwbd_message_handlers[] = {
163 [UWB_EVT_MSG_RESET] = { 154 [UWB_EVT_MSG_RESET] = {
164 .handler = uwbd_msg_handle_reset, 155 .handler = uwbd_msg_handle_reset,
@@ -166,9 +157,7 @@ static const struct uwbd_event uwbd_message_handlers[] = {
166 }, 157 },
167}; 158};
168 159
169static DEFINE_MUTEX(uwbd_event_mutex); 160/*
170
171/**
172 * Handle an URC event passed to the UWB Daemon 161 * Handle an URC event passed to the UWB Daemon
173 * 162 *
174 * @evt: the event to handle 163 * @evt: the event to handle
@@ -188,6 +177,7 @@ static DEFINE_MUTEX(uwbd_event_mutex);
188static 177static
189int uwbd_event_handle_urc(struct uwb_event *evt) 178int uwbd_event_handle_urc(struct uwb_event *evt)
190{ 179{
180 int result = -EINVAL;
191 struct uwbd_evt_type_handler *type_table; 181 struct uwbd_evt_type_handler *type_table;
192 uwbd_evt_handler_f handler; 182 uwbd_evt_handler_f handler;
193 u8 type, context; 183 u8 type, context;
@@ -197,26 +187,24 @@ int uwbd_event_handle_urc(struct uwb_event *evt)
197 event = le16_to_cpu(evt->notif.rceb->wEvent); 187 event = le16_to_cpu(evt->notif.rceb->wEvent);
198 context = evt->notif.rceb->bEventContext; 188 context = evt->notif.rceb->bEventContext;
199 189
200 if (type > uwbd_evt_type_handlers_len) { 190 if (type > ARRAY_SIZE(uwbd_urc_evt_type_handlers))
201 printk(KERN_ERR "UWBD: event type %u: unknown (too high)\n", type); 191 goto out;
202 return -EINVAL; 192 type_table = &uwbd_urc_evt_type_handlers[type];
203 } 193 if (type_table->uwbd_events == NULL)
204 type_table = &uwbd_evt_type_handlers[type]; 194 goto out;
205 if (type_table->uwbd_events == NULL) { 195 if (event > type_table->size)
206 printk(KERN_ERR "UWBD: event type %u: unknown\n", type); 196 goto out;
207 return -EINVAL;
208 }
209 if (event > type_table->size) {
210 printk(KERN_ERR "UWBD: event %s[%u]: unknown (too high)\n",
211 type_table->name, event);
212 return -EINVAL;
213 }
214 handler = type_table->uwbd_events[event].handler; 197 handler = type_table->uwbd_events[event].handler;
215 if (handler == NULL) { 198 if (handler == NULL)
216 printk(KERN_ERR "UWBD: event %s[%u]: unknown\n", type_table->name, event); 199 goto out;
217 return -EINVAL; 200
218 } 201 result = (*handler)(evt);
219 return (*handler)(evt); 202out:
203 if (result < 0)
204 dev_err(&evt->rc->uwb_dev.dev,
205 "UWBD: event 0x%02x/%04x/%02x, handling failed: %d\n",
206 type, event, context, result);
207 return result;
220} 208}
221 209
222static void uwbd_event_handle_message(struct uwb_event *evt) 210static void uwbd_event_handle_message(struct uwb_event *evt)
@@ -231,19 +219,10 @@ static void uwbd_event_handle_message(struct uwb_event *evt)
231 return; 219 return;
232 } 220 }
233 221
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); 222 result = uwbd_message_handlers[evt->message].handler(evt);
241 if (result < 0) 223 if (result < 0)
242 dev_err(&rc->uwb_dev.dev, "UWBD: '%s' message failed: %d\n", 224 dev_err(&rc->uwb_dev.dev, "UWBD: '%s' message failed: %d\n",
243 uwbd_message_handlers[evt->message].name, result); 225 uwbd_message_handlers[evt->message].name, result);
244
245 if (evt->message == UWB_EVT_MSG_RESET)
246 mutex_lock(&uwbd_event_mutex);
247} 226}
248 227
249static void uwbd_event_handle(struct uwb_event *evt) 228static void uwbd_event_handle(struct uwb_event *evt)
@@ -271,20 +250,6 @@ static void uwbd_event_handle(struct uwb_event *evt)
271 250
272 __uwb_rc_put(rc); /* for the __uwb_rc_get() in uwb_rc_notif_cb() */ 251 __uwb_rc_put(rc); /* for the __uwb_rc_get() in uwb_rc_notif_cb() */
273} 252}
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 253
289/** 254/**
290 * UWB Daemon 255 * UWB Daemon
@@ -298,65 +263,58 @@ static DEFINE_SPINLOCK(uwbd_event_list_lock);
298 * FIXME: should change so we don't have a 1HZ timer all the time, but 263 * FIXME: should change so we don't have a 1HZ timer all the time, but
299 * only if there are devices. 264 * only if there are devices.
300 */ 265 */
301static int uwbd(void *unused) 266static int uwbd(void *param)
302{ 267{
268 struct uwb_rc *rc = param;
303 unsigned long flags; 269 unsigned long flags;
304 struct list_head list = LIST_HEAD_INIT(list); 270 struct uwb_event *evt;
305 struct uwb_event *evt, *nxt;
306 int should_stop = 0; 271 int should_stop = 0;
272
307 while (1) { 273 while (1) {
308 wait_event_interruptible_timeout( 274 wait_event_interruptible_timeout(
309 uwbd_wq, 275 rc->uwbd.wq,
310 !list_empty(&uwbd_event_list) 276 !list_empty(&rc->uwbd.event_list)
311 || (should_stop = kthread_should_stop()), 277 || (should_stop = kthread_should_stop()),
312 HZ); 278 HZ);
313 if (should_stop) 279 if (should_stop)
314 break; 280 break;
315 try_to_freeze(); 281 try_to_freeze();
316 282
317 mutex_lock(&uwbd_event_mutex); 283 spin_lock_irqsave(&rc->uwbd.event_list_lock, flags);
318 spin_lock_irqsave(&uwbd_event_list_lock, flags); 284 if (!list_empty(&rc->uwbd.event_list)) {
319 list_splice_init(&uwbd_event_list, &list); 285 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); 286 list_del(&evt->list_node);
287 } else
288 evt = NULL;
289 spin_unlock_irqrestore(&rc->uwbd.event_list_lock, flags);
290
291 if (evt) {
323 uwbd_event_handle(evt); 292 uwbd_event_handle(evt);
324 kfree(evt); 293 kfree(evt);
325 } 294 }
326 mutex_unlock(&uwbd_event_mutex);
327 295
328 uwb_beca_purge(); /* Purge devices that left */ 296 uwb_beca_purge(rc); /* Purge devices that left */
329 } 297 }
330 return 0; 298 return 0;
331} 299}
332 300
333 301
334/** Start the UWB daemon */ 302/** Start the UWB daemon */
335void uwbd_start(void) 303void uwbd_start(struct uwb_rc *rc)
336{ 304{
337 uwbd_task = kthread_run(uwbd, NULL, "uwbd"); 305 rc->uwbd.task = kthread_run(uwbd, rc, "uwbd");
338 if (uwbd_task == NULL) 306 if (rc->uwbd.task == NULL)
339 printk(KERN_ERR "UWB: Cannot start management daemon; " 307 printk(KERN_ERR "UWB: Cannot start management daemon; "
340 "UWB won't work\n"); 308 "UWB won't work\n");
341 else 309 else
342 uwbd_pid = uwbd_task->pid; 310 rc->uwbd.pid = rc->uwbd.task->pid;
343} 311}
344 312
345/* Stop the UWB daemon and free any unprocessed events */ 313/* Stop the UWB daemon and free any unprocessed events */
346void uwbd_stop(void) 314void uwbd_stop(struct uwb_rc *rc)
347{ 315{
348 unsigned long flags; 316 kthread_stop(rc->uwbd.task);
349 struct uwb_event *evt, *nxt; 317 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} 318}
361 319
362/* 320/*
@@ -373,18 +331,20 @@ void uwbd_stop(void)
373 */ 331 */
374void uwbd_event_queue(struct uwb_event *evt) 332void uwbd_event_queue(struct uwb_event *evt)
375{ 333{
334 struct uwb_rc *rc = evt->rc;
376 unsigned long flags; 335 unsigned long flags;
377 spin_lock_irqsave(&uwbd_event_list_lock, flags); 336
378 if (uwbd_pid != 0) { 337 spin_lock_irqsave(&rc->uwbd.event_list_lock, flags);
379 list_add(&evt->list_node, &uwbd_event_list); 338 if (rc->uwbd.pid != 0) {
380 wake_up_all(&uwbd_wq); 339 list_add(&evt->list_node, &rc->uwbd.event_list);
340 wake_up_all(&rc->uwbd.wq);
381 } else { 341 } else {
382 __uwb_rc_put(evt->rc); 342 __uwb_rc_put(evt->rc);
383 if (evt->type == UWB_EVT_TYPE_NOTIF) 343 if (evt->type == UWB_EVT_TYPE_NOTIF)
384 kfree(evt->notif.rceb); 344 kfree(evt->notif.rceb);
385 kfree(evt); 345 kfree(evt);
386 } 346 }
387 spin_unlock_irqrestore(&uwbd_event_list_lock, flags); 347 spin_unlock_irqrestore(&rc->uwbd.event_list_lock, flags);
388 return; 348 return;
389} 349}
390 350
@@ -392,10 +352,8 @@ void uwbd_flush(struct uwb_rc *rc)
392{ 352{
393 struct uwb_event *evt, *nxt; 353 struct uwb_event *evt, *nxt;
394 354
395 mutex_lock(&uwbd_event_mutex); 355 spin_lock_irq(&rc->uwbd.event_list_lock);
396 356 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) { 357 if (evt->rc == rc) {
400 __uwb_rc_put(rc); 358 __uwb_rc_put(rc);
401 list_del(&evt->list_node); 359 list_del(&evt->list_node);
@@ -404,7 +362,5 @@ void uwbd_flush(struct uwb_rc *rc)
404 kfree(evt); 362 kfree(evt);
405 } 363 }
406 } 364 }
407 spin_unlock_irq(&uwbd_event_list_lock); 365 spin_unlock_irq(&rc->uwbd.event_list_lock);
408
409 mutex_unlock(&uwbd_event_mutex);
410} 366}
diff --git a/drivers/uwb/whc-rc.c b/drivers/uwb/whc-rc.c
index 1711deadb114..19a1dd129212 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>
@@ -49,10 +48,8 @@
49#include <linux/uwb.h> 48#include <linux/uwb.h>
50#include <linux/uwb/whci.h> 49#include <linux/uwb/whci.h>
51#include <linux/uwb/umc.h> 50#include <linux/uwb/umc.h>
52#include "uwb-internal.h"
53 51
54#define D_LOCAL 0 52#include "uwb-internal.h"
55#include <linux/uwb/debug.h>
56 53
57/** 54/**
58 * Descriptor for an instance of the UWB Radio Control Driver that 55 * Descriptor for an instance of the UWB Radio Control Driver that
@@ -98,13 +95,8 @@ static int whcrc_cmd(struct uwb_rc *uwb_rc,
98 struct device *dev = &whcrc->umc_dev->dev; 95 struct device *dev = &whcrc->umc_dev->dev;
99 u32 urccmd; 96 u32 urccmd;
100 97
101 d_fnstart(3, dev, "(%p, %p, %zu)\n", uwb_rc, cmd, cmd_size); 98 if (cmd_size >= 4096)
102 might_sleep(); 99 return -EINVAL;
103
104 if (cmd_size >= 4096) {
105 result = -E2BIG;
106 goto error;
107 }
108 100
109 /* 101 /*
110 * If the URC is halted, then the hardware has reset itself. 102 * If the URC is halted, then the hardware has reset itself.
@@ -115,16 +107,14 @@ static int whcrc_cmd(struct uwb_rc *uwb_rc,
115 if (le_readl(whcrc->rc_base + URCSTS) & URCSTS_HALTED) { 107 if (le_readl(whcrc->rc_base + URCSTS) & URCSTS_HALTED) {
116 dev_err(dev, "requesting reset of halted radio controller\n"); 108 dev_err(dev, "requesting reset of halted radio controller\n");
117 uwb_rc_reset_all(uwb_rc); 109 uwb_rc_reset_all(uwb_rc);
118 result = -EIO; 110 return -EIO;
119 goto error;
120 } 111 }
121 112
122 result = wait_event_timeout(whcrc->cmd_wq, 113 result = wait_event_timeout(whcrc->cmd_wq,
123 !(le_readl(whcrc->rc_base + URCCMD) & URCCMD_ACTIVE), HZ/2); 114 !(le_readl(whcrc->rc_base + URCCMD) & URCCMD_ACTIVE), HZ/2);
124 if (result == 0) { 115 if (result == 0) {
125 dev_err(dev, "device is not ready to execute commands\n"); 116 dev_err(dev, "device is not ready to execute commands\n");
126 result = -ETIMEDOUT; 117 return -ETIMEDOUT;
127 goto error;
128 } 118 }
129 119
130 memmove(whcrc->cmd_buf, cmd, cmd_size); 120 memmove(whcrc->cmd_buf, cmd, cmd_size);
@@ -137,10 +127,7 @@ static int whcrc_cmd(struct uwb_rc *uwb_rc,
137 whcrc->rc_base + URCCMD); 127 whcrc->rc_base + URCCMD);
138 spin_unlock(&whcrc->irq_lock); 128 spin_unlock(&whcrc->irq_lock);
139 129
140error: 130 return 0;
141 d_fnend(3, dev, "(%p, %p, %zu) = %d\n",
142 uwb_rc, cmd, cmd_size, result);
143 return result;
144} 131}
145 132
146static int whcrc_reset(struct uwb_rc *rc) 133static int whcrc_reset(struct uwb_rc *rc)
@@ -167,34 +154,25 @@ static int whcrc_reset(struct uwb_rc *rc)
167static 154static
168void whcrc_enable_events(struct whcrc *whcrc) 155void whcrc_enable_events(struct whcrc *whcrc)
169{ 156{
170 struct device *dev = &whcrc->umc_dev->dev;
171 u32 urccmd; 157 u32 urccmd;
172 158
173 d_fnstart(4, dev, "(whcrc %p)\n", whcrc);
174
175 le_writeq(whcrc->evt_dma_buf, whcrc->rc_base + URCEVTADDR); 159 le_writeq(whcrc->evt_dma_buf, whcrc->rc_base + URCEVTADDR);
176 160
177 spin_lock(&whcrc->irq_lock); 161 spin_lock(&whcrc->irq_lock);
178 urccmd = le_readl(whcrc->rc_base + URCCMD) & ~URCCMD_ACTIVE; 162 urccmd = le_readl(whcrc->rc_base + URCCMD) & ~URCCMD_ACTIVE;
179 le_writel(urccmd | URCCMD_EARV, whcrc->rc_base + URCCMD); 163 le_writel(urccmd | URCCMD_EARV, whcrc->rc_base + URCCMD);
180 spin_unlock(&whcrc->irq_lock); 164 spin_unlock(&whcrc->irq_lock);
181
182 d_fnend(4, dev, "(whcrc %p) = void\n", whcrc);
183} 165}
184 166
185static void whcrc_event_work(struct work_struct *work) 167static void whcrc_event_work(struct work_struct *work)
186{ 168{
187 struct whcrc *whcrc = container_of(work, struct whcrc, event_work); 169 struct whcrc *whcrc = container_of(work, struct whcrc, event_work);
188 struct device *dev = &whcrc->umc_dev->dev;
189 size_t size; 170 size_t size;
190 u64 urcevtaddr; 171 u64 urcevtaddr;
191 172
192 urcevtaddr = le_readq(whcrc->rc_base + URCEVTADDR); 173 urcevtaddr = le_readq(whcrc->rc_base + URCEVTADDR);
193 size = urcevtaddr & URCEVTADDR_OFFSET_MASK; 174 size = urcevtaddr & URCEVTADDR_OFFSET_MASK;
194 175
195 d_printf(3, dev, "received %zu octet event\n", size);
196 d_dump(4, dev, whcrc->evt_buf, size > 32 ? 32 : size);
197
198 uwb_rc_neh_grok(whcrc->uwb_rc, whcrc->evt_buf, size); 176 uwb_rc_neh_grok(whcrc->uwb_rc, whcrc->evt_buf, size);
199 whcrc_enable_events(whcrc); 177 whcrc_enable_events(whcrc);
200} 178}
@@ -217,22 +195,15 @@ irqreturn_t whcrc_irq_cb(int irq, void *_whcrc)
217 return IRQ_NONE; 195 return IRQ_NONE;
218 le_writel(urcsts & URCSTS_INT_MASK, whcrc->rc_base + URCSTS); 196 le_writel(urcsts & URCSTS_INT_MASK, whcrc->rc_base + URCSTS);
219 197
220 d_printf(4, dev, "acked 0x%08x, urcsts 0x%08x\n",
221 le_readl(whcrc->rc_base + URCSTS), urcsts);
222
223 if (urcsts & URCSTS_HSE) { 198 if (urcsts & URCSTS_HSE) {
224 dev_err(dev, "host system error -- hardware halted\n"); 199 dev_err(dev, "host system error -- hardware halted\n");
225 /* FIXME: do something sensible here */ 200 /* FIXME: do something sensible here */
226 goto out; 201 goto out;
227 } 202 }
228 if (urcsts & URCSTS_ER) { 203 if (urcsts & URCSTS_ER)
229 d_printf(3, dev, "ER: event ready\n");
230 schedule_work(&whcrc->event_work); 204 schedule_work(&whcrc->event_work);
231 } 205 if (urcsts & URCSTS_RCI)
232 if (urcsts & URCSTS_RCI) {
233 d_printf(3, dev, "RCI: ready to execute another command\n");
234 wake_up_all(&whcrc->cmd_wq); 206 wake_up_all(&whcrc->cmd_wq);
235 }
236out: 207out:
237 return IRQ_HANDLED; 208 return IRQ_HANDLED;
238} 209}
@@ -251,8 +222,7 @@ int whcrc_setup_rc_umc(struct whcrc *whcrc)
251 whcrc->area = umc_dev->resource.start; 222 whcrc->area = umc_dev->resource.start;
252 whcrc->rc_len = umc_dev->resource.end - umc_dev->resource.start + 1; 223 whcrc->rc_len = umc_dev->resource.end - umc_dev->resource.start + 1;
253 result = -EBUSY; 224 result = -EBUSY;
254 if (request_mem_region(whcrc->area, whcrc->rc_len, KBUILD_MODNAME) 225 if (request_mem_region(whcrc->area, whcrc->rc_len, KBUILD_MODNAME) == NULL) {
255 == NULL) {
256 dev_err(dev, "can't request URC region (%zu bytes @ 0x%lx): %d\n", 226 dev_err(dev, "can't request URC region (%zu bytes @ 0x%lx): %d\n",
257 whcrc->rc_len, whcrc->area, result); 227 whcrc->rc_len, whcrc->area, result);
258 goto error_request_region; 228 goto error_request_region;
@@ -287,8 +257,6 @@ int whcrc_setup_rc_umc(struct whcrc *whcrc)
287 dev_err(dev, "Can't allocate evt transfer buffer\n"); 257 dev_err(dev, "Can't allocate evt transfer buffer\n");
288 goto error_evt_buffer; 258 goto error_evt_buffer;
289 } 259 }
290 d_printf(3, dev, "UWB RC Interface: %zu bytes at 0x%p, irq %u\n",
291 whcrc->rc_len, whcrc->rc_base, umc_dev->irq);
292 return 0; 260 return 0;
293 261
294error_evt_buffer: 262error_evt_buffer:
@@ -333,47 +301,23 @@ void whcrc_release_rc_umc(struct whcrc *whcrc)
333static int whcrc_start_rc(struct uwb_rc *rc) 301static int whcrc_start_rc(struct uwb_rc *rc)
334{ 302{
335 struct whcrc *whcrc = rc->priv; 303 struct whcrc *whcrc = rc->priv;
336 int result = 0;
337 struct device *dev = &whcrc->umc_dev->dev; 304 struct device *dev = &whcrc->umc_dev->dev;
338 unsigned long start, duration;
339 305
340 /* Reset the thing */ 306 /* Reset the thing */
341 le_writel(URCCMD_RESET, whcrc->rc_base + URCCMD); 307 le_writel(URCCMD_RESET, whcrc->rc_base + URCCMD);
342 if (d_test(3))
343 start = jiffies;
344 if (whci_wait_for(dev, whcrc->rc_base + URCCMD, URCCMD_RESET, 0, 308 if (whci_wait_for(dev, whcrc->rc_base + URCCMD, URCCMD_RESET, 0,
345 5000, "device to reset at init") < 0) { 309 5000, "hardware reset") < 0)
346 result = -EBUSY; 310 return -EBUSY;
347 goto error;
348 } else if (d_test(3)) {
349 duration = jiffies - start;
350 if (duration > msecs_to_jiffies(40))
351 dev_err(dev, "Device took %ums to "
352 "reset. MAX expected: 40ms\n",
353 jiffies_to_msecs(duration));
354 }
355 311
356 /* Set the event buffer, start the controller (enable IRQs later) */ 312 /* Set the event buffer, start the controller (enable IRQs later) */
357 le_writel(0, whcrc->rc_base + URCINTR); 313 le_writel(0, whcrc->rc_base + URCINTR);
358 le_writel(URCCMD_RS, whcrc->rc_base + URCCMD); 314 le_writel(URCCMD_RS, whcrc->rc_base + URCCMD);
359 result = -ETIMEDOUT;
360 if (d_test(3))
361 start = jiffies;
362 if (whci_wait_for(dev, whcrc->rc_base + URCSTS, URCSTS_HALTED, 0, 315 if (whci_wait_for(dev, whcrc->rc_base + URCSTS, URCSTS_HALTED, 0,
363 5000, "device to start") < 0) 316 5000, "radio controller start") < 0)
364 goto error; 317 return -ETIMEDOUT;
365 if (d_test(3)) {
366 duration = jiffies - start;
367 if (duration > msecs_to_jiffies(40))
368 dev_err(dev, "Device took %ums to start. "
369 "MAX expected: 40ms\n",
370 jiffies_to_msecs(duration));
371 }
372 whcrc_enable_events(whcrc); 318 whcrc_enable_events(whcrc);
373 result = 0;
374 le_writel(URCINTR_EN_ALL, whcrc->rc_base + URCINTR); 319 le_writel(URCINTR_EN_ALL, whcrc->rc_base + URCINTR);
375error: 320 return 0;
376 return result;
377} 321}
378 322
379 323
@@ -395,7 +339,7 @@ void whcrc_stop_rc(struct uwb_rc *rc)
395 339
396 le_writel(0, whcrc->rc_base + URCCMD); 340 le_writel(0, whcrc->rc_base + URCCMD);
397 whci_wait_for(&umc_dev->dev, whcrc->rc_base + URCSTS, 341 whci_wait_for(&umc_dev->dev, whcrc->rc_base + URCSTS,
398 URCSTS_HALTED, 0, 40, "URCSTS.HALTED"); 342 URCSTS_HALTED, URCSTS_HALTED, 100, "radio controller stop");
399} 343}
400 344
401static void whcrc_init(struct whcrc *whcrc) 345static void whcrc_init(struct whcrc *whcrc)
@@ -421,7 +365,6 @@ int whcrc_probe(struct umc_dev *umc_dev)
421 struct whcrc *whcrc; 365 struct whcrc *whcrc;
422 struct device *dev = &umc_dev->dev; 366 struct device *dev = &umc_dev->dev;
423 367
424 d_fnstart(3, dev, "(umc_dev %p)\n", umc_dev);
425 result = -ENOMEM; 368 result = -ENOMEM;
426 uwb_rc = uwb_rc_alloc(); 369 uwb_rc = uwb_rc_alloc();
427 if (uwb_rc == NULL) { 370 if (uwb_rc == NULL) {
@@ -453,7 +396,6 @@ int whcrc_probe(struct umc_dev *umc_dev)
453 if (result < 0) 396 if (result < 0)
454 goto error_rc_add; 397 goto error_rc_add;
455 umc_set_drvdata(umc_dev, whcrc); 398 umc_set_drvdata(umc_dev, whcrc);
456 d_fnend(3, dev, "(umc_dev %p) = 0\n", umc_dev);
457 return 0; 399 return 0;
458 400
459error_rc_add: 401error_rc_add:
@@ -463,7 +405,6 @@ error_setup_rc_umc:
463error_alloc: 405error_alloc:
464 uwb_rc_put(uwb_rc); 406 uwb_rc_put(uwb_rc);
465error_rc_alloc: 407error_rc_alloc:
466 d_fnend(3, dev, "(umc_dev %p) = %d\n", umc_dev, result);
467 return result; 408 return result;
468} 409}
469 410
@@ -486,7 +427,24 @@ static void whcrc_remove(struct umc_dev *umc_dev)
486 whcrc_release_rc_umc(whcrc); 427 whcrc_release_rc_umc(whcrc);
487 kfree(whcrc); 428 kfree(whcrc);
488 uwb_rc_put(uwb_rc); 429 uwb_rc_put(uwb_rc);
489 d_printf(1, &umc_dev->dev, "freed whcrc %p\n", whcrc); 430}
431
432static int whcrc_pre_reset(struct umc_dev *umc)
433{
434 struct whcrc *whcrc = umc_get_drvdata(umc);
435 struct uwb_rc *uwb_rc = whcrc->uwb_rc;
436
437 uwb_rc_pre_reset(uwb_rc);
438 return 0;
439}
440
441static int whcrc_post_reset(struct umc_dev *umc)
442{
443 struct whcrc *whcrc = umc_get_drvdata(umc);
444 struct uwb_rc *uwb_rc = whcrc->uwb_rc;
445
446 uwb_rc_post_reset(uwb_rc);
447 return 0;
490} 448}
491 449
492/* PCI device ID's that we handle [so it gets loaded] */ 450/* PCI device ID's that we handle [so it gets loaded] */
@@ -497,10 +455,12 @@ static struct pci_device_id whcrc_id_table[] = {
497MODULE_DEVICE_TABLE(pci, whcrc_id_table); 455MODULE_DEVICE_TABLE(pci, whcrc_id_table);
498 456
499static struct umc_driver whcrc_driver = { 457static struct umc_driver whcrc_driver = {
500 .name = "whc-rc", 458 .name = "whc-rc",
501 .cap_id = UMC_CAP_ID_WHCI_RC, 459 .cap_id = UMC_CAP_ID_WHCI_RC,
502 .probe = whcrc_probe, 460 .probe = whcrc_probe,
503 .remove = whcrc_remove, 461 .remove = whcrc_remove,
462 .pre_reset = whcrc_pre_reset,
463 .post_reset = whcrc_post_reset,
504}; 464};
505 465
506static int __init whcrc_driver_init(void) 466static int __init whcrc_driver_init(void)
diff --git a/drivers/uwb/whci.c b/drivers/uwb/whci.c
index 3df2388f908f..1f8964ed9882 100644
--- a/drivers/uwb/whci.c
+++ b/drivers/uwb/whci.c
@@ -67,11 +67,11 @@ int whci_wait_for(struct device *dev, u32 __iomem *reg, u32 mask, u32 result,
67 val = le_readl(reg); 67 val = le_readl(reg);
68 if ((val & mask) == result) 68 if ((val & mask) == result)
69 break; 69 break;
70 msleep(10);
71 if (t >= max_ms) { 70 if (t >= max_ms) {
72 dev_err(dev, "timed out waiting for %s ", tag); 71 dev_err(dev, "%s timed out\n", tag);
73 return -ETIMEDOUT; 72 return -ETIMEDOUT;
74 } 73 }
74 msleep(10);
75 t += 10; 75 t += 10;
76 } 76 }
77 return 0; 77 return 0;
@@ -111,7 +111,7 @@ static int whci_add_cap(struct whci_card *card, int n)
111 + UWBCAPDATA_TO_OFFSET(capdata); 111 + UWBCAPDATA_TO_OFFSET(capdata);
112 umc->resource.end = umc->resource.start 112 umc->resource.end = umc->resource.start
113 + (n == 0 ? 0x20 : UWBCAPDATA_TO_SIZE(capdata)) - 1; 113 + (n == 0 ? 0x20 : UWBCAPDATA_TO_SIZE(capdata)) - 1;
114 umc->resource.name = umc->dev.bus_id; 114 umc->resource.name = dev_name(&umc->dev);
115 umc->resource.flags = card->pci->resource[bar].flags; 115 umc->resource.flags = card->pci->resource[bar].flags;
116 umc->resource.parent = &card->pci->resource[bar]; 116 umc->resource.parent = &card->pci->resource[bar];
117 umc->irq = card->pci->irq; 117 umc->irq = card->pci->irq;
diff --git a/drivers/uwb/wlp/eda.c b/drivers/uwb/wlp/eda.c
index 10985fa233cc..69e020039718 100644
--- a/drivers/uwb/wlp/eda.c
+++ b/drivers/uwb/wlp/eda.c
@@ -51,9 +51,7 @@
51 * the tag and address of the transmitting neighbor. 51 * the tag and address of the transmitting neighbor.
52 */ 52 */
53 53
54#define D_LOCAL 5
55#include <linux/netdevice.h> 54#include <linux/netdevice.h>
56#include <linux/uwb/debug.h>
57#include <linux/etherdevice.h> 55#include <linux/etherdevice.h>
58#include <linux/wlp.h> 56#include <linux/wlp.h>
59#include "wlp-internal.h" 57#include "wlp-internal.h"
@@ -304,7 +302,6 @@ int wlp_eda_for_virtual(struct wlp_eda *eda,
304{ 302{
305 int result = 0; 303 int result = 0;
306 struct wlp *wlp = container_of(eda, struct wlp, eda); 304 struct wlp *wlp = container_of(eda, struct wlp, eda);
307 struct device *dev = &wlp->rc->uwb_dev.dev;
308 struct wlp_eda_node *itr; 305 struct wlp_eda_node *itr;
309 unsigned long flags; 306 unsigned long flags;
310 int found = 0; 307 int found = 0;
@@ -313,26 +310,14 @@ int wlp_eda_for_virtual(struct wlp_eda *eda,
313 list_for_each_entry(itr, &eda->cache, list_node) { 310 list_for_each_entry(itr, &eda->cache, list_node) {
314 if (!memcmp(itr->virt_addr, virt_addr, 311 if (!memcmp(itr->virt_addr, virt_addr,
315 sizeof(itr->virt_addr))) { 312 sizeof(itr->virt_addr))) {
316 d_printf(6, dev, "EDA: looking for %pM hit %02x:%02x "
317 "wss %p tag 0x%02x state %u\n",
318 virt_addr,
319 itr->dev_addr.data[1],
320 itr->dev_addr.data[0], itr->wss,
321 itr->tag, itr->state);
322 result = (*function)(wlp, itr, priv); 313 result = (*function)(wlp, itr, priv);
323 *dev_addr = itr->dev_addr; 314 *dev_addr = itr->dev_addr;
324 found = 1; 315 found = 1;
325 break; 316 break;
326 } else 317 }
327 d_printf(6, dev, "EDA: looking for %pM against %pM miss\n",
328 virt_addr, itr->virt_addr);
329 } 318 }
330 if (!found) { 319 if (!found)
331 if (printk_ratelimit())
332 dev_err(dev, "EDA: Eth addr %pM not found.\n",
333 virt_addr);
334 result = -ENODEV; 320 result = -ENODEV;
335 }
336 spin_unlock_irqrestore(&eda->lock, flags); 321 spin_unlock_irqrestore(&eda->lock, flags);
337 return result; 322 return result;
338} 323}
diff --git a/drivers/uwb/wlp/messages.c b/drivers/uwb/wlp/messages.c
index a64cb8241713..aa42fcee4c4f 100644
--- a/drivers/uwb/wlp/messages.c
+++ b/drivers/uwb/wlp/messages.c
@@ -24,8 +24,7 @@
24 */ 24 */
25 25
26#include <linux/wlp.h> 26#include <linux/wlp.h>
27#define D_LOCAL 6 27
28#include <linux/uwb/debug.h>
29#include "wlp-internal.h" 28#include "wlp-internal.h"
30 29
31static 30static
@@ -105,24 +104,18 @@ static inline void wlp_set_attr_hdr(struct wlp_attr_hdr *hdr, unsigned type,
105#define wlp_set(type, type_code, name) \ 104#define wlp_set(type, type_code, name) \
106static size_t wlp_set_##name(struct wlp_attr_##name *attr, type value) \ 105static size_t wlp_set_##name(struct wlp_attr_##name *attr, type value) \
107{ \ 106{ \
108 d_fnstart(6, NULL, "(attribute %p)\n", attr); \
109 wlp_set_attr_hdr(&attr->hdr, type_code, \ 107 wlp_set_attr_hdr(&attr->hdr, type_code, \
110 sizeof(*attr) - sizeof(struct wlp_attr_hdr)); \ 108 sizeof(*attr) - sizeof(struct wlp_attr_hdr)); \
111 attr->name = value; \ 109 attr->name = value; \
112 d_dump(6, NULL, attr, sizeof(*attr)); \
113 d_fnend(6, NULL, "(attribute %p)\n", attr); \
114 return sizeof(*attr); \ 110 return sizeof(*attr); \
115} 111}
116 112
117#define wlp_pset(type, type_code, name) \ 113#define wlp_pset(type, type_code, name) \
118static size_t wlp_set_##name(struct wlp_attr_##name *attr, type value) \ 114static size_t wlp_set_##name(struct wlp_attr_##name *attr, type value) \
119{ \ 115{ \
120 d_fnstart(6, NULL, "(attribute %p)\n", attr); \
121 wlp_set_attr_hdr(&attr->hdr, type_code, \ 116 wlp_set_attr_hdr(&attr->hdr, type_code, \
122 sizeof(*attr) - sizeof(struct wlp_attr_hdr)); \ 117 sizeof(*attr) - sizeof(struct wlp_attr_hdr)); \
123 attr->name = *value; \ 118 attr->name = *value; \
124 d_dump(6, NULL, attr, sizeof(*attr)); \
125 d_fnend(6, NULL, "(attribute %p)\n", attr); \
126 return sizeof(*attr); \ 119 return sizeof(*attr); \
127} 120}
128 121
@@ -139,11 +132,8 @@ static size_t wlp_set_##name(struct wlp_attr_##name *attr, type value) \
139static size_t wlp_set_##name(struct wlp_attr_##name *attr, type value, \ 132static size_t wlp_set_##name(struct wlp_attr_##name *attr, type value, \
140 size_t len) \ 133 size_t len) \
141{ \ 134{ \
142 d_fnstart(6, NULL, "(attribute %p)\n", attr); \
143 wlp_set_attr_hdr(&attr->hdr, type_code, len); \ 135 wlp_set_attr_hdr(&attr->hdr, type_code, len); \
144 memcpy(attr->name, value, len); \ 136 memcpy(attr->name, value, len); \
145 d_dump(6, NULL, attr, sizeof(*attr) + len); \
146 d_fnend(6, NULL, "(attribute %p)\n", attr); \
147 return sizeof(*attr) + len; \ 137 return sizeof(*attr) + len; \
148} 138}
149 139
@@ -182,7 +172,7 @@ static size_t wlp_set_wss_info(struct wlp_attr_wss_info *attr,
182 size_t datalen; 172 size_t datalen;
183 void *ptr = attr->wss_info; 173 void *ptr = attr->wss_info;
184 size_t used = sizeof(*attr); 174 size_t used = sizeof(*attr);
185 d_fnstart(6, NULL, "(attribute %p)\n", attr); 175
186 datalen = sizeof(struct wlp_wss_info) + strlen(wss->name); 176 datalen = sizeof(struct wlp_wss_info) + strlen(wss->name);
187 wlp_set_attr_hdr(&attr->hdr, WLP_ATTR_WSS_INFO, datalen); 177 wlp_set_attr_hdr(&attr->hdr, WLP_ATTR_WSS_INFO, datalen);
188 used = wlp_set_wssid(ptr, &wss->wssid); 178 used = wlp_set_wssid(ptr, &wss->wssid);
@@ -190,9 +180,6 @@ static size_t wlp_set_wss_info(struct wlp_attr_wss_info *attr,
190 used += wlp_set_accept_enrl(ptr + used, wss->accept_enroll); 180 used += wlp_set_accept_enrl(ptr + used, wss->accept_enroll);
191 used += wlp_set_wss_sec_status(ptr + used, wss->secure_status); 181 used += wlp_set_wss_sec_status(ptr + used, wss->secure_status);
192 used += wlp_set_wss_bcast(ptr + used, &wss->bcast); 182 used += wlp_set_wss_bcast(ptr + used, &wss->bcast);
193 d_dump(6, NULL, attr, sizeof(*attr) + datalen);
194 d_fnend(6, NULL, "(attribute %p, used %d)\n",
195 attr, (int)(sizeof(*attr) + used));
196 return sizeof(*attr) + used; 183 return sizeof(*attr) + used;
197} 184}
198 185
@@ -414,7 +401,6 @@ static ssize_t wlp_get_wss_info_attrs(struct wlp *wlp,
414 size_t used = 0; 401 size_t used = 0;
415 ssize_t result = -EINVAL; 402 ssize_t result = -EINVAL;
416 403
417 d_printf(6, dev, "WLP: WSS info: Retrieving WSS name\n");
418 result = wlp_get_wss_name(wlp, ptr, info->name, buflen); 404 result = wlp_get_wss_name(wlp, ptr, info->name, buflen);
419 if (result < 0) { 405 if (result < 0) {
420 dev_err(dev, "WLP: unable to obtain WSS name from " 406 dev_err(dev, "WLP: unable to obtain WSS name from "
@@ -422,7 +408,7 @@ static ssize_t wlp_get_wss_info_attrs(struct wlp *wlp,
422 goto error_parse; 408 goto error_parse;
423 } 409 }
424 used += result; 410 used += result;
425 d_printf(6, dev, "WLP: WSS info: Retrieving accept enroll\n"); 411
426 result = wlp_get_accept_enrl(wlp, ptr + used, &info->accept_enroll, 412 result = wlp_get_accept_enrl(wlp, ptr + used, &info->accept_enroll,
427 buflen - used); 413 buflen - used);
428 if (result < 0) { 414 if (result < 0) {
@@ -437,7 +423,7 @@ static ssize_t wlp_get_wss_info_attrs(struct wlp *wlp,
437 goto error_parse; 423 goto error_parse;
438 } 424 }
439 used += result; 425 used += result;
440 d_printf(6, dev, "WLP: WSS info: Retrieving secure status\n"); 426
441 result = wlp_get_wss_sec_status(wlp, ptr + used, &info->sec_status, 427 result = wlp_get_wss_sec_status(wlp, ptr + used, &info->sec_status,
442 buflen - used); 428 buflen - used);
443 if (result < 0) { 429 if (result < 0) {
@@ -452,7 +438,7 @@ static ssize_t wlp_get_wss_info_attrs(struct wlp *wlp,
452 goto error_parse; 438 goto error_parse;
453 } 439 }
454 used += result; 440 used += result;
455 d_printf(6, dev, "WLP: WSS info: Retrieving broadcast\n"); 441
456 result = wlp_get_wss_bcast(wlp, ptr + used, &info->bcast, 442 result = wlp_get_wss_bcast(wlp, ptr + used, &info->bcast,
457 buflen - used); 443 buflen - used);
458 if (result < 0) { 444 if (result < 0) {
@@ -530,7 +516,7 @@ static ssize_t wlp_get_wss_info(struct wlp *wlp, struct wlp_attr_wss_info *attr,
530 len = result; 516 len = result;
531 used = sizeof(*attr); 517 used = sizeof(*attr);
532 ptr = attr; 518 ptr = attr;
533 d_printf(6, dev, "WLP: WSS info: Retrieving WSSID\n"); 519
534 result = wlp_get_wssid(wlp, ptr + used, wssid, buflen - used); 520 result = wlp_get_wssid(wlp, ptr + used, wssid, buflen - used);
535 if (result < 0) { 521 if (result < 0) {
536 dev_err(dev, "WLP: unable to obtain WSSID from WSS info.\n"); 522 dev_err(dev, "WLP: unable to obtain WSSID from WSS info.\n");
@@ -553,8 +539,6 @@ static ssize_t wlp_get_wss_info(struct wlp *wlp, struct wlp_attr_wss_info *attr,
553 goto out; 539 goto out;
554 } 540 }
555 result = used; 541 result = used;
556 d_printf(6, dev, "WLP: Successfully parsed WLP information "
557 "attribute. used %zu bytes\n", used);
558out: 542out:
559 return result; 543 return result;
560} 544}
@@ -598,8 +582,6 @@ static ssize_t wlp_get_all_wss_info(struct wlp *wlp,
598 struct wlp_wssid_e *wssid_e; 582 struct wlp_wssid_e *wssid_e;
599 char buf[WLP_WSS_UUID_STRSIZE]; 583 char buf[WLP_WSS_UUID_STRSIZE];
600 584
601 d_fnstart(6, dev, "wlp %p, attr %p, neighbor %p, wss %p, buflen %d \n",
602 wlp, attr, neighbor, wss, (int)buflen);
603 if (buflen < 0) 585 if (buflen < 0)
604 goto out; 586 goto out;
605 587
@@ -638,8 +620,7 @@ static ssize_t wlp_get_all_wss_info(struct wlp *wlp,
638 wss->accept_enroll = wss_info.accept_enroll; 620 wss->accept_enroll = wss_info.accept_enroll;
639 wss->state = WLP_WSS_STATE_PART_ENROLLED; 621 wss->state = WLP_WSS_STATE_PART_ENROLLED;
640 wlp_wss_uuid_print(buf, sizeof(buf), &wssid); 622 wlp_wss_uuid_print(buf, sizeof(buf), &wssid);
641 d_printf(2, dev, "WLP: Found WSS %s. Enrolling.\n", 623 dev_dbg(dev, "WLP: Found WSS %s. Enrolling.\n", buf);
642 buf);
643 } else { 624 } else {
644 wssid_e = wlp_create_wssid_e(wlp, neighbor); 625 wssid_e = wlp_create_wssid_e(wlp, neighbor);
645 if (wssid_e == NULL) { 626 if (wssid_e == NULL) {
@@ -660,9 +641,6 @@ error_parse:
660 if (result < 0 && !enroll) /* this was a discovery */ 641 if (result < 0 && !enroll) /* this was a discovery */
661 wlp_remove_neighbor_tmp_info(neighbor); 642 wlp_remove_neighbor_tmp_info(neighbor);
662out: 643out:
663 d_fnend(6, dev, "wlp %p, attr %p, neighbor %p, wss %p, buflen %d, "
664 "result %d \n", wlp, attr, neighbor, wss, (int)buflen,
665 (int)result);
666 return result; 644 return result;
667 645
668} 646}
@@ -718,7 +696,6 @@ static int wlp_build_assoc_d1(struct wlp *wlp, struct wlp_wss *wss,
718 struct sk_buff *_skb; 696 struct sk_buff *_skb;
719 void *d1_itr; 697 void *d1_itr;
720 698
721 d_fnstart(6, dev, "wlp %p\n", wlp);
722 if (wlp->dev_info == NULL) { 699 if (wlp->dev_info == NULL) {
723 result = __wlp_setup_device_info(wlp); 700 result = __wlp_setup_device_info(wlp);
724 if (result < 0) { 701 if (result < 0) {
@@ -728,24 +705,6 @@ static int wlp_build_assoc_d1(struct wlp *wlp, struct wlp_wss *wss,
728 } 705 }
729 } 706 }
730 info = wlp->dev_info; 707 info = wlp->dev_info;
731 d_printf(6, dev, "Local properties:\n"
732 "Device name (%d bytes): %s\n"
733 "Model name (%d bytes): %s\n"
734 "Manufacturer (%d bytes): %s\n"
735 "Model number (%d bytes): %s\n"
736 "Serial number (%d bytes): %s\n"
737 "Primary device type: \n"
738 " Category: %d \n"
739 " OUI: %02x:%02x:%02x \n"
740 " OUI Subdivision: %u \n",
741 (int)strlen(info->name), info->name,
742 (int)strlen(info->model_name), info->model_name,
743 (int)strlen(info->manufacturer), info->manufacturer,
744 (int)strlen(info->model_nr), info->model_nr,
745 (int)strlen(info->serial), info->serial,
746 info->prim_dev_type.category,
747 info->prim_dev_type.OUI[0], info->prim_dev_type.OUI[1],
748 info->prim_dev_type.OUI[2], info->prim_dev_type.OUIsubdiv);
749 _skb = dev_alloc_skb(sizeof(*_d1) 708 _skb = dev_alloc_skb(sizeof(*_d1)
750 + sizeof(struct wlp_attr_uuid_e) 709 + sizeof(struct wlp_attr_uuid_e)
751 + sizeof(struct wlp_attr_wss_sel_mthd) 710 + sizeof(struct wlp_attr_wss_sel_mthd)
@@ -768,7 +727,6 @@ static int wlp_build_assoc_d1(struct wlp *wlp, struct wlp_wss *wss,
768 goto error; 727 goto error;
769 } 728 }
770 _d1 = (void *) _skb->data; 729 _d1 = (void *) _skb->data;
771 d_printf(6, dev, "D1 starts at %p \n", _d1);
772 _d1->hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID); 730 _d1->hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID);
773 _d1->hdr.type = WLP_FRAME_ASSOCIATION; 731 _d1->hdr.type = WLP_FRAME_ASSOCIATION;
774 _d1->type = WLP_ASSOC_D1; 732 _d1->type = WLP_ASSOC_D1;
@@ -791,25 +749,8 @@ static int wlp_build_assoc_d1(struct wlp *wlp, struct wlp_wss *wss,
791 used += wlp_set_prim_dev_type(d1_itr + used, &info->prim_dev_type); 749 used += wlp_set_prim_dev_type(d1_itr + used, &info->prim_dev_type);
792 used += wlp_set_wlp_assc_err(d1_itr + used, WLP_ASSOC_ERROR_NONE); 750 used += wlp_set_wlp_assc_err(d1_itr + used, WLP_ASSOC_ERROR_NONE);
793 skb_put(_skb, sizeof(*_d1) + used); 751 skb_put(_skb, sizeof(*_d1) + used);
794 d_printf(6, dev, "D1 message:\n");
795 d_dump(6, dev, _d1, sizeof(*_d1)
796 + sizeof(struct wlp_attr_uuid_e)
797 + sizeof(struct wlp_attr_wss_sel_mthd)
798 + sizeof(struct wlp_attr_dev_name)
799 + strlen(info->name)
800 + sizeof(struct wlp_attr_manufacturer)
801 + strlen(info->manufacturer)
802 + sizeof(struct wlp_attr_model_name)
803 + strlen(info->model_name)
804 + sizeof(struct wlp_attr_model_nr)
805 + strlen(info->model_nr)
806 + sizeof(struct wlp_attr_serial)
807 + strlen(info->serial)
808 + sizeof(struct wlp_attr_prim_dev_type)
809 + sizeof(struct wlp_attr_wlp_assc_err));
810 *skb = _skb; 752 *skb = _skb;
811error: 753error:
812 d_fnend(6, dev, "wlp %p, result = %d\n", wlp, result);
813 return result; 754 return result;
814} 755}
815 756
@@ -837,7 +778,6 @@ int wlp_build_assoc_d2(struct wlp *wlp, struct wlp_wss *wss,
837 void *d2_itr; 778 void *d2_itr;
838 size_t mem_needed; 779 size_t mem_needed;
839 780
840 d_fnstart(6, dev, "wlp %p\n", wlp);
841 if (wlp->dev_info == NULL) { 781 if (wlp->dev_info == NULL) {
842 result = __wlp_setup_device_info(wlp); 782 result = __wlp_setup_device_info(wlp);
843 if (result < 0) { 783 if (result < 0) {
@@ -847,24 +787,6 @@ int wlp_build_assoc_d2(struct wlp *wlp, struct wlp_wss *wss,
847 } 787 }
848 } 788 }
849 info = wlp->dev_info; 789 info = wlp->dev_info;
850 d_printf(6, dev, "Local properties:\n"
851 "Device name (%d bytes): %s\n"
852 "Model name (%d bytes): %s\n"
853 "Manufacturer (%d bytes): %s\n"
854 "Model number (%d bytes): %s\n"
855 "Serial number (%d bytes): %s\n"
856 "Primary device type: \n"
857 " Category: %d \n"
858 " OUI: %02x:%02x:%02x \n"
859 " OUI Subdivision: %u \n",
860 (int)strlen(info->name), info->name,
861 (int)strlen(info->model_name), info->model_name,
862 (int)strlen(info->manufacturer), info->manufacturer,
863 (int)strlen(info->model_nr), info->model_nr,
864 (int)strlen(info->serial), info->serial,
865 info->prim_dev_type.category,
866 info->prim_dev_type.OUI[0], info->prim_dev_type.OUI[1],
867 info->prim_dev_type.OUI[2], info->prim_dev_type.OUIsubdiv);
868 mem_needed = sizeof(*_d2) 790 mem_needed = sizeof(*_d2)
869 + sizeof(struct wlp_attr_uuid_e) 791 + sizeof(struct wlp_attr_uuid_e)
870 + sizeof(struct wlp_attr_uuid_r) 792 + sizeof(struct wlp_attr_uuid_r)
@@ -892,7 +814,6 @@ int wlp_build_assoc_d2(struct wlp *wlp, struct wlp_wss *wss,
892 goto error; 814 goto error;
893 } 815 }
894 _d2 = (void *) _skb->data; 816 _d2 = (void *) _skb->data;
895 d_printf(6, dev, "D2 starts at %p \n", _d2);
896 _d2->hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID); 817 _d2->hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID);
897 _d2->hdr.type = WLP_FRAME_ASSOCIATION; 818 _d2->hdr.type = WLP_FRAME_ASSOCIATION;
898 _d2->type = WLP_ASSOC_D2; 819 _d2->type = WLP_ASSOC_D2;
@@ -917,11 +838,8 @@ int wlp_build_assoc_d2(struct wlp *wlp, struct wlp_wss *wss,
917 used += wlp_set_prim_dev_type(d2_itr + used, &info->prim_dev_type); 838 used += wlp_set_prim_dev_type(d2_itr + used, &info->prim_dev_type);
918 used += wlp_set_wlp_assc_err(d2_itr + used, WLP_ASSOC_ERROR_NONE); 839 used += wlp_set_wlp_assc_err(d2_itr + used, WLP_ASSOC_ERROR_NONE);
919 skb_put(_skb, sizeof(*_d2) + used); 840 skb_put(_skb, sizeof(*_d2) + used);
920 d_printf(6, dev, "D2 message:\n");
921 d_dump(6, dev, _d2, mem_needed);
922 *skb = _skb; 841 *skb = _skb;
923error: 842error:
924 d_fnend(6, dev, "wlp %p, result = %d\n", wlp, result);
925 return result; 843 return result;
926} 844}
927 845
@@ -947,7 +865,6 @@ int wlp_build_assoc_f0(struct wlp *wlp, struct sk_buff **skb,
947 struct sk_buff *_skb; 865 struct sk_buff *_skb;
948 struct wlp_nonce tmp; 866 struct wlp_nonce tmp;
949 867
950 d_fnstart(6, dev, "wlp %p\n", wlp);
951 _skb = dev_alloc_skb(sizeof(*f0)); 868 _skb = dev_alloc_skb(sizeof(*f0));
952 if (_skb == NULL) { 869 if (_skb == NULL) {
953 dev_err(dev, "WLP: Unable to allocate memory for F0 " 870 dev_err(dev, "WLP: Unable to allocate memory for F0 "
@@ -955,7 +872,6 @@ int wlp_build_assoc_f0(struct wlp *wlp, struct sk_buff **skb,
955 goto error_alloc; 872 goto error_alloc;
956 } 873 }
957 f0 = (void *) _skb->data; 874 f0 = (void *) _skb->data;
958 d_printf(6, dev, "F0 starts at %p \n", f0);
959 f0->f0_hdr.hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID); 875 f0->f0_hdr.hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID);
960 f0->f0_hdr.hdr.type = WLP_FRAME_ASSOCIATION; 876 f0->f0_hdr.hdr.type = WLP_FRAME_ASSOCIATION;
961 f0->f0_hdr.type = WLP_ASSOC_F0; 877 f0->f0_hdr.type = WLP_ASSOC_F0;
@@ -969,7 +885,6 @@ int wlp_build_assoc_f0(struct wlp *wlp, struct sk_buff **skb,
969 *skb = _skb; 885 *skb = _skb;
970 result = 0; 886 result = 0;
971error_alloc: 887error_alloc:
972 d_fnend(6, dev, "wlp %p, result %d \n", wlp, result);
973 return result; 888 return result;
974} 889}
975 890
@@ -1242,12 +1157,9 @@ void wlp_handle_d1_frame(struct work_struct *ws)
1242 enum wlp_wss_sel_mthd sel_mthd = 0; 1157 enum wlp_wss_sel_mthd sel_mthd = 0;
1243 struct wlp_device_info dev_info; 1158 struct wlp_device_info dev_info;
1244 enum wlp_assc_error assc_err; 1159 enum wlp_assc_error assc_err;
1245 char uuid[WLP_WSS_UUID_STRSIZE];
1246 struct sk_buff *resp = NULL; 1160 struct sk_buff *resp = NULL;
1247 1161
1248 /* Parse D1 frame */ 1162 /* Parse D1 frame */
1249 d_fnstart(6, dev, "WLP: handle D1 frame. wlp = %p, skb = %p\n",
1250 wlp, skb);
1251 mutex_lock(&wss->mutex); 1163 mutex_lock(&wss->mutex);
1252 mutex_lock(&wlp->mutex); /* to access wlp->uuid */ 1164 mutex_lock(&wlp->mutex); /* to access wlp->uuid */
1253 memset(&dev_info, 0, sizeof(dev_info)); 1165 memset(&dev_info, 0, sizeof(dev_info));
@@ -1258,30 +1170,6 @@ void wlp_handle_d1_frame(struct work_struct *ws)
1258 kfree_skb(skb); 1170 kfree_skb(skb);
1259 goto out; 1171 goto out;
1260 } 1172 }
1261 wlp_wss_uuid_print(uuid, sizeof(uuid), &uuid_e);
1262 d_printf(6, dev, "From D1 frame:\n"
1263 "UUID-E: %s\n"
1264 "Selection method: %d\n"
1265 "Device name (%d bytes): %s\n"
1266 "Model name (%d bytes): %s\n"
1267 "Manufacturer (%d bytes): %s\n"
1268 "Model number (%d bytes): %s\n"
1269 "Serial number (%d bytes): %s\n"
1270 "Primary device type: \n"
1271 " Category: %d \n"
1272 " OUI: %02x:%02x:%02x \n"
1273 " OUI Subdivision: %u \n",
1274 uuid, sel_mthd,
1275 (int)strlen(dev_info.name), dev_info.name,
1276 (int)strlen(dev_info.model_name), dev_info.model_name,
1277 (int)strlen(dev_info.manufacturer), dev_info.manufacturer,
1278 (int)strlen(dev_info.model_nr), dev_info.model_nr,
1279 (int)strlen(dev_info.serial), dev_info.serial,
1280 dev_info.prim_dev_type.category,
1281 dev_info.prim_dev_type.OUI[0],
1282 dev_info.prim_dev_type.OUI[1],
1283 dev_info.prim_dev_type.OUI[2],
1284 dev_info.prim_dev_type.OUIsubdiv);
1285 1173
1286 kfree_skb(skb); 1174 kfree_skb(skb);
1287 if (!wlp_uuid_is_set(&wlp->uuid)) { 1175 if (!wlp_uuid_is_set(&wlp->uuid)) {
@@ -1316,7 +1204,6 @@ out:
1316 kfree(frame_ctx); 1204 kfree(frame_ctx);
1317 mutex_unlock(&wlp->mutex); 1205 mutex_unlock(&wlp->mutex);
1318 mutex_unlock(&wss->mutex); 1206 mutex_unlock(&wss->mutex);
1319 d_fnend(6, dev, "WLP: handle D1 frame. wlp = %p\n", wlp);
1320} 1207}
1321 1208
1322/** 1209/**
@@ -1546,10 +1433,8 @@ int wlp_parse_c3c4_frame(struct wlp *wlp, struct sk_buff *skb,
1546 void *ptr = skb->data; 1433 void *ptr = skb->data;
1547 size_t len = skb->len; 1434 size_t len = skb->len;
1548 size_t used; 1435 size_t used;
1549 char buf[WLP_WSS_UUID_STRSIZE];
1550 struct wlp_frame_assoc *assoc = ptr; 1436 struct wlp_frame_assoc *assoc = ptr;
1551 1437
1552 d_fnstart(6, dev, "wlp %p, skb %p \n", wlp, skb);
1553 used = sizeof(*assoc); 1438 used = sizeof(*assoc);
1554 result = wlp_get_wssid(wlp, ptr + used, wssid, len - used); 1439 result = wlp_get_wssid(wlp, ptr + used, wssid, len - used);
1555 if (result < 0) { 1440 if (result < 0) {
@@ -1572,14 +1457,7 @@ int wlp_parse_c3c4_frame(struct wlp *wlp, struct sk_buff *skb,
1572 wlp_assoc_frame_str(assoc->type)); 1457 wlp_assoc_frame_str(assoc->type));
1573 goto error_parse; 1458 goto error_parse;
1574 } 1459 }
1575 wlp_wss_uuid_print(buf, sizeof(buf), wssid);
1576 d_printf(6, dev, "WLP: parsed: WSSID %s, tag 0x%02x, virt "
1577 "%02x:%02x:%02x:%02x:%02x:%02x \n", buf, *tag,
1578 virt_addr->data[0], virt_addr->data[1], virt_addr->data[2],
1579 virt_addr->data[3], virt_addr->data[4], virt_addr->data[5]);
1580
1581error_parse: 1460error_parse:
1582 d_fnend(6, dev, "wlp %p, skb %p, result = %d \n", wlp, skb, result);
1583 return result; 1461 return result;
1584} 1462}
1585 1463
@@ -1600,7 +1478,6 @@ int wlp_build_assoc_c1c2(struct wlp *wlp, struct wlp_wss *wss,
1600 } *c; 1478 } *c;
1601 struct sk_buff *_skb; 1479 struct sk_buff *_skb;
1602 1480
1603 d_fnstart(6, dev, "wlp %p, wss %p \n", wlp, wss);
1604 _skb = dev_alloc_skb(sizeof(*c)); 1481 _skb = dev_alloc_skb(sizeof(*c));
1605 if (_skb == NULL) { 1482 if (_skb == NULL) {
1606 dev_err(dev, "WLP: Unable to allocate memory for C1/C2 " 1483 dev_err(dev, "WLP: Unable to allocate memory for C1/C2 "
@@ -1608,7 +1485,6 @@ int wlp_build_assoc_c1c2(struct wlp *wlp, struct wlp_wss *wss,
1608 goto error_alloc; 1485 goto error_alloc;
1609 } 1486 }
1610 c = (void *) _skb->data; 1487 c = (void *) _skb->data;
1611 d_printf(6, dev, "C1/C2 starts at %p \n", c);
1612 c->c_hdr.hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID); 1488 c->c_hdr.hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID);
1613 c->c_hdr.hdr.type = WLP_FRAME_ASSOCIATION; 1489 c->c_hdr.hdr.type = WLP_FRAME_ASSOCIATION;
1614 c->c_hdr.type = type; 1490 c->c_hdr.type = type;
@@ -1616,12 +1492,9 @@ int wlp_build_assoc_c1c2(struct wlp *wlp, struct wlp_wss *wss,
1616 wlp_set_msg_type(&c->c_hdr.msg_type, type); 1492 wlp_set_msg_type(&c->c_hdr.msg_type, type);
1617 wlp_set_wssid(&c->wssid, &wss->wssid); 1493 wlp_set_wssid(&c->wssid, &wss->wssid);
1618 skb_put(_skb, sizeof(*c)); 1494 skb_put(_skb, sizeof(*c));
1619 d_printf(6, dev, "C1/C2 message:\n");
1620 d_dump(6, dev, c, sizeof(*c));
1621 *skb = _skb; 1495 *skb = _skb;
1622 result = 0; 1496 result = 0;
1623error_alloc: 1497error_alloc:
1624 d_fnend(6, dev, "wlp %p, wss %p, result %d \n", wlp, wss, result);
1625 return result; 1498 return result;
1626} 1499}
1627 1500
@@ -1660,7 +1533,6 @@ int wlp_build_assoc_c3c4(struct wlp *wlp, struct wlp_wss *wss,
1660 } *c; 1533 } *c;
1661 struct sk_buff *_skb; 1534 struct sk_buff *_skb;
1662 1535
1663 d_fnstart(6, dev, "wlp %p, wss %p \n", wlp, wss);
1664 _skb = dev_alloc_skb(sizeof(*c)); 1536 _skb = dev_alloc_skb(sizeof(*c));
1665 if (_skb == NULL) { 1537 if (_skb == NULL) {
1666 dev_err(dev, "WLP: Unable to allocate memory for C3/C4 " 1538 dev_err(dev, "WLP: Unable to allocate memory for C3/C4 "
@@ -1668,7 +1540,6 @@ int wlp_build_assoc_c3c4(struct wlp *wlp, struct wlp_wss *wss,
1668 goto error_alloc; 1540 goto error_alloc;
1669 } 1541 }
1670 c = (void *) _skb->data; 1542 c = (void *) _skb->data;
1671 d_printf(6, dev, "C3/C4 starts at %p \n", c);
1672 c->c_hdr.hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID); 1543 c->c_hdr.hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID);
1673 c->c_hdr.hdr.type = WLP_FRAME_ASSOCIATION; 1544 c->c_hdr.hdr.type = WLP_FRAME_ASSOCIATION;
1674 c->c_hdr.type = type; 1545 c->c_hdr.type = type;
@@ -1678,12 +1549,9 @@ int wlp_build_assoc_c3c4(struct wlp *wlp, struct wlp_wss *wss,
1678 wlp_set_wss_tag(&c->wss_tag, wss->tag); 1549 wlp_set_wss_tag(&c->wss_tag, wss->tag);
1679 wlp_set_wss_virt(&c->wss_virt, &wss->virtual_addr); 1550 wlp_set_wss_virt(&c->wss_virt, &wss->virtual_addr);
1680 skb_put(_skb, sizeof(*c)); 1551 skb_put(_skb, sizeof(*c));
1681 d_printf(6, dev, "C3/C4 message:\n");
1682 d_dump(6, dev, c, sizeof(*c));
1683 *skb = _skb; 1552 *skb = _skb;
1684 result = 0; 1553 result = 0;
1685error_alloc: 1554error_alloc:
1686 d_fnend(6, dev, "wlp %p, wss %p, result %d \n", wlp, wss, result);
1687 return result; 1555 return result;
1688} 1556}
1689 1557
@@ -1709,10 +1577,7 @@ static int wlp_send_assoc_##type(struct wlp *wlp, struct wlp_wss *wss, \
1709 struct device *dev = &wlp->rc->uwb_dev.dev; \ 1577 struct device *dev = &wlp->rc->uwb_dev.dev; \
1710 int result; \ 1578 int result; \
1711 struct sk_buff *skb = NULL; \ 1579 struct sk_buff *skb = NULL; \
1712 d_fnstart(6, dev, "wlp %p, wss %p, neighbor: %02x:%02x\n", \ 1580 \
1713 wlp, wss, dev_addr->data[1], dev_addr->data[0]); \
1714 d_printf(6, dev, "WLP: Constructing %s frame. \n", \
1715 wlp_assoc_frame_str(id)); \
1716 /* Build the frame */ \ 1581 /* Build the frame */ \
1717 result = wlp_build_assoc_##type(wlp, wss, &skb); \ 1582 result = wlp_build_assoc_##type(wlp, wss, &skb); \
1718 if (result < 0) { \ 1583 if (result < 0) { \
@@ -1721,9 +1586,6 @@ static int wlp_send_assoc_##type(struct wlp *wlp, struct wlp_wss *wss, \
1721 goto error_build_assoc; \ 1586 goto error_build_assoc; \
1722 } \ 1587 } \
1723 /* Send the frame */ \ 1588 /* Send the frame */ \
1724 d_printf(6, dev, "Transmitting %s frame to %02x:%02x \n", \
1725 wlp_assoc_frame_str(id), \
1726 dev_addr->data[1], dev_addr->data[0]); \
1727 BUG_ON(wlp->xmit_frame == NULL); \ 1589 BUG_ON(wlp->xmit_frame == NULL); \
1728 result = wlp->xmit_frame(wlp, skb, dev_addr); \ 1590 result = wlp->xmit_frame(wlp, skb, dev_addr); \
1729 if (result < 0) { \ 1591 if (result < 0) { \
@@ -1740,8 +1602,6 @@ error_xmit: \
1740 /* We could try again ... */ \ 1602 /* We could try again ... */ \
1741 dev_kfree_skb_any(skb);/*we need to free if tx fails*/ \ 1603 dev_kfree_skb_any(skb);/*we need to free if tx fails*/ \
1742error_build_assoc: \ 1604error_build_assoc: \
1743 d_fnend(6, dev, "wlp %p, wss %p, neighbor: %02x:%02x\n", \
1744 wlp, wss, dev_addr->data[1], dev_addr->data[0]); \
1745 return result; \ 1605 return result; \
1746} 1606}
1747 1607
@@ -1794,12 +1654,9 @@ void wlp_handle_c1_frame(struct work_struct *ws)
1794 struct uwb_dev_addr *src = &frame_ctx->src; 1654 struct uwb_dev_addr *src = &frame_ctx->src;
1795 int result; 1655 int result;
1796 struct wlp_uuid wssid; 1656 struct wlp_uuid wssid;
1797 char buf[WLP_WSS_UUID_STRSIZE];
1798 struct sk_buff *resp = NULL; 1657 struct sk_buff *resp = NULL;
1799 1658
1800 /* Parse C1 frame */ 1659 /* Parse C1 frame */
1801 d_fnstart(6, dev, "WLP: handle C1 frame. wlp = %p, c1 = %p\n",
1802 wlp, c1);
1803 mutex_lock(&wss->mutex); 1660 mutex_lock(&wss->mutex);
1804 result = wlp_get_wssid(wlp, (void *)c1 + sizeof(*c1), &wssid, 1661 result = wlp_get_wssid(wlp, (void *)c1 + sizeof(*c1), &wssid,
1805 len - sizeof(*c1)); 1662 len - sizeof(*c1));
@@ -1807,12 +1664,8 @@ void wlp_handle_c1_frame(struct work_struct *ws)
1807 dev_err(dev, "WLP: unable to obtain WSSID from C1 frame.\n"); 1664 dev_err(dev, "WLP: unable to obtain WSSID from C1 frame.\n");
1808 goto out; 1665 goto out;
1809 } 1666 }
1810 wlp_wss_uuid_print(buf, sizeof(buf), &wssid);
1811 d_printf(6, dev, "Received C1 frame with WSSID %s \n", buf);
1812 if (!memcmp(&wssid, &wss->wssid, sizeof(wssid)) 1667 if (!memcmp(&wssid, &wss->wssid, sizeof(wssid))
1813 && wss->state == WLP_WSS_STATE_ACTIVE) { 1668 && wss->state == WLP_WSS_STATE_ACTIVE) {
1814 d_printf(6, dev, "WSSID from C1 frame is known locally "
1815 "and is active\n");
1816 /* Construct C2 frame */ 1669 /* Construct C2 frame */
1817 result = wlp_build_assoc_c2(wlp, wss, &resp); 1670 result = wlp_build_assoc_c2(wlp, wss, &resp);
1818 if (result < 0) { 1671 if (result < 0) {
@@ -1820,8 +1673,6 @@ void wlp_handle_c1_frame(struct work_struct *ws)
1820 goto out; 1673 goto out;
1821 } 1674 }
1822 } else { 1675 } else {
1823 d_printf(6, dev, "WSSID from C1 frame is not known locally "
1824 "or is not active\n");
1825 /* Construct F0 frame */ 1676 /* Construct F0 frame */
1826 result = wlp_build_assoc_f0(wlp, &resp, WLP_ASSOC_ERROR_INV); 1677 result = wlp_build_assoc_f0(wlp, &resp, WLP_ASSOC_ERROR_INV);
1827 if (result < 0) { 1678 if (result < 0) {
@@ -1830,8 +1681,6 @@ void wlp_handle_c1_frame(struct work_struct *ws)
1830 } 1681 }
1831 } 1682 }
1832 /* Send C2 frame */ 1683 /* Send C2 frame */
1833 d_printf(6, dev, "Transmitting response (C2/F0) frame to %02x:%02x \n",
1834 src->data[1], src->data[0]);
1835 BUG_ON(wlp->xmit_frame == NULL); 1684 BUG_ON(wlp->xmit_frame == NULL);
1836 result = wlp->xmit_frame(wlp, resp, src); 1685 result = wlp->xmit_frame(wlp, resp, src);
1837 if (result < 0) { 1686 if (result < 0) {
@@ -1846,7 +1695,6 @@ out:
1846 kfree_skb(frame_ctx->skb); 1695 kfree_skb(frame_ctx->skb);
1847 kfree(frame_ctx); 1696 kfree(frame_ctx);
1848 mutex_unlock(&wss->mutex); 1697 mutex_unlock(&wss->mutex);
1849 d_fnend(6, dev, "WLP: handle C1 frame. wlp = %p\n", wlp);
1850} 1698}
1851 1699
1852/** 1700/**
@@ -1868,27 +1716,20 @@ void wlp_handle_c3_frame(struct work_struct *ws)
1868 struct sk_buff *skb = frame_ctx->skb; 1716 struct sk_buff *skb = frame_ctx->skb;
1869 struct uwb_dev_addr *src = &frame_ctx->src; 1717 struct uwb_dev_addr *src = &frame_ctx->src;
1870 int result; 1718 int result;
1871 char buf[WLP_WSS_UUID_STRSIZE];
1872 struct sk_buff *resp = NULL; 1719 struct sk_buff *resp = NULL;
1873 struct wlp_uuid wssid; 1720 struct wlp_uuid wssid;
1874 u8 tag; 1721 u8 tag;
1875 struct uwb_mac_addr virt_addr; 1722 struct uwb_mac_addr virt_addr;
1876 1723
1877 /* Parse C3 frame */ 1724 /* Parse C3 frame */
1878 d_fnstart(6, dev, "WLP: handle C3 frame. wlp = %p, skb = %p\n",
1879 wlp, skb);
1880 mutex_lock(&wss->mutex); 1725 mutex_lock(&wss->mutex);
1881 result = wlp_parse_c3c4_frame(wlp, skb, &wssid, &tag, &virt_addr); 1726 result = wlp_parse_c3c4_frame(wlp, skb, &wssid, &tag, &virt_addr);
1882 if (result < 0) { 1727 if (result < 0) {
1883 dev_err(dev, "WLP: unable to obtain values from C3 frame.\n"); 1728 dev_err(dev, "WLP: unable to obtain values from C3 frame.\n");
1884 goto out; 1729 goto out;
1885 } 1730 }
1886 wlp_wss_uuid_print(buf, sizeof(buf), &wssid);
1887 d_printf(6, dev, "Received C3 frame with WSSID %s \n", buf);
1888 if (!memcmp(&wssid, &wss->wssid, sizeof(wssid)) 1731 if (!memcmp(&wssid, &wss->wssid, sizeof(wssid))
1889 && wss->state >= WLP_WSS_STATE_ACTIVE) { 1732 && wss->state >= WLP_WSS_STATE_ACTIVE) {
1890 d_printf(6, dev, "WSSID from C3 frame is known locally "
1891 "and is active\n");
1892 result = wlp_eda_update_node(&wlp->eda, src, wss, 1733 result = wlp_eda_update_node(&wlp->eda, src, wss,
1893 (void *) virt_addr.data, tag, 1734 (void *) virt_addr.data, tag,
1894 WLP_WSS_CONNECTED); 1735 WLP_WSS_CONNECTED);
@@ -1913,8 +1754,6 @@ void wlp_handle_c3_frame(struct work_struct *ws)
1913 } 1754 }
1914 } 1755 }
1915 } else { 1756 } else {
1916 d_printf(6, dev, "WSSID from C3 frame is not known locally "
1917 "or is not active\n");
1918 /* Construct F0 frame */ 1757 /* Construct F0 frame */
1919 result = wlp_build_assoc_f0(wlp, &resp, WLP_ASSOC_ERROR_INV); 1758 result = wlp_build_assoc_f0(wlp, &resp, WLP_ASSOC_ERROR_INV);
1920 if (result < 0) { 1759 if (result < 0) {
@@ -1923,8 +1762,6 @@ void wlp_handle_c3_frame(struct work_struct *ws)
1923 } 1762 }
1924 } 1763 }
1925 /* Send C4 frame */ 1764 /* Send C4 frame */
1926 d_printf(6, dev, "Transmitting response (C4/F0) frame to %02x:%02x \n",
1927 src->data[1], src->data[0]);
1928 BUG_ON(wlp->xmit_frame == NULL); 1765 BUG_ON(wlp->xmit_frame == NULL);
1929 result = wlp->xmit_frame(wlp, resp, src); 1766 result = wlp->xmit_frame(wlp, resp, src);
1930 if (result < 0) { 1767 if (result < 0) {
@@ -1939,8 +1776,6 @@ out:
1939 kfree_skb(frame_ctx->skb); 1776 kfree_skb(frame_ctx->skb);
1940 kfree(frame_ctx); 1777 kfree(frame_ctx);
1941 mutex_unlock(&wss->mutex); 1778 mutex_unlock(&wss->mutex);
1942 d_fnend(6, dev, "WLP: handle C3 frame. wlp = %p, skb = %p\n",
1943 wlp, skb);
1944} 1779}
1945 1780
1946 1781
diff --git a/drivers/uwb/wlp/sysfs.c b/drivers/uwb/wlp/sysfs.c
index 1bb9b1f97d47..0370399ff4bb 100644
--- a/drivers/uwb/wlp/sysfs.c
+++ b/drivers/uwb/wlp/sysfs.c
@@ -23,8 +23,8 @@
23 * FIXME: Docs 23 * FIXME: Docs
24 * 24 *
25 */ 25 */
26
27#include <linux/wlp.h> 26#include <linux/wlp.h>
27
28#include "wlp-internal.h" 28#include "wlp-internal.h"
29 29
30static 30static
diff --git a/drivers/uwb/wlp/txrx.c b/drivers/uwb/wlp/txrx.c
index c701bd1a2887..cd2035768b47 100644
--- a/drivers/uwb/wlp/txrx.c
+++ b/drivers/uwb/wlp/txrx.c
@@ -26,12 +26,10 @@
26 26
27#include <linux/etherdevice.h> 27#include <linux/etherdevice.h>
28#include <linux/wlp.h> 28#include <linux/wlp.h>
29#define D_LOCAL 5
30#include <linux/uwb/debug.h>
31#include "wlp-internal.h"
32 29
30#include "wlp-internal.h"
33 31
34/** 32/*
35 * Direct incoming association msg to correct parsing routine 33 * Direct incoming association msg to correct parsing routine
36 * 34 *
37 * We only expect D1, E1, C1, C3 messages as new. All other incoming 35 * We only expect D1, E1, C1, C3 messages as new. All other incoming
@@ -48,35 +46,31 @@ void wlp_direct_assoc_frame(struct wlp *wlp, struct sk_buff *skb,
48 struct device *dev = &wlp->rc->uwb_dev.dev; 46 struct device *dev = &wlp->rc->uwb_dev.dev;
49 struct wlp_frame_assoc *assoc = (void *) skb->data; 47 struct wlp_frame_assoc *assoc = (void *) skb->data;
50 struct wlp_assoc_frame_ctx *frame_ctx; 48 struct wlp_assoc_frame_ctx *frame_ctx;
51 d_fnstart(5, dev, "wlp %p, skb %p\n", wlp, skb); 49
52 frame_ctx = kmalloc(sizeof(*frame_ctx), GFP_ATOMIC); 50 frame_ctx = kmalloc(sizeof(*frame_ctx), GFP_ATOMIC);
53 if (frame_ctx == NULL) { 51 if (frame_ctx == NULL) {
54 dev_err(dev, "WLP: Unable to allocate memory for association " 52 dev_err(dev, "WLP: Unable to allocate memory for association "
55 "frame handling.\n"); 53 "frame handling.\n");
56 kfree_skb(skb); 54 kfree_skb(skb);
57 goto out; 55 return;
58 } 56 }
59 frame_ctx->wlp = wlp; 57 frame_ctx->wlp = wlp;
60 frame_ctx->skb = skb; 58 frame_ctx->skb = skb;
61 frame_ctx->src = *src; 59 frame_ctx->src = *src;
62 switch (assoc->type) { 60 switch (assoc->type) {
63 case WLP_ASSOC_D1: 61 case WLP_ASSOC_D1:
64 d_printf(5, dev, "Received a D1 frame.\n");
65 INIT_WORK(&frame_ctx->ws, wlp_handle_d1_frame); 62 INIT_WORK(&frame_ctx->ws, wlp_handle_d1_frame);
66 schedule_work(&frame_ctx->ws); 63 schedule_work(&frame_ctx->ws);
67 break; 64 break;
68 case WLP_ASSOC_E1: 65 case WLP_ASSOC_E1:
69 d_printf(5, dev, "Received a E1 frame. FIXME?\n");
70 kfree_skb(skb); /* Temporary until we handle it */ 66 kfree_skb(skb); /* Temporary until we handle it */
71 kfree(frame_ctx); /* Temporary until we handle it */ 67 kfree(frame_ctx); /* Temporary until we handle it */
72 break; 68 break;
73 case WLP_ASSOC_C1: 69 case WLP_ASSOC_C1:
74 d_printf(5, dev, "Received a C1 frame.\n");
75 INIT_WORK(&frame_ctx->ws, wlp_handle_c1_frame); 70 INIT_WORK(&frame_ctx->ws, wlp_handle_c1_frame);
76 schedule_work(&frame_ctx->ws); 71 schedule_work(&frame_ctx->ws);
77 break; 72 break;
78 case WLP_ASSOC_C3: 73 case WLP_ASSOC_C3:
79 d_printf(5, dev, "Received a C3 frame.\n");
80 INIT_WORK(&frame_ctx->ws, wlp_handle_c3_frame); 74 INIT_WORK(&frame_ctx->ws, wlp_handle_c3_frame);
81 schedule_work(&frame_ctx->ws); 75 schedule_work(&frame_ctx->ws);
82 break; 76 break;
@@ -87,11 +81,9 @@ void wlp_direct_assoc_frame(struct wlp *wlp, struct sk_buff *skb,
87 kfree(frame_ctx); 81 kfree(frame_ctx);
88 break; 82 break;
89 } 83 }
90out:
91 d_fnend(5, dev, "wlp %p\n", wlp);
92} 84}
93 85
94/** 86/*
95 * Process incoming association frame 87 * Process incoming association frame
96 * 88 *
97 * Although it could be possible to deal with some incoming association 89 * Although it could be possible to deal with some incoming association
@@ -112,7 +104,6 @@ void wlp_receive_assoc_frame(struct wlp *wlp, struct sk_buff *skb,
112 struct wlp_frame_assoc *assoc = (void *) skb->data; 104 struct wlp_frame_assoc *assoc = (void *) skb->data;
113 struct wlp_session *session = wlp->session; 105 struct wlp_session *session = wlp->session;
114 u8 version; 106 u8 version;
115 d_fnstart(5, dev, "wlp %p, skb %p\n", wlp, skb);
116 107
117 if (wlp_get_version(wlp, &assoc->version, &version, 108 if (wlp_get_version(wlp, &assoc->version, &version,
118 sizeof(assoc->version)) < 0) 109 sizeof(assoc->version)) < 0)
@@ -150,14 +141,12 @@ void wlp_receive_assoc_frame(struct wlp *wlp, struct sk_buff *skb,
150 } else { 141 } else {
151 wlp_direct_assoc_frame(wlp, skb, src); 142 wlp_direct_assoc_frame(wlp, skb, src);
152 } 143 }
153 d_fnend(5, dev, "wlp %p\n", wlp);
154 return; 144 return;
155error: 145error:
156 kfree_skb(skb); 146 kfree_skb(skb);
157 d_fnend(5, dev, "wlp %p\n", wlp);
158} 147}
159 148
160/** 149/*
161 * Verify incoming frame is from connected neighbor, prep to pass to WLP client 150 * Verify incoming frame is from connected neighbor, prep to pass to WLP client
162 * 151 *
163 * Verification proceeds according to WLP 0.99 [7.3.1]. The source address 152 * Verification proceeds according to WLP 0.99 [7.3.1]. The source address
@@ -176,7 +165,6 @@ int wlp_verify_prep_rx_frame(struct wlp *wlp, struct sk_buff *skb,
176 struct wlp_eda_node eda_entry; 165 struct wlp_eda_node eda_entry;
177 struct wlp_frame_std_abbrv_hdr *hdr = (void *) skb->data; 166 struct wlp_frame_std_abbrv_hdr *hdr = (void *) skb->data;
178 167
179 d_fnstart(6, dev, "wlp %p, skb %p \n", wlp, skb);
180 /*verify*/ 168 /*verify*/
181 result = wlp_copy_eda_node(&wlp->eda, src, &eda_entry); 169 result = wlp_copy_eda_node(&wlp->eda, src, &eda_entry);
182 if (result < 0) { 170 if (result < 0) {
@@ -207,11 +195,10 @@ int wlp_verify_prep_rx_frame(struct wlp *wlp, struct sk_buff *skb,
207 /*prep*/ 195 /*prep*/
208 skb_pull(skb, sizeof(*hdr)); 196 skb_pull(skb, sizeof(*hdr));
209out: 197out:
210 d_fnend(6, dev, "wlp %p, skb %p, result = %d \n", wlp, skb, result);
211 return result; 198 return result;
212} 199}
213 200
214/** 201/*
215 * Receive a WLP frame from device 202 * Receive a WLP frame from device
216 * 203 *
217 * @returns: 1 if calling function should free the skb 204 * @returns: 1 if calling function should free the skb
@@ -226,14 +213,12 @@ int wlp_receive_frame(struct device *dev, struct wlp *wlp, struct sk_buff *skb,
226 struct wlp_frame_hdr *hdr; 213 struct wlp_frame_hdr *hdr;
227 int result = 0; 214 int result = 0;
228 215
229 d_fnstart(6, dev, "skb (%p), len (%u)\n", skb, len);
230 if (len < sizeof(*hdr)) { 216 if (len < sizeof(*hdr)) {
231 dev_err(dev, "Not enough data to parse WLP header.\n"); 217 dev_err(dev, "Not enough data to parse WLP header.\n");
232 result = -EINVAL; 218 result = -EINVAL;
233 goto out; 219 goto out;
234 } 220 }
235 hdr = ptr; 221 hdr = ptr;
236 d_dump(6, dev, hdr, sizeof(*hdr));
237 if (le16_to_cpu(hdr->mux_hdr) != WLP_PROTOCOL_ID) { 222 if (le16_to_cpu(hdr->mux_hdr) != WLP_PROTOCOL_ID) {
238 dev_err(dev, "Not a WLP frame type.\n"); 223 dev_err(dev, "Not a WLP frame type.\n");
239 result = -EINVAL; 224 result = -EINVAL;
@@ -270,7 +255,6 @@ int wlp_receive_frame(struct device *dev, struct wlp *wlp, struct sk_buff *skb,
270 "WLP header.\n"); 255 "WLP header.\n");
271 goto out; 256 goto out;
272 } 257 }
273 d_printf(5, dev, "Association frame received.\n");
274 wlp_receive_assoc_frame(wlp, skb, src); 258 wlp_receive_assoc_frame(wlp, skb, src);
275 break; 259 break;
276 default: 260 default:
@@ -283,13 +267,12 @@ out:
283 kfree_skb(skb); 267 kfree_skb(skb);
284 result = 0; 268 result = 0;
285 } 269 }
286 d_fnend(6, dev, "skb (%p)\n", skb);
287 return result; 270 return result;
288} 271}
289EXPORT_SYMBOL_GPL(wlp_receive_frame); 272EXPORT_SYMBOL_GPL(wlp_receive_frame);
290 273
291 274
292/** 275/*
293 * Verify frame from network stack, prepare for further transmission 276 * Verify frame from network stack, prepare for further transmission
294 * 277 *
295 * @skb: the socket buffer that needs to be prepared for transmission (it 278 * @skb: the socket buffer that needs to be prepared for transmission (it
@@ -343,9 +326,7 @@ int wlp_prepare_tx_frame(struct device *dev, struct wlp *wlp,
343 int result = -EINVAL; 326 int result = -EINVAL;
344 struct ethhdr *eth_hdr = (void *) skb->data; 327 struct ethhdr *eth_hdr = (void *) skb->data;
345 328
346 d_fnstart(6, dev, "wlp (%p), skb (%p) \n", wlp, skb);
347 if (is_broadcast_ether_addr(eth_hdr->h_dest)) { 329 if (is_broadcast_ether_addr(eth_hdr->h_dest)) {
348 d_printf(6, dev, "WLP: handling broadcast frame. \n");
349 result = wlp_eda_for_each(&wlp->eda, wlp_wss_send_copy, skb); 330 result = wlp_eda_for_each(&wlp->eda, wlp_wss_send_copy, skb);
350 if (result < 0) { 331 if (result < 0) {
351 if (printk_ratelimit()) 332 if (printk_ratelimit())
@@ -357,7 +338,6 @@ int wlp_prepare_tx_frame(struct device *dev, struct wlp *wlp,
357 result = 1; 338 result = 1;
358 /* Frame will be transmitted by WLP. */ 339 /* Frame will be transmitted by WLP. */
359 } else { 340 } else {
360 d_printf(6, dev, "WLP: handling unicast frame. \n");
361 result = wlp_eda_for_virtual(&wlp->eda, eth_hdr->h_dest, dst, 341 result = wlp_eda_for_virtual(&wlp->eda, eth_hdr->h_dest, dst,
362 wlp_wss_prep_hdr, skb); 342 wlp_wss_prep_hdr, skb);
363 if (unlikely(result < 0)) { 343 if (unlikely(result < 0)) {
@@ -368,7 +348,6 @@ int wlp_prepare_tx_frame(struct device *dev, struct wlp *wlp,
368 } 348 }
369 } 349 }
370out: 350out:
371 d_fnend(6, dev, "wlp (%p), skb (%p). result = %d \n", wlp, skb, result);
372 return result; 351 return result;
373} 352}
374EXPORT_SYMBOL_GPL(wlp_prepare_tx_frame); 353EXPORT_SYMBOL_GPL(wlp_prepare_tx_frame);
diff --git a/drivers/uwb/wlp/wlp-internal.h b/drivers/uwb/wlp/wlp-internal.h
index 1c94fabfb1a7..3e8d5de7c5b9 100644
--- a/drivers/uwb/wlp/wlp-internal.h
+++ b/drivers/uwb/wlp/wlp-internal.h
@@ -42,10 +42,6 @@ enum wlp_wss_connect {
42extern struct kobj_type wss_ktype; 42extern struct kobj_type wss_ktype;
43extern struct attribute_group wss_attr_group; 43extern struct attribute_group wss_attr_group;
44 44
45extern int uwb_rc_ie_add(struct uwb_rc *, const struct uwb_ie_hdr *, size_t);
46extern int uwb_rc_ie_rm(struct uwb_rc *, enum uwb_ie);
47
48
49/* This should be changed to a dynamic array where entries are sorted 45/* This should be changed to a dynamic array where entries are sorted
50 * by eth_addr and search is done in a binary form 46 * by eth_addr and search is done in a binary form
51 * 47 *
diff --git a/drivers/uwb/wlp/wlp-lc.c b/drivers/uwb/wlp/wlp-lc.c
index 0799402e73fb..13db739c4e39 100644
--- a/drivers/uwb/wlp/wlp-lc.c
+++ b/drivers/uwb/wlp/wlp-lc.c
@@ -21,12 +21,9 @@
21 * 21 *
22 * FIXME: docs 22 * FIXME: docs
23 */ 23 */
24
25#include <linux/wlp.h> 24#include <linux/wlp.h>
26#define D_LOCAL 6
27#include <linux/uwb/debug.h>
28#include "wlp-internal.h"
29 25
26#include "wlp-internal.h"
30 27
31static 28static
32void wlp_neighbor_init(struct wlp_neighbor_e *neighbor) 29void wlp_neighbor_init(struct wlp_neighbor_e *neighbor)
@@ -61,11 +58,6 @@ int __wlp_alloc_device_info(struct wlp *wlp)
61static 58static
62void __wlp_fill_device_info(struct wlp *wlp) 59void __wlp_fill_device_info(struct wlp *wlp)
63{ 60{
64 struct device *dev = &wlp->rc->uwb_dev.dev;
65
66 BUG_ON(wlp->fill_device_info == NULL);
67 d_printf(6, dev, "Retrieving device information "
68 "from device driver.\n");
69 wlp->fill_device_info(wlp, wlp->dev_info); 61 wlp->fill_device_info(wlp, wlp->dev_info);
70} 62}
71 63
@@ -127,7 +119,7 @@ void wlp_remove_neighbor_tmp_info(struct wlp_neighbor_e *neighbor)
127 } 119 }
128} 120}
129 121
130/** 122/*
131 * Populate WLP neighborhood cache with neighbor information 123 * Populate WLP neighborhood cache with neighbor information
132 * 124 *
133 * A new neighbor is found. If it is discoverable then we add it to the 125 * A new neighbor is found. If it is discoverable then we add it to the
@@ -141,10 +133,7 @@ int wlp_add_neighbor(struct wlp *wlp, struct uwb_dev *dev)
141 int discoverable; 133 int discoverable;
142 struct wlp_neighbor_e *neighbor; 134 struct wlp_neighbor_e *neighbor;
143 135
144 d_fnstart(6, &dev->dev, "uwb %p \n", dev); 136 /*
145 d_printf(6, &dev->dev, "Found neighbor device %02x:%02x \n",
146 dev->dev_addr.data[1], dev->dev_addr.data[0]);
147 /**
148 * FIXME: 137 * FIXME:
149 * Use contents of WLP IE found in beacon cache to determine if 138 * Use contents of WLP IE found in beacon cache to determine if
150 * neighbor is discoverable. 139 * neighbor is discoverable.
@@ -167,7 +156,6 @@ int wlp_add_neighbor(struct wlp *wlp, struct uwb_dev *dev)
167 list_add(&neighbor->node, &wlp->neighbors); 156 list_add(&neighbor->node, &wlp->neighbors);
168 } 157 }
169error_no_mem: 158error_no_mem:
170 d_fnend(6, &dev->dev, "uwb %p, result = %d \n", dev, result);
171 return result; 159 return result;
172} 160}
173 161
@@ -255,8 +243,6 @@ int wlp_d1d2_exchange(struct wlp *wlp, struct wlp_neighbor_e *neighbor,
255 dev_err(dev, "Unable to send D1 frame to neighbor " 243 dev_err(dev, "Unable to send D1 frame to neighbor "
256 "%02x:%02x (%d)\n", dev_addr->data[1], 244 "%02x:%02x (%d)\n", dev_addr->data[1],
257 dev_addr->data[0], result); 245 dev_addr->data[0], result);
258 d_printf(6, dev, "Add placeholders into buffer next to "
259 "neighbor information we have (dev address).\n");
260 goto out; 246 goto out;
261 } 247 }
262 /* Create session, wait for response */ 248 /* Create session, wait for response */
@@ -284,8 +270,6 @@ int wlp_d1d2_exchange(struct wlp *wlp, struct wlp_neighbor_e *neighbor,
284 /* Parse message in session->data: it will be either D2 or F0 */ 270 /* Parse message in session->data: it will be either D2 or F0 */
285 skb = session.data; 271 skb = session.data;
286 resp = (void *) skb->data; 272 resp = (void *) skb->data;
287 d_printf(6, dev, "Received response to D1 frame. \n");
288 d_dump(6, dev, skb->data, skb->len > 72 ? 72 : skb->len);
289 273
290 if (resp->type == WLP_ASSOC_F0) { 274 if (resp->type == WLP_ASSOC_F0) {
291 result = wlp_parse_f0(wlp, skb); 275 result = wlp_parse_f0(wlp, skb);
@@ -337,10 +321,9 @@ int wlp_enroll_neighbor(struct wlp *wlp, struct wlp_neighbor_e *neighbor,
337 struct device *dev = &wlp->rc->uwb_dev.dev; 321 struct device *dev = &wlp->rc->uwb_dev.dev;
338 char buf[WLP_WSS_UUID_STRSIZE]; 322 char buf[WLP_WSS_UUID_STRSIZE];
339 struct uwb_dev_addr *dev_addr = &neighbor->uwb_dev->dev_addr; 323 struct uwb_dev_addr *dev_addr = &neighbor->uwb_dev->dev_addr;
324
340 wlp_wss_uuid_print(buf, sizeof(buf), wssid); 325 wlp_wss_uuid_print(buf, sizeof(buf), wssid);
341 d_fnstart(6, dev, "wlp %p, neighbor %p, wss %p, wssid %p (%s)\n", 326
342 wlp, neighbor, wss, wssid, buf);
343 d_printf(6, dev, "Complete me.\n");
344 result = wlp_d1d2_exchange(wlp, neighbor, wss, wssid); 327 result = wlp_d1d2_exchange(wlp, neighbor, wss, wssid);
345 if (result < 0) { 328 if (result < 0) {
346 dev_err(dev, "WLP: D1/D2 message exchange for enrollment " 329 dev_err(dev, "WLP: D1/D2 message exchange for enrollment "
@@ -360,13 +343,10 @@ int wlp_enroll_neighbor(struct wlp *wlp, struct wlp_neighbor_e *neighbor,
360 goto error; 343 goto error;
361 } else { 344 } else {
362 wss->state = WLP_WSS_STATE_ENROLLED; 345 wss->state = WLP_WSS_STATE_ENROLLED;
363 d_printf(2, dev, "WLP: Success Enrollment into unsecure WSS " 346 dev_dbg(dev, "WLP: Success Enrollment into unsecure WSS "
364 "%s using neighbor %02x:%02x. \n", buf, 347 "%s using neighbor %02x:%02x. \n",
365 dev_addr->data[1], dev_addr->data[0]); 348 buf, dev_addr->data[1], dev_addr->data[0]);
366 } 349 }
367
368 d_fnend(6, dev, "wlp %p, neighbor %p, wss %p, wssid %p (%s)\n",
369 wlp, neighbor, wss, wssid, buf);
370out: 350out:
371 return result; 351 return result;
372error: 352error:
@@ -449,7 +429,6 @@ ssize_t wlp_discover(struct wlp *wlp)
449 int result = 0; 429 int result = 0;
450 struct device *dev = &wlp->rc->uwb_dev.dev; 430 struct device *dev = &wlp->rc->uwb_dev.dev;
451 431
452 d_fnstart(6, dev, "wlp %p \n", wlp);
453 mutex_lock(&wlp->nbmutex); 432 mutex_lock(&wlp->nbmutex);
454 /* Clear current neighborhood cache. */ 433 /* Clear current neighborhood cache. */
455 __wlp_neighbors_release(wlp); 434 __wlp_neighbors_release(wlp);
@@ -469,7 +448,6 @@ ssize_t wlp_discover(struct wlp *wlp)
469 } 448 }
470error_dev_for_each: 449error_dev_for_each:
471 mutex_unlock(&wlp->nbmutex); 450 mutex_unlock(&wlp->nbmutex);
472 d_fnend(6, dev, "wlp %p \n", wlp);
473 return result; 451 return result;
474} 452}
475 453
@@ -492,9 +470,6 @@ void wlp_uwb_notifs_cb(void *_wlp, struct uwb_dev *uwb_dev,
492 int result; 470 int result;
493 switch (event) { 471 switch (event) {
494 case UWB_NOTIF_ONAIR: 472 case UWB_NOTIF_ONAIR:
495 d_printf(6, dev, "UWB device %02x:%02x is onair\n",
496 uwb_dev->dev_addr.data[1],
497 uwb_dev->dev_addr.data[0]);
498 result = wlp_eda_create_node(&wlp->eda, 473 result = wlp_eda_create_node(&wlp->eda,
499 uwb_dev->mac_addr.data, 474 uwb_dev->mac_addr.data,
500 &uwb_dev->dev_addr); 475 &uwb_dev->dev_addr);
@@ -505,18 +480,11 @@ void wlp_uwb_notifs_cb(void *_wlp, struct uwb_dev *uwb_dev,
505 uwb_dev->dev_addr.data[0]); 480 uwb_dev->dev_addr.data[0]);
506 break; 481 break;
507 case UWB_NOTIF_OFFAIR: 482 case UWB_NOTIF_OFFAIR:
508 d_printf(6, dev, "UWB device %02x:%02x is offair\n",
509 uwb_dev->dev_addr.data[1],
510 uwb_dev->dev_addr.data[0]);
511 wlp_eda_rm_node(&wlp->eda, &uwb_dev->dev_addr); 483 wlp_eda_rm_node(&wlp->eda, &uwb_dev->dev_addr);
512 mutex_lock(&wlp->nbmutex); 484 mutex_lock(&wlp->nbmutex);
513 list_for_each_entry_safe(neighbor, next, &wlp->neighbors, 485 list_for_each_entry_safe(neighbor, next, &wlp->neighbors, node) {
514 node) { 486 if (neighbor->uwb_dev == uwb_dev)
515 if (neighbor->uwb_dev == uwb_dev) {
516 d_printf(6, dev, "Removing device from "
517 "neighborhood.\n");
518 __wlp_neighbor_release(neighbor); 487 __wlp_neighbor_release(neighbor);
519 }
520 } 488 }
521 mutex_unlock(&wlp->nbmutex); 489 mutex_unlock(&wlp->nbmutex);
522 break; 490 break;
@@ -526,38 +494,47 @@ void wlp_uwb_notifs_cb(void *_wlp, struct uwb_dev *uwb_dev,
526 } 494 }
527} 495}
528 496
529int wlp_setup(struct wlp *wlp, struct uwb_rc *rc) 497static void wlp_channel_changed(struct uwb_pal *pal, int channel)
498{
499 struct wlp *wlp = container_of(pal, struct wlp, pal);
500
501 if (channel < 0)
502 netif_carrier_off(wlp->ndev);
503 else
504 netif_carrier_on(wlp->ndev);
505}
506
507int wlp_setup(struct wlp *wlp, struct uwb_rc *rc, struct net_device *ndev)
530{ 508{
531 struct device *dev = &rc->uwb_dev.dev;
532 int result; 509 int result;
533 510
534 d_fnstart(6, dev, "wlp %p\n", wlp);
535 BUG_ON(wlp->fill_device_info == NULL); 511 BUG_ON(wlp->fill_device_info == NULL);
536 BUG_ON(wlp->xmit_frame == NULL); 512 BUG_ON(wlp->xmit_frame == NULL);
537 BUG_ON(wlp->stop_queue == NULL); 513 BUG_ON(wlp->stop_queue == NULL);
538 BUG_ON(wlp->start_queue == NULL); 514 BUG_ON(wlp->start_queue == NULL);
515
539 wlp->rc = rc; 516 wlp->rc = rc;
517 wlp->ndev = ndev;
540 wlp_eda_init(&wlp->eda);/* Set up address cache */ 518 wlp_eda_init(&wlp->eda);/* Set up address cache */
541 wlp->uwb_notifs_handler.cb = wlp_uwb_notifs_cb; 519 wlp->uwb_notifs_handler.cb = wlp_uwb_notifs_cb;
542 wlp->uwb_notifs_handler.data = wlp; 520 wlp->uwb_notifs_handler.data = wlp;
543 uwb_notifs_register(rc, &wlp->uwb_notifs_handler); 521 uwb_notifs_register(rc, &wlp->uwb_notifs_handler);
544 522
545 uwb_pal_init(&wlp->pal); 523 uwb_pal_init(&wlp->pal);
546 result = uwb_pal_register(rc, &wlp->pal); 524 wlp->pal.rc = rc;
525 wlp->pal.channel_changed = wlp_channel_changed;
526 result = uwb_pal_register(&wlp->pal);
547 if (result < 0) 527 if (result < 0)
548 uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler); 528 uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler);
549 529
550 d_fnend(6, dev, "wlp %p, result = %d\n", wlp, result);
551 return result; 530 return result;
552} 531}
553EXPORT_SYMBOL_GPL(wlp_setup); 532EXPORT_SYMBOL_GPL(wlp_setup);
554 533
555void wlp_remove(struct wlp *wlp) 534void wlp_remove(struct wlp *wlp)
556{ 535{
557 struct device *dev = &wlp->rc->uwb_dev.dev;
558 d_fnstart(6, dev, "wlp %p\n", wlp);
559 wlp_neighbors_release(wlp); 536 wlp_neighbors_release(wlp);
560 uwb_pal_unregister(wlp->rc, &wlp->pal); 537 uwb_pal_unregister(&wlp->pal);
561 uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler); 538 uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler);
562 wlp_eda_release(&wlp->eda); 539 wlp_eda_release(&wlp->eda);
563 mutex_lock(&wlp->mutex); 540 mutex_lock(&wlp->mutex);
@@ -565,9 +542,6 @@ void wlp_remove(struct wlp *wlp)
565 kfree(wlp->dev_info); 542 kfree(wlp->dev_info);
566 mutex_unlock(&wlp->mutex); 543 mutex_unlock(&wlp->mutex);
567 wlp->rc = NULL; 544 wlp->rc = NULL;
568 /* We have to use NULL here because this function can be called
569 * when the device disappeared. */
570 d_fnend(6, NULL, "wlp %p\n", wlp);
571} 545}
572EXPORT_SYMBOL_GPL(wlp_remove); 546EXPORT_SYMBOL_GPL(wlp_remove);
573 547
diff --git a/drivers/uwb/wlp/wss-lc.c b/drivers/uwb/wlp/wss-lc.c
index 96b18c9bd6e9..5913c7a5d922 100644
--- a/drivers/uwb/wlp/wss-lc.c
+++ b/drivers/uwb/wlp/wss-lc.c
@@ -43,14 +43,11 @@
43 * wlp_wss_release() 43 * wlp_wss_release()
44 * wlp_wss_reset() 44 * wlp_wss_reset()
45 */ 45 */
46
47#include <linux/etherdevice.h> /* for is_valid_ether_addr */ 46#include <linux/etherdevice.h> /* for is_valid_ether_addr */
48#include <linux/skbuff.h> 47#include <linux/skbuff.h>
49#include <linux/wlp.h> 48#include <linux/wlp.h>
50#define D_LOCAL 5
51#include <linux/uwb/debug.h>
52#include "wlp-internal.h"
53 49
50#include "wlp-internal.h"
54 51
55size_t wlp_wss_key_print(char *buf, size_t bufsize, u8 *key) 52size_t wlp_wss_key_print(char *buf, size_t bufsize, u8 *key)
56{ 53{
@@ -116,9 +113,6 @@ struct uwb_mac_addr wlp_wss_sel_bcast_addr(struct wlp_wss *wss)
116 */ 113 */
117void wlp_wss_reset(struct wlp_wss *wss) 114void wlp_wss_reset(struct wlp_wss *wss)
118{ 115{
119 struct wlp *wlp = container_of(wss, struct wlp, wss);
120 struct device *dev = &wlp->rc->uwb_dev.dev;
121 d_fnstart(5, dev, "wss (%p) \n", wss);
122 memset(&wss->wssid, 0, sizeof(wss->wssid)); 116 memset(&wss->wssid, 0, sizeof(wss->wssid));
123 wss->hash = 0; 117 wss->hash = 0;
124 memset(&wss->name[0], 0, sizeof(wss->name)); 118 memset(&wss->name[0], 0, sizeof(wss->name));
@@ -127,7 +121,6 @@ void wlp_wss_reset(struct wlp_wss *wss)
127 memset(&wss->master_key[0], 0, sizeof(wss->master_key)); 121 memset(&wss->master_key[0], 0, sizeof(wss->master_key));
128 wss->tag = 0; 122 wss->tag = 0;
129 wss->state = WLP_WSS_STATE_NONE; 123 wss->state = WLP_WSS_STATE_NONE;
130 d_fnend(5, dev, "wss (%p) \n", wss);
131} 124}
132 125
133/** 126/**
@@ -145,7 +138,6 @@ int wlp_wss_sysfs_add(struct wlp_wss *wss, char *wssid_str)
145 struct device *dev = &wlp->rc->uwb_dev.dev; 138 struct device *dev = &wlp->rc->uwb_dev.dev;
146 int result; 139 int result;
147 140
148 d_fnstart(5, dev, "wss (%p), wssid: %s\n", wss, wssid_str);
149 result = kobject_set_name(&wss->kobj, "wss-%s", wssid_str); 141 result = kobject_set_name(&wss->kobj, "wss-%s", wssid_str);
150 if (result < 0) 142 if (result < 0)
151 return result; 143 return result;
@@ -162,7 +154,6 @@ int wlp_wss_sysfs_add(struct wlp_wss *wss, char *wssid_str)
162 result); 154 result);
163 goto error_sysfs_create_group; 155 goto error_sysfs_create_group;
164 } 156 }
165 d_fnend(5, dev, "Completed. result = %d \n", result);
166 return 0; 157 return 0;
167error_sysfs_create_group: 158error_sysfs_create_group:
168 159
@@ -214,22 +205,14 @@ int wlp_wss_enroll_target(struct wlp_wss *wss, struct wlp_uuid *wssid,
214 struct wlp *wlp = container_of(wss, struct wlp, wss); 205 struct wlp *wlp = container_of(wss, struct wlp, wss);
215 struct device *dev = &wlp->rc->uwb_dev.dev; 206 struct device *dev = &wlp->rc->uwb_dev.dev;
216 struct wlp_neighbor_e *neighbor; 207 struct wlp_neighbor_e *neighbor;
217 char buf[WLP_WSS_UUID_STRSIZE];
218 int result = -ENXIO; 208 int result = -ENXIO;
219 struct uwb_dev_addr *dev_addr; 209 struct uwb_dev_addr *dev_addr;
220 210
221 wlp_wss_uuid_print(buf, sizeof(buf), wssid);
222 d_fnstart(5, dev, "wss %p, wssid %s, registrar %02x:%02x \n",
223 wss, buf, dest->data[1], dest->data[0]);
224 mutex_lock(&wlp->nbmutex); 211 mutex_lock(&wlp->nbmutex);
225 list_for_each_entry(neighbor, &wlp->neighbors, node) { 212 list_for_each_entry(neighbor, &wlp->neighbors, node) {
226 dev_addr = &neighbor->uwb_dev->dev_addr; 213 dev_addr = &neighbor->uwb_dev->dev_addr;
227 if (!memcmp(dest, dev_addr, sizeof(*dest))) { 214 if (!memcmp(dest, dev_addr, sizeof(*dest))) {
228 d_printf(5, dev, "Neighbor %02x:%02x is valid, " 215 result = wlp_enroll_neighbor(wlp, neighbor, wss, wssid);
229 "enrolling. \n",
230 dev_addr->data[1], dev_addr->data[0]);
231 result = wlp_enroll_neighbor(wlp, neighbor, wss,
232 wssid);
233 break; 216 break;
234 } 217 }
235 } 218 }
@@ -237,8 +220,6 @@ int wlp_wss_enroll_target(struct wlp_wss *wss, struct wlp_uuid *wssid,
237 dev_err(dev, "WLP: Cannot find neighbor %02x:%02x. \n", 220 dev_err(dev, "WLP: Cannot find neighbor %02x:%02x. \n",
238 dest->data[1], dest->data[0]); 221 dest->data[1], dest->data[0]);
239 mutex_unlock(&wlp->nbmutex); 222 mutex_unlock(&wlp->nbmutex);
240 d_fnend(5, dev, "wss %p, wssid %s, registrar %02x:%02x, result %d \n",
241 wss, buf, dest->data[1], dest->data[0], result);
242 return result; 223 return result;
243} 224}
244 225
@@ -260,16 +241,11 @@ int wlp_wss_enroll_discovered(struct wlp_wss *wss, struct wlp_uuid *wssid)
260 char buf[WLP_WSS_UUID_STRSIZE]; 241 char buf[WLP_WSS_UUID_STRSIZE];
261 int result = -ENXIO; 242 int result = -ENXIO;
262 243
263 wlp_wss_uuid_print(buf, sizeof(buf), wssid); 244
264 d_fnstart(5, dev, "wss %p, wssid %s \n", wss, buf);
265 mutex_lock(&wlp->nbmutex); 245 mutex_lock(&wlp->nbmutex);
266 list_for_each_entry(neighbor, &wlp->neighbors, node) { 246 list_for_each_entry(neighbor, &wlp->neighbors, node) {
267 list_for_each_entry(wssid_e, &neighbor->wssid, node) { 247 list_for_each_entry(wssid_e, &neighbor->wssid, node) {
268 if (!memcmp(wssid, &wssid_e->wssid, sizeof(*wssid))) { 248 if (!memcmp(wssid, &wssid_e->wssid, sizeof(*wssid))) {
269 d_printf(5, dev, "Found WSSID %s in neighbor "
270 "%02x:%02x cache. \n", buf,
271 neighbor->uwb_dev->dev_addr.data[1],
272 neighbor->uwb_dev->dev_addr.data[0]);
273 result = wlp_enroll_neighbor(wlp, neighbor, 249 result = wlp_enroll_neighbor(wlp, neighbor,
274 wss, wssid); 250 wss, wssid);
275 if (result == 0) /* enrollment success */ 251 if (result == 0) /* enrollment success */
@@ -279,10 +255,11 @@ int wlp_wss_enroll_discovered(struct wlp_wss *wss, struct wlp_uuid *wssid)
279 } 255 }
280 } 256 }
281out: 257out:
282 if (result == -ENXIO) 258 if (result == -ENXIO) {
259 wlp_wss_uuid_print(buf, sizeof(buf), wssid);
283 dev_err(dev, "WLP: Cannot find WSSID %s in cache. \n", buf); 260 dev_err(dev, "WLP: Cannot find WSSID %s in cache. \n", buf);
261 }
284 mutex_unlock(&wlp->nbmutex); 262 mutex_unlock(&wlp->nbmutex);
285 d_fnend(5, dev, "wss %p, wssid %s, result %d \n", wss, buf, result);
286 return result; 263 return result;
287} 264}
288 265
@@ -307,27 +284,22 @@ int wlp_wss_enroll(struct wlp_wss *wss, struct wlp_uuid *wssid,
307 struct uwb_dev_addr bcast = {.data = {0xff, 0xff} }; 284 struct uwb_dev_addr bcast = {.data = {0xff, 0xff} };
308 285
309 wlp_wss_uuid_print(buf, sizeof(buf), wssid); 286 wlp_wss_uuid_print(buf, sizeof(buf), wssid);
287
310 if (wss->state != WLP_WSS_STATE_NONE) { 288 if (wss->state != WLP_WSS_STATE_NONE) {
311 dev_err(dev, "WLP: Already enrolled in WSS %s.\n", buf); 289 dev_err(dev, "WLP: Already enrolled in WSS %s.\n", buf);
312 result = -EEXIST; 290 result = -EEXIST;
313 goto error; 291 goto error;
314 } 292 }
315 if (!memcmp(&bcast, devaddr, sizeof(bcast))) { 293 if (!memcmp(&bcast, devaddr, sizeof(bcast)))
316 d_printf(5, dev, "Request to enroll in discovered WSS "
317 "with WSSID %s \n", buf);
318 result = wlp_wss_enroll_discovered(wss, wssid); 294 result = wlp_wss_enroll_discovered(wss, wssid);
319 } else { 295 else
320 d_printf(5, dev, "Request to enroll in WSSID %s with "
321 "registrar %02x:%02x\n", buf, devaddr->data[1],
322 devaddr->data[0]);
323 result = wlp_wss_enroll_target(wss, wssid, devaddr); 296 result = wlp_wss_enroll_target(wss, wssid, devaddr);
324 }
325 if (result < 0) { 297 if (result < 0) {
326 dev_err(dev, "WLP: Unable to enroll into WSS %s, result %d \n", 298 dev_err(dev, "WLP: Unable to enroll into WSS %s, result %d \n",
327 buf, result); 299 buf, result);
328 goto error; 300 goto error;
329 } 301 }
330 d_printf(2, dev, "Successfully enrolled into WSS %s \n", buf); 302 dev_dbg(dev, "Successfully enrolled into WSS %s \n", buf);
331 result = wlp_wss_sysfs_add(wss, buf); 303 result = wlp_wss_sysfs_add(wss, buf);
332 if (result < 0) { 304 if (result < 0) {
333 dev_err(dev, "WLP: Unable to set up sysfs for WSS kobject.\n"); 305 dev_err(dev, "WLP: Unable to set up sysfs for WSS kobject.\n");
@@ -363,7 +335,6 @@ int wlp_wss_activate(struct wlp_wss *wss)
363 u8 hash; /* only include one hash */ 335 u8 hash; /* only include one hash */
364 } ie_data; 336 } ie_data;
365 337
366 d_fnstart(5, dev, "Activating WSS %p. \n", wss);
367 BUG_ON(wss->state != WLP_WSS_STATE_ENROLLED); 338 BUG_ON(wss->state != WLP_WSS_STATE_ENROLLED);
368 wss->hash = wlp_wss_comp_wssid_hash(&wss->wssid); 339 wss->hash = wlp_wss_comp_wssid_hash(&wss->wssid);
369 wss->tag = wss->hash; 340 wss->tag = wss->hash;
@@ -382,7 +353,6 @@ int wlp_wss_activate(struct wlp_wss *wss)
382 wss->state = WLP_WSS_STATE_ACTIVE; 353 wss->state = WLP_WSS_STATE_ACTIVE;
383 result = 0; 354 result = 0;
384error_wlp_ie: 355error_wlp_ie:
385 d_fnend(5, dev, "Activating WSS %p, result = %d \n", wss, result);
386 return result; 356 return result;
387} 357}
388 358
@@ -405,7 +375,6 @@ int wlp_wss_enroll_activate(struct wlp_wss *wss, struct wlp_uuid *wssid,
405 int result = 0; 375 int result = 0;
406 char buf[WLP_WSS_UUID_STRSIZE]; 376 char buf[WLP_WSS_UUID_STRSIZE];
407 377
408 d_fnstart(5, dev, "Enrollment and activation requested. \n");
409 mutex_lock(&wss->mutex); 378 mutex_lock(&wss->mutex);
410 result = wlp_wss_enroll(wss, wssid, devaddr); 379 result = wlp_wss_enroll(wss, wssid, devaddr);
411 if (result < 0) { 380 if (result < 0) {
@@ -424,7 +393,6 @@ int wlp_wss_enroll_activate(struct wlp_wss *wss, struct wlp_uuid *wssid,
424error_activate: 393error_activate:
425error_enroll: 394error_enroll:
426 mutex_unlock(&wss->mutex); 395 mutex_unlock(&wss->mutex);
427 d_fnend(5, dev, "Completed. result = %d \n", result);
428 return result; 396 return result;
429} 397}
430 398
@@ -447,11 +415,9 @@ int wlp_wss_create_activate(struct wlp_wss *wss, struct wlp_uuid *wssid,
447 struct device *dev = &wlp->rc->uwb_dev.dev; 415 struct device *dev = &wlp->rc->uwb_dev.dev;
448 int result = 0; 416 int result = 0;
449 char buf[WLP_WSS_UUID_STRSIZE]; 417 char buf[WLP_WSS_UUID_STRSIZE];
450 d_fnstart(5, dev, "Request to create new WSS.\n"); 418
451 result = wlp_wss_uuid_print(buf, sizeof(buf), wssid); 419 result = wlp_wss_uuid_print(buf, sizeof(buf), wssid);
452 d_printf(5, dev, "Request to create WSS: WSSID=%s, name=%s, " 420
453 "sec_status=%u, accepting enrollment=%u \n",
454 buf, name, sec_status, accept);
455 if (!mutex_trylock(&wss->mutex)) { 421 if (!mutex_trylock(&wss->mutex)) {
456 dev_err(dev, "WLP: WLP association session in progress.\n"); 422 dev_err(dev, "WLP: WLP association session in progress.\n");
457 return -EBUSY; 423 return -EBUSY;
@@ -498,7 +464,6 @@ int wlp_wss_create_activate(struct wlp_wss *wss, struct wlp_uuid *wssid,
498 result = 0; 464 result = 0;
499out: 465out:
500 mutex_unlock(&wss->mutex); 466 mutex_unlock(&wss->mutex);
501 d_fnend(5, dev, "Completed. result = %d \n", result);
502 return result; 467 return result;
503} 468}
504 469
@@ -520,16 +485,12 @@ int wlp_wss_is_active(struct wlp *wlp, struct wlp_wss *wss,
520{ 485{
521 int result = 0; 486 int result = 0;
522 struct device *dev = &wlp->rc->uwb_dev.dev; 487 struct device *dev = &wlp->rc->uwb_dev.dev;
523 char buf[WLP_WSS_UUID_STRSIZE];
524 DECLARE_COMPLETION_ONSTACK(completion); 488 DECLARE_COMPLETION_ONSTACK(completion);
525 struct wlp_session session; 489 struct wlp_session session;
526 struct sk_buff *skb; 490 struct sk_buff *skb;
527 struct wlp_frame_assoc *resp; 491 struct wlp_frame_assoc *resp;
528 struct wlp_uuid wssid; 492 struct wlp_uuid wssid;
529 493
530 wlp_wss_uuid_print(buf, sizeof(buf), &wss->wssid);
531 d_fnstart(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n",
532 wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]);
533 mutex_lock(&wlp->mutex); 494 mutex_lock(&wlp->mutex);
534 /* Send C1 association frame */ 495 /* Send C1 association frame */
535 result = wlp_send_assoc_frame(wlp, wss, dev_addr, WLP_ASSOC_C1); 496 result = wlp_send_assoc_frame(wlp, wss, dev_addr, WLP_ASSOC_C1);
@@ -565,8 +526,6 @@ int wlp_wss_is_active(struct wlp *wlp, struct wlp_wss *wss,
565 /* Parse message in session->data: it will be either C2 or F0 */ 526 /* Parse message in session->data: it will be either C2 or F0 */
566 skb = session.data; 527 skb = session.data;
567 resp = (void *) skb->data; 528 resp = (void *) skb->data;
568 d_printf(5, dev, "Received response to C1 frame. \n");
569 d_dump(5, dev, skb->data, skb->len > 72 ? 72 : skb->len);
570 if (resp->type == WLP_ASSOC_F0) { 529 if (resp->type == WLP_ASSOC_F0) {
571 result = wlp_parse_f0(wlp, skb); 530 result = wlp_parse_f0(wlp, skb);
572 if (result < 0) 531 if (result < 0)
@@ -584,11 +543,9 @@ int wlp_wss_is_active(struct wlp *wlp, struct wlp_wss *wss,
584 result = 0; 543 result = 0;
585 goto error_resp_parse; 544 goto error_resp_parse;
586 } 545 }
587 if (!memcmp(&wssid, &wss->wssid, sizeof(wssid))) { 546 if (!memcmp(&wssid, &wss->wssid, sizeof(wssid)))
588 d_printf(5, dev, "WSSID in C2 frame matches local "
589 "active WSS.\n");
590 result = 1; 547 result = 1;
591 } else { 548 else {
592 dev_err(dev, "WLP: Received a C2 frame without matching " 549 dev_err(dev, "WLP: Received a C2 frame without matching "
593 "WSSID.\n"); 550 "WSSID.\n");
594 result = 0; 551 result = 0;
@@ -598,8 +555,6 @@ error_resp_parse:
598out: 555out:
599 wlp->session = NULL; 556 wlp->session = NULL;
600 mutex_unlock(&wlp->mutex); 557 mutex_unlock(&wlp->mutex);
601 d_fnend(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n",
602 wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]);
603 return result; 558 return result;
604} 559}
605 560
@@ -620,16 +575,8 @@ int wlp_wss_activate_connection(struct wlp *wlp, struct wlp_wss *wss,
620{ 575{
621 struct device *dev = &wlp->rc->uwb_dev.dev; 576 struct device *dev = &wlp->rc->uwb_dev.dev;
622 int result = 0; 577 int result = 0;
623 char buf[WLP_WSS_UUID_STRSIZE];
624 wlp_wss_uuid_print(buf, sizeof(buf), wssid);
625 d_fnstart(5, dev, "wlp %p, wss %p, wssid %s, tag %u, virtual "
626 "%02x:%02x:%02x:%02x:%02x:%02x \n", wlp, wss, buf, *tag,
627 virt_addr->data[0], virt_addr->data[1], virt_addr->data[2],
628 virt_addr->data[3], virt_addr->data[4], virt_addr->data[5]);
629 578
630 if (!memcmp(wssid, &wss->wssid, sizeof(*wssid))) { 579 if (!memcmp(wssid, &wss->wssid, sizeof(*wssid))) {
631 d_printf(5, dev, "WSSID from neighbor frame matches local "
632 "active WSS.\n");
633 /* Update EDA cache */ 580 /* Update EDA cache */
634 result = wlp_eda_update_node(&wlp->eda, dev_addr, wss, 581 result = wlp_eda_update_node(&wlp->eda, dev_addr, wss,
635 (void *) virt_addr->data, *tag, 582 (void *) virt_addr->data, *tag,
@@ -638,18 +585,9 @@ int wlp_wss_activate_connection(struct wlp *wlp, struct wlp_wss *wss,
638 dev_err(dev, "WLP: Unable to update EDA cache " 585 dev_err(dev, "WLP: Unable to update EDA cache "
639 "with new connected neighbor information.\n"); 586 "with new connected neighbor information.\n");
640 } else { 587 } else {
641 dev_err(dev, "WLP: Neighbor does not have matching " 588 dev_err(dev, "WLP: Neighbor does not have matching WSSID.\n");
642 "WSSID.\n");
643 result = -EINVAL; 589 result = -EINVAL;
644 } 590 }
645
646 d_fnend(5, dev, "wlp %p, wss %p, wssid %s, tag %u, virtual "
647 "%02x:%02x:%02x:%02x:%02x:%02x, result = %d \n",
648 wlp, wss, buf, *tag,
649 virt_addr->data[0], virt_addr->data[1], virt_addr->data[2],
650 virt_addr->data[3], virt_addr->data[4], virt_addr->data[5],
651 result);
652
653 return result; 591 return result;
654} 592}
655 593
@@ -665,7 +603,6 @@ int wlp_wss_connect_neighbor(struct wlp *wlp, struct wlp_wss *wss,
665{ 603{
666 int result; 604 int result;
667 struct device *dev = &wlp->rc->uwb_dev.dev; 605 struct device *dev = &wlp->rc->uwb_dev.dev;
668 char buf[WLP_WSS_UUID_STRSIZE];
669 struct wlp_uuid wssid; 606 struct wlp_uuid wssid;
670 u8 tag; 607 u8 tag;
671 struct uwb_mac_addr virt_addr; 608 struct uwb_mac_addr virt_addr;
@@ -674,9 +611,6 @@ int wlp_wss_connect_neighbor(struct wlp *wlp, struct wlp_wss *wss,
674 struct wlp_frame_assoc *resp; 611 struct wlp_frame_assoc *resp;
675 struct sk_buff *skb; 612 struct sk_buff *skb;
676 613
677 wlp_wss_uuid_print(buf, sizeof(buf), &wss->wssid);
678 d_fnstart(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n",
679 wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]);
680 mutex_lock(&wlp->mutex); 614 mutex_lock(&wlp->mutex);
681 /* Send C3 association frame */ 615 /* Send C3 association frame */
682 result = wlp_send_assoc_frame(wlp, wss, dev_addr, WLP_ASSOC_C3); 616 result = wlp_send_assoc_frame(wlp, wss, dev_addr, WLP_ASSOC_C3);
@@ -711,8 +645,6 @@ int wlp_wss_connect_neighbor(struct wlp *wlp, struct wlp_wss *wss,
711 /* Parse message in session->data: it will be either C4 or F0 */ 645 /* Parse message in session->data: it will be either C4 or F0 */
712 skb = session.data; 646 skb = session.data;
713 resp = (void *) skb->data; 647 resp = (void *) skb->data;
714 d_printf(5, dev, "Received response to C3 frame. \n");
715 d_dump(5, dev, skb->data, skb->len > 72 ? 72 : skb->len);
716 if (resp->type == WLP_ASSOC_F0) { 648 if (resp->type == WLP_ASSOC_F0) {
717 result = wlp_parse_f0(wlp, skb); 649 result = wlp_parse_f0(wlp, skb);
718 if (result < 0) 650 if (result < 0)
@@ -744,8 +676,6 @@ out:
744 WLP_WSS_CONNECT_FAILED); 676 WLP_WSS_CONNECT_FAILED);
745 wlp->session = NULL; 677 wlp->session = NULL;
746 mutex_unlock(&wlp->mutex); 678 mutex_unlock(&wlp->mutex);
747 d_fnend(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n",
748 wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]);
749 return result; 679 return result;
750} 680}
751 681
@@ -780,12 +710,8 @@ void wlp_wss_connect_send(struct work_struct *ws)
780 struct wlp_wss *wss = &wlp->wss; 710 struct wlp_wss *wss = &wlp->wss;
781 int result; 711 int result;
782 struct device *dev = &wlp->rc->uwb_dev.dev; 712 struct device *dev = &wlp->rc->uwb_dev.dev;
783 char buf[WLP_WSS_UUID_STRSIZE];
784 713
785 mutex_lock(&wss->mutex); 714 mutex_lock(&wss->mutex);
786 wlp_wss_uuid_print(buf, sizeof(buf), &wss->wssid);
787 d_fnstart(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n",
788 wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]);
789 if (wss->state < WLP_WSS_STATE_ACTIVE) { 715 if (wss->state < WLP_WSS_STATE_ACTIVE) {
790 if (printk_ratelimit()) 716 if (printk_ratelimit())
791 dev_err(dev, "WLP: Attempting to connect with " 717 dev_err(dev, "WLP: Attempting to connect with "
@@ -836,7 +762,6 @@ out:
836 BUG_ON(wlp->start_queue == NULL); 762 BUG_ON(wlp->start_queue == NULL);
837 wlp->start_queue(wlp); 763 wlp->start_queue(wlp);
838 mutex_unlock(&wss->mutex); 764 mutex_unlock(&wss->mutex);
839 d_fnend(5, dev, "wlp %p, wss %p (wssid %s)\n", wlp, wss, buf);
840} 765}
841 766
842/** 767/**
@@ -855,7 +780,6 @@ int wlp_wss_prep_hdr(struct wlp *wlp, struct wlp_eda_node *eda_entry,
855 struct sk_buff *skb = _skb; 780 struct sk_buff *skb = _skb;
856 struct wlp_frame_std_abbrv_hdr *std_hdr; 781 struct wlp_frame_std_abbrv_hdr *std_hdr;
857 782
858 d_fnstart(6, dev, "wlp %p \n", wlp);
859 if (eda_entry->state == WLP_WSS_CONNECTED) { 783 if (eda_entry->state == WLP_WSS_CONNECTED) {
860 /* Add WLP header */ 784 /* Add WLP header */
861 BUG_ON(skb_headroom(skb) < sizeof(*std_hdr)); 785 BUG_ON(skb_headroom(skb) < sizeof(*std_hdr));
@@ -873,7 +797,6 @@ int wlp_wss_prep_hdr(struct wlp *wlp, struct wlp_eda_node *eda_entry,
873 dev_addr->data[0]); 797 dev_addr->data[0]);
874 result = -EINVAL; 798 result = -EINVAL;
875 } 799 }
876 d_fnend(6, dev, "wlp %p \n", wlp);
877 return result; 800 return result;
878} 801}
879 802
@@ -893,16 +816,9 @@ int wlp_wss_connect_prep(struct wlp *wlp, struct wlp_eda_node *eda_entry,
893{ 816{
894 int result = 0; 817 int result = 0;
895 struct device *dev = &wlp->rc->uwb_dev.dev; 818 struct device *dev = &wlp->rc->uwb_dev.dev;
896 struct uwb_dev_addr *dev_addr = &eda_entry->dev_addr;
897 unsigned char *eth_addr = eda_entry->eth_addr;
898 struct sk_buff *skb = _skb; 819 struct sk_buff *skb = _skb;
899 struct wlp_assoc_conn_ctx *conn_ctx; 820 struct wlp_assoc_conn_ctx *conn_ctx;
900 821
901 d_fnstart(5, dev, "wlp %p\n", wlp);
902 d_printf(5, dev, "To neighbor %02x:%02x with eth "
903 "%02x:%02x:%02x:%02x:%02x:%02x\n", dev_addr->data[1],
904 dev_addr->data[0], eth_addr[0], eth_addr[1], eth_addr[2],
905 eth_addr[3], eth_addr[4], eth_addr[5]);
906 if (eda_entry->state == WLP_WSS_UNCONNECTED) { 822 if (eda_entry->state == WLP_WSS_UNCONNECTED) {
907 /* We don't want any more packets while we set up connection */ 823 /* We don't want any more packets while we set up connection */
908 BUG_ON(wlp->stop_queue == NULL); 824 BUG_ON(wlp->stop_queue == NULL);
@@ -929,12 +845,9 @@ int wlp_wss_connect_prep(struct wlp *wlp, struct wlp_eda_node *eda_entry,
929 "previously. Not retrying. \n"); 845 "previously. Not retrying. \n");
930 result = -ENONET; 846 result = -ENONET;
931 goto out; 847 goto out;
932 } else { /* eda_entry->state == WLP_WSS_CONNECTED */ 848 } else /* eda_entry->state == WLP_WSS_CONNECTED */
933 d_printf(5, dev, "Neighbor is connected, preparing frame.\n");
934 result = wlp_wss_prep_hdr(wlp, eda_entry, skb); 849 result = wlp_wss_prep_hdr(wlp, eda_entry, skb);
935 }
936out: 850out:
937 d_fnend(5, dev, "wlp %p, result = %d \n", wlp, result);
938 return result; 851 return result;
939} 852}
940 853
@@ -957,8 +870,6 @@ int wlp_wss_send_copy(struct wlp *wlp, struct wlp_eda_node *eda_entry,
957 struct sk_buff *copy; 870 struct sk_buff *copy;
958 struct uwb_dev_addr *dev_addr = &eda_entry->dev_addr; 871 struct uwb_dev_addr *dev_addr = &eda_entry->dev_addr;
959 872
960 d_fnstart(5, dev, "to neighbor %02x:%02x, skb (%p) \n",
961 dev_addr->data[1], dev_addr->data[0], skb);
962 copy = skb_copy(skb, GFP_ATOMIC); 873 copy = skb_copy(skb, GFP_ATOMIC);
963 if (copy == NULL) { 874 if (copy == NULL) {
964 if (printk_ratelimit()) 875 if (printk_ratelimit())
@@ -988,8 +899,6 @@ int wlp_wss_send_copy(struct wlp *wlp, struct wlp_eda_node *eda_entry,
988 dev_kfree_skb_irq(copy);/*we need to free if tx fails */ 899 dev_kfree_skb_irq(copy);/*we need to free if tx fails */
989 } 900 }
990out: 901out:
991 d_fnend(5, dev, "to neighbor %02x:%02x \n", dev_addr->data[1],
992 dev_addr->data[0]);
993 return result; 902 return result;
994} 903}
995 904
@@ -1005,7 +914,7 @@ int wlp_wss_setup(struct net_device *net_dev, struct wlp_wss *wss)
1005 struct wlp *wlp = container_of(wss, struct wlp, wss); 914 struct wlp *wlp = container_of(wss, struct wlp, wss);
1006 struct device *dev = &wlp->rc->uwb_dev.dev; 915 struct device *dev = &wlp->rc->uwb_dev.dev;
1007 int result = 0; 916 int result = 0;
1008 d_fnstart(5, dev, "wss (%p) \n", wss); 917
1009 mutex_lock(&wss->mutex); 918 mutex_lock(&wss->mutex);
1010 wss->kobj.parent = &net_dev->dev.kobj; 919 wss->kobj.parent = &net_dev->dev.kobj;
1011 if (!is_valid_ether_addr(net_dev->dev_addr)) { 920 if (!is_valid_ether_addr(net_dev->dev_addr)) {
@@ -1018,7 +927,6 @@ int wlp_wss_setup(struct net_device *net_dev, struct wlp_wss *wss)
1018 sizeof(wss->virtual_addr.data)); 927 sizeof(wss->virtual_addr.data));
1019out: 928out:
1020 mutex_unlock(&wss->mutex); 929 mutex_unlock(&wss->mutex);
1021 d_fnend(5, dev, "wss (%p) \n", wss);
1022 return result; 930 return result;
1023} 931}
1024EXPORT_SYMBOL_GPL(wlp_wss_setup); 932EXPORT_SYMBOL_GPL(wlp_wss_setup);
@@ -1035,8 +943,7 @@ EXPORT_SYMBOL_GPL(wlp_wss_setup);
1035void wlp_wss_remove(struct wlp_wss *wss) 943void wlp_wss_remove(struct wlp_wss *wss)
1036{ 944{
1037 struct wlp *wlp = container_of(wss, struct wlp, wss); 945 struct wlp *wlp = container_of(wss, struct wlp, wss);
1038 struct device *dev = &wlp->rc->uwb_dev.dev; 946
1039 d_fnstart(5, dev, "wss (%p) \n", wss);
1040 mutex_lock(&wss->mutex); 947 mutex_lock(&wss->mutex);
1041 if (wss->state == WLP_WSS_STATE_ACTIVE) 948 if (wss->state == WLP_WSS_STATE_ACTIVE)
1042 uwb_rc_ie_rm(wlp->rc, UWB_IE_WLP); 949 uwb_rc_ie_rm(wlp->rc, UWB_IE_WLP);
@@ -1050,6 +957,5 @@ void wlp_wss_remove(struct wlp_wss *wss)
1050 wlp_eda_release(&wlp->eda); 957 wlp_eda_release(&wlp->eda);
1051 wlp_eda_init(&wlp->eda); 958 wlp_eda_init(&wlp->eda);
1052 mutex_unlock(&wss->mutex); 959 mutex_unlock(&wss->mutex);
1053 d_fnend(5, dev, "wss (%p) \n", wss);
1054} 960}
1055EXPORT_SYMBOL_GPL(wlp_wss_remove); 961EXPORT_SYMBOL_GPL(wlp_wss_remove);
diff --git a/include/linux/usb/wusb-wa.h b/include/linux/usb/wusb-wa.h
index a102561e7026..fb7c359bdfba 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 f9ccbd9a2ced..c02128991ff7 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
@@ -66,6 +67,7 @@ struct uwb_dev {
66 struct uwb_dev_addr dev_addr; 67 struct uwb_dev_addr dev_addr;
67 int beacon_slot; 68 int beacon_slot;
68 DECLARE_BITMAP(streams, UWB_NUM_STREAMS); 69 DECLARE_BITMAP(streams, UWB_NUM_STREAMS);
70 DECLARE_BITMAP(last_availability_bm, UWB_NUM_MAS);
69}; 71};
70#define to_uwb_dev(d) container_of(d, struct uwb_dev, dev) 72#define to_uwb_dev(d) container_of(d, struct uwb_dev, dev)
71 73
@@ -86,12 +88,31 @@ struct uwb_notifs_chain {
86 struct mutex mutex; 88 struct mutex mutex;
87}; 89};
88 90
91/* Beacon cache list */
92struct uwb_beca {
93 struct list_head list;
94 size_t entries;
95 struct mutex mutex;
96};
97
98/* Event handling thread. */
99struct uwbd {
100 int pid;
101 struct task_struct *task;
102 wait_queue_head_t wq;
103 struct list_head event_list;
104 spinlock_t event_list_lock;
105};
106
89/** 107/**
90 * struct uwb_mas_bm - a bitmap of all MAS in a superframe 108 * struct uwb_mas_bm - a bitmap of all MAS in a superframe
91 * @bm: a bitmap of length #UWB_NUM_MAS 109 * @bm: a bitmap of length #UWB_NUM_MAS
92 */ 110 */
93struct uwb_mas_bm { 111struct uwb_mas_bm {
94 DECLARE_BITMAP(bm, UWB_NUM_MAS); 112 DECLARE_BITMAP(bm, UWB_NUM_MAS);
113 DECLARE_BITMAP(unsafe_bm, UWB_NUM_MAS);
114 int safe;
115 int unsafe;
95}; 116};
96 117
97/** 118/**
@@ -117,14 +138,24 @@ struct uwb_mas_bm {
117 * FIXME: further target states TBD. 138 * FIXME: further target states TBD.
118 */ 139 */
119enum uwb_rsv_state { 140enum uwb_rsv_state {
120 UWB_RSV_STATE_NONE, 141 UWB_RSV_STATE_NONE = 0,
121 UWB_RSV_STATE_O_INITIATED, 142 UWB_RSV_STATE_O_INITIATED,
122 UWB_RSV_STATE_O_PENDING, 143 UWB_RSV_STATE_O_PENDING,
123 UWB_RSV_STATE_O_MODIFIED, 144 UWB_RSV_STATE_O_MODIFIED,
124 UWB_RSV_STATE_O_ESTABLISHED, 145 UWB_RSV_STATE_O_ESTABLISHED,
146 UWB_RSV_STATE_O_TO_BE_MOVED,
147 UWB_RSV_STATE_O_MOVE_EXPANDING,
148 UWB_RSV_STATE_O_MOVE_COMBINING,
149 UWB_RSV_STATE_O_MOVE_REDUCING,
125 UWB_RSV_STATE_T_ACCEPTED, 150 UWB_RSV_STATE_T_ACCEPTED,
126 UWB_RSV_STATE_T_DENIED, 151 UWB_RSV_STATE_T_DENIED,
152 UWB_RSV_STATE_T_CONFLICT,
127 UWB_RSV_STATE_T_PENDING, 153 UWB_RSV_STATE_T_PENDING,
154 UWB_RSV_STATE_T_EXPANDING_ACCEPTED,
155 UWB_RSV_STATE_T_EXPANDING_CONFLICT,
156 UWB_RSV_STATE_T_EXPANDING_PENDING,
157 UWB_RSV_STATE_T_EXPANDING_DENIED,
158 UWB_RSV_STATE_T_RESIZED,
128 159
129 UWB_RSV_STATE_LAST, 160 UWB_RSV_STATE_LAST,
130}; 161};
@@ -149,6 +180,12 @@ struct uwb_rsv_target {
149 }; 180 };
150}; 181};
151 182
183struct uwb_rsv_move {
184 struct uwb_mas_bm final_mas;
185 struct uwb_ie_drp *companion_drp_ie;
186 struct uwb_mas_bm companion_mas;
187};
188
152/* 189/*
153 * Number of streams reserved for reservations targeted at DevAddrs. 190 * Number of streams reserved for reservations targeted at DevAddrs.
154 */ 191 */
@@ -186,6 +223,7 @@ typedef void (*uwb_rsv_cb_f)(struct uwb_rsv *rsv);
186 * 223 *
187 * @status: negotiation status 224 * @status: negotiation status
188 * @stream: stream index allocated for this reservation 225 * @stream: stream index allocated for this reservation
226 * @tiebreaker: conflict tiebreaker for this reservation
189 * @mas: reserved MAS 227 * @mas: reserved MAS
190 * @drp_ie: the DRP IE 228 * @drp_ie: the DRP IE
191 * @ie_valid: true iff the DRP IE matches the reservation parameters 229 * @ie_valid: true iff the DRP IE matches the reservation parameters
@@ -201,25 +239,29 @@ struct uwb_rsv {
201 struct uwb_rc *rc; 239 struct uwb_rc *rc;
202 struct list_head rc_node; 240 struct list_head rc_node;
203 struct list_head pal_node; 241 struct list_head pal_node;
242 struct kref kref;
204 243
205 struct uwb_dev *owner; 244 struct uwb_dev *owner;
206 struct uwb_rsv_target target; 245 struct uwb_rsv_target target;
207 enum uwb_drp_type type; 246 enum uwb_drp_type type;
208 int max_mas; 247 int max_mas;
209 int min_mas; 248 int min_mas;
210 int sparsity; 249 int max_interval;
211 bool is_multicast; 250 bool is_multicast;
212 251
213 uwb_rsv_cb_f callback; 252 uwb_rsv_cb_f callback;
214 void *pal_priv; 253 void *pal_priv;
215 254
216 enum uwb_rsv_state state; 255 enum uwb_rsv_state state;
256 bool needs_release_companion_mas;
217 u8 stream; 257 u8 stream;
258 u8 tiebreaker;
218 struct uwb_mas_bm mas; 259 struct uwb_mas_bm mas;
219 struct uwb_ie_drp *drp_ie; 260 struct uwb_ie_drp *drp_ie;
261 struct uwb_rsv_move mv;
220 bool ie_valid; 262 bool ie_valid;
221 struct timer_list timer; 263 struct timer_list timer;
222 bool expired; 264 struct work_struct handle_timeout_work;
223}; 265};
224 266
225static const 267static const
@@ -261,6 +303,13 @@ struct uwb_drp_avail {
261 bool ie_valid; 303 bool ie_valid;
262}; 304};
263 305
306struct uwb_drp_backoff_win {
307 u8 window;
308 u8 n;
309 int total_expired;
310 struct timer_list timer;
311 bool can_reserve_extra_mases;
312};
264 313
265const char *uwb_rsv_state_str(enum uwb_rsv_state state); 314const char *uwb_rsv_state_str(enum uwb_rsv_state state);
266const char *uwb_rsv_type_str(enum uwb_drp_type type); 315const char *uwb_rsv_type_str(enum uwb_drp_type type);
@@ -276,6 +325,8 @@ void uwb_rsv_terminate(struct uwb_rsv *rsv);
276 325
277void uwb_rsv_accept(struct uwb_rsv *rsv, uwb_rsv_cb_f cb, void *pal_priv); 326void uwb_rsv_accept(struct uwb_rsv *rsv, uwb_rsv_cb_f cb, void *pal_priv);
278 327
328void uwb_rsv_get_usable_mas(struct uwb_rsv *orig_rsv, struct uwb_mas_bm *mas);
329
279/** 330/**
280 * Radio Control Interface instance 331 * Radio Control Interface instance
281 * 332 *
@@ -337,23 +388,33 @@ struct uwb_rc {
337 u8 ctx_roll; 388 u8 ctx_roll;
338 389
339 int beaconing; /* Beaconing state [channel number] */ 390 int beaconing; /* Beaconing state [channel number] */
391 int beaconing_forced;
340 int scanning; 392 int scanning;
341 enum uwb_scan_type scan_type:3; 393 enum uwb_scan_type scan_type:3;
342 unsigned ready:1; 394 unsigned ready:1;
343 struct uwb_notifs_chain notifs_chain; 395 struct uwb_notifs_chain notifs_chain;
396 struct uwb_beca uwb_beca;
397
398 struct uwbd uwbd;
344 399
400 struct uwb_drp_backoff_win bow;
345 struct uwb_drp_avail drp_avail; 401 struct uwb_drp_avail drp_avail;
346 struct list_head reservations; 402 struct list_head reservations;
403 struct list_head cnflt_alien_list;
404 struct uwb_mas_bm cnflt_alien_bitmap;
347 struct mutex rsvs_mutex; 405 struct mutex rsvs_mutex;
406 spinlock_t rsvs_lock;
348 struct workqueue_struct *rsv_workq; 407 struct workqueue_struct *rsv_workq;
349 struct work_struct rsv_update_work;
350 408
409 struct delayed_work rsv_update_work;
410 struct delayed_work rsv_alien_bp_work;
411 int set_drp_ie_pending;
351 struct mutex ies_mutex; 412 struct mutex ies_mutex;
352 struct uwb_rc_cmd_set_ie *ies; 413 struct uwb_rc_cmd_set_ie *ies;
353 size_t ies_capacity; 414 size_t ies_capacity;
354 415
355 spinlock_t pal_lock;
356 struct list_head pals; 416 struct list_head pals;
417 int active_pals;
357 418
358 struct uwb_dbg *dbg; 419 struct uwb_dbg *dbg;
359}; 420};
@@ -361,11 +422,19 @@ struct uwb_rc {
361 422
362/** 423/**
363 * struct uwb_pal - a UWB PAL 424 * struct uwb_pal - a UWB PAL
364 * @name: descriptive name for this PAL (wushc, wlp, etc.). 425 * @name: descriptive name for this PAL (wusbhc, wlp, etc.).
365 * @device: a device for the PAL. Used to link the PAL and the radio 426 * @device: a device for the PAL. Used to link the PAL and the radio
366 * controller in sysfs. 427 * controller in sysfs.
428 * @rc: the radio controller the PAL uses.
429 * @channel_changed: called when the channel used by the radio changes.
430 * A channel of -1 means the channel has been stopped.
367 * @new_rsv: called when a peer requests a reservation (may be NULL if 431 * @new_rsv: called when a peer requests a reservation (may be NULL if
368 * the PAL cannot accept reservation requests). 432 * the PAL cannot accept reservation requests).
433 * @channel: channel being used by the PAL; 0 if the PAL isn't using
434 * the radio; -1 if the PAL wishes to use the radio but
435 * cannot.
436 * @debugfs_dir: a debugfs directory which the PAL can use for its own
437 * debugfs files.
369 * 438 *
370 * A Protocol Adaptation Layer (PAL) is a user of the WiMedia UWB 439 * A Protocol Adaptation Layer (PAL) is a user of the WiMedia UWB
371 * radio platform (e.g., WUSB, WLP or Bluetooth UWB AMP). 440 * radio platform (e.g., WUSB, WLP or Bluetooth UWB AMP).
@@ -384,12 +453,21 @@ struct uwb_pal {
384 struct list_head node; 453 struct list_head node;
385 const char *name; 454 const char *name;
386 struct device *device; 455 struct device *device;
387 void (*new_rsv)(struct uwb_rsv *rsv); 456 struct uwb_rc *rc;
457
458 void (*channel_changed)(struct uwb_pal *pal, int channel);
459 void (*new_rsv)(struct uwb_pal *pal, struct uwb_rsv *rsv);
460
461 int channel;
462 struct dentry *debugfs_dir;
388}; 463};
389 464
390void uwb_pal_init(struct uwb_pal *pal); 465void uwb_pal_init(struct uwb_pal *pal);
391int uwb_pal_register(struct uwb_rc *rc, struct uwb_pal *pal); 466int uwb_pal_register(struct uwb_pal *pal);
392void uwb_pal_unregister(struct uwb_rc *rc, struct uwb_pal *pal); 467void uwb_pal_unregister(struct uwb_pal *pal);
468
469int uwb_radio_start(struct uwb_pal *pal);
470void uwb_radio_stop(struct uwb_pal *pal);
393 471
394/* 472/*
395 * General public API 473 * General public API
@@ -443,8 +521,6 @@ ssize_t uwb_rc_vcmd(struct uwb_rc *rc, const char *cmd_name,
443 struct uwb_rccb *cmd, size_t cmd_size, 521 struct uwb_rccb *cmd, size_t cmd_size,
444 u8 expected_type, u16 expected_event, 522 u8 expected_type, u16 expected_event,
445 struct uwb_rceb **preply); 523 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 524
449size_t __uwb_addr_print(char *, size_t, const unsigned char *, int); 525size_t __uwb_addr_print(char *, size_t, const unsigned char *, int);
450 526
@@ -520,6 +596,8 @@ void uwb_rc_rm(struct uwb_rc *);
520void uwb_rc_neh_grok(struct uwb_rc *, void *, size_t); 596void uwb_rc_neh_grok(struct uwb_rc *, void *, size_t);
521void uwb_rc_neh_error(struct uwb_rc *, int); 597void uwb_rc_neh_error(struct uwb_rc *, int);
522void uwb_rc_reset_all(struct uwb_rc *rc); 598void uwb_rc_reset_all(struct uwb_rc *rc);
599void uwb_rc_pre_reset(struct uwb_rc *rc);
600void uwb_rc_post_reset(struct uwb_rc *rc);
523 601
524/** 602/**
525 * uwb_rsv_is_owner - is the owner of this reservation the RC? 603 * uwb_rsv_is_owner - is the owner of this reservation the RC?
@@ -531,7 +609,9 @@ static inline bool uwb_rsv_is_owner(struct uwb_rsv *rsv)
531} 609}
532 610
533/** 611/**
534 * Events generated by UWB that can be passed to any listeners 612 * enum uwb_notifs - UWB events that can be passed to any listeners
613 * @UWB_NOTIF_ONAIR: a new neighbour has joined the beacon group.
614 * @UWB_NOTIF_OFFAIR: a neighbour has left the beacon group.
535 * 615 *
536 * Higher layers can register callback functions with the radio 616 * Higher layers can register callback functions with the radio
537 * controller using uwb_notifs_register(). The radio controller 617 * controller using uwb_notifs_register(). The radio controller
@@ -539,8 +619,6 @@ static inline bool uwb_rsv_is_owner(struct uwb_rsv *rsv)
539 * nodes when an event occurs. 619 * nodes when an event occurs.
540 */ 620 */
541enum uwb_notifs { 621enum 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, 622 UWB_NOTIF_ONAIR,
545 UWB_NOTIF_OFFAIR, 623 UWB_NOTIF_OFFAIR,
546}; 624};
@@ -652,22 +730,9 @@ static inline int edc_inc(struct edc *err_hist, u16 max_err, u16 timeframe)
652 730
653/* Information Element handling */ 731/* Information Element handling */
654 732
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); 733struct 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, 734int uwb_rc_ie_add(struct uwb_rc *uwb_rc, const struct uwb_ie_hdr *ies, size_t size);
665 const void *buf, size_t size); 735int uwb_rc_ie_rm(struct uwb_rc *uwb_rc, enum uwb_ie element_id);
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);
670
671 736
672/* 737/*
673 * Transmission statistics 738 * Transmission statistics
diff --git a/include/linux/uwb/debug-cmd.h b/include/linux/uwb/debug-cmd.h
index 1141f41bab5c..8da004e25628 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 {
@@ -39,18 +43,25 @@ struct uwb_dbg_cmd_rsv_establish {
39 __u8 type; 43 __u8 type;
40 __u16 max_mas; 44 __u16 max_mas;
41 __u16 min_mas; 45 __u16 min_mas;
42 __u8 sparsity; 46 __u8 max_interval;
43}; 47};
44 48
45struct uwb_dbg_cmd_rsv_terminate { 49struct 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
deleted file mode 100644
index a86a73fe303f..000000000000
--- a/include/linux/uwb/debug.h
+++ /dev/null
@@ -1,82 +0,0 @@
1/*
2 * Ultra Wide Band
3 * Debug Support
4 *
5 * Copyright (C) 2005-2006 Intel Corporation
6 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version
10 * 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
21 *
22 *
23 * FIXME: doc
24 * Invoke like:
25 *
26 * #define D_LOCAL 4
27 * #include <linux/uwb/debug.h>
28 *
29 * At the end of your include files.
30 */
31#include <linux/types.h>
32
33struct device;
34extern void dump_bytes(struct device *dev, const void *_buf, size_t rsize);
35
36/* Master debug switch; !0 enables, 0 disables */
37#define D_MASTER (!0)
38
39/* Local (per-file) debug switch; #define before #including */
40#ifndef D_LOCAL
41#define D_LOCAL 0
42#endif
43
44#undef __d_printf
45#undef d_fnstart
46#undef d_fnend
47#undef d_printf
48#undef d_dump
49
50#define __d_printf(l, _tag, _dev, f, a...) \
51do { \
52 struct device *__dev = (_dev); \
53 if (D_MASTER && D_LOCAL >= (l)) { \
54 char __head[64] = ""; \
55 if (_dev != NULL) { \
56 if ((unsigned long)__dev < 4096) \
57 printk(KERN_ERR "E: Corrupt dev %p\n", \
58 __dev); \
59 else \
60 snprintf(__head, sizeof(__head), \
61 "%s %s: ", \
62 dev_driver_string(__dev), \
63 __dev->bus_id); \
64 } \
65 printk(KERN_ERR "%s%s" _tag ": " f, __head, \
66 __func__, ## a); \
67 } \
68} while (0 && _dev)
69
70#define d_fnstart(l, _dev, f, a...) \
71 __d_printf(l, " FNSTART", _dev, f, ## a)
72#define d_fnend(l, _dev, f, a...) \
73 __d_printf(l, " FNEND", _dev, f, ## a)
74#define d_printf(l, _dev, f, a...) \
75 __d_printf(l, "", _dev, f, ## a)
76#define d_dump(l, _dev, ptr, size) \
77do { \
78 struct device *__dev = _dev; \
79 if (D_MASTER && D_LOCAL >= (l)) \
80 dump_bytes(__dev, ptr, size); \
81} while (0 && _dev)
82#define d_test(l) (D_MASTER && D_LOCAL >= (l))
diff --git a/include/linux/uwb/spec.h b/include/linux/uwb/spec.h
index 198c15f8e251..b52e44f1bd33 100644
--- a/include/linux/uwb/spec.h
+++ b/include/linux/uwb/spec.h
@@ -59,6 +59,11 @@ enum { UWB_NUM_ZONES = 16 };
59#define UWB_MAS_PER_ZONE (UWB_NUM_MAS / UWB_NUM_ZONES) 59#define UWB_MAS_PER_ZONE (UWB_NUM_MAS / UWB_NUM_ZONES)
60 60
61/* 61/*
62 * Number of MAS required before a row can be considered available.
63 */
64#define UWB_USABLE_MAS_PER_ROW (UWB_NUM_ZONES - 1)
65
66/*
62 * Number of streams per DRP reservation between a pair of devices. 67 * Number of streams per DRP reservation between a pair of devices.
63 * 68 *
64 * [ECMA-368] section 16.8.6. 69 * [ECMA-368] section 16.8.6.
@@ -94,6 +99,26 @@ enum { UWB_BEACON_SLOT_LENGTH_US = 85 };
94enum { UWB_MAX_LOST_BEACONS = 3 }; 99enum { UWB_MAX_LOST_BEACONS = 3 };
95 100
96/* 101/*
102 * mDRPBackOffWinMin
103 *
104 * The minimum number of superframes to wait before trying to reserve
105 * extra MAS.
106 *
107 * [ECMA-368] section 17.16
108 */
109enum { UWB_DRP_BACKOFF_WIN_MIN = 2 };
110
111/*
112 * mDRPBackOffWinMax
113 *
114 * The maximum number of superframes to wait before trying to reserve
115 * extra MAS.
116 *
117 * [ECMA-368] section 17.16
118 */
119enum { UWB_DRP_BACKOFF_WIN_MAX = 16 };
120
121/*
97 * Length of a superframe in microseconds. 122 * Length of a superframe in microseconds.
98 */ 123 */
99#define UWB_SUPERFRAME_LENGTH_US (UWB_MAS_LENGTH_US * UWB_NUM_MAS) 124#define UWB_SUPERFRAME_LENGTH_US (UWB_MAS_LENGTH_US * UWB_NUM_MAS)
@@ -200,6 +225,12 @@ enum uwb_drp_reason {
200 UWB_DRP_REASON_MODIFIED, 225 UWB_DRP_REASON_MODIFIED,
201}; 226};
202 227
228/** Relinquish Request Reason Codes ([ECMA-368] table 113) */
229enum uwb_relinquish_req_reason {
230 UWB_RELINQUISH_REQ_REASON_NON_SPECIFIC = 0,
231 UWB_RELINQUISH_REQ_REASON_OVER_ALLOCATION,
232};
233
203/** 234/**
204 * DRP Notification Reason Codes (WHCI 0.95 [3.1.4.9]) 235 * DRP Notification Reason Codes (WHCI 0.95 [3.1.4.9])
205 */ 236 */
@@ -252,6 +283,7 @@ enum uwb_ie {
252 UWB_APP_SPEC_PROBE_IE = 15, 283 UWB_APP_SPEC_PROBE_IE = 15,
253 UWB_IDENTIFICATION_IE = 19, 284 UWB_IDENTIFICATION_IE = 19,
254 UWB_MASTER_KEY_ID_IE = 20, 285 UWB_MASTER_KEY_ID_IE = 20,
286 UWB_RELINQUISH_REQUEST_IE = 21,
255 UWB_IE_WLP = 250, /* WiMedia Logical Link Control Protocol WLP 0.99 */ 287 UWB_IE_WLP = 250, /* WiMedia Logical Link Control Protocol WLP 0.99 */
256 UWB_APP_SPEC_IE = 255, 288 UWB_APP_SPEC_IE = 255,
257}; 289};
@@ -365,6 +397,27 @@ struct uwb_ie_drp_avail {
365 DECLARE_BITMAP(bmp, UWB_NUM_MAS); 397 DECLARE_BITMAP(bmp, UWB_NUM_MAS);
366} __attribute__((packed)); 398} __attribute__((packed));
367 399
400/* Relinqish Request IE ([ECMA-368] section 16.8.19). */
401struct uwb_relinquish_request_ie {
402 struct uwb_ie_hdr hdr;
403 __le16 relinquish_req_control;
404 struct uwb_dev_addr dev_addr;
405 struct uwb_drp_alloc allocs[];
406} __attribute__((packed));
407
408static inline int uwb_ie_relinquish_req_reason_code(struct uwb_relinquish_request_ie *ie)
409{
410 return (le16_to_cpu(ie->relinquish_req_control) >> 0) & 0xf;
411}
412
413static inline void uwb_ie_relinquish_req_set_reason_code(struct uwb_relinquish_request_ie *ie,
414 int reason_code)
415{
416 u16 ctrl = le16_to_cpu(ie->relinquish_req_control);
417 ctrl = (ctrl & ~(0xf << 0)) | (reason_code << 0);
418 ie->relinquish_req_control = cpu_to_le16(ctrl);
419}
420
368/** 421/**
369 * The Vendor ID is set to an OUI that indicates the vendor of the device. 422 * The Vendor ID is set to an OUI that indicates the vendor of the device.
370 * ECMA-368 [16.8.10] 423 * ECMA-368 [16.8.10]
diff --git a/include/linux/uwb/umc.h b/include/linux/uwb/umc.h
index 36a39e34f8d7..4b4fc0f43855 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 033545e145c7..ac95ce6606ac 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 *);