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]

 



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 ?

  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?

Thanks.


best regards
Yuping
--
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