Re: [PATCH 0/3] ACPI / bind: Use struct acpi_device pointers instead of ACPI handles

2013-11-28 Thread Lan Tianyu
On 2013年11月29日 08:36, Rafael J. Wysocki wrote:
 Hi,
 
 Now that we store a pointer to struct acpi_device as the ACPI companion in
 struct device, the code making associations between physical devices and
 ACPI device objects can be modified to work with struct acpi_device pointers
 instead of ACPI handles too.  The first two of the following patches make 
 these
 changes and the third one is just a related cleanup.
 
 [1/3] ACPI / bind: Replace .find_device in struct acpi_bus_type with 
 .find_companion
 [2/3] ACPI / bind: Modify acpi_bind_one() to take a struct acpi_device 
 pointer as
   the second argument.
 [3/3] ACPI / bind: Move acpi_get_child() to ide-acpi.c which is the only 
 remaining
   user of that function.
 

Test usb/ACPI bind part, it works normally.

Tested-by: Lan Tianyu tianyu@intel.com

 The patches are on top of linux-pm.git/linux-next.  Please let me know if you 
 see
 any problems in them.
 
 Thanks!
 


-- 
Best regards
Tianyu Lan
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC Patch] USB: Add check for portnum in the usb_acpi_find_device()

2013-06-02 Thread Lan Tianyu

On 2013/5/31 19:18 Greg KH wrote the following:

On Fri, May 31, 2013 at 02:18:06PM +0800, Lan Tianyu wrote:

This patch is to add a check of portnum which from the usb
port dev's name.


Why do we need this now?


The portnum will be used as array index
for struct usb_hub-ports in the usb_set_hub_port_connect_type().


Is something failing today without this check?  We don't add code to the
kernel until we need it...

No, actually current code will not fail. The patch is the result of
analysis tools Klockwork which is pushed by some QAs. I just notice 
you have said to be over-eager in checking parameters that we have full 
control of is not needed at all. So please ignore this. Sorry for noise.


http://marc.info/?l=linux-usbm=136984950910015w=2


thanks,

greg k-h



--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC Patch] USB: Add check for portnum in the usb_acpi_find_device()

2013-05-31 Thread Lan Tianyu
This patch is to add a check of portnum which from the usb
port dev's name. The portnum will be used as array index
for struct usb_hub-ports in the usb_set_hub_port_connect_type().

Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/usb-acpi.c |3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
index 255c144..ec0e7cf 100644
--- a/drivers/usb/core/usb-acpi.c
+++ b/drivers/usb/core/usb-acpi.c
@@ -183,6 +183,9 @@ static int usb_acpi_find_device(struct device *dev, 
acpi_handle *handle)
/* Get the struct usb_device point of port's hub */
udev = to_usb_device(dev-parent-parent);
 
+   if (port_num == 0 || port_num  udev-maxchild)
+   return -EINVAL;
+
/*
 * The root hub ports' parent is the root hub. The non-root-hub
 * ports' parent is the parent hub port which the hub is
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/4] usb: introduce usb force power off mechanism

2013-04-08 Thread Lan Tianyu

On 2013/3/30 4:24, Alan Stern wrote:

On Fri, 29 Mar 2013, Sarah Sharp wrote:


Also, bear in mind that the proposed patch does not give userspace a
way to power off ports via usbfs.  What the new code does is a
power-off reset -- it turns off power to the port, waits a short time,
and then turns power back on.


I think we need two separate IOCTLs: turn off the port power and turn it
on.  Then we get the manual port power off for our QA testing, distros
can make interesting policies about manually powering off ports, and
userspace can choose how long they want the port to be off.  After all,
different devices may need a longer powered-off period than others.


Or one port-power IOCTL that takes the setting as an argument.  Yes,
this would be more flexible than a power-off reset.

Hi Alan  Sarah:
I just recall why I put power off and power on in one ioctl.
At first, I also tried to make power on and power off into two ioctls.
But I found after powering off a device, the usbfs device node will
be removed and so can't power on the port via the same usbfs node.

For this point, we should add usbfs node for usb port?



Alan Stern



--
Best Regards
Tianyu Lan
linux kernel enabling team
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/4] usb: introduce usb force power off mechanism

2013-04-08 Thread Lan Tianyu

On 2013/4/1 23:12, Alan Stern wrote:

On Mon, 1 Apr 2013, Lan Tianyu wrote:


On 2013年03月30日 01:23, Alan Stern wrote:

On Fri, 29 Mar 2013, Sarah Sharp wrote:

However, what happens if you echo 0 to pm_qos_no_power_off, the
power/control is set to auto, and there's a suspended USB device
attached to the port with remote wakeup enabled?  Will the port be
powered off?  I don't think it will with the current patchset, but I
will have to double check.


It shouldn't be, because remote wakeup is enabled.  But what about the
case where remote wakeup is disabled?  Will writing a 0 to
pm_qos_no_power_off cause the power to be turned off?

Or what about the case where there's no device attached to the port?  I
guess both questions amount to the same thing: When the user writes to
a pm_qos_* file, does the code call pm_runtime_idle?



Usb port's initial usage count is 0. For port attached with usb port,
when usb device is connected, the usb port's usage count is increased by
one. During device's suspend, its usage count would be decreased to 0
and powered of only when remote wakeup disable, persist enable and PM
Qos NO_POWER_OFF unsetting.


I already know all this.


During pm_qos_* file changing, pm_runtime_get_sync/put(port_dev) will be
done in the dev_pm_qos_update_flags(). The port's  usage count would be
increased and decreased by 1. Whether the port's pm_runtime_idle would
be called depends on port's usage count to be set to 0.


That answers my question.


If the usb port has already been powered off(port usage count is already
set to 0), it would be powered on first and powered off depending the PM
Qos NO_POWER_OFF flag value.


Obviously.


If the usb port wasn't powered off, this mean the usb port didn't meet
power off condition() and  its usage count was still greater than 0 So
during changing flag, only usage count was changed and no actual operation.


No, because one of the power off conditions is that the NO_POWER_OFF
flag must be clear.  If that flag was set, the port won't be powered
off even though the usage count is equal to 0.  If the write to the
pm_qos_* file then clears the flag, the port _will_ get powered off.


Hi Alan:
I think current code can't achieve that power off port(whose
child device was already suspended but it was not powered off due to
NO_POWER_OFF flag setting.) via clearing NO_POWER_OFF flag. Because
at that moment, its usage count can't be 0. At last, it should be
1 or large. port's pm_runtime_idle will not be called.

Further thinking, now we call pm_runtime_put_sync() in the
usb_port_suspend() when persist enable, do_remote_wakeup disable and
PM Qos NO_POWER_OFF flag cleared. But PM Qos NO_POWER_OFF flag will
also will be checked in the usb_port_runtime_suspend(). This seems
redundant.

From my opinion, the PM Qos check in the usb_port_suspend()
should be removed and port usage count will reach 0 when persist enable
and remote_wakeup disable. Whether power off or not totally depends on
the PM Qos flag in the usb_port_runtime_suspend(). For NO_POWER_OFF flag
setting case during usb device being suspend, the port's usage count
will be 0 but its runtime status is still active due to flag being set
and usb_port_runtime_suspend() returns -EAGAIN. At this time, clearing
the flag and the port can be powered off. Does this make sense?




For empty port, Only when PM Qos NO_POWER_OFF flag value is set to 0,
the port will be power off.


Alan Stern




--
Best Regards
Tianyu Lan
linux kernel enabling team
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/4] usb: introduce usb force power off mechanism

2013-04-01 Thread Lan Tianyu
On 2013年03月29日 22:11, Alan Stern wrote:
 On Fri, 29 Mar 2013, Lan Tianyu wrote:
 
 Actually, I exposed pm qos flags for usb port via dev_pm_qos_expose_flags().
 It creates power/pm_qos_no_power_off under usb port sysfs directory.
 User can echo 0  pm_qos_no_power_off to power off the empty port.
 
 Before it's too late, we should consider changing the flag's name.  
 Writing 0 to a file named pm_qos_no_power_off is a double negative, 
 which is always awkward to think about.
 
 Instead, how about calling the file pm_qos_allow_power_off?  Will the
 PM-QOS system allow something like that, i.e., something that is the
 opposite of a constraint?
 
 If not, how about naming it pm_qos_keep_power_on?
This is PM core sysfs attribute and I am not sure that this can be changed.

CC: Rafael.

 
 Alan Stern
 


-- 
Best regards
Tianyu Lan
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/4] usb: introduce usb force power off mechanism

2013-04-01 Thread Lan Tianyu
On 2013年03月30日 01:23, Alan Stern wrote:
 On Fri, 29 Mar 2013, Sarah Sharp wrote:
 However, what happens if you echo 0 to pm_qos_no_power_off, the
 power/control is set to auto, and there's a suspended USB device
 attached to the port with remote wakeup enabled?  Will the port be
 powered off?  I don't think it will with the current patchset, but I
 will have to double check.
 
 It shouldn't be, because remote wakeup is enabled.  But what about the
 case where remote wakeup is disabled?  Will writing a 0 to
 pm_qos_no_power_off cause the power to be turned off?
 
 Or what about the case where there's no device attached to the port?  I 
 guess both questions amount to the same thing: When the user writes to 
 a pm_qos_* file, does the code call pm_runtime_idle?
 

Usb port's initial usage count is 0. For port attached with usb port,
when usb device is connected, the usb port's usage count is increased by
one. During device's suspend, its usage count would be decreased to 0
and powered of only when remote wakeup disable, persist enable and PM
Qos NO_POWER_OFF unsetting.

During pm_qos_* file changing, pm_runtime_get_sync/put(port_dev) will be
done in the dev_pm_qos_update_flags(). The port's  usage count would be
increased and decreased by 1. Whether the port's pm_runtime_idle would
be called depends on port's usage count to be set to 0.

If the usb port has already been powered off(port usage count is already
set to 0), it would be powered on first and powered off depending the PM
Qos NO_POWER_OFF flag value.

If the usb port wasn't powered off, this mean the usb port didn't meet
power off condition() and  its usage count was still greater than 0 So
during changing flag, only usage count was changed and no actual operation.

For empty port, Only when PM Qos NO_POWER_OFF flag value is set to 0,
the port will be power off.

 
 Alan Stern
 


-- 
Best regards
Tianyu Lan
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/4] usb: introduce usb force power off mechanism

2013-03-29 Thread Lan Tianyu

On 2013/3/29 6:43, Sarah Sharp wrote:

On Thu, Mar 28, 2013 at 05:00:23PM -0400, Alan Stern wrote:

On Thu, 28 Mar 2013, Sarah Sharp wrote:


On Thu, Mar 28, 2013 at 01:11:02AM +0800, Lan Tianyu wrote:

Some devices' firmware will be broken at some points. Power down
and power on device can help device to rework in this case.

This patch is to add ioctl cmd USBDEVFS_POWER_RESET for usbfs node
to repower usb device. First, call hub_port_logical_disconnect() to
disconnect device. Second, Power down and up usb port.


I don't think this is the right approach.  We want to be able to power
off a port, even if no devices are attached.  One of the use case
scenarios we discussed was allowing distros to turn off empty USB ports
according to some policy (e.g. screen blank, lost bluetooth connection
to their phone that indicates the user walked away from the computer,
server admin wants to save power, etc).

With the current patches in 3.9, I don't see a way we can do that.  The
ports have power/control, which can only be set to 'on' or 'auto'.  You
should add an 'off' option to that file.


Won't empty ports naturally be powered off by runtime PM, so long as
there isn't a PM_QOS constraint to prevent it?  The user (or system
software) may need to write auto to the port's power/control file,
which may require us to put the ports on the usb_bus_type or to make
them class devices.  But however we do it, this should work
automatically.


Now I'm a bit confused and I'll have to look at the code again.  I can't
remember if Tianyu made the kernel add a PM_QOS constraint to set the no
power off flag for hot pluggable ports, or if we expect userspace to use
the connect type sysfs file to figure out it shouldn't write auto to the
file.

Actually, I exposed pm qos flags for usb port via dev_pm_qos_expose_flags().
It creates power/pm_qos_no_power_off under usb port sysfs directory.
User can echo 0  pm_qos_no_power_off to power off the empty port.



If the kernel isn't adding that constraint, then Tianyu *really* needs
to document that.

power/pm_qos_no_power_off is device's power attribute and it has been
described in the sysfs-devices-power. I think I should mention in the
usb/power-management.text.


Sarah Sharp



--
Best Regards
Tianyu Lan
linux kernel enabling team
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/4] usb: introduce usb force power off mechanism

2013-03-28 Thread Lan Tianyu

On 2013/3/28 2:45, Alan Stern wrote:

+int usb_hub_port_power_reset(struct usb_device *hdev, int port1)
+{
+   struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
+   struct usb_interface *intf = to_usb_interface(hub-intfdev);
+   int ret;
+
+   usb_autopm_get_interface(intf);


What happens if hdev is NULL?

Yes, This will be a problem. The repower cmd to root
hub should be ignored.




+   hub_port_logical_disconnect(hub, port1);
+   ret = usb_hub_set_port_power(hdev, port1, false);


How long do you think the power should remain turned off?  This code
will leave it off for only a few milliseconds at most.  That may not
even be long enough for the voltage to drop all the way to 0.

The delay probably should be at least 100 ms.  Maybe more, I don't
know.

I think this depends on the device. I don't find the answer on spec.
I find the cool down delay of over-current for port is 100ms
and one for hub is 500ms. Could we reference these delay?
500ms would be safe.



+   ret |= usb_hub_set_port_power(hdev, port1, true);


Don't use |=.  Skip the second call if the first one fails.


OK.

+   usb_autopm_put_interface(intf);
+
+   return ret;
+}


If you placed this function later on in the source file, you wouldn't
need the forward declaration of hub_port_logical_disconnect().

Yes, I will do this.


Alan Stern



--
Best Regards
Tianyu Lan
linux kernel enabling team
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/4] usb: introduce usb force power off mechanism

2013-03-28 Thread Lan Tianyu

On 2013/3/28 22:46, Alan Stern wrote:

On Thu, 28 Mar 2013, Lan Tianyu wrote:


How long do you think the power should remain turned off?  This code
will leave it off for only a few milliseconds at most.  That may not
even be long enough for the voltage to drop all the way to 0.

The delay probably should be at least 100 ms.  Maybe more, I don't
know.

I think this depends on the device. I don't find the answer on spec.
I find the cool down delay of over-current for port is 100ms
and one for hub is 500ms. Could we reference these delay?
500ms would be safe.


Okay, then use 500 ms.

Alan Stern


Ok.

About the path usb: Add usb port system pm support, do you think it's
ok?

On 2013/3/28 2:47, Alan Stern wrote:

What happens if there's no device plugged in to the port, but the hub
is enabled for remote wakeup?  How will the hub be able to detect a
plug-in event if the port isn't powered?

Alan Stern


Hi Alan:
 Great thanks for your review.
 The hub will not detect the new devices. From my opinion, this
depends on the user space since the port only will be powered off when
pm qos NO_POWER_OFF flag is unset(it is default to be set). If unset
the flag, losing plug-in event should have been took into account.




--
Best Regards
Tianyu Lan
linux kernel enabling team
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/4] usb: introduce usb force power off mechanism

2013-03-28 Thread Lan Tianyu

On 2013/3/29 0:50, Alan Stern wrote:

On Fri, 29 Mar 2013, Lan Tianyu wrote:


About the path usb: Add usb port system pm support, do you think it's
ok?


Generally yes.  But why doesn't usb_port_system_suspend check for any
PM_QOS constraints?  Either on the port itself or on the child device.

Because usb_port_runtime_suspend() will PM Qos flags. If add check in
usb_port_system_suspend(), PM Qos flags would be checked twice and
this seems redundant.


Alan Stern



--
Best Regards
Tianyu Lan
linux kernel enabling team
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/4] usb: introduce usb force power off mechanism

2013-03-28 Thread Lan Tianyu

On 2013/3/29 1:49, Alan Stern wrote:

On Fri, 29 Mar 2013, Lan Tianyu wrote:


On 2013/3/29 0:50, Alan Stern wrote:

On Fri, 29 Mar 2013, Lan Tianyu wrote:


About the path usb: Add usb port system pm support, do you think it's
ok?


Generally yes.  But why doesn't usb_port_system_suspend check for any
PM_QOS constraints?  Either on the port itself or on the child device.

Because usb_port_runtime_suspend() will PM Qos flags. If add check in
usb_port_system_suspend(), PM Qos flags would be checked twice and
this seems redundant.


Yes, that's right -- I noticed this the first time I read the patch and
then forgot it again.

I don't see any other problems with that patch.

Alan Stern



Ok. I just refresh patch usb: introduce usb force power off mechanism
Please have a look.

From 16f5c7c6dd00830530a9ac758af25b575e0b8731 Mon Sep 17 00:00:00 2001
From: Lan Tianyu tianyu@intel.com
Date: Tue, 26 Feb 2013 11:12:09 +0800
Subject: [PATCH] usb: introduce usb force power off mechanism

Some devices' firmware will be broken at some points. Power down
and power on device can help device to rework in this case.

This patch is to add ioctl cmd USBDEVFS_POWER_RESET for usbfs node
to repower usb device. First, call hub_port_logical_disconnect() to
disconnect device. Second, Power down and up usb port.

This patch is also helpful fo some QAs who want to do hcd's memleak
test(Plug and unplug device thousand times.)

Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/devio.c  |   16 
 drivers/usb/core/hub.c|   27 +++
 drivers/usb/core/usb.h|2 ++
 include/uapi/linux/usbdevice_fs.h |1 +
 4 files changed, 46 insertions(+)

diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 8823e98..951e904 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -1102,6 +1102,17 @@ static int proc_resetdevice(struct dev_state *ps)
return usb_reset_device(ps-dev);
 }

+static int proc_resetdevicepower(struct dev_state *ps)
+{
+   struct usb_device *udev = ps-dev;
+   struct usb_device *hdev = udev-parent;
+
+   if (!hdev)
+   return -EINVAL;
+
+   return usb_hub_port_power_reset(hdev, udev-portnum);
+}
+
 static int proc_setintf(struct dev_state *ps, void __user *arg)
 {
struct usbdevfs_setinterface setintf;
@@ -2011,6 +2022,11 @@ static long usbdev_do_ioctl(struct file *file, unsigned 
int cmd,
ret = proc_resetdevice(ps);
break;

+   case USBDEVFS_POWER_RESET:
+   snoop(dev-dev, %s: RESET POWER\n, __func__);
+   ret = proc_resetdevicepower(ps);
+   break;
+
case USBDEVFS_CLEAR_HALT:
snoop(dev-dev, %s: CLEAR_HALT\n, __func__);
ret = proc_clearhalt(ps, p);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 6b7f5b9..9729e36 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -948,6 +948,33 @@ static void hub_port_logical_disconnect(struct usb_hub 
*hub, int port1)
 }

 /**
+ * usb_hub_port_power_reset - repower hub port
+ * @hdev: USB device belonging to the usb hub
+ * @port1: port num to be repowered.
+ *
+ * This routine will try to disconnect the device on
+ * the port and then repower the port.
+ */
+int usb_hub_port_power_reset(struct usb_device *hdev, int port1)
+{
+   struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
+   struct usb_interface *intf = to_usb_interface(hub-intfdev);
+   int ret;
+
+   usb_autopm_get_interface(intf);
+   hub_port_logical_disconnect(hub, port1);
+   ret = usb_hub_set_port_power(hdev, port1, false);
+   if (!ret) {
+   /* Wait for power down device */
+   msleep(500);
+   ret = usb_hub_set_port_power(hdev, port1, true);
+   }
+   usb_autopm_put_interface(intf);
+
+   return ret;
+}
+
+/**
  * usb_remove_device - disable a device's port on its parent hub
  * @udev: device to be disabled and removed
  * Context: @udev locked, must be able to sleep.
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index a7f20bd..4e7785c 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -185,6 +185,8 @@ extern void usb_set_hub_port_connect_type(struct usb_device 
*hdev, int port1,
enum usb_port_connect_type type);
 extern void usb_hub_adjust_deviceremovable(struct usb_device *hdev,
struct usb_hub_descriptor *desc);
+extern int usb_hub_port_power_reset(struct usb_device *hdev,
+   int port1);

 #ifdef CONFIG_ACPI
 extern int usb_acpi_register(void);
diff --git a/include/uapi/linux/usbdevice_fs.h 
b/include/uapi/linux/usbdevice_fs.h
index 0c65e4b..b6e0d17 100644
--- a/include/uapi/linux/usbdevice_fs.h
+++ b/include/uapi/linux/usbdevice_fs.h
@@ -176,5 +176,6 @@ struct usbdevfs_disconnect_claim {
 #define USBDEVFS_RELEASE_PORT  _IOR('U', 25, unsigned int)
 #define

Re: [PATCH 4/4] usb: register usb port to usb_bus_type

2013-03-28 Thread Lan Tianyu

On 2013/3/29 2:21, Greg KH wrote:

What does it look like if you reverse the naming scheme (hub dev name +
port)?  Doesn't that show the devices in a bit more logical way?

Hi Greg:
Do you mean e.g port1.2-1, originally it's port2-1.1.
2-1 is hub dev name?


No, I mean 2-1.port1 as these are the ports on the device, the device
prefix should go first, right?


If right, how about root hub port and it should be port2.usb1?


usb1.port2

Ok. I get it. Yes, this looks more logical. Thanks. Will refresh soon.




--
Best Regards
Tianyu Lan
linux kernel enabling team
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/4] usb: register usb port to usb_bus_type

2013-03-28 Thread Lan Tianyu

On 2013/3/29 2:44, Alan Stern wrote:

On Thu, 28 Mar 2013, Greg KH wrote:


ls /sys/bus/usb/devices
1-0:1.02-0:1.0  port1-1  port1-1.3  port2-1.2  port2-2  port4-3
1-12-1  port1-1.1port1-1.4  port2-1.3  port3-1  port4-4
1-1.1  2-1:1.0  port1-1.2port1-1.5  port2-1.4  port3-2  usb1
1-1:1.03-0:1.0  port1-1.2.1  port1-1.6  port2-1.5  port3-3  usb2
1-1.1:1.0  3-1  port1-1.2.2  port1-2port2-1.6  port3-4  usb3
1-1.2  3-1:1.0  port1-1.2.3  port2-1port2-1.7  port4-1  usb4
1-1.2:1.0  4-0:1.0  port1-1.2.4  port2-1.1  port2-1.8  port4-2


What does it look like if you reverse the naming scheme (hub dev name +
port)?  Doesn't that show the devices in a bit more logical way?

Hi Greg:
Do you mean e.g port1.2-1, originally it's port2-1.1.
2-1 is hub dev name?


No, I mean 2-1.port1 as these are the ports on the device, the device
prefix should go first, right?


If right, how about root hub port and it should be port2.usb1?


usb1.port2


Is this a good idea?  There are userspace programs that look through
the list of files in /sys/bus/usb/devices, and they probably expect
filenames beginning with a number or with 'usb' to be USB devices and

After updating

ls /sys/bus/usb/devices
1-0:1.0  1-1.1:1.0  1-1.4  1-1.port3  2-1:1.02-1.6  2-1.port2  
2-1.port6  usb1.port1  usb2.port1  usb3.port1  usb4 usb4.port4
1-1  1-1.1:1.1  1-1.4:1.0  1-1.port4  2-1.5  2-1.6:1.0 2-1.port3  
3-0:1.0usb1.port2  usb2.port2  usb3.port2  usb4.port1
1-1.11-1.2  1-1.port1  2-0:1.02-1.5:1.0  2-1.6:1.1 2-1.port4  
4-0:1.0usb1.port3  usb2.port3  usb3.port3  usb4.port2
1-1:1.0  1-1.2:1.0  1-1.port2  2-12-1.5:1.1  2-1.port1 2-1.port5  usb1  
 usb2usb3usb3.port4  usb4.port3

interfaces.

Alan Stern



--
Best Regards
Tianyu Lan
linux kernel enabling team
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/4] usb: register usb port to usb_bus_type

2013-03-28 Thread Lan Tianyu

On 2013/3/29 2:53, Greg KH wrote:

On Thu, Mar 28, 2013 at 02:44:01PM -0400, Alan Stern wrote:

On Thu, 28 Mar 2013, Greg KH wrote:


ls /sys/bus/usb/devices
1-0:1.02-0:1.0  port1-1  port1-1.3  port2-1.2  port2-2  port4-3
1-12-1  port1-1.1port1-1.4  port2-1.3  port3-1  port4-4
1-1.1  2-1:1.0  port1-1.2port1-1.5  port2-1.4  port3-2  usb1
1-1:1.03-0:1.0  port1-1.2.1  port1-1.6  port2-1.5  port3-3  usb2
1-1.1:1.0  3-1  port1-1.2.2  port1-2port2-1.6  port3-4  usb3
1-1.2  3-1:1.0  port1-1.2.3  port2-1port2-1.7  port4-1  usb4
1-1.2:1.0  4-0:1.0  port1-1.2.4  port2-1.1  port2-1.8  port4-2


What does it look like if you reverse the naming scheme (hub dev name +
port)?  Doesn't that show the devices in a bit more logical way?

Hi Greg:
Do you mean e.g port1.2-1, originally it's port2-1.1.
2-1 is hub dev name?


No, I mean 2-1.port1 as these are the ports on the device, the device
prefix should go first, right?


If right, how about root hub port and it should be port2.usb1?


usb1.port2


Is this a good idea?  There are userspace programs that look through
the list of files in /sys/bus/usb/devices, and they probably expect
filenames beginning with a number or with 'usb' to be USB devices and
interfaces.


What userspace programs?

And if they do that, then we shouldn't put the ports in here at all.

This means usb port should be assigned to usb_bus_type.
How about creating a usb_port class and assign usb port devices to it?
ATA layer does something like this.


greg k-h



--
Best Regards
Tianyu Lan
linux kernel enabling team
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/4] usb: introduce usb force power off mechanism

2013-03-28 Thread Lan Tianyu

On 2013/3/29 3:38, Alan Stern wrote:

On Fri, 29 Mar 2013, Lan Tianyu wrote:


Ok. I just refresh patch usb: introduce usb force power off mechanism
Please have a look.

  From 16f5c7c6dd00830530a9ac758af25b575e0b8731 Mon Sep 17 00:00:00 2001
From: Lan Tianyu tianyu@intel.com
Date: Tue, 26 Feb 2013 11:12:09 +0800
Subject: [PATCH] usb: introduce usb force power off mechanism

Some devices' firmware will be broken at some points. Power down
and power on device can help device to rework in this case.

This patch is to add ioctl cmd USBDEVFS_POWER_RESET for usbfs node
to repower usb device. First, call hub_port_logical_disconnect() to
disconnect device. Second, Power down and up usb port.

This patch is also helpful fo some QAs who want to do hcd's memleak
test(Plug and unplug device thousand times.)

Signed-off-by: Lan Tianyu tianyu@intel.com


...


--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -185,6 +185,8 @@ extern void usb_set_hub_port_connect_type(struct usb_device 
*hdev, int port1,
enum usb_port_connect_type type);
   extern void usb_hub_adjust_deviceremovable(struct usb_device *hdev,
struct usb_hub_descriptor *desc);
+extern int usb_hub_port_power_reset(struct usb_device *hdev,
+   int port1);


This can all go on one line.


It looks okay.  When you test it, does the attached device get detected
and initialized properly?

I test usb2.0 key on my machine. It works.


Alan Stern



--
Best Regards
Tianyu Lan
linux kernel enabling team
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/4] usb: Add usb port system pm support

2013-03-28 Thread Lan Tianyu

On 2013/3/29 4:47, Sarah Sharp wrote:

On Thu, Mar 28, 2013 at 07:58:47AM +0800, Lan Tianyu wrote:

On 2013/3/28 2:47, Alan Stern wrote:

On Thu, 28 Mar 2013, Lan Tianyu wrote
What happens if there's no device plugged in to the port, but the hub
is enabled for remote wakeup?  How will the hub be able to detect a
plug-in event if the port isn't powered?

Alan Stern


Hi Alan:
Great thanks for your review.
The hub will not detect the new devices. From my opinion, this
depends on the user space since the port only will be powered off when
pm qos NO_POWER_OFF flag is unset(it is default to be set). If unset
the flag, losing plug-in event should have been took into account.


So basically, you're saying that any new distro policy that turns off
port power will need to re-enable it if the user wants hotplug events
from a hub?  I think that's a very important thing to document.

I really think we need to add more description about the port power off
mechanisms to Documentation/usb/power-management.txt.  There's a little
bit in Documentation/ABI/testing/sysfs-bus-usb, but since this mechanism
is so new, I think we need to educate distro users on its effects and
suggestions on how to use it.  Can you take a first stab at an overview,
and I'll let you know what's missing?

That's good idea. Ok. I will do that.


Sarah Sharp



--
Best Regards
Tianyu Lan
linux kernel enabling team
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/4] usb: remote_wakeup code clean up and usb port related feature

2013-03-27 Thread Lan Tianyu
PATCH 1 is for code clean up.
PATCH 2~3 is to introduce usb port power off new feature
PATCH 4 is to fix usb port doesn't register to any bus_type 

usb: add usb_enable/disable_remote_wakeup()
usb: introduce usb force power off mechanism
usb: Add usb port system pm support
usb: register usb port to usb_bus_type


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/4] usb: add usb_enable/disable_remote_wakeup()

2013-03-27 Thread Lan Tianyu
usb2.0 and usb3.0 devices have different ways to enalbe/disable
remote wakeup. This patch is to put both their operations into
the seperate functions. Otherwise, usb_control_msg() has some
long arguments and are usually nested some indentations. So
encapsulating it into seperate functions would be convienient
to use and more readable.

Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/hub.c |  136 
 1 file changed, 68 insertions(+), 68 deletions(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 7815462..6b7f5b9 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2826,22 +2826,72 @@ void usb_enable_ltm(struct usb_device *udev)
 EXPORT_SYMBOL_GPL(usb_enable_ltm);
 
 #ifdef CONFIG_USB_SUSPEND
-/*
- * usb_disable_function_remotewakeup - disable usb3.0
- * device's function remote wakeup
- * @udev: target device
- *
- * Assume there's only one function on the USB 3.0
- * device and disable remote wake for the first
- * interface. FIXME if the interface association
- * descriptor shows there's more than one function.
- */
-static int usb_disable_function_remotewakeup(struct usb_device *udev)
+static int usb_disable_remote_wakeup(struct usb_device *udev)
 {
-   return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
-   USB_REQ_CLEAR_FEATURE, USB_RECIP_INTERFACE,
-   USB_INTRF_FUNC_SUSPEND, 0, NULL, 0,
+   int status = 0;
+   u16 devstatus;
+
+   if (udev-speed != USB_SPEED_SUPER) {
+   status = usb_get_status(udev, USB_RECIP_DEVICE, 0, devstatus);
+   le16_to_cpus(devstatus);
+   if (!status  devstatus  (1  USB_DEVICE_REMOTE_WAKEUP))
+   status = usb_control_msg(udev,
+   usb_sndctrlpipe(udev, 0),
+   USB_REQ_CLEAR_FEATURE,
+   USB_RECIP_DEVICE,
+   USB_DEVICE_REMOTE_WAKEUP, 0,
+   NULL, 0,
+   USB_CTRL_SET_TIMEOUT);
+   } else {
+   /*
+* Assume there's only one function on the USB 3.0
+* device and disable remote wake for the first
+* interface. FIXME if the interface association
+* descriptor shows there's more than one function.
+*/
+   status = usb_get_status(udev, USB_RECIP_INTERFACE, 0,
+   devstatus);
+   le16_to_cpus(devstatus);
+   if (!status  devstatus 
+ (USB_INTRF_STAT_FUNC_RW_CAP | USB_INTRF_STAT_FUNC_RW))
+   status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+   USB_REQ_CLEAR_FEATURE,
+   USB_RECIP_INTERFACE,
+   USB_INTRF_FUNC_SUSPEND, 0,
+   NULL, 0,
+   USB_CTRL_SET_TIMEOUT);
+   }
+
+   return status;
+}
+
+static int usb_enable_remote_wakeup(struct usb_device *udev)
+{
+   int status;
+
+   if (udev-speed != USB_SPEED_SUPER) {
+   status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+   USB_REQ_SET_FEATURE, USB_RECIP_DEVICE,
+   USB_DEVICE_REMOTE_WAKEUP, 0,
+   NULL, 0,
+   USB_CTRL_SET_TIMEOUT);
+   } else {
+   /* Assume there's only one function on the USB 3.0
+* device and enable remote wake for the first
+* interface. FIXME if the interface association
+* descriptor shows there's more than one function.
+*/
+   status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+   USB_REQ_SET_FEATURE,
+   USB_RECIP_INTERFACE,
+   USB_INTRF_FUNC_SUSPEND,
+   USB_INTRF_FUNC_SUSPEND_RW |
+   USB_INTRF_FUNC_SUSPEND_LP,
+   NULL, 0,
USB_CTRL_SET_TIMEOUT);
+   }
+
+   return status;
 }
 
 /*
@@ -2905,27 +2955,7 @@ int usb_port_suspend(struct usb_device *udev, 
pm_message_t msg)
 * we don't explicitly enable it here.
 */
