musb-new: Properly remove a transfer from the schedule on timeout
If a transfer / urb times-out, properly remove it from the schedule, rather then letting it sit on the ep head. This stops the musb code from getting confused and refusing to queue further transfers after a timeout. Tested by unplugging a usb-keyboard, replugging it and doing a usb-reset, before this commit the keyboard would not work after the usb-reset. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
		
							parent
							
								
									90cdc1039d
								
							
						
					
					
						commit
						b918a0c6f6
					
				| 
						 | 
				
			
			@ -2130,8 +2130,6 @@ done:
 | 
			
		|||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef __UBOOT__
 | 
			
		||||
/*
 | 
			
		||||
 * abort a transfer that's at the head of a hardware queue.
 | 
			
		||||
 * called with controller locked, irqs blocked
 | 
			
		||||
| 
						 | 
				
			
			@ -2195,7 +2193,14 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh)
 | 
			
		|||
	return status;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 | 
			
		||||
#ifndef __UBOOT__
 | 
			
		||||
static int musb_urb_dequeue(
 | 
			
		||||
#else
 | 
			
		||||
int musb_urb_dequeue(
 | 
			
		||||
#endif
 | 
			
		||||
	struct usb_hcd *hcd,
 | 
			
		||||
	struct urb *urb,
 | 
			
		||||
	int status)
 | 
			
		||||
{
 | 
			
		||||
	struct musb		*musb = hcd_to_musb(hcd);
 | 
			
		||||
	struct musb_qh		*qh;
 | 
			
		||||
| 
						 | 
				
			
			@ -2253,6 +2258,7 @@ done:
 | 
			
		|||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifndef __UBOOT__
 | 
			
		||||
/* disable an endpoint */
 | 
			
		||||
static void
 | 
			
		||||
musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -110,5 +110,6 @@ static inline struct urb *next_urb(struct musb_qh *qh)
 | 
			
		|||
 | 
			
		||||
#ifdef __UBOOT__
 | 
			
		||||
int musb_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags);
 | 
			
		||||
int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status);
 | 
			
		||||
#endif
 | 
			
		||||
#endif				/* _MUSB_HOST_H */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,6 +77,9 @@ static int submit_urb(struct usb_hcd *hcd, struct urb *urb)
 | 
			
		|||
	} while (urb->status == -EINPROGRESS &&
 | 
			
		||||
		 get_timer(0) < timeout);
 | 
			
		||||
 | 
			
		||||
	if (urb->status == -EINPROGRESS)
 | 
			
		||||
		musb_urb_dequeue(hcd, urb, -ETIME);
 | 
			
		||||
 | 
			
		||||
	return urb->status;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,6 +48,7 @@ struct urb {
 | 
			
		|||
	list_add_tail(&urb->urb_list, &urb->ep->urb_list);	\
 | 
			
		||||
	ret; })
 | 
			
		||||
#define usb_hcd_unlink_urb_from_ep(hcd, urb)	list_del_init(&urb->urb_list)
 | 
			
		||||
#define usb_hcd_check_unlink_urb(hdc, urb, status)	0
 | 
			
		||||
 | 
			
		||||
static inline void usb_hcd_giveback_urb(struct usb_hcd *hcd,
 | 
			
		||||
					struct urb *urb,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue