diff options
-rw-r--r-- | include/net/irda/ircomm_tty.h | 1 | ||||
-rw-r--r-- | net/irda/ircomm/ircomm_tty.c | 38 |
2 files changed, 18 insertions, 21 deletions
diff --git a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h index e4db3b5f6e4c..a9027d8f670d 100644 --- a/include/net/irda/ircomm_tty.h +++ b/include/net/irda/ircomm_tty.h | |||
@@ -96,7 +96,6 @@ struct ircomm_tty_cb { | |||
96 | struct work_struct tqueue; | 96 | struct work_struct tqueue; |
97 | 97 | ||
98 | /* Protect concurent access to : | 98 | /* Protect concurent access to : |
99 | * o self->open_count | ||
100 | * o self->ctrl_skb | 99 | * o self->ctrl_skb |
101 | * o self->tx_skb | 100 | * o self->tx_skb |
102 | * Maybe other things may gain to be protected as well... | 101 | * Maybe other things may gain to be protected as well... |
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index 8e61026b9dd4..7b2152cfd42a 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c | |||
@@ -283,13 +283,12 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, | |||
283 | IRDA_DEBUG(2, "%s(%d):block_til_ready before block on %s open_count=%d\n", | 283 | IRDA_DEBUG(2, "%s(%d):block_til_ready before block on %s open_count=%d\n", |
284 | __FILE__, __LINE__, tty->driver->name, self->port.count); | 284 | __FILE__, __LINE__, tty->driver->name, self->port.count); |
285 | 285 | ||
286 | /* As far as I can see, we protect port.count - Jean II */ | 286 | spin_lock_irqsave(&self->port.lock, flags); |
287 | spin_lock_irqsave(&self->spinlock, flags); | ||
288 | if (!tty_hung_up_p(filp)) { | 287 | if (!tty_hung_up_p(filp)) { |
289 | extra_count = 1; | 288 | extra_count = 1; |
290 | self->port.count--; | 289 | self->port.count--; |
291 | } | 290 | } |
292 | spin_unlock_irqrestore(&self->spinlock, flags); | 291 | spin_unlock_irqrestore(&self->port.lock, flags); |
293 | self->port.blocked_open++; | 292 | self->port.blocked_open++; |
294 | 293 | ||
295 | while (1) { | 294 | while (1) { |
@@ -340,9 +339,9 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, | |||
340 | 339 | ||
341 | if (extra_count) { | 340 | if (extra_count) { |
342 | /* ++ is not atomic, so this should be protected - Jean II */ | 341 | /* ++ is not atomic, so this should be protected - Jean II */ |
343 | spin_lock_irqsave(&self->spinlock, flags); | 342 | spin_lock_irqsave(&self->port.lock, flags); |
344 | self->port.count++; | 343 | self->port.count++; |
345 | spin_unlock_irqrestore(&self->spinlock, flags); | 344 | spin_unlock_irqrestore(&self->port.lock, flags); |
346 | } | 345 | } |
347 | self->port.blocked_open--; | 346 | self->port.blocked_open--; |
348 | 347 | ||
@@ -409,12 +408,12 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) | |||
409 | hashbin_insert(ircomm_tty, (irda_queue_t *) self, line, NULL); | 408 | hashbin_insert(ircomm_tty, (irda_queue_t *) self, line, NULL); |
410 | } | 409 | } |
411 | /* ++ is not atomic, so this should be protected - Jean II */ | 410 | /* ++ is not atomic, so this should be protected - Jean II */ |
412 | spin_lock_irqsave(&self->spinlock, flags); | 411 | spin_lock_irqsave(&self->port.lock, flags); |
413 | self->port.count++; | 412 | self->port.count++; |
414 | 413 | ||
415 | tty->driver_data = self; | 414 | tty->driver_data = self; |
416 | self->tty = tty; | 415 | self->tty = tty; |
417 | spin_unlock_irqrestore(&self->spinlock, flags); | 416 | spin_unlock_irqrestore(&self->port.lock, flags); |
418 | 417 | ||
419 | IRDA_DEBUG(1, "%s(), %s%d, count = %d\n", __func__ , tty->driver->name, | 418 | IRDA_DEBUG(1, "%s(), %s%d, count = %d\n", __func__ , tty->driver->name, |
420 | self->line, self->port.count); | 419 | self->line, self->port.count); |
@@ -495,10 +494,10 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp) | |||
495 | IRDA_ASSERT(self != NULL, return;); | 494 | IRDA_ASSERT(self != NULL, return;); |
496 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 495 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
497 | 496 | ||
498 | spin_lock_irqsave(&self->spinlock, flags); | 497 | spin_lock_irqsave(&self->port.lock, flags); |
499 | 498 | ||
500 | if (tty_hung_up_p(filp)) { | 499 | if (tty_hung_up_p(filp)) { |
501 | spin_unlock_irqrestore(&self->spinlock, flags); | 500 | spin_unlock_irqrestore(&self->port.lock, flags); |
502 | 501 | ||
503 | IRDA_DEBUG(0, "%s(), returning 1\n", __func__ ); | 502 | IRDA_DEBUG(0, "%s(), returning 1\n", __func__ ); |
504 | return; | 503 | return; |
@@ -524,20 +523,15 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp) | |||
524 | self->port.count = 0; | 523 | self->port.count = 0; |
525 | } | 524 | } |
526 | if (self->port.count) { | 525 | if (self->port.count) { |
527 | spin_unlock_irqrestore(&self->spinlock, flags); | 526 | spin_unlock_irqrestore(&self->port.lock, flags); |
528 | 527 | ||
529 | IRDA_DEBUG(0, "%s(), open count > 0\n", __func__ ); | 528 | IRDA_DEBUG(0, "%s(), open count > 0\n", __func__ ); |
530 | return; | 529 | return; |
531 | } | 530 | } |
532 | 531 | ||
533 | /* Hum... Should be test_and_set_bit ??? - Jean II */ | ||
534 | set_bit(ASYNCB_CLOSING, &self->port.flags); | 532 | set_bit(ASYNCB_CLOSING, &self->port.flags); |
535 | 533 | ||
536 | /* We need to unlock here (we were unlocking at the end of this | 534 | spin_unlock_irqrestore(&self->port.lock, flags); |
537 | * function), because tty_wait_until_sent() may schedule. | ||
538 | * I don't know if the rest should be protected somehow, | ||
539 | * so someone should check. - Jean II */ | ||
540 | spin_unlock_irqrestore(&self->spinlock, flags); | ||
541 | 535 | ||
542 | /* | 536 | /* |
543 | * Now we wait for the transmit buffer to clear; and we notify | 537 | * Now we wait for the transmit buffer to clear; and we notify |
@@ -552,16 +546,21 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp) | |||
552 | tty_driver_flush_buffer(tty); | 546 | tty_driver_flush_buffer(tty); |
553 | tty_ldisc_flush(tty); | 547 | tty_ldisc_flush(tty); |
554 | 548 | ||
549 | spin_lock_irqsave(&self->port.lock, flags); | ||
555 | tty->closing = 0; | 550 | tty->closing = 0; |
556 | self->tty = NULL; | 551 | self->tty = NULL; |
557 | 552 | ||
558 | if (self->port.blocked_open) { | 553 | if (self->port.blocked_open) { |
559 | if (self->port.close_delay) | 554 | if (self->port.close_delay) { |
555 | spin_unlock_irqrestore(&self->port.lock, flags); | ||
560 | schedule_timeout_interruptible(self->port.close_delay); | 556 | schedule_timeout_interruptible(self->port.close_delay); |
557 | spin_lock_irqsave(&self->port.lock, flags); | ||
558 | } | ||
561 | wake_up_interruptible(&self->port.open_wait); | 559 | wake_up_interruptible(&self->port.open_wait); |
562 | } | 560 | } |
563 | 561 | ||
564 | self->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | 562 | self->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); |
563 | spin_unlock_irqrestore(&self->port.lock, flags); | ||
565 | wake_up_interruptible(&self->port.close_wait); | 564 | wake_up_interruptible(&self->port.close_wait); |
566 | } | 565 | } |
567 | 566 | ||
@@ -1003,12 +1002,11 @@ static void ircomm_tty_hangup(struct tty_struct *tty) | |||
1003 | /* ircomm_tty_flush_buffer(tty); */ | 1002 | /* ircomm_tty_flush_buffer(tty); */ |
1004 | ircomm_tty_shutdown(self); | 1003 | ircomm_tty_shutdown(self); |
1005 | 1004 | ||
1006 | /* I guess we need to lock here - Jean II */ | 1005 | spin_lock_irqsave(&self->port.lock, flags); |
1007 | spin_lock_irqsave(&self->spinlock, flags); | ||
1008 | self->port.flags &= ~ASYNC_NORMAL_ACTIVE; | 1006 | self->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
1009 | self->tty = NULL; | 1007 | self->tty = NULL; |
1010 | self->port.count = 0; | 1008 | self->port.count = 0; |
1011 | spin_unlock_irqrestore(&self->spinlock, flags); | 1009 | spin_unlock_irqrestore(&self->port.lock, flags); |
1012 | 1010 | ||
1013 | wake_up_interruptible(&self->port.open_wait); | 1011 | wake_up_interruptible(&self->port.open_wait); |
1014 | } | 1012 | } |