// SPDX-License-Identifier: GPL-2.0+
/*
 * Compaq Hot Plug Controller Driver
 *
 * Copyright (C) 1995,2001 Compaq Computer Corporation
 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
 * Copyright (C) 2001 IBM Corp.
 *
 * All rights reserved.
 *
 * Send feedback to <greg@kroah.com>
 *
 */

#define pr_fmt(fmt) "cpqphp: " fmt

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/printk.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/proc_fs.h>
#include <linux/pci.h>
#include <linux/pci_hotplug.h>
#include "../pci.h"
#include "cpqphp.h"
#include "cpqphp_nvram.h"


u8 cpqhp_nic_irq;
u8 cpqhp_disk_irq;

static u16 unused_IRQ;

/*
 * detect_HRT_floating_pointer
 *
 * find the Hot Plug Resource Table in the specified region of memory.
 *
 */
static void __iomem *detect_HRT_floating_pointer(void __iomem *begin, void __iomem *end)
{
	void __iomem *fp;
	void __iomem *endp;
	u8 temp1, temp2, temp3, temp4;
	int status = 0;

	endp = (end - sizeof(struct hrt) + 1);

	for (fp = begin; fp <= endp; fp += 16) {
		temp1 = readb(fp + SIG0);
		temp2 = readb(fp + SIG1);
		temp3 = readb(fp + SIG2);
		temp4 = readb(fp + SIG3);
		if (temp1 == '$' &&
		    temp2 == 'H' &&
		    temp3 == 'R' &&
		    temp4 == 'T') {
			status = 1;
			break;
		}
	}

	if (!status)
		fp = NULL;

	dbg("Discovered Hotplug Resource Table at %p\n", fp);
	return fp;
}


int cpqhp_configure_device(struct controller *ctrl, struct pci_func *func)
{
	struct pci_bus *child;
	int num;

	pci_lock_rescan_remove();

	if (func->pci_dev == NULL)
		func->pci_dev = pci_get_domain_bus_and_slot(0, func->bus,
							PCI_DEVFN(func->device,
							func->function));

	/* No pci device, we need to create it then */
	if (func->pci_dev == NULL) {
		dbg("INFO: pci_dev still null\n");

		num = pci_scan_slot(ctrl->pci_dev->bus, PCI_DEVFN(func->device, func->function));
		if (num)
			pci_bus_add_devices(ctrl->pci_dev->bus);

		func->pci_dev = pci_get_domain_bus_and_slot(0, func->bus,
							PCI_DEVFN(func->device,
							func->function));
		if (func->pci_dev == NULL) {
			dbg("ERROR: pci_dev still null\n");
			goto out;
		}
	}

	if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
		pci_hp_add_bridge(func->pci_dev);
		child = func->pci_dev->subordinate;
		if (child)
			pci_bus_add_devices(child);
	}

	pci_dev_put(func->pci_dev);

 out:
	pci_unlock_rescan_remove();
	return 0;
}


int cpqhp_unconfigure_device(struct pci_func *func)
{
	int j;

	dbg("%s: bus/dev/func = %x/%x/%x\n", __func__, func->bus, func->device, func->function);

	pci_lock_rescan_remove();
	for (j = 0; j < 8 ; j++) {
		struct pci_dev *temp = pci_get_domain_bus_and_slot(0,
							func->bus,
							PCI_DEVFN(func->device,
							j));
		if (temp) {
			pci_dev_put(temp);
			pci_stop_and_remove_bus_device(temp);
		}
	}
	pci_unlock_rescan_remove();
	return 0;
}

/*
 * cpqhp_set_irq
 *
 * @bus_num: bus number of PCI device
 * @dev_num: device number of PCI device
 * @slot: pointer to u8 where slot number will be returned
 */
int cpqhp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
{
	int rc = 0;

	if (cpqhp_legacy_mode) {
		struct pci_dev *fakedev;
		struct pci_bus *fakebus;
		u16 temp_word;

		fakedev = kmalloc_obj(*fakedev);
		fakebus = kmalloc_obj(*fakebus);
		if (!fakedev || !fakebus) {
			kfree(fakedev);
			kfree(fakebus);
			return -ENOMEM;
		}

		fakedev->devfn = dev_num << 3;
		fakedev->bus = fakebus;
		fakebus->number = bus_num;
		dbg("%s: dev %d, bus %d, pin %d, num %d\n",
		    __func__, dev_num, bus_num, int_pin, irq_num);
		rc = pcibios_set_irq_routing(fakedev, int_pin - 1, irq_num);
		kfree(fakedev);
		kfree(fakebus);
		dbg("%s: rc %d\n", __func__, rc);
		if (!rc)
			return !rc;

		/* set the Edge Level Control Register (ELCR) */
		temp_word = inb(0x4d0);
		temp_word |= inb(0x4d1) << 8;

		temp_word |= 0x01 << irq_num;

		/* This should only be for x86 as it sets the Edge Level
		 * Control Register
		 */
		outb((u8)(temp_word & 0xFF), 0x4d0);
		outb((u8)((temp_word & 0xFF00) >> 8), 0x4d1);
		rc = 0;
	}

	return rc;
}


