Commit 14b5cb37 authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'pci/yijing-ari' into next

* pci/yijing-ari:
  PCI: shpchp: Iterate over all devices in slot, not functions 0-7
  PCI: sgihp: Iterate over all devices in slot, not functions 0-7
  PCI: cpcihp: Iterate over all devices in slot, not functions 0-7
  PCI: pciehp: Iterate over all devices in slot, not functions 0-7
  PCI: Consolidate "next-function" functions
  PCI: Rename pci_enable_ari() to pci_configure_ari()
  PCI: Enable ARI if dev and upstream bridge support it; disable otherwise
parents 708b59bf fcbed0bc
Loading
Loading
Loading
Loading
+11 −18
Original line number Diff line number Diff line
@@ -252,8 +252,8 @@ int cpci_led_off(struct slot* slot)

int __ref cpci_configure_slot(struct slot *slot)
{
	struct pci_dev *dev;
	struct pci_bus *parent;
	int fn;

	dbg("%s - enter", __func__);

@@ -282,18 +282,13 @@ int __ref cpci_configure_slot(struct slot *slot)
	}
	parent = slot->dev->bus;

	for (fn = 0; fn < 8; fn++) {
		struct pci_dev *dev;

		dev = pci_get_slot(parent,
				   PCI_DEVFN(PCI_SLOT(slot->devfn), fn));
		if (!dev)
	list_for_each_entry(dev, &parent->devices, bus_list)
		if (PCI_SLOT(dev->devfn) != PCI_SLOT(slot->devfn))
			continue;
		if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
		    (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS))
			pci_hp_add_bridge(dev);
		pci_dev_put(dev);
	}


	pci_assign_unassigned_bridge_resources(parent->self);

@@ -305,8 +300,7 @@ int __ref cpci_configure_slot(struct slot *slot)

int cpci_unconfigure_slot(struct slot* slot)
{
	int i;
	struct pci_dev *dev;
	struct pci_dev *dev, *temp;

	dbg("%s - enter", __func__);
	if (!slot->dev) {
@@ -314,14 +308,13 @@ int cpci_unconfigure_slot(struct slot* slot)
		return -ENODEV;
	}

	for (i = 0; i < 8; i++) {
		dev = pci_get_slot(slot->bus,
				    PCI_DEVFN(PCI_SLOT(slot->devfn), i));
		if (dev) {
	list_for_each_entry_safe(dev, temp, &slot->bus->devices, bus_list) {
		if (PCI_SLOT(dev->devfn) != PCI_SLOT(slot->devfn))
			continue;
		pci_dev_get(dev);
		pci_stop_and_remove_bus_device(dev);
		pci_dev_put(dev);
	}
	}
	pci_dev_put(slot->dev);
	slot->dev = NULL;

+16 −28
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ int pciehp_configure_device(struct slot *p_slot)
	struct pci_dev *dev;
	struct pci_dev *bridge = p_slot->ctrl->pcie->port;
	struct pci_bus *parent = bridge->subordinate;
	int num, fn;
	int num;
	struct controller *ctrl = p_slot->ctrl;

	dev = pci_get_slot(parent, PCI_DEVFN(0, 0));
@@ -57,28 +57,18 @@ int pciehp_configure_device(struct slot *p_slot)
		return -ENODEV;
	}

	for (fn = 0; fn < 8; fn++) {
		dev = pci_get_slot(parent, PCI_DEVFN(0, fn));
		if (!dev)
			continue;
	list_for_each_entry(dev, &parent->devices, bus_list)
		if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
				(dev->hdr_type == PCI_HEADER_TYPE_CARDBUS))
			pci_hp_add_bridge(dev);
		pci_dev_put(dev);
	}

	pci_assign_unassigned_bridge_resources(bridge);

	for (fn = 0; fn < 8; fn++) {
		dev = pci_get_slot(parent, PCI_DEVFN(0, fn));
		if (!dev)
	list_for_each_entry(dev, &parent->devices, bus_list) {
		if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
			continue;
		if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
			pci_dev_put(dev);
			continue;
		}

		pci_configure_slot(dev);
		pci_dev_put(dev);
	}

	pci_bus_add_devices(parent);
@@ -89,9 +79,9 @@ int pciehp_configure_device(struct slot *p_slot)
int pciehp_unconfigure_device(struct slot *p_slot)
{
	int ret, rc = 0;
	int j;
	u8 bctl = 0;
	u8 presence = 0;
	struct pci_dev *dev, *temp;
	struct pci_bus *parent = p_slot->ctrl->pcie->port->subordinate;
	u16 command;
	struct controller *ctrl = p_slot->ctrl;
@@ -102,33 +92,31 @@ int pciehp_unconfigure_device(struct slot *p_slot)
	if (ret)
		presence = 0;

	for (j = 0; j < 8; j++) {
		struct pci_dev *temp = pci_get_slot(parent, PCI_DEVFN(0, j));
		if (!temp)
			continue;
		if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) {
			pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl);
	list_for_each_entry_safe(dev, temp, &parent->devices, bus_list) {
		pci_dev_get(dev);
		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) {
			pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl);
			if (bctl & PCI_BRIDGE_CTL_VGA) {
				ctrl_err(ctrl,
					 "Cannot remove display device %s\n",
					 pci_name(temp));
				pci_dev_put(temp);
					 pci_name(dev));
				pci_dev_put(dev);
				rc = -EINVAL;
				break;
			}
		}
		pci_stop_and_remove_bus_device(temp);
		pci_stop_and_remove_bus_device(dev);
		/*
		 * Ensure that no new Requests will be generated from
		 * the device.
		 */
		if (presence) {
			pci_read_config_word(temp, PCI_COMMAND, &command);
			pci_read_config_word(dev, PCI_COMMAND, &command);
			command &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_SERR);
			command |= PCI_COMMAND_INTX_DISABLE;
			pci_write_config_word(temp, PCI_COMMAND, command);
			pci_write_config_word(dev, PCI_COMMAND, command);
		}
		pci_dev_put(temp);
		pci_dev_put(dev);
	}

	return rc;
+29 −34
Original line number Diff line number Diff line
@@ -334,7 +334,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
	struct slot *slot = bss_hotplug_slot->private;
	struct pci_bus *new_bus = NULL;
	struct pci_dev *dev;
	int func, num_funcs;
	int num_funcs;
	int new_ppb = 0;
	int rc;
	char *ssdt = NULL;
@@ -381,11 +381,10 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
	 * to the Linux PCI interface and tell the drivers
	 * about them.
	 */
	for (func = 0; func < num_funcs;  func++) {
		dev = pci_get_slot(slot->pci_bus,
				   PCI_DEVFN(slot->device_num + 1,
					     PCI_FUNC(func)));
		if (dev) {
	list_for_each_entry(dev, &slot->pci_bus->devices, bus_list) {
		if (PCI_SLOT(dev->devfn) != slot->device_num + 1)
			continue;

		/* Need to do slot fixup on PPB before fixup of children
		 * (PPB's pcidev_info needs to be in pcidev_info list
		 * before child's SN_PCIDEV_INFO() call to setup
@@ -403,8 +402,6 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
				new_ppb = 1;
			}
		}
			pci_dev_put(dev);
		}
	}

	/*
@@ -481,8 +478,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
{
	struct slot *slot = bss_hotplug_slot->private;
	struct pci_dev *dev;
	int func;
	struct pci_dev *dev, *temp;
	int rc;
	acpi_owner_id ssdt_id = 0;

@@ -542,16 +538,15 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
	}

	/* Free the SN resources assigned to the Linux device.*/
	for (func = 0; func < 8;  func++) {
		dev = pci_get_slot(slot->pci_bus,
				   PCI_DEVFN(slot->device_num + 1,
				   	     PCI_FUNC(func)));
		if (dev) {
	list_for_each_entry_safe(dev, temp, &slot->pci_bus->devices, bus_list) {
		if (PCI_SLOT(dev->devfn) != slot->device_num + 1)
			continue;

		pci_dev_get(dev);
		sn_bus_free_data(dev);
		pci_stop_and_remove_bus_device(dev);
		pci_dev_put(dev);
	}
	}

	/* Remove the SSDT for the slot from the ACPI namespace */
	if (SN_ACPI_BASE_SUPPORT() && ssdt_id) {
+16 −20
Original line number Diff line number Diff line
@@ -40,7 +40,7 @@ int __ref shpchp_configure_device(struct slot *p_slot)
	struct controller *ctrl = p_slot->ctrl;
	struct pci_dev *bridge = ctrl->pci_dev;
	struct pci_bus *parent = bridge->subordinate;
	int num, fn;
	int num;

	dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0));
	if (dev) {
@@ -57,24 +57,20 @@ int __ref shpchp_configure_device(struct slot *p_slot)
		return -ENODEV;
	}

	for (fn = 0; fn < 8; fn++) {
		dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn));
		if (!dev)
	list_for_each_entry(dev, &parent->devices, bus_list) {
		if (PCI_SLOT(dev->devfn) != p_slot->device)
			continue;
		if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
		    (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS))
			pci_hp_add_bridge(dev);
		pci_dev_put(dev);
	}

	pci_assign_unassigned_bridge_resources(bridge);

	for (fn = 0; fn < 8; fn++) {
		dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn));
		if (!dev)
	list_for_each_entry(dev, &parent->devices, bus_list) {
		if (PCI_SLOT(dev->devfn) != p_slot->device)
			continue;
		pci_configure_slot(dev);
		pci_dev_put(dev);
	}

	pci_bus_add_devices(parent);
