Re: usb core limit the transfer to one page, which leads to slow transfer for usb DFU

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Aug 12, 2010 at 07:46:57PM +0800, Yuping Luo wrote:
> Hi,
>    I am adding firmware upgrade feature to our uboot , and refer to
> openmoko's way (http://wiki.openmoko.org/wiki/USB_DFU), which use
> control endpoint for data transfer and status control.
>    everything is ok except the slow buring speed, about 0.5~0.8 MB/s
> with the default 4KB transfer length.  and for our usb device
> controller, it's capable to  support 16KB(considering to buffer
> alignment, or 20KB supported)  for each dTD.  after changing the
> proc_control() to follow proc_bulk()'s way, and rebuild the desktop's
> kernel . 2.0~ 2.5 MB/s can be reached.
>    following are my change:
> 
> #define SUPPORT_BIG_CONTRL_XFER
> static int proc_control(struct dev_state *ps, void __user *arg)
> {
>     struct usb_device *dev = ps->dev;
>     struct usbdevfs_ctrltransfer ctrl;
>     unsigned int tmo;
>     unsigned char *tbuf;
>     unsigned wLength;
>     int i, pipe, ret;
> 
>     if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
>         return -EFAULT;
>     ret = check_ctrlrecip(ps, ctrl.bRequestType, ctrl.wIndex);
>     if (ret)
>         return ret;
>     wLength = ctrl.wLength;     /* To suppress 64k PAGE_SIZE warning */
> #ifdef SUPPORT_BIG_CONTRL_XFER
>     if (wLength > MAX_USBFS_BUFFER_SIZE) {
>         printk("%s: wLength too big %d\n", __func__, wLength);
>         return -EINVAL;
>     }
>     tbuf = kmalloc(wLength, GFP_KERNEL);
> #else
>     if (wLength > PAGE_SIZE) {
>         printk("%s: wLength too big %d\n", __func__, wLength);
>         return -EINVAL;
>     }
>     tbuf = (unsigned char *)__get_free_page(GFP_KERNEL);
> #endif
>     if (!tbuf)
>         return -ENOMEM;
>     tmo = ctrl.timeout;
>     if (ctrl.bRequestType & 0x80) {
>         if (ctrl.wLength && !access_ok(VERIFY_WRITE, ctrl.data,
>                            ctrl.wLength)) {
> #ifdef SUPPORT_BIG_CONTRL_XFER
>             kfree(tbuf);
> #else
>             free_page((unsigned long)tbuf);
> 
>                 return -EFAULT;
>             }
>         }
>         pipe = usb_sndctrlpipe(dev, 0);
>         snoop_urb(dev, NULL, pipe, ctrl.wLength, tmo, SUBMIT);
> 
>         usb_unlock_device(dev);
>         i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl.bRequest,
>                     ctrl.bRequestType, ctrl.wValue, ctrl.wIndex,
>                     tbuf, ctrl.wLength, tmo);
>         usb_lock_device(dev);
>         snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE);
>     }
> #ifdef SUPPORT_BIG_CONTRL_XFER
>     kfree(tbuf);
> #else
>     free_page((unsigned long)tbuf);
> #endif
>     if (i < 0 && i != -EPIPE) {
>         dev_printk(KERN_DEBUG, &dev->dev, "usbfs: USBDEVFS_CONTROL "
>                "failed cmd %s rqt %u rq %u len %u ret %d\n",
>                current->comm, ctrl.bRequestType, ctrl.bRequest,
>                ctrl.wLength, i);
>     }
>     return i;
> }
> 
>    so I am eager to know the reason to set such limit, or maybe
> burning image over control EP is not very good ?

Control endpoints are smaller usually, so that would make it a bit
slower, right?

>   and also doubt for USB DFU specification, it's not popular as the
> usb.  Greg, since you are one of contributors for it, what do you say?

I don't understand the question.  Yes, I helped with the DFU spec oh so
many years ago, but I primarily wrote the sample code that is in the end
of the spec (with a nice bug that someone reminds me about once a year
it seems.)

What is the real issue you are having here?

confused,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux