Re: New USB stack on FreeBSD w/Linux emulation layer coming

Hans Petter Selasky <[email protected]>
Newsgroups gmane.linux.usb.devel
Message-ID <[email protected]>
On Thursday 17 May 2007 19:44, David Brownell wrote:
> On Thursday 17 May 2007, Hans Petter Selasky wrote:
> > I would like introduce a new USB API call, so that my pre-allocate model
> > will work better with your USB API. For example I want something like
> > this:
> >
> > void
> > usb_setup_endpoint(struct usb_device *usb, struct usb_interface *ui,
> > struct usb_host_endpoint *uhe, uint32_t bufsize, uint32_t unused0,
> > uint32_t unused1, uint32_t unused2);
>
> The usb_device and usb_interface are implied by the usb_host_endpoint,
> and "unused" parameters are pointless.  Sizes are "size_t", and such
> a call could obviously fail because of invalid parameters.   So
>
> 	int usb_setup_endpoint(struct usb_host_endpoint *hep, size_t bufsize);

To save the "hep" to "struct usb_device" pointer, I would like to have "struct 
usb_device *dev" as an argument. 

>
> What would such a call do, though?  Who would use it, and why?

The call will setup one or two pre-allocated USB transfers for the emulation 
layer between the Linux USB stack and the FreeBSD USB stack.

I've currently put the following into this function:

int32_t
usb_setup_endpoint(struct usb_device *dev, struct usb_host_endpoint *uhe, 
uint32_t bufsize)
{
        struct usbd_config cfg[2];
        uint16_t mfs = usbd_get_max_frame_size((usb_endpoint_descriptor_t 
*)&(uhe->desc));
        uint8_t type = uhe->desc.bmAttributes & UE_XFERTYPE;
        uint8_t addr = uhe->desc.bEndpointAddress;

        usbd_transfer_unsetup(uhe->bsd_xfer, 2);

        if (bufsize == 0) {
            return 0;
        }

        bzero(cfg, sizeof(cfg));

        if (type == UE_ISOCHRONOUS) {

            /* Isochronous is special */

            cfg[0].type = type;
            cfg[0].endpoint = addr & UE_ADDR;
            cfg[0].direction = addr & (UE_DIR_OUT|UE_DIR_IN);
            cfg[0].callback = &usb_linux_isoc_callback;
            cfg[0].bufsize = 0; /* use wMaxPacketSize */

            bcopy(cfg + 0, cfg + 1, sizeof(*cfg));

            if (usbd_transfer_setup(dev->bsd_udev, uhe->bsd_iface_index,
                                    uhe->bsd_xfer, cfg, 2, uhe, 
                                    &usb_global_lock))
            {
                return -EINVAL;
            }
        } else {
            if (bufsize > (1 << 22)) {
                /* limit buffer size */
                bufsize = (1 << 22);
            }

            if (type == UE_CONTROL) {
              /* we need enough room for the control header */
              if (bufsize < sizeof(usb_device_request_t)) {
                  bufsize = sizeof(usb_device_request_t);
              }
            }

            if (bufsize < mfs) {
                /* we need to be able to hold at least one frame! */
                bufsize = mfs;
            }

            cfg[0].type = type;
            cfg[0].endpoint = addr & UE_ADDR;
            cfg[0].direction = addr & (UE_DIR_OUT|UE_DIR_IN);
            cfg[0].callback = &usb_linux_non_isoc_callback;
            cfg[0].bufsize = bufsize;

            if (usbd_transfer_setup(dev->bsd_udev, uhe->bsd_iface_index,
                                    uhe->bsd_xfer, cfg, 1, uhe, 
                                    &usb_global_lock))
            {
                return -EINVAL;
            }
        }
        return 0;
}

The reason for this is to allow Linux USB drivers to tell the FreeBSD USB 
stack that they want larger/smaller buffers.

On Linux this information can be used to reserve EHCI/UHCI/OHCI USB transfer 
descriptors.

>
> > On FreeBSD this function will pre-allocate one or two USB transfers for
> > an endpoint using the given "bufsize" argument. Those FreeBSD USB
> > transfers will then be used to do all the Linux USB transfers. This
> > function can block and must have a context.
>
> So what's the model ... GPL'd Linux drivers will be modified to
> incorporate that call, so they'd work better on FreeBSD?

Yes, and under Linux.

As you can see, it is not possible to emulate an on-the-fly allocation model 
by a pre-allocation model. That's why I suggest this API addition.

--HPS

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.