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; } }
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; } }
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 } }
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 |= ((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 |= ((1 << 1) + (1 << 0)); pcibios_write_config_byte(1, ((31 << 3) + (0 << 0)), 0x3e, reg); return; }
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); }
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); }
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; }
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, ®); 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; }
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); }
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"); } }
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. }
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; }
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); }
/****************************************************************************** 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; }
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; }
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; }