aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/generic_serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/generic_serial.c')
-rw-r--r--drivers/char/generic_serial.c37
1 files changed, 24 insertions, 13 deletions
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
index 2356994ee010..2f040d1ed89f 100644
--- a/drivers/char/generic_serial.c
+++ b/drivers/char/generic_serial.c
@@ -376,7 +376,8 @@ static void gs_shutdown_port (struct gs_port *port)
376 376
377void gs_hangup(struct tty_struct *tty) 377void gs_hangup(struct tty_struct *tty)
378{ 378{
379 struct gs_port *port; 379 struct gs_port *port;
380 unsigned long flags;
380 381
381 func_enter (); 382 func_enter ();
382 383
@@ -386,9 +387,11 @@ void gs_hangup(struct tty_struct *tty)
386 return; 387 return;
387 388
388 gs_shutdown_port (port); 389 gs_shutdown_port (port);
390 spin_lock_irqsave(&port->port.lock, flags);
389 port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|GS_ACTIVE); 391 port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|GS_ACTIVE);
390 port->port.tty = NULL; 392 port->port.tty = NULL;
391 port->port.count = 0; 393 port->port.count = 0;
394 spin_unlock_irqrestore(&port->port.lock, flags);
392 395
393 wake_up_interruptible(&port->port.open_wait); 396 wake_up_interruptible(&port->port.open_wait);
394 func_exit (); 397 func_exit ();
@@ -454,12 +457,12 @@ int gs_block_til_ready(void *port_, struct file * filp)
454 add_wait_queue(&port->open_wait, &wait); 457 add_wait_queue(&port->open_wait, &wait);
455 458
456 gs_dprintk (GS_DEBUG_BTR, "after add waitq.\n"); 459 gs_dprintk (GS_DEBUG_BTR, "after add waitq.\n");
457 spin_lock_irqsave(&gp->driver_lock, flags); 460 spin_lock_irqsave(&port->lock, flags);
458 if (!tty_hung_up_p(filp)) { 461 if (!tty_hung_up_p(filp)) {
459 port->count--; 462 port->count--;
460 } 463 }
461 spin_unlock_irqrestore(&gp->driver_lock, flags);
462 port->blocked_open++; 464 port->blocked_open++;
465 spin_unlock_irqrestore(&port->lock, flags);
463 while (1) { 466 while (1) {
464 CD = tty_port_carrier_raised(port); 467 CD = tty_port_carrier_raised(port);
465 gs_dprintk (GS_DEBUG_BTR, "CD is now %d.\n", CD); 468 gs_dprintk (GS_DEBUG_BTR, "CD is now %d.\n", CD);
@@ -487,16 +490,17 @@ int gs_block_til_ready(void *port_, struct file * filp)
487 port->blocked_open); 490 port->blocked_open);
488 set_current_state (TASK_RUNNING); 491 set_current_state (TASK_RUNNING);
489 remove_wait_queue(&port->open_wait, &wait); 492 remove_wait_queue(&port->open_wait, &wait);
493
494 spin_lock_irqsave(&port->lock, flags);
490 if (!tty_hung_up_p(filp)) { 495 if (!tty_hung_up_p(filp)) {
491 port->count++; 496 port->count++;
492 } 497 }
493 port->blocked_open--; 498 port->blocked_open--;
494 if (retval) 499 if (retval == 0)
495 return retval; 500 port->flags |= ASYNC_NORMAL_ACTIVE;
496 501 spin_unlock_irqrestore(&port->lock, flags);
497 port->flags |= ASYNC_NORMAL_ACTIVE;
498 func_exit (); 502 func_exit ();
499 return 0; 503 return retval;
500} 504}
501 505
502 506
@@ -517,10 +521,10 @@ void gs_close(struct tty_struct * tty, struct file * filp)
517 port->port.tty = tty; 521 port->port.tty = tty;
518 } 522 }
519 523
520 spin_lock_irqsave(&port->driver_lock, flags); 524 spin_lock_irqsave(&port->port.lock, flags);
521 525
522 if (tty_hung_up_p(filp)) { 526 if (tty_hung_up_p(filp)) {
523 spin_unlock_irqrestore(&port->driver_lock, flags); 527 spin_unlock_irqrestore(&port->port.lock, flags);
524 if (port->rd->hungup) 528 if (port->rd->hungup)
525 port->rd->hungup (port); 529 port->rd->hungup (port);
526 func_exit (); 530 func_exit ();
@@ -539,7 +543,7 @@ void gs_close(struct tty_struct * tty, struct file * filp)
539 543
540 if (port->port.count) { 544 if (port->port.count) {
541 gs_dprintk(GS_DEBUG_CLOSE, "gs_close port %p: count: %d\n", port, port->port.count); 545 gs_dprintk(GS_DEBUG_CLOSE, "gs_close port %p: count: %d\n", port, port->port.count);
542 spin_unlock_irqrestore(&port->driver_lock, flags); 546 spin_unlock_irqrestore(&port->port.lock, flags);
543 func_exit (); 547 func_exit ();
544 return; 548 return;
545 } 549 }
@@ -560,8 +564,10 @@ void gs_close(struct tty_struct * tty, struct file * filp)
560 * line status register. 564 * line status register.
561 */ 565 */
562 566
567 spin_lock_irqsave(&port->driver_lock, flags);
563 port->rd->disable_rx_interrupts (port); 568 port->rd->disable_rx_interrupts (port);
564 spin_unlock_irqrestore(&port->driver_lock, flags); 569 spin_unlock_irqrestore(&port->driver_lock, flags);
570 spin_unlock_irqrestore(&port->port.lock, flags);
565 571
566 /* close has no way of returning "EINTR", so discard return value */ 572 /* close has no way of returning "EINTR", so discard return value */
567 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) 573 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
@@ -574,20 +580,25 @@ void gs_close(struct tty_struct * tty, struct file * filp)
574 tty_ldisc_flush(tty); 580 tty_ldisc_flush(tty);
575 tty->closing = 0; 581 tty->closing = 0;
576 582
583 spin_lock_irqsave(&port->driver_lock, flags);
577 port->event = 0; 584 port->event = 0;
578 port->rd->close (port); 585 port->rd->close (port);
579 port->rd->shutdown_port (port); 586 port->rd->shutdown_port (port);
587 spin_unlock_irqrestore(&port->driver_lock, flags);
588
589 spin_lock_irqsave(&port->port.lock, flags);
580 port->port.tty = NULL; 590 port->port.tty = NULL;
581 591
582 if (port->port.blocked_open) { 592 if (port->port.blocked_open) {
583 if (port->close_delay) { 593 if (port->close_delay) {
584 spin_unlock_irqrestore(&port->driver_lock, flags); 594 spin_unlock_irqrestore(&port->port.lock, flags);
585 msleep_interruptible(jiffies_to_msecs(port->close_delay)); 595 msleep_interruptible(jiffies_to_msecs(port->close_delay));
586 spin_lock_irqsave(&port->driver_lock, flags); 596 spin_lock_irqsave(&port->port.lock, flags);
587 } 597 }
588 wake_up_interruptible(&port->port.open_wait); 598 wake_up_interruptible(&port->port.open_wait);
589 } 599 }
590 port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING | ASYNC_INITIALIZED); 600 port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING | ASYNC_INITIALIZED);
601 spin_unlock_irqrestore(&port->port.lock, flags);
591 wake_up_interruptible(&port->port.close_wait); 602 wake_up_interruptible(&port->port.close_wait);
592 603
593 func_exit (); 604 func_exit ();