aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2008-06-18 18:35:49 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-06-26 16:49:18 -0400
commit8bd463f4f913db12a1b7374f84304631289a1e0b (patch)
tree4153e7dd42d6e2aeb9cbe4ff59eb5f7bf0572de6
parent5a9f7b047e81a73a1ce3e42ef87c28a61fd4df24 (diff)
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>
-rw-r--r--drivers/net/wireless/b43/debugfs.c124
-rw-r--r--drivers/net/wireless/b43/debugfs.h9
2 files changed, 133 insertions, 0 deletions
diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c
index 210e2789c1c3..9cdd9eca0822 100644
--- a/drivers/net/wireless/b43/debugfs.c
+++ b/drivers/net/wireless/b43/debugfs.c
@@ -74,6 +74,115 @@ struct b43_dfs_file * fops_to_dfs_file(struct b43_wldev *dev,
74 } while (0) 74 } while (0)
75 75
76 76
77/* The biggest MMIO address that we allow access to from the debugfs files. */
78#define B43_MAX_MMIO_ACCESS (0xF00 - 1)
79
80static ssize_t mmio16read__read_file(struct b43_wldev *dev,
81 char *buf, size_t bufsize)
82{
83 ssize_t count = 0;
84 unsigned int addr;
85 u16 val;
86
87 addr = dev->dfsentry->mmio16read_next;
88 if (addr > B43_MAX_MMIO_ACCESS)
89 return -EDESTADDRREQ;
90
91 val = b43_read16(dev, addr);
92 fappend("0x%04X\n", val);
93
94 return count;
95}
96
97static int mmio16read__write_file(struct b43_wldev *dev,
98 const char *buf, size_t count)
99{
100 unsigned int addr;
101 int res;
102
103 res = sscanf(buf, "0x%X", &addr);
104 if (res != 1)
105 return -EINVAL;
106 if (addr > B43_MAX_MMIO_ACCESS)
107 return -EADDRNOTAVAIL;
108
109 dev->dfsentry->mmio16read_next = addr;
110
111 return 0;
112}
113
114static int mmio16write__write_file(struct b43_wldev *dev,
115 const char *buf, size_t count)
116{
117 unsigned int addr, val;
118 int res;
119
120 res = sscanf(buf, "0x%X = 0x%X", &addr, &val);
121 if (res != 2)
122 return -EINVAL;
123 if (addr > B43_MAX_MMIO_ACCESS)
124 return -EADDRNOTAVAIL;
125 if (val > 0xFFFF)
126 return -E2BIG;
127
128 b43_write16(dev, addr, val);
129
130 return 0;
131}
132
133static ssize_t mmio32read__read_file(struct b43_wldev *dev,
134 char *buf, size_t bufsize)
135{
136 ssize_t count = 0;
137 unsigned int addr;
138 u32 val;
139
140 addr = dev->dfsentry->mmio32read_next;
141 if (addr > B43_MAX_MMIO_ACCESS)
142 return -EDESTADDRREQ;
143
144 val = b43_read32(dev, addr);
145 fappend("0x%08X\n", val);
146
147 return count;
148}
149
150static int mmio32read__write_file(struct b43_wldev *dev,
151 const char *buf, size_t count)
152{
153 unsigned int addr;
154 int res;
155
156 res = sscanf(buf, "0x%X", &addr);
157 if (res != 1)
158 return -EINVAL;
159 if (addr > B43_MAX_MMIO_ACCESS)
160 return -EADDRNOTAVAIL;
161
162 dev->dfsentry->mmio32read_next = addr;
163
164 return 0;
165}
166
167static int mmio32write__write_file(struct b43_wldev *dev,
168 const char *buf, size_t count)
169{
170 unsigned int addr, val;
171 int res;
172
173 res = sscanf(buf, "0x%X = 0x%X", &addr, &val);
174 if (res != 2)
175 return -EINVAL;
176 if (addr > B43_MAX_MMIO_ACCESS)
177 return -EADDRNOTAVAIL;
178 if (val > 0xFFFFFFFF)
179 return -E2BIG;
180
181 b43_write32(dev, addr, val);
182
183 return 0;
184}
185
77/* wl->irq_lock is locked */ 186/* wl->irq_lock is locked */
78static ssize_t tsf_read_file(struct b43_wldev *dev, 187static ssize_t tsf_read_file(struct b43_wldev *dev,
79 char *buf, size_t bufsize) 188 char *buf, size_t bufsize)
@@ -496,6 +605,10 @@ out_unlock:
496 .take_irqlock = _take_irqlock, \ 605 .take_irqlock = _take_irqlock, \
497 } 606 }
498 607
608B43_DEBUGFS_FOPS(mmio16read, mmio16read__read_file, mmio16read__write_file, 1);
609B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file, 1);
610B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1);
611B43_DEBUGFS_FOPS(mmio32write, NULL, mmio32write__write_file, 1);
499B43_DEBUGFS_FOPS(tsf, tsf_read_file, tsf_write_file, 1); 612B43_DEBUGFS_FOPS(tsf, tsf_read_file, tsf_write_file, 1);
500B43_DEBUGFS_FOPS(ucode_regs, ucode_regs_read_file, NULL, 1); 613B43_DEBUGFS_FOPS(ucode_regs, ucode_regs_read_file, NULL, 1);
501B43_DEBUGFS_FOPS(shm, shm_read_file, NULL, 1); 614B43_DEBUGFS_FOPS(shm, shm_read_file, NULL, 1);
@@ -584,6 +697,9 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
584 return; 697 return;
585 } 698 }
586 699
700 e->mmio16read_next = 0xFFFF; /* invalid address */
701 e->mmio32read_next = 0xFFFF; /* invalid address */
702
587#define ADD_FILE(name, mode) \ 703#define ADD_FILE(name, mode) \
588 do { \ 704 do { \
589 struct dentry *d; \ 705 struct dentry *d; \
@@ -596,6 +712,10 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
596 } while (0) 712 } while (0)
597 713
598 714
715 ADD_FILE(mmio16read, 0600);
716 ADD_FILE(mmio16write, 0200);
717 ADD_FILE(mmio32read, 0600);
718 ADD_FILE(mmio32write, 0200);
599 ADD_FILE(tsf, 0600); 719 ADD_FILE(tsf, 0600);
600 ADD_FILE(ucode_regs, 0400); 720 ADD_FILE(ucode_regs, 0400);
601 ADD_FILE(shm, 0400); 721 ADD_FILE(shm, 0400);
@@ -620,6 +740,10 @@ void b43_debugfs_remove_device(struct b43_wldev *dev)
620 return; 740 return;
621 b43_remove_dynamic_debug(dev); 741 b43_remove_dynamic_debug(dev);
622 742
743 debugfs_remove(e->file_mmio16read.dentry);
744 debugfs_remove(e->file_mmio16write.dentry);
745 debugfs_remove(e->file_mmio32read.dentry);
746 debugfs_remove(e->file_mmio32write.dentry);
623 debugfs_remove(e->file_tsf.dentry); 747 debugfs_remove(e->file_tsf.dentry);
624 debugfs_remove(e->file_ucode_regs.dentry); 748 debugfs_remove(e->file_ucode_regs.dentry);
625 debugfs_remove(e->file_shm.dentry); 749 debugfs_remove(e->file_shm.dentry);
diff --git a/drivers/net/wireless/b43/debugfs.h b/drivers/net/wireless/b43/debugfs.h
index c75cff4151d9..d6848696cee0 100644
--- a/drivers/net/wireless/b43/debugfs.h
+++ b/drivers/net/wireless/b43/debugfs.h
@@ -36,6 +36,10 @@ struct b43_dfsentry {
36 struct b43_wldev *dev; 36 struct b43_wldev *dev;
37 struct dentry *subdir; 37 struct dentry *subdir;
38 38
39 struct b43_dfs_file file_mmio16read;
40 struct b43_dfs_file file_mmio16write;
41 struct b43_dfs_file file_mmio32read;
42 struct b43_dfs_file file_mmio32write;
39 struct b43_dfs_file file_tsf; 43 struct b43_dfs_file file_tsf;
40 struct b43_dfs_file file_ucode_regs; 44 struct b43_dfs_file file_ucode_regs;
41 struct b43_dfs_file file_shm; 45 struct b43_dfs_file file_shm;
@@ -46,6 +50,11 @@ struct b43_dfsentry {
46 50
47 struct b43_txstatus_log txstatlog; 51 struct b43_txstatus_log txstatlog;
48 52
53 /* The cached address for the next mmio16read file read */
54 u16 mmio16read_next;
55 /* The cached address for the next mmio32read file read */
56 u16 mmio32read_next;
57
49 /* Enabled/Disabled list for the dynamic debugging features. */ 58 /* Enabled/Disabled list for the dynamic debugging features. */
50 u32 dyn_debug[__B43_NR_DYNDBG]; 59 u32 dyn_debug[__B43_NR_DYNDBG];
51 /* Dentries for the dynamic debugging entries. */ 60 /* Dentries for the dynamic debugging entries. */