Ejemplo n.º 1
0
static void
usie_autoinst(void *arg, struct usb_device *udev,
    struct usb_attach_arg *uaa)
{
	struct usb_interface *iface;
	struct usb_interface_descriptor *id;
	struct usb_device_request req;
	int err;

	if (uaa->dev_state != UAA_DEV_READY)
		return;

	iface = usbd_get_iface(udev, 0);
	if (iface == NULL)
		return;

	id = iface->idesc;
	if (id == NULL || id->bInterfaceClass != UICLASS_MASS)
		return;

	if (usbd_lookup_id_by_uaa(usie_devs, sizeof(usie_devs), uaa) != 0)
		return;			/* no device match */

	if (bootverbose) {
		DPRINTF("Ejecting %s %s\n",
		    usb_get_manufacturer(udev),
		    usb_get_product(udev));
	}
	req.bmRequestType = UT_VENDOR;
	req.bRequest = UR_SET_INTERFACE;
	USETW(req.wValue, UF_DEVICE_REMOTE_WAKEUP);
	USETW(req.wIndex, UHF_PORT_CONNECTION);
	USETW(req.wLength, 0);

	/* at this moment there is no mutex */
	err = usbd_do_request_flags(udev, NULL, &req,
	    NULL, 0, NULL, 250 /* ms */ );

	/* success, mark the udev as disappearing */
	if (err == 0)
		uaa->dev_state = UAA_DEV_EJECTING;
}
Ejemplo n.º 2
0
/*------------------------------------------------------------------------*
 *	usb_gen_fill_deviceinfo
 *
 * This function dumps information about an USB device to the
 * structure pointed to by the "di" argument.
 *
 * Returns:
 *    0: Success
 * Else: Failure
 *------------------------------------------------------------------------*/
