Example #1
0
static int
dotg_obio_attach(device_t dev)
{
	struct dwc_otg_softc *sc = device_get_softc(dev);
	uint32_t tmp;
	int err, rid;

	/* setup controller interface softc */

	/* initialise some bus fields */
	sc->sc_mode = DWC_MODE_HOST;
	sc->sc_bus.parent = dev;
	sc->sc_bus.devices = sc->sc_devices;
	sc->sc_bus.devices_max = DWC_OTG_MAX_DEVICES;
	sc->sc_bus.dma_bits = 32;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_bus,
	    USB_GET_DMA_TAG(dev), NULL)) {
		printf("No mem\n");
		return (ENOMEM);
	}
	rid = 0;
	sc->sc_io_res =
	    bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
	if (!(sc->sc_io_res)) {
		printf("Can`t alloc MEM\n");
		goto error;
	}
	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
	sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
	sc->sc_io_size = rman_get_size(sc->sc_io_res);

	rid = 0;
	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, 
	    &rid, RF_ACTIVE);
	if (!(sc->sc_irq_res)) {
		printf("Can`t alloc IRQ\n");
		goto error;
	}

	sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
	if (!(sc->sc_bus.bdev)) {
		printf("Can`t add usbus\n");
		goto error;
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);

#if (__FreeBSD_version >= 700031)
	err = bus_setup_intr(dev, sc->sc_irq_res,
	    INTR_TYPE_TTY | INTR_MPSAFE, dwc_otg_filter_interrupt,
	    dwc_otg_interrupt, sc, &sc->sc_intr_hdl);
#else
	#error error
	err = bus_setup_intr(dev, sc->sc_irq_res,
	    INTR_TYPE_BIO | INTR_MPSAFE,(driver_intr_t*)dwc_otg_interrupt,
	    sc, &sc->sc_intr_hdl);
#endif
	if (err) {
		sc->sc_intr_hdl = NULL;
		printf("Can`t set IRQ handle\n");
		goto error;
	}

	/* Run clock for OTG core */
	rt305x_sysctl_set(SYSCTL_CLKCFG1, rt305x_sysctl_get(SYSCTL_CLKCFG1) | 
	    SYSCTL_CLKCFG1_OTG_CLK_EN);
	tmp = rt305x_sysctl_get(SYSCTL_RSTCTRL);
	rt305x_sysctl_set(SYSCTL_RSTCTRL, tmp | SYSCTL_RSTCTRL_OTG);
	DELAY(100);
	/*
	 * Docs say that RSTCTRL bits for RT305x are W1C, so there should
	 * be no need for the below, but who really knows?
	 */
//	rt305x_sysctl_set(SYSCTL_RSTCTRL, tmp & ~SYSCTL_RSTCTRL_OTG);
//	DELAY(100);

	err = dwc_otg_init(sc);
	if (err) printf("dotg_init fail\n");
	if (!err) {
		err = device_probe_and_attach(sc->sc_bus.bdev);
		if (err) printf("device_probe_and_attach fail %d\n", err);
	}
	if (err) {
		goto error;
	}
	return (0);

error:
	dotg_obio_detach(dev);
	return (ENXIO);
}
Example #2
0
static int
ar71xx_ohci_attach(device_t dev)
{
	struct ar71xx_ohci_softc *sc = device_get_softc(dev);
	int err;
	int rid;

	/* initialise some bus fields */
	sc->sc_ohci.sc_bus.parent = dev;
	sc->sc_ohci.sc_bus.devices = sc->sc_ohci.sc_devices;
	sc->sc_ohci.sc_bus.devices_max = OHCI_MAX_DEVICES;
	sc->sc_ohci.sc_bus.dma_bits = 32;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_ohci.sc_bus,
	    USB_GET_DMA_TAG(dev), &ohci_iterate_hw_softc)) {
		return (ENOMEM);
	}

	sc->sc_ohci.sc_dev = dev;

	rid = 0;
	sc->sc_ohci.sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
	    RF_ACTIVE);
	if (sc->sc_ohci.sc_io_res == NULL) {
		err = ENOMEM;
		goto error;
	}
	sc->sc_ohci.sc_io_tag = rman_get_bustag(sc->sc_ohci.sc_io_res);
	sc->sc_ohci.sc_io_hdl = rman_get_bushandle(sc->sc_ohci.sc_io_res);
	sc->sc_ohci.sc_io_size = rman_get_size(sc->sc_ohci.sc_io_res);

	rid = 0;
	sc->sc_ohci.sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
	    RF_ACTIVE);
	if (sc->sc_ohci.sc_irq_res == NULL) {
		err = ENOMEM;
		goto error;
	}
	sc->sc_ohci.sc_bus.bdev = device_add_child(dev, "usbus", -1);
	if (sc->sc_ohci.sc_bus.bdev == NULL) {
		err = ENOMEM;
		goto error;
	}
	device_set_ivars(sc->sc_ohci.sc_bus.bdev, &sc->sc_ohci.sc_bus);

	err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res, 
	    INTR_TYPE_BIO | INTR_MPSAFE, NULL, 
	    ar71xx_ohci_intr, sc, &sc->sc_ohci.sc_intr_hdl);
	if (err) {
		err = ENXIO;
		goto error;
	}

	strlcpy(sc->sc_ohci.sc_vendor, "Atheros", sizeof(sc->sc_ohci.sc_vendor));

	bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl, OHCI_CONTROL, 0);

	err = ohci_init(&sc->sc_ohci);
	if (!err)
		err = device_probe_and_attach(sc->sc_ohci.sc_bus.bdev);

	if (err)
		goto error;
	return (0);

error:
	if (err) {
		ar71xx_ohci_detach(dev);
		return (err);
	}
	return (err);
}
Example #3
0
static int
vybrid_ehci_attach(device_t dev)
{
	struct vybrid_ehci_softc *esc;
	ehci_softc_t *sc;
	bus_space_handle_t bsh;
	int err;
	int reg;

	esc = device_get_softc(dev);
	esc->dev = dev;

	sc = &esc->base;
	sc->sc_bus.parent = dev;
	sc->sc_bus.devices = sc->sc_devices;
	sc->sc_bus.devices_max = EHCI_MAX_DEVICES;

	if (bus_alloc_resources(dev, vybrid_ehci_spec, esc->res)) {
		device_printf(dev, "could not allocate resources\n");
		return (ENXIO);
	}

	/* EHCI registers */
	sc->sc_io_tag = rman_get_bustag(esc->res[0]);
	bsh = rman_get_bushandle(esc->res[0]);
	sc->sc_io_size = rman_get_size(esc->res[0]);

	esc->bst_usbc = rman_get_bustag(esc->res[1]);
	esc->bsh_usbc = rman_get_bushandle(esc->res[1]);

	esc->bst_phy = rman_get_bustag(esc->res[2]);
	esc->bsh_phy = rman_get_bushandle(esc->res[2]);

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(dev),
		&ehci_iterate_hw_softc))
		return (ENXIO);

#if 0
	printf("USBx_HCSPARAMS is 0x%08x\n",
	    bus_space_read_4(sc->sc_io_tag, bsh, USB_HCSPARAMS));
	printf("USB_ID == 0x%08x\n",
	    bus_space_read_4(sc->sc_io_tag, bsh, USB_ID));
	printf("USB_HWGENERAL == 0x%08x\n",
	    bus_space_read_4(sc->sc_io_tag, bsh, USB_HWGENERAL));
	printf("USB_HWHOST == 0x%08x\n",
	    bus_space_read_4(sc->sc_io_tag, bsh, USB_HWHOST));
	printf("USB_HWDEVICE == 0x%08x\n",
	    bus_space_read_4(sc->sc_io_tag, bsh, USB_HWDEVICE));
	printf("USB_HWTXBUF == 0x%08x\n",
	    bus_space_read_4(sc->sc_io_tag, bsh, USB_HWTXBUF));
	printf("USB_HWRXBUF == 0x%08x\n",
	    bus_space_read_4(sc->sc_io_tag, bsh, USB_HWRXBUF));
