Exemple #1
0
void
ugen_attach(struct device *parent, struct device *self, void *aux)
{
	struct ugen_softc *sc = (struct ugen_softc *)self;
	struct usb_attach_arg *uaa = aux;
	struct usbd_device *udev;
	usbd_status err;
	int conf;

	sc->sc_udev = udev = uaa->device;

	if (usbd_get_devcnt(udev) > 0)
		sc->sc_secondary = 1;

	if (!sc->sc_secondary) {
		/* First set configuration index 0, the default one for ugen. */
		err = usbd_set_config_index(udev, 0, 0);
		if (err) {
			printf("%s: setting configuration index 0 failed\n",
			       sc->sc_dev.dv_xname);
			usbd_deactivate(sc->sc_udev);
			return;
		}
	}
	conf = usbd_get_config_descriptor(udev)->bConfigurationValue;

	/* Set up all the local state for this configuration. */
	err = ugen_set_config(sc, conf);
	if (err) {
		printf("%s: setting configuration %d failed\n",
		       sc->sc_dev.dv_xname, conf);
		usbd_deactivate(sc->sc_udev);
		return;
	}
}
static int
ugen_set_config(struct usb_fifo *f, uint8_t index)
{
	DPRINTFN(2, "index %u\n", index);

	if (f->udev->flags.usb_mode != USB_MODE_HOST) {
		/* not possible in device side mode */
		return (ENOTTY);
	}
	if (f->udev->curr_config_index == index) {
		/* no change needed */
		return (0);
	}
	/* make sure all FIFO's are gone */
	/* else there can be a deadlock */
	if (ugen_fs_uninit(f)) {
		/* ignore any errors */
		DPRINTFN(6, "no FIFOs\n");
	}
	/* change setting - will free generic FIFOs, if any */
	if (usbd_set_config_index(f->udev, index)) {
		return (EIO);
	}
	/* probe and attach */
	if (usb_probe_and_attach(f->udev, USB_IFACE_INDEX_ANY)) {
		return (EIO);
	}
	return (0);
}
Exemple #3
0
/*------------------------------------------------------------------------*
 *	usb_bus_resume
 *
 * This function is used to resume the USB controller.
 *------------------------------------------------------------------------*/
static void
usb_bus_resume(struct usb_proc_msg *pm)
{
	struct usb_bus *bus;
	struct usb_device *udev;
	usb_error_t err;
	uint8_t do_unlock;

	DPRINTF("\n");

	bus = ((struct usb_bus_msg *)pm)->bus;
	udev = bus->devices[USB_ROOT_HUB_ADDR];

	if (udev == NULL || bus->bdev == NULL)
		return;

	USB_BUS_UNLOCK(bus);

	do_unlock = usbd_enum_lock(udev);
#if 0
	DEVMETHOD(usb_take_controller, NULL);	/* dummy */
#endif
	USB_TAKE_CONTROLLER(device_get_parent(bus->bdev));

	USB_BUS_LOCK(bus);
 	bus->hw_power_state =
	  USB_HW_POWER_CONTROL |
	  USB_HW_POWER_BULK |
	  USB_HW_POWER_INTERRUPT |
	  USB_HW_POWER_ISOC |
	  USB_HW_POWER_NON_ROOT_HUB;
	bus->no_explore = 0;
	USB_BUS_UNLOCK(bus);

	if (bus->methods->set_hw_power_sleep != NULL)
		(bus->methods->set_hw_power_sleep) (bus, USB_HW_POWER_RESUME);

	if (bus->methods->set_hw_power != NULL)
		(bus->methods->set_hw_power) (bus);

	/* restore USB configuration to index 0 */
	err = usbd_set_config_index(udev, 0);
	if (err)
		device_printf(bus->bdev, "Could not configure root HUB\n");

	/* probe and attach */
	err = usb_probe_and_attach(udev, USB_IFACE_INDEX_ANY);
	if (err) {
		device_printf(bus->bdev, "Could not probe and "
		    "attach root HUB\n");
	}

	if (do_unlock)
		usbd_enum_unlock(udev);

	USB_BUS_LOCK(bus);
}
Exemple #4
0
usbd_status
usbd_set_config_no(usbd_device_handle dev, int no, int msg)
{
	int index;
	usb_config_descriptor_t cd;
	usbd_status err;

	if (no == USB_UNCONFIG_NO)
		return (usbd_set_config_index(dev, USB_UNCONFIG_INDEX, msg));

	DPRINTFN(5,("usbd_set_config_no: %d\n", no));
	/* Figure out what config index to use. */
	for (index = 0; index < dev->ddesc.bNumConfigurations; index++) {
		err = usbd_get_config_desc(dev, index, &cd);
		if (err)
			return (err);
		if (cd.bConfigurationValue == no)
			return (usbd_set_config_index(dev, index, msg));
	}
	return (USBD_INVAL);
}
Exemple #5
0
usbd_status
usbd_set_config_no(struct usbd_device *dev, int no, int msg)
{
	USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
	usb_config_descriptor_t cd;
	usbd_status err;
	int index;

	if (no == USB_UNCONFIG_NO)
		return usbd_set_config_index(dev, USB_UNCONFIG_INDEX, msg);

	DPRINTFN(5, "%d", no, 0, 0, 0);
	/* Figure out what config index to use. */
	for (index = 0; index < dev->ud_ddesc.bNumConfigurations; index++) {
		err = usbd_get_config_desc(dev, index, &cd);
		if (err)
			return err;
		if (cd.bConfigurationValue == no)
			return usbd_set_config_index(dev, index, msg);
	}
	return USBD_INVAL;
}
Exemple #6
0
/*------------------------------------------------------------------------*
 *	usb_bus_suspend
 *
 * This function is used to suspend the USB controller.
 *------------------------------------------------------------------------*/
static void
usb_bus_suspend(struct usb_proc_msg *pm)
{
	struct usb_bus *bus;
	struct usb_device *udev;
	usb_error_t err;
	uint8_t do_unlock;

	DPRINTF("\n");

	bus = ((struct usb_bus_msg *)pm)->bus;
	udev = bus->devices[USB_ROOT_HUB_ADDR];

	if (udev == NULL || bus->bdev == NULL)
		return;

	USB_BUS_UNLOCK(bus);

	/*
	 * We use the shutdown event here because the suspend and
	 * resume events are reserved for the USB port suspend and
	 * resume. The USB system suspend is implemented like full
	 * shutdown and all connected USB devices will be disconnected
	 * subsequently. At resume all USB devices will be
	 * re-connected again.
	 */

	bus_generic_shutdown(bus->bdev);

	do_unlock = usbd_enum_lock(udev);

	err = usbd_set_config_index(udev, USB_UNCONFIG_INDEX);
	if (err)
		device_printf(bus->bdev, "Could not unconfigure root HUB\n");

	USB_BUS_LOCK(bus);
	bus->hw_power_state = 0;
	bus->no_explore = 1;
	USB_BUS_UNLOCK(bus);

	if (bus->methods->set_hw_power != NULL)
		(bus->methods->set_hw_power) (bus);

	if (bus->methods->set_hw_power_sleep != NULL)
		(bus->methods->set_hw_power_sleep) (bus, USB_HW_POWER_SUSPEND);

	if (do_unlock)
		usbd_enum_unlock(udev);

	USB_BUS_LOCK(bus);
}
Exemple #7
0
static int
u3g_huawei_reinit(usbd_device_handle dev)
{
	/*
	 * The Huawei device presents itself as a umass device with Windows
	 * drivers on it. After installation of the driver, it reinits into a
	 * 3G serial device.
	 */
	usb_device_request_t req;
	usb_config_descriptor_t *cdesc;

	/* Get the config descriptor */
	cdesc = usbd_get_config_descriptor(dev);
	if (cdesc == NULL) {
		usb_device_descriptor_t dd;

		if (usbd_get_device_desc(dev, &dd) != 0)
			return (UMATCH_NONE);

		if (dd.bNumConfigurations != 1)
			return (UMATCH_NONE);

		if (usbd_set_config_index(dev, 0, 1) != 0)
			return (UMATCH_NONE);

		cdesc = usbd_get_config_descriptor(dev);

		if (cdesc == NULL)
			return (UMATCH_NONE);
	}

	/*
	 * One iface means umass mode, more than 1 (4 usually) means 3G mode.
	 *
	 * XXX: We should check the first interface's device class just to be
	 * sure. If it's a mass storage device, then we can be fairly certain
	 * it needs a mode-switch.
	 */
	if (cdesc->bNumInterface > 1)
		return (UMATCH_NONE);

	req.bmRequestType = UT_WRITE_DEVICE;
	req.bRequest = UR_SET_FEATURE;
	USETW(req.wValue, UF_DEVICE_REMOTE_WAKEUP);
	USETW(req.wIndex, UHF_PORT_SUSPEND);
	USETW(req.wLength, 0);

	(void) usbd_do_request(dev, &req, 0);

	return (UMATCH_HIGHEST); /* Prevent umass from attaching */
}
Exemple #8
0
int
uftdi_match(struct device *parent, void *match, void *aux)
{
	struct usb_attach_arg *uaa = aux;
	int err;
	u_int8_t nifaces;

	if (usb_lookup(uftdi_devs, uaa->vendor, uaa->product) == NULL)
		return (UMATCH_NONE);

	/* Get the number of interfaces. */
	if (uaa->iface != NULL) {
		nifaces = uaa->nifaces;
	} else {
		err = usbd_set_config_index(uaa->device, UFTDI_CONFIG_INDEX, 1);
		if (err)
			return (UMATCH_NONE);
		err = usbd_interface_count(uaa->device, &nifaces);
		if (err)
			return (UMATCH_NONE);
		usbd_set_config_index(uaa->device, USB_UNCONFIG_INDEX, 1);
	}

	/* JTAG on USB interface 0 */
	if (uaa->vendor == USB_VENDOR_FTDI &&
	    uaa->product == USB_PRODUCT_FTDI_OPENRD &&
	    uaa->ifaceno == 0)
		return (UMATCH_NONE);

	if (nifaces <= 1)
		return (UMATCH_VENDOR_PRODUCT);

	/* Dual UART chip */
	if (uaa->iface != NULL)
		return (UMATCH_VENDOR_IFACESUBCLASS);
	else
		return (UMATCH_NONE);
}
/*------------------------------------------------------------------------*
 *	usb_handle_set_config
 *
 * Returns:
 *    0: Success
 * Else: Failure
 *------------------------------------------------------------------------*/
static usb_error_t
usb_handle_set_config(struct usb_xfer *xfer, uint8_t conf_no)
{
	struct usb_device *udev = xfer->xroot->udev;
	usb_error_t err = 0;
	uint8_t do_unlock;

	/*
	 * We need to protect against other threads doing probe and
	 * attach:
	 */
	USB_XFER_UNLOCK(xfer);

	/* Prevent re-enumeration */
	do_unlock = usbd_enum_lock(udev);

	if (conf_no == USB_UNCONFIG_NO) {
		conf_no = USB_UNCONFIG_INDEX;
	} else {
		/*
		 * The relationship between config number and config index
		 * is very simple in our case:
		 */
		conf_no--;
	}

	if (usbd_set_config_index(udev, conf_no)) {
		DPRINTF("set config %d failed\n", conf_no);
		err = USB_ERR_STALLED;
		goto done;
	}
	if (usb_probe_and_attach(udev, USB_IFACE_INDEX_ANY)) {
		DPRINTF("probe and attach failed\n");
		err = USB_ERR_STALLED;
		goto done;
	}
done:
	if (do_unlock)
		usbd_enum_unlock(udev);
	USB_XFER_LOCK(xfer);
	return (err);
}
Exemple #10
0
/*------------------------------------------------------------------------*
 *	usb_bus_shutdown
 *
 * This function is used to shutdown the USB controller.
 *------------------------------------------------------------------------*/
