Пример #1
0
static int
ukbd_enable_intr(keyboard_t *kbd, int on, usbd_intr_t *func)
{
	ukbd_state_t *state = (ukbd_state_t *)kbd->kb_data;
	usbd_status err;

	if (on) {
		/* Set up interrupt pipe. */
		if (state->ks_ifstate & INTRENABLED) {
			return EBUSY;
		}

		state->ks_ifstate |= INTRENABLED;
		err = usbd_open_pipe_intr(state->ks_iface, state->ks_ep_addr,
					USBD_SHORT_XFER_OK | USBD_CALLBACK_LAST,
					&state->ks_intrpipe, kbd,
					&state->ks_ndata,
					sizeof(state->ks_ndata), func,
					USBD_DEFAULT_INTERVAL);
		if (err) {
			return (EIO);
		}
	} else {
		/* Disable interrupts. */
		usbd_abort_pipe(state->ks_intrpipe);
		usbd_close_pipe(state->ks_intrpipe);

		state->ks_ifstate &= ~INTRENABLED;
	}

	return (0);
}
Пример #2
0
Файл: ums.c Проект: MarginC/kame
Static int
ums_enable(void *v)
{
	struct ums_softc *sc = v;

	usbd_status err;

	DPRINTFN(1,("ums_enable: sc=%p\n", sc));

	if (sc->sc_dying)
		return (EIO);

	if (sc->sc_enabled)
		return (EBUSY);

	sc->sc_enabled = 1;
	sc->sc_buttons = 0;

	/* Set up interrupt pipe. */
	err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr, 
		  USBD_SHORT_XFER_OK, &sc->sc_intrpipe, sc, 
		  sc->sc_ibuf, sc->sc_isize, ums_intr, USBD_DEFAULT_INTERVAL);
	if (err) {
		DPRINTF(("ums_enable: usbd_open_pipe_intr failed, error=%d\n",
			 err));
		sc->sc_enabled = 0;
		return (EIO);
	}
	return (0);
}
Пример #3
0
int
uts_enable(void *v)
{
    struct uts_softc *sc = v;
    int err;

    if (sc->sc_dying)
        return (EIO);

    if (sc->sc_enabled)
        return (EBUSY);

    if (sc->sc_isize == 0)
        return (0);
    sc->sc_ibuf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
    err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_intr_number,
                              USBD_SHORT_XFER_OK, &sc->sc_intr_pipe, sc, sc->sc_ibuf,
                              sc->sc_isize, uts_intr, USBD_DEFAULT_INTERVAL);
    if (err) {
        free(sc->sc_ibuf, M_USBDEV);
        sc->sc_intr_pipe = NULL;
        return (EIO);
    }

    sc->sc_enabled = 1;
    sc->sc_buttons = 0;

    return (0);
}
Пример #4
0
int
umct_open(void *addr, int portno)
{
	struct umct_softc *sc = addr;
	int err, lcr_data;

	if (sc->sc_dying)
		return (EIO);

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

	/* initialize LCR */
        lcr_data = LCR_DATA_BITS_8 | LCR_PARITY_NONE |
	    LCR_STOP_BITS_1;
        umct_set_lcr(sc, lcr_data);

	if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
		sc->sc_status = 0; /* clear status bit */
		sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
		err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_intr_number,
			USBD_SHORT_XFER_OK, &sc->sc_intr_pipe, sc,
			sc->sc_intr_buf, sc->sc_isize,
			umct_intr, USBD_DEFAULT_INTERVAL);
		if (err) {
			DPRINTF(("%s: cannot open interrupt pipe (addr %d)\n",
				sc->sc_dev.dv_xname, sc->sc_intr_number));
					return (EIO);
		}
	}

	return (0);
}
Пример #5
0
int
uplcom_open(void *addr, int portno)
{
	struct uplcom_softc *sc = addr;
	usbd_status err;

	if (sc->sc_dying)
		return (EIO);

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

	/* Some unknown device frobbing. */
	if (sc->sc_type == UPLCOM_TYPE_HX)
		uplcom_vendor_control_write(sc->sc_udev, 2, 0x44);
	else
		uplcom_vendor_control_write(sc->sc_udev, 2, 0x24);
	
	if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
		sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
		err = usbd_open_pipe_intr(sc->sc_intr_iface, sc->sc_intr_number,
			USBD_SHORT_XFER_OK, &sc->sc_intr_pipe, sc,
			sc->sc_intr_buf, sc->sc_isize,
			uplcom_intr, USBD_DEFAULT_INTERVAL);
		if (err) {
			DPRINTF(("%s: cannot open interrupt pipe (addr %d)\n",
				USBDEVNAME(sc->sc_dev), sc->sc_intr_number));
					return (EIO);
		}
	}

	if (sc->sc_type == UPLCOM_TYPE_HX)
		return (uplcom_pl2303x_init(sc));

	return (0);
}
Пример #6
0
int
ubsa_open(void *addr, int portno)
{
	struct ubsa_softc *sc = addr;
	int err;

	if (sc->sc_dying)
		return (ENXIO);

	if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
		sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
		/* XXX only iface# = 0 has intr line */
		/* XXX E220 specific? need to check */
		err = usbd_open_pipe_intr(sc->sc_iface[0],
		    sc->sc_intr_number,
		    USBD_SHORT_XFER_OK,
		    &sc->sc_intr_pipe,
		    sc,
		    sc->sc_intr_buf,
		    sc->sc_isize,
		    ubsa_intr,
		    UBSA_INTR_INTERVAL);
		if (err) {
			printf("%s: cannot open interrupt pipe (addr %d)\n",
			    device_xname(sc->sc_dev),
			    sc->sc_intr_number);
			return (EIO);
		}
	}

	return (0);
}
Пример #7
0
Static int
umct_open(void *addr, int portno)
{
	struct umct_softc *sc;
	int err;

	sc = addr;
	if (sc->sc_ucom.sc_dying) {
		return (ENXIO);
	}

	if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
		sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
		err = usbd_open_pipe_intr(sc->sc_intr_iface, sc->sc_intr_number,
		    USBD_SHORT_XFER_OK, &sc->sc_intr_pipe, sc, sc->sc_intr_buf,
		    sc->sc_isize, umct_intr, UMCT_INTR_INTERVAL);
		if (err) {
			printf("%s: cannot open interrupt pipe (addr %d)\n",
			    USBDEVNAME(sc->sc_ucom.sc_dev),
			    sc->sc_intr_number);
			free(sc->sc_intr_buf, M_USBDEV);
			return (EIO);
		}
	}

	return (0);
}
static int
xboxcontroller_wsmouse_enable(void *opaque)
{
	struct xboxcontroller_softc *sc;
	usbd_status err;

	sc = (struct xboxcontroller_softc *)opaque;

	if (sc->sc_dying)
		return EIO;
	if (sc->sc_enabled)
		return EBUSY;

	sc->sc_buf = malloc(XBOX_CONTROLLER_BUFSZ, M_USBDEV, M_WAITOK);
	err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ed,
	    USBD_SHORT_XFER_OK, &sc->sc_ep, sc, sc->sc_buf,
	    XBOX_CONTROLLER_BUFSZ, xboxcontroller_intr,
	    USBD_DEFAULT_INTERVAL);
	if (err) {
		aprint_error_dev(sc->sc_dev, "open pipe failed: %s\n",
		    usbd_errstr(err));
		free(sc->sc_buf, M_USBDEV);
		sc->sc_buf = NULL;
		sc->sc_ep = NULL;
		return EIO;
	}

	sc->sc_enabled = 1;

	return 0;
}
Пример #9
0
int
umsm_open(void *addr, int portno)
{
	struct umsm_softc *sc = addr;
	int err;

	if (usbd_is_dying(sc->sc_udev))
		return (ENXIO);

	if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
		sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
		err = usbd_open_pipe_intr(sc->sc_iface,
		    sc->sc_intr_number,
		    USBD_SHORT_XFER_OK,
		    &sc->sc_intr_pipe,
		    sc,
		    sc->sc_intr_buf,
		    sc->sc_isize,
		    umsm_intr,
		    UMSM_INTR_INTERVAL);
		if (err) {
			printf("%s: cannot open interrupt pipe (addr %d)\n",
			    sc->sc_dev.dv_xname,
			    sc->sc_intr_number);
			return (EIO);
		}
	}

	return (0);
}
Пример #10
0
static int
uticom_open(void *addr, int portno)
{
	struct uticom_softc *sc = addr;
	usbd_status err;

	if (usbd_is_dying(sc->sc_udev))
		return (ENXIO);

	DPRINTF(("%s: uticom_open\n", sc->sc_dev.dv_xname));

	sc->sc_status = 0; /* clear status bit */

	if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
		sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
		err = usbd_open_pipe_intr(sc->sc_intr_iface, sc->sc_intr_number,
		    USBD_SHORT_XFER_OK, &sc->sc_intr_pipe, sc, sc->sc_intr_buf,
		    sc->sc_isize, uticom_intr, UTICOM_INTR_INTERVAL);
		if (err) {
			printf("%s: cannot open interrupt pipe (addr %d)\n",
			    sc->sc_dev.dv_xname, sc->sc_intr_number);
			return (EIO);
		}
	}

	DPRINTF(("%s: uticom_open: port opened\n", sc->sc_dev.dv_xname));
	return (0);
}
Пример #11
0
static int
ubsa_open(void *addr, int portno)
{
	struct ubsa_softc *sc;
	int err;

	sc = addr;
	if (sc->sc_ucom.sc_dying)
		return (ENXIO);

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

	if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
		sc->sc_intr_buf = kmalloc(sc->sc_isize, M_USBDEV, M_WAITOK);
		err = usbd_open_pipe_intr(sc->sc_intr_iface,
		    sc->sc_intr_number,
		    USBD_SHORT_XFER_OK,
		    &sc->sc_intr_pipe,
		    sc,
		    sc->sc_intr_buf,
		    sc->sc_isize,
		    ubsa_intr,
		    UBSA_INTR_INTERVAL);
		if (err) {
			device_printf(sc->sc_ucom.sc_dev, "cannot open "
				      "interrupt pipe (addr %d)\n",
				      sc->sc_intr_number);
			return (EIO);
		}
	}

	return (0);
}
Пример #12
0
int
uhidopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
{
	struct uhid_softc *sc;
	usbd_status err;

	USB_GET_SC_OPEN(uhid, UHIDUNIT(dev), sc);

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

	if (sc->sc_dying)
		return (ENXIO);

	if (sc->sc_state & UHID_OPEN)
		return (EBUSY);
	sc->sc_state |= UHID_OPEN;

	if (clalloc(&sc->sc_q, UHID_BSIZE, 0) == -1) {
		sc->sc_state &= ~UHID_OPEN;
		return (ENOMEM);
	}

	sc->sc_ibuf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
	sc->sc_obuf = malloc(sc->sc_osize, M_USBDEV, M_WAITOK);

	/* Set up interrupt pipe. */
	err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr, 
		  USBD_SHORT_XFER_OK, &sc->sc_intrpipe, sc, sc->sc_ibuf, 
		  sc->sc_isize, uhid_intr, USBD_DEFAULT_INTERVAL);
	if (err) {
		DPRINTF(("uhidopen: usbd_open_pipe_intr failed, "
			 "error=%d\n",err));
		free(sc->sc_ibuf, M_USBDEV);
		free(sc->sc_obuf, M_USBDEV);
		sc->sc_state &= ~UHID_OPEN;
		return (EIO);
	}

	sc->sc_state &= ~UHID_IMMED;

	sc->sc_async = 0;

	return (0);
}
Пример #13
0
int
ugl_openpipes(struct ugl_softc *sc)
{
	struct ugl_chain	*c;
	usbd_status		err;
	int			i;

	/* Open RX and TX pipes. */
	err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UGL_ENDPT_RX],
	    USBD_EXCLUSIVE_USE, &sc->sc_ep[UGL_ENDPT_RX]);
	if (err) {
		printf("%s: open rx pipe failed: %s\n",
		    sc->sc_dev.dv_xname, usbd_errstr(err));
		return (EIO);
	}
	err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UGL_ENDPT_TX],
	    USBD_EXCLUSIVE_USE, &sc->sc_ep[UGL_ENDPT_TX]);
	if (err) {
		printf("%s: open tx pipe failed: %s\n",
		    sc->sc_dev.dv_xname, usbd_errstr(err));
		return (EIO);
	}
	err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ed[UGL_ENDPT_INTR],
	    USBD_EXCLUSIVE_USE, &sc->sc_ep[UGL_ENDPT_INTR], sc,
	    sc->sc_ibuf, UGL_INTR_PKTLEN, ugl_intr,
	    UGL_INTR_INTERVAL);
	if (err) {
		printf("%s: open intr pipe failed: %s\n",
		    sc->sc_dev.dv_xname, usbd_errstr(err));
		return (EIO);
	}

	/* Start up the receive pipe. */
	for (i = 0; i < UGL_RX_LIST_CNT; i++) {
		c = &sc->sc_cdata.ugl_rx_chain[i];
		usbd_setup_xfer(c->ugl_xfer, sc->sc_ep[UGL_ENDPT_RX],
		    c, c->ugl_buf, UGL_BUFSZ,
		    USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT,
		    ugl_rxeof);
		usbd_transfer(c->ugl_xfer);
	}

	return (0);
}
Пример #14
0
static int
umodem_open(void *addr, int portno)
{
	struct umodem_softc *sc = addr;
	int err;

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

	if (sc->sc_ctl_notify != -1 && sc->sc_notify_pipe == NULL) {
		err = usbd_open_pipe_intr(sc->sc_ctl_iface, sc->sc_ctl_notify,
		    USBD_SHORT_XFER_OK, &sc->sc_notify_pipe, sc,
		    &sc->sc_notify_buf, sizeof(sc->sc_notify_buf),
		    umodem_intr, USBD_DEFAULT_INTERVAL);

		if (err) {
			DPRINTF(("Failed to establish notify pipe: %s\n",
				usbd_errstr(err)));
			return EIO;
		}
	}

	return 0;
}
Пример #15
0
int
uhidev_open(struct uhidev *scd)
{
	struct uhidev_softc *sc = scd->sc_parent;
	usbd_status err;

	DPRINTF(("uhidev_open: open pipe, state=%d refcnt=%d\n",
		 scd->sc_state, sc->sc_refcnt));

	if (scd->sc_state & UHIDEV_OPEN)
		return (EBUSY);
	scd->sc_state |= UHIDEV_OPEN;
	if (sc->sc_refcnt++)
		return (0);

	if (sc->sc_isize == 0)
		return (0);

	sc->sc_ibuf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);

	/* Set up interrupt pipe. */
	DPRINTF(("uhidev_open: isize=%d, ep=0x%02x\n", sc->sc_isize,
		 sc->sc_ep_addr));
	err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr, 
		  USBD_SHORT_XFER_OK, &sc->sc_intrpipe, sc, sc->sc_ibuf, 
		  sc->sc_isize, uhidev_intr, USBD_DEFAULT_INTERVAL);
	if (err) {
		DPRINTF(("uhidopen: usbd_open_pipe_intr failed, "
			 "error=%d\n",err));
		free(sc->sc_ibuf, M_USBDEV);
		scd->sc_state &= ~UHIDEV_OPEN;
		sc->sc_refcnt = 0;
		sc->sc_intrpipe = NULL;
		return (EIO);
	}
	return (0);
}
Пример #16
0
void
emdtv_ir_attach(struct emdtv_softc *sc)
{
	struct ir_attach_args ia;
	usb_endpoint_descriptor_t *ed;
	usbd_status status;
	int err;

	ed = usbd_interface2endpoint_descriptor(sc->sc_iface, 0);
	if (ed == NULL)
		return;

	status = usbd_open_pipe_intr(sc->sc_iface, ed->bEndpointAddress,
	    USBD_EXCLUSIVE_USE, &sc->sc_intr_pipe, sc, &sc->sc_intr_buf, 1,
	    emdtv_ir_intr, USBD_DEFAULT_INTERVAL);
	if (status != USBD_NORMAL_COMPLETION) {
		aprint_error_dev(sc->sc_dev, "couldn't open intr pipe: %s\n",
		    usbd_errstr(status));
		return;
	}

	mutex_init(&sc->sc_ir_mutex, MUTEX_DEFAULT, IPL_VM);

	err = workqueue_create(&sc->sc_ir_wq, "emdtvir",
	    emdtv_ir_worker, sc, PRI_NONE, IPL_VM, 0);
	if (err)
		aprint_error_dev(sc->sc_dev, "couldn't create workqueue: %d\n",
		    err);

	ia.ia_type = IR_TYPE_CIR;
	ia.ia_methods = &emdtv_ir_methods;
	ia.ia_handle = sc;

	sc->sc_cirdev =
	    config_found_ia(sc->sc_dev, "irbus", &ia, ir_print);
}
Пример #17
0
int
ukbd_enable(void *v, int on)
{
	struct ukbd_softc *sc = v;
	usbd_status err;

	if (on && sc->sc_dying)
		return (EIO);

	/* Should only be called to change state */
	if (sc->sc_enabled == on) {
#ifdef DIAGNOSTIC
		printf("ukbd_enable: %s: bad call on=%d\n", 
		       USBDEVNAME(sc->sc_dev), on);
#endif
		return (EBUSY);
	}

	DPRINTF(("ukbd_enable: sc=%p on=%d\n", sc, on));
	if (on) {
		/* Set up interrupt pipe. */
		err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr, 
			  USBD_SHORT_XFER_OK, &sc->sc_intrpipe, sc,
			  &sc->sc_ndata, sizeof(sc->sc_ndata), ukbd_intr,
			  USBD_DEFAULT_INTERVAL);
		if (err)
			return (EIO);
	} else {
		/* Disable interrupts. */
		usbd_abort_pipe(sc->sc_intrpipe);
		usbd_close_pipe(sc->sc_intrpipe);
	}
	sc->sc_enabled = on;

	return (0);
}
Пример #18
0
static int
uplcom_open(void *addr, int portno)
{
	struct uplcom_softc *sc = addr;
	int err;

	if (sc->sc_ucom.sc_dying)
		return (ENXIO);

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

	if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
		sc->sc_status = 0; /* clear status bit */
		sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
		err = usbd_open_pipe_intr(sc->sc_intr_iface,
					  sc->sc_intr_number,
					  USBD_SHORT_XFER_OK,
					  &sc->sc_intr_pipe,
					  sc,
					  sc->sc_intr_buf,
					  sc->sc_isize,
					  uplcom_intr,
					  uplcominterval);
		if (err) {
			printf("%s: cannot open interrupt pipe (addr %d)\n",
			       device_get_nameunit(sc->sc_ucom.sc_dev),
			       sc->sc_intr_number);
			return (EIO);
		}
	}

	if (sc->sc_chiptype == TYPE_PL2303X)
		return (uplcom_pl2303x_init(sc));

	return (0);
}
Пример #19
0
int
uplcom_open(void *addr, int portno)
{
	struct uplcom_softc *sc = addr;
	usb_device_request_t req;
	usbd_status uerr;
	int err;

	if (sc->sc_dying)
		return (EIO);

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

	if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
		sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
		err = usbd_open_pipe_intr(sc->sc_intr_iface, sc->sc_intr_number,
			USBD_SHORT_XFER_OK, &sc->sc_intr_pipe, sc,
			sc->sc_intr_buf, sc->sc_isize,
			uplcom_intr, USBD_DEFAULT_INTERVAL);
		if (err) {
			DPRINTF(("%s: cannot open interrupt pipe (addr %d)\n",
				USBDEVNAME(sc->sc_dev), sc->sc_intr_number));
					return (EIO);
		}
	}

	if (sc->sc_type_hx == 1) {
		/*
		 * Undocumented (vendor unresponsive) - possibly changes
		 * flow control semantics. It is needed for HX variant devices.
		 */
		req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
		req.bRequest = UPLCOM_SET_REQUEST;
		USETW(req.wValue, 2);
		USETW(req.wIndex, 0x44);
		USETW(req.wLength, 0);

		uerr = usbd_do_request(sc->sc_udev, &req, 0);
		if (uerr)
			return (EIO);

		/* Reset upstream data pipes */
		req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
		req.bRequest = UPLCOM_SET_REQUEST;
		USETW(req.wValue, 8);
		USETW(req.wIndex, 0);
		USETW(req.wLength, 0);

		uerr = usbd_do_request(sc->sc_udev, &req, 0);
		if (uerr)
			return (EIO);

		req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
		req.bRequest = UPLCOM_SET_REQUEST;
		USETW(req.wValue, 9);
		USETW(req.wIndex, 0);
		USETW(req.wLength, 0);

		uerr = usbd_do_request(sc->sc_udev, &req, 0);
		if (uerr)
			return (EIO);
	}

	return (0);
}
Пример #20
0
int
wi_usb_open_pipes(struct wi_usb_softc *sc)
{
	usbd_status		err;
	int			error = 0;
	struct wi_usb_chain	*c;
	int			i;

	DPRINTFN(10,("%s: %s: enter\n", sc->wi_usb_dev.dv_xname,__func__));

	sc->wi_usb_refcnt++;

	/* Open RX and TX pipes. */
	err = usbd_open_pipe(sc->wi_usb_iface, sc->wi_usb_ed[WI_USB_ENDPT_RX],
	    USBD_EXCLUSIVE_USE, &sc->wi_usb_ep[WI_USB_ENDPT_RX]);
	if (err) {
		printf("%s: open rx pipe failed: %s\n",
		    sc->wi_usb_dev.dv_xname, usbd_errstr(err));
		error = EIO;
		goto done;
	}

	err = usbd_open_pipe(sc->wi_usb_iface, sc->wi_usb_ed[WI_USB_ENDPT_TX],
	    USBD_EXCLUSIVE_USE, &sc->wi_usb_ep[WI_USB_ENDPT_TX]);
	if (err) {
		printf("%s: open tx pipe failed: %s\n",
		    sc->wi_usb_dev.dv_xname, usbd_errstr(err));
		error = EIO;
		goto done;
	}

	/* is this used? */
	err = usbd_open_pipe_intr(sc->wi_usb_iface,
	    sc->wi_usb_ed[WI_USB_ENDPT_INTR], USBD_EXCLUSIVE_USE,
	    &sc->wi_usb_ep[WI_USB_ENDPT_INTR], sc, &sc->wi_usb_ibuf,
	    WI_USB_INTR_PKTLEN, wi_usb_intr, WI_USB_INTR_INTERVAL);
	if (err) {
		printf("%s: open intr pipe failed: %s\n",
		    sc->wi_usb_dev.dv_xname, usbd_errstr(err));
		error = EIO;
		goto done;
	}

	/* Start up the receive pipe. */
	for (i = 0; i < WI_USB_RX_LIST_CNT; i++) {
		c = &sc->wi_usb_rx_chain[i];
		usbd_setup_xfer(c->wi_usb_xfer, sc->wi_usb_ep[WI_USB_ENDPT_RX],
		    c, c->wi_usb_buf, WI_USB_BUFSZ,
		    USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT,
		    wi_usb_rxeof);
		DPRINTFN(10,("%s: %s: start read\n", sc->wi_usb_dev.dv_xname,
			    __func__));
		usbd_transfer(c->wi_usb_xfer);
	}

done:
	if (--sc->wi_usb_refcnt < 0)
		usb_detach_wakeup(&sc->wi_usb_dev);

	return (error);
}
Пример #21
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;
}
Пример #22
0
int
ugenopen(dev_t dev, int flag, int mode, struct proc *p)
{
	struct ugen_softc *sc;
	int unit = UGENUNIT(dev);
	int endpt = UGENENDPOINT(dev);
	usb_endpoint_descriptor_t *edesc;
	struct ugen_endpoint *sce;
	int dir, isize;
	usbd_status err;
	struct usbd_xfer *xfer;
	void *buf;
	int i, j;

	if (unit >= ugen_cd.cd_ndevs)
		return (ENXIO);
	sc = ugen_cd.cd_devs[unit];
	if (sc == NULL)
		return (ENXIO);

	DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n",
		     flag, mode, unit, endpt));

	if (sc == NULL || usbd_is_dying(sc->sc_udev))
		return (ENXIO);

	if (sc->sc_is_open[endpt])
		return (EBUSY);

	if (endpt == USB_CONTROL_ENDPOINT) {
		sc->sc_is_open[USB_CONTROL_ENDPOINT] = 1;
		return (0);
	}

	/* Make sure there are pipes for all directions. */
	for (dir = OUT; dir <= IN; dir++) {
		if (flag & (dir == OUT ? FWRITE : FREAD)) {
			sce = &sc->sc_endpoints[endpt][dir];
			if (sce == 0 || sce->edesc == 0)
				return (ENXIO);
		}
	}

	/* Actually open the pipes. */
	/* XXX Should back out properly if it fails. */
	for (dir = OUT; dir <= IN; dir++) {
		if (!(flag & (dir == OUT ? FWRITE : FREAD)))
			continue;
		sce = &sc->sc_endpoints[endpt][dir];
		sce->state = 0;
		sce->timeout = USBD_NO_TIMEOUT;
		DPRINTFN(5, ("ugenopen: sc=%p, endpt=%d, dir=%d, sce=%p\n",
			     sc, endpt, dir, sce));
		edesc = sce->edesc;
		switch (edesc->bmAttributes & UE_XFERTYPE) {
		case UE_INTERRUPT:
			if (dir == OUT) {
				err = usbd_open_pipe(sce->iface,
				    edesc->bEndpointAddress, 0, &sce->pipeh);
				if (err)
					return (EIO);
				break;
			}
			isize = UGETW(edesc->wMaxPacketSize);
			if (isize == 0)	/* shouldn't happen */
				return (EINVAL);
			sce->ibuf = malloc(isize, M_USBDEV, M_WAITOK);
			DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n",
				     endpt, isize));
			clalloc(&sce->q, UGEN_IBSIZE, 0);
			err = usbd_open_pipe_intr(sce->iface,
				  edesc->bEndpointAddress,
				  USBD_SHORT_XFER_OK, &sce->pipeh, sce,
				  sce->ibuf, isize, ugenintr,
				  USBD_DEFAULT_INTERVAL);
			if (err) {
				free(sce->ibuf, M_USBDEV, 0);
				clfree(&sce->q);
				return (EIO);
			}
			DPRINTFN(5, ("ugenopen: interrupt open done\n"));
			break;
		case UE_BULK:
			err = usbd_open_pipe(sce->iface,
				  edesc->bEndpointAddress, 0, &sce->pipeh);
			if (err)
				return (EIO);
			break;
		case UE_ISOCHRONOUS:
			if (dir == OUT)
				return (EINVAL);
			isize = UGETW(edesc->wMaxPacketSize);
			if (isize == 0)	/* shouldn't happen */
				return (EINVAL);
			sce->ibuf = malloc(isize * UGEN_NISOFRAMES,
				M_USBDEV, M_WAITOK);
			sce->cur = sce->fill = sce->ibuf;
			sce->limit = sce->ibuf + isize * UGEN_NISOFRAMES;
			DPRINTFN(5, ("ugenopen: isoc endpt=%d, isize=%d\n",
				     endpt, isize));
			err = usbd_open_pipe(sce->iface,
				  edesc->bEndpointAddress, 0, &sce->pipeh);
			if (err) {
				free(sce->ibuf, M_USBDEV, 0);
				return (EIO);
			}
			for(i = 0; i < UGEN_NISOREQS; ++i) {
				sce->isoreqs[i].sce = sce;
				xfer = usbd_alloc_xfer(sc->sc_udev);
				if (xfer == 0)
					goto bad;
				sce->isoreqs[i].xfer = xfer;
				buf = usbd_alloc_buffer
					(xfer, isize * UGEN_NISORFRMS);
				if (buf == 0) {
					i++;
					goto bad;
				}
				sce->isoreqs[i].dmabuf = buf;
				for(j = 0; j < UGEN_NISORFRMS; ++j)
					sce->isoreqs[i].sizes[j] = isize;
				usbd_setup_isoc_xfer
					(xfer, sce->pipeh, &sce->isoreqs[i],
					 sce->isoreqs[i].sizes,
					 UGEN_NISORFRMS, USBD_NO_COPY,
					 ugen_isoc_rintr);
				(void)usbd_transfer(xfer);
			}
			DPRINTFN(5, ("ugenopen: isoc open done\n"));
			break;
		bad:
			while (--i >= 0) /* implicit buffer free */
				usbd_free_xfer(sce->isoreqs[i].xfer);
			return (ENOMEM);
		case UE_CONTROL:
			sce->timeout = USBD_DEFAULT_TIMEOUT;
			return (EINVAL);
		}
	}
	sc->sc_is_open[endpt] = 1;
	return (0);
}
Пример #23
0
Static int
url_openpipes(struct url_softc *sc)
{
	struct url_chain *c;
	usbd_status err;
	int i;
	int error = 0;

	if (sc->sc_dying)
		return (EIO);

	sc->sc_refcnt++;

	/* Open RX pipe */
	err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkin_no,
			     USBD_EXCLUSIVE_USE, &sc->sc_pipe_rx);
	if (err) {
		printf("%s: open rx pipe failed: %s\n",
		       USBDEVNAME(sc->sc_dev), usbd_errstr(err));
		error = EIO;
		goto done;
	}

	/* Open TX pipe */
	err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkout_no,
			     USBD_EXCLUSIVE_USE, &sc->sc_pipe_tx);
	if (err) {
		printf("%s: open tx pipe failed: %s\n",
		       USBDEVNAME(sc->sc_dev), usbd_errstr(err));
		error = EIO;
		goto done;
	}

