处理Linux驱动程序上未连接的USB电缆

时间:2015-04-20 13:59:46

标签: c linux kernel usb driver

我需要什么: 基于usb的通信设备,从嵌入式目标(运行linux)到主机(运行Windows)

我有什么: 一个基于社区驱动程序的tty设备(u_serial.c,f_acm.c)和一个利用open / close / write / read命令的用户空间程序。

问题: 即使没有连接USB电缆,用户空间守护程序也会成功打开tty设备并从中读取。如果在发生这种情况时连接usb电缆 - 所有usb枚举都被保持,直到我取消程序(取消read(),即)。 当tty仅为open()ed而没有read()时,会发生相同的行为。

我看到了什么: 我的设备的open()函数定义为u_serial.c open()。 它看起来像这样:

static int gs_open(struct tty_struct *tty, struct file *file)
{
/*
 *definitions
 */

/*
 *basic error checks
 */

//check if the tty device is already open/not opened/currently being opened and deal with each
//if not open:
//<real code starts:>

/* Do the "real open" */
spin_lock_irq(&port->port_lock);

/* allocate circular buffer on first open */
if (port->port_write_buf.buf_buf == NULL) {

    spin_unlock_irq(&port->port_lock);
    status = gs_buf_alloc(&port->port_write_buf, WRITE_BUF_SIZE);
    spin_lock_irq(&port->port_lock);

    if (status) {
        pr_debug("gs_open: ttyGS%d (%p,%p) no buffer\n",
            port->port_num, tty, file);
        port->openclose = false;
        goto exit_unlock_port;
    }
}


tty->driver_data = port;
port->port_tty = tty;

port->open_count = 1;
port->openclose = false;


/* if connected, start the I/O stream */
if (port->port_usb) {
    struct gserial  *gser = port->port_usb;

    pr_debug("gs_open: start ttyGS%d\n", port->port_num);
    gs_start_io(port);

    if (gser->connect)
        gser->connect(gser);
}

pr_debug("gs_open: ttyGS%d (%p,%p)\n", port->port_num, tty, file);

status = 0;

exit_unlock_port:
spin_unlock_irq(&port->port_lock);
return status;
}

删除了一些不相关的代码。见来源here

请注意,即使usb没有连接(port-&gt; port_usb为0) - 我们继续并返回0,这意味着一切正常。 另请注意,如果未连接usb,我们不会执行gs_start_io(),它用于从设备进行实际读取,仅在连接usb时才有效。

这里有一个问题 - 如果内核是在open()命令没有错误的情况下构建的,而usb cable没有连接 - 为什么当我有一个开放的描述符到设备时它保持? 我会假设它无法在第一时间打开设备,或者忽略这种情况并继续正常连接USB连接。 另外,如果这是正确的行为 - 我如何处理/知道电缆是否断开?

几年前,here进行了类似的讨论,没有真正的结论。

最后的想法 - 如果在连接usb时会通知用户空间程序,可以解决这个问题,但这并不意味着当前的行为是正确的。

感谢。

0 个答案:

没有答案