static void
usb_bus_shutdown(struct usb_proc_msg *pm)
{
	struct usb_bus *bus;
	struct usb_device *udev;
	usb_error_t err;
	uint8_t do_unlock;

	bus = ((struct usb_bus_msg *)pm)->bus;
	udev = bus->devices[USB_ROOT_HUB_ADDR];

	if (udev == NULL || bus->bdev == NULL)
		return;

	USB_BUS_UNLOCK(bus);

	bus_generic_shutdown(bus->bdev);

	do_unlock = usbd_enum_lock(udev);

	err = usbd_set_config_index(udev, USB_UNCONFIG_INDEX);
	if (err)
		device_printf(bus->bdev, "Could not unconfigure root HUB\n");

	USB_BUS_LOCK(bus);
	bus->hw_power_state = 0;
	bus->no_explore = 1;
	USB_BUS_UNLOCK(bus);

	if (bus->methods->set_hw_power != NULL)
		(bus->methods->set_hw_power) (bus);

	if (bus->methods->set_hw_power_sleep != NULL)
		(bus->methods->set_hw_power_sleep) (bus, USB_HW_POWER_SHUTDOWN);

	if (do_unlock)
		usbd_enum_unlock(udev);

	USB_BUS_LOCK(bus);
}
Exemple #11
0
static void
u3ginit_attach(device_t parent, device_t self, void *aux)
{
	struct usb_attach_arg *uaa = aux;

	aprint_naive("\n");
	aprint_normal(": Switching to 3G mode\n");

	if (uaa->vendor == USB_VENDOR_NOVATEL2) {
		switch (uaa->product) {
	    	case USB_PRODUCT_NOVATEL2_MC950D_DRIVER:
	    	case USB_PRODUCT_NOVATEL2_U760_DRIVER:
			/* About to disappear... */
			return;
			break;
		default:
			break;
		}
	}

	/* Move the device into the configured state. */
	(void) usbd_set_config_index(uaa->device, 0, 1);
}
Exemple #12
0
static int
uhub_attach(device_t self)
{
	struct uhub_softc *sc = device_get_softc(self);
	struct usb_attach_arg *uaa = device_get_ivars(self);
	usbd_device_handle dev = uaa->device;
	usbd_status err;
	struct usbd_hub *hub = NULL;
	usb_device_request_t req;
	usb_hub_descriptor_t hubdesc;
	int p, port, nports, nremov, pwrdly;
	usbd_interface_handle iface;
	usb_endpoint_descriptor_t *ed;
	struct usbd_tt *tts = NULL;

	DPRINTFN(1,("uhub_attach\n"));
	sc->sc_hub = dev;

	if (dev->depth > 0 && UHUB_IS_HIGH_SPEED(sc)) {
		device_printf(self,
		    "%s transaction translator%s\n",
		    UHUB_IS_SINGLE_TT(sc) ? "single" : "multiple",
		    UHUB_IS_SINGLE_TT(sc) ? "" : "s");
	}
	err = usbd_set_config_index(dev, 0, 1);
	if (err) {
		DPRINTF(("%s: configuration failed, error=%s\n",
			 device_get_nameunit(self), usbd_errstr(err)));
		return ENXIO;
	}

	if (dev->depth > USB_HUB_MAX_DEPTH) {
		device_printf(self,
		    "hub depth (%d) exceeded, hub ignored\n",
		    USB_HUB_MAX_DEPTH);
		return ENXIO;
	}

	/* Get hub descriptor. */
	req.bmRequestType = UT_READ_CLASS_DEVICE;
	req.bRequest = UR_GET_DESCRIPTOR;
	USETW2(req.wValue, (dev->address > 1 ? UDESC_HUB : 0), 0);
	USETW(req.wIndex, 0);
	USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE);
	DPRINTFN(1,("usb_init_hub: getting hub descriptor\n"));
	err = usbd_do_request(dev, &req, &hubdesc);
	nports = hubdesc.bNbrPorts;
	if (!err && nports > 7) {
		USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE + (nports+1) / 8);
		err = usbd_do_request(dev, &req, &hubdesc);
	}
	if (err) {
		DPRINTF(("%s: getting hub descriptor failed, error=%s\n",
			 device_get_nameunit(self), usbd_errstr(err)));
		return ENXIO;
	}

	for (nremov = 0, port = 1; port <= nports; port++)
		if (!UHD_NOT_REMOV(&hubdesc, port))
			nremov++;
	device_printf(self,
	    "%d port%s with %d removable, %s powered\n",
	    nports, nports != 1 ? "s" : "",
	    nremov, dev->self_powered ? "self" : "bus");

	if (nports == 0) {
		device_printf(self, "no ports, hub ignored\n");
		goto bad;
	}

	hub = kmalloc(sizeof(*hub) + (nports-1) * sizeof(struct usbd_port),
		     M_USBDEV, M_WAITOK);
	dev->hub = hub;
	dev->hub->hubdev = self; 
	hub->explore = uhub_explore;
	hub->hubdesc = hubdesc;

	DPRINTFN(1,("usbhub_init_hub: selfpowered=%d, parent=%p, "
		    "parent->selfpowered=%d\n",
		 dev->self_powered, dev->powersrc->parent,
		 dev->powersrc->parent ?
		 dev->powersrc->parent->self_powered : 0));

	if (!dev->self_powered && dev->powersrc->parent != NULL &&
	    !dev->powersrc->parent->self_powered) {
		device_printf(self,
		    "bus powered hub connected to bus powered hub, "
		    "ignored\n");
		goto bad;
	}

	/* Set up interrupt pipe. */
	err = usbd_device2interface_handle(dev, 0, &iface);
	if (err) {
		device_printf(self, "no interface handle\n");
		goto bad;
	}
	ed = usbd_interface2endpoint_descriptor(iface, 0);
	if (ed == NULL) {
		device_printf(self, "no endpoint descriptor\n");
		goto bad;
	}
	if ((ed->bmAttributes & UE_XFERTYPE) != UE_INTERRUPT) {
		device_printf(self, "bad interrupt endpoint\n");
		goto bad;
	}

	err = usbd_open_pipe_intr(iface, ed->bEndpointAddress,
		  USBD_SHORT_XFER_OK, &sc->sc_ipipe, sc, sc->sc_status,
		  sizeof(sc->sc_status), uhub_intr, UHUB_INTR_INTERVAL);
	if (err) {
		device_printf(self, "cannot open interrupt pipe\n");
		goto bad;
	}

	/* Wait with power off for a while. */
	usbd_delay_ms(dev, USB_POWER_DOWN_TIME);

	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, dev, self);

	/*
	 * To have the best chance of success we do things in the exact same
	 * order as Windoze98.  This should not be necessary, but some
	 * devices do not follow the USB specs to the letter.
	 *
	 * These are the events on the bus when a hub is attached:
	 *  Get device and config descriptors (see attach code)
	 *  Get hub descriptor (see above)
	 *  For all ports
	 *     turn on power
	 *     wait for power to become stable
	 * (all below happens in explore code)
	 *  For all ports
	 *     clear C_PORT_CONNECTION
	 *  For all ports
	 *     get port status
	 *     if device connected
	 *        wait 100 ms
	 *        turn on reset
	 *        wait
	 *        clear C_PORT_RESET
	 *        get port status
	 *        proceed with device attachment
	 */

	if (UHUB_IS_HIGH_SPEED(sc)) {
		tts = kmalloc((UHUB_IS_SINGLE_TT(sc) ? 1 : nports) *
			      sizeof(struct usbd_tt), M_USBDEV, M_WAITOK);
	}

	/* Set up data structures */
	for (p = 0; p < nports; p++) {
		struct usbd_port *up = &hub->ports[p];
		up->device = NULL;
		up->parent = dev;
		up->portno = p+1;
		if (dev->self_powered)
			/* Self powered hub, give ports maximum current. */
			up->power = USB_MAX_POWER;
		else
			up->power = USB_MIN_POWER;
		up->restartcnt = 0;
		if (UHUB_IS_HIGH_SPEED(sc)) {
			up->tt = &tts[UHUB_IS_SINGLE_TT(sc) ? 0 : p];
			up->tt->hub = hub;
		} else {
			up->tt = NULL;
		}
	}

	/* XXX should check for none, individual, or ganged power? */

	pwrdly = dev->hub->hubdesc.bPwrOn2PwrGood * UHD_PWRON_FACTOR
	    + USB_EXTRA_POWER_UP_TIME;
	for (port = 1; port <= nports; port++) {
		/* Turn the power on. */
		err = usbd_set_port_feature(dev, port, UHF_PORT_POWER);
		if (err)
			device_printf(self,
			    "port %d power on failed, %s\n",
			    port, usbd_errstr(err));
		DPRINTF(("usb_init_port: turn on port %d power\n", port));
	}

	/* Wait for stable power if we are not a root hub */
	if (dev->powersrc->parent != NULL)
		usbd_delay_ms(dev, pwrdly);

	/* The usual exploration will finish the setup. */

	sc->sc_running = 1;

	return 0;

 bad:
	if (hub)
		kfree(hub, M_USBDEV);
	dev->hub = NULL;
	return ENXIO;
}
Exemple #13
0
void
ubsa_attach(struct device *parent, struct device *self, void *aux)
{
	struct ubsa_softc *sc = (struct ubsa_softc *)self;
	struct usb_attach_arg *uaa = aux;
	struct usbd_device *dev = uaa->device;
	usb_config_descriptor_t *cdesc;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;
	const char *devname = sc->sc_dev.dv_xname;
	usbd_status err;
	struct ucom_attach_args uca;
	int i;

	sc->sc_udev = dev;

	/*
	 * initialize rts, dtr variables to something
	 * different from boolean 0, 1
	 */
	sc->sc_dtr = -1;
	sc->sc_rts = -1;

	DPRINTF(("ubsa attach: sc = %p\n", sc));

	/* initialize endpoints */
	uca.bulkin = uca.bulkout = -1;
	sc->sc_intr_number = -1;
	sc->sc_intr_pipe = NULL;

	/* Move the device into the configured state. */
	err = usbd_set_config_index(dev, UBSA_CONFIG_INDEX, 1);
	if (err) {
		printf("%s: failed to set configuration: %s\n",
		    devname, usbd_errstr(err));
		usbd_deactivate(sc->sc_udev);
		goto error;
	}

	/* get the config descriptor */
	cdesc = usbd_get_config_descriptor(sc->sc_udev);

	if (cdesc == NULL) {
		printf("%s: failed to get configuration descriptor\n",
		    devname);
		usbd_deactivate(sc->sc_udev);
		goto error;
	}

	/* get the first interface */
	err = usbd_device2interface_handle(dev, UBSA_IFACE_INDEX,
	    &sc->sc_iface);
	if (err) {
		printf("%s: failed to get interface: %s\n",
			devname, usbd_errstr(err));
		usbd_deactivate(sc->sc_udev);
		goto error;
	}

	/* Find the endpoints */

	id = usbd_get_interface_descriptor(sc->sc_iface);
	sc->sc_iface_number = id->bInterfaceNumber;

	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
		if (ed == NULL) {
			printf("%s: no endpoint descriptor for %d\n",
			    sc->sc_dev.dv_xname, i);
			usbd_deactivate(sc->sc_udev);
			goto error;
		}

		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
			sc->sc_intr_number = ed->bEndpointAddress;
			sc->sc_isize = UGETW(ed->wMaxPacketSize);
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			uca.bulkin = ed->bEndpointAddress;
			uca.ibufsize = UGETW(ed->wMaxPacketSize);
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			uca.bulkout = ed->bEndpointAddress;
			uca.obufsize = UGETW(ed->wMaxPacketSize);
		}
	}

	if (sc->sc_intr_number == -1) {
		printf("%s: Could not find interrupt in\n", devname);
		usbd_deactivate(sc->sc_udev);
		goto error;
	}

	if (uca.bulkin == -1) {
		printf("%s: Could not find data bulk in\n", devname);
		usbd_deactivate(sc->sc_udev);
		goto error;
	}

	if (uca.bulkout == -1) {
		printf("%s: Could not find data bulk out\n", devname);
		usbd_deactivate(sc->sc_udev);
		goto error;
	}

	uca.portno = UCOM_UNK_PORTNO;
	/* bulkin, bulkout set above */
	uca.ibufsizepad = uca.ibufsize;
	uca.opkthdrlen = 0;
	uca.device = dev;
	uca.iface = sc->sc_iface;
	uca.methods = &ubsa_methods;
	uca.arg = sc;
	uca.info = NULL;

	DPRINTF(("ubsa: in = 0x%x, out = 0x%x, intr = 0x%x\n",
	    uca.bulkin, uca.bulkout, sc->sc_intr_number));

	sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch);

