From owner-p4-projects@FreeBSD.ORG Mon Jul 7 14:45:04 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 6F3EC1065672; Mon, 7 Jul 2008 14:45:04 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 189FA106564A for ; Mon, 7 Jul 2008 14:45:04 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 051DF8FC14 for ; Mon, 7 Jul 2008 14:45:04 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m67Ej3QR048712 for ; Mon, 7 Jul 2008 14:45:03 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.2/8.14.1/Submit) id m67Ej3XF048710 for perforce@freebsd.org; Mon, 7 Jul 2008 14:45:03 GMT (envelope-from hselasky@FreeBSD.org) Date: Mon, 7 Jul 2008 14:45:03 GMT Message-Id: <200807071445.m67Ej3XF048710@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 144828 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 07 Jul 2008 14:45:04 -0000 http://perforce.freebsd.org/chv.cgi?CH=144828 Change 144828 by hselasky@hselasky_laptop001 on 2008/07/07 14:44:04 More patches to add support for LibUSB 1.0 - allow multiple instances when opening an endpoint Affected files ... .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_core.h#9 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.c#11 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.h#6 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_generic.c#9 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_transfer.c#11 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_core.h#9 (text+ko) ==== @@ -295,6 +295,8 @@ #define USB_NO_TIMEOUT 0 #define USB_DEFAULT_TIMEOUT 5000 /* 5000 ms = 5 seconds */ + uint32_t max_frame_count; /* initial value of "nframes" after + * setup */ uint32_t nframes; /* number of USB frames to transfer */ uint32_t aframes; /* actual number of USB frames * transferred */ ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.c#11 (text+ko) ==== @@ -71,7 +71,6 @@ static uint32_t usb2_path_convert_one(const char **pp); static uint32_t usb2_path_convert(const char *path); static uint8_t usb2_match_perm(struct usb2_perm *psystem, struct usb2_perm *puser); -static struct usb2_fifo *usb2_fifo_alloc(uint8_t fifo_index); static int usb2_fifo_open(struct usb2_fifo *f, struct file *fp, struct thread *td, int fflags); static void usb2_fifo_close(struct usb2_fifo *f, struct thread *td, int fflags); static void usb2_dev_init(void *arg); @@ -81,6 +80,8 @@ static void usb2_fifo_wakeup(struct usb2_fifo *f); static void usb2_fifo_check_methods(struct usb2_fifo_methods *pm); static void usb2_clone(void *arg, USB_UCRED char *name, int namelen, struct cdev **dev); +static struct usb2_fifo *usb2_fifo_alloc(void); +static struct usb2_pipe *usb2_dev_get_pipe(struct usb2_device *udev, uint8_t iface_index, uint8_t ep_index, uint8_t dir); static d_fdopen_t usb2_fdopen; static d_close_t usb2_close; @@ -200,7 +201,7 @@ temp = usb2_path_convert_one(&path); - if (temp >= USB_FIFO_MAX) { + if (temp >= ((USB_FIFO_MAX / 2) + (USB_EP_MAX / 2))) { return (0 - 1); } devloc += (temp * USB_IFACE_MAX * USB_DEV_MAX * USB_BUS_MAX); @@ -280,25 +281,32 @@ usb2_error_t usb2_ref_device(struct file *fp, struct usb2_location *ploc, uint32_t devloc) { + struct usb2_fifo **ppf; + struct usb2_fifo *f; int fflags; if (fp) { - /* get the device location */ + /* + * Get the device location which should be valid and + * correct: + */ devloc = USB_P2U(fp->f_data); fflags = fp->f_flag; /* only ref FIFO */ ploc->is_uref = 0; + /* devloc should be valid */ } else { /* only ref device */ fflags = 0; + /* search for FIFO */ ploc->is_uref = 1; + /* check "devloc" */ + if (devloc >= (USB_BUS_MAX * USB_DEV_MAX * + USB_IFACE_MAX * ((USB_EP_MAX / 2) + (USB_FIFO_MAX / 2)))) { + return (USB_ERR_INVAL); + } } - if (devloc > (USB_BUS_MAX * USB_DEV_MAX * - USB_EP_MAX * USB_IFACE_MAX)) { - /* invalid device location */ - return (USB_ERR_INVAL); - } /* store device location */ ploc->devloc = devloc; ploc->bus_index = devloc % USB_BUS_MAX; @@ -306,7 +314,7 @@ ploc->iface_index = (devloc / (USB_BUS_MAX * USB_DEV_MAX)) % USB_IFACE_MAX; ploc->ep_index = (devloc / (USB_BUS_MAX * USB_DEV_MAX * - USB_IFACE_MAX)) % USB_EP_MAX; + USB_IFACE_MAX)); mtx_lock(&usb2_ref_lock); ploc->bus = devclass_get_softc(usb2_devclass_ptr, ploc->bus_index); @@ -339,50 +347,68 @@ goto error; } } - /* check TX FIFO */ - - ploc->txfifo = ploc->udev->fifo[(2 * ploc->ep_index) + USB_FIFO_TX]; - if ((ploc->txfifo != NULL) && - (ploc->txfifo->refcount != USB_FIFO_REF_MAX) && - (ploc->txfifo->curr_file == fp)) { - ploc->is_write = 1; /* ref */ + /* check if we are doing an open */ + if (fp == NULL) { + /* set defaults */ + ploc->txfifo = NULL; + ploc->rxfifo = NULL; + ploc->is_write = 0; + ploc->is_read = 0; } else { + /* check for write */ if (fflags & FWRITE) { - goto error; + ppf = ploc->udev->fifo; + f = ppf[ploc->ep_index + USB_FIFO_TX]; + ploc->txfifo = f; + ploc->is_write = 1; /* ref */ + if ((f == NULL) || + (f->refcount == USB_FIFO_REF_MAX) || + (f->curr_file != fp)) { + goto error; + } + } else { + ploc->txfifo = NULL; + ploc->is_write = 0; /* no ref */ } - ploc->is_write = 0; /* no ref */ - ploc->txfifo = NULL; /* no access */ - } - /* check RX FIFO */ - - ploc->rxfifo = ploc->udev->fifo[(2 * ploc->ep_index) + USB_FIFO_RX]; - if ((ploc->rxfifo != NULL) && - (ploc->rxfifo->refcount != USB_FIFO_REF_MAX) && - (ploc->rxfifo->curr_file == fp)) { - ploc->is_read = 1; /* ref */ - } else { + /* check for read */ if (fflags & FREAD) { - goto error; + ppf = ploc->udev->fifo; + f = ppf[ploc->ep_index + USB_FIFO_RX]; + ploc->rxfifo = f; + ploc->is_read = 1; /* ref */ + if ((f == NULL) || + (f->refcount == USB_FIFO_REF_MAX) || + (f->curr_file != fp)) { + goto error; + } + } else { + ploc->rxfifo = NULL; + ploc->is_read = 0; /* no ref */ } - ploc->is_read = 0; /* no ref */ - ploc->rxfifo = NULL; /* no access */ } /* when everything is OK we increment the refcounts */ - - if (ploc->is_uref) { - DPRINTF(1, "ref udev\n"); - ploc->udev->refcount++; - } if (ploc->is_write) { DPRINTF(1, "ref write\n"); ploc->txfifo->refcount++; + if (ploc->txfifo->flag_no_uref == 0) { + /* we need extra locking */ + ploc->is_uref = 1; + } } if (ploc->is_read) { DPRINTF(1, "ref read\n"); ploc->rxfifo->refcount++; + if (ploc->rxfifo->flag_no_uref == 0) { + /* we need extra locking */ + ploc->is_uref = 1; + } } + if (ploc->is_uref) { + DPRINTF(1, "ref udev\n"); + ploc->udev->refcount++; + } mtx_unlock(&usb2_ref_lock); if (ploc->is_uref) { @@ -435,21 +461,178 @@ } static struct usb2_fifo * -usb2_fifo_alloc(uint8_t fifo_index) +usb2_fifo_alloc(void) { struct usb2_fifo *f; f = malloc(sizeof(*f), M_USBDEV, M_WAITOK | M_ZERO); - if (f) { cv_init(&f->cv_io, "FIFO-IO"); cv_init(&f->cv_drain, "FIFO-DRAIN"); f->refcount = 1; - f->fifo_index = fifo_index; } return (f); } +/*------------------------------------------------------------------------* + * usb2_fifo_create + *------------------------------------------------------------------------*/ +static int +usb2_fifo_create(struct usb2_location *ploc, uint32_t *pdevloc, int fflags) +{ + struct usb2_device *udev = ploc->udev; + struct usb2_fifo *f; + struct usb2_pipe *pipe; + uint8_t iface_index = ploc->iface_index; + uint8_t dev_ep_index = ploc->ep_index; + uint8_t n; + uint8_t is_tx; + uint8_t is_rx; + uint8_t no_null; + uint8_t is_busy; + + is_tx = (fflags & FWRITE) ? 1 : 0; + is_rx = (fflags & FREAD) ? 1 : 0; + no_null = 1; + is_busy = 0; + + /* search for a free FIFO slot */ + + for (n = 0;; n += 2) { + + if (n == USB_FIFO_MAX) { + if (no_null) { + no_null = 0; + n = 0; + } else { + /* end of FIFOs reached */ + return (ENOMEM); + } + } + /* Check for TX FIFO */ + if (is_tx) { + f = udev->fifo[n + USB_FIFO_TX]; + if (f != NULL) { + if (f->dev_ep_index != dev_ep_index) { + /* wrong endpoint index */ + continue; + } + if ((dev_ep_index != 0) && + (f->iface_index != iface_index)) { + /* wrong interface index */ + continue; + } + if (f->curr_file != NULL) { + /* FIFO is opened */ + is_busy = 1; + continue; + } + } else if (no_null) { + continue; + } + } + /* Check for RX FIFO */ + if (is_rx) { + f = udev->fifo[n + USB_FIFO_RX]; + if (f != NULL) { + if (f->dev_ep_index != dev_ep_index) { + /* wrong endpoint index */ + continue; + } + if ((dev_ep_index != 0) && + (f->iface_index != iface_index)) { + /* wrong interface index */ + continue; + } + if (f->curr_file != NULL) { + /* FIFO is opened */ + is_busy = 1; + continue; + } + } else if (no_null) { + continue; + } + } + break; + } + + if (no_null == 0) { + if (dev_ep_index >= (USB_EP_MAX / 2)) { + /* we don't create any endpoints in this range */ + return (is_busy ? EBUSY : EINVAL); + } + } + /* Check TX FIFO */ + if (is_tx && + (udev->fifo[n + USB_FIFO_TX] == NULL)) { + pipe = usb2_dev_get_pipe(udev, + iface_index, dev_ep_index, USB_FIFO_TX); + if (pipe == NULL) { + return (EINVAL); + } + f = usb2_fifo_alloc(); + if (f == NULL) { + return (ENOMEM); + } + /* update some fields */ + f->fifo_index = n + USB_FIFO_TX; + f->dev_ep_index = dev_ep_index; + f->priv_mtx = udev->default_mtx; + f->priv_sc0 = pipe; + f->methods = &usb2_ugen_methods; + f->iface_index = iface_index; + f->udev = udev; + if (dev_ep_index != 0) { + f->flag_no_uref = 1; + } + mtx_lock(&usb2_ref_lock); + udev->fifo[n + USB_FIFO_TX] = f; + mtx_unlock(&usb2_ref_lock); + } + /* Check RX FIFO */ + if (is_rx && + (udev->fifo[n + USB_FIFO_RX] == NULL)) { + + pipe = usb2_dev_get_pipe(udev, + iface_index, dev_ep_index, USB_FIFO_RX); + if (pipe == NULL) { + return (EINVAL); + } + f = usb2_fifo_alloc(); + if (f == NULL) { + return (ENOMEM); + } + /* update some fields */ + f->fifo_index = n + USB_FIFO_RX; + f->dev_ep_index = dev_ep_index; + f->priv_mtx = udev->default_mtx; + f->priv_sc0 = pipe; + f->methods = &usb2_ugen_methods; + f->iface_index = iface_index; + f->udev = udev; + if (dev_ep_index != 0) { + f->flag_no_uref = 1; + } + mtx_lock(&usb2_ref_lock); + udev->fifo[n + USB_FIFO_RX] = f; + mtx_unlock(&usb2_ref_lock); + } + if (is_tx) { + ploc->txfifo = udev->fifo[n + USB_FIFO_TX]; + } + if (is_rx) { + ploc->rxfifo = udev->fifo[n + USB_FIFO_RX]; + } + /* replace endpoint index by FIFO index */ + + (*pdevloc) %= (USB_BUS_MAX * USB_DEV_MAX * USB_IFACE_MAX); + (*pdevloc) += (USB_BUS_MAX * USB_DEV_MAX * USB_IFACE_MAX) * n; + + /* complete */ + + return (0); +} + void usb2_fifo_free(struct usb2_fifo *f) { @@ -470,7 +653,8 @@ /* delink ourselves to stop calls from userland */ if ((f->fifo_index < USB_FIFO_MAX) && - (f->udev != NULL)) { + (f->udev != NULL) && + (f->udev->fifo[f->fifo_index] == f)) { f->udev->fifo[f->fifo_index] = NULL; } else { DPRINTF(-1, "USB FIFO %p has not been linked!\n", f); @@ -505,44 +689,17 @@ return; } -/*------------------------------------------------------------------------* - * usb2_fifo_check - *------------------------------------------------------------------------*/ -static void -usb2_fifo_check(struct usb2_location *ploc, int fflags) +static struct usb2_pipe * +usb2_dev_get_pipe(struct usb2_device *udev, + uint8_t iface_index, uint8_t ep_index, uint8_t dir) { - struct usb2_device *udev; struct usb2_pipe *pipe; - struct usb2_fifo *f; - uint8_t ep_index; uint8_t ep_dir; - udev = ploc->udev; - ep_index = ploc->ep_index; - if (fflags & FREAD) { - f = ploc->rxfifo; - } else if (fflags & FWRITE) { - f = ploc->txfifo; - } else { - /* nothing to do */ - return; - } - - if (f) { - /* nothing do to - we already have a FIFO */ - DPRINTF(1, "has FIFO\n"); - return; - } - if (ep_index >= 16) { - /* nothing to do - these are virtual endpoints */ - DPRINTF(1, "VEP\n"); - return; - } - /* automatically create a generic endpoint */ if (ep_index == 0) { pipe = &(udev->default_pipe); } else { - if (fflags & FREAD) { + if (dir == USB_FIFO_RX) { if (udev->flags.usb2_mode == USB_MODE_HOST) { ep_dir = UE_DIR_IN; } else { @@ -556,53 +713,26 @@ } } pipe = usb2_get_pipe_by_addr(udev, ep_index | ep_dir); - if (pipe == NULL) { - /* if the pipe does not exist then return */ - return; - } - if (pipe->edesc == NULL) { - /* invalid pipe */ - return; - } - if (pipe->iface_index != ploc->iface_index) { + } + + if (pipe == NULL) { + /* if the pipe does not exist then return */ + return (NULL); + } + if (pipe->edesc == NULL) { + /* invalid pipe */ + return (NULL); + } + if (ep_index != 0) { + if (pipe->iface_index != iface_index) { /* * Permissions violation - trying to access a * pipe that does not belong to the interface. */ - return; + return (NULL); } } - if (fflags & FREAD) { - f = usb2_fifo_alloc((2 * ep_index) + USB_FIFO_RX); - } else { - f = usb2_fifo_alloc((2 * ep_index) + USB_FIFO_TX); - } - if (f == NULL) { - /* could not create FIFO */ - return; - } - /* update some fields */ - f->priv_mtx = udev->default_mtx; - f->priv_sc0 = pipe; - f->unit = 0; - f->methods = &usb2_ugen_methods; - f->iface_index = ploc->iface_index; - f->udev = udev; - - /* check the methods */ - usb2_fifo_check_methods(f->methods); - - /* register our FIFO */ - mtx_lock(&usb2_ref_lock); - if (fflags & FREAD) { - udev->fifo[(2 * ep_index) + USB_FIFO_RX] = f; - } else { - udev->fifo[(2 * ep_index) + USB_FIFO_TX] = f; - } - mtx_unlock(&usb2_ref_lock); - - /* we are done */ - return; + return (pipe); /* success */ } /*------------------------------------------------------------------------* @@ -662,7 +792,9 @@ f->async_p = NULL; /* set which file we belong to */ + mtx_lock(&usb2_ref_lock); f->curr_file = fp; + mtx_unlock(&usb2_ref_lock); /* reset queue */ usb2_fifo_reset(f); @@ -841,16 +973,7 @@ mtx_lock(loc.udev->default_mtx); /* scan down the permissions tree */ - - if ((fflags & FWRITE) && (loc.txfifo != NULL) && - (loc.txfifo->iface_index != loc.iface_index)) { - /* the FIFO does not belong to the specified interface */ - err = EPERM; - } else if ((fflags & FREAD) && (loc.rxfifo != NULL) && - (loc.rxfifo->iface_index != loc.iface_index)) { - /* the FIFO does not belong to the specified interface */ - err = EPERM; - } else if ((loc.ep_index != 0) && loc.iface && + if ((loc.ep_index != 0) && loc.iface && usb2_match_perm(&perm, &loc.iface->perm)) { /* we got access through the interface */ err = 0; @@ -875,18 +998,15 @@ usb2_unref_device(&loc); return (err); } - usb2_fifo_check(&loc, fflags & FREAD); - usb2_fifo_check(&loc, fflags & FWRITE); - usb2_unref_device(&loc); - - /* try to refer the device and associated FIFOs again */ - err = usb2_ref_device(NULL, &loc, devloc); + /* create FIFOs, if any */ + err = usb2_fifo_create(&loc, &devloc, fflags); + /* check for error */ if (err) { - return (ENXIO); + usb2_unref_device(&loc); + return (err); } if (fflags & FREAD) { - err = usb2_fifo_open(loc.rxfifo, fp, td, - fflags); + err = usb2_fifo_open(loc.rxfifo, fp, td, fflags); if (err) { DPRINTF(1, "read open failed\n"); usb2_unref_device(&loc); @@ -894,8 +1014,7 @@ } } if (fflags & FWRITE) { - err = usb2_fifo_open(loc.txfifo, fp, td, - fflags); + err = usb2_fifo_open(loc.txfifo, fp, td, fflags); if (err) { DPRINTF(1, "write open failed\n"); if (fflags & FREAD) { @@ -911,7 +1030,7 @@ * directly and don't have to create another device: */ fp->f_ops = &usb2_ops_f; - fp->f_data = ((uint8_t *)0) + loc.devloc; + fp->f_data = ((uint8_t *)0) + devloc; usb2_unref_device(&loc); @@ -968,6 +1087,8 @@ usb2_dev_init(void *arg) { mtx_init(&usb2_ref_lock, "USB ref mutex", NULL, MTX_DEF); + /* check the UGEN methods */ + usb2_fifo_check_methods(&usb2_ugen_methods); return; } @@ -1623,24 +1744,32 @@ if (pm == NULL) return (EINVAL); + /* check the methods */ + usb2_fifo_check_methods(pm); + if (priv_mtx == NULL) priv_mtx = &Giant; /* search for a free FIFO slot */ - - for (n = USB_EP_MAX;; n += 2) { + for (n = 0;; n += 2) { if (n == USB_FIFO_MAX) { + /* end of FIFOs reached */ return (ENOMEM); } - if ((udev->fifo[n + USB_FIFO_TX] == NULL) && - (udev->fifo[n + USB_FIFO_RX] == NULL)) { - break; + /* Check for TX FIFO */ + if (udev->fifo[n + USB_FIFO_TX] != NULL) { + continue; + } + /* Check for RX FIFO */ + if (udev->fifo[n + USB_FIFO_RX] != NULL) { + continue; } + break; } - f_tx = usb2_fifo_alloc(n + USB_FIFO_TX); /* write FIFO */ - f_rx = usb2_fifo_alloc(n + USB_FIFO_RX); /* read FIFO */ + f_tx = usb2_fifo_alloc(); + f_rx = usb2_fifo_alloc(); if ((f_tx == NULL) || (f_rx == NULL)) { usb2_fifo_free(f_tx); @@ -1649,29 +1778,30 @@ } /* initialise FIFO structures */ + f_tx->fifo_index = n + USB_FIFO_TX; + f_tx->dev_ep_index = (n / 2) + (USB_EP_MAX / 2); f_tx->priv_mtx = priv_mtx; f_tx->priv_sc0 = priv_sc; - f_tx->unit = unit; + f_tx->methods = pm; f_tx->iface_index = iface_index; - f_tx->methods = pm; f_tx->udev = udev; + f_tx->flag_no_uref = 1; + f_rx->fifo_index = n + USB_FIFO_RX; + f_rx->dev_ep_index = (n / 2) + (USB_EP_MAX / 2); f_rx->priv_mtx = priv_mtx; f_rx->priv_sc0 = priv_sc; - f_rx->unit = unit; + f_rx->methods = pm; f_rx->iface_index = iface_index; - f_rx->methods = pm; f_rx->udev = udev; - - /* check the methods */ - usb2_fifo_check_methods(pm); + f_rx->flag_no_uref = 1; f_sc->fp[USB_FIFO_TX] = f_tx; f_sc->fp[USB_FIFO_RX] = f_rx; mtx_lock(&usb2_ref_lock); - udev->fifo[n + USB_FIFO_TX] = f_tx; - udev->fifo[n + USB_FIFO_RX] = f_rx; + udev->fifo[f_tx->fifo_index] = f_tx; + udev->fifo[f_rx->fifo_index] = f_rx; mtx_unlock(&usb2_ref_lock); if (snprintf(src, sizeof(src), @@ -1679,7 +1809,7 @@ device_get_unit(udev->bus->bdev), udev->device_index, iface_index, - n / 2)) { + f_tx->dev_ep_index)) { /* ignore */ } for (n = 0; n != 4; n++) { ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.h#6 (text+ko) ==== @@ -83,8 +83,9 @@ void *queue_data; uint32_t timeout; /* timeout in milliseconds */ uint32_t bufsize; /* BULK and INTERRUPT buffer size */ - uint16_t unit; uint16_t nframes; /* for isochronous mode */ + uint16_t dev_ep_index; /* our device endpoint index */ + uint8_t flag_no_uref; /* set if FIFO is not control endpoint */ uint8_t flag_sleeping; /* set if FIFO is sleeping */ uint8_t flag_iserror; /* set if FIFO error happened */ uint8_t flag_isselect; /* set if FIFO is selected */ ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_generic.c#9 (text+ko) ==== @@ -575,7 +575,7 @@ { DPRINTF(1, "index %u\n", index); - if (f->fifo_index >= 2) { + if (f->flag_no_uref) { /* not the control endpoint - just forget it */ return (EINVAL); } @@ -604,7 +604,7 @@ { DPRINTF(1, "%u, %u\n", iface_index, alt_index); - if (f->fifo_index >= 2) { + if (f->flag_no_uref) { /* not the control endpoint - just forget it */ return (EINVAL); } @@ -640,7 +640,7 @@ DPRINTF(5, "\n"); - if (f->fifo_index >= 2) { + if (f->flag_no_uref) { /* control endpoint only */ return (EINVAL); } @@ -689,7 +689,7 @@ uint16_t size = sizeof(f->udev->bus->scratch[0].data); int error; - if (f->fifo_index >= 2) { + if (f->flag_no_uref) { /* control endpoint only */ return (EINVAL); } @@ -735,7 +735,7 @@ uint8_t i; uint8_t max; - if (f->fifo_index >= 2) { + if (f->flag_no_uref) { /* control endpoint only */ return (EINVAL); } @@ -802,7 +802,7 @@ uint8_t isread; void *data = NULL; - if (f->fifo_index >= 2) { + if (f->flag_no_uref) { /* control endpoint only */ return (EINVAL); } @@ -883,7 +883,7 @@ struct usb2_device *udev = f->udev; int error; - if (f->fifo_index >= 2) { + if (f->flag_no_uref) { /* control endpoint only */ return (EINVAL); } @@ -1122,7 +1122,7 @@ int error; DPRINTF(5, "cmd=%08lx\n", cmd); - if (f->fifo_index >= 2) { + if (f->flag_no_uref) { mtx_lock(f->priv_mtx); error = ugen_iface_ioctl(f, cmd, addr); mtx_unlock(f->priv_mtx); ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_transfer.c#11 (text+ko) ==== @@ -585,6 +585,10 @@ parm->err = USB_ERR_INVAL; goto done; } + /* initialize max frame count */ + + xfer->max_frame_count = xfer->nframes; + /* initialize frame buffers */ if (parm->buf) { @@ -614,6 +618,7 @@ xfer->max_packet_size = 1; xfer->max_data_length = 0; xfer->nframes = 0; + xfer->max_frame_count = 0; } return; }