Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0587102c authored by Alan Cox's avatar Alan Cox Committed by Greg Kroah-Hartman
Browse files

tty: icount changeover for other main devices



Again basically cut and paste

Convert the main driver set to use the hooks for GICOUNT

Signed-off-by: default avatarAlan Cox <alan@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 0bca1b91
Loading
Loading
Loading
Loading
+1 −11
Original line number Diff line number Diff line
@@ -395,7 +395,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
{
	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
	    (cmd != TIOCMIWAIT)) {
		if (tty->flags & (1 << TTY_IO_ERROR))
		    return -EIO;
	}
@@ -433,16 +433,6 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
		case TIOCMIWAIT:
			printk(KERN_INFO "rs_ioctl: TIOCMIWAIT: called\n");
			return 0;
		/*
		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
		 * Return: write counters to the user passed counter struct
		 * NB: both 1->0 and 0->1 transitions are counted except for
		 *     RI where only 0->1 is counted.
		 */
		case TIOCGICOUNT:
			printk(KERN_INFO "rs_ioctl: TIOCGICOUNT called\n");
			return 0;

		case TIOCSERGWILD:
		case TIOCSERSWILD:
			/* "setserial -W" is called in Debian boot */
+31 −25
Original line number Diff line number Diff line
@@ -1263,6 +1263,36 @@ static int rs_break(struct tty_struct *tty, int break_state)
	return 0;
}

/*
 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
 * Return: write counters to the user passed counter struct
 * NB: both 1->0 and 0->1 transitions are counted except for
 *     RI where only 0->1 is counted.
 */
static int rs_get_icount(struct tty_struct *tty,
				struct serial_icounter_struct *icount)
{
	struct async_struct *info = tty->driver_data;
	struct async_icount cnow;
	unsigned long flags;

	local_irq_save(flags);
	cnow = info->state->icount;
	local_irq_restore(flags);
	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 0;
}

static int rs_ioctl(struct tty_struct *tty, struct file * file,
		    unsigned int cmd, unsigned long arg)
@@ -1332,31 +1362,6 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
			}
			/* NOTREACHED */

		/* 
		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
		 * Return: write counters to the user passed counter struct
		 * NB: both 1->0 and 0->1 transitions are counted except for
		 *     RI where only 0->1 is counted.
		 */
		case TIOCGICOUNT:
			local_irq_save(flags);
			cnow = info->state->icount;
			local_irq_restore(flags);
			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(argp, &icount, sizeof(icount)))
				return -EFAULT;
			return 0;
		case TIOCSERGWILD:
		case TIOCSERSWILD:
			/* "setserial -W" is called in Debian boot */
@@ -1958,6 +1963,7 @@ static const struct tty_operations serial_ops = {
	.wait_until_sent = rs_wait_until_sent,
	.tiocmget = rs_tiocmget,
	.tiocmset = rs_tiocmset,
	.get_icount = rs_get_icount,
	.proc_fops = &rs_proc_fops,
};

+26 −23
Original line number Diff line number Diff line
@@ -2790,29 +2790,6 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
		 * NB: both 1->0 and 0->1 transitions are counted except for
		 *     RI where only 0->1 is counted.
		 */
	case TIOCGICOUNT: {
		struct serial_icounter_struct sic = { };

		spin_lock_irqsave(&info->card->card_lock, flags);
		cnow = info->icount;
		spin_unlock_irqrestore(&info->card->card_lock, flags);

		sic.cts = cnow.cts;
		sic.dsr = cnow.dsr;
		sic.rng = cnow.rng;
		sic.dcd = cnow.dcd;
		sic.rx = cnow.rx;
		sic.tx = cnow.tx;
		sic.frame = cnow.frame;
		sic.overrun = cnow.overrun;
		sic.parity = cnow.parity;
		sic.brk = cnow.brk;
		sic.buf_overrun = cnow.buf_overrun;

		if (copy_to_user(argp, &sic, sizeof(sic)))
			ret_val = -EFAULT;
		break;
	}
	default:
		ret_val = -ENOIOCTLCMD;
	}