error:
	return;
}
Exemple #14
0
void
uhub_attach(struct device *parent, struct device *self, void *aux)
{
	struct uhub_softc *sc = (struct uhub_softc *)self;
	struct usb_attach_arg *uaa = aux;
	struct usbd_device *dev = uaa->device;
	struct usbd_hub *hub = NULL;
	union {
		usb_hub_descriptor_t	hs;
		usb_hub_ss_descriptor_t	ss;
	} hd;
	int p, port, nports, powerdelay;
	struct usbd_interface *iface;
	usb_endpoint_descriptor_t *ed;
	struct usbd_tt *tts = NULL;
	uint8_t ttthink = 0;
	usbd_status err;
#ifdef UHUB_DEBUG
	int nremov;
#endif

	sc->sc_hub = dev;

	err = usbd_set_config_index(dev, 0, 1);
	if (err) {
		DPRINTF("%s: configuration failed, error=%s\n",
			 sc->sc_dev.dv_xname, usbd_errstr(err));
		return;
	}

	if (dev->depth > USB_HUB_MAX_DEPTH) {
		printf("%s: hub depth (%d) exceeded, hub ignored\n",
		       sc->sc_dev.dv_xname, USB_HUB_MAX_DEPTH);
		return;
	}

	/*
	 * Super-Speed hubs need to know their depth to be able to
	 * parse the bits of the route-string that correspond to
	 * their downstream port number.
	 *
	 * This does no apply to root hubs.
	 */
	if (dev->depth != 0 && dev->speed == USB_SPEED_SUPER) {
		if (usbd_set_hub_depth(dev, dev->depth - 1)) {
			printf("%s: unable to set HUB depth\n",
			    sc->sc_dev.dv_xname);
			return;
		}
	}

	/* Get hub descriptor. */
	if (dev->speed == USB_SPEED_SUPER) {
		err = usbd_get_hub_ss_descriptor(dev, &hd.ss, 1);
		nports = hd.ss.bNbrPorts;
		powerdelay = (hd.ss.bPwrOn2PwrGood * UHD_PWRON_FACTOR);
		if (!err && nports > 7)
			usbd_get_hub_ss_descriptor(dev, &hd.ss, nports);
	} else {
		err = usbd_get_hub_descriptor(dev, &hd.hs, 1);
		nports = hd.hs.bNbrPorts;
		powerdelay = (hd.hs.bPwrOn2PwrGood * UHD_PWRON_FACTOR);
		ttthink = UGETW(hd.hs.wHubCharacteristics) & UHD_TT_THINK;
		if (!err && nports > 7)
			usbd_get_hub_descriptor(dev, &hd.hs, nports);
	}

	if (err) {
		DPRINTF("%s: getting hub descriptor failed, error=%s\n",
			 sc->sc_dev.dv_xname, usbd_errstr(err));
		return;
	}

#ifdef UHUB_DEBUG
	for (nremov = 0, port = 1; port <= nports; port++) {
		if (dev->speed == USB_SPEED_SUPER) {
			if (!UHD_NOT_REMOV(&hd.ss, port))
				nremov++;
		} else {
			if (!UHD_NOT_REMOV(&hd.hs, port))
				nremov++;
		}
	}

	printf("%s: %d port%s with %d removable, %s powered",
	       sc->sc_dev.dv_xname, nports, nports != 1 ? "s" : "",
	       nremov, dev->self_powered ? "self" : "bus");

	if (dev->depth > 0 && UHUB_IS_HIGH_SPEED(sc)) {
		printf(", %s transaction translator%s",
		    UHUB_IS_SINGLE_TT(sc) ? "single" : "multiple",
		    UHUB_IS_SINGLE_TT(sc) ? "" : "s");
	}

	printf("\n");
#endif

	if (nports == 0) {
		printf("%s: no ports, hub ignored\n", sc->sc_dev.dv_xname);
		goto bad;
	}

	hub = malloc(sizeof(*hub), M_USBDEV, M_NOWAIT);
	if (hub == NULL)
		return;
	hub->ports = mallocarray(nports, sizeof(struct usbd_port),
	    M_USBDEV, M_NOWAIT);
	if (hub->ports == NULL) {
		free(hub, M_USBDEV, 0);
		return;
	}
	dev->hub = hub;
	dev->hub->hubsoftc = sc;
	hub->explore = uhub_explore;
	hub->nports = nports;
	hub->powerdelay = powerdelay;
	hub->ttthink = ttthink >> 5;

	if (!dev->self_powered && dev->powersrc->parent != NULL &&
	    !dev->powersrc->parent->self_powered) {
		printf("%s: bus powered hub connected to bus powered hub, "
		       "ignored\n", sc->sc_dev.dv_xname);
		goto bad;
	}

	/* Set up interrupt pipe. */
	err = usbd_device2interface_handle(dev, 0, &iface);
	if (err) {
		printf("%s: no interface handle\n", sc->sc_dev.dv_xname);
		goto bad;
	}
	ed = usbd_interface2endpoint_descriptor(iface, 0);
	if (ed == NULL) {
		printf("%s: no endpoint descriptor\n", sc->sc_dev.dv_xname);
		goto bad;
	}
	if ((ed->bmAttributes & UE_XFERTYPE) != UE_INTERRUPT) {
		printf("%s: bad interrupt endpoint\n", sc->sc_dev.dv_xname);
		goto bad;
	}

	sc->sc_statuslen = (nports + 1 + 7) / 8;
	sc->sc_statusbuf = malloc(sc->sc_statuslen, M_USBDEV, M_NOWAIT);
	if (!sc->sc_statusbuf)
		goto bad;

	err = usbd_open_pipe_intr(iface, ed->bEndpointAddress,
		  USBD_SHORT_XFER_OK, &sc->sc_ipipe, sc, sc->sc_statusbuf,
		  sc->sc_statuslen, uhub_intr, UHUB_INTR_INTERVAL);
	if (err) {
		printf("%s: cannot open interrupt pipe\n",
		       sc->sc_dev.dv_xname);
		goto bad;
	}

	/* Wait with power off for a while. */
	usbd_delay_ms(dev, USB_POWER_DOWN_TIME);

	/*
	 * To have the best chance of success we do things in the exact same
	 * order as Windoze98.  This should not be necessary, but some
	 * devices do not follow the USB specs to the letter.
	 *
	 * These are the events on the bus when a hub is attached:
	 *  Get device and config descriptors (see attach code)
	 *  Get hub descriptor (see above)
	 *  For all ports
	 *     turn on power
	 *     wait for power to become stable
	 * (all below happens in explore code)
	 *  For all ports
	 *     clear C_PORT_CONNECTION
	 *  For all ports
	 *     get port status
	 *     if device connected
	 *        wait 100 ms
	 *        turn on reset
	 *        wait
	 *        clear C_PORT_RESET
	 *        get port status
	 *        proceed with device attachment
	 */

	if (UHUB_IS_HIGH_SPEED(sc)) {
		tts = mallocarray((UHUB_IS_SINGLE_TT(sc) ? 1 : nports),
		    sizeof (struct usbd_tt), M_USBDEV, M_NOWAIT);
		if (!tts)
			goto bad;
	}
	/* Set up data structures */
	for (p = 0; p < nports; p++) {
		struct usbd_port *up = &hub->ports[p];
		up->device = NULL;
		up->parent = dev;
		up->portno = p + 1;
		if (dev->self_powered)
			/* Self powered hub, give ports maximum current. */
			up->power = USB_MAX_POWER;
		else
			up->power = USB_MIN_POWER;
		up->restartcnt = 0;
		up->reattach = 0;
		if (UHUB_IS_HIGH_SPEED(sc)) {
			up->tt = &tts[UHUB_IS_SINGLE_TT(sc) ? 0 : p];
			up->tt->hub = hub;
		} else {
			up->tt = NULL;
		}
	}

	for (port = 1; port <= nports; port++) {
		/* Turn the power on. */
		err = usbd_set_port_feature(dev, port, UHF_PORT_POWER);
		if (err)
			printf("%s: port %d power on failed, %s\n",
			       sc->sc_dev.dv_xname, port,
			       usbd_errstr(err));
		/* Make sure we check the port status at least once. */
		sc->sc_status |= (1 << port);
	}

	/* Wait for stable power. */
        if (dev->powersrc->parent != NULL)
		usbd_delay_ms(dev, powerdelay + USB_EXTRA_POWER_UP_TIME);

	/* The usual exploration will finish the setup. */

	sc->sc_running = 1;

	return;

 bad:
	if (sc->sc_statusbuf)
		free(sc->sc_statusbuf, M_USBDEV, 0);
	if (hub) {
		if (hub->ports)
			free(hub->ports, M_USBDEV, 0);
		free(hub, M_USBDEV, 0);
	}
	dev->hub = NULL;
}
Exemple #15
0
void 
uftdi_attach(device_t parent, device_t self, void *aux)
{
	struct uftdi_softc *sc = device_private(self);
	struct usb_attach_arg *uaa = aux;
	usbd_device_handle dev = uaa->device;
	usbd_interface_handle iface;
	usb_device_descriptor_t *ddesc;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;
	char *devinfop;
	const char *devname = device_xname(self);
	int i,idx;
	usbd_status err;
	struct ucom_attach_args uca;

	DPRINTFN(10,("\nuftdi_attach: sc=%p\n", sc));

	aprint_naive("\n");
	aprint_normal("\n");

	devinfop = usbd_devinfo_alloc(dev, 0);
	aprint_normal_dev(self, "%s\n", devinfop);
	usbd_devinfo_free(devinfop);

	/* Move the device into the configured state. */
	err = usbd_set_config_index(dev, UFTDI_CONFIG_INDEX, 1);
	if (err) {
		aprint_error("\n%s: failed to set configuration, err=%s\n",
		       devname, usbd_errstr(err));
		goto bad;
	}

	sc->sc_dev = self;
	sc->sc_udev = dev;
	sc->sc_numports = 1;
	sc->sc_type = UFTDI_TYPE_8U232AM; /* most devices are post-8U232AM */
	sc->sc_hdrlen = 0;
	if (uaa->vendor == USB_VENDOR_FTDI
	    && uaa->product == USB_PRODUCT_FTDI_SERIAL_8U100AX) {
		sc->sc_type = UFTDI_TYPE_SIO;
		sc->sc_hdrlen = 1;
	}

	ddesc = usbd_get_device_descriptor(dev);
	sc->sc_chiptype = UGETW(ddesc->bcdDevice);
	switch (sc->sc_chiptype) {
	case 0x500: /* 2232D */
	case 0x700: /* 2232H */
		sc->sc_numports = 2;
		break;
	case 0x800: /* 4232H */
		sc->sc_numports = 4;
		break;
	case 0x200: /* 232/245AM */
	case 0x400: /* 232/245BL */
	case 0x600: /* 232/245R */
	default:
		break;
	}

	for (idx = UFTDI_IFACE_INDEX; idx < sc->sc_numports; idx++) {
		err = usbd_device2interface_handle(dev, idx, &iface);
		if (err) {
			aprint_error(
			    "\n%s: failed to get interface idx=%d, err=%s\n",
			    devname, idx, usbd_errstr(err));
			goto bad;
		}

		id = usbd_get_interface_descriptor(iface);

		sc->sc_iface[idx] = iface;

		uca.bulkin = uca.bulkout = -1;
		uca.ibufsize = uca.obufsize = 0;
		for (i = 0; i < id->bNumEndpoints; i++) {
			int addr, dir, attr;
			ed = usbd_interface2endpoint_descriptor(iface, i);
			if (ed == NULL) {
				aprint_error_dev(self,
				    "could not read endpoint descriptor: %s\n",
				    usbd_errstr(err));
				goto bad;
			}

			addr = ed->bEndpointAddress;
			dir = UE_GET_DIR(ed->bEndpointAddress);
			attr = ed->bmAttributes & UE_XFERTYPE;
			if (dir == UE_DIR_IN && attr == UE_BULK) {
				uca.bulkin = addr;
				uca.ibufsize = UGETW(ed->wMaxPacketSize);
				if (uca.ibufsize >= UFTDI_MAX_IBUFSIZE)
					uca.ibufsize = UFTDI_MAX_IBUFSIZE;
			} else if (dir == UE_DIR_OUT && attr == UE_BULK) {
				uca.bulkout = addr;
				uca.obufsize = UGETW(ed->wMaxPacketSize)
				    - sc->sc_hdrlen;
				if (uca.obufsize >= UFTDI_MAX_OBUFSIZE)
					uca.obufsize = UFTDI_MAX_OBUFSIZE;
				/* Limit length if we have a 6-bit header.  */
				if ((sc->sc_hdrlen > 0) &&
				    (uca.obufsize > UFTDIOBUFSIZE))
					uca.obufsize = UFTDIOBUFSIZE;
			} else {
				aprint_error_dev(self,
				    "unexpected endpoint\n");
				goto bad;
			}
		}
		if (uca.bulkin == -1) {
			aprint_error_dev(self,
			    "Could not find data bulk in\n");
			goto bad;
		}
		if (uca.bulkout == -1) {
			aprint_error_dev(self,
			    "Could not find data bulk out\n");
			goto bad;
		}

		uca.portno = FTDI_PIT_SIOA + idx;
		/* bulkin, bulkout set above */
		if (uca.ibufsize == 0)
			uca.ibufsize = UFTDIIBUFSIZE;
		uca.ibufsizepad = uca.ibufsize;
		if (uca.obufsize == 0)
			uca.obufsize = UFTDIOBUFSIZE - sc->sc_hdrlen;
		uca.opkthdrlen = sc->sc_hdrlen;
		uca.device = dev;
		uca.iface = iface;
		uca.methods = &uftdi_methods;
		uca.arg = sc;
		uca.info = NULL;

		DPRINTF(("uftdi: in=0x%x out=0x%x isize=0x%x osize=0x%x\n",
			uca.bulkin, uca.bulkout,
			uca.ibufsize, uca.obufsize));
		sc->sc_subdev[idx] = config_found_sm_loc(self, "ucombus", NULL,
		    &uca, ucomprint, ucomsubmatch);
	}

	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
			   sc->sc_dev);

	return;

