Fixed code to fix tty_driver's kref field
checkpatch.pl clean up
Signed-off-by: Baodong Chen <[email protected]>
---
 drivers/staging/net/pc300_tty.c |  763 ++++++++++++++++++++-------------------
 1 files changed, 386 insertions(+), 377 deletions(-)

diff --git a/drivers/staging/net/pc300_tty.c b/drivers/staging/net/pc300_tty.c
index 4709f42..859f680 100644
--- a/drivers/staging/net/pc300_tty.c
+++ b/drivers/staging/net/pc300_tty.c
@@ -9,7 +9,7 @@
  *  modify it under the terms of the GNU General Public License
  *  as published by the Free Software Foundation; either version
  *  2 of the License, or (at your option) any later version.
- *   
+ *
  *  $Log: pc300_tty.c,v $
  *  Revision 3.7  2002/03/07 14:17:09  henrique
  *  License data fixed
@@ -30,7 +30,7 @@
  *  bug fix - DCD-OFF in pc300 tty driver
  *
  *     DMA transmission bug fix
- *  
+ *
  *  Revision 3.1  2001/06/22 13:13:02  regina
  *  MLPPP implementation
  *
@@ -46,6 +46,8 @@
 #include <linux/slab.h>
 #include <linux/if.h>
 #include <linux/skbuff.h>
+#include <linux/kref.h>
+
 /* TTY includes */
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
@@ -59,50 +61,50 @@
 /* defines and macros */
 /* TTY Global definitions */
 #define        CPC_TTY_NPORTS  8       /* maximum number of the sync tty 
connections */
-#define        CPC_TTY_MAJOR   CYCLADES_MAJOR  
+#define        CPC_TTY_MAJOR   CYCLADES_MAJOR
 #define CPC_TTY_MINOR_START    240     /* minor of the first PC300 interface */
 
-#define CPC_TTY_MAX_MTU        2000    
+#define CPC_TTY_MAX_MTU        2000
 
 /* tty interface state */
 #define        CPC_TTY_ST_IDLE 0
 #define CPC_TTY_ST_INIT        1       /* configured with MLPPP and up */
 #define CPC_TTY_ST_OPEN        2       /* opened by application */
 
-#define        CPC_TTY_LOCK(card,flags)\
+#define        CPC_TTY_LOCK(card, flags)\
        do {\
                spin_lock_irqsave(&card->card_lock, flags);     \
        } while (0)
 
-#define CPC_TTY_UNLOCK(card,flags)     \
+#define CPC_TTY_UNLOCK(card, flags)    \
        do {\
                spin_unlock_irqrestore(&card->card_lock, flags);        \
        } while (0)
 
-//#define      CPC_TTY_DBG(format,a...)        printk(format,##a)
-#define        CPC_TTY_DBG(format,a...)
+/* #define     CPC_TTY_DBG(format, a...)       printk(format, ##a) */
+#define        CPC_TTY_DBG(format, a...)
 
 /* data structures */
-typedef struct _st_cpc_rx_buf {
-       struct _st_cpc_rx_buf   *next;
+struct st_cpc_rx_buf {
+       struct st_cpc_rx_buf *next;
        int             size;
        unsigned char   data[1];
-} st_cpc_rx_buf;
+};
 
 struct st_cpc_rx_list {
-       st_cpc_rx_buf   *first;
-       st_cpc_rx_buf   *last;
+       struct st_cpc_rx_buf    *first;
+       struct st_cpc_rx_buf    *last;
 };
 
 typedef        struct _st_cpc_tty_area {
        int             state;          /* state of the TTY interface */
-       int             num_open;       
+       int             num_open;
        unsigned int    tty_minor;      /* minor this interface */
        volatile struct st_cpc_rx_list buf_rx;  /* ptr. to reception buffer */
-       unsigned char*  buf_tx;         /* ptr. to transmission buffer */
-       pc300dev_t*     pc300dev;       /* ptr. to info struct in PC300 driver 
*/
+       unsigned char   *buf_tx;                /* ptr. to transmission buffer 
*/
+       pc300dev_t      *pc300dev;      /* ptr. to info struct in PC300 driver 
*/
        unsigned char   name[20];       /* interf. name + "-tty" */
-       struct tty_struct *tty;         
+       struct tty_struct *tty;
        struct work_struct tty_tx_work; /* tx work - tx interrupt */
        struct work_struct tty_rx_work; /* rx work - rx interrupt */
        } st_cpc_tty_area;
@@ -126,36 +128,50 @@ static void cpc_tty_flush_buffer(struct tty_struct *tty);
 static void cpc_tty_hangup(struct tty_struct *tty);
 static void cpc_tty_rx_work(struct work_struct *work);
 static void cpc_tty_tx_work(struct work_struct *work);
-static int cpc_tty_send_to_card(pc300dev_t *dev,void *buf, int len);
-static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx);
+static int cpc_tty_send_to_card(pc300dev_t *dev, void *buf, int len);
+static void cpc_tty_trace(pc300dev_t *dev, char *buf, int len, char rxtx);
 static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char);
 static void cpc_tty_signal_on(pc300dev_t *pc300dev, unsigned char);
 
 static int pc300_tiocmset(struct tty_struct *, unsigned int, unsigned int);
 static int pc300_tiocmget(struct tty_struct *);
 
+static void cpc_tty_do_unreg_driver(struct kref *ref);
+
 /* functions called by PC300 driver */
 void cpc_tty_init(pc300dev_t *dev);
 void cpc_tty_unregister_service(pc300dev_t *pc300dev);
 void cpc_tty_receive(pc300dev_t *pc300dev);
 void cpc_tty_trigger_poll(pc300dev_t *pc300dev);
 
+static void cpc_tty_do_unreg_driver(struct kref *ref)
+{
+       struct tty_driver *drv = container_of(ref, struct tty_driver, kref);
+       int ret;
+
+       cpc_tty_unreg_flag = 0;
+
+       res = tty_unregister_driver(drv);
+       if (res)
+               CPC_TTY_DBG("unregister the tty driver error=%d\n", res);
+}
+
 /*
  * PC300 TTY clear "signal"
  */
 static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char signal)
 {
-       pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; 
-       pc300_t *card = (pc300_t *) pc300chan->card; 
-       int ch = pc300chan->channel; 
-       unsigned long flags; 
+       pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan;
+       pc300_t *card = (pc300_t *) pc300chan->card;
+       int ch = pc300chan->channel;
+       unsigned long flags;
 
        CPC_TTY_DBG("%s-tty: Clear signal %x\n",
                pc300dev->dev->name, signal);
-       CPC_TTY_LOCK(card, flags); 
-       cpc_writeb(card->hw.scabase + M_REG(CTL,ch), 
-               cpc_readb(card->hw.scabase+M_REG(CTL,ch))& signal);
-       CPC_TTY_UNLOCK(card,flags); 
+       CPC_TTY_LOCK(card, flags);
+       cpc_writeb(card->hw.scabase + M_REG(CTL, ch),
+               cpc_readb(card->hw.scabase + M_REG(CTL, ch)) & signal);
+       CPC_TTY_UNLOCK(card, flags);
 }
 
 /*
@@ -163,17 +179,17 @@ static void cpc_tty_signal_off(pc300dev_t *pc300dev, 
unsigned char signal)
  */
 static void cpc_tty_signal_on(pc300dev_t *pc300dev, unsigned char signal)
 {
-       pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; 
-       pc300_t *card = (pc300_t *) pc300chan->card; 
-       int ch = pc300chan->channel; 
-       unsigned long flags; 
+       pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan;
+       pc300_t *card = (pc300_t *) pc300chan->card;
+       int ch = pc300chan->channel;
+       unsigned long flags;
 
        CPC_TTY_DBG("%s-tty: Set signal %x\n",
                pc300dev->dev->name, signal);
-       CPC_TTY_LOCK(card, flags); 
-       cpc_writeb(card->hw.scabase + M_REG(CTL,ch), 
-               cpc_readb(card->hw.scabase+M_REG(CTL,ch))& ~signal);
-       CPC_TTY_UNLOCK(card,flags); 
+       CPC_TTY_LOCK(card, flags);
+       cpc_writeb(card->hw.scabase + M_REG(CTL, ch),
+               cpc_readb(card->hw.scabase + M_REG(CTL, ch)) & ~signal);
+       CPC_TTY_UNLOCK(card, flags);
 }
 
 
