mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-18 01:34:14 +08:00
rt2x00: Fix unbalanced mutex locking
The usb_cache_mutex was not correctly released under all circumstances. Both rt73usb as rt2500usb didn't release the mutex under certain conditions when the register access failed. Obviously such failure would lead to deadlocks. In addition under similar circumstances when the bbp register couldn't be read the value must be set to 0xff to indicate that the value is wrong. This too didn't happen under all circumstances. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
2f9ec47d09
commit
99ade2597e
@ -138,11 +138,8 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
|
||||
* Wait until the BBP becomes ready.
|
||||
*/
|
||||
reg = rt2500usb_bbp_check(rt2x00dev);
|
||||
if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) {
|
||||
ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n");
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
return;
|
||||
}
|
||||
if (rt2x00_get_field16(reg, PHY_CSR8_BUSY))
|
||||
goto exit_fail;
|
||||
|
||||
/*
|
||||
* Write the data into the BBP.
|
||||
@ -155,6 +152,13 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
|
||||
rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg);
|
||||
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
|
||||
return;
|
||||
|
||||
exit_fail:
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
|
||||
ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n");
|
||||
}
|
||||
|
||||
static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||
@ -168,10 +172,8 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||
* Wait until the BBP becomes ready.
|
||||
*/
|
||||
reg = rt2500usb_bbp_check(rt2x00dev);
|
||||
if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) {
|
||||
ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n");
|
||||
return;
|
||||
}
|
||||
if (rt2x00_get_field16(reg, PHY_CSR8_BUSY))
|
||||
goto exit_fail;
|
||||
|
||||
/*
|
||||
* Write the request into the BBP.
|
||||
@ -186,17 +188,21 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||
* Wait until the BBP becomes ready.
|
||||
*/
|
||||
reg = rt2500usb_bbp_check(rt2x00dev);
|
||||
if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) {
|
||||
ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n");
|
||||
*value = 0xff;
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
return;
|
||||
}
|
||||
if (rt2x00_get_field16(reg, PHY_CSR8_BUSY))
|
||||
goto exit_fail;
|
||||
|
||||
rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, ®);
|
||||
*value = rt2x00_get_field16(reg, PHY_CSR7_DATA);
|
||||
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
|
||||
return;
|
||||
|
||||
exit_fail:
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
|
||||
ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n");
|
||||
*value = 0xff;
|
||||
}
|
||||
|
||||
static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||
|
@ -134,11 +134,8 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev,
|
||||
* Wait until the BBP becomes ready.
|
||||
*/
|
||||
reg = rt73usb_bbp_check(rt2x00dev);
|
||||
if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
|
||||
ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
return;
|
||||
}
|
||||
if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
|
||||
goto exit_fail;
|
||||
|
||||
/*
|
||||
* Write the data into the BBP.
|
||||
@ -151,6 +148,13 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev,
|
||||
|
||||
rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg);
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
|
||||
return;
|
||||
|
||||
exit_fail:
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
|
||||
ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
|
||||
}
|
||||
|
||||
static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||
@ -164,11 +168,8 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||
* Wait until the BBP becomes ready.
|
||||
*/
|
||||
reg = rt73usb_bbp_check(rt2x00dev);
|
||||
if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
|
||||
ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
return;
|
||||
}
|
||||
if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
|
||||
goto exit_fail;
|
||||
|
||||
/*
|
||||
* Write the request into the BBP.
|
||||
@ -184,14 +185,19 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||
* Wait until the BBP becomes ready.
|
||||
*/
|
||||
reg = rt73usb_bbp_check(rt2x00dev);
|
||||
if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
|
||||
ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
|
||||
*value = 0xff;
|
||||
return;
|
||||
}
|
||||
if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
|
||||
goto exit_fail;
|
||||
|
||||
*value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
|
||||
return;
|
||||
|
||||
exit_fail:
|
||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
||||
|
||||
ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
|
||||
*value = 0xff;
|
||||
}
|
||||
|
||||
static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||
|
Loading…
Reference in New Issue
Block a user