Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=0ffbbe25a73db12792a05f725aa39f8a5de2c882
Commit:     0ffbbe25a73db12792a05f725aa39f8a5de2c882
Parent:     a69228deefea57ca27c17a196e5727b091c6d323
Author:     Oliver Neukum <[EMAIL PROTECTED]>
AuthorDate: Mon Jul 9 12:03:08 2007 -0700
Committer:  Greg Kroah-Hartman <[EMAIL PROTECTED]>
CommitDate: Thu Jul 12 16:34:40 2007 -0700

    USB: ftdi_sio: fix oops due to processing workarounds too early
    
    Fix an oops that happens in relation with applying work arounds for buggy
    ftdi_sio devices.  The quirks were handled too early because due to changes 
in
    the initialisation of usb serial devices the device was not fully 
initialised
    when the old hook was called.
    
    Addresses bug 8564
    
    Cc: <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>
---
 drivers/usb/serial/ftdi_sio.c |  104 +++++++++++++++++-----------------------
 1 files changed, 44 insertions(+), 60 deletions(-)

diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 4066a46..7b1673a 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -271,26 +271,58 @@ static int debug;
 static __u16 vendor = FTDI_VID;
 static __u16 product;
 
+struct ftdi_private {
+       ftdi_chip_type_t chip_type;
+                               /* type of the device, either SIO or FT8U232AM 
*/
+       int baud_base;          /* baud base clock for divisor setting */
+       int custom_divisor;     /* custom_divisor kludge, this is for baud_base 
(different from what goes to the chip!) */
+       __u16 last_set_data_urb_value ;
+                               /* the last data state set - needed for doing a 
break */
+        int write_offset;       /* This is the offset in the usb data block to 
write the serial data -
+                                * it is different between devices
+                                */
+       int flags;              /* some ASYNC_xxxx flags are supported */
+       unsigned long last_dtr_rts;     /* saved modem control outputs */
+        wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
+       char prev_status, diff_status;        /* Used for TIOCMIWAIT */
+       __u8 rx_flags;          /* receive state flags (throttling) */
+       spinlock_t rx_lock;     /* spinlock for receive state */
+       struct delayed_work rx_work;
+       struct usb_serial_port *port;
+       int rx_processed;
+       unsigned long rx_bytes;
+
+       __u16 interface;        /* FT2232C port interface (0 for FT232/245) */
+
+       int force_baud;         /* if non-zero, force the baud rate to this 
value */
+       int force_rtscts;       /* if non-zero, force RTS-CTS to always be 
enabled */
+
+       spinlock_t tx_lock;     /* spinlock for transmit state */
+       unsigned long tx_bytes;
+       unsigned long tx_outstanding_bytes;
+       unsigned long tx_outstanding_urbs;
+};
+
 /* struct ftdi_sio_quirk is used by devices requiring special attention. */
 struct ftdi_sio_quirk {
        int (*probe)(struct usb_serial *);
-       void (*setup)(struct usb_serial *); /* Special settings during startup. 
*/
+       void (*port_probe)(struct ftdi_private *); /* Special settings for 
probed ports. */
 };
 
 static int   ftdi_olimex_probe         (struct usb_serial *serial);
-static void  ftdi_USB_UIRT_setup       (struct usb_serial *serial);
-static void  ftdi_HE_TIRA1_setup       (struct usb_serial *serial);
+static void  ftdi_USB_UIRT_setup       (struct ftdi_private *priv);
+static void  ftdi_HE_TIRA1_setup       (struct ftdi_private *priv);
 
 static struct ftdi_sio_quirk ftdi_olimex_quirk = {
        .probe  = ftdi_olimex_probe,
 };
 
 static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