#if 0
	/* XXX: interrupt endpoint is not yet supported */
	/* Open Interrupt pipe */
	err = usbd_open_pipe_intr(sc->sc_ctl_iface, sc->sc_intrin_no,
				  USBD_EXCLUSIVE_USE, &sc->sc_pipe_intr, sc,
				  &sc->sc_cdata.url_ibuf, URL_INTR_PKGLEN,
				  url_intr, URL_INTR_INTERVAL);
	if (err) {
		printf("%s: open intr pipe failed: %s\n",
		       USBDEVNAME(sc->sc_dev), usbd_errstr(err));
		error = EIO;
		goto done;
	}
#endif


	/* Start up the receive pipe. */
	for (i = 0; i < URL_RX_LIST_CNT; i++) {
		c = &sc->sc_cdata.url_rx_chain[i];
		usbd_setup_xfer(c->url_xfer, sc->sc_pipe_rx,
				c, c->url_buf, URL_BUFSZ,
				USBD_SHORT_XFER_OK | USBD_NO_COPY,
				USBD_NO_TIMEOUT, url_rxeof);
		(void)usbd_transfer(c->url_xfer);
		DPRINTF(("%s: %s: start read\n", USBDEVNAME(sc->sc_dev),
			 __func__));
	}

 done:
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(USBDEV(sc->sc_dev));

	return (error);
}
Пример #24
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;
}
Пример #25
0
int
uhidev_open(struct uhidev *scd)
{
	struct uhidev_softc *sc = scd->sc_parent;
	usbd_status err;
	int error;

	DPRINTF(("uhidev_open: open pipe, state=%d refcnt=%d\n",
		 scd->sc_state, sc->sc_refcnt));

	if (scd->sc_state & UHIDEV_OPEN)
		return (EBUSY);
	scd->sc_state |= UHIDEV_OPEN;
	if (sc->sc_refcnt++)
		return (0);

	if (sc->sc_isize == 0)
		return (0);

	sc->sc_ibuf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);

	/* Set up input interrupt pipe. */
	DPRINTF(("uhidev_open: isize=%d, ep=0x%02x\n", sc->sc_isize,
	    sc->sc_iep_addr));
		
	err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_iep_addr,
		  USBD_SHORT_XFER_OK, &sc->sc_ipipe, sc, sc->sc_ibuf,
		  sc->sc_isize, uhidev_intr, USBD_DEFAULT_INTERVAL);
	if (err != USBD_NORMAL_COMPLETION) {
		DPRINTF(("uhidopen: usbd_open_pipe_intr failed, "
		    "error=%d\n", err));
		error = EIO;
		goto out1;
	}

	DPRINTF(("uhidev_open: sc->sc_ipipe=%p\n", sc->sc_ipipe));

	sc->sc_ixfer = usbd_alloc_xfer(sc->sc_udev);
	if (sc->sc_ixfer == NULL) {
		DPRINTF(("uhidev_open: couldn't allocate an xfer\n"));
		error = ENOMEM;
		goto out1; // xxxx
	}

	/*
	 * Set up output interrupt pipe if an output interrupt endpoint
	 * exists.
	 */
	if (sc->sc_oep_addr != -1) {
		DPRINTF(("uhidev_open: oep=0x%02x\n", sc->sc_oep_addr));

		err = usbd_open_pipe(sc->sc_iface, sc->sc_oep_addr,
		    0, &sc->sc_opipe);

		if (err != USBD_NORMAL_COMPLETION) {
			DPRINTF(("uhidev_open: usbd_open_pipe failed, "
			    "error=%d\n", err));
			error = EIO;
			goto out2;
		}
		DPRINTF(("uhidev_open: sc->sc_opipe=%p\n", sc->sc_opipe));

		sc->sc_oxfer = usbd_alloc_xfer(sc->sc_udev);
		if (sc->sc_oxfer == NULL) {
			DPRINTF(("uhidev_open: couldn't allocate an xfer\n"));
			error = ENOMEM;
			goto out3;
		}

		sc->sc_owxfer = usbd_alloc_xfer(sc->sc_udev);
		if (sc->sc_owxfer == NULL) {
			DPRINTF(("uhidev_open: couldn't allocate owxfer\n"));
			error = ENOMEM;
			goto out3;
		}
	}
	
	return (0);

