Esempio n. 1
0
int
uriowrite(dev_t dev, struct uio *uio, int flag)
{
	struct urio_softc *sc;
	usbd_xfer_handle xfer;
	usbd_status err;
	void *bufp;
	u_int32_t n;
	int error = 0;

	sc = device_lookup_private(&urio_cd, URIOUNIT(dev));

	DPRINTFN(5, ("uriowrite: unit=%d, len=%ld\n", URIOUNIT(dev),
		     (long)uio->uio_resid));

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

	xfer = usbd_alloc_xfer(sc->sc_udev);
	if (xfer == NULL)
		return (ENOMEM);
	bufp = usbd_alloc_buffer(xfer, URIO_BSIZE);
	if (bufp == NULL) {
		usbd_free_xfer(xfer);
		return (ENOMEM);
	}

	sc->sc_refcnt++;

	while ((n = min(URIO_BSIZE, uio->uio_resid)) != 0) {
		error = uiomove(bufp, n, uio);
		if (error)
			break;

		DPRINTFN(1, ("uriowrite: transfer %d bytes\n", n));

		err = usbd_bulk_transfer(xfer, sc->sc_out_pipe, USBD_NO_COPY,
			  URIO_RW_TIMEOUT, bufp, &n, "uriowr");
		DPRINTFN(2, ("uriowrite: err=%d\n", err));
		if (err) {
			if (err == USBD_INTERRUPTED)
				error = EINTR;
			else if (err == USBD_TIMEOUT)
				error = ETIMEDOUT;
			else
				error = EIO;
			break;
		}
	}

	usbd_free_xfer(xfer);

	if (--sc->sc_refcnt < 0)
		usb_detach_wakeupold(sc->sc_dev);

	DPRINTFN(5, ("uriowrite: done unit=%d, error=%d\n", URIOUNIT(dev),
		     error));

	return (error);
}
Esempio n. 2
0
int
uriowrite(dev_t dev, struct uio *uio, int flag)
{
	struct urio_softc *sc;
	struct usbd_xfer *xfer;
	usbd_status err;
	void *bufp;
	u_int32_t n;
	int error = 0;

	sc = urio_cd.cd_devs[URIOUNIT(dev)];

	DPRINTFN(5, ("uriowrite: unit=%d, len=%ld\n", URIOUNIT(dev),
		     (long)uio->uio_resid));

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

	xfer = usbd_alloc_xfer(sc->sc_udev);
	if (xfer == NULL)
		return (ENOMEM);
	bufp = usbd_alloc_buffer(xfer, URIO_BSIZE);
	if (bufp == NULL) {
		usbd_free_xfer(xfer);
		return (ENOMEM);
	}

	sc->sc_refcnt++;

	while ((n = min(URIO_BSIZE, uio->uio_resid)) != 0) {
		error = uiomove(bufp, n, uio);
		if (error)
			break;

		DPRINTFN(1, ("uriowrite: transfer %d bytes\n", n));

		usbd_setup_xfer(xfer, sc->sc_out_pipe, 0, bufp, n,
		    USBD_NO_COPY | USBD_SYNCHRONOUS, URIO_RW_TIMEOUT, NULL);
		err = usbd_transfer(xfer);
		DPRINTFN(2, ("uriowrite: err=%d\n", err));
		if (err) {
			usbd_clear_endpoint_stall(sc->sc_out_pipe);
			if (err == USBD_TIMEOUT)
				error = ETIMEDOUT;
			else
				error = EIO;
			break;
		}
	}

	usbd_free_xfer(xfer);

	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(&sc->sc_dev);

	DPRINTFN(5, ("uriowrite: done unit=%d, error=%d\n", URIOUNIT(dev),
		     error));

	return (error);
}
Esempio n. 3
0
int
urioopen(dev_t dev, int flag, int mode, struct lwp *l)
{
	struct urio_softc *sc;
	usbd_status err;

	sc = device_lookup_private(&urio_cd, URIOUNIT(dev));
	if (sc == NULL)
		return ENXIO;

	DPRINTFN(5, ("urioopen: flag=%d, mode=%d, unit=%d\n",
		     flag, mode, URIOUNIT(dev)));

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

	if (sc->sc_in_pipe != NULL)
		return (EBUSY);

	if ((flag & (FWRITE|FREAD)) != (FWRITE|FREAD))
		return (EACCES);

	err = usbd_open_pipe(sc->sc_iface, sc->sc_in_addr, 0, &sc->sc_in_pipe);
	if (err)
		return (EIO);
	err = usbd_open_pipe(sc->sc_iface, sc->sc_out_addr,0,&sc->sc_out_pipe);
	if (err) {
		usbd_close_pipe(sc->sc_in_pipe);
		sc->sc_in_pipe = NULL;
		return (EIO);
	}

	return (0);
}
Esempio n. 4
0
int
urioread(dev_t dev, struct uio *uio, int flag)
{
	struct urio_softc *sc;
	usbd_xfer_handle xfer;
	usbd_status err;
	void *bufp;
	u_int32_t n, tn;
	int error = 0;

	sc = device_lookup_private(&urio_cd, URIOUNIT(dev));

	DPRINTFN(5, ("urioread: %d\n", URIOUNIT(dev)));

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

	xfer = usbd_alloc_xfer(sc->sc_udev);
	if (xfer == NULL)
		return (ENOMEM);
	bufp = usbd_alloc_buffer(xfer, URIO_BSIZE);
	if (bufp == NULL) {
		usbd_free_xfer(xfer);
		return (ENOMEM);
	}

	sc->sc_refcnt++;

	while ((n = min(URIO_BSIZE, uio->uio_resid)) != 0) {
		DPRINTFN(1, ("urioread: start transfer %d bytes\n", n));
		tn = n;
		err = usbd_bulk_transfer(xfer, sc->sc_in_pipe, USBD_NO_COPY,
			  URIO_RW_TIMEOUT, bufp, &tn, "uriors");
		if (err) {
			if (err == USBD_INTERRUPTED)
				error = EINTR;
			else if (err == USBD_TIMEOUT)
				error = ETIMEDOUT;
			else
				error = EIO;
			break;
		}

		DPRINTFN(1, ("urioread: got %d bytes\n", tn));

		error = uiomove(bufp, tn, uio);
		if (error || tn < n)
			break;
	}
	usbd_free_xfer(xfer);

	if (--sc->sc_refcnt < 0)
		usb_detach_wakeupold(sc->sc_dev);

	return (error);
}
Esempio n. 5
0
int
urioclose(dev_t dev, int flag, int mode, struct proc *p)
{
	struct urio_softc *sc;
	sc = urio_cd.cd_devs[URIOUNIT(dev)];

	DPRINTFN(5, ("urioclose: flag=%d, mode=%d, unit=%d\n",
		     flag, mode, URIOUNIT(dev)));

	if (sc->sc_in_pipe != NULL) {
		usbd_abort_pipe(sc->sc_in_pipe);
		usbd_close_pipe(sc->sc_in_pipe);
		sc->sc_in_pipe = NULL;
	}
	if (sc->sc_out_pipe != NULL) {
		usbd_abort_pipe(sc->sc_out_pipe);
		usbd_close_pipe(sc->sc_out_pipe);
		sc->sc_out_pipe = NULL;
	}

	return (0);
}
Esempio n. 6
0
int
urioclose(dev_t dev, int flag, int mode,
    struct lwp *l)
{
	struct urio_softc *sc;
	sc = device_lookup_private(&urio_cd, URIOUNIT(dev));

