Beispiel #1
0
static int __devinit agp_nvidia_probe(struct pci_dev *pdev,
				      const struct pci_device_id *ent)
{
	struct agp_bridge_data *bridge;
	u8 cap_ptr;

	nvidia_private.dev_1 =
		pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 1));
	nvidia_private.dev_2 =
		pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 2));
	nvidia_private.dev_3 =
		pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(30, 0));

	if (!nvidia_private.dev_1 || !nvidia_private.dev_2 || !nvidia_private.dev_3) {
		printk(KERN_INFO PFX "Detected an NVIDIA nForce/nForce2 "
			"chipset, but could not find the secondary devices.\n");
		return -ENODEV;
	}

	cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
	if (!cap_ptr)
		return -ENODEV;

	switch (pdev->device) {
	case PCI_DEVICE_ID_NVIDIA_NFORCE:
		printk(KERN_INFO PFX "Detected NVIDIA nForce chipset\n");
		nvidia_private.wbc_mask = 0x00010000;
		break;
	case PCI_DEVICE_ID_NVIDIA_NFORCE2:
		printk(KERN_INFO PFX "Detected NVIDIA nForce2 chipset\n");
		nvidia_private.wbc_mask = 0x80000000;
		break;
	default:
		printk(KERN_ERR PFX "Unsupported NVIDIA chipset (device id: %04x)\n",
			    pdev->device);
		return -ENODEV;
	}

	bridge = agp_alloc_bridge();
	if (!bridge)
		return -ENOMEM;

	bridge->driver = &nvidia_driver;
	bridge->dev_private_data = &nvidia_private,
	bridge->dev = pdev;
	bridge->capndx = cap_ptr;

	/* Fill in the mode register */
	pci_read_config_dword(pdev,
			bridge->capndx+PCI_AGP_STATUS,
			&bridge->mode);

	pci_set_drvdata(pdev, bridge);
	return agp_add_bridge(bridge);
}
Beispiel #2
0
static void ixdp2400_pci_postinit(void)
{
	struct pci_dev *dev;

	if (ixdp2x00_master_npu()) {
		dev = pci_find_slot(1, IXDP2400_SLAVE_ENET_DEVFN);
		pci_remove_bus_device(dev);
	} else {
		dev = pci_find_slot(1, IXDP2400_MASTER_ENET_DEVFN);
		pci_remove_bus_device(dev);

		ixdp2x00_slave_pci_postinit();
	}
}
acpi_status
acpi_os_write_pci_configuration (
    acpi_pci_id	*pci_id,
    u32		reg,
    NATIVE_UINT	value,
    u32		width)
{
    int devfn = PCI_DEVFN(pci_id->device, pci_id->function);
    struct pci_dev *dev = pci_find_slot(pci_id->bus, devfn);

    if (!dev)
        return AE_ERROR;

    switch (width)
    {
    case 8:
        if (pci_write_config_byte(dev, reg, value))
            return AE_ERROR;
        break;
    case 16:
        if (pci_write_config_word(dev, reg, value))
            return AE_ERROR;
        break;
    case 32:
        if (pci_write_config_dword(dev, reg, value))
            return AE_ERROR;
        break;
    default:
        BUG();
    }

    return AE_OK;
}
Beispiel #4
0
VOID *RTMPFindHostPCIDev(VOID *pPciDevSrc)
{
	struct pci_dev *pci_dev = (struct pci_dev *)pPciDevSrc;
	//struct pci_dev *parent_pci_dev;
	USHORT reg16;
	UCHAR reg8;
	UINT DevFn;
	PPCI_DEV pPci_dev;


	MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("%s.===>\n", __FUNCTION__));

	//parent_pci_dev = NULL;
	if (pci_dev->bus->parent)
	{
		for (DevFn = 0; DevFn < 255; DevFn++)
		{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
			pPci_dev = pci_get_slot(pci_dev->bus->parent, DevFn);
#else
			pPci_dev = pci_find_slot(pci_dev->bus->parent->number, DevFn);
#endif
			if (pPci_dev)
			{                
				pci_read_config_word(pPci_dev, PCI_CLASS_DEVICE, &reg16);
				reg16 = le2cpu16(reg16);
				pci_read_config_byte(pPci_dev, PCI_CB_CARD_BUS, &reg8);
				if ((reg16 == PCI_CLASS_BRIDGE_PCI) && 
					(reg8 == pci_dev->bus->number))
					return pPci_dev;
			}
		}
	}
	return NULL;
}
Beispiel #5
0
static int dhahelper_free_irq(dhahelper_irq_t *arg)
{
	dhahelper_irq_t irq;
	struct pci_dev *pci;
	int irqn;

	if (copy_from_user(&irq, arg, sizeof(dhahelper_irq_t)))
	{
		if (dhahelper_verbosity > 0)
		    printk(KERN_ERR "dhahelper: failed copy from userspace\n");
		return -EFAULT;
	}

	pci = pci_find_slot(irq.bus, PCI_DEVFN(irq.dev, irq.func));
	if(!pci)
	    return -EINVAL;

	irqn = pci->irq;

	spin_lock_irqsave(&dha_irqs[irqn].lock, dha_irqs[irqn].flags);
	if(dha_irqs[irqn].handled) {
		free_irq(irqn, pci);
		dha_irqs[irqn].handled = 0;
		printk("IRQ %i: %li\n", irqn, dha_irqs[irqn].count);
	}
	spin_unlock_irqrestore(&dha_irqs[irqn].lock, dha_irqs[irqn].flags);
	return 0;
}
Beispiel #6
0
int pcidata_read_proc(char *buf, char **start, off_t offset,
                   int len, int *eof, void *data)
{
    int i, pos=0;
    int bus, devfn;

    if (!pcibios_present())
        return sprintf(buf,"No PCI bios present\n");

    /*
     * This code is derived from "drivers/pci/pci.c". This means that
     * the GPL applies to this source file and credit is due to the
     * original authors (Drew Eckhardt, Frederic Potter, David
     * Mosberger-Tang)
     */
    for (bus=0; !bus; bus++) { /* only bus 0 :-) */
        for (devfn=0; devfn < 0x100 && pos < PAGE_SIZE/2; devfn++) {
	    struct pci_dev *dev = NULL;

	    dev = pci_find_slot(bus, devfn);
	    if (!dev) continue;

            /* Ok, we've found a device, copy its cfg space to the buffer*/
            for (i=0; i<256; i += sizeof(u32), pos += sizeof(u32))
                pci_read_config_dword(dev,i,(u32 *)(buf+pos));
	    pci_release_device(dev); /* 2.0 compatibility */
        }
    }
    *eof=1;
    return pos;
}
/*
 * It looks like the master IOC3 is usually on bus 0, device 4.  Hope
 * that's right
 */
