Commit 52f62ca4 authored by Romain Liévin's avatar Romain Liévin Committed by Linus Torvalds

[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.
parent b157e37f
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* tiglusb -- Texas Instruments' USB GraphLink (aka SilverLink) driver. * tiglusb -- Texas Instruments' USB GraphLink (aka SilverLink) driver.
* Target: Texas Instruments graphing calculators (http://lpg.ticalc.org). * Target: Texas Instruments graphing calculators (http://lpg.ticalc.org).
* *
* Copyright (C) 2001-2002: * Copyright (C) 2001-2004:
* Romain Lievin <roms@lpg.ticalc.org> * Romain Lievin <roms@lpg.ticalc.org>
* Julien BLACHE <jb@technologeek.org> * Julien BLACHE <jb@technologeek.org>
* under the terms of the GNU General Public License. * under the terms of the GNU General Public License.
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
* 1.04, Julien: clean-up & fixes; Romain: 2.4 backport. * 1.04, Julien: clean-up & fixes; Romain: 2.4 backport.
* 1.05, Randy Dunlap: bug fix with the timeout parameter (divide-by-zero). * 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.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 <linux/module.h> #include <linux/module.h>
...@@ -38,8 +40,8 @@ ...@@ -38,8 +40,8 @@
/* /*
* Version Information * Version Information
*/ */
#define DRIVER_VERSION "1.06" #define DRIVER_VERSION "1.07"
#define DRIVER_AUTHOR "Romain Lievin <roms@lpg.ticalc.org> & Julien Blache <jb@jblache.org>" #define DRIVER_AUTHOR "Romain Lievin <roms@tilp.info> & Julien Blache <jb@jblache.org>"
#define DRIVER_DESC "TI-GRAPH LINK USB (aka SilverLink) driver" #define DRIVER_DESC "TI-GRAPH LINK USB (aka SilverLink) driver"
#define DRIVER_LICENSE "GPL" #define DRIVER_LICENSE "GPL"
...@@ -72,15 +74,15 @@ clear_pipes (struct usb_device *dev) ...@@ -72,15 +74,15 @@ clear_pipes (struct usb_device *dev)
{ {
unsigned int pipe; unsigned int pipe;
pipe = usb_sndbulkpipe (dev, 1); pipe = usb_sndbulkpipe (dev, 2);
if (usb_clear_halt (dev, usb_pipeendpoint (pipe))) { if (usb_clear_halt (dev, pipe)) {
err ("clear_pipe (r), request failed"); err ("clear_pipe (w), request failed");
return -1; return -1;
} }
pipe = usb_sndbulkpipe (dev, 2); pipe = usb_rcvbulkpipe (dev, 1);
if (usb_clear_halt (dev, usb_pipeendpoint (pipe))) { if (usb_clear_halt (dev, pipe)) {
err ("clear_pipe (w), request failed"); err ("clear_pipe (r), request failed");
return -1; return -1;
} }
...@@ -181,17 +183,16 @@ tiglusb_read (struct file *filp, char __user *buf, size_t count, loff_t * f_pos) ...@@ -181,17 +183,16 @@ tiglusb_read (struct file *filp, char __user *buf, size_t count, loff_t * f_pos)
pipe = usb_rcvbulkpipe (s->dev, 1); pipe = usb_rcvbulkpipe (s->dev, 1);
result = usb_bulk_msg (s->dev, pipe, buffer, bytes_to_read, 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 */ if (result == -ETIMEDOUT) { /* NAK */
ret = result; if (!bytes_read)
if (!bytes_read) {
dbg ("quirk !"); dbg ("quirk !");
}
warn ("tiglusb_read, NAK received."); warn ("tiglusb_read, NAK received.");
ret = result;
goto out; goto out;
} else if (result == -EPIPE) { /* STALL -- shouldn't happen */ } else if (result == -EPIPE) { /* STALL -- shouldn't happen */
warn ("clear_halt request to remove STALL condition."); 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"); err ("clear_halt, request failed");
clear_device (s->dev); clear_device (s->dev);
ret = result; ret = result;
...@@ -243,7 +244,7 @@ tiglusb_write (struct file *filp, const char __user *buf, size_t count, loff_t * ...@@ -243,7 +244,7 @@ tiglusb_write (struct file *filp, const char __user *buf, size_t count, loff_t *
pipe = usb_sndbulkpipe (s->dev, 2); pipe = usb_sndbulkpipe (s->dev, 2);
result = usb_bulk_msg (s->dev, pipe, buffer, bytes_to_write, 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 */ if (result == -ETIMEDOUT) { /* NAK */
warn ("tiglusb_write, NAK received."); warn ("tiglusb_write, NAK received.");
...@@ -251,7 +252,7 @@ tiglusb_write (struct file *filp, const char __user *buf, size_t count, loff_t * ...@@ -251,7 +252,7 @@ tiglusb_write (struct file *filp, const char __user *buf, size_t count, loff_t *
goto out; goto out;
} else if (result == -EPIPE) { /* STALL -- shouldn't happen */ } else if (result == -EPIPE) { /* STALL -- shouldn't happen */
warn ("clear_halt request to remove STALL condition."); 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"); err ("clear_halt, request failed");
clear_device (s->dev); clear_device (s->dev);
ret = result; ret = result;
...@@ -292,15 +293,16 @@ tiglusb_ioctl (struct inode *inode, struct file *filp, ...@@ -292,15 +293,16 @@ tiglusb_ioctl (struct inode *inode, struct file *filp,
switch (cmd) { switch (cmd) {
case IOCTL_TIUSB_TIMEOUT: case IOCTL_TIUSB_TIMEOUT:
timeout = arg; // timeout value in tenth of seconds if (arg > 0)
timeout = arg;
else
ret = -EINVAL;
break; break;
case IOCTL_TIUSB_RESET_DEVICE: case IOCTL_TIUSB_RESET_DEVICE:
dbg ("IOCTL_TIGLUSB_RESET_DEVICE");
if (clear_device (s->dev)) if (clear_device (s->dev))
ret = -EIO; ret = -EIO;
break; break;
case IOCTL_TIUSB_RESET_PIPES: case IOCTL_TIUSB_RESET_PIPES:
dbg ("IOCTL_TIGLUSB_RESET_PIPES");
if (clear_pipes (s->dev)) if (clear_pipes (s->dev))
ret = -EIO; ret = -EIO;
break; break;
...@@ -447,7 +449,7 @@ static struct usb_driver tiglusb_driver = { ...@@ -447,7 +449,7 @@ static struct usb_driver tiglusb_driver = {
#ifndef MODULE #ifndef MODULE
/* /*
* You can use 'tiusb=timeout' * You can use 'tiusb=timeout' to set timeout.
*/ */
static int __init static int __init
tiglusb_setup (char *str) tiglusb_setup (char *str)
...@@ -457,10 +459,11 @@ tiglusb_setup (char *str) ...@@ -457,10 +459,11 @@ tiglusb_setup (char *str)
str = get_options (str, ARRAY_SIZE (ints), ints); str = get_options (str, ARRAY_SIZE (ints), ints);
if (ints[0] > 0) { 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; return 1;
} }
...@@ -502,9 +505,6 @@ tiglusb_init (void) ...@@ -502,9 +505,6 @@ tiglusb_init (void)
info (DRIVER_DESC ", version " DRIVER_VERSION); info (DRIVER_DESC ", version " DRIVER_VERSION);
if (timeout <= 0)
timeout = TIMAXTIME;
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment