示例#1
0
文件: ata.c 项目: goroutines/rumprun
/*
 * 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");
}
示例#2
0
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);
	}
}
示例#3
0
文件: usbf.c 项目: sofuture/bitrig
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);
}
示例#4
0
/* 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");
	}
}
示例#5
0
/*
 * 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");
	}
}
示例#6
0
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");
}