All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] PCI PM: Two patches for 2.6.31
@ 2009-05-18 20:46 Rafael J. Wysocki
  2009-05-18 20:51 ` [PATCH 1/2] PCI PM: Follow PCI_PM_CTRL_NO_SOFT_RESET during transitions from D3 Rafael J. Wysocki
                   ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: Rafael J. Wysocki @ 2009-05-18 20:46 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: pm list, Linux PCI, LKML

Hi,

The following two patches change the behavior of pci_raw_set_power_state()
slightly to make if follow the PCI PM specification [1/2] and to prevent it
from setting current_state in a wrong way [2/2].

Please consider for applying.

Best,
Rafael


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 1/2] PCI PM: Follow PCI_PM_CTRL_NO_SOFT_RESET during transitions from D3
  2009-05-18 20:46 [PATCH 0/2] PCI PM: Two patches for 2.6.31 Rafael J. Wysocki
@ 2009-05-18 20:51 ` Rafael J. Wysocki
  2009-06-11 18:26   ` Jesse Barnes
  2009-06-11 18:26   ` Jesse Barnes
  2009-05-18 20:51 ` Rafael J. Wysocki
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 15+ messages in thread
From: Rafael J. Wysocki @ 2009-05-18 20:51 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: pm list, Linux PCI, LKML

From: Rafael J. Wysocki <rjw@sisk.pl>

According to the PCI PM specification (PCI Bus Power Management
Interface Specification, Rev. 1.2, Section 5.4.1) we are supposed to
reinitialize devices that have PCI_PM_CTRL_NO_SOFT_RESET clear during
all transitions from PCI_D3hot to PCI_D0, but we only do it if the
device's current_state field is equal to PCI_UNKNOWN.

This may lead to problems if a device with PCI_PM_CTRL_NO_SOFT_RESET
unset is put into PCI_D3hot at run time by its driver and
pci_set_power_state() is used to put it back into PCI_D0, because in
that case the device will remain uninitialized after
pci_set_power_state() has returned.  Prevent that from happening by
modifying pci_raw_set_power_state() to reinitialize devices with
PCI_PM_CTRL_NO_SOFT_RESET unset during all transitions from D3 to D0.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
 drivers/pci/pci.c |    2 ++
 1 file changed, 2 insertions(+)

Index: linux-2.6/drivers/pci/pci.c
===================================================================
--- linux-2.6.orig/drivers/pci/pci.c
+++ linux-2.6/drivers/pci/pci.c
@@ -480,6 +480,8 @@ static int pci_raw_set_power_state(struc
 		pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
 		pmcsr |= state;
 		break;
+	case PCI_D3hot:
+	case PCI_D3cold:
 	case PCI_UNKNOWN: /* Boot-up */
 		if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot
 		 && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 1/2] PCI PM: Follow PCI_PM_CTRL_NO_SOFT_RESET during transitions from D3
  2009-05-18 20:46 [PATCH 0/2] PCI PM: Two patches for 2.6.31 Rafael J. Wysocki
  2009-05-18 20:51 ` [PATCH 1/2] PCI PM: Follow PCI_PM_CTRL_NO_SOFT_RESET during transitions from D3 Rafael J. Wysocki
@ 2009-05-18 20:51 ` Rafael J. Wysocki
  2009-05-18 20:52 ` [PATCH 2/2] PCI PM: Read device power state from register after updating it Rafael J. Wysocki
  2009-05-18 20:52 ` Rafael J. Wysocki
  3 siblings, 0 replies; 15+ messages in thread
From: Rafael J. Wysocki @ 2009-05-18 20:51 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: Linux PCI, pm list, LKML

From: Rafael J. Wysocki <rjw@sisk.pl>

According to the PCI PM specification (PCI Bus Power Management
Interface Specification, Rev. 1.2, Section 5.4.1) we are supposed to
reinitialize devices that have PCI_PM_CTRL_NO_SOFT_RESET clear during
all transitions from PCI_D3hot to PCI_D0, but we only do it if the
device's current_state field is equal to PCI_UNKNOWN.

This may lead to problems if a device with PCI_PM_CTRL_NO_SOFT_RESET
unset is put into PCI_D3hot at run time by its driver and
pci_set_power_state() is used to put it back into PCI_D0, because in
that case the device will remain uninitialized after
pci_set_power_state() has returned.  Prevent that from happening by
modifying pci_raw_set_power_state() to reinitialize devices with
PCI_PM_CTRL_NO_SOFT_RESET unset during all transitions from D3 to D0.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
 drivers/pci/pci.c |    2 ++
 1 file changed, 2 insertions(+)

Index: linux-2.6/drivers/pci/pci.c
===================================================================
--- linux-2.6.orig/drivers/pci/pci.c
+++ linux-2.6/drivers/pci/pci.c
@@ -480,6 +480,8 @@ static int pci_raw_set_power_state(struc
 		pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
 		pmcsr |= state;
 		break;
+	case PCI_D3hot:
+	case PCI_D3cold:
 	case PCI_UNKNOWN: /* Boot-up */
 		if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot
 		 && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 2/2] PCI PM: Read device power state from register after updating it
  2009-05-18 20:46 [PATCH 0/2] PCI PM: Two patches for 2.6.31 Rafael J. Wysocki
                   ` (2 preceding siblings ...)
  2009-05-18 20:52 ` [PATCH 2/2] PCI PM: Read device power state from register after updating it Rafael J. Wysocki
@ 2009-05-18 20:52 ` Rafael J. Wysocki
  2009-05-26 19:52     ` Rafael J. Wysocki
  3 siblings, 1 reply; 15+ messages in thread
From: Rafael J. Wysocki @ 2009-05-18 20:52 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: pm list, Linux PCI, LKML

From: Rafael J. Wysocki <rjw@sisk.pl>

After attempting to change the power state of a PCI device
pci_raw_set_power_state() doesn't check if the value it wrote into
the device's PCI_PM_CTRL register has been stored in there.  Still,
it modifies the device's current_state field as though that's the
case.  This may cause the driver of the device to think that its
power state has been changed while in fact it hasn't.

To prevent such situations from happening modify
pci_raw_set_power_state() so that it reads the device's PCI_PM_CTRL
register after writing into it and uses the value read from the
register to update the device's current_state field.  Also make it
return -EIO if the new state of the device is not equal to the state
requested by the called.

To distinguish this error condition from the other ones make
pci_raw_set_power_state() return -ENOSYS instead of -EIO when it is
impossible to change the power state of the device, because it
doesn't support the native PCI PM at all or the requested target
state is not supported by it.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
 drivers/pci/pci.c |   10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

Index: linux-2.6/drivers/pci/pci.c
===================================================================
--- linux-2.6.orig/drivers/pci/pci.c
+++ linux-2.6/drivers/pci/pci.c
@@ -446,7 +446,7 @@ static int pci_raw_set_power_state(struc
 		return 0;
 
 	if (!dev->pm_cap)
-		return -EIO;
+		return -ENOSYS;
 
 	if (state < PCI_D0 || state > PCI_D3hot)
 		return -EINVAL;
@@ -465,7 +465,7 @@ static int pci_raw_set_power_state(struc
 	/* check if this device supports the desired state */
 	if ((state == PCI_D1 && !dev->d1_support)
 	   || (state == PCI_D2 && !dev->d2_support))
-		return -EIO;
+		return -ENOSYS;
 
 	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
 
@@ -502,7 +502,11 @@ static int pci_raw_set_power_state(struc
 	else if (state == PCI_D2 || dev->current_state == PCI_D2)
 		udelay(PCI_PM_D2_DELAY);
 
-	dev->current_state = state;
+	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
+	dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK);
+	/* Return error code if we have failed to change the state */
+	if (dev->current_state != state)
+		return -EIO;
 
 	/* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT
 	 * INTERFACE SPECIFICATION, REV. 1.2", a device transitioning

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 2/2] PCI PM: Read device power state from register after updating it
  2009-05-18 20:46 [PATCH 0/2] PCI PM: Two patches for 2.6.31 Rafael J. Wysocki
  2009-05-18 20:51 ` [PATCH 1/2] PCI PM: Follow PCI_PM_CTRL_NO_SOFT_RESET during transitions from D3 Rafael J. Wysocki
  2009-05-18 20:51 ` Rafael J. Wysocki
@ 2009-05-18 20:52 ` Rafael J. Wysocki
  2009-05-18 20:52 ` Rafael J. Wysocki
  3 siblings, 0 replies; 15+ messages in thread
From: Rafael J. Wysocki @ 2009-05-18 20:52 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: Linux PCI, pm list, LKML

From: Rafael J. Wysocki <rjw@sisk.pl>

After attempting to change the power state of a PCI device
pci_raw_set_power_state() doesn't check if the value it wrote into
the device's PCI_PM_CTRL register has been stored in there.  Still,
it modifies the device's current_state field as though that's the
case.  This may cause the driver of the device to think that its
power state has been changed while in fact it hasn't.

To prevent such situations from happening modify
pci_raw_set_power_state() so that it reads the device's PCI_PM_CTRL
register after writing into it and uses the value read from the
register to update the device's current_state field.  Also make it
return -EIO if the new state of the device is not equal to the state
requested by the called.

To distinguish this error condition from the other ones make
pci_raw_set_power_state() return -ENOSYS instead of -EIO when it is
impossible to change the power state of the device, because it
doesn't support the native PCI PM at all or the requested target
state is not supported by it.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
 drivers/pci/pci.c |   10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

Index: linux-2.6/drivers/pci/pci.c
===================================================================
--- linux-2.6.orig/drivers/pci/pci.c
+++ linux-2.6/drivers/pci/pci.c
@@ -446,7 +446,7 @@ static int pci_raw_set_power_state(struc
 		return 0;
 
 	if (!dev->pm_cap)
-		return -EIO;
+		return -ENOSYS;
 
 	if (state < PCI_D0 || state > PCI_D3hot)
 		return -EINVAL;
@@ -465,7 +465,7 @@ static int pci_raw_set_power_state(struc
 	/* check if this device supports the desired state */
 	if ((state == PCI_D1 && !dev->d1_support)
 	   || (state == PCI_D2 && !dev->d2_support))
-		return -EIO;
+		return -ENOSYS;
 
 	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
 
@@ -502,7 +502,11 @@ static int pci_raw_set_power_state(struc
 	else if (state == PCI_D2 || dev->current_state == PCI_D2)
 		udelay(PCI_PM_D2_DELAY);
 
-	dev->current_state = state;
+	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
+	dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK);
+	/* Return error code if we have failed to change the state */
+	if (dev->current_state != state)
+		return -EIO;
 
 	/* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT
 	 * INTERFACE SPECIFICATION, REV. 1.2", a device transitioning

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/2] PCI PM: Read device power state from register after updating it
  2009-05-18 20:52 ` Rafael J. Wysocki
@ 2009-05-26 19:52     ` Rafael J. Wysocki
  0 siblings, 0 replies; 15+ messages in thread
From: Rafael J. Wysocki @ 2009-05-26 19:52 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: pm list, Linux PCI, LKML

On Monday 18 May 2009, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rjw@sisk.pl>
> 
> After attempting to change the power state of a PCI device
> pci_raw_set_power_state() doesn't check if the value it wrote into
> the device's PCI_PM_CTRL register has been stored in there.  Still,
> it modifies the device's current_state field as though that's the
> case.  This may cause the driver of the device to think that its
> power state has been changed while in fact it hasn't.
> 
> To prevent such situations from happening modify
> pci_raw_set_power_state() so that it reads the device's PCI_PM_CTRL
> register after writing into it and uses the value read from the
> register to update the device's current_state field.  Also make it
> return -EIO if the new state of the device is not equal to the state
> requested by the called.
> 
> To distinguish this error condition from the other ones make
> pci_raw_set_power_state() return -ENOSYS instead of -EIO when it is
> impossible to change the power state of the device, because it
> doesn't support the native PCI PM at all or the requested target
> state is not supported by it.

Having reconsidered it I think that -ENODEV is probably better than -ENOSYS for
this purpose.  Updated patch follows.

Thanks,
Rafael

---
From: Rafael J. Wysocki <rjw@sisk.pl>
Subject: PCI PM: Read device power state from register after updating it

After attempting to change the power state of a PCI device
pci_raw_set_power_state() doesn't check if the value it wrote into
the device's PCI_PM_CTRL register has been stored in there.  Still,
it modifies the device's current_state field as though that's the
case.  This may cause the driver of the device to think that its
power state has been changed while in fact it hasn't.

To prevent such situations from happening modify
pci_raw_set_power_state() so that it reads the device's PCI_PM_CTRL
register after writing into it and uses the value read from the
register to update the device's current_state field.  Also make it
return -EIO if the new state of the device is not equal to the state
requested by the called.

To distinguish this error condition from the other ones make
pci_raw_set_power_state() return -ENODEV instead of -EIO when it is
impossible to change the power state of the device, because it
doesn't support the native PCI PM at all or the requested target
state is not supported by it.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
 drivers/pci/pci.c |   10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

Index: linux-2.6/drivers/pci/pci.c
===================================================================
--- linux-2.6.orig/drivers/pci/pci.c
+++ linux-2.6/drivers/pci/pci.c
@@ -446,7 +446,7 @@ static int pci_raw_set_power_state(struc
 		return 0;
 
 	if (!dev->pm_cap)
-		return -EIO;
+		return -ENODEV;
 
 	if (state < PCI_D0 || state > PCI_D3hot)
 		return -EINVAL;
@@ -465,7 +465,7 @@ static int pci_raw_set_power_state(struc
 	/* check if this device supports the desired state */
 	if ((state == PCI_D1 && !dev->d1_support)
 	   || (state == PCI_D2 && !dev->d2_support))
-		return -EIO;
+		return -ENODEV;
 
 	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
 
@@ -502,7 +502,11 @@ static int pci_raw_set_power_state(struc
 	else if (state == PCI_D2 || dev->current_state == PCI_D2)
 		udelay(PCI_PM_D2_DELAY);
 
-	dev->current_state = state;
+	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
+	dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK);
+	/* Return error code if we have failed to change the state */
+	if (dev->current_state != state)
+		return -EIO;
 
 	/* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT
 	 * INTERFACE SPECIFICATION, REV. 1.2", a device transitioning

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/2] PCI PM: Read device power state from register after updating it
@ 2009-05-26 19:52     ` Rafael J. Wysocki
  0 siblings, 0 replies; 15+ messages in thread
