/* Reset device */ static int hci_uart_flush(struct hci_dev *hdev) { struct hci_uart *hu = (struct hci_uart *) hdev->driver_data; struct tty_struct *tty = hu->tty; BT_DBG("hdev %p tty %p", hdev, tty); if (hu->tx_skb) { kfree_skb(hu->tx_skb); hu->tx_skb = NULL; } /* Flush any pending characters in the driver and discipline. */ tty_ldisc_flush(tty); tty_driver_flush_buffer(tty); if (test_bit(HCI_UART_PROTO_SET, &hu->flags)) hu->proto->flush(hu); return 0; }
/* * ------------------------------------------------------------ * rs_close() * * This routine is called when the serial port gets closed. First, we * wait for the last remaining data to be sent. Then, we unlink its * async structure from the interrupt chain if necessary, and we free * that IRQ if nothing is left in the chain. * ------------------------------------------------------------ */ static void rs_close(struct tty_struct *tty, struct file * filp) { struct serial_state *state = tty->driver_data; struct tty_port *port = &state->tport; if (serial_paranoia_check(state, tty->name, "rs_close")) return; if (tty_port_close_start(port, tty, filp) == 0) return; /* * At this point we stop accepting input. To do this, we * disable the receive line status interrupts, and tell the * interrupt driver to stop checking the data ready bit in the * line status register. */ state->read_status_mask &= ~UART_LSR_DR; if (port->flags & ASYNC_INITIALIZED) { /* disable receive interrupts */ custom.intena = IF_RBF; mb(); /* clear any pending receive interrupt */ custom.intreq = IF_RBF; mb(); /* * Before we drop DTR, make sure the UART transmitter * has completely drained; this is especially * important if there is a transmit FIFO! */ rs_wait_until_sent(tty, state->timeout); } shutdown(tty, state); rs_flush_buffer(tty); tty_ldisc_flush(tty); port->tty = NULL; tty_port_close_end(port, tty); }
/* Reset device */ static int hci_uart_flush(struct hci_dev *hdev) { struct hci_uart *hu = (struct hci_uart *) hdev->driver_data; struct tty_struct *tty = hu->tty; BT_DBG("hdev %p tty %p", hdev, tty); if (hu->tx_skb) { kfree_skb(hu->tx_skb); hu->tx_skb = NULL; } tty_ldisc_flush(tty); if (tty->driver.flush_buffer) tty->driver.flush_buffer(tty); if (test_bit(HCI_UART_PROTO_SET, &hu->flags)) hu->proto->flush(hu); return 0; }
/* * Close down a RIN channel. * This means flushing out any pending queues, and then returning. This * call is serialized against other ldisc functions. */ static void rin_close(struct tty_struct *tty) { struct rin_st *sl = tty->disc_data; /* First make sure we're connected. */ if (!sl || sl->magic != RIN_MAGIC || sl->tty != tty) return; //spin_lock(&sl->lock); //LGE_DOMESTIC_ADD_START 2011-09-29 //if(rin_tx_wq) //flush_workqueue(rin_tx_wq); //LGE_DOMESTIC_ADD_END tty_ldisc_flush(tty); tty->disc_data = NULL; sl->tty = NULL; if (!sl->leased) sl->line = 0; rindrv_count++; if(DEBUG) printk("%s - line : %d - rindrv_count = %d\n", __FUNCTION__, __LINE__, rindrv_count); //spin_unlock(&sl->lock); }
/* * functions called from TTY layer */ static int st_tty_open(struct tty_struct *tty) { int err = 0; struct st_data_s *st_gdata; pr_info("%s ", __func__); st_kim_ref(&st_gdata, 0); st_gdata->tty = tty; tty->disc_data = st_gdata; if (tty->dev->parent) st_gdata->tty_dev = tty->dev->parent; else return -EINVAL; /* Asynchronous Get is enough here since we just want to avoid * interface to be released too early */ pm_runtime_get(st_gdata->tty_dev); /* don't do an wakeup for now */ clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); /* mem already allocated */ tty->receive_room = 65536; /* Flush any pending characters in the driver and discipline. */ tty_ldisc_flush(tty); tty_driver_flush_buffer(tty); /* * signal to UIM via KIM that - * installation of N_TI_WL ldisc is complete */ st_kim_complete(st_gdata->kim_data); pr_debug("done %s", __func__); return err; }
/* * Close down a RIN channel. * This means flushing out any pending queues, and then returning. This * call is serialized against other ldisc functions. */ static void rin_close(struct tty_struct *tty) { struct rin_st *sl = tty->disc_data; /* First make sure we're connected. */ if (!sl || sl->magic != RIN_MAGIC || sl->tty != tty) return; // START:: RIP-11174 [Data] Upon RIL recovery completion, multiple RIN channel should be opened. spin_lock(&sl->lock); if(rin_tx_wq) flush_workqueue(rin_tx_wq); // END:: RIP-11174 [Data] Upon RIL recovery completion, multiple RIN channel should be opened. tty_ldisc_flush(tty); tty->disc_data = NULL; sl->tty = NULL; if (!sl->leased) sl->line = 0; rindrv_count++; printk("%s - line : %d - rindrv_count = %d\n", __FUNCTION__, __LINE__, rindrv_count); // START:: RIP-11174 [Data] Upon RIL recovery completion, multiple RIN channel should be opened. spin_unlock(&sl->lock); // END:: RIP-11174 [Data] Upon RIL recovery completion, multiple RIN channel should be opened. }
void gs_close(struct tty_struct * tty, struct file * filp) { unsigned long flags; struct gs_port *port; func_enter (); if (!tty) return; port = (struct gs_port *) tty->driver_data; if (!port) return; if (!port->tty) { /* This seems to happen when this is called from vhangup. */ gs_dprintk (GS_DEBUG_CLOSE, "gs: Odd: port->tty is NULL\n"); port->tty = tty; } spin_lock_irqsave(&port->driver_lock, flags); if (tty_hung_up_p(filp)) { spin_unlock_irqrestore(&port->driver_lock, flags); if (port->rd->hungup) port->rd->hungup (port); func_exit (); return; } if ((tty->count == 1) && (port->count != 1)) { printk(KERN_ERR "gs: gs_close port %p: bad port count;" " tty->count is 1, port count is %d\n", port, port->count); port->count = 1; } if (--port->count < 0) { printk(KERN_ERR "gs: gs_close port %p: bad port count: %d\n", port, port->count); port->count = 0; } if (port->count) { gs_dprintk(GS_DEBUG_CLOSE, "gs_close port %p: count: %d\n", port, port->count); spin_unlock_irqrestore(&port->driver_lock, flags); func_exit (); return; } port->flags |= ASYNC_CLOSING; /* * Now we wait for the transmit buffer to clear; and we notify * the line discipline to only process XON/XOFF characters. */ tty->closing = 1; /* if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) tty_wait_until_sent(tty, port->closing_wait); */ /* * At this point we stop accepting input. To do this, we * disable the receive line status interrupts, and tell the * interrupt driver to stop checking the data ready bit in the * line status register. */ port->rd->disable_rx_interrupts (port); spin_unlock_irqrestore(&port->driver_lock, flags); /* close has no way of returning "EINTR", so discard return value */ if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) gs_wait_tx_flushed (port, port->closing_wait); port->flags &= ~GS_ACTIVE; if (tty->driver->flush_buffer) tty->driver->flush_buffer(tty); tty_ldisc_flush(tty); tty->closing = 0; port->event = 0; port->rd->close (port); port->rd->shutdown_port (port); port->tty = NULL; if (port->blocked_open) { if (port->close_delay) { spin_unlock_irqrestore(&port->driver_lock, flags); msleep_interruptible(jiffies_to_msecs(port->close_delay)); spin_lock_irqsave(&port->driver_lock, flags); } wake_up_interruptible(&port->open_wait); } port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING | ASYNC_INITIALIZED); wake_up_interruptible(&port->close_wait); func_exit (); }
/* * ------------------------------------------------------------ * rs_close() * * This routine is called when the serial port gets closed. First, we * wait for the last remaining data to be sent. Then, we unlink its * S structure from the interrupt chain if necessary, and we free * that IRQ if nothing is left in the chain. * ------------------------------------------------------------ */ static void rs_close(struct tty_struct *tty, struct file * filp) { struct m68k_serial * info = (struct m68k_serial *)tty->driver_data; m68328_uart *uart = &uart_addr[info->line]; unsigned long flags; if (!info || serial_paranoia_check(info, tty->name, "rs_close")) return; local_irq_save(flags); if (tty_hung_up_p(filp)) { local_irq_restore(flags); return; } if ((tty->count == 1) && (info->count != 1)) { /* * Uh, oh. tty->count is 1, which means that the tty * structure will be freed. Info->count should always * be one in these conditions. If it's greater than * one, we've got real problems, since it means the * serial port won't be shutdown. */ printk("rs_close: bad serial port count; tty->count is 1, " "info->count is %d\n", info->count); info->count = 1; } if (--info->count < 0) { printk("rs_close: bad serial port count for ttyS%d: %d\n", info->line, info->count); info->count = 0; } if (info->count) { local_irq_restore(flags); return; } info->flags |= S_CLOSING; /* * Now we wait for the transmit buffer to clear; and we notify * the line discipline to only process XON/XOFF characters. */ tty->closing = 1; if (info->closing_wait != S_CLOSING_WAIT_NONE) tty_wait_until_sent(tty, info->closing_wait); /* * At this point we stop accepting input. To do this, we * disable the receive line status interrupts, and tell the * interrupt driver to stop checking the data ready bit in the * line status register. */ uart->ustcnt &= ~USTCNT_RXEN; uart->ustcnt &= ~(USTCNT_RXEN | USTCNT_RX_INTR_MASK); shutdown(info); rs_flush_buffer(tty); tty_ldisc_flush(tty); tty->closing = 0; info->event = 0; info->tty = NULL; #warning "This is not and has never been valid so fix it" #if 0 if (tty->ldisc.num != ldiscs[N_TTY].num) { if (tty->ldisc.close) (tty->ldisc.close)(tty); tty->ldisc = ldiscs[N_TTY]; tty->termios->c_line = N_TTY; if (tty->ldisc.open) (tty->ldisc.open)(tty); } #endif if (info->blocked_open) { if (info->close_delay) { msleep_interruptible(jiffies_to_msecs(info->close_delay)); } wake_up_interruptible(&info->open_wait); } info->flags &= ~(S_NORMAL_ACTIVE|S_CLOSING); wake_up_interruptible(&info->close_wait); local_irq_restore(flags); }
/** * Prototype : release_tty_drv * Description : called from PS Core when BT protocol stack drivers * unregistration,or FM/GNSS hal stack close FM/GNSS inode * input : ps_plat_d * output : return 0--> open tty uart is ok * return !0-> open tty uart is false * Calls : * Called By : * * History : * 1.Date : 2012/11/05 * Author : wx144390 * Modification : Created function * */ int32 release_tty_drv(void *pm_data) { int32 error; struct ps_plat_s *ps_plat_d = NULL; struct tty_struct *tty = NULL; struct ps_core_s *ps_core_d; uint64 timeleft = 0; uint8 delay_times = RELEASE_DELAT_TIMES; PS_PRINT_INFO("%s\n", __func__); if (unlikely(NULL == pm_data)) { PS_PRINT_ERR("pm_data is NULL"); return -EINVAL; } ps_plat_d = (struct ps_plat_s *)pm_data; ps_core_d = ps_plat_d->core_data; tty = ps_core_d->tty; if (false == ps_core_d->tty_have_open) { PS_PRINT_INFO("hisi bfgx line discipline have uninstalled, ignored\n"); return 0; } /* clean all tx sk_buff */ while(((ps_core_d->tx_high_seq.qlen)||(ps_core_d->tx_low_seq.qlen))&&(delay_times)) { msleep(100); delay_times --; } msleep(200); if (tty) { /* can be called before ldisc is installed */ /* Flush any pending characters in the driver and discipline. */ PS_PRINT_INFO(" %s--> into flush_buffer\n", __func__); tty_ldisc_flush(tty); tty_driver_flush_buffer(tty); } INIT_COMPLETION(ps_plat_d->ldisc_uninstalled); ps_plat_d->ldisc_install = TTY_LDISC_UNINSTALL; PS_PRINT_INFO("ldisc_install = %d\n", TTY_LDISC_UNINSTALL); sysfs_notify(g_sysfs_hi110x_bfgx, NULL, "install"); ps_uart_state_pre(ps_core_d->tty); timeleft = wait_for_completion_timeout(&ps_plat_d->ldisc_uninstalled, msecs_to_jiffies(HISI_LDISC_TIME)); if (!timeleft) { ps_uart_state_dump(ps_core_d->tty); PS_PRINT_ERR("hisi bfgx ldisc uninstall timeout\n"); error = -ETIMEDOUT; } else { PS_PRINT_SUC("hisi bfgx line discipline uninstall succ\n"); error = 0; } ps_core_d->tty_have_open = false; ps_plat_d->flow_cntrl = FLOW_CTRL_ENABLE; ps_plat_d->baud_rate = DEFAULT_BAUD_RATE; return error; }
/* * ------------------------------------------------------------ * mcfrs_close() * * This routine is called when the serial port gets closed. First, we * wait for the last remaining data to be sent. Then, we unlink its * S structure from the interrupt chain if necessary, and we free * that IRQ if nothing is left in the chain. * ------------------------------------------------------------ */ static void mcfrs_close(struct tty_struct *tty, struct file * filp) { volatile unsigned char *uartp; struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; unsigned long flags; if (!info || serial_paranoia_check(info, tty->name, "mcfrs_close")) return; local_irq_save(flags); if (tty_hung_up_p(filp)) { local_irq_restore(flags); return; } #ifdef SERIAL_DEBUG_OPEN printk("mcfrs_close ttyS%d, count = %d\n", info->line, info->count); #endif if ((tty->count == 1) && (info->count != 1)) { /* * Uh, oh. tty->count is 1, which means that the tty * structure will be freed. Info->count should always * be one in these conditions. If it's greater than * one, we've got real problems, since it means the * serial port won't be shutdown. */ printk("MCFRS: bad serial port count; tty->count is 1, " "info->count is %d\n", info->count); info->count = 1; } if (--info->count < 0) { printk("MCFRS: bad serial port count for ttyS%d: %d\n", info->line, info->count); info->count = 0; } if (info->count) { local_irq_restore(flags); return; } info->flags |= ASYNC_CLOSING; /* * Now we wait for the transmit buffer to clear; and we notify * the line discipline to only process XON/XOFF characters. */ tty->closing = 1; if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) tty_wait_until_sent(tty, info->closing_wait); /* * At this point we stop accepting input. To do this, we * disable the receive line status interrupts, and tell the * interrupt driver to stop checking the data ready bit in the * line status register. */ info->imr &= ~MCFUART_UIR_RXREADY; uartp = info->addr; uartp[MCFUART_UIMR] = info->imr; #if 0 /* FIXME: do we need to keep this enabled for console?? */ if (mcfrs_console_inited && (mcfrs_console_port == info->line)) { /* Do not disable the UART */ ; } else #endif shutdown(info); mcfrs_flush_buffer(tty); tty_ldisc_flush(tty); tty->closing = 0; info->event = 0; info->port.tty = NULL; #if 0 if (tty->ldisc.num != ldiscs[N_TTY].num) { if (tty->ldisc.close) (tty->ldisc.close)(tty); tty->ldisc = ldiscs[N_TTY]; tty->termios->c_line = N_TTY; if (tty->ldisc.open) (tty->ldisc.open)(tty); } #endif if (info->blocked_open) { if (info->close_delay) { msleep_interruptible(jiffies_to_msecs(info->close_delay)); } wake_up_interruptible(&info->open_wait); } info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); wake_up_interruptible(&info->close_wait); local_irq_restore(flags); }
void sab8253x_closeS(struct tty_struct *tty, struct file * filp) { struct sab_port *port = (struct sab_port *)tty->driver_data; unsigned long flags; MOD_DEC_USE_COUNT; if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_closeS")) { return; } if(port->open_type == OPEN_SYNC_NET) { /* port->tty field should already be NULL */ return; } save_flags(flags); cli(); --(port->count); if (tty_hung_up_p(filp)) { if(port->count == 0) /* I think the reason for the weirdness relates to freeing of structures in the tty driver */ { port->open_type = OPEN_NOT; } else if(port->count < 0) { printk(KERN_ALERT "XX20: port->count went negative.\n"); port->count = 0; port->open_type = OPEN_NOT; } restore_flags(flags); return; } #if 0 if ((tty->count == 1) && (port->count != 0)) { /* * Uh, oh. tty->count is 1, which means that the tty * structure will be freed. port->count should always * be one in these conditions. If it's greater than * one, we've got real problems, since it means the * serial port won't be shutdown. */ printk("sab8253x_close: bad serial port count; tty->count is 1," " port->count is %d\n", port->count); port->count = 0; } #endif if (port->count < 0) { printk(KERN_ALERT "sab8253x_close: bad serial port count for ttys%d: %d\n", port->line, port->count); port->count = 0; } if (port->count) { restore_flags(flags); return; } port->flags |= FLAG8253X_CLOSING; /* * Save the termios structure, since this port may have * separate termios for callout and dialin. */ if (port->flags & FLAG8253X_NORMAL_ACTIVE) { port->normal_termios = *tty->termios; } if (port->flags & FLAG8253X_CALLOUT_ACTIVE) { port->callout_termios = *tty->termios; } /* * Now we wait for the transmit buffer to clear; and we notify * the line discipline to only process XON/XOFF characters. */ tty->closing = 1; if (port->closing_wait != SAB8253X_CLOSING_WAIT_NONE) { tty_wait_until_sent(tty, port->closing_wait); } /* * At this point we stop accepting input. To do this, we * disable the receive line status interrupts, and turn off * the receiver. */ #if 0 port->interrupt_mask0 |= SAB82532_IMR0_TCD; /* not needed for sync */ #endif WRITEB(port,imr0,port->interrupt_mask0); CLEAR_REG_BIT(port, mode, SAB82532_MODE_RAC); /* turn off receiver */ if (port->flags & FLAG8253X_INITIALIZED) { /* * Before we drop DTR, make sure the UART transmitter * has completely drained; this is especially * important if there is a transmit FIFO! */ sab8253x_wait_until_sent(tty, port->timeout); } sab8253x_shutdownS(port); Sab8253xCleanUpTransceiveN(port); if (tty->driver.flush_buffer) { tty->driver.flush_buffer(tty); } tty_ldisc_flush(tty); tty->closing = 0; port->event = 0; port->tty = 0; if (port->blocked_open) { if (port->close_delay) { current->state = TASK_INTERRUPTIBLE; schedule_timeout(port->close_delay); } wake_up_interruptible(&port->open_wait); } port->flags &= ~(FLAG8253X_NORMAL_ACTIVE|FLAG8253X_CALLOUT_ACTIVE| FLAG8253X_CLOSING); wake_up_interruptible(&port->close_wait); port->open_type = OPEN_NOT; restore_flags(flags); }
/* * ------------------------------------------------------------ * dz_close() * * This routine is called when the serial port gets closed. First, we * wait for the last remaining data to be sent. Then, we turn off * the transmit enable and receive enable flags. * ------------------------------------------------------------ */ static void dz_close(struct tty_struct *tty, struct file *filp) { struct dz_serial *info = (struct dz_serial *) tty->driver_data; unsigned long flags; if (!info) return; save_flags(flags); cli(); if (tty_hung_up_p(filp)) { restore_flags(flags); return; } if ((tty->count == 1) && (info->count != 1)) { /* * Uh, oh. tty->count is 1, which means that the tty * structure will be freed. Info->count should always * be one in these conditions. If it's greater than * one, we've got real problems, since it means the * serial port won't be shutdown. */ printk("dz_close: bad serial port count; tty->count is 1, " "info->count is %d\n", info->count); info->count = 1; } if (--info->count < 0) { printk("ds_close: bad serial port count for ttyS%02d: %d\n", info->line, info->count); info->count = 0; } if (info->count) { restore_flags(flags); return; } info->flags |= DZ_CLOSING; /* * Save the termios structure, since this port may have * separate termios for callout and dialin. */ if (info->flags & DZ_NORMAL_ACTIVE) info->normal_termios = *tty->termios; if (info->flags & DZ_CALLOUT_ACTIVE) info->callout_termios = *tty->termios; /* * Now we wait for the transmit buffer to clear; and we notify * the line discipline to only process XON/XOFF characters. */ tty->closing = 1; if (info->closing_wait != DZ_CLOSING_WAIT_NONE) tty_wait_until_sent(tty, info->closing_wait); /* * At this point we stop accepting input. To do this, we * disable the receive line status interrupts. */ shutdown(info); if (tty->driver.flush_buffer) tty->driver.flush_buffer(tty); tty_ldisc_flush(tty); tty->closing = 0; info->event = 0; info->tty = 0; if (tty->ldisc.num != N_TTY) { if (tty->ldisc.close) (tty->ldisc.close) (tty); tty->ldisc = *(tty_ldisc_get(N_TTY)); tty->termios->c_line = N_TTY; if (tty->ldisc.open) (tty->ldisc.open) (tty); } if (info->blocked_open) { if (info->close_delay) { current->state = TASK_INTERRUPTIBLE; schedule_timeout(info->close_delay); } wake_up_interruptible(&info->open_wait); } info->flags &= ~(DZ_NORMAL_ACTIVE | DZ_CALLOUT_ACTIVE | DZ_CLOSING); wake_up_interruptible(&info->close_wait); restore_flags(flags); }
/* * ------------------------------------------------------------ * rs_close() * * This routine is called when the serial port gets closed. First, we * wait for the last remaining data to be sent. Then, we unlink its * async structure from the interrupt chain if necessary, and we free * that IRQ if nothing is left in the chain. * ------------------------------------------------------------ */ static void rs_close(struct tty_struct *tty, struct file * filp) { struct async_struct * info = (struct async_struct *)tty->driver_data; struct serial_state *state; unsigned long flags; if (!info ) return; state = info->state; local_irq_save(flags); if (tty_hung_up_p(filp)) { #ifdef SIMSERIAL_DEBUG printk("rs_close: hung_up\n"); #endif local_irq_restore(flags); return; } #ifdef SIMSERIAL_DEBUG printk("rs_close ttys%d, count = %d\n", info->line, state->count); #endif if ((tty->count == 1) && (state->count != 1)) { /* * Uh, oh. tty->count is 1, which means that the tty * structure will be freed. state->count should always * be one in these conditions. If it's greater than * one, we've got real problems, since it means the * serial port won't be shutdown. */ printk(KERN_ERR "rs_close: bad serial port count; tty->count is 1, " "state->count is %d\n", state->count); state->count = 1; } if (--state->count < 0) { printk(KERN_ERR "rs_close: bad serial port count for ttys%d: %d\n", info->line, state->count); state->count = 0; } if (state->count) { local_irq_restore(flags); return; } info->flags |= ASYNC_CLOSING; local_irq_restore(flags); /* * Now we wait for the transmit buffer to clear; and we notify * the line discipline to only process XON/XOFF characters. */ shutdown(info); rs_flush_buffer(tty); tty_ldisc_flush(tty); info->event = 0; info->tty = NULL; if (info->blocked_open) { if (info->close_delay) schedule_timeout_interruptible(info->close_delay); wake_up_interruptible(&info->open_wait); } info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); wake_up_interruptible(&info->close_wait); }
static void rs_close(struct tty_struct *tty, struct file * filp) { struct async_struct * info = tty->driver_data; struct serial_state *state; unsigned long flags; if (!info || serial_paranoia_check(info, tty->name, "rs_close")) return; state = info->state; local_irq_save(flags); if (tty_hung_up_p(filp)) { DBG_CNT("before DEC-hung"); local_irq_restore(flags); return; } #ifdef SERIAL_DEBUG_OPEN printk("rs_close ttys%d, count = %d\n", info->line, state->count); #endif if ((tty->count == 1) && (state->count != 1)) { /* * Uh, oh. tty->count is 1, which means that the tty * structure will be freed. state->count should always * be one in these conditions. If it's greater than * one, we've got real problems, since it means the * serial port won't be shutdown. */ printk("rs_close: bad serial port count; tty->count is 1, " "state->count is %d\n", state->count); state->count = 1; } if (--state->count < 0) { printk("rs_close: bad serial port count for ttys%d: %d\n", info->line, state->count); state->count = 0; } if (state->count) { DBG_CNT("before DEC-2"); local_irq_restore(flags); return; } info->flags |= ASYNC_CLOSING; /* * Now we wait for the transmit buffer to clear; and we notify * the line discipline to only process XON/XOFF characters. */ tty->closing = 1; if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) tty_wait_until_sent(tty, info->closing_wait); /* * At this point we stop accepting input. To do this, we * disable the receive line status interrupts, and tell the * interrupt driver to stop checking the data ready bit in the * line status register. */ info->read_status_mask &= ~UART_LSR_DR; if (info->flags & ASYNC_INITIALIZED) { /* disable receive interrupts */ custom.intena = IF_RBF; mb(); /* clear any pending receive interrupt */ custom.intreq = IF_RBF; mb(); /* * Before we drop DTR, make sure the UART transmitter * has completely drained; this is especially * important if there is a transmit FIFO! */ rs_wait_until_sent(tty, info->timeout); } shutdown(info); rs_flush_buffer(tty); tty_ldisc_flush(tty); tty->closing = 0; info->event = 0; info->tty = NULL; if (info->blocked_open) { if (info->close_delay) { msleep_interruptible(jiffies_to_msecs(info->close_delay)); } wake_up_interruptible(&info->open_wait); } info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); wake_up_interruptible(&info->close_wait); local_irq_restore(flags); }