static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 *dev_num)
{
	u16 tdevice;
	u32 work;
	int ret = -1;

	ctrl->pci_bus->number = bus_num;

	for (tdevice = 0; tdevice < 0xFF; tdevice++) {
		/* Scan for access first */
		if (!pci_bus_read_dev_vendor_id(ctrl->pci_bus, tdevice, &work, 0))
			continue;
		ret = pci_bus_read_config_dword(ctrl->pci_bus, tdevice, PCI_CLASS_REVISION, &work);
		if (ret)
			continue;
		dbg("Looking for nonbridge bus_num %d dev_num %d\n", bus_num, tdevice);
		/* Yep we got one. Not a bridge ? */
		if ((work >> 8) != PCI_TO_PCI_BRIDGE_CLASS) {
			*dev_num = tdevice;
			dbg("found it !\n");
			return 0;
		} else {
			/*
			 * XXX: Code whose debug printout indicated
			 * recursion to buses underneath bridges might be
			 * necessary was removed because it never did
			 * any recursion.
			 */
			ret = 0;
			pr_warn("missing feature: bridge scan recursion not implemented\n");
		}
	}


	return ret;
}


static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot, u8 nobridge)
{
	int loop, len;
	u32 work;
	u8 tbus, tdevice, tslot;

	len = cpqhp_routing_table_length();
	for (loop = 0; loop < len; ++loop) {
		tbus = cpqhp_routing_table->slots[loop].bus;
		tdevice = cpqhp_routing_table->slots[loop].devfn;
		tslot = cpqhp_routing_table->slots[loop].slot;

		if (tslot == slot) {
			*bus_num = tbus;
			*dev_num = tdevice;
			ctrl->pci_bus->number = tbus;
			pci_bus_read_config_dword(ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work);
			if (!nobridge || PCI_POSSIBLE_ERROR(work))
				return 0;

			dbg("bus_num %d devfn %d\n", *bus_num, *dev_num);
			pci_bus_read_config_dword(ctrl->pci_bus, *dev_num, PCI_CLASS_REVISION, &work);
			dbg("work >> 8 (%x) = BRIDGE (%x)\n", work >> 8, PCI_TO_PCI_BRIDGE_CLASS);

			if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
				pci_bus_read_config_byte(ctrl->pci_bus, *dev_num, PCI_SECONDARY_BUS, &tbus);
				dbg("Scan bus for Non Bridge: bus %d\n", tbus);
				if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) {
					*bus_num = tbus;
					return 0;
				}
			} else
				return 0;
		}
	}
	return -1;
}


int cpqhp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot)
{
	/* plain (bridges allowed) */
	return PCI_GetBusDevHelper(ctrl, bus_num, dev_num, slot, 0);
}


/* More PCI configuration routines; this time centered around hotplug
 * controller
 */


/*
 * cpqhp_save_config
 *
 * Reads configuration for all slots in a PCI bus and saves info.
 *
 * Note:  For non-hot plug buses, the slot # saved is the device #
 *
 * returns 0 if success
 */
int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
{
	long rc;
	u8 class_code;
	u8 header_type;
	u32 ID;
	u8 secondary_bus;
	struct pci_func *new_slot;
	int sub_bus;
	int FirstSupported;
	int LastSupported;
	int max_functions;
	int function;
	u8 DevError;
	int device = 0;
	int cloop = 0;
	int stop_it;
	int index;
	u16 devfn;

	/* Decide which slots are supported */

	if (is_hot_plug) {
		/*
		 * is_hot_plug is the slot mask
		 */
		FirstSupported = is_hot_plug >> 4;
		LastSupported = FirstSupported + (is_hot_plug & 0x0F) - 1;
	} else {
		FirstSupported = 0;
		LastSupported = 0x1F;
	}

	/* Save PCI configuration space for all devices in supported slots */
	ctrl->pci_bus->number = busnumber;
	for (device = FirstSupported; device <= LastSupported; device++) {
		ID = 0xFFFFFFFF;
		rc = pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);

		if (ID == 0xFFFFFFFF) {
			if (is_hot_plug) {
				/* Setup slot structure with entry for empty
				 * slot
				 */
				new_slot = cpqhp_slot_create(busnumber);
				if (new_slot == NULL)
					return 1;

				new_slot->bus = (u8) busnumber;
				new_slot->device = (u8) device;
				new_slot->function = 0;
				new_slot->is_a_board = 0;
				new_slot->presence_save = 0;
				new_slot->switch_save = 0;
			}
			continue;
		}

		rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, 0), 0x0B, &class_code);
		if (rc)
			return rc;

		rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_HEADER_TYPE, &header_type);
		if (rc)
			return rc;

		/* If multi-function device, set max_functions to 8 */
		if (header_type & PCI_HEADER_TYPE_MFD)
			max_functions = 8;
		else
			max_functions = 1;

		function = 0;

		do {
			DevError = 0;
			if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
				/* Recurse the subordinate bus
				 * get the subordinate bus number
				 */
				rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, function), PCI_SECONDARY_BUS, &secondary_bus);
				if (rc) {
					return rc;
				} else {
					sub_bus = (int) secondary_bus;

					/* Save secondary bus cfg spc
					 * with this recursive call.
					 */
					rc = cpqhp_save_config(ctrl, sub_bus, 0);
					if (rc)
						return rc;
					ctrl->pci_bus->number = busnumber;
				}
			}

			index = 0;
			new_slot = cpqhp_slot_find(busnumber, device, index++);
			while (new_slot &&
			       (new_slot->function != (u8) function))
				new_slot = cpqhp_slot_find(busnumber, device, index++);

			if (!new_slot) {
				/* Setup slot structure. */
				new_slot = cpqhp_slot_create(busnumber);
				if (new_slot == NULL)
					return 1;
			}

			new_slot->bus = (u8) busnumber;
			new_slot->device = (u8) device;
			new_slot->function = (u8) function;
			new_slot->is_a_board = 1;
			new_slot->switch_save = 0x10;
			/* In case of unsupported board */
			new_slot->status = DevError;
			devfn = (new_slot->device << 3) | new_slot->function;
			new_slot->pci_dev = pci_get_domain_bus_and_slot(0,
							new_slot->bus, devfn);

			for (cloop = 0; cloop < 0x20; cloop++) {
				rc = pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(device, function), cloop << 2, (u32 *) &(new_slot->config_space[cloop]));
				if (rc)
					return rc;
			}

			pci_dev_put(new_slot->pci_dev);

			function++;

			stop_it = 0;

			/* this loop skips to the next present function
			 * reading in Class Code and Header type.
			 */
			while ((function < max_functions) && (!stop_it)) {
				rc = pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(device, function), PCI_VENDOR_ID, &ID);
				if (ID == 0xFFFFFFFF) {
					function++;
					continue;
				}
				rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, function), 0x0B, &class_code);
				if (rc)
					return rc;

				rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, function), PCI_HEADER_TYPE, &header_type);
				if (rc)
					return rc;

				stop_it++;
			}

		} while (function < max_functions);
	}			/* End of FOR loop */

	return 0;
}


