# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.524.9.8 -> 1.524.9.9 # drivers/usb/serial/ipaq.c 1.14 -> 1.15 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/08/01 ganesh@vxindia.veritas.com 1.524.9.9 # [PATCH] bugfix for drivers/usb/serial/ipaq.c # # Buggy error handling fixed. Retry the "kickstart" packet much harder - # this greatly reduces instances of connection failures. # -------------------------------------------- # diff -Nru a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c --- a/drivers/usb/serial/ipaq.c Fri Aug 2 11:15:34 2002 +++ b/drivers/usb/serial/ipaq.c Fri Aug 2 11:15:34 2002 @@ -9,6 +9,10 @@ * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * + * (26/7/2002) ganesh + * Fixed up broken error handling in ipaq_open. Retry the "kickstart" + * packet much harder - this drastically reduces connection failures. + * * (30/4/2002) ganesh * Added support for the Casio EM500. Completely untested. Thanks * to info from Nathan @@ -54,6 +58,8 @@ #include "usb-serial.h" #include "ipaq.h" +#define KP_RETRIES 100 + /* * Version Information */ @@ -118,6 +124,7 @@ struct ipaq_private *priv; struct ipaq_packet *pkt; int i, result = 0; + int retries = KP_RETRIES; if (port_paranoia_check(port, __FUNCTION__)) { return -ENODEV; @@ -192,31 +199,35 @@ result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) { err(__FUNCTION__ " - failed submitting read urb, error %d", result); + goto error; } /* - * Send out two control messages observed in win98 sniffs. Not sure what - * they do. + * Send out control message observed in win98 sniffs. Not sure what + * it does, but from empirical observations, it seems that the device + * will start the chat sequence once one of these messages gets + * through. Since this has a reasonably high failure rate, we retry + * several times. */ - result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 0x22, 0x21, - 0x1, 0, NULL, 0, 5 * HZ); - if (result < 0) { - err(__FUNCTION__ " - failed doing control urb, error %d", result); - } - result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 0x22, 0x21, - 0x1, 0, NULL, 0, 5 * HZ); - if (result < 0) { - err(__FUNCTION__ " - failed doing control urb, error %d", result); + while (retries--) { + result = usb_control_msg(serial->dev, + usb_sndctrlpipe(serial->dev, 0), 0x22, 0x21, + 0x1, 0, NULL, 0, HZ / 10 + 1); + if (result == 0) { + return 0; + } } - - return result; + err(__FUNCTION__ " - failed doing control urb, error %d", result); + goto error; enomem: + result = -ENOMEM; + err(__FUNCTION__ " - Out of memory"); +error: ipaq_destroy_lists(port); kfree(priv); - err(__FUNCTION__ " - Out of memory"); - return -ENOMEM; + return result; }