示例#1
0
static void
pxaohci_power(int why, void *arg)
{
	struct pxaohci_softc *sc = (struct pxaohci_softc *)arg;
	int s;

	s = splhardusb();
	sc->sc.sc_bus.ub_usepolling++;
	switch (why) {
	case PWR_STANDBY:
	case PWR_SUSPEND:
#if 0
		ohci_power(why, &sc->sc);
#endif
		pxa2x0_clkman_config(CKEN_USBHC, 0);
		break;

	case PWR_RESUME:
		pxa2x0_clkman_config(CKEN_USBHC, 1);
		pxaohci_enable(sc);
#if 0
		ohci_power(why, &sc->sc);
#endif
		break;
	}
	sc->sc.sc_bus.ub_usepolling--;
	splx(s);
}
示例#2
0
void
uhci_pci_attach_deferred(struct device *self)
{
	struct uhci_pci_softc *sc = (struct uhci_pci_softc *)self;
	char *devname = sc->sc.sc_bus.bdev.dv_xname;
	usbd_status r;
	int s;

	s = splhardusb();
	
	sc->sc.sc_bus.dying = 0;
	r = uhci_init(&sc->sc);
	if (r != USBD_NORMAL_COMPLETION) {
		printf("%s: init failed, error=%d\n", devname, r);
		goto unmap_ret;
	}
	splx(s);

	/* Attach usb device. */
	sc->sc.sc_child = config_found((void *)sc, &sc->sc.sc_bus,
				       usbctlprint);

	return;

unmap_ret:
	bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
	pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
	splx(s);
}
示例#3
0
void
ehci_obio_attach(struct device *parent, struct device *self, void *aux)
{
	struct ehci_softc *sc = (void *)self;
	struct obio_attach_args *oa = aux;
	usbd_status r;
	int s;

	sc->iot = oa->oa_iot;
	sc->sc_size = 1028;
	if (bus_space_map(sc->iot, oa->oa_offset + USB_EHCI_OFFSET,
	    sc->sc_size, 0, &sc->ioh)) {
		printf(": can't map registers\n");
		return;
	}

	sc->sc_id_vendor = PCI_VENDOR_FREESCALE;
	strlcpy(sc->sc_vendor, "Freescale", sizeof sc->sc_vendor);

	sc->sc_bus.dmatag = &ehci_bus_dma_tag;

	bus_space_write_4(sc->iot, sc->ioh, USB_CONTROL, USB_CONTROL_USB_EN);
	bus_space_write_4(sc->iot, sc->ioh, USB_SNOOP1, USB_SNOOP_2GB);

	s = splhardusb();
	sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH);
	EOWRITE2(sc, EHCI_USBINTR, 0);

	intr_establish(oa->oa_ivec, IST_LEVEL, IPL_USB, ehci_intr, sc,
	    sc->sc_bus.bdev.dv_xname);

	r = ehci_init(sc);
	if (r != USBD_NORMAL_COMPLETION) {
		printf(": init failed, error=%d\n", r);
		goto unmap_ret;
	}
	splx(s);

	printf("\n");

	/* Attach usb device. */
	sc->sc_child = config_found((void *)sc, &sc->sc_bus, usbctlprint);

	return;

unmap_ret:
	bus_space_unmap(sc->iot, sc->ioh, sc->sc_size);
	splx(s);
}
示例#4
0
static void
uhci_pci_attach(device_t parent, device_t self, void *aux)
{
	struct uhci_pci_softc *sc = device_private(self);
	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	pcitag_t tag = pa->pa_tag;
	char const *intrstr;
	pci_intr_handle_t ih;
	pcireg_t csr;
	usbd_status r;
	int s;
	char intrbuf[PCI_INTRSTR_LEN];

	sc->sc.sc_dev = self;
	sc->sc.sc_bus.hci_private = sc;

	pci_aprint_devinfo(pa, NULL);

	/* Map I/O registers */
	if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
			   &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size)) {
		aprint_error_dev(self, "can't map i/o space\n");
		return;
	}

	/*
	 * Disable interrupts, so we don't get any spurious ones.
	 * Acknowledge all pending interrupts.
	 */
	bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_INTR, 0);
	bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_STS,
	    bus_space_read_2(sc->sc.iot, sc->sc.ioh, UHCI_STS));

	sc->sc_pc = pc;
	sc->sc_tag = tag;
	sc->sc.sc_bus.dmatag = pa->pa_dmat;

	/* Enable the device. */
	csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
	pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG,
		       csr | PCI_COMMAND_MASTER_ENABLE);

	/* Map and establish the interrupt. */
	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->sc_ih = pci_intr_establish(pc, ih, IPL_USB, uhci_intr, sc);
	if (sc->sc_ih == NULL) {
		aprint_error_dev(self, "couldn't establish interrupt");
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		return;
	}
	aprint_normal_dev(self, "interrupting at %s\n", intrstr);

	/*
	 * Set LEGSUP register to its default value.
	 * This can re-enable or trigger interrupts, so protect against
	 * them and explicitly disable and ACK them afterwards.
	 */
	s = splhardusb();
	pci_conf_write(pc, tag, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN);
	bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_INTR, 0);
	bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_STS,
	    bus_space_read_2(sc->sc.iot, sc->sc.ioh, UHCI_STS));
	splx(s);

	switch(pci_conf_read(pc, tag, PCI_USBREV) & PCI_USBREV_MASK) {
	case PCI_USBREV_PRE_1_0:
		sc->sc.sc_bus.usbrev = USBREV_PRE_1_0;
		break;
	case PCI_USBREV_1_0:
		sc->sc.sc_bus.usbrev = USBREV_1_0;
		break;
	case PCI_USBREV_1_1:
		sc->sc.sc_bus.usbrev = USBREV_1_1;
		break;
	default:
		sc->sc.sc_bus.usbrev = USBREV_UNKNOWN;
		break;
	}

	/* Figure out vendor for root hub descriptor. */
	sc->sc.sc_id_vendor = PCI_VENDOR(pa->pa_id);
	pci_findvendor(sc->sc.sc_vendor, sizeof(sc->sc.sc_vendor),
	    sc->sc.sc_id_vendor);
	r = uhci_init(&sc->sc);
	if (r != USBD_NORMAL_COMPLETION) {
		aprint_error_dev(self, "init failed, error=%d\n", r);
		return;
	}
	sc->sc_initialized = SC_INIT_UHCI;

