コード例 #1
0
void
nautilus_kill_arch(int mode)
{
	u32 pmuport;
	int off;

	switch (mode) {
	case LINUX_REBOOT_CMD_RESTART:
		if (! alpha_using_srm) {
			u8 t8;
			pcibios_read_config_byte(0, 0x38, 0x43, &t8);
			pcibios_write_config_byte(0, 0x38, 0x43, t8 | 0x80);
			outb(1, 0x92);
			outb(0, 0x92);
			/* NOTREACHED */
		}
		break;

	case LINUX_REBOOT_CMD_POWER_OFF:
		/* Assume M1543C */
		off = 0x2000;		/* SLP_TYPE = 0, SLP_EN = 1 */
		pcibios_read_config_dword(0, 0x88, 0x10, &pmuport);
		if (!pmuport) {
			/* M1535D/D+ */
			off = 0x3400;	/* SLP_TYPE = 5, SLP_EN = 1 */
			pcibios_read_config_dword(0, 0x88, 0xe0, &pmuport);
		}
		pmuport &= 0xfffe;
		outw(0xffff, pmuport);	/* Clear pending events. */
		outw(off, pmuport + 4);
		/* NOTREACHED */
		break;
	}
}
コード例 #2
0
ファイル: sys_nautilus.c プロジェクト: dduval/kernel-rhel3
void
nautilus_kill_arch(int mode)
{
	switch (mode) {
	case LINUX_REBOOT_CMD_RESTART:
		if (! alpha_using_srm) {
			u8 t8;
			pcibios_read_config_byte(0, 0x38, 0x43, &t8);
			pcibios_write_config_byte(0, 0x38, 0x43, t8 | 0x80);
			outb(1, 0x92);
			outb(0, 0x92);
			/* NOTREACHED */
		}
		break;

	case LINUX_REBOOT_CMD_POWER_OFF:
		{
			u32 pmuport;
			pcibios_read_config_dword(0, 0x88, 0x10, &pmuport);
			pmuport &= 0xfffe;
			outl(0xffff, pmuport); /* clear pending events */
			outw(0x2000, pmuport+4); /* power off */
			/* NOTREACHED */
		}
		break;
	}
}
コード例 #3
0
ファイル: bios32.c プロジェクト: rickgaiser/linux-2.2.1-ps2
void
reset_for_srm(void)
{
	struct srm_irq_reset *qreset;
	struct srm_io_reset *ireset;

	/* Reset any IRQs that we changed.  */
	for (qreset = srm_irq_resets; qreset ; qreset = qreset->next) {
		pcibios_write_config_byte(qreset->dev->bus->number,
					  qreset->dev->devfn,
					  PCI_INTERRUPT_LINE,
					  qreset->irq);
#if 1
		printk("reset_for_srm: bus %d slot 0x%x "
		       "SRM IRQ 0x%x changed back from 0x%x\n",
		       qreset->dev->bus->number,
		       PCI_SLOT(qreset->dev->devfn),
		       qreset->irq, qreset->dev->irq);
#endif
	}

	/* Reset any IO addresses that we changed.  */
	for (ireset = srm_io_resets; ireset ; ireset = ireset->next) {
		pcibios_write_config_dword(ireset->dev->bus->number,
					   ireset->dev->devfn,
					   ireset->reg, ireset->io);
#if 1
		printk("reset_for_srm: bus %d slot 0x%x "
		       "SRM MEM/IO restored to 0x%x\n",
		       ireset->dev->bus->number,
		       PCI_SLOT(ireset->dev->devfn),
		       ireset->io);
#endif
	}
}
コード例 #4
0
ファイル: pci_parity.c プロジェクト: canistation/coreboot
void p64h2_pci_parity_enable(void)
{
	uint8_t reg;

	/* 2SERREN - SERR enable for PCI bridge secondary device  */
	/* 2PEREN  - Parity error for PCI bridge secondary device  */
	pcibios_read_config_byte(1, ((29 << 3) + (0 << 0)), 0x3e, &reg);
	reg |= ((1 << 1) + (1 << 0));
	pcibios_write_config_byte(1, ((29 << 3) + (0 << 0)), 0x3e, reg);

	/* 2SERREN - SERR enable for PCI bridge secondary device  */
	/* 2PEREN  - Parity error for PCI bridge secondary device  */
	pcibios_read_config_byte(1, ((31 << 3) + (0 << 0)), 0x3e, &reg);
	reg |= ((1 << 1) + (1 << 0));
	pcibios_write_config_byte(1, ((31 << 3) + (0 << 0)), 0x3e, reg);

	return;
}
コード例 #5
0
ファイル: smbus.c プロジェクト: 0ida/coreboot
void smbus_enable(void)
{
	/* iobase addr */
	pcibios_write_config_dword(PM_BUS, PM_DEVFN, SMB_BASE,
							   SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO);
	/* smbus enable */
	pcibios_write_config_byte(PM_BUS, PM_DEVFN, HOSTC, HST_EN);
	/* iospace enable */
	pcibios_write_config_word(PM_BUS, PM_DEVFN, PCI_COMMAND, PCI_COMMAND_IO);

    /* Disable interrupt generation */
    outb(0, SMBUS_IO_BASE + SMBHSTCTL);
}
コード例 #6
0
ファイル: smbus.c プロジェクト: RafaelRMachado/Coreboot
void smbus_enable(void)
{
	unsigned char byte;
	/* iobase addr */
	pcibios_write_config_dword(PM_BUS, PM_DEVFN, 0x20, SMBUS_IO_BASE | 1);
	/* smbus enable */
	pcibios_write_config_byte(PM_BUS, PM_DEVFN, 0x40, 1);
	/* iospace enable */
	pcibios_write_config_word(PM_BUS, PM_DEVFN, 0x4, 1);

	/* Disable interrupt generation */
	outb(0, SMBUS_IO_BASE + SMBHSTCTL);

}
コード例 #7
0
ファイル: bios32.c プロジェクト: rickgaiser/linux-2.2.1-ps2
asmlinkage int
sys_pciconfig_write(unsigned long bus, unsigned long dfn,
		    unsigned long off, unsigned long len,
		    unsigned char *buf)
{
	unsigned char ubyte;
	unsigned short ushort;
	unsigned int uint;
	long err = 0;

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

	switch (len) {
	case 1:
		err = get_user(ubyte, buf);
		if (err)
			break;
		err = pcibios_write_config_byte(bus, dfn, off, ubyte);
		if (err != PCIBIOS_SUCCESSFUL) {
			err = -EFAULT;
		}
		break;
	case 2:
		err = get_user(ushort, (unsigned short *)buf);
		if (err)
			break;
		err = pcibios_write_config_word(bus, dfn, off, ushort);
		if (err != PCIBIOS_SUCCESSFUL) {
			err = -EFAULT;
		}
		break;
	case 4:
		err = get_user(uint, (unsigned int *)buf);
		if (err)
			break;
		err = pcibios_write_config_dword(bus, dfn, off, uint);
		if (err != PCIBIOS_SUCCESSFUL) {
			err = -EFAULT;
		}
		break;
	default:
		err = -EINVAL;
		break;
	}
	return err;
}
コード例 #8
0
ファイル: sis900.c プロジェクト: qtekfun/htcDesire820Kernel
static int sis630e_get_mac_addr(struct pci_device * pci_dev, struct nic *nic)
{
	u8 reg;
	int i;
	struct pci_device	*p;

	
	eth_pci_init(pci_isa_bridge_list);

    
    p = pci_isa_bridge_list;

	pcibios_read_config_byte(p->bus,p->devfn, 0x48, &reg);
	pcibios_write_config_byte(p->bus,p->devfn, 0x48, reg | 0x40);

	for (i = 0; i < ETH_ALEN; i++)
	{
		outb(0x09 + i, 0x70);
		((u8 *)(nic->node_addr))[i] = inb(0x71);
	}
	pcibios_write_config_byte(p->bus,p->devfn, 0x48, reg & ~0x40);

	return 1;
}
コード例 #9
0
ファイル: simple_test5.c プロジェクト: 0ida/coreboot
static void spd_enable_refresh(void)
{
    /*
     * Effects:	Uses serial presence detect to set the
     *              refresh rate in the DRAMC register.
     *		see spd_set_dramc for the other values.
     * FIXME:	Check for illegal/unsupported ram configurations and abort
     */
#if HAVE_STATIC_ARRAY_SUPPORT
    static const unsigned char refresh_rates[] = {
        0x01, /* Normal        15.625 us -> 15.6 us */
        0x05, /* Reduced(.25X) 3.9 us    -> 7.8 us */
        0x05, /* Reduced(.5X)  7.8 us    -> 7.8 us */
        0x02, /* Extended(2x)  31.3 us   -> 31.2 us */
        0x03, /* Extended(4x)  62.5 us   -> 62.4 us */
        0x04, /* Extended(8x)  125 us    -> 124.8 us */
    };
#endif
    /* Find the first dimm and assume the rest are the same */
    int status;
    int byte;
    unsigned device;
    unsigned refresh_rate;
    byte = -1;
    status = -1;
    device = SMBUS_MEM_DEVICE_START;
    while ((byte < 0) && (device <= SMBUS_MEM_DEVICE_END)) {
        byte = smbus_read_byte(device, 12);
        device += SMBUS_MEM_DEVICE_INC;
    }
    if (byte < 0) {
        /* We couldn't find anything we must have no memory */
        sdram_no_memory();
    }
    byte &= 0x7f;
    /* Default refresh rate be conservative */
    refresh_rate = 5;
    /* see if the ram refresh is a supported one */
    if (byte < 6) {
#if HAVE_STATIC_ARRAY_SUPPORT
        refresh_rate = refresh_rates[byte];
#endif
    }
    byte = pcibios_read_config_byte(I440GX_BUS, I440GX_DEVFN, 0x57);
    byte &= 0xf8;
    byte |= refresh_rate;
    pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x57, byte);
}
コード例 #10
0
ファイル: linio.c プロジェクト: dmgerman/linux-pre-history
void UxPciConfigWrite(ux_diva_card_t *card, int size, int offset, void *value)
{
	switch (size)
	{
	case sizeof(byte):
		pcibios_write_config_byte(card->bus_num, card->func_num, offset, * (byte *) value);
		break;
	case sizeof(word):
		pcibios_write_config_word(card->bus_num, card->func_num, offset, * (word *) value);
		break;
	case sizeof(dword):
		pcibios_write_config_dword(card->bus_num, card->func_num, offset, * (dword *) value);
		break;
	default:
		printk(KERN_WARNING "Divas: Invalid size in UxPciConfigWrite\n");
	}
}
コード例 #11
0
ファイル: superio.c プロジェクト: iper4497/codigo_c
void
final_superio_fixup()
{
        unsigned int devfn;
        unsigned char enables;

	/* enable com ports, since we're using this built-in superio */
        // enable com1 and com2.
        enables = pcibios_read_config_byte(0, devfn, 0x83, &enables);
        // 0x80 is enable com port b, 0x1 is to make it com2, 0x8 is enable com port a as com1
        enables = 0x80 | 0x1 | 0x8 ;
        pcibios_write_config_byte(0, devfn, 0x83, enables);
        // note: this is also a redo of some port of assembly, but we want everything up.
        // set com1 to 115 kbaud
        // not clear how to do this yet.
        // forget it; done in assembly.

}
コード例 #12
0
int islpci_probe_pci(struct net_device *nw_device, struct pci_dev *pci_device,
                     const struct pci_device_id *id)
{
#else
int  islpci_probe_pci(struct pci_dev *pci_device, const struct pci_device_id *id)
{
    struct net_device *nw_device=NULL;
#endif
    void *phymem;
    u16 irq;
    u8 bus, devfn, latency_tmr;
    islpci_private *private_config;
    int rvalue, dev_id;
    int dma_mask = 0xffffffff;
    char firmware[256];

#if VERBOSE > SHOW_ERROR_MESSAGES 
    DEBUG(SHOW_FUNCTION_CALLS, "islpci_probe_pci\n");
#endif

    // Enable the pci device
    if (pci_enable_device(pci_device))
    {
        DEBUG(SHOW_ERROR_MESSAGES, "%s: pci_enable_device() failed.\n",
            DRIVER_NAME );
        return -EIO;
    }
    // Figure out our resources
    irq = pci_device->irq;
    bus = pci_device->bus->number;
    devfn = pci_device->devfn;
    dev_id = pci_device->device;

	// check whether the latency timer is set correctly
#ifdef CONFIG_ARCH_ISL3893
    pcibios_write_config_byte(bus, devfn, PCI_TRDY_TIMEOUT_VALUE, 0 );
    pcibios_write_config_byte(bus, devfn, PCI_RETRY_TIMEOUT_VALUE, 0 );
#else
    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 );
	}
