精华内容
下载资源
问答
  • usb设备无法启动,Windows 没有启动相关的设备驱动程序 用户电脑问题: 用户电脑的usb每次只要重启就会出问题,具体就是开机后所有的usb设备us
    原文地址为:
    usb设备无法启动,Windows 没有启动相关的设备驱动程序
    

    usb设备无法启动,Windows 没有启动相关的设备驱动程序

    用户电脑问题:

     

      用户电脑的usb每次只要重启就会出问题,具体就是开机后所有的usb设备usb鼠标和u盘等,在设备管理器中查看就是每个usb设备前面都有一个感叹号。如果把设备禁用再启用就可以使用了。在其他系统中可以正常使用usb设备因此可以基本排除是硬件的问题。

     

    思路:首先想到的是注册表问题

     

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class,一个一个的点开,看右边有没有“通用串行总线控制器”这些文字,在右面窗口找到“upperfilter”项或“lowerfilter”项,删除,然后进入设备管理器中把通用串行总线控制器下面的所有带叹号的设备都卸载掉。在设备管理器的菜单中,点“操作”-“扫描检测硬件改动”,让系统自动重装一下驱动.重启之后问题依旧,询问用户之前做过什么操作,用户说做过量产,之后找到解决办法

     

     

    解决方案:


    1、传输文件c:\windows\inf\usbstor.inf,再右键点击选择安装生成一个,usbstor.PNF(应该是即插即用驱动)的文件后即可使用。

    2、在本机的inf目录下有个名为usbstor.ibk的文件是usbstor.inf的备份,改一下名字就可以了,然后重复上述的安装步骤。


    转载请注明本文地址: usb设备无法启动,Windows 没有启动相关的设备驱动程序
    展开全文
  • 高通9008设备驱动程序

    2019-01-26 03:31:22
    我上传的这个驱动程序是高通签名过的,不需要进入“禁用驱动程序签名强制”模式即可正常识别9008设备。 没安装高通驱动之前的9008设备名称为“QHSUSB_DLOAD”,并且有感叹号。安装了高通驱动之后,之前的“QHSUSB_...
  • libwdi, USB设备的Windows 驱动程序安装程序库 libwdi: 用于USB设备的Windows 驱动程序安装库 的主要功能自动创建信息,使用报告的USB设备名称自动编录文件创建和签名,使用自动生成的证书用于 32位和 64位平台的...
  • USB设备驱动程序-USB Gadget Driver

    千次阅读 2017-01-03 08:42:55
    USB设备驱动程序-USB Gadget Driver(三) 4680阅读 0评论2013-10-10 visualfan 分类:LINUX Gadget设备层  这一层是可选的,介于UDC驱动层和Gadget功能层之间。主要源码在composite.c和composite.h文件...

    USB设备驱动程序-USB Gadget Driver(三)

    4680阅读 0评论2013-10-10 visualfan
    分类:LINUX

    Gadget设备层

           这一层是可选的,介于UDC驱动层和Gadget功能层之间。主要源码在composite.c和composite.h文件中,设备层其实和硬件无关,主要实现一些通用性的代码,减少gadget功能层的代码重复工作。Gadget设备层其中承上启下的作用,联系Gadget功能层和UDC驱动层。

           将composite源码独立出来,还为复合设备的实现提供了一个通用性的框架。复合设备是指在一个配置描述符中支持多个功能,或者支持多个配置的设备中,每个配置都有一个不同的功能。如一个设备同时支持网络和存储,一个设备同时支持键盘和鼠标功能等。

    Gadget设备层的主要数据结构:

    1. Function

    struct usb_function { //描述一个配置的一个功能

                                        const char *name; //功能名称

                                        struct usb_gadget_strings **strings; //string数组,通过bind中分配的id访问

                                        struct usb_descriptor_header **descriptors; //全速和低速的描述符表,用于bind中分配的接口描述符和string描述符

                                        struct usb_descriptor_header **hs_descriptors; //高速描述符表

                                         struct usb_configuration *config;//调用usb_add_function()函数赋值,是这个功能关联的配置描述符

                                       /* REVISIT: bind() functions can be marked __init, which

                                         * makes trouble for section mismatch analysis. See if

                                         * we can't restructure things to avoid mismatching.

                                         * Related: unbind() may kfree() but bind() won't...

                                        */

                                        /* configuration management: bind/unbind */

                                         /*在Gadget注册时,分配资源*/

                                       int (*bind)(struct usb_configuration *, struct usb_function *);

                                        /*unbind的逆操作*/

                                        void (*unbind)(struct usb_configuration *, struct usb_function *);

                                       /* runtime state management */

                                       /*重新配置altsetting,*/

                                       int (*set_alt)(struct usb_function *,unsigned interface, unsigned alt);

                                       /*获取当前altsetting*/

                                       int (*get_alt)(struct usb_function *, unsigned interface);

                                         /*关闭功能*/

                                         void (*disable)(struct usb_function *);

                                         /*接口相关的控制处理*/

                                        int (*setup)(struct usb_function *, const struct usb_ctrlrequest *);

                                        /*电源管理相关的挂起和恢复功能*/

                                        void (*suspend)(struct usb_function *);

                                        void (*resume)(struct usb_function *);

                                       /* private: */

                                      /* internals */

                                        struct list_head list;

                                         DECLARE_BITMAP(endpoints, 32);

    };

    2. Config

    struct usb_configuration { //表示一个Gadget配置

                                                  const char *label; //配置名称

                                       struct usb_gadget_strings **strings; //字符串表

                                        const struct usb_descriptor_header **descriptors; //功能描述符表

                                          /* REVISIT: bind() functions can be marked __init, which

                                            * makes trouble for section mismatch analysis. See if

                                             * we can't restructure things to avoid mismatching...

                                           */

                                           /* configuration management: bind/unbind */

                                           /*在usb_add_config函数中调用,分配资源等*/

                                            int (*bind)(struct usb_configuration *);

                                            void (*unbind)(struct usb_configuration *);

                                         /*处理驱动框架不能处理的配置控制请求*/

                                              int (*setup)(struct usb_configuration *, const struct usb_ctrlrequest *);

                                         /* fields in the config descriptor */

                                         /*用来赋值配置描述符*/

                                          u8 bConfigurationValue;

                                           u8 iConfiguration;

                                           u8 bmAttributes;

                                           u8 bMaxPower;

                                       /*和composite设备关联,在usb_add_config函数中设置*/

                                          struct usb_composite_dev *cdev;

                                       /* private: */

                                        /* internals */

                                           struct list_head list;

                                            struct list_head functions; //功能链表

                                            u8 next_interface_id;

                                            unsigned highspeed:1;

                                             unsigned fullspeed:1;

                                              struct usb_function *interface[MAX_CONFIG_INTERFACES];

    };

    3. Driver

    struct usb_composite_driver {

                                                      const char *name; //驱动名称

                                                      const struct usb_device_descriptor *dev; //设备描述符

                                                      struct usb_gadget_strings **strings; //字符串表

                                                       /* REVISIT: bind() functions can be marked __init, which

                                                        * makes trouble for section mismatch analysis. See if

                                                        * we can't restructure things to avoid mismatching...

                                                         */

                                                      int (*bind)(struct usb_composite_dev *);

                                                      int (*unbind)(struct usb_composite_dev *);

                                                      /* global suspend hooks */

                                                     void (*suspend)(struct usb_composite_dev *);

                                                     void (*resume)(struct usb_composite_dev *);

    };

    4. Dev

    struct usb_composite_dev { //表示一个composite设备

                                                 struct usb_gadget *gadget; //关联的gadget

                                                 struct usb_request *req; //用于控制响应,提前分配的

                                                  unsigned bufsiz; //req中提前分配的buffer长度

                                                 struct usb_configuration *config; //当前配置

                                                            /* private: */

                                                  /* internals */

                                                struct usb_device_descriptor desc;

                                                struct list_head configs; //配置链表

                                                 struct usb_composite_driver *driver;

                                                  u8 next_string_id;

                                               /* the gadget driver won't enable the data pullup

                                                 * while the deactivation count is nonzero.

                                                */

                                                 unsigned deactivations;

                                                 /* protects at least deactivation count */

                                                spinlock_t lock;

    };

    其中重要的函数:

    1.

    static int __init composite_bind(struct usb_gadget *gadget)

    {

              struct usb_composite_dev *cdev;

               int status = -ENOMEM;

               cdev = kzalloc(sizeof *cdev, GFP_KERNEL); //分配一个composite设备对象

               if (!cdev)

                             return status;

                spin_lock_init(&cdev->lock);

                /*将udc gadget和composite设备建立关系*/

                 cdev->gadget = gadget;

                set_gadget_data(gadget, cdev);

                 INIT_LIST_HEAD(&cdev->configs); //初始化配置链表

                   /* preallocate control response and buffer */

                  /*分配控制端点的请求数据结构和缓存区*/

                 cdev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL);

                 if (!cdev->req)

                                          goto fail;

                 cdev->req->buf = kmalloc(USB_BUFSIZ, GFP_KERNEL); //分配控制请求的缓冲区

                if (!cdev->req->buf)

                                          goto fail;

                 cdev->req->complete = composite_setup_complete; //端的0的完成函数

                 gadget->ep0->driver_data = cdev;

                  cdev->bufsiz = USB_BUFSIZ;

                   cdev->driver = composite;

               /*设置gadget的供电模式*/

                usb_gadget_set_selfpowered(gadget);

              /* interface and string IDs start at zero via kzalloc.

               * we force endpoints to start unassigned; few controller

               * drivers will zero ep->driver_data.

               */

               /*将所有端点的driver_data成员清零*/

                usb_ep_autoconfig_reset(cdev->gadget);

             /* composite gadget needs to assign strings for whole device (like

               * serial number), register function drivers, potentially update

               * power state and consumption, etc

              */

             /*调用功能层提供的bind函数,分配资源*/

             status = composite->bind(cdev);

             if (status < 0)

                              goto fail;

              /*设置composite设备的设备描述符*/

              cdev->desc = *composite->dev;

               cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket;

              /* standardized runtime overrides for device ID data */

              /*设置composite设备的设备描述符信息*/

             if (idVendor)

                            cdev->desc.idVendor = cpu_to_le16(idVendor);

             if (idProduct)

                           cdev->desc.idProduct = cpu_to_le16(idProduct);

            if (bcdDevice)

                           cdev->desc.bcdDevice = cpu_to_le16(bcdDevice);

             /* strings can't be assigned before bind() allocates the

              * releavnt identifiers

              */

              /*设置字符串描述符*/

            if (cdev->desc.iManufacturer && iManufacturer)

                              string_override(composite->strings, cdev->desc.iManufacturer, iManufacturer);

           if (cdev->desc.iProduct && iProduct)

                             string_override(composite->strings, cdev->desc.iProduct, iProduct);

          if (cdev->desc.iSerialNumber && iSerialNumber)

                              string_override(composite->strings, cdev->desc.iSerialNumber, iSerialNumber);

             INFO(cdev, "%s ready\n", composite->name);

              return 0;

    fail:

                   composite_unbind(gadget);

                  return status;

    }

    Composite_bind函数主要完成UDC驱动层gadget设备和设备层composite设备关系的建立,分配控制端点0的请求数据结构,设置设备描述符,并调用功能层的bind函数分配功能层所需要的资源等工作。

    2.

    static void /* __init_or_exit */ composite_unbind(struct usb_gadget *gadget)

    {

                      struct usb_composite_dev *cdev = get_gadget_data(gadget);

                                 /* composite_disconnect() must already have been called

                        * by the underlying peripheral controller driver!

                         * so there's no i/o concurrency that could affect the

                         * state protected by cdev->lock.

                        */

                        WARN_ON(cdev->config);

                       while ( !list_empty(&cdev->configs)) { //遍历设备的配置链表

                                          struct usb_configuration *c;

                                          c = list_first_entry(&cdev->configs, struct usb_configuration, list);

                                          while (!list_empty(&c->functions)) { //遍历这个配置下的所有功能

                                                                 struct usb_function *f;

                                                                  f = list_first_entry(&c->functions, struct usb_function, list);

                                                                   list_del(&f->list);

                                                                  if (f->unbind) { //调用功能的unbind函数

                                                                                         DBG(cdev, "unbind function '%s'/%p\n", f->name, f);

                                                                                         f->unbind(c, f);

                                                                                         /* may free memory for "f" */

                                                                    }

                                             }

                                            list_del(&c->list);

                                            if (c->unbind) { //调用配置的unbind函数

                                                                DBG(cdev, "unbind config '%s'/%p\n", c->label, c);

                                                                          c->unbind(c);

                                                                /* may free memory for "c" */

                                              }

                       }

                      if (composite->unbind) //调用功能驱动的unbind函数

                                      composite->unbind(cdev);

                     if (cdev->req) { //释放分配的控制请求的缓存区

                                     kfree(cdev->req->buf);

                                    usb_ep_free_request(gadget->ep0, cdev->req);

                     }

                    kfree(cdev); //释放composite设备

                    set_gadget_data(gadget, NULL);

                    composite = NULL;

    }

    Unbind函数完成bind函数中分配的资源,并遍历所有配置和各个配置下的功能,调用其对应得unbind函数来释放资源。

    其他重要函数:

    在配置中增加一个功能,每个配置初始化后都必须至少有一个功能。

    int __init usb_add_function(struct usb_configuration *config, struct usb_function *function)

    {

                     int value = -EINVAL;

                      DBG(config->cdev, "adding '%s'/%p to config '%s'/%p\n",function->name, function,config->label, config);

                      if (!function->set_alt || !function->disable)

                                               goto done;

                      /*设置功能所属配置,并将功能加入配置的链表中*/

                       function->config = config;

                       list_add_tail(&function->list, &config->functions);

                       /* REVISIT *require* function->bind? */

                       if (function->bind) { //调用功能的bind函数

                                                      value = function->bind(config, function); //分配这个功能所需要的资源

                                                       if (value < 0) {

                                                                             list_del(&function->list);

                                                                             function->config = NULL;

                                                       }

                        }

                        else

                                         value = 0;

                       /* We allow configurations that don't work at both speeds.

                         * If we run into a lowspeed Linux system, treat it the same

                         * as full speed ... it's the function drivers that will need

                         * to avoid bulk and ISO transfers.

                          */

                       if (!config->fullspeed && function->descriptors)

                                                       config->fullspeed = true;

                        if (!config->highspeed && function->hs_descriptors)

                                                     config->highspeed = true;

             done:

                       if (value)

                                    DBG(config->cdev, "adding '%s'/%p --> %d\n", function->name, function, value);

                      return value;

    }

    /*为设备增加一个配置,这个实现原理和在配置下增加一个功能类似*/

    int __init usb_add_config(struct usb_composite_dev *cdev, struct usb_configuration *config)

    {

                     int status = -EINVAL;

                      struct usb_configuration *c;

                      DBG(cdev, "adding config #%u '%s'/%p\n", config->bConfigurationValue, config->label, config);

                      if (!config->bConfigurationValue || !config->bind)

                                                goto done;

                         /* Prevent duplicate configuration identifiers */

                             list_for_each_entry(c, &cdev->configs, list) { //若配置已经加入了,则不需要再加

                                                     if (c->bConfigurationValue == config->bConfigurationValue) {

                                                                                        status = -EBUSY;

                                                                                         goto done;

                                                     }

                                }

                            /*将这个配置加入composite设备*/

                             config->cdev = cdev;

                             list_add_tail(&config->list, &cdev->configs);

                             /*初始化这个配置的功能链表头*/

                             INIT_LIST_HEAD(&config->functions);

                             config->next_interface_id = 0;

                              status = config->bind(config); //完成这个配置的资源分配

                               if (status < 0) {

                                                           list_del(&config->list);

                                                          config->cdev = NULL;

                                }

                                else

                                {

                                                          unsigned i;

                                                          DBG(cdev, "cfg %d/%p speeds:%s%s\n", config->bConfigurationValue, config, config->highspeed ? " high" : "",

                                                                  config->fullspeed? (gadget_is_dualspeed(cdev->gadget)? " full": " full/low"): "");

                                                          for (i = 0; i < MAX_CONFIG_INTERFACES; i++) { //查看这个配置下有哪有功能

                                                                                         struct usb_function *f = config->interface[i];

                                                                                         if (!f)

                                                                                                 continue;

                                                                                         DBG(cdev, " interface %d = %s/%p\n",i, f->name, f);

                                                             }

                                }

                              /* set_alt(), or next config->bind(), sets up

                                * ep->driver_data as needed.

                              */

                               //将gadget设备的所有端点的driver_data清零

                                usb_ep_autoconfig_reset(cdev->gadget);

                  done:

                               if (status)

                                               DBG(cdev, "added config '%s'/%u --> %d\n", config->label, config->bConfigurationValue, status);

                               return status;

    }

     

    /*设置一个配置*/

    static int set_config(struct usb_composite_dev *cdev, const struct usb_ctrlrequest *ctrl, unsigned number)

    {

                       struct usb_gadget *gadget = cdev->gadget;

                       struct usb_configuration *c = NULL;

                        int result = -EINVAL;

                        unsigned power = gadget_is_otg(gadget) ? 8 : 100;

                         int tmp;

                       if (cdev->config)

                                      reset_config(cdev); //清除设备目前使用的配置

                      if (number) { //根据配置值找到对应的配置

                                           list_for_each_entry(c, &cdev->configs, list) {

                                                                              if (c->bConfigurationValue == number) {

                                                                                                            result = 0;

                                                                                                            break;

                                                                              }

                                          }

                                         if (result < 0) //没有找到这个配置

                                                          goto done;

                     }

                    else

                              result = 0;

                  INFO(cdev, "%s speed config #%d: %s\n", ({ char *speed;

                               switch (gadget->speed) {

                                                  case USB_SPEED_LOW: speed = "low"; break;

                                                 case USB_SPEED_FULL: speed = "full"; break;

                                                case USB_SPEED_HIGH: speed = "high"; break;

                                                 default: speed = "?"; break;

                               } ; speed; }), number, c ? c->label : "unconfigured");

              if (!c)

                          goto done;

             cdev->config = c; //设置为设备使用的配置

            /* Initialize all interfaces by setting them to altsetting zero. */

               for (tmp = 0; tmp < MAX_CONFIG_INTERFACES; tmp++) {

                                    struct usb_function *f = c->interface[tmp];

                                    struct usb_descriptor_header **descriptors;

                                    if (!f)

                                                               break;

                                     /*

                                               * Record which endpoints are used by the function. This is used

                                              * to dispatch control requests targeted at that endpoint to the

                                              * function's setup callback instead of the current

                                              * configuration's setup callback.

                                     */

                                    if (gadget->speed == USB_SPEED_HIGH)

                                                          descriptors = f->hs_descriptors;

                                    else

                                                          descriptors = f->descriptors;

                                   for (; *descriptors; ++descriptors) { //遍历功能的所有端点描述符

                                                         struct usb_endpoint_descriptor *ep;

                                                        int addr;

                                                        if ((*descriptors)->bDescriptorType != USB_DT_ENDPOINT)

                                                                                          continue;

                                                         ep = (struct usb_endpoint_descriptor *)*descriptors;

                                                         addr = ((ep->bEndpointAddress & 0x80) >> 3) | (ep->bEndpointAddress & 0x0f);

                                                       set_bit(addr, f->endpoints); //这个功能采用的端点号

                                      }

                                      result = f->set_alt(f, tmp, 0); //设置功能的默认值

                                     if (result < 0) {

                                                        DBG(cdev, "interface %d (%s/%p) alt 0 --> %d\n", tmp, f->name, f, result);

                                                        reset_config(cdev);

                                                         goto done;

                                       }

                     }

                   /* when we return, be sure our power usage is valid */

                            power = c->bMaxPower ? (2 * c->bMaxPower) : CONFIG_USB_GADGET_VBUS_DRAW;

        done:

                 usb_gadget_vbus_draw(gadget, power);

                  return result;

    }

    /*这个setup函数完成了ep0所需要处理的而底层不能处理的功能,由于这一个层实现了这个函数,所以功能层就不需要关注于USB协议的这些事务性处理,而重点放在需要实现的功能上*/

    static int composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)

    {

                      struct usb_composite_dev *cdev = get_gadget_data(gadget); //由gadget获取composite设备

                      struct usb_request *req = cdev->req; //控制请求

                      int value = -EOPNOTSUPP;

                       u16 w_index = le16_to_cpu(ctrl->wIndex);

                        u8 intf = w_index & 0xFF;

                        u16 w_value = le16_to_cpu(ctrl->wValue);

                       u16 w_length = le16_to_cpu(ctrl->wLength);

                     struct usb_function *f = NULL;

                     u8 endp;

                   /* partial re-init of the response message; the function or the

                       * gadget might need to intercept e.g. a control-OUT completion

                    * when we delegate to it.

                    */

                  //初始化响应请求信息

                    req->zero = 0;

                    req->complete = composite_setup_complete;

                   req->length = USB_BUFSIZ;

                   gadget->ep0->driver_data = cdev;

                   switch (ctrl->bRequest) { //根据请求类型处理

                                                     /* we handle all standard USB descriptors */

                                                   case USB_REQ_GET_DESCRIPTOR: //返回描述符

                                                                            if (ctrl->bRequestType != USB_DIR_IN)

                                                                                                          goto unknown;

                                                                           switch (w_value >> 8) {

                                                                                                       case USB_DT_DEVICE: //返回设备描述符

                                                                                                                             cdev->desc.bNumConfigurations =  count_configs(cdev, USB_DT_DEVICE);

                                                                                                                              value = min(w_length, (u16) sizeof cdev->desc);

                                                                                                                              memcpy(req->buf, &cdev->desc, value);

                                                                                                                              break;

                                                                                                         case USB_DT_DEVICE_QUALIFIER: //返回qualifier描述符

                                                                                                                              if (!gadget_is_dualspeed(gadget))

                                                                                                                                                               break;

                                                                                                                               device_qual(cdev);

                                                                                                                              value = min_t(int, w_length, sizeof(struct usb_qualifier_descriptor));

                                                                                                                              break;

                                                                                                        case USB_DT_OTHER_SPEED_CONFIG:

                                                                                                                               if (!gadget_is_dualspeed(gadget))

                                                                                                                                                                   break;

                                                                                                                                /* FALLTHROUGH */

                                                                                                        case USB_DT_CONFIG: //返回配置描述符

                                                                                                                               value = config_desc(cdev, w_value);

                                                                                                                               if (value >= 0)

                                                                                                                                                      value = min(w_length, (u16) value);

                                                                                                                                break;

                                                                                                          case USB_DT_STRING: //返回字符串描述符

                                                                                                                                 value = get_string(cdev, req->buf, w_index, w_value & 0xff);

                                                                                                                                 if (value >= 0)

                                                                                                                                                          value = min(w_length, (u16) value);

                                                                                                                                 break;

                                                                                           }

                                                                                 break;

                                                                                 /* any number of configs can work */

                                           case USB_REQ_SET_CONFIGURATION: //设置配置

                                                                                if (ctrl->bRequestType != 0)

                                                                                                          goto unknown;

                                                                               if (gadget_is_otg(gadget)) {

                                                                                                        if (gadget->a_hnp_support)

                                                                                                                              DBG(cdev, "HNP available\n");

                                                                                                         else if (gadget->a_alt_hnp_support)

                                                                                                                              DBG(cdev, "HNP on another port\n");

                                                                                                        else

                                                                                                                             VDBG(cdev, "HNP inactive\n");

                                                                                   }

                                                                                spin_lock(&cdev->lock);

                                                                                 value = set_config(cdev, ctrl, w_value);

                                                                                 spin_unlock(&cdev->lock);

                                                                                 break;

                                       case USB_REQ_GET_CONFIGURATION: //返回当前配置

                                                                              if (ctrl->bRequestType != USB_DIR_IN)

                                                                                                                      goto unknown;

                                                                             if (cdev->config)

                                                                                                                    *(u8 *)req->buf = cdev->config->bConfigurationValue;

                                                                             else

                                                                                                                       *(u8 *)req->buf = 0;

                                                                              value = min(w_length, (u16) 1);

                                                                               break;

                                /* function drivers must handle get/set altsetting; if there's

                                 * no get() method, we know only altsetting zero works.

                                 */

                               case USB_REQ_SET_INTERFACE: //设置接口设置

                                                                             if (ctrl->bRequestType != USB_RECIP_INTERFACE)

                                                                                                                             goto unknown;

                                                                            if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES)

                                                                                                                              break;

                                                                            f = cdev->config->interface[intf];

                                                                            if (!f)

                                                                                         break;

                                                                           if (w_value && !f->set_alt)

                                                                                          break;

                                                                          value = f->set_alt(f, w_index, w_value);

                                                                           break;

                                     case USB_REQ_GET_INTERFACE: //返回接口设置

                                                                       if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE))

                                                                                                        goto unknown;

                                                                      if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES)

                                                                                                        break;

                                                                        f = cdev->config->interface[intf];

                                                                      if (!f)

                                                                                                    break;

                                                                      /* lots of interfaces only need altsetting zero... */

                                                                       value = f->get_alt ? f->get_alt(f, w_index) : 0;

                                                                       if (value < 0)

                                                                                                        break;

                                                                      *((u8 *)req->buf) = value;

                                                                      value = min(w_length, (u16) 1);

                                                                       break;

                                    default:

       unknown:

                  VDBG(cdev, "non-core control req%02x.%02x v%04x i%04x l%d\n",ctrl->bRequestType, ctrl->bRequest,w_value, w_index, w_length);

                  /* functions always handle their interfaces and endpoints...

                    * punt other recipients (other, WUSB, ...) to the current

                    * configuration code.

                    *

                    * REVISIT it could make sense to let the composite device

                    * take such requests too, if that's ever needed: to work

                    * in config 0, etc.

                  */

              switch (ctrl->bRequestType & USB_RECIP_MASK) {

                           case USB_RECIP_INTERFACE:

                                           f = cdev->config->interface[intf];

                                           break;

                          case USB_RECIP_ENDPOINT:

                                          endp = ((w_index & 0x80) >> 3) | (w_index & 0x0f);

                                           list_for_each_entry(f, &cdev->config->functions, list) {

                                                        if (test_bit(endp, f->endpoints))

                                                                                         break;

                                             }

                                           if (&f->list == &cdev->config->functions)

                                                                         f = NULL;

                                         break;

           }

           if (f && f->setup)

                           value = f->setup(f, ctrl);

         else {

                            struct usb_configuration *c;

                             c = cdev->config;

                             if (c && c->setup)

                                           value = c->setup(c, ctrl);

           }

         goto done;

    }

       /* respond with data transfer before status phase? */

        if (value >= 0) {

                               req->length = value;

                                  req->zero = value < w_length;

                              value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);

                            if (value < 0) {

                                            DBG(cdev, "ep_queue --> %d\n", value);

                                             req->status = 0;

                                           composite_setup_complete(gadget->ep0, req);

                          }

             }

    done:

               /* device either stalls (value < 0) or reports success */

                 return value;

    }


    展开全文
  • Windows 中包括的 USB 设备驱动程序

    千次阅读 2017-11-07 21:37:50
    Windows 中包括的 USB 设备驱动程序 本主题列举了 Microsoft 为支持的 USB 设备类提供的驱动程序。 如果你正在安装 USB 驱动程序: 你不需要下载 USB 设备驱动程序。它们是自动安装的。Windows 中...

    Windows 中包括的 USB 设备类驱动程序


    本主题列举了 Microsoft 为支持的 USB 设备类提供的驱动程序。

    如果你正在安装 USB 驱动程序:   你不需要下载 USB 设备类驱动程序。它们是自动安装的。Windows 中包含了这些驱动程序及其安装文件。可以在 \Windows\System32\DriverStore\FileRepository 文件夹中找到这些文件。驱动程序通过“Windows 更新”进行更新。

    如果你正在编写一个自定义驱动程序:  在为 USB 设备编写驱动程序之前,先确定 Microsoft 提供的驱动程序是否满足设备要求。如果 Microsoft 提供的驱动程序对于你的设备所属的 USB 设备类不可用,则考虑使用通用驱动程序 Winusb.sys 或 Usbccgp.sys。仅在必要时才编写驱动程序。选择用于开发 USB 客户端驱动程序的驱动程序模型提供了更多指导。

    USB 设备类

    USB 设备类是具有类似特征、执行通用功能的设备类别。在 USB-IF 中定义了这些类及其规范。每个设备类由 USB-IF 批准的类、子类和协议代码识别,所有这些都由 IHV 在固件的设备描述符中提供。Microsoft 为其中一些设备类提供自带的驱动程序,称为 USB 设备类驱动程序。 如果所连接的设备属于系统支持的设备类,Windows 将自动加载类驱动程序,无需其他驱动程序即可保证设备正常工作。 

    硬件供应商不应为支持的设备类编写驱动程序。Windows 类驱动程序可能并不支持类规范中描述的所有功能。如果类驱动程序未能实现设备的部分功能,则供应商应提供补充性驱动程序,以便与类驱动程序协同工作,支持设备提供的全部功能。

    有关 USB-IF 批准的设备类的一般信息,请参阅 USB 技术网站。

    有关 USB 类规范和类代码的最新列表,请参阅 USB DWG 网站

    设备安装程序类

    Windows 按“设备安装程序类”(表示设备的功能)对设备分类。

    Microsoft 为大多数设备定义安装程序类。IHV 和 OEM 可以定义新的设备安装程序类,但仅在现有类都不适用时。有关详细信息,请参阅系统定义的设备安装程序类

    用于 USB 设备的两个重要设备安装程序类为:

    • USBDevice {88BAE032-5A81-49f0-BC3D-A4FF138216D6}:IHV 必须将此类用于不属于另一个类的自定义设备。此类不用于 USB 主控制器和集线器。

    • USB {36fc9e60-c465-11cf-8056-444553540000}:IHV 不得将此类用于其自定义设备。它是为 USB 主控制器和 USB 集线器保留的。

    设备安装程序类不同于前面讨论的 USB 设备类。例如,音频设备在其描述符中具有 USB 设备类代码 01h。当连接到系统时,Windows 会加载 Microsoft 提供的类驱动程序 Usbaudio.sys。在设备管理器中,设备显示在声音、视频和滑稽戏控制器的下面,表示设备安装程序类是“媒体”。

    Microsoft 提供的 USB 设备类驱动程序

    USB-IF 类代码设备安装程序类Microsoft 提供的驱动程序和 INFWindows 支持描述
    音频 (01h)

    媒体

    {4d36e96c-e325-11ce-bfc1-08002be10318}

    Usbaudio.sys

    Wdma_usb.inf

    Windows 8.1

    Windows 8

    Windows 7

    Windows Server 2008

    Windows Vista

    Windows Server 2003

    Windows XP

    Windows 2000

    Microsoft 通过 Usbaudio.sys 驱动程序为 USB 音频设备类提供支持。有关详细信息,请参阅内核模式 WDM 音频组件中的“USBAudio 类系统驱动程序”。有关 Windows 音频支持的详细信息,请参阅适用于 Windows 的音频设备技术网站。

    通信和 CDC 控件 (02h)

    调制解调器

    {4D36E96D-E325-11CE-BFC1-08002BE10318}

    注意  支持子类 02h (ACM)

    Usbser.sys

    Usbser.inf

    Windows 8.1

    Windows 8

    Windows 7

    Windows Server 2008

    Windows Vista

    从 Windows Vista 开始,用户即可通过设置注册表值来启用 CDC 和无线移动 CDC (WMCDC) 支持,如无线移动通信设备类支持中所述。

    启用 CDC 支持时,USB 公用类通用父驱动程序将枚举对应于 CDC 和 WMCDC 控制模型的接口集合,并为这些集合分配物理设备对象 (PDO)。

    Net

    {4d36e972-e325-11ce-bfc1-08002be10318}

    注意  支持子类 0Eh (MBIM) 

    wmbclass.sys

    Netwmbclass.inf

    Windows 8.1

    Windows 8

    从 Windows 8 开始,Microsoft 提供 wmbclass.sys 驱动程序用于移动宽带设备。请参阅 MB 接口模型
    HID(人体学接口设备) (03h)

    HIDClass

    {745a17a0-74d3-11d0-b6fe-00a0c90f57da}

    Hidclass.sys

    Hidusb.sys

    Input.inf

    Windows 8.1

    Windows 8

    Windows 7

    Windows Server 2008

    Windows Vista

    Windows Server 2003

    Windows XP

    Windows 2000

    Microsoft 提供了 HID 类驱动程序 (Hidclass.sys) 和微型类驱动程序 (Hidusb.sys),用以操作符合 USB HID 标准的设备。有关详细信息,请参阅 HID 体系结构微型驱动程序与 HID 类驱动程序。有关 Windows 中输入硬件支持的详细信息,请参阅输入和 HID - 体系结构与驱动程序支持网站。
    物理设备 (05h)---建议的驱动程序:WinUSB (Winusb.sys)
    图像 (06h)

    图像

    {6bdd1fc6-810f-11d0-bec7-08002be2092f}

    Usbscan.sys

    Sti.inf

    Windows 8.1

    Windows 8

    Windows 7

    Windows Server 2008

    Windows Vista

    Windows Server 2003

    Windows XP

    Microsoft 提供了 Usbscan.sys 驱动程序,用于在 Windows XP 和更新版本的操作系统中管理 USB 数码相机和扫描仪。 这个驱动程序实现了 Windows 图像体系结构 (WIA) 的 USB 组件。有关 WIA 的详细信息,请参阅 Windows 图像采集驱动程序和 Windows 图像组件网站。有关 Usbscan.sys 在 WIA 中承担哪种角色的详细信息,请参阅 WIA 核心组件
    打印机 (07h)

    USB

    注意  Usbprint.sys 在设备安装程序类下枚举打印机设备: Printer{4d36e979-e325-11ce-bfc1-08002be10318}。

    Usbprint.sys

    Usbprint.inf

    Windows 8.1

    Windows 8

    Windows 7

    Windows Server 2008

    Windows Vista

    Windows Server 2003

    Windows XP

    Windows 2000

    Microsoft 提供了 Usbprint.sys 类驱动程序,用以管理 USB 打印机。有关 Windows 中打印机类实现的信息,请参阅打印 - 体系结构与驱动程序支持网站。
    大容量存储 (08h)

    USB

    Usbstor.sys

    Windows 8.1

    Windows 8

    Windows 7

    Windows Server 2008

    Windows Vista

    Windows Server 2003

    Windows XP

    Windows 2000

    Microsoft 提供了 Usbstor.sys 端口驱动程序,用以通过 Microsoft 本机存储类驱动程序管理 USB 大容量存储设备。有关此驱动程序管理的设备堆栈的示例,请参阅 USB 大容量存储设备的设备对象示例。有关 Windows 存储支持的信息,请参阅存储技术网站。

    SCSIAdapter

    {4d36e97b-e325-11ce-bfc1-08002be10318}

    子类 (06) 和协议 (62)

    Uaspstor.sys

    Uaspstor.inf

    Windows 8.1

    Windows 8

    Uaspstor.sys 是用于支持批量流终结点的 SuperSpeed USB 设备的类驱动程序。有关详细信息,请参阅:
    集线器 (09h)

    USB

    {36fc9e60-c465-11cf-8056-444553540000} 

    Usbhub.sys

    Usb.inf

    Windows 8.1

    Windows 8

    Windows 7

    Windows Server 2008

    Windows Vista

    Windows Server 2003

    Windows XP

    Windows 2000

    Microsoft 提供了 Usbhub.sys 驱动程序来管理 USB 集线器。有关集线器类驱动程序与 USB 堆栈间关系的详细信息,请参阅 USB 驱动程序堆栈体系结构

    Usbhub3.sys

    Usbhub3.inf

    Windows 8.1

    Windows 8

    Microsoft 提供了 Usbhub3.sys 驱动程序来管理 SuperSpeed (USB 3.0) USB 集线器。

    当 SuperSpeed 集线器连接到 xHCI 控制器时加载该驱动程序。请参阅 USB 驱动程序堆栈体系结构

    CDC 数据(0Ah)---建议的驱动程序:WinUSB (Winusb.sys)
    智能卡 (0Bh)

    SmartCardReader

    {50dd5230-ba8a-11d1-bf5d-0000f805f530}

    Usbccid.sys(已过时)

    Windows 7

    Windows Server 2008

    Windows Vista

    Windows Server 2003

    Windows XP

    Microsoft 提供了 Usbccid.sys 微型类驱动程序,用于管理 USB 智能卡读卡器。 有关 Windows 中智能卡驱动程序的详细信息,请参阅智能卡设计指南

    请注意,对于 Windows Server 2003、Windows XP 和 Windows 2000,需要遵照特殊说明加载此驱动程序,因为此驱动程序的发布时间可能晚于这些操作系统的发布时间。

    注意  

    Usbccid.sys 驱动程序已替换为 UMDF 驱动程序 WUDFUsbccidDriver.dll。

    WUDFUsbccidDriver.dll

    WUDFUsbccidDriver.inf

    Windows 8.1

    Windows 8

    WUDFUsbccidDriver.dll 是用户模式的驱动程序,用于 USB CCID 智能卡读取器设备。
    内容安全性 (0Dh)---建议的驱动程序:USB 通用父驱动程序 (Usbccgp.sys)。在 Usbccgp.sys 中实现了一些内容安全性功能。请参阅Usbccgp.sys 中的内容安全性功能
    视频 (0Eh)

    图像

    {6bdd1fc6-810f-11d0-bec7-08002be2092f}

    Usbvideo.sys

    Usbvideo.inf

    Windows Vista

    Windows XP

    Microsoft 通过 Usbvideo.sys 驱动程序提供了 USB 视频类支持。有关详细信息,请参阅 AVStream 微型驱动程序中的“USB 视频类驱动程序”。

    请注意,对于 Windows XP,需要遵照特殊说明加载此驱动程序,因为此驱动程序的发布时间可能晚于操作系统的发布时间。

    个人医疗(0Fh)---建议的驱动程序:WinUSB (Winusb.sys)
    音频/视频设备(10h)--- 
    诊断设备 (DCh)---建议的驱动程序:WinUSB (Winusb.sys)
    无线控制器 (E0h)
    注意  支持子类 01h 和协议 01h

    蓝牙

    {e0cbf06c-cd8b-4647-bb8a-263b43f0f974}

    Bthusb.sys

    Bth.inf

    Windows 8.1

    Windows 8

    Windows 7

    Windows Vista

    Windows XP

    Microsoft 提供了 Bthusb.sys 微型端口驱动程序,用于管理 USB 蓝牙无线电。 有关详细信息,请参阅蓝牙设计指南
    其他 (EFh)

    Net

    {4d36e972-e325-11ce-bfc1-08002be10318}

    注意  支持子类 04h 和协议 01h

    Rndismp.sys

    Rndismp.inf

    Windows 8.1

    Windows 8

    Windows 7

    Windows Vista

    Windows XP

    在 Windows Vista 之前,CDC 支持仅限带有供应商特有协议 (bInterfaceProtocol) 值 0xFF 的特定于 RNDIS 的抽象控制模型 (ACM) 实现。RNDIS 设施在单独一个类驱动程序 Rndismp.sys 中集中了所有 802 式网卡的管理。有关远程 NDIS 的详细信息,请参阅远程 NDIS 概述。远程 NDIS 与 USB 的映射是在 Usb8023.sys 驱动程序中实现的。有关 Windows 中网络支持的详细信息,请参阅网络与无线技术网站。

    应用程序特定 (FEh)---建议的驱动程序:WinUSB (Winusb.sys)
    供应商特定 (FFh)---建议的驱动程序:WinUSB (Winusb.sys)

     




    from:http://blog.csdn.net/m_o_bz/article/details/44230103


    展开全文
  • (一)USB驱动程序_USB基础知识

    千次阅读 2018-10-11 10:20:05
    USB驱动程序可以粗分为两类: 一、主机(Host)系统上的驱动程序 ,这个驱动程序控制插入其中的USB设备 二、设备(Device)上的驱动程序,这个驱动程序控制USB设备如何与主机通信 为了举一个形象的例子,我得先...
    深入,并且广泛
    				-沉默犀牛
    

    USB设备驱动分类

    USB驱动程序可以粗分为两类:
    一、主机(Host)系统上的驱动程序 ,这个驱动程序控制插入其中的USB设备
    二、设备(Device)上的驱动程序,这个驱动程序控制USB设备如何与主机通信

    为了举一个形象的例子,我得先展示一张图片,更细致的介绍一下以上的两种分类:

    HostDevice
    USB设备驱动(Mass storage/CDC/HID)Gadget Function 驱动(serial…)
    USB核心Gadet Funtion API
    USB Host Controller 驱动(OHCI/EHCI/UHCI)UDC驱动(omap/pxa2xx…)
    USB Host ControllerUDC

    在这个图中,主机侧与设备侧又分别分为了两个驱动:
    Host:USB设备驱动、USB Host Controller 驱动
    Device:Gadget Function 驱动、UDC驱动

    USB设备驱动和USB Host Controller驱动之间的USB core负责了USB驱动管理和协议处理的主要工作。
    1.它通过定义一些数据结构体、宏和功能函数,向上为设备驱动提供编程接口,向下为USB Host Controller驱 动提供编程接口;
    2.维护整个系统的USB设备信息;
    3.完成设备热拔插控制、总线数据传输控制等

    Gadet Function API现在是UDC驱动程序回调函数的包装

    举一个生活中的例子:当用Android系统的手机 通过USB线 连接Linux系统的PC

    Host(PC)的动作:

    1.如果你插入了USB2.0的设备,则Host的USB Host Controller 驱动要使能EHCI,如果是USB1.1的设备,就要使能OHCI
    /UHCI,不过一般做法是全都使能。在这里我们手机插入后,Host Controller 驱动会启用EHCI

    2.这个USB设备驱动,会根据插入的设备不同,而选择不同的驱动。默认已经有的驱动有存储设备、键盘、鼠标、游戏
    杆、网络设备和调制解调器。如果是其他的设备,则需要自己写驱动了。在我们的例子里,手机通过USB连接到PC上
    后,可以选择几个不同的模式,当选择仅限充电时,Host的USB设备驱动就走充电的驱动,当选择传输文件(MTP)
    时,Host的USB设备驱动就走传输文件的驱动,当选择当做摄像头时(现在大部分手机不会设置这个功能了),Host
    的USB设备驱动就走摄像头的驱动。

    Device(手机)的动作:

    1.当我的手机通过USB连接电脑以后,手机的底层USB控制器行使UDC功能,这时运行在底层的是UDC驱动.

    2.然后我再选择手机的模式,当选择仅充电时,Device的Gadget Function驱动就走充电的驱动,当选择文件传输时,
    Device的Gadget Function驱动就走文件传输的驱动(Mass storage)

    现在我们已经理清了这四种驱动都是在哪用的(Host/Device)、都是何时用的、都是干什么的。

    USB设备基础

    USB设备是非常复杂的,它由许多不同的逻辑单元组成,这些逻辑单元之间的关系可以简单地描述如下:

    1. 设备通常具有一个或者多个配置
    2. 配置经常具有一个或者多个接口
    3. 接口通常具有一个或者多个设置
    4. 接口没有或者具有一个以上端点

    接下来就以上提到的概念详细分析:

    端点:

    USB通信的最基本形式是通过一个名为端点(endpoint)的东西,USB端点只能往一个方向传送数据,从Host到Device称为OUT端点,从Device到Host称为IN端点,端点可以看做是单项的管道它有四种不同的类型,分别具有不同的传送数据的方式:

    控制:

    控制端点用来控制对USB设备的不同部分的访问。它们通常用于配置设备、获取设备信息、发送命令到设备,或者获取设备的状态报告。这些端点一般体积较小,每个USB设备都有一个名为“端点0”的控制端点,USB核心使用该端点在插入时进行设备的配置。USB协议保证这些传输始终有足够的传输带宽以传送数据到设备,这里关于端点0的功能举一个例子:在手机插入PC的例子中,我选择charge模式后,就是通过端点0来告诉PC的,切换成MTP模式后,也是通过端点0来告诉PC的,PC知道后就会进行相应的配置,这个配置就是调用上述相应的driver

    中断

    每当USB Host要求设备传输数据时,中断端点就以一个固定的速率来传送少量的数据。这些端点是USB键盘和鼠标所使用的主要传输方式。它们通常还用于发送数据到USB设备以控制设备,不过一般不用来传输大量的数据。USB协议保证这些传输始终有足够的保留带宽以传送数据

    批量

    批量(bulk)端点传送大批量的数据。这些端点通常比中断端点大得多(它们可以一次持有更多的字符)。它们常见于需要确保没有数据丢失的传输的设备。USB协议不保证这些传输始终可以在特定的时间内完成。如果总线上的空间不足以发送整个批量包,它将被分割为多个包进行传输。这些端点通常出现在打印机、存储设备和网络设备上

    等时

    等时(isochronous)端点同样可以传送大批量的数据,但数据是否达到是没有保证的。这些端点用于可以应付数据丢失情况的设备,这类设备更注重于保持一个恒定的数据流。实时的数据手记(例如音频和视频设备)几乎毫无例外都使用这类端点。

    我们知道“端点”是逻辑上的意义,在代码中是如何实现的呢?或者说,用什么东西来代表端点呢?我之后还会再多啰嗦一下其他的类似“逻辑上的意义”这种问题。现在先来看描述端点的东西吧!其实就是结构体啦,我会结合《LDD3》和《Linux设备驱动开发详解》中的描述进行注释

    /* USB_DT_ENDPOINT: Endpoint descriptor */
    struct usb_endpoint_descriptor {
    	__u8  bLength;			//描述符长度
    	__u8  bDescriptorType;		//描述符类型
    	
    	__u8  bEndpointAddress;  	//端点地址:0-3位是端点号,第7位是方向(0为out,1为in)
    	__u8  bmAttributes;		//端点属性(类型):bit[0:1] 00表示控制 01表示等时 10表示批量 11表示中断
    	__le16 wMaxPacketSize;		//该端点一次可以处理的最大字节数。
    					  注意:driver可以发送数量大于此值的数据到端点,
    					  但是在实际传输到设备的时候,数据将被分割为wMaxPacketSize大小的块。
    	__u8  bInterval;		//轮询数据传送端点的时间间隔
    					  对于批量和控制的端点,忽略此域
    					  对于等时的端点,必须为1
    					  对于中断的端点,必须为1-255
    
    	/* NOTE:  these two are _only_ in audio endpoints. */
    	/* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
    	__u8  bRefresh;
    	__u8  bSynchAddress;
    } __attribute__ ((packed));
    
    

    接口:

    USB端点被捆绑为接口。USB接口只处理一种USB逻辑连接,例如鼠标、键盘或者音频流。一些USB设备具有多个接口,例如USB扬声器可以包括两个接口:一个USB键盘用于按键和一个USB音频流。因为一个USB接口代表了一个基本功能,而每个USB驱动程序控制一个接口,因此,以扬声器为例,Linux需要两个不同的驱动程序来处理一个硬件

    接下来看看接口的结构体:

    /* USB_DT_INTERFACE: Interface descriptor */
    struct usb_interface_descriptor {
    	__u8  bLength;				//描述符长度
    	__u8  bDescriptorType;			//描述符类型
    
    	__u8  bInterfaceNumber;			//接口的编号
    	__u8  bAlternateSetting;		//备用的接口描述符编号
    	__u8  bNumEndpoints;			//接口使用的端点数,不包括端点0
    	__u8  bInterfaceClass;			//接口类型
    	__u8  bInterfaceSubClass;		//接口子类型
    	__u8  bInterfaceProtocol;		//接口所遵循的协议
    	__u8  iInterface;			//描述该接口的字符串索引值
    } __attribute__ ((packed));
    
    

    配置

    USB接口本身被捆绑为配置。一个USB设备可以有多个配置,而且可以在配置之间切换以改变设备的状态。比如手机可以选择charge only 、MTP、PTP、Camera这几个配置。用usb_config_descriptor结构体来描述配置。USB设备驱动程序通常不需要改变这个结构体中的任何值,因此在这里不详述了。

    这里顺便提一嘴怎么看你设备中的usb设备的这些结构体信息:
    1.lsusb 查看每一个设备的 bus号 和 device号
    在这里插入图片描述
    2.lsusb -s -v [Bus:Device] 就可以显示出你填入的Bus和Device指定的设备的信息
    在这里插入图片描述

    以上是先要准备的有关USB的基础知识,下两篇文章我们分析一下驱动的源码,这四个驱动中有两个是我们不会去改动的:Host Controller driver 和 UDC 因为这都是默认的,只需要config一下就可以了。所以我们的目标放在了另外的两个驱动上: USB设备驱动 和 Function 驱动

    这里多说一下上文提到的“逻辑上的意义”,在我学习Linux驱动这三个月以来,我感觉到Device、Driver这样的东西对于Kernel来说,都是逻辑上的,只要我把Device的信息写到DTS中,那Linux的Kernel启动时,就会展开DTS,并且把这些node最终解析为device结构体,然后注册(这时是注册platform_device,其他总线上的Device是(在对应总线注册时)注册的 ),你看,kernel并不知道这些我们硬件上到底有没有连接这些Device,我想表达的就是,在Kernel看来,这些最终解析成的device结构体,就是有意义的。但是这些node在我们看来,只有逻辑上的意义。有了它们,Kernel才能认识Device。同理的去理解本文中的结构体,和Kernel中的其他结构体,它们都是只有逻辑上的意义

    那么既然Kernel并不知道Device到底存不存在,那也不能让Kernel去控制一个不存在的Device吧,这个问题怎么解决的呢?这就是Driver的用处之一了。Driver也都是体现成了结构体。比如usb_driver、i2c_driver等等,所以Driver也是在我们的眼中看来,它们也是逻辑上的并不像是我们用来控制游戏人物的键盘、鼠标那么具体。Driver写好后,Kernel就认为这是一个Device的“控制器”了,但是它不会对应现实世界的任何实物。那么Driver是怎么解决“到底有没有真实的Device连接在硬件上?”这个问题的呢?Driver通过向真实器件读取信息来判断到底有没有真实的Device,如果没有真实的Device,那Driver就读不出来正确的数据,那我Kernel就认为没有这个真实器件,也正是这个原因,我们调试某器件的时候发现driver没有加载上,就是因为Device的配置有问题,导致Kernel误认为没有这个真实器件

    为了更好的解释这个问题,我用我所接触过的两个例子,来再次阐述:
    1.TouchPanel: 大部分TouchPanel是挂载在i2c上的,所以TP的Driver->probe函数中,会通过i2c总线向TP硬件的IC读取一些信息,这就起到了验证硬件在不在的作用,如果读出的数据不对,直接return
    2.LCD:LCD会面对一个问题,就是一套代码,要适应多个屏幕,(因为咱们手机或者其他嵌入式设备的配置不同,高配的用好一点的,低配的用差一点的)那一套代码怎么适应不同的屏幕呢?就是从LCD的硬件IC读取一些信息,比如硬件的编号,GPIO的高低等等,然后用这个编号来找对应的配置,读取编号的时候,不就可以验证硬件在不在了吗。

    这篇博文参考了《Linux设备驱动开发详解》《Linux Device Driver 3》和《Linux那些事儿-我是USB》

    展开全文
  • 驱动名称】ASUS华硕P8H61/USB3主板BIOS 3602版(2012年3月15日发布) 【驱动描述】此版BIOS主要解决了以下问题: 1.改善系统稳定性; 2.改善内存兼容性; 3.对新的CPU提供了支持 支持英特尔下一代22纳米处理器 E1...
  • 这个程序考虑到了多配置、高速传输、USB OTG等因素。应该说写的比较清楚,是我们了解gadget驱动架构的一个非常好的途径。但把这些东西都放在一起,对很多初学人员来说还是不能快速理解。那就再把它简化一些,针对S3C...
  • 本节讨论使用DSF设备模拟器测试USB驱动程序的技术。 本节包括: 创建一个模拟USB 2.0 EHCI控制器 在模拟USB 2.0控制器中插入设备 模拟设备PNP枚举 用设备模拟器协调I/O 在计算机上重启模拟设备 使用设备仿真...
  • wince下USB设备驱动程序导读

    千次阅读 2017-02-18 14:56:26
    随着USB设备的不断增加,我们这些开发人员也就多了对USB设备进行驱动程序开发的工作...二是对WinCE自带的USB驱动程序的例子没有弄懂,看到一大堆文件夹结构和源程序思维混乱;   三是几乎没有什么中文的参考资料,不
  • 设备驱动程序是操作系统内核和机器硬件之间的接口,由一组函数和一些私有数据组成,是应用程序和硬件设备之间的桥梁。在应用程序看来,硬件设备只是一个设备文件,应用程序可以像操作普通文件一样对硬件设备进行操作...
  • 内核使用2.6.29.4    拓扑结构上, 一个 USB 子系统并不是以...USB主控制器负责询问每个USB设备是否有数据需要发送。 由于这个拓扑结构,一个 USB 设备在没有主控制器要求的情况下不能发送数据. 也就是说:USB
  • USB设备驱动驱动

    千次阅读 2018-10-11 18:14:25
    上一篇文章USB设备驱动设备讲到 USB设备的EEPROM中,固化了设备的一些描述信息和一些程序。当USB设备插入USB插槽时,会引起一个电信号的变化,主机控制器捕获这个电信号,并命令USB核心处理对设备的加载工作。US....
  • 驱动名称】ASUS华硕M5A78L-M/USB3主板BIOS 1003版(2012年4月1日发布) 【驱动描述】此版BIOS主要解决了以下问题: 提升板载网卡性能。 可用ASUS Update升级工具在Windows下更新,选择“从档案升级BIOS”,之后...
  • 在Windows 10上,全新安装是清除设备出现问题时从头开始擦除硬盘驱动器的最佳选择。例如,使用这种方法可以帮助解决性能、启动、关闭、内存和应用程序问题。此外,这是删除病毒和几乎任何类型的恶意软件的有效方法,...
  • 一、使用STM32CubeMX生成USB驱动程序 打开STM32CubeMX软件,选择Start My project formMCU,点ACCESS TO MCU SELECTOR。 选择相应的芯片信号,点击Start Project 配置RCC的High Speed Clock为图中所示,...
  • 操作系统实验·字符设备驱动程序

    千次阅读 2021-12-10 23:08:56
    编写一个简单的字符设备驱动程序,该字符设备并不驱动特定的硬件, 而是用内核空间模拟字符设备,要求该字符设备包括以下几个基本操作,打开、读、写和释放,并编写测试程序用于测试所编写的字符设备驱动程序。...
  • 一款使用32位ARM CPU、运行linux系统的机。本文档描述自带USB驱动程序及USB功能的实现。 说明: 1.程序名称USB驱动程序
  • 驱动名称】ASUS华硕M4A89GTD PRO/USB3主板BIOS 1703版(2011年1月6日发布) 【驱动描述】提高了系统的稳定性
  • 驱动名称】ASUS华硕P8H61-M LE/USB3主板BIOS 0601版(2011年9月12日发布) 【驱动名称】适合型号:ASUS华硕P8H61-M LE/USB3主板
  • USBASP编程器Win10驱动安装工具,源文件名称Zadig。网上有好多下载,但是要积分,币什么的。这里分享出来,供大家使用。大家也可以到:https://zadig.akeo.ie去下载。
  • 驱动名称】ASUS华硕M5A78L/USB3主板BIOS 1003版(2012年4月1日发布) 【驱动描述】此版BIOS主要解决了以下问题: 提升板载网卡性能。 可用ASUS Update升级工具在Windows下更新,选择“从档案升级BIOS”,之后按照...
  • 驱动名称】ASUS华硕M4A87TD/USB3主板BIOS 1102版(2011年1月6日发布) 【驱动描述】修正当Load line calibration打开时,CPU倍频可能会降为X4的问题
  • 驱动名称】ASUS华硕P7H55-M LX/USB3主板BIOS 0210版(2011年2月24日发布) 【驱动描述】首版BIOS。 适合型号:ASUS华硕P7H55-M LX/USB3主板
  • 驱动名称】ASUS华硕H61M-A/USB3主板BIOS 0304版(2013年2月19日发布) 【驱动描述】 此版BIOS主要解决了以下问题: 改善系统稳定性。 可用ASUS Update升级工具在Windows下更新,选择“从档案升级BIOS”,之后按照...
  • 驱动名称】ASUS华硕M4A88T-M/USB3主板BIOS 0703版(2011年2月17日发布) 【驱动描述】改进EPU功能。 适合型号:ASUS华硕M4A88T-M/USB3主板
  • pciusb3.0扩展卡驱动可以让没有USB3.0接口的主板升级至USB3.0高速接口,让您享受大容量与高效能储存能力,适用于多媒体影音剪辑、服务器数据库、DVR数据储存、2D/3D动画制作、美工绘图及系统数据备份等的呢,支持...
  • 随着USB设备的不断增加,我们这些开发人员也就多了对USB设备进行驱动程序开发的工作。但是对于很多初学者来说,存在以下三个困难:  一是对WinCE的驱动程序结构了解得太少,没办法得心应手的专注于驱动程序的开发...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 28,574
精华内容 11,429
关键字:

usb设备的驱动程序名称