The g_file_storage module part fills an IN buffer if the requested read would have ended in the middle of a page. With wireless USB this can result in enqueued requests that are not a multiple of wMaxPacketSize (e.g., 3584) and consequentially the host would receive an unexpected short packet. Is there are reason for this check for the page boundary? Is it simply an optimization so subsequent calls to vfs_read() are page-aligned? The attached patch simply removes the check for partial pages. David -- David Vrabel, Senior Software Engineer, Drivers CSR, Churchill House, Cambridge Business Park, Tel: +44 (0)1223 692562 Cowley Road, Cambridge, CB4 0WZ http://www.csr.com/
usb: g_file_storage: don't enqueue partial buffers where possible The g_file_storage module would part fill an IN buffer if the requested read would have ended in the middle of a page. With wireless USB this can result in enqueued requests that are not a multiple of the wMaxPacketSize (e.g., 3584) and consequentially the host would receive a short packet too early. Signed-off-by: David Vrabel <david.vrabel@xxxxxxx> Index: linux-working/drivers/usb/gadget/file_storage.c =================================================================== --- linux-working.orig/drivers/usb/gadget/file_storage.c 2009-03-09 15:16:59.000000000 +0000 +++ linux-working/drivers/usb/gadget/file_storage.c 2009-03-09 15:58:50.000000000 +0000 @@ -1645,7 +1645,6 @@ u32 amount_left; loff_t file_offset, file_offset_tmp; unsigned int amount; - unsigned int partial_page; ssize_t nread; /* Get the starting Logical Block Address and check that it's @@ -1680,17 +1679,11 @@ * Try to read the remaining amount. * But don't read more than the buffer size. * And don't try to read past the end of the file. - * Finally, if we're not at a page boundary, don't read past - * the next page. * If this means reading 0 then we were asked to read past * the end of file. */ amount = min((unsigned int) amount_left, mod_data.buflen); amount = min((loff_t) amount, curlun->file_length - file_offset); - partial_page = file_offset & (PAGE_CACHE_SIZE - 1); - if (partial_page > 0) - amount = min(amount, (unsigned int) PAGE_CACHE_SIZE - - partial_page); /* Wait for the next buffer to become available */ bh = fsg->next_buffhd_to_fill;