Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 122027
b: refs/heads/master
c: 8ff48a8
h: refs/heads/master
i:
  122025: d6d3277
  122023: dea23db
v: v3
  • Loading branch information
Ivo van Doorn authored and John W. Linville committed Nov 21, 2008
1 parent 7df7778 commit 69bc21e
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 82 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bad13639a30e1557fbe9d440adc1906673c9de4e
refs/heads/master: 8ff48a8bbe4a1ba29dea2836dfce74660f97c1be
47 changes: 34 additions & 13 deletions trunk/drivers/net/wireless/rt2x00/rt2400pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,14 @@ static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev,
{
u32 reg;

mutex_lock(&rt2x00dev->csr_mutex);

/*
* Wait until the BBP becomes ready.
*/
reg = rt2400pci_bbp_check(rt2x00dev);
if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n");
return;
}
if (rt2x00_get_field32(reg, BBPCSR_BUSY))
goto exit_fail;

/*
* Write the data into the BBP.
Expand All @@ -88,21 +88,30 @@ static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&reg, BBPCSR_WRITE_CONTROL, 1);

rt2x00pci_register_write(rt2x00dev, BBPCSR, reg);

mutex_unlock(&rt2x00dev->csr_mutex);

return;

exit_fail:
mutex_unlock(&rt2x00dev->csr_mutex);

ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n");
}

static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u8 *value)
{
u32 reg;

mutex_lock(&rt2x00dev->csr_mutex);

/*
* Wait until the BBP becomes ready.
*/
reg = rt2400pci_bbp_check(rt2x00dev);
if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
return;
}
if (rt2x00_get_field32(reg, BBPCSR_BUSY))
goto exit_fail;

/*
* Write the request into the BBP.
Expand All @@ -118,13 +127,20 @@ static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev,
* Wait until the BBP becomes ready.
*/
reg = rt2400pci_bbp_check(rt2x00dev);
if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
*value = 0xff;
return;
}
if (rt2x00_get_field32(reg, BBPCSR_BUSY))
goto exit_fail;

*value = rt2x00_get_field32(reg, BBPCSR_VALUE);

mutex_unlock(&rt2x00dev->csr_mutex);

return;

exit_fail:
mutex_unlock(&rt2x00dev->csr_mutex);

ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
*value = 0xff;
}

static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev,
Expand All @@ -136,13 +152,16 @@ static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev,
if (!word)
return;

mutex_lock(&rt2x00dev->csr_mutex);

for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
rt2x00pci_register_read(rt2x00dev, RFCSR, &reg);
if (!rt2x00_get_field32(reg, RFCSR_BUSY))
goto rf_write;
udelay(REGISTER_BUSY_DELAY);
}

mutex_unlock(&rt2x00dev->csr_mutex);
ERROR(rt2x00dev, "RFCSR register busy. Write failed.\n");
return;

Expand All @@ -155,6 +174,8 @@ static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev,

rt2x00pci_register_write(rt2x00dev, RFCSR, reg);
rt2x00_rf_write(rt2x00dev, word, value);

mutex_unlock(&rt2x00dev->csr_mutex);
}

static void rt2400pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
Expand Down
47 changes: 34 additions & 13 deletions trunk/drivers/net/wireless/rt2x00/rt2500pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,14 @@ static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev,
{
u32 reg;

mutex_lock(&rt2x00dev->csr_mutex);

/*
* Wait until the BBP becomes ready.
*/
reg = rt2500pci_bbp_check(rt2x00dev);
if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n");
return;
}
if (rt2x00_get_field32(reg, BBPCSR_BUSY))
goto exit_fail;