#endif

    // 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 -EIO;
        }
    }

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

    // call for the physical address to address the PCI device
    phymem = (void *) pci_resource_start(pci_device, 0);
#ifdef CONFIG_ARCH_ISL3893
    // FIXme
    printk("!!pci_resource_start = %p, shound be 0x10000000\n", phymem );
    phymem = 0x10000000;
#endif
    // request the pci device for regions ???
    
    if (rvalue = pci_request_regions(pci_device, DRIVER_NAME ), rvalue)
    {
        DEBUG(SHOW_ERROR_MESSAGES, "pci_request_regions failure, rvalue %i\n",
            rvalue );
        return -EIO;
    }
    
    // enable PCI bus-mastering
    pci_set_master(pci_device);

    // Log the device resources information
#if VERBOSE > SHOW_ERROR_MESSAGES 
    DEBUG(SHOW_TRACING, "islpci device: phymem:0x%lx, irq:%d \n",
        (long) phymem, irq);
#endif

    // setup the network device interface and its structure
    if (nw_device = islpci_probe(nw_device, pci_device, (long) phymem, (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 -EIO;
    }

    // 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
    printk("request_irq(%d)\n", irq );
    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 -EIO;
    }

#ifdef CONFIG_ARCH_ISL3893
    uPCI->ARMIntEnReg = 0x20000FF;
#endif

#ifndef CONFIG_ARCH_ISL3893
    // 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, "Firmware file: %s \n", firmware );
#endif
	
    if (isl38xx_upload_firmware( firmware, private_config->remapped_device_base,
        private_config->device_host_address ) == -1)
    {
        DEBUG(SHOW_ERROR_MESSAGES, "ERROR: %s could not upload the "
            "firmware \n", DRIVER_NAME );
        return -EIO;
    }
#endif

#ifdef CONFIG_ARCH_ISL3893
    mgt_initialize();
#endif

#ifdef INTERSIL_EVENTS 
    mgt_indication_handler ( DEV_NETWORK, nw_device->name, 0, islpci_mgt_indication );
#endif
#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

    return 0;
}