static __init int efi_ioc3_time_init(void)
{
	struct pci_dev *dev;
	static struct ioc3 *ioc3;

	dev = pci_find_slot(0, PCI_DEVFN(4, 0));
	if (!dev) {
		printk(KERN_CRIT "Couldn't find master IOC3\n");

		return -ENODEV;
	}

	ioc3 = ioremap(pci_resource_start(dev, 0), pci_resource_len(dev, 0));
	nvram_base = (unsigned long) ioc3 + IOC3_BYTEBUS_DEV0;

	tod_chip_type = get_tod_chip_type();
	if (tod_chip_type == 1)
		printk(KERN_NOTICE "TOD type is SGS M48T35\n");
	else if (tod_chip_type == 2)
		printk(KERN_NOTICE "TOD type is Dallas DS1386\n");
	else
		printk(KERN_CRIT "No or unknown TOD\n");

	efi.get_time = ioc3_get_time;
	efi.set_time = ioc3_set_time;
	efi.get_wakeup_time = ioc3_get_wakeup_time;
	efi.set_wakeup_time = ioc3_set_wakeup_time;

	return 0;
}
static int __devinit
hc_found_ohci (struct pci_dev *dev, int irq,
	void *mem_base, const struct pci_device_id *id)
{
	unsigned long flags = id->driver_data;
	
	printk(KERN_INFO __FILE__ ": usb-%s, %s\n", dev->slot_name, dev->name);
	
	/* Check for NSC87560. We have to look at the bridge (fn1) to identify
	   the USB (fn2). This quirk might apply to more or even all NSC stuff
	   I don't know.. */
	   
	if(dev->vendor == PCI_VENDOR_ID_NS)
	{
		struct pci_dev *fn1  = pci_find_slot(dev->bus->number, PCI_DEVFN(PCI_SLOT(dev->devfn), 1));
		if(fn1 && fn1->vendor == PCI_VENDOR_ID_NS && fn1->device == PCI_DEVICE_ID_NS_87560_LIO)
			flags |= OHCI_QUIRK_SUCKYIO;
		
	}
	
	if (flags & OHCI_QUIRK_SUCKYIO)
		printk (KERN_INFO __FILE__ ": Using NSC SuperIO setup\n");
	if (flags & OHCI_QUIRK_AMD756)
		printk (KERN_INFO __FILE__ ": AMD756 erratum 4 workaround\n");

	return hc_add_ohci(dev, irq, mem_base, flags,
			   ohci_pci_driver.name, dev->slot_name);
}
Beispiel #9
0
static dev_node_t *serial_attach(dev_locator_t *loc)
{
    u_int io;
    u_char irq;
    int line;
    struct serial_struct serial;
    struct pci_dev *pdev;
    dev_node_t *node;

    MOD_INC_USE_COUNT;

    if (loc->bus != LOC_PCI) goto err_out;
    pdev = pci_find_slot (loc->b.pci.bus, loc->b.pci.devfn);
    if (!pdev) goto err_out;
    if (pci_enable_device(pdev)) goto err_out;

    printk(KERN_INFO "serial_attach(bus %d, fn %d)\n", pdev->bus->number, pdev->devfn);
    io = pci_resource_start (pdev, 0);
    irq = pdev->irq;
    if (!(pci_resource_flags(pdev, 0) & IORESOURCE_IO)) {
        printk(KERN_NOTICE "serial_cb: PCI base address 0 is not IO\n");
        goto err_out;
    }
    device_setup(pdev, io);
    memset(&serial, 0, sizeof(serial));
    serial.port = io;
    serial.irq = irq;
    serial.flags = ASYNC_SKIP_TEST | ASYNC_SHARE_IRQ;

    /* Some devices seem to need extra time */
    __set_current_state(TASK_UNINTERRUPTIBLE);
    schedule_timeout(HZ/50);

    line = register_serial(&serial);
    if (line < 0) {
        printk(KERN_NOTICE "serial_cb: register_serial() at 0x%04x, "
               "irq %d failed\n", serial.port, serial.irq);
        goto err_out;
    }

    node = kmalloc(sizeof(dev_node_t), GFP_KERNEL);
    if (!node)
        goto err_out_unregister;
    sprintf(node->dev_name, "ttyS%d", line);
    node->major = TTY_MAJOR;
    node->minor = 0x40 + line;
    node->next = NULL;
    return node;

err_out_unregister:
    unregister_serial(line);
err_out:
    MOD_DEC_USE_COUNT;
    return NULL;
}
Beispiel #10
0
asmlinkage long
sys_pciconfig_write(unsigned long bus, unsigned long dfn,
		    unsigned long off, unsigned long len,
		    void __user *buf)
{
	struct pci_dev *dev;
	u8 byte;
	u16 word;
	u32 dword;
	int err = 0;

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	dev = pci_find_slot(bus, dfn);
	if (!dev)
		return -ENODEV;

	lock_kernel();
	switch(len) {
	case 1:
		err = get_user(byte, (u8 __user *)buf);
		if (err)
			break;
		err = pci_write_config_byte(dev, off, byte);
		if (err != PCIBIOS_SUCCESSFUL)
			err = -EIO;
		break;

	case 2:
		err = get_user(word, (u16 __user *)buf);
		if (err)
			break;
		err = pci_write_config_word(dev, off, word);
		if (err != PCIBIOS_SUCCESSFUL)
			err = -EIO;
		break;

	case 4:
		err = get_user(dword, (u32 __user *)buf);
		if (err)
			break;
		err = pci_write_config_dword(dev, off, dword);
		if (err != PCIBIOS_SUCCESSFUL)
			err = -EIO;
		break;

	default:
		err = -EINVAL;
		break;
	};
	unlock_kernel();

	return err;
}
static int __init cpcihp_generic_init(void)
{
	int status;
	struct resource* r;
	struct pci_dev* dev;

	info(DRIVER_DESC " version: " DRIVER_VERSION);
	status = validate_parameters();
	if(status != 0)
		return status;

	r = request_region(port, 1, "#ENUM hotswap signal register");
	if(!r)
		return -EBUSY;

	dev = pci_find_slot(bridge_busnr, PCI_DEVFN(bridge_slot, 0));
	if(!dev || dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
		err("Invalid bridge device %s", bridge);
		return -EINVAL;
	}
	bus = dev->subordinate;

	memset(&generic_hpc, 0, sizeof (struct cpci_hp_controller));
	generic_hpc_ops.query_enum = query_enum;
	generic_hpc.ops = &generic_hpc_ops;

	status = cpci_hp_register_controller(&generic_hpc);
	if(status != 0) {
		err("Could not register cPCI hotplug controller");
		return -ENODEV;
	}
	dbg("registered controller");

	status = cpci_hp_register_bus(bus, first_slot, last_slot);
	if(status != 0) {
		err("Could not register cPCI hotplug bus");
		goto init_bus_register_error;
	}
	dbg("registered bus");

	status = cpci_hp_start();
	if(status != 0) {
		err("Could not started cPCI hotplug system");
		goto init_start_error;
	}
	dbg("started cpci hp system");
	return 0;
init_start_error:
	cpci_hp_unregister_bus(bus);
init_bus_register_error:
	cpci_hp_unregister_controller(&generic_hpc);
	err("status = %d", status);
	return status;

}
Beispiel #12
0
int __init ixdp2800_pci_init(void)
{
	if (machine_is_ixdp2800()) {
		struct pci_dev *dev;

		pci_common_init(&ixdp2800_pci);
		if (ixdp2x00_master_npu()) {
			dev = pci_find_slot(1, IXDP2800_SLAVE_ENET_DEVFN);
			pci_remove_bus_device(dev);

			ixdp2800_master_enable_slave();
			ixdp2800_master_wait_for_slave_bus_scan();
		} else {
			dev = pci_find_slot(1, IXDP2800_MASTER_ENET_DEVFN);
			pci_remove_bus_device(dev);
		}
	}

	return 0;
}
Beispiel #13
0
static int via_get_revision(void)
{
    u8 rev;
    struct pci_dev* dev;

    dev = pci_find_slot(0,0);
    if (dev == NULL) return 0;

    pci_read_config_byte(dev, 0xf6, &rev);

    return rev;
}
Beispiel #14
0
Datei: edd.c Projekt: wxlong/Test
/**
 * edd_get_pci_dev() - finds pci_dev that matches edev
 * @edev - edd_device
 *
 * Returns pci_dev if found, or NULL
 */
static struct pci_dev *
edd_get_pci_dev(struct edd_device *edev)
{
	struct edd_info *info = edd_dev_get_info(edev);

	if (edd_dev_is_type(edev, "PCI")) {
		return pci_find_slot(info->params.interface_path.pci.bus,
				     PCI_DEVFN(info->params.interface_path.pci.slot,
					       info->params.interface_path.pci.
					       function));
	}
	return NULL;
}
Beispiel #15
0
int drm_irq_busid(struct inode *inode, struct file *filp, unsigned int cmd,
		  unsigned long arg)
{
	drm_irq_busid_t p;
	struct pci_dev	*dev;

	if (copy_from_user(&p, (drm_irq_busid_t *)arg, sizeof(p)))
		return -EFAULT;
	dev = pci_find_slot(p.busnum, PCI_DEVFN(p.devnum, p.funcnum));
	if (dev) p.irq = dev->irq;
	else	 p.irq = 0;
	DRM_DEBUG("%d:%d:%d => IRQ %d\n",
		  p.busnum, p.devnum, p.funcnum, p.irq);
	if (copy_to_user((drm_irq_busid_t *)arg, &p, sizeof(p)))
		return -EFAULT;
	return 0;
}
void __init
nautilus_init_pci(void)
{
	struct pci_controller *hose = hose_head;
	struct pci_bus *bus;
	struct pci_dev *dev;
	unsigned long bus_align, bus_size, pci_mem;
	unsigned long memtop = max_low_pfn << PAGE_SHIFT;

	/* Scan our single hose.  */
	bus = pci_scan_bus(0, alpha_mv.pci_ops, hose);
	hose->bus = bus;
	hose->last_busno = bus->subordinate;

	bus->self = pci_find_slot(0, 0);
	bus->resource[1] = &irongate_mem;

	pbus_size_bridges(bus);

	/* IO port range. */
	bus->resource[0]->start = 0;
	bus->resource[0]->end = 0xffff;

	/* Set up PCI memory range - limit is hardwired to 0xffffffff,
	   base must be at aligned to 16Mb. */
	bus_align = bus->resource[1]->start;
	bus_size = bus->resource[1]->end + 1 - bus_align;
	if (bus_align < 0x1000000UL)
		bus_align = 0x1000000UL;

	pci_mem = (0x100000000UL - bus_size) & -bus_align;

	bus->resource[1]->start = pci_mem;
	bus->resource[1]->end = 0xffffffffUL;
	if (request_resource(&iomem_resource, bus->resource[1]) < 0)
		printk(KERN_ERR "Failed to request MEM on hose 0\n");

	if (pci_mem < memtop)
		memtop = pci_mem;
	if (memtop > alpha_mv.min_mem_address) {
		free_reserved_mem(__va(alpha_mv.min_mem_address),
				  __va(memtop));
		printk("nautilus_init_pci: %ldk freed\n",
			(memtop - alpha_mv.min_mem_address) >> 10);
	}
VOID *RTMPFindHostPCIDev(
    IN	VOID					*pPciDevSrc)
{
	struct pci_dev *pci_dev = (struct pci_dev *)pPciDevSrc;
	struct pci_dev *parent_pci_dev;
    USHORT  reg16;
    UCHAR   reg8;
	UINT	DevFn;
    PPCI_DEV    pPci_dev;
/*	POS_COOKIE 	pObj; */

/*	pObj = (POS_COOKIE) pAd->OS_Cookie; */

/*	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) */
/*		return; */
    
    DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __FUNCTION__));

    parent_pci_dev = NULL;
    if (pci_dev->bus->parent)
    {
        for (DevFn = 0; DevFn < 255; DevFn++)
        {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
            pPci_dev = pci_get_slot(pci_dev->bus->parent, DevFn);
#else
            pPci_dev = pci_find_slot(pci_dev->bus->parent->number, DevFn);
#endif
            if (pPci_dev)
            {                
                pci_read_config_word(pPci_dev, PCI_CLASS_DEVICE, &reg16);
                reg16 = le2cpu16(reg16);
                pci_read_config_byte(pPci_dev, PCI_CB_CARD_BUS, &reg8);
                if ((reg16 == PCI_CLASS_BRIDGE_PCI) && 
                    (reg8 == pci_dev->bus->number))
                {
                    return pPci_dev;
                }
            }
        }
    }
	return NULL;
}
Beispiel #18
0
__initfunc(int safl_scan(void))
{
    if (pcibios_present()) {
        int index;

        /*
         * Search for an EBSA-285 board or an IOP board. Stop at
         * first one found.
         */
        for (index = 0; index < 8; index++) {
            if (pcibios_find_device (PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21554,
                                     index, &safl_pci_bus, &safl_pci_devfn)
                    == PCIBIOS_SUCCESSFUL) {
                safl_devid = PCI_DEVICE_ID_DEC_21554;
                break;
            }
            if (pcibios_find_device (PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285,
                                     index, &safl_pci_bus, &safl_pci_devfn)
                    == PCIBIOS_SUCCESSFUL) {
                safl_devid = PCI_DEVICE_ID_DEC_21285;
                break;
            }
        }

        if (index < 8) {
#ifdef PCI_SUPPORT_VER2
            safl_pdev = pci_find_slot(safl_pci_bus, safl_pci_devfn);
#endif
            misc_register(&safl_dev);
            return 0;
        }
    }
    if (safl_debug)
        printk(KERN_INFO "Can't find device.\n");
    return -ENODEV;
}
Beispiel #19
0
static int oprompci2node(void __user *argp, struct device_node *dp, struct openpromio *op, int bufsize, DATA *data)
{
	int err = -EINVAL;

	if (bufsize >= 2*sizeof(int)) {
#ifdef CONFIG_PCI
		struct pci_dev *pdev;
		struct pcidev_cookie *pcp;
		pdev = pci_find_slot (((int *) op->oprom_array)[0],
				      ((int *) op->oprom_array)[1]);

		pcp = pdev->sysdata;
		if (pcp != NULL) {
			dp = pcp->prom_node;
			data->current_node = dp;
			*((int *)op->oprom_array) = dp->node;
			op->oprom_size = sizeof(int);
			err = copyout(argp, op, bufsize + sizeof(int));
		}
#endif
	}

	return err;
}
Beispiel #20
0
int awc4500_pci_probe(struct net_device *dev)
{
    int cards_found = 0;
    static int pci_index;	/* Static, for multiple probe calls. */
    u8 pci_irq_line = 0;
//	int p;

    unsigned char awc_pci_dev, awc_pci_bus;

    if (!pci_present())
        return -1;

    for (; pci_index < 0xff; pci_index++) {
        u16 vendor, device, pci_command, new_command;
        u32 pci_memaddr;
        u32 pci_ioaddr;
        u32 pci_cisaddr;
        struct pci_dev *pdev;

        if (pcibios_find_class	(PCI_CLASS_NETWORK_OTHER << 8,
                                 reverse_probe ? 0xfe - pci_index : pci_index,
                                 &awc_pci_bus, &awc_pci_dev) != PCIBIOS_SUCCESSFUL) {
            if (reverse_probe) {
                continue;
            } else {
                break;
            }
        }
        pdev = pci_find_slot(awc_pci_bus, awc_pci_dev);
        if (!pdev)
            continue;
        if (pci_enable_device(pdev))
            continue;
        vendor = pdev->vendor;
        device = pdev->device;
        pci_irq_line = pdev->irq;
        pci_memaddr = pci_resource_start (pdev, 0);
        pci_cisaddr = pci_resource_start (pdev, 1);
        pci_ioaddr = pci_resource_start (pdev, 2);

//		printk("\n pci capabilities %x and ptr %x \n",pci_caps,pci_caps_ptr);
        /* Remove I/O space marker in bit 0. */

        if (vendor != PCI_VENDOR_ID_AIRONET)
            continue;
        if (device != PCI_DEVICE_AIRONET_4800_1 &&
                device != PCI_DEVICE_AIRONET_4800 &&
                device != PCI_DEVICE_AIRONET_4500 )
            continue;

//		if (check_region(pci_ioaddr, AIRONET4X00_IO_SIZE) ||
//			check_region(pci_cisaddr, AIRONET4X00_CIS_SIZE) ||
//			check_region(pci_memaddr, AIRONET4X00_MEM_SIZE)) {
//				printk(KERN_ERR "aironet4X00 mem addrs not available for maping \n");
//				continue;
//		}
        if (!request_region(pci_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr"))
            continue;
//		request_region(pci_cisaddr, AIRONET4X00_CIS_SIZE, "aironet4x00 cis");
//		request_region(pci_memaddr, AIRONET4X00_MEM_SIZE, "aironet4x00 mem");

        mdelay(10);

        pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
        new_command = pci_command | PCI_COMMAND_SERR;
        if (pci_command != new_command)
            pci_write_config_word(pdev, PCI_COMMAND, new_command);


        /*		if (device == PCI_DEVICE_AIRONET_4800)
        			pci_write_config_dword(pdev, 0x40, 0x00000000);

        		udelay(1000);
        */
        if (device == PCI_DEVICE_AIRONET_4800)
            pci_write_config_dword(pdev, 0x40, 0x40000000);

        if (awc_pci_init(dev, pdev, pci_ioaddr,pci_cisaddr,pci_memaddr,pci_irq_line)) {
            printk(KERN_ERR "awc4800 pci init failed \n");
            break;
        }
        dev = 0;
        cards_found++;
    }

    return cards_found ? 0 : -ENODEV;
}
Beispiel #21
0
int
mac53c94_detect(Scsi_Host_Template *tp)
{
	struct device_node *node;
	int nfscs;
	struct fsc_state *state, **prev_statep;
	struct Scsi_Host *host;
	void *dma_cmd_space;
	unsigned char *clkprop;
	int proplen;
	struct pci_dev *pdev;
	u8 pbus, devfn;

	nfscs = 0;
	prev_statep = &all_53c94s;
	for (node = find_devices("53c94"); node != 0; node = node->next) {
		if (node->n_addrs != 2 || node->n_intrs != 2) {
			printk(KERN_ERR "mac53c94: expected 2 addrs and intrs"
			       " (got %d/%d) for node %s\n",
			       node->n_addrs, node->n_intrs, node->full_name);
			continue;
		}

		pdev = NULL;
		if (node->parent != NULL
		    && !pci_device_from_OF_node(node->parent, &pbus, &devfn))
			pdev = pci_find_slot(pbus, devfn);
		if (pdev == NULL) {
			printk(KERN_ERR "mac53c94: can't find PCI device "
			       "for %s\n", node->full_name);
			continue;
		}

		host = scsi_register(tp, sizeof(struct fsc_state));
		if (host == NULL)
			break;
		host->unique_id = nfscs;

		state = (struct fsc_state *) host->hostdata;
		if (state == 0) {
			/* "can't happen" */
			printk(KERN_ERR "mac53c94: no state for %s?!\n",
			       node->full_name);
			scsi_unregister(host);
			break;
		}
		state->host = host;
		state->pdev = pdev;

		state->regs = (volatile struct mac53c94_regs *)
			ioremap(node->addrs[0].address, 0x1000);
		state->intr = node->intrs[0].line;
		state->dma = (volatile struct dbdma_regs *)
			ioremap(node->addrs[1].address, 0x1000);
		state->dmaintr = node->intrs[1].line;
		if (state->regs == NULL || state->dma == NULL) {
			printk(KERN_ERR "mac53c94: ioremap failed for %s\n",
			       node->full_name);
			if (state->dma != NULL)
				iounmap(state->dma);
			if (state->regs != NULL)
				iounmap(state->regs);
			scsi_unregister(host);
			break;
		}

		clkprop = get_property(node, "clock-frequency", &proplen);
		if (clkprop == NULL || proplen != sizeof(int)) {
			printk(KERN_ERR "%s: can't get clock frequency, "
			       "assuming 25MHz\n", node->full_name);
			state->clk_freq = 25000000;
		} else
			state->clk_freq = *(int *)clkprop;

		/* Space for dma command list: +1 for stop command,
		   +1 to allow for aligning. */
		dma_cmd_space = kmalloc((host->sg_tablesize + 2) *
					sizeof(struct dbdma_cmd), GFP_KERNEL);
		if (dma_cmd_space == 0) {
			printk(KERN_ERR "mac53c94: couldn't allocate dma "
			       "command space for %s\n", node->full_name);
			goto err_cleanup;
		}
		state->dma_cmds = (struct dbdma_cmd *)
			DBDMA_ALIGN(dma_cmd_space);
		memset(state->dma_cmds, 0, (host->sg_tablesize + 1)
		       * sizeof(struct dbdma_cmd));
		state->dma_cmd_space = dma_cmd_space;

		*prev_statep = state;
		prev_statep = &state->next;

		if (request_irq(state->intr, do_mac53c94_interrupt, 0,
				"53C94", state)) {
			printk(KERN_ERR "mac53C94: can't get irq %d for %s\n",
			       state->intr, node->full_name);
		err_cleanup:
			iounmap(state->dma);
			iounmap(state->regs);
			scsi_unregister(host);
			break;
		}

		mac53c94_init(state);

		++nfscs;
	}
	return nfscs;
}
Beispiel #22
0
static int __devinit
hc_found_ohci (struct pci_dev *dev, int irq,
	void *mem_base, const struct pci_device_id *id)
{
	ohci_t * ohci;
	char buf[8], *bufp = buf;
	int ret;

#ifndef __sparc__
	sprintf(buf, "%d", irq);
#else
	bufp = __irq_itoa(irq);
#endif
	printk(KERN_INFO __FILE__ ": USB OHCI at membase 0x%lx, IRQ %s\n",
		(unsigned long)	mem_base, bufp);
	printk(KERN_INFO __FILE__ ": usb-%s, %s\n", dev->slot_name, dev->name);
    
	ohci = hc_alloc_ohci (dev, mem_base);
	if (!ohci) {
		return -ENOMEM;
	}
	if ((ret = ohci_mem_init (ohci)) < 0) {
		hc_release_ohci (ohci);
		return ret;
	}
	ohci->flags = id->driver_data;

	/* Check for NSC87560. We have to look at the bridge (fn1) to identify
	   the USB (fn2). This quirk might apply to more or even all NSC stuff
	   I don't know.. */
	   
	if(dev->vendor == PCI_VENDOR_ID_NS)
	{
		struct pci_dev *fn1  = pci_find_slot(dev->bus->number, PCI_DEVFN(PCI_SLOT(dev->devfn), 1));
		if(fn1 && fn1->vendor == PCI_VENDOR_ID_NS && fn1->device == PCI_DEVICE_ID_NS_87560_LIO)
			ohci->flags |= OHCI_QUIRK_SUCKYIO;
		
	}
	
	if (ohci->flags & OHCI_QUIRK_SUCKYIO)
		printk (KERN_INFO __FILE__ ": Using NSC SuperIO setup\n");
	if (ohci->flags & OHCI_QUIRK_AMD756)
		printk (KERN_INFO __FILE__ ": AMD756 erratum 4 workaround\n");
	if (hc_reset (ohci) < 0) {
		hc_release_ohci (ohci);
		return -ENODEV;
	}

	/* FIXME this is a second HC reset; why?? */
	writel (ohci->hc_control = OHCI_USB_RESET, &ohci->regs->control);
	wait_ms (10);

	usb_register_bus (ohci->bus);
	
	if (request_irq (irq, hc_interrupt, SA_SHIRQ,
			ohci_pci_driver.name, ohci) != 0) {
		err ("request interrupt %s failed", bufp);
		hc_release_ohci (ohci);
		return -EBUSY;
	}
	ohci->irq = irq;     

	if (hc_start (ohci) < 0) {
		err ("can't start usb-%s", dev->slot_name);
		hc_release_ohci (ohci);
		return -EBUSY;
	}

#ifdef	DEBUG
	ohci_dump (ohci, 1);
#endif
	return 0;
}
Beispiel #23
0
static int __devinit
ohci_pci_start (struct usb_hcd *hcd)
{
	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
	int		ret;

	if(hcd->self.controller && hcd->self.controller->bus == &pci_bus_type) {
		struct pci_dev *pdev = to_pci_dev(hcd->self.controller);

		/* AMD 756, for most chips (early revs), corrupts register
		 * values on read ... so enable the vendor workaround.
		 */
		if (pdev->vendor == PCI_VENDOR_ID_AMD
				&& pdev->device == 0x740c) {
			ohci->flags = OHCI_QUIRK_AMD756;
			ohci_dbg (ohci, "AMD756 erratum 4 workaround\n");
			// also somewhat erratum 10 (suspend/resume issues)
		}

		/* FIXME for some of the early AMD 760 southbridges, OHCI
		 * won't work at all.  blacklist them.
		 */

		/* Apple's OHCI driver has a lot of bizarre workarounds
		 * for this chip.  Evidently control and bulk lists
		 * can get confused.  (B&W G3 models, and ...)
		 */
		else if (pdev->vendor == PCI_VENDOR_ID_OPTI
				&& pdev->device == 0xc861) {
			ohci_dbg (ohci,
				"WARNING: OPTi workarounds unavailable\n");
		}

		/* Check for NSC87560. We have to look at the bridge (fn1) to
		 * identify the USB (fn2). This quirk might apply to more or
		 * even all NSC stuff.
		 */
		else if (pdev->vendor == PCI_VENDOR_ID_NS) {
			struct pci_dev	*b;

			b  = pci_find_slot (pdev->bus->number,
					PCI_DEVFN (PCI_SLOT (pdev->devfn), 1));
			if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO
					&& b->vendor == PCI_VENDOR_ID_NS) {
				ohci->flags |= OHCI_QUIRK_SUPERIO;
				ohci_dbg (ohci, "Using NSC SuperIO setup\n");
			}
		}

		/* Check for Compaq's ZFMicro chipset, which needs short 
		 * delays before control or bulk queues get re-activated
		 * in finish_unlinks()
		 */
		else if (pdev->vendor == PCI_VENDOR_ID_COMPAQ
				&& pdev->device  == 0xa0f8) {
			ohci->flags |= OHCI_QUIRK_ZFMICRO;
			ohci_dbg (ohci,
				"enabled Compaq ZFMicro chipset quirk\n");
		}
	}

	/* NOTE: there may have already been a first reset, to
	 * keep bios/smm irqs from making trouble
	 */
	if ((ret = ohci_run (ohci)) < 0) {
		ohci_err (ohci, "can't start\n");
		ohci_stop (hcd);
		return ret;
	}
	return 0;
}
Beispiel #24
0
static int pcicommand(pcidata* x)
{
  struct pci_dev* sh=(struct pci_dev*)x->starthandle;

  switch(x->command) {
  case CMD_FIND_SLOT:
    x->handle=(unsigned long)pci_find_slot(x->busnum,
					   PCI_DEVFN(x->devnum,x->funnum));
    return 0;
  case CMD_FIND_SUBSYS:
    x->handle=(unsigned long)pci_find_subsys(x->vendor,
					     x->device,
					     x->subsys_vendor,
					     x->subsys_device,
					     sh);
    return 0;
  case CMD_FIND_DEVICE:
    x->handle=(unsigned long)pci_find_device(x->vendor,
					     x->device,
					     sh);
    return 0;
  case CMD_FIND_CLASS:
    x->handle=(unsigned long)pci_find_class(x->class,
					    sh);
    return 0;
  case CMD_FIND_CAPAB:
    x->cappos=pci_find_capability(sh,
				  x->capability);
    return 0;
  case CMD_SET_POWER:
    x->oldpowerstate=pci_set_power_state(sh,
					 x->powerstate);
    return 0;
  case CMD_ENABLE:
    x->result=pci_enable_device(sh);
    return 0;
  case CMD_DISABLE:
    pci_disable_device(sh);
    return 0;
  case CMD_RELEASE:
    release_device(sh,0);
    return 0;
  case CMD_REQUEST:
    {
      char* name;
      
      if (x->res_name) {
	int len;
	char c;
	int i;

	len=0;
	while (!COPY_FROM_USER(&c, x->res_name+len,1)) {
	  if (!c)
	    break;
	  len++;
	}
	name=kmalloc(len+1,GFP_KERNEL);
	for (i=0;i<len;i++) {
	  name[i]=0;
	  COPY_FROM_USER(name+i, x->res_name+i,1);
	}
	name[i]=0;
      }
      else {
	name=kmalloc(22,GFP_KERNEL);
	strcpy(name,"amithlon pci system");
      }

      x->result=pci_request_regions(sh,name);
      if (!x->result) { /* Successful */
	pci_list* n=kmalloc(sizeof(pci_list),GFP_KERNEL);
	n->dev=sh;
	if (x->releasecode) {
	  int size=find_code_size(x->releasecode);
	  n->releasecode=kmalloc(size,GFP_KERNEL);
	  COPY_FROM_USER(n->releasecode,x->releasecode,size);
	}
	else 
	  n->releasecode=NULL;
	n->name=name;
	n->next=devlist;
	n->prev_p=&devlist;
	if (devlist)
	  devlist->prev_p=&(n->next);
	devlist=n;
      }
      else {
	kfree(name);
      }
    }
    return 0;
    
  case CMD_READBYTE:
    x->confdata=0;
    x->result=pci_read_config_byte(sh,
				   x->offset,
				   (u8*)&(x->confdata));
    return 0;

  case CMD_READWORD:
    x->confdata=0;
    x->result=pci_read_config_word(sh,
				   x->offset,
				   (u16*)&(x->confdata));
    return 0;
  case CMD_READLONG:
    x->confdata=0;
    x->result=pci_read_config_dword(sh,
				    x->offset,
				    (u32*)&(x->confdata));
    return 0;
  case CMD_WRITEBYTE:
    x->result=pci_write_config_byte(sh,
				    x->offset,
				    (u8)(x->confdata));
    return 0;
  case CMD_WRITEWORD:
    x->result=pci_write_config_word(sh,
				    x->offset,
				    (u16)(x->confdata));
    return 0;
  case CMD_WRITELONG:
    x->result=pci_write_config_dword(sh,
				     x->offset,
				     (u32)(x->confdata));
    return 0;
    
  case CMD_GETBASE:
    x->start=sh->resource[x->basenum].start;
    x->end=sh->resource[x->basenum].end;
    x->flags=sh->resource[x->basenum].flags;
    return 0;

  case CMD_GETINFO:
    x->irq=sh->irq;
    x->devnum=PCI_SLOT(sh->devfn);
    x->funnum=PCI_FUNC(sh->devfn);
    x->busnum=sh->bus->number;
    return 0;

  case CMD_GETNAME:
    {
      int len=0;
      do {  
	if (COPY_TO_USER((void*)(x->res_name+len),(void*)(sh->name+len),1))
	  return -EFAULT;
      } while (sh->name[len++]);
    }
    return 0;
  default:
    return -EINVAL;
  }
}
Beispiel #25
0
int
acpi_pci_bind (
    struct acpi_device	*device)
{
    int			result = 0;
    acpi_status		status = AE_OK;
    struct acpi_pci_data	*data = NULL;
    struct acpi_pci_data	*pdata = NULL;
    char			*pathname = NULL;
    struct acpi_buffer	buffer = {0, NULL};
    acpi_handle		handle = NULL;

    ACPI_FUNCTION_TRACE("acpi_pci_bind");

    if (!device || !device->parent)
        return_VALUE(-EINVAL);

    pathname = kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
    if(!pathname)
        return_VALUE(-ENOMEM);
    memset(pathname, 0, ACPI_PATHNAME_MAX);
    buffer.length = ACPI_PATHNAME_MAX;
    buffer.pointer = pathname;

    data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
    if (!data) {
        kfree (pathname);
        return_VALUE(-ENOMEM);
    }
    memset(data, 0, sizeof(struct acpi_pci_data));

    acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
    ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI device [%s]...\n",
                      pathname));

    /*
     * Segment & Bus
     * -------------
     * These are obtained via the parent device's ACPI-PCI context.
     */
    status = acpi_get_data(device->parent->handle, acpi_pci_data_handler,
                           (void**) &pdata);
    if (ACPI_FAILURE(status) || !pdata || !pdata->bus) {
        ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
                          "Invalid ACPI-PCI context for parent device %s\n",
                          acpi_device_bid(device->parent)));
        result = -ENODEV;
        goto end;
    }
    data->id.segment = pdata->id.segment;
    data->id.bus = pdata->bus->number;

    /*
     * Device & Function
     * -----------------
     * These are simply obtained from the device's _ADR method.  Note
     * that a value of zero is valid.
     */
    data->id.device = device->pnp.bus_address >> 16;
    data->id.function = device->pnp.bus_address & 0xFFFF;

    ACPI_DEBUG_PRINT((ACPI_DB_INFO, "...to %02x:%02x:%02x.%02x\n",
                      data->id.segment, data->id.bus, data->id.device,
                      data->id.function));

    /*
     * TBD: Support slot devices (e.g. function=0xFFFF).
     */

    /*
     * Locate PCI Device
     * -----------------
     * Locate matching device in PCI namespace.  If it doesn't exist
     * this typically means that the device isn't currently inserted
     * (e.g. docking station, port replicator, etc.).
     */
    data->dev = pci_find_slot(data->id.bus, PCI_DEVFN(data->id.device, data->id.function));
    if (!data->dev) {
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                          "Device %02x:%02x:%02x.%02x not present in PCI namespace\n",
                          data->id.segment, data->id.bus,
                          data->id.device, data->id.function));
        result = -ENODEV;
        goto end;
    }
    if (!data->dev->bus) {
        ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
                          "Device %02x:%02x:%02x.%02x has invalid 'bus' field\n",
                          data->id.segment, data->id.bus,
                          data->id.device, data->id.function));
        result = -ENODEV;
        goto end;
    }

    /*
     * PCI Bridge?
     * -----------
     * If so, set the 'bus' field and install the 'bind' function to
     * facilitate callbacks for all of its children.
     */
    if (data->dev->subordinate) {
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                          "Device %02x:%02x:%02x.%02x is a PCI bridge\n",
                          data->id.segment, data->id.bus,
                          data->id.device, data->id.function));
        data->bus = data->dev->subordinate;
        device->ops.bind = acpi_pci_bind;
        device->ops.unbind = acpi_pci_unbind;
    }

    /*
     * Attach ACPI-PCI Context
     * -----------------------
     * Thus binding the ACPI and PCI devices.
     */
    status = acpi_attach_data(device->handle, acpi_pci_data_handler, data);
    if (ACPI_FAILURE(status)) {
        ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
                          "Unable to attach ACPI-PCI context to device %s\n",
                          acpi_device_bid(device)));
        result = -ENODEV;
        goto end;
    }

    /*
     * PCI Routing Table
     * -----------------
     * Evaluate and parse _PRT, if exists.  This code is independent of
     * PCI bridges (above) to allow parsing of _PRT objects within the
     * scope of non-bridge devices.  Note that _PRTs within the scope of
     * a PCI bridge assume the bridge's subordinate bus number.
     *
     * TBD: Can _PRTs exist within the scope of non-bridge PCI devices?
     */
    status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle);
    if (ACPI_SUCCESS(status)) {
        if (data->bus)				    /* PCI-PCI bridge */
            acpi_pci_irq_add_prt(device->handle, data->id.segment,
                                 data->bus->number);
        else				     /* non-bridge PCI device */
            acpi_pci_irq_add_prt(device->handle, data->id.segment,
                                 data->id.bus);
    }

end:
    kfree(pathname);
    if (result)
        kfree(data);

    return_VALUE(result);
}
Beispiel #26
0
static int __devinit agp_serverworks_probe(struct pci_dev *pdev,
					   const struct pci_device_id *ent)
{
	struct agp_bridge_data *bridge;
	struct pci_dev *bridge_dev;
	u32 temp, temp2;
	u8 cap_ptr = 0;

	/* Everything is on func 1 here so we are hardcoding function one */
	bridge_dev = pci_find_slot((unsigned int)pdev->bus->number,
			PCI_DEVFN(0, 1));
	if (!bridge_dev) {
		printk(KERN_INFO PFX "Detected a Serverworks chipset "
		       "but could not find the secondary device.\n");
		return -ENODEV;
	}

	cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);

	switch (pdev->device) {
	case 0x0006:
		/* ServerWorks CNB20HE
		Fail silently.*/
		printk (KERN_ERR PFX "Detected ServerWorks CNB20HE chipset: No AGP present.\n");
		return -ENODEV;

	case PCI_DEVICE_ID_SERVERWORKS_HE:
	case PCI_DEVICE_ID_SERVERWORKS_LE:
	case 0x0007:
		break;

	default:
		if (cap_ptr)
			printk(KERN_ERR PFX "Unsupported Serverworks chipset "
					"(device id: %04x)\n", pdev->device);
		return -ENODEV;
	}

	serverworks_private.svrwrks_dev = bridge_dev;
	serverworks_private.gart_addr_ofs = 0x10;

	pci_read_config_dword(pdev, SVWRKS_APSIZE, &temp);
	if (temp & PCI_BASE_ADDRESS_MEM_TYPE_64) {
		pci_read_config_dword(pdev, SVWRKS_APSIZE + 4, &temp2);
		if (temp2 != 0) {
			printk(KERN_INFO PFX "Detected 64 bit aperture address, "
			       "but top bits are not zero.  Disabling agp\n");
			return -ENODEV;
		}
		serverworks_private.mm_addr_ofs = 0x18;
	} else
		serverworks_private.mm_addr_ofs = 0x14;

	pci_read_config_dword(pdev, serverworks_private.mm_addr_ofs, &temp);
	if (temp & PCI_BASE_ADDRESS_MEM_TYPE_64) {
		pci_read_config_dword(pdev,
				serverworks_private.mm_addr_ofs + 4, &temp2);
		if (temp2 != 0) {
			printk(KERN_INFO PFX "Detected 64 bit MMIO address, "
			       "but top bits are not zero.  Disabling agp\n");
			return -ENODEV;
		}
	}

	bridge = agp_alloc_bridge();
	if (!bridge)
		return -ENOMEM;

	bridge->driver = &sworks_driver;
	bridge->dev_private_data = &serverworks_private,
	bridge->dev = pdev;

	pci_set_drvdata(pdev, bridge);
	return agp_add_bridge(bridge);
}
Beispiel #27
0
static int pci_etherdev_probe(struct device *dev, struct pci_id_info pci_tbl[])
{
	int cards_found = 0;
	int pci_index = 0;
	unsigned char pci_bus, pci_device_fn;

	if ( ! pcibios_present())
		return -ENODEV;

	for (;pci_index < 0xff; pci_index++) {
		u16 vendor, device, pci_command, new_command;
		int chip_idx, irq;
		long pciaddr;
		long ioaddr;

		if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8, pci_index,
								&pci_bus, &pci_device_fn)
			!= PCIBIOS_SUCCESSFUL)
			break;
		pcibios_read_config_word(pci_bus, pci_device_fn,
								 PCI_VENDOR_ID, &vendor);
		pcibios_read_config_word(pci_bus, pci_device_fn,
								 PCI_DEVICE_ID, &device);

		for (chip_idx = 0; pci_tbl[chip_idx].vendor_id; chip_idx++)
			if (vendor == pci_tbl[chip_idx].vendor_id
				&& (device & pci_tbl[chip_idx].device_id_mask) ==
				pci_tbl[chip_idx].device_id)
				break;
		if (pci_tbl[chip_idx].vendor_id == 0) 		/* Compiled out! */
			continue;

		{
#if defined(PCI_SUPPORT_VER2)
			struct pci_dev *pdev = pci_find_slot(pci_bus, pci_device_fn);
#ifdef VIA_USE_IO
			pciaddr = pdev->base_address[0];
#else
			pciaddr = pdev->base_address[1];
#endif
			irq = pdev->irq;
#else
			u32 pci_memaddr;
			u8 pci_irq_line;
			pcibios_read_config_byte(pci_bus, pci_device_fn,
									 PCI_INTERRUPT_LINE, &pci_irq_line);
#ifdef VIA_USE_IO
			pcibios_read_config_dword(pci_bus, pci_device_fn,
									  PCI_BASE_ADDRESS_0, &pci_memaddr);
			pciaddr = pci_memaddr;
#else
			pcibios_read_config_dword(pci_bus, pci_device_fn,
									  PCI_BASE_ADDRESS_1, &pci_memaddr);
			pciaddr = pci_memaddr;
#endif
			irq = pci_irq_line;
#endif
		}

		if (debug > 2)
			printk(KERN_INFO "Found %s at PCI address %#lx, IRQ %d.\n",
				   pci_tbl[chip_idx].name, pciaddr, irq);

		if (pci_tbl[chip_idx].flags & PCI_USES_IO) {
			ioaddr = pciaddr & ~3;
			if (check_region(ioaddr, pci_tbl[chip_idx].io_size))
				continue;
		} else if ((ioaddr = (long)ioremap(pciaddr & ~0xf,
										 pci_tbl[chip_idx].io_size)) == 0) {
			printk(KERN_INFO "Failed to map PCI address %#lx.\n",
				   pciaddr);
			continue;
		}

		pcibios_read_config_word(pci_bus, pci_device_fn,
								 PCI_COMMAND, &pci_command);
		new_command = pci_command | (pci_tbl[chip_idx].flags & 7);
		if (pci_command != new_command) {
			printk(KERN_INFO "  The PCI BIOS has not enabled the"
				   " device at %d/%d!  Updating PCI command %4.4x->%4.4x.\n",
				   pci_bus, pci_device_fn, pci_command, new_command);
			pcibios_write_config_word(pci_bus, pci_device_fn,
									  PCI_COMMAND, new_command);
		}

		dev = pci_tbl[chip_idx].probe1(pci_bus, pci_device_fn, dev, ioaddr,
									   irq, chip_idx, cards_found);

		if (dev  && (pci_tbl[chip_idx].flags & PCI_COMMAND_MASTER)) {
			u8 pci_latency;
			pcibios_read_config_byte(pci_bus, pci_device_fn,
									 PCI_LATENCY_TIMER, &pci_latency);
			if (pci_latency < min_pci_latency) {
				printk(KERN_INFO "  PCI latency timer (CFLT) is "
					   "unreasonably low at %d.  Setting to %d clocks.\n",
					   pci_latency, min_pci_latency);
				pcibios_write_config_byte(pci_bus, pci_device_fn,
										  PCI_LATENCY_TIMER, min_pci_latency);
			}
		}
		dev = 0;
		cards_found++;
	}

	return cards_found ? 0 : -ENODEV;
}
Beispiel #28
0
/*
 *	SunOS and Solaris /dev/openprom ioctl calls.
 */