/*
 * cpqhp_save_slot_config
 *
 * Saves configuration info for all PCI devices in a given slot
 * including subordinate buses.
 *
 * returns 0 if success
 */
int cpqhp_save_slot_config(struct controller *ctrl, struct pci_func *new_slot)
{
	long rc;
	u8 class_code;
	u8 header_type;
	u32 ID;
	u8 secondary_bus;
	int sub_bus;
	int max_functions;
	int function = 0;
	int cloop;
	int stop_it;

	ID = 0xFFFFFFFF;

	ctrl->pci_bus->number = new_slot->bus;
	pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_VENDOR_ID, &ID);

	if (ID == 0xFFFFFFFF)
		return 2;

	pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), 0x0B, &class_code);
	pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_HEADER_TYPE, &header_type);

	if (header_type & PCI_HEADER_TYPE_MFD)
		max_functions = 8;
	else
		max_functions = 1;

	while (function < max_functions) {
		if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
			/*  Recurse the subordinate bus */
			pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_SECONDARY_BUS, &secondary_bus);

			sub_bus = (int) secondary_bus;

			/* Save the config headers for the secondary
			 * bus.
			 */
			rc = cpqhp_save_config(ctrl, sub_bus, 0);
			if (rc)
				return(rc);
			ctrl->pci_bus->number = new_slot->bus;

		}

		new_slot->status = 0;

		for (cloop = 0; cloop < 0x20; cloop++)
			pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), cloop << 2, (u32 *) &(new_slot->config_space[cloop]));

		function++;

		stop_it = 0;

		/* this loop skips to the next present function
		 * reading in the Class Code and the Header type.
		 */
		while ((function < max_functions) && (!stop_it)) {
			pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_VENDOR_ID, &ID);

			if (ID == 0xFFFFFFFF)
				function++;
			else {
				pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), 0x0B, &class_code);
				pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_HEADER_TYPE, &header_type);
				stop_it++;
			}
		}

	}

	return 0;
}


/*
 * cpqhp_save_base_addr_length
 *
 * Saves the length of all base address registers for the
 * specified slot.  this is for hot plug REPLACE
 *
 * returns 0 if success
 */
