static void tegra_gpio_attach_bank(struct tegra_gpio_softc *sc, u_int bankno) { struct tegra_gpio_bank *bank = &sc->sc_banks[bankno]; struct gpiobus_attach_args gba; u_int pin; bank->bank_sc = sc; bank->bank_pb = &tegra_gpio_pinbanks[bankno]; bank->bank_gc.gp_cookie = bank; bank->bank_gc.gp_pin_read = tegra_gpio_pin_read; bank->bank_gc.gp_pin_write = tegra_gpio_pin_write; bank->bank_gc.gp_pin_ctl = tegra_gpio_pin_ctl; const uint32_t cnf = GPIO_READ(bank, GPIO_CNF_REG); for (pin = 0; pin < __arraycount(bank->bank_pins); pin++) { bank->bank_pins[pin].pin_num = pin; /* skip pins in SFIO mode */ if ((cnf & __BIT(pin)) == 0) continue; bank->bank_pins[pin].pin_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_TRISTATE; bank->bank_pins[pin].pin_state = tegra_gpio_pin_read(bank, pin); } memset(&gba, 0, sizeof(gba)); gba.gba_gc = &bank->bank_gc; gba.gba_pins = bank->bank_pins; gba.gba_npins = __arraycount(bank->bank_pins); bank->bank_dev = config_found_ia(sc->sc_dev, "gpiobus", &gba, tegra_gpio_cfprint); }
void emdtv_ir_attach(struct emdtv_softc *sc) { struct ir_attach_args ia; usb_endpoint_descriptor_t *ed; usbd_status status; int err; ed = usbd_interface2endpoint_descriptor(sc->sc_iface, 0); if (ed == NULL) return; status = usbd_open_pipe_intr(sc->sc_iface, ed->bEndpointAddress, USBD_EXCLUSIVE_USE, &sc->sc_intr_pipe, sc, &sc->sc_intr_buf, 1, emdtv_ir_intr, USBD_DEFAULT_INTERVAL); if (status != USBD_NORMAL_COMPLETION) { aprint_error_dev(sc->sc_dev, "couldn't open intr pipe: %s\n", usbd_errstr(status)); return; } mutex_init(&sc->sc_ir_mutex, MUTEX_DEFAULT, IPL_VM); err = workqueue_create(&sc->sc_ir_wq, "emdtvir", emdtv_ir_worker, sc, PRI_NONE, IPL_VM, 0); if (err) aprint_error_dev(sc->sc_dev, "couldn't create workqueue: %d\n", err); ia.ia_type = IR_TYPE_CIR; ia.ia_methods = &emdtv_ir_methods; ia.ia_handle = sc; sc->sc_cirdev = config_found_ia(sc->sc_dev, "irbus", &ia, ir_print); }
static void eppcic_config_socket(struct eppcic_handle *ph) { struct eppcic_softc *sc = ph->ph_sc; eppcic_chipset_tag_t pcic = sc->sc_pcic; struct pcmciabus_attach_args paa; int wait; paa.paa_busname = "pcmcia"; paa.pct = (pcmcia_chipset_tag_t)&eppcic_functions; paa.pch = (pcmcia_chipset_handle_t)ph; paa.iobase = ph->ph_space[IO].base; paa.iosize = ph->ph_space[IO].size; ph->ph_card = config_found_ia((void*)sc, "pcmciabus", &paa, eppcic_print); epgpio_intr_establish(sc->sc_gpio, ph->ph_port, ph->ph_cd[0], EDGE_TRIGGER | FALLING_EDGE | DEBOUNCE, IPL_TTY, eppcic_intr_carddetect, ph); epgpio_intr_establish(sc->sc_gpio, ph->ph_port, ph->ph_cd[1], EDGE_TRIGGER | RISING_EDGE | DEBOUNCE, IPL_TTY, eppcic_intr_carddetect, ph); wait = (pcic->power_ctl)(sc, ph->ph_socket, POWER_OFF); delay(wait); ph->ph_status[0] = epgpio_read(sc->sc_gpio, ph->ph_port, ph->ph_cd[0]); ph->ph_status[1] = epgpio_read(sc->sc_gpio, ph->ph_port, ph->ph_cd[1]); DPRINTFN(1, ("eppcic_config_socket: cd1=%d, cd2=%d\n",ph->ph_status[0],ph->ph_status[1])); ph->ph_run = 1; kthread_create(PRI_NONE, 0, NULL, eppcic_event_thread, ph, &ph->ph_event_thread, "%s,%d", sc->sc_dev.dv_xname, ph->ph_socket); }
static void mppb_attach(device_t parent, device_t self, void *aux) { struct mppb_softc *sc; struct pcibus_attach_args pba; struct zbus_args *zap; pci_chipset_tag_t pc; #ifdef PCI_NETBSD_CONFIGURE struct extent *ioext, *memext; #endif /* PCI_NETBSD_CONFIGURE */ zap = aux; sc = device_private(self); pc = &sc->apc; sc->sc_dev = self; sc->ba = zap->va; aprint_normal(": Matay Prometheus PCI bridge\n"); /* Setup bus space mappings. */ sc->pci_conf_area.base = (bus_addr_t) sc->ba + MPPB_CONF_BASE; sc->pci_conf_area.absm = &amiga_bus_stride_1swap; sc->pci_mem_area.base = (bus_addr_t) sc->ba + MPPB_MEM_BASE; sc->pci_mem_area.absm = &amiga_bus_stride_1; sc->pci_io_area.base = (bus_addr_t) sc->ba + MPPB_IO_BASE; sc->pci_io_area.absm = &amiga_bus_stride_1; #ifdef MPPB_DEBUG aprint_normal("mppb mapped conf %x->%x, mem %x->%x\n, io %x->%x\n", kvtop((void*) sc->pci_conf_area.base), sc->pci_conf_area.base, kvtop((void*) sc->pci_mem_area.base), sc->pci_mem_area.base, kvtop((void*) sc->pci_io_area.base), sc->pci_io_area.base); #endif sc->apc.pci_conf_datat = &(sc->pci_conf_area); if (bus_space_map(sc->apc.pci_conf_datat, 0, MPPB_CONF_SIZE, 0, &sc->apc.pci_conf_datah)) aprint_error_dev(self, "couldn't map PCI configuration data space\n"); /* Initialize the PCI chipset tag. */ sc->apc.pc_conf_v = (void*) pc; sc->apc.pc_bus_maxdevs = mppb_pci_bus_maxdevs; sc->apc.pc_make_tag = amiga_pci_make_tag; sc->apc.pc_decompose_tag = amiga_pci_decompose_tag; sc->apc.pc_conf_read = mppb_pci_conf_read; sc->apc.pc_conf_write = mppb_pci_conf_write; sc->apc.pc_attach_hook = mppb_pci_attach_hook; sc->apc.pc_intr_map = mppb_pci_intr_map; sc->apc.pc_intr_string = amiga_pci_intr_string; sc->apc.pc_intr_establish = amiga_pci_intr_establish; sc->apc.pc_intr_disestablish = amiga_pci_intr_disestablish; sc->apc.pc_conf_hook = amiga_pci_conf_hook; sc->apc.pc_conf_interrupt = amiga_pci_conf_interrupt; #ifdef PCI_NETBSD_CONFIGURE ioext = extent_create("mppbio", MPPB_IO_BASE, MPPB_IO_BASE + MPPB_IO_SIZE, NULL, 0, EX_NOWAIT); memext = extent_create("mppbmem", MPPB_MEM_BASE, MPPB_MEM_BASE + MPPB_MEM_SIZE, NULL, 0, EX_NOWAIT); #ifdef MPPB_DEBUG aprint_normal("mppb: reconfiguring the bus!\n"); #endif /* MPPB_DEBUG */ pci_configure_bus(pc, ioext, memext, NULL, 0, CACHELINE_SIZE); extent_destroy(ioext); extent_destroy(memext); #endif /* PCI_NETBSD_CONFIGURE */ pba.pba_iot = &(sc->pci_io_area); pba.pba_memt = &(sc->pci_mem_area); pba.pba_dmat = NULL; pba.pba_dmat64 = NULL; pba.pba_pc = pc; pba.pba_flags = PCI_FLAGS_MEM_OKAY | PCI_FLAGS_IO_OKAY; pba.pba_bus = 0; pba.pba_bridgetag = NULL; config_found_ia(self, "pcibus", &pba, pcibusprint); }
static void macepci_attach(device_t parent, device_t self, void *aux) { struct macepci_softc *sc = device_private(self); pci_chipset_tag_t pc = &sc->sc_pc; struct mace_attach_args *maa = aux; struct pcibus_attach_args pba; u_int32_t control; int rev; if (bus_space_subregion(maa->maa_st, maa->maa_sh, maa->maa_offset, 0, &pc->ioh) ) panic("macepci_attach: couldn't map"); pc->iot = maa->maa_st; rev = bus_space_read_4(pc->iot, pc->ioh, MACEPCI_REVISION); printf(": rev %d\n", rev); pc->pc_bus_maxdevs = macepci_bus_maxdevs; pc->pc_conf_read = macepci_conf_read; pc->pc_conf_write = macepci_conf_write; pc->pc_intr_map = macepci_intr_map; pc->pc_intr_string = macepci_intr_string; pc->intr_establish = mace_intr_establish; pc->intr_disestablish = mace_intr_disestablish; bus_space_write_4(pc->iot, pc->ioh, MACE_PCI_ERROR_ADDR, 0); bus_space_write_4(pc->iot, pc->ioh, MACE_PCI_ERROR_FLAGS, 0); /* Turn on PCI error interrupts */ bus_space_write_4(pc->iot, pc->ioh, MACE_PCI_CONTROL, MACE_PCI_CONTROL_SERR_ENA | MACE_PCI_CONTROL_PARITY_ERR | MACE_PCI_CONTROL_PARK_LIU | MACE_PCI_CONTROL_OVERRUN_INT | MACE_PCI_CONTROL_PARITY_INT | MACE_PCI_CONTROL_SERR_INT | MACE_PCI_CONTROL_IT_INT | MACE_PCI_CONTROL_RE_INT | MACE_PCI_CONTROL_DPED_INT | MACE_PCI_CONTROL_TAR_INT | MACE_PCI_CONTROL_MAR_INT); /* * Enable all MACE PCI interrupts. They will be masked by * the CRIME code. */ control = bus_space_read_4(pc->iot, pc->ioh, MACEPCI_CONTROL); control |= CONTROL_INT_MASK; bus_space_write_4(pc->iot, pc->ioh, MACEPCI_CONTROL, control); #if NPCI > 0 pc->pc_ioext = extent_create("macepciio", 0x00001000, 0x01ffffff, NULL, 0, EX_NOWAIT); pc->pc_memext = extent_create("macepcimem", 0x80100000, 0x81ffffff, NULL, 0, EX_NOWAIT); pci_configure_bus(pc, pc->pc_ioext, pc->pc_memext, NULL, 0, mips_cache_info.mci_dcache_align); memset(&pba, 0, sizeof pba); /*XXX*/ pba.pba_iot = SGIMIPS_BUS_SPACE_IO; /*XXX*/ pba.pba_memt = SGIMIPS_BUS_SPACE_MEM; pba.pba_dmat = &pci_bus_dma_tag; pba.pba_dmat64 = NULL; pba.pba_bus = 0; pba.pba_bridgetag = NULL; pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY | PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY; pba.pba_pc = pc; #ifdef MACEPCI_IO_WAS_BUGGY if (rev == 0) pba.pba_flags &= ~PCI_FLAGS_IO_OKAY; /* Buggy? */ #endif cpu_intr_establish(maa->maa_intr, IPL_NONE, macepci_intr, sc); config_found_ia(self, "pcibus", &pba, pcibusprint); #endif }
static void jmide_attach(device_t parent, device_t self, void *aux) { struct pci_attach_args *pa = aux; struct jmide_softc *sc = device_private(self); const struct jmide_product *jp; const char *intrstr; pci_intr_handle_t intrhandle; u_int32_t pcictrl0 = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_JM_CONTROL0); u_int32_t pcictrl1 = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_JM_CONTROL1); struct pciide_product_desc *pp; int ahci_used = 0; sc->sc_pciide.sc_wdcdev.sc_atac.atac_dev = self; jp = jmide_lookup(pa->pa_id); if (jp == NULL) { printf("jmide_attach: WTF?\n"); return; } sc->sc_npata = jp->jm_npata; sc->sc_nsata = jp->jm_nsata; pci_aprint_devinfo(pa, "JMICRON PATA/SATA disk controller"); aprint_normal("%s: ", JM_NAME(sc)); if (sc->sc_npata) aprint_normal("%d PATA port%s", sc->sc_npata, (sc->sc_npata > 1) ? "s" : ""); if (sc->sc_nsata) aprint_normal("%s%d SATA port%s", sc->sc_npata ? ", " : "", sc->sc_nsata, (sc->sc_nsata > 1) ? "s" : ""); aprint_normal("\n"); if (pci_intr_map(pa, &intrhandle) != 0) { aprint_error("%s: couldn't map interrupt\n", JM_NAME(sc)); return; } intrstr = pci_intr_string(pa->pa_pc, intrhandle); sc->sc_pciide.sc_pci_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO, jmide_intr, sc); if (sc->sc_pciide.sc_pci_ih == NULL) { aprint_error("%s: couldn't establish interrupt", JM_NAME(sc)); return; } aprint_normal("%s: interrupting at %s\n", JM_NAME(sc), intrstr ? intrstr : "unknown interrupt"); if (pcictrl0 & JM_CONTROL0_AHCI_EN) { bus_size_t size; struct jmahci_attach_args jma; u_int32_t saved_pcictrl0; /* * ahci controller enabled; disable sata on pciide and * enable on ahci */ saved_pcictrl0 = pcictrl0; pcictrl0 |= JM_CONTROL0_SATA0_AHCI | JM_CONTROL0_SATA1_AHCI; pcictrl0 &= ~(JM_CONTROL0_SATA0_IDE | JM_CONTROL0_SATA1_IDE); pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_JM_CONTROL0, pcictrl0); /* attach ahci controller if on the right function */ if ((pa->pa_function == 0 && (pcictrl0 & JM_CONTROL0_AHCI_F1) == 0) || (pa->pa_function == 1 && (pcictrl0 & JM_CONTROL0_AHCI_F1) != 0)) { jma.jma_pa = pa; /* map registers */ if (pci_mapreg_map(pa, AHCI_PCI_ABAR, PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &jma.jma_ahcit, &jma.jma_ahcih, NULL, &size) != 0) { aprint_error("%s: can't map ahci registers\n", JM_NAME(sc)); } else { sc->sc_ahci = config_found_ia( sc->sc_pciide.sc_wdcdev.sc_atac.atac_dev, "jmide_hl", &jma, jmahci_print); } /* * if we couldn't attach an ahci, try to fall back * to pciide. Note that this will not work if IDE * is on function 0 and AHCI on function 1. */ if (sc->sc_ahci == NULL) { pcictrl0 = saved_pcictrl0 & ~(JM_CONTROL0_SATA0_AHCI | JM_CONTROL0_SATA1_AHCI | JM_CONTROL0_AHCI_EN); pcictrl0 |= JM_CONTROL0_SATA1_IDE | JM_CONTROL0_SATA0_IDE; pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_JM_CONTROL0, pcictrl0); } else ahci_used = 1; } } sc->sc_chan_swap = ((pcictrl0 & JM_CONTROL0_PCIIDE_CS) != 0); /* compute the type of internal primary channel */ if (pcictrl1 & JM_CONTROL1_PATA1_PRI) { if (sc->sc_npata > 1) sc->sc_chan_type[sc->sc_chan_swap ? 1 : 0] = TYPE_PATA; else sc->sc_chan_type[sc->sc_chan_swap ? 1 : 0] = TYPE_NONE; } else if (ahci_used == 0 && sc->sc_nsata > 0) sc->sc_chan_type[sc->sc_chan_swap ? 1 : 0] = TYPE_SATA; else sc->sc_chan_type[sc->sc_chan_swap ? 1 : 0] = TYPE_NONE; /* compute the type of internal secondary channel */ if (sc->sc_nsata > 1 && ahci_used == 0 && (pcictrl0 & JM_CONTROL0_PCIIDE0_MS) == 0) { sc->sc_chan_type[sc->sc_chan_swap ? 0 : 1] = TYPE_SATA; } else { /* only a drive if first PATA enabled */ if (sc->sc_npata > 0 && (pcictrl0 & JM_CONTROL0_PATA0_EN) && (pcictrl0 & (sc->sc_chan_swap ? JM_CONTROL0_PATA0_PRI: JM_CONTROL0_PATA0_SEC))) sc->sc_chan_type[sc->sc_chan_swap ? 0 : 1] = TYPE_PATA; else sc->sc_chan_type[sc->sc_chan_swap ? 0 : 1] = TYPE_NONE; } if (sc->sc_chan_type[0] == TYPE_NONE && sc->sc_chan_type[1] == TYPE_NONE) return; if (pa->pa_function == 0 && (pcictrl0 & JM_CONTROL0_PCIIDE_F1)) return; if (pa->pa_function == 1 && (pcictrl0 & JM_CONTROL0_PCIIDE_F1) == 0) return; pp = malloc(sizeof(struct pciide_product_desc), M_DEVBUF, M_NOWAIT); if (pp == NULL) { aprint_error("%s: can't malloc sc_pp\n", JM_NAME(sc)); return; } aprint_normal("%s: PCI IDE interface used", JM_NAME(sc)); pp->ide_product = 0; pp->ide_flags = 0; pp->ide_name = NULL; pp->chip_map = jmpata_chip_map; pciide_common_attach(&sc->sc_pciide, pa, pp); }
void gtpci_attach(struct device *parent, struct device *self, void *aux) { struct pcibus_attach_args pba; struct gt_attach_args * const ga = aux; struct gt_softc * const gt = device_private(parent); struct gtpci_softc * const gtp = device_private(self); struct gtpci_chipset * const gtpc = >p->gtpci_gtpc; struct pci_chipset * const pc = >pc->gtpc_pc; const int busno = ga->ga_unit; uint32_t data; GT_PCIFOUND(gt, ga); pc->pc_funcs = >pci_functions; pc->pc_parent = self; gtpc->gtpc_busno = busno; gtpc->gtpc_cfgaddr = PCI_CONFIG_ADDR(busno); gtpc->gtpc_cfgdata = PCI_CONFIG_DATA(busno); gtpc->gtpc_syncreg = PCI_SYNC_REG(busno); gtpc->gtpc_gt_memt = ga->ga_memt; gtpc->gtpc_gt_memh = ga->ga_memh; /* * Let's find out where we are located. */ data = gtpci_read(gtpc, PCI_P2P_CONFIGURATION(gtpc->gtpc_busno)); gtpc->gtpc_self = gtpci_make_tag(>pc->gtpc_pc, PCI_P2PCFG_BusNum_GET(data), PCI_P2PCFG_DevNum_GET(data), 0); switch (busno) { case 0: gtpc->gtpc_io_bs = gt->gt_pci0_iot; gtpc->gtpc_mem_bs = gt->gt_pci0_memt; gtpc->gtpc_host = gt->gt_pci0_host; break; case 1: gtpc->gtpc_io_bs = gt->gt_pci1_iot; gtpc->gtpc_mem_bs = gt->gt_pci1_memt; gtpc->gtpc_host = gt->gt_pci1_host; break; default: break; } /* * If no bus_spaces exist, then it's been disabled. */ if (gtpc->gtpc_io_bs == NULL && gtpc->gtpc_mem_bs == NULL) { aprint_normal(": disabled\n"); return; } aprint_normal("\n"); /* * clear any pre-existing error interrupt(s) * clear latched pci error registers * establish ISRs for PCI errors * enable PCI error interrupts */ gtpci_write(gtpc, PCI_ERROR_MASK(gtpc->gtpc_busno), 0); gtpci_write(gtpc, PCI_ERROR_CAUSE(gtpc->gtpc_busno), 0); (void)gtpci_read(gtpc, PCI_ERROR_DATA_LOW(gtpc->gtpc_busno)); (void)gtpci_read(gtpc, PCI_ERROR_DATA_HIGH(gtpc->gtpc_busno)); (void)gtpci_read(gtpc, PCI_ERROR_COMMAND(gtpc->gtpc_busno)); (void)gtpci_read(gtpc, PCI_ERROR_ADDRESS_HIGH(gtpc->gtpc_busno)); (void)gtpci_read(gtpc, PCI_ERROR_ADDRESS_LOW(gtpc->gtpc_busno)); if (gtpc->gtpc_host) { intr_establish(pci_irqs[gtpc->gtpc_busno][0], IST_LEVEL, IPL_VM, gtpci_error_intr, pc); intr_establish(pci_irqs[gtpc->gtpc_busno][1], IST_LEVEL, IPL_VM, gtpci_error_intr, pc); intr_establish(pci_irqs[gtpc->gtpc_busno][2], IST_LEVEL, IPL_VM, gtpci_error_intr, pc); aprint_normal_dev(pc->pc_parent, "%s%d error interrupts at irqs %s, %s, %s\n", "pci", busno, intr_string(pci_irqs[gtpc->gtpc_busno][0]), intr_string(pci_irqs[gtpc->gtpc_busno][1]), intr_string(pci_irqs[gtpc->gtpc_busno][2])); gtpci_write(gtpc, PCI_ERROR_MASK(gtpc->gtpc_busno), PCI_SERRMSK_ALL_ERRS); } /* * Fill in the pci_bus_attach_args */ pba.pba_pc = pc; pba.pba_bus = 0; pba.pba_iot = gtpc->gtpc_io_bs; pba.pba_memt = gtpc->gtpc_mem_bs; pba.pba_dmat = gt->gt_dmat; pba.pba_flags = 0; if (pba.pba_iot != NULL) pba.pba_flags |= PCI_FLAGS_IO_ENABLED; if (pba.pba_memt != NULL) pba.pba_flags |= PCI_FLAGS_MEM_ENABLED; data = gtpci_read(gtpc, PCI_COMMAND(gtpc->gtpc_busno)); if (data & PCI_CMD_MRdMul) pba.pba_flags |= PCI_FLAGS_MRM_OKAY; if (data & PCI_CMD_MRdLine) pba.pba_flags |= PCI_FLAGS_MRL_OKAY; pba.pba_flags |= PCI_FLAGS_MWI_OKAY; gt_watchdog_service(); /* * Configure the pci bus. */ config_found_ia(self, "pcibus", &pba, gtpci_cfprint); gt_watchdog_service(); }
/* * Attach the mainbus. */ void mainbus_attach(device_t parent, device_t self, void *aux) { struct pcibus_attach_args pba; #if NPCI > 0 struct genppc_pci_chipset_businfo *pbi; #endif #ifdef PCI_NETBSD_CONFIGURE struct extent *ioext, *memext; #endif mainbus_found = 1; aprint_normal("\n"); /* attach cpu */ config_found_ia(self, "mainbus", NULL, mainbus_print); /* * XXX Note also that the presence of a PCI bus should * XXX _always_ be checked, and if present the bus should be * XXX 'found'. However, because of the structure of the code, * XXX that's not currently possible. */ #if NPCI > 0 genppc_pct = malloc(sizeof(struct genppc_pci_chipset), M_DEVBUF, M_NOWAIT); KASSERT(genppc_pct != NULL); mvmeppc_pci_get_chipset_tag(genppc_pct); pbi = malloc(sizeof(struct genppc_pci_chipset_businfo), M_DEVBUF, M_NOWAIT); KASSERT(pbi != NULL); pbi->pbi_properties = prop_dictionary_create(); KASSERT(pbi->pbi_properties != NULL); SIMPLEQ_INIT(&genppc_pct->pc_pbi); SIMPLEQ_INSERT_TAIL(&genppc_pct->pc_pbi, pbi, next); #ifdef PCI_NETBSD_CONFIGURE ioext = extent_create("pciio", 0x00008000, 0x0000ffff, NULL, 0, EX_NOWAIT); memext = extent_create("pcimem", 0x00000000, 0x0fffffff, NULL, 0, EX_NOWAIT); pci_configure_bus(genppc_pct, ioext, memext, NULL, 0, CACHELINESIZE); extent_destroy(ioext); extent_destroy(memext); #endif pba.pba_iot = &prep_io_space_tag; pba.pba_memt = &prep_mem_space_tag; pba.pba_dmat = &pci_bus_dma_tag; pba.pba_dmat64 = NULL; pba.pba_pc = genppc_pct; pba.pba_bus = 0; pba.pba_bridgetag = NULL; pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY; config_found_ia(self, "pcibus", &pba, pcibusprint); #endif }
static void igma_i2c_attach(struct igma_softc *sc) { struct igma_i2c *ii; int i; #if 0 struct i2cbus_attach_args iba; #endif for (i=0; i<sc->sc_chip.num_gmbus; ++i) { ii = &sc->sc_ii[i]; ii->ii_sc = sc; /* XXX */ ii->ii_reg = sc->sc_chip.gpio_offset - PCH_GPIOA; switch (i) { case 0: ii->ii_reg += PCH_GPIOB; ii->ii_name = "ssc"; break; case 1: ii->ii_reg += PCH_GPIOA; ii->ii_name = "vga"; break; case 2: ii->ii_reg += PCH_GPIOC; ii->ii_name = "panel"; break; case 3: ii->ii_reg += PCH_GPIOD; ii->ii_name = "dpc"; break; case 4: ii->ii_reg += PCH_GPIOE; ii->ii_name = "dpb"; break; case 5: ii->ii_reg += PCH_GPIOF; ii->ii_name = "dpd"; break; default: panic("don't know GMBUS %d\n",i); } mutex_init(&ii->ii_lock, MUTEX_DEFAULT, IPL_NONE); ii->ii_i2c.ic_cookie = ii; ii->ii_i2c.ic_acquire_bus = igma_i2c_acquire_bus; ii->ii_i2c.ic_release_bus = igma_i2c_release_bus; ii->ii_i2c.ic_send_start = igma_i2c_send_start; ii->ii_i2c.ic_send_stop = igma_i2c_send_stop; ii->ii_i2c.ic_initiate_xfer = igma_i2c_initiate_xfer; ii->ii_i2c.ic_read_byte = igma_i2c_read_byte; ii->ii_i2c.ic_write_byte = igma_i2c_write_byte; ii->ii_i2c.ic_exec = NULL; #if 0 iba.iba_type = I2C_TYPE_SMBUS; iba.iba_tag = &ii->ii_i2c; config_found_ia(sc->sc_dev, "i2cbus", &iba, iicbus_print); #endif } }
static void pchbattach(device_t parent, device_t self, void *aux) { struct plb_attach_args *paa = aux; struct pcibus_attach_args pba; char devinfo[256]; #ifdef PCI_NETBSD_CONFIGURE struct extent *ioext, *memext; #ifdef PCI_CONFIGURE_VERBOSE extern int pci_conf_debug; pci_conf_debug = 1; #endif #endif pci_chipset_tag_t pc = 0; pcitag_t tag; int class, id; pci_machdep_init(); tag = pci_make_tag(pc, 0, 0, 0); class = pci_conf_read(pc, tag, PCI_CLASS_REG); id = pci_conf_read(pc, tag, PCI_ID_REG); aprint_normal("\n"); pcifound = true; /* * All we do is print out a description. Eventually, we * might want to add code that does something that's * possibly chipset-specific. */ pci_devinfo(id, class, 0, devinfo, sizeof(devinfo)); aprprint_normal_dev(self, "%s (rev. 0x%02x)\n", devinfo, PCI_REVISION(class)); pci_machdep_init(); /* Redundant... */ ibm4xx_setup_pci(); #ifdef PCI_CONFIGURE_VERBOSE ibm4xx_show_pci_map(); #endif if (bus_space_init(&pchb_io_tag, "pchbio", NULL, 0)) panic("pchbattach: can't init IO tag"); if (bus_space_init(&pchb_mem_tag, "pchbmem", NULL, 0)) panic("pchbattach: can't init MEM tag"); #ifdef PCI_NETBSD_CONFIGURE memext = extent_create("pcimem", MIN_PCI_MEMADDR_NOPREFETCH, MIN_PCI_MEMADDR_NOPREFETCH + 0x1fffffff, M_DEVBUF, NULL, 0, EX_NOWAIT); ioext = extent_create("pciio", MIN_PCI_PCI_IOADDR, MIN_PCI_PCI_IOADDR + 0xffff, M_DEVBUF, NULL, 0, EX_NOWAIT); pci_configure_bus(0, ioext, memext, NULL, 0, 32); extent_destroy(memext); extent_destroy(ioext); #endif /* PCI_NETBSD_CONFIGURE */ #ifdef PCI_CONFIGURE_VERBOSE printf("running config_found PCI\n"); #endif /* IO window located @ e8000000 and maps to 0-0xffff */ pba.pba_iot = &pchb_io_tag; /* PCI memory window is directly mapped */ pba.pba_memt = &pchb_mem_tag; pba.pba_dmat = paa->plb_dmat; pba.pba_dmat64 = NULL; pba.pba_bus = 0; pba.pba_bridgetag = NULL; pba.pba_flags = PCI_FLAGS_MEM_OKAY | PCI_FLAGS_IO_OKAY; config_found_ia(self, "pcibus", &pba, pchbprint); }
static void ofbattach(device_t parent, device_t self, void *aux) { struct ofb_softc *sc = device_private(self); struct pci_attach_args *pa = aux; struct wsemuldisplaydev_attach_args a; struct rasops_info *ri = &rascons_console_screen.scr_ri; long defattr; int console, node, sub; char devinfo[256]; sc->sc_dev = self; pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); printf(": %s\n", devinfo); if (console_node == 0) return; node = pcidev_to_ofdev(pa->pa_pc, pa->pa_tag); console = (node == console_node); if (!console) { /* check if any of the childs matches */ sub = OF_child(node); while ((sub != 0) && (sub != console_node)) { sub = OF_peer(sub); } if (sub == console_node) { console = true; } } sc->sc_memt = pa->pa_memt; sc->sc_iot = pa->pa_iot; sc->sc_pc = pa->pa_pc; sc->sc_pcitag = pa->pa_tag; sc->sc_mode = WSDISPLAYIO_MODE_EMUL; if (!console) return; vcons_init(&sc->vd, sc, &rascons_stdscreen, &ofb_accessops); sc->vd.init_screen = ofb_init_screen; sc->sc_node = console_node; sc->sc_ih = console_instance; vcons_init_screen(&sc->vd, &rascons_console_screen, 1, &defattr); rascons_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; printf("%s: %d x %d, %dbpp\n", device_xname(self), ri->ri_width, ri->ri_height, ri->ri_depth); sc->sc_fbaddr = 0; if (OF_getprop(sc->sc_node, "address", &sc->sc_fbaddr, 4) != 4) OF_interpret("frame-buffer-adr", 0, 1, &sc->sc_fbaddr); if (sc->sc_fbaddr == 0) { printf("%s: Unable to find the framebuffer address.\n", device_xname(sc->sc_dev)); return; } sc->sc_fbsize = round_page(ri->ri_stride * ri->ri_height); /* XXX */ if (OF_getprop(sc->sc_node, "assigned-addresses", sc->sc_addrs, sizeof(sc->sc_addrs)) == -1) { sc->sc_node = OF_parent(sc->sc_node); OF_getprop(sc->sc_node, "assigned-addresses", sc->sc_addrs, sizeof(sc->sc_addrs)); } ofb_init_cmap(sc); a.console = console; a.scrdata = &ofb_screenlist; a.accessops = &ofb_accessops; a.accesscookie = &sc->vd; config_found(self, &a, wsemuldisplaydevprint); config_found_ia(self, "drm", aux, ofb_drm_print); }
static void obio_attach(device_t parent, device_t self, void *aux) { struct obio_softc *sc = device_private(self); struct mainbus_attach_args *mb = (struct mainbus_attach_args *)aux; #if NPCI > 0 struct pcibus_attach_args pba; #endif sc->sc_dev = self; sc->sc_iot = &gemini_bs_tag; aprint_normal(": On-Board IO\n"); #if (GEMINI_BUSBASE != 0) sc->sc_dmarange.dr_sysbase = 0; sc->sc_dmarange.dr_busbase = (GEMINI_BUSBASE * 1024 * 1024); sc->sc_dmarange.dr_len = MEMSIZE * 1024 * 1024; gemini_bus_dma_tag._ranges = &sc->sc_dmarange; gemini_bus_dma_tag._nranges = 1; #endif sc->sc_ioh = 0; sc->sc_dmat = &gemini_bus_dma_tag; sc->sc_base = mb->mb_iobase; sc->sc_size = mb->mb_iosize; /* * Attach critical devices first. */ obio_attach_critical(sc); #if NPCI > 0 /* * map PCI controller registers */ if (bus_space_map(sc->sc_iot, GEMINI_PCICFG_BASE, GEMINI_PCI_CFG_DATA+4, 0, &sc->sc_pcicfg_ioh)) { aprint_error("cannot map PCI controller at %#x\n", GEMINI_PCICFG_BASE); return; } /* * initialize the PCI chipset tag */ gemini_pci_init(&sc->sc_pci_chipset, sc); #endif /* NPCI */ /* * attach the rest of our devices */ config_search_ia(obio_search, self, "obio", NULL); #if NPCI > 0 /* * attach the PCI bus */ pba.pba_memt = sc->sc_iot; pba.pba_iot = sc->sc_iot; pba.pba_dmat = sc->sc_dmat; pba.pba_dmat64 = NULL; pba.pba_pc = &sc->sc_pci_chipset; pba.pba_bus = 0; pba.pba_bridgetag = NULL; pba.pba_intrswiz = 0; pba.pba_intrtag = 0; pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY | PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY; (void) config_found_ia(sc->sc_dev, "pcibus", &pba, pcibusprint); #endif /* NPCI */ }
static void coram_attach(device_t parent, device_t self, void *aux) { struct coram_softc *sc = device_private(self); const struct pci_attach_args *pa = aux; pci_intr_handle_t ih; pcireg_t reg; const char *intrstr; struct coram_iic_softc *cic; uint32_t value; int i; #ifdef CORAM_ATTACH_I2C struct i2cbus_attach_args iba; #endif sc->sc_dev = self; pci_aprint_devinfo(pa, NULL); reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG); sc->sc_board = coram_board_lookup(PCI_VENDOR(reg), PCI_PRODUCT(reg)); KASSERT(sc->sc_board != NULL); if (pci_mapreg_map(pa, CX23885_MMBASE, PCI_MAPREG_TYPE_MEM, 0, &sc->sc_memt, &sc->sc_memh, NULL, &sc->sc_mems)) { aprint_error_dev(self, "couldn't map memory space\n"); return; } sc->sc_dmat = pa->pa_dmat; sc->sc_pc = pa->pa_pc; if (pci_intr_map(pa, &ih)) { aprint_error_dev(self, "couldn't map interrupt\n"); return; } intrstr = pci_intr_string(pa->pa_pc, ih); sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_VM, coram_intr, self); if (sc->sc_ih == NULL) { aprint_error_dev(self, "couldn't establish interrupt"); if (intrstr != NULL) aprint_error(" at %s", intrstr); aprint_error("\n"); return; } aprint_normal_dev(self, "interrupting at %s\n", intrstr); /* set master */ reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); reg |= PCI_COMMAND_MASTER_ENABLE; pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, reg); /* I2C */ for(i = 0; i < I2C_NUM; i++) { cic = &sc->sc_iic[i]; cic->cic_sc = sc; if (bus_space_subregion(sc->sc_memt, sc->sc_memh, I2C_BASE + (I2C_SIZE * i), I2C_SIZE, &cic->cic_regh)) panic("failed to subregion i2c"); mutex_init(&cic->cic_busmutex, MUTEX_DRIVER, IPL_NONE); cic->cic_i2c.ic_cookie = cic; cic->cic_i2c.ic_acquire_bus = coram_iic_acquire_bus; cic->cic_i2c.ic_release_bus = coram_iic_release_bus; cic->cic_i2c.ic_exec = coram_iic_exec; #ifdef CORAM_ATTACH_I2C /* attach iic(4) */ memset(&iba, 0, sizeof(iba)); iba.iba_tag = &cic->cic_i2c; iba.iba_type = I2C_TYPE_SMBUS; cic->cic_i2cdev = config_found_ia(self, "i2cbus", &iba, iicbus_print); #endif } /* HVR1250 GPIO */ value = bus_space_read_4(sc->sc_memt, sc->sc_memh, 0x110010); #if 1 value &= ~0x00010001; bus_space_write_4(sc->sc_memt, sc->sc_memh, 0x110010, value); delay(5000); #endif value |= 0x00010001; bus_space_write_4(sc->sc_memt, sc->sc_memh, 0x110010, value); #if 0 int i; uint8_t foo[256]; uint8_t bar; bar = 0; // seeprom_bootstrap_read(&sc->sc_i2c, 0x50, 0, 256, foo, 256); iic_acquire_bus(&sc->sc_i2c, I2C_F_POLL); iic_exec(&sc->sc_i2c, I2C_OP_READ_WITH_STOP, 0x50, &bar, 1, foo, 256, I2C_F_POLL); iic_release_bus(&sc->sc_i2c, I2C_F_POLL); printf("\n"); for ( i = 0; i < 256; i++) { if ( (i % 8) == 0 ) printf("%02x: ", i); printf("%02x", foo[i]); if ( (i % 8) == 7 ) printf("\n"); else printf(" "); } printf("\n"); #endif sc->sc_demod = cx24227_open(sc->sc_dev, &sc->sc_iic[0].cic_i2c, 0x19); if (sc->sc_demod == NULL) aprint_error_dev(self, "couldn't open cx24227\n"); sc->sc_tuner = mt2131_open(sc->sc_dev, &sc->sc_iic[0].cic_i2c, 0x61); if (sc->sc_tuner == NULL) aprint_error_dev(self, "couldn't open mt2131\n"); coram_mpeg_attach(sc); if (!pmf_device_register(self, NULL, coram_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); return; }
/* * Attach the mainbus. */ void mainbus_attach(device_t parent, device_t self, void *aux) { union mainbus_attach_args mba; #if defined(DOM0OPS) && defined(XEN3) int numcpus = 0; #ifdef MPBIOS int mpbios_present = 0; #endif #if NACPI > 0 || defined(MPBIOS) int numioapics = 0; #endif #endif /* defined(DOM0OPS) && defined(XEN3) */ aprint_naive("\n"); aprint_normal("\n"); #ifndef XEN3 memset(&mba.mba_caa, 0, sizeof(mba.mba_caa)); mba.mba_caa.cpu_number = 0; mba.mba_caa.cpu_role = CPU_ROLE_SP; mba.mba_caa.cpu_func = 0; config_found_ia(self, "cpubus", &mba.mba_caa, mainbus_print); #else /* XEN3 */ #ifdef DOM0OPS if (xendomain_is_dom0()) { #ifdef MPBIOS mpbios_present = mpbios_probe(self); #endif #if NPCI > 0 /* ACPI needs to be able to access PCI configuration space. */ pci_mode = pci_mode_detect(); #ifdef PCI_BUS_FIXUP pci_maxbus = pci_bus_fixup(NULL, 0); aprint_debug_dev(self, "PCI bus max, after pci_bus_fixup: %i\n", pci_maxbus); #ifdef PCI_ADDR_FIXUP pciaddr.extent_port = NULL; pciaddr.extent_mem = NULL; pci_addr_fixup(NULL, pci_maxbus); #endif /* PCI_ADDR_FIXUP */ #endif /* PCI_BUS_FIXUP */ #if NACPI > 0 acpi_present = acpi_probe(); if (acpi_present) mpacpi_active = mpacpi_scan_apics(self, &numcpus, &numioapics); if (!mpacpi_active) #endif { #ifdef MPBIOS if (mpbios_present) mpbios_scan(self, &numcpus, &numioapics); else #endif if (numcpus == 0) { memset(&mba.mba_caa, 0, sizeof(mba.mba_caa)); mba.mba_caa.cpu_number = 0; mba.mba_caa.cpu_role = CPU_ROLE_SP; mba.mba_caa.cpu_func = 0; config_found_ia(self, "cpubus", &mba.mba_caa, mainbus_print); } } #if NIOAPIC > 0 ioapic_enable(); #endif #endif /* NPCI */ } #endif /* DOM0OPS */ #endif /* XEN3 */ #if NIPMI > 0 memset(&mba.mba_ipmi, 0, sizeof(mba.mba_ipmi)); mba.mba_ipmi.iaa_iot = X86_BUS_SPACE_IO; mba.mba_ipmi.iaa_memt = X86_BUS_SPACE_MEM; if (ipmi_probe(&mba.mba_ipmi)) config_found_ia(self, "ipmibus", &mba.mba_ipmi, 0); #endif #if NHYPERVISOR > 0 mba.mba_haa.haa_busname = "hypervisor"; config_found_ia(self, "hypervisorbus", &mba.mba_haa, mainbus_print); #endif }
static void bcmgpio_attach(device_t parent, device_t self, void *aux) { struct bcmgpio_softc * const sc = device_private(self); #if NGPIO > 0 struct amba_attach_args *aaa = aux; struct gpiobus_attach_args gba; int pin, minpin, maxpin; u_int func; int error; #endif sc->sc_dev = self; #if NGPIO > 0 if (device_unit(sc->sc_dev) > 1) { aprint_naive(" NO GPIO\n"); aprint_normal(": NO GPIO\n"); return; } else if (device_unit(sc->sc_dev) == 1) { maxpin = 53; minpin = 32; } else { maxpin = 31; minpin = 0; } aprint_naive("\n"); aprint_normal(": GPIO [%d...%d]\n", minpin, maxpin); sc->sc_iot = aaa->aaa_iot; error = bus_space_map(sc->sc_iot, aaa->aaa_addr, aaa->aaa_size, 0, &sc->sc_ioh); if (error) { aprint_error_dev(self, "can't map registers for %s: %d\n", aaa->aaa_name, error); return; } for (pin = minpin; pin <= maxpin; pin++) { int epin = pin - minpin; sc->sc_gpio_pins[epin].pin_num = epin; /* * find out pins still available for GPIO */ func = bcm2835gpio_function_read(pin); if (func == BCM2835_GPIO_IN || func == BCM2835_GPIO_OUT) { sc->sc_gpio_pins[epin].pin_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_PUSHPULL | GPIO_PIN_TRISTATE | GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN; /* read initial state */ sc->sc_gpio_pins[epin].pin_state = bcm2835gpio_gpio_pin_read(sc, epin); DPRINTF(1, ("%s: attach pin %d\n", device_xname(sc->sc_dev), pin)); } else { sc->sc_gpio_pins[epin].pin_caps = 0; sc->sc_gpio_pins[epin].pin_state = 0; DPRINTF(1, ("%s: skip pin %d - func = 0x%x\n", device_xname(sc->sc_dev), pin, func)); } } /* create controller tag */ sc->sc_gpio_gc.gp_cookie = sc; sc->sc_gpio_gc.gp_pin_read = bcm2835gpio_gpio_pin_read; sc->sc_gpio_gc.gp_pin_write = bcm2835gpio_gpio_pin_write; sc->sc_gpio_gc.gp_pin_ctl = bcm2835gpio_gpio_pin_ctl; gba.gba_gc = &sc->sc_gpio_gc; gba.gba_pins = sc->sc_gpio_pins; gba.gba_npins = maxpin - minpin + 1; config_found_ia(self, "gpiobus", &gba, gpiobus_print); #else aprint_normal_dev(sc->sc_dev, "no GPIO configured in kernel"); #endif }
/* * Attach the mainbus. */ void mainbus_attach(device_t parent, device_t self, void *aux) { union mainbus_attach_args mba; struct confargs ca; #if NPCI > 0 struct genppc_pci_chipset_businfo *pbi; #ifdef PCI_NETBSD_CONFIGURE struct extent *ioext, *memext; #endif #endif mainbus_found = 1; aprint_normal("\n"); #if defined(RESIDUAL_DATA_DUMP) print_residual_device_info(); #endif /* * Always find the CPU */ ca.ca_name = "cpu"; ca.ca_node = 0; config_found_ia(self, "mainbus", &ca, mainbus_print); ca.ca_name = "cpu"; ca.ca_node = 1; config_found_ia(self, "mainbus", &ca, mainbus_print); /* * XXX Note also that the presence of a PCI bus should * XXX _always_ be checked, and if present the bus should be * XXX 'found'. However, because of the structure of the code, * XXX that's not currently possible. */ #if NPCI > 0 genppc_pct = malloc(sizeof(struct genppc_pci_chipset), M_DEVBUF, M_NOWAIT); KASSERT(genppc_pct != NULL); bebox_pci_get_chipset_tag(genppc_pct); pbi = malloc(sizeof(struct genppc_pci_chipset_businfo), M_DEVBUF, M_NOWAIT); KASSERT(pbi != NULL); pbi->pbi_properties = prop_dictionary_create(); KASSERT(pbi->pbi_properties != NULL); SIMPLEQ_INIT(&genppc_pct->pc_pbi); SIMPLEQ_INSERT_TAIL(&genppc_pct->pc_pbi, pbi, next); #ifdef PCI_NETBSD_CONFIGURE ioext = extent_create("pciio", 0x00008000, 0x0000ffff, NULL, 0, EX_NOWAIT); memext = extent_create("pcimem", 0x00000000, 0x0fffffff, NULL, 0, EX_NOWAIT); pci_configure_bus(genppc_pct, ioext, memext, NULL, 0, CACHELINESIZE); extent_destroy(ioext); extent_destroy(memext); #endif /* PCI_NETBSD_CONFIGURE */ #endif /* NPCI */ #if NPCI > 0 memset(&mba, 0, sizeof(mba)); mba.mba_pba.pba_iot = &prep_io_space_tag; mba.mba_pba.pba_memt = &prep_mem_space_tag; mba.mba_pba.pba_dmat = &pci_bus_dma_tag; mba.mba_pba.pba_dmat64 = NULL; mba.mba_pba.pba_pc = genppc_pct; mba.mba_pba.pba_bus = 0; mba.mba_pba.pba_bridgetag = NULL; mba.mba_pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY; config_found_ia(self, "pcibus", &mba.mba_pba, pcibusprint); #endif /* NPCI */ #ifdef RESIDUAL_DATA_DUMP SIMPLEQ_FOREACH(pbi, &genppc_pct->pc_pbi, next) printf("%s\n", prop_dictionary_externalize(pbi->pbi_properties)); #endif }
static void uninorth_attach(device_t parent, device_t self, void *aux) { struct uninorth_softc *sc = device_private(self); pci_chipset_tag_t pc = &sc->sc_pc; struct confargs *ca = aux; struct pcibus_attach_args pba; int len, child, node = ca->ca_node; uint32_t reg[2], busrange[2]; char compat[32]; int ver; struct ranges { uint32_t pci_hi, pci_mid, pci_lo; uint32_t host; uint32_t size_hi, size_lo; } ranges[6], *rp = ranges; printf("\n"); sc->sc_dev = self; memset(compat, 0, sizeof(compat)); OF_getprop(ca->ca_node, "compatible", compat, sizeof(compat)); if (strcmp(compat, "u3-agp") == 0) ver = 3; else if (strcmp(compat, "u4-pcie") == 0) ver = 4; else ver = 0; /* UniNorth address */ if (OF_getprop(node, "reg", reg, sizeof(reg)) < 8) return; /* PCI bus number */ if (OF_getprop(node, "bus-range", busrange, sizeof(busrange)) != 8) return; memset(&sc->sc_iot, 0, sizeof(sc->sc_iot)); /* find i/o tag */ len = OF_getprop(node, "ranges", ranges, sizeof(ranges)); if (len == -1) return; while (len >= sizeof(ranges[0])) { if ((rp->pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) == OFW_PCI_PHYS_HI_SPACE_IO) { sc->sc_iot.pbs_base = rp->host; sc->sc_iot.pbs_limit = rp->host + rp->size_lo; break; } len -= sizeof(ranges[0]); rp++; } /* XXX enable gmac ethernet */ for (child = OF_child(node); child; child = OF_peer(child)) { volatile int *gmac_gbclock_en = (void *)0xf8000020; memset(compat, 0, sizeof(compat)); OF_getprop(child, "compatible", compat, sizeof(compat)); if (strcmp(compat, "gmac") == 0) *gmac_gbclock_en |= 0x02; } sc->sc_iot.pbs_flags = _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_IO_TYPE; sc->sc_iot.pbs_offset = 0; if (ofwoea_map_space(RANGE_TYPE_PCI, RANGE_IO, node, &sc->sc_iot, "uninorth io-space") != 0) panic("Can't init uninorth io tag"); memset(&sc->sc_memt, 0, sizeof(sc->sc_memt)); sc->sc_memt.pbs_flags = _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE; sc->sc_memt.pbs_base = 0x00000000; if (ofwoea_map_space(RANGE_TYPE_PCI, RANGE_MEM, node, &sc->sc_memt, "uninorth mem-space") != 0) panic("Can't init uninorth mem tag"); macppc_pci_get_chipset_tag(pc); pc->pc_node = node; pc->pc_bus = busrange[0]; pc->pc_iot = &sc->sc_iot; pc->pc_memt = &sc->sc_memt; if (ver < 3) { pc->pc_addr = mapiodev(reg[0] + 0x800000, 4, false); pc->pc_data = mapiodev(reg[0] + 0xc00000, 8, false); pc->pc_conf_read = uninorth_conf_read; pc->pc_conf_write = uninorth_conf_write; } else { pc->pc_addr = mapiodev(reg[1] + 0x800000, 4, false); pc->pc_data = mapiodev(reg[1] + 0xc00000, 8, false); pc->pc_conf_read = uninorth_conf_read_v3; pc->pc_conf_write = uninorth_conf_write_v3; } memset(&pba, 0, sizeof(pba)); pba.pba_memt = pc->pc_memt; pba.pba_iot = pc->pc_iot; pba.pba_dmat = &pci_bus_dma_tag; pba.pba_dmat64 = NULL; pba.pba_bus = pc->pc_bus; pba.pba_bridgetag = NULL; pba.pba_pc = pc; pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY; config_found_ia(self, "pcibus", &pba, pcibusprint); }
/* * atabus_configthread: finish attach of atabus's childrens, in a separate * kernel thread. */ static void atabusconfig_thread(void *arg) { struct atabus_softc *atabus_sc = arg; struct ata_channel *chp = atabus_sc->sc_chan; struct atac_softc *atac = chp->ch_atac; struct atabus_initq *atabus_initq = NULL; int i, s; /* XXX seems wrong */ mutex_enter(&atabus_qlock); atabus_initq = TAILQ_FIRST(&atabus_initq_head); KASSERT(atabus_initq->atabus_sc == atabus_sc); mutex_exit(&atabus_qlock); /* * First look for a port multiplier */ if (chp->ch_ndrives == PMP_MAX_DRIVES && chp->ch_drive[PMP_PORT_CTL].drive_type == ATA_DRIVET_PM) { #if NSATA_PMP > 0 satapmp_attach(chp); #else aprint_error_dev(atabus_sc->sc_dev, "SATA port multiplier not supported\n"); /* no problems going on, all drives are ATA_DRIVET_NONE */ #endif } /* * Attach an ATAPI bus, if needed. */ KASSERT(chp->ch_ndrives == 0 || chp->ch_drive != NULL); for (i = 0; i < chp->ch_ndrives && chp->atapibus == NULL; i++) { if (chp->ch_drive[i].drive_type == ATA_DRIVET_ATAPI) { #if NATAPIBUS > 0 (*atac->atac_atapibus_attach)(atabus_sc); #else /* * Fake the autoconfig "not configured" message */ aprint_normal("atapibus at %s not configured\n", device_xname(atac->atac_dev)); chp->atapibus = NULL; s = splbio(); for (i = 0; i < chp->ch_ndrives; i++) { if (chp->ch_drive[i].drive_type == ATA_DRIVET_ATAPI) chp->ch_drive[i].drive_type = ATA_DRIVET_NONE; } splx(s); #endif break; } } for (i = 0; i < chp->ch_ndrives; i++) { struct ata_device adev; if (chp->ch_drive[i].drive_type != ATA_DRIVET_ATA && chp->ch_drive[i].drive_type != ATA_DRIVET_OLD) { continue; } if (chp->ch_drive[i].drv_softc != NULL) continue; memset(&adev, 0, sizeof(struct ata_device)); adev.adev_bustype = atac->atac_bustype_ata; adev.adev_channel = chp->ch_channel; adev.adev_openings = 1; adev.adev_drv_data = &chp->ch_drive[i]; chp->ch_drive[i].drv_softc = config_found_ia(atabus_sc->sc_dev, "ata_hl", &adev, ataprint); if (chp->ch_drive[i].drv_softc != NULL) { ata_probe_caps(&chp->ch_drive[i]); } else { s = splbio(); chp->ch_drive[i].drive_type = ATA_DRIVET_NONE; splx(s); } } /* now that we know the drives, the controller can set its modes */ if (atac->atac_set_modes) { (*atac->atac_set_modes)(chp); ata_print_modes(chp); } #if NATARAID > 0 if (atac->atac_cap & ATAC_CAP_RAID) { for (i = 0; i < chp->ch_ndrives; i++) { if (chp->ch_drive[i].drive_type == ATA_DRIVET_ATA) { ata_raid_check_component( chp->ch_drive[i].drv_softc); } } } #endif /* NATARAID > 0 */ /* * reset drive_flags for unattached devices, reset state for attached * ones */ s = splbio(); for (i = 0; i < chp->ch_ndrives; i++) { if (chp->ch_drive[i].drive_type == ATA_DRIVET_PM) continue; if (chp->ch_drive[i].drv_softc == NULL) { chp->ch_drive[i].drive_flags = 0; chp->ch_drive[i].drive_type = ATA_DRIVET_NONE; } else chp->ch_drive[i].state = 0; } splx(s); mutex_enter(&atabus_qlock); TAILQ_REMOVE(&atabus_initq_head, atabus_initq, atabus_initq); cv_broadcast(&atabus_qcv); mutex_exit(&atabus_qlock); free(atabus_initq, M_DEVBUF); ata_delref(chp); config_pending_decr(atac->atac_dev); kthread_exit(0); }
static void igma_attach(device_t parent, device_t self, void *aux) { struct igma_softc *sc = device_private(self); const struct pci_attach_args *pa = (struct pci_attach_args *)aux; struct igma_attach_args iaa; bus_space_tag_t gttmmt, gmt, regt; bus_space_handle_t gttmmh, gmh, regh; bus_addr_t gttmmb, gmb; pci_aprint_devinfo(pa, NULL); sc->sc_dev = self; /* Initialize according to chip type */ igma_product_to_chip(pa, &sc->sc_chip); if (pci_mapreg_map(pa, PCI_BAR0, PCI_MAPREG_TYPE_MEM, BUS_SPACE_MAP_LINEAR, >tmmt, >tmmh, >tmmb, NULL)) { aprint_error_dev(sc->sc_dev, "unable to map GTTMM\n"); return; } sc->sc_chip.mmiot = gttmmt; if (bus_space_subregion(gttmmt, gttmmh, 0, 2*1024*1024, &sc->sc_chip.mmioh)) { aprint_error_dev(sc->sc_dev, "unable to submap MMIO\n"); return; } sc->sc_chip.gttt = gttmmt; if (bus_space_subregion(gttmmt, gttmmh, 2*1024*1024, 2*1024*1024, &sc->sc_chip.gtth)) { aprint_error_dev(sc->sc_dev, "unable to submap GTT\n"); return; } if (pci_mapreg_map(pa, PCI_BAR2, PCI_MAPREG_TYPE_MEM, BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE, &gmt, &gmh, &gmb, NULL)) { aprint_error_dev(sc->sc_dev, "unable to map aperture\n"); return; } sc->sc_chip.gmt = gmt; sc->sc_chip.gmh = gmh; sc->sc_chip.gmb = gmb; if (pci_mapreg_map(pa, PCI_BAR4, PCI_MAPREG_TYPE_IO, 0, ®t, ®h, NULL, NULL)) { aprint_error_dev(sc->sc_dev, "unable to map IO registers\n"); return; } #if NVGA > 0 iaa.iaa_console = vga_cndetach() ? true : false; #else iaa.iaa_console = 0; #endif sc->sc_chip.vgat = regt; if (bus_space_map(regt, 0x3c0, 0x10, 0, &sc->sc_chip.vgah)) { aprint_error_dev(sc->sc_dev, "unable to map VGA registers\n"); return; } /* Check hardware for more information */ igma_adjust_chip(sc, &sc->sc_chip); aprint_normal("%s: VGA_CNTRL: 0x%x\n",device_xname(sc->sc_dev), sc->sc_chip.vga_cntrl); aprint_normal("%s: GPIO_OFFSET: 0x%x\n",device_xname(sc->sc_dev), sc->sc_chip.gpio_offset); aprint_normal("%s: BACKLIGHT_CTRL: 0x%x\n",device_xname(sc->sc_dev), sc->sc_chip.backlight_cntrl); aprint_normal("%s: BACKLIGHT_CTRL2: 0x%x\n",device_xname(sc->sc_dev), sc->sc_chip.backlight_cntrl2); #if NIGMAFB > 0 strcpy(iaa.iaa_name, "igmafb"); iaa.iaa_chip = sc->sc_chip; config_found_ia(sc->sc_dev, "igmabus", &iaa, igma_print); #endif igma_i2c_attach(sc); }
void ixp425_attach(device_t self) { struct ixp425_softc *sc = device_private(self); #if NPCI > 0 struct pcibus_attach_args pba; #endif sc->sc_dev = self; sc->sc_iot = &ixp425_bs_tag; ixp425_softc = sc; printf("\n"); /* * Mapping for GPIO Registers */ if (bus_space_map(sc->sc_iot, IXP425_GPIO_HWBASE, IXP425_GPIO_SIZE, 0, &sc->sc_gpio_ioh)) panic("%s: unable to map GPIO registers", device_xname(self)); if (bus_space_map(sc->sc_iot, IXP425_EXP_HWBASE, IXP425_EXP_SIZE, 0, &sc->sc_exp_ioh)) panic("%s: unable to map Expansion Bus registers", device_xname(self)); #if NPCI > 0 /* * Mapping for PCI CSR */ if (bus_space_map(sc->sc_iot, IXP425_PCI_HWBASE, IXP425_PCI_SIZE, 0, &sc->sc_pci_ioh)) panic("%s: unable to map PCI registers", device_xname(self)); /* * Invoke the board-specific PCI initialization code */ ixp425_md_pci_init(sc); /* * Generic initialization of the PCI chipset. */ ixp425_pci_init(sc); /* * Initialize the DMA tags. */ ixp425_pci_dma_init(sc); /* * Attach the PCI bus. */ pba.pba_pc = &sc->ia_pci_chipset; pba.pba_iot = &sc->sc_pci_iot; pba.pba_memt = &sc->sc_pci_memt; pba.pba_dmat = &sc->ia_pci_dmat; pba.pba_bus = 0; /* bus number = 0 */ pba.pba_bridgetag = NULL; pba.pba_intrswiz = 0; /* XXX */ pba.pba_intrtag = 0; pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY | PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY; (void) config_found_ia(self, "pcibus", &pba, pcibusprint); #endif }
static void cuda_attach(device_t parent, device_t dev, void *aux) { struct confargs *ca = aux; struct cuda_softc *sc = device_private(dev); struct i2cbus_attach_args iba; static struct cuda_attach_args caa; int irq = ca->ca_intr[0]; int node, i, child; char name[32]; sc->sc_dev = dev; node = of_getnode_byname(OF_parent(ca->ca_node), "extint-gpio1"); if (node) OF_getprop(node, "interrupts", &irq, 4); printf(" irq %d: ", irq); sc->sc_node = ca->ca_node; sc->sc_memt = ca->ca_tag; sc->sc_sent = 0; sc->sc_received = 0; sc->sc_waiting = 0; sc->sc_polling = 0; sc->sc_state = CUDA_NOTREADY; sc->sc_error = 0; sc->sc_i2c_read_len = 0; if (bus_space_map(sc->sc_memt, ca->ca_reg[0] + ca->ca_baseaddr, ca->ca_reg[1], 0, &sc->sc_memh) != 0) { printf("%s: unable to map registers\n", dev->dv_xname); return; } sc->sc_ih = intr_establish(irq, IST_EDGE, IPL_TTY, cuda_intr, sc); printf("\n"); for (i = 0; i < 16; i++) { sc->sc_handlers[i].handler = NULL; sc->sc_handlers[i].cookie = NULL; } cuda_init(sc); /* now attach children */ config_interrupts(dev, cuda_final); cuda_set_handler(sc, CUDA_ERROR, cuda_error_handler, sc); cuda_set_handler(sc, CUDA_PSEUDO, cuda_todr_handler, sc); child = OF_child(ca->ca_node); while (child != 0) { if (OF_getprop(child, "name", name, 32) == 0) continue; if (strncmp(name, "adb", 4) == 0) { cuda_set_handler(sc, CUDA_ADB, cuda_adb_handler, sc); sc->sc_adbops.cookie = sc; sc->sc_adbops.send = cuda_adb_send; sc->sc_adbops.poll = cuda_adb_poll; sc->sc_adbops.autopoll = cuda_autopoll; sc->sc_adbops.set_handler = cuda_adb_set_handler; config_found_ia(dev, "adb_bus", &sc->sc_adbops, nadb_print); } else if (strncmp(name, "rtc", 4) == 0) { sc->sc_todr.todr_gettime = cuda_todr_get; sc->sc_todr.todr_settime = cuda_todr_set; sc->sc_todr.cookie = sc; todr_attach(&sc->sc_todr); } child = OF_peer(child); } caa.cookie = sc; caa.set_handler = cuda_set_handler; caa.send = cuda_send; caa.poll = cuda_poll; #if notyet config_found(dev, &caa, cuda_print); #endif mutex_init(&sc->sc_buslock, MUTEX_DEFAULT, IPL_NONE); iba.iba_tag = &sc->sc_i2c; sc->sc_i2c.ic_cookie = sc; sc->sc_i2c.ic_acquire_bus = cuda_i2c_acquire_bus; sc->sc_i2c.ic_release_bus = cuda_i2c_release_bus; sc->sc_i2c.ic_send_start = NULL; sc->sc_i2c.ic_send_stop = NULL; sc->sc_i2c.ic_initiate_xfer = NULL; sc->sc_i2c.ic_read_byte = NULL; sc->sc_i2c.ic_write_byte = NULL; sc->sc_i2c.ic_exec = cuda_i2c_exec; config_found_ia(sc->sc_dev, "i2cbus", &iba, iicbus_print); if (cuda0 == NULL) cuda0 = &caa; }
static void piixpm_attach(device_t parent, device_t self, void *aux) { struct piixpm_softc *sc = device_private(self); struct pci_attach_args *pa = aux; struct i2cbus_attach_args iba; pcireg_t base, conf; pcireg_t pmmisc; pci_intr_handle_t ih; const char *intrstr = NULL; int i, numbusses = 1; sc->sc_dev = self; sc->sc_iot = pa->pa_iot; sc->sc_id = pa->pa_id; sc->sc_pc = pa->pa_pc; sc->sc_pcitag = pa->pa_tag; pci_aprint_devinfo(pa, NULL); if (!pmf_device_register(self, piixpm_suspend, piixpm_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); /* Read configuration */ conf = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_HOSTC); DPRINTF(("%s: conf 0x%x\n", device_xname(self), conf)); if ((PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL) || (PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_INTEL_82371AB_PMC)) goto nopowermanagement; /* check whether I/O access to PM regs is enabled */ pmmisc = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_PMREGMISC); if (!(pmmisc & 1)) goto nopowermanagement; /* Map I/O space */ base = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_PM_BASE); if (bus_space_map(sc->sc_pm_iot, PCI_MAPREG_IO_ADDR(base), PIIX_PM_SIZE, 0, &sc->sc_pm_ioh)) { aprint_error_dev(self, "can't map power management I/O space\n"); goto nopowermanagement; } /* * Revision 0 and 1 are PIIX4, 2 is PIIX4E, 3 is PIIX4M. * PIIX4 and PIIX4E have a bug in the timer latch, see Errata #20 * in the "Specification update" (document #297738). */ acpipmtimer_attach(self, sc->sc_pm_iot, sc->sc_pm_ioh, PIIX_PM_PMTMR, (PCI_REVISION(pa->pa_class) < 3) ? ACPIPMT_BADLATCH : 0 ); nopowermanagement: /* SB800 rev 0x40+ needs special initialization */ if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ATI && PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ATI_SB600_SMB && PCI_REVISION(pa->pa_class) >= 0x40) { if (piixpm_sb800_init(sc) == 0) { numbusses = 4; goto attach_i2c; } aprint_normal_dev(self, "SMBus disabled\n"); return; } if ((conf & PIIX_SMB_HOSTC_HSTEN) == 0) { aprint_normal_dev(self, "SMBus disabled\n"); return; } /* Map I/O space */ base = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_BASE) & 0xffff; if (bus_space_map(sc->sc_smb_iot, PCI_MAPREG_IO_ADDR(base), PIIX_SMB_SIZE, 0, &sc->sc_smb_ioh)) { aprint_error_dev(self, "can't map smbus I/O space\n"); return; } sc->sc_poll = 1; aprint_normal_dev(self, ""); if ((conf & PIIX_SMB_HOSTC_INTMASK) == PIIX_SMB_HOSTC_SMI) { /* No PCI IRQ */ aprint_normal("interrupting at SMI, "); } else if ((conf & PIIX_SMB_HOSTC_INTMASK) == PIIX_SMB_HOSTC_IRQ) { /* Install interrupt handler */ if (pci_intr_map(pa, &ih) == 0) { intrstr = pci_intr_string(pa->pa_pc, ih); sc->sc_smb_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, piixpm_intr, sc); if (sc->sc_smb_ih != NULL) { aprint_normal("interrupting at %s", intrstr); sc->sc_poll = 0; } } } if (sc->sc_poll) aprint_normal("polling"); aprint_normal("\n"); attach_i2c: /* Attach I2C bus */ mutex_init(&sc->sc_i2c_mutex, MUTEX_DEFAULT, IPL_NONE); for (i = 0; i < numbusses; i++) { sc->sc_busses[i].sda = i; sc->sc_busses[i].softc = sc; sc->sc_i2c_tags[i].ic_cookie = &sc->sc_busses[i]; sc->sc_i2c_tags[i].ic_acquire_bus = piixpm_i2c_acquire_bus; sc->sc_i2c_tags[i].ic_release_bus = piixpm_i2c_release_bus; sc->sc_i2c_tags[i].ic_exec = piixpm_i2c_exec; memset(&iba, 0, sizeof(iba)); iba.iba_type = I2C_TYPE_SMBUS; iba.iba_tag = &sc->sc_i2c_tags[i]; config_found_ia(self, "i2cbus", &iba, iicbus_print); } }
static void giopci_attach(struct device *parent, struct device *self, void *aux) { struct giopci_softc *sc = (void *)self; pci_chipset_tag_t pc = &sc->sc_pc; struct gio_attach_args *ga = aux; uint32_t pci_off, pci_len, arb; struct pcibus_attach_args pba; u_long m_start, m_end; #ifdef PCI_NETBSD_CONFIGURE extern int pci_conf_debug; pci_conf_debug = giopci_debug; #endif sc->sc_iot = ga->ga_iot; sc->sc_slot = ga->ga_slot; sc->sc_gprid = GIO_PRODUCT_PRODUCTID(ga->ga_product); if (mach_type == MACH_SGI_IP22 && mach_subtype == MACH_SGI_IP22_FULLHOUSE) arb = GIO_ARB_RT | GIO_ARB_MST | GIO_ARB_PIPE; else arb = GIO_ARB_RT | GIO_ARB_MST; if (gio_arb_config(ga->ga_slot, arb)) { printf(": failed to configure GIO bus arbiter\n"); return; } #if (NIMC > 0) imc_disable_sysad_parity(); #endif switch (sc->sc_gprid) { case PHOBOS_G100: case PHOBOS_G130: case PHOBOS_G160: pci_off = PHOBOS_PCI_OFFSET; pci_len = PHOBOS_PCI_LENGTH; m_start = MIPS_KSEG1_TO_PHYS(ga->ga_addr + PHOBOS_TULIP_START); m_end = MIPS_KSEG1_TO_PHYS(ga->ga_addr + PHOBOS_TULIP_END); break; case SETENG_GFE: /* * NB: The SetEng board does not allow the ThunderLAN's DMA * engine to properly transfer segments that span page * boundaries. See sgimips/autoconf.c where we catch a * tl(4) device attachment and create an appropriate * proplib entry to enable the workaround. */ pci_off = SETENG_PCI_OFFSET; pci_len = SETENG_PCI_LENGTH; m_start = MIPS_KSEG1_TO_PHYS(ga->ga_addr + SETENG_TLAN_START); m_end = MIPS_KSEG1_TO_PHYS(ga->ga_addr + SETENG_TLAN_END); bus_space_write_4(ga->ga_iot, ga->ga_ioh, SETENG_MAGIC_OFFSET, SETENG_MAGIC_VALUE); break; default: panic("giopci_attach: unsupported GIO product id 0x%02x", sc->sc_gprid); } if (bus_space_subregion(ga->ga_iot, ga->ga_ioh, pci_off, pci_len, &sc->sc_ioh)) { printf("%s: unable to map PCI registers\n",sc->sc_dev.dv_xname); return; } sc->sc_pci_len = pci_len; pc->pc_bus_maxdevs = giopci_bus_maxdevs; pc->pc_conf_read = giopci_conf_read; pc->pc_conf_write = giopci_conf_write; pc->pc_conf_hook = giopci_conf_hook; pc->pc_intr_map = giopci_intr_map; pc->pc_intr_string = giopci_intr_string; pc->intr_establish = giopci_intr_establish; pc->intr_disestablish = giopci_intr_disestablish; pc->iot = ga->ga_iot; pc->ioh = ga->ga_ioh; pc->cookie = sc; printf(": %s\n", gio_product_string(sc->sc_gprid)); #ifdef PCI_NETBSD_CONFIGURE pc->pc_memext = extent_create("giopcimem", m_start, m_end, M_DEVBUF, NULL, 0, EX_NOWAIT); pci_configure_bus(pc, NULL, pc->pc_memext, NULL, 0, mips_dcache_align); #endif memset(&pba, 0, sizeof(pba)); pba.pba_memt = SGIMIPS_BUS_SPACE_MEM; pba.pba_dmat = ga->ga_dmat; pba.pba_pc = pc; pba.pba_flags = PCI_FLAGS_MEM_ENABLED; /* NB: do not set PCI_FLAGS_{MRL,MRM,MWI}_OKAY -- true ?! */ config_found_ia(self, "pcibus", &pba, pcibusprint); }
void ciaattach(device_t parent, device_t self, void *aux) { struct cia_softc *sc = device_private(self); struct cia_config *ccp; struct pcibus_attach_args pba; char bits[64]; const char *name; int pass; /* note that we've attached the chipset; can't have 2 CIAs. */ ciafound = 1; sc->sc_dev = self; /* * set up the chipset's info; done once at console init time * (maybe), but we must do it here as well to take care of things * that need to use memory allocation. */ ccp = sc->sc_ccp = &cia_configuration; cia_init(ccp, 1); if (ccp->cc_flags & CCF_ISPYXIS) { name = "Pyxis"; pass = ccp->cc_rev; } else { name = "ALCOR/ALCOR2"; pass = ccp->cc_rev + 1; } aprint_normal(": DECchip 2117x Core Logic Chipset (%s), pass %d\n", name, pass); if (ccp->cc_cnfg) { snprintb(bits, sizeof(bits), CIA_CSR_CNFG_BITS, ccp->cc_cnfg); aprint_normal_dev(self, "extended capabilities: %s\n", bits); } switch (ccp->cc_flags & (CCF_PCI_USE_BWX|CCF_BUS_USE_BWX)) { case CCF_PCI_USE_BWX|CCF_BUS_USE_BWX: name = "PCI config and bus"; break; case CCF_PCI_USE_BWX: name = "PCI config"; break; case CCF_BUS_USE_BWX: name = "bus"; break; default: name = NULL; break; } if (name != NULL) aprint_normal_dev(self, "using BWX for %s access\n", name); #ifdef DEC_550 if (cputype == ST_DEC_550 && (hwrpb->rpb_variation & SV_ST_MASK) < SV_ST_MIATA_1_5) { /* * Miata 1 systems have a bug: DMA cannot cross * an 8k boundary! Make sure PCI read prefetching * is disabled on these chips. Note that secondary * PCI busses don't have this problem, because of * the way PPBs handle PCI read requests. * * In the 21174 Technical Reference Manual, this is * actually documented as "Pyxis Pass 1", but apparently * there are chips that report themselves as "Pass 1" * which do not have the bug! Miatas with the Cypress * PCI-ISA bridge (i.e. Miata 1.5 and Miata 2) do not * have the bug, so we use this check. * * NOTE: This bug is actually worked around in cia_dma.c, * when direct-mapped DMA maps are created. * * XXX WE NEED TO THINK ABOUT HOW TO HANDLE THIS FOR * XXX SGMAP DMA MAPPINGS! */ uint32_t ctrl; /* XXX no bets... */ aprint_error_dev(self, "WARNING: Pyxis pass 1 DMA bug; no bets...\n"); ccp->cc_flags |= CCF_PYXISBUG; alpha_mb(); ctrl = REGVAL(CIA_CSR_CTRL); ctrl &= ~(CTRL_RD_TYPE|CTRL_RL_TYPE|CTRL_RM_TYPE); REGVAL(CIA_CSR_CTRL) = ctrl; alpha_mb(); } #endif /* DEC_550 */ cia_dma_init(ccp); switch (cputype) { #ifdef DEC_KN20AA case ST_DEC_KN20AA: pci_kn20aa_pickintr(ccp); break; #endif #ifdef DEC_EB164 case ST_EB164: pci_eb164_pickintr(ccp); break; #endif #ifdef DEC_550 case ST_DEC_550: pci_550_pickintr(ccp); break; #endif #ifdef DEC_1000A case ST_DEC_1000A: pci_1000a_pickintr(ccp, &ccp->cc_iot, &ccp->cc_memt, &ccp->cc_pc); break; #endif #ifdef DEC_1000 case ST_DEC_1000: pci_1000_pickintr(ccp, &ccp->cc_iot, &ccp->cc_memt, &ccp->cc_pc); break; #endif default: panic("ciaattach: shouldn't be here, really..."); } pba.pba_iot = &ccp->cc_iot; pba.pba_memt = &ccp->cc_memt; pba.pba_dmat = alphabus_dma_get_tag(&ccp->cc_dmat_direct, ALPHA_BUS_PCI); pba.pba_dmat64 = NULL; pba.pba_pc = &ccp->cc_pc; pba.pba_bus = 0; pba.pba_bridgetag = NULL; pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY; if ((ccp->cc_flags & CCF_PYXISBUG) == 0) pba.pba_flags |= PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY; config_found_ia(self, "pcibus", &pba, pcibusprint); }
static void ofwpci_attach(device_t parent, device_t self, void *aux) { struct ofwpci_softc *sc = device_private(self); pci_chipset_tag_t pc = &sc->sc_pc; struct confargs *ca = aux; struct pcibus_attach_args pba; struct genppc_pci_chipset_businfo *pbi; int node = ca->ca_node; int i, isprim = 0; uint32_t busrange[2]; char buf[64]; #ifdef PCI_NETBSD_CONFIGURE struct extent *ioext, *memext; #endif aprint_normal("\n"); sc->sc_dev = self; /* PCI bus number */ if (OF_getprop(node, "bus-range", busrange, sizeof(busrange)) != 8) return; /* bus space map the io ranges */ sc->sc_iot.pbs_flags = _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_IO_TYPE; sc->sc_iot.pbs_base = 0x00000000; if (ofwoea_map_space(RANGE_TYPE_PCI, RANGE_IO, node, &sc->sc_iot, "ofwpci io-space") != 0) panic("Can't init ofwpci io tag"); sc->sc_memt.pbs_flags = _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE; sc->sc_memt.pbs_base = 0x00000000; if (ofwoea_map_space(RANGE_TYPE_PCI, RANGE_MEM, node, &sc->sc_memt, "ofwpci mem-space") != 0) panic("Can't init ofwpci mem tag"); aprint_debug("io base=0x%"PRIxPTR" offset=0x%"PRIxPTR" limit=0x%"PRIxPTR"\n", sc->sc_iot.pbs_base, sc->sc_iot.pbs_offset, sc->sc_iot.pbs_limit); aprint_debug("mem base=0x%"PRIxPTR" offset=0x%"PRIxPTR" limit=0x%"PRIxPTR"\n", sc->sc_memt.pbs_base, sc->sc_memt.pbs_offset, sc->sc_memt.pbs_limit); /* are we the primary pci bus? */ if (of_find_firstchild_byname(OF_finddevice("/"), "pci") == node) { int isa_node; isprim++; /* yes we are, now do we have an ISA child? */ isa_node = of_find_firstchild_byname(node, "isa"); if (isa_node != -1) { /* isa == pci */ genppc_isa_io_space_tag = sc->sc_iot; genppc_isa_mem_space_tag = sc->sc_memt; map_isa_ioregs(); init_ofppc_interrupt(); ofppc_init_comcons(isa_node); } } ofwpci_get_chipset_tag(pc); pc->pc_node = node; i = OF_package_to_path(node, buf, sizeof(buf)-5); if (i <= 0) panic("Can't determine path for pci node %d", node); buf[i] = '\0'; pc->pc_ihandle = OF_open(buf); if (pc->pc_ihandle < 0) panic("Can't open device %s", buf); pc->pc_bus = busrange[0]; pc->pc_iot = &sc->sc_iot; pc->pc_memt = &sc->sc_memt; pbi = malloc(sizeof(struct genppc_pci_chipset_businfo), M_DEVBUF, M_NOWAIT); KASSERT(pbi != NULL); pbi->pbi_properties = prop_dictionary_create(); KASSERT(pbi->pbi_properties != NULL); SIMPLEQ_INIT(&pc->pc_pbi); SIMPLEQ_INSERT_TAIL(&pc->pc_pbi, pbi, next); genofw_setup_pciintr_map((void *)pc, pbi, pc->pc_node); #ifdef PCI_NETBSD_CONFIGURE ioext = extent_create("pciio", modeldata.pciiodata[device_unit(self)].start, modeldata.pciiodata[device_unit(self)].limit, NULL, 0, EX_NOWAIT); memext = extent_create("pcimem", sc->sc_memt.pbs_base, sc->sc_memt.pbs_limit-1, NULL, 0, EX_NOWAIT); if (pci_configure_bus(pc, ioext, memext, NULL, 0, CACHELINESIZE)) aprint_error("pci_configure_bus() failed\n"); extent_destroy(ioext); extent_destroy(memext); #endif /* PCI_NETBSD_CONFIGURE */ memset(&pba, 0, sizeof(pba)); pba.pba_memt = pc->pc_memt; pba.pba_iot = pc->pc_iot; pba.pba_dmat = &pci_bus_dma_tag; pba.pba_dmat64 = NULL; pba.pba_bus = pc->pc_bus; pba.pba_bridgetag = NULL; pba.pba_pc = pc; pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY; config_found_ia(self, "pcibus", &pba, pcibusprint); }
void fdcfinishattach(device_t self) { struct fdc_softc *fdc = device_private(self); bus_space_tag_t iot = fdc->sc_iot; bus_space_handle_t ioh = fdc->sc_ioh; struct fdc_attach_args fa; /* * Reset the controller to get it into a known state. Not all * probes necessarily need do this to discover the controller up * front, so don't assume anything. */ bus_space_write_1(iot, ioh, fdout, 0); delay(100); bus_space_write_1(iot, ioh, fdout, FDO_FRST); /* see if it can handle a command */ if (out_fdc(iot, ioh, NE7CMD_SPECIFY) < 0) { aprint_normal_dev(fdc->sc_dev, "can't reset controller\n"); return; } out_fdc(iot, ioh, 0xdf); out_fdc(iot, ioh, 2); #if defined(i386) || defined(x86_64) /* * The NVRAM info only tells us about the first two disks on the * `primary' floppy controller. */ /* XXX device_unit() abuse */ if (device_unit(fdc->sc_dev) == 0) { int type = mc146818_read(NULL, NVRAM_DISKETTE); /* XXX softc */ fdc->sc_known = 1; fdc->sc_knownfds[0] = fd_nvtotype(device_xname(fdc->sc_dev), type, 0); if (fdc->sc_knownfds[0] != NULL) fdc->sc_present |= 1; fdc->sc_knownfds[1] = fd_nvtotype(device_xname(fdc->sc_dev), type, 1); if (fdc->sc_knownfds[1] != NULL) fdc->sc_present |= 2; } #endif /* i386 || x86_64 */ /* physical limit: four drives per controller. */ fdc->sc_state = PROBING; for (fa.fa_drive = 0; fa.fa_drive < 4; fa.fa_drive++) { if (fdc->sc_known) { if (fdc->sc_present & (1 << fa.fa_drive)) { fa.fa_deftype = fdc->sc_knownfds[fa.fa_drive]; config_found(fdc->sc_dev, (void *)&fa, fdprint); } } else { #if defined(atari) /* * Atari has a different ordening, defaults to 1.44 */ fa.fa_deftype = &fd_types[2]; #else /* * Default to 1.44MB on Alpha and BeBox. How do we tell * on these platforms? */ fa.fa_deftype = &fd_types[0]; #endif (void)config_found_ia(fdc->sc_dev, "fdc", (void *)&fa, fdprint); } } fdc->sc_state = DEVIDLE; }
static void rmixl_pcix_attach(device_t parent, device_t self, void *aux) { rmixl_pcix_softc_t *sc = device_private(self); struct obio_attach_args *obio = aux; struct rmixl_config *rcp = &rmixl_configuration; struct pcibus_attach_args pba; uint32_t bar; rmixl_pcix_found = 1; sc->sc_dev = self; sc->sc_29bit_dmat = obio->obio_29bit_dmat; sc->sc_32bit_dmat = obio->obio_32bit_dmat; sc->sc_64bit_dmat = obio->obio_64bit_dmat; sc->sc_tmsk = obio->obio_tmsk; aprint_normal(": RMI XLR PCI-X Interface\n"); mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_HIGH); rmixl_pcix_intcfg(sc); rmixl_pcix_errata(sc); /* * check XLR Control Register */ DPRINTF(("%s: XLR_CONTROL=%#x\n", __func__, RMIXL_PCIXREG_READ(RMIXL_PCIX_ECFG_XLR_CONTROL))); /* * HBAR[0] if a 32 bit BAR, or * HBAR[0,1] if a 64 bit BAR pair * must cover all RAM */ extern u_quad_t mem_cluster_maxaddr; uint64_t hbar_addr; uint64_t hbar_size; uint32_t hbar_size_lo, hbar_size_hi; uint32_t hbar_addr_lo, hbar_addr_hi; hbar_addr_lo = RMIXL_PCIXREG_READ(RMIXL_PCIX_ECFG_HOST_BAR0_ADDR); hbar_addr_hi = RMIXL_PCIXREG_READ(RMIXL_PCIX_ECFG_HOST_BAR1_ADDR); hbar_size_lo = RMIXL_PCIXREG_READ(RMIXL_PCIX_ECFG_HOST_BAR0_SIZE); hbar_size_hi = RMIXL_PCIXREG_READ(RMIXL_PCIX_ECFG_HOST_BAR1_SIZE); hbar_addr = (u_quad_t)(hbar_addr_lo & PCI_MAPREG_MEM_ADDR_MASK); hbar_size = hbar_size_lo; if ((hbar_size_lo & PCI_MAPREG_MEM_TYPE_64BIT) != 0) { hbar_addr |= (uint64_t)hbar_addr_hi << 32; hbar_size |= (uint64_t)hbar_size_hi << 32; } if ((hbar_addr != 0) || (hbar_size < mem_cluster_maxaddr)) { int error; aprint_error_dev(self, "HostBAR0 addr %#x, size %#x\n", hbar_addr_lo, hbar_size_lo); if ((hbar_size_lo & PCI_MAPREG_MEM_TYPE_64BIT) != 0) aprint_error_dev(self, "HostBAR1 addr %#x, size %#x\n", hbar_addr_hi, hbar_size_hi); aprint_error_dev(self, "WARNING: firmware PCI-X setup error: " "RAM %#"PRIx64"..%#"PRIx64" not accessible by Host BAR, " "enabling DMA bounce buffers\n", hbar_size, mem_cluster_maxaddr-1); /* * force use of bouce buffers for inaccessible RAM addrs */ if (hbar_size < ((uint64_t)1 << 32)) { error = bus_dmatag_subregion(sc->sc_32bit_dmat, 0, (bus_addr_t)hbar_size, &sc->sc_32bit_dmat, BUS_DMA_NOWAIT); if (error) panic("%s: failed to subregion 32-bit dma tag:" " error %d", __func__, error); sc->sc_64bit_dmat = NULL; } else { error = bus_dmatag_subregion(sc->sc_64bit_dmat, 0, (bus_addr_t)hbar_size, &sc->sc_64bit_dmat, BUS_DMA_NOWAIT); if (error) panic("%s: failed to subregion 64-bit dma tag:" " error %d", __func__, error); } } /* * check PCI-X interface byteswap setup * ensure 'Match Byte Lane' is disabled */ uint32_t mble; mble = RMIXL_PCIXREG_READ(RMIXL_PCIX_ECFG_XLR_MBLE); #ifdef PCI_DEBUG uint32_t mba, mbs; mba = RMIXL_PCIXREG_READ(RMIXL_PCIX_ECFG_MATCH_BIT_ADDR); mbs = RMIXL_PCIXREG_READ(RMIXL_PCIX_ECFG_MATCH_BIT_SIZE); DPRINTF(("%s: MBLE=%#x, MBA=%#x, MBS=%#x\n", __func__, mble, mba, mbs)); #endif if ((mble & __BIT(40)) != 0) RMIXL_PCIXREG_WRITE(RMIXL_PCIX_ECFG_XLR_MBLE, 0); /* * get PCI config space base addr from SBC PCIe CFG BAR * initialize it if necessary */ bar = RMIXL_IOREG_READ(RMIXL_IO_DEV_BRIDGE + RMIXLR_SBC_PCIX_CFG_BAR); DPRINTF(("%s: PCIX_CFG_BAR %#x\n", __func__, bar)); if ((bar & RMIXL_PCIX_CFG_BAR_ENB) == 0) { u_long n = RMIXL_PCIX_CFG_SIZE / (1024 * 1024); RMIXL_PCIX_BAR_INIT(CFG, bar, n, n); } rcp->rc_pci_cfg_pbase = (bus_addr_t)RMIXL_PCIX_CFG_BAR_TO_BA(bar); rcp->rc_pci_cfg_size = (bus_size_t)RMIXL_PCIX_CFG_SIZE; /* * get PCI MEM space base [addr, size] from SBC PCIe MEM BAR * initialize it if necessary */ bar = RMIXL_IOREG_READ(RMIXL_IO_DEV_BRIDGE + RMIXLR_SBC_PCIX_MEM_BAR); DPRINTF(("%s: PCIX_MEM_BAR %#x\n", __func__, bar)); if ((bar & RMIXL_PCIX_MEM_BAR_ENB) == 0) { u_long n = 256; /* 256 MB */ RMIXL_PCIX_BAR_INIT(MEM, bar, n, n); } rcp->rc_pci_mem_pbase = (bus_addr_t)RMIXL_PCIX_MEM_BAR_TO_BA(bar); rcp->rc_pci_mem_size = (bus_size_t)RMIXL_PCIX_MEM_BAR_TO_SIZE(bar); /* * get PCI IO space base [addr, size] from SBC PCIe IO BAR * initialize it if necessary */ bar = RMIXL_IOREG_READ(RMIXL_IO_DEV_BRIDGE + RMIXLR_SBC_PCIX_IO_BAR); DPRINTF(("%s: PCIX_IO_BAR %#x\n", __func__, bar)); if ((bar & RMIXL_PCIX_IO_BAR_ENB) == 0) { u_long n = 32; /* 32 MB */ RMIXL_PCIX_BAR_INIT(IO, bar, n, n); } rcp->rc_pci_io_pbase = (bus_addr_t)RMIXL_PCIX_IO_BAR_TO_BA(bar); rcp->rc_pci_io_size = (bus_size_t)RMIXL_PCIX_IO_BAR_TO_SIZE(bar); /* * initialize the PCI CFG bus space tag */ rmixl_pci_cfg_bus_mem_init(&rcp->rc_pci_cfg_memt, rcp); sc->sc_pci_cfg_memt = &rcp->rc_pci_cfg_memt; /* * initialize the PCI MEM and IO bus space tags */ rmixl_pci_bus_mem_init(&rcp->rc_pci_memt, rcp); rmixl_pci_bus_io_init(&rcp->rc_pci_iot, rcp); /* * initialize the extended configuration regs */ rmixl_pcix_init_errors(sc); /* * initialize the PCI chipset tag */ rmixl_pcix_init(sc); /* * attach the PCI bus */ memset(&pba, 0, sizeof(pba)); pba.pba_memt = &rcp->rc_pci_memt; pba.pba_iot = &rcp->rc_pci_iot; pba.pba_dmat = sc->sc_32bit_dmat; pba.pba_dmat64 = sc->sc_64bit_dmat; pba.pba_pc = &sc->sc_pci_chipset; pba.pba_bus = 0; pba.pba_bridgetag = NULL; pba.pba_intrswiz = 0; pba.pba_intrtag = 0; pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY | PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY; (void) config_found_ia(self, "pcibus", &pba, pcibusprint); }
void aupciattach(device_t parent, device_t self, void *aux) { struct aupci_softc *sc = device_private(self); struct aubus_attach_args *aa = (struct aubus_attach_args *)aux; uint32_t cfg; #if NPCI > 0 uint32_t mbar, mask; bus_addr_t mstart; struct pcibus_attach_args pba; #endif aupci_found = 1; sc->sc_dev = self; sc->sc_bust = aa->aa_st; if (bus_space_map(sc->sc_bust, aa->aa_addrs[0], 512, 0, &sc->sc_bush) != 0) { aprint_error(": unable to map PCI registers\n"); return; } #if NPCI > 0 /* * These physical addresses are locked in on the CPUs we have * seen. Perhaps these should be passed in via locators, thru * the configuration file. */ sc->sc_cfgbase = PCI_CONFIG_BASE; sc->sc_membase = PCI_MEM_BASE; sc->sc_iobase = PCI_IO_BASE; #endif /* * Configure byte swapping, as YAMON doesn't do it. YAMON does take * care of most of the rest of the details (clocking, etc.), however. */ #if _BYTE_ORDER == _BIG_ENDIAN /* * N.B.: This still doesn't do the DMA thing properly. I have * not yet figured out how to get DMA access to work properly * without having bytes swapped while the processor is in * big-endian mode. I'm not even sure that the Alchemy part * can do it without swapping the bytes (which would be a * bummer, since then only parts which had hardware detection * and swapping support would work without special hacks in * their drivers.) */ cfg = AUPCI_CONFIG_CH | AUPCI_CONFIG_R1H | AUPCI_CONFIG_R2H | AUPCI_CONFIG_AEN | AUPCI_CONFIG_SM | AUPCI_CONFIG_ST | AUPCI_CONFIG_SIC_DATA; #else cfg = AUPCI_CONFIG_CH | AUPCI_CONFIG_R1H | AUPCI_CONFIG_R2H | AUPCI_CONFIG_AEN; #endif bus_space_write_4(sc->sc_bust, sc->sc_bush, AUPCI_CONFIG, cfg); cfg = bus_space_read_4(sc->sc_bust, sc->sc_bush, AUPCI_COMMAND_STATUS); aprint_normal(": Alchemy Host-PCI Bridge, %sMHz\n", (cfg & PCI_STATUS_66MHZ_SUPPORT) ? "66" : "33"); aprint_naive("\n"); #if NPCI > 0 /* * PCI configuration space. Address in this bus are * orthogonal to other spaces. We need to make the entire * 32-bit address space available. */ sc->sc_cfgt = &sc->sc_cfg_space; au_himem_space_init(sc->sc_cfgt, "pcicfg", sc->sc_cfgbase, 0x00000000, 0xffffffff, AU_HIMEM_SPACE_IO); /* * Virtual PCI memory. Configured so that we don't overlap * with PCI memory space. */ mask = bus_space_read_4(sc->sc_bust, sc->sc_bush, AUPCI_MWMASK); mask >>= AUPCI_MWMASK_SHIFT; mask <<= AUPCI_MWMASK_SHIFT; mbar = bus_space_read_4(sc->sc_bust, sc->sc_bush, AUPCI_MBAR); mstart = (mbar & mask) + (~mask + 1); sc->sc_memt = &sc->sc_mem_space; au_himem_space_init(sc->sc_memt, "pcimem", sc->sc_membase, mstart, 0xffffffff, AU_HIMEM_SPACE_LITTLE_ENDIAN); /* * IO space. Address in this bus are orthogonal to other spaces. * 16 MB should be plenty. We don't start from zero to avoid * potential device bugs. */ sc->sc_iot = &sc->sc_io_space; au_himem_space_init(sc->sc_iot, "pciio", sc->sc_iobase, AUPCI_IO_START, AUPCI_IO_END, AU_HIMEM_SPACE_LITTLE_ENDIAN | AU_HIMEM_SPACE_IO); sc->sc_pc.pc_conf_v = sc; sc->sc_pc.pc_attach_hook = aupci_attach_hook; sc->sc_pc.pc_bus_maxdevs = aupci_bus_maxdevs; sc->sc_pc.pc_make_tag = aupci_make_tag; sc->sc_pc.pc_decompose_tag = aupci_decompose_tag; sc->sc_pc.pc_conf_read = aupci_conf_read; sc->sc_pc.pc_conf_write = aupci_conf_write; sc->sc_pc.pc_intr_v = sc; sc->sc_pc.pc_intr_map = aupci_intr_map; sc->sc_pc.pc_intr_string = aupci_intr_string; sc->sc_pc.pc_intr_establish = aupci_intr_establish; sc->sc_pc.pc_intr_disestablish = aupci_intr_disestablish; sc->sc_pc.pc_conf_interrupt = aupci_conf_interrupt; #ifdef PCI_NETBSD_CONFIGURE mem_ex = extent_create("pcimem", mstart, 0xffffffff, NULL, 0, EX_WAITOK); io_ex = extent_create("pciio", AUPCI_IO_START, AUPCI_IO_END, NULL, 0, EX_WAITOK); pci_configure_bus(&sc->sc_pc, io_ex, mem_ex, NULL, 0, mips_cache_info.mci_dcache_align); extent_destroy(mem_ex); extent_destroy(io_ex); #endif pba.pba_iot = sc->sc_iot; pba.pba_memt = sc->sc_memt; /* XXX: review dma tag logic */ pba.pba_dmat = aa->aa_dt; pba.pba_dmat64 = NULL; pba.pba_pc = &sc->sc_pc; pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY; pba.pba_bus = 0; pba.pba_bridgetag = NULL; config_found_ia(self, "pcibus", &pba, pcibusprint); #endif /* NPCI > 0 */ }
static void pmu_attach(device_t parent, device_t self, void *aux) { struct confargs *ca = aux; struct pmu_softc *sc = device_private(self); #if notyet struct i2cbus_attach_args iba; #endif uint32_t regs[16]; int irq = ca->ca_intr[0]; int node, extint_node, root_node; int nbat = 1, i, pmnode; int type = IST_EDGE; uint8_t cmd[2] = {2, 0}; uint8_t resp[16]; char name[256]; extint_node = of_getnode_byname(OF_parent(ca->ca_node), "extint-gpio1"); if (extint_node) { OF_getprop(extint_node, "interrupts", &irq, 4); type = IST_LEVEL; } aprint_normal(" irq %d: ", irq); sc->sc_dev = self; sc->sc_node = ca->ca_node; sc->sc_memt = ca->ca_tag; root_node = OF_finddevice("/"); sc->sc_error = 0; sc->sc_autopoll = 0; sc->sc_pending_eject = 0; sc->sc_brightness = sc->sc_brightness_wanted = 0x80; sc->sc_volume = sc->sc_volume_wanted = 0x80; sc->sc_flags = 0; sc->sc_callback = NULL; sc->sc_lid_closed = 0; if (bus_space_map(sc->sc_memt, ca->ca_reg[0] + ca->ca_baseaddr, ca->ca_reg[1], 0, &sc->sc_memh) != 0) { aprint_error_dev(self, "unable to map registers\n"); return; } sc->sc_ih = intr_establish(irq, type, IPL_TTY, pmu_intr, sc); pmu_init(sc); sc->sc_pmu_ops.cookie = sc; sc->sc_pmu_ops.do_command = pmu_send; sc->sc_pmu_ops.register_callback = pmu_register_callback; if (pmu0 == NULL) pmu0 = sc; pmu_send(sc, PMU_SYSTEM_READY, 1, cmd, 16, resp); /* check what kind of PMU we're talking to */ if (pmu_send(sc, PMU_GET_VERSION, 0, cmd, 16, resp) > 1) aprint_normal(" rev. %d", resp[1]); aprint_normal("\n"); node = OF_child(sc->sc_node); while (node != 0) { if (OF_getprop(node, "name", name, 256) == 0) goto next; if (strncmp(name, "pmu-i2c", 8) == 0) { aprint_normal_dev(self, "initializing IIC bus\n"); goto next; } if (strncmp(name, "adb", 4) == 0) { aprint_normal_dev(self, "initializing ADB\n"); sc->sc_adbops.cookie = sc; sc->sc_adbops.send = pmu_adb_send; sc->sc_adbops.poll = pmu_adb_poll; sc->sc_adbops.autopoll = pmu_autopoll; sc->sc_adbops.set_handler = pmu_adb_set_handler; #if NNADB > 0 config_found_ia(self, "adb_bus", &sc->sc_adbops, nadb_print); #endif goto next; } if (strncmp(name, "rtc", 4) == 0) { aprint_normal_dev(self, "initializing RTC\n"); sc->sc_todr.todr_gettime = pmu_todr_get; sc->sc_todr.todr_settime = pmu_todr_set; sc->sc_todr.cookie = sc; todr_attach(&sc->sc_todr); goto next; } if (strncmp(name, "battery", 8) == 0) goto next; aprint_normal_dev(self, "%s not configured\n", name); next: node = OF_peer(node); } if (OF_finddevice("/bandit/ohare") != -1) { aprint_normal_dev(self, "enabling ohare backlight control\n"); sc->sc_flags |= PMU_HAS_BACKLIGHT_CONTROL; cmd[0] = 0; cmd[1] = 0; memset(resp, 0, 6); if (pmu_send(sc, PMU_READ_BRIGHTNESS, 1, cmd, 16, resp) > 1) { sc->sc_brightness_wanted = resp[1]; pmu_update_brightness(sc); } } /* attach batteries */ if (of_compatible(root_node, has_legacy_battery) != -1) { pmu_attach_legacy_battery(sc); } else if (of_compatible(root_node, has_two_smart_batteries) != -1) { pmu_attach_smart_battery(sc, 0); pmu_attach_smart_battery(sc, 1); } else { /* check how many batteries we have */ pmnode = of_getnode_byname(ca->ca_node, "power-mgt"); if (pmnode == -1) goto bat_done; if (OF_getprop(pmnode, "prim-info", regs, sizeof(regs)) < 24) goto bat_done; nbat = regs[6] >> 16; for (i = 0; i < nbat; i++) pmu_attach_smart_battery(sc, i); } bat_done: #if notyet memset(&iba, 0, sizeof(iba)); iba.iba_tag = &sc->sc_i2c; sc->sc_i2c.ic_cookie = sc; sc->sc_i2c.ic_acquire_bus = pmu_i2c_acquire_bus; sc->sc_i2c.ic_release_bus = pmu_i2c_release_bus; sc->sc_i2c.ic_send_start = NULL; sc->sc_i2c.ic_send_stop = NULL; sc->sc_i2c.ic_initiate_xfer = NULL; sc->sc_i2c.ic_read_byte = NULL; sc->sc_i2c.ic_write_byte = NULL; sc->sc_i2c.ic_exec = pmu_i2c_exec; config_found_ia(sc->sc_dev, "i2cbus", &iba, iicbus_print); #endif if (kthread_create(PRI_NONE, 0, NULL, pmu_thread, sc, &sc->sc_thread, "%s", "pmu") != 0) { aprint_error_dev(self, "unable to create event kthread\n"); } sc->sc_lidswitch.smpsw_name = "Lid switch"; sc->sc_lidswitch.smpsw_type = PSWITCH_TYPE_LID; if (sysmon_pswitch_register(&sc->sc_lidswitch) != 0) aprint_error_dev(self, "unable to register lid switch with sysmon\n"); }
static void piixpm_attach(device_t parent, device_t self, void *aux) { struct piixpm_softc *sc = device_private(self); struct pci_attach_args *pa = aux; struct i2cbus_attach_args iba; pcireg_t base, conf; pcireg_t pmmisc; pci_intr_handle_t ih; char devinfo[256]; const char *intrstr = NULL; sc->sc_dev = self; sc->sc_pc = pa->pa_pc; sc->sc_pcitag = pa->pa_tag; aprint_naive("\n"); aprint_normal("\n"); pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); aprint_normal_dev(self, "%s (rev. 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class)); if (!pmf_device_register(self, piixpm_suspend, piixpm_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); /* Read configuration */ conf = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_HOSTC); DPRINTF(("%s: conf 0x%x\n", device_xname(self), conf)); if ((PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL) || (PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_INTEL_82371AB_PMC)) goto nopowermanagement; /* check whether I/O access to PM regs is enabled */ pmmisc = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_PMREGMISC); if (!(pmmisc & 1)) goto nopowermanagement; sc->sc_pm_iot = pa->pa_iot; /* Map I/O space */ base = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_PM_BASE); if (bus_space_map(sc->sc_pm_iot, PCI_MAPREG_IO_ADDR(base), PIIX_PM_SIZE, 0, &sc->sc_pm_ioh)) { aprint_error_dev(self, "can't map power management I/O space\n"); goto nopowermanagement; } /* * Revision 0 and 1 are PIIX4, 2 is PIIX4E, 3 is PIIX4M. * PIIX4 and PIIX4E have a bug in the timer latch, see Errata #20 * in the "Specification update" (document #297738). */ acpipmtimer_attach(self, sc->sc_pm_iot, sc->sc_pm_ioh, PIIX_PM_PMTMR, (PCI_REVISION(pa->pa_class) < 3) ? ACPIPMT_BADLATCH : 0 ); nopowermanagement: if ((conf & PIIX_SMB_HOSTC_HSTEN) == 0) { aprint_normal_dev(self, "SMBus disabled\n"); return; } /* Map I/O space */ sc->sc_smb_iot = pa->pa_iot; base = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_BASE) & 0xffff; if (bus_space_map(sc->sc_smb_iot, PCI_MAPREG_IO_ADDR(base), PIIX_SMB_SIZE, 0, &sc->sc_smb_ioh)) { aprint_error_dev(self, "can't map smbus I/O space\n"); return; } sc->sc_poll = 1; if ((conf & PIIX_SMB_HOSTC_INTMASK) == PIIX_SMB_HOSTC_SMI) { /* No PCI IRQ */ aprint_normal_dev(self, "interrupting at SMI"); } else if ((conf & PIIX_SMB_HOSTC_INTMASK) == PIIX_SMB_HOSTC_IRQ) { /* Install interrupt handler */ if (pci_intr_map(pa, &ih) == 0) { intrstr = pci_intr_string(pa->pa_pc, ih); sc->sc_smb_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, piixpm_intr, sc); if (sc->sc_smb_ih != NULL) { aprint_normal_dev(self, "interrupting at %s", intrstr); sc->sc_poll = 0; } } } if (sc->sc_poll) aprint_normal_dev(self, "polling"); aprint_normal("\n"); /* Attach I2C bus */ rw_init(&sc->sc_i2c_rwlock); sc->sc_i2c_tag.ic_cookie = sc; sc->sc_i2c_tag.ic_acquire_bus = piixpm_i2c_acquire_bus; sc->sc_i2c_tag.ic_release_bus = piixpm_i2c_release_bus; sc->sc_i2c_tag.ic_exec = piixpm_i2c_exec; bzero(&iba, sizeof(iba)); iba.iba_tag = &sc->sc_i2c_tag; config_found_ia(self, "i2cbus", &iba, iicbus_print); return; }