[RFC 5/13] Char: nozomi, ioctls cleanup

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



nozomi, ioctls cleanup

- init tty_wait
- don't forget to wake up tiocmiwait waiters
- convert the whole tiocmiwait into wait_event_interruptible
- don't check for cmd == TIOCGICOUNT in ntty_ioctl_tiocgicount, as it's
  expected to be it when we call the function, also pass internal
  structures (port, argp) directly instead of ioctl params
- remove TIOCMGET, TIOCMSET, TIOCMBIC, TIOCMBIS as it is never invoked by
  tty layer this way, add ntty_tiocmget into tty ops instead

Signed-off-by: Jiri Slaby <[email protected]>

---
commit 2470e477561f2577137d557aa4dcf92b0229a745
tree 3486f8adf936d56143d46b5b9e6ad7f55c7a88db
parent 3afb47133874a0979f57928d7450612fa982a6c5
author Jiri Slaby <[email protected]> Mon, 29 Oct 2007 12:28:57 +0100
committer Jiri Slaby <[email protected]> Fri, 09 Nov 2007 23:12:06 +0100

 drivers/char/nozomi.c |  153 ++++++++++++++++---------------------------------
 1 files changed, 50 insertions(+), 103 deletions(-)

diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c
index d19b5c5..3f4ae3d 100644
--- a/drivers/char/nozomi.c
+++ b/drivers/char/nozomi.c
@@ -1199,6 +1199,9 @@ static int receive_flow_control(struct nozomi *dc, struct irq *m)
 		dc->port[port].tty_icount.rng++;
 	if (old_ctrl.DCD != ctrl_dl.DCD)
 		dc->port[port].tty_icount.dcd++;
+
+	wake_up_interruptible(&dc->port[port].tty_wait);
+
 	DBG1("port: %d DCD(%d), CTS(%d), RI(%d), DSR(%d)",
 	   port,
 	   dc->port[port].tty_icount.dcd, dc->port[port].tty_icount.cts,
@@ -1494,6 +1497,7 @@ static void nozomi_get_card_type(struct nozomi *dc)
 static void nozomi_setup_private_data(struct nozomi *dc)
 {
 	void __iomem *offset = dc->base_addr + dc->card_type / 2;
+	unsigned int i;
 
 	dc->reg_fcr = (void __iomem *)(offset + R_FCR);
 	dc->reg_iir = (void __iomem *)(offset + R_IIR);
@@ -1505,6 +1509,9 @@ static void nozomi_setup_private_data(struct nozomi *dc)
 	dc->port[PORT_DIAG].token_dl = DIAG_DL;
 	dc->port[PORT_APP1].token_dl = APP1_DL;
 	dc->port[PORT_APP2].token_dl = APP2_DL;
+
+	for (i = 0; i < MAX_PORT; i++)
+		init_waitqueue_head(&dc->port[i].tty_wait);
 }
 
 static ssize_t card_type_show(struct device *dev, struct device_attribute *attr,
@@ -1965,12 +1972,12 @@ static int ntty_tiocmget(struct tty_struct *tty, struct file *file)
 	struct ctrl_dl *ctrl_dl = &port->ctrl_dl;
 	struct ctrl_ul *ctrl_ul = &port->ctrl_ul;
 
-	return 0 | (ctrl_ul->RTS ? TIOCM_RTS : 0)
-	    | (ctrl_ul->DTR ? TIOCM_DTR : 0)
-	    | (ctrl_dl->DCD ? TIOCM_CAR : 0)
-	    | (ctrl_dl->RI ? TIOCM_RNG : 0)
-	    | (ctrl_dl->DSR ? TIOCM_DSR : 0)
-	    | (ctrl_dl->CTS ? TIOCM_CTS : 0);
+	return	(ctrl_ul->RTS ? TIOCM_RTS : 0) |
+		(ctrl_ul->DTR ? TIOCM_DTR : 0) |
+		(ctrl_dl->DCD ? TIOCM_CAR : 0) |
+		(ctrl_dl->RI  ? TIOCM_RNG : 0) |
+		(ctrl_dl->DSR ? TIOCM_DSR : 0) |
+		(ctrl_dl->CTS ? TIOCM_CTS : 0);
 }
 
 /* Sets io controls parameters */
@@ -1990,121 +1997,60 @@ static int ntty_tiocmset(struct tty_struct *tty, struct file *file,
 	return 0;
 }
 
-static int ntty_ioctl_tiocmiwait(struct tty_struct *tty, struct file *file,
-				 unsigned int cmd, unsigned long arg)
+static int ntty_cflags_changed(struct port *port, unsigned long flags,
+		struct async_icount *cprev)
 {
-	struct port *port = (struct port *)tty->driver_data;
+	struct async_icount cnow = port->tty_icount;
+	int ret;
 
-	if (cmd == TIOCMIWAIT) {
-		DECLARE_WAITQUEUE(wait, current);
-		struct async_icount cnow;
-		struct async_icount cprev;
-
-		cprev = port->tty_icount;
-		while (1) {
-			add_wait_queue(&port->tty_wait, &wait);
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule();
-			remove_wait_queue(&port->tty_wait, &wait);
-
-			/* see if a signal woke us up */
-			if (signal_pending(current))
-				return -ERESTARTSYS;
-
-			cnow = port->tty_icount;
-			if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
-			    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
-				return -EIO;	/* no change => error */
-			if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
-			    ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
-			    ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
-			    ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)))
-				return 0;
-
-			cprev = cnow;
-		}
+	ret =	((flags & TIOCM_RNG) && (cnow.rng != cprev->rng)) ||
+		((flags & TIOCM_DSR) && (cnow.dsr != cprev->dsr)) ||
+		((flags & TIOCM_CD)  && (cnow.dcd != cprev->dcd)) ||
+		((flags & TIOCM_CTS) && (cnow.cts != cprev->cts));
 