bad:
	DPRINTF(("uftdi_attach: ATTACH ERROR\n"));
	sc->sc_dying = 1;
	return;
}
Exemple #16
0
void
uvisor_attach(struct device *parent, struct device *self, void *aux)
{
	struct uvisor_softc *sc = (struct uvisor_softc *)self;
	struct usb_attach_arg *uaa = aux;
	struct usbd_device *dev = uaa->device;
	struct usbd_interface *iface;
	usb_interface_descriptor_t *id;
	struct uvisor_connection_info coninfo;
	struct uvisor_palm_connection_info palmconinfo;
	usb_endpoint_descriptor_t *ed;
	int i, j, hasin, hasout, port;
	usbd_status err;
	struct ucom_attach_args uca;

	DPRINTFN(10,("\nuvisor_attach: sc=%p\n", sc));

	/* Move the device into the configured state. */
	err = usbd_set_config_index(dev, UVISOR_CONFIG_INDEX, 1);
	if (err) {
		printf(": failed to set configuration, err=%s\n",
		    usbd_errstr(err));
		goto bad;
	}

	err = usbd_device2interface_handle(dev, UVISOR_IFACE_INDEX, &iface);
	if (err) {
		printf(": failed to get interface, err=%s\n",
		    usbd_errstr(err));
		goto bad;
	}

	sc->sc_flags = uvisor_lookup(uaa->vendor, uaa->product)->uv_flags;
	sc->sc_vendor = uaa->vendor;
	
	if ((sc->sc_flags & (VISOR | PALM4)) == 0) {
		printf("%s: device is neither visor nor palm\n", 
		    sc->sc_dev.dv_xname);
		goto bad;
	}

	id = usbd_get_interface_descriptor(iface);

	sc->sc_udev = dev;
	sc->sc_iface = iface;

	uca.ibufsize = UVISORIBUFSIZE;
	uca.obufsize = UVISOROBUFSIZE;
	uca.ibufsizepad = UVISORIBUFSIZE;
	uca.opkthdrlen = 0;
	uca.device = dev;
	uca.iface = iface;
	uca.methods = &uvisor_methods;
	uca.arg = sc;

	err = uvisor_init(sc, &coninfo, &palmconinfo);
	if (err) {
		printf("%s: init failed, %s\n", sc->sc_dev.dv_xname,
		       usbd_errstr(err));
		goto bad;
	}

	if (sc->sc_flags & VISOR) {
		sc->sc_numcon = UGETW(coninfo.num_ports);
		if (sc->sc_numcon > UVISOR_MAX_CONN)
			sc->sc_numcon = UVISOR_MAX_CONN;

		/* Attach a ucom for each connection. */
		for (i = 0; i < sc->sc_numcon; ++i) {
			switch (coninfo.connections[i].port_function_id) {
			case UVISOR_FUNCTION_GENERIC:
				uca.info = "Generic";
				break;
			case UVISOR_FUNCTION_DEBUGGER:
				uca.info = "Debugger";
				break;
			case UVISOR_FUNCTION_HOTSYNC:
				uca.info = "HotSync";
				break;
			case UVISOR_FUNCTION_REMOTE_FILE_SYS:
				uca.info = "Remote File System";
				break;
			default:
				uca.info = "unknown";
				break;
			}
			port = coninfo.connections[i].port;
			uca.portno = port;
			uca.bulkin = port | UE_DIR_IN;
			uca.bulkout = port | UE_DIR_OUT;
			/* Verify that endpoints exist. */
			hasin = 0;
			hasout = 0;
			for (j = 0; j < id->bNumEndpoints; j++) {
				ed = usbd_interface2endpoint_descriptor(iface, j);
				if (ed == NULL)
					break;
				if (UE_GET_ADDR(ed->bEndpointAddress) == port &&
				    (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
					if (UE_GET_DIR(ed->bEndpointAddress)
					    == UE_DIR_IN)
						hasin++;
					else
						hasout++;
				}
			}
			if (hasin == 1 && hasout == 1)
				sc->sc_subdevs[i] = config_found_sm(self, &uca,
				    ucomprint, ucomsubmatch);
			else
				printf("%s: no proper endpoints for port %d (%d,%d)\n",
				    sc->sc_dev.dv_xname, port, hasin, hasout);
		}
	} else {
		sc->sc_numcon = palmconinfo.num_ports;
		if (sc->sc_numcon > UVISOR_MAX_CONN)
			sc->sc_numcon = UVISOR_MAX_CONN;

		/* Attach a ucom for each connection. */
		for (i = 0; i < sc->sc_numcon; ++i) {
			/*
			 * XXX this should copy out 4-char string from the
			 * XXX port_function_id, but where would the string go?
			 * XXX uca.info is a const char *, not an array.
			 */
			uca.info = "sync";
			uca.portno = i;
			if (palmconinfo.endpoint_numbers_different) {
				port = palmconinfo.connections[i].end_point_info;
				uca.bulkin = (port >> 4) | UE_DIR_IN;
				uca.bulkout = (port & 0xf) | UE_DIR_OUT;
			} else {
				port = palmconinfo.connections[i].port;
				uca.bulkin = port | UE_DIR_IN;
				uca.bulkout = port | UE_DIR_OUT;
			}
			sc->sc_subdevs[i] = config_found_sm(self, &uca,
			    ucomprint, ucomsubmatch);
		}
Exemple #17
0
void
uts_attach(struct device *parent, struct device *self, void *aux)
{
    struct uts_softc *sc = (struct uts_softc *)self;
    struct usb_attach_arg *uaa = aux;
    usb_config_descriptor_t *cdesc;
    usb_interface_descriptor_t *id;
    usb_endpoint_descriptor_t *ed;
    struct wsmousedev_attach_args a;
    int i;

    sc->sc_udev = uaa->device;
    sc->sc_product = uaa->product;
    sc->sc_vendor = uaa->vendor;
    sc->sc_intr_number = -1;
    sc->sc_intr_pipe = NULL;
    sc->sc_enabled = sc->sc_isize = 0;

    /* Copy the default scalue values to each softc */
    bcopy(&def_scale, &sc->sc_tsscale, sizeof(sc->sc_tsscale));

    /* Move the device into the configured state. */
    if (usbd_set_config_index(uaa->device, UTS_CONFIG_INDEX, 1) != 0) {
        printf("%s: could not set configuartion no\n",
               sc->sc_dev.dv_xname);
        sc->sc_dying = 1;
        return;
    }

    /* get the config descriptor */
    cdesc = usbd_get_config_descriptor(sc->sc_udev);
    if (cdesc == NULL) {
        printf("%s: failed to get configuration descriptor\n",
               sc->sc_dev.dv_xname);
        sc->sc_dying = 1;
        return;
    }

    /* get the interface */
    if (usbd_device2interface_handle(uaa->device, 0, &sc->sc_iface) != 0) {
        printf("%s: failed to get interface\n",
               sc->sc_dev.dv_xname);
        sc->sc_dying = 1;
        return;
    }

    /* Find the interrupt endpoint */
    id = usbd_get_interface_descriptor(sc->sc_iface);
    sc->sc_iface_number = id->bInterfaceNumber;

    for (i = 0; i < id->bNumEndpoints; i++) {
        ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
        if (ed == NULL) {
            printf("%s: no endpoint descriptor for %d\n",
                   sc->sc_dev.dv_xname, i);
            sc->sc_dying = 1;
            return;
        }

        if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
                UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
            sc->sc_intr_number = ed->bEndpointAddress;
            sc->sc_isize = UGETW(ed->wMaxPacketSize);
        }
    }

    if (sc->sc_intr_number== -1) {
        printf("%s: Could not find interrupt in\n",
               sc->sc_dev.dv_xname);
        sc->sc_dying = 1;
        return;
    }

    a.accessops = &uts_accessops;
    a.accesscookie = sc;

    sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
}
Exemple #18
0
static int
moscom_attach(device_t self)
{
	struct moscom_softc *sc = device_get_softc(self);
	struct usb_attach_arg *uaa = device_get_ivars(self);
	struct ucom_softc *ucom;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;
	usbd_status error;
	int i;

	bzero(sc, sizeof (struct moscom_softc));
	ucom = &sc->sc_ucom;
	ucom->sc_dev = self;
	ucom->sc_udev = uaa->device;
	ucom->sc_iface = uaa->iface;

	if (usbd_set_config_index(ucom->sc_udev, MOSCOM_CONFIG_NO, 1) != 0) {
		device_printf(ucom->sc_dev, "could not set configuration no\n");
		ucom->sc_dying = 1;
		return ENXIO;
	}

	/* get the first interface handle */
	error = usbd_device2interface_handle(ucom->sc_udev, MOSCOM_IFACE_NO,
	    &ucom->sc_iface);
	if (error != 0) {
		device_printf(ucom->sc_dev, "could not get interface handle\n");
		ucom->sc_dying = 1;
		return ENXIO;
	}

	id = usbd_get_interface_descriptor(ucom->sc_iface);

	ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i);
		if (ed == NULL) {
			device_printf(ucom->sc_dev, "no endpoint descriptor "
				      "found for %d\n", i);
			ucom->sc_dying = 1;
			return ENXIO;
		}

		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
			ucom->sc_bulkin_no = ed->bEndpointAddress;
		else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
			ucom->sc_bulkout_no = ed->bEndpointAddress;
	}

	if (ucom->sc_bulkin_no == -1 || ucom->sc_bulkout_no == -1) {
		device_printf(ucom->sc_dev, "missing endpoint\n");
		ucom->sc_dying = 1;
		return ENXIO;
	}

	ucom->sc_parent = sc;
	ucom->sc_portno = UCOM_UNK_PORTNO;
	ucom->sc_ibufsize = MOSCOMBUFSZ;
	ucom->sc_obufsize = MOSCOMBUFSZ;
	ucom->sc_ibufsizepad = MOSCOMBUFSZ;
	ucom->sc_opkthdrlen = 0;
	ucom->sc_callback = &moscom_callback;

	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, ucom->sc_udev,
			   ucom->sc_dev);

	return 0;
}
Exemple #19
0
void 
moscom_attach(device_t parent, device_t self, void *aux)
{
	struct moscom_softc *sc = device_private(self);
	struct usb_attach_arg *uaa = aux;
	usbd_device_handle dev = uaa->device;
	struct ucom_attach_args uca;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;
	char *devinfop;
	usbd_status error;
	int i;

	aprint_naive("\n");
	aprint_normal("\n");

	devinfop = usbd_devinfo_alloc(dev, 0);
	aprint_normal_dev(self, "%s\n", devinfop);
	usbd_devinfo_free(devinfop);

	sc->sc_dev = self;

	bzero(&uca, sizeof(uca));
	sc->sc_udev = uaa->device;

	if (usbd_set_config_index(sc->sc_udev, MOSCOM_CONFIG_NO, 1) != 0) {
		aprint_error_dev(self, "could not set configuration no\n");
		sc->sc_dying = 1;
		return;
	}

	/* get the first interface handle */
	error = usbd_device2interface_handle(sc->sc_udev, MOSCOM_IFACE_NO,
	    &sc->sc_iface);
	if (error != 0) {
		aprint_error_dev(self, "could not get interface handle\n");
		sc->sc_dying = 1;
		return;
	}

	id = usbd_get_interface_descriptor(sc->sc_iface);

	uca.bulkin = uca.bulkout = -1;
	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
		if (ed == NULL) {
			aprint_error_dev(self,
			    "no endpoint descriptor found for %d\n", i);
			sc->sc_dying = 1;
			return;
		}

		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
			uca.bulkin = ed->bEndpointAddress;
		else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
			uca.bulkout = ed->bEndpointAddress;
	}

	if (uca.bulkin == -1 || uca.bulkout == -1) {
		aprint_error_dev(self, "missing endpoint\n");
		sc->sc_dying = 1;
		return;
	}

	uca.ibufsize = MOSCOMBUFSZ;
	uca.obufsize = MOSCOMBUFSZ;
	uca.ibufsizepad = MOSCOMBUFSZ;
	uca.opkthdrlen = 0;
	uca.device = sc->sc_udev;
	uca.iface = sc->sc_iface;
	uca.methods = &moscom_methods;
	uca.arg = sc;
	uca.info = NULL;

	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
	    sc->sc_dev);
	
	sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL, &uca,
					    ucomprint, ucomsubmatch);

	return;
}
Exemple #20
0
void
uticom_attach_hook(void *arg)
{
	struct uticom_softc		*sc = arg;
	usb_config_descriptor_t		*cdesc;
	usb_interface_descriptor_t	*id;
	usb_endpoint_descriptor_t	*ed;
	usbd_status			 err;
	int				 status, i;
	usb_device_descriptor_t		*dd;
	struct ucom_attach_args		 uca;

	/* Initialize endpoints. */
	uca.bulkin = uca.bulkout = -1;
	sc->sc_intr_number = -1;
	sc->sc_intr_pipe = NULL;

	dd = usbd_get_device_descriptor(sc->sc_udev);
	DPRINTF(("%s: uticom_attach: num of configurations %d\n",
	    sc->sc_dev.dv_xname, dd->bNumConfigurations));

	/* The device without firmware has single configuration with single
	 * bulk out interface. */
	if (dd->bNumConfigurations > 1)
		goto fwload_done;

	/* Loading firmware. */
	DPRINTF(("%s: uticom_attach: starting loading firmware\n",
	    sc->sc_dev.dv_xname));

	err = usbd_set_config_index(sc->sc_udev, UTICOM_CONFIG_INDEX, 1);
	if (err) {
		printf("%s: failed to set configuration: %s\n",
		    sc->sc_dev.dv_xname, usbd_errstr(err));
		usbd_deactivate(sc->sc_udev);
		return;
	}

	/* Get the config descriptor. */
	cdesc = usbd_get_config_descriptor(sc->sc_udev);

	if (cdesc == NULL) {
		printf("%s: failed to get configuration descriptor\n",
		    sc->sc_dev.dv_xname);
		usbd_deactivate(sc->sc_udev);
		return;
	}

	err = usbd_device2interface_handle(sc->sc_udev, UTICOM_IFACE_INDEX,
	    &sc->sc_iface);
	if (err) {
		printf("%s: failed to get interface: %s\n",
		    sc->sc_dev.dv_xname, usbd_errstr(err));
		usbd_deactivate(sc->sc_udev);
		return;
	}

	/* Find the bulk out interface used to upload firmware. */
	id = usbd_get_interface_descriptor(sc->sc_iface);
	sc->sc_iface_number = id->bInterfaceNumber;

	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
		if (ed == NULL) {
			printf("%s: no endpoint descriptor for %d\n",
			    sc->sc_dev.dv_xname, i);
			usbd_deactivate(sc->sc_udev);
			return;
		}

		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			uca.bulkout = ed->bEndpointAddress;
			DPRINTF(("%s: uticom_attach: data bulk out num: %d\n",
			    sc->sc_dev.dv_xname, ed->bEndpointAddress));
		}

		if (uca.bulkout == -1) {
			printf("%s: could not find data bulk out\n",
			    sc->sc_dev.dv_xname);
			usbd_deactivate(sc->sc_udev);
			return;
		}
	}

	status = uticom_download_fw(sc, uca.bulkout, sc->sc_udev);

	if (status) {
		printf("%s: firmware download failed\n",
		    sc->sc_dev.dv_xname);
		usbd_deactivate(sc->sc_udev);
		return;
	} else {
		DPRINTF(("%s: firmware download succeeded\n",
		    sc->sc_dev.dv_xname));
	}

	status = usbd_reload_device_desc(sc->sc_udev);
	if (status) {
		printf("%s: error reloading device descriptor\n",
		    sc->sc_dev.dv_xname);
		usbd_deactivate(sc->sc_udev);
		return;
	}

