linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [Patch] 2/4 PCI Hot-plug driver patch for 2.5.74 kernel
@ 2003-07-14 14:30 Dely Sy
  0 siblings, 0 replies; only message in thread
From: Dely Sy @ 2003-07-14 14:30 UTC (permalink / raw)
  To: linux-kernel

diff -Nru a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c
--- a/drivers/pci/hotplug/cpqphp_ctrl.c	2003-07-02 13:45:17.000000000 -0700
+++ b/drivers/pci/hotplug/cpqphp_ctrl.c	2003-07-07 09:32:21.000000000 -0700
@@ -38,9 +38,12 @@
 #include <linux/smp_lock.h>
 #include <linux/pci.h>
 #include "cpqphp.h"
+#include "phprm.h"
 
-static u32 configure_new_device(struct controller* ctrl, struct pci_func *func,u8 behind_bridge, struct resource_lists *resources);
-static int configure_new_function(struct controller* ctrl, struct pci_func *func,u8 behind_bridge, struct resource_lists *resources);
+static u32 configure_new_device(struct controller *ctrl, struct pci_func *func,
+	u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev);
+static int configure_new_function( struct controller *ctrl, struct pci_func *func,
+	u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev);
 static void interrupt_event_handler(struct controller *ctrl);
 
 static struct semaphore event_semaphore;	/* mutex for process loop (up if something to process) */
@@ -76,54 +79,59 @@
 }
 
 
-//FIXME: The following line needs to be somewhere else...
-#define WRONG_BUS_FREQUENCY 0x07
-static u8 handle_switch_change(u8 change, struct controller * ctrl)
+u8 handle_switch_change(unsigned int change, void *inst_id)
 {
+	struct controller *ctrl = (struct controller *) inst_id;
+	struct slot *p_slot;
 	int hp_slot;
 	u8 rc = 0;
-	u16 temp_word;
+	u8 getstatus;
 	struct pci_func *func;
 	struct event_info *taskInfo;
 
 	if (!change)
 		return 0;
 
-	// Switch Change
-	dbg("cpqsbd:  Switch interrupt received.\n");
+	/* Switch Change */
+	dbg("cpqphp:  Switch interrupt received.\n");
 
-	for (hp_slot = 0; hp_slot < 6; hp_slot++) {
+	for (hp_slot = 0; hp_slot < ctrl->num_ctlr_slots; hp_slot++) {
 		if (change & (0x1L << hp_slot)) {
-			//*********************************
-			// this one changed.
-			//*********************************
+			/*********************************
+			 *  this one changed.
+			 *********************************/
 			func = cpqhp_slot_find(ctrl->bus, (hp_slot + ctrl->slot_device_offset), 0);
 
-			//this is the structure that tells the worker thread
-			//what to do
+			/*  
+			 * this is the structure that tells the worker thread
+			 * what to do
+			 */
 			taskInfo = &(ctrl->event_queue[ctrl->next_event]);
 			ctrl->next_event = (ctrl->next_event + 1) % 10;
 			taskInfo->hp_slot = hp_slot;
 
 			rc++;
+			p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->first_device_num);
+			if (!p_slot)
+				return 0;
 
-			temp_word = ctrl->ctrl_int_comp >> 16;
-			func->presence_save = (temp_word >> hp_slot) & 0x01;
-			func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
-
-			if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
-				//*********************************
-				// Switch opened
-				//*********************************
+			p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
 
+			p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
+
+			if (!getstatus) {
+				/*********************************
+				 *  Switch opened
+				 *********************************/
+				info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot);
 				func->switch_save = 0;
 
 				taskInfo->event_type = INT_SWITCH_OPEN;
 			} else {
-				//*********************************
-				// Switch closed
-				//*********************************
-
+				/*********************************
+				 *  Switch closed
+				 *********************************/
+				info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot);
 				func->switch_save = 0x10;
 
 				taskInfo->event_type = INT_SWITCH_CLOSE;
@@ -131,54 +139,37 @@
 		}
 	}
 
-	return rc;
-}
-
-
-/*
- * cpqhp_find_slot
- */
-struct slot *cpqhp_find_slot (struct controller * ctrl, u8 device)
-{
-	struct slot *slot;
-
-	if (!ctrl)
-		return NULL;
-
-	slot = ctrl->slot;
-
-	while (slot && (slot->device != device)) {
-		slot = slot->next;
-	}
+	if (rc)
+		up(&event_semaphore);	/* signal event thread that new event is posted */
 
-	return slot;
+	return rc;
 }
 
-
-static u8 handle_presence_change(u16 change, struct controller * ctrl)
+u8 handle_presence_change(unsigned int change, void *inst_id)
 {
+	struct controller *ctrl = (struct controller *) inst_id;
+	struct slot *p_slot;
 	int hp_slot;
 	u8 rc = 0;
 	u8 temp_byte;
-	u16 temp_word;
 	struct pci_func *func;
 	struct event_info *taskInfo;
-	struct slot *p_slot;
+	int push_button = !(ctrl->ctlrcap & 0x0002);
 
 	if (!change)
 		return 0;
 
-	//*********************************
-	// Presence Change
-	//*********************************
-	dbg("cpqsbd:  Presence/Notify input change.\n");
+	/*********************************
+	 *  Presence Change
+	**********************************/
+	dbg("cpqphp:  Presence/Notify input change.\n");
 	dbg("         Changed bits are 0x%4.4x\n", change );
 
-	for (hp_slot = 0; hp_slot < 6; hp_slot++) {
+	for (hp_slot = 0; hp_slot < ctrl->num_ctlr_slots; hp_slot++) {
 		if (change & (0x0101 << hp_slot)) {
-			//*********************************
-			// this one changed.
-			//*********************************
+			/*********************************
+			 *  this one changed.
+			 *********************************/
 			func = cpqhp_slot_find(ctrl->bus, (hp_slot + ctrl->slot_device_offset), 0);
 
 			taskInfo = &(ctrl->event_queue[ctrl->next_event]);
@@ -186,72 +177,74 @@
 			taskInfo->hp_slot = hp_slot;
 
 			rc++;
-
-			p_slot = cpqhp_find_slot(ctrl, hp_slot + (readb(ctrl->hpc_reg + SLOT_MASK) >> 4));
+			p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->first_device_num);
+			
 			if (!p_slot)
 				return 0;
 
-			// If the switch closed, must be a button
-			// If not in button mode, nevermind
-			if (func->switch_save && (ctrl->push_button == 1)) {
-				temp_word = ctrl->ctrl_int_comp >> 16;
-				temp_byte = (temp_word >> hp_slot) & 0x01;
-				temp_byte |= (temp_word >> (hp_slot + 7)) & 0x02;
+			/*  
+			 *  If the switch closed, must be a button
+			 *  If not in button mode, nevermind
+			 */
+			if (func->switch_save && push_button) {
+				/* phphpc_get_adapter_status (p_slot, &temp_byte); */
+				p_slot->hpc_ops->get_adapter_status(p_slot, &temp_byte);
 
 				if (temp_byte != func->presence_save) {
-					//*********************************
-					// button Pressed (doesn't do anything)
-					//*********************************
-					dbg("hp_slot %d button pressed\n", hp_slot);
+					/*********************************
+					 *  button Pressed (doesn't do anything)
+					 *********************************/
+					info("Button pressed on Slot(%d)\n", ctrl->first_slot + hp_slot);
 					taskInfo->event_type = INT_BUTTON_PRESS;
 				} else {
-					//*********************************
-					// button Released - TAKE ACTION!!!!
-					//*********************************
-					dbg("hp_slot %d button released\n", hp_slot);
+					/*********************************
+					 *  button Released - TAKE ACTION!!!!
+					 *********************************/
+					info("Button released on Slot(%d)\n", ctrl->first_slot + hp_slot);
 					taskInfo->event_type = INT_BUTTON_RELEASE;
 
-					// Cancel if we are still blinking
+					/* Cancel if we are still blinking */
 					if ((p_slot->state == BLINKINGON_STATE)
 					    || (p_slot->state == BLINKINGOFF_STATE)) {
 						taskInfo->event_type = INT_BUTTON_CANCEL;
-						dbg("hp_slot %d button cancel\n", hp_slot);
+						info("Button cancel on Slot(%d)\n", ctrl->first_slot + hp_slot);
 					} else if ((p_slot->state == POWERON_STATE)
 						   || (p_slot->state == POWEROFF_STATE)) {
-						//info(msg_button_ignore, p_slot->number);
 						taskInfo->event_type = INT_BUTTON_IGNORE;
-						dbg("hp_slot %d button ignore\n", hp_slot);
+						info("Button ignore on Slot(%d)\n", ctrl->first_slot + hp_slot);
 					}
 				}
 			} else {
-				// Switch is open, assume a presence change
-				// Save the presence state
-				temp_word = ctrl->ctrl_int_comp >> 16;
-				func->presence_save = (temp_word >> hp_slot) & 0x01;
-				func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
-
-				if ((!(ctrl->ctrl_int_comp & (0x010000 << hp_slot))) ||
-				    (!(ctrl->ctrl_int_comp & (0x01000000 << hp_slot)))) {
-					//*********************************
-					// Present
-					//*********************************
+				/*  
+				 *  Switch is open, assume a presence change
+				 *  Save the presence state
+				 */
+				p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
+				if (func->presence_save) {
+					/*********************************
+					 *  Present
+					 *********************************/
 					taskInfo->event_type = INT_PRESENCE_ON;
 				} else {
-					//*********************************
-					// Not Present
-					//*********************************
+					/*********************************
+					 *   Not Present
+					 *********************************/
 					taskInfo->event_type = INT_PRESENCE_OFF;
 				}
 			}
 		}
 	}
 
+	if (rc)
+		up(&event_semaphore);	/* signal event thread that new event is posted */
+
 	return rc;
 }
 
-
-static u8 handle_power_fault(u8 change, struct controller * ctrl)
+u8 handle_power_fault(unsigned int change, void *inst_id)
 {
+	struct controller *ctrl = (struct controller *) inst_id;
+	struct slot *p_slot;
 	int hp_slot;
 	u8 rc = 0;
 	struct pci_func *func;
@@ -260,17 +253,16 @@
 	if (!change)
 		return 0;
 
-	//*********************************
-	// power fault
-	//*********************************
+	/*********************************
+	 *   power fault
+	 *********************************/
+	dbg("cpqphp:  Power fault interrupt received.\n");
 
-	info("power fault interrupt\n");
-
-	for (hp_slot = 0; hp_slot < 6; hp_slot++) {
+	for (hp_slot = 0; hp_slot < ctrl->num_ctlr_slots; hp_slot++) {
 		if (change & (0x01 << hp_slot)) {
-			//*********************************
-			// this one changed.
-			//*********************************
+			/*********************************
+			 *  this one changed.
+			 *********************************/
 			func = cpqhp_slot_find(ctrl->bus, (hp_slot + ctrl->slot_device_offset), 0);
 
 			taskInfo = &(ctrl->event_queue[ctrl->next_event]);
@@ -278,37 +270,51 @@
 			taskInfo->hp_slot = hp_slot;
 
 			rc++;
+			p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->first_device_num);
+			if (!p_slot)
+				return 0;
 
-			if (ctrl->ctrl_int_comp & (0x00000100 << hp_slot)) {
-				//*********************************
-				// power fault Cleared
-				//*********************************
+			if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) {
+				/*********************************
+				 *   power fault Cleared
+				 *********************************/
+				info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot);
 				func->status = 0x00;
-
 				taskInfo->event_type = INT_POWER_FAULT_CLEAR;
 			} else {
-				//*********************************
-				// power fault
-				//*********************************
+				/*********************************
+				 *  power fault
+				 *********************************/
+				info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot);
 				taskInfo->event_type = INT_POWER_FAULT;
 
 				if (ctrl->rev < 4) {
-					amber_LED_on (ctrl, hp_slot);
-					green_LED_off (ctrl, hp_slot);
-					set_SOGO (ctrl);
-
-					// this is a fatal condition, we want to crash the
-					// machine to protect from data corruption
-					// simulated_NMI shouldn't ever return
-					//FIXME
-					//simulated_NMI(hp_slot, ctrl);
-
-					//The following code causes a software crash just in
-					//case simulated_NMI did return
-					//FIXME
-					//panic(msg_power_fault);
+					/* Wait for exclusive access to hardware */
+					down(&ctrl->crit_sect);
+
+					p_slot->hpc_ops->green_led_off(p_slot);
+					p_slot->hpc_ops->set_attention_status(p_slot, 1);
+					p_slot->hpc_ops->update_hpc(p_slot);
+
+					/* Done with exclusive hardware access */
+					up(&ctrl->crit_sect);
+
+					/* 
+					 *  this is a fatal condition, we want to crash the
+					 *  machine to protect from data corruption
+					 *  simulated_NMI shouldn't ever return
+					 *  FIXME
+					 *  simulated_NMI(hp_slot, ctrl);
+					 */
+
+					/*  
+					 *  The following code causes a software crash just in
+					 *  case simulated_NMI did return
+					 *  FIXME
+					 *  panic(msg_power_fault);
+					 */
 				} else {
-					// set power fault status for this board
+					/* set power fault status for this board */
 					func->status = 0xFF;
 					info("power fault bit %x set\n", hp_slot);
 				}
@@ -316,6 +322,9 @@
 		}
 	}
 
+	if (rc)
+		up(&event_semaphore);	/* signal event thread that new event is posted */
+
 	return rc;
 }
 
@@ -342,7 +351,7 @@
 	while (out_of_order) {
 		out_of_order = 0;
 
-		// Special case for swapping list head
+		/* Special case for swapping list head */
 		if (((*head)->next) &&
 		    ((*head)->length > (*head)->next->length)) {
 			out_of_order++;
@@ -365,7 +374,7 @@
 			} else
 				current_res = current_res->next;
 		}
-	}  // End of out_of_order loop
+	}  /*  End of out_of_order loop */
 
 	return(0);
 }
