This is a note to let you know that I've just added the patch titled
Subject: [PATCH 2/10] USB: reorganize urb->status use in ehci-hcd
to my gregkh-2.6 tree. Its filename is
usb-reorganize-urb-status-use-in-ehci-hcd.patch
This tree can be found at
http://www.kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/patches/
>From [email protected] Fri Aug 24 12:40:21 2007
From: Alan Stern <[email protected]>
Date: Fri, 24 Aug 2007 15:40:19 -0400 (EDT)
Subject: [PATCH 2/10] USB: reorganize urb->status use in ehci-hcd
To: Greg KH <[email protected]>
Cc: David Brownell <[email protected]>, USB development list <[email protected]>
Message-ID: <[email protected]>
This patch (as974) reorganizes the way ehci-hcd sets urb->status. It
now keeps the information in a local variable until the last moment.
The patch also simplifies the handling of -EREMOTEIO, since the only
use of that code is to set the do_status flag.
Signed-off-by: Alan Stern <[email protected]>
CC: David Brownell <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/usb/host/ehci-q.c | 62 ++++++++++++++++++++++--------------------
drivers/usb/host/ehci-sched.c | 4 +-
2 files changed, 35 insertions(+), 31 deletions(-)
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -139,63 +139,65 @@ qh_refresh (struct ehci_hcd *ehci, struc
/*-------------------------------------------------------------------------*/
-static void qtd_copy_status (
+static int qtd_copy_status (
struct ehci_hcd *ehci,
struct urb *urb,
size_t length,
u32 token
)
{
+ int status = -EINPROGRESS;
+
/* count IN/OUT bytes, not SETUP (even short packets) */
if (likely (QTD_PID (token) != 2))
urb->actual_length += length - QTD_LENGTH (token);
/* don't modify error codes */
if (unlikely(urb->unlinked))
- return;
+ return status;
/* force cleanup after short read; not always an error */
if (unlikely (IS_SHORT_READ (token)))
- urb->status = -EREMOTEIO;
+ status = -EREMOTEIO;
/* serious "can't proceed" faults reported by the hardware */
if (token & QTD_STS_HALT) {
if (token & QTD_STS_BABBLE) {
/* FIXME "must" disable babbling device's port too */
- urb->status = -EOVERFLOW;
+ status = -EOVERFLOW;
} else if (token & QTD_STS_MMF) {
/* fs/ls interrupt xfer missed the complete-split */
- urb->status = -EPROTO;
+ status = -EPROTO;
} else if (token & QTD_STS_DBE) {
- urb->status = (QTD_PID (token) == 1) /* IN ? */
+ status = (QTD_PID (token) == 1) /* IN ? */
? -ENOSR /* hc couldn't read data */
: -ECOMM; /* hc couldn't write data */
} else if (token & QTD_STS_XACT) {
/* timeout, bad crc, wrong PID, etc; retried */
if (QTD_CERR (token))
- urb->status = -EPIPE;
+ status = -EPIPE;
else {
ehci_dbg (ehci, "devpath %s ep%d%s 3strikes\n",
urb->dev->devpath,
usb_pipeendpoint (urb->pipe),
usb_pipein (urb->pipe) ? "in" : "out");
- urb->status = -EPROTO;
+ status = -EPROTO;
}
/* CERR nonzero + no errors + halt --> stall */
} else if (QTD_CERR (token))
- urb->status = -EPIPE;
+ status = -EPIPE;
else /* unknown */
- urb->status = -EPROTO;
+ status = -EPROTO;
ehci_vdbg (ehci,
"dev%d ep%d%s qtd token %08x --> status %d\n",
usb_pipedevice (urb->pipe),
usb_pipeendpoint (urb->pipe),
usb_pipein (urb->pipe) ? "in" : "out",
- token, urb->status);
+ token, status);
/* if async CSPLIT failed, try cleaning out the TT buffer */
- if (urb->status != -EPIPE
+ if (status != -EPIPE
&& urb->dev->tt && !usb_pipeint (urb->pipe)
&& ((token & QTD_STS_MMF) != 0
|| QTD_CERR(token) == 0)
@@ -212,10 +214,12 @@ static void qtd_copy_status (
usb_hub_tt_clear_buffer (urb->dev, urb->pipe);
}
}
+
+ return status;
}
static void
-ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb)
+ehci_urb_done(struct ehci_hcd *ehci, struct urb *urb, int status)
__releases(ehci->lock)
__acquires(ehci->lock)
{
@@ -231,17 +235,13 @@ __acquires(ehci->lock)
qh_put (qh);
}
- spin_lock (&urb->lock);
if (unlikely(urb->unlinked)) {
COUNT(ehci->stats.unlink);
} else {
- if (likely(urb->status == -EINPROGRESS ||
- (urb->status == -EREMOTEIO &&
- !(urb->transfer_flags & URB_SHORT_NOT_OK))))
- urb->status = 0;
+ if (likely(status == -EINPROGRESS))
+ status = 0;
COUNT(ehci->stats.complete);
}
- spin_unlock (&urb->lock);
#ifdef EHCI_URB_TRACE
ehci_dbg (ehci,
@@ -249,13 +249,14 @@ __acquires(ehci->lock)
__FUNCTION__, urb->dev->devpath, urb,
usb_pipeendpoint (urb->pipe),
usb_pipein (urb->pipe) ? "in" : "out",
- urb->status,
+ status,
urb->actual_length, urb->transfer_buffer_length);
#endif
/* complete() can reenter this HCD */
usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
spin_unlock (&ehci->lock);
+ urb->status = status;
usb_hcd_giveback_urb (ehci_to_hcd(ehci), urb);
spin_lock (&ehci->lock);
}
@@ -276,6 +277,7 @@ qh_completions (struct ehci_hcd *ehci, s
{
struct ehci_qtd *last = NULL, *end = qh->dummy;
struct list_head *entry, *tmp;
+ int last_status = -EINPROGRESS;
int stopped;
unsigned count = 0;
int do_status = 0;
@@ -304,6 +306,7 @@ qh_completions (struct ehci_hcd *ehci, s
struct ehci_qtd *qtd;
struct urb *urb;
u32 token = 0;
+ int qtd_status;
qtd = list_entry (entry, struct ehci_qtd, qtd_list);
urb = qtd->urb;
@@ -311,11 +314,12 @@ qh_completions (struct ehci_hcd *ehci, s
/* clean up any state from previous QTD ...*/
if (last) {
if (likely (last->urb != urb)) {
- ehci_urb_done (ehci, last->urb);
+ ehci_urb_done(ehci, last->urb, last_status);
count++;
}
ehci_qtd_free (ehci, last);
last = NULL;
+ last_status = -EINPROGRESS;
}
/* ignore urbs submitted during completions we reported */
@@ -351,13 +355,13 @@ qh_completions (struct ehci_hcd *ehci, s
stopped = 1;
if (unlikely (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state)))
- urb->status = -ESHUTDOWN;
+ last_status = -ESHUTDOWN;
/* ignore active urbs unless some previous qtd
* for the urb faulted (including short read) or
* its urb was canceled. we may patch qh or qtds.
*/
- if (likely(urb->status == -EINPROGRESS &&
+ if (likely(last_status == -EINPROGRESS &&
!urb->unlinked))
continue;
@@ -386,14 +390,14 @@ halt:
}
/* remove it from the queue */
- spin_lock (&urb->lock);
- qtd_copy_status (ehci, urb, qtd->length, token);
- if (unlikely(urb->status == -EREMOTEIO)) {
+ qtd_status = qtd_copy_status(ehci, urb, qtd->length, token);
+ if (unlikely(qtd_status == -EREMOTEIO)) {
do_status = (!urb->unlinked &&
usb_pipecontrol(urb->pipe));
- urb->status = 0;
+ qtd_status = 0;
}
- spin_unlock (&urb->lock);
+ if (likely(last_status == -EINPROGRESS))
+ last_status = qtd_status;
if (stopped && qtd->qtd_list.prev != &qh->qtd_list) {
last = list_entry (qtd->qtd_list.prev,
@@ -406,7 +410,7 @@ halt:
/* last urb's completion might still need calling */
if (likely (last != NULL)) {
- ehci_urb_done (ehci, last->urb);
+ ehci_urb_done(ehci, last->urb, last_status);
count++;
ehci_qtd_free (ehci, last);
}
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -1627,7 +1627,7 @@ itd_complete (
/* give urb back to the driver ... can be out-of-order */
dev = urb->dev;
- ehci_urb_done (ehci, urb);
+ ehci_urb_done(ehci, urb, 0);
urb = NULL;
/* defer stopping schedule; completion can submit */
@@ -2000,7 +2000,7 @@ sitd_complete (
/* give urb back to the driver */
dev = urb->dev;
- ehci_urb_done (ehci, urb);
+ ehci_urb_done(ehci, urb, 0);
urb = NULL;
/* defer stopping schedule; completion can submit */
Patches currently in gregkh-2.6 which might be from [email protected] are
driver/sysfs-remove-first-pass-at-shadow-directory-support.patch
driver/sysfs-fix-i_mutex-locking-in-sysfs_get_dentry.patch
driver/sysfs-in-sysfs_lookup-don-t-open-code-sysfs_find_dirent.patch
driver/sysfs-cosmetic-changes-in-sysfs_lookup.patch
driver/sysfs-make-sysfs_add-remove_one-call-link-unlink_sibling-implictly.patch
driver/sysfs-make-sysfs_add_one-automatically-check-for-duplicate-entry.patch
driver/sysfs-make-sysfs_addrm_finish-return-void.patch
driver/sysfs-simplify-sysfs_rename_dir.patch
driver/sysfs-introduce-sysfs_rename_mutex.patch
driver/sysfs-kill-sysfs_flag_removed.patch
driver/sysfs-make-sysfs_mount-static.patch
driver/sysfs-remove-s_dentry.patch
driver/sysfs-remove-sysfs_instantiate.patch
driver/sysfs-rewrite-rename-in-terms-of-sysfs-dirents.patch
driver/sysfs-move-all-of-inode-initialization-into-sysfs_init_inode.patch
driver/sysfs-rewrite-sysfs_drop_dentry.patch
driver/sysfs-rewrite-sysfs_move_dir-in-terms-of-sysfs-dirents.patch
driver/sysfs-simplify-readdir.patch
driver/sysfs-simply-sysfs_get_dentry.patch
driver/sysfs-use-kill_anon_super.patch
usb/usb-add-ep-enable.patch
usb/usb-avoid-the-donelist-after-an-error-in-ohci-hcd.patch
usb/usb-add-direction-bit-to-urb-transfer_flags.patch
usb/usb-add-urb-ep.patch
usb/usb-address-0-handling-during-device-initialization.patch
usb/usb-avoid-urb-pipe-in-usbfs.patch
usb/usb-avoid-urb-pipe-in-usbmon.patch
usb/usb-avoid-using-urb-pipe-in-usbcore.patch
usb/usb-cleanup-for-previous-patches.patch
usb/usb-gadget-file-storage-gadget-cleanups.patch
usb/usb-separate-out-endpoint-queue-management-and-dma-mapping-routines.patch
usb/usb-update-spinlock-usage-for-root-hub-urbs.patch
usb/usb-fix-mistake-in-usb_hcd_giveback_urb.patch
usb/usb-less-restrictive-command-checking-in-g-file-storage.patch
usb/usb-reorganize-urb-status-use-in-dummy-hcd.patch
usb/usb-reorganize-urb-status-use-in-ehci-hcd.patch
usb/usb-reorganize-urb-status-use-in-ohci-hcd.patch
usb/usb-reorganize-urb-status-use-in-r8a66597-hcd.patch
usb/usb-reorganize-urb-status-use-in-sl811-hcd.patch
usb/usb-reorganize-urb-status-use-in-usbmon.patch
usb/usb-cleanups-for-g_file_storage.patch
usb/usb-don-t-touch-sysfs-stuff-when-altsetting-is-unchanged.patch
usb/usb-make-hcds-responsible-for-managing-endpoint-queues.patch
usb/usbmon-update-pipe-removal-to-suit-my-taste.patch
usb/usb-remove-unnecessary-tests-in-isp116x-and-sl811.patch
usb/usb-add-urb-unlinked-field.patch
usb/usb-centralize-eremoteio-handling.patch
usb/usb-driver-for-ch341-usb-serial-adaptor.patch
usb/usb-minor-fixes-for-r8a66597-driver.patch
usb/usb-remove-iso-status-value-in-uhci-hcd.patch
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.