linux usb总线状态,Linux下的USB总线驱动

static int skel_do_read_io(struct usb_skel *dev, size_t count)

{

int rv;

usb_fill_bulk_urb(dev->bulk_in_urb,dev->udev,usb_rcvbulkpipe(dev->udev,

dev->bulk_in_endpointAddr),dev->bulk_in_buffer,

min(dev->bulk_in_size, count),skel_read_bulk_callback,dev); //填充urb

spin_lock_irq(&dev->err_lock);

dev->ongoing_read = 1;  //标志正在读取数据中

spin_unlock_irq(&dev->err_lock);

rv = usb_submit_urb(dev->bulk_in_urb, GFP_KERNEL);  //提交urb

if (rv < 0) {

err("%s - failed submitting read urb, error %d",

__func__, rv);

dev->bulk_in_filled = 0;

rv = (rv == -ENOMEM) ? rv : -EIO;

spin_lock_irq(&dev->err_lock);

dev->ongoing_read = 0;

spin_unlock_irq(&dev->err_lock);

}

return rv;

}

好了,其实skel_do_read_io只是完成了urb的填充和提交,USB核心读取到了数据后,会调用填充urb时设置的回调函数skel_read_bulk_callback。

static void skel_read_bulk_callback(struct urb *urb)

{

struct usb_skel *dev;

dev = urb->context;

spin_lock(&dev->err_lock);

if (urb->status) {          //根据返回状态判断是否出错

if (!(urb->status == -ENOENT ||

urb->status == -ECONNRESET ||

urb->status == -ESHUTDOWN))

err("%s - nonzero write bulk status received: %d",

__func__, urb->status);

dev->errors = urb->status;

} else {

dev->bulk_in_filled = urb->actual_length;  //记录缓冲区的大小

}

dev->ongoing_read = 0;    //已经读取数据完毕

spin_unlock(&dev->err_lock);

complete(&dev->bulk_in_completion);  //唤醒skel_read函数

}

好了,到目前为止,我们已经把USB驱动框架usb-skeleton.c分析完了,总结下,其实很简单,在模块加载里面注册usb_driver,然后在probe函数里初始化一些参数,最重要的是注册了USB设备,这个USB设备相当于一个字符设备,提供file_operations接口。然后设计open,close,read,write函数,这个open里基本没做什么事情,在write中,通过分配urb、填充urb和提交urb。注意读的urb的分配在probe里申请空间,写的urb的分配在write里申请空间。在这个驱动程序中,我们重点掌握usb_fill_bulk_urb的设计。0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值