void rump_hyperentropy_init(void) { if (rump_threads) { rndsource_setcb(&rndsrc, feedrandom, &rndsrc); rnd_attach_source(&rndsrc, "rump_hyperent", RND_TYPE_VM, RND_FLAG_NO_ESTIMATE|RND_FLAG_HASCB); } else { /* without threads, just fill the pool */ rnd_attach_source(&rndsrc, "rump_hyperent", RND_TYPE_VM, RND_FLAG_NO_ESTIMATE); feedrandom(RND_POOLBITS/NBBY, NULL); } }
static int pckbc_attach_slot(struct pckbc_softc *sc, pckbc_slot_t slot) { struct pckbc_internal *t = sc->id; void *sdata; device_t child; int alloced = 0; if (t->t_slotdata[slot] == NULL) { sdata = malloc(sizeof(struct pckbc_slotdata), M_DEVBUF, M_NOWAIT); if (sdata == NULL) { aprint_error_dev(sc->sc_dv, "no memory\n"); return (0); } t->t_slotdata[slot] = sdata; pckbc_init_slotdata(t->t_slotdata[slot]); alloced++; } child = pckbport_attach_slot(sc->sc_dv, t->t_pt, slot); if (child == NULL && alloced) { free(t->t_slotdata[slot], M_DEVBUF); t->t_slotdata[slot] = NULL; } if (child != NULL && t->t_slotdata[slot] != NULL) rnd_attach_source(&t->t_slotdata[slot]->rnd_source, device_xname(child), RND_TYPE_TTY, 0); return child != NULL; }
static void ingenic_rng_attach(device_t parent, device_t self, void *aux) { struct ingenic_rng_softc * const sc = device_private(self); const struct apbus_attach_args * const aa = aux; bus_addr_t addr = aa->aa_addr; int error; sc->sc_dev = self; sc->sc_bst = aa->aa_bst; if (addr == 0) addr = JZ_RNG; error = bus_space_map(aa->aa_bst, addr, 4, 0, &sc->sc_bsh); if (error) { aprint_error_dev(self, "can't map registers for %s: %d\n", aa->aa_name, error); return; } mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM); aprint_naive(": Ingenic random number generator\n"); aprint_normal(": Ingenic random number generator\n"); rndsource_setcb(&sc->sc_rndsource, ingenic_rng_get, sc); rnd_attach_source(&sc->sc_rndsource, device_xname(self), RND_TYPE_RNG, RND_FLAG_COLLECT_VALUE|RND_FLAG_HASCB); ingenic_rng_get(RND_POOLBITS / NBBY, sc); }
static void bcmrng_attach(device_t parent, device_t self, void *aux) { struct bcm2835rng_softc *sc = device_private(self); struct amba_attach_args *aaa = aux; uint32_t ctrl; aprint_naive("\n"); aprint_normal(": RNG\n"); sc->sc_dev = self; sc->sc_iot = aaa->aaa_iot; if (bus_space_map(aaa->aaa_iot, aaa->aaa_addr, BCM2835_RNG_SIZE, 0, &sc->sc_ioh)) { aprint_error_dev(sc->sc_dev, "unable to map device\n"); goto fail0; } /* discard initial numbers, broadcom says they are "less random" */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, RNG_STATUS, 0x40000); /* enable rng */ ctrl = bus_space_read_4(sc->sc_iot, sc->sc_ioh, RNG_CTRL); ctrl |= RNG_CTRL_EN; bus_space_write_4(sc->sc_iot, sc->sc_ioh, RNG_CTRL, ctrl); /* set up a softint for adding data */ mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SERIAL); sc->sc_bytes_wanted = 0; sc->sc_sih = softint_establish(SOFTINT_SERIAL|SOFTINT_MPSAFE, &bcmrng_get_intr, sc); if (sc->sc_sih == NULL) { aprint_error_dev(sc->sc_dev, "unable to establish softint"); goto fail1; } /* set up an rndsource */ mutex_init(&sc->sc_rnd_lock, MUTEX_DEFAULT, IPL_SERIAL); rndsource_setcb(&sc->sc_rndsource, &bcmrng_get_cb, sc); rnd_attach_source(&sc->sc_rndsource, device_xname(self), RND_TYPE_RNG, RND_FLAG_NO_ESTIMATE|RND_FLAG_HASCB); /* get some initial entropy ASAP */ bcmrng_get_cb(RND_POOLBITS / NBBY, sc); /* Success! */ return; fail1: mutex_destroy(&sc->sc_intr_lock); bus_space_unmap(aaa->aaa_iot, sc->sc_ioh, BCM2835_RNG_SIZE); fail0: return; }
static void ed_mca_attach(device_t parent, device_t self, void *aux) { struct ed_softc *ed = device_private(self); struct edc_mca_softc *sc = device_private(parent); struct ed_attach_args *eda = aux; char pbuf[8]; int drv_flags; ed->sc_dev = self; ed->edc_softc = sc; ed->sc_devno = eda->edc_drive; edc_add_disk(sc, ed); bufq_alloc(&ed->sc_q, "disksort", BUFQ_SORT_RAWBLOCK); mutex_init(&ed->sc_q_lock, MUTEX_DEFAULT, IPL_VM); if (ed_get_params(ed, &drv_flags)) { printf(": IDENTIFY failed, no disk found\n"); return; } format_bytes(pbuf, sizeof(pbuf), (u_int64_t) ed->sc_capacity * DEV_BSIZE); printf(": %s, %u cyl, %u head, %u sec, 512 bytes/sect x %u sectors\n", pbuf, ed->cyl, ed->heads, ed->sectors, ed->sc_capacity); printf("%s: %u spares/cyl, %s, %s, %s, %s, %s\n", device_xname(ed->sc_dev), ed->spares, (drv_flags & (1 << 0)) ? "NoRetries" : "Retries", (drv_flags & (1 << 1)) ? "Removable" : "Fixed", (drv_flags & (1 << 2)) ? "SkewedFormat" : "NoSkew", (drv_flags & (1 << 3)) ? "ZeroDefect" : "Defects", (drv_flags & (1 << 4)) ? "InvalidSecondary" : "SecondaryOK" ); /* * Initialize and attach the disk structure. */ disk_init(&ed->sc_dk, device_xname(ed->sc_dev), &eddkdriver); disk_attach(&ed->sc_dk); rnd_attach_source(&ed->rnd_source, device_xname(ed->sc_dev), RND_TYPE_DISK, RND_FLAG_DEFAULT); ed->sc_flags |= EDF_INIT; /* * XXX We should try to discovery wedges here, but * XXX that would mean being able to do I/O. Should * XXX use config_defer() here. */ }
void ldattach(struct ld_softc *sc) { char buf[9]; if ((sc->sc_flags & LDF_ENABLED) == 0) { printf("%s: disabled\n", sc->sc_dv.dv_xname); return; } /* Initialise and attach the disk structure. */ sc->sc_dk.dk_driver = &lddkdriver; sc->sc_dk.dk_name = sc->sc_dv.dv_xname; disk_attach(&sc->sc_dk); if (sc->sc_maxxfer > MAXPHYS) sc->sc_maxxfer = MAXPHYS; /* Build synthetic geometry. */ if (sc->sc_secperunit <= 528 * 2048) /* 528MB */ sc->sc_nheads = 16; else if (sc->sc_secperunit <= 1024 * 2048) /* 1GB */ sc->sc_nheads = 32; else if (sc->sc_secperunit <= 21504 * 2048) /* 21GB */ sc->sc_nheads = 64; else if (sc->sc_secperunit <= 43008 * 2048) /* 42GB */ sc->sc_nheads = 128; else sc->sc_nheads = 255; sc->sc_nsectors = 63; sc->sc_ncylinders = sc->sc_secperunit / (sc->sc_nheads * sc->sc_nsectors); format_bytes(buf, sizeof(buf), (u_int64_t)sc->sc_secperunit * sc->sc_secsize); printf("%s: %s, %d cyl, %d head, %d sec, %d bytes/sect x %d sectors\n", sc->sc_dv.dv_xname, buf, sc->sc_ncylinders, sc->sc_nheads, sc->sc_nsectors, sc->sc_secsize, sc->sc_secperunit); #if NRND > 0 /* Attach the device into the rnd source list. */ rnd_attach_source(&sc->sc_rnd_source, sc->sc_dv.dv_xname, RND_TYPE_DISK, 0); #endif /* Set the `shutdownhook'. */ if (ld_sdh == NULL) ld_sdh = shutdownhook_establish(ldshutdown, NULL); BUFQ_INIT(&sc->sc_bufq); }
void ucom_attach(device_t parent, device_t self, void *aux) { struct ucom_softc *sc = device_private(self); struct ucom_attach_args *uca = aux; struct tty *tp; if (uca->info != NULL) aprint_normal(": %s", uca->info); aprint_normal("\n"); sc->sc_dev = self; sc->sc_udev = uca->device; sc->sc_iface = uca->iface; sc->sc_bulkout_no = uca->bulkout; sc->sc_bulkin_no = uca->bulkin; sc->sc_ibufsize = uca->ibufsize; sc->sc_ibufsizepad = uca->ibufsizepad; sc->sc_obufsize = uca->obufsize; sc->sc_opkthdrlen = uca->opkthdrlen; sc->sc_methods = uca->methods; sc->sc_parent = uca->arg; sc->sc_portno = uca->portno; sc->sc_lsr = 0; sc->sc_msr = 0; sc->sc_mcr = 0; sc->sc_tx_stopped = 0; sc->sc_swflags = 0; sc->sc_opening = 0; sc->sc_refcnt = 0; sc->sc_dying = 0; sc->sc_si = softint_establish(SOFTINT_NET, ucom_softintr, sc); tp = tty_alloc(); tp->t_oproc = ucomstart; tp->t_param = ucomparam; tp->t_hwiflow = ucomhwiflow; sc->sc_tty = tp; DPRINTF(("ucom_attach: tty_attach %p\n", tp)); tty_attach(tp); rnd_attach_source(&sc->sc_rndsource, device_xname(sc->sc_dev), RND_TYPE_TTY, RND_FLAG_DEFAULT); if (!pmf_device_register(self, NULL, NULL)) aprint_error_dev(self, "couldn't establish power handler\n"); return; }
/* * Controller is working, and drive responded. Attach it. */ void fdattach(device_t parent, device_t self, void *aux) { struct fdc_softc *fdc = device_private(parent); struct fd_softc *fd = device_private(self); struct fdc_attach_args *fa = aux; const struct fd_type *type = fa->fa_deftype; int drive = fa->fa_drive; fd->sc_dev = self; callout_init(&fd->sc_motoron_ch, 0); callout_init(&fd->sc_motoroff_ch, 0); /* XXX Allow `flags' to override device type? */ if (type) aprint_normal(": %s, %d cyl, %d head, %d sec\n", type->name, type->cyls, type->heads, type->sectrac); else aprint_normal(": density unknown\n"); bufq_alloc(&fd->sc_q, "disksort", BUFQ_SORT_CYLINDER); fd->sc_cylin = -1; fd->sc_drive = drive; fd->sc_deftype = type; fdc->sc_fd[drive] = fd; /* * Initialize and attach the disk structure. */ disk_init(&fd->sc_dk, device_xname(fd->sc_dev), &fddkdriver); disk_attach(&fd->sc_dk); /* * Establish a mountroot hook. */ fd->sc_roothook = mountroothook_establish(fd_mountroot_hook, fd->sc_dev); #if NRND > 0 rnd_attach_source(&fd->rnd_source, device_xname(fd->sc_dev), RND_TYPE_DISK, 0); #endif fd_set_properties(fd); if (!pmf_device_register(self, NULL, NULL)) aprint_error_dev(self, "cannot set power mgmt handler\n"); }
void dk_attach(struct dk_softc *dksc) { KASSERT(dksc->sc_dev != NULL); mutex_init(&dksc->sc_iolock, MUTEX_DEFAULT, IPL_VM); dksc->sc_flags |= DKF_READYFORDUMP; #ifdef DIAGNOSTIC dksc->sc_flags |= DKF_WARNLABEL | DKF_LABELSANITY; #endif /* Attach the device into the rnd source list. */ rnd_attach_source(&dksc->sc_rnd_source, dksc->sc_xname, RND_TYPE_DISK, RND_FLAG_DEFAULT); }
static void rdattach(device_t parent, device_t self, void *aux) { struct rd_softc *sc = device_private(self); struct hpibbus_attach_args *ha = aux; sc->sc_dev = self; bufq_alloc(&sc->sc_tab, "disksort", BUFQ_SORT_RAWBLOCK); if (rdident(parent, sc, ha) == 0) { aprint_error(": didn't respond to describe command!\n"); return; } /* * Initialize and attach the disk structure. */ memset(&sc->sc_dkdev, 0, sizeof(sc->sc_dkdev)); disk_init(&sc->sc_dkdev, device_xname(sc->sc_dev), NULL); disk_attach(&sc->sc_dkdev); sc->sc_slave = ha->ha_slave; sc->sc_punit = ha->ha_punit; callout_init(&sc->sc_restart_ch, 0); /* Initialize the hpib job queue entry */ sc->sc_hq.hq_softc = sc; sc->sc_hq.hq_slave = sc->sc_slave; sc->sc_hq.hq_start = rdstart; sc->sc_hq.hq_go = rdgo; sc->sc_hq.hq_intr = rdintr; sc->sc_flags = RDF_ALIVE; #ifdef DEBUG /* always report errors */ if (rddebug & RDB_ERROR) rderrthresh = 0; #endif /* * attach the device into the random source list */ rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), RND_TYPE_DISK, RND_FLAG_DEFAULT); }
void mb8795_config(struct mb8795_softc *sc, int *media, int nmedia, int defmedia) { struct ifnet *ifp = &sc->sc_ethercom.ec_if; DPRINTF(("%s: mb8795_config()\n",device_xname(sc->sc_dev))); /* Initialize ifnet structure. */ memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); ifp->if_softc = sc; ifp->if_start = mb8795_start; ifp->if_ioctl = mb8795_ioctl; ifp->if_watchdog = mb8795_watchdog; ifp->if_flags = IFF_BROADCAST | IFF_NOTRAILERS; /* Initialize media goo. */ ifmedia_init(&sc->sc_media, 0, mb8795_mediachange, mb8795_mediastatus); if (media != NULL) { int i; for (i = 0; i < nmedia; i++) ifmedia_add(&sc->sc_media, media[i], 0, NULL); ifmedia_set(&sc->sc_media, defmedia); } else { ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL); ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL); } /* Attach the interface. */ if_attach(ifp); ether_ifattach(ifp, sc->sc_enaddr); sc->sc_sh = shutdownhook_establish(mb8795_shutdown, sc); if (sc->sc_sh == NULL) panic("mb8795_config: can't establish shutdownhook"); rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), RND_TYPE_NET, RND_FLAG_DEFAULT); DPRINTF(("%s: leaving mb8795_config()\n",device_xname(sc->sc_dev))); }
static void ingenic_rng_attach(device_t parent, device_t self, void *aux) { struct ingenic_rng_softc * const sc = device_private(self); struct apbus_attach_args * const aa = aux; int error; sc->sc_dev = self; sc->sc_bst = aa->aa_bst; if (aa->aa_addr == 0) { aa->aa_addr = JZ_RNG; } error = bus_space_map(aa->aa_bst, aa->aa_addr, 4, 0, &sc->sc_bsh); if (error) { aprint_error_dev(self, "can't map registers for %s: %d\n", aa->aa_name, error); return; } mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SERIAL); mutex_init(&sc->sc_rnd_lock, MUTEX_DEFAULT, IPL_SERIAL); aprint_naive(": Ingenic random number generator\n"); aprint_normal(": Ingenic random number generator\n"); sc->sc_sih = softint_establish(SOFTINT_SERIAL|SOFTINT_MPSAFE, ingenic_rng_get_intr, sc); if (sc->sc_sih == NULL) { aprint_error_dev(self, "couldn't establish softint\n"); return; } rndsource_setcb(&sc->sc_rndsource, ingenic_rng_get_cb, sc); rnd_attach_source(&sc->sc_rndsource, device_xname(self), RND_TYPE_RNG, RND_FLAG_COLLECT_VALUE|RND_FLAG_HASCB); ingenic_rng_get_cb(RND_POOLBITS / NBBY, sc); }
static void xbd_attach(struct device *parent, struct device *self, void *aux) { struct xbd_attach_args *xbda = (struct xbd_attach_args *)aux; struct xbd_softc *xs = (struct xbd_softc *)self; aprint_normal(": Xen Virtual Block Device"); simple_lock_init(&xs->sc_slock); dk_sc_init(&xs->sc_dksc, xs, xs->sc_dev.dv_xname); xbdinit(xs, xbda->xa_xd, xbda->xa_dkintf); if (diskcookies) { /* XXX beware that xs->sc_xd_device is a long */ sysctl_createv(NULL, 0, &diskcookies, NULL, 0, CTLTYPE_INT, xs->sc_dev.dv_xname, NULL, NULL, 0, &xs->sc_xd_device, 0, CTL_CREATE, CTL_EOL); } #if NRND > 0 rnd_attach_source(&xs->rnd_source, xs->sc_dev.dv_xname, RND_TYPE_DISK, 0); #endif }
/* * ae_attach: * * Attach an ae interface to the system. */ void ae_attach(device_t parent, device_t self, void *aux) { const uint8_t *enaddr; prop_data_t ea; struct ae_softc *sc = device_private(self); struct arbus_attach_args *aa = aux; struct ifnet *ifp = &sc->sc_ethercom.ec_if; int i, error; sc->sc_dev = self; callout_init(&sc->sc_tick_callout, 0); printf(": Atheros AR531X 10/100 Ethernet\n"); /* * Try to get MAC address. */ ea = prop_dictionary_get(device_properties(sc->sc_dev), "mac-address"); if (ea == NULL) { printf("%s: unable to get mac-addr property\n", device_xname(sc->sc_dev)); return; } KASSERT(prop_object_type(ea) == PROP_TYPE_DATA); KASSERT(prop_data_size(ea) == ETHER_ADDR_LEN); enaddr = prop_data_data_nocopy(ea); /* Announce ourselves. */ printf("%s: Ethernet address %s\n", device_xname(sc->sc_dev), ether_sprintf(enaddr)); sc->sc_cirq = aa->aa_cirq; sc->sc_mirq = aa->aa_mirq; sc->sc_st = aa->aa_bst; sc->sc_dmat = aa->aa_dmat; SIMPLEQ_INIT(&sc->sc_txfreeq); SIMPLEQ_INIT(&sc->sc_txdirtyq); /* * Map registers. */ sc->sc_size = aa->aa_size; if ((error = bus_space_map(sc->sc_st, aa->aa_addr, sc->sc_size, 0, &sc->sc_sh)) != 0) { printf("%s: unable to map registers, error = %d\n", device_xname(sc->sc_dev), error); goto fail_0; } /* * Allocate the control data structures, and create and load the * DMA map for it. */ if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct ae_control_data), PAGE_SIZE, 0, &sc->sc_cdseg, 1, &sc->sc_cdnseg, 0)) != 0) { printf("%s: unable to allocate control data, error = %d\n", device_xname(sc->sc_dev), error); goto fail_1; } if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg, sizeof(struct ae_control_data), (void **)&sc->sc_control_data, BUS_DMA_COHERENT)) != 0) { printf("%s: unable to map control data, error = %d\n", device_xname(sc->sc_dev), error); goto fail_2; } if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct ae_control_data), 1, sizeof(struct ae_control_data), 0, 0, &sc->sc_cddmamap)) != 0) { printf("%s: unable to create control data DMA map, " "error = %d\n", device_xname(sc->sc_dev), error); goto fail_3; } if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap, sc->sc_control_data, sizeof(struct ae_control_data), NULL, 0)) != 0) { printf("%s: unable to load control data DMA map, error = %d\n", device_xname(sc->sc_dev), error); goto fail_4; } /* * Create the transmit buffer DMA maps. */ for (i = 0; i < AE_TXQUEUELEN; i++) { if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, AE_NTXSEGS, MCLBYTES, 0, 0, &sc->sc_txsoft[i].txs_dmamap)) != 0) { printf("%s: unable to create tx DMA map %d, " "error = %d\n", device_xname(sc->sc_dev), i, error); goto fail_5; } } /* * Create the receive buffer DMA maps. */ for (i = 0; i < AE_NRXDESC; i++) { if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0, 0, &sc->sc_rxsoft[i].rxs_dmamap)) != 0) { printf("%s: unable to create rx DMA map %d, " "error = %d\n", device_xname(sc->sc_dev), i, error); goto fail_6; } sc->sc_rxsoft[i].rxs_mbuf = NULL; } /* * Reset the chip to a known state. */ ae_reset(sc); /* * From this point forward, the attachment cannot fail. A failure * before this point releases all resources that may have been * allocated. */ sc->sc_flags |= AE_ATTACHED; /* * Initialize our media structures. This may probe the MII, if * present. */ sc->sc_mii.mii_ifp = ifp; sc->sc_mii.mii_readreg = ae_mii_readreg; sc->sc_mii.mii_writereg = ae_mii_writereg; sc->sc_mii.mii_statchg = ae_mii_statchg; sc->sc_ethercom.ec_mii = &sc->sc_mii; ifmedia_init(&sc->sc_mii.mii_media, 0, ether_mediachange, ether_mediastatus); mii_attach(sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL); ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE); } else ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO); sc->sc_tick = ae_mii_tick; strcpy(ifp->if_xname, device_xname(sc->sc_dev)); ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; sc->sc_if_flags = ifp->if_flags; ifp->if_ioctl = ae_ioctl; ifp->if_start = ae_start; ifp->if_watchdog = ae_watchdog; ifp->if_init = ae_init; ifp->if_stop = ae_stop; IFQ_SET_READY(&ifp->if_snd); /* * We can support 802.1Q VLAN-sized frames. */ sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU; /* * Attach the interface. */ if_attach(ifp); ether_ifattach(ifp, enaddr); ether_set_ifflags_cb(&sc->sc_ethercom, ae_ifflags_cb); rnd_attach_source(&sc->sc_rnd_source, device_xname(sc->sc_dev), RND_TYPE_NET, RND_FLAG_DEFAULT); /* * Make sure the interface is shutdown during reboot. */ sc->sc_sdhook = shutdownhook_establish(ae_shutdown, sc); if (sc->sc_sdhook == NULL) printf("%s: WARNING: unable to establish shutdown hook\n", device_xname(sc->sc_dev)); /* * Add a suspend hook to make sure we come back up after a * resume. */ sc->sc_powerhook = powerhook_establish(device_xname(sc->sc_dev), ae_power, sc); if (sc->sc_powerhook == NULL) printf("%s: WARNING: unable to establish power hook\n", device_xname(sc->sc_dev)); return; /* * Free any resources we've allocated during the failed attach * attempt. Do this in reverse order and fall through. */ fail_6: for (i = 0; i < AE_NRXDESC; i++) { if (sc->sc_rxsoft[i].rxs_dmamap != NULL) bus_dmamap_destroy(sc->sc_dmat, sc->sc_rxsoft[i].rxs_dmamap); } fail_5: for (i = 0; i < AE_TXQUEUELEN; i++) { if (sc->sc_txsoft[i].txs_dmamap != NULL) bus_dmamap_destroy(sc->sc_dmat, sc->sc_txsoft[i].txs_dmamap); } bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap); fail_4: bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap); fail_3: bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_control_data, sizeof(struct ae_control_data)); fail_2: bus_dmamem_free(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg); fail_1: bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_size); fail_0: return; }
void viornd_attach( device_t parent, device_t self, void *aux) { struct viornd_softc *sc = device_private(self); struct virtio_softc *vsc = device_private(parent); bus_dma_segment_t segs[1]; int nsegs; int error; uint32_t features; char buf[256]; vsc->sc_vqs = &sc->sc_vq; vsc->sc_nvqs = 1; vsc->sc_config_change = NULL; if (vsc->sc_child != NULL) panic("already attached to something else"); vsc->sc_child = self; vsc->sc_ipl = IPL_NET; vsc->sc_intrhand = virtio_vq_intr; sc->sc_virtio = vsc; sc->sc_dev = self; features = virtio_negotiate_features(vsc, 0); snprintb(buf, sizeof(buf), VIRTIO_COMMON_FLAG_BITS, features); aprint_normal(": Features: %s\n", buf); aprint_naive("\n"); mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_VM); error = bus_dmamem_alloc(vsc->sc_dmat, VIRTIO_PAGE_SIZE, 0, 0, segs, 1, &nsegs, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW); if (error) { aprint_error_dev(sc->sc_dev, "can't alloc dmamem: %d\n", error); goto alloc_failed; } error = bus_dmamem_map(vsc->sc_dmat, segs, nsegs, VIORND_BUFSIZE, &sc->sc_buf, BUS_DMA_NOWAIT); if (error) { aprint_error_dev(sc->sc_dev, "can't map dmamem: %d\n", error); goto map_failed; } error = bus_dmamap_create(vsc->sc_dmat, VIORND_BUFSIZE, 1, VIORND_BUFSIZE, 0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW, &sc->sc_dmamap); if (error) { aprint_error_dev(sc->sc_dev, "can't alloc dmamap: %d\n", error); goto create_failed; } error = bus_dmamap_load(vsc->sc_dmat, sc->sc_dmamap, sc->sc_buf, VIORND_BUFSIZE, NULL, BUS_DMA_NOWAIT|BUS_DMA_READ); if (error) { aprint_error_dev(sc->sc_dev, "can't load dmamap: %d\n", error); goto load_failed; } error = virtio_alloc_vq(vsc, &sc->sc_vq, 0, VIORND_BUFSIZE, 1, "Entropy request"); if (error) { aprint_error_dev(sc->sc_dev, "can't alloc virtqueue: %d\n", error); goto vio_failed; } sc->sc_vq.vq_done = viornd_vq_done; virtio_start_vq_intr(vsc, &sc->sc_vq); rndsource_setcb(&sc->sc_rndsource, viornd_get, sc); rnd_attach_source(&sc->sc_rndsource, device_xname(sc->sc_dev), RND_TYPE_RNG, RND_FLAG_COLLECT_VALUE|RND_FLAG_HASCB); viornd_get(VIORND_BUFSIZE, sc); return; vio_failed: bus_dmamap_unload(vsc->sc_dmat, sc->sc_dmamap); load_failed: bus_dmamap_destroy(vsc->sc_dmat, sc->sc_dmamap); create_failed: bus_dmamem_unmap(vsc->sc_dmat, sc->sc_buf, VIORND_BUFSIZE); map_failed: bus_dmamem_free(vsc->sc_dmat, segs, nsegs); alloc_failed: vsc->sc_child = (void *)1; /* XXX bare constant 1 */ return; }
static void sackbc_attach(device_t parent, device_t self, void *aux) { struct sackbc_softc *sc = device_private(self); struct sacc_softc *psc = device_private(parent); struct sa1111_attach_args *aa = (struct sa1111_attach_args *)aux; device_t child; uint32_t tmp, clock_bit; int intr, slot; switch (aa->sa_addr) { case SACC_KBD0: clock_bit = (1<<6); intr = 21; break; case SACC_KBD1: clock_bit = (1<<5); intr = 18; break; default: return; } if (aa->sa_size <= 0) aa->sa_size = SACCKBD_SIZE; if (aa->sa_intr == SACCCF_INTR_DEFAULT) aa->sa_intr = intr; sc->dev = self; sc->iot = psc->sc_iot; if (bus_space_subregion(psc->sc_iot, psc->sc_ioh, aa->sa_addr, aa->sa_size, &sc->ioh)) { aprint_normal(": can't map subregion\n"); return; } /* enable clock for PS/2 kbd or mouse */ tmp = bus_space_read_4(psc->sc_iot, psc->sc_ioh, SACCSC_SKPCR); bus_space_write_4(psc->sc_iot, psc->sc_ioh, SACCSC_SKPCR, tmp | clock_bit); sc->ih_rx = NULL; sc->intr = aa->sa_intr; sc->polling = 0; tmp = bus_space_read_4(sc->iot, sc->ioh, SACCKBD_CR); bus_space_write_4(sc->iot, sc->ioh, SACCKBD_CR, tmp | KBDCR_ENA); /* XXX: this is necessary to get keyboard working. but I don't know why */ bus_space_write_4(sc->iot, sc->ioh, SACCKBD_CLKDIV, 2); tmp = bus_space_read_4(sc->iot, sc->ioh, SACCKBD_STAT); if ((tmp & KBDSTAT_ENA) == 0) { printf("??? can't enable KBD controller\n"); return; } printf("\n"); sc->pt = pckbport_attach(sc, &sackbc_ops); /* * Although there is no such thing as SLOT for SA-1111 kbd * controller, pckbd and pms drivers require it. */ for (slot = PCKBPORT_KBD_SLOT; slot <= PCKBPORT_AUX_SLOT; ++slot) { child = pckbport_attach_slot(self, sc->pt, slot); if (child == NULL) continue; sc->slot = slot; rnd_attach_source(&sc->rnd_source, device_xname(child), RND_TYPE_TTY, RND_FLAG_DEFAULT|RND_FLAG_ESTIMATE_VALUE); /* only one of KBD_SLOT or AUX_SLOT is used. */ break; } }
/* * Attach the interface. Allocate softc structures, do ifmedia * setup and ethernet/BPF attach. */ void rtk_attach(struct rtk_softc *sc) { device_t self = sc->sc_dev; struct ifnet *ifp; struct rtk_tx_desc *txd; uint16_t val; uint8_t eaddr[ETHER_ADDR_LEN]; int error; int i, addr_len; callout_init(&sc->rtk_tick_ch, 0); /* * Check EEPROM type 9346 or 9356. */ if (rtk_read_eeprom(sc, RTK_EE_ID, RTK_EEADDR_LEN1) == 0x8129) addr_len = RTK_EEADDR_LEN1; else addr_len = RTK_EEADDR_LEN0; /* * Get station address. */ val = rtk_read_eeprom(sc, RTK_EE_EADDR0, addr_len); eaddr[0] = val & 0xff; eaddr[1] = val >> 8; val = rtk_read_eeprom(sc, RTK_EE_EADDR1, addr_len); eaddr[2] = val & 0xff; eaddr[3] = val >> 8; val = rtk_read_eeprom(sc, RTK_EE_EADDR2, addr_len); eaddr[4] = val & 0xff; eaddr[5] = val >> 8; if ((error = bus_dmamem_alloc(sc->sc_dmat, RTK_RXBUFLEN + 16, PAGE_SIZE, 0, &sc->sc_dmaseg, 1, &sc->sc_dmanseg, BUS_DMA_NOWAIT)) != 0) { aprint_error_dev(self, "can't allocate recv buffer, error = %d\n", error); goto fail_0; } if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_dmaseg, sc->sc_dmanseg, RTK_RXBUFLEN + 16, (void **)&sc->rtk_rx_buf, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) { aprint_error_dev(self, "can't map recv buffer, error = %d\n", error); goto fail_1; } if ((error = bus_dmamap_create(sc->sc_dmat, RTK_RXBUFLEN + 16, 1, RTK_RXBUFLEN + 16, 0, BUS_DMA_NOWAIT, &sc->recv_dmamap)) != 0) { aprint_error_dev(self, "can't create recv buffer DMA map, error = %d\n", error); goto fail_2; } if ((error = bus_dmamap_load(sc->sc_dmat, sc->recv_dmamap, sc->rtk_rx_buf, RTK_RXBUFLEN + 16, NULL, BUS_DMA_READ|BUS_DMA_NOWAIT)) != 0) { aprint_error_dev(self, "can't load recv buffer DMA map, error = %d\n", error); goto fail_3; } for (i = 0; i < RTK_TX_LIST_CNT; i++) { txd = &sc->rtk_tx_descs[i]; if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0, BUS_DMA_NOWAIT, &txd->txd_dmamap)) != 0) { aprint_error_dev(self, "can't create snd buffer DMA map, error = %d\n", error); goto fail_4; } txd->txd_txaddr = RTK_TXADDR0 + (i * 4); txd->txd_txstat = RTK_TXSTAT0 + (i * 4); } SIMPLEQ_INIT(&sc->rtk_tx_free); SIMPLEQ_INIT(&sc->rtk_tx_dirty); /* * From this point forward, the attachment cannot fail. A failure * before this releases all resources thar may have been * allocated. */ sc->sc_flags |= RTK_ATTACHED; /* Reset the adapter. */ rtk_reset(sc); aprint_normal_dev(self, "Ethernet address %s\n", ether_sprintf(eaddr)); ifp = &sc->ethercom.ec_if; ifp->if_softc = sc; strcpy(ifp->if_xname, device_xname(self)); ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = rtk_ioctl; ifp->if_start = rtk_start; ifp->if_watchdog = rtk_watchdog; ifp->if_init = rtk_init; ifp->if_stop = rtk_stop; IFQ_SET_READY(&ifp->if_snd); /* * Do ifmedia setup. */ sc->mii.mii_ifp = ifp; sc->mii.mii_readreg = rtk_phy_readreg; sc->mii.mii_writereg = rtk_phy_writereg; sc->mii.mii_statchg = rtk_phy_statchg; sc->ethercom.ec_mii = &sc->mii; ifmedia_init(&sc->mii.mii_media, IFM_IMASK, ether_mediachange, ether_mediastatus); mii_attach(self, &sc->mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); /* Choose a default media. */ if (LIST_FIRST(&sc->mii.mii_phys) == NULL) { ifmedia_add(&sc->mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL); ifmedia_set(&sc->mii.mii_media, IFM_ETHER|IFM_NONE); } else { ifmedia_set(&sc->mii.mii_media, IFM_ETHER|IFM_AUTO); } /* * Call MI attach routines. */ if_attach(ifp); ether_ifattach(ifp, eaddr); rnd_attach_source(&sc->rnd_source, device_xname(self), RND_TYPE_NET, RND_FLAG_DEFAULT); return; fail_4: for (i = 0; i < RTK_TX_LIST_CNT; i++) { txd = &sc->rtk_tx_descs[i]; if (txd->txd_dmamap != NULL) bus_dmamap_destroy(sc->sc_dmat, txd->txd_dmamap); } fail_3: bus_dmamap_destroy(sc->sc_dmat, sc->recv_dmamap); fail_2: bus_dmamem_unmap(sc->sc_dmat, sc->rtk_rx_buf, RTK_RXBUFLEN + 16); fail_1: bus_dmamem_free(sc->sc_dmat, &sc->sc_dmaseg, sc->sc_dmanseg); fail_0: return; }
void smap_attach(struct device *parent, struct device *self, void *aux) { struct spd_attach_args *spa = aux; struct smap_softc *sc = (void *)self; struct emac3_softc *emac3 = &sc->emac3; struct ifnet *ifp = &sc->ethercom.ec_if; struct mii_data *mii = &emac3->mii; void *txbuf, *rxbuf; u_int16_t r; #ifdef SMAP_DEBUG __sc = sc; #endif printf(": %s\n", spa->spa_product_name); /* SPD EEPROM */ if (smap_get_eaddr(sc, emac3->eaddr) != 0) return; printf("%s: Ethernet address %s\n", DEVNAME, ether_sprintf(emac3->eaddr)); /* disable interrupts */ r = _reg_read_2(SPD_INTR_ENABLE_REG16); r &= ~(SPD_INTR_RXEND | SPD_INTR_TXEND | SPD_INTR_RXDNV | SPD_INTR_EMAC3); _reg_write_2(SPD_INTR_ENABLE_REG16, r); emac3_intr_disable(); /* clear pending interrupts */ _reg_write_2(SPD_INTR_CLEAR_REG16, SPD_INTR_RXEND | SPD_INTR_TXEND | SPD_INTR_RXDNV); emac3_intr_clear(); /* buffer descriptor mode */ _reg_write_1(SMAP_DESC_MODE_REG8, 0); if (smap_fifo_init(sc) != 0) return; if (emac3_init(&sc->emac3) != 0) return; emac3_intr_disable(); emac3_disable(); smap_desc_init(sc); /* allocate temporary buffer */ txbuf = malloc(ETHER_MAX_LEN - ETHER_CRC_LEN + SMAP_FIFO_ALIGN + 16, M_DEVBUF, M_NOWAIT); if (txbuf == NULL) { printf("%s: no memory.\n", DEVNAME); return; } rxbuf = malloc(ETHER_MAX_LEN + SMAP_FIFO_ALIGN + 16, M_DEVBUF, M_NOWAIT); if (rxbuf == NULL) { printf("%s: no memory.\n", DEVNAME); free(txbuf, M_DEVBUF); return; } sc->tx_buf = (u_int32_t *)ROUND16((vaddr_t)txbuf); sc->rx_buf = (u_int32_t *)ROUND16((vaddr_t)rxbuf); /* * setup MI layer */ strcpy(ifp->if_xname, DEVNAME); ifp->if_softc = sc; ifp->if_start = smap_start; ifp->if_ioctl = smap_ioctl; ifp->if_init = smap_init; ifp->if_stop = smap_stop; ifp->if_watchdog= smap_watchdog; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST; IFQ_SET_READY(&ifp->if_snd); /* ifmedia setup. */ mii->mii_ifp = ifp; mii->mii_readreg = emac3_phy_readreg; mii->mii_writereg = emac3_phy_writereg; mii->mii_statchg = emac3_phy_statchg; sc->ethercom.ec_mii = mii; ifmedia_init(&mii->mii_media, 0, ether_mediachange, ether_mediastatus); mii_attach(&emac3->dev, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); /* Choose a default media. */ if (LIST_FIRST(&mii->mii_phys) == NULL) { ifmedia_add(&mii->mii_media, IFM_ETHER|IFM_NONE, 0, NULL); ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_NONE); } else { ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_AUTO); } if_attach(ifp); ether_ifattach(ifp, emac3->eaddr); spd_intr_establish(SPD_NIC, smap_intr, sc); #if NRND > 0 rnd_attach_source(&sc->rnd_source, DEVNAME, RND_TYPE_NET, RND_FLAG_DEFAULT); #endif }
void uhidev_attach(device_t parent, device_t self, void *aux) { struct uhidev_softc *sc = device_private(self); struct usbif_attach_arg *uiaa = aux; struct usbd_interface *iface = uiaa->uiaa_iface; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; struct uhidev_attach_arg uha; device_t dev; struct uhidev *csc; int maxinpktsize, size, nrepid, repid, repsz; int *repsizes; int i; void *desc; const void *descptr; usbd_status err; char *devinfop; int locs[UHIDBUSCF_NLOCS]; sc->sc_dev = self; sc->sc_udev = uiaa->uiaa_device; sc->sc_iface = iface; aprint_naive("\n"); aprint_normal("\n"); mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB); id = usbd_get_interface_descriptor(iface); devinfop = usbd_devinfo_alloc(uiaa->uiaa_device, 0); aprint_normal_dev(self, "%s, iclass %d/%d\n", devinfop, id->bInterfaceClass, id->bInterfaceSubClass); usbd_devinfo_free(devinfop); if (!pmf_device_register(self, NULL, NULL)) aprint_error_dev(self, "couldn't establish power handler\n"); (void)usbd_set_idle(iface, 0, 0); #if 0 if ((usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_NO_SET_PROTO) == 0 && id->bInterfaceSubClass != UISUBCLASS_BOOT) (void)usbd_set_protocol(iface, 1); #endif maxinpktsize = 0; sc->sc_iep_addr = sc->sc_oep_addr = -1; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(iface, i); if (ed == NULL) { aprint_error_dev(self, "could not read endpoint descriptor\n"); sc->sc_dying = 1; return; } DPRINTFN(10,("uhidev_attach: bLength=%d bDescriptorType=%d " "bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d" " bInterval=%d\n", ed->bLength, ed->bDescriptorType, ed->bEndpointAddress & UE_ADDR, UE_GET_DIR(ed->bEndpointAddress)==UE_DIR_IN? "in" : "out", ed->bmAttributes & UE_XFERTYPE, UGETW(ed->wMaxPacketSize), ed->bInterval)); if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) { maxinpktsize = UGETW(ed->wMaxPacketSize); sc->sc_iep_addr = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) { sc->sc_oep_addr = ed->bEndpointAddress; } else { aprint_verbose_dev(self, "endpoint %d: ignored\n", i); } } /* * Check that we found an input interrupt endpoint. The output interrupt * endpoint is optional */ if (sc->sc_iep_addr == -1) { aprint_error_dev(self, "no input interrupt endpoint\n"); sc->sc_dying = 1; return; } /* XXX need to extend this */ descptr = NULL; if (uiaa->uiaa_vendor == USB_VENDOR_WACOM) { static uByte reportbuf[] = {2, 2, 2}; /* The report descriptor for the Wacom Graphire is broken. */ switch (uiaa->uiaa_product) { case USB_PRODUCT_WACOM_GRAPHIRE: case USB_PRODUCT_WACOM_GRAPHIRE2: case USB_PRODUCT_WACOM_GRAPHIRE3_4X5: case USB_PRODUCT_WACOM_GRAPHIRE3_6X8: case USB_PRODUCT_WACOM_GRAPHIRE4_4X5: /* The 6x8 too? */ /* * The Graphire3 needs 0x0202 to be written to * feature report ID 2 before it'll start * returning digitizer data. */ usbd_set_report(uiaa->uiaa_iface, UHID_FEATURE_REPORT, 2, &reportbuf, sizeof(reportbuf)); size = sizeof(uhid_graphire3_4x5_report_descr); descptr = uhid_graphire3_4x5_report_descr; break; default: /* Keep descriptor */ break; } } if (USBIF_IS_XINPUT(uiaa)) { size = sizeof(uhid_xinput_report_descr); descptr = uhid_xinput_report_descr; } if (USBIF_IS_X1INPUT(uiaa)) { sc->sc_flags |= UHIDEV_F_XB1; size = sizeof(uhid_x1input_report_descr); descptr = uhid_x1input_report_descr; } if (descptr) { desc = kmem_alloc(size, KM_SLEEP); if (desc == NULL) err = USBD_NOMEM; else { err = USBD_NORMAL_COMPLETION; memcpy(desc, descptr, size); } } else { desc = NULL; err = usbd_read_report_desc(uiaa->uiaa_iface, &desc, &size); } if (err) { aprint_error_dev(self, "no report descriptor\n"); sc->sc_dying = 1; return; } if (uiaa->uiaa_vendor == USB_VENDOR_HOSIDEN && uiaa->uiaa_product == USB_PRODUCT_HOSIDEN_PPP) { static uByte reportbuf[] = { 1 }; /* * This device was sold by Konami with its ParaParaParadise * game for PlayStation2. It needs to be "turned on" * before it will send any reports. */ usbd_set_report(uiaa->uiaa_iface, UHID_FEATURE_REPORT, 0, &reportbuf, sizeof(reportbuf)); } if (uiaa->uiaa_vendor == USB_VENDOR_LOGITECH && uiaa->uiaa_product == USB_PRODUCT_LOGITECH_CBT44 && size == 0xb1) { uint8_t *data = desc; /* * This device has a odd USAGE_MINIMUM value that would * cause the multimedia keys to have their usage number * shifted up one usage. Adjust so the usages are sane. */ if (data[0x56] == 0x19 && data[0x57] == 0x01 && data[0x58] == 0x2a && data[0x59] == 0x8c) data[0x57] = 0x00; } /* * Enable the Six Axis and DualShock 3 controllers. * See http://ps3.jim.sh/sixaxis/usb/ */ if (uiaa->uiaa_vendor == USB_VENDOR_SONY && uiaa->uiaa_product == USB_PRODUCT_SONY_PS3CONTROLLER) { usb_device_request_t req; char data[17]; int actlen; req.bmRequestType = UT_READ_CLASS_INTERFACE; req.bRequest = 1; USETW(req.wValue, 0x3f2); USETW(req.wIndex, 0); USETW(req.wLength, sizeof(data)); usbd_do_request_flags(sc->sc_udev, &req, data, USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT); } sc->sc_repdesc = desc; sc->sc_repdesc_size = size; uha.uiaa = uiaa; nrepid = uhidev_maxrepid(desc, size); if (nrepid < 0) return; if (nrepid > 0) aprint_normal_dev(self, "%d report ids\n", nrepid); nrepid++; repsizes = kmem_alloc(nrepid * sizeof(*repsizes), KM_SLEEP); if (repsizes == NULL) goto nomem; sc->sc_subdevs = kmem_zalloc(nrepid * sizeof(device_t), KM_SLEEP); if (sc->sc_subdevs == NULL) { kmem_free(repsizes, nrepid * sizeof(*repsizes)); nomem: aprint_error_dev(self, "no memory\n"); return; } /* Just request max packet size for the interrupt pipe */ sc->sc_isize = maxinpktsize; sc->sc_nrepid = nrepid; usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); for (repid = 0; repid < nrepid; repid++) { repsz = hid_report_size(desc, size, hid_input, repid); DPRINTF(("uhidev_match: repid=%d, repsz=%d\n", repid, repsz)); repsizes[repid] = repsz; } DPRINTF(("uhidev_attach: isize=%d\n", sc->sc_isize)); uha.parent = sc; for (repid = 0; repid < nrepid; repid++) { DPRINTF(("uhidev_match: try repid=%d\n", repid)); if (hid_report_size(desc, size, hid_input, repid) == 0 && hid_report_size(desc, size, hid_output, repid) == 0 && hid_report_size(desc, size, hid_feature, repid) == 0) { ; /* already NULL in sc->sc_subdevs[repid] */ } else { uha.reportid = repid; locs[UHIDBUSCF_REPORTID] = repid; dev = config_found_sm_loc(self, "uhidbus", locs, &uha, uhidevprint, config_stdsubmatch); sc->sc_subdevs[repid] = dev; if (dev != NULL) { csc = device_private(dev); csc->sc_in_rep_size = repsizes[repid]; #ifdef DIAGNOSTIC DPRINTF(("uhidev_match: repid=%d dev=%p\n", repid, dev)); if (csc->sc_intr == NULL) { kmem_free(repsizes, nrepid * sizeof(*repsizes)); aprint_error_dev(self, "sc_intr == NULL\n"); return; } #endif rnd_attach_source(&csc->rnd_source, device_xname(dev), RND_TYPE_TTY, RND_FLAG_DEFAULT); } } } kmem_free(repsizes, nrepid * sizeof(*repsizes)); return; }
/* Attach */ void url_attach(device_t parent, device_t self, void *aux) { struct url_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; usbd_device_handle dev = uaa->device; usbd_interface_handle iface; usbd_status err; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; char *devinfop; struct ifnet *ifp; struct mii_data *mii; u_char eaddr[ETHER_ADDR_LEN]; int i, s; sc->sc_dev = self; aprint_naive("\n"); aprint_normal("\n"); devinfop = usbd_devinfo_alloc(dev, 0); aprint_normal_dev(self, "%s\n", devinfop); usbd_devinfo_free(devinfop); /* Move the device into the configured state. */ err = usbd_set_config_no(dev, URL_CONFIG_NO, 1); if (err) { aprint_error_dev(self, "failed to set configuration" ", err=%s\n", usbd_errstr(err)); goto bad; } usb_init_task(&sc->sc_tick_task, url_tick_task, sc, 0); rw_init(&sc->sc_mii_rwlock); usb_init_task(&sc->sc_stop_task, (void (*)(void *))url_stop_task, sc, 0); /* get control interface */ err = usbd_device2interface_handle(dev, URL_IFACE_INDEX, &iface); if (err) { aprint_error_dev(self, "failed to get interface, err=%s\n", usbd_errstr(err)); goto bad; } sc->sc_udev = dev; sc->sc_ctl_iface = iface; sc->sc_flags = url_lookup(uaa->vendor, uaa->product)->url_flags; /* get interface descriptor */ id = usbd_get_interface_descriptor(sc->sc_ctl_iface); /* find endpoints */ sc->sc_bulkin_no = sc->sc_bulkout_no = sc->sc_intrin_no = -1; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_ctl_iface, i); if (ed == NULL) { aprint_error_dev(self, "couldn't get endpoint %d\n", i); goto bad; } if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK && UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) sc->sc_bulkin_no = ed->bEndpointAddress; /* RX */ else if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK && UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT) sc->sc_bulkout_no = ed->bEndpointAddress; /* TX */ else if ((ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT && UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) sc->sc_intrin_no = ed->bEndpointAddress; /* Status */ } if (sc->sc_bulkin_no == -1 || sc->sc_bulkout_no == -1 || sc->sc_intrin_no == -1) { aprint_error_dev(self, "missing endpoint\n"); goto bad; } s = splnet(); /* reset the adapter */ url_reset(sc); /* Get Ethernet Address */ err = url_mem(sc, URL_CMD_READMEM, URL_IDR0, (void *)eaddr, ETHER_ADDR_LEN); if (err) { aprint_error_dev(self, "read MAC address failed\n"); splx(s); goto bad; } /* Print Ethernet Address */ aprint_normal_dev(self, "Ethernet address %s\n", ether_sprintf(eaddr)); /* initialize interface information */ ifp = GET_IFP(sc); ifp->if_softc = sc; ifp->if_mtu = ETHERMTU; strncpy(ifp->if_xname, device_xname(self), IFNAMSIZ); ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_start = url_start; ifp->if_ioctl = url_ioctl; ifp->if_watchdog = url_watchdog; ifp->if_init = url_init; ifp->if_stop = url_stop; IFQ_SET_READY(&ifp->if_snd); /* * Do ifmedia setup. */ mii = &sc->sc_mii; mii->mii_ifp = ifp; mii->mii_readreg = url_int_miibus_readreg; mii->mii_writereg = url_int_miibus_writereg; #if 0 if (sc->sc_flags & URL_EXT_PHY) { mii->mii_readreg = url_ext_miibus_readreg; mii->mii_writereg = url_ext_miibus_writereg; } #endif mii->mii_statchg = url_miibus_statchg; mii->mii_flags = MIIF_AUTOTSLEEP; sc->sc_ec.ec_mii = mii; ifmedia_init(&mii->mii_media, 0, url_ifmedia_change, url_ifmedia_status); mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); if (LIST_FIRST(&mii->mii_phys) == NULL) { ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL); ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE); } else ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO); /* attach the interface */ if_attach(ifp); ether_ifattach(ifp, eaddr); rnd_attach_source(&sc->rnd_source, device_xname(self), RND_TYPE_NET, 0); callout_init(&sc->sc_stat_ch, 0); sc->sc_attached = 1; splx(s); usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, dev, sc->sc_dev); return; bad: sc->sc_dying = 1; return; }
void sbscn_attach_channel(struct sbscn_softc *sc, int chan, int intr) { struct sbscn_channel *ch = &sc->sc_channels[chan]; u_long chan_addr; struct tty *tp; ch->ch_sc = sc; ch->ch_num = chan; chan_addr = sc->sc_addr + (0x100 * chan); ch->ch_base = (void *)MIPS_PHYS_TO_KSEG1(chan_addr); ch->ch_isr_base = (void *)MIPS_PHYS_TO_KSEG1(sc->sc_addr + 0x220 + (0x20 * chan)); ch->ch_imr_base = (void *)MIPS_PHYS_TO_KSEG1(sc->sc_addr + 0x230 + (0x20 * chan)); #ifdef XXXCGDnotyet ch->ch_inchg_base = (void *)MIPS_PHYS_TO_KSEG1(sc->sc_addr + 0x2d0 + (0x10 * chan)); #endif ch->ch_i_dcd = ch->ch_i_dcd_pin = 0 /* XXXCGD */; ch->ch_i_cts = ch->ch_i_cts_pin = 0 /* XXXCGD */; ch->ch_i_dsr = ch->ch_i_dsr_pin = 0 /* XXXCGD */; ch->ch_i_ri = ch->ch_i_ri_pin = 0 /* XXXCGD */; ch->ch_i_mask = ch->ch_i_dcd | ch->ch_i_cts | ch->ch_i_dsr | ch->ch_i_ri; ch->ch_o_dtr = ch->ch_o_dtr_pin = 0 /* XXXCGD */; ch->ch_o_rts = ch->ch_o_rts_pin = 0 /* XXXCGD */; ch->ch_o_mask = ch->ch_o_dtr | ch->ch_o_rts; ch->ch_intrhand = cpu_intr_establish(intr, IPL_SERIAL, sbscn_intr, ch); callout_init(&ch->ch_diag_callout, 0); /* Disable interrupts before configuring the device. */ ch->ch_imr = 0; WRITE_REG(ch->ch_imr_base, ch->ch_imr); if (sbscn_cons_present && sbscn_cons_addr == chan_addr && sbscn_cons_chan == chan) { sbscn_cons_attached = 1; /* Make sure the console is always "hardwired". */ delay(1000); /* wait for output to finish */ SET(ch->ch_hwflags, SBSCN_HW_CONSOLE); SET(ch->ch_swflags, TIOCFLAG_SOFTCAR); } tp = tty_alloc(); tp->t_oproc = sbscn_start; tp->t_param = sbscn_param; tp->t_hwiflow = sbscn_hwiflow; ch->ch_tty = tp; ch->ch_rbuf = malloc(sbscn_rbuf_size << 1, M_DEVBUF, M_NOWAIT); if (ch->ch_rbuf == NULL) { aprint_error_dev(sc->sc_dev, "channel %d: unable to allocate ring buffer\n", chan); return; } ch->ch_ebuf = ch->ch_rbuf + (sbscn_rbuf_size << 1); tty_attach(tp); if (ISSET(ch->ch_hwflags, SBSCN_HW_CONSOLE)) { int maj; /* locate the major number */ maj = cdevsw_lookup_major(&sbscn_cdevsw); cn_tab->cn_dev = makedev(maj, (device_unit(sc->sc_dev) << 1) + chan); aprint_normal_dev(sc->sc_dev, "channel %d: %s\n", chan, "console"); } #ifdef KGDB /* * Allow kgdb to "take over" this port. If this is * the kgdb device, it has exclusive use. */ if (sbscn_kgdb_present && sbscn_kgdb_addr == chan_addr && sbscn_kgdb_chan == chan) { sbscn_kgdb_attached = 1; SET(sc->sc_hwflags, SBSCN_HW_KGDB); aprint_normal_dev(sc->sc_dev, "channel %d: %s\n", chan, "kgdb"); } #endif ch->ch_si = softint_establish(SOFTINT_SERIAL, sbscn_soft, ch); #ifdef RND_SBSCN rnd_attach_source(&ch->ch_rnd_source, device_xname(sc->sc_dev), RND_TYPE_TTY, 0); #endif sbscn_config(ch); SET(ch->ch_hwflags, SBSCN_HW_DEV_OK); }
static void bce_attach(device_t parent, device_t self, void *aux) { struct bce_softc *sc = device_private(self); struct pci_attach_args *pa = aux; const struct bce_product *bp; pci_chipset_tag_t pc = pa->pa_pc; pci_intr_handle_t ih; const char *intrstr = NULL; uint32_t command; pcireg_t memtype, pmode; bus_addr_t memaddr; bus_size_t memsize; void *kva; bus_dma_segment_t seg; int error, i, pmreg, rseg; struct ifnet *ifp; char intrbuf[PCI_INTRSTR_LEN]; sc->bce_dev = self; bp = bce_lookup(pa); KASSERT(bp != NULL); sc->bce_pa = *pa; /* BCM440x can only address 30 bits (1GB) */ if (bus_dmatag_subregion(pa->pa_dmat, 0, (1 << 30), &(sc->bce_dmatag), BUS_DMA_NOWAIT) != 0) { aprint_error_dev(self, "WARNING: failed to restrict dma range," " falling back to parent bus dma range\n"); sc->bce_dmatag = pa->pa_dmat; } aprint_naive(": Ethernet controller\n"); aprint_normal(": %s\n", bp->bp_name); /* * Map control/status registers. */ command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); command |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE; pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, command); command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); if (!(command & PCI_COMMAND_MEM_ENABLE)) { aprint_error_dev(self, "failed to enable memory mapping!\n"); return; } memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, BCE_PCI_BAR0); switch (memtype) { case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT: if (pci_mapreg_map(pa, BCE_PCI_BAR0, memtype, 0, &sc->bce_btag, &sc->bce_bhandle, &memaddr, &memsize) == 0) break; default: aprint_error_dev(self, "unable to find mem space\n"); return; } /* Get it out of power save mode if needed. */ if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT, &pmreg, NULL)) { pmode = pci_conf_read(pc, pa->pa_tag, pmreg + 4) & 0x3; if (pmode == 3) { /* * The card has lost all configuration data in * this state, so punt. */ aprint_error_dev(self, "unable to wake up from power state D3\n"); return; } if (pmode != 0) { aprint_normal_dev(self, "waking up from power state D%d\n", pmode); pci_conf_write(pc, pa->pa_tag, pmreg + 4, 0); } } if (pci_intr_map(pa, &ih)) { aprint_error_dev(self, "couldn't map interrupt\n"); return; } intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf)); sc->bce_intrhand = pci_intr_establish(pc, ih, IPL_NET, bce_intr, sc); if (sc->bce_intrhand == NULL) { aprint_error_dev(self, "couldn't establish interrupt\n"); if (intrstr != NULL) aprint_error(" at %s", intrstr); aprint_error("\n"); return; } aprint_normal_dev(self, "interrupting at %s\n", intrstr); /* reset the chip */ bce_reset(sc); /* * Allocate DMA-safe memory for ring descriptors. * The receive, and transmit rings can not share the same * 4k space, however both are allocated at once here. */ /* * XXX PAGE_SIZE is wasteful; we only need 1KB + 1KB, but * due to the limition above. ?? */ if ((error = bus_dmamem_alloc(sc->bce_dmatag, 2 * PAGE_SIZE, PAGE_SIZE, 2 * PAGE_SIZE, &seg, 1, &rseg, BUS_DMA_NOWAIT))) { aprint_error_dev(self, "unable to alloc space for ring descriptors, error = %d\n", error); return; } /* map ring space to kernel */ if ((error = bus_dmamem_map(sc->bce_dmatag, &seg, rseg, 2 * PAGE_SIZE, &kva, BUS_DMA_NOWAIT))) { aprint_error_dev(self, "unable to map DMA buffers, error = %d\n", error); bus_dmamem_free(sc->bce_dmatag, &seg, rseg); return; } /* create a dma map for the ring */ if ((error = bus_dmamap_create(sc->bce_dmatag, 2 * PAGE_SIZE, 1, 2 * PAGE_SIZE, 0, BUS_DMA_NOWAIT, &sc->bce_ring_map))) { aprint_error_dev(self, "unable to create ring DMA map, error = %d\n", error); bus_dmamem_unmap(sc->bce_dmatag, kva, 2 * PAGE_SIZE); bus_dmamem_free(sc->bce_dmatag, &seg, rseg); return; } /* connect the ring space to the dma map */ if (bus_dmamap_load(sc->bce_dmatag, sc->bce_ring_map, kva, 2 * PAGE_SIZE, NULL, BUS_DMA_NOWAIT)) { bus_dmamap_destroy(sc->bce_dmatag, sc->bce_ring_map); bus_dmamem_unmap(sc->bce_dmatag, kva, 2 * PAGE_SIZE); bus_dmamem_free(sc->bce_dmatag, &seg, rseg); return; } /* save the ring space in softc */ sc->bce_rx_ring = (struct bce_dma_slot *) kva; sc->bce_tx_ring = (struct bce_dma_slot *) ((char *)kva + PAGE_SIZE); /* Create the transmit buffer DMA maps. */ for (i = 0; i < BCE_NTXDESC; i++) { if ((error = bus_dmamap_create(sc->bce_dmatag, MCLBYTES, BCE_NTXFRAGS, MCLBYTES, 0, 0, &sc->bce_cdata.bce_tx_map[i])) != 0) { aprint_error_dev(self, "unable to create tx DMA map, error = %d\n", error); } sc->bce_cdata.bce_tx_chain[i] = NULL; } /* Create the receive buffer DMA maps. */ for (i = 0; i < BCE_NRXDESC; i++) { if ((error = bus_dmamap_create(sc->bce_dmatag, MCLBYTES, 1, MCLBYTES, 0, 0, &sc->bce_cdata.bce_rx_map[i])) != 0) { aprint_error_dev(self, "unable to create rx DMA map, error = %d\n", error); } sc->bce_cdata.bce_rx_chain[i] = NULL; } /* Set up ifnet structure */ ifp = &sc->ethercom.ec_if; strcpy(ifp->if_xname, device_xname(self)); ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = bce_ioctl; ifp->if_start = bce_start; ifp->if_watchdog = bce_watchdog; ifp->if_init = bce_init; ifp->if_stop = bce_stop; IFQ_SET_READY(&ifp->if_snd); /* Initialize our media structures and probe the MII. */ sc->bce_mii.mii_ifp = ifp; sc->bce_mii.mii_readreg = bce_mii_read; sc->bce_mii.mii_writereg = bce_mii_write; sc->bce_mii.mii_statchg = bce_statchg; sc->ethercom.ec_mii = &sc->bce_mii; ifmedia_init(&sc->bce_mii.mii_media, 0, ether_mediachange, ether_mediastatus); mii_attach(sc->bce_dev, &sc->bce_mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, MIIF_FORCEANEG|MIIF_DOPAUSE); if (LIST_FIRST(&sc->bce_mii.mii_phys) == NULL) { ifmedia_add(&sc->bce_mii.mii_media, IFM_ETHER | IFM_NONE, 0, NULL); ifmedia_set(&sc->bce_mii.mii_media, IFM_ETHER | IFM_NONE); } else ifmedia_set(&sc->bce_mii.mii_media, IFM_ETHER | IFM_AUTO); /* get the phy */ sc->bce_phy = bus_space_read_1(sc->bce_btag, sc->bce_bhandle, BCE_MAGIC_PHY) & 0x1f; /* * Enable activity led. * XXX This should be in a phy driver, but not currently. */ bce_mii_write(sc->bce_dev, 1, 26, /* MAGIC */ bce_mii_read(sc->bce_dev, 1, 26) & 0x7fff); /* MAGIC */ /* enable traffic meter led mode */ bce_mii_write(sc->bce_dev, 1, 27, /* MAGIC */ bce_mii_read(sc->bce_dev, 1, 27) | (1 << 6)); /* MAGIC */ /* Attach the interface */ if_attach(ifp); sc->enaddr[0] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle, BCE_MAGIC_ENET0); sc->enaddr[1] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle, BCE_MAGIC_ENET1); sc->enaddr[2] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle, BCE_MAGIC_ENET2); sc->enaddr[3] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle, BCE_MAGIC_ENET3); sc->enaddr[4] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle, BCE_MAGIC_ENET4); sc->enaddr[5] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle, BCE_MAGIC_ENET5); aprint_normal_dev(self, "Ethernet address %s\n", ether_sprintf(sc->enaddr)); ether_ifattach(ifp, sc->enaddr); rnd_attach_source(&sc->rnd_source, device_xname(self), RND_TYPE_NET, 0); callout_init(&sc->bce_timeout, 0); if (pmf_device_register(self, NULL, bce_resume)) pmf_class_network_register(self, ifp); else aprint_error_dev(self, "couldn't establish power handler\n"); }
/* * Attach the interface. Allocate softc structures, do * setup and ethernet/BPF attach. */ void kue_attach(device_t parent, device_t self, void *aux) { struct kue_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; char *devinfop; int s; struct ifnet *ifp; usbd_device_handle dev = uaa->device; usbd_interface_handle iface; usbd_status err; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; int i; DPRINTFN(5,(" : kue_attach: sc=%p, dev=%p", sc, dev)); sc->kue_dev = self; aprint_naive("\n"); aprint_normal("\n"); devinfop = usbd_devinfo_alloc(dev, 0); aprint_normal_dev(self, "%s\n", devinfop); usbd_devinfo_free(devinfop); err = usbd_set_config_no(dev, KUE_CONFIG_NO, 1); if (err) { aprint_error_dev(self, "failed to set configuration" ", err=%s\n", usbd_errstr(err)); return; } sc->kue_udev = dev; sc->kue_product = uaa->product; sc->kue_vendor = uaa->vendor; /* Load the firmware into the NIC. */ if (kue_load_fw(sc)) { aprint_error_dev(self, "loading firmware failed\n"); return; } err = usbd_device2interface_handle(dev, KUE_IFACE_IDX, &iface); if (err) { aprint_error_dev(self, "getting interface handle failed\n"); return; } sc->kue_iface = iface; id = usbd_get_interface_descriptor(iface); /* Find endpoints. */ for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(iface, i); if (ed == NULL) { aprint_error_dev(self, "couldn't get ep %d\n", i); return; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { sc->kue_ed[KUE_ENDPT_RX] = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { sc->kue_ed[KUE_ENDPT_TX] = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { sc->kue_ed[KUE_ENDPT_INTR] = ed->bEndpointAddress; } } if (sc->kue_ed[KUE_ENDPT_RX] == 0 || sc->kue_ed[KUE_ENDPT_TX] == 0) { aprint_error_dev(self, "missing endpoint\n"); return; } /* Read ethernet descriptor */ err = kue_ctl(sc, KUE_CTL_READ, KUE_CMD_GET_ETHER_DESCRIPTOR, 0, &sc->kue_desc, sizeof(sc->kue_desc)); if (err) { aprint_error_dev(self, "could not read Ethernet descriptor\n"); return; } sc->kue_mcfilters = malloc(KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN, M_USBDEV, M_NOWAIT); if (sc->kue_mcfilters == NULL) { aprint_error_dev(self, "no memory for multicast filter buffer\n"); return; } s = splnet(); /* * A KLSI chip was detected. Inform the world. */ aprint_normal_dev(self, "Ethernet address %s\n", ether_sprintf(sc->kue_desc.kue_macaddr)); /* Initialize interface info.*/ ifp = GET_IFP(sc); ifp->if_softc = sc; ifp->if_mtu = ETHERMTU; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = kue_ioctl; ifp->if_start = kue_start; ifp->if_watchdog = kue_watchdog; strncpy(ifp->if_xname, device_xname(sc->kue_dev), IFNAMSIZ); IFQ_SET_READY(&ifp->if_snd); /* Attach the interface. */ if_attach(ifp); ether_ifattach(ifp, sc->kue_desc.kue_macaddr); rnd_attach_source(&sc->rnd_source, device_xname(sc->kue_dev), RND_TYPE_NET, RND_FLAG_DEFAULT); sc->kue_attached = true; splx(s); usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->kue_udev, sc->kue_dev); return; }
void sscom_attach_subr(struct sscom_softc *sc) { int unit = sc->sc_unit; bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh = sc->sc_ioh; struct tty *tp; callout_init(&sc->sc_diag_callout, 0); #if (defined(MULTIPROCESSOR) || defined(LOCKDEBUG)) && defined(SSCOM_MPLOCK) sc->sc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SERIAL); #endif sc->sc_ucon = UCON_RXINT_ENABLE|UCON_TXINT_ENABLE; /* * set default for modem control hook */ if (sc->sc_set_modem_control == NULL) sc->sc_set_modem_control = sscom_set_modem_control; if (sc->sc_read_modem_status == NULL) sc->sc_read_modem_status = sscom_read_modem_status; /* Disable interrupts before configuring the device. */ KASSERT(sc->sc_change_txrx_interrupts != NULL); KASSERT(sc->sc_clear_interrupts != NULL); sscom_disable_txrxint(sc); #ifdef KGDB /* * Allow kgdb to "take over" this port. If this is * the kgdb device, it has exclusive use. */ if (unit == sscom_kgdb_unit) { SET(sc->sc_hwflags, SSCOM_HW_KGDB); sc->sc_ucon = UCON_DEBUGPORT; } #endif if (unit == sscomconsunit) { uint32_t stat; int timo; sscomconsattached = 1; sscomconstag = iot; sscomconsioh = ioh; /* wait for this transmission to complete */ timo = 1500000; do { stat = bus_space_read_4(iot, ioh, SSCOM_UTRSTAT); } while ((stat & UTRSTAT_TXEMPTY) == 0 && --timo > 0); /* Make sure the console is always "hardwired". */ SET(sc->sc_hwflags, SSCOM_HW_CONSOLE); SET(sc->sc_swflags, TIOCFLAG_SOFTCAR); sc->sc_ucon = UCON_DEBUGPORT; } /* set RX/TX trigger to half values */ bus_space_write_4(iot, ioh, SSCOM_UFCON, __SHIFTIN(4, UFCON_TXTRIGGER) | __SHIFTIN(4, UFCON_RXTRIGGER) | UFCON_FIFO_ENABLE | UFCON_TXFIFO_RESET| UFCON_RXFIFO_RESET); /* tx/rx fifo reset are auto-cleared */ bus_space_write_4(iot, ioh, SSCOM_UCON, sc->sc_ucon); #ifdef KGDB if (ISSET(sc->sc_hwflags, SSCOM_HW_KGDB)) { sscom_kgdb_attached = 1; printf("%s: kgdb\n", device_xname(sc->sc_dev)); sscom_enable_debugport(sc); return; } #endif tp = tty_alloc(); tp->t_oproc = sscomstart; tp->t_param = sscomparam; tp->t_hwiflow = sscomhwiflow; sc->sc_tty = tp; sc->sc_rbuf = malloc(sscom_rbuf_size << 1, M_DEVBUF, M_NOWAIT); sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; sc->sc_rbavail = sscom_rbuf_size; if (sc->sc_rbuf == NULL) { printf("%s: unable to allocate ring buffer\n", device_xname(sc->sc_dev)); return; } sc->sc_ebuf = sc->sc_rbuf + (sscom_rbuf_size << 1); tty_attach(tp); if (ISSET(sc->sc_hwflags, SSCOM_HW_CONSOLE)) { int maj; /* locate the major number */ maj = cdevsw_lookup_major(&sscom_cdevsw); cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev)); printf("%s: console (major=%d)\n", device_xname(sc->sc_dev), maj); } sc->sc_si = softint_establish(SOFTINT_SERIAL, sscomsoft, sc); #ifdef RND_COM rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), RND_TYPE_TTY, RND_FLAG_DEFAULT); #endif /* if there are no enable/disable functions, assume the device is always enabled */ if (ISSET(sc->sc_hwflags, SSCOM_HW_CONSOLE)) sscom_enable_debugport(sc); else sscom_disable_txrxint(sc); SET(sc->sc_hwflags, SSCOM_HW_DEV_OK); }
void sacom_attach_subr(struct sacom_softc *sc) { bus_addr_t iobase = sc->sc_baseaddr; bus_space_tag_t iot = sc->sc_iot; struct tty *tp; /* XXX Do we need to disable interrupts here? */ if (iot == sacomconstag && iobase == sacomconsaddr) { sacomconsattached = 1; sc->sc_speed = SACOMSPEED(sacomconsrate); /* Make sure the console is always "hardwired". */ delay(10000); /* wait for output to finish */ SET(sc->sc_hwflags, COM_HW_CONSOLE); SET(sc->sc_swflags, TIOCFLAG_SOFTCAR); } tp = ttymalloc(); tp->t_oproc = sacomstart; tp->t_param = sacomparam; tp->t_hwiflow = sacomhwiflow; sc->sc_tty = tp; sc->sc_rbuf = malloc(SACOM_RING_SIZE << 1, M_DEVBUF, M_NOWAIT); sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; sc->sc_rbavail = SACOM_RING_SIZE; if (sc->sc_rbuf == NULL) { printf("%s: unable to allocate ring buffer\n", sc->sc_dev.dv_xname); return; } sc->sc_ebuf = sc->sc_rbuf + (SACOM_RING_SIZE << 1); sc->sc_tbc = 0; tty_attach(tp); if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { int maj; /* locate the major number */ maj = cdevsw_lookup_major(&sacom_cdevsw); cn_tab->cn_dev = makedev(maj, device_unit(&sc->sc_dev)); delay(10000); /* XXX */ printf("%s: console\n", sc->sc_dev.dv_xname); delay(10000); /* XXX */ } sc->sc_si = softint_establish(SOFTINT_SERIAL, sacomsoft, sc); #if NRND > 0 && defined(RND_COM) rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname, RND_TYPE_TTY, 0); #endif /* if there are no enable/disable functions, assume the device is always enabled */ if (!sc->enable) sc->enabled = 1; sacom_config(sc); SET(sc->sc_hwflags, COM_HW_DEV_OK); }
static void at91dbgu_attach(device_t parent, device_t self, void *aux) { struct at91dbgu_softc *sc = device_private(self); struct at91bus_attach_args *sa = aux; struct tty *tp; printf("\n"); sc->sc_dev = self; bus_space_map(sa->sa_iot, sa->sa_addr, sa->sa_size, 0, &sc->sc_ioh); sc->sc_iot = sa->sa_iot; sc->sc_hwbase = sa->sa_addr; DBGUREG(DBGU_IDR) = -1; at91_intr_establish(sa->sa_pid, IPL_SERIAL, INTR_HIGH_LEVEL, dbgu_intr, sc); DBGU_INIT(AT91_MSTCLK, 115200U); if (sc->sc_iot == dbgu_cn_sc.sc_iot && sc->sc_hwbase == dbgu_cn_sc.sc_hwbase) { dbgu_cn_sc.sc_attached = 1; /* Make sure the console is always "hardwired". */ delay(10000); /* wait for output to finish */ SET(sc->sc_hwflags, COM_HW_CONSOLE); SET(sc->sc_swflags, TIOCFLAG_SOFTCAR); SET(sc->sc_ier, DBGU_INT_RXRDY); DBGUREG(DBGU_IER) = DBGU_INT_RXRDY; // @@@@@ } tp = tty_alloc(); tp->t_oproc = at91dbgu_start; tp->t_param = at91dbgu_param; tp->t_hwiflow = at91dbgu_hwiflow; sc->sc_tty = tp; sc->sc_rbuf = malloc(AT91DBGU_RING_SIZE << 1, M_DEVBUF, M_NOWAIT); sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; sc->sc_rbavail = AT91DBGU_RING_SIZE; if (sc->sc_rbuf == NULL) { printf("%s: unable to allocate ring buffer\n", device_xname(sc->sc_dev)); return; } sc->sc_ebuf = sc->sc_rbuf + (AT91DBGU_RING_SIZE << 1); sc->sc_tbc = 0; tty_attach(tp); if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { int maj; /* locate the major number */ maj = cdevsw_lookup_major(&at91dbgu_cdevsw); cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev)); aprint_normal("%s: console (maj %u min %u cn_dev %#"PRIx64")\n", device_xname(sc->sc_dev), maj, device_unit(sc->sc_dev), cn_tab->cn_dev); } sc->sc_si = softint_establish(SOFTINT_SERIAL, at91dbgu_soft, sc); #ifdef RND_COM rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), RND_TYPE_TTY, 0); #endif /* if there are no enable/disable functions, assume the device is always enabled */ if (!sc->enable) sc->enabled = 1; /* XXX configure register */ /* xxx_config(sc) */ SET(sc->sc_hwflags, COM_HW_DEV_OK); }
/* * Attach the interface to the kernel data structures. By the time this is * called, we know that the card exists at the given I/O address. We still * assume that the IRQ given is correct. */ void elattach(device_t parent, device_t self, void *aux) { struct el_softc *sc = device_private(self); struct isa_attach_args *ia = aux; bus_space_tag_t iot = ia->ia_iot; bus_space_handle_t ioh; struct ifnet *ifp = &sc->sc_ethercom.ec_if; u_int8_t myaddr[ETHER_ADDR_LEN]; u_int8_t i; sc->sc_dev = self; printf("\n"); DPRINTF(("Attaching %s...\n", device_xname(sc->sc_dev))); /* Map i/o space. */ if (bus_space_map(iot, ia->ia_io[0].ir_addr, 16, 0, &ioh)) { aprint_error_dev(self, "can't map i/o space\n"); return; } sc->sc_iot = iot; sc->sc_ioh = ioh; /* Reset the board. */ bus_space_write_1(iot, ioh, EL_AC, EL_AC_RESET); delay(5); bus_space_write_1(iot, ioh, EL_AC, 0); /* Now read the address. */ for (i = 0; i < ETHER_ADDR_LEN; i++) { bus_space_write_1(iot, ioh, EL_GPBL, i); myaddr[i] = bus_space_read_1(iot, ioh, EL_EAW); } /* Stop the board. */ elstop(sc); /* Initialize ifnet structure. */ strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); ifp->if_softc = sc; ifp->if_start = elstart; ifp->if_ioctl = elioctl; ifp->if_watchdog = elwatchdog; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS; IFQ_SET_READY(&ifp->if_snd); /* Now we can attach the interface. */ DPRINTF(("Attaching interface...\n")); if_attach(ifp); ether_ifattach(ifp, myaddr); /* Print out some information for the user. */ printf("%s: address %s\n", device_xname(self), ether_sprintf(myaddr)); sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq, IST_EDGE, IPL_NET, elintr, sc); DPRINTF(("Attaching to random...\n")); rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), RND_TYPE_NET, RND_FLAG_DEFAULT); DPRINTF(("elattach() finished.\n")); }
void at91usart_attach_subr(struct at91usart_softc *sc, struct at91bus_attach_args *sa) { struct tty *tp; int err; printf("\n"); if (bus_space_map(sa->sa_iot, sa->sa_addr, sa->sa_size, 0, &sc->sc_ioh)) panic("%s: Cannot map registers", device_xname(sc->sc_dev)); sc->sc_iot = sa->sa_iot; sc->sc_hwbase = sa->sa_addr; sc->sc_dmat = sa->sa_dmat; sc->sc_pid = sa->sa_pid; /* allocate fifos */ err = at91pdc_alloc_fifo(sc->sc_dmat, &sc->sc_rx_fifo, AT91USART_RING_SIZE, BUS_DMA_READ | BUS_DMA_STREAMING); if (err) panic("%s: cannot allocate rx fifo", device_xname(sc->sc_dev)); err = at91pdc_alloc_fifo(sc->sc_dmat, &sc->sc_tx_fifo, AT91USART_RING_SIZE, BUS_DMA_WRITE | BUS_DMA_STREAMING); if (err) panic("%s: cannot allocate tx fifo", device_xname(sc->sc_dev)); /* initialize uart */ at91_peripheral_clock(sc->sc_pid, 1); at91usart_writereg(sc, US_IDR, -1); at91usart_writereg(sc, US_RTOR, 12); // 12-bit timeout at91usart_writereg(sc, US_PDC + PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS); at91_intr_establish(sa->sa_pid, IPL_TTY, INTR_HIGH_LEVEL, at91usart_intr, sc); USART_INIT(sc, 115200U); #ifdef NOTYET if (sc->sc_iot == usart_cn_sc.sc_iot && sc->sc_hwbase == usart_cn_sc.sc_hwbase) { usart_cn_sc.sc_attached = 1; /* Make sure the console is always "hardwired". */ delay(10000); /* wait for output to finish */ SET(sc->sc_hwflags, COM_HW_CONSOLE); SET(sc->sc_swflags, TIOCFLAG_SOFTCAR); SET(sc->sc_ier, USART_INT_RXRDY); USARTREG(USART_IER) = USART_INT_RXRDY; // @@@@@ } #endif // NOTYET tp = tty_alloc(); tp->t_oproc = at91usart_start; tp->t_param = at91usart_param; tp->t_hwiflow = at91usart_hwiflow; sc->sc_tty = tp; tty_attach(tp); #if NOTYET if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { int maj; /* locate the major number */ maj = cdevsw_lookup_major(&at91usart_cdevsw); cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev)); aprint_normal("%s: console (maj %u min %u cn_dev %u)\n", device_xname(sc->sc_dev), maj, device_unit(sc->sc_dev), cn_tab->cn_dev); } #endif /* NOTYET */ sc->sc_si = softint_establish(SOFTINT_SERIAL, at91usart_soft, sc); #ifdef RND_COM rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), RND_TYPE_TTY, RND_FLAG_DEFAULT); #endif /* if there are no enable/disable functions, assume the device is always enabled */ if (!sc->enable) sc->enabled = 1; /* XXX configure register */ /* xxx_config(sc) */ SET(sc->sc_hwflags, COM_HW_DEV_OK); }
static void arckbd_attach(device_t parent, device_t self, void *aux) { struct arckbd_softc *sc = device_private(self); struct ioc_attach_args *ioc = aux; bus_space_tag_t bst; bus_space_handle_t bsh; struct wskbddev_attach_args wskbdargs; struct wsmousedev_attach_args wsmouseargs; bst = sc->sc_bst = ioc->ioc_fast_t; bsh = sc->sc_bsh = ioc->ioc_fast_h; sc->sc_dev = self; evcnt_attach_dynamic(&sc->sc_rev, EVCNT_TYPE_INTR, NULL, device_xname(sc->sc_dev), "rx intr"); sc->sc_rirq = irq_establish(IOC_IRQ_SRX, IPL_TTY, arckbd_rint, self, &sc->sc_rev); aprint_verbose("\n%s: interrupting at %s (rx)", device_xname(self), irq_string(sc->sc_rirq)); evcnt_attach_dynamic(&sc->sc_xev, EVCNT_TYPE_INTR, NULL, device_xname(sc->sc_dev), "tx intr"); sc->sc_xirq = irq_establish(IOC_IRQ_STX, IPL_TTY, arckbd_xint, self, &sc->sc_xev); irq_disable(sc->sc_xirq); aprint_verbose(" and %s (tx)", irq_string(sc->sc_xirq)); /* Initialisation of IOC KART per IOC Data Sheet section 6.2.3. */ /* Set up IOC counter 3 */ /* k_BAUD = 1/((latch+1)*16) MHz */ ioc_counter_start(parent, 3, 62500 / ARCKBD_BAUD - 1); /* Read from Rx register and discard. */ (void)bus_space_read_1(bst, bsh, 0); /* Kick the keyboard into life */ arckbd_send(self, ARCKBD_HRST, AS_HRST, 0); sc->sc_mapdata = arckbd_mapdata_default; sc->sc_mapdata.layout = KB_UK; /* Reasonable default */ /* Attach the wskbd console */ arckbd_cnattach(self); aprint_normal("\n"); rnd_attach_source(&sc->sc_rnd_source, device_xname(self), RND_TYPE_TTY, 0); wskbdargs.console = 1; /* XXX FIXME */ wskbdargs.keymap = &sc->sc_mapdata; wskbdargs.accessops = &arckbd_accessops; wskbdargs.accesscookie = sc; sc->sc_wskbddev = config_found_ia(self, "wskbddev", &wskbdargs, NULL); wsmouseargs.accessops = &arcmouse_accessops; wsmouseargs.accesscookie = sc; sc->sc_wsmousedev = config_found_ia(self, "wsmousedev", &wsmouseargs, NULL); }