out3:
	/* Abort output pipe */
	usbd_close_pipe(sc->sc_opipe);
out2:
	/* Abort input pipe */
	usbd_close_pipe(sc->sc_ipipe);
out1:
	DPRINTF(("uhidev_open: failed in someway"));
	free(sc->sc_ibuf, M_USBDEV);
	scd->sc_state &= ~UHIDEV_OPEN;
	sc->sc_refcnt = 0;
	sc->sc_ipipe = NULL;
	sc->sc_opipe = NULL;
	if (sc->sc_oxfer != NULL) {
		usbd_free_xfer(sc->sc_oxfer);
		sc->sc_oxfer = NULL;
	}
	if (sc->sc_owxfer != NULL) {
		usbd_free_xfer(sc->sc_owxfer);
		sc->sc_owxfer = NULL;
	}
	return (error);
}
Пример #26
0
static int
ufoma_attach(device_t self)
{
	struct ufoma_softc *sc = device_get_softc(self);
	struct usb_attach_arg *uaa = device_get_ivars(self);
	usbd_device_handle dev = uaa->device;
	usb_config_descriptor_t *cd;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;
	usb_mcpc_acm_descriptor *mad;
	struct ucom_softc *ucom = &sc->sc_ucom;
	const char *devname,*modename;
	int ctl_notify;
	int i,err;
	int elements;
	uByte *mode;
	struct sysctl_ctx_list *sctx;
	struct sysctl_oid *soid;
	
	ucom->sc_dev = self;
	ucom->sc_udev = dev;
	sc->sc_ctl_iface = uaa->iface;
	mtx_init(&sc->sc_mtx, "ufoma", NULL, MTX_DEF);	

	cd = usbd_get_config_descriptor(ucom->sc_udev);
	id = usbd_get_interface_descriptor(sc->sc_ctl_iface);
	sc->sc_ctl_iface_no = id->bInterfaceNumber;
	
	devname = device_get_nameunit(self);
	device_printf(self, "iclass %d/%d ifno:%d\n",
	    id->bInterfaceClass, id->bInterfaceSubClass, sc->sc_ctl_iface_no);

	ctl_notify = -1;
	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(sc->sc_ctl_iface, i);
		if (ed == NULL)
			continue;

		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {
			ctl_notify = ed->bEndpointAddress;
		}
	}

	if(ctl_notify== -1){
		/*NOTIFY is mandatory.*/
		printf("NOTIFY interface not found\n");
		goto error;
	}

	err = usbd_open_pipe_intr(sc->sc_ctl_iface, ctl_notify, 
	    USBD_SHORT_XFER_OK, &sc->sc_notify_pipe, sc, &sc->sc_notify_buf,
	    sizeof(sc->sc_notify_buf), ufoma_intr, USBD_DEFAULT_INTERVAL);
	if(err){
		printf("PIPE open error %d\n", err);
		goto error;
	}
	mad = ufoma_get_intconf(cd, id , UDESC_VS_INTERFACE, UDESCSUB_MCPC_ACM);
	if(mad ==NULL){
		goto error;
	}

	printf("%s:Supported Mode:", devname);
	for(mode = mad->bMode; 
	    mode < ((uByte *)mad + mad->bFunctionLength); mode++){
		modename = ufoma_mode_to_str(*mode);
		if(modename){
			printf("%s", ufoma_mode_to_str(*mode));
		}else{
			printf("(%x)", *mode);
		}
		if(mode != ((uByte*)mad + mad->bFunctionLength-1)){
			printf(",");
		}
	}
	printf("\n");

	if((mad->bType == UMCPC_ACM_TYPE_AB5)
	   ||(mad->bType == UMCPC_ACM_TYPE_AB6)){
		/*These does not have data interface*/
		sc->sc_is_ucom = 0;
		ufoma_init_pseudo_ucom(sc);
	}else{
		if(ufoma_init_modem(sc, uaa)){
			goto error;
		}
	}
	elements = mad->bFunctionLength - sizeof(*mad)+1;

	sc->sc_msgxf = usbd_alloc_xfer(ucom->sc_udev);
	sc->sc_nummsg = 0;

	/*Initialize Mode vars.*/
	sc->sc_modetable = malloc(elements + 1, M_USBDEV, M_WAITOK);
	sc->sc_modetable[0] = elements + 1;
	bcopy(mad->bMode, &sc->sc_modetable[1], elements);
	sc->sc_currentmode = UMCPC_ACM_MODE_UNLINKED;
	sc->sc_modetoactivate = mad->bMode[0];
	/*Sysctls*/
	sctx = device_get_sysctl_ctx(self);
	soid = device_get_sysctl_tree(self);

	SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "supportmode",
			CTLFLAG_RD|CTLTYPE_STRING, sc, 0, ufoma_sysctl_support,
			"A", "Supporting port role");

	SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "currentmode",
			CTLFLAG_RD|CTLTYPE_STRING, sc, 0, ufoma_sysctl_current,
			"A", "Current port role");

	SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "openmode",
			CTLFLAG_RW|CTLTYPE_STRING, sc, 0, ufoma_sysctl_open,
			"A", "Mode to transit when port is opened");
	return 0;
 error:
	if(sc->sc_modetable)
		free(sc->sc_modetable, M_USBDEV);
	return EIO;
}
Пример #27
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 */
Пример #28
0
/*******************************************************************************
 *
 * Bluetooth Unit/USB callbacks
 *
 * All of this will be called at the IPL_ we specified above
 */
int
ubt_enable(struct device *self)
{
	struct ubt_softc *sc = device_get_softc(self);
	usbd_status err;
	int i, error;

	DPRINTFN(1, "%s: sc=%p\n", __func__, sc);

	if (sc->sc_enabled)
		return 0;

	crit_enter();

	/* Events */
	sc->sc_evt_buf = kmalloc(UBT_BUFSIZ_EVENT, M_USBDEV, M_NOWAIT);
	if (sc->sc_evt_buf == NULL) {
		error = ENOMEM;
		goto bad;
	}

	err = usbd_open_pipe_intr(sc->sc_iface0,
				  sc->sc_evt_addr,
				  USBD_SHORT_XFER_OK,
				  &sc->sc_evt_pipe,
				  sc,
				  sc->sc_evt_buf,
				  UBT_BUFSIZ_EVENT,
				  ubt_recv_event,
				  UBT_INTR_TIMEOUT);
	if (err != USBD_NORMAL_COMPLETION) {
		error = EIO;
		kprintf("can't open events pipe_intr\n");
		goto bad;
	}

	/* Commands */
	sc->sc_cmd_xfer = usbd_alloc_xfer(sc->sc_udev);
	if (sc->sc_cmd_xfer == NULL) {
		kprintf("can't allocate cmd_xfer\n");
		error = ENOMEM;
		goto bad;
	}
	sc->sc_cmd_buf = usbd_alloc_buffer(sc->sc_cmd_xfer, UBT_BUFSIZ_CMD);
	if (sc->sc_cmd_buf == NULL) {
		kprintf("can't allocate cmd_buf\n");
		error = ENOMEM;
		goto bad;
	}
	sc->sc_cmd_busy = 0;

	/* ACL read */
	err = usbd_open_pipe(sc->sc_iface0, sc->sc_aclrd_addr,
				USBD_EXCLUSIVE_USE, &sc->sc_aclrd_pipe);
	if (err != USBD_NORMAL_COMPLETION) {
		kprintf("can't open aclrd pipe\n");
		error = EIO;
		goto bad;
	}
	sc->sc_aclrd_xfer = usbd_alloc_xfer(sc->sc_udev);
	if (sc->sc_aclrd_xfer == NULL) {
		kprintf("can't allocate aclrd_xfer\n");
		error = ENOMEM;
		goto bad;
	}
	sc->sc_aclrd_buf = usbd_alloc_buffer(sc->sc_aclrd_xfer, UBT_BUFSIZ_ACL);
	if (sc->sc_aclrd_buf == NULL) {
		kprintf("can't allocate aclrd_buf\n");
		error = ENOMEM;
		goto bad;
	}
	sc->sc_aclrd_busy = 0;
	ubt_recv_acl_start(sc);

	/* ACL write */
	err = usbd_open_pipe(sc->sc_iface0, sc->sc_aclwr_addr,
				USBD_EXCLUSIVE_USE, &sc->sc_aclwr_pipe);
	if (err != USBD_NORMAL_COMPLETION) {
		kprintf("can't open aclwr pipe\n");
		error = EIO;
		goto bad;
	}
	sc->sc_aclwr_xfer = usbd_alloc_xfer(sc->sc_udev);
	if (sc->sc_aclwr_xfer == NULL) {
		kprintf("can't allocate aclwr_xfer\n");
		error = ENOMEM;
		goto bad;
	}
	sc->sc_aclwr_buf = usbd_alloc_buffer(sc->sc_aclwr_xfer, UBT_BUFSIZ_ACL);
	if (sc->sc_aclwr_buf == NULL) {
		kprintf("can't allocate aclwr_buf\n");
		error = ENOMEM;
		goto bad;
	}
	sc->sc_aclwr_busy = 0;

	/* SCO read */
	if (sc->sc_scord_size > 0) {
		err = usbd_open_pipe(sc->sc_iface1, sc->sc_scord_addr,
					USBD_EXCLUSIVE_USE, &sc->sc_scord_pipe);
		if (err != USBD_NORMAL_COMPLETION) {
			error = EIO;
			goto bad;
		}

		for (i = 0 ; i < UBT_NXFERS ; i++) {
			sc->sc_scord[i].xfer = usbd_alloc_xfer(sc->sc_udev);
			if (sc->sc_scord[i].xfer == NULL) {
				error = ENOMEM;
				goto bad;
			}
			sc->sc_scord[i].buf = usbd_alloc_buffer(sc->sc_scord[i].xfer,
						sc->sc_scord_size * UBT_NFRAMES);
			if (sc->sc_scord[i].buf == NULL) {
				error = ENOMEM;
				goto bad;
			}
			sc->sc_scord[i].softc = sc;
			sc->sc_scord[i].busy = 0;
			ubt_recv_sco_start1(sc, &sc->sc_scord[i]);
		}
	}

	/* SCO write */
	if (sc->sc_scowr_size > 0) {
		err = usbd_open_pipe(sc->sc_iface1, sc->sc_scowr_addr,
					USBD_EXCLUSIVE_USE, &sc->sc_scowr_pipe);
		if (err != USBD_NORMAL_COMPLETION) {
			error = EIO;
			goto bad;
		}

		for (i = 0 ; i < UBT_NXFERS ; i++) {
			sc->sc_scowr[i].xfer = usbd_alloc_xfer(sc->sc_udev);
			if (sc->sc_scowr[i].xfer == NULL) {
				error = ENOMEM;
				goto bad;
			}
			sc->sc_scowr[i].buf = usbd_alloc_buffer(sc->sc_scowr[i].xfer,
						sc->sc_scowr_size * UBT_NFRAMES);
			if (sc->sc_scowr[i].buf == NULL) {
				error = ENOMEM;
				goto bad;
			}
			sc->sc_scowr[i].softc = sc;
			sc->sc_scowr[i].busy = 0;
		}

		sc->sc_scowr_busy = 0;
	}

	sc->sc_enabled = 1;
	crit_exit();
	return 0;

bad:
	ubt_abortdealloc(sc);
	crit_exit();
	return error;
}
Пример #29
0
Static int
uvscom_open(void *addr, int portno)
{
	struct uvscom_softc *sc = addr;
	int err;
	int i;
	
	if (sc->sc_dying)
		return (EIO);

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

	if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
		DPRINTF(("uvscom_open: open interrupt pipe.\n"));

		sc->sc_usr = 0;		/* clear unit status */

		err = uvscom_readstat(sc);
		if (err) {
			DPRINTF(("%s: uvscom_open: readstat faild\n",
				 USBDEVNAME(sc->sc_dev)));
			return (EIO);
		}

		sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
		err = usbd_open_pipe_intr(sc->sc_iface,
					  sc->sc_intr_number,
					  USBD_SHORT_XFER_OK,
					  &sc->sc_intr_pipe,
					  sc,
					  sc->sc_intr_buf,
					  sc->sc_isize,
					  uvscom_intr,
					  UVSCOM_INTR_INTERVAL);
		if (err) {
			printf("%s: cannot open interrupt pipe (addr %d)\n",
				 USBDEVNAME(sc->sc_dev),
				 sc->sc_intr_number);
			return (EIO);
		}
	} else {
		DPRINTF(("uvscom_open: did not open interrupt pipe.\n"));
	}

	if ((sc->sc_usr & UVSCOM_USTAT_MASK) == 0) {
		/* unit is not ready */

		for (i = UVSCOM_UNIT_WAIT; i > 0; --i) {
			tsleep(&err, TTIPRI, "uvsop", hz);	/* XXX */
			if (ISSET(sc->sc_usr, UVSCOM_USTAT_MASK))
				break;
		}
		if (i == 0) {
			DPRINTF(("%s: unit is not ready\n",
				 USBDEVNAME(sc->sc_dev)));
			return (EIO);
		}

		/* check PC card was inserted */
		if (ISSET(sc->sc_usr, UVSCOM_NOCARD)) {
			DPRINTF(("%s: no card\n",
				 USBDEVNAME(sc->sc_dev)));
			return (EIO);
		}
	}

	return (0);
}
Пример #30
0
int
uhidev_open(struct uhidev *scd)
{
	struct uhidev_softc *sc = scd->sc_parent;
	usbd_status err;
	int error;

	DPRINTF(("uhidev_open: open pipe, state=%d\n", scd->sc_state));

	mutex_enter(&sc->sc_lock);
	if (scd->sc_state & UHIDEV_OPEN) {
		mutex_exit(&sc->sc_lock);
		return EBUSY;
	}
	scd->sc_state |= UHIDEV_OPEN;
	if (sc->sc_refcnt++) {
		mutex_exit(&sc->sc_lock);
		return 0;
	}
	mutex_exit(&sc->sc_lock);

	if (sc->sc_isize == 0)
		return 0;

	sc->sc_ibuf = kmem_alloc(sc->sc_isize, KM_SLEEP);

	/* Set up input interrupt pipe. */
	DPRINTF(("uhidev_open: isize=%d, ep=0x%02x\n", sc->sc_isize,
		 sc->sc_iep_addr));

	err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_iep_addr,
		  USBD_SHORT_XFER_OK, &sc->sc_ipipe, sc, sc->sc_ibuf,
		  sc->sc_isize, uhidev_intr, USBD_DEFAULT_INTERVAL);
	if (err != USBD_NORMAL_COMPLETION) {
		DPRINTF(("uhidopen: usbd_open_pipe_intr failed, "
		    "error=%d\n", err));
		error = EIO;
		goto out1;
	}

	/*
	 * Set up output interrupt pipe if an output interrupt endpoint
	 * exists.
	 */
	if (sc->sc_oep_addr != -1) {
		DPRINTF(("uhidev_open: oep=0x%02x\n", sc->sc_oep_addr));

		err = usbd_open_pipe(sc->sc_iface, sc->sc_oep_addr,
		    0, &sc->sc_opipe);

		if (err != USBD_NORMAL_COMPLETION) {
			DPRINTF(("uhidev_open: usbd_open_pipe failed, "
			    "error=%d\n", err));
			error = EIO;
			goto out2;
		}
		DPRINTF(("uhidev_open: sc->sc_opipe=%p\n", sc->sc_opipe));

		error = usbd_create_xfer(sc->sc_opipe, UHIDEV_OSIZE, 0, 0,
		    &sc->sc_oxfer);
		if (error) {
			DPRINTF(("uhidev_open: couldn't allocate an xfer\n"));
			goto out3;
		}

		if (sc->sc_flags & UHIDEV_F_XB1) {
			uint8_t init_data[] = { 0x05, 0x20 };
			int init_data_len = sizeof(init_data);
			err = usbd_intr_transfer(sc->sc_oxfer, sc->sc_opipe, 0,
			    USBD_NO_TIMEOUT, init_data, &init_data_len);
			if (err != USBD_NORMAL_COMPLETION) {
				DPRINTF(("uhidev_open: xb1 init failed, "
				    "error=%d\n", err));
				error = EIO;
				goto out4;
			}
		}
	}

	return 0;
out4:
	/* Free output xfer */
	if (sc->sc_oxfer != NULL)
		usbd_destroy_xfer(sc->sc_oxfer);
out3:
	/* Abort output pipe */
	usbd_close_pipe(sc->sc_opipe);
out2:
	/* Abort input pipe */
	usbd_close_pipe(sc->sc_ipipe);
out1:
	DPRINTF(("uhidev_open: failed in someway"));
	kmem_free(sc->sc_ibuf, sc->sc_isize);
	mutex_enter(&sc->sc_lock);
	scd->sc_state &= ~UHIDEV_OPEN;
	sc->sc_refcnt = 0;
	sc->sc_ibuf = NULL;
	sc->sc_ipipe = NULL;
	sc->sc_opipe = NULL;
	sc->sc_oxfer = NULL;
	mutex_exit(&sc->sc_lock);
	return error;
}