Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

USB: usbtest fix endless loop in unlink tests.

In tests 11 and 12 if the URB completes with an error status (eg babble)
the asynchrous unlink entered an endless loop trying to unlink
a non resubmitted URB.

Signed-off-by: Martin Fuzzey <mfuzzey@gmail.com>
Acked-by: David Brownell <david-b@pacbell.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Martin Fuzzey and committed by
Greg Kroah-Hartman
3b6c023f e60c65d3

+25 -14
+25 -14
drivers/usb/misc/usbtest.c
··· 1072 1072 */ 1073 1073 msleep (jiffies % (2 * INTERRUPT_RATE)); 1074 1074 if (async) { 1075 - retry: 1076 - retval = usb_unlink_urb (urb); 1077 - if (retval == -EBUSY || retval == -EIDRM) { 1078 - /* we can't unlink urbs while they're completing. 1079 - * or if they've completed, and we haven't resubmitted. 1080 - * "normal" drivers would prevent resubmission, but 1081 - * since we're testing unlink paths, we can't. 1082 - */ 1083 - ERROR(dev, "unlink retry\n"); 1084 - goto retry; 1075 + while (!completion_done(&completion)) { 1076 + retval = usb_unlink_urb(urb); 1077 + 1078 + switch (retval) { 1079 + case -EBUSY: 1080 + case -EIDRM: 1081 + /* we can't unlink urbs while they're completing 1082 + * or if they've completed, and we haven't 1083 + * resubmitted. "normal" drivers would prevent 1084 + * resubmission, but since we're testing unlink 1085 + * paths, we can't. 1086 + */ 1087 + ERROR(dev, "unlink retry\n"); 1088 + continue; 1089 + case 0: 1090 + case -EINPROGRESS: 1091 + break; 1092 + 1093 + default: 1094 + dev_err(&dev->intf->dev, 1095 + "unlink fail %d\n", retval); 1096 + return retval; 1097 + } 1098 + 1099 + break; 1085 1100 } 1086 1101 } else 1087 1102 usb_kill_urb (urb); 1088 - if (!(retval == 0 || retval == -EINPROGRESS)) { 1089 - dev_err(&dev->intf->dev, "unlink fail %d\n", retval); 1090 - return retval; 1091 - } 1092 1103 1093 1104 wait_for_completion (&completion); 1094 1105 retval = urb->status;