#endif

	if (phy_init(esc)) {
		device_printf(dev, "Could not setup PHY\n");
		return (1);
	}

	/*
	 * Set handle to USB related registers subregion used by
	 * generic EHCI driver.
	 */
	err = bus_space_subregion(sc->sc_io_tag, bsh, 0x100,
	    sc->sc_io_size, &sc->sc_io_hdl);
	if (err != 0)
		return (ENXIO);

	/* Setup interrupt handler */
	err = bus_setup_intr(dev, esc->res[3], INTR_TYPE_BIO | INTR_MPSAFE,
	    NULL, (driver_intr_t *)ehci_interrupt, sc,
	    &sc->sc_intr_hdl);
	if (err) {
		device_printf(dev, "Could not setup irq, "
		    "%d\n", err);
		return (1);
	}

	/* Add USB device */
	sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
	if (!sc->sc_bus.bdev) {
		device_printf(dev, "Could not add USB device\n");
		err = bus_teardown_intr(dev, esc->res[5],
		    sc->sc_intr_hdl);
		if (err)
			device_printf(dev, "Could not tear down irq,"
			    " %d\n", err);
		return (1);
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);

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

	/* Set host mode */
	reg = bus_space_read_4(sc->sc_io_tag, sc->sc_io_hdl, 0xA8);
	reg |= 0x3;
	bus_space_write_4(sc->sc_io_tag, sc->sc_io_hdl, 0xA8, reg);

	/* Set flags */
	sc->sc_flags |= EHCI_SCFLG_SETMODE | EHCI_SCFLG_NORESTERM;

	err = ehci_init(sc);
	if (!err) {
		sc->sc_flags |= EHCI_SCFLG_DONEINIT;
		err = device_probe_and_attach(sc->sc_bus.bdev);
	} else {
		device_printf(dev, "USB init failed err=%d\n", err);

		device_delete_child(dev, sc->sc_bus.bdev);
		sc->sc_bus.bdev = NULL;

		err = bus_teardown_intr(dev, esc->res[5],
		    sc->sc_intr_hdl);
		if (err)
			device_printf(dev, "Could not tear down irq,"
			    " %d\n", err);
		return (1);
	}
	return (0);
}
Example #4
0
static int
exynos_ehci_attach(device_t dev)
{
	struct exynos_ehci_softc *esc;
	ehci_softc_t *sc;
	bus_space_handle_t bsh;
	int err;

	esc = device_get_softc(dev);
	esc->dev = dev;
	sc = &esc->base;
	sc->sc_bus.parent = dev;
	sc->sc_bus.devices = sc->sc_devices;
	sc->sc_bus.devices_max = EHCI_MAX_DEVICES;

	if (bus_alloc_resources(dev, exynos_ehci_spec, esc->res)) {
		device_printf(dev, "could not allocate resources\n");
		return (ENXIO);
	}

	/* EHCI registers */
	sc->sc_io_tag = rman_get_bustag(esc->res[0]);
	bsh = rman_get_bushandle(esc->res[0]);
	sc->sc_io_size = rman_get_size(esc->res[0]);

	/* EHCI HOST ctrl registers */
	esc->host_bst = rman_get_bustag(esc->res[1]);
	esc->host_bsh = rman_get_bushandle(esc->res[1]);

	/* PWR registers */
	esc->pwr_bst = rman_get_bustag(esc->res[2]);
	esc->pwr_bsh = rman_get_bushandle(esc->res[2]);

	/* SYSREG */
	esc->sysreg_bst = rman_get_bustag(esc->res[3]);
	esc->sysreg_bsh = rman_get_bushandle(esc->res[3]);

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(dev),
		&ehci_iterate_hw_softc))
		return (ENXIO);

	/*
	 * Set handle to USB related registers subregion used by
	 * generic EHCI driver.
	 */
	err = bus_space_subregion(sc->sc_io_tag, bsh, 0x0,
	    sc->sc_io_size, &sc->sc_io_hdl);
	if (err != 0)
		return (ENXIO);

	phy_init(esc);

	/* Setup interrupt handler */
	err = bus_setup_intr(dev, esc->res[4], INTR_TYPE_BIO | INTR_MPSAFE,
	    NULL, (driver_intr_t *)ehci_interrupt, sc,
	    &sc->sc_intr_hdl);
	if (err) {
		device_printf(dev, "Could not setup irq, "
		    "%d\n", err);
		return (1);
	}

	/* Add USB device */
	sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
	if (!sc->sc_bus.bdev) {
		device_printf(dev, "Could not add USB device\n");
		err = bus_teardown_intr(dev, esc->res[4],
		    sc->sc_intr_hdl);
		if (err)
			device_printf(dev, "Could not tear down irq,"
			    " %d\n", err);
		return (1);
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);

	strlcpy(sc->sc_vendor, "Samsung", sizeof(sc->sc_vendor));

	err = ehci_init(sc);
	if (!err) {
		sc->sc_flags |= EHCI_SCFLG_DONEINIT;
		err = device_probe_and_attach(sc->sc_bus.bdev);
	} else {
		device_printf(dev, "USB init failed err=%d\n", err);

		device_delete_child(dev, sc->sc_bus.bdev);
		sc->sc_bus.bdev = NULL;

		err = bus_teardown_intr(dev, esc->res[4],
		    sc->sc_intr_hdl);
		if (err)
			device_printf(dev, "Could not tear down irq,"
			    " %d\n", err);
		return (1);
	}
	return (0);
}
static int
atmegadci_attach(device_t dev)
{
	struct atmegadci_super_softc *sc = device_get_softc(dev);
	int err;
	int rid;

	/* setup MUSB OTG USB controller interface softc */
	sc->sc_otg.sc_clocks_on = &atmegadci_clocks_on;
	sc->sc_otg.sc_clocks_off = &atmegadci_clocks_off;

	/* initialise some bus fields */
	sc->sc_otg.sc_bus.parent = dev;
	sc->sc_otg.sc_bus.devices = sc->sc_otg.sc_devices;
	sc->sc_otg.sc_bus.devices_max = ATMEGA_MAX_DEVICES;
	sc->sc_otg.sc_bus.dma_bits = 32;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_otg.sc_bus,
	    USB_GET_DMA_TAG(dev), NULL)) {
		return (ENOMEM);
	}
	rid = 0;
	sc->sc_otg.sc_io_res =
	    bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);

	if (!(sc->sc_otg.sc_io_res)) {
		err = ENOMEM;
		goto error;
	}
	sc->sc_otg.sc_io_tag = rman_get_bustag(sc->sc_otg.sc_io_res);
	sc->sc_otg.sc_io_hdl = rman_get_bushandle(sc->sc_otg.sc_io_res);

	rid = 0;
	sc->sc_otg.sc_irq_res =
	    bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
	if (!(sc->sc_otg.sc_irq_res)) {
		goto error;
	}
	sc->sc_otg.sc_bus.bdev = device_add_child(dev, "usbus", -1);
	if (!(sc->sc_otg.sc_bus.bdev)) {
		goto error;
	}
	device_set_ivars(sc->sc_otg.sc_bus.bdev, &sc->sc_otg.sc_bus);

	err = bus_setup_intr(dev, sc->sc_otg.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
	    NULL, (driver_intr_t *)atmegadci_interrupt, sc, &sc->sc_otg.sc_intr_hdl);
	if (err) {
		sc->sc_otg.sc_intr_hdl = NULL;
		goto error;
	}
	err = atmegadci_init(&sc->sc_otg);
	if (!err) {
		err = device_probe_and_attach(sc->sc_otg.sc_bus.bdev);
	}
	if (err) {
		goto error;
	}
	return (0);

error:
	atmegadci_detach(dev);
	return (ENXIO);
}
Example #6
0
static int
musbotg_attach(device_t dev)
{
	struct musbotg_super_softc *sc = device_get_softc(dev);
	int err;
	int rid;

	/* setup MUSB OTG USB controller interface softc */
	sc->sc_otg.sc_clocks_on = &musbotg_clocks_on;
	sc->sc_otg.sc_clocks_off = &musbotg_clocks_off;
	sc->sc_otg.sc_clocks_arg = sc;

	/* initialise some bus fields */
	sc->sc_otg.sc_bus.parent = dev;
	sc->sc_otg.sc_bus.devices = sc->sc_otg.sc_devices;
	sc->sc_otg.sc_bus.devices_max = MUSB2_MAX_DEVICES;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_otg.sc_bus,
	    USB_GET_DMA_TAG(dev), NULL)) {
		return (ENOMEM);
	}
	rid = 0;
	sc->sc_otg.sc_io_res =
	    bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);

	if (!(sc->sc_otg.sc_io_res)) {
		err = ENOMEM;
		goto error;
	}
	sc->sc_otg.sc_io_tag = rman_get_bustag(sc->sc_otg.sc_io_res);
	sc->sc_otg.sc_io_hdl = rman_get_bushandle(sc->sc_otg.sc_io_res);
	sc->sc_otg.sc_io_size = rman_get_size(sc->sc_otg.sc_io_res);

	rid = 0;
	sc->sc_otg.sc_irq_res =
	    bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
	if (!(sc->sc_otg.sc_irq_res)) {
		goto error;
	}
	sc->sc_otg.sc_bus.bdev = device_add_child(dev, "usbus", -1);
	if (!(sc->sc_otg.sc_bus.bdev)) {
		goto error;
	}
	device_set_ivars(sc->sc_otg.sc_bus.bdev, &sc->sc_otg.sc_bus);

#if (__FreeBSD_version >= 700031)
	err = bus_setup_intr(dev, sc->sc_otg.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
	    NULL, (driver_intr_t *)musbotg_interrupt, sc, &sc->sc_otg.sc_intr_hdl);
#else
	err = bus_setup_intr(dev, sc->sc_otg.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
	    (driver_intr_t *)musbotg_interrupt, sc, &sc->sc_otg.sc_intr_hdl);
#endif
	if (err) {
		sc->sc_otg.sc_intr_hdl = NULL;
		goto error;
	}
	err = musbotg_init(&sc->sc_otg);
	if (!err) {
		err = device_probe_and_attach(sc->sc_otg.sc_bus.bdev);
	}
	if (err) {
		goto error;
	} else {
		/* poll VBUS one time */
		musbotg_vbus_poll(sc);
	}
	return (0);

error:
	musbotg_detach(dev);
	return (ENXIO);
}
Example #7
0
static int
dwc_otg_attach(device_t dev)
{
	struct dwc_otg_super_softc *sc = device_get_softc(dev);
	int err;
	int rid;

	/* initialise some bus fields */
	sc->sc_otg.sc_bus.parent = dev;
	sc->sc_otg.sc_bus.devices = sc->sc_otg.sc_devices;
	sc->sc_otg.sc_bus.devices_max = DWC_OTG_MAX_DEVICES;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_otg.sc_bus,
	    USB_GET_DMA_TAG(dev), NULL)) {
		return (ENOMEM);
	}
	rid = 0;
	sc->sc_otg.sc_io_res =
	    bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);

	if (!(sc->sc_otg.sc_io_res)) {
		err = ENOMEM;
		goto error;
	}
	sc->sc_otg.sc_io_tag = rman_get_bustag(sc->sc_otg.sc_io_res);
	sc->sc_otg.sc_io_hdl = rman_get_bushandle(sc->sc_otg.sc_io_res);
	sc->sc_otg.sc_io_size = rman_get_size(sc->sc_otg.sc_io_res);

	rid = 0;
	sc->sc_otg.sc_irq_res =
	    bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
	if (sc->sc_otg.sc_irq_res == NULL)
		goto error;

	sc->sc_otg.sc_bus.bdev = device_add_child(dev, "usbus", -1);
	if (sc->sc_otg.sc_bus.bdev == NULL)
		goto error;

	device_set_ivars(sc->sc_otg.sc_bus.bdev, &sc->sc_otg.sc_bus);

	err = bus_setup_intr(dev, sc->sc_otg.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
	    NULL, (driver_intr_t *)dwc_otg_interrupt, sc, &sc->sc_otg.sc_intr_hdl);
	if (err) {
		sc->sc_otg.sc_intr_hdl = NULL;
		goto error;
	}
	err = dwc_otg_init(&sc->sc_otg);
	if (err == 0) {
		err = device_probe_and_attach(sc->sc_otg.sc_bus.bdev);
	}
	if (err)
		goto error;


	return (0);

error:
	dwc_otg_detach(dev);
	return (ENXIO);
}
Example #8
0
int
dwc_otg_attach(device_t dev)
{
	struct dwc_otg_fdt_softc *sc = device_get_softc(dev);
	char usb_mode[24];
	int err;
	int rid;

	/* initialise some bus fields */
	sc->sc_otg.sc_bus.parent = dev;
	sc->sc_otg.sc_bus.devices = sc->sc_otg.sc_devices;
	sc->sc_otg.sc_bus.devices_max = DWC_OTG_MAX_DEVICES;
	sc->sc_otg.sc_bus.dma_bits = 32;

	/* get USB mode, if any */
	if (OF_getprop(ofw_bus_get_node(dev), "dr_mode",
	    &usb_mode, sizeof(usb_mode)) > 0) {

		/* ensure proper zero termination */
		usb_mode[sizeof(usb_mode) - 1] = 0;

		if (strcasecmp(usb_mode, "host") == 0)
			sc->sc_otg.sc_mode = DWC_MODE_HOST;
		else if (strcasecmp(usb_mode, "peripheral") == 0)
			sc->sc_otg.sc_mode = DWC_MODE_DEVICE;
		else if (strcasecmp(usb_mode, "otg") != 0) {
			device_printf(dev, "Invalid FDT dr_mode: %s\n",
			    usb_mode);
		}
	}

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_otg.sc_bus,
	    USB_GET_DMA_TAG(dev), NULL)) {
		return (ENOMEM);
	}
	rid = 0;
	sc->sc_otg.sc_io_res =
	    bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);

	if (!(sc->sc_otg.sc_io_res)) {
		err = ENOMEM;
		goto error;
	}
	sc->sc_otg.sc_io_tag = rman_get_bustag(sc->sc_otg.sc_io_res);
	sc->sc_otg.sc_io_hdl = rman_get_bushandle(sc->sc_otg.sc_io_res);
	sc->sc_otg.sc_io_size = rman_get_size(sc->sc_otg.sc_io_res);


	/*
	 * brcm,bcm2708-usb FDT provides two interrupts,
	 * we need only second one (VC_USB)
	 */
	rid = ofw_bus_is_compatible(dev, "brcm,bcm2708-usb") ? 1 : 0;
	sc->sc_otg.sc_irq_res =
	    bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
	if (sc->sc_otg.sc_irq_res == NULL)
		goto error;

	sc->sc_otg.sc_bus.bdev = device_add_child(dev, "usbus", -1);
	if (sc->sc_otg.sc_bus.bdev == NULL)
		goto error;

	device_set_ivars(sc->sc_otg.sc_bus.bdev, &sc->sc_otg.sc_bus);

	err = bus_setup_intr(dev, sc->sc_otg.sc_irq_res, INTR_TYPE_TTY | INTR_MPSAFE,
	    &dwc_otg_filter_interrupt, &dwc_otg_interrupt, sc, &sc->sc_otg.sc_intr_hdl);
	if (err) {
		sc->sc_otg.sc_intr_hdl = NULL;
		goto error;
	}
	err = dwc_otg_init(&sc->sc_otg);
	if (err == 0) {
		err = device_probe_and_attach(sc->sc_otg.sc_bus.bdev);
	}
	if (err)
		goto error;


	return (0);