static int openprom_sunos_ioctl(struct inode * inode, struct file * file,
				unsigned int cmd, unsigned long arg, int node)
{
	DATA *data = (DATA *) file->private_data;
	char buffer[OPROMMAXPARAM+1], *buf;
	struct openpromio *opp;
	unsigned long flags;
	int bufsize, len, error = 0;
	extern char saved_command_line[];
	static int cnt;

	if (cmd == OPROMSETOPT)
		bufsize = getstrings((void *)arg, &opp);
	else
		bufsize = copyin((void *)arg, &opp);

	if (bufsize < 0)
		return bufsize;

	switch (cmd) {
	case OPROMGETOPT:
	case OPROMGETPROP:
		save_and_cli(flags);
		len = prom_getproplen(node, opp->oprom_array);
		restore_flags(flags);

		if (len <= 0 || len > bufsize) {
			error = copyout((void *)arg, opp, sizeof(int));
			break;
		}

		save_and_cli(flags);
		len = prom_getproperty(node, opp->oprom_array, buffer, bufsize);
		restore_flags(flags);

		memcpy(opp->oprom_array, buffer, len);
		opp->oprom_array[len] = '\0';
		opp->oprom_size = len;

		error = copyout((void *)arg, opp, sizeof(int) + bufsize);
		break;

	case OPROMNXTOPT:
	case OPROMNXTPROP:
		save_and_cli(flags);
		buf = prom_nextprop(node, opp->oprom_array, buffer);
		restore_flags(flags);

		len = strlen(buf);
		if (len == 0 || len + 1 > bufsize) {
			error = copyout((void *)arg, opp, sizeof(int));
			break;
		}

		memcpy(opp->oprom_array, buf, len);
		opp->oprom_array[len] = '\0';
		opp->oprom_size = ++len;

		error = copyout((void *)arg, opp, sizeof(int) + bufsize);
		break;

	case OPROMSETOPT:
	case OPROMSETOPT2:
		buf = opp->oprom_array + strlen(opp->oprom_array) + 1;
		len = opp->oprom_array + bufsize - buf;

		save_and_cli(flags);
		error = prom_setprop(options_node, opp->oprom_array,
				     buf, len);
		restore_flags(flags);

		if (error < 0)
			error = -EINVAL;
		break;

	case OPROMNEXT:
	case OPROMCHILD:
	case OPROMSETCUR:
		if (bufsize < sizeof(int)) {
			error = -EINVAL;
			break;
		}

		node = *((int *) opp->oprom_array);

		save_and_cli(flags);
		switch (cmd) {
		case OPROMNEXT: node = __prom_getsibling(node); break;
		case OPROMCHILD: node = __prom_getchild(node); break;
		case OPROMSETCUR: break;
		}
		restore_flags(flags);

		data->current_node = node;
		*((int *)opp->oprom_array) = node;
		opp->oprom_size = sizeof(int);

		error = copyout((void *)arg, opp, bufsize + sizeof(int));
		break;

	case OPROMPCI2NODE:
		error = -EINVAL;

		if (bufsize >= 2*sizeof(int)) {
#ifdef CONFIG_PCI
			struct pci_dev *pdev;
			struct pcidev_cookie *pcp;
			pdev = pci_find_slot (((int *) opp->oprom_array)[0],
					      ((int *) opp->oprom_array)[1]);

			pcp = pdev->sysdata;
			if (pcp != NULL && pcp->prom_node != -1 && pcp->prom_node) {
				node = pcp->prom_node;
				data->current_node = node;
				*((int *)opp->oprom_array) = node;
				opp->oprom_size = sizeof(int);
				error = copyout((void *)arg, opp, bufsize + sizeof(int));
			}
#endif
		}
		break;

	case OPROMPATH2NODE:
		save_and_cli(flags);
		node = prom_finddevice(opp->oprom_array);
		restore_flags(flags);
		data->current_node = node;
		*((int *)opp->oprom_array) = node;
		opp->oprom_size = sizeof(int);

		error = copyout((void *)arg, opp, bufsize + sizeof(int));
		break;

	case OPROMGETBOOTARGS:
		buf = saved_command_line;

		len = strlen(buf);

		if (len > bufsize) {
			error = -EINVAL;
			break;
		}

		strcpy(opp->oprom_array, buf);
		opp->oprom_size = len;

		error = copyout((void *)arg, opp, bufsize + sizeof(int));
		break;

	case OPROMU2P:
	case OPROMGETCONS:
	case OPROMGETFBNAME:
		if (cnt++ < 10)
			printk(KERN_INFO "openprom_sunos_ioctl: unimplemented ioctl\n");
		error = -EINVAL;
		break;
	default:
		if (cnt++ < 10)
			printk(KERN_INFO "openprom_sunos_ioctl: cmd 0x%X, arg 0x%lX\n", cmd, arg);
		error = -EINVAL;
		break;
	}

	kfree(opp);
	return error;
}
Beispiel #29
0
int pciregions_read_proc(char *buf, char **start, off_t offset,
                   int len, int *eof, void *data)
{
    int i, pos=0;
    int bus, devfn, is_multi = 0;
    unsigned char headertype, pribus, secbus;
    u16 vendorid, deviceid = 0;

    /* to print information about several buses, keep an array of them */
    #define MAXNBUS 8
    int buses[MAXNBUS] = {0,};
    int lastbus = 0; /* only one bus, by default, bus 0 */
    int busindex = 0;

    /* this macro helps keeping the following lines short */
    #define PRINTF(fmt, args...) sprintf(buf+len, fmt, ## args)
    len=0;

    /* Loop through the devices (code not printed in the book) */

    if (!pci_present())
        return sprintf(buf, "PCI not available in this computer\n");

    bus = buses[busindex]; /* first bus (bus 0) */
    for (devfn=0; pos < PAGE_SIZE; devfn++) {
	struct pci_dev *dev = NULL;
	/*
	 * A clean implementation
	 * would have a separate function to dump a single bus, but i
	 * preferred to keep it in one function to include part of it
	 * in the book (the printed code is automagically extracted from
	 * this file).
	 *
	 * Instead, I use a dirty trick to fold two loops in one.
	 */
	if (devfn > 0xff) { /* end of this bus */
	    if (busindex == lastbus) break; 
	    /* loop over to the next bus */
	    bus = buses[++busindex];
	    devfn = 0;
	}

	/*
	 * This code is derived from "drivers/pci/pci.c" in version
	 * 2.0, although it has been modified to work with the 2.4 interface.
	 * This means that the GPL applies to this source file
	 * and credit is due to the original authors
	 * (Drew Eckhardt, Frederic Potter, David Mosberger-Tang)
	 */

        if (PCI_FUNC(devfn) && !is_multi) /* not multi-function */
	    continue;

	dev = pci_find_slot(bus, devfn);
	if (!dev) {
	    if (!PCI_FUNC(devfn)) is_multi = 0; /* no first implies no other */
	    continue; /* no such device */
	}
	pci_read_config_byte(dev, PCI_HEADER_TYPE, &headertype);
        if (!PCI_FUNC(devfn)) /* first function */
	    is_multi = headertype & 0x80;
	headertype &= 0x7f; /* mask multi-function bit */

	/* FIXME: should get rid of the PAGE_SIZE limit */
        if (len > PAGE_SIZE / 2) { /* a big margin, just to be sure */
	    *eof = 1; return len;
	}
	vendorid = dev->vendor;
	deviceid = dev->device;

        len += PRINTF("Bus %i, device %2i, devfn %2i (id %04x-%04x,"
		      " headertype 0x%02x)\n",
		      bus, devfn>>3, devfn & 7,
		      vendorid, deviceid, headertype);
	if (headertype == PCI_HEADER_TYPE_BRIDGE) {
	    /* This is a bridge, print what it does */
	    pci_read_config_byte(dev, PCI_PRIMARY_BUS, &pribus);
	    pci_read_config_byte(dev, PCI_SECONDARY_BUS, &secbus);
	    len += PRINTF("\tbridge connecting PCI bus %i to PCI bus %i\n",
			  secbus, pribus);
	    /* remember about this bus, to dump it later */
	    if (lastbus <= MAXNBUS-1) {
		lastbus++;
		buses[lastbus] = secbus;
		len += PRINTF("\t(bus %i is dumped below)\n", secbus);
	    } else {
		len += PRINTF("\t(bus %i won't be dumped)\n", secbus);
	    }
	    pci_release_device(dev); /* 2.0 compatibility */
	    continue;
	} else if (headertype == PCI_HEADER_TYPE_CARDBUS) {
	    /* This is a CardBus bridge, print what it does */
	    pci_read_config_byte(dev, PCI_CB_PRIMARY_BUS,&pribus);
	    pci_read_config_byte(dev, PCI_CB_CARD_BUS,&secbus);
	    len += PRINTF("\tbridge connecting CardBus %i to PCI bus %i\n",
			  secbus, pribus);
	    pci_release_device(dev); /* 2.0 compatibility */
	    continue;
	} else if (headertype != PCI_HEADER_TYPE_NORMAL) {
	    len += PRINTF("\tunknown header type, skipping\n");
	    pci_release_device(dev); /* 2.0 compatibility */
	    continue;
	}
		
        /* Print the address regions of this device */
        for (i=0; addresses[i]; i++) {
            u32 curr, mask, size;
            char *type;

            pci_read_config_dword(dev, addresses[i],&curr);
            cli();
            pci_write_config_dword(dev, addresses[i],~0);
            pci_read_config_dword(dev, addresses[i],&mask);
            pci_write_config_dword(dev, addresses[i],curr);
            sti();

            if (!mask)
		continue; /* there may be other regions */

	    /*
	     * apply the I/O or memory mask to current position
	     * note that I/O is limited to 0xffff, and 64-bit is not
	     * supported by this simple imeplementation
	     */
	    if (curr & PCI_BASE_ADDRESS_SPACE_IO) {
		curr &= PCI_BASE_ADDRESS_IO_MASK;
	    } else {
		curr &= PCI_BASE_ADDRESS_MEM_MASK;
	    }
		
            len += PRINTF("\tregion %i: mask 0x%08lx, now at 0x%08lx\n", i,
                           (unsigned long)mask,
                           (unsigned long)curr);
            /* extract the type, and the programmable bits */
            if (mask & PCI_BASE_ADDRESS_SPACE_IO) {
                type = "I/O"; mask &= PCI_BASE_ADDRESS_IO_MASK;
		size = (~mask + 1) & 0xffff; /* Bleah */
            } else {
                type = "mem"; mask &= PCI_BASE_ADDRESS_MEM_MASK;
		size = ~mask + 1;
            }
            len += PRINTF("\tregion %i: type %s, size %i (%i%s)\n", i,
                          type, size,
			  (size & 0xfffff) == 0 ? size >> 20 :
			    (size & 0x3ff) == 0 ? size >> 10 : size,
			  (size & 0xfffff) == 0 ? "MB" :
			    (size & 0x3ff) == 0 ? "KB" : "B");
	    if (len > PAGE_SIZE / 2) {
		len += PRINTF("... more info skipped ...\n");
		*eof = 1; return len;
	    }
        }
	pci_release_device(dev); /* 2.0 compatibility */
    } /* devfn */
    *eof = 1;
    return len;
}
Beispiel #30
0
/******************************************************************************
    Module initialization functions
******************************************************************************/
dev_node_t *islpci_attach(dev_locator_t * loc)
{
    u32 io;
    u16 dev_id;
    u8 bus, devfn, irq, latency_tmr;
    struct pci_dev *pci_device;
    struct net_device *nw_device;
    dev_node_t *node;
    islpci_private *private_config;
    int rvalue;
    int dma_mask = 0xffffffff;
    char firmware[256];

    // perform some initial setting checks
    if (loc->bus != LOC_PCI)
        return NULL;
    bus = loc->b.pci.bus;
    devfn = loc->b.pci.devfn;

#if VERBOSE > SHOW_ERROR_MESSAGES 
    DEBUG(SHOW_FUNCTION_CALLS, "islpci_attach(bus %d, function %d)\n",
        bus, devfn);
#endif

    // get some pci settings for verification
    pcibios_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0, &io);
    pcibios_read_config_byte(bus, devfn, PCI_INTERRUPT_LINE, &irq);
    pcibios_read_config_word(bus, devfn, PCI_DEVICE_ID, &dev_id);

	// check whether the latency timer is set correctly
    pcibios_read_config_byte(bus, devfn, PCI_LATENCY_TIMER, &latency_tmr);
