提交 51370e5b 编写于 作者: T Tilman Schmidt 提交者: David S. Miller

gigaset: in file ops, check for device disconnect before anything else

When the device is disconnected, the dev structure goes away, so
trying to report another error via dev_printk is bound to oops.
To avoid that, first check whether the device is still connected
and return quietly if it isn't.

Impact: error handling
Signed-off-by: NTilman Schmidt <tilman@imap.cc>
Reported-by: NPaul Bolle <pebolle@tiscali.nl>
Tested-by: NPaul Bolle <pebolle@tiscali.nl>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 368fd81d
...@@ -193,7 +193,9 @@ static void if_close(struct tty_struct *tty, struct file *filp) ...@@ -193,7 +193,9 @@ static void if_close(struct tty_struct *tty, struct file *filp)
mutex_lock(&cs->mutex); mutex_lock(&cs->mutex);
if (!cs->open_count) if (!cs->connected)
gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */
else if (!cs->open_count)
dev_warn(cs->dev, "%s: device not opened\n", __func__); dev_warn(cs->dev, "%s: device not opened\n", __func__);
else { else {
if (!--cs->open_count) { if (!--cs->open_count) {
...@@ -228,7 +230,10 @@ static int if_ioctl(struct tty_struct *tty, struct file *file, ...@@ -228,7 +230,10 @@ static int if_ioctl(struct tty_struct *tty, struct file *file,
if (mutex_lock_interruptible(&cs->mutex)) if (mutex_lock_interruptible(&cs->mutex))
return -ERESTARTSYS; // FIXME -EINTR? return -ERESTARTSYS; // FIXME -EINTR?
if (!cs->open_count) if (!cs->connected) {
gig_dbg(DEBUG_IF, "not connected");
retval = -ENODEV;
} else if (!cs->open_count)
dev_warn(cs->dev, "%s: device not opened\n", __func__); dev_warn(cs->dev, "%s: device not opened\n", __func__);
else { else {
retval = 0; retval = 0;
...@@ -248,13 +253,6 @@ static int if_ioctl(struct tty_struct *tty, struct file *file, ...@@ -248,13 +253,6 @@ static int if_ioctl(struct tty_struct *tty, struct file *file,
retval = put_user(int_arg, (int __user *) arg); retval = put_user(int_arg, (int __user *) arg);
break; break;
case GIGASET_BRKCHARS: case GIGASET_BRKCHARS:
//FIXME test if MS_LOCKED
if (!cs->connected) {
gig_dbg(DEBUG_ANY,
"can't communicate with unplugged device");
retval = -ENODEV;
break;
}
retval = copy_from_user(&buf, retval = copy_from_user(&buf,
(const unsigned char __user *) arg, 6) (const unsigned char __user *) arg, 6)
? -EFAULT : 0; ? -EFAULT : 0;
...@@ -331,7 +329,7 @@ static int if_tiocmset(struct tty_struct *tty, struct file *file, ...@@ -331,7 +329,7 @@ static int if_tiocmset(struct tty_struct *tty, struct file *file,
return -ERESTARTSYS; // FIXME -EINTR? return -ERESTARTSYS; // FIXME -EINTR?
if (!cs->connected) { if (!cs->connected) {
gig_dbg(DEBUG_ANY, "can't communicate with unplugged device"); gig_dbg(DEBUG_IF, "not connected");
retval = -ENODEV; retval = -ENODEV;
} else { } else {
mc = (cs->control_state | set) & ~clear & (TIOCM_RTS|TIOCM_DTR); mc = (cs->control_state | set) & ~clear & (TIOCM_RTS|TIOCM_DTR);
...@@ -360,14 +358,14 @@ static int if_write(struct tty_struct *tty, const unsigned char *buf, int count) ...@@ -360,14 +358,14 @@ static int if_write(struct tty_struct *tty, const unsigned char *buf, int count)
if (mutex_lock_interruptible(&cs->mutex)) if (mutex_lock_interruptible(&cs->mutex))
return -ERESTARTSYS; // FIXME -EINTR? return -ERESTARTSYS; // FIXME -EINTR?
if (!cs->open_count) if (!cs->connected) {
gig_dbg(DEBUG_IF, "not connected");
retval = -ENODEV;
} else if (!cs->open_count)
dev_warn(cs->dev, "%s: device not opened\n", __func__); dev_warn(cs->dev, "%s: device not opened\n", __func__);
else if (cs->mstate != MS_LOCKED) { else if (cs->mstate != MS_LOCKED) {
dev_warn(cs->dev, "can't write to unlocked device\n"); dev_warn(cs->dev, "can't write to unlocked device\n");
retval = -EBUSY; retval = -EBUSY;
} else if (!cs->connected) {
gig_dbg(DEBUG_ANY, "can't write to unplugged device");
retval = -EBUSY; //FIXME
} else { } else {
retval = cs->ops->write_cmd(cs, buf, count, retval = cs->ops->write_cmd(cs, buf, count,
&cs->if_wake_tasklet); &cs->if_wake_tasklet);
...@@ -394,14 +392,14 @@ static int if_write_room(struct tty_struct *tty) ...@@ -394,14 +392,14 @@ static int if_write_room(struct tty_struct *tty)
if (mutex_lock_interruptible(&cs->mutex)) if (mutex_lock_interruptible(&cs->mutex))
return -ERESTARTSYS; // FIXME -EINTR? return -ERESTARTSYS; // FIXME -EINTR?
if (!cs->open_count) if (!cs->connected) {
gig_dbg(DEBUG_IF, "not connected");
retval = -ENODEV;
} else if (!cs->open_count)
dev_warn(cs->dev, "%s: device not opened\n", __func__); dev_warn(cs->dev, "%s: device not opened\n", __func__);
else if (cs->mstate != MS_LOCKED) { else if (cs->mstate != MS_LOCKED) {
dev_warn(cs->dev, "can't write to unlocked device\n"); dev_warn(cs->dev, "can't write to unlocked device\n");
retval = -EBUSY; retval = -EBUSY;
} else if (!cs->connected) {
gig_dbg(DEBUG_ANY, "can't write to unplugged device");
retval = -EBUSY; //FIXME
} else } else
retval = cs->ops->write_room(cs); retval = cs->ops->write_room(cs);
...@@ -426,14 +424,14 @@ static int if_chars_in_buffer(struct tty_struct *tty) ...@@ -426,14 +424,14 @@ static int if_chars_in_buffer(struct tty_struct *tty)
if (mutex_lock_interruptible(&cs->mutex)) if (mutex_lock_interruptible(&cs->mutex))
return -ERESTARTSYS; // FIXME -EINTR? return -ERESTARTSYS; // FIXME -EINTR?
if (!cs->open_count) if (!cs->connected) {
gig_dbg(DEBUG_IF, "not connected");
retval = -ENODEV;
} else if (!cs->open_count)
dev_warn(cs->dev, "%s: device not opened\n", __func__); dev_warn(cs->dev, "%s: device not opened\n", __func__);
else if (cs->mstate != MS_LOCKED) { else if (cs->mstate != MS_LOCKED) {
dev_warn(cs->dev, "can't write to unlocked device\n"); dev_warn(cs->dev, "can't write to unlocked device\n");
retval = -EBUSY; retval = -EBUSY;
} else if (!cs->connected) {
gig_dbg(DEBUG_ANY, "can't write to unplugged device");
retval = -EBUSY; //FIXME
} else } else
retval = cs->ops->chars_in_buffer(cs); retval = cs->ops->chars_in_buffer(cs);
...@@ -456,7 +454,9 @@ static void if_throttle(struct tty_struct *tty) ...@@ -456,7 +454,9 @@ static void if_throttle(struct tty_struct *tty)
mutex_lock(&cs->mutex); mutex_lock(&cs->mutex);
if (!cs->open_count) if (!cs->connected)
gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */
else if (!cs->open_count)
dev_warn(cs->dev, "%s: device not opened\n", __func__); dev_warn(cs->dev, "%s: device not opened\n", __func__);
else { else {
//FIXME //FIXME
...@@ -479,7 +479,9 @@ static void if_unthrottle(struct tty_struct *tty) ...@@ -479,7 +479,9 @@ static void if_unthrottle(struct tty_struct *tty)
mutex_lock(&cs->mutex); mutex_lock(&cs->mutex);
if (!cs->open_count) if (!cs->connected)
gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */
else if (!cs->open_count)
dev_warn(cs->dev, "%s: device not opened\n", __func__); dev_warn(cs->dev, "%s: device not opened\n", __func__);
else { else {
//FIXME //FIXME
...@@ -506,13 +508,13 @@ static void if_set_termios(struct tty_struct *tty, struct ktermios *old) ...@@ -506,13 +508,13 @@ static void if_set_termios(struct tty_struct *tty, struct ktermios *old)
mutex_lock(&cs->mutex); mutex_lock(&cs->mutex);
if (!cs->open_count) { if (!cs->connected) {
dev_warn(cs->dev, "%s: device not opened\n", __func__); gig_dbg(DEBUG_IF, "not connected");
goto out; goto out;
} }
if (!cs->connected) { if (!cs->open_count) {
gig_dbg(DEBUG_ANY, "can't communicate with unplugged device"); dev_warn(cs->dev, "%s: device not opened\n", __func__);
goto out; goto out;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册