error:
	dwc_otg_detach(dev);
	return (ENXIO);
}
Example #9
0
static int
ohci_ec_attach(device_t dev)
{
	struct ec_ohci_softc *sc = device_get_softc(dev);
	bus_space_handle_t bsh;
	int err;
	int rid;

	/* initialise some bus fields */
	sc->sc_ohci.sc_bus.parent = dev;
	sc->sc_ohci.sc_bus.devices = sc->sc_ohci.sc_devices;
	sc->sc_ohci.sc_bus.devices_max = OHCI_MAX_DEVICES;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_ohci.sc_bus,
	    USB_GET_DMA_TAG(dev), &ohci_iterate_hw_softc)) {
		return (ENOMEM);
	}
	sc->sc_ohci.sc_dev = dev;

	rid = MEM_RID;

	sc->sc_ohci.sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
	    &rid, RF_ACTIVE);

	if (!(sc->sc_ohci.sc_io_res)) {
		err = ENOMEM;
		goto error;
	}
	sc->sc_ohci.sc_io_tag = rman_get_bustag(sc->sc_ohci.sc_io_res);
	bsh = rman_get_bushandle(sc->sc_ohci.sc_io_res);
	/* Undocumented magic initialization */
	bus_space_write_4((sc)->sc_ohci.sc_io_tag, bsh,0x04, 0x146);

	bus_space_write_4((sc)->sc_ohci.sc_io_tag, bsh,0x44, 0x0200);

	DELAY(1000);

	sc->sc_ohci.sc_io_size = rman_get_size(sc->sc_ohci.sc_io_res);

	if (bus_space_subregion(sc->sc_ohci.sc_io_tag, bsh, 0x4000000,
	    sc->sc_ohci.sc_io_size, &sc->sc_ohci.sc_io_hdl) != 0)
		panic("%s: unable to subregion USB host registers",
		    device_get_name(dev));

	rid = 0;
	sc->sc_ohci.sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
	    RF_ACTIVE);
	if (!(sc->sc_ohci.sc_irq_res)) {
		goto error;
	}
	sc->sc_ohci.sc_bus.bdev = device_add_child(dev, "usbus", -1);
	if (!(sc->sc_ohci.sc_bus.bdev)) {
		goto error;
	}
	device_set_ivars(sc->sc_ohci.sc_bus.bdev, &sc->sc_ohci.sc_bus);

	strlcpy(sc->sc_ohci.sc_vendor, "Cavium",
		sizeof(sc->sc_ohci.sc_vendor));

#if (__FreeBSD_version >= 700031)
	err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res,
	    INTR_TYPE_BIO | INTR_MPSAFE,  NULL,
	    (driver_intr_t *)ohci_interrupt, sc,
	    &sc->sc_ohci.sc_intr_hdl);
#else
	err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res,
	    INTR_TYPE_BIO | INTR_MPSAFE,
	    (driver_intr_t *)ohci_interrupt, sc,
	    &sc->sc_ohci.sc_intr_hdl);
#endif
	if (err) {
		sc->sc_ohci.sc_intr_hdl = NULL;
		goto error;
	}

	bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl,
	    OHCI_CONTROL, 0);

	err = ohci_init(&sc->sc_ohci);
	if (!err) {
		err = device_probe_and_attach(sc->sc_ohci.sc_bus.bdev);
	}
	if (err) {
		goto error;
	}
	return (0);

error:
	ohci_ec_detach(dev);
	return (ENXIO);
}
Example #10
0
static int
dotg_fdt_attach(device_t dev)
{
	struct dwc_otg_softc *sc = device_get_softc(dev);
	int err, rid;

	/* setup controller interface softc */

	/* initialise some bus fields */
	sc->sc_mode = DWC_MODE_HOST;
	sc->sc_bus.parent = dev;
	sc->sc_bus.devices = sc->sc_devices;
	sc->sc_bus.devices_max = DWC_OTG_MAX_DEVICES;
	sc->sc_bus.dma_bits = 32;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_bus,
	    USB_GET_DMA_TAG(dev), NULL)) {
		printf("No mem\n");
		return (ENOMEM);
	}
	rid = 0;
	sc->sc_io_res =
	    bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
	if (!(sc->sc_io_res)) {
		printf("Can`t alloc MEM\n");
		goto error;
	}
	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
	sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
	sc->sc_io_size = rman_get_size(sc->sc_io_res);

	rid = 0;
	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, 
	    &rid, RF_ACTIVE);
	if (!(sc->sc_irq_res)) {
		printf("Can`t alloc IRQ\n");
		goto error;
	}

	sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
	if (!(sc->sc_bus.bdev)) {
		printf("Can`t add usbus\n");
		goto error;
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);

	err = bus_setup_intr(dev, sc->sc_irq_res,
	    INTR_TYPE_TTY | INTR_MPSAFE, dwc_otg_filter_interrupt,
	    dwc_otg_interrupt, sc, &sc->sc_intr_hdl);
	if (err) {
		sc->sc_intr_hdl = NULL;
		printf("Can`t set IRQ handle\n");
		goto error;
	}

	err = dwc_otg_init(sc);
	if (err) printf("dotg_init fail\n");
	if (!err) {
		err = device_probe_and_attach(sc->sc_bus.bdev);
		if (err) printf("device_probe_and_attach fail %d\n", err);
	}
	if (err) {
		goto error;
	}
	return (0);

error:
	dotg_fdt_detach(dev);
	return (ENXIO);
}
Example #11
0
static int
saf1761_otg_fdt_attach(device_t dev)
{
	struct saf1761_otg_softc *sc = device_get_softc(dev);
	char param[24];
	int err;
	int rid;

	/* get configuration from FDT */

	/* get bus-width, if any */
	if (OF_getprop(ofw_bus_get_node(dev), "bus-width",
	    &param, sizeof(param)) > 0) {
		param[sizeof(param) - 1] = 0;
		if (strcmp(param, "32") == 0)
			sc->sc_hw_mode |= SOTG_HW_MODE_CTRL_DATA_BUS_WIDTH;
	} else {
		/* assume 32-bit data bus */
		sc->sc_hw_mode |= SOTG_HW_MODE_CTRL_DATA_BUS_WIDTH;
	}

	/* get analog over-current setting */
	if (OF_getprop(ofw_bus_get_node(dev), "analog-oc",
	    &param, sizeof(param)) > 0) {
		sc->sc_hw_mode |= SOTG_HW_MODE_CTRL_ANA_DIGI_OC;
	}

	/* get DACK polarity */
	if (OF_getprop(ofw_bus_get_node(dev), "dack-polarity",
	    &param, sizeof(param)) > 0) {
		sc->sc_hw_mode |= SOTG_HW_MODE_CTRL_DACK_POL;
	}

	/* get DREQ polarity */
	if (OF_getprop(ofw_bus_get_node(dev), "dreq-polarity",
	    &param, sizeof(param)) > 0) {
		sc->sc_hw_mode |= SOTG_HW_MODE_CTRL_DREQ_POL;
	}

	/* get IRQ polarity */
	if (OF_getprop(ofw_bus_get_node(dev), "int-polarity",
	    &param, sizeof(param)) > 0) {
		sc->sc_interrupt_cfg |= SOTG_INTERRUPT_CFG_INTPOL;
		sc->sc_hw_mode |= SOTG_HW_MODE_CTRL_INTR_POL;
	}

	/* get IRQ level triggering */
	if (OF_getprop(ofw_bus_get_node(dev), "int-level",
	    &param, sizeof(param)) > 0) {
		sc->sc_interrupt_cfg |= SOTG_INTERRUPT_CFG_INTLVL;
		sc->sc_hw_mode |= SOTG_HW_MODE_CTRL_INTR_LEVEL;
	}

	/* initialise some bus fields */
	sc->sc_bus.parent = dev;
	sc->sc_bus.devices = sc->sc_devices;
	sc->sc_bus.devices_max = SOTG_MAX_DEVICES;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_bus,
	    USB_GET_DMA_TAG(dev), NULL)) {
		return (ENOMEM);
	}
	rid = 0;
	sc->sc_io_res =
	    bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);

	if (sc->sc_io_res == NULL) 
		goto error;

	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
	sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
	sc->sc_io_size = rman_get_size(sc->sc_io_res);

	/* try to allocate the HC interrupt first */
	rid = 1;
	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
	    RF_SHAREABLE | RF_ACTIVE);
	if (sc->sc_irq_res == NULL) {
		/* try to allocate a common IRQ second */
		rid = 0;
		sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
		    RF_SHAREABLE | RF_ACTIVE);
		if (sc->sc_irq_res == NULL)
			goto error;
	}

	sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
	if (sc->sc_bus.bdev == NULL)
		goto error;

	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);

	err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_TTY | INTR_MPSAFE,
	    &saf1761_otg_filter_interrupt, &saf1761_otg_interrupt, sc, &sc->sc_intr_hdl);
	if (err) {
		sc->sc_intr_hdl = NULL;
		goto error;
	}
	err = saf1761_otg_init(sc);
	if (err) {
		device_printf(dev, "Init failed\n");
		goto error;
	}
	err = device_probe_and_attach(sc->sc_bus.bdev);
	if (err) {
		device_printf(dev, "USB probe and attach failed\n");
		goto error;
	}
	return (0);

error:
	saf1761_otg_fdt_detach(dev);
	return (ENXIO);
}
Example #12
0
static int
ohci_atmelarm_attach(device_t dev)
{
    struct at91_ohci_softc *sc = device_get_softc(dev);
    int err;
    int rid;

    /* initialise some bus fields */
    sc->sc_ohci.sc_bus.parent = dev;
    sc->sc_ohci.sc_bus.devices = sc->sc_ohci.sc_devices;
    sc->sc_ohci.sc_bus.devices_max = OHCI_MAX_DEVICES;

    /* get all DMA memory */
    if (usb_bus_mem_alloc_all(&sc->sc_ohci.sc_bus,
                              USB_GET_DMA_TAG(dev), &ohci_iterate_hw_softc)) {
        return (ENOMEM);
    }
    sc->iclk = at91_pmc_clock_ref("ohci_clk");
    sc->fclk = at91_pmc_clock_ref("uhpck");

    sc->sc_ohci.sc_dev = dev;

    rid = MEM_RID;
    sc->sc_ohci.sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
                            &rid, RF_ACTIVE);

    if (!(sc->sc_ohci.sc_io_res)) {
        err = ENOMEM;
        goto error;
    }
    sc->sc_ohci.sc_io_tag = rman_get_bustag(sc->sc_ohci.sc_io_res);
    sc->sc_ohci.sc_io_hdl = rman_get_bushandle(sc->sc_ohci.sc_io_res);
    sc->sc_ohci.sc_io_size = rman_get_size(sc->sc_ohci.sc_io_res);

    rid = 0;
    sc->sc_ohci.sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
                             RF_ACTIVE);
    if (!(sc->sc_ohci.sc_irq_res)) {
        goto error;
    }
    sc->sc_ohci.sc_bus.bdev = device_add_child(dev, "usbus", -1);
    if (!(sc->sc_ohci.sc_bus.bdev)) {
        goto error;
    }
    device_set_ivars(sc->sc_ohci.sc_bus.bdev, &sc->sc_ohci.sc_bus);

    strlcpy(sc->sc_ohci.sc_vendor, "Atmel", sizeof(sc->sc_ohci.sc_vendor));

