コード例 #1
0
ファイル: quirks.c プロジェクト: CCNITSilchar/linux
/* Set correct numa_node information for AMD NB functions */
static void quirk_amd_nb_node(struct pci_dev *dev)
{
	struct pci_dev *nb_ht;
	unsigned int devfn;
	u32 node;
	u32 val;

	devfn = PCI_DEVFN(PCI_SLOT(dev->devfn), 0);
	nb_ht = pci_get_slot(dev->bus, devfn);
	if (!nb_ht)
		return;

	pci_read_config_dword(nb_ht, 0x60, &val);
	node = pcibus_to_node(dev->bus) | (val & 7);
	/*
	 * Some hardware may return an invalid node ID,
	 * so check it first:
	 */
	if (node_online(node))
		set_dev_node(&dev->dev, node);
	pci_dev_put(nb_ht);
}
コード例 #2
0
/*
 * This function called by IOMMU driver on PPR failure
 */
static int iommu_invalid_ppr_cb(struct pci_dev *pdev, int pasid,
		unsigned long address, u16 flags)
{
	struct kfd_dev *dev;

	dev_warn(kfd_device,
			"Invalid PPR device %x:%x.%x pasid %d address 0x%lX flags 0x%X",
			PCI_BUS_NUM(pdev->devfn),
			PCI_SLOT(pdev->devfn),
			PCI_FUNC(pdev->devfn),
			pasid,
			address,
			flags);

	dev = kfd_device_by_pci_dev(pdev);
	BUG_ON(dev == NULL);

	kfd_signal_iommu_event(dev, pasid, address,
			flags & PPR_FAULT_WRITE, flags & PPR_FAULT_EXEC);

	return AMD_IOMMU_INV_PRI_RSP_INVALID;
}
コード例 #3
0
ファイル: direct.c プロジェクト: 303750856/linux-3.1
static int pci_conf2_write(unsigned int seg, unsigned int bus,
			   unsigned int devfn, int reg, int len, u32 value)
{
	unsigned long flags;
	int dev, fn;

	WARN_ON(seg);
	if ((bus > 255) || (devfn > 255) || (reg > 255)) 
		return -EINVAL;

	dev = PCI_SLOT(devfn);
	fn = PCI_FUNC(devfn);

	if (dev & 0x10) 
		return PCIBIOS_DEVICE_NOT_FOUND;

	raw_spin_lock_irqsave(&pci_config_lock, flags);

	outb((u8)(0xF0 | (fn << 1)), 0xCF8);
	outb((u8)bus, 0xCFA);

	switch (len) {
	case 1:
		outb((u8)value, PCI_CONF2_ADDRESS(dev, reg));
		break;
	case 2:
		outw((u16)value, PCI_CONF2_ADDRESS(dev, reg));
		break;
	case 4:
		outl((u32)value, PCI_CONF2_ADDRESS(dev, reg));
		break;
	}

	outb(0, 0xCF8);    

	raw_spin_unlock_irqrestore(&pci_config_lock, flags);

	return 0;
}
コード例 #4
0
static void bcm63xx_fixup_header(struct pci_dev *dev)
{
    uint32 memaddr;
    uint32 size;

    memaddr = pci_resource_start(dev, 0);
    size = pci_resource_len(dev, 0);

    if (dev->bus->number == BCM_BUS_PCI) {
        switch (PCI_SLOT(dev->devfn)) {
#if defined(CONFIG_USB)
            case USB_HOST_SLOT:
                dev->resource[0].flags |= IORESOURCE_PCI_FIXED; // prevent linux from reallocating resources
                break;
    
            case USB20_HOST_SLOT:
               dev->resource[0].flags |= IORESOURCE_PCI_FIXED; // prevent linux from reallocating resources
               break;
#endif
        }
    }
}
コード例 #5
0
ファイル: xenbus.c プロジェクト: 0xroot/Blackphone-BP1-Kernel
static int xen_pcibk_publish_pci_dev(struct xen_pcibk_device *pdev,
				   unsigned int domain, unsigned int bus,
				   unsigned int devfn, unsigned int devid)
{
	int err;
	int len;
	char str[64];

	len = snprintf(str, sizeof(str), "vdev-%d", devid);
	if (unlikely(len >= (sizeof(str) - 1))) {
		err = -ENOMEM;
		goto out;
	}

	/* Note: The PV protocol uses %02x, don't change it */
	err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, str,
			    "%04x:%02x:%02x.%02x", domain, bus,
			    PCI_SLOT(devfn), PCI_FUNC(devfn));

out:
	return err;
}
コード例 #6
0
ファイル: adf_ctl_drv.c プロジェクト: 3null/linux
static int adf_ctl_ioctl_get_status(struct file *fp, unsigned int cmd,
				    unsigned long arg)
{
	struct adf_hw_device_data *hw_data;
	struct adf_dev_status_info dev_info;
	struct adf_accel_dev *accel_dev;

	if (copy_from_user(&dev_info, (void __user *)arg,
			   sizeof(struct adf_dev_status_info))) {
		pr_err("QAT: failed to copy from user.\n");
		return -EFAULT;
	}

	accel_dev = adf_devmgr_get_dev_by_id(dev_info.accel_id);
	if (!accel_dev) {
		pr_err("QAT: Device %d not found\n", dev_info.accel_id);
		return -ENODEV;
	}
	hw_data = accel_dev->hw_device;
	dev_info.state = adf_dev_started(accel_dev) ? DEV_UP : DEV_DOWN;
	dev_info.num_ae = hw_data->get_num_aes(hw_data);
	dev_info.num_accel = hw_data->get_num_accels(hw_data);
	dev_info.num_logical_accel = hw_data->num_logical_accel;
	dev_info.banks_per_accel = hw_data->num_banks
					/ hw_data->num_logical_accel;
	strlcpy(dev_info.name, hw_data->dev_class->name, sizeof(dev_info.name));
	dev_info.instance_id = hw_data->instance_id;
	dev_info.type = hw_data->dev_class->type;
	dev_info.bus = accel_to_pci_dev(accel_dev)->bus->number;
	dev_info.dev = PCI_SLOT(accel_to_pci_dev(accel_dev)->devfn);
	dev_info.fun = PCI_FUNC(accel_to_pci_dev(accel_dev)->devfn);

	if (copy_to_user((void __user *)arg, &dev_info,
			 sizeof(struct adf_dev_status_info))) {
		pr_err("QAT: failed to copy status.\n");
		return -EFAULT;
	}
	return 0;
}
コード例 #7
0
ファイル: hotplug.c プロジェクト: iPodLinux/linux-2.6.7-ipod
/**
 * pci_visit_dev - scans the pci buses.
 * Every bus and every function is presented to a custom
 * function that can act upon it.
 */
int pci_visit_dev(struct pci_visit *fn, struct pci_dev_wrapped *wrapped_dev,
		  struct pci_bus_wrapped *wrapped_parent)
{
	struct pci_dev* dev = wrapped_dev ? wrapped_dev->dev : NULL;
	int result = 0;

	if (!dev)
		return 0;

	if (fn->pre_visit_pci_dev) {
		result = fn->pre_visit_pci_dev(wrapped_dev, wrapped_parent);
		if (result)
			return result;
	}

	switch (dev->class >> 8) {
		case PCI_CLASS_BRIDGE_PCI:
			result = pci_visit_bridge(fn, wrapped_dev,
						  wrapped_parent);
			if (result)
				return result;
			break;
		default:
			DBG("scanning device %02x, %02x\n",
			    PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
			if (fn->visit_pci_dev) {
				result = fn->visit_pci_dev (wrapped_dev,
							    wrapped_parent);
				if (result)
					return result;
			}
	}

	if (fn->post_visit_pci_dev)
		result = fn->post_visit_pci_dev(wrapped_dev, wrapped_parent);

	return result;
}
コード例 #8
0
ファイル: pdc202xx_new.c プロジェクト: Epirex/Chrono_Kernel-1
static int __devinit pdc202new_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
	const struct ide_port_info *d = &pdcnew_chipsets[id->driver_data];
	struct pci_dev *bridge = dev->bus->self;

	if (dev->device == PCI_DEVICE_ID_PROMISE_20270 && bridge &&
	    bridge->vendor == PCI_VENDOR_ID_DEC &&
	    bridge->device == PCI_DEVICE_ID_DEC_21150) {
		struct pci_dev *dev2;

		if (PCI_SLOT(dev->devfn) & 2)
			return -ENODEV;

		dev2 = pdc20270_get_dev2(dev);

		if (dev2) {
			int ret = ide_pci_init_two(dev, dev2, d, NULL);
			if (ret < 0)
				pci_dev_put(dev2);
			return ret;
		}
	}

	if (dev->device == PCI_DEVICE_ID_PROMISE_20276 && bridge &&
	    bridge->vendor == PCI_VENDOR_ID_INTEL &&
	    (bridge->device == PCI_DEVICE_ID_INTEL_I960 ||
	     bridge->device == PCI_DEVICE_ID_INTEL_I960RM)) {
#ifdef CONFIG_DEBUG_PRINTK
		printk(KERN_INFO DRV_NAME " %s: attached to I2O RAID controller,"
			" skipping\n", pci_name(dev));
#else
		;
#endif
		return -ENODEV;
	}

	return ide_pci_init_one(dev, d, NULL);
}
コード例 #9
0
ファイル: i2c.c プロジェクト: lynxis/coreboot-signed
static void i2c_early_init_bus(unsigned int bus)
{
	ROMSTAGE_CONST struct soc_intel_skylake_config *config;
	ROMSTAGE_CONST struct device *tree_dev;
	pci_devfn_t dev;
	int devfn;
	uintptr_t base;

	/* Find the PCI device for this bus controller */
	devfn = i2c_bus_to_devfn(bus);
	if (devfn < 0)
		return;

	/* Look up the controller device in the devicetree */
	dev = PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn));
	tree_dev = dev_find_slot(0, devfn);
	if (!tree_dev || !tree_dev->enabled)
		return;

	/* Skip if not enabled for early init */
	config = tree_dev->chip_info;
	if (!config)
		return;
	if (!config->i2c[bus].early_init)
		return;

	/* Prepare early base address for access before memory */
	base = EARLY_I2C_BASE(bus);
	pci_write_config32(dev, PCI_BASE_ADDRESS_0, base);
	pci_write_config32(dev, PCI_COMMAND,
			   PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);

	/* Take device out of reset */
	lpss_reset_release(base);

	/* Initialize the controller */
	lpss_i2c_init(bus, &config->i2c[bus]);
}
コード例 #10
0
/**
 * Note access to the configuration registers are protected at the higher layer
 * by 'pci_lock' in drivers/pci/access.c
 */
