static int gem_sbus_probe(device_t dev) { if (strcmp(ofw_bus_get_name(dev), "network") == 0 && ofw_bus_get_compat(dev) != NULL && strcmp(ofw_bus_get_compat(dev), "SUNW,sbus-gem") == 0) { device_set_desc(dev, "Sun GEM Gigabit Ethernet"); return (0); } return (ENXIO); }
static int rtc_ebus_probe(device_t dev) { if (strcmp(ofw_bus_get_name(dev), "rtc") == 0) { /* The bq4802 is not supported, yet. */ if (ofw_bus_get_compat(dev) != NULL && strcmp(ofw_bus_get_compat(dev), "bq4802") == 0) return (ENXIO); device_set_desc(dev, RTC_DESC); return (0); } return (ENXIO); }
int ofw_bus_is_compatible(device_t dev, const char *onecompat) { phandle_t node; const char *compat; int len, onelen, l; if ((compat = ofw_bus_get_compat(dev)) == NULL) return (0); if ((node = ofw_bus_get_node(dev)) == -1) return (0); /* Get total 'compatible' prop len */ if ((len = OF_getproplen(node, "compatible")) <= 0) return (0); onelen = strlen(onecompat); while (len > 0) { if (strlen(compat) == onelen && strncasecmp(compat, onecompat, onelen) == 0) /* Found it. */ return (1); /* Slide to the next sub-string. */ l = strlen(compat) + 1; compat += l; len -= l; } return (0); }
static int uninorth_probe(device_t dev) { const char *type, *compatible; type = ofw_bus_get_type(dev); compatible = ofw_bus_get_compat(dev); if (type == NULL || compatible == NULL) return (ENXIO); if (strcmp(type, "pci") != 0) return (ENXIO); if (strcmp(compatible, "uni-north") == 0) { device_set_desc(dev, "Apple UniNorth Host-PCI bridge"); return (0); } else if (strcmp(compatible, "u3-agp") == 0) { device_set_desc(dev, "Apple U3 Host-AGP bridge"); return (0); } else if (strcmp(compatible, "u4-pcie") == 0) { device_set_desc(dev, "IBM CPC945 PCI Express Root"); return (0); } return (ENXIO); }
int ofw_bus_gen_child_pnpinfo_str(device_t cbdev, device_t child, char *buf, size_t buflen) { if (ofw_bus_get_name(child) != NULL) { strlcat(buf, "name=", buflen); strlcat(buf, ofw_bus_get_name(child), buflen); } if (ofw_bus_get_compat(child) != NULL) { strlcat(buf, " compat=", buflen); strlcat(buf, ofw_bus_get_compat(child), buflen); } return (0); };
/** * twl_probe - * @dev: the twl device * * Scans the FDT for a match for the device, possible compatible device * strings are; "ti,twl6030", "ti,twl6025", "ti,twl4030". * * The FDT compat string also determines the type of device (it is currently * not possible to dynamically determine the device type). * */ static int twl_probe(device_t dev) { phandle_t node; const char *compat; int len, l; struct twl_softc *sc; if ((compat = ofw_bus_get_compat(dev)) == NULL) return (ENXIO); if ((node = ofw_bus_get_node(dev)) == 0) return (ENXIO); /* Get total 'compatible' prop len */ if ((len = OF_getproplen(node, "compatible")) <= 0) return (ENXIO); sc = device_get_softc(dev); sc->sc_dev = dev; sc->sc_type = TWL_DEVICE_UNKNOWN; while (len > 0) { if (strncasecmp(compat, "ti,twl6030", 10) == 0) sc->sc_type = TWL_DEVICE_6030; else if (strncasecmp(compat, "ti,twl6025", 10) == 0) sc->sc_type = TWL_DEVICE_6025; else if (strncasecmp(compat, "ti,twl4030", 10) == 0) sc->sc_type = TWL_DEVICE_4030; if (sc->sc_type != TWL_DEVICE_UNKNOWN) break; /* Slide to the next sub-string. */ l = strlen(compat) + 1; compat += l; len -= l; } switch (sc->sc_type) { case TWL_DEVICE_4030: device_set_desc(dev, "TI TWL4030/TPS659x0 Companion IC"); break; case TWL_DEVICE_6025: device_set_desc(dev, "TI TWL6025 Companion IC"); break; case TWL_DEVICE_6030: device_set_desc(dev, "TI TWL6030 Companion IC"); break; case TWL_DEVICE_UNKNOWN: default: return (ENXIO); } return (0); }
static int schppm_probe(device_t dev) { const char* compat; compat = ofw_bus_get_compat(dev); if (compat != NULL && strcmp(ofw_bus_get_name(dev), "ppm") == 0 && strcmp(compat, "gp2-ppm") == 0) { device_set_desc(dev, "Schizo power management"); return (BUS_PROBE_DEFAULT); } return (ENXIO); }
static int ebus_nexus_probe(device_t dev) { const char* compat; compat = ofw_bus_get_compat(dev); if (compat != NULL && strcmp(ofw_bus_get_name(dev), "ebus") == 0 && strcmp(compat, "jbus-ebus") == 0) { device_set_desc(dev, "JBus-EBus bridge"); return (BUS_PROBE_GENERIC); } return (ENXIO); }
static int epic_probe(device_t dev) { const char* compat; compat = ofw_bus_get_compat(dev); if (compat != NULL && strcmp(ofw_bus_get_name(dev), "env-monitor") == 0 && strcmp(compat, "epic") == 0) { device_set_desc(dev, "Sun Fire V215/V245 LEDs"); return (BUS_PROBE_DEFAULT); } return (ENXIO); }
int ofw_bus_is_compatible_strict(device_t dev, const char *compatible) { const char *compat; if ((compat = ofw_bus_get_compat(dev)) == NULL) return (0); if (strncasecmp(compat, compatible, strlen(compatible)) == 0) return (1); return (0); }
int ofw_bus_is_compatible_strict(device_t dev, const char *compatible) { const char *compat; size_t len; if ((compat = ofw_bus_get_compat(dev)) == NULL) return (0); len = strlen(compatible); if (strlen(compat) == len && strncasecmp(compat, compatible, len) == 0) return (1); return (0); }
static int grackle_probe(device_t dev) { const char *type, *compatible; type = ofw_bus_get_type(dev); compatible = ofw_bus_get_compat(dev); if (type == NULL || compatible == NULL) return (ENXIO); if (strcmp(type, "pci") != 0 || strcmp(compatible, "grackle") != 0) return (ENXIO); device_set_desc(dev, "MPC106 (Grackle) Host-PCI bridge"); return (0); }
static int pcf_ebus_probe(device_t dev) { const char *compat; /* * We must not attach to this i2c device if this is a system with * a boot-bus controller. Additionally testing the compatibility * property will hopefully take care of this. */ if (strcmp("i2c", ofw_bus_get_name(dev)) == 0) { compat = ofw_bus_get_compat(dev); if (compat != NULL && strcmp("i2cpcf,8584", compat) == 0) { device_set_desc(dev, "PCF8584 I2C bus controller"); return (0); } } return (ENXIO); }
int ofw_bus_is_compatible(device_t dev, const char *onecompat) { phandle_t node; const char *compat; int len; if ((compat = ofw_bus_get_compat(dev)) == NULL) return (0); if ((node = ofw_bus_get_node(dev)) == -1) return (0); /* Get total 'compatible' prop len */ if ((len = OF_getproplen(node, "compatible")) <= 0) return (0); return (ofw_bus_node_is_compatible(compat, len, onecompat)); }
static int scc_ebus_probe(device_t dev) { struct scc_softc *sc; const char *cmpt, *nm; sc = device_get_softc(dev); nm = ofw_bus_get_name(dev); cmpt = ofw_bus_get_compat(dev); if (cmpt == NULL) cmpt = ""; if (!strcmp(nm, "se") || !strcmp(nm, "FJSV,se") || !strcmp(cmpt, "sab82532")) { device_set_desc(dev, "Siemens SAB 82532 dual channel SCC"); sc->sc_class = &scc_sab82532_class; return (scc_bfe_probe(dev, EBUS_REGSHFT, EBUS_RCLK, 0)); } return (ENXIO); }
static int uart_ebus_probe(device_t dev) { const char *nm, *cmpt; struct uart_softc *sc; struct uart_devinfo dummy; sc = device_get_softc(dev); sc->sc_class = NULL; nm = ofw_bus_get_name(dev); cmpt = ofw_bus_get_compat(dev); if (cmpt == NULL) cmpt = ""; if (!strcmp(nm, "lom-console") || !strcmp(nm, "su") || !strcmp(nm, "su_pnp") || !strcmp(cmpt, "rsc-console") || !strcmp(cmpt, "rsc-control") || !strcmp(cmpt, "su") || !strcmp(cmpt, "su16550")) { /* * On AXi and AXmp boards the NS16550 (used to connect * keyboard/mouse) share their IRQ lines with the i8042. * Any IRQ activity (typically during attach) of the * NS16550 used to connect the keyboard when actually the * PS/2 keyboard is selected in OFW causes interaction * with the OBP i8042 driver resulting in a hang and vice * versa. As RS232 keyboards and mice obviously aren't * meant to be used in parallel with PS/2 ones on these * boards don't attach to the NS16550 in case the RS232 * keyboard isn't selected in order to prevent such hangs. */ if ((!strcmp(sparc64_model, "SUNW,UltraAX-MP") || !strcmp(sparc64_model, "SUNW,UltraSPARC-IIi-Engine")) && uart_cpu_getdev(UART_DEV_KEYBOARD, &dummy)) { device_disable(dev); return (ENXIO); } sc->sc_class = &uart_ns8250_class; return (uart_bus_probe(dev, 0, 0, 0, 0)); } return (ENXIO); }
static void simplebus_probe_nomatch(device_t bus, device_t child) { const char *name, *type, *compat; if (!bootverbose) return; compat = ofw_bus_get_compat(child); if (compat == NULL) return; name = ofw_bus_get_name(child); type = ofw_bus_get_type(child); device_printf(bus, "<%s>", name != NULL ? name : "unknown"); simplebus_print_res(device_get_ivars(child)); if (!ofw_bus_status_okay(child)) printf(" disabled"); if (type) printf(" type %s", type); printf(" compat %s (no driver attached)\n", compat); }
static int onyx_probe(device_t dev) { const char *name, *compat; name = ofw_bus_get_name(dev); if (name == NULL) return (ENXIO); if (strcmp(name, "codec") == 0) { if (iicbus_get_addr(dev) != PCM3052_IICADDR) return (ENXIO); } else if (strcmp(name, "codec") == 0) { compat = ofw_bus_get_compat(dev); if (compat == NULL || strcmp(compat, "pcm3052") != 0) return (ENXIO); } else return (ENXIO); device_set_desc(dev, "Texas Instruments PCM3052 Audio Codec"); return (0); }
static int snapper_probe(device_t dev) { const char *name, *compat; name = ofw_bus_get_name(dev); if (name == NULL) return (ENXIO); if (strcmp(name, "deq") == 0) { if (iicbus_get_addr(dev) != SNAPPER_IICADDR) return (ENXIO); } else if (strcmp(name, "codec") == 0) { compat = ofw_bus_get_compat(dev); if (compat == NULL || strcmp(compat, "tas3004") != 0) return (ENXIO); } else { return (ENXIO); } device_set_desc(dev, "Texas Instruments TAS3004 Audio Codec"); return (0); }
static int uninorth_attach(device_t dev) { struct uninorth_softc *sc; const char *compatible; phandle_t node; uint32_t reg[3]; uint64_t regbase; cell_t acells; node = ofw_bus_get_node(dev); sc = device_get_softc(dev); if (OF_getprop(node, "reg", reg, sizeof(reg)) < 8) return (ENXIO); sc->sc_ver = 0; compatible = ofw_bus_get_compat(dev); if (strcmp(compatible, "u3-agp") == 0) sc->sc_ver = 3; if (strcmp(compatible, "u4-pcie") == 0) sc->sc_ver = 4; acells = 1; OF_getprop(OF_parent(node), "#address-cells", &acells, sizeof(acells)); regbase = reg[0]; if (acells == 2) { regbase <<= 32; regbase |= reg[1]; } sc->sc_addr = (vm_offset_t)pmap_mapdev(regbase + 0x800000, PAGE_SIZE); sc->sc_data = (vm_offset_t)pmap_mapdev(regbase + 0xc00000, PAGE_SIZE); return (ofw_pci_attach(dev)); }
/* * PCI attach: scan Open Firmware child nodes, and attach these as children * of the macio bus */ static int macio_attach(device_t dev) { struct macio_softc *sc; struct macio_devinfo *dinfo; phandle_t root; phandle_t child; phandle_t subchild; device_t cdev; u_int reg[3]; char compat[32]; int error, quirks; sc = device_get_softc(dev); root = sc->sc_node = ofw_bus_get_node(dev); /* * Locate the device node and it's base address */ if (OF_getprop(root, "assigned-addresses", reg, sizeof(reg)) < (ssize_t)sizeof(reg)) { return (ENXIO); } /* Used later to see if we have to enable the I2S part. */ OF_getprop(root, "compatible", compat, sizeof(compat)); sc->sc_base = reg[2]; sc->sc_size = MACIO_REG_SIZE; sc->sc_memrid = PCIR_BAR(0); sc->sc_memr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_memrid, RF_ACTIVE); sc->sc_mem_rman.rm_type = RMAN_ARRAY; sc->sc_mem_rman.rm_descr = "MacIO Device Memory"; error = rman_init(&sc->sc_mem_rman); if (error) { device_printf(dev, "rman_init() failed. error = %d\n", error); return (error); } error = rman_manage_region(&sc->sc_mem_rman, 0, sc->sc_size); if (error) { device_printf(dev, "rman_manage_region() failed. error = %d\n", error); return (error); } /* * Iterate through the sub-devices */ for (child = OF_child(root); child != 0; child = OF_peer(child)) { dinfo = malloc(sizeof(*dinfo), M_MACIO, M_WAITOK | M_ZERO); if (ofw_bus_gen_setup_devinfo(&dinfo->mdi_obdinfo, child) != 0) { free(dinfo, M_MACIO); continue; } quirks = macio_get_quirks(dinfo->mdi_obdinfo.obd_name); if ((quirks & MACIO_QUIRK_IGNORE) != 0) { ofw_bus_gen_destroy_devinfo(&dinfo->mdi_obdinfo); free(dinfo, M_MACIO); continue; } resource_list_init(&dinfo->mdi_resources); dinfo->mdi_ninterrupts = 0; macio_add_intr(child, dinfo); if ((quirks & MACIO_QUIRK_USE_CHILD_REG) != 0) macio_add_reg(OF_child(child), dinfo); else macio_add_reg(child, dinfo); if ((quirks & MACIO_QUIRK_CHILD_HAS_INTR) != 0) for (subchild = OF_child(child); subchild != 0; subchild = OF_peer(subchild)) macio_add_intr(subchild, dinfo); cdev = device_add_child(dev, NULL, -1); if (cdev == NULL) { device_printf(dev, "<%s>: device_add_child failed\n", dinfo->mdi_obdinfo.obd_name); resource_list_free(&dinfo->mdi_resources); ofw_bus_gen_destroy_devinfo(&dinfo->mdi_obdinfo); free(dinfo, M_MACIO); continue; } device_set_ivars(cdev, dinfo); /* Set FCRs to enable some devices */ if (sc->sc_memr == NULL) continue; if (strcmp(ofw_bus_get_name(cdev), "bmac") == 0 || strcmp(ofw_bus_get_compat(cdev), "bmac+") == 0) { uint32_t fcr; fcr = bus_read_4(sc->sc_memr, HEATHROW_FCR); fcr |= FCR_ENET_ENABLE & ~FCR_ENET_RESET; bus_write_4(sc->sc_memr, HEATHROW_FCR, fcr); DELAY(50000); fcr |= FCR_ENET_RESET; bus_write_4(sc->sc_memr, HEATHROW_FCR, fcr); DELAY(50000); fcr &= ~FCR_ENET_RESET; bus_write_4(sc->sc_memr, HEATHROW_FCR, fcr); DELAY(50000); bus_write_4(sc->sc_memr, HEATHROW_FCR, fcr); } /* * Make sure the I2S0 and the I2S0_CLK are enabled. * On certain G5's they are not. */ if ((strcmp(ofw_bus_get_name(cdev), "i2s") == 0) && (strcmp(compat, "K2-Keylargo") == 0)) { uint32_t fcr1; fcr1 = bus_read_4(sc->sc_memr, KEYLARGO_FCR1); fcr1 |= FCR1_I2S0_CLK_ENABLE | FCR1_I2S0_ENABLE; bus_write_4(sc->sc_memr, KEYLARGO_FCR1, fcr1); } } return (bus_generic_attach(dev)); }
static int ata_kauai_probe(device_t dev) { struct ata_channel *ch; struct ata_kauai_softc *sc; u_int32_t devid; phandle_t node; const char *compatstring = NULL; int i, found, rid; found = 0; devid = pci_get_devid(dev); for (i = 0; kauai_pci_devlist[i].kpd_desc != NULL; i++) { if (devid == kauai_pci_devlist[i].kpd_devid) { found = 1; device_set_desc(dev, kauai_pci_devlist[i].kpd_desc); } } if (!found) return (ENXIO); node = ofw_bus_get_node(dev); sc = device_get_softc(dev); bzero(sc, sizeof(struct ata_kauai_softc)); ch = &sc->sc_ch.sc_ch; compatstring = ofw_bus_get_compat(dev); if (compatstring != NULL && strcmp(compatstring,"shasta-ata") == 0) sc->shasta = 1; /* Pre-K2 controllers apparently need this hack */ if (!sc->shasta && (compatstring == NULL || strcmp(compatstring, "K2-UATA") != 0)) bus_set_resource(dev, SYS_RES_IRQ, 0, 39, 1); rid = PCIR_BARS; sc->sc_memr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (sc->sc_memr == NULL) { device_printf(dev, "could not allocate memory\n"); return (ENXIO); } /* * Set up the resource vectors */ for (i = ATA_DATA; i <= ATA_COMMAND; i++) { ch->r_io[i].res = sc->sc_memr; ch->r_io[i].offset = i*ATA_KAUAI_REGGAP + ATA_KAUAI_REGOFFSET; } ch->r_io[ATA_CONTROL].res = sc->sc_memr; ch->r_io[ATA_CONTROL].offset = ATA_KAUAI_ALTOFFSET; ata_default_registers(dev); ch->unit = 0; ch->flags |= ATA_USE_16BIT; /* XXX: ATAPI DMA is unreliable. We should find out why. */ ch->flags |= ATA_NO_ATAPI_DMA; ata_generic_hw(dev); return (ata_probe(dev)); }