本文共 2712 字,大约阅读时间需要 9 分钟。
tty_open
-> if (tty) { retval = tty_reopen(tty);}
->
static int tty_reopen(struct tty_struct *tty)
{ struct tty_driver *driver = tty->driver; if (test_bit(TTY_CLOSING, &tty->flags) || test_bit(TTY_HUPPING, &tty->flags) || test_bit(TTY_LDISC_CHANGING, &tty->flags)) return -EIO; if (driver->type == TTY_DRIVER_TYPE_PTY && driver->subtype == PTY_TYPE_MASTER) { /* * special case for PTY masters: only one open permitted, * and the slave side open count is incremented as well. */ if (tty->count) return -EIO; tty->link->count++; } tty->count++; mutex_lock(&tty->ldisc_mutex); WARN_ON(!test_bit(TTY_LDISC, &tty->flags)); mutex_unlock(&tty->ldisc_mutex); return 0; } /*---------------------------------------------------------------------------*/ static void smd_ch_irq_tasklet_handler(unsigned long data) { unsigned char *ptr; int avail; struct tty_struct *tty; int index=data; unsigned long flags; struct smd_tty_info *tty_info = &driver_info->smd_tty[index]; dbg("enter %s\n",__func__); spin_lock_irqsave(&driver_info->lock, flags); tty = tty_port_tty_get(&tty_info->port); if (!tty){ spin_unlock_irqrestore(&driver_info->lock, flags); return; } avail = smd_stream_read_avail(tty_info->ch); if (!avail){ spin_unlock_irqrestore(&driver_info->lock, flags); return; } avail = tty_prepare_flip_string(tty, &ptr, avail); if(!avail){ spin_unlock_irqrestore(&driver_info->lock, flags); pr_err("smd_ch_irq_tasklet_handler: cannot get space from tty_buffer!\n"); return; } smd_stream_read(tty_info->ch,ptr,avail); smd_send_intr(tty_info->a2b_int_rx); tty_flip_buffer_push(tty); tty_kref_put(tty); spin_unlock_irqrestore(&driver_info->lock, flags); } 更改为: /*---------------------------------------------------------------------------*/ static void smd_ch_irq_tasklet_handler(unsigned long data) { unsigned char *ptr; int avail; struct tty_struct *tty; int index=data; unsigned long flags; struct smd_tty_info *tty_info = &driver_info->smd_tty[index]; dbg("enter %s\n",__func__); spin_lock_irqsave(&driver_info->lock, flags); tty = tty_port_tty_get(&tty_info->port); if (!tty){ spin_unlock_irqrestore(&driver_info->lock, flags); return; } avail = smd_stream_read_avail(tty_info->ch); if (!avail){ tty_kref_put(tty); spin_unlock_irqrestore(&driver_info->lock, flags); return; } avail = tty_prepare_flip_string(tty, &ptr, avail); if(!avail){ tty_kref_put(tty); spin_unlock_irqrestore(&driver_info->lock, flags); pr_err("smd_ch_irq_tasklet_handler: cannot get space from tty_buffer!\n"); return; } smd_stream_read(tty_info->ch,ptr,avail); smd_send_intr(tty_info->a2b_int_rx); tty_flip_buffer_push(tty); tty_kref_put(tty); spin_unlock_irqrestore(&driver_info->lock, flags); } 就是说tty_port_tty_get和tty_kref_put没有成对出现具体的原因,有时间在填上。
转载地址:http://kekzk.baihongyu.com/