>From 109b59f272890bcc662f1bdf22175eba489f4a48 Mon Sep 17 00:00:00 2001 From: Jun Nie <njun@xxxxxxxxxxx> Date: Tue, 7 Dec 2010 14:00:55 +0800 Subject: [PATCH] usb: fix stream reference after it is freed Signed-off-by: Jun Nie <njun@xxxxxxxxxxx> --- drivers/usb/host/ehci-sched.c | 18 ++++++++++++++---- 1 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index d9f78eb..cc92d13 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1685,6 +1685,7 @@ itd_complete ( struct ehci_iso_stream *stream = itd->stream; struct usb_device *dev; unsigned retval = false; + unsigned stream_freed = 0; /* for each uframe with a packet */ for (uframe = 0; uframe < 8; uframe++) { @@ -1748,6 +1749,8 @@ itd_complete ( dev->devpath, stream->bEndpointAddress & 0x0f, (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); } + if (1 == stream->refcount) + stream_freed = 1; iso_stream_put (ehci, stream); done: @@ -1755,8 +1758,10 @@ done: if (ehci->clock_frame != itd->frame || itd->index[7] != -1) { /* OK to recycle this ITD now. */ itd->stream = NULL; - list_move(&itd->itd_list, &stream->free_list); - iso_stream_put(ehci, stream); + if (!stream_freed) { + list_move(&itd->itd_list, &stream->free_list); + iso_stream_put(ehci, stream); + } } else { /* HW might remember this ITD, so we can't recycle it yet. * Move it to a safe place until a new frame starts. @@ -2086,6 +2091,7 @@ sitd_complete ( struct ehci_iso_stream *stream = sitd->stream; struct usb_device *dev; unsigned retval = false; + unsigned stream_freed = 0; urb_index = sitd->index; desc = &urb->iso_frame_desc [urb_index]; @@ -2133,6 +2139,8 @@ sitd_complete ( dev->devpath, stream->bEndpointAddress & 0x0f, (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); } + if (1 == stream->refcount) + stream_freed = 1; iso_stream_put (ehci, stream); done: @@ -2140,8 +2148,10 @@ done: if (ehci->clock_frame != sitd->frame) { /* OK to recycle this SITD now. */ sitd->stream = NULL; - list_move(&sitd->sitd_list, &stream->free_list); - iso_stream_put(ehci, stream); + if (!stream_freed) { + list_move(&sitd->sitd_list, &stream->free_list); + iso_stream_put(ehci, stream); + } } else { /* HW might remember this SITD, so we can't recycle it yet. * Move it to a safe place until a new frame starts. -- 1.7.0.4
From 109b59f272890bcc662f1bdf22175eba489f4a48 Mon Sep 17 00:00:00 2001 From: Jun Nie <njun@xxxxxxxxxxx> Date: Tue, 7 Dec 2010 14:00:55 +0800 Subject: [PATCH] usb: fix stream reference after it is freed Signed-off-by: Jun Nie <njun@xxxxxxxxxxx> --- drivers/usb/host/ehci-sched.c | 18 ++++++++++++++---- 1 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index d9f78eb..cc92d13 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1685,6 +1685,7 @@ itd_complete ( struct ehci_iso_stream *stream = itd->stream; struct usb_device *dev; unsigned retval = false; + unsigned stream_freed = 0; /* for each uframe with a packet */ for (uframe = 0; uframe < 8; uframe++) { @@ -1748,6 +1749,8 @@ itd_complete ( dev->devpath, stream->bEndpointAddress & 0x0f, (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); } + if (1 == stream->refcount) + stream_freed = 1; iso_stream_put (ehci, stream); done: @@ -1755,8 +1758,10 @@ done: if (ehci->clock_frame != itd->frame || itd->index[7] != -1) { /* OK to recycle this ITD now. */ itd->stream = NULL; - list_move(&itd->itd_list, &stream->free_list); - iso_stream_put(ehci, stream); + if (!stream_freed) { + list_move(&itd->itd_list, &stream->free_list); + iso_stream_put(ehci, stream); + } } else { /* HW might remember this ITD, so we can't recycle it yet. * Move it to a safe place until a new frame starts. @@ -2086,6 +2091,7 @@ sitd_complete ( struct ehci_iso_stream *stream = sitd->stream; struct usb_device *dev; unsigned retval = false; + unsigned stream_freed = 0; urb_index = sitd->index; desc = &urb->iso_frame_desc [urb_index]; @@ -2133,6 +2139,8 @@ sitd_complete ( dev->devpath, stream->bEndpointAddress & 0x0f, (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); } + if (1 == stream->refcount) + stream_freed = 1; iso_stream_put (ehci, stream); done: @@ -2140,8 +2148,10 @@ done: if (ehci->clock_frame != sitd->frame) { /* OK to recycle this SITD now. */ sitd->stream = NULL; - list_move(&sitd->sitd_list, &stream->free_list); - iso_stream_put(ehci, stream); + if (!stream_freed) { + list_move(&sitd->sitd_list, &stream->free_list); + iso_stream_put(ehci, stream); + } } else { /* HW might remember this SITD, so we can't recycle it yet. * Move it to a safe place until a new frame starts. -- 1.7.0.4