@@ -193,7 +209,7 @@ static const struct tty_operations pc300_ops = {
 /*
  * PC300 TTY initialization routine
  *
- * This routine is called by the PC300 driver during board configuration 
+ * This routine is called by the PC300 driver during board configuration
  * (ioctl=SIOCSP300CONF). At this point the adapter is completely
  * initialized.
  * o verify kernel version (only 2.4.x)
@@ -204,14 +220,14 @@ void cpc_tty_init(pc300dev_t *pc300dev)
 {
        unsigned long port;
        int aux;
-       st_cpc_tty_area * cpc_tty;
+       st_cpc_tty_area *cpc_tty;
 
        /* hdlcX - X=interface number */
        port = pc300dev->dev->name[4] - '0';
        if (port >= CPC_TTY_NPORTS) {
                printk("%s-tty: invalid interface selected (0-%i): %li",
                        pc300dev->dev->name,
-                       CPC_TTY_NPORTS-1,port);
+                       CPC_TTY_NPORTS-1, port);
                return;
        }
 
@@ -221,7 +237,7 @@ void cpc_tty_init(pc300dev_t *pc300dev)
                        CPC_TTY_MAJOR, CPC_TTY_MINOR_START,
                        CPC_TTY_MINOR_START+CPC_TTY_NPORTS);
                /* initialize tty driver struct */
-               memset(&serial_drv,0,sizeof(struct tty_driver));
+               memset(&serial_drv, 0, sizeof(struct tty_driver));
                serial_drv.magic = TTY_DRIVER_MAGIC;
                serial_drv.owner = THIS_MODULE;
                serial_drv.driver_name = "pc300_tty";
@@ -239,19 +255,21 @@ void cpc_tty_init(pc300dev_t *pc300dev)
                /* interface routines from the upper tty layer to the tty 
driver */
                tty_set_operations(&serial_drv, &pc300_ops);
 
+               kref_init(&serial_drv.kref);
+
                /* register the TTY driver */
-               if (tty_register_driver(&serial_drv)) { 
+               if (tty_register_driver(&serial_drv)) {
                        printk("%s-tty: Failed to register serial driver! ",
                                pc300dev->dev->name);
-                       return;
-               } 
+                       return;
+               }
 
                memset((void *)cpc_tty_area, 0,
-                                                               
sizeof(st_cpc_tty_area) * CPC_TTY_NPORTS);
+                       sizeof(st_cpc_tty_area) * CPC_TTY_NPORTS);
        }
 
        cpc_tty = &cpc_tty_area[port];
-       
+
        if (cpc_tty->state != CPC_TTY_ST_IDLE) {
                CPC_TTY_DBG("%s-tty: TTY port %i, already in use.\n",
                                pc300dev->dev->name, port);
@@ -259,34 +277,34 @@ void cpc_tty_init(pc300dev_t *pc300dev)
        }
 
        cpc_tty_cnt++;
-       cpc_tty->state = CPC_TTY_ST_INIT; 
-       cpc_tty->num_open= 0;
+       cpc_tty->state = CPC_TTY_ST_INIT;
+       cpc_tty->num_open = 0;
        cpc_tty->tty_minor = port + CPC_TTY_MINOR_START;
-       cpc_tty->pc300dev = pc300dev; 
+       cpc_tty->pc300dev = pc300dev;
 
        INIT_WORK(&cpc_tty->tty_tx_work, cpc_tty_tx_work);
        INIT_WORK(&cpc_tty->tty_rx_work, cpc_tty_rx_work);
-       
+
        cpc_tty->buf_rx.first = cpc_tty->buf_rx.last = NULL;
 
-       pc300dev->cpc_tty = (void *)cpc_tty; 
-       
+       pc300dev->cpc_tty = (void *)cpc_tty;
+
        aux = strlen(pc300dev->dev->name);
        memcpy(cpc_tty->name, pc300dev->dev->name, aux);
        memcpy(&cpc_tty->name[aux], "-tty", 5);
-       
+
        cpc_open(pc300dev->dev);
        cpc_tty_signal_off(pc300dev, CTL_DTR);
 
        CPC_TTY_DBG("%s: Initializing TTY Sync Driver, tty major#%d minor#%i\n",
-                       cpc_tty->name,CPC_TTY_MAJOR,cpc_tty->tty_minor); 
-       return; 
-} 
+                       cpc_tty->name, CPC_TTY_MAJOR, cpc_tty->tty_minor);
+       return;
+}
 
 /*
  * PC300 TTY OPEN routine
  *
- * This routine is called by the tty driver to open the interface 
+ * This routine is called by the tty driver to open the interface
  * o verify minor
  * o allocate buffer to Rx and Tx
  */
@@ -295,36 +313,36 @@ static int cpc_tty_open(struct tty_struct *tty, struct 
file *flip)
        int port ;
        st_cpc_tty_area *cpc_tty;
 
-       if (!tty) { 
+       if (!tty) {
                return -ENODEV;
-       } 
+       }
 
        port = tty->index;
 
-       if ((port < 0) || (port >= CPC_TTY_NPORTS)){ 
+       if ((port < 0) || (port >= CPC_TTY_NPORTS)) {
                CPC_TTY_DBG("pc300_tty: open invalid port %d\n", port);
                return -ENODEV;
-       } 
+       }
 
        cpc_tty = &cpc_tty_area[port];
