From 67c7d2657d3741989e04063172496e023b65c83e Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Wed, 7 Jan 2009 10:54:22 +0000 Subject: [PATCH] --- yaml --- r: 130711 b: refs/heads/master c: a5e6ced58d423cb09c4fc0087dcfdb0b5deb5e1c h: refs/heads/master i: 130709: 7d43b66292a17243a61126952753c6de8816cd73 130707: 50615015bce4dce29cd74b4217f5039b63bf2fa6 130703: 9e8f25eb847722299a67d3613f1570dff8857edf v: v3 --- [refs] | 2 +- trunk/drivers/usb/host/whci/asl.c | 9 +++++++-- trunk/drivers/usb/host/whci/hw.c | 15 +++++++++++++++ trunk/drivers/usb/host/whci/pzl.c | 9 +++++++-- trunk/drivers/usb/host/whci/whcd.h | 1 + 5 files changed, 31 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index ca7d80b56724..3cf2d8f542f9 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: a23e66f3b8cfdedec14541e71ef29a754870a20c +refs/heads/master: a5e6ced58d423cb09c4fc0087dcfdb0b5deb5e1c diff --git a/trunk/drivers/usb/host/whci/asl.c b/trunk/drivers/usb/host/whci/asl.c index 577c0d29849d..2291c5f5af51 100644 --- a/trunk/drivers/usb/host/whci/asl.c +++ b/trunk/drivers/usb/host/whci/asl.c @@ -170,12 +170,17 @@ void asl_stop(struct whc *whc) void asl_update(struct whc *whc, uint32_t wusbcmd) { struct wusbhc *wusbhc = &whc->wusbhc; + long t; 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); + t = wait_event_timeout( + whc->async_list_wq, + (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0, + msecs_to_jiffies(1000)); + if (t == 0) + whc_hw_error(whc, "ASL update timeout"); } mutex_unlock(&wusbhc->mutex); } diff --git a/trunk/drivers/usb/host/whci/hw.c b/trunk/drivers/usb/host/whci/hw.c index d498e7203217..6afa2e379160 100644 --- a/trunk/drivers/usb/host/whci/hw.c +++ b/trunk/drivers/usb/host/whci/hw.c @@ -87,3 +87,18 @@ int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len) return ret; } + +/** + * whc_hw_error - recover from a hardware error + * @whc: the WHCI HC that broke. + * @reason: a description of the failure. + * + * Recover from broken hardware with a full reset. + */ +void whc_hw_error(struct whc *whc, const char *reason) +{ + struct wusbhc *wusbhc = &whc->wusbhc; + + dev_err(&whc->umc->dev, "hardware error: %s\n", reason); + wusbhc_reset_all(wusbhc); +} diff --git a/trunk/drivers/usb/host/whci/pzl.c b/trunk/drivers/usb/host/whci/pzl.c index 2ae5abf69a6a..7dc85a0bee7c 100644 --- a/trunk/drivers/usb/host/whci/pzl.c +++ b/trunk/drivers/usb/host/whci/pzl.c @@ -183,12 +183,17 @@ void pzl_stop(struct whc *whc) void pzl_update(struct whc *whc, uint32_t wusbcmd) { struct wusbhc *wusbhc = &whc->wusbhc; + long t; 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); + t = wait_event_timeout( + whc->periodic_list_wq, + (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0, + msecs_to_jiffies(1000)); + if (t == 0) + whc_hw_error(whc, "PZL update timeout"); } mutex_unlock(&wusbhc->mutex); } diff --git a/trunk/drivers/usb/host/whci/whcd.h b/trunk/drivers/usb/host/whci/whcd.h index 0f3540f04f53..d3543a181dc9 100644 --- a/trunk/drivers/usb/host/whci/whcd.h +++ b/trunk/drivers/usb/host/whci/whcd.h @@ -137,6 +137,7 @@ void whc_clean_up(struct whc *whc); /* hw.c */ void whc_write_wusbcmd(struct whc *whc, u32 mask, u32 val); int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len); +void whc_hw_error(struct whc *whc, const char *reason); /* wusb.c */ int whc_wusbhc_start(struct wusbhc *wusbhc);