@@ -393,7 +402,7 @@
 	while (out_of_order) {
 		out_of_order = 0;
 
-		// Special case for swapping list head
+		/* Special case for swapping list head */
 		if (((*head)->next) &&
 		    ((*head)->length < (*head)->next->length)) {
 			out_of_order++;
@@ -416,7 +425,7 @@
 			} else
 				current_res = current_res->next;
 		}
-	}  // End of out_of_order loop
+	}  /* End of out_of_order loop */
 
 	return(0);
 }
@@ -452,14 +461,18 @@
 		return(NULL);
 
 
-	// If we got here, there the bridge requires some of the resource, but
-	// we may be able to split some off of the front
+	/* 
+	 *  If we got here, there the bridge requires some of the resource, but
+	 *  we may be able to split some off of the front
+	 */
 
 	node = *head;
 
 	if (node->length & (alignment -1)) {
-		// this one isn't an aligned length, so we'll make a new entry
-		// and split it up.
+		/*  
+		 *  this one isn't an aligned length, so we'll make a new entry
+		 *  and split it up.
+		 */
 		split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
 
 		if (!split_node)
@@ -473,7 +486,7 @@
 		node->length -= temp_dword;
 		node->base += split_node->length;
 
-		// Put it in the list
+		/* Put it in the list */
 		*head = split_node;
 		split_node->next = node;
 	}
@@ -482,7 +495,7 @@
 		return(NULL);
 	}
 
-	// Now unlink it
+	/*  Now unlink it */
 	if (*head == node) {
 		*head = node->next;
 		node->next = NULL;
@@ -534,7 +547,7 @@
 	}
 
 	if (node->base & (alignment - 1)) {
-		// Short circuit if adjusted size is too small
+		/* Short circuit if adjusted size is too small */
 		temp_dword = (node->base | (alignment-1)) + 1;
 		if ((node->length - (temp_dword - node->base)) < alignment) {
 			kfree(node);
@@ -546,7 +559,7 @@
 	}
 
 	if (node->length & (alignment - 1)) {
-		// There's stuff in use after this node
+		/* There's stuff in use after this node */
 		kfree(node);
 		return(NULL);
 	}
@@ -569,7 +582,7 @@
 {
 	struct pci_resource *prevnode;
 	struct pci_resource *node;
-	struct pci_resource *split_node;
+	struct pci_resource *split_node = NULL;
 	u32 temp_dword;
 
 	if (!(*head))
@@ -586,11 +599,13 @@
 			continue;
 
 		if (node->base & (size - 1)) {
-			// this one isn't base aligned properly
-			// so we'll make a new entry and split it up
+			/*  
+			 *  this one isn't base aligned properly
+			 *  so we'll make a new entry and split it up
+			 */
 			temp_dword = (node->base | (size-1)) + 1;
 
-			// Short circuit if adjusted size is too small
+			/* Short circuit if adjusted size is too small */
 			if ((node->length - (temp_dword - node->base)) < size)
 				continue;
 
@@ -604,15 +619,17 @@
 			node->base = temp_dword;
 			node->length -= split_node->length;
 
-			// Put it in the list
+			/*  Put it in the list */
 			split_node->next = node->next;
 			node->next = split_node;
-		} // End of non-aligned base
+		} /* End of non-aligned base */
 
-		// Don't need to check if too small since we already did
+		/* Don't need to check if too small since we already did */
 		if (node->length > size) {
-			// this one is longer than we need
-			// so we'll make a new entry and split it up
+			/*
+			 *   this one is longer than we need
+			 *   so we'll make a new entry and split it up
+			 */
 			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
 
 			if (!split_node)
@@ -622,17 +639,19 @@
 			split_node->length = node->length - size;
 			node->length = size;
 
-			// Put it in the list
+			/* Put it in the list */
 			split_node->next = node->next;
 			node->next = split_node;
-		}  // End of too big on top end
+		}  /*  End of too big on top end */
 
-		// For IO make sure it's not in the ISA aliasing space
+		/* For IO make sure it's not in the ISA aliasing space */
 		if (node->base & 0x300L)
 			continue;
 
-		// If we got here, then it is the right size
-		// Now take it out of the list
+		/* 
+		 *  If we got here, then it is the right size
+		 *  Now take it out of the list
+		 */
 		if (*head == node) {
 			*head = node->next;
 		} else {
@@ -643,7 +662,7 @@
 			prevnode->next = node->next;
 		}
 		node->next = NULL;
-		// Stop looping
+		/* Stop looping */
 		break;
 	}
 
@@ -657,6 +676,8 @@
  * Gets the largest node that is at least "size" big from the
  * list pointed to by head.  It aligns the node on top and bottom
  * to "size" alignment before returning it.
+ * J.I. modified to put max size limits of; 64M->32M->16M->8M->4M->1M
+ *  This is needed to avoid allocating entire ACPI _CRS res to one child bridge/slot.
  */
 static struct pci_resource *get_max_resource (struct pci_resource **head, u32 size)
 {
@@ -664,6 +685,8 @@
 	struct pci_resource *temp;
 	struct pci_resource *split_node;
 	u32 temp_dword;
+	u32 max_size[] = { 0x4000000, 0x2000000, 0x1000000, 0x0800000, 0x0400000, 0x0200000, 0x0100000, 0x00 };
+	int i;
 
 	if (!(*head))
 		return(NULL);
@@ -676,17 +699,21 @@
 
 	for (max = *head;max; max = max->next) {
 
-		// If not big enough we could probably just bail, 
-		// instead we'll continue to the next.
+		/*  
+		 *  If not big enough we could probably just bail, 
+		 *  instead we'll continue to the next.
+		 */
 		if (max->length < size)
 			continue;
 
 		if (max->base & (size - 1)) {
-			// this one isn't base aligned properly
-			// so we'll make a new entry and split it up
+			/*  
+			 *  this one isn't base aligned properly
+			 *  so we'll make a new entry and split it up
+			 */
 			temp_dword = (max->base | (size-1)) + 1;
 
-			// Short circuit if adjusted size is too small
+			/* Short circuit if adjusted size is too small */
 			if ((max->length - (temp_dword - max->base)) < size)
 				continue;
 
@@ -700,14 +727,16 @@
 			max->base = temp_dword;
 			max->length -= split_node->length;
 
-			// Put it next in the list
+			/* Put it next in the list */
 			split_node->next = max->next;
 			max->next = split_node;
 		}
 
 		if ((max->base + max->length) & (size - 1)) {
-			// this one isn't end aligned properly at the top
-			// so we'll make a new entry and split it up
+			/* 
+			 *  this one isn't end aligned properly at the top
+			 *  so we'll make a new entry and split it up
+			 */
 			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
 
 			if (!split_node)
@@ -718,16 +747,31 @@
 					     - split_node->base;
 			max->length -= split_node->length;
 
-			// Put it in the list
+			/* Put it in the list */
 			split_node->next = max->next;
 			max->next = split_node;
 		}
 
-		// Make sure it didn't shrink too much when we aligned it
+		/* Make sure it didn't shrink too much when we aligned it */
 		if (max->length < size)
 			continue;
 
-		// Now take it out of the list
+		for ( i = 0; max_size[i] > size; i++) {
+			if (max->length > max_size[i]) {
+				split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+				if (!split_node)
+					break;
+				split_node->base = max->base + max_size[i];
+				split_node->length = max->length - max_size[i];
+				max->length = max_size[i];
+				/* Put it next in the list */
+				split_node->next = max->next;
+				max->next = split_node;
+				break;
+			}
+		}
+
+		/* Now take it out of the list */
 		temp = (struct pci_resource*) *head;
 		if (temp == max) {
 			*head = max->next;
@@ -743,7 +787,7 @@
 		return(max);
 	}
 
-	// If we get here, we couldn't find one
+	/* If we get here, we couldn't find one */
 	return(NULL);
 }
 
@@ -781,11 +825,13 @@
 
 		if (node->base & (size - 1)) {
 			dbg("%s: not aligned\n", __FUNCTION__);
-			// this one isn't base aligned properly
-			// so we'll make a new entry and split it up
+			/*  
+			 *   this one isn't base aligned properly
+			 *   so we'll make a new entry and split it up
+			 */
 			temp_dword = (node->base | (size-1)) + 1;
 
-			// Short circuit if adjusted size is too small
+			/* Short circuit if adjusted size is too small */
 			if ((node->length - (temp_dword - node->base)) < size)
 				continue;
 
@@ -799,16 +845,18 @@
 			node->base = temp_dword;
 			node->length -= split_node->length;
 
-			// Put it in the list
+			/* Put it in the list */
 			split_node->next = node->next;
 			node->next = split_node;
-		} // End of non-aligned base
+		} /* End of non-aligned base */
 
-		// Don't need to check if too small since we already did
+		/* Don't need to check if too small since we already did */
 		if (node->length > size) {
 			dbg("%s: too big\n", __FUNCTION__);
-			// this one is longer than we need
-			// so we'll make a new entry and split it up
+			/*  
+			 *  this one is longer than we need
+			 *  so we'll make a new entry and split it up
+			 */
 			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
 
 			if (!split_node)
@@ -818,14 +866,16 @@
 			split_node->length = node->length - size;
 			node->length = size;
 
-			// Put it in the list
+			/* Put it in the list */
 			split_node->next = node->next;
 			node->next = split_node;
-		}  // End of too big on top end
+		}  /* End of too big on top end */
 
 		dbg("%s: got one!!!\n", __FUNCTION__);
-		// If we got here, then it is the right size
-		// Now take it out of the list
+		/* 
+		 *  If we got here, then it is the right size
+		 *  Now take it out of the list
+		 */
 		if (*head == node) {
 			*head = node->next;
 		} else {
@@ -836,7 +886,7 @@
 			prevnode->next = node->next;
 		}
 		node->next = NULL;
-		// Stop looping
+		/* Stop looping */
 		break;
 	}
 	return(node);
@@ -873,7 +923,7 @@
 	while (out_of_order) {
 		out_of_order = 0;
 
-		// Special case for swapping list head
+		/* Special case for swapping list head */
 		if (((*head)->next) &&
 		    ((*head)->base > (*head)->next->base)) {
 			node1 = *head;
@@ -896,13 +946,13 @@
 			} else
 				node1 = node1->next;
 		}
-	}  // End of out_of_order loop
+	}  /* End of out_of_order loop */
 
 	node1 = *head;
 
 	while (node1 && node1->next) {
 		if ((node1->base + node1->length) == node1->next->base) {
-			// Combine
+			/* Combine */
 			dbg("8..\n");
 			node1->length += node1->next->length;
 			node2 = node1->next;
@@ -916,79 +966,6 @@
 }
 
 
-irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data, struct pt_regs *regs)
-{
-	struct controller *ctrl = data;
-	u8 schedule_flag = 0;
-	u8 reset;
-	u16 misc;
-	u32 Diff;
-	u32 temp_dword;
-
-	
-	misc = readw(ctrl->hpc_reg + MISC);
-	//*********************************
-	// Check to see if it was our interrupt
-	//*********************************
-	if (!(misc & 0x000C)) {
-		return IRQ_NONE;
-	}
-
-	if (misc & 0x0004) {
-		//*********************************
-		// Serial Output interrupt Pending
-		//*********************************
-
-		// Clear the interrupt
-		misc |= 0x0004;
-		writew(misc, ctrl->hpc_reg + MISC);
-
-		// Read to clear posted writes
-		misc = readw(ctrl->hpc_reg + MISC);
-
-		dbg ("%s - waking up\n", __FUNCTION__);
-		wake_up_interruptible(&ctrl->queue);
-	}
-
-	if (misc & 0x0008) {
-		// General-interrupt-input interrupt Pending
-		Diff = readl(ctrl->hpc_reg + INT_INPUT_CLEAR) ^ ctrl->ctrl_int_comp;
-
-		ctrl->ctrl_int_comp = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
-
-		// Clear the interrupt
-		writel(Diff, ctrl->hpc_reg + INT_INPUT_CLEAR);
-
-		// Read it back to clear any posted writes
-		temp_dword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
-
-		if (!Diff) {
-			// Clear all interrupts
-			writel(0xFFFFFFFF, ctrl->hpc_reg + INT_INPUT_CLEAR);
-		}
-
-		schedule_flag += handle_switch_change((u8)(Diff & 0xFFL), ctrl);
-		schedule_flag += handle_presence_change((u16)((Diff & 0xFFFF0000L) >> 16), ctrl);
-		schedule_flag += handle_power_fault((u8)((Diff & 0xFF00L) >> 8), ctrl);
-	}
-
-	reset = readb(ctrl->hpc_reg + RESET_FREQ_MODE);
-	if (reset & 0x40) {
-		/* Bus reset has completed */
-		reset &= 0xCF;
-		writeb(reset, ctrl->hpc_reg + RESET_FREQ_MODE);
-		reset = readb(ctrl->hpc_reg + RESET_FREQ_MODE);
-		wake_up_interruptible(&ctrl->queue);
-	}
-
-	if (schedule_flag) {
-		up(&event_semaphore);
-		dbg("Signal event_semaphore\n");
-	}
-	return IRQ_HANDLED;
-}
-
-
 /**
  * cpqhp_slot_create - Creates a node and adds it to the proper bus.
  * @busnumber - bus where new node is to be located
@@ -1003,8 +980,10 @@
 	new_slot = (struct pci_func *) kmalloc(sizeof(struct pci_func), GFP_KERNEL);
 
 	if (new_slot == NULL) {
-		// I'm not dead yet!
-		// You will be.
+		/*  
+		 *  I'm not dead yet!
+		 *  You will be.
+		 */
 		return(new_slot);
 	}
 