#if (__FreeBSD_version >= 700031)
    err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
                         NULL, (driver_intr_t *)ohci_interrupt, sc, &sc->sc_ohci.sc_intr_hdl);
#else
    err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
                         (driver_intr_t *)ohci_interrupt, sc, &sc->sc_ohci.sc_intr_hdl);
#endif
    if (err) {
        sc->sc_ohci.sc_intr_hdl = NULL;
        goto error;
    }
    /*
     * turn on the clocks from the AT91's point of view.  Keep the unit in reset.
     */
    at91_pmc_clock_enable(sc->iclk);
    at91_pmc_clock_enable(sc->fclk);
    bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl,
                      OHCI_CONTROL, 0);

    err = ohci_init(&sc->sc_ohci);
    if (!err) {
        err = device_probe_and_attach(sc->sc_ohci.sc_bus.bdev);
    }
    if (err) {
        goto error;
    }
    return (0);

error:
    ohci_atmelarm_detach(dev);
    return (ENXIO);
}
Example #13
0
static int
imx_ehci_attach(device_t dev)
{
	struct imx_ehci_softc *sc;
	ehci_softc_t *esc;
	int err, rid;

	sc = device_get_softc(dev);
	esc = &sc->ehci_softc;
	err = 0;

	/* Allocate bus_space resources. */
	rid = 0;
	sc->ehci_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
	    RF_ACTIVE);
	if (sc->ehci_mem_res == NULL) {
		device_printf(dev, "Cannot allocate memory resources\n");
		err = ENXIO;
		goto out;
	}

	rid = 0;
	sc->ehci_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
	    RF_ACTIVE);
	if (sc->ehci_irq_res == NULL) {
		device_printf(dev, "Cannot allocate IRQ resources\n");
		err = ENXIO;
		goto out;
	}

	esc->sc_io_tag = rman_get_bustag(sc->ehci_mem_res);
	esc->sc_bus.parent = dev;
	esc->sc_bus.devices = esc->sc_devices;
	esc->sc_bus.devices_max = EHCI_MAX_DEVICES;
	esc->sc_bus.dma_bits = 32;

	/* allocate all DMA memory */
	if (usb_bus_mem_alloc_all(&esc->sc_bus, USB_GET_DMA_TAG(dev),
	    &ehci_iterate_hw_softc) != 0) {
		device_printf(dev, "usb_bus_mem_alloc_all() failed\n");
		err = ENOMEM;
		goto out;
	}

	/*
	 * Set handle to USB related registers subregion used by
	 * generic EHCI driver.
	 */
	err = bus_space_subregion(esc->sc_io_tag, 
	    rman_get_bushandle(sc->ehci_mem_res),
	    IMX_EHCI_REG_OFF, IMX_EHCI_REG_SIZE, &esc->sc_io_hdl);
	if (err != 0) {
		device_printf(dev, "bus_space_subregion() failed\n");
		err = ENXIO;
		goto out;
	}

	/* Setup interrupt handler. */
	err = bus_setup_intr(dev, sc->ehci_irq_res, INTR_TYPE_BIO, NULL, 
	    (driver_intr_t *)ehci_interrupt, esc, &esc->sc_intr_hdl);
	if (err != 0) {
		device_printf(dev, "Could not setup IRQ\n");
		goto out;
	}

	/* Turn on clocks. */
	imx_ccm_usb_enable(dev);

	/* Add USB bus device. */
	esc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
	if (esc->sc_bus.bdev == NULL) {
		device_printf(dev, "Could not add USB device\n");
		goto out;
	}
	device_set_ivars(esc->sc_bus.bdev, &esc->sc_bus);

	esc->sc_id_vendor = USB_VENDOR_FREESCALE;
	strlcpy(esc->sc_vendor, "Freescale", sizeof(esc->sc_vendor));

	/* Set flags that affect ehci_init() behavior. */
	esc->sc_flags |= EHCI_SCFLG_DONTRESET | EHCI_SCFLG_NORESTERM;
	err = ehci_init(esc);
	if (err != 0) {
		device_printf(dev, "USB init failed, usb_err_t=%d\n", 
		    err);
		goto out;
	}
	esc->sc_flags |= EHCI_SCFLG_DONEINIT;

	/* Probe the bus. */
	err = device_probe_and_attach(esc->sc_bus.bdev);
	if (err != 0) {
		device_printf(dev,
		    "device_probe_and_attach() failed\n");
		goto out;
	}

	err = 0;

out:

	if (err != 0)
		imx_ehci_detach(dev);

	return (err);
}
Example #14
0
static int
bhnd_ohci_attach(device_t self)
{
	ohci_softc_t	*sc;
	int		 rid;
	int		 err;

	sc = device_get_softc(self);
	/* initialise some bus fields */
	sc->sc_bus.parent = self;
	sc->sc_bus.devices = sc->sc_devices;
	sc->sc_bus.devices_max = OHCI_MAX_DEVICES;
	sc->sc_bus.dma_bits = 32;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(self),
	    &ohci_iterate_hw_softc)) {
		return (ENOMEM);
	}
	sc->sc_dev = self;

	rid = 0;
	sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
	    RF_ACTIVE);
	if (!sc->sc_io_res) {
		device_printf(self, "Could not map memory\n");
		goto error;
	}
	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
	sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
	sc->sc_io_size = rman_get_size(sc->sc_io_res);

	rid = 0;
	sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
	    RF_SHAREABLE | RF_ACTIVE);
	if (sc->sc_irq_res == NULL) {
		device_printf(self, "Could not allocate irq\n");
		goto error;
	}
	sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
	if (!sc->sc_bus.bdev) {
		device_printf(self, "Could not add USB device\n");
		goto error;
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);

	strlcpy(sc->sc_vendor, "Broadcom", sizeof(sc->sc_vendor));

	err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
	    NULL, (driver_intr_t *)ohci_interrupt, sc, &sc->sc_intr_hdl);

	if (err) {
		device_printf(self, "Could not setup irq, %d\n", err);
		sc->sc_intr_hdl = NULL;
		goto error;
	}
	err = ohci_init(sc);
	if (!err) {
		err = device_probe_and_attach(sc->sc_bus.bdev);
	}
	if (err) {
		device_printf(self, "USB init failed\n");
		goto error;
	}
	return (0);

error:
	bhnd_ohci_detach(self);
	return (ENXIO);
}
Example #15
0
static int
uhci_pci_attach(device_t self)
{
	uhci_softc_t *sc = device_get_softc(self);
	int rid;
	int err;

	/* initialise some bus fields */
	sc->sc_bus.parent = self;
	sc->sc_bus.devices = sc->sc_devices;
	sc->sc_bus.devices_max = UHCI_MAX_DEVICES;
	sc->sc_bus.dma_bits = 32;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(self),
	    &uhci_iterate_hw_softc)) {
		return ENOMEM;
	}
	sc->sc_dev = self;

	pci_enable_busmaster(self);

	rid = PCI_UHCI_BASE_REG;
	sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_IOPORT, &rid,
	    RF_ACTIVE);
	if (!sc->sc_io_res) {
		device_printf(self, "Could not map ports\n");
		goto error;
	}
	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
	sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
	sc->sc_io_size = rman_get_size(sc->sc_io_res);

	/* disable interrupts */
	bus_space_write_2(sc->sc_io_tag, sc->sc_io_hdl, UHCI_INTR, 0);

	rid = 0;
	sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
	    RF_SHAREABLE | RF_ACTIVE);
	if (sc->sc_irq_res == NULL) {
		device_printf(self, "Could not allocate irq\n");
		goto error;
	}
	sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
	if (!sc->sc_bus.bdev) {
		device_printf(self, "Could not add USB device\n");
		goto error;
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);

	/*
	 * uhci_pci_match must never return NULL if uhci_pci_probe
	 * succeeded
	 */
	device_set_desc(sc->sc_bus.bdev, uhci_pci_match(self));
	switch (pci_get_vendor(self)) {
	case PCI_UHCI_VENDORID_INTEL:
		sprintf(sc->sc_vendor, "Intel");
		break;
	case PCI_UHCI_VENDORID_HP:
		sprintf(sc->sc_vendor, "HP");
		break;
	case PCI_UHCI_VENDORID_VIA:
		sprintf(sc->sc_vendor, "VIA");
		break;
	default:
		if (bootverbose) {
			device_printf(self, "(New UHCI DeviceId=0x%08x)\n",
			    pci_get_devid(self));
		}
		sprintf(sc->sc_vendor, "(0x%04x)", pci_get_vendor(self));
	}

	switch (pci_read_config(self, PCI_USBREV, 1) & PCI_USB_REV_MASK) {
	case PCI_USB_REV_PRE_1_0:
		sc->sc_bus.usbrev = USB_REV_PRE_1_0;
		break;
	case PCI_USB_REV_1_0:
		sc->sc_bus.usbrev = USB_REV_1_0;
		break;
	default:
		/* Quirk for Parallels Desktop 4.0 */
		device_printf(self, "USB revision is unknown. Assuming v1.1.\n");
		sc->sc_bus.usbrev = USB_REV_1_1;
		break;
	}

#if (__FreeBSD_version >= 700031)
	err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
	    NULL, (driver_intr_t *)uhci_interrupt, sc, &sc->sc_intr_hdl);
#else
	err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
	    (driver_intr_t *)uhci_interrupt, sc, &sc->sc_intr_hdl);
#endif

	if (err) {
		device_printf(self, "Could not setup irq, %d\n", err);
		sc->sc_intr_hdl = NULL;
		goto error;
	}
	/*
	 * Set the PIRQD enable bit and switch off all the others. We don't
	 * want legacy support to interfere with us XXX Does this also mean
	 * that the BIOS won't touch the keyboard anymore if it is connected
	 * to the ports of the root hub?
	 */
#ifdef USB_DEBUG
	if (pci_read_config(self, PCI_LEGSUP, 2) != PCI_LEGSUP_USBPIRQDEN) {
		device_printf(self, "LegSup = 0x%04x\n",
		    pci_read_config(self, PCI_LEGSUP, 2));
	}
#endif
	pci_write_config(self, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN, 2);

	err = uhci_init(sc);
	if (!err) {
		err = device_probe_and_attach(sc->sc_bus.bdev);
	}
	if (err) {
		device_printf(self, "USB init failed\n");
		goto error;
	}
	return (0);

