diff options
author | Michael Buesch <mb@bu3sch.de> | 2008-06-19 13:33:51 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-06-26 16:49:18 -0400 |
commit | 6bbc321a96d4d3533eb136b981baba6c8248d635 (patch) | |
tree | 6458968538ebe0c1cf3f65adab9fd9b0ea4e3439 /drivers/net/wireless/b43/debugfs.c | |
parent | 8bd463f4f913db12a1b7374f84304631289a1e0b (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.c | 178 |
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 | |||
81 | static 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 | |||
100 | static 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 | |||
124 | static 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 | |||
160 | static 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 | |||
179 | static 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 | |||
203 | static 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 | ||
770 | B43_DEBUGFS_FOPS(shm16read, shm16read__read_file, shm16read__write_file, 1); | ||
771 | B43_DEBUGFS_FOPS(shm16write, NULL, shm16write__write_file, 1); | ||
772 | B43_DEBUGFS_FOPS(shm32read, shm32read__read_file, shm32read__write_file, 1); | ||
773 | B43_DEBUGFS_FOPS(shm32write, NULL, shm32write__write_file, 1); | ||
608 | B43_DEBUGFS_FOPS(mmio16read, mmio16read__read_file, mmio16read__write_file, 1); | 774 | B43_DEBUGFS_FOPS(mmio16read, mmio16read__read_file, mmio16read__write_file, 1); |
609 | B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file, 1); | 775 | B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file, 1); |
610 | B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1); | 776 | B43_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); |