Exemple #1
0
asmlinkage int
sys_pciconfig_read(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 = pcibios_read_config_byte(bus, dfn, off, &ubyte);
		put_user(ubyte, buf);
		break;
	case 2:
		err = pcibios_read_config_word(bus, dfn, off, &ushort);
		put_user(ushort, (unsigned short *)buf);
		break;
	case 4:
		err = pcibios_read_config_dword(bus, dfn, off, &uint);
		put_user(uint, (unsigned int *)buf);
		break;
	default:
		err = -EINVAL;
		break;
	}
	return err;
}
Exemple #2
0
/*
 * Find the IO address of the controller, its IRQ and so forth.  Fill
 * in some basic stuff into the ctlr_info_t structure.
 */
static void cpqarray_pci_init(ctlr_info_t *c, unchar bus, unchar device_fn)
{
	ushort vendor_id, device_id, command;
	unchar cache_line_size, latency_timer;
	unchar irq, revision;
	uint addr[6];

	int i;

	(void) pcibios_read_config_word(bus, device_fn,
					PCI_VENDOR_ID, &vendor_id);
	(void) pcibios_read_config_word(bus, device_fn,
					PCI_DEVICE_ID, &device_id);
	(void) pcibios_read_config_word(bus, device_fn,
					PCI_COMMAND, &command);
	for(i=0; i<6; i++)
		(void) pcibios_read_config_dword(bus, device_fn,
				PCI_BASE_ADDRESS_0 + i*4, addr+i);

	(void) pcibios_read_config_byte(bus, device_fn,
					PCI_CLASS_REVISION,&revision);
	(void) pcibios_read_config_byte(bus, device_fn,
					PCI_INTERRUPT_LINE, &irq);
	(void) pcibios_read_config_byte(bus, device_fn,
					PCI_CACHE_LINE_SIZE, &cache_line_size);
	(void) pcibios_read_config_byte(bus, device_fn,
					PCI_LATENCY_TIMER, &latency_timer);

DBGINFO(
	printk("vendor_id = %x\n", vendor_id);
	printk("device_id = %x\n", device_id);
	printk("command = %x\n", command);
	for(i=0; i<6; i++)
		printk("addr[%d] = %x\n", i, addr[i]);
	printk("revision = %x\n", revision);
	printk("irq = %x\n", irq);
	printk("cache_line_size = %x\n", cache_line_size);
	printk("latency_timer = %x\n", latency_timer);
);
Exemple #3
0
void UxPciConfigRead(ux_diva_card_t *card, int size, int offset, void *value)
{
	switch (size)
	{
	case sizeof(byte):
		pcibios_read_config_byte(card->bus_num, card->func_num, offset, (byte *) value);
		break;
	case sizeof(word):
		pcibios_read_config_word(card->bus_num, card->func_num, offset, (word *) value);
		break;
	case sizeof(dword):
		pcibios_read_config_dword(card->bus_num, card->func_num, offset, (unsigned int *) value);
		break;
	default:
		printk(KERN_WARNING "Divas: Invalid size in UxPciConfigRead\n");
	}
}
Exemple #4
0
/*
 * ide_init_triton() prepares the IDE driver for DMA operation.
 * This routine is called once, from ide.c during driver initialization,
 * for each triton chipset which is found (unlikely to be more than one).
 */
void ide_init_triton (byte bus, byte fn)
{
	int rc = 0, h;
	int dma_enabled = 0;
	unsigned short bmiba, pcicmd;
	unsigned int timings;

	printk("ide: Triton BM-IDE on PCI bus %d function %d\n", bus, fn);
	/*
	 * See if IDE and BM-DMA features are enabled:
	 */
	if ((rc = pcibios_read_config_word(bus, fn, 0x04, &pcicmd)))
		goto quit;
	if ((pcicmd & 1) == 0)  {
		printk("ide: Triton IDE ports are not enabled\n");
		goto quit;
	}
	if ((pcicmd & 4) == 0) {
		printk("ide: Triton BM-DMA feature is not enabled -- upgrade your BIOS\n");
	} else {
		/*
		 * Get the bmiba base address
		 */
		if ((rc = pcibios_read_config_word(bus, fn, 0x20, &bmiba)))
			goto quit;
		bmiba &= 0xfff0;	/* extract port base address */
		dma_enabled = 1;
	}

	/*
	 * See if ide port(s) are enabled
	 */
	if ((rc = pcibios_read_config_dword(bus, fn, 0x40, &timings)))
		goto quit;
	if (!(timings & 0x80008000)) {
		printk("ide: neither Triton IDE port is enabled\n");
		goto quit;
	}

	/*
	 * Save the dma_base port addr for each interface
	 */
	for (h = 0; h < MAX_HWIFS; ++h) {
		byte s_clks, r_clks;
		ide_hwif_t *hwif = &ide_hwifs[h];
		unsigned short time;
		if (hwif->io_base == 0x1f0) {
			time = timings & 0xffff;
			if ((timings & 0x8000) == 0)	/* interface enabled? */
				continue;
			hwif->chipset = ide_triton;
			if (dma_enabled)
				init_triton_dma(hwif, bmiba);
		} else if (hwif->io_base == 0x170) {
			time = timings >> 16;
			if ((timings & 0x8000) == 0)	/* interface enabled? */
				continue;
			hwif->chipset = ide_triton;
			if (dma_enabled)
				init_triton_dma(hwif, bmiba + 8);
		} else
			continue;
Exemple #5
0
__initfunc(int w83c553f_init(void))
{
    u_char bus, dev;
#if 0    
    unsigned char t8;
    unsigned short t16;
#endif    
    unsigned int t32;
    struct pci_dev *pdev;
    if ((pdev = pci_find_device(PCI_VENDOR_ID_WINBOND,
				PCI_DEVICE_ID_WINBOND_83C553, NULL))) {
	bus = pdev->bus->number;
	dev = pdev->devfn + 1;
	pcibios_read_config_dword(bus, dev, PCI_VENDOR_ID, &t32);
	if (t32 == (PCI_DEVICE_ID_WINBOND_82C105<<16) + PCI_VENDOR_ID_WINBOND) {
#if 0
	    printk("Enabling SL82C105 IDE on W83C553F\n");
	    /*
	     *  FIXME: this doesn't help :-(
	     */

	    /* I/O mapping */
	    pcibios_read_config_word(bus, dev, PCI_COMMAND, &t16);
	    t16 |= PCI_COMMAND_IO;
	    pcibios_write_config_word(bus, dev, PCI_COMMAND, t16);

	    /* Standard IDE registers */
	    pcibios_write_config_dword(bus, dev, PCI_BASE_ADDRESS_0,
					    0xffffffff);
	    pcibios_read_config_dword(bus, dev, PCI_BASE_ADDRESS_0, &t32);
	    pcibios_write_config_dword(bus, dev, PCI_BASE_ADDRESS_0,
					    0x000001f0 | 1);
	    pcibios_write_config_dword(bus, dev, PCI_BASE_ADDRESS_1,
					    0xffffffff);
	    pcibios_read_config_dword(bus, dev, PCI_BASE_ADDRESS_1, &t32);
	    pcibios_write_config_dword(bus, dev, PCI_BASE_ADDRESS_1,
					    0x000003f4 | 1);
	    pcibios_write_config_dword(bus, dev, PCI_BASE_ADDRESS_2,
					    0xffffffff);
	    pcibios_read_config_dword(bus, dev, PCI_BASE_ADDRESS_2, &t32);
	    pcibios_write_config_dword(bus, dev, PCI_BASE_ADDRESS_2,
					    0x00000170 | 1);
	    pcibios_write_config_dword(bus, dev, PCI_BASE_ADDRESS_3,
					    0xffffffff);
	    pcibios_read_config_dword(bus, dev, PCI_BASE_ADDRESS_3, &t32);
	    pcibios_write_config_dword(bus, dev, PCI_BASE_ADDRESS_3,
					    0x00000374 | 1);

	    /* IDE Bus Master Control */
	    pcibios_write_config_dword(bus, dev, PCI_BASE_ADDRESS_4,
					    0xffffffff);
	    pcibios_read_config_dword(bus, dev, PCI_BASE_ADDRESS_4, &t32);
	    pcibios_write_config_dword(bus, dev, PCI_BASE_ADDRESS_4,
					    0x1000 | 1);
	    pcibios_write_config_dword(bus, dev, PCI_BASE_ADDRESS_5,
					    0xffffffff);
	    pcibios_read_config_dword(bus, dev, PCI_BASE_ADDRESS_5, &t32);
	    pcibios_write_config_dword(bus, dev, PCI_BASE_ADDRESS_5,
					    0x1010 | 1);

	    /* IDE Interrupt */
	    pcibios_read_config_byte(bus, dev, PCI_INTERRUPT_LINE, &t8);
	    chrp_ide_irq = t8;
#endif
	    return 1;
	}
    }
    return 0;
}
Exemple #6
0
static int RCscan(void)
{
    int cards_found = 0;
    struct device *dev = 0;

    if (pcibios_present())
    {
        static int pci_index = 0;
        unsigned char pci_bus, pci_device_fn;
        int scan_status;
        int board_index = 0;

        for (; pci_index < 0xff; pci_index++)
        {
            unsigned char pci_irq_line;
            unsigned short pci_command, vendor, device, class;
            unsigned int pci_ioaddr;


            scan_status =
                (pcibios_find_device (RC_PCI45_VENDOR_ID,
                                      RC_PCI45_DEVICE_ID,
                                      pci_index,
                                      &pci_bus,
                                      &pci_device_fn));
#ifdef RCDEBUG
            printk("rc scan_status = 0x%X\n", scan_status);
#endif
            if (scan_status != 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);
            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);
            pcibios_read_config_word(pci_bus,
                                     pci_device_fn,
                                     PCI_CLASS_DEVICE, &class);

            pci_ioaddr &= ~0xf;

#ifdef RCDEBUG
            printk("rc: Found RedCreek PCI adapter\n");
            printk("rc: pci class = 0x%x  0x%x \n", class, class>>8);
            printk("rc: pci_bus = %d,  pci_device_fn = %d\n", pci_bus, pci_device_fn);
            printk("rc: pci_irq_line = 0x%x \n", pci_irq_line);
            printk("rc: pci_ioaddr = 0x%x\n", pci_ioaddr);
#endif

#if 0
            if (check_region(pci_ioaddr, 32768))
            {
                printk("rc: check_region failed\n");
                continue;
            }
            else
            {
                printk("rc: check_region passed\n");
            }
#endif

            /*
             * Get and check the bus-master and latency values.
             * Some PCI BIOSes fail to set the master-enable bit.
             */

            pcibios_read_config_word(pci_bus,
                                     pci_device_fn,
                                     PCI_COMMAND,
                                     &pci_command);
            if ( ! (pci_command & PCI_COMMAND_MASTER)) {
                printk("rc: PCI Master Bit has not been set!\n");

                pci_command |= PCI_COMMAND_MASTER;
                pcibios_write_config_word(pci_bus,
                                          pci_device_fn,
                                          PCI_COMMAND,
                                          pci_command);
            }
            if ( ! (pci_command & PCI_COMMAND_MEMORY)) {
                /*
                 * If the BIOS did not set the memory enable bit, what else
                 * did it not initialize?  Skip this adapter.
                 */
                printk("rc: Adapter %d, PCI Memory Bit has not been set!\n",
                       cards_found);
                printk("rc: Bios problem? \n");
                continue;
            }

            dev = RCfound_device(dev, pci_ioaddr, pci_irq_line,
                                 pci_bus, pci_device_fn,
                                 board_index++, cards_found);

            if (dev) {
                dev = 0;
                cards_found++;
            }
        }
    }
    printk("rc: found %d cards \n", cards_found);
    return cards_found;
}
Exemple #7
0
/*****************************************************************************
 Function name	: orc_ReturnNumberOfAdapters
 Description	: This function will scan PCI bus to get all Orchid card
 Input		: None.
 Output		: None.
 Return		: SUCCESSFUL	- Successful scan
		  ohterwise	- No drives founded
*****************************************************************************/
int orc_ReturnNumberOfAdapters(void)
{
	unsigned int i, iAdapters;

	iAdapters = 0;
	/*
	 * PCI-bus probe.
	 */
	if (pcibios_present()) {
		struct {
			unsigned short vendor_id;
			unsigned short device_id;
		} const inia100_pci_devices[] =
		{
			{ORC_VENDOR_ID, I920_DEVICE_ID},
			{ORC_VENDOR_ID, ORC_DEVICE_ID}
		};

		unsigned int dRegValue;
		unsigned short command;
		WORD wBIOS, wBASE;
		BYTE bPCIBusNum, bInterrupt, bPCIDeviceNum;

#ifdef MMAPIO
		unsigned long page_offset, base;
#endif

#if LINUX_VERSION_CODE > CVT_LINUX_VERSION(2,1,92)
		struct pci_dev *pdev = NULL;
#else
		int index;
		unsigned char pci_bus, pci_devfn;
#endif

		bPCIBusNum = 0;
		bPCIDeviceNum = 0;
		init_inia100Adapter_table();
		for (i = 0; i < NUMBER(inia100_pci_devices); i++) {
#if LINUX_VERSION_CODE > CVT_LINUX_VERSION(2,1,92)
			pdev = NULL;
			while ((pdev = pci_find_device(inia100_pci_devices[i].vendor_id,
					inia100_pci_devices[i].device_id,
						       pdev)))
#else
			index = 0;
			while (!(pcibios_find_device(inia100_pci_devices[i].vendor_id,
					inia100_pci_devices[i].device_id,
					 index++, &pci_bus, &pci_devfn)))
#endif
			{
				if (iAdapters >= MAX_SUPPORTED_ADAPTERS)
					break;	/* Never greater than maximum   */

				if (i == 0) {
					/*
					   printk("inia100: The RAID controller is not supported by\n");
					   printk("inia100:         this driver, we are ignoring it.\n");
					 */
				} else {
					/*
					 * Read sundry information from PCI BIOS.
					 */
#if LINUX_VERSION_CODE > CVT_LINUX_VERSION(2,1,92)
					bPCIBusNum = pdev->bus->number;
					bPCIDeviceNum = pdev->devfn;
					dRegValue = pdev->base_address[0];
					if (dRegValue == -1) {	/* Check return code            */
						printk("\n\rinia100: orchid read configuration error.\n");
						return (0);	/* Read configuration space error  */
					}
					/* <02> read from base address + 0x50 offset to get the wBIOS balue. */
					wBASE = (WORD) dRegValue;

					/* Now read the interrupt line  */
					dRegValue = pdev->irq;
					bInterrupt = dRegValue & 0xFF;	/* Assign interrupt line      */
					pci_read_config_word(pdev, PCI_COMMAND, &command);
					pci_write_config_word(pdev, PCI_COMMAND,
							      command | PCI_COMMAND_MASTER | PCI_COMMAND_IO);

#else
					bPCIBusNum = pci_bus;
					bPCIDeviceNum = pci_devfn;
					pcibios_read_config_dword(pci_bus, pci_devfn, PCI_BASE_ADDRESS_0,
							     &dRegValue);
					if (dRegValue == -1) {	/* Check return code            */
						printk("\n\rinia100: Orchid read configuration error.\n");
						return (0);	/* Read configuration space error  */
					}
					/* <02> read from base address + 0x50 offset to get the wBIOS balue. */
					wBASE = (WORD) dRegValue;

					/* Now read the interrupt line  */
					pcibios_read_config_dword(pci_bus, pci_devfn, PCI_INTERRUPT_LINE,
							     &dRegValue);
					bInterrupt = dRegValue & 0xFF;	/* Assign interrupt line      */
					pcibios_read_config_word(pci_bus, pci_devfn, PCI_COMMAND, &command);
					pcibios_write_config_word(pci_bus, pci_devfn, PCI_COMMAND,
								  command | PCI_COMMAND_MASTER | PCI_COMMAND_IO);
#endif
					wBASE &= PCI_BASE_ADDRESS_IO_MASK;
					wBIOS = ORC_RDWORD(wBASE, 0x50);

#ifdef MMAPIO
					base = wBASE & PAGE_MASK;
					page_offset = wBASE - base;

					/*
					 * replace the next line with this one if you are using 2.1.x:
					 * temp_p->maddr = ioremap(base, page_offset + 256);
					 */
#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,0)
					wBASE = ioremap(base, page_offset + 256);
#else
					wBASE = (WORD) vremap(base, page_offset + 256);
#endif
					if (wBASE) {
						wBASE += page_offset;
					}
#endif

					if (Addinia100_into_Adapter_table(wBIOS, wBASE, bInterrupt, bPCIBusNum,
					    bPCIDeviceNum) == SUCCESSFUL)
						iAdapters++;
				}
			}	/* while(pdev=....) */
		}		/* for PCI_DEVICES */
	}			/* PCI BIOS present */
	return (iAdapters);
}
/*
scan the pci bus
 look for vendor/device Id == Siemens PITA
 if found
    look for  subvendor id
    if found
      write to pita register 1c in the first address range the value 0x04000000
*/
int pcimod_scan(void)
{
    int i, pos = 0;
    int bus, fun;
    unsigned char headertype = 0;
    u32 id;
    u32 vdid;				/* vendor/device id */
    int candev = 0;				/* number of found devices */

    if (!pcibios_present()) {
        printk("CAN: No PCI bios present\n");
        return ENODEV;
    }
    /* printk("CAN: 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 (fun=0; fun < 0x100 && pos < PAGE_SIZE; fun++) {
            if (!PCI_FUNC(fun)) /* first function */
                pcibios_read_config_byte(bus,fun,PCI_HEADER_TYPE, &headertype);
            else if (!(headertype & 0x80))
                continue;
            /* the following call gets vendor AND device ID */
            pcibios_read_config_dword(bus, fun, PCI_VENDOR_ID, &id);
            if (!id || id == ~0) {
                headertype = 0; continue;
            }
            /* v-endor and d-evice id */
            vdid = id;
#if 0
            printk(" -- found pci device, vendor id = %u/0x%x , device 0x%x\n",
            	(id & 0xffff), (id & 0xffff), (id >> 16));
#endif
            pcibios_read_config_dword(bus, fun, PCI_CLASS_REVISION, &id);
#if 0
            printk("    class 0x%x, Revision %d\n",
            	(id >> 8), (id & 0x0ff));
#endif
            if(vdid == (PCI_VENDOR + (PCI_DEVICE << 16))) {
		unsigned char irq;
		u16 cmd;
		u32 svdid;			/* subsystem vendor/device id */
		    /* found EMS CAN CPC-PCI */
		    vdid = 0;	/* reset it */
		    printk("    found Siemens PITA PCI-Chip\n");
		    pcibios_read_config_byte(bus, fun, PCI_INTERRUPT_LINE, &irq);
		    printk("        using IRQ %d\n", irq);
		    pcibios_read_config_word(bus, fun, PCI_COMMAND, &cmd);
		    /* printk("        cmd: 0x%x\n", cmd); */

                    /* PCI_COMMAND should be at least PCI_COMMAND_MEMORY */
		    pcibios_write_config_word(bus, fun,
		    		/* PCI_COMMAND, PCI_COMMAND_MEMORY); */
		    		PCI_COMMAND, PCI_COMMAND_MEMORY + PCI_COMMAND_MASTER	);
		    pcibios_read_config_word(bus, fun, PCI_COMMAND, &cmd);
		    /* printk("        cmd: 0x%x\n", cmd); */




		    pcibios_read_config_dword(bus, fun, PCI_SUBSYSTEM_VENDOR_ID, &svdid);
		    /* printk("        s_vendor 0x%x, s_device 0x%x\n", */
					/* (svdid & 0xffff), (svdid >> 16)); */

		/* How can we be sure that that is an EMS CAN card ?? */


		for (i = 0; addresses[i]; i++) {
		    u32 curr, mask;
		    char *type;

		    pcibios_read_config_dword(bus, fun, addresses[i], &curr);
		    cli();
		    pcibios_write_config_dword(bus, fun, addresses[i], ~0);
		    pcibios_read_config_dword(bus, fun, addresses[i], &mask);
		    pcibios_write_config_dword(bus, fun, addresses[i], curr);
		    sti();

		    /* printk("    region %i: mask 0x%08lx, now at 0x%08lx\n", i, */
				   /* (unsigned long)mask, */
				   /* (unsigned long)curr); */
#if 0 /* we don't need this message, so we don't need this code */
		    if (!mask) {
			printk("    region %i not existent\n", i);
			break;
		    }
#endif
		    /* extract the type, and the programmable bits */
		    if (mask & PCI_BASE_ADDRESS_SPACE) {
		    type = "I/O"; mask &= PCI_BASE_ADDRESS_IO_MASK;
		    } else {
			type = "mem"; mask &= PCI_BASE_ADDRESS_MEM_MASK;
		    }
		/* printk("    region %i: type %s, size %i\n", i, */
			      /* type, ~mask+1); */

		    if(i == 0) {
		    	/* BAR0 internal PITA registers */
			unsigned long ptr = (unsigned long)ioremap(curr, 256);
			/* enable memory access */
		    	/* printk("write to pita\n"); */
			writel(0x04000000, ptr + 0x1c);
			Can_pitapci_control[candev] = ptr;

		    }
		    if(i == 1) {
		    	/* BAR1 parallel I/O
		    	 * at address 0 are some EMS control registers
		    	 * at address 0x400 the first controller area 
		    	 * at address 0x600 the second controller area 
			 * registers are read as 32bit
			 *
			 * at adress 0 we can verify the card
			 * 0x55 0xaa 0x01 0xcb
			 */
			/* dump_CAN(curr, 4); */

			reset_CPC_PCI(curr);

			/* enable interrupts Int_0 */
			/* write to PITAs ICR register */
    			writel(0x00020000, Can_pitapci_control[candev] + 0x0);

			/* dump_CAN(curr + 0x400, 4); */
			if(controller_available(curr + 0x400, 4)) {
			    printk("CAN: at pos 1\n");
			    if(candev > 4) {
				printk("CAN: only 4 devices supported\n");
				break; /* the devices scan loop */
			    }
			    Base[candev]
			    = (unsigned long)ioremap(curr + 0x400, 32*4);
			    IOModel[candev] = 'm';
			    IRQ[candev] = irq;
			    candev++;
			} else {
			    printk("CAN: NO at pos 1\n");
			}
			/* dump_CAN(curr + 0x600, 4); */

			if(controller_available(curr + 0x600, 4)) {
			    printk("CAN: at pos 2\n");
			    if(candev > 4) {
				printk("CAN: only 4 devices supported\n");
				break; /* the devices scan loop */
			    }
			    /* share the board control register with prev ch */
    			    Can_pitapci_control[candev] = 
				Can_pitapci_control[candev - 1];
			    Base[candev]
			    = (unsigned long)ioremap(curr + 0x600, 32*4);
			    IOModel[candev] = 'm';
			    IRQ[candev] = irq;
			    candev++;
			} else {
			    printk("CAN: NO at pos 2\n");
			}
		    }

		}
            } /* EMS CPC-PCI */
        } /* for all devices */
    } /* for all busses */
    return 0;
}
HPT_U16 pcicfg_read_word(HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg)
{
	HPT_U16 v;
	if (pcibios_read_config_word(bus, (dev<<3)|func, reg, &v)) return 0xffff;
	return v;
}
int DivasCardsDiscover(void)
{
	word wNumCards = 0, wDeviceIndex = 0;
	byte byBus, byFunc;
	word wPCIConsultation, PCItmp;
	dword j, i;
	unsigned int PCIserial;
	dia_card_t Card;
	byte *b;
	
	while (wDeviceIndex < 10)
	{
		wPCIConsultation = pcibios_find_device(PCI_VENDOR_ID_EICON, 
				PCI_DEVICE_ID_EICON_MAESTRAQ, 
				wDeviceIndex, 
				&byBus, &byFunc);

		if (wPCIConsultation == PCIBIOS_SUCCESSFUL)
		{

			dword dwRAM, dwDivasIOBase, dwCFG, dwCTL; 			
			byte byIRQ;
			
			printk(KERN_DEBUG "Divas: DIVA Server 4BRI Found\n");
			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_2,(unsigned int *) &dwRAM);
			dwRAM &= 0xFFC00000;
			
			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_1,(unsigned int *) &dwDivasIOBase);
			dwDivasIOBase &= 0xFFFFFF00;
			
			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_0,(unsigned int *) &dwCFG);
			dwCFG &= 0xFFFFFF00;
			
			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_3,(unsigned int *) &dwCTL);
			dwCTL &= 0xFFFFE000;
			

			pcibios_read_config_byte(byBus, byFunc, PCI_INTERRUPT_LINE, &byIRQ);
			/* Retrieve the serial number */

			pcibios_write_config_word(byBus,byFunc,0x4E,0x00FC);

			for (j=0, PCItmp=0; j<10000 && !PCItmp; j++)
			{
				pcibios_read_config_word(byBus,byFunc,0x4E, &PCItmp);
				PCItmp &= 0x8000;  // extract done flag
			}

			pcibios_read_config_dword(byBus,byFunc,0x50, &PCIserial);

		
			Card.memory[DIVAS_RAM_MEMORY] = ioremap(dwRAM, 0x400000);
			Card.memory[DIVAS_CTL_MEMORY] = ioremap(dwCTL, 0x2000);
			Card.memory[DIVAS_CFG_MEMORY] = ioremap(dwCFG, 0x100);
			Card.io_base=dwDivasIOBase;

			Card.irq = byIRQ;
			
			Card.card_type = DIA_CARD_TYPE_DIVA_SERVER_Q;
			Card.bus_type = DIA_BUS_TYPE_PCI;
	
			FPGA_Done = 0;

			/* Create four virtual card structures as we want to treat 
			   the 4Bri card as 4 Bri cards*/
			for(i=0;i<4;i++)
			{

				b=Card.memory[DIVAS_RAM_MEMORY];
				b+=(MQ_PROTCODE_OFFSET) * (i==0?0:1); 
				DPRINTF(("divas: offset = 0x%x", i* MQ_PROTCODE_OFFSET));
				Card.memory[DIVAS_RAM_MEMORY]=b;
 
				b = Card.memory[DIVAS_RAM_MEMORY];
				b += MQ_SM_OFFSET;
				Card.memory[DIVAS_SHARED_MEMORY] = b;

				Card.bus_num = byBus;
				Card.func_num = byFunc;
				Card.slot = -1;

			
				/* Fill in Name */
				Card.name[0] = 'D';
				Card.name[1] = 'I';
				Card.name[2] = 'V';
				Card.name[3] = 'A';
				Card.name[4] = 'S';
				Card.name[5] = 'Q';
				Card.name[6] = '0' + i;
				Card.name[7] = '\0';

				Card.serial = PCIserial;

			 	Card.card_id = wNumCards;

 				if (DivasCardNew(&Card) != 0)
				{
					// Force for loop to terminate
					i = 4;
					continue;
				}
				wNumCards++;

			}//for
		}
		wDeviceIndex++;
	}

	wDeviceIndex = 0;

	while (wDeviceIndex < 10)
	{
		wPCIConsultation = pcibios_find_device(PCI_VENDOR_ID_EICON, 
				PCI_DEVICE_ID_EICON_MAESTRA, 
				wDeviceIndex, 
				&byBus, &byFunc);

		if (wPCIConsultation == PCIBIOS_SUCCESSFUL)
		{
			dword dwPLXIOBase, dwDivasIOBase;
			byte byIRQ;

			printk(KERN_DEBUG "Divas: DIVA Server BRI (S/T) Found\n");
			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_1, (unsigned int *) &dwPLXIOBase);
			dwPLXIOBase &= 0xFFFFFF80;

			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_2, (unsigned int *) &dwDivasIOBase);
			dwDivasIOBase &= 0xFFFFFFFC;

			pcibios_read_config_byte(byBus, byFunc, PCI_INTERRUPT_LINE, &byIRQ);

			Card.card_id = wNumCards;
			Card.card_type = DIA_CARD_TYPE_DIVA_SERVER_B;
			Card.bus_type = DIA_BUS_TYPE_PCI;
			Card.irq = byIRQ;
			Card.reset_base = dwPLXIOBase;
			Card.io_base = dwDivasIOBase;
			Card.bus_num = byBus;
			Card.func_num = byFunc;
			Card.slot = -1;
			Card.name[0] = 'D';
			Card.name[1] = 'I';
			Card.name[2] = 'V';
			Card.name[3] = 'A';
			Card.name[4] = 'S';
			Card.name[5] = 'B';
			Card.name[6] = '\0';

			if (check_region(Card.io_base, 0x20))
			{
				printk(KERN_WARNING "Divas: DIVA I/O Base already in use 0x%x-0x%x\n", Card.io_base, Card.io_base + 0x1F);
				wDeviceIndex++;
				continue;
			}

			if (check_region(Card.reset_base, 0x80))
			{
				printk(KERN_WARNING "Divas: PLX I/O Base already in use 0x%x-0x%x\n", Card.reset_base, Card.reset_base + 0x7F);
				wDeviceIndex++;
				continue;
			}

			if (DivasCardNew(&Card) != 0)
			{
				wDeviceIndex++;
				continue;
			}
			wNumCards++;
		}

		wPCIConsultation = pcibios_find_device(PCI_VENDOR_ID_EICON, 
				PCI_DEVICE_ID_EICON_MAESTRAQ_U, 
				wDeviceIndex, 
				&byBus, &byFunc);

		if (wPCIConsultation == PCIBIOS_SUCCESSFUL)
		{
			dword dwPLXIOBase, dwDivasIOBase;
			byte byIRQ;

			printk(KERN_DEBUG "Divas: DIVA Server BRI (U) Found\n");

			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_1, (unsigned int *) &dwPLXIOBase);
			dwPLXIOBase &= 0xFFFFFF80;

			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_2, (unsigned int *) &dwDivasIOBase);
			dwDivasIOBase &= 0xFFFFFFFC;

			pcibios_read_config_byte(byBus, byFunc, PCI_INTERRUPT_LINE, &byIRQ);

			Card.card_id = wNumCards;
			Card.card_type = DIA_CARD_TYPE_DIVA_SERVER_B;
			Card.bus_type = DIA_BUS_TYPE_PCI;
			Card.irq = byIRQ;
			Card.reset_base = dwPLXIOBase;
			Card.io_base = dwDivasIOBase;
			Card.bus_num = byBus;
			Card.func_num = byFunc;
			Card.slot = -1;
			Card.name[0] = 'D';
			Card.name[1] = 'I';
			Card.name[2] = 'V';
			Card.name[3] = 'A';
			Card.name[4] = 'S';
			Card.name[5] = 'B';
			Card.name[6] = '\0';

			if (check_region(Card.io_base, 0x20))
			{
				printk(KERN_WARNING "Divas: DIVA I/O Base already in use 0x%x-0x%x\n", Card.io_base, Card.io_base + 0x1F);	
				wDeviceIndex++;
				continue;
			}

			if (check_region(Card.reset_base, 0x80))
			{
				printk(KERN_WARNING "Divas: PLX I/O Base already in use 0x%x-0x%x\n", Card.reset_base, Card.reset_base + 0x7F);
				wDeviceIndex++;
				continue;
			}

			if (DivasCardNew(&Card) != 0)
			{
				wDeviceIndex++;
				continue;
			}
			wNumCards++;
		}

		wDeviceIndex++;
	}

	wDeviceIndex = 0;

	while (wDeviceIndex < 10)
	{
		wPCIConsultation = pcibios_find_device(PCI_VENDOR_ID_EICON, 
				PCI_DEVICE_ID_EICON_MAESTRAP, 
				wDeviceIndex, 
				&byBus, &byFunc);

		if (wPCIConsultation == PCIBIOS_SUCCESSFUL)
		{
			dword dwRAM, dwREG, dwCFG;
			byte byIRQ;

			printk(KERN_DEBUG "Divas: DIVA Server PRI Found\n");

			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_0, (unsigned int *) &dwRAM);
			dwRAM &= 0xFFFFF000;

			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_2, (unsigned int *) &dwREG);
			dwREG &= 0xFFFFF000;
			
			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_4, (unsigned int *) &dwCFG);
			dwCFG &= 0xFFFFF000;

			pcibios_read_config_byte(byBus, byFunc, PCI_INTERRUPT_LINE, &byIRQ);

			Card.memory[DIVAS_RAM_MEMORY] = ioremap(dwRAM, 0x10000);
			Card.memory[DIVAS_REG_MEMORY] = ioremap(dwREG, 0x4000);
			Card.memory[DIVAS_CFG_MEMORY] = ioremap(dwCFG, 0x1000);
			Card.memory[DIVAS_SHARED_MEMORY] = Card.memory[DIVAS_RAM_MEMORY] + DIVAS_SHARED_OFFSET;

