コード例 #1
0
ファイル: pci_mcfg.c プロジェクト: guanhe0/kernel
void __iomem *
pci_mcfg_dev_base(struct pci_bus *bus, unsigned int devfn, int offset)
{
	struct pci_mmcfg_region *cfg;

	cfg = pci_mmconfig_lookup(pci_domain_nr(bus), bus->number);
	if (cfg && cfg->virt)
		return cfg->virt +
			(PCI_MMCFG_BUS_OFFSET(bus->number) | (devfn << 12)) +
			offset;
	return NULL;
}
コード例 #2
0
ファイル: rpaphp_pci.c プロジェクト: 3sOx/asuswrt-merlin
static void set_slot_name(struct slot *slot)
{
	struct pci_bus *bus = slot->bus;
	struct pci_dev *bridge;

	bridge = bus->self;
	if (bridge)
		strcpy(slot->name, pci_name(bridge));
	else
		sprintf(slot->name, "%04x:%02x:00.0", pci_domain_nr(bus),
			bus->number);
}
コード例 #3
0
ファイル: cdv_device.c プロジェクト: grate-driver/linux
static void cdv_errata(struct drm_device *dev)
{
	/* Disable bonus launch.
	 *	CPU and GPU competes for memory and display misses updates and
	 *	flickers. Worst with dual core, dual displays.
	 *
	 *	Fixes were done to Win 7 gfx driver to disable a feature called
	 *	Bonus Launch to work around the issue, by degrading
	 *	performance.
	 */
	 CDV_MSG_WRITE32(pci_domain_nr(dev->pdev->bus), 3, 0x30, 0x08027108);
}
コード例 #4
0
int kvm_assign_device(struct kvm *kvm,
                      struct kvm_assigned_dev_kernel *assigned_dev)
{
    struct pci_dev *pdev = NULL;
    struct iommu_domain *domain = kvm->arch.iommu_domain;
    int r, last_flags;

    /* check if iommu exists and in use */
    if (!domain)
        return 0;

    pdev = assigned_dev->dev;
    if (pdev == NULL)
        return -ENODEV;

    r = iommu_attach_device(domain, &pdev->dev);
    if (r) {
        printk(KERN_ERR "assign device %x:%x:%x.%x failed",
               pci_domain_nr(pdev->bus),
               pdev->bus->number,
               PCI_SLOT(pdev->devfn),
               PCI_FUNC(pdev->devfn));
        return r;
    }

    last_flags = kvm->arch.iommu_flags;
    if (iommu_domain_has_cap(kvm->arch.iommu_domain,
                             IOMMU_CAP_CACHE_COHERENCY))
        kvm->arch.iommu_flags |= KVM_IOMMU_CACHE_COHERENCY;

    /* Check if need to update IOMMU page table for guest memory */
    if ((last_flags ^ kvm->arch.iommu_flags) ==
            KVM_IOMMU_CACHE_COHERENCY) {
        kvm_iommu_unmap_memslots(kvm);
        r = kvm_iommu_map_memslots(kvm);
        if (r)
            goto out_unmap;
    }

    printk(KERN_DEBUG "assign device %x:%x:%x.%x\n",
           assigned_dev->host_segnr,
           assigned_dev->host_busnr,
           PCI_SLOT(assigned_dev->host_devfn),
           PCI_FUNC(assigned_dev->host_devfn));

    return 0;
out_unmap:
    kvm_iommu_unmap_memslots(kvm);
    return r;
}
コード例 #5
0
ファイル: efivar.c プロジェクト: 020gzh/linux
/*
 * Read an HFI1 EFI variable of the form:
 *	<PCIe address>-<kind>
 * Return an kalloc'ed array and size of the data.
 *
 * Returns 0 on success, -errno on failure.
 */
int read_hfi1_efi_var(struct hfi1_devdata *dd, const char *kind,
		      unsigned long *size, void **return_data)
{
	char name[64];

	/* create a common prefix */
	snprintf(name, sizeof(name), "%04x:%02x:%02x.%x-%s",
		 pci_domain_nr(dd->pcidev->bus),
		 dd->pcidev->bus->number,
		 PCI_SLOT(dd->pcidev->devfn),
		 PCI_FUNC(dd->pcidev->devfn),
		 kind);

	return read_efi_var(name, size, return_data);
}
コード例 #6
0
ファイル: pciehp_ctrl.c プロジェクト: forgivemyheart/linux
/**
 * board_added - Called after a board has been added to the system.
 * @p_slot: &slot where board is added
 *
 * Turns power on for the board.
 * Configures board.
 */
