USB: Add support to enable/disable USB3 link states.
[cascardo/linux.git] / include / linux / usb.h
index 73b68d1..40439df 100644 (file)
@@ -351,10 +351,6 @@ struct usb_bus {
        int bandwidth_int_reqs;         /* number of Interrupt requests */
        int bandwidth_isoc_reqs;        /* number of Isoc. requests */
 
-#ifdef CONFIG_USB_DEVICEFS
-       struct dentry *usbfs_dentry;    /* usbfs dentry entry for the bus */
-#endif
-
 #if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)
        struct mon_bus *mon_bus;        /* non-null when associated */
        int monitored;                  /* non-zero when monitored */
@@ -382,6 +378,45 @@ enum usb_device_removable {
        USB_DEVICE_FIXED,
 };
 
+/*
+ * USB 3.0 Link Power Management (LPM) parameters.
+ *
+ * PEL and SEL are USB 3.0 Link PM latencies for device-initiated LPM exit.
+ * MEL is the USB 3.0 Link PM latency for host-initiated LPM exit.
+ * All three are stored in nanoseconds.
+ */
+struct usb3_lpm_parameters {
+       /*
+        * Maximum exit latency (MEL) for the host to send a packet to the
+        * device (either a Ping for isoc endpoints, or a data packet for
+        * interrupt endpoints), the hubs to decode the packet, and for all hubs
+        * in the path to transition the links to U0.
+        */
+       unsigned int mel;
+       /*
+        * Maximum exit latency for a device-initiated LPM transition to bring
+        * all links into U0.  Abbreviated as "PEL" in section 9.4.12 of the USB
+        * 3.0 spec, with no explanation of what "P" stands for.  "Path"?
+        */
+       unsigned int pel;
+
+       /*
+        * The System Exit Latency (SEL) includes PEL, and three other
+        * latencies.  After a device initiates a U0 transition, it will take
+        * some time from when the device sends the ERDY to when it will finally
+        * receive the data packet.  Basically, SEL should be the worse-case
+        * latency from when a device starts initiating a U0 transition to when
+        * it will get data.
+        */
+       unsigned int sel;
+       /*
+        * The idle timeout value that is currently programmed into the parent
+        * hub for this device.  When the timer counts to zero, the parent hub
+        * will initiate an LPM transition to either U1 or U2.
+        */
+       int timeout;
+};
+
 /**
  * struct usb_device - kernel's representation of a USB device
  * @devnum: device number; address on a USB bus
@@ -439,6 +474,12 @@ enum usb_device_removable {
  *     specific data for the device.
  * @slot_id: Slot ID assigned by xHCI
  * @removable: Device can be physically removed from this port
+ * @u1_params: exit latencies for USB3 U1 LPM state, and hub-initiated timeout.
+ * @u2_params: exit latencies for USB3 U2 LPM state, and hub-initiated timeout.
+ * @lpm_disable_count: Ref count used by usb_disable_lpm() and usb_enable_lpm()
+ *     to keep track of the number of functions that require USB 3.0 Link Power
+ *     Management to be disabled for this usb_device.  This count should only
+ *     be manipulated by those functions, with the bandwidth_mutex is held.
  *
  * Notes:
  * Usbcore drivers should not set usbdev->state directly.  Instead use
@@ -493,12 +534,6 @@ struct usb_device {
        char *serial;
 
        struct list_head filelist;
-#ifdef CONFIG_USB_DEVICE_CLASS
-       struct device *usb_classdev;
-#endif
-#ifdef CONFIG_USB_DEVICEFS
-       struct dentry *usbfs_dentry;
-#endif
 
        int maxchild;
        struct usb_device **children;
@@ -517,6 +552,9 @@ struct usb_device {
        struct wusb_dev *wusb_dev;
        int slot_id;
        enum usb_device_removable removable;
+       struct usb3_lpm_parameters u1_params;
+       struct usb3_lpm_parameters u2_params;
+       unsigned lpm_disable_count;
 };
 #define        to_usb_device(d) container_of(d, struct usb_device, dev)
 
@@ -552,6 +590,12 @@ extern void usb_autopm_put_interface_async(struct usb_interface *intf);
 extern void usb_autopm_get_interface_no_resume(struct usb_interface *intf);
 extern void usb_autopm_put_interface_no_suspend(struct usb_interface *intf);
 
+extern int usb_disable_lpm(struct usb_device *udev);
+extern void usb_enable_lpm(struct usb_device *udev);
+/* Same as above, but these functions lock/unlock the bandwidth_mutex. */
+extern int usb_unlocked_disable_lpm(struct usb_device *udev);
+extern void usb_unlocked_enable_lpm(struct usb_device *udev);
+
 static inline void usb_mark_last_busy(struct usb_device *udev)
 {
        pm_runtime_mark_last_busy(&udev->dev);
@@ -800,6 +844,8 @@ extern ssize_t usb_store_new_id(struct usb_dynids *dynids,
                                struct device_driver *driver,
                                const char *buf, size_t count);
 
+extern ssize_t usb_show_dynids(struct usb_dynids *dynids, char *buf);
+
 /**
  * struct usbdrv_wrap - wrapper for driver-model structure
  * @driver: The driver-model core driver structure.
@@ -850,6 +896,9 @@ struct usbdrv_wrap {
  *     for interfaces bound to this driver.
  * @soft_unbind: if set to 1, the USB core will not kill URBs and disable
  *     endpoints before calling the driver's disconnect method.
+ * @disable_hub_initiated_lpm: if set to 0, the USB core will not allow hubs
+ *     to initiate lower power link state transitions when an idle timeout
+ *     occurs.  Device-initiated USB 3.0 link PM will still be allowed.
  *
  * USB interface drivers must provide a name, probe() and disconnect()
  * methods, and an id_table.  Other driver fields are optional.
@@ -890,6 +939,7 @@ struct usb_driver {
        struct usbdrv_wrap drvwrap;
        unsigned int no_dynamic_id:1;
        unsigned int supports_autosuspend:1;
+       unsigned int disable_hub_initiated_lpm:1;
        unsigned int soft_unbind:1;
 };
 #define        to_usb_driver(d) container_of(d, struct usb_driver, drvwrap.driver)
@@ -1379,6 +1429,7 @@ extern int usb_unlink_urb(struct urb *urb);
 extern void usb_kill_urb(struct urb *urb);
 extern void usb_poison_urb(struct urb *urb);
 extern void usb_unpoison_urb(struct urb *urb);
+extern void usb_block_urb(struct urb *urb);
 extern void usb_kill_anchored_urbs(struct usb_anchor *anchor);
 extern void usb_poison_anchored_urbs(struct usb_anchor *anchor);
 extern void usb_unpoison_anchored_urbs(struct usb_anchor *anchor);
@@ -1391,6 +1442,8 @@ extern struct urb *usb_get_from_anchor(struct usb_anchor *anchor);
 extern void usb_scuttle_anchored_urbs(struct usb_anchor *anchor);
 extern int usb_anchor_empty(struct usb_anchor *anchor);
 
+#define usb_unblock_urb        usb_unpoison_urb
+
 /**
  * usb_urb_dir_in - check if an URB describes an IN transfer
  * @urb: URB to be checked
@@ -1627,6 +1680,7 @@ static inline int usb_translate_errors(int error_code)
        case 0:
        case -ENOMEM:
        case -ENODEV:
+       case -EOPNOTSUPP:
                return error_code;
        default:
                return -EIO;
@@ -1652,9 +1706,6 @@ do {                                                                      \
 } while (0)
 #endif
 
-#define err(format, arg...)                                    \
-       printk(KERN_ERR KBUILD_MODNAME ": " format "\n", ##arg)
-
 /* debugfs stuff */
 extern struct dentry *usb_debug_root;