#if VERBOSE > SHOW_ERROR_MESSAGES 
	DEBUG( SHOW_TRACING, "latency timer: %x\n", latency_tmr );
#endif
	if( latency_tmr < PCIDEVICE_LATENCY_TIMER_MIN )
	{
		// set the latency timer
		pcibios_write_config_byte(bus, devfn, PCI_LATENCY_TIMER, 
			PCIDEVICE_LATENCY_TIMER_VAL );
	}

    if (io &= ~3, io == 0 || irq == 0)
    {
        DEBUG(SHOW_ERROR_MESSAGES, "The ISL38XX Ethernet interface was not "
        "assigned an %s.\n" KERN_ERR "  It will not be activated.\n",
        io == 0 ? "I/O address" : "IRQ");
        return NULL;
    }
    // get pci device information by loading the pci_dev structure
    if (pci_device = pci_find_slot(bus, devfn), pci_device == NULL)
    {
        // error reading the pci device structure
        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: %s could not get PCI device "
            "information \n", DRIVER_NAME );
        return NULL;
    }

    // determine what the supported DMA memory region is
    while( pci_set_dma_mask( pci_device, dma_mask ) != 0 )
    {
        // range not supported, shift the mask and check again
        if( dma_mask >>=  1, dma_mask == 0 )
        {
            // mask is zero, DMA memory not supported by PCI
            DEBUG(SHOW_ERROR_MESSAGES, "DMA Memory not supported\n" );
            return NULL;
        }
    }

