void nep_attach(struct device *parent, struct device *self, void *aux) { struct nep_softc *sc = (struct nep_softc *)self; struct pci_attach_args *pa = aux; struct ifnet *ifp = &sc->sc_ac.ac_if; struct mii_data *mii = &sc->sc_mii; pcireg_t memtype; uint64_t cfg; sc->sc_dmat = pa->pa_dmat; memtype = PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT; if (pci_mapreg_map(pa, PCI_MAPREG_START, memtype, 0, &sc->sc_memt, &sc->sc_memh, NULL, &sc->sc_mems, 0)) { printf(": can't map registers\n"); return; } sc->sc_port = pa->pa_function; #ifdef __sparc64__ if (OF_getprop(PCITAG_NODE(pa->pa_tag), "local-mac-address", sc->sc_ac.ac_enaddr, ETHER_ADDR_LEN) <= 0) myetheraddr(sc->sc_ac.ac_enaddr); #endif printf(", address %s\n", ether_sprintf(sc->sc_ac.ac_enaddr)); cfg = nep_read(sc, MIF_CONFIG); cfg &= ~MIF_CONFIG_INDIRECT_MODE; nep_write(sc, MIF_CONFIG, cfg); strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, sizeof(ifp->if_xname)); ifp->if_softc = sc; ifp->if_ioctl = nep_ioctl; mii->mii_ifp = ifp; mii->mii_readreg = nep_mii_readreg; mii->mii_writereg = nep_mii_writereg; mii->mii_statchg = nep_mii_statchg; ifmedia_init(&mii->mii_media, 0, nep_mediachange, nep_mediastatus); mii_attach(&sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY, sc->sc_port, 0); ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_AUTO); if_attach(ifp); ether_ifattach(ifp); timeout_set(&sc->sc_tick_ch, nep_tick, sc); }
int gfxp_match(struct device *parent, void *cf, void *aux) { struct pci_attach_args *pa = aux; int node; char *name; node = PCITAG_NODE(pa->pa_tag); name = getpropstring(node, "name"); if (strcmp(name, "TECH-SOURCE,gfxp") == 0 || strcmp(name, "TSI,gfxp") == 0) return (10); return (0); }
static void igsfb_pci_attach(device_t parent, device_t self, void *aux) { struct igsfb_softc *sc = device_private(self); struct pci_attach_args *pa = aux; int isconsole; sc->sc_dev = self; pci_aprint_devinfo(pa, NULL); #if defined(__sparc__) && !defined(KRUPS_FORCE_SERIAL_CONSOLE) /* XXX: this doesn't belong here */ if (PCITAG_NODE(pa->pa_tag) == prom_instance_to_package(prom_stdout())) { int b, d, f; pci_decompose_tag(pa->pa_pc, pa->pa_tag, &b, &d, &f); igsfb_pci_cnattach(pa->pa_iot, pa->pa_memt, pa->pa_pc, b,d,f); } #endif isconsole = 0; if (igsfb_pci_is_console(pa->pa_pc, pa->pa_tag)) { sc->sc_dc = &igsfb_console_dc; isconsole = 1; } else { sc->sc_dc = malloc(sizeof(struct igsfb_devconfig), M_DEVBUF, M_NOWAIT | M_ZERO); if (sc->sc_dc == NULL) panic("unable to allocate igsfb_devconfig"); if (igsfb_pci_map_regs(sc->sc_dc, pa->pa_iot, pa->pa_memt, pa->pa_pc, pa->pa_tag, PCI_PRODUCT(pa->pa_id)) != 0) { printf("unable to map device registers\n"); free(sc->sc_dc, M_DEVBUF); sc->sc_dc = NULL; return; } igsfb_enable(sc->sc_dc->dc_iot, sc->sc_dc->dc_iobase, sc->sc_dc->dc_ioflags); } igsfb_attach_subr(sc, isconsole); }
void pccbb_attach_hook(struct device *parent, struct device *self, struct pci_attach_args *pa) { pci_chipset_tag_t pc = pa->pa_pc; int node = PCITAG_NODE(pa->pa_tag); int bus, busrange[2]; if (OF_getprop(OF_parent(node), "bus-range", &busrange, sizeof(busrange)) != sizeof(busrange)) return; bus = busrange[0] + 1; while (bus < 256 && pc->busnode[bus]) bus++; if (bus == 256) return; pc->busnode[bus] = node; }
void cas_attach(struct device *parent, struct device *self, void *aux) { struct pci_attach_args *pa = aux; struct cas_softc *sc = (void *)self; pci_intr_handle_t ih; #ifdef __sparc64__ /* XXX the following declarations should be elsewhere */ extern void myetheraddr(u_char *); #endif const char *intrstr = NULL; bus_size_t size; int gotenaddr = 0; sc->sc_rev = PCI_REVISION(pa->pa_class); sc->sc_dmatag = pa->pa_dmat; #define PCI_CAS_BASEADDR 0x10 if (pci_mapreg_map(pa, PCI_CAS_BASEADDR, PCI_MAPREG_TYPE_MEM, 0, &sc->sc_memt, &sc->sc_memh, NULL, &size, 0) != 0) { printf(": could not map registers\n"); return; } if (cas_pci_enaddr(sc, pa) == 0) gotenaddr = 1; #ifdef __sparc64__ if (!gotenaddr) { if (OF_getprop(PCITAG_NODE(pa->pa_tag), "local-mac-address", sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN) <= 0) myetheraddr(sc->sc_arpcom.ac_enaddr); gotenaddr = 1; } #endif #ifdef __powerpc__ if (!gotenaddr) { pci_ether_hw_addr(pa->pa_pc, sc->sc_arpcom.ac_enaddr); gotenaddr = 1; } #endif sc->sc_burst = 16; /* XXX */ if (pci_intr_map(pa, &ih) != 0) { printf(": couldn't map interrupt\n"); bus_space_unmap(sc->sc_memt, sc->sc_memh, size); return; } intrstr = pci_intr_string(pa->pa_pc, ih); sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_NET, cas_intr, sc, self->dv_xname); if (sc->sc_ih == NULL) { printf(": couldn't establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); bus_space_unmap(sc->sc_memt, sc->sc_memh, size); return; } printf(": %s", intrstr); /* * call the main configure */ cas_config(sc); }
/* * Called back during autoconfiguration for each device found */ void device_register(device_t dev, void *aux) { device_t busdev = device_parent(dev); int ofnode = 0; /* * We don't know the type of 'aux' - it depends on the * bus this device attaches to. We are only interested in * certain bus types, this only is used to find the boot * device. */ if (busdev == NULL) { /* * Ignore mainbus0 itself, it certainly is not a boot * device. */ } else if (device_is_a(busdev, "mainbus")) { struct mainbus_attach_args *ma = aux; ofnode = ma->ma_node; } else if (device_is_a(busdev, "pci")) { struct pci_attach_args *pa = aux; ofnode = PCITAG_NODE(pa->pa_tag); } else if (device_is_a(busdev, "sbus") || device_is_a(busdev, "dma") || device_is_a(busdev, "ledma")) { struct sbus_attach_args *sa = aux; ofnode = sa->sa_node; } else if (device_is_a(busdev, "ebus")) { struct ebus_attach_args *ea = aux; ofnode = ea->ea_node; } else if (device_is_a(busdev, "iic")) { struct i2c_attach_args *ia = aux; if (ia->ia_name == NULL) /* indirect config */ return; ofnode = (int)ia->ia_cookie; } else if (device_is_a(dev, "sd") || device_is_a(dev, "cd")) { struct scsipibus_attach_args *sa = aux; struct scsipi_periph *periph = sa->sa_periph; int off = 0; /* * There are two "cd" attachments: * atapibus -> atabus -> controller * scsibus -> controller * We want the node of the controller. */ if (device_is_a(busdev, "atapibus")) { busdev = device_parent(busdev); /* * if the atapibus is connected to the secondary * channel of the atabus, we need an offset of 2 * to match OF's idea of the target number. * (i.e. on U5/U10 "cdrom" and "disk2" have the * same target encoding, though different names) */ if (periph->periph_channel->chan_channel == 1) off = 2; } ofnode = device_ofnode(device_parent(busdev)); dev_path_drive_match(dev, ofnode, periph->periph_target + off, 0, periph->periph_lun); return; } else if (device_is_a(dev, "wd")) { struct ata_device *adev = aux; ofnode = device_ofnode(device_parent(busdev)); dev_path_drive_match(dev, ofnode, adev->adev_channel*2+ adev->adev_drv_data->drive, 0, 0); return; } if (busdev == NULL) return; if (ofnode != 0) { uint8_t eaddr[ETHER_ADDR_LEN]; char tmpstr[32]; char tmpstr2[32]; int node; uint32_t id = 0; uint64_t nwwn = 0, pwwn = 0; prop_dictionary_t dict; prop_data_t blob; prop_number_t pwwnd = NULL, nwwnd = NULL; prop_number_t idd = NULL; device_setofnode(dev, ofnode); dev_path_exact_match(dev, ofnode); if (OF_getprop(ofnode, "name", tmpstr, sizeof(tmpstr)) <= 0) tmpstr[0] = 0; if (OF_getprop(ofnode, "device_type", tmpstr2, sizeof(tmpstr2)) <= 0) tmpstr2[0] = 0; /* * If this is a network interface, note the * mac address. */ if (strcmp(tmpstr, "network") == 0 || strcmp(tmpstr, "ethernet") == 0 || strcmp(tmpstr2, "network") == 0 || strcmp(tmpstr2, "ethernet") == 0 || OF_getprop(ofnode, "mac-address", &eaddr, sizeof(eaddr)) >= ETHER_ADDR_LEN || OF_getprop(ofnode, "local-mac-address", &eaddr, sizeof(eaddr)) >= ETHER_ADDR_LEN) { dict = device_properties(dev); /* * Is it a network interface with FCode? */ if (strcmp(tmpstr, "network") == 0 || strcmp(tmpstr2, "network") == 0) { prop_dictionary_set_bool(dict, "without-seeprom", true); prom_getether(ofnode, eaddr); } else { if (!prom_get_node_ether(ofnode, eaddr)) goto noether; } blob = prop_data_create_data(eaddr, ETHER_ADDR_LEN); prop_dictionary_set(dict, "mac-address", blob); prop_object_release(blob); of_to_dataprop(dict, ofnode, "shared-pins", "shared-pins"); } noether: /* is this a FC node? */ if (strcmp(tmpstr, "scsi-fcp") == 0) { dict = device_properties(dev); if (OF_getprop(ofnode, "port-wwn", &pwwn, sizeof(pwwn)) == sizeof(pwwn)) { pwwnd = prop_number_create_unsigned_integer(pwwn); prop_dictionary_set(dict, "port-wwn", pwwnd); prop_object_release(pwwnd); } if (OF_getprop(ofnode, "node-wwn", &nwwn, sizeof(nwwn)) == sizeof(nwwn)) { nwwnd = prop_number_create_unsigned_integer(nwwn); prop_dictionary_set(dict, "node-wwn", nwwnd); prop_object_release(nwwnd); } } /* is this an spi device? look for scsi-initiator-id */ if (strcmp(tmpstr2, "scsi") == 0 || strcmp(tmpstr2, "scsi-2") == 0) { dict = device_properties(dev); for (node = ofnode; node != 0; node = OF_parent(node)) { if (OF_getprop(node, "scsi-initiator-id", &id, sizeof(id)) <= 0) continue; idd = prop_number_create_unsigned_integer(id); prop_dictionary_set(dict, "scsi-initiator-id", idd); prop_object_release(idd); break; } } } /* * Check for I2C busses and add data for their direct configuration. */ if (device_is_a(dev, "iic")) { int busnode = device_ofnode(busdev); if (busnode) { prop_dictionary_t props = device_properties(busdev); prop_object_t cfg = prop_dictionary_get(props, "i2c-child-devices"); if (!cfg) { int node; const char *name; /* * pmu's i2c devices are under the "i2c" node, * so find it out. */ name = prom_getpropstring(busnode, "name"); if (strcmp(name, "pmu") == 0) { for (node = OF_child(busnode); node != 0; node = OF_peer(node)) { name = prom_getpropstring(node, "name"); if (strcmp(name, "i2c") == 0) { busnode = node; break; } } } of_enter_i2c_devs(props, busnode, sizeof(cell_t)); } } /* * Add SPARCle spdmem devices (0x50 and 0x51) that the * firmware does not know about. */ if (!strcmp(machine_model, "TAD,SPARCLE")) { prop_dictionary_t props = device_properties(busdev); prop_array_t cfg = prop_array_create(); int i; DPRINTF(ACDB_PROBE, ("\nAdding spdmem for SPARCle ")); for (i = 0x50; i <= 0x51; i++) { prop_dictionary_t spd = prop_dictionary_create(); prop_dictionary_set_cstring(spd, "name", "dimm-spd"); prop_dictionary_set_uint32(spd, "addr", i); prop_dictionary_set_uint64(spd, "cookie", 0); prop_array_add(cfg, spd); prop_object_release(spd); } prop_dictionary_set(props, "i2c-child-devices", cfg); prop_object_release(cfg); } } /* set properties for PCI framebuffers */ if (device_is_a(busdev, "pci")) { /* see if this is going to be console */ struct pci_attach_args *pa = aux; prop_dictionary_t dict; int sub; int console = 0; dict = device_properties(dev); /* we only care about display devices from here on */ if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY) return; console = (ofnode == console_node); if (!console) { /* * see if any child matches since OF attaches * nodes for each head and /chosen/stdout * points to the head rather than the device * itself in this case */ sub = OF_child(ofnode); while ((sub != 0) && (sub != console_node)) { sub = OF_peer(sub); } if (sub == console_node) { console = true; } } copyprops(busdev, ofnode, dict, console); if (console) { uint64_t cmap_cb; prop_dictionary_set_uint32(dict, "instance_handle", console_instance); gfb_cb.gcc_cookie = (void *)(intptr_t)console_instance; gfb_cb.gcc_set_mapreg = of_set_palette; cmap_cb = (uint64_t)(uintptr_t)&gfb_cb; prop_dictionary_set_uint64(dict, "cmap_callback", cmap_cb); } #ifdef notyet else { int width; /* * the idea is to 'open' display devices with no useful * properties, in the hope that the firmware will * properly initialize them and we can run things like * genfb on them */ if (OF_getprop(node, "width", &width, sizeof(width)) != 4) { instance = OF_open(name); #endif } } /* * Called back after autoconfiguration of a device is done */ void device_register_post_config(device_t dev, void *aux) { if (booted_device == NULL && device_is_a(dev, "sd")) { struct scsipibus_attach_args *sa = aux; struct scsipi_periph *periph = sa->sa_periph; uint64_t wwn = 0; int ofnode; /* * If this is a FC-AL drive it will have * aquired its WWN device property by now, * so we can properly match it. */ if (prop_dictionary_get_uint64(device_properties(dev), "port-wwn", &wwn)) { /* * Different to what we do in device_register, * we do not pass the "controller" ofnode, * because FC-AL devices attach below a "fp" node, * E.g.: /pci/SUNW,qlc@4/fp@0,0/disk * and we need the parent of "disk" here. */ ofnode = device_ofnode( device_parent(device_parent(dev))); for (ofnode = OF_child(ofnode); ofnode != 0 && booted_device == NULL; ofnode = OF_peer(ofnode)) { dev_path_drive_match(dev, ofnode, periph->periph_target, wwn, periph->periph_lun); } } } } static void copyprops(device_t busdev, int node, prop_dictionary_t dict, int is_console) { device_t cntrlr; prop_dictionary_t psycho; paddr_t fbpa, mem_base = 0; uint32_t temp, fboffset; uint32_t fbaddr = 0; int options; char output_device[256]; char *pos; cntrlr = device_parent(busdev); if (cntrlr != NULL) { psycho = device_properties(cntrlr); prop_dictionary_get_uint64(psycho, "mem_base", &mem_base); } if (is_console) prop_dictionary_set_bool(dict, "is_console", 1); of_to_uint32_prop(dict, node, "width", "width"); of_to_uint32_prop(dict, node, "height", "height"); of_to_uint32_prop(dict, node, "linebytes", "linebytes"); if (!of_to_uint32_prop(dict, node, "depth", "depth") && /* Some cards have an extra space in the property name */ !of_to_uint32_prop(dict, node, "depth ", "depth")) { /* * XXX we should check linebytes vs. width but those * FBs that don't have a depth property ( /chaos/control... ) * won't have linebytes either */ prop_dictionary_set_uint32(dict, "depth", 8); } OF_getprop(node, "address", &fbaddr, sizeof(fbaddr)); if (fbaddr != 0) { pmap_extract(pmap_kernel(), fbaddr, &fbpa); #ifdef DEBUG printf("membase: %lx fbpa: %lx\n", (unsigned long)mem_base, (unsigned long)fbpa); #endif if (mem_base == 0) { /* XXX this is guesswork */ fboffset = (uint32_t)(fbpa & 0xffffffff); } fboffset = (uint32_t)(fbpa - mem_base); prop_dictionary_set_uint32(dict, "address", fboffset); } if (!of_to_dataprop(dict, node, "EDID", "EDID")) of_to_dataprop(dict, node, "edid", "EDID"); temp = 0; if (OF_getprop(node, "ATY,RefCLK", &temp, sizeof(temp)) != 4) { OF_getprop(OF_parent(node), "ATY,RefCLK", &temp, sizeof(temp)); } if (temp != 0) prop_dictionary_set_uint32(dict, "refclk", temp / 10); /* * finally, let's see if there's a video mode specified in * output-device and pass it on so drivers like radeonfb * can do their thing */ if (!is_console) return; options = OF_finddevice("/options"); if ((options == 0) || (options == -1)) return; if (OF_getprop(options, "output-device", output_device, 256) == 0) return; /* find the mode string if there is one */ pos = strstr(output_device, ":r"); if (pos == NULL) return; prop_dictionary_set_cstring(dict, "videomode", pos + 2); } static void of_set_palette(void *cookie, int index, int r, int g, int b) { int ih = (int)((intptr_t)cookie); OF_call_method_1("color!", ih, 4, r, g, b, index); }
/* * Attach the interface. Allocate softc structures, do ifmedia * setup and ethernet/BPF attach. */ void dc_pci_attach(struct device *parent, struct device *self, void *aux) { const char *intrstr = NULL; pcireg_t command; struct dc_pci_softc *psc = (struct dc_pci_softc *)self; struct dc_softc *sc = &psc->psc_softc; struct pci_attach_args *pa = aux; pci_chipset_tag_t pc = pa->pa_pc; pci_intr_handle_t ih; int found = 0; psc->psc_pc = pa->pa_pc; sc->sc_dmat = pa->pa_dmat; pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0); sc->dc_csid = pci_conf_read(pc, pa->pa_tag, PCI_SUBSYS_ID_REG); /* * Map control/status registers. */ #ifdef DC_USEIOSPACE if (pci_mapreg_map(pa, DC_PCI_CFBIO, PCI_MAPREG_TYPE_IO, 0, &sc->dc_btag, &sc->dc_bhandle, NULL, &psc->psc_mapsize, 0)) { printf(": can't map i/o space\n"); return; } #else if (pci_mapreg_map(pa, DC_PCI_CFBMA, PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->dc_btag, &sc->dc_bhandle, NULL, &psc->psc_mapsize, 0)) { printf(": can't map mem space\n"); return; } #endif /* Allocate interrupt */ if (pci_intr_map(pa, &ih)) { printf(": couldn't map interrupt\n"); goto fail_1; } intrstr = pci_intr_string(pc, ih); sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, dc_intr, sc, self->dv_xname); if (sc->sc_ih == NULL) { printf(": couldn't establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); goto fail_1; } printf(": %s", intrstr); /* Need this info to decide on a chip type. */ sc->dc_revision = PCI_REVISION(pa->pa_class); /* Get the eeprom width, if possible */ if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_LITEON && PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_LITEON_PNIC)) ; /* PNIC has non-standard eeprom */ else if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_XIRCOM && PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_XIRCOM_X3201_3_21143)) ; /* XIRCOM has non-standard eeprom */ else dc_eeprom_width(sc); switch (PCI_VENDOR(pa->pa_id)) { case PCI_VENDOR_DEC: if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DEC_21140 || PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DEC_21142) { found = 1; sc->dc_type = DC_TYPE_21143; sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR; sc->dc_flags |= DC_REDUCED_MII_POLL; dc_read_srom(sc, sc->dc_romwidth); } break; case PCI_VENDOR_INTEL: if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_21145) { found = 1; sc->dc_type = DC_TYPE_21145; sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR; sc->dc_flags |= DC_REDUCED_MII_POLL; dc_read_srom(sc, sc->dc_romwidth); } break; case PCI_VENDOR_DAVICOM: if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DAVICOM_DM9100 || PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DAVICOM_DM9102 || PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DAVICOM_DM9009) { found = 1; sc->dc_type = DC_TYPE_DM9102; sc->dc_flags |= DC_TX_COALESCE|DC_TX_INTR_ALWAYS; sc->dc_flags |= DC_REDUCED_MII_POLL|DC_TX_STORENFWD; sc->dc_flags |= DC_TX_ALIGN; sc->dc_pmode = DC_PMODE_MII; /* Increase the latency timer value. */ command = pci_conf_read(pc, pa->pa_tag, DC_PCI_CFLT); command &= 0xFFFF00FF; command |= 0x00008000; pci_conf_write(pc, pa->pa_tag, DC_PCI_CFLT, command); } break; case PCI_VENDOR_ADMTEK: case PCI_VENDOR_3COM: case PCI_VENDOR_MICROSOFT: if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ADMTEK_AL981) { found = 1; sc->dc_type = DC_TYPE_AL981; sc->dc_flags |= DC_TX_USE_TX_INTR; sc->dc_flags |= DC_TX_ADMTEK_WAR; sc->dc_pmode = DC_PMODE_MII; dc_read_srom(sc, sc->dc_romwidth); } if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ADMTEK_ADM9511 || PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ADMTEK_ADM9513 || PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ADMTEK_AN983 || PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_3COM_3CSHO100BTX || PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_MICROSOFT_MN130) { found = 1; sc->dc_type = DC_TYPE_AN983; sc->dc_flags |= DC_TX_USE_TX_INTR; sc->dc_flags |= DC_TX_ADMTEK_WAR; sc->dc_flags |= DC_64BIT_HASH; sc->dc_pmode = DC_PMODE_MII; /* Don't read SROM for - auto-loaded on reset */ } break; case PCI_VENDOR_MACRONIX: case PCI_VENDOR_ACCTON: if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ACCTON_EN2242) { found = 1; sc->dc_type = DC_TYPE_AN983; sc->dc_flags |= DC_TX_USE_TX_INTR; sc->dc_flags |= DC_TX_ADMTEK_WAR; sc->dc_flags |= DC_64BIT_HASH; sc->dc_pmode = DC_PMODE_MII; /* Don't read SROM for - auto-loaded on reset */ } if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_MACRONIX_MX98713) { found = 1; if (sc->dc_revision < DC_REVISION_98713A) sc->dc_type = DC_TYPE_98713; if (sc->dc_revision >= DC_REVISION_98713A) { sc->dc_type = DC_TYPE_98713A; sc->dc_flags |= DC_21143_NWAY; } sc->dc_flags |= DC_REDUCED_MII_POLL; sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR; } if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_MACRONIX_MX98715 || PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ACCTON_EN1217) { found = 1; if (sc->dc_revision >= DC_REVISION_98715AEC_C && sc->dc_revision < DC_REVISION_98725) sc->dc_flags |= DC_128BIT_HASH; sc->dc_type = DC_TYPE_987x5; sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR; sc->dc_flags |= DC_REDUCED_MII_POLL|DC_21143_NWAY; } if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_MACRONIX_MX98727) { found = 1; sc->dc_type = DC_TYPE_987x5; sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR; sc->dc_flags |= DC_REDUCED_MII_POLL|DC_21143_NWAY; } break; case PCI_VENDOR_COMPEX: if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_COMPEX_98713) { found = 1; if (sc->dc_revision < DC_REVISION_98713A) { sc->dc_type = DC_TYPE_98713; sc->dc_flags |= DC_REDUCED_MII_POLL; } if (sc->dc_revision >= DC_REVISION_98713A) sc->dc_type = DC_TYPE_98713A; sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR; } break; case PCI_VENDOR_LITEON: if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_LITEON_PNICII) { found = 1; sc->dc_type = DC_TYPE_PNICII; sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR; sc->dc_flags |= DC_REDUCED_MII_POLL|DC_21143_NWAY; sc->dc_flags |= DC_128BIT_HASH; } if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_LITEON_PNIC) { found = 1; sc->dc_type = DC_TYPE_PNIC; sc->dc_flags |= DC_TX_STORENFWD|DC_TX_INTR_ALWAYS; sc->dc_flags |= DC_PNIC_RX_BUG_WAR; sc->dc_pnic_rx_buf = malloc(ETHER_MAX_DIX_LEN * 5, M_DEVBUF, M_NOWAIT); if (sc->dc_pnic_rx_buf == NULL) panic("dc_pci_attach"); if (sc->dc_revision < DC_REVISION_82C169) sc->dc_pmode = DC_PMODE_SYM; } break; case PCI_VENDOR_ASIX: if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ASIX_AX88140A) { found = 1; sc->dc_type = DC_TYPE_ASIX; sc->dc_flags |= DC_TX_USE_TX_INTR|DC_TX_INTR_FIRSTFRAG; sc->dc_flags |= DC_REDUCED_MII_POLL; sc->dc_pmode = DC_PMODE_MII; } break; case PCI_VENDOR_CONEXANT: if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CONEXANT_RS7112) { found = 1; sc->dc_type = DC_TYPE_CONEXANT; sc->dc_flags |= DC_TX_INTR_ALWAYS; sc->dc_flags |= DC_REDUCED_MII_POLL; sc->dc_pmode = DC_PMODE_MII; dc_read_srom(sc, sc->dc_romwidth); } break; case PCI_VENDOR_XIRCOM: if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_XIRCOM_X3201_3_21143) { found = 1; sc->dc_type = DC_TYPE_XIRCOM; sc->dc_flags |= DC_TX_INTR_ALWAYS; sc->dc_flags |= DC_TX_COALESCE; sc->dc_flags |= DC_TX_ALIGN; sc->dc_pmode = DC_PMODE_MII; } break; } if (found == 0) { /* This shouldn't happen if probe has done its job... */ printf(": unknown device: %x:%x\n", PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id)); goto fail_2; } /* Save the cache line size. */ if (DC_IS_DAVICOM(sc)) sc->dc_cachesize = 0; else sc->dc_cachesize = pci_conf_read(pc, pa->pa_tag, DC_PCI_CFLT) & 0xFF; /* Reset the adapter. */ dc_reset(sc); /* Take 21143 out of snooze mode */ if (DC_IS_INTEL(sc) || DC_IS_XIRCOM(sc)) { command = pci_conf_read(pc, pa->pa_tag, DC_PCI_CFDD); command &= ~(DC_CFDD_SNOOZE_MODE|DC_CFDD_SLEEP_MODE); pci_conf_write(pc, pa->pa_tag, DC_PCI_CFDD, command); } /* * If we discover later (in dc_attach) that we have an * MII with no PHY, we need to have the 21143 drive the LEDs. * Except there are some systems like the NEC VersaPro NoteBook PC * which have no LEDs, and twiddling these bits has adverse effects * on them. (I.e. you suddenly can't get a link.) * * If mii_attach() returns an error, we leave the DC_TULIP_LEDS * bit set, else we clear it. Since our dc(4) driver is split into * bus-dependent and bus-independent parts, we must do set this bit * here while we are able to do PCI configuration reads. */ if (DC_IS_INTEL(sc)) { if (pci_conf_read(pc, pa->pa_tag, DC_PCI_CSID) != 0x80281033) sc->dc_flags |= DC_TULIP_LEDS; } /* * Try to learn something about the supported media. * We know that ASIX and ADMtek and Davicom devices * will *always* be using MII media, so that's a no-brainer. * The tricky ones are the Macronix/PNIC II and the * Intel 21143. */ if (DC_IS_INTEL(sc)) dc_parse_21143_srom(sc); else if (DC_IS_MACRONIX(sc) || DC_IS_PNICII(sc)) { if (sc->dc_type == DC_TYPE_98713) sc->dc_pmode = DC_PMODE_MII; else sc->dc_pmode = DC_PMODE_SYM; } else if (!sc->dc_pmode) sc->dc_pmode = DC_PMODE_MII; #ifdef __sparc64__ { extern void myetheraddr(u_char *); if (OF_getprop(PCITAG_NODE(pa->pa_tag), "local-mac-address", sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN) <= 0) myetheraddr(sc->sc_arpcom.ac_enaddr); if (sc->sc_arpcom.ac_enaddr[0] == 0x00 && sc->sc_arpcom.ac_enaddr[1] == 0x03 && sc->sc_arpcom.ac_enaddr[2] == 0xcc) sc->dc_flags |= DC_MOMENCO_BOTCH; sc->sc_hasmac = 1; } #endif #ifdef SRM_MEDIA sc->dc_srm_media = 0; /* Remember the SRM console media setting */ if (DC_IS_INTEL(sc)) { command = pci_conf_read(pc, pa->pa_tag, DC_PCI_CFDD); command &= ~(DC_CFDD_SNOOZE_MODE|DC_CFDD_SLEEP_MODE); switch ((command >> 8) & 0xff) { case 3: sc->dc_srm_media = IFM_10_T; break; case 4: sc->dc_srm_media = IFM_10_T | IFM_FDX; break; case 5: sc->dc_srm_media = IFM_100_TX; break; case 6: sc->dc_srm_media = IFM_100_TX | IFM_FDX; break; } if (sc->dc_srm_media) sc->dc_srm_media |= IFM_ACTIVE | IFM_ETHER; } #endif dc_attach(sc); return; fail_2: pci_intr_disestablish(pc, sc->sc_ih); fail_1: bus_space_unmap(sc->dc_btag, sc->dc_bhandle, psc->psc_mapsize); }
/* * Called back during autoconfiguration for each device found */ void device_register(struct device *dev, void *aux) { struct device *busdev = device_parent(dev); int ofnode; /* * We don't know the type of 'aux' - it depends on the * bus this device attaches to. We are only interested in * certain bus types, this only is used to find the boot * device. */ if (busdev == NULL) { /* * Ignore mainbus0 itself, it certainly is not a boot * device. */ } else if (device_is_a(busdev, "mainbus")) { struct mainbus_attach_args *ma = aux; device_setofnode(dev, ma->ma_node); dev_path_exact_match(dev, ma->ma_node); } else if (device_is_a(busdev, "pci")) { struct pci_attach_args *pa = aux; ofnode = PCITAG_NODE(pa->pa_tag); device_setofnode(dev, ofnode); dev_path_exact_match(dev, ofnode); } else if (device_is_a(busdev, "sbus") || device_is_a(busdev, "dma") || device_is_a(busdev, "ledma")) { struct sbus_attach_args *sa = aux; ofnode = sa->sa_node; device_setofnode(dev, ofnode); dev_path_exact_match(dev, sa->sa_node); } else if (device_is_a(dev, "sd") || device_is_a(dev, "cd")) { struct scsipibus_attach_args *sa = aux; struct scsipi_periph *periph = sa->sa_periph; /* * There are two "cd" attachments: * atapibus -> atabus -> controller * scsibus -> controller * We want the node of the controller. */ if (device_is_a(busdev, "atapibus")) busdev = device_parent(busdev); ofnode = device_ofnode(device_parent(busdev)); dev_path_drive_match(dev, ofnode, periph->periph_target, periph->periph_lun); } else if (device_is_a(dev, "wd")) { struct ata_device *adev = aux; ofnode = device_ofnode(device_parent(busdev)); dev_path_drive_match(dev, ofnode, adev->adev_channel*2+ adev->adev_drv_data->drive, 0); } /* set properties for PCI framebuffers */ if (busdev == NULL) return; if (device_is_a(busdev, "pci")) { /* see if this is going to be console */ struct pci_attach_args *pa = aux; prop_dictionary_t dict; int node, sub; int console = 0; dict = device_properties(dev); node = PCITAG_NODE(pa->pa_tag); device_setofnode(dev, node); /* we only care about display devices from here on */ if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY) return; console = (node == console_node); if (!console) { /* * see if any child matches since OF attaches * nodes for each head and /chosen/stdout * points to the head rather than the device * itself in this case */ sub = OF_child(node); while ((sub != 0) && (sub != console_node)) { sub = OF_peer(sub); } if (sub == console_node) { console = true; } } if (console) { uint64_t cmap_cb; prop_dictionary_set_uint32(dict, "instance_handle", console_instance); copyprops(busdev, console_node, dict); gfb_cb.gcc_cookie = (void *)(intptr_t)console_instance; gfb_cb.gcc_set_mapreg = of_set_palette; cmap_cb = (uint64_t)&gfb_cb; prop_dictionary_set_uint64(dict, "cmap_callback", cmap_cb); } } }
void sbbc_attach(struct device *parent, struct device *self, void *aux) { struct sbbc_softc *sc = (void *)self; struct pci_attach_args *pa = aux; struct sbbc_sram_toc *toc; bus_addr_t base; bus_size_t size; pci_intr_handle_t ih; int chosen, iosram; int i; /* XXX Don't byteswap. */ sc->sc_bbt = *pa->pa_memt; sc->sc_bbt.sasi = ASI_PRIMARY; sc->sc_iot = &sc->sc_bbt; if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, SBBC_PCI_BAR, PCI_MAPREG_TYPE_MEM, &base, &size, NULL)) { printf(": can't find register space\n"); return; } if (bus_space_map(sc->sc_iot, base + SBBC_REGS_OFFSET, SBBC_REGS_SIZE, 0, &sc->sc_regs_ioh)) { printf(": can't map register space\n"); return; } if (bus_space_map(sc->sc_iot, base + SBBC_EPLD_OFFSET, SBBC_EPLD_SIZE, 0, &sc->sc_epld_ioh)) { printf(": can't map EPLD registers\n"); goto unmap_regs; } if (bus_space_map(sc->sc_iot, base + SBBC_SRAM_OFFSET, SBBC_SRAM_SIZE, 0, &sc->sc_sram_ioh)) { printf(": can't map SRAM\n"); goto unmap_epld; } if (pci_intr_map(pa, &ih)) { printf(": unable to map interrupt\n"); goto unmap_sram; } printf(": %s\n", pci_intr_string(pa->pa_pc, ih)); sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_TTY, sbbc_intr, sc, sc->sc_dv.dv_xname); if (sc->sc_ih == NULL) { printf("%s: unable to establish interrupt\n", sc->sc_dv.dv_xname); goto unmap_sram; } bus_space_write_4(sc->sc_iot, sc->sc_regs_ioh, SBBC_PCI_INT_ENABLE, SBBC_PCI_ENABLE_INT_A); /* Check if we are the chosen one. */ chosen = OF_finddevice("/chosen"); if (OF_getprop(chosen, "iosram", &iosram, sizeof(iosram)) <= 0 || PCITAG_NODE(pa->pa_tag) != iosram) return; /* SRAM TOC offset defaults to 0. */ if (OF_getprop(chosen, "iosram-toc", &sc->sc_sram_toc, sizeof(sc->sc_sram_toc)) <= 0) sc->sc_sram_toc = 0; sc->sc_sram = bus_space_vaddr(sc->sc_iot, sc->sc_sram_ioh); toc = (struct sbbc_sram_toc *)(sc->sc_sram + sc->sc_sram_toc); for (i = 0; i < toc->toc_ntags; i++) { if (strcmp(toc->toc_tag[i].tag_key, "SOLSCIE") == 0) sc->sc_sram_solscie = (uint32_t *) (sc->sc_sram + toc->toc_tag[i].tag_offset); if (strcmp(toc->toc_tag[i].tag_key, "SOLSCIR") == 0) sc->sc_sram_solscir = (uint32_t *) (sc->sc_sram + toc->toc_tag[i].tag_offset); if (strcmp(toc->toc_tag[i].tag_key, "SCSOLIE") == 0) sc->sc_sram_scsolie = (uint32_t *) (sc->sc_sram + toc->toc_tag[i].tag_offset); if (strcmp(toc->toc_tag[i].tag_key, "SCSOLIR") == 0) sc->sc_sram_scsolir = (uint32_t *) (sc->sc_sram + toc->toc_tag[i].tag_offset); } for (i = 0; i < toc->toc_ntags; i++) { if (strcmp(toc->toc_tag[i].tag_key, "TODDATA") == 0) sbbc_attach_tod(sc, toc->toc_tag[i].tag_offset); if (strcmp(toc->toc_tag[i].tag_key, "SOLCONS") == 0) sbbc_attach_cons(sc, toc->toc_tag[i].tag_offset); } return; unmap_sram: bus_space_unmap(sc->sc_iot, sc->sc_sram_ioh, SBBC_SRAM_SIZE); unmap_epld: bus_space_unmap(sc->sc_iot, sc->sc_sram_ioh, SBBC_EPLD_SIZE); unmap_regs: bus_space_unmap(sc->sc_iot, sc->sc_sram_ioh, SBBC_REGS_SIZE); }
/** * radeon_driver_load_kms - Main load function for KMS. * * @dev: drm dev pointer * @flags: device flags * * This is the main load function for KMS (all asics). * It calls radeon_device_init() to set up the non-display * parts of the chip (asic init, CP, writeback, etc.), and * radeon_modeset_init() to set up the display parts * (crtcs, encoders, hotplug detect, etc.). * Returns 0 on success, error on failure. */ void radeondrm_attach_kms(struct device *parent, struct device *self, void *aux) { struct radeon_device *rdev = (struct radeon_device *)self; struct drm_device *dev; struct pci_attach_args *pa = aux; const struct drm_pcidev *id_entry; int is_agp; pcireg_t type; uint8_t iobar; #if defined(__sparc64__) || defined(__macppc__) extern int fbnode; #endif id_entry = drm_find_description(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id), radeondrm_pciidlist); rdev->flags = id_entry->driver_data; rdev->pc = pa->pa_pc; rdev->pa_tag = pa->pa_tag; rdev->iot = pa->pa_iot; rdev->memt = pa->pa_memt; rdev->dmat = pa->pa_dmat; #if defined(__sparc64__) || defined(__macppc__) if (fbnode == PCITAG_NODE(rdev->pa_tag)) rdev->console = 1; #else if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY && PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_DISPLAY_VGA && (pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) & (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) == (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) { rdev->console = 1; #if NVGA > 0 vga_console_attached = 1; #endif } #endif #define RADEON_PCI_MEM 0x10 #define RADEON_PCI_IO 0x14 #define RADEON_PCI_MMIO 0x18 #define RADEON_PCI_IO2 0x20 type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM); if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM || pci_mapreg_info(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM, type, &rdev->fb_aper_offset, &rdev->fb_aper_size, NULL)) { printf(": can't get frambuffer info\n"); return; } if (PCI_MAPREG_MEM_TYPE(type) != PCI_MAPREG_MEM_TYPE_64BIT) iobar = RADEON_PCI_IO; else iobar = RADEON_PCI_IO2; if (pci_mapreg_map(pa, iobar, PCI_MAPREG_TYPE_IO, 0, NULL, &rdev->rio_mem, NULL, &rdev->rio_mem_size, 0)) { printf(": can't map IO space\n"); return; } type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RADEON_PCI_MMIO); if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM || pci_mapreg_map(pa, RADEON_PCI_MMIO, type, 0, NULL, &rdev->rmmio, &rdev->rmmio_base, &rdev->rmmio_size, 0)) { printf(": can't map mmio space\n"); return; } if (pci_intr_map(pa, &rdev->intrh) != 0) { printf(": couldn't map interrupt\n"); return; } printf(": %s\n", pci_intr_string(pa->pa_pc, rdev->intrh)); #ifdef notyet mtx_init(&rdev->swi_lock, IPL_TTY); #endif /* update BUS flag */ if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL)) { rdev->flags |= RADEON_IS_AGP; } else if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PCIEXPRESS, NULL, NULL)) { rdev->flags |= RADEON_IS_PCIE; } else { rdev->flags |= RADEON_IS_PCI; } DRM_DEBUG("%s card detected\n", ((rdev->flags & RADEON_IS_AGP) ? "AGP" : (((rdev->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); is_agp = pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL); dev = (struct drm_device *)drm_attach_pci(&kms_driver, pa, is_agp, self); rdev->ddev = dev; rdev->irqh = pci_intr_establish(pa->pa_pc, rdev->intrh, IPL_TTY, radeon_driver_irq_handler_kms, rdev->ddev, rdev->dev.dv_xname); if (rdev->irqh == NULL) { printf("%s: couldn't establish interrupt\n", rdev->dev.dv_xname); return; } #ifdef __sparc64__ { struct rasops_info *ri; int node, console; node = PCITAG_NODE(pa->pa_tag); console = (fbnode == node); fb_setsize(&rdev->sf, 8, 1152, 900, node, 0); /* * The firmware sets up the framebuffer such that at starts at * an offset from the start of video memory. */ rdev->fb_offset = bus_space_read_4(rdev->memt, rdev->rmmio, RADEON_CRTC_OFFSET); if (bus_space_map(rdev->memt, rdev->fb_aper_offset + rdev->fb_offset, rdev->sf.sf_fbsize, BUS_SPACE_MAP_LINEAR, &rdev->memh)) { printf("%s: can't map video memory\n", rdev->dev.dv_xname); return; } ri = &rdev->sf.sf_ro; ri->ri_bits = bus_space_vaddr(rdev->memt, rdev->memh); ri->ri_hw = rdev; ri->ri_updatecursor = NULL; fbwscons_init(&rdev->sf, RI_VCONS | RI_WRONLY | RI_BSWAP, console); if (console) fbwscons_console_init(&rdev->sf, -1); } #endif rdev->shutdown = true; if (rootvp == NULL) mountroothook_establish(radeondrm_attachhook, rdev); else radeondrm_attachhook(rdev); }
/** * radeon_driver_load_kms - Main load function for KMS. * * @dev: drm dev pointer * @flags: device flags * * This is the main load function for KMS (all asics). * It calls radeon_device_init() to set up the non-display * parts of the chip (asic init, CP, writeback, etc.), and * radeon_modeset_init() to set up the display parts * (crtcs, encoders, hotplug detect, etc.). * Returns 0 on success, error on failure. */ void radeondrm_attach_kms(struct device *parent, struct device *self, void *aux) { struct radeon_device *rdev = (struct radeon_device *)self; struct drm_device *dev; struct pci_attach_args *pa = aux; const struct drm_pcidev *id_entry; int is_agp; pcireg_t type; uint8_t iobar; #if !defined(__sparc64__) pcireg_t addr, mask; int s; #endif #if defined(__sparc64__) || defined(__macppc__) extern int fbnode; #endif id_entry = drm_find_description(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id), radeondrm_pciidlist); rdev->flags = id_entry->driver_data; rdev->pc = pa->pa_pc; rdev->pa_tag = pa->pa_tag; rdev->iot = pa->pa_iot; rdev->memt = pa->pa_memt; rdev->dmat = pa->pa_dmat; #if defined(__sparc64__) || defined(__macppc__) if (fbnode == PCITAG_NODE(rdev->pa_tag)) rdev->console = 1; #else if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY && PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_DISPLAY_VGA && (pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) & (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) == (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) { rdev->console = 1; #if NVGA > 0 vga_console_attached = 1; #endif } #if NEFIFB > 0 if (efifb_is_console(pa)) { rdev->console = 1; efifb_cndetach(); } #endif #endif #define RADEON_PCI_MEM 0x10 #define RADEON_PCI_IO 0x14 #define RADEON_PCI_MMIO 0x18 #define RADEON_PCI_IO2 0x20 type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM); if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM || pci_mapreg_info(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM, type, &rdev->fb_aper_offset, &rdev->fb_aper_size, NULL)) { printf(": can't get frambuffer info\n"); return; } if (PCI_MAPREG_MEM_TYPE(type) != PCI_MAPREG_MEM_TYPE_64BIT) iobar = RADEON_PCI_IO; else iobar = RADEON_PCI_IO2; if (pci_mapreg_map(pa, iobar, PCI_MAPREG_TYPE_IO, 0, NULL, &rdev->rio_mem, NULL, &rdev->rio_mem_size, 0)) { printf(": can't map IO space\n"); return; } type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RADEON_PCI_MMIO); if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM || pci_mapreg_map(pa, RADEON_PCI_MMIO, type, 0, NULL, &rdev->rmmio, &rdev->rmmio_base, &rdev->rmmio_size, 0)) { printf(": can't map mmio space\n"); return; } #if !defined(__sparc64__) /* * Make sure we have a base address for the ROM such that we * can map it later. */ s = splhigh(); addr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG); pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, ~PCI_ROM_ENABLE); mask = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG); pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, addr); splx(s); if (addr == 0 && PCI_ROM_SIZE(mask) != 0 && pa->pa_memex) { bus_size_t size, start, end; bus_addr_t base; size = PCI_ROM_SIZE(mask); start = max(PCI_MEM_START, pa->pa_memex->ex_start); end = min(PCI_MEM_END, pa->pa_memex->ex_end); if (extent_alloc_subregion(pa->pa_memex, start, end, size, size, 0, 0, 0, &base) == 0) pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, base); } #endif #ifdef notyet mtx_init(&rdev->swi_lock, IPL_TTY); #endif /* update BUS flag */ if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL)) { rdev->flags |= RADEON_IS_AGP; } else if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PCIEXPRESS, NULL, NULL)) { rdev->flags |= RADEON_IS_PCIE; } else { rdev->flags |= RADEON_IS_PCI; } DRM_DEBUG("%s card detected\n", ((rdev->flags & RADEON_IS_AGP) ? "AGP" : (((rdev->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); is_agp = pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL); printf("\n"); kms_driver.num_ioctls = radeon_max_kms_ioctl; dev = (struct drm_device *)drm_attach_pci(&kms_driver, pa, is_agp, rdev->console, self); rdev->ddev = dev; rdev->pdev = dev->pdev; rdev->family = rdev->flags & RADEON_FAMILY_MASK; if (!radeon_msi_ok(rdev)) pa->pa_flags &= ~PCI_FLAGS_MSI_ENABLED; rdev->msi_enabled = 0; if (pci_intr_map_msi(pa, &rdev->intrh) == 0) rdev->msi_enabled = 1; else if (pci_intr_map(pa, &rdev->intrh) != 0) { printf(": couldn't map interrupt\n"); return; } printf("%s: %s\n", rdev->dev.dv_xname, pci_intr_string(pa->pa_pc, rdev->intrh)); rdev->irqh = pci_intr_establish(pa->pa_pc, rdev->intrh, IPL_TTY, radeon_driver_irq_handler_kms, rdev->ddev, rdev->dev.dv_xname); if (rdev->irqh == NULL) { printf("%s: couldn't establish interrupt\n", rdev->dev.dv_xname); return; } #ifdef __sparc64__ { struct rasops_info *ri; int node, console; node = PCITAG_NODE(pa->pa_tag); console = (fbnode == node); fb_setsize(&rdev->sf, 8, 1152, 900, node, 0); /* * The firmware sets up the framebuffer such that at starts at * an offset from the start of video memory. */ rdev->fb_offset = bus_space_read_4(rdev->memt, rdev->rmmio, RADEON_CRTC_OFFSET); if (bus_space_map(rdev->memt, rdev->fb_aper_offset + rdev->fb_offset, rdev->sf.sf_fbsize, BUS_SPACE_MAP_LINEAR, &rdev->memh)) { printf("%s: can't map video memory\n", rdev->dev.dv_xname); return; } ri = &rdev->sf.sf_ro; ri->ri_bits = bus_space_vaddr(rdev->memt, rdev->memh); ri->ri_hw = rdev; ri->ri_updatecursor = NULL; fbwscons_init(&rdev->sf, RI_VCONS | RI_WRONLY | RI_BSWAP, console); if (console) fbwscons_console_init(&rdev->sf, -1); } #endif rdev->shutdown = true; config_mountroot(self, radeondrm_attachhook); }
void gfxp_attach(struct device *parent, struct device *self, void *aux) { struct gfxp_softc *sc = (struct gfxp_softc *)self; struct pci_attach_args *pa = aux; struct rasops_info *ri; int node, console, flags; char *model; sc->sc_pcitag = pa->pa_tag; node = PCITAG_NODE(pa->pa_tag); console = gfxp_is_console(node); printf("\n"); model = getpropstring(node, "model"); printf("%s: %s", self->dv_xname, model); if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, PM2_PCI_MEM_LE, PCI_MAPREG_TYPE_MEM, &sc->sc_membase_le, &sc->sc_memsize_le, NULL)) sc->sc_memsize_le = 0; if (pci_mapreg_map(pa, PM2_PCI_MEM_BE, PCI_MAPREG_TYPE_MEM, BUS_SPACE_MAP_LINEAR, &sc->sc_memt, &sc->sc_memh, &sc->sc_membase_be, &sc->sc_memsize_be, 0)) { printf("\n%s: can't map video memory\n", self->dv_xname); return; } if (pci_mapreg_map(pa, PM2_PCI_MMIO, PCI_MAPREG_TYPE_MEM, 0, &sc->sc_mmiot, &sc->sc_mmioh, &sc->sc_mmiobase, &sc->sc_mmiosize, 0)) { bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_memsize_be); printf("\n%s: can't map mmio\n", self->dv_xname); return; } fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, 0); printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); ri = &sc->sc_sunfb.sf_ro; ri->ri_bits = bus_space_vaddr(sc->sc_memt, sc->sc_memh); ri->ri_hw = sc; flags = RI_BSWAP; if (sc->sc_sunfb.sf_depth == 32) { ri->ri_rnum = 8; ri->ri_rpos = 16; ri->ri_gnum = 8; ri->ri_gpos = 8; ri->ri_bnum = 8; ri->ri_bpos = 0; flags &= ~RI_BSWAP; } fbwscons_init(&sc->sc_sunfb, flags, console); fbwscons_setcolormap(&sc->sc_sunfb, gfxp_setcolor); sc->sc_mode = WSDISPLAYIO_MODE_EMUL; gfxp_init(sc); ri->ri_ops.copyrows = gfxp_copyrows; ri->ri_ops.copycols = gfxp_copycols; ri->ri_ops.eraserows = gfxp_eraserows; ri->ri_ops.erasecols = gfxp_erasecols; if (console) fbwscons_console_init(&sc->sc_sunfb, -1); fbwscons_attach(&sc->sc_sunfb, &gfxp_accessops, console); }
void gem_attach_pci(struct device *parent, struct device *self, void *aux) { struct pci_attach_args *pa = aux; struct gem_pci_softc *gsc = (void *)self; struct gem_softc *sc = &gsc->gsc_gem; pci_intr_handle_t ih; #ifdef __sparc64__ /* XXX the following declarations should be elsewhere */ extern void myetheraddr(u_char *); #endif const char *intrstr = NULL; int type, gotenaddr = 0; gsc->gsc_pc = pa->pa_pc; if (pa->pa_memt) { type = PCI_MAPREG_TYPE_MEM; sc->sc_bustag = pa->pa_memt; } else { type = PCI_MAPREG_TYPE_IO; sc->sc_bustag = pa->pa_iot; } sc->sc_dmatag = pa->pa_dmat; sc->sc_pci = 1; /* XXXXX should all be done in bus_dma. */ switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_SUN_GEMNETWORK: sc->sc_variant = GEM_SUN_GEM; break; case PCI_PRODUCT_SUN_ERINETWORK: sc->sc_variant = GEM_SUN_ERI; break; case PCI_PRODUCT_APPLE_K2_GMAC: sc->sc_variant = GEM_APPLE_K2_GMAC; break; default: sc->sc_variant = GEM_APPLE_GMAC; } #define PCI_GEM_BASEADDR 0x10 if (pci_mapreg_map(pa, PCI_GEM_BASEADDR, type, 0, &gsc->gsc_memt, &gsc->gsc_memh, NULL, &gsc->gsc_memsize, 0) != 0) { printf(": can't map registers\n"); return; } sc->sc_bustag = gsc->gsc_memt; sc->sc_h1 = gsc->gsc_memh; if (bus_space_subregion(sc->sc_bustag, sc->sc_h1, GEM_PCI_BANK2_OFFSET, GEM_PCI_BANK2_SIZE, &sc->sc_h2)) { printf(": unable to create bank 2 subregion\n"); bus_space_unmap(gsc->gsc_memt, gsc->gsc_memh, gsc->gsc_memsize); return; } if (gem_pci_enaddr(sc, pa) == 0) gotenaddr = 1; #ifdef __sparc64__ if (!gotenaddr) { if (OF_getprop(PCITAG_NODE(pa->pa_tag), "local-mac-address", sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN) <= 0) myetheraddr(sc->sc_arpcom.ac_enaddr); gotenaddr = 1; } #endif #ifdef __powerpc__ if (!gotenaddr) { pci_ether_hw_addr(pa->pa_pc, sc->sc_arpcom.ac_enaddr); gotenaddr = 1; } #endif sc->sc_burst = 16; /* XXX */ if (pci_intr_map(pa, &ih) != 0) { printf(": couldn't map interrupt\n"); bus_space_unmap(gsc->gsc_memt, gsc->gsc_memh, gsc->gsc_memsize); return; } intrstr = pci_intr_string(pa->pa_pc, ih); gsc->gsc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_NET, gem_intr, sc, self->dv_xname); if (gsc->gsc_ih == NULL) { printf(": couldn't establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); bus_space_unmap(gsc->gsc_memt, gsc->gsc_memh, gsc->gsc_memsize); return; } printf(": %s", intrstr); /* * call the main configure */ gem_config(sc); }
void mpi_pci_attach(struct device *parent, struct device *self, void *aux) { struct mpi_pci_softc *psc = (void *)self; struct mpi_softc *sc = &psc->psc_mpi; struct pci_attach_args *pa = aux; pcireg_t memtype; int r; pci_intr_handle_t ih; const char *intrstr; #ifdef __sparc64__ int node; #endif psc->psc_pc = pa->pa_pc; psc->psc_tag = pa->pa_tag; psc->psc_ih = NULL; sc->sc_dmat = pa->pa_dmat; sc->sc_ios = 0; sc->sc_target = -1; /* find the appropriate memory base */ for (r = PCI_MAPREG_START; r < PCI_MAPREG_END; r += sizeof(memtype)) { memtype = pci_mapreg_type(psc->psc_pc, psc->psc_tag, r); if ((memtype & PCI_MAPREG_TYPE_MASK) == PCI_MAPREG_TYPE_MEM) break; } if (r >= PCI_MAPREG_END) { printf(": unable to locate system interface registers\n"); return; } if (pci_mapreg_map(pa, r, memtype, 0, &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_ios, 0) != 0) { printf(": unable to map system interface registers\n"); return; } /* disable the expansion rom */ PWRITE(psc, PCI_ROM_REG, PREAD(psc, PCI_ROM_REG) & ~PCI_ROM_ENABLE); /* hook up the interrupt */ if (pci_intr_map(pa, &ih)) { printf(": unable to map interrupt\n"); goto unmap; } intrstr = pci_intr_string(psc->psc_pc, ih); psc->psc_ih = pci_intr_establish(psc->psc_pc, ih, IPL_BIO, mpi_intr, sc, sc->sc_dev.dv_xname); if (psc->psc_ih == NULL) { printf(": unable to map interrupt%s%s\n", intrstr == NULL ? "" : " at ", intrstr == NULL ? "" : intrstr); goto unmap; } printf(": %s", intrstr); if (pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ID_REG) == PCI_ID_CODE(PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_1030)) { sc->sc_flags |= MPI_F_SPI; #ifdef __sparc64__ /* * Walk up the Open Firmware device tree until we find a * "scsi-initiator-id" property. */ node = PCITAG_NODE(pa->pa_tag); while (node) { if (OF_getprop(node, "scsi-initiator-id", &sc->sc_target, sizeof(sc->sc_target)) == sizeof(sc->sc_target)) break; node = OF_parent(node); } #endif } if (mpi_attach(sc) != 0) { /* error printed by mpi_attach */ goto deintr; } return; deintr: pci_intr_disestablish(psc->psc_pc, psc->psc_ih); psc->psc_ih = NULL; unmap: bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); sc->sc_ios = 0; }