From 1e5b1dd686ca089f9b4034ec26541e7515c9fa58 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 20 Jan 2013 22:45:53 +0100 Subject: [PATCH 119/364] Split long USB transfers into short ones. --- ChangeLog | 4 ++++ grub-core/bus/usb/usbtrans.c | 20 ++++++++++++++++---- include/grub/usbtrans.h | 2 ++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4d09825..c8edf73 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-01-20 Aleš Nesrsta + + Split long USB transfers into short ones. + 2013-01-20 Andrey Borzenkov * docs/grub.texi (Simple configuration): Clarify GRUB_HIDDEN_TIMEOUT diff --git a/grub-core/bus/usb/usbtrans.c b/grub-core/bus/usb/usbtrans.c index 167fae5..154c72d 100644 --- a/grub-core/bus/usb/usbtrans.c +++ b/grub-core/bus/usb/usbtrans.c @@ -351,11 +351,23 @@ grub_usb_err_t grub_usb_bulk_read (grub_usb_device_t dev, int endpoint, grub_size_t size, char *data) { - grub_size_t actual; + grub_size_t actual, transferred; grub_usb_err_t err; - err = grub_usb_bulk_readwrite (dev, endpoint, size, data, - GRUB_USB_TRANSFER_TYPE_IN, 1000, &actual); - if (!err && actual != size) + grub_size_t current_size, position; + + for (position = 0, transferred = 0; + position < size; position += MAX_USB_TRANSFER_LEN) + { + current_size = size - position; + if (current_size >= MAX_USB_TRANSFER_LEN) + current_size = MAX_USB_TRANSFER_LEN; + err = grub_usb_bulk_readwrite (dev, endpoint, current_size, + &data[position], GRUB_USB_TRANSFER_TYPE_IN, 1000, &actual); + transferred += actual; + if (err || (current_size != actual) ) break; + } + + if (!err && transferred != size) err = GRUB_USB_ERR_DATA; return err; } diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h index 5ee276d..5429007 100644 --- a/include/grub/usbtrans.h +++ b/include/grub/usbtrans.h @@ -19,6 +19,8 @@ #ifndef GRUB_USBTRANS_H #define GRUB_USBTRANS_H 1 +#define MAX_USB_TRANSFER_LEN 0x0800 + typedef enum { GRUB_USB_TRANSFER_TYPE_IN, -- 1.8.1.4