Date: Tue, 10 May 2005 13:48:31 +0200 From: Hans Petter Selasky <hselasky@c2i.net> To: FreeBSD-gnats-submit@FreeBSD.org Subject: usb/80854: suggestion for new iface-no-probe mechanism Message-ID: <200505101348.32720.hselasky@c2i.net> Resent-Message-ID: <200505101150.j4ABo2rg035952@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 80854 >Category: usb >Synopsis: suggestion for new iface-no-probe mechanism >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-usb >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Tue May 10 11:50:02 GMT 2005 >Closed-Date: >Last-Modified: >Originator: HPS >Release: FreeBSD 6.0-CURRENT i386 >Organization: >Environment: System: FreeBSD 6.0-CURRENT FreeBSD 6.0-CURRENT #45: Mon Mar 21 15:40:17 CET 2005 root@:/usr/obj/usr/src/sys/custom i386 >Description: There is a special mechanism where probe/attach can clear an entry in the array pointed to by "uaa->ifaces". I have a suggestion to replace this mechanism, that will save some memory allocation: >How-To-Repeat: >Fix: New library function: struct usbd_interface * usbd_get_iface(struct usbd_device *udev, u_int8_t iface_index) { struct usbd_interface *iface = &udev->ifaces[iface_index]; if((iface < &udev->ifaces[0]) || (iface >= &udev->ifaces_end[0]) || (udev->cdesc == NULL) || (iface_index >= udev->cdesc->bNumInterface)) { return NULL; } return iface; } New structure fields: struct usbd_device { ... u_int8_t ifaces_no_probe[(USB_MAX_ENDPOINTS + 7) / 8]; #define USBD_SET_IFACE_NO_PROBE(udev, ii) \ { (udev)->ifaces_no_probe[(ii) >> 3] |= (1 << ((ii) & 7)); } #define USBD_CLR_IFACE_NO_PROBE(udev, ii) \ { (udev)->ifaces_no_probe[(ii) >> 3] &= ~(1 << ((ii) & 7)); } #define USBD_GET_IFACE_NO_PROBE(udev, ii) \ ((udev)->ifaces_no_probe[(ii) >> 3] & (1 << ((ii) & 7))) ... } Re-initialization in case a new configuration index is selected: usbd_status usbd_fill_iface_data(struct usbd_device *udev, int iface_index, int alt_index) { ... USBD_CLR_IFACE_NO_PROBE(udev, iface_index); ... } Make sure new variable is checked: usbd_status usbd_probe_and_attach(struct device *parent, int port, struct usbd_port *up) { ... if((USBD_GET_IFACE_NO_PROBE(udev, i) == 0) && (udev->subdevs[i] == NULL) && (device_probe_and_attach(bdev) == 0)) { ... } Update existing code, that uses old mechanism: for (i = 0; i < uaa->nifaces; i++) { if (uaa->ifaces[i] != NULL) { id = usbd_get_interface_descriptor( uaa->ifaces[i]); if (id != NULL && id->bInterfaceNumber == data_ifcno) { sc->cdce_data_iface = uaa->ifaces[i]; uaa->ifaces[i] = NULL; } } } New code: for(i = 0;; i++) { iface = usbd_get_iface(udev, i); if(iface == NULL) { break; } id = usbd_get_interface_descriptor(iface); if(id && (id->bInterfaceNumber == data_ifcno)) { sc->cdce_data_iface = iface; USBD_SET_IFACE_NO_PROBE(udev, i); } } Then remove "nifaces" and "ifaces" from "struct usb_attach_arg". >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200505101348.32720.hselasky>