/*
* Write the data into the BBP.
Expand All @@ -88,21 +88,30 @@ static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&reg, BBPCSR_WRITE_CONTROL, 1);

rt2x00pci_register_write(rt2x00dev, BBPCSR, reg);

mutex_unlock(&rt2x00dev->csr_mutex);

return;

exit_fail:
mutex_unlock(&rt2x00dev->csr_mutex);

ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n");
}

static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u8 *value)
{
u32 reg;

mutex_lock(&rt2x00dev->csr_mutex);

/*
* Wait until the BBP becomes ready.
*/
reg = rt2500pci_bbp_check(rt2x00dev);
if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
return;
}
if (rt2x00_get_field32(reg, BBPCSR_BUSY))
goto exit_fail;

/*
* Write the request into the BBP.
Expand All @@ -118,13 +127,20 @@ static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev,
* Wait until the BBP becomes ready.
*/
reg = rt2500pci_bbp_check(rt2x00dev);
if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
*value = 0xff;
return;
}
if (rt2x00_get_field32(reg, BBPCSR_BUSY))
goto exit_fail;

*value = rt2x00_get_field32(reg, BBPCSR_VALUE);

mutex_unlock(&rt2x00dev->csr_mutex);

return;

exit_fail:
mutex_unlock(&rt2x00dev->csr_mutex);

ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
*value = 0xff;
}

static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev,
Expand All @@ -136,13 +152,16 @@ static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev,
if (!word)
return;

mutex_lock(&rt2x00dev->csr_mutex);

for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
rt2x00pci_register_read(rt2x00dev, RFCSR, &reg);
if (!rt2x00_get_field32(reg, RFCSR_BUSY))
goto rf_write;
udelay(REGISTER_BUSY_DELAY);
}

mutex_unlock(&rt2x00dev->csr_mutex);
ERROR(rt2x00dev, "RFCSR register busy. Write failed.\n");
return;

Expand All @@ -155,6 +174,8 @@ static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev,

rt2x00pci_register_write(rt2x00dev, RFCSR, reg);
rt2x00_rf_write(rt2x00dev, word, value);

mutex_unlock(&rt2x00dev->csr_mutex);
}

