diff options
author | Tilman Schmidt <tilman@imap.cc> | 2009-04-05 02:39:33 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-04-06 20:07:57 -0400 |
commit | 51370e5b21c5825cff7482e1c38f4e7c5dab3e2b (patch) | |
tree | a20d0e46399d92a72f0056abdb025c63afae53f6 | |
parent | 368fd81d2db26e3338c7f42778a695510aff31b3 (diff) |
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: Tilman Schmidt <tilman@imap.cc>
Reported-by: Paul Bolle <pebolle@tiscali.nl>
Tested-by: Paul Bolle <pebolle@tiscali.nl>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/isdn/gigaset/interface.c | 58 |
1 files changed, 30 insertions, 28 deletions
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index 311e7ca0fb01..820a30923fee 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c | |||
@@ -193,7 +193,9 @@ static void if_close(struct tty_struct *tty, struct file *filp) | |||
193 | 193 | ||
194 | mutex_lock(&cs->mutex); | 194 | mutex_lock(&cs->mutex); |
195 | 195 | ||
196 | if (!cs->open_count) | 196 | if (!cs->connected) |
197 | gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */ | ||
198 | else if (!cs->open_count) | ||
197 | dev_warn(cs->dev, "%s: device not opened\n", __func__); | 199 | dev_warn(cs->dev, "%s: device not opened\n", __func__); |
198 | else { | 200 | else { |
199 | if (!--cs->open_count) { | 201 | if (!--cs->open_count) { |
@@ -228,7 +230,10 @@ static int if_ioctl(struct tty_struct *tty, struct file *file, | |||
228 | if (mutex_lock_interruptible(&cs->mutex)) | 230 | if (mutex_lock_interruptible(&cs->mutex)) |
229 | return -ERESTARTSYS; // FIXME -EINTR? | 231 | return -ERESTARTSYS; // FIXME -EINTR? |
230 | 232 | ||
231 | if (!cs->open_count) | 233 | if (!cs->connected) { |
234 | gig_dbg(DEBUG_IF, "not connected"); | ||
235 | retval = -ENODEV; | ||
236 | } else if (!cs->open_count) | ||
232 | dev_warn(cs->dev, "%s: device not opened\n", __func__); | 237 | dev_warn(cs->dev, "%s: device not opened\n", __func__); |
233 | else { | 238 | else { |
234 | retval = 0; | 239 | retval = 0; |
@@ -248,13 +253,6 @@ static int if_ioctl(struct tty_struct *tty, struct file *file, | |||
248 | retval = put_user(int_arg, (int __user *) arg); | 253 | retval = put_user(int_arg, (int __user *) arg); |
249 | break; | 254 | break; |
250 | case GIGASET_BRKCHARS: | 255 | case GIGASET_BRKCHARS: |
251 | //FIXME test if MS_LOCKED | ||
252 | if (!cs->connected) { | ||
253 | gig_dbg(DEBUG_ANY, | ||
254 | "can't communicate with unplugged device"); | ||
255 | retval = -ENODEV; | ||
256 | break; | ||
257 | } | ||
258 | retval = copy_from_user(&buf, | 256 | retval = copy_from_user(&buf, |
259 | (const unsigned char __user *) arg, 6) | 257 | (const unsigned char __user *) arg, 6) |
260 | ? -EFAULT : 0; | 258 | ? -EFAULT : 0; |
@@ -331,7 +329,7 @@ static int if_tiocmset(struct tty_struct *tty, struct file *file, | |||
331 | return -ERESTARTSYS; // FIXME -EINTR? | 329 | return -ERESTARTSYS; // FIXME -EINTR? |
332 | 330 | ||
333 | if (!cs->connected) { | 331 | if (!cs->connected) { |
334 | gig_dbg(DEBUG_ANY, "can't communicate with unplugged device"); | 332 | gig_dbg(DEBUG_IF, "not connected"); |
335 | retval = -ENODEV; | 333 | retval = -ENODEV; |
336 | } else { | 334 | } else { |
337 | mc = (cs->control_state | set) & ~clear & (TIOCM_RTS|TIOCM_DTR); | 335 | 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 | if (mutex_lock_interruptible(&cs->mutex)) | 358 | if (mutex_lock_interruptible(&cs->mutex)) |
361 | return -ERESTARTSYS; // FIXME -EINTR? | 359 | return -ERESTARTSYS; // FIXME -EINTR? |
362 | 360 | ||
363 | if (!cs->open_count) | 361 | if (!cs->connected) { |
362 | gig_dbg(DEBUG_IF, "not connected"); | ||
363 | retval = -ENODEV; | ||
364 | } else if (!cs->open_count) | ||
364 | dev_warn(cs->dev, "%s: device not opened\n", __func__); | 365 | dev_warn(cs->dev, "%s: device not opened\n", __func__); |
365 | else if (cs->mstate != MS_LOCKED) { | 366 | else if (cs->mstate != MS_LOCKED) { |
366 | dev_warn(cs->dev, "can't write to unlocked device\n"); | 367 | dev_warn(cs->dev, "can't write to unlocked device\n"); |
367 | retval = -EBUSY; | 368 | retval = -EBUSY; |
368 | } else if (!cs->connected) { | ||
369 | gig_dbg(DEBUG_ANY, "can't write to unplugged device"); | ||
370 | retval = -EBUSY; //FIXME | ||
371 | } else { | 369 | } else { |
372 | retval = cs->ops->write_cmd(cs, buf, count, | 370 | retval = cs->ops->write_cmd(cs, buf, count, |
373 | &cs->if_wake_tasklet); | 371 | &cs->if_wake_tasklet); |
@@ -394,14 +392,14 @@ static int if_write_room(struct tty_struct *tty) | |||
394 | if (mutex_lock_interruptible(&cs->mutex)) | 392 | if (mutex_lock_interruptible(&cs->mutex)) |
395 | return -ERESTARTSYS; // FIXME -EINTR? | 393 | return -ERESTARTSYS; // FIXME -EINTR? |
396 | 394 | ||
397 | if (!cs->open_count) | 395 | if (!cs->connected) { |
396 | gig_dbg(DEBUG_IF, "not connected"); | ||
397 | retval = -ENODEV; | ||
398 | } else if (!cs->open_count) | ||
398 | dev_warn(cs->dev, "%s: device not opened\n", __func__); | 399 | dev_warn(cs->dev, "%s: device not opened\n", __func__); |
399 | else if (cs->mstate != MS_LOCKED) { | 400 | else if (cs->mstate != MS_LOCKED) { |
400 | dev_warn(cs->dev, "can't write to unlocked device\n"); | 401 | dev_warn(cs->dev, "can't write to unlocked device\n"); |
401 | retval = -EBUSY; | 402 | retval = -EBUSY; |
402 | } else if (!cs->connected) { | ||
403 | gig_dbg(DEBUG_ANY, "can't write to unplugged device"); | ||
404 | retval = -EBUSY; //FIXME | ||
405 | } else | 403 | } else |
406 | retval = cs->ops->write_room(cs); | 404 | retval = cs->ops->write_room(cs); |
407 | 405 | ||
@@ -426,14 +424,14 @@ static int if_chars_in_buffer(struct tty_struct *tty) | |||
426 | if (mutex_lock_interruptible(&cs->mutex)) | 424 | if (mutex_lock_interruptible(&cs->mutex)) |
427 | return -ERESTARTSYS; // FIXME -EINTR? | 425 | return -ERESTARTSYS; // FIXME -EINTR? |
428 | 426 | ||
429 | if (!cs->open_count) | 427 | if (!cs->connected) { |
428 | gig_dbg(DEBUG_IF, "not connected"); | ||
429 | retval = -ENODEV; | ||
430 | } else if (!cs->open_count) | ||
430 | dev_warn(cs->dev, "%s: device not opened\n", __func__); | 431 | dev_warn(cs->dev, "%s: device not opened\n", __func__); |
431 | else if (cs->mstate != MS_LOCKED) { | 432 | else if (cs->mstate != MS_LOCKED) { |
432 | dev_warn(cs->dev, "can't write to unlocked device\n"); | 433 | dev_warn(cs->dev, "can't write to unlocked device\n"); |
433 | retval = -EBUSY; | 434 | retval = -EBUSY; |
434 | } else if (!cs->connected) { | ||
435 | gig_dbg(DEBUG_ANY, "can't write to unplugged device"); | ||
436 | retval = -EBUSY; //FIXME | ||
437 | } else | 435 | } else |
438 | retval = cs->ops->chars_in_buffer(cs); | 436 | retval = cs->ops->chars_in_buffer(cs); |
439 | 437 | ||
@@ -456,7 +454,9 @@ static void if_throttle(struct tty_struct *tty) | |||
456 | 454 | ||
457 | mutex_lock(&cs->mutex); | 455 | mutex_lock(&cs->mutex); |
458 | 456 | ||
459 | if (!cs->open_count) | 457 | if (!cs->connected) |
458 | gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */ | ||
459 | else if (!cs->open_count) | ||
460 | dev_warn(cs->dev, "%s: device not opened\n", __func__); | 460 | dev_warn(cs->dev, "%s: device not opened\n", __func__); |
461 | else { | 461 | else { |
462 | //FIXME | 462 | //FIXME |
@@ -479,7 +479,9 @@ static void if_unthrottle(struct tty_struct *tty) | |||
479 | 479 | ||
480 | mutex_lock(&cs->mutex); | 480 | mutex_lock(&cs->mutex); |
481 | 481 | ||
482 | if (!cs->open_count) | 482 | if (!cs->connected) |
483 | gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */ | ||
484 | else if (!cs->open_count) | ||
483 | dev_warn(cs->dev, "%s: device not opened\n", __func__); | 485 | dev_warn(cs->dev, "%s: device not opened\n", __func__); |
484 | else { | 486 | else { |
485 | //FIXME | 487 | //FIXME |
@@ -506,13 +508,13 @@ static void if_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
506 | 508 | ||
507 | mutex_lock(&cs->mutex); | 509 | mutex_lock(&cs->mutex); |
508 | 510 | ||
509 | if (!cs->open_count) { | 511 | if (!cs->connected) { |
510 | dev_warn(cs->dev, "%s: device not opened\n", __func__); | 512 | gig_dbg(DEBUG_IF, "not connected"); |
511 | goto out; | 513 | goto out; |
512 | } | 514 | } |
513 | 515 | ||
514 | if (!cs->connected) { | 516 | if (!cs->open_count) { |
515 | gig_dbg(DEBUG_ANY, "can't communicate with unplugged device"); | 517 | dev_warn(cs->dev, "%s: device not opened\n", __func__); |
516 | goto out; | 518 | goto out; |
517 | } | 519 | } |
518 | 520 | ||