From dbd7a78818d125a0ebd5507d4edb4dd5900006ab Mon Sep 17 00:00:00 2001 From: "rajesh.shah@intel.com" Date: Thu, 13 Oct 2005 12:05:36 -0700 Subject: [PATCH] shpchp: use the PCI core for hotplug resource management This patch converts the standard hotplug controller driver to use the PCI core for resource management. This eliminates a whole lot of duplicated code, and integrates shpchp in the system's normal PCI handling code. Signed-off-by: Rajesh Shah Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchprm_legacy.c | 294 ---------------------------------- 1 file changed, 294 deletions(-) (limited to 'drivers/pci/hotplug/shpchprm_legacy.c') diff --git a/drivers/pci/hotplug/shpchprm_legacy.c b/drivers/pci/hotplug/shpchprm_legacy.c index ba6c549c9b9..6c27debe952 100644 --- a/drivers/pci/hotplug/shpchprm_legacy.c +++ b/drivers/pci/hotplug/shpchprm_legacy.c @@ -34,25 +34,11 @@ #include #include #include -#ifdef CONFIG_IA64 -#include -#endif #include "shpchp.h" #include "shpchprm.h" -#include "shpchprm_legacy.h" - -static void __iomem *shpchp_rom_start; -static u16 unused_IRQ; void shpchprm_cleanup(void) { - if (shpchp_rom_start) - iounmap(shpchp_rom_start); -} - -int shpchprm_print_pirt(void) -{ - return 0; } int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) @@ -63,280 +49,6 @@ int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busn return 0; } -/* 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; -} - -/* - * shpchprm_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 shpchprm_find_available_resources(struct controller *ctrl) -{ - u8 populated_slot; - u8 bridged_slot; - void __iomem *one_slot; - struct pci_func *func = NULL; - int i = 10, index = 0; - u32 temp_dword, rc; - ulong temp_ulong; - struct pci_resource *mem_node; - struct pci_resource *p_mem_node; - struct pci_resource *io_node; - struct pci_resource *bus_node; - void __iomem *rom_resource_table; - struct pci_bus lpci_bus, *pci_bus; - u8 cfgspc_irq, temp; - - memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus)); - pci_bus = &lpci_bus; - rom_resource_table = detect_HRT_floating_pointer(shpchp_rom_start, shpchp_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) { - shpchp_disk_irq = temp; - break; - } - unused_IRQ = unused_IRQ >> 1; - temp++; - } - - dbg("shpchp_disk_irq= %d\n", shpchp_disk_irq); - unused_IRQ = unused_IRQ >> 1; - temp++; - - while (unused_IRQ) { - if (unused_IRQ & 1) { - shpchp_nic_irq = temp; - break; - } - unused_IRQ = unused_IRQ >> 1; - temp++; - } - - dbg("shpchp_nic_irq= %d\n", shpchp_nic_irq); - unused_IRQ = readl(rom_resource_table + PCIIRQ); - - temp = 0; - - pci_read_config_byte(ctrl->pci_dev, PCI_INTERRUPT_LINE, &cfgspc_irq); - - if (!shpchp_nic_irq) { - shpchp_nic_irq = cfgspc_irq; - } - - if (!shpchp_disk_irq) { - shpchp_disk_irq = cfgspc_irq; - } - - dbg("shpchp_disk_irq, shpchp_nic_irq= %d, %d\n", shpchp_disk_irq, shpchp_nic_irq); - - 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|MEMbase|length|PM 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->slot_bus) { - i--; - one_slot += sizeof(struct slot_rt); - continue; - } - /* find out if this entry is for an occupied slot */ - temp_dword = 0xFFFFFFFF; - pci_bus->number = primary_bus; - pci_bus_read_config_dword(pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword); - - dbg("temp_D_word = %x\n", temp_dword); - - if (temp_dword != 0xFFFFFFFF) { - index = 0; - func = shpchp_slot_find(primary_bus, dev_func >> 3, 0); - - while (func && (func->function != (dev_func & 0x07))) { - dbg("func = %p b:d:f(%x:%x:%x)\n", func, primary_bus, dev_func >> 3, index); - func = shpchp_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; - } - dbg("slot populated =%s \n", populated_slot?"yes":"no"); - - /* If we've got a valid IO base, use it */ - - temp_ulong = io_base + io_length; - - if ((io_base) && (temp_ulong <= 0x10000)) { - io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); - if (!io_node) - return -ENOMEM; - - io_node->base = (ulong)io_base; - io_node->length = (ulong)io_length; - dbg("found io_node(base, length) = %x, %x\n", io_node->base, io_node->length); - - 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_ulong = mem_base + mem_length; - if ((mem_base) && (temp_ulong <= 0x10000)) { - mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); - if (!mem_node) - return -ENOMEM; - - mem_node->base = (ulong)mem_base << 16; - mem_node->length = (ulong)(mem_length << 16); - dbg("found mem_node(base, length) = %x, %x\n", mem_node->base, mem_node->length); - - 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_ulong = pre_mem_base + pre_mem_length; - if ((pre_mem_base) && (temp_ulong <= 0x10000)) { - p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); - if (!p_mem_node) - return -ENOMEM; - - p_mem_node->base = (ulong)pre_mem_base << 16; - p_mem_node->length = (ulong)pre_mem_length << 16; - dbg("found p_mem_node(base, length) = %x, %x\n", p_mem_node->base, p_mem_node->length); - - 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 = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); - if (!bus_node) - return -ENOMEM; - - bus_node->base = (ulong)secondary_bus; - bus_node->length = (ulong)(max_bus - secondary_bus + 1); - dbg("found bus_node(base, length) = %x, %x\n", bus_node->base, bus_node->length); - - 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 &= shpchp_resource_sort_and_combine(&(ctrl->mem_head)); - rc &= shpchp_resource_sort_and_combine(&(ctrl->p_mem_head)); - rc &= shpchp_resource_sort_and_combine(&(ctrl->io_head)); - rc &= shpchp_resource_sort_and_combine(&(ctrl->bus_head)); - - return (rc); -} - int shpchprm_set_hpp( struct controller *ctrl, struct pci_func *func, @@ -413,12 +125,6 @@ void shpchprm_enable_card( static int legacy_shpchprm_init_pci(void) { - shpchp_rom_start = ioremap(ROM_PHY_ADDR, ROM_PHY_LEN); - if (!shpchp_rom_start) { - err("Could not ioremap memory region for ROM\n"); - return -EIO; - } - return 0; } -- cgit v1.2.3 From 424600f9706b20a8a33ad928d3d0326bd88679bc Mon Sep 17 00:00:00 2001 From: "rajesh.shah@intel.com" Date: Thu, 13 Oct 2005 12:05:38 -0700 Subject: [PATCH] shpchp: reduce dependence on ACPI Reduce the SHPC hotplug driver's dependence on ACPI. We don't walk the acpi namespace anymore to build a list of bridges and devices. The remaining interaction with ACPI is to run the _OSHP method to transition control of hotplug hardware from system BIOS to the shpc hotplug driver, and to run the _HPP method to get hotplug device parameters like cache line size, latency timer and SERR/PERR enable from BIOS. Note that one of the side effects of this patch is that shpchp does not enable the hot-added device or its DMA bus mastering automatically now. It expects the device driver to do that. This may break some drivers and we will have to fix them as they are reported. Signed-off-by: Rajesh Shah Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchprm_legacy.c | 97 ++--------------------------------- 1 file changed, 5 insertions(+), 92 deletions(-) (limited to 'drivers/pci/hotplug/shpchprm_legacy.c') diff --git a/drivers/pci/hotplug/shpchprm_legacy.c b/drivers/pci/hotplug/shpchprm_legacy.c index 6c27debe952..cfc6092e2af 100644 --- a/drivers/pci/hotplug/shpchprm_legacy.c +++ b/drivers/pci/hotplug/shpchprm_legacy.c @@ -37,10 +37,6 @@ #include "shpchp.h" #include "shpchprm.h" -void shpchprm_cleanup(void) -{ -} - int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) { int offset = devnum - ctrl->slot_device_offset; @@ -49,97 +45,14 @@ int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busn return 0; } -int shpchprm_set_hpp( - struct controller *ctrl, - struct pci_func *func, - u8 card_type) +void get_hp_params_from_firmware(struct pci_dev *dev, + struct hotplug_params *hpp) { - u32 rc; - u8 temp_byte; - struct pci_bus lpci_bus, *pci_bus; - unsigned int devfn; - memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus)); - pci_bus = &lpci_bus; - pci_bus->number = func->bus; - devfn = PCI_DEVFN(func->device, func->function); - - temp_byte = 0x40; /* hard coded value for LT */ - if (card_type == PCI_HEADER_TYPE_BRIDGE) { - /* set subordinate Latency Timer */ - rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte); - if (rc) { - dbg("%s: set secondary LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, - func->device, func->function); - return rc; - } - } - - /* set base Latency Timer */ - rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte); - if (rc) { - dbg("%s: set LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function); - return rc; - } - - /* set Cache Line size */ - temp_byte = 0x08; /* hard coded value for CLS */ - rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte); - if (rc) { - dbg("%s: set CLS error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function); - } - - /* set enable_perr */ - /* set enable_serr */ - - return rc; + return; } -void shpchprm_enable_card( - struct controller *ctrl, - struct pci_func *func, - u8 card_type) +void get_hp_hw_control_from_firmware(struct pci_dev *dev) { - u16 command, bcommand; - struct pci_bus lpci_bus, *pci_bus; - unsigned int devfn; - int rc; - - memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus)); - pci_bus = &lpci_bus; - pci_bus->number = func->bus; - devfn = PCI_DEVFN(func->device, func->function); - - rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command); - command |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR - | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE - | PCI_COMMAND_IO | PCI_COMMAND_MEMORY; - rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command); - - if (card_type == PCI_HEADER_TYPE_BRIDGE) { - rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand); - bcommand |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR - | PCI_BRIDGE_CTL_NO_ISA; - rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand); - } -} - -static int legacy_shpchprm_init_pci(void) -{ - return 0; + return; } -int shpchprm_init(enum php_ctlr_type ctrl_type) -{ - int retval; - - switch (ctrl_type) { - case PCI: - retval = legacy_shpchprm_init_pci(); - break; - default: - retval = -ENODEV; - break; - } - - return retval; -} -- cgit v1.2.3 From ee138334d5eb5ca662b2d69228420c1ccc051e0e Mon Sep 17 00:00:00 2001 From: "rajesh.shah@intel.com" Date: Thu, 13 Oct 2005 12:05:42 -0700 Subject: [PATCH] shpchp: miscellaneous cleanups Remove un-necessary header includes, remove dead code, remove some type casts, receive function return in the correct data type... Signed-off-by: Rajesh Shah Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchprm_legacy.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/pci/hotplug/shpchprm_legacy.c') diff --git a/drivers/pci/hotplug/shpchprm_legacy.c b/drivers/pci/hotplug/shpchprm_legacy.c index cfc6092e2af..ed6c1254bf6 100644 --- a/drivers/pci/hotplug/shpchprm_legacy.c +++ b/drivers/pci/hotplug/shpchprm_legacy.c @@ -27,15 +27,11 @@ * */ -#include #include #include #include #include -#include -#include #include "shpchp.h" -#include "shpchprm.h" int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) { -- cgit v1.2.3