ChangeSet 1.1934, 2004/04/22 13:53:08-07:00, lkml@lievin.net [PATCH] USB: tiglusb: wrong timeout value Hi, this patch (cumulative; 2.4 & 2.6) fixes another bug in the tiglusb driver. The formula used to calculate jiffies from timeout is wrong. The new formula is ok and takes care of integer computation/rounding. This is the same kind of bug than in the tipar char driver. drivers/usb/misc/tiglusb.c | 52 ++++++++++++++++++++++----------------------- 1 files changed, 26 insertions(+), 26 deletions(-) diff -Nru a/drivers/usb/misc/tiglusb.c b/drivers/usb/misc/tiglusb.c --- a/drivers/usb/misc/tiglusb.c Thu Apr 22 14:41:11 2004 +++ b/drivers/usb/misc/tiglusb.c Thu Apr 22 14:41:11 2004 @@ -3,7 +3,7 @@ * tiglusb -- Texas Instruments' USB GraphLink (aka SilverLink) driver. * Target: Texas Instruments graphing calculators (http://lpg.ticalc.org). * - * Copyright (C) 2001-2002: + * Copyright (C) 2001-2004: * Romain Lievin * Julien BLACHE * under the terms of the GNU General Public License. @@ -20,6 +20,8 @@ * 1.04, Julien: clean-up & fixes; Romain: 2.4 backport. * 1.05, Randy Dunlap: bug fix with the timeout parameter (divide-by-zero). * 1.06, Romain: synched with 2.5, version/firmware changed (confusing). + * 1.07, Romain: fixed bad use of usb_clear_halt (invalid argument); + * timeout argument checked in ioctl + clean-up. */ #include @@ -38,8 +40,8 @@ /* * Version Information */ -#define DRIVER_VERSION "1.06" -#define DRIVER_AUTHOR "Romain Lievin & Julien Blache " +#define DRIVER_VERSION "1.07" +#define DRIVER_AUTHOR "Romain Lievin & Julien Blache " #define DRIVER_DESC "TI-GRAPH LINK USB (aka SilverLink) driver" #define DRIVER_LICENSE "GPL" @@ -72,15 +74,15 @@ { unsigned int pipe; - pipe = usb_sndbulkpipe (dev, 1); - if (usb_clear_halt (dev, usb_pipeendpoint (pipe))) { - err ("clear_pipe (r), request failed"); + pipe = usb_sndbulkpipe (dev, 2); + if (usb_clear_halt (dev, pipe)) { + err ("clear_pipe (w), request failed"); return -1; } - pipe = usb_sndbulkpipe (dev, 2); - if (usb_clear_halt (dev, usb_pipeendpoint (pipe))) { - err ("clear_pipe (w), request failed"); + pipe = usb_rcvbulkpipe (dev, 1); + if (usb_clear_halt (dev, pipe)) { + err ("clear_pipe (r), request failed"); return -1; } @@ -181,17 +183,16 @@ pipe = usb_rcvbulkpipe (s->dev, 1); result = usb_bulk_msg (s->dev, pipe, buffer, bytes_to_read, - &bytes_read, HZ * 10 / timeout); + &bytes_read, (HZ * timeout) / 10); if (result == -ETIMEDOUT) { /* NAK */ - ret = result; - if (!bytes_read) { + if (!bytes_read) dbg ("quirk !"); - } warn ("tiglusb_read, NAK received."); + ret = result; goto out; } else if (result == -EPIPE) { /* STALL -- shouldn't happen */ warn ("clear_halt request to remove STALL condition."); - if (usb_clear_halt (s->dev, usb_pipeendpoint (pipe))) + if (usb_clear_halt (s->dev, pipe)) err ("clear_halt, request failed"); clear_device (s->dev); ret = result; @@ -243,7 +244,7 @@ pipe = usb_sndbulkpipe (s->dev, 2); result = usb_bulk_msg (s->dev, pipe, buffer, bytes_to_write, - &bytes_written, HZ * 10 / timeout); + &bytes_written, (HZ * timeout) / 10); if (result == -ETIMEDOUT) { /* NAK */ warn ("tiglusb_write, NAK received."); @@ -251,7 +252,7 @@ goto out; } else if (result == -EPIPE) { /* STALL -- shouldn't happen */ warn ("clear_halt request to remove STALL condition."); - if (usb_clear_halt (s->dev, usb_pipeendpoint (pipe))) + if (usb_clear_halt (s->dev, pipe)) err ("clear_halt, request failed"); clear_device (s->dev); ret = result; @@ -292,15 +293,16 @@ switch (cmd) { case IOCTL_TIUSB_TIMEOUT: - timeout = arg; // timeout value in tenth of seconds + if (arg > 0) + timeout = arg; + else + ret = -EINVAL; break; case IOCTL_TIUSB_RESET_DEVICE: - dbg ("IOCTL_TIGLUSB_RESET_DEVICE"); if (clear_device (s->dev)) ret = -EIO; break; case IOCTL_TIUSB_RESET_PIPES: - dbg ("IOCTL_TIGLUSB_RESET_PIPES"); if (clear_pipes (s->dev)) ret = -EIO; break; @@ -447,7 +449,7 @@ #ifndef MODULE /* - * You can use 'tiusb=timeout' + * You can use 'tiusb=timeout' to set timeout. */ static int __init tiglusb_setup (char *str) @@ -457,10 +459,11 @@ str = get_options (str, ARRAY_SIZE (ints), ints); if (ints[0] > 0) { - timeout = ints[1]; + if (ints[1] > 0) + timeout = ints[1]; + else + info ("tiglusb: wrong timeout value (0), using default value."); } - if (timeout <= 0) - timeout = TIMAXTIME; return 1; } @@ -501,9 +504,6 @@ } info (DRIVER_DESC ", version " DRIVER_VERSION); - - if (timeout <= 0) - timeout = TIMAXTIME; return 0; }