From b09ac64b7b2d93efab3998033588f5cb0e470ccf Mon Sep 17 00:00:00 2001 From: David Vrabel <david.vrabel@csr.com> Date: Mon, 27 Oct 2008 15:14:03 +0000 Subject: wusb: release mutex in the error path of whci-hcd's whc_do_gencmd() Signed-off-by: David Vrabel <david.vrabel@csr.com> --- drivers/usb/host/whci/hw.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/whci/hw.c b/drivers/usb/host/whci/hw.c index ac86e59c122..d498e720321 100644 --- a/drivers/usb/host/whci/hw.c +++ b/drivers/usb/host/whci/hw.c @@ -50,6 +50,7 @@ int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len) unsigned long flags; dma_addr_t dma_addr; int t; + int ret = 0; mutex_lock(&whc->mutex); @@ -61,7 +62,8 @@ int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len) dev_err(&whc->umc->dev, "generic command timeout (%04x/%04x)\n", le_readl(whc->base + WUSBGENCMDSTS), le_readl(whc->base + WUSBGENCMDPARAMS)); - return -ETIMEDOUT; + ret = -ETIMEDOUT; + goto out; } if (addr) { @@ -80,8 +82,8 @@ int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len) whc->base + WUSBGENCMDSTS); spin_unlock_irqrestore(&whc->lock, flags); - +out: mutex_unlock(&whc->mutex); - return 0; + return ret; } -- cgit v1.2.3-18-g5258 From cae1c11414912bf77a62aebd65ced321f0b9da51 Mon Sep 17 00:00:00 2001 From: David Vrabel <david.vrabel@csr.com> Date: Mon, 27 Oct 2008 15:22:46 +0000 Subject: uwb: reference count reservations Reference counting the struct uwb_rsv's is safer and easier to get right than the transferring ownership of the structures from the PAL to reservation manager. This fixes an oops in the debug PAL after a reservation timed out. Signed-off-by: David Vrabel <david.vrabel@csr.com> --- drivers/usb/wusbcore/reservation.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/wusbcore/reservation.c b/drivers/usb/wusbcore/reservation.c index fc63e77ded2..7b6525dac2f 100644 --- a/drivers/usb/wusbcore/reservation.c +++ b/drivers/usb/wusbcore/reservation.c @@ -59,7 +59,6 @@ static void wusbhc_rsv_complete_cb(struct uwb_rsv *rsv) case UWB_RSV_STATE_NONE: dev_dbg(dev, "removed reservation\n"); wusbhc_bwa_set(wusbhc, 0, NULL); - wusbhc->rsv = NULL; break; default: dev_dbg(dev, "unexpected reservation state: %d\n", rsv->state); @@ -105,11 +104,11 @@ int wusbhc_rsv_establish(struct wusbhc *wusbhc) /** - * wusbhc_rsv_terminate - terminate any cluster reservation + * wusbhc_rsv_terminate - terminate the cluster reservation * @wusbhc: the WUSB host whose reservation is to be terminated */ void wusbhc_rsv_terminate(struct wusbhc *wusbhc) { - if (wusbhc->rsv) - uwb_rsv_terminate(wusbhc->rsv); + uwb_rsv_terminate(wusbhc->rsv); + uwb_rsv_destroy(wusbhc->rsv); } -- cgit v1.2.3-18-g5258 From d409f3bf47c5e5ae10601d079204e263bc176bcf Mon Sep 17 00:00:00 2001 From: David Vrabel <david.vrabel@csr.com> Date: Mon, 27 Oct 2008 15:30:12 +0000 Subject: wusb: disable verification of the key generation algorithms Verifing the key generation algorithms could take too long on a freshly booted system (due to lack of entropy) so disable the test unless a module parameter (debug_crypto_verify) is specified. Signed-off-by: David Vrabel <david.vrabel@csr.com> --- drivers/usb/wusbcore/crypto.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/wusbcore/crypto.c b/drivers/usb/wusbcore/crypto.c index c36c4389baa..0ca860305fe 100644 --- a/drivers/usb/wusbcore/crypto.c +++ b/drivers/usb/wusbcore/crypto.c @@ -54,6 +54,10 @@ #define D_LOCAL 0 #include <linux/uwb/debug.h> +static int debug_crypto_verify = 0; + +module_param(debug_crypto_verify, int, 0); +MODULE_PARM_DESC(debug_crypto_verify, "verify the key generation algorithms"); /* * Block of data, as understood by AES-CCM @@ -526,10 +530,13 @@ int wusb_crypto_init(void) { int result; - result = wusb_key_derive_verify(); - if (result < 0) - return result; - return wusb_oob_mic_verify(); + if (debug_crypto_verify) { + result = wusb_key_derive_verify(); + if (result < 0) + return result; + return wusb_oob_mic_verify(); + } + return 0; } void wusb_crypto_exit(void) -- cgit v1.2.3-18-g5258 From 4d2bea4ca0adb4cebfbf89d34869c74081c42577 Mon Sep 17 00:00:00 2001 From: David Vrabel <david.vrabel@csr.com> Date: Mon, 27 Oct 2008 15:42:31 +0000 Subject: wusb: do a proper channel stop When stopping the WUSB channel the host should send Channel Stop IEs giving the WUSB Channel Time of the last MMC. Both WHCI and HWA hosts provide a channel stop command for this. Signed-off-by: David Vrabel <david.vrabel@csr.com> --- drivers/usb/host/hwa-hc.c | 102 +++++++++++++++++++--------------------- drivers/usb/host/whci/whcd.h | 2 +- drivers/usb/host/whci/whci-hc.h | 2 + drivers/usb/host/whci/wusb.c | 15 ++++-- drivers/usb/wusbcore/mmc.c | 8 +--- drivers/usb/wusbcore/wusbhc.h | 24 ++++++---- 6 files changed, 79 insertions(+), 74 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c index 64be4d88df1..0e18989e165 100644 --- a/drivers/usb/host/hwa-hc.c +++ b/drivers/usb/host/hwa-hc.c @@ -171,11 +171,6 @@ static int hwahc_op_start(struct usb_hcd *usb_hcd) if (result < 0) goto error_set_cluster_id; - result = wa_nep_arm(&hwahc->wa, GFP_KERNEL); - if (result < 0) { - dev_err(dev, "cannot listen to notifications: %d\n", result); - goto error_stop; - } usb_hcd->uses_new_polling = 1; usb_hcd->poll_rh = 1; usb_hcd->state = HC_STATE_RUNNING; @@ -185,8 +180,6 @@ out: d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result); return result; -error_stop: - __wa_stop(&hwahc->wa); error_set_cluster_id: wusb_cluster_id_put(wusbhc->cluster_id); error_cluster_id_get: @@ -194,39 +187,6 @@ error_cluster_id_get: } -/* - * FIXME: break this function up - */ -static int __hwahc_op_wusbhc_start(struct wusbhc *wusbhc) -{ - int result; - struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc); - struct device *dev = &hwahc->wa.usb_iface->dev; - - /* Set up a Host Info WUSB Information Element */ - d_fnstart(4, dev, "(hwahc %p)\n", hwahc); - result = -ENOSPC; - - result = __wa_set_feature(&hwahc->wa, WA_ENABLE); - if (result < 0) { - dev_err(dev, "error commanding HC to start: %d\n", result); - goto error_stop; - } - result = __wa_wait_status(&hwahc->wa, WA_ENABLE, WA_ENABLE); - if (result < 0) { - dev_err(dev, "error waiting for HC to start: %d\n", result); - goto error_stop; - } - result = 0; -out: - d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result); - return result; - -error_stop: - result = __wa_clear_feature(&hwahc->wa, WA_ENABLE); - goto out; -} - static int hwahc_op_suspend(struct usb_hcd *usb_hcd, pm_message_t msg) { struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); @@ -246,18 +206,6 @@ static int hwahc_op_resume(struct usb_hcd *usb_hcd) return -ENOSYS; } -static void __hwahc_op_wusbhc_stop(struct wusbhc *wusbhc) -{ - int result; - struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc); - struct device *dev = &hwahc->wa.usb_iface->dev; - - d_fnstart(4, dev, "(hwahc %p)\n", hwahc); - /* Nothing for now */ - d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result); - return; -} - /* * No need to abort pipes, as when this is called, all the children * has been disconnected and that has done it [through @@ -275,8 +223,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); - wa_nep_disarm(&hwahc->wa); - result = __wa_stop(&hwahc->wa); wusb_cluster_id_put(wusbhc->cluster_id); mutex_unlock(&wusbhc->mutex); d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result); @@ -325,6 +271,54 @@ static void hwahc_op_endpoint_disable(struct usb_hcd *usb_hcd, rpipe_ep_disable(&hwahc->wa, ep); } +static int __hwahc_op_wusbhc_start(struct wusbhc *wusbhc) +{ + int result; + struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc); + struct device *dev = &hwahc->wa.usb_iface->dev; + + result = __wa_set_feature(&hwahc->wa, WA_ENABLE); + if (result < 0) { + dev_err(dev, "error commanding HC to start: %d\n", result); + goto error_stop; + } + result = __wa_wait_status(&hwahc->wa, WA_ENABLE, WA_ENABLE); + if (result < 0) { + dev_err(dev, "error waiting for HC to start: %d\n", result); + goto error_stop; + } + result = wa_nep_arm(&hwahc->wa, GFP_KERNEL); + if (result < 0) { + dev_err(dev, "cannot listen to notifications: %d\n", result); + goto error_stop; + } + return result; + +error_stop: + __wa_clear_feature(&hwahc->wa, WA_ENABLE); + return result; +} + +static void __hwahc_op_wusbhc_stop(struct wusbhc *wusbhc, int delay) +{ + struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc); + struct wahc *wa = &hwahc->wa; + u8 iface_no = wa->usb_iface->cur_altsetting->desc.bInterfaceNumber; + int ret; + + ret = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0), + WUSB_REQ_CHAN_STOP, + USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + delay * 1000, + iface_no, + NULL, 0, 1000 /* FIXME: arbitrary */); + if (ret == 0) + msleep(delay); + + wa_nep_disarm(&hwahc->wa); + __wa_stop(&hwahc->wa); +} + /* * Set the UWB MAS allocation for the WUSB cluster * diff --git a/drivers/usb/host/whci/whcd.h b/drivers/usb/host/whci/whcd.h index 1d2a53bd39f..1bbb8cb6bf8 100644 --- a/drivers/usb/host/whci/whcd.h +++ b/drivers/usb/host/whci/whcd.h @@ -136,7 +136,7 @@ int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len); /* wusb.c */ int whc_wusbhc_start(struct wusbhc *wusbhc); -void whc_wusbhc_stop(struct wusbhc *wusbhc); +void whc_wusbhc_stop(struct wusbhc *wusbhc, int delay); int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt, u8 handle, struct wuie_hdr *wuie); int whc_mmcie_rm(struct wusbhc *wusbhc, u8 handle); diff --git a/drivers/usb/host/whci/whci-hc.h b/drivers/usb/host/whci/whci-hc.h index bff1eb7a35c..51df7e313b3 100644 --- a/drivers/usb/host/whci/whci-hc.h +++ b/drivers/usb/host/whci/whci-hc.h @@ -410,6 +410,8 @@ struct dn_buf_entry { # define WUSBDNTSCTRL_SLOTS(s) ((s) << 0) #define WUSBTIME 0x68 +# define WUSBTIME_CHANNEL_TIME_MASK 0x00ffffff + #define WUSBBPST 0x6c #define WUSBDIBUPDATED 0x70 diff --git a/drivers/usb/host/whci/wusb.c b/drivers/usb/host/whci/wusb.c index 66e4ddcd961..2befd475def 100644 --- a/drivers/usb/host/whci/wusb.c +++ b/drivers/usb/host/whci/wusb.c @@ -64,8 +64,9 @@ static int whc_update_di(struct whc *whc, int idx) } /* - * WHCI starts and stops MMCs based on there being a valid GTK so - * these need only start/stop the asynchronous and periodic schedules. + * WHCI starts MMCs based on there being a valid GTK so these need + * only start/stop the asynchronous and periodic schedules and send a + * channel stop command. */ int whc_wusbhc_start(struct wusbhc *wusbhc) @@ -78,12 +79,20 @@ int whc_wusbhc_start(struct wusbhc *wusbhc) return 0; } -void whc_wusbhc_stop(struct wusbhc *wusbhc) +void whc_wusbhc_stop(struct wusbhc *wusbhc, int delay) { struct whc *whc = wusbhc_to_whc(wusbhc); + u32 stop_time, now_time; + int ret; pzl_stop(whc); asl_stop(whc); + + now_time = le_readl(whc->base + WUSBTIME) & WUSBTIME_CHANNEL_TIME_MASK; + stop_time = (now_time + ((delay * 8) << 7)) & 0x00ffffff; + ret = whc_do_gencmd(whc, WUSBGENCMDSTS_CHAN_STOP, stop_time, NULL, 0); + if (ret == 0) + msleep(delay); } int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt, diff --git a/drivers/usb/wusbcore/mmc.c b/drivers/usb/wusbcore/mmc.c index cfa77a01ceb..af2aee0fdff 100644 --- a/drivers/usb/wusbcore/mmc.c +++ b/drivers/usb/wusbcore/mmc.c @@ -250,18 +250,14 @@ error_alloc: * wusbhc_stop - stop transmitting MMCs * @wusbhc: the HC to stop * - * Send a Host Disconnect IE, wait, remove all the MMCs (stop sending MMCs). - * - * If we can't allocate a Host Stop IE, screw it, we don't notify the - * devices we are disconnecting... + * Stops the WUSB channel and removes the cluster reservation. */ void wusbhc_stop(struct wusbhc *wusbhc) { if (wusbhc->active) { wusbhc->active = 0; - wusbhc->stop(wusbhc); + wusbhc->stop(wusbhc, WUSB_CHANNEL_STOP_DELAY_MS); wusbhc_sec_stop(wusbhc); - __wusbhc_host_disconnect_ie(wusbhc); wusbhc_devconnect_stop(wusbhc); wusbhc_rsv_terminate(wusbhc); } diff --git a/drivers/usb/wusbcore/wusbhc.h b/drivers/usb/wusbcore/wusbhc.h index d0c132434f1..b9bdf5a5f11 100644 --- a/drivers/usb/wusbcore/wusbhc.h +++ b/drivers/usb/wusbcore/wusbhc.h @@ -64,6 +64,13 @@ #include <linux/uwb.h> #include <linux/usb/wusb.h> +/* + * Time from a WUSB channel stop request to the last transmitted MMC. + * + * This needs to be > 4.096 ms in case no MMCs can be transmitted in + * zone 0. + */ +#define WUSB_CHANNEL_STOP_DELAY_MS 8 /** * Wireless USB device @@ -198,21 +205,18 @@ struct wusb_port { * @mmcies_max Max number of Information Elements this HC can send * in its MMC. Read-only. * + * @start Start the WUSB channel. + * + * @stop Stop the WUSB channel after the specified number of + * milliseconds. Channel Stop IEs should be transmitted + * as required by [WUSB] 4.16.2.1. + * * @mmcie_add HC specific operation (WHCI or HWA) for adding an * MMCIE. * * @mmcie_rm HC specific operation (WHCI or HWA) for removing an * MMCIE. * - * @enc_types Array which describes the encryptions methods - * supported by the host as described in WUSB1.0 -- - * one entry per supported method. As of WUSB1.0 there - * is only four methods, we make space for eight just in - * case they decide to add some more (and pray they do - * it in sequential order). if 'enc_types[enc_method] - * != 0', then it is supported by the host. enc_method - * is USB_ENC_TYPE*. - * * @set_ptk: Set the PTK and enable encryption for a device. Or, if * the supplied key is NULL, disable encryption for that * device. @@ -269,7 +273,7 @@ struct wusbhc { u8 mmcies_max; /* FIXME: make wusbhc_ops? */ int (*start)(struct wusbhc *wusbhc); - void (*stop)(struct wusbhc *wusbhc); + void (*stop)(struct wusbhc *wusbhc, int delay); int (*mmcie_add)(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt, u8 handle, struct wuie_hdr *wuie); int (*mmcie_rm)(struct wusbhc *wusbhc, u8 handle); -- cgit v1.2.3-18-g5258 From 4656d5de9555e263c5b4c0462b5af7e7bded1b42 Mon Sep 17 00:00:00 2001 From: David Vrabel <david.vrabel@csr.com> Date: Mon, 27 Oct 2008 17:12:33 +0000 Subject: wusb: reset WUSB devices with SetAddress(0) Using a Reset Device IE to reset a WUSB device is too heavyweight as it causes the devcie to disconnect (which the USB stack does not expect and cannot handle). Instead, do a SetAddress(0); SetAddress(AuthAddr) for authenticated devices. Unauthenticated devices will not be reset and the stack will have to rely on the device timing out after TrustTimeout and disconnecting. Signed-off-by: David Vrabel <david.vrabel@csr.com> --- drivers/usb/wusbcore/devconnect.c | 100 +------------------------------------- drivers/usb/wusbcore/rh.c | 40 ++++++++------- drivers/usb/wusbcore/security.c | 3 +- drivers/usb/wusbcore/wusbhc.h | 4 +- 4 files changed, 25 insertions(+), 122 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c index f45d777bef3..c01c7a80744 100644 --- a/drivers/usb/wusbcore/devconnect.c +++ b/drivers/usb/wusbcore/devconnect.c @@ -57,9 +57,6 @@ * Called by notif.c:wusb_handle_dn_connect() * when a DN_Connect is received. * - * wusbhc_devconnect_auth() Called by rh.c:wusbhc_rh_port_reset() when - * doing the device connect sequence. - * * wusb_devconnect_acked() Ack done, release resources. * * wusb_handle_dn_alive() Called by notif.c:wusb_handle_dn() @@ -69,9 +66,6 @@ * process a disconenct request from a * device. * - * wusb_dev_reset() Called by rh.c:wusbhc_rh_port_reset() when - * resetting a device. - * * __wusb_dev_disable() Called by rh.c:wusbhc_rh_clear_port_feat() when * disabling a port. * @@ -366,12 +360,10 @@ void wusbhc_devconnect_ack(struct wusbhc *wusbhc, struct wusb_dn_connect *dnc, port->wusb_dev = wusb_dev; port->status |= USB_PORT_STAT_CONNECTION; port->change |= USB_PORT_STAT_C_CONNECTION; - port->reset_count = 0; /* Now the port status changed to connected; khubd will * pick the change up and try to reset the port to bring it to * the enabled state--so this process returns up to the stack - * and it calls back into wusbhc_rh_port_reset() who will call - * devconnect_auth(). + * and it calls back into wusbhc_rh_port_reset(). */ error_unlock: mutex_unlock(&wusbhc->mutex); @@ -413,9 +405,6 @@ static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc, wusb_dev_put(wusb_dev); } port->wusb_dev = NULL; - /* don't reset the reset_count to zero or wusbhc_rh_port_reset will get - * confused! We only reset to zero when we connect a new device. - */ /* After a device disconnects, change the GTK (see [WUSB] * section 6.2.11.2). */ @@ -428,39 +417,6 @@ static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc, */ } -/* - * Authenticate a device into the WUSB Cluster - * - * Called from the Root Hub code (rh.c:wusbhc_rh_port_reset()) when - * asking for a reset on a port that is not enabled (ie: first connect - * on the port). - * - * Performs the 4way handshake to allow the device to comunicate w/ the - * WUSB Cluster securely; once done, issue a request to the device for - * it to change to address 0. - * - * This mimics the reset step of Wired USB that once resetting a - * device, leaves the port in enabled state and the dev with the - * default address (0). - * - * WUSB1.0[7.1.2] - * - * @port_idx: port where the change happened--This is the index into - * the wusbhc port array, not the USB port number. - */ -int wusbhc_devconnect_auth(struct wusbhc *wusbhc, u8 port_idx) -{ - struct device *dev = wusbhc->dev; - struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx); - - d_fnstart(3, dev, "(%p, %u)\n", wusbhc, port_idx); - port->status &= ~USB_PORT_STAT_RESET; - port->status |= USB_PORT_STAT_ENABLE; - port->change |= USB_PORT_STAT_C_RESET | USB_PORT_STAT_C_ENABLE; - d_fnend(3, dev, "(%p, %u) = 0\n", wusbhc, port_idx); - return 0; -} - /* * Refresh the list of keep alives to emit in the MMC * @@ -661,60 +617,6 @@ static void wusbhc_handle_dn_disconnect(struct wusbhc *wusbhc, struct wusb_dev * mutex_unlock(&wusbhc->mutex); } -/* - * Reset a WUSB device on a HWA - * - * @wusbhc - * @port_idx Index of the port where the device is - * - * In Wireless USB, a reset is more or less equivalent to a full - * disconnect; so we just do a full disconnect and send the device a - * Device Reset IE (WUSB1.0[7.5.11]) giving it a few millisecs (6 MMCs). - * - * @wusbhc should be refcounted and unlocked - */ -int wusbhc_dev_reset(struct wusbhc *wusbhc, u8 port_idx) -{ - int result; - struct device *dev = wusbhc->dev; - struct wusb_dev *wusb_dev; - struct wuie_reset *ie; - - d_fnstart(3, dev, "(%p, %u)\n", wusbhc, port_idx); - mutex_lock(&wusbhc->mutex); - result = 0; - wusb_dev = wusb_port_by_idx(wusbhc, port_idx)->wusb_dev; - if (wusb_dev == NULL) { - /* reset no device? ignore */ - dev_dbg(dev, "RESET: no device at port %u, ignoring\n", - port_idx); - goto error_unlock; - } - result = -ENOMEM; - ie = kzalloc(sizeof(*ie), GFP_KERNEL); - if (ie == NULL) - goto error_unlock; - ie->hdr.bLength = sizeof(ie->hdr) + sizeof(ie->CDID); - ie->hdr.bIEIdentifier = WUIE_ID_RESET_DEVICE; - ie->CDID = wusb_dev->cdid; - result = wusbhc_mmcie_set(wusbhc, 0xff, 6, &ie->hdr); - if (result < 0) { - dev_err(dev, "RESET: cant's set MMC: %d\n", result); - goto error_kfree; - } - __wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, port_idx)); - - /* 120ms, hopefully 6 MMCs (FIXME) */ - msleep(120); - wusbhc_mmcie_rm(wusbhc, &ie->hdr); -error_kfree: - kfree(ie); -error_unlock: - mutex_unlock(&wusbhc->mutex); - d_fnend(3, dev, "(%p, %u) = %d\n", wusbhc, port_idx, result); - return result; -} - /* * Handle a Device Notification coming a host * diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c index 267a6432510..1c733192ec2 100644 --- a/drivers/usb/wusbcore/rh.c +++ b/drivers/usb/wusbcore/rh.c @@ -77,13 +77,17 @@ /* * Reset a fake port * - * This can be called to reset a port from any other state or to reset - * it when connecting. In Wireless USB they are different; when doing - * a new connect that involves going over the authentication. When - * just reseting, its a different story. + * Using a Reset Device IE is too heavyweight as it causes the device + * to enter the UnConnected state and leave the cluster, this can mean + * that when the device reconnects it is connected to a different fake + * port. * - * The Linux USB stack resets a port twice before it considers it - * enabled, so we have to detect and ignore that. + * Instead, reset authenticated devices with a SetAddress(0), followed + * by a SetAddresss(AuthAddr). + * + * For unauthenticated devices just pretend to reset but do nothing. + * If the device initialization continues to fail it will eventually + * time out after TrustTimeout and enter the UnConnected state. * * @wusbhc is assumed referenced and @wusbhc->mutex unlocked. * @@ -97,20 +101,20 @@ static int wusbhc_rh_port_reset(struct wusbhc *wusbhc, u8 port_idx) { int result = 0; struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx); + struct wusb_dev *wusb_dev = port->wusb_dev; + + port->status |= USB_PORT_STAT_RESET; + port->change |= USB_PORT_STAT_C_RESET; - d_fnstart(3, wusbhc->dev, "(wusbhc %p port_idx %u)\n", - wusbhc, port_idx); - if (port->reset_count == 0) { - wusbhc_devconnect_auth(wusbhc, port_idx); - port->reset_count++; - } else if (port->reset_count == 1) - /* see header */ - d_printf(2, wusbhc->dev, "Ignoring second reset on port_idx " - "%u\n", port_idx); + if (wusb_dev->addr & WUSB_DEV_ADDR_UNAUTH) + result = 0; else - result = wusbhc_dev_reset(wusbhc, port_idx); - d_fnend(3, wusbhc->dev, "(wusbhc %p port_idx %u) = %d\n", - wusbhc, port_idx, result); + result = wusb_dev_update_address(wusbhc, wusb_dev); + + port->status &= ~USB_PORT_STAT_RESET; + port->status |= USB_PORT_STAT_ENABLE; + port->change |= USB_PORT_STAT_C_RESET | USB_PORT_STAT_C_ENABLE; + return result; } diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c index a101cad6a8d..ac00640bba6 100644 --- a/drivers/usb/wusbcore/security.c +++ b/drivers/usb/wusbcore/security.c @@ -338,8 +338,7 @@ static void hs_printk(unsigned level, struct device *dev, * Before the device's address (as known by it) was usb_dev->devnum | * 0x80 (unauthenticated address). With this we update it to usb_dev->devnum. */ -static int wusb_dev_update_address(struct wusbhc *wusbhc, - struct wusb_dev *wusb_dev) +int wusb_dev_update_address(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev) { int result = -ENOMEM; struct usb_device *usb_dev = wusb_dev->usb_dev; diff --git a/drivers/usb/wusbcore/wusbhc.h b/drivers/usb/wusbcore/wusbhc.h index b9bdf5a5f11..8fef934ad2f 100644 --- a/drivers/usb/wusbcore/wusbhc.h +++ b/drivers/usb/wusbcore/wusbhc.h @@ -154,7 +154,6 @@ struct wusb_port { u16 status; u16 change; struct wusb_dev *wusb_dev; /* connected device's info */ - unsigned reset_count; u32 ptk_tkid; }; @@ -387,10 +386,8 @@ extern void wusbhc_devconnect_destroy(struct wusbhc *); extern int wusbhc_devconnect_start(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid); extern void wusbhc_devconnect_stop(struct wusbhc *wusbhc); -extern int wusbhc_devconnect_auth(struct wusbhc *, u8); extern void wusbhc_handle_dn(struct wusbhc *, u8 srcaddr, struct wusb_dn_hdr *dn_hdr, size_t size); -extern int wusbhc_dev_reset(struct wusbhc *wusbhc, u8 port); extern void __wusbhc_dev_disable(struct wusbhc *wusbhc, u8 port); extern int wusb_usb_ncb(struct notifier_block *nb, unsigned long val, void *priv); @@ -436,6 +433,7 @@ extern void wusb_dev_sec_rm(struct wusb_dev *) ; extern int wusb_dev_4way_handshake(struct wusbhc *, struct wusb_dev *, struct wusb_ckhdid *ck); void wusbhc_gtk_rekey(struct wusbhc *wusbhc); +int wusb_dev_update_address(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev); /* WUSB Cluster ID handling */ -- cgit v1.2.3-18-g5258 From f88518d122f1b007f47a46aff37ca2885126a923 Mon Sep 17 00:00:00 2001 From: Huang Weiyi <weiyi.huang@gmail.com> Date: Fri, 31 Oct 2008 22:49:58 +0800 Subject: wusb: remove unused #include <version.h> 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 <version.h>. Signed-off-by: Huang Weiyi <weiyi.huang@gmail.com> Signed-off-by: David Vrabel <david.vrabel@csr.com> --- drivers/usb/host/hwa-hc.c | 1 - drivers/usb/host/whci/hcd.c | 1 - drivers/usb/host/whci/int.c | 1 - drivers/usb/host/whci/wusb.c | 1 - drivers/usb/wusbcore/cbaf.c | 1 - 5 files changed, 5 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c index 0e18989e165..2827353e97e 100644 --- a/drivers/usb/host/hwa-hc.c +++ b/drivers/usb/host/hwa-hc.c @@ -54,7 +54,6 @@ * DWA). */ #include <linux/kernel.h> -#include <linux/version.h> #include <linux/init.h> #include <linux/module.h> #include <linux/workqueue.h> 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 <http://www.gnu.org/licenses/>. */ -#include <linux/version.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/uwb/umc.h> diff --git a/drivers/usb/host/whci/int.c b/drivers/usb/host/whci/int.c index fce01174aa9..6aae7002810 100644 --- a/drivers/usb/host/whci/int.c +++ b/drivers/usb/host/whci/int.c @@ -15,7 +15,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <linux/version.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/uwb/umc.h> diff --git a/drivers/usb/host/whci/wusb.c b/drivers/usb/host/whci/wusb.c index 2befd475def..540021a0971 100644 --- a/drivers/usb/host/whci/wusb.c +++ b/drivers/usb/host/whci/wusb.c @@ -15,7 +15,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <linux/version.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/uwb/umc.h> diff --git a/drivers/usb/wusbcore/cbaf.c b/drivers/usb/wusbcore/cbaf.c index ab4788d1785..1335cbe1191 100644 --- a/drivers/usb/wusbcore/cbaf.c +++ b/drivers/usb/wusbcore/cbaf.c @@ -88,7 +88,6 @@ */ #include <linux/module.h> #include <linux/ctype.h> -#include <linux/version.h> #include <linux/usb.h> #include <linux/interrupt.h> #include <linux/delay.h> -- cgit v1.2.3-18-g5258 From 6fae35f9cea92793a98b2d9ab21235e5ae035581 Mon Sep 17 00:00:00 2001 From: David Vrabel <david.vrabel@csr.com> 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 <david.vrabel@csr.com> --- 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 ++--- 6 files changed, 33 insertions(+), 74 deletions(-) (limited to 'drivers/usb') 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); -- cgit v1.2.3-18-g5258 From 56968d0c1a920eb165c06318f5c458724e1df0af Mon Sep 17 00:00:00 2001 From: David Vrabel <david.vrabel@csr.com> Date: Tue, 25 Nov 2008 14:23:40 +0000 Subject: wusb: whci-hcd shouldn't do ASL/PZL updates while channel is inactive ASL/PZL updates while the WUSB channel is inactive (i.e., the PZL and ASL are stopped) may not complete. This causes hangs when removing the whci-hcd module if a device is still connected (removing the device does an endpoint_disable which results in an ASL update to remove the qset). If the WUSB channel is inactive the update can simply be skipped as the WHC doesn't care about the state of the ASL/PZL. Signed-off-by: David Vrabel <david.vrabel@csr.com> --- drivers/usb/host/whci/asl.c | 21 ++++++++++++++++++--- drivers/usb/host/whci/pzl.c | 21 ++++++++++++++++++--- drivers/usb/wusbcore/devconnect.c | 24 +++++++++--------------- drivers/usb/wusbcore/mmc.c | 37 +++++++++++++++++++++++++++---------- 4 files changed, 72 insertions(+), 31 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c index 4d7078e5057..ba99a7a3f81 100644 --- a/drivers/usb/host/whci/asl.c +++ b/drivers/usb/host/whci/asl.c @@ -179,11 +179,26 @@ void asl_stop(struct whc *whc) 1000, "stop ASL"); } +/** + * asl_update - request an ASL update and wait for the hardware to be synced + * @whc: the WHCI HC + * @wusbcmd: WUSBCMD value to start the update. + * + * If the WUSB HC is inactive (i.e., the ASL is stopped) then the + * update must be skipped as the hardware may not respond to update + * requests. + */ void asl_update(struct whc *whc, uint32_t wusbcmd) { - whc_write_wusbcmd(whc, wusbcmd, wusbcmd); - wait_event(whc->async_list_wq, - (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0); + struct wusbhc *wusbhc = &whc->wusbhc; + + mutex_lock(&wusbhc->mutex); + if (wusbhc->active) { + whc_write_wusbcmd(whc, wusbcmd, wusbcmd); + wait_event(whc->async_list_wq, + (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0); + } + mutex_unlock(&wusbhc->mutex); } /** diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c index 8d62df0c330..34d3a0aeab2 100644 --- a/drivers/usb/host/whci/pzl.c +++ b/drivers/usb/host/whci/pzl.c @@ -195,11 +195,26 @@ void pzl_stop(struct whc *whc) 1000, "stop PZL"); } +/** + * pzl_update - request a PZL update and wait for the hardware to be synced + * @whc: the WHCI HC + * @wusbcmd: WUSBCMD value to start the update. + * + * If the WUSB HC is inactive (i.e., the PZL is stopped) then the + * update must be skipped as the hardware may not respond to update + * requests. + */ void pzl_update(struct whc *whc, uint32_t wusbcmd) { - whc_write_wusbcmd(whc, wusbcmd, wusbcmd); - wait_event(whc->periodic_list_wq, - (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0); + struct wusbhc *wusbhc = &whc->wusbhc; + + mutex_lock(&wusbhc->mutex); + if (wusbhc->active) { + whc_write_wusbcmd(whc, wusbcmd, wusbcmd); + wait_event(whc->periodic_list_wq, + (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0); + } + mutex_unlock(&wusbhc->mutex); } static void update_pzl_hw_view(struct whc *whc) diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c index 08a1ec90386..26cbc89ea28 100644 --- a/drivers/usb/wusbcore/devconnect.c +++ b/drivers/usb/wusbcore/devconnect.c @@ -484,21 +484,15 @@ static void __wusbhc_keep_alive(struct wusbhc *wusbhc) */ static void wusbhc_keep_alive_run(struct work_struct *ws) { - struct delayed_work *dw = - container_of(ws, struct delayed_work, work); - struct wusbhc *wusbhc = - container_of(dw, struct wusbhc, keep_alive_timer); - - d_fnstart(5, wusbhc->dev, "(wusbhc %p)\n", wusbhc); - if (wusbhc->active) { - mutex_lock(&wusbhc->mutex); - __wusbhc_keep_alive(wusbhc); - mutex_unlock(&wusbhc->mutex); - queue_delayed_work(wusbd, &wusbhc->keep_alive_timer, - (wusbhc->trust_timeout * CONFIG_HZ)/1000/2); - } - d_fnend(5, wusbhc->dev, "(wusbhc %p) = void\n", wusbhc); - return; + struct delayed_work *dw = container_of(ws, struct delayed_work, work); + struct wusbhc *wusbhc = container_of(dw, struct wusbhc, keep_alive_timer); + + mutex_lock(&wusbhc->mutex); + __wusbhc_keep_alive(wusbhc); + mutex_unlock(&wusbhc->mutex); + + queue_delayed_work(wusbd, &wusbhc->keep_alive_timer, + msecs_to_jiffies(wusbhc->trust_timeout / 2)); } /* diff --git a/drivers/usb/wusbcore/mmc.c b/drivers/usb/wusbcore/mmc.c index 5463ecebafd..3b52161e6e9 100644 --- a/drivers/usb/wusbcore/mmc.c +++ b/drivers/usb/wusbcore/mmc.c @@ -159,6 +159,27 @@ found: } EXPORT_SYMBOL_GPL(wusbhc_mmcie_rm); +static int wusbhc_mmc_start(struct wusbhc *wusbhc) +{ + int ret; + + mutex_lock(&wusbhc->mutex); + ret = wusbhc->start(wusbhc); + if (ret >= 0) + wusbhc->active = 1; + mutex_unlock(&wusbhc->mutex); + + return ret; +} + +static void wusbhc_mmc_stop(struct wusbhc *wusbhc) +{ + mutex_lock(&wusbhc->mutex); + wusbhc->active = 0; + wusbhc->stop(wusbhc, WUSB_CHANNEL_STOP_DELAY_MS); + mutex_unlock(&wusbhc->mutex); +} + /* * wusbhc_start - start transmitting MMCs and accepting connections * @wusbhc: the HC to start @@ -198,12 +219,12 @@ int wusbhc_start(struct wusbhc *wusbhc) dev_err(dev, "Cannot set DNTS parameters: %d\n", result); goto error_set_num_dnts; } - result = wusbhc->start(wusbhc); + result = wusbhc_mmc_start(wusbhc); if (result < 0) { dev_err(dev, "error starting wusbch: %d\n", result); goto error_wusbhc_start; } - wusbhc->active = 1; + return 0; error_wusbhc_start: @@ -225,15 +246,11 @@ error_rsv_establish: */ void wusbhc_stop(struct wusbhc *wusbhc) { - if (wusbhc->active) { - wusbhc->active = 0; - wusbhc->stop(wusbhc, WUSB_CHANNEL_STOP_DELAY_MS); - wusbhc_sec_stop(wusbhc); - wusbhc_devconnect_stop(wusbhc); - wusbhc_rsv_terminate(wusbhc); - } + wusbhc_mmc_stop(wusbhc); + wusbhc_sec_stop(wusbhc); + wusbhc_devconnect_stop(wusbhc); + wusbhc_rsv_terminate(wusbhc); } -EXPORT_SYMBOL_GPL(wusbhc_stop); /* * Set/reset/update a new CHID -- cgit v1.2.3-18-g5258 From dcc7461eef7341e84e2f7274f904ce01a43b2506 Mon Sep 17 00:00:00 2001 From: David Vrabel <david.vrabel@csr.com> 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 <david.vrabel@csr.com> --- 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 ------ 8 files changed, 201 insertions(+), 121 deletions(-) create mode 100644 drivers/usb/host/whci/debug.c (limited to 'drivers/usb') 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 <linux/dma-mapping.h> #include <linux/uwb/umc.h> #include <linux/usb.h> -#define D_LOCAL 0 -#include <linux/uwb/debug.h> #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 <http://www.gnu.org/licenses/>. + */ +#include <linux/kernel.h> +#include <linux/debugfs.h> +#include <linux/seq_file.h> + +#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 <linux/dma-mapping.h> #include <linux/uwb/umc.h> #include <linux/usb.h> -#define D_LOCAL 0 -#include <linux/uwb/debug.h> #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 <linux/uwb/whci.h> +#include <linux/uwb/umc.h> #include <linux/workqueue.h> #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 <linux/kernel.h> #include <linux/init.h> #include <linux/uwb/umc.h> -#define D_LOCAL 1 -#include <linux/uwb/debug.h> #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, -- cgit v1.2.3-18-g5258 From 5b37717a23b8e40f6cf7ad85a26ddcf41c171e2c Mon Sep 17 00:00:00 2001 From: Stefano Panella <stefano.panella@csr.com> Date: Fri, 12 Dec 2008 13:00:06 +0000 Subject: uwb: improved MAS allocator and reservation conflict handling Greatly enhance the MAS allocator: - Handle row and column reservations. - Permit all the available MAS to be allocated. - Follows the WiMedia rules on MAS selection. Take appropriate action when reservation conflicts are detected. - Correctly identify which reservation wins the conflict. - Protect alien BP reservations. - If an owned reservation loses, resize/move it. - Follow the backoff procedure before requesting additional MAS. When reservations are terminated, move the remaining reservations (if necessary) so they keep following the MAS allocation rules. Signed-off-by: Stefano Panella <stefano.panella@csr.com> Signed-off-by: David Vrabel <david.vrabel@csr.com> --- drivers/usb/wusbcore/reservation.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/wusbcore/reservation.c b/drivers/usb/wusbcore/reservation.c index 7b6525dac2f..c37e4f83e54 100644 --- a/drivers/usb/wusbcore/reservation.c +++ b/drivers/usb/wusbcore/reservation.c @@ -48,13 +48,15 @@ static void wusbhc_rsv_complete_cb(struct uwb_rsv *rsv) { struct wusbhc *wusbhc = rsv->pal_priv; struct device *dev = wusbhc->dev; + struct uwb_mas_bm mas; char buf[72]; switch (rsv->state) { case UWB_RSV_STATE_O_ESTABLISHED: - bitmap_scnprintf(buf, sizeof(buf), rsv->mas.bm, UWB_NUM_MAS); + uwb_rsv_get_usable_mas(rsv, &mas); + bitmap_scnprintf(buf, sizeof(buf), mas.bm, UWB_NUM_MAS); dev_dbg(dev, "established reservation: %s\n", buf); - wusbhc_bwa_set(wusbhc, rsv->stream, &rsv->mas); + wusbhc_bwa_set(wusbhc, rsv->stream, &mas); break; case UWB_RSV_STATE_NONE: dev_dbg(dev, "removed reservation\n"); @@ -85,13 +87,12 @@ int wusbhc_rsv_establish(struct wusbhc *wusbhc) bcid.data[0] = wusbhc->cluster_id; bcid.data[1] = 0; - rsv->owner = &rc->uwb_dev; rsv->target.type = UWB_RSV_TARGET_DEVADDR; rsv->target.devaddr = bcid; rsv->type = UWB_DRP_TYPE_PRIVATE; - rsv->max_mas = 256; - rsv->min_mas = 16; /* one MAS per zone? */ - rsv->sparsity = 16; /* at least one MAS in each zone? */ + rsv->max_mas = 256; /* try to get as much as possible */ + rsv->min_mas = 15; /* one MAS per zone */ + rsv->max_interval = 1; /* max latency is one zone */ rsv->is_multicast = true; ret = uwb_rsv_establish(rsv); -- cgit v1.2.3-18-g5258 From fe6e87a4b570d2e435709746ba550a7197016bd0 Mon Sep 17 00:00:00 2001 From: David Vrabel <david.vrabel@csr.com> Date: Fri, 12 Dec 2008 13:25:21 +0000 Subject: wusb: fix oops when terminating a non-existant reservation If a reservation was not established, do not try terminating it. Signed-off-by: David Vrabel <david.vrabel@csr.com> --- drivers/usb/wusbcore/reservation.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/wusbcore/reservation.c b/drivers/usb/wusbcore/reservation.c index c37e4f83e54..4ed97360c04 100644 --- a/drivers/usb/wusbcore/reservation.c +++ b/drivers/usb/wusbcore/reservation.c @@ -110,6 +110,9 @@ int wusbhc_rsv_establish(struct wusbhc *wusbhc) */ void wusbhc_rsv_terminate(struct wusbhc *wusbhc) { - uwb_rsv_terminate(wusbhc->rsv); - uwb_rsv_destroy(wusbhc->rsv); + if (wusbhc->rsv) { + uwb_rsv_terminate(wusbhc->rsv); + uwb_rsv_destroy(wusbhc->rsv); + wusbhc->rsv = NULL; + } } -- cgit v1.2.3-18-g5258 From bce83697c5fe84a7a5d38c96fbbe43b4bc028c3e Mon Sep 17 00:00:00 2001 From: David Vrabel <david.vrabel@csr.com> Date: Mon, 22 Dec 2008 18:22:50 +0000 Subject: uwb: use dev_dbg() for debug messages Instead of the home-grown d_fnstart(), d_fnend() and d_printf() macros, use dev_dbg() or remove the message entirely. Signed-off-by: David Vrabel <david.vrabel@csr.com> --- drivers/usb/host/hwa-hc.c | 55 ++---------- drivers/usb/wusbcore/crypto.c | 30 ------- drivers/usb/wusbcore/dev-sysfs.c | 4 - drivers/usb/wusbcore/devconnect.c | 104 ++++------------------ drivers/usb/wusbcore/rh.c | 64 ++++---------- drivers/usb/wusbcore/security.c | 75 ++-------------- drivers/usb/wusbcore/wa-rpipe.c | 68 ++++---------- drivers/usb/wusbcore/wa-xfer.c | 180 +++++++++----------------------------- 8 files changed, 103 insertions(+), 477 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c index 2a4d36fa70b..8582236e4ca 100644 --- a/drivers/usb/host/hwa-hc.c +++ b/drivers/usb/host/hwa-hc.c @@ -62,16 +62,12 @@ #include "../wusbcore/wa-hc.h" #include "../wusbcore/wusbhc.h" -#define D_LOCAL 0 -#include <linux/uwb/debug.h> - struct hwahc { struct wusbhc wusbhc; /* has to be 1st */ struct wahc wa; - u8 buffer[16]; /* for misc usb transactions */ }; -/** +/* * FIXME should be wusbhc * * NOTE: we need to cache the Cluster ID because later...there is no @@ -125,7 +121,6 @@ static int hwahc_op_reset(struct usb_hcd *usb_hcd) struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc); struct device *dev = &hwahc->wa.usb_iface->dev; - d_fnstart(4, dev, "(hwahc %p)\n", hwahc); mutex_lock(&wusbhc->mutex); wa_nep_disarm(&hwahc->wa); result = __wa_set_feature(&hwahc->wa, WA_RESET); @@ -133,7 +128,6 @@ static int hwahc_op_reset(struct usb_hcd *usb_hcd) dev_err(dev, "error commanding HC to reset: %d\n", result); goto error_unlock; } - d_printf(3, dev, "reset: waiting for device to change state\n"); result = __wa_wait_status(&hwahc->wa, WA_STATUS_RESETTING, 0); if (result < 0) { dev_err(dev, "error waiting for HC to reset: %d\n", result); @@ -141,7 +135,6 @@ static int hwahc_op_reset(struct usb_hcd *usb_hcd) } error_unlock: mutex_unlock(&wusbhc->mutex); - d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result); return result; } @@ -154,15 +147,9 @@ static int hwahc_op_start(struct usb_hcd *usb_hcd) int result; struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc); - struct device *dev = &hwahc->wa.usb_iface->dev; - /* Set up a Host Info WUSB Information Element */ - d_fnstart(4, dev, "(hwahc %p)\n", hwahc); result = -ENOSPC; mutex_lock(&wusbhc->mutex); - /* Start the numbering from the top so that the bottom - * range of the unauth addr space is used for devices, - * the top for HCs; use 0xfe - RC# */ addr = wusb_cluster_id_get(); if (addr == 0) goto error_cluster_id_get; @@ -176,7 +163,6 @@ static int hwahc_op_start(struct usb_hcd *usb_hcd) result = 0; out: mutex_unlock(&wusbhc->mutex); - d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result); return result; error_set_cluster_id: @@ -213,18 +199,11 @@ static int hwahc_op_resume(struct usb_hcd *usb_hcd) */ static void hwahc_op_stop(struct usb_hcd *usb_hcd) { - int result; struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); - struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc); - struct wahc *wa = &hwahc->wa; - struct device *dev = &wa->usb_iface->dev; - d_fnstart(4, dev, "(hwahc %p)\n", hwahc); mutex_lock(&wusbhc->mutex); wusb_cluster_id_put(wusbhc->cluster_id); mutex_unlock(&wusbhc->mutex); - d