diff options
Diffstat (limited to 'drivers/usb/serial/quatech2.c')
| -rw-r--r-- | drivers/usb/serial/quatech2.c | 160 |
1 files changed, 42 insertions, 118 deletions
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index 00e6c9bac8a..504f5bff79c 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c @@ -15,7 +15,6 @@ #include <asm/unaligned.h> #include <linux/errno.h> -#include <linux/init.h> #include <linux/slab.h> #include <linux/tty.h> #include <linux/tty_driver.h> @@ -62,6 +61,7 @@ #define MAX_BAUD_RATE 921600 #define DEFAULT_BAUD_RATE 9600 +#define QT2_READ_BUFFER_SIZE 512 /* size of read buffer */ #define QT2_WRITE_BUFFER_SIZE 512 /* size of write buffer */ #define QT2_WRITE_CONTROL_SIZE 5 /* control bytes used for a write */ @@ -112,25 +112,21 @@ struct qt2_serial_private { unsigned char current_port; /* current port for incoming data */ struct urb *read_urb; /* shared among all ports */ - char read_buffer[512]; + char *read_buffer; }; struct qt2_port_private { - bool is_open; u8 device_port; spinlock_t urb_lock; bool urb_in_use; struct urb *write_urb; - char write_buffer[QT2_WRITE_BUFFER_SIZE]; + char *write_buffer; spinlock_t lock; u8 shadowLSR; u8 shadowMSR; - wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ - struct async_icount icount; - struct usb_serial_port *port; }; @@ -146,6 +142,7 @@ static void qt2_release(struct usb_serial *serial) serial_priv = usb_get_serial_data(serial); usb_free_urb(serial_priv->read_urb); + kfree(serial_priv->read_buffer); kfree(serial_priv); } @@ -347,7 +344,7 @@ static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port) int status; unsigned long flags; - device_port = (u16) (port->number - port->serial->minor); + device_port = port->port_number; serial = port->serial; @@ -375,7 +372,7 @@ static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port) device_port, data, 2, QT2_USB_TIMEOUT); if (status < 0) { - dev_err(&port->dev, "%s - open port failed %i", __func__, + dev_err(&port->dev, "%s - open port failed %i\n", __func__, status); kfree(data); return status; @@ -392,13 +389,11 @@ static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port) status = qt2_set_port_config(serial->dev, device_port, DEFAULT_BAUD_RATE, UART_LCR_WLEN8); if (status < 0) { - dev_err(&port->dev, - "%s - initial setup failed for port %i (%i)\n", - __func__, port->number, device_port); + dev_err(&port->dev, "%s - initial setup failed (%i)\n", + __func__, device_port); return status; } - port_priv->is_open = true; port_priv->device_port = (u8) device_port; if (tty) @@ -418,19 +413,11 @@ static void qt2_close(struct usb_serial_port *port) serial = port->serial; port_priv = usb_get_serial_port_data(port); - port_priv->is_open = false; - spin_lock_irqsave(&port_priv->urb_lock, flags); usb_kill_urb(port_priv->write_urb); port_priv->urb_in_use = false; spin_unlock_irqrestore(&port_priv->urb_lock, flags); - mutex_lock(&port->serial->disc_mutex); - if (port->serial->disconnected) { - mutex_unlock(&port->serial->disc_mutex); - return; - } - /* flush the port transmit buffer */ i = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), @@ -461,8 +448,6 @@ static void qt2_close(struct usb_serial_port *port) if (i < 0) dev_err(&port->dev, "%s - close port failed %i\n", __func__, i); - - mutex_unlock(&port->serial->disc_mutex); } static void qt2_disconnect(struct usb_serial *serial) @@ -481,7 +466,7 @@ static int get_serial_info(struct usb_serial_port *port, return -EFAULT; memset(&tmp, 0, sizeof(tmp)); - tmp.line = port->serial->minor; + tmp.line = port->minor; tmp.port = 0; tmp.irq = 0; tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; @@ -495,67 +480,6 @@ static int get_serial_info(struct usb_serial_port *port, return 0; } -static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) -{ - struct qt2_port_private *priv = usb_get_serial_port_data(port); - struct async_icount prev, cur; - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - prev = priv->icount; - spin_unlock_irqrestore(&priv->lock, flags); - - while (1) { - wait_event_interruptible(priv->delta_msr_wait, - ((priv->icount.rng != prev.rng) || - (priv->icount.dsr != prev.dsr) || - (priv->icount.dcd != prev.dcd) || - (priv->icount.cts != prev.cts))); - - if (signal_pending(current)) - return -ERESTARTSYS; - - spin_lock_irqsave(&priv->lock, flags); - cur = priv->icount; - spin_unlock_irqrestore(&priv->lock, flags); - - if ((prev.rng == cur.rng) && - (prev.dsr == cur.dsr) && - (prev.dcd == cur.dcd) && - (prev.cts == cur.cts)) - return -EIO; - - if ((arg & TIOCM_RNG && (prev.rng != cur.rng)) || - (arg & TIOCM_DSR && (prev.dsr != cur.dsr)) || - (arg & TIOCM_CD && (prev.dcd != cur.dcd)) || - (arg & TIOCM_CTS && (prev.cts != cur.cts))) - return 0; - } - return 0; -} - -static int qt2_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct usb_serial_port *port = tty->driver_data; - struct qt2_port_private *priv = usb_get_serial_port_data(port); - struct async_icount cnow = priv->icount; - - 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 qt2_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { @@ -565,10 +489,6 @@ static int qt2_ioctl(struct tty_struct *tty, case TIOCGSERIAL: return get_serial_info(port, (struct serial_struct __user *)arg); - - case TIOCMIWAIT: - return wait_modem_info(port, arg); - default: break; } @@ -603,7 +523,7 @@ static void qt2_process_flush(struct usb_serial_port *port, unsigned char *ch) return; } -void qt2_process_read_urb(struct urb *urb) +static void qt2_process_read_urb(struct urb *urb) { struct usb_serial *serial; struct qt2_serial_private *serial_priv; @@ -755,16 +675,14 @@ static int qt2_setup_urbs(struct usb_serial *serial) serial_priv = usb_get_serial_data(serial); serial_priv->read_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!serial_priv->read_urb) { - dev_err(&serial->dev->dev, "No free urbs available\n"); + if (!serial_priv->read_urb) return -ENOMEM; - } usb_fill_bulk_urb(serial_priv->read_urb, serial->dev, usb_rcvbulkpipe(serial->dev, port0->bulk_in_endpointAddress), serial_priv->read_buffer, - sizeof(serial_priv->read_buffer), + QT2_READ_BUFFER_SIZE, qt2_read_bulk_callback, serial); status = usb_submit_urb(serial_priv->read_urb, GFP_KERNEL); @@ -794,9 +712,13 @@ static int qt2_attach(struct usb_serial *serial) } serial_priv = kzalloc(sizeof(*serial_priv), GFP_KERNEL); - if (!serial_priv) { - dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__); + if (!serial_priv) return -ENOMEM; + + serial_priv->read_buffer = kmalloc(QT2_READ_BUFFER_SIZE, GFP_KERNEL); + if (!serial_priv->read_buffer) { + status = -ENOMEM; + goto err_buf; } usb_set_serial_data(serial, serial_priv); @@ -808,6 +730,8 @@ static int qt2_attach(struct usb_serial *serial) return 0; attach_failed: + kfree(serial_priv->read_buffer); +err_buf: kfree(serial_priv); return status; } @@ -824,24 +748,31 @@ static int qt2_port_probe(struct usb_serial_port *port) spin_lock_init(&port_priv->lock); spin_lock_init(&port_priv->urb_lock); - init_waitqueue_head(&port_priv->delta_msr_wait); port_priv->port = port; + port_priv->write_buffer = kmalloc(QT2_WRITE_BUFFER_SIZE, GFP_KERNEL); + if (!port_priv->write_buffer) + goto err_buf; + port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!port_priv->write_urb) { - kfree(port_priv); - return -ENOMEM; - } + if (!port_priv->write_urb) + goto err_urb; + bEndpointAddress = serial->port[0]->bulk_out_endpointAddress; usb_fill_bulk_urb(port_priv->write_urb, serial->dev, usb_sndbulkpipe(serial->dev, bEndpointAddress), port_priv->write_buffer, - sizeof(port_priv->write_buffer), + QT2_WRITE_BUFFER_SIZE, qt2_write_bulk_callback, port); usb_set_serial_port_data(port, port_priv); return 0; +err_urb: + kfree(port_priv->write_buffer); +err_buf: + kfree(port_priv); + return -ENOMEM; } static int qt2_port_remove(struct usb_serial_port *port) @@ -850,6 +781,7 @@ static int qt2_port_remove(struct usb_serial_port *port) port_priv = usb_get_serial_port_data(port); usb_free_urb(port_priv->write_urb); + kfree(port_priv->write_buffer); kfree(port_priv); return 0; @@ -905,12 +837,6 @@ static void qt2_break_ctl(struct tty_struct *tty, int break_state) port_priv = usb_get_serial_port_data(port); - if (!port_priv->is_open) { - dev_err(&port->dev, - "%s - port is not open\n", __func__); - return; - } - val = (break_state == -1) ? 1 : 0; status = qt2_control_msg(port->serial->dev, QT2_BREAK_CONTROL, @@ -956,18 +882,15 @@ static void qt2_update_msr(struct usb_serial_port *port, unsigned char *ch) if (newMSR & UART_MSR_ANY_DELTA) { /* update input line counters */ if (newMSR & UART_MSR_DCTS) - port_priv->icount.cts++; - + port->icount.cts++; if (newMSR & UART_MSR_DDSR) - port_priv->icount.dsr++; - + port->icount.dsr++; if (newMSR & UART_MSR_DDCD) - port_priv->icount.dcd++; - + port->icount.dcd++; if (newMSR & UART_MSR_TERI) - port_priv->icount.rng++; + port->icount.rng++; - wake_up_interruptible(&port_priv->delta_msr_wait); + wake_up_interruptible(&port->port.delta_msr_wait); } } @@ -987,7 +910,7 @@ static void qt2_update_lsr(struct usb_serial_port *port, unsigned char *ch) port_priv->shadowLSR = newLSR; spin_unlock_irqrestore(&port_priv->lock, flags); - icount = &port_priv->icount; + icount = &port->icount; if (newLSR & UART_LSR_BRK_ERROR_BITS) { @@ -1097,7 +1020,8 @@ static struct usb_serial_driver qt2_device = { .break_ctl = qt2_break_ctl, .tiocmget = qt2_tiocmget, .tiocmset = qt2_tiocmset, - .get_icount = qt2_get_icount, + .tiocmiwait = usb_serial_generic_tiocmiwait, + .get_icount = usb_serial_generic_get_icount, .ioctl = qt2_ioctl, .set_termios = qt2_set_termios, }; |
