Commit ebf02028 authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman

[PATCH] USB: rndis (2/4) fix memory leaks

Tao Huang wrote:
> 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)

Thanks ... this is a nice patch to have.


From:          Tao Huang <huangt@star-net.cn>
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent e9bcd70c
...@@ -1345,14 +1345,11 @@ static void eth_setup_complete (struct usb_ep *ep, struct usb_request *req) ...@@ -1345,14 +1345,11 @@ static void eth_setup_complete (struct usb_ep *ep, struct usb_request *req)
static void rndis_response_complete (struct usb_ep *ep, struct usb_request *req) 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) if (req->status || req->actual != req->length)
DEBUG (dev, "rndis response complete --> %d, %d/%d\n", DEBUG (dev, "rndis response complete --> %d, %d/%d\n",
req->status, req->actual, req->length); req->status, req->actual, req->length);
/* done sending after CDC_GET_ENCAPSULATED_RESPONSE */ /* 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) static void rndis_command_complete (struct usb_ep *ep, struct usb_request *req)
...@@ -1580,6 +1577,7 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) ...@@ -1580,6 +1577,7 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
if (buf) { if (buf) {
memcpy (req->buf, buf, value); memcpy (req->buf, buf, value);
req->complete = rndis_response_complete; req->complete = rndis_response_complete;
rndis_free_response(dev->rndis_config, buf);
} }
/* else stalls ... spec says to avoid that */ /* else stalls ... spec says to avoid that */
} }
...@@ -2064,6 +2062,16 @@ static void rndis_send_media_state (struct eth_dev *dev, int connect) ...@@ -2064,6 +2062,16 @@ static void rndis_send_media_state (struct eth_dev *dev, int connect)
} }
} }
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) static int rndis_control_ack (struct net_device *net)
{ {
struct eth_dev *dev = (struct eth_dev *) net->priv; struct eth_dev *dev = (struct eth_dev *) net->priv;
...@@ -2095,7 +2103,7 @@ static int rndis_control_ack (struct net_device *net) ...@@ -2095,7 +2103,7 @@ static int rndis_control_ack (struct net_device *net)
* CDC_NOTIFY_RESPONSE_AVAILABLE should work too * CDC_NOTIFY_RESPONSE_AVAILABLE should work too
*/ */
resp->length = 8; 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) = __constant_cpu_to_le32 (1);
*((u32 *) resp->buf + 1) = __constant_cpu_to_le32 (0); *((u32 *) resp->buf + 1) = __constant_cpu_to_le32 (0);
...@@ -2103,7 +2111,7 @@ static int rndis_control_ack (struct net_device *net) ...@@ -2103,7 +2111,7 @@ static int rndis_control_ack (struct net_device *net)
length = usb_ep_queue (dev->status_ep, resp, GFP_ATOMIC); length = usb_ep_queue (dev->status_ep, resp, GFP_ATOMIC);
if (length < 0) { if (length < 0) {
resp->status = 0; resp->status = 0;
rndis_response_complete (dev->status_ep, resp); rndis_control_ack_complete (dev->status_ep, resp);
} }
return 0; return 0;
......
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