linux/drivers/pci/hotplug/ibmphp_core.c
<<
>>
Prefs
   1/*
   2 * IBM Hot Plug Controller Driver
   3 *
   4 * Written By: Chuck Cole, Jyoti Shah, Tong Yu, Irene Zubarev, IBM Corporation
   5 *
   6 * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
   7 * Copyright (C) 2001-2003 IBM Corp.
   8 *
   9 * All rights reserved.
  10 *
  11 * This program is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License as published by
  13 * the Free Software Foundation; either version 2 of the License, or (at
  14 * your option) any later version.
  15 *
  16 * This program is distributed in the hope that it will be useful, but
  17 * WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  19 * NON INFRINGEMENT.  See the GNU General Public License for more
  20 * details.
  21 *
  22 * You should have received a copy of the GNU General Public License
  23 * along with this program; if not, write to the Free Software
  24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  25 *
  26 * Send feedback to <gregkh@us.ibm.com>
  27 *
  28 */
  29
  30#include <linux/init.h>
  31#include <linux/module.h>
  32#include <linux/slab.h>
  33#include <linux/pci.h>
  34#include <linux/interrupt.h>
  35#include <linux/delay.h>
  36#include <linux/wait.h>
  37#include "../pci.h"
  38#include <asm/pci_x86.h>                /* for struct irq_routing_table */
  39#include "ibmphp.h"
  40
  41#define attn_on(sl)  ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNON)
  42#define attn_off(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNOFF)
  43#define attn_LED_blink(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_BLINKLED)
  44#define get_ctrl_revision(sl, rev) ibmphp_hpc_readslot (sl, READ_REVLEVEL, rev)
  45#define get_hpc_options(sl, opt) ibmphp_hpc_readslot (sl, READ_HPCOPTIONS, opt)
  46
  47#define DRIVER_VERSION  "0.6"
  48#define DRIVER_DESC     "IBM Hot Plug PCI Controller Driver"
  49
  50int ibmphp_debug;
  51
  52static int debug;
  53module_param(debug, bool, S_IRUGO | S_IWUSR);
  54MODULE_PARM_DESC (debug, "Debugging mode enabled or not");
  55MODULE_LICENSE ("GPL");
  56MODULE_DESCRIPTION (DRIVER_DESC);
  57
  58struct pci_bus *ibmphp_pci_bus;
  59static int max_slots;
  60
  61static int irqs[16];    /* PIC mode IRQ's we're using so far (in case MPS
  62                         * tables don't provide default info for empty slots */
  63
  64static int init_flag;
  65
  66/*
  67static int get_max_adapter_speed_1 (struct hotplug_slot *, u8 *, u8);
  68
  69static inline int get_max_adapter_speed (struct hotplug_slot *hs, u8 *value)
  70{
  71        return get_max_adapter_speed_1 (hs, value, 1);
  72}
  73*/
  74static inline int get_cur_bus_info(struct slot **sl) 
  75{
  76        int rc = 1;
  77        struct slot * slot_cur = *sl;
  78
  79        debug("options = %x\n", slot_cur->ctrl->options);
  80        debug("revision = %x\n", slot_cur->ctrl->revision);     
  81
  82        if (READ_BUS_STATUS(slot_cur->ctrl)) 
  83                rc = ibmphp_hpc_readslot(slot_cur, READ_BUSSTATUS, NULL);
  84        
  85        if (rc) 
  86                return rc;
  87          
  88        slot_cur->bus_on->current_speed = CURRENT_BUS_SPEED(slot_cur->busstatus);
  89        if (READ_BUS_MODE(slot_cur->ctrl))
  90                slot_cur->bus_on->current_bus_mode =
  91                                CURRENT_BUS_MODE(slot_cur->busstatus);
  92        else
  93                slot_cur->bus_on->current_bus_mode = 0xFF;
  94
  95        debug("busstatus = %x, bus_speed = %x, bus_mode = %x\n",
  96                        slot_cur->busstatus,
  97                        slot_cur->bus_on->current_speed,
  98                        slot_cur->bus_on->current_bus_mode);
  99        
 100        *sl = slot_cur;
 101        return 0;
 102}
 103
 104static inline int slot_update(struct slot **sl)
 105{
 106        int rc;
 107        rc = ibmphp_hpc_readslot(*sl, READ_ALLSTAT, NULL);
 108        if (rc) 
 109                return rc;
 110        if (!init_flag)
 111                rc = get_cur_bus_info(sl);
 112        return rc;
 113}
 114
 115static int __init get_max_slots (void)
 116{
 117        struct slot * slot_cur;
 118        struct list_head * tmp;
 119        u8 slot_count = 0;
 120
 121        list_for_each(tmp, &ibmphp_slot_head) {
 122                slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
 123                /* sometimes the hot-pluggable slots start with 4 (not always from 1) */
 124                slot_count = max(slot_count, slot_cur->number);
 125        }
 126        return slot_count;
 127}
 128
 129/* This routine will put the correct slot->device information per slot.  It's
 130 * called from initialization of the slot structures. It will also assign
 131 * interrupt numbers per each slot.
 132 * Parameters: struct slot
 133 * Returns 0 or errors
 134 */
 135int ibmphp_init_devno(struct slot **cur_slot)
 136{
 137        struct irq_routing_table *rtable;
 138        int len;
 139        int loop;
 140        int i;
 141
 142        rtable = pcibios_get_irq_routing_table();
 143        if (!rtable) {
 144                err("no BIOS routing table...\n");
 145                return -ENOMEM;
 146        }
 147
 148        len = (rtable->size - sizeof(struct irq_routing_table)) /
 149                        sizeof(struct irq_info);
 150
 151        if (!len) {
 152                kfree(rtable);
 153                return -1;
 154        }
 155        for (loop = 0; loop < len; loop++) {
 156                if ((*cur_slot)->number == rtable->slots[loop].slot &&
 157                    (*cur_slot)->bus == rtable->slots[loop].bus) {
 158                        struct io_apic_irq_attr irq_attr;
 159
 160                        (*cur_slot)->device = PCI_SLOT(rtable->slots[loop].devfn);
 161                        for (i = 0; i < 4; i++)
 162                                (*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector((int) (*cur_slot)->bus,
 163                                                (int) (*cur_slot)->device, i,
 164                                                &irq_attr);
 165
 166                        debug("(*cur_slot)->irq[0] = %x\n",
 167                                        (*cur_slot)->irq[0]);
 168                        debug("(*cur_slot)->irq[1] = %x\n",
 169                                        (*cur_slot)->irq[1]);
 170                        debug("(*cur_slot)->irq[2] = %x\n",
 171                                        (*cur_slot)->irq[2]);
 172                        debug("(*cur_slot)->irq[3] = %x\n",
 173                                        (*cur_slot)->irq[3]);
 174
 175                        debug("rtable->exlusive_irqs = %x\n",
 176                                        rtable->exclusive_irqs);
 177                        debug("rtable->slots[loop].irq[0].bitmap = %x\n",
 178                                        rtable->slots[loop].irq[0].bitmap);
 179                        debug("rtable->slots[loop].irq[1].bitmap = %x\n",
 180                                        rtable->slots[loop].irq[1].bitmap);
 181                        debug("rtable->slots[loop].irq[2].bitmap = %x\n",
 182                                        rtable->slots[loop].irq[2].bitmap);
 183                        debug("rtable->slots[loop].irq[3].bitmap = %x\n",
 184                                        rtable->slots[loop].irq[3].bitmap);
 185
 186                        debug("rtable->slots[loop].irq[0].link = %x\n",
 187                                        rtable->slots[loop].irq[0].link);
 188                        debug("rtable->slots[loop].irq[1].link = %x\n",
 189                                        rtable->slots[loop].irq[1].link);
 190                        debug("rtable->slots[loop].irq[2].link = %x\n",
 191                                        rtable->slots[loop].irq[2].link);
 192                        debug("rtable->slots[loop].irq[3].link = %x\n",
 193                                        rtable->slots[loop].irq[3].link);
 194                        debug("end of init_devno\n");
 195                        kfree(rtable);
 196                        return 0;
 197                }
 198        }
 199
 200        kfree(rtable);
 201        return -1;
 202}
 203
 204static inline int power_on(struct slot *slot_cur)
 205{
 206        u8 cmd = HPC_SLOT_ON;
 207        int retval;
 208
 209        retval = ibmphp_hpc_writeslot(slot_cur, cmd);
 210        if (retval) {
 211                err("power on failed\n");
 212                return retval;
 213        }
 214        if (CTLR_RESULT(slot_cur->ctrl->status)) {
 215                err("command not completed successfully in power_on\n");
 216                return -EIO;
 217        }
 218        msleep(3000);   /* For ServeRAID cards, and some 66 PCI */
 219        return 0;
 220}
 221
 222static inline int power_off(struct slot *slot_cur)
 223{
 224        u8 cmd = HPC_SLOT_OFF;
 225        int retval;
 226
 227        retval = ibmphp_hpc_writeslot(slot_cur, cmd);
 228        if (retval) {
 229                err("power off failed\n");
 230                return retval;
 231        }
 232        if (CTLR_RESULT(slot_cur->ctrl->status)) {
 233                err("command not completed successfully in power_off\n");
 234                retval = -EIO;
 235        }
 236        return retval;
 237}
 238
 239static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value)
 240{
 241        int rc = 0;
 242        struct slot *pslot;
 243        u8 cmd = 0x00;     /* avoid compiler warning */
 244
 245        debug("set_attention_status - Entry hotplug_slot[%lx] value[%x]\n",
 246                        (ulong) hotplug_slot, value);
 247        ibmphp_lock_operations();
 248
 249
 250        if (hotplug_slot) {
 251                switch (value) {
 252                case HPC_SLOT_ATTN_OFF:
 253                        cmd = HPC_SLOT_ATTNOFF;
 254                        break;
 255                case HPC_SLOT_ATTN_ON:
 256                        cmd = HPC_SLOT_ATTNON;
 257                        break;
 258                case HPC_SLOT_ATTN_BLINK:
 259                        cmd = HPC_SLOT_BLINKLED;
 260                        break;
 261                default:
 262                        rc = -ENODEV;
 263                        err("set_attention_status - Error : invalid input [%x]\n",
 264                                        value);
 265                        break;
 266                }
 267                if (rc == 0) {
 268                        pslot = hotplug_slot->private;
 269                        if (pslot)
 270                                rc = ibmphp_hpc_writeslot(pslot, cmd);
 271                        else
 272                                rc = -ENODEV;
 273                }
 274        } else  
 275                rc = -ENODEV;
 276
 277        ibmphp_unlock_operations();
 278
 279        debug("set_attention_status - Exit rc[%d]\n", rc);
 280        return rc;
 281}
 282
 283static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value)
 284{
 285        int rc = -ENODEV;
 286        struct slot *pslot;
 287        struct slot myslot;
 288
 289        debug("get_attention_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
 290                                        (ulong) hotplug_slot, (ulong) value);
 291        
 292        ibmphp_lock_operations();
 293        if (hotplug_slot) {
 294                pslot = hotplug_slot->private;
 295                if (pslot) {
 296                        memcpy(&myslot, pslot, sizeof(struct slot));
 297                        rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
 298                                                &(myslot.status));
 299                        if (!rc)
 300                                rc = ibmphp_hpc_readslot(pslot,
 301                                                READ_EXTSLOTSTATUS,
 302                                                &(myslot.ext_status));
 303                        if (!rc)
 304                                *value = SLOT_ATTN(myslot.status,
 305                                                myslot.ext_status);
 306                }
 307        }
 308
 309        ibmphp_unlock_operations();
 310        debug("get_attention_status - Exit rc[%d] value[%x]\n", rc, *value);
 311        return rc;
 312}
 313
 314static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value)
 315{
 316        int rc = -ENODEV;
 317        struct slot *pslot;
 318        struct slot myslot;
 319
 320        debug("get_latch_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
 321                                        (ulong) hotplug_slot, (ulong) value);
 322        ibmphp_lock_operations();
 323        if (hotplug_slot) {
 324                pslot = hotplug_slot->private;
 325                if (pslot) {
 326                        memcpy(&myslot, pslot, sizeof(struct slot));
 327                        rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
 328                                                &(myslot.status));
 329                        if (!rc)
 330                                *value = SLOT_LATCH(myslot.status);
 331                }
 332        }
 333
 334        ibmphp_unlock_operations();
 335        debug("get_latch_status - Exit rc[%d] rc[%x] value[%x]\n",
 336                        rc, rc, *value);
 337        return rc;
 338}
 339
 340
 341static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value)
 342{
 343        int rc = -ENODEV;
 344        struct slot *pslot;
 345        struct slot myslot;
 346
 347        debug("get_power_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
 348                                        (ulong) hotplug_slot, (ulong) value);
 349        ibmphp_lock_operations();
 350        if (hotplug_slot) {
 351                pslot = hotplug_slot->private;
 352                if (pslot) {
 353                        memcpy(&myslot, pslot, sizeof(struct slot));
 354                        rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
 355                                                &(myslot.status));
 356                        if (!rc)
 357                                *value = SLOT_PWRGD(myslot.status);
 358                }
 359        }
 360
 361        ibmphp_unlock_operations();
 362        debug("get_power_status - Exit rc[%d] rc[%x] value[%x]\n",
 363                        rc, rc, *value);
 364        return rc;
 365}
 366
 367static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 * value)
 368{
 369        int rc = -ENODEV;
 370        struct slot *pslot;
 371        u8 present;
 372        struct slot myslot;
 373
 374        debug("get_adapter_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
 375                                        (ulong) hotplug_slot, (ulong) value);
 376        ibmphp_lock_operations();
 377        if (hotplug_slot) {
 378                pslot = hotplug_slot->private;
 379                if (pslot) {
 380                        memcpy(&myslot, pslot, sizeof(struct slot));
 381                        rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
 382                                                &(myslot.status));
 383                        if (!rc) {
 384                                present = SLOT_PRESENT(myslot.status);
 385                                if (present == HPC_SLOT_EMPTY)
 386                                        *value = 0;
 387                                else
 388                                        *value = 1;
 389                        }
 390                }
 391        }
 392
 393        ibmphp_unlock_operations();
 394        debug("get_adapter_present - Exit rc[%d] value[%x]\n", rc, *value);
 395        return rc;
 396}
 397
 398static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
 399{
 400        int rc = -ENODEV;
 401        struct slot *pslot;
 402        u8 mode = 0;
 403
 404        debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __func__,
 405                hotplug_slot, value);
 406
 407        ibmphp_lock_operations();
 408
 409        if (hotplug_slot) {
 410                pslot = hotplug_slot->private;
 411                if (pslot) {
 412                        rc = 0;
 413                        mode = pslot->supported_bus_mode;
 414                        *value = pslot->supported_speed; 
 415                        switch (*value) {
 416                        case BUS_SPEED_33:
 417                                break;
 418                        case BUS_SPEED_66:
 419                                if (mode == BUS_MODE_PCIX) 
 420                                        *value += 0x01;
 421                                break;
 422                        case BUS_SPEED_100:
 423                        case BUS_SPEED_133:
 424                                *value = pslot->supported_speed + 0x01;
 425                                break;
 426                        default:
 427                                /* Note (will need to change): there would be soon 256, 512 also */
 428                                rc = -ENODEV;
 429                        }
 430                }
 431        }
 432
 433        ibmphp_unlock_operations();
 434        debug("%s - Exit rc[%d] value[%x]\n", __func__, rc, *value);
 435        return rc;
 436}
 437
 438static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
 439{
 440        int rc = -ENODEV;
 441        struct slot *pslot;
 442        u8 mode = 0;
 443
 444        debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __func__,
 445                hotplug_slot, value);
 446
 447        ibmphp_lock_operations();
 448
 449        if (hotplug_slot) {
 450                pslot = hotplug_slot->private;
 451                if (pslot) {
 452                        rc = get_cur_bus_info(&pslot);
 453                        if (!rc) {
 454                                mode = pslot->bus_on->current_bus_mode;
 455                                *value = pslot->bus_on->current_speed;
 456                                switch (*value) {
 457                                case BUS_SPEED_33:
 458                                        break;
 459                                case BUS_SPEED_66:
 460                                        if (mode == BUS_MODE_PCIX) 
 461                                                *value += 0x01;
 462                                        else if (mode == BUS_MODE_PCI)
 463                                                ;
 464                                        else
 465                                                *value = PCI_SPEED_UNKNOWN;
 466                                        break;
 467                                case BUS_SPEED_100:
 468                                case BUS_SPEED_133:
 469                                        *value += 0x01;
 470                                        break;
 471                                default:
 472                                        /* Note of change: there would also be 256, 512 soon */
 473                                        rc = -ENODEV;
 474                                }
 475                        }
 476                }
 477        }
 478
 479        ibmphp_unlock_operations();
 480        debug("%s - Exit rc[%d] value[%x]\n", __func__, rc, *value);
 481        return rc;
 482}
 483
 484/*
 485static int get_max_adapter_speed_1(struct hotplug_slot *hotplug_slot, u8 * value, u8 flag)
 486{
 487        int rc = -ENODEV;
 488        struct slot *pslot;
 489        struct slot myslot;
 490
 491        debug("get_max_adapter_speed_1 - Entry hotplug_slot[%lx] pvalue[%lx]\n",
 492                                                (ulong)hotplug_slot, (ulong) value);
 493
 494        if (flag)
 495                ibmphp_lock_operations();
 496
 497        if (hotplug_slot && value) {
 498                pslot = hotplug_slot->private;
 499                if (pslot) {
 500                        memcpy(&myslot, pslot, sizeof(struct slot));
 501                        rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
 502                                                &(myslot.status));
 503
 504                        if (!(SLOT_LATCH (myslot.status)) &&
 505                                        (SLOT_PRESENT (myslot.status))) {
 506                                rc = ibmphp_hpc_readslot(pslot,
 507                                                READ_EXTSLOTSTATUS,
 508                                                &(myslot.ext_status));
 509                                if (!rc)
 510                                        *value = SLOT_SPEED(myslot.ext_status);
 511                        } else
 512                                *value = MAX_ADAPTER_NONE;
 513                }
 514        }
 515
 516        if (flag)
 517                ibmphp_unlock_operations();
 518
 519        debug("get_max_adapter_speed_1 - Exit rc[%d] value[%x]\n", rc, *value);
 520        return rc;
 521}
 522
 523static int get_bus_name(struct hotplug_slot *hotplug_slot, char * value)
 524{
 525        int rc = -ENODEV;
 526        struct slot *pslot = NULL;
 527
 528        debug("get_bus_name - Entry hotplug_slot[%lx]\n", (ulong)hotplug_slot);
 529
 530        ibmphp_lock_operations();
 531
 532        if (hotplug_slot) {
 533                pslot = hotplug_slot->private;
 534                if (pslot) {
 535                        rc = 0;
 536                        snprintf(value, 100, "Bus %x", pslot->bus);
 537                }
 538        } else
 539                rc = -ENODEV;
 540
 541        ibmphp_unlock_operations();
 542        debug("get_bus_name - Exit rc[%d] value[%x]\n", rc, *value);
 543        return rc;
 544}
 545*/
 546
 547/****************************************************************************
 548 * This routine will initialize the ops data structure used in the validate
 549 * function. It will also power off empty slots that are powered on since BIOS
 550 * leaves those on, albeit disconnected
 551 ****************************************************************************/
 552static int __init init_ops(void)
 553{
 554        struct slot *slot_cur;
 555        struct list_head *tmp;
 556        int retval;
 557        int rc;
 558
 559        list_for_each(tmp, &ibmphp_slot_head) {
 560                slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
 561
 562                if (!slot_cur)
 563                        return -ENODEV;
 564
 565                debug("BEFORE GETTING SLOT STATUS, slot # %x\n",
 566                                                        slot_cur->number);
 567                if (slot_cur->ctrl->revision == 0xFF) 
 568                        if (get_ctrl_revision(slot_cur,
 569                                                &slot_cur->ctrl->revision))
 570                                return -1;
 571
 572                if (slot_cur->bus_on->current_speed == 0xFF) 
 573                        if (get_cur_bus_info(&slot_cur)) 
 574                                return -1;
 575
 576                if (slot_cur->ctrl->options == 0xFF)
 577                        if (get_hpc_options(slot_cur, &slot_cur->ctrl->options))
 578                                return -1;
 579
 580                retval = slot_update(&slot_cur);
 581                if (retval)
 582                        return retval;
 583
 584                debug("status = %x\n", slot_cur->status);
 585                debug("ext_status = %x\n", slot_cur->ext_status);
 586                debug("SLOT_POWER = %x\n", SLOT_POWER(slot_cur->status));
 587                debug("SLOT_PRESENT = %x\n", SLOT_PRESENT(slot_cur->status));
 588                debug("SLOT_LATCH = %x\n", SLOT_LATCH(slot_cur->status));
 589
 590                if ((SLOT_PWRGD(slot_cur->status)) && 
 591                    !(SLOT_PRESENT(slot_cur->status)) && 
 592                    !(SLOT_LATCH(slot_cur->status))) {
 593                        debug("BEFORE POWER OFF COMMAND\n");
 594                                rc = power_off(slot_cur);
 595                                if (rc)
 596                                        return rc;
 597
 598        /*              retval = slot_update(&slot_cur);
 599         *              if (retval)
 600         *                      return retval;
 601         *              ibmphp_update_slot_info(slot_cur);
 602         */
 603                }
 604        }
 605        init_flag = 0;
 606        return 0;
 607}
 608
 609/* This operation will check whether the slot is within the bounds and
 610 * the operation is valid to perform on that slot
 611 * Parameters: slot, operation
 612 * Returns: 0 or error codes
 613 */
 614static int validate(struct slot *slot_cur, int opn)
 615{
 616        int number;
 617        int retval;
 618
 619        if (!slot_cur)
 620                return -ENODEV;
 621        number = slot_cur->number;
 622        if ((number > max_slots) || (number < 0))
 623                return -EBADSLT;
 624        debug("slot_number in validate is %d\n", slot_cur->number);
 625
 626        retval = slot_update(&slot_cur);
 627        if (retval)
 628                return retval;
 629
 630        switch (opn) {
 631                case ENABLE:
 632                        if (!(SLOT_PWRGD(slot_cur->status)) && 
 633                             (SLOT_PRESENT(slot_cur->status)) && 
 634                             !(SLOT_LATCH(slot_cur->status)))
 635                                return 0;
 636                        break;
 637                case DISABLE:
 638                        if ((SLOT_PWRGD(slot_cur->status)) && 
 639                            (SLOT_PRESENT(slot_cur->status)) &&
 640                            !(SLOT_LATCH(slot_cur->status)))
 641                                return 0;
 642                        break;
 643                default:
 644                        break;
 645        }
 646        err("validate failed....\n");
 647        return -EINVAL;
 648}
 649
 650/****************************************************************************
 651 * This routine is for updating the data structures in the hotplug core
 652 * Parameters: struct slot
 653 * Returns: 0 or error
 654 ****************************************************************************/
 655int ibmphp_update_slot_info(struct slot *slot_cur)
 656{
 657        struct hotplug_slot_info *info;
 658        int rc;
 659        u8 bus_speed;
 660        u8 mode;
 661
 662        info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
 663        if (!info) {
 664                err("out of system memory\n");
 665                return -ENOMEM;
 666        }
 667        
 668        info->power_status = SLOT_PWRGD(slot_cur->status);
 669        info->attention_status = SLOT_ATTN(slot_cur->status,
 670                                                slot_cur->ext_status);
 671        info->latch_status = SLOT_LATCH(slot_cur->status);
 672        if (!SLOT_PRESENT(slot_cur->status)) {
 673                info->adapter_status = 0;
 674/*              info->max_adapter_speed_status = MAX_ADAPTER_NONE; */
 675        } else {
 676                info->adapter_status = 1;
 677/*              get_max_adapter_speed_1(slot_cur->hotplug_slot,
 678                                        &info->max_adapter_speed_status, 0); */
 679        }
 680
 681        bus_speed = slot_cur->bus_on->current_speed;
 682        mode = slot_cur->bus_on->current_bus_mode;
 683
 684        switch (bus_speed) {
 685                case BUS_SPEED_33:
 686                        break;
 687                case BUS_SPEED_66:
 688                        if (mode == BUS_MODE_PCIX) 
 689                                bus_speed += 0x01;
 690                        else if (mode == BUS_MODE_PCI)
 691                                ;
 692                        else
 693                                bus_speed = PCI_SPEED_UNKNOWN;
 694                        break;
 695                case BUS_SPEED_100:
 696                case BUS_SPEED_133:
 697                        bus_speed += 0x01;
 698                        break;
 699                default:
 700                        bus_speed = PCI_SPEED_UNKNOWN;
 701        }
 702
 703        info->cur_bus_speed = bus_speed;
 704        info->max_bus_speed = slot_cur->hotplug_slot->info->max_bus_speed;
 705        // To do: bus_names 
 706        
 707        rc = pci_hp_change_slot_info(slot_cur->hotplug_slot, info);
 708        kfree(info);
 709        return rc;
 710}
 711
 712
 713/******************************************************************************
 714 * This function will return the pci_func, given bus and devfunc, or NULL.  It
 715 * is called from visit routines
 716 ******************************************************************************/
 717
 718static struct pci_func *ibm_slot_find(u8 busno, u8 device, u8 function)
 719{
 720        struct pci_func *func_cur;
 721        struct slot *slot_cur;
 722        struct list_head * tmp;
 723        list_for_each(tmp, &ibmphp_slot_head) {
 724                slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
 725                if (slot_cur->func) {
 726                        func_cur = slot_cur->func;
 727                        while (func_cur) {
 728                                if ((func_cur->busno == busno) &&
 729                                                (func_cur->device == device) &&
 730                                                (func_cur->function == function))
 731                                        return func_cur;
 732                                func_cur = func_cur->next;
 733                        }
 734                }
 735        }
 736        return NULL;
 737}
 738
 739/*************************************************************
 740 * This routine frees up memory used by struct slot, including
 741 * the pointers to pci_func, bus, hotplug_slot, controller,
 742 * and deregistering from the hotplug core
 743 *************************************************************/
 744static void free_slots(void)
 745{
 746        struct slot *slot_cur;
 747        struct list_head * tmp;
 748        struct list_head * next;
 749
 750        debug("%s -- enter\n", __func__);
 751
 752        list_for_each_safe(tmp, next, &ibmphp_slot_head) {
 753                slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
 754                pci_hp_deregister(slot_cur->hotplug_slot);
 755        }
 756        debug("%s -- exit\n", __func__);
 757}
 758
 759static void ibm_unconfigure_device(struct pci_func *func)
 760{
 761        struct pci_dev *temp;
 762        u8 j;
 763
 764        debug("inside %s\n", __func__);
 765        debug("func->device = %x, func->function = %x\n",
 766                                        func->device, func->function);
 767        debug("func->device << 3 | 0x0  = %x\n", func->device << 3 | 0x0);
 768
 769        for (j = 0; j < 0x08; j++) {
 770                temp = pci_get_bus_and_slot(func->busno, (func->device << 3) | j);
 771                if (temp) {
 772                        pci_remove_bus_device(temp);
 773                        pci_dev_put(temp);
 774                }
 775        }
 776        pci_dev_put(func->dev);
 777}
 778
 779/*
 780 * The following function is to fix kernel bug regarding 
 781 * getting bus entries, here we manually add those primary 
 782 * bus entries to kernel bus structure whenever apply
 783 */
 784static u8 bus_structure_fixup(u8 busno)
 785{
 786        struct pci_bus *bus;
 787        struct pci_dev *dev;
 788        u16 l;
 789
 790        if (pci_find_bus(0, busno) || !(ibmphp_find_same_bus_num(busno)))
 791                return 1;
 792
 793        bus = kmalloc(sizeof(*bus), GFP_KERNEL);
 794        if (!bus) {
 795                err("%s - out of memory\n", __func__);
 796                return 1;
 797        }
 798        dev = kmalloc(sizeof(*dev), GFP_KERNEL);
 799        if (!dev) {
 800                kfree(bus);
 801                err("%s - out of memory\n", __func__);
 802                return 1;
 803        }
 804
 805        bus->number = busno;
 806        bus->ops = ibmphp_pci_bus->ops;
 807        dev->bus = bus;
 808        for (dev->devfn = 0; dev->devfn < 256; dev->devfn += 8) {
 809                if (!pci_read_config_word(dev, PCI_VENDOR_ID, &l) &&
 810                                        (l != 0x0000) && (l != 0xffff)) {
 811                        debug("%s - Inside bus_struture_fixup()\n",
 812                                                        __func__);
 813                        pci_scan_bus(busno, ibmphp_pci_bus->ops, NULL);
 814                        break;
 815                }
 816        }
 817
 818        kfree(dev);
 819        kfree(bus);
 820
 821        return 0;
 822}
 823
 824static int ibm_configure_device(struct pci_func *func)
 825{
 826        unsigned char bus;
 827        struct pci_bus *child;
 828        int num;
 829        int flag = 0;   /* this is to make sure we don't double scan the bus,
 830                                        for bridged devices primarily */
 831
 832        if (!(bus_structure_fixup(func->busno)))
 833                flag = 1;
 834        if (func->dev == NULL)
 835                func->dev = pci_get_bus_and_slot(func->busno,
 836                                PCI_DEVFN(func->device, func->function));
 837
 838        if (func->dev == NULL) {
 839                struct pci_bus *bus = pci_find_bus(0, func->busno);
 840                if (!bus)
 841                        return 0;
 842
 843                num = pci_scan_slot(bus,
 844                                PCI_DEVFN(func->device, func->function));
 845                if (num)
 846                        pci_bus_add_devices(bus);
 847
 848                func->dev = pci_get_bus_and_slot(func->busno,
 849                                PCI_DEVFN(func->device, func->function));
 850                if (func->dev == NULL) {
 851                        err("ERROR... : pci_dev still NULL\n");
 852                        return 0;
 853                }
 854        }
 855        if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
 856                pci_read_config_byte(func->dev, PCI_SECONDARY_BUS, &bus);
 857                child = pci_add_new_bus(func->dev->bus, func->dev, bus);
 858                pci_do_scan_bus(child);
 859        }
 860
 861        return 0;
 862}
 863
 864/*******************************************************
 865 * Returns whether the bus is empty or not 
 866 *******************************************************/
 867static int is_bus_empty(struct slot * slot_cur)
 868{
 869        int rc;
 870        struct slot * tmp_slot;
 871        u8 i = slot_cur->bus_on->slot_min;
 872
 873        while (i <= slot_cur->bus_on->slot_max) {
 874                if (i == slot_cur->number) {
 875                        i++;
 876                        continue;
 877                }
 878                tmp_slot = ibmphp_get_slot_from_physical_num(i);
 879                if (!tmp_slot)
 880                        return 0;
 881                rc = slot_update(&tmp_slot);
 882                if (rc)
 883                        return 0;
 884                if (SLOT_PRESENT(tmp_slot->status) &&
 885                                        SLOT_PWRGD(tmp_slot->status))
 886                        return 0;
 887                i++;
 888        }
 889        return 1;
 890}
 891
 892/***********************************************************
 893 * If the HPC permits and the bus currently empty, tries to set the 
 894 * bus speed and mode at the maximum card and bus capability
 895 * Parameters: slot
 896 * Returns: bus is set (0) or error code
 897 ***********************************************************/
 898static int set_bus(struct slot * slot_cur)
 899{
 900        int rc;
 901        u8 speed;
 902        u8 cmd = 0x0;
 903        int retval;
 904        static struct pci_device_id ciobx[] = {
 905                { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, 0x0101) },
 906                { },
 907        };      
 908
 909        debug("%s - entry slot # %d\n", __func__, slot_cur->number);
 910        if (SET_BUS_STATUS(slot_cur->ctrl) && is_bus_empty(slot_cur)) {
 911                rc = slot_update(&slot_cur);
 912                if (rc)
 913                        return rc;
 914                speed = SLOT_SPEED(slot_cur->ext_status);
 915                debug("ext_status = %x, speed = %x\n", slot_cur->ext_status, speed);
 916                switch (speed) {
 917                case HPC_SLOT_SPEED_33:
 918                        cmd = HPC_BUS_33CONVMODE;
 919                        break;
 920                case HPC_SLOT_SPEED_66:
 921                        if (SLOT_PCIX(slot_cur->ext_status)) {
 922                                if ((slot_cur->supported_speed >= BUS_SPEED_66) &&
 923                                                (slot_cur->supported_bus_mode == BUS_MODE_PCIX))
 924                                        cmd = HPC_BUS_66PCIXMODE;
 925                                else if (!SLOT_BUS_MODE(slot_cur->ext_status))
 926                                        /* if max slot/bus capability is 66 pci
 927                                        and there's no bus mode mismatch, then
 928                                        the adapter supports 66 pci */ 
 929                                        cmd = HPC_BUS_66CONVMODE;
 930                                else
 931                                        cmd = HPC_BUS_33CONVMODE;
 932                        } else {
 933                                if (slot_cur->supported_speed >= BUS_SPEED_66)
 934                                        cmd = HPC_BUS_66CONVMODE;
 935                                else
 936                                        cmd = HPC_BUS_33CONVMODE;
 937                        }
 938                        break;
 939                case HPC_SLOT_SPEED_133:
 940                        switch (slot_cur->supported_speed) {
 941                        case BUS_SPEED_33:
 942                                cmd = HPC_BUS_33CONVMODE;
 943                                break;
 944                        case BUS_SPEED_66:
 945                                if (slot_cur->supported_bus_mode == BUS_MODE_PCIX)
 946                                        cmd = HPC_BUS_66PCIXMODE;
 947                                else
 948                                        cmd = HPC_BUS_66CONVMODE;
 949                                break;
 950                        case BUS_SPEED_100:
 951                                cmd = HPC_BUS_100PCIXMODE;
 952                                break;
 953                        case BUS_SPEED_133:
 954                                /* This is to take care of the bug in CIOBX chip */
 955                                if (pci_dev_present(ciobx))
 956                                        ibmphp_hpc_writeslot(slot_cur,
 957                                                        HPC_BUS_100PCIXMODE);
 958                                cmd = HPC_BUS_133PCIXMODE;
 959                                break;
 960                        default:
 961                                err("Wrong bus speed\n");
 962                                return -ENODEV;
 963                        }
 964                        break;
 965                default:
 966                        err("wrong slot speed\n");
 967                        return -ENODEV;
 968                }
 969                debug("setting bus speed for slot %d, cmd %x\n",
 970                                                slot_cur->number, cmd);
 971                retval = ibmphp_hpc_writeslot(slot_cur, cmd);
 972                if (retval) {
 973                        err("setting bus speed failed\n");
 974                        return retval;
 975                }
 976                if (CTLR_RESULT(slot_cur->ctrl->status)) {
 977                        err("command not completed successfully in set_bus\n");
 978                        return -EIO;
 979                }
 980        }
 981        /* This is for x440, once Brandon fixes the firmware, 
 982        will not need this delay */
 983        msleep(1000);
 984        debug("%s -Exit\n", __func__);
 985        return 0;
 986}
 987
 988/* This routine checks the bus limitations that the slot is on from the BIOS.
 989 * This is used in deciding whether or not to power up the slot.  
 990 * (electrical/spec limitations. For example, >1 133 MHz or >2 66 PCI cards on
 991 * same bus) 
 992 * Parameters: slot
 993 * Returns: 0 = no limitations, -EINVAL = exceeded limitations on the bus
 994 */
 995static int check_limitations(struct slot *slot_cur)
 996{
 997        u8 i;
 998        struct slot * tmp_slot;
 999        u8 count = 0;
1000        u8 limitation = 0;
1001
1002        for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) {
1003                tmp_slot = ibmphp_get_slot_from_physical_num(i);
1004                if (!tmp_slot)
1005                        return -ENODEV;
1006                if ((SLOT_PWRGD(tmp_slot->status)) &&
1007                                        !(SLOT_CONNECT(tmp_slot->status)))
1008                        count++;
1009        }
1010        get_cur_bus_info(&slot_cur);
1011        switch (slot_cur->bus_on->current_speed) {
1012        case BUS_SPEED_33:
1013                limitation = slot_cur->bus_on->slots_at_33_conv;
1014                break;
1015        case BUS_SPEED_66:
1016                if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX)
1017                        limitation = slot_cur->bus_on->slots_at_66_pcix;
1018                else
1019                        limitation = slot_cur->bus_on->slots_at_66_conv;
1020                break;
1021        case BUS_SPEED_100:
1022                limitation = slot_cur->bus_on->slots_at_100_pcix;
1023                break;
1024        case BUS_SPEED_133:
1025                limitation = slot_cur->bus_on->slots_at_133_pcix;
1026                break;
1027        }
1028
1029        if ((count + 1) > limitation)
1030                return -EINVAL;
1031        return 0;
1032}
1033
1034static inline void print_card_capability(struct slot *slot_cur)
1035{
1036        info("capability of the card is ");
1037        if ((slot_cur->ext_status & CARD_INFO) == PCIX133) 
1038                info("   133 MHz PCI-X\n");
1039        else if ((slot_cur->ext_status & CARD_INFO) == PCIX66)
1040                info("    66 MHz PCI-X\n");
1041        else if ((slot_cur->ext_status & CARD_INFO) == PCI66)
1042                info("    66 MHz PCI\n");
1043        else
1044                info("    33 MHz PCI\n");
1045
1046}
1047
1048/* This routine will power on the slot, configure the device(s) and find the
1049 * drivers for them.
1050 * Parameters: hotplug_slot
1051 * Returns: 0 or failure codes
1052 */
1053static int enable_slot(struct hotplug_slot *hs)
1054{
1055        int rc, i, rcpr;
1056        struct slot *slot_cur;
1057        u8 function;
1058        struct pci_func *tmp_func;
1059
1060        ibmphp_lock_operations();
1061
1062        debug("ENABLING SLOT........\n");
1063        slot_cur = hs->private;
1064
1065        if ((rc = validate(slot_cur, ENABLE))) {
1066                err("validate function failed\n");
1067                goto error_nopower;
1068        }
1069
1070        attn_LED_blink(slot_cur);
1071        
1072        rc = set_bus(slot_cur);
1073        if (rc) {
1074                err("was not able to set the bus\n");
1075                goto error_nopower;
1076        }
1077
1078        /*-----------------debugging------------------------------*/
1079        get_cur_bus_info(&slot_cur);
1080        debug("the current bus speed right after set_bus = %x\n",
1081                                        slot_cur->bus_on->current_speed);
1082        /*----------------------------------------------------------*/
1083
1084        rc = check_limitations(slot_cur);
1085        if (rc) {
1086                err("Adding this card exceeds the limitations of this bus.\n");
1087                err("(i.e., >1 133MHz cards running on same bus, or "
1088                     ">2 66 PCI cards running on same bus.\n");
1089                err("Try hot-adding into another bus\n");
1090                rc = -EINVAL;
1091                goto error_nopower;
1092        }
1093
1094        rc = power_on(slot_cur);
1095
1096        if (rc) {
1097                err("something wrong when powering up... please see below for details\n");
1098                /* need to turn off before on, otherwise, blinking overwrites */
1099                attn_off(slot_cur);
1100                attn_on(slot_cur);
1101                if (slot_update(&slot_cur)) {
1102                        attn_off(slot_cur);
1103                        attn_on(slot_cur);
1104                        rc = -ENODEV;
1105                        goto exit;
1106                }
1107                /* Check to see the error of why it failed */
1108                if ((SLOT_POWER(slot_cur->status)) &&
1109                                        !(SLOT_PWRGD(slot_cur->status)))
1110                        err("power fault occurred trying to power up\n");
1111                else if (SLOT_BUS_SPEED(slot_cur->status)) {
1112                        err("bus speed mismatch occurred.  please check "
1113                                "current bus speed and card capability\n");
1114                        print_card_capability(slot_cur);
1115                } else if (SLOT_BUS_MODE(slot_cur->ext_status)) {
1116                        err("bus mode mismatch occurred.  please check "
1117                                "current bus mode and card capability\n");
1118                        print_card_capability(slot_cur);
1119                }
1120                ibmphp_update_slot_info(slot_cur);
1121                goto exit;
1122        }
1123        debug("after power_on\n");
1124        /*-----------------------debugging---------------------------*/
1125        get_cur_bus_info(&slot_cur);
1126        debug("the current bus speed right after power_on = %x\n",
1127                                        slot_cur->bus_on->current_speed);
1128        /*----------------------------------------------------------*/
1129
1130        rc = slot_update(&slot_cur);
1131        if (rc)
1132                goto error_power;
1133        
1134        rc = -EINVAL;
1135        if (SLOT_POWER(slot_cur->status) && !(SLOT_PWRGD(slot_cur->status))) {
1136                err("power fault occurred trying to power up...\n");
1137                goto error_power;
1138        }
1139        if (SLOT_POWER(slot_cur->status) && (SLOT_BUS_SPEED(slot_cur->status))) {
1140                err("bus speed mismatch occurred.  please check current bus "
1141                                        "speed and card capability\n");
1142                print_card_capability(slot_cur);
1143                goto error_power;
1144        } 
1145        /* Don't think this case will happen after above checks...
1146         * but just in case, for paranoia sake */
1147        if (!(SLOT_POWER(slot_cur->status))) {
1148                err("power on failed...\n");
1149                goto error_power;
1150        }
1151
1152        slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
1153        if (!slot_cur->func) {
1154                /* We cannot do update_slot_info here, since no memory for
1155                 * kmalloc n.e.ways, and update_slot_info allocates some */
1156                err("out of system memory\n");
1157                rc = -ENOMEM;
1158                goto error_power;
1159        }
1160        slot_cur->func->busno = slot_cur->bus;
1161        slot_cur->func->device = slot_cur->device;
1162        for (i = 0; i < 4; i++)
1163                slot_cur->func->irq[i] = slot_cur->irq[i];
1164
1165        debug("b4 configure_card, slot_cur->bus = %x, slot_cur->device = %x\n",
1166                                        slot_cur->bus, slot_cur->device);
1167
1168        if (ibmphp_configure_card(slot_cur->func, slot_cur->number)) {
1169                err("configure_card was unsuccessful...\n");
1170                /* true because don't need to actually deallocate resources,
1171                 * just remove references */
1172                ibmphp_unconfigure_card(&slot_cur, 1);
1173                debug("after unconfigure_card\n");
1174                slot_cur->func = NULL;
1175                rc = -ENOMEM;
1176                goto error_power;
1177        }
1178
1179        function = 0x00;
1180        do {
1181                tmp_func = ibm_slot_find(slot_cur->bus, slot_cur->func->device,
1182                                                        function++);
1183                if (tmp_func && !(tmp_func->dev))
1184                        ibm_configure_device(tmp_func);
1185        } while (tmp_func);
1186
1187        attn_off(slot_cur);
1188        if (slot_update(&slot_cur)) {
1189                rc = -EFAULT;
1190                goto exit;
1191        }
1192        ibmphp_print_test();
1193        rc = ibmphp_update_slot_info(slot_cur);
1194exit:
1195        ibmphp_unlock_operations(); 
1196        return rc;
1197
1198error_nopower:
1199        attn_off(slot_cur);     /* need to turn off if was blinking b4 */
1200        attn_on(slot_cur);
1201error_cont:
1202        rcpr = slot_update(&slot_cur);
1203        if (rcpr) {
1204                rc = rcpr;
1205                goto exit;
1206        }
1207        ibmphp_update_slot_info(slot_cur);
1208        goto exit;
1209
1210error_power:
1211        attn_off(slot_cur);     /* need to turn off if was blinking b4 */
1212        attn_on(slot_cur);
1213        rcpr = power_off(slot_cur);
1214        if (rcpr) {
1215                rc = rcpr;
1216                goto exit;
1217        }
1218        goto error_cont;
1219}
1220
1221/**************************************************************
1222* HOT REMOVING ADAPTER CARD                                   *
1223* INPUT: POINTER TO THE HOTPLUG SLOT STRUCTURE                *
1224* OUTPUT: SUCCESS 0 ; FAILURE: UNCONFIGURE , VALIDATE         *
1225          DISABLE POWER ,                                    *
1226**************************************************************/
1227static int ibmphp_disable_slot(struct hotplug_slot *hotplug_slot)
1228{
1229        struct slot *slot = hotplug_slot->private;
1230        int rc;
1231        
1232        ibmphp_lock_operations();
1233        rc = ibmphp_do_disable_slot(slot);
1234        ibmphp_unlock_operations();
1235        return rc;
1236}
1237
1238int ibmphp_do_disable_slot(struct slot *slot_cur)
1239{
1240        int rc;
1241        u8 flag;
1242
1243        debug("DISABLING SLOT...\n"); 
1244                
1245        if ((slot_cur == NULL) || (slot_cur->ctrl == NULL)) {
1246                return -ENODEV;
1247        }
1248        
1249        flag = slot_cur->flag;
1250        slot_cur->flag = 1;
1251
1252        if (flag == 1) {
1253                rc = validate(slot_cur, DISABLE);
1254                        /* checking if powered off already & valid slot # */
1255                if (rc)
1256                        goto error;
1257        }
1258        attn_LED_blink(slot_cur);
1259
1260        if (slot_cur->func == NULL) {
1261                /* We need this for fncs's that were there on bootup */
1262                slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
1263                if (!slot_cur->func) {
1264                        err("out of system memory\n");
1265                        rc = -ENOMEM;
1266                        goto error;
1267                }
1268                slot_cur->func->busno = slot_cur->bus;
1269                slot_cur->func->device = slot_cur->device;
1270        }
1271
1272        ibm_unconfigure_device(slot_cur->func);
1273        
1274        /* If we got here from latch suddenly opening on operating card or 
1275        a power fault, there's no power to the card, so cannot
1276        read from it to determine what resources it occupied.  This operation
1277        is forbidden anyhow.  The best we can do is remove it from kernel
1278        lists at least */
1279
1280        if (!flag) {
1281                attn_off(slot_cur);
1282                return 0;
1283        }
1284
1285        rc = ibmphp_unconfigure_card(&slot_cur, 0);
1286        slot_cur->func = NULL;
1287        debug("in disable_slot. after unconfigure_card\n");
1288        if (rc) {
1289                err("could not unconfigure card.\n");
1290                goto error;
1291        }
1292
1293        rc = ibmphp_hpc_writeslot(slot_cur, HPC_SLOT_OFF);
1294        if (rc)
1295                goto error;
1296
1297        attn_off(slot_cur);
1298        rc = slot_update(&slot_cur);
1299        if (rc)
1300                goto exit;
1301
1302        rc = ibmphp_update_slot_info(slot_cur);
1303        ibmphp_print_test();
1304exit:
1305        return rc;
1306
1307error:
1308        /*  Need to turn off if was blinking b4 */
1309        attn_off(slot_cur);
1310        attn_on(slot_cur);
1311        if (slot_update(&slot_cur)) {
1312                rc = -EFAULT;
1313                goto exit;
1314        }
1315        if (flag)               
1316                ibmphp_update_slot_info(slot_cur);
1317        goto exit;
1318}
1319
1320struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
1321        .set_attention_status =         set_attention_status,
1322        .enable_slot =                  enable_slot,
1323        .disable_slot =                 ibmphp_disable_slot,
1324        .hardware_test =                NULL,
1325        .get_power_status =             get_power_status,
1326        .get_attention_status =         get_attention_status,
1327        .get_latch_status =             get_latch_status,
1328        .get_adapter_status =           get_adapter_present,
1329        .get_max_bus_speed =            get_max_bus_speed,
1330        .get_cur_bus_speed =            get_cur_bus_speed,
1331/*      .get_max_adapter_speed =        get_max_adapter_speed,
1332        .get_bus_name_status =          get_bus_name,
1333*/
1334};
1335
1336static void ibmphp_unload(void)
1337{
1338        free_slots();
1339        debug("after slots\n");
1340        ibmphp_free_resources();
1341        debug("after resources\n");
1342        ibmphp_free_bus_info_queue();
1343        debug("after bus info\n");
1344        ibmphp_free_ebda_hpc_queue();
1345        debug("after ebda hpc\n");
1346        ibmphp_free_ebda_pci_rsrc_queue();
1347        debug("after ebda pci rsrc\n");
1348        kfree(ibmphp_pci_bus);
1349}
1350
1351static int __init ibmphp_init(void)
1352{
1353        struct pci_bus *bus;
1354        int i = 0;
1355        int rc = 0;
1356
1357        init_flag = 1;
1358
1359        info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
1360
1361        ibmphp_pci_bus = kmalloc(sizeof(*ibmphp_pci_bus), GFP_KERNEL);
1362        if (!ibmphp_pci_bus) {
1363                err("out of memory\n");
1364                rc = -ENOMEM;
1365                goto exit;
1366        }
1367
1368        bus = pci_find_bus(0, 0);
1369        if (!bus) {
1370                err("Can't find the root pci bus, can not continue\n");
1371                rc = -ENODEV;
1372                goto error;
1373        }
1374        memcpy(ibmphp_pci_bus, bus, sizeof(*ibmphp_pci_bus));
1375
1376        ibmphp_debug = debug;
1377
1378        ibmphp_hpc_initvars();
1379
1380        for (i = 0; i < 16; i++)
1381                irqs[i] = 0;
1382
1383        if ((rc = ibmphp_access_ebda()))
1384                goto error;
1385        debug("after ibmphp_access_ebda()\n");
1386
1387        if ((rc = ibmphp_rsrc_init()))
1388                goto error;
1389        debug("AFTER Resource & EBDA INITIALIZATIONS\n");
1390
1391        max_slots = get_max_slots();
1392        
1393        if ((rc = ibmphp_register_pci()))
1394                goto error;
1395
1396        if (init_ops()) {
1397                rc = -ENODEV;
1398                goto error;
1399        }
1400
1401        ibmphp_print_test();
1402        if ((rc = ibmphp_hpc_start_poll_thread())) {
1403                goto error;
1404        }
1405
1406exit:
1407        return rc;
1408
1409error:
1410        ibmphp_unload();
1411        goto exit;
1412}
1413
1414static void __exit ibmphp_exit(void)
1415{
1416        ibmphp_hpc_stop_poll_thread();
1417        debug("after polling\n");
1418        ibmphp_unload();
1419        debug("done\n");
1420}
1421
1422module_init(ibmphp_init);
1423module_exit(ibmphp_exit);
1424