int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func *func)
{
	u8 cloop;
	u8 header_type;
	u8 secondary_bus;
	u8 type;
	int sub_bus;
	u32 temp_register;
	u32 base;
	u32 rc;
	struct pci_func *next;
	int index = 0;
	struct pci_bus *pci_bus = ctrl->pci_bus;
	unsigned int devfn;

	func = cpqhp_slot_find(func->bus, func->device, index++);

	while (func != NULL) {
		pci_bus->number = func->bus;
		devfn = PCI_DEVFN(func->device, func->function);

		/* Check for Bridge */
		pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);

		if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
			pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);

			sub_bus = (int) secondary_bus;

			next = cpqhp_slot_list[sub_bus];

			while (next != NULL) {
				rc = cpqhp_save_base_addr_length(ctrl, next);
				if (rc)
					return rc;

				next = next->next;
			}
			pci_bus->number = func->bus;

			/* FIXME: this loop is duplicated in the non-bridge
			 * case.  The two could be rolled together Figure out
			 * IO and memory base lengths
			 */
			for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
				temp_register = 0xFFFFFFFF;
				pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
				pci_bus_read_config_dword(pci_bus, devfn, cloop, &base);
				/* If this register is implemented */
				if (base) {
					if (base & 0x01L) {
						/* IO base
						 * set base = amount of IO space
						 * requested
						 */
						base = base & 0xFFFFFFFE;
						base = (~base) + 1;

						type = 1;
					} else {
						/* memory base */
						base = base & 0xFFFFFFF0;
						base = (~base) + 1;

						type = 0;
					}
				} else {
					base = 0x0L;
					type = 0;
				}

				/* Save information in slot structure */
				func->base_length[(cloop - 0x10) >> 2] =
				base;
				func->base_type[(cloop - 0x10) >> 2] = type;

			}	/* End of base register loop */

		} else if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_NORMAL) {
			/* Figure out IO and memory base lengths */
			for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
				temp_register = 0xFFFFFFFF;
				pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
				pci_bus_read_config_dword(pci_bus, devfn, cloop, &base);

				/* If this register is implemented */
				if (base) {
					if (base & 0x01L) {
						/* IO base
						 * base = amount of IO space
						 * requested
						 */
						base = base & 0xFFFFFFFE;
						base = (~base) + 1;

						type = 1;
					} else {
						/* memory base
						 * base = amount of memory
						 * space requested
						 */
						base = base & 0xFFFFFFF0;
						base = (~base) + 1;

						type = 0;
					}
				} else {
					base = 0x0L;
					type = 0;
				}

				/* Save information in slot structure */
				func->base_length[(cloop - 0x10) >> 2] = base;
				func->base_type[(cloop - 0x10) >> 2] = type;

			}	/* End of base register loop */

		} else {	  /* Some other unknown header type */
		}

		/* find the next device in this slot */
		func = cpqhp_slot_find(func->bus, func->device, index++);
	}

	return(0);
}


/*
 * cpqhp_save_used_resources
 *
 * Stores used resource information for existing boards.  this is
 * for boards that were in the system when this driver was loaded.
 * this function is for hot plug ADD
 *
 * returns 0 if success
 */
int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func)
{
	u8 cloop;
	u8 header_type;
	u8 secondary_bus;
	u8 temp_byte;
	u8 b_base;
	u8 b_length;
	u16 command;
	u16 save_command;
	u16 w_base;
	u16 w_length;
	u32 temp_register;
	u32 save_base;
	u32 base;
	int index = 0;
	struct pci_resource *mem_node;
	struct pci_resource *p_mem_node;
	struct pci_resource *io_node;
	struct pci_resource *bus_node;
	struct pci_bus *pci_bus = ctrl->pci_bus;
	unsigned int devfn;

	func = cpqhp_slot_find(func->bus, func->device, index++);

	while ((func != NULL) && func->is_a_board) {
		pci_bus->number = func->bus;
		devfn = PCI_DEVFN(func->device, func->function);

		/* Save the command register */
		pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &save_command);

		/* disable card */
		command = 0x00;
		pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);

		/* Check for Bridge */
		pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);

		if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
			/* Clear Bridge Control Register */
			command = 0x00;
			pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
			pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
			pci_bus_read_config_byte(pci_bus, devfn, PCI_SUBORDINATE_BUS, &temp_byte);

			bus_node = kmalloc_obj(*bus_node);
			if (!bus_node)
				return -ENOMEM;

			bus_node->base = secondary_bus;
			bus_node->length = temp_byte - secondary_bus + 1;

			bus_node->next = func->bus_head;
			func->bus_head = bus_node;

			/* Save IO base and Limit registers */
			pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_BASE, &b_base);
			pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_LIMIT, &b_length);

			if ((b_base <= b_length) && (save_command & 0x01)) {
				io_node = kmalloc_obj(*io_node);
				if (!io_node)
					return -ENOMEM;

				io_node->base = (b_base & 0xF0) << 8;
				io_node->length = (b_length - b_base + 0x10) << 8;

				io_node->next = func->io_head;
				func->io_head = io_node;
			}

			/* Save memory base and Limit registers */
			pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_BASE, &w_base);
			pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length);

			if ((w_base <= w_length) && (save_command & 0x02)) {
				mem_node = kmalloc_obj(*mem_node);
				if (!mem_node)
					return -ENOMEM;

				mem_node->base = w_base << 16;
				mem_node->length = (w_length - w_base + 0x10) << 16;

				mem_node->next = func->mem_head;
				func->mem_head = mem_node;
			}

			/* Save prefetchable memory base and Limit registers */
			pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base);
			pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length);

			if ((w_base <= w_length) && (save_command & 0x02)) {
				p_mem_node = kmalloc_obj(*p_mem_node);
				if (!p_mem_node)
					return -ENOMEM;

				p_mem_node->base = w_base << 16;
				p_mem_node->length = (w_length - w_base + 0x10) << 16;

				p_mem_node->next = func->p_mem_head;
				func->p_mem_head = p_mem_node;
			}
			/* Figure out IO and memory base lengths */
			for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
				pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base);

				temp_register = 0xFFFFFFFF;
				pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
				pci_bus_read_config_dword(pci_bus, devfn, cloop, &base);

				temp_register = base;

				/* If this register is implemented */
				if (base) {
					if (((base & 0x03L) == 0x01)
					    && (save_command & 0x01)) {
						/* IO base
						 * set temp_register = amount
						 * of IO space requested
						 */
						temp_register = base & 0xFFFFFFFE;
						temp_register = (~temp_register) + 1;

						io_node = kmalloc_obj(*io_node);
						if (!io_node)
							return -ENOMEM;

						io_node->base =
						save_base & (~0x03L);
						io_node->length = temp_register;

						io_node->next = func->io_head;
						func->io_head = io_node;
					} else
						if (((base & 0x0BL) == 0x08)
						    && (save_command & 0x02)) {
						/* prefetchable memory base */
						temp_register = base & 0xFFFFFFF0;
						temp_register = (~temp_register) + 1;

						p_mem_node = kmalloc_obj(*p_mem_node);
						if (!p_mem_node)
							return -ENOMEM;

						p_mem_node->base = save_base & (~0x0FL);
						p_mem_node->length = temp_register;

						p_mem_node->next = func->p_mem_head;
						func->p_mem_head = p_mem_node;
					} else
						if (((base & 0x0BL) == 0x00)
						    && (save_command & 0x02)) {
						/* prefetchable memory base */
						temp_register = base & 0xFFFFFFF0;
						temp_register = (~temp_register) + 1;

						mem_node = kmalloc_obj(*mem_node);
						if (!mem_node)
							return -ENOMEM;

						mem_node->base = save_base & (~0x0FL);
						mem_node->length = temp_register;

						mem_node->next = func->mem_head;
						func->mem_head = mem_node;
					} else
						return(1);
				}
			}	/* End of base register loop */
		/* Standard header */
		} else if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_NORMAL) {
			/* Figure out IO and memory base lengths */
			for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
				pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base);

				temp_register = 0xFFFFFFFF;
				pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
				pci_bus_read_config_dword(pci_bus, devfn, cloop, &base);

				temp_register = base;

				/* If this register is implemented */
				if (base) {
					if (((base & 0x03L) == 0x01)
					    && (save_command & 0x01)) {
						/* IO base
						 * set temp_register = amount
						 * of IO space requested
						 */
						temp_register = base & 0xFFFFFFFE;
						temp_register = (~temp_register) + 1;

						io_node = kmalloc_obj(*io_node);
						if (!io_node)
							return -ENOMEM;

						io_node->base = save_base & (~0x01L);
						io_node->length = temp_register;

						io_node->next = func->io_head;
						func->io_head = io_node;
					} else
						if (((base & 0x0BL) == 0x08)
						    && (save_command & 0x02)) {
						/* prefetchable memory base */
						temp_register = base & 0xFFFFFFF0;
						temp_register = (~temp_register) + 1;

						p_mem_node = kmalloc_obj(*p_mem_node);
						if (!p_mem_node)
							return -ENOMEM;

						p_mem_node->base = save_base & (~0x0FL);
						p_mem_node->length = temp_register;

						p_mem_node->next = func->p_mem_head;
						func->p_mem_head = p_mem_node;
					} else
						if (((base & 0x0BL) == 0x00)
						    && (save_command & 0x02)) {
						/* prefetchable memory base */
						temp_register = base & 0xFFFFFFF0;
						temp_register = (~temp_register) + 1;

						mem_node = kmalloc_obj(*mem_node);
						if (!mem_node)
							return -ENOMEM;

						mem_node->base = save_base & (~0x0FL);
						mem_node->length = temp_register;

						mem_node->next = func->mem_head;
						func->mem_head = mem_node;
					} else
						return(1);
				}
			}	/* End of base register loop */
		}

		/* find the next device in this slot */
		func = cpqhp_slot_find(func->bus, func->device, index++);
	}

	return 0;
}