static int board_added(struct slot *p_slot)
{
	int retval = 0;
	struct controller *ctrl = p_slot->ctrl;
	struct pci_bus *parent = ctrl->pcie->port->subordinate;

	if (POWER_CTRL(ctrl)) {
		/* Power on slot */
		retval = pciehp_power_on_slot(p_slot);
		if (retval)
			return retval;
	}

	pciehp_green_led_blink(p_slot);

	/* Check link training status */
	pm_runtime_get_sync(&ctrl->pcie->port->dev);
	retval = pciehp_check_link_status(ctrl);
	if (retval) {
		ctrl_err(ctrl, "Failed to check link status\n");
		goto err_exit;
	}

	/* Check for a power fault */
	if (ctrl->power_fault_detected || pciehp_query_power_fault(p_slot)) {
		ctrl_err(ctrl, "Slot(%s): Power fault\n", slot_name(p_slot));
		retval = -EIO;
		goto err_exit;
	}

	retval = pciehp_configure_device(p_slot);
	if (retval) {
		ctrl_err(ctrl, "Cannot add device at %04x:%02x:00\n",
			 pci_domain_nr(parent), parent->number);
		if (retval != -EEXIST)
			goto err_exit;
	}
	pm_runtime_put(&ctrl->pcie->port->dev);

	pciehp_green_led_on(p_slot);
	pciehp_set_attention_status(p_slot, 0);
	return 0;

err_exit:
	pm_runtime_put(&ctrl->pcie->port->dev);
	set_slot_off(ctrl, p_slot);
	return retval;
}
コード例 #7
0
ファイル: shpchp_sysfs.c プロジェクト: CSCLOG/beaglebone
static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, char *buf)
{
	struct pci_dev *pdev;
	char * out = buf;
	int index, busnr;
	struct resource *res;
	struct pci_bus *bus;

	pdev = container_of (dev, struct pci_dev, dev);
	bus = pdev->subordinate;

	out += sprintf(buf, "Free resources: memory\n");
	pci_bus_for_each_resource(bus, res, index) {
		if (res && (res->flags & IORESOURCE_MEM) &&
				!(res->flags & IORESOURCE_PREFETCH)) {
			out += sprintf(out, "start = %8.8llx, length = %8.8llx\n",
				       (unsigned long long)res->start,
				       (unsigned long long)resource_size(res));
		}
	}
	out += sprintf(out, "Free resources: prefetchable memory\n");
	pci_bus_for_each_resource(bus, res, index) {
		if (res && (res->flags & IORESOURCE_MEM) &&
			       (res->flags & IORESOURCE_PREFETCH)) {
			out += sprintf(out, "start = %8.8llx, length = %8.8llx\n",
				       (unsigned long long)res->start,
				       (unsigned long long)resource_size(res));
		}
	}
	out += sprintf(out, "Free resources: IO\n");
	pci_bus_for_each_resource(bus, res, index) {
		if (res && (res->flags & IORESOURCE_IO)) {
			out += sprintf(out, "start = %8.8llx, length = %8.8llx\n",
				       (unsigned long long)res->start,
				       (unsigned long long)resource_size(res));
		}
	}
	out += sprintf(out, "Free resources: bus numbers\n");
	for (busnr = bus->secondary; busnr <= bus->subordinate; busnr++) {
		if (!pci_find_bus(pci_domain_nr(bus), busnr))
			break;
	}
	if (busnr < bus->subordinate)
		out += sprintf(out, "start = %8.8x, length = %8.8x\n",
				busnr, (bus->subordinate - busnr));

	return out - buf;
}
コード例 #8
0
ファイル: bcm5301x_pcie.c プロジェクト: hajuuk/R7000
static int soc_pcie_map_irq(struct pci_dev *pdev, u8 slot, u8 pin)
{
	struct soc_pcie_port *port = soc_pcie_pdev2port(pdev);
	int irq;

	irq = port->irqs[5];	/* All INTx share int src 5, last per port */

	pr_debug("PCIe map irq: %04d:%02x:%02x.%02x slot %d, pin %d, irq: %d\n",
		pci_domain_nr(pdev->bus),
		pdev->bus->number,
		PCI_SLOT(pdev->devfn),
		PCI_FUNC(pdev->devfn),
		slot, pin, irq);

	return irq;
}
コード例 #9
0
ファイル: reserve.c プロジェクト: AsadRaza/OCTEON-Linux
static unsigned long pci_reserve_size(struct pci_bus *pbus, int flags)
{
	char *sp;
	char *ep;

	int seg;
	int bus;
	int dev;
	int func;

	unsigned long io_size;
	unsigned long mem_size;

	sp = pci_reserve_param;

	do {
		ep = strchr(sp, ',');
		if (ep)
			*ep = '\0';	/* chomp */

		if (pci_reserve_parse_one(sp, &seg, &bus, &dev, &func,
					  &io_size, &mem_size) == 0) {
			if (pci_domain_nr(pbus) == seg &&
			    pbus->number == bus &&
			    PCI_SLOT(pbus->self->devfn) == dev &&
			    PCI_FUNC(pbus->self->devfn) == func) {
				switch (flags) {
				case IORESOURCE_IO:
					return io_size;
				case IORESOURCE_MEM:
					return mem_size;
				default:
					break;
				}
			}
		}

		if (ep) {
			*ep = ',';	/* restore chomp'ed ',' for later */
			ep++;
		}
		sp = ep;
	} while (ep);

	return 0;
}
コード例 #10
0
ファイル: mid_bios.c プロジェクト: AlexShiLucky/linux
/*
 *	Get the revison ID, B0:D2:F0;0x08
 */
static void mid_get_pci_revID(struct drm_psb_private *dev_priv)
{
	uint32_t platform_rev_id = 0;
	int domain = pci_domain_nr(dev_priv->dev->pdev->bus);
	struct pci_dev *pci_gfx_root =
		pci_get_domain_bus_and_slot(domain, 0, PCI_DEVFN(2, 0));

	if (pci_gfx_root == NULL) {
		WARN_ON(1);
		return;
	}
	pci_read_config_dword(pci_gfx_root, 0x08, &platform_rev_id);
	dev_priv->platform_rev_id = (uint8_t) platform_rev_id;
	pci_dev_put(pci_gfx_root);
	dev_dbg(dev_priv->dev->dev, "platform_rev_id is %x\n",
					dev_priv->platform_rev_id);
}
コード例 #11
0
ファイル: pci-p5ioc2.c プロジェクト: 0-T-0/ps4-linux
static void pnv_pci_p5ioc2_dma_dev_setup(struct pnv_phb *phb,
					 struct pci_dev *pdev)
{
	struct iommu_table *tbl = phb->p5ioc2.table_group.tables[0];