@@ -1151,11 +1130,13 @@
 }
 
 
-// DJZ: I don't think is_bridge will work as is.
-//FIXME
+/* 
+ *  DJZ: I don't think is_bridge will work as is.
+ *  FIXME
+ */
 static int is_bridge(struct pci_func * func)
 {
-	// Check the header type
+	/* Check the header type */
 	if (((func->config_space[0x03] >> 16) & 0xFF) == 0x01)
 		return 1;
 	else
@@ -1169,214 +1150,6 @@
 
 
 /**
- * board_replaced - Called after a board has been replaced in the system.
- *
- * This is only used if we don't have resources for hot add
- * Turns power on for the board
- * Checks to see if board is the same
- * If board is same, reconfigures it
- * If board isn't same, turns it back off.
- *
- */
-static u32 board_replaced(struct pci_func * func, struct controller * ctrl)
-{
-	u8 hp_slot;
-	u8 temp_byte;
-	u8 adapter_speed;
-	u32 index;
-	u32 rc = 0;
-	u32 src = 8;
-
-	hp_slot = func->device - ctrl->slot_device_offset;
-
-	if (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot)) {
-		//*********************************
-		// The switch is open.
-		//*********************************
-		rc = INTERLOCK_OPEN;
-	} else if (is_slot_enabled (ctrl, hp_slot)) {
-		//*********************************
-		// The board is already on
-		//*********************************
-		rc = CARD_FUNCTIONING;
-	} else {
-		// Wait for exclusive access to hardware
-		down(&ctrl->crit_sect);
-
-		// turn on board without attaching to the bus
-		enable_slot_power (ctrl, hp_slot);
-
-		set_SOGO(ctrl);
-
-		// Wait for SOBS to be unset
-		wait_for_ctrl_irq (ctrl);
-
-		// Change bits in slot power register to force another shift out
-		// NOTE: this is to work around the timer bug
-		temp_byte = readb(ctrl->hpc_reg + SLOT_POWER);
-		writeb(0x00, ctrl->hpc_reg + SLOT_POWER);
-		writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER);
-
-		set_SOGO(ctrl);
-
-		// Wait for SOBS to be unset
-		wait_for_ctrl_irq (ctrl);
-		
-		adapter_speed = get_adapter_speed(ctrl, hp_slot);
-		if (ctrl->speed != adapter_speed)
-			if (set_controller_speed(ctrl, adapter_speed, hp_slot))
-				rc = WRONG_BUS_FREQUENCY;
-
-		// turn off board without attaching to the bus
-		disable_slot_power (ctrl, hp_slot);
-
-		set_SOGO(ctrl);
-
-		// Wait for SOBS to be unset
-		wait_for_ctrl_irq (ctrl);
-
-		// Done with exclusive hardware access
-		up(&ctrl->crit_sect);
-
-		if (rc)
-			return(rc);
-
-		// Wait for exclusive access to hardware
-		down(&ctrl->crit_sect);
-
-		slot_enable (ctrl, hp_slot);
-		green_LED_blink (ctrl, hp_slot);
-
-		amber_LED_off (ctrl, hp_slot);
-
-		set_SOGO(ctrl);
-
-		// Wait for SOBS to be unset
-		wait_for_ctrl_irq (ctrl);
-
-		// Done with exclusive hardware access
-		up(&ctrl->crit_sect);
-
-		// Wait for ~1 second because of hot plug spec
-		long_delay(1*HZ);
-
-		// Check for a power fault
-		if (func->status == 0xFF) {
-			// power fault occurred, but it was benign
-			rc = POWER_FAILURE;
-			func->status = 0;
-		} else
-			rc = cpqhp_valid_replace(ctrl, func);
-
-		if (!rc) {
-			// It must be the same board
-
-			rc = cpqhp_configure_board(ctrl, func);
-
-			if (rc || src) {
-				// If configuration fails, turn it off
-				// Get slot won't work for devices behind bridges, but
-				// in this case it will always be called for the "base"
-				// bus/dev/func of an adapter.
-
-				// Wait for exclusive access to hardware
-				down(&ctrl->crit_sect);
-
-				amber_LED_on (ctrl, hp_slot);
-				green_LED_off (ctrl, hp_slot);
-				slot_disable (ctrl, hp_slot);
-
-				set_SOGO(ctrl);
-
-				// Wait for SOBS to be unset
-				wait_for_ctrl_irq (ctrl);
-
-				// Done with exclusive hardware access
-				up(&ctrl->crit_sect);
-
-				if (rc)
-					return(rc);
-				else
-					return(1);
-			}
-
-			func->status = 0;
-			func->switch_save = 0x10;
-
-			index = 1;
-			while (((func = cpqhp_slot_find(func->bus, func->device, index)) != NULL) && !rc) {
-				rc |= cpqhp_configure_board(ctrl, func);
-				index++;
-			}
-
-			if (rc) {
-				// If configuration fails, turn it off
-				// Get slot won't work for devices behind bridges, but
-				// in this case it will always be called for the "base"
-				// bus/dev/func of an adapter.
-
-				// Wait for exclusive access to hardware
-				down(&ctrl->crit_sect);
-
-				amber_LED_on (ctrl, hp_slot);
-				green_LED_off (ctrl, hp_slot);
-				slot_disable (ctrl, hp_slot);
-
-				set_SOGO(ctrl);
-
-				// Wait for SOBS to be unset
-				wait_for_ctrl_irq (ctrl);
-
-				// Done with exclusive hardware access
-				up(&ctrl->crit_sect);
-
-				return(rc);
-			}
-			// Done configuring so turn LED on full time
-
-			// Wait for exclusive access to hardware
-			down(&ctrl->crit_sect);
-
-			green_LED_on (ctrl, hp_slot);
-
-			set_SOGO(ctrl);
-
-			// Wait for SOBS to be unset
-			wait_for_ctrl_irq (ctrl);
-
-			// Done with exclusive hardware access
-			up(&ctrl->crit_sect);
-			rc = 0;
-		} else {
-			// Something is wrong
-
-			// Get slot won't work for devices behind bridges, but
-			// in this case it will always be called for the "base"
-			// bus/dev/func of an adapter.
-
-			// Wait for exclusive access to hardware
-			down(&ctrl->crit_sect);
-
-			amber_LED_on (ctrl, hp_slot);
-			green_LED_off (ctrl, hp_slot);
-			slot_disable (ctrl, hp_slot);
-
-			set_SOGO(ctrl);
-
-			// Wait for SOBS to be unset
-			wait_for_ctrl_irq (ctrl);
-
-			// Done with exclusive hardware access
-			up(&ctrl->crit_sect);
-		}
-
-	}
-	return(rc);
-
-}
-
-
-/**
  * board_added - Called after a board has been added to the system.
  *
  * Turns power on for the board
@@ -1386,131 +1159,105 @@
 static u32 board_added(struct pci_func * func, struct controller * ctrl)
 {
 	u8 hp_slot;
-	u8 temp_byte;
-	u8 adapter_speed;
 	int index;
 	u32 temp_register = 0xFFFFFFFF;
 	u32 rc = 0;
-	struct pci_func *new_slot = NULL;
+	struct pci_func *new_func = NULL;
 	struct slot *p_slot;
 	struct resource_lists res_lists;
+	enum pci_bus_speed adapter_speed, bus_speed;
 
+	p_slot = cpqhp_find_slot(ctrl, func->device);
 	hp_slot = func->device - ctrl->slot_device_offset;
-	dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n",
-	    __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot);
 
-	// Wait for exclusive access to hardware
-	down(&ctrl->crit_sect);
-
-	// turn on board without attaching to the bus
-	enable_slot_power (ctrl, hp_slot);
-
-	set_SOGO(ctrl);
+	dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n", __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot);
 
-	// Wait for SOBS to be unset
-	wait_for_ctrl_irq (ctrl);
+	rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &adapter_speed);
 
-	// Change bits in slot power register to force another shift out
-	// NOTE: this is to work around the timer bug
-	temp_byte = readb(ctrl->hpc_reg + SLOT_POWER);
-	writeb(0x00, ctrl->hpc_reg + SLOT_POWER);
-	writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER);
-
-	set_SOGO(ctrl);
-
-	// Wait for SOBS to be unset
-	wait_for_ctrl_irq (ctrl);
-	
-	adapter_speed = get_adapter_speed(ctrl, hp_slot);
-	if (ctrl->speed != adapter_speed)
-		if (set_controller_speed(ctrl, adapter_speed, hp_slot))
-			rc = WRONG_BUS_FREQUENCY;
-	
-	// turn off board without attaching to the bus
-	disable_slot_power (ctrl, hp_slot);
-
-	set_SOGO(ctrl);
-
-	// Wait for SOBS to be unset
-	wait_for_ctrl_irq (ctrl);
-
-	// Done with exclusive hardware access
-	up(&ctrl->crit_sect);
+	/*
+	 *  0 = PCI 33Mhz, 1 = PCI 66 Mhz, 2 = PCI-X 66 Mhz, 3 = PCI-X 100 Mhz,
+	 *  4 = PCI-X 133 Mhz, 0xAC = ACPI (unknown)
+	 */
+	if (rc  || adapter_speed == PCI_SPEED_UNKNOWN) {
+		err("%s: Can't get adapter speed  or bus mode mismatch\n", __FUNCTION__);
+		return WRONG_BUS_FREQUENCY;
+	}
 
-	if (rc)
-		return(rc);
-	
-	p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
+	rc = p_slot->hpc_ops->get_cur_bus_speed(p_slot, &bus_speed);
+	if (rc || bus_speed == PCI_SPEED_UNKNOWN) {
+		err("%s: Can't get bus operation speed\n", __FUNCTION__);
+		return WRONG_BUS_FREQUENCY;
+	}
 
-	// turn on board and blink green LED
+	if (adapter_speed != bus_speed) {
+		if ((ctrl->pci_dev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ) && 
+				(ctrl->rev >= 0x13)) {
+			if (p_slot->hpc_ops->set_controller_speed(p_slot, adapter_speed))
+				return WRONG_BUS_FREQUENCY;
+		} else if (adapter_speed < bus_speed) {
+				err("%s: speeds of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
+				return WRONG_BUS_FREQUENCY;
+		}
+	}
 
-	// Wait for exclusive access to hardware
-	dbg("%s: before down\n", __FUNCTION__);
+	/* Wait for exclusive access to hardware */
 	down(&ctrl->crit_sect);
-	dbg("%s: after down\n", __FUNCTION__);
-
-	dbg("%s: before slot_enable\n", __FUNCTION__);
-	slot_enable (ctrl, hp_slot);
 
-	dbg("%s: before green_LED_blink\n", __FUNCTION__);
-	green_LED_blink (ctrl, hp_slot);
+	/* turn on board */
+	p_slot->hpc_ops->power_on_slot(p_slot);
 
-	dbg("%s: before amber_LED_blink\n", __FUNCTION__);
-	amber_LED_off (ctrl, hp_slot);
+	/* blink green LED, turn off Amber LEDs */
+	p_slot->hpc_ops->green_led_blink(p_slot);
+	p_slot->hpc_ops->set_attention_status(p_slot, 0);
 
-	dbg("%s: before set_SOGO\n", __FUNCTION__);
-	set_SOGO(ctrl);
+	p_slot->hpc_ops->update_hpc(p_slot);
+	dbg("%s: after update_hpc\n", __FUNCTION__);
 
-	// Wait for SOBS to be unset
-	dbg("%s: before wait_for_ctrl_irq\n", __FUNCTION__);
-	wait_for_ctrl_irq (ctrl);
-	dbg("%s: after wait_for_ctrl_irq\n", __FUNCTION__);
-
-	// Done with exclusive hardware access
-	dbg("%s: before up\n", __FUNCTION__);
+	/* Done with exclusive hardware access */
 	up(&ctrl->crit_sect);
-	dbg("%s: after up\n", __FUNCTION__);
 
-	// Wait for ~1 second because of hot plug spec
+	/* Wait for ~1 second because of hot plug spec */
 	dbg("%s: before long_delay\n", __FUNCTION__);
 	long_delay(1*HZ);
 	dbg("%s: after long_delay\n", __FUNCTION__);
 
 	dbg("%s: func status = %x\n", __FUNCTION__, func->status);
-	// Check for a power fault
+	/* Check for a power fault */
 	if (func->status == 0xFF) {
-		// power fault occurred, but it was benign
+		/*  
+		 *  power fault occurred, but it was benign
+		 */
 		temp_register = 0xFFFFFFFF;
 		dbg("%s: temp register set to %x by power fault\n", __FUNCTION__, temp_register);
 		rc = POWER_FAILURE;
 		func->status = 0;
 	} else {
-		// Get vendor/device ID u32
+		/* Get vendor/device ID u32 */
 		ctrl->pci_bus->number = func->bus;
 		rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, func->function), PCI_VENDOR_ID, &temp_register);
-		dbg("%s: pci_read_config_dword returns %d\n", __FUNCTION__, rc);
+		dbg("%s: pci_bus_read_config_dword returns %d\n", __FUNCTION__, rc);
 		dbg("%s: temp_register is %x\n", __FUNCTION__, temp_register);
 
 		if (rc != 0) {
-			// Something's wrong here
+			/* Something's wrong here */
 			temp_register = 0xFFFFFFFF;
 			dbg("%s: temp register set to %x by error\n", __FUNCTION__, temp_register);
 		}
