After enabling the HIGHMEM and VMSPLIT_3G, the urb sent to the driver of dwc_otg maybe allocated in the highmem, if it is in the highmem, the usb core will not set the urb->transfer_buffer and call hcd->urb_enquenue().
With other hcd drivers, they could handle the situation of urb->transfer_buffer to be NULL, but for dwc_otg hcd driver, it returns an error unconditionally if the urb->transfer_buffer is NULL. I check the code, the dwc_otg driver could handle the situation that the urb buffer is in highmem (urb->tansfer_buffer is NULL).
Probably I found the root cause of this problem.
After enabling the HIGHMEM and VMSPLIT_3G, the urb sent to the driver of dwc_otg maybe allocated in the highmem, if it is in the highmem, the usb core will not set the urb->transfer_ buffer and call hcd->urb_ enquenue( ).
With other hcd drivers, they could handle the situation of urb->transfer_ buffer to be NULL, but for dwc_otg hcd driver, it returns an error unconditionally if the urb->transfer_ buffer is NULL. I check the code, the dwc_otg driver could handle the situation that the urb buffer is in highmem (urb->tansfer_ buffer is NULL).
Maybe we could fix this issue with a simple patch, I will post my found to the upstream bug https:/ /github. com/raspberrypi /linux/ issues/ 3332
hwang4@ hwang4- Vostro- 5390:~/ work/mainline/ raspi/linux- 32$ git diff usb/host/ dwc_otg/ dwc_otg_ hcd_linux. c b/drivers/ usb/host/ dwc_otg/ dwc_otg_ hcd_linux. c .5d04adfc58c0 100644 usb/host/ dwc_otg/ dwc_otg_ hcd_linux. c usb/host/ dwc_otg/ dwc_otg_ hcd_linux. c urb_enqueue( struct usb_hcd *hcd,
dump_ urb_info( urb, "dwc_otg_ urb_enqueue" ); transfer_ buffer && urb->transfer_ buffer_ length)
return -EINVAL; urb->pipe) == PIPE_ISOCHRONOUS) urb->pipe) == PIPE_INTERRUPT)) { hcd_is_ bandwidth_ allocated
diff --git a/drivers/
index 08a3e41038a3.
--- a/drivers/
+++ b/drivers/
@@ -821,10 +821,10 @@ static int dwc_otg_
}
#endif
-
+#if 0
if (!urb->
-
+#endif
if ((usb_pipetype(
|| (usb_pipetype(
if (!dwc_otg_