if (udev-do_remote_wakeup) {
-   if (!hub_is_superspeed(hub-hdev)) {
-   status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
-   USB_REQ_SET_FEATURE, USB_RECIP_DEVICE,
-   USB_DEVICE_REMOTE_WAKEUP, 0,
-   NULL, 0

[PATCH 3/4] usb: Add usb port system pm support

2013-03-27 Thread Lan Tianyu
This patch is to add usb port system pm support. Add
usb port's system suspend/resume callbacks and call
usb_port_runtime_resume/suspend() to power off these
ports whose pm qos NO_POWER_OFF flag is not set, system
wakeup is disabled and persist is enalbed.

During system pm, usb port should be powered off after
dev being suspended and powered on before dev being
resumed. Since usb ports and devs enable async suspend,
call device_pm_wait_for_dev() in the usb_port_system_suspend()
and usb_port_resume() to keeping the order.

If usb port was already powered off by runtime pm with
port_dev-power_is_on being false, usb_port_system_suspend()
returns directly.

If usb port was not powered off during system suspend with
port_dev-power_is_on being true, usb_port_system_resume()
returns directly.

Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/hub.c  |4 
 drivers/usb/core/port.c |   49 ---
 2 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index c228e69..8c2562e 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3166,6 +3166,10 @@ int usb_port_resume(struct usb_device *udev, 
pm_message_t msg)
int status;
u16 portchange, portstatus;
 
+   /* Wait for usb port system resume finishing */
+   if (!PMSG_IS_AUTO(msg))
+   device_pm_wait_for_dev(udev-dev, port_dev-dev);
+
if (port_dev-did_runtime_put) {
status = pm_runtime_get_sync(port_dev-dev);
port_dev-did_runtime_put = false;
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 797f9d5..f14fc72 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -71,7 +71,7 @@ static void usb_port_device_release(struct device *dev)
kfree(port_dev);
 }
 
-#ifdef CONFIG_USB_SUSPEND
+#ifdef CONFIG_PM
 static int usb_port_runtime_resume(struct device *dev)
 {
struct usb_port *port_dev = to_usb_port(dev);
@@ -131,25 +131,68 @@ static int usb_port_runtime_suspend(struct device *dev)
set_bit(port1, hub-busy_bits);
retval = usb_hub_set_port_power(hdev, port1, false);
usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION);
-   usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_ENABLE);
+   usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_ENABLE);
clear_bit(port1, hub-busy_bits);
usb_autopm_put_interface(intf);
return retval;
 }
-#endif
+
+static int usb_port_system_suspend(struct device *dev)
+{
+   struct usb_port *port_dev = to_usb_port(dev);
+
+   if (!port_dev-power_is_on)
+   return 0;
+
+   if (port_dev-child) {
+   struct usb_device *udev = port_dev-child;
+
+   /*
+* usb port can't be powered off when dev's system
+* wakeup is enabled or persist is disabled.
+*/
+   if (device_may_wakeup(udev-dev)
+   || !udev-persist_enabled)
+   return 0;
+
+   /*
+* usb port should be powered off after usb dev
+* being suspended.
+*/
+   device_pm_wait_for_dev(dev, port_dev-child-dev);
+   }
+
+   usb_port_runtime_suspend(dev);
+   return 0;
+}
+
+static int usb_port_system_resume(struct device *dev)
+{
+   struct usb_port *port_dev = to_usb_port(dev);
+
+   if (port_dev-power_is_on)
+   return 0;
+
+   return usb_port_runtime_resume(dev);
+}
 
 static const struct dev_pm_ops usb_port_pm_ops = {
+   .suspend =  usb_port_system_suspend,
+   .resume =   usb_port_system_resume,
 #ifdef CONFIG_USB_SUSPEND
.runtime_suspend =  usb_port_runtime_suspend,
.runtime_resume =   usb_port_runtime_resume,
.runtime_idle = pm_generic_runtime_idle,
 #endif
 };
+#endif
 
 struct device_type usb_port_device_type = {
.name = usb_port,
.release =  usb_port_device_release,
+#if CONFIG_PM
.pm =   usb_port_pm_ops,
+#endif
 };
 
 int usb_hub_create_port_device(struct usb_hub *hub, int port1)
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/4] usb: register usb port to usb_bus_type

2013-03-27 Thread Lan Tianyu
Usb port isn't assigned to any bus_type. This seems not good from
Greg's comments.
http://marc.info/?l=linux-usbm=136200364929942w=2

This patch is to register usb port to usb_bus_type. The usb port's
original name is portX. This will cause name confilct after adding
usb port to usb_bus_type since the usb ports with same port num under
different hub have the same name. So change the usb port's name format
to port + (hub dev name) + '.' + (port num) for non-root hub and
port + (usb bus num) + '-' + (port num) for root hub.

ls /sys/bus/usb/devices
1-0:1.02-0:1.0  port1-1  port1-1.3  port2-1.2  port2-2  port4-3
1-12-1  port1-1.1port1-1.4  port2-1.3  port3-1  port4-4
1-1.1  2-1:1.0  port1-1.2port1-1.5  port2-1.4  port3-2  usb1
1-1:1.03-0:1.0  port1-1.2.1  port1-1.6  port2-1.5  port3-3  usb2
1-1.1:1.0  3-1  port1-1.2.2  port1-2port2-1.6  port3-4  usb3
1-1.2  3-1:1.0  port1-1.2.3  port2-1port2-1.7  port4-1  usb4
1-1.2:1.0  4-0:1.0  port1-1.2.4  port2-1.1  port2-1.8  port4-2

Signed-off-by: Lan Tianyu tianyu@intel.com
---
 Documentation/ABI/testing/sysfs-bus-usb |6 +++---
 drivers/usb/core/port.c |   10 +-
 drivers/usb/core/usb-acpi.c |7 +--
 3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-usb 
b/Documentation/ABI/testing/sysfs-bus-usb
index c8baaf5..842e8b8 100644
--- a/Documentation/ABI/testing/sysfs-bus-usb
+++ b/Documentation/ABI/testing/sysfs-bus-usb
@@ -221,14 +221,14 @@ Description:
The file will be present for all speeds of USB devices, and will
always read no for USB 1.1 and USB 2.0 devices.
 
-What:  /sys/bus/usb/devices/.../(hub interface)/portX
+What:  /sys/bus/usb/devices/.../(hub interface)/portX-X
 Date:  August 2012
 Contact:   Lan Tianyu tianyu@intel.com
 Description:
-   The /sys/bus/usb/devices/.../(hub interface)/portX
+   The /sys/bus/usb/devices/.../(hub interface)/portX-X
is usb port device's sysfs directory.
 
-What:  /sys/bus/usb/devices/.../(hub interface)/portX/connect_type
+What:  /sys/bus/usb/devices/.../(hub interface)/portX-X/connect_type
 Date:  January 2013
 Contact:   Lan Tianyu tianyu@intel.com
 Description:
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index f14fc72..2c086dc 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -198,6 +198,7 @@ struct device_type usb_port_device_type = {
 int usb_hub_create_port_device(struct usb_hub *hub, int port1)
 {
struct usb_port *port_dev = NULL;
+   struct usb_device *hdev = hub-hdev;
int retval;
 
port_dev = kzalloc(sizeof(*port_dev), GFP_KERNEL);
@@ -212,7 +213,14 @@ int usb_hub_create_port_device(struct usb_hub *hub, int 
port1)
port_dev-dev.parent = hub-intfdev;
port_dev-dev.groups = port_dev_group;
port_dev-dev.type = usb_port_device_type;
-   dev_set_name(port_dev-dev, port%d, port1);
+   port_dev-dev.bus = usb_bus_type;
+
+   if (!hdev-parent)
+   dev_set_name(port_dev-dev, port%d-%d,
+   hdev-bus-busnum, port1);
+   else
+   dev_set_name(port_dev-dev, port%s.%d,
+   dev_name(hdev-dev), port1);
 
retval = device_register(port_dev-dev);
if (retval)
diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
index b6f4bad..1cc55c9 100644
--- a/drivers/usb/core/usb-acpi.c
+++ b/drivers/usb/core/usb-acpi.c
@@ -17,7 +17,7 @@
 #include linux/pci.h
 #include acpi/acpi_bus.h
 
-#include usb.h
+#include hub.h
 
 /**
  * usb_acpi_power_manageable - check whether usb port has
@@ -178,7 +178,10 @@ static int usb_acpi_find_device(struct device *dev, 
acpi_handle *handle)
return -ENODEV;
return 0;
} else if (is_usb_port(dev)) {
-   sscanf(dev_name(dev), port%d, port_num);
+   struct usb_port *port_dev = to_usb_port(dev);
+
+   port_num = port_dev-portnum;
+
/* Get the struct usb_device point of port's hub */
udev = to_usb_device(dev-parent-parent);
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/4] usb: introduce usb force power off mechanism

2013-03-27 Thread Lan Tianyu
Some devices' firmware will be broken at some points. Power down
and power on device can help device to rework in this case.

This patch is to add ioctl cmd USBDEVFS_POWER_RESET for usbfs node
to repower usb device. First, call hub_port_logical_disconnect() to
disconnect device. Second, Power down and up usb port.

This patch is also helpful fo some QAs who want to do hcd's memleak
test(Plug and unplug device thousand times.)

Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/devio.c  |   13 +
 drivers/usb/core/hub.c|   16 
 drivers/usb/core/usb.h|2 ++
 include/uapi/linux/usbdevice_fs.h |1 +
 4 files changed, 32 insertions(+)

diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 8823e98..a76b326 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -1102,6 +1102,14 @@ static int proc_resetdevice(struct dev_state *ps)
return usb_reset_device(ps-dev);
 }
 
+static int proc_resetdevicepower(struct dev_state *ps)
+{
+   struct usb_device *udev = ps-dev;
+   struct usb_device *hdev = udev-parent;
+
+   return usb_hub_port_power_reset(hdev, udev-portnum);
+}
+
 static int proc_setintf(struct dev_state *ps, void __user *arg)
 {
struct usbdevfs_setinterface setintf;
@@ -2011,6 +2019,11 @@ static long usbdev_do_ioctl(struct file *file, unsigned 
int cmd,
ret = proc_resetdevice(ps);
break;
 
+   case USBDEVFS_POWER_RESET:
+   snoop(dev-dev, %s: RESET POWER\n, __func__);
+   ret = proc_resetdevicepower(ps);
+   break;
+
case USBDEVFS_CLEAR_HALT:
snoop(dev-dev, %s: CLEAR_HALT\n, __func__);
ret = proc_clearhalt(ps, p);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 6b7f5b9..c228e69 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -114,6 +114,7 @@ EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem);
 #define HUB_DEBOUNCE_STABLE 100
 
 static int usb_reset_and_verify_device(struct usb_device *udev);
+static void hub_port_logical_disconnect(struct usb_hub *hub, int port1);
 
 static inline char *portspeed(struct usb_hub *hub, int portstatus)
 {
@@ -741,6 +742,21 @@ int usb_hub_set_port_power(struct usb_device *hdev, int 
port1,
return ret;
 }
 
+int usb_hub_port_power_reset(struct usb_device *hdev, int port1)
+{
+   struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
+   struct usb_interface *intf = to_usb_interface(hub-intfdev);
+   int ret;
+
+   usb_autopm_get_interface(intf);
+   hub_port_logical_disconnect(hub, port1);
+   ret = usb_hub_set_port_power(hdev, port1, false);
+   ret |= usb_hub_set_port_power(hdev, port1, true);
+   usb_autopm_put_interface(intf);
+
+   return ret;
+}
+
 /**
  * usb_hub_clear_tt_buffer - clear control/bulk TT state in high speed hub
  * @urb: an URB associated with the failed or incomplete split transaction
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index a7f20bd..4e7785c 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -185,6 +185,8 @@ extern void usb_set_hub_port_connect_type(struct usb_device 
*hdev, int port1,
enum usb_port_connect_type type);
 extern void usb_hub_adjust_deviceremovable(struct usb_device *hdev,
struct usb_hub_descriptor *desc);
+extern int usb_hub_port_power_reset(struct usb_device *hdev,
+   int port1);
 
 #ifdef CONFIG_ACPI
 extern int usb_acpi_register(void);
diff --git a/include/uapi/linux/usbdevice_fs.h 
b/include/uapi/linux/usbdevice_fs.h
index 0c65e4b..b6e0d17 100644
--- a/include/uapi/linux/usbdevice_fs.h
+++ b/include/uapi/linux/usbdevice_fs.h
@@ -176,5 +176,6 @@ struct usbdevfs_disconnect_claim {
 #define USBDEVFS_RELEASE_PORT  _IOR('U', 25, unsigned int)
 #define USBDEVFS_GET_CAPABILITIES  _IOR('U', 26, __u32)
 #define USBDEVFS_DISCONNECT_CLAIM  _IOR('U', 27, struct 
usbdevfs_disconnect_claim)
+#define USBDEVFS_POWER_RESET  _IO('U', 28)
 
 #endif /* _UAPI_LINUX_USBDEVICE_FS_H */
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 2/4] usb: introduce usb force power off mechanism

2013-03-27 Thread Lan, Tianyu
A small tool to test this patch.

#include stdio.h
#include unistd.h
#include fcntl.h
#include errno.h
#include sys/ioctl.h
#include linux/usbdevice_fs.h

#define USBDEVFS_POWER_RESET   _IO('U', 28)

int main(int argc, char **argv)
{
const char *filename;
int fd;
int rc;

if (argc != 2) {
fprintf(stderr, Usage: usbreset device-filename\n);
return 1;
}
filename = argv[1];

fd = open(filename, O_WRONLY);
if (fd  0) {
perror(Error opening output file);
return 1;
}

printf(Repowering USB device %s\n, filename);
rc = ioctl(fd, USBDEVFS_POWER_RESET, 0);
if (rc  0) {
perror(Error in ioctl);
return 1;
}
printf(Repower successful\n);

close(fd);
return 0;
}


Best Regards 
Tianyu Lan 


-Original Message-
From: Lan, Tianyu 
Sent: Thursday, March 28, 2013 1:11 AM
To: gre...@linuxfoundation.org; sarah.a.sh...@linux.intel.com; 
st...@rowland.harvard.edu
Cc: linux-usb@vger.kernel.org; Lan, Tianyu
Subject: [PATCH 2/4] usb: introduce usb force power off mechanism

Some devices' firmware will be broken at some points. Power down and power on 
device can help device to rework in this case.

This patch is to add ioctl cmd USBDEVFS_POWER_RESET for usbfs node to repower 
usb device. First, call hub_port_logical_disconnect() to disconnect device. 
Second, Power down and up usb port.

This patch is also helpful fo some QAs who want to do hcd's memleak test(Plug 
and unplug device thousand times.)

Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/devio.c  |   13 +
 drivers/usb/core/hub.c|   16 
 drivers/usb/core/usb.h|2 ++
 include/uapi/linux/usbdevice_fs.h |1 +
 4 files changed, 32 insertions(+)

diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 
8823e98..a76b326 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -1102,6 +1102,14 @@ static int proc_resetdevice(struct dev_state *ps)
return usb_reset_device(ps-dev);
 }
 
+static int proc_resetdevicepower(struct dev_state *ps) {
+   struct usb_device *udev = ps-dev;
+   struct usb_device *hdev = udev-parent;
+
+   return usb_hub_port_power_reset(hdev, udev-portnum); }
+
 static int proc_setintf(struct dev_state *ps, void __user *arg)  {
struct usbdevfs_setinterface setintf;
@@ -2011,6 +2019,11 @@ static long usbdev_do_ioctl(struct file *file, unsigned 
int cmd,
ret = proc_resetdevice(ps);
break;
 
+   case USBDEVFS_POWER_RESET:
+   snoop(dev-dev, %s: RESET POWER\n, __func__);
+   ret = proc_resetdevicepower(ps);
+   break;
+
case USBDEVFS_CLEAR_HALT:
snoop(dev-dev, %s: CLEAR_HALT\n, __func__);
ret = proc_clearhalt(ps, p);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 
6b7f5b9..c228e69 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -114,6 +114,7 @@ EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem);
 #define HUB_DEBOUNCE_STABLE 100
 
 static int usb_reset_and_verify_device(struct usb_device *udev);
+static void hub_port_logical_disconnect(struct usb_hub *hub, int 
+port1);
 
 static inline char *portspeed(struct usb_hub *hub, int portstatus)  { @@ 
-741,6 +742,21 @@ int usb_hub_set_port_power(struct usb_device *hdev, int port1,
return ret;
 }
 
+int usb_hub_port_power_reset(struct usb_device *hdev, int port1) {
+   struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
+   struct usb_interface *intf = to_usb_interface(hub-intfdev);
+   int ret;
+
+   usb_autopm_get_interface(intf);
+   hub_port_logical_disconnect(hub, port1);
+   ret = usb_hub_set_port_power(hdev, port1, false);
+   ret |= usb_hub_set_port_power(hdev, port1, true);
+   usb_autopm_put_interface(intf);
+
+   return ret;
+}
+
 /**
  * usb_hub_clear_tt_buffer - clear control/bulk TT state in high speed hub
  * @urb: an URB associated with the failed or incomplete split transaction 
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 
a7f20bd..4e7785c 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -185,6 +185,8 @@ extern void usb_set_hub_port_connect_type(struct usb_device 
*hdev, int port1,
enum usb_port_connect_type type);
 extern void usb_hub_adjust_deviceremovable(struct usb_device *hdev,
struct usb_hub_descriptor *desc);
+extern int usb_hub_port_power_reset(struct usb_device *hdev,
+   int port1);
 
 #ifdef CONFIG_ACPI
 extern int usb_acpi_register(void);
diff --git a/include/uapi/linux/usbdevice_fs.h 
b/include/uapi/linux/usbdevice_fs.h
index 0c65e4b..b6e0d17 100644
--- a/include/uapi/linux/usbdevice_fs.h
+++ b/include/uapi/linux/usbdevice_fs.h
@@ -176,5 +176,6

Re: [PATCH 3/4] usb: Add usb port system pm support

2013-03-27 Thread Lan Tianyu

On 2013/3/28 2:47, Alan Stern wrote:

On Thu, 28 Mar 2013, Lan Tianyu wrote
What happens if there's no device plugged in to the port, but the hub
is enabled for remote wakeup?  How will the hub be able to detect a
plug-in event if the port isn't powered?

Alan Stern


Hi Alan:
Great thanks for your review.
The hub will not detect the new devices. From my opinion, this
depends on the user space since the port only will be powered off when
pm qos NO_POWER_OFF flag is unset(it is default to be set). If unset
the flag, losing plug-in event should have been took into account.

--
Best Regards
Tianyu Lan
linux kernel enabling team
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: USB port power-off and system suspend

2013-03-23 Thread Lan, Tianyu
On 2013/3/23 1:35, Alan Stern wrote: Tianyu:
 
 Did you ever test the port power-off mechanism with system suspend?
 Right now it doesn't seem like it would work, because it relies on
 runtime PM to turn off the port power, and runtime PM doesn't operate
 normally during a system suspend.
 
 Alan Stern
 

Hi Alan:
You are right. Current the port power-off can't work during
system suspend. I have already worked on a patch of adding usb
port system pm support. But there is a still problem that how to
control power off mechanism from kernel side. Before, we have a solution
for runtime pm that increase/decrease port dev's usage count.
http://marc.info/?l=linux-usbm=135772122031446w=2
But now, we have another user, System pm. So I think we should find
a solution to cover these two cases. Maybe add a new pm qos request
for NO_POWER_OFF flag? I'd like to see your opinion. 

I have a patch that can work and it still needs to add some condition
checks in the usb_port_system_suspend(). Dev's system wakeup disable
and persist enable.
 
From c3abd373707910672d6fd2e96da78879b3e22417 Mon Sep 17 00:00:00 2001
From: Lan Tianyu tianyu@intel.com
Date: Tue, 26 Feb 2013 11:12:09 +0800
Subject: [PATCH] usb: Add usb port system pm support

This patch is to add usb port system pm support. Add
usb port's system suspend/resume callbacks and call
usb_port_runtime_resume/suspend() to power off these
ports without pm qos NO_POWER_OFF flag setting.

During system pm, usb port should be powered off after
dev being suspended and powered on before dev being
resumed. Usb ports and devs enable async suspend. In
order to keeping the order, call device_pm_wait_for_dev()
in the usb_port_system_suspend() and usb_port_resume().

Usb_port_system_suspend() ignores EAGAIN from usb_port_runtime_suspend().
EAGAIN is caused by pm qos NO_POWER_OFF setting. This is
not an error for usb port system pm.
---
 drivers/usb/core/hub.c  |4 
 drivers/usb/core/port.c |   31 +++
 2 files changed, 35 insertions(+)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 53c1555..8868f15 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3162,6 +3162,10 @@ int usb_port_resume(struct usb_device *udev, 
pm_message_t msg)
int status;
u16 portchange, portstatus;
 
+   /* Wait for usb port system resume finishing */
+   if (!PMSG_IS_AUTO(msg))
+   device_pm_wait_for_dev(udev-dev, port_dev-dev);
+
if (port_dev-did_runtime_put) {
status = pm_runtime_get_sync(port_dev-dev);
port_dev-did_runtime_put = false;
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 797f9d5..e5c6ec5 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -84,6 +84,9 @@ static int usb_port_runtime_resume(struct device *dev)
if (!hub)
return -EINVAL;
 
+   if (port_dev-power_is_on)
+   return 0;
+
usb_autopm_get_interface(intf);
set_bit(port1, hub-busy_bits);
 
@@ -127,6 +130,9 @@ static int usb_port_runtime_suspend(struct device *dev)
== PM_QOS_FLAGS_ALL)
return -EAGAIN;
 
+   if (!port_dev-power_is_on)
+   return 0;
+
usb_autopm_get_interface(intf);
set_bit(port1, hub-busy_bits);
retval = usb_hub_set_port_power(hdev, port1, false);
@@ -136,9 +142,34 @@ static int usb_port_runtime_suspend(struct device *dev)
usb_autopm_put_interface(intf);
return retval;
 }
+#else
+static int usb_port_runtime_suspend(struct device *dev) { return 0; }
+static int usb_port_runtime_resume(struct device *dev) { return 0; }
 #endif
 
+static int usb_port_system_suspend(struct device *dev)
+{
+   struct usb_port *port_dev = to_usb_port(dev);
+   int retval;
+
+   if (port_dev-child)
+   device_pm_wait_for_dev(dev, port_dev-child-dev);
+
+   retval = usb_port_runtime_suspend(dev);
+   if (retval  0  retval != -EAGAIN)
+   return retval;
+
+   return 0;
+}
+
+static int usb_port_system_resume(struct device *dev)
+{
+   return usb_port_runtime_resume(dev);
+}
+
 static const struct dev_pm_ops usb_port_pm_ops = {
+   .suspend =  usb_port_system_suspend,
+   .resume =   usb_port_system_resume,
 #ifdef CONFIG_USB_SUSPEND
.runtime_suspend =  usb_port_runtime_suspend,
.runtime_resume =   usb_port_runtime_resume,
-- 
1.7.10.4



-- 
Best Regards
Tianyu Lan
linux kernel enabling team
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH] usb: register usb port to usb_bus_type

2013-03-21 Thread Lan Tianyu
Usb port isn't assigned to any bus_type. This seems not good from
Greg's comments.
http://marc.info/?l=linux-usbm=136200364929942w=2

This patch is to register usb port to usb_bus_type. The usb port's
original name is portX. This will cause name confilct after adding
usb port to usb_bus_type since the usb ports with same port num under
different hub have the same name. So change the usb port's name format
to port + (hub dev name) + '.' + (port num) for non-root hub and
port + (usb bus num) + '-' + (port num) for root hub.

ls /sys/bus/usb/devices
1-0:1.02-0:1.0  port1-1  port1-1.3  port2-1.2  port2-2  port4-3
1-12-1  port1-1.1port1-1.4  port2-1.3  port3-1  port4-4
1-1.1  2-1:1.0  port1-1.2port1-1.5  port2-1.4  port3-2  usb1
1-1:1.03-0:1.0  port1-1.2.1  port1-1.6  port2-1.5  port3-3  usb2
1-1.1:1.0  3-1  port1-1.2.2  port1-2port2-1.6  port3-4  usb3
1-1.2  3-1:1.0  port1-1.2.3  port2-1port2-1.7  port4-1  usb4
1-1.2:1.0  4-0:1.0  port1-1.2.4  port2-1.1  port2-1.8  port4-2

Signed-off-by: Lan Tianyu tianyu@intel.com
---
 Documentation/ABI/testing/sysfs-bus-usb |6 +++---
 drivers/usb/core/port.c |   10 +-
 drivers/usb/core/usb-acpi.c |7 +--
 3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-usb 
b/Documentation/ABI/testing/sysfs-bus-usb
index c8baaf5..842e8b8 100644
--- a/Documentation/ABI/testing/sysfs-bus-usb
+++ b/Documentation/ABI/testing/sysfs-bus-usb
@@ -221,14 +221,14 @@ Description:
The file will be present for all speeds of USB devices, and will
always read no for USB 1.1 and USB 2.0 devices.
 
-What:  /sys/bus/usb/devices/.../(hub interface)/portX
+What:  /sys/bus/usb/devices/.../(hub interface)/portX-X
 Date:  August 2012
 Contact:   Lan Tianyu tianyu@intel.com
 Description:
-   The /sys/bus/usb/devices/.../(hub interface)/portX
+   The /sys/bus/usb/devices/.../(hub interface)/portX-X
is usb port device's sysfs directory.
 
-What:  /sys/bus/usb/devices/.../(hub interface)/portX/connect_type
+What:  /sys/bus/usb/devices/.../(hub interface)/portX-X/connect_type
 Date:  January 2013
 Contact:   Lan Tianyu tianyu@intel.com
 Description:
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 797f9d5..4d37984 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -155,6 +155,7 @@ struct device_type usb_port_device_type = {
 int usb_hub_create_port_device(struct usb_hub *hub, int port1)
 {
struct usb_port *port_dev = NULL;
+   struct usb_device *hdev = hub-hdev;
int retval;
 
port_dev = kzalloc(sizeof(*port_dev), GFP_KERNEL);
@@ -169,7 +170,14 @@ int usb_hub_create_port_device(struct usb_hub *hub, int 
port1)
port_dev-dev.parent = hub-intfdev;
port_dev-dev.groups = port_dev_group;
port_dev-dev.type = usb_port_device_type;
-   dev_set_name(port_dev-dev, port%d, port1);
+   port_dev-dev.bus = usb_bus_type;
+
+   if (!hdev-parent)
+   dev_set_name(port_dev-dev, port%d-%d,
+   hdev-bus-busnum, port1);
+   else
+   dev_set_name(port_dev-dev, port%s.%d,
+   dev_name(hdev-dev), port1);
 
retval = device_register(port_dev-dev);
if (retval)
diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
index b6f4bad..1cc55c9 100644
--- a/drivers/usb/core/usb-acpi.c
+++ b/drivers/usb/core/usb-acpi.c
@@ -17,7 +17,7 @@
 #include linux/pci.h
 #include acpi/acpi_bus.h
 
-#include usb.h
+#include hub.h
 
 /**
  * usb_acpi_power_manageable - check whether usb port has
@@ -178,7 +178,10 @@ static int usb_acpi_find_device(struct device *dev, 
acpi_handle *handle)
return -ENODEV;
return 0;
} else if (is_usb_port(dev)) {
-   sscanf(dev_name(dev), port%d, port_num);
+   struct usb_port *port_dev = to_usb_port(dev);
+
+   port_num = port_dev-portnum;
+
/* Get the struct usb_device point of port's hub */
udev = to_usb_device(dev-parent-parent);
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V4 2/2] usb/acpi: binding xhci root hub usb port with ACPI

2013-03-20 Thread Lan Tianyu
On 2013年03月21日 02:28, Sarah Sharp wrote:
 On Wed, Mar 20, 2013 at 10:18:03AM +0800, Lan Tianyu wrote:
 On 2013年03月20日 03:06, Sarah Sharp wrote:
 Ok, this looks sane, and our Intel testers report it doesn't oops like
 v2.  The patch description on the first patch is better as well.

 Tianyu, I know this introduces a new API to the host controller driver
 structure, and we would normally queue these two patches for 3.10.

 However, I know a lot of the port power off code went into 3.9.  If we
 don't have these patches in 3.9, what will be the impact?  Will we say,
 misassign a power resource from a particular port, or mismark a USB port
 connection type?  Is there any user-level impact if we don't have these
 in 3.9?

 If these patches should go into 3.9, should they also be backported to
 3.8 and 3.7?  Commit d557542421da643358201664903e67fd01dfca1a
 usb/acpi: Bind ACPI node to USB port, not usb_device. was first
 introduced in 3.7, and it looks like the sysfs files to turn on and off
 ports were added in 3.7 as well.  Without these two patches, will
 that sysfs interface work correctly?

 I think there is an impact for usb3.0 paired ports. So it's better to
 backport these patchs to 3.7, 3.8, 3.9 if possible. These patches also
 depend on the commit 1033f9041d ACPI: Allow ACPI binding with USB-3.0
 hub. I'd like to take the job if I could do.

 I'm not sure what you mean by I'd like to take the job if I could do.
 If you are talking about backporting patches to stable, I'll just mark
 your two patches to Cc the stable mailing list, and Greg will
 automatically backport this when it hits Linus' tree.  There's no work
 for you or I to do, unless the patches don't apply.
Sorry. I didn't say clearly. My concern is that these patches may not be
applied on the v3.7, v3.8 or v3.9. If that case, we would need to rework
these patches.


 BTW, the sysfs files to turn on and off ports has been reverted by Greg
 in v3.7.

 If the sysfs files were reverted for 3.7, and there was no policy for
 how to use the port connection information, is there any point in fixing
 this in 3.7?  Yes, the connection info might be wrong, but if no one can
 use it, why should we go to the trouble of backporting it?
There is also no policy for how to use the port connection information
in v3.8. If ignore wrong connect info, this seems also not to be needed
in v3.8.


 I do agree this should be in 3.8 and 3.9, I'm just not sure about 3.7.

 Sarah Sharp



-- 
Best regards
Tianyu Lan
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Resend PATCH V2] usb: add usb_enable/disable_remote_wakeup()

2013-03-20 Thread Lan Tianyu
usb2.0 and usb3.0 devices have different ways to enalbe/disable
remote wakeup. This patch is to put both their operations into
the seperate functions. Otherwise, usb_control_msg() has some
long arguments and are usually nested some indentations. So
encapsulating it into seperate functions would be convienient
to use and more readable.

Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/hub.c |  136 
 1 file changed, 68 insertions(+), 68 deletions(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 5480352..56eea28 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2822,22 +2822,72 @@ void usb_enable_ltm(struct usb_device *udev)
 EXPORT_SYMBOL_GPL(usb_enable_ltm);
 
 #ifdef CONFIG_USB_SUSPEND
-/*
- * usb_disable_function_remotewakeup - disable usb3.0
- * device's function remote wakeup
- * @udev: target device
- *
- * Assume there's only one function on the USB 3.0
- * device and disable remote wake for the first
- * interface. FIXME if the interface association
- * descriptor shows there's more than one function.
- */
-static int usb_disable_function_remotewakeup(struct usb_device *udev)
+static int usb_disable_remote_wakeup(struct usb_device *udev)
 {
-   return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
-   USB_REQ_CLEAR_FEATURE, USB_RECIP_INTERFACE,
-   USB_INTRF_FUNC_SUSPEND, 0, NULL, 0,
+   int status = 0;
+   u16 devstatus;
+
+   if (udev-speed != USB_SPEED_SUPER) {
+   status = usb_get_status(udev, USB_RECIP_DEVICE, 0, devstatus);
+   le16_to_cpus(devstatus);
+   if (!status  devstatus  (1  USB_DEVICE_REMOTE_WAKEUP))
+   status = usb_control_msg(udev,
+   usb_sndctrlpipe(udev, 0),
+   USB_REQ_CLEAR_FEATURE,
+   USB_RECIP_DEVICE,
+   USB_DEVICE_REMOTE_WAKEUP, 0,
+   NULL, 0,
+   USB_CTRL_SET_TIMEOUT);
+   } else {
+   /*
+* Assume there's only one function on the USB 3.0
+* device and disable remote wake for the first
+* interface. FIXME if the interface association
+* descriptor shows there's more than one function.
+*/
+   status = usb_get_status(udev, USB_RECIP_INTERFACE, 0,
+   devstatus);
+   le16_to_cpus(devstatus);
+   if (!status  devstatus 
+ (USB_INTRF_STAT_FUNC_RW_CAP | USB_INTRF_STAT_FUNC_RW))
+   status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+   USB_REQ_CLEAR_FEATURE,
+   USB_RECIP_INTERFACE,
+   USB_INTRF_FUNC_SUSPEND, 0,
+   NULL, 0,
+   USB_CTRL_SET_TIMEOUT);
+   }
+
+   return status;
+}
+
+static int usb_enable_remote_wakeup(struct usb_device *udev)
+{
+   int status;
+
+   if (udev-speed != USB_SPEED_SUPER) {
+   status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+   USB_REQ_SET_FEATURE, USB_RECIP_DEVICE,
+   USB_DEVICE_REMOTE_WAKEUP, 0,
+   NULL, 0,
+   USB_CTRL_SET_TIMEOUT);
+   } else {
+   /* Assume there's only one function on the USB 3.0
+* device and enable remote wake for the first
+* interface. FIXME if the interface association
+* descriptor shows there's more than one function.
+*/
+   status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+   USB_REQ_SET_FEATURE,
+   USB_RECIP_INTERFACE,
+   USB_INTRF_FUNC_SUSPEND,
+   USB_INTRF_FUNC_SUSPEND_RW |
+   USB_INTRF_FUNC_SUSPEND_LP,
+   NULL, 0,
USB_CTRL_SET_TIMEOUT);
+   }
+
+   return status;
 }
 
 /*
@@ -2901,27 +2951,7 @@ int usb_port_suspend(struct usb_device *udev, 
pm_message_t msg)
 * we don't explicitly enable it here.
 */
if (udev-do_remote_wakeup) {
-   if (!hub_is_superspeed(hub-hdev)) {
-   status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
-   USB_REQ_SET_FEATURE, USB_RECIP_DEVICE,
-   USB_DEVICE_REMOTE_WAKEUP, 0,
-   NULL, 0

[PATCH V4 1/2] usb: add find_raw_port_number callback to struct hc_driver()

2013-03-19 Thread Lan Tianyu
xhci driver divides the root hub into two logical hubs which work
respectively for usb 2.0 and usb 3.0 devices. They are independent
devices in the usb core. But in the ACPI table, it's one device node
and all usb2.0 and usb3.0 ports are under it. Binding usb port with
its acpi node needs the raw port number which is reflected in the xhci
extended capabilities table. This patch is to add find_raw_port_number
callback to struct hc_driver(), fill it with xhci_find_raw_port_number()
which will return raw port number and add a wrap usb_hcd_find_raw_port_number().

Otherwise, refactor xhci_find_real_port_number(). Using
xhci_find_raw_port_number() to get real index in the HW port status
registers instead of scanning through the xHCI roothub port array.
This can help to speed up.

All addresses in xhci-usb2_ports and xhci-usb3_ports array are
kown good ports and don't include following bad ports in the extended
capabilities talbe.
 (1) root port that doesn't have an entry
 (2) root port with unknown speed
 (3) root port that is listed twice and with different speeds.

So xhci_find_raw_port_number() will only return port num of good ones
and never touch bad ports above.

Signed-off-by: Lan Tianyu tianyu@intel.com
---
This patchset is based on usb-next tree commit 3f3b55bf
usb: ehci-s5p: Use devm for requesting ehci_vbus_gpio.

Change since v1:
Don't export usb_hcd_find_raw_port_number() symbol since there is no
its user outside of usb core.

Change since v2:
combine patch usb: add find_raw_port_number callback to struct
hc_driver() with this patch.

Change since v3:
add more changlog to prove this patch will not break previous function

 drivers/usb/core/hcd.c  |8 
 drivers/usb/host/xhci-mem.c |   36 
 drivers/usb/host/xhci-pci.c |1 +
 drivers/usb/host/xhci.c |   22 ++
 drivers/usb/host/xhci.h |1 +
 include/linux/usb/hcd.h |2 ++
 6 files changed, 42 insertions(+), 28 deletions(-)

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 99b34a3..f9ec44c 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2412,6 +2412,14 @@ int usb_hcd_is_primary_hcd(struct usb_hcd *hcd)
 }
 EXPORT_SYMBOL_GPL(usb_hcd_is_primary_hcd);
 
+int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1)
+{
+   if (!hcd-driver-find_raw_port_number)
+   return port1;
+
+   return hcd-driver-find_raw_port_number(hcd, port1);
+}
+
 static int usb_hcd_request_irqs(struct usb_hcd *hcd,
unsigned int irqnum, unsigned long irqflags)
 {
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 35616ff..6dc238c 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1022,44 +1022,24 @@ void xhci_copy_ep0_dequeue_into_input_ctx(struct 
xhci_hcd *xhci,
  * is attached to (or the roothub port its ancestor hub is attached to).  All 
we
  * know is the index of that port under either the USB 2.0 or the USB 3.0
  * roothub, but that doesn't give us the real index into the HW port status
- * registers.  Scan through the xHCI roothub port array, looking for the Nth
- * entry of the correct port speed.  Return the port number of that entry.
+ * registers. Call xhci_find_raw_port_number() to get real index.
  */
 static u32 xhci_find_real_port_number(struct xhci_hcd *xhci,
struct usb_device *udev)
 {
struct usb_device *top_dev;
-   unsigned int num_similar_speed_ports;
-   unsigned int faked_port_num;
-   int i;
+   struct usb_hcd *hcd;
+
+   if (udev-speed == USB_SPEED_SUPER)
+   hcd = xhci-shared_hcd;
+   else
+   hcd = xhci-main_hcd;
 
for (top_dev = udev; top_dev-parent  top_dev-parent-parent;
top_dev = top_dev-parent)
/* Found device below root hub */;
-   faked_port_num = top_dev-portnum;
-   for (i = 0, num_similar_speed_ports = 0;
-   i  HCS_MAX_PORTS(xhci-hcs_params1); i++) {
-   u8 port_speed = xhci-port_array[i];
-
-   /*
-* Skip ports that don't have known speeds, or have duplicate
-* Extended Capabilities port speed entries.
-*/
-   if (port_speed == 0 || port_speed == DUPLICATE_ENTRY)
-   continue;
 
-   /*
-* USB 3.0 ports are always under a USB 3.0 hub.  USB 2.0 and
-* 1.1 ports are under the USB 2.0 hub.  If the port speed
-* matches the device speed, it's a similar speed port.
-*/
-   if ((port_speed == 0x03) == (udev-speed == USB_SPEED_SUPER))
-   num_similar_speed_ports++;
-   if (num_similar_speed_ports == faked_port_num)
-   /* Roothub ports are numbered from 1 to N */
-   return i+1

[PATCH V4 2/2] usb/acpi: binding xhci root hub usb port with ACPI

2013-03-19 Thread Lan Tianyu
This patch is to bind xhci root hub usb port with its acpi node.
The port num in the acpi table matches with the sequence in the xhci
extended capabilities table. So call usb_hcd_find_raw_port_number() to
transfer hub port num into raw port number which associates with
the sequence in the xhci extended capabilities table before binding.

Signed-off-by: Lan Tianyu tianyu@intel.com
---
Change since v3:
   add a temprorary variable to recard raw port num and get ACPI
handle rahter than overwrite port num with raw port num. This is
to avoid passing raw port num as port num to usb_acpi_check_port_connect_type().

 drivers/usb/core/usb-acpi.c |8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
index b6f4bad..255c144 100644
--- a/drivers/usb/core/usb-acpi.c
+++ b/drivers/usb/core/usb-acpi.c
@@ -15,6 +15,7 @@
 #include linux/kernel.h
 #include linux/acpi.h
 #include linux/pci.h
+#include linux/usb/hcd.h
 #include acpi/acpi_bus.h
 
 #include usb.h
@@ -188,8 +189,13 @@ static int usb_acpi_find_device(struct device *dev, 
acpi_handle *handle)
 * connected to.
 */
if (!udev-parent) {
-   *handle = acpi_get_child(DEVICE_ACPI_HANDLE(udev-dev),
+   struct usb_hcd *hcd = bus_to_hcd(udev-bus);
+   int raw_port_num;
+
+   raw_port_num = usb_hcd_find_raw_port_number(hcd,
port_num);
+   *handle = acpi_get_child(DEVICE_ACPI_HANDLE(udev-dev),
+   raw_port_num);
if (!*handle)
return -ENODEV;
} else {
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V4 2/2] usb/acpi: binding xhci root hub usb port with ACPI

2013-03-19 Thread Lan Tianyu
On 2013年03月20日 03:06, Sarah Sharp wrote:
 Ok, this looks sane, and our Intel testers report it doesn't oops like
 v2.  The patch description on the first patch is better as well.
 
 Tianyu, I know this introduces a new API to the host controller driver
 structure, and we would normally queue these two patches for 3.10.
 
 However, I know a lot of the port power off code went into 3.9.  If we
 don't have these patches in 3.9, what will be the impact?  Will we say,
 misassign a power resource from a particular port, or mismark a USB port
 connection type?  Is there any user-level impact if we don't have these
 in 3.9?
 
 If these patches should go into 3.9, should they also be backported to
 3.8 and 3.7?  Commit d557542421da643358201664903e67fd01dfca1a
 usb/acpi: Bind ACPI node to USB port, not usb_device. was first
 introduced in 3.7, and it looks like the sysfs files to turn on and off
 ports were added in 3.7 as well.  Without these two patches, will
 that sysfs interface work correctly?

I think there is an impact for usb3.0 paired ports. So it's better to
backport these patchs to 3.7, 3.8, 3.9 if possible. These patches also
depend on the commit 1033f9041d ACPI: Allow ACPI binding with USB-3.0
hub. I'd like to take the job if I could do.

BTW, the sysfs files to turn on and off ports has been reverted by Greg
in v3.7.

 
 Sarah Sharp
 
 On Tue, Mar 19, 2013 at 04:48:13PM +0800, Lan Tianyu wrote:
 This patch is to bind xhci root hub usb port with its acpi node.
 The port num in the acpi table matches with the sequence in the xhci
 extended capabilities table. So call usb_hcd_find_raw_port_number() to
 transfer hub port num into raw port number which associates with
 the sequence in the xhci extended capabilities table before binding.

 Signed-off-by: Lan Tianyu tianyu@intel.com
 ---
 Change since v3:
add a temprorary variable to recard raw port num and get ACPI
 handle rahter than overwrite port num with raw port num. This is
 to avoid passing raw port num as port num to 
 usb_acpi_check_port_connect_type().

  drivers/usb/core/usb-acpi.c |8 +++-
  1 file changed, 7 insertions(+), 1 deletion(-)

 diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
 index b6f4bad..255c144 100644
 --- a/drivers/usb/core/usb-acpi.c
 +++ b/drivers/usb/core/usb-acpi.c
 @@ -15,6 +15,7 @@
  #include linux/kernel.h
  #include linux/acpi.h
  #include linux/pci.h
 +#include linux/usb/hcd.h
  #include acpi/acpi_bus.h
  
  #include usb.h
 @@ -188,8 +189,13 @@ static int usb_acpi_find_device(struct device *dev, 
 acpi_handle *handle)
   * connected to.
   */
  if (!udev-parent) {
 -*handle = acpi_get_child(DEVICE_ACPI_HANDLE(udev-dev),
 +struct usb_hcd *hcd = bus_to_hcd(udev-bus);
 +int raw_port_num;
 +
 +raw_port_num = usb_hcd_find_raw_port_number(hcd,
  port_num);
 +*handle = acpi_get_child(DEVICE_ACPI_HANDLE(udev-dev),
 +raw_port_num);
  if (!*handle)
  return -ENODEV;
  } else {
 -- 
 1.7.9.5



-- 
Best regards
Tianyu Lan
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Testing for hardware bug in EHCI controllers

2013-03-04 Thread Lan Tianyu
2013/2/26 Alan Stern st...@rowland.harvard.edu:
 Sarah (and anyone else who's interested):

 A while ago I wrote about a hardware bug in my Intel ICH5 and ICH8 EHCI
 controllers.  You pointed out that these are rather old components, not
 being used in current systems, which is quite true.

 Now I have figured out a simple way for anyone to test for this bug in
 any EHCI controller, without the need for a g-zero gadget.  It's a
 two-part procedure:

 Apply the patch below (which is written for vanilla 3.8) and
 load the resulting driver.  The patch adds an explicit test
 to ehci-hcd for detecting the bug.

 Then plug in an ordinary USB flash drive and run the attached
 program (as root), giving it the device path for the flash
 drive as the single command-line argument.  For example:

 sudo ./ehci-test /dev/bus/usb/002/003

 The program won't do anything bad to the flash drive; it just reads the
 first 256 KB of data over and over again, now and then unlinking an URB
 to try and trigger the bug.  If the program works right, it will print
 out a loop counter every hundred iterations.  If it runs for 1000
 iterations with no error messages in the kernel log, you may consider
 that the controller has passed the test.  This should take under a
 minute, depending on the hardware speed.

 The program won't stop by itself unless something goes wrong.  You can
 kill it with ^C or more simply by unplugging the flash drive.  (If you
 want to be safe, make sure there are no mounted filesystems on the
 drive before running the test program.)

 If the hardware bug is detected, the kernel patch will print error
 messages to the system log.  For example, when I run the test on the
 Intel controller in this computer, I get:

 [  150.019441] usb-storage 3-8:1.0: disconnect by usbfs
 [  150.271190] ehci-pci :00:1d.7: EHCI hardware bug detected: 8d00 
 80008d00
 [  150.591089] ehci-pci :00:1d.7: EHCI hardware bug detected: 8d00 
 80008d00
 [  151.538560] ehci-pci :00:1d.7: EHCI hardware bug detected: 8d00 
 80008d00
 [  151.857569] ehci-pci :00:1d.7: EHCI hardware bug detected: 8d00 
 80008d00
 [  152.018886] ehci-pci :00:1d.7: EHCI hardware bug detected: 8d00 
 80008d00
 [  152.179810] ehci-pci :00:1d.7: EHCI hardware bug detected: 80008d00 
 8d00
 [  153.211804] ehci-pci :00:1d.7: EHCI hardware bug detected: 8d00 
 80008d00
 [  153.374497] ehci-pci :00:1d.7: EHCI hardware bug detected: 8d00 
 80008d00
 [  153.770443] ehci-pci :00:1d.7: EHCI hardware bug detected: 80008d00 
 8d00
 [  154.247861] ehci-pci :00:1d.7: EHCI hardware bug detected: 82008d80 
 8d00
 [  154.566912] ehci-pci :00:1d.7: EHCI hardware bug detected: 82008d80 
 8d00
 [  155.359101] ehci-pci :00:1d.7: EHCI hardware bug detected: 8d00 
 80008d00
 [  155.838132] ehci-pci :00:1d.7: EHCI hardware bug detected: 8d00 
 80008d00
 [  156.791107] ehci-pci :00:1d.7: EHCI hardware bug detected: 80008d00 
 8d00
 [  157.267620] ehci-pci :00:1d.7: EHCI hardware bug detected: 8d00 
 80008d00
 [  159.252057] ehci-pci :00:1d.7: EHCI hardware bug detected: 80008d00 
 8d00
 [  159.886048] ehci-pci :00:1d.7: EHCI hardware bug detected: 80008d00 
 8d00
 [  160.206625] ehci-pci :00:1d.7: EHCI hardware bug detected: 02008d80 
 80008d00
 ...

 You get the idea.  The values in the two columns on the right are
 always supposed to be equal; when they aren't it indicates that the
 controller has done a DMA write at a time when ehci-hcd isn't expecting
 one to happen.

 I'd be interested to hear the results of testing on a variety of
 controllers.  (This computer also has an NEC EHCI controller, and that
 one does not have the bug.)  Do the EHCI controllers on current Intel
 chipsets pass the test?  What about other vendors?

 Thanks to all who try it out and report their results.
Test on the Sandybridge platform.
At the first time, I get following output. But after that, I was
hard to get any output. And test on the v3.8.

sudo ./ehci-test /dev/bus/usb/001/003
[  140.855342] usb-storage 1-1.2:1.0: disconnect by usbfs
Invalid URB stat[  140.863000] ehci-pci :00:1a.0: shutdown urb
88014545f300 ep1in-bulk
[  140.871303] ehci-pci :00:1a.0: shutdown urb 88014545f0c0 ep1in-bulk
[  140.878231] ehci-pci :00:1a.0: shutdown urb 88014545fcc0 ep1in-bulk
[  140.885158] ehci-pci :00:1a.0: shutdown urb 88014545fb40 ep1in-bulk
[  140.892088] ehci-pci :00:1a.0: shutdown urb 88014545f9c0 ep1in-bulk
[  140.899015] ehci-pci :00:1a.0: shutdown urb 88014545f780 ep1in-bulk
[  140.905941] ehci-pci :00:1a.0: shutdown urb 88014545f240 ep1in-bulk
[  140.912870] ehci-pci :00:1a.0: shutdown urb 88014545f900 ep1in-bulk
[  140.919799] ehci-pci :00:1a.0: shutdown urb 88014545fc00 ep1in-bulk
[  140.926725] ehci-pci :00:1a.0: shutdown urb 

Re: [PATCH 4/5] usb: call pm_runtime_put_sync in pm_runtime_get_sync failed case

2013-02-28 Thread Lan Tianyu
On 2013年02月28日 15:57, Li Fei wrote:
 
 Even in failed case of pm_runtime_get_sync, the usage_count
 is incremented. In order to keep the usage_count with correct
 value and runtime power management to behave correctly, call
 pm_runtime_put(_sync) in such case.

Hi Fei:
It's not necessary. Because the did_runtime_put == true means the
port's usage count has already been decreased during
usb_port_suspend().So to keep usage count balance, we should increase
the usage count in the usb_port_resume() whatever.

 
 Signed-off-by Liu Chuansheng chuansheng@intel.com
 Signed-off-by: Li Fei fei...@intel.com
 ---
  drivers/usb/core/hub.c |1 +
  1 files changed, 1 insertions(+), 0 deletions(-)
 
 diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
 index 5480352..b68493b 100644
 --- a/drivers/usb/core/hub.c
 +++ b/drivers/usb/core/hub.c
 @@ -3152,6 +3152,7 @@ int usb_port_resume(struct usb_device *udev, 
 pm_message_t msg)
   if (status  0) {
   dev_dbg(udev-dev, can't resume usb port, status 
 %d\n,
   status);
 + pm_runtime_put_sync(port_dev-dev);
   return status;
   }
   }
 
Hi Alan:
Further thinking, the device should be disconnected since the port
can't be resumed and the device will not work normally. Something like
following. Does this make sense?
---
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index d5d3de4..cf36b11 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3170,6 +3170,7 @@ int usb_port_resume(struct usb_device *udev,
pm_message_t msg)
if (status  0) {
dev_dbg(udev-dev, can't resume usb port,
status %d\n,
status);
+   hub_port_logical_disconnect(hub, port1);
return status;
}
}


-- 
Best regards
Tianyu Lan
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Resend][PATCH] ACPI / glue: Drop .find_bridge() callback from struct acpi_bus_type

2013-02-27 Thread Lan Tianyu
On 2013年02月28日 07:31, Yinghai Lu wrote:
 On Wed, Feb 27, 2013 at 2:20 PM, Greg Kroah-Hartman
 gre...@linuxfoundation.org wrote:
 On Wed, Feb 27, 2013 at 11:06:52PM +0100, Rafael J. Wysocki wrote:
 From: Rafael J. Wysocki rafael.j.wyso...@intel.com

 After PCI has stopped using the .find_bridge() callback in
 struct acpi_bus_type, the only remaining users of it are SATA and
 USB.  However, SATA only pretends to be a user, because it points
 that callback to a stub always returning -ENODEV, and USB uses it
 incorrectly, because as a result of the way it is used by USB every
 device in the system that doesn't have a bus type or parent is
 passed to usb_acpi_find_device() for inspection.

 What USB actually needs, though, is to call usb_acpi_find_device()
 for USB ports that don't have a bus type defined, but have
 usb_port_device_type as their device type.

 Ick, that's not good.  Can you have the original creator of that code
 (someone else from Intel, I can't remember at the moment), fix that up
 properly and send me patches?
 
 [Add To: Lan Tianyu tianyu@intel.com]
Ok. I will fix it later.
 

 Please let me know if there are any objections.
 
 I still prefer to ask USB to add bus_type instead at first.
 
 Thanks
 
 Yinghai
 


-- 
Best regards
Tianyu Lan
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [GIT PATCH] USB patches for 3.9-rc1

2013-02-22 Thread Lan Tianyu

On 2013/2/22 16:59, Dave Jones wrote:

On Thu, Feb 21, 2013 at 10:40:10AM -0800, Greg KH wrote:

   USB patches for 3.9-rc1
  
   Here's the big USB merge for 3.9-rc1
  
   Nothing major, lots of gadget fixes, and of course, xhci stuff.

I get no USB devices recognised when I insert them any more, which
I think is pretty major.  I suspect it has something to do with this ?

   Lan Tianyu (12):
 usb: add runtime pm support for usb port device
 usb: add usb port auto power off mechanism

It looks like every port on my laptop is powered down, as I can't
even charge devices with it.


Hi Dave:
Do you disable usb port's pm_qos_no_power_off?
cat /sys/bus/usb/devices/(dev)/port/power/pm_qos_no_power_off


I tried running powertop, which noted autosuspend for the usb controllers
was 'good'. I flipped them to 'bad', but it made no difference.

What can I do to debug this ?

Can you attach the output of dmesg with CONFIG_USB_DEBUG?


$ lspci | grep USB
00:14.0 USB controller: Intel Corporation 7 Series/C210 Series Chipset Family 
USB xHCI Host Controller (rev 04)
00:1a.0 USB controller: Intel Corporation 7 Series/C210 Series Chipset Family 
USB Enhanced Host Controller #2 (rev 04)
00:1d.0 USB controller: Intel Corporation 7 Series/C210 Series Chipset Family 
USB Enhanced Host Controller #1 (rev 04)

$ lsusb
Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 0a5c:21e6 Broadcom Corp. BCM20702 Bluetooth 4.0 
[ThinkPad]
Bus 001 Device 004: ID 5986:02d5 Acer, Inc

(inserted USB devices don't show up in this list)

$ dmesg | grep -i usb
[0.996096] ACPI: bus type usb registered
[0.996428] usbcore: registered new interface driver usbfs
[0.996638] usbcore: registered new interface driver hub
[0.996875] usbcore: registered new device driver usb
[1.874896] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[1.876103] ehci-pci :00:1a.0: new USB bus registered, assigned bus 
number 1
[1.886220] ehci-pci :00:1a.0: USB 2.0 started, EHCI 1.00
[1.886781] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
[1.886878] usb usb1: New USB device strings: Mfr=3, Product=2, 
SerialNumber=1
[1.887017] usb usb1: Product: EHCI Host Controller
[1.887111] usb usb1: Manufacturer: Linux 3.8.0+ ehci_hcd
[1.887220] usb usb1: SerialNumber: :00:1a.0
[1.888942] hub 1-0:1.0: USB hub found
[1.892347] ehci-pci :00:1d.0: new USB bus registered, assigned bus 
number 2
[1.902216] ehci-pci :00:1d.0: USB 2.0 started, EHCI 1.00
[1.902674] usb usb2: New USB device found, idVendor=1d6b, idProduct=0002
[1.902770] usb usb2: New USB device strings: Mfr=3, Product=2, 
SerialNumber=1
[1.902910] usb usb2: Product: EHCI Host Controller
[1.903004] usb usb2: Manufacturer: Linux 3.8.0+ ehci_hcd
[1.903098] usb usb2: SerialNumber: :00:1d.0
[1.90] hub 2-0:1.0: USB hub found
[1.906795] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[1.906970] uhci_hcd: USB Universal Host Controller Interface driver
[1.908243] xhci_hcd :00:14.0: new USB bus registered, assigned bus 
number 3
[1.909823] usb usb3: New USB device found, idVendor=1d6b, idProduct=0002
[1.909920] usb usb3: New USB device strings: Mfr=3, Product=2, 
SerialNumber=1
[1.910060] usb usb3: Product: xHCI Host Controller
[1.910153] usb usb3: Manufacturer: Linux 3.8.0+ xhci_hcd
[1.910260] usb usb3: SerialNumber: :00:14.0
[1.911644] hub 3-0:1.0: USB hub found
[1.930176] xhci_hcd :00:14.0: new USB bus registered, assigned bus 
number 4
[1.930802] usb usb4: New USB device found, idVendor=1d6b, idProduct=0003
[1.930899] usb usb4: New USB device strings: Mfr=3, Product=2, 
SerialNumber=1
[1.931039] usb usb4: Product: xHCI Host Controller
[1.931131] usb usb4: Manufacturer: Linux 3.8.0+ xhci_hcd
[1.931239] usb usb4: SerialNumber: :00:14.0
[1.932568] hub 4-0:1.0: USB hub found
[1.950215] usbcore: registered new interface driver usbserial
[1.950388] usbcore: registered new interface driver usbserial_generic
[1.950612] usbserial: USB Serial support registered for generic
[1.950781] usbcore: registered new interface driver usb_debug
[1.950959] usbserial: USB Serial support registered for debug
[1.972227] usbcore: registered new interface driver usbhid
[1.972322] usbhid: USB HID core driver
[2.193584] usb 1-1: new high-speed USB device number 2 using ehci-pci
[2.309836] usb 1-1: New USB device found, idVendor=8087, idProduct=0024
[2.309965] usb 1-1: New USB device strings: Mfr=0

Re: [GIT PATCH] USB patches for 3.9-rc1

2013-02-22 Thread Lan Tianyu

On 2013/2/23 0:43, Dave Jones wrote:

On Fri, Feb 22, 2013 at 05:51:10PM +0800, Lan Tianyu wrote:

   Nothing major, lots of gadget fixes, and of course, xhci stuff.
   
I get no USB devices recognised when I insert them any more, which
I think is pretty major.  I suspect it has something to do with this ?
   
   Lan Tianyu (12):
 usb: add runtime pm support for usb port device
 usb: add usb port auto power off mechanism
   
It looks like every port on my laptop is powered down, as I can't
even charge devices with it.
  
Do you enable the port/power/pm_qos_no_power_off?
cat /sys/bus/usb/devices/(dev)/port/power/pm_qos_no_power_off to show.

/sys/bus/usb/devices/1-1.4/port/power/pm_qos_no_power_off:1
/sys/bus/usb/devices/1-1.6/port/power/pm_qos_no_power_off:1
/sys/bus/usb/devices/1-1/port/power/pm_qos_no_power_off:1
/sys/bus/usb/devices/2-1/port/power/pm_qos_no_power_off:1


At last, this mean usb port power off mechanism should not work.


I changed them to 0, made no difference.

What can I do to debug this ?
Can you attach the output of dmesg with CONFIG_USB_DEBUG?

http://paste.fedoraproject.org/3620

How aboutsudo lsusb -s 1:1 -v or 2:1?


Dave



--
Best Regards
Tianyu Lan
linux kernel enabling team
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [GIT PATCH] USB patches for 3.9-rc1

2013-02-22 Thread Lan Tianyu

On 2013/2/23 1:14, Dave Jones wrote:

On Sat, Feb 23, 2013 at 01:02:11AM +0800, Lan Tianyu wrote:

What can I do to debug this ?
Can you attach the output of dmesg with CONFIG_USB_DEBUG?
   
http://paste.fedoraproject.org/3620
   How aboutsudo lsusb -s 1:1 -v or 2:1?

(12:13:51:davej@t430s:~)$ sudo lsusb -s 1:1
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
(12:13:53:davej@t430s:~)$ sudo lsusb -s 2:1
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub


Oh. Sorry, I didn't say clearly.
Please run
sudo lsusb -s 1:1 -v
sudo lsusb -s 2:1 -v

--
Best Regards
Tianyu Lan
linux kernel enabling team
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Not enough resource for old configuration after USB bus reset

2013-02-20 Thread Lan Tianyu
2013/2/19 Soar Hung soarh...@realtek.com:
 Hi all,

 I checkout the usb-next branch (on 2/18) and following the 
 https://wiki.ubuntu.com/KernelTeam/GitKernelBuild to build the kernel.

 After reboot, the new kernel version is Linux dev 3.8.0-rc5-usbnext #1 SMP 
 Mon Feb 18 18:04:02 CST 2013 i686 i686 i386 GNU/Linux.

 I try the same operation to produce the issue, and it also fails.
Please attach the output of dmesg with CONFIG_USB_DEBUG and XHCI_DEBUG.

 Thanks,
 Soar

 -Original Message-
 From: Lan Tianyu [mailto:lantianyu1...@gmail.com]
 Sent: Friday, February 08, 2013 12:57 AM
 To: Soar Hung
 Cc: Alan Stern; Sarah Sharp; linux-usb@vger.kernel.org
 Subject: Re: Not enough resource for old configuration after USB bus reset

 于 2013/2/7 16:59, Soar Hung 写道:
 Hi Tianyu,

 I can produce the issue on the Ubuntu 12.10 (linux 3.5), too.

 However, could you tell me more detail about what to do or give me some hint 
 for google?
 Do you mean replacing the usb related source with source from 'usb next', 
 rebuild the kernel, and test again?

 I think you can git clone
 git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git and git 
 checkout usb-next.
 Compile kernel and test it.
 Best regards,
 Soar

 -Original Message-
 From: Lan Tianyu [mailto:lantianyu1...@gmail.com]
 Sent: Thursday, February 07, 2013 4:18 PM
 To: Soar Hung
 Cc: Alan Stern; Sarah Sharp; linux-usb@vger.kernel.org
 Subject: Re: Not enough resource for old configuration after USB bus
 reset

 2013/2/4 Soar Hung soarh...@realtek.com:
 Hi Alan, Sarah,

 Thank you for your kindly help.

 Can I do something to provide some help?

 You found the issue on the 3.0.30+ kernel. Can you test it on the usb-next 
 branch of usb tree?  Sarah has fixed a lot of bugs since v3.0.
 Best regards,
 Soar

 -Original Message-
 From: Alan Stern [mailto:st...@rowland.harvard.edu]
 Sent: Friday, February 01, 2013 11:36 PM
 To: Soar Hung
 Cc: Sarah Sharp; linux-usb@vger.kernel.org
 Subject: RE: Not enough resource for old configuration after USB bus
 reset

 On Fri, 1 Feb 2013, [big5]  x R   wrote:

 Hi,

 According to xHCI spec Rev1 page 125, Endpoint context state diagram.

 When reset device, the endpoint state transit to disabled state.

 Do I make some mistake?

 I'll try to figure out the endopint state transitions during the reset 
 flow, and update information later.

 Thanks for the direction.

 Ah, now I understand the problem.  The device reset automatically disables 
 the endpoints, so when usb_reset_and_verify_device calls 
 usb_hcd_alloc_bandwidth, and that routine tries to drop the endpoints, it 
 fails because the endpoints are already disabled.

 Sarah is going to to have to figure out the right way to fix this.
 She's the maintainer for xhci-hcd.

 Alan Stern




 --
 Best regards
 Tianyu Lan

 --Please consider the environment before printing this e-mail.


 --
 Best regards
 Tianyu Lan



-- 
Best regards
Tianyu Lan
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Not enough resource for old configuration after USB bus reset

2013-02-07 Thread Lan Tianyu
2013/2/4 Soar Hung soarh...@realtek.com:
 Hi Alan, Sarah,

 Thank you for your kindly help.

 Can I do something to provide some help?

You found the issue on the 3.0.30+ kernel. Can you test
it on the usb-next branch of usb tree?  Sarah has
fixed a lot of bugs since v3.0.
 Best regards,
 Soar

 -Original Message-
 From: Alan Stern [mailto:st...@rowland.harvard.edu]
 Sent: Friday, February 01, 2013 11:36 PM
 To: Soar Hung
 Cc: Sarah Sharp; linux-usb@vger.kernel.org
 Subject: RE: Not enough resource for old configuration after USB bus reset

 On Fri, 1 Feb 2013, [big5]  x R   wrote:

 Hi,

 According to xHCI spec Rev1 page 125, Endpoint context state diagram.

 When reset device, the endpoint state transit to disabled state.

 Do I make some mistake?

 I'll try to figure out the endopint state transitions during the reset flow, 
 and update information later.

 Thanks for the direction.

 Ah, now I understand the problem.  The device reset automatically disables 
 the endpoints, so when usb_reset_and_verify_device calls 
 usb_hcd_alloc_bandwidth, and that routine tries to drop the endpoints, it 
 fails because the endpoints are already disabled.

 Sarah is going to to have to figure out the right way to fix this.
 She's the maintainer for xhci-hcd.

 Alan Stern




-- 
Best regards
Tianyu Lan
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Not enough resource for old configuration after USB bus reset

2013-02-07 Thread Lan Tianyu

于 2013/2/7 16:59, Soar Hung 写道:

Hi Tianyu,

I can produce the issue on the Ubuntu 12.10 (linux 3.5), too.

However, could you tell me more detail about what to do or give me some hint 
for google?
Do you mean replacing the usb related source with source from 'usb next', 
rebuild the kernel, and test again?

I think you can git clone 
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git and git checkout 
usb-next.

Compile kernel and test it.

Best regards,
Soar

-Original Message-
From: Lan Tianyu [mailto:lantianyu1...@gmail.com]
Sent: Thursday, February 07, 2013 4:18 PM
To: Soar Hung
Cc: Alan Stern; Sarah Sharp; linux-usb@vger.kernel.org
Subject: Re: Not enough resource for old configuration after USB bus reset

2013/2/4 Soar Hung soarh...@realtek.com:

Hi Alan, Sarah,

Thank you for your kindly help.

Can I do something to provide some help?


You found the issue on the 3.0.30+ kernel. Can you test it on the usb-next 
branch of usb tree?  Sarah has fixed a lot of bugs since v3.0.

Best regards,
Soar

-Original Message-
From: Alan Stern [mailto:st...@rowland.harvard.edu]
Sent: Friday, February 01, 2013 11:36 PM
To: Soar Hung
Cc: Sarah Sharp; linux-usb@vger.kernel.org
Subject: RE: Not enough resource for old configuration after USB bus
reset

On Fri, 1 Feb 2013, [big5]  x R   wrote:


Hi,

According to xHCI spec Rev1 page 125, Endpoint context state diagram.

When reset device, the endpoint state transit to disabled state.

Do I make some mistake?

I'll try to figure out the endopint state transitions during the reset flow, 
and update information later.

Thanks for the direction.


Ah, now I understand the problem.  The device reset automatically disables the 
endpoints, so when usb_reset_and_verify_device calls usb_hcd_alloc_bandwidth, 
and that routine tries to drop the endpoints, it fails because the endpoints 
are already disabled.

Sarah is going to to have to figure out the right way to fix this.
She's the maintainer for xhci-hcd.

Alan Stern





--
Best regards
Tianyu Lan

--Please consider the environment before printing this e-mail.



--
Best regards
Tianyu Lan
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] Revert usb: Register usb port's acpi power resources

2013-01-28 Thread Lan Tianyu
This reverts commit 88bb965ed711e8a5984e70208ebc901a6ff4141f.

The linux-next branch of linux-pm tree has replaced
acpi_power_resource_(un)register_device() with new routines.
Commit 88bb965 will cause conflict in the linux-next tree.
So revert it and this will not affect other functions. Will
send a new patch with new routines after 3.9 merge window.

Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/port.c |6 --
 drivers/usb/core/usb-acpi.c |   18 --
 drivers/usb/core/usb.h  |6 --
 3 files changed, 30 deletions(-)

diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 5df143d..797f9d5 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -68,7 +68,6 @@ static void usb_port_device_release(struct device *dev)
struct usb_port *port_dev = to_usb_port(dev);
 
dev_pm_qos_hide_flags(dev);
-   usb_acpi_unregister_power_resources(dev);
kfree(port_dev);
 }
 
@@ -187,11 +186,6 @@ int usb_hub_create_port_device(struct usb_hub *hub, int 
port1)
pm_runtime_enable(port_dev-dev);
 
device_enable_async_suspend(port_dev-dev);
-
-   retval = usb_acpi_register_power_resources(port_dev-dev);
-   if (retval  retval != -ENODEV)
-   dev_warn(port_dev-dev, the port can't register its ACPI 
power resource.\n);
-
return 0;
 
 error_register:
diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
index 8d304b0..cef4252 100644
--- a/drivers/usb/core/usb-acpi.c
+++ b/drivers/usb/core/usb-acpi.c
@@ -216,24 +216,6 @@ static struct acpi_bus_type usb_acpi_bus = {
.find_device = usb_acpi_find_device,
 };
 
-int usb_acpi_register_power_resources(struct device *dev)
-{
-   acpi_handle port_handle = DEVICE_ACPI_HANDLE(dev);
-
-   if (!port_handle)
-   return -ENODEV;
-
-   return acpi_power_resource_register_device(dev, port_handle);
-}
-
-void usb_acpi_unregister_power_resources(struct device *dev)
-{
-   acpi_handle port_handle = DEVICE_ACPI_HANDLE(dev);
-
-   if (port_handle)
-   acpi_power_resource_unregister_device(dev, port_handle);
-}
-
 int usb_acpi_register(void)
 {
return register_acpi_bus_type(usb_acpi_bus);
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 601b044..a7f20bd 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -191,13 +191,7 @@ extern int usb_acpi_register(void);
 extern void usb_acpi_unregister(void);
 extern acpi_handle usb_get_hub_port_acpi_handle(struct usb_device *hdev,
int port1);
-extern int usb_acpi_register_power_resources(struct device *dev);
-extern void usb_acpi_unregister_power_resources(struct device *dev);
 #else
 static inline int usb_acpi_register(void) { return 0; };
 static inline void usb_acpi_unregister(void) { };
-static inline int usb_acpi_register_power_resources(struct device *dev)
-   { return 0; };
-static inline void usb_acpi_unregister_power_resources(struct device *dev)
-   { };
 #endif
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 1/3] usb: add find_raw_port_number callback to struct hc_driver()

2013-01-24 Thread Lan Tianyu
On 2013年01月25日 08:52, Sarah Sharp wrote:
 Please combine this patch with patch three, so that I can clearly see
 what is being replaced in xhci-mem.c:xhci_find_real_port_number.
 
Ok, I will refresh it soon.
 Sarah Sharp
 
 On Sat, Jan 19, 2013 at 12:43:32AM +0800, Lan Tianyu wrote:
 xhci driver divides the root hub into two logical hubs which work
 respectively for usb 2.0 and usb 3.0 devices. They are independent
 devices in the usb core. But in the ACPI table, it's one device node
 and all usb2.0 and usb3.0 ports are under it. Binding usb port with
 its acpi node needs the raw port number which is reflected in the xhci
 extended capabilities table. This patch is to add find_raw_port_number
 callback to struct hc_driver() and fill it with xhci_find_raw_port_number().

 Signed-off-by: Lan Tianyu tianyu@intel.com
 ---
 Change since v1:
  Don't export usb_hcd_find_raw_port_number() symbol since there is no
 its user outside of usb core.

 This patchset is rebased on the usb-next tree commit 74ff31b81d9
 usb: misc: usb3503_probe() can be static
 ---
  drivers/usb/core/hcd.c  |8 
  drivers/usb/host/xhci-pci.c |1 +
  drivers/usb/host/xhci.c |   22 ++
  drivers/usb/host/xhci.h |1 +
  include/linux/usb/hcd.h |2 ++
  5 files changed, 34 insertions(+)

 diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
 index 5f6da8b..0277bd2 100644
 --- a/drivers/usb/core/hcd.c
 +++ b/drivers/usb/core/hcd.c
 @@ -2364,6 +2364,14 @@ int usb_hcd_is_primary_hcd(struct usb_hcd *hcd)
  }
  EXPORT_SYMBOL_GPL(usb_hcd_is_primary_hcd);
  
 +int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1)
 +{
 +if (!hcd-driver-find_raw_port_number)
 +return port1;
 +
 +return hcd-driver-find_raw_port_number(hcd, port1);
 +}
 +
  static int usb_hcd_request_irqs(struct usb_hcd *hcd,
  unsigned int irqnum, unsigned long irqflags)
  {
 diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
 index af259e0..1a30c38 100644
 --- a/drivers/usb/host/xhci-pci.c
 +++ b/drivers/usb/host/xhci-pci.c
 @@ -313,6 +313,7 @@ static const struct hc_driver xhci_pci_hc_driver = {
  .set_usb2_hw_lpm =  xhci_set_usb2_hardware_lpm,
  .enable_usb3_lpm_timeout =  xhci_enable_usb3_lpm_timeout,
  .disable_usb3_lpm_timeout = xhci_disable_usb3_lpm_timeout,
 +.find_raw_port_number = xhci_find_raw_port_number,
  };
  
  
 /*-*/
 diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
 index f1f01a8..0780d8f 100644
 --- a/drivers/usb/host/xhci.c
 +++ b/drivers/usb/host/xhci.c
 @@ -3778,6 +3778,28 @@ int xhci_address_device(struct usb_hcd *hcd, struct 
 usb_device *udev)
  return 0;
  }
  
 +/*
 + * Transfer the port index into real index in the HW port status
 + * registers. Caculate offset between the port's PORTSC register
 + * and port status base. Divide the number of per port register
 + * to get the real index. The raw port number bases 1.
 + */
 +int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1)
 +{
 +struct xhci_hcd *xhci = hcd_to_xhci(hcd);
 +__le32 __iomem *base_addr = xhci-op_regs-port_status_base;
 +__le32 __iomem *addr;
 +int raw_port;
 +
 +if (hcd-speed != HCD_USB3)
 +addr = xhci-usb2_ports[port1 - 1];
 +else
 +addr = xhci-usb3_ports[port1 - 1];
 +
 +raw_port = (addr - base_addr)/NUM_PORT_REGS + 1;
 +return raw_port;
 +}
 +
  #ifdef CONFIG_USB_SUSPEND
  
  /* BESL to HIRD Encoding array for USB2 LPM */
 diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
 index f791bd0..55345d9 100644
 --- a/drivers/usb/host/xhci.h
 +++ b/drivers/usb/host/xhci.h
 @@ -1829,6 +1829,7 @@ void xhci_test_and_clear_bit(struct xhci_hcd *xhci, 
 __le32 __iomem **port_array,
  int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 
 wIndex,
  char *buf, u16 wLength);
  int xhci_hub_status_data(struct usb_hcd *hcd, char *buf);
 +int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1);
  
  #ifdef CONFIG_PM
  int xhci_bus_suspend(struct usb_hcd *hcd);
 diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
 index 608050b..61b88b5 100644
 --- a/include/linux/usb/hcd.h
 +++ b/include/linux/usb/hcd.h
 @@ -357,6 +357,7 @@ struct hc_driver {
   */
  int (*disable_usb3_lpm_timeout)(struct usb_hcd *,
  struct usb_device *, enum usb3_link_state state);
 +int (*find_raw_port_number)(struct usb_hcd *, int);
  };
  
  extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
 @@ -396,6 +397,7 @@ extern int usb_hcd_is_primary_hcd(struct usb_hcd *hcd);
  extern int usb_add_hcd(struct usb_hcd *hcd,
  unsigned int irqnum, unsigned long irqflags);
  extern void usb_remove_hcd(struct usb_hcd *hcd);
 +extern int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1

[PATCH v3 1/2] usb: add find_raw_port_number callback to struct hc_driver()

2013-01-24 Thread Lan Tianyu
xhci driver divides the root hub into two logical hubs which work
respectively for usb 2.0 and usb 3.0 devices. They are independent
devices in the usb core. But in the ACPI table, it's one device node
and all usb2.0 and usb3.0 ports are under it. Binding usb port with
its acpi node needs the raw port number which is reflected in the xhci
extended capabilities table. This patch is to add find_raw_port_number
callback to struct hc_driver() and fill it with xhci_find_raw_port_number().
Otherwise, call xhci_find_raw_port_number() to get real index in the HW port
status registers instead of scanning through the xHCI roothub port array in
the xhci_find_real_port_number().

Signed-off-by: Lan Tianyu tianyu@intel.com
---
Change since v1:
Don't export usb_hcd_find_raw_port_number() symbol since there is no
its user outside of usb core.

Change since v2:
combine patch usb: add find_raw_port_number callback to struct
hc_driver() with this patch.

This patchset is rebased on the usb-next tree commit 6e24777
usb: ehci-s5p/ohci-exynos: Fix compatible strings for the device


 drivers/usb/core/hcd.c  |9 +
 drivers/usb/host/xhci-mem.c |   36 
 drivers/usb/host/xhci-pci.c |1 +
 drivers/usb/host/xhci.c |   22 ++
 drivers/usb/host/xhci.h |1 +
 include/linux/usb/hcd.h |2 ++
 6 files changed, 43 insertions(+), 28 deletions(-)

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 2459896..774ac61 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2368,6 +2368,15 @@ int usb_hcd_is_primary_hcd(struct usb_hcd *hcd)
 }
 EXPORT_SYMBOL_GPL(usb_hcd_is_primary_hcd);
 