fwload_done:
	dd = usbd_get_device_descriptor(sc->sc_udev);
	DPRINTF(("%s: uticom_attach: num of configurations %d\n",
	    sc->sc_dev.dv_xname, dd->bNumConfigurations));

	err = usbd_set_config_index(sc->sc_udev, UTICOM_ACTIVE_INDEX, 1);
	if (err) {
		printf("%s: failed to set configuration: %s\n",
		    sc->sc_dev.dv_xname, usbd_errstr(err));
		usbd_deactivate(sc->sc_udev);
		return;
	}

	/* Get the config descriptor. */
	cdesc = usbd_get_config_descriptor(sc->sc_udev);
	if (cdesc == NULL) {
		printf("%s: failed to get configuration descriptor\n",
		    sc->sc_dev.dv_xname);
		usbd_deactivate(sc->sc_udev);
		return;
	}

	/* Get the interface (XXX: multiport chips are not supported yet). */
	err = usbd_device2interface_handle(sc->sc_udev, UTICOM_IFACE_INDEX,
	    &sc->sc_iface);
	if (err) {
		printf("%s: failed to get interface: %s\n",
		    sc->sc_dev.dv_xname, usbd_errstr(err));
		usbd_deactivate(sc->sc_udev);
		return;
	}

	/* Find the interrupt endpoints. */
	id = usbd_get_interface_descriptor(sc->sc_iface);
	sc->sc_iface_number = id->bInterfaceNumber;

	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
		if (ed == NULL) {
			printf("%s: no endpoint descriptor for %d\n",
			    sc->sc_dev.dv_xname, i);
			usbd_deactivate(sc->sc_udev);
			return;
		}

		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
			sc->sc_intr_number = ed->bEndpointAddress;
			sc->sc_isize = UGETW(ed->wMaxPacketSize);

		}
	}

	if (sc->sc_intr_number == -1) {
		printf("%s: could not find interrupt in\n",
		    sc->sc_dev.dv_xname);
		usbd_deactivate(sc->sc_udev);
		return;
	}

	/* Keep interface for interrupt. */
	sc->sc_intr_iface = sc->sc_iface;

	/* Find the bulk{in,out} endpoints. */
	id = usbd_get_interface_descriptor(sc->sc_iface);
	sc->sc_iface_number = id->bInterfaceNumber;

	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
		if (ed == NULL) {
			printf("%s: no endpoint descriptor for %d\n",
			    sc->sc_dev.dv_xname, i);
			usbd_deactivate(sc->sc_udev);
			return;
		}

		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			uca.bulkin = ed->bEndpointAddress;
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			uca.bulkout = ed->bEndpointAddress;
		}
	}

	if (uca.bulkin == -1) {
		printf("%s: could not find data bulk in\n",
		    sc->sc_dev.dv_xname);
		usbd_deactivate(sc->sc_udev);
		return;
	}

	if (uca.bulkout == -1) {
		printf("%s: could not find data bulk out\n",
		    sc->sc_dev.dv_xname);
		usbd_deactivate(sc->sc_udev);
		return;
	}

	sc->sc_dtr = sc->sc_rts = -1;

	uca.portno = UCOM_UNK_PORTNO;
	uca.ibufsize = UTICOM_IBUFSZ;
	uca.obufsize = UTICOM_OBUFSZ;
	uca.ibufsizepad = UTICOM_IBUFSZ;
	uca.device = sc->sc_udev;
	uca.iface = sc->sc_iface;
	uca.opkthdrlen = 0;
	uca.methods = &uticom_methods;
	uca.arg = sc;
	uca.info = NULL;

	err = uticom_reset(sc);
	if (err) {
		printf("%s: reset failed: %s\n",
		    sc->sc_dev.dv_xname, usbd_errstr(err));
		usbd_deactivate(sc->sc_udev);
		return;
	}

	DPRINTF(("%s: uticom_attach: in = 0x%x, out = 0x%x, intr = 0x%x\n",
	    sc->sc_dev.dv_xname, uca.bulkin,
	    uca.bulkout, sc->sc_intr_number));

	sc->sc_subdev = config_found_sm((struct device *)sc, &uca, ucomprint, ucomsubmatch);
}
Exemple #21
0
static int
uplcom_attach(device_t self)
{
	struct uplcom_softc *sc = device_get_softc(self);
	struct usb_attach_arg *uaa = device_get_ivars(self);
	usbd_device_handle dev = uaa->device;
	struct ucom_softc *ucom;
	usb_config_descriptor_t *cdesc;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;
	const char *devname;
	usbd_status err;
	int i;

	ucom = &sc->sc_ucom;
	ucom->sc_dev = self;
	ucom->sc_udev = dev;
	ucom->sc_iface = uaa->iface;

	devname = device_get_nameunit(ucom->sc_dev);

	DPRINTF(("uplcom attach: sc = %p\n", sc));

	/* determine chip type */
	for (i = 0; uplcom_products[i].vendor != 0; i++) {
		if (uplcom_products[i].vendor == uaa->vendor &&
		    uplcom_products[i].product == uaa->product &&
		    (uplcom_products[i].release == uaa->release ||
		     uplcom_products[i].release == -1)) {
			sc->sc_chiptype = uplcom_products[i].chiptype;
			break;
		}
	}

	/*
	 * check we found the device - attach should have ensured we
	 * don't get here without matching device
	 */
	if (uplcom_products[i].vendor == 0) {
		printf("%s: didn't match\n", devname);
		ucom->sc_dying = 1;
		goto error;
	}

#ifdef USB_DEBUG
	/* print the chip type */
	if (sc->sc_chiptype == TYPE_PL2303X) {
		DPRINTF(("uplcom_attach: chiptype 2303X\n"));
	} else {
		DPRINTF(("uplcom_attach: chiptype 2303\n"));
	}
#endif

	/* initialize endpoints */
	ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
	sc->sc_intr_number = -1;
	sc->sc_intr_pipe = NULL;

	/* Move the device into the configured state. */
	err = usbd_set_config_index(dev, UPLCOM_CONFIG_INDEX, 1);
	if (err) {
		printf("%s: failed to set configuration: %s\n",
			devname, usbd_errstr(err));
		ucom->sc_dying = 1;
		goto error;
	}

	/* get the config descriptor */
	cdesc = usbd_get_config_descriptor(ucom->sc_udev);

	if (cdesc == NULL) {
		printf("%s: failed to get configuration descriptor\n",
			device_get_nameunit(ucom->sc_dev));
		ucom->sc_dying = 1;
		goto error;
	}

	/* get the (first/common) interface */
	err = usbd_device2interface_handle(dev, UPLCOM_IFACE_INDEX,
					   &ucom->sc_iface);
	if (err) {
		printf("%s: failed to get interface: %s\n",
			devname, usbd_errstr(err));
		ucom->sc_dying = 1;
		goto error;
	}

	/* Find the interrupt endpoints */

	id = usbd_get_interface_descriptor(ucom->sc_iface);
	sc->sc_iface_number = id->bInterfaceNumber;

	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i);
		if (ed == NULL) {
			printf("%s: no endpoint descriptor for %d\n",
				device_get_nameunit(ucom->sc_dev), i);
			ucom->sc_dying = 1;
			goto error;
		}

		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
			sc->sc_intr_number = ed->bEndpointAddress;
			sc->sc_isize = UGETW(ed->wMaxPacketSize);
		}
	}

	if (sc->sc_intr_number == -1) {
		printf("%s: Could not find interrupt in\n",
			device_get_nameunit(ucom->sc_dev));
		ucom->sc_dying = 1;
		goto error;
	}

	/* keep interface for interrupt */
	sc->sc_intr_iface = ucom->sc_iface;

	/*
	 * USB-RSAQ1 has two interface
	 *
	 *  USB-RSAQ1       | USB-RSAQ2
	 * -----------------+-----------------
	 * Interface 0      |Interface 0
	 *  Interrupt(0x81) | Interrupt(0x81)
	 * -----------------+ BulkIN(0x02)
	 * Interface 1	    | BulkOUT(0x83)
	 *   BulkIN(0x02)   |
	 *   BulkOUT(0x83)  |
	 */
	if (cdesc->bNumInterface == 2) {
		err = usbd_device2interface_handle(dev,
						   UPLCOM_SECOND_IFACE_INDEX,
						   &ucom->sc_iface);
		if (err) {
			printf("%s: failed to get second interface: %s\n",
				devname, usbd_errstr(err));
			ucom->sc_dying = 1;
			goto error;
		}
	}

	/* Find the bulk{in,out} endpoints */

	id = usbd_get_interface_descriptor(ucom->sc_iface);
	sc->sc_iface_number = id->bInterfaceNumber;

	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i);
		if (ed == NULL) {
			printf("%s: no endpoint descriptor for %d\n",
				device_get_nameunit(ucom->sc_dev), i);
			ucom->sc_dying = 1;
			goto error;
		}

		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			ucom->sc_bulkin_no = ed->bEndpointAddress;
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			ucom->sc_bulkout_no = ed->bEndpointAddress;
		}
	}

	if (ucom->sc_bulkin_no == -1) {
		printf("%s: Could not find data bulk in\n",
			device_get_nameunit(ucom->sc_dev));
		ucom->sc_dying = 1;
		goto error;
	}

	if (ucom->sc_bulkout_no == -1) {
		printf("%s: Could not find data bulk out\n",
			device_get_nameunit(ucom->sc_dev));
		ucom->sc_dying = 1;
		goto error;
	}

	sc->sc_dtr = sc->sc_rts = -1;
	ucom->sc_parent = sc;
	ucom->sc_portno = UCOM_UNK_PORTNO;
	/* bulkin, bulkout set above */
	ucom->sc_ibufsize = UPLCOMIBUFSIZE;
	ucom->sc_obufsize = UPLCOMOBUFSIZE;
	ucom->sc_ibufsizepad = UPLCOMIBUFSIZE;
	ucom->sc_opkthdrlen = 0;
	ucom->sc_callback = &uplcom_callback;

	err = uplcom_reset(sc);

	if (err) {
		printf("%s: reset failed: %s\n",
		       device_get_nameunit(ucom->sc_dev), usbd_errstr(err));
		ucom->sc_dying = 1;
		goto error;
	}

	DPRINTF(("uplcom: in = 0x%x, out = 0x%x, intr = 0x%x\n",
		 ucom->sc_bulkin_no, ucom->sc_bulkout_no, sc->sc_intr_number));

	TASK_INIT(&sc->sc_task, 0, uplcom_notify, sc);
	ucom_attach(&sc->sc_ucom);
	return 0;

