mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Tsozik <tsozik@yahoo.com>
To: Greg Kroah-Hartman <gregkh@suse.de>, Pete Zaitcev <zaitcev@redhat.com>
Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 1/1] mct_u232: added _ioctl and _get_icount functions
Date: Sun, 26 Dec 2010 18:58:46 -0800 (PST)	[thread overview]
Message-ID: <342039.62488.qm@web65711.mail.ac4.yahoo.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 722 bytes --]

Pete, Greg,

Again thank you very much for your valuable feedback. I generated another patch (based on linux-2.6.37-rc7) and ran it against scripts/checkpatch.pl script which didn't produce any errors or warnings:

[vtsozik@SR71 2.6.37-rc7]$ /usr/src/kernels/2.6.37-rc7/scripts/checkpatch.pl mct_u232.c.patch.submit 
total: 0 errors, 0 warnings, 191 lines checked

mct_u232.c.patch.submit has no obvious style problems and is ready for submission.
[vtsozik@SR71 2.6.37-rc7]$

I attached mct_u232.c.patch.submit file to this email, so tabs will not be expanded into spaces. Please let me know if there's anything else I need to correct before it can be rolled out,

Again thank you for your help with this,
 Vadim.


      

[-- Attachment #2: mct_u232.c.patch.submit --]
[-- Type: application/octet-stream, Size: 6790 bytes --]

From: From: Vadim Tsozik <tsozik@yahoo.com>

Added mct_u232_ioctl (implements TIOCMIWAIT command) and mct_u232_get_icount (implements TIOCGICOUNT command) functions. MCT u232 p9 is one of a few usb to serail adapters which converts USB +/-5v voltage levels to COM +/-15 voltages. So it can also power COM interfaced devices. This makes it very usable for legacy COM interfaced data-acquisition hardware. I tested new implementation with AWARE Electronics RM-60 radiation meter, which sends pulse via RNG COM line whenever new particle is registered.

Signed-off-by: Vadim Tsozik <tsozik@yahoo.com>

---

Patch below is based on linux-2.6.37-rc7

--- usb/serial/mct_u232.c.orig	2010-12-26 16:54:16.660294924 -0500
+++ usb/serial/mct_u232.c	2010-12-26 20:45:41.711682127 -0500
@@ -78,6 +78,8 @@
 #include <asm/unaligned.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
+#include <linux/serial.h>
+#include <linux/ioctl.h>
 #include "mct_u232.h"
 
 /*
@@ -104,6 +106,10 @@ static void mct_u232_break_ctl(struct tt
 static int  mct_u232_tiocmget(struct tty_struct *tty, struct file *file);
 static int  mct_u232_tiocmset(struct tty_struct *tty, struct file *file,
 			unsigned int set, unsigned int clear);
+static int  mct_u232_ioctl(struct tty_struct *tty, struct file *file,
+			unsigned int cmd, unsigned long arg);
+static int  mct_u232_get_icount(struct tty_struct *tty,
+			struct serial_icounter_struct *icount);
 static void mct_u232_throttle(struct tty_struct *tty);
 static void mct_u232_unthrottle(struct tty_struct *tty);
 
@@ -150,9 +156,10 @@ static struct usb_serial_driver mct_u232
 	.tiocmset =	     mct_u232_tiocmset,
 	.attach =	     mct_u232_startup,
 	.release =	     mct_u232_release,
+	.ioctl =             mct_u232_ioctl,
+	.get_icount =        mct_u232_get_icount,
 };
 
-
 struct mct_u232_private {
 	spinlock_t lock;
 	unsigned int	     control_state; /* Modem Line Setting (TIOCM) */
@@ -160,6 +167,9 @@ struct mct_u232_private {
 	unsigned char	     last_lsr;      /* Line Status Register */
 	unsigned char	     last_msr;      /* Modem Status Register */
 	unsigned int	     rx_flags;      /* Throttling flags */
+	struct async_icount  icount;
+	wait_queue_head_t    msr_wait;	/* for handling sleeping while waiting
+						for msr change to happen */
 };
 
 #define THROTTLED		0x01
@@ -386,27 +396,41 @@ static int mct_u232_get_modem_stat(struc
 	return rc;
 } /* mct_u232_get_modem_stat */
 
-static void mct_u232_msr_to_state(unsigned int *control_state,
-						unsigned char msr)
+static void mct_u232_msr_to_state(struct mct_u232_private *priv)
 {
+	unsigned char msr = priv->last_msr;
+	unsigned int *control_state = &priv->control_state;
+	struct async_icount *icount = &priv->icount;
+
 	/* Translate Control Line states */
-	if (msr & MCT_U232_MSR_DSR)
+	if (msr & MCT_U232_MSR_DSR) {
 		*control_state |=  TIOCM_DSR;
-	else
+		icount->dsr++;
+	} else {
 		*control_state &= ~TIOCM_DSR;
-	if (msr & MCT_U232_MSR_CTS)
+	}
+	if (msr & MCT_U232_MSR_CTS) {
 		*control_state |=  TIOCM_CTS;
-	else
+		icount->cts++;
+	} else {
 		*control_state &= ~TIOCM_CTS;
-	if (msr & MCT_U232_MSR_RI)
+	}
+	if (msr & MCT_U232_MSR_RI) {
 		*control_state |=  TIOCM_RI;
-	else
+		icount->rng++;
+	} else {
 		*control_state &= ~TIOCM_RI;
-	if (msr & MCT_U232_MSR_CD)
+	}
+	if (msr & MCT_U232_MSR_CD) {
 		*control_state |=  TIOCM_CD;
-	else
+		icount->dcd++;
+	} else {
 		*control_state &= ~TIOCM_CD;
+	}
+
 	dbg("msr_to_state: msr=0x%x ==> state=0x%x", msr, *control_state);
+
+	wake_up_interruptible(&priv->msr_wait);
 } /* mct_u232_msr_to_state */
 
 /*
@@ -422,6 +446,7 @@ static int mct_u232_startup(struct usb_s
 	if (!priv)
 		return -ENOMEM;
 	spin_lock_init(&priv->lock);
+	init_waitqueue_head(&priv->msr_wait);
 	usb_set_serial_port_data(serial->port[0], priv);
 
 	init_waitqueue_head(&serial->port[0]->write_wait);
@@ -498,7 +523,7 @@ static int  mct_u232_open(struct tty_str
 	mct_u232_get_modem_stat(serial, &last_msr);
 	spin_lock_irqsave(&priv->lock, flags);
 	priv->last_msr = last_msr;
-	mct_u232_msr_to_state(&priv->control_state, priv->last_msr);
+	mct_u232_msr_to_state(priv);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	port->read_urb->dev = port->serial->dev;
@@ -619,7 +644,7 @@ static void mct_u232_read_int_callback(s
 	priv->last_msr = data[MCT_U232_MSR_INDEX];
 
 	/* Record Control Line states */
-	mct_u232_msr_to_state(&priv->control_state, priv->last_msr);
+	mct_u232_msr_to_state(priv);
 
 #if 0
 	/* Not yet handled. See belkin_sa.c for further information */
@@ -826,7 +851,6 @@ static void mct_u232_throttle(struct tty
 	}
 }
 
