usb/80854: suggestion for new iface-no-probe mechanism

Hans Petter Selasky hselasky at c2i.net
Tue May 10 04:50:03 PDT 2005


>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:


More information about the freebsd-usb mailing list