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

Reply via email to