error:
	return ENXIO;
}
Exemple #22
0
usbd_status
usbd_probe_and_attach(device_t parent, struct usbd_device *dev,
                      int port, int addr)
{
	USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
	usb_device_descriptor_t *dd = &dev->ud_ddesc;
	int confi, nifaces;
	usbd_status err;

	/* First try with device specific drivers. */
	DPRINTF("trying device specific drivers", 0, 0, 0, 0);
	err = usbd_attachwholedevice(parent, dev, port, 0);
	if (dev->ud_nifaces_claimed || err)
		return err;
	DPRINTF("no device specific driver found", 0, 0, 0, 0);

	DPRINTF("looping over %d configurations", dd->bNumConfigurations,
	    0, 0, 0);
	for (confi = 0; confi < dd->bNumConfigurations; confi++) {
		DPRINTFN(1, "trying config idx=%d", confi, 0, 0, 0);
		err = usbd_set_config_index(dev, confi, 1);
		if (err) {
			DPRINTF("port %d, set config at addr %d failed, "
			    "error=%d", port, addr, err, 0);
			printf("%s: port %d, set config at addr %d failed\n",
			    device_xname(parent), port, addr);
			return err;
		}
		nifaces = dev->ud_cdesc->bNumInterface;
		dev->ud_subdevs = kmem_zalloc(nifaces * sizeof(device_t),
		    KM_SLEEP);
		if (dev->ud_subdevs == NULL)
			return USBD_NOMEM;
		dev->ud_subdevlen = nifaces;

		err = usbd_attachinterfaces(parent, dev, port, NULL);

		if (!dev->ud_nifaces_claimed) {
			kmem_free(dev->ud_subdevs,
			    dev->ud_subdevlen * sizeof(device_t));
			dev->ud_subdevs = 0;
			dev->ud_subdevlen = 0;
		}
		if (dev->ud_nifaces_claimed || err)
			return err;
	}
	/* No interfaces were attached in any of the configurations. */

	if (dd->bNumConfigurations > 1) /* don't change if only 1 config */
		usbd_set_config_index(dev, 0, 0);

	DPRINTF("no interface drivers found", 0, 0, 0, 0);

	/* Finally try the generic driver. */
	err = usbd_attachwholedevice(parent, dev, port, 1);

	/*
	 * The generic attach failed, but leave the device as it is.
	 * We just did not find any drivers, that's all.  The device is
	 * fully operational and not harming anyone.
	 */
	DPRINTF("generic attach failed", 0, 0, 0, 0);

	return USBD_NORMAL_COMPLETION;
}
Exemple #23
0
void
umct_attach(struct device *parent, struct device *self, void *aux)
{
	struct umct_softc *sc = (struct umct_softc *)self;
	struct usb_attach_arg *uaa = aux;
	usbd_device_handle dev = uaa->device;
	usb_config_descriptor_t *cdesc;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;

	char *devname = sc->sc_dev.dv_xname;
	usbd_status err;
	int i;
	struct ucom_attach_args uca;

        sc->sc_udev = dev;
	sc->sc_product = uaa->product;

	DPRINTF(("\n\numct attach: sc=%p\n", sc));

	/* initialize endpoints */
	uca.bulkin = uca.bulkout = -1;
	sc->sc_intr_number = -1;
	sc->sc_intr_pipe = NULL;

	/* Move the device into the configured state. */
	err = usbd_set_config_index(dev, UMCT_CONFIG_INDEX, 1);
	if (err) {
		printf("\n%s: failed to set configuration, err=%s\n",
			devname, usbd_errstr(err));
		sc->sc_dying = 1;
		return;
	}

	/* get the config descriptor */
	cdesc = usbd_get_config_descriptor(sc->sc_udev);

	if (cdesc == NULL) {
		printf("%s: failed to get configuration descriptor\n",
			sc->sc_dev.dv_xname);
		sc->sc_dying = 1;
		return;
	}

	/* get the interface */
	err = usbd_device2interface_handle(dev, UMCT_IFACE_INDEX,
							&sc->sc_iface);
	if (err) {
		printf("\n%s: failed to get interface, err=%s\n",
			devname, usbd_errstr(err));
		sc->sc_dying = 1;
		return;
	}

	/* Find the bulk{in,out} and interrupt endpoints */

	id = usbd_get_interface_descriptor(sc->sc_iface);
	sc->sc_iface_number = id->bInterfaceNumber;

	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
		if (ed == NULL) {
			printf("%s: no endpoint descriptor for %d\n",
				sc->sc_dev.dv_xname, i);
			sc->sc_dying = 1;
			return;
		}

		/*
		 * The Bulkin endpoint is marked as an interrupt. Since
		 * we can't rely on the endpoint descriptor order, we'll
		 * check the wMaxPacketSize field to differentiate.
		 */
		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT &&
		    UGETW(ed->wMaxPacketSize) != 0x2) {
			uca.bulkin = ed->bEndpointAddress;
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			uca.bulkout = ed->bEndpointAddress;
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
			sc->sc_intr_number = ed->bEndpointAddress;
			sc->sc_isize = UGETW(ed->wMaxPacketSize);
		}
	}

	if (uca.bulkin == -1) {
		printf("%s: Could not find data bulk in\n",
			sc->sc_dev.dv_xname);
		sc->sc_dying = 1;
		return;
	}

	if (uca.bulkout == -1) {
		printf("%s: Could not find data bulk out\n",
			sc->sc_dev.dv_xname);
		sc->sc_dying = 1;
		return;
	}

	if (sc->sc_intr_number== -1) {
		printf("%s: Could not find interrupt in\n",
			sc->sc_dev.dv_xname);
		sc->sc_dying = 1;
		return;
	}

	sc->sc_dtr = sc->sc_rts = 0;
	uca.portno = UCOM_UNK_PORTNO;
	/* bulkin, bulkout set above */
	uca.ibufsize = UMCTIBUFSIZE;
	if (sc->sc_product == USB_PRODUCT_MCT_SITECOM_USB232)
		uca.obufsize = 16; /* device is broken */
	else
		uca.obufsize = UMCTOBUFSIZE;
	uca.ibufsizepad = UMCTIBUFSIZE;
	uca.opkthdrlen = 0;
	uca.device = dev;
	uca.iface = sc->sc_iface;
	uca.methods = &umct_methods;
	uca.arg = sc;
	uca.info = NULL;

	umct_init(sc);

	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
			   &sc->sc_dev);

	DPRINTF(("umct: in=0x%x out=0x%x intr=0x%x\n",
			uca.bulkin, uca.bulkout, sc->sc_intr_number ));
	sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch);
}
Exemple #24
0
void
uvscom_attach(struct device *parent, struct device *self, void *aux)
{
	struct uvscom_softc *sc = (struct uvscom_softc *)self;
	struct usb_attach_arg *uaa = aux;
	usbd_device_handle dev = uaa->device;
	usb_config_descriptor_t *cdesc;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;
	const char *devname = sc->sc_dev.dv_xname;
	usbd_status err;
	int i;
	struct ucom_attach_args uca;

        sc->sc_udev = dev;

	DPRINTF(("uvscom attach: sc = %p\n", sc));

	/* initialize endpoints */
	uca.bulkin = uca.bulkout = -1;
	sc->sc_intr_number = -1;
	sc->sc_intr_pipe = NULL;

	/* Move the device into the configured state. */
	err = usbd_set_config_index(dev, UVSCOM_CONFIG_INDEX, 1);
	if (err) {
		printf("%s: failed to set configuration, err=%s\n",
			devname, usbd_errstr(err));
		sc->sc_dying = 1;
		return;
	}

	/* get the config descriptor */
	cdesc = usbd_get_config_descriptor(sc->sc_udev);

	if (cdesc == NULL) {
		printf("%s: failed to get configuration descriptor\n",
			sc->sc_dev.dv_xname);
		sc->sc_dying = 1;
		return;
	}

	/* get the common interface */
	err = usbd_device2interface_handle(dev, UVSCOM_IFACE_INDEX,
					   &sc->sc_iface);
	if (err) {
		printf("%s: failed to get interface, err=%s\n",
			devname, usbd_errstr(err));
		sc->sc_dying = 1;
		return;
	}

	id = usbd_get_interface_descriptor(sc->sc_iface);
	sc->sc_iface_number = id->bInterfaceNumber;

	/* Find endpoints */
	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
		if (ed == NULL) {
			printf("%s: no endpoint descriptor for %d\n",
				sc->sc_dev.dv_xname, i);
			sc->sc_dying = 1;
			return;
		}

		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			uca.bulkin = ed->bEndpointAddress;
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
			   UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			uca.bulkout = ed->bEndpointAddress;
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
			   UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
			sc->sc_intr_number = ed->bEndpointAddress;
			sc->sc_isize = UGETW(ed->wMaxPacketSize);
		}
	}

	if (uca.bulkin == -1) {
		printf("%s: Could not find data bulk in\n",
			sc->sc_dev.dv_xname);
		sc->sc_dying = 1;
		return;
	}
	if (uca.bulkout == -1) {
		printf("%s: Could not find data bulk out\n",
			sc->sc_dev.dv_xname);
		sc->sc_dying = 1;
		return;
	}
	if (sc->sc_intr_number == -1) {
		printf("%s: Could not find interrupt in\n",
			sc->sc_dev.dv_xname);
		sc->sc_dying = 1;
		return;
	}

	sc->sc_dtr = sc->sc_rts = 0;
	sc->sc_lcr = UVSCOM_LINE_INIT;

	uca.portno = UCOM_UNK_PORTNO;
	/* bulkin, bulkout set above */
	uca.ibufsize = UVSCOMIBUFSIZE;
	uca.obufsize = UVSCOMOBUFSIZE;
	uca.ibufsizepad = UVSCOMIBUFSIZE;
	uca.opkthdrlen = 0;
	uca.device = dev;
	uca.iface = sc->sc_iface;
	uca.methods = &uvscom_methods;
	uca.arg = sc;
	uca.info = NULL;

	err = uvscom_reset(sc);

	if (err) {
		printf("%s: reset failed, %s\n", sc->sc_dev.dv_xname,
			usbd_errstr(err));
		sc->sc_dying = 1;
		return;
	}

	DPRINTF(("uvscom: in = 0x%x out = 0x%x intr = 0x%x\n",
		 ucom->sc_bulkin_no, ucom->sc_bulkout_no, sc->sc_intr_number));

	DPRINTF(("uplcom: in=0x%x out=0x%x intr=0x%x\n",
			uca.bulkin, uca.bulkout, sc->sc_intr_number ));
	sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch);
}
Exemple #25
0
void
uftdi_attach(struct device *parent, struct device *self, void *aux)
{
	struct uftdi_softc *sc = (struct uftdi_softc *)self;
	struct usb_attach_arg *uaa = aux;
	struct usbd_device *dev = uaa->device;
	struct usbd_interface *iface;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;
	char *devname = sc->sc_dev.dv_xname;
	int i;
	usbd_status err;
	struct ucom_attach_args uca;

	DPRINTFN(10,("\nuftdi_attach: sc=%p\n", sc));

	sc->sc_udev = dev;

	if (uaa->iface == NULL) {
		/* Move the device into the configured state. */
		err = usbd_set_config_index(dev, UFTDI_CONFIG_INDEX, 1);
		if (err) {
			printf("%s: failed to set configuration, err=%s\n",
			    sc->sc_dev.dv_xname, usbd_errstr(err));
			goto bad;
		}

		err = usbd_device2interface_handle(dev, UFTDI_IFACE_INDEX, &iface);
		if (err) {
			printf("%s: failed to get interface, err=%s\n",
			    sc->sc_dev.dv_xname, usbd_errstr(err));
			goto bad;
		}
	} else
		iface = uaa->iface;

	id = usbd_get_interface_descriptor(iface);

	sc->sc_iface = iface;

	if (uaa->release < 0x0200) {
		sc->sc_type = UFTDI_TYPE_SIO;
		sc->sc_hdrlen = 1;
	} else if (uaa->release == 0x0700  || uaa->release == 0x0800) {
		sc->sc_type = UFTDI_TYPE_2232H;
		sc->sc_hdrlen = 0;
	} else {
		sc->sc_type = UFTDI_TYPE_8U232AM;
		sc->sc_hdrlen = 0;
	}

	uca.bulkin = uca.bulkout = -1;
	for (i = 0; i < id->bNumEndpoints; i++) {
		int addr, dir, attr;
		ed = usbd_interface2endpoint_descriptor(iface, i);
		if (ed == NULL) {
			printf("%s: could not read endpoint descriptor\n",
			    devname);
			goto bad;
		}

		addr = ed->bEndpointAddress;
		dir = UE_GET_DIR(ed->bEndpointAddress);
		attr = ed->bmAttributes & UE_XFERTYPE;
		if (dir == UE_DIR_IN && attr == UE_BULK) {
			uca.bulkin = addr;
			uca.ibufsize = (UGETW(ed->wMaxPacketSize) > 0) ?
			    UGETW(ed->wMaxPacketSize) : UFTDIIBUFSIZE;
		} else if (dir == UE_DIR_OUT && attr == UE_BULK) {
			uca.bulkout = addr;
			uca.obufsize = (UGETW(ed->wMaxPacketSize) > 0) ?
			    UGETW(ed->wMaxPacketSize) : UFTDIOBUFSIZE;
			uca.obufsize-= sc->sc_hdrlen;
		} else {
			printf("%s: unexpected endpoint\n", devname);
			goto bad;
		}
	}
	if (uca.bulkin == -1) {
		printf("%s: Could not find data bulk in\n",
		       sc->sc_dev.dv_xname);
		goto bad;
	}
	if (uca.bulkout == -1) {
		printf("%s: Could not find data bulk out\n",
		       sc->sc_dev.dv_xname);
		goto bad;
	}

	if (uaa->iface == NULL)
		uca.portno = FTDI_PIT_SIOA;
	else
		uca.portno = FTDI_PIT_SIOA + id->bInterfaceNumber;
	/* bulkin, bulkout set above */
	uca.ibufsizepad = uca.ibufsize;
	uca.opkthdrlen = sc->sc_hdrlen;
	uca.device = dev;
	uca.iface = iface;
	uca.methods = &uftdi_methods;
	uca.arg = sc;
	uca.info = NULL;

	DPRINTF(("uftdi: in=0x%x out=0x%x\n", uca.bulkin, uca.bulkout));
	sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch);

	return;