static void rt2500pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
Expand Down
20 changes: 10 additions & 10 deletions trunk/drivers/net/wireless/rt2x00/rt2500usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
* between each attampt. When the busy bit is still set at that time,
* the access attempt is considered to have failed,
* and we will print an error.
* If the usb_cache_mutex is already held then the _lock variants must
* If the csr_mutex is already held then the _lock variants must
* be used instead.
*/
static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev,
Expand Down Expand Up @@ -132,7 +132,7 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
{
u16 reg;

mutex_lock(&rt2x00dev->usb_cache_mutex);
mutex_lock(&rt2x00dev->csr_mutex);

/*
* Wait until the BBP becomes ready.
Expand All @@ -151,12 +151,12 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,

rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg);

mutex_unlock(&rt2x00dev->usb_cache_mutex);
mutex_unlock(&rt2x00dev->csr_mutex);

return;

exit_fail:
mutex_unlock(&rt2x00dev->usb_cache_mutex);
mutex_unlock(&rt2x00dev->csr_mutex);

ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n");
}
Expand All @@ -166,7 +166,7 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
{
u16 reg;

mutex_lock(&rt2x00dev->usb_cache_mutex);
mutex_lock(&rt2x00dev->csr_mutex);

/*
* Wait until the BBP becomes ready.
Expand Down Expand Up @@ -194,12 +194,12 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, &reg);
*value = rt2x00_get_field16(reg, PHY_CSR7_DATA);

mutex_unlock(&rt2x00dev->usb_cache_mutex);
mutex_unlock(&rt2x00dev->csr_mutex);

return;

exit_fail:
mutex_unlock(&rt2x00dev->usb_cache_mutex);
mutex_unlock(&rt2x00dev->csr_mutex);

ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n");
*value = 0xff;
Expand All @@ -214,7 +214,7 @@ static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
if (!word)
return;

mutex_lock(&rt2x00dev->usb_cache_mutex);
mutex_lock(&rt2x00dev->csr_mutex);

for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
rt2500usb_register_read_lock(rt2x00dev, PHY_CSR10, &reg);
Expand All @@ -223,7 +223,7 @@ static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
udelay(REGISTER_BUSY_DELAY);
}

mutex_unlock(&rt2x00dev->usb_cache_mutex);
mutex_unlock(&rt2x00dev->csr_mutex);
ERROR(rt2x00dev, "PHY_CSR10 register busy. Write failed.\n");
return;

Expand All @@ -241,7 +241,7 @@ static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
rt2500usb_register_write_lock(rt2x00dev, PHY_CSR10, reg);
rt2x00_rf_write(rt2x00dev, word, value);

mutex_unlock(&rt2x00dev->usb_cache_mutex);
mutex_unlock(&rt2x00dev->csr_mutex);
}

#ifdef CONFIG_RT2X00_LIB_DEBUGFS
Expand Down
19 changes: 9 additions & 10 deletions trunk/drivers/net/wireless/rt2x00/rt2x00.h
Original file line number Diff line number Diff line change
Expand Up @@ -746,16 +746,15 @@ struct rt2x00_dev {
} csr;

/*
* Mutex to protect register accesses on USB devices.
* There are 2 reasons this is needed, one is to ensure
* use of the csr_cache (for USB devices) by one thread
* isn't corrupted by another thread trying to access it.
* The other is that access to BBP and RF registers
* require multiple BUS transactions and if another thread
* attempted to access one of those registers at the same
* time one of the writes could silently fail.
*/
struct mutex usb_cache_mutex;
* Mutex to protect register accesses.
* For PCI and USB devices it protects against concurrent indirect
* register access (BBP, RF, MCU) since accessing those
* registers require multiple calls to the CSR registers.
* For USB devices it also protects the csr_cache since that
* field is used for normal CSR access and it cannot support
* multiple callers simultaneously.
*/
struct mutex csr_mutex;

/*
* Current packet filter configuration for the device.
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/net/wireless/rt2x00/rt2x00dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -1051,6 +1051,8 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
{
int retval = -ENOMEM;

mutex_init(&rt2x00dev->csr_mutex);

/*
* Make room for rt2x00_intf inside the per-interface
* structure ieee80211_vif.
Expand Down
11 changes: 5 additions & 6 deletions trunk/drivers/net/wireless/rt2x00/rt2x00usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev,
{
int status;

BUG_ON(!mutex_is_locked(&rt2x00dev->usb_cache_mutex));
BUG_ON(!mutex_is_locked(&rt2x00dev->csr_mutex));

/*
* Check for Cache availability.
Expand Down Expand Up @@ -110,13 +110,13 @@ int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev,
{
int status;

mutex_lock(&rt2x00dev->usb_cache_mutex);
mutex_lock(&rt2x00dev->csr_mutex);

status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request,
requesttype, offset, buffer,
buffer_length, timeout);

mutex_unlock(&rt2x00dev->usb_cache_mutex);
mutex_unlock(&rt2x00dev->csr_mutex);

return status;
}
Expand All @@ -132,7 +132,7 @@ int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
unsigned char *tb;
u16 off, len, bsize;

mutex_lock(&rt2x00dev->usb_cache_mutex);
mutex_lock(&rt2x00dev->csr_mutex);

tb = (char *)buffer;
off = offset;
Expand All @@ -148,7 +148,7 @@ int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
off += bsize;
}

mutex_unlock(&rt2x00dev->usb_cache_mutex);
mutex_unlock(&rt2x00dev->csr_mutex);

return status;
}
Expand Down Expand Up @@ -531,7 +531,6 @@ int rt2x00usb_probe(struct usb_interface *usb_intf,
rt2x00dev->dev = &usb_intf->dev;
rt2x00dev->ops = ops;
rt2x00dev->hw = hw;
mutex_init(&rt2x00dev->usb_cache_mutex);

rt2x00dev->usb_maxpacket =
usb_maxpacket(usb_dev, usb_sndbulkpipe(usb_dev, 1), 1);
Expand Down
Loading

0 comments on commit 69bc21e

Please sign in to comment.