From owner-svn-src-all@FreeBSD.ORG Sat Feb 28 17:14:04 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 06B0A106564A; Sat, 28 Feb 2009 17:14:04 +0000 (UTC) (envelope-from thompsa@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id E76128FC08; Sat, 28 Feb 2009 17:14:03 +0000 (UTC) (envelope-from thompsa@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n1SHE3vh015518; Sat, 28 Feb 2009 17:14:03 GMT (envelope-from thompsa@svn.freebsd.org) Received: (from thompsa@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n1SHE3r5015514; Sat, 28 Feb 2009 17:14:03 GMT (envelope-from thompsa@svn.freebsd.org) Message-Id: <200902281714.n1SHE3r5015514@svn.freebsd.org> From: Andrew Thompson Date: Sat, 28 Feb 2009 17:14:03 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r189172 - head/sys/dev/usb X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 28 Feb 2009 17:14:04 -0000 Author: thompsa Date: Sat Feb 28 17:14:03 2009 New Revision: 189172 URL: http://svn.freebsd.org/changeset/base/189172 Log: - Remove the usb interface number from the device nodes as it is not needed. - Do not recreate the device nodes in set_alt_interface as the endpoints do not change. Submitted by: Hans Petter Selasky Modified: head/sys/dev/usb/usb_dev.c head/sys/dev/usb/usb_dev.h head/sys/dev/usb/usb_device.c head/sys/dev/usb/usb_device.h Modified: head/sys/dev/usb/usb_dev.c ============================================================================== --- head/sys/dev/usb/usb_dev.c Sat Feb 28 17:01:55 2009 (r189171) +++ head/sys/dev/usb/usb_dev.c Sat Feb 28 17:14:03 2009 (r189172) @@ -82,7 +82,7 @@ static int usb2_fifo_uiomove(struct usb2 static void usb2_fifo_check_methods(struct usb2_fifo_methods *); static struct usb2_fifo *usb2_fifo_alloc(void); static struct usb2_pipe *usb2_dev_get_pipe(struct usb2_device *, uint8_t, - uint8_t, uint8_t); + uint8_t); static void usb2_loc_fill(struct usb2_fs_privdata *, struct usb2_cdev_privdata *); static void usb2_close(void *); @@ -140,7 +140,6 @@ usb2_loc_fill(struct usb2_fs_privdata* p { cpd->bus_index = pd->bus_index; cpd->dev_index = pd->dev_index; - cpd->iface_index = pd->iface_index; cpd->ep_addr = pd->ep_addr; cpd->fifo_index = pd->fifo_index; } @@ -238,19 +237,6 @@ usb2_ref_device(struct usb2_cdev_privdat } } - /* check if we require an interface */ - cpd->iface = usb2_get_iface(cpd->udev, cpd->iface_index); - if (dev_ep_index != 0) { - /* non control endpoint - we need an interface */ - if (cpd->iface == NULL) { - DPRINTFN(2, "no iface\n"); - goto error; - } - if (cpd->iface->idesc == NULL) { - DPRINTFN(2, "no idesc\n"); - goto error; - } - } /* when everything is OK we increment the refcounts */ if (cpd->is_write) { DPRINTFN(2, "ref write\n"); @@ -394,7 +380,6 @@ usb2_fifo_create(struct usb2_cdev_privda struct usb2_device *udev = cpd->udev; struct usb2_fifo *f; struct usb2_pipe *pipe; - uint8_t iface_index = cpd->iface_index; uint8_t n; uint8_t is_tx; uint8_t is_rx; @@ -449,11 +434,6 @@ usb2_fifo_create(struct usb2_cdev_privda /* wrong endpoint index */ continue; } - if (ep != 0 && - f->iface_index != iface_index) { - /* wrong interface index */ - continue; - } if (f->opened) { /* FIFO is opened */ is_busy = 1; @@ -471,11 +451,6 @@ usb2_fifo_create(struct usb2_cdev_privda /* wrong endpoint index */ continue; } - if (ep != 0 && - f->iface_index != iface_index) { - /* wrong interface index */ - continue; - } if (f->opened) { /* FIFO is opened */ is_busy = 1; @@ -499,8 +474,8 @@ usb2_fifo_create(struct usb2_cdev_privda if (is_tx && (udev->fifo[n + USB_FIFO_TX] == NULL)) { pipe = usb2_dev_get_pipe(udev, - iface_index, ep, USB_FIFO_TX); - DPRINTFN(5, "dev_get_pipe(%d, 0x%x, 0x%x)\n", iface_index, ep, USB_FIFO_TX); + ep, USB_FIFO_TX); + DPRINTFN(5, "dev_get_pipe(%d, 0x%x)\n", ep, USB_FIFO_TX); if (pipe == NULL) { DPRINTFN(5, "dev_get_pipe returned NULL\n"); return (EINVAL); @@ -516,7 +491,7 @@ usb2_fifo_create(struct usb2_cdev_privda f->priv_mtx = udev->default_mtx; f->priv_sc0 = pipe; f->methods = &usb2_ugen_methods; - f->iface_index = iface_index; + f->iface_index = pipe->iface_index; f->udev = udev; mtx_lock(&usb2_ref_lock); udev->fifo[n + USB_FIFO_TX] = f; @@ -527,8 +502,8 @@ usb2_fifo_create(struct usb2_cdev_privda (udev->fifo[n + USB_FIFO_RX] == NULL)) { pipe = usb2_dev_get_pipe(udev, - iface_index, ep, USB_FIFO_RX); - DPRINTFN(5, "dev_get_pipe(%d, 0x%x, 0x%x)\n", iface_index, ep, USB_FIFO_RX); + ep, USB_FIFO_RX); + DPRINTFN(5, "dev_get_pipe(%d, 0x%x)\n", ep, USB_FIFO_RX); if (pipe == NULL) { DPRINTFN(5, "dev_get_pipe returned NULL\n"); return (EINVAL); @@ -544,7 +519,7 @@ usb2_fifo_create(struct usb2_cdev_privda f->priv_mtx = udev->default_mtx; f->priv_sc0 = pipe; f->methods = &usb2_ugen_methods; - f->iface_index = iface_index; + f->iface_index = pipe->iface_index; f->udev = udev; mtx_lock(&usb2_ref_lock); udev->fifo[n + USB_FIFO_RX] = f; @@ -624,7 +599,7 @@ usb2_fifo_free(struct usb2_fifo *f) static struct usb2_pipe * usb2_dev_get_pipe(struct usb2_device *udev, - uint8_t iface_index, uint8_t ep_index, uint8_t dir) + uint8_t ep_index, uint8_t dir) { struct usb2_pipe *pipe; uint8_t ep_dir; @@ -656,15 +631,6 @@ usb2_dev_get_pipe(struct usb2_device *ud /* 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 (NULL); - } - } return (pipe); /* success */ } @@ -1059,7 +1025,12 @@ usb2_ioctl(struct cdev *dev, u_long cmd, if (err != 0) return (err); - err = usb2_ref_device(cpd, 1); + /* + * Performance optimistaion: We try to check for IOCTL's that + * don't need the USB reference first. Then we grab the USB + * reference if we need it! + */ + err = usb2_ref_device(cpd, 0 /* no uref */ ); if (err) { return (ENXIO); } @@ -1719,7 +1690,6 @@ usb2_fifo_attach(struct usb2_device *ude pd = malloc(sizeof(struct usb2_fs_privdata), M_USBDEV, M_WAITOK | M_ZERO); pd->bus_index = device_get_unit(udev->bus->bdev); pd->dev_index = udev->device_index; - pd->iface_index = iface_index; pd->ep_addr = -1; /* not an endpoint */ pd->fifo_index = f_tx->fifo_index; pd->mode = FREAD|FWRITE; Modified: head/sys/dev/usb/usb_dev.h ============================================================================== --- head/sys/dev/usb/usb_dev.h Sat Feb 28 17:01:55 2009 (r189171) +++ head/sys/dev/usb/usb_dev.h Sat Feb 28 17:14:03 2009 (r189172) @@ -92,7 +92,6 @@ struct usb2_cdev_privdata { struct usb2_fifo *txfifo; int bus_index; /* bus index */ int dev_index; /* device index */ - int iface_index; /* interface index */ int ep_addr; /* endpoint address */ uint8_t fifo_index; /* FIFO index */ uint8_t is_read; /* location has read access */ @@ -105,7 +104,6 @@ struct usb2_cdev_privdata { struct usb2_fs_privdata { int bus_index; int dev_index; - int iface_index; int ep_addr; int mode; int fifo_index; Modified: head/sys/dev/usb/usb_device.c ============================================================================== --- head/sys/dev/usb/usb_device.c Sat Feb 28 17:01:55 2009 (r189171) +++ head/sys/dev/usb/usb_device.c Sat Feb 28 17:14:03 2009 (r189172) @@ -74,7 +74,7 @@ static usb2_error_t usb2_fill_iface_data uint8_t); static void usb2_notify_addq(const char *type, struct usb2_device *); static void usb2_fifo_free_wrap(struct usb2_device *, uint8_t, uint8_t); -static struct cdev *usb2_make_dev(struct usb2_device *, int, int, int); +static struct cdev *usb2_make_dev(struct usb2_device *, int, int); static void usb2_cdev_create(struct usb2_device *); static void usb2_cdev_free(struct usb2_device *); static void usb2_cdev_cleanup(void *); @@ -421,7 +421,6 @@ usb2_fill_iface_data(struct usb2_device iface->idesc = id; iface->alt_index = alt_index; iface->parent_iface_index = USB_IFACE_INDEX_ANY; - iface->ep_in_mask = iface->ep_out_mask = 0; nendpt = id->bNumEndpoints; DPRINTFN(5, "found idesc nendpt=%d\n", nendpt); @@ -445,14 +444,6 @@ usb2_fill_iface_data(struct usb2_device found: ed = (void *)desc; - /* Fill in the endpoint bitmasks */ - if (ed->bEndpointAddress & UE_DIR_IN) - iface->ep_in_mask |= - 1 << UE_GET_ADDR(ed->bEndpointAddress); - else - iface->ep_out_mask |= - 1 << UE_GET_ADDR(ed->bEndpointAddress); - /* find a free pipe */ while (pipe != pipe_end) { if (pipe->edesc == NULL) { @@ -730,7 +721,6 @@ usb2_set_alt_interface_index(struct usb2 * Free all generic FIFOs for this interface, except control * endpoint FIFOs: */ - usb2_cdev_free(udev); usb2_fifo_free_wrap(udev, iface_index, 0); err = usb2_fill_iface_data(udev, iface_index, alt_index); @@ -740,9 +730,6 @@ usb2_set_alt_interface_index(struct usb2 err = usb2_req_set_alt_interface_no(udev, NULL, iface_index, iface->idesc->bAlternateSetting); - /* create device nodes for each endpoint */ - usb2_cdev_create(udev); - done: if (do_unlock) { sx_unlock(udev->default_sx + 1); @@ -1447,7 +1434,7 @@ usb2_alloc_device(device_t parent_dev, s udev->device_index = device_index; /* Create the control endpoint device */ - udev->default_dev = usb2_make_dev(udev, 0 , 0, FREAD|FWRITE); + udev->default_dev = usb2_make_dev(udev, 0, FREAD|FWRITE); /* Create a link from /dev/ugenX.X to the default endpoint */ snprintf(udev->ugen_name, sizeof(udev->ugen_name), USB_GENERIC_NAME "%u.%u", device_get_unit(bus->bdev), @@ -1720,7 +1707,7 @@ done: } static struct cdev * -usb2_make_dev(struct usb2_device *udev, int iface_index, int ep, int mode) +usb2_make_dev(struct usb2_device *udev, int ep, int mode) { struct usb2_fs_privdata* pd; char devname[20]; @@ -1730,14 +1717,13 @@ usb2_make_dev(struct usb2_device *udev, M_WAITOK | M_ZERO); pd->bus_index = device_get_unit(udev->bus->bdev); pd->dev_index = udev->device_index; - pd->iface_index = iface_index; pd->ep_addr = ep; pd->mode = mode; /* Now, create the device itself */ - snprintf(devname, sizeof(devname), "%u.%u.%u.%u", + snprintf(devname, sizeof(devname), "%u.%u.%u", pd->bus_index, pd->dev_index, - pd->iface_index, pd->ep_addr); + pd->ep_addr); pd->cdev = make_dev(&usb2_devsw, 0, UID_ROOT, GID_OPERATOR, 0600, USB_DEVICE_DIR "/%s", devname); pd->cdev->si_drv1 = pd; @@ -1748,20 +1734,18 @@ usb2_make_dev(struct usb2_device *udev, static void usb2_cdev_create(struct usb2_device *udev) { - struct usb2_interface *iface; + struct usb2_config_descriptor *cd = usb2_get_config_descriptor(udev); + struct usb2_endpoint_descriptor *ed; + struct usb2_descriptor *desc; struct usb2_fs_privdata* pd; struct cdev *dev; - uint8_t niface; - int i, ep, mode, inmode, outmode; + int inmode, outmode, inmask, outmask, mode; + uint8_t ep; KASSERT(LIST_FIRST(&udev->pd_list) == NULL, ("stale cdev entries")); DPRINTFN(2, "Creating device nodes\n"); - usb2_interface_count(udev, &niface); - if (niface == 0) - return; /* nothing to do */ - if (usb2_get_mode(udev) == USB_MODE_DEVICE) { inmode = FWRITE; outmode = FREAD; @@ -1770,24 +1754,40 @@ usb2_cdev_create(struct usb2_device *ude outmode = FWRITE; } - for (i = 0; i < niface; i++) { - iface = usb2_get_iface(udev, i); - if (iface == NULL) - break; + inmask = 0; + outmask = 0; + desc = NULL; - /* Create all available endpoints except EP0 */ - for (ep = 1; ep < 16; ep++) { - mode = 0; - mode |= iface->ep_in_mask & (1 << ep) ? inmode : 0; - mode |= iface->ep_out_mask & (1 << ep) ? outmode : 0; - if (mode == 0) - continue; /* no IN or OUT endpoint */ - - dev = usb2_make_dev(udev, i , ep, mode); - pd = dev->si_drv1; - LIST_INSERT_HEAD(&udev->pd_list, pd, pd_next); + /* + * Collect all used endpoint numbers instead of just + * generating 16 static endpoints. + */ + while ((desc = usb2_desc_foreach(cd, desc))) { + /* filter out all endpoint descriptors */ + if ((desc->bDescriptorType == UDESC_ENDPOINT) && + (desc->bLength >= sizeof(*ed))) { + ed = (struct usb2_endpoint_descriptor *)desc; + + /* update masks */ + ep = ed->bEndpointAddress; + if (UE_GET_DIR(ep) == UE_DIR_OUT) + outmask |= 1 << UE_GET_ADDR(ep); + else + inmask |= 1 << UE_GET_ADDR(ep); } } + + /* Create all available endpoints except EP0 */ + for (ep = 1; ep < 16; ep++) { + mode = inmask & (1 << ep) ? inmode : 0; + mode |= outmask & (1 << ep) ? outmode : 0; + if (mode == 0) + continue; /* no IN or OUT endpoint */ + + dev = usb2_make_dev(udev, ep, mode); + pd = dev->si_drv1; + LIST_INSERT_HEAD(&udev->pd_list, pd, pd_next); + } } static void Modified: head/sys/dev/usb/usb_device.h ============================================================================== --- head/sys/dev/usb/usb_device.h Sat Feb 28 17:01:55 2009 (r189171) +++ head/sys/dev/usb/usb_device.h Sat Feb 28 17:14:03 2009 (r189172) @@ -65,8 +65,6 @@ struct usb2_interface { device_t subdev; uint8_t alt_index; uint8_t parent_iface_index; - uint16_t ep_in_mask; /* bitmask of IN endpoints */ - uint16_t ep_out_mask; /* bitmask of OUT endpoints */ }; /*