error:
	uhci_pci_detach(self);
	return (ENXIO);
}
Example #16
0
static int
mv_ehci_attach(device_t self)
{
    ehci_softc_t *sc = device_get_softc(self);
    bus_space_handle_t bsh;
    int err;
    int rid;

    /* initialise some bus fields */
    sc->sc_bus.parent = self;
    sc->sc_bus.devices = sc->sc_devices;
    sc->sc_bus.devices_max = EHCI_MAX_DEVICES;

    /* get all DMA memory */
    if (usb_bus_mem_alloc_all(&sc->sc_bus,
                              USB_GET_DMA_TAG(self), &ehci_iterate_hw_softc)) {
        return (ENOMEM);
    }

    rid = 0;
    sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, RF_ACTIVE);
    if (!sc->sc_io_res) {
        device_printf(self, "Could not map memory\n");
        goto error;
    }
    sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
    bsh = rman_get_bushandle(sc->sc_io_res);
    sc->sc_io_size = rman_get_size(sc->sc_io_res) - MV_USB_HOST_OFST;

    /*
     * Marvell EHCI host controller registers start at certain offset
     * within the whole USB registers range, so create a subregion for the
     * host mode configuration purposes.
     */

    if (bus_space_subregion(sc->sc_io_tag, bsh, MV_USB_HOST_OFST,
                            sc->sc_io_size, &sc->sc_io_hdl) != 0)
        panic("%s: unable to subregion USB host registers",
              device_get_name(self));

    rid = 0;
    irq_err = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
                                     RF_SHAREABLE | RF_ACTIVE);
    if (irq_err == NULL) {
        device_printf(self, "Could not allocate error irq\n");
        mv_ehci_detach(self);
        return (ENXIO);
    }

    /*
     * Notice: Marvell EHCI controller has TWO interrupt lines, so make
     * sure to use the correct rid for the main one (controller interrupt)
     * -- refer to DTS for the right resource number to use here.
     */
    rid = 1;
    sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
                                            RF_SHAREABLE | RF_ACTIVE);
    if (sc->sc_irq_res == NULL) {
        device_printf(self, "Could not allocate irq\n");
        goto error;
    }

    sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
    if (!sc->sc_bus.bdev) {
        device_printf(self, "Could not add USB device\n");
        goto error;
    }
    device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
    device_set_desc(sc->sc_bus.bdev, EHCI_HC_DEVSTR);

    sprintf(sc->sc_vendor, "Marvell");

    err = bus_setup_intr(self, irq_err, INTR_TYPE_BIO,
                         err_intr, NULL, sc, &ih_err);
    if (err) {
        device_printf(self, "Could not setup error irq, %d\n", err);
        ih_err = NULL;
        goto error;
    }

    EWRITE4(sc, USB_BRIDGE_INTR_MASK, MV_USB_ADDR_DECODE_ERR |
            MV_USB_HOST_UNDERFLOW | MV_USB_HOST_OVERFLOW |
            MV_USB_DEVICE_UNDERFLOW);

    err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
                         NULL, (driver_intr_t *)ehci_interrupt, sc, &sc->sc_intr_hdl);
    if (err) {
        device_printf(self, "Could not setup irq, %d\n", err);
        sc->sc_intr_hdl = NULL;
        goto error;
    }

    /*
     * Workaround for Marvell integrated EHCI controller: reset of
     * the EHCI core clears the USBMODE register, which sets the core in
     * an undefined state (neither host nor agent), so it needs to be set
     * again for proper operation.
     *
     * Refer to errata document MV-S500832-00D.pdf (p. 5.24 GL USB-2) for
     * details.
     */
    sc->sc_flags |= EHCI_SCFLG_SETMODE;
    if (bootverbose)
        device_printf(self, "5.24 GL USB-2 workaround enabled\n");

    /* XXX all MV chips need it? */
    sc->sc_flags |= EHCI_SCFLG_FORCESPEED | EHCI_SCFLG_NORESTERM;

    err = ehci_init(sc);
    if (!err) {
        err = device_probe_and_attach(sc->sc_bus.bdev);
    }
    if (err) {
        device_printf(self, "USB init failed err=%d\n", err);
        goto error;
    }
    return (0);

error:
    mv_ehci_detach(self);
    return (ENXIO);
}
Example #17
0
static int
ehci_xls_attach(device_t self)
{
	ehci_softc_t *sc = device_get_softc(self);
	int err;
	int rid;

	sc->sc_bus.parent = self;
	sc->sc_bus.devices = sc->sc_devices;
	sc->sc_bus.devices_max = EHCI_MAX_DEVICES;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_bus,
	    USB_GET_DMA_TAG(self), &ehci_iterate_hw_softc)) {
		return (ENOMEM);
	}

	rid = 0;
	sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
	    RF_ACTIVE);
	if (!sc->sc_io_res) {
		device_printf(self, "Could not map memory\n");
		goto error;
	}
	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
	sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
	printf("IO Resource tag %lx, hdl %lx, size %lx\n",
	       (u_long)sc->sc_io_tag, (u_long)sc->sc_io_hdl, 
	       (u_long)sc->sc_io_size);

	rid = 0;
	sc->sc_irq_res = bus_alloc_resource(self, SYS_RES_IRQ, &rid,
	    PIC_USB_IRQ, PIC_USB_IRQ, 1, RF_SHAREABLE | RF_ACTIVE);
	if (sc->sc_irq_res == NULL) {
		device_printf(self, "Could not allocate irq\n");
		goto error;
	}

	sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
	if (!sc->sc_bus.bdev) {
		device_printf(self, "Could not add USB device\n");
		goto error;
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
	device_set_desc(sc->sc_bus.bdev, xlr_usb_dev_desc);

	sprintf(sc->sc_vendor, xlr_vendor_desc);

	err = bus_setup_intr(self, sc->sc_irq_res,
	    INTR_TYPE_BIO | INTR_MPSAFE, NULL,
	    (driver_intr_t *) ehci_interrupt, sc, &sc->sc_intr_hdl);
	if (err) {
		device_printf(self, "Could not setup irq, %d\n", err);
		sc->sc_intr_hdl = NULL;
		goto error;
	}

	err = ehci_init(sc);
	if (err) {
		device_printf(self, "USB init failed err=%d\n", err);
		goto error;
	}

	err = device_probe_and_attach(sc->sc_bus.bdev);
	if (err) {
		device_printf(self, "USB probe and attach failed err=%d\n", err);
		goto error;
	}

	return (0);

error:
	ehci_xls_detach(self);
	return (ENXIO);
}
Example #18
0
static int
uss820_atmelarm_attach(device_t dev)
{
	struct uss820dci_softc *sc = device_get_softc(dev);
	int err;
	int rid;

	/* initialise some bus fields */
	sc->sc_bus.parent = dev;
	sc->sc_bus.devices = sc->sc_devices;
	sc->sc_bus.devices_max = USS820_MAX_DEVICES;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_bus,
	    USB_GET_DMA_TAG(dev), NULL)) {
		return (ENOMEM);
	}
	rid = 0;
	sc->sc_io_res =
	    bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);

	if (!sc->sc_io_res) {
		goto error;
	}
	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
	sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
	sc->sc_io_size = rman_get_size(sc->sc_io_res);

	rid = 0;
	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
	    RF_SHAREABLE | RF_ACTIVE);
	if (sc->sc_irq_res == NULL) {
		goto error;
	}
	sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
	if (!(sc->sc_bus.bdev)) {
		goto error;
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);

#if (__FreeBSD_version >= 700031)
	err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
	    NULL, (driver_intr_t *)uss820dci_interrupt, sc, &sc->sc_intr_hdl);
#else
	err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
	    (driver_intr_t *)uss820dci_interrupt, sc, &sc->sc_intr_hdl);
#endif
	if (err) {
		sc->sc_intr_hdl = NULL;
		goto error;
	}
	err = uss820dci_init(sc);
	if (err) {
		device_printf(dev, "Init failed\n");
		goto error;
	}
	err = device_probe_and_attach(sc->sc_bus.bdev);
	if (err) {
		device_printf(dev, "USB probe and attach failed\n");
		goto error;
	}
	return (0);

error:
	uss820_atmelarm_detach(dev);
	return (ENXIO);
}
Example #19
0
static int
at91_udp_attach(device_t dev)
{
	struct at91_udp_softc *sc = device_get_softc(dev);
	int err;
	int rid;

	/* setup AT9100 USB device controller interface softc */

	sc->sc_dci.sc_clocks_on = &at91_udp_clocks_on;
	sc->sc_dci.sc_clocks_off = &at91_udp_clocks_off;
	sc->sc_dci.sc_clocks_arg = sc;
	sc->sc_dci.sc_pull_up = &at91_udp_pull_up;
	sc->sc_dci.sc_pull_down = &at91_udp_pull_down;
	sc->sc_dci.sc_pull_arg = sc;

	/* initialise some bus fields */
	sc->sc_dci.sc_bus.parent = dev;
	sc->sc_dci.sc_bus.devices = sc->sc_dci.sc_devices;
	sc->sc_dci.sc_bus.devices_max = AT91_MAX_DEVICES;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_dci.sc_bus,
	    USB_GET_DMA_TAG(dev), NULL)) {
		return (ENOMEM);
	}
	callout_init_mtx(&sc->sc_vbus, &sc->sc_dci.sc_bus.bus_mtx, 0);

	/*
	 * configure VBUS input pin, enable deglitch and enable
	 * interrupt :
	 */
	at91_pio_use_gpio(VBUS_BASE, VBUS_MASK);
	at91_pio_gpio_input(VBUS_BASE, VBUS_MASK);
	at91_pio_gpio_set_deglitch(VBUS_BASE, VBUS_MASK, 1);
	at91_pio_gpio_set_interrupt(VBUS_BASE, VBUS_MASK, 0);

	/*
	 * configure PULLUP output pin :
	 */
	at91_pio_use_gpio(PULLUP_BASE, PULLUP_MASK);
	at91_pio_gpio_output(PULLUP_BASE, PULLUP_MASK, 0);

	at91_udp_pull_down(sc);

	/* wait 10ms for pulldown to stabilise */
	usb_pause_mtx(NULL, hz / 100);

	sc->sc_mclk = at91_pmc_clock_ref("mck");
	sc->sc_iclk = at91_pmc_clock_ref("udc_clk");
	sc->sc_fclk = at91_pmc_clock_ref("udpck");

	rid = MEM_RID;
	sc->sc_dci.sc_io_res =
	    bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);

	if (!(sc->sc_dci.sc_io_res)) {
		err = ENOMEM;
		goto error;
	}
	sc->sc_dci.sc_io_tag = rman_get_bustag(sc->sc_dci.sc_io_res);
	sc->sc_dci.sc_io_hdl = rman_get_bushandle(sc->sc_dci.sc_io_res);
	sc->sc_dci.sc_io_size = rman_get_size(sc->sc_dci.sc_io_res);

	rid = 0;
	sc->sc_dci.sc_irq_res =
	    bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
	if (!(sc->sc_dci.sc_irq_res)) {
		goto error;
	}
	sc->sc_dci.sc_bus.bdev = device_add_child(dev, "usbus", -1);
	if (!(sc->sc_dci.sc_bus.bdev)) {
		goto error;
	}
	device_set_ivars(sc->sc_dci.sc_bus.bdev, &sc->sc_dci.sc_bus);

	err = bus_setup_intr(dev, sc->sc_dci.sc_irq_res, INTR_TYPE_TTY | INTR_MPSAFE,
	    at91dci_filter_interrupt, at91dci_interrupt, sc, &sc->sc_dci.sc_intr_hdl);
	if (err) {
		sc->sc_dci.sc_intr_hdl = NULL;
		goto error;
	}

	err = at91dci_init(&sc->sc_dci);
	if (!err) {
		err = device_probe_and_attach(sc->sc_dci.sc_bus.bdev);
	}
	if (err) {
		goto error;
	} else {
		/* poll VBUS one time */
		USB_BUS_LOCK(&sc->sc_dci.sc_bus);
		at91_vbus_poll(sc);
		USB_BUS_UNLOCK(&sc->sc_dci.sc_bus);
	}
	return (0);