static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,
					    unsigned int devfn,
					    int where)
{
	struct iproc_pcie *pcie = iproc_data(bus);
	unsigned slot = PCI_SLOT(devfn);
	unsigned fn = PCI_FUNC(devfn);
	unsigned busno = bus->number;
	u32 val;
	u16 offset;

	if (!iproc_pcie_device_is_valid(pcie, slot, fn))
		return NULL;

	/* root complex access */
	if (busno == 0) {
		iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_IND_ADDR,
				     where & CFG_IND_ADDR_MASK);
		offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_IND_DATA);
		if (iproc_pcie_reg_is_invalid(offset))
			return NULL;
		else
			return (pcie->base + offset);
	}

	/* EP device access */
	val = (busno << CFG_ADDR_BUS_NUM_SHIFT) |
		(slot << CFG_ADDR_DEV_NUM_SHIFT) |
		(fn << CFG_ADDR_FUNC_NUM_SHIFT) |
		(where & CFG_ADDR_REG_NUM_MASK) |
		(1 & CFG_ADDR_CFG_TYPE_MASK);
	iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_ADDR, val);
	offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_DATA);
	if (iproc_pcie_reg_is_invalid(offset))
		return NULL;
	else
		return (pcie->base + offset);
}
コード例 #11
0
ファイル: pci-keystone-dw.c プロジェクト: 19Dan01/linux
/**
 * ks_pcie_cfg_setup() - Set up configuration space address for a device
 *
 * @ks_pcie: ptr to keystone_pcie structure
 * @bus: Bus number the device is residing on
 * @devfn: device, function number info
 *
 * Forms and returns the address of configuration space mapped in PCIESS
 * address space 0.  Also configures CFG_SETUP for remote configuration space
 * access.
 *
 * The address space has two regions to access configuration - local and remote.
 * We access local region for bus 0 (as RC is attached on bus 0) and remote
 * region for others with TYPE 1 access when bus > 1.  As for device on bus = 1,
 * we will do TYPE 0 access as it will be on our secondary bus (logical).
 * CFG_SETUP is needed only for remote configuration access.
 */
static void __iomem *ks_pcie_cfg_setup(struct keystone_pcie *ks_pcie, u8 bus,
				       unsigned int devfn)
{
	u8 device = PCI_SLOT(devfn), function = PCI_FUNC(devfn);
	struct pcie_port *pp = &ks_pcie->pp;
	u32 regval;

	if (bus == 0)
		return pp->dbi_base;

	regval = (bus << 16) | (device << 8) | function;

	/*
	 * Since Bus#1 will be a virtual bus, we need to have TYPE0
	 * access only.
	 * TYPE 1
	 */
	if (bus != 1)
		regval |= BIT(24);

	writel(regval, ks_pcie->va_app_base + CFG_SETUP);
	return pp->va_cfg0_base;
}
コード例 #12
0
ファイル: iommu.c プロジェクト: Addision/LVS
int kvm_deassign_device(struct kvm *kvm,
			struct kvm_assigned_dev_kernel *assigned_dev)
{
	struct iommu_domain *domain = kvm->arch.iommu_domain;
	struct pci_dev *pdev = NULL;

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

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

	iommu_detach_device(domain, &pdev->dev);

	printk(KERN_DEBUG "deassign device: host bdf = %x:%x:%x\n",
		assigned_dev->host_busnr,
		PCI_SLOT(assigned_dev->host_devfn),
		PCI_FUNC(assigned_dev->host_devfn));

	return 0;
}
コード例 #13
0
ファイル: pci-ip27.c プロジェクト: AlexShiLucky/linux
/* Do platform specific device initialization at pci_enable_device() time */
int pcibios_plat_dev_init(struct pci_dev *dev)
{
	struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
	struct pci_dev *rdev = bridge_root_dev(dev);
	int slot = PCI_SLOT(rdev->devfn);
	int irq;

	irq = bc->pci_int[slot];
	if (irq == -1) {
		irq = request_bridge_irq(bc);
		if (irq < 0)
			return irq;

		bc->pci_int[slot] = irq;
	}

	irq_to_bridge[irq] = bc;
	irq_to_slot[irq] = slot;

	dev->irq = irq;

	return 0;
}
コード例 #14
0
uintptr_t dw_i2c_base_address(unsigned int bus)
{
	int devfn;
	pci_devfn_t dev;
	uintptr_t base;

	/* Find device+function for this controller */
	devfn = dw_i2c_soc_bus_to_devfn(bus);
	if (devfn < 0)
		return (uintptr_t)NULL;

	/* Form a PCI address for this device */
	dev = PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn));

	/* Read the first base address for this device */
	base = ALIGN_DOWN(pci_read_config32(dev, PCI_BASE_ADDRESS_0), 16);

	/* Attempt to initialize bus if base is not set yet */
	if (!base && !lpss_i2c_early_init_bus(bus))
		base = ALIGN_DOWN(pci_read_config32(dev, PCI_BASE_ADDRESS_0),
				  16);
	return base;
}
コード例 #15
0
void pci_device_hot_add(Monitor *mon, const QDict *qdict)
{
    PCIDevice *dev = NULL;
    const char *pci_addr = qdict_get_str(qdict, "pci_addr");
    const char *type = qdict_get_str(qdict, "type");
    const char *opts = qdict_get_try_str(qdict, "opts");

    /* strip legacy tag */
    if (!strncmp(pci_addr, "pci_addr=", 9)) {
        pci_addr += 9;
    }

    if (!opts) {
        opts = "";
    }

    if (!strcmp(pci_addr, "auto"))
        pci_addr = NULL;

    if (strcmp(type, "nic") == 0)
        dev = qemu_pci_hot_add_nic(mon, pci_addr, opts);
    else if (strcmp(type, "storage") == 0)
        dev = qemu_pci_hot_add_storage(mon, pci_addr, opts);
#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT
    else if (strcmp(type, "host") == 0)
        dev = qemu_pci_hot_assign_device(mon, pci_addr, opts);
#endif /* CONFIG_KVM_DEVICE_ASSIGNMENT */
    else
        monitor_printf(mon, "invalid type: %s\n", type);

    if (dev) {
        monitor_printf(mon, "OK domain %d, bus %d, slot %d, function %d\n",
                       0, pci_bus_num(dev->bus), PCI_SLOT(dev->devfn),
                       PCI_FUNC(dev->devfn));
    } else
        monitor_printf(mon, "failed to add %s\n", opts);
}
コード例 #16
0
static void bcm63xx_fixup_final(struct pci_dev *dev)
{
    uint32 memaddr;
    uint32 size;
    uint32 resno;

    memaddr = pci_resource_start(dev, 0);
    size = pci_resource_len(dev, 0);

    if (dev->bus->number == BCM_BUS_PCI) {
    
        switch (PCI_SLOT(dev->devfn)) {
#if defined(CONFIG_BCM96368)
            case 0:   
                // Move device in slot 0 to a different memory range
                // In case this is a CB device, it will be accessed via l2pmremap1
                // which will have CARDBUS_MEM bit set
                for (resno = 0; resno < 6; resno++) {
                    if (dev->resource[resno].end && (dev->resource[resno].start < BCM_CB_MEM_BASE)) {
                        dev->resource[resno].start += (BCM_CB_MEM_BASE - BCM_PCI_MEM_BASE);
                        dev->resource[resno].end += (BCM_CB_MEM_BASE - BCM_PCI_MEM_BASE);
                        dev->resource[resno].flags |= IORESOURCE_PCI_FIXED; // prevent linux from reallocating resources
                    }
                }   
                break;
#endif                
#if defined(CONFIG_BCM96362)              
            case WLAN_ONCHIP_DEV_SLOT:            	
                 if(((dev->device<<16)|dev->vendor) == WLAN_ONCHIP_PCI_ID) {                        	      
                      dev->resource[0].end   = WLAN_CHIPC_BASE+ WLAN_ONCHIP_RESOURCE_SIZE -1 ;
                      dev->resource[0].start = WLAN_CHIPC_BASE;
                 }                
#endif                       
		break;            
        }
    }
}
コード例 #17
0
ファイル: msi.c プロジェクト: BackupTheBerlios/tuxap
void pci_disable_msi(struct pci_dev* dev)
{
	struct msi_desc *entry;
	int pos, default_vector;
	u16 control;
	unsigned long flags;

   	if (!dev || !(pos = pci_find_capability(dev, PCI_CAP_ID_MSI)))
		return;

	pci_read_config_word(dev, msi_control_reg(pos), &control);
	if (!(control & PCI_MSI_FLAGS_ENABLE))
		return;

	spin_lock_irqsave(&msi_lock, flags);
	entry = msi_desc[dev->irq];
	if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) {
		spin_unlock_irqrestore(&msi_lock, flags);
		return;
	}
	if (entry->msi_attrib.state) {
		spin_unlock_irqrestore(&msi_lock, flags);
		printk(KERN_DEBUG "Driver[%d:%d:%d] unloaded wo doing free_irq on vector->%d\n",
		dev->bus->number, PCI_SLOT(dev->devfn),	PCI_FUNC(dev->devfn),
		dev->irq);
		BUG_ON(entry->msi_attrib.state > 0);
	} else {
		vector_irq[dev->irq] = 0; /* free it */
		nr_released_vectors++;
		default_vector = entry->msi_attrib.default_vector;
		spin_unlock_irqrestore(&msi_lock, flags);
		/* Restore dev->irq to its default pin-assertion vector */
		dev->irq = default_vector;
		disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI),
					PCI_CAP_ID_MSI);
	}
}
コード例 #18
0
ファイル: undiload.c プロジェクト: CSU-GH/gpxe
/**
 * Call UNDI loader to create a pixie
 *
 * @v undi		UNDI device
 * @v undirom		UNDI ROM
 * @ret rc		Return status code
 */
int undi_load ( struct undi_device *undi, struct undi_rom *undirom ) {
	struct s_PXE ppxe;
	unsigned int fbms_seg;
	uint16_t exit;
	int rc;

	/* Only one UNDI instance may be loaded at any given time */
	if ( undi_loader_entry.segment ) {
		DBG ( "UNDI %p cannot load multiple instances\n", undi );
		return -EBUSY;
	}

	/* Set up START_UNDI parameters */
	memset ( &undi_loader, 0, sizeof ( undi_loader ) );
	undi_loader.AX = undi->pci_busdevfn;
	undi_loader.BX = undi->isapnp_csn;
	undi_loader.DX = undi->isapnp_read_port;
	undi_loader.ES = BIOS_SEG;
	undi_loader.DI = find_pnp_bios();

	/* Allocate base memory for PXE stack */
	undi->restore_fbms = get_fbms();
	fbms_seg = ( undi->restore_fbms << 6 );
	fbms_seg -= ( ( undirom->code_size + 0x0f ) >> 4 );
	undi_loader.UNDI_CS = fbms_seg;
	fbms_seg -= ( ( undirom->data_size + 0x0f ) >> 4 );
	undi_loader.UNDI_DS = fbms_seg;

	/* Debug info */
	DBGC ( undi, "UNDI %p loading UNDI ROM %p to CS %04x DS %04x for ",
	       undi, undirom, undi_loader.UNDI_CS, undi_loader.UNDI_DS );
	if ( undi->pci_busdevfn != UNDI_NO_PCI_BUSDEVFN ) {
		unsigned int bus = ( undi->pci_busdevfn >> 8 );
		unsigned int devfn = ( undi->pci_busdevfn & 0xff );
		DBGC ( undi, "PCI %02x:%02x.%x\n",
		       bus, PCI_SLOT ( devfn ), PCI_FUNC ( devfn ) );
	}
コード例 #19
0
ファイル: ppc440spe_pcie.c プロジェクト: 274914765/C
static int
pcie_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
              int len, u32 val)
{
    struct pci_controller *hose = bus->sysdata;

    if (PCI_SLOT(devfn) != 1)
        return PCIBIOS_DEVICE_NOT_FOUND;

    offset += devfn << 12;

    switch (len) {
    case 1:
        out_8(hose->cfg_data + offset, val);
        break;
    case 2:
        out_le16(hose->cfg_data + offset, val);
        break;
    default:
        out_le32(hose->cfg_data + offset, val);
        break;
    }
    return PCIBIOS_SUCCESSFUL;
}
コード例 #20
0
static int msc_pcibios_config_access(unsigned char access_type,
	struct pci_bus *bus, unsigned int devfn, int where, u32 * data)
{
	unsigned char busnum = bus->number;
	u32 intr;