	if (!tbl->it_map) {
		tbl->it_ops = &pnv_p5ioc2_iommu_ops;
		iommu_init_table(tbl, phb->hose->node);
		iommu_register_group(&phb->p5ioc2.table_group,
				pci_domain_nr(phb->hose->bus), phb->opal_id);
		INIT_LIST_HEAD_RCU(&tbl->it_group_list);
		pnv_pci_link_table_and_group(phb->hose->node, 0,
				tbl, &phb->p5ioc2.table_group);
	}

	set_iommu_table_base(&pdev->dev, tbl);
	iommu_add_device(&pdev->dev);
}
コード例 #12
0
static uint64_t get_callback_via(struct pci_dev *pdev)
{
	u8 pin;
	int irq;

	irq = pdev->irq;
	if (irq < 16)
		return irq; /* ISA IRQ */

	pin = pdev->pin;

	/* We don't know the GSI. Specify the PCI INTx line instead. */
	return ((uint64_t)0x01 << 56) | /* PCI INTx identifier */
		((uint64_t)pci_domain_nr(pdev->bus) << 32) |
		((uint64_t)pdev->bus->number << 16) |
		((uint64_t)(pdev->devfn & 0xff) << 8) |
		((uint64_t)(pin - 1) & 3);
}
コード例 #13
0
ファイル: pci_dma.c プロジェクト: dduval/kernel-rhel4
int sn_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size)
{
	unsigned long addr;
	int ret;
	struct ia64_sal_retval isrv;

	/*
	 * First, try the SN_SAL_IOIF_PCI_SAFE SAL call which can work
	 * around hw issues at the pci bus level.  SGI proms older than
	 * 4.10 don't implment this.
	 */

	SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE,
		 pci_domain_nr(bus), bus->number,
		 0, /* io */
		 0, /* read */
		 port, size, __pa(val));

	if (isrv.status == 0)
		return size;

	/*
	 * If the above failed, retry using the SAL_PROBE call which should
	 * be present in all proms (but which cannot work round PCI chipset
	 * bugs).  This code is retained for compatability with old
	 * pre-4.10 proms, and should be removed at some point in the future.
	 */

	if (!SN_PCIBUS_BUSSOFT(bus))
		return -ENODEV;

	addr = SN_PCIBUS_BUSSOFT(bus)->bs_legacy_io | __IA64_UNCACHED_OFFSET;
	addr += port;

	ret = ia64_sn_probe_mem(addr, (long)size, (void *)val);

	if (ret == 2)
		return -EINVAL;

	if (ret == 1)
		*val = -1;

	return size;
}
コード例 #14
0
ファイル: ltp_tpci.c プロジェクト: 1587/ltp
/*
 * find_bus
 *	call to pci_find_bus, use values from bus
 *	pointer in ltp_pci, make sure that returns
 *	bus with same values
 */
static int test_find_bus(void)
{
	int num = ltp_pci.bus->number;
	struct pci_bus *temp = NULL;

	prk_info("find bus");

	temp = pci_find_bus(pci_domain_nr(ltp_pci.bus), num);

	if (!temp) {
		prk_info("pci_find_bus failed");
		return TFAIL;
	} else if (temp->number != num) {
		prk_err("returned bus pointer w/ wrong bus number");
		return TFAIL;
	}

	prk_info("success returned bus pointer");
	return TPASS;
}
コード例 #15
0
ファイル: htirq.c プロジェクト: laborjack/ENGLinuxLatest
static int htirq_domain_alloc(struct irq_domain *domain, unsigned int virq,
			      unsigned int nr_irqs, void *arg)
{
	struct ht_irq_cfg *ht_cfg;
	struct irq_alloc_info *info = arg;
	struct pci_dev *dev;
	irq_hw_number_t hwirq;
	int ret;

	if (nr_irqs > 1 || !info)
		return -EINVAL;

	dev = info->ht_dev;
	hwirq = (info->ht_idx & 0xFF) |
		PCI_DEVID(dev->bus->number, dev->devfn) << 8 |
		(pci_domain_nr(dev->bus) & 0xFFFFFFFF) << 24;
	if (irq_find_mapping(domain, hwirq) > 0)
		return -EEXIST;

	ht_cfg = kmalloc(sizeof(*ht_cfg), GFP_KERNEL);
	if (!ht_cfg)
		return -ENOMEM;

	ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, info);
	if (ret < 0) {
		kfree(ht_cfg);
		return ret;
	}

	/* Initialize msg to a value that will never match the first write. */
	ht_cfg->msg.address_lo = 0xffffffff;
	ht_cfg->msg.address_hi = 0xffffffff;
	ht_cfg->dev = info->ht_dev;
	ht_cfg->update = info->ht_update;
	ht_cfg->pos = info->ht_pos;
	ht_cfg->idx = 0x10 + (info->ht_idx * 2);
	irq_domain_set_info(domain, virq, hwirq, &ht_irq_chip, ht_cfg,
			    handle_edge_irq, ht_cfg, "edge");

	return 0;
}
コード例 #16
0
ファイル: acpi_pcihp.c プロジェクト: 274914765/C
/* acpi_get_hp_params_from_firmware
 *
 * @bus - the pci_bus of the bus on which the device is newly added
 * @hpp - allocated by the caller
 */
acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus,
        struct hotplug_params *hpp)
{
    acpi_status status = AE_NOT_FOUND;
    acpi_handle handle, phandle;
    struct pci_bus *pbus = bus;
    struct pci_dev *pdev;

    do {
        pdev = pbus->self;
        if (!pdev) {
            handle = acpi_get_pci_rootbridge_handle(
                pci_domain_nr(pbus), pbus->number);
            break;
        }
        handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
        pbus = pbus->parent;
    } while (!handle);

    /*
     * _HPP settings apply to all child buses, until another _HPP is
     * encountered. If we don't find an _HPP for the input pci dev,
     * look for it in the parent device scope since that would apply to
     * this pci dev. If we don't find any _HPP, use hardcoded defaults
     */
    while (handle) {
        status = acpi_run_hpx(handle, hpp);
        if (ACPI_SUCCESS(status))
            break;
        status = acpi_run_hpp(handle, hpp);
        if (ACPI_SUCCESS(status))
            break;
        if (acpi_root_bridge(handle))
            break;
        status = acpi_get_parent(handle, &phandle);
        if (ACPI_FAILURE(status))
            break;
        handle = phandle;
    }
    return status;
}
コード例 #17
0
ファイル: setup-irq.c プロジェクト: 3sOx/asuswrt-merlin
static void __init
pdev_fixup_irq(struct pci_dev *dev,
	       u8 (*swizzle)(struct pci_dev *, u8 *),
	       int (*map_irq)(struct pci_dev *, u8, u8))
{
	u8 pin, slot;
	int irq = 0;

#ifdef CONFIG_BCM47XX
	if (pci_domain_nr(dev->bus) == 0)
		return;
#endif

	/* If this device is not on the primary bus, we need to figure out
	   which interrupt pin it will come in on.   We know which slot it
	   will come in on 'cos that slot is where the bridge is.   Each
	   time the interrupt line passes through a PCI-PCI bridge we must
	   apply the swizzle function.  */

	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
	/* Cope with illegal. */
	if (pin > 4)
		pin = 1;

	if (pin != 0) {
		/* Follow the chain of bridges, swizzling as we go.  */
		slot = (*swizzle)(dev, &pin);

		irq = (*map_irq)(dev, slot, pin);
		if (irq == -1)
			irq = 0;
	}
	dev->irq = irq;

	dev_dbg(&dev->dev, "fixup irq: got %d\n", dev->irq);

	/* Always tell the device, so the driver knows what is
	   the real IRQ to use; the device does not use it. */
	pcibios_update_irq(dev, irq);
}
コード例 #18
0
ファイル: gma_device.c プロジェクト: AlexShiLucky/linux
void gma_get_core_freq(struct drm_device *dev)
{
	uint32_t clock;
	struct pci_dev *pci_root =
		pci_get_domain_bus_and_slot(pci_domain_nr(dev->pdev->bus),
					    0, 0);
	struct drm_psb_private *dev_priv = dev->dev_private;

	/*pci_write_config_dword(pci_root, 0xD4, 0x00C32004);*/
	/*pci_write_config_dword(pci_root, 0xD0, 0xE0033000);*/

	pci_write_config_dword(pci_root, 0xD0, 0xD0050300);
	pci_read_config_dword(pci_root, 0xD4, &clock);
	pci_dev_put(pci_root);

	switch (clock & 0x07) {
	case 0:
		dev_priv->core_freq = 100;
		break;
	case 1:
		dev_priv->core_freq = 133;
		break;
	case 2:
		dev_priv->core_freq = 150;
		break;
	case 3:
		dev_priv->core_freq = 178;
		break;
	case 4:
		dev_priv->core_freq = 200;
		break;
	case 5:
	case 6:
	case 7:
		dev_priv->core_freq = 266;
		break;
	default:
		dev_priv->core_freq = 0;
	}
}
コード例 #19
0
ファイル: proc.c プロジェクト: ricardoanguiano/linux-xlnx
static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd,
                               unsigned long arg)
{
    struct pci_dev *dev = PDE_DATA(file_inode(file));
#ifdef HAVE_PCI_MMAP
    struct pci_filp_private *fpriv = file->private_data;
#endif /* HAVE_PCI_MMAP */
    int ret = 0;

    switch (cmd) {
    case PCIIOC_CONTROLLER:
        ret = pci_domain_nr(dev->bus);
        break;

#ifdef HAVE_PCI_MMAP
    case PCIIOC_MMAP_IS_IO:
        fpriv->mmap_state = pci_mmap_io;
        break;

    case PCIIOC_MMAP_IS_MEM:
        fpriv->mmap_state = pci_mmap_mem;
        break;

    case PCIIOC_WRITE_COMBINE:
        if (arg)
            fpriv->write_combine = 1;
        else
            fpriv->write_combine = 0;
        break;

#endif /* HAVE_PCI_MMAP */

    default:
        ret = -EINVAL;
        break;
    }

    return ret;
}
コード例 #20
0
ファイル: hotplug-pci.c プロジェクト: 03199618/linux
int __ref pci_hp_add_bridge(struct pci_dev *dev)
{
	struct pci_bus *parent = dev->bus;
	int pass, busnr, start = parent->busn_res.start;
	int end = parent->busn_res.end;

	for (busnr = start; busnr <= end; busnr++) {
		if (!pci_find_bus(pci_domain_nr(parent), busnr))
			break;
	}
	if (busnr-- > end) {
		printk(KERN_ERR "No bus number available for hot-added bridge %s\n",
				pci_name(dev));
		return -1;
	}
	for (pass = 0; pass < 2; pass++)
		busnr = pci_scan_bridge(parent, dev, busnr, pass);
	if (!dev->subordinate)
		return -1;

	return 0;
}
コード例 #21
0
ファイル: dbgp.c プロジェクト: LITMUS-RT/litmus-rt-odroidx
static int xen_dbgp_op(struct usb_hcd *hcd, int op)
{
	const struct device *ctrlr = hcd_to_bus(hcd)->controller;
	struct physdev_dbgp_op dbgp;

	if (!xen_initial_domain())
		return 0;

	dbgp.op = op;

#ifdef CONFIG_PCI
	if (ctrlr->bus == &pci_bus_type) {
		const struct pci_dev *pdev = to_pci_dev(ctrlr);

		dbgp.u.pci.seg = pci_domain_nr(pdev->bus);
		dbgp.u.pci.bus = pdev->bus->number;
		dbgp.u.pci.devfn = pdev->devfn;
		dbgp.bus = PHYSDEVOP_DBGP_BUS_PCI;
	} else
#endif
		dbgp.bus = PHYSDEVOP_DBGP_BUS_UNKNOWN;

	return HYPERVISOR_physdev_op(PHYSDEVOP_dbgp_op, &dbgp);
}
コード例 #22
0
ファイル: pci_bind.c プロジェクト: AdrianHuang/linux-3.8.13
static int acpi_pci_unbind(struct acpi_device *device)
{
	struct pci_dev *dev;

	dev = acpi_get_pci_dev(device->handle);
	if (!dev)
		goto out;

	device_set_run_wake(&dev->dev, false);
	pci_acpi_remove_pm_notifier(device);
	acpi_power_resource_unregister_device(&dev->dev, device->handle);

	if (!dev->subordinate)
		goto out;

	acpi_pci_irq_del_prt(pci_domain_nr(dev->bus), dev->subordinate->number);

	device->ops.bind = NULL;
	device->ops.unbind = NULL;

out:
	pci_dev_put(dev);
	return 0;
}
コード例 #23
0
static int xen_add_device(struct device *dev)
{
	int r;
	struct pci_dev *pci_dev = to_pci_dev(dev);
#ifdef CONFIG_PCI_IOV
	struct pci_dev *physfn = pci_dev->physfn;
#endif

	if (pci_seg_supported) {
		struct physdev_pci_device_add add = {
			.seg = pci_domain_nr(pci_dev->bus),
			.bus = pci_dev->bus->number,
			.devfn = pci_dev->devfn
		};
#ifdef CONFIG_ACPI
		acpi_handle handle;
#endif

#ifdef CONFIG_PCI_IOV
		if (pci_dev->is_virtfn) {
			add.flags = XEN_PCI_DEV_VIRTFN;
			add.physfn.bus = physfn->bus->number;
			add.physfn.devfn = physfn->devfn;
		} else
#endif
		if (pci_ari_enabled(pci_dev->bus) && PCI_SLOT(pci_dev->devfn))
			add.flags = XEN_PCI_DEV_EXTFN;

#ifdef CONFIG_ACPI
		handle = DEVICE_ACPI_HANDLE(&pci_dev->dev);
		if (!handle)
			handle = DEVICE_ACPI_HANDLE(pci_dev->bus->bridge);
#ifdef CONFIG_PCI_IOV
		if (!handle && pci_dev->is_virtfn)
			handle = DEVICE_ACPI_HANDLE(physfn->bus->bridge);
#endif
		if (handle) {
			acpi_status status;

			do {
				unsigned long long pxm;

				status = acpi_evaluate_integer(handle, "_PXM",
							       NULL, &pxm);
				if (ACPI_SUCCESS(status)) {
					add.optarr[0] = pxm;
					add.flags |= XEN_PCI_DEV_PXM;
					break;
				}
				status = acpi_get_parent(handle, &handle);
			} while (ACPI_SUCCESS(status));
		}
#endif /* CONFIG_ACPI */

		r = HYPERVISOR_physdev_op(PHYSDEVOP_pci_device_add, &add);
		if (r != -ENOSYS)
			return r;
		pci_seg_supported = false;
	}

	if (pci_domain_nr(pci_dev->bus))
		r = -ENOSYS;
#ifdef CONFIG_PCI_IOV
	else if (pci_dev->is_virtfn) {
		struct physdev_manage_pci_ext manage_pci_ext = {
			.bus		= pci_dev->bus->number,
			.devfn		= pci_dev->devfn,
			.is_virtfn 	= 1,
			.physfn.bus	= physfn->bus->number,
			.physfn.devfn	= physfn->devfn,
		};

		r = HYPERVISOR_physdev_op(PHYSDEVOP_manage_pci_add_ext,
			&manage_pci_ext);
	}
#endif
	else if (pci_ari_enabled(pci_dev->bus) && PCI_SLOT(pci_dev->devfn)) {
		struct physdev_manage_pci_ext manage_pci_ext = {
			.bus		= pci_dev->bus->number,
			.devfn		= pci_dev->devfn,
			.is_extfn	= 1,
		};

		r = HYPERVISOR_physdev_op(PHYSDEVOP_manage_pci_add_ext,
			&manage_pci_ext);
	} else {
		struct physdev_manage_pci manage_pci = {
			.bus	= pci_dev->bus->number,
			.devfn	= pci_dev->devfn,
		};

		r = HYPERVISOR_physdev_op(PHYSDEVOP_manage_pci_add,
			&manage_pci);
	}

	return r;
}