error:
	at91_udp_detach(dev);
	return (ENXIO);
}
Example #20
0
static int
bhnd_ehci_attach(device_t self)
{
	ehci_softc_t	*sc;
	int		 err;
	int		 rid;

	sc = device_get_softc(self);
	/* initialise some bus fields */
	sc->sc_bus.parent = self;
	sc->sc_bus.devices = sc->sc_devices;
	sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
	sc->sc_bus.usbrev = USB_REV_2_0;
	sc->sc_bus.dma_bits = 32;

	/* get all DMA memory */
	if ((err = usb_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(self),
	    &ehci_iterate_hw_softc)) != 0) {
		BHND_ERROR_DEV(self, "can't allocate DMA memory: %d", err);
		return (ENOMEM);
	}

	rid = 0;
	sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, 
	    RF_ACTIVE);
	if (!sc->sc_io_res) {
		BHND_ERROR_DEV(self, "Could not map memory");
		goto error;
	}
	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
	sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
	sc->sc_io_size = rman_get_size(sc->sc_io_res);

	rid = 0;
	sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
	    RF_SHAREABLE | RF_ACTIVE);

	if (sc->sc_irq_res == NULL) {
		BHND_ERROR_DEV(self, "Could not allocate error irq");
		bhnd_ehci_detach(self);
		return (ENXIO);
	}

	sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
	if (!sc->sc_bus.bdev) {
		BHND_ERROR_DEV(self, "Could not add USB device");
		goto error;
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
	device_set_desc(sc->sc_bus.bdev, EHCI_HC_DEVSTR);

 	sprintf(sc->sc_vendor, "Broadcom");

	err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
	    NULL, (driver_intr_t *)ehci_interrupt, sc, &sc->sc_intr_hdl);
	if (err) {
		BHND_ERROR_DEV(self, "Could not setup irq, %d", err);
		sc->sc_intr_hdl = NULL;
		goto error;
	}

	sc->sc_flags |= EHCI_SCFLG_LOSTINTRBUG;
	sc->sc_vendor_post_reset = bhnd_ehci_post_reset;

	err = ehci_init(sc);
	if (!err) {
		err = device_probe_and_attach(sc->sc_bus.bdev);
	}
	if (err) {
		BHND_ERROR_DEV(self, "USB init failed err=%d", err);
		goto error;
	}
	return (0);

error:
	bhnd_ehci_detach(self);
	return (ENXIO);
}
Example #21
0
static int
ar71xx_ehci_attach(device_t self)
{
	struct ar71xx_ehci_softc *isc = device_get_softc(self);
	ehci_softc_t *sc = &isc->base;
	int err;
	int rid;

	/* initialise some bus fields */
	sc->sc_bus.parent = self;
	sc->sc_bus.devices = sc->sc_devices;
	sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
	sc->sc_bus.dma_bits = 32;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_bus,
	    USB_GET_DMA_TAG(self), &ehci_iterate_hw_softc)) {
		return (ENOMEM);
	}

	sc->sc_bus.usbrev = USB_REV_2_0;

	/* NB: hints fix the memory location and irq */

	rid = 0;
	sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, RF_ACTIVE);
	if (!sc->sc_io_res) {
		device_printf(self, "Could not map memory\n");
		goto error;
	}

	/*
	 * Craft special resource for bus space ops that handle
	 * byte-alignment of non-word addresses.  
	 */
	sc->sc_io_tag = ar71xx_bus_space_reversed;
	sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
	sc->sc_io_size = rman_get_size(sc->sc_io_res);

	rid = 0;
	sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
	    RF_ACTIVE | RF_SHAREABLE);
	if (sc->sc_irq_res == NULL) {
		device_printf(self, "Could not allocate irq\n");
		goto error;
	}
	sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
	if (!sc->sc_bus.bdev) {
		device_printf(self, "Could not add USB device\n");
		goto error;
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
	device_set_desc(sc->sc_bus.bdev, EHCI_HC_DEVSTR);

	sprintf(sc->sc_vendor, "Atheros");

	err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
	    NULL, ar71xx_ehci_intr, sc, &sc->sc_intr_hdl);
	if (err) {
		device_printf(self, "Could not setup irq, %d\n", err);
		sc->sc_intr_hdl = NULL;
		goto error;
	}

	/*
	 * Arrange to force Host mode, select big-endian byte alignment,
	 * and arrange to not terminate reset operations (the adapter
	 * will ignore it if we do but might as well save a reg write).
	 * Also, the controller has an embedded Transaction Translator
	 * which means port speed must be read from the Port Status
	 * register following a port enable.
	 */
	sc->sc_flags = EHCI_SCFLG_SETMODE;

	switch (ar71xx_soc) {
		case AR71XX_SOC_AR7241:
		case AR71XX_SOC_AR7242:
		case AR71XX_SOC_AR9130:
		case AR71XX_SOC_AR9132:
		case AR71XX_SOC_AR9330:
		case AR71XX_SOC_AR9331:
		case AR71XX_SOC_AR9341:
		case AR71XX_SOC_AR9342:
		case AR71XX_SOC_AR9344:
		case AR71XX_SOC_QCA9533:
		case AR71XX_SOC_QCA9533_V2:
		case AR71XX_SOC_QCA9556:
		case AR71XX_SOC_QCA9558:
			sc->sc_flags |= EHCI_SCFLG_TT | EHCI_SCFLG_NORESTERM;
			break;
		default:
			/* fallthrough */
			break;
	}

	/*
	 * ehci_reset() needs the correct offset to access the host controller
	 * registers. The AR724x/AR913x offsets aren't 0.
	*/
	sc->sc_offs = EHCI_CAPLENGTH(EREAD4(sc, EHCI_CAPLEN_HCIVERSION));

	(void) ehci_reset(sc);

	err = ehci_init(sc);
	if (!err) {
		err = device_probe_and_attach(sc->sc_bus.bdev);
	}
	if (err) {
		device_printf(self, "USB init failed err=%d\n", err);
		goto error;
	}
	return (0);

error:
	ar71xx_ehci_detach(self);
	return (ENXIO);
}
Example #22
0
static int
fsl_ehci_attach(device_t self)
{
	ehci_softc_t *sc;
	int rid;
	int err;
	bus_space_handle_t ioh;
	bus_space_tag_t iot;

	sc = device_get_softc(self);
	rid = 0;

	sc->sc_bus.parent = self;
	sc->sc_bus.devices = sc->sc_devices;
	sc->sc_bus.devices_max = EHCI_MAX_DEVICES;

	if (usb_bus_mem_alloc_all(&sc->sc_bus,
	    USB_GET_DMA_TAG(self), &ehci_iterate_hw_softc))
		return (ENOMEM);

	/* Allocate io resource for EHCI */
	sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
	    RF_ACTIVE);
	if (sc->sc_io_res == NULL) {
		err = fsl_ehci_detach(self);
		if (err) {
			device_printf(self,
			    "Detach of the driver failed with error %d\n",
			    err);
		}
		return (ENXIO);
	}
	iot = rman_get_bustag(sc->sc_io_res);

	/*
	 * Set handle to USB related registers subregion used by generic
	 * EHCI driver
	 */
	ioh = rman_get_bushandle(sc->sc_io_res);

	err = bus_space_subregion(iot, ioh, FSL_EHCI_REG_OFF, FSL_EHCI_REG_SIZE,
	    &sc->sc_io_hdl);
	if (err != 0) {
		err = fsl_ehci_detach(self);
		if (err) {
			device_printf(self,
			    "Detach of the driver failed with error %d\n",
			    err);
		}
		return (ENXIO);
	}

	/* Set little-endian tag for use by the generic EHCI driver */
	sc->sc_io_tag = &bs_le_tag;

	/* Allocate irq */
	sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
	    RF_ACTIVE);
	if (sc->sc_irq_res == NULL) {
		err = fsl_ehci_detach(self);
		if (err) {
			device_printf(self,
			    "Detach of the driver failed with error %d\n",
			    err);
		}
		return (ENXIO);
	}

	/* Setup interrupt handler */
	err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO,
	    NULL, (driver_intr_t *)ehci_interrupt, sc, &sc->sc_intr_hdl);
	if (err) {
		device_printf(self, "Could not setup irq, %d\n", err);
		sc->sc_intr_hdl = NULL;
		err = fsl_ehci_detach(self);
		if (err) {
			device_printf(self,
			    "Detach of the driver failed with error %d\n",
			    err);
		}
		return (ENXIO);
	}

	/* Add USB device */
	sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
	if (!sc->sc_bus.bdev) {
		device_printf(self, "Could not add USB device\n");
		err = fsl_ehci_detach(self);
		if (err) {
			device_printf(self,
			    "Detach of the driver failed with error %d\n",
			    err);
		}
		return (ENOMEM);
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);

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

	/* Enable USB */
	err = ehci_reset(sc);
	if (err) {
		device_printf(self, "Could not reset the controller\n");
		err = fsl_ehci_detach(self);
		if (err) {
			device_printf(self,
			    "Detach of the driver failed with error %d\n",
			    err);
		}
		return (ENXIO);
	}

	enable_usb(self, iot, ioh);
	set_snooping(iot, ioh);
	set_to_host_mode(sc);
	set_32b_prefetch(iot, ioh);

	/*
	 * If usb subsystem is enabled in U-Boot, port power has to be turned
	 * off to allow proper discovery of devices during boot up.
	 */
	clear_port_power(sc);

	/* Set flags */
	sc->sc_flags |= EHCI_SCFLG_DONTRESET | EHCI_SCFLG_NORESTERM;

	err = ehci_init(sc);
	if (!err) {
		sc->sc_flags |= EHCI_SCFLG_DONEINIT;
		err = device_probe_and_attach(sc->sc_bus.bdev);
	}

	if (err) {
		device_printf(self, "USB init failed err=%d\n", err);
		err = fsl_ehci_detach(self);
		if (err) {
			device_printf(self,
			    "Detach of the driver failed with error %d\n",
			    err);
		}
		return (EIO);
	}

	return (0);
}
Example #23
0
static int
zy7_ehci_attach(device_t dev)
{
	ehci_softc_t *sc = device_get_softc(dev);
	bus_space_handle_t bsh;
	int err, rid;
	
	/* initialize some bus fields */
	sc->sc_bus.parent = dev;
	sc->sc_bus.devices = sc->sc_devices;
	sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
	sc->sc_bus.dma_bits = 32;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_bus,
	    USB_GET_DMA_TAG(dev), &ehci_iterate_hw_softc))
		return (ENOMEM);

	/* Allocate memory. */
	rid = 0;
	sc->sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
					       &rid, RF_ACTIVE);
	if (sc->sc_io_res == NULL) {
		device_printf(dev, "Can't allocate memory");
		zy7_ehci_detach(dev);
		return (ENOMEM);
	}

	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
	bsh = rman_get_bushandle(sc->sc_io_res);
	sc->sc_io_size = EHCI_REG_SIZE;

	if (bus_space_subregion(sc->sc_io_tag, bsh, EHCI_REG_OFFSET,
				sc->sc_io_size, &sc->sc_io_hdl) != 0)
		panic("%s: unable to subregion USB host registers",
		      device_get_name(dev));

	/* Allocate IRQ. */
	rid = 0;
	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
						RF_ACTIVE);
	if (sc->sc_irq_res == NULL) {
		device_printf(dev, "Can't allocate IRQ\n");
		zy7_ehci_detach(dev);
		return (ENOMEM);
	}

	/* Add USB device */
	sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
	if (!sc->sc_bus.bdev) {
		device_printf(dev, "Could not add USB device\n");
		zy7_ehci_detach(dev);
		return (ENXIO);
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
	device_set_desc(sc->sc_bus.bdev, "Zynq-7000 ehci USB 2.0 controller");

	strcpy(sc->sc_vendor, "Xilinx"); /* or IP vendor? */

	/* Activate the interrupt */
	err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
			     NULL, (driver_intr_t *)ehci_interrupt, sc,
			     &sc->sc_intr_hdl);
	if (err) {
		device_printf(dev, "Cannot setup IRQ\n");
		zy7_ehci_detach(dev);
		return (err);
	}

	/* Customization. */
	sc->sc_flags |= EHCI_SCFLG_TT |	EHCI_SCFLG_NORESTERM;
	sc->sc_vendor_post_reset = zy7_ehci_post_reset;
	sc->sc_vendor_get_port_speed = ehci_get_port_speed_portsc;

	/* Modify FIFO burst threshold from 2 to 8. */
	bus_space_write_4(sc->sc_io_tag, bsh,
			  ZY7_USB_TXFILLTUNING,
			  8 << ZY7_USB_TXFILLTUNING_TXFIFOTHRES_SHFT);

	/* Handle PHY options. */
	if (zy7_phy_config(dev, sc->sc_io_tag, bsh) < 0) {
		device_printf(dev, "Cannot config phy!\n");
		zy7_ehci_detach(dev);
		return (EIO);
	}

	/* Init ehci. */
	err = ehci_init(sc);
	if (!err) {
		sc->sc_flags |= EHCI_SCFLG_DONEINIT;
		err = device_probe_and_attach(sc->sc_bus.bdev);
	}
	if (err) {
		device_printf(dev, "USB init failed err=%d\n", err);
		zy7_ehci_detach(dev);
		return (err);
	}

	return (0);
}
Example #24
0
/**
 *	omap_ehci_attach - driver entry point, sets up the ECHI controller/driver
 *	@dev: the new device handle
 *	
 *	Sets up bus spaces, interrupt handles, etc for the EHCI controller.  It also
 *	parses the resource hints and calls omap_ehci_init() to initialise the
 *	H/W.
 *
 *	LOCKING:
 *	none
 *
 *	RETURNS:
 *	0 on success or a positive error code on failure.
 */
