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/ _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel