linux-old/drivers/hotplug/cpqphp_core.c
<<
>>
Prefs
   1/*
   2 * Compaq Hot Plug Controller Driver
   3 *
   4 * Copyright (C) 1995,2001 Compaq Computer Corporation
   5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
   6 * Copyright (C) 2001 IBM Corp.
   7 *
   8 * All rights reserved.
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License as published by
  12 * the Free Software Foundation; either version 2 of the License, or (at
  13 * your option) any later version.
  14 *
  15 * This program is distributed in the hope that it will be useful, but
  16 * WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  18 * NON INFRINGEMENT.  See the GNU General Public License for more
  19 * details.
  20 *
  21 * You should have received a copy of the GNU General Public License
  22 * along with this program; if not, write to the Free Software
  23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24 *
  25 * Send feedback to <greg@kroah.com>
  26 *
  27 * Jan 12, 2003 -       Added 66/100/133MHz PCI-X support, 
  28 *                      Torben Mathiasen <torben.mathiasen@hp.com>
  29 *
  30 */
  31
  32#include <linux/config.h>
  33#include <linux/module.h>
  34#include <linux/kernel.h>
  35#include <linux/types.h>
  36#include <linux/proc_fs.h>
  37#include <linux/miscdevice.h>
  38#include <linux/slab.h>
  39#include <linux/pci.h>
  40#include <linux/init.h>
  41#include <asm/uaccess.h>
  42#include "cpqphp.h"
  43#include "cpqphp_nvram.h"
  44#include "../../arch/i386/kernel/pci-i386.h"    /* horrible hack showing how processor dependant we are... */
  45
  46
  47/* Global variables */
  48int cpqhp_debug;
  49struct controller *cpqhp_ctrl_list;     /* = NULL */
  50struct pci_func *cpqhp_slot_list[256];
  51
  52/* local variables */
  53static void *smbios_table;
  54static void *smbios_start;
  55static void *cpqhp_rom_start;
  56static u8 power_mode;
  57static int debug;
  58
  59#define DRIVER_VERSION  "0.9.7"
  60#define DRIVER_AUTHOR   "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>"
  61#define DRIVER_DESC     "Compaq Hot Plug PCI Controller Driver"
  62
  63MODULE_AUTHOR(DRIVER_AUTHOR);
  64MODULE_DESCRIPTION(DRIVER_DESC);
  65MODULE_LICENSE("GPL");
  66
  67MODULE_PARM(power_mode, "b");
  68MODULE_PARM_DESC(power_mode, "Power mode enabled or not");
  69
  70MODULE_PARM(debug, "i");
  71MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
  72
  73#define CPQHPC_MODULE_MINOR 208
  74
  75static int one_time_init (void);
  76static int set_attention_status (struct hotplug_slot *slot, u8 value);
  77static int process_SI           (struct hotplug_slot *slot);
  78static int process_SS           (struct hotplug_slot *slot);
  79static int hardware_test        (struct hotplug_slot *slot, u32 value);
  80static int get_power_status     (struct hotplug_slot *slot, u8 *value);
  81static int get_attention_status (struct hotplug_slot *slot, u8 *value);
  82static int get_latch_status     (struct hotplug_slot *slot, u8 *value);
  83static int get_adapter_status   (struct hotplug_slot *slot, u8 *value);
  84static int get_max_bus_speed    (struct hotplug_slot *slot, enum pci_bus_speed *value);
  85static int get_cur_bus_speed    (struct hotplug_slot *slot, enum pci_bus_speed *value);
  86
  87static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = {
  88        .owner =                THIS_MODULE,
  89        .set_attention_status = set_attention_status,
  90        .enable_slot =          process_SI,
  91        .disable_slot =         process_SS,
  92        .hardware_test =        hardware_test,
  93        .get_power_status =     get_power_status,
  94        .get_attention_status = get_attention_status,
  95        .get_latch_status =     get_latch_status,
  96        .get_adapter_status =   get_adapter_status,
  97        .get_max_bus_speed =    get_max_bus_speed,
  98        .get_cur_bus_speed =    get_cur_bus_speed,
  99};
 100
 101
 102static inline int is_slot64bit (struct slot *slot)
 103{
 104        if (!slot || !slot->p_sm_slot)
 105                return 0;
 106
 107        if (readb(slot->p_sm_slot + SMBIOS_SLOT_WIDTH) == 0x06)
 108                return 1;
 109
 110        return 0;
 111}
 112
 113static inline int is_slot66mhz (struct slot *slot)
 114{
 115        if (!slot || !slot->p_sm_slot)
 116                return 0;
 117
 118        if (readb(slot->p_sm_slot + SMBIOS_SLOT_TYPE) == 0x0E)
 119                return 1;
 120
 121        return 0;
 122}
 123
 124/**
 125 * detect_SMBIOS_pointer - find the system Management BIOS Table in the specified region of memory.
 126 *
 127 * @begin: begin pointer for region to be scanned.
 128 * @end: end pointer for region to be scanned.
 129 *
 130 * Returns pointer to the head of the SMBIOS tables (or NULL)
 131 *
 132 */
 133static void * detect_SMBIOS_pointer(void *begin, void *end)
 134{
 135        void *fp;
 136        void *endp;
 137        u8 temp1, temp2, temp3, temp4;
 138        int status = 0;
 139
 140        endp = (end - sizeof(u32) + 1);
 141
 142        for (fp = begin; fp <= endp; fp += 16) {
 143                temp1 = readb(fp);
 144                temp2 = readb(fp+1);
 145                temp3 = readb(fp+2);
 146                temp4 = readb(fp+3);
 147                if (temp1 == '_' &&
 148                    temp2 == 'S' &&
 149                    temp3 == 'M' &&
 150                    temp4 == '_') {
 151                        status = 1;
 152                        break;
 153                }
 154        }
 155        
 156        if (!status)
 157                fp = NULL;
 158
 159        dbg("Discovered SMBIOS Entry point at %p\n", fp);
 160
 161        return fp;
 162}
 163
 164/**
 165 * init_SERR - Initializes the per slot SERR generation.
 166 *
 167 * For unexpected switch opens
 168 *
 169 */
 170static int init_SERR(struct controller * ctrl)
 171{
 172        u32 tempdword;
 173        u32 number_of_slots;
 174        u8 physical_slot;
 175
 176        if (!ctrl)
 177                return 1;
 178
 179        tempdword = ctrl->first_slot;
 180
 181        number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
 182        // Loop through slots
 183        while (number_of_slots) {
 184                physical_slot = tempdword;
 185                writeb(0, ctrl->hpc_reg + SLOT_SERR);
 186                tempdword++;
 187                number_of_slots--;
 188        }
 189
 190        return 0;
 191}
 192
 193
 194/* nice debugging output */
 195static int pci_print_IRQ_route (void)
 196{
 197        struct irq_routing_table *routing_table;
 198        int len;
 199        int loop;
 200
 201        u8 tbus, tdevice, tslot;
 202
 203        routing_table = pcibios_get_irq_routing_table();
 204        if (routing_table == NULL) {
 205                err("No BIOS Routing Table??? Not good\n");
 206                return -ENOMEM;
 207        }
 208
 209        len = (routing_table->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
 210        // Make sure I got at least one entry
 211        if (len == 0) {
 212                kfree(routing_table);
 213                return -1;
 214        }
 215
 216        dbg("bus dev func slot\n");
 217
 218        for (loop = 0; loop < len; ++loop) {
 219                tbus = routing_table->slots[loop].bus;
 220                tdevice = routing_table->slots[loop].devfn;
 221                tslot = routing_table->slots[loop].slot;
 222                dbg("%d %d %d %d\n", tbus, tdevice >> 3, tdevice & 0x7, tslot);
 223
 224        }
 225        kfree(routing_table);
 226        return 0;
 227}
 228
 229
 230/*
 231 * get_subsequent_smbios_entry
 232 *
 233 * Gets the first entry if previous == NULL
 234 * Otherwise, returns the next entry
 235 * Uses global SMBIOS Table pointer
 236 *
 237 * @curr: %NULL or pointer to previously returned structure
 238 *
 239 * returns a pointer to an SMBIOS structure or NULL if none found
 240 */
 241static void * get_subsequent_smbios_entry(void *smbios_start, void *smbios_table, void *curr)
 242{
 243        u8 bail = 0;
 244        u8 previous_byte = 1;
 245        void *p_temp;
 246        void *p_max;
 247
 248        if (!smbios_table || !curr)
 249                return(NULL);
 250
 251        // set p_max to the end of the table
 252        p_max = smbios_start + readw(smbios_table + ST_LENGTH);
 253
 254        p_temp = curr;
 255        p_temp += readb(curr + SMBIOS_GENERIC_LENGTH);
 256
 257        while ((p_temp < p_max) && !bail) {
 258                // Look for the double NULL terminator
 259                // The first condition is the previous byte and the second is the curr
 260                if (!previous_byte && !(readb(p_temp))) {
 261                        bail = 1;
 262                }
 263
 264                previous_byte = readb(p_temp);
 265                p_temp++;
 266        }
 267
 268        if (p_temp < p_max) {
 269                return p_temp;
 270        } else {
 271                return NULL;
 272        }
 273}
 274
 275
 276/**
 277 * get_SMBIOS_entry
 278 *
 279 * @type:SMBIOS structure type to be returned
 280 * @previous: %NULL or pointer to previously returned structure
 281 *
 282 * Gets the first entry of the specified type if previous == NULL
 283 * Otherwise, returns the next entry of the given type.
 284 * Uses global SMBIOS Table pointer
 285 * Uses get_subsequent_smbios_entry
 286 *
 287 * returns a pointer to an SMBIOS structure or %NULL if none found
 288 */
 289static void *get_SMBIOS_entry (void *smbios_start, void *smbios_table, u8 type, void * previous)
 290{
 291        if (!smbios_table)
 292                return NULL;
 293
 294        if (!previous) {                  
 295                previous = smbios_start;
 296        } else {
 297                previous = get_subsequent_smbios_entry(smbios_start, smbios_table, previous);
 298        }
 299
 300        while (previous) {
 301                if (readb(previous + SMBIOS_GENERIC_TYPE) != type) {
 302                        previous = get_subsequent_smbios_entry(smbios_start, smbios_table, previous);
 303                } else {
 304                        break;
 305                }
 306        }
 307
 308        return previous;
 309}
 310
 311
 312static int ctrl_slot_setup (struct controller * ctrl, void *smbios_start, void *smbios_table)
 313{
 314        struct slot *new_slot;
 315        u8 number_of_slots;
 316        u8 slot_device;
 317        u8 slot_number;
 318        u8 ctrl_slot;
 319        u32 tempdword;
 320        void *slot_entry= NULL;
 321        int result;
 322
 323        dbg("%s\n", __FUNCTION__);
 324
 325        tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
 326
 327        number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
 328        slot_device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
 329        slot_number = ctrl->first_slot;
 330
 331        while (number_of_slots) {
 332                new_slot = (struct slot *) kmalloc(sizeof(struct slot), GFP_KERNEL);
 333                if (!new_slot)
 334                        return -ENOMEM;
 335
 336                memset(new_slot, 0, sizeof(struct slot));
 337                new_slot->hotplug_slot = kmalloc (sizeof (struct hotplug_slot), GFP_KERNEL);
 338                if (!new_slot->hotplug_slot) {
 339                        kfree (new_slot);
 340                        return -ENOMEM;
 341                }
 342                memset(new_slot->hotplug_slot, 0, sizeof (struct hotplug_slot));
 343
 344                new_slot->hotplug_slot->info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
 345                if (!new_slot->hotplug_slot->info) {
 346                        kfree (new_slot->hotplug_slot);
 347                        kfree (new_slot);
 348                        return -ENOMEM;
 349                }
 350                memset(new_slot->hotplug_slot->info, 0, sizeof (struct hotplug_slot_info));
 351                new_slot->hotplug_slot->name = kmalloc (SLOT_NAME_SIZE, GFP_KERNEL);
 352                if (!new_slot->hotplug_slot->name) {
 353                        kfree (new_slot->hotplug_slot->info);
 354                        kfree (new_slot->hotplug_slot);
 355                        kfree (new_slot);
 356                        return -ENOMEM;
 357                }
 358
 359                new_slot->magic = SLOT_MAGIC;
 360                new_slot->ctrl = ctrl;
 361                new_slot->bus = ctrl->bus;
 362                new_slot->device = slot_device;
 363                new_slot->number = slot_number;
 364                dbg("slot->number = %d\n",new_slot->number);
 365
 366                slot_entry = get_SMBIOS_entry(smbios_start, smbios_table, 9, slot_entry);
 367
 368                while (slot_entry && (readw(slot_entry + SMBIOS_SLOT_NUMBER) != new_slot->number)) {
 369                        slot_entry = get_SMBIOS_entry(smbios_start, smbios_table, 9, slot_entry);
 370                }
 371
 372                new_slot->p_sm_slot = slot_entry;
 373
 374                init_timer(&new_slot->task_event);
 375                new_slot->task_event.expires = jiffies + 5 * HZ;
 376                new_slot->task_event.function = cpqhp_pushbutton_thread;
 377
 378                //FIXME: these capabilities aren't used but if they are
 379                //       they need to be correctly implemented
 380                new_slot->capabilities |= PCISLOT_REPLACE_SUPPORTED;
 381                new_slot->capabilities |= PCISLOT_INTERLOCK_SUPPORTED;
 382
 383                if (is_slot64bit(new_slot))
 384                        new_slot->capabilities |= PCISLOT_64_BIT_SUPPORTED;
 385                if (is_slot66mhz(new_slot))
 386                        new_slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED;
 387                if (ctrl->speed == PCI_SPEED_66MHz)
 388                        new_slot->capabilities |= PCISLOT_66_MHZ_OPERATION;
 389
 390                ctrl_slot = slot_device - (readb(ctrl->hpc_reg + SLOT_MASK) >> 4);
 391
 392                // Check presence
 393                new_slot->capabilities |= ((((~tempdword) >> 23) | ((~tempdword) >> 15)) >> ctrl_slot) & 0x02;
 394                // Check the switch state
 395                new_slot->capabilities |= ((~tempdword & 0xFF) >> ctrl_slot) & 0x01;
 396                // Check the slot enable
 397                new_slot->capabilities |= ((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04;
 398
 399                /* register this slot with the hotplug pci core */
 400                new_slot->hotplug_slot->private = new_slot;
 401                make_slot_name (new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot);
 402                new_slot->hotplug_slot->ops = &cpqphp_hotplug_slot_ops;
 403                
 404                new_slot->hotplug_slot->info->power_status = get_slot_enabled(ctrl, new_slot);
 405                new_slot->hotplug_slot->info->attention_status = cpq_get_attention_status(ctrl, new_slot);
 406                new_slot->hotplug_slot->info->latch_status = cpq_get_latch_status(ctrl, new_slot);
 407                new_slot->hotplug_slot->info->adapter_status = get_presence_status(ctrl, new_slot);
 408                
 409                dbg ("registering bus %d, dev %d, number %d, ctrl->slot_device_offset %d, slot %d\n", 
 410                     new_slot->bus, new_slot->device, new_slot->number, ctrl->slot_device_offset, slot_number);
 411                result = pci_hp_register (new_slot->hotplug_slot);
 412                if (result) {
 413                        err ("pci_hp_register failed with error %d\n", result);
 414                        kfree (new_slot->hotplug_slot->info);
 415                        kfree (new_slot->hotplug_slot->name);
 416                        kfree (new_slot->hotplug_slot);
 417                        kfree (new_slot);
 418                        return result;
 419                }
 420                
 421                new_slot->next = ctrl->slot;
 422                ctrl->slot = new_slot;
 423
 424                number_of_slots--;
 425                slot_device++;
 426                slot_number++;
 427        }
 428
 429        return(0);
 430}
 431
 432
 433static int ctrl_slot_cleanup (struct controller * ctrl)
 434{
 435        struct slot *old_slot, *next_slot;
 436
 437        old_slot = ctrl->slot;
 438        ctrl->slot = NULL;
 439
 440        while (old_slot) {
 441                next_slot = old_slot->next;
 442                pci_hp_deregister (old_slot->hotplug_slot);
 443                kfree(old_slot->hotplug_slot->info);
 444                kfree(old_slot->hotplug_slot->name);
 445                kfree(old_slot->hotplug_slot);
 446                kfree(old_slot);
 447                old_slot = next_slot;
 448        }
 449
 450        //Free IRQ associated with hot plug device
 451        free_irq(ctrl->interrupt, ctrl);
 452        //Unmap the memory
 453        iounmap(ctrl->hpc_reg);
 454        //Finally reclaim PCI mem
 455        release_mem_region(pci_resource_start(ctrl->pci_dev, 0),
 456                           pci_resource_len(ctrl->pci_dev, 0));
 457
 458        return(0);
 459}
 460
 461
 462//============================================================================
 463// function:    get_slot_mapping
 464//
 465// Description: Attempts to determine a logical slot mapping for a PCI
 466//              device.  Won't work for more than one PCI-PCI bridge
 467//              in a slot.
 468//
 469// Input:       u8 bus_num - bus number of PCI device
 470//              u8 dev_num - device number of PCI device
 471//              u8 *slot - Pointer to u8 where slot number will
 472//                      be returned
 473//
 474// Output:      SUCCESS or FAILURE
 475//=============================================================================
 476static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *slot)
 477{
 478        struct irq_routing_table *PCIIRQRoutingInfoLength;
 479        u32 work;
 480        long len;
 481        long loop;
 482
 483        u8 tbus, tdevice, tslot, bridgeSlot;
 484
 485        dbg("%s %p, %d, %d, %p\n", __FUNCTION__, ops, bus_num, dev_num, slot);
 486
 487        bridgeSlot = 0xFF;
 488
 489        PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table();
 490
 491        len = (PCIIRQRoutingInfoLength->size -
 492               sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
 493        // Make sure I got at least one entry
 494        if (len == 0) {
 495                if (PCIIRQRoutingInfoLength != NULL) kfree(PCIIRQRoutingInfoLength );
 496                return -1;
 497        }
 498
 499
 500        for (loop = 0; loop < len; ++loop) {
 501                tbus = PCIIRQRoutingInfoLength->slots[loop].bus;
 502                tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn >> 3;
 503                tslot = PCIIRQRoutingInfoLength->slots[loop].slot;
 504
 505                if ((tbus == bus_num) && (tdevice == dev_num)) {
 506                        *slot = tslot;
 507
 508                        if (PCIIRQRoutingInfoLength != NULL) kfree(PCIIRQRoutingInfoLength );
 509                        return 0;
 510                } else {
 511                        // Didn't get a match on the target PCI device. Check if the
 512                        // current IRQ table entry is a PCI-to-PCI bridge device.  If so,
 513                        // and it's secondary bus matches the bus number for the target 
 514                        // device, I need to save the bridge's slot number.  If I can't 
 515                        // find an entry for the target device, I will have to assume it's 
 516                        // on the other side of the bridge, and assign it the bridge's slot.
 517                        pci_read_config_dword_nodev (ops, tbus, tdevice, 0, PCI_REVISION_ID, &work);
 518
 519                        if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
 520                                pci_read_config_dword_nodev (ops, tbus, tdevice, 0, PCI_PRIMARY_BUS, &work);
 521                                // See if bridge's secondary bus matches target bus.
 522                                if (((work >> 8) & 0x000000FF) == (long) bus_num) {
 523                                        bridgeSlot = tslot;
 524                                }
 525                        }
 526                }
 527
 528        }
 529
 530
 531        // If we got here, we didn't find an entry in the IRQ mapping table 
 532        // for the target PCI device.  If we did determine that the target 
 533        // device is on the other side of a PCI-to-PCI bridge, return the 
 534        // slot number for the bridge.
 535        if (bridgeSlot != 0xFF) {
 536                *slot = bridgeSlot;
 537                if (PCIIRQRoutingInfoLength != NULL) kfree(PCIIRQRoutingInfoLength );
 538                return 0;
 539        }
 540        if (PCIIRQRoutingInfoLength != NULL) kfree(PCIIRQRoutingInfoLength );
 541        // Couldn't find an entry in the routing table for this PCI device
 542        return -1;
 543}
 544
 545
 546/**
 547 * cpqhp_set_attention_status - Turns the Amber LED for a slot on or off
 548 *
 549 */
 550static int cpqhp_set_attention_status (struct controller *ctrl, struct pci_func *func, u32 status)
 551{
 552        u8 hp_slot;
 553
 554        hp_slot = func->device - ctrl->slot_device_offset;
 555
 556        if (func == NULL)
 557                return(1);
 558
 559        // Wait for exclusive access to hardware
 560        down(&ctrl->crit_sect);
 561
 562        if (status == 1) {
 563                amber_LED_on (ctrl, hp_slot);
 564        } else if (status == 0) {
 565                amber_LED_off (ctrl, hp_slot);
 566        } else {
 567                // Done with exclusive hardware access
 568                up(&ctrl->crit_sect);
 569                return(1);
 570        }
 571
 572        set_SOGO(ctrl);
 573
 574        // Wait for SOBS to be unset
 575        wait_for_ctrl_irq (ctrl);
 576
 577        // Done with exclusive hardware access
 578        up(&ctrl->crit_sect);
 579
 580        return(0);
 581}
 582
 583
 584/**
 585 * set_attention_status - Turns the Amber LED for a slot on or off
 586 *
 587 */
 588static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
 589{
 590        struct pci_func *slot_func;
 591        struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
 592        struct controller *ctrl;
 593        u8 bus;
 594        u8 devfn;
 595        u8 device;
 596        u8 function;
 597        
 598        if (slot == NULL)
 599                return -ENODEV;
 600        
 601        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
 602
 603        ctrl = slot->ctrl;
 604        if (ctrl == NULL)
 605                return -ENODEV;
 606        
 607        if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
 608                return -ENODEV;
 609
 610        device = devfn >> 3;
 611        function = devfn & 0x7;
 612        dbg("bus, dev, fn = %d, %d, %d\n", bus, device, function);
 613
 614        slot_func = cpqhp_slot_find(bus, device, function);
 615        if (!slot_func) {
 616                return -ENODEV;
 617        }
 618
 619        return cpqhp_set_attention_status(ctrl, slot_func, status);
 620}
 621
 622
 623static int process_SI (struct hotplug_slot *hotplug_slot)
 624{
 625        struct pci_func *slot_func;
 626        struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
 627        struct controller *ctrl;
 628        u8 bus;
 629        u8 devfn;
 630        u8 device;
 631        u8 function;
 632        
 633        if (slot == NULL)
 634                return -ENODEV;
 635        
 636        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
 637
 638        ctrl = slot->ctrl;
 639        if (ctrl == NULL)
 640                return -ENODEV;
 641        
 642        if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
 643                return -ENODEV;
 644
 645        device = devfn >> 3;
 646        function = devfn & 0x7;
 647        dbg("bus, dev, fn = %d, %d, %d\n", bus, device, function);
 648
 649        slot_func = cpqhp_slot_find(bus, device, function);
 650        if (!slot_func) {
 651                return -ENODEV;
 652        }
 653
 654        slot_func->bus = bus;
 655        slot_func->device = device;
 656        slot_func->function = function;
 657        slot_func->configured = 0;
 658        dbg("board_added(%p, %p)\n", slot_func, ctrl);
 659        return cpqhp_process_SI(ctrl, slot_func);
 660}
 661
 662
 663static int process_SS (struct hotplug_slot *hotplug_slot)
 664{
 665        struct pci_func *slot_func;
 666        struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
 667        struct controller *ctrl;
 668        u8 bus;
 669        u8 devfn;
 670        u8 device;
 671        u8 function;
 672        
 673        if (slot == NULL)
 674                return -ENODEV;
 675        
 676        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
 677
 678        ctrl = slot->ctrl;
 679        if (ctrl == NULL)
 680                return -ENODEV;
 681        
 682        if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
 683                return -ENODEV;
 684
 685        device = devfn >> 3;
 686        function = devfn & 0x7;
 687        dbg("bus, dev, fn = %d, %d, %d\n", bus, device, function);
 688
 689        slot_func = cpqhp_slot_find(bus, device, function);
 690        if (!slot_func) {
 691                return -ENODEV;
 692        }
 693        
 694        dbg("In power_down_board, slot_func = %p, ctrl = %p\n", slot_func, ctrl);
 695        return cpqhp_process_SS(ctrl, slot_func);
 696}
 697
 698
 699static int hardware_test (struct hotplug_slot *hotplug_slot, u32 value)
 700{
 701        struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
 702        struct controller *ctrl;
 703
 704        dbg("%s\n", __FUNCTION__);
 705
 706        if (slot == NULL)
 707                return -ENODEV;
 708
 709        ctrl = slot->ctrl;
 710        if (ctrl == NULL)
 711                return -ENODEV;
 712
 713        return cpqhp_hardware_test (ctrl, value);       
 714}
 715
 716
 717static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
 718{
 719        struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
 720        struct controller *ctrl;
 721        
 722        if (slot == NULL)
 723                return -ENODEV;
 724        
 725        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
 726
 727        ctrl = slot->ctrl;
 728        if (ctrl == NULL)
 729                return -ENODEV;
 730        
 731        *value = get_slot_enabled(ctrl, slot);
 732        return 0;
 733}
 734
 735static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
 736{
 737        struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
 738        struct controller *ctrl;
 739        
 740        if (slot == NULL)
 741                return -ENODEV;
 742        
 743        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
 744
 745        ctrl = slot->ctrl;
 746        if (ctrl == NULL)
 747                return -ENODEV;
 748        
 749        *value = cpq_get_attention_status(ctrl, slot);
 750        return 0;
 751}
 752
 753static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
 754{
 755        struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
 756        struct controller *ctrl;
 757        
 758        if (slot == NULL)
 759                return -ENODEV;
 760        
 761        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
 762
 763        ctrl = slot->ctrl;
 764        if (ctrl == NULL)
 765                return -ENODEV;
 766        
 767        *value = cpq_get_latch_status (ctrl, slot);
 768
 769        return 0;
 770}
 771
 772static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
 773{
 774        struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
 775        struct controller *ctrl;
 776        
 777        if (slot == NULL)
 778                return -ENODEV;
 779        
 780        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
 781
 782        ctrl = slot->ctrl;
 783        if (ctrl == NULL)
 784                return -ENODEV;
 785        
 786        *value = get_presence_status (ctrl, slot);
 787
 788        return 0;
 789}
 790
 791static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
 792{
 793        struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
 794        struct controller *ctrl;
 795        
 796        if (slot == NULL)
 797                return -ENODEV;
 798
 799        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
 800
 801        ctrl = slot->ctrl;
 802        if (ctrl == NULL)
 803                return -ENODEV;
 804        
 805        *value = ctrl->speed_capability;
 806
 807        return 0;
 808}
 809
 810static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
 811{
 812        struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
 813        struct controller *ctrl;
 814        
 815        if (slot == NULL)
 816                return -ENODEV;
 817
 818        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
 819
 820        ctrl = slot->ctrl;
 821        if (ctrl == NULL)
 822                return -ENODEV;
 823        
 824        *value = ctrl->speed;
 825
 826        return 0;
 827}
 828
 829static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 830{
 831        u8 num_of_slots = 0;
 832        u8 hp_slot = 0;
 833        u8 device;
 834        u8 rev;
 835        u8 bus_cap;
 836        u16 temp_word;
 837        u16 vendor_id;
 838        u16 subsystem_vid;
 839        u16 subsystem_deviceid;
 840        u32 rc;
 841        struct controller *ctrl;
 842        struct pci_func *func;
 843
 844        // Need to read VID early b/c it's used to differentiate CPQ and INTC discovery
 845        rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id);
 846        if (rc || ((vendor_id != PCI_VENDOR_ID_COMPAQ) && (vendor_id != PCI_VENDOR_ID_INTEL))) {
 847                err(msg_HPC_non_compaq_or_intel);
 848                return -ENODEV;
 849        }
 850        dbg("Vendor ID: %x\n", vendor_id);
 851
 852        rc = pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
 853        dbg("revision: %d\n", rev);
 854        if (rc || ((vendor_id == PCI_VENDOR_ID_COMPAQ) && (!rev))) {
 855                err(msg_HPC_rev_error);
 856                return -ENODEV;
 857        }
 858
 859        /* Check for the proper subsytem ID's
 860         * Intel uses a different SSID programming model than Compaq.  
 861         * For Intel, each SSID bit identifies a PHP capability.
 862         * Also Intel HPC's may have RID=0.
 863         */
 864        if ((rev > 2) || (vendor_id == PCI_VENDOR_ID_INTEL)) {
 865                // TODO: This code can be made to support non-Compaq or Intel subsystem IDs
 866                rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid);
 867                if (rc) {
 868                        err("%s : pci_read_config_word failed\n", __FUNCTION__);
 869                        return rc;
 870                }
 871                dbg("Subsystem Vendor ID: %x\n", subsystem_vid);
 872                if ((subsystem_vid != PCI_VENDOR_ID_COMPAQ) && (subsystem_vid != PCI_VENDOR_ID_INTEL)) {
 873                        err(msg_HPC_non_compaq_or_intel);
 874                        return -ENODEV;
 875                }
 876
 877                ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL);
 878                if (!ctrl) {
 879                        err("%s : out of memory\n", __FUNCTION__);
 880                        return -ENOMEM;
 881                }
 882                memset(ctrl, 0, sizeof(struct controller));
 883
 884                rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid);
 885                if (rc) {
 886                        err("%s : pci_read_config_word failed\n", __FUNCTION__);
 887                        goto err_free_ctrl;
 888                }
 889
 890                info("Hot Plug Subsystem Device ID: %x\n", subsystem_deviceid);
 891
 892                /* Set Vendor ID, so it can be accessed later from other functions */
 893                ctrl->vendor_id = vendor_id;
 894
 895                switch (subsystem_vid) {
 896                        case PCI_VENDOR_ID_COMPAQ:
 897                                if (rev >= 0x13) { /* CIOBX */
 898                                        ctrl->push_flag = 1;
 899                                        ctrl->slot_switch_type = 1;             // Switch is present
 900                                        ctrl->push_button = 1;                  // Pushbutton is present
 901                                        ctrl->pci_config_space = 1;             // Index/data access to working registers 0 = not supported, 1 = supported
 902                                        ctrl->defeature_PHP = 1;                // PHP is supported
 903                                        ctrl->pcix_support = 1;                 // PCI-X supported
 904                                        ctrl->pcix_speed_capability = 1;
 905                                        pci_read_config_byte(pdev, 0x41, &bus_cap);
 906                                        if (bus_cap & 0x80) {
 907                                                dbg("bus max supports 133MHz PCI-X\n");
 908                                                ctrl->speed_capability = PCI_SPEED_133MHz_PCIX;
 909                                                break;
 910                                        }
 911                                        if (bus_cap & 0x40) {
 912                                                dbg("bus max supports 100MHz PCI-X\n");
 913                                                ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
 914                                                break;
 915                                        }
 916                                        if (bus_cap & 20) {
 917                                                dbg("bus max supports 66MHz PCI-X\n");
 918                                                ctrl->speed_capability = PCI_SPEED_66MHz_PCIX;
 919                                                break;
 920                                        }
 921                                        if (bus_cap & 10) {
 922                                                dbg("bus max supports 66MHz PCI\n");
 923                                                ctrl->speed_capability = PCI_SPEED_66MHz;
 924                                                break;
 925                                        }
 926
 927                                        break;
 928                                }
 929
 930                                switch (subsystem_deviceid) {
 931                                        case PCI_SUB_HPC_ID:
 932                                                /* Original 6500/7000 implementation */
 933                                                ctrl->slot_switch_type = 1;             // Switch is present
 934                                                ctrl->speed_capability = PCI_SPEED_33MHz;
 935                                                ctrl->push_button = 0;                  // No pushbutton
 936                                                ctrl->pci_config_space = 1;             // Index/data access to working registers 0 = not supported, 1 = supported
 937                                                ctrl->defeature_PHP = 1;                // PHP is supported
 938                                                ctrl->pcix_support = 0;                 // PCI-X not supported
 939                                                ctrl->pcix_speed_capability = 0;        // N/A since PCI-X not supported
 940                                                break;
 941                                        case PCI_SUB_HPC_ID2:
 942                                                /* First Pushbutton implementation */
 943                                                ctrl->push_flag = 1;
 944                                                ctrl->slot_switch_type = 1;             // Switch is present
 945                                                ctrl->speed_capability = PCI_SPEED_33MHz;
 946                                                ctrl->push_button = 1;                  // Pushbutton is present
 947                                                ctrl->pci_config_space = 1;             // Index/data access to working registers 0 = not supported, 1 = supported
 948                                                ctrl->defeature_PHP = 1;                // PHP is supported
 949                                                ctrl->pcix_support = 0;                 // PCI-X not supported
 950                                                ctrl->pcix_speed_capability = 0;        // N/A since PCI-X not supported
 951                                                break;
 952                                        case PCI_SUB_HPC_ID_INTC:
 953                                                /* Third party (6500/7000) */
 954                                                ctrl->slot_switch_type = 1;             // Switch is present
 955                                                ctrl->speed_capability = PCI_SPEED_33MHz;
 956                                                ctrl->push_button = 0;                  // No pushbutton
 957                                                ctrl->pci_config_space = 1;             // Index/data access to working registers 0 = not supported, 1 = supported
 958                                                ctrl->defeature_PHP = 1;                        // PHP is supported
 959                                                ctrl->pcix_support = 0;                 // PCI-X not supported
 960                                                ctrl->pcix_speed_capability = 0;                // N/A since PCI-X not supported
 961                                                break;
 962                                        case PCI_SUB_HPC_ID3:
 963                                                /* First 66 Mhz implementation */
 964                                                ctrl->push_flag = 1;
 965                                                ctrl->slot_switch_type = 1;             // Switch is present
 966                                                ctrl->speed_capability = PCI_SPEED_66MHz;
 967                                                ctrl->push_button = 1;                  // Pushbutton is present
 968                                                ctrl->pci_config_space = 1;             // Index/data access to working registers 0 = not supported, 1 = supported
 969                                                ctrl->defeature_PHP = 1;                // PHP is supported
 970                                                ctrl->pcix_support = 0;                 // PCI-X not supported
 971                                                ctrl->pcix_speed_capability = 0;        // N/A since PCI-X not supported
 972                                                break;
 973                                        case PCI_SUB_HPC_ID4:
 974                                                /* First PCI-X implementation, 100MHz */
 975                                                ctrl->push_flag = 1;
 976                                                ctrl->slot_switch_type = 1;             // Switch is present
 977                                                ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
 978                                                ctrl->push_button = 1;                  // Pushbutton is present
 979                                                ctrl->pci_config_space = 1;             // Index/data access to working registers 0 = not supported, 1 = supported
 980                                                ctrl->defeature_PHP = 1;                // PHP is supported
 981                                                ctrl->pcix_support = 1;                 // PCI-X supported
 982                                                ctrl->pcix_speed_capability = 0;        
 983                                                break;
 984                                        default:
 985                                                err(msg_HPC_not_supported);
 986                                                rc = -ENODEV;
 987                                                goto err_free_ctrl;
 988                                }
 989                                break;
 990
 991                        case PCI_VENDOR_ID_INTEL:
 992                                /* Check for speed capability (0=33, 1=66) */
 993                                if (subsystem_deviceid & 0x0001) {
 994                                        ctrl->speed_capability = PCI_SPEED_66MHz;
 995                                } else {
 996                                        ctrl->speed_capability = PCI_SPEED_33MHz;
 997                                }
 998
 999                                /* Check for push button */
1000                                if (subsystem_deviceid & 0x0002) {
1001                                        /* no push button */
1002                                        ctrl->push_button = 0;
1003                                } else {
1004                                        /* push button supported */
1005                                        ctrl->push_button = 1;
1006                                }
1007
1008                                /* Check for slot switch type (0=mechanical, 1=not mechanical) */
1009                                if (subsystem_deviceid & 0x0004) {
1010                                        /* no switch */
1011                                        ctrl->slot_switch_type = 0;
1012                                } else {
1013                                        /* switch */
1014                                        ctrl->slot_switch_type = 1;
1015                                }
1016
1017                                /* PHP Status (0=De-feature PHP, 1=Normal operation) */
1018                                if (subsystem_deviceid & 0x0008) {
1019                                        ctrl->defeature_PHP = 1;        // PHP supported
1020                                } else {
1021                                        ctrl->defeature_PHP = 0;        // PHP not supported
1022                                }
1023
1024                                /* Alternate Base Address Register Interface (0=not supported, 1=supported) */
1025                                if (subsystem_deviceid & 0x0010) {
1026                                        ctrl->alternate_base_address = 1;       // supported
1027                                } else {
1028                                        ctrl->alternate_base_address = 0;       // not supported
1029                                }
1030
1031                                /* PCI Config Space Index (0=not supported, 1=supported) */
1032                                if (subsystem_deviceid & 0x0020) {
1033                                        ctrl->pci_config_space = 1;             // supported
1034                                } else {
1035                                        ctrl->pci_config_space = 0;             // not supported
1036                                }
1037
1038                                /* PCI-X support */
1039                                if (subsystem_deviceid & 0x0080) {
1040                                        /* PCI-X capable */
1041                                        ctrl->pcix_support = 1;
1042                                        /* Frequency of operation in PCI-X mode */
1043                                        if (subsystem_deviceid & 0x0040) {
1044                                                /* 133MHz PCI-X if bit 7 is 1 */
1045                                                ctrl->pcix_speed_capability = 1;
1046                                        } else {
1047                                                /* 100MHz PCI-X if bit 7 is 1 and bit 0 is 0, */
1048                                                /* 66MHz PCI-X if bit 7 is 1 and bit 0 is 1 */
1049                                                ctrl->pcix_speed_capability = 0;
1050                                        }
1051                                } else {
1052                                        /* Conventional PCI */
1053                                        ctrl->pcix_support = 0;
1054                                        ctrl->pcix_speed_capability = 0;
1055                                }
1056                                break;
1057
1058                        default:
1059                                err(msg_HPC_not_supported);
1060                                rc = -ENODEV;
1061                                goto err_free_ctrl;
1062                }
1063
1064        } else {
1065                err(msg_HPC_not_supported);
1066                return -ENODEV;
1067        }
1068
1069        // Tell the user that we found one.
1070        info("Initializing the PCI hot plug controller residing on PCI bus %d\n", pdev->bus->number);
1071
1072        dbg ("Hotplug controller capabilities:\n");
1073        dbg ("    speed_capability       %d\n", ctrl->speed_capability);
1074        dbg ("    slot_switch_type       %s\n", ctrl->slot_switch_type == 0 ? "no switch" : "switch present");
1075        dbg ("    defeature_PHP          %s\n", ctrl->defeature_PHP == 0 ? "PHP not supported" : "PHP supported");
1076        dbg ("    alternate_base_address %s\n", ctrl->alternate_base_address == 0 ? "not supported" : "supported");
1077        dbg ("    pci_config_space       %s\n", ctrl->pci_config_space == 0 ? "not supported" : "supported");
1078        dbg ("    pcix_speed_capability  %s\n", ctrl->pcix_speed_capability == 0 ? "not supported" : "supported");
1079        dbg ("    pcix_support           %s\n", ctrl->pcix_support == 0 ? "not supported" : "supported");
1080
1081        ctrl->pci_dev = pdev;
1082        ctrl->pci_ops = pdev->bus->ops;
1083        ctrl->bus = pdev->bus->number;
1084        ctrl->device = PCI_SLOT(pdev->devfn);
1085        ctrl->function = PCI_FUNC(pdev->devfn);
1086        ctrl->rev = rev;
1087        dbg("bus device function rev: %d %d %d %d\n", ctrl->bus, ctrl->device, ctrl->function, ctrl->rev);
1088
1089        init_MUTEX(&ctrl->crit_sect);
1090        init_waitqueue_head(&ctrl->queue);
1091
1092        /* initialize our threads if they haven't already been started up */
1093        rc = one_time_init();
1094        if (rc) {
1095                goto err_free_ctrl;
1096        }
1097        
1098        dbg("pdev = %p\n", pdev);
1099        dbg("pci resource start %lx\n", pci_resource_start(pdev, 0));
1100        dbg("pci resource len %lx\n", pci_resource_len(pdev, 0));
1101
1102        if (!request_mem_region(pci_resource_start(pdev, 0),
1103                                pci_resource_len(pdev, 0), MY_NAME)) {
1104                err("cannot reserve MMIO region\n");
1105                rc = -ENOMEM;
1106                goto err_free_ctrl;
1107        }
1108
1109        ctrl->hpc_reg = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
1110        if (!ctrl->hpc_reg) {
1111                err("cannot remap MMIO region %lx @ %lx\n", pci_resource_len(pdev, 0), pci_resource_start(pdev, 0));
1112                rc = -ENODEV;
1113                goto err_free_mem_region;
1114        }
1115
1116        // Check for 66Mhz and/or PCI-X operation
1117        ctrl->speed = get_controller_speed(ctrl);
1118        
1119        //**************************************************
1120        //
1121        //              Save configuration headers for this and
1122        //              subordinate PCI buses
1123        //
1124        //**************************************************
1125
1126        // find the physical slot number of the first hot plug slot
1127
1128        // Get slot won't work for devices behind bridges, but
1129        // in this case it will always be called for the "base"
1130        // bus/dev/func of a slot.
1131        // CS: this is leveraging the PCIIRQ routing code from the kernel (pci-pc.c: get_irq_routing_table)
1132        rc = get_slot_mapping(ctrl->pci_ops, pdev->bus->number, (readb(ctrl->hpc_reg + SLOT_MASK) >> 4), &(ctrl->first_slot));
1133        dbg("get_slot_mapping: first_slot = %d, returned = %d\n", ctrl->first_slot, rc);
1134        if (rc) {
1135                err(msg_initialization_err, rc);
1136                goto err_iounmap;
1137        }
1138
1139        // Store PCI Config Space for all devices on this bus
1140        rc = cpqhp_save_config(ctrl, ctrl->bus, readb(ctrl->hpc_reg + SLOT_MASK));
1141        if (rc) {
1142                err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc);
1143                goto err_iounmap;
1144        }
1145
1146        /*
1147         * Get IO, memory, and IRQ resources for new devices
1148         */
1149        // The next line is required for cpqhp_find_available_resources
1150        ctrl->interrupt = pdev->irq;
1151
1152        rc = cpqhp_find_available_resources(ctrl, cpqhp_rom_start);
1153        ctrl->add_support = !rc;
1154        if (rc) {
1155                dbg("cpqhp_find_available_resources = 0x%x\n", rc);
1156                err("unable to locate PCI configuration resources for hot plug add.\n");
1157                goto err_iounmap;
1158        }
1159
1160        /*
1161         * Finish setting up the hot plug ctrl device
1162         */
1163        ctrl->slot_device_offset = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
1164        dbg("NumSlots %d \n", ctrl->slot_device_offset);
1165
1166        ctrl->next_event = 0;
1167
1168        /* Setup the slot information structures */
1169        rc = ctrl_slot_setup(ctrl, smbios_start, smbios_table);
1170        if (rc) {
1171                err(msg_initialization_err, 6);
1172                err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc);
1173                goto err_iounmap;
1174        }
1175        
1176        /* Mask all general input interrupts */
1177        writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_MASK);
1178
1179        /* set up the interrupt */
1180        dbg("HPC interrupt = %d \n", ctrl->interrupt);
1181        if (request_irq(ctrl->interrupt,
1182                        (void (*)(int, void *, struct pt_regs *)) &cpqhp_ctrl_intr,
1183                        SA_SHIRQ, MY_NAME, ctrl)) {
1184                err("Can't get irq %d for the hotplug pci controller\n", ctrl->interrupt);
1185                rc = -ENODEV;
1186                goto err_iounmap;
1187        }
1188
1189        /* Enable Shift Out interrupt and clear it, also enable SERR on power fault */
1190        temp_word = readw(ctrl->hpc_reg + MISC);
1191        temp_word |= 0x4006;
1192        writew(temp_word, ctrl->hpc_reg + MISC);
1193
1194        // Changed 05/05/97 to clear all interrupts at start
1195        writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_INPUT_CLEAR);
1196
1197        ctrl->ctrl_int_comp = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
1198
1199        writel(0x0L, ctrl->hpc_reg + INT_MASK);
1200
1201        if (!cpqhp_ctrl_list) {
1202                cpqhp_ctrl_list = ctrl;
1203                ctrl->next = NULL;
1204        } else {
1205                ctrl->next = cpqhp_ctrl_list;
1206                cpqhp_ctrl_list = ctrl;
1207        }
1208
1209        // turn off empty slots here unless command line option "ON" set
1210        // Wait for exclusive access to hardware
1211        down(&ctrl->crit_sect);
1212
1213        num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
1214
1215        // find first device number for the ctrl
1216        device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
1217
1218        while (num_of_slots) {
1219                dbg("num_of_slots: %d\n", num_of_slots);
1220                func = cpqhp_slot_find(ctrl->bus, device, 0);
1221                if (!func)
1222                        break;
1223
1224                hp_slot = func->device - ctrl->slot_device_offset;
1225                dbg("hp_slot: %d\n", hp_slot);
1226
1227                // We have to save the presence info for these slots
1228                temp_word = ctrl->ctrl_int_comp >> 16;
1229                func->presence_save = (temp_word >> hp_slot) & 0x01;
1230                func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
1231
1232                if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
1233                        func->switch_save = 0;
1234                } else {
1235                        func->switch_save = 0x10;
1236                }
1237
1238                if (!power_mode) {
1239                        if (!func->is_a_board) {
1240                                green_LED_off (ctrl, hp_slot);
1241                                slot_disable (ctrl, hp_slot);
1242                        }
1243                }
1244
1245                device++;
1246                num_of_slots--;
1247        }
1248
1249        if (!power_mode) {
1250                set_SOGO(ctrl);
1251                // Wait for SOBS to be unset
1252                wait_for_ctrl_irq (ctrl);
1253        }
1254
1255        rc = init_SERR(ctrl);
1256        if (rc) {
1257                err("init_SERR failed\n");
1258                up(&ctrl->crit_sect);
1259                goto err_free_irq;
1260        }
1261
1262        // Done with exclusive hardware access
1263        up(&ctrl->crit_sect);
1264
1265        rc = cpqhp_proc_create_ctrl (ctrl);
1266        if (rc) {
1267                err("cpqhp_proc_create_ctrl failed\n");
1268                goto err_free_irq;
1269        }
1270
1271        return 0;
1272
1273err_free_irq:
1274        free_irq(ctrl->interrupt, ctrl);
1275err_iounmap:
1276        iounmap(ctrl->hpc_reg);
1277err_free_mem_region:
1278        release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
1279err_free_ctrl:
1280        kfree(ctrl);
1281        return rc;
1282}
1283
1284
1285static int one_time_init(void)
1286{
1287        int loop;
1288        int retval = 0;
1289        static int initialized = 0;
1290
1291        if (initialized)
1292                return 0;
1293
1294        power_mode = 0;
1295
1296        retval = pci_print_IRQ_route();
1297        if (retval)
1298                goto error;
1299
1300        dbg("Initialize + Start the notification mechanism \n");
1301
1302        retval = cpqhp_event_start_thread();
1303        if (retval)
1304                goto error;
1305
1306        dbg("Initialize slot lists\n");
1307        for (loop = 0; loop < 256; loop++) {
1308                cpqhp_slot_list[loop] = NULL;
1309        }
1310
1311        // FIXME: We also need to hook the NMI handler eventually.
1312        // this also needs to be worked with Christoph
1313        // register_NMI_handler();
1314
1315        // Map rom address
1316        cpqhp_rom_start = ioremap(ROM_PHY_ADDR, ROM_PHY_LEN);
1317        if (!cpqhp_rom_start) {
1318                err ("Could not ioremap memory region for ROM\n");
1319                retval = -EIO;;
1320                goto error;
1321        }
1322        
1323        /* Now, map the int15 entry point if we are on compaq specific hardware */
1324        compaq_nvram_init(cpqhp_rom_start);
1325        
1326        /* Map smbios table entry point structure */
1327        smbios_table = detect_SMBIOS_pointer(cpqhp_rom_start, cpqhp_rom_start + ROM_PHY_LEN);
1328        if (!smbios_table) {
1329                err ("Could not find the SMBIOS pointer in memory\n");
1330                retval = -EIO;;
1331                goto error;
1332        }
1333
1334        smbios_start = ioremap(readl(smbios_table + ST_ADDRESS), readw(smbios_table + ST_LENGTH));
1335        if (!smbios_start) {
1336                err ("Could not ioremap memory region taken from SMBIOS values\n");
1337                retval = -EIO;;
1338                goto error;
1339        }
1340
1341        retval = cpqhp_proc_init_ctrl();
1342        if (retval)
1343                goto error;
1344
1345        initialized = 1;
1346
1347        return retval;
1348
1349error:
1350        if (cpqhp_rom_start)
1351                iounmap(cpqhp_rom_start);
1352        if (smbios_start)
1353                iounmap(smbios_start);
1354        
1355        return retval;
1356}
1357
1358
1359static void unload_cpqphpd(void)
1360{
1361        struct pci_func *next;
1362        struct pci_func *TempSlot;
1363        int loop;
1364        u32 rc;
1365        struct controller *ctrl;
1366        struct controller *tctrl;
1367        struct pci_resource *res;
1368        struct pci_resource *tres;
1369
1370        rc = compaq_nvram_store(cpqhp_rom_start);
1371
1372        ctrl = cpqhp_ctrl_list;
1373
1374        while (ctrl) {
1375                cpqhp_proc_remove_ctrl (ctrl);
1376
1377                if (ctrl->hpc_reg) {
1378                        u16 misc;
1379                        rc = read_slot_enable (ctrl);
1380                        
1381                        writeb(0, ctrl->hpc_reg + SLOT_SERR);
1382                        writel(0xFFFFFFC0L | ~rc, ctrl->hpc_reg + INT_MASK);
1383                        
1384                        misc = readw(ctrl->hpc_reg + MISC);
1385                        misc &= 0xFFFD;
1386                        writew(misc, ctrl->hpc_reg + MISC);
1387                }
1388
1389                ctrl_slot_cleanup(ctrl);
1390
1391                res = ctrl->io_head;
1392                while (res) {
1393                        tres = res;
1394                        res = res->next;
1395                        kfree(tres);
1396                }
1397
1398                res = ctrl->mem_head;
1399                while (res) {
1400                        tres = res;
1401                        res = res->next;
1402                        kfree(tres);
1403                }
1404
1405                res = ctrl->p_mem_head;
1406                while (res) {
1407                        tres = res;
1408                        res = res->next;
1409                        kfree(tres);
1410                }
1411
1412                res = ctrl->bus_head;
1413                while (res) {
1414                        tres = res;
1415                        res = res->next;
1416                        kfree(tres);
1417                }
1418
1419                tctrl = ctrl;
1420                ctrl = ctrl->next;
1421                kfree(tctrl);
1422        }
1423
1424        for (loop = 0; loop < 256; loop++) {
1425                next = cpqhp_slot_list[loop];
1426                while (next != NULL) {
1427                        res = next->io_head;
1428                        while (res) {
1429                                tres = res;
1430                                res = res->next;
1431                                kfree(tres);
1432                        }
1433
1434                        res = next->mem_head;
1435                        while (res) {
1436                                tres = res;
1437                                res = res->next;
1438                                kfree(tres);
1439                        }
1440
1441                        res = next->p_mem_head;
1442                        while (res) {
1443                                tres = res;
1444                                res = res->next;
1445                                kfree(tres);
1446                        }
1447
1448                        res = next->bus_head;
1449                        while (res) {
1450                                tres = res;
1451                                res = res->next;
1452                                kfree(tres);
1453                        }
1454
1455                        TempSlot = next;
1456                        next = next->next;
1457                        kfree(TempSlot);
1458                }
1459        }
1460
1461        remove_proc_entry("hpc", 0);
1462
1463        // Stop the notification mechanism
1464        cpqhp_event_stop_thread();
1465
1466        //unmap the rom address
1467        if (cpqhp_rom_start)
1468                iounmap(cpqhp_rom_start);
1469        if (smbios_start)
1470                iounmap(smbios_start);
1471}
1472
1473
1474
1475static struct pci_device_id hpcd_pci_tbl[] __devinitdata = {
1476        {
1477        /* handle any PCI Hotplug controller */
1478        class:          ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),
1479        class_mask:     ~0,
1480        
1481        /* no matter who makes it */
1482        vendor:         PCI_ANY_ID,
1483        device:         PCI_ANY_ID,
1484        subvendor:      PCI_ANY_ID,
1485        subdevice:      PCI_ANY_ID,
1486        
1487        }, { /* end: all zeroes */ }
1488};
1489
1490MODULE_DEVICE_TABLE(pci, hpcd_pci_tbl);
1491
1492
1493
1494static struct pci_driver cpqhpc_driver = {
1495        name:           "pci_hotplug",
1496        id_table:       hpcd_pci_tbl,
1497        probe:          cpqhpc_probe,
1498        /* remove:      cpqhpc_remove_one, */
1499};
1500
1501
1502
1503static int __init cpqhpc_init(void)
1504{
1505        int result;
1506
1507        cpqhp_debug = debug;
1508
1509        result = pci_module_init(&cpqhpc_driver);
1510        dbg("pci_module_init = %d\n", result);
1511        if (result)
1512                return result;
1513        info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
1514        return 0;
1515}
1516
1517
1518static void __exit cpqhpc_cleanup(void)
1519{
1520        dbg("cleaning up proc entries\n");
1521        cpqhp_proc_destroy_ctrl();
1522
1523        dbg("unload_cpqphpd()\n");
1524        unload_cpqphpd();
1525
1526        dbg("pci_unregister_driver\n");
1527        pci_unregister_driver(&cpqhpc_driver);
1528}
1529
1530
1531module_init(cpqhpc_init);
1532module_exit(cpqhpc_cleanup);
1533
1534
1535
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.