On Fri, May 10, 2013 at 09:44:53AM +0200, Martin Pieuchot wrote:

> So this is is one more step in my effort to merge the various code paths
> to submit an USB transfer.
> 
> This diff gets rid of the two badly named functions: usbd_bulk_transfer()
> & usbd_intr_transfer() and makes use of the usbd_setup_xfer(9) + 
> usbd_transfer(9) combination.  These functions were badly named because
> they are identical wrappers to submit a synchronous transfer.  There are
> however two small functional differences with this diff:
> 
>  - previously a custom name for the wait channel was given to tlseep(9)
>    while sleeping for I/O. Now it will be "usbsyn" for all USB
>    synchronous transfers.
> 
>  - previously the priority given to tlseep(9) was PZERO. Now it will be
>    PRIBIO like for all USB synchronous transfers. But this shouldn't make
>    a difference in practice, because the only priority between the two,
>    PVFS, is unused. 
> 
> This diff also includes a new manual for the above mentioned functions.
> I'd like to document as much functions of our USB stack as possible to
> make sure driver porter/writer understand how it works.
> 
> ok?

This is OK for me.
 
> Index: sys/dev/usb/ugen.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/usb/ugen.c,v
> retrieving revision 1.71
> diff -u -p -r1.71 ugen.c
> --- sys/dev/usb/ugen.c        15 Apr 2013 09:23:02 -0000      1.71
> +++ sys/dev/usb/ugen.c        26 Apr 2013 15:09:55 -0000
> @@ -478,7 +478,7 @@ ugen_do_read(struct ugen_softc *sc, int 
>       struct usbd_xfer *xfer;
>       usbd_status err;
>       int s;
> -     int error = 0;
> +     int flags, error = 0;
>       u_char buffer[UGEN_CHUNK];
>  
>       DPRINTFN(5, ("%s: ugenread: %d\n", sc->sc_dev.dv_xname, endpt));
> @@ -546,14 +546,17 @@ ugen_do_read(struct ugen_softc *sc, int 
>               xfer = usbd_alloc_xfer(sc->sc_udev);
>               if (xfer == 0)
>                       return (ENOMEM);
> +             flags = USBD_SYNCHRONOUS;
> +             if (sce->state & UGEN_SHORT_OK)
> +                     flags |= USBD_SHORT_XFER_OK;
> +             if (sce->timeout == 0)
> +                     flags |= USBD_CATCH;
>               while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
>                       DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n));
>                       tn = n;
> -                     err = usbd_bulk_transfer(
> -                               xfer, sce->pipeh,
> -                               sce->state & UGEN_SHORT_OK ?
> -                                   USBD_SHORT_XFER_OK : 0,
> -                               sce->timeout, buf, &tn, "ugenrb");
> +                     usbd_setup_xfer(xfer, sce->pipeh, 0, buf, tn,
> +                         flags, sce->timeout, NULL);
> +                     err = usbd_transfer(xfer);
>                       if (err) {
>                               if (err == USBD_INTERRUPTED)
>                                       error = EINTR;
> @@ -640,7 +643,7 @@ ugen_do_write(struct ugen_softc *sc, int
>  {
>       struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][OUT];
>       u_int32_t n;
> -     int error = 0;
> +     int flags, error = 0;
>       char buf[UGEN_BBSIZE];
>       struct usbd_xfer *xfer;
>       usbd_status err;
> @@ -663,6 +666,9 @@ ugen_do_write(struct ugen_softc *sc, int
>               return (EIO);
>       }
>  #endif
> +     flags = USBD_SYNCHRONOUS;
> +     if (sce->timeout == 0)
> +             flags |= USBD_CATCH;
>  
>       switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
>       case UE_BULK:
> @@ -674,8 +680,9 @@ ugen_do_write(struct ugen_softc *sc, int
>                       if (error)
>                               break;
>                       DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
> -                     err = usbd_bulk_transfer(xfer, sce->pipeh, 0,
> -                               sce->timeout, buf, &n,"ugenwb");
> +                     usbd_setup_xfer(xfer, sce->pipeh, 0, buf, n,
> +                         flags, sce->timeout, NULL);
> +                     err = usbd_transfer(xfer);
>                       if (err) {
>                               if (err == USBD_INTERRUPTED)
>                                       error = EINTR;
> @@ -698,8 +705,9 @@ ugen_do_write(struct ugen_softc *sc, int
>                       if (error)
>                               break;
>                       DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
> -                     err = usbd_intr_transfer(xfer, sce->pipeh, 0,
> -                         sce->timeout, buf, &n, "ugenwi");
> +                     usbd_setup_xfer(xfer, sce->pipeh, 0, buf, n,
> +                         flags, sce->timeout, NULL);
> +                     err = usbd_transfer(xfer);
>                       if (err) {
>                               if (err == USBD_INTERRUPTED)
>                                       error = EINTR;
> Index: sys/dev/usb/uhidev.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/usb/uhidev.c,v
> retrieving revision 1.43
> diff -u -p -r1.43 uhidev.c
> --- sys/dev/usb/uhidev.c      15 Apr 2013 09:23:02 -0000      1.43
> +++ sys/dev/usb/uhidev.c      26 Apr 2013 15:03:01 -0000
> @@ -650,8 +650,9 @@ uhidev_write(struct uhidev_softc *sc, vo
>               DPRINTF(("\n"));
>       }
>  #endif
> -     return usbd_intr_transfer(sc->sc_owxfer, sc->sc_opipe, 0,
> -         USBD_NO_TIMEOUT, data, &len, "uhidevwi");
> +     usbd_setup_xfer(sc->sc_owxfer, sc->sc_opipe, 0, data, len,
> +         USBD_SYNCHRONOUS | USBD_CATCH, 0, NULL);
> +     return usbd_transfer(sc->sc_owxfer);
>  }
>  
>  int
> Index: sys/dev/usb/ulpt.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/usb/ulpt.c,v
> retrieving revision 1.43
> diff -u -p -r1.43 ulpt.c
> --- sys/dev/usb/ulpt.c        15 Apr 2013 09:23:02 -0000      1.43
> +++ sys/dev/usb/ulpt.c        26 Apr 2013 15:02:55 -0000
> @@ -636,8 +636,9 @@ ulpt_do_write(struct ulpt_softc *sc, str
>               if (error)
>                       break;
>               DPRINTFN(1, ("ulptwrite: transfer %d bytes\n", n));
> -             err = usbd_bulk_transfer(xfer, sc->sc_out_pipe, USBD_NO_COPY,
> -                       USBD_NO_TIMEOUT, bufp, &n, "ulptwr");
> +             usbd_setup_xfer(xfer, sc->sc_out_pipe, 0, bufp, n,
> +                 USBD_NO_COPY | USBD_SYNCHRONOUS | USBD_CATCH, 0, NULL);
> +             err = usbd_transfer(xfer);
>               if (err) {
>                       DPRINTF(("ulptwrite: error=%d\n", err));
>                       error = EIO;
> @@ -704,8 +705,9 @@ ulpt_ucode_loader_hp(struct ulpt_softc *
>       while (remain > 0) {
>               len = min(remain, ULPT_BSIZE);
>               memcpy(bufp, &ucode[offset], len);
> -             error = usbd_bulk_transfer(xfer, sc->sc_out_pipe, USBD_NO_COPY,
> -                       USBD_NO_TIMEOUT, bufp, &len, "ulptwr");
> +             usbd_setup_xfer(xfer, sc->sc_out_pipe, 0, bufp, len,
> +                 USBD_NO_COPY | USBD_SYNCHRONOUS, 0, NULL);
> +             error = usbd_transfer(xfer);
>               if (error != USBD_NORMAL_COMPLETION) {
>                       printf("%s: ucode upload error=%s!\n",
>                           sc->sc_dev.dv_xname, usbd_errstr(error));
> Index: sys/dev/usb/umsm.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/usb/umsm.c,v
> retrieving revision 1.90
> diff -u -p -r1.90 umsm.c
> --- sys/dev/usb/umsm.c        15 Apr 2013 09:23:02 -0000      1.90
> +++ sys/dev/usb/umsm.c        26 Apr 2013 15:02:43 -0000
> @@ -767,8 +767,9 @@ umsm_umass_changemode(struct umsm_softc 
>               else {
>                       n = UMASS_BBB_CBW_SIZE;
>                       memcpy(bufp, &cbw, UMASS_BBB_CBW_SIZE);
> -                     err = usbd_bulk_transfer(xfer, cmdpipe, USBD_NO_COPY,
> -                         USBD_NO_TIMEOUT, bufp, &n, "umsm");
> +                     usbd_setup_xfer(xfer, cmdpipe, 0, bufp, n,
> +                         USBD_NO_COPY | USBD_SYNCHRONOUS, 0, NULL);
> +                     err = usbd_transfer(xfer);
>                       if (err)
>                               DPRINTF(("%s: send error:%s", __func__,
>                                   usbd_errstr(err)));
> Index: sys/dev/usb/urio.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/usb/urio.c,v
> retrieving revision 1.41
> diff -u -p -r1.41 urio.c
> --- sys/dev/usb/urio.c        15 Apr 2013 09:23:02 -0000      1.41
> +++ sys/dev/usb/urio.c        26 Apr 2013 15:02:02 -0000
> @@ -328,8 +328,9 @@ urioread(dev_t dev, struct uio *uio, int
>       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");
> +             usbd_setup_xfer(xfer, sc->sc_in_pipe, 0, bufp, tn,
> +                 USBD_NO_COPY | USBD_SYNCHRONOUS, URIO_RW_TIMEOUT, NULL);
> +             err = usbd_transfer(xfer);
>               if (err) {
>                       if (err == USBD_INTERRUPTED)
>                               error = EINTR;
> @@ -390,8 +391,9 @@ uriowrite(dev_t dev, struct uio *uio, in
>  
>               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");
> +             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) {
>                       if (err == USBD_INTERRUPTED)
> Index: sys/dev/usb/usbdi.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/usb/usbdi.c,v
> retrieving revision 1.55
> diff -u -p -r1.55 usbdi.c
> --- sys/dev/usb/usbdi.c       26 Apr 2013 14:19:25 -0000      1.55
> +++ sys/dev/usb/usbdi.c       26 Apr 2013 15:14:07 -0000
> @@ -293,7 +293,7 @@ usbd_transfer(struct usbd_xfer *xfer)
>       struct usb_dma *dmap = &xfer->dmabuf;
>       usbd_status err;
>       u_int size;
> -     int s;
> +     int flags, s;
>  
>       if (usbd_is_dying(pipe->device))
>               return (USBD_IOERROR);
> @@ -351,7 +351,8 @@ usbd_transfer(struct usbd_xfer *xfer)
>       while (!xfer->done) {
>               if (pipe->device->bus->use_polling)
>                       panic("usbd_transfer: not done");
> -             tsleep(xfer, PRIBIO, "usbsyn", 0);
> +             flags = PRIBIO | (xfer->flags & USBD_CATCH ? PCATCH : 0);
> +             tsleep(xfer, flags, "usbsyn", 0);
>       }
>       splx(s);
>       return (xfer->status);
> Index: sys/dev/usb/usbdi.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/usb/usbdi.h,v
> retrieving revision 1.53
> diff -u -p -r1.53 usbdi.h
> --- sys/dev/usb/usbdi.h       26 Apr 2013 14:19:25 -0000      1.53
> +++ sys/dev/usb/usbdi.h       26 Apr 2013 14:20:01 -0000
> @@ -76,6 +76,7 @@ typedef void (*usbd_callback)(struct usb
>  #define USBD_SYNCHRONOUS     0x02    /* wait for completion */
>  /* in usb.h #define USBD_SHORT_XFER_OK       0x04*/  /* allow short reads */
>  #define USBD_FORCE_SHORT_XFER        0x08    /* force last short packet on 
> write */
> +#define USBD_CATCH           0x10    /* catch signals while sleeping */
>  
>  #define USBD_NO_TIMEOUT 0
>  #define USBD_DEFAULT_TIMEOUT 5000 /* ms = 5 s */
> Index: sys/dev/usb/usbdi_util.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/usb/usbdi_util.c,v
> retrieving revision 1.31
> diff -u -p -r1.31 usbdi_util.c
> --- sys/dev/usb/usbdi_util.c  15 Apr 2013 09:23:02 -0000      1.31
> +++ sys/dev/usb/usbdi_util.c  26 Apr 2013 14:20:01 -0000
> @@ -396,90 +396,6 @@ usbd_get_config(struct usbd_device *dev,
>       return (usbd_do_request(dev, &req, conf));
>  }
>  
> -void usbd_bulk_transfer_cb(struct usbd_xfer *xfer, void *priv,
> -    usbd_status status);
> -void
> -usbd_bulk_transfer_cb(struct usbd_xfer *xfer, void *priv,
> -    usbd_status status)
> -{
> -     wakeup(xfer);
> -}
> -
> -usbd_status
> -usbd_bulk_transfer(struct usbd_xfer *xfer, struct usbd_pipe *pipe,
> -    u_int16_t flags, u_int32_t timeout, void *buf, u_int32_t *size, char 
> *lbl)
> -{
> -     usbd_status err;
> -     int s, error, pri;
> -
> -     usbd_setup_xfer(xfer, pipe, 0, buf, *size, flags, timeout,
> -         usbd_bulk_transfer_cb);
> -     DPRINTFN(1, ("usbd_bulk_transfer: start transfer %d bytes\n", *size));
> -     s = splusb();           /* don't want callback until tsleep() */
> -     err = usbd_transfer(xfer);
> -     if (err != USBD_IN_PROGRESS) {
> -             splx(s);
> -             return (err);
> -     }
> -     pri = timeout == 0 ? (PZERO | PCATCH) : PZERO;
> -     error = tsleep((caddr_t)xfer, pri, lbl, 0);
> -     splx(s);
> -     if (error) {
> -             DPRINTF(("usbd_bulk_transfer: tsleep=%d\n", error));
> -             usbd_abort_pipe(pipe);
> -             return (USBD_INTERRUPTED);
> -     }
> -     usbd_get_xfer_status(xfer, NULL, NULL, size, &err);
> -     DPRINTFN(1,("usbd_bulk_transfer: transferred %d\n", *size));
> -     if (err) {
> -             DPRINTF(("usbd_bulk_transfer: error=%d\n", err));
> -             usbd_clear_endpoint_stall(pipe);
> -     }
> -     return (err);
> -}
> -
> -void usbd_intr_transfer_cb(struct usbd_xfer *xfer, void *priv,
> -    usbd_status status);
> -void
> -usbd_intr_transfer_cb(struct usbd_xfer *xfer, void *priv,
> -    usbd_status status)
> -{
> -     wakeup(xfer);
> -}
> -
> -usbd_status
> -usbd_intr_transfer(struct usbd_xfer *xfer, struct usbd_pipe *pipe,
> -    u_int16_t flags, u_int32_t timeout, void *buf, u_int32_t *size, char 
> *lbl)
> -{
> -     usbd_status err;
> -     int s, error, pri;
> -
> -     usbd_setup_xfer(xfer, pipe, 0, buf, *size, flags, timeout,
> -         usbd_intr_transfer_cb);
> -     DPRINTFN(1, ("usbd_intr_transfer: start transfer %d bytes\n", *size));
> -     s = splusb();           /* don't want callback until tsleep() */
> -     err = usbd_transfer(xfer);
> -     if (err != USBD_IN_PROGRESS) {
> -             splx(s);
> -             return (err);
> -     }
> -     pri = timeout == 0 ? (PZERO | PCATCH) : PZERO;
> -     error = tsleep(xfer, pri, lbl, 0);
> -     splx(s);
> -     if (error) {
> -             DPRINTF(("usbd_intr_transfer: tsleep=%d\n", error));
> -             usbd_abort_pipe(pipe);
> -             return (USBD_INTERRUPTED);
> -     }
> -     usbd_get_xfer_status(xfer, NULL, NULL, size, &err);
> -     DPRINTFN(1,("usbd_intr_transfer: transferred %d\n", *size));
> -     if (err) {
> -             DPRINTF(("usbd_intr_transfer: error=%d\n", err));
> -             usbd_clear_endpoint_stall(pipe);
> -     }
> -     return (err);
> -}
> -
>  void
>  usb_detach_wait(struct device *dv)
>  {
> Index: sys/dev/usb/usbdi_util.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/usb/usbdi_util.h,v
> retrieving revision 1.21
> diff -u -p -r1.21 usbdi_util.h
> --- sys/dev/usb/usbdi_util.h  15 Apr 2013 09:23:02 -0000      1.21
> +++ sys/dev/usb/usbdi_util.h  26 Apr 2013 14:20:01 -0000
> @@ -69,13 +69,5 @@ usbd_status        usbd_set_config_no(struct us
>  usbd_status  usbd_set_config_index(struct usbd_device *dev, int index,
>                   int msg);
>  
> -usbd_status  usbd_bulk_transfer(struct usbd_xfer *xfer,
> -                 struct usbd_pipe *pipe, u_int16_t flags, u_int32_t timeout,
> -                 void *buf, u_int32_t *size, char *lbl);
> -
> -usbd_status  usbd_intr_transfer(struct usbd_xfer *xfer,
> -                 struct usbd_pipe *pipe, u_int16_t flags, u_int32_t timeout,
> -                 void *buf, u_int32_t *size, char *lbl);
> -
>  void usb_detach_wait(struct device *);
>  void usb_detach_wakeup(struct device *);
> Index: sys/dev/usb/uscanner.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/usb/uscanner.c,v
> retrieving revision 1.48
> diff -u -p -r1.48 uscanner.c
> --- sys/dev/usb/uscanner.c    15 Apr 2013 09:23:02 -0000      1.48
> +++ sys/dev/usb/uscanner.c    26 Apr 2013 15:01:47 -0000
> @@ -464,11 +464,12 @@ uscanner_do_read(struct uscanner_softc *
>               DPRINTFN(1, ("uscannerread: start transfer %d bytes\n",n));
>               tn = n;
>  
> -             err = usbd_bulk_transfer(
> +             usbd_setup_xfer(
>                       sc->sc_bulkin_xfer, sc->sc_bulkin_pipe,
> -                     USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT,
> -                     sc->sc_bulkin_buffer, &tn,
> -                     "uscnrb");
> +                     0, sc->sc_bulkin_buffer, tn,
> +                     USBD_SHORT_XFER_OK | USBD_SYNCHRONOUS | USBD_CATCH, 0,
> +                     NULL);
> +             err = usbd_transfer(sc->sc_bulkin_xfer);
>               if (err) {
>                       if (err == USBD_INTERRUPTED)
>                               error = EINTR;
> @@ -520,11 +521,11 @@ uscanner_do_write(struct uscanner_softc 
>               if (error)
>                       break;
>               DPRINTFN(1, ("uscanner_do_write: transfer %d bytes\n", n));
> -             err = usbd_bulk_transfer(
> +             usbd_setup_xfer(
>                       sc->sc_bulkout_xfer, sc->sc_bulkout_pipe,
> -                     0, USBD_NO_TIMEOUT,
> -                     sc->sc_bulkout_buffer, &n,
> -                     "uscnwb");
> +                     0, sc->sc_bulkout_buffer, n,
> +                     USBD_SYNCHRONOUS | USBD_CATCH, 0, NULL);
> +             err = usbd_transfer(sc->sc_bulkout_xfer);
>               if (err) {
>                       if (err == USBD_INTERRUPTED)
>                               error = EINTR;
> Index: share/man/man9//Makefile
> ===================================================================
> RCS file: /cvs/src/share/man/man9/Makefile,v
> retrieving revision 1.177
> diff -u -p -r1.177 Makefile
> --- share/man/man9//Makefile  24 Apr 2013 17:29:02 -0000      1.177
> +++ share/man/man9//Makefile  30 Apr 2013 11:28:30 -0000
> @@ -25,7 +25,9 @@ MAN=        altq.9 aml_evalnode.9 atomic.9 audi
>       route.9 rwlock.9 sensor_attach.9 \
>       shutdownhook_establish.9 tsleep.9 spl.9 startuphook_establish.9 \
>       socreate.9 sosplice.9 style.9 syscall.9 systrace.9 sysctl_int.9 \
> -     tc_init.9 time.9 timeout.9 tvtohz.9 uiomove.9 uvm.9 vfs.9 vfs_busy.9 \
> +     tc_init.9 time.9 timeout.9 tvtohz.9 uiomove.9 uvm.9 \
> +     usbd_transfer.9 \
> +     vfs.9 vfs_busy.9 \
>       vfs_cache.9 vaccess.9 vclean.9 vcount.9 vdevgone.9 vfinddev.9 vflush.9 \
>       vflushbuf.9 vget.9 vgone.9 vhold.9 vinvalbuf.9 vnode.9 vnsubr.9 \
>       VOP_GETATTR.9 VOP_LOOKUP.9 vput.9 vrecycle.9 vref.9 vrele.9 \
> @@ -331,6 +333,7 @@ MLINKS+=timeout.9 timeout_add.9 timeout.
>  MLINKS+=tsleep.9 wakeup.9 tsleep.9 msleep.9
>  MLINKS+=tvtohz.9 tstohz.9
>  MLINKS+=uiomove.9 uio.9
> +MLINKS+=usbd_transfer.9 usbd_setup_xfer.9
>  MLINKS+=uvm.9 uvm_init.9 uvm.9 uvm_init_limits.9 uvm.9 uvm_setpagesize.9 \
>       uvm.9 uvm_swap_init.9 uvm.9 uvm_map.9 uvm.9 uvm_map_pageable.9 \
>       uvm.9 uvm_map_pageable_all.9 uvm.9 uvm_map_checkprot.9 \
> Index: share/man/man9//usbd_transfer.9
> ===================================================================
> RCS file: share/man/man9//usbd_transfer.9
> diff -N share/man/man9//usbd_transfer.9
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ share/man/man9//usbd_transfer.9   30 Apr 2013 11:46:51 -0000
> @@ -0,0 +1,102 @@
> +.\" $OpenBSD$
> +.\"
> +.\" Copyright (c) 2013 Martin Pieuchot <m...@openbsd.org>
> +.\"
> +.\" Permission to use, copy, modify, and distribute this software for any
> +.\" purpose with or without fee is hereby granted, provided that the above
> +.\" copyright notice and this permission notice appear in all copies.
> +.\"
> +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> +.\"
> +.Dd $Mdocdate$
> +.Dt USBD_TRANSFER 9
> +.Os
> +.Sh NAME
> +.Nm usbd_setup_xfer , usbd_transfer
> +.Nd submit USB data transfers
> +.Sh SYNOPSIS
> +.In dev/usb/usb.h
> +.In dev/usb/usbdi.h
> +.Ft void
> +.Fn usbd_setup_xfer "struct usbd_xfer *xfer" "struct usbd_pipe *pipe" \
> + "void *priv" "void *buffer" "uint32_t length" "uint16_t flags" \
> + "uint32_t timeout" "usbd_callback callback"
> +.Ft usbd_status
> +.Fn usbd_transfer "struct usbd_xfer *xfer"
> +.Sh DESCRIPTION
> +These functions provide a controller independent mechanism to perform USB
> +data transfers.
> +.Pp
> +The function 
> +.Fn usbd_setup_xfer
> +is used to initialized the structure pointed by
> +.Fa xfer 
> +describing an individual transfer to submit.
> +It takes the following arguments:
> +.Bl -tag -width callback
> +.It Fa xfer
> +A pointer to an existing structure describing a transfer.
> +.It Fa pipe
> +A pointer to a pipe associated to the endpoint for the transfer.
> +.It Fa priv
> +A pointer to a private cookie untouched by the USB stack for re-use in the 
> +.Fa callback .
> +.It Fa buffer
> +A pointer to the data buffer.
> +.It Fa length
> +The total length of the data to read or write.
> +.It Fa flags
> +The characteristics of the transfer as follows:
> +.Bl -tag -width xxx -offset indent
> +.It Dv USBD_NO_COPY
> +Do not copy data between
> +.Fa buffer
> +and the DMA buffer.
> +.It Dv USBD_SYNCHRONOUS
> +Causes
> +.Fn usbd_transfer
> +to sleep until the I/O transfer is complete or the
> +.Fa timeout
> +expires.
> +.It Dv USBD_SHORT_XFER_OK
> +Do not report short reads, when the length of the data read is lower than
> +.Fa length ,
> +as errors.
> +.It Dv USBD_FORCE_SHORT_XFER
> +Submit a supplementary zero length packet at the end of the data if
> +.Fa length
> +is a multiple of the endpoint's wMaxPacketSize.
> +.It Dv USBD_CATCH
> +Used in conjunction with the USBD_SYNCHRONOUS flag to pass the PCATCH flag to
> +.Xr tsleep 9 
> +in order to check for signals before and after sleeping.
> +.El
> +.It Fa timout
> +Timeout of the transfer in milliseconds.
> +.It Fa callback
> +A routine invoked upon completion of the transfer wether successful or not.
> +.El
> +.Pp
> +The function 
> +.Fn usbd_transfer
> +is used to submit the USB transfer described by
> +.Fa xfer
> +to the corresponding
> +.Xr usb 4
> +host controller to perfom I/O with devices.
> +.Pp
> +.Sh CODE REFERENCES
> +These functions are implemented in the file
> +.Pa sys/dev/usb/usbdi.c .
> +.Sh SEE ALSO
> +.Xr usb 4 ,
> +.Xr ehci 4 ,
> +.Xr ohci 4 ,
> +.Xr uhci 4 ,
> +.Xr tsleep 9
> 

-- 
[ Marcus Glocker, mar...@nazgul.ch, mgloc...@openbsd.org               ]

Reply via email to