-		// Preset return code.  It will be changed later if things go okay.
+		/* Preset return code.  It will be changed later if things go okay. */
 		rc = NO_ADAPTER_PRESENT;
 	}
 
-	// All F's is an empty slot or an invalid board
-	if (temp_register != 0xFFFFFFFF) {	  // Check for a board in the slot
+	/* All F's is an empty slot or an invalid board */
+	if (temp_register != 0xFFFFFFFF) {	  /* Check for a board in the slot */
 		res_lists.io_head = ctrl->io_head;
 		res_lists.mem_head = ctrl->mem_head;
 		res_lists.p_mem_head = ctrl->p_mem_head;
 		res_lists.bus_head = ctrl->bus_head;
 		res_lists.irqs = NULL;
 
-		rc = configure_new_device(ctrl, func, 0, &res_lists);
-
+		rc = configure_new_device(ctrl, func, 0, &res_lists, 0, 0);
 		dbg("%s: back from configure_new_device\n", __FUNCTION__);
+
 		ctrl->io_head = res_lists.io_head;
 		ctrl->mem_head = res_lists.mem_head;
 		ctrl->p_mem_head = res_lists.p_mem_head;
@@ -1522,66 +1269,67 @@
 		cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
 
 		if (rc) {
-			// Wait for exclusive access to hardware
+			/* Wait for exclusive access to hardware */
 			down(&ctrl->crit_sect);
 
-			amber_LED_on (ctrl, hp_slot);
-			green_LED_off (ctrl, hp_slot);
-			slot_disable (ctrl, hp_slot);
+			/* turn off slot */
+			p_slot->hpc_ops->power_off_slot(p_slot);
 
-			set_SOGO(ctrl);
+			/* turn on Amber LED */
+			/* turn off Green LED */
+			p_slot->hpc_ops->set_attention_status(p_slot, 1);
+			p_slot->hpc_ops->green_led_off(p_slot);
 
-			// Wait for SOBS to be unset
-			wait_for_ctrl_irq (ctrl);
+			p_slot->hpc_ops->update_hpc(p_slot);
 
-			// Done with exclusive hardware access
+			/* Done with exclusive hardware access */
 			up(&ctrl->crit_sect);
+
 			return(rc);
-		} else {
-			cpqhp_save_slot_config(ctrl, func);
 		}
-
+		cpqhp_save_slot_config(ctrl, func);
 
 		func->status = 0;
 		func->switch_save = 0x10;
 		func->is_a_board = 0x01;
 
-		//next, we will instantiate the linux pci_dev structures (with appropriate driver notification, if already present)
-		dbg("%s: configure linux pci_dev structure\n", __FUNCTION__);
+		/*  next, we will instantiate the linux pci_dev structures 
+		 *  (with appropriate driver notification, if already present)
+		 */
 		index = 0;
 		do {
-			new_slot = cpqhp_slot_find(ctrl->bus, func->device, index++);
-			if (new_slot && !new_slot->pci_dev) {
-				cpqhp_configure_device(ctrl, new_slot);
+			new_func = cpqhp_slot_find(ctrl->bus, func->device, index++);
+			if (new_func && !new_func->pci_dev) {
+				dbg("%s:call pci_hp_configure_dev\n", __FUNCTION__);
+				cpqhp_configure_device(ctrl, new_func);
 			}
-		} while (new_slot);
+		} while (new_func);
 
-		// Wait for exclusive access to hardware
+		/* Wait for exclusive access to hardware */
 		down(&ctrl->crit_sect);
 
-		green_LED_on (ctrl, hp_slot);
-
-		set_SOGO(ctrl);
+		p_slot->hpc_ops->green_led_on(p_slot);
 
-		// Wait for SOBS to be unset
-		wait_for_ctrl_irq (ctrl);
+		p_slot->hpc_ops->update_hpc(p_slot);
 
-		// Done with exclusive hardware access
+		/* Done with exclusive hardware access */
 		up(&ctrl->crit_sect);
+
 	} else {
-		// Wait for exclusive access to hardware
+		/* Wait for exclusive access to hardware */
 		down(&ctrl->crit_sect);
 
-		amber_LED_on (ctrl, hp_slot);
-		green_LED_off (ctrl, hp_slot);
-		slot_disable (ctrl, hp_slot);
+		/* turn off slot */
+		p_slot->hpc_ops->power_off_slot(p_slot);
 
-		set_SOGO(ctrl);
-
-		// Wait for SOBS to be unset
-		wait_for_ctrl_irq (ctrl);
+		/* turn on Amber LED */
+		/* turn off Green LED */
+		p_slot->hpc_ops->set_attention_status(p_slot, 1);
+		p_slot->hpc_ops->green_led_off(p_slot);
+		
+		p_slot->hpc_ops->update_hpc(p_slot);
 
-		// Done with exclusive hardware access
+		/* Done with exclusive hardware access */
 		up(&ctrl->crit_sect);
 
 		return(rc);
@@ -1594,16 +1342,16 @@
  * remove_board - Turns off slot and LED's
  *
  */
-static u32 remove_board(struct pci_func * func, u32 replace_flag, struct controller * ctrl)
+static u32 remove_board(struct pci_func *func, struct controller *ctrl)
 {
 	int index;
 	u8 skip = 0;
 	u8 device;
 	u8 hp_slot;
-	u8 temp_byte;
 	u32 rc;
 	struct resource_lists res_lists;
 	struct pci_func *temp_func;
+	struct slot *p_slot;
 
 	if (func == NULL)
 		return(1);
@@ -1614,62 +1362,60 @@
 	device = func->device;
 
 	hp_slot = func->device - ctrl->slot_device_offset;
+	p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->first_device_num);
+
 	dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
 
-	// When we get here, it is safe to change base Address Registers.
-	// We will attempt to save the base Address Register Lengths
-	if (replace_flag || !ctrl->add_support)
-		rc = cpqhp_save_base_addr_length(ctrl, func);
-	else if (!func->bus_head && !func->mem_head &&
-		 !func->p_mem_head && !func->io_head) {
-		// Here we check to see if we've saved any of the board's
-		// resources already.  If so, we'll skip the attempt to
-		// determine what's being used.
+	if ((ctrl->add_support) &&
+		!(func->bus_head || func->mem_head || func->p_mem_head || func->io_head)) {
+		/* 
+		 *  Here we check to see if we've saved any of the board's
+		 *  resources already.  If so, we'll skip the attempt to
+		 *  determine what's being used. */
 		index = 0;
-		temp_func = cpqhp_slot_find(func->bus, func->device, index++);
-		while (temp_func) {
+
+		temp_func = func;
+
+		while ((temp_func = cpqhp_slot_find(temp_func->bus, temp_func->device, index++))) {
 			if (temp_func->bus_head || temp_func->mem_head
 			    || temp_func->p_mem_head || temp_func->io_head) {
 				skip = 1;
 				break;
 			}
-			temp_func = cpqhp_slot_find(temp_func->bus, temp_func->device, index++);
 		}
 
 		if (!skip)
-			rc = cpqhp_save_used_resources(ctrl, func);
+			rc = cpqhp_save_used_resources(ctrl, func, DISABLE_CARD);
 	}
-	// Change status to shutdown
+	/* Change status to shutdown */
 	if (func->is_a_board)
 		func->status = 0x01;
 	func->configured = 0;
 
-	// Wait for exclusive access to hardware
+	/* Wait for exclusive access to hardware */
 	down(&ctrl->crit_sect);
 
-	green_LED_off (ctrl, hp_slot);
-	slot_disable (ctrl, hp_slot);
-
-	set_SOGO(ctrl);
+	/* turn off Green LED */
+	p_slot->hpc_ops->green_led_off(p_slot);
 
-	// turn off SERR for slot
-	temp_byte = readb(ctrl->hpc_reg + SLOT_SERR);
-	temp_byte &= ~(0x01 << hp_slot);
-	writeb(temp_byte, ctrl->hpc_reg + SLOT_SERR);
+	/* turn off the slot */
+	/* phphpc_power_off_slot(p_slot); */
+	p_slot->hpc_ops->power_off_slot(p_slot);
 
-	// Wait for SOBS to be unset
-	wait_for_ctrl_irq (ctrl);
+	p_slot->hpc_ops->update_hpc(p_slot);
 
-	// Done with exclusive hardware access
+	/* Done with exclusive hardware access */
 	up(&ctrl->crit_sect);
 
-	if (!replace_flag && ctrl->add_support) {
+	if (ctrl->add_support) {
 		while (func) {
 			res_lists.io_head = ctrl->io_head;
 			res_lists.mem_head = ctrl->mem_head;
 			res_lists.p_mem_head = ctrl->p_mem_head;
 			res_lists.bus_head = ctrl->bus_head;
 
+			dbg("Returning resources to ctlr lists for (B/D/F) = (%#x/%#x/%#x)\n", func->bus, func->device, func->function);
+
 			cpqhp_return_board_resources(func, &res_lists);
 
 			ctrl->io_head = res_lists.io_head;
@@ -1683,18 +1429,20 @@
 			cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
 
 			if (is_bridge(func)) {
+				info("PCI Bridge Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device, func->function);
 				bridge_slot_remove(func);
 			} else
+				info("PCI Function Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device, func->function);
 				slot_remove(func);
 
 			func = cpqhp_slot_find(ctrl->bus, device, 0);
 		}
 
-		// Setup slot structure with entry for empty slot
+		/* Setup slot structure with entry for empty slot */
 		func = cpqhp_slot_create(ctrl->bus);
 
 		if (func == NULL) {
-			// Out of memory
+			/* Out of memory */
 			return(1);
 		}
 
@@ -1718,20 +1466,21 @@
 }
 
 
-// this is the main worker thread
+/* this is the main worker thread */
 static int event_thread(void* data)
 {
 	struct controller *ctrl;
+
 	lock_kernel();
 	daemonize("phpd_event");
-	
 	unlock_kernel();
 
 	while (1) {
 		dbg("!!!!event_thread sleeping\n");
 		down_interruptible (&event_semaphore);
 		dbg("event_thread woken finished = %d\n", event_finished);
-		if (event_finished) break;
+		if (event_finished || signal_pending(current))
+			break;
 		/* Do stuff here */
 		if (pushbutton_pending)
 			cpqhp_pushbutton_thread(pushbutton_pending);
@@ -1775,7 +1524,7 @@
 }
 
 
-static int update_slot_info (struct controller *ctrl, struct slot *slot)
+static int update_slot_info (struct slot *slot)
 {
 	struct hotplug_slot_info *info;
 	int result;
@@ -1784,11 +1533,13 @@
 	if (!info)
 		return -ENOMEM;
 
-	info->power_status = get_slot_enabled(ctrl, slot);
-	info->attention_status = cpq_get_attention_status(ctrl, slot);
-	info->latch_status = cpq_get_latch_status(ctrl, slot);
-	info->adapter_status = get_presence_status(ctrl, slot);
+	slot->hpc_ops->get_power_status(slot, &(info->power_status));
+	slot->hpc_ops->get_attention_status(slot, &(info->attention_status));
+	slot->hpc_ops->get_latch_status(slot, &(info->latch_status));
+	slot->hpc_ops->get_adapter_status(slot, &(info->adapter_status));
+
 	result = pci_hp_change_slot_info(slot->hotplug_slot, info);
+
 	kfree (info);
 	return result;
 }
@@ -1799,13 +1550,13 @@
 	int change = 1;
 	struct pci_func *func;
 	u8 hp_slot;
+	u8 getstatus;
 	struct slot *p_slot;
 
 	while (change) {
 		change = 0;
 
 		for (loop = 0; loop < 10; loop++) {
-			//dbg("loop %d\n", loop);
 			if (ctrl->event_queue[loop].event_type != 0) {
 				hp_slot = ctrl->event_queue[loop].hp_slot;
 
@@ -1827,90 +1578,104 @@
 					dbg("button cancel\n");
 					del_timer(&p_slot->task_event);
 
-					// Wait for exclusive access to hardware
-					down(&ctrl->crit_sect);
-
-					if (p_slot->state == BLINKINGOFF_STATE) {
-						// slot is on
-						// turn on green LED
-						dbg("turn on green LED\n");
-						green_LED_on (ctrl, hp_slot);
-					} else if (p_slot->state == BLINKINGON_STATE) {
-						// slot is off
-						// turn off green LED
-						dbg("turn off green LED\n");
-						green_LED_off (ctrl, hp_slot);
+					switch (p_slot->state) {
+					case BLINKINGOFF_STATE:
+						/* Wait for exclusive access to hardware */
+						down(&ctrl->crit_sect);
+
+						p_slot->hpc_ops->green_led_on(p_slot);
+						p_slot->hpc_ops->set_attention_status(p_slot, 0);
+
+						p_slot->hpc_ops->update_hpc(p_slot);
+
+						/* Done with exclusive hardware access */
+						up(&ctrl->crit_sect);
+
+						break;
+					case BLINKINGON_STATE:
+						/* Wait for exclusive access to hardware */
+						down(&ctrl->crit_sect);
+
+						p_slot->hpc_ops->green_led_off(p_slot);
+						p_slot->hpc_ops->set_attention_status(p_slot, 0);
+						
+						p_slot->hpc_ops->update_hpc(p_slot);
+
+						/* Done with exclusive hardware access */
+						up(&ctrl->crit_sect);
+
+						break;
+					default:
+						warn("Not a valid state\n");
+						return;
 					}
-
 					info(msg_button_cancel, p_slot->number);
-
 					p_slot->state = STATIC_STATE;
-
-					amber_LED_off (ctrl, hp_slot);
-
-					set_SOGO(ctrl);
-
-					// Wait for SOBS to be unset
-					wait_for_ctrl_irq (ctrl);
-
-					// Done with exclusive hardware access
-					up(&ctrl->crit_sect);
 				}
-				// ***********button Released (No action on press...)
+				/*********** button Released (No action on press...) */
 				else if (ctrl->event_queue[loop].event_type == INT_BUTTON_RELEASE) {
 					dbg("button release\n");
+					p_slot->hp_slot = hp_slot;
+					p_slot->ctrl = ctrl;
 
-					if (is_slot_enabled (ctrl, hp_slot)) {
-						// slot is on
+					/* phphpc_get_power_status (p_slot, &getstatus); */
+					p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
+
+					if (getstatus) {
+						/* slot is on */
 						dbg("slot is on\n");
 						p_slot->state = BLINKINGOFF_STATE;
 						info(msg_button_off, p_slot->number);
 					} else {
-						// slot is off
+						/* slot is off */
 						dbg("slot is off\n");
 						p_slot->state = BLINKINGON_STATE;
 						info(msg_button_on, p_slot->number);
 					}
-					// Wait for exclusive access to hardware
+
+					/* Wait for exclusive access to hardware */
 					down(&ctrl->crit_sect);
-					
-					dbg("blink green LED and turn off amber\n");
-					
-					amber_LED_off (ctrl, hp_slot);
-					green_LED_blink (ctrl, hp_slot);
-					
-					set_SOGO(ctrl);
 
-					// Wait for SOBS to be unset
-					wait_for_ctrl_irq (ctrl);
+					/* blink green LED and turn off amber */
+					p_slot->hpc_ops->green_led_blink(p_slot);
+					p_slot->hpc_ops->set_attention_status(p_slot, 0);
+		
+					p_slot->hpc_ops->update_hpc(p_slot);
 
-					// Done with exclusive hardware access
+					/* Done with exclusive hardware access */
 					up(&ctrl->crit_sect);
+
 					init_timer(&p_slot->task_event);
-					p_slot->hp_slot = hp_slot;
-					p_slot->ctrl = ctrl;
-//					p_slot->physical_slot = physical_slot;
-					p_slot->task_event.expires = jiffies + 5 * HZ;   // 5 second delay
-					p_slot->task_event.function = pushbutton_helper_thread;
+					p_slot->task_event.expires = jiffies + 5 * HZ;   /* 5 second delay */
+					p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread;
 					p_slot->task_event.data = (u32) p_slot;
 
-					dbg("add_timer p_slot = %p\n", p_slot);
+					dbg("add_timer p_slot = %p\n", (void *) p_slot);
 					add_timer(&p_slot->task_event);
 				}
-				// ***********POWER FAULT
+				/* ***********POWER FAULT*****************/
 				else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
 					dbg("power fault\n");
+					/* Wait for exclusive access to hardware */
+					down(&ctrl->crit_sect);
+
+					p_slot->hpc_ops->set_attention_status(p_slot, 1);
+					p_slot->hpc_ops->green_led_off(p_slot);
+
+					/* Done with exclusive hardware access */
+					up(&ctrl->crit_sect);
+
 				} else {
 					/* refresh notification */
 					if (p_slot)
-						update_slot_info(ctrl, p_slot);
+						update_slot_info(p_slot);
 				}
 
 				ctrl->event_queue[loop].event_type = 0;
 
 				change = 1;
 			}
-		}		// End of FOR loop
+		}		/* End of FOR loop */
 	}
 
 	return;
@@ -1926,63 +1691,55 @@
  */
 void cpqhp_pushbutton_thread (unsigned long slot)
 {
-	u8 hp_slot;
-	u8 device;
-	struct pci_func *func;
 	struct slot *p_slot = (struct slot *) slot;
-	struct controller *ctrl = (struct controller *) p_slot->ctrl;
+	u8 getstatus;
 
 	pushbutton_pending = 0;
-	hp_slot = p_slot->hp_slot;
 
-	device = p_slot->device;
+	if (!p_slot) {
+		dbg("%s: Error! slot NULL\n", __FUNCTION__);
+		return;
+	}
+
+	p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
 
-	if (is_slot_enabled (ctrl, hp_slot)) {
+	if (getstatus) {
 		p_slot->state = POWEROFF_STATE;
-		// power Down board
-		func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);
-		dbg("In power_down_board, func = %p, ctrl = %p\n", func, ctrl);
-		if (!func) {
-			dbg("Error! func NULL in %s\n", __FUNCTION__);
-			return ;
-		}
-
-		if (func != NULL && ctrl != NULL) {
-			if (cpqhp_process_SS(ctrl, func) != 0) {
-				amber_LED_on (ctrl, hp_slot);
-				green_LED_on (ctrl, hp_slot);
-				
-				set_SOGO(ctrl);
+		dbg("In power_down_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
 
-				// Wait for SOBS to be unset
-				wait_for_ctrl_irq (ctrl);
-			}
-		}
+		if (cpqhp_process_SS(p_slot)) {
+			/* Wait for exclusive access to hardware */
+			down(&p_slot->ctrl->crit_sect);
+
+			/* Turn on the LED */
+			p_slot->hpc_ops->set_attention_status(p_slot, 1);
+			p_slot->hpc_ops->green_led_on(p_slot);
+
+			p_slot->hpc_ops->update_hpc(p_slot);
 
+			/* Done with exclusive hardware access */
+			up(&p_slot->ctrl->crit_sect);
+
+		}
 		p_slot->state = STATIC_STATE;
 	} else {
 		p_slot->state = POWERON_STATE;
-		// slot is off
+		dbg("In add_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
 
-		func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);
-		dbg("In add_board, func = %p, ctrl = %p\n", func, ctrl);
-		if (!func) {
-			dbg("Error! func NULL in %s\n", __FUNCTION__);
-			return ;
-		}
-
-		if (func != NULL && ctrl != NULL) {
-			if (cpqhp_process_SI(ctrl, func) != 0) {
-				amber_LED_on (ctrl, hp_slot);
-				green_LED_off (ctrl, hp_slot);
-				
-				set_SOGO(ctrl);
+		if (cpqhp_process_SI(p_slot)) {
+			/* Wait for exclusive access to hardware */
+			down(&p_slot->ctrl->crit_sect);
 
-				// Wait for SOBS to be unset
-				wait_for_ctrl_irq (ctrl);
-			}
-		}
+			/* Turn off the green LED */
+			p_slot->hpc_ops->set_attention_status(p_slot, 1);
+			p_slot->hpc_ops->green_led_off(p_slot);
+
+			p_slot->hpc_ops->update_hpc(p_slot);
+
+			/* Done with exclusive hardware access */
+			up(&p_slot->ctrl->crit_sect);
 
+		}
 		p_slot->state = STATIC_STATE;
 	}
 
@@ -1990,132 +1747,144 @@
 }
 
 
-int cpqhp_process_SI (struct controller *ctrl, struct pci_func *func)
+int cpqhp_process_SI (struct slot *p_slot)
 {
-	u8 device, hp_slot;
-	u16 temp_word;
-	u32 tempdword;
+	u8 getstatus = 0;
 	int rc;
-	struct slot* p_slot;
-	int physical_slot = 0;
+	struct pci_func *func;
 
-	if (!ctrl)
-		return(1);
+	func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);
+	if (!func) {
+		dbg("%s: Error! slot NULL\n", __FUNCTION__);
+		return (1);
+	}
 
-	tempdword = 0;
+	/* Check to see if (latch closed, card present, power off) */
+	down(&p_slot->ctrl->crit_sect);
 
-	device = func->device;
-	hp_slot = device - ctrl->slot_device_offset;
-	p_slot = cpqhp_find_slot(ctrl, device);
-	if (p_slot) {
-		physical_slot = p_slot->number;
+	rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
+	if (rc || !getstatus) {
+		info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
+		up(&p_slot->ctrl->crit_sect);
+		return (0);
 	}
 
-	// Check to see if the interlock is closed
-	tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
-
-	if (tempdword & (0x01 << hp_slot)) {
-		return(1);
+	rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
+	if (rc || !getstatus) {
+		info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
+		up(&p_slot->ctrl->crit_sect);
+		return (0);
 	}
 
-	if (func->is_a_board) {
-		rc = board_replaced(func, ctrl);
-	} else {
-		// add board
-		slot_remove(func);
+	rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
+	if (rc || getstatus) {
+		info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number);
+		up(&p_slot->ctrl->crit_sect);
+		return (0);
+	}
+	up(&p_slot->ctrl->crit_sect);
 
-		func = cpqhp_slot_create(ctrl->bus);
-		if (func == NULL) {
-			return(1);
-		}
+	/* add board */
+	slot_remove(func);
 
-		func->bus = ctrl->bus;
-		func->device = device;
-		func->function = 0;
-		func->configured = 0;
-		func->is_a_board = 1;
-
-		// We have to save the presence info for these slots
-		temp_word = ctrl->ctrl_int_comp >> 16;
-		func->presence_save = (temp_word >> hp_slot) & 0x01;
-		func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
+	func = cpqhp_slot_create(p_slot->bus);
+	if (func == NULL)
+		return (1);
 
-		if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
-			func->switch_save = 0;
-		} else {
-			func->switch_save = 0x10;
-		}
+	func->bus = p_slot->bus;
+	func->device = p_slot->device;
+	func->function = 0;
+	func->configured = 0;
+	func->is_a_board = 1;
 
-		rc = board_added(func, ctrl);
-		if (rc) {
-			if (is_bridge(func)) {
-				bridge_slot_remove(func);
-			} else
-				slot_remove(func);
+	/* We have to save the presence info for these slots */
+	p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
+	p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
+	
+	func->switch_save = !getstatus? 0x10:0;
 
-			// Setup slot structure with entry for empty slot
-			func = cpqhp_slot_create(ctrl->bus);
+	rc = board_added(func, p_slot->ctrl);
+	if (rc) {
+		if (is_bridge(func))
+			bridge_slot_remove(func);
+		else
+			slot_remove(func);
 
-			if (func == NULL) {
-				// Out of memory
-				return(1);
-			}
+		/* Setup slot structure with entry for empty slot */
+		func = cpqhp_slot_create(p_slot->bus);
+		if (func == NULL)
+			return (1);	/* Out of memory */
 
-			func->bus = ctrl->bus;
-			func->device = device;
-			func->function = 0;
-			func->configured = 0;
-			func->is_a_board = 0;
-
-			// We have to save the presence info for these slots
-			temp_word = ctrl->ctrl_int_comp >> 16;
-			func->presence_save = (temp_word >> hp_slot) & 0x01;
-			func->presence_save |=
-			(temp_word >> (hp_slot + 7)) & 0x02;
+		func->bus = p_slot->bus;
+		func->device = p_slot->device;
+		func->function = 0;
+		func->configured = 0;
+		func->is_a_board = 1;
 
-			if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
-				func->switch_save = 0;
-			} else {
-				func->switch_save = 0x10;
-			}
-		}
-	}
+		/* We have to save the presence info for these slots */
+		p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
+		p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
 
-	if (rc) {
-		dbg("%s: rc = %d\n", __FUNCTION__, rc);
+		func->switch_save = !getstatus? 0x10:0;
 	}
 
 	if (p_slot)
-		update_slot_info(ctrl, p_slot);
+		update_slot_info(p_slot);
 
 	return rc;
 }
 
 
-int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func)
+int cpqhp_process_SS (struct slot *p_slot)
 {
-	u8 device, class_code, header_type, BCR;
+	u8 class_code, header_type, BCR;
 	u8 index = 0;
-	u8 replace_flag;
+	u8 getstatus = 0;
 	u32 rc = 0;
+	int ret = 0;
 	unsigned int devfn;
-	struct slot* p_slot;
-	struct pci_bus *pci_bus = ctrl->pci_bus;
-	int physical_slot=0;
-
-	device = func->device; 
-	func = cpqhp_slot_find(ctrl->bus, device, index++);
-	p_slot = cpqhp_find_slot(ctrl, device);
-	if (p_slot) {
-		physical_slot = p_slot->number;
+	struct pci_bus *pci_bus = p_slot->ctrl->pci_bus;
+	struct pci_func *func;
+
+	if (!p_slot->ctrl)
+		return (1);
+
+	/* Check to see if (latch closed, card present, power on) */
+	down(&p_slot->ctrl->crit_sect);
+
+	ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
+	if (ret || !getstatus) {
+		info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
+		up(&p_slot->ctrl->crit_sect);
+		return (0);
+	}
+
+	ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
+	if (ret || !getstatus) {
+		info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
+		up(&p_slot->ctrl->crit_sect);
+		return (0);
 	}
 
-	// Make sure there are no video controllers here
+	ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
+	if (ret || !getstatus) {
+		info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number);
+		up(&p_slot->ctrl->crit_sect);
+		return (0);
+	}
+	up(&p_slot->ctrl->crit_sect);
+
+	func = cpqhp_slot_find(p_slot->bus, p_slot->device, index++);
+
+	/* 
+	 *  Make sure there are no video controllers here
+	 *  for all func of p_slot
+	 */
 	while (func && !rc) {
 		pci_bus->number = func->bus;
 		devfn = PCI_DEVFN(func->device, func->function);
 
-		// Check the Class Code
+		/* Check the Class Code */
 		rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
 		if (rc)
 			return rc;
@@ -2124,213 +1893,40 @@
 			/* Display/Video adapter (not supported) */
 			rc = REMOVE_NOT_SUPPORTED;
 		} else {
-			// See if it's a bridge
+			/* See if it's a bridge */
 			rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
 			if (rc)
 				return rc;
 
-			// If it's a bridge, check the VGA Enable bit
+			/* If it's a bridge, check the VGA Enable bit */
 			if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
 				rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
 				if (rc)
 					return rc;
 
-				// If the VGA Enable bit is set, remove isn't supported
+				/* If the VGA Enable bit is set, remove isn't supported */
 				if (BCR & PCI_BRIDGE_CTL_VGA) {
 					rc = REMOVE_NOT_SUPPORTED;
 				}
 			}
 		}
 
-		func = cpqhp_slot_find(ctrl->bus, device, index++);
+		func = cpqhp_slot_find(p_slot->bus, p_slot->device, index++);
 	}
 
-	func = cpqhp_slot_find(ctrl->bus, device, 0);
+	func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);
 	if ((func != NULL) && !rc) {
-		//FIXME: Replace flag should be passed into process_SS
-		replace_flag = !(ctrl->add_support);
-		rc = remove_board(func, replace_flag, ctrl);
-	} else if (!rc) {
+		rc = remove_board(func, p_slot->ctrl);
+	} else if (!rc)
 		rc = 1;
-	}
 
 	if (p_slot)
-		update_slot_info(ctrl, p_slot);
+		update_slot_info(p_slot);
 
 	return(rc);
 }
 
 
-
-/**
- * hardware_test - runs hardware tests
- *
- * For hot plug ctrl folks to play with.
- * test_num is the number entered in the GUI
- *
- */
-int cpqhp_hardware_test(struct controller *ctrl, int test_num)
-{
-	u32 save_LED;
-	u32 work_LED;
-	int loop;
-	int num_of_slots;
-
-	num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0f;
-
-	switch (test_num) {
-		case 1:
-			// Do stuff here!
-
-			// Do that funky LED thing
-			save_LED = readl(ctrl->hpc_reg + LED_CONTROL);	// so we can restore them later
-			work_LED = 0x01010101;
-			writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-			for (loop = 0; loop < num_of_slots; loop++) {
-				set_SOGO(ctrl);
-
-				// Wait for SOGO interrupt
-				wait_for_ctrl_irq (ctrl);
-
-				// Get ready for next iteration
-				work_LED = work_LED << 1;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-				long_delay((2*HZ)/10);
-			}
-			for (loop = 0; loop < num_of_slots; loop++) {
-				work_LED = work_LED >> 1;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-				
-				set_SOGO(ctrl);
-
-				// Wait for SOGO interrupt
-				wait_for_ctrl_irq (ctrl);
-
-				// Get ready for next iteration
-				long_delay((2*HZ)/10);
-			}
-			for (loop = 0; loop < num_of_slots; loop++) {
-				work_LED = work_LED << 1;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-				
-				set_SOGO(ctrl);
-
-				// Wait for SOGO interrupt
-				wait_for_ctrl_irq (ctrl);
-
-				// Get ready for next iteration
-				long_delay((2*HZ)/10);
-			}
-			for (loop = 0; loop < num_of_slots; loop++) {
-				work_LED = work_LED >> 1;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-				
-				set_SOGO(ctrl);
-
-				// Wait for SOGO interrupt
-				wait_for_ctrl_irq (ctrl);
-
-				// Get ready for next iteration
-				long_delay((2*HZ)/10);
-			}
-
-			work_LED = 0x01010000;
-			writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-			for (loop = 0; loop < num_of_slots; loop++) {
-				set_SOGO(ctrl);
-
-				// Wait for SOGO interrupt
-				wait_for_ctrl_irq (ctrl);
-
-				// Get ready for next iteration
-				work_LED = work_LED << 1;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-				long_delay((2*HZ)/10);
-			}
-			for (loop = 0; loop < num_of_slots; loop++) {
-				work_LED = work_LED >> 1;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-				
-				set_SOGO(ctrl);
-
-				// Wait for SOGO interrupt
-				wait_for_ctrl_irq (ctrl);
-
-				// Get ready for next iteration
-				long_delay((2*HZ)/10);
-			}
-			work_LED = 0x00000101;
-			writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-			for (loop = 0; loop < num_of_slots; loop++) {
-				work_LED = work_LED << 1;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-				
-				set_SOGO(ctrl);
-
-				// Wait for SOGO interrupt
-				wait_for_ctrl_irq (ctrl);
-
-				// Get ready for next iteration
-				long_delay((2*HZ)/10);
-			}
-			for (loop = 0; loop < num_of_slots; loop++) {
-				work_LED = work_LED >> 1;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-				
-				set_SOGO(ctrl);
-
-				// Wait for SOGO interrupt
-				wait_for_ctrl_irq (ctrl);
-
-				// Get ready for next iteration
-				long_delay((2*HZ)/10);
-			}
-
-
-			work_LED = 0x01010000;
-			writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-			for (loop = 0; loop < num_of_slots; loop++) {
-				set_SOGO(ctrl);
-
-				// Wait for SOGO interrupt
-				wait_for_ctrl_irq (ctrl);
-
-				// Get ready for next iteration
-				long_delay((3*HZ)/10);
-				work_LED = work_LED >> 16;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-				
-				set_SOGO(ctrl);
-
-				// Wait for SOGO interrupt
-				wait_for_ctrl_irq (ctrl);
-
-				// Get ready for next iteration
-				long_delay((3*HZ)/10);
-				work_LED = work_LED << 16;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-				work_LED = work_LED << 1;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-			}
-
-			writel (save_LED, ctrl->hpc_reg + LED_CONTROL);	// put it back the way it was
-
-			set_SOGO(ctrl);
-
-			// Wait for SOBS to be unset
-			wait_for_ctrl_irq (ctrl);
-			break;
-		case 2:
-			// Do other stuff here!
-			break;
-		case 3:
-			// and more...
-			break;
-	}
-	return 0;
-}
-
-
 /**
  * configure_new_device - Configures the PCI header information of one board.
  *
@@ -2343,26 +1939,30 @@
  *
  */
 static u32 configure_new_device (struct controller * ctrl, struct pci_func * func,
-				 u8 behind_bridge, struct resource_lists * resources)
+	u8 behind_bridge, struct resource_lists * resources, u8 bridge_bus, u8 bridge_dev)
 {
 	u8 temp_byte, function, max_functions, stop_it;
 	int rc;
 	u32 ID;
 	struct pci_func *new_slot;
+	struct pci_bus lpci_bus, *pci_bus;
 	int index;
 
 	new_slot = func;
 
 	dbg("%s\n", __FUNCTION__);
-	// Check for Multi-function device
-	ctrl->pci_bus->number = func->bus;
-	rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(func->device, func->function), 0x0E, &temp_byte);
+	memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
+	pci_bus = &lpci_bus;
+	pci_bus->number = func->bus;
+
+	/* Check for Multi-function device */
+	rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(func->device, func->function), 0x0E, &temp_byte);
 	if (rc) {
 		dbg("%s: rc = %d\n", __FUNCTION__, rc);
 		return rc;
 	}
 
