From cbad42a979b023107e6f19101654c821556023bb Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Thu, 31 Jan 2008 14:51:16 +0000 Subject: add 2.6.24 specific patchset for the usb driver SVN-Revision: 10338 --- .../914-usb_reorganize_urb_status_use.patch | 242 +++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 target/linux/adm5120/patches-2.6.24/914-usb_reorganize_urb_status_use.patch (limited to 'target/linux/adm5120/patches-2.6.24/914-usb_reorganize_urb_status_use.patch') diff --git a/target/linux/adm5120/patches-2.6.24/914-usb_reorganize_urb_status_use.patch b/target/linux/adm5120/patches-2.6.24/914-usb_reorganize_urb_status_use.patch new file mode 100644 index 0000000000..79a53d8012 --- /dev/null +++ b/target/linux/adm5120/patches-2.6.24/914-usb_reorganize_urb_status_use.patch @@ -0,0 +1,242 @@ +Index: linux-2.6.24/drivers/usb/host/adm5120-dbg.c +=================================================================== +--- linux-2.6.24.orig/drivers/usb/host/adm5120-dbg.c ++++ linux-2.6.24/drivers/usb/host/adm5120-dbg.c +@@ -82,7 +82,7 @@ static inline char *td_togglestring(u32 + * small: 0) header + data packets 1) just header + */ + static void __attribute__((unused)) +-urb_print(struct admhcd *ahcd, struct urb *urb, char *str, int small) ++urb_print(struct admhcd *ahcd, struct urb *urb, char *str, int small, int status) + { + unsigned int pipe = urb->pipe; + +@@ -92,7 +92,7 @@ urb_print(struct admhcd *ahcd, struct ur + } + + #ifndef ADMHC_VERBOSE_DEBUG +- if (urb->status != 0) ++ if (status != 0) + #endif + admhc_dbg(ahcd, "URB-%s %p dev=%d ep=%d%s-%s flags=%x len=%d/%d " + "stat=%d\n", +@@ -105,7 +105,7 @@ urb_print(struct admhcd *ahcd, struct ur + urb->transfer_flags, + urb->actual_length, + urb->transfer_buffer_length, +- urb->status); ++ status); + + #ifdef ADMHC_VERBOSE_DEBUG + if (!small) { +@@ -125,7 +125,7 @@ urb_print(struct admhcd *ahcd, struct ur + urb->transfer_buffer_length: urb->actual_length; + for (i = 0; i < 16 && i < len; i++) + printk(" %02x", ((__u8 *)urb->transfer_buffer)[i]); +- printk("%s stat:%d\n", i < len? "...": "", urb->status); ++ printk("%s stat:%d\n", i < len? "...": "", status); + } + } + #endif /* ADMHC_VERBOSE_DEBUG */ +Index: linux-2.6.24/drivers/usb/host/adm5120-hcd.c +=================================================================== +--- linux-2.6.24.orig/drivers/usb/host/adm5120-hcd.c ++++ linux-2.6.24/drivers/usb/host/adm5120-hcd.c +@@ -96,7 +96,7 @@ static int admhc_urb_enqueue(struct usb_ + + #ifdef ADMHC_VERBOSE_DEBUG + spin_lock_irqsave(&ahcd->lock, flags); +- urb_print(ahcd, urb, "ENQEUE", usb_pipein(pipe)); ++ urb_print(ahcd, urb, "ENQEUE", usb_pipein(pipe), -EINPROGRESS); + spin_unlock_irqrestore(&ahcd->lock, flags); + #endif + +@@ -208,8 +208,8 @@ fail: + } + + /* +- * decouple the URB from the HC queues (TDs, urb_priv); it's +- * already marked using urb->status. reporting is always done ++ * decouple the URB from the HC queues (TDs, urb_priv); ++ * reporting is always done + * asynchronously, and we might be dealing with an urb that's + * partially transferred, or an ED with other urbs being unlinked. + */ +@@ -223,7 +223,7 @@ static int admhc_urb_dequeue(struct usb_ + spin_lock_irqsave(&ahcd->lock, flags); + + #ifdef ADMHC_VERBOSE_DEBUG +- urb_print(ahcd, urb, "DEQUEUE", 1); ++ urb_print(ahcd, urb, "DEQUEUE", 1, status); + #endif + ret = usb_hcd_check_unlink_urb(hcd, urb, status); + if (ret) { +@@ -247,7 +247,7 @@ static int admhc_urb_dequeue(struct usb_ + * any more ... just clean up every urb's memory. + */ + if (urb->hcpriv) +- finish_urb(ahcd, urb); ++ finish_urb(ahcd, urb, status); + } + spin_unlock_irqrestore(&ahcd->lock, flags); + +Index: linux-2.6.24/drivers/usb/host/adm5120-pm.c +=================================================================== +--- linux-2.6.24.orig/drivers/usb/host/adm5120-pm.c ++++ linux-2.6.24/drivers/usb/host/adm5120-pm.c +@@ -383,9 +383,8 @@ static int admhc_restart(struct admhcd * + ed, ed->state); + } + +- spin_lock(&urb->lock); +- urb->status = -ESHUTDOWN; +- spin_unlock(&urb->lock); ++ if (!urb->unlinked) ++ urb->unlinked = -ESHUTDOWN; + } + finish_unlinks(ahcd, 0); + spin_unlock_irq(&ahcd->lock); +Index: linux-2.6.24/drivers/usb/host/adm5120-q.c +=================================================================== +--- linux-2.6.24.orig/drivers/usb/host/adm5120-q.c ++++ linux-2.6.24/drivers/usb/host/adm5120-q.c +@@ -23,16 +23,14 @@ + * PRECONDITION: ahcd lock held, irqs blocked. + */ + static void +-finish_urb(struct admhcd *ahcd, struct urb *urb) ++finish_urb(struct admhcd *ahcd, struct urb *urb, int status) + __releases(ahcd->lock) + __acquires(ahcd->lock) + { + urb_priv_free(ahcd, urb->hcpriv); + +- spin_lock(&urb->lock); +- if (likely(urb->status == -EINPROGRESS)) +- urb->status = 0; +- spin_unlock(&urb->lock); ++ if (likely(status == -EINPROGRESS)) ++ status = 0; + + switch (usb_pipetype(urb->pipe)) { + case PIPE_ISOCHRONOUS: +@@ -44,12 +42,13 @@ __acquires(ahcd->lock) + } + + #ifdef ADMHC_VERBOSE_DEBUG +- urb_print(ahcd, urb, "RET", usb_pipeout (urb->pipe)); ++ urb_print(ahcd, urb, "RET", usb_pipeout (urb->pipe), status); + #endif + + /* urb->complete() can reenter this HCD */ + usb_hcd_unlink_urb_from_ep(admhcd_to_hcd(ahcd), urb); + spin_unlock(&ahcd->lock); ++ urb->status = status; + usb_hcd_giveback_urb(admhcd_to_hcd(ahcd), urb); + spin_lock(&ahcd->lock); + } +@@ -557,9 +556,7 @@ static void td_submit_urb(struct admhcd + * Done List handling functions + *-------------------------------------------------------------------------*/ + +-/* calculate transfer length/status and update the urb +- * PRECONDITION: irqsafe (only for urb->status locking) +- */ ++/* calculate transfer length/status and update the urb */ + static int td_done(struct admhcd *ahcd, struct urb *urb, struct td *td) + { + struct urb_priv *urb_priv = urb->hcpriv; +@@ -568,6 +565,7 @@ static int td_done(struct admhcd *ahcd, + u32 tdDBP; + int type = usb_pipetype(urb->pipe); + int cc; ++ int status = -EINPROGRESS; + + info = hc32_to_cpup(ahcd, &td->hwINFO); + tdDBP = hc32_to_cpup(ahcd, &td->hwDBP); +@@ -582,10 +580,9 @@ static int td_done(struct admhcd *ahcd, + /* NOTE: assumes FC in tdINFO == 0, and that + * only the first of 0..MAXPSW psws is used. + */ +-#if 0 +- if (tdINFO & TD_CC) /* hc didn't touch? */ +- return; +-#endif ++ if (info & TD_CC) /* hc didn't touch? */ ++ return status; ++ + if (usb_pipeout(urb->pipe)) + dlen = urb->iso_frame_desc[td->index].length; + else { +@@ -614,11 +611,9 @@ static int td_done(struct admhcd *ahcd, + && !(urb->transfer_flags & URB_SHORT_NOT_OK)) + cc = TD_CC_NOERROR; + +- if (cc != TD_CC_NOERROR && cc < TD_CC_HCD0) { +- spin_lock(&urb->lock); +- urb->status = cc_to_error[cc]; +- spin_unlock(&urb->lock); +- } ++ if (cc != TD_CC_NOERROR && cc < TD_CC_HCD0) ++ status = cc_to_error[cc]; ++ + + /* count all non-empty packets except control SETUP packet */ + if ((type != PIPE_CONTROL || td->index != 0) && tdDBP != 0) { +@@ -636,7 +631,7 @@ static int td_done(struct admhcd *ahcd, + list_del(&td->td_list); + urb_priv->td_idx++; + +- return cc; ++ return status; + } + + /*-------------------------------------------------------------------------*/ +@@ -771,6 +766,7 @@ rescan_this: + struct urb *urb; + struct urb_priv *urb_priv; + __hc32 savebits; ++ int status; + + td = list_entry(entry, struct td, td_list); + urb = td->urb; +@@ -792,12 +788,12 @@ rescan_this: + #ifdef ADMHC_VERBOSE_DEBUG + urb_print(ahcd, urb, "PARTIAL", 0); + #endif +- td_done(ahcd, urb, td); ++ status = td_done(ahcd, urb, td); + + /* if URB is done, clean up */ + if (urb_priv->td_idx == urb_priv->td_cnt) { + modified = completed = 1; +- finish_urb(ahcd, urb); ++ finish_urb(ahcd, urb, status); + } + } + if (completed && !list_empty(&ed->td_list)) +@@ -895,13 +891,13 @@ static void ed_update(struct admhcd *ahc + struct td *td = list_entry(entry, struct td, td_list); + struct urb *urb = td->urb; + struct urb_priv *urb_priv = urb->hcpriv; +- int cc; ++ int status; + + if (hc32_to_cpup(ahcd, &td->hwINFO) & TD_OWN) + break; + + /* update URB's length and status from TD */ +- cc = td_done(ahcd, urb, td); ++ status = td_done(ahcd, urb, td); + if (is_ed_halted(ahcd, ed) && is_td_halted(ahcd, ed, td)) + ed_unhalt(ahcd, ed, urb); + +@@ -910,7 +906,7 @@ static void ed_update(struct admhcd *ahc + + /* If all this urb's TDs are done, call complete() */ + if (urb_priv->td_idx == urb_priv->td_cnt) +- finish_urb(ahcd, urb); ++ finish_urb(ahcd, urb, status); + + /* clean schedule: unlink EDs that are no longer busy */ + if (list_empty(&ed->td_list)) { -- cgit v1.2.3