From: Rafael J. Wysocki @ 2009-05-26 19:52 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: Linux PCI, pm list, LKML

On Monday 18 May 2009, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rjw@sisk.pl>
> 
> After attempting to change the power state of a PCI device
> pci_raw_set_power_state() doesn't check if the value it wrote into
> the device's PCI_PM_CTRL register has been stored in there.  Still,
> it modifies the device's current_state field as though that's the
> case.  This may cause the driver of the device to think that its
> power state has been changed while in fact it hasn't.
> 
> To prevent such situations from happening modify
> pci_raw_set_power_state() so that it reads the device's PCI_PM_CTRL
> register after writing into it and uses the value read from the
> register to update the device's current_state field.  Also make it
> return -EIO if the new state of the device is not equal to the state
> requested by the called.
> 
> To distinguish this error condition from the other ones make
> pci_raw_set_power_state() return -ENOSYS instead of -EIO when it is
> impossible to change the power state of the device, because it
> doesn't support the native PCI PM at all or the requested target
> state is not supported by it.

Having reconsidered it I think that -ENODEV is probably better than -ENOSYS for
this purpose.  Updated patch follows.

Thanks,
Rafael

---
From: Rafael J. Wysocki <rjw@sisk.pl>
Subject: PCI PM: Read device power state from register after updating it

After attempting to change the power state of a PCI device
pci_raw_set_power_state() doesn't check if the value it wrote into
the device's PCI_PM_CTRL register has been stored in there.  Still,
it modifies the device's current_state field as though that's the
case.  This may cause the driver of the device to think that its
power state has been changed while in fact it hasn't.

To prevent such situations from happening modify
pci_raw_set_power_state() so that it reads the device's PCI_PM_CTRL
register after writing into it and uses the value read from the
register to update the device's current_state field.  Also make it
return -EIO if the new state of the device is not equal to the state
requested by the called.

To distinguish this error condition from the other ones make
pci_raw_set_power_state() return -ENODEV instead of -EIO when it is
impossible to change the power state of the device, because it
doesn't support the native PCI PM at all or the requested target
state is not supported by it.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
 drivers/pci/pci.c |   10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

