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