This is a note to let you know that I've just added the patch titled

    USB: serial: mos7840: Fixed MCS7820 device attach problem

to the 3.3-stable tree which can be found at:
    
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     usb-serial-mos7840-fixed-mcs7820-device-attach-problem.patch
and it can be found in the queue-3.3 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <[email protected]> know about it.


>From 093ea2d3a766cb8a4c4de57efec6c0a127a58792 Mon Sep 17 00:00:00 2001
From: Donald Lee <[email protected]>
Date: Wed, 14 Mar 2012 15:26:33 +0800
Subject: USB: serial: mos7840: Fixed MCS7820 device attach problem

From: Donald Lee <[email protected]>

commit 093ea2d3a766cb8a4c4de57efec6c0a127a58792 upstream.

A MCS7820 device supports two serial ports and a MCS7840 device supports
four serial ports. Both devices use the same driver, but the attach function
in driver was unable to correctly handle the port numbers for MCS7820
device. This problem has been fixed in this patch and this fix has been
verified on x86 Linux kernel 3.2.9 with both MCS7820 and MCS7840 devices.

Signed-off-by: Donald Lee <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
 drivers/usb/serial/mos7840.c |   81 +++++++++++++++++++++++++++++--------------
 1 file changed, 56 insertions(+), 25 deletions(-)

--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -174,6 +174,7 @@
 
 #define CLK_MULTI_REGISTER         ((__u16)(0x02))
 #define CLK_START_VALUE_REGISTER   ((__u16)(0x03))
+#define GPIO_REGISTER              ((__u16)(0x07))
 
 #define SERIAL_LCR_DLAB            ((__u16)(0x0080))
 
@@ -1101,14 +1102,25 @@ static int mos7840_open(struct tty_struc
        mos7840_port->read_urb = port->read_urb;
 
        /* set up our bulk in urb */
-
-       usb_fill_bulk_urb(mos7840_port->read_urb,
-                         serial->dev,
-                         usb_rcvbulkpipe(serial->dev,
-                                         port->bulk_in_endpointAddress),
-                         port->bulk_in_buffer,
-                         mos7840_port->read_urb->transfer_buffer_length,
-                         mos7840_bulk_in_callback, mos7840_port);
+       if ((serial->num_ports == 2)
+               && ((((__u16)port->number -
+                       (__u16)(port->serial->minor)) % 2) != 0)) {
+               usb_fill_bulk_urb(mos7840_port->read_urb,
+                       serial->dev,
+                       usb_rcvbulkpipe(serial->dev,
+                               (port->bulk_in_endpointAddress) + 2),
+                       port->bulk_in_buffer,
+                       mos7840_port->read_urb->transfer_buffer_length,
+                       mos7840_bulk_in_callback, mos7840_port);
+       } else {
+               usb_fill_bulk_urb(mos7840_port->read_urb,
+                       serial->dev,
+                       usb_rcvbulkpipe(serial->dev,
+                               port->bulk_in_endpointAddress),
+                       port->bulk_in_buffer,
+                       mos7840_port->read_urb->transfer_buffer_length,
+                       mos7840_bulk_in_callback, mos7840_port);
+       }
 
        dbg("mos7840_open: bulkin endpoint is %d",
            port->bulk_in_endpointAddress);
@@ -1519,13 +1531,25 @@ static int mos7840_write(struct tty_stru
        memcpy(urb->transfer_buffer, current_position, transfer_size);
 
        /* fill urb with data and submit  */
-       usb_fill_bulk_urb(urb,
-                         serial->dev,
-                         usb_sndbulkpipe(serial->dev,
-                                         port->bulk_out_endpointAddress),
-                         urb->transfer_buffer,
-                         transfer_size,
-                         mos7840_bulk_out_data_callback, mos7840_port);
+       if ((serial->num_ports == 2)
+               && ((((__u16)port->number -
+                       (__u16)(port->serial->minor)) % 2) != 0)) {
+               usb_fill_bulk_urb(urb,
+                       serial->dev,
+                       usb_sndbulkpipe(serial->dev,
+                               (port->bulk_out_endpointAddress) + 2),
+                       urb->transfer_buffer,
+                       transfer_size,
+                       mos7840_bulk_out_data_callback, mos7840_port);
+       } else {
+               usb_fill_bulk_urb(urb,
+                       serial->dev,
+                       usb_sndbulkpipe(serial->dev,
+                               port->bulk_out_endpointAddress),
+                       urb->transfer_buffer,
+                       transfer_size,
+                       mos7840_bulk_out_data_callback, mos7840_port);
+       }
 
        data1 = urb->transfer_buffer;
        dbg("bulkout endpoint is %d", port->bulk_out_endpointAddress);
@@ -1838,7 +1862,7 @@ static int mos7840_send_cmd_write_baud_r
 
        } else {
 #ifdef HW_flow_control
-               / *setting h/w flow control bit to 0 */
+               /* setting h/w flow control bit to 0 */
                Data = 0xb;
                mos7840_port->shadowMCR = Data;
                status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
@@ -2305,19 +2329,26 @@ static int mos7840_ioctl(struct tty_stru
 
 static int mos7840_calc_num_ports(struct usb_serial *serial)
 {
-       int mos7840_num_ports = 0;
+       __u16 Data = 0x00;
+       int ret = 0;
+       int mos7840_num_ports;
 
-       dbg("numberofendpoints: cur %d, alt %d",
-           (int)serial->interface->cur_altsetting->desc.bNumEndpoints,
-           (int)serial->interface->altsetting->desc.bNumEndpoints);
-       if (serial->interface->cur_altsetting->desc.bNumEndpoints == 5) {
-               mos7840_num_ports = serial->num_ports = 2;
-       } else if (serial->interface->cur_altsetting->desc.bNumEndpoints == 9) {
+       ret = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+               MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &Data,
+               VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
+
+       if ((Data & 0x01) == 0) {
+               mos7840_num_ports = 2;
+               serial->num_bulk_in = 2;
+               serial->num_bulk_out = 2;
+               serial->num_ports = 2;
+       } else {
+               mos7840_num_ports = 4;
                serial->num_bulk_in = 4;
                serial->num_bulk_out = 4;
-               mos7840_num_ports = serial->num_ports = 4;
+               serial->num_ports = 4;
        }
-       dbg ("mos7840_num_ports = %d", mos7840_num_ports);
+
        return mos7840_num_ports;
 }
 


Patches currently in stable-queue which might be from [email protected] are

queue-3.3/usb-serial-mos7840-fixed-mcs7820-device-attach-problem.patch
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to