예제 #1
0
static int
octusb_octeon_attach(device_t dev)
{
	struct octusb_octeon_softc *sc = device_get_softc(dev);
	int err;
	int rid;

	/* 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);
	}
	rid = 0;
	sc->sc_dci.sc_irq_res =
	    bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
			       CVMX_IRQ_USB, CVMX_IRQ_USB, 1, 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);

#if (__FreeBSD_version >= 700031)
	err = bus_setup_intr(dev, sc->sc_dci.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
	    NULL, (driver_intr_t *)octusb_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 *)octusb_interrupt, sc, &sc->sc_dci.sc_intr_hdl);
#endif
	if (err) {
		sc->sc_dci.sc_intr_hdl = NULL;
		goto error;
	}
	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);
}
예제 #2
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);
}