	DPRINTFN(5, ("urioclose: flag=%d, mode=%d, unit=%d\n",
		     flag, mode, URIOUNIT(dev)));

	if (sc->sc_in_pipe != NULL) {
		usbd_abort_pipe(sc->sc_in_pipe);
		usbd_close_pipe(sc->sc_in_pipe);
		sc->sc_in_pipe = NULL;
	}
	if (sc->sc_out_pipe != NULL) {
		usbd_abort_pipe(sc->sc_out_pipe);
		usbd_close_pipe(sc->sc_out_pipe);
		sc->sc_out_pipe = NULL;
	}

	return (0);
}
Esempio n. 7
0
int
urioopen(dev_t dev, int flag, int mode, struct proc *p)
{
	struct urio_softc *sc;
	usbd_status err;

	if (URIOUNIT(dev) >= urio_cd.cd_ndevs)
		return (ENXIO);
	sc = urio_cd.cd_devs[URIOUNIT(dev)];
	if (sc == NULL)
		return (ENXIO);

	DPRINTFN(5, ("urioopen: flag=%d, mode=%d, unit=%d\n",
		     flag, mode, URIOUNIT(dev)));

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

	if (sc->sc_in_pipe != NULL)
		return (EBUSY);

	if ((flag & (FWRITE|FREAD)) != (FWRITE|FREAD))
		return (EACCES);

	err = usbd_open_pipe(sc->sc_iface, sc->sc_in_addr, 0, &sc->sc_in_pipe);
	if (err)
		return (EIO);
	err = usbd_open_pipe(sc->sc_iface, sc->sc_out_addr,0,&sc->sc_out_pipe);
	if (err) {
		usbd_close_pipe(sc->sc_in_pipe);
		sc->sc_in_pipe = NULL;
		return (EIO);
	}

	return (0);
}
Esempio n. 8
0
int
urioopen(struct dev_open_args *ap)
{
    cdev_t dev = ap->a_head.a_dev;
#if (USBDI >= 1)
    struct urio_softc * sc;
#endif
    int unit = URIOUNIT(dev);
    sc = devclass_get_softc(urio_devclass, unit);
    if (sc == NULL)
        return (ENXIO);

    DPRINTFN(5, ("urioopen: flag=%d, mode=%d, unit=%d\n",
                 ap->a_oflags, ap->a_devtype, unit));

    if (sc->sc_opened)
        return EBUSY;

    if ((ap->a_oflags & (FWRITE|FREAD)) != (FWRITE|FREAD))
        return EACCES;

    sc->sc_opened = 1;
    sc->sc_pipeh_in = 0;
    sc->sc_pipeh_out = 0;
    if (usbd_open_pipe(sc->sc_iface,
                       sc->sc_epaddr[RIO_IN], 0, &sc->sc_pipeh_in)
            != USBD_NORMAL_COMPLETION)
    {
        sc->sc_pipeh_in = 0;
        return EIO;
    };
    if (usbd_open_pipe(sc->sc_iface,
                       sc->sc_epaddr[RIO_OUT], 0, &sc->sc_pipeh_out)
            != USBD_NORMAL_COMPLETION)
    {
        usbd_close_pipe(sc->sc_pipeh_in);
        sc->sc_pipeh_in = 0;
        sc->sc_pipeh_out = 0;
        return EIO;
    };
    return 0;
}
Esempio n. 9
0
int
urioclose(struct dev_close_args *ap)
{
    cdev_t dev = ap->a_head.a_dev;
#if (USBDI >= 1)
    struct urio_softc * sc;
#endif
    int unit = URIOUNIT(dev);
    sc = devclass_get_softc(urio_devclass, unit);

    DPRINTFN(5, ("urioclose: flag=%d, mode=%d, unit=%d\n",
                 ap->a_fflag, ap->a_devtype, unit));
    if (sc->sc_pipeh_in)
        usbd_close_pipe(sc->sc_pipeh_in);

    if (sc->sc_pipeh_out)
        usbd_close_pipe(sc->sc_pipeh_out);

    sc->sc_pipeh_in = 0;
    sc->sc_pipeh_out = 0;
    sc->sc_opened = 0;
    sc->sc_refcnt = 0;
    return 0;
}
Esempio n. 10
0
int
urioioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
{
	struct urio_softc * sc;
	int unit = URIOUNIT(dev);
	struct urio_command *rcmd;
	int requesttype, len;
	struct iovec iov;
	struct uio uio;
	usb_device_request_t req;
	usbd_status err;
	u_int32_t req_actlen = 0;
	void *ptr = NULL;
	int error = 0;

	sc = urio_cd.cd_devs[unit];

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

	rcmd = (struct urio_command *)addr;

	switch (cmd) {
	case URIO_RECV_COMMAND:
		requesttype = rcmd->requesttype | UT_READ_VENDOR_DEVICE;
		break;

	case URIO_SEND_COMMAND:
		requesttype = rcmd->requesttype | UT_WRITE_VENDOR_DEVICE;
		break;

	default:
		return (EINVAL);
		break;
	}

	if (!(flag & FWRITE))
		return (EPERM);
	len = rcmd->length;

	DPRINTFN(1,("urio_ioctl: cmd=0x%08lx reqtype=0x%0x req=0x%0x "
		    "value=0x%0x index=0x%0x len=0x%0x\n",
		    cmd, requesttype, rcmd->request, rcmd->value,
		    rcmd->index, len));

	/* Send rio control message */
	req.bmRequestType = requesttype;
	req.bRequest = rcmd->request;
	USETW(req.wValue, rcmd->value);
	USETW(req.wIndex, rcmd->index);
	USETW(req.wLength, len);

	if (len < 0 || len > 32767)
		return (EINVAL);
	if (len != 0) {
		iov.iov_base = (caddr_t)rcmd->buffer;
		iov.iov_len = len;
		uio.uio_iov = &iov;
		uio.uio_iovcnt = 1;
		uio.uio_resid = len;
		uio.uio_offset = 0;
		uio.uio_segflg = UIO_USERSPACE;
		uio.uio_rw = req.bmRequestType & UT_READ ?
			     UIO_READ : UIO_WRITE;
		uio.uio_procp = p;
		ptr = malloc(len, M_TEMP, M_WAITOK);
		if (uio.uio_rw == UIO_WRITE) {
			error = uiomove(ptr, len, &uio);
			if (error)
				goto ret;
		}
	}

	sc->sc_refcnt++;

	err = usbd_do_request_flags(sc->sc_udev, &req, ptr, 0,
		  &req_actlen, USBD_DEFAULT_TIMEOUT);

	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(&sc->sc_dev);

	if (err) {
		error = EIO;
	} else {
		if (req_actlen != 0 && uio.uio_rw == UIO_READ)
			error = uiomove(ptr, req_actlen, &uio);
	}

ret:
	if (ptr != NULL)
		free(ptr, M_TEMP);
	return (error);
}
Esempio n. 11
0
int
urioioctl(struct dev_ioctl_args *ap)
{
    cdev_t dev = ap->a_head.a_dev;
#if (USBDI >= 1)
    struct urio_softc * sc;
#endif
    int unit = URIOUNIT(dev);
    struct RioCommand *rio_cmd;
    int requesttype, len;
    struct iovec iov;
    struct uio uio;
    usb_device_request_t req;
    int req_flags = 0, req_actlen = 0;
    void *ptr = NULL;
    int error = 0;
    usbd_status r;

    sc = devclass_get_softc(urio_devclass, unit);

    switch (ap->a_cmd) {
    case RIO_RECV_COMMAND:
        if (!(ap->a_fflag & FWRITE))
            return EPERM;
        rio_cmd = (struct RioCommand *)ap->a_data;
        if (rio_cmd == NULL)
            return EINVAL;
        len = rio_cmd->length;

        requesttype = rio_cmd->requesttype | UT_READ_VENDOR_DEVICE;
        DPRINTFN(1,("sending command:reqtype=%0x req=%0x value=%0x index=%0x len=%0x\n",
                    requesttype, rio_cmd->request, rio_cmd->value, rio_cmd->index, len));
        break;

    case RIO_SEND_COMMAND:
        if (!(ap->a_fflag & FWRITE))
            return EPERM;
        rio_cmd = (struct RioCommand *)ap->a_data;
        if (rio_cmd == NULL)
            return EINVAL;
        len = rio_cmd->length;

        requesttype = rio_cmd->requesttype | UT_WRITE_VENDOR_DEVICE;
        DPRINTFN(1,("sending command:reqtype=%0x req=%0x value=%0x index=%0x len=%0x\n",
                    requesttype, rio_cmd->request, rio_cmd->value, rio_cmd->index, len));
        break;

    default:
        return EINVAL;
        break;
    }

    /* Send rio control message */
    req.bmRequestType = requesttype;
    req.bRequest = rio_cmd->request;
    USETW(req.wValue, rio_cmd->value);
    USETW(req.wIndex, rio_cmd->index);
    USETW(req.wLength, len);

    if (len < 0 || len > 32767)
        return EINVAL;
    if (len != 0) {
        iov.iov_base = (caddr_t)rio_cmd->buffer;
        iov.iov_len = len;
        uio.uio_iov = &iov;
        uio.uio_iovcnt = 1;
        uio.uio_resid = len;
        uio.uio_offset = 0;
        uio.uio_segflg = UIO_USERSPACE;
        uio.uio_rw =
            req.bmRequestType & UT_READ ?
            UIO_READ : UIO_WRITE;
        uio.uio_td = curthread;
        ptr = kmalloc(len, M_TEMP, M_WAITOK);
        if (uio.uio_rw == UIO_WRITE) {
            error = uiomove(ptr, len, &uio);
            if (error)
                goto ret;
        }
    }

    r = usbd_do_request_flags(sc->sc_udev, &req,
                              ptr, req_flags, &req_actlen,
                              USBD_DEFAULT_TIMEOUT);
    if (r == USBD_NORMAL_COMPLETION) {
        error = 0;
        if (len != 0) {
            if (uio.uio_rw == UIO_READ) {
                error = uiomove(ptr, len, &uio);
            }
        }
    } else {
        error = EIO;
    }

ret:
    if (ptr)
        kfree(ptr, M_TEMP);
    return error;
}
Esempio n. 12
0
int
uriowrite(struct dev_write_args *ap)
{
    cdev_t dev = ap->a_head.a_dev;
    struct uio *uio = ap->a_uio;
#if (USBDI >= 1)
    struct urio_softc * sc;
    usbd_xfer_handle reqh;
#else
    usbd_request_handle reqh;
#endif
    int unit = URIOUNIT(dev);
    usbd_status r;
    char buf[URIO_BBSIZE];
    u_int32_t n;
    int error = 0;

    sc = devclass_get_softc(urio_devclass, unit);

    DPRINTFN(5, ("uriowrite: %d\n", unit));
    if (!sc->sc_opened)
        return EIO;

#if (USBDI >= 1)
    sc->sc_refcnt++;
    reqh = usbd_alloc_xfer(sc->sc_udev);
#else
    reqh = usbd_alloc_request();
#endif
    if (reqh == 0)
        return EIO;
    while ((n = szmin(URIO_BBSIZE, uio->uio_resid)) != 0) {
        error = uiomove(buf, n, uio);
        if (error)
            break;
        DPRINTFN(1, ("uriowrite: transfer %d bytes\n", n));
#if (USBDI >= 1)
        usbd_setup_xfer(reqh, sc->sc_pipeh_out, 0, buf, n,
                        0, RIO_RW_TIMEOUT, 0);
#else
        r = usbd_setup_request(reqh, sc->sc_pipeh_out, 0, buf, n,
                               0, RIO_RW_TIMEOUT, 0);
        if (r != USBD_NORMAL_COMPLETION) {
            error = EIO;
            break;
        }
#endif
        r = usbd_sync_transfer(reqh);
        if (r != USBD_NORMAL_COMPLETION) {
            DPRINTFN(1, ("uriowrite: error=%d\n", r));
            usbd_clear_endpoint_stall(sc->sc_pipeh_out);
            error = EIO;
            break;
        }
#if (USBDI >= 1)
        usbd_get_xfer_status(reqh, 0, 0, 0, 0);
#endif
    }

#if (USBDI >= 1)
    usbd_free_xfer(reqh);
#else
    usbd_free_request(reqh);
#endif

    return error;
}