static int
omap_ehci_attach(device_t dev)
{
	struct omap_ehci_softc *isc = device_get_softc(dev);
	ehci_softc_t *sc = &isc->base;
	int err;
	int rid;

	/* initialise some bus fields */
	sc->sc_bus.parent = dev;
	sc->sc_bus.devices = sc->sc_devices;
	sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
	sc->sc_bus.dma_bits = 32;

	sprintf(sc->sc_vendor, "Texas Instruments");

	/* save the device */
	isc->sc_dev = dev;
	
	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(dev),
	                          &ehci_iterate_hw_softc)) {
		return (ENOMEM);
	}
	
	/* Allocate resource for the EHCI register set */
	rid = 0;
	sc->sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
	if (!sc->sc_io_res) {
		device_printf(dev, "Error: Could not map EHCI memory\n");
		goto error;
	}
	/* Request an interrupt resource */
	rid = 0;
	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
	if (sc->sc_irq_res == NULL) {
		device_printf(dev, "Error: could not allocate irq\n");
		goto error;
	}

	/* Add this device as a child of the USBus device */
	sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
	if (!sc->sc_bus.bdev) {
		device_printf(dev, "Error: could not add USB device\n");
		goto error;
	}

	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
	device_set_desc(sc->sc_bus.bdev, OMAP_EHCI_HC_DEVSTR);
	
	/* Initialise the ECHI registers */
	err = omap_ehci_init(isc);
	if (err) {
		device_printf(dev, "Error: could not setup OMAP EHCI, %d\n", err);
		goto error;
	}
		
	/* Set the tag and size of the register set in the EHCI context */
	sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
	sc->sc_io_size = rman_get_size(sc->sc_io_res);

	/* Setup the interrupt */
	err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
						 NULL, (driver_intr_t *)ehci_interrupt, sc, &sc->sc_intr_hdl);
	if (err) {
		device_printf(dev, "Error: could not setup irq, %d\n", err);
		sc->sc_intr_hdl = NULL;
		goto error;
	}
	
	/* Finally we are ready to kick off the ECHI host controller */
	err = ehci_init(sc);
	if (err == 0) {
		err = device_probe_and_attach(sc->sc_bus.bdev);
	}
	if (err) {
		device_printf(dev, "Error: USB init failed err=%d\n", err);
		goto error;
	}
	
	return (0);
	
error:
	omap_ehci_detach(dev);
	return (ENXIO);
}
Example #25
0
static int
ehci_obio_attach(device_t self)
{
	ehci_softc_t *sc = device_get_softc(self);
	uint32_t reg;
	int err;
	int rid;

	/* setup controller interface softc */
	reg = rt305x_sysctl_get(SYSCTL_SYSCFG1);
	reg |= SYSCTL_SYSCFG1_USB0_HOST_MODE;
	rt305x_sysctl_set(SYSCTL_SYSCFG1, reg);

	reg = rt305x_sysctl_get(SYSCTL_CLKCFG1);
	reg |= SYSCTL_CLKCFG1_UPHY0_CLK_EN;
#ifdef MT7620
	reg |= SYSCTL_CLKCFG1_UPHY1_CLK_EN;
#endif
	rt305x_sysctl_set(SYSCTL_CLKCFG1, reg);

	reg = rt305x_sysctl_get(SYSCTL_RSTCTRL);
	reg |= SYSCTL_RSTCTRL_UPHY0 | SYSCTL_RSTCTRL_UPHY1;
	rt305x_sysctl_set(SYSCTL_RSTCTRL, reg);
	reg &= ~(SYSCTL_RSTCTRL_UPHY0 | SYSCTL_RSTCTRL_UPHY1);
	DELAY(100000);
	rt305x_sysctl_set(SYSCTL_RSTCTRL, reg);
	DELAY(100000);

	/* initialise some bus fields */
	sc->sc_bus.parent = self;
	sc->sc_bus.devices = sc->sc_devices;
	sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
	sc->sc_bus.dma_bits = 32;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_bus,
	    USB_GET_DMA_TAG(self), &ehci_iterate_hw_softc)) {
		printf("No mem\n");
		return (ENOMEM);
	}

	rid = 0;
	sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
				RF_ACTIVE);
	if (!sc->sc_io_res) {
		device_printf(self, "Could not map memory\n");
		goto error;
	}
	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
	sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
	sc->sc_io_size = rman_get_size(sc->sc_io_res);

	rid = 0;
	sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
		RF_SHAREABLE | RF_ACTIVE);
	if (sc->sc_irq_res == NULL) {
		device_printf(self, "Could not allocate irq\n");
		goto error;
	}

	sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
	if (!(sc->sc_bus.bdev)) {
		device_printf(self, "Could not add USB device\n");
		goto error;
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
	device_set_desc(sc->sc_bus.bdev, EHCI_HC_DEVSTR);

	sprintf(sc->sc_vendor, "Ralink");

	err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
		NULL, (driver_intr_t *)ehci_interrupt, sc, &sc->sc_intr_hdl);
	if (err) {
		device_printf(self, "Could not setup irq, %d\n", err);
		sc->sc_intr_hdl = NULL;
		goto error;
	}

	err = ehci_init(sc);
	if (!err) {
		err = device_probe_and_attach(sc->sc_bus.bdev);
	}
	if (err) {
		device_printf(self, "USB init failed err=%d\n", err);
		goto error;
	}
	return (0);

error:
	ehci_obio_detach(self);
	return (ENXIO);
}
Example #26
0
static int
ehci_ebus_attach(device_t self)
{
	ehci_softc_t *sc = device_get_softc(self);
	bus_space_handle_t bsh;
	int err;
	int rid;

	/* initialise some bus fields */
	sc->sc_bus.parent = self;
	sc->sc_bus.devices = sc->sc_devices;
	sc->sc_bus.devices_max = EHCI_MAX_DEVICES;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_bus,
	    USB_GET_DMA_TAG(self), &ehci_iterate_hw_softc)) {
		return (ENOMEM);
	}

	sc->sc_bus.usbrev = USB_REV_2_0;

	rid = 0;
	sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY,
	    &rid, RF_ACTIVE);
	if (!sc->sc_io_res) {
		device_printf(self, "Could not map memory\n");
		goto error;
	}
	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
	bsh = rman_get_bushandle(sc->sc_io_res);

	/*magic, undocumented initialization*/
	bus_space_write_4((sc)->sc_io_tag, bsh, 0x04, 0x106);

	bus_space_write_4((sc)->sc_io_tag, bsh, 0x40, (3 << 5)|0x2000);

	DELAY(1000);

	sc->sc_io_size =  4096;

	if (bus_space_subregion(sc->sc_io_tag, bsh, 0x4000000,
	    sc->sc_io_size, &sc->sc_io_hdl) != 0)
		panic("%s: unable to subregion USB host registers",
		    device_get_name(self));

	rid = 0;
	sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
	    RF_SHAREABLE | RF_ACTIVE);
	if (sc->sc_irq_res == NULL) {
		device_printf(self, "Could not allocate irq\n");
		ehci_ebus_detach(self);
		return (ENXIO);
	}

	sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
	if (!sc->sc_bus.bdev) {
		device_printf(self, "Could not add USB device\n");
		goto error;
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
	device_set_desc(sc->sc_bus.bdev, EHCI_HC_DEVSTR);

	sprintf(sc->sc_vendor, "Cavium");

	err = bus_setup_intr(self,sc->sc_irq_res,
	    INTR_TYPE_BIO | INTR_MPSAFE, NULL,
	    (driver_intr_t *)ehci_interrupt, sc,
	    &sc->sc_intr_hdl);
	if (err) {
		device_printf(self, "Could not setup error irq, %d\n", err);
		ih_err = NULL;
		goto error;
	}

	err = ehci_init(sc);
	if (!err) {
		err = device_probe_and_attach(sc->sc_bus.bdev);
	}
	if (err) {
		device_printf(self, "USB init failed err=%d\n", err);
		goto error;
	}
	return (0);

error:
	ehci_ebus_detach(self);
	return (ENXIO);
}
Example #27
0
static int
octusb_octeon_attach(device_t dev)
{
    struct octusb_octeon_softc *sc = device_get_softc(dev);
    int err;
    int rid;
    int nports;
    int i;

    /* setup controller interface softc */

    /* initialise some bus fields */
    sc->sc_dci.sc_bus.parent = dev;
    sc->sc_dci.sc_bus.devices = sc->sc_dci.sc_devices;
    sc->sc_dci.sc_bus.devices_max = OCTUSB_MAX_DEVICES;

    /* get all DMA memory */
    if (usb_bus_mem_alloc_all(&sc->sc_dci.sc_bus,
                              USB_GET_DMA_TAG(dev), NULL)) {
        return (ENOMEM);
    }
    nports = cvmx_usb_get_num_ports();
    if (nports > OCTUSB_MAX_PORTS)
        panic("octusb: too many USB ports %d", nports);
    for (i = 0; i < nports; i++) {
        rid = 0;
        sc->sc_dci.sc_irq_res[i] =
            bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
                               OCTEON_IRQ_USB0 + i, OCTEON_IRQ_USB0 + i, 1, RF_ACTIVE);
        if (!(sc->sc_dci.sc_irq_res[i])) {
            goto error;
        }

#if (__FreeBSD_version >= 700031)
        err = bus_setup_intr(dev, sc->sc_dci.sc_irq_res[i], INTR_TYPE_BIO | INTR_MPSAFE,
                             NULL, (driver_intr_t *)octusb_interrupt, sc, &sc->sc_dci.sc_intr_hdl[i]);
#else
        err = bus_setup_intr(dev, sc->sc_dci.sc_irq_res[i], INTR_TYPE_BIO | INTR_MPSAFE,
                             (driver_intr_t *)octusb_interrupt, sc, &sc->sc_dci.sc_intr_hdl[i]);
#endif
        if (err) {
            sc->sc_dci.sc_intr_hdl[i] = NULL;
            goto error;
        }
    }

    sc->sc_dci.sc_bus.bdev = device_add_child(dev, "usbus", -1);
    if (!(sc->sc_dci.sc_bus.bdev)) {
        goto error;
    }
    device_set_ivars(sc->sc_dci.sc_bus.bdev, &sc->sc_dci.sc_bus);


    err = octusb_init(&sc->sc_dci);
    if (!err) {
        err = device_probe_and_attach(sc->sc_dci.sc_bus.bdev);
    }
    if (err) {
        goto error;
    }
    return (0);

