tty: isicom: sort out the board init logic
authorAlan Cox <alan@linux.intel.com>
Mon, 30 Nov 2009 13:17:30 +0000 (13:17 +0000)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 11 Dec 2009 23:18:07 +0000 (15:18 -0800)
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>
drivers/char/isicom.c
include/linux/isicom.h

index e7be3ec6d21c1b8815c79a21c789f33620345cdd..1e91c302ee423cf814aa55d8acde12f050a71d67 100644 (file)
@@ -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)
index bbd42197298f14b95f78ffcc24d6d2db508de56f..b92e0565063939ede488f0764011614999e0c148 100644 (file)
@@ -67,6 +67,7 @@
 
 #define                FIRMWARE_LOADED         0x0001
 #define                BOARD_ACTIVE            0x0002
+#define                BOARD_INIT              0x0004
 
        /* isi_port status bitmap  */