USB: f_phonet: avoid pskb_pull(), fix OOPS with CONFIG_HIGHMEM
authorRémi Denis-Courmont <remi.denis-courmont@nokia.com>
Mon, 21 Feb 2011 14:16:53 +0000 (16:16 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 25 Feb 2011 19:35:21 +0000 (11:35 -0800)
This is similar to what we already do in cdc-phonet.c in the same
situation.

Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/gadget/f_phonet.c

index 3c6e1a058745c739e40cdd825882993a5671661f..5e1495097ec3bf8ad892c0b653e869c2faed5ab9 100644 (file)
@@ -346,14 +346,19 @@ static void pn_rx_complete(struct usb_ep *ep, struct usb_request *req)
 
                if (unlikely(!skb))
                        break;
-               skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, 0,
-                               req->actual);
-               page = NULL;
 
-               if (req->actual < req->length) { /* Last fragment */
+               if (skb->len == 0) { /* First fragment */
                        skb->protocol = htons(ETH_P_PHONET);
                        skb_reset_mac_header(skb);
-                       pskb_pull(skb, 1);
+                       /* Can't use pskb_pull() on page in IRQ */
+                       memcpy(skb_put(skb, 1), page_address(page), 1);
+               }
+
+               skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
+                               skb->len == 0, req->actual);
+               page = NULL;
+
+               if (req->actual < req->length) { /* Last fragment */
                        skb->dev = dev;
                        dev->stats.rx_packets++;
                        dev->stats.rx_bytes += skb->len;