aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial
diff options
context:
space:
mode:
authorDonald Lee <donald@asix.com.tw>2012-03-14 03:26:33 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-03-14 15:25:26 -0400
commit093ea2d3a766cb8a4c4de57efec6c0a127a58792 (patch)
treed97a4cbade1793fd5e32066b4f4b5f4b21591e7e /drivers/usb/serial
parent53c6bc24fdc8db87109a5760579cbb060fa644cf (diff)
USB: serial: mos7840: Fixed MCS7820 device attach problem
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 <donald@asix.com.tw> Cc: stable <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r--drivers/usb/serial/mos7840.c83
1 files changed, 57 insertions, 26 deletions
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index f7e6e30f53ee..c526550694a0 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -174,6 +174,7 @@
174 174
175#define CLK_MULTI_REGISTER ((__u16)(0x02)) 175#define CLK_MULTI_REGISTER ((__u16)(0x02))
176#define CLK_START_VALUE_REGISTER ((__u16)(0x03)) 176#define CLK_START_VALUE_REGISTER ((__u16)(0x03))
177#define GPIO_REGISTER ((__u16)(0x07))
177 178
178#define SERIAL_LCR_DLAB ((__u16)(0x0080)) 179#define SERIAL_LCR_DLAB ((__u16)(0x0080))
179 180
@@ -1101,14 +1102,25 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port)
1101 mos7840_port->read_urb = port->read_urb; 1102 mos7840_port->read_urb = port->read_urb;
1102 1103
1103 /* set up our bulk in urb */ 1104 /* set up our bulk in urb */
1104 1105 if ((serial->num_ports == 2)
1105 usb_fill_bulk_urb(mos7840_port->read_urb, 1106 && ((((__u16)port->number -
1106 serial->dev, 1107 (__u16)(port->serial->minor)) % 2) != 0)) {
1107 usb_rcvbulkpipe(serial->dev, 1108 usb_fill_bulk_urb(mos7840_port->read_urb,
1108 port->bulk_in_endpointAddress), 1109 serial->dev,
1109 port->bulk_in_buffer, 1110 usb_rcvbulkpipe(serial->dev,
1110 mos7840_port->read_urb->transfer_buffer_length, 1111 (port->bulk_in_endpointAddress) + 2),
1111 mos7840_bulk_in_callback, mos7840_port); 1112 port->bulk_in_buffer,
1113 mos7840_port->read_urb->transfer_buffer_length,
1114 mos7840_bulk_in_callback, mos7840_port);
1115 } else {
1116 usb_fill_bulk_urb(mos7840_port->read_urb,
1117 serial->dev,
1118 usb_rcvbulkpipe(serial->dev,
1119 port->bulk_in_endpointAddress),
1120 port->bulk_in_buffer,
1121 mos7840_port->read_urb->transfer_buffer_length,
1122 mos7840_bulk_in_callback, mos7840_port);
1123 }
1112 1124
1113 dbg("mos7840_open: bulkin endpoint is %d", 1125 dbg("mos7840_open: bulkin endpoint is %d",
1114 port->bulk_in_endpointAddress); 1126 port->bulk_in_endpointAddress);
@@ -1519,13 +1531,25 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port,
1519 memcpy(urb->transfer_buffer, current_position, transfer_size); 1531 memcpy(urb->transfer_buffer, current_position, transfer_size);
1520 1532
1521 /* fill urb with data and submit */ 1533 /* fill urb with data and submit */
1522 usb_fill_bulk_urb(urb, 1534 if ((serial->num_ports == 2)
1523 serial->dev, 1535 && ((((__u16)port->number -
1524 usb_sndbulkpipe(serial->dev, 1536 (__u16)(port->serial->minor)) % 2) != 0)) {
1525 port->bulk_out_endpointAddress), 1537 usb_fill_bulk_urb(urb,
1526 urb->transfer_buffer, 1538 serial->dev,
1527 transfer_size, 1539 usb_sndbulkpipe(serial->dev,
1528 mos7840_bulk_out_data_callback, mos7840_port); 1540 (port->bulk_out_endpointAddress) + 2),
1541 urb->transfer_buffer,
1542 transfer_size,
1543 mos7840_bulk_out_data_callback, mos7840_port);
1544 } else {
1545 usb_fill_bulk_urb(urb,
1546 serial->dev,
1547 usb_sndbulkpipe(serial->dev,
1548 port->bulk_out_endpointAddress),
1549 urb->transfer_buffer,
1550 transfer_size,
1551 mos7840_bulk_out_data_callback, mos7840_port);
1552 }
1529 1553
1530 data1 = urb->transfer_buffer; 1554 data1 = urb->transfer_buffer;
1531 dbg("bulkout endpoint is %d", port->bulk_out_endpointAddress); 1555 dbg("bulkout endpoint is %d", port->bulk_out_endpointAddress);
@@ -1838,7 +1862,7 @@ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port,
1838 1862
1839 } else { 1863 } else {
1840#ifdef HW_flow_control 1864#ifdef HW_flow_control
1841 / *setting h/w flow control bit to 0 */ 1865 /* setting h/w flow control bit to 0 */
1842 Data = 0xb; 1866 Data = 0xb;
1843 mos7840_port->shadowMCR = Data; 1867 mos7840_port->shadowMCR = Data;
1844 status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, 1868 status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
@@ -2305,19 +2329,26 @@ static int mos7840_ioctl(struct tty_struct *tty,
2305 2329
2306static int mos7840_calc_num_ports(struct usb_serial *serial) 2330static int mos7840_calc_num_ports(struct usb_serial *serial)
2307{ 2331{
2308 int mos7840_num_ports = 0; 2332 __u16 Data = 0x00;
2309 2333 int ret = 0;
2310 dbg("numberofendpoints: cur %d, alt %d", 2334 int mos7840_num_ports;
2311 (int)serial->interface->cur_altsetting->desc.bNumEndpoints, 2335
2312 (int)serial->interface->altsetting->desc.bNumEndpoints); 2336 ret = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
2313 if (serial->interface->cur_altsetting->desc.bNumEndpoints == 5) { 2337 MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &Data,
2314 mos7840_num_ports = serial->num_ports = 2; 2338 VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
2315 } else if (serial->interface->cur_altsetting->desc.bNumEndpoints == 9) { 2339
2340 if ((Data & 0x01) == 0) {
2341 mos7840_num_ports = 2;
2342 serial->num_bulk_in = 2;
2343 serial->num_bulk_out = 2;
2344 serial->num_ports = 2;
2345 } else {
2346 mos7840_num_ports = 4;
2316 serial->num_bulk_in = 4; 2347 serial->num_bulk_in = 4;
2317 serial->num_bulk_out = 4; 2348 serial->num_bulk_out = 4;
2318 mos7840_num_ports = serial->num_ports = 4; 2349 serial->num_ports = 4;
2319 } 2350 }
2320 dbg ("mos7840_num_ports = %d", mos7840_num_ports); 2351
2321 return mos7840_num_ports; 2352 return mos7840_num_ports;
2322} 2353}
2323 2354