aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/debugfs.c
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2008-06-19 13:33:51 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-06-26 16:49:18 -0400
commit6bbc321a96d4d3533eb136b981baba6c8248d635 (patch)
tree6458968538ebe0c1cf3f65adab9fd9b0ea4e3439 /drivers/net/wireless/b43/debugfs.c
parent8bd463f4f913db12a1b7374f84304631289a1e0b (diff)
b43: Add debugfs files for random SHM access
This adds debugfs files for random SHM access. This is needed in order to implement firmware and driver debugging scripts in userspace. Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43/debugfs.c')
-rw-r--r--drivers/net/wireless/b43/debugfs.c178
1 files changed, 178 insertions, 0 deletions
diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c
index 9cdd9eca0822..dd40ad826c78 100644
--- a/drivers/net/wireless/b43/debugfs.c
+++ b/drivers/net/wireless/b43/debugfs.c
@@ -74,6 +74,168 @@ 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 address values for SHM access from the debugfs files. */
78#define B43_MAX_SHM_ROUTING 4
79#define B43_MAX_SHM_ADDR 0xFFFF
80
81static ssize_t shm16read__read_file(struct b43_wldev *dev,
82 char *buf, size_t bufsize)
83{
84 ssize_t count = 0;
85 unsigned int routing, addr;
86 u16 val;
87
88 routing = dev->dfsentry->shm16read_routing_next;
89 addr = dev->dfsentry->shm16read_addr_next;
90 if ((routing > B43_MAX_SHM_ROUTING) ||
91 (addr > B43_MAX_SHM_ADDR))
92 return -EDESTADDRREQ;
93
94 val = b43_shm_read16(dev, routing, addr);
95 fappend("0x%04X\n", val);
96
97 return count;
98}
99
100static int shm16read__write_file(struct b43_wldev *dev,
101 const char *buf, size_t count)
102{
103 unsigned int routing, addr;
104 int res;
105
106 res = sscanf(buf, "0x%X 0x%X", &routing, &addr);
107 if (res != 2)
108 return -EINVAL;
109 if (routing > B43_MAX_SHM_ROUTING)
110 return -EADDRNOTAVAIL;
111 if (addr > B43_MAX_SHM_ADDR)
112 return -EADDRNOTAVAIL;
113 if (routing == B43_SHM_SHARED) {
114 if ((addr % 2) != 0)
115 return -EADDRNOTAVAIL;
116 }
117
118 dev->dfsentry->shm16read_routing_next = routing;
119 dev->dfsentry->shm16read_addr_next = addr;
120
121 return 0;
122}
123
124static int shm16write__write_file(struct b43_wldev *dev,
125 const char *buf, size_t count)
126{
127 unsigned int routing, addr, mask, set;
128 u16 val;
129 int res;
130 unsigned long flags;
131
132 res = sscanf(buf, "0x%X 0x%X 0x%X 0x%X",
133 &routing, &addr, &mask, &set);
134 if (res != 4)
135 return -EINVAL;
136 if (routing > B43_MAX_SHM_ROUTING)
137 return -EADDRNOTAVAIL;
138 if (addr > B43_MAX_SHM_ADDR)
139 return -EADDRNOTAVAIL;
140 if (routing == B43_SHM_SHARED) {
141 if ((addr % 2) != 0)
142 return -EADDRNOTAVAIL;
143 }
144 if ((mask > 0xFFFF) || (set > 0xFFFF))
145 return -E2BIG;
146
147 spin_lock_irqsave(&dev->wl->shm_lock, flags);
148 if (mask == 0)
149 val = 0;
150 else
151 val = __b43_shm_read16(dev, routing, addr);
152 val &= mask;
153 val |= set;
154 __b43_shm_write16(dev, routing, addr, val);
155 spin_unlock_irqrestore(&dev->wl->shm_lock, flags);
156
157 return 0;
158}
159
160static ssize_t shm32read__read_file(struct b43_wldev *dev,
161 char *buf, size_t bufsize)
162{
163 ssize_t count = 0;
164 unsigned int routing, addr;
165 u32 val;
166
167 routing = dev->dfsentry->shm32read_routing_next;
168 addr = dev->dfsentry->shm32read_addr_next;
169 if ((routing > B43_MAX_SHM_ROUTING) ||
170 (addr > B43_MAX_SHM_ADDR))
171 return -EDESTADDRREQ;
172
173 val = b43_shm_read32(dev, routing, addr);
174 fappend("0x%08X\n", val);
175
176 return count;
177}
178
179static int shm32read__write_file(struct b43_wldev *dev,
180 const char *buf, size_t count)
181{
182 unsigned int routing, addr;
183 int res;
184
185 res = sscanf(buf, "0x%X 0x%X", &routing, &addr);
186 if (res != 2)
187 return -EINVAL;
188 if (routing > B43_MAX_SHM_ROUTING)
189 return -EADDRNOTAVAIL;
190 if (addr > B43_MAX_SHM_ADDR)
191 return -EADDRNOTAVAIL;
192 if (routing == B43_SHM_SHARED) {
193 if ((addr % 2) != 0)
194 return -EADDRNOTAVAIL;
195 }
196
197 dev->dfsentry->shm32read_routing_next = routing;
198 dev->dfsentry->shm32read_addr_next = addr;
199
200 return 0;
201}
202
203static int shm32write__write_file(struct b43_wldev *dev,
204 const char *buf, size_t count)
205{
206 unsigned int routing, addr, mask, set;
207 u32 val;
208 int res;
209 unsigned long flags;
210
211 res = sscanf(buf, "0x%X 0x%X 0x%X 0x%X",
212 &routing, &addr, &mask, &set);
213 if (res != 4)
214 return -EINVAL;
215 if (routing > B43_MAX_SHM_ROUTING)
216 return -EADDRNOTAVAIL;
217 if (addr > B43_MAX_SHM_ADDR)
218 return -EADDRNOTAVAIL;
219 if (routing == B43_SHM_SHARED) {
220 if ((addr % 2) != 0)
221 return -EADDRNOTAVAIL;
222 }
223 if ((mask > 0xFFFFFFFF) || (set > 0xFFFFFFFF))
224 return -E2BIG;
225
226 spin_lock_irqsave(&dev->wl->shm_lock, flags);
227 if (mask == 0)
228 val = 0;
229 else
230 val = __b43_shm_read32(dev, routing, addr);
231 val &= mask;
232 val |= set;
233 __b43_shm_write32(dev, routing, addr, val);
234 spin_unlock_irqrestore(&dev->wl->shm_lock, flags);
235
236 return 0;
237}
238
77/* The biggest MMIO address that we allow access to from the debugfs files. */ 239/* The biggest MMIO address that we allow access to from the debugfs files. */
78#define B43_MAX_MMIO_ACCESS (0xF00 - 1) 240#define B43_MAX_MMIO_ACCESS (0xF00 - 1)
79 241
@@ -605,6 +767,10 @@ out_unlock:
605 .take_irqlock = _take_irqlock, \ 767 .take_irqlock = _take_irqlock, \
606 } 768 }
607 769
770B43_DEBUGFS_FOPS(shm16read, shm16read__read_file, shm16read__write_file, 1);
771B43_DEBUGFS_FOPS(shm16write, NULL, shm16write__write_file, 1);
772B43_DEBUGFS_FOPS(shm32read, shm32read__read_file, shm32read__write_file, 1);
773B43_DEBUGFS_FOPS(shm32write, NULL, shm32write__write_file, 1);
608B43_DEBUGFS_FOPS(mmio16read, mmio16read__read_file, mmio16read__write_file, 1); 774B43_DEBUGFS_FOPS(mmio16read, mmio16read__read_file, mmio16read__write_file, 1);
609B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file, 1); 775B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file, 1);
610B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1); 776B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1);
@@ -699,6 +865,10 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
699 865
700 e->mmio16read_next = 0xFFFF; /* invalid address */ 866 e->mmio16read_next = 0xFFFF; /* invalid address */
701 e->mmio32read_next = 0xFFFF; /* invalid address */ 867 e->mmio32read_next = 0xFFFF; /* invalid address */
868 e->shm16read_routing_next = 0xFFFFFFFF; /* invalid routing */
869 e->shm16read_addr_next = 0xFFFFFFFF; /* invalid address */
870 e->shm32read_routing_next = 0xFFFFFFFF; /* invalid routing */
871 e->shm32read_addr_next = 0xFFFFFFFF; /* invalid address */
702 872
703#define ADD_FILE(name, mode) \ 873#define ADD_FILE(name, mode) \
704 do { \ 874 do { \
@@ -712,6 +882,10 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
712 } while (0) 882 } while (0)
713 883
714 884
885 ADD_FILE(shm16read, 0600);
886 ADD_FILE(shm16write, 0200);
887 ADD_FILE(shm32read, 0600);
888 ADD_FILE(shm32write, 0200);
715 ADD_FILE(mmio16read, 0600); 889 ADD_FILE(mmio16read, 0600);
716 ADD_FILE(mmio16write, 0200); 890 ADD_FILE(mmio16write, 0200);
717 ADD_FILE(mmio32read, 0600); 891 ADD_FILE(mmio32read, 0600);
@@ -740,6 +914,10 @@ void b43_debugfs_remove_device(struct b43_wldev *dev)
740 return; 914 return;
741 b43_remove_dynamic_debug(dev); 915 b43_remove_dynamic_debug(dev);
742 916
917 debugfs_remove(e->file_shm16read.dentry);
918 debugfs_remove(e->file_shm16write.dentry);
919 debugfs_remove(e->file_shm32read.dentry);
920 debugfs_remove(e->file_shm32write.dentry);
743 debugfs_remove(e->file_mmio16read.dentry); 921 debugfs_remove(e->file_mmio16read.dentry);
744 debugfs_remove(e->file_mmio16write.dentry); 922 debugfs_remove(e->file_mmio16write.dentry);
745 debugfs_remove(e->file_mmio32read.dentry); 923 debugfs_remove(e->file_mmio32read.dentry);