ChangeSet 1.1451.1.1, 2004/07/30 13:39:32-07:00, dlsy@snoqualmie.dp.intel.com [PATCH] PCI Hotplug: Fixes for hot-plug drivers in 2.4 kernel Here is the 2.4 patch (against 2.4.27-rc2) for the shpchp and pciehp drivers. This patch has the same fixes as in the last 2.6.7 patch that I sent you and is now in the 2.6 kernel tree. Also, this patch removes the flag CONFIG_PCI_USE_VECTOR, the pci_enable_msi() and chipset fix for MSI, which were in the last 2.4 patch, because MSI and vector-based interrupt is not in 2.4 kernel. I cleaned up some debug prints and uncommented the pci_enable_device() in pciehp driver for some adapter drivers that don't call this API. arch/i386/kernel/pci-irq.c | 4 - drivers/hotplug/pciehp.h | 2 drivers/hotplug/pciehp_ctrl.c | 146 ++++++++++++------------------------- drivers/hotplug/pciehp_hpc.c | 29 +------ drivers/hotplug/pciehp_pci.c | 4 - drivers/hotplug/pciehprm_acpi.c | 22 ++++- drivers/hotplug/pciehprm_nonacpi.c | 18 +++- drivers/hotplug/shpchp.h | 1 drivers/hotplug/shpchp_ctrl.c | 54 +++++-------- drivers/hotplug/shpchp_hpc.c | 10 -- drivers/hotplug/shpchp_pci.c | 1 drivers/hotplug/shpchprm_acpi.c | 22 ++++- drivers/hotplug/shpchprm_nonacpi.c | 18 +++- drivers/pci/pci.c | 1 drivers/pci/quirks.c | 9 -- include/linux/pci.h | 2 16 files changed, 135 insertions(+), 208 deletions(-) diff -Nru a/arch/i386/kernel/pci-irq.c b/arch/i386/kernel/pci-irq.c --- a/arch/i386/kernel/pci-irq.c 2004-08-23 15:07:00 -07:00 +++ b/arch/i386/kernel/pci-irq.c 2004-08-23 15:07:00 -07:00 @@ -1103,10 +1103,6 @@ } dev = temp_dev; if (irq >= 0) { -#ifdef CONFIG_PCI_USE_VECTOR - if (!platform_legacy_irq(irq)) - irq = IO_APIC_VECTOR(irq); -#endif printk(KERN_INFO "PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n", dev->bus->number, PCI_SLOT(dev->devfn), pin, irq); dev->irq = irq; diff -Nru a/drivers/hotplug/pciehp.h b/drivers/hotplug/pciehp.h --- a/drivers/hotplug/pciehp.h 2004-08-23 15:07:00 -07:00 +++ b/drivers/hotplug/pciehp.h 2004-08-23 15:07:00 -07:00 @@ -45,8 +45,6 @@ extern int pciehp_poll_time; extern int pciehp_debug; -extern int pciehp_msi_quirk; - /*#define dbg(format, arg...) do { if (pciehp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/ #define dbg(format, arg...) do { if (pciehp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0) #define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg) diff -Nru a/drivers/hotplug/pciehp_ctrl.c b/drivers/hotplug/pciehp_ctrl.c --- a/drivers/hotplug/pciehp_ctrl.c 2004-08-23 15:07:00 -07:00 +++ b/drivers/hotplug/pciehp_ctrl.c 2004-08-23 15:07:00 -07:00 @@ -1053,6 +1053,34 @@ hotplug controller logic */ +static void set_slot_off(struct controller *ctrl, struct slot * pslot) +{ + /* Wait for exclusive access to hardware */ + down(&ctrl->crit_sect); + + /* turn off slot, turn on Amber LED, turn off Green LED */ + if (pslot->hpc_ops->power_off_slot(pslot)) { + err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__); + up(&ctrl->crit_sect); + return; + } + wait_for_ctrl_irq (ctrl); + + pslot->hpc_ops->green_led_off(pslot); + + wait_for_ctrl_irq (ctrl); + + /* turn on Amber LED */ + if (pslot->hpc_ops->set_attention_status(pslot, 1)) { + err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__); + up(&ctrl->crit_sect); + return; + } + wait_for_ctrl_irq (ctrl); + + /* Done with exclusive hardware access */ + up(&ctrl->crit_sect); +} /** * board_added - Called after a board has been added to the system. @@ -1066,7 +1094,7 @@ u8 hp_slot; int index; u32 temp_register = 0xFFFFFFFF; - u32 retval, rc = 0; + u32 rc = 0; struct pci_func *new_func = NULL; struct slot *p_slot; struct resource_lists res_lists; @@ -1082,8 +1110,10 @@ /* Power on slot */ rc = p_slot->hpc_ops->power_on_slot(p_slot); - if (rc) + if (rc) { + up(&ctrl->crit_sect); return -1; + } /* Wait for the command to complete */ wait_for_ctrl_irq(ctrl); @@ -1105,10 +1135,11 @@ dbg("%s: afterlong_delay\n", __FUNCTION__); dbg("%s: before check link status", __FUNCTION__); - /* Make this to check for link training status */ + /* Check link training status */ rc = p_slot->hpc_ops->check_lnk_status(ctrl); if (rc) { err("%s: Failed to check link status\n", __FUNCTION__); + set_slot_off(ctrl, p_slot); return -1; } @@ -1161,36 +1192,7 @@ pciehp_resource_sort_and_combine(&(ctrl->bus_head)); if (rc) { - /* Wait for exclusive access to hardware */ - down(&ctrl->crit_sect); - - /* Turn off slot, turn on Amber LED, turn off Green LED */ - retval = p_slot->hpc_ops->power_off_slot(p_slot); - /* In PCI Express, just power off slot */ - if (retval) { - err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__); - return retval; - } - /* Wait for the command to complete */ - wait_for_ctrl_irq(ctrl); - - p_slot->hpc_ops->green_led_off(p_slot); - - /* Wait for the command to complete */ - wait_for_ctrl_irq(ctrl); - - /* Turn on Amber LED */ - retval = p_slot->hpc_ops->set_attention_status(p_slot, 1); - if (retval) { - err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__); - return retval; - } - /* Wait for the command to complete */ - wait_for_ctrl_irq(ctrl); - - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - + set_slot_off(ctrl, p_slot); return(rc); } pciehp_save_slot_config(ctrl, func); @@ -1220,42 +1222,12 @@ /* Wait for the command to complete */ wait_for_ctrl_irq(ctrl); - /* Done with exclusive hardware access */ up(&ctrl->crit_sect); } else { - /* Wait for exclusive access to hardware */ - down(&ctrl->crit_sect); - - /* Turn off slot, turn on Amber LED, turn off Green LED */ - retval = p_slot->hpc_ops->power_off_slot(p_slot); - /* In PCI Express, just power off slot */ - if (retval) { - err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__); - return retval; - } - /* Wait for the command to complete */ - wait_for_ctrl_irq(ctrl); - - p_slot->hpc_ops->green_led_off(p_slot); - - /* Wait for the command to complete */ - wait_for_ctrl_irq(ctrl); - - /* Turn on Amber LED */ - retval = p_slot->hpc_ops->set_attention_status(p_slot, 1); - if (retval) { - err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__); - return retval; - } - /* Wait for the command to complete */ - wait_for_ctrl_irq(ctrl); - - /* Done with exclusive hardware access */ - up(&ctrl->crit_sect); - - return(rc); + set_slot_off(ctrl, p_slot); + return -1; } return 0; } @@ -1323,6 +1295,7 @@ rc = p_slot->hpc_ops->power_off_slot(p_slot); if (rc) { err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); + up(&ctrl->crit_sect); return rc; } /* Wait for the command to complete */ @@ -1592,7 +1565,10 @@ down(&ctrl->crit_sect); p_slot->hpc_ops->set_attention_status(p_slot, 1); + wait_for_ctrl_irq(ctrl); + p_slot->hpc_ops->green_led_off(p_slot); + wait_for_ctrl_irq(ctrl); /* Done with exclusive hardware access */ up(&ctrl->crit_sect); @@ -1624,7 +1600,6 @@ { struct slot *p_slot = (struct slot *) slot; u8 getstatus; - int rc; pushbutton_pending = 0; @@ -1638,23 +1613,7 @@ p_slot->state = POWEROFF_STATE; dbg("In power_down_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device); - if (pciehp_disable_slot(p_slot)) { - /* Wait for exclusive access to hardware */ - down(&p_slot->ctrl->crit_sect); - - /* Turn on the Attention LED */ - rc = p_slot->hpc_ops->set_attention_status(p_slot, 1); - if (rc) { - err("%s: Issue of Set Atten Indicator On command failed\n", __FUNCTION__); - return; - } - - /* Wait for the command to complete */ - wait_for_ctrl_irq (p_slot->ctrl); - - /* Done with exclusive hardware access */ - up(&p_slot->ctrl->crit_sect); - } + pciehp_disable_slot(p_slot); p_slot->state = STATIC_STATE; } else { p_slot->state = POWERON_STATE; @@ -1664,15 +1623,6 @@ /* Wait for exclusive access to hardware */ down(&p_slot->ctrl->crit_sect); - /* Turn off the green LED */ - rc = p_slot->hpc_ops->set_attention_status(p_slot, 1); - if (rc) { - err("%s: Issue of Set Attn Indicator On command failed\n", __FUNCTION__); - return; - } - /* Wait for the command to complete */ - wait_for_ctrl_irq (p_slot->ctrl); - p_slot->hpc_ops->green_led_off(p_slot); /* Wait for the command to complete */ @@ -1706,21 +1656,21 @@ if (rc || !getstatus) { info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return (1); } rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (rc || getstatus) { info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return (1); } rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (rc || getstatus) { info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return (1); } up(&p_slot->ctrl->crit_sect); @@ -1793,21 +1743,21 @@ if (ret || !getstatus) { info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return (1); } ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (ret || getstatus) { info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return (1); } ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (ret || !getstatus) { info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return (1); } up(&p_slot->ctrl->crit_sect); diff -Nru a/drivers/hotplug/pciehp_hpc.c b/drivers/hotplug/pciehp_hpc.c --- a/drivers/hotplug/pciehp_hpc.c 2004-08-23 15:07:00 -07:00 +++ b/drivers/hotplug/pciehp_hpc.c 2004-08-23 15:07:00 -07:00 @@ -346,10 +346,11 @@ return retval; } - if ( (lnk_status & (LNK_TRN | LNK_TRN_ERR)) == 0x0C00) { + dbg("%s: lnk_status = %x\n", __FUNCTION__, lnk_status); + if ( (lnk_status & LNK_TRN) || (lnk_status & LNK_TRN_ERR) || + !(lnk_status & NEG_LINK_WD)) { err("%s : Link Training Error occurs \n", __FUNCTION__); - retval = -1; - return retval; + return -1; } DBG_LEAVE_ROUTINE @@ -911,7 +912,6 @@ err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); return; } - /* dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status); */ intr_detect = ( ATTN_BUTTN_PRESSED | PWR_FAULT_DETECTED | MRL_SENS_CHANGED | PRSN_DETECT_CHANGED | CMD_COMPLETED ); @@ -932,8 +932,6 @@ return; } - dbg("%s: Set Mask Hot-plug Interrupt Enable\n", __FUNCTION__); - dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word); @@ -941,14 +939,12 @@ err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); return; } - dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); if (rc) { err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); return; } - dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status); /* Clear command complete interrupt caused by this write */ temp_word = 0x1f; @@ -957,7 +953,6 @@ err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); return; } - dbg("%s: hp_register_write_word SLOT_STATUS with value %x\n", __FUNCTION__, temp_word); } if (intr_loc & CMD_COMPLETED) { @@ -995,8 +990,6 @@ err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); return; } - dbg("%s: Unmask Hot-plug Interrupt Enable\n", __FUNCTION__); - dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE; rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word); @@ -1004,14 +997,12 @@ err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); return; } - dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); if (rc) { err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); return; } - dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status); /* Clear command complete interrupt caused by this write */ temp_word = 0x1F; @@ -1020,7 +1011,6 @@ err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); return; } - dbg("%s: hp_register_write_word SLOT_STATUS with value %x\n", __FUNCTION__, temp_word); } return; } @@ -1409,17 +1399,6 @@ start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */ } else { /* Installs the interrupt handler */ -#ifdef CONFIG_PCI_USE_VECTOR - if (!pciehp_msi_quirk) { - rc = pci_enable_msi(pdev); - if (rc) { - info("Can't get msi for the hotplug controller\n"); - info("Use INTx for the hotplug controller\n"); - dbg("%s: rc = %x\n", __FUNCTION__, rc); - } else - php_ctlr->irq = pdev->irq; - } -#endif rc = request_irq(php_ctlr->irq, pcie_isr, SA_SHIRQ, MY_NAME, (void *) ctrl); dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc); if (rc) { diff -Nru a/drivers/hotplug/pciehp_pci.c b/drivers/hotplug/pciehp_pci.c --- a/drivers/hotplug/pciehp_pci.c 2004-08-23 15:07:00 -07:00 +++ b/drivers/hotplug/pciehp_pci.c 2004-08-23 15:07:00 -07:00 @@ -117,9 +117,7 @@ temp_func->pci_dev->bus->number, temp_func->pci_dev->devfn); dbg("%s: PCI_SLOT_NAME=%s\n", __FUNCTION__, temp_func->pci_dev->slot_name); - //pci_enable_device(temp_func->pci_dev); - //dbg("%s: after calling pci_enable_device, irq = %x\n", - // __FUNCTION__, temp_func->pci_dev->irq); + pci_enable_device(temp_func->pci_dev); pci_proc_attach_device(temp_func->pci_dev); pci_announce_device_to_drivers(temp_func->pci_dev); } diff -Nru a/drivers/hotplug/pciehprm_acpi.c b/drivers/hotplug/pciehprm_acpi.c --- a/drivers/hotplug/pciehprm_acpi.c 2004-08-23 15:07:00 -07:00 +++ b/drivers/hotplug/pciehprm_acpi.c 2004-08-23 15:07:00 -07:00 @@ -217,6 +217,10 @@ } ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL); + if (!ab->_hpp) { + err ("acpi_pciehprm:%s alloc for _HPP failed\n", path_name); + goto free_and_return; + } memset(ab->_hpp, 0, sizeof(struct acpi__hpp)); ab->_hpp->cache_line_size = nui[0]; @@ -1392,7 +1396,7 @@ static int bind_pci_resources_to_slots ( struct controller *ctrl) { - struct pci_func *func; + struct pci_func *func, new_func; int busn = ctrl->slot_bus; int devn, funn; u32 vid; @@ -1411,11 +1415,19 @@ if (vid != 0xFFFFFFFF) { dbg("%s: vid = %x\n", __FUNCTION__, vid); func = pciehp_slot_find(busn, devn, funn); - if (!func) - continue; - configure_existing_function(ctrl, func); + if (!func) { + memset(&new_func, 0, sizeof(struct pci_func)); + new_func.bus = busn; + new_func.device = devn; + new_func.function = funn; + new_func.is_a_board = 1; + configure_existing_function(ctrl, &new_func); + pciehprm_dump_func_res(&new_func); + } else { + configure_existing_function(ctrl, func); + pciehprm_dump_func_res(func); + } dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus); - pciehprm_dump_func_res(func); } } } diff -Nru a/drivers/hotplug/pciehprm_nonacpi.c b/drivers/hotplug/pciehprm_nonacpi.c --- a/drivers/hotplug/pciehprm_nonacpi.c 2004-08-23 15:07:00 -07:00 +++ b/drivers/hotplug/pciehprm_nonacpi.c 2004-08-23 15:07:00 -07:00 @@ -281,7 +281,7 @@ static int bind_pci_resources_to_slots ( struct controller *ctrl) { - struct pci_func *func; + struct pci_func *func, new_func; int busn = ctrl->slot_bus; int devn, funn; u32 vid; @@ -301,11 +301,19 @@ vid, busn, devn, funn); func = pciehp_slot_find(busn, devn, funn); dbg("%s: func = %p\n", __FUNCTION__,func); - if (!func) - continue; - configure_existing_function(ctrl, func); + if (!func) { + memset(&new_func, 0, sizeof(struct pci_func)); + new_func.bus = busn; + new_func.device = devn; + new_func.function = funn; + new_func.is_a_board = 1; + configure_existing_function(ctrl, &new_func); + phprm_dump_func_res(&new_func); + } else { + configure_existing_function(ctrl, func); + phprm_dump_func_res(func); + } dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus); - phprm_dump_func_res(func); } } } diff -Nru a/drivers/hotplug/shpchp.h b/drivers/hotplug/shpchp.h --- a/drivers/hotplug/shpchp.h 2004-08-23 15:07:00 -07:00 +++ b/drivers/hotplug/shpchp.h 2004-08-23 15:07:00 -07:00 @@ -61,6 +61,7 @@ u8 configured; u8 switch_save; u8 presence_save; + u8 pwr_save; u32 base_length[0x06]; u8 base_type[0x06]; u16 reserved2; diff -Nru a/drivers/hotplug/shpchp_ctrl.c b/drivers/hotplug/shpchp_ctrl.c --- a/drivers/hotplug/shpchp_ctrl.c 2004-08-23 15:07:00 -07:00 +++ b/drivers/hotplug/shpchp_ctrl.c 2004-08-23 15:07:00 -07:00 @@ -137,6 +137,8 @@ p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save)); p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); + dbg("%s: Card present %x Power status %x\n", __FUNCTION__, + func->presence_save, func->pwr_save); if (getstatus) { /* @@ -145,6 +147,10 @@ info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot); func->switch_save = 0; taskInfo->event_type = INT_SWITCH_OPEN; + if (func->pwr_save && func->presence_save) { + taskInfo->event_type = INT_POWER_FAULT; + err("Surprise Removal of card\n"); + } } else { /* * Switch closed @@ -1431,6 +1437,7 @@ rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, adapter_speed); if (rc) { err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__); + up(&ctrl->crit_sect); return WRONG_BUS_FREQUENCY; } @@ -1442,6 +1449,7 @@ err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n", __FUNCTION__); err("%s: Error code (%d)\n", __FUNCTION__, rc); + up(&ctrl->crit_sect); return WRONG_BUS_FREQUENCY; } /* Done with exclusive hardware access */ @@ -1592,7 +1600,8 @@ func->status = 0; func->switch_save = 0x10; func->is_a_board = 0x01; - + func->pwr_save = 1; + /* Next, we will instantiate the linux pci_dev structures * (with appropriate driver notification, if already present) */ @@ -1785,6 +1794,7 @@ func->function = 0; func->configured = 0; func->switch_save = 0x10; + func->pwr_save = 0; func->is_a_board = 0; } @@ -2038,7 +2048,6 @@ { struct slot *p_slot = (struct slot *) slot; u8 getstatus; - int rc; pushbutton_pending = 0; @@ -2052,23 +2061,7 @@ p_slot->state = POWEROFF_STATE; dbg("In power_down_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device); - if (shpchp_disable_slot(p_slot)) { - /* Wait for exclusive access to hardware */ - down(&p_slot->ctrl->crit_sect); - - /* Turn on the Attention LED */ - rc = p_slot->hpc_ops->set_attention_status(p_slot, 1); - if (rc) { - err("%s: Issue of Set Atten Indicator On command failed\n", __FUNCTION__); - return; - } - - /* Wait for the command to complete */ - wait_for_ctrl_irq(p_slot->ctrl); - - /* Done with exclusive hardware access */ - up(&p_slot->ctrl->crit_sect); - } + shpchp_disable_slot(p_slot); p_slot->state = STATIC_STATE; } else { p_slot->state = POWERON_STATE; @@ -2078,15 +2071,6 @@ /* Wait for exclusive access to hardware */ down(&p_slot->ctrl->crit_sect); - /* Turn off the green LED */ - rc = p_slot->hpc_ops->set_attention_status(p_slot, 1); - if (rc) { - err("%s: Issue of Set Atten Indicator On command failed\n", __FUNCTION__); - return; - } - /* Wait for the command to complete */ - wait_for_ctrl_irq(p_slot->ctrl); - p_slot->hpc_ops->green_led_off(p_slot); /* Wait for the command to complete */ @@ -2120,19 +2104,19 @@ if (rc || !getstatus) { info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return (1); } rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (rc || getstatus) { info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return (1); } rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (rc || getstatus) { info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return (1); } up(&p_slot->ctrl->crit_sect); @@ -2150,6 +2134,8 @@ /* We have to save the presence info for these slots */ p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save)); + p_slot->hpc_ops->get_power_status(p_slot, &(func->pwr_save)); + dbg("%s: func->pwr_save %x\n", __FUNCTION__, func->pwr_save); p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); func->switch_save = !getstatus? 0x10:0; @@ -2205,19 +2191,19 @@ if (ret || !getstatus) { info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return (1); } ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (ret || getstatus) { info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return (1); } ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (ret || !getstatus) { info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); - return (0); + return (1); } up(&p_slot->ctrl->crit_sect); diff -Nru a/drivers/hotplug/shpchp_hpc.c b/drivers/hotplug/shpchp_hpc.c --- a/drivers/hotplug/shpchp_hpc.c 2004-08-23 15:07:00 -07:00 +++ b/drivers/hotplug/shpchp_hpc.c 2004-08-23 15:07:00 -07:00 @@ -1547,15 +1547,6 @@ start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */ } else { /* Installs the interrupt handler */ -#ifdef CONFIG_PCI_USE_VECTOR - rc = pci_enable_msi(pdev); - if (rc) { - info("Can't get msi for the hotplug controller\n"); - info("Use INTx for the hotplug controller\n"); - dbg("%s: rc = %x\n", __FUNCTION__, rc); - } else - php_ctlr->irq = pdev->irq; -#endif rc = request_irq(php_ctlr->irq, shpc_isr, SA_SHIRQ, MY_NAME, (void *) ctrl); dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc); @@ -1563,7 +1554,6 @@ err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq); goto abort_free_ctlr; } - /* Execute OSHP method here */ } dbg("%s: Before adding HPC to HPC list\n", __FUNCTION__); diff -Nru a/drivers/hotplug/shpchp_pci.c b/drivers/hotplug/shpchp_pci.c --- a/drivers/hotplug/shpchp_pci.c 2004-08-23 15:07:00 -07:00 +++ b/drivers/hotplug/shpchp_pci.c 2004-08-23 15:07:00 -07:00 @@ -481,6 +481,7 @@ new_slot->function = (u8) function; new_slot->is_a_board = 1; new_slot->switch_save = 0x10; + new_slot->pwr_save = 1; /* In case of unsupported board */ new_slot->status = DevError; new_slot->pci_dev = pci_find_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function); diff -Nru a/drivers/hotplug/shpchprm_acpi.c b/drivers/hotplug/shpchprm_acpi.c --- a/drivers/hotplug/shpchprm_acpi.c 2004-08-23 15:07:00 -07:00 +++ b/drivers/hotplug/shpchprm_acpi.c 2004-08-23 15:07:00 -07:00 @@ -217,6 +217,10 @@ } ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL); + if (!ab->_hpp) { + err ("acpi_shpchprm:%s alloc for _HPP failed\n", path_name); + goto free_and_return; + } memset(ab->_hpp, 0, sizeof(struct acpi__hpp)); ab->_hpp->cache_line_size = nui[0]; @@ -1387,7 +1391,7 @@ static int bind_pci_resources_to_slots ( struct controller *ctrl) { - struct pci_func *func; + struct pci_func *func, new_func; int busn = ctrl->bus; int devn, funn; u32 vid; @@ -1402,11 +1406,19 @@ if (vid != 0xFFFFFFFF) { func = shpchp_slot_find(busn, devn, funn); - if (!func) - continue; - configure_existing_function(ctrl, func); + if (!func) { + memset(&new_func, 0, sizeof(struct pci_func)); + new_func.bus = busn; + new_func.device = devn; + new_func.function = funn; + new_func.is_a_board = 1; + configure_existing_function(ctrl, &new_func); + shpchprm_dump_func_res(&new_func); + } else { + configure_existing_function(ctrl, func); + shpchprm_dump_func_res(func); + } dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus); - shpchprm_dump_func_res(func); } } } diff -Nru a/drivers/hotplug/shpchprm_nonacpi.c b/drivers/hotplug/shpchprm_nonacpi.c --- a/drivers/hotplug/shpchprm_nonacpi.c 2004-08-23 15:07:00 -07:00 +++ b/drivers/hotplug/shpchprm_nonacpi.c 2004-08-23 15:07:00 -07:00 @@ -213,7 +213,7 @@ static int bind_pci_resources_to_slots ( struct controller *ctrl) { - struct pci_func *func; + struct pci_func *func, new_func; int busn = ctrl->slot_bus; int devn, funn; u32 vid; @@ -230,11 +230,19 @@ if (vid != 0xFFFFFFFF) { func = shpchp_slot_find(busn, devn, funn); - if (!func) - continue; - configure_existing_function(ctrl, func); + if (!func) { + memset(&new_func, 0, sizeof(struct pci_func)); + new_func.bus = busn; + new_func.device = devn; + new_func.function = funn; + new_func.is_a_board = 1; + configure_existing_function(ctrl, &new_func); + phprm_dump_func_res(&new_func); + } else { + configure_existing_function(ctrl, func); + phprm_dump_func_res(func); + } dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus); - phprm_dump_func_res(func); } } } diff -Nru a/drivers/pci/pci.c b/drivers/pci/pci.c --- a/drivers/pci/pci.c 2004-08-23 15:07:00 -07:00 +++ b/drivers/pci/pci.c 2004-08-23 15:07:00 -07:00 @@ -2214,7 +2214,6 @@ EXPORT_SYMBOL(isa_dma_bridge_buggy); EXPORT_SYMBOL(pci_pci_problems); -EXPORT_SYMBOL(pciehp_msi_quirk); /* Pool allocator */ diff -Nru a/drivers/pci/quirks.c b/drivers/pci/quirks.c --- a/drivers/pci/quirks.c 2004-08-23 15:07:00 -07:00 +++ b/drivers/pci/quirks.c 2004-08-23 15:07:00 -07:00 @@ -719,13 +719,6 @@ } } -int pciehp_msi_quirk; - -static void __devinit quirk_pciehp_msi(struct pci_dev *pdev) -{ - pciehp_msi_quirk = 1; -} - /* * The main table of quirks. */ @@ -815,8 +808,6 @@ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc }, - { PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SMCH, quirk_pciehp_msi }, - { 0 } }; diff -Nru a/include/linux/pci.h b/include/linux/pci.h --- a/include/linux/pci.h 2004-08-23 15:07:00 -07:00 +++ b/include/linux/pci.h 2004-08-23 15:07:00 -07:00 @@ -835,7 +835,5 @@ #define PCIPCI_VSFX 16 #define PCIPCI_ALIMAGIK 32 -extern int pciehp_msi_quirk; - #endif /* __KERNEL__ */ #endif /* LINUX_PCI_H */