This is a 2.4 version of a patch from Duncan Sands, accepted in 2.6 with the following explanation:
Hi Greg, this patch fixes a memory leak in the speedtouch driver. The leak occurs when the ATM layer submits a skbuff for transmission, but the driver rejects it (because the device has been unplugged for example). The ATM layer requires the driver to free the skbuff in this case. The patch is against your 2.6 kernel tree. -- Pete diff -urp -X dontdiff linux-2.4.27-pre2/drivers/usb/speedtch.c linux-2.4.27-pre2-usb/drivers/usb/speedtch.c --- linux-2.4.27-pre2/drivers/usb/speedtch.c 2003-11-29 18:53:05.000000000 -0800 +++ linux-2.4.27-pre2-usb/drivers/usb/speedtch.c 2004-05-15 23:06:11.000000000 -0700 @@ -83,6 +83,10 @@ #define VERBOSE_DEBUG */ +#if !defined (DEBUG) && defined (CONFIG_USB_DEBUG) +# define DEBUG +#endif + #include <linux/usb.h> #ifdef DEBUG @@ -101,8 +105,8 @@ static int udsl_print_packet (const unsi #endif #define DRIVER_AUTHOR "Johan Verrept, Duncan Sands <[EMAIL PROTECTED]>" -#define DRIVER_DESC "Alcatel SpeedTouch USB driver" -#define DRIVER_VERSION "1.7" +#define DRIVER_VERSION "1.8" +#define DRIVER_DESC "Alcatel SpeedTouch USB driver version " DRIVER_VERSION static const char udsl_driver_name [] = "speedtch"; @@ -294,6 +298,19 @@ static struct usb_driver udsl_usb_driver }; +/*********** +** misc ** +***********/ + +static inline void udsl_pop (struct atm_vcc *vcc, struct sk_buff *skb) +{ + if (vcc->pop) + vcc->pop (vcc, skb); + else + dev_kfree_skb (skb); +} + + /************* ** decode ** *************/ @@ -717,10 +734,7 @@ made_progress: if (!UDSL_SKB (skb)->num_cells) { struct atm_vcc *vcc = UDSL_SKB (skb)->atm_data.vcc; - if (vcc->pop) - vcc->pop (vcc, skb); - else - dev_kfree_skb (skb); + udsl_pop (vcc, skb); instance->current_skb = NULL; atomic_inc (&vcc->stats->tx); @@ -739,10 +753,7 @@ static void udsl_cancel_send (struct uds if (UDSL_SKB (skb)->atm_data.vcc == vcc) { dbg ("udsl_cancel_send: popping skb 0x%p", skb); __skb_unlink (skb, &instance->sndqueue); - if (vcc->pop) - vcc->pop (vcc, skb); - else - dev_kfree_skb (skb); + udsl_pop (vcc, skb); } spin_unlock_irq (&instance->sndqueue.lock); @@ -750,10 +761,7 @@ static void udsl_cancel_send (struct uds if ((skb = instance->current_skb) && (UDSL_SKB (skb)->atm_data.vcc == vcc)) { dbg ("udsl_cancel_send: popping current skb (0x%p)", skb); instance->current_skb = NULL; - if (vcc->pop) - vcc->pop (vcc, skb); - else - dev_kfree_skb (skb); + udsl_pop (vcc, skb); } tasklet_enable (&instance->send_tasklet); dbg ("udsl_cancel_send done"); @@ -762,22 +770,26 @@ static void udsl_cancel_send (struct uds static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb) { struct udsl_instance_data *instance = vcc->dev->dev_data; + int err; vdbg ("udsl_atm_send called (skb 0x%p, len %u)", skb, skb->len); if (!instance || !instance->usb_dev) { dbg ("udsl_atm_send: NULL data!"); - return -ENODEV; + err = -ENODEV; + goto fail; } if (vcc->qos.aal != ATM_AAL5) { dbg ("udsl_atm_send: unsupported ATM type %d!", vcc->qos.aal); - return -EINVAL; + err = -EINVAL; + goto fail; } if (skb->len > ATM_MAX_AAL5_PDU) { dbg ("udsl_atm_send: packet too long (%d vs %d)!", skb->len, ATM_MAX_AAL5_PDU); - return -EINVAL; + err = -EINVAL; + goto fail; } PACKETDEBUG (skb->data, skb->len); @@ -787,6 +799,10 @@ static int udsl_atm_send (struct atm_vcc tasklet_schedule (&instance->send_tasklet); return 0; + +fail: + udsl_pop (vcc, skb); + return err; } ------------------------------------------------------- This SF.Net email is sponsored by: SourceForge.net Broadband Sign-up now for SourceForge Broadband and get the fastest 6.0/768 connection for only $19.95/mo for the first 3 months! http://ads.osdn.com/?ad_id=2562&alloc_id=6184&op=click _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel