summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSakethram Bommisetti <sakethram.bommisetti@stericsson.com>2011-11-07 16:37:31 +0530
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:03:14 +0200
commit6dfb7bff0f0da151f93f716038269f3c1fd3745d (patch)
tree96cfc106e41b2d648ae5356e61fb992f0b2be7ac
parent751b08002d52e0790075f02413b434cac0ab7504 (diff)
ux500:USB:Updating is_compatible with class checks
Current checks in is_compatible doesn't handle all the needed DMA cases. In case of Ethernet out transactions data size is not known and we cannot use the dma effectively in such cases. So,Using class names to accurately handle all the musb dma limitations/features.Hence, only for mass storage and ACM classes, data will be transfered over DMA. ST-Ericsson Linux next: NA ST-Ericsson ID: 373086 ST-Ericsson FOSS-OUT ID: Trivial Change-Id: If83db00286bdc04c3d8e65e272b3ed586390ecfb Signed-off-by: Sakethram Bommisetti <sakethram.bommisetti@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/36991 Reviewed-by: Praveena NADAHALLY <praveen.nadahally@stericsson.com> Reviewed-by: Rabin VINCENT <rabin.vincent@stericsson.com>
-rw-r--r--drivers/usb/musb/ux500_dma.c50
1 files changed, 43 insertions, 7 deletions
diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c
index 389bf8890a5..cb86beb8ec2 100644
--- a/drivers/usb/musb/ux500_dma.c
+++ b/drivers/usb/musb/ux500_dma.c
@@ -32,6 +32,11 @@
#include <linux/pfn.h>
#include <mach/usb.h>
#include "musb_core.h"
+#undef DBG
+#undef WARNING
+#undef INFO
+#include <linux/usb/composite.h>
+#define U8500_USB_DMA_MIN_TRANSFER_SIZE 512
struct ux500_dma_channel {
struct dma_channel channel;
@@ -205,13 +210,44 @@ static void ux500_dma_channel_release(struct dma_channel *channel)
static int ux500_dma_is_compatible(struct dma_channel *channel,
u16 maxpacket, void *buf, u32 length)
{
- if ((maxpacket & 0x3) ||
- ((int)buf & 0x3) ||
- (length < 512) ||
- (length & 0x3))
- return false;
- else
- return true;
+ struct ux500_dma_channel *ux500_channel = channel->private_data;
+ struct musb_hw_ep *hw_ep = ux500_channel->hw_ep;
+ struct musb *musb = hw_ep->musb;
+ struct usb_descriptor_header **descriptors;
+ struct usb_function *f;
+ struct usb_gadget *gadget = &musb->g;
+ struct usb_composite_dev *cdev = get_gadget_data(gadget);
+
+ if (length < U8500_USB_DMA_MIN_TRANSFER_SIZE)
+ return 0;
+
+ list_for_each_entry(f, &cdev->config->functions, list) {
+ if (!strcmp(f->name, "cdc_ethernet") ||
+ !strcmp(f->name, "rndis") ||
+ !strcmp(f->name, "phonet") ||
+ !strcmp(f->name, "adb")) {
+ if (gadget->speed == USB_SPEED_HIGH)
+ descriptors = f->hs_descriptors;
+ else
+ descriptors = f->descriptors;
+
+ for (; *descriptors; ++descriptors) {
+ struct usb_endpoint_descriptor *ep;
+
+ if ((*descriptors)->bDescriptorType !=
+ USB_DT_ENDPOINT)
+ continue;
+
+ ep = (struct usb_endpoint_descriptor *)
+ *descriptors;
+ if (ep->bEndpointAddress ==
+ ux500_channel->hw_ep->epnum)
+ return 0;
+ }
+ }
+ }
+
+ return 1;
}
/**