Loading drivers/usb/serial/oti6858.c +70 −66 Original line number Diff line number Diff line Loading @@ -25,7 +25,8 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License. * * See Documentation/usb/usb-serial.txt for more information on using this driver * See Documentation/usb/usb-serial.txt for more information on using this * driver * * TODO: * - implement correct flushing for ioctls and oti6858_close() Loading @@ -49,7 +50,7 @@ #include <linux/spinlock.h> #include <linux/usb.h> #include <linux/usb/serial.h> #include <asm/uaccess.h> #include <linux/uaccess.h> #include "oti6858.h" #define OTI6858_DESCRIPTION \ Loading Loading @@ -229,7 +230,8 @@ struct oti6858_private { static void setup_line(struct work_struct *work) { struct oti6858_private *priv = container_of(work, struct oti6858_private, delayed_setup_work.work); struct oti6858_private *priv = container_of(work, struct oti6858_private, delayed_setup_work.work); struct usb_serial_port *port = priv->port; struct oti6858_control_pkt *new_setup; unsigned long flags; Loading @@ -237,10 +239,12 @@ static void setup_line(struct work_struct *work) dbg("%s(port = %d)", __func__, port->number); if ((new_setup = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL)) == NULL) { new_setup = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL); if (new_setup == NULL) { dev_err(&port->dev, "%s(): out of memory!\n", __func__); /* we will try again */ schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2)); schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2)); return; } Loading @@ -256,7 +260,8 @@ static void setup_line(struct work_struct *work) dev_err(&port->dev, "%s(): error reading status\n", __func__); kfree(new_setup); /* we will try again */ schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2)); schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2)); return; } Loading Loading @@ -297,7 +302,8 @@ static void setup_line(struct work_struct *work) void send_data(struct work_struct *work) { struct oti6858_private *priv = container_of(work, struct oti6858_private, delayed_write_work.work); struct oti6858_private *priv = container_of(work, struct oti6858_private, delayed_write_work.work); struct usb_serial_port *port = priv->port; int count = 0, result; unsigned long flags; Loading @@ -308,7 +314,8 @@ void send_data(struct work_struct *work) spin_lock_irqsave(&priv->lock, flags); if (priv->flags.write_urb_in_use) { spin_unlock_irqrestore(&priv->lock, flags); schedule_delayed_work(&priv->delayed_write_work, msecs_to_jiffies(2)); schedule_delayed_work(&priv->delayed_write_work, msecs_to_jiffies(2)); return; } priv->flags.write_urb_in_use = 1; Loading Loading @@ -375,8 +382,8 @@ static int oti6858_startup(struct usb_serial *serial) spin_lock_init(&priv->lock); init_waitqueue_head(&priv->intr_wait); // INIT_WORK(&priv->setup_work, setup_line, serial->port[i]); // INIT_WORK(&priv->write_work, send_data, serial->port[i]); /* INIT_WORK(&priv->setup_work, setup_line, serial->port[i]); */ /* INIT_WORK(&priv->write_work, send_data, serial->port[i]); */ priv->port = port; INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line); INIT_DELAYED_WORK(&priv->delayed_write_work, send_data); Loading Loading @@ -517,19 +524,17 @@ static void oti6858_set_termios(struct tty_struct *tty, } frame_fmt &= ~FMT_STOP_BITS_MASK; if ((cflag & CSTOPB) != 0) { if ((cflag & CSTOPB) != 0) frame_fmt |= FMT_STOP_BITS_2; } else { else frame_fmt |= FMT_STOP_BITS_1; } frame_fmt &= ~FMT_PARITY_MASK; if ((cflag & PARENB) != 0) { if ((cflag & PARODD) != 0) { if ((cflag & PARODD) != 0) frame_fmt |= FMT_PARITY_ODD; } else { else frame_fmt |= FMT_PARITY_EVEN; } } else { frame_fmt |= FMT_PARITY_NONE; } Loading Loading @@ -584,7 +589,8 @@ static int oti6858_open(struct tty_struct *tty, if (port->port.count != 1) return 0; if ((buf = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL)) == NULL) { buf = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL); if (buf == NULL) { dev_err(&port->dev, "%s(): out of memory!\n", __func__); return -ENOMEM; } Loading Loading @@ -729,11 +735,10 @@ static int oti6858_tiocmset(struct tty_struct *tty, struct file *file, if ((clear & TIOCM_DTR) != 0) control &= ~CONTROL_DTR_HIGH; if (control != priv->pending_setup.control) { if (control != priv->pending_setup.control) priv->pending_setup.control = control; } spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags); return 0; } Loading Loading @@ -785,7 +790,8 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) spin_unlock_irqrestore(&priv->lock, flags); while (1) { wait_event_interruptible(priv->intr_wait, priv->status.pin_state != prev); wait_event_interruptible(priv->intr_wait, priv->status.pin_state != prev); if (signal_pending(current)) return -ERESTARTSYS; Loading @@ -798,9 +804,8 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) if (((arg & TIOCM_RNG) && (changed & PIN_RI)) || ((arg & TIOCM_DSR) && (changed & PIN_DSR)) || ((arg & TIOCM_CD) && (changed & PIN_DCD)) || ((arg & TIOCM_CTS) && (changed & PIN_CTS))) { ((arg & TIOCM_CTS) && (changed & PIN_CTS))) return 0; } prev = status; } Loading @@ -820,12 +825,10 @@ static int oti6858_ioctl(struct tty_struct *tty, struct file *file, case TIOCMIWAIT: dbg("%s(): TIOCMIWAIT", __func__); return wait_modem_info(port, arg); default: dbg("%s(): 0x%04x not supported", __func__, cmd); break; } return -ENOIOCTLCMD; } Loading Loading @@ -950,7 +953,7 @@ static void oti6858_read_int_callback(struct urb *urb) if (resubmit) { int result; // dbg("%s(): submitting interrupt urb", __func__); /* dbg("%s(): submitting interrupt urb", __func__); */ urb->dev = port->serial->dev; result = usb_submit_urb(urb, GFP_ATOMIC); if (result != 0) { Loading Loading @@ -985,8 +988,10 @@ static void oti6858_read_bulk_callback(struct urb *urb) } /* if (status == -EPROTO) { // PL2303 mysteriously fails with -EPROTO reschedule the read dbg("%s - caught -EPROTO, resubmitting the urb", __func__); * PL2303 mysteriously fails with -EPROTO reschedule the read * dbg("%s - caught -EPROTO, resubmitting the urb", __func__); result = usb_submit_urb(urb, GFP_ATOMIC); if (result) dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result); Loading @@ -1003,7 +1008,7 @@ static void oti6858_read_bulk_callback(struct urb *urb) tty_flip_buffer_push(tty); } // schedule the interrupt urb if we are still open */ /* schedule the interrupt urb if we are still open */ if (port->port.count != 0) { port->interrupt_in_urb->dev = port->serial->dev; result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); Loading Loading @@ -1055,7 +1060,7 @@ static void oti6858_write_bulk_callback(struct urb *urb) priv->flags.write_urb_in_use = 0; // schedule the interrupt urb if we are still open */ /* schedule the interrupt urb if we are still open */ port->interrupt_in_urb->dev = port->serial->dev; dbg("%s(): submitting interrupt urb", __func__); result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); Loading Loading @@ -1130,7 +1135,7 @@ static unsigned int oti6858_buf_data_avail(struct oti6858_buf *pb) { if (pb == NULL) return 0; return ((pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size); return (pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size; } /* Loading @@ -1143,7 +1148,7 @@ static unsigned int oti6858_buf_space_avail(struct oti6858_buf *pb) { if (pb == NULL) return 0; return ((pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size); return (pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size; } /* Loading Loading @@ -1230,13 +1235,12 @@ static int __init oti6858_init(void) { int retval; if ((retval = usb_serial_register(&oti6858_device)) == 0) { if ((retval = usb_register(&oti6858_driver)) != 0) retval = usb_serial_register(&oti6858_device); if (retval == 0) { retval = usb_register(&oti6858_driver); if (retval) usb_serial_deregister(&oti6858_device); else return 0; } return retval; } Loading Loading
drivers/usb/serial/oti6858.c +70 −66 Original line number Diff line number Diff line Loading @@ -25,7 +25,8 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License. * * See Documentation/usb/usb-serial.txt for more information on using this driver * See Documentation/usb/usb-serial.txt for more information on using this * driver * * TODO: * - implement correct flushing for ioctls and oti6858_close() Loading @@ -49,7 +50,7 @@ #include <linux/spinlock.h> #include <linux/usb.h> #include <linux/usb/serial.h> #include <asm/uaccess.h> #include <linux/uaccess.h> #include "oti6858.h" #define OTI6858_DESCRIPTION \ Loading Loading @@ -229,7 +230,8 @@ struct oti6858_private { static void setup_line(struct work_struct *work) { struct oti6858_private *priv = container_of(work, struct oti6858_private, delayed_setup_work.work); struct oti6858_private *priv = container_of(work, struct oti6858_private, delayed_setup_work.work); struct usb_serial_port *port = priv->port; struct oti6858_control_pkt *new_setup; unsigned long flags; Loading @@ -237,10 +239,12 @@ static void setup_line(struct work_struct *work) dbg("%s(port = %d)", __func__, port->number); if ((new_setup = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL)) == NULL) { new_setup = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL); if (new_setup == NULL) { dev_err(&port->dev, "%s(): out of memory!\n", __func__); /* we will try again */ schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2)); schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2)); return; } Loading @@ -256,7 +260,8 @@ static void setup_line(struct work_struct *work) dev_err(&port->dev, "%s(): error reading status\n", __func__); kfree(new_setup); /* we will try again */ schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2)); schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2)); return; } Loading Loading @@ -297,7 +302,8 @@ static void setup_line(struct work_struct *work) void send_data(struct work_struct *work) { struct oti6858_private *priv = container_of(work, struct oti6858_private, delayed_write_work.work); struct oti6858_private *priv = container_of(work, struct oti6858_private, delayed_write_work.work); struct usb_serial_port *port = priv->port; int count = 0, result; unsigned long flags; Loading @@ -308,7 +314,8 @@ void send_data(struct work_struct *work) spin_lock_irqsave(&priv->lock, flags); if (priv->flags.write_urb_in_use) { spin_unlock_irqrestore(&priv->lock, flags); schedule_delayed_work(&priv->delayed_write_work, msecs_to_jiffies(2)); schedule_delayed_work(&priv->delayed_write_work, msecs_to_jiffies(2)); return; } priv->flags.write_urb_in_use = 1; Loading Loading @@ -375,8 +382,8 @@ static int oti6858_startup(struct usb_serial *serial) spin_lock_init(&priv->lock); init_waitqueue_head(&priv->intr_wait); // INIT_WORK(&priv->setup_work, setup_line, serial->port[i]); // INIT_WORK(&priv->write_work, send_data, serial->port[i]); /* INIT_WORK(&priv->setup_work, setup_line, serial->port[i]); */ /* INIT_WORK(&priv->write_work, send_data, serial->port[i]); */ priv->port = port; INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line); INIT_DELAYED_WORK(&priv->delayed_write_work, send_data); Loading Loading @@ -517,19 +524,17 @@ static void oti6858_set_termios(struct tty_struct *tty, } frame_fmt &= ~FMT_STOP_BITS_MASK; if ((cflag & CSTOPB) != 0) { if ((cflag & CSTOPB) != 0) frame_fmt |= FMT_STOP_BITS_2; } else { else frame_fmt |= FMT_STOP_BITS_1; } frame_fmt &= ~FMT_PARITY_MASK; if ((cflag & PARENB) != 0) { if ((cflag & PARODD) != 0) { if ((cflag & PARODD) != 0) frame_fmt |= FMT_PARITY_ODD; } else { else frame_fmt |= FMT_PARITY_EVEN; } } else { frame_fmt |= FMT_PARITY_NONE; } Loading Loading @@ -584,7 +589,8 @@ static int oti6858_open(struct tty_struct *tty, if (port->port.count != 1) return 0; if ((buf = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL)) == NULL) { buf = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL); if (buf == NULL) { dev_err(&port->dev, "%s(): out of memory!\n", __func__); return -ENOMEM; } Loading Loading @@ -729,11 +735,10 @@ static int oti6858_tiocmset(struct tty_struct *tty, struct file *file, if ((clear & TIOCM_DTR) != 0) control &= ~CONTROL_DTR_HIGH; if (control != priv->pending_setup.control) { if (control != priv->pending_setup.control) priv->pending_setup.control = control; } spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags); return 0; } Loading Loading @@ -785,7 +790,8 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) spin_unlock_irqrestore(&priv->lock, flags); while (1) { wait_event_interruptible(priv->intr_wait, priv->status.pin_state != prev); wait_event_interruptible(priv->intr_wait, priv->status.pin_state != prev); if (signal_pending(current)) return -ERESTARTSYS; Loading @@ -798,9 +804,8 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) if (((arg & TIOCM_RNG) && (changed & PIN_RI)) || ((arg & TIOCM_DSR) && (changed & PIN_DSR)) || ((arg & TIOCM_CD) && (changed & PIN_DCD)) || ((arg & TIOCM_CTS) && (changed & PIN_CTS))) { ((arg & TIOCM_CTS) && (changed & PIN_CTS))) return 0; } prev = status; } Loading @@ -820,12 +825,10 @@ static int oti6858_ioctl(struct tty_struct *tty, struct file *file, case TIOCMIWAIT: dbg("%s(): TIOCMIWAIT", __func__); return wait_modem_info(port, arg); default: dbg("%s(): 0x%04x not supported", __func__, cmd); break; } return -ENOIOCTLCMD; } Loading Loading @@ -950,7 +953,7 @@ static void oti6858_read_int_callback(struct urb *urb) if (resubmit) { int result; // dbg("%s(): submitting interrupt urb", __func__); /* dbg("%s(): submitting interrupt urb", __func__); */ urb->dev = port->serial->dev; result = usb_submit_urb(urb, GFP_ATOMIC); if (result != 0) { Loading Loading @@ -985,8 +988,10 @@ static void oti6858_read_bulk_callback(struct urb *urb) } /* if (status == -EPROTO) { // PL2303 mysteriously fails with -EPROTO reschedule the read dbg("%s - caught -EPROTO, resubmitting the urb", __func__); * PL2303 mysteriously fails with -EPROTO reschedule the read * dbg("%s - caught -EPROTO, resubmitting the urb", __func__); result = usb_submit_urb(urb, GFP_ATOMIC); if (result) dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result); Loading @@ -1003,7 +1008,7 @@ static void oti6858_read_bulk_callback(struct urb *urb) tty_flip_buffer_push(tty); } // schedule the interrupt urb if we are still open */ /* schedule the interrupt urb if we are still open */ if (port->port.count != 0) { port->interrupt_in_urb->dev = port->serial->dev; result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); Loading Loading @@ -1055,7 +1060,7 @@ static void oti6858_write_bulk_callback(struct urb *urb) priv->flags.write_urb_in_use = 0; // schedule the interrupt urb if we are still open */ /* schedule the interrupt urb if we are still open */ port->interrupt_in_urb->dev = port->serial->dev; dbg("%s(): submitting interrupt urb", __func__); result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); Loading Loading @@ -1130,7 +1135,7 @@ static unsigned int oti6858_buf_data_avail(struct oti6858_buf *pb) { if (pb == NULL) return 0; return ((pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size); return (pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size; } /* Loading @@ -1143,7 +1148,7 @@ static unsigned int oti6858_buf_space_avail(struct oti6858_buf *pb) { if (pb == NULL) return 0; return ((pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size); return (pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size; } /* Loading Loading @@ -1230,13 +1235,12 @@ static int __init oti6858_init(void) { int retval; if ((retval = usb_serial_register(&oti6858_device)) == 0) { if ((retval = usb_register(&oti6858_driver)) != 0) retval = usb_serial_register(&oti6858_device); if (retval == 0) { retval = usb_register(&oti6858_driver); if (retval) usb_serial_deregister(&oti6858_device); else return 0; } return retval; } Loading