bad:
	DPRINTF(("uftdi_attach: ATTACH ERROR\n"));
	usbd_deactivate(sc->sc_udev);
}
Exemple #26
0
/*
 ****************************************************************
 *	Função de "attach"					*
 ****************************************************************
 */
int
uhub_attach (struct device *dev)
{
        struct uhub_softc		*sc;
        struct usb_attach_arg		*uaa  = dev->ivars;
	struct usbd_device		*udev = uaa->device;
	struct usbd_hub			*hub  = NULL;
	struct usb_device_request	req;
	struct usb_hub_descriptor	*hubdesc = NULL;
	struct usbd_interface		*iface;
	struct usb_endpoint_descriptor	*ed;
	int				p, port, nports, nremov, pwrdly, err;

	/*
	 *	Aloca e zera a estrutura "softc"
	 */
	if ((sc = dev->softc = malloc_byte (sizeof (struct uhub_softc))) == NULL)
		return (-1);

	memclr (sc, sizeof (struct uhub_softc));

#if (0)	/*******************************************************/
{
	char				*devinfo;

	if ((devinfo = malloc_byte (1024)) == NULL)
		goto bad;

	memclr (devinfo, 1024);

	usbd_devinfo (udev, USBD_SHOW_INTERFACE_CLASS, devinfo);

	device_set_desc_copy (dev, devinfo);

	free_byte (devinfo);
}
#endif	/*******************************************************/

	sc->sc_hub = udev;
	sc->sc_dev = dev;

	if (err = usbd_set_config_index (udev, 0, 1))
	{
		printf ("uhub_attach (%s): erro na configuração (%s)\n", dev->nameunit, usbd_errstr (err));
		goto bad;
	}

	if (udev->depth > USB_HUB_MAX_DEPTH)
	{
		printf
		(	"uhub_attach (%s): profundidade máxima excedida (%d > %d), \"hub\" ignorado\n",
			dev->nameunit, udev->depth, USB_HUB_MAX_DEPTH
		);
		goto bad;
	}

	/* Get hub descriptor */

	if ((hubdesc = malloc_byte (sizeof (struct usb_hub_descriptor))) == NULL)
		{ err = USBD_NOMEM; goto bad; }

	req.bmRequestType	= UT_READ_CLASS_DEVICE;
	req.bRequest		= UR_GET_DESCRIPTOR;

	USETW2 (req.wValue, (udev->address > 1 ? UDESC_HUB : 0), 0);
	USETW  (req.wIndex, 0);
	USETW  (req.wLength, USB_HUB_DESCRIPTOR_SIZE);

	err = usbd_do_request (udev, &req, hubdesc);

	nports = hubdesc->bNbrPorts;

	if (err == 0 && nports > 7)
	{
		USETW (req.wLength, USB_HUB_DESCRIPTOR_SIZE + (nports + 1) / 8);

		err = usbd_do_request (udev, &req, hubdesc);
	}

	if (err)
	{
		printf
		(	"uhub_attach (%s): erro ao ler descritor do hub (%s)\n",
			dev->nameunit, usbd_errstr (err)
		);

		goto bad;
	}

	for (nremov = 0, port = 1; port <= nports; port++)
	{
		if (!UHD_NOT_REMOV (hubdesc, port))
			nremov++;
	}

	if (nports == 0)
		{ printf ("%s: hub sem portas ignorado\n", dev->nameunit); goto bad; }

	printf
	(	"%s: %d porta%s, %d removíve%s, %s energizadas\n",
		dev->nameunit,
		nports, nports != 1 ? "s" : "",
		nremov, nremov != 1 ? "is" : "l",
		udev->self_powered ? "auto" : "bus"
	);

	if ((hub = malloc_byte (sizeof (*hub) + (nports - 1) * sizeof (struct usbd_port))) == NULL)
		goto bad;

	memclr (hub, (sizeof (*hub) + (nports - 1) * sizeof (struct usbd_port)));

	udev->hub		= hub;
	udev->hub->hubsoftc	= sc;
	hub->explore		= uhub_explore;
	hub->hubdesc		= *hubdesc;

	free_byte (hubdesc); hubdesc = NULL;

#ifdef	USB_MSG
	printf
	(	"uhub_attach: selfpowered=%d, parent=%p, parent->selfpowered=%d\n",
		 dev->self_powered, dev->powersrc->parent,
		 dev->powersrc->parent ? dev->powersrc->parent->self_powered : 0
	);
#endif	USB_MSG

	if (!udev->self_powered && udev->powersrc->parent != NULL && !udev->powersrc->parent->self_powered)
	{
		printf
		(	"uhub_attach (%s): bus powered hub connected to bus powered hub, ignored\n",
			dev->nameunit
		);
		goto bad;
	}

	/* Set up interrupt pipe */

	if (usbd_device2interface_handle (udev, 0, &iface))
	{
		printf ("uhub_attach (%s): no interface handle\n", dev->nameunit);
		goto bad;
	}

	if ((ed = usbd_interface2endpoint_descriptor (iface, 0)) == NULL)
	{
		printf ("uhub_attach (%s): no endpoint descriptor\n", dev->nameunit);
		goto bad;
	}

	if ((ed->bmAttributes & UE_XFERTYPE) != UE_INTERRUPT)
	{
		printf ("uhub_attach (%s): bad interrupt endpoint\n", dev->nameunit);
		goto bad;
	}

	if
	(	usbd_open_pipe_intr
		(	iface, ed->bEndpointAddress,
			USBD_SHORT_XFER_OK, &sc->sc_ipipe, sc, sc->sc_status, 
			sizeof (sc->sc_status), uhub_intr, UHUB_INTR_INTERVAL
		)
	)
	{
		printf ("uhub_attach (%s): cannot open interrupt pipe\n", dev->nameunit);
		goto bad;
	}

	/* Wait with power off for a while */

	usbd_delay_ms (udev, USB_POWER_DOWN_TIME);

	/*
	 * To have the best chance of success we do things in the exact same
	 * order as Windoze98.  This should not be necessary, but some
	 * devices do not follow the USB specs to the letter.
	 *
	 * These are the events on the bus when a hub is attached:
	 *  Get device and config descriptors (see attach code)
	 *  Get hub descriptor (see above)
	 *  For all ports
	 *     turn on power
	 *     wait for power to become stable
	 * (all below happens in explore code)
	 *  For all ports
	 *     clear C_PORT_CONNECTION
	 *  For all ports
	 *     get port status
	 *     if device connected
	 *        wait 100 ms
	 *        turn on reset
	 *        wait
	 *        clear C_PORT_RESET
	 *        get port status
	 *        proceed with device attachment
	 */

	/* Set up data structures */

	for (p = 0; p < nports; p++)
	{
		struct usbd_port	*up = &hub->ports[p];

		up->device = NULL;
		up->parent = udev;
		up->portno = p+1;

		if (udev->self_powered) /* Self powered hub, give ports maximum current */
			up->power = USB_MAX_POWER;
		else
			up->power = USB_MIN_POWER;

		up->restartcnt = 0;
	}

	/* XXX should check for none, individual, or ganged power? */

	pwrdly = udev->hub->hubdesc.bPwrOn2PwrGood * UHD_PWRON_FACTOR + USB_EXTRA_POWER_UP_TIME;

	for (port = 1; port <= nports; port++)
	{
		/* Turn the power on */

		if (err = usbd_set_port_feature (udev, port, UHF_PORT_POWER))
		{
			printf
			(	"uhub_attach (%s): port %d power on failed, %s\n", 
				dev->nameunit, port, usbd_errstr (err)
			);
		}

#ifdef	USB_MSG
		printf ("uhub_attach: turn on port %d power\n", port);
#endif	USB_MSG

		/* Wait for stable power */

		usbd_delay_ms (udev, pwrdly);
	}

	/* The usual exploration will finish the setup */

	sc->sc_running = 1;

	return (0);

	/*
	 *	Em caso de erro, ...
	 */
    bad:
	if (hubdesc != NULL)
		free_byte (hubdesc);

	if (hub != NULL)
		free_byte (hub);

	udev->hub = NULL;

	free_byte (sc);	dev->softc = NULL;

	return (-1);

}	/* end uhub_attach */
Exemple #27
0
static int
ubsa_attach(device_t self)
{
	struct ubsa_softc *sc = device_get_softc(self);
	struct usb_attach_arg *uaa = device_get_ivars(self);
	usbd_device_handle dev;
	struct ucom_softc *ucom;
	usb_config_descriptor_t *cdesc;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;
	usbd_status err;
	int i;

	dev = uaa->device;
	ucom = &sc->sc_ucom;
	bzero(sc, sizeof (struct ubsa_softc));

	/*
	 * initialize rts, dtr variables to something
	 * different from boolean 0, 1
	 */
	sc->sc_dtr = -1;
	sc->sc_rts = -1;

	ucom->sc_dev = self;
	ucom->sc_udev = dev;
	ucom->sc_iface = uaa->iface;

	DPRINTF(("ubsa attach: sc = %p\n", sc));

	/* initialize endpoints */
	ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
	sc->sc_intr_number = -1;
	sc->sc_intr_pipe = NULL;

	/* Move the device into the configured state. */
	err = usbd_set_config_index(dev, UBSA_CONFIG_INDEX, 1);
	if (err) {
		device_printf(ucom->sc_dev, "failed to set configuration: %s\n",
			      usbd_errstr(err));
		ucom->sc_dying = 1;
		goto error;
	}

	/* get the config descriptor */
	cdesc = usbd_get_config_descriptor(ucom->sc_udev);

	if (cdesc == NULL) {
		device_printf(ucom->sc_dev, "failed to get configuration "
			      "descriptor\n");
		ucom->sc_dying = 1;
		goto error;
	}

	/* get the first interface */
	err = usbd_device2interface_handle(dev, UBSA_IFACE_INDEX,
	    &ucom->sc_iface);
	if (err) {
		device_printf(ucom->sc_dev, "failed to get interface: %s\n",
			      usbd_errstr(err));
		ucom->sc_dying = 1;
		goto error;
	}

	/* Find the endpoints */

	id = usbd_get_interface_descriptor(ucom->sc_iface);
	sc->sc_iface_number = id->bInterfaceNumber;

	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i);
		if (ed == NULL) {
			device_printf(ucom->sc_dev, "no endpoint descriptor "
				      "for %d\n", i);
			ucom->sc_dying = 1;
			goto error;
		}

		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
			sc->sc_intr_number = ed->bEndpointAddress;
			sc->sc_isize = UGETW(ed->wMaxPacketSize);
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			ucom->sc_bulkin_no = ed->bEndpointAddress;
			ucom->sc_ibufsize = UGETW(ed->wMaxPacketSize);
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			ucom->sc_bulkout_no = ed->bEndpointAddress;
			ucom->sc_obufsize = UGETW(ed->wMaxPacketSize);
		}
	}

	if (sc->sc_intr_number == -1) {
		device_printf(ucom->sc_dev, "could not find interrupt in\n");
		ucom->sc_dying = 1;
		goto error;
	}

	/* keep interface for interrupt */
	sc->sc_intr_iface = ucom->sc_iface;

	if (ucom->sc_bulkin_no == -1) {
		device_printf(ucom->sc_dev, "could not find data bulk in\n");
		ucom->sc_dying = 1;
		goto error;
	}

	if (ucom->sc_bulkout_no == -1) {
		device_printf(ucom->sc_dev, "could not find data bulk out\n");
		ucom->sc_dying = 1;
		goto error;
	}

	ucom->sc_parent = sc;
	ucom->sc_portno = UCOM_UNK_PORTNO;
	/* bulkin, bulkout set above */
	ucom->sc_ibufsizepad = ucom->sc_ibufsize;
	ucom->sc_opkthdrlen = 0;
	ucom->sc_callback = &ubsa_callback;

	DPRINTF(("ubsa: in = 0x%x, out = 0x%x, intr = 0x%x\n",
	    ucom->sc_bulkin_no, ucom->sc_bulkout_no, sc->sc_intr_number));

	ucom_attach(ucom);

	return 0;

