diff options
author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2009-02-21 18:31:23 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-02-27 17:40:51 -0500 |
commit | 3ecdb9acf343bbcf2bb2c287dc524ab709cfad7e (patch) | |
tree | 0e6bb1dada7b9793c7f95cff9498a3283fade244 /drivers/usb | |
parent | 51d9f3e100a8f8cc2be89d5f13d37de61e2da38a (diff) |
USB: musb: be careful with 64K+ transfer lengths, host side
Feeding 32-bit length cast down to 'u16' to min() to calculate the FIFO
count in musb_host_tx() risks sending a short packet prematurely for
transfer sizes over 64 KB.
Similarly, although data transfer size shouldn't exceed 65535 bytes for
the control endpoint, making musb_h_ep0_continue() more robust WRT URBs
with possibly oversized buffer will not hurt either...
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Felipe Balbi <felipe.balbi@nokia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/musb/musb_host.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index fc79e76b3845..23d3890fd54d 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -937,8 +937,8 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb) | |||
937 | switch (musb->ep0_stage) { | 937 | switch (musb->ep0_stage) { |
938 | case MUSB_EP0_IN: | 938 | case MUSB_EP0_IN: |
939 | fifo_dest = urb->transfer_buffer + urb->actual_length; | 939 | fifo_dest = urb->transfer_buffer + urb->actual_length; |
940 | fifo_count = min(len, ((u16) (urb->transfer_buffer_length | 940 | fifo_count = min_t(size_t, len, urb->transfer_buffer_length - |
941 | - urb->actual_length))); | 941 | urb->actual_length); |
942 | if (fifo_count < len) | 942 | if (fifo_count < len) |
943 | urb->status = -EOVERFLOW; | 943 | urb->status = -EOVERFLOW; |
944 | 944 | ||
@@ -971,10 +971,9 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb) | |||
971 | } | 971 | } |
972 | /* FALLTHROUGH */ | 972 | /* FALLTHROUGH */ |
973 | case MUSB_EP0_OUT: | 973 | case MUSB_EP0_OUT: |
974 | fifo_count = min(qh->maxpacket, ((u16) | 974 | fifo_count = min_t(size_t, qh->maxpacket, |
975 | (urb->transfer_buffer_length | 975 | urb->transfer_buffer_length - |
976 | - urb->actual_length))); | 976 | urb->actual_length); |
977 | |||
978 | if (fifo_count) { | 977 | if (fifo_count) { |
979 | fifo_dest = (u8 *) (urb->transfer_buffer | 978 | fifo_dest = (u8 *) (urb->transfer_buffer |
980 | + urb->actual_length); | 979 | + urb->actual_length); |
@@ -1304,7 +1303,8 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
1304 | * packets before updating TXCSR ... other docs disagree ... | 1303 | * packets before updating TXCSR ... other docs disagree ... |
1305 | */ | 1304 | */ |
1306 | /* PIO: start next packet in this URB */ | 1305 | /* PIO: start next packet in this URB */ |
1307 | wLength = min(qh->maxpacket, (u16) wLength); | 1306 | if (wLength > qh->maxpacket) |
1307 | wLength = qh->maxpacket; | ||
1308 | musb_write_fifo(hw_ep, wLength, buf); | 1308 | musb_write_fifo(hw_ep, wLength, buf); |
1309 | qh->segsize = wLength; | 1309 | qh->segsize = wLength; |
1310 | 1310 | ||