static int xen_remove_device(struct device *dev)
{
	int r;
	struct pci_dev *pci_dev = to_pci_dev(dev);

	if (pci_seg_supported) {
		struct physdev_pci_device device = {
			.seg = pci_domain_nr(pci_dev->bus),
			.bus = pci_dev->bus->number,
			.devfn = pci_dev->devfn
		};

		r = HYPERVISOR_physdev_op(PHYSDEVOP_pci_device_remove,
					  &device);
	} else if (pci_domain_nr(pci_dev->bus))
		r = -ENOSYS;
	else {
		struct physdev_manage_pci manage_pci = {
			.bus = pci_dev->bus->number,
			.devfn = pci_dev->devfn
		};

		r = HYPERVISOR_physdev_op(PHYSDEVOP_manage_pci_remove,
					  &manage_pci);
	}

	return r;
}

static int xen_pci_notifier(struct notifier_block *nb,
			    unsigned long action, void *data)
{
	struct device *dev = data;
	int r = 0;

	switch (action) {
	case BUS_NOTIFY_ADD_DEVICE:
		r = xen_add_device(dev);
		break;
	case BUS_NOTIFY_DEL_DEVICE:
		r = xen_remove_device(dev);
		break;
	default:
		return NOTIFY_DONE;
	}
	if (r)
		dev_err(dev, "Failed to %s - passthrough or MSI/MSI-X might fail!\n",
			action == BUS_NOTIFY_ADD_DEVICE ? "add" :
			(action == BUS_NOTIFY_DEL_DEVICE ? "delete" : "?"));
	return NOTIFY_OK;
}