/*
 * cpqhp_configure_board
 *
 * Copies saved configuration information to one slot.
 * this is called recursively for bridge devices.
 * this is for hot plug REPLACE!
 *
 * returns 0 if success
 */
int cpqhp_configure_board(struct controller *ctrl, struct pci_func *func)
{
	int cloop;
	u8 header_type;
	u8 secondary_bus;
	int sub_bus;
	struct pci_func *next;
	u32 temp;
	u32 rc;
	int index = 0;
	struct pci_bus *pci_bus = ctrl->pci_bus;
	unsigned int devfn;

	func = cpqhp_slot_find(func->bus, func->device, index++);

	while (func != NULL) {
		pci_bus->number = func->bus;
		devfn = PCI_DEVFN(func->device, func->function);

		/* Start at the top of config space so that the control
		 * registers are programmed last
		 */
		for (cloop = 0x3C; cloop > 0; cloop -= 4)
			pci_bus_write_config_dword(pci_bus, devfn, cloop, func->config_space[cloop >> 2]);

		pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);

		/* If this is a bridge device, restore subordinate devices */
		if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
			pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);

			sub_bus = (int) secondary_bus;

			next = cpqhp_slot_list[sub_bus];

			while (next != NULL) {
				rc = cpqhp_configure_board(ctrl, next);
				if (rc)
					return rc;

				next = next->next;
			}
		} else {

			/* Check all the base Address Registers to make sure
			 * they are the same.  If not, the board is different.
			 */

			for (cloop = 16; cloop < 40; cloop += 4) {
				pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp);

				if (temp != func->config_space[cloop >> 2]) {
					dbg("Config space compare failure!!! offset = %x\n", cloop);
					dbg("bus = %x, device = %x, function = %x\n", func->bus, func->device, func->function);
					dbg("temp = %x, config space = %x\n\n", temp, func->config_space[cloop >> 2]);
					return 1;
				}
			}
		}

		func->configured = 1;

		func = cpqhp_slot_find(func->bus, func->device, index++);
	}

	return 0;
}


