summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2009-11-30 13:17:30 +0000
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 15:18:07 -0800
commit6ed847d8efd08658ece10c9129cd511c8d7452cd (patch)
tree9c32476496a46fa6671ac212324a11b177578a67 /drivers
parentbaaa08acb0ca2df47830b58b5df8b9059cf9ddd2 (diff)
downloadlinux-6ed847d8efd08658ece10c9129cd511c8d7452cd.tar.bz2
tty: isicom: sort out the board init logic
Split this into two flags - INIT meaning the board is set up and ACTIVE meaning the board has ports open. Remove the broken HUPCL casing and push the counts somewhere sensible. Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/isicom.c41
1 files changed, 11 insertions, 30 deletions
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index e7be3ec6d21c..1e91c302ee42 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -793,21 +793,19 @@ static inline void isicom_setup_board(struct isi_board *bp)
{
int channel;
struct isi_port *port;
- unsigned long flags;
- spin_lock_irqsave(&bp->card_lock, flags);
- if (bp->status & BOARD_ACTIVE) {
- spin_unlock_irqrestore(&bp->card_lock, flags);
- return;
- }
- port = bp->ports;
- bp->status |= BOARD_ACTIVE;
- for (channel = 0; channel < bp->port_count; channel++, port++)
- drop_dtr_rts(port);
bp->count++;
- spin_unlock_irqrestore(&bp->card_lock, flags);
+ if (!(bp->status & BOARD_INIT)) {
+ port = bp->ports;
+ for (channel = 0; channel < bp->port_count; channel++, port++)
+ drop_dtr_rts(port);
+ }
+ bp->status |= BOARD_ACTIVE | BOARD_INIT;
}
+/* Activate and thus setup board are protected from races against shutdown
+ by the tty_port mutex */
+
static int isicom_activate(struct tty_port *tport, struct tty_struct *tty)
{
struct isi_port *port = container_of(tport, struct isi_port, port);
@@ -884,19 +882,10 @@ static int isicom_open(struct tty_struct *tty, struct file *filp)
/* close et all */
-static inline void isicom_shutdown_board(struct isi_board *bp)
-{
- if (bp->status & BOARD_ACTIVE)
- bp->status &= ~BOARD_ACTIVE;
-}
-
/* card->lock HAS to be held */
static void isicom_shutdown_port(struct isi_port *port)
{
struct isi_board *card = port->card;
- struct tty_struct *tty;
-
- tty = tty_port_tty_get(&port->port);
tty_port_free_xmit_buf(&port->port);
if (--card->count < 0) {
@@ -904,17 +893,9 @@ static void isicom_shutdown_port(struct isi_port *port)
card->base, card->count);
card->count = 0;
}
-
/* last port was closed, shutdown that board too */
- if (tty && C_HUPCL(tty)) {
- /* FIXME: this logic is bogus - it's the old logic that was
- bogus before but it still wants fixing */
- if (!card->count) {
- if (card->status & BOARD_ACTIVE)
- card->status &= ~BOARD_ACTIVE;
- }
- }
- tty_kref_put(tty);
+ if (!card->count)
+ card->status &= BOARD_ACTIVE;
}
static void isicom_flush_buffer(struct tty_struct *tty)