usb: serial: mos7840: Fixup mos7840_chars_in_buffer()
[pandora-kernel.git] / drivers / usb / serial / mos7840.c
index c72abd5..b150ed9 100644 (file)
 
 #define CLK_MULTI_REGISTER         ((__u16)(0x02))
 #define CLK_START_VALUE_REGISTER   ((__u16)(0x03))
+#define GPIO_REGISTER              ((__u16)(0x07))
 
 #define SERIAL_LCR_DLAB            ((__u16)(0x0080))
 
@@ -1103,14 +1104,25 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port)
        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);
@@ -1179,9 +1191,12 @@ static int mos7840_chars_in_buffer(struct tty_struct *tty)
        }
 
        spin_lock_irqsave(&mos7840_port->pool_lock, flags);
-       for (i = 0; i < NUM_URBS; ++i)
-               if (mos7840_port->busy[i])
-                       chars += URB_TRANSFER_BUFFER_SIZE;
+       for (i = 0; i < NUM_URBS; ++i) {
+               if (mos7840_port->busy[i]) {
+                       struct urb *urb = mos7840_port->write_urb_pool[i];
+                       chars += urb->transfer_buffer_length;
+               }
+       }
        spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
        dbg("%s - returns %d", __func__, chars);
        return chars;
@@ -1521,13 +1536,25 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port,
        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);
@@ -1840,7 +1867,7 @@ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port,
 
        } 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,
@@ -2309,19 +2336,26 @@ static int mos7840_ioctl(struct tty_struct *tty,
 
 static int mos7840_calc_num_ports(struct usb_serial *serial)
 {
-       int mos7840_num_ports = 0;
-
-       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) {
+       __u16 Data = 0x00;
+       int ret = 0;
+       int mos7840_num_ports;
+
+       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;
 }