+int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1)
+{
+   if (!hcd-driver-find_raw_port_number)
+   return port1;
+
+   return hcd-driver-find_raw_port_number(hcd, port1);
+}
+EXPORT_SYMBOL_GPL(usb_hcd_find_raw_port_number);
+
 static int usb_hcd_request_irqs(struct usb_hcd *hcd,
unsigned int irqnum, unsigned long irqflags)
 {
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 35616ff..6dc238c 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1022,44 +1022,24 @@ void xhci_copy_ep0_dequeue_into_input_ctx(struct 
xhci_hcd *xhci,
  * is attached to (or the roothub port its ancestor hub is attached to).  All 
we
  * know is the index of that port under either the USB 2.0 or the USB 3.0
  * roothub, but that doesn't give us the real index into the HW port status
- * registers.  Scan through the xHCI roothub port array, looking for the Nth
- * entry of the correct port speed.  Return the port number of that entry.
+ * registers. Call xhci_find_raw_port_number() to get real index.
  */
 static u32 xhci_find_real_port_number(struct xhci_hcd *xhci,
struct usb_device *udev)
 {
struct usb_device *top_dev;
-   unsigned int num_similar_speed_ports;
-   unsigned int faked_port_num;
-   int i;
+   struct usb_hcd *hcd;
+
+   if (udev-speed == USB_SPEED_SUPER)
+   hcd = xhci-shared_hcd;
+   else
+   hcd = xhci-main_hcd;
 
for (top_dev = udev; top_dev-parent  top_dev-parent-parent;
top_dev = top_dev-parent)
/* Found device below root hub */;
-   faked_port_num = top_dev-portnum;
-   for (i = 0, num_similar_speed_ports = 0;
-   i  HCS_MAX_PORTS(xhci-hcs_params1); i++) {
-   u8 port_speed = xhci-port_array[i];
-
-   /*
-* Skip ports that don't have known speeds, or have duplicate
-* Extended Capabilities port speed entries.
-*/
-   if (port_speed == 0 || port_speed == DUPLICATE_ENTRY)
-   continue;
 
-   /*
-* USB 3.0 ports are always under a USB 3.0 hub.  USB 2.0 and
-* 1.1 ports are under the USB 2.0 hub.  If the port speed
-* matches the device speed, it's a similar speed port.
-*/
-   if ((port_speed == 0x03) == (udev-speed == USB_SPEED_SUPER))
-   num_similar_speed_ports++;
-   if (num_similar_speed_ports == faked_port_num)
-   /* Roothub ports are numbered from 1 to N */
-   return i+1;
-   }
-   return 0;
+   return  xhci_find_raw_port_number(hcd, top_dev-portnum);
 }
 
 /* Setup an xHCI virtual device for a Set Address command */
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index af259e0..1a30c38 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -313,6 +313,7 @@ static const struct hc_driver xhci_pci_hc_driver = {
.set_usb2_hw_lpm =  xhci_set_usb2_hardware_lpm,
.enable_usb3_lpm_timeout =  xhci_enable_usb3_lpm_timeout

[PATCH v3 2/2] usb/acpi: binding xhci root hub usb port with ACPI

2013-01-24 Thread Lan Tianyu
This patch is to bind xhci root hub usb port with its acpi node.
The port num in the acpi table matches with the sequence in the xhci
extended capabilities table. So call usb_hcd_find_raw_port_number() to
transfer hub port num into raw port number which associates with
the sequence in the xhci extended capabilities table before binding.

Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/usb-acpi.c |4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
index cef4252..40f5a6a 100644
--- a/drivers/usb/core/usb-acpi.c
+++ b/drivers/usb/core/usb-acpi.c
@@ -15,6 +15,7 @@
 #include linux/kernel.h
 #include linux/acpi.h
 #include linux/pci.h
+#include linux/usb/hcd.h
 #include acpi/acpi_bus.h
 
 #include usb.h
@@ -188,6 +189,9 @@ static int usb_acpi_find_device(struct device *dev, 
acpi_handle *handle)
 * connected to.
 */
if (!udev-parent) {
+   struct usb_hcd *hcd = bus_to_hcd(udev-bus);
+
+   port_num = usb_hcd_find_raw_port_number(hcd, port_num);
*handle = acpi_get_child(DEVICE_ACPI_HANDLE(udev-dev),
port_num);
if (!*handle)
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 1/2] usb: Using correct way to clear usb3.0 device's remote wakeup feature.

2013-01-23 Thread Lan Tianyu
Usb3.0 device defines function remote wakeup which is only for interface
recipient rather than device recipient. This is different with usb2.0 device's
remote wakeup feature which is defined for device recipient. According usb3.0
spec 9.4.5, the function remote wakeup can be modified by the SetFeature()
requests using the FUNCTION_SUSPEND feature selector. This patch is to use
correct way to disable usb3.0 device's function remote wakeup after suspend
error and resuming.

Signed-off-by: Lan Tianyu tianyu@intel.com
---
This patchset is based on the usb-next tree commit d2123fd:
USB: Set usb port's DeviceRemovable according acpi information

 drivers/usb/core/hub.c   |   70 +++---
 include/uapi/linux/usb/ch9.h |6 
 2 files changed, 58 insertions(+), 18 deletions(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 29ca6ed..29791a6 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2776,6 +2776,23 @@ void usb_enable_ltm(struct usb_device *udev)
 EXPORT_SYMBOL_GPL(usb_enable_ltm);
 
 #ifdef CONFIG_USB_SUSPEND
+/*
+ * usb_disable_function_remotewakeup - disable usb3.0
+ * device's function remote wakeup
+ * @udev: target device
+ *
+ * Assume there's only one function on the USB 3.0
+ * device and disable remote wake for the first
+ * interface. FIXME if the interface association
+ * descriptor shows there's more than one function.
+ */
+static int usb_disable_function_remotewakeup(struct usb_device *udev)
+{
+   return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+   USB_REQ_CLEAR_FEATURE, USB_RECIP_INTERFACE,
+   USB_INTRF_FUNC_SUSPEND, 0, NULL, 0,
+   USB_CTRL_SET_TIMEOUT);
+}
 
 /*
  * usb_port_suspend - suspend a usb device's upstream port
@@ -2891,12 +2908,19 @@ int usb_port_suspend(struct usb_device *udev, 
pm_message_t msg)
dev_dbg(hub-intfdev, can't suspend port %d, status %d\n,
port1, status);
/* paranoia:  should not happen */
-   if (udev-do_remote_wakeup)
-   (void) usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
-   USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE,
-   USB_DEVICE_REMOTE_WAKEUP, 0,
-   NULL, 0,
-   USB_CTRL_SET_TIMEOUT);
+   if (udev-do_remote_wakeup) {
+   if (!hub_is_superspeed(hub-hdev)) {
+   (void) usb_control_msg(udev,
+   usb_sndctrlpipe(udev, 0),
+   USB_REQ_CLEAR_FEATURE,
+   USB_RECIP_DEVICE,
+   USB_DEVICE_REMOTE_WAKEUP, 0,
+   NULL, 0,
+   USB_CTRL_SET_TIMEOUT);
+   } else
+   (void) usb_disable_function_remotewakeup(udev);
+
+   }
 
/* Try to enable USB2 hardware LPM again */
if (udev-usb2_hw_lpm_capable == 1)
@@ -2988,20 +3012,30 @@ static int finish_port_resume(struct usb_device *udev)
 * udev-reset_resume
 */
} else if (udev-actconfig  !udev-reset_resume) {
-   le16_to_cpus(devstatus);
-   if (devstatus  (1  USB_DEVICE_REMOTE_WAKEUP)) {
-   status = usb_control_msg(udev,
-   usb_sndctrlpipe(udev, 0),
-   USB_REQ_CLEAR_FEATURE,
+   if (!hub_is_superspeed(udev-parent)) {
+   le16_to_cpus(devstatus);
+   if (devstatus  (1  USB_DEVICE_REMOTE_WAKEUP))
+   status = usb_control_msg(udev,
+   usb_sndctrlpipe(udev, 0),
+   USB_REQ_CLEAR_FEATURE,
USB_RECIP_DEVICE,
-   USB_DEVICE_REMOTE_WAKEUP, 0,
-   NULL, 0,
-   USB_CTRL_SET_TIMEOUT);
-   if (status)
-   dev_dbg(udev-dev,
-   disable remote wakeup, status %d\n,
-   status);
+   USB_DEVICE_REMOTE_WAKEUP, 0,
+   NULL, 0,
+   USB_CTRL_SET_TIMEOUT);
+   } else {
+   status = usb_get_status(udev, USB_RECIP_INTERFACE, 0,
+   devstatus);
+   le16_to_cpus(devstatus

[PATCH v2 2/2] usb: add usb_enable/disable_remote_wakeup()

2013-01-23 Thread Lan Tianyu
usb2.0 and usb3.0 devices have different ways to enalbe/disable
remote wakeup. This patch is to put both their operations into
the seperate functions. Otherwise, usb_control_msg() has some
long arguments and are usually nested some indentations. So
encapsulating it into seperate functions would be convienient
to use and more readable.

Signed-off-by: Lan Tianyu tianyu@intel.com
---
Change since v1:
remove usb_disable_function_remotewakeup() and
call usb_control_msg()  directly in the usb_disable_remote_wakeup()

 drivers/usb/core/hub.c |  136 
 1 file changed, 68 insertions(+), 68 deletions(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 29791a6..4c14b04 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2776,22 +2776,72 @@ void usb_enable_ltm(struct usb_device *udev)
 EXPORT_SYMBOL_GPL(usb_enable_ltm);
 
 #ifdef CONFIG_USB_SUSPEND
-/*
- * usb_disable_function_remotewakeup - disable usb3.0
- * device's function remote wakeup
- * @udev: target device
- *
- * Assume there's only one function on the USB 3.0
- * device and disable remote wake for the first
- * interface. FIXME if the interface association
- * descriptor shows there's more than one function.
- */
-static int usb_disable_function_remotewakeup(struct usb_device *udev)
+static int usb_disable_remote_wakeup(struct usb_device *udev)
 {
-   return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
-   USB_REQ_CLEAR_FEATURE, USB_RECIP_INTERFACE,
-   USB_INTRF_FUNC_SUSPEND, 0, NULL, 0,
+   int status = 0;
+   u16 devstatus;
+
+   if (udev-speed != USB_SPEED_SUPER) {
+   status = usb_get_status(udev, USB_RECIP_DEVICE, 0, devstatus);
+   le16_to_cpus(devstatus);
+   if (!status  devstatus  (1  USB_DEVICE_REMOTE_WAKEUP))
+   status = usb_control_msg(udev,
+   usb_sndctrlpipe(udev, 0),
+   USB_REQ_CLEAR_FEATURE,
+   USB_RECIP_DEVICE,
+   USB_DEVICE_REMOTE_WAKEUP, 0,
+   NULL, 0,
+   USB_CTRL_SET_TIMEOUT);
+   } else {
+   /*
+* Assume there's only one function on the USB 3.0
+* device and disable remote wake for the first
+* interface. FIXME if the interface association
+* descriptor shows there's more than one function.
+*/
+   status = usb_get_status(udev, USB_RECIP_INTERFACE, 0,
+   devstatus);
+   le16_to_cpus(devstatus);
+   if (!status  devstatus 
+ (USB_INTRF_STAT_FUNC_RW_CAP | USB_INTRF_STAT_FUNC_RW))
+   status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+   USB_REQ_CLEAR_FEATURE,
+   USB_RECIP_INTERFACE,
+   USB_INTRF_FUNC_SUSPEND, 0,
+   NULL, 0,
+   USB_CTRL_SET_TIMEOUT);
+   }
+
+   return status;
+}
+
+static int usb_enable_remote_wakeup(struct usb_device *udev)
+{
+   int status;
+
+   if (udev-speed != USB_SPEED_SUPER) {
+   status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+   USB_REQ_SET_FEATURE, USB_RECIP_DEVICE,
+   USB_DEVICE_REMOTE_WAKEUP, 0,
+   NULL, 0,
+   USB_CTRL_SET_TIMEOUT);
+   } else {
+   /* Assume there's only one function on the USB 3.0
+* device and enable remote wake for the first
+* interface. FIXME if the interface association
+* descriptor shows there's more than one function.
+*/
+   status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+   USB_REQ_SET_FEATURE,
+   USB_RECIP_INTERFACE,
+   USB_INTRF_FUNC_SUSPEND,
+   USB_INTRF_FUNC_SUSPEND_RW |
+   USB_INTRF_FUNC_SUSPEND_LP,
+   NULL, 0,
USB_CTRL_SET_TIMEOUT);
+   }
+
+   return status;
 }
 
 /*
@@ -2853,27 +2903,7 @@ int usb_port_suspend(struct usb_device *udev, 
pm_message_t msg)
 * we don't explicitly enable it here.
 */
if (udev-do_remote_wakeup) {
-   if (!hub_is_superspeed(hub-hdev)) {
-   status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
-   USB_REQ_SET_FEATURE, USB_RECIP_DEVICE

Re: [PATCH v6 6/8] usb: expose usb port's pm qos flags to user space

2013-01-22 Thread Lan Tianyu

On 2013/1/22 5:31, Greg KH wrote:

On Mon, Jan 21, 2013 at 10:18:05PM +0800, Lan Tianyu wrote:

This patch is to expose usb port's pm qos flags(pm_qos_no_power_off,
pm_qos_remote_wakeup) to user space. User can set pm_qos_no_power_off
flag to prohibit the port from being powered off.


How are they now seen by userspace?  Should a new Documentation/ABI
entry be created somewhere describing this?
There are already some descriptors in the 
Documentation/ABI/testing/sysfs-devices-power(line 208, lin223).


thanks,

greg k-h




--
Best Regards
Tianyu Lan
linux kernel enabling team
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v6 7/8] usb: add usb_device_allow_power_off() and usb_device_prevent_power_off() function.

2013-01-22 Thread Lan Tianyu

On 2013/1/22 5:33, Greg KH wrote:

On Mon, Jan 21, 2013 at 10:18:06PM +0800, Lan Tianyu wrote:

Some usb devices can't be resumed correctly after power off. This
patch is to add usb_device_allow_power_off() and usb_device_prevent_power_off()
for device's driver. Call pm_runtime_get_sync(portdev) to increase port's usage
count and then port will not be suspended. The device will not be powered off.


Please linewrap comments at the proper level (git likes 72).



Acked-by: Alan Stern st...@rowland.harvard.edu
Signed-off-by: Lan Tianyu tianyu@intel.com
---
  drivers/usb/core/port.c |   28 
  1 file changed, 28 insertions(+)

diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 0c51d24..0334d91 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -18,11 +18,39 @@

  #include linux/slab.h
  #include linux/pm_qos.h
+#include linux/module.h

  #include hub.h

  static const struct attribute_group *port_dev_group[];

+/**
+ * usb_device_control_power_off - Allow or prohibit power off device.
+ * @udev: target usb device
+ * @allow: choice of allow or prohibit
+ *
+ * Call pm_runtime_get/put_sync(portdev) to allow or prohibit target
+ * usb device to be powered off in the kernel. The operations of setting
+ * true and false should be couple. The default status is allowed.
+ */
+int usb_device_control_power_off(struct usb_device *udev, bool allow)


Ick, again with the boolean variables.  Please don't do this, just make
two different functions:
usb_device_allow_power_off()
usb_device_forbid_power_off()
that makes it much easier to understand when you see the function being
called, right?

Ok. I will do it.


thanks,

greg k-h




--
Best Regards
Tianyu Lan
linux kernel enabling team
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v6 7/8] usb: add usb_device_allow_power_off() and usb_device_prevent_power_off() function.

2013-01-22 Thread Lan Tianyu

On 2013/1/22 5:33, Greg KH wrote:

On Mon, Jan 21, 2013 at 10:18:06PM +0800, Lan Tianyu wrote:

Some usb devices can't be resumed correctly after power off. This
patch is to add usb_device_allow_power_off() and usb_device_prevent_power_off()
for device's driver. Call pm_runtime_get_sync(portdev) to increase port's usage
count and then port will not be suspended. The device will not be powered off.

Acked-by: Alan Stern st...@rowland.harvard.edu
Signed-off-by: Lan Tianyu tianyu@intel.com
---
  drivers/usb/core/port.c |   28 
  1 file changed, 28 insertions(+)

diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 0c51d24..0334d91 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -18,11 +18,39 @@

  #include linux/slab.h
  #include linux/pm_qos.h
+#include linux/module.h

  #include hub.h

  static const struct attribute_group *port_dev_group[];

+/**
+ * usb_device_control_power_off - Allow or prohibit power off device.
+ * @udev: target usb device
+ * @allow: choice of allow or prohibit
+ *
+ * Call pm_runtime_get/put_sync(portdev) to allow or prohibit target
+ * usb device to be powered off in the kernel. The operations of setting
+ * true and false should be couple. The default status is allowed.
+ */
+int usb_device_control_power_off(struct usb_device *udev, bool allow)
+{
+   struct usb_port *port_dev;
+
+   if (!udev-parent)
+   return -EINVAL;
+
+   port_dev = hdev_to_hub(udev-parent)-ports[udev-portnum - 1];
+
+   if (allow)
+   pm_runtime_put_sync(port_dev-dev);
+   else
+   pm_runtime_get_sync(port_dev-dev);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(usb_device_control_power_off);


Oh, I don't see any code calling this function, so why did you add it?

Who needs it?  Where is that code?
This is provided for device driver. Some device may not be compatible 
with the power off mechanism and driver can use these function to 
forbid/allow it. But currently, we are not sure which kinds of device

they are. So just provide new interfaces.


thanks,

greg k-h




--
Best Regards
Tianyu Lan
linux kernel enabling team
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v6 8/8] usb: enable usb port device's async suspend.

2013-01-22 Thread Lan Tianyu

On 2013/1/22 5:34, Greg KH wrote:

On Mon, Jan 21, 2013 at 10:18:07PM +0800, Lan Tianyu wrote:

Signed-off-by: Lan Tianyu tianyu@intel.com


Why are you doing this?  Why is it now ok?

We need a much better changelog entry here.

Ok. I will add later.


thanks,

greg k-h




--
Best Regards
Tianyu Lan
linux kernel enabling team
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v6 5/8] usb: add usb port auto power off mechanism

2013-01-22 Thread Lan Tianyu

On 2013/1/22 5:30, Greg KH wrote:

On Mon, Jan 21, 2013 at 10:18:04PM +0800, Lan Tianyu wrote:

This patch is to add usb port auto power off mechanism.
When usb device is suspending, usb core will suspend usb port and
usb port runtime pm callback will clear PORT_POWER feature to
power off port if all conditions were met. These conditions are
remote wakeup disable, pm qos NO_POWER_OFF flag clear and persist
enable. When it resumes, power on port again. Add did_runtime_put
in the struct usb_port in order to call pm_runtime_get/put(portdev)
paired during suspending and resuming.


I don't understand what did_runtime_put is supposed to mean.  Care to
explain this better?

Ok.




Acked-by: Alan Stern st...@rowland.harvard.edu
Acked-by: Rafael J. Wysocki rafael.j.wyso...@intel.com
Signed-off-by: Lan Tianyu tianyu@intel.com
---
  drivers/usb/core/hub.c  |   67 ---
  drivers/usb/core/hub.h  |9 +++
  drivers/usb/core/port.c |   40 ++--
  3 files changed, 105 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 8c1f9a5..786db99 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -26,6 +26,7 @@
  #include linux/mutex.h
  #include linux/freezer.h
  #include linux/random.h
+#include linux/pm_qos.h

  #include asm/uaccess.h
  #include asm/byteorder.h
@@ -108,7 +109,7 @@ MODULE_PARM_DESC(use_both_schemes,
  DECLARE_RWSEM(ehci_cf_port_reset_rwsem);
  EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem);

-#define HUB_DEBOUNCE_TIMEOUT   1500
+#define HUB_DEBOUNCE_TIMEOUT   2000


Why did you increase this timeout?  You don't mention that above in the
changelog entry.

I will add this into change log.



  #define HUB_DEBOUNCE_STEP   25
  #define HUB_DEBOUNCE_STABLE100

@@ -127,7 +128,7 @@ static inline char *portspeed(struct usb_hub *hub, int 
portstatus)
  }

  /* Note that hdev or one of its children must be locked! */
-static struct usb_hub *hdev_to_hub(struct usb_device *hdev)
+struct usb_hub *hdev_to_hub(struct usb_device *hdev)


This needs a better name now that this is a global function.  No one
knows what a hdev is.
Actually the routine will only be used in the driver/usb/core/(hub.c, 
port.c). Port also should be the part of hub, right? Moving port related 
code to port.c is to make code more clear. I am not sure whether we 
should rename it.


If we renamed it, how about usb_hub_to_struct_hub? \
Should we do rename operation in a separate patch since hdev_to_hub() is 
called many places in the hub.c?





  {
if (!hdev || !hdev-actconfig || !hdev-maxchild)
return NULL;
@@ -393,7 +394,7 @@ static int clear_hub_feature(struct usb_device *hdev, int 
feature)
  /*
   * USB 2.0 spec Section 11.24.2.2
   */
-static int clear_port_feature(struct usb_device *hdev, int port1, int feature)
+int clear_port_feature(struct usb_device *hdev, int port1, int feature)


This is now a global function, please put usb_ infront of it.


Same above?

  {
return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port1,
@@ -718,11 +719,16 @@ int usb_hub_set_port_power(struct usb_device *hdev, int 
port1,
bool set)
  {
int ret;
+   struct usb_hub *hub = hdev_to_hub(hdev);
+   struct usb_port *port_dev = hub-ports[port1 - 1];

if (set)
ret = set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
else
ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
+
+   if (!ret)
+   port_dev-power_is_on = set;
return ret;
  }

@@ -802,7 +808,11 @@ static unsigned hub_power_on(struct usb_hub *hub, bool 
do_delay)
dev_dbg(hub-intfdev, trying to enable port power on 
non-switchable hub\n);
for (port1 = 1; port1 = hub-descriptor-bNbrPorts; port1++)
-   set_port_feature(hub-hdev, port1, USB_PORT_FEAT_POWER);
+   if (hub-ports[port1 - 1]-power_is_on)
+   set_port_feature(hub-hdev, port1, USB_PORT_FEAT_POWER);
+   else
+   clear_port_feature(hub-hdev, port1,
+   USB_PORT_FEAT_POWER);

/* Wait at least 100 msec for power to become stable */
delay = max(pgood_delay, (unsigned) 100);
@@ -1134,10 +1144,16 @@ static void hub_activate(struct usb_hub *hub, enum 
hub_activation_type type)
set_bit(port1, hub-change_bits);

} else if (udev-persist_enabled) {
+   struct usb_port *port_dev = hub-ports[port1 - 1];
+
  #ifdef CONFIG_PM
udev-reset_resume = 1;
  #endif
-   set_bit(port1, hub-change_bits);
+   /* Don't set the change_bits when the device
+* was powered off

Re: [PATCH v6 7/8] usb: add usb_device_allow_power_off() and usb_device_prevent_power_off() function.

2013-01-22 Thread Lan Tianyu

On 2013/1/22 23:05, Greg KH wrote:

On Tue, Jan 22, 2013 at 10:23:12PM +0800, Lan Tianyu wrote:

On 2013/1/22 5:33, Greg KH wrote:

On Mon, Jan 21, 2013 at 10:18:06PM +0800, Lan Tianyu wrote:

Some usb devices can't be resumed correctly after power off. This
patch is to add usb_device_allow_power_off() and usb_device_prevent_power_off()
for device's driver. Call pm_runtime_get_sync(portdev) to increase port's usage
count and then port will not be suspended. The device will not be powered off.

Acked-by: Alan Stern st...@rowland.harvard.edu
Signed-off-by: Lan Tianyu tianyu@intel.com
---
  drivers/usb/core/port.c |   28 
  1 file changed, 28 insertions(+)

diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 0c51d24..0334d91 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -18,11 +18,39 @@

  #include linux/slab.h
  #include linux/pm_qos.h
+#include linux/module.h

  #include hub.h

  static const struct attribute_group *port_dev_group[];

+/**
+ * usb_device_control_power_off - Allow or prohibit power off device.
+ * @udev: target usb device
+ * @allow: choice of allow or prohibit
+ *
+ * Call pm_runtime_get/put_sync(portdev) to allow or prohibit target
+ * usb device to be powered off in the kernel. The operations of setting
+ * true and false should be couple. The default status is allowed.
+ */
+int usb_device_control_power_off(struct usb_device *udev, bool allow)
+{
+   struct usb_port *port_dev;
+
+   if (!udev-parent)
+   return -EINVAL;
+
+   port_dev = hdev_to_hub(udev-parent)-ports[udev-portnum - 1];
+
+   if (allow)
+   pm_runtime_put_sync(port_dev-dev);
+   else
+   pm_runtime_get_sync(port_dev-dev);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(usb_device_control_power_off);


Oh, I don't see any code calling this function, so why did you add it?

Who needs it?  Where is that code?

This is provided for device driver. Some device may not be
compatible with the power off mechanism and driver can use these
function to forbid/allow it. But currently, we are not sure which
kinds of device
they are. So just provide new interfaces.


We don't add new interfaces to the kernel unless they have a user.  If I
were to see this in the tree, I would expect it to be removed because of
that.  So don't add it at all, only add it when it is needed.

Ok. I will add it later when I find such device.


thanks,

greg k-h




--
Best Regards
Tianyu Lan
linux kernel enabling team
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v6 5/8] usb: add usb port auto power off mechanism

2013-01-22 Thread Lan Tianyu

On 2013/1/23 0:02, Greg KH wrote:

On Tue, Jan 22, 2013 at 11:32:13PM +0800, Lan Tianyu wrote:

On 2013/1/22 5:30, Greg KH wrote:

On Mon, Jan 21, 2013 at 10:18:04PM +0800, Lan Tianyu wrote:

@@ -127,7 +128,7 @@ static inline char *portspeed(struct usb_hub *hub, int 
portstatus)
  }

  /* Note that hdev or one of its children must be locked! */
-static struct usb_hub *hdev_to_hub(struct usb_device *hdev)
+struct usb_hub *hdev_to_hub(struct usb_device *hdev)


This needs a better name now that this is a global function.  No one
knows what a hdev is.

Actually the routine will only be used in the
driver/usb/core/(hub.c, port.c). Port also should be the part of
hub, right? Moving port related code to port.c is to make code more
clear. I am not sure whether we should rename it.


It is now a global symbol in the kernel name space, so yes, it should be
renamed.


If we renamed it, how about usb_hub_to_struct_hub? \
Should we do rename operation in a separate patch since
hdev_to_hub() is called many places in the hub.c?


That's fine with me.


  {
if (!hdev || !hdev-actconfig || !hdev-maxchild)
return NULL;
@@ -393,7 +394,7 @@ static int clear_hub_feature(struct usb_device *hdev, int 
feature)
  /*
   * USB 2.0 spec Section 11.24.2.2
   */
-static int clear_port_feature(struct usb_device *hdev, int port1, int feature)
+int clear_port_feature(struct usb_device *hdev, int port1, int feature)


This is now a global function, please put usb_ infront of it.


Same above?


Yes.


-static int hub_port_debounce(struct usb_hub *hub, int port1)
+int hub_port_debounce(struct usb_hub *hub, int port1, bool must_be_connected)


I hate boolean flags in functions that do different things depending on
the value.  Can you just make two different functions here, and have
them call this private one with the proper flag set?

Sorry. I am not very sure I understand correctly.
Do you mean to create two wraps which call hub_port_debounce()?
Just like
hub_port_debounce_be_counted()
{
hub_port_debounce(...,..., true);
}

hub_port_debounce_be_counted()
{
hub_port_debounce(...,..., false);
}


If you name the functions differently, yes :)


@@ -3758,7 +3805,9 @@ static int hub_port_debounce(struct usb_hub *hub, int 
port1)

if (!(portchange  USB_PORT_STAT_C_CONNECTION) 
 (portstatus  USB_PORT_STAT_CONNECTION) == connection) {
-   stable_time += HUB_DEBOUNCE_STEP;
+   if (!must_be_connected || (connection
+   == USB_PORT_STAT_CONNECTION))


Please do:
if (!must_be_connected ||
(connection == USB_PORT_STAT_CONNECTION))

instead, that makes it much more readable.

Oh. I originally do the same thing. But there is following code
which requires this line to be more indention. This will cause this
line over 80 characters. So I had to break this line.


The above line, as written is under 80 characters, so I don't understand
the issue.

If I do following, scripts/checkpatch.pl will complain over 80 characters.

@@ -3767,7 +3814,9 @@

if (!(portchange  USB_PORT_STAT_C_CONNECTION) 
 (portstatus  USB_PORT_STAT_CONNECTION) == connection) {
-   stable_time += HUB_DEBOUNCE_STEP;
+   if (!must_be_connected ||
+   (connection == 
USB_PORT_STAT_CONNECTION))
+   stable_time += HUB_DEBOUNCE_STEP;
if (stable_time = HUB_DEBOUNCE_STABLE)
break;
} else {

WARNING: line over 80 characters
#203: FILE: drivers/usb/core/hub.c:3818:
+   (connection == 
USB_PORT_STAT_CONNECTION))

If I use (connection  USB_PORT_STAT_CONNECTION)), that will be ok.
I am curious about that checkpatch.pl considers a space or tab as a character?





I finally find that if I just do following, it also can work.
if (!must_be_connected || connection)
stable_time += HUB_DEBOUNCE_STEP;
Does this make sense? Since connection only will be assigned to the
result of  portstatus  USB_PORT_STAT_CONNECTION.


Connection is an enumerated type, please be explicit when testing it.

thanks,

greg k-h



--
Best Regards
Tianyu Lan
linux kernel enabling team
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v6 5/8] usb: add usb port auto power off mechanism

2013-01-22 Thread Lan Tianyu

On 2013/1/23 1:18, Greg KH wrote:

On Wed, Jan 23, 2013 at 12:58:09AM +0800, Lan Tianyu wrote

The above line, as written is under 80 characters, so I don't understand
the issue.

If I do following, scripts/checkpatch.pl will complain over 80 characters.

@@ -3767,7 +3814,9 @@

 if (!(portchange  USB_PORT_STAT_C_CONNECTION) 
  (portstatus  USB_PORT_STAT_CONNECTION) == connection) {
-   stable_time += HUB_DEBOUNCE_STEP;
+   if (!must_be_connected ||
+   (connection == 
USB_PORT_STAT_CONNECTION))
+   stable_time += HUB_DEBOUNCE_STEP;
 if (stable_time = HUB_DEBOUNCE_STABLE)
 break;
 } else {

WARNING: line over 80 characters
#203: FILE: drivers/usb/core/hub.c:3818:
+   (connection == 
USB_PORT_STAT_CONNECTION))


Of course, which is why I didn't say to do that :)

See above for where to line up the line with the previous one, showing
that it all can fit just fine within 80 characters.


Ok. I get it. learn one more trick. :)

Now I have two solutions. Which one do you think more readable?
@@ -3740,7 +3814,9 @@ static int hub_port_debounce(struct usb_hub *hub, int 
port1)

if (!(portchange  USB_PORT_STAT_C_CONNECTION) 
 (portstatus  USB_PORT_STAT_CONNECTION) == connection) {
-   stable_time += HUB_DEBOUNCE_STEP;
+   if (!must_be_connected ||
+   (connection  USB_PORT_STAT_CONNECTION))
+   stable_time += HUB_DEBOUNCE_STEP;
if (stable_time = HUB_DEBOUNCE_STABLE)
break;


@@ -3740,7 +3814,9 @@ static int hub_port_debounce(struct usb_hub *hub, int 
port1)

if (!(portchange  USB_PORT_STAT_C_CONNECTION) 
 (portstatus  USB_PORT_STAT_CONNECTION) == connection) {
-   stable_time += HUB_DEBOUNCE_STEP;
+   if (!must_be_connected ||
+(connection == USB_PORT_STAT_CONNECTION))
+   stable_time += HUB_DEBOUNCE_STEP;
if (stable_time = HUB_DEBOUNCE_STABLE)









If I use (connection  USB_PORT_STAT_CONNECTION)), that will be ok.
I am curious about that checkpatch.pl considers a space or tab as a character?


It understands the difference between tabs and spaces properly.

thanks,

greg k-h



--
Best Regards
Tianyu Lan
linux kernel enabling team
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V7 0/6] usb: usb port power off mechanism

2013-01-22 Thread Lan Tianyu
Change since v1:
   optimize the export connect type patch and adjust the DeviceRemovalbe 
flag
in the rh_call_control() after GetHubDescriptor request being processed.
   move all debounce operation to usb port's runtime resume callback(). Add
did_runtime_put in the struct usb_port to call pm_runtime_get/put(portdev) 
paired.
   using pm_runtime_get/put(portdev) to allow or prohibit device to be power
off inside of pm qos request in the kernel side. 

Change since v2:
   Correct some link breaks. 
   Add did_runtime_put in the usb_disconnect() before calling 
pm_runtime_put(portdev).
   Provide two seperate functions usb_device_allow_power_off() and 
usb_device_prevent_power_off()
instead of just one.

Change since v3:
Set did_runtime_put to false in usb_disconnect() when its value is true
Add comment about not enable port runtime pm if fail to expose port's 
pm qos. and call
pm_runtime_set_active(portdev) unconditionally.
rename usb_device_allow_prevent_power_off with 
usb_device_control_power_off
Modify be power off to be powered off
Expose dev_pm_qos_flags() symbol in order to ensure usb core can 
compile as module. 

Resend v4:
make patch PM/Qos: Expose dev_pm_qos_flags symbol as first patch to 
avoid compilation error during git bisect
correct some comments.

Change since v4:
use EXPORT_SYMBOL_GPL to export dev_pm_qos_flags().
correct some unnecessary link breaks.   
Add CONFIG_USB_SUSPEND check around usb_port_runtime_resume() and 
usb_port_runtime_suspend()

Change since v5:
predefine struct usb_hub_descriptor in the /driver/usb/core/usb.h 
instead of including linux/usb/ch11.h
move patch PM/Qos: Expose dev_pm_qos_flags symbol before patch usb: 
add runtime pm support for usb port device
 where dev_pm_qos_flags() fistly is called.

Change since v6:
Patch 1: add usb_acpi_register_power_resources() error handle. If there 
was acpi power resource for usb port and
register failed, produce a warning.
Patch 3: add kerneldoc for usb_hub_set_port_power()
Patch 4: add more detail change logs. Make clear_port_feature() and 
hdev_to_hub() as global symbol.
Extend hub_port_debounce() and add two wraps to call it. Change 
soeme indention.
Patch 6: add changelog

This patchset is based on usb-next tree commit d2123fd USB: Set usb port's 
DeviceRemovable according acpi information
 

This patchset is to add usb port power off mechanism and
merge with patchset usb: expose DeviceRemovable to user space via sysfs 
attribute.

Patchset usb: expose DeviceRemovable to user space via sysfs attribute.
http://marc.info/?l=linux-usbm=135279430410171w=2 with some link break 
corrects

The main discussion about usb port power off mechanism is in the following link:
http://marc.info/?l=linux-usbm=134818340017208w=2

usb: Register usb port's acpi power resources
PM/Qos: Expose dev_pm_qos_flags symbol
usb: add runtime pm support for usb port device
usb: add usb port auto power off mechanism
usb: expose usb port's pm qos flags to user space
usb: enable usb port device's async suspend.
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v7 1/6] usb: Register usb port's acpi power resources

2013-01-22 Thread Lan Tianyu
This patch is to register usb port's acpi power resources. Create
link between usb port device and its acpi power resource.

Acked-by: Alan Stern st...@rowland.harvard.edu
Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/port.c |5 +
 drivers/usb/core/usb-acpi.c |   18 ++
 drivers/usb/core/usb.h  |6 ++
 3 files changed, 29 insertions(+)

diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index fe5959f..153e799 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -66,6 +66,7 @@ static void usb_port_device_release(struct device *dev)
 {
struct usb_port *port_dev = to_usb_port(dev);
 
+   usb_acpi_unregister_power_resources(dev);
kfree(port_dev);
 }
 
@@ -95,6 +96,10 @@ int usb_hub_create_port_device(struct usb_hub *hub, int 
port1)
if (retval)
goto error_register;
 
+   retval = usb_acpi_register_power_resources(port_dev-dev);
+   if (retval  retval != -ENODEV)
+   dev_warn(port_dev-dev, the port can't register its ACPI 
power resource.\n);
+
return 0;
 
 error_register:
diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
index cef4252..8d304b0 100644
--- a/drivers/usb/core/usb-acpi.c
+++ b/drivers/usb/core/usb-acpi.c
@@ -216,6 +216,24 @@ static struct acpi_bus_type usb_acpi_bus = {
.find_device = usb_acpi_find_device,
 };
 
+int usb_acpi_register_power_resources(struct device *dev)
+{
+   acpi_handle port_handle = DEVICE_ACPI_HANDLE(dev);
+
+   if (!port_handle)
+   return -ENODEV;
+
+   return acpi_power_resource_register_device(dev, port_handle);
+}
+
+void usb_acpi_unregister_power_resources(struct device *dev)
+{
+   acpi_handle port_handle = DEVICE_ACPI_HANDLE(dev);
+
+   if (port_handle)
+   acpi_power_resource_unregister_device(dev, port_handle);
+}
+
 int usb_acpi_register(void)
 {
return register_acpi_bus_type(usb_acpi_bus);
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index a7f20bd..601b044 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -191,7 +191,13 @@ extern int usb_acpi_register(void);
 extern void usb_acpi_unregister(void);
 extern acpi_handle usb_get_hub_port_acpi_handle(struct usb_device *hdev,
int port1);
+extern int usb_acpi_register_power_resources(struct device *dev);
+extern void usb_acpi_unregister_power_resources(struct device *dev);
 #else
 static inline int usb_acpi_register(void) { return 0; };
 static inline void usb_acpi_unregister(void) { };
+static inline int usb_acpi_register_power_resources(struct device *dev)
+   { return 0; };
+static inline void usb_acpi_unregister_power_resources(struct device *dev)
+   { };
 #endif
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v7 2/6] PM/Qos: Expose dev_pm_qos_flags symbol

2013-01-22 Thread Lan Tianyu
The dev_pm_qos_flags() will be used in the usb core which could be
compiled as a module. This patch is to export it.

Acked-by: Alan Stern st...@rowland.harvard.edu
Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/base/power/qos.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c
index d213495..3d4d1f8 100644
--- a/drivers/base/power/qos.c
+++ b/drivers/base/power/qos.c
@@ -91,6 +91,7 @@ enum pm_qos_flags_status dev_pm_qos_flags(struct device *dev, 
s32 mask)
 
return ret;
 }
+EXPORT_SYMBOL_GPL(dev_pm_qos_flags);
 
 /**
  * __dev_pm_qos_read_value - Get PM QoS constraint for a given device.
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v7 3/6] usb: add runtime pm support for usb port device

2013-01-22 Thread Lan Tianyu
This patch is to add runtime pm callback for usb port device.
Set/clear PORT_POWER feature in the resume/suspend callback.
Add portnum for struct usb_port to record port number. Do
pm_rumtime_get_sync/put(portdev) when a device is plugged/unplugged
to prevent it from being powered off when it is active.

Acked-by: Alan Stern st...@rowland.harvard.edu
Acked-by: Rafael J. Wysocki rafael.j.wyso...@intel.com
Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/hub.c  |   27 +++
 drivers/usb/core/hub.h  |4 
 drivers/usb/core/port.c |   46 ++
 3 files changed, 77 insertions(+)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 29ca6ed..7fb1633 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -715,6 +715,27 @@ static void hub_tt_work(struct work_struct *work)
 }
 
 /**
+ * usb_hub_set_port_power - control hub port's power state
+ * @hdev: target hub
+ * @port1: port index
+ * @set: expected status
+ *
+ * call this function to control port's power via setting or
+ * clearing the port's PORT_POWER feature.
+ */
+int usb_hub_set_port_power(struct usb_device *hdev, int port1,
+   bool set)
+{
+   int ret;
+
+   if (set)
+   ret = set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
+   else
+   ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
+   return ret;
+}
+
+/**
  * usb_hub_clear_tt_buffer - clear control/bulk TT state in high speed hub
  * @urb: an URB associated with the failed or incomplete split transaction
  *
@@ -1569,6 +1590,7 @@ static void hub_disconnect(struct usb_interface *intf)
kfree(hub-status);
kfree(hub-buffer);
 
+   pm_suspend_ignore_children(intf-dev, false);
kref_put(hub-kref, hub_release);
 }
 
@@ -1671,6 +1693,7 @@ descriptor_error:
 
usb_set_intfdata (intf, hub);
intf-needs_remote_wakeup = 1;
+   pm_suspend_ignore_children(intf-dev, true);
 
if (hdev-speed == USB_SPEED_HIGH)
highspeed_hubs++;
@@ -1997,6 +2020,8 @@ void usb_disconnect(struct usb_device **pdev)
 
sysfs_remove_link(udev-dev.kobj, port);
sysfs_remove_link(port_dev-dev.kobj, device);
+
+   pm_runtime_put(port_dev-dev);
}
 
usb_remove_ep_devs(udev-ep0);
@@ -2307,6 +2332,8 @@ int usb_new_device(struct usb_device *udev)
sysfs_remove_link(udev-dev.kobj, port);
goto fail;
}
+
+   pm_runtime_get_sync(port_dev-dev);
}
 
(void) usb_create_ep_devs(udev-dev, udev-ep0, udev);
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
index d16a7c9..8ea6bc8 100644
--- a/drivers/usb/core/hub.h
+++ b/drivers/usb/core/hub.h
@@ -79,12 +79,14 @@ struct usb_hub {
  * @dev: generic device interface
  * @port_owner: port's owner
  * @connect_type: port's connect type
+ * @portnum: port index num based one
  */
 struct usb_port {
struct usb_device *child;
struct device dev;
struct dev_state *port_owner;
enum usb_port_connect_type connect_type;
+   u8 portnum;
 };
 
 #define to_usb_port(_dev) \
@@ -94,4 +96,6 @@ extern int usb_hub_create_port_device(struct usb_hub *hub,
int port1);
 extern void usb_hub_remove_port_device(struct usb_hub *hub,
int port1);
+extern int usb_hub_set_port_power(struct usb_device *hdev,
+   int port1, bool set);
 
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 153e799..169c89e 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -17,6 +17,7 @@
  */
 
 #include linux/slab.h
+#include linux/pm_qos.h
 
 #include hub.h
 
@@ -70,9 +71,50 @@ static void usb_port_device_release(struct device *dev)
kfree(port_dev);
 }
 
+#ifdef CONFIG_USB_SUSPEND
+static int usb_port_runtime_resume(struct device *dev)
+{
+   struct usb_port *port_dev = to_usb_port(dev);
+   struct usb_device *hdev = to_usb_device(dev-parent-parent);
+   struct usb_interface *intf = to_usb_interface(dev-parent);
+   int retval;
+
+   usb_autopm_get_interface(intf);
+   retval = usb_hub_set_port_power(hdev, port_dev-portnum, true);
+   usb_autopm_put_interface(intf);
+   return retval;
+}
+
+static int usb_port_runtime_suspend(struct device *dev)
+{
+   struct usb_port *port_dev = to_usb_port(dev);
+   struct usb_device *hdev = to_usb_device(dev-parent-parent);
+   struct usb_interface *intf = to_usb_interface(dev-parent);
+   int retval;
+
+   if (dev_pm_qos_flags(port_dev-dev, PM_QOS_FLAG_NO_POWER_OFF)
+   == PM_QOS_FLAGS_ALL)
+   return -EAGAIN;
+
+   usb_autopm_get_interface(intf);
+   retval = usb_hub_set_port_power(hdev, port_dev-portnum, false);
+   usb_autopm_put_interface(intf);
+   return retval;
+}
+#endif
+
+static const

[PATCH v7 5/6] usb: expose usb port's pm qos flags to user space

2013-01-22 Thread Lan Tianyu
This patch is to expose usb port's pm qos flags(pm_qos_no_power_off,
pm_qos_remote_wakeup) to user space. User can set pm_qos_no_power_off
flag to prohibit the port from being powered off.

Acked-by: Alan Stern st...@rowland.harvard.edu
Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/port.c |   11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 36003e0..968dd41 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -67,6 +67,7 @@ static void usb_port_device_release(struct device *dev)
 {
struct usb_port *port_dev = to_usb_port(dev);
 
+   dev_pm_qos_hide_flags(dev);
usb_acpi_unregister_power_resources(dev);
kfree(port_dev);
 }
@@ -176,7 +177,15 @@ int usb_hub_create_port_device(struct usb_hub *hub, int 
port1)
goto error_register;
 
pm_runtime_set_active(port_dev-dev);
-   pm_runtime_enable(port_dev-dev);
+
+   /* It would be dangerous if user space couldn't
+* prevent usb device from being powered off. So don't
+* enable port runtime pm if failed to expose port's pm qos.
+*/
+   if (!dev_pm_qos_expose_flags(port_dev-dev,
+   PM_QOS_FLAG_NO_POWER_OFF))
+   pm_runtime_enable(port_dev-dev);
+
 
retval = usb_acpi_register_power_resources(port_dev-dev);
if (retval  retval != -ENODEV)
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v7 6/6] usb: enable usb port device's async suspend.

2013-01-22 Thread Lan Tianyu
This patch is to set power.async_suspend for usb port in order
to allow it to be suspended and resumed asynchronously during
system sleep transitions.

The power.async_suspend flag is also set for devices that don't have
suspend or resume callbacks, because otherwise they would make the
main suspend/resume thread wait for their asynchronous children
(during suspend) or parents (during resume), effectively negating the
possible gains from executing these devices' suspend and resume
callbacks asynchronously.

Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/port.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 968dd41..0248b88 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -186,6 +186,7 @@ int usb_hub_create_port_device(struct usb_hub *hub, int 
port1)
PM_QOS_FLAG_NO_POWER_OFF))
pm_runtime_enable(port_dev-dev);
 
+   device_enable_async_suspend(port_dev-dev);
 
retval = usb_acpi_register_power_resources(port_dev-dev);
if (retval  retval != -ENODEV)
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v7 4/6] usb: add usb port auto power off mechanism

2013-01-22 Thread Lan Tianyu
This patch is to add usb port auto power off mechanism.
When usb device is suspending, usb core will suspend usb port and
usb port runtime pm callback will clear PORT_POWER feature to
power off port if all conditions were met. These conditions are
remote wakeup disable, pm qos NO_POWER_OFF flag clear and persist
enable. When it resumes, power on port again.

Add did_runtime_put in the struct usb_port to ensure
pm_runtime_get/put(portdev) to be called pairedly.  Set did_runtime_put
to true when call pm_runtime_put(portdev) during suspending. The
pm_runtime_get(portdev) only will be called when did_runtime_put
is set to true during resuming. Set did_runtime_put to false after
calling pm_runtime_get(portdev).

Make clear_port_feature() and hdev_to_hub() as global symbol.
Rename clear_port_feature() to usb_clear_port_feature() and
hdev_to_hub() to usb_hub_to_struct_hub().

Extend hub_port_debounce() with the fuction of debouncing to
be connected. Add two wraps: hub_port_debounce_be_connected()
and hub_port_debouce_be_stable().

Increase HUB_DEBOUNCE_TIMEOUT to 2000 because some usb ssds
needs around 1.5 or more to make the hub port status to be
connected steadily after being powered off and powered on.

Acked-by: Alan Stern st...@rowland.harvard.edu
Acked-by: Rafael J. Wysocki rafael.j.wyso...@intel.com
Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/hub.c  |  161 ++-
 drivers/usb/core/hub.h  |   21 +++
 drivers/usb/core/port.c |   40 +++-
 3 files changed, 164 insertions(+), 58 deletions(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 7fb1633..0883364 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -26,6 +26,7 @@
 #include linux/mutex.h
 #include linux/freezer.h
 #include linux/random.h
+#include linux/pm_qos.h
 
 #include asm/uaccess.h
 #include asm/byteorder.h
@@ -108,7 +109,7 @@ MODULE_PARM_DESC(use_both_schemes,
 DECLARE_RWSEM(ehci_cf_port_reset_rwsem);
 EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem);
 
-#define HUB_DEBOUNCE_TIMEOUT   1500
+#define HUB_DEBOUNCE_TIMEOUT   2000
 #define HUB_DEBOUNCE_STEP25
 #define HUB_DEBOUNCE_STABLE 100
 
@@ -127,7 +128,7 @@ static inline char *portspeed(struct usb_hub *hub, int 
portstatus)
 }
 
 /* Note that hdev or one of its children must be locked! */