	/* Clear status register bits. */
	MSC_WRITE(MSC01_PCI_INTSTAT,
		  (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT));

	MSC_WRITE(MSC01_PCI_CFGADDR,
		  ((busnum << MSC01_PCI_CFGADDR_BNUM_SHF) |
		   (PCI_SLOT(devfn) << MSC01_PCI_CFGADDR_DNUM_SHF) |
		   (PCI_FUNC(devfn) << MSC01_PCI_CFGADDR_FNUM_SHF) |
		   ((where / 4) << MSC01_PCI_CFGADDR_RNUM_SHF)));

	/* Perform access */
	if (access_type == PCI_ACCESS_WRITE)
		MSC_WRITE(MSC01_PCI_CFGDATA, *data);
	else
		MSC_READ(MSC01_PCI_CFGDATA, *data);

	/* Detect Master/Target abort */
	MSC_READ(MSC01_PCI_INTSTAT, intr);
	if (intr & (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT)) {
		/* Error occurred */

		/* Clear bits */
		MSC_WRITE(MSC01_PCI_INTSTAT,
			  (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT));

		return -1;
	}

	return 0;
}
コード例 #21
0
ファイル: ops-msc.c プロジェクト: Blackburn29/PsycoKernel
static int msc_pcibios_config_access(unsigned char access_type,
	struct pci_bus *bus, unsigned int devfn, int where, u32 * data)
{
	unsigned char busnum = bus->number;
	u32 intr;

	
	MSC_WRITE(MSC01_PCI_INTSTAT,
		  (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT));

	MSC_WRITE(MSC01_PCI_CFGADDR,
		  ((busnum << MSC01_PCI_CFGADDR_BNUM_SHF) |
		   (PCI_SLOT(devfn) << MSC01_PCI_CFGADDR_DNUM_SHF) |
		   (PCI_FUNC(devfn) << MSC01_PCI_CFGADDR_FNUM_SHF) |
		   ((where / 4) << MSC01_PCI_CFGADDR_RNUM_SHF)));

	
	if (access_type == PCI_ACCESS_WRITE)
		MSC_WRITE(MSC01_PCI_CFGDATA, *data);
	else
		MSC_READ(MSC01_PCI_CFGDATA, *data);

	
	MSC_READ(MSC01_PCI_INTSTAT, intr);
	if (intr & (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT)) {
		

		
		MSC_WRITE(MSC01_PCI_INTSTAT,
			  (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT));

		return -1;
	}

	return 0;
}
コード例 #22
0
ファイル: pata_ns87415.c プロジェクト: chunyenho/RTS-hw2
static int ns87415_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
    static int printed_version;
    static const struct ata_port_info info = {
        .flags		= ATA_FLAG_SLAVE_POSS,
        .pio_mask	= ATA_PIO4,
        .mwdma_mask	= ATA_MWDMA2,
        .port_ops	= &ns87415_pata_ops,
    };
    const struct ata_port_info *ppi[] = { &info, NULL };
    int rc;
#if defined(CONFIG_SUPERIO)
    static const struct ata_port_info info87560 = {
        .flags		= ATA_FLAG_SLAVE_POSS,
        .pio_mask	= ATA_PIO4,
        .mwdma_mask	= ATA_MWDMA2,
        .port_ops	= &ns87560_pata_ops,
    };

    if (PCI_SLOT(pdev->devfn) == 0x0E)
        ppi[0] = &info87560;
#endif
    if (!printed_version++)
        dev_printk(KERN_DEBUG, &pdev->dev,
                   "version " DRV_VERSION "\n");

    rc = pcim_enable_device(pdev);
    if (rc)
        return rc;

    /* Select 512 byte sectors */
    pci_write_config_byte(pdev, 0x55, 0xEE);
    /* Select PIO0 8bit clocking */
    pci_write_config_byte(pdev, 0x54, 0xB7);
    return ata_pci_sff_init_one(pdev, ppi, &ns87415_sht, NULL);
}
コード例 #23
0
/*
 * Titan PCI Config Byte Write
 */