@@ -2823,6 +2800,31 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
	return ret_val;
}				/* cy_ioctl */

static int cy_get_icount(struct tty_struct *tty,
				struct serial_icounter_struct *sic)
{
	struct cyclades_port *info = tty->driver_data;
	struct cyclades_icount cnow;	/* Used to snapshot */
	unsigned long flags;

	spin_lock_irqsave(&info->card->card_lock, flags);
	cnow = info->icount;
	spin_unlock_irqrestore(&info->card->card_lock, flags);

	sic->cts = cnow.cts;
	sic->dsr = cnow.dsr;
	sic->rng = cnow.rng;
	sic->dcd = cnow.dcd;
	sic->rx = cnow.rx;
	sic->tx = cnow.tx;
	sic->frame = cnow.frame;
	sic->overrun = cnow.overrun;
	sic->parity = cnow.parity;
	sic->brk = cnow.brk;
	sic->buf_overrun = cnow.buf_overrun;
	return 0;
}

/*
 * This routine allows the tty driver to be notified when
 * device's termios settings have changed.  Note that a
@@ -4084,6 +4086,7 @@ static const struct tty_operations cy_ops = {
	.wait_until_sent = cy_wait_until_sent,
	.tiocmget = cy_tiocmget,
	.tiocmset = cy_tiocmset,
	.get_icount = cy_get_icount,
	.proc_fops = &cyclades_proc_fops,
};

+43 −29
Original line number Diff line number Diff line
@@ -183,6 +183,8 @@ static void ip2_hangup(PTTY);
static int  ip2_tiocmget(struct tty_struct *tty, struct file *file);
static int  ip2_tiocmset(struct tty_struct *tty, struct file *file,
			 unsigned int set, unsigned int clear);
static int ip2_get_icount(struct tty_struct *tty,
		struct serial_icounter_struct *icount);

static void set_irq(int, int);
static void ip2_interrupt_bh(struct work_struct *work);
@@ -454,6 +456,7 @@ static const struct tty_operations ip2_ops = {
	.hangup          = ip2_hangup,
	.tiocmget	 = ip2_tiocmget,
	.tiocmset	 = ip2_tiocmset,
	.get_icount	 = ip2_get_icount,
	.proc_fops	 = &ip2_proc_fops,
};

@@ -2128,7 +2131,6 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
	i2ChanStrPtr pCh = DevTable[tty->index];
	i2eBordStrPtr pB;
	struct async_icount cprev, cnow;	/* kernel counter temps */
	struct serial_icounter_struct __user *p_cuser;
	int rc = 0;
	unsigned long flags;
	void __user *argp = (void __user *)arg;
@@ -2296,34 +2298,6 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
		return rc;
		break;

	/*
	 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
	 * Return: write counters to the user passed counter struct
	 * NB: both 1->0 and 0->1 transitions are counted except for RI where
	 * only 0->1 is counted. The controller is quite capable of counting
	 * both, but this done to preserve compatibility with the standard
	 * serial driver.
	 */
	case TIOCGICOUNT:
		ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc );

		write_lock_irqsave(&pB->read_fifo_spinlock, flags);
		cnow = pCh->icount;
		write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
		p_cuser = argp;
		rc = put_user(cnow.cts, &p_cuser->cts);
		rc = put_user(cnow.dsr, &p_cuser->dsr);
		rc = put_user(cnow.rng, &p_cuser->rng);
		rc = put_user(cnow.dcd, &p_cuser->dcd);
		rc = put_user(cnow.rx, &p_cuser->rx);
		rc = put_user(cnow.tx, &p_cuser->tx);
		rc = put_user(cnow.frame, &p_cuser->frame);
		rc = put_user(cnow.overrun, &p_cuser->overrun);
		rc = put_user(cnow.parity, &p_cuser->parity);
		rc = put_user(cnow.brk, &p_cuser->brk);
		rc = put_user(cnow.buf_overrun, &p_cuser->buf_overrun);
		break;

	/*
	 * The rest are not supported by this driver. By returning -ENOIOCTLCMD they
	 * will be passed to the line discipline for it to handle.
@@ -2348,6 +2322,46 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
	return rc;
}

static int ip2_get_icount(struct tty_struct *tty,
		struct serial_icounter_struct *icount)
{
	i2ChanStrPtr pCh = DevTable[tty->index];
	i2eBordStrPtr pB;
	struct async_icount cnow;	/* kernel counter temp */
	unsigned long flags;

	if ( pCh == NULL )
		return -ENODEV;

	pB = pCh->pMyBord;

	/*
	 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
	 * Return: write counters to the user passed counter struct
	 * NB: both 1->0 and 0->1 transitions are counted except for RI where
	 * only 0->1 is counted. The controller is quite capable of counting
	 * both, but this done to preserve compatibility with the standard
	 * serial driver.
	 */

	write_lock_irqsave(&pB->read_fifo_spinlock, flags);
	cnow = pCh->icount;
	write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);

	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 0;
}

/******************************************************************************/
/* Function:   GetSerialInfo()                                                */
/* Parameters: Pointer to channel structure                                   */
+35 −27
Original line number Diff line number Diff line
@@ -1700,7 +1700,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
		return 0;
	}

	if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT && cmd != TIOCGICOUNT &&
	if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT &&
			test_bit(TTY_IO_ERROR, &tty->flags))
		return -EIO;

@@ -1730,32 +1730,6 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,

		return wait_event_interruptible(info->port.delta_msr_wait,
				mxser_cflags_changed(info, arg, &cnow));
	/*
	 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
	 * Return: write counters to the user passed counter struct
	 * NB: both 1->0 and 0->1 transitions are counted except for
	 *     RI where only 0->1 is counted.
	 */
	case TIOCGICOUNT: {
		struct serial_icounter_struct icnt = { 0 };
		spin_lock_irqsave(&info->slock, flags);
		cnow = info->icount;
		spin_unlock_irqrestore(&info->slock, flags);

		icnt.frame = cnow.frame;
		icnt.brk = cnow.brk;
		icnt.overrun = cnow.overrun;
		icnt.buf_overrun = cnow.buf_overrun;
		icnt.parity = cnow.parity;
		icnt.rx = cnow.rx;
		icnt.tx = cnow.tx;
		icnt.cts = cnow.cts;
		icnt.dsr = cnow.dsr;
		icnt.rng = cnow.rng;
		icnt.dcd = cnow.dcd;

		return copy_to_user(argp, &icnt, sizeof(icnt)) ? -EFAULT : 0;
	}
	case MOXA_HighSpeedOn:
		return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp);
	case MOXA_SDS_RSTICOUNTER:
@@ -1828,6 +1802,39 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
	return 0;
}

	/*
	 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
	 * Return: write counters to the user passed counter struct
	 * NB: both 1->0 and 0->1 transitions are counted except for
	 *     RI where only 0->1 is counted.
	 */

static int mxser_get_icount(struct tty_struct *tty,
		struct serial_icounter_struct *icount)

{
	struct mxser_port *info = tty->driver_data;
	struct async_icount cnow;
	unsigned long flags;

	spin_lock_irqsave(&info->slock, flags);
	cnow = info->icount;
	spin_unlock_irqrestore(&info->slock, flags);

	icount->frame = cnow.frame;
	icount->brk = cnow.brk;
	icount->overrun = cnow.overrun;
	icount->buf_overrun = cnow.buf_overrun;
	icount->parity = cnow.parity;
	icount->rx = cnow.rx;
	icount->tx = cnow.tx;
	icount->cts = cnow.cts;
	icount->dsr = cnow.dsr;
	icount->rng = cnow.rng;
	icount->dcd = cnow.dcd;
	return 0;
}

static void mxser_stoprx(struct tty_struct *tty)
{
	struct mxser_port *info = tty->driver_data;
@@ -2326,6 +2333,7 @@ static const struct tty_operations mxser_ops = {
	.wait_until_sent = mxser_wait_until_sent,
	.tiocmget = mxser_tiocmget,
	.tiocmset = mxser_tiocmset,
	.get_icount = mxser_get_icount,
};

struct tty_port_operations mxser_port_ops = {
Loading