-	if (temp_byte & 0x80)	// Multi-function device
+	if (temp_byte & 0x80)	/* Multi-function device */
 		max_functions = 8;
 	else
 		max_functions = 1;
@@ -2370,7 +1970,7 @@
 	function = 0;
 
 	do {
-		rc = configure_new_function(ctrl, new_slot, behind_bridge, resources);
+		rc = configure_new_function(ctrl, new_slot, behind_bridge, resources, bridge_bus, bridge_dev);
 
 		if (rc) {
 			dbg("configure_new_function failed %d\n",rc);
@@ -2390,20 +1990,21 @@
 
 		stop_it = 0;
 
-		//  The following loop skips to the next present function
-		//  and creates a board structure
+		/*  
+		 *  The following loop skips to the next present function
+		 *  and creates a board structure
+		 */
 
 		while ((function < max_functions) && (!stop_it)) {
-			pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
-
-			if (ID == 0xFFFFFFFF) {	  // There's nothing there. 
+			pci_bus_read_config_dword(pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
+			if (ID == 0xFFFFFFFF) {	  /* There's nothing there.  */
 				function++;
-			} else {  // There's something there
-				// Setup slot structure.
+			} else {  /* There's something there */
+				/* Setup slot structure. */
 				new_slot = cpqhp_slot_create(func->bus);
 
 				if (new_slot == NULL) {
-					// Out of memory
+					/* Out of memory */
 					return(1);
 				}
 
@@ -2443,16 +2044,13 @@
  *
  */
 static int configure_new_function (struct controller * ctrl, struct pci_func * func,
-				   u8 behind_bridge, struct resource_lists * resources)
+	u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev)
 {
 	int cloop;
-	u8 IRQ;
 	u8 temp_byte;
 	u8 device;
 	u8 class_code;
-	u16 command;
 	u16 temp_word;
-	u32 temp_dword;
 	u32 rc;
 	u32 temp_register;
 	u32 base;
@@ -2468,82 +2066,86 @@
 	struct pci_resource *hold_bus_node;
 	struct irq_mapping irqs;
 	struct pci_func *new_slot;
-	struct pci_bus *pci_bus;
+	struct pci_bus lpci_bus, *pci_bus;
 	struct resource_lists temp_resources;
 
-	pci_bus = ctrl->pci_bus;
+	memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
+	pci_bus = &lpci_bus;
 	pci_bus->number = func->bus;
 	devfn = PCI_DEVFN(func->device, func->function);
 
-	// Check for Bridge
+	/* Check for Bridge */
 	rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &temp_byte);
 	if (rc)
 		return rc;
 
-	if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
-		// set Primary bus
-		dbg("set Primary bus = %d\n", func->bus);
-		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);
+	if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
+		/* set Primary bus */
+		dbg("set Primary bus = 0x%x\n", func->bus);
+		rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);
 		if (rc)
 			return rc;
 
-		// find range of busses to use
-		dbg("find ranges of buses to use\n");
-		bus_node = get_max_resource(&resources->bus_head, 1);
+		/* find range of busses to use */
+		bus_node = get_max_resource(&resources->bus_head, 1L);
 
-		// If we don't have any busses to allocate, we can't continue
-		if (!bus_node)
+		/* If we don't have any busses to allocate, we can't continue */
+		if (!bus_node) {
+			err("Got NO bus resource to use\n");
 			return -ENOMEM;
+		}
+		dbg("Got ranges of buses to use: base:len=0x%x:%x\n", bus_node->base, bus_node->length);
 
-		// set Secondary bus
-		temp_byte = bus_node->base;
-		dbg("set Secondary bus = %d\n", bus_node->base);
-		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, temp_byte);
+		/* set Secondary bus */
+		temp_byte = (u8)bus_node->base;
+		dbg("set Secondary bus = 0x%x\n", temp_byte);
+		rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, temp_byte);
 		if (rc)
 			return rc;
 
-		// set subordinate bus
-		temp_byte = bus_node->base + bus_node->length - 1;
-		dbg("set subordinate bus = %d\n", bus_node->base + bus_node->length - 1);
+		/* set subordinate bus */
+		temp_byte = (u8)(bus_node->base + bus_node->length - 1);
+		dbg("set subordinate bus = 0x%x\n", temp_byte);
 		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
 		if (rc)
 			return rc;
 
-		// set subordinate Latency Timer and base Latency Timer
-		temp_byte = 0x40;
-		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
-		if (rc)
-			return rc;
-		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
+		/* Set HP parameters (Cache Line Size, Latency Timer) */
+		rc = phprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_BRIDGE);
 		if (rc)
 			return rc;
 
