Commit 5180c534 authored by Duncan Sands's avatar Duncan Sands Committed by Greg Kroah-Hartman

[PATCH] USB speedtouch: re-recycle speedtouch receive buffers

Rediffed version of the original patch - no sk_buff on the stack this time.

  speedtouch: recycle the receive urb's buffer.  Currently, every time a receive urb
    completes, its old buffer is thrown away and replaced with a new one.  This patch
    performs the minor changes needed to reuse the old buffer.
parent b0e4361a
...@@ -701,9 +701,8 @@ struct sk_buff *atmsar_decode_rawcell (struct atmsar_vcc_data *list, struct sk_b ...@@ -701,9 +701,8 @@ struct sk_buff *atmsar_decode_rawcell (struct atmsar_vcc_data *list, struct sk_b
} else { } else {
/* If data is corrupt and skb doesn't hold a whole cell, flush the lot */ /* If data is corrupt and skb doesn't hold a whole cell, flush the lot */
if (skb_pull (skb, (list->flags & ATMSAR_USE_53BYTE_CELL ? 53 : 52)) == if (skb_pull (skb, (list->flags & ATMSAR_USE_53BYTE_CELL ? 53 : 52)) ==
NULL) { NULL)
skb_trim (skb, 0); return NULL;
}
} }
} }
......
...@@ -348,9 +348,11 @@ static void udsl_atm_processqueue (unsigned long data) ...@@ -348,9 +348,11 @@ static void udsl_atm_processqueue (unsigned long data)
struct udsl_instance_data *instance = (struct udsl_instance_data *) data; struct udsl_instance_data *instance = (struct udsl_instance_data *) data;
struct udsl_data_ctx *ctx; struct udsl_data_ctx *ctx;
unsigned long flags; unsigned long flags;
unsigned char *data_start;
struct sk_buff *skb;
struct urb *urb; struct urb *urb;
struct atmsar_vcc_data *atmsar_vcc = NULL; struct atmsar_vcc_data *atmsar_vcc = NULL;
struct sk_buff *new = NULL, *skb = NULL, *tmp = NULL; struct sk_buff *new = NULL, *tmp = NULL;
PDEBUG ("udsl_atm_processqueue entered\n"); PDEBUG ("udsl_atm_processqueue entered\n");
...@@ -369,22 +371,11 @@ static void udsl_atm_processqueue (unsigned long data) ...@@ -369,22 +371,11 @@ static void udsl_atm_processqueue (unsigned long data)
/* update the skb structure */ /* update the skb structure */
skb = ctx->skb; skb = ctx->skb;
skb_trim (skb, 0);
skb_put (skb, urb->actual_length); skb_put (skb, urb->actual_length);
data_start = skb->data;
/* get a new skb */ PDEBUG ("skb->len = %d\n", skb->len);
ctx->skb = dev_alloc_skb (UDSL_RECEIVE_BUFFER_SIZE);
if (!ctx->skb)
PDEBUG ("No skb, loosing urb.\n");
else {
usb_fill_bulk_urb (urb,
instance->usb_dev,
usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN),
(unsigned char *) ctx->skb->data,
UDSL_RECEIVE_BUFFER_SIZE, udsl_usb_data_receive, ctx);
usb_submit_urb (urb, GFP_ATOMIC);
}
PDEBUG ("skb = %p, skb->len = %d\n", skb, skb->len);
PACKETDEBUG (skb->data, skb->len); PACKETDEBUG (skb->data, skb->len);
while ((new = while ((new =
...@@ -423,8 +414,20 @@ static void udsl_atm_processqueue (unsigned long data) ...@@ -423,8 +414,20 @@ static void udsl_atm_processqueue (unsigned long data)
break; break;
} }
} }
dev_kfree_skb (skb);
default: /* restore skb */
skb_push (skb, skb->data - data_start);
usb_fill_bulk_urb (urb,
instance->usb_dev,
usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN),
(unsigned char *) ctx->skb->data,
UDSL_RECEIVE_BUFFER_SIZE, udsl_usb_data_receive, ctx);
if (!usb_submit_urb (urb, GFP_ATOMIC))
break;
PDEBUG ("udsl_atm_processqueue: submission failed\n");
/* fall through */
default: /* error or urb unlinked */
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment