Fixes for uhci

Pavel Machek (pavel@bug.ucw.cz)
Tue, 21 Sep 1999 17:43:49 +0200


Hi!

Without this, uhci discards about half of characters coming from
modem, making it useless. Please apply.

Pavel
[PS: I do not know who is original author of this. I extracted this
fix from bigger patch which touched much too much things for me to
like it. Relative to 2.3.18, but will apply cleanly to ac7.]

PPS: BTW, alan, ac7 will not boot for me, it oopses while trying to
read partition table. Let me know if you are interested.

--- clean//drivers/usb/uhci.c Sat Sep 11 20:56:02 1999
+++ linux/drivers/usb/uhci.c Tue Sep 21 17:37:41 1999
@@ -126,7 +126,7 @@
{
unsigned int status;
struct uhci_td *tmp;
- int count = 1000;
+ int count = 1000, bytesreceived = 0;

if (rval)
*rval = 0;
@@ -144,8 +144,10 @@
do {
status = uhci_status_bits(tmp->status);

- if (status) {
- if (debug) {
+ if (status)
+ break;
+#if 0
+ if (debug) {
/* Must reset the toggle on first error */
if (uhci_debug) {
printk(KERN_DEBUG "Set toggle from %x rval %ld\n",
@@ -161,6 +163,13 @@
if (rval && ((tmp->info & 0xFF) == USB_PID_IN))
*rval += uhci_actual_length(tmp->status);
}
+#endif
+ /* The length field is only valid if the TD was completed */
+ if (!(tmp->status & TD_CTRL_ACTIVE) && uhci_packetin(tmp->info)) {
+ bytesreceived += uhci_actual_length(tmp->status);
+ if (rval)
+ *rval += uhci_actual_length(tmp->status);
+ }

if ((tmp->link & UHCI_PTR_TERM) ||
(tmp->link & UHCI_PTR_QH))
@@ -173,8 +182,35 @@
printk(KERN_ERR "runaway td's in uhci_td_result!\n");
/* Force debugging on */
debug = 1;
- } else if (!status)
- return USB_ST_NOERROR;
+ } else {
+ /* If we got to the last TD */
+
+ /* No error */
+ if (!status)
+ return USB_ST_NOERROR;
+
+ /* APC BackUPS Pro kludge */
+ /* It tries to send all of the descriptor instead of */
+ /* the amount we requested */
+ if (tmp->status & TD_CTRL_IOC &&
+ tmp->status & TD_CTRL_ACTIVE &&
+ tmp->status & TD_CTRL_NAK)
+ return USB_ST_NOERROR;
+
+#if 0
+ /* We got to an error, but the controller hasn't finished */
+ /* with it, yet */
+ if (tmp->status & TD_CTRL_ACTIVE)
+ return USB_ST_NOCHANGE;
+#endif
+
+ /* If this wasn't the last TD and SPD is set, ACTIVE */
+ /* is not and NAK isn't then we received a short */
+ /* packet */
+ if (tmp->status & TD_CTRL_SPD &&
+ !(tmp->status & TD_CTRL_NAK))
+ return USB_ST_NOERROR;
+ }

/* Some debugging code */
if (debug && uhci_debug) {

-- 
I'm also pavel@suse.de.
Hi! I'm a .signature virus! Copy me into your ~/.signature, please!

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/