-		// set Cache Line size
-		temp_byte = 0x08;
-		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
-		if (rc)
-			return rc;
-
-		// Setup the IO, memory, and prefetchable windows
+		/* Setup the IO, memory, and prefetchable windows */
 
-		io_node = get_max_resource(&(resources->io_head), 0x1000);
-		if (!io_node)
+		io_node = get_max_resource(&(resources->io_head), 0x1000L);
+		if (io_node) {
+			dbg("io_node(base, len, next) (%x, %x, %p)\n", io_node->base, io_node->length, io_node->next);
+		} else
 			return -ENOMEM;
-		mem_node = get_max_resource(&(resources->mem_head), 0x100000);
-		if (!mem_node)
+
+		mem_node = get_max_resource(&(resources->mem_head), 0x100000L);
+		if (mem_node) {
+			dbg("mem_node(base, len, next) (%x, %x, %p)\n", mem_node->base, mem_node->length, mem_node->next);
+		} else
 			return -ENOMEM;
-		p_mem_node = get_max_resource(&(resources->p_mem_head), 0x100000);
-		if (!p_mem_node)
+
+		if (resources->p_mem_head)
+			p_mem_node = get_max_resource(&(resources->p_mem_head), 0x100000L);
+		else {
+			/*
+			 * In some platform implementation, MEM and PMEM are not
+			 *  distinguished, and hence ACPI _CRS has only MEM entries
+			 *  for both MEM and PMEM.
+			 */
+			dbg("using MEM for PMEM\n");
+			p_mem_node = get_max_resource(&(resources->mem_head), 0x100000L);
+		}
+		if (p_mem_node) {
+			dbg("p_mem_node(base, len, next) (%x, %x, %p)\n", p_mem_node->base, p_mem_node->length, p_mem_node->next);
+		} else
 			return -ENOMEM;
-		dbg("Setup the IO, memory, and prefetchable windows\n");
-		dbg("io_node\n");
-		dbg("(base, len, next) (%x, %x, %p)\n", io_node->base, io_node->length, io_node->next);
-		dbg("mem_node\n");
-		dbg("(base, len, next) (%x, %x, %p)\n", mem_node->base, mem_node->length, mem_node->next);
-		dbg("p_mem_node\n");
-		dbg("(base, len, next) (%x, %x, %p)\n", p_mem_node->base, p_mem_node->length, p_mem_node->next);
 
-		// set up the IRQ info
+		/* set up the IRQ info */
 		if (!resources->irqs) {
 			irqs.barber_pole = 0;
 			irqs.interrupt[0] = 0;
@@ -2560,16 +2162,20 @@
 			irqs.valid_INT = resources->irqs->valid_INT;
 		}
 
