brintos

brintos / linux-shallow public Read only

0
0
Text · 73.4 KiB · c01968e Raw
2912 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * Compaq Hot Plug Controller Driver4 *5 * Copyright (C) 1995,2001 Compaq Computer Corporation6 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)7 * Copyright (C) 2001 IBM Corp.8 *9 * All rights reserved.10 *11 * Send feedback to <greg@kroah.com>12 *13 */14 15#include <linux/module.h>16#include <linux/kernel.h>17#include <linux/types.h>18#include <linux/slab.h>19#include <linux/workqueue.h>20#include <linux/interrupt.h>21#include <linux/delay.h>22#include <linux/wait.h>23#include <linux/pci.h>24#include <linux/pci_hotplug.h>25#include <linux/kthread.h>26#include "cpqphp.h"27 28static u32 configure_new_device(struct controller *ctrl, struct pci_func *func,29			u8 behind_bridge, struct resource_lists *resources);30static int configure_new_function(struct controller *ctrl, struct pci_func *func,31			u8 behind_bridge, struct resource_lists *resources);32static void interrupt_event_handler(struct controller *ctrl);33 34 35static struct task_struct *cpqhp_event_thread;36static struct timer_list *pushbutton_pending;	/* = NULL */37 38/* delay is in jiffies to wait for */39static void long_delay(int delay)40{41	/*42	 * XXX(hch): if someone is bored please convert all callers43	 * to call msleep_interruptible directly.  They really want44	 * to specify timeouts in natural units and spend a lot of45	 * effort converting them to jiffies..46	 */47	msleep_interruptible(jiffies_to_msecs(delay));48}49 50 51/* FIXME: The following line needs to be somewhere else... */52#define WRONG_BUS_FREQUENCY 0x0753static u8 handle_switch_change(u8 change, struct controller *ctrl)54{55	int hp_slot;56	u8 rc = 0;57	u16 temp_word;58	struct pci_func *func;59	struct event_info *taskInfo;60 61	if (!change)62		return 0;63 64	/* Switch Change */65	dbg("cpqsbd:  Switch interrupt received.\n");66 67	for (hp_slot = 0; hp_slot < 6; hp_slot++) {68		if (change & (0x1L << hp_slot)) {69			/*70			 * this one changed.71			 */72			func = cpqhp_slot_find(ctrl->bus,73				(hp_slot + ctrl->slot_device_offset), 0);74 75			/* this is the structure that tells the worker thread76			 * what to do77			 */78			taskInfo = &(ctrl->event_queue[ctrl->next_event]);79			ctrl->next_event = (ctrl->next_event + 1) % 10;80			taskInfo->hp_slot = hp_slot;81 82			rc++;83 84			temp_word = ctrl->ctrl_int_comp >> 16;85			func->presence_save = (temp_word >> hp_slot) & 0x01;86			func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;87 88			if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {89				/*90				 * Switch opened91				 */92 93				func->switch_save = 0;94 95				taskInfo->event_type = INT_SWITCH_OPEN;96			} else {97				/*98				 * Switch closed99				 */100 101				func->switch_save = 0x10;102 103				taskInfo->event_type = INT_SWITCH_CLOSE;104			}105		}106	}107 108	return rc;109}110 111/**112 * cpqhp_find_slot - find the struct slot of given device113 * @ctrl: scan lots of this controller114 * @device: the device id to find115 */116static struct slot *cpqhp_find_slot(struct controller *ctrl, u8 device)117{118	struct slot *slot = ctrl->slot;119 120	while (slot && (slot->device != device))121		slot = slot->next;122 123	return slot;124}125 126 127static u8 handle_presence_change(u16 change, struct controller *ctrl)128{129	int hp_slot;130	u8 rc = 0;131	u8 temp_byte;132	u16 temp_word;133	struct pci_func *func;134	struct event_info *taskInfo;135	struct slot *p_slot;136 137	if (!change)138		return 0;139 140	/*141	 * Presence Change142	 */143	dbg("cpqsbd:  Presence/Notify input change.\n");144	dbg("         Changed bits are 0x%4.4x\n", change);145 146	for (hp_slot = 0; hp_slot < 6; hp_slot++) {147		if (change & (0x0101 << hp_slot)) {148			/*149			 * this one changed.150			 */151			func = cpqhp_slot_find(ctrl->bus,152				(hp_slot + ctrl->slot_device_offset), 0);153 154			taskInfo = &(ctrl->event_queue[ctrl->next_event]);155			ctrl->next_event = (ctrl->next_event + 1) % 10;156			taskInfo->hp_slot = hp_slot;157 158			rc++;159 160			p_slot = cpqhp_find_slot(ctrl, hp_slot + (readb(ctrl->hpc_reg + SLOT_MASK) >> 4));161			if (!p_slot)162				return 0;163 164			/* If the switch closed, must be a button165			 * If not in button mode, nevermind166			 */167			if (func->switch_save && (ctrl->push_button == 1)) {168				temp_word = ctrl->ctrl_int_comp >> 16;169				temp_byte = (temp_word >> hp_slot) & 0x01;170				temp_byte |= (temp_word >> (hp_slot + 7)) & 0x02;171 172				if (temp_byte != func->presence_save) {173					/*174					 * button Pressed (doesn't do anything)175					 */176					dbg("hp_slot %d button pressed\n", hp_slot);177					taskInfo->event_type = INT_BUTTON_PRESS;178				} else {179					/*180					 * button Released - TAKE ACTION!!!!181					 */182					dbg("hp_slot %d button released\n", hp_slot);183					taskInfo->event_type = INT_BUTTON_RELEASE;184 185					/* Cancel if we are still blinking */186					if ((p_slot->state == BLINKINGON_STATE)187					    || (p_slot->state == BLINKINGOFF_STATE)) {188						taskInfo->event_type = INT_BUTTON_CANCEL;189						dbg("hp_slot %d button cancel\n", hp_slot);190					} else if ((p_slot->state == POWERON_STATE)191						   || (p_slot->state == POWEROFF_STATE)) {192						/* info(msg_button_ignore, p_slot->number); */193						taskInfo->event_type = INT_BUTTON_IGNORE;194						dbg("hp_slot %d button ignore\n", hp_slot);195					}196				}197			} else {198				/* Switch is open, assume a presence change199				 * Save the presence state200				 */201				temp_word = ctrl->ctrl_int_comp >> 16;202				func->presence_save = (temp_word >> hp_slot) & 0x01;203				func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;204 205				if ((!(ctrl->ctrl_int_comp & (0x010000 << hp_slot))) ||206				    (!(ctrl->ctrl_int_comp & (0x01000000 << hp_slot)))) {207					/* Present */208					taskInfo->event_type = INT_PRESENCE_ON;209				} else {210					/* Not Present */211					taskInfo->event_type = INT_PRESENCE_OFF;212				}213			}214		}215	}216 217	return rc;218}219 220 221static u8 handle_power_fault(u8 change, struct controller *ctrl)222{223	int hp_slot;224	u8 rc = 0;225	struct pci_func *func;226	struct event_info *taskInfo;227 228	if (!change)229		return 0;230 231	/*232	 * power fault233	 */234 235	info("power fault interrupt\n");236 237	for (hp_slot = 0; hp_slot < 6; hp_slot++) {238		if (change & (0x01 << hp_slot)) {239			/*240			 * this one changed.241			 */242			func = cpqhp_slot_find(ctrl->bus,243				(hp_slot + ctrl->slot_device_offset), 0);244 245			taskInfo = &(ctrl->event_queue[ctrl->next_event]);246			ctrl->next_event = (ctrl->next_event + 1) % 10;247			taskInfo->hp_slot = hp_slot;248 249			rc++;250 251			if (ctrl->ctrl_int_comp & (0x00000100 << hp_slot)) {252				/*253				 * power fault Cleared254				 */255				func->status = 0x00;256 257				taskInfo->event_type = INT_POWER_FAULT_CLEAR;258			} else {259				/*260				 * power fault261				 */262				taskInfo->event_type = INT_POWER_FAULT;263 264				if (ctrl->rev < 4) {265					amber_LED_on(ctrl, hp_slot);266					green_LED_off(ctrl, hp_slot);267					set_SOGO(ctrl);268 269					/* this is a fatal condition, we want270					 * to crash the machine to protect from271					 * data corruption. simulated_NMI272					 * shouldn't ever return */273					/* FIXME274					simulated_NMI(hp_slot, ctrl); */275 276					/* The following code causes a software277					 * crash just in case simulated_NMI did278					 * return */279					/*FIXME280					panic(msg_power_fault); */281				} else {282					/* set power fault status for this board */283					func->status = 0xFF;284					info("power fault bit %x set\n", hp_slot);285				}286			}287		}288	}289 290	return rc;291}292 293 294/**295 * sort_by_size - sort nodes on the list by their length, smallest first.296 * @head: list to sort297 */298static int sort_by_size(struct pci_resource **head)299{300	struct pci_resource *current_res;301	struct pci_resource *next_res;302	int out_of_order = 1;303 304	if (!(*head))305		return 1;306 307	if (!((*head)->next))308		return 0;309 310	while (out_of_order) {311		out_of_order = 0;312 313		/* Special case for swapping list head */314		if (((*head)->next) &&315		    ((*head)->length > (*head)->next->length)) {316			out_of_order++;317			current_res = *head;318			*head = (*head)->next;319			current_res->next = (*head)->next;320			(*head)->next = current_res;321		}322 323		current_res = *head;324 325		while (current_res->next && current_res->next->next) {326			if (current_res->next->length > current_res->next->next->length) {327				out_of_order++;328				next_res = current_res->next;329				current_res->next = current_res->next->next;330				current_res = current_res->next;331				next_res->next = current_res->next;332				current_res->next = next_res;333			} else334				current_res = current_res->next;335		}336	}  /* End of out_of_order loop */337 338	return 0;339}340 341 342/**343 * sort_by_max_size - sort nodes on the list by their length, largest first.344 * @head: list to sort345 */346static int sort_by_max_size(struct pci_resource **head)347{348	struct pci_resource *current_res;349	struct pci_resource *next_res;350	int out_of_order = 1;351 352	if (!(*head))353		return 1;354 355	if (!((*head)->next))356		return 0;357 358	while (out_of_order) {359		out_of_order = 0;360 361		/* Special case for swapping list head */362		if (((*head)->next) &&363		    ((*head)->length < (*head)->next->length)) {364			out_of_order++;365			current_res = *head;366			*head = (*head)->next;367			current_res->next = (*head)->next;368			(*head)->next = current_res;369		}370 371		current_res = *head;372 373		while (current_res->next && current_res->next->next) {374			if (current_res->next->length < current_res->next->next->length) {375				out_of_order++;376				next_res = current_res->next;377				current_res->next = current_res->next->next;378				current_res = current_res->next;379				next_res->next = current_res->next;380				current_res->next = next_res;381			} else382				current_res = current_res->next;383		}384	}  /* End of out_of_order loop */385 386	return 0;387}388 389 390/**391 * do_pre_bridge_resource_split - find node of resources that are unused392 * @head: new list head393 * @orig_head: original list head394 * @alignment: max node size (?)395 */396static struct pci_resource *do_pre_bridge_resource_split(struct pci_resource **head,397				struct pci_resource **orig_head, u32 alignment)398{399	struct pci_resource *prevnode = NULL;400	struct pci_resource *node;401	struct pci_resource *split_node;402	u32 rc;403	u32 temp_dword;404	dbg("do_pre_bridge_resource_split\n");405 406	if (!(*head) || !(*orig_head))407		return NULL;408 409	rc = cpqhp_resource_sort_and_combine(head);410 411	if (rc)412		return NULL;413 414	if ((*head)->base != (*orig_head)->base)415		return NULL;416 417	if ((*head)->length == (*orig_head)->length)418		return NULL;419 420 421	/* If we got here, there the bridge requires some of the resource, but422	 * we may be able to split some off of the front423	 */424 425	node = *head;426 427	if (node->length & (alignment - 1)) {428		/* this one isn't an aligned length, so we'll make a new entry429		 * and split it up.430		 */431		split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);432 433		if (!split_node)434			return NULL;435 436		temp_dword = (node->length | (alignment-1)) + 1 - alignment;437 438		split_node->base = node->base;439		split_node->length = temp_dword;440 441		node->length -= temp_dword;442		node->base += split_node->length;443 444		/* Put it in the list */445		*head = split_node;446		split_node->next = node;447	}448 449	if (node->length < alignment)450		return NULL;451 452	/* Now unlink it */453	if (*head == node) {454		*head = node->next;455	} else {456		prevnode = *head;457		while (prevnode->next != node)458			prevnode = prevnode->next;459 460		prevnode->next = node->next;461	}462	node->next = NULL;463 464	return node;465}466 467 468/**469 * do_bridge_resource_split - find one node of resources that aren't in use470 * @head: list head471 * @alignment: max node size (?)472 */473static struct pci_resource *do_bridge_resource_split(struct pci_resource **head, u32 alignment)474{475	struct pci_resource *prevnode = NULL;476	struct pci_resource *node;477	u32 rc;478	u32 temp_dword;479 480	rc = cpqhp_resource_sort_and_combine(head);481 482	if (rc)483		return NULL;484 485	node = *head;486 487	while (node->next) {488		prevnode = node;489		node = node->next;490		kfree(prevnode);491	}492 493	if (node->length < alignment)494		goto error;495 496	if (node->base & (alignment - 1)) {497		/* Short circuit if adjusted size is too small */498		temp_dword = (node->base | (alignment-1)) + 1;499		if ((node->length - (temp_dword - node->base)) < alignment)500			goto error;501 502		node->length -= (temp_dword - node->base);503		node->base = temp_dword;504	}505 506	if (node->length & (alignment - 1))507		/* There's stuff in use after this node */508		goto error;509 510	return node;511error:512	kfree(node);513	return NULL;514}515 516 517/**518 * get_io_resource - find first node of given size not in ISA aliasing window.519 * @head: list to search520 * @size: size of node to find, must be a power of two.521 *522 * Description: This function sorts the resource list by size and then523 * returns the first node of "size" length that is not in the ISA aliasing524 * window.  If it finds a node larger than "size" it will split it up.525 */526static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size)527{528	struct pci_resource *prevnode;529	struct pci_resource *node;530	struct pci_resource *split_node;531	u32 temp_dword;532 533	if (!(*head))534		return NULL;535 536	if (cpqhp_resource_sort_and_combine(head))537		return NULL;538 539	if (sort_by_size(head))540		return NULL;541 542	for (node = *head; node; node = node->next) {543		if (node->length < size)544			continue;545 546		if (node->base & (size - 1)) {547			/* this one isn't base aligned properly548			 * so we'll make a new entry and split it up549			 */550			temp_dword = (node->base | (size-1)) + 1;551 552			/* Short circuit if adjusted size is too small */553			if ((node->length - (temp_dword - node->base)) < size)554				continue;555 556			split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);557 558			if (!split_node)559				return NULL;560 561			split_node->base = node->base;562			split_node->length = temp_dword - node->base;563			node->base = temp_dword;564			node->length -= split_node->length;565 566			/* Put it in the list */567			split_node->next = node->next;568			node->next = split_node;569		} /* End of non-aligned base */570 571		/* Don't need to check if too small since we already did */572		if (node->length > size) {573			/* this one is longer than we need574			 * so we'll make a new entry and split it up575			 */576			split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);577 578			if (!split_node)579				return NULL;580 581			split_node->base = node->base + size;582			split_node->length = node->length - size;583			node->length = size;584 585			/* Put it in the list */586			split_node->next = node->next;587			node->next = split_node;588		}  /* End of too big on top end */589 590		/* For IO make sure it's not in the ISA aliasing space */591		if (node->base & 0x300L)592			continue;593 594		/* If we got here, then it is the right size595		 * Now take it out of the list and break596		 */597		if (*head == node) {598			*head = node->next;599		} else {600			prevnode = *head;601			while (prevnode->next != node)602				prevnode = prevnode->next;603 604			prevnode->next = node->next;605		}606		node->next = NULL;607		break;608	}609 610	return node;611}612 613 614/**615 * get_max_resource - get largest node which has at least the given size.616 * @head: the list to search the node in617 * @size: the minimum size of the node to find618 *619 * Description: Gets the largest node that is at least "size" big from the620 * list pointed to by head.  It aligns the node on top and bottom621 * to "size" alignment before returning it.622 */623static struct pci_resource *get_max_resource(struct pci_resource **head, u32 size)624{625	struct pci_resource *max;626	struct pci_resource *temp;627	struct pci_resource *split_node;628	u32 temp_dword;629 630	if (cpqhp_resource_sort_and_combine(head))631		return NULL;632 633	if (sort_by_max_size(head))634		return NULL;635 636	for (max = *head; max; max = max->next) {637		/* If not big enough we could probably just bail,638		 * instead we'll continue to the next.639		 */640		if (max->length < size)641			continue;642 643		if (max->base & (size - 1)) {644			/* this one isn't base aligned properly645			 * so we'll make a new entry and split it up646			 */647			temp_dword = (max->base | (size-1)) + 1;648 649			/* Short circuit if adjusted size is too small */650			if ((max->length - (temp_dword - max->base)) < size)651				continue;652 653			split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);654 655			if (!split_node)656				return NULL;657 658			split_node->base = max->base;659			split_node->length = temp_dword - max->base;660			max->base = temp_dword;661			max->length -= split_node->length;662 663			split_node->next = max->next;664			max->next = split_node;665		}666 667		if ((max->base + max->length) & (size - 1)) {668			/* this one isn't end aligned properly at the top669			 * so we'll make a new entry and split it up670			 */671			split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);672 673			if (!split_node)674				return NULL;675			temp_dword = ((max->base + max->length) & ~(size - 1));676			split_node->base = temp_dword;677			split_node->length = max->length + max->base678					     - split_node->base;679			max->length -= split_node->length;680 681			split_node->next = max->next;682			max->next = split_node;683		}684 685		/* Make sure it didn't shrink too much when we aligned it */686		if (max->length < size)687			continue;688 689		/* Now take it out of the list */690		temp = *head;691		if (temp == max) {692			*head = max->next;693		} else {694			while (temp && temp->next != max)695				temp = temp->next;696 697			if (temp)698				temp->next = max->next;699		}700 701		max->next = NULL;702		break;703	}704 705	return max;706}707 708 709/**710 * get_resource - find resource of given size and split up larger ones.711 * @head: the list to search for resources712 * @size: the size limit to use713 *714 * Description: This function sorts the resource list by size and then715 * returns the first node of "size" length.  If it finds a node716 * larger than "size" it will split it up.717 *718 * size must be a power of two.719 */720static struct pci_resource *get_resource(struct pci_resource **head, u32 size)721{722	struct pci_resource *prevnode;723	struct pci_resource *node;724	struct pci_resource *split_node;725	u32 temp_dword;726 727	if (cpqhp_resource_sort_and_combine(head))728		return NULL;729 730	if (sort_by_size(head))731		return NULL;732 733	for (node = *head; node; node = node->next) {734		dbg("%s: req_size =%x node=%p, base=%x, length=%x\n",735		    __func__, size, node, node->base, node->length);736		if (node->length < size)737			continue;738 739		if (node->base & (size - 1)) {740			dbg("%s: not aligned\n", __func__);741			/* this one isn't base aligned properly742			 * so we'll make a new entry and split it up743			 */744			temp_dword = (node->base | (size-1)) + 1;745 746			/* Short circuit if adjusted size is too small */747			if ((node->length - (temp_dword - node->base)) < size)748				continue;749 750			split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);751 752			if (!split_node)753				return NULL;754 755			split_node->base = node->base;756			split_node->length = temp_dword - node->base;757			node->base = temp_dword;758			node->length -= split_node->length;759 760			split_node->next = node->next;761			node->next = split_node;762		} /* End of non-aligned base */763 764		/* Don't need to check if too small since we already did */765		if (node->length > size) {766			dbg("%s: too big\n", __func__);767			/* this one is longer than we need768			 * so we'll make a new entry and split it up769			 */770			split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);771 772			if (!split_node)773				return NULL;774 775			split_node->base = node->base + size;776			split_node->length = node->length - size;777			node->length = size;778 779			/* Put it in the list */780			split_node->next = node->next;781			node->next = split_node;782		}  /* End of too big on top end */783 784		dbg("%s: got one!!!\n", __func__);785		/* If we got here, then it is the right size786		 * Now take it out of the list */787		if (*head == node) {788			*head = node->next;789		} else {790			prevnode = *head;791			while (prevnode->next != node)792				prevnode = prevnode->next;793 794			prevnode->next = node->next;795		}796		node->next = NULL;797		break;798	}799	return node;800}801 802 803/**804 * cpqhp_resource_sort_and_combine - sort nodes by base addresses and clean up805 * @head: the list to sort and clean up806 *807 * Description: Sorts all of the nodes in the list in ascending order by808 * their base addresses.  Also does garbage collection by809 * combining adjacent nodes.810 *811 * Returns %0 if success.812 */813int cpqhp_resource_sort_and_combine(struct pci_resource **head)814{815	struct pci_resource *node1;816	struct pci_resource *node2;817	int out_of_order = 1;818 819	dbg("%s: head = %p, *head = %p\n", __func__, head, *head);820 821	if (!(*head))822		return 1;823 824	dbg("*head->next = %p\n", (*head)->next);825 826	if (!(*head)->next)827		return 0;	/* only one item on the list, already sorted! */828 829	dbg("*head->base = 0x%x\n", (*head)->base);830	dbg("*head->next->base = 0x%x\n", (*head)->next->base);831	while (out_of_order) {832		out_of_order = 0;833 834		/* Special case for swapping list head */835		if (((*head)->next) &&836		    ((*head)->base > (*head)->next->base)) {837			node1 = *head;838			(*head) = (*head)->next;839			node1->next = (*head)->next;840			(*head)->next = node1;841			out_of_order++;842		}843 844		node1 = (*head);845 846		while (node1->next && node1->next->next) {847			if (node1->next->base > node1->next->next->base) {848				out_of_order++;849				node2 = node1->next;850				node1->next = node1->next->next;851				node1 = node1->next;852				node2->next = node1->next;853				node1->next = node2;854			} else855				node1 = node1->next;856		}857	}  /* End of out_of_order loop */858 859	node1 = *head;860 861	while (node1 && node1->next) {862		if ((node1->base + node1->length) == node1->next->base) {863			/* Combine */864			dbg("8..\n");865			node1->length += node1->next->length;866			node2 = node1->next;867			node1->next = node1->next->next;868			kfree(node2);869		} else870			node1 = node1->next;871	}872 873	return 0;874}875 876 877irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data)878{879	struct controller *ctrl = data;880	u8 schedule_flag = 0;881	u8 reset;882	u16 misc;883	u32 Diff;884 885 886	misc = readw(ctrl->hpc_reg + MISC);887	/*888	 * Check to see if it was our interrupt889	 */890	if (!(misc & 0x000C))891		return IRQ_NONE;892 893	if (misc & 0x0004) {894		/*895		 * Serial Output interrupt Pending896		 */897 898		/* Clear the interrupt */899		misc |= 0x0004;900		writew(misc, ctrl->hpc_reg + MISC);901 902		/* Read to clear posted writes */903		misc = readw(ctrl->hpc_reg + MISC);904 905		dbg("%s - waking up\n", __func__);906		wake_up_interruptible(&ctrl->queue);907	}908 909	if (misc & 0x0008) {910		/* General-interrupt-input interrupt Pending */911		Diff = readl(ctrl->hpc_reg + INT_INPUT_CLEAR) ^ ctrl->ctrl_int_comp;912 913		ctrl->ctrl_int_comp = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);914 915		/* Clear the interrupt */916		writel(Diff, ctrl->hpc_reg + INT_INPUT_CLEAR);917 918		/* Read it back to clear any posted writes */919		readl(ctrl->hpc_reg + INT_INPUT_CLEAR);920 921		if (!Diff)922			/* Clear all interrupts */923			writel(0xFFFFFFFF, ctrl->hpc_reg + INT_INPUT_CLEAR);924 925		schedule_flag += handle_switch_change((u8)(Diff & 0xFFL), ctrl);926		schedule_flag += handle_presence_change((u16)((Diff & 0xFFFF0000L) >> 16), ctrl);927		schedule_flag += handle_power_fault((u8)((Diff & 0xFF00L) >> 8), ctrl);928	}929 930	reset = readb(ctrl->hpc_reg + RESET_FREQ_MODE);931	if (reset & 0x40) {932		/* Bus reset has completed */933		reset &= 0xCF;934		writeb(reset, ctrl->hpc_reg + RESET_FREQ_MODE);935		reset = readb(ctrl->hpc_reg + RESET_FREQ_MODE);936		wake_up_interruptible(&ctrl->queue);937	}938 939	if (schedule_flag) {940		wake_up_process(cpqhp_event_thread);941		dbg("Waking even thread");942	}943	return IRQ_HANDLED;944}945 946 947/**948 * cpqhp_slot_create - Creates a node and adds it to the proper bus.949 * @busnumber: bus where new node is to be located950 *951 * Returns pointer to the new node or %NULL if unsuccessful.952 */953struct pci_func *cpqhp_slot_create(u8 busnumber)954{955	struct pci_func *new_slot;956	struct pci_func *next;957 958	new_slot = kzalloc(sizeof(*new_slot), GFP_KERNEL);959	if (new_slot == NULL)960		return new_slot;961 962	new_slot->next = NULL;963	new_slot->configured = 1;964 965	if (cpqhp_slot_list[busnumber] == NULL) {966		cpqhp_slot_list[busnumber] = new_slot;967	} else {968		next = cpqhp_slot_list[busnumber];969		while (next->next != NULL)970			next = next->next;971		next->next = new_slot;972	}973	return new_slot;974}975 976 977/**978 * slot_remove - Removes a node from the linked list of slots.979 * @old_slot: slot to remove980 *981 * Returns %0 if successful, !0 otherwise.982 */983static int slot_remove(struct pci_func *old_slot)984{985	struct pci_func *next;986 987	if (old_slot == NULL)988		return 1;989 990	next = cpqhp_slot_list[old_slot->bus];991	if (next == NULL)992		return 1;993 994	if (next == old_slot) {995		cpqhp_slot_list[old_slot->bus] = old_slot->next;996		cpqhp_destroy_board_resources(old_slot);997		kfree(old_slot);998		return 0;999	}1000 1001	while ((next->next != old_slot) && (next->next != NULL))1002		next = next->next;1003 1004	if (next->next == old_slot) {1005		next->next = old_slot->next;1006		cpqhp_destroy_board_resources(old_slot);1007		kfree(old_slot);1008		return 0;1009	} else1010		return 2;1011}1012 1013 1014/**1015 * bridge_slot_remove - Removes a node from the linked list of slots.1016 * @bridge: bridge to remove1017 *1018 * Returns %0 if successful, !0 otherwise.1019 */1020static int bridge_slot_remove(struct pci_func *bridge)1021{1022	u8 subordinateBus, secondaryBus;1023	u8 tempBus;1024	struct pci_func *next;1025 1026	secondaryBus = (bridge->config_space[0x06] >> 8) & 0xFF;1027	subordinateBus = (bridge->config_space[0x06] >> 16) & 0xFF;1028 1029	for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) {1030		next = cpqhp_slot_list[tempBus];1031 1032		while (!slot_remove(next))1033			next = cpqhp_slot_list[tempBus];1034	}1035 1036	next = cpqhp_slot_list[bridge->bus];1037 1038	if (next == NULL)1039		return 1;1040 1041	if (next == bridge) {1042		cpqhp_slot_list[bridge->bus] = bridge->next;1043		goto out;1044	}1045 1046	while ((next->next != bridge) && (next->next != NULL))1047		next = next->next;1048 1049	if (next->next != bridge)1050		return 2;1051	next->next = bridge->next;1052out:1053	kfree(bridge);1054	return 0;1055}1056 1057 1058/**1059 * cpqhp_slot_find - Looks for a node by bus, and device, multiple functions accessed1060 * @bus: bus to find1061 * @device: device to find1062 * @index: is %0 for first function found, %1 for the second...1063 *1064 * Returns pointer to the node if successful, %NULL otherwise.1065 */1066struct pci_func *cpqhp_slot_find(u8 bus, u8 device, u8 index)1067{1068	int found = -1;1069	struct pci_func *func;1070 1071	func = cpqhp_slot_list[bus];1072 1073	if ((func == NULL) || ((func->device == device) && (index == 0)))1074		return func;1075 1076	if (func->device == device)1077		found++;1078 1079	while (func->next != NULL) {1080		func = func->next;1081 1082		if (func->device == device)1083			found++;1084 1085		if (found == index)1086			return func;1087	}1088 1089	return NULL;1090}1091 1092 1093/* DJZ: I don't think is_bridge will work as is.1094 * FIXME */1095static int is_bridge(struct pci_func *func)1096{1097	/* Check the header type */1098	if (((func->config_space[0x03] >> 16) & 0xFF) == 0x01)1099		return 1;1100	else1101		return 0;1102}1103 1104 1105/**1106 * set_controller_speed - set the frequency and/or mode of a specific controller segment.1107 * @ctrl: controller to change frequency/mode for.1108 * @adapter_speed: the speed of the adapter we want to match.1109 * @hp_slot: the slot number where the adapter is installed.1110 *1111 * Returns %0 if we successfully change frequency and/or mode to match the1112 * adapter speed.1113 */1114static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_slot)1115{1116	struct slot *slot;1117	struct pci_bus *bus = ctrl->pci_bus;1118	u8 reg;1119	u8 slot_power = readb(ctrl->hpc_reg + SLOT_POWER);1120	u16 reg16;1121	u32 leds = readl(ctrl->hpc_reg + LED_CONTROL);1122 1123	if (bus->cur_bus_speed == adapter_speed)1124		return 0;1125 1126	/* We don't allow freq/mode changes if we find another adapter running1127	 * in another slot on this controller1128	 */1129	for (slot = ctrl->slot; slot; slot = slot->next) {1130		if (slot->device == (hp_slot + ctrl->slot_device_offset))1131			continue;1132		if (get_presence_status(ctrl, slot) == 0)1133			continue;1134		/* If another adapter is running on the same segment but at a1135		 * lower speed/mode, we allow the new adapter to function at1136		 * this rate if supported1137		 */1138		if (bus->cur_bus_speed < adapter_speed)1139			return 0;1140 1141		return 1;1142	}1143 1144	/* If the controller doesn't support freq/mode changes and the1145	 * controller is running at a higher mode, we bail1146	 */1147	if ((bus->cur_bus_speed > adapter_speed) && (!ctrl->pcix_speed_capability))1148		return 1;1149 1150	/* But we allow the adapter to run at a lower rate if possible */1151	if ((bus->cur_bus_speed < adapter_speed) && (!ctrl->pcix_speed_capability))1152		return 0;1153 1154	/* We try to set the max speed supported by both the adapter and1155	 * controller1156	 */1157	if (bus->max_bus_speed < adapter_speed) {1158		if (bus->cur_bus_speed == bus->max_bus_speed)1159			return 0;1160		adapter_speed = bus->max_bus_speed;1161	}1162 1163	writel(0x0L, ctrl->hpc_reg + LED_CONTROL);1164	writeb(0x00, ctrl->hpc_reg + SLOT_ENABLE);1165 1166	set_SOGO(ctrl);1167	wait_for_ctrl_irq(ctrl);1168 1169	if (adapter_speed != PCI_SPEED_133MHz_PCIX)1170		reg = 0xF5;1171	else1172		reg = 0xF4;1173	pci_write_config_byte(ctrl->pci_dev, 0x41, reg);1174 1175	reg16 = readw(ctrl->hpc_reg + NEXT_CURR_FREQ);1176	reg16 &= ~0x000F;1177	switch (adapter_speed) {1178		case(PCI_SPEED_133MHz_PCIX):1179			reg = 0x75;1180			reg16 |= 0xB;1181			break;1182		case(PCI_SPEED_100MHz_PCIX):1183			reg = 0x74;1184			reg16 |= 0xA;1185			break;1186		case(PCI_SPEED_66MHz_PCIX):1187			reg = 0x73;1188			reg16 |= 0x9;1189			break;1190		case(PCI_SPEED_66MHz):1191			reg = 0x73;1192			reg16 |= 0x1;1193			break;1194		default: /* 33MHz PCI 2.2 */1195			reg = 0x71;1196			break;1197 1198	}1199	reg16 |= 0xB << 12;1200	writew(reg16, ctrl->hpc_reg + NEXT_CURR_FREQ);1201 1202	mdelay(5);1203 1204	/* Re-enable interrupts */1205	writel(0, ctrl->hpc_reg + INT_MASK);1206 1207	pci_write_config_byte(ctrl->pci_dev, 0x41, reg);1208 1209	/* Restart state machine */1210	reg = ~0xF;1211	pci_read_config_byte(ctrl->pci_dev, 0x43, &reg);1212	pci_write_config_byte(ctrl->pci_dev, 0x43, reg);1213 1214	/* Only if mode change...*/1215	if (((bus->cur_bus_speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) ||1216		((bus->cur_bus_speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz)))1217			set_SOGO(ctrl);1218 1219	wait_for_ctrl_irq(ctrl);1220	mdelay(1100);1221 1222	/* Restore LED/Slot state */1223	writel(leds, ctrl->hpc_reg + LED_CONTROL);1224	writeb(slot_power, ctrl->hpc_reg + SLOT_ENABLE);1225 1226	set_SOGO(ctrl);1227	wait_for_ctrl_irq(ctrl);1228 1229	bus->cur_bus_speed = adapter_speed;1230	slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);1231 1232	info("Successfully changed frequency/mode for adapter in slot %d\n",1233			slot->number);1234	return 0;1235}1236 1237/* the following routines constitute the bulk of the1238 * hotplug controller logic1239 */1240 1241 1242/**1243 * board_replaced - Called after a board has been replaced in the system.1244 * @func: PCI device/function information1245 * @ctrl: hotplug controller1246 *1247 * This is only used if we don't have resources for hot add.1248 * Turns power on for the board.1249 * Checks to see if board is the same.1250 * If board is same, reconfigures it.1251 * If board isn't same, turns it back off.1252 */1253static u32 board_replaced(struct pci_func *func, struct controller *ctrl)1254{1255	struct pci_bus *bus = ctrl->pci_bus;1256	u8 hp_slot;1257	u8 temp_byte;1258	u8 adapter_speed;1259	u32 rc = 0;1260 1261	hp_slot = func->device - ctrl->slot_device_offset;1262 1263	/*1264	 * The switch is open.1265	 */1266	if (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot))1267		rc = INTERLOCK_OPEN;1268	/*1269	 * The board is already on1270	 */1271	else if (is_slot_enabled(ctrl, hp_slot))1272		rc = CARD_FUNCTIONING;1273	else {1274		mutex_lock(&ctrl->crit_sect);1275 1276		/* turn on board without attaching to the bus */1277		enable_slot_power(ctrl, hp_slot);1278 1279		set_SOGO(ctrl);1280 1281		/* Wait for SOBS to be unset */1282		wait_for_ctrl_irq(ctrl);1283 1284		/* Change bits in slot power register to force another shift out1285		 * NOTE: this is to work around the timer bug */1286		temp_byte = readb(ctrl->hpc_reg + SLOT_POWER);1287		writeb(0x00, ctrl->hpc_reg + SLOT_POWER);1288		writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER);1289 1290		set_SOGO(ctrl);1291 1292		/* Wait for SOBS to be unset */1293		wait_for_ctrl_irq(ctrl);1294 1295		adapter_speed = get_adapter_speed(ctrl, hp_slot);1296		if (bus->cur_bus_speed != adapter_speed)1297			if (set_controller_speed(ctrl, adapter_speed, hp_slot))1298				rc = WRONG_BUS_FREQUENCY;1299 1300		/* turn off board without attaching to the bus */1301		disable_slot_power(ctrl, hp_slot);1302 1303		set_SOGO(ctrl);1304 1305		/* Wait for SOBS to be unset */1306		wait_for_ctrl_irq(ctrl);1307 1308		mutex_unlock(&ctrl->crit_sect);1309 1310		if (rc)1311			return rc;1312 1313		mutex_lock(&ctrl->crit_sect);1314 1315		slot_enable(ctrl, hp_slot);1316		green_LED_blink(ctrl, hp_slot);1317 1318		amber_LED_off(ctrl, hp_slot);1319 1320		set_SOGO(ctrl);1321 1322		/* Wait for SOBS to be unset */1323		wait_for_ctrl_irq(ctrl);1324 1325		mutex_unlock(&ctrl->crit_sect);1326 1327		/* Wait for ~1 second because of hot plug spec */1328		long_delay(1*HZ);1329 1330		/* Check for a power fault */1331		if (func->status == 0xFF) {1332			/* power fault occurred, but it was benign */1333			rc = POWER_FAILURE;1334			func->status = 0;1335		} else1336			rc = cpqhp_valid_replace(ctrl, func);1337 1338		if (!rc) {1339			/* It must be the same board */1340 1341			rc = cpqhp_configure_board(ctrl, func);1342 1343			/* If configuration fails, turn it off1344			 * Get slot won't work for devices behind1345			 * bridges, but in this case it will always be1346			 * called for the "base" bus/dev/func of an1347			 * adapter.1348			 */1349 1350			mutex_lock(&ctrl->crit_sect);1351 1352			amber_LED_on(ctrl, hp_slot);1353			green_LED_off(ctrl, hp_slot);1354			slot_disable(ctrl, hp_slot);1355 1356			set_SOGO(ctrl);1357 1358			/* Wait for SOBS to be unset */1359			wait_for_ctrl_irq(ctrl);1360 1361			mutex_unlock(&ctrl->crit_sect);1362 1363			if (rc)1364				return rc;1365			else1366				return 1;1367 1368		} else {1369			/* Something is wrong1370 1371			 * Get slot won't work for devices behind bridges, but1372			 * in this case it will always be called for the "base"1373			 * bus/dev/func of an adapter.1374			 */1375 1376			mutex_lock(&ctrl->crit_sect);1377 1378			amber_LED_on(ctrl, hp_slot);1379			green_LED_off(ctrl, hp_slot);1380			slot_disable(ctrl, hp_slot);1381 1382			set_SOGO(ctrl);1383 1384			/* Wait for SOBS to be unset */1385			wait_for_ctrl_irq(ctrl);1386 1387			mutex_unlock(&ctrl->crit_sect);1388		}1389 1390	}1391	return rc;1392 1393}1394 1395 1396/**1397 * board_added - Called after a board has been added to the system.1398 * @func: PCI device/function info1399 * @ctrl: hotplug controller1400 *1401 * Turns power on for the board.1402 * Configures board.1403 */1404static u32 board_added(struct pci_func *func, struct controller *ctrl)1405{1406	u8 hp_slot;1407	u8 temp_byte;1408	u8 adapter_speed;1409	int index;1410	u32 temp_register = 0xFFFFFFFF;1411	u32 rc = 0;1412	struct pci_func *new_slot = NULL;1413	struct pci_bus *bus = ctrl->pci_bus;1414	struct resource_lists res_lists;1415 1416	hp_slot = func->device - ctrl->slot_device_offset;1417	dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n",1418	    __func__, func->device, ctrl->slot_device_offset, hp_slot);1419 1420	mutex_lock(&ctrl->crit_sect);1421 1422	/* turn on board without attaching to the bus */1423	enable_slot_power(ctrl, hp_slot);1424 1425	set_SOGO(ctrl);1426 1427	/* Wait for SOBS to be unset */1428	wait_for_ctrl_irq(ctrl);1429 1430	/* Change bits in slot power register to force another shift out1431	 * NOTE: this is to work around the timer bug1432	 */1433	temp_byte = readb(ctrl->hpc_reg + SLOT_POWER);1434	writeb(0x00, ctrl->hpc_reg + SLOT_POWER);1435	writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER);1436 1437	set_SOGO(ctrl);1438 1439	/* Wait for SOBS to be unset */1440	wait_for_ctrl_irq(ctrl);1441 1442	adapter_speed = get_adapter_speed(ctrl, hp_slot);1443	if (bus->cur_bus_speed != adapter_speed)1444		if (set_controller_speed(ctrl, adapter_speed, hp_slot))1445			rc = WRONG_BUS_FREQUENCY;1446 1447	/* turn off board without attaching to the bus */1448	disable_slot_power(ctrl, hp_slot);1449 1450	set_SOGO(ctrl);1451 1452	/* Wait for SOBS to be unset */1453	wait_for_ctrl_irq(ctrl);1454 1455	mutex_unlock(&ctrl->crit_sect);1456 1457	if (rc)1458		return rc;1459 1460	cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);1461 1462	/* turn on board and blink green LED */1463 1464	dbg("%s: before down\n", __func__);1465	mutex_lock(&ctrl->crit_sect);1466	dbg("%s: after down\n", __func__);1467 1468	dbg("%s: before slot_enable\n", __func__);1469	slot_enable(ctrl, hp_slot);1470 1471	dbg("%s: before green_LED_blink\n", __func__);1472	green_LED_blink(ctrl, hp_slot);1473 1474	dbg("%s: before amber_LED_blink\n", __func__);1475	amber_LED_off(ctrl, hp_slot);1476 1477	dbg("%s: before set_SOGO\n", __func__);1478	set_SOGO(ctrl);1479 1480	/* Wait for SOBS to be unset */1481	dbg("%s: before wait_for_ctrl_irq\n", __func__);1482	wait_for_ctrl_irq(ctrl);1483	dbg("%s: after wait_for_ctrl_irq\n", __func__);1484 1485	dbg("%s: before up\n", __func__);1486	mutex_unlock(&ctrl->crit_sect);1487	dbg("%s: after up\n", __func__);1488 1489	/* Wait for ~1 second because of hot plug spec */1490	dbg("%s: before long_delay\n", __func__);1491	long_delay(1*HZ);1492	dbg("%s: after long_delay\n", __func__);1493 1494	dbg("%s: func status = %x\n", __func__, func->status);1495	/* Check for a power fault */1496	if (func->status == 0xFF) {1497		/* power fault occurred, but it was benign */1498		temp_register = 0xFFFFFFFF;1499		dbg("%s: temp register set to %x by power fault\n", __func__, temp_register);1500		rc = POWER_FAILURE;1501		func->status = 0;1502	} else {1503		/* Get vendor/device ID u32 */1504		ctrl->pci_bus->number = func->bus;1505		rc = pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(func->device, func->function), PCI_VENDOR_ID, &temp_register);1506		dbg("%s: pci_read_config_dword returns %d\n", __func__, rc);1507		dbg("%s: temp_register is %x\n", __func__, temp_register);1508 1509		if (rc != 0) {1510			/* Something's wrong here */1511			temp_register = 0xFFFFFFFF;1512			dbg("%s: temp register set to %x by error\n", __func__, temp_register);1513		}1514		/* Preset return code.  It will be changed later if things go okay. */1515		rc = NO_ADAPTER_PRESENT;1516	}1517 1518	/* All F's is an empty slot or an invalid board */1519	if (temp_register != 0xFFFFFFFF) {1520		res_lists.io_head = ctrl->io_head;1521		res_lists.mem_head = ctrl->mem_head;1522		res_lists.p_mem_head = ctrl->p_mem_head;1523		res_lists.bus_head = ctrl->bus_head;1524		res_lists.irqs = NULL;1525 1526		rc = configure_new_device(ctrl, func, 0, &res_lists);1527 1528		dbg("%s: back from configure_new_device\n", __func__);1529		ctrl->io_head = res_lists.io_head;1530		ctrl->mem_head = res_lists.mem_head;1531		ctrl->p_mem_head = res_lists.p_mem_head;1532		ctrl->bus_head = res_lists.bus_head;1533 1534		cpqhp_resource_sort_and_combine(&(ctrl->mem_head));1535		cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));1536		cpqhp_resource_sort_and_combine(&(ctrl->io_head));1537		cpqhp_resource_sort_and_combine(&(ctrl->bus_head));1538 1539		if (rc) {1540			mutex_lock(&ctrl->crit_sect);1541 1542			amber_LED_on(ctrl, hp_slot);1543			green_LED_off(ctrl, hp_slot);1544			slot_disable(ctrl, hp_slot);1545 1546			set_SOGO(ctrl);1547 1548			/* Wait for SOBS to be unset */1549			wait_for_ctrl_irq(ctrl);1550 1551			mutex_unlock(&ctrl->crit_sect);1552			return rc;1553		} else {1554			cpqhp_save_slot_config(ctrl, func);1555		}1556 1557 1558		func->status = 0;1559		func->switch_save = 0x10;1560		func->is_a_board = 0x01;1561 1562		/* next, we will instantiate the linux pci_dev structures (with1563		 * appropriate driver notification, if already present) */1564		dbg("%s: configure linux pci_dev structure\n", __func__);1565		index = 0;1566		do {1567			new_slot = cpqhp_slot_find(ctrl->bus, func->device, index++);1568			if (new_slot && !new_slot->pci_dev)1569				cpqhp_configure_device(ctrl, new_slot);1570		} while (new_slot);1571 1572		mutex_lock(&ctrl->crit_sect);1573 1574		green_LED_on(ctrl, hp_slot);1575 1576		set_SOGO(ctrl);1577 1578		/* Wait for SOBS to be unset */1579		wait_for_ctrl_irq(ctrl);1580 1581		mutex_unlock(&ctrl->crit_sect);1582	} else {1583		mutex_lock(&ctrl->crit_sect);1584 1585		amber_LED_on(ctrl, hp_slot);1586		green_LED_off(ctrl, hp_slot);1587		slot_disable(ctrl, hp_slot);1588 1589		set_SOGO(ctrl);1590 1591		/* Wait for SOBS to be unset */1592		wait_for_ctrl_irq(ctrl);1593 1594		mutex_unlock(&ctrl->crit_sect);1595 1596		return rc;1597	}1598	return 0;1599}1600 1601 1602/**1603 * remove_board - Turns off slot and LEDs1604 * @func: PCI device/function info1605 * @replace_flag: whether replacing or adding a new device1606 * @ctrl: target controller1607 */1608static u32 remove_board(struct pci_func *func, u32 replace_flag, struct controller *ctrl)1609{1610	int index;1611	u8 skip = 0;1612	u8 device;1613	u8 hp_slot;1614	u8 temp_byte;1615	struct resource_lists res_lists;1616	struct pci_func *temp_func;1617 1618	if (cpqhp_unconfigure_device(func))1619		return 1;1620 1621	device = func->device;1622 1623	hp_slot = func->device - ctrl->slot_device_offset;1624	dbg("In %s, hp_slot = %d\n", __func__, hp_slot);1625 1626	/* When we get here, it is safe to change base address registers.1627	 * We will attempt to save the base address register lengths */1628	if (replace_flag || !ctrl->add_support)1629		cpqhp_save_base_addr_length(ctrl, func);1630	else if (!func->bus_head && !func->mem_head &&1631		 !func->p_mem_head && !func->io_head) {1632		/* Here we check to see if we've saved any of the board's1633		 * resources already.  If so, we'll skip the attempt to1634		 * determine what's being used. */1635		index = 0;1636		temp_func = cpqhp_slot_find(func->bus, func->device, index++);1637		while (temp_func) {1638			if (temp_func->bus_head || temp_func->mem_head1639			    || temp_func->p_mem_head || temp_func->io_head) {1640				skip = 1;1641				break;1642			}1643			temp_func = cpqhp_slot_find(temp_func->bus, temp_func->device, index++);1644		}1645 1646		if (!skip)1647			cpqhp_save_used_resources(ctrl, func);1648	}1649	/* Change status to shutdown */1650	if (func->is_a_board)1651		func->status = 0x01;1652	func->configured = 0;1653 1654	mutex_lock(&ctrl->crit_sect);1655 1656	green_LED_off(ctrl, hp_slot);1657	slot_disable(ctrl, hp_slot);1658 1659	set_SOGO(ctrl);1660 1661	/* turn off SERR for slot */1662	temp_byte = readb(ctrl->hpc_reg + SLOT_SERR);1663	temp_byte &= ~(0x01 << hp_slot);1664	writeb(temp_byte, ctrl->hpc_reg + SLOT_SERR);1665 1666	/* Wait for SOBS to be unset */1667	wait_for_ctrl_irq(ctrl);1668 1669	mutex_unlock(&ctrl->crit_sect);1670 1671	if (!replace_flag && ctrl->add_support) {1672		while (func) {1673			res_lists.io_head = ctrl->io_head;1674			res_lists.mem_head = ctrl->mem_head;1675			res_lists.p_mem_head = ctrl->p_mem_head;1676			res_lists.bus_head = ctrl->bus_head;1677 1678			cpqhp_return_board_resources(func, &res_lists);1679 1680			ctrl->io_head = res_lists.io_head;1681			ctrl->mem_head = res_lists.mem_head;1682			ctrl->p_mem_head = res_lists.p_mem_head;1683			ctrl->bus_head = res_lists.bus_head;1684 1685			cpqhp_resource_sort_and_combine(&(ctrl->mem_head));1686			cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));1687			cpqhp_resource_sort_and_combine(&(ctrl->io_head));1688			cpqhp_resource_sort_and_combine(&(ctrl->bus_head));1689 1690			if (is_bridge(func)) {1691				bridge_slot_remove(func);1692			} else1693				slot_remove(func);1694 1695			func = cpqhp_slot_find(ctrl->bus, device, 0);1696		}1697 1698		/* Setup slot structure with entry for empty slot */1699		func = cpqhp_slot_create(ctrl->bus);1700 1701		if (func == NULL)1702			return 1;1703 1704		func->bus = ctrl->bus;1705		func->device = device;1706		func->function = 0;1707		func->configured = 0;1708		func->switch_save = 0x10;1709		func->is_a_board = 0;1710		func->p_task_event = NULL;1711	}1712 1713	return 0;1714}1715 1716static void pushbutton_helper_thread(struct timer_list *t)1717{1718	pushbutton_pending = t;1719 1720	wake_up_process(cpqhp_event_thread);1721}1722 1723 1724/* this is the main worker thread */1725static int event_thread(void *data)1726{1727	struct controller *ctrl;1728 1729	while (1) {1730		dbg("!!!!event_thread sleeping\n");1731		set_current_state(TASK_INTERRUPTIBLE);1732		schedule();1733 1734		if (kthread_should_stop())1735			break;1736		/* Do stuff here */1737		if (pushbutton_pending)1738			cpqhp_pushbutton_thread(pushbutton_pending);1739		else1740			for (ctrl = cpqhp_ctrl_list; ctrl; ctrl = ctrl->next)1741				interrupt_event_handler(ctrl);1742	}1743	dbg("event_thread signals exit\n");1744	return 0;1745}1746 1747int cpqhp_event_start_thread(void)1748{1749	cpqhp_event_thread = kthread_run(event_thread, NULL, "phpd_event");1750	if (IS_ERR(cpqhp_event_thread)) {1751		err("Can't start up our event thread\n");1752		return PTR_ERR(cpqhp_event_thread);1753	}1754 1755	return 0;1756}1757 1758 1759void cpqhp_event_stop_thread(void)1760{1761	kthread_stop(cpqhp_event_thread);1762}1763 1764 1765static void interrupt_event_handler(struct controller *ctrl)1766{1767	int loop;1768	int change = 1;1769	struct pci_func *func;1770	u8 hp_slot;1771	struct slot *p_slot;1772 1773	while (change) {1774		change = 0;1775 1776		for (loop = 0; loop < 10; loop++) {1777			/* dbg("loop %d\n", loop); */1778			if (ctrl->event_queue[loop].event_type != 0) {1779				hp_slot = ctrl->event_queue[loop].hp_slot;1780 1781				func = cpqhp_slot_find(ctrl->bus, (hp_slot + ctrl->slot_device_offset), 0);1782				if (!func)1783					return;1784 1785				p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);1786				if (!p_slot)1787					return;1788 1789				dbg("hp_slot %d, func %p, p_slot %p\n",1790				    hp_slot, func, p_slot);1791 1792				if (ctrl->event_queue[loop].event_type == INT_BUTTON_PRESS) {1793					dbg("button pressed\n");1794				} else if (ctrl->event_queue[loop].event_type ==1795					   INT_BUTTON_CANCEL) {1796					dbg("button cancel\n");1797					del_timer(&p_slot->task_event);1798 1799					mutex_lock(&ctrl->crit_sect);1800 1801					if (p_slot->state == BLINKINGOFF_STATE) {1802						/* slot is on */1803						dbg("turn on green LED\n");1804						green_LED_on(ctrl, hp_slot);1805					} else if (p_slot->state == BLINKINGON_STATE) {1806						/* slot is off */1807						dbg("turn off green LED\n");1808						green_LED_off(ctrl, hp_slot);1809					}1810 1811					info(msg_button_cancel, p_slot->number);1812 1813					p_slot->state = STATIC_STATE;1814 1815					amber_LED_off(ctrl, hp_slot);1816 1817					set_SOGO(ctrl);1818 1819					/* Wait for SOBS to be unset */1820					wait_for_ctrl_irq(ctrl);1821 1822					mutex_unlock(&ctrl->crit_sect);1823				}1824				/*** button Released (No action on press...) */1825				else if (ctrl->event_queue[loop].event_type == INT_BUTTON_RELEASE) {1826					dbg("button release\n");1827 1828					if (is_slot_enabled(ctrl, hp_slot)) {1829						dbg("slot is on\n");1830						p_slot->state = BLINKINGOFF_STATE;1831						info(msg_button_off, p_slot->number);1832					} else {1833						dbg("slot is off\n");1834						p_slot->state = BLINKINGON_STATE;1835						info(msg_button_on, p_slot->number);1836					}1837					mutex_lock(&ctrl->crit_sect);1838 1839					dbg("blink green LED and turn off amber\n");1840 1841					amber_LED_off(ctrl, hp_slot);1842					green_LED_blink(ctrl, hp_slot);1843 1844					set_SOGO(ctrl);1845 1846					/* Wait for SOBS to be unset */1847					wait_for_ctrl_irq(ctrl);1848 1849					mutex_unlock(&ctrl->crit_sect);1850					timer_setup(&p_slot->task_event,1851						    pushbutton_helper_thread,1852						    0);1853					p_slot->hp_slot = hp_slot;1854					p_slot->ctrl = ctrl;1855/*					p_slot->physical_slot = physical_slot; */1856					p_slot->task_event.expires = jiffies + 5 * HZ;   /* 5 second delay */1857 1858					dbg("add_timer p_slot = %p\n", p_slot);1859					add_timer(&p_slot->task_event);1860				}1861				/***********POWER FAULT */1862				else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {1863					dbg("power fault\n");1864				}1865 1866				ctrl->event_queue[loop].event_type = 0;1867 1868				change = 1;1869			}1870		}		/* End of FOR loop */1871	}1872}1873 1874 1875/**1876 * cpqhp_pushbutton_thread - handle pushbutton events1877 * @t: pointer to struct timer_list which holds all timer-related callbacks1878 *1879 * Scheduled procedure to handle blocking stuff for the pushbuttons.1880 * Handles all pending events and exits.1881 */1882void cpqhp_pushbutton_thread(struct timer_list *t)1883{1884	u8 hp_slot;1885	struct pci_func *func;1886	struct slot *p_slot = from_timer(p_slot, t, task_event);1887	struct controller *ctrl = (struct controller *) p_slot->ctrl;1888 1889	pushbutton_pending = NULL;1890	hp_slot = p_slot->hp_slot;1891 1892	if (is_slot_enabled(ctrl, hp_slot)) {1893		p_slot->state = POWEROFF_STATE;1894		/* power Down board */1895		func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);1896		dbg("In power_down_board, func = %p, ctrl = %p\n", func, ctrl);1897		if (!func) {1898			dbg("Error! func NULL in %s\n", __func__);1899			return;1900		}1901 1902		if (cpqhp_process_SS(ctrl, func) != 0) {1903			amber_LED_on(ctrl, hp_slot);1904			green_LED_on(ctrl, hp_slot);1905 1906			set_SOGO(ctrl);1907 1908			/* Wait for SOBS to be unset */1909			wait_for_ctrl_irq(ctrl);1910		}1911 1912		p_slot->state = STATIC_STATE;1913	} else {1914		p_slot->state = POWERON_STATE;1915		/* slot is off */1916 1917		func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);1918		dbg("In add_board, func = %p, ctrl = %p\n", func, ctrl);1919		if (!func) {1920			dbg("Error! func NULL in %s\n", __func__);1921			return;1922		}1923 1924		if (ctrl != NULL) {1925			if (cpqhp_process_SI(ctrl, func) != 0) {1926				amber_LED_on(ctrl, hp_slot);1927				green_LED_off(ctrl, hp_slot);1928 1929				set_SOGO(ctrl);1930 1931				/* Wait for SOBS to be unset */1932				wait_for_ctrl_irq(ctrl);1933			}1934		}1935 1936		p_slot->state = STATIC_STATE;1937	}1938}1939 1940 1941int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func)1942{1943	u8 device, hp_slot;1944	u16 temp_word;1945	u32 tempdword;1946	int rc;1947	struct slot *p_slot;1948 1949	tempdword = 0;1950 1951	device = func->device;1952	hp_slot = device - ctrl->slot_device_offset;1953	p_slot = cpqhp_find_slot(ctrl, device);1954 1955	/* Check to see if the interlock is closed */1956	tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);1957 1958	if (tempdword & (0x01 << hp_slot))1959		return 1;1960 1961	if (func->is_a_board) {1962		rc = board_replaced(func, ctrl);1963	} else {1964		/* add board */1965		slot_remove(func);1966 1967		func = cpqhp_slot_create(ctrl->bus);1968		if (func == NULL)1969			return 1;1970 1971		func->bus = ctrl->bus;1972		func->device = device;1973		func->function = 0;1974		func->configured = 0;1975		func->is_a_board = 1;1976 1977		/* We have to save the presence info for these slots */1978		temp_word = ctrl->ctrl_int_comp >> 16;1979		func->presence_save = (temp_word >> hp_slot) & 0x01;1980		func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;1981 1982		if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {1983			func->switch_save = 0;1984		} else {1985			func->switch_save = 0x10;1986		}1987 1988		rc = board_added(func, ctrl);1989		if (rc) {1990			if (is_bridge(func)) {1991				bridge_slot_remove(func);1992			} else1993				slot_remove(func);1994 1995			/* Setup slot structure with entry for empty slot */1996			func = cpqhp_slot_create(ctrl->bus);1997 1998			if (func == NULL)1999				return 1;2000 2001			func->bus = ctrl->bus;2002			func->device = device;2003			func->function = 0;2004			func->configured = 0;2005			func->is_a_board = 0;2006 2007			/* We have to save the presence info for these slots */2008			temp_word = ctrl->ctrl_int_comp >> 16;2009			func->presence_save = (temp_word >> hp_slot) & 0x01;2010			func->presence_save |=2011			(temp_word >> (hp_slot + 7)) & 0x02;2012 2013			if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {2014				func->switch_save = 0;2015			} else {2016				func->switch_save = 0x10;2017			}2018		}2019	}2020 2021	if (rc)2022		dbg("%s: rc = %d\n", __func__, rc);2023 2024	return rc;2025}2026 2027 2028int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func)2029{2030	u8 device, class_code, header_type, BCR;2031	u8 index = 0;2032	u8 replace_flag;2033	u32 rc = 0;2034	unsigned int devfn;2035	struct slot *p_slot;2036	struct pci_bus *pci_bus = ctrl->pci_bus;2037 2038	device = func->device;2039	func = cpqhp_slot_find(ctrl->bus, device, index++);2040	p_slot = cpqhp_find_slot(ctrl, device);2041 2042	/* Make sure there are no video controllers here */2043	while (func && !rc) {2044		pci_bus->number = func->bus;2045		devfn = PCI_DEVFN(func->device, func->function);2046 2047		/* Check the Class Code */2048		rc = pci_bus_read_config_byte(pci_bus, devfn, 0x0B, &class_code);2049		if (rc)2050			return rc;2051 2052		if (class_code == PCI_BASE_CLASS_DISPLAY) {2053			/* Display/Video adapter (not supported) */2054			rc = REMOVE_NOT_SUPPORTED;2055		} else {2056			/* See if it's a bridge */2057			rc = pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);2058			if (rc)2059				return rc;2060 2061			/* If it's a bridge, check the VGA Enable bit */2062			if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {2063				rc = pci_bus_read_config_byte(pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);2064				if (rc)2065					return rc;2066 2067				/* If the VGA Enable bit is set, remove isn't2068				 * supported */2069				if (BCR & PCI_BRIDGE_CTL_VGA)2070					rc = REMOVE_NOT_SUPPORTED;2071			}2072		}2073 2074		func = cpqhp_slot_find(ctrl->bus, device, index++);2075	}2076 2077	func = cpqhp_slot_find(ctrl->bus, device, 0);2078	if ((func != NULL) && !rc) {2079		/* FIXME: Replace flag should be passed into process_SS */2080		replace_flag = !(ctrl->add_support);2081		rc = remove_board(func, replace_flag, ctrl);2082	} else if (!rc) {2083		rc = 1;2084	}2085 2086	return rc;2087}2088 2089/**2090 * switch_leds - switch the leds, go from one site to the other.2091 * @ctrl: controller to use2092 * @num_of_slots: number of slots to use2093 * @work_LED: LED control value2094 * @direction: 1 to start from the left side, 0 to start right.2095 */2096static void switch_leds(struct controller *ctrl, const int num_of_slots,2097			u32 *work_LED, const int direction)2098{2099	int loop;2100 2101	for (loop = 0; loop < num_of_slots; loop++) {2102		if (direction)2103			*work_LED = *work_LED >> 1;2104		else2105			*work_LED = *work_LED << 1;2106		writel(*work_LED, ctrl->hpc_reg + LED_CONTROL);2107 2108		set_SOGO(ctrl);2109 2110		/* Wait for SOGO interrupt */2111		wait_for_ctrl_irq(ctrl);2112 2113		/* Get ready for next iteration */2114		long_delay((2*HZ)/10);2115	}2116}2117 2118/**2119 * cpqhp_hardware_test - runs hardware tests2120 * @ctrl: target controller2121 * @test_num: the number written to the "test" file in sysfs.2122 *2123 * For hot plug ctrl folks to play with.2124 */2125int cpqhp_hardware_test(struct controller *ctrl, int test_num)2126{2127	u32 save_LED;2128	u32 work_LED;2129	int loop;2130	int num_of_slots;2131 2132	num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0f;2133 2134	switch (test_num) {2135	case 1:2136		/* Do stuff here! */2137 2138		/* Do that funky LED thing */2139		/* so we can restore them later */2140		save_LED = readl(ctrl->hpc_reg + LED_CONTROL);2141		work_LED = 0x01010101;2142		switch_leds(ctrl, num_of_slots, &work_LED, 0);2143		switch_leds(ctrl, num_of_slots, &work_LED, 1);2144		switch_leds(ctrl, num_of_slots, &work_LED, 0);2145		switch_leds(ctrl, num_of_slots, &work_LED, 1);2146 2147		work_LED = 0x01010000;2148		writel(work_LED, ctrl->hpc_reg + LED_CONTROL);2149		switch_leds(ctrl, num_of_slots, &work_LED, 0);2150		switch_leds(ctrl, num_of_slots, &work_LED, 1);2151		work_LED = 0x00000101;2152		writel(work_LED, ctrl->hpc_reg + LED_CONTROL);2153		switch_leds(ctrl, num_of_slots, &work_LED, 0);2154		switch_leds(ctrl, num_of_slots, &work_LED, 1);2155 2156		work_LED = 0x01010000;2157		writel(work_LED, ctrl->hpc_reg + LED_CONTROL);2158		for (loop = 0; loop < num_of_slots; loop++) {2159			set_SOGO(ctrl);2160 2161			/* Wait for SOGO interrupt */2162			wait_for_ctrl_irq(ctrl);2163 2164			/* Get ready for next iteration */2165			long_delay((3*HZ)/10);2166			work_LED = work_LED >> 16;2167			writel(work_LED, ctrl->hpc_reg + LED_CONTROL);2168 2169			set_SOGO(ctrl);2170 2171			/* Wait for SOGO interrupt */2172			wait_for_ctrl_irq(ctrl);2173 2174			/* Get ready for next iteration */2175			long_delay((3*HZ)/10);2176			work_LED = work_LED << 16;2177			writel(work_LED, ctrl->hpc_reg + LED_CONTROL);2178			work_LED = work_LED << 1;2179			writel(work_LED, ctrl->hpc_reg + LED_CONTROL);2180		}2181 2182		/* put it back the way it was */2183		writel(save_LED, ctrl->hpc_reg + LED_CONTROL);2184 2185		set_SOGO(ctrl);2186 2187		/* Wait for SOBS to be unset */2188		wait_for_ctrl_irq(ctrl);2189		break;2190	case 2:2191		/* Do other stuff here! */2192		break;2193	case 3:2194		/* and more... */2195		break;2196	}2197	return 0;2198}2199 2200 2201/**2202 * configure_new_device - Configures the PCI header information of one board.2203 * @ctrl: pointer to controller structure2204 * @func: pointer to function structure2205 * @behind_bridge: 1 if this is a recursive call, 0 if not2206 * @resources: pointer to set of resource lists2207 *2208 * Returns 0 if success.2209 */2210static u32 configure_new_device(struct controller  *ctrl, struct pci_func  *func,2211				 u8 behind_bridge, struct resource_lists  *resources)2212{2213	u8 temp_byte, function, max_functions, stop_it;2214	int rc;2215	u32 ID;2216	struct pci_func *new_slot;2217	int index;2218 2219	new_slot = func;2220 2221	dbg("%s\n", __func__);2222	/* Check for Multi-function device */2223	ctrl->pci_bus->number = func->bus;2224	rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(func->device, func->function), 0x0E, &temp_byte);2225	if (rc) {2226		dbg("%s: rc = %d\n", __func__, rc);2227		return rc;2228	}2229 2230	if (temp_byte & 0x80)	/* Multi-function device */2231		max_functions = 8;2232	else2233		max_functions = 1;2234 2235	function = 0;2236 2237	do {2238		rc = configure_new_function(ctrl, new_slot, behind_bridge, resources);2239 2240		if (rc) {2241			dbg("configure_new_function failed %d\n", rc);2242			index = 0;2243 2244			while (new_slot) {2245				new_slot = cpqhp_slot_find(new_slot->bus, new_slot->device, index++);2246 2247				if (new_slot)2248					cpqhp_return_board_resources(new_slot, resources);2249			}2250 2251			return rc;2252		}2253 2254		function++;2255 2256		stop_it = 0;2257 2258		/* The following loop skips to the next present function2259		 * and creates a board structure */2260 2261		while ((function < max_functions) && (!stop_it)) {2262			pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);2263 2264			if (PCI_POSSIBLE_ERROR(ID)) {2265				function++;2266			} else {2267				/* Setup slot structure. */2268				new_slot = cpqhp_slot_create(func->bus);2269 2270				if (new_slot == NULL)2271					return 1;2272 2273				new_slot->bus = func->bus;2274				new_slot->device = func->device;2275				new_slot->function = function;2276				new_slot->is_a_board = 1;2277				new_slot->status = 0;2278 2279				stop_it++;2280			}2281		}2282 2283	} while (function < max_functions);2284	dbg("returning from configure_new_device\n");2285 2286	return 0;2287}2288 2289 2290/*2291 * Configuration logic that involves the hotplug data structures and2292 * their bookkeeping2293 */2294 2295 2296/**2297 * configure_new_function - Configures the PCI header information of one device2298 * @ctrl: pointer to controller structure2299 * @func: pointer to function structure2300 * @behind_bridge: 1 if this is a recursive call, 0 if not2301 * @resources: pointer to set of resource lists2302 *2303 * Calls itself recursively for bridged devices.2304 * Returns 0 if success.2305 */2306static int configure_new_function(struct controller *ctrl, struct pci_func *func,2307				   u8 behind_bridge,2308				   struct resource_lists *resources)2309{2310	int cloop;2311	u8 IRQ = 0;2312	u8 temp_byte;2313	u8 device;2314	u8 class_code;2315	u16 command;2316	u16 temp_word;2317	u32 temp_dword;2318	u32 rc;2319	u32 temp_register;2320	u32 base;2321	u32 ID;2322	unsigned int devfn;2323	struct pci_resource *mem_node;2324	struct pci_resource *p_mem_node;2325	struct pci_resource *io_node;2326	struct pci_resource *bus_node;2327	struct pci_resource *hold_mem_node;2328	struct pci_resource *hold_p_mem_node;2329	struct pci_resource *hold_IO_node;2330	struct pci_resource *hold_bus_node;2331	struct irq_mapping irqs;2332	struct pci_func *new_slot;2333	struct pci_bus *pci_bus;2334	struct resource_lists temp_resources;2335 2336	pci_bus = ctrl->pci_bus;2337	pci_bus->number = func->bus;2338	devfn = PCI_DEVFN(func->device, func->function);2339 2340	/* Check for Bridge */2341	rc = pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &temp_byte);2342	if (rc)2343		return rc;2344 2345	if ((temp_byte & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {2346		/* set Primary bus */2347		dbg("set Primary bus = %d\n", func->bus);2348		rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);2349		if (rc)2350			return rc;2351 2352		/* find range of buses to use */2353		dbg("find ranges of buses to use\n");2354		bus_node = get_max_resource(&(resources->bus_head), 1);2355 2356		/* If we don't have any buses to allocate, we can't continue */2357		if (!bus_node)2358			return -ENOMEM;2359 2360		/* set Secondary bus */2361		temp_byte = bus_node->base;2362		dbg("set Secondary bus = %d\n", bus_node->base);2363		rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, temp_byte);2364		if (rc)2365			return rc;2366 2367		/* set subordinate bus */2368		temp_byte = bus_node->base + bus_node->length - 1;2369		dbg("set subordinate bus = %d\n", bus_node->base + bus_node->length - 1);2370		rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);2371		if (rc)2372			return rc;2373 2374		/* set subordinate Latency Timer and base Latency Timer */2375		temp_byte = 0x40;2376		rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);2377		if (rc)2378			return rc;2379		rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);2380		if (rc)2381			return rc;2382 2383		/* set Cache Line size */2384		temp_byte = 0x08;2385		rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);2386		if (rc)2387			return rc;2388 2389		/* Setup the IO, memory, and prefetchable windows */2390		io_node = get_max_resource(&(resources->io_head), 0x1000);2391		if (!io_node)2392			return -ENOMEM;2393		mem_node = get_max_resource(&(resources->mem_head), 0x100000);2394		if (!mem_node)2395			return -ENOMEM;2396		p_mem_node = get_max_resource(&(resources->p_mem_head), 0x100000);2397		if (!p_mem_node)2398			return -ENOMEM;2399		dbg("Setup the IO, memory, and prefetchable windows\n");2400		dbg("io_node\n");2401		dbg("(base, len, next) (%x, %x, %p)\n", io_node->base,2402					io_node->length, io_node->next);2403		dbg("mem_node\n");2404		dbg("(base, len, next) (%x, %x, %p)\n", mem_node->base,2405					mem_node->length, mem_node->next);2406		dbg("p_mem_node\n");2407		dbg("(base, len, next) (%x, %x, %p)\n", p_mem_node->base,2408					p_mem_node->length, p_mem_node->next);2409 2410		/* set up the IRQ info */2411		if (!resources->irqs) {2412			irqs.barber_pole = 0;2413			irqs.interrupt[0] = 0;2414			irqs.interrupt[1] = 0;2415			irqs.interrupt[2] = 0;2416			irqs.interrupt[3] = 0;2417			irqs.valid_INT = 0;2418		} else {2419			irqs.barber_pole = resources->irqs->barber_pole;2420			irqs.interrupt[0] = resources->irqs->interrupt[0];2421			irqs.interrupt[1] = resources->irqs->interrupt[1];2422			irqs.interrupt[2] = resources->irqs->interrupt[2];2423			irqs.interrupt[3] = resources->irqs->interrupt[3];2424			irqs.valid_INT = resources->irqs->valid_INT;2425		}2426 2427		/* set up resource lists that are now aligned on top and bottom2428		 * for anything behind the bridge. */2429		temp_resources.bus_head = bus_node;2430		temp_resources.io_head = io_node;2431		temp_resources.mem_head = mem_node;2432		temp_resources.p_mem_head = p_mem_node;2433		temp_resources.irqs = &irqs;2434 2435		/* Make copies of the nodes we are going to pass down so that2436		 * if there is a problem,we can just use these to free resources2437		 */2438		hold_bus_node = kmalloc(sizeof(*hold_bus_node), GFP_KERNEL);2439		hold_IO_node = kmalloc(sizeof(*hold_IO_node), GFP_KERNEL);2440		hold_mem_node = kmalloc(sizeof(*hold_mem_node), GFP_KERNEL);2441		hold_p_mem_node = kmalloc(sizeof(*hold_p_mem_node), GFP_KERNEL);2442 2443		if (!hold_bus_node || !hold_IO_node || !hold_mem_node || !hold_p_mem_node) {2444			kfree(hold_bus_node);2445			kfree(hold_IO_node);2446			kfree(hold_mem_node);2447			kfree(hold_p_mem_node);2448 2449			return 1;2450		}2451 2452		memcpy(hold_bus_node, bus_node, sizeof(struct pci_resource));2453 2454		bus_node->base += 1;2455		bus_node->length -= 1;2456		bus_node->next = NULL;2457 2458		/* If we have IO resources copy them and fill in the bridge's2459		 * IO range registers */2460		memcpy(hold_IO_node, io_node, sizeof(struct pci_resource));2461		io_node->next = NULL;2462 2463		/* set IO base and Limit registers */2464		temp_byte = io_node->base >> 8;2465		rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_BASE, temp_byte);2466 2467		temp_byte = (io_node->base + io_node->length - 1) >> 8;2468		rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte);2469 2470		/* Copy the memory resources and fill in the bridge's memory2471		 * range registers.2472		 */2473		memcpy(hold_mem_node, mem_node, sizeof(struct pci_resource));2474		mem_node->next = NULL;2475 2476		/* set Mem base and Limit registers */2477		temp_word = mem_node->base >> 16;2478		rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word);2479 2480		temp_word = (mem_node->base + mem_node->length - 1) >> 16;2481		rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);2482 2483		memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource));2484		p_mem_node->next = NULL;2485 2486		/* set Pre Mem base and Limit registers */2487		temp_word = p_mem_node->base >> 16;2488		rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);2489 2490		temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16;2491		rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);2492 2493		/* Adjust this to compensate for extra adjustment in first loop2494		 */2495		irqs.barber_pole--;2496 2497		rc = 0;2498 2499		/* Here we actually find the devices and configure them */2500		for (device = 0; (device <= 0x1F) && !rc; device++) {2501			irqs.barber_pole = (irqs.barber_pole + 1) & 0x03;2502 2503			ID = 0xFFFFFFFF;2504			pci_bus->number = hold_bus_node->base;2505			pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0), 0x00, &ID);2506			pci_bus->number = func->bus;2507 2508			if (!PCI_POSSIBLE_ERROR(ID)) {	  /*  device present */2509				/* Setup slot structure. */2510				new_slot = cpqhp_slot_create(hold_bus_node->base);2511 2512				if (new_slot == NULL) {2513					rc = -ENOMEM;2514					continue;2515				}2516 2517				new_slot->bus = hold_bus_node->base;2518				new_slot->device = device;2519				new_slot->function = 0;2520				new_slot->is_a_board = 1;2521				new_slot->status = 0;2522 2523				rc = configure_new_device(ctrl, new_slot, 1, &temp_resources);2524				dbg("configure_new_device rc=0x%x\n", rc);2525			}	/* End of IF (device in slot?) */2526		}		/* End of FOR loop */2527 2528		if (rc)2529			goto free_and_out;2530		/* save the interrupt routing information */2531		if (resources->irqs) {2532			resources->irqs->interrupt[0] = irqs.interrupt[0];2533			resources->irqs->interrupt[1] = irqs.interrupt[1];2534			resources->irqs->interrupt[2] = irqs.interrupt[2];2535			resources->irqs->interrupt[3] = irqs.interrupt[3];2536			resources->irqs->valid_INT = irqs.valid_INT;2537		} else if (!behind_bridge) {2538			/* We need to hook up the interrupts here */2539			for (cloop = 0; cloop < 4; cloop++) {2540				if (irqs.valid_INT & (0x01 << cloop)) {2541					rc = cpqhp_set_irq(func->bus, func->device,2542							   cloop + 1, irqs.interrupt[cloop]);2543					if (rc)2544						goto free_and_out;2545				}2546			}	/* end of for loop */2547		}2548		/* Return unused bus resources2549		 * First use the temporary node to store information for2550		 * the board */2551		if (bus_node && temp_resources.bus_head) {2552			hold_bus_node->length = bus_node->base - hold_bus_node->base;2553 2554			hold_bus_node->next = func->bus_head;2555			func->bus_head = hold_bus_node;2556 2557			temp_byte = temp_resources.bus_head->base - 1;2558 2559			/* set subordinate bus */2560			rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);2561 2562			if (temp_resources.bus_head->length == 0) {2563				kfree(temp_resources.bus_head);2564				temp_resources.bus_head = NULL;2565			} else {2566				return_resource(&(resources->bus_head), temp_resources.bus_head);2567			}2568		}2569 2570		/* If we have IO space available and there is some left,2571		 * return the unused portion */2572		if (hold_IO_node && temp_resources.io_head) {2573			io_node = do_pre_bridge_resource_split(&(temp_resources.io_head),2574							       &hold_IO_node, 0x1000);2575 2576			/* Check if we were able to split something off */2577			if (io_node) {2578				hold_IO_node->base = io_node->base + io_node->length;2579 2580				temp_byte = (hold_IO_node->base) >> 8;2581				rc = pci_bus_write_config_word(pci_bus, devfn, PCI_IO_BASE, temp_byte);2582 2583				return_resource(&(resources->io_head), io_node);2584			}2585 2586			io_node = do_bridge_resource_split(&(temp_resources.io_head), 0x1000);2587 2588			/* Check if we were able to split something off */2589			if (io_node) {2590				/* First use the temporary node to store2591				 * information for the board */2592				hold_IO_node->length = io_node->base - hold_IO_node->base;2593 2594				/* If we used any, add it to the board's list */2595				if (hold_IO_node->length) {2596					hold_IO_node->next = func->io_head;2597					func->io_head = hold_IO_node;2598 2599					temp_byte = (io_node->base - 1) >> 8;2600					rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte);2601 2602					return_resource(&(resources->io_head), io_node);2603				} else {2604					/* it doesn't need any IO */2605					temp_word = 0x0000;2606					rc = pci_bus_write_config_word(pci_bus, devfn, PCI_IO_LIMIT, temp_word);2607 2608					return_resource(&(resources->io_head), io_node);2609					kfree(hold_IO_node);2610				}2611			} else {2612				/* it used most of the range */2613				hold_IO_node->next = func->io_head;2614				func->io_head = hold_IO_node;2615			}2616		} else if (hold_IO_node) {2617			/* it used the whole range */2618			hold_IO_node->next = func->io_head;2619			func->io_head = hold_IO_node;2620		}2621		/* If we have memory space available and there is some left,2622		 * return the unused portion */2623		if (hold_mem_node && temp_resources.mem_head) {2624			mem_node = do_pre_bridge_resource_split(&(temp_resources.  mem_head),2625								&hold_mem_node, 0x100000);2626 2627			/* Check if we were able to split something off */2628			if (mem_node) {2629				hold_mem_node->base = mem_node->base + mem_node->length;2630 2631				temp_word = (hold_mem_node->base) >> 16;2632				rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word);2633 2634				return_resource(&(resources->mem_head), mem_node);2635			}2636 2637			mem_node = do_bridge_resource_split(&(temp_resources.mem_head), 0x100000);2638 2639			/* Check if we were able to split something off */2640			if (mem_node) {2641				/* First use the temporary node to store2642				 * information for the board */2643				hold_mem_node->length = mem_node->base - hold_mem_node->base;2644 2645				if (hold_mem_node->length) {2646					hold_mem_node->next = func->mem_head;2647					func->mem_head = hold_mem_node;2648 2649					/* configure end address */2650					temp_word = (mem_node->base - 1) >> 16;2651					rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);2652 2653					/* Return unused resources to the pool */2654					return_resource(&(resources->mem_head), mem_node);2655				} else {2656					/* it doesn't need any Mem */2657					temp_word = 0x0000;2658					rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);2659 2660					return_resource(&(resources->mem_head), mem_node);2661					kfree(hold_mem_node);2662				}2663			} else {2664				/* it used most of the range */2665				hold_mem_node->next = func->mem_head;2666				func->mem_head = hold_mem_node;2667			}2668		} else if (hold_mem_node) {2669			/* it used the whole range */2670			hold_mem_node->next = func->mem_head;2671			func->mem_head = hold_mem_node;2672		}2673		/* If we have prefetchable memory space available and there2674		 * is some left at the end, return the unused portion */2675		if (temp_resources.p_mem_head) {2676			p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head),2677								  &hold_p_mem_node, 0x100000);2678 2679			/* Check if we were able to split something off */2680			if (p_mem_node) {2681				hold_p_mem_node->base = p_mem_node->base + p_mem_node->length;2682 2683				temp_word = (hold_p_mem_node->base) >> 16;2684				rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);2685 2686				return_resource(&(resources->p_mem_head), p_mem_node);2687			}2688 2689			p_mem_node = do_bridge_resource_split(&(temp_resources.p_mem_head), 0x100000);2690 2691			/* Check if we were able to split something off */2692			if (p_mem_node) {2693				/* First use the temporary node to store2694				 * information for the board */2695				hold_p_mem_node->length = p_mem_node->base - hold_p_mem_node->base;2696 2697				/* If we used any, add it to the board's list */2698				if (hold_p_mem_node->length) {2699					hold_p_mem_node->next = func->p_mem_head;2700					func->p_mem_head = hold_p_mem_node;2701 2702					temp_word = (p_mem_node->base - 1) >> 16;2703					rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);2704 2705					return_resource(&(resources->p_mem_head), p_mem_node);2706				} else {2707					/* it doesn't need any PMem */2708					temp_word = 0x0000;2709					rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);2710 2711					return_resource(&(resources->p_mem_head), p_mem_node);2712					kfree(hold_p_mem_node);2713				}2714			} else {2715				/* it used the most of the range */2716				hold_p_mem_node->next = func->p_mem_head;2717				func->p_mem_head = hold_p_mem_node;2718			}2719		} else if (hold_p_mem_node) {2720			/* it used the whole range */2721			hold_p_mem_node->next = func->p_mem_head;2722			func->p_mem_head = hold_p_mem_node;2723		}2724		/* We should be configuring an IRQ and the bridge's base address2725		 * registers if it needs them.  Although we have never seen such2726		 * a device */2727 2728		/* enable card */2729		command = 0x0157;	/* = PCI_COMMAND_IO |2730					 *   PCI_COMMAND_MEMORY |2731					 *   PCI_COMMAND_MASTER |2732					 *   PCI_COMMAND_INVALIDATE |2733					 *   PCI_COMMAND_PARITY |2734					 *   PCI_COMMAND_SERR */2735		rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);2736 2737		/* set Bridge Control Register */2738		command = 0x07;		/* = PCI_BRIDGE_CTL_PARITY |2739					 *   PCI_BRIDGE_CTL_SERR |2740					 *   PCI_BRIDGE_CTL_NO_ISA */2741		rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command);2742	} else if ((temp_byte & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_NORMAL) {2743		/* Standard device */2744		rc = pci_bus_read_config_byte(pci_bus, devfn, 0x0B, &class_code);2745 2746		if (class_code == PCI_BASE_CLASS_DISPLAY) {2747			/* Display (video) adapter (not supported) */2748			return DEVICE_TYPE_NOT_SUPPORTED;2749		}2750		/* Figure out IO and memory needs */2751		for (cloop = 0x10; cloop <= 0x24; cloop += 4) {2752			temp_register = 0xFFFFFFFF;2753 2754			dbg("CND: bus=%d, devfn=%d, offset=%d\n", pci_bus->number, devfn, cloop);2755			rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);2756 2757			rc = pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register);2758			dbg("CND: base = 0x%x\n", temp_register);2759 2760			if (temp_register) {	  /* If this register is implemented */2761				if ((temp_register & 0x03L) == 0x01) {2762					/* Map IO */2763 2764					/* set base = amount of IO space */2765					base = temp_register & 0xFFFFFFFC;2766					base = ~base + 1;2767 2768					dbg("CND:      length = 0x%x\n", base);2769					io_node = get_io_resource(&(resources->io_head), base);2770					if (!io_node)2771						return -ENOMEM;2772					dbg("Got io_node start = %8.8x, length = %8.8x next (%p)\n",2773					    io_node->base, io_node->length, io_node->next);2774					dbg("func (%p) io_head (%p)\n", func, func->io_head);2775 2776					/* allocate the resource to the board */2777					base = io_node->base;2778					io_node->next = func->io_head;2779					func->io_head = io_node;2780				} else if ((temp_register & 0x0BL) == 0x08) {2781					/* Map prefetchable memory */2782					base = temp_register & 0xFFFFFFF0;2783					base = ~base + 1;2784 2785					dbg("CND:      length = 0x%x\n", base);2786					p_mem_node = get_resource(&(resources->p_mem_head), base);2787 2788					/* allocate the resource to the board */2789					if (p_mem_node) {2790						base = p_mem_node->base;2791 2792						p_mem_node->next = func->p_mem_head;2793						func->p_mem_head = p_mem_node;2794					} else2795						return -ENOMEM;2796				} else if ((temp_register & 0x0BL) == 0x00) {2797					/* Map memory */2798					base = temp_register & 0xFFFFFFF0;2799					base = ~base + 1;2800 2801					dbg("CND:      length = 0x%x\n", base);2802					mem_node = get_resource(&(resources->mem_head), base);2803 2804					/* allocate the resource to the board */2805					if (mem_node) {2806						base = mem_node->base;2807 2808						mem_node->next = func->mem_head;2809						func->mem_head = mem_node;2810					} else2811						return -ENOMEM;2812				} else {2813					/* Reserved bits or requesting space below 1M */2814					return NOT_ENOUGH_RESOURCES;2815				}2816 2817				rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, base);2818 2819				/* Check for 64-bit base */2820				if ((temp_register & 0x07L) == 0x04) {2821					cloop += 4;2822 2823					/* Upper 32 bits of address always zero2824					 * on today's systems */2825					/* FIXME this is probably not true on2826					 * Alpha and ia64??? */2827					base = 0;2828					rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, base);2829				}2830			}2831		}		/* End of base register loop */2832		if (cpqhp_legacy_mode) {2833			/* Figure out which interrupt pin this function uses */2834			rc = pci_bus_read_config_byte(pci_bus, devfn,2835				PCI_INTERRUPT_PIN, &temp_byte);2836 2837			/* If this function needs an interrupt and we are behind2838			 * a bridge and the pin is tied to something that's2839			 * already mapped, set this one the same */2840			if (temp_byte && resources->irqs &&2841			    (resources->irqs->valid_INT &2842			     (0x01 << ((temp_byte + resources->irqs->barber_pole - 1) & 0x03)))) {2843				/* We have to share with something already set up */2844				IRQ = resources->irqs->interrupt[(temp_byte +2845					resources->irqs->barber_pole - 1) & 0x03];2846			} else {2847				/* Program IRQ based on card type */2848				rc = pci_bus_read_config_byte(pci_bus, devfn, 0x0B, &class_code);2849 2850				if (class_code == PCI_BASE_CLASS_STORAGE)2851					IRQ = cpqhp_disk_irq;2852				else2853					IRQ = cpqhp_nic_irq;2854			}2855 2856			/* IRQ Line */2857			rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_INTERRUPT_LINE, IRQ);2858		}2859 2860		if (!behind_bridge) {2861			rc = cpqhp_set_irq(func->bus, func->device, temp_byte, IRQ);2862			if (rc)2863				return 1;2864		} else {2865			/* TBD - this code may also belong in the other clause2866			 * of this If statement */2867			resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03] = IRQ;2868			resources->irqs->valid_INT |= 0x01 << (temp_byte + resources->irqs->barber_pole - 1) & 0x03;2869		}2870 2871		/* Latency Timer */2872		temp_byte = 0x40;2873		rc = pci_bus_write_config_byte(pci_bus, devfn,2874					PCI_LATENCY_TIMER, temp_byte);2875 2876		/* Cache Line size */2877		temp_byte = 0x08;2878		rc = pci_bus_write_config_byte(pci_bus, devfn,2879					PCI_CACHE_LINE_SIZE, temp_byte);2880 2881		/* disable ROM base Address */2882		temp_dword = 0x00L;2883		rc = pci_bus_write_config_word(pci_bus, devfn,2884					PCI_ROM_ADDRESS, temp_dword);2885 2886		/* enable card */2887		temp_word = 0x0157;	/* = PCI_COMMAND_IO |2888					 *   PCI_COMMAND_MEMORY |2889					 *   PCI_COMMAND_MASTER |2890					 *   PCI_COMMAND_INVALIDATE |2891					 *   PCI_COMMAND_PARITY |2892					 *   PCI_COMMAND_SERR */2893		rc = pci_bus_write_config_word(pci_bus, devfn,2894					PCI_COMMAND, temp_word);2895	} else {		/* End of Not-A-Bridge else */2896		/* It's some strange type of PCI adapter (Cardbus?) */2897		return DEVICE_TYPE_NOT_SUPPORTED;2898	}2899 2900	func->configured = 1;2901 2902	return 0;2903free_and_out:2904	cpqhp_destroy_resource_list(&temp_resources);2905 2906	return_resource(&(resources->bus_head), hold_bus_node);2907	return_resource(&(resources->io_head), hold_IO_node);2908	return_resource(&(resources->mem_head), hold_mem_node);2909	return_resource(&(resources->p_mem_head), hold_p_mem_node);2910	return rc;2911}2912