Exemplo n.º 1
0
/*------------------------------------------------------------------------*
 *	usb_attach_sub
 *
 * This function creates a thread which runs the USB attach code.
 *------------------------------------------------------------------------*/
static void
usb_attach_sub(device_t dev, struct usb_bus *bus)
{
	const char *pname = device_get_nameunit(dev);

	mtx_lock(&Giant);
	if (usb_devclass_ptr == NULL)
		usb_devclass_ptr = devclass_find("usbus");
	mtx_unlock(&Giant);

#if USB_HAVE_PF
	usbpf_attach(bus);
#endif
	/* Initialise USB process messages */
	bus->explore_msg[0].hdr.pm_callback = &usb_bus_explore;
	bus->explore_msg[0].bus = bus;
	bus->explore_msg[1].hdr.pm_callback = &usb_bus_explore;
	bus->explore_msg[1].bus = bus;

	bus->detach_msg[0].hdr.pm_callback = &usb_bus_detach;
	bus->detach_msg[0].bus = bus;
	bus->detach_msg[1].hdr.pm_callback = &usb_bus_detach;
	bus->detach_msg[1].bus = bus;

	bus->attach_msg[0].hdr.pm_callback = &usb_bus_attach;
	bus->attach_msg[0].bus = bus;
	bus->attach_msg[1].hdr.pm_callback = &usb_bus_attach;
	bus->attach_msg[1].bus = bus;

	/* Create USB explore and callback processes */

	if (usb_proc_create(&bus->giant_callback_proc,
	    &bus->bus_mtx, pname, USB_PRI_MED)) {
		device_printf(dev, "WARNING: Creation of USB Giant "
		    "callback process failed.\n");
	} else if (usb_proc_create(&bus->non_giant_callback_proc,
	    &bus->bus_mtx, pname, USB_PRI_HIGH)) {
		device_printf(dev, "WARNING: Creation of USB non-Giant "
		    "callback process failed.\n");
	} else if (usb_proc_create(&bus->explore_proc,
	    &bus->bus_mtx, pname, USB_PRI_MED)) {
		device_printf(dev, "WARNING: Creation of USB explore "
		    "process failed.\n");
	} else if (usb_proc_create(&bus->control_xfer_proc,
	    &bus->bus_mtx, pname, USB_PRI_MED)) {
		device_printf(dev, "WARNING: Creation of USB control transfer "
		    "process failed.\n");
	} else {
		/* Get final attach going */
		USB_BUS_LOCK(bus);
		if (usb_proc_msignal(&bus->explore_proc,
		    &bus->attach_msg[0], &bus->attach_msg[1])) {
			/* ignore */
		}
		USB_BUS_UNLOCK(bus);

		/* Do initial explore */
		usb_needs_explore(bus, 1);
	}
}
int
uether_ifattach(struct usb_ether *ue)
{
	int error;

	/* check some critical parameters */
	if ((ue->ue_dev == NULL) ||
	    (ue->ue_udev == NULL) ||
	    (ue->ue_mtx == NULL) ||
	    (ue->ue_methods == NULL))
		return (EINVAL);

	error = usb_proc_create(&ue->ue_tq, ue->ue_mtx, 
	    device_get_nameunit(ue->ue_dev), USB_PRI_MED);
	if (error) {
		device_printf(ue->ue_dev, "could not setup taskqueue\n");
		goto error;
	}

	/* fork rest of the attach code */
	UE_LOCK(ue);
	ue_queue_command(ue, ue_attach_post_task,
	    &ue->ue_sync_task[0].hdr,
	    &ue->ue_sync_task[1].hdr);
	UE_UNLOCK(ue);

error:
	return (error);
}
Exemplo n.º 3
0
/*
 * "N" sub_units are setup at a time. All sub-units will
 * be given sequential unit numbers. The number of
 * sub-units can be used to differentiate among
 * different types of devices.
 *
 * The mutex pointed to by "mtx" is applied before all
 * callbacks are called back. Also "mtx" must be applied
 * before calling into the ucom-layer!
 */
