aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-02-02 22:20:17 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-02-02 22:20:17 -0500
commit17294ab2ca8e8c46f2e4825c55541b2b88e52bf4 (patch)
treec44fd3cf1c20c5724e719a3339a5734f2eae7e58 /drivers
parent86adf8adfcb3d3f4b6c30aeb40da480da02de1d1 (diff)
parent8f04915532485d81e7f6c580a396ea7b01094221 (diff)
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/dvrabel/uwb
* 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/dvrabel/uwb: uwb: lock rc->rsvs_lock with spin_lock_bh() wusb: timeout when waiting for ASL/PZL updates in whci-hcd uwb: remove unused #include <version.h>'s wusb: return -ENOTCONN when resetting a port with no connected device uwb: safely remove all reservations
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/host/whci/asl.c9
-rw-r--r--drivers/usb/host/whci/hw.c15
-rw-r--r--drivers/usb/host/whci/pzl.c9
-rw-r--r--drivers/usb/host/whci/whcd.h1
-rw-r--r--drivers/usb/wusbcore/devconnect.c1
-rw-r--r--drivers/usb/wusbcore/rh.c3
-rw-r--r--drivers/uwb/allocator.c1
-rw-r--r--drivers/uwb/drp.c4
-rw-r--r--drivers/uwb/rsv.c21
9 files changed, 51 insertions, 13 deletions
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c
index 577c0d29849d..2291c5f5af51 100644
--- a/drivers/usb/host/whci/asl.c
+++ b/drivers/usb/host/whci/asl.c
@@ -170,12 +170,17 @@ void asl_stop(struct whc *whc)
170void asl_update(struct whc *whc, uint32_t wusbcmd) 170void asl_update(struct whc *whc, uint32_t wusbcmd)
171{ 171{
172 struct wusbhc *wusbhc = &whc->wusbhc; 172 struct wusbhc *wusbhc = &whc->wusbhc;
173 long t;
173 174
174 mutex_lock(&wusbhc->mutex); 175 mutex_lock(&wusbhc->mutex);
175 if (wusbhc->active) { 176 if (wusbhc->active) {
176 whc_write_wusbcmd(whc, wusbcmd, wusbcmd); 177 whc_write_wusbcmd(whc, wusbcmd, wusbcmd);
177 wait_event(whc->async_list_wq, 178 t = wait_event_timeout(
178 (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0); 179 whc->async_list_wq,
180 (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0,
181 msecs_to_jiffies(1000));
182 if (t == 0)
183 whc_hw_error(whc, "ASL update timeout");
179 } 184 }
180 mutex_unlock(&wusbhc->mutex); 185 mutex_unlock(&wusbhc->mutex);
181} 186}
diff --git a/drivers/usb/host/whci/hw.c b/drivers/usb/host/whci/hw.c
index d498e7203217..6afa2e379160 100644
--- a/drivers/usb/host/whci/hw.c
+++ b/drivers/usb/host/whci/hw.c
@@ -87,3 +87,18 @@ out:
87 87
88 return ret; 88 return ret;
89} 89}
90
91/**
92 * whc_hw_error - recover from a hardware error
93 * @whc: the WHCI HC that broke.
94 * @reason: a description of the failure.
95 *
96 * Recover from broken hardware with a full reset.
97 */
98void whc_hw_error(struct whc *whc, const char *reason)
99{
100 struct wusbhc *wusbhc = &whc->wusbhc;
101
102 dev_err(&whc->umc->dev, "hardware error: %s\n", reason);
103 wusbhc_reset_all(wusbhc);
104}
diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c
index 2ae5abf69a6a..7dc85a0bee7c 100644
--- a/drivers/usb/host/whci/pzl.c
+++ b/drivers/usb/host/whci/pzl.c
@@ -183,12 +183,17 @@ void pzl_stop(struct whc *whc)
183void pzl_update(struct whc *whc, uint32_t wusbcmd) 183void pzl_update(struct whc *whc, uint32_t wusbcmd)
184{ 184{
185 struct wusbhc *wusbhc = &whc->wusbhc; 185 struct wusbhc *wusbhc = &whc->wusbhc;
186 long t;
186 187
187 mutex_lock(&wusbhc->mutex); 188 mutex_lock(&wusbhc->mutex);
188 if (wusbhc->active) { 189 if (wusbhc->active) {
189 whc_write_wusbcmd(whc, wusbcmd, wusbcmd); 190 whc_write_wusbcmd(whc, wusbcmd, wusbcmd);
190 wait_event(whc->periodic_list_wq, 191 t = wait_event_timeout(
191 (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0); 192 whc->periodic_list_wq,
193 (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0,
194 msecs_to_jiffies(1000));
195 if (t == 0)
196 whc_hw_error(whc, "PZL update timeout");
192 } 197 }
193 mutex_unlock(&wusbhc->mutex); 198 mutex_unlock(&wusbhc->mutex);
194} 199}
diff --git a/drivers/usb/host/whci/whcd.h b/drivers/usb/host/whci/whcd.h
index 0f3540f04f53..d3543a181dc9 100644
--- a/drivers/usb/host/whci/whcd.h
+++ b/drivers/usb/host/whci/whcd.h
@@ -137,6 +137,7 @@ void whc_clean_up(struct whc *whc);
137/* hw.c */ 137/* hw.c */
138void whc_write_wusbcmd(struct whc *whc, u32 mask, u32 val); 138void whc_write_wusbcmd(struct whc *whc, u32 mask, u32 val);
139int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len); 139int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len);
140void whc_hw_error(struct whc *whc, const char *reason);
140 141
141/* wusb.c */ 142/* wusb.c */
142int whc_wusbhc_start(struct wusbhc *wusbhc); 143int whc_wusbhc_start(struct wusbhc *wusbhc);
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c
index e2e7e4bc8463..8e18141bb2e0 100644
--- a/drivers/usb/wusbcore/devconnect.c
+++ b/drivers/usb/wusbcore/devconnect.c
@@ -386,6 +386,7 @@ static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc,
386 | USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED); 386 | USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED);
387 port->change |= USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE; 387 port->change |= USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE;
388 if (wusb_dev) { 388 if (wusb_dev) {
389 dev_dbg(wusbhc->dev, "disconnecting device from port %d\n", wusb_dev->port_idx);
389 if (!list_empty(&wusb_dev->cack_node)) 390 if (!list_empty(&wusb_dev->cack_node))
390 list_del_init(&wusb_dev->cack_node); 391 list_del_init(&wusb_dev->cack_node);
391 /* For the one in cack_add() */ 392 /* For the one in cack_add() */
diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c
index 3937bf6f8cef..9fe4246cecb9 100644
--- a/drivers/usb/wusbcore/rh.c
+++ b/drivers/usb/wusbcore/rh.c
@@ -100,6 +100,9 @@ static int wusbhc_rh_port_reset(struct wusbhc *wusbhc, u8 port_idx)
100 struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx); 100 struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx);
101 struct wusb_dev *wusb_dev = port->wusb_dev; 101 struct wusb_dev *wusb_dev = port->wusb_dev;
102 102
103 if (wusb_dev == NULL)
104 return -ENOTCONN;
105
103 port->status |= USB_PORT_STAT_RESET; 106 port->status |= USB_PORT_STAT_RESET;
104 port->change |= USB_PORT_STAT_C_RESET; 107 port->change |= USB_PORT_STAT_C_RESET;
105 108
diff --git a/drivers/uwb/allocator.c b/drivers/uwb/allocator.c
index c8185e6b0cd5..c13cec7dcbc5 100644
--- a/drivers/uwb/allocator.c
+++ b/drivers/uwb/allocator.c
@@ -15,7 +15,6 @@
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18#include <linux/version.h>
19#include <linux/kernel.h> 18#include <linux/kernel.h>
20#include <linux/uwb.h> 19#include <linux/uwb.h>
21 20
diff --git a/drivers/uwb/drp.c b/drivers/uwb/drp.c
index 2b4f9406789d..4f5ca99a04b9 100644
--- a/drivers/uwb/drp.c
+++ b/drivers/uwb/drp.c
@@ -66,14 +66,14 @@ static void uwb_rc_set_drp_cmd_done(struct uwb_rc *rc, void *arg,
66 } else 66 } else
67 dev_err(&rc->uwb_dev.dev, "SET-DRP-IE: timeout\n"); 67 dev_err(&rc->uwb_dev.dev, "SET-DRP-IE: timeout\n");
68 68
69 spin_lock(&rc->rsvs_lock); 69 spin_lock_bh(&rc->rsvs_lock);
70 if (rc->set_drp_ie_pending > 1) { 70 if (rc->set_drp_ie_pending > 1) {
71 rc->set_drp_ie_pending = 0; 71 rc->set_drp_ie_pending = 0;
72 uwb_rsv_queue_update(rc); 72 uwb_rsv_queue_update(rc);
73 } else { 73 } else {
74 rc->set_drp_ie_pending = 0; 74 rc->set_drp_ie_pending = 0;
75 } 75 }
76 spin_unlock(&rc->rsvs_lock); 76 spin_unlock_bh(&rc->rsvs_lock);
77} 77}
78 78
79/** 79/**
diff --git a/drivers/uwb/rsv.c b/drivers/uwb/rsv.c
index ec6eecb32f30..6b76f4bb4cc7 100644
--- a/drivers/uwb/rsv.c
+++ b/drivers/uwb/rsv.c
@@ -114,7 +114,8 @@ void uwb_rsv_dump(char *text, struct uwb_rsv *rsv)
114 devaddr = rsv->target.devaddr; 114 devaddr = rsv->target.devaddr;
115 uwb_dev_addr_print(target, sizeof(target), &devaddr); 115 uwb_dev_addr_print(target, sizeof(target), &devaddr);
116 116
117 dev_dbg(dev, "rsv %s -> %s: %s\n", owner, target, uwb_rsv_state_str(rsv->state)); 117 dev_dbg(dev, "rsv %s %s -> %s: %s\n",
118 text, owner, target, uwb_rsv_state_str(rsv->state));
118} 119}
119 120
120static void uwb_rsv_release(struct kref *kref) 121static void uwb_rsv_release(struct kref *kref)
@@ -511,8 +512,7 @@ void uwb_rsv_remove(struct uwb_rsv *rsv)
511 512
512 if (uwb_rsv_is_owner(rsv)) 513 if (uwb_rsv_is_owner(rsv))
513 uwb_rsv_put_stream(rsv); 514 uwb_rsv_put_stream(rsv);
514 515
515 del_timer_sync(&rsv->timer);
516 uwb_dev_put(rsv->owner); 516 uwb_dev_put(rsv->owner);
517 if (rsv->target.type == UWB_RSV_TARGET_DEV) 517 if (rsv->target.type == UWB_RSV_TARGET_DEV)
518 uwb_dev_put(rsv->target.dev); 518 uwb_dev_put(rsv->target.dev);
@@ -870,7 +870,7 @@ void uwb_rsv_queue_update(struct uwb_rc *rc)
870 */ 870 */
871void uwb_rsv_sched_update(struct uwb_rc *rc) 871void uwb_rsv_sched_update(struct uwb_rc *rc)
872{ 872{
873 spin_lock(&rc->rsvs_lock); 873 spin_lock_bh(&rc->rsvs_lock);
874 if (!delayed_work_pending(&rc->rsv_update_work)) { 874 if (!delayed_work_pending(&rc->rsv_update_work)) {
875 if (rc->set_drp_ie_pending > 0) { 875 if (rc->set_drp_ie_pending > 0) {
876 rc->set_drp_ie_pending++; 876 rc->set_drp_ie_pending++;
@@ -879,7 +879,7 @@ void uwb_rsv_sched_update(struct uwb_rc *rc)
879 uwb_rsv_queue_update(rc); 879 uwb_rsv_queue_update(rc);
880 } 880 }
881unlock: 881unlock:
882 spin_unlock(&rc->rsvs_lock); 882 spin_unlock_bh(&rc->rsvs_lock);
883} 883}
884 884
885/* 885/*
@@ -943,13 +943,22 @@ void uwb_rsv_remove_all(struct uwb_rc *rc)
943 943
944 mutex_lock(&rc->rsvs_mutex); 944 mutex_lock(&rc->rsvs_mutex);
945 list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) { 945 list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) {
946 uwb_rsv_remove(rsv); 946 if (rsv->state != UWB_RSV_STATE_NONE)
947 uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE);
948 del_timer_sync(&rsv->timer);
947 } 949 }
948 /* Cancel any postponed update. */ 950 /* Cancel any postponed update. */
949 rc->set_drp_ie_pending = 0; 951 rc->set_drp_ie_pending = 0;
950 mutex_unlock(&rc->rsvs_mutex); 952 mutex_unlock(&rc->rsvs_mutex);
951 953
952 cancel_delayed_work_sync(&rc->rsv_update_work); 954 cancel_delayed_work_sync(&rc->rsv_update_work);
955 flush_workqueue(rc->rsv_workq);
956
957 mutex_lock(&rc->rsvs_mutex);
958 list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) {
959 uwb_rsv_remove(rsv);
960 }
961 mutex_unlock(&rc->rsvs_mutex);
953} 962}
954 963
955void uwb_rsv_init(struct uwb_rc *rc) 964void uwb_rsv_init(struct uwb_rc *rc)