Chinaunix首页 | 论坛 | 博客
  • 博客访问: 216831
  • 博文数量: 32
  • 博客积分: 410
  • 博客等级: 一等列兵
  • 技术积分: 396
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-03 16:58
文章分类

全部博文(32)

文章存档

2013年(17)

2012年(15)

我的朋友

分类: LINUX

2013-04-12 13:35:14

linux的usb hub<第一步>

以前不太了解hub,一直认为它只是一个可选设备,和网络集线器类似,有它不多,少它也可;
太低调了,以至于都不晓得它长在哪里,今天在网上百度了一下,发现它是window和linux系统上一个必备的设备;是EHCI/UHCI的私生子,一直躺在妈妈的怀里;

设备部分:<usb_device_type 篇>
hub是usb控制器的私生子,那么他就在hcd.c中生成:
usb_add_hcd()
{
...
rhdev = usb_alloc_dev(NULL, &hcd->self, 0);
hcd->self.root_hub = rhdev;
register_root_hub(hcd);//完成设备添加了;
...
}
下面中的介绍usb_alloc_dev和register_root_hub
函数一

点击(此处)折叠或打开

  1. /**
  2.  * usb_add_hcd - finish generic HCD structure initialization and register
  3.  * @hcd: the usb_hcd structure to initialize
  4.  * @irqnum: Interrupt line to allocate
  5.  * @irqflags: Interrupt type flags
  6.  *
  7.  * Finish the remaining parts of generic HCD initialization: allocate the
  8.  * buffers of consistent memory, register the bus, request the IRQ line,
  9.  * and call the driver's reset() and start() routines.
  10.  */
  11. int usb_add_hcd(struct usb_hcd *hcd,
  12.         unsigned int irqnum, unsigned long irqflags)
  13. {
  14.     int retval;
  15.     struct usb_device *rhdev;

  16.     dev_info(hcd->self.controller, "%s\n", hcd->product_desc);

  17.     hcd->authorized_default = hcd->wireless? 0 : 1;
  18.     set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);

  19.     /* HC is in reset state, but accessible. Now do the one-time init,
  20.      * bottom up so that hcds can customize the root hubs before khubd
  21.      * starts talking to them. (Note, bus id is assigned early too.)
  22.      */
  23.     if ((retval = hcd_buffer_create(hcd)) != 0) {
  24.         dev_dbg(hcd->self.controller, "pool alloc failed\n");
  25.         return retval;
  26.     }

  27.     if ((retval = usb_register_bus(&hcd->self)) < 0)
  28.         goto err_register_bus;

  29.     if ((rhdev = usb_alloc_dev(NULL, &hcd->self, 0)) == NULL) {
  30.         dev_err(hcd->self.controller, "unable to allocate root hub\n");
  31.         retval = -ENOMEM;
  32.         goto err_allocate_root_hub;
  33.     }

  34.     switch (hcd->driver->flags & HCD_MASK) {
  35.     case HCD_USB11:
  36.         rhdev->speed = USB_SPEED_FULL;
  37.         break;
  38.     case HCD_USB2:
  39.         rhdev->speed = USB_SPEED_HIGH;
  40.         break;
  41.     case HCD_USB3:
  42.         rhdev->speed = USB_SPEED_SUPER;
  43.         break;
  44.     default:
  45.         goto err_allocate_root_hub;
  46.     }
  47.     hcd->self.root_hub = rhdev;//设备

  48.     /* wakeup flag init defaults to "everything works" for root hubs,
  49.      * but drivers can override it in reset() if needed, along with
  50.      * recording the overall controller's system wakeup capability.
  51.      */
  52.     device_init_wakeup(&rhdev->dev, 1);

  53.     /* "reset" is misnamed; its role is now one-time init. the controller
  54.      * should already have been reset (and boot firmware kicked off etc).
  55.      */
  56.      //控制器复位:ehci_pci_setup
  57.     if (hcd->driver->reset && (retval = hcd->driver->reset(hcd)) < 0) {
  58.         dev_err(hcd->self.controller, "can't setup\n");
  59.         goto err_hcd_driver_setup;
  60.     }

  61.     /* NOTE: root hub and controller capabilities may not be the same */
  62.     if (device_can_wakeup(hcd->self.controller)
  63.             && device_can_wakeup(&hcd->self.root_hub->dev))
  64.         dev_dbg(hcd->self.controller, "supports USB remote wakeup\n");
  65. //控制器中断处理接口
  66.     /* enable irqs just before we start the controller */
  67.     if (hcd->driver->irq) {

  68.         /* IRQF_DISABLED doesn't work as advertised when used together
  69.          * with IRQF_SHARED. As usb_hcd_irq() will always disable
  70.          * interrupts we can remove it here.
  71.          */
  72.         if (irqflags & IRQF_SHARED)
  73.             irqflags &= ~IRQF_DISABLED;

  74.         snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d",
  75.                 hcd->driver->description, hcd->self.busnum);
  76.         if ((retval = request_irq(irqnum, &usb_hcd_irq, irqflags,
  77.                 hcd->irq_descr, hcd)) != 0) {
  78.             dev_err(hcd->self.controller,
  79.                     "request interrupt %d failed\n", irqnum);
  80.             goto err_request_irq;
  81.         }
  82.         hcd->irq = irqnum;
  83.         dev_info(hcd->self.controller, "irq %d, %s 0x%08llx\n", irqnum,
  84.                 (hcd->driver->flags & HCD_MEMORY) ?
  85.                     "io mem" : "io base",
  86.                     (unsigned long long)hcd->rsrc_start);
  87.     } else {
  88.         hcd->irq = -1;
  89.         if (hcd->rsrc_start)
  90.             dev_info(hcd->self.controller, "%s 0x%08llx\n",
  91.                     (hcd->driver->flags & HCD_MEMORY) ?
  92.                     "io mem" : "io base",
  93.                     (unsigned long long)hcd->rsrc_start);
  94.     }
  95. //控制器run:ehci_run
  96.     if ((retval = hcd->driver->start(hcd)) < 0) {
  97.         dev_err(hcd->self.controller, "startup error %d\n", retval);
  98.         goto err_hcd_driver_start;
  99.     }

  100.     /* starting here, usbcore will pay attention to this root hub */
  101.     rhdev->bus_mA = min(500u, hcd->power_budget);
  102.     if ((retval = register_root_hub(hcd)) != 0)//设备添加到内核中了;
  103.         goto err_register_root_hub;

  104.     retval = sysfs_create_group(&rhdev->dev.kobj, &usb_bus_attr_group);
  105.     if (retval < 0) {
  106.         printk(KERN_ERR "Cannot register USB bus sysfs attributes: %d\n",
  107.          retval);
  108.         goto error_create_attr_group;
  109.     }
  110.     if (hcd->uses_new_polling && hcd->poll_rh)
  111.         usb_hcd_poll_rh_status(hcd);
  112.     return retval;

  113. error_create_attr_group:
  114.     mutex_lock(&usb_bus_list_lock);
  115.     usb_disconnect(&hcd->self.root_hub);
  116.     mutex_unlock(&usb_bus_list_lock);
  117. err_register_root_hub:
  118.     hcd->driver->stop(hcd);
  119. err_hcd_driver_start:
  120.     if (hcd->irq >= 0)
  121.         free_irq(irqnum, hcd);
  122. err_request_irq:
  123. err_hcd_driver_setup:
  124.     hcd->self.root_hub = NULL;
  125.     usb_put_dev(rhdev);
  126. err_allocate_root_hub:
  127.     usb_deregister_bus(&hcd->self);
  128. err_register_bus:
  129.     hcd_buffer_destroy(hcd);
  130.     return retval;
  131. }



