]> git.ipfire.org Git - ipfire-2.x.git/blame - src/install+setup/install/pcmcia.c
git-svn-id: http://svn.ipfire.org/svn/ipfire/1.4/source@36 ea5c0bd1-69bd-2848-81d8...
[ipfire-2.x.git] / src / install+setup / install / pcmcia.c
CommitLineData
cd1a2927
MT
1/*\r
2 * PCMCIA bridge device probe\r
3 *\r
4 * This file is part of the IPCop Firewall.\r
5 *\r
6 * IPCop is free software; you can redistribute it and/or modify\r
7 * it under the terms of the GNU General Public License as published by\r
8 * the Free Software Foundation; either version 2 of the License, or\r
9 * (at your option) any later version.\r
10 *\r
11 * IPCop is distributed in the hope that it will be useful,\r
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
14 * GNU General Public License for more details.\r
15 *\r
16 * You should have received a copy of the GNU General Public License\r
17 * along with IPCop; if not, write to the Free Software\r
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
19 *\r
20 * The initial developer of the original code is David A. Hinds\r
21 * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds\r
22 * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.\r
23 *\r
24 * $Id: pcmcia.c,v 1.6.2.4 2005/12/08 02:12:28 franck78 Exp $\r
25 *\r
26 */\r
27\r
28#include "install.h"\r
29#include "pcmcia.h"\r
30\r
31#ifdef __GLIBC__\r
32#include <sys/io.h>\r
33#else\r
34#include <asm/io.h>\r
35#endif\r
36\r
37extern FILE *flog;\r
38extern int modprobe(char *);\r
39\r
40/*====================================================================*/\r
41\r
42typedef struct {\r
43 u_short vendor, device;\r
44 char *modname;\r
45 char *name;\r
46} pci_id_t;\r
47\r
48pci_id_t pci_id[] = {\r
49 { 0x1013, 0x1100, "i82365", "Cirrus Logic CL 6729" },\r
50 { 0x1013, 0x1110, "yenta_socket", "Cirrus Logic PD 6832" },\r
51 { 0x10b3, 0xb106, "yenta_socket", "SMC 34C90" },\r
52 { 0x1180, 0x0465, "yenta_socket", "Ricoh RL5C465" },\r
53 { 0x1180, 0x0466, "yenta_socket", "Ricoh RL5C466" },\r
54 { 0x1180, 0x0475, "yenta_socket", "Ricoh RL5C475" },\r
55 { 0x1180, 0x0476, "yenta_socket", "Ricoh RL5C476" },\r
56 { 0x1180, 0x0477, "yenta_socket", "Ricoh RL5C477" },\r
57 { 0x1180, 0x0478, "yenta_socket", "Ricoh RL5C478" },\r
58 { 0x104c, 0xac12, "yenta_socket", "Texas Instruments PCI1130" }, \r
59 { 0x104c, 0xac13, "yenta_socket", "Texas Instruments PCI1031" }, \r
60 { 0x104c, 0xac15, "yenta_socket", "Texas Instruments PCI1131" }, \r
61 { 0x104c, 0xac1a, "yenta_socket", "Texas Instruments PCI1210" }, \r
62 { 0x104c, 0xac1e, "yenta_socket", "Texas Instruments PCI1211" }, \r
63 { 0x104c, 0xac17, "yenta_socket", "Texas Instruments PCI1220" }, \r
64 { 0x104c, 0xac19, "yenta_socket", "Texas Instruments PCI1221" }, \r
65 { 0x104c, 0xac1c, "yenta_socket", "Texas Instruments PCI1225" }, \r
66 { 0x104c, 0xac16, "yenta_socket", "Texas Instruments PCI1250" }, \r
67 { 0x104c, 0xac1d, "yenta_socket", "Texas Instruments PCI1251A" }, \r
68 { 0x104c, 0xac1f, "yenta_socket", "Texas Instruments PCI1251B" }, \r
69 { 0x104c, 0xac50, "yenta_socket", "Texas Instruments PCI1410" }, \r
70 { 0x104c, 0xac51, "yenta_socket", "Texas Instruments PCI1420" }, \r
71 { 0x104c, 0xac1b, "yenta_socket", "Texas Instruments PCI1450" }, \r
72 { 0x104c, 0xac52, "yenta_socket", "Texas Instruments PCI1451" }, \r
73 { 0x104c, 0xac56, "yenta_socket", "Texas Instruments PCI1510" }, \r
74 { 0x104c, 0xac55, "yenta_socket", "Texas Instruments PCI1520" }, \r
75 { 0x104c, 0xac54, "yenta_socket", "Texas Instruments PCI1620" }, \r
76 { 0x104c, 0xac41, "yenta_socket", "Texas Instruments PCI4410" }, \r
77 { 0x104c, 0xac40, "yenta_socket", "Texas Instruments PCI4450" }, \r
78 { 0x104c, 0xac42, "yenta_socket", "Texas Instruments PCI4451" }, \r
79 { 0x104c, 0xac44, "yenta_socket", "Texas Instruments PCI4510" }, \r
80 { 0x104c, 0xac46, "yenta_socket", "Texas Instruments PCI4520" }, \r
81 { 0x104c, 0xac49, "yenta_socket", "Texas Instruments PCI7410" }, \r
82 { 0x104c, 0xac47, "yenta_socket", "Texas Instruments PCI7510" }, \r
83 { 0x104c, 0xac48, "yenta_socket", "Texas Instruments PCI7610" }, \r
84 { 0x1217, 0x6729, "i82365", "O2 Micro 6729" }, \r
85 { 0x1217, 0x673a, "i82365", "O2 Micro 6730" }, \r
86 { 0x1217, 0x6832, "yenta_socket", "O2 Micro 6832/6833" }, \r
87 { 0x1217, 0x6836, "yenta_socket", "O2 Micro 6836/6860" }, \r
88 { 0x1217, 0x6872, "yenta_socket", "O2 Micro 6812" }, \r
89 { 0x1217, 0x6925, "yenta_socket", "O2 Micro 6922" }, \r
90 { 0x1217, 0x6933, "yenta_socket", "O2 Micro 6933" }, \r
91 { 0x1217, 0x6972, "yenta_socket", "O2 Micro 6912" }, \r
92 { 0x1179, 0x0603, "i82365", "Toshiba ToPIC95-A" }, \r
93 { 0x1179, 0x060a, "yenta_socket", "Toshiba ToPIC95-B" }, \r
94 { 0x1179, 0x060f, "yenta_socket", "Toshiba ToPIC97" }, \r
95 { 0x1179, 0x0617, "yenta_socket", "Toshiba ToPIC100" }, \r
96 { 0x119b, 0x1221, "i82365", "Omega Micro 82C092G" }, \r
97 { 0x8086, 0x1221, "i82092", "Intel 82092AA_0" }, \r
98 { 0x8086, 0x1222, "i82092", "Intel 82092AA_1" }, \r
99 { 0x1524, 0x1211, "yenta_socket", "ENE 1211" },\r
100 { 0x1524, 0x1225, "yenta_socket", "ENE 1225" },\r
101 { 0x1524, 0x1410, "yenta_socket", "ENE 1410" },\r
102 { 0x1524, 0x1420, "yenta_socket", "ENE 1420" },\r
103};\r
104#define PCI_COUNT (sizeof(pci_id)/sizeof(pci_id_t))\r
105\r
106static char * pci_probe()\r
107{\r
108 char s[256], *modname = NULL;\r
109 u_int device, vendor, i;\r
110 FILE *f;\r
111 \r
112 if ((f = fopen("/proc/bus/pci/devices", "r")) != NULL) {\r
113 while (fgets(s, 256, f) != NULL) {\r
114 u_int n = strtoul(s+5, NULL, 16);\r
115 vendor = (n >> 16); device = (n & 0xffff);\r
116 for (i = 0; i < PCI_COUNT; i++)\r
117 if ((vendor == pci_id[i].vendor) &&\r
118 (device == pci_id[i].device)) break;\r
119\r
120 if (i < PCI_COUNT) {\r
121 modname = pci_id[i].modname;\r
122 break;\r
123 }\r
124 }\r
125 }\r
126 \r
127 return modname;\r
128}\r
129\r
130/*====================================================================*/\r
131\r
132#ifndef __alpha__\r
133typedef u_short ioaddr_t;\r
134\r
135static ioaddr_t i365_base = 0x03e0;\r
136\r
137static u_char i365_get(u_short sock, u_short reg)\r
138{\r
139 u_char val = I365_REG(sock, reg);\r
140 outb(val, i365_base); val = inb(i365_base+1);\r
141 return val;\r
142}\r
143\r
144#if 0 // the following code do nothing usefull, it ends with return 0 anyway\r
145\r
146static void i365_set(u_short sock, u_short reg, u_char data)\r
147{\r
148 u_char val = I365_REG(sock, reg);\r
149 outb(val, i365_base); outb(data, i365_base+1);\r
150}\r
151\r
152static void i365_bset(u_short sock, u_short reg, u_char mask)\r
153{\r
154 u_char d = i365_get(sock, reg);\r
155 d |= mask;\r
156 i365_set(sock, reg, d);\r
157}\r
158\r
159static void i365_bclr(u_short sock, u_short reg, u_char mask)\r
160{\r
161 u_char d = i365_get(sock, reg);\r
162 d &= ~mask;\r
163 i365_set(sock, reg, d);\r
164}\r
165#endif\r
166\r
167int i365_probe()\r
168{\r
169 int val, slot, sock, done;\r
170// char *name = "i82365sl";\r
171\r
172 ioperm(i365_base, 4, 1);\r
173 ioperm(0x80, 1, 1);\r
174 for (slot = 0; slot < 2; slot++) {\r
175 for (sock = done = 0; sock < 2; sock++) {\r
176 val = i365_get(sock, I365_IDENT);\r
177 switch (val) {\r
178 case 0x82:\r
179// name = "i82365sl A step";\r
180// break;\r
181 case 0x83:\r
182// name = "i82365sl B step";\r
183// break;\r
184 case 0x84:\r
185// name = "VLSI 82C146";\r
186// break;\r
187 case 0x88: case 0x89: case 0x8a:\r
188// name = "IBM Clone";\r
189// break;\r
190 case 0x8b: case 0x8c:\r
191 break;\r
192 default:\r
193 done = 1;\r
194 }\r
195 if (done) break;\r
196 }\r
197 if (done && sock) break;\r
198 i365_base += 2;\r
199 }\r
200\r
201 if (sock == 0) {\r
202 return -1;\r
203 }\r
204\r
205#if 0 // the following code do nothing usefull, it ends with return 0 anyway\r
206 if ((sock == 2) && (strcmp(name, "VLSI 82C146") == 0))\r
207 name = "i82365sl DF";\r
208\r
209 /* Check for Vadem chips */\r
210 outb(0x0e, i365_base);\r
211 outb(0x37, i365_base);\r
212 i365_bset(0, VG468_MISC, VG468_MISC_VADEMREV);\r
213 val = i365_get(0, I365_IDENT);\r
214 if (val & I365_IDENT_VADEM) {\r
215 if ((val & 7) < 4)\r
216 name = "Vadem VG-468";\r
217 else\r
218 name = "Vadem VG-469";\r
219 i365_bclr(0, VG468_MISC, VG468_MISC_VADEMREV);\r
220 }\r
221 \r
222 /* Check for Cirrus CL-PD67xx chips */\r
223 i365_set(0, PD67_CHIP_INFO, 0);\r
224 val = i365_get(0, PD67_CHIP_INFO);\r
225 if ((val & PD67_INFO_CHIP_ID) == PD67_INFO_CHIP_ID) {\r
226 val = i365_get(0, PD67_CHIP_INFO);\r
227 if ((val & PD67_INFO_CHIP_ID) == 0) {\r
228 if (val & PD67_INFO_SLOTS)\r
229 name = "Cirrus CL-PD672x";\r
230 else {\r
231 name = "Cirrus CL-PD6710";\r
232 sock = 1;\r
233 }\r
234 i365_set(0, PD67_EXT_INDEX, 0xe5);\r
235 if (i365_get(0, PD67_EXT_INDEX) != 0xe5)\r
236 name = "VIA VT83C469";\r
237 }\r
238 }\r
239#endif\r
240 return 0;\r
241 \r
242} /* i365_probe */\r
243#endif\r
244\r
245/*====================================================================*/\r
246\r
247#ifndef __alpha__\r
248static u_short tcic_getw(ioaddr_t base, u_char reg)\r
249{\r
250 u_short val = inw(base+reg);\r
251 return val;\r
252}\r
253\r
254static void tcic_setw(ioaddr_t base, u_char reg, u_short data)\r
255{\r
256 outw(data, base+reg);\r
257}\r
258\r
259int tcic_probe_at(ioaddr_t base)\r
260{\r
261 int i;\r
262 u_short old;\r
263 \r
264 /* Anything there?? */\r
265 for (i = 0; i < 0x10; i += 2)\r
266 if (tcic_getw(base, i) == 0xffff)\r
267 return -1;\r
268\r
269 /* Try to reset the chip */\r
270 tcic_setw(base, TCIC_SCTRL, TCIC_SCTRL_RESET);\r
271 tcic_setw(base, TCIC_SCTRL, 0);\r
272 \r
273 /* Can we set the addr register? */\r
274 old = tcic_getw(base, TCIC_ADDR);\r
275 tcic_setw(base, TCIC_ADDR, 0);\r
276 if (tcic_getw(base, TCIC_ADDR) != 0) {\r
277 tcic_setw(base, TCIC_ADDR, old);\r
278 return -2;\r
279 }\r
280 \r
281 tcic_setw(base, TCIC_ADDR, 0xc3a5);\r
282 if (tcic_getw(base, TCIC_ADDR) != 0xc3a5)\r
283 return -3;\r
284\r
285 return 2;\r
286}\r
287\r
288int tcic_probe(ioaddr_t base)\r
289{\r
290 int sock;\r
291\r
292 ioperm(base, 16, 1);\r
293 ioperm(0x80, 1, 1);\r
294 sock = tcic_probe_at(base);\r
295 \r
296 if (sock <= 0) {\r
297 return -1;\r
298 }\r
299\r
300 return 0;\r
301 \r
302} /* tcic_probe */\r
303#endif\r
304\r
305/*====================================================================*/\r
306char * initialize_pcmcia (void)\r
307{\r
308#ifndef __alpha__\r
309 ioaddr_t tcic_base = TCIC_BASE;\r
310#endif\r
311 char* pcmcia;\r
312 \r
313 if ((pcmcia = pci_probe()))\r
314 return pcmcia; /* we're all done */\r
315#ifndef __alpha__\r
316 else if (i365_probe() == 0)\r
317 return "i82365";\r
318 else if (tcic_probe(tcic_base) == 0)\r
319 return "tcic";\r
320#endif\r
321 else {\r
322 /* Detect ISAPNP based i82365 controllers */\r
323 FILE *f;\r
324 modprobe("i82365");\r
325 if ((f = fopen("/proc/bus/pccard/00/info", "r"))) {\r
326 fclose(f);\r
327 return "i82365";\r
328 }\r
329 }\r
330\r
331 return NULL;\r
332}\r