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