#if NEHCI > 0
	usb_pci_add(&sc->sc_pci, pa, self);
#endif

	if (!pmf_device_register(self, uhci_suspend, uhci_pci_resume))
		aprint_error_dev(self, "couldn't establish power handler\n");
	else
		sc->sc_initialized |= SC_INIT_PMF;

	/* Attach usb device. */
	sc->sc.sc_child = config_found(self, &sc->sc.sc_bus, usbctlprint);
}
示例#5
0
void
ehci_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct ehci_pci_softc *sc = (struct ehci_pci_softc *)self;
	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	pcitag_t tag = pa->pa_tag;
	char const *intrstr;
	pci_intr_handle_t ih;
	const char *vendor;
	char *devname = sc->sc.sc_bus.bdev.dv_xname;
	usbd_status r;
	int s;

	/* Map I/O registers */
	if (pci_mapreg_map(pa, PCI_CBMEM, PCI_MAPREG_TYPE_MEM, 0,
			   &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size, 0)) {
		printf(": can't map mem space\n");
		return;
	}

	sc->sc_pc = pc;
	sc->sc_tag = tag;
	sc->sc.sc_bus.dmatag = pa->pa_dmat;

	/* Disable interrupts, so we don't get any spurious ones. */
	s = splhardusb();
	sc->sc.sc_offs = EREAD1(&sc->sc, EHCI_CAPLENGTH);
	DPRINTF(("%s: offs=%d\n", devname, sc->sc.sc_offs));
	EOWRITE2(&sc->sc, EHCI_USBINTR, 0);

	/* Handle quirks */
	switch (PCI_VENDOR(pa->pa_id)) {
	case PCI_VENDOR_ATI:
		if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ATI_SB600_EHCI ||
		    (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ATI_SB700_EHCI &&
		     pci_find_device(NULL, ehci_sb700_match))) {
			pcireg_t value;

			/* apply the ATI SB600/SB700 workaround */
			value = pci_conf_read(sc->sc_pc, sc->sc_tag,
			    EHCI_SBx00_WORKAROUND_REG);
			pci_conf_write(sc->sc_pc, sc->sc_tag,
			    EHCI_SBx00_WORKAROUND_REG, value |
			    EHCI_SBx00_WORKAROUND_ENABLE);
		}
		break;

	case PCI_VENDOR_VIATECH:
		if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_VIATECH_VT6202 &&
		    (PCI_REVISION(pa->pa_class) & 0xf0) == 0x60) {
			pcireg_t value;

			/*
			 * The VT6202 defaults to a 1 usec EHCI sleep time
			 * which hogs the PCI bus *badly*. Setting bit 5 of
			 * the register makes that sleep time use the conventional
			 * 10 usec.
			 */
			value = pci_conf_read(sc->sc_pc, sc->sc_tag,
			    EHCI_VT6202_WORKAROUND_REG);
			pci_conf_write(sc->sc_pc, sc->sc_tag,
			    EHCI_VT6202_WORKAROUND_REG, value | 0x20000000);
		}
		break;
	}

	/* Map and establish the interrupt. */
	if (pci_intr_map(pa, &ih)) {
		printf(": couldn't map interrupt\n");
		goto unmap_ret;
	}
	intrstr = pci_intr_string(pc, ih);
	sc->sc_ih = pci_intr_establish(pc, ih, IPL_USB | IPL_MPSAFE,
	    ehci_intr, sc, devname);
	if (sc->sc_ih == NULL) {
		printf(": couldn't establish interrupt");
		if (intrstr != NULL)
			printf(" at %s", intrstr);
		printf("\n");
		goto unmap_ret;
	}
	printf(": %s\n", intrstr);

	switch(pci_conf_read(pc, tag, PCI_USBREV) & PCI_USBREV_MASK) {
	case PCI_USBREV_PRE_1_0:
	case PCI_USBREV_1_0:
	case PCI_USBREV_1_1:
		sc->sc.sc_bus.usbrev = USBREV_UNKNOWN;
		printf("%s: pre-2.0 USB rev\n", devname);
		goto disestablish_ret;
	case PCI_USBREV_2_0:
		sc->sc.sc_bus.usbrev = USBREV_2_0;
		break;
	default:
		sc->sc.sc_bus.usbrev = USBREV_UNKNOWN;
		break;
	}

	/* Figure out vendor for root hub descriptor. */
	vendor = pci_findvendor(pa->pa_id);
	sc->sc.sc_id_vendor = PCI_VENDOR(pa->pa_id);
	if (vendor)
		strlcpy(sc->sc.sc_vendor, vendor, sizeof(sc->sc.sc_vendor));
	else
		snprintf(sc->sc.sc_vendor, sizeof(sc->sc.sc_vendor),
		    "vendor 0x%04x", PCI_VENDOR(pa->pa_id));

	/* Enable workaround for dropped interrupts as required */
	if (sc->sc.sc_id_vendor == PCI_VENDOR_VIATECH)
		sc->sc.sc_flags |= EHCIF_DROPPED_INTR_WORKAROUND;

	ehci_pci_takecontroller(sc, 0);
	r = ehci_init(&sc->sc);
	if (r != USBD_NORMAL_COMPLETION) {
		printf("%s: init failed, error=%d\n", devname, r);
		goto disestablish_ret;
	}

	/* Attach usb device. */
	config_found(self, &sc->sc.sc_bus, usbctlprint);
	splx(s);
	return;

