root/drivers/net/arcnet/com20020-pci.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. led_tx_set
  2. led_recon_set
  3. backplane_mode_show
  4. com20020pci_probe
  5. com20020pci_remove
  6. com20020pci_init
  7. com20020pci_cleanup

   1 /*
   2  * Linux ARCnet driver - COM20020 PCI support
   3  * Contemporary Controls PCI20 and SOHARD SH-ARC PCI
   4  *
   5  * Written 1994-1999 by Avery Pennarun,
   6  *    based on an ISA version by David Woodhouse.
   7  * Written 1999-2000 by Martin Mares <mj@ucw.cz>.
   8  * Derived from skeleton.c by Donald Becker.
   9  *
  10  * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
  11  *  for sponsoring the further development of this driver.
  12  *
  13  * **********************
  14  *
  15  * The original copyright of skeleton.c was as follows:
  16  *
  17  * skeleton.c Written 1993 by Donald Becker.
  18  * Copyright 1993 United States Government as represented by the
  19  * Director, National Security Agency.  This software may only be used
  20  * and distributed according to the terms of the GNU General Public License as
  21  * modified by SRC, incorporated herein by reference.
  22  *
  23  * **********************
  24  *
  25  * For more details, see drivers/net/arcnet.c
  26  *
  27  * **********************
  28  */
  29 
  30 #define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
  31 
  32 #include <linux/module.h>
  33 #include <linux/moduleparam.h>
  34 #include <linux/kernel.h>
  35 #include <linux/types.h>
  36 #include <linux/ioport.h>
  37 #include <linux/errno.h>
  38 #include <linux/netdevice.h>
  39 #include <linux/init.h>
  40 #include <linux/interrupt.h>
  41 #include <linux/pci.h>
  42 #include <linux/list.h>
  43 #include <linux/io.h>
  44 #include <linux/leds.h>
  45 
  46 #include "arcdevice.h"
  47 #include "com20020.h"
  48 
  49 /* Module parameters */
  50 
  51 static int node;
  52 static char device[9];          /* use eg. device="arc1" to change name */
  53 static int timeout = 3;
  54 static int backplane;
  55 static int clockp;
  56 static int clockm;
  57 
  58 module_param(node, int, 0);
  59 module_param_string(device, device, sizeof(device), 0);
  60 module_param(timeout, int, 0);
  61 module_param(backplane, int, 0);
  62 module_param(clockp, int, 0);
  63 module_param(clockm, int, 0);
  64 MODULE_LICENSE("GPL");
  65 
  66 static void led_tx_set(struct led_classdev *led_cdev,
  67                              enum led_brightness value)
  68 {
  69         struct com20020_dev *card;
  70         struct com20020_priv *priv;
  71         struct com20020_pci_card_info *ci;
  72 
  73         card = container_of(led_cdev, struct com20020_dev, tx_led);
  74 
  75         priv = card->pci_priv;
  76         ci = priv->ci;
  77 
  78         outb(!!value, priv->misc + ci->leds[card->index].green);
  79 }
  80 
  81 static void led_recon_set(struct led_classdev *led_cdev,
  82                              enum led_brightness value)
  83 {
  84         struct com20020_dev *card;
  85         struct com20020_priv *priv;
  86         struct com20020_pci_card_info *ci;
  87 
  88         card = container_of(led_cdev, struct com20020_dev, recon_led);
  89 
  90         priv = card->pci_priv;
  91         ci = priv->ci;
  92 
  93         outb(!!value, priv->misc + ci->leds[card->index].red);
  94 }
  95 
  96 static ssize_t backplane_mode_show(struct device *dev,
  97                                    struct device_attribute *attr,
  98                                    char *buf)
  99 {
 100         struct net_device *net_dev = to_net_dev(dev);
 101         struct arcnet_local *lp = netdev_priv(net_dev);
 102 
 103         return sprintf(buf, "%s\n", lp->backplane ? "true" : "false");
 104 }
 105 static DEVICE_ATTR_RO(backplane_mode);
 106 
 107 static struct attribute *com20020_state_attrs[] = {
 108         &dev_attr_backplane_mode.attr,
 109         NULL,
 110 };
 111 
 112 static const struct attribute_group com20020_state_group = {
 113         .name = NULL,
 114         .attrs = com20020_state_attrs,
 115 };
 116 
 117 static void com20020pci_remove(struct pci_dev *pdev);
 118 
 119 static int com20020pci_probe(struct pci_dev *pdev,
 120                              const struct pci_device_id *id)
 121 {
 122         struct com20020_pci_card_info *ci;
 123         struct com20020_pci_channel_map *mm;
 124         struct net_device *dev;
 125         struct arcnet_local *lp;
 126         struct com20020_priv *priv;
 127         int i, ioaddr, ret;
 128         struct resource *r;
 129 
 130         if (pci_enable_device(pdev))
 131                 return -EIO;
 132 
 133         priv = devm_kzalloc(&pdev->dev, sizeof(struct com20020_priv),
 134                             GFP_KERNEL);
 135         if (!priv)
 136                 return -ENOMEM;
 137 
 138         ci = (struct com20020_pci_card_info *)id->driver_data;
 139         priv->ci = ci;
 140         mm = &ci->misc_map;
 141 
 142         INIT_LIST_HEAD(&priv->list_dev);
 143 
 144         if (mm->size) {
 145                 ioaddr = pci_resource_start(pdev, mm->bar) + mm->offset;
 146                 r = devm_request_region(&pdev->dev, ioaddr, mm->size,
 147                                         "com20020-pci");
 148                 if (!r) {
 149                         pr_err("IO region %xh-%xh already allocated.\n",
 150                                ioaddr, ioaddr + mm->size - 1);
 151                         return -EBUSY;
 152                 }
 153                 priv->misc = ioaddr;
 154         }
 155 
 156         for (i = 0; i < ci->devcount; i++) {
 157                 struct com20020_pci_channel_map *cm = &ci->chan_map_tbl[i];
 158                 struct com20020_dev *card;
 159                 int dev_id_mask = 0xf;
 160 
 161                 dev = alloc_arcdev(device);
 162                 if (!dev) {
 163                         ret = -ENOMEM;
 164                         goto out_port;
 165                 }
 166                 dev->dev_port = i;
 167 
 168                 dev->netdev_ops = &com20020_netdev_ops;
 169 
 170                 lp = netdev_priv(dev);
 171 
 172                 arc_printk(D_NORMAL, dev, "%s Controls\n", ci->name);
 173                 ioaddr = pci_resource_start(pdev, cm->bar) + cm->offset;
 174 
 175                 r = devm_request_region(&pdev->dev, ioaddr, cm->size,
 176                                         "com20020-pci");
 177                 if (!r) {
 178                         pr_err("IO region %xh-%xh already allocated\n",
 179                                ioaddr, ioaddr + cm->size - 1);
 180                         ret = -EBUSY;
 181                         goto out_port;
 182                 }
 183 
 184                 /* Dummy access after Reset
 185                  * ARCNET controller needs
 186                  * this access to detect bustype
 187                  */
 188                 arcnet_outb(0x00, ioaddr, COM20020_REG_W_COMMAND);
 189                 arcnet_inb(ioaddr, COM20020_REG_R_DIAGSTAT);
 190 
 191                 SET_NETDEV_DEV(dev, &pdev->dev);
 192                 dev->base_addr = ioaddr;
 193                 dev->dev_addr[0] = node;
 194                 dev->sysfs_groups[0] = &com20020_state_group;
 195                 dev->irq = pdev->irq;
 196                 lp->card_name = "PCI COM20020";
 197                 lp->card_flags = ci->flags;
 198                 lp->backplane = backplane;
 199                 lp->clockp = clockp & 7;
 200                 lp->clockm = clockm & 3;
 201                 lp->timeout = timeout;
 202                 lp->hw.owner = THIS_MODULE;
 203 
 204                 lp->backplane = (inb(priv->misc) >> (2 + i)) & 0x1;
 205 
 206                 if (!strncmp(ci->name, "EAE PLX-PCI FB2", 15))
 207                         lp->backplane = 1;
 208 
 209                 /* Get the dev_id from the PLX rotary coder */
 210                 if (!strncmp(ci->name, "EAE PLX-PCI MA1", 15))
 211                         dev_id_mask = 0x3;
 212                 dev->dev_id = (inb(priv->misc + ci->rotary) >> 4) & dev_id_mask;
 213 
 214                 snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i);
 215 
 216                 if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) {
 217                         pr_err("IO address %Xh is empty!\n", ioaddr);
 218                         ret = -EIO;
 219                         goto out_port;
 220                 }
 221                 if (com20020_check(dev)) {
 222                         ret = -EIO;
 223                         goto out_port;
 224                 }
 225 
 226                 card = devm_kzalloc(&pdev->dev, sizeof(struct com20020_dev),
 227                                     GFP_KERNEL);
 228                 if (!card) {
 229                         ret = -ENOMEM;
 230                         goto out_port;
 231                 }
 232 
 233                 card->index = i;
 234                 card->pci_priv = priv;
 235                 card->tx_led.brightness_set = led_tx_set;
 236                 card->tx_led.default_trigger = devm_kasprintf(&pdev->dev,
 237                                                 GFP_KERNEL, "arc%d-%d-tx",
 238                                                 dev->dev_id, i);
 239                 card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
 240                                                 "pci:green:tx:%d-%d",
 241                                                 dev->dev_id, i);
 242 
 243                 card->tx_led.dev = &dev->dev;
 244                 card->recon_led.brightness_set = led_recon_set;
 245                 card->recon_led.default_trigger = devm_kasprintf(&pdev->dev,
 246                                                 GFP_KERNEL, "arc%d-%d-recon",
 247                                                 dev->dev_id, i);
 248                 card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
 249                                                 "pci:red:recon:%d-%d",
 250                                                 dev->dev_id, i);
 251                 card->recon_led.dev = &dev->dev;
 252                 card->dev = dev;
 253 
 254                 ret = devm_led_classdev_register(&pdev->dev, &card->tx_led);
 255                 if (ret)
 256                         goto out_port;
 257 
 258                 ret = devm_led_classdev_register(&pdev->dev, &card->recon_led);
 259                 if (ret)
 260                         goto out_port;
 261 
 262                 dev_set_drvdata(&dev->dev, card);
 263 
 264                 ret = com20020_found(dev, IRQF_SHARED);
 265                 if (ret)
 266                         goto out_port;
 267 
 268                 devm_arcnet_led_init(dev, dev->dev_id, i);
 269 
 270                 list_add(&card->list, &priv->list_dev);
 271         }
 272 
 273         pci_set_drvdata(pdev, priv);
 274 
 275         return 0;
 276 
 277 out_port:
 278         com20020pci_remove(pdev);
 279         return ret;
 280 }
 281 
 282 static void com20020pci_remove(struct pci_dev *pdev)
 283 {
 284         struct com20020_dev *card, *tmpcard;
 285         struct com20020_priv *priv;
 286 
 287         priv = pci_get_drvdata(pdev);
 288 
 289         list_for_each_entry_safe(card, tmpcard, &priv->list_dev, list) {
 290                 struct net_device *dev = card->dev;
 291 
 292                 unregister_netdev(dev);
 293                 free_irq(dev->irq, dev);
 294                 free_netdev(dev);
 295         }
 296 }
 297 
 298 static struct com20020_pci_card_info card_info_10mbit = {
 299         .name = "ARC-PCI",
 300         .devcount = 1,
 301         .chan_map_tbl = {
 302                 {
 303                         .bar = 2,
 304                         .offset = 0x00,
 305                         .size = 0x08,
 306                 },
 307         },
 308         .flags = ARC_CAN_10MBIT,
 309 };
 310 
 311 static struct com20020_pci_card_info card_info_5mbit = {
 312         .name = "ARC-PCI",
 313         .devcount = 1,
 314         .chan_map_tbl = {
 315                 {
 316                         .bar = 2,
 317                         .offset = 0x00,
 318                         .size = 0x08,
 319                 },
 320         },
 321         .flags = ARC_IS_5MBIT,
 322 };
 323 
 324 static struct com20020_pci_card_info card_info_sohard = {
 325         .name = "PLX-PCI",
 326         .devcount = 1,
 327         /* SOHARD needs PCI base addr 4 */
 328         .chan_map_tbl = {
 329                 {
 330                         .bar = 4,
 331                         .offset = 0x00,
 332                         .size = 0x08
 333                 },
 334         },
 335         .flags = ARC_CAN_10MBIT,
 336 };
 337 
 338 static struct com20020_pci_card_info card_info_eae_arc1 = {
 339         .name = "EAE PLX-PCI ARC1",
 340         .devcount = 1,
 341         .chan_map_tbl = {
 342                 {
 343                         .bar = 2,
 344                         .offset = 0x00,
 345                         .size = 0x08,
 346                 },
 347         },
 348         .misc_map = {
 349                 .bar = 2,
 350                 .offset = 0x10,
 351                 .size = 0x04,
 352         },
 353         .leds = {
 354                 {
 355                         .green = 0x0,
 356                         .red = 0x1,
 357                 },
 358         },
 359         .rotary = 0x0,
 360         .flags = ARC_CAN_10MBIT,
 361 };
 362 
 363 static struct com20020_pci_card_info card_info_eae_ma1 = {
 364         .name = "EAE PLX-PCI MA1",
 365         .devcount = 2,
 366         .chan_map_tbl = {
 367                 {
 368                         .bar = 2,
 369                         .offset = 0x00,
 370                         .size = 0x08,
 371                 }, {
 372                         .bar = 2,
 373                         .offset = 0x08,
 374                         .size = 0x08,
 375                 }
 376         },
 377         .misc_map = {
 378                 .bar = 2,
 379                 .offset = 0x10,
 380                 .size = 0x04,
 381         },
 382         .leds = {
 383                 {
 384                         .green = 0x0,
 385                         .red = 0x1,
 386                 }, {
 387                         .green = 0x2,
 388                         .red = 0x3,
 389                 },
 390         },
 391         .rotary = 0x0,
 392         .flags = ARC_CAN_10MBIT,
 393 };
 394 
 395 static struct com20020_pci_card_info card_info_eae_fb2 = {
 396         .name = "EAE PLX-PCI FB2",
 397         .devcount = 1,
 398         .chan_map_tbl = {
 399                 {
 400                         .bar = 2,
 401                         .offset = 0x00,
 402                         .size = 0x08,
 403                 },
 404         },
 405         .misc_map = {
 406                 .bar = 2,
 407                 .offset = 0x10,
 408                 .size = 0x04,
 409         },
 410         .leds = {
 411                 {
 412                         .green = 0x0,
 413                         .red = 0x1,
 414                 },
 415         },
 416         .rotary = 0x0,
 417         .flags = ARC_CAN_10MBIT,
 418 };
 419 
 420 static const struct pci_device_id com20020pci_id_table[] = {
 421         {
 422                 0x1571, 0xa001,
 423                 PCI_ANY_ID, PCI_ANY_ID,
 424                 0, 0,
 425                 0,
 426         },
 427         {
 428                 0x1571, 0xa002,
 429                 PCI_ANY_ID, PCI_ANY_ID,
 430                 0, 0,
 431                 0,
 432         },
 433         {
 434                 0x1571, 0xa003,
 435                 PCI_ANY_ID, PCI_ANY_ID,
 436                 0, 0,
 437                 0
 438         },
 439         {
 440                 0x1571, 0xa004,
 441                 PCI_ANY_ID, PCI_ANY_ID,
 442                 0, 0,
 443                 0,
 444         },
 445         {
 446                 0x1571, 0xa005,
 447                 PCI_ANY_ID, PCI_ANY_ID,
 448                 0, 0,
 449                 0
 450         },
 451         {
 452                 0x1571, 0xa006,
 453                 PCI_ANY_ID, PCI_ANY_ID,
 454                 0, 0,
 455                 0
 456         },
 457         {
 458                 0x1571, 0xa007,
 459                 PCI_ANY_ID, PCI_ANY_ID,
 460                 0, 0,
 461                 0
 462         },
 463         {
 464                 0x1571, 0xa008,
 465                 PCI_ANY_ID, PCI_ANY_ID,
 466                 0, 0,
 467                 0
 468         },
 469         {
 470                 0x1571, 0xa009,
 471                 PCI_ANY_ID, PCI_ANY_ID,
 472                 0, 0,
 473                 (kernel_ulong_t)&card_info_5mbit
 474         },
 475         {
 476                 0x1571, 0xa00a,
 477                 PCI_ANY_ID, PCI_ANY_ID,
 478                 0, 0,
 479                 (kernel_ulong_t)&card_info_5mbit
 480         },
 481         {
 482                 0x1571, 0xa00b,
 483                 PCI_ANY_ID, PCI_ANY_ID,
 484                 0, 0,
 485                 (kernel_ulong_t)&card_info_5mbit
 486         },
 487         {
 488                 0x1571, 0xa00c,
 489                 PCI_ANY_ID, PCI_ANY_ID,
 490                 0, 0,
 491                 (kernel_ulong_t)&card_info_5mbit
 492         },
 493         {
 494                 0x1571, 0xa00d,
 495                 PCI_ANY_ID, PCI_ANY_ID,
 496                 0, 0,
 497                 (kernel_ulong_t)&card_info_5mbit
 498         },
 499         {
 500                 0x1571, 0xa00e,
 501                 PCI_ANY_ID, PCI_ANY_ID,
 502                 0, 0,
 503                 (kernel_ulong_t)&card_info_5mbit
 504         },
 505         {
 506                 0x1571, 0xa201,
 507                 PCI_ANY_ID, PCI_ANY_ID,
 508                 0, 0,
 509                 (kernel_ulong_t)&card_info_10mbit
 510         },
 511         {
 512                 0x1571, 0xa202,
 513                 PCI_ANY_ID, PCI_ANY_ID,
 514                 0, 0,
 515                 (kernel_ulong_t)&card_info_10mbit
 516         },
 517         {
 518                 0x1571, 0xa203,
 519                 PCI_ANY_ID, PCI_ANY_ID,
 520                 0, 0,
 521                 (kernel_ulong_t)&card_info_10mbit
 522         },
 523         {
 524                 0x1571, 0xa204,
 525                 PCI_ANY_ID, PCI_ANY_ID,
 526                 0, 0,
 527                 (kernel_ulong_t)&card_info_10mbit
 528         },
 529         {
 530                 0x1571, 0xa205,
 531                 PCI_ANY_ID, PCI_ANY_ID,
 532                 0, 0,
 533                 (kernel_ulong_t)&card_info_10mbit
 534         },
 535         {
 536                 0x1571, 0xa206,
 537                 PCI_ANY_ID, PCI_ANY_ID,
 538                 0, 0,
 539                 (kernel_ulong_t)&card_info_10mbit
 540         },
 541         {
 542                 0x10B5, 0x9030,
 543                 0x10B5, 0x2978,
 544                 0, 0,
 545                 (kernel_ulong_t)&card_info_sohard
 546         },
 547         {
 548                 0x10B5, 0x9050,
 549                 0x10B5, 0x2273,
 550                 0, 0,
 551                 (kernel_ulong_t)&card_info_sohard
 552         },
 553         {
 554                 0x10B5, 0x9050,
 555                 0x10B5, 0x3263,
 556                 0, 0,
 557                 (kernel_ulong_t)&card_info_eae_arc1
 558         },
 559         {
 560                 0x10B5, 0x9050,
 561                 0x10B5, 0x3292,
 562                 0, 0,
 563                 (kernel_ulong_t)&card_info_eae_ma1
 564         },
 565         {
 566                 0x10B5, 0x9050,
 567                 0x10B5, 0x3294,
 568                 0, 0,
 569                 (kernel_ulong_t)&card_info_eae_fb2
 570         },
 571         {
 572                 0x14BA, 0x6000,
 573                 PCI_ANY_ID, PCI_ANY_ID,
 574                 0, 0,
 575                 (kernel_ulong_t)&card_info_10mbit
 576         },
 577         {
 578                 0x10B5, 0x2200,
 579                 PCI_ANY_ID, PCI_ANY_ID,
 580                 0, 0,
 581                 (kernel_ulong_t)&card_info_10mbit
 582         },
 583         { 0, }
 584 };
 585 
 586 MODULE_DEVICE_TABLE(pci, com20020pci_id_table);
 587 
 588 static struct pci_driver com20020pci_driver = {
 589         .name           = "com20020",
 590         .id_table       = com20020pci_id_table,
 591         .probe          = com20020pci_probe,
 592         .remove         = com20020pci_remove,
 593 };
 594 
 595 static int __init com20020pci_init(void)
 596 {
 597         if (BUGLVL(D_NORMAL))
 598                 pr_info("%s\n", "COM20020 PCI support");
 599         return pci_register_driver(&com20020pci_driver);
 600 }
 601 
 602 static void __exit com20020pci_cleanup(void)
 603 {
 604         pci_unregister_driver(&com20020pci_driver);
 605 }
 606 
 607 module_init(com20020pci_init)
 608 module_exit(com20020pci_cleanup)

/* [<][>][^][v][top][bottom][index][help] */