error:
    octusb_octeon_detach(dev);
    return (ENXIO);
}
Example #28
0
static int
a10_ehci_attach(device_t self)
{
	ehci_softc_t *sc = device_get_softc(self);
	bus_space_handle_t bsh;
	device_t sc_gpio_dev;
	int err;
	int rid;
	uint32_t reg_value = 0;

	/* initialise some bus fields */
	sc->sc_bus.parent = self;
	sc->sc_bus.devices = sc->sc_devices;
	sc->sc_bus.devices_max = EHCI_MAX_DEVICES;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_bus,
	    USB_GET_DMA_TAG(self), &ehci_iterate_hw_softc)) {
		return (ENOMEM);
	}

	sc->sc_bus.usbrev = USB_REV_2_0;

	rid = 0;
	sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, RF_ACTIVE);
	if (!sc->sc_io_res) {
		device_printf(self, "Could not map memory\n");
		goto error;
	}

	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
	sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
	bsh = rman_get_bushandle(sc->sc_io_res);

	sc->sc_io_size = rman_get_size(sc->sc_io_res);

	if (bus_space_subregion(sc->sc_io_tag, bsh, 0x00,
	    sc->sc_io_size, &sc->sc_io_hdl) != 0)
		panic("%s: unable to subregion USB host registers",
		    device_get_name(self));

	rid = 0;
	sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
	    RF_SHAREABLE | RF_ACTIVE);
	if (sc->sc_irq_res == NULL) {
		device_printf(self, "Could not allocate irq\n");
		goto error;
	}
	sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
	if (!sc->sc_bus.bdev) {
		device_printf(self, "Could not add USB device\n");
		goto error;
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
	device_set_desc(sc->sc_bus.bdev, EHCI_HC_DEVSTR);

	sprintf(sc->sc_vendor, "Allwinner");

        /* Get the GPIO device, we need this to give power to USB */
	sc_gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
	if (sc_gpio_dev == NULL) {
		device_printf(self, "Error: failed to get the GPIO device\n");
		goto error;
	}

	err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
	    NULL, (driver_intr_t *)ehci_interrupt, sc, &sc->sc_intr_hdl);
	if (err) {
		device_printf(self, "Could not setup irq, %d\n", err);
		sc->sc_intr_hdl = NULL;
		goto error;
	}

	sc->sc_flags |= EHCI_SCFLG_DONTRESET;

	/* Enable clock for USB */
	a10_clk_usb_activate();

	/* Give power to USB */
	GPIO_PIN_SETFLAGS(sc_gpio_dev, GPIO_USB2_PWR, GPIO_PIN_OUTPUT);
	GPIO_PIN_SET(sc_gpio_dev, GPIO_USB2_PWR, GPIO_PIN_HIGH);

	/* Give power to USB */
	GPIO_PIN_SETFLAGS(sc_gpio_dev, GPIO_USB1_PWR, GPIO_PIN_OUTPUT);
	GPIO_PIN_SET(sc_gpio_dev, GPIO_USB1_PWR, GPIO_PIN_HIGH);

	/* Enable passby */
	reg_value = A10_READ_4(sc, SW_USB_PMU_IRQ_ENABLE);
	reg_value |= SW_AHB_INCR8; /* AHB INCR8 enable */
	reg_value |= SW_AHB_INCR4; /* AHB burst type INCR4 enable */
	reg_value |= SW_AHB_INCRX_ALIGN; /* AHB INCRX align enable */
	reg_value |= SW_ULPI_BYPASS; /* ULPI bypass enable */
	A10_WRITE_4(sc, SW_USB_PMU_IRQ_ENABLE, reg_value);

	/* Configure port */
	reg_value = A10_READ_4(sc, SW_SDRAM_REG_HPCR_USB2);
	reg_value |= SW_SDRAM_BP_HPCR_ACCESS;
	A10_WRITE_4(sc, SW_SDRAM_REG_HPCR_USB2, reg_value);

	err = ehci_init(sc);
	if (!err) {
		err = device_probe_and_attach(sc->sc_bus.bdev);
	}
	if (err) {
		device_printf(self, "USB init failed err=%d\n", err);
		goto error;
	}
	return (0);

error:
	a10_ehci_detach(self);
	return (ENXIO);
}
Example #29
0
static int
ehci_ps3_attach(device_t dev)
{
	ehci_softc_t *sc = device_get_softc(dev);
	int rid, err;

	sc->sc_bus.parent = dev;
	sc->sc_bus.devices = sc->sc_devices;
	sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
	sc->sc_bus.dma_bits = 32;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_bus,
	    USB_GET_DMA_TAG(dev), &ehci_iterate_hw_softc))
		return (ENOMEM);

	rid = 1;
	sc->sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
	    &rid, RF_ACTIVE);

	if (!sc->sc_io_res) {
		device_printf(dev, "Could not map memory\n");
		goto error;
	}

	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
	sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
	sc->sc_io_size = rman_get_size(sc->sc_io_res);

	rid = 1;
	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
	    RF_SHAREABLE | RF_ACTIVE);

	if (sc->sc_irq_res == NULL) {
		device_printf(dev, "Could not allocate irq\n");
		return (ENXIO);
	}

	sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
	if (!sc->sc_bus.bdev) {
		device_printf(dev, "Could not add USB device\n");
		return (ENXIO);
	}

	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);

	sprintf(sc->sc_vendor, "Sony");

	err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
	    NULL, (driver_intr_t *)ehci_interrupt, sc, &sc->sc_intr_hdl);
	if (err) {
		device_printf(dev, "Could not setup error irq, %d\n", err);
		goto error;
	}

	sc->sc_vendor_post_reset = ehci_ps3_post_reset;
	err = ehci_init(sc);
	if (err) {
		device_printf(dev, "USB init failed err=%d\n", err);
		goto error;
	}

	err = device_probe_and_attach(sc->sc_bus.bdev);
	if (err == 0)
		return (0);

error:
	return (ENXIO);
}
Example #30
0
static int
dotg_obio_attach(device_t dev)
{
	struct dotg_obio_softc *sc = device_get_softc(dev);
	int err;

	/* setup controller interface softc */

	/* initialise some bus fields */
	sc->sc_dci.sc_dev = dev;
	sc->sc_dci.sc_bus.parent = dev;
	sc->sc_dci.sc_bus.devices = sc->sc_dci.sc_devices;
	sc->sc_dci.sc_bus.devices_max = DOTG_MAX_DEVICES;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_dci.sc_bus,
	    USB_GET_DMA_TAG(dev), NULL)) {
		printf("No mem\n");
		return (ENOMEM);
	}
	sc->sc_dci.sc_mem_rid = 0;
	sc->sc_dci.sc_mem_res =
	    bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_dci.sc_irq_rid,
			       RF_ACTIVE);
	if (!(sc->sc_dci.sc_mem_res)) {
		printf("Can`t alloc MEM\n");
		goto error;
	}
	sc->sc_dci.sc_bst = rman_get_bustag(sc->sc_dci.sc_mem_res);
	sc->sc_dci.sc_bsh = rman_get_bushandle(sc->sc_dci.sc_mem_res);

	sc->sc_dci.sc_irq_rid = 0;
	sc->sc_dci.sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, 
	    &sc->sc_dci.sc_irq_rid, RF_SHAREABLE| RF_ACTIVE);
	if (!(sc->sc_dci.sc_irq_res)) {
		printf("Can`t alloc IRQ\n");
		goto error;
	}

	sc->sc_dci.sc_bus.bdev = device_add_child(dev, "usbus", -1);
	if (!(sc->sc_dci.sc_bus.bdev)) {
		printf("Can`t add usbus\n");
		goto error;
	}
	device_set_ivars(sc->sc_dci.sc_bus.bdev, &sc->sc_dci.sc_bus);

#if (__FreeBSD_version >= 700031)
	err = bus_setup_intr(dev, sc->sc_dci.sc_irq_res,
	    INTR_TYPE_BIO | INTR_MPSAFE, NULL, (driver_intr_t *)dotg_interrupt,
	    sc, &sc->sc_dci.sc_intr_hdl);
#else
	err = bus_setup_intr(dev, sc->sc_dci.sc_irq_res,
	    INTR_TYPE_BIO | INTR_MPSAFE, (driver_intr_t *)dotg_interrupt,
	    sc, &sc->sc_dci.sc_intr_hdl);
#endif
	if (err) {
		sc->sc_dci.sc_intr_hdl = NULL;
		printf("Can`t set IRQ handle\n");
		goto error;
	}

	/* Run clock for OTG core */
	rt305x_sysctl_set(SYSCTL_CLKCFG1, rt305x_sysctl_get(SYSCTL_CLKCFG1) | 
	    SYSCTL_CLKCFG1_OTG_CLK_EN);
	rt305x_sysctl_set(SYSCTL_RSTCTRL, SYSCTL_RSTCTRL_OTG);
	DELAY(100);

	err = dotg_init(&sc->sc_dci);
	if (err) printf("dotg_init fail\n");
	if (!err) {
		err = device_probe_and_attach(sc->sc_dci.sc_bus.bdev);
		if (err) printf("device_probe_and_attach fail\n");
	}
	if (err) {
		goto error;
	}
	return (0);

error:
	dotg_obio_detach(dev);
	return (ENXIO);
}