函数



点击(此处)折叠或打开

  1. /**
  2.  * usb_alloc_dev - usb device constructor (usbcore-internal)
  3.  * @parent: hub to which device is connected; null to allocate a root hub
  4.  * @bus: bus used to access the device
  5.  * @port1: one-based index of port; ignored for root hubs
  6.  * Context: !in_interrupt()
  7.  *
  8.  * Only hub drivers (including virtual root hub drivers for host
  9.  * controllers) should ever call this.
  10.  *
  11.  * This call may not be used in a non-sleeping context.
  12.  */
  13. struct usb_device *usb_alloc_dev(struct usb_device *parent,
  14.                  struct usb_bus *bus, unsigned port1)
  15. {
  16.     struct usb_device *dev;
  17.     struct usb_hcd *usb_hcd = container_of(bus, struct usb_hcd, self);
  18.     unsigned root_hub = 0;
  19. //usb设备对象;
  20.     dev = kzalloc(sizeof(*dev), GFP_KERNEL);
  21.     if (!dev)
  22.         return NULL;

  23.     if (!usb_get_hcd(bus_to_hcd(bus))) {
  24.         kfree(dev);
  25.         return NULL;
  26.     }
  27.     /* Root hubs aren't true devices, so don't allocate HCD resources */
  28.     if (usb_hcd->driver->alloc_dev && parent &&
  29.         !usb_hcd->driver->alloc_dev(usb_hcd, dev)) {
  30.         usb_put_hcd(bus_to_hcd(bus));
  31.         kfree(dev);
  32.         return NULL;
  33.     }
  34.     //usb_device_type
  35. //usb设备的基本属性还是device;
  36.     device_initialize(&dev->dev);
  37.     dev->dev.bus = &usb_bus_type;//所属总线;
  38.     dev->dev.type = &usb_device_type;//usb设备类型,有别于usb_if_device_type;
  39.     dev->dev.groups = usb_device_groups;
  40.     dev->dev.dma_mask = bus->controller->dma_mask;
  41.     set_dev_node(&dev->dev, dev_to_node(bus->controller));
  42.     //USB设备的状态变化;表示已连接上(生来就是在一起的)
  43.     //后面这个状态会一直变化的;
  44.     dev->state = USB_STATE_ATTACHED;
  45.     atomic_set(&dev->urbnum, 0);

  46.     INIT_LIST_HEAD(&dev->ep0.urb_list);
  47.     //初始化端点信息
  48.     dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE;
  49.     dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT;
  50.     /* ep0 maxpacket comes later, from device descriptor */
  51.     //使能控制:ep->enabled = 1;
  52.     usb_enable_endpoint(dev, &dev->ep0, false);
  53.     dev->can_submit = 1;

  54.     /* Save readable and stable topology id, distinguishing devices
  55.      * by location for diagnostics, tools, driver model, etc. The
  56.      * string is a path along hub ports, from the root. Each device's
  57.      * dev->devpath will be stable until USB is re-cabled, and hubs
  58.      * are often labeled with these port numbers. The name isn't
  59.      * as stable: bus->busnum changes easily from modprobe order,
  60.      * cardbus or pci hotplugging, and so on.
  61.      */
  62.     if (unlikely(!parent)) {//hub就是这条路;
  63.         dev->devpath[0] = '0';
  64.         dev->route = 0;

  65.         dev->dev.parent = bus->controller;
  66.         dev_set_name(&dev->dev, "usb%d", bus->busnum);//设备名称usbXX
  67.         root_hub = 1;
  68.     } else {
  69.         /* match any labeling on the hubs; it's one-based */
  70.         if (parent->devpath[0] == '0') {
  71.             snprintf(dev->devpath, sizeof dev->devpath,
  72.                 "%d", port1);
  73.             /* Root ports are not counted in route string */
  74.             dev->route = 0;
  75.         } else {
  76.             snprintf(dev->devpath, sizeof dev->devpath,
  77.                 "%s.%d", parent->devpath, port1);
  78.             /* Route string assumes hubs have less than 16 ports */
  79.             if (port1 < 15)
  80.                 dev->route = parent->route +
  81.                     (port1 << ((parent->level - 1)*4));
  82.             else
  83.                 dev->route = parent->route +
  84.                     (15 << ((parent->level - 1)*4));
  85.         }

  86.         dev->dev.parent = &parent->dev;
  87.         dev_set_name(&dev->dev, "%d-%s", bus->busnum, dev->devpath);

  88.         /* hub driver sets up TT records */
  89.     }

  90.     dev->portnum = port1;
  91.     dev->bus = bus;
  92.     dev->parent = parent;
  93.     INIT_LIST_HEAD(&dev->filelist);

  94. #ifdef    CONFIG_PM
  95.     mutex_init(&dev->pm_mutex);
  96.     INIT_DELAYED_WORK(&dev->autosuspend, usb_autosuspend_work);
  97.     INIT_WORK(&dev->autoresume, usb_autoresume_work);
  98.     dev->autosuspend_delay = usb_autosuspend_delay * HZ;
  99.     dev->connect_time = jiffies;
  100.     dev->active_duration = -jiffies;
  101. #endif
  102.     if (root_hub)    /* Root hub always ok [and always wired] */
  103.         dev->authorized = 1;//hub 默认;
  104.     else {
  105.         dev->authorized = usb_hcd->authorized_default;
  106.         dev->wusb = usb_bus_is_wusb(bus)? 1 : 0;
  107.     }
  108.     return dev;
  109. }