int
ucom_attach(struct ucom_super_softc *ssc, struct ucom_softc *sc,
    uint32_t sub_units, void *parent,
    const struct ucom_callback *callback, struct mtx *mtx)
{
	uint32_t n;
	uint32_t root_unit;
	int error = 0;

	if ((sc == NULL) ||
	    (sub_units == 0) ||
	    (sub_units > UCOM_SUB_UNIT_MAX) ||
	    (callback == NULL)) {
		return (EINVAL);
	}

	/* XXX unit management does not really belong here */
	if (ucom_units_alloc(sub_units, &root_unit)) {
		return (ENOMEM);
	}

	error = usb_proc_create(&ssc->sc_tq, mtx, "ucom", USB_PRI_MED);
	if (error) {
		ucom_units_free(root_unit, sub_units);
		return (error);
	}

	for (n = 0; n != sub_units; n++, sc++) {
		sc->sc_unit = root_unit + n;
		sc->sc_local_unit = n;
		sc->sc_super = ssc;
		sc->sc_mtx = mtx;
		sc->sc_parent = parent;
		sc->sc_callback = callback;

		error = ucom_attach_tty(sc, sub_units);
		if (error) {
			ucom_detach(ssc, sc - n, n);
			ucom_units_free(root_unit + n, sub_units - n);
			return (error);
		}
		sc->sc_flag |= UCOM_FLAG_ATTACHED;
	}
	return (0);
}
Exemplo n.º 4
0
/*
 * Setup a group of one or more serial ports.
 *
 * The mutex pointed to by "mtx" is applied before all
 * callbacks are called back. Also "mtx" must be applied
 * before calling into the ucom-layer!
 */
int
ucom_attach(struct ucom_super_softc *ssc, struct ucom_softc *sc,
    int subunits, void *parent,
    const struct ucom_callback *callback, struct mtx *mtx)
{
	int subunit;
	int error = 0;

	if ((sc == NULL) ||
	    (subunits <= 0) ||
	    (callback == NULL) ||
	    (mtx == NULL)) {
		return (EINVAL);
	}

	/* allocate a uniq unit number */
	ssc->sc_unit = ucom_unit_alloc();
	if (ssc->sc_unit == -1)
		return (ENOMEM);

	/* generate TTY name string */
	snprintf(ssc->sc_ttyname, sizeof(ssc->sc_ttyname),
	    UCOM_TTY_PREFIX "%d", ssc->sc_unit);

	/* create USB request handling process */
	error = usb_proc_create(&ssc->sc_tq, mtx, "ucom", USB_PRI_MED);
	if (error) {
		ucom_unit_free(ssc->sc_unit);
		return (error);
	}
	ssc->sc_subunits = subunits;
	ssc->sc_flag = UCOM_FLAG_ATTACHED |
	    UCOM_FLAG_FREE_UNIT;

	if (callback->ucom_free == NULL)
		ssc->sc_flag |= UCOM_FLAG_WAIT_REFS;

	/* increment reference count */
	ucom_ref(ssc);

	for (subunit = 0; subunit < ssc->sc_subunits; subunit++) {
		sc[subunit].sc_subunit = subunit;
		sc[subunit].sc_super = ssc;
		sc[subunit].sc_mtx = mtx;
		sc[subunit].sc_parent = parent;
		sc[subunit].sc_callback = callback;

		error = ucom_attach_tty(ssc, &sc[subunit]);
		if (error) {
			ucom_detach(ssc, &sc[0]);
			return (error);
		}
		/* increment reference count */
		ucom_ref(ssc);

		/* set subunit attached */
		sc[subunit].sc_flag |= UCOM_FLAG_ATTACHED;
	}

	DPRINTF("tp = %p, unit = %d, subunits = %d\n",
		sc->sc_tty, ssc->sc_unit, ssc->sc_subunits);

	return (0);
}
Exemplo n.º 5
0
/*------------------------------------------------------------------------*
 *	usb_attach_sub
 *
 * This function creates a thread which runs the USB attach code.
 *------------------------------------------------------------------------*/
static void
usb_attach_sub(device_t dev, struct usb_bus *bus)
{
	mtx_lock(&Giant);
	if (usb_devclass_ptr == NULL)
		usb_devclass_ptr = devclass_find("usbus");
	mtx_unlock(&Giant);

#if USB_HAVE_PF
	usbpf_attach(bus);
#endif
	/* Initialise USB process messages */
	bus->explore_msg[0].hdr.pm_callback = &usb_bus_explore;
	bus->explore_msg[0].bus = bus;
	bus->explore_msg[1].hdr.pm_callback = &usb_bus_explore;
	bus->explore_msg[1].bus = bus;

	bus->detach_msg[0].hdr.pm_callback = &usb_bus_detach;
	bus->detach_msg[0].bus = bus;
	bus->detach_msg[1].hdr.pm_callback = &usb_bus_detach;
	bus->detach_msg[1].bus = bus;

	bus->attach_msg[0].hdr.pm_callback = &usb_bus_attach;
	bus->attach_msg[0].bus = bus;
	bus->attach_msg[1].hdr.pm_callback = &usb_bus_attach;
	bus->attach_msg[1].bus = bus;

	bus->suspend_msg[0].hdr.pm_callback = &usb_bus_suspend;
	bus->suspend_msg[0].bus = bus;
	bus->suspend_msg[1].hdr.pm_callback = &usb_bus_suspend;
	bus->suspend_msg[1].bus = bus;

	bus->resume_msg[0].hdr.pm_callback = &usb_bus_resume;
	bus->resume_msg[0].bus = bus;
	bus->resume_msg[1].hdr.pm_callback = &usb_bus_resume;
	bus->resume_msg[1].bus = bus;

	bus->reset_msg[0].hdr.pm_callback = &usb_bus_reset;
	bus->reset_msg[0].bus = bus;
	bus->reset_msg[1].hdr.pm_callback = &usb_bus_reset;
	bus->reset_msg[1].bus = bus;

	bus->shutdown_msg[0].hdr.pm_callback = &usb_bus_shutdown;
	bus->shutdown_msg[0].bus = bus;
	bus->shutdown_msg[1].hdr.pm_callback = &usb_bus_shutdown;
	bus->shutdown_msg[1].bus = bus;

#if USB_HAVE_PER_BUS_PROCESS
	/* Create USB explore and callback processes */

	if (usb_proc_create(USB_BUS_GIANT_PROC(bus),
	    &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_MED)) {
		device_printf(dev, "WARNING: Creation of USB Giant "
		    "callback process failed.\n");
	} else if (usb_proc_create(USB_BUS_NON_GIANT_PROC(bus),
	    &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_HIGH)) {
		device_printf(dev, "WARNING: Creation of USB non-Giant "
		    "callback process failed.\n");
	} else if (usb_proc_create(USB_BUS_EXPLORE_PROC(bus),
	    &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_MED)) {
		device_printf(dev, "WARNING: Creation of USB explore "
		    "process failed.\n");
	} else if (usb_proc_create(USB_BUS_CONTROL_XFER_PROC(bus),
	    &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_MED)) {
		device_printf(dev, "WARNING: Creation of USB control transfer "
		    "process failed.\n");
	} else
#endif
	{
		/* Get final attach going */
		USB_BUS_LOCK(bus);
		usb_proc_msignal(USB_BUS_EXPLORE_PROC(bus),
		    &bus->attach_msg[0], &bus->attach_msg[1]);
		USB_BUS_UNLOCK(bus);

		/* Do initial explore */
		usb_needs_explore(bus, 1);
	}
}