/*
 * cpqhp_valid_replace
 *
 * this function checks to see if a board is the same as the
 * one it is replacing.  this check will detect if the device's
 * vendor or device id's are the same
 *
 * returns 0 if the board is the same nonzero otherwise
 */
int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func)
{
	u8 cloop;
	u8 header_type;
	u8 secondary_bus;
	u8 type;
	u32 temp_register = 0;
	u32 base;
	u32 rc;
	struct pci_func *next;
	int index = 0;
	struct pci_bus *pci_bus = ctrl->pci_bus;
	unsigned int devfn;

	if (!func->is_a_board)
		return(ADD_NOT_SUPPORTED);

	func = cpqhp_slot_find(func->bus, func->device, index++);

	while (func != NULL) {
		pci_bus->number = func->bus;
		devfn = PCI_DEVFN(func->device, func->function);

		pci_bus_read_config_dword(pci_bus, devfn, PCI_VENDOR_ID, &temp_register);

		/* No adapter present */
		if (temp_register == 0xFFFFFFFF)
			return(NO_ADAPTER_PRESENT);

		if (temp_register != func->config_space[0])
			return(ADAPTER_NOT_SAME);

		/* Check for same revision number and class code */
		pci_bus_read_config_dword(pci_bus, devfn, PCI_CLASS_REVISION, &temp_register);

		/* Adapter not the same */
		if (temp_register != func->config_space[0x08 >> 2])
			return(ADAPTER_NOT_SAME);

		/* Check for Bridge */
		pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);

		if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
			/* In order to continue checking, we must program the
			 * bus registers in the bridge to respond to accesses
			 * for its subordinate bus(es)
			 */

			temp_register = func->config_space[0x18 >> 2];
			pci_bus_write_config_dword(pci_bus, devfn, PCI_PRIMARY_BUS, temp_register);

			secondary_bus = (temp_register >> 8) & 0xFF;

			next = cpqhp_slot_list[secondary_bus];

			while (next != NULL) {
				rc = cpqhp_valid_replace(ctrl, next);
				if (rc)
					return rc;

				next = next->next;
			}

		}
		/* Check to see if it is a standard config header */
		else if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_NORMAL) {
			/* Check subsystem vendor and ID */
			pci_bus_read_config_dword(pci_bus, devfn, PCI_SUBSYSTEM_VENDOR_ID, &temp_register);

			if (temp_register != func->config_space[0x2C >> 2]) {
				/* If it's a SMART-2 and the register isn't
				 * filled in, ignore the difference because
				 * they just have an old rev of the firmware
				 */
				if (!((func->config_space[0] == 0xAE100E11)
				      && (temp_register == 0x00L)))
					return(ADAPTER_NOT_SAME);
			}
			/* Figure out IO and memory base lengths */
			for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
				temp_register = 0xFFFFFFFF;
				pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
				pci_bus_read_config_dword(pci_bus, devfn, cloop, &base);

				/* If this register is implemented */
				if (base) {
					if (base & 0x01L) {
						/* IO base
						 * set base = amount of IO
						 * space requested
						 */
						base = base & 0xFFFFFFFE;
						base = (~base) + 1;

						type = 1;
					} else {
						/* memory base */
						base = base & 0xFFFFFFF0;
						base = (~base) + 1;

						type = 0;
					}
				} else {
					base = 0x0L;
					type = 0;
				}

				/* Check information in slot structure */
				if (func->base_length[(cloop - 0x10) >> 2] != base)
					return(ADAPTER_NOT_SAME);

				if (func->base_type[(cloop - 0x10) >> 2] != type)
					return(ADAPTER_NOT_SAME);

			}	/* End of base register loop */

		}		/* End of (type 0 config space) else */
		else {
			/* this is not a type 0 or 1 config space header so
			 * we don't know how to do it
			 */
			return(DEVICE_TYPE_NOT_SUPPORTED);
		}

		/* Get the next function */
		func = cpqhp_slot_find(func->bus, func->device, index++);
	}


	return 0;
}


/*
 * cpqhp_find_available_resources
 *
 * Finds available memory, IO, and IRQ resources for programming
 * devices which may be added to the system
 * this function is for hot plug ADD!
 *
 * returns 0 if success
 */