-		// set up resource lists that are now aligned on top and bottom
-		// for anything behind the bridge.
+		/* 
+		 * set up resource lists that are now aligned on top and bottom
+		 * for anything behind the bridge.
+		 */
 		temp_resources.bus_head = bus_node;
 		temp_resources.io_head = io_node;
 		temp_resources.mem_head = mem_node;
 		temp_resources.p_mem_head = p_mem_node;
 		temp_resources.irqs = &irqs;
 
-		// Make copies of the nodes we are going to pass down so that
-		// if there is a problem,we can just use these to free resources
+		/*  
+		 *  Make copies of the nodes we are going to pass down so that
+		 *  if there is a problem,we can just use these to free resources
+		 */
 		hold_bus_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
 		hold_IO_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
 		hold_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
@@ -2594,35 +2200,42 @@
 		bus_node->length -= 1;
 		bus_node->next = NULL;
 
-		// If we have IO resources copy them and fill in the bridge's
-		// IO range registers
+		/*  
+		 *  If we have IO resources copy them and fill in the bridge's
+		 *  IO range registers
+		 */
 		if (io_node) {
 			memcpy(hold_IO_node, io_node, sizeof(struct pci_resource));
 			io_node->next = NULL;
 
-			// set IO base and Limit registers
-			temp_byte = io_node->base >> 8;
+			/* set IO base and Limit registers */
+			RES_CHECK(io_node->base, 8);
+			temp_byte = (u8)(io_node->base >> 8);
 			rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte);
-
-			temp_byte = (io_node->base + io_node->length - 1) >> 8;
+			RES_CHECK(io_node->base + io_node->length - 1, 8);
+			temp_byte = (u8)((io_node->base + io_node->length - 1) >> 8);
 			rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
 		} else {
 			kfree(hold_IO_node);
 			hold_IO_node = NULL;
 		}
 
-		// If we have memory resources copy them and fill in the bridge's
-		// memory range registers.  Otherwise, fill in the range
-		// registers with values that disable them.
+		/*  
+		 *  If we have memory resources copy them and fill in the bridge's
+		 *  memory range registers.  Otherwise, fill in the range
+		 *  registers with values that disable them.
+		 */
 		if (mem_node) {
 			memcpy(hold_mem_node, mem_node, sizeof(struct pci_resource));
 			mem_node->next = NULL;
 
-			// set Mem base and Limit registers
-			temp_word = mem_node->base >> 16;
-			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
+			/* set Mem base and Limit registers */
+			RES_CHECK(mem_node->base, 16);
+			temp_word = (u32)(mem_node->base >> 16);
 
-			temp_word = (mem_node->base + mem_node->length - 1) >> 16;
+			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
+			RES_CHECK(mem_node->base + mem_node->length - 1, 16);
+			temp_word = (u32)((mem_node->base + mem_node->length - 1) >> 16);
 			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
 		} else {
 			temp_word = 0xFFFF;
@@ -2635,19 +2248,24 @@
 			hold_mem_node = NULL;
 		}
 
-		// If we have prefetchable memory resources copy them and 
-		// fill in the bridge's memory range registers.  Otherwise,
-		// fill in the range registers with values that disable them.
+		/* 
+		 *  If we have prefetchable memory resources copy them and 
+		 *  fill in the bridge's memory range registers.  Otherwise,
+		 *  fill in the range registers with values that disable them.
+		 */
 		if (p_mem_node) {
 			memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource));
 			p_mem_node->next = NULL;
 
-			// set Pre Mem base and Limit registers
-			temp_word = p_mem_node->base >> 16;
+			/* set Pre Mem base and Limit registers */
+			RES_CHECK(p_mem_node->base, 16);
+			temp_word = (u32)(p_mem_node->base >> 16);
 			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
 
-			temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16;
+			RES_CHECK(p_mem_node->base + p_mem_node->length - 1, 16);
+			temp_word = (u32)((p_mem_node->base + p_mem_node->length - 1) >> 16);
 			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
+
 		} else {
 			temp_word = 0xFFFF;
 			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
@@ -2659,26 +2277,27 @@
 			hold_p_mem_node = NULL;
 		}
 
-		// Adjust this to compensate for extra adjustment in first loop
+		/* Adjust this to compensate for extra adjustment in first loop */
 		irqs.barber_pole--;
 
 		rc = 0;
 
-		// Here we actually find the devices and configure them
+		/* Here we actually find the devices and configure them */
 		for (device = 0; (device <= 0x1F) && !rc; device++) {
 			irqs.barber_pole = (irqs.barber_pole + 1) & 0x03;
 
 			ID = 0xFFFFFFFF;
 			pci_bus->number = hold_bus_node->base;
-			pci_bus_read_config_dword (pci_bus, PCI_DEVFN(device, 0), 0x00, &ID);
+			pci_bus_read_config_dword (pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);
+
 			pci_bus->number = func->bus;
 
-			if (ID != 0xFFFFFFFF) {	  //  device Present
-				// Setup slot structure.
+			if (ID != 0xFFFFFFFF) {	  /*  device Present */
+				/* Setup slot structure. */
 				new_slot = cpqhp_slot_create(hold_bus_node->base);
 
 				if (new_slot == NULL) {
-					// Out of memory
+					/* Out of memory */
 					rc = -ENOMEM;
 					continue;
 				}
@@ -2689,10 +2308,10 @@
 				new_slot->is_a_board = 1;
 				new_slot->status = 0;
 
-				rc = configure_new_device(ctrl, new_slot, 1, &temp_resources);
+				rc = configure_new_device(ctrl, new_slot, 1, &temp_resources, func->bus, func->device);
 				dbg("configure_new_device rc=0x%x\n",rc);
-			}	// End of IF (device in slot?)
-		}		// End of FOR loop
+			}	/* End of IF (device in slot?) */
+		}		/* End of FOR loop */
 
 		if (rc) {
 			cpqhp_destroy_resource_list(&temp_resources);
@@ -2703,7 +2322,8 @@
 			return_resource(&(resources->p_mem_head), hold_p_mem_node);
 			return(rc);
 		}
-		// save the interrupt routing information
+
+		/* save the interrupt routing information */
 		if (resources->irqs) {
 			resources->irqs->interrupt[0] = irqs.interrupt[0];
 			resources->irqs->interrupt[1] = irqs.interrupt[1];
@@ -2711,129 +2331,136 @@
 			resources->irqs->interrupt[3] = irqs.interrupt[3];
 			resources->irqs->valid_INT = irqs.valid_INT;
 		} else if (!behind_bridge) {
-			// We need to hook up the interrupts here
+			/* We need to hook up the interrupts here */
 			for (cloop = 0; cloop < 4; cloop++) {
 				if (irqs.valid_INT & (0x01 << cloop)) {
 					rc = cpqhp_set_irq(func->bus, func->device,
 							   0x0A + cloop, irqs.interrupt[cloop]);
 					if (rc) {
 						cpqhp_destroy_resource_list (&temp_resources);
-
-						return_resource(&(resources-> bus_head), hold_bus_node);
-						return_resource(&(resources-> io_head), hold_IO_node);
-						return_resource(&(resources-> mem_head), hold_mem_node);
-						return_resource(&(resources-> p_mem_head), hold_p_mem_node);
+						return_resource(&(resources->bus_head), hold_bus_node);
+						return_resource(&(resources->io_head), hold_IO_node);
+						return_resource(&(resources->mem_head), hold_mem_node);
+						return_resource(&(resources->p_mem_head), hold_p_mem_node);
 						return rc;
 					}
 				}
-			}	// end of for loop
+			}	/* end of for loop */
 		}
-		// Return unused bus resources
-		// First use the temporary node to store information for the board
+
+		/* Return unused bus resources */
+		/* First use the temporary node to store information for the board */
 		if (hold_bus_node && bus_node && temp_resources.bus_head) {
 			hold_bus_node->length = bus_node->base - hold_bus_node->base;
 
 			hold_bus_node->next = func->bus_head;
 			func->bus_head = hold_bus_node;
 
-			temp_byte = temp_resources.bus_head->base - 1;
+			temp_byte = (u8)(temp_resources.bus_head->base - 1);
 
-			// set subordinate bus
+			/* set subordinate bus */
+			dbg("re-set subordinate bus = 0x%x\n", temp_byte);
 			rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
 
 			if (temp_resources.bus_head->length == 0) {
 				kfree(temp_resources.bus_head);
 				temp_resources.bus_head = NULL;
 			} else {
+				dbg("return bus res of b:d(0x%x:%x) base:len(0x%x:%x)\n",
+					func->bus, func->device, temp_resources.bus_head->base, temp_resources.bus_head->length);
 				return_resource(&(resources->bus_head), temp_resources.bus_head);
 			}
 		}
 
-		// If we have IO space available and there is some left,
-		// return the unused portion
+		/* If we have IO space available and there is some left,
+		   return the unused portion */
 		if (hold_IO_node && temp_resources.io_head) {
 			io_node = do_pre_bridge_resource_split(&(temp_resources.io_head),
 							       &hold_IO_node, 0x1000);
 
-			// Check if we were able to split something off
+			/* Check if we were able to split something off */
 			if (io_node) {
 				hold_IO_node->base = io_node->base + io_node->length;
 
-				temp_byte = (hold_IO_node->base) >> 8;
-				rc = pci_bus_write_config_word (pci_bus, devfn, PCI_IO_BASE, temp_byte);
+				RES_CHECK(hold_IO_node->base, 8);
+				temp_byte = (u8)((hold_IO_node->base) >> 8);
+				rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte);
 
 				return_resource(&(resources->io_head), io_node);
 			}
 
 			io_node = do_bridge_resource_split(&(temp_resources.io_head), 0x1000);
 
-			// Check if we were able to split something off
+			/* Check if we were able to split something off */
 			if (io_node) {
-				// First use the temporary node to store information for the board
+				/* First use the temporary node to store information for the board */
 				hold_IO_node->length = io_node->base - hold_IO_node->base;
 
-				// If we used any, add it to the board's list
+				/* If we used any, add it to the board's list */
 				if (hold_IO_node->length) {
 					hold_IO_node->next = func->io_head;
 					func->io_head = hold_IO_node;
 
-					temp_byte = (io_node->base - 1) >> 8;
+					RES_CHECK(io_node->base - 1, 8);
+					temp_byte = (u8)((io_node->base - 1) >> 8);
 					rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
 
 					return_resource(&(resources->io_head), io_node);
 				} else {
-					// it doesn't need any IO
-					temp_word = 0x0000;
-					rc = pci_bus_write_config_word (pci_bus, devfn, PCI_IO_LIMIT, temp_word);
+					/* it doesn't need any IO */
+					temp_byte = 0x00;
+					rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
 
 					return_resource(&(resources->io_head), io_node);
 					kfree(hold_IO_node);
 				}
 			} else {
-				// it used most of the range
+				/* it used most of the range */
 				hold_IO_node->next = func->io_head;
 				func->io_head = hold_IO_node;
 			}
 		} else if (hold_IO_node) {
-			// it used the whole range
+			/* it used the whole range */
 			hold_IO_node->next = func->io_head;
 			func->io_head = hold_IO_node;
 		}
-		// If we have memory space available and there is some left,
-		// return the unused portion
+
+		/* If we have memory space available and there is some left,
+		   return the unused portion */
 		if (hold_mem_node && temp_resources.mem_head) {
-			mem_node = do_pre_bridge_resource_split(&(temp_resources.  mem_head),
-								&hold_mem_node, 0x100000);
+			mem_node = do_pre_bridge_resource_split(&(temp_resources.mem_head), &hold_mem_node, 0x100000L);
 
-			// Check if we were able to split something off
+			/* Check if we were able to split something off */
 			if (mem_node) {
 				hold_mem_node->base = mem_node->base + mem_node->length;
 
-				temp_word = (hold_mem_node->base) >> 16;
+				RES_CHECK(hold_mem_node->base, 16);
+				temp_word = (u32)((hold_mem_node->base) >> 16);
 				rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
 
 				return_resource(&(resources->mem_head), mem_node);
 			}
 
-			mem_node = do_bridge_resource_split(&(temp_resources.mem_head), 0x100000);
+			mem_node = do_bridge_resource_split(&(temp_resources.mem_head), 0x100000L);
 
-			// Check if we were able to split something off
+			/* Check if we were able to split something off */
 			if (mem_node) {
-				// First use the temporary node to store information for the board
+				/* First use the temporary node to store information for the board */
 				hold_mem_node->length = mem_node->base - hold_mem_node->base;
 
 				if (hold_mem_node->length) {
 					hold_mem_node->next = func->mem_head;
 					func->mem_head = hold_mem_node;
 
-					// configure end address
-					temp_word = (mem_node->base - 1) >> 16;
+					/* configure end address */
+					RES_CHECK(mem_node->base - 1, 16);
+					temp_word = (u32)((mem_node->base - 1) >> 16);
 					rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
 
-					// Return unused resources to the pool
+					/* Return unused resources to the pool */
 					return_resource(&(resources->mem_head), mem_node);
 				} else {
-					// it doesn't need any Mem
+					/* it doesn't need any Mem */
 					temp_word = 0x0000;
 					rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
 
@@ -2841,49 +2468,52 @@
 					kfree(hold_mem_node);
 				}
 			} else {
-				// it used most of the range
+				/* it used most of the range */
 				hold_mem_node->next = func->mem_head;
 				func->mem_head = hold_mem_node;
 			}
 		} else if (hold_mem_node) {
-			// it used the whole range
+			/* it used the whole range */
 			hold_mem_node->next = func->mem_head;
 			func->mem_head = hold_mem_node;
 		}
