先从初始化开始
__init hci_uart_init(void)
{
…… //注册ldisc
hci_uart_ldisc.magic
= TTY_LDISC_MAGIC; //通过i = N_HCI; if (ioctl(fd,
TIOCSETD, &i) < 0)获得
hci_uart_ldisc.name
= "n_hci";
hci_uart_ldisc.open
= hci_uart_tty_open;
hci_uart_ldisc.close
= hci_uart_tty_close;
hci_uart_ldisc.read
= hci_uart_tty_read;
hci_uart_ldisc.write
= hci_uart_tty_write;
hci_uart_ldisc.ioctl
= hci_uart_tty_ioctl;
hci_uart_ldisc.poll
= hci_uart_tty_poll;
hci_uart_ldisc.receive_buf
= hci_uart_tty_receive;
hci_uart_ldisc.write_wakeup
= hci_uart_tty_wakeup; //
ldisc对应的处理函数
hci_uart_ldisc.owner
= THIS_MODULE;
……
if ((err =
tty_register_ldisc(N_HCI, &hci_uart_ldisc)))
……
bcsp_init(); //取决于hciattach中选择的uart[]
……
}
源码在/drivers/char/tty_io.c
int tty_register_ldisc(int disc, struct
tty_ldisc *new_ldisc)
{
unsigned long flags;
int ret = 0;
if (disc < N_TTY || disc >=
NR_LDISCS)
return -EINVAL;
spin_lock_irqsave(&tty_ldisc_lock, flags);
tty_ldiscs[disc] = *new_ldisc;
tty_ldiscs[disc].num = disc;
tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED;
tty_ldiscs[disc].refcount = 0;
spin_unlock_irqrestore(&tty_ldisc_lock, flags);
return ret;
}
/* Line disc dispatch table */
static struct tty_ldisc tty_ldiscs[NR_LDISCS];
bcsp_init()--> hci_uart_register_proto(&bcsp); //注册proto操作函数
{
if (p->id >= HCI_UART_MAX_PROTO)
return -EINVAL;
if (hup[p->id])
return -EEXIST;
hup[p->id] = p; //static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO];
return 0;
}
struct
hci_uart_proto {
unsigned int id;
int (*open)(struct hci_uart *hu);
int (*close)(struct hci_uart *hu);
int (*flush)(struct hci_uart *hu);
int (*recv)(struct hci_uart *hu, void *data, int len);
int (*enqueue)(struct hci_uart *hu, struct sk_buff *skb);
struct sk_buff *(*dequeue)(struct hci_uart *hu);
};
struct
hci_uart {
struct tty_struct
*tty;
struct hci_dev
*hdev;
unsigned long
flags;
unsigned long
hdev_flags;
struct hci_uart_proto
*proto;
void
*priv;
struct sk_buff
*tx_skb;
unsigned long
tx_state;
spinlock_t
rx_lock;
};