static int titan_write_config(struct pci_bus *bus, unsigned int devfn, int reg,
	int size, u32 val)
{
	uint32_t address_reg, data_reg, address;
	int dev, bus, func;

	bus = device->bus->number;
	dev = PCI_SLOT(device->devfn);
	func = PCI_FUNC(device->devfn);

	address_reg = TITAN_PCI_0_CONFIG_ADDRESS;
	data_reg = TITAN_PCI_0_CONFIG_DATA;

	address = (bus << 16) | (dev << 11) | (func << 8) |
		(offset & 0xfc) | 0x80000000;

	/* start the configuration cycle */
	TITAN_WRITE(address_reg, address);

	/* write the data */
	switch (size) {
	case 1:
		TITAN_WRITE_8(data_reg + (offset & 0x3), val);
		break;

	case 2:
		TITAN_WRITE_16(data_reg + (offset & 0x2), val);
		break;

	case 4:
		TITAN_WRITE(data_reg, val);
		break;
	}

	return PCIBIOS_SUCCESSFUL;
}
コード例 #24
0
ファイル: pci.c プロジェクト: nhanh0/hah
void __init pcibios_fixup_irqs(void)
{
        struct pci_dev *dev;
        int slot_num;

	pci_for_each_dev(dev) {
		slot_num = PCI_SLOT(dev->devfn);

               /* we don't do IRQ fixup for sub-bus yet */
               if (dev->bus->parent != NULL) {
                       db_run(printk("Don't know how to fixup irq for PCI device %d on sub-bus %d\n",
                                       slot_num, dev->bus->number));
                       continue;
               }

		db_assert(slot_num < MAX_SLOT_NUM);
		db_assert(irq_map[slot_num] != 0xff);

		pci_write_config_byte(dev, 
				      PCI_INTERRUPT_LINE,
				      irq_map[slot_num]);
		dev->irq = vrc5477_irq_to_irq(irq_map[slot_num]);
	}
}
コード例 #25
0
ファイル: pci.c プロジェクト: TitaniumBoy/lin
/*
 * snia64_read_config_dword - Read 4 bytes from the config area of the device.
 */