static struct notifier_block device_nb = {
	.notifier_call = xen_pci_notifier,
};

static int __init register_xen_pci_notifier(void)
{
	if (!xen_initial_domain())
		return 0;

	return bus_register_notifier(&pci_bus_type, &device_nb);
}

arch_initcall(register_xen_pci_notifier);
コード例 #24
0
ファイル: common.c プロジェクト: 08opt/linux
static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
{
	return raw_pci_write(pci_domain_nr(bus), bus->number,
				  devfn, where, size, value);
}
コード例 #25
0
ファイル: shpchp_pci.c プロジェクト: CSCLOG/beaglebone
int __ref shpchp_configure_device(struct slot *p_slot)
{
	struct pci_dev *dev;
	struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
	int num, fn;
	struct controller *ctrl = p_slot->ctrl;

	dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0));
	if (dev) {
		ctrl_err(ctrl, "Device %s already exists "
			 "at %04x:%02x:%02x, cannot hot-add\n", pci_name(dev),
			 pci_domain_nr(parent), p_slot->bus, p_slot->device);
		pci_dev_put(dev);
		return -EINVAL;
	}

	num = pci_scan_slot(parent, PCI_DEVFN(p_slot->device, 0));
	if (num == 0) {
		ctrl_err(ctrl, "No new device found\n");
		return -ENODEV;
	}

	for (fn = 0; fn < 8; fn++) {
		dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn));
		if (!dev)
			continue;
		if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
				(dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
			/* Find an unused bus number for the new bridge */
			struct pci_bus *child;
			unsigned char busnr, start = parent->secondary;
			unsigned char end = parent->subordinate;
			for (busnr = start; busnr <= end; busnr++) {
				if (!pci_find_bus(pci_domain_nr(parent),
							busnr))
					break;
			}
			if (busnr > end) {
				ctrl_err(ctrl,
					 "No free bus for hot-added bridge\n");
				pci_dev_put(dev);
				continue;
			}
			child = pci_add_new_bus(parent, dev, busnr);
			if (!child) {
				ctrl_err(ctrl, "Cannot add new bus for %s\n",
					 pci_name(dev));
				pci_dev_put(dev);
				continue;
			}
			child->subordinate = pci_do_scan_bus(child);
			pci_bus_size_bridges(child);
		}
		pci_configure_slot(dev);
		pci_dev_put(dev);
	}

	pci_bus_assign_resources(parent);
	pci_bus_add_devices(parent);
	pci_enable_bridges(parent);
	return 0;
}
コード例 #26
0
static void __devinit cnb20le_res(struct pci_dev *dev)
{
	struct pci_root_info *info;
	struct resource res;
	u16 word1, word2;
	u8 fbus, lbus;
	int i;

	/*
	 * The x86_pci_root_bus_res_quirks() function already refuses to use
	 * this information if ACPI _CRS was used. Therefore, we don't bother
	 * checking if ACPI is enabled, and just generate the information
	 * for both the ACPI _CRS and no ACPI cases.
	 */

	info = &pci_root_info[pci_root_num];
	pci_root_num++;

	/* read the PCI bus numbers */
	pci_read_config_byte(dev, 0x44, &fbus);
	pci_read_config_byte(dev, 0x45, &lbus);
	info->bus_min = fbus;
	info->bus_max = lbus;

	/*
	 * Add the legacy IDE ports on bus 0
	 *
	 * These do not exist anywhere in the bridge registers, AFAICT. I do
	 * not have the datasheet, so this is the best I can do.
	 */
	if (fbus == 0) {
		update_res(info, 0x01f0, 0x01f7, IORESOURCE_IO, 0);
		update_res(info, 0x03f6, 0x03f6, IORESOURCE_IO, 0);
		update_res(info, 0x0170, 0x0177, IORESOURCE_IO, 0);
		update_res(info, 0x0376, 0x0376, IORESOURCE_IO, 0);
		update_res(info, 0xffa0, 0xffaf, IORESOURCE_IO, 0);
	}

	/* read the non-prefetchable memory window */
	pci_read_config_word(dev, 0xc0, &word1);
	pci_read_config_word(dev, 0xc2, &word2);
	if (word1 != word2) {
		res.start = (word1 << 16) | 0x0000;
		res.end   = (word2 << 16) | 0xffff;
		res.flags = IORESOURCE_MEM;
		update_res(info, res.start, res.end, res.flags, 0);
	}

	/* read the prefetchable memory window */
	pci_read_config_word(dev, 0xc4, &word1);
	pci_read_config_word(dev, 0xc6, &word2);
	if (word1 != word2) {
		res.start = (word1 << 16) | 0x0000;
		res.end   = (word2 << 16) | 0xffff;
		res.flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
		update_res(info, res.start, res.end, res.flags, 0);
	}

	/* read the IO port window */
	pci_read_config_word(dev, 0xd0, &word1);
	pci_read_config_word(dev, 0xd2, &word2);
	if (word1 != word2) {
		res.start = word1;
		res.end   = word2;
		res.flags = IORESOURCE_IO;
		update_res(info, res.start, res.end, res.flags, 0);
	}

	/* print information about this host bridge */
	res.start = fbus;
	res.end   = lbus;
	res.flags = IORESOURCE_BUS;
	dev_info(&dev->dev, "CNB20LE PCI Host Bridge (domain %04x %pR)\n",
			    pci_domain_nr(dev->bus), &res);

	for (i = 0; i < info->res_num; i++)
		dev_info(&dev->dev, "host bridge window %pR\n", &info->res[i]);
}
コード例 #27
0
ファイル: cpci_hotplug_pci.c プロジェクト: 274914765/C
int __ref cpci_configure_slot(struct slot *slot)
{
    struct pci_bus *parent;
    int fn;

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

    if (slot->dev == NULL) {
        dbg("pci_dev null, finding %02x:%02x:%x",
            slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn));
        slot->dev = pci_get_slot(slot->bus, slot->devfn);
    }

    /* Still NULL? Well then scan for it! */
    if (slot->dev == NULL) {
        int n;
        dbg("pci_dev still null");

        /*
         * This will generate pci_dev structures for all functions, but
         * we will only call this case when lookup fails.
         */
        n = pci_scan_slot(slot->bus, slot->devfn);
        dbg("%s: pci_scan_slot returned %d", __func__, n);
        slot->dev = pci_get_slot(slot->bus, slot->devfn);
        if (slot->dev == NULL) {
            err("Could not find PCI device for slot %02x", slot->number);
            return -ENODEV;
        }
    }
    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)
            continue;
        if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
            (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
            /* Find an unused bus number for the new bridge */
            struct pci_bus *child;
            unsigned char busnr, start = parent->secondary;
            unsigned char end = parent->subordinate;

            for (busnr = start; busnr <= end; busnr++) {
                if (!pci_find_bus(pci_domain_nr(parent),
                          busnr))
                    break;
            }
            if (busnr >= end) {
                err("No free bus for hot-added bridge\n");
                pci_dev_put(dev);
                continue;
            }
            child = pci_add_new_bus(parent, dev, busnr);
            if (!child) {
                err("Cannot add new bus for %s\n",
                    pci_name(dev));
                pci_dev_put(dev);
                continue;
            }
            child->subordinate = pci_do_scan_bus(child);
            pci_bus_size_bridges(child);
        }
        pci_dev_put(dev);
    }

    pci_bus_assign_resources(parent);
    pci_bus_add_devices(parent);
    pci_enable_bridges(parent);

    dbg("%s - exit", __func__);
    return 0;
}
コード例 #28
0
ファイル: shpchp_ctrl.c プロジェクト: johnny/CobraDroidBeta
/**
 * board_added - Called after a board has been added to the system.
 * @p_slot: target &slot
 *
 * Turns power on for the board.
 * Configures board.
 */
static int board_added(struct slot *p_slot)
{
	u8 hp_slot;
	u8 slots_not_empty = 0;
	int rc = 0;
	enum pci_bus_speed asp, bsp, msp;
	struct controller *ctrl = p_slot->ctrl;
	struct pci_bus *parent = ctrl->pci_dev->subordinate;

	hp_slot = p_slot->device - ctrl->slot_device_offset;

	ctrl_dbg(ctrl,
		 "%s: p_slot->device, slot_offset, hp_slot = %d, %d ,%d\n",
		 __func__, p_slot->device, ctrl->slot_device_offset, hp_slot);

	/* Power on slot without connecting to bus */
	rc = p_slot->hpc_ops->power_on_slot(p_slot);
	if (rc) {
		ctrl_err(ctrl, "Failed to power on slot\n");
		return -1;
	}

	if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) {
		if (slots_not_empty)
			return WRONG_BUS_FREQUENCY;

		if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, PCI_SPEED_33MHz))) {
			ctrl_err(ctrl, "%s: Issue of set bus speed mode command"
				 " failed\n", __func__);
			return WRONG_BUS_FREQUENCY;
		}

		/* turn on board, blink green LED, turn off Amber LED */
		if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) {
			ctrl_err(ctrl, "Issue of Slot Enable command failed\n");
			return rc;
		}
	}

	rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &asp);
	if (rc) {
		ctrl_err(ctrl, "Can't get adapter speed or "
			 "bus mode mismatch\n");
		return WRONG_BUS_FREQUENCY;
	}

	rc = p_slot->hpc_ops->get_cur_bus_speed(p_slot, &bsp);
	if (rc) {
		ctrl_err(ctrl, "Can't get bus operation speed\n");
		return WRONG_BUS_FREQUENCY;
	}

	rc = p_slot->hpc_ops->get_max_bus_speed(p_slot, &msp);
	if (rc) {
		ctrl_err(ctrl, "Can't get max bus operation speed\n");
		msp = bsp;
	}

	/* Check if there are other slots or devices on the same bus */
	if (!list_empty(&ctrl->pci_dev->subordinate->devices))
		slots_not_empty = 1;

	ctrl_dbg(ctrl, "%s: slots_not_empty %d, adapter_speed %d, bus_speed %d,"
		 " max_bus_speed %d\n", __func__, slots_not_empty, asp,
		 bsp, msp);

	rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, asp, bsp, msp);
	if (rc)
		return rc;

	/* turn on board, blink green LED, turn off Amber LED */
	if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) {
		ctrl_err(ctrl, "Issue of Slot Enable command failed\n");
		return rc;
	}

	/* Wait for ~1 second */
	msleep(1000);

	ctrl_dbg(ctrl, "%s: slot status = %x\n", __func__, p_slot->status);
	/* Check for a power fault */
	if (p_slot->status == 0xFF) {
		/* power fault occurred, but it was benign */
		ctrl_dbg(ctrl, "%s: Power fault\n", __func__);
		rc = POWER_FAILURE;
		p_slot->status = 0;
		goto err_exit;
	}

	if (shpchp_configure_device(p_slot)) {
		ctrl_err(ctrl, "Cannot add device at %04x:%02x:%02x\n",
			 pci_domain_nr(parent), p_slot->bus, p_slot->device);
		goto err_exit;
	}

	p_slot->status = 0;
	p_slot->is_a_board = 0x01;
	p_slot->pwr_save = 1;

	p_slot->hpc_ops->green_led_on(p_slot);

	return 0;