-       
-       if (cpc_tty->state == CPC_TTY_ST_IDLE){
+
+       if (cpc_tty->state == CPC_TTY_ST_IDLE) {
                CPC_TTY_DBG("%s: open - invalid interface, port=%d\n",
                                        cpc_tty->name, tty->index);
                return -ENODEV;
        }
 
        if (cpc_tty->num_open == 0) { /* first open of this tty */
-               if (!cpc_tty_area[port].buf_tx){
-                       cpc_tty_area[port].buf_tx = 
kmalloc(CPC_TTY_MAX_MTU,GFP_KERNEL);
+               if (!cpc_tty_area[port].buf_tx) {
+                       cpc_tty_area[port].buf_tx = kmalloc(CPC_TTY_MAX_MTU, 
GFP_KERNEL);
                        if (!cpc_tty_area[port].buf_tx) {
-                               CPC_TTY_DBG("%s: error in memory 
allocation\n",cpc_tty->name);
+                               CPC_TTY_DBG("%s: error in memory allocation\n", 
cpc_tty->name);
                                return -ENOMEM;
                        }
-               } 
+               }
 
                if (cpc_tty_area[port].buf_rx.first) {
-                       unsigned char * aux;
+                       unsigned char *aux;
                        while (cpc_tty_area[port].buf_rx.first) {
                                aux = (unsigned char 
*)cpc_tty_area[port].buf_rx.first;
                                cpc_tty_area[port].buf_rx.first = 
cpc_tty_area[port].buf_rx.first->next;
@@ -339,20 +357,20 @@ static int cpc_tty_open(struct tty_struct *tty, struct 
file *flip)
                tty->driver_data = &cpc_tty_area[port];
 
                cpc_tty_signal_on(cpc_tty->pc300dev, CTL_DTR);
-       } 
+       }
 
        cpc_tty->num_open++;
 
        CPC_TTY_DBG("%s: opening TTY driver\n", cpc_tty->name);
-       
-       /* avisar driver PC300 */ 
-       return 0; 
+
+       /* avisar driver PC300 */
+       return 0;
 }
 
 /*
  * PC300 TTY CLOSE routine
  *
- * This routine is called by the tty driver to close the interface 
+ * This routine is called by the tty driver to close the interface
  * o call close channel in PC300 driver (cpc_closech)
  * o free Rx and Tx buffers
  */
@@ -363,37 +381,37 @@ static void cpc_tty_close(struct tty_struct *tty, struct 
file *flip)
        unsigned long flags;
        int res;
 
-       if (!tty || !tty->driver_data ) {
+       if (!tty || !tty->driver_data) {
                CPC_TTY_DBG("hdlx-tty: no TTY in close\n");
                return;
        }
 
        cpc_tty = (st_cpc_tty_area *) tty->driver_data;
 
-       if ((cpc_tty->tty != tty)|| (cpc_tty->state != CPC_TTY_ST_OPEN)) {
-               CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name);
+       if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) {
+               CPC_TTY_DBG("%s: TTY is not opened\n", cpc_tty->name);
                return;
        }
-       
+
        if (!cpc_tty->num_open) {
-               CPC_TTY_DBG("%s: TTY is closed\n",cpc_tty->name);
+               CPC_TTY_DBG("%s: TTY is closed\n", cpc_tty->name);
                return;
        }
 
        if (--cpc_tty->num_open > 0) {
-               CPC_TTY_DBG("%s: TTY closed\n",cpc_tty->name);
+               CPC_TTY_DBG("%s: TTY closed\n", cpc_tty->name);
                return;
        }
 
        cpc_tty_signal_off(cpc_tty->pc300dev, CTL_DTR);
 
-       CPC_TTY_LOCK(cpc_tty->pc300dev->chan->card, flags);  /* lock irq */ 
+       CPC_TTY_LOCK(cpc_tty->pc300dev->chan->card, flags);  /* lock irq */
        cpc_tty->tty = NULL;
        cpc_tty->state = CPC_TTY_ST_INIT;
-       CPC_TTY_UNLOCK(cpc_tty->pc300dev->chan->card, flags); /* unlock irq */ 
-       
+       CPC_TTY_UNLOCK(cpc_tty->pc300dev->chan->card, flags); /* unlock irq */
+
        if (cpc_tty->buf_rx.first) {
-               unsigned char * aux;
+               unsigned char *aux;
                while (cpc_tty->buf_rx.first) {
                        aux = (unsigned char *)cpc_tty->buf_rx.first;
                        cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next;
@@ -402,22 +420,18 @@ static void cpc_tty_close(struct tty_struct *tty, struct 
file *flip)
                cpc_tty->buf_rx.first = NULL;
                cpc_tty->buf_rx.last = NULL;
        }
-       
+
        kfree(cpc_tty->buf_tx);
        cpc_tty->buf_tx = NULL;
 
-       CPC_TTY_DBG("%s: TTY closed\n",cpc_tty->name);
-       
-       if (!serial_drv.refcount && cpc_tty_unreg_flag) {
-               cpc_tty_unreg_flag = 0;
-               CPC_TTY_DBG("%s: unregister the tty driver\n", cpc_tty->name);
-               if ((res=tty_unregister_driver(&serial_drv))) { 
-                       CPC_TTY_DBG("%s: ERROR ->unregister the tty driver 
error=%d\n",
-                                                       cpc_tty->name,res);
-               }
+       CPC_TTY_DBG("%s: TTY closed\n", cpc_tty->name);
+
+       if (cpc_tty_unreg_flag) {
+               CPC_TTY_DBG("%s: checking unregister the tty driver...\n", 
cpc_tty->name);
+               kref_put(&serial_drv.kref, cpc_tty_do_unreg_driver);
        }
-       return; 
-} 
+       return;
+}
 
 /*
  * PC300 TTY WRITE routine
@@ -429,131 +443,131 @@ static void cpc_tty_close(struct tty_struct *tty, 
struct file *flip)
  */
 static int cpc_tty_write(struct tty_struct *tty, const unsigned char *buf, int 
count)
 {
-       st_cpc_tty_area    *cpc_tty; 
-       pc300ch_t *pc300chan; 
-       pc300_t *card; 
-       int ch; 
-       unsigned long flags; 
-       struct net_device_stats *stats; 
-
-       if (!tty || !tty->driver_data ) { 
+       st_cpc_tty_area    *cpc_tty;
+       pc300ch_t *pc300chan;
+       pc300_t *card;
+       int ch;
+       unsigned long flags;
+       struct net_device_stats *stats;
+
+       if (!tty || !tty->driver_data) {
                CPC_TTY_DBG("hdlcX-tty: no TTY in write\n");
                return -ENODEV;
-       } 
+       }
 
-       cpc_tty = (st_cpc_tty_area *) tty->driver_data; 
+       cpc_tty = (st_cpc_tty_area *) tty->driver_data;
 
-       if ((cpc_tty->tty != tty) ||  (cpc_tty->state != CPC_TTY_ST_OPEN)) { 
+       if ((cpc_tty->tty != tty) ||  (cpc_tty->state != CPC_TTY_ST_OPEN)) {
                CPC_TTY_DBG("%s: TTY is not opened\n", cpc_tty->name);
-               return -ENODEV; 
+               return -ENODEV;
        }
 
-       if (count > CPC_TTY_MAX_MTU) { 
-               CPC_TTY_DBG("%s: count is invalid\n",cpc_tty->name);
-               return -EINVAL;        /* frame too big */ 
+       if (count > CPC_TTY_MAX_MTU) {
+               CPC_TTY_DBG("%s: count is invalid\n", cpc_tty->name);
+               return -EINVAL;        /* frame too big */
        }
 
-       CPC_TTY_DBG("%s: cpc_tty_write data len=%i\n",cpc_tty->name,count);
-       
-       pc300chan = (pc300ch_t *)((pc300dev_t*)cpc_tty->pc300dev)->chan; 
+       CPC_TTY_DBG("%s: cpc_tty_write data len=%i\n", cpc_tty->name, count);
+
+       pc300chan = (pc300ch_t *)((pc300dev_t *)cpc_tty->pc300dev)->chan;
        stats = &cpc_tty->pc300dev->dev->stats;
        card = (pc300_t *) pc300chan->card;
-       ch = pc300chan->channel; 
+       ch = pc300chan->channel;
 
-       /* verify DCD signal*/ 
-       if (cpc_readb(card->hw.scabase + M_REG(ST3,ch)) & ST3_DCD) { 
-               /* DCD is OFF */ 
+       /* verify DCD signal*/
+       if (cpc_readb(card->hw.scabase + M_REG(ST3, ch)) & ST3_DCD) {
+               /* DCD is OFF */
                CPC_TTY_DBG("%s : DCD is OFF\n", cpc_tty->name);
                stats->tx_errors++;
                stats->tx_carrier_errors++;
-               CPC_TTY_LOCK(card, flags); 
-               cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_BUF_CLR); 
-               
-               if (card->hw.type == PC300_TE) { 
-                       cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, 
-                               cpc_readb(card->hw.falcbase + 
card->hw.cpld_reg2) & 
-                               ~(CPLD_REG2_FALC_LED1 << (2 *ch))); 
+               CPC_TTY_LOCK(card, flags);
+               cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_BUF_CLR);
+
+               if (card->hw.type == PC300_TE) {
+                       cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2,
+                               cpc_readb(card->hw.falcbase + 
card->hw.cpld_reg2) &
+                               ~(CPLD_REG2_FALC_LED1 << (2 * ch)));
                }
 
-               CPC_TTY_UNLOCK(card, flags); 
+               CPC_TTY_UNLOCK(card, flags);
 
-               return -EINVAL; 
+               return -EINVAL;
        }
 
-       if (cpc_tty_send_to_card(cpc_tty->pc300dev, (void*)buf, count)) { 
+       if (cpc_tty_send_to_card(cpc_tty->pc300dev, (void *)buf, count)) {
           /* failed to send */
           CPC_TTY_DBG("%s: trasmition error\n", cpc_tty->name);
           return 0;
        }
-       return count; 
-} 
+       return count;
+}
 
 /*
  * PC300 TTY Write Room routine
- * 
+ *
  * This routine returns the numbers of characteres the tty driver will accept
- * for queuing to be written. 
+ * for queuing to be written.
  * o return MTU
  */
 static int cpc_tty_write_room(struct tty_struct *tty)
 {
-       st_cpc_tty_area    *cpc_tty; 
+       st_cpc_tty_area    *cpc_tty;
 
-       if (!tty || !tty->driver_data ) { 
+       if (!tty || !tty->driver_data) {
                CPC_TTY_DBG("hdlcX-tty: no TTY to write room\n");
                return -ENODEV;
        }
 
-       cpc_tty = (st_cpc_tty_area *) tty->driver_data; 
+       cpc_tty = (st_cpc_tty_area *) tty->driver_data;
 
-       if ((cpc_tty->tty != tty) ||  (cpc_tty->state != CPC_TTY_ST_OPEN)) { 
-               CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name);
-               return -ENODEV; 
+       if ((cpc_tty->tty != tty) ||  (cpc_tty->state != CPC_TTY_ST_OPEN)) {
+               CPC_TTY_DBG("%s: TTY is not opened\n", cpc_tty->name);
+               return -ENODEV;
        }
-       
-       CPC_TTY_DBG("%s: write room\n",cpc_tty->name);
-       
+
+       CPC_TTY_DBG("%s: write room\n", cpc_tty->name);
+
        return CPC_TTY_MAX_MTU;
-} 
+}
 
 /*
  * PC300 TTY chars in buffer routine
- * 
- * This routine returns the chars number in the transmission buffer 
+ *
+ * This routine returns the chars number in the transmission buffer
  * o returns 0
  */
 static int cpc_tty_chars_in_buffer(struct tty_struct *tty)
 {
-       st_cpc_tty_area    *cpc_tty; 
+       st_cpc_tty_area    *cpc_tty;
 
-       if (!tty || !tty->driver_data ) {
+       if (!tty || !tty->driver_data) {
                CPC_TTY_DBG("hdlcX-tty: no TTY to chars in buffer\n");
-               return -ENODEV; 
+               return -ENODEV;
        }
 
-       cpc_tty = (st_cpc_tty_area *) tty->driver_data; 
+       cpc_tty = (st_cpc_tty_area *) tty->driver_data;
 
-       if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { 
-               CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name);
-               return -ENODEV; 
+       if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) {
+               CPC_TTY_DBG("%s: TTY is not opened\n", cpc_tty->name);
+               return -ENODEV;
        }
-   
+
        return 0;
-} 
+}
 
 static int pc300_tiocmset(struct tty_struct *tty,
                          unsigned int set, unsigned int clear)
 {
-       st_cpc_tty_area    *cpc_tty; 
+       st_cpc_tty_area    *cpc_tty;
 
        CPC_TTY_DBG("%s: set:%x clear:%x\n", __func__, set, clear);
 
-       if (!tty || !tty->driver_data ) {
-               CPC_TTY_DBG("hdlcX-tty: no TTY to chars in buffer\n");  
-               return -ENODEV; 
+       if (!tty || !tty->driver_data) {
+               CPC_TTY_DBG("hdlcX-tty: no TTY to chars in buffer\n");
+               return -ENODEV;
        }
 
-       cpc_tty = (st_cpc_tty_area *) tty->driver_data; 
+       cpc_tty = (st_cpc_tty_area *) tty->driver_data;
 
        if (set & TIOCM_RTS)
                cpc_tty_signal_on(cpc_tty->pc300dev, CTL_RTS);
@@ -582,11 +596,11 @@ static int pc300_tiocmget(struct tty_struct *tty)
        cpc_tty = (st_cpc_tty_area *) tty->driver_data;
 
        CPC_TTY_DBG("%s-tty: tiocmget\n",
-               ((struct net_device*)(pc300dev->hdlc))->name);
+               ((struct net_device *)(pc300dev->hdlc))->name);
 
        CPC_TTY_LOCK(card, flags);
-       status = cpc_readb(card->hw.scabase+M_REG(CTL,ch));
-       CPC_TTY_UNLOCK(card,flags);
+       status = cpc_readb(card->hw.scabase + M_REG(CTL, ch));
+       CPC_TTY_UNLOCK(card, flags);
 
        result = ((status & CTL_DTR) ? TIOCM_DTR : 0) |
                 ((status & CTL_RTS) ? TIOCM_RTS : 0);
@@ -597,60 +611,56 @@ static int pc300_tiocmget(struct tty_struct *tty)
 /*
  * PC300 TTY Flush Buffer routine
  *
- * This routine resets the transmission buffer 
+ * This routine resets the transmission buffer
  */
 static void cpc_tty_flush_buffer(struct tty_struct *tty)
-{ 
-       st_cpc_tty_area    *cpc_tty; 
-       
-       if (!tty || !tty->driver_data ) {
-               CPC_TTY_DBG("hdlcX-tty: no TTY to flush buffer\n");     
-               return; 
+{
+       st_cpc_tty_area    *cpc_tty;
+
+       if (!tty || !tty->driver_data) {
+               CPC_TTY_DBG("hdlcX-tty: no TTY to flush buffer\n");
+               return;
        }
 
-       cpc_tty = (st_cpc_tty_area *) tty->driver_data; 
+       cpc_tty = (st_cpc_tty_area *) tty->driver_data;
 
-       if ((cpc_tty->tty != tty) ||  (cpc_tty->state != CPC_TTY_ST_OPEN)) { 
-               CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name);
-               return; 
+       if ((cpc_tty->tty != tty) ||  (cpc_tty->state != CPC_TTY_ST_OPEN)) {
+               CPC_TTY_DBG("%s: TTY is not opened\n", cpc_tty->name);
+               return;
        }
 
-       CPC_TTY_DBG("%s: call wake_up_interruptible\n",cpc_tty->name);
+       CPC_TTY_DBG("%s: call wake_up_interruptible\n", cpc_tty->name);
 
-       tty_wakeup(tty);        
-       return; 
-} 
+       tty_wakeup(tty);
+       return;
+}
 
 /*
  * PC300 TTY Hangup routine
  *
- * This routine is called by the tty driver to hangup the interface 
+ * This routine is called by the tty driver to hangup the interface
  * o clear DTR signal
  */
 
 static void cpc_tty_hangup(struct tty_struct *tty)
-{ 
-       st_cpc_tty_area    *cpc_tty; 
+{
+       st_cpc_tty_area    *cpc_tty;
        int res;
 
-       if (!tty || !tty->driver_data ) {
-               CPC_TTY_DBG("hdlcX-tty: no TTY to hangup\n");   
-               return ; 
+       if (!tty || !tty->driver_data) {
+               CPC_TTY_DBG("hdlcX-tty: no TTY to hangup\n");
+               return ;
        }
 
-       cpc_tty = (st_cpc_tty_area *) tty->driver_data; 
+       cpc_tty = (st_cpc_tty_area *) tty->driver_data;
 
        if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) {
-               CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name);
+               CPC_TTY_DBG("%s: TTY is not opened\n", cpc_tty->name);
                return ;
        }
-       if (!serial_drv.refcount && cpc_tty_unreg_flag) {
-               cpc_tty_unreg_flag = 0;
-               CPC_TTY_DBG("%s: unregister the tty driver\n", cpc_tty->name);
-               if ((res=tty_unregister_driver(&serial_drv))) { 
-                       CPC_TTY_DBG("%s: ERROR ->unregister the tty driver 
error=%d\n",
-                                                       cpc_tty->name,res);
-               }
+       if (cpc_tty_unreg_flag) {
+               CPC_TTY_DBG("%s: checking unregister the tty driver...\n", 
cpc_tty->name);
+               kref_put(&serial_drv.kref, cpc_tty_do_unreg_driver);
        }
        cpc_tty_signal_off(cpc_tty->pc300dev, CTL_DTR);
 }
@@ -667,96 +677,98 @@ static void cpc_tty_rx_work(struct work_struct *work)
        st_cpc_tty_area *cpc_tty;
        unsigned long port;
        int i, j;
-       volatile st_cpc_rx_buf *buf;
-       char flags=0,flg_rx=1; 
+       volatile struct st_cpc_rx_buf *buf;
+       char flags = 0, flg_rx = 1;
        struct tty_ldisc *ld;
 
-       if (cpc_tty_cnt == 0) return;
-       
-       for (i=0; (i < 4) && flg_rx ; i++) {
+       if (cpc_tty_cnt == 0)
+               return;
+
+       for (i = 0; (i < 4) && flg_rx ; i++) {
                flg_rx = 0;
 
                cpc_tty = container_of(work, st_cpc_tty_area, tty_rx_work);
                port = cpc_tty - cpc_tty_area;
 
-               for (j=0; j < CPC_TTY_NPORTS; j++) {
+               for (j = 0; j < CPC_TTY_NPORTS; j++) {
                        cpc_tty = &cpc_tty_area[port];
-               
-                       if ((buf=cpc_tty->buf_rx.first) != NULL) {
+                       buf = cpc_tty->buf_rx.first
+                       if (buf != NULL) {
                                if (cpc_tty->tty) {
                                        ld = tty_ldisc_ref(cpc_tty->tty);
                                        if (ld) {
                                                if (ld->ops->receive_buf) {
-                                                       CPC_TTY_DBG("%s: call 
line disc. receive_buf\n",cpc_tty->name);
+                                                       CPC_TTY_DBG("%s: call 
line disc. receive_buf\n", cpc_tty->name);
                                                        
ld->ops->receive_buf(cpc_tty->tty, (char *)(buf->data), &flags, buf->size);
                                                }
                                                tty_ldisc_deref(ld);
                                        }
-                               }       
+                               }
                                cpc_tty->buf_rx.first = 
cpc_tty->buf_rx.first->next;
                                kfree((void *)buf);
                                buf = cpc_tty->buf_rx.first;
                                flg_rx = 1;
                        }
-                       if (++port == CPC_TTY_NPORTS) port = 0;
+                       if (++port == CPC_TTY_NPORTS)
+                               port = 0;
                }
        }
-} 
+}
 
 /*
  * PC300 TTY RX work routine
  *
- * This routine treats RX interrupt. 
+ * This routine treats RX interrupt.
  * o read all frames in card
  * o verify the frame size
  * o read the frame in rx buffer
  */
 static void cpc_tty_rx_disc_frame(pc300ch_t *pc300chan)
 {
-       volatile pcsca_bd_t __iomem * ptdescr; 
-       volatile unsigned char status; 
-       pc300_t *card = (pc300_t *)pc300chan->card; 
-       int ch = pc300chan->channel; 
-
-       /* dma buf read */ 
-       ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + 
-                               RX_BD_ADDR(ch, pc300chan->rx_first_bd)); 
-       while (pc300chan->rx_first_bd != pc300chan->rx_last_bd) { 
-               status = cpc_readb(&ptdescr->status); 
-               cpc_writeb(&ptdescr->status, 0); 
-               cpc_writeb(&ptdescr->len, 0); 
-               pc300chan->rx_first_bd = (pc300chan->rx_first_bd + 1) & 
-                                       (N_DMA_RX_BUF - 1); 
-               if (status & DST_EOM) { 
+       volatile pcsca_bd_t __iomem *ptdescr;
+       volatile unsigned char status;
+       pc300_t *card = (pc300_t *)pc300chan->card;
+       int ch = pc300chan->channel;
+
+       /* dma buf read */
+       ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase +
+                               RX_BD_ADDR(ch, pc300chan->rx_first_bd));
+       while (pc300chan->rx_first_bd != pc300chan->rx_last_bd) {
+               status = cpc_readb(&ptdescr->status);
+               cpc_writeb(&ptdescr->status, 0);
+               cpc_writeb(&ptdescr->len, 0);
+               pc300chan->rx_first_bd = (pc300chan->rx_first_bd + 1) &
+                                       (N_DMA_RX_BUF - 1);
+               if (status & DST_EOM) {
                        break; /* end of message */
                }
-               ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + 
cpc_readl(&ptdescr->next)); 
+               ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + 
cpc_readl(&ptdescr->next));
        }
 }
 
 void cpc_tty_receive(pc300dev_t *pc300dev)
 {
-       st_cpc_tty_area *cpc_tty; 
-       pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; 
-       pc300_t *card = (pc300_t *)pc300chan->card; 
-       int ch = pc300chan->channel; 
-       volatile pcsca_bd_t  __iomem * ptdescr; 
+       st_cpc_tty_area *cpc_tty;
+       pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan;
+       pc300_t *card = (pc300_t *)pc300chan->card;
+       int ch = pc300chan->channel;
+       volatile pcsca_bd_t  __iomem *ptdescr;
        struct net_device_stats *stats = &pc300dev->dev->stats;
-       int rx_len, rx_aux; 
-       volatile unsigned char status; 
+       int rx_len, rx_aux;
+       volatile unsigned char status;
        unsigned short first_bd = pc300chan->rx_first_bd;
-       st_cpc_rx_buf *new = NULL;
+       struct st_cpc_rx_buf *new = NULL;
        unsigned char dsr_rx;
 
-       if (pc300dev->cpc_tty == NULL) { 
-               return; 
+       if (pc300dev->cpc_tty == NULL) {
+               return;
        }
 
        dsr_rx = cpc_readb(card->hw.scabase + DSR_RX(ch));
 
        cpc_tty = pc300dev->cpc_tty;
 
-       while (1) { 
+       while (1) {
                rx_len = 0;
                ptdescr = (pcsca_bd_t  __iomem *)(card->hw.rambase + 
RX_BD_ADDR(ch, first_bd));
                while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) {
@@ -767,55 +779,55 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
                        }
                        ptdescr = (pcsca_bd_t __iomem 
*)(card->hw.rambase+cpc_readl(&ptdescr->next));
                }
-                       
-               if (!rx_len) { 
+
+               if (!rx_len) {
                        if (dsr_rx & DSR_BOF) {
-                               /* update EDA */ 
-                               cpc_writel(card->hw.scabase + DRX_REG(EDAL, 
ch), 
-                                               RX_BD_ADDR(ch, 
pc300chan->rx_last_bd)); 
+                               /* update EDA */
+                               cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch),
+                                               RX_BD_ADDR(ch, 
pc300chan->rx_last_bd));
                        }
                        kfree(new);
-                       return; 
+                       return;
                }
-               
-               if (rx_len > CPC_TTY_MAX_MTU) { 
-                       /* Free RX descriptors */ 
-                       CPC_TTY_DBG("%s: frame size is 
invalid.\n",cpc_tty->name);
-                       stats->rx_errors++; 
-                       stats->rx_frame_errors++; 
+
+               if (rx_len > CPC_TTY_MAX_MTU) {
+                       /* Free RX descriptors */
+                       CPC_TTY_DBG("%s: frame size is invalid.\n", 
cpc_tty->name);
+                       stats->rx_errors++;
+                       stats->rx_frame_errors++;
                        cpc_tty_rx_disc_frame(pc300chan);
                        continue;
-               } 
-               
-               new = kmalloc(rx_len + sizeof(st_cpc_rx_buf), GFP_ATOMIC);
+               }
+
+               new = kmalloc(rx_len + sizeof(struct st_cpc_rx_buf), 
GFP_ATOMIC);
                if (!new) {
                        cpc_tty_rx_disc_frame(pc300chan);
                        continue;
                }
-               
-               /* dma buf read */ 
-               ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + 
-                               RX_BD_ADDR(ch, pc300chan->rx_first_bd)); 
+
+               /* dma buf read */
+               ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase +
+                               RX_BD_ADDR(ch, pc300chan->rx_first_bd));
 
                rx_len = 0;     /* counter frame size */
-               
+
                while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) {
                        rx_aux = cpc_readw(&ptdescr->len);
                        if ((status & (DST_OVR | DST_CRC | DST_RBIT |  DST_SHRT 
| DST_ABT))
                                || (rx_aux > BD_DEF_LEN)) {
                                CPC_TTY_DBG("%s: reception error\n", 
cpc_tty->name);
-                               stats->rx_errors++; 
-                               if (status & DST_OVR) { 
-                                       stats->rx_fifo_errors++; 
+                               stats->rx_errors++;
+                               if (status & DST_OVR) {
+                                       stats->rx_fifo_errors++;
                                }
-                               if (status & DST_CRC) { 
-                                       stats->rx_crc_errors++; 
+                               if (status & DST_CRC) {
+                                       stats->rx_crc_errors++;
                                }
                                if ((status & (DST_RBIT | DST_SHRT | DST_ABT)) 
||
-                                       (rx_aux > BD_DEF_LEN))  { 
-                                       stats->rx_frame_errors++; 
-                               } 
-                               /* discard remainig descriptors used by the bad 
frame */ 
+                                       (rx_aux > BD_DEF_LEN))  {
+                                       stats->rx_frame_errors++;
+                               }
+                               /* discard remainig descriptors used by the bad 
frame */
                                CPC_TTY_DBG("%s: reception error - discard 
descriptors",
                                                cpc_tty->name);
                                cpc_tty_rx_disc_frame(pc300chan);
@@ -826,10 +838,10 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
                        }
 
                        if (cpc_tty->state != CPC_TTY_ST_OPEN) {
-                               /* Free RX descriptors */ 
+                               /* Free RX descriptors */
                                cpc_tty_rx_disc_frame(pc300chan);
-                               stats->rx_dropped++; 
-                               rx_len = 0; 
+                               stats->rx_dropped++;
+                               rx_len = 0;
                                kfree(new);
                                new = NULL;
                                break; /* read next frame - while(1) */
@@ -837,34 +849,35 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
 
                        /* read the segment of the frame */
                        if (rx_aux != 0) {
-                               memcpy_fromio((new->data + rx_len), 
-                                       (void __iomem *)(card->hw.rambase + 
+                               memcpy_fromio((new->data + rx_len),
+                                       (void __iomem *)(card->hw.rambase +
                                         cpc_readl(&ptdescr->ptbuf)), rx_aux);
-                               rx_len += rx_aux; 
+                               rx_len += rx_aux;
                        }
-                       cpc_writeb(&ptdescr->status,0); 
-                       cpc_writeb(&ptdescr->len, 0); 
-                       pc300chan->rx_first_bd = (pc300chan->rx_first_bd + 1) & 
-                                       (N_DMA_RX_BUF -1); 
-                       if (status & DST_EOM)break;
-                       
-                       ptdescr = (pcsca_bd_t __iomem *) (card->hw.rambase + 
-                                       cpc_readl(&ptdescr->next)); 
+                       cpc_writeb(&ptdescr->status, 0);
+                       cpc_writeb(&ptdescr->len, 0);
+                       pc300chan->rx_first_bd = (pc300chan->rx_first_bd + 1) &
+                                       (N_DMA_RX_BUF - 1);
+                       if (status & DST_EOM)
+                               break;
+
+                       ptdescr = (pcsca_bd_t __iomem *) (card->hw.rambase +
+                                       cpc_readl(&ptdescr->next));
                }
-               /* update pointer */ 
-               pc300chan->rx_last_bd = (pc300chan->rx_first_bd - 1) & 
-                                       (N_DMA_RX_BUF - 1) ; 
+               /* update pointer */
+               pc300chan->rx_last_bd = (pc300chan->rx_first_bd - 1) &
+                                       (N_DMA_RX_BUF - 1) ;
                if (!(dsr_rx & DSR_BOF)) {
-                       /* update EDA */ 
-                       cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), 
-                                       RX_BD_ADDR(ch, pc300chan->rx_last_bd)); 
+                       /* update EDA */
+                       cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch),
+                                       RX_BD_ADDR(ch, pc300chan->rx_last_bd));
                }
-               if (rx_len != 0) { 
-                       stats->rx_bytes += rx_len; 
-               
-                       if (pc300dev->trace_on) { 
-                               cpc_tty_trace(pc300dev, new->data,rx_len, 'R'); 
-                       } 
+               if (rx_len != 0) {
+                       stats->rx_bytes += rx_len;
+
+                       if (pc300dev->trace_on) {
+                               cpc_tty_trace(pc300dev, new->data, rx_len, 'R');
+                       }
                        new->size = rx_len;
                        new->next = NULL;
                        if (cpc_tty->buf_rx.first == NULL) {
@@ -877,13 +890,13 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
                        schedule_work(&(cpc_tty->tty_rx_work));
                        stats->rx_packets++;
                }
-       } 
-} 
+       }
+}
 
 /*
  * PC300 TTY TX work routine
- * 
- * This routine treats TX interrupt. 
+ *
+ * This routine treats TX interrupt.
  * o if need call line discipline wakeup
  * o call wake_up_interruptible
  */
@@ -891,56 +904,56 @@ static void cpc_tty_tx_work(struct work_struct *work)
 {
        st_cpc_tty_area *cpc_tty =
                container_of(work, st_cpc_tty_area, tty_tx_work);
-       struct tty_struct *tty; 
+       struct tty_struct *tty = cpc_tty->tty;
+
+       CPC_TTY_DBG("%s: cpc_tty_tx_work init\n", cpc_tty->name);
 
-       CPC_TTY_DBG("%s: cpc_tty_tx_work init\n",cpc_tty->name);
-       
-       if ((tty = cpc_tty->tty) == NULL) { 
-               CPC_TTY_DBG("%s: the interface is not opened\n",cpc_tty->name);
-               return; 
+       if (tty == NULL) {
+               CPC_TTY_DBG("%s: the interface is not opened\n", cpc_tty->name);
+               return;
        }
        tty_wakeup(tty);
 }
 
 /*
  * PC300 TTY send to card routine
- * 
- * This routine send data to card. 
+ *
+ * This routine send data to card.
  * o clear descriptors
  * o write data to DMA buffers
  * o start the transmission
  */
-static int cpc_tty_send_to_card(pc300dev_t *dev,void* buf, int len)
+static int cpc_tty_send_to_card(pc300dev_t *dev, void *buf, int len)
 {
-       pc300ch_t *chan = (pc300ch_t *)dev->chan; 
-       pc300_t *card = (pc300_t *)chan->card; 
-       int ch = chan->channel; 
+       pc300ch_t *chan = (pc300ch_t *)dev->chan;
+       pc300_t *card = (pc300_t *)chan->card;
+       int ch = chan->channel;
        struct net_device_stats *stats = &dev->dev->stats;
-       unsigned long flags; 
-       volatile pcsca_bd_t __iomem *ptdescr; 
+       unsigned long flags;
+       volatile pcsca_bd_t __iomem *ptdescr;
        int i, nchar;
        int tosend = len;
        int nbuf = ((len - 1)/BD_DEF_LEN) + 1;
-       unsigned char *pdata=buf;
+       unsigned char *pdata = buf;
 
-       CPC_TTY_DBG("%s:cpc_tty_send_to_cars len=%i", 
-                       (st_cpc_tty_area *)dev->cpc_tty->name,len);     
+       CPC_TTY_DBG("%s:cpc_tty_send_to_cars len=%i",
+                       (st_cpc_tty_area *)dev->cpc_tty->name, len);
 
        if (nbuf >= card->chan[ch].nfree_tx_bd) {
                return 1;
        }
-       
-       /* write buffer to DMA buffers */ 
+
+       /* write buffer to DMA buffers */
        CPC_TTY_DBG("%s: call dma_buf_write\n",
-                       (st_cpc_tty_area *)dev->cpc_tty->name); 
+                       (st_cpc_tty_area *)dev->cpc_tty->name);
        for (i = 0 ; i < nbuf ; i++) {
-               ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + 
+               ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase +
                        TX_BD_ADDR(ch, card->chan[ch].tx_next_bd));
                nchar = (BD_DEF_LEN > tosend) ? tosend : BD_DEF_LEN;
                if (cpc_readb(&ptdescr->status) & DST_OSB) {
-                       memcpy_toio((void __iomem *)(card->hw.rambase + 
-                               cpc_readl(&ptdescr->ptbuf)), 
-                               &pdata[len - tosend], 
+                       memcpy_toio((void __iomem *)(card->hw.rambase +
+                               cpc_readl(&ptdescr->ptbuf)),
+                               &pdata[len - tosend],
                                nchar);
                        card->chan[ch].nfree_tx_bd--;
                        if ((i + 1) == nbuf) {
@@ -952,128 +965,124 @@ static int cpc_tty_send_to_card(pc300dev_t *dev,void* 
buf, int len)
                        cpc_writew(&ptdescr->len, nchar);
                } else {
                        CPC_TTY_DBG("%s: error in dma_buf_write\n",
-                                       (st_cpc_tty_area *)dev->cpc_tty->name); 
+                                       (st_cpc_tty_area *)dev->cpc_tty->name);
                        stats->tx_dropped++;
-                       return 1; 
+                       return 1;
                }
                tosend -= nchar;
-               card->chan[ch].tx_next_bd = 
+               card->chan[ch].tx_next_bd =
                        (card->chan[ch].tx_next_bd + 1) & (N_DMA_TX_BUF - 1);
        }
 
-       if (dev->trace_on) { 
-               cpc_tty_trace(dev, buf, len,'T'); 
+       if (dev->trace_on) {
+               cpc_tty_trace(dev, buf, len, 'T');
        }
 
-       /* start transmission */ 
+       /* start transmission */
        CPC_TTY_DBG("%s: start transmission\n",
-               (st_cpc_tty_area *)dev->cpc_tty->name); 
-       
-       CPC_TTY_LOCK(card, flags); 
-       cpc_writeb(card->hw.scabase + DTX_REG(EDAL, ch), 
-                       TX_BD_ADDR(ch, chan->tx_next_bd)); 
-       cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_ENA); 
-       cpc_writeb(card->hw.scabase + DSR_TX(ch), DSR_DE); 
-
-       if (card->hw.type == PC300_TE) { 
-               cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, 
+               (st_cpc_tty_area *)dev->cpc_tty->name);
+
+       CPC_TTY_LOCK(card, flags);
+       cpc_writeb(card->hw.scabase + DTX_REG(EDAL, ch),
+                       TX_BD_ADDR(ch, chan->tx_next_bd));
+       cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_ENA);
+       cpc_writeb(card->hw.scabase + DSR_TX(ch), DSR_DE);
+
+       if (card->hw.type == PC300_TE) {
+               cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2,
                        cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) |
-                       (CPLD_REG2_FALC_LED1 << (2 * ch))); 
+                       (CPLD_REG2_FALC_LED1 << (2 * ch)));
        }
