Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.16-rc5 382 lines 10 kB view raw
1/* Copyright (C) 2007 One Stop Systems 2 * Copyright (C) 2003-2005 SBE, Inc. 3 * 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. 8 * 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. 13 */ 14 15#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 16 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 33 34extern int error_flag; 35extern int drvr_state; 36 37/* forward references */ 38void c4_stopwd(ci_t *); 39struct net_device * __init c4_add_dev(hdw_info_t *, int, unsigned long, 40 unsigned long, int, int); 41 42 43struct s_hdw_info hdw_info[MAX_BOARDS]; 44 45 46void __init 47show_two(hdw_info_t *hi, int brdno) 48{ 49 ci_t *ci; 50 struct pci_dev *pdev; 51 char *bid; 52 char banner[80]; 53 char sn[6] = {0,}; 54 55 ci = (ci_t *)(netdev_priv(hi->ndev)); 56 bid = sbeid_get_bdname(ci); 57 switch (hi->promfmt) { 58 case PROM_FORMAT_TYPE1: 59 memcpy(sn, hi->mfg_info.pft1.Serial, 6); 60 break; 61 case PROM_FORMAT_TYPE2: 62 memcpy(sn, hi->mfg_info.pft2.Serial, 6); 63 break; 64 } 65 66 sprintf(banner, "%s: %s S/N %06X, MUSYCC Rev %02X", 67 hi->devname, bid, 68 ((sn[3] << 16) & 0xff0000) | 69 ((sn[4] << 8) & 0x00ff00) | 70 (sn[5] & 0x0000ff), 71 (u_int8_t) hi->revid[0]); 72 73 pr_info("%s\n", banner); 74 75 pdev = hi->pdev[0]; 76 pr_info("%s: %s at v/p=%lx/%lx (%02x:%02x.%x) irq %d\n", 77 hi->devname, "MUSYCC", 78 (unsigned long) hi->addr_mapped[0], hi->addr[0], 79 hi->pci_busno, (u_int8_t) PCI_SLOT(pdev->devfn), 80 (u_int8_t) PCI_FUNC(pdev->devfn), pdev->irq); 81 82 pdev = hi->pdev[1]; 83 pr_info("%s: %s at v/p=%lx/%lx (%02x:%02x.%x) irq %d\n", 84 hi->devname, "EBUS ", 85 (unsigned long) hi->addr_mapped[1], hi->addr[1], 86 hi->pci_busno, (u_int8_t) PCI_SLOT(pdev->devfn), 87 (u_int8_t) PCI_FUNC(pdev->devfn), pdev->irq); 88} 89 90 91void __init 92hdw_sn_get(hdw_info_t *hi, int brdno) 93{ 94 /* obtain hardware EEPROM information */ 95 long addr; 96 97 addr = (long) hi->addr_mapped[1] + EEPROM_OFFSET; 98 99 /* read EEPROM with largest known format size... */ 100 pmc_eeprom_read_buffer(addr, 0, (char *)hi->mfg_info.data, 101 sizeof(FLD_TYPE2)); 102 103#if 0 104 { 105 unsigned char *ucp = (unsigned char *) &hi->mfg_info.data; 106 107 pr_info("eeprom[00]: %02x %02x %02x %02x %02x %02x %02x %02x\n", 108 *(ucp + 0), *(ucp + 1), *(ucp + 2), *(ucp + 3), 109 *(ucp + 4), *(ucp + 5), *(ucp + 6), *(ucp + 7)); 110 pr_info("eeprom[08]: %02x %02x %02x %02x %02x %02x %02x %02x\n", 111 *(ucp + 8), *(ucp + 9), *(ucp + 10), *(ucp + 11), 112 *(ucp + 12), *(ucp + 13), *(ucp + 14), *(ucp + 15)); 113 pr_info("eeprom[16]: %02x %02x %02x %02x %02x %02x %02x %02x\n", 114 *(ucp + 16), *(ucp + 17), *(ucp + 18), *(ucp + 19), 115 *(ucp + 20), *(ucp + 21), *(ucp + 22), *(ucp + 23)); 116 pr_info("eeprom[24]: %02x %02x %02x %02x %02x %02x %02x %02x\n", 117 *(ucp + 24), *(ucp + 25), *(ucp + 26), *(ucp + 27), 118 *(ucp + 28), *(ucp + 29), *(ucp + 30), *(ucp + 31)); 119 pr_info("eeprom[32]: %02x %02x %02x %02x %02x %02x %02x %02x\n", 120 *(ucp + 32), *(ucp + 33), *(ucp + 34), *(ucp + 35), 121 *(ucp + 36), *(ucp + 37), *(ucp + 38), *(ucp + 39)); 122 pr_info("eeprom[40]: %02x %02x %02x %02x %02x %02x %02x %02x\n", 123 *(ucp + 40), *(ucp + 41), *(ucp + 42), *(ucp + 43), 124 *(ucp + 44), *(ucp + 45), *(ucp + 46), *(ucp + 47)); 125 } 126#endif 127#if 0 128 pr_info("sn: %x %x %x %x %x %x\n", 129 hi->mfg_info.Serial[0], 130 hi->mfg_info.Serial[1], 131 hi->mfg_info.Serial[2], 132 hi->mfg_info.Serial[3], 133 hi->mfg_info.Serial[4], 134 hi->mfg_info.Serial[5]); 135#endif 136 137 hi->promfmt = pmc_verify_cksum(&hi->mfg_info.data); 138 if (hi->promfmt == PROM_FORMAT_Unk) { 139 /* bad crc, data is suspect */ 140 if (cxt1e1_log_level >= LOG_WARN) 141 pr_info("%s: EEPROM cksum error\n", hi->devname); 142 hi->mfg_info_sts = EEPROM_CRCERR; 143 } else 144 hi->mfg_info_sts = EEPROM_OK; 145} 146 147 148 void __init 149prep_hdw_info(void) 150{ 151 hdw_info_t *hi; 152 int i; 153 154 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) { 155 hi->pci_busno = 0xff; 156 hi->pci_slot = 0xff; 157 hi->pci_pin[0] = 0; 158 hi->pci_pin[1] = 0; 159 hi->ndev = NULL; 160 hi->addr[0] = 0L; 161 hi->addr[1] = 0L; 162 hi->addr_mapped[0] = NULL; 163 hi->addr_mapped[1] = NULL; 164 } 165} 166 167void 168cleanup_ioremap(void) 169{ 170 hdw_info_t *hi; 171 int i; 172 173 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) { 174 if (hi->pci_slot == 0xff) 175 break; 176 if (hi->addr_mapped[0]) { 177 iounmap(hi->addr_mapped[0]); 178 release_mem_region((long) hi->addr[0], hi->len[0]); 179 hi->addr_mapped[0] = NULL; 180 } 181 if (hi->addr_mapped[1]) { 182 iounmap(hi->addr_mapped[1]); 183 release_mem_region((long) hi->addr[1], hi->len[1]); 184 hi->addr_mapped[1] = NULL; 185 } 186 } 187} 188 189 190void 191cleanup_devs(void) 192{ 193 hdw_info_t *hi; 194 int i; 195 196 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) { 197 if (hi->pci_slot == 0xff || !hi->ndev) 198 break; 199 c4_stopwd(netdev_priv(hi->ndev)); 200#ifdef CONFIG_PROC_FS 201 sbecom_proc_brd_cleanup(netdev_priv(hi->ndev)); 202#endif 203 unregister_netdev(hi->ndev); 204 free_irq(hi->pdev[0]->irq, hi->ndev); 205#ifdef CONFIG_SBE_PMCC4_NCOMM 206 free_irq(hi->pdev[1]->irq, hi->ndev); 207#endif 208 kfree(hi->ndev); 209 } 210} 211 212 213static int __init 214c4_hdw_init(struct pci_dev *pdev, int found) 215{ 216 hdw_info_t *hi; 217 int i; 218 int fun, slot; 219 unsigned char busno = 0xff; 220 221 /* our MUSYCC chip supports two functions, 0 & 1 */ 222 fun = PCI_FUNC(pdev->devfn); 223 if (fun > 1) { 224 pr_warning("unexpected devfun: 0x%x\n", pdev->devfn); 225 return 0; 226 } 227 228 /* obtain bus number */ 229 if (pdev->bus) 230 busno = pdev->bus->number; 231 else 232 busno = 0; /* default for system PCI inconsistency */ 233 slot = pdev->devfn & ~0x07; 234 235 /* 236 * Functions 0 & 1 for a given board (identified by same bus(busno) and 237 * slot(slot)) are placed into the same 'hardware' structure. The first 238 * part of the board's functionality will be placed into an unpopulated 239 * element, identified by "slot==(0xff)". The second part of a board's 240 * functionality will match the previously loaded slot/busno. 241 */ 242 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) { 243 /* 244 * match with board's first found interface, otherwise this is 245 * fisrt found 246 */ 247 if ((hi->pci_slot == 0xff) || /* new board */ 248 ((hi->pci_slot == slot) && (hi->bus == pdev->bus))) 249 break; /* found for-loop exit */ 250 } 251 252 /* no match in above loop means MAX exceeded */ 253 if (i == MAX_BOARDS) { 254 pr_warning("exceeded number of allowed devices (>%d)?\n", 255 MAX_BOARDS); 256 return 0; 257 } 258 259 if (pdev->bus) 260 hi->pci_busno = pdev->bus->number; 261 else 262 hi->pci_busno = 0; /* default for system PCI inconsistency */ 263 264 hi->pci_slot = slot; 265 pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &hi->pci_pin[fun]); 266 pci_read_config_byte(pdev, PCI_REVISION_ID, &hi->revid[fun]); 267 hi->bus = pdev->bus; 268 hi->addr[fun] = pci_resource_start(pdev, 0); 269 hi->len[fun] = pci_resource_end(pdev, 0) - hi->addr[fun] + 1; 270 hi->pdev[fun] = pdev; 271 272 { 273 /* 274 * create device name from module name, plus add the appropriate 275 * board number 276 */ 277 char *cp = hi->devname; 278 279 strcpy(cp, KBUILD_MODNAME); 280 cp += strlen(cp); /* reposition */ 281 *cp++ = '-'; 282 *cp++ = '0' + (found / 2); /* there are two found interfaces per 283 * board */ 284 *cp = 0; /* termination */ 285 } 286 287 return 1; 288} 289 290status_t __init 291c4hw_attach_all(void) 292{ 293 hdw_info_t *hi; 294 struct pci_dev *pdev = NULL; 295 int found = 0, i, j; 296 297 error_flag = 0; 298 prep_hdw_info(); 299 /*** scan PCI bus for all possible boards */ 300 while ((pdev = pci_get_device(PCI_VENDOR_ID_CONEXANT, 301 PCI_DEVICE_ID_CN8474, 302 pdev))) { 303 if (c4_hdw_init(pdev, found)) 304 found++; 305 } 306 307 if (!found) { 308 pr_warning("No boards found\n"); 309 return -ENODEV; 310 } 311 312 /* sanity check for consistent hardware found */ 313 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) { 314 if (hi->pci_slot != 0xff && (!hi->addr[0] || !hi->addr[1])) { 315 pr_warning("%s: something very wrong with pci_get_device\n", 316 hi->devname); 317 return -EIO; 318 } 319 } 320 /* bring board's memory regions on/line */ 321 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) { 322 if (hi->pci_slot == 0xff) 323 break; 324 for (j = 0; j < 2; j++) { 325 if (!request_mem_region(hi->addr[j], hi->len[j], hi->devname)) { 326 pr_warning("%s: memory in use, addr=0x%lx, len=0x%lx ?\n", 327 hi->devname, hi->addr[j], hi->len[j]); 328 cleanup_ioremap(); 329 return -ENOMEM; 330 } 331 332 hi->addr_mapped[j] = ioremap(hi->addr[j], hi->len[j]); 333 if (!hi->addr_mapped[j]) { 334 pr_warning("%s: ioremap fails, addr=0x%lx, len=0x%lx ?\n", 335 hi->devname, hi->addr[j], hi->len[j]); 336 cleanup_ioremap(); 337 return -ENOMEM; 338 } 339#ifdef SBE_MAP_DEBUG 340 pr_warning("%s: io remapped from phys %x to virt %x\n", 341 hi->devname, (u_int32_t) hi->addr[j], 342 (u_int32_t) hi->addr_mapped[j]); 343#endif 344 } 345 } 346 347 drvr_state = SBE_DRVR_AVAILABLE; 348 349 /* Have now memory mapped all boards. Now allow board's access to system */ 350 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) { 351 if (hi->pci_slot == 0xff) 352 break; 353 if (pci_enable_device(hi->pdev[0]) || 354 pci_enable_device(hi->pdev[1])) { 355 drvr_state = SBE_DRVR_DOWN; 356 pr_warning("%s: failed to enable card %d slot %d\n", 357 hi->devname, i, hi->pci_slot); 358 cleanup_devs(); 359 cleanup_ioremap(); 360 return -EIO; 361 } 362 pci_set_master(hi->pdev[0]); 363 pci_set_master(hi->pdev[1]); 364 hi->ndev = c4_add_dev(hi, i, (long) hi->addr_mapped[0], 365 (long) hi->addr_mapped[1], 366 hi->pdev[0]->irq, 367 hi->pdev[1]->irq); 368 if (!hi->ndev) { 369 drvr_state = SBE_DRVR_DOWN; 370 cleanup_ioremap(); 371 /* NOTE: c4_add_dev() does its own device cleanup */ 372#if 0 373 cleanup_devs(); 374#endif 375 return error_flag; /* error_flag set w/in add_dev() */ 376 } 377 show_two(hi, i); /* displays found information */ 378 } 379 return 0; 380} 381 382/*** End-of-File ***/