/* * drm_probe_helper: called by a driver at the end of its probe * method. */ int drm_probe_helper(device_t kdev, drm_pci_id_list_t *idlist) { drm_pci_id_list_t *id_entry; int vendor, device; vendor = pci_get_vendor(kdev); device = pci_get_device(kdev); if (pci_get_class(kdev) != PCIC_DISPLAY || (pci_get_subclass(kdev) != PCIS_DISPLAY_VGA && pci_get_subclass(kdev) != PCIS_DISPLAY_OTHER)) return (-ENXIO); id_entry = drm_find_description(vendor, device, idlist); if (id_entry != NULL) { if (device_get_desc(kdev) == NULL) { DRM_DEBUG("%s desc: %s\n", device_get_nameunit(kdev), id_entry->name); device_set_desc(kdev, id_entry->name); } return (0); } return (-ENXIO); }
int proto_attach(device_t dev) { struct proto_softc *sc; struct proto_res *r; u_int res; sc = device_get_softc(dev); sc->sc_dev = dev; for (res = 0; res < sc->sc_rescnt; res++) { r = sc->sc_res + res; switch (r->r_type) { case SYS_RES_IRQ: /* XXX TODO */ break; case SYS_RES_DRQ: break; case SYS_RES_MEMORY: case SYS_RES_IOPORT: r->r_size = rman_get_size(r->r_d.res); r->r_u.cdev = make_dev(&proto_devsw, res, 0, 0, 0666, "proto/%s/%02x.%s", device_get_desc(dev), r->r_rid, (r->r_type == SYS_RES_IOPORT) ? "io" : "mem"); r->r_u.cdev->si_drv1 = sc; r->r_u.cdev->si_drv2 = r; break; case PROTO_RES_PCICFG: r->r_size = 4096; r->r_u.cdev = make_dev(&proto_devsw, res, 0, 0, 0666, "proto/%s/pcicfg", device_get_desc(dev)); r->r_u.cdev->si_drv1 = sc; r->r_u.cdev->si_drv2 = r; break; case PROTO_RES_BUSDMA: r->r_d.busdma = proto_busdma_attach(sc); r->r_size = 0; /* no read(2) nor write(2) */ r->r_u.cdev = make_dev(&proto_devsw, res, 0, 0, 0666, "proto/%s/busdma", device_get_desc(dev)); r->r_u.cdev->si_drv1 = sc; r->r_u.cdev->si_drv2 = r; break; } } return (0); }
int scc_bfe_probe(device_t dev, u_int regshft, u_int rclk, u_int rid) { struct scc_softc *sc; struct scc_class *cl; u_long size, sz; int error; /* * Initialize the instance. Note that the instance (=softc) does * not necessarily match the hardware specific softc. We can't do * anything about it now, because we may not attach to the device. * Hardware drivers cannot use any of the class specific fields * while probing. */ sc = device_get_softc(dev); cl = sc->sc_class; kobj_init((kobj_t)sc, (kobj_class_t)cl); sc->sc_dev = dev; if (device_get_desc(dev) == NULL) device_set_desc(dev, cl->name); size = abs(cl->cl_range) << regshft; /* * Allocate the register resource. We assume that all SCCs have a * single register window in either I/O port space or memory mapped * I/O space. Any SCC that needs multiple windows will consequently * not be supported by this driver as-is. */ sc->sc_rrid = rid; sc->sc_rtype = SYS_RES_MEMORY; sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype, &sc->sc_rrid, 0, ~0, cl->cl_channels * size, RF_ACTIVE); if (sc->sc_rres == NULL) { sc->sc_rrid = rid; sc->sc_rtype = SYS_RES_IOPORT; sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype, &sc->sc_rrid, 0, ~0, cl->cl_channels * size, RF_ACTIVE); if (sc->sc_rres == NULL) return (ENXIO); } /* * Fill in the bus access structure and call the hardware specific * probe method. */ sz = (size != 0) ? size : rman_get_size(sc->sc_rres); sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres); sc->sc_bas.bst = rman_get_bustag(sc->sc_rres); sc->sc_bas.range = sz; sc->sc_bas.rclk = rclk; sc->sc_bas.regshft = regshft; error = SCC_PROBE(sc); bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres); return ((error == 0) ? BUS_PROBE_DEFAULT : error); }
int proto_probe(device_t dev, const char *prefix, char ***devnamesp) { char **devnames = *devnamesp; const char *dn, *ep, *ev; size_t pfxlen; int idx, names; if (devnames == NULL) { pfxlen = strlen(prefix); names = 1; /* NULL pointer */ ev = kern_getenv("hw.proto.attach"); if (ev != NULL) { dn = ev; while (*dn != '\0') { ep = dn; while (*ep != ',' && *ep != '\0') ep++; if ((ep - dn) > pfxlen && strncmp(dn, prefix, pfxlen) == 0) names++; dn = (*ep == ',') ? ep + 1 : ep; } } devnames = malloc(names * sizeof(caddr_t), M_DEVBUF, M_WAITOK | M_ZERO); *devnamesp = devnames; if (ev != NULL) { dn = ev; idx = 0; while (*dn != '\0') { ep = dn; while (*ep != ',' && *ep != '\0') ep++; if ((ep - dn) > pfxlen && strncmp(dn, prefix, pfxlen) == 0) { devnames[idx] = malloc(ep - dn + 1, M_DEVBUF, M_WAITOK | M_ZERO); memcpy(devnames[idx], dn, ep - dn); idx++; } dn = (*ep == ',') ? ep + 1 : ep; } freeenv(__DECONST(char *, ev)); } } dn = device_get_desc(dev); while (*devnames != NULL) { if (strcmp(dn, *devnames) == 0) return (BUS_PROBE_SPECIFIC); devnames++; } return (BUS_PROBE_HOOVER); }
static int ucom_detach(device_t self) { struct ucom_softc *sc = device_get_softc(self); char *devinfo = (char *) device_get_desc(self); if (devinfo) { device_set_desc(self, NULL); free(devinfo, M_USB); } return 0; }
/*------------------------------------------------------------------------* * ugen_get_iface_driver * * This function generates an USB interface description for userland. * * Returns: * 0: Success * Else: Failure *------------------------------------------------------------------------*/ static int ugen_get_iface_driver(struct usb_fifo *f, struct usb_gen_descriptor *ugd) { struct usb_device *udev = f->udev; struct usb_interface *iface; const char *ptr; const char *desc; unsigned int len; unsigned int maxlen; char buf[128]; int error; DPRINTFN(6, "\n"); if ((ugd->ugd_data == NULL) || (ugd->ugd_maxlen == 0)) { /* userland pointer should not be zero */ return (EINVAL); } iface = usbd_get_iface(udev, ugd->ugd_iface_index); if ((iface == NULL) || (iface->idesc == NULL)) { /* invalid interface index */ return (EINVAL); } /* read out device nameunit string, if any */ if ((iface->subdev != NULL) && device_is_attached(iface->subdev) && (ptr = device_get_nameunit(iface->subdev)) && (desc = device_get_desc(iface->subdev))) { /* print description */ snprintf(buf, sizeof(buf), "%s: <%s>", ptr, desc); /* range checks */ maxlen = ugd->ugd_maxlen - 1; len = strlen(buf); if (len > maxlen) len = maxlen; /* update actual length, including terminating zero */ ugd->ugd_actlen = len + 1; /* copy out interface description */ error = copyout(buf, ugd->ugd_data, ugd->ugd_actlen); } else { /* zero length string is default */ error = copyout("", ugd->ugd_data, 1); } return (error); }
static int km_probe(struct device *dev) { char *desc; if (pci_get_vendor(dev) != PCI_VENDOR_AMD) return ENXIO; switch (pci_get_device(dev)) { case PCI_PRODUCT_AMD_AMD64_F10_MISC: desc = "AMD Family 10h temperature sensor"; break; case PCI_PRODUCT_AMD_AMD64_F11_MISC: desc = "AMD Family 11h temperature sensor"; break; case PCI_PRODUCT_AMD_AMD64_F14_MISC: if (CPUID_TO_FAMILY(cpu_id) == 0x12) desc = "AMD Family 12h temperature sensor"; else desc = "AMD Family 14h temperature sensor"; break; case PCI_PRODUCT_AMD_AMD64_F15_0x_MISC: desc = "AMD Family 15/0xh temperature sensor"; break; case PCI_PRODUCT_AMD_AMD64_F15_1x_MISC: desc = "AMD Family 15/1xh temperature sensor"; break; case PCI_PRODUCT_AMD_AMD64_F15_3x_MISC: desc = "AMD Family 15/3xh temperature sensor"; break; case PCI_PRODUCT_AMD_AMD64_F16_MISC: desc = "AMD Family 16h temperature sensor"; break; default: return ENXIO; } if (device_get_desc(dev) == NULL) device_set_desc(dev, desc); return 0; }
static int km_probe(struct device *dev) { int ten = 0; if (pci_get_vendor(dev) != PCI_VENDOR_AMD) return ENXIO; switch (pci_get_device(dev)) { case PCI_PRODUCT_AMD_AMD64_F10_MISC: ten = 1; /* FALLTHROUGH */ case PCI_PRODUCT_AMD_AMD64_F11_MISC: if (device_get_desc(dev) == NULL) device_set_desc(dev, ten ? "AMD Family 10h temperature sensor" : "AMD Family 11h temperature sensor"); return 0; default: return ENXIO; } }
int quicc_bfe_probe(device_t dev, u_int clock) { struct quicc_softc *sc; uint16_t rev; sc = device_get_softc(dev); sc->sc_dev = dev; if (device_get_desc(dev) == NULL) device_set_desc(dev, "Quad integrated communications controller"); sc->sc_rrid = 0; sc->sc_rtype = SYS_RES_MEMORY; sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype, &sc->sc_rrid, 0, ~0, 0, RF_ACTIVE); if (sc->sc_rres == NULL) { sc->sc_rrid = 0; sc->sc_rtype = SYS_RES_IOPORT; sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype, &sc->sc_rrid, 0, ~0, 0, RF_ACTIVE); if (sc->sc_rres == NULL) return (ENXIO); } sc->sc_clock = clock; /* * Check that the microcode revision is 0x00e8, as documented * in the MPC8555E PowerQUICC III Integrated Processor Family * Reference Manual. */ rev = quicc_read2(sc->sc_rres, QUICC_PRAM_REV_NUM); bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres); return ((rev == 0x00e8) ? BUS_PROBE_DEFAULT : ENXIO); }
static int gmbus_xfer(device_t adapter, struct iic_msg *msgs, uint32_t num) { struct intel_iic_softc *sc = device_get_softc(adapter); struct intel_gmbus *bus = sc->bus; struct drm_i915_private *dev_priv = bus->dev_priv; int i, reg_offset; int ret = 0; sx_xlock(&dev_priv->gmbus_mutex); if (bus->force_bit) { ret = -IICBUS_TRANSFER(bus->bbbus, msgs, num); goto out; } reg_offset = dev_priv->gpio_mmio_base; I915_WRITE(GMBUS0 + reg_offset, bus->reg0); for (i = 0; i < num; i++) { u32 gmbus2; if (gmbus_is_index_read(msgs, i, num)) { ret = gmbus_xfer_index_read(dev_priv, &msgs[i]); i += 1; /* set i to the index of the read xfer */ } else if (msgs[i].flags & I2C_M_RD) { ret = gmbus_xfer_read(dev_priv, &msgs[i], 0); } else { ret = gmbus_xfer_write(dev_priv, &msgs[i]); } if (ret == -ETIMEDOUT) goto timeout; if (ret == -ENXIO) goto clear_err; ret = wait_for((gmbus2 = I915_READ(GMBUS2 + reg_offset)) & (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE), 50); if (ret) goto timeout; if (gmbus2 & GMBUS_SATOER) goto clear_err; } /* Generate a STOP condition on the bus. Note that gmbus can't generata * a STOP on the very first cycle. To simplify the code we * unconditionally generate the STOP condition with an additional gmbus * cycle. */ I915_WRITE(GMBUS1 + reg_offset, GMBUS_CYCLE_STOP | GMBUS_SW_RDY); /* Mark the GMBUS interface as disabled after waiting for idle. * We will re-enable it at the start of the next xfer, * till then let it sleep. */ if (wait_for((I915_READ(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0, 10)) { DRM_DEBUG_KMS("GMBUS [%s] timed out waiting for idle\n", device_get_desc(adapter)); ret = -ETIMEDOUT; } I915_WRITE(GMBUS0 + reg_offset, 0); goto out; clear_err: /* * Wait for bus to IDLE before clearing NAK. * If we clear the NAK while bus is still active, then it will stay * active and the next transaction may fail. * * If no ACK is received during the address phase of a transaction, the * adapter must report -ENXIO. It is not clear what to return if no ACK * is received at other times. But we have to be careful to not return * spurious -ENXIO because that will prevent i2c and drm edid functions * from retrying. So return -ENXIO only when gmbus properly quiescents - * timing out seems to happen when there _is_ a ddc chip present, but * it's slow responding and only answers on the 2nd retry. */ ret = -ENXIO; if (wait_for((I915_READ(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0, 10)) { DRM_DEBUG_KMS("GMBUS [%s] timed out after NAK\n", device_get_desc(adapter)); ret = -ETIMEDOUT; } /* Toggle the Software Clear Interrupt bit. This has the effect * of resetting the GMBUS controller and so clearing the * BUS_ERROR raised by the slave's NAK. */ I915_WRITE(GMBUS1 + reg_offset, GMBUS_SW_CLR_INT); I915_WRITE(GMBUS1 + reg_offset, 0); I915_WRITE(GMBUS0 + reg_offset, 0); DRM_DEBUG_KMS("GMBUS [%s] NAK for addr: %04x %c(%d)\n", device_get_desc(adapter), msgs[i].slave >> 1, (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len); goto out; timeout: DRM_INFO("GMBUS [%s] timed out, falling back to bit banging on pin %d\n", device_get_desc(adapter), bus->reg0 & 0xff); I915_WRITE(GMBUS0 + reg_offset, 0); /* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */ bus->force_bit = 1; ret = -IICBUS_TRANSFER(bus->bbbus, msgs, num); out: sx_xunlock(&dev_priv->gmbus_mutex); return -ret; }
/*---------------------------------------------------------------------------* * attach for ISA PnP cards *---------------------------------------------------------------------------*/ static int isic_pnp_attach(device_t dev) { u_int32_t vend_id = isa_get_vendorid(dev); /* vendor id */ unsigned int unit = device_get_unit(dev); /* get unit */ const char *name = device_get_desc(dev); /* get description */ struct l1_softc *sc = 0; /* softc */ void *ih = 0; /* a dummy */ int ret; /* see if we are out of bounds */ if(unit >= ISIC_MAXUNIT) { printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for %s\n", unit, unit, name); return ENXIO; } /* get information structure for this unit */ sc = &l1_sc[unit]; /* get io_base */ if(!(sc->sc_resources.io_base[0] = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->sc_resources.io_rid[0], 0UL, ~0UL, 1, RF_ACTIVE ) )) { printf("isic_pnp_attach: Couldn't get my io_base.\n"); return ENXIO; } /* will not be used for pnp devices */ sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]); /* get irq, release io_base if we don't get it */ if(!(sc->sc_resources.irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->sc_resources.irq_rid, 0UL, ~0UL, 1, RF_ACTIVE))) { printf("isic%d: Could not get irq.\n",unit); isic_detach_common(dev); return ENXIO; } /* not needed */ sc->sc_irq = rman_get_start(sc->sc_resources.irq); /* set flag so we know what this card is */ ret = ENXIO; switch(vend_id) { #if defined(TEL_S0_16_3_P) || defined(CRTX_S0_P) || defined(COMPAQ_M610) case VID_TEL163PNP: sc->sc_cardtyp = CARD_TYPEP_163P; ret = isic_attach_Cs0P(dev); break; case VID_CREATIXPP: sc->sc_cardtyp = CARD_TYPEP_CS0P; ret = isic_attach_Cs0P(dev); break; case VID_COMPAQ_M610: sc->sc_cardtyp = CARD_TYPEP_COMPAQ_M610; ret = isic_attach_Cs0P(dev); break; #endif #ifdef DYNALINK case VID_DYNALINK: sc->sc_cardtyp = CARD_TYPEP_DYNALINK; ret = isic_attach_Dyn(dev); break; #endif #ifdef SEDLBAUER case VID_SEDLBAUER: sc->sc_cardtyp = CARD_TYPEP_SWS; ret = isic_attach_sws(dev); break; #endif #ifdef DRN_NGO case VID_NICCYGO: sc->sc_cardtyp = CARD_TYPEP_DRNNGO; ret = isic_attach_drnngo(dev); break; #endif #ifdef ELSA_QS1ISA case VID_ELSAQS1P: sc->sc_cardtyp = CARD_TYPEP_ELSAQS1ISA; ret = isic_attach_Eqs1pi(dev); break; #endif #ifdef ITKIX1 case VID_ITK0025: sc->sc_cardtyp = CARD_TYPEP_ITKIX1; ret = isic_attach_itkix1(dev); break; #endif #ifdef SIEMENS_ISURF2 case VID_SIESURF2: sc->sc_cardtyp = CARD_TYPEP_SIE_ISURF2; ret = isic_attach_siemens_isurf(dev); break; #endif #ifdef ASUSCOM_IPAC case VID_ASUSCOM_IPAC: sc->sc_cardtyp = CARD_TYPEP_ASUSCOMIPAC; ret = isic_attach_asi(dev); break; #endif #ifdef EICON_DIVA case VID_EICON_DIVA_20: sc->sc_cardtyp = CARD_TYPEP_DIVA_ISA; ret = isic_attach_diva(dev); break; case VID_EICON_DIVA_202: sc->sc_cardtyp = CARD_TYPEP_DIVA_ISA; ret = isic_attach_diva_ipac(dev); break; #endif default: printf("isic%d: Error, no driver for %s\n", unit, name); ret = ENXIO; break; } if(ret) { isic_detach_common(dev); return ENXIO; } if(isic_attach_common(dev)) { /* unset flag */ sc->sc_cardtyp = CARD_TYPEP_UNK; /* free irq here, it hasn't been attached yet */ bus_release_resource(dev,SYS_RES_IRQ,sc->sc_resources.irq_rid, sc->sc_resources.irq); sc->sc_resources.irq = 0; isic_detach_common(dev); return ENXIO; } else { /* setup intr routine */ bus_setup_intr(dev,sc->sc_resources.irq,INTR_TYPE_NET, (void(*)(void*))isicintr, sc,&ih); return 0; } }
int zstty_attach(device_t dev) { struct zstty_softc *sc; struct tty *tp; char mode[32]; int reset; int baud; int clen; char parity; int stop; char c; sc = device_get_softc(dev); mtx_init(&sc->sc_mtx, "zstty", NULL, MTX_SPIN); sc->sc_dev = dev; sc->sc_iput = sc->sc_iget = sc->sc_ibuf; sc->sc_oget = sc->sc_obuf; tp = ttymalloc(NULL); sc->sc_si = make_dev(&zstty_cdevsw, device_get_unit(dev), UID_ROOT, GID_WHEEL, 0600, "%s", device_get_desc(dev)); sc->sc_si->si_drv1 = sc; sc->sc_si->si_tty = tp; tp->t_dev = sc->sc_si; sc->sc_tty = tp; tp->t_oproc = zsttystart; tp->t_param = zsttyparam; tp->t_stop = zsttystop; tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_lflag = TTYDEF_LFLAG; tp->t_cflag = CREAD | CLOCAL | CS8; tp->t_ospeed = TTYDEF_SPEED; tp->t_ispeed = TTYDEF_SPEED; if (zstty_console(dev, mode, sizeof(mode))) { ttychars(tp); /* format: 9600,8,n,1,- */ if (sscanf(mode, "%d,%d,%c,%d,%c", &baud, &clen, &parity, &stop, &c) == 5) { tp->t_ospeed = baud; tp->t_ispeed = baud; tp->t_cflag = CREAD | CLOCAL; switch (clen) { case 5: tp->t_cflag |= CS5; break; case 6: tp->t_cflag |= CS6; break; case 7: tp->t_cflag |= CS7; break; case 8: default: tp->t_cflag |= CS8; break; } if (parity == 'e') tp->t_cflag |= PARENB; else if (parity == 'o') tp->t_cflag |= PARENB | PARODD; if (stop == 2) tp->t_cflag |= CSTOPB; } device_printf(dev, "console %s\n", mode); sc->sc_console = 1; zstty_cons = sc; } else { if ((device_get_unit(dev) & 1) == 0) reset = ZSWR9_A_RESET; else reset = ZSWR9_B_RESET; ZS_WRITE_REG(sc, 9, reset); } return (0); }
/* * Quiz the PnP BIOS, build a list of PNP IDs and resource data. */ static int pnpbios_identify(driver_t *driver, device_t parent) { struct PnPBIOS_table *pt = PnPBIOStable; struct bios_args args; struct pnp_sysdev *pd; struct pnp_sysdevargs *pda; uint16_t ndevs, bigdev; int error, currdev; uint8_t *devnodebuf, tag; uint32_t *devid, *compid; int idx, left; device_t dev; /* * Umm, we aren't going to rescan the PnP BIOS to look for new additions. */ if (device_get_state(parent) == DS_ATTACHED) return (0); /* no PnP BIOS information */ if (pt == NULL) return (ENXIO); /* ACPI already active */ if (devclass_get_softc(devclass_find("ACPI"), 0) != NULL) return (ENXIO); bzero(&args, sizeof(args)); args.seg.code16.base = BIOS_PADDRTOVADDR(pt->pmentrybase); args.seg.code16.limit = 0xffff; /* XXX ? */ args.seg.data.base = BIOS_PADDRTOVADDR(pt->pmdataseg); args.seg.data.limit = 0xffff; args.entry = pt->pmentryoffset; if ((error = bios16(&args, PNP_COUNT_DEVNODES, &ndevs, &bigdev)) || (args.r.eax & 0xff)) kprintf("pnpbios: error %d/%x getting device count/size limit\n", error, args.r.eax); ndevs &= 0xff; /* clear high byte garbage */ if (bootverbose) kprintf("pnpbios: %d devices, largest %d bytes\n", ndevs, bigdev); devnodebuf = kmalloc(bigdev + (sizeof(struct pnp_sysdevargs) - sizeof(struct pnp_sysdev)), M_DEVBUF, M_INTWAIT); pda = (struct pnp_sysdevargs *)devnodebuf; pd = &pda->node; for (currdev = 0, left = ndevs; (currdev != 0xff) && (left > 0); left--) { bzero(pd, bigdev); pda->next = currdev; /* get current configuration */ if ((error = bios16(&args, PNP_GET_DEVNODE, &pda->next, &pda->node, 1))) { kprintf("pnpbios: error %d making BIOS16 call\n", error); break; } if (bootverbose) kprintf("pnp_get_devnode cd=%d nxt=%d size=%d handle=%d devid=%08x type=%02x%02x%02x, attrib=%04x\n", currdev, pda->next, pd->size, pd->handle, pd->devid, pd->type[0], pd->type[1], pd->type[2], pd->attrib); if ((error = (args.r.eax & 0xff))) { if (bootverbose) kprintf("pnpbios: %s 0x%x fetching node %d\n", error & 0x80 ? "error" : "warning", error, currdev); if (error & 0x80) break; } currdev = pda->next; if (pd->size < sizeof(struct pnp_sysdev)) { kprintf("pnpbios: bogus system node data, aborting scan\n"); break; } /* * Ignore PICs so that we don't have to worry about the PICs * claiming IRQs to prevent their use. The PIC drivers * already ensure that invalid IRQs are not used. */ if (!strcmp(pnp_eisaformat(pd->devid), "PNP0000")) /* ISA PIC */ continue; if (!strcmp(pnp_eisaformat(pd->devid), "PNP0003")) /* APIC */ continue; /* Add the device and parse its resources */ dev = BUS_ADD_CHILD(parent, parent, ISA_ORDER_PNP, NULL, -1); isa_set_vendorid(dev, pd->devid); isa_set_logicalid(dev, pd->devid); /* * It appears that some PnP BIOS doesn't allow us to re-enable * the embedded system device once it is disabled. We shall * mark all system device nodes as "cannot be disabled", regardless * of actual settings in the device attribute byte. XXX */ #if 0 isa_set_configattr(dev, ((pd->attrib & PNPATTR_NODISABLE) ? 0 : ISACFGATTR_CANDISABLE) | ((!(pd->attrib & PNPATTR_NOCONFIG) && PNPATTR_CONFIG(pd->attrib) != PNPATTR_CONFIG_STATIC) ? ISACFGATTR_DYNAMIC : 0)); #endif isa_set_configattr(dev, (!(pd->attrib & PNPATTR_NOCONFIG) && PNPATTR_CONFIG(pd->attrib) != PNPATTR_CONFIG_STATIC) ? ISACFGATTR_DYNAMIC : 0); ISA_SET_CONFIG_CALLBACK(parent, dev, pnpbios_set_config, 0); pnp_parse_resources(dev, &pd->devdata[0], pd->size - sizeof(struct pnp_sysdev), 0); if (!device_get_desc(dev)) device_set_desc_copy(dev, pnp_eisaformat(pd->devid)); /* Find device IDs */ devid = &pd->devid; compid = NULL; /* look for a compatible device ID too */ left = pd->size - sizeof(struct pnp_sysdev); idx = 0; while (idx < left) { tag = pd->devdata[idx++]; if (PNP_RES_TYPE(tag) == 0) { /* Small resource */ switch (PNP_SRES_NUM(tag)) { case PNP_TAG_COMPAT_DEVICE: compid = (uint32_t *)(pd->devdata + idx); if (bootverbose) kprintf("pnpbios: node %d compat ID 0x%08x\n", pd->handle, *compid); /* FALLTHROUGH */ case PNP_TAG_END: idx = left; break; default: idx += PNP_SRES_LEN(tag); break; } } else /* Large resource, skip it */ idx += *(uint16_t *)(pd->devdata + idx) + 2; } if (bootverbose) { kprintf("pnpbios: handle %d device ID %s (%08x)", pd->handle, pnp_eisaformat(*devid), *devid); if (compid != NULL) kprintf(" compat ID %s (%08x)", pnp_eisaformat(*compid), *compid); kprintf("\n"); } } return (0); }
static int aw_ir_attach(device_t dev) { struct aw_ir_softc *sc; hwreset_t rst_apb; clk_t clk_ir, clk_gate; int err; uint32_t val = 0; clk_ir = clk_gate = NULL; rst_apb = NULL; sc = device_get_softc(dev); sc->dev = dev; if (bus_alloc_resources(dev, aw_ir_spec, sc->res) != 0) { device_printf(dev, "could not allocate memory resource\n"); return (ENXIO); } switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) { case A10_IR: sc->fifo_size = 16; break; case A13_IR: sc->fifo_size = 64; break; } /* De-assert reset */ if (hwreset_get_by_ofw_name(dev, 0, "apb", &rst_apb) == 0) { err = hwreset_deassert(rst_apb); if (err != 0) { device_printf(dev, "cannot de-assert reset\n"); goto error; } } /* Reset buffer */ aw_ir_buf_reset(sc); /* Get clocks and enable them */ err = clk_get_by_ofw_name(dev, 0, "apb", &clk_gate); if (err != 0) { device_printf(dev, "Cannot get gate clock\n"); goto error; } err = clk_get_by_ofw_name(dev, 0, "ir", &clk_ir); if (err != 0) { device_printf(dev, "Cannot get IR clock\n"); goto error; } /* Set clock rate */ err = clk_set_freq(clk_ir, AW_IR_BASE_CLK, 0); if (err != 0) { device_printf(dev, "cannot set IR clock rate\n"); goto error; } /* Enable clocks */ err = clk_enable(clk_gate); if (err != 0) { device_printf(dev, "Cannot enable clk gate\n"); goto error; } err = clk_enable(clk_ir); if (err != 0) { device_printf(dev, "Cannot enable IR clock\n"); goto error; } if (bus_setup_intr(dev, sc->res[1], INTR_TYPE_MISC | INTR_MPSAFE, NULL, aw_ir_intr, sc, &sc->intrhand)) { bus_release_resources(dev, aw_ir_spec, sc->res); device_printf(dev, "cannot setup interrupt handler\n"); return (ENXIO); } /* Enable CIR Mode */ WRITE(sc, AW_IR_CTL, AW_IR_CTL_MD); /* * Set clock sample, filter, idle thresholds. * Frequency sample = 3MHz/128 = 23437.5Hz (42.7us) */ val = AW_IR_SAMPLE_128; val |= (AW_IR_RXFILT_VAL | AW_IR_RXIDLE_VAL); val |= (AW_IR_ACTIVE_T | AW_IR_ACTIVE_T_C); WRITE(sc, AW_IR_CIR, val); /* Invert Input Signal */ WRITE(sc, AW_IR_RXCTL, AW_IR_RXCTL_RPPI); /* Clear All RX Interrupt Status */ WRITE(sc, AW_IR_RXSTA, AW_IR_RXSTA_CLEARALL); /* * Enable RX interrupt in case of overflow, packet end * and FIFO available. * RX FIFO Threshold = FIFO size / 2 */ WRITE(sc, AW_IR_RXINT, AW_IR_RXINT_ROI_EN | AW_IR_RXINT_RPEI_EN | AW_IR_RXINT_RAI_EN | AW_IR_RXINT_RAL((sc->fifo_size >> 1) - 1)); /* Enable IR Module */ val = READ(sc, AW_IR_CTL); WRITE(sc, AW_IR_CTL, val | AW_IR_CTL_GEN | AW_IR_CTL_RXEN); sc->sc_evdev = evdev_alloc(); evdev_set_name(sc->sc_evdev, device_get_desc(sc->dev)); evdev_set_phys(sc->sc_evdev, device_get_nameunit(sc->dev)); evdev_set_id(sc->sc_evdev, BUS_HOST, 0, 0, 0); evdev_support_event(sc->sc_evdev, EV_SYN); evdev_support_event(sc->sc_evdev, EV_MSC); evdev_support_msc(sc->sc_evdev, MSC_SCAN); err = evdev_register(sc->sc_evdev); if (err) { device_printf(dev, "failed to register evdev: error=%d\n", err); goto error; } return (0); error: if (clk_gate != NULL) clk_release(clk_gate); if (clk_ir != NULL) clk_release(clk_ir); if (rst_apb != NULL) hwreset_release(rst_apb); evdev_free(sc->sc_evdev); sc->sc_evdev = NULL; /* Avoid double free */ bus_release_resources(dev, aw_ir_spec, sc->res); return (ENXIO); }
static int ichwd_attach(device_t dev) { struct ichwd_softc *sc; struct ichwd_device *id_p; device_t ich; unsigned int pmbase = 0; sc = device_get_softc(dev); sc->device = dev; ich = ichwd_find_ich_lpc_bridge(&id_p); if (ich == NULL) { device_printf(sc->device, "Can not find ICH device.\n"); goto fail; } sc->ich = ich; sc->ich_version = id_p->version; /* get ACPI base address */ pmbase = pci_read_config(ich, ICH_PMBASE, 2) & ICH_PMBASE_MASK; if (pmbase == 0) { device_printf(dev, "ICH PMBASE register is empty\n"); goto fail; } /* allocate I/O register space */ sc->smi_rid = 0; sc->smi_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->smi_rid, pmbase + SMI_BASE, pmbase + SMI_BASE + SMI_LEN - 1, SMI_LEN, RF_ACTIVE | RF_SHAREABLE); if (sc->smi_res == NULL) { device_printf(dev, "unable to reserve SMI registers\n"); goto fail; } sc->tco_rid = 1; sc->tco_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->tco_rid, pmbase + TCO_BASE, pmbase + TCO_BASE + TCO_LEN - 1, TCO_LEN, RF_ACTIVE | RF_SHAREABLE); if (sc->tco_res == NULL) { device_printf(dev, "unable to reserve TCO registers\n"); goto fail; } sc->gcs_rid = 0; if (sc->ich_version >= 6) { sc->gcs_res = bus_alloc_resource_any(ich, SYS_RES_MEMORY, &sc->gcs_rid, RF_ACTIVE|RF_SHAREABLE); if (sc->gcs_res == NULL) { device_printf(dev, "unable to reserve GCS registers\n"); goto fail; } } if (ichwd_clear_noreboot(sc) != 0) goto fail; ichwd_verbose_printf(dev, "%s (ICH%d or equivalent)\n", device_get_desc(dev), sc->ich_version); /* * Determine if we are coming up after a watchdog-induced reset. Some * BIOSes may clear this bit at bootup, preventing us from reporting * this case on such systems. We clear this bit in ichwd_sts_reset(). */ if ((ichwd_read_tco_2(sc, TCO2_STS) & TCO_SECOND_TO_STS) != 0) device_printf(dev, "resuming after hardware watchdog timeout\n"); /* reset the watchdog status registers */ ichwd_sts_reset(sc); /* make sure the WDT starts out inactive */ ichwd_tmr_disable(sc); /* register the watchdog event handler */ sc->ev_tag = EVENTHANDLER_REGISTER(watchdog_list, ichwd_event, sc, 0); /* disable the SMI handler */ sc->smi_enabled = ichwd_smi_is_enabled(sc); ichwd_smi_disable(sc); return (0); fail: sc = device_get_softc(dev); if (sc->tco_res != NULL) bus_release_resource(dev, SYS_RES_IOPORT, sc->tco_rid, sc->tco_res); if (sc->smi_res != NULL) bus_release_resource(dev, SYS_RES_IOPORT, sc->smi_rid, sc->smi_res); if (sc->gcs_res != NULL) bus_release_resource(ich, SYS_RES_MEMORY, sc->gcs_rid, sc->gcs_res); return (ENXIO); }