From 5263c43067b341a1fcc6921575a41ddb11ee0c5c Mon Sep 17 00:00:00 2001 From: hwg Date: Tue, 18 Jun 2013 20:09:52 +0800 Subject: [PATCH] solve usb buffer align problem to support usb tether(rndis) --- drivers/usb/gadget/u_ether.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index 51d572eae9ad..273718441c38 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c @@ -31,6 +31,7 @@ #include "u_ether.h" +static gfp_t g_gfp_flags; /* * This component encapsulates the Ethernet link glue needed to provide @@ -253,7 +254,7 @@ rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags) * but on at least one, checksumming fails otherwise. Note: * RNDIS headers involve variable numbers of LE32 values. */ - skb_reserve(skb, NET_IP_ALIGN); + //skb_reserve(skb, NET_IP_ALIGN); req->buf = skb->data; req->length = size; @@ -577,6 +578,21 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, length = skb->len; } + + // for tx fixup + { + struct sk_buff *tx_skb; + if ((unsigned long)skb->data % 4) { + tx_skb = alloc_skb(skb->len + NET_IP_ALIGN, g_gfp_flags); + if (tx_skb) + memcpy(skb_put(tx_skb, skb->len), skb->data, skb->len); + dev_kfree_skb_any(skb); + skb = tx_skb; + } + length = skb->len; + } + // for tx fixup + req->buf = skb->data; req->context = skb; req->complete = tx_complete; @@ -632,6 +648,8 @@ drop: static void eth_start(struct eth_dev *dev, gfp_t gfp_flags) { DBG(dev, "%s\n", __func__); + + g_gfp_flags = gfp_flags; /* fill the rx queue */ rx_fill(dev, gfp_flags); -- 2.34.1