-static struct usb_hub *hdev_to_hub(struct usb_device *hdev)
+struct usb_hub *usb_hub_to_struct_hub(struct usb_device *hdev)
 {
if (!hdev || !hdev-actconfig || !hdev-maxchild)
return NULL;
@@ -301,7 +302,7 @@ static void usb_set_lpm_parameters(struct usb_device *udev)
if (!udev-lpm_capable || udev-speed != USB_SPEED_SUPER)
return;
 
-   hub = hdev_to_hub(udev-parent);
+   hub = usb_hub_to_struct_hub(udev-parent);
/* It doesn't take time to transition the roothub into U0, since it
 * doesn't have an upstream link.
 */
@@ -393,7 +394,7 @@ static int clear_hub_feature(struct usb_device *hdev, int 
feature)
 /*
  * USB 2.0 spec Section 11.24.2.2
  */
-static int clear_port_feature(struct usb_device *hdev, int port1, int feature)
+int usb_clear_port_feature(struct usb_device *hdev, int port1, int feature)
 {
return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port1,
@@ -586,7 +587,7 @@ static void kick_khubd(struct usb_hub *hub)
 
 void usb_kick_khubd(struct usb_device *hdev)
 {
-   struct usb_hub *hub = hdev_to_hub(hdev);
+   struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
 
if (hub)
kick_khubd(hub);
@@ -608,7 +609,7 @@ void usb_wakeup_notification(struct usb_device *hdev,
if (!hdev)
return;
 
-   hub = hdev_to_hub(hdev);
+   hub = usb_hub_to_struct_hub(hdev);
if (hub) {
set_bit(portnum, hub-wakeup_bits);
kick_khubd(hub);
@@ -727,11 +728,16 @@ int usb_hub_set_port_power(struct usb_device *hdev, int 
port1,
bool set)
 {
int ret;
+   struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
+   struct usb_port *port_dev = hub-ports[port1 - 1];
 
if (set)
ret = set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
else
-   ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
+   ret = usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
+
+   if (!ret)
+   port_dev-power_is_on = set;
return ret;
 }
 
@@ -811,7 +817,11 @@ static unsigned hub_power_on(struct usb_hub *hub, bool 
do_delay)
dev_dbg(hub-intfdev, trying to enable port power on 
non-switchable hub\n);
for (port1 = 1; port1 = hub-descriptor-bNbrPorts; port1++)
-   set_port_feature(hub-hdev, port1, USB_PORT_FEAT_POWER);
+   if (hub-ports[port1 - 1]-power_is_on

[PATCH V6 0/8] usb: usb port power off mechanism and expose usb port connect type

2013-01-21 Thread Lan Tianyu
Change since v1:
   optimize the export connect type patch and adjust the DeviceRemovalbe 
flag
in the rh_call_control() after GetHubDescriptor request being processed.
   move all debounce operation to usb port's runtime resume callback(). Add
did_runtime_put in the struct usb_port to call pm_runtime_get/put(portdev) 
paired.
   using pm_runtime_get/put(portdev) to allow or prohibit device to be power
off inside of pm qos request in the kernel side. 

Change since v2:
   Correct some link breaks. 
   Add did_runtime_put in the usb_disconnect() before calling 
pm_runtime_put(portdev).
   Provide two seperate functions usb_device_allow_power_off() and 
usb_device_prevent_power_off()
instead of just one.

Change since v3:
Set did_runtime_put to false in usb_disconnect() when its value is true
Add comment about not enable port runtime pm if fail to expose port's 
pm qos. and call
pm_runtime_set_active(portdev) unconditionally.
rename usb_device_allow_prevent_power_off with 
usb_device_control_power_off
Modify be power off to be powered off
Expose dev_pm_qos_flags() symbol in order to ensure usb core can 
compile as module. 

Resend v4:
make patch PM/Qos: Expose dev_pm_qos_flags symbol as first patch to 
avoid compilation error during git bisect
correct some comments.

Change since v4:
use EXPORT_SYMBOL_GPL to export dev_pm_qos_flags().
correct some unnecessary link breaks.   
Add CONFIG_USB_SUSPEND check around usb_port_runtime_resume() and 
usb_port_runtime_suspend()

Change since v5:
predefine struct usb_hub_descriptor in the /driver/usb/core/usb.h 
instead of including linux/usb/ch11.h
move patch PM/Qos: Expose dev_pm_qos_flags symbol before patch usb: 
add runtime pm support for usb port device
 where dev_pm_qos_flags() fistly is called.


This patchset is based on usb-next tree commit f4cc1834 USB: storage: avoid 
scanning other targets for single target device

This patchset is to add usb port power off mechanism and
merge with patchset usb: expose DeviceRemovable to user space via sysfs 
attribute.

Patchset usb: expose DeviceRemovable to user space via sysfs attribute.
http://marc.info/?l=linux-usbm=135279430410171w=2 with some link break 
corrects

The main discussion about usb port power off mechanism is in the following link:
http://marc.info/?l=linux-usbm=134818340017208w=2


USB: Set usb port's DeviceRemovable according acpi information
usb: Register usb port's acpi power resources
PM/Qos: Expose dev_pm_qos_flags symbol
usb: add runtime pm support for usb port device
usb: add usb port auto power off mechanism
usb: expose usb port's pm qos flags to user space
usb: add usb_device_allow_power_off() and usb_device_prevent_power_off() 
function.
usb: enable usb port device's async suspend.
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 1/8] USB: Set usb port's DeviceRemovable according acpi information

2013-01-21 Thread Lan Tianyu
ACPI provide _PLD and _UPC aml methods to describe usb port
visibility and connectability. This patch is to add 
usb_hub_adjust_DeviceRemovable()
to adjust usb hub port's DeviceRemovable according ACPI information and invoke 
it in
the rh_call_control(). When hub descriptor request is issued at first time,
usb port device isn't created and usb port is not bound with acpi. So first
hub descriptor request is not changed based on ACPI information. After usb
port devices being created, call usb_hub_adjust_DeviceRemovable in the 
hub_configure()
and then set hub port's DeviceRemovable according ACPI information and this 
also works
for non-root hub.

Acked-by: Alan Stern st...@rowland.harvard.edu
Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/hcd.c |4 
 drivers/usb/core/hub.c |   43 +++
 drivers/usb/core/usb.h |3 +++
 3 files changed, 50 insertions(+)

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 5f6da8b..2459896 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -619,6 +619,10 @@ nongeneric:
status = hcd-driver-hub_control (hcd,
typeReq, wValue, wIndex,
tbuf, wLength);
+
+   if (typeReq == GetHubDescriptor)
+   usb_hub_adjust_deviceremovable(hcd-self.root_hub,
+   (struct usb_hub_descriptor *)tbuf);
break;
 error:
/* protocol stall on error */
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index cfdd4ee..29ca6ed 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1513,6 +1513,8 @@ static int hub_configure(struct usb_hub *hub,
dev_err(hub-intfdev,
couldn't create port%d device.\n, i + 1);
 
+   usb_hub_adjust_deviceremovable(hdev, hub-descriptor);
+
hub_activate(hub, HUB_INIT);
return 0;
 
@@ -5219,6 +5221,47 @@ usb_get_hub_port_connect_type(struct usb_device *hdev, 
int port1)
return hub-ports[port1 - 1]-connect_type;
 }
 
+void usb_hub_adjust_deviceremovable(struct usb_device *hdev,
+   struct usb_hub_descriptor *desc)
+{
+   enum usb_port_connect_type connect_type;
+   int i;
+
+   if (!hub_is_superspeed(hdev)) {
+   for (i = 1; i = hdev-maxchild; i++) {
+   connect_type = usb_get_hub_port_connect_type(hdev, i);
+
+   if (connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) {
+   u8 mask = 1  (i%8);
+
+   if (!(desc-u.hs.DeviceRemovable[i/8]  mask)) {
+   dev_dbg(hdev-dev, usb port%d's 
DeviceRemovable is changed to 1 according to platform information.\n,
+   i);
+   desc-u.hs.DeviceRemovable[i/8] |= mask;
+   }
+   }
+   }
+   } else {
+   u16 port_removable = le16_to_cpu(desc-u.ss.DeviceRemovable);
+
+   for (i = 1; i = hdev-maxchild; i++) {
+   connect_type = usb_get_hub_port_connect_type(hdev, i);
+
+   if (connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) {
+   u16 mask = 1  i;
+
+   if (!(port_removable  mask)) {
+   dev_dbg(hdev-dev, usb port%d's 
DeviceRemovable is changed to 1 according to platform information.\n,
+   i);
+   port_removable |= mask;
+   }
+   }
+   }
+
+   desc-u.ss.DeviceRemovable = cpu_to_le16(port_removable);
+   }
+}
+
 #ifdef CONFIG_ACPI
 /**
  * usb_get_hub_port_acpi_handle - Get the usb port's acpi handle
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index fb7d8fc..a7f20bd 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -1,6 +1,7 @@
 #include linux/pm.h
 #include linux/acpi.h
 
+struct usb_hub_descriptor;
 struct dev_state;
 
 /* Functions local to drivers/usb/core/ */
@@ -182,6 +183,8 @@ extern enum usb_port_connect_type
usb_get_hub_port_connect_type(struct usb_device *hdev, int port1);
 extern void usb_set_hub_port_connect_type(struct usb_device *hdev, int port1,
enum usb_port_connect_type type);
+extern void usb_hub_adjust_deviceremovable(struct usb_device *hdev,
+   struct usb_hub_descriptor *desc);
 
 #ifdef CONFIG_ACPI
 extern int usb_acpi_register(void);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 2/8] usb: Register usb port's acpi power resources

2013-01-21 Thread Lan Tianyu
This patch is to register usb port's acpi power resources. Create
link between usb port device and its acpi power resource.

Acked-by: Alan Stern st...@rowland.harvard.edu
Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/port.c |3 +++
 drivers/usb/core/usb-acpi.c |   20 
 drivers/usb/core/usb.h  |6 ++
 3 files changed, 29 insertions(+)

diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index fe5959f..4dfa254 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -66,6 +66,7 @@ static void usb_port_device_release(struct device *dev)
 {
struct usb_port *port_dev = to_usb_port(dev);
 
+   usb_acpi_unregister_power_resources(dev);
kfree(port_dev);
 }
 
@@ -95,6 +96,8 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1)
if (retval)
goto error_register;
 
+   usb_acpi_register_power_resources(port_dev-dev);
+
return 0;
 
 error_register:
diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
index cef4252..558ab01 100644
--- a/drivers/usb/core/usb-acpi.c
+++ b/drivers/usb/core/usb-acpi.c
@@ -216,6 +216,26 @@ static struct acpi_bus_type usb_acpi_bus = {
.find_device = usb_acpi_find_device,
 };
 
+int usb_acpi_register_power_resources(struct device *dev)
+{
+   acpi_handle port_handle = DEVICE_ACPI_HANDLE(dev);
+
+   if (!port_handle)
+   return -ENODEV;
+
+   if (acpi_power_resource_register_device(dev, port_handle)  0)
+   return -ENODEV;
+   return 0;
+}
+
+void usb_acpi_unregister_power_resources(struct device *dev)
+{
+   acpi_handle port_handle = DEVICE_ACPI_HANDLE(dev);
+
+   if (port_handle)
+   acpi_power_resource_unregister_device(dev, port_handle);
+}
+
 int usb_acpi_register(void)
 {
return register_acpi_bus_type(usb_acpi_bus);
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index a7f20bd..601b044 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -191,7 +191,13 @@ extern int usb_acpi_register(void);
 extern void usb_acpi_unregister(void);
 extern acpi_handle usb_get_hub_port_acpi_handle(struct usb_device *hdev,
int port1);
+extern int usb_acpi_register_power_resources(struct device *dev);
+extern void usb_acpi_unregister_power_resources(struct device *dev);
 #else
 static inline int usb_acpi_register(void) { return 0; };
 static inline void usb_acpi_unregister(void) { };
+static inline int usb_acpi_register_power_resources(struct device *dev)
+   { return 0; };
+static inline void usb_acpi_unregister_power_resources(struct device *dev)
+   { };
 #endif
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 3/8] PM/Qos: Expose dev_pm_qos_flags symbol

2013-01-21 Thread Lan Tianyu
The dev_pm_qos_flags() will be used in the usb core which could be
compiled as a module. This patch is to export it.

Acked-by: Alan Stern st...@rowland.harvard.edu
Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/base/power/qos.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c
index d213495..3d4d1f8 100644
--- a/drivers/base/power/qos.c
+++ b/drivers/base/power/qos.c
@@ -91,6 +91,7 @@ enum pm_qos_flags_status dev_pm_qos_flags(struct device *dev, 
s32 mask)
 
return ret;
 }
+EXPORT_SYMBOL_GPL(dev_pm_qos_flags);
 
 /**
  * __dev_pm_qos_read_value - Get PM QoS constraint for a given device.
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 4/8] usb: add runtime pm support for usb port device

2013-01-21 Thread Lan Tianyu
This patch is to add runtime pm callback for usb port device.
Set/clear PORT_POWER feature in the resume/suspend callbak.
Add portnum for struct usb_port to record port number. Do
pm_rumtime_get_sync/put(portdev) when a device is plugged/unplugged
to prevent it from being powered off when it is active.

Acked-by: Alan Stern st...@rowland.harvard.edu
Acked-by: Rafael J. Wysocki rafael.j.wyso...@intel.com
Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/hub.c  |   18 ++
 drivers/usb/core/hub.h  |4 
 drivers/usb/core/port.c |   45 +
 3 files changed, 67 insertions(+)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 29ca6ed..8c1f9a5 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -714,6 +714,18 @@ static void hub_tt_work(struct work_struct *work)
spin_unlock_irqrestore (hub-tt.lock, flags);
 }
 
+int usb_hub_set_port_power(struct usb_device *hdev, int port1,
+   bool set)
+{
+   int ret;
+
+   if (set)
+   ret = set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
+   else
+   ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
+   return ret;
+}
+
 /**
  * usb_hub_clear_tt_buffer - clear control/bulk TT state in high speed hub
  * @urb: an URB associated with the failed or incomplete split transaction
@@ -1569,6 +1581,7 @@ static void hub_disconnect(struct usb_interface *intf)
kfree(hub-status);
kfree(hub-buffer);
 
+   pm_suspend_ignore_children(intf-dev, false);
kref_put(hub-kref, hub_release);
 }
 
@@ -1671,6 +1684,7 @@ descriptor_error:
 
usb_set_intfdata (intf, hub);
intf-needs_remote_wakeup = 1;
+   pm_suspend_ignore_children(intf-dev, true);
 
if (hdev-speed == USB_SPEED_HIGH)
highspeed_hubs++;
@@ -1997,6 +2011,8 @@ void usb_disconnect(struct usb_device **pdev)
 
sysfs_remove_link(udev-dev.kobj, port);
sysfs_remove_link(port_dev-dev.kobj, device);
+
+   pm_runtime_put(port_dev-dev);
}
 
usb_remove_ep_devs(udev-ep0);
@@ -2307,6 +2323,8 @@ int usb_new_device(struct usb_device *udev)
sysfs_remove_link(udev-dev.kobj, port);
goto fail;
}
+
+   pm_runtime_get_sync(port_dev-dev);
}
 
(void) usb_create_ep_devs(udev-dev, udev-ep0, udev);
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
index d16a7c9..8ea6bc8 100644
--- a/drivers/usb/core/hub.h
+++ b/drivers/usb/core/hub.h
@@ -79,12 +79,14 @@ struct usb_hub {
  * @dev: generic device interface
  * @port_owner: port's owner
  * @connect_type: port's connect type
+ * @portnum: port index num based one
  */
 struct usb_port {
struct usb_device *child;
struct device dev;
struct dev_state *port_owner;
enum usb_port_connect_type connect_type;
+   u8 portnum;
 };
 
 #define to_usb_port(_dev) \
@@ -94,4 +96,6 @@ extern int usb_hub_create_port_device(struct usb_hub *hub,
int port1);
 extern void usb_hub_remove_port_device(struct usb_hub *hub,
int port1);
+extern int usb_hub_set_port_power(struct usb_device *hdev,
+   int port1, bool set);
 
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 4dfa254..bd08f7e 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -17,6 +17,7 @@
  */
 
 #include linux/slab.h
+#include linux/pm_qos.h
 
 #include hub.h
 
@@ -70,9 +71,50 @@ static void usb_port_device_release(struct device *dev)
kfree(port_dev);
 }
 
+#ifdef CONFIG_USB_SUSPEND
+static int usb_port_runtime_resume(struct device *dev)
+{
+   struct usb_port *port_dev = to_usb_port(dev);
+   struct usb_device *hdev = to_usb_device(dev-parent-parent);
+   struct usb_interface *intf = to_usb_interface(dev-parent);
+   int retval;
+
+   usb_autopm_get_interface(intf);
+   retval = usb_hub_set_port_power(hdev, port_dev-portnum, true);
+   usb_autopm_put_interface(intf);
+   return retval;
+}
+
+static int usb_port_runtime_suspend(struct device *dev)
+{
+   struct usb_port *port_dev = to_usb_port(dev);
+   struct usb_device *hdev = to_usb_device(dev-parent-parent);
+   struct usb_interface *intf = to_usb_interface(dev-parent);
+   int retval;
+
+   if (dev_pm_qos_flags(port_dev-dev, PM_QOS_FLAG_NO_POWER_OFF)
+   == PM_QOS_FLAGS_ALL)
+   return -EAGAIN;
+
+   usb_autopm_get_interface(intf);
+   retval = usb_hub_set_port_power(hdev, port_dev-portnum, false);
+   usb_autopm_put_interface(intf);
+   return retval;
+}
+#endif
+
+static const struct dev_pm_ops usb_port_pm_ops = {
+#ifdef CONFIG_USB_SUSPEND
+   .runtime_suspend =  usb_port_runtime_suspend,
+   .runtime_resume =   usb_port_runtime_resume,
+   .runtime_idle

[PATCH v6 6/8] usb: expose usb port's pm qos flags to user space

2013-01-21 Thread Lan Tianyu
This patch is to expose usb port's pm qos flags(pm_qos_no_power_off,
pm_qos_remote_wakeup) to user space. User can set pm_qos_no_power_off
flag to prohibit the port from being powered off.

Acked-by: Alan Stern st...@rowland.harvard.edu
Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/port.c |   11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index dc1aaec..0c51d24 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -67,6 +67,7 @@ static void usb_port_device_release(struct device *dev)
 {
struct usb_port *port_dev = to_usb_port(dev);
 
+   dev_pm_qos_hide_flags(dev);
usb_acpi_unregister_power_resources(dev);
kfree(port_dev);
 }
@@ -176,7 +177,15 @@ int usb_hub_create_port_device(struct usb_hub *hub, int 
port1)
goto error_register;
 
pm_runtime_set_active(port_dev-dev);
-   pm_runtime_enable(port_dev-dev);
+
+   /* It would be dangerous if user space couldn't
+* prevent usb device from being powered off. So don't
+* enable port runtime pm if failed to expose port's pm qos.
+*/
+   if (!dev_pm_qos_expose_flags(port_dev-dev,
+   PM_QOS_FLAG_NO_POWER_OFF))
+   pm_runtime_enable(port_dev-dev);
+
usb_acpi_register_power_resources(port_dev-dev);
 
return 0;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 8/8] usb: enable usb port device's async suspend.

2013-01-21 Thread Lan Tianyu
Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/port.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 0334d91..50b646e 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -215,7 +215,7 @@ int usb_hub_create_port_device(struct usb_hub *hub, int 
port1)
pm_runtime_enable(port_dev-dev);
 
usb_acpi_register_power_resources(port_dev-dev);
-
+   device_enable_async_suspend(port_dev-dev);
return 0;
 
 error_register:
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v6 2/8] usb: Register usb port's acpi power resources

2013-01-21 Thread Lan Tianyu
Hi Greg:
Great thanks for your review. I learn a lot from your comments which I
have not noticed before.

On 2013年01月22日 05:20, Greg KH wrote:
 On Mon, Jan 21, 2013 at 10:18:01PM +0800, Lan Tianyu wrote:
 This patch is to register usb port's acpi power resources. Create
 link between usb port device and its acpi power resource.

 Acked-by: Alan Stern st...@rowland.harvard.edu
 Signed-off-by: Lan Tianyu tianyu@intel.com
 ---
  drivers/usb/core/port.c |3 +++
  drivers/usb/core/usb-acpi.c |   20 
  drivers/usb/core/usb.h  |6 ++
  3 files changed, 29 insertions(+)

 diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
 index fe5959f..4dfa254 100644
 --- a/drivers/usb/core/port.c
 +++ b/drivers/usb/core/port.c
 @@ -66,6 +66,7 @@ static void usb_port_device_release(struct device *dev)
  {
  struct usb_port *port_dev = to_usb_port(dev);
  
 +usb_acpi_unregister_power_resources(dev);
  kfree(port_dev);
  }
  
 @@ -95,6 +96,8 @@ int usb_hub_create_port_device(struct usb_hub *hub, int 
 port1)
  if (retval)
  goto error_register;
  
 +usb_acpi_register_power_resources(port_dev-dev);
 +
  return 0;
  
  error_register:
 diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
 index cef4252..558ab01 100644
 --- a/drivers/usb/core/usb-acpi.c
 +++ b/drivers/usb/core/usb-acpi.c
 @@ -216,6 +216,26 @@ static struct acpi_bus_type usb_acpi_bus = {
  .find_device = usb_acpi_find_device,
  };
  
 +int usb_acpi_register_power_resources(struct device *dev)
 +{
 +acpi_handle port_handle = DEVICE_ACPI_HANDLE(dev);
 +
 +if (!port_handle)
 +return -ENODEV;
 +
 +if (acpi_power_resource_register_device(dev, port_handle)  0)
 +return -ENODEV;
 +return 0;
 +}
 
 Why return a value if you never check it?  Either properly handle the
 error in the place you call this function, or don't have a return value.
 
 I'd prefer you to handle the error properly.
Not all system will provide acpi power resouces for usb port and this
will not damage usb device function. So I think I should produce some
warning if the return value is not ENODEV.
 
 thanks,
 
 greg k-h
 


-- 
Best regards
Tianyu Lan
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v6 4/8] usb: add runtime pm support for usb port device

2013-01-21 Thread Lan Tianyu
On 2013年01月22日 05:24, Greg KH wrote:
 On Mon, Jan 21, 2013 at 10:18:03PM +0800, Lan Tianyu wrote:
 This patch is to add runtime pm callback for usb port device.
 Set/clear PORT_POWER feature in the resume/suspend callbak.
 Add portnum for struct usb_port to record port number. Do
 pm_rumtime_get_sync/put(portdev) when a device is plugged/unplugged
 to prevent it from being powered off when it is active.

 Acked-by: Alan Stern st...@rowland.harvard.edu
 Acked-by: Rafael J. Wysocki rafael.j.wyso...@intel.com
 Signed-off-by: Lan Tianyu tianyu@intel.com
 ---
  drivers/usb/core/hub.c  |   18 ++
  drivers/usb/core/hub.h  |4 
  drivers/usb/core/port.c |   45 +
  3 files changed, 67 insertions(+)

 diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
 index 29ca6ed..8c1f9a5 100644
 --- a/drivers/usb/core/hub.c
 +++ b/drivers/usb/core/hub.c
 @@ -714,6 +714,18 @@ static void hub_tt_work(struct work_struct *work)
  spin_unlock_irqrestore (hub-tt.lock, flags);
  }
  
 +int usb_hub_set_port_power(struct usb_device *hdev, int port1,
 +bool set)
 
 As this is a new global USB function, please provide the proper
 kerneldoc comments describing what it does.
 
OK. I will add later and actually the function will be only used in the
driver/usb/core/hub.c and port.c.
 thanks,
 
 greg k-h
 


-- 
Best regards
Tianyu Lan
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V5 0/10] usb: usb port power off mechanism and expose usb port connect type

2013-01-20 Thread Lan Tianyu
2013/1/21 Greg KH gre...@linuxfoundation.org

 On Sun, Jan 20, 2013 at 01:53:29AM +0800, Lan Tianyu wrote:
  Change since v5:
use EXPORT_SYMBOL_GPL to export dev_pm_qos_flags().
correct some unnecessary link breaks.
Add CONFIG_USB_SUSPEND check around usb_port_runtime_resume() and
  usb_port_runtime_suspend()

 I've applied a few of these, care to redo the series based on the
 feedback for the .h file issue?
Ok. I wll update soon.

 thanks,

 greg k-h
 --
 To unsubscribe from this list: send the line unsubscribe linux-usb in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html




--
Best regards
Tianyu Lan
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] usb: fix compilation error and warning of driver/usb/core/port.c on arm and blackfin

2013-01-19 Thread Lan Tianyu
This patch is to fix compilation error and warning on the arm and blackfin.
Add linux/slab.h head file to driver/usb/core/port.c. These are reported
from 0-DAY kernel build testing backend.

head:   6e30d7cba992d626c9d16b3873a7b90c700d0e95
commit: 6e30d7cba992d626c9d16b3873a7b90c700d0e95 [26/26] usb: Add 
driver/usb/core/(port.c,hub.h) files
config: make ARCH=arm at91_dt_defconfig

All error/warnings:

   drivers/usb/core/port.c: In function 'usb_port_device_release':
 drivers/usb/core/port.c:25:2: error: implicit declaration of function 
 'kfree' [-Werror=implicit-function-declaration]
   drivers/usb/core/port.c: In function 'usb_hub_create_port_device':
 drivers/usb/core/port.c:38:2: error: implicit declaration of function 
 'kzalloc' [-Werror=implicit-function-declaration]
 drivers/usb/core/port.c:38:40: error: 'GFP_KERNEL' undeclared (first use in 
 this function)
   drivers/usb/core/port.c:38:40: note: each undeclared identifier is reported 
only once for each function it appears in
   cc1: some warnings being treated as errors

head:   6e30d7cba992d626c9d16b3873a7b90c700d0e95
commit: 6e30d7cba992d626c9d16b3873a7b90c700d0e95 [26/26] usb: Add 
driver/usb/core/(port.c,hub.h) files
config: make ARCH=blackfin BF526-EZBRD_defconfig

All warnings:

   drivers/usb/core/port.c: In function 'usb_port_device_release':
   drivers/usb/core/port.c:25:2: error: implicit declaration of function 
'kfree' [-Werror=implicit-function-declaration]
   drivers/usb/core/port.c: In function 'usb_hub_create_port_device':
   drivers/usb/core/port.c:38:2: error: implicit declaration of function 
'kzalloc' [-Werror=implicit-function-declaration]
 drivers/usb/core/port.c:38:11: warning: assignment makes pointer from 
 integer without a cast [enabled by default]
   cc1: some warnings being treated as errors

Reported-by: Fengguang Wu w...@linux.intel.com
Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/port.c |2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 2bc1cef..3734850 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -16,6 +16,8 @@
  *
  */
 
+#include linux/slab.h
+
 #include hub.h
 
 static void usb_port_device_release(struct device *dev)
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V5 0/10] usb: usb port power off mechanism and expose usb port connect type

2013-01-19 Thread Lan Tianyu
Change since v1:
   optimize the export connect type patch and adjust the DeviceRemovalbe 
flag
in the rh_call_control() after GetHubDescriptor request being processed.
   move all debounce operation to usb port's runtime resume callback(). Add
did_runtime_put in the struct usb_port to call pm_runtime_get/put(portdev) 
paired.
   using pm_runtime_get/put(portdev) to allow or prohibit device to be power
off inside of pm qos request in the kernel side. 

Change since v2:
   Correct some link breaks. 
   Add did_runtime_put in the usb_disconnect() before calling 
pm_runtime_put(portdev).
   Provide two seperate functions usb_device_allow_power_off() and 
usb_device_prevent_power_off()
instead of just one.

Change since v3:
Set did_runtime_put to false in usb_disconnect() when its value is true
Add comment about not enable port runtime pm if fail to expose port's 
pm qos. and call
pm_runtime_set_active(portdev) unconditionally.
rename usb_device_allow_prevent_power_off with 
usb_device_control_power_off
Modify be power off to be powered off
Expose dev_pm_qos_flags() symbol in order to ensure usb core can 
compile as module. 

Resend v4:
make patch PM/Qos: Expose dev_pm_qos_flags symbol as first patch to 
avoid compilation error during git bisect
correct some comments.

Change since v5:
use EXPORT_SYMBOL_GPL to export dev_pm_qos_flags().
correct some unnecessary link breaks.   
Add CONFIG_USB_SUSPEND check around usb_port_runtime_resume() and 
usb_port_runtime_suspend()


This patchset is based on usb-next tree commit 6e30d7cba usb: Add 
driver/usb/core/(port.c,hub.h) files
and the patch usb: fix compilation error and warning of driver/usb/core/port.c 
on arm and blackfin
http://marc.info/?l=linux-usbm=135860593115173w=2 

This patchset is to add usb port power off mechanism and
merge with patchset usb: expose DeviceRemovable to user space via sysfs 
attribute.

Patchset usb: expose DeviceRemovable to user space via sysfs attribute.
http://marc.info/?l=linux-usbm=135279430410171w=2 with some link break 
corrects

The main discussion about usb port power off mechanism is in the following link:
http://marc.info/?l=linux-usbm=134818340017208w=2


PM/Qos: Expose dev_pm_qos_flags symbol
USB: Set usb port's DeviceRemovable according acpi information
usb: Add portX/connect_type attribute to expose usb port's connect type
usb: Create link files between child device and usb port device.
usb: Register usb port's acpi power resources
usb: add runtime pm support for usb port device
usb: add usb port auto power off mechanism
usb: expose usb port's pm qos flags to user space
usb: add usb_device_allow_power_off() and usb_device_prevent_power_off() 
function.
usb: enable usb port device's async suspend.
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 01/10] PM/Qos: Expose dev_pm_qos_flags symbol

2013-01-19 Thread Lan Tianyu
The dev_pm_qos_flags() will be used in the usb core which could be
compiled as a module. This patch is to export it.

Acked-by: Alan Stern st...@rowland.harvard.edu
Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/base/power/qos.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c
index d213495..3d4d1f8 100644
--- a/drivers/base/power/qos.c
+++ b/drivers/base/power/qos.c
@@ -91,6 +91,7 @@ enum pm_qos_flags_status dev_pm_qos_flags(struct device *dev, 
s32 mask)
 
return ret;
 }
+EXPORT_SYMBOL_GPL(dev_pm_qos_flags);
 
 /**
  * __dev_pm_qos_read_value - Get PM QoS constraint for a given device.
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 02/10] USB: Set usb port's DeviceRemovable according acpi information

2013-01-19 Thread Lan Tianyu
ACPI provide _PLD and _UPC aml methods to describe usb port
visibility and connectability. This patch is to add 
usb_hub_adjust_DeviceRemovable()
to adjust usb hub port's DeviceRemovable according ACPI information and invoke 
it in
the rh_call_control(). When hub descriptor request is issued at first time,
usb port device isn't created and usb port is not bound with acpi. So first
hub descriptor request is not changed based on ACPI information. After usb
port devices being created, call usb_hub_adjust_DeviceRemovable in the 
hub_configure()
and then set hub port's DeviceRemovable according ACPI information and this 
also works
for non-root hub.

Acked-by: Alan Stern st...@rowland.harvard.edu
Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/hcd.c |4 
 drivers/usb/core/hub.c |   43 +++
 drivers/usb/core/usb.h |3 +++
 3 files changed, 50 insertions(+)

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 5f6da8b..2459896 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -619,6 +619,10 @@ nongeneric:
status = hcd-driver-hub_control (hcd,
typeReq, wValue, wIndex,
tbuf, wLength);
+
+   if (typeReq == GetHubDescriptor)
+   usb_hub_adjust_deviceremovable(hcd-self.root_hub,
+   (struct usb_hub_descriptor *)tbuf);
break;
 error:
/* protocol stall on error */
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index f6ff130..f7e1402 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1513,6 +1513,8 @@ static int hub_configure(struct usb_hub *hub,
dev_err(hub-intfdev,
couldn't create port%d device.\n, i + 1);
 
+   usb_hub_adjust_deviceremovable(hdev, hub-descriptor);
+
hub_activate(hub, HUB_INIT);
return 0;
 
@@ -5193,6 +5195,47 @@ usb_get_hub_port_connect_type(struct usb_device *hdev, 
int port1)
return hub-ports[port1 - 1]-connect_type;
 }
 
+void usb_hub_adjust_deviceremovable(struct usb_device *hdev,
+   struct usb_hub_descriptor *desc)
+{
+   enum usb_port_connect_type connect_type;
+   int i;
+
+   if (!hub_is_superspeed(hdev)) {
+   for (i = 1; i = hdev-maxchild; i++) {
+   connect_type = usb_get_hub_port_connect_type(hdev, i);
+
+   if (connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) {
+   u8 mask = 1  (i%8);
+
+   if (!(desc-u.hs.DeviceRemovable[i/8]  mask)) {
+   dev_dbg(hdev-dev, usb port%d's 
DeviceRemovable is changed to 1 according to platform information.\n,
+   i);
+   desc-u.hs.DeviceRemovable[i/8] |= mask;
+   }
+   }
+   }
+   } else {
+   u16 port_removable = le16_to_cpu(desc-u.ss.DeviceRemovable);
+
+   for (i = 1; i = hdev-maxchild; i++) {
+   connect_type = usb_get_hub_port_connect_type(hdev, i);
+
+   if (connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) {
+   u16 mask = 1  i;
+
+   if (!(port_removable  mask)) {
+   dev_dbg(hdev-dev, usb port%d's 
DeviceRemovable is changed to 1 according to platform information.\n,
+   i);
+   port_removable |= mask;
+   }
+   }
+   }
+
+   desc-u.ss.DeviceRemovable = cpu_to_le16(port_removable);
+   }
+}
+
 #ifdef CONFIG_ACPI
 /**
  * usb_get_hub_port_acpi_handle - Get the usb port's acpi handle
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index fb7d8fc..31f32cd 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -1,5 +1,6 @@
 #include linux/pm.h
 #include linux/acpi.h
+#include linux/usb/ch11.h
 
 struct dev_state;
 
@@ -182,6 +183,8 @@ extern enum usb_port_connect_type
usb_get_hub_port_connect_type(struct usb_device *hdev, int port1);
 extern void usb_set_hub_port_connect_type(struct usb_device *hdev, int port1,
enum usb_port_connect_type type);
+extern void usb_hub_adjust_deviceremovable(struct usb_device *hdev,
+   struct usb_hub_descriptor *desc);
 
 #ifdef CONFIG_ACPI
 extern int usb_acpi_register(void);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 03/10] usb: Add portX/connect_type attribute to expose usb port's connect type

2013-01-19 Thread Lan Tianyu
Some platforms provide usb port connect types through ACPI. This
patch is to add this new attribute to expose these information
to user space.

Acked-by: Alan Stern st...@rowland.harvard.edu
Signed-off-by: Lan Tianyu tianyu@intel.com
---
 Documentation/ABI/testing/sysfs-bus-usb |9 +++
 drivers/usb/core/port.c |   43 +++
 2 files changed, 52 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-usb 
b/Documentation/ABI/testing/sysfs-bus-usb
index b6fbe51..c8baaf5 100644
--- a/Documentation/ABI/testing/sysfs-bus-usb
+++ b/Documentation/ABI/testing/sysfs-bus-usb
@@ -227,3 +227,12 @@ Contact:   Lan Tianyu tianyu@intel.com
 Description:
The /sys/bus/usb/devices/.../(hub interface)/portX
is usb port device's sysfs directory.
+
+What:  /sys/bus/usb/devices/.../(hub interface)/portX/connect_type
+Date:  January 2013
+Contact:   Lan Tianyu tianyu@intel.com
+Description:
+   Some platforms provide usb port connect types through ACPI.
+   This attribute is to expose these information to user space.
+   The file will read hotplug, wired and not used if the
+   information is available, and unknown otherwise.
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 3734850..fe5959f 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -20,6 +20,48 @@
 
 #include hub.h
 
+static const struct attribute_group *port_dev_group[];
+
+static ssize_t show_port_connect_type(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   struct usb_port *port_dev = to_usb_port(dev);
+   char *result;
+
+   switch (port_dev-connect_type) {
+   case USB_PORT_CONNECT_TYPE_HOT_PLUG:
+   result = hotplug;
+   break;
+   case USB_PORT_CONNECT_TYPE_HARD_WIRED:
+   result = hardwired;
+   break;
+   case USB_PORT_NOT_USED:
+   result = not used;
+   break;
+   default:
+   result = unknown;
+   break;
+   }
+
+   return sprintf(buf, %s\n, result);
+}
+static DEVICE_ATTR(connect_type, S_IRUGO, show_port_connect_type,
+   NULL);
+
+static struct attribute *port_dev_attrs[] = {
+   dev_attr_connect_type.attr,
+   NULL,
+};
+
+static struct attribute_group port_dev_attr_grp = {
+   .attrs = port_dev_attrs,
+};
+
+static const struct attribute_group *port_dev_group[] = {
+   port_dev_attr_grp,
+   NULL,
+};
+
 static void usb_port_device_release(struct device *dev)
 {
struct usb_port *port_dev = to_usb_port(dev);
@@ -45,6 +87,7 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1)
 
hub-ports[port1 - 1] = port_dev;
port_dev-dev.parent = hub-intfdev;
+   port_dev-dev.groups = port_dev_group;
port_dev-dev.type = usb_port_device_type;
dev_set_name(port_dev-dev, port%d, port1);
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 04/10] usb: Create link files between child device and usb port device.

2013-01-19 Thread Lan Tianyu
To show the relationship between usb port and child device,
add link file port under usb device's sysfs directoy and
device under usb port device's sysfs directory. They are linked
to each other.

Acked-by: Alan Stern st...@rowland.harvard.edu
Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/hub.c |   26 ++
 1 file changed, 26 insertions(+)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index f7e1402..29ca6ed 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1991,6 +1991,14 @@ void usb_disconnect(struct usb_device **pdev)
usb_disable_device(udev, 0);
usb_hcd_synchronize_unlinks(udev);
 
+   if (udev-parent) {
+   struct usb_port *port_dev =
+   hdev_to_hub(udev-parent)-ports[udev-portnum - 1];
+
+   sysfs_remove_link(udev-dev.kobj, port);
+   sysfs_remove_link(port_dev-dev.kobj, device);
+   }
+
usb_remove_ep_devs(udev-ep0);
usb_unlock_device(udev);
 
@@ -2283,6 +2291,24 @@ int usb_new_device(struct usb_device *udev)
goto fail;
}
 
+   /* Create link files between child device and usb port device. */
+   if (udev-parent) {
+   struct usb_port *port_dev =
+   hdev_to_hub(udev-parent)-ports[udev-portnum - 1];
+
+   err = sysfs_create_link(udev-dev.kobj,
+   port_dev-dev.kobj, port);
+   if (err)
+   goto fail;
+
+   err = sysfs_create_link(port_dev-dev.kobj,
+   udev-dev.kobj, device);
+   if (err) {
+   sysfs_remove_link(udev-dev.kobj, port);
+   goto fail;
+   }
+   }
+
(void) usb_create_ep_devs(udev-dev, udev-ep0, udev);
usb_mark_last_busy(udev);
pm_runtime_put_sync_autosuspend(udev-dev);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 05/10] usb: Register usb port's acpi power resources

2013-01-19 Thread Lan Tianyu
This patch is to register usb port's acpi power resources. Create
link between usb port device and its acpi power resource.

Acked-by: Alan Stern st...@rowland.harvard.edu
Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/port.c |3 +++
 drivers/usb/core/usb-acpi.c |   20 
 drivers/usb/core/usb.h  |6 ++
 3 files changed, 29 insertions(+)

diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index fe5959f..4dfa254 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -66,6 +66,7 @@ static void usb_port_device_release(struct device *dev)
 {
struct usb_port *port_dev = to_usb_port(dev);
 
+   usb_acpi_unregister_power_resources(dev);
kfree(port_dev);
 }
 
@@ -95,6 +96,8 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1)
if (retval)
goto error_register;
 
+   usb_acpi_register_power_resources(port_dev-dev);
+
return 0;
 
 error_register:
diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
index cef4252..558ab01 100644
--- a/drivers/usb/core/usb-acpi.c
+++ b/drivers/usb/core/usb-acpi.c
@@ -216,6 +216,26 @@ static struct acpi_bus_type usb_acpi_bus = {
.find_device = usb_acpi_find_device,
 };
 