err_exit:
	/* turn off slot, turn on Amber LED, turn off Green LED */
	rc = p_slot->hpc_ops->slot_disable(p_slot);
	if (rc) {
		ctrl_err(ctrl, "%s: Issue of Slot Disable command failed\n",
			 __func__);
		return rc;
	}

	return(rc);
}
コード例 #29
0
static int quirk_pcie_aspm_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
{
    return raw_pci_read(pci_domain_nr(bus), bus->number,
                        devfn, where, size, value);
}
コード例 #30
0
ファイル: mid_bios.c プロジェクト: AlexShiLucky/linux
static void mid_get_fuse_settings(struct drm_device *dev)
{
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct pci_dev *pci_root =
		pci_get_domain_bus_and_slot(pci_domain_nr(dev->pdev->bus),
					    0, 0);
	uint32_t fuse_value = 0;
	uint32_t fuse_value_tmp = 0;

#define FB_REG06 0xD0810600
#define FB_MIPI_DISABLE  (1 << 11)
#define FB_REG09 0xD0810900
#define FB_SKU_MASK  0x7000
#define FB_SKU_SHIFT 12
#define FB_SKU_100 0
#define FB_SKU_100L 1
#define FB_SKU_83 2
	if (pci_root == NULL) {
		WARN_ON(1);
		return;
	}


	pci_write_config_dword(pci_root, 0xD0, FB_REG06);
	pci_read_config_dword(pci_root, 0xD4, &fuse_value);

	/* FB_MIPI_DISABLE doesn't mean LVDS on with Medfield */
	if (IS_MRST(dev))
		dev_priv->iLVDS_enable = fuse_value & FB_MIPI_DISABLE;

	DRM_INFO("internal display is %s\n",
		 dev_priv->iLVDS_enable ? "LVDS display" : "MIPI display");

	 /* Prevent runtime suspend at start*/
	 if (dev_priv->iLVDS_enable) {
		dev_priv->is_lvds_on = true;
		dev_priv->is_mipi_on = false;
	} else {
		dev_priv->is_mipi_on = true;
		dev_priv->is_lvds_on = false;
	}

	dev_priv->video_device_fuse = fuse_value;

	pci_write_config_dword(pci_root, 0xD0, FB_REG09);
	pci_read_config_dword(pci_root, 0xD4, &fuse_value);

	dev_dbg(dev->dev, "SKU values is 0x%x.\n", fuse_value);
	fuse_value_tmp = (fuse_value & FB_SKU_MASK) >> FB_SKU_SHIFT;

	dev_priv->fuse_reg_value = fuse_value;

	switch (fuse_value_tmp) {
	case FB_SKU_100:
		dev_priv->core_freq = 200;
		break;
	case FB_SKU_100L:
		dev_priv->core_freq = 100;
		break;
	case FB_SKU_83:
		dev_priv->core_freq = 166;
		break;
	default:
		dev_warn(dev->dev, "Invalid SKU values, SKU value = 0x%08x\n",
								fuse_value_tmp);
		dev_priv->core_freq = 0;
	}
	dev_dbg(dev->dev, "LNC core clk is %dMHz.\n", dev_priv->core_freq);
	pci_dev_put(pci_root);
}