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