linux/drivers/net/arcnet/com90xx.c
<<
>>
Prefs
   1/*
   2 * Linux ARCnet driver - COM90xx chipset (memory-mapped buffers)
   3 *
   4 * Written 1994-1999 by Avery Pennarun.
   5 * Written 1999 by Martin Mares <mj@ucw.cz>.
   6 * Derived from skeleton.c by Donald Becker.
   7 *
   8 * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
   9 *  for sponsoring the further development of this driver.
  10 *
  11 * **********************
  12 *
  13 * The original copyright of skeleton.c was as follows:
  14 *
  15 * skeleton.c Written 1993 by Donald Becker.
  16 * Copyright 1993 United States Government as represented by the
  17 * Director, National Security Agency.  This software may only be used
  18 * and distributed according to the terms of the GNU General Public License as
  19 * modified by SRC, incorporated herein by reference.
  20 *
  21 * **********************
  22 *
  23 * For more details, see drivers/net/arcnet.c
  24 *
  25 * **********************
  26 */
  27
  28#define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
  29
  30#include <linux/module.h>
  31#include <linux/moduleparam.h>
  32#include <linux/init.h>
  33#include <linux/interrupt.h>
  34#include <linux/ioport.h>
  35#include <linux/delay.h>
  36#include <linux/netdevice.h>
  37#include <linux/slab.h>
  38#include <linux/io.h>
  39
  40#include "arcdevice.h"
  41#include "com9026.h"
  42
  43/* Define this to speed up the autoprobe by assuming if only one io port and
  44 * shmem are left in the list at Stage 5, they must correspond to each
  45 * other.
  46 *
  47 * This is undefined by default because it might not always be true, and the
  48 * extra check makes the autoprobe even more careful.  Speed demons can turn
  49 * it on - I think it should be fine if you only have one ARCnet card
  50 * installed.
  51 *
  52 * If no ARCnet cards are installed, this delay never happens anyway and thus
  53 * the option has no effect.
  54 */
  55#undef FAST_PROBE
  56
  57/* Internal function declarations */
  58static int com90xx_found(int ioaddr, int airq, u_long shmem, void __iomem *);
  59static void com90xx_command(struct net_device *dev, int command);
  60static int com90xx_status(struct net_device *dev);
  61static void com90xx_setmask(struct net_device *dev, int mask);
  62static int com90xx_reset(struct net_device *dev, int really_reset);
  63static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,
  64                                 void *buf, int count);
  65static void com90xx_copy_from_card(struct net_device *dev, int bufnum,
  66                                   int offset, void *buf, int count);
  67
  68/* Known ARCnet cards */
  69
  70static struct net_device *cards[16];
  71static int numcards;
  72
  73/* Handy defines for ARCnet specific stuff */
  74
  75/* The number of low I/O ports used by the card */
  76#define ARCNET_TOTAL_SIZE       16
  77
  78/* Amount of I/O memory used by the card */
  79#define BUFFER_SIZE (512)
  80#define MIRROR_SIZE (BUFFER_SIZE * 4)
  81
  82static int com90xx_skip_probe __initdata = 0;
  83
  84/* Module parameters */
  85
  86static int io;                  /* use the insmod io= irq= shmem= options */
  87static int irq;
  88static int shmem;
  89static char device[9];          /* use eg. device=arc1 to change name */
  90
  91module_param_hw(io, int, ioport, 0);
  92module_param_hw(irq, int, irq, 0);
  93module_param(shmem, int, 0);
  94module_param_string(device, device, sizeof(device), 0);
  95
  96static void __init com90xx_probe(void)
  97{
  98        int count, status, ioaddr, numprint, airq, openparen = 0;
  99        unsigned long airqmask;
 100        int ports[(0x3f0 - 0x200) / 16 + 1] = { 0 };
 101        unsigned long *shmems;
 102        void __iomem **iomem;
 103        int numports, numshmems, *port;
 104        u_long *p;
 105        int index;
 106
 107        if (!io && !irq && !shmem && !*device && com90xx_skip_probe)
 108                return;
 109
 110        shmems = kzalloc(((0x100000 - 0xa0000) / 0x800) * sizeof(unsigned long),
 111                         GFP_KERNEL);
 112        if (!shmems)
 113                return;
 114        iomem = kzalloc(((0x100000 - 0xa0000) / 0x800) * sizeof(void __iomem *),
 115                        GFP_KERNEL);
 116        if (!iomem) {
 117                kfree(shmems);
 118                return;
 119        }
 120
 121        if (BUGLVL(D_NORMAL))
 122                pr_info("%s\n", "COM90xx chipset support");
 123
 124        /* set up the arrays where we'll store the possible probe addresses */
 125        numports = numshmems = 0;
 126        if (io)
 127                ports[numports++] = io;
 128        else
 129                for (count = 0x200; count <= 0x3f0; count += 16)
 130                        ports[numports++] = count;
 131        if (shmem)
 132                shmems[numshmems++] = shmem;
 133        else
 134                for (count = 0xA0000; count <= 0xFF800; count += 2048)
 135                        shmems[numshmems++] = count;
 136
 137        /* Stage 1: abandon any reserved ports, or ones with status==0xFF
 138         * (empty), and reset any others by reading the reset port.
 139         */
 140        numprint = -1;
 141        for (port = &ports[0]; port - ports < numports; port++) {
 142                numprint++;
 143                numprint %= 8;
 144                if (!numprint) {
 145                        arc_cont(D_INIT, "\n");
 146                        arc_cont(D_INIT, "S1: ");
 147                }
 148                arc_cont(D_INIT, "%Xh ", *port);
 149
 150                ioaddr = *port;
 151
 152                if (!request_region(*port, ARCNET_TOTAL_SIZE,
 153                                    "arcnet (90xx)")) {
 154                        arc_cont(D_INIT_REASONS, "(request_region)\n");
 155                        arc_cont(D_INIT_REASONS, "S1: ");
 156                        if (BUGLVL(D_INIT_REASONS))
 157                                numprint = 0;
 158                        *port-- = ports[--numports];
 159                        continue;
 160                }
 161                if (arcnet_inb(ioaddr, COM9026_REG_R_STATUS) == 0xFF) {
 162                        arc_cont(D_INIT_REASONS, "(empty)\n");
 163                        arc_cont(D_INIT_REASONS, "S1: ");
 164                        if (BUGLVL(D_INIT_REASONS))
 165                                numprint = 0;
 166                        release_region(*port, ARCNET_TOTAL_SIZE);
 167                        *port-- = ports[--numports];
 168                        continue;
 169                }
 170                /* begin resetting card */
 171                arcnet_inb(ioaddr, COM9026_REG_R_RESET);
 172
 173                arc_cont(D_INIT_REASONS, "\n");
 174                arc_cont(D_INIT_REASONS, "S1: ");
 175                if (BUGLVL(D_INIT_REASONS))
 176                        numprint = 0;
 177        }
 178        arc_cont(D_INIT, "\n");
 179
 180        if (!numports) {
 181                arc_cont(D_NORMAL, "S1: No ARCnet cards found.\n");
 182                kfree(shmems);
 183                kfree(iomem);
 184                return;
 185        }
 186        /* Stage 2: we have now reset any possible ARCnet cards, so we can't
 187         * do anything until they finish.  If D_INIT, print the list of
 188         * cards that are left.
 189         */
 190        numprint = -1;
 191        for (port = &ports[0]; port < ports + numports; port++) {
 192                numprint++;
 193                numprint %= 8;
 194                if (!numprint) {
 195                        arc_cont(D_INIT, "\n");
 196                        arc_cont(D_INIT, "S2: ");
 197                }
 198                arc_cont(D_INIT, "%Xh ", *port);
 199        }
 200        arc_cont(D_INIT, "\n");
 201        mdelay(RESETtime);
 202
 203        /* Stage 3: abandon any shmem addresses that don't have the signature
 204         * 0xD1 byte in the right place, or are read-only.
 205         */
 206        numprint = -1;
 207        for (index = 0, p = &shmems[0]; index < numshmems; p++, index++) {
 208                void __iomem *base;
 209
 210                numprint++;
 211                numprint %= 8;
 212                if (!numprint) {
 213                        arc_cont(D_INIT, "\n");
 214                        arc_cont(D_INIT, "S3: ");
 215                }
 216                arc_cont(D_INIT, "%lXh ", *p);
 217
 218                if (!request_mem_region(*p, MIRROR_SIZE, "arcnet (90xx)")) {
 219                        arc_cont(D_INIT_REASONS, "(request_mem_region)\n");
 220                        arc_cont(D_INIT_REASONS, "Stage 3: ");
 221                        if (BUGLVL(D_INIT_REASONS))
 222                                numprint = 0;
 223                        goto out;
 224                }
 225                base = ioremap(*p, MIRROR_SIZE);
 226                if (!base) {
 227                        arc_cont(D_INIT_REASONS, "(ioremap)\n");
 228                        arc_cont(D_INIT_REASONS, "Stage 3: ");
 229                        if (BUGLVL(D_INIT_REASONS))
 230                                numprint = 0;
 231                        goto out1;
 232                }
 233                if (arcnet_readb(base, COM9026_REG_R_STATUS) != TESTvalue) {
 234                        arc_cont(D_INIT_REASONS, "(%02Xh != %02Xh)\n",
 235                                 arcnet_readb(base, COM9026_REG_R_STATUS),
 236                                 TESTvalue);
 237                        arc_cont(D_INIT_REASONS, "S3: ");
 238                        if (BUGLVL(D_INIT_REASONS))
 239                                numprint = 0;
 240                        goto out2;
 241                }
 242                /* By writing 0x42 to the TESTvalue location, we also make
 243                 * sure no "mirror" shmem areas show up - if they occur
 244                 * in another pass through this loop, they will be discarded
 245                 * because *cptr != TESTvalue.
 246                 */
 247                arcnet_writeb(0x42, base, COM9026_REG_W_INTMASK);
 248                if (arcnet_readb(base, COM9026_REG_R_STATUS) != 0x42) {
 249                        arc_cont(D_INIT_REASONS, "(read only)\n");
 250                        arc_cont(D_INIT_REASONS, "S3: ");
 251                        goto out2;
 252                }
 253                arc_cont(D_INIT_REASONS, "\n");
 254                arc_cont(D_INIT_REASONS, "S3: ");
 255                if (BUGLVL(D_INIT_REASONS))
 256                        numprint = 0;
 257                iomem[index] = base;
 258                continue;
 259        out2:
 260                iounmap(base);
 261        out1:
 262                release_mem_region(*p, MIRROR_SIZE);
 263        out:
 264                *p-- = shmems[--numshmems];
 265                index--;
 266        }
 267        arc_cont(D_INIT, "\n");
 268
 269        if (!numshmems) {
 270                arc_cont(D_NORMAL, "S3: No ARCnet cards found.\n");
 271                for (port = &ports[0]; port < ports + numports; port++)
 272                        release_region(*port, ARCNET_TOTAL_SIZE);
 273                kfree(shmems);
 274                kfree(iomem);
 275                return;
 276        }
 277        /* Stage 4: something of a dummy, to report the shmems that are
 278         * still possible after stage 3.
 279         */
 280        numprint = -1;
 281        for (p = &shmems[0]; p < shmems + numshmems; p++) {
 282                numprint++;
 283                numprint %= 8;
 284                if (!numprint) {
 285                        arc_cont(D_INIT, "\n");
 286                        arc_cont(D_INIT, "S4: ");
 287                }
 288                arc_cont(D_INIT, "%lXh ", *p);
 289        }
 290        arc_cont(D_INIT, "\n");
 291
 292        /* Stage 5: for any ports that have the correct status, can disable
 293         * the RESET flag, and (if no irq is given) generate an autoirq,
 294         * register an ARCnet device.
 295         *
 296         * Currently, we can only register one device per probe, so quit
 297         * after the first one is found.
 298         */
 299        numprint = -1;
 300        for (port = &ports[0]; port < ports + numports; port++) {
 301                int found = 0;
 302
 303                numprint++;
 304                numprint %= 8;
 305                if (!numprint) {
 306                        arc_cont(D_INIT, "\n");
 307                        arc_cont(D_INIT, "S5: ");
 308                }
 309                arc_cont(D_INIT, "%Xh ", *port);
 310
 311                ioaddr = *port;
 312                status = arcnet_inb(ioaddr, COM9026_REG_R_STATUS);
 313
 314                if ((status & 0x9D)
 315                    != (NORXflag | RECONflag | TXFREEflag | RESETflag)) {
 316                        arc_cont(D_INIT_REASONS, "(status=%Xh)\n", status);
 317                        arc_cont(D_INIT_REASONS, "S5: ");
 318                        if (BUGLVL(D_INIT_REASONS))
 319                                numprint = 0;
 320                        release_region(*port, ARCNET_TOTAL_SIZE);
 321                        *port-- = ports[--numports];
 322                        continue;
 323                }
 324                arcnet_outb(CFLAGScmd | RESETclear | CONFIGclear,
 325                            ioaddr, COM9026_REG_W_COMMAND);
 326                status = arcnet_inb(ioaddr, COM9026_REG_R_STATUS);
 327                if (status & RESETflag) {
 328                        arc_cont(D_INIT_REASONS, " (eternal reset, status=%Xh)\n",
 329                                 status);
 330                        arc_cont(D_INIT_REASONS, "S5: ");
 331                        if (BUGLVL(D_INIT_REASONS))
 332                                numprint = 0;
 333                        release_region(*port, ARCNET_TOTAL_SIZE);
 334                        *port-- = ports[--numports];
 335                        continue;
 336                }
 337                /* skip this completely if an IRQ was given, because maybe
 338                 * we're on a machine that locks during autoirq!
 339                 */
 340                if (!irq) {
 341                        /* if we do this, we're sure to get an IRQ since the
 342                         * card has just reset and the NORXflag is on until
 343                         * we tell it to start receiving.
 344                         */
 345                        airqmask = probe_irq_on();
 346                        arcnet_outb(NORXflag, ioaddr, COM9026_REG_W_INTMASK);
 347                        udelay(1);
 348                        arcnet_outb(0, ioaddr, COM9026_REG_W_INTMASK);
 349                        airq = probe_irq_off(airqmask);
 350
 351                        if (airq <= 0) {
 352                                arc_cont(D_INIT_REASONS, "(airq=%d)\n", airq);
 353                                arc_cont(D_INIT_REASONS, "S5: ");
 354                                if (BUGLVL(D_INIT_REASONS))
 355                                        numprint = 0;
 356                                release_region(*port, ARCNET_TOTAL_SIZE);
 357                                *port-- = ports[--numports];
 358                                continue;
 359                        }
 360                } else {
 361                        airq = irq;
 362                }
 363
 364                arc_cont(D_INIT, "(%d,", airq);
 365                openparen = 1;
 366
 367                /* Everything seems okay.  But which shmem, if any, puts
 368                 * back its signature byte when the card is reset?
 369                 *
 370                 * If there are multiple cards installed, there might be
 371                 * multiple shmems still in the list.
 372                 */
 373#ifdef FAST_PROBE
 374                if (numports > 1 || numshmems > 1) {
 375                        arcnet_inb(ioaddr, COM9026_REG_R_RESET);
 376                        mdelay(RESETtime);
 377                } else {
 378                        /* just one shmem and port, assume they match */
 379                        arcnet_writeb(TESTvalue, iomem[0],
 380                                      COM9026_REG_W_INTMASK);
 381                }
 382#else
 383                arcnet_inb(ioaddr, COM9026_REG_R_RESET);
 384                mdelay(RESETtime);
 385#endif
 386
 387                for (index = 0; index < numshmems; index++) {
 388                        u_long ptr = shmems[index];
 389                        void __iomem *base = iomem[index];
 390
 391                        if (arcnet_readb(base, COM9026_REG_R_STATUS) == TESTvalue) {    /* found one */
 392                                arc_cont(D_INIT, "%lXh)\n", *p);
 393                                openparen = 0;
 394
 395                                /* register the card */
 396                                if (com90xx_found(*port, airq, ptr, base) == 0)
 397                                        found = 1;
 398                                numprint = -1;
 399
 400                                /* remove shmem from the list */
 401                                shmems[index] = shmems[--numshmems];
 402                                iomem[index] = iomem[numshmems];
 403                                break;  /* go to the next I/O port */
 404                        } else {
 405                                arc_cont(D_INIT_REASONS, "%Xh-",
 406                                         arcnet_readb(base, COM9026_REG_R_STATUS));
 407                        }
 408                }
 409
 410                if (openparen) {
 411                        if (BUGLVL(D_INIT))
 412                                pr_cont("no matching shmem)\n");
 413                        if (BUGLVL(D_INIT_REASONS)) {
 414                                pr_cont("S5: ");
 415                                numprint = 0;
 416                        }
 417                }
 418                if (!found)
 419                        release_region(*port, ARCNET_TOTAL_SIZE);
 420                *port-- = ports[--numports];
 421        }
 422
 423        if (BUGLVL(D_INIT_REASONS))
 424                pr_cont("\n");
 425
 426        /* Now put back TESTvalue on all leftover shmems. */
 427        for (index = 0; index < numshmems; index++) {
 428                arcnet_writeb(TESTvalue, iomem[index], COM9026_REG_W_INTMASK);
 429                iounmap(iomem[index]);
 430                release_mem_region(shmems[index], MIRROR_SIZE);
 431        }
 432        kfree(shmems);
 433        kfree(iomem);
 434}
 435
 436static int __init check_mirror(unsigned long addr, size_t size)
 437{
 438        void __iomem *p;
 439        int res = -1;
 440
 441        if (!request_mem_region(addr, size, "arcnet (90xx)"))
 442                return -1;
 443
 444        p = ioremap(addr, size);
 445        if (p) {
 446                if (arcnet_readb(p, COM9026_REG_R_STATUS) == TESTvalue)
 447                        res = 1;
 448                else
 449                        res = 0;
 450                iounmap(p);
 451        }
 452
 453        release_mem_region(addr, size);
 454        return res;
 455}
 456
 457/* Set up the struct net_device associated with this card.  Called after
 458 * probing succeeds.
 459 */
 460static int __init com90xx_found(int ioaddr, int airq, u_long shmem,
 461                                void __iomem *p)
 462{
 463        struct net_device *dev = NULL;
 464        struct arcnet_local *lp;
 465        u_long first_mirror, last_mirror;
 466        int mirror_size;
 467
 468        /* allocate struct net_device */
 469        dev = alloc_arcdev(device);
 470        if (!dev) {
 471                arc_cont(D_NORMAL, "com90xx: Can't allocate device!\n");
 472                iounmap(p);
 473                release_mem_region(shmem, MIRROR_SIZE);
 474                return -ENOMEM;
 475        }
 476        lp = netdev_priv(dev);
 477        /* find the real shared memory start/end points, including mirrors */
 478
 479        /* guess the actual size of one "memory mirror" - the number of
 480         * bytes between copies of the shared memory.  On most cards, it's
 481         * 2k (or there are no mirrors at all) but on some, it's 4k.
 482         */
 483        mirror_size = MIRROR_SIZE;
 484        if (arcnet_readb(p, COM9026_REG_R_STATUS) == TESTvalue &&
 485            check_mirror(shmem - MIRROR_SIZE, MIRROR_SIZE) == 0 &&
 486            check_mirror(shmem - 2 * MIRROR_SIZE, MIRROR_SIZE) == 1)
 487                mirror_size = 2 * MIRROR_SIZE;
 488
 489        first_mirror = shmem - mirror_size;
 490        while (check_mirror(first_mirror, mirror_size) == 1)
 491                first_mirror -= mirror_size;
 492        first_mirror += mirror_size;
 493
 494        last_mirror = shmem + mirror_size;
 495        while (check_mirror(last_mirror, mirror_size) == 1)
 496                last_mirror += mirror_size;
 497        last_mirror -= mirror_size;
 498
 499        dev->mem_start = first_mirror;
 500        dev->mem_end = last_mirror + MIRROR_SIZE - 1;
 501
 502        iounmap(p);
 503        release_mem_region(shmem, MIRROR_SIZE);
 504
 505        if (!request_mem_region(dev->mem_start,
 506                                dev->mem_end - dev->mem_start + 1,
 507                                "arcnet (90xx)"))
 508                goto err_free_dev;
 509
 510        /* reserve the irq */
 511        if (request_irq(airq, arcnet_interrupt, 0, "arcnet (90xx)", dev)) {
 512                arc_printk(D_NORMAL, dev, "Can't get IRQ %d!\n", airq);
 513                goto err_release_mem;
 514        }
 515        dev->irq = airq;
 516
 517        /* Initialize the rest of the device structure. */
 518        lp->card_name = "COM90xx";
 519        lp->hw.command = com90xx_command;
 520        lp->hw.status = com90xx_status;
 521        lp->hw.intmask = com90xx_setmask;
 522        lp->hw.reset = com90xx_reset;
 523        lp->hw.owner = THIS_MODULE;
 524        lp->hw.copy_to_card = com90xx_copy_to_card;
 525        lp->hw.copy_from_card = com90xx_copy_from_card;
 526        lp->mem_start = ioremap(dev->mem_start,
 527                                dev->mem_end - dev->mem_start + 1);
 528        if (!lp->mem_start) {
 529                arc_printk(D_NORMAL, dev, "Can't remap device memory!\n");
 530                goto err_free_irq;
 531        }
 532
 533        /* get and check the station ID from offset 1 in shmem */
 534        dev->dev_addr[0] = arcnet_readb(lp->mem_start, COM9026_REG_R_STATION);
 535
 536        dev->base_addr = ioaddr;
 537
 538        arc_printk(D_NORMAL, dev, "COM90xx station %02Xh found at %03lXh, IRQ %d, ShMem %lXh (%ld*%xh).\n",
 539                   dev->dev_addr[0],
 540                   dev->base_addr, dev->irq, dev->mem_start,
 541                   (dev->mem_end - dev->mem_start + 1) / mirror_size,
 542                   mirror_size);
 543
 544        if (register_netdev(dev))
 545                goto err_unmap;
 546
 547        cards[numcards++] = dev;
 548        return 0;
 549
 550err_unmap:
 551        iounmap(lp->mem_start);
 552err_free_irq:
 553        free_irq(dev->irq, dev);
 554err_release_mem:
 555        release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
 556err_free_dev:
 557        free_arcdev(dev);
 558        return -EIO;
 559}
 560
 561static void com90xx_command(struct net_device *dev, int cmd)
 562{
 563        short ioaddr = dev->base_addr;
 564
 565        arcnet_outb(cmd, ioaddr, COM9026_REG_W_COMMAND);
 566}
 567
 568static int com90xx_status(struct net_device *dev)
 569{
 570        short ioaddr = dev->base_addr;
 571
 572        return arcnet_inb(ioaddr, COM9026_REG_R_STATUS);
 573}
 574
 575static void com90xx_setmask(struct net_device *dev, int mask)
 576{
 577        short ioaddr = dev->base_addr;
 578
 579        arcnet_outb(mask, ioaddr, COM9026_REG_W_INTMASK);
 580}
 581
 582/* Do a hardware reset on the card, and set up necessary registers.
 583 *
 584 * This should be called as little as possible, because it disrupts the
 585 * token on the network (causes a RECON) and requires a significant delay.
 586 *
 587 * However, it does make sure the card is in a defined state.
 588 */
 589static int com90xx_reset(struct net_device *dev, int really_reset)
 590{
 591        struct arcnet_local *lp = netdev_priv(dev);
 592        short ioaddr = dev->base_addr;
 593
 594        arc_printk(D_INIT, dev, "Resetting (status=%02Xh)\n",
 595                   arcnet_inb(ioaddr, COM9026_REG_R_STATUS));
 596
 597        if (really_reset) {
 598                /* reset the card */
 599                arcnet_inb(ioaddr, COM9026_REG_R_RESET);
 600                mdelay(RESETtime);
 601        }
 602        /* clear flags & end reset */
 603        arcnet_outb(CFLAGScmd | RESETclear, ioaddr, COM9026_REG_W_COMMAND);
 604        arcnet_outb(CFLAGScmd | CONFIGclear, ioaddr, COM9026_REG_W_COMMAND);
 605
 606#if 0
 607        /* don't do this until we verify that it doesn't hurt older cards! */
 608        arcnet_outb(arcnet_inb(ioaddr, COM9026_REG_RW_CONFIG) | ENABLE16flag,
 609                    ioaddr, COM9026_REG_RW_CONFIG);
 610#endif
 611
 612        /* verify that the ARCnet signature byte is present */
 613        if (arcnet_readb(lp->mem_start, COM9026_REG_R_STATUS) != TESTvalue) {
 614                if (really_reset)
 615                        arc_printk(D_NORMAL, dev, "reset failed: TESTvalue not present.\n");
 616                return 1;
 617        }
 618        /* enable extended (512-byte) packets */
 619        arcnet_outb(CONFIGcmd | EXTconf, ioaddr, COM9026_REG_W_COMMAND);
 620
 621        /* clean out all the memory to make debugging make more sense :) */
 622        if (BUGLVL(D_DURING))
 623                memset_io(lp->mem_start, 0x42, 2048);
 624
 625        /* done!  return success. */
 626        return 0;
 627}
 628
 629static void com90xx_copy_to_card(struct net_device *dev, int bufnum,
 630                                 int offset, void *buf, int count)
 631{
 632        struct arcnet_local *lp = netdev_priv(dev);
 633        void __iomem *memaddr = lp->mem_start + bufnum * 512 + offset;
 634
 635        TIME(dev, "memcpy_toio", count, memcpy_toio(memaddr, buf, count));
 636}
 637
 638static void com90xx_copy_from_card(struct net_device *dev, int bufnum,
 639                                   int offset, void *buf, int count)
 640{
 641        struct arcnet_local *lp = netdev_priv(dev);
 642        void __iomem *memaddr = lp->mem_start + bufnum * 512 + offset;
 643
 644        TIME(dev, "memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
 645}
 646
 647MODULE_LICENSE("GPL");
 648
 649static int __init com90xx_init(void)
 650{
 651        if (irq == 2)
 652                irq = 9;
 653        com90xx_probe();
 654        if (!numcards)
 655                return -EIO;
 656        return 0;
 657}
 658
 659static void __exit com90xx_exit(void)
 660{
 661        struct net_device *dev;
 662        struct arcnet_local *lp;
 663        int count;
 664
 665        for (count = 0; count < numcards; count++) {
 666                dev = cards[count];
 667                lp = netdev_priv(dev);
 668
 669                unregister_netdev(dev);
 670                free_irq(dev->irq, dev);
 671                iounmap(lp->mem_start);
 672                release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
 673                release_mem_region(dev->mem_start,
 674                                   dev->mem_end - dev->mem_start + 1);
 675                free_arcdev(dev);
 676        }
 677}
 678
 679module_init(com90xx_init);
 680module_exit(com90xx_exit);
 681
 682#ifndef MODULE
 683static int __init com90xx_setup(char *s)
 684{
 685        int ints[8];
 686
 687        s = get_options(s, 8, ints);
 688        if (!ints[0] && !*s) {
 689                pr_notice("Disabled\n");
 690                return 1;
 691        }
 692
 693        switch (ints[0]) {
 694        default:                /* ERROR */
 695                pr_err("Too many arguments\n");
 696                fallthrough;
 697        case 3:         /* Mem address */
 698                shmem = ints[3];
 699                fallthrough;
 700        case 2:         /* IRQ */
 701                irq = ints[2];
 702                fallthrough;
 703        case 1:         /* IO address */
 704                io = ints[1];
 705        }
 706
 707        if (*s)
 708                snprintf(device, sizeof(device), "%s", s);
 709
 710        return 1;
 711}
 712
 713__setup("com90xx=", com90xx_setup);
 714#endif
 715