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