Sorry, resending with the patch actually attached.
Necessary 'if' condition was missing, please merge.
Add a missing 'if' condition for an OUT endpoint.
Signed-off-by: Eugeny S. Mints <[EMAIL PROTECTED]>
A short explanation:
1 } else if ((ep->bEndpointAddress & USB_DIR_IN) != 0 2 && (*ep->reg_udccs & UDCCS_BI_TFS) != 0 3 && write_fifo(ep, req)) { 4 req = 0; 5 } else if ((*ep->reg_udccs & UDCCS_BO_RFS) != 0 6 && read_fifo(ep, req)) { 7 req = 0; 8 }
Let condition on line 1 is true (i.e. ep is IN endpoint) but condition on line 2 is false at the moment. Then we go to condition check on line 5. But since UDCCS_BI_TFS and UDCCS_BO_RFS define the same bit offset (i.e. (1<<0)) it may happen that condition on line 5 may become true for current ep (i.e. IN endpoint) if zero bit of ep->reg_udccs register gets set inbetween checks for condtiions on lines 2 and 5. If so, read_fifo() will be called for IN endpoint, but inside read_fifo() routine we access *ep->reg_ubcr register which is uninitialized (NULL) for any IN endpoint(i.e endpoints 1,3,5,6, 8, 10, 11, 13, 15).
--- pxa2xx_udc.c.orig 2005-04-26 12:31:49.000000000 +0400 +++ pxa2xx_udc.c 2005-04-26 12:32:26.000000000 +0400 @@ -970,7 +970,8 @@ && (*ep->reg_udccs & UDCCS_BI_TFS) != 0 && write_fifo(ep, req)) { req = 0; - } else if ((*ep->reg_udccs & UDCCS_BO_RFS) != 0 + } else if ((ep->bEndpointAddress & USB_DIR_IN) == 0 + && (*ep->reg_udccs & UDCCS_BO_RFS) != 0 && read_fifo(ep, req)) { req = 0; }