int ral_cardbus_match(struct device *parent, struct cfdata *cfdata, void *aux) { struct cardbus_attach_args *ca = aux; if (PCI_VENDOR(ca->ca_id) == PCI_VENDOR_RALINK) { switch (PCI_PRODUCT(ca->ca_id)) { case PCI_PRODUCT_RALINK_RT2560: case PCI_PRODUCT_RALINK_RT2561: case PCI_PRODUCT_RALINK_RT2561S: case PCI_PRODUCT_RALINK_RT2661: return 1; default: return 0; } } return 0; }
/* * Determine which flags should be passed to the primary PCI bus's * autoconfiguration node. We use this to detect broken chipsets * which cannot safely use memory-mapped device access. */ int pci_bus_flags() { int rval = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED | PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY; int device, maxndevs; pcitag_t tag; pcireg_t id; maxndevs = pci_bus_maxdevs(NULL, 0); for (device = 0; device < maxndevs; device++) { tag = pci_make_tag(NULL, 0, device, 0); id = pci_conf_read(NULL, tag, PCI_ID_REG); /* Invalid vendor ID value? */ if (PCI_VENDOR(id) == PCI_VENDOR_INVALID) continue; /* XXX Not invalid, but we've done this ~forever. */ if (PCI_VENDOR(id) == 0) continue; switch (PCI_VENDOR(id)) { case PCI_VENDOR_SIS: switch (PCI_PRODUCT(id)) { case PCI_PRODUCT_SIS_85C496: goto disable_mem; } break; } } return (rval); disable_mem: printf("Warning: broken PCI-Host bridge detected; " "disabling memory-mapped access\n"); rval &= ~(PCI_FLAGS_MEM_ENABLED|PCI_FLAGS_MRL_OKAY|PCI_FLAGS_MRM_OKAY| PCI_FLAGS_MWI_OKAY); return (rval); }
static int ichsmb_match(device_t parent, cfdata_t match, void *aux) { struct pci_attach_args *pa = aux; if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL) { switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_INTEL_6300ESB_SMB: case PCI_PRODUCT_INTEL_63XXESB_SMB: case PCI_PRODUCT_INTEL_82801AA_SMB: case PCI_PRODUCT_INTEL_82801AB_SMB: case PCI_PRODUCT_INTEL_82801BA_SMB: case PCI_PRODUCT_INTEL_82801CA_SMB: case PCI_PRODUCT_INTEL_82801DB_SMB: case PCI_PRODUCT_INTEL_82801E_SMB: case PCI_PRODUCT_INTEL_82801EB_SMB: case PCI_PRODUCT_INTEL_82801FB_SMB: case PCI_PRODUCT_INTEL_82801G_SMB: case PCI_PRODUCT_INTEL_82801H_SMB: case PCI_PRODUCT_INTEL_82801I_SMB: case PCI_PRODUCT_INTEL_82801JD_SMB: case PCI_PRODUCT_INTEL_82801JI_SMB: case PCI_PRODUCT_INTEL_3400_SMB: case PCI_PRODUCT_INTEL_6SERIES_SMB: case PCI_PRODUCT_INTEL_7SERIES_SMB: case PCI_PRODUCT_INTEL_8SERIES_SMB: case PCI_PRODUCT_INTEL_CORE4G_M_SMB: case PCI_PRODUCT_INTEL_BAYTRAIL_PCU_SMB: case PCI_PRODUCT_INTEL_C600_SMBUS: case PCI_PRODUCT_INTEL_C600_SMB_0: case PCI_PRODUCT_INTEL_C600_SMB_1: case PCI_PRODUCT_INTEL_C600_SMB_2: case PCI_PRODUCT_INTEL_EP80579_SMB: case PCI_PRODUCT_INTEL_DH89XXCC_SMB: case PCI_PRODUCT_INTEL_DH89XXCL_SMB: case PCI_PRODUCT_INTEL_C2000_PCU_SMBUS: return 1; } } return 0; }
static int iop_pci_match(struct device *parent, struct cfdata *match, void *aux) { struct pci_attach_args *pa; u_int product, vendor; pcireg_t reg; pa = aux; /* * Look for an "intelligent I/O processor" that adheres to the I2O * specification. Ignore the device if it doesn't support interrupt * driven operation. */ if (PCI_CLASS(pa->pa_class) == PCI_CLASS_I2O && PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_I2O_STANDARD && PCI_INTERFACE(pa->pa_class) == PCI_INTERFACE_I2O_INTRDRIVEN) return (1); /* * Match boards that don't conform exactly to the spec. */ vendor = PCI_VENDOR(pa->pa_id); product = PCI_PRODUCT(pa->pa_id); if (vendor == PCI_VENDOR_DPT && (product == PCI_PRODUCT_DPT_RAID_I2O || product == PCI_PRODUCT_DPT_RAID_2005S)) return (1); if (vendor == PCI_VENDOR_INTEL && (product == PCI_PRODUCT_INTEL_80960RM_2 || product == PCI_PRODUCT_INTEL_80960_RP)) { reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG); if (PCI_VENDOR(reg) == PCI_VENDOR_PROMISE) return (1); } return (0); }
int obio_match(device_t parent, cfdata_t cf, void *aux) { struct pci_attach_args *pa = aux; if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_APPLE) switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_APPLE_GC: case PCI_PRODUCT_APPLE_OHARE: case PCI_PRODUCT_APPLE_HEATHROW: case PCI_PRODUCT_APPLE_PADDINGTON: case PCI_PRODUCT_APPLE_KEYLARGO: case PCI_PRODUCT_APPLE_PANGEA_MACIO: case PCI_PRODUCT_APPLE_INTREPID: case PCI_PRODUCT_APPLE_K2: case PCI_PRODUCT_APPLE_SHASTA: return 1; } return 0; }
static int pchb_match(struct device *parent, struct cfdata *match, void *aux) { struct pci_attach_args *pa = aux; /* * Match all known PCI host chipsets. */ if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE && PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_HOST) { switch (PCI_VENDOR(pa->pa_id)) { case PCI_VENDOR_GALILEO: switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_GALILEO_GT64120: return (!pcifound); } break; } } return (0); }
static int fwohci_pci_match(device_t parent, cfdata_t match, void *aux) { struct pci_attach_args *pa = (struct pci_attach_args *) aux; /* * XXX * Firewire controllers used in some G3 PowerBooks hang the system * when trying to discover devices - don't attach to those for now * until someone with the right hardware can investigate */ if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_APPLE) && (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_APPLE_PBG3_FW)) return 0; if (PCI_CLASS(pa->pa_class) == PCI_CLASS_SERIALBUS && PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_SERIALBUS_FIREWIRE && PCI_INTERFACE(pa->pa_class) == PCI_INTERFACE_OHCI) return 1; return 0; }
int pci_conf_hook(pci_chipset_tag_t pc, int bus, int dev, int func, pcireg_t id) { /* ignore bogus IDs */ if (PCI_VENDOR(id) == 0) return 0; /* 2700 hardware wedges on accesses to device 6. */ if (bus == 0 && dev == 6) return 0; /* 2800 hardware wedges on accesses to device 31. */ if (bus == 0 && dev == 31) return 0; /* Don't configure the bridge and PCI probe. */ if (PCI_VENDOR(id) == PCI_VENDOR_MARVELL && PCI_PRODUCT(id) == PCI_PRODUCT_MARVELL_GT64011) return 0; /* Don't configure on-board VIA VT82C586 (pcib, uhci) */ if (bus == 0 && dev == 9 && (func == 0 || func == 2)) return 0; /* Enable viaide secondary port. Some firmware doesn't enable it. */ if (bus == 0 && dev == 9 && func == 1) { pcitag_t tag; pcireg_t csr; #define APO_VIAIDECONF (APO_VIA_REGBASE + 0x00) tag = pci_make_tag(pc, bus, dev, func); csr = pci_conf_read(pc, tag, APO_VIAIDECONF); pci_conf_write(pc, tag, APO_VIAIDECONF, csr | APO_IDECONF_EN(1)); } return PCI_CONF_DEFAULT & ~(PCI_COMMAND_SERR_ENABLE | PCI_COMMAND_PARITY_ENABLE); }
int yds_match(struct device *parent, void *match, void *aux) { struct pci_attach_args *pa = (struct pci_attach_args *) aux; switch (PCI_VENDOR(pa->pa_id)) { case PCI_VENDOR_YAMAHA: switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_YAMAHA_YMF724: case PCI_PRODUCT_YAMAHA_YMF740: case PCI_PRODUCT_YAMAHA_YMF740C: case PCI_PRODUCT_YAMAHA_YMF724F: case PCI_PRODUCT_YAMAHA_YMF744: case PCI_PRODUCT_YAMAHA_YMF754: /* 734, 737, 738?? */ return (1); } break; } return (0); }
static int yds_match(device_t parent, cfdata_t match, void *aux) { struct pci_attach_args *pa; pa = (struct pci_attach_args *)aux; switch (PCI_VENDOR(pa->pa_id)) { case PCI_VENDOR_YAMAHA: switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_YAMAHA_YMF724: case PCI_PRODUCT_YAMAHA_YMF740: case PCI_PRODUCT_YAMAHA_YMF740C: case PCI_PRODUCT_YAMAHA_YMF724F: case PCI_PRODUCT_YAMAHA_YMF744B: case PCI_PRODUCT_YAMAHA_YMF754: return 1; } break; } return 0; }
int ppbmatch(struct device *parent, void *match, void *aux) { struct pci_attach_args *pa = aux; /* * This device is mislabeled. It is not a PCI bridge. */ if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_VIATECH && PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_VIATECH_VT82C586_PWR) return (0); /* * Check the ID register to see that it's a PCI bridge. * If it is, we assume that we can deal with it; it _should_ * work in a standardized way... */ if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE && PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_PCI) return (1); return (0); }
static void scan_pci_bus(void) { pcitag_t tag; int i, x; for (i=0;i<32;i++){ tag = pci_make_tag(0, 0, i, 0); x = pci_conf_read(0, tag, 0); printf("%d tag=%08x : %08x\n", i, tag, x); #if 0 if (PCI_VENDOR(x) == PCI_VENDOR_INTEL && PCI_PRODUCT(x) == PCI_PRODUCT_INTEL_80960_RP) { /* Do not configure PCI bus analyzer */ continue; } x = pci_conf_read(0, tag, PCI_COMMAND_STATUS_REG); x |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE; pci_conf_write(0, tag, PCI_COMMAND_STATUS_REG, x); #endif } }
int gdt_pci_probe(struct device *parent, void *match, void *aux) { struct pci_attach_args *pa = aux; if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_VORTEX && ((PCI_PRODUCT(pa->pa_id) >= GDT_DEVICE_ID_MIN && PCI_PRODUCT(pa->pa_id) <= GDT_DEVICE_ID_MAX) || PCI_PRODUCT(pa->pa_id) == GDT_DEVICE_ID_NEWRX || PCI_PRODUCT(pa->pa_id) == GDT_DEVICE_ID_NEWRX2)) return (1); if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL && (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_GDT_RAID1 || PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_GDT_RAID2)) return (1); return (0); }
int kauaiatamatch(struct device *parent, void *match, void *aux) { struct pci_attach_args *pa = aux; /* * Match the adapter * XXX match routine?? */ switch(PCI_VENDOR(pa->pa_id)) { case PCI_VENDOR_APPLE: switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_APPLE_UNINORTH_ATA: case PCI_PRODUCT_APPLE_INTREPID_ATA: case PCI_PRODUCT_APPLE_INTREPID2_ATA: case PCI_PRODUCT_APPLE_K2_ATA: case PCI_PRODUCT_APPLE_SHASTA_ATA: return (1); } break; } return 0; }
static const char * iwic_find_card(const struct pci_attach_args * pa) { pcireg_t type = pa->pa_id; pcireg_t reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG); int sv = PCI_VENDOR(reg); int sd = PCI_PRODUCT(reg); struct winids *wip = win_ids; while (wip->type) { if (wip->type == type) { if (((wip->sv == -1) && (wip->sd == -1)) || ((wip->sv == sv) && (wip->sd == sd))) break; } ++wip; } if (wip->desc) return wip->desc; return 0; }
static int pci_matchbyid(lua_State *L) { struct pci_attach_args *pa; const struct pci_matchid *ids; int nent; const struct pci_matchid *pm; int i; pa = lua_touserdata(L, -3); ids = lua_touserdata(L, -2); nent = lua_tointeger(L, -1); lua_pop(L, 3); for (i = 0, pm = ids; i < nent; i++, pm++) if (PCI_VENDOR(pa->pa_id) == pm->pm_vid && PCI_PRODUCT(pa->pa_id) == pm->pm_pid) { lua_pushinteger(L, 1); return 1; } lua_pushinteger(L, 0); return 1; }
static int yds_read_codec(void *sc_, uint8_t reg, uint16_t *data) { struct yds_codec_softc *sc; sc = sc_; YWRITE2(sc->sc, AC97_CMD_ADDR, AC97_CMD_READ | AC97_ID(sc->id) | reg); if (yds_ready_codec(sc)) { aprint_error_dev(sc->sc->sc_dev, "yds_read_codec timeout\n"); return EIO; } if (PCI_PRODUCT(sc->sc->sc_id) == PCI_PRODUCT_YAMAHA_YMF744B && sc->sc->sc_revision < 2) { int i; for (i=0; i<600; i++) (void)YREAD2(sc->sc, sc->status_data); } *data = YREAD2(sc->sc, sc->status_data); return 0; }
int pci_conf_hook(void *v, int bus, int dev, int func, pcireg_t id) { /* * We need to disable devices in the Southbridge, and as * we have all the tags we need at this point, this is * where we do it. */ if (PCI_VENDOR(id) == PCI_VENDOR_ALI && PCI_PRODUCT(id) == PCI_PRODUCT_ALI_M1543) { pcitag_t tag; int status; pci_chipset_tag_t pc = (pci_chipset_tag_t) v; tag = pci_make_tag(pc, bus, dev, func); /* Undocumented magic */ /* Disable USB */ pci_conf_write_byte(pc, tag, 0x53, 0x40); pci_conf_write_byte(pc, tag, 0x52, 0x00); status = pci_conf_read_byte(pc, tag, 0x7e); pci_conf_write_byte(pc, tag, 0x7e, status & ~0x80); /* Disable modem */ pci_conf_write_byte(pc, tag, 0x77, 1 << 6); /* Disable SCI */ pci_conf_write_byte(pc, tag, 0x78, 1 << 7); } return (PCI_CONF_DEFAULT); }
int yds_read_codec(void *sc_, u_int8_t reg, u_int16_t *data) { struct yds_codec_softc *sc = sc_; YWRITE2(sc->sc, AC97_CMD_ADDR, AC97_CMD_READ | AC97_ID(sc->id) | reg); if (yds_ready_codec(sc)) { printf("%s: yds_read_codec timeout\n", sc->sc->sc_dev.dv_xname); return EIO; } if (PCI_PRODUCT(sc->sc->sc_id) == PCI_PRODUCT_YAMAHA_YMF744 && sc->sc->sc_revision < 2) { int i; for (i = 0; i < 600; i++) YREAD2(sc->sc, sc->status_data); } *data = YREAD2(sc->sc, sc->status_data); return 0; }
/*static*/ int ndis_probe_pci(device_t parent, cfdata_t match, void *aux) { struct pci_attach_args *pa = aux; int vendor = PCI_VENDOR(pa->pa_id); int product = PCI_PRODUCT(pa->pa_id); struct ndis_pci_type *t = ndis_devs; driver_object *drv = NULL; /* = windrv_lookup(0, "PCI Bus");**/ #ifdef NDIS_DBG printf("in ndis_probe_pci\n"); printf("vendor = %x, product = %x\n", vendor, product); #endif while(t->ndis_name != NULL) { #ifdef NDIS_DBG printf("t->ndis_vid = %x, t->ndis_did = %x\n", t->ndis_vid, t->ndis_did); #endif if((vendor == t->ndis_vid) && (product == t->ndis_did)) { #ifdef _MODULE ndisdrv_modevent(NULL, MOD_LOAD); //kthread_create(load_ndisdrv, NULL); #endif /* _MODULE */ drv = windrv_lookup(0, "PCI Bus"); printf("Matching vendor: %x, product: %x, name: %s\n", vendor, product, t->ndis_name); windrv_create_pdo(drv, parent); return 1; } t++; } return 0; /* dosen't match */ }
void nfe_attach(struct device *parent, struct device *self, void *aux) { struct nfe_softc *sc = (struct nfe_softc *)self; struct pci_attach_args *pa = aux; pci_chipset_tag_t pc = pa->pa_pc; pci_intr_handle_t ih; const char *intrstr; struct ifnet *ifp; bus_size_t memsize; pcireg_t memtype; memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, NFE_PCI_BA); if (pci_mapreg_map(pa, NFE_PCI_BA, memtype, 0, &sc->sc_memt, &sc->sc_memh, NULL, &memsize, 0)) { printf(": can't map mem space\n"); return; } if (pci_intr_map(pa, &ih) != 0) { printf(": can't map interrupt\n"); return; } intrstr = pci_intr_string(pc, ih); sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, nfe_intr, sc, sc->sc_dev.dv_xname); if (sc->sc_ih == NULL) { printf(": could not establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); return; } printf(": %s", intrstr); sc->sc_dmat = pa->pa_dmat; sc->sc_flags = 0; switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_NVIDIA_NFORCE3_LAN2: case PCI_PRODUCT_NVIDIA_NFORCE3_LAN3: case PCI_PRODUCT_NVIDIA_NFORCE3_LAN4: case PCI_PRODUCT_NVIDIA_NFORCE3_LAN5: sc->sc_flags |= NFE_JUMBO_SUP | NFE_HW_CSUM; break; case PCI_PRODUCT_NVIDIA_MCP51_LAN1: case PCI_PRODUCT_NVIDIA_MCP51_LAN2: sc->sc_flags |= NFE_40BIT_ADDR | NFE_PWR_MGMT; break; case PCI_PRODUCT_NVIDIA_MCP61_LAN1: case PCI_PRODUCT_NVIDIA_MCP61_LAN2: case PCI_PRODUCT_NVIDIA_MCP61_LAN3: case PCI_PRODUCT_NVIDIA_MCP61_LAN4: case PCI_PRODUCT_NVIDIA_MCP67_LAN1: case PCI_PRODUCT_NVIDIA_MCP67_LAN2: case PCI_PRODUCT_NVIDIA_MCP67_LAN3: case PCI_PRODUCT_NVIDIA_MCP67_LAN4: case PCI_PRODUCT_NVIDIA_MCP73_LAN1: case PCI_PRODUCT_NVIDIA_MCP73_LAN2: case PCI_PRODUCT_NVIDIA_MCP73_LAN3: case PCI_PRODUCT_NVIDIA_MCP73_LAN4: sc->sc_flags |= NFE_40BIT_ADDR | NFE_CORRECT_MACADDR | NFE_PWR_MGMT; break; case PCI_PRODUCT_NVIDIA_MCP77_LAN1: case PCI_PRODUCT_NVIDIA_MCP77_LAN2: case PCI_PRODUCT_NVIDIA_MCP77_LAN3: case PCI_PRODUCT_NVIDIA_MCP77_LAN4: sc->sc_flags |= NFE_40BIT_ADDR | NFE_HW_CSUM | NFE_CORRECT_MACADDR | NFE_PWR_MGMT; break; case PCI_PRODUCT_NVIDIA_MCP79_LAN1: case PCI_PRODUCT_NVIDIA_MCP79_LAN2: case PCI_PRODUCT_NVIDIA_MCP79_LAN3: case PCI_PRODUCT_NVIDIA_MCP79_LAN4: case PCI_PRODUCT_NVIDIA_MCP89_LAN: sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM | NFE_CORRECT_MACADDR | NFE_PWR_MGMT; break; case PCI_PRODUCT_NVIDIA_CK804_LAN1: case PCI_PRODUCT_NVIDIA_CK804_LAN2: case PCI_PRODUCT_NVIDIA_MCP04_LAN1: case PCI_PRODUCT_NVIDIA_MCP04_LAN2: sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM; break; case PCI_PRODUCT_NVIDIA_MCP65_LAN1: case PCI_PRODUCT_NVIDIA_MCP65_LAN2: case PCI_PRODUCT_NVIDIA_MCP65_LAN3: case PCI_PRODUCT_NVIDIA_MCP65_LAN4: sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_CORRECT_MACADDR | NFE_PWR_MGMT; break; case PCI_PRODUCT_NVIDIA_MCP55_LAN1: case PCI_PRODUCT_NVIDIA_MCP55_LAN2: sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM | NFE_HW_VLAN | NFE_PWR_MGMT; break; } if (sc->sc_flags & NFE_PWR_MGMT) { NFE_WRITE(sc, NFE_RXTX_CTL, NFE_RXTX_RESET | NFE_RXTX_BIT2); NFE_WRITE(sc, NFE_MAC_RESET, NFE_MAC_RESET_MAGIC); DELAY(100); NFE_WRITE(sc, NFE_MAC_RESET, 0); DELAY(100); NFE_WRITE(sc, NFE_RXTX_CTL, NFE_RXTX_BIT2); NFE_WRITE(sc, NFE_PWR2_CTL, NFE_READ(sc, NFE_PWR2_CTL) & ~NFE_PWR2_WAKEUP_MASK); } nfe_get_macaddr(sc, sc->sc_arpcom.ac_enaddr); printf(", address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr)); /* * Allocate Tx and Rx rings. */ if (nfe_alloc_tx_ring(sc, &sc->txq) != 0) { printf("%s: could not allocate Tx ring\n", sc->sc_dev.dv_xname); return; } if (nfe_alloc_rx_ring(sc, &sc->rxq) != 0) { printf("%s: could not allocate Rx ring\n", sc->sc_dev.dv_xname); nfe_free_tx_ring(sc, &sc->txq); return; } ifp = &sc->sc_arpcom.ac_if; ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = nfe_ioctl; ifp->if_start = nfe_start; ifp->if_watchdog = nfe_watchdog; IFQ_SET_MAXLEN(&ifp->if_snd, NFE_IFQ_MAXLEN); IFQ_SET_READY(&ifp->if_snd); strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ); ifp->if_capabilities = IFCAP_VLAN_MTU; #ifndef SMALL_KERNEL ifp->if_capabilities |= IFCAP_WOL; ifp->if_wol = nfe_wol; nfe_wol(ifp, 0); #endif #if NVLAN > 0 if (sc->sc_flags & NFE_HW_VLAN) ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING; #endif if (sc->sc_flags & NFE_HW_CSUM) { ifp->if_capabilities |= IFCAP_CSUM_IPv4 | IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4; } sc->sc_mii.mii_ifp = ifp; sc->sc_mii.mii_readreg = nfe_miibus_readreg; sc->sc_mii.mii_writereg = nfe_miibus_writereg; sc->sc_mii.mii_statchg = nfe_miibus_statchg; ifmedia_init(&sc->sc_mii.mii_media, 0, nfe_ifmedia_upd, nfe_ifmedia_sts); mii_attach(self, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, 0, 0); if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { printf("%s: no PHY found!\n", sc->sc_dev.dv_xname); ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL, 0, NULL); ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL); } else ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO); if_attach(ifp); ether_ifattach(ifp); timeout_set(&sc->sc_tick_ch, nfe_tick, sc); }
int pci_system_openbsd_create(void) { struct pci_device_private *device; int domain, bus, dev, func, ndevs, nfuncs; char path[MAXPATHLEN]; uint32_t reg; if (ndomains > 0) return 0; pci_sys = calloc(1, sizeof(struct pci_system)); if (pci_sys == NULL) return ENOMEM; pci_sys->methods = &openbsd_pci_methods; for (domain = 0; domain < sizeof(pcifd) / sizeof(pcifd[0]); domain++) { snprintf(path, sizeof(path), "/dev/pci%d", domain); pcifd[domain] = open(path, O_RDWR | O_CLOEXEC); if (pcifd[domain] == -1) { pcifd[domain] = open(path, O_RDONLY | O_CLOEXEC); if (pcifd[domain] == -1) break; } ndomains++; } if (ndomains == 0) return ENXIO; ndevs = 0; for (domain = 0; domain < ndomains; domain++) { for (bus = 0; bus < 256; bus++) { for (dev = 0; dev < 32; dev++) { nfuncs = pci_nfuncs(domain, bus, dev); for (func = 0; func < nfuncs; func++) { if (pci_read(domain, bus, dev, func, PCI_ID_REG, ®) != 0) continue; if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID || PCI_VENDOR(reg) == 0) continue; ndevs++; } } } } pci_sys->num_devices = ndevs; pci_sys->devices = calloc(ndevs, sizeof(struct pci_device_private)); if (pci_sys->devices == NULL) { free(pci_sys); pci_sys = NULL; for (domain = 0; domain < ndomains; domain++) close(pcifd[domain]); ndomains = 0; return ENOMEM; } device = pci_sys->devices; for (domain = 0; domain < ndomains; domain++) { for (bus = 0; bus < 256; bus++) { for (dev = 0; dev < 32; dev++) { nfuncs = pci_nfuncs(domain, bus, dev); for (func = 0; func < nfuncs; func++) { if (pci_read(domain, bus, dev, func, PCI_ID_REG, ®) != 0) continue; if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID || PCI_VENDOR(reg) == 0) continue; device->base.domain = domain; device->base.bus = bus; device->base.dev = dev; device->base.func = func; device->base.vendor_id = PCI_VENDOR(reg); device->base.device_id = PCI_PRODUCT(reg); if (pci_read(domain, bus, dev, func, PCI_CLASS_REG, ®) != 0) continue; device->base.device_class = PCI_INTERFACE(reg) | PCI_CLASS(reg) << 16 | PCI_SUBCLASS(reg) << 8; device->base.revision = PCI_REVISION(reg); if (pci_read(domain, bus, dev, func, PCI_SUBVEND_0, ®) != 0) continue; device->base.subvendor_id = PCI_VENDOR(reg); device->base.subdevice_id = PCI_PRODUCT(reg); device++; } } } } return 0; }
void main(int argc, char *argv[], char *bootargs_start, char *bootargs_end) { unsigned long marks[MARK_MAX]; struct brdprop *brdprop; char *new_argv[MAX_ARGS]; char *bname; ssize_t len; int err, fd, howto, i, n; printf("\n>> %s altboot, revision %s\n", bootprog_name, bootprog_rev); brdprop = brd_lookup(brdtype); printf(">> %s, cpu %u MHz, bus %u MHz, %dMB SDRAM\n", brdprop->verbose, cpuclock / 1000000, busclock / 1000000, bi_mem.memsize >> 20); nata = pcilookup(PCI_CLASS_IDE, lata, 2); if (nata == 0) nata = pcilookup(PCI_CLASS_RAID, lata, 2); if (nata == 0) nata = pcilookup(PCI_CLASS_MISCSTORAGE, lata, 2); if (nata == 0) nata = pcilookup(PCI_CLASS_SCSI, lata, 2); nnif = pcilookup(PCI_CLASS_ETH, lnif, 2); nusb = pcilookup(PCI_CLASS_USB, lusb, 3); #ifdef DEBUG if (nata == 0) printf("No IDE/SATA found\n"); else for (n = 0; n < nata; n++) { int b, d, f, bdf, pvd; bdf = lata[n].bdf; pvd = lata[n].pvd; pcidecomposetag(bdf, &b, &d, &f); printf("%04x.%04x DSK %02d:%02d:%02d\n", PCI_VENDOR(pvd), PCI_PRODUCT(pvd), b, d, f); } if (nnif == 0) printf("no NET found\n"); else for (n = 0; n < nnif; n++) { int b, d, f, bdf, pvd; bdf = lnif[n].bdf; pvd = lnif[n].pvd; pcidecomposetag(bdf, &b, &d, &f); printf("%04x.%04x NET %02d:%02d:%02d\n", PCI_VENDOR(pvd), PCI_PRODUCT(pvd), b, d, f); } if (nusb == 0) printf("no USB found\n"); else for (n = 0; n < nusb; n++) { int b, d, f, bdf, pvd; bdf = lusb[0].bdf; pvd = lusb[0].pvd; pcidecomposetag(bdf, &b, &d, &f); printf("%04x.%04x USB %02d:%02d:%02d\n", PCI_VENDOR(pvd), PCI_PRODUCT(pvd), b, d, f); } #endif pcisetup(); pcifixup(); /* * When argc is too big then it is probably a pointer, which could * indicate that we were launched as a Linux kernel module using * "bootm". */ if (argc > MAX_ARGS) { if (argv != NULL) { /* * initrd image was loaded: * check if it contains a valid altboot command line */ char *p = (char *)argv; if (strncmp(p, "altboot:", 8) == 0) { *p = 0; for (p = p + 8; *p >= ' '; p++); argc = parse_cmdline(new_argv, MAX_ARGS, ((char *)argv) + 8, p); argv = new_argv; } else argc = 0; /* boot default */ } else { /* parse standard Linux bootargs */ argc = parse_cmdline(new_argv, MAX_ARGS, bootargs_start, bootargs_end); argv = new_argv; } } /* look for a PATA drive configuration string under the arguments */ for (n = 1; n < argc; n++) { if (strncmp(argv[n], "ide:", 4) == 0 && argv[n][4] >= '0' && argv[n][4] <= '2') { drive_config = &argv[n][4]; break; } } /* intialize a disk driver */ for (i = 0, n = 0; i < nata; i++) n += dskdv_init(&lata[i]); if (n == 0) printf("IDE/SATA device driver was not found\n"); /* initialize a network interface */ for (n = 0; n < nnif; n++) if (netif_init(&lnif[n]) != 0) break; if (n >= nnif) printf("no NET device driver was found\n"); /* wait 2s for user to enter interactive mode */ for (n = 200; n >= 0; n--) { if (n % 100 == 0) printf("\rHit any key to enter interactive mode: %d", n / 100); if (tstchar()) { #ifdef DEBUG unsigned c; c = toupper(getchar()); if (c == 'C') { /* controller test terminal */ sat_test(); n = 200; continue; } else if (c == 'F') { /* find strings in Flash ROM */ findflash(); n = 200; continue; } #else (void)getchar(); #endif /* enter command line */ argv = new_argv; argc = input_cmdline(argv, MAX_ARGS); break; } delay(10000); } putchar('\n'); howto = RB_AUTOBOOT; /* default is autoboot = 0 */ /* get boot options and determine bootname */ for (n = 1; n < argc; n++) { if (strncmp(argv[n], "ide:", 4) == 0) continue; /* ignore drive configuration argument */ for (i = 0; i < sizeof(bootargs) / sizeof(bootargs[0]); i++) { if (strncasecmp(argv[n], bootargs[i].name, strlen(bootargs[i].name)) == 0) { howto |= bootargs[i].value; break; } } if (i >= sizeof(bootargs) / sizeof(bootargs[0])) break; /* break on first unknown string */ } /* * If no device name is given, we construct a list of drives * which have valid disklabels. */ if (n >= argc) { static const size_t blen = sizeof("wdN:"); n = 0; argc = 0; argv = alloc(MAX_UNITS * (sizeof(char *) + blen)); bname = (char *)(argv + MAX_UNITS); for (i = 0; i < MAX_UNITS; i++) { if (!dlabel_valid(i)) continue; snprintf(bname, blen, "wd%d:", i); argv[argc++] = bname; bname += blen; } /* use default drive if no valid disklabel is found */ if (argc == 0) { argc = 1; argv[0] = BNAME_DEFAULT; } } /* try to boot off kernel from the drive list */ while (n < argc) { bname = argv[n++]; if (check_bootname(bname) == 0) { printf("%s not a valid bootname\n", bname); continue; } if ((fd = open(bname, 0)) < 0) { if (errno == ENOENT) printf("\"%s\" not found\n", bi_path.bootpath); continue; } printf("loading \"%s\" ", bi_path.bootpath); marks[MARK_START] = 0; if (howto == -1) { /* load another altboot binary and replace ourselves */ len = read(fd, (void *)0x100000, 0x1000000 - 0x100000); if (len == -1) goto loadfail; close(fd); netif_shutdown_all(); memcpy((void *)0xf0000, newaltboot, newaltboot_end - newaltboot); __syncicache((void *)0xf0000, newaltboot_end - newaltboot); printf("Restarting...\n"); run((void *)1, argv, (void *)0x100000, (void *)len, (void *)0xf0000); } err = fdloadfile(fd, marks, LOAD_KERNEL); close(fd); if (err < 0) continue; printf("entry=%p, ssym=%p, esym=%p\n", (void *)marks[MARK_ENTRY], (void *)marks[MARK_SYM], (void *)marks[MARK_END]); bootinfo = (void *)0x4000; bi_init(bootinfo); bi_add(&bi_cons, BTINFO_CONSOLE, sizeof(bi_cons)); bi_add(&bi_mem, BTINFO_MEMORY, sizeof(bi_mem)); bi_add(&bi_clk, BTINFO_CLOCK, sizeof(bi_clk)); bi_add(&bi_path, BTINFO_BOOTPATH, sizeof(bi_path)); bi_add(&bi_rdev, BTINFO_ROOTDEVICE, sizeof(bi_rdev)); bi_add(&bi_fam, BTINFO_PRODFAMILY, sizeof(bi_fam)); if (brdtype == BRD_SYNOLOGY || brdtype == BRD_DLINKDSM) { /* need to pass this MAC address to kernel */ bi_add(&bi_net, BTINFO_NET, sizeof(bi_net)); } if (modules_enabled) { if (fsmod != NULL) module_add(fsmod); kmodloadp = marks[MARK_END]; btinfo_modulelist = NULL; module_load(bname); if (btinfo_modulelist != NULL && btinfo_modulelist->num > 0) bi_add(btinfo_modulelist, BTINFO_MODULELIST, btinfo_modulelist_size); } launchfixup(); netif_shutdown_all(); __syncicache((void *)marks[MARK_ENTRY], (u_int)marks[MARK_SYM] - (u_int)marks[MARK_ENTRY]); run((void *)marks[MARK_SYM], (void *)marks[MARK_END], (void *)howto, bootinfo, (void *)marks[MARK_ENTRY]); /* should never come here */ printf("exec returned. Restarting...\n"); _rtt(); } loadfail: printf("load failed. Restarting...\n"); _rtt(); }
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; const char *intrstr; bool ahci_cap_64bit; bool ahci_bad_64bit; pci_intr_handle_t intrhandle; 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, &sc->sc_ahcis) != 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_aprint_devinfo(pa, "AHCI disk controller"); if (pci_intr_map(pa, &intrhandle) != 0) { aprint_error_dev(self, "couldn't map interrupt\n"); return; } intrstr = pci_intr_string(pa->pa_pc, intrhandle); psc->sc_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO, ahci_intr, sc); if (psc->sc_ih == NULL) { aprint_error_dev(self, "couldn't establish interrupt\n"); return; } aprint_normal_dev(self, "interrupting at %s\n", intrstr ? intrstr : "unknown interrupt"); sc->sc_dmat = pa->pa_dmat; sc->sc_ahci_quirks = ahci_pci_has_quirk(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id)); ahci_cap_64bit = (AHCI_READ(sc, AHCI_CAP) & AHCI_CAP_64BIT) != 0; ahci_bad_64bit = ((sc->sc_ahci_quirks & AHCI_PCI_QUIRK_BAD64) != 0); if (pci_dma64_available(pa) && ahci_cap_64bit) { if (!ahci_bad_64bit) sc->sc_dmat = pa->pa_dmat64; aprint_verbose_dev(self, "64-bit DMA%s\n", (sc->sc_dmat == pa->pa_dmat) ? " unavailable" : ""); } 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"); }
void ti_pci_attach(struct device *parent, struct device *self, void *aux) { struct ti_softc *sc = (struct ti_softc *)self; struct pci_attach_args *pa = aux; pci_chipset_tag_t pc = pa->pa_pc; pci_intr_handle_t ih; const char *intrstr = NULL; bus_size_t size; /* * Map control/status registers. */ if (pci_mapreg_map(pa, TI_PCI_LOMEM, PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->ti_btag, &sc->ti_bhandle, NULL, &size, 0)) { printf(": can't map registers\n"); return; } sc->sc_dmatag = pa->pa_dmat; if (pci_intr_map(pa, &ih)) { printf(": can't map interrupt\n"); goto unmap; } intrstr = pci_intr_string(pc, ih); sc->ti_intrhand = pci_intr_establish(pc, ih, IPL_NET, ti_intr, sc, self->dv_xname); if (sc->ti_intrhand == NULL) { printf(": can't establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); goto unmap; } printf(": %s", intrstr); /* * We really need a better way to tell a 1000baseTX card * from a 1000baseSX one, since in theory there could be * OEMed 1000baseTX cards from lame vendors who aren't * clever enough to change the PCI ID. For the moment * though, the AceNIC is the only copper card available. */ if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ALTEON && PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ALTEON_ACENICT) sc->ti_copper = 1; /* Ok, it's not the only copper card available */ if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NETGEAR && PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NETGEAR_GA620T) sc->ti_copper = 1; if (ti_attach(sc) == 0) return; pci_intr_disestablish(pc, sc->ti_intrhand); unmap: bus_space_unmap(sc->ti_btag, sc->ti_bhandle, size); }
void ciss_pci_attach(struct device *parent, struct device *self, void *aux) { struct ciss_softc *sc = (struct ciss_softc *)self; struct pci_attach_args *pa = aux; bus_size_t size, cfgsz; pci_intr_handle_t ih; const char *intrstr; int cfg_bar, memtype; pcireg_t reg; memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, CISS_BAR); if (pci_mapreg_map(pa, CISS_BAR, memtype, 0, &sc->iot, &sc->ioh, NULL, &size, 0)) { printf(": can't map controller mem space\n"); return; } sc->dmat = pa->pa_dmat; sc->iem = CISS_READYENA; reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG); if (PCI_VENDOR(reg) == PCI_VENDOR_COMPAQ && (PCI_PRODUCT(reg) == PCI_PRODUCT_COMPAQ_CSA5i || PCI_PRODUCT(reg) == PCI_PRODUCT_COMPAQ_CSA532 || PCI_PRODUCT(reg) == PCI_PRODUCT_COMPAQ_CSA5312)) sc->iem = CISS_READYENAB; cfg_bar = bus_space_read_2(sc->iot, sc->ioh, CISS_CFG_BAR); sc->cfgoff = bus_space_read_4(sc->iot, sc->ioh, CISS_CFG_OFF); if (cfg_bar != CISS_BAR) { if (pci_mapreg_map(pa, cfg_bar, PCI_MAPREG_TYPE_MEM, 0, NULL, &sc->cfg_ioh, NULL, &cfgsz, 0)) { printf(": can't map controller config space\n"); bus_space_unmap(sc->iot, sc->ioh, size); return; } } else { sc->cfg_ioh = sc->ioh; cfgsz = size; } if (sc->cfgoff + sizeof(struct ciss_config) > cfgsz) { printf(": unfit config space\n"); bus_space_unmap(sc->iot, sc->ioh, size); if (cfg_bar != CISS_BAR) bus_space_unmap(sc->iot, sc->cfg_ioh, cfgsz); return; } /* disable interrupts until ready */ bus_space_write_4(sc->iot, sc->ioh, CISS_IMR, bus_space_read_4(sc->iot, sc->ioh, CISS_IMR) | sc->iem); if (pci_intr_map(pa, &ih)) { printf(": can't map interrupt\n"); bus_space_unmap(sc->iot, sc->ioh, size); if (cfg_bar != CISS_BAR) bus_space_unmap(sc->iot, sc->cfg_ioh, cfgsz); return; } intrstr = pci_intr_string(pa->pa_pc, ih); sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, ciss_intr, sc, sc->sc_dev.dv_xname); if (!sc->sc_ih) { printf(": can't establish interrupt"); if (intrstr) printf(" at %s", intrstr); printf("\n"); bus_space_unmap(sc->iot, sc->ioh, size); if (cfg_bar != CISS_BAR) bus_space_unmap(sc->iot, sc->cfg_ioh, cfgsz); } printf(": %s\n%s", intrstr, sc->sc_dev.dv_xname); if (ciss_attach(sc)) { pci_intr_disestablish(pa->pa_pc, sc->sc_ih); sc->sc_ih = NULL; bus_space_unmap(sc->iot, sc->ioh, size); if (cfg_bar != CISS_BAR) bus_space_unmap(sc->iot, sc->cfg_ioh, cfgsz); return; } /* enable interrupts now */ bus_space_write_4(sc->iot, sc->ioh, CISS_IMR, bus_space_read_4(sc->iot, sc->ioh, CISS_IMR) & ~sc->iem); }
static void virtio_attach(device_t parent, device_t self, void *aux) { struct virtio_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; int revision; pcireg_t id; char const *intrstr; pci_intr_handle_t ih; revision = PCI_REVISION(pa->pa_class); if (revision != 0) { aprint_normal(": unknown revision 0x%02x; giving up\n", revision); return; } aprint_normal("\n"); aprint_naive("\n"); /* subsystem ID shows what I am */ id = pci_conf_read(pc, tag, PCI_SUBSYS_ID_REG); aprint_normal_dev(self, "%s Virtio %s Device (rev. 0x%02x)\n", pci_findvendor(id), (PCI_PRODUCT(id)<NDEVNAMES? virtio_device_name[PCI_PRODUCT(id)]:"Unknown"), revision); sc->sc_dev = self; sc->sc_pc = pc; sc->sc_tag = tag; sc->sc_iot = pa->pa_iot; sc->sc_dmat = pa->pa_dmat; sc->sc_config_offset = VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI; if (pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_TYPE_IO, 0, &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_iosize)) { aprint_error_dev(self, "can't map i/o space\n"); return; } virtio_device_reset(sc); virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_ACK); virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER); /* XXX: use softc as aux... */ sc->sc_childdevid = PCI_PRODUCT(id); sc->sc_child = NULL; config_found(self, sc, NULL); if (sc->sc_child == NULL) { aprint_error_dev(self, "no matching child driver; not configured\n"); return; } if (sc->sc_child == (void*)1) { /* this shows error */ aprint_error_dev(self, "virtio configuration failed\n"); virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED); return; } if (pci_intr_map(pa, &ih)) { aprint_error_dev(self, "couldn't map interrupt\n"); virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED); return; } intrstr = pci_intr_string(pc, ih); sc->sc_ih = pci_intr_establish(pc, ih, sc->sc_ipl, virtio_intr, sc); if (sc->sc_ih == NULL) { aprint_error_dev(self, "couldn't establish interrupt"); if (intrstr != NULL) aprint_error(" at %s", intrstr); aprint_error("\n"); virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED); return; } aprint_normal_dev(self, "interrupting at %s\n", intrstr); virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK); return; }
static void bwi_pci_attach(device_t parent, device_t self, void *aux) { struct bwi_pci_softc *psc = device_private(self); struct pci_attach_args *pa = aux; struct bwi_softc *sc = &psc->psc_bwi; const char *intrstr = NULL; pci_intr_handle_t ih; pcireg_t memtype, reg; int error = 0; char intrbuf[PCI_INTRSTR_LEN]; aprint_naive("\n"); aprint_normal(": Broadcom Wireless\n"); sc->sc_dev = self; sc->sc_dmat = pa->pa_dmat; psc->psc_pc = pa->pa_pc; psc->psc_pcitag = pa->pa_tag; /* map control / status registers */ memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, BWI_PCI_BAR0); switch (memtype) { case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT: break; default: aprint_error_dev(self, "invalid base address register\n"); return; } if (pci_mapreg_map(pa, BWI_PCI_BAR0, memtype, 0, &sc->sc_mem_bt, &sc->sc_mem_bh, NULL, &psc->psc_mapsize) != 0) { aprint_error_dev(self, "could not map mem space\n"); return; } /* map interrupt */ if (pci_intr_map(pa, &ih) != 0) { aprint_error_dev(self, "could not map interrupt\n"); goto fail; } /* establish interrupt */ intrstr = pci_intr_string(psc->psc_pc, ih, intrbuf, sizeof(intrbuf)); sc->sc_ih = pci_intr_establish(psc->psc_pc, ih, IPL_NET, bwi_intr, sc); if (sc->sc_ih == NULL) { aprint_error_dev(self, "could not establish interrupt"); if (intrstr != NULL) aprint_error(" at %s", intrstr); aprint_error("\n"); goto fail; } aprint_normal_dev(self, "interrupting at %s\n", intrstr); /* we need to access PCI config space from the driver */ sc->sc_conf_write = bwi_pci_conf_write; sc->sc_conf_read = bwi_pci_conf_read; reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG); sc->sc_pci_revid = PCI_REVISION(pa->pa_class); sc->sc_pci_did = PCI_PRODUCT(pa->pa_id); sc->sc_pci_subvid = PCI_VENDOR(reg); sc->sc_pci_subdid = PCI_PRODUCT(reg); if (!pmf_device_register(self, bwi_suspend, bwi_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); error = bwi_attach(sc); if (error) goto fail; return; fail: if (sc->sc_ih) { pci_intr_disestablish(psc->psc_pc, sc->sc_ih); sc->sc_ih = NULL; } if (psc->psc_mapsize) { bus_space_unmap(sc->sc_mem_bt, sc->sc_mem_bh, psc->psc_mapsize); psc->psc_mapsize = 0; } return; }
/* * Attach all the sub-devices we can find */ void macobio_attach(struct device *parent, struct device *self, void *aux) { struct macobio_softc *sc = (struct macobio_softc *)self; struct pci_attach_args *pa = aux; struct confargs ca; int node, child, namelen; u_int32_t reg[20]; int32_t intr[8]; char name[32]; int need_interrupt_controller = 0; sc->sc_id = pa->pa_id; /* save of type for later */ switch (PCI_PRODUCT(pa->pa_id)) { /* XXX should not use name */ case PCI_PRODUCT_APPLE_GC: node = OF_finddevice("/bandit/gc"); need_interrupt_controller = 1; break; case PCI_PRODUCT_APPLE_OHARE: node = OF_finddevice("/bandit/ohare"); need_interrupt_controller = 1; break; case PCI_PRODUCT_APPLE_HEATHROW: case PCI_PRODUCT_APPLE_PADDINGTON: node = OF_finddevice("mac-io"); if (node == -1) node = OF_finddevice("/pci/mac-io"); if (OF_getprop(node, "assigned-addresses", reg, sizeof(reg)) == (sizeof (reg[0]) * 5)) { /* always ??? */ heathrow_FCR = mapiodev(reg[2] + HEATHROW_FCR_OFFSET, 4); } break; case PCI_PRODUCT_APPLE_KEYLARGO: case PCI_PRODUCT_APPLE_INTREPID: case PCI_PRODUCT_APPLE_PANGEA_MACIO: case PCI_PRODUCT_APPLE_SHASTA: case PCI_PRODUCT_APPLE_K2_MACIO: node = OF_finddevice("mac-io"); if (node == -1) node = OF_finddevice("/pci/mac-io"); if (OF_getprop(node, "assigned-addresses", reg, sizeof(reg)) == (sizeof (reg[0]) * 5)) sc->obiomem = mapiodev(reg[2], 0x100); break; default: printf(": unknown macobio controller\n"); return; } sc->sc_node = node; if (OF_getprop(node, "assigned-addresses", reg, sizeof(reg)) < 12) return; ca.ca_baseaddr = reg[2]; sc->sc_membus_space.bus_base = ca.ca_baseaddr; ca.ca_iot = &sc->sc_membus_space; ca.ca_dmat = pa->pa_dmat; printf("\n"); /* * This might be a hack, but it makes the interrupt controller * attach as expected if a device node existed in the OF tree. */ if (need_interrupt_controller) { /* force attachment of legacy interrupt controllers */ ca.ca_name = "legacy-interrupt-controller"; ca.ca_node = 0; ca.ca_nreg = 0; ca.ca_nintr = 0; ca.ca_reg = NULL; ca.ca_intr = NULL; config_found(self, &ca, macobio_print); } for (child = OF_child(node); child; child = OF_peer(child)) { namelen = OF_getprop(child, "name", name, sizeof(name)); if (namelen < 0) continue; if (namelen >= sizeof(name)) continue; name[namelen] = 0; ca.ca_name = name; ca.ca_node = child; ca.ca_nreg = OF_getprop(child, "reg", reg, sizeof(reg)); ca.ca_nintr = OF_getprop(child, "AAPL,interrupts", intr, sizeof(intr)); if (ca.ca_nintr == -1) ca.ca_nintr = OF_getprop(child, "interrupts", intr, sizeof(intr)); ca.ca_reg = reg; ca.ca_intr = intr; config_found(self, &ca, macobio_print); } }
void gdt_pci_attach(struct device *parent, struct device *self, void *aux) { struct pci_attach_args *pa = aux; struct gdt_softc *sc = (void *)self; bus_space_tag_t dpmemt, iomemt, iot; bus_space_handle_t dpmemh, iomemh, ioh; bus_addr_t dpmembase, iomembase, iobase; bus_size_t dpmemsize, iomemsize, iosize; u_int16_t prod; u_int32_t status = 0; #define DPMEM_MAPPED 1 #define IOMEM_MAPPED 2 #define IO_MAPPED 4 #define INTR_ESTABLISHED 8 int retries; u_int8_t protocol; pci_intr_handle_t ih; const char *intrstr; printf(": "); sc->sc_class = 0; if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_VORTEX) { prod = PCI_PRODUCT(pa->pa_id); switch (prod) { case PCI_PRODUCT_VORTEX_GDT_60x0: case PCI_PRODUCT_VORTEX_GDT_6000B: sc->sc_class = GDT_PCI; break; case PCI_PRODUCT_VORTEX_GDT_6x10: case PCI_PRODUCT_VORTEX_GDT_6x20: case PCI_PRODUCT_VORTEX_GDT_6530: case PCI_PRODUCT_VORTEX_GDT_6550: case PCI_PRODUCT_VORTEX_GDT_6x17: case PCI_PRODUCT_VORTEX_GDT_6x27: case PCI_PRODUCT_VORTEX_GDT_6537: case PCI_PRODUCT_VORTEX_GDT_6557: case PCI_PRODUCT_VORTEX_GDT_6x15: case PCI_PRODUCT_VORTEX_GDT_6x25: case PCI_PRODUCT_VORTEX_GDT_6535: case PCI_PRODUCT_VORTEX_GDT_6555: sc->sc_class = GDT_PCINEW; break; case PCI_PRODUCT_VORTEX_GDT_6x17RP: case PCI_PRODUCT_VORTEX_GDT_6x27RP: case PCI_PRODUCT_VORTEX_GDT_6537RP: case PCI_PRODUCT_VORTEX_GDT_6557RP: case PCI_PRODUCT_VORTEX_GDT_6x11RP: case PCI_PRODUCT_VORTEX_GDT_6x21RP: case PCI_PRODUCT_VORTEX_GDT_6x17RD: case PCI_PRODUCT_VORTEX_GDT_6x27RD: case PCI_PRODUCT_VORTEX_GDT_6537RD: case PCI_PRODUCT_VORTEX_GDT_6557RD: case PCI_PRODUCT_VORTEX_GDT_6x11RD: case PCI_PRODUCT_VORTEX_GDT_6x21RD: case PCI_PRODUCT_VORTEX_GDT_6x18RD: case PCI_PRODUCT_VORTEX_GDT_6x28RD: case PCI_PRODUCT_VORTEX_GDT_6x38RD: case PCI_PRODUCT_VORTEX_GDT_6x58RD: case PCI_PRODUCT_VORTEX_GDT_6518RS: case PCI_PRODUCT_VORTEX_GDT_7x18RN: case PCI_PRODUCT_VORTEX_GDT_7x28RN: case PCI_PRODUCT_VORTEX_GDT_7x38RN: case PCI_PRODUCT_VORTEX_GDT_7x58RN: case PCI_PRODUCT_VORTEX_GDT_6x19RD: case PCI_PRODUCT_VORTEX_GDT_6x29RD: case PCI_PRODUCT_VORTEX_GDT_7x19RN: case PCI_PRODUCT_VORTEX_GDT_7x29RN: case PCI_PRODUCT_VORTEX_GDT_7x43RN: sc->sc_class = GDT_MPR; } /* If we don't recognize it, determine class heuristically. */ if (sc->sc_class == 0) sc->sc_class = prod < 0x100 ? GDT_PCINEW : GDT_MPR; if (prod >= GDT_PCI_PRODUCT_FC) sc->sc_class |= GDT_FC; } else if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL) { sc->sc_class = GDT_MPR; } if (pci_mapreg_map(pa, GDT_CLASS(sc) == GDT_PCINEW ? GDT_PCINEW_DPMEM : GDT_PCI_DPMEM, PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &dpmemt, &dpmemh, &dpmembase, &dpmemsize, 0)) { if (pci_mapreg_map(pa, GDT_CLASS(sc) == GDT_PCINEW ? GDT_PCINEW_DPMEM : GDT_PCI_DPMEM, PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT_1M, 0, &dpmemt,&dpmemh, &dpmembase, &dpmemsize, 0)) { printf("cannot map DPMEM\n"); goto bail_out; } } status |= DPMEM_MAPPED; sc->sc_dpmemt = dpmemt; sc->sc_dpmemh = dpmemh; sc->sc_dpmembase = dpmembase; sc->sc_dmat = pa->pa_dmat; /* * The GDT_PCINEW series also has two other regions to map. */ if (GDT_CLASS(sc) == GDT_PCINEW) { if (pci_mapreg_map(pa, GDT_PCINEW_IOMEM, PCI_MAPREG_TYPE_MEM, 0, &iomemt, &iomemh, &iomembase, &iomemsize, 0)) { printf("can't map memory mapped i/o ports\n"); goto bail_out; } status |= IOMEM_MAPPED; if (pci_mapreg_map(pa, GDT_PCINEW_IO, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, &iobase, &iosize, 0)) { printf("can't map i/o space\n"); goto bail_out; } status |= IO_MAPPED; sc->sc_iot = iot; sc->sc_ioh = ioh; sc->sc_iobase = iobase; } switch (GDT_CLASS(sc)) { case GDT_PCI: bus_space_set_region_4(dpmemt, dpmemh, 0, 0, GDT_DPR_IF_SZ >> 2); if (bus_space_read_1(dpmemt, dpmemh, 0) != 0) { printf("can't write to DPMEM\n"); goto bail_out; } #if 0 /* disable board interrupts, deinit services */ gdth_writeb(0xff, &dp6_ptr->io.irqdel); gdth_writeb(0x00, &dp6_ptr->io.irqen); gdth_writeb(0x00, &dp6_ptr->u.ic.S_Status); gdth_writeb(0x00, &dp6_ptr->u.ic.Cmd_Index); gdth_writel(pcistr->dpmem, &dp6_ptr->u.ic.S_Info[0]); gdth_writeb(0xff, &dp6_ptr->u.ic.S_Cmd_Indx); gdth_writeb(0, &dp6_ptr->io.event); retries = INIT_RETRIES; gdth_delay(20); while (gdth_readb(&dp6_ptr->u.ic.S_Status) != 0xff) { if (--retries == 0) { printk("initialization error (DEINIT failed)\n"); gdth_munmap(ha->brd); return 0; } gdth_delay(1); } prot_ver = (unchar)gdth_readl(&dp6_ptr->u.ic.S_Info[0]); gdth_writeb(0, &dp6_ptr->u.ic.S_Status); gdth_writeb(0xff, &dp6_ptr->io.irqdel); if (prot_ver != PROTOCOL_VERSION) { printk("illegal protocol version\n"); gdth_munmap(ha->brd); return 0; } ha->type = GDT_PCI; ha->ic_all_size = sizeof(dp6_ptr->u); /* special command to controller BIOS */ gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[0]); gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[1]); gdth_writel(0x01, &dp6_ptr->u.ic.S_Info[2]); gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[3]); gdth_writeb(0xfe, &dp6_ptr->u.ic.S_Cmd_Indx); gdth_writeb(0, &dp6_ptr->io.event); retries = INIT_RETRIES; gdth_delay(20); while (gdth_readb(&dp6_ptr->u.ic.S_Status) != 0xfe) { if (--retries == 0) { printk("initialization error\n"); gdth_munmap(ha->brd); return 0; } gdth_delay(1); } gdth_writeb(0, &dp6_ptr->u.ic.S_Status); gdth_writeb(0xff, &dp6_ptr->io.irqdel); #endif sc->sc_ic_all_size = GDT_DPRAM_SZ; sc->sc_copy_cmd = gdt_pci_copy_cmd; sc->sc_get_status = gdt_pci_get_status; sc->sc_intr = gdt_pci_intr; sc->sc_release_event = gdt_pci_release_event; sc->sc_set_sema0 = gdt_pci_set_sema0; sc->sc_test_busy = gdt_pci_test_busy; break; case GDT_PCINEW: bus_space_set_region_4(dpmemt, dpmemh, 0, 0, GDT_DPR_IF_SZ >> 2); if (bus_space_read_1(dpmemt, dpmemh, 0) != 0) { printf("cannot write to DPMEM\n"); goto bail_out; } #if 0 /* disable board interrupts, deinit services */ outb(0x00,PTR2USHORT(&ha->plx->control1)); outb(0xff,PTR2USHORT(&ha->plx->edoor_reg)); gdth_writeb(0x00, &dp6c_ptr->u.ic.S_Status); gdth_writeb(0x00, &dp6c_ptr->u.ic.Cmd_Index); gdth_writel(pcistr->dpmem, &dp6c_ptr->u.ic.S_Info[0]); gdth_writeb(0xff, &dp6c_ptr->u.ic.S_Cmd_Indx); outb(1,PTR2USHORT(&ha->plx->ldoor_reg)); retries = INIT_RETRIES; gdth_delay(20); while (gdth_readb(&dp6c_ptr->u.ic.S_Status) != 0xff) { if (--retries == 0) { printk("initialization error (DEINIT failed)\n"); gdth_munmap(ha->brd); return 0; } gdth_delay(1); } prot_ver = (unchar)gdth_readl(&dp6c_ptr->u.ic.S_Info[0]); gdth_writeb(0, &dp6c_ptr->u.ic.Status); if (prot_ver != PROTOCOL_VERSION) { printk("illegal protocol version\n"); gdth_munmap(ha->brd); return 0; } ha->type = GDT_PCINEW; ha->ic_all_size = sizeof(dp6c_ptr->u); /* special command to controller BIOS */ gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[0]); gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[1]); gdth_writel(0x01, &dp6c_ptr->u.ic.S_Info[2]); gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[3]); gdth_writeb(0xfe, &dp6c_ptr->u.ic.S_Cmd_Indx); outb(1,PTR2USHORT(&ha->plx->ldoor_reg)); retries = INIT_RETRIES; gdth_delay(20); while (gdth_readb(&dp6c_ptr->u.ic.S_Status) != 0xfe) { if (--retries == 0) { printk("initialization error\n"); gdth_munmap(ha->brd); return 0; } gdth_delay(1); } gdth_writeb(0, &dp6c_ptr->u.ic.S_Status); #endif sc->sc_ic_all_size = GDT_PCINEW_SZ; sc->sc_copy_cmd = gdt_pcinew_copy_cmd; sc->sc_get_status = gdt_pcinew_get_status; sc->sc_intr = gdt_pcinew_intr; sc->sc_release_event = gdt_pcinew_release_event; sc->sc_set_sema0 = gdt_pcinew_set_sema0; sc->sc_test_busy = gdt_pcinew_test_busy; break; case GDT_MPR: bus_space_write_4(dpmemt, dpmemh, GDT_MPR_IC, GDT_MPR_MAGIC); if (bus_space_read_4(dpmemt, dpmemh, GDT_MPR_IC) != GDT_MPR_MAGIC) { printf("cannot access DPMEM at 0x%lx (shadowed?)\n", dpmembase); goto bail_out; } /* * XXX Here the Linux driver has a weird remapping logic I * don't understand. My controller does not need it, and I * cannot see what purpose it serves, therefore I did not * do anything similar. */ bus_space_set_region_4(dpmemt, dpmemh, GDT_I960_SZ, 0, GDT_DPR_IF_SZ >> 2); /* Disable everything */ bus_space_write_1(dpmemt, dpmemh, GDT_EDOOR_EN, bus_space_read_1(dpmemt, dpmemh, GDT_EDOOR_EN) | 4); bus_space_write_1(dpmemt, dpmemh, GDT_MPR_EDOOR, 0xff); bus_space_write_1(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_STATUS, 0); bus_space_write_1(dpmemt, dpmemh, GDT_MPR_IC + GDT_CMD_INDEX, 0); bus_space_write_4(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_INFO, dpmembase); bus_space_write_1(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_CMD_INDX, 0xff); bus_space_write_1(dpmemt, dpmemh, GDT_MPR_LDOOR, 1); DELAY(20); retries = GDT_RETRIES; while (bus_space_read_1(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_STATUS) != 0xff) { if (--retries == 0) { printf("DEINIT failed (status 0x%x)\n", bus_space_read_1(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_STATUS)); goto bail_out; } DELAY(1); } protocol = (u_int8_t)bus_space_read_4(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_INFO); bus_space_write_1(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_STATUS, 0); if (protocol != GDT_PROTOCOL_VERSION) { printf("unsupported protocol %d\n", protocol); goto bail_out; } /* special commnd to controller BIOS */ bus_space_write_4(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_INFO, 0); bus_space_write_4(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_INFO + sizeof (u_int32_t), 0); bus_space_write_4(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_INFO + 2 * sizeof (u_int32_t), 1); bus_space_write_4(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_INFO + 3 * sizeof (u_int32_t), 0); bus_space_write_1(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_CMD_INDX, 0xfe); bus_space_write_1(dpmemt, dpmemh, GDT_MPR_LDOOR, 1); DELAY(20); retries = GDT_RETRIES; while (bus_space_read_1(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_STATUS) != 0xfe) { if (--retries == 0) { printf("initialization error\n"); goto bail_out; } DELAY(1); } bus_space_write_1(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_STATUS, 0); sc->sc_ic_all_size = GDT_MPR_SZ; sc->sc_copy_cmd = gdt_mpr_copy_cmd; sc->sc_get_status = gdt_mpr_get_status; sc->sc_intr = gdt_mpr_intr; sc->sc_release_event = gdt_mpr_release_event; sc->sc_set_sema0 = gdt_mpr_set_sema0; sc->sc_test_busy = gdt_mpr_test_busy; } if (pci_intr_map(pa, &ih)) { printf("couldn't map interrupt\n"); goto bail_out; } intrstr = pci_intr_string(pa->pa_pc, ih); sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, gdt_intr, sc, sc->sc_dev.dv_xname); if (sc->sc_ih == NULL) { printf("couldn't establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); goto bail_out; } status |= INTR_ESTABLISHED; if (intrstr != NULL) printf("%s ", intrstr); if (gdt_attach(sc)) goto bail_out; gdt_pci_enable_intr(sc); return; bail_out: if (status & DPMEM_MAPPED) bus_space_unmap(dpmemt, dpmemh, dpmemsize); if (status & IOMEM_MAPPED) bus_space_unmap(iomemt, iomemh, iomembase); if (status & IO_MAPPED) bus_space_unmap(iot, ioh, iosize); if (status & INTR_ESTABLISHED) pci_intr_disestablish(pa->pa_pc, sc->sc_ih); return; }