* Fix minor NAND JFFS2 related issue

* Fixes for SL811 USB controller:
  - implement workaround for broken memory stick
  - improve error handling

* Increase packet send timeout to 10 ms in cpu/mpc8xx/scc.c to better
  cope with congested networks.
diff --git a/drivers/sl811_usb.c b/drivers/sl811_usb.c
index a18e54d..ce5afe0 100644
--- a/drivers/sl811_usb.c
+++ b/drivers/sl811_usb.c
@@ -229,8 +229,8 @@
 int sl811_send_packet(int dir_to_host, int data1, __u8 *buffer, int len)
 {
 	__u8 ctrl = SL811_USB_CTRL_ARM | SL811_USB_CTRL_ENABLE;
-	__u16 status;
-	int err = 0;
+	__u16 status = 0;
+	int err = 0, timeout = get_timer(0) + 5*CFG_HZ;
 
 	if (len > 239)
 		return -1;
@@ -240,19 +240,26 @@
 	if (data1)
 		ctrl |= SL811_USB_CTRL_TOGGLE_1;
 
-	sl811_write(SL811_ADDR_A, 0x10);
-	sl811_write(SL811_LEN_A, len);
-	if (!dir_to_host && len)
-		sl811_write_buf(0x10, buffer, len);
+	sl811_write(SL811_INTRSTS, 0xff);
 
 	while (err < 3) {
+		sl811_write(SL811_ADDR_A, 0x10);
+		sl811_write(SL811_LEN_A, len);
+		if (!dir_to_host && len)
+			sl811_write_buf(0x10, buffer, len);
+
 		if (sl811_read(SL811_SOFCNTDIV)*64 < len * 8 * 2)
 			ctrl |= SL811_USB_CTRL_SOF;
 		else
 			ctrl &= ~SL811_USB_CTRL_SOF;
+
 		sl811_write(SL811_CTRL_A, ctrl);
-		while (!(sl811_read(SL811_INTRSTS) & SL811_INTR_DONE_A))
-			; /* do nothing */
+ 		while (!(sl811_read(SL811_INTRSTS) & SL811_INTR_DONE_A)) {
+			if (timeout < get_timer(0)) {
+				printf("USB transmit timed out\n");
+				return -USB_ST_CRC_ERR;
+			}
+		}
 
 		sl811_write(SL811_INTRSTS, 0xff);
 		status = sl811_read(SL811_STS_A);
@@ -275,7 +282,16 @@
 		err++;
 	}
 
-	return -1;
+	err = 0;
+
+	if (status & SL811_USB_STS_ERROR)
+		err |= USB_ST_BUF_ERR;
+	if (status & SL811_USB_STS_TIMEOUT)
+		err |= USB_ST_CRC_ERR;
+	if (status & SL811_USB_STS_STALL)
+		err |= USB_ST_STALLED;
+
+	return -err;
 }
 
 int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
@@ -299,7 +315,7 @@
 					    buf+done,
 					    max > len - done ? len - done : max);
 		if (res < 0) {
-			dev->status = res;
+			dev->status = -res;
 			return res;
 		}
 
@@ -345,8 +361,10 @@
 		while (done < len) {
 			int res = sl811_send_packet(dir_in, data1, buf+done,
 						    max > len - done ? len - done : max);
-			if (res < 0)
-				return res;
+			if (res < 0) {
+				dev->status = -res;
+				return 0;
+			}
 			done += res;
 
 			if (dir_in && res < max) /* short packet */
@@ -375,7 +393,7 @@
 int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 		   int len, int interval)
 {
-	PDEBUG(7, "dev = %p pipe = %#lx buf = %p size = %d int = %d\n", dev, pipe,
+	PDEBUG(0, "dev = %p pipe = %#lx buf = %p size = %d int = %d\n", dev, pipe,
 	       buffer, len, interval);
 	return -1;
 }