mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-06 10:57:46 +00:00
b43: Add debugfs files for MMIO register access
This adds debugfs files for reading and writing arbitrary wireless core registers. This is useful for debugging. Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
5a9f7b047e
commit
8bd463f4f9
2 changed files with 133 additions and 0 deletions
|
@ -74,6 +74,115 @@ struct b43_dfs_file * fops_to_dfs_file(struct b43_wldev *dev,
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
/* The biggest MMIO address that we allow access to from the debugfs files. */
|
||||||
|
#define B43_MAX_MMIO_ACCESS (0xF00 - 1)
|
||||||
|
|
||||||
|
static ssize_t mmio16read__read_file(struct b43_wldev *dev,
|
||||||
|
char *buf, size_t bufsize)
|
||||||
|
{
|
||||||
|
ssize_t count = 0;
|
||||||
|
unsigned int addr;
|
||||||
|
u16 val;
|
||||||
|
|
||||||
|
addr = dev->dfsentry->mmio16read_next;
|
||||||
|
if (addr > B43_MAX_MMIO_ACCESS)
|
||||||
|
return -EDESTADDRREQ;
|
||||||
|
|
||||||
|
val = b43_read16(dev, addr);
|
||||||
|
fappend("0x%04X\n", val);
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mmio16read__write_file(struct b43_wldev *dev,
|
||||||
|
const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
unsigned int addr;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
res = sscanf(buf, "0x%X", &addr);
|
||||||
|
if (res != 1)
|
||||||
|
return -EINVAL;
|
||||||
|
if (addr > B43_MAX_MMIO_ACCESS)
|
||||||
|
return -EADDRNOTAVAIL;
|
||||||
|
|
||||||
|
dev->dfsentry->mmio16read_next = addr;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mmio16write__write_file(struct b43_wldev *dev,
|
||||||
|
const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
unsigned int addr, val;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
res = sscanf(buf, "0x%X = 0x%X", &addr, &val);
|
||||||
|
if (res != 2)
|
||||||
|
return -EINVAL;
|
||||||
|
if (addr > B43_MAX_MMIO_ACCESS)
|
||||||
|
return -EADDRNOTAVAIL;
|
||||||
|
if (val > 0xFFFF)
|
||||||
|
return -E2BIG;
|
||||||
|
|
||||||
|
b43_write16(dev, addr, val);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t mmio32read__read_file(struct b43_wldev *dev,
|
||||||
|
char *buf, size_t bufsize)
|
||||||
|
{
|
||||||
|
ssize_t count = 0;
|
||||||
|
unsigned int addr;
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
addr = dev->dfsentry->mmio32read_next;
|
||||||
|
if (addr > B43_MAX_MMIO_ACCESS)
|
||||||
|
return -EDESTADDRREQ;
|
||||||
|
|
||||||
|
val = b43_read32(dev, addr);
|
||||||
|
fappend("0x%08X\n", val);
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mmio32read__write_file(struct b43_wldev *dev,
|
||||||
|
const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
unsigned int addr;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
res = sscanf(buf, "0x%X", &addr);
|
||||||
|
if (res != 1)
|
||||||
|
return -EINVAL;
|
||||||
|
if (addr > B43_MAX_MMIO_ACCESS)
|
||||||
|
return -EADDRNOTAVAIL;
|
||||||
|
|
||||||
|
dev->dfsentry->mmio32read_next = addr;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mmio32write__write_file(struct b43_wldev *dev,
|
||||||
|
const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
unsigned int addr, val;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
res = sscanf(buf, "0x%X = 0x%X", &addr, &val);
|
||||||
|
if (res != 2)
|
||||||
|
return -EINVAL;
|
||||||
|
if (addr > B43_MAX_MMIO_ACCESS)
|
||||||
|
return -EADDRNOTAVAIL;
|
||||||
|
if (val > 0xFFFFFFFF)
|
||||||
|
return -E2BIG;
|
||||||
|
|
||||||
|
b43_write32(dev, addr, val);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* wl->irq_lock is locked */
|
/* wl->irq_lock is locked */
|
||||||
static ssize_t tsf_read_file(struct b43_wldev *dev,
|
static ssize_t tsf_read_file(struct b43_wldev *dev,
|
||||||
char *buf, size_t bufsize)
|
char *buf, size_t bufsize)
|
||||||
|
@ -496,6 +605,10 @@ static ssize_t b43_debugfs_write(struct file *file,
|
||||||
.take_irqlock = _take_irqlock, \
|
.take_irqlock = _take_irqlock, \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
B43_DEBUGFS_FOPS(mmio16read, mmio16read__read_file, mmio16read__write_file, 1);
|
||||||
|
B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file, 1);
|
||||||
|
B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1);
|
||||||
|
B43_DEBUGFS_FOPS(mmio32write, NULL, mmio32write__write_file, 1);
|
||||||
B43_DEBUGFS_FOPS(tsf, tsf_read_file, tsf_write_file, 1);
|
B43_DEBUGFS_FOPS(tsf, tsf_read_file, tsf_write_file, 1);
|
||||||
B43_DEBUGFS_FOPS(ucode_regs, ucode_regs_read_file, NULL, 1);
|
B43_DEBUGFS_FOPS(ucode_regs, ucode_regs_read_file, NULL, 1);
|
||||||
B43_DEBUGFS_FOPS(shm, shm_read_file, NULL, 1);
|
B43_DEBUGFS_FOPS(shm, shm_read_file, NULL, 1);
|
||||||
|
@ -584,6 +697,9 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e->mmio16read_next = 0xFFFF; /* invalid address */
|
||||||
|
e->mmio32read_next = 0xFFFF; /* invalid address */
|
||||||
|
|
||||||
#define ADD_FILE(name, mode) \
|
#define ADD_FILE(name, mode) \
|
||||||
do { \
|
do { \
|
||||||
struct dentry *d; \
|
struct dentry *d; \
|
||||||
|
@ -596,6 +712,10 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
ADD_FILE(mmio16read, 0600);
|
||||||
|
ADD_FILE(mmio16write, 0200);
|
||||||
|
ADD_FILE(mmio32read, 0600);
|
||||||
|
ADD_FILE(mmio32write, 0200);
|
||||||
ADD_FILE(tsf, 0600);
|
ADD_FILE(tsf, 0600);
|
||||||
ADD_FILE(ucode_regs, 0400);
|
ADD_FILE(ucode_regs, 0400);
|
||||||
ADD_FILE(shm, 0400);
|
ADD_FILE(shm, 0400);
|
||||||
|
@ -620,6 +740,10 @@ void b43_debugfs_remove_device(struct b43_wldev *dev)
|
||||||
return;
|
return;
|
||||||
b43_remove_dynamic_debug(dev);
|
b43_remove_dynamic_debug(dev);
|
||||||
|
|
||||||
|
debugfs_remove(e->file_mmio16read.dentry);
|
||||||
|
debugfs_remove(e->file_mmio16write.dentry);
|
||||||
|
debugfs_remove(e->file_mmio32read.dentry);
|
||||||
|
debugfs_remove(e->file_mmio32write.dentry);
|
||||||
debugfs_remove(e->file_tsf.dentry);
|
debugfs_remove(e->file_tsf.dentry);
|
||||||
debugfs_remove(e->file_ucode_regs.dentry);
|
debugfs_remove(e->file_ucode_regs.dentry);
|
||||||
debugfs_remove(e->file_shm.dentry);
|
debugfs_remove(e->file_shm.dentry);
|
||||||
|
|
|
@ -36,6 +36,10 @@ struct b43_dfsentry {
|
||||||
struct b43_wldev *dev;
|
struct b43_wldev *dev;
|
||||||
struct dentry *subdir;
|
struct dentry *subdir;
|
||||||
|
|
||||||
|
struct b43_dfs_file file_mmio16read;
|
||||||
|
struct b43_dfs_file file_mmio16write;
|
||||||
|
struct b43_dfs_file file_mmio32read;
|
||||||
|
struct b43_dfs_file file_mmio32write;
|
||||||
struct b43_dfs_file file_tsf;
|
struct b43_dfs_file file_tsf;
|
||||||
struct b43_dfs_file file_ucode_regs;
|
struct b43_dfs_file file_ucode_regs;
|
||||||
struct b43_dfs_file file_shm;
|
struct b43_dfs_file file_shm;
|
||||||
|
@ -46,6 +50,11 @@ struct b43_dfsentry {
|
||||||
|
|
||||||
struct b43_txstatus_log txstatlog;
|
struct b43_txstatus_log txstatlog;
|
||||||
|
|
||||||
|
/* The cached address for the next mmio16read file read */
|
||||||
|
u16 mmio16read_next;
|
||||||
|
/* The cached address for the next mmio32read file read */
|
||||||
|
u16 mmio32read_next;
|
||||||
|
|
||||||
/* Enabled/Disabled list for the dynamic debugging features. */
|
/* Enabled/Disabled list for the dynamic debugging features. */
|
||||||
u32 dyn_debug[__B43_NR_DYNDBG];
|
u32 dyn_debug[__B43_NR_DYNDBG];
|
||||||
/* Dentries for the dynamic debugging entries. */
|
/* Dentries for the dynamic debugging entries. */
|
||||||
|
|
Loading…
Reference in a new issue