static void pchb_attach(struct device *parent, struct device *self, void *aux) { struct pci_attach_args *pa = aux; char devinfo[256]; printf("\n"); pcifound++; /* * All we do is print out a description. Eventually, we * might want to add code that does something that's * possibly chipset-specific. */ if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_GALILEO && PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_GALILEO_GT64120) { /* Bah, same product ID... */ /* * XXX: Is the >= 0x10 test correct? The '120 doco * lists rev == 0x02 and the '120A doco lists * rev == 0x10. */ snprintf(devinfo, sizeof(devinfo), "Galileo Technology GT-64120%s System Controller", PCI_REVISION(pa->pa_class) >= 0x10 ? "A" : ""); } else { pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo); } printf("%s: %s (rev. 0x%02x)\n", self->dv_xname, devinfo, PCI_REVISION(pa->pa_class)); }
int pciprint(void *aux, const char *pnp) { struct pci_attach_args *pa = aux; char devinfo[256]; const struct pci_quirkdata *qd; if (pnp) { pci_devinfo(pa->pa_id, pa->pa_class, 1, devinfo, sizeof(devinfo)); aprint_normal("%s at %s", devinfo, pnp); } aprint_normal(" dev %d function %d", pa->pa_device, pa->pa_function); if (pci_config_dump) { printf(": "); pci_conf_print(pa->pa_pc, pa->pa_tag, NULL); if (!pnp) pci_devinfo(pa->pa_id, pa->pa_class, 1, devinfo, sizeof(devinfo)); printf("%s at %s", devinfo, pnp ? pnp : "?"); printf(" dev %d function %d (", pa->pa_device, pa->pa_function); #ifdef __i386__ printf("tag %#lx, intrtag %#lx, intrswiz %#lx, intrpin %#lx", *(long *)&pa->pa_tag, *(long *)&pa->pa_intrtag, (long)pa->pa_intrswiz, (long)pa->pa_intrpin); #else printf("intrswiz %#lx, intrpin %#lx", (long)pa->pa_intrswiz, (long)pa->pa_intrpin); #endif printf(", i/o %s, mem %s,", pa->pa_flags & PCI_FLAGS_IO_OKAY ? "on" : "off", pa->pa_flags & PCI_FLAGS_MEM_OKAY ? "on" : "off"); qd = pci_lookup_quirkdata(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id)); if (qd == NULL) { printf(" no quirks"); } else { snprintb(devinfo, sizeof (devinfo), "\002\001multifn\002singlefn\003skipfunc0" "\004skipfunc1\005skipfunc2\006skipfunc3" "\007skipfunc4\010skipfunc5\011skipfunc6" "\012skipfunc7", qd->quirks); printf(" quirks %s", devinfo); } printf(")"); } return UNCONF; }
void pchbattach(struct device *parent, struct device *self, void *aux) { struct pci_attach_args *pa = aux; char devinfo[256]; #if NAGP > 0 struct agpbus_attach_args apa; #endif volatile unsigned char *python; uint32_t v; aprint_normal("\n"); /* * 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(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); aprint_normal("%s: %s (rev. 0x%02x)\n", self->dv_xname, devinfo, PCI_REVISION(pa->pa_class)); switch (PCI_VENDOR(pa->pa_id)) { case PCI_VENDOR_IBM: switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_IBM_82660: ibm82660_print(pa, self); break; case PCI_PRODUCT_IBM_PYTHON: python = mapiodev(0xfeff6000, 0x60); v = 0x88b78e01; /* taken from linux */ out32rb(python+0x30, v); v = in32rb(python+0x30); aprint_debug("Reset python reg 30 to 0x%x\n", v); break; } break; case PCI_VENDOR_MOT: switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_MOT_MPC105: mpc105_print(pa, self); break; case PCI_PRODUCT_MOT_MPC106: mpc106_print(pa, self); break; } break; } #if NAGP > 0 if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL) != 0) { apa.apa_pci_args = *pa; config_found_ia(self, "agpbus", &apa, agpbusprint); } #endif /* NAGP */ }
static void nfsmbc_attach(device_t parent, device_t self, void *aux) { struct nfsmbc_softc *sc = device_private(self); struct pci_attach_args *pa = aux; struct nfsmbc_attach_args nfsmbca; pcireg_t reg; int baseregs[2]; char devinfo[256]; aprint_naive("\n"); pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); aprint_normal(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class)); sc->sc_dev = self; sc->sc_pc = pa->pa_pc; sc->sc_tag = pa->pa_tag; sc->sc_pa = pa; sc->sc_iot = pa->pa_iot; nfsmbca.nfsmb_iot = sc->sc_iot; switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_NVIDIA_NFORCE2_SMBUS: case PCI_PRODUCT_NVIDIA_NFORCE2_400_SMBUS: case PCI_PRODUCT_NVIDIA_NFORCE3_SMBUS: case PCI_PRODUCT_NVIDIA_NFORCE3_250_SMBUS: case PCI_PRODUCT_NVIDIA_NFORCE4_SMBUS: baseregs[0] = NFORCE_OLD_SMB1; baseregs[1] = NFORCE_OLD_SMB2; break; default: baseregs[0] = NFORCE_SMB1; baseregs[1] = NFORCE_SMB2; break; } reg = pci_conf_read(pa->pa_pc, pa->pa_tag, baseregs[0]); nfsmbca.nfsmb_num = 1; nfsmbca.nfsmb_addr = NFORCE_SMBBASE(reg); sc->sc_nfsmb[0] = config_found(sc->sc_dev, &nfsmbca, nfsmbc_print); reg = pci_conf_read(pa->pa_pc, pa->pa_tag, baseregs[1]); nfsmbca.nfsmb_num = 2; nfsmbca.nfsmb_addr = NFORCE_SMBBASE(reg); sc->sc_nfsmb[1] = config_found(sc->sc_dev, &nfsmbca, nfsmbc_print); /* This driver is similar to an ISA bridge that doesn't * need any special handling. So registering NULL handlers * are sufficent. */ if (!pmf_device_register(self, NULL, NULL)) aprint_error_dev(self, "couldn't establish power handler\n"); }
static void ahci_pci_attach(device_t parent, device_t self, void *aux) { struct pci_attach_args *pa = aux; struct ahci_pci_softc *psc = device_private(self); struct ahci_softc *sc = &psc->ah_sc; bus_size_t size; char devinfo[256]; const char *intrstr; pci_intr_handle_t intrhandle; void *ih; sc->sc_atac.atac_dev = self; if (pci_mapreg_map(pa, AHCI_PCI_ABAR, PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->sc_ahcit, &sc->sc_ahcih, NULL, &size) != 0) { aprint_error_dev(self, "can't map ahci registers\n"); return; } psc->sc_pc = pa->pa_pc; psc->sc_pcitag = pa->pa_tag; pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); aprint_naive(": AHCI disk controller\n"); aprint_normal(": %s\n", devinfo); if (pci_intr_map(pa, &intrhandle) != 0) { aprint_error("%s: couldn't map interrupt\n", AHCINAME(sc)); return; } intrstr = pci_intr_string(pa->pa_pc, intrhandle); ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO, ahci_intr, sc); if (ih == NULL) { aprint_error("%s: couldn't establish interrupt", AHCINAME(sc)); return; } aprint_normal("%s: interrupting at %s\n", AHCINAME(sc), intrstr ? intrstr : "unknown interrupt"); sc->sc_dmat = pa->pa_dmat; if (PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_RAID) { AHCIDEBUG_PRINT(("%s: RAID mode\n", AHCINAME(sc)), DEBUG_PROBE); sc->sc_atac_capflags = ATAC_CAP_RAID; } else { AHCIDEBUG_PRINT(("%s: SATA mode\n", AHCINAME(sc)), DEBUG_PROBE); } ahci_attach(sc); if (!pmf_device_register(self, NULL, ahci_pci_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); }
static void pcib_attach(device_t parent, device_t self, void *aux) { struct pci_attach_args *pa = aux; char devinfo[256]; aprint_normal("\n"); pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); aprint_normal_dev(self, "%s, rev %d\n", devinfo, PCI_REVISION(pa->pa_class)); }
void ral_cardbus_attach(struct device *parent, struct device *self, void *aux) { struct ral_cardbus_softc *csc = (struct ral_cardbus_softc *)self; struct rt2560_softc *sc = &csc->sc_sc; struct cardbus_attach_args *ca = aux; cardbus_devfunc_t ct = ca->ca_ct; char devinfo[256]; bus_addr_t base; int error, revision; pci_devinfo(ca->ca_id, ca->ca_class, 0, devinfo, sizeof(devinfo)); revision = PCI_REVISION(ca->ca_class); aprint_normal(": %s (rev. 0x%02x)\n", devinfo, revision); csc->sc_opns = (CARDBUS_PRODUCT(ca->ca_id) == PCI_PRODUCT_RALINK_RT2560) ? &ral_rt2560_opns : &ral_rt2661_opns; sc->sc_dmat = ca->ca_dmat; csc->sc_ct = ct; csc->sc_tag = ca->ca_tag; csc->sc_intrline = ca->ca_intrline; /* power management hooks */ sc->sc_enable = ral_cardbus_enable; sc->sc_disable = ral_cardbus_disable; /* map control/status registers */ error = Cardbus_mapreg_map(ct, CARDBUS_BASE0_REG, CARDBUS_MAPREG_TYPE_MEM, 0, &sc->sc_st, &sc->sc_sh, &base, &csc->sc_mapsize); if (error != 0) { printf(": could not map memory space\n"); return; } #if rbus #else (*cf->cardbus_mem_open)(cc, 0, base, base + csc->sc_mapsize); #endif csc->sc_bar_val = base | CARDBUS_MAPREG_TYPE_MEM; /* set up the PCI configuration registers */ ral_cardbus_setup(csc); (*csc->sc_opns->attach)(sc, CARDBUS_PRODUCT(ca->ca_id)); Cardbus_function_disable(ct); }
int jmb_print(void *aux, const char *pnp) { struct pci_attach_args *pa = aux; char devinfo[256]; if (pnp != NULL) { pci_devinfo(pa->pa_id, pa->pa_class, 1, devinfo, sizeof(devinfo)); printf("%s at %s", devinfo, pnp); } return (UNCONF); }
void ral_cardbus_attach(device_t parent, device_t self, void *aux) { struct ral_cardbus_softc *csc = device_private(self); struct rt2560_softc *sc = &csc->sc_sc; struct cardbus_attach_args *ca = aux; cardbus_devfunc_t ct = ca->ca_ct; char devinfo[256]; bus_addr_t base; int error, revision; pci_devinfo(ca->ca_id, ca->ca_class, 0, devinfo, sizeof(devinfo)); revision = PCI_REVISION(ca->ca_class); aprint_normal(": %s (rev. 0x%02x)\n", devinfo, revision); csc->sc_opns = (PCI_PRODUCT(ca->ca_id) == PCI_PRODUCT_RALINK_RT2560) ? &ral_rt2560_opns : &ral_rt2661_opns; sc->sc_dev = self; sc->sc_dmat = ca->ca_dmat; csc->sc_ct = ct; csc->sc_tag = ca->ca_tag; /* power management hooks */ sc->sc_enable = ral_cardbus_enable; sc->sc_disable = ral_cardbus_disable; /* map control/status registers */ error = Cardbus_mapreg_map(ct, PCI_BAR0, PCI_MAPREG_TYPE_MEM, 0, &sc->sc_st, &sc->sc_sh, &base, &csc->sc_mapsize); if (error != 0) { aprint_error(": could not map memory space\n"); return; } csc->sc_bar_val = base | PCI_MAPREG_TYPE_MEM; /* set up the PCI configuration registers */ ral_cardbus_setup(csc); (*csc->sc_opns->attach)(sc, PCI_PRODUCT(ca->ca_id)); Cardbus_function_disable(ct); }
void pcmbattach(device_t parent, device_t self, void *aux) { struct pci_attach_args *pa = aux; char devinfo[256]; aprint_naive("\n"); aprint_normal("\n"); /* * Just print out a description and defer configuration * until all PCI devices have been attached. */ 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)); config_defer(self, pcmb_callback); }
static void joy_pci_attach(device_t parent, device_t self, void *aux) { struct joy_softc *sc = device_private(self); struct pci_attach_args *pa = aux; char devinfo[256]; bus_size_t mapsize; int reg; pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); aprint_normal(": %s (rev 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class)); for (reg = PCI_MAPREG_START; reg < PCI_MAPREG_END; reg += sizeof(pcireg_t)) if (bar_is_io(pa->pa_pc, pa->pa_tag, reg)) break; if (reg >= PCI_MAPREG_END) { aprint_error_dev(self, "violates PCI spec, no IO region found\n"); return; } if (pci_mapreg_map(pa, reg, PCI_MAPREG_TYPE_IO, 0, &sc->sc_iot, &sc->sc_ioh, NULL, &mapsize)) { aprint_error_dev(self, "could not map IO space\n"); return; } if (mapsize != 2) { if (!bus_space_subregion(sc->sc_iot, sc->sc_ioh, 1, 1, &sc->sc_ioh) < 0) { aprint_error_dev(self, "error mapping subregion\n"); return; } } sc->sc_dev = self; joyattach(sc); }
void ohci_cardbus_attach(device_t parent, device_t self, void *aux) { struct ohci_cardbus_softc *sc = device_private(self); struct cardbus_attach_args *ca = aux; cardbus_devfunc_t ct = ca->ca_ct; cardbus_chipset_tag_t cc = ct->ct_cc; cardbus_function_tag_t cf = ct->ct_cf; pcireg_t csr; char devinfo[256]; usbd_status r; const char *vendor; const char *devname = device_xname(self); sc->sc.sc_dev = self; sc->sc.sc_bus.hci_private = sc; pci_devinfo(ca->ca_id, ca->ca_class, 0, devinfo, sizeof(devinfo)); printf(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(ca->ca_class)); /* Map I/O registers */ if (Cardbus_mapreg_map(ct, PCI_CBMEM, PCI_MAPREG_TYPE_MEM, 0, &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size)) { printf("%s: can't map mem space\n", devname); return; } sc->sc_cc = cc; sc->sc_cf = cf; sc->sc_ct = ct; sc->sc.sc_bus.dmatag = ca->ca_dmat; /* Enable the device. */ csr = Cardbus_conf_read(ct, ca->ca_tag, PCI_COMMAND_STATUS_REG); Cardbus_conf_write(ct, ca->ca_tag, PCI_COMMAND_STATUS_REG, csr | PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_MEM_ENABLE); /* Disable interrupts, so we don't can any spurious ones. */ bus_space_write_4(sc->sc.iot, sc->sc.ioh, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS); sc->sc_ih = Cardbus_intr_establish(ct, IPL_USB, ohci_intr, sc); if (sc->sc_ih == NULL) { printf("%s: couldn't establish interrupt\n", devname); return; } /* Figure out vendor for root hub descriptor. */ vendor = pci_findvendor(ca->ca_id); sc->sc.sc_id_vendor = PCI_VENDOR(ca->ca_id); if (vendor) strlcpy(sc->sc.sc_vendor, vendor, sizeof(sc->sc.sc_vendor)); else snprintf(sc->sc.sc_vendor, sizeof(sc->sc.sc_vendor), "vendor 0x%04x", PCI_VENDOR(ca->ca_id)); r = ohci_init(&sc->sc); if (r != USBD_NORMAL_COMPLETION) { printf("%s: init failed, error=%d\n", devname, r); /* Avoid spurious interrupts. */ Cardbus_intr_disestablish(ct, sc->sc_ih); sc->sc_ih = 0; return; } #if NEHCI_CARDBUS > 0 usb_cardbus_add(&sc->sc_cardbus, ca, self); #endif if (!pmf_device_register1(self, ohci_suspend, ohci_resume, ohci_shutdown)) aprint_error_dev(self, "couldn't establish power handler\n"); /* Attach usb device. */ sc->sc.sc_child = config_found(self, &sc->sc.sc_bus, usbctlprint); }
static void uhci_cardbus_attach(device_t parent, device_t self, void *aux) { struct uhci_cardbus_softc *sc = device_private(self); struct cardbus_attach_args *ca = (struct cardbus_attach_args *)aux; cardbus_devfunc_t ct = ca->ca_ct; cardbus_chipset_tag_t cc = ct->ct_cc; cardbus_function_tag_t cf = ct->ct_cf; pcitag_t tag = ca->ca_tag; pcireg_t csr; const char *vendor; const char *devname = device_xname(self); char devinfo[256]; usbd_status r; sc->sc.sc_dev = self; sc->sc.sc_bus.hci_private = sc; pci_devinfo(ca->ca_id, ca->ca_class, 0, devinfo, sizeof(devinfo)); printf(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(ca->ca_class)); /* Map I/O registers */ if (Cardbus_mapreg_map(ct, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0, &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size)) { printf("%s: can't map i/o space\n", devname); return; } sc->sc_cc = cc; sc->sc_cf = cf; sc->sc_ct = ct; sc->sc_tag = tag; sc->sc.sc_bus.dmatag = ca->ca_dmat; /* Enable the device. */ csr = Cardbus_conf_read(ct, tag, PCI_COMMAND_STATUS_REG); Cardbus_conf_write(ct, tag, PCI_COMMAND_STATUS_REG, csr | PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_IO_ENABLE); /* Disable interrupts, so we don't get any spurious ones. */ bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_INTR, 0); /* Map and establish the interrupt. */ sc->sc_ih = Cardbus_intr_establish(ct, IPL_USB, uhci_intr, sc); if (sc->sc_ih == NULL) { printf("%s: couldn't establish interrupt\n", devname); return; } /* Set LEGSUP register to its default value. */ Cardbus_conf_write(ct, tag, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN); switch(Cardbus_conf_read(ct, tag, PCI_USBREV) & PCI_USBREV_MASK) { case PCI_USBREV_PRE_1_0: sc->sc.sc_bus.usbrev = USBREV_PRE_1_0; break; case PCI_USBREV_1_0: sc->sc.sc_bus.usbrev = USBREV_1_0; break; case PCI_USBREV_1_1: sc->sc.sc_bus.usbrev = USBREV_1_1; break; default: sc->sc.sc_bus.usbrev = USBREV_UNKNOWN; break; } /* Figure out vendor for root hub descriptor. */ vendor = pci_findvendor(ca->ca_id); sc->sc.sc_id_vendor = PCI_VENDOR(ca->ca_id); if (vendor) strlcpy(sc->sc.sc_vendor, vendor, sizeof(sc->sc.sc_vendor)); else snprintf(sc->sc.sc_vendor, sizeof(sc->sc.sc_vendor), "vendor 0x%04x", PCI_VENDOR(ca->ca_id)); r = uhci_init(&sc->sc); if (r != USBD_NORMAL_COMPLETION) { printf("%s: init failed, error=%d\n", devname, r); /* Avoid spurious interrupts. */ Cardbus_intr_disestablish(ct, sc->sc_ih); sc->sc_ih = NULL; return; } #if NEHCI_CARDBUS > 0 usb_cardbus_add(&sc->sc_cardbus, ca, self); #endif /* Attach usb device. */ sc->sc.sc_child = config_found(self, &sc->sc.sc_bus, usbctlprint); }
static void wi_pci_attach(struct device *parent, struct device *self, void *aux) { struct wi_pci_softc *psc = (struct wi_pci_softc *)self; struct wi_softc *sc = &psc->psc_wi; struct pci_attach_args *pa = aux; pci_chipset_tag_t pc = pa->pa_pc; const char *intrstr; const struct wi_pci_product *wpp; pci_intr_handle_t ih; bus_space_tag_t memt, iot, plxt, tmdt; bus_space_handle_t memh, ioh, plxh, tmdh; psc->psc_pc = pc; psc->psc_pcitag = pa->pa_tag; wpp = wi_pci_lookup(pa); #ifdef DIAGNOSTIC if (wpp == NULL) { printf("\n"); panic("wi_pci_attach: impossible"); } #endif switch (wpp->wpp_chip) { case CHIP_PLX_OTHER: case CHIP_PLX_9052: /* Map memory and I/O registers. */ if (pci_mapreg_map(pa, WI_PCI_LOMEM, PCI_MAPREG_TYPE_MEM, 0, &memt, &memh, NULL, NULL) != 0) { printf(": can't map mem space\n"); return; } if (pci_mapreg_map(pa, WI_PCI_LOIO, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, NULL, NULL) != 0) { printf(": can't map I/O space\n"); return; } if (wpp->wpp_chip == CHIP_PLX_OTHER) { /* The PLX 9052 doesn't have IO at 0x14. Perhaps other chips have, so we'll make this conditional. */ if (pci_mapreg_map(pa, WI_PCI_PLX_LOIO, PCI_MAPREG_TYPE_IO, 0, &plxt, &plxh, NULL, NULL) != 0) { printf(": can't map PLX\n"); return; } } break; case CHIP_TMD_7160: /* Used instead of PLX on at least one revision of * the National Datacomm Corporation NCP130. Values * for registers acquired from OpenBSD, which in * turn got them from a Linux driver. */ /* Map COR and I/O registers. */ if (pci_mapreg_map(pa, WI_TMD_COR, PCI_MAPREG_TYPE_IO, 0, &tmdt, &tmdh, NULL, NULL) != 0) { printf(": can't map TMD\n"); return; } if (pci_mapreg_map(pa, WI_TMD_IO, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, NULL, NULL) != 0) { printf(": can't map I/O space\n"); return; } break; default: if (pci_mapreg_map(pa, WI_PCI_CBMA, PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &iot, &ioh, NULL, NULL) != 0) { printf(": can't map mem space\n"); return; } memt = iot; memh = ioh; sc->sc_pci = 1; break; } { char devinfo[256]; pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); printf(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class)); } sc->sc_enabled = 1; sc->sc_enable = wi_pci_enable; sc->sc_disable = wi_pci_disable; sc->sc_iot = iot; sc->sc_ioh = ioh; /* Make sure interrupts are disabled. */ CSR_WRITE_2(sc, WI_INT_EN, 0); CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); if (wpp->wpp_chip == CHIP_PLX_OTHER) { uint32_t command; #define WI_LOCAL_INTCSR 0x4c #define WI_LOCAL_INTEN 0x40 /* poke this into INTCSR */ command = bus_space_read_4(plxt, plxh, WI_LOCAL_INTCSR); command |= WI_LOCAL_INTEN; bus_space_write_4(plxt, plxh, WI_LOCAL_INTCSR, command); } /* Map and establish the interrupt. */ if (pci_intr_map(pa, &ih)) { aprint_error_dev(self, "couldn't map interrupt\n"); return; } intrstr = pci_intr_string(pc, ih); psc->psc_ih = ih; sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, wi_intr, sc); if (sc->sc_ih == NULL) { aprint_error_dev(self, "couldn't establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); return; } printf("%s: interrupting at %s\n", device_xname(self), intrstr); switch (wpp->wpp_chip) { case CHIP_PLX_OTHER: case CHIP_PLX_9052: /* * Setup the PLX chip for level interrupts and config index 1 * XXX - should really reset the PLX chip too. */ bus_space_write_1(memt, memh, WI_PLX_COR_OFFSET, WI_PLX_COR_VALUE); break; case CHIP_TMD_7160: /* Enable I/O mode and level interrupts on the embedded * card. The card's COR is the first byte of BAR 0. */ bus_space_write_1(tmdt, tmdh, 0, WI_COR_IOMODE); break; default: /* reset HFA3842 MAC core */ wi_pci_reset(sc); break; } printf("%s:", device_xname(self)); if (wi_attach(sc, 0) != 0) { aprint_error_dev(self, "failed to attach controller\n"); pci_intr_disestablish(pa->pa_pc, sc->sc_ih); return; } if (!wpp->wpp_chip) sc->sc_reset = wi_pci_reset; if (!pmf_device_register(self, NULL, NULL)) aprint_error_dev(self, "couldn't establish power handler\n"); else pmf_class_network_register(self, &sc->sc_if); }
/*static*/ void ndis_attach_pci(device_t parent, device_t self, void *aux) { struct ndis_softc *sc = device_private(self); struct pci_attach_args *pa = aux; #ifdef NDIS_DBG char devinfo[256]; #endif pci_intr_handle_t ih; pcireg_t type; bus_addr_t base; bus_size_t size; int flags; ndis_resource_list *rl = NULL; struct cm_partial_resource_desc *prd = NULL; #ifdef NDIS_DBG struct pci_conf_state conf_state; int revision, i; #endif int bar; size_t rllen; printf("in ndis_attach_pci()\n"); /* initalize the softc */ //sc->ndis_hardware_type = NDIS_PCI; sc->ndis_dev = self; sc->ndis_iftype = PCIBus; sc->ndis_res_pc = pa->pa_pc; sc->ndis_res_pctag = pa->pa_tag; /* TODO: is this correct? All are just pa->pa_dmat? */ sc->ndis_mtag = pa->pa_dmat; sc->ndis_ttag = pa->pa_dmat; sc->ndis_parent_tag = pa->pa_dmat; sc->ndis_res_io = NULL; sc->ndis_res_mem = NULL; sc->ndis_res_altmem = NULL; sc->ndis_block = NULL; sc->ndis_shlist = NULL; ndis_in_isr = FALSE; printf("sc->ndis_mtag = %x\n", (unsigned int)sc->ndis_mtag); rllen = sizeof(ndis_resource_list) + sizeof(cm_partial_resource_desc) * (MAX_RESOURCES - 1); rl = malloc(rllen, M_DEVBUF, M_NOWAIT|M_ZERO); if(rl == NULL) { sc->error = ENOMEM; //printf("error: out of memory\n"); return; } rl->cprl_version = 5; rl->cprl_version = 1; rl->cprl_count = 0; prd = rl->cprl_partial_descs; #ifdef NDIS_DBG pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof devinfo); revision = PCI_REVISION(pa->pa_class); printf(": %s (rev. 0x%02x)\n", devinfo, revision); pci_conf_print(sc->ndis_res_pc, sc->ndis_res_pctag, NULL); pci_conf_capture(sc->ndis_res_pc, sc->ndis_res_pctag, &conf_state); for(i=0; i<16; i++) { printf("conf_state.reg[%d] = %x\n", i, conf_state.reg[i]); } #endif /* just do the conversion work in attach instead of calling ndis_convert_res() */ for(bar = 0x10; bar <= 0x24; bar += 0x04) { type = pci_mapreg_type(sc->ndis_res_pc, sc->ndis_res_pctag, bar); if(pci_mapreg_info(sc->ndis_res_pc, sc->ndis_res_pctag, bar, type, &base, &size, &flags)) { printf("pci_mapreg_info() failed on BAR 0x%x!\n", bar); } else { switch(type) { case PCI_MAPREG_TYPE_IO: prd->cprd_type = CmResourceTypePort; prd->cprd_flags = CM_RESOURCE_PORT_IO; prd->u.cprd_port.cprd_start.np_quad = (uint64_t)base; prd->u.cprd_port.cprd_len = (uint32_t)size; if((sc->ndis_res_io = malloc(sizeof(struct ndis_resource), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) { //printf("error: out of memory\n"); sc->error = ENOMEM; goto out; } sc->ndis_res_io->res_base = base; sc->ndis_res_io->res_size = size; sc->ndis_res_io->res_tag = x86_bus_space_io; bus_space_map(sc->ndis_res_io->res_tag, sc->ndis_res_io->res_base, sc->ndis_res_io->res_size, flags, &sc->ndis_res_io->res_handle); break; case PCI_MAPREG_TYPE_MEM: prd->cprd_type = CmResourceTypeMemory; prd->cprd_flags = CM_RESOURCE_MEMORY_READ_WRITE; prd->u.cprd_mem.cprd_start.np_quad = (uint64_t)base; prd->u.cprd_mem.cprd_len = (uint32_t)size; if(sc->ndis_res_mem != NULL && sc->ndis_res_altmem != NULL) { printf("too many resources\n"); sc->error = ENXIO; goto out; } if(sc->ndis_res_mem) { if((sc->ndis_res_altmem = malloc(sizeof(struct ndis_resource), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) { sc->error = ENOMEM; return; } sc->ndis_res_altmem->res_base = base; sc->ndis_res_altmem->res_size = size; sc->ndis_res_altmem->res_tag = x86_bus_space_mem; if(bus_space_map(sc->ndis_res_altmem->res_tag, sc->ndis_res_altmem->res_base, sc->ndis_res_altmem->res_size, flags|BUS_SPACE_MAP_LINEAR, &sc->ndis_res_altmem->res_handle)) { printf("bus_space_map failed\n"); } } else { if((sc->ndis_res_mem = malloc(sizeof(struct ndis_resource), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) { sc->error = ENOMEM; goto out; } sc->ndis_res_mem->res_base = base; sc->ndis_res_mem->res_size = size; sc->ndis_res_mem->res_tag = x86_bus_space_mem; if(bus_space_map(sc->ndis_res_mem->res_tag, sc->ndis_res_mem->res_base, sc->ndis_res_mem->res_size, flags|BUS_SPACE_MAP_LINEAR, &sc->ndis_res_mem->res_handle)) { printf("bus_space_map failed\n"); } } break; default: printf("unknown type\n"); } prd->cprd_sharedisp = CmResourceShareDeviceExclusive; rl->cprl_count++; prd++; } } /* add the interrupt to the list */ prd->cprd_type = CmResourceTypeInterrupt; prd->cprd_flags = 0; /* TODO: is this all we need to save for the interrupt? */ prd->u.cprd_intr.cprd_level = pa->pa_intrline; prd->u.cprd_intr.cprd_vector = pa->pa_intrline; prd->u.cprd_intr.cprd_affinity = 0; rl->cprl_count++; pci_intr_map(pa, &ih); sc->ndis_intrhand = pci_intr_establish(pa->pa_pc, ih, IPL_NET /*| PCATCH*/, ndis_intr, sc); sc->ndis_irq = (void *)sc->ndis_intrhand; printf("pci interrupt: %s\n", pci_intr_string(pa->pa_pc, ih)); /* save resource list in the softc */ sc->ndis_rl = rl; sc->ndis_rescnt = rl->cprl_count; kthread_create(PRI_NONE, 0, NULL, ndis_attach, (void *)sc, NULL, "ndis_attach"); return; out: free(rl, M_DEVBUF); return; }
static void ohci_pci_attach(device_t parent, device_t self, void *aux) { struct ohci_pci_softc *sc = device_private(self); struct pci_attach_args *pa = (struct pci_attach_args *)aux; pci_chipset_tag_t pc = pa->pa_pc; pcitag_t tag = pa->pa_tag; char const *intrstr; pci_intr_handle_t ih; pcireg_t csr; char devinfo[256]; usbd_status r; const char *vendor; const char *devname = device_xname(self); sc->sc.sc_dev = self; sc->sc.sc_bus.hci_private = sc; pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); printf(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class)); /* Map I/O registers */ if (pci_mapreg_map(pa, PCI_CBMEM, PCI_MAPREG_TYPE_MEM, 0, &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size)) { printf("%s: can't map mem space\n", devname); return; } /* Disable interrupts, so we don't get any spurious ones. */ bus_space_write_4(sc->sc.iot, sc->sc.ioh, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS); sc->sc_pc = pc; sc->sc_tag = tag; sc->sc.sc_bus.dmatag = pa->pa_dmat; /* Enable the device. */ csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr | PCI_COMMAND_MASTER_ENABLE); /* Map and establish the interrupt. */ if (pci_intr_map(pa, &ih)) { printf("%s: couldn't map interrupt\n", devname); return; } intrstr = pci_intr_string(pc, ih); sc->sc_ih = pci_intr_establish(pc, ih, IPL_USB, ohci_intr, sc); if (sc->sc_ih == NULL) { printf("%s: couldn't establish interrupt", devname); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); return; } printf("%s: interrupting at %s\n", devname, intrstr); /* Figure out vendor for root hub descriptor. */ vendor = pci_findvendor(pa->pa_id); sc->sc.sc_id_vendor = PCI_VENDOR(pa->pa_id); if (vendor) strlcpy(sc->sc.sc_vendor, vendor, sizeof(sc->sc.sc_vendor)); else snprintf(sc->sc.sc_vendor, sizeof(sc->sc.sc_vendor), "vendor 0x%04x", PCI_VENDOR(pa->pa_id)); r = ohci_init(&sc->sc); if (r != USBD_NORMAL_COMPLETION) { printf("%s: init failed, error=%d\n", devname, r); return; } #if NEHCI > 0 usb_pci_add(&sc->sc_pci, pa, self); #endif if (!pmf_device_register1(self, ohci_suspend, ohci_resume, ohci_shutdown)) aprint_error_dev(self, "couldn't establish power handler\n"); /* Attach usb device. */ sc->sc.sc_child = config_found(self, &sc->sc.sc_bus, usbctlprint); }
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); }
void uhci_pci_attach(struct device *parent, struct device *self, void *aux) { struct uhci_pci_softc *sc = (struct uhci_pci_softc *)self; struct pci_attach_args *pa = (struct pci_attach_args *)aux; pci_chipset_tag_t pc = pa->pa_pc; pcitag_t tag = pa->pa_tag; char const *intrstr; pci_intr_handle_t ih; const char *vendor; char *devname = sc->sc.sc_bus.bdev.dv_xname; int s; #if defined(__NetBSD__) char devinfo[256]; pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo); printf(": %s (rev. 0x%02x)", devinfo, PCI_REVISION(pa->pa_class)); #endif /* Map I/O registers */ if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0, &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size, 0)) { printf(": can't map i/o space\n"); return; } /* Disable interrupts, so we don't get any spurious ones. */ s = splhardusb(); bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_INTR, 0); sc->sc_pc = pc; sc->sc_tag = tag; sc->sc.sc_bus.dmatag = pa->pa_dmat; /* Map and establish the interrupt. */ if (pci_intr_map(pa, &ih)) { printf(": couldn't map interrupt\n"); goto unmap_ret; } intrstr = pci_intr_string(pc, ih); sc->sc_ih = pci_intr_establish(pc, ih, IPL_USB, uhci_intr, sc, devname); if (sc->sc_ih == NULL) { printf(": couldn't establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); goto unmap_ret; } printf(": %s\n", intrstr); /* Set LEGSUP register to its default value. */ pci_conf_write(pc, tag, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN); switch(pci_conf_read(pc, tag, PCI_USBREV) & PCI_USBREV_MASK) { case PCI_USBREV_PRE_1_0: sc->sc.sc_bus.usbrev = USBREV_PRE_1_0; break; case PCI_USBREV_1_0: sc->sc.sc_bus.usbrev = USBREV_1_0; break; case PCI_USBREV_1_1: sc->sc.sc_bus.usbrev = USBREV_1_1; break; default: sc->sc.sc_bus.usbrev = USBREV_UNKNOWN; break; } uhci_run(&sc->sc, 0); /* stop the controller */ /* disable interrupts */ bus_space_barrier(sc->sc.iot, sc->sc.ioh, 0, sc->sc.sc_size, BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE); bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_INTR, 0); /* Figure out vendor for root hub descriptor. */ vendor = pci_findvendor(pa->pa_id); sc->sc.sc_id_vendor = PCI_VENDOR(pa->pa_id); if (vendor) strlcpy(sc->sc.sc_vendor, vendor, sizeof (sc->sc.sc_vendor)); else snprintf(sc->sc.sc_vendor, sizeof (sc->sc.sc_vendor), "vendor 0x%04x", PCI_VENDOR(pa->pa_id)); config_defer(self, uhci_pci_attach_deferred); /* Ignore interrupts for now */ sc->sc.sc_dying = 1; splx(s); return; unmap_ret: bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size); splx(s); }
static void siisata_pci_attach(device_t parent, device_t self, void *aux) { struct pci_attach_args *pa = aux; struct siisata_pci_softc *psc = device_private(self); struct siisata_softc *sc = &psc->si_sc; char devinfo[256]; const char *intrstr; pci_intr_handle_t intrhandle; pcireg_t csr, memtype; const struct siisata_pci_product *spp; void *ih; bus_space_tag_t memt; bus_space_handle_t memh; uint32_t gcreg; int memh_valid; bus_size_t grsize, prsize; sc->sc_atac.atac_dev = self; psc->sc_pc = pa->pa_pc; psc->sc_pcitag = pa->pa_tag; pci_devinfo(pa->pa_id, pa->pa_class, 1, devinfo, sizeof(devinfo)); aprint_naive(": SATA-II HBA\n"); aprint_normal(": %s\n", devinfo); /* map bar0 */ #if 1 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, SIISATA_PCI_BAR0); #else memtype = PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT; #endif switch (memtype) { case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT: memh_valid = (pci_mapreg_map(pa, SIISATA_PCI_BAR0, memtype, 0, &memt, &memh, NULL, &grsize) == 0); break; default: memh_valid = 0; } if (memh_valid) { sc->sc_grt = memt; sc->sc_grh = memh; } else { aprint_error("%s: unable to map device global registers\n", SIISATANAME(sc)); return; } /* map bar1 */ #if 1 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, SIISATA_PCI_BAR1); #else memtype = PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT; #endif switch (memtype) { case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT: memh_valid = (pci_mapreg_map(pa, SIISATA_PCI_BAR1, memtype, 0, &memt, &memh, NULL, &prsize) == 0); break; default: memh_valid = 0; } if (memh_valid) { sc->sc_prt = memt; sc->sc_prh = memh; } else { bus_space_unmap(sc->sc_grt, sc->sc_grh, grsize); aprint_error("%s: unable to map device port registers\n", SIISATANAME(sc)); return; } if (pci_dma64_available(pa)) { sc->sc_dmat = pa->pa_dmat64; sc->sc_have_dma64 = 1; aprint_debug("64-bit PCI DMA available\n"); } else { sc->sc_dmat = pa->pa_dmat; sc->sc_have_dma64 = 0; } /* map interrupt */ if (pci_intr_map(pa, &intrhandle) != 0) { bus_space_unmap(sc->sc_grt, sc->sc_grh, grsize); bus_space_unmap(sc->sc_prt, sc->sc_prh, prsize); aprint_error("%s: couldn't map interrupt\n", SIISATANAME(sc)); return; } intrstr = pci_intr_string(pa->pa_pc, intrhandle); ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO, siisata_intr, sc); if (ih == NULL) { bus_space_unmap(sc->sc_grt, sc->sc_grh, grsize); bus_space_unmap(sc->sc_prt, sc->sc_prh, prsize); aprint_error("%s: couldn't establish interrupt" "at %s\n", SIISATANAME(sc), intrstr); return; } aprint_normal("%s: interrupting at %s\n", SIISATANAME(sc), intrstr ? intrstr : "unknown interrupt"); /* fill in number of ports on this device */ spp = siisata_pci_lookup(pa); if (spp != NULL) { sc->sc_atac.atac_nchannels = spp->spp_ports; sc->sc_chip = spp->spp_chip; } else /* _match() should prevent us from getting here */ panic("siisata: the universe might be falling apart!\n"); gcreg = GRREAD(sc, GR_GC); aprint_normal("%s: SiI%d on ", SIISATANAME(sc), sc->sc_chip); if (sc->sc_chip == 3124) { aprint_normal("%d-bit, ", (gcreg & GR_GC_REQ64) ? 64 : 32); switch (gcreg & (GR_GC_DEVSEL | GR_GC_STOP | GR_GC_TRDY)) { case 0: aprint_normal("%d", (gcreg & GR_GC_M66EN) ? 66 : 33); break; case GR_GC_TRDY: aprint_normal("%d", 66); break; case GR_GC_STOP: aprint_normal("%d", 100); break; case GR_GC_STOP | GR_GC_TRDY: aprint_normal("%d", 133); break; default: break; } aprint_normal("MHz PCI%s bus.", (gcreg & (GR_GC_DEVSEL | GR_GC_STOP | GR_GC_TRDY)) ? "-X" : ""); } else { /* XXX - but only x1 devices so far */ aprint_normal("PCI-Express x1 port."); } if (gcreg & GR_GC_3GBPS) aprint_normal(" 3.0Gb/s capable.\n"); else aprint_normal("\n"); /* enable bus mastering in case the firmware didn't */ csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); csr |= PCI_COMMAND_MASTER_ENABLE; csr |= PCI_COMMAND_MEM_ENABLE; pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, csr); siisata_attach(sc); if (!pmf_device_register(self, NULL, siisata_pci_resume)) aprint_error_dev(self, "couldn't establish power handler\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; }