Linux Audio

Check our new training course

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