void islpci_remove_pci( struct pci_dev *pci_device )
{
    struct net_device **devp, **next;
    islpci_private *private_config;

#if VERBOSE > SHOW_ERROR_MESSAGES 
    DEBUG(SHOW_FUNCTION_CALLS, "islpci_remove_pci\n");
#endif

    for (devp = &root_islpci_device; *devp; devp = next)
    {
        next = &((islpci_private *) (*devp)->priv)->next_module;
        private_config = (*devp)->priv;

        // free the interrupt request
        writel(0, private_config->remapped_device_base + ISL38XX_INT_EN_REG);
        free_irq(private_config->pci_irq, private_config);
    }

}

int init_module( void )
{
    DEBUG(SHOW_ANYTHING, "Loaded %s, version %s\n", DRIVER_NAME, VERSIONID );

    if (pci_register_driver(&islpci_pci_drv_id) <= 0)
    {
        DEBUG(SHOW_ERROR_MESSAGES, "%s: No devices found, driver not "
            "installed.\n", DRIVER_NAME);
        pci_unregister_driver(&islpci_pci_drv_id);
        return -ENODEV;
    }

    return 0;
}
コード例 #13
0
void pcicfg_write_byte (HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg, HPT_U8 v)
{
	pcibios_write_config_byte(bus, (dev<<3)|func, reg, v);
}
コード例 #14
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;
}
コード例 #15
0
ファイル: via-rhine.c プロジェクト: chinnyannieb/empeg-hijack
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;
}
コード例 #16
0
ファイル: rtl8139.c プロジェクト: chinnyannieb/empeg-hijack
int rtl8139_probe(struct device *dev)
{
	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 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);
			ioaddr = pdev->base_address[0] & ~3;
			irq = pdev->irq;
#else
			u32 pci_ioaddr;
			u8 pci_irq_line;
			pcibios_read_config_byte(pci_bus, pci_device_fn,
									 PCI_INTERRUPT_LINE, &pci_irq_line);
			pcibios_read_config_dword(pci_bus, pci_device_fn,
									  PCI_BASE_ADDRESS_0, &pci_ioaddr);
			ioaddr = pci_ioaddr & ~3;
			irq = pci_irq_line;
#endif
		}

		if ((pci_tbl[chip_idx].flags & PCI_USES_IO) &&
			check_region(ioaddr, pci_tbl[chip_idx].io_size))
			continue;

		/* Activate the card: fix for brain-damaged Win98 BIOSes. */
		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 < 32) {
				printk(KERN_NOTICE "  PCI latency timer (CFLT) is "
					   "unreasonably low at %d.  Setting to 64 clocks.\n",
					   pci_latency);
				pcibios_write_config_byte(pci_bus, pci_device_fn,
										  PCI_LATENCY_TIMER, 64);
			}
		}
		dev = 0;
		cards_found++;
	}

	return cards_found ? 0 : -ENODEV;
}