From 468c740ee5372b74e9d9bd4d7ec2d81d44e67f2d Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 21 Mar 2013 12:37:12 +0100 Subject: USB: mct_u232: switch to generic get_icount implementation Switch to the generic get_icount implementation. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/mct_u232.c | 40 ++++------------------------------------ 1 file changed, 4 insertions(+), 36 deletions(-) (limited to 'drivers/usb/serial/mct_u232.c') diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 06d5a60be2c4..6f4303cef0d8 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -59,8 +59,6 @@ static int mct_u232_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); static int mct_u232_ioctl(struct tty_struct *tty, 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); @@ -99,7 +97,7 @@ static struct usb_serial_driver mct_u232_device = { .port_probe = mct_u232_port_probe, .port_remove = mct_u232_port_remove, .ioctl = mct_u232_ioctl, - .get_icount = mct_u232_get_icount, + .get_icount = usb_serial_generic_get_icount, }; static struct usb_serial_driver * const serial_drivers[] = { @@ -113,7 +111,6 @@ 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; }; #define THROTTLED 0x01 @@ -570,7 +567,7 @@ static void mct_u232_read_int_callback(struct urb *urb) /* Record Control Line states */ mct_u232_msr_to_state(port, &priv->control_state, priv->last_msr); - mct_u232_msr_to_icount(&priv->icount, priv->last_msr); + mct_u232_msr_to_icount(&port->icount, priv->last_msr); #if 0 /* Not yet handled. See belkin_sa.c for further information */ @@ -804,7 +801,7 @@ static int mct_u232_ioctl(struct tty_struct *tty, dev_dbg(&port->dev, "%s TIOCMIWAIT", __func__); spin_lock_irqsave(&mct_u232_port->lock, flags); - cprev = mct_u232_port->icount; + cprev = port->icount; spin_unlock_irqrestore(&mct_u232_port->lock, flags); for ( ; ; ) { prepare_to_wait(&port->delta_msr_wait, @@ -819,7 +816,7 @@ static int mct_u232_ioctl(struct tty_struct *tty, return -EIO; spin_lock_irqsave(&mct_u232_port->lock, flags); - cnow = mct_u232_port->icount; + cnow = port->icount; spin_unlock_irqrestore(&mct_u232_port->lock, flags); if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) @@ -837,35 +834,6 @@ static int mct_u232_ioctl(struct tty_struct *tty, 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; - unsigned long flags; - - spin_lock_irqsave(&mct_u232_port->lock, flags); - - 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; - - spin_unlock_irqrestore(&mct_u232_port->lock, flags); - - dev_dbg(&port->dev, "%s TIOCGICOUNT RX=%d, TX=%d\n", - __func__, icount->rx, icount->tx); - return 0; -} - module_usb_serial_driver(serial_drivers, id_table); MODULE_AUTHOR(DRIVER_AUTHOR); -- cgit v1.2.3 From 128434ab5607c6bccf385765e94382cedd3d06fa Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 21 Mar 2013 12:37:13 +0100 Subject: USB: mct_u232: switch to generic TIOCMIWAIT implementation Switch to the generic TIOCMIWAIT implementation. This also fixes the issue with processes waiting for modem-status-changes not being woken up at disconnect. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/mct_u232.c | 58 ++----------------------------------------- 1 file changed, 2 insertions(+), 56 deletions(-) (limited to 'drivers/usb/serial/mct_u232.c') diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 6f4303cef0d8..3353c9ed7721 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -35,7 +35,6 @@ #include #include #include -#include #include "mct_u232.h" #define DRIVER_AUTHOR "Wolfgang Grandegger " @@ -57,8 +56,6 @@ static void mct_u232_break_ctl(struct tty_struct *tty, int break_state); static int mct_u232_tiocmget(struct tty_struct *tty); static int mct_u232_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); -static int mct_u232_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg); static void mct_u232_throttle(struct tty_struct *tty); static void mct_u232_unthrottle(struct tty_struct *tty); @@ -93,10 +90,10 @@ static struct usb_serial_driver mct_u232_device = { .break_ctl = mct_u232_break_ctl, .tiocmget = mct_u232_tiocmget, .tiocmset = mct_u232_tiocmset, + .tiocmiwait = usb_serial_generic_tiocmiwait, .attach = mct_u232_startup, .port_probe = mct_u232_port_probe, .port_remove = mct_u232_port_remove, - .ioctl = mct_u232_ioctl, .get_icount = usb_serial_generic_get_icount, }; @@ -595,7 +592,7 @@ static void mct_u232_read_int_callback(struct urb *urb) tty_kref_put(tty); } #endif - wake_up_interruptible(&port->delta_msr_wait); + wake_up_interruptible(&port->port.delta_msr_wait); spin_unlock_irqrestore(&priv->lock, flags); exit: retval = usb_submit_urb(urb, GFP_ATOMIC); @@ -783,57 +780,6 @@ static void mct_u232_unthrottle(struct tty_struct *tty) } } -static int mct_u232_ioctl(struct tty_struct *tty, - 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; - unsigned long flags; - - dev_dbg(&port->dev, "%s - cmd = 0x%x\n", __func__, cmd); - - switch (cmd) { - - case TIOCMIWAIT: - - dev_dbg(&port->dev, "%s TIOCMIWAIT", __func__); - - spin_lock_irqsave(&mct_u232_port->lock, flags); - cprev = port->icount; - spin_unlock_irqrestore(&mct_u232_port->lock, flags); - for ( ; ; ) { - prepare_to_wait(&port->delta_msr_wait, - &wait, TASK_INTERRUPTIBLE); - schedule(); - finish_wait(&port->delta_msr_wait, &wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - - if (port->serial->disconnected) - return -EIO; - - spin_lock_irqsave(&mct_u232_port->lock, flags); - cnow = port->icount; - spin_unlock_irqrestore(&mct_u232_port->lock, flags); - 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; -} - module_usb_serial_driver(serial_drivers, id_table); MODULE_AUTHOR(DRIVER_AUTHOR); -- cgit v1.2.3 From 35807187e4b35200b12edad319a36ee7a0167ba7 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 16 Apr 2013 18:01:27 +0200 Subject: USB: mct_u232: clean up read implementation The device uses the second interrupt-in endpoint of the interface for reading. Stop abusing the port read urb and store a pointer to the second interrupt-in urb as port-private data instead. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/mct_u232.c | 37 +++++++++++-------------------------- 1 file changed, 11 insertions(+), 26 deletions(-) (limited to 'drivers/usb/serial/mct_u232.c') diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 3353c9ed7721..6a15adf53360 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -43,7 +43,6 @@ /* * Function prototypes */ -static int mct_u232_startup(struct usb_serial *serial); static int mct_u232_port_probe(struct usb_serial_port *port); static int mct_u232_port_remove(struct usb_serial_port *remove); static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port); @@ -91,7 +90,6 @@ static struct usb_serial_driver mct_u232_device = { .tiocmget = mct_u232_tiocmget, .tiocmset = mct_u232_tiocmset, .tiocmiwait = usb_serial_generic_tiocmiwait, - .attach = mct_u232_startup, .port_probe = mct_u232_port_probe, .port_remove = mct_u232_port_remove, .get_icount = usb_serial_generic_get_icount, @@ -102,6 +100,7 @@ static struct usb_serial_driver * const serial_drivers[] = { }; struct mct_u232_private { + struct urb *read_urb; spinlock_t lock; unsigned int control_state; /* Modem Line Setting (TIOCM) */ unsigned char last_lcr; /* Line Control Register */ @@ -376,22 +375,6 @@ static void mct_u232_msr_to_state(struct usb_serial_port *port, * Driver's tty interface functions */ -static int mct_u232_startup(struct usb_serial *serial) -{ - struct usb_serial_port *port, *rport; - - /* Puh, that's dirty */ - port = serial->port[0]; - rport = serial->port[1]; - /* No unlinking, it wasn't submitted yet. */ - usb_free_urb(port->read_urb); - port->read_urb = rport->interrupt_in_urb; - rport->interrupt_in_urb = NULL; - port->read_urb->context = port; - - return 0; -} /* mct_u232_startup */ - static int mct_u232_port_probe(struct usb_serial_port *port) { struct mct_u232_private *priv; @@ -400,6 +383,10 @@ static int mct_u232_port_probe(struct usb_serial_port *port) if (!priv) return -ENOMEM; + /* Use second interrupt-in endpoint for reading. */ + priv->read_urb = port->serial->port[1]->interrupt_in_urb; + priv->read_urb->context = port; + spin_lock_init(&priv->lock); usb_set_serial_port_data(port, priv); @@ -463,17 +450,17 @@ static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port) mct_u232_msr_to_state(port, &priv->control_state, priv->last_msr); spin_unlock_irqrestore(&priv->lock, flags); - retval = usb_submit_urb(port->read_urb, GFP_KERNEL); + retval = usb_submit_urb(priv->read_urb, GFP_KERNEL); if (retval) { dev_err(&port->dev, - "usb_submit_urb(read bulk) failed pipe 0x%x err %d\n", + "usb_submit_urb(read) failed pipe 0x%x err %d\n", port->read_urb->pipe, retval); goto error; } retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); if (retval) { - usb_kill_urb(port->read_urb); + usb_kill_urb(priv->read_urb); dev_err(&port->dev, "usb_submit_urb(read int) failed pipe 0x%x err %d", port->interrupt_in_urb->pipe, retval); @@ -503,11 +490,9 @@ static void mct_u232_dtr_rts(struct usb_serial_port *port, int on) static void mct_u232_close(struct usb_serial_port *port) { - /* - * Must kill the read urb as it is actually an interrupt urb, which - * generic close thus fails to kill. - */ - usb_kill_urb(port->read_urb); + struct mct_u232_private *priv = usb_get_serial_port_data(port); + + usb_kill_urb(priv->read_urb); usb_kill_urb(port->interrupt_in_urb); usb_serial_generic_close(port); -- cgit v1.2.3