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; }
/* * 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); );
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"); } }
/* * 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;
__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; }
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; }
/***************************************************************************** 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; }
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; }
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; }