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