函数三


点击(此处)折叠或打开

  1. /**
  2.  * register_root_hub - called by usb_add_hcd() to register a root hub
  3.  * @hcd: host controller for this root hub
  4.  *
  5.  * This function registers the root hub with the USB subsystem. It sets up
  6.  * the device properly in the device tree and then calls usb_new_device()
  7.  * to register the usb device. It also assigns the root hub's USB address
  8.  * (always 1).
  9.  */
  10. static int register_root_hub(struct usb_hcd *hcd)
  11. {
  12.     struct device *parent_dev = hcd->self.controller;
  13.     struct usb_device *usb_dev = hcd->self.root_hub;
  14.     const int devnum = 1;
  15.     int retval;

  16.     usb_dev->devnum = devnum;
  17.     usb_dev->bus->devnum_next = devnum + 1;
  18.     memset (&usb_dev->bus->devmap.devicemap, 0,
  19.             sizeof usb_dev->bus->devmap.devicemap);
  20.     set_bit (devnum, usb_dev->bus->devmap.devicemap);
  21. //作为usb设备状态,第二种:USB_STATE_ADDRESS
  22.     usb_set_device_state(usb_dev, USB_STATE_ADDRESS);

  23.     mutex_lock(&usb_bus_list_lock);

  24.     usb_dev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
  25. //usb_get_descriptor--usb_control_msg--usb_start_wait_urb--usb_hcd_submit_urb--rh_urb_enqueue
  26. //其实只知道一点就好了,roothub的描述符都是不需要控制器帮忙的,
  27. //自带的;hub.c中有列出来;
  28.     retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);
  29.     if (retval != sizeof usb_dev->descriptor) {
  30.         mutex_unlock(&usb_bus_list_lock);
  31.         dev_dbg (parent_dev, "can't read %s device descriptor %d\n",
  32.                 dev_name(&usb_dev->dev), retval);
  33.         return (retval < 0) ? retval : -EMSGSIZE;
  34.     }
  35. //这里面就是很熟悉的代码了
  36. //device_add(dev);
  37.     retval = usb_new_device (usb_dev);
  38.     if (retval) {
  39.         dev_err (parent_dev, "can't register root hub for %s, %d\n",
  40.                 dev_name(&usb_dev->dev), retval);
  41.     }
  42.     mutex_unlock(&usb_bus_list_lock);

  43.     if (retval == 0) {
  44.         spin_lock_irq (&hcd_root_hub_lock);
  45.         hcd->rh_registered = 1;
  46.         spin_unlock_irq (&hcd_root_hub_lock);

  47.         /* Did the HC die before the root hub was registered? */
  48.         if (hcd->state == HC_STATE_HALT)
  49.             usb_hc_died (hcd);    /* This time clean up */
  50.     }

  51.     return retval;
  52. }



阅读(1479) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~