[PATCH] PCI Hotplug: Fix echoing 1 to power file of enabled slot problem with SHPC driver
Here is a patch to fix the problem of echoing 1 to "power" file to enabled slot causing the slot to power down, and echoing 0 to disabled slot causing shpchp_disabled_slot() to be called twice. This problem was reported by kenji Kaneshige. Thanks, Dely Signed-off-by: Dely Sy <dely.l.sy@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
ff0d2f90fd
commit
ee17fd93a5
2 changed files with 16 additions and 16 deletions
|
@ -95,7 +95,7 @@ static struct hotplug_slot_ops shpchp_hotplug_slot_ops = {
|
||||||
*/
|
*/
|
||||||
static void release_slot(struct hotplug_slot *hotplug_slot)
|
static void release_slot(struct hotplug_slot *hotplug_slot)
|
||||||
{
|
{
|
||||||
struct slot *slot = (struct slot *)hotplug_slot->private;
|
struct slot *slot = hotplug_slot->private;
|
||||||
|
|
||||||
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
|
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
|
||||||
|
|
||||||
|
|
|
@ -1885,7 +1885,7 @@ int shpchp_enable_slot (struct slot *p_slot)
|
||||||
func = shpchp_slot_find(p_slot->bus, p_slot->device, 0);
|
func = shpchp_slot_find(p_slot->bus, p_slot->device, 0);
|
||||||
if (!func) {
|
if (!func) {
|
||||||
dbg("%s: Error! slot NULL\n", __FUNCTION__);
|
dbg("%s: Error! slot NULL\n", __FUNCTION__);
|
||||||
return 1;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check to see if (latch closed, card present, power off) */
|
/* Check to see if (latch closed, card present, power off) */
|
||||||
|
@ -1894,19 +1894,19 @@ int shpchp_enable_slot (struct slot *p_slot)
|
||||||
if (rc || !getstatus) {
|
if (rc || !getstatus) {
|
||||||
info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
|
info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
|
||||||
up(&p_slot->ctrl->crit_sect);
|
up(&p_slot->ctrl->crit_sect);
|
||||||
return 1;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
|
rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
|
||||||
if (rc || getstatus) {
|
if (rc || getstatus) {
|
||||||
info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
|
info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
|
||||||
up(&p_slot->ctrl->crit_sect);
|
up(&p_slot->ctrl->crit_sect);
|
||||||
return 1;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
|
rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
|
||||||
if (rc || getstatus) {
|
if (rc || getstatus) {
|
||||||
info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number);
|
info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number);
|
||||||
up(&p_slot->ctrl->crit_sect);
|
up(&p_slot->ctrl->crit_sect);
|
||||||
return 1;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
up(&p_slot->ctrl->crit_sect);
|
up(&p_slot->ctrl->crit_sect);
|
||||||
|
|
||||||
|
@ -1914,7 +1914,7 @@ int shpchp_enable_slot (struct slot *p_slot)
|
||||||
|
|
||||||
func = shpchp_slot_create(p_slot->bus);
|
func = shpchp_slot_create(p_slot->bus);
|
||||||
if (func == NULL)
|
if (func == NULL)
|
||||||
return 1;
|
return -ENOMEM;
|
||||||
|
|
||||||
func->bus = p_slot->bus;
|
func->bus = p_slot->bus;
|
||||||
func->device = p_slot->device;
|
func->device = p_slot->device;
|
||||||
|
@ -1939,7 +1939,7 @@ int shpchp_enable_slot (struct slot *p_slot)
|
||||||
/* Setup slot structure with entry for empty slot */
|
/* Setup slot structure with entry for empty slot */
|
||||||
func = shpchp_slot_create(p_slot->bus);
|
func = shpchp_slot_create(p_slot->bus);
|
||||||
if (func == NULL)
|
if (func == NULL)
|
||||||
return (1); /* Out of memory */
|
return -ENOMEM; /* Out of memory */
|
||||||
|
|
||||||
func->bus = p_slot->bus;
|
func->bus = p_slot->bus;
|
||||||
func->device = p_slot->device;
|
func->device = p_slot->device;
|
||||||
|
@ -1972,7 +1972,7 @@ int shpchp_disable_slot (struct slot *p_slot)
|
||||||
struct pci_func *func;
|
struct pci_func *func;
|
||||||
|
|
||||||
if (!p_slot->ctrl)
|
if (!p_slot->ctrl)
|
||||||
return 1;
|
return -ENODEV;
|
||||||
|
|
||||||
pci_bus = p_slot->ctrl->pci_dev->subordinate;
|
pci_bus = p_slot->ctrl->pci_dev->subordinate;
|
||||||
|
|
||||||
|
@ -1983,19 +1983,19 @@ int shpchp_disable_slot (struct slot *p_slot)
|
||||||
if (ret || !getstatus) {
|
if (ret || !getstatus) {
|
||||||
info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
|
info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
|
||||||
up(&p_slot->ctrl->crit_sect);
|
up(&p_slot->ctrl->crit_sect);
|
||||||
return 1;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
|
ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
|
||||||
if (ret || getstatus) {
|
if (ret || getstatus) {
|
||||||
info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
|
info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
|
||||||
up(&p_slot->ctrl->crit_sect);
|
up(&p_slot->ctrl->crit_sect);
|
||||||
return 1;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
|
ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
|
||||||
if (ret || !getstatus) {
|
if (ret || !getstatus) {
|
||||||
info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number);
|
info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number);
|
||||||
up(&p_slot->ctrl->crit_sect);
|
up(&p_slot->ctrl->crit_sect);
|
||||||
return 1;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
up(&p_slot->ctrl->crit_sect);
|
up(&p_slot->ctrl->crit_sect);
|
||||||
|
|
||||||
|
@ -2011,7 +2011,7 @@ int shpchp_disable_slot (struct slot *p_slot)
|
||||||
/* Check the Class Code */
|
/* Check the Class Code */
|
||||||
rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
|
rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return -ENODEV;
|
||||||
|
|
||||||
if (class_code == PCI_BASE_CLASS_DISPLAY) {
|
if (class_code == PCI_BASE_CLASS_DISPLAY) {
|
||||||
/* Display/Video adapter (not supported) */
|
/* Display/Video adapter (not supported) */
|
||||||
|
@ -2020,13 +2020,13 @@ int shpchp_disable_slot (struct slot *p_slot)
|
||||||
/* See if it's a bridge */
|
/* See if it's a bridge */
|
||||||
rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
|
rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return -ENODEV;
|
||||||
|
|
||||||
/* If it's a bridge, check the VGA Enable bit */
|
/* If it's a bridge, check the VGA Enable bit */
|
||||||
if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
|
if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
|
||||||
rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
|
rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return -ENODEV;
|
||||||
|
|
||||||
/* If the VGA Enable bit is set, remove isn't supported */
|
/* If the VGA Enable bit is set, remove isn't supported */
|
||||||
if (BCR & PCI_BRIDGE_CTL_VGA) {
|
if (BCR & PCI_BRIDGE_CTL_VGA) {
|
||||||
|
@ -2042,12 +2042,12 @@ int shpchp_disable_slot (struct slot *p_slot)
|
||||||
if ((func != NULL) && !rc) {
|
if ((func != NULL) && !rc) {
|
||||||
rc = remove_board(func, p_slot->ctrl);
|
rc = remove_board(func, p_slot->ctrl);
|
||||||
} else if (!rc)
|
} else if (!rc)
|
||||||
rc = 1;
|
rc = -ENODEV;
|
||||||
|
|
||||||
if (p_slot)
|
if (p_slot)
|
||||||
update_slot_info(p_slot);
|
update_slot_info(p_slot);
|
||||||
|
|
||||||
return(rc);
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue