diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/mca/mca-proc.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/mca/mca-proc.c')
-rw-r--r-- | drivers/mca/mca-proc.c | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/drivers/mca/mca-proc.c b/drivers/mca/mca-proc.c new file mode 100644 index 000000000000..33d5e0820cc5 --- /dev/null +++ b/drivers/mca/mca-proc.c | |||
@@ -0,0 +1,249 @@ | |||
1 | /* -*- mode: c; c-basic-offset: 8 -*- */ | ||
2 | |||
3 | /* | ||
4 | * MCA bus support functions for the proc fs. | ||
5 | * | ||
6 | * NOTE: this code *requires* the legacy MCA api. | ||
7 | * | ||
8 | * Legacy API means the API that operates in terms of MCA slot number | ||
9 | * | ||
10 | * (C) 2002 James Bottomley <James.Bottomley@HansenPartnership.com> | ||
11 | * | ||
12 | **----------------------------------------------------------------------------- | ||
13 | ** | ||
14 | ** This program is free software; you can redistribute it and/or modify | ||
15 | ** it under the terms of the GNU General Public License as published by | ||
16 | ** the Free Software Foundation; either version 2 of the License, or | ||
17 | ** (at your option) any later version. | ||
18 | ** | ||
19 | ** This program is distributed in the hope that it will be useful, | ||
20 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | ** GNU General Public License for more details. | ||
23 | ** | ||
24 | ** You should have received a copy of the GNU General Public License | ||
25 | ** along with this program; if not, write to the Free Software | ||
26 | ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | ** | ||
28 | **----------------------------------------------------------------------------- | ||
29 | */ | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/proc_fs.h> | ||
33 | #include <linux/mca.h> | ||
34 | |||
35 | static int get_mca_info_helper(struct mca_device *mca_dev, char *page, int len) | ||
36 | { | ||
37 | int j; | ||
38 | |||
39 | for(j=0; j<8; j++) | ||
40 | len += sprintf(page+len, "%02x ", | ||
41 | mca_dev ? mca_dev->pos[j] : 0xff); | ||
42 | len += sprintf(page+len, " %s\n", mca_dev ? mca_dev->name : ""); | ||
43 | return len; | ||
44 | } | ||
45 | |||
46 | static int get_mca_info(char *page, char **start, off_t off, | ||
47 | int count, int *eof, void *data) | ||
48 | { | ||
49 | int i, len = 0; | ||
50 | |||
51 | if(MCA_bus) { | ||
52 | struct mca_device *mca_dev; | ||
53 | /* Format POS registers of eight MCA slots */ | ||
54 | |||
55 | for(i=0; i<MCA_MAX_SLOT_NR; i++) { | ||
56 | mca_dev = mca_find_device_by_slot(i); | ||
57 | |||
58 | len += sprintf(page+len, "Slot %d: ", i+1); | ||
59 | len = get_mca_info_helper(mca_dev, page, len); | ||
60 | } | ||
61 | |||
62 | /* Format POS registers of integrated video subsystem */ | ||
63 | |||
64 | mca_dev = mca_find_device_by_slot(MCA_INTEGVIDEO); | ||
65 | len += sprintf(page+len, "Video : "); | ||
66 | len = get_mca_info_helper(mca_dev, page, len); | ||
67 | |||
68 | /* Format POS registers of integrated SCSI subsystem */ | ||
69 | |||
70 | mca_dev = mca_find_device_by_slot(MCA_INTEGSCSI); | ||
71 | len += sprintf(page+len, "SCSI : "); | ||
72 | len = get_mca_info_helper(mca_dev, page, len); | ||
73 | |||
74 | /* Format POS registers of motherboard */ | ||
75 | |||
76 | mca_dev = mca_find_device_by_slot(MCA_MOTHERBOARD); | ||
77 | len += sprintf(page+len, "Planar: "); | ||
78 | len = get_mca_info_helper(mca_dev, page, len); | ||
79 | } else { | ||
80 | /* Leave it empty if MCA not detected - this should *never* | ||
81 | * happen! | ||
82 | */ | ||
83 | } | ||
84 | |||
85 | if (len <= off+count) *eof = 1; | ||
86 | *start = page + off; | ||
87 | len -= off; | ||
88 | if (len>count) len = count; | ||
89 | if (len<0) len = 0; | ||
90 | return len; | ||
91 | } | ||
92 | |||
93 | /*--------------------------------------------------------------------*/ | ||
94 | |||
95 | static int mca_default_procfn(char* buf, struct mca_device *mca_dev) | ||
96 | { | ||
97 | int len = 0, i; | ||
98 | int slot = mca_dev->slot; | ||
99 | |||
100 | /* Print out the basic information */ | ||
101 | |||
102 | if(slot < MCA_MAX_SLOT_NR) { | ||
103 | len += sprintf(buf+len, "Slot: %d\n", slot+1); | ||
104 | } else if(slot == MCA_INTEGSCSI) { | ||
105 | len += sprintf(buf+len, "Integrated SCSI Adapter\n"); | ||
106 | } else if(slot == MCA_INTEGVIDEO) { | ||
107 | len += sprintf(buf+len, "Integrated Video Adapter\n"); | ||
108 | } else if(slot == MCA_MOTHERBOARD) { | ||
109 | len += sprintf(buf+len, "Motherboard\n"); | ||
110 | } | ||
111 | if (mca_dev->name[0]) { | ||
112 | |||
113 | /* Drivers might register a name without /proc handler... */ | ||
114 | |||
115 | len += sprintf(buf+len, "Adapter Name: %s\n", | ||
116 | mca_dev->name); | ||
117 | } else { | ||
118 | len += sprintf(buf+len, "Adapter Name: Unknown\n"); | ||
119 | } | ||
120 | len += sprintf(buf+len, "Id: %02x%02x\n", | ||
121 | mca_dev->pos[1], mca_dev->pos[0]); | ||
122 | len += sprintf(buf+len, "Enabled: %s\nPOS: ", | ||
123 | mca_device_status(mca_dev) == MCA_ADAPTER_NORMAL ? | ||
124 | "Yes" : "No"); | ||
125 | for(i=0; i<8; i++) { | ||
126 | len += sprintf(buf+len, "%02x ", mca_dev->pos[i]); | ||
127 | } | ||
128 | len += sprintf(buf+len, "\nDriver Installed: %s", | ||
129 | mca_device_claimed(mca_dev) ? "Yes" : "No"); | ||
130 | buf[len++] = '\n'; | ||
131 | buf[len] = 0; | ||
132 | |||
133 | return len; | ||
134 | } /* mca_default_procfn() */ | ||
135 | |||
136 | static int get_mca_machine_info(char* page, char **start, off_t off, | ||
137 | int count, int *eof, void *data) | ||
138 | { | ||
139 | int len = 0; | ||
140 | |||
141 | len += sprintf(page+len, "Model Id: 0x%x\n", machine_id); | ||
142 | len += sprintf(page+len, "Submodel Id: 0x%x\n", machine_submodel_id); | ||
143 | len += sprintf(page+len, "BIOS Revision: 0x%x\n", BIOS_revision); | ||
144 | |||
145 | if (len <= off+count) *eof = 1; | ||
146 | *start = page + off; | ||
147 | len -= off; | ||
148 | if (len>count) len = count; | ||
149 | if (len<0) len = 0; | ||
150 | return len; | ||
151 | } | ||
152 | |||
153 | static int mca_read_proc(char *page, char **start, off_t off, | ||
154 | int count, int *eof, void *data) | ||
155 | { | ||
156 | struct mca_device *mca_dev = (struct mca_device *)data; | ||
157 | int len = 0; | ||
158 | |||
159 | /* Get the standard info */ | ||
160 | |||
161 | len = mca_default_procfn(page, mca_dev); | ||
162 | |||
163 | /* Do any device-specific processing, if there is any */ | ||
164 | |||
165 | if(mca_dev->procfn) { | ||
166 | len += mca_dev->procfn(page+len, mca_dev->slot, | ||
167 | mca_dev->proc_dev); | ||
168 | } | ||
169 | if (len <= off+count) *eof = 1; | ||
170 | *start = page + off; | ||
171 | len -= off; | ||
172 | if (len>count) len = count; | ||
173 | if (len<0) len = 0; | ||
174 | return len; | ||
175 | } /* mca_read_proc() */ | ||
176 | |||
177 | /*--------------------------------------------------------------------*/ | ||
178 | |||
179 | void __init mca_do_proc_init(void) | ||
180 | { | ||
181 | int i; | ||
182 | struct proc_dir_entry *proc_mca; | ||
183 | struct proc_dir_entry* node = NULL; | ||
184 | struct mca_device *mca_dev; | ||
185 | |||
186 | proc_mca = proc_mkdir("mca", &proc_root); | ||
187 | create_proc_read_entry("pos",0,proc_mca,get_mca_info,NULL); | ||
188 | create_proc_read_entry("machine",0,proc_mca,get_mca_machine_info,NULL); | ||
189 | |||
190 | /* Initialize /proc/mca entries for existing adapters */ | ||
191 | |||
192 | for(i = 0; i < MCA_NUMADAPTERS; i++) { | ||
193 | enum MCA_AdapterStatus status; | ||
194 | mca_dev = mca_find_device_by_slot(i); | ||
195 | if(!mca_dev) | ||
196 | continue; | ||
197 | |||
198 | mca_dev->procfn = NULL; | ||
199 | |||
200 | if(i < MCA_MAX_SLOT_NR) sprintf(mca_dev->procname,"slot%d", i+1); | ||
201 | else if(i == MCA_INTEGVIDEO) sprintf(mca_dev->procname,"video"); | ||
202 | else if(i == MCA_INTEGSCSI) sprintf(mca_dev->procname,"scsi"); | ||
203 | else if(i == MCA_MOTHERBOARD) sprintf(mca_dev->procname,"planar"); | ||
204 | |||
205 | status = mca_device_status(mca_dev); | ||
206 | if (status != MCA_ADAPTER_NORMAL && | ||
207 | status != MCA_ADAPTER_DISABLED) | ||
208 | continue; | ||
209 | |||
210 | node = create_proc_read_entry(mca_dev->procname, 0, proc_mca, | ||
211 | mca_read_proc, (void *)mca_dev); | ||
212 | |||
213 | if(node == NULL) { | ||
214 | printk("Failed to allocate memory for MCA proc-entries!"); | ||
215 | return; | ||
216 | } | ||
217 | } | ||
218 | |||
219 | } /* mca_do_proc_init() */ | ||
220 | |||
221 | /** | ||
222 | * mca_set_adapter_procfn - Set the /proc callback | ||
223 | * @slot: slot to configure | ||
224 | * @procfn: callback function to call for /proc | ||
225 | * @dev: device information passed to the callback | ||
226 | * | ||
227 | * This sets up an information callback for /proc/mca/slot?. The | ||
228 | * function is called with the buffer, slot, and device pointer (or | ||
229 | * some equally informative context information, or nothing, if you | ||
230 | * prefer), and is expected to put useful information into the | ||
231 | * buffer. The adapter name, ID, and POS registers get printed | ||
232 | * before this is called though, so don't do it again. | ||
233 | * | ||
234 | * This should be called with a %NULL @procfn when a module | ||
235 | * unregisters, thus preventing kernel crashes and other such | ||
236 | * nastiness. | ||
237 | */ | ||
238 | |||
239 | void mca_set_adapter_procfn(int slot, MCA_ProcFn procfn, void* proc_dev) | ||
240 | { | ||
241 | struct mca_device *mca_dev = mca_find_device_by_slot(slot); | ||
242 | |||
243 | if(!mca_dev) | ||
244 | return; | ||
245 | |||
246 | mca_dev->procfn = procfn; | ||
247 | mca_dev->proc_dev = proc_dev; | ||
248 | } | ||
249 | EXPORT_SYMBOL(mca_set_adapter_procfn); | ||