刷新USB驱动程序中中断端点上的传入字节

时间:2018-08-09 04:27:25

标签: linux linux-kernel usb linux-device-driver flush

我正在用Linux编写USB驱动程序。小工具上有两个中断端点。

以下是数据包格式:

|===========================================================
|  RequestId  ||  RequestId  ||  Command    ||  Data...    |
|   Lsb       ||   Msb       ||             ||             |
|===========================================================

我正在通过OUT中断端点传输命令和数据

unsigned short request_id = (unsigned short)(jiffies & 0xFFFF);
((struct out_request_header *)dev->interrupt_out_buffer)->request_id = request_id;
((struct out_request_header *)dev->interrupt_out_buffer)->command = command;
buffer_index = sizeof(struct out_request_header);
for (i = 0; (i < request_buffer_length) &&
                (buffer_index < dev->interrupt_out_endpoint_size-1);)
    dev->interrupt_out_buffer[buffer_index++] =
            ((unsigned char *)request_buffer)[i++];

usb_fill_int_urb(dev->interrupt_out_urb,
        dev->usb_dev,
        usb_sndintpipe(dev->usb_dev,
            dev->interrupt_out_endpoint->bEndpointAddress),
        dev->interrupt_out_buffer,
        buffer_index,
        mib_usb_interrupt_out_callback,
        dev,
        dev->interrupt_out_interval);

dev->interrupt_out_busy = 1;
retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL);

if (retval) {
        dev_err(&dev->interface->dev, "%s: Error:%d while submitting OUT URB\n",
                __func__, retval);
        goto lbl_cf_send_protocol_command_end;
    }

retval = wait_event_interruptible(dev->write_wait, !dev->interrupt_out_busy);

if (retval < 0)
    goto lbl_cf_send_protocol_command_end;

if (dev->error) {
    retval = dev->error;
    dev_err(&dev->interface->dev, "%s:Error:%d after Transmitting OUT URB\n"
            , __func__, retval);
    goto lbl_cf_send_protocol_command_end;
}

//
// Do a check on the bytes written, not sure if there is much of a way
// for this to fail and the write to succeed
//
if (buffer_index != dev->bulk_out_transmitted) {
    dev_err(&dev->interface->dev, "%s: Bytes Written %02x does not match"
            " requested bytes written:%02x\n",__func__, buffer_index,
            dev->bulk_out_transmitted);
    retval = -EINVAL;
    goto lbl_cf_send_protocol_command_end;

}

此后,我正在通过IN端点读取小工具设备的响应。

usb_fill_int_urb(dev->interrupt_in_urb,
            dev->usb_dev,
            usb_rcvintpipe(dev->usb_dev,
                dev->interrupt_in_endpoint->bEndpointAddress),
            dev->interrupt_in_buffer,
            dev->interrupt_in_endpoint_size,
            mib_usb_interrupt_in_callback,
            dev,
            dev->interrupt_in_interval);

    dev->interrupt_in_running = 1;
    dev->interrupt_in_done = 0;

    retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
    if (retval) {
        dev_err(&dev->interface->dev, "%s:Failed to submit IN urb,"
                "retval:%d\n", __func__, retval);
        goto lbl_cf_send_protocol_command_end;
    }

    retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done);

    if (retval)
        goto lbl_cf_send_protocol_command_end;

    if (dev->error) {
        retval = dev->error;
        dev_err(&dev->interface->dev, "%s:Error:%d after Transmitting OUT URB\n"
                , __func__, retval);
        goto lbl_cf_send_protocol_command_end;
    }

我面临的问题是,有时由于某些原因,OUT中断通信失败,例如,我无法发送正确的字节数或任何其他原因。.在这种情况下,我只是从函数中退出无需从IN端点读取任何内容。

lbl_cf_send_protocol_command_end:
    if (mutex_is_locked(&dev->command_mutex))
        mutex_unlock(&dev->command_mutex);
    return retval;

现在,当我发送下一个数据包时,我会收到请求ID不匹配的消息,这意味着该小工具正在发送旧的IN数据包,由于OUT中断端点通信期间发生错误,我没有读过。.

在中断OUT端点发生错误的情况下,是否有任何方法可以刷新中断IN端点的传入字节。或什么是最好的解决方案。

感谢您的帮助和时间。如果您需要,我可以为您提供更多信息

0 个答案:

没有答案