ChinaUnix.net 首页 | 博客 | Linux | 论坛 | 人才 | 培训 | 知识库 | 资料 | 读书 | 手册 | 精华 | 下载 | 沙龙 | 搜索
Linux首页 | Linux论坛 | 论坛精华 | 开源新闻 | 技术文章 | 专题专栏 | 新手指南 | 迁移方案 | 产品方案 | 开源项目 | 开源图书 | 软件下载 | 人才招聘 | Linux博客
  搜索

  产品与方案
·中科红旗全面打造现代化邮政体系
·红旗助力“网上审批服务” 推动电子政务
·红旗正版化开创呼和浩特网吧建设新起点
·红旗Linux助信息产业部邮件服务器“快跑”
·中标普华Linux 为电子政务信息化保驾护航
·中标普华Linux助力基金产业
·中标普华Office率先支持UOF标准
·中标普华邮件系统助力西藏政府信息化建设
·红旗Linux助力国库集中支付系统改革
·红旗助中信卫星 掀起GIS通信应用风暴
·红旗软件助力烟草总局 全面建设“数字烟草”
·红旗助力“信访阳光工程”打造畅通信访渠道
·红帽联合FIS发布下一代实时核心银行平台
·红旗助力金盾 打造全无忧出入境信息系统
·红旗Linux全力打造中国邮政总局名址信息库
·爱尔兰证交所从Unix迁移到红帽企业Linux
·一流的意大利银行选择使用红帽企业Linux
·PLUS Finanzservice选择使用红帽企业Linux
·红帽助力TransACT Communications 公司
·法国零售业巨头Lapeyre采用Redhat Linux
·旅游预订网站选择使用红帽企业Linux
·马哈拉施特拉邦政府的红帽解决之道
·美国联邦政府案例
·红帽为慕尼黑展览会提供现代化集群系统
·Yuba郡用开源软件和红帽产品提高了效率
·红帽企业Linux助印度理工建立高性能计算中心
·采用红帽Linux 将系统维护时间缩短了65%
·从UNIX迁移到Linux使Peñoles公司获益非浅
·Hikal公司用红帽企业Linux开展任务关键的ERP项目
·KDE3.5.4新版本发布
·芝加哥商业交易所从Unix向Linux迁移
·南方基金管理有限公司成功案例 Red Hat Linux
·广东北电通讯设备有限公司成功案例
·挪威国家石油公司从UNIX迁移到红帽Linux,成本减半
·中央电视台CCTV动画部案例 Red Hat Linux

  图书

鸟哥的Linux私房菜基础学..


Linux程序设计.第3版


Linux设备驱动开发详解


  下载
·Endian Firewall
·linux kernel(Linux 内核)
·CentOS
·Fedora Core 6
·Scientific Linux
·Slackware 11.0
·Gentoo Linux
·ubuntu-6.10-i386服务器版本
·ubuntu-6.10-amd64服务器版
·ubuntu-6.10-i386桌面版
·ubuntu-6.10-amd64桌面版
·Engarde Linux
您的位置: Linux时代 > 技术文档 > 程序开发 >

Linux环境下如何设置USB驱动程序(3)

日期:2007-09-20 作者:中科红旗 梁国军 来自:linux.chinaunix.net


  for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {

  endpoint = &iface_desc->endpoint[i].desc;

  if (!dev->bulk_in_endpointAddr &&

  (endpoint->bEndpointAddress & USB_DIR_IN) &&

  ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)

  == USB_ENDPOINT_XFER_BULK)) {

  /* 找到一个批量IN端点 */

  buffer_size = endpoint->wMaxPacketSize;

  dev->bulk_in_size = buffer_size;

  dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;

  dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);

  if (!dev->bulk_in_buffer) {

  err("Could not allocate bulk_in_buffer");

  goto error;

  }

  }

  if (!dev->bulk_out_endpointAddr &&

  !(endpoint->bEndpointAddress & USB_DIR_IN) &&

  ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)

  == USB_ENDPOINT_XFER_BULK)) {

  /* 找到一个批量OUT端点 */

  dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;

  }

  }

  if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {

  err("Could not find both bulk-in and bulk-out endpoints");

  goto error;

  }

  在探测函数里,这个循环首先访问该接口中存在的每一个端点,给该端点一个局部指针以便以后访问:

  for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {

  endpoint = &iface_desc->endpoint[i].desc;

  在一轮探测过后,我们就有了一个端点,在还没有发现批量IN类型的端点时,探测该端点方向是否为IN,这可以通过检查USB_DIR_IN是否包含在bEndpointAddress端点变量有确定,如果是的话,我们在探测该端点类型是否为批量,先用USB_ENDPOINT_XFERTYPE_MASK位掩来取bmAttributes变量的值,然后探测它是否和USB_ENDPOINT_XFER_BULK值匹配:

  if (!dev->bulk_out_endpointAddr &&

  !(endpoint->bEndpointAddress & USB_DIR_IN) &&

  ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)

  == USB_ENDPOINT_XFER_BULK))

  如果所有这些探测都通过了,驱动程序就知道它已经发现了正确的端点类型,可以把该端点的相关信息保存到一个局部结构体中以便稍后用它来和端点进行通信:

  /* 找到一个批量IN类型的端点 */

  buffer_size = endpoint->wMaxPacketSize;

  dev->bulk_in_size = buffer_size;

  dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;

  dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);

  if (!dev->bulk_in_buffer) {

  err("Could not allocate bulk_in_buffer");

  goto error;

  }

  因为USB驱动程序要在设备的生命周期的稍后时间获取和接口相关联的局部数据结构体,所以调用了usb_set_intfdata函数,把它保存到struct usb_interface结构体中以便后面的访问

  /* 把数据指针保存到这个接口设备中 */

  usb_set_intfdata(interface, dev);

  我们以后调用usb_set_intfdata函数来获取数据。当这一切都完成后,USB驱动程序必须在探测函数中调用usb_register_dev函数来把该设备注册到USB核心里:

  /* 注册设备到USB核心 */

  retval = usb_register_dev(interface, &skel_class);

  if (retval) {

  /* 有些情况下是不允许注册驱动程序的 */

  err("Not able to get a minor for this device.");

  usb_set_intfdata(interface, NULL);

  goto error;

  }

  当一个USB设备被断开时,和该设备相关联的所有资源都应该被尽可能的清理掉,在此时,如果已在在探测函数中调用了注册函数来为该USB设备分配了一个次设备号话,必须调用usb_deregister_dev函数来把次设备号交还给USB核心。在断开函数中,从接口获取之前调用usb_set_intfdata设置的任何数据也是很重要的。然后设置struct usb_interface结构体中的数据指针为NULL,以防任何不适当的对该数据的错误访问。

  在探测函数中会对每一个接口进行一次探测,所以我们在写USB驱动程序的时候,只要做好第一个端点,其它的端点就会自动完成探测。在探测函数中我们要注意的是在内核中用结构体struct usb_host_endpoint来描述USB端点,这个结构体在另一个名为struct usb_endpoint_descriptor的结构体中包含了真正的端点信息,struct usb_endpoint_descriptor结构体包含了所有的USB特定的数据,该结构体中我们要关心的几个字段是:

本文被浏览



 相关新闻



 相关评论
关于我们 | 联系方式 | 广告合作 | 诚聘英才 | 网站地图 | 免费注册

Copyright © 2001-2006 ChinaUnix.net All Rights Reserved

感谢所有关心和支持过ChinaUnix的朋友们

京ICP证041476号