-       .setup = ftdi_USB_UIRT_setup,
+       .port_probe = ftdi_USB_UIRT_setup,
 };
 
 static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = {
-       .setup = ftdi_HE_TIRA1_setup,
+       .port_probe = ftdi_HE_TIRA1_setup,
 };
 
 /*
@@ -567,38 +599,6 @@ static const char *ftdi_chip_name[] = {
 #define THROTTLED              0x01
 #define ACTUALLY_THROTTLED     0x02
 
-struct ftdi_private {
-       ftdi_chip_type_t chip_type;
-                               /* type of the device, either SIO or FT8U232AM 
*/
-       int baud_base;          /* baud base clock for divisor setting */
-       int custom_divisor;     /* custom_divisor kludge, this is for baud_base 
(different from what goes to the chip!) */
-       __u16 last_set_data_urb_value ;
-                               /* the last data state set - needed for doing a 
break */
-        int write_offset;       /* This is the offset in the usb data block to 
write the serial data -
-                                * it is different between devices
-                                */
-       int flags;              /* some ASYNC_xxxx flags are supported */
-       unsigned long last_dtr_rts;     /* saved modem control outputs */
-        wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
-       char prev_status, diff_status;        /* Used for TIOCMIWAIT */
-       __u8 rx_flags;          /* receive state flags (throttling) */
-       spinlock_t rx_lock;     /* spinlock for receive state */
-       struct delayed_work rx_work;
-       struct usb_serial_port *port;
-       int rx_processed;
-       unsigned long rx_bytes;
-
-       __u16 interface;        /* FT2232C port interface (0 for FT232/245) */
-
-       int force_baud;         /* if non-zero, force the baud rate to this 
value */
-       int force_rtscts;       /* if non-zero, force RTS-CTS to always be 
enabled */
-
-       spinlock_t tx_lock;     /* spinlock for transmit state */
-       unsigned long tx_bytes;
-       unsigned long tx_outstanding_bytes;
-       unsigned long tx_outstanding_urbs;
-};
-
 /* Used for TIOCMIWAIT */
 #define FTDI_STATUS_B0_MASK    (FTDI_RS0_CTS | FTDI_RS0_DSR | FTDI_RS0_RI | 
FTDI_RS0_RLSD)
 #define FTDI_STATUS_B1_MASK    (FTDI_RS_BI)
@@ -609,7 +609,6 @@ struct ftdi_private {
 
 /* function prototypes for a FTDI serial converter */
 static int  ftdi_sio_probe     (struct usb_serial *serial, const struct 
usb_device_id *id);
-static int  ftdi_sio_attach            (struct usb_serial *serial);
 static void ftdi_shutdown              (struct usb_serial *serial);
 static int  ftdi_sio_port_probe        (struct usb_serial_port *port);
 static int  ftdi_sio_port_remove       (struct usb_serial_port *port);
@@ -663,7 +662,6 @@ static struct usb_serial_driver ftdi_sio_device = {
        .ioctl =                ftdi_ioctl,
        .set_termios =          ftdi_set_termios,
        .break_ctl =            ftdi_break_ctl,
-       .attach =               ftdi_sio_attach,
        .shutdown =             ftdi_shutdown,
 };
 
@@ -1200,6 +1198,8 @@ static int ftdi_sio_probe (struct usb_serial *serial, 
const struct usb_device_id
 static int ftdi_sio_port_probe(struct usb_serial_port *port)
 {
        struct ftdi_private *priv;
+       struct ftdi_sio_quirk *quirk = usb_get_serial_data(port->serial);
+
 
        dbg("%s",__FUNCTION__);
 
@@ -1216,6 +1216,9 @@ static int ftdi_sio_port_probe(struct usb_serial_port 
*port)
           than queue a task to deliver them */
        priv->flags = ASYNC_LOW_LATENCY;
 
+       if (quirk && quirk->port_probe)
+               quirk->port_probe(priv);
+
        /* Increase the size of read buffers */
        kfree(port->bulk_in_buffer);
        port->bulk_in_buffer = kmalloc (BUFSZ, GFP_KERNEL);
@@ -1246,29 +1249,13 @@ static int ftdi_sio_port_probe(struct usb_serial_port 
*port)
        return 0;
 }
 
-/* attach subroutine */
-static int ftdi_sio_attach (struct usb_serial *serial)
-{
-       /* Check for device requiring special set up. */
-       struct ftdi_sio_quirk *quirk = usb_get_serial_data(serial);
-
-       if (quirk && quirk->setup)
-               quirk->setup(serial);
-
-       return 0;
-} /* ftdi_sio_attach */
-
-
 /* Setup for the USB-UIRT device, which requires hardwired
  * baudrate (38400 gets mapped to 312500) */
 /* Called from usbserial:serial_probe */
-static void ftdi_USB_UIRT_setup (struct usb_serial *serial)
+static void ftdi_USB_UIRT_setup (struct ftdi_private *priv)
 {
-       struct ftdi_private *priv;
-
        dbg("%s",__FUNCTION__);
 
-       priv = usb_get_serial_port_data(serial->port[0]);
        priv->flags |= ASYNC_SPD_CUST;
        priv->custom_divisor = 77;
        priv->force_baud = B38400;
@@ -1276,13 +1263,10 @@ static void ftdi_USB_UIRT_setup (struct usb_serial 
*serial)
 
 /* Setup for the HE-TIRA1 device, which requires hardwired
  * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled.  */
-static void ftdi_HE_TIRA1_setup (struct usb_serial *serial)
+static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv)
 {
-       struct ftdi_private *priv;
-
        dbg("%s",__FUNCTION__);
 
-       priv = usb_get_serial_port_data(serial->port[0]);
        priv->flags |= ASYNC_SPD_CUST;
        priv->custom_divisor = 240;
        priv->force_baud = B38400;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to