error:
	return ENXIO;
}
Exemple #28
0
void
uslcom_attach(struct device *parent, struct device *self, void *aux)
{
	struct uslcom_softc *sc = (struct uslcom_softc *)self;
	struct usb_attach_arg *uaa = aux;
	struct ucom_attach_args uca;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;
	usbd_status error;
	int i;

	bzero(&uca, sizeof(uca));
	sc->sc_udev = uaa->device;

	if (usbd_set_config_index(sc->sc_udev, USLCOM_CONFIG_NO, 1) != 0) {
		printf("%s: could not set configuration no\n",
		    sc->sc_dev.dv_xname);
		sc->sc_dying = 1;
		return;
	}

	/* get the first interface handle */
	error = usbd_device2interface_handle(sc->sc_udev, USLCOM_IFACE_NO,
	    &sc->sc_iface);
	if (error != 0) {
		printf("%s: could not get interface handle\n",
		    sc->sc_dev.dv_xname);
		sc->sc_dying = 1;
		return;
	}

	id = usbd_get_interface_descriptor(sc->sc_iface);

	uca.bulkin = uca.bulkout = -1;
	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
		if (ed == NULL) {
			printf("%s: no endpoint descriptor found for %d\n",
			    sc->sc_dev.dv_xname, i);
			sc->sc_dying = 1;
			return;
		}

		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
			uca.bulkin = ed->bEndpointAddress;
		else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
			uca.bulkout = ed->bEndpointAddress;
	}

	if (uca.bulkin == -1 || uca.bulkout == -1) {
		printf("%s: missing endpoint\n", sc->sc_dev.dv_xname);
		sc->sc_dying = 1;
		return;
	}

	uca.ibufsize = USLCOMBUFSZ;
	uca.obufsize = USLCOMBUFSZ;
	uca.ibufsizepad = USLCOMBUFSZ;
	uca.opkthdrlen = 0;
	uca.device = sc->sc_udev;
	uca.iface = sc->sc_iface;
	uca.methods = &uslcom_methods;
	uca.arg = sc;
	uca.info = NULL;

	sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch);
}
Exemple #29
0
void 
ubsa_attach(device_t parent, device_t self, void *aux)
{
	struct ubsa_softc *sc = device_private(self);
	struct usb_attach_arg *uaa = aux;
	usbd_device_handle dev = uaa->device;
	usb_config_descriptor_t *cdesc;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;
	char *devinfop;
	usbd_status err;
	struct ucom_attach_args uca;
	int i;

	sc->sc_dev = self;

	aprint_naive("\n");
	aprint_normal("\n");

	devinfop = usbd_devinfo_alloc(dev, 0);
	aprint_normal_dev(self, "%s\n", devinfop);
	usbd_devinfo_free(devinfop);

        sc->sc_udev = dev;
	sc->sc_config_index = UBSA_DEFAULT_CONFIG_INDEX;
	sc->sc_numif = 1; /* default device has one interface */

	/*
	 * initialize rts, dtr variables to something
	 * different from boolean 0, 1
	 */
	sc->sc_dtr = -1;
	sc->sc_rts = -1;

	/*
	 * Quad UMTS cards use different requests to
	 * control com settings and only some.
	 */
	sc->sc_quadumts = 0;
	if (uaa->vendor == USB_VENDOR_OPTIONNV) {
		switch (uaa->product) {
		case USB_PRODUCT_OPTIONNV_QUADUMTS:
		case USB_PRODUCT_OPTIONNV_QUADUMTS2:
			sc->sc_quadumts = 1;
			break;
		}
	}

	DPRINTF(("ubsa attach: sc = %p\n", sc));

	/* Move the device into the configured state. */
	err = usbd_set_config_index(dev, sc->sc_config_index, 1);
	if (err) {
		aprint_error_dev(self,
		    "failed to set configuration: %s\n",
		    usbd_errstr(err));
		sc->sc_dying = 1;
		goto error;
	}

	/* get the config descriptor */
	cdesc = usbd_get_config_descriptor(sc->sc_udev);

	if (cdesc == NULL) {
		aprint_error_dev(self,
		    "failed to get configuration descriptor\n");
		sc->sc_dying = 1;
		goto error;
	}

	sc->sc_intr_number = -1;
	sc->sc_intr_pipe = NULL;

	/* get the interfaces */
	err = usbd_device2interface_handle(dev, UBSA_IFACE_INDEX_OFFSET,
			 &sc->sc_iface[0]);
	if (err) {
		/* can not get main interface */
		sc->sc_dying = 1;
		goto error;
	}

	/* Find the endpoints */
	id = usbd_get_interface_descriptor(sc->sc_iface[0]);
	sc->sc_iface_number[0] = id->bInterfaceNumber;

	/* initialize endpoints */
	uca.bulkin = uca.bulkout = -1;

	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(sc->sc_iface[0], i);
		if (ed == NULL) {
			aprint_error_dev(self,
			     "no endpoint descriptor for %d\n", i);
			break;
		}

		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
			sc->sc_intr_number = ed->bEndpointAddress;
			sc->sc_isize = UGETW(ed->wMaxPacketSize);
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			uca.bulkin = ed->bEndpointAddress;
			uca.ibufsize = UGETW(ed->wMaxPacketSize);
		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
			uca.bulkout = ed->bEndpointAddress;
			uca.obufsize = UGETW(ed->wMaxPacketSize);
		}
	} /* end of Endpoint loop */

	if (sc->sc_intr_number == -1) {
		aprint_error_dev(self, "Could not find interrupt in\n");
		sc->sc_dying = 1;
		goto error;
	}

	if (uca.bulkin == -1) {
		aprint_error_dev(self, "Could not find data bulk in\n");
		sc->sc_dying = 1;
		goto error;
	}

	if (uca.bulkout == -1) {
		aprint_error_dev(self, "Could not find data bulk out\n");
		sc->sc_dying = 1;
		goto error;
	}

	uca.portno = 0;
	/* bulkin, bulkout set above */
	uca.ibufsizepad = uca.ibufsize;
	uca.opkthdrlen = 0;
	uca.device = dev;
	uca.iface = sc->sc_iface[0];
	uca.methods = &ubsa_methods;
	uca.arg = sc;
	uca.info = NULL;
	DPRINTF(("ubsa: int#=%d, in = 0x%x, out = 0x%x, intr = 0x%x\n",
    		i, uca.bulkin, uca.bulkout, sc->sc_intr_number));
	sc->sc_subdevs[0] = config_found_sm_loc(self, "ucombus", NULL, &uca,
				    ucomprint, ucomsubmatch);

	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
			   sc->sc_dev);

	return;

error:
	return;
}
Exemple #30
0
static int
ubt_attach(device_t self)
{
	struct ubt_softc *sc = device_get_softc(self);
	struct usb_attach_arg *uaa = device_get_ivars(self);

	usb_config_descriptor_t *cd;
	usb_endpoint_descriptor_t *ed;
	int err;
	uint8_t count, i;

	DPRINTFN(50, "ubt_attach: sc=%p\n", sc);

	sc->sc_udev = uaa->device;
	sc->sc_dev = self;

	/*
	 * Move the device into the configured state
	 */
	err = usbd_set_config_index(sc->sc_udev, 0, 1);
	if (err) {
		kprintf("%s: failed to set configuration idx 0: %s\n",
		    device_get_nameunit(sc->sc_dev), usbd_errstr(err));

		return ENXIO;
	}

	/*
	 * Interface 0 must have 3 endpoints
	 *	1) Interrupt endpoint to receive HCI events
	 *	2) Bulk IN endpoint to receive ACL data
	 *	3) Bulk OUT endpoint to send ACL data
	 */
	err = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface0);
	if (err) {
		kprintf("%s: Could not get interface 0 handle %s (%d)\n",
				device_get_nameunit(sc->sc_dev), usbd_errstr(err), err);

		return ENXIO;
	}

	sc->sc_evt_addr = -1;
	sc->sc_aclrd_addr = -1;
	sc->sc_aclwr_addr = -1;

	count = 0;
	(void)usbd_endpoint_count(sc->sc_iface0, &count);

	for (i = 0 ; i < count ; i++) {
		int dir, type;

		ed = usbd_interface2endpoint_descriptor(sc->sc_iface0, i);
		if (ed == NULL) {
			kprintf("%s: could not read endpoint descriptor %d\n",
			    device_get_nameunit(sc->sc_dev), i);

			return ENXIO;
		}

		dir = UE_GET_DIR(ed->bEndpointAddress);
		type = UE_GET_XFERTYPE(ed->bmAttributes);

		if (dir == UE_DIR_IN && type == UE_INTERRUPT)
			sc->sc_evt_addr = ed->bEndpointAddress;
		else if (dir == UE_DIR_IN && type == UE_BULK)
			sc->sc_aclrd_addr = ed->bEndpointAddress;
		else if (dir == UE_DIR_OUT && type == UE_BULK)
			sc->sc_aclwr_addr = ed->bEndpointAddress;
	}

	if (sc->sc_evt_addr == -1) {
		kprintf("%s: missing INTERRUPT endpoint on interface 0\n",
				device_get_nameunit(sc->sc_dev));

		return ENXIO;
	}
	if (sc->sc_aclrd_addr == -1) {
		kprintf("%s: missing BULK IN endpoint on interface 0\n",
				device_get_nameunit(sc->sc_dev));

		return ENXIO;
	}
	if (sc->sc_aclwr_addr == -1) {
		kprintf("%s: missing BULK OUT endpoint on interface 0\n",
				device_get_nameunit(sc->sc_dev));

		return ENXIO;
	}

	/*
	 * Interface 1 must have 2 endpoints
	 *	1) Isochronous IN endpoint to receive SCO data
	 *	2) Isochronous OUT endpoint to send SCO data
	 *
	 * and will have several configurations, which can be selected
	 * via a sysctl variable. We select config 0 to start, which
	 * means that no SCO data will be available.
	 */
	err = usbd_device2interface_handle(sc->sc_udev, 1, &sc->sc_iface1);
	if (err) {
		kprintf("%s: Could not get interface 1 handle %s (%d)\n",
		    device_get_nameunit(sc->sc_dev), usbd_errstr(err), err);

		return ENXIO;
	}

	cd = usbd_get_config_descriptor(sc->sc_udev);
	if (cd == NULL) {
		kprintf("%s: could not get config descriptor\n",
			device_get_nameunit(sc->sc_dev));

		return ENXIO;
	}

	sc->sc_alt_config = usbd_get_no_alts(cd, 1);

	/* set initial config */
	err = ubt_set_isoc_config(sc);
	if (err) {
		kprintf("%s: ISOC config failed\n",
			device_get_nameunit(sc->sc_dev));

		return ENXIO;
	}

	/* Attach HCI */
	sc->sc_unit = hci_attach(&ubt_hci, sc->sc_dev, 0);

	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
			   sc->sc_dev);

	sc->sc_ok = 1;

	sysctl_ctx_init(&sc->sysctl_ctx);
	sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx,
					  SYSCTL_STATIC_CHILDREN(_hw),
					  OID_AUTO,
					  device_get_nameunit(sc->sc_dev),
					  CTLFLAG_RD, 0, "");

	if (sc->sysctl_tree == NULL) {
		/* Failure isn't fatal */
		device_printf(sc->sc_dev, "Unable to create sysctl tree\n");
		return 0;
	}

	SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
			OID_AUTO, "config", CTLTYPE_INT|CTLFLAG_RW, (void *)sc,
			0, ubt_sysctl_config, "I", "Configuration number");
	SYSCTL_ADD_INT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
		       OID_AUTO, "alt_config", CTLFLAG_RD, &sc->sc_alt_config,
		       0, "Number of alternate configurations");
	SYSCTL_ADD_INT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
		       OID_AUTO, "sco_rxsize", CTLFLAG_RD, &sc->sc_scord_size,
		       0, "Max SCO receive size");
	SYSCTL_ADD_INT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
		       OID_AUTO, "sco_wrsize", CTLFLAG_RD, &sc->sc_scowr_size,
		       0, "Max SCO transmit size");

	return 0;
}