lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Sun, 29 Jul 2012 16:40:48 +0800
From:	Baodong Chen <chenbdchenbd@...il.com>
To:	gregkh@...uxfoundation.org, jslaby@...e.cz, davem@...emloft.net
Cc:	devel@...verdev.osuosl.org, linux-kernel@...r.kernel.org,
	Baodong Chen <chenbdchenbd@...il.com>
Subject: [PATCH] staging:net:fixed to fit tty_driver's kref field

Fixed code to fix tty_driver's kref field
checkpatch.pl clean up
Signed-off-by: Baodong Chen <chenbdchenbd@...il.com>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