linux/drivers/usb/serial/mos7840.c
<<
>>
Prefs
   1/*
   2 * This program is free software; you can redistribute it and/or modify
   3 * it under the terms of the GNU General Public License as published by
   4 * the Free Software Foundation; either version 2 of the License, or
   5 * (at your option) any later version.
   6 *
   7 * This program is distributed in the hope that it will be useful,
   8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
   9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10 * GNU General Public License for more details.
  11 *
  12 * You should have received a copy of the GNU General Public License
  13 * along with this program; if not, write to the Free Software
  14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  15 *
  16 * Clean ups from Moschip version and a few ioctl implementations by:
  17 *      Paul B Schroeder <pschroeder "at" uplogix "dot" com>
  18 *
  19 * Originally based on drivers/usb/serial/io_edgeport.c which is:
  20 *      Copyright (C) 2000 Inside Out Networks, All rights reserved.
  21 *      Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com>
  22 *
  23 */
  24
  25#include <linux/kernel.h>
  26#include <linux/errno.h>
  27#include <linux/init.h>
  28#include <linux/slab.h>
  29#include <linux/tty.h>
  30#include <linux/tty_driver.h>
  31#include <linux/tty_flip.h>
  32#include <linux/module.h>
  33#include <linux/serial.h>
  34#include <linux/usb.h>
  35#include <linux/usb/serial.h>
  36#include <linux/uaccess.h>
  37
  38/*
  39 * Version Information
  40 */
  41#define DRIVER_VERSION "1.3.2"
  42#define DRIVER_DESC "Moschip 7840/7820 USB Serial Driver"
  43
  44/*
  45 * 16C50 UART register defines
  46 */
  47
  48#define LCR_BITS_5             0x00     /* 5 bits/char */
  49#define LCR_BITS_6             0x01     /* 6 bits/char */
  50#define LCR_BITS_7             0x02     /* 7 bits/char */
  51#define LCR_BITS_8             0x03     /* 8 bits/char */
  52#define LCR_BITS_MASK          0x03     /* Mask for bits/char field */
  53
  54#define LCR_STOP_1             0x00     /* 1 stop bit */
  55#define LCR_STOP_1_5           0x04     /* 1.5 stop bits (if 5   bits/char) */
  56#define LCR_STOP_2             0x04     /* 2 stop bits   (if 6-8 bits/char) */
  57#define LCR_STOP_MASK          0x04     /* Mask for stop bits field */
  58
  59#define LCR_PAR_NONE           0x00     /* No parity */
  60#define LCR_PAR_ODD            0x08     /* Odd parity */
  61#define LCR_PAR_EVEN           0x18     /* Even parity */
  62#define LCR_PAR_MARK           0x28     /* Force parity bit to 1 */
  63#define LCR_PAR_SPACE          0x38     /* Force parity bit to 0 */
  64#define LCR_PAR_MASK           0x38     /* Mask for parity field */
  65
  66#define LCR_SET_BREAK          0x40     /* Set Break condition */
  67#define LCR_DL_ENABLE          0x80     /* Enable access to divisor latch */
  68
  69#define MCR_DTR                0x01     /* Assert DTR */
  70#define MCR_RTS                0x02     /* Assert RTS */
  71#define MCR_OUT1               0x04     /* Loopback only: Sets state of RI */
  72#define MCR_MASTER_IE          0x08     /* Enable interrupt outputs */
  73#define MCR_LOOPBACK           0x10     /* Set internal (digital) loopback mode */
  74#define MCR_XON_ANY            0x20     /* Enable any char to exit XOFF mode */
  75
  76#define MOS7840_MSR_CTS        0x10     /* Current state of CTS */
  77#define MOS7840_MSR_DSR        0x20     /* Current state of DSR */
  78#define MOS7840_MSR_RI         0x40     /* Current state of RI */
  79#define MOS7840_MSR_CD         0x80     /* Current state of CD */
  80
  81/*
  82 * Defines used for sending commands to port
  83 */
  84
  85#define WAIT_FOR_EVER   (HZ * 0)        /* timeout urb is wait for ever */
  86#define MOS_WDR_TIMEOUT (HZ * 5)        /* default urb timeout */
  87
  88#define MOS_PORT1       0x0200
  89#define MOS_PORT2       0x0300
  90#define MOS_VENREG      0x0000
  91#define MOS_MAX_PORT    0x02
  92#define MOS_WRITE       0x0E
  93#define MOS_READ        0x0D
  94
  95/* Requests */
  96#define MCS_RD_RTYPE    0xC0
  97#define MCS_WR_RTYPE    0x40
  98#define MCS_RDREQ       0x0D
  99#define MCS_WRREQ       0x0E
 100#define MCS_CTRL_TIMEOUT        500
 101#define VENDOR_READ_LENGTH      (0x01)
 102
 103#define MAX_NAME_LEN    64
 104
 105#define ZLP_REG1  0x3A          /* Zero_Flag_Reg1    58 */
 106#define ZLP_REG5  0x3E          /* Zero_Flag_Reg5    62 */
 107
 108/* For higher baud Rates use TIOCEXBAUD */
 109#define TIOCEXBAUD     0x5462
 110
 111/* vendor id and device id defines */
 112
 113/* The native mos7840/7820 component */
 114#define USB_VENDOR_ID_MOSCHIP           0x9710
 115#define MOSCHIP_DEVICE_ID_7840          0x7840
 116#define MOSCHIP_DEVICE_ID_7820          0x7820
 117/* The native component can have its vendor/device id's overridden
 118 * in vendor-specific implementations.  Such devices can be handled
 119 * by making a change here, in moschip_port_id_table, and in
 120 * moschip_id_table_combined
 121 */
 122#define USB_VENDOR_ID_BANDB              0x0856
 123#define BANDB_DEVICE_ID_USO9ML2_2        0xAC22
 124#define BANDB_DEVICE_ID_USO9ML2_2P       0xBC00
 125#define BANDB_DEVICE_ID_USO9ML2_4        0xAC24
 126#define BANDB_DEVICE_ID_USO9ML2_4P       0xBC01
 127#define BANDB_DEVICE_ID_US9ML2_2         0xAC29
 128#define BANDB_DEVICE_ID_US9ML2_4         0xAC30
 129#define BANDB_DEVICE_ID_USPTL4_2         0xAC31
 130#define BANDB_DEVICE_ID_USPTL4_4         0xAC32
 131#define BANDB_DEVICE_ID_USOPTL4_2        0xAC42
 132#define BANDB_DEVICE_ID_USOPTL4_2P       0xBC02
 133#define BANDB_DEVICE_ID_USOPTL4_4        0xAC44
 134#define BANDB_DEVICE_ID_USOPTL4_4P       0xBC03
 135#define BANDB_DEVICE_ID_USOPTL2_4        0xAC24
 136
 137/* This driver also supports
 138 * ATEN UC2324 device using Moschip MCS7840
 139 * ATEN UC2322 device using Moschip MCS7820
 140 */
 141#define USB_VENDOR_ID_ATENINTL          0x0557
 142#define ATENINTL_DEVICE_ID_UC2324       0x2011
 143#define ATENINTL_DEVICE_ID_UC2322       0x7820
 144
 145/* Interrupt Routine Defines    */
 146
 147#define SERIAL_IIR_RLS      0x06
 148#define SERIAL_IIR_MS       0x00
 149
 150/*
 151 *  Emulation of the bit mask on the LINE STATUS REGISTER.
 152 */
 153#define SERIAL_LSR_DR       0x0001
 154#define SERIAL_LSR_OE       0x0002
 155#define SERIAL_LSR_PE       0x0004
 156#define SERIAL_LSR_FE       0x0008
 157#define SERIAL_LSR_BI       0x0010
 158
 159#define MOS_MSR_DELTA_CTS   0x10
 160#define MOS_MSR_DELTA_DSR   0x20
 161#define MOS_MSR_DELTA_RI    0x40
 162#define MOS_MSR_DELTA_CD    0x80
 163
 164/* Serial Port register Address */
 165#define INTERRUPT_ENABLE_REGISTER  ((__u16)(0x01))
 166#define FIFO_CONTROL_REGISTER      ((__u16)(0x02))
 167#define LINE_CONTROL_REGISTER      ((__u16)(0x03))
 168#define MODEM_CONTROL_REGISTER     ((__u16)(0x04))
 169#define LINE_STATUS_REGISTER       ((__u16)(0x05))
 170#define MODEM_STATUS_REGISTER      ((__u16)(0x06))
 171#define SCRATCH_PAD_REGISTER       ((__u16)(0x07))
 172#define DIVISOR_LATCH_LSB          ((__u16)(0x00))
 173#define DIVISOR_LATCH_MSB          ((__u16)(0x01))
 174
 175#define CLK_MULTI_REGISTER         ((__u16)(0x02))
 176#define CLK_START_VALUE_REGISTER   ((__u16)(0x03))
 177
 178#define SERIAL_LCR_DLAB            ((__u16)(0x0080))
 179
 180/*
 181 * URB POOL related defines
 182 */
 183#define NUM_URBS                        16      /* URB Count */
 184#define URB_TRANSFER_BUFFER_SIZE        32      /* URB Size  */
 185
 186
 187static const struct usb_device_id moschip_port_id_table[] = {
 188        {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
 189        {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
 190        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)},
 191        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)},
 192        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)},
 193        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4P)},
 194        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)},
 195        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)},
 196        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)},
 197        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)},
 198        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
 199        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2P)},
 200        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
 201        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4P)},
 202        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)},
 203        {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)},
 204        {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)},
 205        {}                      /* terminating entry */
 206};
 207
 208static const struct usb_device_id moschip_id_table_combined[] __devinitconst = {
 209        {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
 210        {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
 211        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)},
 212        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)},
 213        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)},
 214        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4P)},
 215        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)},
 216        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)},
 217        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)},
 218        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)},
 219        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
 220        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2P)},
 221        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
 222        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4P)},
 223        {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)},
 224        {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)},
 225        {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)},
 226        {}                      /* terminating entry */
 227};
 228
 229MODULE_DEVICE_TABLE(usb, moschip_id_table_combined);
 230
 231/* This structure holds all of the local port information */
 232
 233struct moschip_port {
 234        int port_num;           /*Actual port number in the device(1,2,etc) */
 235        struct urb *write_urb;  /* write URB for this port */
 236        struct urb *read_urb;   /* read URB for this port */
 237        struct urb *int_urb;
 238        __u8 shadowLCR;         /* last LCR value received */
 239        __u8 shadowMCR;         /* last MCR value received */
 240        char open;
 241        char open_ports;
 242        char zombie;
 243        wait_queue_head_t wait_chase;   /* for handling sleeping while waiting for chase to finish */
 244        wait_queue_head_t delta_msr_wait;       /* for handling sleeping while waiting for msr change to happen */
 245        int delta_msr_cond;
 246        struct async_icount icount;
 247        struct usb_serial_port *port;   /* loop back to the owner of this object */
 248
 249        /* Offsets */
 250        __u8 SpRegOffset;
 251        __u8 ControlRegOffset;
 252        __u8 DcrRegOffset;
 253        /* for processing control URBS in interrupt context */
 254        struct urb *control_urb;
 255        struct usb_ctrlrequest *dr;
 256        char *ctrl_buf;
 257        int MsrLsr;
 258
 259        spinlock_t pool_lock;
 260        struct urb *write_urb_pool[NUM_URBS];
 261        char busy[NUM_URBS];
 262        bool read_urb_busy;
 263};
 264
 265
 266static int debug;
 267
 268/*
 269 * mos7840_set_reg_sync
 270 *      To set the Control register by calling usb_fill_control_urb function
 271 *      by passing usb_sndctrlpipe function as parameter.
 272 */
 273
 274static int mos7840_set_reg_sync(struct usb_serial_port *port, __u16 reg,
 275                                __u16 val)
 276{
 277        struct usb_device *dev = port->serial->dev;
 278        val = val & 0x00ff;
 279        dbg("mos7840_set_reg_sync offset is %x, value %x", reg, val);
 280
 281        return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), MCS_WRREQ,
 282                               MCS_WR_RTYPE, val, reg, NULL, 0,
 283                               MOS_WDR_TIMEOUT);
 284}
 285
 286/*
 287 * mos7840_get_reg_sync
 288 *      To set the Uart register by calling usb_fill_control_urb function by
 289 *      passing usb_rcvctrlpipe function as parameter.
 290 */
 291
 292static int mos7840_get_reg_sync(struct usb_serial_port *port, __u16 reg,
 293                                __u16 *val)
 294{
 295        struct usb_device *dev = port->serial->dev;
 296        int ret = 0;
 297        u8 *buf;
 298
 299        buf = kmalloc(VENDOR_READ_LENGTH, GFP_KERNEL);
 300        if (!buf)
 301                return -ENOMEM;
 302
 303        ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ,
 304                              MCS_RD_RTYPE, 0, reg, buf, VENDOR_READ_LENGTH,
 305                              MOS_WDR_TIMEOUT);
 306        *val = buf[0];
 307        dbg("mos7840_get_reg_sync offset is %x, return val %x", reg, *val);
 308
 309        kfree(buf);
 310        return ret;
 311}
 312
 313/*
 314 * mos7840_set_uart_reg
 315 *      To set the Uart register by calling usb_fill_control_urb function by
 316 *      passing usb_sndctrlpipe function as parameter.
 317 */
 318
 319static int mos7840_set_uart_reg(struct usb_serial_port *port, __u16 reg,
 320                                __u16 val)
 321{
 322
 323        struct usb_device *dev = port->serial->dev;
 324        val = val & 0x00ff;
 325        /* For the UART control registers, the application number need
 326           to be Or'ed */
 327        if (port->serial->num_ports == 4) {
 328                val |= (((__u16) port->number -
 329                                (__u16) (port->serial->minor)) + 1) << 8;
 330                dbg("mos7840_set_uart_reg application number is %x", val);
 331        } else {
 332                if (((__u16) port->number - (__u16) (port->serial->minor)) == 0) {
 333                        val |= (((__u16) port->number -
 334                              (__u16) (port->serial->minor)) + 1) << 8;
 335                        dbg("mos7840_set_uart_reg application number is %x",
 336                            val);
 337                } else {
 338                        val |=
 339                            (((__u16) port->number -
 340                              (__u16) (port->serial->minor)) + 2) << 8;
 341                        dbg("mos7840_set_uart_reg application number is %x",
 342                            val);
 343                }
 344        }
 345        return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), MCS_WRREQ,
 346                               MCS_WR_RTYPE, val, reg, NULL, 0,
 347                               MOS_WDR_TIMEOUT);
 348
 349}
 350
 351/*
 352 * mos7840_get_uart_reg
 353 *      To set the Control register by calling usb_fill_control_urb function
 354 *      by passing usb_rcvctrlpipe function as parameter.
 355 */
 356static int mos7840_get_uart_reg(struct usb_serial_port *port, __u16 reg,
 357                                __u16 *val)
 358{
 359        struct usb_device *dev = port->serial->dev;
 360        int ret = 0;
 361        __u16 Wval;
 362        u8 *buf;
 363
 364        buf = kmalloc(VENDOR_READ_LENGTH, GFP_KERNEL);
 365        if (!buf)
 366                return -ENOMEM;
 367
 368        /* dbg("application number is %4x",
 369            (((__u16)port->number - (__u16)(port->serial->minor))+1)<<8); */
 370        /* Wval  is same as application number */
 371        if (port->serial->num_ports == 4) {
 372                Wval =
 373                    (((__u16) port->number - (__u16) (port->serial->minor)) +
 374                     1) << 8;
 375                dbg("mos7840_get_uart_reg application number is %x", Wval);
 376        } else {
 377                if (((__u16) port->number - (__u16) (port->serial->minor)) == 0) {
 378                        Wval = (((__u16) port->number -
 379                              (__u16) (port->serial->minor)) + 1) << 8;
 380                        dbg("mos7840_get_uart_reg application number is %x",
 381                            Wval);
 382                } else {
 383                        Wval = (((__u16) port->number -
 384                              (__u16) (port->serial->minor)) + 2) << 8;
 385                        dbg("mos7840_get_uart_reg application number is %x",
 386                            Wval);
 387                }
 388        }
 389        ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ,
 390                              MCS_RD_RTYPE, Wval, reg, buf, VENDOR_READ_LENGTH,
 391                              MOS_WDR_TIMEOUT);
 392        *val = buf[0];
 393
 394        kfree(buf);
 395        return ret;
 396}
 397
 398static void mos7840_dump_serial_port(struct moschip_port *mos7840_port)
 399{
 400
 401        dbg("***************************************");
 402        dbg("SpRegOffset is %2x", mos7840_port->SpRegOffset);
 403        dbg("ControlRegOffset is %2x", mos7840_port->ControlRegOffset);
 404        dbg("DCRRegOffset is %2x", mos7840_port->DcrRegOffset);
 405        dbg("***************************************");
 406
 407}
 408
 409/************************************************************************/
 410/************************************************************************/
 411/*             I N T E R F A C E   F U N C T I O N S                    */
 412/*             I N T E R F A C E   F U N C T I O N S                    */
 413/************************************************************************/
 414/************************************************************************/
 415
 416static inline void mos7840_set_port_private(struct usb_serial_port *port,
 417                                            struct moschip_port *data)
 418{
 419        usb_set_serial_port_data(port, (void *)data);
 420}
 421
 422static inline struct moschip_port *mos7840_get_port_private(struct
 423                                                            usb_serial_port
 424                                                            *port)
 425{
 426        return (struct moschip_port *)usb_get_serial_port_data(port);
 427}
 428
 429static void mos7840_handle_new_msr(struct moschip_port *port, __u8 new_msr)
 430{
 431        struct moschip_port *mos7840_port;
 432        struct async_icount *icount;
 433        mos7840_port = port;
 434        icount = &mos7840_port->icount;
 435        if (new_msr &
 436            (MOS_MSR_DELTA_CTS | MOS_MSR_DELTA_DSR | MOS_MSR_DELTA_RI |
 437             MOS_MSR_DELTA_CD)) {
 438                icount = &mos7840_port->icount;
 439
 440                /* update input line counters */
 441                if (new_msr & MOS_MSR_DELTA_CTS) {
 442                        icount->cts++;
 443                        smp_wmb();
 444                }
 445                if (new_msr & MOS_MSR_DELTA_DSR) {
 446                        icount->dsr++;
 447                        smp_wmb();
 448                }
 449                if (new_msr & MOS_MSR_DELTA_CD) {
 450                        icount->dcd++;
 451                        smp_wmb();
 452                }
 453                if (new_msr & MOS_MSR_DELTA_RI) {
 454                        icount->rng++;
 455                        smp_wmb();
 456                }
 457        }
 458}
 459
 460static void mos7840_handle_new_lsr(struct moschip_port *port, __u8 new_lsr)
 461{
 462        struct async_icount *icount;
 463
 464        dbg("%s - %02x", __func__, new_lsr);
 465
 466        if (new_lsr & SERIAL_LSR_BI) {
 467                /*
 468                 * Parity and Framing errors only count if they
 469                 * occur exclusive of a break being
 470                 * received.
 471                 */
 472                new_lsr &= (__u8) (SERIAL_LSR_OE | SERIAL_LSR_BI);
 473        }
 474
 475        /* update input line counters */
 476        icount = &port->icount;
 477        if (new_lsr & SERIAL_LSR_BI) {
 478                icount->brk++;
 479                smp_wmb();
 480        }
 481        if (new_lsr & SERIAL_LSR_OE) {
 482                icount->overrun++;
 483                smp_wmb();
 484        }
 485        if (new_lsr & SERIAL_LSR_PE) {
 486                icount->parity++;
 487                smp_wmb();
 488        }
 489        if (new_lsr & SERIAL_LSR_FE) {
 490                icount->frame++;
 491                smp_wmb();
 492        }
 493}
 494
 495/************************************************************************/
 496/************************************************************************/
 497/*            U S B  C A L L B A C K   F U N C T I O N S                */
 498/*            U S B  C A L L B A C K   F U N C T I O N S                */
 499/************************************************************************/
 500/************************************************************************/
 501
 502static void mos7840_control_callback(struct urb *urb)
 503{
 504        unsigned char *data;
 505        struct moschip_port *mos7840_port;
 506        __u8 regval = 0x0;
 507        int result = 0;
 508        int status = urb->status;
 509
 510        mos7840_port = urb->context;
 511
 512        switch (status) {
 513        case 0:
 514                /* success */
 515                break;
 516        case -ECONNRESET:
 517        case -ENOENT:
 518        case -ESHUTDOWN:
 519                /* this urb is terminated, clean up */
 520                dbg("%s - urb shutting down with status: %d", __func__,
 521                    status);
 522                return;
 523        default:
 524                dbg("%s - nonzero urb status received: %d", __func__,
 525                    status);
 526                goto exit;
 527        }
 528
 529        dbg("%s urb buffer size is %d", __func__, urb->actual_length);
 530        dbg("%s mos7840_port->MsrLsr is %d port %d", __func__,
 531            mos7840_port->MsrLsr, mos7840_port->port_num);
 532        data = urb->transfer_buffer;
 533        regval = (__u8) data[0];
 534        dbg("%s data is %x", __func__, regval);
 535        if (mos7840_port->MsrLsr == 0)
 536                mos7840_handle_new_msr(mos7840_port, regval);
 537        else if (mos7840_port->MsrLsr == 1)
 538                mos7840_handle_new_lsr(mos7840_port, regval);
 539
 540exit:
 541        spin_lock(&mos7840_port->pool_lock);
 542        if (!mos7840_port->zombie)
 543                result = usb_submit_urb(mos7840_port->int_urb, GFP_ATOMIC);
 544        spin_unlock(&mos7840_port->pool_lock);
 545        if (result) {
 546                dev_err(&urb->dev->dev,
 547                        "%s - Error %d submitting interrupt urb\n",
 548                        __func__, result);
 549        }
 550}
 551
 552static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg,
 553                           __u16 *val)
 554{
 555        struct usb_device *dev = mcs->port->serial->dev;
 556        struct usb_ctrlrequest *dr = mcs->dr;
 557        unsigned char *buffer = mcs->ctrl_buf;
 558        int ret;
 559
 560        dr->bRequestType = MCS_RD_RTYPE;
 561        dr->bRequest = MCS_RDREQ;
 562        dr->wValue = cpu_to_le16(Wval); /* 0 */
 563        dr->wIndex = cpu_to_le16(reg);
 564        dr->wLength = cpu_to_le16(2);
 565
 566        usb_fill_control_urb(mcs->control_urb, dev, usb_rcvctrlpipe(dev, 0),
 567                             (unsigned char *)dr, buffer, 2,
 568                             mos7840_control_callback, mcs);
 569        mcs->control_urb->transfer_buffer_length = 2;
 570        ret = usb_submit_urb(mcs->control_urb, GFP_ATOMIC);
 571        return ret;
 572}
 573
 574/*****************************************************************************
 575 * mos7840_interrupt_callback
 576 *      this is the callback function for when we have received data on the
 577 *      interrupt endpoint.
 578 *****************************************************************************/
 579
 580static void mos7840_interrupt_callback(struct urb *urb)
 581{
 582        int result;
 583        int length;
 584        struct moschip_port *mos7840_port;
 585        struct usb_serial *serial;
 586        __u16 Data;
 587        unsigned char *data;
 588        __u8 sp[5], st;
 589        int i, rv = 0;
 590        __u16 wval, wreg = 0;
 591        int status = urb->status;
 592
 593        dbg("%s", " : Entering");
 594
 595        switch (status) {
 596        case 0:
 597                /* success */
 598                break;
 599        case -ECONNRESET:
 600        case -ENOENT:
 601        case -ESHUTDOWN:
 602                /* this urb is terminated, clean up */
 603                dbg("%s - urb shutting down with status: %d", __func__,
 604                    status);
 605                return;
 606        default:
 607                dbg("%s - nonzero urb status received: %d", __func__,
 608                    status);
 609                goto exit;
 610        }
 611
 612        length = urb->actual_length;
 613        data = urb->transfer_buffer;
 614
 615        serial = urb->context;
 616
 617        /* Moschip get 5 bytes
 618         * Byte 1 IIR Port 1 (port.number is 0)
 619         * Byte 2 IIR Port 2 (port.number is 1)
 620         * Byte 3 IIR Port 3 (port.number is 2)
 621         * Byte 4 IIR Port 4 (port.number is 3)
 622         * Byte 5 FIFO status for both */
 623
 624        if (length && length > 5) {
 625                dbg("%s", "Wrong data !!!");
 626                return;
 627        }
 628
 629        sp[0] = (__u8) data[0];
 630        sp[1] = (__u8) data[1];
 631        sp[2] = (__u8) data[2];
 632        sp[3] = (__u8) data[3];
 633        st = (__u8) data[4];
 634
 635        for (i = 0; i < serial->num_ports; i++) {
 636                mos7840_port = mos7840_get_port_private(serial->port[i]);
 637                wval =
 638                    (((__u16) serial->port[i]->number -
 639                      (__u16) (serial->minor)) + 1) << 8;
 640                if (mos7840_port->open) {
 641                        if (sp[i] & 0x01) {
 642                                dbg("SP%d No Interrupt !!!", i);
 643                        } else {
 644                                switch (sp[i] & 0x0f) {
 645                                case SERIAL_IIR_RLS:
 646                                        dbg("Serial Port %d: Receiver status error or ", i);
 647                                        dbg("address bit detected in 9-bit mode");
 648                                        mos7840_port->MsrLsr = 1;
 649                                        wreg = LINE_STATUS_REGISTER;
 650                                        break;
 651                                case SERIAL_IIR_MS:
 652                                        dbg("Serial Port %d: Modem status change", i);
 653                                        mos7840_port->MsrLsr = 0;
 654                                        wreg = MODEM_STATUS_REGISTER;
 655                                        break;
 656                                }
 657                                spin_lock(&mos7840_port->pool_lock);
 658                                if (!mos7840_port->zombie) {
 659                                        rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data);
 660                                } else {
 661                                        spin_unlock(&mos7840_port->pool_lock);
 662                                        return;
 663                                }
 664                                spin_unlock(&mos7840_port->pool_lock);
 665                        }
 666                }
 667        }
 668        if (!(rv < 0))
 669                /* the completion handler for the control urb will resubmit */
 670                return;
 671exit:
 672        result = usb_submit_urb(urb, GFP_ATOMIC);
 673        if (result) {
 674                dev_err(&urb->dev->dev,
 675                        "%s - Error %d submitting interrupt urb\n",
 676                        __func__, result);
 677        }
 678}
 679
 680static int mos7840_port_paranoia_check(struct usb_serial_port *port,
 681                                       const char *function)
 682{
 683        if (!port) {
 684                dbg("%s - port == NULL", function);
 685                return -1;
 686        }
 687        if (!port->serial) {
 688                dbg("%s - port->serial == NULL", function);
 689                return -1;
 690        }
 691
 692        return 0;
 693}
 694
 695/* Inline functions to check the sanity of a pointer that is passed to us */
 696static int mos7840_serial_paranoia_check(struct usb_serial *serial,
 697                                         const char *function)
 698{
 699        if (!serial) {
 700                dbg("%s - serial == NULL", function);
 701                return -1;
 702        }
 703        if (!serial->type) {
 704                dbg("%s - serial->type == NULL!", function);
 705                return -1;
 706        }
 707
 708        return 0;
 709}
 710
 711static struct usb_serial *mos7840_get_usb_serial(struct usb_serial_port *port,
 712                                                 const char *function)
 713{
 714        /* if no port was specified, or it fails a paranoia check */
 715        if (!port ||
 716            mos7840_port_paranoia_check(port, function) ||
 717            mos7840_serial_paranoia_check(port->serial, function)) {
 718                /* then say that we don't have a valid usb_serial thing,
 719                 * which will end up genrating -ENODEV return values */
 720                return NULL;
 721        }
 722
 723        return port->serial;
 724}
 725
 726/*****************************************************************************
 727 * mos7840_bulk_in_callback
 728 *      this is the callback function for when we have received data on the
 729 *      bulk in endpoint.
 730 *****************************************************************************/
 731
 732static void mos7840_bulk_in_callback(struct urb *urb)
 733{
 734        int retval;
 735        unsigned char *data;
 736        struct usb_serial *serial;
 737        struct usb_serial_port *port;
 738        struct moschip_port *mos7840_port;
 739        struct tty_struct *tty;
 740        int status = urb->status;
 741
 742        mos7840_port = urb->context;
 743        if (!mos7840_port) {
 744                dbg("%s", "NULL mos7840_port pointer");
 745                return;
 746        }
 747
 748        if (status) {
 749                dbg("nonzero read bulk status received: %d", status);
 750                mos7840_port->read_urb_busy = false;
 751                return;
 752        }
 753
 754        port = (struct usb_serial_port *)mos7840_port->port;
 755        if (mos7840_port_paranoia_check(port, __func__)) {
 756                dbg("%s", "Port Paranoia failed");
 757                mos7840_port->read_urb_busy = false;
 758                return;
 759        }
 760
 761        serial = mos7840_get_usb_serial(port, __func__);
 762        if (!serial) {
 763                dbg("%s", "Bad serial pointer");
 764                mos7840_port->read_urb_busy = false;
 765                return;
 766        }
 767
 768        dbg("%s", "Entering... ");
 769
 770        data = urb->transfer_buffer;
 771
 772        dbg("%s", "Entering ...........");
 773
 774        if (urb->actual_length) {
 775                tty = tty_port_tty_get(&mos7840_port->port->port);
 776                if (tty) {
 777                        tty_insert_flip_string(tty, data, urb->actual_length);
 778                        dbg(" %s ", data);
 779                        tty_flip_buffer_push(tty);
 780                        tty_kref_put(tty);
 781                }
 782                mos7840_port->icount.rx += urb->actual_length;
 783                smp_wmb();
 784                dbg("mos7840_port->icount.rx is %d:",
 785                    mos7840_port->icount.rx);
 786        }
 787
 788        if (!mos7840_port->read_urb) {
 789                dbg("%s", "URB KILLED !!!");
 790                mos7840_port->read_urb_busy = false;
 791                return;
 792        }
 793
 794
 795        mos7840_port->read_urb->dev = serial->dev;
 796
 797        mos7840_port->read_urb_busy = true;
 798        retval = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC);
 799
 800        if (retval) {
 801                dbg("usb_submit_urb(read bulk) failed, retval = %d", retval);
 802                mos7840_port->read_urb_busy = false;
 803        }
 804}
 805
 806/*****************************************************************************
 807 * mos7840_bulk_out_data_callback
 808 *      this is the callback function for when we have finished sending
 809 *      serial data on the bulk out endpoint.
 810 *****************************************************************************/
 811
 812static void mos7840_bulk_out_data_callback(struct urb *urb)
 813{
 814        struct moschip_port *mos7840_port;
 815        struct tty_struct *tty;
 816        int status = urb->status;
 817        int i;
 818
 819        mos7840_port = urb->context;
 820        spin_lock(&mos7840_port->pool_lock);
 821        for (i = 0; i < NUM_URBS; i++) {
 822                if (urb == mos7840_port->write_urb_pool[i]) {
 823                        mos7840_port->busy[i] = 0;
 824                        break;
 825                }
 826        }
 827        spin_unlock(&mos7840_port->pool_lock);
 828
 829        if (status) {
 830                dbg("nonzero write bulk status received:%d", status);
 831                return;
 832        }
 833
 834        if (mos7840_port_paranoia_check(mos7840_port->port, __func__)) {
 835                dbg("%s", "Port Paranoia failed");
 836                return;
 837        }
 838
 839        dbg("%s", "Entering .........");
 840
 841        tty = tty_port_tty_get(&mos7840_port->port->port);
 842        if (tty && mos7840_port->open)
 843                tty_wakeup(tty);
 844        tty_kref_put(tty);
 845
 846}
 847
 848/************************************************************************/
 849/*       D R I V E R  T T Y  I N T E R F A C E  F U N C T I O N S       */
 850/************************************************************************/
 851#ifdef MCSSerialProbe
 852static int mos7840_serial_probe(struct usb_serial *serial,
 853                                const struct usb_device_id *id)
 854{
 855
 856        /*need to implement the mode_reg reading and updating\
 857           structures usb_serial_ device_type\
 858           (i.e num_ports, num_bulkin,bulkout etc) */
 859        /* Also we can update the changes  attach */
 860        return 1;
 861}
 862#endif
 863
 864/*****************************************************************************
 865 * mos7840_open
 866 *      this function is called by the tty driver when a port is opened
 867 *      If successful, we return 0
 868 *      Otherwise we return a negative error number.
 869 *****************************************************************************/
 870
 871static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port)
 872{
 873        int response;
 874        int j;
 875        struct usb_serial *serial;
 876        struct urb *urb;
 877        __u16 Data;
 878        int status;
 879        struct moschip_port *mos7840_port;
 880        struct moschip_port *port0;
 881
 882        dbg ("%s enter", __func__);
 883
 884        if (mos7840_port_paranoia_check(port, __func__)) {
 885                dbg("%s", "Port Paranoia failed");
 886                return -ENODEV;
 887        }
 888
 889        serial = port->serial;
 890
 891        if (mos7840_serial_paranoia_check(serial, __func__)) {
 892                dbg("%s", "Serial Paranoia failed");
 893                return -ENODEV;
 894        }
 895
 896        mos7840_port = mos7840_get_port_private(port);
 897        port0 = mos7840_get_port_private(serial->port[0]);
 898
 899        if (mos7840_port == NULL || port0 == NULL)
 900                return -ENODEV;
 901
 902        usb_clear_halt(serial->dev, port->write_urb->pipe);
 903        usb_clear_halt(serial->dev, port->read_urb->pipe);
 904        port0->open_ports++;
 905
 906        /* Initialising the write urb pool */
 907        for (j = 0; j < NUM_URBS; ++j) {
 908                urb = usb_alloc_urb(0, GFP_KERNEL);
 909                mos7840_port->write_urb_pool[j] = urb;
 910
 911                if (urb == NULL) {
 912                        dev_err(&port->dev, "No more urbs???\n");
 913                        continue;
 914                }
 915
 916                urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE,
 917                                                                GFP_KERNEL);
 918                if (!urb->transfer_buffer) {
 919                        usb_free_urb(urb);
 920                        mos7840_port->write_urb_pool[j] = NULL;
 921                        dev_err(&port->dev,
 922                                "%s-out of memory for urb buffers.\n",
 923                                __func__);
 924                        continue;
 925                }
 926        }
 927
 928/*****************************************************************************
 929 * Initialize MCS7840 -- Write Init values to corresponding Registers
 930 *
 931 * Register Index
 932 * 1 : IER
 933 * 2 : FCR
 934 * 3 : LCR
 935 * 4 : MCR
 936 *
 937 * 0x08 : SP1/2 Control Reg
 938 *****************************************************************************/
 939
 940        /* NEED to check the following Block */
 941
 942        Data = 0x0;
 943        status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset, &Data);
 944        if (status < 0) {
 945                dbg("Reading Spreg failed");
 946                return -1;
 947        }
 948        Data |= 0x80;
 949        status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);
 950        if (status < 0) {
 951                dbg("writing Spreg failed");
 952                return -1;
 953        }
 954
 955        Data &= ~0x80;
 956        status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);
 957        if (status < 0) {
 958                dbg("writing Spreg failed");
 959                return -1;
 960        }
 961        /* End of block to be checked */
 962
 963        Data = 0x0;
 964        status = mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset,
 965                                                                        &Data);
 966        if (status < 0) {
 967                dbg("Reading Controlreg failed");
 968                return -1;
 969        }
 970        Data |= 0x08;           /* Driver done bit */
 971        Data |= 0x20;           /* rx_disable */
 972        status = mos7840_set_reg_sync(port,
 973                                mos7840_port->ControlRegOffset, Data);
 974        if (status < 0) {
 975                dbg("writing Controlreg failed");
 976                return -1;
 977        }
 978        /* do register settings here */
 979        /* Set all regs to the device default values. */
 980        /***********************************
 981         * First Disable all interrupts.
 982         ***********************************/
 983        Data = 0x00;
 984        status = mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
 985        if (status < 0) {
 986                dbg("disabling interrupts failed");
 987                return -1;
 988        }
 989        /* Set FIFO_CONTROL_REGISTER to the default value */
 990        Data = 0x00;
 991        status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
 992        if (status < 0) {
 993                dbg("Writing FIFO_CONTROL_REGISTER  failed");
 994                return -1;
 995        }
 996
 997        Data = 0xcf;
 998        status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
 999        if (status < 0) {
1000                dbg("Writing FIFO_CONTROL_REGISTER  failed");
1001                return -1;
1002        }
1003
1004        Data = 0x03;
1005        status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
1006        mos7840_port->shadowLCR = Data;
1007
1008        Data = 0x0b;
1009        status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
1010        mos7840_port->shadowMCR = Data;
1011
1012        Data = 0x00;
1013        status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data);
1014        mos7840_port->shadowLCR = Data;
1015
1016        Data |= SERIAL_LCR_DLAB;        /* data latch enable in LCR 0x80 */
1017        status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
1018
1019        Data = 0x0c;
1020        status = mos7840_set_uart_reg(port, DIVISOR_LATCH_LSB, Data);
1021
1022        Data = 0x0;
1023        status = mos7840_set_uart_reg(port, DIVISOR_LATCH_MSB, Data);
1024
1025        Data = 0x00;
1026        status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data);
1027
1028        Data = Data & ~SERIAL_LCR_DLAB;
1029        status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
1030        mos7840_port->shadowLCR = Data;
1031
1032        /* clearing Bulkin and Bulkout Fifo */
1033        Data = 0x0;
1034        status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset, &Data);
1035
1036        Data = Data | 0x0c;
1037        status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);
1038
1039        Data = Data & ~0x0c;
1040        status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);
1041        /* Finally enable all interrupts */
1042        Data = 0x0c;
1043        status = mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
1044
1045        /* clearing rx_disable */
1046        Data = 0x0;
1047        status = mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset,
1048                                                                        &Data);
1049        Data = Data & ~0x20;
1050        status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset,
1051                                                                        Data);
1052
1053        /* rx_negate */
1054        Data = 0x0;
1055        status = mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset,
1056                                                                        &Data);
1057        Data = Data | 0x10;
1058        status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset,
1059                                                                        Data);
1060
1061        /* Check to see if we've set up our endpoint info yet    *
1062         * (can't set it up in mos7840_startup as the structures *
1063         * were not set up at that time.)                        */
1064        if (port0->open_ports == 1) {
1065                if (serial->port[0]->interrupt_in_buffer == NULL) {
1066                        /* set up interrupt urb */
1067                        usb_fill_int_urb(serial->port[0]->interrupt_in_urb,
1068                                serial->dev,
1069                                usb_rcvintpipe(serial->dev,
1070                                serial->port[0]->interrupt_in_endpointAddress),
1071                                serial->port[0]->interrupt_in_buffer,
1072                                serial->port[0]->interrupt_in_urb->
1073                                transfer_buffer_length,
1074                                mos7840_interrupt_callback,
1075                                serial,
1076                                serial->port[0]->interrupt_in_urb->interval);
1077
1078                        /* start interrupt read for mos7840               *
1079                         * will continue as long as mos7840 is connected  */
1080
1081                        response =
1082                            usb_submit_urb(serial->port[0]->interrupt_in_urb,
1083                                           GFP_KERNEL);
1084                        if (response) {
1085                                dev_err(&port->dev, "%s - Error %d submitting "
1086                                        "interrupt urb\n", __func__, response);
1087                        }
1088
1089                }
1090
1091        }
1092
1093        /* see if we've set up our endpoint info yet   *
1094         * (can't set it up in mos7840_startup as the  *
1095         * structures were not set up at that time.)   */
1096
1097        dbg("port number is %d", port->number);
1098        dbg("serial number is %d", port->serial->minor);
1099        dbg("Bulkin endpoint is %d", port->bulk_in_endpointAddress);
1100        dbg("BulkOut endpoint is %d", port->bulk_out_endpointAddress);
1101        dbg("Interrupt endpoint is %d", port->interrupt_in_endpointAddress);
1102        dbg("port's number in the device is %d", mos7840_port->port_num);
1103        mos7840_port->read_urb = port->read_urb;
1104
1105        /* set up our bulk in urb */
1106
1107        usb_fill_bulk_urb(mos7840_port->read_urb,
1108                          serial->dev,
1109                          usb_rcvbulkpipe(serial->dev,
1110                                          port->bulk_in_endpointAddress),
1111                          port->bulk_in_buffer,
1112                          mos7840_port->read_urb->transfer_buffer_length,
1113                          mos7840_bulk_in_callback, mos7840_port);
1114
1115        dbg("mos7840_open: bulkin endpoint is %d",
1116            port->bulk_in_endpointAddress);
1117        mos7840_port->read_urb_busy = true;
1118        response = usb_submit_urb(mos7840_port->read_urb, GFP_KERNEL);
1119        if (response) {
1120                dev_err(&port->dev, "%s - Error %d submitting control urb\n",
1121                        __func__, response);
1122                mos7840_port->read_urb_busy = false;
1123        }
1124
1125        /* initialize our wait queues */
1126        init_waitqueue_head(&mos7840_port->wait_chase);
1127        init_waitqueue_head(&mos7840_port->delta_msr_wait);
1128
1129        /* initialize our icount structure */
1130        memset(&(mos7840_port->icount), 0x00, sizeof(mos7840_port->icount));
1131
1132        /* initialize our port settings */
1133        /* Must set to enable ints! */
1134        mos7840_port->shadowMCR = MCR_MASTER_IE;
1135        /* send a open port command */
1136        mos7840_port->open = 1;
1137        /* mos7840_change_port_settings(mos7840_port,old_termios); */
1138        mos7840_port->icount.tx = 0;
1139        mos7840_port->icount.rx = 0;
1140
1141        dbg("usb_serial serial:%p       mos7840_port:%p\n      usb_serial_port port:%p",
1142                                serial, mos7840_port, port);
1143
1144        dbg ("%s leave", __func__);
1145
1146        return 0;
1147
1148}
1149
1150/*****************************************************************************
1151 * mos7840_chars_in_buffer
1152 *      this function is called by the tty driver when it wants to know how many
1153 *      bytes of data we currently have outstanding in the port (data that has
1154 *      been written, but hasn't made it out the port yet)
1155 *      If successful, we return the number of bytes left to be written in the
1156 *      system,
1157 *      Otherwise we return zero.
1158 *****************************************************************************/
1159
1160static int mos7840_chars_in_buffer(struct tty_struct *tty)
1161{
1162        struct usb_serial_port *port = tty->driver_data;
1163        int i;
1164        int chars = 0;
1165        unsigned long flags;
1166        struct moschip_port *mos7840_port;
1167
1168        dbg("%s", " mos7840_chars_in_buffer:entering ...........");
1169
1170        if (mos7840_port_paranoia_check(port, __func__)) {
1171                dbg("%s", "Invalid port");
1172                return 0;
1173        }
1174
1175        mos7840_port = mos7840_get_port_private(port);
1176        if (mos7840_port == NULL) {
1177                dbg("%s", "mos7840_break:leaving ...........");
1178                return 0;
1179        }
1180
1181        spin_lock_irqsave(&mos7840_port->pool_lock, flags);
1182        for (i = 0; i < NUM_URBS; ++i)
1183                if (mos7840_port->busy[i])
1184                        chars += URB_TRANSFER_BUFFER_SIZE;
1185        spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
1186        dbg("%s - returns %d", __func__, chars);
1187        return chars;
1188
1189}
1190
1191/*****************************************************************************
1192 * mos7840_close
1193 *      this function is called by the tty driver when a port is closed
1194 *****************************************************************************/
1195
1196static void mos7840_close(struct usb_serial_port *port)
1197{
1198        struct usb_serial *serial;
1199        struct moschip_port *mos7840_port;
1200        struct moschip_port *port0;
1201        int j;
1202        __u16 Data;
1203
1204        dbg("%s", "mos7840_close:entering...");
1205
1206        if (mos7840_port_paranoia_check(port, __func__)) {
1207                dbg("%s", "Port Paranoia failed");
1208                return;
1209        }
1210
1211        serial = mos7840_get_usb_serial(port, __func__);
1212        if (!serial) {
1213                dbg("%s", "Serial Paranoia failed");
1214                return;
1215        }
1216
1217        mos7840_port = mos7840_get_port_private(port);
1218        port0 = mos7840_get_port_private(serial->port[0]);
1219
1220        if (mos7840_port == NULL || port0 == NULL)
1221                return;
1222
1223        for (j = 0; j < NUM_URBS; ++j)
1224                usb_kill_urb(mos7840_port->write_urb_pool[j]);
1225
1226        /* Freeing Write URBs */
1227        for (j = 0; j < NUM_URBS; ++j) {
1228                if (mos7840_port->write_urb_pool[j]) {
1229                        if (mos7840_port->write_urb_pool[j]->transfer_buffer)
1230                                kfree(mos7840_port->write_urb_pool[j]->
1231                                      transfer_buffer);
1232
1233                        usb_free_urb(mos7840_port->write_urb_pool[j]);
1234                }
1235        }
1236
1237        /* While closing port, shutdown all bulk read, write  *
1238         * and interrupt read if they exists                  */
1239        if (serial->dev) {
1240                if (mos7840_port->write_urb) {
1241                        dbg("%s", "Shutdown bulk write");
1242                        usb_kill_urb(mos7840_port->write_urb);
1243                }
1244                if (mos7840_port->read_urb) {
1245                        dbg("%s", "Shutdown bulk read");
1246                        usb_kill_urb(mos7840_port->read_urb);
1247                        mos7840_port->read_urb_busy = false;
1248                }
1249                if ((&mos7840_port->control_urb)) {
1250                        dbg("%s", "Shutdown control read");
1251                        /*/      usb_kill_urb (mos7840_port->control_urb); */
1252                }
1253        }
1254/*      if(mos7840_port->ctrl_buf != NULL) */
1255/*              kfree(mos7840_port->ctrl_buf); */
1256        port0->open_ports--;
1257        dbg("mos7840_num_open_ports in close%d:in port%d",
1258            port0->open_ports, port->number);
1259        if (port0->open_ports == 0) {
1260                if (serial->port[0]->interrupt_in_urb) {
1261                        dbg("%s", "Shutdown interrupt_in_urb");
1262                        usb_kill_urb(serial->port[0]->interrupt_in_urb);
1263                }
1264        }
1265
1266        if (mos7840_port->write_urb) {
1267                /* if this urb had a transfer buffer already (old tx) free it */
1268                if (mos7840_port->write_urb->transfer_buffer != NULL)
1269                        kfree(mos7840_port->write_urb->transfer_buffer);
1270                usb_free_urb(mos7840_port->write_urb);
1271        }
1272
1273        Data = 0x0;
1274        mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
1275
1276        Data = 0x00;
1277        mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
1278
1279        mos7840_port->open = 0;
1280
1281        dbg("%s", "Leaving ............");
1282}
1283
1284/************************************************************************
1285 *
1286 * mos7840_block_until_chase_response
1287 *
1288 *      This function will block the close until one of the following:
1289 *              1. Response to our Chase comes from mos7840
1290 *              2. A timeout of 10 seconds without activity has expired
1291 *                 (1K of mos7840 data @ 2400 baud ==> 4 sec to empty)
1292 *
1293 ************************************************************************/
1294
1295static void mos7840_block_until_chase_response(struct tty_struct *tty,
1296                                        struct moschip_port *mos7840_port)
1297{
1298        int timeout = 1 * HZ;
1299        int wait = 10;
1300        int count;
1301
1302        while (1) {
1303                count = mos7840_chars_in_buffer(tty);
1304
1305                /* Check for Buffer status */
1306                if (count <= 0)
1307                        return;
1308
1309                /* Block the thread for a while */
1310                interruptible_sleep_on_timeout(&mos7840_port->wait_chase,
1311                                               timeout);
1312                /* No activity.. count down section */
1313                wait--;
1314                if (wait == 0) {
1315                        dbg("%s - TIMEOUT", __func__);
1316                        return;
1317                } else {
1318                        /* Reset timeout value back to seconds */
1319                        wait = 10;
1320                }
1321        }
1322
1323}
1324
1325/*****************************************************************************
1326 * mos7840_break
1327 *      this function sends a break to the port
1328 *****************************************************************************/
1329static void mos7840_break(struct tty_struct *tty, int break_state)
1330{
1331        struct usb_serial_port *port = tty->driver_data;
1332        unsigned char data;
1333        struct usb_serial *serial;
1334        struct moschip_port *mos7840_port;
1335
1336        dbg("%s", "Entering ...........");
1337        dbg("mos7840_break: Start");
1338
1339        if (mos7840_port_paranoia_check(port, __func__)) {
1340                dbg("%s", "Port Paranoia failed");
1341                return;
1342        }
1343
1344        serial = mos7840_get_usb_serial(port, __func__);
1345        if (!serial) {
1346                dbg("%s", "Serial Paranoia failed");
1347                return;
1348        }
1349
1350        mos7840_port = mos7840_get_port_private(port);
1351
1352        if (mos7840_port == NULL)
1353                return;
1354
1355        if (serial->dev)
1356                /* flush and block until tx is empty */
1357                mos7840_block_until_chase_response(tty, mos7840_port);
1358
1359        if (break_state == -1)
1360                data = mos7840_port->shadowLCR | LCR_SET_BREAK;
1361        else
1362                data = mos7840_port->shadowLCR & ~LCR_SET_BREAK;
1363
1364        /* FIXME: no locking on shadowLCR anywhere in driver */
1365        mos7840_port->shadowLCR = data;
1366        dbg("mcs7840_break mos7840_port->shadowLCR is %x",
1367            mos7840_port->shadowLCR);
1368        mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER,
1369                             mos7840_port->shadowLCR);
1370}
1371
1372/*****************************************************************************
1373 * mos7840_write_room
1374 *      this function is called by the tty driver when it wants to know how many
1375 *      bytes of data we can accept for a specific port.
1376 *      If successful, we return the amount of room that we have for this port
1377 *      Otherwise we return a negative error number.
1378 *****************************************************************************/
1379
1380static int mos7840_write_room(struct tty_struct *tty)
1381{
1382        struct usb_serial_port *port = tty->driver_data;
1383        int i;
1384        int room = 0;
1385        unsigned long flags;
1386        struct moschip_port *mos7840_port;
1387
1388        dbg("%s", " mos7840_write_room:entering ...........");
1389
1390        if (mos7840_port_paranoia_check(port, __func__)) {
1391                dbg("%s", "Invalid port");
1392                dbg("%s", " mos7840_write_room:leaving ...........");
1393                return -1;
1394        }
1395
1396        mos7840_port = mos7840_get_port_private(port);
1397        if (mos7840_port == NULL) {
1398                dbg("%s", "mos7840_break:leaving ...........");
1399                return -1;
1400        }
1401
1402        spin_lock_irqsave(&mos7840_port->pool_lock, flags);
1403        for (i = 0; i < NUM_URBS; ++i) {
1404                if (!mos7840_port->busy[i])
1405                        room += URB_TRANSFER_BUFFER_SIZE;
1406        }
1407        spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
1408
1409        room = (room == 0) ? 0 : room - URB_TRANSFER_BUFFER_SIZE + 1;
1410        dbg("%s - returns %d", __func__, room);
1411        return room;
1412
1413}
1414
1415/*****************************************************************************
1416 * mos7840_write
1417 *      this function is called by the tty driver when data should be written to
1418 *      the port.
1419 *      If successful, we return the number of bytes written, otherwise we
1420 *      return a negative error number.
1421 *****************************************************************************/
1422
1423static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port,
1424                         const unsigned char *data, int count)
1425{
1426        int status;
1427        int i;
1428        int bytes_sent = 0;
1429        int transfer_size;
1430        unsigned long flags;
1431
1432        struct moschip_port *mos7840_port;
1433        struct usb_serial *serial;
1434        struct urb *urb;
1435        /* __u16 Data; */
1436        const unsigned char *current_position = data;
1437        unsigned char *data1;
1438        dbg("%s", "entering ...........");
1439        /* dbg("mos7840_write: mos7840_port->shadowLCR is %x",
1440                                        mos7840_port->shadowLCR); */
1441
1442#ifdef NOTMOS7840
1443        Data = 0x00;
1444        status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data);
1445        mos7840_port->shadowLCR = Data;
1446        dbg("mos7840_write: LINE_CONTROL_REGISTER is %x", Data);
1447        dbg("mos7840_write: mos7840_port->shadowLCR is %x",
1448            mos7840_port->shadowLCR);
1449
1450        /* Data = 0x03; */
1451        /* status = mos7840_set_uart_reg(port,LINE_CONTROL_REGISTER,Data); */
1452        /* mos7840_port->shadowLCR=Data;//Need to add later */
1453
1454        Data |= SERIAL_LCR_DLAB;        /* data latch enable in LCR 0x80 */
1455        status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
1456
1457        /* Data = 0x0c; */
1458        /* status = mos7840_set_uart_reg(port,DIVISOR_LATCH_LSB,Data); */
1459        Data = 0x00;
1460        status = mos7840_get_uart_reg(port, DIVISOR_LATCH_LSB, &Data);
1461        dbg("mos7840_write:DLL value is %x", Data);
1462
1463        Data = 0x0;
1464        status = mos7840_get_uart_reg(port, DIVISOR_LATCH_MSB, &Data);
1465        dbg("mos7840_write:DLM value is %x", Data);
1466
1467        Data = Data & ~SERIAL_LCR_DLAB;
1468        dbg("mos7840_write: mos7840_port->shadowLCR is %x",
1469            mos7840_port->shadowLCR);
1470        status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
1471#endif
1472
1473        if (mos7840_port_paranoia_check(port, __func__)) {
1474                dbg("%s", "Port Paranoia failed");
1475                return -1;
1476        }
1477
1478        serial = port->serial;
1479        if (mos7840_serial_paranoia_check(serial, __func__)) {
1480                dbg("%s", "Serial Paranoia failed");
1481                return -1;
1482        }
1483
1484        mos7840_port = mos7840_get_port_private(port);
1485        if (mos7840_port == NULL) {
1486                dbg("%s", "mos7840_port is NULL");
1487                return -1;
1488        }
1489
1490        /* try to find a free urb in the list */
1491        urb = NULL;
1492
1493        spin_lock_irqsave(&mos7840_port->pool_lock, flags);
1494        for (i = 0; i < NUM_URBS; ++i) {
1495                if (!mos7840_port->busy[i]) {
1496                        mos7840_port->busy[i] = 1;
1497                        urb = mos7840_port->write_urb_pool[i];
1498                        dbg("URB:%d", i);
1499                        break;
1500                }
1501        }
1502        spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
1503
1504        if (urb == NULL) {
1505                dbg("%s - no more free urbs", __func__);
1506                goto exit;
1507        }
1508
1509        if (urb->transfer_buffer == NULL) {
1510                urb->transfer_buffer =
1511                    kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
1512
1513                if (urb->transfer_buffer == NULL) {
1514                        dev_err(&port->dev, "%s no more kernel memory...\n",
1515                                __func__);
1516                        goto exit;
1517                }
1518        }
1519        transfer_size = min(count, URB_TRANSFER_BUFFER_SIZE);
1520
1521        memcpy(urb->transfer_buffer, current_position, transfer_size);
1522
1523        /* fill urb with data and submit  */
1524        usb_fill_bulk_urb(urb,
1525                          serial->dev,
1526                          usb_sndbulkpipe(serial->dev,
1527                                          port->bulk_out_endpointAddress),
1528                          urb->transfer_buffer,
1529                          transfer_size,
1530                          mos7840_bulk_out_data_callback, mos7840_port);
1531
1532        data1 = urb->transfer_buffer;
1533        dbg("bulkout endpoint is %d", port->bulk_out_endpointAddress);
1534
1535        /* send it down the pipe */
1536        status = usb_submit_urb(urb, GFP_ATOMIC);
1537
1538        if (status) {
1539                mos7840_port->busy[i] = 0;
1540                dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed "
1541                        "with status = %d\n", __func__, status);
1542                bytes_sent = status;
1543                goto exit;
1544        }
1545        bytes_sent = transfer_size;
1546        mos7840_port->icount.tx += transfer_size;
1547        smp_wmb();
1548        dbg("mos7840_port->icount.tx is %d:", mos7840_port->icount.tx);
1549exit:
1550        return bytes_sent;
1551
1552}
1553
1554/*****************************************************************************
1555 * mos7840_throttle
1556 *      this function is called by the tty driver when it wants to stop the data
1557 *      being read from the port.
1558 *****************************************************************************/
1559
1560static void mos7840_throttle(struct tty_struct *tty)
1561{
1562        struct usb_serial_port *port = tty->driver_data;
1563        struct moschip_port *mos7840_port;
1564        int status;
1565
1566        if (mos7840_port_paranoia_check(port, __func__)) {
1567                dbg("%s", "Invalid port");
1568                return;
1569        }
1570
1571        dbg("- port %d", port->number);
1572
1573        mos7840_port = mos7840_get_port_private(port);
1574
1575        if (mos7840_port == NULL)
1576                return;
1577
1578        if (!mos7840_port->open) {
1579                dbg("%s", "port not opened");
1580                return;
1581        }
1582
1583        dbg("%s", "Entering ..........");
1584
1585        /* if we are implementing XON/XOFF, send the stop character */
1586        if (I_IXOFF(tty)) {
1587                unsigned char stop_char = STOP_CHAR(tty);
1588                status = mos7840_write(tty, port, &stop_char, 1);
1589                if (status <= 0)
1590                        return;
1591        }
1592        /* if we are implementing RTS/CTS, toggle that line */
1593        if (tty->termios->c_cflag & CRTSCTS) {
1594                mos7840_port->shadowMCR &= ~MCR_RTS;
1595                status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
1596                                         mos7840_port->shadowMCR);
1597                if (status < 0)
1598                        return;
1599        }
1600}
1601
1602/*****************************************************************************
1603 * mos7840_unthrottle
1604 *      this function is called by the tty driver when it wants to resume
1605 *      the data being read from the port (called after mos7840_throttle is
1606 *      called)
1607 *****************************************************************************/
1608static void mos7840_unthrottle(struct tty_struct *tty)
1609{
1610        struct usb_serial_port *port = tty->driver_data;
1611        int status;
1612        struct moschip_port *mos7840_port = mos7840_get_port_private(port);
1613
1614        if (mos7840_port_paranoia_check(port, __func__)) {
1615                dbg("%s", "Invalid port");
1616                return;
1617        }
1618
1619        if (mos7840_port == NULL)
1620                return;
1621
1622        if (!mos7840_port->open) {
1623                dbg("%s - port not opened", __func__);
1624                return;
1625        }
1626
1627        dbg("%s", "Entering ..........");
1628
1629        /* if we are implementing XON/XOFF, send the start character */
1630        if (I_IXOFF(tty)) {
1631                unsigned char start_char = START_CHAR(tty);
1632                status = mos7840_write(tty, port, &start_char, 1);
1633                if (status <= 0)
1634                        return;
1635        }
1636
1637        /* if we are implementing RTS/CTS, toggle that line */
1638        if (tty->termios->c_cflag & CRTSCTS) {
1639                mos7840_port->shadowMCR |= MCR_RTS;
1640                status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
1641                                         mos7840_port->shadowMCR);
1642                if (status < 0)
1643                        return;
1644        }
1645}
1646
1647static int mos7840_tiocmget(struct tty_struct *tty, struct file *file)
1648{
1649        struct usb_serial_port *port = tty->driver_data;
1650        struct moschip_port *mos7840_port;
1651        unsigned int result;
1652        __u16 msr;
1653        __u16 mcr;
1654        int status;
1655        mos7840_port = mos7840_get_port_private(port);
1656
1657        dbg("%s - port %d", __func__, port->number);
1658
1659        if (mos7840_port == NULL)
1660                return -ENODEV;
1661
1662        status = mos7840_get_uart_reg(port, MODEM_STATUS_REGISTER, &msr);
1663        status = mos7840_get_uart_reg(port, MODEM_CONTROL_REGISTER, &mcr);
1664        result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0)
1665            | ((mcr & MCR_RTS) ? TIOCM_RTS : 0)
1666            | ((mcr & MCR_LOOPBACK) ? TIOCM_LOOP : 0)
1667            | ((msr & MOS7840_MSR_CTS) ? TIOCM_CTS : 0)
1668            | ((msr & MOS7840_MSR_CD) ? TIOCM_CAR : 0)
1669            | ((msr & MOS7840_MSR_RI) ? TIOCM_RI : 0)
1670            | ((msr & MOS7840_MSR_DSR) ? TIOCM_DSR : 0);
1671
1672        dbg("%s - 0x%04X", __func__, result);
1673
1674        return result;
1675}
1676
1677static int mos7840_tiocmset(struct tty_struct *tty, struct file *file,
1678                            unsigned int set, unsigned int clear)
1679{
1680        struct usb_serial_port *port = tty->driver_data;
1681        struct moschip_port *mos7840_port;
1682        unsigned int mcr;
1683        int status;
1684
1685        dbg("%s - port %d", __func__, port->number);
1686
1687        mos7840_port = mos7840_get_port_private(port);
1688
1689        if (mos7840_port == NULL)
1690                return -ENODEV;
1691
1692        /* FIXME: What locks the port registers ? */
1693        mcr = mos7840_port->shadowMCR;
1694        if (clear & TIOCM_RTS)
1695                mcr &= ~MCR_RTS;
1696        if (clear & TIOCM_DTR)
1697                mcr &= ~MCR_DTR;
1698        if (clear & TIOCM_LOOP)
1699                mcr &= ~MCR_LOOPBACK;
1700
1701        if (set & TIOCM_RTS)
1702                mcr |= MCR_RTS;
1703        if (set & TIOCM_DTR)
1704                mcr |= MCR_DTR;
1705        if (set & TIOCM_LOOP)
1706                mcr |= MCR_LOOPBACK;
1707
1708        mos7840_port->shadowMCR = mcr;
1709
1710        status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, mcr);
1711        if (status < 0) {
1712                dbg("setting MODEM_CONTROL_REGISTER Failed");
1713                return status;
1714        }
1715
1716        return 0;
1717}
1718
1719/*****************************************************************************
1720 * mos7840_calc_baud_rate_divisor
1721 *      this function calculates the proper baud rate divisor for the specified
1722 *      baud rate.
1723 *****************************************************************************/
1724static int mos7840_calc_baud_rate_divisor(int baudRate, int *divisor,
1725                                          __u16 *clk_sel_val)
1726{
1727
1728        dbg("%s - %d", __func__, baudRate);
1729
1730        if (baudRate <= 115200) {
1731                *divisor = 115200 / baudRate;
1732                *clk_sel_val = 0x0;
1733        }
1734        if ((baudRate > 115200) && (baudRate <= 230400)) {
1735                *divisor = 230400 / baudRate;
1736                *clk_sel_val = 0x10;
1737        } else if ((baudRate > 230400) && (baudRate <= 403200)) {
1738                *divisor = 403200 / baudRate;
1739                *clk_sel_val = 0x20;
1740        } else if ((baudRate > 403200) && (baudRate <= 460800)) {
1741                *divisor = 460800 / baudRate;
1742                *clk_sel_val = 0x30;
1743        } else if ((baudRate > 460800) && (baudRate <= 806400)) {
1744                *divisor = 806400 / baudRate;
1745                *clk_sel_val = 0x40;
1746        } else if ((baudRate > 806400) && (baudRate <= 921600)) {
1747                *divisor = 921600 / baudRate;
1748                *clk_sel_val = 0x50;
1749        } else if ((baudRate > 921600) && (baudRate <= 1572864)) {
1750                *divisor = 1572864 / baudRate;
1751                *clk_sel_val = 0x60;
1752        } else if ((baudRate > 1572864) && (baudRate <= 3145728)) {
1753                *divisor = 3145728 / baudRate;
1754                *clk_sel_val = 0x70;
1755        }
1756        return 0;
1757
1758#ifdef NOTMCS7840
1759
1760        for (i = 0; i < ARRAY_SIZE(mos7840_divisor_table); i++) {
1761                if (mos7840_divisor_table[i].BaudRate == baudrate) {
1762                        *divisor = mos7840_divisor_table[i].Divisor;
1763                        return 0;
1764                }
1765        }
1766
1767        /* After trying for all the standard baud rates    *
1768         * Try calculating the divisor for this baud rate  */
1769
1770        if (baudrate > 75 && baudrate < 230400) {
1771                /* get the divisor */
1772                custom = (__u16) (230400L / baudrate);
1773
1774                /* Check for round off */
1775                round1 = (__u16) (2304000L / baudrate);
1776                round = (__u16) (round1 - (custom * 10));
1777                if (round > 4)
1778                        custom++;
1779                *divisor = custom;
1780
1781                dbg(" Baud %d = %d", baudrate, custom);
1782                return 0;
1783        }
1784
1785        dbg("%s", " Baud calculation Failed...");
1786        return -1;
1787#endif
1788}
1789
1790/*****************************************************************************
1791 * mos7840_send_cmd_write_baud_rate
1792 *      this function sends the proper command to change the baud rate of the
1793 *      specified port.
1794 *****************************************************************************/
1795
1796static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port,
1797                                            int baudRate)
1798{
1799        int divisor = 0;
1800        int status;
1801        __u16 Data;
1802        unsigned char number;
1803        __u16 clk_sel_val;
1804        struct usb_serial_port *port;
1805
1806        if (mos7840_port == NULL)
1807                return -1;
1808
1809        port = (struct usb_serial_port *)mos7840_port->port;
1810        if (mos7840_port_paranoia_check(port, __func__)) {
1811                dbg("%s", "Invalid port");
1812                return -1;
1813        }
1814
1815        if (mos7840_serial_paranoia_check(port->serial, __func__)) {
1816                dbg("%s", "Invalid Serial");
1817                return -1;
1818        }
1819
1820        dbg("%s", "Entering ..........");
1821
1822        number = mos7840_port->port->number - mos7840_port->port->serial->minor;
1823
1824        dbg("%s - port = %d, baud = %d", __func__,
1825            mos7840_port->port->number, baudRate);
1826        /* reset clk_uart_sel in spregOffset */
1827        if (baudRate > 115200) {
1828#ifdef HW_flow_control
1829                /* NOTE: need to see the pther register to modify */
1830                /* setting h/w flow control bit to 1 */
1831                Data = 0x2b;
1832                mos7840_port->shadowMCR = Data;
1833                status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
1834                                                                        Data);
1835                if (status < 0) {
1836                        dbg("Writing spreg failed in set_serial_baud");
1837                        return -1;
1838                }
1839#endif
1840
1841        } else {
1842#ifdef HW_flow_control
1843                / *setting h/w flow control bit to 0 */
1844                Data = 0xb;
1845                mos7840_port->shadowMCR = Data;
1846                status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
1847                                                                        Data);
1848                if (status < 0) {
1849                        dbg("Writing spreg failed in set_serial_baud");
1850                        return -1;
1851                }
1852#endif
1853
1854        }
1855
1856        if (1) {                /* baudRate <= 115200) */
1857                clk_sel_val = 0x0;
1858                Data = 0x0;
1859                status = mos7840_calc_baud_rate_divisor(baudRate, &divisor,
1860                                                   &clk_sel_val);
1861                status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset,
1862                                                                 &Data);
1863                if (status < 0) {
1864                        dbg("reading spreg failed in set_serial_baud");
1865                        return -1;
1866                }
1867                Data = (Data & 0x8f) | clk_sel_val;
1868                status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset,
1869                                                                Data);
1870                if (status < 0) {
1871                        dbg("Writing spreg failed in set_serial_baud");
1872                        return -1;
1873                }
1874                /* Calculate the Divisor */
1875
1876                if (status) {
1877                        dev_err(&port->dev, "%s - bad baud rate\n", __func__);
1878                        return status;
1879                }
1880                /* Enable access to divisor latch */
1881                Data = mos7840_port->shadowLCR | SERIAL_LCR_DLAB;
1882                mos7840_port->shadowLCR = Data;
1883                mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
1884
1885                /* Write the divisor */
1886                Data = (unsigned char)(divisor & 0xff);
1887                dbg("set_serial_baud Value to write DLL is %x", Data);
1888                mos7840_set_uart_reg(port, DIVISOR_LATCH_LSB, Data);
1889
1890                Data = (unsigned char)((divisor & 0xff00) >> 8);
1891                dbg("set_serial_baud Value to write DLM is %x", Data);
1892                mos7840_set_uart_reg(port, DIVISOR_LATCH_MSB, Data);
1893
1894                /* Disable access to divisor latch */
1895                Data = mos7840_port->shadowLCR & ~SERIAL_LCR_DLAB;
1896                mos7840_port->shadowLCR = Data;
1897                mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
1898
1899        }
1900        return status;
1901}
1902
1903/*****************************************************************************
1904 * mos7840_change_port_settings
1905 *      This routine is called to set the UART on the device to match
1906 *      the specified new settings.
1907 *****************************************************************************/
1908
1909static void mos7840_change_port_settings(struct tty_struct *tty,
1910        struct moschip_port *mos7840_port, struct ktermios *old_termios)
1911{
1912        int baud;
1913        unsigned cflag;
1914        unsigned iflag;
1915        __u8 lData;
1916        __u8 lParity;
1917        __u8 lStop;
1918        int status;
1919        __u16 Data;
1920        struct usb_serial_port *port;
1921        struct usb_serial *serial;
1922
1923        if (mos7840_port == NULL)
1924                return;
1925
1926        port = (struct usb_serial_port *)mos7840_port->port;
1927
1928        if (mos7840_port_paranoia_check(port, __func__)) {
1929                dbg("%s", "Invalid port");
1930                return;
1931        }
1932
1933        if (mos7840_serial_paranoia_check(port->serial, __func__)) {
1934                dbg("%s", "Invalid Serial");
1935                return;
1936        }
1937
1938        serial = port->serial;
1939
1940        dbg("%s - port %d", __func__, mos7840_port->port->number);
1941
1942        if (!mos7840_port->open) {
1943                dbg("%s - port not opened", __func__);
1944                return;
1945        }
1946
1947        dbg("%s", "Entering ..........");
1948
1949        lData = LCR_BITS_8;
1950        lStop = LCR_STOP_1;
1951        lParity = LCR_PAR_NONE;
1952
1953        cflag = tty->termios->c_cflag;
1954        iflag = tty->termios->c_iflag;
1955
1956        /* Change the number of bits */
1957        if (cflag & CSIZE) {
1958                switch (cflag & CSIZE) {
1959                case CS5:
1960                        lData = LCR_BITS_5;
1961                        break;
1962
1963                case CS6:
1964                        lData = LCR_BITS_6;
1965                        break;
1966
1967                case CS7:
1968                        lData = LCR_BITS_7;
1969                        break;
1970                default:
1971                case CS8:
1972                        lData = LCR_BITS_8;
1973                        break;
1974                }
1975        }
1976        /* Change the Parity bit */
1977        if (cflag & PARENB) {
1978                if (cflag & PARODD) {
1979                        lParity = LCR_PAR_ODD;
1980                        dbg("%s - parity = odd", __func__);
1981                } else {
1982                        lParity = LCR_PAR_EVEN;
1983                        dbg("%s - parity = even", __func__);
1984                }
1985
1986        } else {
1987                dbg("%s - parity = none", __func__);
1988        }
1989
1990        if (cflag & CMSPAR)
1991                lParity = lParity | 0x20;
1992
1993        /* Change the Stop bit */
1994        if (cflag & CSTOPB) {
1995                lStop = LCR_STOP_2;
1996                dbg("%s - stop bits = 2", __func__);
1997        } else {
1998                lStop = LCR_STOP_1;
1999                dbg("%s - stop bits = 1", __func__);
2000        }
2001
2002        /* Update the LCR with the correct value */
2003        mos7840_port->shadowLCR &=
2004            ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK);
2005        mos7840_port->shadowLCR |= (lData | lParity | lStop);
2006
2007        dbg("mos7840_change_port_settings mos7840_port->shadowLCR is %x",
2008            mos7840_port->shadowLCR);
2009        /* Disable Interrupts */
2010        Data = 0x00;
2011        mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
2012
2013        Data = 0x00;
2014        mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
2015
2016        Data = 0xcf;
2017        mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
2018
2019        /* Send the updated LCR value to the mos7840 */
2020        Data = mos7840_port->shadowLCR;
2021
2022        mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
2023
2024        Data = 0x00b;
2025        mos7840_port->shadowMCR = Data;
2026        mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
2027        Data = 0x00b;
2028        mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
2029
2030        /* set up the MCR register and send it to the mos7840 */
2031
2032        mos7840_port->shadowMCR = MCR_MASTER_IE;
2033        if (cflag & CBAUD)
2034                mos7840_port->shadowMCR |= (MCR_DTR | MCR_RTS);
2035
2036        if (cflag & CRTSCTS)
2037                mos7840_port->shadowMCR |= (MCR_XON_ANY);
2038        else
2039                mos7840_port->shadowMCR &= ~(MCR_XON_ANY);
2040
2041        Data = mos7840_port->shadowMCR;
2042        mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
2043
2044        /* Determine divisor based on baud rate */
2045        baud = tty_get_baud_rate(tty);
2046
2047        if (!baud) {
2048                /* pick a default, any default... */
2049                dbg("%s", "Picked default baud...");
2050                baud = 9600;
2051        }
2052
2053        dbg("%s - baud rate = %d", __func__, baud);
2054        status = mos7840_send_cmd_write_baud_rate(mos7840_port, baud);
2055
2056        /* Enable Interrupts */
2057        Data = 0x0c;
2058        mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
2059
2060        if (mos7840_port->read_urb_busy == false) {
2061                mos7840_port->read_urb->dev = serial->dev;
2062                mos7840_port->read_urb_busy = true;
2063                status = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC);
2064                if (status) {
2065                        dbg("usb_submit_urb(read bulk) failed, status = %d",
2066                            status);
2067                        mos7840_port->read_urb_busy = false;
2068                }
2069        }
2070        wake_up(&mos7840_port->delta_msr_wait);
2071        mos7840_port->delta_msr_cond = 1;
2072        dbg("mos7840_change_port_settings mos7840_port->shadowLCR is End %x",
2073            mos7840_port->shadowLCR);
2074}
2075
2076/*****************************************************************************
2077 * mos7840_set_termios
2078 *      this function is called by the tty driver when it wants to change
2079 *      the termios structure
2080 *****************************************************************************/
2081
2082static void mos7840_set_termios(struct tty_struct *tty,
2083                                struct usb_serial_port *port,
2084                                struct ktermios *old_termios)
2085{
2086        int status;
2087        unsigned int cflag;
2088        struct usb_serial *serial;
2089        struct moschip_port *mos7840_port;
2090        dbg("mos7840_set_termios: START");
2091        if (mos7840_port_paranoia_check(port, __func__)) {
2092                dbg("%s", "Invalid port");
2093                return;
2094        }
2095
2096        serial = port->serial;
2097
2098        if (mos7840_serial_paranoia_check(serial, __func__)) {
2099                dbg("%s", "Invalid Serial");
2100                return;
2101        }
2102
2103        mos7840_port = mos7840_get_port_private(port);
2104
2105        if (mos7840_port == NULL)
2106                return;
2107
2108        if (!mos7840_port->open) {
2109                dbg("%s - port not opened", __func__);
2110                return;
2111        }
2112
2113        dbg("%s", "setting termios - ");
2114
2115        cflag = tty->termios->c_cflag;
2116
2117        dbg("%s - clfag %08x iflag %08x", __func__,
2118            tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag));
2119        dbg("%s - old clfag %08x old iflag %08x", __func__,
2120            old_termios->c_cflag, RELEVANT_IFLAG(old_termios->c_iflag));
2121        dbg("%s - port %d", __func__, port->number);
2122
2123        /* change the port settings to the new ones specified */
2124
2125        mos7840_change_port_settings(tty, mos7840_port, old_termios);
2126
2127        if (!mos7840_port->read_urb) {
2128                dbg("%s", "URB KILLED !!!!!");
2129                return;
2130        }
2131
2132        if (mos7840_port->read_urb_busy == false) {
2133                mos7840_port->read_urb->dev = serial->dev;
2134                mos7840_port->read_urb_busy = true;
2135                status = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC);
2136                if (status) {
2137                        dbg("usb_submit_urb(read bulk) failed, status = %d",
2138                            status);
2139                        mos7840_port->read_urb_busy = false;
2140                }
2141        }
2142}
2143
2144/*****************************************************************************
2145 * mos7840_get_lsr_info - get line status register info
2146 *
2147 * Purpose: Let user call ioctl() to get info when the UART physically
2148 *          is emptied.  On bus types like RS485, the transmitter must
2149 *          release the bus after transmitting. This must be done when
2150 *          the transmit shift register is empty, not be done when the
2151 *          transmit holding register is empty.  This functionality
2152 *          allows an RS485 driver to be written in user space.
2153 *****************************************************************************/
2154
2155static int mos7840_get_lsr_info(struct tty_struct *tty,
2156                                unsigned int __user *value)
2157{
2158        int count;
2159        unsigned int result = 0;
2160
2161        count = mos7840_chars_in_buffer(tty);
2162        if (count == 0) {
2163                dbg("%s -- Empty", __func__);
2164                result = TIOCSER_TEMT;
2165        }
2166
2167        if (copy_to_user(value, &result, sizeof(int)))
2168                return -EFAULT;
2169        return 0;
2170}
2171
2172/*****************************************************************************
2173 * mos7840_get_serial_info
2174 *      function to get information about serial port
2175 *****************************************************************************/
2176
2177static int mos7840_get_serial_info(struct moschip_port *mos7840_port,
2178                                   struct serial_struct __user *retinfo)
2179{
2180        struct serial_struct tmp;
2181
2182        if (mos7840_port == NULL)
2183                return -1;
2184
2185        if (!retinfo)
2186                return -EFAULT;
2187
2188        memset(&tmp, 0, sizeof(tmp));
2189
2190        tmp.type = PORT_16550A;
2191        tmp.line = mos7840_port->port->serial->minor;
2192        tmp.port = mos7840_port->port->number;
2193        tmp.irq = 0;
2194        tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
2195        tmp.xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE;
2196        tmp.baud_base = 9600;
2197        tmp.close_delay = 5 * HZ;
2198        tmp.closing_wait = 30 * HZ;
2199
2200        if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
2201                return -EFAULT;
2202        return 0;
2203}
2204
2205static int mos7840_get_icount(struct tty_struct *tty,
2206                        struct serial_icounter_struct *icount)
2207{
2208        struct usb_serial_port *port = tty->driver_data;
2209        struct moschip_port *mos7840_port;
2210        struct async_icount cnow;
2211
2212        mos7840_port = mos7840_get_port_private(port);
2213        cnow = mos7840_port->icount;
2214
2215        smp_rmb();
2216        icount->cts = cnow.cts;
2217        icount->dsr = cnow.dsr;
2218        icount->rng = cnow.rng;
2219        icount->dcd = cnow.dcd;
2220        icount->rx = cnow.rx;
2221        icount->tx = cnow.tx;
2222        icount->frame = cnow.frame;
2223        icount->overrun = cnow.overrun;
2224        icount->parity = cnow.parity;
2225        icount->brk = cnow.brk;
2226        icount->buf_overrun = cnow.buf_overrun;
2227
2228        dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __func__,
2229                port->number, icount->rx, icount->tx);
2230        return 0;
2231}
2232
2233/*****************************************************************************
2234 * SerialIoctl
2235 *      this function handles any ioctl calls to the driver
2236 *****************************************************************************/
2237
2238static int mos7840_ioctl(struct tty_struct *tty, struct file *file,
2239                         unsigned int cmd, unsigned long arg)
2240{
2241        struct usb_serial_port *port = tty->driver_data;
2242        void __user *argp = (void __user *)arg;
2243        struct moschip_port *mos7840_port;
2244
2245        struct async_icount cnow;
2246        struct async_icount cprev;
2247
2248        if (mos7840_port_paranoia_check(port, __func__)) {
2249                dbg("%s", "Invalid port");
2250                return -1;
2251        }
2252
2253        mos7840_port = mos7840_get_port_private(port);
2254
2255        if (mos7840_port == NULL)
2256                return -1;
2257
2258        dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd);
2259
2260        switch (cmd) {
2261                /* return number of bytes available */
2262
2263        case TIOCSERGETLSR:
2264                dbg("%s (%d) TIOCSERGETLSR", __func__, port->number);
2265                return mos7840_get_lsr_info(tty, argp);
2266                return 0;
2267
2268        case TIOCGSERIAL:
2269                dbg("%s (%d) TIOCGSERIAL", __func__, port->number);
2270                return mos7840_get_serial_info(mos7840_port, argp);
2271
2272        case TIOCSSERIAL:
2273                dbg("%s (%d) TIOCSSERIAL", __func__, port->number);
2274                break;
2275
2276        case TIOCMIWAIT:
2277                dbg("%s (%d) TIOCMIWAIT", __func__, port->number);
2278                cprev = mos7840_port->icount;
2279                while (1) {
2280                        /* interruptible_sleep_on(&mos7840_port->delta_msr_wait); */
2281                        mos7840_port->delta_msr_cond = 0;
2282                        wait_event_interruptible(mos7840_port->delta_msr_wait,
2283                                                 (mos7840_port->
2284                                                  delta_msr_cond == 1));
2285
2286                        /* see if a signal did it */
2287                        if (signal_pending(current))
2288                                return -ERESTARTSYS;
2289                        cnow = mos7840_port->icount;
2290                        smp_rmb();
2291                        if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
2292                            cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
2293                                return -EIO;    /* no change => error */
2294                        if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
2295                            ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
2296                            ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
2297                            ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
2298                                return 0;
2299                        }
2300                        cprev = cnow;
2301                }
2302                /* NOTREACHED */
2303                break;
2304
2305        default:
2306                break;
2307        }
2308        return -ENOIOCTLCMD;
2309}
2310
2311static int mos7840_calc_num_ports(struct usb_serial *serial)
2312{
2313        int mos7840_num_ports = 0;
2314
2315        dbg("numberofendpoints: cur %d, alt %d",
2316            (int)serial->interface->cur_altsetting->desc.bNumEndpoints,
2317            (int)serial->interface->altsetting->desc.bNumEndpoints);
2318        if (serial->interface->cur_altsetting->desc.bNumEndpoints == 5) {
2319                mos7840_num_ports = serial->num_ports = 2;
2320        } else if (serial->interface->cur_altsetting->desc.bNumEndpoints == 9) {
2321                serial->num_bulk_in = 4;
2322                serial->num_bulk_out = 4;
2323                mos7840_num_ports = serial->num_ports = 4;
2324        }
2325        dbg ("mos7840_num_ports = %d", mos7840_num_ports);
2326        return mos7840_num_ports;
2327}
2328
2329/****************************************************************************
2330 * mos7840_startup
2331 ****************************************************************************/
2332
2333static int mos7840_startup(struct usb_serial *serial)
2334{
2335        struct moschip_port *mos7840_port;
2336        struct usb_device *dev;
2337        int i, status;
2338
2339        __u16 Data;
2340        dbg("%s", "mos7840_startup :Entering..........");
2341
2342        if (!serial) {
2343                dbg("%s", "Invalid Handler");
2344                return -1;
2345        }
2346
2347        dev = serial->dev;
2348
2349        dbg("%s", "Entering...");
2350        dbg ("mos7840_startup: serial = %p", serial);
2351
2352        /* we set up the pointers to the endpoints in the mos7840_open *
2353         * function, as the structures aren't created yet.             */
2354
2355        /* set up port private structures */
2356        for (i = 0; i < serial->num_ports; ++i) {
2357                dbg ("mos7840_startup: configuring port %d............", i);
2358                mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL);
2359                if (mos7840_port == NULL) {
2360                        dev_err(&dev->dev, "%s - Out of memory\n", __func__);
2361                        status = -ENOMEM;
2362                        i--; /* don't follow NULL pointer cleaning up */
2363                        goto error;
2364                }
2365
2366                /* Initialize all port interrupt end point to port 0 int
2367                 * endpoint. Our device has only one interrupt end point
2368                 * common to all port */
2369
2370                mos7840_port->port = serial->port[i];
2371                mos7840_set_port_private(serial->port[i], mos7840_port);
2372                spin_lock_init(&mos7840_port->pool_lock);
2373
2374                /* minor is not initialised until later by
2375                 * usb-serial.c:get_free_serial() and cannot therefore be used
2376                 * to index device instances */
2377                mos7840_port->port_num = i + 1;
2378                dbg ("serial->port[i]->number = %d", serial->port[i]->number);
2379                dbg ("serial->port[i]->serial->minor = %d", serial->port[i]->serial->minor);
2380                dbg ("mos7840_port->port_num = %d", mos7840_port->port_num);
2381                dbg ("serial->minor = %d", serial->minor);
2382
2383                if (mos7840_port->port_num == 1) {
2384                        mos7840_port->SpRegOffset = 0x0;
2385                        mos7840_port->ControlRegOffset = 0x1;
2386                        mos7840_port->DcrRegOffset = 0x4;
2387                } else if ((mos7840_port->port_num == 2)
2388                           && (serial->num_ports == 4)) {
2389                        mos7840_port->SpRegOffset = 0x8;
2390                        mos7840_port->ControlRegOffset = 0x9;
2391                        mos7840_port->DcrRegOffset = 0x16;
2392                } else if ((mos7840_port->port_num == 2)
2393                           && (serial->num_ports == 2)) {
2394                        mos7840_port->SpRegOffset = 0xa;
2395                        mos7840_port->ControlRegOffset = 0xb;
2396                        mos7840_port->DcrRegOffset = 0x19;
2397                } else if ((mos7840_port->port_num == 3)
2398                           && (serial->num_ports == 4)) {
2399                        mos7840_port->SpRegOffset = 0xa;
2400                        mos7840_port->ControlRegOffset = 0xb;
2401                        mos7840_port->DcrRegOffset = 0x19;
2402                } else if ((mos7840_port->port_num == 4)
2403                           && (serial->num_ports == 4)) {
2404                        mos7840_port->SpRegOffset = 0xc;
2405                        mos7840_port->ControlRegOffset = 0xd;
2406                        mos7840_port->DcrRegOffset = 0x1c;
2407                }
2408                mos7840_dump_serial_port(mos7840_port);
2409                mos7840_set_port_private(serial->port[i], mos7840_port);
2410
2411                /* enable rx_disable bit in control register */
2412                status = mos7840_get_reg_sync(serial->port[i],
2413                                 mos7840_port->ControlRegOffset, &Data);
2414                if (status < 0) {
2415                        dbg("Reading ControlReg failed status-0x%x", status);
2416                        break;
2417                } else
2418                        dbg("ControlReg Reading success val is %x, status%d",
2419                            Data, status);
2420                Data |= 0x08;   /* setting driver done bit */
2421                Data |= 0x04;   /* sp1_bit to have cts change reflect in
2422                                   modem status reg */
2423
2424                /* Data |= 0x20; //rx_disable bit */
2425                status = mos7840_set_reg_sync(serial->port[i],
2426                                         mos7840_port->ControlRegOffset, Data);
2427                if (status < 0) {
2428                        dbg("Writing ControlReg failed(rx_disable) status-0x%x", status);
2429                        break;
2430                } else
2431                        dbg("ControlReg Writing success(rx_disable) status%d",
2432                            status);
2433
2434                /* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2
2435                   and 0x24 in DCR3 */
2436                Data = 0x01;
2437                status = mos7840_set_reg_sync(serial->port[i],
2438                         (__u16) (mos7840_port->DcrRegOffset + 0), Data);
2439                if (status < 0) {
2440                        dbg("Writing DCR0 failed status-0x%x", status);
2441                        break;
2442                } else
2443                        dbg("DCR0 Writing success status%d", status);
2444
2445                Data = 0x05;
2446                status = mos7840_set_reg_sync(serial->port[i],
2447                         (__u16) (mos7840_port->DcrRegOffset + 1), Data);
2448                if (status < 0) {
2449                        dbg("Writing DCR1 failed status-0x%x", status);
2450                        break;
2451                } else
2452                        dbg("DCR1 Writing success status%d", status);
2453
2454                Data = 0x24;
2455                status = mos7840_set_reg_sync(serial->port[i],
2456                         (__u16) (mos7840_port->DcrRegOffset + 2), Data);
2457                if (status < 0) {
2458                        dbg("Writing DCR2 failed status-0x%x", status);
2459                        break;
2460                } else
2461                        dbg("DCR2 Writing success status%d", status);
2462
2463                /* write values in clkstart0x0 and clkmulti 0x20 */
2464                Data = 0x0;
2465                status = mos7840_set_reg_sync(serial->port[i],
2466                                         CLK_START_VALUE_REGISTER, Data);
2467                if (status < 0) {
2468                        dbg("Writing CLK_START_VALUE_REGISTER failed status-0x%x", status);
2469                        break;
2470                } else
2471                        dbg("CLK_START_VALUE_REGISTER Writing success status%d", status);
2472
2473                Data = 0x20;
2474                status = mos7840_set_reg_sync(serial->port[i],
2475                                        CLK_MULTI_REGISTER, Data);
2476                if (status < 0) {
2477                        dbg("Writing CLK_MULTI_REGISTER failed status-0x%x",
2478                            status);
2479                        goto error;
2480                } else
2481                        dbg("CLK_MULTI_REGISTER Writing success status%d",
2482                            status);
2483
2484                /* write value 0x0 to scratchpad register */
2485                Data = 0x00;
2486                status = mos7840_set_uart_reg(serial->port[i],
2487                                                SCRATCH_PAD_REGISTER, Data);
2488                if (status < 0) {
2489                        dbg("Writing SCRATCH_PAD_REGISTER failed status-0x%x",
2490                            status);
2491                        break;
2492                } else
2493                        dbg("SCRATCH_PAD_REGISTER Writing success status%d",
2494                            status);
2495
2496                /* Zero Length flag register */
2497                if ((mos7840_port->port_num != 1)
2498                    && (serial->num_ports == 2)) {
2499
2500                        Data = 0xff;
2501                        status = mos7840_set_reg_sync(serial->port[i],
2502                                      (__u16) (ZLP_REG1 +
2503                                      ((__u16)mos7840_port->port_num)), Data);
2504                        dbg("ZLIP offset %x",
2505                            (__u16) (ZLP_REG1 +
2506                                        ((__u16) mos7840_port->port_num)));
2507                        if (status < 0) {
2508                                dbg("Writing ZLP_REG%d failed status-0x%x",
2509                                    i + 2, status);
2510                                break;
2511                        } else
2512                                dbg("ZLP_REG%d Writing success status%d",
2513                                    i + 2, status);
2514                } else {
2515                        Data = 0xff;
2516                        status = mos7840_set_reg_sync(serial->port[i],
2517                              (__u16) (ZLP_REG1 +
2518                              ((__u16)mos7840_port->port_num) - 0x1), Data);
2519                        dbg("ZLIP offset %x",
2520                            (__u16) (ZLP_REG1 +
2521                                     ((__u16) mos7840_port->port_num) - 0x1));
2522                        if (status < 0) {
2523                                dbg("Writing ZLP_REG%d failed status-0x%x",
2524                                    i + 1, status);
2525                                break;
2526                        } else
2527                                dbg("ZLP_REG%d Writing success status%d",
2528                                    i + 1, status);
2529
2530                }
2531                mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL);
2532                mos7840_port->ctrl_buf = kmalloc(16, GFP_KERNEL);
2533                mos7840_port->dr = kmalloc(sizeof(struct usb_ctrlrequest),
2534                                                                GFP_KERNEL);
2535                if (!mos7840_port->control_urb || !mos7840_port->ctrl_buf ||
2536                                                        !mos7840_port->dr) {
2537                        status = -ENOMEM;
2538                        goto error;
2539                }
2540        }
2541        dbg ("mos7840_startup: all ports configured...........");
2542
2543        /* Zero Length flag enable */
2544        Data = 0x0f;
2545        status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data);
2546        if (status < 0) {
2547                dbg("Writing ZLP_REG5 failed status-0x%x", status);
2548                goto error;
2549        } else
2550                dbg("ZLP_REG5 Writing success status%d", status);
2551
2552        /* setting configuration feature to one */
2553        usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
2554                        (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5 * HZ);
2555        return 0;
2556error:
2557        for (/* nothing */; i >= 0; i--) {
2558                mos7840_port = mos7840_get_port_private(serial->port[i]);
2559
2560                kfree(mos7840_port->dr);
2561                kfree(mos7840_port->ctrl_buf);
2562                usb_free_urb(mos7840_port->control_urb);
2563                kfree(mos7840_port);
2564                serial->port[i] = NULL;
2565        }
2566        return status;
2567}
2568
2569/****************************************************************************
2570 * mos7840_disconnect
2571 *      This function is called whenever the device is removed from the usb bus.
2572 ****************************************************************************/
2573
2574static void mos7840_disconnect(struct usb_serial *serial)
2575{
2576        int i;
2577        unsigned long flags;
2578        struct moschip_port *mos7840_port;
2579        dbg("%s", " disconnect :entering..........");
2580
2581        if (!serial) {
2582                dbg("%s", "Invalid Handler");
2583                return;
2584        }
2585
2586        /* check for the ports to be closed,close the ports and disconnect */
2587
2588        /* free private structure allocated for serial port  *
2589         * stop reads and writes on all ports                */
2590
2591        for (i = 0; i < serial->num_ports; ++i) {
2592                mos7840_port = mos7840_get_port_private(serial->port[i]);
2593                dbg ("mos7840_port %d = %p", i, mos7840_port);
2594                if (mos7840_port) {
2595                        spin_lock_irqsave(&mos7840_port->pool_lock, flags);
2596                        mos7840_port->zombie = 1;
2597                        spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
2598                        usb_kill_urb(mos7840_port->control_urb);
2599                }
2600        }
2601
2602        dbg("%s", "Thank u :: ");
2603
2604}
2605
2606/****************************************************************************
2607 * mos7840_release
2608 *      This function is called when the usb_serial structure is freed.
2609 ****************************************************************************/
2610
2611static void mos7840_release(struct usb_serial *serial)
2612{
2613        int i;
2614        struct moschip_port *mos7840_port;
2615        dbg("%s", " release :entering..........");
2616
2617        if (!serial) {
2618                dbg("%s", "Invalid Handler");
2619                return;
2620        }
2621
2622        /* check for the ports to be closed,close the ports and disconnect */
2623
2624        /* free private structure allocated for serial port  *
2625         * stop reads and writes on all ports                */
2626
2627        for (i = 0; i < serial->num_ports; ++i) {
2628                mos7840_port = mos7840_get_port_private(serial->port[i]);
2629                dbg("mos7840_port %d = %p", i, mos7840_port);
2630                if (mos7840_port) {
2631                        kfree(mos7840_port->ctrl_buf);
2632                        kfree(mos7840_port->dr);
2633                        kfree(mos7840_port);
2634                }
2635        }
2636
2637        dbg("%s", "Thank u :: ");
2638
2639}
2640
2641static struct usb_driver io_driver = {
2642        .name = "mos7840",
2643        .probe = usb_serial_probe,
2644        .disconnect = usb_serial_disconnect,
2645        .id_table = moschip_id_table_combined,
2646        .no_dynamic_id = 1,
2647};
2648
2649static struct usb_serial_driver moschip7840_4port_device = {
2650        .driver = {
2651                   .owner = THIS_MODULE,
2652                   .name = "mos7840",
2653                   },
2654        .description = DRIVER_DESC,
2655        .usb_driver = &io_driver,
2656        .id_table = moschip_port_id_table,
2657        .num_ports = 4,
2658        .open = mos7840_open,
2659        .close = mos7840_close,
2660        .write = mos7840_write,
2661        .write_room = mos7840_write_room,
2662        .chars_in_buffer = mos7840_chars_in_buffer,
2663        .throttle = mos7840_throttle,
2664        .unthrottle = mos7840_unthrottle,
2665        .calc_num_ports = mos7840_calc_num_ports,
2666#ifdef MCSSerialProbe
2667        .probe = mos7840_serial_probe,
2668#endif
2669        .ioctl = mos7840_ioctl,
2670        .set_termios = mos7840_set_termios,
2671        .break_ctl = mos7840_break,
2672        .tiocmget = mos7840_tiocmget,
2673        .tiocmset = mos7840_tiocmset,
2674        .get_icount = mos7840_get_icount,
2675        .attach = mos7840_startup,
2676        .disconnect = mos7840_disconnect,
2677        .release = mos7840_release,
2678        .read_bulk_callback = mos7840_bulk_in_callback,
2679        .read_int_callback = mos7840_interrupt_callback,
2680};
2681
2682/****************************************************************************
2683 * moschip7840_init
2684 *      This is called by the module subsystem, or on startup to initialize us
2685 ****************************************************************************/
2686static int __init moschip7840_init(void)
2687{
2688        int retval;
2689
2690        dbg("%s", " mos7840_init :entering..........");
2691
2692        /* Register with the usb serial */
2693        retval = usb_serial_register(&moschip7840_4port_device);
2694
2695        if (retval)
2696                goto failed_port_device_register;
2697
2698        dbg("%s", "Entering...");
2699        printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
2700               DRIVER_DESC "\n");
2701
2702        /* Register with the usb */
2703        retval = usb_register(&io_driver);
2704        if (retval == 0) {
2705                dbg("%s", "Leaving...");
2706                return 0;
2707        }
2708        usb_serial_deregister(&moschip7840_4port_device);
2709failed_port_device_register:
2710        return retval;
2711}
2712
2713/****************************************************************************
2714 * moschip7840_exit
2715 *      Called when the driver is about to be unloaded.
2716 ****************************************************************************/
2717static void __exit moschip7840_exit(void)
2718{
2719
2720        dbg("%s", " mos7840_exit :entering..........");
2721
2722        usb_deregister(&io_driver);
2723
2724        usb_serial_deregister(&moschip7840_4port_device);
2725
2726        dbg("%s", "Entering...");
2727}
2728
2729module_init(moschip7840_init);
2730module_exit(moschip7840_exit);
2731
2732/* Module information */
2733MODULE_DESCRIPTION(DRIVER_DESC);
2734MODULE_LICENSE("GPL");
2735
2736module_param(debug, bool, S_IRUGO | S_IWUSR);
2737MODULE_PARM_DESC(debug, "Debug enabled or not");
2738