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;
next 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®