usb suspend

ddv posted @ 2009年9月28日 19:09 in Linux driver , 15145 阅读

 driver/usb/core/hub.c

  1. /**
  2. * usb_reset_device - warn interface drivers and perform a USB port reset
  3. * @udev: device to reset (not in SUSPENDED or NOTATTACHED state)
  4. *
  5. * Warns all drivers bound to registered interfaces (using their pre_reset
  6. * method), performs the port reset, and then lets the drivers know that
  7. * the reset is over (using their post_reset method).
  8. *
  9. * Return value is the same as for usb_reset_and_verify_device().
  10. *
  11. * The caller must own the device lock.  For example, it's safe to use
  12. * this from a driver probe() routine after downloading new firmware.
  13. * For calls that might not occur during probe(), drivers should lock
  14. * the device using usb_lock_device_for_reset().
  15. *
  16. * If an interface is currently being probed or disconnected, we assume
  17. * its driver knows how to handle resets.  For all other interfaces,
  18. * if the driver doesn't have pre_reset and post_reset methods then
  19. * we attempt to unbind it and rebind afterward.
  20. */
  21. int usb_reset_device(struct usb_device *udev)
  22. {
  23.         int ret;
  24.         int i;
  25.         struct usb_host_config *config = udev->actconfig;
  26.  
  27.         if (udev->state == USB_STATE_NOTATTACHED ||
  28.                         udev->state == USB_STATE_SUSPENDED) {
  29.                 dev_dbg(&udev->dev, "device reset not allowed in state %d\n",
  30.                                 udev->state);
  31.                 return -EINVAL;
  32.         }
  33.  
  34.         /* Prevent autosuspend during the reset */
  35.         usb_autoresume_device(udev);
  36.  
  37.         if (config) {
  38.                 for (i = 0; i < config->desc.bNumInterfaces; ++i) {
  39.                         struct usb_interface *cintf = config->interface[i];
  40.                         struct usb_driver *drv;
  41.                         int unbind = 0;
  42.  
  43.                         if (cintf->dev.driver) {
  44.                                 drv = to_usb_driver(cintf->dev.driver);
  45.                                 if (drv->pre_reset && drv->post_reset)
  46.                                         unbind = (drv->pre_reset)(cintf);
  47.                                 else if (cintf->condition ==
  48.                                                 USB_INTERFACE_BOUND)
  49.                                         unbind = 1;
  50.                                 if (unbind)
  51.                                         usb_forced_unbind_intf(cintf);
  52.                         }
  53.                 }
  54.         }
  55.  
  56.         ret = usb_reset_and_verify_device(udev);
  57.  
  58.         if (config) {
  59.                 for (i = config->desc.bNumInterfaces - 1; i >= 0; --i) {
  60.                         struct usb_interface *cintf = config->interface[i];
  61.                         struct usb_driver *drv;
  62.                         int rebind = cintf->needs_binding;
  63.  
  64.                         if (!rebind && cintf->dev.driver) {
  65.                                 drv = to_usb_driver(cintf->dev.driver);
  66.                                 if (drv->post_reset)
  67.                                         rebind = (drv->post_reset)(cintf);
  68.                                 else if (cintf->condition ==
  69.                                                 USB_INTERFACE_BOUND)
  70.                                         rebind = 1;
  71.                         }
  72.                         if (ret == 0 && rebind)
  73.                                 usb_rebind_intf(cintf);
  74.                 }
  75.         }
  76.  
  77.         usb_autosuspend_device(udev);
  78.         return ret;
  79. }

这个函数实现的功能:通知接口驱动并执行USB端口重置。参数udev就是想要重置的那个设备。预先通知所有的已绑定的注册了的接口,执行端口重置,并让驱动知道重置结束。27-32行,先判断一下这个设备,如果是USB_STATE_NOTATTACHED 或者USB_STATE_SUSPENDED,那么就打印该状态不允许重置并返回;35行,autoresume为防止在重置过程中autosuspend;37-54行,将当前配置的所有接口驱动和接口解绑;56行,真正的执行重置的函数,并做检验;58-75行,将当前配置的所有接口和接口驱动重新绑定;77行,打开autosuspend;最后返回。

  1. /**
  2. * usb_reset_and_verify_device - perform a USB port reset to reinitialize a device
  3. * @udev: device to reset (not in SUSPENDED or NOTATTACHED state)
  4. *
  5. * WARNING - don't use this routine to reset a composite device
  6. * (one with multiple interfaces owned by separate drivers)!
  7. * Use usb_reset_device() instead.
  8. *
  9. * Do a port reset, reassign the device's address, and establish its
  10. * former operating configuration.  If the reset fails, or the device's
  11. * descriptors change from their values before the reset, or the original
  12. * configuration and altsettings cannot be restored, a flag will be set
  13. * telling khubd to pretend the device has been disconnected and then
  14. * re-connected.  All drivers will be unbound, and the device will be
  15. * re-enumerated and probed all over again.
  16. *
  17. * Returns 0 if the reset succeeded, -ENODEV if the device has been
  18. * flagged for logical disconnection, or some other negative error code
  19. * if the reset wasn't even attempted.
  20. *
  21. * The caller must own the device lock.  For example, it's safe to use
  22. * this from a driver probe() routine after downloading new firmware.
  23. * For calls that might not occur during probe(), drivers should lock
  24. * the device using usb_lock_device_for_reset().
  25. *
  26. * Locking exception: This routine may also be called from within an
  27. * autoresume handler.  Such usage won't conflict with other tasks
  28. * holding the device lock because these tasks should always call
  29. * usb_autopm_resume_device(), thereby preventing any unwanted autoresume.
  30. */
  31. static int usb_reset_and_verify_device(struct usb_device *udev)
  32. {
  33.         struct usb_device              *parent_hdev = udev->parent;
  34.         struct usb_hub      *parent_hub;
  35.         struct usb_device_descriptor    descriptor = udev->descriptor;
  36.         int                 i, ret = 0;
  37.         int                    port1 = udev->portnum;
  38.  
  39.         if (udev->state == USB_STATE_NOTATTACHED ||
  40.                         udev->state == USB_STATE_SUSPENDED) {
  41.                 dev_dbg(&udev->dev, "device reset not allowed in state %d\n",
  42.                                 udev->state);
  43.                 return -EINVAL;
  44.         }
  45.  
  46.         if (!parent_hdev) {
  47.                 /* this requires hcd-specific logic; see OHCI hc_restart() */
  48.                 dev_dbg(&udev->dev, "%s for root hub!\n", __func__);
  49.                 return -EISDIR;
  50.         }
  51.         parent_hub = hdev_to_hub(parent_hdev);
  52.  
  53.         set_bit(port1, parent_hub->busy_bits);
  54.         for (i = 0; i < SET_CONFIG_TRIES; ++i) {
  55.  
  56.                 /* ep0 maxpacket size may change; let the HCD know about it.
  57.                  * Other endpoints will be handled by re-enumeration. */
  58.                 usb_ep0_reinit(udev);
  59.                 ret = hub_port_init(parent_hub, udev, port1, i);
  60.                 if (ret >= 0 || ret == -ENOTCONN || ret == -ENODEV)
  61.                         break;
  62.         }
  63.         clear_bit(port1, parent_hub->busy_bits);
  64.  
  65.         if (ret < 0)
  66.                 goto re_enumerate;
  67.  
  68.         /* Device might have changed firmware (DFU or similar) */
  69.         if (descriptors_changed(udev, &descriptor)) {
  70.                 dev_info(&udev->dev, "device firmware changed\n");
  71.                 udev->descriptor = descriptor;  /* for disconnect() calls */
  72.                 goto re_enumerate;
  73.         }
  74.  
  75.         if (!udev->actconfig)
  76.                 goto done;
  77.  
  78.         ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  79.                         USB_REQ_SET_CONFIGURATION, 0,
  80.                         udev->actconfig->desc.bConfigurationValue, 0,
  81.                         NULL, 0, USB_CTRL_SET_TIMEOUT);
  82.         if (ret < 0) {
  83.                 dev_err(&udev->dev,
  84.                         "can't restore configuration #%d (error=%d)\n",
  85.                         udev->actconfig->desc.bConfigurationValue, ret);
  86.                 goto re_enumerate;
  87.         }
  88.         usb_set_device_state(udev, USB_STATE_CONFIGURED);
  89.  
  90.         for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
  91.                 struct usb_interface *intf = udev->actconfig->interface[i];
  92.                 struct usb_interface_descriptor *desc;
  93.  
  94.                 /* set_interface resets host side toggle even
  95.                  * for altsetting zero.  the interface may have no driver.
  96.                  */
  97.                 desc = &intf->cur_altsetting->desc;
  98.                 ret = usb_set_interface(udev, desc->bInterfaceNumber,
  99.                         desc->bAlternateSetting);
  100.                 if (ret < 0) {
  101.                         dev_err(&udev->dev, "failed to restore interface %d "
  102.                                 "altsetting %d (error=%d)\n",
  103.                                 desc->bInterfaceNumber,
  104.                                 desc->bAlternateSetting,
  105.                                 ret);
  106.                         goto re_enumerate;
  107.                 }
  108.         }
  109.  
  110. done:
  111.         return 0;
  112.  
  113. re_enumerate:
  114.         hub_port_logical_disconnect(parent_hub, port1);
  115.         return -ENODEV;
  116. }