+int usb_acpi_register_power_resources(struct device *dev)
+{
+   acpi_handle port_handle = DEVICE_ACPI_HANDLE(dev);
+
+   if (!port_handle)
+   return -ENODEV;
+
+   if (acpi_power_resource_register_device(dev, port_handle)  0)
+   return -ENODEV;
+   return 0;
+}
+
+void usb_acpi_unregister_power_resources(struct device *dev)
+{
+   acpi_handle port_handle = DEVICE_ACPI_HANDLE(dev);
+
+   if (port_handle)
+   acpi_power_resource_unregister_device(dev, port_handle);
+}
+
 int usb_acpi_register(void)
 {
return register_acpi_bus_type(usb_acpi_bus);
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 31f32cd..bf524e4 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -191,7 +191,13 @@ extern int usb_acpi_register(void);
 extern void usb_acpi_unregister(void);
 extern acpi_handle usb_get_hub_port_acpi_handle(struct usb_device *hdev,
int port1);
+extern int usb_acpi_register_power_resources(struct device *dev);
+extern void usb_acpi_unregister_power_resources(struct device *dev);
 #else
 static inline int usb_acpi_register(void) { return 0; };
 static inline void usb_acpi_unregister(void) { };
+static inline int usb_acpi_register_power_resources(struct device *udev)
+   { return 0; };
+static inline void usb_acpi_unregister_power_resources(struct device *udev)
+   { };
 #endif
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 07/10] usb: add usb port auto power off mechanism

2013-01-19 Thread Lan Tianyu
This patch is to add usb port auto power off mechanism.
When usb device is suspending, usb core will suspend usb port and
usb port runtime pm callback will clear PORT_POWER feature to
power off port if all conditions were met. These conditions are
remote wakeup disable, pm qos NO_POWER_OFF flag clear and persist
enable. When it resumes, power on port again. Add did_runtime_put
in the struct usb_port in order to call pm_runtime_get/put(portdev)
paired during suspending and resuming.

Acked-by: Alan Stern st...@rowland.harvard.edu
Acked-by: Rafael J. Wysocki rafael.j.wyso...@intel.com
Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/hub.c  |   67 ---
 drivers/usb/core/hub.h  |9 +++
 drivers/usb/core/port.c |   40 ++--
 3 files changed, 105 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 8c1f9a5..786db99 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -26,6 +26,7 @@
 #include linux/mutex.h
 #include linux/freezer.h
 #include linux/random.h
+#include linux/pm_qos.h
 
 #include asm/uaccess.h
 #include asm/byteorder.h
@@ -108,7 +109,7 @@ MODULE_PARM_DESC(use_both_schemes,
 DECLARE_RWSEM(ehci_cf_port_reset_rwsem);
 EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem);
 
-#define HUB_DEBOUNCE_TIMEOUT   1500
+#define HUB_DEBOUNCE_TIMEOUT   2000
 #define HUB_DEBOUNCE_STEP25
 #define HUB_DEBOUNCE_STABLE 100
 
@@ -127,7 +128,7 @@ static inline char *portspeed(struct usb_hub *hub, int 
portstatus)
 }
 
 /* Note that hdev or one of its children must be locked! */
-static struct usb_hub *hdev_to_hub(struct usb_device *hdev)
+struct usb_hub *hdev_to_hub(struct usb_device *hdev)
 {
if (!hdev || !hdev-actconfig || !hdev-maxchild)
return NULL;
@@ -393,7 +394,7 @@ static int clear_hub_feature(struct usb_device *hdev, int 
feature)
 /*
  * USB 2.0 spec Section 11.24.2.2
  */
-static int clear_port_feature(struct usb_device *hdev, int port1, int feature)
+int clear_port_feature(struct usb_device *hdev, int port1, int feature)
 {
return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port1,
@@ -718,11 +719,16 @@ int usb_hub_set_port_power(struct usb_device *hdev, int 
port1,
bool set)
 {
int ret;
+   struct usb_hub *hub = hdev_to_hub(hdev);
+   struct usb_port *port_dev = hub-ports[port1 - 1];
 
if (set)
ret = set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
else
ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
+
+   if (!ret)
+   port_dev-power_is_on = set;
return ret;
 }
 
@@ -802,7 +808,11 @@ static unsigned hub_power_on(struct usb_hub *hub, bool 
do_delay)
dev_dbg(hub-intfdev, trying to enable port power on 
non-switchable hub\n);
for (port1 = 1; port1 = hub-descriptor-bNbrPorts; port1++)
-   set_port_feature(hub-hdev, port1, USB_PORT_FEAT_POWER);
+   if (hub-ports[port1 - 1]-power_is_on)
+   set_port_feature(hub-hdev, port1, USB_PORT_FEAT_POWER);
+   else
+   clear_port_feature(hub-hdev, port1,
+   USB_PORT_FEAT_POWER);
 
/* Wait at least 100 msec for power to become stable */
delay = max(pgood_delay, (unsigned) 100);
@@ -1134,10 +1144,16 @@ static void hub_activate(struct usb_hub *hub, enum 
hub_activation_type type)
set_bit(port1, hub-change_bits);
 
} else if (udev-persist_enabled) {
+   struct usb_port *port_dev = hub-ports[port1 - 1];
+
 #ifdef CONFIG_PM
udev-reset_resume = 1;
 #endif
-   set_bit(port1, hub-change_bits);
+   /* Don't set the change_bits when the device
+* was powered off.
+*/
+   if (port_dev-power_is_on)
+   set_bit(port1, hub-change_bits);
 
} else {
/* The power session is gone; tell khubd */
@@ -2012,7 +2028,10 @@ void usb_disconnect(struct usb_device **pdev)
sysfs_remove_link(udev-dev.kobj, port);
sysfs_remove_link(port_dev-dev.kobj, device);
 
-   pm_runtime_put(port_dev-dev);
+   if (!port_dev-did_runtime_put)
+   pm_runtime_put(port_dev-dev);
+   else
+   port_dev-did_runtime_put = false;
}
 
usb_remove_ep_devs(udev-ep0);
@@ -2844,6 +2863,8 @@ EXPORT_SYMBOL_GPL(usb_enable_ltm);
 int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
 {
struct usb_hub  *hub = hdev_to_hub(udev-parent);
+   struct usb_port *port_dev = hub-ports

[PATCH v5 08/10] usb: expose usb port's pm qos flags to user space

2013-01-19 Thread Lan Tianyu
This patch is to expose usb port's pm qos flags(pm_qos_no_power_off,
pm_qos_remote_wakeup) to user space. User can set pm_qos_no_power_off
flag to prohibit the port from being powered off.

Acked-by: Alan Stern st...@rowland.harvard.edu
Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/port.c |   11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index dc1aaec..0c51d24 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -67,6 +67,7 @@ static void usb_port_device_release(struct device *dev)
 {
struct usb_port *port_dev = to_usb_port(dev);
 
+   dev_pm_qos_hide_flags(dev);
usb_acpi_unregister_power_resources(dev);
kfree(port_dev);
 }
@@ -176,7 +177,15 @@ int usb_hub_create_port_device(struct usb_hub *hub, int 
port1)
goto error_register;
 
pm_runtime_set_active(port_dev-dev);
-   pm_runtime_enable(port_dev-dev);
+
+   /* It would be dangerous if user space couldn't
+* prevent usb device from being powered off. So don't
+* enable port runtime pm if failed to expose port's pm qos.
+*/
+   if (!dev_pm_qos_expose_flags(port_dev-dev,
+   PM_QOS_FLAG_NO_POWER_OFF))
+   pm_runtime_enable(port_dev-dev);
+
usb_acpi_register_power_resources(port_dev-dev);
 
return 0;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 09/10] usb: add usb_device_allow_power_off() and usb_device_prevent_power_off() function.

2013-01-19 Thread Lan Tianyu
Some usb devices can't be resumed correctly after power off. This
patch is to add usb_device_allow_power_off() and usb_device_prevent_power_off()
for device's driver. Call pm_runtime_get_sync(portdev) to increase port's usage
count and then port will not be suspended. The device will not be powered off.

Acked-by: Alan Stern st...@rowland.harvard.edu
Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/port.c |   28 
 1 file changed, 28 insertions(+)

diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 0c51d24..0334d91 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -18,11 +18,39 @@
 
 #include linux/slab.h
 #include linux/pm_qos.h
+#include linux/module.h
 
 #include hub.h
 
 static const struct attribute_group *port_dev_group[];
 
+/**
+ * usb_device_control_power_off - Allow or prohibit power off device.
+ * @udev: target usb device
+ * @allow: choice of allow or prohibit
+ *
+ * Call pm_runtime_get/put_sync(portdev) to allow or prohibit target
+ * usb device to be powered off in the kernel. The operations of setting
+ * true and false should be couple. The default status is allowed.
+ */
+int usb_device_control_power_off(struct usb_device *udev, bool allow)
+{
+   struct usb_port *port_dev;
+
+   if (!udev-parent)
+   return -EINVAL;
+
+   port_dev = hdev_to_hub(udev-parent)-ports[udev-portnum - 1];
+
+   if (allow)
+   pm_runtime_put_sync(port_dev-dev);
+   else
+   pm_runtime_get_sync(port_dev-dev);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(usb_device_control_power_off);
+
 static ssize_t show_port_connect_type(struct device *dev,
struct device_attribute *attr, char *buf)
 {
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 10/10] usb: enable usb port device's async suspend.

2013-01-19 Thread Lan Tianyu

Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/port.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 0334d91..50b646e 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -215,7 +215,7 @@ int usb_hub_create_port_device(struct usb_hub *hub, int 
port1)
pm_runtime_enable(port_dev-dev);
 
usb_acpi_register_power_resources(port_dev-dev);
-
+   device_enable_async_suspend(port_dev-dev);
return 0;
 
 error_register:
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Resend PATCH V4 0/10] usb: usb port power off mechanism anc expose usb port connect type

2013-01-18 Thread Lan Tianyu
On 2013年01月16日 23:45, Alan Stern wrote:
 On Tue, 15 Jan 2013, Lan Tianyu wrote:
 
 Hi GregAlan:
  Do you have some more comments about this patchset? Thanks.
 
 I don't have any more comments at this point.  It looks okay to me.
 
 Acked-by: Alan Stern st...@rowland.harvard.edu
 
 By the way, have you checked whether the auto-power-off mechanism works 
 correctly when you do a system suspend?
 
Thanks for reminder. I test this today and find an issue. If usb device
was powered off during runtime, pm_runtime_get_sync() in the
usb_port_resume() will return -EACCES when do system resume. This is
because port's runtime pm was disabled during system suspend. Following
are some log. The device's runtime pm will be enabled after system
suspend. The port device is advance to be inserted in the dpm_list than
usb device(port device is created before creating usb device). So the
resume sequence is that resume usb device firstly and then usb port. In
the result, pm_runtime_get_sync() doesn't work.

[   70.448028] power LNXPOWER:03: driver resume
[   70.448029] usb usb4: runtime enable
[   70.448031] usb 3-1: can't resume usb port, status -13
[   70.448032] usb usb4: type resume
[   70.448039] dpm_run_callback(): usb_dev_resume+0x0/0x15 returns -13
[   70.448040] usb usb4: usb resume
[   70.448041] usb 3-2: can't resume usb port, status -13
[   70.448043] PM: Device 3-1 failed to resume async: error -13
[   70.448047] dpm_run_callback(): usb_dev_resume+0x0/0x15 returns -13
[   70.448048] PM: Device 3-2 failed to resume async: error -13
[   70.448056] hub 4-0:1.0: hub_resume
[   70.448088] acpi device:49: runtime enable

I found one solution of adding pm_runtime_enable/disable() in the
usb_port_resume(). This is simple sovlution.

if (port_dev-did_runtime_put) {
if (!PMSG_IS_AUTO(msg)) {
pm_runtime_enable(port_dev-dev);
status = pm_runtime_get_sync(port_dev-dev);
pm_runtime_disable(port_dev-dev);
} else
status = pm_runtime_get_sync(port_dev-dev);

port_dev-did_runtime_put = false;
if (status  0) {
dev_dbg(udev-dev, can't resume usb port, status %d\n,
status);
return status;
}
}

This can work but I am not sure that it is safe to do system resume() in
the system resume().

Another proposal is to export usb_port_runtime_resume() or do a wrapper.
Call it in the usb_port_resume() with pm_runtime_get_noresume() and
pm_runtime_set_active(). This also work.

if (port_dev-did_runtime_put) {
if (!PMSG_IS_AUTO(msg)) {
status = usb_port_runtime_resume(port_dev-dev);
pm_runtime_get_noresume(port_dev-dev);
pm_runtime_set_active(udev-dev);
} else
status = pm_runtime_get_sync(port_dev-dev);

port_dev-did_runtime_put = false;
if (status  0) {
dev_dbg(udev-dev, can't resume usb port, status %d\n,
status);
return status;
}
}





 Alan Stern
 


-- 
Best regards
Tianyu Lan
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Rebase PATCH] usb: Using correct way to clear usb3.0 device's remote wakeup feature.

2013-01-18 Thread Lan Tianyu
Usb3.0 device defines function remote wakeup which is only for interface
recipient rather than device recipient. This is different with usb2.0 device's
remote wakeup feature which is defined for device recipient. According usb3.0
spec 9.4.5, the function remote wakeup can be modified by the SetFeature()
requests using the FUNCTION_SUSPEND feature selector. This patch is to use
correct way to disable usb3.0 device's function remote wakeup after suspend
error and resuming.

Signed-off-by: Lan Tianyu tianyu@intel.com
---
This patch is rebased on the usb-linus branch commit 1ee0a224bc9aa
USB: io_ti: Fix NULL dereference in chase_port()
---
 drivers/usb/core/hub.c   |   71 +++---
 include/uapi/linux/usb/ch9.h |6 
 2 files changed, 59 insertions(+), 18 deletions(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 957ed2c..d1753d6 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2837,6 +2837,24 @@ void usb_enable_ltm(struct usb_device *udev)
 }
 EXPORT_SYMBOL_GPL(usb_enable_ltm);
 
+/*
+ * usb_disable_function_remotewakeup - disable usb3.0
+ * device's function remote wakeup
+ * @udev: target device
+ *
+ * Assume there's only one function on the USB 3.0
+ * device and disable remote wake for the first
+ * interface. FIXME if the interface association
+ * descriptor shows there's more than one function.
+ */
+static int usb_disable_function_remotewakeup(struct usb_device *udev)
+{
+   return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+   USB_REQ_CLEAR_FEATURE, USB_RECIP_INTERFACE,
+   USB_INTRF_FUNC_SUSPEND, 0, NULL, 0,
+   USB_CTRL_SET_TIMEOUT);
+}
+
 #ifdef CONFIG_USB_SUSPEND
 
 /*
@@ -2955,12 +2973,19 @@ int usb_port_suspend(struct usb_device *udev, 
pm_message_t msg)
dev_dbg(hub-intfdev, can't suspend port %d, status %d\n,
port1, status);
/* paranoia:  should not happen */
-   if (udev-do_remote_wakeup)
-   (void) usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
-   USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE,
-   USB_DEVICE_REMOTE_WAKEUP, 0,
-   NULL, 0,
-   USB_CTRL_SET_TIMEOUT);
+   if (udev-do_remote_wakeup) {
+   if (!hub_is_superspeed(hub-hdev)) {
+   (void) usb_control_msg(udev,
+   usb_sndctrlpipe(udev, 0),
+   USB_REQ_CLEAR_FEATURE,
+   USB_RECIP_DEVICE,
+   USB_DEVICE_REMOTE_WAKEUP, 0,
+   NULL, 0,
+   USB_CTRL_SET_TIMEOUT);
+   } else
+   (void) usb_disable_function_remotewakeup(udev);
+
+   }
 
/* Try to enable USB2 hardware LPM again */
if (udev-usb2_hw_lpm_capable == 1)
@@ -3052,20 +3077,30 @@ static int finish_port_resume(struct usb_device *udev)
 * udev-reset_resume
 */
} else if (udev-actconfig  !udev-reset_resume) {
-   le16_to_cpus(devstatus);
-   if (devstatus  (1  USB_DEVICE_REMOTE_WAKEUP)) {
-   status = usb_control_msg(udev,
-   usb_sndctrlpipe(udev, 0),
-   USB_REQ_CLEAR_FEATURE,
+   if (!hub_is_superspeed(udev-parent)) {
+   le16_to_cpus(devstatus);
+   if (devstatus  (1  USB_DEVICE_REMOTE_WAKEUP))
+   status = usb_control_msg(udev,
+   usb_sndctrlpipe(udev, 0),
+   USB_REQ_CLEAR_FEATURE,
USB_RECIP_DEVICE,
-   USB_DEVICE_REMOTE_WAKEUP, 0,
-   NULL, 0,
-   USB_CTRL_SET_TIMEOUT);
-   if (status)
-   dev_dbg(udev-dev,
-   disable remote wakeup, status %d\n,
-   status);
+   USB_DEVICE_REMOTE_WAKEUP, 0,
+   NULL, 0,
+   USB_CTRL_SET_TIMEOUT);
+   } else {
+   status = usb_get_status(udev, USB_RECIP_INTERFACE, 0,
+   devstatus);
+   le16_to_cpus(devstatus);
+   if (!status  devstatus

[PATCH v2 1/3] usb: add find_raw_port_number callback to struct hc_driver()

2013-01-18 Thread Lan Tianyu
xhci driver divides the root hub into two logical hubs which work
respectively for usb 2.0 and usb 3.0 devices. They are independent
devices in the usb core. But in the ACPI table, it's one device node
and all usb2.0 and usb3.0 ports are under it. Binding usb port with
its acpi node needs the raw port number which is reflected in the xhci
extended capabilities table. This patch is to add find_raw_port_number
callback to struct hc_driver() and fill it with xhci_find_raw_port_number().

Signed-off-by: Lan Tianyu tianyu@intel.com
---
Change since v1:
Don't export usb_hcd_find_raw_port_number() symbol since there is no
its user outside of usb core.

This patchset is rebased on the usb-next tree commit 74ff31b81d9
usb: misc: usb3503_probe() can be static
---
 drivers/usb/core/hcd.c  |8 
 drivers/usb/host/xhci-pci.c |1 +
 drivers/usb/host/xhci.c |   22 ++
 drivers/usb/host/xhci.h |1 +
 include/linux/usb/hcd.h |2 ++
 5 files changed, 34 insertions(+)

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 5f6da8b..0277bd2 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2364,6 +2364,14 @@ int usb_hcd_is_primary_hcd(struct usb_hcd *hcd)
 }
 EXPORT_SYMBOL_GPL(usb_hcd_is_primary_hcd);
 
+int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1)
+{
+   if (!hcd-driver-find_raw_port_number)
+   return port1;
+
+   return hcd-driver-find_raw_port_number(hcd, port1);
+}
+
 static int usb_hcd_request_irqs(struct usb_hcd *hcd,
unsigned int irqnum, unsigned long irqflags)
 {
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index af259e0..1a30c38 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -313,6 +313,7 @@ static const struct hc_driver xhci_pci_hc_driver = {
.set_usb2_hw_lpm =  xhci_set_usb2_hardware_lpm,
.enable_usb3_lpm_timeout =  xhci_enable_usb3_lpm_timeout,
.disable_usb3_lpm_timeout = xhci_disable_usb3_lpm_timeout,
+   .find_raw_port_number = xhci_find_raw_port_number,
 };
 
 /*-*/
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index f1f01a8..0780d8f 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -3778,6 +3778,28 @@ int xhci_address_device(struct usb_hcd *hcd, struct 
usb_device *udev)
return 0;
 }
 
+/*
+ * Transfer the port index into real index in the HW port status
+ * registers. Caculate offset between the port's PORTSC register
+ * and port status base. Divide the number of per port register
+ * to get the real index. The raw port number bases 1.
+ */
+int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1)
+{
+   struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+   __le32 __iomem *base_addr = xhci-op_regs-port_status_base;
+   __le32 __iomem *addr;
+   int raw_port;
+
+   if (hcd-speed != HCD_USB3)
+   addr = xhci-usb2_ports[port1 - 1];
+   else
+   addr = xhci-usb3_ports[port1 - 1];
+
+   raw_port = (addr - base_addr)/NUM_PORT_REGS + 1;
+   return raw_port;
+}
+
 #ifdef CONFIG_USB_SUSPEND
 
 /* BESL to HIRD Encoding array for USB2 LPM */
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index f791bd0..55345d9 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1829,6 +1829,7 @@ void xhci_test_and_clear_bit(struct xhci_hcd *xhci, 
__le32 __iomem **port_array,
 int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex,
char *buf, u16 wLength);
 int xhci_hub_status_data(struct usb_hcd *hcd, char *buf);
+int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1);
 
 #ifdef CONFIG_PM
 int xhci_bus_suspend(struct usb_hcd *hcd);
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index 608050b..61b88b5 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -357,6 +357,7 @@ struct hc_driver {
 */
int (*disable_usb3_lpm_timeout)(struct usb_hcd *,
struct usb_device *, enum usb3_link_state state);
+   int (*find_raw_port_number)(struct usb_hcd *, int);
 };
 
 extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
@@ -396,6 +397,7 @@ extern int usb_hcd_is_primary_hcd(struct usb_hcd *hcd);
 extern int usb_add_hcd(struct usb_hcd *hcd,
unsigned int irqnum, unsigned long irqflags);
 extern void usb_remove_hcd(struct usb_hcd *hcd);
+extern int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1);
 
 struct platform_device;
 extern void usb_hcd_platform_shutdown(struct platform_device *dev);
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 2/3] usb/acpi: binding xhci root hub usb port with ACPI

2013-01-18 Thread Lan Tianyu
This patch is to bind xhci root hub usb port with its acpi node.
The port num in the acpi table matches with the sequence in the xhci
extended capabilities table. So call usb_hcd_find_raw_port_number() to
transfer hub port num into raw port number which associates with
the sequence in the xhci extended capabilities table before binding.

Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/usb-acpi.c |4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
index cef4252..40f5a6a 100644
--- a/drivers/usb/core/usb-acpi.c
+++ b/drivers/usb/core/usb-acpi.c
@@ -15,6 +15,7 @@
 #include linux/kernel.h
 #include linux/acpi.h
 #include linux/pci.h
+#include linux/usb/hcd.h
 #include acpi/acpi_bus.h
 
 #include usb.h
@@ -188,6 +189,9 @@ static int usb_acpi_find_device(struct device *dev, 
acpi_handle *handle)
 * connected to.
 */
if (!udev-parent) {
+   struct usb_hcd *hcd = bus_to_hcd(udev-bus);
+
+   port_num = usb_hcd_find_raw_port_number(hcd, port_num);
*handle = acpi_get_child(DEVICE_ACPI_HANDLE(udev-dev),
port_num);
if (!*handle)
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 3/3] usb/xhci: refactor xhci_find_real_port_number()

