|
@@ -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)
|