Index: linux-2.6/drivers/pci/pci.c
===================================================================
--- linux-2.6.orig/drivers/pci/pci.c
+++ linux-2.6/drivers/pci/pci.c
@@ -446,7 +446,7 @@ static int pci_raw_set_power_state(struc
 		return 0;
 
 	if (!dev->pm_cap)
-		return -EIO;
+		return -ENODEV;
 
 	if (state < PCI_D0 || state > PCI_D3hot)
 		return -EINVAL;
@@ -465,7 +465,7 @@ static int pci_raw_set_power_state(struc
 	/* check if this device supports the desired state */
 	if ((state == PCI_D1 && !dev->d1_support)
 	   || (state == PCI_D2 && !dev->d2_support))
-		return -EIO;
+		return -ENODEV;
 
 	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
 
@@ -502,7 +502,11 @@ static int pci_raw_set_power_state(struc
 	else if (state == PCI_D2 || dev->current_state == PCI_D2)
 		udelay(PCI_PM_D2_DELAY);
 
-	dev->current_state = state;
+	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
+	dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK);
+	/* Return error code if we have failed to change the state */
+	if (dev->current_state != state)
+		return -EIO;
 
 	/* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT
 	 * INTERFACE SPECIFICATION, REV. 1.2", a device transitioning

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 1/2] PCI PM: Follow PCI_PM_CTRL_NO_SOFT_RESET during transitions from D3
  2009-05-18 20:51 ` [PATCH 1/2] PCI PM: Follow PCI_PM_CTRL_NO_SOFT_RESET during transitions from D3 Rafael J. Wysocki
@ 2009-06-11 18:26   ` Jesse Barnes
  2009-06-11 18:26   ` Jesse Barnes
  1 sibling, 0 replies; 15+ messages in thread
From: Jesse Barnes @ 2009-06-11 18:26 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: pm list, Linux PCI, LKML

On Mon, 18 May 2009 22:51:12 +0200
"Rafael J. Wysocki" <rjw@sisk.pl> wrote:

> From: Rafael J. Wysocki <rjw@sisk.pl>
> 
> According to the PCI PM specification (PCI Bus Power Management
> Interface Specification, Rev. 1.2, Section 5.4.1) we are supposed to
> reinitialize devices that have PCI_PM_CTRL_NO_SOFT_RESET clear during
> all transitions from PCI_D3hot to PCI_D0, but we only do it if the
> device's current_state field is equal to PCI_UNKNOWN.
> 
> This may lead to problems if a device with PCI_PM_CTRL_NO_SOFT_RESET
> unset is put into PCI_D3hot at run time by its driver and
> pci_set_power_state() is used to put it back into PCI_D0, because in
> that case the device will remain uninitialized after
> pci_set_power_state() has returned.  Prevent that from happening by
> modifying pci_raw_set_power_state() to reinitialize devices with
> PCI_PM_CTRL_NO_SOFT_RESET unset during all transitions from D3 to D0.
> 
> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
> ---
>  drivers/pci/pci.c |    2 ++
>  1 file changed, 2 insertions(+)
> 
> Index: linux-2.6/drivers/pci/pci.c
> ===================================================================
> --- linux-2.6.orig/drivers/pci/pci.c
> +++ linux-2.6/drivers/pci/pci.c
> @@ -480,6 +480,8 @@ static int pci_raw_set_power_state(struc
>  		pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
>  		pmcsr |= state;
>  		break;
> +	case PCI_D3hot:
> +	case PCI_D3cold:
>  	case PCI_UNKNOWN: /* Boot-up */
>  		if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot
>  		 && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
> 

Applied to my linux-next branch, thanks Rafael.  I've also included
stable@kernel.org in the cc, since this is a small but important fix.

-- 
Jesse Barnes, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 1/2] PCI PM: Follow PCI_PM_CTRL_NO_SOFT_RESET during transitions from D3
  2009-05-18 20:51 ` [PATCH 1/2] PCI PM: Follow PCI_PM_CTRL_NO_SOFT_RESET during transitions from D3 Rafael J. Wysocki
  2009-06-11 18:26   ` Jesse Barnes
@ 2009-06-11 18:26   ` Jesse Barnes
  1 sibling, 0 replies; 15+ messages in thread
From: Jesse Barnes @ 2009-06-11 18:26 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: Linux PCI, pm list, LKML

On Mon, 18 May 2009 22:51:12 +0200
"Rafael J. Wysocki" <rjw@sisk.pl> wrote:

> From: Rafael J. Wysocki <rjw@sisk.pl>
> 
> According to the PCI PM specification (PCI Bus Power Management
> Interface Specification, Rev. 1.2, Section 5.4.1) we are supposed to
> reinitialize devices that have PCI_PM_CTRL_NO_SOFT_RESET clear during
> all transitions from PCI_D3hot to PCI_D0, but we only do it if the
> device's current_state field is equal to PCI_UNKNOWN.
> 
> This may lead to problems if a device with PCI_PM_CTRL_NO_SOFT_RESET
> unset is put into PCI_D3hot at run time by its driver and
> pci_set_power_state() is used to put it back into PCI_D0, because in
> that case the device will remain uninitialized after
> pci_set_power_state() has returned.  Prevent that from happening by
> modifying pci_raw_set_power_state() to reinitialize devices with
> PCI_PM_CTRL_NO_SOFT_RESET unset during all transitions from D3 to D0.
> 
> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
> ---
>  drivers/pci/pci.c |    2 ++
>  1 file changed, 2 insertions(+)
> 
> Index: linux-2.6/drivers/pci/pci.c
> ===================================================================
> --- linux-2.6.orig/drivers/pci/pci.c
> +++ linux-2.6/drivers/pci/pci.c
> @@ -480,6 +480,8 @@ static int pci_raw_set_power_state(struc
>  		pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
>  		pmcsr |= state;
>  		break;
> +	case PCI_D3hot:
> +	case PCI_D3cold:
>  	case PCI_UNKNOWN: /* Boot-up */
>  		if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot
>  		 && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
> 

Applied to my linux-next branch, thanks Rafael.  I've also included
stable@kernel.org in the cc, since this is a small but important fix.

-- 
Jesse Barnes, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/2] PCI PM: Read device power state from register after updating it
  2009-05-26 19:52     ` Rafael J. Wysocki
  (?)
  (?)
@ 2009-06-11 18:54     ` Jesse Barnes
  2009-06-11 19:53       ` Rafael J. Wysocki
  2009-06-11 19:53       ` Rafael J. Wysocki
  -1 siblings, 2 replies; 15+ messages in thread
From: Jesse Barnes @ 2009-06-11 18:54 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: pm list, Linux PCI, LKML

On Tue, 26 May 2009 21:52:29 +0200
"Rafael J. Wysocki" <rjw@sisk.pl> wrote:

> On Monday 18 May 2009, Rafael J. Wysocki wrote:
> > From: Rafael J. Wysocki <rjw@sisk.pl>
> > 
> > After attempting to change the power state of a PCI device
> > pci_raw_set_power_state() doesn't check if the value it wrote into
> > the device's PCI_PM_CTRL register has been stored in there.  Still,
> > it modifies the device's current_state field as though that's the
> > case.  This may cause the driver of the device to think that its
> > power state has been changed while in fact it hasn't.
> > 
> > To prevent such situations from happening modify
> > pci_raw_set_power_state() so that it reads the device's PCI_PM_CTRL
> > register after writing into it and uses the value read from the
> > register to update the device's current_state field.  Also make it
> > return -EIO if the new state of the device is not equal to the state
> > requested by the called.
> > 
> > To distinguish this error condition from the other ones make
> > pci_raw_set_power_state() return -ENOSYS instead of -EIO when it is
> > impossible to change the power state of the device, because it
> > doesn't support the native PCI PM at all or the requested target
> > state is not supported by it.
> 
> Having reconsidered it I think that -ENODEV is probably better than
> -ENOSYS for this purpose.  Updated patch follows.

Applied to linux-next, thanks Rafael.

-- 
Jesse Barnes, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/2] PCI PM: Read device power state from register after updating it
  2009-05-26 19:52     ` Rafael J. Wysocki
  (?)
@ 2009-06-11 18:54     ` Jesse Barnes
  -1 siblings, 0 replies; 15+ messages in thread
From: Jesse Barnes @ 2009-06-11 18:54 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: Linux PCI, pm list, LKML

On Tue, 26 May 2009 21:52:29 +0200
"Rafael J. Wysocki" <rjw@sisk.pl> wrote:

> On Monday 18 May 2009, Rafael J. Wysocki wrote:
> > From: Rafael J. Wysocki <rjw@sisk.pl>
> > 
> > After attempting to change the power state of a PCI device
> > pci_raw_set_power_state() doesn't check if the value it wrote into
> > the device's PCI_PM_CTRL register has been stored in there.  Still,
> > it modifies the device's current_state field as though that's the
> > case.  This may cause the driver of the device to think that its
> > power state has been changed while in fact it hasn't.
> > 
> > To prevent such situations from happening modify
> > pci_raw_set_power_state() so that it reads the device's PCI_PM_CTRL
> > register after writing into it and uses the value read from the
> > register to update the device's current_state field.  Also make it
> > return -EIO if the new state of the device is not equal to the state
> > requested by the called.
> > 
> > To distinguish this error condition from the other ones make
> > pci_raw_set_power_state() return -ENOSYS instead of -EIO when it is
> > impossible to change the power state of the device, because it
> > doesn't support the native PCI PM at all or the requested target
> > state is not supported by it.
> 
> Having reconsidered it I think that -ENODEV is probably better than
> -ENOSYS for this purpose.  Updated patch follows.

Applied to linux-next, thanks Rafael.

-- 
Jesse Barnes, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/2] PCI PM: Read device power state from register after updating it
  2009-06-11 18:54     ` Jesse Barnes
  2009-06-11 19:53       ` Rafael J. Wysocki
@ 2009-06-11 19:53       ` Rafael J. Wysocki
  2009-06-11 20:00         ` Jesse Barnes
  2009-06-11 20:00         ` Jesse Barnes
  1 sibling, 2 replies; 15+ messages in thread
From: Rafael J. Wysocki @ 2009-06-11 19:53 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: pm list, Linux PCI, LKML, Jiri Slaby

On Thursday 11 June 2009, Jesse Barnes wrote:
> On Tue, 26 May 2009 21:52:29 +0200
> "Rafael J. Wysocki" <rjw@sisk.pl> wrote:
> 
> > On Monday 18 May 2009, Rafael J. Wysocki wrote:
> > > From: Rafael J. Wysocki <rjw@sisk.pl>
> > > 
> > > After attempting to change the power state of a PCI device
> > > pci_raw_set_power_state() doesn't check if the value it wrote into
> > > the device's PCI_PM_CTRL register has been stored in there.  Still,
> > > it modifies the device's current_state field as though that's the
> > > case.  This may cause the driver of the device to think that its
> > > power state has been changed while in fact it hasn't.
> > > 
> > > To prevent such situations from happening modify
> > > pci_raw_set_power_state() so that it reads the device's PCI_PM_CTRL
> > > register after writing into it and uses the value read from the
> > > register to update the device's current_state field.  Also make it
> > > return -EIO if the new state of the device is not equal to the state
> > > requested by the called.
> > > 
> > > To distinguish this error condition from the other ones make
> > > pci_raw_set_power_state() return -ENOSYS instead of -EIO when it is
> > > impossible to change the power state of the device, because it
> > > doesn't support the native PCI PM at all or the requested target
> > > state is not supported by it.
> > 
> > Having reconsidered it I think that -ENODEV is probably better than
> > -ENOSYS for this purpose.  Updated patch follows.
> 
> Applied to linux-next, thanks Rafael.

Please drop.  It has been reported by Jiri to cause a regression to happen.

Best,
Rafael

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/2] PCI PM: Read device power state from register after updating it
  2009-06-11 18:54     ` Jesse Barnes
@ 2009-06-11 19:53       ` Rafael J. Wysocki
  2009-06-11 19:53       ` Rafael J. Wysocki
  1 sibling, 0 replies; 15+ messages in thread
From: Rafael J. Wysocki @ 2009-06-11 19:53 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: Linux PCI, pm list, LKML, Jiri Slaby

On Thursday 11 June 2009, Jesse Barnes wrote:
> On Tue, 26 May 2009 21:52:29 +0200
> "Rafael J. Wysocki" <rjw@sisk.pl> wrote:
> 
> > On Monday 18 May 2009, Rafael J. Wysocki wrote:
> > > From: Rafael J. Wysocki <rjw@sisk.pl>
> > > 
> > > After attempting to change the power state of a PCI device
> > > pci_raw_set_power_state() doesn't check if the value it wrote into
> > > the device's PCI_PM_CTRL register has been stored in there.  Still,
> > > it modifies the device's current_state field as though that's the
> > > case.  This may cause the driver of the device to think that its
> > > power state has been changed while in fact it hasn't.
> > > 
> > > To prevent such situations from happening modify
> > > pci_raw_set_power_state() so that it reads the device's PCI_PM_CTRL
> > > register after writing into it and uses the value read from the
> > > register to update the device's current_state field.  Also make it
> > > return -EIO if the new state of the device is not equal to the state
> > > requested by the called.
> > > 
> > > To distinguish this error condition from the other ones make
> > > pci_raw_set_power_state() return -ENOSYS instead of -EIO when it is
> > > impossible to change the power state of the device, because it
> > > doesn't support the native PCI PM at all or the requested target
> > > state is not supported by it.
> > 
> > Having reconsidered it I think that -ENODEV is probably better than
> > -ENOSYS for this purpose.  Updated patch follows.
> 
> Applied to linux-next, thanks Rafael.

Please drop.  It has been reported by Jiri to cause a regression to happen.

Best,
Rafael

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/2] PCI PM: Read device power state from register after updating it
  2009-06-11 19:53       ` Rafael J. Wysocki
