GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / cxt1e1 / hwprobe.c
blob6138cd071bb2a4ce9fd3e24b0fcfbc7cfb194fbd
1 /* Copyright (C) 2007 One Stop Systems
2 * Copyright (C) 2003-2005 SBE, Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17 #include <linux/netdevice.h>
18 #include <linux/hdlc.h>
19 #include <linux/if_arp.h>
20 #include <asm/uaccess.h>
21 #include <linux/rtnetlink.h>
22 #include <linux/pci.h>
23 #include "pmcc4_sysdep.h"
24 #include "sbecom_inline_linux.h"
25 #include "libsbew.h"
26 #include "pmcc4_private.h"
27 #include "pmcc4.h"
28 #include "pmcc4_ioctls.h"
29 #include "pmc93x6_eeprom.h"
30 #ifdef CONFIG_PROC_FS
31 #include "sbeproc.h"
32 #endif
34 #ifdef SBE_INCLUDE_SYMBOLS
35 #define STATIC
36 #else
37 #define STATIC static
38 #endif
40 extern int log_level;
41 extern int error_flag;
42 extern int drvr_state;
44 /* forward references */
45 void c4_stopwd (ci_t *);
46 struct net_device * __init c4_add_dev (hdw_info_t *, int, unsigned long, unsigned long, int, int);
49 struct s_hdw_info hdw_info[MAX_BOARDS];
52 void __init
53 show_two (hdw_info_t * hi, int brdno)
55 ci_t *ci;
56 struct pci_dev *pdev;
57 char *bid;
58 char *bp, banner[80];
59 char sn[6];
61 bp = banner;
62 memset (banner, 0, 80); /* clear print buffer */
64 ci = (ci_t *)(netdev_priv(hi->ndev));
65 bid = sbeid_get_bdname (ci);
66 switch (hi->promfmt)
68 case PROM_FORMAT_TYPE1:
69 memcpy (sn, (FLD_TYPE1 *) (hi->mfg_info.pft1.Serial), 6);
70 break;
71 case PROM_FORMAT_TYPE2:
72 memcpy (sn, (FLD_TYPE2 *) (hi->mfg_info.pft2.Serial), 6);
73 break;
74 default:
75 memset (sn, 0, 6);
76 break;
79 sprintf (banner, "%s: %s S/N %06X, MUSYCC Rev %02X",
80 hi->devname, bid,
81 ((sn[3] << 16) & 0xff0000) |
82 ((sn[4] << 8) & 0x00ff00) |
83 (sn[5] & 0x0000ff),
84 (u_int8_t) hi->revid[0]);
86 pr_info("%s\n", banner);
88 pdev = hi->pdev[0];
89 pr_info("%s: %s at v/p=%lx/%lx (%02x:%02x.%x) irq %d\n",
90 hi->devname, "MUSYCC",
91 (unsigned long) hi->addr_mapped[0], hi->addr[0],
92 hi->pci_busno, (u_int8_t) PCI_SLOT (pdev->devfn),
93 (u_int8_t) PCI_FUNC (pdev->devfn), pdev->irq);
95 pdev = hi->pdev[1];
96 pr_info("%s: %s at v/p=%lx/%lx (%02x:%02x.%x) irq %d\n",
97 hi->devname, "EBUS ",
98 (unsigned long) hi->addr_mapped[1], hi->addr[1],
99 hi->pci_busno, (u_int8_t) PCI_SLOT (pdev->devfn),
100 (u_int8_t) PCI_FUNC (pdev->devfn), pdev->irq);
104 void __init
105 hdw_sn_get (hdw_info_t * hi, int brdno)
107 /* obtain hardware EEPROM information */
108 long addr;
110 addr = (long) hi->addr_mapped[1] + EEPROM_OFFSET;
112 /* read EEPROM with largest known format size... */
113 pmc_eeprom_read_buffer (addr, 0, (char *) hi->mfg_info.data, sizeof (FLD_TYPE2));
116 if ((hi->promfmt = pmc_verify_cksum (&hi->mfg_info.data)) == PROM_FORMAT_Unk)
118 /* bad crc, data is suspect */
119 if (log_level >= LOG_WARN)
120 pr_info("%s: EEPROM cksum error\n", hi->devname);
121 hi->mfg_info_sts = EEPROM_CRCERR;
122 } else
123 hi->mfg_info_sts = EEPROM_OK;
127 void __init
128 prep_hdw_info (void)
130 hdw_info_t *hi;
131 int i;
133 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
135 hi->pci_busno = 0xff;
136 hi->pci_slot = 0xff;
137 hi->pci_pin[0] = 0;
138 hi->pci_pin[1] = 0;
139 hi->ndev = 0;
140 hi->addr[0] = 0L;
141 hi->addr[1] = 0L;
142 hi->addr_mapped[0] = 0L;
143 hi->addr_mapped[1] = 0L;
147 void
148 cleanup_ioremap (void)
150 hdw_info_t *hi;
151 int i;
153 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
155 if (hi->pci_slot == 0xff)
156 break;
157 if (hi->addr_mapped[0])
159 iounmap ((void *) (hi->addr_mapped[0]));
160 release_mem_region ((long) hi->addr[0], hi->len[0]);
161 hi->addr_mapped[0] = 0;
163 if (hi->addr_mapped[1])
165 iounmap ((void *) (hi->addr_mapped[1]));
166 release_mem_region ((long) hi->addr[1], hi->len[1]);
167 hi->addr_mapped[1] = 0;
173 void
174 cleanup_devs (void)
176 hdw_info_t *hi;
177 int i;
179 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
181 if (hi->pci_slot == 0xff || !hi->ndev)
182 break;
183 c4_stopwd(netdev_priv(hi->ndev));
184 #ifdef CONFIG_PROC_FS
185 sbecom_proc_brd_cleanup(netdev_priv(hi->ndev));
186 #endif
187 unregister_netdev (hi->ndev);
188 free_irq (hi->pdev[0]->irq, hi->ndev);
189 #ifdef CONFIG_SBE_PMCC4_NCOMM
190 free_irq (hi->pdev[1]->irq, hi->ndev);
191 #endif
192 OS_kfree (hi->ndev);
197 STATIC int __init
198 c4_hdw_init (struct pci_dev * pdev, int found)
200 hdw_info_t *hi;
201 int i;
202 int fun, slot;
203 unsigned char busno = 0xff;
205 /* our MUSYCC chip supports two functions, 0 & 1 */
206 if ((fun = PCI_FUNC (pdev->devfn)) > 1)
208 pr_warning("unexpected devfun: 0x%x\n", pdev->devfn);
209 return 0;
211 if (pdev->bus) /* obtain bus number */
212 busno = pdev->bus->number;
213 else
214 busno = 0; /* default for system PCI inconsistency */
215 slot = pdev->devfn & ~0x07;
218 * Functions 0 & 1 for a given board (identified by same bus(busno) and
219 * slot(slot)) are placed into the same 'hardware' structure. The first
220 * part of the board's functionality will be placed into an unpopulated
221 * element, identified by "slot==(0xff)". The second part of a board's
222 * functionality will match the previously loaded slot/busno.
224 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
227 * match with board's first found interface, otherwise this is first
228 * found
230 if ((hi->pci_slot == 0xff) || /* new board */
231 ((hi->pci_slot == slot) && (hi->bus == pdev->bus)))
232 break; /* found for-loop exit */
234 if (i == MAX_BOARDS) /* no match in above loop means MAX
235 * exceeded */
237 pr_warning("exceeded number of allowed devices (>%d)?\n", MAX_BOARDS);
238 return 0;
240 if (pdev->bus)
241 hi->pci_busno = pdev->bus->number;
242 else
243 hi->pci_busno = 0; /* default for system PCI inconsistency */
244 hi->pci_slot = slot;
245 pci_read_config_byte (pdev, PCI_INTERRUPT_PIN, &hi->pci_pin[fun]);
246 pci_read_config_byte (pdev, PCI_REVISION_ID, &hi->revid[fun]);
247 hi->bus = pdev->bus;
248 hi->addr[fun] = pci_resource_start (pdev, 0);
249 hi->len[fun] = pci_resource_end (pdev, 0) - hi->addr[fun] + 1;
250 hi->pdev[fun] = pdev;
254 * create device name from module name, plus add the appropriate
255 * board number
257 char *cp = hi->devname;
259 strcpy (cp, KBUILD_MODNAME);
260 cp += strlen (cp); /* reposition */
261 *cp++ = '-';
262 *cp++ = '0' + (found / 2); /* there are two found interfaces per
263 * board */
264 *cp = 0; /* termination */
267 return 1;
271 status_t __init
272 c4hw_attach_all (void)
274 hdw_info_t *hi;
275 struct pci_dev *pdev = NULL;
276 int found = 0, i, j;
278 error_flag = 0;
279 prep_hdw_info ();
280 /*** scan PCI bus for all possible boards */
281 while ((pdev = pci_get_device (PCI_VENDOR_ID_CONEXANT,
282 PCI_DEVICE_ID_CN8474,
283 pdev)))
285 if (c4_hdw_init (pdev, found))
286 found++;
288 if (!found)
290 pr_warning("No boards found\n");
291 return ENODEV;
293 /* sanity check for consistant hardware found */
294 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
296 if (hi->pci_slot != 0xff && (!hi->addr[0] || !hi->addr[1]))
298 pr_warning("%s: something very wrong with pci_get_device\n",
299 hi->devname);
300 return EIO;
303 /* bring board's memory regions on/line */
304 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
306 if (hi->pci_slot == 0xff)
307 break;
308 for (j = 0; j < 2; j++)
310 if (request_mem_region (hi->addr[j], hi->len[j], hi->devname) == 0)
312 pr_warning("%s: memory in use, addr=0x%lx, len=0x%lx ?\n",
313 hi->devname, hi->addr[j], hi->len[j]);
314 cleanup_ioremap ();
315 return ENOMEM;
317 hi->addr_mapped[j] = (unsigned long) ioremap (hi->addr[j], hi->len[j]);
318 if (!hi->addr_mapped[j])
320 pr_warning("%s: ioremap fails, addr=0x%lx, len=0x%lx ?\n",
321 hi->devname, hi->addr[j], hi->len[j]);
322 cleanup_ioremap ();
323 return ENOMEM;
325 #ifdef SBE_MAP_DEBUG
326 pr_warning("%s: io remapped from phys %x to virt %x\n",
327 hi->devname, (u_int32_t) hi->addr[j], (u_int32_t) hi->addr_mapped[j]);
328 #endif
332 drvr_state = SBE_DRVR_AVAILABLE;
334 /* Have now memory mapped all boards. Now allow board's access to system */
335 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
337 if (hi->pci_slot == 0xff)
338 break;
339 if (pci_enable_device (hi->pdev[0]) ||
340 pci_enable_device (hi->pdev[1]))
342 drvr_state = SBE_DRVR_DOWN;
343 pr_warning("%s: failed to enable card %d slot %d\n",
344 hi->devname, i, hi->pci_slot);
345 cleanup_devs ();
346 cleanup_ioremap ();
347 return EIO;
349 pci_set_master (hi->pdev[0]);
350 pci_set_master (hi->pdev[1]);
351 if (!(hi->ndev = c4_add_dev (hi, i, (long) hi->addr_mapped[0],
352 (long) hi->addr_mapped[1],
353 hi->pdev[0]->irq,
354 hi->pdev[1]->irq)))
356 drvr_state = SBE_DRVR_DOWN;
357 cleanup_ioremap ();
358 /* NOTE: c4_add_dev() does its own device cleanup */
359 return error_flag; /* error_flag set w/in add_dev() */
361 show_two (hi, i); /* displays found information */
363 return 0;
366 /*** End-of-File ***/