/*			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_1, (unsigned int *) &dwPLXIOBase);
			dwPLXIOBase &= 0xFFFFFFFc;

			pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_2, (unsigned int *) &dwDivasIOBase);
			dwDivasIOBase &= 0xFFFFFF80;

			pcibios_read_config_byte(byBus, byFunc, PCI_INTERRUPT_LINE, &byIRQ);
*/
			Card.card_id = wNumCards;
			Card.card_type = DIA_CARD_TYPE_DIVA_SERVER;
			Card.bus_type = DIA_BUS_TYPE_PCI;
			Card.irq = byIRQ;
/*			Card.reset_base = dwPLXIOBase;
			Card.io_base = dwDivasIOBase;*/
			Card.bus_num = byBus;
			Card.func_num = byFunc;
			Card.slot = -1;
			Card.name[0] = 'D';
			Card.name[1] = 'I';
			Card.name[2] = 'V';
			Card.name[3] = 'A';
			Card.name[4] = 'S';
			Card.name[5] = 'P';
			Card.name[6] = '\0';

			if (DivasCardNew(&Card) != 0)
			{
				wDeviceIndex++;
				continue;
			}
			wNumCards++;
		}

		wDeviceIndex++;
	}


	printk(KERN_INFO "Divas: %d cards detected\n", wNumCards);

	if(wNumCards == 0)
	{
		return -1;
	}

	Divas_fops.ioctl = do_ioctl;
	Divas_fops.poll = do_poll;
	Divas_fops.read = do_read;
	Divas_fops.open = do_open;
	Divas_fops.release = do_release;

	Divas_major = register_chrdev(0, "Divas", &Divas_fops);

	if (Divas_major < 0)
	{
		printk(KERN_WARNING "Divas: Unable to register character driver\n");
		return -1;
	}

	return 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;
}
Exemple #12
0
static int tc2550_pci_bios_detect(int *irq, int *iobase)
{
	int error;
	unsigned char pci_bus, pci_dev_fn;	/* PCI bus & device function */
	unsigned char pci_irq;	/* PCI interrupt line */
	unsigned int pci_base;	/* PCI I/O base address */
	unsigned short pci_vendor, pci_device;	/* PCI vendor & device IDs */


	/* We will have to change this if more than 1 PCI bus is present and the
	   tripace scsi host is not on the first bus (i.e., a PCI to PCI bridge,
	   which is not supported by bios32 right now anyway). */

	pci_bus = 0;

	for (pci_dev_fn = 0x0; pci_dev_fn < 0xff; pci_dev_fn++)
	{
		pcibios_read_config_word(pci_bus,
					 pci_dev_fn,
					 PCI_VENDOR_ID,
					 &pci_vendor);

		if (pci_vendor == 0x1190)
		{
			pcibios_read_config_word(pci_bus,
						 pci_dev_fn,
						 PCI_DEVICE_ID,
						 &pci_device);

			if (pci_device == 0xc731)
			{
				/* Break out once we have the correct device.  If othertrip 
				   PCI devices are added to this driver we will need to add
				   an or of the other PCI_DEVICE_ID here. */
				printk(KERN_INFO "Tripace TC-2550x based PCI SCSI Adapter detected\n");
				break;
			} else
			{
				/* If we can't finl an tripace scsi card we give up. */
				return 0;
			}
		}
	}

/* vendor id not found */

	if (pci_device != 0xc731)
	{
		printk(KERN_INFO "Tripace TC-2550x - No Host Adapter Detected \n");
		return (0);
	}
	/* We now have the appropriate device function for the tripace board so we
	   just read the PCI config info from the registers.  */

	if ((error = pcibios_read_config_dword(pci_bus,
					       pci_dev_fn,
					       PCI_BASE_ADDRESS_0,
					       &pci_base))
	    || (error = pcibios_read_config_byte(pci_bus,
						 pci_dev_fn,
						 PCI_INTERRUPT_LINE,
						 &pci_irq)))
	{
		printk(KERN_ERR "Tripace TC-2550x not initializing"
		       " due to error reading configuration space\n");
		return 0;
	} else
	{
		printk(KERN_INFO "TC-2550x PCI: IRQ = %u, I/O base = %X\n",
		       pci_irq, pci_base);

		/* Now we have the I/O base address and interrupt from the PCI
		   configuration registers.  
		 */

		*irq = pci_irq;
		*iobase = (pci_base & 0xfff8);
		CFG_BASE = *iobase;

		printk(KERN_INFO "TC-2550x Driver version 1.00.000 (904)\n");
		printk(KERN_INFO "TC-2550x: IRQ = %d, I/O base = 0x%X\n", *irq, *iobase);
		return 1;
	}
	return 0;
}
Exemple #13
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;
}
Exemple #14
0
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;
}