-       CPC_TTY_UNLOCK(card, flags); 
-       return 0; 
-} 
+       CPC_TTY_UNLOCK(card, flags);
+       return 0;
+}
 
 /*
  *     PC300 TTY trace routine
  *
- *  This routine send trace of connection to application. 
+ *  This routine send trace of connection to application.
  *  o clear descriptors
  *  o write data to DMA buffers
  *  o start the transmission
  */
 
-static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx)
+static void cpc_tty_trace(pc300dev_t *dev, char *buf, int len, char rxtx)
 {
-       struct sk_buff *skb; 
+       struct sk_buff *skb = dev_alloc_skb(10 + len);
 
-       if ((skb = dev_alloc_skb(10 + len)) == NULL) { 
-               /* out of memory */ 
+       if (skb == NULL) {
+               /* out of memory */
                CPC_TTY_DBG("%s: tty_trace - out of memory\n", dev->dev->name);
-               return; 
+               return;
        }
 
-       skb_put (skb, 10 + len); 
-       skb->dev = dev->dev; 
-       skb->protocol = htons(ETH_P_CUST); 
+       skb_put (skb, 10 + len);
+       skb->dev = dev->dev;
+       skb->protocol = htons(ETH_P_CUST);
        skb_reset_mac_header(skb);
-       skb->pkt_type = PACKET_HOST; 
-       skb->len = 10 + len; 
+       skb->pkt_type = PACKET_HOST;
+       skb->len = 10 + len;
 
        skb_copy_to_linear_data(skb, dev->dev->name, 5);
-       skb->data[5] = '['; 
-       skb->data[6] = rxtx; 
-       skb->data[7] = ']'; 
-       skb->data[8] = ':'; 
-       skb->data[9] = ' '; 
+       skb->data[5] = '[';
+       skb->data[6] = rxtx;
+       skb->data[7] = ']';
+       skb->data[8] = ':';
+       skb->data[9] = ' ';
        skb_copy_to_linear_data_offset(skb, 10, buf, len);
-       netif_rx(skb); 
-}      
+       netif_rx(skb);
+}
 
 /*
  *     PC300 TTY unregister service routine
  *
- *     This routine unregister one interface. 
+ *     This routine unregister one interface.
  */
 void cpc_tty_unregister_service(pc300dev_t *pc300dev)
 {
-       st_cpc_tty_area *cpc_tty; 
+       st_cpc_tty_area *cpc_tty = (st_cpc_tty_area *) pc300dev->cpc_tty;
        ulong flags;
        int res;
 
-       if ((cpc_tty= (st_cpc_tty_area *) pc300dev->cpc_tty) == NULL) {
+       if (cpc_tty == NULL) {
                CPC_TTY_DBG("%s: interface is not TTY\n", pc300dev->dev->name);
-               return; 
+               return;
        }
        CPC_TTY_DBG("%s: cpc_tty_unregister_service", cpc_tty->name);
 
-       if (cpc_tty->pc300dev != pc300dev) { 
-               CPC_TTY_DBG("%s: invalid tty ptr=%s\n", 
+       if (cpc_tty->pc300dev != pc300dev) {
+               CPC_TTY_DBG("%s: invalid tty ptr=%s\n",
                pc300dev->dev->name, cpc_tty->name);
-               return; 
+               return;
        }
 
-       if (--cpc_tty_cnt == 0) { 
-               if (serial_drv.refcount) {
-                       CPC_TTY_DBG("%s: unregister is not possible, 
refcount=%d",
-                                                       cpc_tty->name, 
serial_drv.refcount);
+       if (--cpc_tty_cnt == 0) {
+               CPC_TTY_DBG("%s: checking unregister the tty driver...\n",
+                               cpc_tty->name);
+               res = kref_put(&serial_drv.kref, cpc_tty_do_unreg_driver);
+               if (0 == res) {
+                       CPC_TTY_DBG("%s: unregister is not possible\n",
+                                       cpc_tty->name);
                        cpc_tty_cnt++;
                        cpc_tty_unreg_flag = 1;
                        return;
-               } else { 
-                       CPC_TTY_DBG("%s: unregister the tty driver\n", 
cpc_tty->name);
-                       if ((res=tty_unregister_driver(&serial_drv))) { 
-                               CPC_TTY_DBG("%s: ERROR ->unregister the tty 
driver error=%d\n",
-                                                               
cpc_tty->name,res);
-                       }
                }
        }
-       CPC_TTY_LOCK(pc300dev->chan->card,flags);
-       cpc_tty->tty = NULL; 
+       CPC_TTY_LOCK(pc300dev->chan->card, flags);
+       cpc_tty->tty = NULL;
        CPC_TTY_UNLOCK(pc300dev->chan->card, flags);
-       cpc_tty->tty_minor = 0; 
-       cpc_tty->state = CPC_TTY_ST_IDLE; 
-} 
+       cpc_tty->tty_minor = 0;
+       cpc_tty->state = CPC_TTY_ST_IDLE;
+}
 
 /*
  * PC300 TTY trigger poll routine
- * This routine is called by pc300driver to treats Tx interrupt. 
+ * This routine is called by pc300driver to treats Tx interrupt.
  */
 void cpc_tty_trigger_poll(pc300dev_t *pc300dev)
 {
-       st_cpc_tty_area *cpc_tty = (st_cpc_tty_area *)pc300dev->cpc_tty; 
-       if (!cpc_tty) {
+       st_cpc_tty_area *cpc_tty = (st_cpc_tty_area *)pc300dev->cpc_tty;
+       if (!cpc_tty)
                return;
-       }
-       schedule_work(&(cpc_tty->tty_tx_work)); 
-} 
+       schedule_work(&(cpc_tty->tty_tx_work));
+}
-- 
1.7.0.4

_______________________________________________
devel mailing list
[email protected]
http://driverdev.linuxdriverproject.org/mailman/listinfo/devel

Reply via email to