git.openpandora.org
/
pandora-kernel.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
USB: keyspan: fix null-deref at disconnect and release
[pandora-kernel.git]
/
drivers
/
usb
/
serial
/
spcp8x5.c
diff --git
a/drivers/usb/serial/spcp8x5.c
b/drivers/usb/serial/spcp8x5.c
index
180ea6c
..
f3179b0
100644
(file)
--- a/
drivers/usb/serial/spcp8x5.c
+++ b/
drivers/usb/serial/spcp8x5.c
@@
-163,7
+163,6
@@
static struct usb_driver spcp8x5_driver = {
struct spcp8x5_private {
spinlock_t lock;
enum spcp8x5_type type;
struct spcp8x5_private {
spinlock_t lock;
enum spcp8x5_type type;
- wait_queue_head_t delta_msr_wait;
u8 line_control;
u8 line_status;
};
u8 line_control;
u8 line_status;
};
@@
-197,7
+196,6
@@
static int spcp8x5_startup(struct usb_serial *serial)
goto cleanup;
spin_lock_init(&priv->lock);
goto cleanup;
spin_lock_init(&priv->lock);
- init_waitqueue_head(&priv->delta_msr_wait);
priv->type = type;
usb_set_serial_port_data(serial->port[i] , priv);
}
priv->type = type;
usb_set_serial_port_data(serial->port[i] , priv);
}
@@
-340,7
+338,6
@@
static void spcp8x5_set_termios(struct tty_struct *tty,
struct spcp8x5_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
unsigned int cflag = tty->termios->c_cflag;
struct spcp8x5_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
unsigned int cflag = tty->termios->c_cflag;
- unsigned int old_cflag = old_termios->c_cflag;
unsigned short uartdata;
unsigned char buf[2] = {0, 0};
int baud;
unsigned short uartdata;
unsigned char buf[2] = {0, 0};
int baud;
@@
-349,15
+346,15
@@
static void spcp8x5_set_termios(struct tty_struct *tty,
/* check that they really want us to change something */
/* check that they really want us to change something */
- if (!tty_termios_hw_change(tty->termios, old_termios))
+ if (
old_termios &&
!tty_termios_hw_change(tty->termios, old_termios))
return;
/* set DTR/RTS active */
spin_lock_irqsave(&priv->lock, flags);
control = priv->line_control;
return;
/* set DTR/RTS active */
spin_lock_irqsave(&priv->lock, flags);
control = priv->line_control;
- if (
(old
_cflag & CBAUD) == B0) {
+ if (
old_termios && (old_termios->c
_cflag & CBAUD) == B0) {
priv->line_control |= MCR_DTR;
priv->line_control |= MCR_DTR;
- if (!(old_cflag & CRTSCTS))
+ if (!(old_
termios->c_
cflag & CRTSCTS))
priv->line_control |= MCR_RTS;
}
if (control != priv->line_control) {
priv->line_control |= MCR_RTS;
}
if (control != priv->line_control) {
@@
-447,7
+444,6
@@
static void spcp8x5_set_termios(struct tty_struct *tty,
* status of the device. */
static int spcp8x5_open(struct tty_struct *tty, struct usb_serial_port *port)
{
* status of the device. */
static int spcp8x5_open(struct tty_struct *tty, struct usb_serial_port *port)
{
- struct ktermios tmp_termios;
struct usb_serial *serial = port->serial;
struct spcp8x5_private *priv = usb_get_serial_port_data(port);
int ret;
struct usb_serial *serial = port->serial;
struct spcp8x5_private *priv = usb_get_serial_port_data(port);
int ret;
@@
-470,7
+466,7
@@
static int spcp8x5_open(struct tty_struct *tty, struct usb_serial_port *port)
/* Setup termios */
if (tty)
/* Setup termios */
if (tty)
- spcp8x5_set_termios(tty, port,
&tmp_termios
);
+ spcp8x5_set_termios(tty, port,
NULL
);
spcp8x5_get_msr(serial->dev, &status, priv->type);
spcp8x5_get_msr(serial->dev, &status, priv->type);
@@
-502,7
+498,7
@@
static void spcp8x5_process_read_urb(struct urb *urb)
priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
spin_unlock_irqrestore(&priv->lock, flags);
/* wake up the wait for termios */
priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
spin_unlock_irqrestore(&priv->lock, flags);
/* wake up the wait for termios */
- wake_up_interruptible(&p
riv
->delta_msr_wait);
+ wake_up_interruptible(&p
ort
->delta_msr_wait);
if (!urb->actual_length)
return;
if (!urb->actual_length)
return;
@@
-552,12
+548,15
@@
static int spcp8x5_wait_modem_info(struct usb_serial_port *port,
while (1) {
/* wake up in bulk read */
while (1) {
/* wake up in bulk read */
- interruptible_sleep_on(&p
riv
->delta_msr_wait);
+ interruptible_sleep_on(&p
ort
->delta_msr_wait);
/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;
/* see if a signal did it */
if (signal_pending(current))
return -ERESTARTSYS;
+ if (port->serial->disconnected)
+ return -EIO;
+
spin_lock_irqsave(&priv->lock, flags);
status = priv->line_status;
spin_unlock_irqrestore(&priv->lock, flags);
spin_lock_irqsave(&priv->lock, flags);
status = priv->line_status;
spin_unlock_irqrestore(&priv->lock, flags);