static int snia64_read_config_dword (struct pci_dev *dev,
                                    int where, unsigned int *val)
{
	unsigned long res = 0;
	unsigned size = 4; /* 4 bytes */
	devfs_handle_t device_vertex;

	if (where & 3) {
		return PCIBIOS_BAD_REGISTER_NUMBER;
	}
	if ( (dev == (struct pci_dev *)0) || (val == (unsigned int *)0) ) {
		return PCIBIOS_DEVICE_NOT_FOUND;
	}

	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
	if (!device_vertex) {
		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
		return(-1);
	}
	res = pciio_config_get(device_vertex, (unsigned) where, size);
	*val = (unsigned int) res;
	return PCIBIOS_SUCCESSFUL;
}
コード例 #26
0
ファイル: driver_pci_host.c プロジェクト: schidler/RT5350
/* Early PCI fixup for all PCI-cores to set the correct memory address. */
static void bcma_core_pci_fixup_addresses(struct pci_dev *dev)
{
    struct resource *res;
    int pos, err;

    if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
        /* This is not a device on the PCI-core bridge. */
        return;
    }
    if (PCI_SLOT(dev->devfn) == 0)
        return;

    pr_info("PCI: Fixing up addresses %s\n", pci_name(dev));

    for (pos = 0; pos < 6; pos++) {
        res = &dev->resource[pos];
        if (res->flags & (IORESOURCE_IO | IORESOURCE_MEM)) {
            err = pci_assign_resource(dev, pos);
            if (err)
                pr_err("PCI: Problem fixing up the addresses on %s\n",
                       pci_name(dev));
        }
    }
}
コード例 #27
0
static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
		struct ieee80211_hw *hw)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
	struct pci_dev *bridge_pdev = pdev->bus->self;
	u16 venderid;
	u16 deviceid;
	u16 irqline;
	u8 tmp;

	venderid = pdev->vendor;
	deviceid = pdev->device;
	pci_read_config_word(pdev, 0x3C, &irqline);

	if (deviceid == RTL_PCI_8192_DID ||
	    deviceid == RTL_PCI_0044_DID ||
	    deviceid == RTL_PCI_0047_DID ||
	    deviceid == RTL_PCI_8192SE_DID ||
	    deviceid == RTL_PCI_8174_DID ||
	    deviceid == RTL_PCI_8173_DID ||
	    deviceid == RTL_PCI_8172_DID ||
	    deviceid == RTL_PCI_8171_DID) {
		switch (pdev->revision) {
		case RTL_PCI_REVISION_ID_8192PCIE:
			RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
				 ("8192 PCI-E is found - "
				  "vid/did=%x/%x\n", venderid, deviceid));
			rtlhal->hw_type = HARDWARE_TYPE_RTL8192E;
			break;
		case RTL_PCI_REVISION_ID_8192SE:
			RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
				 ("8192SE is found - "
				  "vid/did=%x/%x\n", venderid, deviceid));
			rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE;
			break;
		default:
			RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
				 ("Err: Unknown device - "
				  "vid/did=%x/%x\n", venderid, deviceid));
			rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE;
			break;

		}
	} else if (deviceid == RTL_PCI_8192CET_DID ||
		   deviceid == RTL_PCI_8192CE_DID ||
		   deviceid == RTL_PCI_8191CE_DID ||
		   deviceid == RTL_PCI_8188CE_DID) {
		rtlhal->hw_type = HARDWARE_TYPE_RTL8192CE;
		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
			 ("8192C PCI-E is found - "
			  "vid/did=%x/%x\n", venderid, deviceid));
	} else {
		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
			 ("Err: Unknown device -"
			  " vid/did=%x/%x\n", venderid, deviceid));

		rtlhal->hw_type = RTL_DEFAULT_HARDWARE_TYPE;
	}

	/*find bus info */
	pcipriv->ndis_adapter.busnumber = pdev->bus->number;
	pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn);
	pcipriv->ndis_adapter.funcnumber = PCI_FUNC(pdev->devfn);

	/*find bridge info */
	pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor;
	for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) {
		if (bridge_pdev->vendor == pcibridge_vendors[tmp]) {
			pcipriv->ndis_adapter.pcibridge_vendor = tmp;
			RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
				 ("Pci Bridge Vendor is found index: %d\n",
				  tmp));
			break;
		}
	}

	if (pcipriv->ndis_adapter.pcibridge_vendor !=
		PCI_BRIDGE_VENDOR_UNKNOWN) {
		pcipriv->ndis_adapter.pcibridge_busnum =
		    bridge_pdev->bus->number;
		pcipriv->ndis_adapter.pcibridge_devnum =
		    PCI_SLOT(bridge_pdev->devfn);
		pcipriv->ndis_adapter.pcibridge_funcnum =
		    PCI_FUNC(bridge_pdev->devfn);
		pcipriv->ndis_adapter.pcibridge_pciehdr_offset =
		    pci_pcie_cap(bridge_pdev);
		pcipriv->ndis_adapter.pcicfg_addrport =
		    (pcipriv->ndis_adapter.pcibridge_busnum << 16) |
		    (pcipriv->ndis_adapter.pcibridge_devnum << 11) |
		    (pcipriv->ndis_adapter.pcibridge_funcnum << 8) | (1 << 31);
		pcipriv->ndis_adapter.num4bytes =
		    (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10) / 4;

		rtl_pci_get_linkcontrol_field(hw);

		if (pcipriv->ndis_adapter.pcibridge_vendor ==
		    PCI_BRIDGE_VENDOR_AMD) {
			pcipriv->ndis_adapter.amd_l1_patch =
			    rtl_pci_get_amd_l1_patch(hw);
		}
	}

	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
		 ("pcidev busnumber:devnumber:funcnumber:"
		  "vendor:link_ctl %d:%d:%d:%x:%x\n",
		  pcipriv->ndis_adapter.busnumber,
		  pcipriv->ndis_adapter.devnumber,
		  pcipriv->ndis_adapter.funcnumber,
		  pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg));

	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
		 ("pci_bridge busnumber:devnumber:funcnumber:vendor:"
		  "pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n",
		  pcipriv->ndis_adapter.pcibridge_busnum,
		  pcipriv->ndis_adapter.pcibridge_devnum,
		  pcipriv->ndis_adapter.pcibridge_funcnum,
		  pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor],
		  pcipriv->ndis_adapter.pcibridge_pciehdr_offset,
		  pcipriv->ndis_adapter.pcibridge_linkctrlreg,
		  pcipriv->ndis_adapter.amd_l1_patch));

	rtl_pci_parse_configuration(pdev, hw);

	return true;
}
コード例 #28
0
ファイル: sdhci-pci.c プロジェクト: vikastaneja/linux
static int jmicron_probe(struct sdhci_pci_chip *chip)
{
	int ret;
	u16 mmcdev = 0;

	if (chip->pdev->revision == 0) {
		chip->quirks |= SDHCI_QUIRK_32BIT_DMA_ADDR |
			  SDHCI_QUIRK_32BIT_DMA_SIZE |
			  SDHCI_QUIRK_32BIT_ADMA_SIZE |
			  SDHCI_QUIRK_RESET_AFTER_REQUEST |
			  SDHCI_QUIRK_BROKEN_SMALL_PIO;
	}

	/*
	 * JMicron chips can have two interfaces to the same hardware
	 * in order to work around limitations in Microsoft's driver.
	 * We need to make sure we only bind to one of them.
	 *
	 * This code assumes two things:
	 *
	 * 1. The PCI code adds subfunctions in order.
	 *
	 * 2. The MMC interface has a lower subfunction number
	 *    than the SD interface.
	 */
	if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_SD)
		mmcdev = PCI_DEVICE_ID_JMICRON_JMB38X_MMC;
	else if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_SD)
		mmcdev = PCI_DEVICE_ID_JMICRON_JMB388_ESD;

	if (mmcdev) {
		struct pci_dev *sd_dev;

		sd_dev = NULL;
		while ((sd_dev = pci_get_device(PCI_VENDOR_ID_JMICRON,
						mmcdev, sd_dev)) != NULL) {
			if ((PCI_SLOT(chip->pdev->devfn) ==
				PCI_SLOT(sd_dev->devfn)) &&
				(chip->pdev->bus == sd_dev->bus))
				break;
		}

		if (sd_dev) {
			pci_dev_put(sd_dev);
			dev_info(&chip->pdev->dev, "Refusing to bind to "
				"secondary interface.\n");
			return -ENODEV;
		}
	}

	/*
	 * JMicron chips need a bit of a nudge to enable the power
	 * output pins.
	 */
	ret = jmicron_pmos(chip, 1);
	if (ret) {
		dev_err(&chip->pdev->dev, "Failure enabling card power\n");
		return ret;
	}

	/* quirk for unsable RO-detection on JM388 chips */
	if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_SD ||
	    chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD)
		chip->quirks |= SDHCI_QUIRK_UNSTABLE_RO_DETECT;

	return 0;
}
コード例 #29
0
ファイル: pcibr_dma.c プロジェクト: 1x23/unifi-gpl
static dma_addr_t
pcibr_dmamap_ate32(struct pcidev_info *info,
		   uint64_t paddr, size_t req_size, uint64_t flags)
{

	struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info;
	struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info->
	    pdi_pcibus_info;
	uint8_t internal_device = (PCI_SLOT(pcidev_info->pdi_host_pcidev_info->
					    pdi_linux_pcidev->devfn)) - 1;
	int ate_count;
	int ate_index;
	uint64_t ate_flags = flags | PCI32_ATE_V;
	uint64_t ate;
	uint64_t pci_addr;
	uint64_t xio_addr;
	uint64_t offset;

	/* PIC in PCI-X mode does not supports 32bit PageMap mode */
	if (IS_PIC_SOFT(pcibus_info) && IS_PCIX(pcibus_info)) {
		return 0;
	}

	/* Calculate the number of ATEs needed. */
	if (!(MINIMAL_ATE_FLAG(paddr, req_size))) {
		ate_count = IOPG((IOPGSIZE - 1)	/* worst case start offset */
				 +req_size	/* max mapping bytes */
				 - 1) + 1;	/* round UP */
	} else {		/* assume requested target is page aligned */
		ate_count = IOPG(req_size	/* max mapping bytes */
				 - 1) + 1;	/* round UP */
	}

	/* Get the number of ATEs required. */
	ate_index = pcibr_ate_alloc(pcibus_info, ate_count);
	if (ate_index < 0)
		return 0;

	/* In PCI-X mode, Prefetch not supported */
	if (IS_PCIX(pcibus_info))
		ate_flags &= ~(PCI32_ATE_PREF);

	xio_addr =
	    IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) :
	    PHYS_TO_TIODMA(paddr);
	offset = IOPGOFF(xio_addr);
	ate = ate_flags | (xio_addr - offset);

	/* If PIC, put the targetid in the ATE */
	if (IS_PIC_SOFT(pcibus_info)) {
		ate |= (pcibus_info->pbi_hub_xid << PIC_ATE_TARGETID_SHFT);
	}
	ate_write(pcibus_info, ate_index, ate_count, ate);

	/*
	 * Set up the DMA mapped Address.
	 */
	pci_addr = PCI32_MAPPED_BASE + offset + IOPGSIZE * ate_index;

	/*
	 * If swap was set in device in pcibr_endian_set()
	 * we need to turn swapping on.
	 */
	if (pcibus_info->pbi_devreg[internal_device] & PCIBR_DEV_SWAP_DIR)
		ATE_SWAP_ON(pci_addr);

	return pci_addr;
}
コード例 #30
0
ファイル: hysdn_procconf.c プロジェクト: Aaroneke/galaxy-2636
static int
hysdn_conf_open(struct inode *ino, struct file *filep)
{
	hysdn_card *card;
	struct proc_dir_entry *pd;
	struct conf_writedata *cnf;
	char *cp, *tmp;

	/* now search the addressed card */
	mutex_lock(&hysdn_conf_mutex);
	card = card_root;
	while (card) {
		pd = card->procconf;
		if (pd == PDE(ino))
			break;
		card = card->next;	/* search next entry */
	}
	if (!card) {
		mutex_unlock(&hysdn_conf_mutex);
		return (-ENODEV);	/* device is unknown/invalid */
	}
	if (card->debug_flags & (LOG_PROC_OPEN | LOG_PROC_ALL))
		hysdn_addlog(card, "config open for uid=%d gid=%d mode=0x%x",
			     filep->f_cred->fsuid, filep->f_cred->fsgid,
			     filep->f_mode);

	if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) {
		/* write only access -> write boot file or conf line */

		if (!(cnf = kmalloc(sizeof(struct conf_writedata), GFP_KERNEL))) {
			mutex_unlock(&hysdn_conf_mutex);
			return (-EFAULT);
		}
		cnf->card = card;
		cnf->buf_size = 0;	/* nothing buffered */
		cnf->state = CONF_STATE_DETECT;		/* start auto detect */
		filep->private_data = cnf;

	} else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
		/* read access -> output card info data */

		if (!(tmp = kmalloc(INFO_OUT_LEN * 2 + 2, GFP_KERNEL))) {
			mutex_unlock(&hysdn_conf_mutex);
			return (-EFAULT);	/* out of memory */
		}
		filep->private_data = tmp;	/* start of string */

		/* first output a headline */
		sprintf(tmp, "id bus slot type irq iobase dp-mem     b-chans fax-chans state device");
		cp = tmp;	/* start of string */
		while (*cp)
			cp++;
		while (((cp - tmp) % (INFO_OUT_LEN + 1)) != INFO_OUT_LEN)
			*cp++ = ' ';
		*cp++ = '\n';

		/* and now the data */
		sprintf(cp, "%d  %3d %4d %4d %3d 0x%04x 0x%08lx %7d %9d %3d   %s",
			card->myid,
			card->bus,
			PCI_SLOT(card->devfn),
			card->brdtype,
			card->irq,
			card->iobase,
			card->membase,
			card->bchans,
			card->faxchans,
			card->state,
			hysdn_net_getname(card));
		while (*cp)
			cp++;
		while (((cp - tmp) % (INFO_OUT_LEN + 1)) != INFO_OUT_LEN)
			*cp++ = ' ';
		*cp++ = '\n';
		*cp = 0;	/* end of string */
	} else {		/* simultaneous read/write access forbidden ! */
		mutex_unlock(&hysdn_conf_mutex);
		return (-EPERM);	/* no permission this time */
	}
	mutex_unlock(&hysdn_conf_mutex);
	return nonseekable_open(ino, filep);
}				/* hysdn_conf_open */