-	}
-	return -ENOIOCTLCMD;
+	*cprev = cnow;
+
+	return ret;
 }
 
-static int ntty_ioctl_tiocgicount(struct tty_struct *tty, struct file *file,
-				  unsigned int cmd, void __user *arg)
+static int ntty_ioctl_tiocgicount(struct port *port, void __user *argp)
 {
-	struct port *port = (struct port *)tty->driver_data;
-
-	if (cmd == TIOCGICOUNT) {
-		struct async_icount cnow = port->tty_icount;
-		struct serial_icounter_struct icount;
-
-		icount.cts = cnow.cts;
-		icount.dsr = cnow.dsr;
-		icount.rng = cnow.rng;
-		icount.dcd = cnow.dcd;
-		icount.rx = cnow.rx;
-		icount.tx = cnow.tx;
-		icount.frame = cnow.frame;
-		icount.overrun = cnow.overrun;
-		icount.parity = cnow.parity;
-		icount.brk = cnow.brk;
-		icount.buf_overrun = cnow.buf_overrun;
-
-		if (copy_to_user(arg, &icount, sizeof(icount)))
-			return -EFAULT;
-		return 0;
-	}
-	return -ENOIOCTLCMD;
+	struct async_icount cnow = port->tty_icount;
+	struct serial_icounter_struct icount;
+
+	icount.cts = cnow.cts;
+	icount.dsr = cnow.dsr;
+	icount.rng = cnow.rng;
+	icount.dcd = cnow.dcd;
+	icount.rx = cnow.rx;
+	icount.tx = cnow.tx;
+	icount.frame = cnow.frame;
+	icount.overrun = cnow.overrun;
+	icount.parity = cnow.parity;
+	icount.brk = cnow.brk;
+	icount.buf_overrun = cnow.buf_overrun;
+
+	return copy_to_user(argp, &icount, sizeof(icount));
 }
 
 static int ntty_ioctl(struct tty_struct *tty, struct file *file,
 		      unsigned int cmd, unsigned long arg)
 {
-	struct nozomi *dc = get_dc_by_tty(tty);
-	unsigned long flags;
-	int mask;
+	struct port *port = tty->driver_data;
+	void __user *argp = (void __user *)arg;
 	int rval = -ENOIOCTLCMD;
 
 	DBG1("******** IOCTL, cmd: %d", cmd);
 
 	switch (cmd) {
-	case TIOCMIWAIT:
-		rval = ntty_ioctl_tiocmiwait(tty, file, cmd, arg);
-		break;
-	case TIOCGICOUNT:
-		rval =
-		    ntty_ioctl_tiocgicount(tty, file, cmd, (void __user *)arg);
-		break;
-	case TIOCMGET:
-		spin_lock_irqsave(&dc->spin_mutex, flags);
-		rval = ntty_tiocmget(tty, file);
-		spin_unlock_irqrestore(&dc->spin_mutex, flags);
-		break;
-	case TIOCMSET:
-		rval = ntty_tiocmset(tty, file, arg, ~arg);
-		break;
-	case TIOCMBIC:
-		if (get_user(mask, (unsigned long __user *)arg))
-			return -EFAULT;
+	case TIOCMIWAIT: {
+		struct async_icount cprev = port->tty_icount;
 
-		spin_lock_irqsave(&dc->spin_mutex, flags);
-		if (mask & TIOCM_RTS)
-			set_rts(tty->index, 0);
-		if (mask & TIOCM_DTR)
-			set_dtr(tty->index, 0);
-		spin_unlock_irqrestore(&dc->spin_mutex, flags);
-		rval = 0;
+		rval = wait_event_interruptible(port->tty_wait,
+				ntty_cflags_changed(port, arg, &cprev));
 		break;
-	case TIOCMBIS:
-		if (get_user(mask, (unsigned long __user *)arg))
-			return -EFAULT;
-
-		spin_lock_irqsave(&dc->spin_mutex, flags);
-		if (mask & TIOCM_RTS)
-			set_rts(tty->index, 1);
-		if (mask & TIOCM_DTR)
-			set_dtr(tty->index, 1);
-		spin_unlock_irqrestore(&dc->spin_mutex, flags);
-		rval = 0;
+	} case TIOCGICOUNT:
+		rval = ntty_ioctl_tiocgicount(port, argp);
 		break;
 	default:
 		DBG1("ERR: 0x%08X, %d", cmd, cmd);
@@ -2186,6 +2132,7 @@ static struct tty_operations tty_ops = {
 	.throttle = ntty_throttle,
 	.chars_in_buffer = ntty_chars_in_buffer,
 	.put_char = ntty_put_char,
+	.tiocmget = ntty_tiocmget,
 	.tiocmset = ntty_tiocmset,
 };
 
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux