aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@csr.com>2008-11-17 10:53:42 -0500
committerDavid Vrabel <david.vrabel@csr.com>2008-11-19 09:46:33 -0500
commit6fae35f9cea92793a98b2d9ab21235e5ae035581 (patch)
tree82142169ff2ccada8c6c98beb6da59cafe8d913d /drivers/usb
parente17be2b2a95b43fe0d5878adf330701bb7a77115 (diff)
uwb: add basic radio manager
The UWB radio manager coordinates the use of the radio between the PALs that may be using it. PALs request use of the radio with uwb_radio_start() and the radio manager will start beaconing if its not already doing so. When the last PAL has called uwb_radio_stop() beaconing will be stopped. In the future, the radio manager will have a more sophisticated channel selection algorithm, probably following the Channel Selection Policy from the WiMedia Alliance when it is finalized. For now, channel 9 (BG1, TFC1) is selected. The user may override the channel selected by the radio manager and may force the radio to stop beaconing. The WUSB Host Controller PAL makes use of this and there are two new debug PAL commands that can be used for testing. Signed-off-by: David Vrabel <david.vrabel@csr.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/hwa-hc.c1
-rw-r--r--drivers/usb/host/whci/hcd.c2
-rw-r--r--drivers/usb/wusbcore/devconnect.c5
-rw-r--r--drivers/usb/wusbcore/mmc.c75
-rw-r--r--drivers/usb/wusbcore/pal.c16
-rw-r--r--drivers/usb/wusbcore/wusbhc.h8
6 files changed, 33 insertions, 74 deletions
diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c
index 2827353e97e1..2a4d36fa70b0 100644
--- a/drivers/usb/host/hwa-hc.c
+++ b/drivers/usb/host/hwa-hc.c
@@ -221,7 +221,6 @@ static void hwahc_op_stop(struct usb_hcd *usb_hcd)
221 221
222 d_fnstart(4, dev, "(hwahc %p)\n", hwahc); 222 d_fnstart(4, dev, "(hwahc %p)\n", hwahc);
223 mutex_lock(&wusbhc->mutex); 223 mutex_lock(&wusbhc->mutex);
224 wusbhc_stop(wusbhc);
225 wusb_cluster_id_put(wusbhc->cluster_id); 224 wusb_cluster_id_put(wusbhc->cluster_id);
226 mutex_unlock(&wusbhc->mutex); 225 mutex_unlock(&wusbhc->mutex);
227 d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result); 226 d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result);
diff --git a/drivers/usb/host/whci/hcd.c b/drivers/usb/host/whci/hcd.c
index de1e07271b81..f599f89d3be1 100644
--- a/drivers/usb/host/whci/hcd.c
+++ b/drivers/usb/host/whci/hcd.c
@@ -91,8 +91,6 @@ static void whc_stop(struct usb_hcd *usb_hcd)
91 91
92 mutex_lock(&wusbhc->mutex); 92 mutex_lock(&wusbhc->mutex);
93 93
94 wusbhc_stop(wusbhc);
95
96 /* stop HC */ 94 /* stop HC */
97 le_writel(0, whc->base + WUSBINTR); 95 le_writel(0, whc->base + WUSBINTR);
98 whc_write_wusbcmd(whc, WUSBCMD_RUN, 0); 96 whc_write_wusbcmd(whc, WUSBCMD_RUN, 0);
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c
index c01c7a80744c..08a1ec903867 100644
--- a/drivers/usb/wusbcore/devconnect.c
+++ b/drivers/usb/wusbcore/devconnect.c
@@ -1124,8 +1124,7 @@ void wusbhc_devconnect_destroy(struct wusbhc *wusbhc)
1124 * FIXME: This also enables the keep alives but this is not necessary 1124 * FIXME: This also enables the keep alives but this is not necessary
1125 * until there are connected and authenticated devices. 1125 * until there are connected and authenticated devices.
1126 */ 1126 */
1127int wusbhc_devconnect_start(struct wusbhc *wusbhc, 1127int wusbhc_devconnect_start(struct wusbhc *wusbhc)
1128 const struct wusb_ckhdid *chid)
1129{ 1128{
1130 struct device *dev = wusbhc->dev; 1129 struct device *dev = wusbhc->dev;
1131 struct wuie_host_info *hi; 1130 struct wuie_host_info *hi;
@@ -1138,7 +1137,7 @@ int wusbhc_devconnect_start(struct wusbhc *wusbhc,
1138 hi->hdr.bLength = sizeof(*hi); 1137 hi->hdr.bLength = sizeof(*hi);
1139 hi->hdr.bIEIdentifier = WUIE_ID_HOST_INFO; 1138 hi->hdr.bIEIdentifier = WUIE_ID_HOST_INFO;
1140 hi->attributes = cpu_to_le16((wusbhc->rsv->stream << 3) | WUIE_HI_CAP_ALL); 1139 hi->attributes = cpu_to_le16((wusbhc->rsv->stream << 3) | WUIE_HI_CAP_ALL);
1141 hi->CHID = *chid; 1140 hi->CHID = wusbhc->chid;
1142 result = wusbhc_mmcie_set(wusbhc, 0, 0, &hi->hdr); 1141 result = wusbhc_mmcie_set(wusbhc, 0, 0, &hi->hdr);
1143 if (result < 0) { 1142 if (result < 0) {
1144 dev_err(dev, "Cannot add Host Info MMCIE: %d\n", result); 1143 dev_err(dev, "Cannot add Host Info MMCIE: %d\n", result);
diff --git a/drivers/usb/wusbcore/mmc.c b/drivers/usb/wusbcore/mmc.c
index af2aee0fdffa..5463ecebafdf 100644
--- a/drivers/usb/wusbcore/mmc.c
+++ b/drivers/usb/wusbcore/mmc.c
@@ -162,12 +162,11 @@ EXPORT_SYMBOL_GPL(wusbhc_mmcie_rm);
162/* 162/*
163 * wusbhc_start - start transmitting MMCs and accepting connections 163 * wusbhc_start - start transmitting MMCs and accepting connections
164 * @wusbhc: the HC to start 164 * @wusbhc: the HC to start
165 * @chid: the CHID to use for this host
166 * 165 *
167 * Establishes a cluster reservation, enables device connections, and 166 * Establishes a cluster reservation, enables device connections, and
168 * starts MMCs with appropriate DNTS parameters. 167 * starts MMCs with appropriate DNTS parameters.
169 */ 168 */
170int wusbhc_start(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid) 169int wusbhc_start(struct wusbhc *wusbhc)
171{ 170{
172 int result; 171 int result;
173 struct device *dev = wusbhc->dev; 172 struct device *dev = wusbhc->dev;
@@ -181,7 +180,7 @@ int wusbhc_start(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid)
181 goto error_rsv_establish; 180 goto error_rsv_establish;
182 } 181 }
183 182
184 result = wusbhc_devconnect_start(wusbhc, chid); 183 result = wusbhc_devconnect_start(wusbhc);
185 if (result < 0) { 184 if (result < 0) {
186 dev_err(dev, "error enabling device connections: %d\n", result); 185 dev_err(dev, "error enabling device connections: %d\n", result);
187 goto error_devconnect_start; 186 goto error_devconnect_start;
@@ -219,34 +218,6 @@ error_rsv_establish:
219} 218}
220 219
221/* 220/*
222 * Disconnect all from the WUSB Channel
223 *
224 * Send a Host Disconnect IE in the MMC, wait, don't send it any more
225 */
226static int __wusbhc_host_disconnect_ie(struct wusbhc *wusbhc)
227{
228 int result = -ENOMEM;
229 struct wuie_host_disconnect *host_disconnect_ie;
230 might_sleep();
231 host_disconnect_ie = kmalloc(sizeof(*host_disconnect_ie), GFP_KERNEL);
232 if (host_disconnect_ie == NULL)
233 goto error_alloc;
234 host_disconnect_ie->hdr.bLength = sizeof(*host_disconnect_ie);
235 host_disconnect_ie->hdr.bIEIdentifier = WUIE_ID_HOST_DISCONNECT;
236 result = wusbhc_mmcie_set(wusbhc, 0, 0, &host_disconnect_ie->hdr);
237 if (result < 0)
238 goto error_mmcie_set;
239
240 /* WUSB1.0[8.5.3.1 & 7.5.2] */
241 msleep(100);
242 wusbhc_mmcie_rm(wusbhc, &host_disconnect_ie->hdr);
243error_mmcie_set:
244 kfree(host_disconnect_ie);
245error_alloc:
246 return result;
247}
248
249/*
250 * wusbhc_stop - stop transmitting MMCs 221 * wusbhc_stop - stop transmitting MMCs
251 * @wusbhc: the HC to stop 222 * @wusbhc: the HC to stop
252 * 223 *
@@ -265,29 +236,6 @@ void wusbhc_stop(struct wusbhc *wusbhc)
265EXPORT_SYMBOL_GPL(wusbhc_stop); 236EXPORT_SYMBOL_GPL(wusbhc_stop);
266 237
267/* 238/*
268 * Change the CHID in a WUSB Channel
269 *
270 * If it is just a new CHID, send a Host Disconnect IE and then change
271 * the CHID IE.
272 */
273static int __wusbhc_chid_change(struct wusbhc *wusbhc,
274 const struct wusb_ckhdid *chid)
275{
276 int result = -ENOSYS;
277 struct device *dev = wusbhc->dev;
278 dev_err(dev, "%s() not implemented yet\n", __func__);
279 return result;
280
281 BUG_ON(wusbhc->wuie_host_info == NULL);
282 __wusbhc_host_disconnect_ie(wusbhc);
283 wusbhc->wuie_host_info->CHID = *chid;
284 result = wusbhc_mmcie_set(wusbhc, 0, 0, &wusbhc->wuie_host_info->hdr);
285 if (result < 0)
286 dev_err(dev, "Can't update Host Info WUSB IE: %d\n", result);
287 return result;
288}
289
290/*
291 * Set/reset/update a new CHID 239 * Set/reset/update a new CHID
292 * 240 *
293 * Depending on the previous state of the MMCs, start, stop or change 241 * Depending on the previous state of the MMCs, start, stop or change
@@ -302,16 +250,19 @@ int wusbhc_chid_set(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid)
302 chid = NULL; 250 chid = NULL;
303 251
304 mutex_lock(&wusbhc->mutex); 252 mutex_lock(&wusbhc->mutex);
305 if (wusbhc->active) { 253 if (chid) {
306 if (chid) 254 if (wusbhc->active) {
307 result = __wusbhc_chid_change(wusbhc, chid); 255 mutex_unlock(&wusbhc->mutex);
308 else 256 return -EBUSY;
309 wusbhc_stop(wusbhc); 257 }
310 } else { 258 wusbhc->chid = *chid;
311 if (chid)
312 wusbhc_start(wusbhc, chid);
313 } 259 }
314 mutex_unlock(&wusbhc->mutex); 260 mutex_unlock(&wusbhc->mutex);
261
262 if (chid)
263 result = uwb_radio_start(&wusbhc->pal);
264 else
265 uwb_radio_stop(&wusbhc->pal);
315 return result; 266 return result;
316} 267}
317EXPORT_SYMBOL_GPL(wusbhc_chid_set); 268EXPORT_SYMBOL_GPL(wusbhc_chid_set);
diff --git a/drivers/usb/wusbcore/pal.c b/drivers/usb/wusbcore/pal.c
index 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/wusbhc.h b/drivers/usb/wusbcore/wusbhc.h
index 8fef934ad2f3..797c2453a35b 100644
--- a/drivers/usb/wusbcore/wusbhc.h
+++ b/drivers/usb/wusbcore/wusbhc.h
@@ -252,7 +252,8 @@ struct wusbhc {
252 struct uwb_pal pal; 252 struct uwb_pal pal;
253 253
254 unsigned trust_timeout; /* in jiffies */ 254 unsigned trust_timeout; /* in jiffies */
255 struct wuie_host_info *wuie_host_info; /* Includes CHID */ 255 struct wusb_ckhdid chid;
256 struct wuie_host_info *wuie_host_info;
256 257
257 struct mutex mutex; /* locks everything else */ 258 struct mutex mutex; /* locks everything else */
258 u16 cluster_id; /* Wireless USB Cluster ID */ 259 u16 cluster_id; /* Wireless USB Cluster ID */
@@ -376,15 +377,14 @@ static inline void wusbhc_put(struct wusbhc *wusbhc)
376 usb_put_hcd(&wusbhc->usb_hcd); 377 usb_put_hcd(&wusbhc->usb_hcd);
377} 378}
378 379
379int wusbhc_start(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid); 380int wusbhc_start(struct wusbhc *wusbhc);
380void wusbhc_stop(struct wusbhc *wusbhc); 381void wusbhc_stop(struct wusbhc *wusbhc);
381extern int wusbhc_chid_set(struct wusbhc *, const struct wusb_ckhdid *); 382extern int wusbhc_chid_set(struct wusbhc *, const struct wusb_ckhdid *);
382 383
383/* Device connect handling */ 384/* Device connect handling */
384extern int wusbhc_devconnect_create(struct wusbhc *); 385extern int wusbhc_devconnect_create(struct wusbhc *);
385extern void wusbhc_devconnect_destroy(struct wusbhc *); 386extern void wusbhc_devconnect_destroy(struct wusbhc *);
386extern int wusbhc_devconnect_start(struct wusbhc *wusbhc, 387extern int wusbhc_devconnect_start(struct wusbhc *wusbhc);
387 const struct wusb_ckhdid *chid);
388extern void wusbhc_devconnect_stop(struct wusbhc *wusbhc); 388extern void wusbhc_devconnect_stop(struct wusbhc *wusbhc);
389extern void wusbhc_handle_dn(struct wusbhc *, u8 srcaddr, 389extern void wusbhc_handle_dn(struct wusbhc *, u8 srcaddr,
390 struct wusb_dn_hdr *dn_hdr, size_t size); 390 struct wusb_dn_hdr *dn_hdr, size_t size);