#if VERBOSE > SHOW_ERROR_MESSAGES 
    DEBUG(SHOW_TRACING, "DMA Memory support mask is 0x%x \n", dma_mask );
#endif

    // setup the network device interface and its structure
    if (nw_device = islpci_probe(NULL, pci_device, (long) io, (int) irq),
        nw_device == NULL)
    {
        // error configuring the driver as a network device
        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: %s could not configure "
        "network device \n", DRIVER_NAME );
        return NULL;
    }

#ifdef WDS_LINKS
    mgt_indication_handler ( DEV_NETWORK, nw_device->name, DOT11_OID_WDSLINKADD, islpci_wdslink_add_hndl );
    mgt_indication_handler ( DEV_NETWORK, nw_device->name, DOT11_OID_WDSLINKREMOVE, islpci_wdslink_del_hndl );
#endif

    // save the interrupt request line and use the remapped device base address
    // as the device identification both for uniqueness and parameter passing
    // to the interrupt handler
    private_config = nw_device->priv;
    private_config->pci_irq = irq;
    private_config->pci_dev_id = dev_id;
    private_config->device_id = private_config->remapped_device_base;
	spin_lock_init( &private_config->slock );

    // request for the interrupt before uploading the firmware
    if (rvalue = request_irq(irq, &islpci_interrupt, SA_INTERRUPT | SA_SHIRQ,
        DRIVER_NAME, private_config), rvalue != 0)
    {
        // error, could not hook the handler to the irq
        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: %s could not install "
            "IRQ-handler \n", DRIVER_NAME );
        return NULL;
    }

    // select the firmware file depending on the device id, take for default
    // the 3877 firmware file
    if( dev_id == PCIDEVICE_ISL3890 )
    	strcpy( firmware, ISL3890_IMAGE_FILE );
    else
    	strcpy( firmware, ISL3877_IMAGE_FILE );

#if VERBOSE > SHOW_ERROR_MESSAGES 
    DEBUG(SHOW_TRACING, "Device %x, firmware file: %s \n", dev_id, firmware );
#endif
	
    if (isl38xx_upload_firmware( firmware, private_config->remapped_device_base,
        private_config->device_host_address  ) == -1)
    {
        // error uploading the firmware
        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: %s could not upload the "
        "firmware \n", DRIVER_NAME );
        return NULL;
    }

    // finally setup the node structure with the device information
    node = kmalloc(sizeof(dev_node_t), GFP_KERNEL);
    strcpy(node->dev_name, nw_device->name);
    node->major = 0;
    node->minor = 0;
    node->next = NULL;
    MOD_INC_USE_COUNT;
    return node;
}