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没有成对出现
具体的原因,有时间在填上。