其实重置就是将重置的设备重新初始化。这个函数一般通过usb_reset_device()调用。132行,设置usb_hub->busy_bits,表示设置正在重置或者resume;133-141行,重新初始化端点0并初始化端口;142行,清除usb_hub->busy_bits,表示初始化结束;144-145行,如果上面的端口初始化失败,那么跳转到re_enumerate标志处执行标志段,hub_port_logical_disconnect(parent_hub, port)设置逻辑的连接变化事件,然后khubd会重新枚举这个设备。

 

 

 

 

Avatar_small
maid services dubai 说:
2019年9月14日 15:55

With regard to larger jobs as an apartment complicated, a list complex, an work place, a resort, or a sizable leasing neighborhood, a full-time cleaning service is probably in purchase. Janitorial services could be much more inexpensive than getting an in-house solution. Plus, you will get a assure from the majority of cleaning companies in addition to proof associated with insurance.

Avatar_small
freezebusinessrates. 说:
2019年11月14日 00:39

or many of us, buying a residence is quite possibly the most costly and even significant fee they'll ever in your life make to their lives. That's why, it helps to stay the can spend ones own mortgage bucks wisely.

Avatar_small
sikkim health 说:
2020年3月19日 20:00

Wellness worries really serve an objective and this particular purpose isn't difficult in order to detect in the event that one appears deep sufficient into this particular pattern associated with behavior. Often this particular pattern involves the mind distracting through specific emotions that the individual discovers difficult to deal with.

Avatar_small
clean tech laws 说:
2020年3月19日 20:01

Help to make personal obligation your default environment. Yes, initially it's easier, cheaper and much more convenient at fault, excuse, refuse and/or disregard responsibility compared to to accept it. Such would be the current default settings in many cultures, including our very own. In the actual long otherwise medium variety, however, it's healthier, as pleasing and far better to assume a minimum of some level of responsibility.

Avatar_small
bank ruptcy law merc 说:
2020年3月19日 20:01

The actual demand with regard to law school and also the government subsidization associated with school resulted in the growth from the school business, aided through publications such as U. Utes. News using its ludicrous college rankings. Schools grew to become financial revenue centers associated with universities (such as successful sports activities programs) and in some cases were necessary to kick back again money towards the central college administration to assist underwrite all of those other less profitable areas of the college.

Avatar_small
dui lawyer montreal 说:
2020年3月19日 20:01

What the law states of Appeal has received a lot of media attention recently. Thanks towards the movie The key and the next explosion associated with television, printing media as well as internet protection, nearly everybody in Traditional western society offers heard the actual phrase "Law associated with Attraction".

Avatar_small
wendy wood law 说:
2020年3月19日 20:02

If we're able to accept that possibilities exist in our moment as well as remain focused within the Now associated with life, consciously permitting the Laws and regulations of Existence to readily operate via us, we'd soon notice that we have been in a co-created globe which we now have personal obligation for getting into living.

Avatar_small
maids in dubai 说:
2020年4月28日 19:13

After you hire some sort of servant maid to decontaminate you office or house, you usually are permitting her to reach to your very own belongings. And so before getting a house maid, you really should ask a number of questions to find out about her track record information in addition to personal recommendations. First matter is of which, you really should inquire your buddies, relatives or maybe acquaintances with regards to personal experience while using the servant maids.

Avatar_small
painters in Dubai 说:
2020年4月28日 19:13

If you would like give the house a certain style of atmosphere, then inner surface paints are important. The paints you choose are able to offer either temperature or coolness towards rooms of your dwelling and if you need to paint by yourself or seek the services of house painters; keep as the primary goal we now have many ideas that you consider. These thoughts include buying things such as right colour, colors, colours, schemes, coloration methods, along with related facets.


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter