linux/drivers/sn/ioc3.c
<<
>>
Prefs
   1/*
   2 * SGI IOC3 master driver and IRQ demuxer
   3 *
   4 * Copyright (c) 2005 Stanislaw Skowronek <skylark@linux-mips.org>
   5 * Heavily based on similar work by:
   6 *   Brent Casavant <bcasavan@sgi.com> - IOC4 master driver
   7 *   Pat Gefre <pfg@sgi.com> - IOC3 serial port IRQ demuxer
   8 */
   9
  10#include <linux/errno.h>
  11#include <linux/module.h>
  12#include <linux/pci.h>
  13#include <linux/dma-mapping.h>
  14#include <linux/interrupt.h>
  15#include <linux/spinlock.h>
  16#include <linux/delay.h>
  17#include <linux/ioc3.h>
  18#include <linux/rwsem.h>
  19
  20#define IOC3_PCI_SIZE 0x100000
  21
  22static LIST_HEAD(ioc3_devices);
  23static int ioc3_counter;
  24static DECLARE_RWSEM(ioc3_devices_rwsem);
  25
  26static struct ioc3_submodule *ioc3_submodules[IOC3_MAX_SUBMODULES];
  27static struct ioc3_submodule *ioc3_ethernet;
  28static DEFINE_RWLOCK(ioc3_submodules_lock);
  29
  30/* NIC probing code */
  31
  32#define GPCR_MLAN_EN    0x00200000      /* enable MCR to pin 8 */
  33
  34static inline unsigned mcr_pack(unsigned pulse, unsigned sample)
  35{
  36        return (pulse << 10) | (sample << 2);
  37}
  38
  39static int nic_wait(struct ioc3_driver_data *idd)
  40{
  41        unsigned mcr;
  42
  43        do {
  44                mcr = readl(&idd->vma->mcr);
  45        } while (!(mcr & 2));
  46
  47        return mcr & 1;
  48}
  49
  50static int nic_reset(struct ioc3_driver_data *idd)
  51{
  52        int presence;
  53        unsigned long flags;
  54
  55        local_irq_save(flags);
  56        writel(mcr_pack(500, 65), &idd->vma->mcr);
  57        presence = nic_wait(idd);
  58        local_irq_restore(flags);
  59
  60        udelay(500);
  61
  62        return presence;
  63}
  64
  65static int nic_read_bit(struct ioc3_driver_data *idd)
  66{
  67        int result;
  68        unsigned long flags;
  69
  70        local_irq_save(flags);
  71        writel(mcr_pack(6, 13), &idd->vma->mcr);
  72        result = nic_wait(idd);
  73        local_irq_restore(flags);
  74
  75        udelay(500);
  76
  77        return result;
  78}
  79
  80static void nic_write_bit(struct ioc3_driver_data *idd, int bit)
  81{
  82        if (bit)
  83                writel(mcr_pack(6, 110), &idd->vma->mcr);
  84        else
  85                writel(mcr_pack(80, 30), &idd->vma->mcr);
  86
  87        nic_wait(idd);
  88}
  89
  90static unsigned nic_read_byte(struct ioc3_driver_data *idd)
  91{
  92        unsigned result = 0;
  93        int i;
  94
  95        for (i = 0; i < 8; i++)
  96                result = (result >> 1) | (nic_read_bit(idd) << 7);
  97
  98        return result;
  99}
 100
 101static void nic_write_byte(struct ioc3_driver_data *idd, int byte)
 102{
 103        int i, bit;
 104
 105        for (i = 8; i; i--) {
 106                bit = byte & 1;
 107                byte >>= 1;
 108
 109                nic_write_bit(idd, bit);
 110        }
 111}
 112
 113static unsigned long
 114nic_find(struct ioc3_driver_data *idd, int *last, unsigned long addr)
 115{
 116        int a, b, index, disc;
 117
 118        nic_reset(idd);
 119
 120        /* Search ROM.  */
 121        nic_write_byte(idd, 0xF0);
 122
 123        /* Algorithm from ``Book of iButton Standards''.  */
 124        for (index = 0, disc = 0; index < 64; index++) {
 125                a = nic_read_bit(idd);
 126                b = nic_read_bit(idd);
 127
 128                if (a && b) {
 129                        printk(KERN_WARNING "IOC3 NIC search failed.\n");
 130                        *last = 0;
 131                        return 0;
 132                }
 133
 134                if (!a && !b) {
 135                        if (index == *last) {
 136                                addr |= 1UL << index;
 137                        } else if (index > *last) {
 138                                addr &= ~(1UL << index);
 139                                disc = index;
 140                        } else if ((addr & (1UL << index)) == 0)
 141                                disc = index;
 142                        nic_write_bit(idd, (addr>>index)&1);
 143                        continue;
 144                } else {
 145                        if (a)
 146                                addr |= 1UL << index;
 147                        else
 148                                addr &= ~(1UL << index);
 149                        nic_write_bit(idd, a);
 150                        continue;
 151                }
 152        }
 153        *last = disc;
 154        return addr;
 155}
 156
 157static void nic_addr(struct ioc3_driver_data *idd, unsigned long addr)
 158{
 159        int index;
 160
 161        nic_reset(idd);
 162        nic_write_byte(idd, 0xF0);
 163        for (index = 0; index < 64; index++) {
 164                nic_read_bit(idd);
 165                nic_read_bit(idd);
 166                nic_write_bit(idd, (addr>>index)&1);
 167        }
 168}
 169
 170static void crc16_byte(unsigned int *crc, unsigned char db)
 171{
 172        int i;
 173
 174        for(i=0;i<8;i++) {
 175                *crc <<= 1;
 176                if((db^(*crc>>16)) & 1)
 177                        *crc ^= 0x8005;
 178                db >>= 1;
 179        }
 180        *crc &= 0xFFFF;
 181}
 182
 183static unsigned int crc16_area(unsigned char *dbs, int size, unsigned int crc)
 184{
 185        while(size--)
 186                crc16_byte(&crc, *(dbs++));
 187        return crc;
 188}
 189
 190static void crc8_byte(unsigned int *crc, unsigned char db)
 191{
 192        int i,f;
 193
 194        for(i=0;i<8;i++) {
 195                f = (*crc ^ db) & 1;
 196                *crc >>= 1;
 197                db >>= 1;
 198                if(f)
 199                        *crc ^= 0x8c;
 200        }
 201        *crc &= 0xff;
 202}
 203
 204static unsigned int crc8_addr(unsigned long addr)
 205{
 206        int i;
 207        unsigned int crc = 0x00;
 208
 209        for(i=0;i<8;i++)
 210                crc8_byte(&crc, addr>>(i<<3));
 211        return crc;
 212}
 213
 214static void
 215read_redir_page(struct ioc3_driver_data *idd, unsigned long addr, int page,
 216                        unsigned char *redir, unsigned char *data)
 217{
 218        int loops = 16, i;
 219
 220        while(redir[page] != 0xFF) {
 221                page = redir[page]^0xFF;
 222                loops--;
 223                if(loops<0) {
 224                        printk(KERN_ERR "IOC3: NIC circular redirection\n");
 225                        return;
 226                }
 227        }
 228        loops = 3;
 229        while(loops>0) {
 230                nic_addr(idd, addr);
 231                nic_write_byte(idd, 0xF0);
 232                nic_write_byte(idd, (page << 5) & 0xE0);
 233                nic_write_byte(idd, (page >> 3) & 0x1F);
 234                for(i=0;i<0x20;i++)
 235                        data[i] = nic_read_byte(idd);
 236                if(crc16_area(data, 0x20, 0x0000) == 0x800d)
 237                        return;
 238                loops--;
 239        }
 240        printk(KERN_ERR "IOC3: CRC error in data page\n");
 241        for(i=0;i<0x20;i++)
 242                data[i] = 0x00;
 243}
 244
 245static void
 246read_redir_map(struct ioc3_driver_data *idd, unsigned long addr,
 247                                         unsigned char *redir)
 248{
 249        int i,j,loops = 3,crc_ok;
 250        unsigned int crc;
 251
 252        while(loops>0) {
 253                crc_ok = 1;
 254                nic_addr(idd, addr);
 255                nic_write_byte(idd, 0xAA);
 256                nic_write_byte(idd, 0x00);
 257                nic_write_byte(idd, 0x01);
 258                for(i=0;i<64;i+=8) {
 259                        for(j=0;j<8;j++)
 260                                redir[i+j] = nic_read_byte(idd);
 261                        crc = crc16_area(redir+i, 8, (i==0)?0x8707:0x0000);
 262                        crc16_byte(&crc, nic_read_byte(idd));
 263                        crc16_byte(&crc, nic_read_byte(idd));
 264                        if(crc != 0x800d)
 265                                crc_ok = 0;
 266                }
 267                if(crc_ok)
 268                        return;
 269                loops--;
 270        }
 271        printk(KERN_ERR "IOC3: CRC error in redirection page\n");
 272        for(i=0;i<64;i++)
 273                redir[i] = 0xFF;
 274}
 275
 276static void read_nic(struct ioc3_driver_data *idd, unsigned long addr)
 277{
 278        unsigned char redir[64];
 279        unsigned char data[64],part[32];
 280        int i,j;
 281
 282        /* read redirections */
 283        read_redir_map(idd, addr, redir);
 284        /* read data pages */
 285        read_redir_page(idd, addr, 0, redir, data);
 286        read_redir_page(idd, addr, 1, redir, data+32);
 287        /* assemble the part # */
 288        j=0;
 289        for(i=0;i<19;i++)
 290                if(data[i+11] != ' ')
 291                        part[j++] = data[i+11];
 292        for(i=0;i<6;i++)
 293                if(data[i+32] != ' ')
 294                        part[j++] = data[i+32];
 295        part[j] = 0;
 296        /* skip Octane power supplies */
 297        if(!strncmp(part, "060-0035-", 9))
 298                return;
 299        if(!strncmp(part, "060-0038-", 9))
 300                return;
 301        strcpy(idd->nic_part, part);
 302        /* assemble the serial # */
 303        j=0;
 304        for(i=0;i<10;i++)
 305                if(data[i+1] != ' ')
 306                        idd->nic_serial[j++] = data[i+1];
 307        idd->nic_serial[j] = 0;
 308}
 309
 310static void read_mac(struct ioc3_driver_data *idd, unsigned long addr)
 311{
 312        int i, loops = 3;
 313        unsigned char data[13];
 314
 315        while(loops>0) {
 316                nic_addr(idd, addr);
 317                nic_write_byte(idd, 0xF0);
 318                nic_write_byte(idd, 0x00);
 319                nic_write_byte(idd, 0x00);
 320                nic_read_byte(idd);
 321                for(i=0;i<13;i++)
 322                        data[i] = nic_read_byte(idd);
 323                if(crc16_area(data, 13, 0x0000) == 0x800d) {
 324                        for(i=10;i>4;i--)
 325                                idd->nic_mac[10-i] = data[i];
 326                        return;
 327                }
 328                loops--;
 329        }
 330        printk(KERN_ERR "IOC3: CRC error in MAC address\n");
 331        for(i=0;i<6;i++)
 332                idd->nic_mac[i] = 0x00;
 333}
 334
 335static void probe_nic(struct ioc3_driver_data *idd)
 336{
 337        int save = 0, loops = 3;
 338        unsigned long first, addr;
 339
 340        writel(GPCR_MLAN_EN, &idd->vma->gpcr_s);
 341
 342        while(loops>0) {
 343                idd->nic_part[0] = 0;
 344                idd->nic_serial[0] = 0;
 345                addr = first = nic_find(idd, &save, 0);
 346                if(!first)
 347                        return;
 348                while(1) {
 349                        if(crc8_addr(addr))
 350                                break;
 351                        else {
 352                                switch(addr & 0xFF) {
 353                                case 0x0B:
 354                                        read_nic(idd, addr);
 355                                        break;
 356                                case 0x09:
 357                                case 0x89:
 358                                case 0x91:
 359                                        read_mac(idd, addr);
 360                                        break;
 361                                }
 362                        }
 363                        addr = nic_find(idd, &save, addr);
 364                        if(addr == first)
 365                                return;
 366                }
 367                loops--;
 368        }
 369        printk(KERN_ERR "IOC3: CRC error in NIC address\n");
 370}
 371
 372/* Interrupts */
 373
 374static void write_ireg(struct ioc3_driver_data *idd, uint32_t val, int which)
 375{
 376        unsigned long flags;
 377
 378        spin_lock_irqsave(&idd->ir_lock, flags);
 379        switch (which) {
 380        case IOC3_W_IES:
 381                writel(val, &idd->vma->sio_ies);
 382                break;
 383        case IOC3_W_IEC:
 384                writel(val, &idd->vma->sio_iec);
 385                break;
 386        }
 387        spin_unlock_irqrestore(&idd->ir_lock, flags);
 388}
 389static inline uint32_t get_pending_intrs(struct ioc3_driver_data *idd)
 390{
 391        unsigned long flag;
 392        uint32_t intrs = 0;
 393
 394        spin_lock_irqsave(&idd->ir_lock, flag);
 395        intrs = readl(&idd->vma->sio_ir);
 396        intrs &= readl(&idd->vma->sio_ies);
 397        spin_unlock_irqrestore(&idd->ir_lock, flag);
 398        return intrs;
 399}
 400
 401static irqreturn_t ioc3_intr_io(int irq, void *arg)
 402{
 403        unsigned long flags;
 404        struct ioc3_driver_data *idd = arg;
 405        int handled = 1, id;
 406        unsigned int pending;
 407
 408        read_lock_irqsave(&ioc3_submodules_lock, flags);
 409
 410        if(idd->dual_irq && readb(&idd->vma->eisr)) {
 411                /* send Ethernet IRQ to the driver */
 412                if(ioc3_ethernet && idd->active[ioc3_ethernet->id] &&
 413                                                ioc3_ethernet->intr) {
 414                        handled = handled && !ioc3_ethernet->intr(ioc3_ethernet,
 415                                                        idd, 0);
 416                }
 417        }
 418        pending = get_pending_intrs(idd);       /* look at the IO IRQs */
 419
 420        for(id=0;id<IOC3_MAX_SUBMODULES;id++) {
 421                if(idd->active[id] && ioc3_submodules[id]
 422                                && (pending & ioc3_submodules[id]->irq_mask)
 423                                && ioc3_submodules[id]->intr) {
 424                        write_ireg(idd, ioc3_submodules[id]->irq_mask,
 425                                                        IOC3_W_IEC);
 426                        if(!ioc3_submodules[id]->intr(ioc3_submodules[id],
 427                                   idd, pending & ioc3_submodules[id]->irq_mask))
 428                                pending &= ~ioc3_submodules[id]->irq_mask;
 429                        if (ioc3_submodules[id]->reset_mask)
 430                                write_ireg(idd, ioc3_submodules[id]->irq_mask,
 431                                                        IOC3_W_IES);
 432                }
 433        }
 434        read_unlock_irqrestore(&ioc3_submodules_lock, flags);
 435        if(pending) {
 436                printk(KERN_WARNING
 437                  "IOC3: Pending IRQs 0x%08x discarded and disabled\n",pending);
 438                write_ireg(idd, pending, IOC3_W_IEC);
 439                handled = 1;
 440        }
 441        return handled?IRQ_HANDLED:IRQ_NONE;
 442}
 443
 444static irqreturn_t ioc3_intr_eth(int irq, void *arg)
 445{
 446        unsigned long flags;
 447        struct ioc3_driver_data *idd = (struct ioc3_driver_data *)arg;
 448        int handled = 1;
 449
 450        if(!idd->dual_irq)
 451                return IRQ_NONE;
 452        read_lock_irqsave(&ioc3_submodules_lock, flags);
 453        if(ioc3_ethernet && idd->active[ioc3_ethernet->id]
 454                                && ioc3_ethernet->intr)
 455                handled = handled && !ioc3_ethernet->intr(ioc3_ethernet, idd, 0);
 456        read_unlock_irqrestore(&ioc3_submodules_lock, flags);
 457        return handled?IRQ_HANDLED:IRQ_NONE;
 458}
 459
 460void ioc3_enable(struct ioc3_submodule *is,
 461                                struct ioc3_driver_data *idd, unsigned int irqs)
 462{
 463        write_ireg(idd, irqs & is->irq_mask, IOC3_W_IES);
 464}
 465
 466void ioc3_ack(struct ioc3_submodule *is, struct ioc3_driver_data *idd,
 467                                unsigned int irqs)
 468{
 469        writel(irqs & is->irq_mask, &idd->vma->sio_ir);
 470}
 471
 472void ioc3_disable(struct ioc3_submodule *is,
 473                                struct ioc3_driver_data *idd, unsigned int irqs)
 474{
 475        write_ireg(idd, irqs & is->irq_mask, IOC3_W_IEC);
 476}
 477
 478void ioc3_gpcr_set(struct ioc3_driver_data *idd, unsigned int val)
 479{
 480        unsigned long flags;
 481        spin_lock_irqsave(&idd->gpio_lock, flags);
 482        writel(val, &idd->vma->gpcr_s);
 483        spin_unlock_irqrestore(&idd->gpio_lock, flags);
 484}
 485
 486/* Keep it simple, stupid! */
 487static int find_slot(void **tab, int max)
 488{
 489        int i;
 490        for(i=0;i<max;i++)
 491                if(!(tab[i]))
 492                        return i;
 493        return -1;
 494}
 495
 496/* Register an IOC3 submodule */
 497int ioc3_register_submodule(struct ioc3_submodule *is)
 498{
 499        struct ioc3_driver_data *idd;
 500        int alloc_id;
 501        unsigned long flags;
 502
 503        write_lock_irqsave(&ioc3_submodules_lock, flags);
 504        alloc_id = find_slot((void **)ioc3_submodules, IOC3_MAX_SUBMODULES);
 505        if(alloc_id != -1) {
 506                ioc3_submodules[alloc_id] = is;
 507                if(is->ethernet) {
 508                        if(ioc3_ethernet==NULL)
 509                                ioc3_ethernet=is;
 510                        else
 511                                printk(KERN_WARNING
 512                                  "IOC3 Ethernet module already registered!\n");
 513                }
 514        }
 515        write_unlock_irqrestore(&ioc3_submodules_lock, flags);
 516
 517        if(alloc_id == -1) {
 518                printk(KERN_WARNING "Increase IOC3_MAX_SUBMODULES!\n");
 519                return -ENOMEM;
 520        }
 521
 522        is->id=alloc_id;
 523
 524        /* Initialize submodule for each IOC3 */
 525        if (!is->probe)
 526                return 0;
 527
 528        down_read(&ioc3_devices_rwsem);
 529        list_for_each_entry(idd, &ioc3_devices, list) {
 530                /* set to 1 for IRQs in probe */
 531                idd->active[alloc_id] = 1;
 532                idd->active[alloc_id] = !is->probe(is, idd);
 533        }
 534        up_read(&ioc3_devices_rwsem);
 535
 536        return 0;
 537}
 538
 539/* Unregister an IOC3 submodule */
 540void ioc3_unregister_submodule(struct ioc3_submodule *is)
 541{
 542        struct ioc3_driver_data *idd;
 543        unsigned long flags;
 544
 545        write_lock_irqsave(&ioc3_submodules_lock, flags);
 546        if(ioc3_submodules[is->id]==is)
 547                ioc3_submodules[is->id]=NULL;
 548        else
 549                printk(KERN_WARNING
 550                        "IOC3 submodule %s has wrong ID.\n",is->name);
 551        if(ioc3_ethernet==is)
 552                ioc3_ethernet = NULL;
 553        write_unlock_irqrestore(&ioc3_submodules_lock, flags);
 554
 555        /* Remove submodule for each IOC3 */
 556        down_read(&ioc3_devices_rwsem);
 557        list_for_each_entry(idd, &ioc3_devices, list)
 558                if(idd->active[is->id]) {
 559                        if(is->remove)
 560                                if(is->remove(is, idd))
 561                                        printk(KERN_WARNING
 562                                               "%s: IOC3 submodule %s remove failed "
 563                                               "for pci_dev %s.\n",
 564                                               __func__, module_name(is->owner),
 565                                               pci_name(idd->pdev));
 566                        idd->active[is->id] = 0;
 567                        if(is->irq_mask)
 568                                write_ireg(idd, is->irq_mask, IOC3_W_IEC);
 569                }
 570        up_read(&ioc3_devices_rwsem);
 571}
 572
 573/*********************
 574 * Device management *
 575 *********************/
 576
 577static char *
 578ioc3_class_names[]={"unknown", "IP27 BaseIO", "IP30 system", "MENET 1/2/3",
 579                        "MENET 4", "CADduo", "Altix Serial"};
 580
 581static int ioc3_class(struct ioc3_driver_data *idd)
 582{
 583        int res = IOC3_CLASS_NONE;
 584        /* NIC-based logic */
 585        if(!strncmp(idd->nic_part, "030-0891-", 9))
 586                res = IOC3_CLASS_BASE_IP30;
 587        if(!strncmp(idd->nic_part, "030-1155-", 9))
 588                res = IOC3_CLASS_CADDUO;
 589        if(!strncmp(idd->nic_part, "030-1657-", 9))
 590                res = IOC3_CLASS_SERIAL;
 591        if(!strncmp(idd->nic_part, "030-1664-", 9))
 592                res = IOC3_CLASS_SERIAL;
 593        /* total random heuristics */
 594#ifdef CONFIG_SGI_IP27
 595        if(!idd->nic_part[0])
 596                res = IOC3_CLASS_BASE_IP27;
 597#endif
 598        /* print educational message */
 599        printk(KERN_INFO "IOC3 part: [%s], serial: [%s] => class %s\n",
 600                        idd->nic_part, idd->nic_serial, ioc3_class_names[res]);
 601        return res;
 602}
 603/* Adds a new instance of an IOC3 card */
 604static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
 605{
 606        struct ioc3_driver_data *idd;
 607        uint32_t pcmd;
 608        int ret, id;
 609
 610        /* Enable IOC3 and take ownership of it */
 611        if ((ret = pci_enable_device(pdev))) {
 612                printk(KERN_WARNING
 613                       "%s: Failed to enable IOC3 device for pci_dev %s.\n",
 614                       __func__, pci_name(pdev));
 615                goto out;
 616        }
 617        pci_set_master(pdev);
 618
 619#ifdef USE_64BIT_DMA
 620        ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
 621        if (!ret) {
 622                ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
 623                if (ret < 0) {
 624                        printk(KERN_WARNING "%s: Unable to obtain 64 bit DMA "
 625                               "for consistent allocations\n",
 626                                __func__);
 627                }
 628        }
 629#endif
 630
 631        /* Set up per-IOC3 data */
 632        idd = kzalloc(sizeof(struct ioc3_driver_data), GFP_KERNEL);
 633        if (!idd) {
 634                printk(KERN_WARNING
 635                       "%s: Failed to allocate IOC3 data for pci_dev %s.\n",
 636                       __func__, pci_name(pdev));
 637                ret = -ENODEV;
 638                goto out_idd;
 639        }
 640        spin_lock_init(&idd->ir_lock);
 641        spin_lock_init(&idd->gpio_lock);
 642        idd->pdev = pdev;
 643
 644        /* Map all IOC3 registers.  These are shared between subdevices
 645         * so the main IOC3 module manages them.
 646         */
 647        idd->pma = pci_resource_start(pdev, 0);
 648        if (!idd->pma) {
 649                printk(KERN_WARNING
 650                       "%s: Unable to find IOC3 resource "
 651                       "for pci_dev %s.\n",
 652                       __func__, pci_name(pdev));
 653                ret = -ENODEV;
 654                goto out_pci;
 655        }
 656        if (!request_mem_region(idd->pma, IOC3_PCI_SIZE, "ioc3")) {
 657                printk(KERN_WARNING
 658                       "%s: Unable to request IOC3 region "
 659                       "for pci_dev %s.\n",
 660                       __func__, pci_name(pdev));
 661                ret = -ENODEV;
 662                goto out_pci;
 663        }
 664        idd->vma = ioremap(idd->pma, IOC3_PCI_SIZE);
 665        if (!idd->vma) {
 666                printk(KERN_WARNING
 667                       "%s: Unable to remap IOC3 region "
 668                       "for pci_dev %s.\n",
 669                       __func__, pci_name(pdev));
 670                ret = -ENODEV;
 671                goto out_misc_region;
 672        }
 673
 674        /* Track PCI-device specific data */
 675        pci_set_drvdata(pdev, idd);
 676        down_write(&ioc3_devices_rwsem);
 677        list_add_tail(&idd->list, &ioc3_devices);
 678        idd->id = ioc3_counter++;
 679        up_write(&ioc3_devices_rwsem);
 680
 681        idd->gpdr_shadow = readl(&idd->vma->gpdr);
 682
 683        /* Read IOC3 NIC contents */
 684        probe_nic(idd);
 685
 686        /* Detect IOC3 class */
 687        idd->class = ioc3_class(idd);
 688
 689        /* Initialize IOC3 */
 690       pci_read_config_dword(pdev, PCI_COMMAND, &pcmd);
 691       pci_write_config_dword(pdev, PCI_COMMAND,
 692                               pcmd | PCI_COMMAND_MEMORY |
 693                               PCI_COMMAND_PARITY | PCI_COMMAND_SERR |
 694                               PCI_SCR_DROP_MODE_EN);
 695
 696        write_ireg(idd, ~0, IOC3_W_IEC);
 697        writel(~0, &idd->vma->sio_ir);
 698
 699        /* Set up IRQs */
 700        if(idd->class == IOC3_CLASS_BASE_IP30
 701                                || idd->class == IOC3_CLASS_BASE_IP27) {
 702                writel(0, &idd->vma->eier);
 703                writel(~0, &idd->vma->eisr);
 704
 705                idd->dual_irq = 1;
 706                if (!request_irq(pdev->irq, ioc3_intr_eth, IRQF_SHARED,
 707                                 "ioc3-eth", (void *)idd)) {
 708                        idd->irq_eth = pdev->irq;
 709                } else {
 710                        printk(KERN_WARNING
 711                               "%s : request_irq fails for IRQ 0x%x\n ",
 712                               __func__, pdev->irq);
 713                }
 714                if (!request_irq(pdev->irq+2, ioc3_intr_io, IRQF_SHARED,
 715                                 "ioc3-io", (void *)idd)) {
 716                        idd->irq_io = pdev->irq+2;
 717                } else {
 718                        printk(KERN_WARNING
 719                               "%s : request_irq fails for IRQ 0x%x\n ",
 720                               __func__, pdev->irq+2);
 721                }
 722        } else {
 723                if (!request_irq(pdev->irq, ioc3_intr_io, IRQF_SHARED,
 724                                 "ioc3", (void *)idd)) {
 725                        idd->irq_io = pdev->irq;
 726                } else {
 727                        printk(KERN_WARNING
 728                               "%s : request_irq fails for IRQ 0x%x\n ",
 729                               __func__, pdev->irq);
 730                }
 731        }
 732
 733        /* Add this IOC3 to all submodules */
 734        for(id=0;id<IOC3_MAX_SUBMODULES;id++)
 735                if(ioc3_submodules[id] && ioc3_submodules[id]->probe) {
 736                        idd->active[id] = 1;
 737                        idd->active[id] = !ioc3_submodules[id]->probe
 738                                                (ioc3_submodules[id], idd);
 739                }
 740
 741        printk(KERN_INFO "IOC3 Master Driver loaded for %s\n", pci_name(pdev));
 742
 743        return 0;
 744
 745out_misc_region:
 746        release_mem_region(idd->pma, IOC3_PCI_SIZE);
 747out_pci:
 748        kfree(idd);
 749out_idd:
 750        pci_disable_device(pdev);
 751out:
 752        return ret;
 753}
 754
 755/* Removes a particular instance of an IOC3 card. */
 756static void ioc3_remove(struct pci_dev *pdev)
 757{
 758        int id;
 759        struct ioc3_driver_data *idd;
 760
 761        idd = pci_get_drvdata(pdev);
 762
 763        /* Remove this IOC3 from all submodules */
 764        for(id=0;id<IOC3_MAX_SUBMODULES;id++)
 765                if(idd->active[id]) {
 766                        if(ioc3_submodules[id] && ioc3_submodules[id]->remove)
 767                                if(ioc3_submodules[id]->remove(ioc3_submodules[id],
 768                                                                idd))
 769                                        printk(KERN_WARNING
 770                                               "%s: IOC3 submodule 0x%s remove failed "
 771                                               "for pci_dev %s.\n",
 772                                                __func__,
 773                                                module_name(ioc3_submodules[id]->owner),
 774                                                pci_name(pdev));
 775                        idd->active[id] = 0;
 776                }
 777
 778        /* Clear and disable all IRQs */
 779        write_ireg(idd, ~0, IOC3_W_IEC);
 780        writel(~0, &idd->vma->sio_ir);
 781
 782        /* Release resources */
 783        free_irq(idd->irq_io, (void *)idd);
 784        if(idd->dual_irq)
 785                free_irq(idd->irq_eth, (void *)idd);
 786        iounmap(idd->vma);
 787        release_mem_region(idd->pma, IOC3_PCI_SIZE);
 788
 789        /* Disable IOC3 and relinquish */
 790        pci_disable_device(pdev);
 791
 792        /* Remove and free driver data */
 793        down_write(&ioc3_devices_rwsem);
 794        list_del(&idd->list);
 795        up_write(&ioc3_devices_rwsem);
 796        kfree(idd);
 797}
 798
 799static struct pci_device_id ioc3_id_table[] = {
 800        {PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3, PCI_ANY_ID, PCI_ANY_ID},
 801        {0}
 802};
 803
 804static struct pci_driver ioc3_driver = {
 805        .name = "IOC3",
 806        .id_table = ioc3_id_table,
 807        .probe = ioc3_probe,
 808        .remove = ioc3_remove,
 809};
 810
 811MODULE_DEVICE_TABLE(pci, ioc3_id_table);
 812
 813/*********************
 814 * Module management *
 815 *********************/
 816
 817/* Module load */
 818static int __devinit ioc3_init(void)
 819{
 820        if (ia64_platform_is("sn2"))
 821                return pci_register_driver(&ioc3_driver);
 822        return 0;
 823}
 824
 825/* Module unload */
 826static void __devexit ioc3_exit(void)
 827{
 828        pci_unregister_driver(&ioc3_driver);
 829}
 830
 831module_init(ioc3_init);
 832module_exit(ioc3_exit);
 833
 834MODULE_AUTHOR("Stanislaw Skowronek <skylark@linux-mips.org>");
 835MODULE_DESCRIPTION("PCI driver for SGI IOC3");
 836MODULE_LICENSE("GPL");
 837
 838EXPORT_SYMBOL_GPL(ioc3_register_submodule);
 839EXPORT_SYMBOL_GPL(ioc3_unregister_submodule);
 840EXPORT_SYMBOL_GPL(ioc3_ack);
 841EXPORT_SYMBOL_GPL(ioc3_gpcr_set);
 842EXPORT_SYMBOL_GPL(ioc3_disable);
 843EXPORT_SYMBOL_GPL(ioc3_enable);
 844