/* * atabus_attach: * * Autoconfiguration attach routine. */ static void atabus_attach(device_t parent, device_t self, void *aux) { struct atabus_softc *sc = device_private(self); struct ata_channel *chp = aux; struct atabus_initq *initq; int error; sc->sc_chan = chp; aprint_normal("\n"); aprint_naive("\n"); sc->sc_dev = self; if (ata_addref(chp)) return; RUN_ONCE(&ata_init_ctrl, atabus_init); initq = malloc(sizeof(*initq), M_DEVBUF, M_WAITOK); initq->atabus_sc = sc; TAILQ_INSERT_TAIL(&atabus_initq_head, initq, atabus_initq); config_pending_incr(sc->sc_dev); if ((error = kthread_create(PRI_NONE, 0, NULL, atabus_thread, sc, &chp->ch_thread, "%s", device_xname(self))) != 0) aprint_error_dev(self, "unable to create kernel thread: error %d\n", error); if (!pmf_device_register(self, atabus_suspend, atabus_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); }
void pxapcic_attach(struct pxapcic_softc *sc, void (*socket_setup_hook)(struct pxapcic_socket *)) { struct pcmciabus_attach_args paa; struct pxapcic_socket *so; int i; printf(": %d slot%s\n", sc->sc_nslots, sc->sc_nslots==1 ? "" : "s"); if (bus_space_map(sc->sc_iot, PXA2X0_MEMCTL_BASE, PXA2X0_MEMCTL_SIZE, 0, &sc->sc_memctl_ioh)) { printf("%s: failed to map MEMCTL\n", sc->sc_dev.dv_xname); return; } /* Clear CIT (card present) and set NOS correctly. */ bus_space_write_4(sc->sc_iot, sc->sc_memctl_ioh, MEMCTL_MECR, sc->sc_nslots == 2 ? MECR_NOS : 0); /* zaurus: configure slot 1 first to make internal drive be wd0. */ for (i = sc->sc_nslots-1; i >= 0; i--) { so = &sc->sc_socket[i]; so->sc = sc; so->socket = i; so->flags = 0; socket_setup_hook(so); paa.paa_busname = "pcmcia"; paa.pct = (pcmcia_chipset_tag_t)&pxapcic_pcmcia_functions; paa.pch = (pcmcia_chipset_handle_t)so; paa.iobase = 0; paa.iosize = 0x4000000; so->pcmcia = config_found_sm(&sc->sc_dev, &paa, pxapcic_print, pxapcic_submatch); pxa2x0_gpio_set_function(sc->sc_irqpin[i], GPIO_IN); pxa2x0_gpio_set_function(sc->sc_irqcfpin[i], GPIO_IN); /* Card slot interrupt */ so->irq = pxa2x0_gpio_intr_establish(sc->sc_irqcfpin[i], IST_EDGE_BOTH, IPL_BIO /* XXX */, pxapcic_intr, so, sc->sc_dev.dv_xname); /* GPIO pin for interrupt */ so->irqpin = sc->sc_irqpin[i]; #ifdef DO_CONFIG_PENDING config_pending_incr(); #endif kthread_create_deferred(pxapcic_create_event_thread, so); } }
void usbf_attach(struct device *parent, struct device *self, void *aux) { struct usbf_softc *sc = (struct usbf_softc *)self; int usbrev; int speed; usbf_status err; /* Continue to set up the bus struct. */ sc->sc_bus = aux; sc->sc_bus->usbfctl = sc; usbrev = sc->sc_bus->usbrev; printf(": USB revision %s", usbrev_str[usbrev]); switch (usbrev) { case USBREV_2_0: speed = USB_SPEED_HIGH; break; case USBREV_1_1: case USBREV_1_0: speed = USB_SPEED_FULL; break; default: printf(", not supported\n"); sc->sc_dying = 1; return; } printf("\n"); /* Initialize the usbf struct. */ TAILQ_INIT(&sc->sc_tskq); /* Establish the software interrupt. */ if (usbf_softintr_establish(sc->sc_bus)) { printf("%s: can't establish softintr\n", DEVNAME(sc)); sc->sc_dying = 1; return; } /* Attach the function driver. */ err = usbf_new_device(self, sc->sc_bus, 0, speed, 0, &sc->sc_port); if (err) { printf("%s: usbf_new_device failed, %s\n", DEVNAME(sc), usbf_errstr(err)); sc->sc_dying = 1; return; } /* Create a process context for asynchronous tasks. */ config_pending_incr(); kthread_create_deferred(usbf_create_thread, sc); }
/* ARGSUSED */ static void ld_sdmmc_attach(device_t parent, device_t self, void *aux) { struct ld_sdmmc_softc *sc = device_private(self); struct sdmmc_attach_args *sa = aux; struct ld_softc *ld = &sc->sc_ld; struct lwp *lwp; ld->sc_dv = self; aprint_normal(": <0x%02x:0x%04x:%s:0x%02x:0x%08x:0x%03x>\n", sa->sf->cid.mid, sa->sf->cid.oid, sa->sf->cid.pnm, sa->sf->cid.rev, sa->sf->cid.psn, sa->sf->cid.mdt); aprint_naive("\n"); callout_init(&sc->sc_task.task_callout, CALLOUT_MPSAFE); sc->sc_hwunit = 0; /* always 0? */ sc->sc_sf = sa->sf; ld->sc_flags = LDF_ENABLED; ld->sc_secperunit = sc->sc_sf->csd.capacity; ld->sc_secsize = SDMMC_SECTOR_SIZE; ld->sc_maxxfer = MAXPHYS; ld->sc_maxqueuecnt = 1; ld->sc_dump = ld_sdmmc_dump; ld->sc_start = ld_sdmmc_start; /* * It is avoided that the error occurs when the card attaches it, * when wedge is supported. */ config_pending_incr(self); if (kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL, ld_sdmmc_doattach, sc, &lwp, "%sattach", device_xname(self))) { aprint_error_dev(self, "couldn't create thread\n"); } }
/* * finishing attaching the socket. Interrupts may now be on * if so expects the pcic interrupt to be blocked */ void pcic_attach_socket_finish(struct pcic_handle *h) { struct pcic_softc *sc = device_private(h->ph_parent); int reg; char cs[4]; DPRINTF(("%s: attach finish socket %ld\n", device_xname(h->ph_parent), (long) (h - &sc->handle[0]))); /* * Set up a powerhook to ensure it continues to interrupt on * card detect even after suspend. * (this works around a bug seen in suspend-to-disk on the * Sony VAIO Z505; on resume, the CSC_INTR state is not preserved). */ powerhook_establish(device_xname(h->ph_parent), pcic_power, h); /* enable interrupts on card detect, poll for them if no irq avail */ reg = PCIC_CSC_INTR_CD_ENABLE; if (sc->irq == -1) { if (sc->poll_established == 0) { callout_init(&sc->poll_ch, 0); callout_reset(&sc->poll_ch, hz / 2, pcic_poll_intr, sc); sc->poll_established = 1; } } else reg |= sc->irq << PCIC_CSC_INTR_IRQ_SHIFT; pcic_write(h, PCIC_CSC_INTR, reg); /* steer above mgmt interrupt to configured place */ if (sc->irq == 0) pcic_write(h, PCIC_INTR, PCIC_INTR_ENABLE); /* clear possible card detect interrupt */ (void) pcic_read(h, PCIC_CSC); DPRINTF(("%s: attach finish vendor 0x%02x\n", device_xname(h->ph_parent), h->vendor)); /* unsleep the cirrus controller */ if (h->vendor == PCIC_VENDOR_CIRRUS_PD67XX) { reg = pcic_read(h, PCIC_CIRRUS_MISC_CTL_2); if (reg & PCIC_CIRRUS_MISC_CTL_2_SUSPEND) { DPRINTF(("%s: socket %02x was suspended\n", device_xname(h->ph_parent), h->sock)); reg &= ~PCIC_CIRRUS_MISC_CTL_2_SUSPEND; pcic_write(h, PCIC_CIRRUS_MISC_CTL_2, reg); } } /* if there's a card there, then attach it. */ reg = pcic_read(h, PCIC_IF_STATUS); if ((reg & PCIC_IF_STATUS_CARDDETECT_MASK) == PCIC_IF_STATUS_CARDDETECT_PRESENT) { pcic_queue_event(h, PCIC_EVENT_INSERTION); h->laststate = PCIC_LASTSTATE_PRESENT; } else { h->laststate = PCIC_LASTSTATE_EMPTY; } /* * queue creation of a kernel thread to handle insert/removal events. */ #ifdef DIAGNOSTIC if (h->event_thread != NULL) panic("pcic_attach_socket: event thread"); #endif config_pending_incr(sc->dev); snprintf(cs, sizeof(cs), "%d,%d", h->chip, h->socket); if (kthread_create(PRI_NONE, 0, NULL, pcic_event_thread, h, &h->event_thread, "%s,%s", device_xname(h->ph_parent), cs)) { aprint_error_dev(h->ph_parent, "unable to create event thread for sock 0x%02x\n", h->sock); panic("pcic_attach_socket"); } }
STATIC void cardslotattach(device_t parent, device_t self, void *aux) { struct cardslot_softc *sc = device_private(self); struct cardslot_attach_args *caa = aux; struct cbslot_attach_args *cba = caa->caa_cb_attach; struct pcmciabus_attach_args *pa = caa->caa_16_attach; struct cardbus_softc *csc = NULL; struct pcmcia_softc *psc = NULL; sc->sc_dev = self; sc->sc_cb_softc = NULL; sc->sc_16_softc = NULL; SIMPLEQ_INIT(&sc->sc_events); sc->sc_th_enable = 0; aprint_naive("\n"); aprint_normal("\n"); DPRINTF(("%s attaching CardBus bus...\n", device_xname(self))); if (cba != NULL) { csc = device_private(config_found_ia(self, "cbbus", cba, cardslot_cb_print)); if (csc) { /* cardbus found */ DPRINTF(("%s: found cardbus on %s\n", __func__, device_xname(self))); sc->sc_cb_softc = csc; } } if (pa != NULL) { sc->sc_16_softc = config_found_sm_loc(self, "pcmciabus", NULL, pa, cardslot_16_print, cardslot_16_submatch); if (sc->sc_16_softc) { /* pcmcia 16-bit bus found */ DPRINTF(("%s: found 16-bit pcmcia bus\n", __func__)); psc = device_private(sc->sc_16_softc); } } if (csc != NULL || psc != NULL) { config_pending_incr(self); if (kthread_create(PRI_NONE, 0, NULL, cardslot_event_thread, sc, &sc->sc_event_thread, "%s", device_xname(self))) { aprint_error_dev(sc->sc_dev, "unable to create thread\n"); panic("cardslotattach"); } sc->sc_th_enable = 1; } if (csc && (csc->sc_cf->cardbus_ctrl)(csc->sc_cc, CARDBUS_CD)) { DPRINTF(("%s: CardBus card found\n", __func__)); /* attach deferred */ cardslot_event_throw(sc, CARDSLOT_EVENT_INSERTION_CB); } if (psc && (psc->pct->card_detect)(psc->pch)) { DPRINTF(("%s: 16-bit card found\n", __func__)); /* attach deferred */ cardslot_event_throw(sc, CARDSLOT_EVENT_INSERTION_16); } if (!pmf_device_register(self, NULL, NULL)) aprint_error_dev(self, "couldn't establish power handler\n"); }