-
 static void mct_u232_unthrottle(struct tty_struct *tty)
 {
 	struct usb_serial_port *port = tty->driver_data;
@@ -847,6 +871,72 @@ static void mct_u232_unthrottle(struct t
 	}
 }
 
+static int  mct_u232_ioctl(struct tty_struct *tty, struct file *file,
+			unsigned int cmd, unsigned long arg)
+{
+	DEFINE_WAIT(wait);
+	struct usb_serial_port *port = tty->driver_data;
+	struct mct_u232_private *mct_u232_port = usb_get_serial_port_data(port);
+	struct async_icount cnow, cprev;
+
+	dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd);
+
+	switch (cmd) {
+
+	case TIOCMIWAIT:
+
+		dbg("%s (%d) TIOCMIWAIT", __func__,  port->number);
+
+		cprev = mct_u232_port->icount;
+		for ( ; ; ) {
+			prepare_to_wait(&mct_u232_port->msr_wait,
+					&wait, TASK_INTERRUPTIBLE);
+			schedule();
+			finish_wait(&mct_u232_port->msr_wait, &wait);
+			/* see if a signal did it */
+			if (signal_pending(current))
+				return -ERESTARTSYS;
+			cnow = mct_u232_port->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;
+		}
+
+	}
+	return -ENOIOCTLCMD;
+}
+
+static int  mct_u232_get_icount(struct tty_struct *tty,
+			struct serial_icounter_struct *icount)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	struct mct_u232_private *mct_u232_port = usb_get_serial_port_data(port);
+	struct async_icount *ic = &mct_u232_port->icount;
+
+	icount->cts = ic->cts;
+	icount->dsr = ic->dsr;
+	icount->rng = ic->rng;
+	icount->dcd = ic->dcd;
+	icount->rx = ic->rx;
+	icount->tx = ic->tx;
+	icount->frame = ic->frame;
+	icount->overrun = ic->overrun;
+	icount->parity = ic->parity;
+	icount->brk = ic->brk;
+	icount->buf_overrun = ic->buf_overrun;
+
+	dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d",
+		__func__,  port->number, icount->rx, icount->tx);
+	return 0;
+}
+
 static int __init mct_u232_init(void)
 {
 	int retval;

             reply	other threads:[~2010-12-27  3:04 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-12-27  2:58 Tsozik [this message]
2010-12-27  3:57 ` Pete Zaitcev
2010-12-27  6:34 Tsozik
2010-12-27 17:08 ` Pete Zaitcev

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=342039.62488.qm@web65711.mail.ac4.yahoo.com \
    --to=tsozik@yahoo.com \
    --cc=gregkh@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=zaitcev@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®