brintos

brintos / linux-shallow public Read only

0
0
Text · 2.0 KiB · 36db0c3 Raw
86 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * Standard Hot Plug Controller Driver4 *5 * Copyright (C) 1995,2001 Compaq Computer Corporation6 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)7 * Copyright (C) 2001 IBM Corp.8 * Copyright (C) 2003-2004 Intel Corporation9 *10 * All rights reserved.11 *12 * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>13 *14 */15 16#include <linux/module.h>17#include <linux/kernel.h>18#include <linux/types.h>19#include <linux/pci.h>20#include "../pci.h"21#include "shpchp.h"22 23int shpchp_configure_device(struct slot *p_slot)24{25	struct pci_dev *dev;26	struct controller *ctrl = p_slot->ctrl;27	struct pci_dev *bridge = ctrl->pci_dev;28	struct pci_bus *parent = bridge->subordinate;29	int num, ret = 0;30 31	pci_lock_rescan_remove();32 33	dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0));34	if (dev) {35		ctrl_err(ctrl, "Device %s already exists at %04x:%02x:%02x, cannot hot-add\n",36			 pci_name(dev), pci_domain_nr(parent),37			 p_slot->bus, p_slot->device);38		pci_dev_put(dev);39		ret = -EINVAL;40		goto out;41	}42 43	num = pci_scan_slot(parent, PCI_DEVFN(p_slot->device, 0));44	if (num == 0) {45		ctrl_err(ctrl, "No new device found\n");46		ret = -ENODEV;47		goto out;48	}49 50	for_each_pci_bridge(dev, parent) {51		if (PCI_SLOT(dev->devfn) == p_slot->device)52			pci_hp_add_bridge(dev);53	}54 55	pci_assign_unassigned_bridge_resources(bridge);56	pcie_bus_configure_settings(parent);57	pci_bus_add_devices(parent);58 59 out:60	pci_unlock_rescan_remove();61	return ret;62}63 64void shpchp_unconfigure_device(struct slot *p_slot)65{66	struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;67	struct pci_dev *dev, *temp;68	struct controller *ctrl = p_slot->ctrl;69 70	ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:%02x\n",71		 __func__, pci_domain_nr(parent), p_slot->bus, p_slot->device);72 73	pci_lock_rescan_remove();74 75	list_for_each_entry_safe(dev, temp, &parent->devices, bus_list) {76		if (PCI_SLOT(dev->devfn) != p_slot->device)77			continue;78 79		pci_dev_get(dev);80		pci_stop_and_remove_bus_device(dev);81		pci_dev_put(dev);82	}83 84	pci_unlock_rescan_remove();85}86