-		// If we have prefetchable memory space available and there is some 
-		// left at the end, return the unused portion
+
+		/* If we have prefetchable memory space available and there is some 
+		   left at the end, return the unused portion */
 		if (hold_p_mem_node && temp_resources.p_mem_head) {
 			p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head),
-								  &hold_p_mem_node, 0x100000);
+								  &hold_p_mem_node, 0x100000L);
 
-			// Check if we were able to split something off
+			/* Check if we were able to split something off */
 			if (p_mem_node) {
 				hold_p_mem_node->base = p_mem_node->base + p_mem_node->length;
 
-				temp_word = (hold_p_mem_node->base) >> 16;
+				RES_CHECK(hold_p_mem_node->base, 16);
+				temp_word = (u32)((hold_p_mem_node->base) >> 16);
 				rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
 
 				return_resource(&(resources->p_mem_head), p_mem_node);
 			}
 
-			p_mem_node = do_bridge_resource_split(&(temp_resources.p_mem_head), 0x100000);
+			p_mem_node = do_bridge_resource_split(&(temp_resources.p_mem_head), 0x100000L);
 
-			// Check if we were able to split something off
+			/* Check if we were able to split something off */
 			if (p_mem_node) {
-				// First use the temporary node to store information for the board
+				/* First use the temporary node to store information for the board */
 				hold_p_mem_node->length = p_mem_node->base - hold_p_mem_node->base;
 
-				// If we used any, add it to the board's list
+				/* If we used any, add it to the board's list */
 				if (hold_p_mem_node->length) {
 					hold_p_mem_node->next = func->p_mem_head;
 					func->p_mem_head = hold_p_mem_node;
 
-					temp_word = (p_mem_node->base - 1) >> 16;
+					RES_CHECK(p_mem_node->base - 1, 16);
+					temp_word = (u32)((p_mem_node->base - 1) >> 16);
 					rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
 
 					return_resource(&(resources->p_mem_head), p_mem_node);
 				} else {
-					// it doesn't need any PMem
+					/* it doesn't need any PMem */
 					temp_word = 0x0000;
 					rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
 
@@ -2891,189 +2521,167 @@
 					kfree(hold_p_mem_node);
 				}
 			} else {
-				// it used the most of the range
+				/* it used the most of the range */
 				hold_p_mem_node->next = func->p_mem_head;
 				func->p_mem_head = hold_p_mem_node;
 			}
 		} else if (hold_p_mem_node) {
-			// it used the whole range
+			/* it used the whole range */
 			hold_p_mem_node->next = func->p_mem_head;
 			func->p_mem_head = hold_p_mem_node;
 		}
-		// We should be configuring an IRQ and the bridge's base address
-		// registers if it needs them.  Although we have never seen such
-		// a device
-
-		// enable card
-		command = 0x0157;	// = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |  PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR
-		rc = pci_bus_write_config_word (pci_bus, devfn, PCI_COMMAND, command);
-
-		// set Bridge Control Register
-		command = 0x07;		// = PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_NO_ISA
-		rc = pci_bus_write_config_word (pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
+
+		/* We should be configuring an IRQ and the bridge's base address
+		   registers if it needs them.  Although we have never seen such
+		   a device */
+
+		phprm_enable_card(ctrl, func, PCI_HEADER_TYPE_BRIDGE);
+
+		info("PCI Bridge Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device, func->function);
 	} else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
-		// Standard device
+		/* Standard device */
+		u64	base64;
 		rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
 
-		if (class_code == PCI_BASE_CLASS_DISPLAY) {
-			// Display (video) adapter (not supported)
-			return(DEVICE_TYPE_NOT_SUPPORTED);
-		}
-		// Figure out IO and memory needs
-		for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
+		if (class_code == PCI_BASE_CLASS_DISPLAY)
+			return (DEVICE_TYPE_NOT_SUPPORTED);
+
+		/* Figure out IO and memory needs */
+		for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) {
 			temp_register = 0xFFFFFFFF;
 
-			dbg("CND: bus=%d, devfn=%d, offset=%d\n", pci_bus->number, devfn, cloop);
 			rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
+			rc = pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register);
 
-			rc = pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp_register);
-			dbg("CND: base = 0x%x\n", temp_register);
-
-			if (temp_register) {	  // If this register is implemented
-				if ((temp_register & 0x03L) == 0x01) {
-					// Map IO
-
-					// set base = amount of IO space
-					base = temp_register & 0xFFFFFFFC;
-					base = ~base + 1;
-
-					dbg("CND:      length = 0x%x\n", base);
-					io_node = get_io_resource(&(resources->io_head), base);
-					dbg("Got io_node start = %8.8x, length = %8.8x next (%p)\n",
-					    io_node->base, io_node->length, io_node->next);
-					dbg("func (%p) io_head (%p)\n", func, func->io_head);
-
-					// allocate the resource to the board
-					if (io_node) {
-						base = io_node->base;
-
-						io_node->next = func->io_head;
-						func->io_head = io_node;
-					} else
-						return -ENOMEM;
-				} else if ((temp_register & 0x0BL) == 0x08) {
-					// Map prefetchable memory
-					base = temp_register & 0xFFFFFFF0;
-					base = ~base + 1;
-
-					dbg("CND:      length = 0x%x\n", base);
-					p_mem_node = get_resource(&(resources->p_mem_head), base);
-
-					// allocate the resource to the board
-					if (p_mem_node) {
-						base = p_mem_node->base;
-
-						p_mem_node->next = func->p_mem_head;
-						func->p_mem_head = p_mem_node;
-					} else
-						return -ENOMEM;
-				} else if ((temp_register & 0x0BL) == 0x00) {
-					// Map memory
-					base = temp_register & 0xFFFFFFF0;
-					base = ~base + 1;
+			dbg("Bar[%x]=0x%x on bus:dev:func(0x%x:%x:%x)\n", cloop, temp_register, func->bus, func->device, func->function);
 
-					dbg("CND:      length = 0x%x\n", base);
-					mem_node = get_resource(&(resources->mem_head), base);
+			if (!temp_register)
+				continue;
 
-					// allocate the resource to the board
-					if (mem_node) {
-						base = mem_node->base;
+			base64 = 0L;
+			if (temp_register & PCI_BASE_ADDRESS_SPACE_IO) {
+				/* Map IO */
+
+				/* set base = amount of IO space */
+				base = temp_register & 0xFFFFFFFC;
+				base = ~base + 1;
+
+				dbg("NEED IO length(0x%x)\n", base);
+				io_node = get_io_resource(&(resources->io_head),(ulong)base);
+
+				/* allocate the resource to the board */
+				if (io_node) {
+					dbg("Got IO base=0x%x(length=0x%x)\n", io_node->base, io_node->length);
+					base = (u32)io_node->base;
+					io_node->next = func->io_head;
+					func->io_head = io_node;
+				} else {
+					err("Got NO IO resource(length=0x%x)\n", base);
+					return -ENOMEM;
+				}
+			} else {	/* map MEM */
+				int prefetchable = 1;
+				struct pci_resource **res_node = &func->p_mem_head;
+				char *res_type_str = "PMEM";
+				u32	temp_register2;
+
+				if (!(temp_register & PCI_BASE_ADDRESS_MEM_PREFETCH)) {
+					prefetchable = 0;
+					res_node = &func->mem_head;
+					res_type_str++;
+				}
 
-						mem_node->next = func->mem_head;
-						func->mem_head = mem_node;
-					} else
-						return -ENOMEM;
-				} else if ((temp_register & 0x0BL) == 0x04) {
-					// Map memory
-					base = temp_register & 0xFFFFFFF0;
-					base = ~base + 1;
+				base = temp_register & 0xFFFFFFF0;
+				base = ~base + 1;
 
-					dbg("CND:      length = 0x%x\n", base);
-					mem_node = get_resource(&(resources->mem_head), base);
+				switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
+				case PCI_BASE_ADDRESS_MEM_TYPE_32:
+					dbg("NEED 32 %s bar=0x%x(length=0x%x)\n", res_type_str, temp_register, base);
+
+					if (prefetchable && resources->p_mem_head)
+						mem_node=get_resource(&(resources->p_mem_head), (ulong)base);
+					else {
+						if (prefetchable)
+							dbg("using MEM for PMEM\n");
+						mem_node=get_resource(&(resources->mem_head), (ulong)base);
+					}
 
-					// allocate the resource to the board
+					/* allocate the resource to the board */
 					if (mem_node) {
-						base = mem_node->base;
+						base = (u32)mem_node->base; 
+						mem_node->next = *res_node;
+						*res_node = mem_node;
+						dbg("Got 32 %s base=0x%x(length=0x%x)\n", res_type_str, mem_node->base, mem_node->length);
+					} else {
+						err("Got NO 32 %s resource(length=0x%x)\n", res_type_str, base);
+						return -ENOMEM;
+					}
+					break;
+				case PCI_BASE_ADDRESS_MEM_TYPE_64:
+					rc = pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2);
+
+					dbg("NEED 64 %s bar=0x%x:%x(length=0x%x)\n", res_type_str, temp_register2, temp_register, base);
+
+					if (prefetchable && resources->p_mem_head)
+						mem_node = get_resource(&(resources->p_mem_head), (ulong)base);
+					else {
+						if (prefetchable)
+							dbg("using MEM for PMEM\n");
+						mem_node = get_resource(&(resources->mem_head), (ulong)base);
+					}
 
-						mem_node->next = func->mem_head;
-						func->mem_head = mem_node;
-					} else
+					/* allocate the resource to the board */
+					if (mem_node) {
+						base64 = mem_node->base; 
+						mem_node->next = *res_node;
+						*res_node = mem_node;
+						dbg("Got 64 %s base=0x%x:%x(length=%x)\n", res_type_str, (u32)(base64 >> 32), (u32)base64, mem_node->length);
+					} else {
+						err("Got NO 64 %s resource(length=0x%x)\n", res_type_str, base);
 						return -ENOMEM;
-				} else if ((temp_register & 0x0BL) == 0x06) {
-					// Those bits are reserved, we can't handle this
-					return(1);
-				} else {
-					// Requesting space below 1M
-					return(NOT_ENOUGH_RESOURCES);
+					}
+					break;
+				default:
+					dbg("reserved BAR type=0x%x\n", temp_register);
+					break;
 				}
 
-				rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, base);
-
-				// Check for 64-bit base
-				if ((temp_register & 0x07L) == 0x04) {
-					cloop += 4;
-
-					// Upper 32 bits of address always zero on today's systems
-					// FIXME this is probably not true on Alpha and ia64???
-					base = 0;
-					rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, base);
-				}
 			}
-		}		// End of base register loop
 
-		// Figure out which interrupt pin this function uses
-		rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_INTERRUPT_PIN, &temp_byte);
+			if (base64) {
+				rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64);
 
-		// If this function needs an interrupt and we are behind a bridge
-		// and the pin is tied to something that's alread mapped,
-		// set this one the same
-		if (temp_byte && resources->irqs && 
-		    (resources->irqs->valid_INT & 
-		     (0x01 << ((temp_byte + resources->irqs->barber_pole - 1) & 0x03)))) {
-			// We have to share with something already set up
-			IRQ = resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03];
-		} else {
-			// Program IRQ based on card type
-			rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
+				cloop += 4;
+				base64 >>= 32;
+
+				if (base64) {
+					dbg("%s: high dword of base64(0x%x) set to 0\n", __FUNCTION__, (u32)base64);
+					base64 = 0x0L;
+				}
+
+				rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64);
 
-			if (class_code == PCI_BASE_CLASS_STORAGE) {
-				IRQ = cpqhp_disk_irq;
 			} else {
-				IRQ = cpqhp_nic_irq;
+				rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, base);
+
 			}
-		}
+		}		/* End of base register loop */
 
-		// IRQ Line
-		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_INTERRUPT_LINE, IRQ);
+		/* disable ROM base Address */
+		temp_word = 0x00L;
+		rc = pci_bus_write_config_word (pci_bus, devfn, PCI_ROM_ADDRESS, temp_word);
 
-		if (!behind_bridge) {
-			rc = cpqhp_set_irq(func->bus, func->device, temp_byte + 0x09, IRQ);
-			if (rc)
-				return(1);
-		} else {
-			//TBD - this code may also belong in the other clause of this If statement
-			resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03] = IRQ;
-			resources->irqs->valid_INT |= 0x01 << (temp_byte + resources->irqs->barber_pole - 1) & 0x03;
-		}
-
-		// Latency Timer
-		temp_byte = 0x40;
-		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
-
-		// Cache Line size
-		temp_byte = 0x08;
-		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
-
-		// disable ROM base Address
-		temp_dword = 0x00L;
-		rc = pci_bus_write_config_word (pci_bus, devfn, PCI_ROM_ADDRESS, temp_dword);
-
-		// enable card
-		temp_word = 0x0157;	// = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |  PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR
-		rc = pci_bus_write_config_word (pci_bus, devfn, PCI_COMMAND, temp_word);
-	}			// End of Not-A-Bridge else
+		/* Set HP parameters (Cache Line Size, Latency Timer) */
+		rc = phprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_NORMAL);
+		if (rc)
+			return rc;
+
+		phprm_enable_card(ctrl, func, PCI_HEADER_TYPE_NORMAL);
+
+		info("PCI function Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device, func->function);
+	}			/* End of Not-A-Bridge else */
 	else {
-		// It's some strange type of PCI adapter (Cardbus?)
+		/* It's some strange type of PCI adapter (Cardbus?) */
 		return(DEVICE_TYPE_NOT_SUPPORTED);
 	}
 

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2003-07-14 14:27 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-07-14 14:30 [Patch] 2/4 PCI Hot-plug driver patch for 2.5.74 kernel Dely Sy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).