@ 2009-06-11 20:00         ` Jesse Barnes
  2009-06-11 20:00         ` Jesse Barnes
  1 sibling, 0 replies; 15+ messages in thread
From: Jesse Barnes @ 2009-06-11 20:00 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: pm list, Linux PCI, LKML, Jiri Slaby

On Thu, 11 Jun 2009 12:53:16 -0700
"Rafael J. Wysocki" <rjw@sisk.pl> wrote:

> On Thursday 11 June 2009, Jesse Barnes wrote:
> > On Tue, 26 May 2009 21:52:29 +0200
> > "Rafael J. Wysocki" <rjw@sisk.pl> wrote:
> > 
> > > On Monday 18 May 2009, Rafael J. Wysocki wrote:
> > > > From: Rafael J. Wysocki <rjw@sisk.pl>
> > > > 
> > > > After attempting to change the power state of a PCI device
> > > > pci_raw_set_power_state() doesn't check if the value it wrote
> > > > into the device's PCI_PM_CTRL register has been stored in
> > > > there.  Still, it modifies the device's current_state field as
> > > > though that's the case.  This may cause the driver of the
> > > > device to think that its power state has been changed while in
> > > > fact it hasn't.
> > > > 
> > > > To prevent such situations from happening modify
> > > > pci_raw_set_power_state() so that it reads the device's
> > > > PCI_PM_CTRL register after writing into it and uses the value
> > > > read from the register to update the device's current_state
> > > > field.  Also make it return -EIO if the new state of the device
> > > > is not equal to the state requested by the called.
> > > > 
> > > > To distinguish this error condition from the other ones make
> > > > pci_raw_set_power_state() return -ENOSYS instead of -EIO when
> > > > it is impossible to change the power state of the device,
> > > > because it doesn't support the native PCI PM at all or the
> > > > requested target state is not supported by it.
> > > 
> > > Having reconsidered it I think that -ENODEV is probably better
> > > than -ENOSYS for this purpose.  Updated patch follows.
> > 
> > Applied to linux-next, thanks Rafael.
> 
> Please drop.  It has been reported by Jiri to cause a regression to
> happen.