@@ -85,32 +81,32 @@ int __ref shpchp_configure_device(struct slot *p_slot)
int shpchp_unconfigure_device(struct slot *p_slot)
{
	int rc = 0;
	int j;
	u8 bctl = 0;
	struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
	struct pci_dev *dev, *temp;
	struct controller *ctrl = p_slot->ctrl;

	ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:%02x\n",
		 __func__, pci_domain_nr(parent), p_slot->bus, p_slot->device);

	for (j = 0; j < 8 ; j++) {
		struct pci_dev *temp = pci_get_slot(parent,
				(p_slot->device << 3) | j);
		if (!temp)
	list_for_each_entry_safe(dev, temp, &parent->devices, bus_list) {
		if (PCI_SLOT(dev->devfn) != p_slot->device)
			continue;
		if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
			pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl);

		pci_dev_get(dev);
		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
			pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl);
			if (bctl & PCI_BRIDGE_CTL_VGA) {
				ctrl_err(ctrl,
					 "Cannot remove display device %s\n",
					 pci_name(temp));
				pci_dev_put(temp);
					 pci_name(dev));
				pci_dev_put(dev);
				rc = -EINVAL;
				break;
			}
		}
		pci_stop_and_remove_bus_device(temp);
		pci_dev_put(temp);
		pci_stop_and_remove_bus_device(dev);
		pci_dev_put(dev);
	}
	return rc;
}
+14 −7
Original line number Diff line number Diff line
@@ -2042,10 +2042,13 @@ void pci_free_cap_save_buffers(struct pci_dev *dev)
}

/**
 * pci_enable_ari - enable ARI forwarding if hardware support it
 * pci_configure_ari - enable or disable ARI forwarding
 * @dev: the PCI device
 *
 * If @dev and its upstream bridge both support ARI, enable ARI in the
 * bridge.  Otherwise, disable ARI in the bridge.
 */
void pci_enable_ari(struct pci_dev *dev)
void pci_configure_ari(struct pci_dev *dev)
{
	u32 cap;
	struct pci_dev *bridge;
@@ -2053,9 +2056,6 @@ void pci_enable_ari(struct pci_dev *dev)
	if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn)
		return;

	if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI))
		return;

	bridge = dev->bus->self;
	if (!bridge)
		return;
@@ -2064,8 +2064,15 @@ void pci_enable_ari(struct pci_dev *dev)
	if (!(cap & PCI_EXP_DEVCAP2_ARI))
		return;

	pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2, PCI_EXP_DEVCTL2_ARI);
	if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI)) {
		pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2,
					 PCI_EXP_DEVCTL2_ARI);
		bridge->ari_enabled = 1;
	} else {
		pcie_capability_clear_word(bridge, PCI_EXP_DEVCTL2,
					   PCI_EXP_DEVCTL2_ARI);
		bridge->ari_enabled = 0;
	}
}

/**
Loading