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