Ah as I went through the rebase I thought I remembered something like
that.  Will drop.

Thanks,
-- 
Jesse Barnes, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/2] PCI PM: Read device power state from register after updating it
  2009-06-11 19:53       ` Rafael J. Wysocki
  2009-06-11 20:00         ` Jesse Barnes
@ 2009-06-11 20:00         ` Jesse Barnes
  1 sibling, 0 replies; 15+ messages in thread
From: Jesse Barnes @ 2009-06-11 20:00 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: Jiri, Linux PCI, pm list, LKML, Slaby

On Thu, 11 Jun 2009 12:53:16 -0700
"Rafael J. Wysocki" <rjw@sisk.pl> wrote:

> On Thursday 11 June 2009, Jesse Barnes wrote:
> > On Tue, 26 May 2009 21:52:29 +0200
> > "Rafael J. Wysocki" <rjw@sisk.pl> wrote:
> > 
> > > On Monday 18 May 2009, Rafael J. Wysocki wrote:
> > > > From: Rafael J. Wysocki <rjw@sisk.pl>
> > > > 
> > > > After attempting to change the power state of a PCI device
> > > > pci_raw_set_power_state() doesn't check if the value it wrote
> > > > into the device's PCI_PM_CTRL register has been stored in
> > > > there.  Still, it modifies the device's current_state field as
> > > > though that's the case.  This may cause the driver of the
> > > > device to think that its power state has been changed while in
> > > > fact it hasn't.
> > > > 
> > > > To prevent such situations from happening modify
> > > > pci_raw_set_power_state() so that it reads the device's
> > > > PCI_PM_CTRL register after writing into it and uses the value
> > > > read from the register to update the device's current_state
> > > > field.  Also make it return -EIO if the new state of the device
> > > > is not equal to the state requested by the called.
> > > > 
> > > > To distinguish this error condition from the other ones make
> > > > pci_raw_set_power_state() return -ENOSYS instead of -EIO when
> > > > it is impossible to change the power state of the device,
> > > > because it doesn't support the native PCI PM at all or the
> > > > requested target state is not supported by it.
> > > 
> > > Having reconsidered it I think that -ENODEV is probably better
> > > than -ENOSYS for this purpose.  Updated patch follows.
> > 
> > Applied to linux-next, thanks Rafael.
> 
> Please drop.  It has been reported by Jiri to cause a regression to
> happen.

Ah as I went through the rebase I thought I remembered something like
that.  Will drop.

Thanks,
-- 
Jesse Barnes, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2009-06-11 20:01 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-05-18 20:46 [PATCH 0/2] PCI PM: Two patches for 2.6.31 Rafael J. Wysocki
2009-05-18 20:51 ` [PATCH 1/2] PCI PM: Follow PCI_PM_CTRL_NO_SOFT_RESET during transitions from D3 Rafael J. Wysocki
2009-06-11 18:26   ` Jesse Barnes
2009-06-11 18:26   ` Jesse Barnes
2009-05-18 20:51 ` Rafael J. Wysocki
2009-05-18 20:52 ` [PATCH 2/2] PCI PM: Read device power state from register after updating it Rafael J. Wysocki
2009-05-18 20:52 ` Rafael J. Wysocki
2009-05-26 19:52   ` Rafael J. Wysocki
2009-05-26 19:52     ` Rafael J. Wysocki
2009-06-11 18:54     ` Jesse Barnes
2009-06-11 18:54     ` Jesse Barnes
2009-06-11 19:53       ` Rafael J. Wysocki
2009-06-11 19:53       ` Rafael J. Wysocki
2009-06-11 20:00         ` Jesse Barnes
2009-06-11 20:00         ` Jesse Barnes

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.