2013-01-18 Thread Lan Tianyu
This patch is to optimize xhci_find_realport_number(). Call
xhci_find_raw_port_number() to get real index in the HW port
status registers instead of scanning through the xHCI roothub
port array.

Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/host/xhci-mem.c |   36 
 1 file changed, 8 insertions(+), 28 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 35616ff..6dc238c 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1022,44 +1022,24 @@ void xhci_copy_ep0_dequeue_into_input_ctx(struct 
xhci_hcd *xhci,
  * is attached to (or the roothub port its ancestor hub is attached to).  All 
we
  * know is the index of that port under either the USB 2.0 or the USB 3.0
  * roothub, but that doesn't give us the real index into the HW port status
- * registers.  Scan through the xHCI roothub port array, looking for the Nth
- * entry of the correct port speed.  Return the port number of that entry.
+ * registers. Call xhci_find_raw_port_number() to get real index.
  */
 static u32 xhci_find_real_port_number(struct xhci_hcd *xhci,
struct usb_device *udev)
 {
struct usb_device *top_dev;
-   unsigned int num_similar_speed_ports;
-   unsigned int faked_port_num;
-   int i;
+   struct usb_hcd *hcd;
+
+   if (udev-speed == USB_SPEED_SUPER)
+   hcd = xhci-shared_hcd;
+   else
+   hcd = xhci-main_hcd;
 
for (top_dev = udev; top_dev-parent  top_dev-parent-parent;
top_dev = top_dev-parent)
/* Found device below root hub */;
-   faked_port_num = top_dev-portnum;
-   for (i = 0, num_similar_speed_ports = 0;
-   i  HCS_MAX_PORTS(xhci-hcs_params1); i++) {
-   u8 port_speed = xhci-port_array[i];
-
-   /*
-* Skip ports that don't have known speeds, or have duplicate
-* Extended Capabilities port speed entries.
-*/
-   if (port_speed == 0 || port_speed == DUPLICATE_ENTRY)
-   continue;
 
-   /*
-* USB 3.0 ports are always under a USB 3.0 hub.  USB 2.0 and
-* 1.1 ports are under the USB 2.0 hub.  If the port speed
-* matches the device speed, it's a similar speed port.
-*/
-   if ((port_speed == 0x03) == (udev-speed == USB_SPEED_SUPER))
-   num_similar_speed_ports++;
-   if (num_similar_speed_ports == faked_port_num)
-   /* Roothub ports are numbered from 1 to N */
-   return i+1;
-   }
-   return 0;
+   return  xhci_find_raw_port_number(hcd, top_dev-portnum);
 }
 
 /* Setup an xHCI virtual device for a Set Address command */
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [Resend PATCH V4 0/10] usb: usb port power off mechanism anc expose usb port connect type

2013-01-18 Thread Lan, Tianyu
HI Alan:
I just find Rafael's patch has resolved this issue. In this 
patch, enable runtime PM
right after executing subsystem/driver .resume_early() callbacks. When do 
resume(),
the device's runtime pm has been enabled. This patch now is already in the 
v3.8-rc4.
So this patchset will not cause problem with Rafael patch and I have tested. 
About the
port system suspend/resume() callback, Could I do this in the next step?

commit a8d3848dadc2fd41a9117cb08dc04fe6d7c551f9
Author: Rafael J. Wysocki rafael.j.wyso...@intel.com
Date:   Sat Dec 22 23:59:01 2012 +0100

PM: Move disabling/enabling runtime PM to late suspend/early resume

Currently, the PM core disables runtime PM for all devices right
after executing subsystem/driver .suspend() callbacks for them
and re-enables it right before executing subsystem/driver .resume()
callbacks for them.  This may lead to problems when there are
two devices such that the .suspend() callback executed for one of
them depends on runtime PM working for the other.  In that case,
if runtime PM has already been disabled for the second device,
the first one's .suspend() won't work correctly (and analogously
for resume).

To make those issues go away, make the PM core disable runtime PM
for devices right before executing subsystem/driver .suspend_late()
callbacks for them and enable runtime PM for them right after
executing subsystem/driver .resume_early() callbacks for them.  This
way the potential conflitcs between .suspend_late()/.resume_early()
and their runtime PM counterparts are still prevented from happening,
but the subtle ordering issues related to disabling/enabling runtime
PM for devices during system suspend/resume are much easier to avoid.

Best Regards 
Tianyu Lan 


-Original Message-
From: Alan Stern [mailto:st...@rowland.harvard.edu] 
Sent: Saturday, January 19, 2013 12:21 AM
To: Lan, Tianyu
Cc: r...@sisk.pl; gre...@linuxfoundation.org; sarah.a.sh...@linux.intel.com; 
oneu...@suse.de; linux-usb@vger.kernel.org
Subject: Re: [Resend PATCH V4 0/10] usb: usb port power off mechanism anc 
expose usb port connect type

On Fri, 18 Jan 2013, Lan Tianyu wrote:

  By the way, have you checked whether the auto-power-off mechanism 
  works correctly when you do a system suspend?
  
 Thanks for reminder. I test this today and find an issue. If usb 
 device was powered off during runtime, pm_runtime_get_sync() in the
 usb_port_resume() will return -EACCES when do system resume. This is 
 because port's runtime pm was disabled during system suspend.

Actually it's worse than that.  The PM layer assumes that devices are brought 
back to full power during system resume.  But that's not true for your usb_port 
devices, because they don't have a resume callback.

In addition, we need to enable async PM for the usb_ports, just like everything 
else in the USB stack.  This means you have to call device_enable_async_suspend 
before the port is registered.

  Following
 are some log. The device's runtime pm will be enabled after system 
 suspend. The port device is advance to be inserted in the dpm_list 
 than usb device(port device is created before creating usb device). So 
 the resume sequence is that resume usb device firstly and then usb 
 port. In the result, pm_runtime_get_sync() doesn't work.

When async is enabled, there won't be any defined ordering.  We will have to 
enforce the proper ordering by hand.  This means usb_resume_device will have to 
call device_pm_wait_for_dev for the port device (it already does this for the 
companion root hub).  In fact, the code to do this waiting probably should be 
moved to usb_resume, because it applies only to system resume, not to runtime 
resume.

 [   70.448028] power LNXPOWER:03: driver resume
 [   70.448029] usb usb4: runtime enable
 [   70.448031] usb 3-1: can't resume usb port, status -13
 [   70.448032] usb usb4: type resume
 [   70.448039] dpm_run_callback(): usb_dev_resume+0x0/0x15 returns -13
 [   70.448040] usb usb4: usb resume
 [   70.448041] usb 3-2: can't resume usb port, status -13
 [   70.448043] PM: Device 3-1 failed to resume async: error -13
 [   70.448047] dpm_run_callback(): usb_dev_resume+0x0/0x15 returns -13
 [   70.448048] PM: Device 3-2 failed to resume async: error -13
 [   70.448056] hub 4-0:1.0: hub_resume
 [   70.448088] acpi device:49: runtime enable
 
 I found one solution of adding pm_runtime_enable/disable() in the 
 usb_port_resume(). This is simple sovlution.
 
 if (port_dev-did_runtime_put) {
   if (!PMSG_IS_AUTO(msg)) {
   pm_runtime_enable(port_dev-dev);
   status = pm_runtime_get_sync(port_dev-dev);
   pm_runtime_disable(port_dev-dev);
   } else
   status = pm_runtime_get_sync(port_dev-dev);
 
   port_dev-did_runtime_put = false;
   if (status  0) {
   dev_dbg(udev-dev, can't resume usb port, status %d\n

[PATCH] usb: Using correct way to clear usb3.0 device's remote wakeup feature.

2013-01-16 Thread Lan Tianyu
Usb3.0 device defines function remote wakeup which is only for interface
recipient rather than device recipient. This is different with usb2.0 device's
remote wakeup feature which is defined for device recipient. According usb3.0
spec 9.4.5, the function remote wakeup can be modified by the SetFeature()
requests using the FUNCTION_SUSPEND feature selector. This patch is to use
correct way to disable usb3.0 device's function remote wakeup after suspend
error and resuming.

Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/hub.c   |   71 +++---
 include/uapi/linux/usb/ch9.h |6 
 2 files changed, 59 insertions(+), 18 deletions(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 0ef512a..08c9c04 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2852,6 +2852,24 @@ void usb_enable_ltm(struct usb_device *udev)
 }
 EXPORT_SYMBOL_GPL(usb_enable_ltm);
 
+/*
+ * usb_disable_function_remotewakeup - disable usb3.0
+ * device's function remote wakeup
+ * @udev: target device
+ *
+ * Assume there's only one function on the USB 3.0
+ * device and disable remote wake for the first
+ * interface. FIXME if the interface association
+ * descriptor shows there's more than one function.
+ */
+static int usb_disable_function_remotewakeup(struct usb_device *udev)
+{
+   return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+   USB_REQ_CLEAR_FEATURE, USB_RECIP_INTERFACE,
+   USB_INTRF_FUNC_SUSPEND, 0, NULL, 0,
+   USB_CTRL_SET_TIMEOUT);
+}
+
 #ifdef CONFIG_USB_SUSPEND
 
 /*
@@ -2968,12 +2986,19 @@ int usb_port_suspend(struct usb_device *udev, 
pm_message_t msg)
dev_dbg(hub-intfdev, can't suspend port %d, status %d\n,
port1, status);
/* paranoia:  should not happen */
-   if (udev-do_remote_wakeup)
-   (void) usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
-   USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE,
-   USB_DEVICE_REMOTE_WAKEUP, 0,
-   NULL, 0,
-   USB_CTRL_SET_TIMEOUT);
+   if (udev-do_remote_wakeup) {
+   if (!hub_is_superspeed(hub-hdev)) {
+   (void) usb_control_msg(udev,
+   usb_sndctrlpipe(udev, 0),
+   USB_REQ_CLEAR_FEATURE,
+   USB_RECIP_DEVICE,
+   USB_DEVICE_REMOTE_WAKEUP, 0,
+   NULL, 0,
+   USB_CTRL_SET_TIMEOUT);
+   } else
+   (void) usb_disable_function_remotewakeup(udev);
+
+   }
 
/* Try to enable USB2 hardware LPM again */
if (udev-usb2_hw_lpm_capable == 1)
@@ -3059,20 +3084,30 @@ static int finish_port_resume(struct usb_device *udev)
dev_dbg(udev-dev, gone after usb resume? status %d\n,
status);
} else if (udev-actconfig) {
-   le16_to_cpus(devstatus);
-   if (devstatus  (1  USB_DEVICE_REMOTE_WAKEUP)) {
-   status = usb_control_msg(udev,
-   usb_sndctrlpipe(udev, 0),
-   USB_REQ_CLEAR_FEATURE,
+   if (!hub_is_superspeed(udev-parent)) {
+   le16_to_cpus(devstatus);
+   if (devstatus  (1  USB_DEVICE_REMOTE_WAKEUP))
+   status = usb_control_msg(udev,
+   usb_sndctrlpipe(udev, 0),
+   USB_REQ_CLEAR_FEATURE,
USB_RECIP_DEVICE,
-   USB_DEVICE_REMOTE_WAKEUP, 0,
-   NULL, 0,
-   USB_CTRL_SET_TIMEOUT);
-   if (status)
-   dev_dbg(udev-dev,
-   disable remote wakeup, status %d\n,
-   status);
+   USB_DEVICE_REMOTE_WAKEUP, 0,
+   NULL, 0,
+   USB_CTRL_SET_TIMEOUT);
+   } else {
+   status = usb_get_status(udev, USB_RECIP_INTERFACE, 0,
+   devstatus);
+   le16_to_cpus(devstatus);
+   if (!status  devstatus  (USB_INTRF_STAT_FUNC_RW_CAP

Re: [Resend PATCH V4 0/10] usb: usb port power off mechanism anc expose usb port connect type

2013-01-14 Thread Lan Tianyu
On 2013年01月11日 20:10, Lan Tianyu wrote:
 Change since v1:
optimize the export connect type patch and adjust the DeviceRemovalbe 
 flag
 in the rh_call_control() after GetHubDescriptor request being processed.
move all debounce operation to usb port's runtime resume callback(). 
 Add
 did_runtime_put in the struct usb_port to call pm_runtime_get/put(portdev) 
 paired.
using pm_runtime_get/put(portdev) to allow or prohibit device to be 
 power
 off inside of pm qos request in the kernel side. 
 
 Change since v2:
Correct some link breaks. 
Add did_runtime_put in the usb_disconnect() before calling 
 pm_runtime_put(portdev).
Provide two seperate functions usb_device_allow_power_off() and 
 usb_device_prevent_power_off()
 instead of just one.
 
 Change since v3:
   Set did_runtime_put to false in usb_disconnect() when its value is true
   Add comment about not enable port runtime pm if fail to expose port's 
 pm qos. and call
 pm_runtime_set_active(portdev) unconditionally.
   rename usb_device_allow_prevent_power_off with 
 usb_device_control_power_off
   Modify be power off to be powered off
   Expose dev_pm_qos_flags() symbol in order to ensure usb core can 
 compile as module. 
 
 Resend v4:
make patch PM/Qos: Expose dev_pm_qos_flags symbol as first patch to 
 avoid compilation
 error during git bisect
   correct some comments.
 
 This Patchset is based on usb-next tree commit 102ee001912 Merge tag 
 'for-usb-next-2013-01-03' 
 
 This patchset is to add usb port power off mechanism and
 merge with patchset usb: expose DeviceRemovable to user space via sysfs 
 attribute.
 
 Patchset usb: expose DeviceRemovable to user space via sysfs attribute.
 http://marc.info/?l=linux-usbm=135279430410171w=2 with some link break 
 corrects
 
 The main discussion about usb port power off mechanism is in the following 
 link:
 http://marc.info/?l=linux-usbm=134818340017208w=2
 
 
 PM/Qos: Expose dev_pm_qos_flags symbol
 usb: Add driver/usb/core/(port.c,hub.h) files
 USB: Set usb port's DeviceRemovable according acpi information
 usb: Add portX/connect_type attribute to expose usb port's connect type
 usb: Create link files between child device and usb port device.
 usb: Register usb port's acpi power resources
 usb: add runtime pm support for usb port device
 usb: add usb port auto power off mechanism
 usb: expose usb port's pm qos flags to user space
 usb: add usb_device_allow_power_off() and usb_device_prevent_power_off() 
 function.
 
Hi GregAlan:
Do you have some more comments about this patchset? Thanks.
 


-- 
Best regards
Tianyu Lan
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: USB device cannot be reconnected and khubd blocked for more than 120 seconds

2013-01-12 Thread Lan Tianyu

On 2013年1月12日 15:48:59, Alex Riesen wrote:

On Fri, Jan 11, 2013 at 10:04 PM, Alex Riesen raa.l...@gmail.com wrote:

Hi,

the USB stick (an Cruzer Titanium 2GB) was not recognized at any of
the USB ports of this system (an System76 lemu4 laptop, XHCI device)
after it was removed. If I attempt to insert it again in any of the
ports (one of the two USB3, or the USB2) the led on the stick lights
up shortly and if off again. There is no media detection messages in
the dmesg output, only that from the first time:

 usb 1-1.2: new high-speed USB device number 3 using ehci-pci
 usb 1-1.2: New USB device found, idVendor=0781, idProduct=5408
 usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
 usb 1-1.2: Product: U3 Titanium
 usb 1-1.2: Manufacturer: SanDisk Corporation
 usb 1-1.2: SerialNumber: 187A3A60F1E9
 scsi6 : usb-storage 1-1.2:1.0
 io scheduler deadline registered (default)
 usb 1-1.2: USB disconnect, device number 3

The kernel is v3.8-rc3. I never had this problem in 3.7. I could almost
reproduce the problem later in a simplified setup (init=/bin/bash) on
USB3 ports by inserting and removing the stick quickly. Almost - because
the USB3 ports recovered after some time, while the USB2 port never
experienced the problem.


One more detail: I usually use the noop elevator. That time it was
the deadline. And I just reproduced it easily with deadline.

Can you provide the output of dmesg with CONFIG_USB_DEBUG? This will
be helpful.

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html




--
Best regards
Tianyu Lan
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Resend PATCH V4 0/10] usb: usb port power off mechanism anc expose usb port connect type

2013-01-11 Thread Lan Tianyu
Change since v1:
   optimize the export connect type patch and adjust the DeviceRemovalbe 
flag
in the rh_call_control() after GetHubDescriptor request being processed.
   move all debounce operation to usb port's runtime resume callback(). Add
did_runtime_put in the struct usb_port to call pm_runtime_get/put(portdev) 
paired.
   using pm_runtime_get/put(portdev) to allow or prohibit device to be power
off inside of pm qos request in the kernel side. 

Change since v2:
   Correct some link breaks. 
   Add did_runtime_put in the usb_disconnect() before calling 
pm_runtime_put(portdev).
   Provide two seperate functions usb_device_allow_power_off() and 
usb_device_prevent_power_off()
instead of just one.

Change since v3:
Set did_runtime_put to false in usb_disconnect() when its value is true
Add comment about not enable port runtime pm if fail to expose port's 
pm qos. and call
pm_runtime_set_active(portdev) unconditionally.
rename usb_device_allow_prevent_power_off with 
usb_device_control_power_off
Modify be power off to be powered off
Expose dev_pm_qos_flags() symbol in order to ensure usb core can 
compile as module. 

Resend v4:
   make patch PM/Qos: Expose dev_pm_qos_flags symbol as first patch to 
avoid compilation
error during git bisect
  correct some comments.

This Patchset is based on usb-next tree commit 102ee001912 Merge tag 
'for-usb-next-2013-01-03' 

This patchset is to add usb port power off mechanism and
merge with patchset usb: expose DeviceRemovable to user space via sysfs 
attribute.

Patchset usb: expose DeviceRemovable to user space via sysfs attribute.
http://marc.info/?l=linux-usbm=135279430410171w=2 with some link break 
corrects

The main discussion about usb port power off mechanism is in the following link:
http://marc.info/?l=linux-usbm=134818340017208w=2


PM/Qos: Expose dev_pm_qos_flags symbol
usb: Add driver/usb/core/(port.c,hub.h) files
USB: Set usb port's DeviceRemovable according acpi information
usb: Add portX/connect_type attribute to expose usb port's connect type
usb: Create link files between child device and usb port device.
usb: Register usb port's acpi power resources
usb: add runtime pm support for usb port device
usb: add usb port auto power off mechanism
usb: expose usb port's pm qos flags to user space
usb: add usb_device_allow_power_off() and usb_device_prevent_power_off() 
function.


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Resend PATCH v4 01/10] PM/Qos: Expose dev_pm_qos_flags symbol

2013-01-11 Thread Lan Tianyu
The dev_pm_qos_flags() will be used in the usb core which could be
compiled as a module. This patch is to export it.

Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/base/power/qos.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c
index ff46387..e26b380 100644
--- a/drivers/base/power/qos.c
+++ b/drivers/base/power/qos.c
@@ -91,6 +91,7 @@ enum pm_qos_flags_status dev_pm_qos_flags(struct device *dev, 
s32 mask)
 
return ret;
 }
+EXPORT_SYMBOL(dev_pm_qos_flags);
 
 /**
  * __dev_pm_qos_read_value - Get PM QoS constraint for a given device.
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Resend PATCH v4 02/10] usb: Add driver/usb/core/(port.c,hub.h) files

2013-01-11 Thread Lan Tianyu
This patch is to create driver/usb/core/(port.c,hub.h) files and move usb
port related code into port.c.

Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/Makefile |1 +
 drivers/usb/core/hub.c|  107 +
 drivers/usb/core/hub.h|   97 
 drivers/usb/core/port.c   |   66 
 4 files changed, 165 insertions(+), 106 deletions(-)
 create mode 100644 drivers/usb/core/hub.h
 create mode 100644 drivers/usb/core/port.c

diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
index 26059b9..5e847ad 100644
--- a/drivers/usb/core/Makefile
+++ b/drivers/usb/core/Makefile
@@ -7,6 +7,7 @@ ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
 usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o
 usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o
 usbcore-y += devio.o notify.o generic.o quirks.o devices.o
+usbcore-y += port.o
 
 usbcore-$(CONFIG_PCI)  += hcd-pci.o
 usbcore-$(CONFIG_ACPI) += usb-acpi.o
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index ae10862..f5caf72 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -30,7 +30,7 @@
 #include asm/uaccess.h
 #include asm/byteorder.h
 
-#include usb.h
+#include hub.h
 
 /* if we are in debug mode, always announce new devices */
 #ifdef DEBUG
@@ -42,62 +42,6 @@
 #define USB_VENDOR_GENESYS_LOGIC   0x05e3
 #define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND   0x01
 
-struct usb_port {
-   struct usb_device *child;
-   struct device dev;
-   struct dev_state *port_owner;
-   enum usb_port_connect_type connect_type;
-};
-
-struct usb_hub {
-   struct device   *intfdev;   /* the interface device */
-   struct usb_device   *hdev;
-   struct kref kref;
-   struct urb  *urb;   /* for interrupt polling pipe */
-
-   /* buffer for urb ... with extra space in case of babble */
-   char(*buffer)[8];
-   union {
-   struct usb_hub_status   hub;
-   struct usb_port_status  port;
-   }   *status;/* buffer for status reports */
-   struct mutexstatus_mutex;   /* for the status buffer */
-
-   int error;  /* last reported error */
-   int nerrors;/* track consecutive errors */
-
-   struct list_headevent_list; /* hubs w/data or errs ready */
-   unsigned long   event_bits[1];  /* status change bitmask */
-   unsigned long   change_bits[1]; /* ports with logical connect
-   status change */
-   unsigned long   busy_bits[1];   /* ports being reset or
-   resumed */
-   unsigned long   removed_bits[1]; /* ports with a removed
-   device present */
-   unsigned long   wakeup_bits[1]; /* ports that have signaled
-   remote wakeup */
-#if USB_MAXCHILDREN  31 /* 8*sizeof(unsigned long) - 1 */
-#error event_bits[] is too short!
-#endif
-
-   struct usb_hub_descriptor *descriptor;  /* class descriptor */
-   struct usb_tt   tt; /* Transaction Translator */
-
-   unsignedmA_per_port;/* current for each child */
-
-   unsignedlimited_power:1;
-   unsignedquiescing:1;
-   unsigneddisconnected:1;
-
-   unsignedquirk_check_port_auto_suspend:1;
-
-   unsignedhas_indicators:1;
-   u8  indicator[USB_MAXCHILDREN];
-   struct delayed_work leds;
-   struct delayed_work init_work;
-   struct usb_port **ports;
-};
-
 static inline int hub_is_superspeed(struct usb_device *hdev)
 {
return (hdev-descriptor.bDeviceProtocol == USB_HUB_PR_SS);
@@ -168,9 +112,6 @@ EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem);
 #define HUB_DEBOUNCE_STEP25
 #define HUB_DEBOUNCE_STABLE 100
 
-#define to_usb_port(_dev) \
-   container_of(_dev, struct usb_port, dev)
-
 static int usb_reset_and_verify_device(struct usb_device *udev);
 
 static inline char *portspeed(struct usb_hub *hub, int portstatus)
@@ -1294,52 +1235,6 @@ static int hub_post_reset(struct usb_interface *intf)
return 0;
 }
 
-static void usb_port_device_release(struct device *dev)
-{
-   struct usb_port *port_dev = to_usb_port(dev);
-
-   kfree(port_dev);
-}
-
-static void usb_hub_remove_port_device(struct usb_hub *hub,
-  int port1)
-{
-   device_unregister(hub-ports[port1 - 1]-dev);
-}
-
-struct device_type usb_port_device_type = {
-   .name = usb_port

[Resend PATCH v4 04/10] usb: Add portX/connect_type attribute to expose usb port's connect type

2013-01-11 Thread Lan Tianyu
Some platforms provide usb port connect types through ACPI. This
patch is to add this new attribute to expose these information
to user space.

Signed-off-by: Lan Tianyu tianyu@intel.com
---
 Documentation/ABI/testing/sysfs-bus-usb |9 +++
 drivers/usb/core/port.c |   43 +++
 2 files changed, 52 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-usb 
b/Documentation/ABI/testing/sysfs-bus-usb
index b6fbe51..c8baaf5 100644
--- a/Documentation/ABI/testing/sysfs-bus-usb
+++ b/Documentation/ABI/testing/sysfs-bus-usb
@@ -227,3 +227,12 @@ Contact:   Lan Tianyu tianyu@intel.com
 Description:
The /sys/bus/usb/devices/.../(hub interface)/portX
is usb port device's sysfs directory.
+
+What:  /sys/bus/usb/devices/.../(hub interface)/portX/connect_type
+Date:  January 2013
+Contact:   Lan Tianyu tianyu@intel.com
+Description:
+   Some platforms provide usb port connect types through ACPI.
+   This attribute is to expose these information to user space.
+   The file will read hotplug, wired and not used if the
+   information is available, and unknown otherwise.
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 2bc1cef..824e90b 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -18,6 +18,48 @@
 
 #include hub.h
 
+static const struct attribute_group *port_dev_group[];
+
+static ssize_t show_port_connect_type(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   struct usb_port *port_dev = to_usb_port(dev);
+   char *result;
+
+   switch (port_dev-connect_type) {
+   case USB_PORT_CONNECT_TYPE_HOT_PLUG:
+   result = hotplug;
+   break;
+   case USB_PORT_CONNECT_TYPE_HARD_WIRED:
+   result = hardwired;
+   break;
+   case USB_PORT_NOT_USED:
+   result = not used;
+   break;
+   default:
+   result = unknown;
+   break;
+   }
+
+   return sprintf(buf, %s\n, result);
+}
+static DEVICE_ATTR(connect_type, S_IRUGO, show_port_connect_type,
+   NULL);
+
+static struct attribute *port_dev_attrs[] = {
+   dev_attr_connect_type.attr,
+   NULL,
+};
+
+static struct attribute_group port_dev_attr_grp = {
+   .attrs = port_dev_attrs,
+};
+
+static const struct attribute_group *port_dev_group[] = {
+   port_dev_attr_grp,
+   NULL,
+};
+
 static void usb_port_device_release(struct device *dev)
 {
struct usb_port *port_dev = to_usb_port(dev);
@@ -43,6 +85,7 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1)
 
hub-ports[port1 - 1] = port_dev;
port_dev-dev.parent = hub-intfdev;
+   port_dev-dev.groups = port_dev_group;
port_dev-dev.type = usb_port_device_type;
dev_set_name(port_dev-dev, port%d, port1);
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Resend PATCH v4 05/10] usb: Create link files between child device and usb port device.

2013-01-11 Thread Lan Tianyu
To show the relationship between usb port and child device,
add link file port under usb device's sysfs directoy and
device under usb port device's sysfs directory. They are linked
to each other.

Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/hub.c |   26 ++
 1 file changed, 26 insertions(+)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 7a893b0..05bdb04 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1978,6 +1978,14 @@ void usb_disconnect(struct usb_device **pdev)
usb_disable_device(udev, 0);
usb_hcd_synchronize_unlinks(udev);
 
+   if (udev-parent) {
+   struct usb_port *port_dev =
+   hdev_to_hub(udev-parent)-ports[udev-portnum - 1];
+
+   sysfs_remove_link(udev-dev.kobj, port);
+   sysfs_remove_link(port_dev-dev.kobj, device);
+   }
+
usb_remove_ep_devs(udev-ep0);
usb_unlock_device(udev);
 
@@ -2270,6 +2278,24 @@ int usb_new_device(struct usb_device *udev)
goto fail;
}
 
+   /* Create link files between child device and usb port device. */
+   if (udev-parent) {
+   struct usb_port *port_dev =
+   hdev_to_hub(udev-parent)-ports[udev-portnum - 1];
+
+   err = sysfs_create_link(udev-dev.kobj,
+   port_dev-dev.kobj, port);
+   if (err)
+   goto fail;
+
+   err = sysfs_create_link(port_dev-dev.kobj,
+   udev-dev.kobj, device);
+   if (err) {
+   sysfs_remove_link(udev-dev.kobj, port);
+   goto fail;
+   }
+   }
+
(void) usb_create_ep_devs(udev-dev, udev-ep0, udev);
usb_mark_last_busy(udev);
pm_runtime_put_sync_autosuspend(udev-dev);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Resend PATCH v4 03/10] USB: Set usb port's DeviceRemovable according acpi information

2013-01-11 Thread Lan Tianyu
ACPI provide _PLD and _UPC aml methods to describe usb port
visibility and connectability. This patch is to add 
usb_hub_adjust_DeviceRemovable()
to adjust usb hub port's DeviceRemovable according ACPI information and invoke 
it in
the rh_call_control(). When hub descriptor request is issued at first time,
usb port device isn't created and usb port is not bound with acpi. So first
hub descriptor request is not changed based on ACPI information. After usb
port devices being created, call usb_hub_adjust_DeviceRemovable in the 
hub_configure()
and then set hub port's DeviceRemovable according ACPI information and this 
also works
for non-root hub.

Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/hcd.c |4 
 drivers/usb/core/hub.c |   48 
 drivers/usb/core/usb.h |3 +++
 3 files changed, 55 insertions(+)

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 4225d5e..6687302 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -619,6 +619,10 @@ nongeneric:
status = hcd-driver-hub_control (hcd,
typeReq, wValue, wIndex,
tbuf, wLength);
+
+   if (typeReq == GetHubDescriptor)
+   usb_hub_adjust_deviceremovable(hcd-self.root_hub,
+   (struct usb_hub_descriptor *)tbuf);
break;
 error:
/* protocol stall on error */
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index f5caf72..7a893b0 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1500,6 +1500,8 @@ static int hub_configure(struct usb_hub *hub,
dev_err(hub-intfdev,
couldn't create port%d device.\n, i + 1);
 
+   usb_hub_adjust_deviceremovable(hdev, hub-descriptor);
+
hub_activate(hub, HUB_INIT);
return 0;
 
@@ -5162,6 +5164,52 @@ usb_get_hub_port_connect_type(struct usb_device *hdev, 
int port1)
return hub-ports[port1 - 1]-connect_type;
 }
 
+void usb_hub_adjust_deviceremovable(struct usb_device *hdev,
+   struct usb_hub_descriptor *desc)
+{
+   enum usb_port_connect_type connect_type;
+   int i;
+
+   if (!hub_is_superspeed(hdev)) {
+   for (i = 1; i = hdev-maxchild; i++) {
+   connect_type =
+   usb_get_hub_port_connect_type(hdev, i);
+
+   if (connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) {
+   u8 mask = 1  (i%8);
+
+   if (!(desc-u.hs.DeviceRemovable[i/8]  mask)) {
+   dev_dbg(hdev-dev, usb port%d's 
DeviceRemovable is changed to 1 according to platform information.\n,
+   i);
+   desc-u.hs.DeviceRemovable[i/8]
+   |= mask;
+   }
+   }
+   }
+   } else {
+   u16 port_removable =
+   le16_to_cpu(desc-u.ss.DeviceRemovable);
+
+   for (i = 1; i = hdev-maxchild; i++) {
+   connect_type =
+   usb_get_hub_port_connect_type(hdev, i);
+
+   if (connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) {
+   u16 mask = 1  i;
+
+   if (!(port_removable  mask)) {
+   dev_dbg(hdev-dev, usb port%d's 
DeviceRemovable is changed to 1 according to platform information.\n,
+   i);
+   port_removable |= mask;
+   }
+   }
+   }
+
+   desc-u.ss.DeviceRemovable =
+   cpu_to_le16(port_removable);
+   }
+}
+
 #ifdef CONFIG_ACPI
 /**
  * usb_get_hub_port_acpi_handle - Get the usb port's acpi handle
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 1c528c1..3f18f2d 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -1,5 +1,6 @@
 #include linux/pm.h
 #include linux/acpi.h
+#include linux/usb/ch11.h
 
 struct dev_state;
 
@@ -173,6 +174,8 @@ extern enum usb_port_connect_type
usb_get_hub_port_connect_type(struct usb_device *hdev, int port1);
 extern void usb_set_hub_port_connect_type(struct usb_device *hdev, int port1,
enum usb_port_connect_type type);
+extern void usb_hub_adjust_deviceremovable(struct usb_device *hdev,
+   struct usb_hub_descriptor *desc);
 
 #ifdef CONFIG_ACPI
 extern int usb_acpi_register(void);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org

[Resend PATCH v4 06/10] usb: Register usb port's acpi power resources

2013-01-11 Thread Lan Tianyu
This patch is to register usb port's acpi power resources. Create
link between usb port device and its acpi power resource.

Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/port.c |3 +++
 drivers/usb/core/usb-acpi.c |   20 
 drivers/usb/core/usb.h  |6 ++
 3 files changed, 29 insertions(+)

diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 824e90b..2365d5e 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -64,6 +64,7 @@ static void usb_port_device_release(struct device *dev)
 {
struct usb_port *port_dev = to_usb_port(dev);
 
+   usb_acpi_unregister_power_resources(dev);
kfree(port_dev);
 }
 
@@ -93,6 +94,8 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1)
if (retval)
goto error_register;
 
+   usb_acpi_register_power_resources(port_dev-dev);
+
return 0;
 
 error_register:
diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
index cef4252..558ab01 100644
--- a/drivers/usb/core/usb-acpi.c
+++ b/drivers/usb/core/usb-acpi.c
@@ -216,6 +216,26 @@ static struct acpi_bus_type usb_acpi_bus = {
.find_device = usb_acpi_find_device,
 };
 
+int usb_acpi_register_power_resources(struct device *dev)
+{
+   acpi_handle port_handle = DEVICE_ACPI_HANDLE(dev);
+
+   if (!port_handle)
+   return -ENODEV;
+
+   if (acpi_power_resource_register_device(dev, port_handle)  0)
+   return -ENODEV;
+   return 0;
+}
+
+void usb_acpi_unregister_power_resources(struct device *dev)
+{
+   acpi_handle port_handle = DEVICE_ACPI_HANDLE(dev);
+
+   if (port_handle)
+   acpi_power_resource_unregister_device(dev, port_handle);
+}
+
 int usb_acpi_register(void)
 {
return register_acpi_bus_type(usb_acpi_bus);
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 3f18f2d..386f562 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -182,7 +182,13 @@ extern int usb_acpi_register(void);
 extern void usb_acpi_unregister(void);
 extern acpi_handle usb_get_hub_port_acpi_handle(struct usb_device *hdev,
int port1);
+extern int usb_acpi_register_power_resources(struct device *dev);
+extern void usb_acpi_unregister_power_resources(struct device *dev);
 #else
 static inline int usb_acpi_register(void) { return 0; };
 static inline void usb_acpi_unregister(void) { };
+static inline int usb_acpi_register_power_resources(struct usb_device *udev)
+   { return 0; };
+static inline int usb_acpi_unregister_power_resources(struct usb_device *udev)
+   { };
 #endif
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Resend PATCH v4 07/10] usb: add runtime pm support for usb port device

2013-01-11 Thread Lan Tianyu
This patch is to add runtime pm callback for usb port device.
Set/clear PORT_POWER feature in the resume/suspend callbak.
Add portnum for struct usb_port to record port number. Do
pm_rumtime_get_sync/put(portdev) when a device is plugged/unplugged
to prevent it from being powered off when it is active.

Acked-by: Rafael J. Wysocki rafael.j.wyso...@intel.com
Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/hub.c  |   18 ++
 drivers/usb/core/hub.h  |4 
 drivers/usb/core/port.c |   43 +++
 3 files changed, 65 insertions(+)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 05bdb04..a0dfdc5 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -714,6 +714,18 @@ static void hub_tt_work(struct work_struct *work)
spin_unlock_irqrestore (hub-tt.lock, flags);
 }
 
+int usb_hub_set_port_power(struct usb_device *hdev, int port1,
+   bool set)
+{
+   int ret;
+
+   if (set)
+   ret = set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
+   else
+   ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
+   return ret;
+}
+
 /**
  * usb_hub_clear_tt_buffer - clear control/bulk TT state in high speed hub
  * @urb: an URB associated with the failed or incomplete split transaction
@@ -1556,6 +1568,7 @@ static void hub_disconnect(struct usb_interface *intf)
kfree(hub-status);
kfree(hub-buffer);
 
+   pm_suspend_ignore_children(intf-dev, false);
kref_put(hub-kref, hub_release);
 }
 
@@ -1658,6 +1671,7 @@ descriptor_error:
 
usb_set_intfdata (intf, hub);
intf-needs_remote_wakeup = 1;
+   pm_suspend_ignore_children(intf-dev, true);
 
if (hdev-speed == USB_SPEED_HIGH)
highspeed_hubs++;
@@ -1984,6 +1998,8 @@ void usb_disconnect(struct usb_device **pdev)
 
sysfs_remove_link(udev-dev.kobj, port);
sysfs_remove_link(port_dev-dev.kobj, device);
+
+   pm_runtime_put(port_dev-dev);
}
 
usb_remove_ep_devs(udev-ep0);
@@ -2294,6 +2310,8 @@ int usb_new_device(struct usb_device *udev)
sysfs_remove_link(udev-dev.kobj, port);
goto fail;
}
+
+   pm_runtime_get_sync(port_dev-dev);
}
 
(void) usb_create_ep_devs(udev-dev, udev-ep0, udev);
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
index d16a7c9..8ea6bc8 100644
--- a/drivers/usb/core/hub.h
+++ b/drivers/usb/core/hub.h
@@ -79,12 +79,14 @@ struct usb_hub {
  * @dev: generic device interface
  * @port_owner: port's owner
  * @connect_type: port's connect type
+ * @portnum: port index num based one
  */
 struct usb_port {
struct usb_device *child;
struct device dev;
struct dev_state *port_owner;
enum usb_port_connect_type connect_type;
+   u8 portnum;
 };
 
 #define to_usb_port(_dev) \
@@ -94,4 +96,6 @@ extern int usb_hub_create_port_device(struct usb_hub *hub,
int port1);
 extern void usb_hub_remove_port_device(struct usb_hub *hub,
int port1);
+extern int usb_hub_set_port_power(struct usb_device *hdev,
+   int port1, bool set);
 
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 2365d5e..a966596 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -17,6 +17,7 @@
  */
 
 #include hub.h
+#include linux/pm_qos.h
 
 static const struct attribute_group *port_dev_group[];
 
@@ -68,9 +69,48 @@ static void usb_port_device_release(struct device *dev)
kfree(port_dev);
 }
 
+static int usb_port_runtime_resume(struct device *dev)
+{
+   struct usb_port *port_dev = to_usb_port(dev);
+   struct usb_device *hdev = to_usb_device(dev-parent-parent);
+   struct usb_interface *intf = to_usb_interface(dev-parent);
+   int retval;
+
+   usb_autopm_get_interface(intf);
+   retval = usb_hub_set_port_power(hdev, port_dev-portnum, true);
+   usb_autopm_put_interface(intf);
+   return retval;
+}
+
+static int usb_port_runtime_suspend(struct device *dev)
+{
+   struct usb_port *port_dev = to_usb_port(dev);
+   struct usb_device *hdev = to_usb_device(dev-parent-parent);
+   struct usb_interface *intf = to_usb_interface(dev-parent);
+   int retval;
+
+   if (dev_pm_qos_flags(port_dev-dev, PM_QOS_FLAG_NO_POWER_OFF)
+   == PM_QOS_FLAGS_ALL)
+   return -EAGAIN;
+
+   usb_autopm_get_interface(intf);
+   retval = usb_hub_set_port_power(hdev, port_dev-portnum, false);
+   usb_autopm_put_interface(intf);
+   return retval;
+}
+
+static const struct dev_pm_ops usb_port_pm_ops = {
+#ifdef CONFIG_USB_SUSPEND
+   .runtime_suspend =  usb_port_runtime_suspend,
+   .runtime_resume =   usb_port_runtime_resume,
+   .runtime_idle = pm_generic_runtime_idle,
+#endif
+};
+
 struct

[Resend PATCH v4 08/10] usb: add usb port auto power off mechanism

2013-01-11 Thread Lan Tianyu
This patch is to add usb port auto power off mechanism.
When usb device is suspending, usb core will suspend usb port and
usb port runtime pm callback will clear PORT_POWER feature to
power off port if all conditions were met. These conditions are
remote wakeup disable, pm qos NO_POWER_OFF flag clear and persist
enable. When it resumes, power on port again. Add did_runtime_put
in the struct usb_port in order to call pm_runtime_get/put(portdev)
paired during suspending and resuming.

Acked-by: Rafael J. Wysocki rafael.j.wyso...@intel.com
Signed-off-by: Lan Tianyu tianyu@intel.com
---
 drivers/usb/core/hub.c  |   65 ---
 drivers/usb/core/hub.h  |9 +++
 drivers/usb/core/port.c |   40 +++--
 3 files changed, 103 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index a0dfdc5..c81d374 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -26,6 +26,7 @@
 #include linux/mutex.h
 #include linux/freezer.h
 #include linux/random.h
+#include linux/pm_qos.h
 
 #include asm/uaccess.h
 #include asm/byteorder.h
@@ -108,7 +109,7 @@ MODULE_PARM_DESC(use_both_schemes,
 DECLARE_RWSEM(ehci_cf_port_reset_rwsem);
 EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem);
 
-#define HUB_DEBOUNCE_TIMEOUT   1500
+#define HUB_DEBOUNCE_TIMEOUT   2000
 #define HUB_DEBOUNCE_STEP25
 #define HUB_DEBOUNCE_STABLE 100
 
@@ -127,7 +128,7 @@ static inline char *portspeed(struct usb_hub *hub, int 
portstatus)
 }
 
 /* Note that hdev or one of its children must be locked! */
-static struct usb_hub *hdev_to_hub(struct usb_device *hdev)
+struct usb_hub *hdev_to_hub(struct usb_device *hdev)
 {
if (!hdev || !hdev-actconfig || !hdev-maxchild)
return NULL;
@@ -393,7 +394,7 @@ static int clear_hub_feature(struct usb_device *hdev, int 
feature)
 /*
  * USB 2.0 spec Section 11.24.2.2
  */
-static int clear_port_feature(struct usb_device *hdev, int port1, int feature)
+int clear_port_feature(struct usb_device *hdev, int port1, int feature)
 {
return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port1,
@@ -718,11 +719,16 @@ int usb_hub_set_port_power(struct usb_device *hdev, int 
port1,
bool set)
 {
int ret;
+   struct usb_hub *hub = hdev_to_hub(hdev);
+   struct usb_port *port_dev = hub-ports[port1 - 1];
 
if (set)
ret = set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
else
ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
+
+   if (!ret)
+   port_dev-power_is_on = set;
return ret;
 }
 
@@ -802,7 +808,11 @@ static unsigned hub_power_on(struct usb_hub *hub, bool 
do_delay)
dev_dbg(hub-intfdev, trying to enable port power on 
non-switchable hub\n);
for (port1 = 1; port1 = hub-descriptor-bNbrPorts; port1++)
-   set_port_feature(hub-hdev, port1, USB_PORT_FEAT_POWER);
+   if (hub-ports[port1 - 1]-power_is_on)
+   set_port_feature(hub-hdev, port1, USB_PORT_FEAT_POWER);
+   else
+   clear_port_feature(hub-hdev, port1,
+   USB_PORT_FEAT_POWER);
 
/* Wait at least 100 msec for power to become stable */
delay = max(pgood_delay, (unsigned) 100);
@@ -1134,10 +1144,16 @@ static void hub_activate(struct usb_hub *hub, enum 
hub_activation_type type)
set_bit(port1, hub-change_bits);
 
} else if (udev-persist_enabled) {
+   struct usb_port *port_dev = hub-ports[port1 - 1];
+
 #ifdef CONFIG_PM
udev-reset_resume = 1;
 #endif
-   set_bit(port1, hub-change_bits);
+   /* Don't set the change_bits when the device
+* was powered off.
+*/
+   if (port_dev-power_is_on)
+   set_bit(port1, hub-change_bits);
 
} else {
/* The power session is gone; tell khubd */
@@ -1999,7 +2015,10 @@ void usb_disconnect(struct usb_device **pdev)
sysfs_remove_link(udev-dev.kobj, port);
sysfs_remove_link(port_dev-dev.kobj, device);
 
-   pm_runtime_put(port_dev-dev);
+   if (!port_dev-did_runtime_put)
+   pm_runtime_put(port_dev-dev);
+   else
+   port_dev-did_runtime_put = false;
}
 
usb_remove_ep_devs(udev-ep0);
@@ -2831,6 +2850,7 @@ EXPORT_SYMBOL_GPL(usb_enable_ltm);
 int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
 {
struct usb_hub  *hub = hdev_to_hub(udev-parent);
+   struct usb_port *port_dev = hub-ports[udev-portnum - 1];
int

  1   2   3   >