I'm writing udc driver for S3C2410. I found RNDIS almost not call my
driver's free_request and free_buffer. So after run my driver about 3
hours the system will out of memory. 

This patch will fix the memory leak. 

There will still have memory leak when driver unload, but I don't known
where is the proper place to fix it.
1) rndis.c should free resp_queue when it unload
2) ether.c should free tx_reqs and rx_reqs when it unload (as
eth_reset_config)


--- ether.c.orig	2004-05-31 12:56:06.000000000 +0800
+++ ether.c	2004-05-31 12:57:31.000000000 +0800
@@ -1346,14 +1357,11 @@ static void eth_setup_complete (struct u
 
 static void rndis_response_complete (struct usb_ep *ep, struct usb_request *req)
 {
-	struct eth_dev          *dev = ep->driver_data;
-	
 	if (req->status || req->actual != req->length)
 		DEBUG (dev, "rndis response complete --> %d, %d/%d\n",
 		       req->status, req->actual, req->length);
 
 	/* done sending after CDC_GET_ENCAPSULATED_RESPONSE */
-	rndis_free_response (dev->rndis_config, req->buf);
 }
 
 static void rndis_command_complete (struct usb_ep *ep, struct usb_request *req)
@@ -1583,6 +1593,7 @@ done_set_intf:
 			if (buf) {
 				memcpy (req->buf, buf, value);
 				req->complete = rndis_response_complete;
+				rndis_free_response(dev->rndis_config, buf);
 			}
 			/* else stalls ... spec says to avoid that */
 		}
@@ -2067,6 +2077,16 @@ static void rndis_send_media_state (stru
 	}
 }
 
+static void rndis_control_ack_complete (struct usb_ep *ep, struct usb_request *req)
+{
+	if (req->status || req->actual != req->length)
+		DEBUG (dev, "rndis control ack complete --> %d, %d/%d\n",
+		       req->status, req->actual, req->length);
+
+	usb_ep_free_buffer(ep, req->buf, req->dma, 8);
+	usb_ep_free_request(ep, req);
+}
+
 static int rndis_control_ack (struct net_device *net)
 {
 	struct eth_dev          *dev = (struct eth_dev *) net->priv;
@@ -2098,7 +2118,7 @@ static int rndis_control_ack (struct net
 	 * CDC_NOTIFY_RESPONSE_AVAILABLE should work too
 	 */
 	resp->length = 8;
-	resp->complete = rndis_response_complete;
+	resp->complete = rndis_control_ack_complete;
 	
 	*((u32 *) resp->buf) = __constant_cpu_to_le32 (1);
 	*((u32 *) resp->buf + 1) = __constant_cpu_to_le32 (0);
@@ -2106,7 +2126,7 @@ static int rndis_control_ack (struct net
 	length = usb_ep_queue (dev->status_ep, resp, GFP_ATOMIC);
 	if (length < 0) {
 		resp->status = 0;
-		rndis_response_complete (dev->status_ep, resp);
+		rndis_control_ack_complete (dev->status_ep, resp);
 	}
 	
 	return 0;

Reply via email to