Subject: Re: usb: want to switch interfaceprotocol.
To: Alfred Perlstein <bright@mu.org>
From: Lennart Augustsson <lennart@augustsson.net>
List: tech-kern
Date: 02/26/2002 11:34:22
Yes, I think that code should work.

    -- Lennart

Alfred Perlstein wrote:

> My printer reports:
>
> > >   INTERFACE descriptor index 0, alt index 0:
> > >   bLength=9 bDescriptorType=4 bInterfaceNumber=0 bAlternateSetting=0
> > >   bNumEndpoints=3 bInterfaceClass=7 bInterfaceSubClass=1
> > >   bInterfaceProtocol=3 iInterface=0
> > ...
> > >   INTERFACE descriptor index 0, alt index 1:
> > >   bLength=9 bDescriptorType=4 bInterfaceNumber=0 bAlternateSetting=1
> > >   bNumEndpoints=2 bInterfaceClass=7 bInterfaceSubClass=1
> > >   bInterfaceProtocol=2 iInterface=0
> > ...
> > >   INTERFACE descriptor index 0, alt index 2:
> > >   bLength=9 bDescriptorType=4 bInterfaceNumber=0 bAlternateSetting=2
> > >   bNumEndpoints=1 bInterfaceClass=7 bInterfaceSubClass=1
> > >   bInterfaceProtocol=1 iInterface=0
>
> Assuming the device is open (ulptopen has been called) will this code
> sequence work?  Or do I need to tear down pipes and such?  Any clues
> on how to do this?  If you want a better idea of what I want to do
> it's to implement most of the stuff on this wishlist:
>   http://hpoj.sourceforge.net/doc/ioctl_requests.html
> specifically changing the protocol.
>
>                 error = ulpt_getdescriptbyproto(dev, *(int *)data, &id, &altno);
>                 if (error)
>                         break;
>                 error = usbd_set_interface(sc->sc_iface, altno);
>                 if (error)
>                         break;
>                 sc->sc_ifaceno = id->bInterfaceNumber;
>
> Where ulpt_getdescriptbyproto is:
> int
> ulpt_getdescriptbyproto(dev, proto, idret, altnoret)
>         dev_t dev;
>         int proto;
>         usb_interface_descriptor_t **idret;
>         int *altnoret;
> {
>         struct ulpt_softc *sc;
>         usb_config_descriptor_t *cdesc;
>         usb_interface_descriptor_t *id, *ifcd, *iend;
>
>         USB_GET_SC(ulpt, ULPTUNIT(dev), sc);
>         ifcd = usbd_get_interface_descriptor(sc_iface);
>         cdesc = usbd_get_config_descriptor(sc->sc_udev);
>         iend = (usb_interface_descriptor_t *)
>             ((char *)cdesc + UGETW(cdesc->wTotalLength));
>
>         for (id = ifcd, altno = 0;
>              id < iend;
>              id = (void *)((char *)id + id->bLength)) {
>                 if (id->bDescriptorType == UDESC_INTERFACE &&
>                     id->bInterfaceNumber == ifcd->bInterfaceNumber) {
>                         if (id->bInterfaceClass == UICLASS_PRINTER &&
>                             id->bInterfaceSubClass == UISUBCLASS_PRINTER &&
>                             id->bInterfaceProtocol == proto)
>                                 goto found;
>                         altno++;
>                 }
>         }
>         return (ENOENT);
> found:
>         *altnoret = altno;
>         *idret = id;
>         return (0);
> }
>
> thanks,
> --
> -Alfred Perlstein [alfred@freebsd.org]
> 'Instead of asking why a piece of software is using "1970s technology,"
>  start asking why software is ignoring 30 years of accumulated wisdom.'
> Tax deductible donations for FreeBSD: http://www.freebsdfoundation.org/

--

        -- Lennart