int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_start)
{
	u8 temp;
	u8 populated_slot;
	u8 bridged_slot;
	void __iomem *one_slot;
	void __iomem *rom_resource_table;
	struct pci_func *func = NULL;
	int i = 10, index;
	u32 temp_dword, rc;
	struct pci_resource *mem_node;
	struct pci_resource *p_mem_node;
	struct pci_resource *io_node;
	struct pci_resource *bus_node;

	rom_resource_table = detect_HRT_floating_pointer(rom_start, rom_start+0xffff);
	dbg("rom_resource_table = %p\n", rom_resource_table);

	if (rom_resource_table == NULL)
		return -ENODEV;

	/* Sum all resources and setup resource maps */
	unused_IRQ = readl(rom_resource_table + UNUSED_IRQ);
	dbg("unused_IRQ = %x\n", unused_IRQ);

	temp = 0;
	while (unused_IRQ) {
		if (unused_IRQ & 1) {
			cpqhp_disk_irq = temp;
			break;
		}
		unused_IRQ = unused_IRQ >> 1;
		temp++;
	}

	dbg("cpqhp_disk_irq= %d\n", cpqhp_disk_irq);
	unused_IRQ = unused_IRQ >> 1;
	temp++;

	while (unused_IRQ) {
		if (unused_IRQ & 1) {
			cpqhp_nic_irq = temp;
			break;
		}
		unused_IRQ = unused_IRQ >> 1;
		temp++;
	}

	dbg("cpqhp_nic_irq= %d\n", cpqhp_nic_irq);
	unused_IRQ = readl(rom_resource_table + PCIIRQ);

	temp = 0;

	if (!cpqhp_nic_irq)
		cpqhp_nic_irq = ctrl->cfgspc_irq;

	if (!cpqhp_disk_irq)
		cpqhp_disk_irq = ctrl->cfgspc_irq;

	dbg("cpqhp_disk_irq, cpqhp_nic_irq= %d, %d\n", cpqhp_disk_irq, cpqhp_nic_irq);

	rc = compaq_nvram_load(rom_start, ctrl);
	if (rc)
		return rc;

	one_slot = rom_resource_table + sizeof(struct hrt);

	i = readb(rom_resource_table + NUMBER_OF_ENTRIES);
	dbg("number_of_entries = %d\n", i);

	if (!readb(one_slot + SECONDARY_BUS))
		return 1;

	dbg("dev|IO base|length|Mem base|length|Pre base|length|PB SB MB\n");

	while (i && readb(one_slot + SECONDARY_BUS)) {
		u8 dev_func = readb(one_slot + DEV_FUNC);
		u8 primary_bus = readb(one_slot + PRIMARY_BUS);
		u8 secondary_bus = readb(one_slot + SECONDARY_BUS);
		u8 max_bus = readb(one_slot + MAX_BUS);
		u16 io_base = readw(one_slot + IO_BASE);
		u16 io_length = readw(one_slot + IO_LENGTH);
		u16 mem_base = readw(one_slot + MEM_BASE);
		u16 mem_length = readw(one_slot + MEM_LENGTH);
		u16 pre_mem_base = readw(one_slot + PRE_MEM_BASE);
		u16 pre_mem_length = readw(one_slot + PRE_MEM_LENGTH);

		dbg("%2.2x | %4.4x  | %4.4x | %4.4x   | %4.4x | %4.4x   | %4.4x |%2.2x %2.2x %2.2x\n",
		    dev_func, io_base, io_length, mem_base, mem_length, pre_mem_base, pre_mem_length,
		    primary_bus, secondary_bus, max_bus);

		/* If this entry isn't for our controller's bus, ignore it */
		if (primary_bus != ctrl->bus) {
			i--;
			one_slot += sizeof(struct slot_rt);
			continue;
		}
		/* find out if this entry is for an occupied slot */
		ctrl->pci_bus->number = primary_bus;
		pci_bus_read_config_dword(ctrl->pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword);
		dbg("temp_D_word = %x\n", temp_dword);

		if (temp_dword != 0xFFFFFFFF) {
			index = 0;
			func = cpqhp_slot_find(primary_bus, dev_func >> 3, 0);

			while (func && (func->function != (dev_func & 0x07))) {
				dbg("func = %p (bus, dev, fun) = (%d, %d, %d)\n", func, primary_bus, dev_func >> 3, index);
				func = cpqhp_slot_find(primary_bus, dev_func >> 3, index++);
			}

			/* If we can't find a match, skip this table entry */
			if (!func) {
				i--;
				one_slot += sizeof(struct slot_rt);
				continue;
			}
			/* this may not work and shouldn't be used */
			if (secondary_bus != primary_bus)
				bridged_slot = 1;
			else
				bridged_slot = 0;

			populated_slot = 1;
		} else {
			populated_slot = 0;
			bridged_slot = 0;
		}


		/* If we've got a valid IO base, use it */

		temp_dword = io_base + io_length;

		if ((io_base) && (temp_dword < 0x10000)) {
			io_node = kmalloc_obj(*io_node);
			if (!io_node)
				return -ENOMEM;

			io_node->base = io_base;
			io_node->length = io_length;

			dbg("found io_node(base, length) = %x, %x\n",
					io_node->base, io_node->length);
			dbg("populated slot = %d\n", populated_slot);
			if (!populated_slot) {
				io_node->next = ctrl->io_head;
				ctrl->io_head = io_node;
			} else {
				io_node->next = func->io_head;
				func->io_head = io_node;
			}
		}

		/* If we've got a valid memory base, use it */
		temp_dword = mem_base + mem_length;
		if ((mem_base) && (temp_dword < 0x10000)) {
			mem_node = kmalloc_obj(*mem_node);
			if (!mem_node)
				return -ENOMEM;

			mem_node->base = mem_base << 16;

			mem_node->length = mem_length << 16;

			dbg("found mem_node(base, length) = %x, %x\n",
					mem_node->base, mem_node->length);
			dbg("populated slot = %d\n", populated_slot);
			if (!populated_slot) {
				mem_node->next = ctrl->mem_head;
				ctrl->mem_head = mem_node;
			} else {
				mem_node->next = func->mem_head;
				func->mem_head = mem_node;
			}
		}

		/* If we've got a valid prefetchable memory base, and
		 * the base + length isn't greater than 0xFFFF
		 */
		temp_dword = pre_mem_base + pre_mem_length;
		if ((pre_mem_base) && (temp_dword < 0x10000)) {
			p_mem_node = kmalloc_obj(*p_mem_node);
			if (!p_mem_node)
				return -ENOMEM;

			p_mem_node->base = pre_mem_base << 16;

			p_mem_node->length = pre_mem_length << 16;
			dbg("found p_mem_node(base, length) = %x, %x\n",
					p_mem_node->base, p_mem_node->length);
			dbg("populated slot = %d\n", populated_slot);

			if (!populated_slot) {
				p_mem_node->next = ctrl->p_mem_head;
				ctrl->p_mem_head = p_mem_node;
			} else {
				p_mem_node->next = func->p_mem_head;
				func->p_mem_head = p_mem_node;
			}
		}

		/* If we've got a valid bus number, use it
		 * The second condition is to ignore bus numbers on
		 * populated slots that don't have PCI-PCI bridges
		 */
		if (secondary_bus && (secondary_bus != primary_bus)) {
			bus_node = kmalloc_obj(*bus_node);
			if (!bus_node)
				return -ENOMEM;

			bus_node->base = secondary_bus;
			bus_node->length = max_bus - secondary_bus + 1;
			dbg("found bus_node(base, length) = %x, %x\n",
					bus_node->base, bus_node->length);
			dbg("populated slot = %d\n", populated_slot);
			if (!populated_slot) {
				bus_node->next = ctrl->bus_head;
				ctrl->bus_head = bus_node;
			} else {
				bus_node->next = func->bus_head;
				func->bus_head = bus_node;
			}
		}

		i--;
		one_slot += sizeof(struct slot_rt);
	}

	/* If all of the following fail, we don't have any resources for
	 * hot plug add
	 */
	rc = 1;
	rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
	rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
	rc &= cpqhp_resource_sort_and_combine(&(ctrl->io_head));
	rc &= cpqhp_resource_sort_and_combine(&(ctrl->bus_head));

	return rc;
}


