我正在用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端点的传入字节。或什么是最好的解决方案。
感谢您的帮助和时间。如果您需要,我可以为您提供更多信息