From f88518d122f1b007f47a46aff37ca2885126a923 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Fri, 31 Oct 2008 22:49:58 +0800 Subject: wusb: remove unused #include The file(s) below do not use LINUX_VERSION_CODE nor KERNEL_VERSION. drivers/usb/host/hwa-hc.c drivers/usb/host/whci/hcd.c drivers/usb/host/whci/int.c drivers/usb/host/whci/wusb.c drivers/usb/wusbcore/cbaf.c This patch removes the said #include . Signed-off-by: Huang Weiyi Signed-off-by: David Vrabel --- drivers/usb/host/whci/hcd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/usb/host/whci/hcd.c') diff --git a/drivers/usb/host/whci/hcd.c b/drivers/usb/host/whci/hcd.c index ef3ad4dca94..de1e07271b8 100644 --- a/drivers/usb/host/whci/hcd.c +++ b/drivers/usb/host/whci/hcd.c @@ -15,7 +15,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -#include #include #include #include -- cgit v1.2.3-70-g09d2 From 6fae35f9cea92793a98b2d9ab21235e5ae035581 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Mon, 17 Nov 2008 15:53:42 +0000 Subject: 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 --- Documentation/ABI/testing/sysfs-class-uwb_rc | 14 +- Documentation/usb/wusb-cbaf | 9 -- drivers/usb/host/hwa-hc.c | 1 - drivers/usb/host/whci/hcd.c | 2 - drivers/usb/wusbcore/devconnect.c | 5 +- drivers/usb/wusbcore/mmc.c | 75 ++-------- drivers/usb/wusbcore/pal.c | 16 ++- drivers/usb/wusbcore/wusbhc.h | 8 +- drivers/uwb/Makefile | 1 + drivers/uwb/beacon.c | 26 ++-- drivers/uwb/drp.c | 24 +--- drivers/uwb/lc-rc.c | 11 +- drivers/uwb/pal.c | 20 +-- drivers/uwb/radio.c | 202 +++++++++++++++++++++++++++ drivers/uwb/reset.c | 6 +- drivers/uwb/rsv.c | 4 +- drivers/uwb/uwb-debug.c | 26 +++- drivers/uwb/uwb-internal.h | 5 + drivers/uwb/wlp/wlp-lc.c | 5 +- include/linux/uwb.h | 23 ++- include/linux/uwb/debug-cmd.h | 2 + 21 files changed, 323 insertions(+), 162 deletions(-) create mode 100644 drivers/uwb/radio.c (limited to 'drivers/usb/host/whci/hcd.c') diff --git a/Documentation/ABI/testing/sysfs-class-uwb_rc b/Documentation/ABI/testing/sysfs-class-uwb_rc index a0d18dbeb7a..6a5fd072849 100644 --- a/Documentation/ABI/testing/sysfs-class-uwb_rc +++ b/Documentation/ABI/testing/sysfs-class-uwb_rc @@ -32,14 +32,16 @@ Contact: linux-usb@vger.kernel.org Description: Write: - [] + - to start beaconing on a specific channel, or stop - beaconing if is -1. Valid channels depends - on the radio controller's supported band groups. + to force a specific channel to be used when beaconing, + or, if is -1, to prohibit beaconing. If + is 0, then the default channel selection + algorithm will be used. Valid channels depends on the + radio controller's supported band groups. - may be used to try and join a specific - beacon group if more than one was found during a scan. + Reading returns the currently active channel, or -1 if + the radio controller is not beaconing. What: /sys/class/uwb_rc/uwbN/scan Date: July 2008 diff --git a/Documentation/usb/wusb-cbaf b/Documentation/usb/wusb-cbaf index 2e78b70f3ad..426ddaaef96 100644 --- a/Documentation/usb/wusb-cbaf +++ b/Documentation/usb/wusb-cbaf @@ -80,12 +80,6 @@ case $1 in start) for dev in ${2:-$hdevs} do - uwb_rc=$(readlink -f $dev/uwb_rc) - if cat $uwb_rc/beacon | grep -q -- "-1" - then - echo 13 0 > $uwb_rc/beacon - echo I: started beaconing on ch 13 on $(basename $uwb_rc) >&2 - fi echo $host_CHID > $dev/wusb_chid echo I: started host $(basename $dev) >&2 done @@ -95,9 +89,6 @@ case $1 in do echo 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > $dev/wusb_chid echo I: stopped host $(basename $dev) >&2 - uwb_rc=$(readlink -f $dev/uwb_rc) - echo -1 | cat > $uwb_rc/beacon - echo I: stopped beaconing on $(basename $uwb_rc) >&2 done ;; set-chid) diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c index 2827353e97e..2a4d36fa70b 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) d_fnstart(4, dev, "(hwahc %p)\n", hwahc); mutex_lock(&wusbhc->mutex); - wusbhc_stop(wusbhc); wusb_cluster_id_put(wusbhc->cluster_id); mutex_unlock(&wusbhc->mutex); 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 de1e07271b8..f599f89d3be 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) mutex_lock(&wusbhc->mutex); - wusbhc_stop(wusbhc); - /* stop HC */ le_writel(0, whc->base + WUSBINTR); whc_write_wusbcmd(whc, WUSBCMD_RUN, 0); diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c index c01c7a80744..08a1ec90386 100644 --- a/drivers/usb/wusbcore/devconnect.c +++ b/drivers/usb/wusbcore/devconnect.c @@ -1124,8 +1124,7 @@ void wusbhc_devconnect_destroy(struct wusbhc *wusbhc) * FIXME: This also enables the keep alives but this is not necessary * until there are connected and authenticated devices. */ -int wusbhc_devconnect_start(struct wusbhc *wusbhc, - const struct wusb_ckhdid *chid) +int wusbhc_devconnect_start(struct wusbhc *wusbhc) { struct device *dev = wusbhc->dev; struct wuie_host_info *hi; @@ -1138,7 +1137,7 @@ int wusbhc_devconnect_start(struct wusbhc *wusbhc, hi->hdr.bLength = sizeof(*hi); hi->hdr.bIEIdentifier = WUIE_ID_HOST_INFO; hi->attributes = cpu_to_le16((wusbhc->rsv->stream << 3) | WUIE_HI_CAP_ALL); - hi->CHID = *chid; + hi->CHID = wusbhc->chid; result = wusbhc_mmcie_set(wusbhc, 0, 0, &hi->hdr); if (result < 0) { 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 af2aee0fdff..5463ecebafd 100644 --- a/drivers/usb/wusbcore/mmc.c +++ b/drivers/usb/wusbcore/mmc.c @@ -162,12 +162,11 @@ EXPORT_SYMBOL_GPL(wusbhc_mmcie_rm); /* * wusbhc_start - start transmitting MMCs and accepting connections * @wusbhc: the HC to start - * @chid: the CHID to use for this host * * Establishes a cluster reservation, enables device connections, and * starts MMCs with appropriate DNTS parameters. */ -int wusbhc_start(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid) +int wusbhc_start(struct wusbhc *wusbhc) { int result; struct device *dev = wusbhc->dev; @@ -181,7 +180,7 @@ int wusbhc_start(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid) goto error_rsv_establish; } - result = wusbhc_devconnect_start(wusbhc, chid); + result = wusbhc_devconnect_start(wusbhc); if (result < 0) { dev_err(dev, "error enabling device connections: %d\n", result); goto error_devconnect_start; @@ -218,34 +217,6 @@ error_rsv_establish: return result; } -/* - * Disconnect all from the WUSB Channel - * - * Send a Host Disconnect IE in the MMC, wait, don't send it any more - */ -static int __wusbhc_host_disconnect_ie(struct wusbhc *wusbhc) -{ - int result = -ENOMEM; - struct wuie_host_disconnect *host_disconnect_ie; - might_sleep(); - host_disconnect_ie = kmalloc(sizeof(*host_disconnect_ie), GFP_KERNEL); - if (host_disconnect_ie == NULL) - goto error_alloc; - host_disconnect_ie->hdr.bLength = sizeof(*host_disconnect_ie); - host_disconnect_ie->hdr.bIEIdentifier = WUIE_ID_HOST_DISCONNECT; - result = wusbhc_mmcie_set(wusbhc, 0, 0, &host_disconnect_ie->hdr); - if (result < 0) - goto error_mmcie_set; - - /* WUSB1.0[8.5.3.1 & 7.5.2] */ - msleep(100); - wusbhc_mmcie_rm(wusbhc, &host_disconnect_ie->hdr); -error_mmcie_set: - kfree(host_disconnect_ie); -error_alloc: - return result; -} - /* * wusbhc_stop - stop transmitting MMCs * @wusbhc: the HC to stop @@ -264,29 +235,6 @@ void wusbhc_stop(struct wusbhc *wusbhc) } EXPORT_SYMBOL_GPL(wusbhc_stop); -/* - * Change the CHID in a WUSB Channel - * - * If it is just a new CHID, send a Host Disconnect IE and then change - * the CHID IE. - */ -static int __wusbhc_chid_change(struct wusbhc *wusbhc, - const struct wusb_ckhdid *chid) -{ - int result = -ENOSYS; - struct device *dev = wusbhc->dev; - dev_err(dev, "%s() not implemented yet\n", __func__); - return result; - - BUG_ON(wusbhc->wuie_host_info == NULL); - __wusbhc_host_disconnect_ie(wusbhc); - wusbhc->wuie_host_info->CHID = *chid; - result = wusbhc_mmcie_set(wusbhc, 0, 0, &wusbhc->wuie_host_info->hdr); - if (result < 0) - dev_err(dev, "Can't update Host Info WUSB IE: %d\n", result); - return result; -} - /* * Set/reset/update a new CHID * @@ -302,16 +250,19 @@ int wusbhc_chid_set(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid) chid = NULL; mutex_lock(&wusbhc->mutex); - if (wusbhc->active) { - if (chid) - result = __wusbhc_chid_change(wusbhc, chid); - else - wusbhc_stop(wusbhc); - } else { - if (chid) - wusbhc_start(wusbhc, chid); + if (chid) { + if (wusbhc->active) { + mutex_unlock(&wusbhc->mutex); + return -EBUSY; + } + wusbhc->chid = *chid; } mutex_unlock(&wusbhc->mutex); + + if (chid) + result = uwb_radio_start(&wusbhc->pal); + else + uwb_radio_stop(&wusbhc->pal); return result; } EXPORT_SYMBOL_GPL(wusbhc_chid_set); diff --git a/drivers/usb/wusbcore/pal.c b/drivers/usb/wusbcore/pal.c index 7cc51e9905c..d0b172c5ecc 100644 --- a/drivers/usb/wusbcore/pal.c +++ b/drivers/usb/wusbcore/pal.c @@ -18,6 +18,16 @@ */ #include "wusbhc.h" +static void wusbhc_channel_changed(struct uwb_pal *pal, int channel) +{ + struct wusbhc *wusbhc = container_of(pal, struct wusbhc, pal); + + if (channel < 0) + wusbhc_stop(wusbhc); + else + wusbhc_start(wusbhc); +} + /** * wusbhc_pal_register - register the WUSB HC as a UWB PAL * @wusbhc: the WUSB HC @@ -28,8 +38,10 @@ int wusbhc_pal_register(struct wusbhc *wusbhc) wusbhc->pal.name = "wusbhc"; wusbhc->pal.device = wusbhc->usb_hcd.self.controller; + wusbhc->pal.rc = wusbhc->uwb_rc; + wusbhc->pal.channel_changed = wusbhc_channel_changed; - return uwb_pal_register(wusbhc->uwb_rc, &wusbhc->pal); + return uwb_pal_register(&wusbhc->pal); } /** @@ -38,5 +50,5 @@ int wusbhc_pal_register(struct wusbhc *wusbhc) */ void wusbhc_pal_unregister(struct wusbhc *wusbhc) { - uwb_pal_unregister(wusbhc->uwb_rc, &wusbhc->pal); + uwb_pal_unregister(&wusbhc->pal); } diff --git a/drivers/usb/wusbcore/wusbhc.h b/drivers/usb/wusbcore/wusbhc.h index 8fef934ad2f..797c2453a35 100644 --- a/drivers/usb/wusbcore/wusbhc.h +++ b/drivers/usb/wusbcore/wusbhc.h @@ -252,7 +252,8 @@ struct wusbhc { struct uwb_pal pal; unsigned trust_timeout; /* in jiffies */ - struct wuie_host_info *wuie_host_info; /* Includes CHID */ + struct wusb_ckhdid chid; + struct wuie_host_info *wuie_host_info; struct mutex mutex; /* locks everything else */ u16 cluster_id; /* Wireless USB Cluster ID */ @@ -376,15 +377,14 @@ static inline void wusbhc_put(struct wusbhc *wusbhc) usb_put_hcd(&wusbhc->usb_hcd); } -int wusbhc_start(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid); +int wusbhc_start(struct wusbhc *wusbhc); void wusbhc_stop(struct wusbhc *wusbhc); extern int wusbhc_chid_set(struct wusbhc *, const struct wusb_ckhdid *); /* Device connect handling */ extern int wusbhc_devconnect_create(struct wusbhc *); extern void wusbhc_devconnect_destroy(struct wusbhc *); -extern int wusbhc_devconnect_start(struct wusbhc *wusbhc, - const struct wusb_ckhdid *chid); +extern int wusbhc_devconnect_start(struct wusbhc *wusbhc); extern void wusbhc_devconnect_stop(struct wusbhc *wusbhc); extern void wusbhc_handle_dn(struct wusbhc *, u8 srcaddr, struct wusb_dn_hdr *dn_hdr, size_t size); diff --git a/drivers/uwb/Makefile b/drivers/uwb/Makefile index 2b99c3e6167..ce21a95da04 100644 --- a/drivers/uwb/Makefile +++ b/drivers/uwb/Makefile @@ -18,6 +18,7 @@ uwb-objs := \ lc-rc.o \ neh.o \ pal.o \ + radio.o \ reset.o \ rsv.o \ scan.o \ diff --git a/drivers/uwb/beacon.c b/drivers/uwb/beacon.c index d9f2a8acc59..247956098af 100644 --- a/drivers/uwb/beacon.c +++ b/drivers/uwb/beacon.c @@ -119,7 +119,6 @@ int uwb_rc_beacon(struct uwb_rc *rc, int channel, unsigned bpst_offset) int result; struct device *dev = &rc->uwb_dev.dev; - mutex_lock(&rc->uwb_dev.mutex); if (channel < 0) channel = -1; if (channel == -1) @@ -128,7 +127,7 @@ int uwb_rc_beacon(struct uwb_rc *rc, int channel, unsigned bpst_offset) /* channel >= 0...dah */ result = uwb_rc_start_beacon(rc, bpst_offset, channel); if (result < 0) - goto out_up; + return result; if (le16_to_cpu(rc->ies->wIELength) > 0) { result = uwb_rc_set_ie(rc, rc->ies); if (result < 0) { @@ -137,19 +136,14 @@ int uwb_rc_beacon(struct uwb_rc *rc, int channel, unsigned bpst_offset) result = uwb_rc_stop_beacon(rc); channel = -1; bpst_offset = 0; - } else - result = 0; + } } } - if (result < 0) - goto out_up; - rc->beaconing = channel; - - uwb_notify(rc, NULL, uwb_bg_joined(rc) ? UWB_NOTIF_BG_JOIN : UWB_NOTIF_BG_LEAVE); - -out_up: - mutex_unlock(&rc->uwb_dev.mutex); + if (result >= 0) { + rc->beaconing = channel; + uwb_notify(rc, NULL, uwb_bg_joined(rc) ? UWB_NOTIF_BG_JOIN : UWB_NOTIF_BG_LEAVE); + } return result; } @@ -618,9 +612,6 @@ static ssize_t uwb_rc_beacon_show(struct device *dev, /* * Start beaconing on the specified channel, or stop beaconing. - * - * The BPST offset of when to start searching for a beacon group to - * join may be specified. */ static ssize_t uwb_rc_beacon_store(struct device *dev, struct device_attribute *attr, @@ -629,12 +620,11 @@ static ssize_t uwb_rc_beacon_store(struct device *dev, struct uwb_dev *uwb_dev = to_uwb_dev(dev); struct uwb_rc *rc = uwb_dev->rc; int channel; - unsigned bpst_offset = 0; ssize_t result = -EINVAL; - result = sscanf(buf, "%d %u\n", &channel, &bpst_offset); + result = sscanf(buf, "%d", &channel); if (result >= 1) - result = uwb_rc_beacon(rc, channel, bpst_offset); + result = uwb_radio_force_channel(rc, channel); return result < 0 ? result : size; } diff --git a/drivers/uwb/drp.c b/drivers/uwb/drp.c index c0b1e5e2bd0..fe328146adb 100644 --- a/drivers/uwb/drp.c +++ b/drivers/uwb/drp.c @@ -37,14 +37,13 @@ * * A DRP Availability IE is appended. * - * rc->uwb_dev.mutex is held + * rc->rsvs_mutex is held * * FIXME We currently ignore the returned value indicating the remaining space * in beacon. This could be used to deny reservation requests earlier if * determined that they would cause the beacon space to be exceeded. */ -static -int uwb_rc_gen_send_drp_ie(struct uwb_rc *rc) +int uwb_rc_send_all_drp_ie(struct uwb_rc *rc) { int result; struct device *dev = &rc->uwb_dev.dev; @@ -102,25 +101,6 @@ error_cmd: kfree(cmd); error: return result; - -} -/** - * Send all DRP IEs associated with this host - * - * @returns: >= 0 number of bytes still available in the beacon - * < 0 errno code on error. - * - * As per the protocol we obtain the host controller device lock to access - * bandwidth structures. - */ -int uwb_rc_send_all_drp_ie(struct uwb_rc *rc) -{ - int result; - - mutex_lock(&rc->uwb_dev.mutex); - result = uwb_rc_gen_send_drp_ie(rc); - mutex_unlock(&rc->uwb_dev.mutex); - return result; } void uwb_drp_handle_timeout(struct uwb_rsv *rsv) diff --git a/drivers/uwb/lc-rc.c b/drivers/uwb/lc-rc.c index f00633d334d..9cf21e6bb62 100644 --- a/drivers/uwb/lc-rc.c +++ b/drivers/uwb/lc-rc.c @@ -189,9 +189,9 @@ static int uwb_rc_setup(struct uwb_rc *rc) int result; struct device *dev = &rc->uwb_dev.dev; - result = uwb_rc_reset(rc); + result = uwb_radio_setup(rc); if (result < 0) { - dev_err(dev, "cannot reset UWB radio: %d\n", result); + dev_err(dev, "cannot setup UWB radio: %d\n", result); goto error; } result = uwb_rc_mac_addr_setup(rc); @@ -311,12 +311,7 @@ void uwb_rc_rm(struct uwb_rc *rc) uwb_dbg_del_rc(rc); uwb_rsv_remove_all(rc); - uwb_rc_ie_rm(rc, UWB_IDENTIFICATION_IE); - if (rc->beaconing >= 0) - uwb_rc_beacon(rc, -1, 0); - if (rc->scan_type != UWB_SCAN_DISABLED) - uwb_rc_scan(rc, rc->scanning, UWB_SCAN_DISABLED, 0); - uwb_rc_reset(rc); + uwb_radio_shutdown(rc); rc->stop(rc); diff --git a/drivers/uwb/pal.c b/drivers/uwb/pal.c index 1afb38eacb9..605765124f5 100644 --- a/drivers/uwb/pal.c +++ b/drivers/uwb/pal.c @@ -32,13 +32,13 @@ EXPORT_SYMBOL_GPL(uwb_pal_init); /** * uwb_pal_register - register a UWB PAL - * @rc: the radio controller the PAL will be using * @pal: the PAL * * The PAL must be initialized with uwb_pal_init(). */ -int uwb_pal_register(struct uwb_rc *rc, struct uwb_pal *pal) +int uwb_pal_register(struct uwb_pal *pal) { + struct uwb_rc *rc = pal->rc; int ret; if (pal->device) { @@ -54,9 +54,9 @@ int uwb_pal_register(struct uwb_rc *rc, struct uwb_pal *pal) } } - spin_lock(&rc->pal_lock); + mutex_lock(&rc->uwb_dev.mutex); list_add(&pal->node, &rc->pals); - spin_unlock(&rc->pal_lock); + mutex_unlock(&rc->uwb_dev.mutex); return 0; } @@ -64,14 +64,17 @@ EXPORT_SYMBOL_GPL(uwb_pal_register); /** * uwb_pal_register - unregister a UWB PAL - * @rc: the radio controller the PAL was using * @pal: the PAL */ -void uwb_pal_unregister(struct uwb_rc *rc, struct uwb_pal *pal) +void uwb_pal_unregister(struct uwb_pal *pal) { - spin_lock(&rc->pal_lock); + struct uwb_rc *rc = pal->rc; + + uwb_radio_stop(pal); + + mutex_lock(&rc->uwb_dev.mutex); list_del(&pal->node); - spin_unlock(&rc->pal_lock); + mutex_unlock(&rc->uwb_dev.mutex); if (pal->device) { sysfs_remove_link(&rc->uwb_dev.dev.kobj, pal->name); @@ -86,6 +89,5 @@ EXPORT_SYMBOL_GPL(uwb_pal_unregister); */ void uwb_rc_pal_init(struct uwb_rc *rc) { - spin_lock_init(&rc->pal_lock); INIT_LIST_HEAD(&rc->pals); } diff --git a/drivers/uwb/radio.c b/drivers/uwb/radio.c new file mode 100644 index 00000000000..f0d55495f5e --- /dev/null +++ b/drivers/uwb/radio.c @@ -0,0 +1,202 @@ +/* + * UWB radio (channel) management. + * + * Copyright (C) 2008 Cambridge Silicon Radio Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include + +#include "uwb-internal.h" + + +static int uwb_radio_select_channel(struct uwb_rc *rc) +{ + /* + * Default to channel 9 (BG1, TFC1) unless the user has + * selected a specific channel or there are no active PALs. + */ + if (rc->active_pals == 0) + return -1; + if (rc->beaconing_forced) + return rc->beaconing_forced; + return 9; +} + + +/* + * Notify all active PALs that the channel has changed. + */ +static void uwb_radio_channel_changed(struct uwb_rc *rc, int channel) +{ + struct uwb_pal *pal; + + list_for_each_entry(pal, &rc->pals, node) { + if (pal->channel && channel != pal->channel) { + pal->channel = channel; + if (pal->channel_changed) + pal->channel_changed(pal, pal->channel); + } + } +} + +/* + * Change to a new channel and notify any active PALs of the new + * channel. + * + * When stopping the radio, PALs need to be notified first so they can + * terminate any active reservations. + */ +static int uwb_radio_change_channel(struct uwb_rc *rc, int channel) +{ + int ret = 0; + + if (channel == -1) + uwb_radio_channel_changed(rc, channel); + + if (channel != rc->beaconing) { + if (rc->beaconing != -1 && channel != -1) { + /* + * FIXME: should signal the channel change + * with a Channel Change IE. + */ + ret = uwb_radio_change_channel(rc, -1); + if (ret < 0) + return ret; + } + ret = uwb_rc_beacon(rc, channel, 0); + } + + if (channel != -1) + uwb_radio_channel_changed(rc, rc->beaconing); + + return ret; +} + +/** + * uwb_radio_start - request that the radio be started + * @pal: the PAL making the request. + * + * If the radio is not already active, aa suitable channel is selected + * and beacons are started. + */ +int uwb_radio_start(struct uwb_pal *pal) +{ + struct uwb_rc *rc = pal->rc; + int ret = 0; + + mutex_lock(&rc->uwb_dev.mutex); + + if (!pal->channel) { + pal->channel = -1; + rc->active_pals++; + ret = uwb_radio_change_channel(rc, uwb_radio_select_channel(rc)); + } + + mutex_unlock(&rc->uwb_dev.mutex); + return ret; +} +EXPORT_SYMBOL_GPL(uwb_radio_start); + +/** + * uwb_radio_stop - request tha the radio be stopped. + * @pal: the PAL making the request. + * + * Stops the radio if no other PAL is making use of it. + */ +void uwb_radio_stop(struct uwb_pal *pal) +{ + struct uwb_rc *rc = pal->rc; + + mutex_lock(&rc->uwb_dev.mutex); + + if (pal->channel) { + rc->active_pals--; + uwb_radio_change_channel(rc, uwb_radio_select_channel(rc)); + pal->channel = 0; + } + + mutex_unlock(&rc->uwb_dev.mutex); +} +EXPORT_SYMBOL_GPL(uwb_radio_stop); + +/* + * uwb_radio_force_channel - force a specific channel to be used + * @rc: the radio controller. + * @channel: the channel to use; -1 to force the radio to stop; 0 to + * use the default channel selection algorithm. + */ +int uwb_radio_force_channel(struct uwb_rc *rc, int channel) +{ + int ret = 0; + + mutex_lock(&rc->uwb_dev.mutex); + + rc->beaconing_forced = channel; + ret = uwb_radio_change_channel(rc, uwb_radio_select_channel(rc)); + + mutex_unlock(&rc->uwb_dev.mutex); + return ret; +} + +/* + * uwb_radio_setup - setup the radio manager + * @rc: the radio controller. + * + * The radio controller is reset to ensure it's in a known state + * before it's used. + */ +int uwb_radio_setup(struct uwb_rc *rc) +{ + return uwb_rc_reset(rc); +} + +/* + * uwb_radio_reset_state - reset any radio manager state + * @rc: the radio controller. + * + * All internal radio manager state is reset to values corresponding + * to a reset radio controller. + */ +void uwb_radio_reset_state(struct uwb_rc *rc) +{ + struct uwb_pal *pal; + + mutex_lock(&rc->uwb_dev.mutex); + + list_for_each_entry(pal, &rc->pals, node) { + if (pal->channel) { + pal->channel = -1; + if (pal->channel_changed) + pal->channel_changed(pal, -1); + } + } + + rc->beaconing = -1; + rc->scanning = -1; + + mutex_unlock(&rc->uwb_dev.mutex); +} + +/* + * uwb_radio_shutdown - shutdown the radio manager + * @rc: the radio controller. + * + * The radio controller is reset. + */ +void uwb_radio_shutdown(struct uwb_rc *rc) +{ + uwb_radio_reset_state(rc); + uwb_rc_reset(rc); +} diff --git a/drivers/uwb/reset.c b/drivers/uwb/reset.c index e39b32099af..ce8283cc809 100644 --- a/drivers/uwb/reset.c +++ b/drivers/uwb/reset.c @@ -365,11 +365,7 @@ void uwb_rc_pre_reset(struct uwb_rc *rc) rc->stop(rc); uwbd_flush(rc); - mutex_lock(&rc->uwb_dev.mutex); - rc->beaconing = -1; - rc->scanning = -1; - mutex_unlock(&rc->uwb_dev.mutex); - + uwb_radio_reset_state(rc); uwb_rsv_remove_all(rc); } EXPORT_SYMBOL_GPL(uwb_rc_pre_reset); diff --git a/drivers/uwb/rsv.c b/drivers/uwb/rsv.c index 935d5b536db..1cd84f92754 100644 --- a/drivers/uwb/rsv.c +++ b/drivers/uwb/rsv.c @@ -555,14 +555,14 @@ static struct uwb_rsv *uwb_rsv_new_target(struct uwb_rc *rc, * deny the request. */ rsv->state = UWB_RSV_STATE_T_DENIED; - spin_lock(&rc->pal_lock); + mutex_lock(&rc->uwb_dev.mutex); list_for_each_entry(pal, &rc->pals, node) { if (pal->new_rsv) pal->new_rsv(pal, rsv); if (rsv->state == UWB_RSV_STATE_T_ACCEPTED) break; } - spin_unlock(&rc->pal_lock); + mutex_unlock(&rc->uwb_dev.mutex); list_add_tail(&rsv->rc_node, &rc->reservations); state = rsv->state; diff --git a/drivers/uwb/uwb-debug.c b/drivers/uwb/uwb-debug.c index 217ebaac128..0e58071a232 100644 --- a/drivers/uwb/uwb-debug.c +++ b/drivers/uwb/uwb-debug.c @@ -192,7 +192,7 @@ static ssize_t command_write(struct file *file, const char __user *buf, { struct uwb_rc *rc = file->private_data; struct uwb_dbg_cmd cmd; - int ret; + int ret = 0; if (len != sizeof(struct uwb_dbg_cmd)) return -EINVAL; @@ -213,6 +213,12 @@ static ssize_t command_write(struct file *file, const char __user *buf, case UWB_DBG_CMD_IE_RM: ret = cmd_ie_rm(rc, &cmd.ie_rm); break; + case UWB_DBG_CMD_RADIO_START: + ret = uwb_radio_start(&rc->dbg->pal); + break; + case UWB_DBG_CMD_RADIO_STOP: + uwb_radio_stop(&rc->dbg->pal); + break; default: return -EINVAL; } @@ -306,6 +312,17 @@ static struct file_operations drp_avail_fops = { .owner = THIS_MODULE, }; +static void uwb_dbg_channel_changed(struct uwb_pal *pal, int channel) +{ + struct uwb_dbg *dbg = container_of(pal, struct uwb_dbg, pal); + struct device *dev = &pal->rc->uwb_dev.dev; + + if (channel > 0) + dev_info(dev, "debug: channel %d started\n", channel); + else + dev_info(dev, "debug: channel stopped\n"); +} + static void uwb_dbg_new_rsv(struct uwb_pal *pal, struct uwb_rsv *rsv) { struct uwb_dbg *dbg = container_of(pal, struct uwb_dbg, pal); @@ -329,8 +346,11 @@ void uwb_dbg_add_rc(struct uwb_rc *rc) INIT_LIST_HEAD(&rc->dbg->rsvs); uwb_pal_init(&rc->dbg->pal); + rc->dbg->pal.rc = rc; + rc->dbg->pal.channel_changed = uwb_dbg_channel_changed; rc->dbg->pal.new_rsv = uwb_dbg_new_rsv; - uwb_pal_register(rc, &rc->dbg->pal); + uwb_pal_register(&rc->dbg->pal); + if (root_dir) { rc->dbg->root_d = debugfs_create_dir(dev_name(&rc->uwb_dev.dev), root_dir); @@ -364,7 +384,7 @@ void uwb_dbg_del_rc(struct uwb_rc *rc) uwb_rsv_terminate(rsv); } - uwb_pal_unregister(rc, &rc->dbg->pal); + uwb_pal_unregister(&rc->dbg->pal); if (root_dir) { debugfs_remove(rc->dbg->drp_avail_f); diff --git a/drivers/uwb/uwb-internal.h b/drivers/uwb/uwb-internal.h index af95541dabc..9c0cdb4ded0 100644 --- a/drivers/uwb/uwb-internal.h +++ b/drivers/uwb/uwb-internal.h @@ -238,6 +238,11 @@ struct uwb_dev *uwb_dev_get_by_devaddr(struct uwb_rc *rc, struct uwb_dev *uwb_dev_get_by_macaddr(struct uwb_rc *rc, const struct uwb_mac_addr *macaddr); +int uwb_radio_setup(struct uwb_rc *rc); +void uwb_radio_reset_state(struct uwb_rc *rc); +void uwb_radio_shutdown(struct uwb_rc *rc); +int uwb_radio_force_channel(struct uwb_rc *rc, int channel); + /* -- UWB Sysfs representation */ extern struct class uwb_rc_class; extern struct device_attribute dev_attr_mac_address; diff --git a/drivers/uwb/wlp/wlp-lc.c b/drivers/uwb/wlp/wlp-lc.c index 0799402e73f..7e5eb49b03b 100644 --- a/drivers/uwb/wlp/wlp-lc.c +++ b/drivers/uwb/wlp/wlp-lc.c @@ -543,7 +543,8 @@ int wlp_setup(struct wlp *wlp, struct uwb_rc *rc) uwb_notifs_register(rc, &wlp->uwb_notifs_handler); uwb_pal_init(&wlp->pal); - result = uwb_pal_register(rc, &wlp->pal); + wlp->pal.rc = rc; + result = uwb_pal_register(&wlp->pal); if (result < 0) uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler); @@ -557,7 +558,7 @@ void wlp_remove(struct wlp *wlp) struct device *dev = &wlp->rc->uwb_dev.dev; d_fnstart(6, dev, "wlp %p\n", wlp); wlp_neighbors_release(wlp); - uwb_pal_unregister(wlp->rc, &wlp->pal); + uwb_pal_unregister(&wlp->pal); uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler); wlp_eda_release(&wlp->eda); mutex_lock(&wlp->mutex); diff --git a/include/linux/uwb.h b/include/linux/uwb.h index effd97998fd..7d3ebf046f9 100644 --- a/include/linux/uwb.h +++ b/include/linux/uwb.h @@ -355,6 +355,7 @@ struct uwb_rc { u8 ctx_roll; int beaconing; /* Beaconing state [channel number] */ + int beaconing_forced; int scanning; enum uwb_scan_type scan_type:3; unsigned ready:1; @@ -373,8 +374,8 @@ struct uwb_rc { struct uwb_rc_cmd_set_ie *ies; size_t ies_capacity; - spinlock_t pal_lock; struct list_head pals; + int active_pals; struct uwb_dbg *dbg; }; @@ -382,11 +383,17 @@ struct uwb_rc { /** * struct uwb_pal - a UWB PAL - * @name: descriptive name for this PAL (wushc, wlp, etc.). + * @name: descriptive name for this PAL (wusbhc, wlp, etc.). * @device: a device for the PAL. Used to link the PAL and the radio * controller in sysfs. + * @rc: the radio controller the PAL uses. + * @channel_changed: called when the channel used by the radio changes. + * A channel of -1 means the channel has been stopped. * @new_rsv: called when a peer requests a reservation (may be NULL if * the PAL cannot accept reservation requests). + * @channel: channel being used by the PAL; 0 if the PAL isn't using + * the radio; -1 if the PAL wishes to use the radio but + * cannot. * * A Protocol Adaptation Layer (PAL) is a user of the WiMedia UWB * radio platform (e.g., WUSB, WLP or Bluetooth UWB AMP). @@ -405,12 +412,20 @@ struct uwb_pal { struct list_head node; const char *name; struct device *device; + struct uwb_rc *rc; + + void (*channel_changed)(struct uwb_pal *pal, int channel); void (*new_rsv)(struct uwb_pal *pal, struct uwb_rsv *rsv); + + int channel; }; void uwb_pal_init(struct uwb_pal *pal); -int uwb_pal_register(struct uwb_rc *rc, struct uwb_pal *pal); -void uwb_pal_unregister(struct uwb_rc *rc, struct uwb_pal *pal); +int uwb_pal_register(struct uwb_pal *pal); +void uwb_pal_unregister(struct uwb_pal *pal); + +int uwb_radio_start(struct uwb_pal *pal); +void uwb_radio_stop(struct uwb_pal *pal); /* * General public API diff --git a/include/linux/uwb/debug-cmd.h b/include/linux/uwb/debug-cmd.h index 6a16566f022..07efbe17db5 100644 --- a/include/linux/uwb/debug-cmd.h +++ b/include/linux/uwb/debug-cmd.h @@ -34,6 +34,8 @@ enum uwb_dbg_cmd_type { UWB_DBG_CMD_RSV_TERMINATE = 2, UWB_DBG_CMD_IE_ADD = 3, UWB_DBG_CMD_IE_RM = 4, + UWB_DBG_CMD_RADIO_START = 5, + UWB_DBG_CMD_RADIO_STOP = 6, }; struct uwb_dbg_cmd_rsv_establish { -- cgit v1.2.3-70-g09d2 From dcc7461eef7341e84e2f7274f904ce01a43b2506 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Wed, 26 Nov 2008 13:36:59 +0000 Subject: wusb: add debug files for ASL, PZL and DI to the whci-hcd driver Add asl, pzl and di debugfs files to uwb/uwbN/wusbhc for WHCI host controller. These dump the current ASL, PZL and DI buffer. Signed-off-by: David Vrabel --- drivers/usb/host/whci/Kbuild | 1 + drivers/usb/host/whci/asl.c | 25 ------ drivers/usb/host/whci/debug.c | 189 ++++++++++++++++++++++++++++++++++++++++++ drivers/usb/host/whci/hcd.c | 3 + drivers/usb/host/whci/pzl.c | 28 ------- drivers/usb/host/whci/qset.c | 40 --------- drivers/usb/host/whci/whcd.h | 9 +- drivers/usb/host/whci/wusb.c | 27 ------ drivers/uwb/pal.c | 5 ++ drivers/uwb/uwb-debug.c | 13 +++ drivers/uwb/uwb-internal.h | 3 +- include/linux/uwb.h | 3 + 12 files changed, 223 insertions(+), 123 deletions(-) create mode 100644 drivers/usb/host/whci/debug.c (limited to 'drivers/usb/host/whci/hcd.c') diff --git a/drivers/usb/host/whci/Kbuild b/drivers/usb/host/whci/Kbuild index 26a3871ea0f..11e5040b833 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 whci-hcd-y := \ asl.o \ + debug.o \ hcd.o \ hw.o \ init.o \ diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c index ba99a7a3f81..577c0d29849 100644 --- a/drivers/usb/host/whci/asl.c +++ b/drivers/usb/host/whci/asl.c @@ -19,32 +19,11 @@ #include #include #include -#define D_LOCAL 0 -#include #include "../../wusbcore/wusbhc.h" #include "whcd.h" -#if D_LOCAL >= 4 -static void dump_asl(struct whc *whc, const char *tag) -{ - struct device *dev = &whc->umc->dev; - struct whc_qset *qset; - - d_printf(4, dev, "ASL %s\n", tag); - - list_for_each_entry(qset, &whc->async_list, list_node) { - dump_qset(qset, dev); - } -} -#else -static inline void dump_asl(struct whc *whc, const char *tag) -{ -} -#endif - - static void qset_get_next_prev(struct whc *whc, struct whc_qset *qset, struct whc_qset **next, struct whc_qset **prev) { @@ -217,8 +196,6 @@ void scan_async_work(struct work_struct *work) spin_lock_irq(&whc->lock); - dump_asl(whc, "before processing"); - /* * Transerve the software list backwards so new qsets can be * safely inserted into the ASL without making it non-circular. @@ -232,8 +209,6 @@ void scan_async_work(struct work_struct *work) update |= process_qset(whc, qset); } - dump_asl(whc, "after processing"); - spin_unlock_irq(&whc->lock); if (update) { diff --git a/drivers/usb/host/whci/debug.c b/drivers/usb/host/whci/debug.c new file mode 100644 index 00000000000..cf2d45946c5 --- /dev/null +++ b/drivers/usb/host/whci/debug.c @@ -0,0 +1,189 @@ +/* + * Wireless Host Controller (WHC) debug. + * + * Copyright (C) 2008 Cambridge Silicon Radio Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include +#include + +#include "../../wusbcore/wusbhc.h" + +#include "whcd.h" + +struct whc_dbg { + struct dentry *di_f; + struct dentry *asl_f; + struct dentry *pzl_f; +}; + +void qset_print(struct seq_file *s, struct whc_qset *qset) +{ + struct whc_std *std; + struct urb *urb = NULL; + int i; + + seq_printf(s, "qset %08x\n", (u32)qset->qset_dma); + seq_printf(s, " -> %08x\n", (u32)qset->qh.link); + seq_printf(s, " info: %08x %08x %08x\n", + qset->qh.info1, qset->qh.info2, qset->qh.info3); + seq_printf(s, " sts: %04x errs: %d\n", qset->qh.status, qset->qh.err_count); + seq_printf(s, " TD: sts: %08x opts: %08x\n", + qset->qh.overlay.qtd.status, qset->qh.overlay.qtd.options); + + for (i = 0; i < WHCI_QSET_TD_MAX; i++) { + seq_printf(s, " %c%c TD[%d]: sts: %08x opts: %08x ptr: %08x\n", + i == qset->td_start ? 'S' : ' ', + i == qset->td_end ? 'E' : ' ', + i, qset->qtd[i].status, qset->qtd[i].options, + (u32)qset->qtd[i].page_list_ptr); + } + seq_printf(s, " ntds: %d\n", qset->ntds); + list_for_each_entry(std, &qset->stds, list_node) { + if (urb != std->urb) { + urb = std->urb; + seq_printf(s, " urb %p transferred: %d bytes\n", urb, + urb->actual_length); + } + if (std->qtd) + seq_printf(s, " sTD[%td]: %zu bytes @ %08x\n", + std->qtd - &qset->qtd[0], + std->len, std->num_pointers ? + (u32)(std->pl_virt[0].buf_ptr) : (u32)std->dma_addr); + else + seq_printf(s, " sTD[-]: %zd bytes @ %08x\n", + std->len, std->num_pointers ? + (u32)(std->pl_virt[0].buf_ptr) : (u32)std->dma_addr); + } +} + +static int di_print(struct seq_file *s, void *p) +{ + struct whc *whc = s->private; + char buf[72]; + int d; + + for (d = 0; d < whc->n_devices; d++) { + struct di_buf_entry *di = &whc->di_buf[d]; + + bitmap_scnprintf(buf, sizeof(buf), + (unsigned long *)di->availability_info, UWB_NUM_MAS); + + seq_printf(s, "DI[%d]\n", d); + seq_printf(s, " availability: %s\n", buf); + seq_printf(s, " %c%c key idx: %d dev addr: %d\n", + (di->addr_sec_info & WHC_DI_SECURE) ? 'S' : ' ', + (di->addr_sec_info & WHC_DI_DISABLE) ? 'D' : ' ', + (di->addr_sec_info & WHC_DI_KEY_IDX_MASK) >> 8, + (di->addr_sec_info & WHC_DI_DEV_ADDR_MASK)); + } + return 0; +} + +static int asl_print(struct seq_file *s, void *p) +{ + struct whc *whc = s->private; + struct whc_qset *qset; + + list_for_each_entry(qset, &whc->async_list, list_node) { + qset_print(s, qset); + } + + return 0; +} + +static int pzl_print(struct seq_file *s, void *p) +{ + struct whc *whc = s->private; + struct whc_qset *qset; + int period; + + for (period = 0; period < 5; period++) { + seq_printf(s, "Period %d\n", period); + list_for_each_entry(qset, &whc->periodic_list[period], list_node) { + qset_print(s, qset); + } + } + return 0; +} + +static int di_open(struct inode *inode, struct file *file) +{ + return single_open(file, di_print, inode->i_private); +} + +static int asl_open(struct inode *inode, struct file *file) +{ + return single_open(file, asl_print, inode->i_private); +} + +static int pzl_open(struct inode *inode, struct file *file) +{ + return single_open(file, pzl_print, inode->i_private); +} + +static struct file_operations di_fops = { + .open = di_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static struct file_operations asl_fops = { + .open = asl_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static struct file_operations pzl_fops = { + .open = pzl_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +void whc_dbg_init(struct whc *whc) +{ + if (whc->wusbhc.pal.debugfs_dir == NULL) + return; + + whc->dbg = kzalloc(sizeof(struct whc_dbg), GFP_KERNEL); + if (whc->dbg == NULL) + return; + + whc->dbg->di_f = debugfs_create_file("di", 0444, + whc->wusbhc.pal.debugfs_dir, whc, + &di_fops); + whc->dbg->asl_f = debugfs_create_file("asl", 0444, + whc->wusbhc.pal.debugfs_dir, whc, + &asl_fops); + whc->dbg->pzl_f = debugfs_create_file("pzl", 0444, + whc->wusbhc.pal.debugfs_dir, whc, + &pzl_fops); +} + +void whc_dbg_clean_up(struct whc *whc) +{ + if (whc->dbg) { + debugfs_remove(whc->dbg->pzl_f); + debugfs_remove(whc->dbg->asl_f); + debugfs_remove(whc->dbg->di_f); + kfree(whc->dbg); + } +} diff --git a/drivers/usb/host/whci/hcd.c b/drivers/usb/host/whci/hcd.c index f599f89d3be..1569afd6245 100644 --- a/drivers/usb/host/whci/hcd.c +++ b/drivers/usb/host/whci/hcd.c @@ -273,6 +273,8 @@ static int whc_probe(struct umc_dev *umc) goto error_wusbhc_b_create; } + whc_dbg_init(whc); + return 0; error_wusbhc_b_create: @@ -296,6 +298,7 @@ static void whc_remove(struct umc_dev *umc) struct whc *whc = wusbhc_to_whc(wusbhc); if (usb_hcd) { + whc_dbg_clean_up(whc); wusbhc_b_destroy(wusbhc); usb_remove_hcd(usb_hcd); wusbhc_destroy(wusbhc); diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c index 34d3a0aeab2..2ae5abf69a6 100644 --- a/drivers/usb/host/whci/pzl.c +++ b/drivers/usb/host/whci/pzl.c @@ -19,35 +19,11 @@ #include #include #include -#define D_LOCAL 0 -#include #include "../../wusbcore/wusbhc.h" #include "whcd.h" -#if D_LOCAL >= 4 -static void dump_pzl(struct whc *whc, const char *tag) -{ - struct device *dev = &whc->umc->dev; - struct whc_qset *qset; - int period = 0; - - d_printf(4, dev, "PZL %s\n", tag); - - for (period = 0; period < 5; period++) { - d_printf(4, dev, "Period %d\n", period); - list_for_each_entry(qset, &whc->periodic_list[period], list_node) { - dump_qset(qset, dev); - } - } -} -#else -static inline void dump_pzl(struct whc *whc, const char *tag) -{ -} -#endif - static void update_pzl_pointers(struct whc *whc, int period, u64 addr) { switch (period) { @@ -250,8 +226,6 @@ void scan_periodic_work(struct work_struct *work) spin_lock_irq(&whc->lock); - dump_pzl(whc, "before processing"); - for (period = 4; period >= 0; period--) { list_for_each_entry_safe(qset, t, &whc->periodic_list[period], list_node) { if (!qset->in_hw_list) @@ -263,8 +237,6 @@ void scan_periodic_work(struct work_struct *work) if (update & (WHC_UPDATE_ADDED | WHC_UPDATE_REMOVED)) update_pzl_hw_view(whc); - dump_pzl(whc, "after processing"); - spin_unlock_irq(&whc->lock); if (update) { diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c index 0420037d2e1..7be74314ee1 100644 --- a/drivers/usb/host/whci/qset.c +++ b/drivers/usb/host/whci/qset.c @@ -24,46 +24,6 @@ #include "whcd.h" -void dump_qset(struct whc_qset *qset, struct device *dev) -{ - struct whc_std *std; - struct urb *urb = NULL; - int i; - - dev_dbg(dev, "qset %08x\n", (u32)qset->qset_dma); - dev_dbg(dev, " -> %08x\n", (u32)qset->qh.link); - dev_dbg(dev, " info: %08x %08x %08x\n", - qset->qh.info1, qset->qh.info2, qset->qh.info3); - dev_dbg(dev, " sts: %04x errs: %d\n", qset->qh.status, qset->qh.err_count); - dev_dbg(dev, " TD: sts: %08x opts: %08x\n", - qset->qh.overlay.qtd.status, qset->qh.overlay.qtd.options); - - for (i = 0; i < WHCI_QSET_TD_MAX; i++) { - dev_dbg(dev, " %c%c TD[%d]: sts: %08x opts: %08x ptr: %08x\n", - i == qset->td_start ? 'S' : ' ', - i == qset->td_end ? 'E' : ' ', - i, qset->qtd[i].status, qset->qtd[i].options, - (u32)qset->qtd[i].page_list_ptr); - } - dev_dbg(dev, " ntds: %d\n", qset->ntds); - list_for_each_entry(std, &qset->stds, list_node) { - if (urb != std->urb) { - urb = std->urb; - dev_dbg(dev, " urb %p transferred: %d bytes\n", urb, - urb->actual_length); - } - if (std->qtd) - dev_dbg(dev, " sTD[%td]: %zu bytes @ %08x\n", - std->qtd - &qset->qtd[0], - std->len, std->num_pointers ? - (u32)(std->pl_virt[0].buf_ptr) : (u32)std->dma_addr); - else - dev_dbg(dev, " sTD[-]: %zd bytes @ %08x\n", - std->len, std->num_pointers ? - (u32)(std->pl_virt[0].buf_ptr) : (u32)std->dma_addr); - } -} - struct whc_qset *qset_alloc(struct whc *whc, gfp_t mem_flags) { struct whc_qset *qset; diff --git a/drivers/usb/host/whci/whcd.h b/drivers/usb/host/whci/whcd.h index 1bbb8cb6bf8..0f3540f04f5 100644 --- a/drivers/usb/host/whci/whcd.h +++ b/drivers/usb/host/whci/whcd.h @@ -21,6 +21,7 @@ #define __WHCD_H #include +#include #include #include "whci-hc.h" @@ -28,6 +29,7 @@ /* Generic command timeout. */ #define WHC_GENCMD_TIMEOUT_MS 100 +struct whc_dbg; struct whc { struct wusbhc wusbhc; @@ -69,6 +71,8 @@ struct whc { struct list_head periodic_removed_list; wait_queue_head_t periodic_list_wq; struct work_struct periodic_work; + + struct whc_dbg *dbg; }; #define wusbhc_to_whc(w) (container_of((w), struct whc, wusbhc)) @@ -190,8 +194,11 @@ void process_inactive_qtd(struct whc *whc, struct whc_qset *qset, struct whc_qtd *qtd); enum whc_update qset_add_qtds(struct whc *whc, struct whc_qset *qset); void qset_remove_complete(struct whc *whc, struct whc_qset *qset); -void dump_qset(struct whc_qset *qset, struct device *dev); void pzl_update(struct whc *whc, uint32_t wusbcmd); void asl_update(struct whc *whc, uint32_t wusbcmd); +/* debug.c */ +void whc_dbg_init(struct whc *whc); +void whc_dbg_clean_up(struct whc *whc); + #endif /* #ifndef __WHCD_H */ diff --git a/drivers/usb/host/whci/wusb.c b/drivers/usb/host/whci/wusb.c index 540021a0971..f24efdebad1 100644 --- a/drivers/usb/host/whci/wusb.c +++ b/drivers/usb/host/whci/wusb.c @@ -18,43 +18,16 @@ #include #include #include -#define D_LOCAL 1 -#include #include "../../wusbcore/wusbhc.h" #include "whcd.h" -#if D_LOCAL >= 1 -static void dump_di(struct whc *whc, int idx) -{ - struct di_buf_entry *di = &whc->di_buf[idx]; - struct device *dev = &whc->umc->dev; - char buf[128]; - - bitmap_scnprintf(buf, sizeof(buf), (unsigned long *)di->availability_info, UWB_NUM_MAS); - - d_printf(1, dev, "DI[%d]\n", idx); - d_printf(1, dev, " availability: %s\n", buf); - d_printf(1, dev, " %c%c key idx: %d dev addr: %d\n", - (di->addr_sec_info & WHC_DI_SECURE) ? 'S' : ' ', - (di->addr_sec_info & WHC_DI_DISABLE) ? 'D' : ' ', - (di->addr_sec_info & WHC_DI_KEY_IDX_MASK) >> 8, - (di->addr_sec_info & WHC_DI_DEV_ADDR_MASK)); -} -#else -static inline void dump_di(struct whc *whc, int idx) -{ -} -#endif - static int whc_update_di(struct whc *whc, int idx) { int offset = idx / 32; u32 bit = 1 << (idx % 32); - dump_di(whc, idx); - le_writel(bit, whc->base + WUSBDIBUPDATED + offset); return whci_wait_for(&whc->umc->dev, diff --git a/drivers/uwb/pal.c b/drivers/uwb/pal.c index 605765124f5..99a19c19909 100644 --- a/drivers/uwb/pal.c +++ b/drivers/uwb/pal.c @@ -16,6 +16,7 @@ * along with this program. If not, see . */ #include +#include #include #include "uwb-internal.h" @@ -54,6 +55,8 @@ int uwb_pal_register(struct uwb_pal *pal) } } + pal->debugfs_dir = uwb_dbg_create_pal_dir(pal); + mutex_lock(&rc->uwb_dev.mutex); list_add(&pal->node, &rc->pals); mutex_unlock(&rc->uwb_dev.mutex); @@ -76,6 +79,8 @@ void uwb_pal_unregister(struct uwb_pal *pal) list_del(&pal->node); mutex_unlock(&rc->uwb_dev.mutex); + debugfs_remove(pal->debugfs_dir); + if (pal->device) { sysfs_remove_link(&rc->uwb_dev.dev.kobj, pal->name); sysfs_remove_link(&pal->device->kobj, "uwb_rc"); diff --git a/drivers/uwb/uwb-debug.c b/drivers/uwb/uwb-debug.c index ec1b7a403ff..a6debb9baf3 100644 --- a/drivers/uwb/uwb-debug.c +++ b/drivers/uwb/uwb-debug.c @@ -407,3 +407,16 @@ void uwb_dbg_exit(void) { debugfs_remove(root_dir); } + +/** + * uwb_dbg_create_pal_dir - create a debugfs directory for a PAL + * @pal: The PAL. + */ +struct dentry *uwb_dbg_create_pal_dir(struct uwb_pal *pal) +{ + struct uwb_rc *rc = pal->rc; + + if (root_dir && rc->dbg && rc->dbg->root_d && pal->name) + return debugfs_create_dir(pal->name, rc->dbg->root_d); + return NULL; +} diff --git a/drivers/uwb/uwb-internal.h b/drivers/uwb/uwb-internal.h index 9c0cdb4ded0..f0f21f406bf 100644 --- a/drivers/uwb/uwb-internal.h +++ b/drivers/uwb/uwb-internal.h @@ -284,8 +284,7 @@ void uwb_dbg_init(void); void uwb_dbg_exit(void); void uwb_dbg_add_rc(struct uwb_rc *rc); void uwb_dbg_del_rc(struct uwb_rc *rc); - -/* Workarounds for version specific stuff */ +struct dentry *uwb_dbg_create_pal_dir(struct uwb_pal *pal); static inline void uwb_dev_lock(struct uwb_dev *uwb_dev) { diff --git a/include/linux/uwb.h b/include/linux/uwb.h index 1719709d60c..d7ed5201ade 100644 --- a/include/linux/uwb.h +++ b/include/linux/uwb.h @@ -394,6 +394,8 @@ struct uwb_rc { * @channel: channel being used by the PAL; 0 if the PAL isn't using * the radio; -1 if the PAL wishes to use the radio but * cannot. + * @debugfs_dir: a debugfs directory which the PAL can use for its own + * debugfs files. * * A Protocol Adaptation Layer (PAL) is a user of the WiMedia UWB * radio platform (e.g., WUSB, WLP or Bluetooth UWB AMP). @@ -418,6 +420,7 @@ struct uwb_pal { void (*new_rsv)(struct uwb_pal *pal, struct uwb_rsv *rsv); int channel; + struct dentry *debugfs_dir; }; void uwb_pal_init(struct uwb_pal *pal); -- cgit v1.2.3-70-g09d2