static int
usb_gen_fill_deviceinfo(struct usb_fifo *f, struct usb_device_info *di)
{
	struct usb_device *udev;
	struct usb_device *hub;

	udev = f->udev;

	bzero(di, sizeof(di[0]));

	di->udi_bus = device_get_unit(udev->bus->bdev);
	di->udi_addr = udev->address;
	di->udi_index = udev->device_index;
	strlcpy(di->udi_serial, usb_get_serial(udev), sizeof(di->udi_serial));
	strlcpy(di->udi_vendor, usb_get_manufacturer(udev), sizeof(di->udi_vendor));
	strlcpy(di->udi_product, usb_get_product(udev), sizeof(di->udi_product));
	usb_printbcd(di->udi_release, sizeof(di->udi_release),
	    UGETW(udev->ddesc.bcdDevice));
	di->udi_vendorNo = UGETW(udev->ddesc.idVendor);
	di->udi_productNo = UGETW(udev->ddesc.idProduct);
	di->udi_releaseNo = UGETW(udev->ddesc.bcdDevice);
	di->udi_class = udev->ddesc.bDeviceClass;
	di->udi_subclass = udev->ddesc.bDeviceSubClass;
	di->udi_protocol = udev->ddesc.bDeviceProtocol;
	di->udi_config_no = udev->curr_config_no;
	di->udi_config_index = udev->curr_config_index;
	di->udi_power = udev->flags.self_powered ? 0 : udev->power;
	di->udi_speed = udev->speed;
	di->udi_mode = udev->flags.usb_mode;
	di->udi_power_mode = udev->power_mode;
	di->udi_suspended = udev->flags.peer_suspended;

	hub = udev->parent_hub;
	if (hub) {
		di->udi_hubaddr = hub->address;
		di->udi_hubindex = hub->device_index;
		di->udi_hubport = udev->port_no;
	}
	return (0);
}
Ejemplo n.º 3
0
static int
uhso_attach(device_t self)
{
	struct uhso_softc *sc = device_get_softc(self);
	struct usb_attach_arg *uaa = device_get_ivars(self);
	struct usb_interface_descriptor *id;
	struct sysctl_ctx_list *sctx;
	struct sysctl_oid *soid;
	struct sysctl_oid *tree = NULL, *tty_node;
	struct ucom_softc *ucom;
	struct uhso_tty *ht;
	int i, error, port;
	void *probe_f;
	usb_error_t uerr;
	char *desc;

	sc->sc_dev = self;
	sc->sc_udev = uaa->device;
	mtx_init(&sc->sc_mtx, "uhso", NULL, MTX_DEF);
	ucom_ref(&sc->sc_super_ucom);

	sc->sc_ucom = NULL;
	sc->sc_ttys = 0;
	sc->sc_radio = 1;

	id = usbd_get_interface_descriptor(uaa->iface);
	sc->sc_ctrl_iface_no = id->bInterfaceNumber;

	sc->sc_iface_no = uaa->info.bIfaceNum;
	sc->sc_iface_index = uaa->info.bIfaceIndex;

	/* Setup control pipe */
	uerr = usbd_transfer_setup(uaa->device,
	    &sc->sc_iface_index, sc->sc_ctrl_xfer,
	    uhso_ctrl_config, UHSO_CTRL_MAX, sc, &sc->sc_mtx);
	if (uerr) {
		device_printf(self, "Failed to setup control pipe: %s\n",
		    usbd_errstr(uerr));
		goto out;
	}

	if (USB_GET_DRIVER_INFO(uaa) == UHSO_STATIC_IFACE)
		probe_f = uhso_probe_iface_static;
	else if (USB_GET_DRIVER_INFO(uaa) == UHSO_AUTO_IFACE)
		probe_f = uhso_probe_iface_auto;
	else
		goto out;

	error = uhso_probe_iface(sc, uaa->info.bIfaceNum, probe_f);
	if (error != 0)
		goto out;

	sctx = device_get_sysctl_ctx(sc->sc_dev);
	soid = device_get_sysctl_tree(sc->sc_dev);

	SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "type",
	    CTLFLAG_RD, uhso_port[UHSO_IFACE_PORT(sc->sc_type)], 0,
	    "Port available at this interface");
	SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "radio",
	    CTLTYPE_INT | CTLFLAG_RW, sc, 0, uhso_radio_sysctl, "I", "Enable radio");

	/*
	 * The default interface description on most Option devices isn't
	 * very helpful. So we skip device_set_usb_desc and set the
	 * device description manually.
	 */
	device_set_desc_copy(self, uhso_port_type[UHSO_IFACE_PORT_TYPE(sc->sc_type)]); 
	/* Announce device */
	device_printf(self, "<%s port> at <%s %s> on %s\n",
	    uhso_port_type[UHSO_IFACE_PORT_TYPE(sc->sc_type)],
	    usb_get_manufacturer(uaa->device),
	    usb_get_product(uaa->device),
	    device_get_nameunit(device_get_parent(self)));

	if (sc->sc_ttys > 0) {
		SYSCTL_ADD_INT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "ports",
		    CTLFLAG_RD, &sc->sc_ttys, 0, "Number of attached serial ports");

		tree = SYSCTL_ADD_NODE(sctx, SYSCTL_CHILDREN(soid), OID_AUTO,
		    "port", CTLFLAG_RD, NULL, "Serial ports");
	}

	/*
	 * Loop through the number of found TTYs and create sysctl
	 * nodes for them.
	 */
	for (i = 0; i < sc->sc_ttys; i++) {
		ht = &sc->sc_tty[i];
		ucom = &sc->sc_ucom[i];

		if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX)
			port = uhso_mux_port_map[ht->ht_muxport];
		else
			port = UHSO_IFACE_PORT_TYPE(sc->sc_type);

		desc = uhso_port_type_sysctl[port];

		tty_node = SYSCTL_ADD_NODE(sctx, SYSCTL_CHILDREN(tree), OID_AUTO,
		    desc, CTLFLAG_RD, NULL, "");

		ht->ht_name[0] = 0;
		if (sc->sc_ttys == 1)
			snprintf(ht->ht_name, 32, "cuaU%d", ucom->sc_super->sc_unit);
		else {
			snprintf(ht->ht_name, 32, "cuaU%d.%d",
			    ucom->sc_super->sc_unit, ucom->sc_subunit);
		}

		desc = uhso_port_type[port];
		SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(tty_node), OID_AUTO,
		    "tty", CTLFLAG_RD, ht->ht_name, 0, "");
		SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(tty_node), OID_AUTO,
		    "desc", CTLFLAG_RD, desc, 0, "");

		if (bootverbose)
			device_printf(sc->sc_dev,
			    "\"%s\" port at %s\n", desc, ht->ht_name);
	}

	return (0);
out:
	uhso_detach(sc->sc_dev);
	return (ENXIO);
}