/*
 * cpqhp_return_board_resources
 *
 * this routine returns all resources allocated to a board to
 * the available pool.
 *
 * returns 0 if success
 */
int cpqhp_return_board_resources(struct pci_func *func, struct resource_lists *resources)
{
	int rc = 0;
	struct pci_resource *node;
	struct pci_resource *t_node;
	dbg("%s\n", __func__);

	if (!func)
		return 1;

	node = func->io_head;
	func->io_head = NULL;
	while (node) {
		t_node = node->next;
		return_resource(&(resources->io_head), node);
		node = t_node;
	}

	node = func->mem_head;
	func->mem_head = NULL;
	while (node) {
		t_node = node->next;
		return_resource(&(resources->mem_head), node);
		node = t_node;
	}

	node = func->p_mem_head;
	func->p_mem_head = NULL;
	while (node) {
		t_node = node->next;
		return_resource(&(resources->p_mem_head), node);
		node = t_node;
	}

	node = func->bus_head;
	func->bus_head = NULL;
	while (node) {
		t_node = node->next;
		return_resource(&(resources->bus_head), node);
		node = t_node;
	}

	rc |= cpqhp_resource_sort_and_combine(&(resources->mem_head));
	rc |= cpqhp_resource_sort_and_combine(&(resources->p_mem_head));
	rc |= cpqhp_resource_sort_and_combine(&(resources->io_head));
	rc |= cpqhp_resource_sort_and_combine(&(resources->bus_head));

	return rc;
}


/*
 * cpqhp_destroy_resource_list
 *
 * Puts node back in the resource list pointed to by head
 */
void cpqhp_destroy_resource_list(struct resource_lists *resources)
{
	struct pci_resource *res, *tres;

	res = resources->io_head;
	resources->io_head = NULL;

	while (res) {
		tres = res;
		res = res->next;
		kfree(tres);
	}

	res = resources->mem_head;
	resources->mem_head = NULL;

	while (res) {
		tres = res;
		res = res->next;
		kfree(tres);
	}

	res = resources->p_mem_head;
	resources->p_mem_head = NULL;

	while (res) {
		tres = res;
		res = res->next;
		kfree(tres);
	}

	res = resources->bus_head;
	resources->bus_head = NULL;

	while (res) {
		tres = res;
		res = res->next;
		kfree(tres);
	}
}


/*
 * cpqhp_destroy_board_resources
 *
 * Puts node back in the resource list pointed to by head
 */
void cpqhp_destroy_board_resources(struct pci_func *func)
{
	struct pci_resource *res, *tres;

	res = func->io_head;
	func->io_head = NULL;

	while (res) {
		tres = res;
		res = res->next;
		kfree(tres);
	}

	res = func->mem_head;
	func->mem_head = NULL;

	while (res) {
		tres = res;
		res = res->next;
		kfree(tres);
	}

	res = func->p_mem_head;
	func->p_mem_head = NULL;

	while (res) {
		tres = res;
		res = res->next;
		kfree(tres);
	}

	res = func->bus_head;
	func->bus_head = NULL;

	while (res) {
		tres = res;
		res = res->next;
		kfree(tres);
	}
}
