diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2008-11-09 17:40:46 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-11-21 11:08:16 -0500 |
commit | 8ff48a8bbe4a1ba29dea2836dfce74660f97c1be (patch) | |
tree | 611c0e996813c59c229694b52d329c24829b80e8 /drivers/net/wireless/rt2x00/rt2x00usb.c | |
parent | bad13639a30e1557fbe9d440adc1906673c9de4e (diff) |
rt2x00: Fix race condition when using inderect registers
Indirect registers require multiple calls to the CSR
register in order to access the indirect registers.
This must be protected under a lock to prevent race
conditions which could cause invalid data to
be returned when reading from the indirect register or silent
failures when writing data to the indirect register.
USB drivers where already protected under a mutex,
so rename the mutex and make PCI drivers use the mutex
as well.
This now means that BBP and RF registers are no longer
accessible in interrupt context. That is not a bad
situation since the slow behavior of accessing
those registers means we don't _want_ to access them
in interrupt context either.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00usb.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00usb.c | 11 |
1 files changed, 5 insertions, 6 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 4eb550fab2f6..c507b0d9409f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -79,7 +79,7 @@ int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev, | |||
79 | { | 79 | { |
80 | int status; | 80 | int status; |
81 | 81 | ||
82 | BUG_ON(!mutex_is_locked(&rt2x00dev->usb_cache_mutex)); | 82 | BUG_ON(!mutex_is_locked(&rt2x00dev->csr_mutex)); |
83 | 83 | ||
84 | /* | 84 | /* |
85 | * Check for Cache availability. | 85 | * Check for Cache availability. |
@@ -110,13 +110,13 @@ int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev, | |||
110 | { | 110 | { |
111 | int status; | 111 | int status; |
112 | 112 | ||
113 | mutex_lock(&rt2x00dev->usb_cache_mutex); | 113 | mutex_lock(&rt2x00dev->csr_mutex); |
114 | 114 | ||
115 | status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request, | 115 | status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request, |
116 | requesttype, offset, buffer, | 116 | requesttype, offset, buffer, |
117 | buffer_length, timeout); | 117 | buffer_length, timeout); |
118 | 118 | ||
119 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | 119 | mutex_unlock(&rt2x00dev->csr_mutex); |
120 | 120 | ||
121 | return status; | 121 | return status; |
122 | } | 122 | } |
@@ -132,7 +132,7 @@ int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev, | |||
132 | unsigned char *tb; | 132 | unsigned char *tb; |
133 | u16 off, len, bsize; | 133 | u16 off, len, bsize; |
134 | 134 | ||
135 | mutex_lock(&rt2x00dev->usb_cache_mutex); | 135 | mutex_lock(&rt2x00dev->csr_mutex); |
136 | 136 | ||
137 | tb = (char *)buffer; | 137 | tb = (char *)buffer; |
138 | off = offset; | 138 | off = offset; |
@@ -148,7 +148,7 @@ int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev, | |||
148 | off += bsize; | 148 | off += bsize; |
149 | } | 149 | } |
150 | 150 | ||
151 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | 151 | mutex_unlock(&rt2x00dev->csr_mutex); |
152 | 152 | ||
153 | return status; | 153 | return status; |
154 | } | 154 | } |
@@ -531,7 +531,6 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, | |||
531 | rt2x00dev->dev = &usb_intf->dev; | 531 | rt2x00dev->dev = &usb_intf->dev; |
532 | rt2x00dev->ops = ops; | 532 | rt2x00dev->ops = ops; |
533 | rt2x00dev->hw = hw; | 533 | rt2x00dev->hw = hw; |
534 | mutex_init(&rt2x00dev->usb_cache_mutex); | ||
535 | 534 | ||
536 | rt2x00dev->usb_maxpacket = | 535 | rt2x00dev->usb_maxpacket = |
537 | usb_maxpacket(usb_dev, usb_sndbulkpipe(usb_dev, 1), 1); | 536 | usb_maxpacket(usb_dev, usb_sndbulkpipe(usb_dev, 1), 1); |