disestablish_ret:
	pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
unmap_ret:
	bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
	splx(s);
}
示例#6
0
void
uhci_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct uhci_pci_softc *sc = (struct uhci_pci_softc *)self;
	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	pcitag_t tag = pa->pa_tag;
	char const *intrstr;
	pci_intr_handle_t ih;
	const char *vendor;
	char *devname = sc->sc.sc_bus.bdev.dv_xname;
	int s;

	/* Map I/O registers */
	if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
		    &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size, 0)) {
		printf(": can't map i/o space\n");
		return;
	}


	/* Disable interrupts, so we don't get any spurious ones. */
	s = splhardusb();
	bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_INTR, 0);

	sc->sc_pc = pc;
	sc->sc_tag = tag;
	sc->sc.sc_bus.dmatag = pa->pa_dmat;

	/* Map and establish the interrupt. */
	if (pci_intr_map(pa, &ih)) {
		printf(": couldn't map interrupt\n");
		goto unmap_ret;
	}
	intrstr = pci_intr_string(pc, ih);
	sc->sc_ih = pci_intr_establish(pc, ih, IPL_USB, uhci_intr, sc,
				       devname);
	if (sc->sc_ih == NULL) {
		printf(": couldn't establish interrupt");
		if (intrstr != NULL)
			printf(" at %s", intrstr);
		printf("\n");
		goto unmap_ret;
	}
	printf(": %s\n", intrstr);

	/* Set LEGSUP register to its default value. */
	pci_conf_write(pc, tag, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN);

	switch(pci_conf_read(pc, tag, PCI_USBREV) & PCI_USBREV_MASK) {
	case PCI_USBREV_PRE_1_0:
		sc->sc.sc_bus.usbrev = USBREV_PRE_1_0;
		break;
	case PCI_USBREV_1_0:
		sc->sc.sc_bus.usbrev = USBREV_1_0;
		break;
	case PCI_USBREV_1_1:
		sc->sc.sc_bus.usbrev = USBREV_1_1;
		break;
	default:
		sc->sc.sc_bus.usbrev = USBREV_UNKNOWN;
		break;
	}

	uhci_run(&sc->sc, 0);			/* stop the controller */
						/* disable interrupts */
	bus_space_barrier(sc->sc.iot, sc->sc.ioh, 0, sc->sc.sc_size,
	    BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
	bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_INTR, 0);

	/* Figure out vendor for root hub descriptor. */
	vendor = pci_findvendor(pa->pa_id);
	sc->sc.sc_id_vendor = PCI_VENDOR(pa->pa_id);
	if (vendor)
		strlcpy(sc->sc.sc_vendor, vendor, sizeof (sc->sc.sc_vendor));
	else
		snprintf(sc->sc.sc_vendor, sizeof (sc->sc.sc_vendor),
			"vendor 0x%04x", PCI_VENDOR(pa->pa_id));

	config_defer(self, uhci_pci_attach_deferred);
	
	/* Ignore interrupts for now */
	sc->sc.sc_bus.dying = 1;

	splx(s);

	return;

unmap_ret:
	bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
	splx(s);
}