aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTilman Schmidt <tilman@imap.cc>2009-04-05 02:39:33 -0400
committerDavid S. Miller <davem@davemloft.net>2009-04-06 20:07:57 -0400
commit51370e5b21c5825cff7482e1c38f4e7c5dab3e2b (patch)
treea20d0e46399d92a72f0056abdb025c63afae53f6
parent368fd81d2db26e3338c7f42778a695510aff31b3 (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.c58
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