aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorInaky Perez-Gonzalez <inaky@linux.intel.com>2009-01-19 08:19:30 -0500
committerDavid S. Miller <davem@davemloft.net>2009-01-19 20:58:08 -0500
commitf4895b8bc83a22a36446c4aee277e1750fcc6a18 (patch)
treee1c340f625af67069b23d693bde9e4ddb9da7ce6
parentfe65e704534de5d0661ebc3466a2b9018945f694 (diff)
wimax/i2400m: error paths that need to free an skb should use kfree_skb()
Roel Kluin reported a bug in two error paths where skbs were wrongly being freed using kfree(). He provided a fix where it was replaced to kfree_skb(), as it should be. However, in i2400mu_rx(), the error path was missing returning an indication of the failure. Changed to reset rx_skb to NULL and return it to the caller, i2400mu_rxd(). It will be treated as a transient error and just ignore the packet. Depending on the buffering conditions inside the device, the data packet might be dropped or the device will signal the host again for data-ready-to-read and the host will retry. Signed-off-by: Inaky Perez-Gonzalez <inaky@linux.intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/wimax/i2400m/control.c2
-rw-r--r--drivers/net/wimax/i2400m/usb-rx.c9
2 files changed, 7 insertions, 4 deletions
diff --git a/drivers/net/wimax/i2400m/control.c b/drivers/net/wimax/i2400m/control.c
index d3d37fed6893..15d9f51b292c 100644
--- a/drivers/net/wimax/i2400m/control.c
+++ b/drivers/net/wimax/i2400m/control.c
@@ -609,7 +609,7 @@ void i2400m_msg_to_dev_cancel_wait(struct i2400m *i2400m, int code)
609 spin_lock_irqsave(&i2400m->rx_lock, flags); 609 spin_lock_irqsave(&i2400m->rx_lock, flags);
610 ack_skb = i2400m->ack_skb; 610 ack_skb = i2400m->ack_skb;
611 if (ack_skb && !IS_ERR(ack_skb)) 611 if (ack_skb && !IS_ERR(ack_skb))
612 kfree(ack_skb); 612 kfree_skb(ack_skb);
613 i2400m->ack_skb = ERR_PTR(code); 613 i2400m->ack_skb = ERR_PTR(code);
614 spin_unlock_irqrestore(&i2400m->rx_lock, flags); 614 spin_unlock_irqrestore(&i2400m->rx_lock, flags);
615} 615}
diff --git a/drivers/net/wimax/i2400m/usb-rx.c b/drivers/net/wimax/i2400m/usb-rx.c
index 074cc1f89853..a314799967cf 100644
--- a/drivers/net/wimax/i2400m/usb-rx.c
+++ b/drivers/net/wimax/i2400m/usb-rx.c
@@ -184,6 +184,8 @@ void i2400mu_rx_size_maybe_shrink(struct i2400mu *i2400mu)
184 * NOTE: this function might realloc the skb (if it is too small), 184 * NOTE: this function might realloc the skb (if it is too small),
185 * so always update with the one returned. 185 * so always update with the one returned.
186 * ERR_PTR() is < 0 on error. 186 * ERR_PTR() is < 0 on error.
187 * Will return NULL if it cannot reallocate -- this can be
188 * considered a transient retryable error.
187 */ 189 */
188static 190static
189struct sk_buff *i2400mu_rx(struct i2400mu *i2400mu, struct sk_buff *rx_skb) 191struct sk_buff *i2400mu_rx(struct i2400mu *i2400mu, struct sk_buff *rx_skb)
@@ -243,8 +245,8 @@ retry:
243 if (printk_ratelimit()) 245 if (printk_ratelimit())
244 dev_err(dev, "RX: Can't reallocate skb to %d; " 246 dev_err(dev, "RX: Can't reallocate skb to %d; "
245 "RX dropped\n", rx_size); 247 "RX dropped\n", rx_size);
246 kfree(rx_skb); 248 kfree_skb(rx_skb);
247 result = 0; 249 rx_skb = NULL;
248 goto out; /* drop it...*/ 250 goto out; /* drop it...*/
249 } 251 }
250 kfree_skb(rx_skb); 252 kfree_skb(rx_skb);
@@ -344,7 +346,8 @@ int i2400mu_rxd(void *_i2400mu)
344 if (IS_ERR(rx_skb)) 346 if (IS_ERR(rx_skb))
345 goto out; 347 goto out;
346 atomic_dec(&i2400mu->rx_pending_count); 348 atomic_dec(&i2400mu->rx_pending_count);
347 if (rx_skb->len == 0) { /* some ignorable condition */ 349 if (rx_skb == NULL || rx_skb->len == 0) {
350 /* some "ignorable" condition */
348 kfree_skb(rx_skb); 351 kfree_skb(rx_skb);
349 continue; 352 continue;
350 } 353 }