Re: [patch 2.6.13-rc2] pci: restore BAR values from pci_set_power_state for D3hot->D0

2005-07-27 Thread John W. Linville
On Tue, Jul 26, 2005 at 09:36:02PM -0400, John W. Linville wrote:
> On Tue, Jul 26, 2005 at 04:49:34PM -0700, Greg KH wrote:

> > This code doesn't even build, as need_restore isn't a global variable.
> 
> Hmmm...you must be missing this hunk from the patch posted on July 8?

> > Care to redo this patch (and merge it with your other one) and resend
> > it?
> 
> I'll be happy to do so, and include the other comment tweaks that
> Grant requested.  I should get to it tomorrow morning.

Looks like there was enough change between 8 July and now that patch
(the utility) got confused.  When I applied my 8 July patch against a
current tree, it put the last hunk in some totally different function.
This probably accounts for the compile failure you saw... :-)

New patch (w/ comment tweaks and symbol export) to follow...

John
-- 
John W. Linville
[EMAIL PROTECTED]
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [patch 2.6.13-rc2] pci: restore BAR values from pci_set_power_state for D3hot-D0

2005-07-27 Thread John W. Linville
On Tue, Jul 26, 2005 at 09:36:02PM -0400, John W. Linville wrote:
 On Tue, Jul 26, 2005 at 04:49:34PM -0700, Greg KH wrote:

  This code doesn't even build, as need_restore isn't a global variable.
 
 Hmmm...you must be missing this hunk from the patch posted on July 8?

  Care to redo this patch (and merge it with your other one) and resend
  it?
 
 I'll be happy to do so, and include the other comment tweaks that
 Grant requested.  I should get to it tomorrow morning.

Looks like there was enough change between 8 July and now that patch
(the utility) got confused.  When I applied my 8 July patch against a
current tree, it put the last hunk in some totally different function.
This probably accounts for the compile failure you saw... :-)

New patch (w/ comment tweaks and symbol export) to follow...

John
-- 
John W. Linville
[EMAIL PROTECTED]
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [patch 2.6.13-rc2] pci: restore BAR values from pci_set_power_state for D3hot->D0

2005-07-26 Thread John W. Linville
On Tue, Jul 26, 2005 at 04:49:34PM -0700, Greg KH wrote:
> On Fri, Jul 08, 2005 at 02:34:56PM -0400, John W. Linville wrote:
> > @@ -301,6 +335,16 @@ pci_set_power_state(struct pci_dev *dev,
> > udelay(200);
> > dev->current_state = state;
> >  
> > +   /* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT
> > +* INTERFACE SPECIFICATION, REV. 1.2", a device transitioning
> > +* from D3hot to D0 _may_ perform an internal reset, thereby
> > +* going to "D0 Uninitialized" rather than "D0 Initialized".
> > +* In that case, we need to restore at least the BARs so that
> > +* the device will be accessible to its driver.
> > +*/
> > +   if (need_restore)
> > +   pci_restore_bars(dev);
> > +
> 
> This code doesn't even build, as need_restore isn't a global variable.

Hmmm...you must be missing this hunk from the patch posted on July 8?

@@ -239,7 +270,7 @@ pci_find_parent_resource(const struct pc
 int
 pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 {
-   int pm;
+   int pm, need_restore = 0;
u16 pmcsr, pmc;

/* bound the state we're entering */

 
> Care to redo this patch (and merge it with your other one) and resend
> it?

I'll be happy to do so, and include the other comment tweaks that
Grant requested.  I should get to it tomorrow morning.

Thanks,

John
-- 
John W. Linville
[EMAIL PROTECTED]
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [patch 2.6.13-rc2] pci: restore BAR values from pci_set_power_state for D3hot->D0

2005-07-26 Thread Greg KH
On Fri, Jul 08, 2005 at 02:34:56PM -0400, John W. Linville wrote:
> @@ -301,6 +335,16 @@ pci_set_power_state(struct pci_dev *dev,
>   udelay(200);
>   dev->current_state = state;
>  
> + /* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT
> +  * INTERFACE SPECIFICATION, REV. 1.2", a device transitioning
> +  * from D3hot to D0 _may_ perform an internal reset, thereby
> +  * going to "D0 Uninitialized" rather than "D0 Initialized".
> +  * In that case, we need to restore at least the BARs so that
> +  * the device will be accessible to its driver.
> +  */
> + if (need_restore)
> + pci_restore_bars(dev);
> +

This code doesn't even build, as need_restore isn't a global variable.

Care to redo this patch (and merge it with your other one) and resend
it?

thanks,

greg k-h
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [patch 2.6.13-rc2] pci: restore BAR values from pci_set_power_state for D3hot-D0

2005-07-26 Thread Greg KH
On Fri, Jul 08, 2005 at 02:34:56PM -0400, John W. Linville wrote:
 @@ -301,6 +335,16 @@ pci_set_power_state(struct pci_dev *dev,
   udelay(200);
   dev-current_state = state;
  
 + /* According to section 5.4.1 of the PCI BUS POWER MANAGEMENT
 +  * INTERFACE SPECIFICATION, REV. 1.2, a device transitioning
 +  * from D3hot to D0 _may_ perform an internal reset, thereby
 +  * going to D0 Uninitialized rather than D0 Initialized.
 +  * In that case, we need to restore at least the BARs so that
 +  * the device will be accessible to its driver.
 +  */
 + if (need_restore)
 + pci_restore_bars(dev);
 +

This code doesn't even build, as need_restore isn't a global variable.

Care to redo this patch (and merge it with your other one) and resend
it?

thanks,

greg k-h
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [patch 2.6.13-rc2] pci: restore BAR values from pci_set_power_state for D3hot-D0

2005-07-26 Thread John W. Linville
On Tue, Jul 26, 2005 at 04:49:34PM -0700, Greg KH wrote:
 On Fri, Jul 08, 2005 at 02:34:56PM -0400, John W. Linville wrote:
  @@ -301,6 +335,16 @@ pci_set_power_state(struct pci_dev *dev,
  udelay(200);
  dev-current_state = state;
   
  +   /* According to section 5.4.1 of the PCI BUS POWER MANAGEMENT
  +* INTERFACE SPECIFICATION, REV. 1.2, a device transitioning
  +* from D3hot to D0 _may_ perform an internal reset, thereby
  +* going to D0 Uninitialized rather than D0 Initialized.
  +* In that case, we need to restore at least the BARs so that
  +* the device will be accessible to its driver.
  +*/
  +   if (need_restore)
  +   pci_restore_bars(dev);
  +
 
 This code doesn't even build, as need_restore isn't a global variable.

Hmmm...you must be missing this hunk from the patch posted on July 8?

@@ -239,7 +270,7 @@ pci_find_parent_resource(const struct pc
 int
 pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 {
-   int pm;
+   int pm, need_restore = 0;
u16 pmcsr, pmc;

/* bound the state we're entering */

 
 Care to redo this patch (and merge it with your other one) and resend
 it?

I'll be happy to do so, and include the other comment tweaks that
Grant requested.  I should get to it tomorrow morning.

Thanks,

John
-- 
John W. Linville
[EMAIL PROTECTED]
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [patch 2.6.13-rc2] pci: restore BAR values from pci_set_power_state for D3hot->D0

2005-07-13 Thread John W. Linville
On Mon, Jul 11, 2005 at 10:28:55PM -0400, Adam Belay wrote:
> On Fri, Jul 08, 2005 at 02:34:56PM -0400, John W. Linville wrote:

> > Some firmware leaves devices in D3hot after a (re)boot.  Most drivers
> > call pci_enable_device very early, so devices left in D3hot that lose
> > configuration during the D3hot->D0 transition will be inaccessible to
> > their drivers.
> 
> Also, I think there is a possibility of only enabling boot devices for ACPI
> S4.  However, for the reboot case, we're not restoring anything.  Instead new
> resource assignments are being made.  Doesn't the PCI subsystem already
> handle this?

I'm not sure I understand you...the kernel doesn't actually make the
assignments, relying on the BIOS to do so...am I wrong?

So, if the BIOS leaves a device in D3hot, it will loose it's
BIOS-assigned resources when it transitions to D0 in pci_enable_device.
The point of this patch is to restore those BAR assignments so that
the device's registers will be accessible to the driver.  The driver
remains blissfully unaware of the D3hot->D0 issue.

> >   * pci_set_power_state - Set the power state of a PCI device
> >   * @dev: PCI device to be suspended
> >   * @state: PCI power state (D0, D1, D2, D3hot, D3cold) we're entering
> > @@ -239,7 +270,7 @@ pci_find_parent_resource(const struct pc
> >  int
> >  pci_set_power_state(struct pci_dev *dev, pci_power_t state)
> >  {
> 
> Couldn't this be in pci_restore_state() instead?  I was thinking it would
> (in part) replace the ugly dword reads we have now.  They include many
> registers we don't need to touch.  I wonder if we'll need pci_save_state()
> at all or if we can derive all the information from the pci_dev.  I'll have
> to look into it further.
 
Currently pci_restore_state is only useful if there is a preceding
pci_save_state.  While this commonly occurs in the ->resume routines,
most drivers don't do any such thing (i.e. either save or restore) in
the ->probe routines.  This is likely because it only makes sense to
do so if you know about the D3hot->D0 issue; in that case, we would
be back to replicating code in any number of drivers.  I think we
agree that should be avoided.

> Also we need a way to restore specific PCI capabilities.

If you are asking for additional patches (or more changes to this one)
then you'll have to be more specific.  I don't know what you want here.

Thanks,

John
-- 
John W. Linville
[EMAIL PROTECTED]
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [patch 2.6.13-rc2] pci: restore BAR values from pci_set_power_state for D3hot-D0

2005-07-13 Thread John W. Linville
On Mon, Jul 11, 2005 at 10:28:55PM -0400, Adam Belay wrote:
 On Fri, Jul 08, 2005 at 02:34:56PM -0400, John W. Linville wrote:

  Some firmware leaves devices in D3hot after a (re)boot.  Most drivers
  call pci_enable_device very early, so devices left in D3hot that lose
  configuration during the D3hot-D0 transition will be inaccessible to
  their drivers.
 
 Also, I think there is a possibility of only enabling boot devices for ACPI
 S4.  However, for the reboot case, we're not restoring anything.  Instead new
 resource assignments are being made.  Doesn't the PCI subsystem already
 handle this?

I'm not sure I understand you...the kernel doesn't actually make the
assignments, relying on the BIOS to do so...am I wrong?

So, if the BIOS leaves a device in D3hot, it will loose it's
BIOS-assigned resources when it transitions to D0 in pci_enable_device.
The point of this patch is to restore those BAR assignments so that
the device's registers will be accessible to the driver.  The driver
remains blissfully unaware of the D3hot-D0 issue.

* pci_set_power_state - Set the power state of a PCI device
* @dev: PCI device to be suspended
* @state: PCI power state (D0, D1, D2, D3hot, D3cold) we're entering
  @@ -239,7 +270,7 @@ pci_find_parent_resource(const struct pc
   int
   pci_set_power_state(struct pci_dev *dev, pci_power_t state)
   {
 
 Couldn't this be in pci_restore_state() instead?  I was thinking it would
 (in part) replace the ugly dword reads we have now.  They include many
 registers we don't need to touch.  I wonder if we'll need pci_save_state()
 at all or if we can derive all the information from the pci_dev.  I'll have
 to look into it further.
 
Currently pci_restore_state is only useful if there is a preceding
pci_save_state.  While this commonly occurs in the -resume routines,
most drivers don't do any such thing (i.e. either save or restore) in
the -probe routines.  This is likely because it only makes sense to
do so if you know about the D3hot-D0 issue; in that case, we would
be back to replicating code in any number of drivers.  I think we
agree that should be avoided.

 Also we need a way to restore specific PCI capabilities.

If you are asking for additional patches (or more changes to this one)
then you'll have to be more specific.  I don't know what you want here.

Thanks,

John
-- 
John W. Linville
[EMAIL PROTECTED]
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [patch 2.6.13-rc2] pci: restore BAR values from pci_set_power_state for D3hot->D0

2005-07-11 Thread Adam Belay
On Fri, Jul 08, 2005 at 02:34:56PM -0400, John W. Linville wrote:
> Some PCI devices lose all configuration (including BARs) when
> transitioning from D3hot->D0.  This leaves such a device in an
> inaccessible state.  The patch below causes the BARs to be restored
> when enabling such a device, so that its driver will be able to
> access it.
> 
> Signed-off-by: John W. Linville <[EMAIL PROTECTED]>
> ---
> Some firmware leaves devices in D3hot after a (re)boot.  Most drivers
> call pci_enable_device very early, so devices left in D3hot that lose
> configuration during the D3hot->D0 transition will be inaccessible to
> their drivers.

Also, I think there is a possibility of only enabling boot devices for ACPI
S4.  However, for the reboot case, we're not restoring anything.  Instead new
resource assignments are being made.  Doesn't the PCI subsystem already
handle this?

> 
> Drivers could be modified to account for this, but it would
> be difficult to know which drivers need modification.  This is
> especially true since often many devices are covered by the same
> driver.  It likely would be necessary to replicate code across dozens
> of drivers.

Agreed.

> 
> The patch below should trigger only when transitioning from D3hot->D0
> (or at boot), and only for devices that have the "no soft reset" bit
> cleared in the PM control register.  I believe it is safe to include as
> part of the PCI infrastructure.


>   * pci_set_power_state - Set the power state of a PCI device
>   * @dev: PCI device to be suspended
>   * @state: PCI power state (D0, D1, D2, D3hot, D3cold) we're entering
> @@ -239,7 +270,7 @@ pci_find_parent_resource(const struct pc
>  int
>  pci_set_power_state(struct pci_dev *dev, pci_power_t state)
>  {

Couldn't this be in pci_restore_state() instead?  I was thinking it would
(in part) replace the ugly dword reads we have now.  They include many
registers we don't need to touch.  I wonder if we'll need pci_save_state()
at all or if we can derive all the information from the pci_dev.  I'll have
to look into it further.

Also we need a way to restore specific PCI capabilities.

Thanks,
Adam
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [patch 2.6.13-rc2] pci: restore BAR values from pci_set_power_state for D3hot->D0

2005-07-11 Thread John W. Linville
On Mon, Jul 11, 2005 at 02:48:44PM +0200, Lennert Buytenhek wrote:
> On Fri, Jul 08, 2005 at 02:34:56PM -0400, John W. Linville wrote:
> 
> > Some PCI devices lose all configuration (including BARs) when
> > transitioning from D3hot->D0.  This leaves such a device in an
> > inaccessible state.  The patch below causes the BARs to be restored
> > when enabling such a device, so that its driver will be able to
> > access it.
> 
> It might be useful to have this functionality exported to outside of
> the generic PCI code.

Fine by me...patch to follow...

John
-- 
John W. Linville
[EMAIL PROTECTED]
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [patch 2.6.13-rc2] pci: restore BAR values from pci_set_power_state for D3hot->D0

2005-07-11 Thread Lennert Buytenhek
On Fri, Jul 08, 2005 at 02:34:56PM -0400, John W. Linville wrote:

> Some PCI devices lose all configuration (including BARs) when
> transitioning from D3hot->D0.  This leaves such a device in an
> inaccessible state.  The patch below causes the BARs to be restored
> when enabling such a device, so that its driver will be able to
> access it.

It might be useful to have this functionality exported to outside of
the generic PCI code.

There are a number of PCI boards that have their reset logic wired
up wrong and lose their config space info (BARs) when you reset them.
The Radisys ENP2611 PCI board is a good example -- it has its reset
logic wired in such a way that if you reset the (ARM-based) CPU on
the board, it also causes the 21555 nontransparent PCI bridge on the
board to be reset, which makes it lose all its primary config space
info (BARs, etc.)  The IXP1200 CPU-based PCI cards (now obsolete)
used to suffer from the same issue.

This is currently worked around in the driver, which caches all BAR
values when the module is first loaded, and detects when the card is
reset and then writes back all BARs manually.


--L
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [patch 2.6.13-rc2] pci: restore BAR values from pci_set_power_state for D3hot-D0

2005-07-11 Thread Lennert Buytenhek
On Fri, Jul 08, 2005 at 02:34:56PM -0400, John W. Linville wrote:

 Some PCI devices lose all configuration (including BARs) when
 transitioning from D3hot-D0.  This leaves such a device in an
 inaccessible state.  The patch below causes the BARs to be restored
 when enabling such a device, so that its driver will be able to
 access it.

It might be useful to have this functionality exported to outside of
the generic PCI code.

There are a number of PCI boards that have their reset logic wired
up wrong and lose their config space info (BARs) when you reset them.
The Radisys ENP2611 PCI board is a good example -- it has its reset
logic wired in such a way that if you reset the (ARM-based) CPU on
the board, it also causes the 21555 nontransparent PCI bridge on the
board to be reset, which makes it lose all its primary config space
info (BARs, etc.)  The IXP1200 CPU-based PCI cards (now obsolete)
used to suffer from the same issue.

This is currently worked around in the driver, which caches all BAR
values when the module is first loaded, and detects when the card is
reset and then writes back all BARs manually.


--L
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [patch 2.6.13-rc2] pci: restore BAR values from pci_set_power_state for D3hot-D0

2005-07-11 Thread John W. Linville
On Mon, Jul 11, 2005 at 02:48:44PM +0200, Lennert Buytenhek wrote:
 On Fri, Jul 08, 2005 at 02:34:56PM -0400, John W. Linville wrote:
 
  Some PCI devices lose all configuration (including BARs) when
  transitioning from D3hot-D0.  This leaves such a device in an
  inaccessible state.  The patch below causes the BARs to be restored
  when enabling such a device, so that its driver will be able to
  access it.
 
 It might be useful to have this functionality exported to outside of
 the generic PCI code.

Fine by me...patch to follow...

John
-- 
John W. Linville
[EMAIL PROTECTED]
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [patch 2.6.13-rc2] pci: restore BAR values from pci_set_power_state for D3hot-D0

2005-07-11 Thread Adam Belay
On Fri, Jul 08, 2005 at 02:34:56PM -0400, John W. Linville wrote:
 Some PCI devices lose all configuration (including BARs) when
 transitioning from D3hot-D0.  This leaves such a device in an
 inaccessible state.  The patch below causes the BARs to be restored
 when enabling such a device, so that its driver will be able to
 access it.
 
 Signed-off-by: John W. Linville [EMAIL PROTECTED]
 ---
 Some firmware leaves devices in D3hot after a (re)boot.  Most drivers
 call pci_enable_device very early, so devices left in D3hot that lose
 configuration during the D3hot-D0 transition will be inaccessible to
 their drivers.

Also, I think there is a possibility of only enabling boot devices for ACPI
S4.  However, for the reboot case, we're not restoring anything.  Instead new
resource assignments are being made.  Doesn't the PCI subsystem already
handle this?

 
 Drivers could be modified to account for this, but it would
 be difficult to know which drivers need modification.  This is
 especially true since often many devices are covered by the same
 driver.  It likely would be necessary to replicate code across dozens
 of drivers.

Agreed.

 
 The patch below should trigger only when transitioning from D3hot-D0
 (or at boot), and only for devices that have the no soft reset bit
 cleared in the PM control register.  I believe it is safe to include as
 part of the PCI infrastructure.


   * pci_set_power_state - Set the power state of a PCI device
   * @dev: PCI device to be suspended
   * @state: PCI power state (D0, D1, D2, D3hot, D3cold) we're entering
 @@ -239,7 +270,7 @@ pci_find_parent_resource(const struct pc
  int
  pci_set_power_state(struct pci_dev *dev, pci_power_t state)
  {

Couldn't this be in pci_restore_state() instead?  I was thinking it would
(in part) replace the ugly dword reads we have now.  They include many
registers we don't need to touch.  I wonder if we'll need pci_save_state()
at all or if we can derive all the information from the pci_dev.  I'll have
to look into it further.

Also we need a way to restore specific PCI capabilities.

Thanks,
Adam
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [patch 2.6.13-rc2] pci: restore BAR values from pci_set_power_state for D3hot->D0

2005-07-10 Thread Ivan Kokshaysky
On Fri, Jul 08, 2005 at 02:34:56PM -0400, John W. Linville wrote:
> Some PCI devices lose all configuration (including BARs) when
> transitioning from D3hot->D0.  This leaves such a device in an
> inaccessible state.  The patch below causes the BARs to be restored
> when enabling such a device, so that its driver will be able to
> access it.
> 
> Signed-off-by: John W. Linville <[EMAIL PROTECTED]>

Acked-by: Ivan Kokshaysky <[EMAIL PROTECTED]>

Ivan.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [patch 2.6.13-rc2] pci: restore BAR values from pci_set_power_state for D3hot-D0

2005-07-10 Thread Ivan Kokshaysky
On Fri, Jul 08, 2005 at 02:34:56PM -0400, John W. Linville wrote:
 Some PCI devices lose all configuration (including BARs) when
 transitioning from D3hot-D0.  This leaves such a device in an
 inaccessible state.  The patch below causes the BARs to be restored
 when enabling such a device, so that its driver will be able to
 access it.
 
 Signed-off-by: John W. Linville [EMAIL PROTECTED]

Acked-by: Ivan Kokshaysky [EMAIL PROTECTED]

Ivan.
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [patch 2.6.13-rc2] pci: restore BAR values from pci_set_power_state for D3hot->D0

2005-07-08 Thread David S. Miller
From: "John W. Linville" <[EMAIL PROTECTED]>
Date: Fri, 8 Jul 2005 14:34:56 -0400

> The cleanest implementation of pci_restore_bars was to call
> pci_update_resource.  Unfortunately, that does not currently exist
> for the sparc64 architecture.  The patch below includes a stub
> implemenation of pci_update_resource for sparc64.

I have no problems with the sparc64 part.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[patch 2.6.13-rc2] pci: restore BAR values from pci_set_power_state for D3hot->D0

2005-07-08 Thread John W. Linville
Some PCI devices lose all configuration (including BARs) when
transitioning from D3hot->D0.  This leaves such a device in an
inaccessible state.  The patch below causes the BARs to be restored
when enabling such a device, so that its driver will be able to
access it.

Signed-off-by: John W. Linville <[EMAIL PROTECTED]>
---
Some firmware leaves devices in D3hot after a (re)boot.  Most drivers
call pci_enable_device very early, so devices left in D3hot that lose
configuration during the D3hot->D0 transition will be inaccessible to
their drivers.

Drivers could be modified to account for this, but it would
be difficult to know which drivers need modification.  This is
especially true since often many devices are covered by the same
driver.  It likely would be necessary to replicate code across dozens
of drivers.

The patch below should trigger only when transitioning from D3hot->D0
(or at boot), and only for devices that have the "no soft reset" bit
cleared in the PM control register.  I believe it is safe to include as
part of the PCI infrastructure.

The cleanest implementation of pci_restore_bars was to call
pci_update_resource.  Unfortunately, that does not currently exist
for the sparc64 architecture.  The patch below includes a stub
implemenation of pci_update_resource for sparc64.

 arch/sparc64/kernel/pci.c |6 +
 drivers/pci/pci.c |   52 ++
 drivers/pci/setup-res.c   |2 -
 include/linux/pci.h   |2 +
 4 files changed, 57 insertions(+), 5 deletions(-)

diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -413,6 +413,12 @@ static int pci_assign_bus_resource(const
return -EBUSY;
 }
 
+void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno)
+{
+   /* Not implemented for sparc64... */
+   BUG();
+}
+
 int pci_assign_resource(struct pci_dev *pdev, int resource)
 {
struct pcidev_cookie *pcp = pdev->sysdata;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -222,6 +222,37 @@ pci_find_parent_resource(const struct pc
 }
 
 /**
+ * pci_restore_bars - restore a devices BAR values (e.g. after wake-up)
+ * @dev: PCI device to have its BARs restored
+ *
+ * Restore the BAR values for a given device, so as to make it
+ * accessible by its driver.
+ */
+static void
+pci_restore_bars(struct pci_dev *dev)
+{
+   int i, numres;
+
+   switch (dev->hdr_type) {
+   case PCI_HEADER_TYPE_NORMAL:
+   numres = 6;
+   break;
+   case PCI_HEADER_TYPE_BRIDGE:
+   numres = 2;
+   break;
+   case PCI_HEADER_TYPE_CARDBUS:
+   numres = 1;
+   break;
+   default:
+   /* Should never get here, but just in case... */
+   return;
+   }
+
+   for (i = 0; i < numres; i ++)
+   pci_update_resource(dev, >resource[i], i);
+}
+
+/**
  * pci_set_power_state - Set the power state of a PCI device
  * @dev: PCI device to be suspended
  * @state: PCI power state (D0, D1, D2, D3hot, D3cold) we're entering
@@ -239,7 +270,7 @@ pci_find_parent_resource(const struct pc
 int
 pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 {
-   int pm;
+   int pm, need_restore = 0;
u16 pmcsr, pmc;
 
/* bound the state we're entering */
@@ -278,14 +309,17 @@ pci_set_power_state(struct pci_dev *dev,
return -EIO;
}
 
+   pci_read_config_word(dev, pm + PCI_PM_CTRL, );
+
/* If we're in D3, force entire word to 0.
 * This doesn't affect PME_Status, disables PME_En, and
 * sets PowerState to 0.
 */
-   if (dev->current_state >= PCI_D3hot)
+   if (dev->current_state >= PCI_D3hot) {
+   if (!(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
+   need_restore = 1;
pmcsr = 0;
-   else {
-   pci_read_config_word(dev, pm + PCI_PM_CTRL, );
+   } else {
pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
pmcsr |= state;
}
@@ -301,6 +335,16 @@ pci_set_power_state(struct pci_dev *dev,
udelay(200);
dev->current_state = state;
 
+   /* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT
+* INTERFACE SPECIFICATION, REV. 1.2", a device transitioning
+* from D3hot to D0 _may_ perform an internal reset, thereby
+* going to "D0 Uninitialized" rather than "D0 Initialized".
+* In that case, we need to restore at least the BARs so that
+* the device will be accessible to its driver.
+*/
+   if (need_restore)
+   pci_restore_bars(dev);
+
return 0;
 }
 
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -26,7 +26,7 @@
 #include "pci.h"
 
 
-static 

Re: [linux-pm] [patch 2.6.13-rc2] pci: restore BAR values in pci_set_power_state for D3hot->D0

2005-07-08 Thread John W. Linville
On Thu, Jul 07, 2005 at 08:43:02PM -0700, [EMAIL PROTECTED] wrote:
> > Some PCI devices lose all configuration (including BARs) when
> > transitioning from D3hot->D0.  This leaves such a device in an

> Hmm, I wonder if I missed something in previous email, but exactly
> why isn't this the responsibility of the driver for that device?

It certainly could be handled that way.  Of course, that could
mean replicating essentially identical code across dozens (or more)
drivers.  Plus, many of those drivers might only need such changes for
one variation of a device or for devices under a handful of BIOSen.
Those drivers probably won't get fixed anytime soon unless some kernel
hacker happens to stumble into such a situation.  In the meantime,
those drivers fail to work when they "should" be working.

In my mind, this is a documented behaviour that should not be
unexpected.  It is not some random quirk of some oddball device.
A few simple steps taken when this situation is recognized can allow
drivers to remain unaware of this detail of PCI PM.  That seems
worthwhile to me.

John
-- 
John W. Linville
[EMAIL PROTECTED]
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [linux-pm] [patch 2.6.13-rc2] pci: restore BAR values in pci_set_power_state for D3hot-D0

2005-07-08 Thread John W. Linville
On Thu, Jul 07, 2005 at 08:43:02PM -0700, [EMAIL PROTECTED] wrote:
  Some PCI devices lose all configuration (including BARs) when
  transitioning from D3hot-D0.  This leaves such a device in an

 Hmm, I wonder if I missed something in previous email, but exactly
 why isn't this the responsibility of the driver for that device?

It certainly could be handled that way.  Of course, that could
mean replicating essentially identical code across dozens (or more)
drivers.  Plus, many of those drivers might only need such changes for
one variation of a device or for devices under a handful of BIOSen.
Those drivers probably won't get fixed anytime soon unless some kernel
hacker happens to stumble into such a situation.  In the meantime,
those drivers fail to work when they should be working.

In my mind, this is a documented behaviour that should not be
unexpected.  It is not some random quirk of some oddball device.
A few simple steps taken when this situation is recognized can allow
drivers to remain unaware of this detail of PCI PM.  That seems
worthwhile to me.

John
-- 
John W. Linville
[EMAIL PROTECTED]
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[patch 2.6.13-rc2] pci: restore BAR values from pci_set_power_state for D3hot-D0

2005-07-08 Thread John W. Linville
Some PCI devices lose all configuration (including BARs) when
transitioning from D3hot-D0.  This leaves such a device in an
inaccessible state.  The patch below causes the BARs to be restored
when enabling such a device, so that its driver will be able to
access it.

Signed-off-by: John W. Linville [EMAIL PROTECTED]
---
Some firmware leaves devices in D3hot after a (re)boot.  Most drivers
call pci_enable_device very early, so devices left in D3hot that lose
configuration during the D3hot-D0 transition will be inaccessible to
their drivers.

Drivers could be modified to account for this, but it would
be difficult to know which drivers need modification.  This is
especially true since often many devices are covered by the same
driver.  It likely would be necessary to replicate code across dozens
of drivers.

The patch below should trigger only when transitioning from D3hot-D0
(or at boot), and only for devices that have the no soft reset bit
cleared in the PM control register.  I believe it is safe to include as
part of the PCI infrastructure.

The cleanest implementation of pci_restore_bars was to call
pci_update_resource.  Unfortunately, that does not currently exist
for the sparc64 architecture.  The patch below includes a stub
implemenation of pci_update_resource for sparc64.

 arch/sparc64/kernel/pci.c |6 +
 drivers/pci/pci.c |   52 ++
 drivers/pci/setup-res.c   |2 -
 include/linux/pci.h   |2 +
 4 files changed, 57 insertions(+), 5 deletions(-)

diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -413,6 +413,12 @@ static int pci_assign_bus_resource(const
return -EBUSY;
 }
 
+void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno)
+{
+   /* Not implemented for sparc64... */
+   BUG();
+}
+
 int pci_assign_resource(struct pci_dev *pdev, int resource)
 {
struct pcidev_cookie *pcp = pdev-sysdata;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -222,6 +222,37 @@ pci_find_parent_resource(const struct pc
 }
 
 /**
+ * pci_restore_bars - restore a devices BAR values (e.g. after wake-up)
+ * @dev: PCI device to have its BARs restored
+ *
+ * Restore the BAR values for a given device, so as to make it
+ * accessible by its driver.
+ */
+static void
+pci_restore_bars(struct pci_dev *dev)
+{
+   int i, numres;
+
+   switch (dev-hdr_type) {
+   case PCI_HEADER_TYPE_NORMAL:
+   numres = 6;
+   break;
+   case PCI_HEADER_TYPE_BRIDGE:
+   numres = 2;
+   break;
+   case PCI_HEADER_TYPE_CARDBUS:
+   numres = 1;
+   break;
+   default:
+   /* Should never get here, but just in case... */
+   return;
+   }
+
+   for (i = 0; i  numres; i ++)
+   pci_update_resource(dev, dev-resource[i], i);
+}
+
+/**
  * pci_set_power_state - Set the power state of a PCI device
  * @dev: PCI device to be suspended
  * @state: PCI power state (D0, D1, D2, D3hot, D3cold) we're entering
@@ -239,7 +270,7 @@ pci_find_parent_resource(const struct pc
 int
 pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 {
-   int pm;
+   int pm, need_restore = 0;
u16 pmcsr, pmc;
 
/* bound the state we're entering */
@@ -278,14 +309,17 @@ pci_set_power_state(struct pci_dev *dev,
return -EIO;
}
 
+   pci_read_config_word(dev, pm + PCI_PM_CTRL, pmcsr);
+
/* If we're in D3, force entire word to 0.
 * This doesn't affect PME_Status, disables PME_En, and
 * sets PowerState to 0.
 */
-   if (dev-current_state = PCI_D3hot)
+   if (dev-current_state = PCI_D3hot) {
+   if (!(pmcsr  PCI_PM_CTRL_NO_SOFT_RESET))
+   need_restore = 1;
pmcsr = 0;
-   else {
-   pci_read_config_word(dev, pm + PCI_PM_CTRL, pmcsr);
+   } else {
pmcsr = ~PCI_PM_CTRL_STATE_MASK;
pmcsr |= state;
}
@@ -301,6 +335,16 @@ pci_set_power_state(struct pci_dev *dev,
udelay(200);
dev-current_state = state;
 
+   /* According to section 5.4.1 of the PCI BUS POWER MANAGEMENT
+* INTERFACE SPECIFICATION, REV. 1.2, a device transitioning
+* from D3hot to D0 _may_ perform an internal reset, thereby
+* going to D0 Uninitialized rather than D0 Initialized.
+* In that case, we need to restore at least the BARs so that
+* the device will be accessible to its driver.
+*/
+   if (need_restore)
+   pci_restore_bars(dev);
+
return 0;
 }
 
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -26,7 +26,7 @@
 #include pci.h
 
 
-static void
+void
 

Re: [patch 2.6.13-rc2] pci: restore BAR values from pci_set_power_state for D3hot-D0

2005-07-08 Thread David S. Miller
From: John W. Linville [EMAIL PROTECTED]
Date: Fri, 8 Jul 2005 14:34:56 -0400

 The cleanest implementation of pci_restore_bars was to call
 pci_update_resource.  Unfortunately, that does not currently exist
 for the sparc64 architecture.  The patch below includes a stub
 implemenation of pci_update_resource for sparc64.

I have no problems with the sparc64 part.
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [linux-pm] [patch 2.6.13-rc2] pci: restore BAR values in pci_set_power_state for D3hot->D0

2005-07-07 Thread david-b
> Some PCI devices lose all configuration (including BARs) when
> transitioning from D3hot->D0.  This leaves such a device in an
> inaccessible state.  The patch below causes the BARs to be restored
> when enabling such a device, so that its driver will be able to
> access it.

Hmm, I wonder if I missed something in previous email, but exactly
why isn't this the responsibility of the driver for that device?
It's only one of several similar issues, and not necessarily the
dominant one.

We had to address this D3hot->D0uninitialized issue for various USB
HCDs, in conjunction with similar problems wherein BIOS or swsusp
may also have stuck their nasty little fingers in the middle of the
power state transitions.  (And similarly, the variability of system
sleep states putting a USB controller into D3hot or D3cold... not
always with system wakeup capabilities.)

There, it was relatively straightforward to NOT involve the PCI layer;
and given the complications with BIOS, "legacy PCI" hardware (without
PCI PM support), and swsusp (plus different types of hardware support
even for hardware that does support PCI PM) more or less essential not
to do so.  Though to be sure, it did involve PCI-specific usbcore glue
code in hcd-pci.c; the PCI PM framework seemed to maybe expect less
variation in system behavior than seems routine with USB controllers.
But all that's just to condition things so the HCDs more or less see
a limited and sane set of states in their resume() methods.

- Dave

p.s. Until I sort out some mailer issues, it seems like my email
  is getting filtered from many lists; remember that for followups.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[patch 2.6.13-rc2] pci: restore BAR values in pci_set_power_state for D3hot->D0

2005-07-07 Thread John W. Linville
Some PCI devices lose all configuration (including BARs) when
transitioning from D3hot->D0.  This leaves such a device in an
inaccessible state.  The patch below causes the BARs to be restored
when enabling such a device, so that its driver will be able to
access it.

Signed-off-by: John W. Linville <[EMAIL PROTECTED]>
---
Some firmware leaves devices in D3hot after a (re)boot.  Most drivers
call pci_enable_device very early, so devices left in D3hot that lose
configuration during the D3hot->D0 transition will be inaccessible to
their drivers.

Drivers could be modified to account for this, but it would
be difficult to know which drivers need modification.  This is
especially true since often many devices are covered by the same
driver.  It likely would be necessary to replicate code across dozens
of drivers.

The patch below should trigger only when transitioning from D3hot->D0
(or at boot), and only for devices that have the "no soft reset" bit
cleared in the PM control register.  I believe it is safe to include as
part of the PCI infrastructure.

 drivers/pci/pci.c   |   74 +---
 include/linux/pci.h |1 
 2 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -222,6 +222,59 @@ pci_find_parent_resource(const struct pc
 }
 
 /**
+ * pci_restore_bars - restore a devices BAR values (e.g. after wake-up)
+ * @dev: PCI device to have its BARs restored
+ *
+ * Restore the BAR values for a given device, so as to make it
+ * accessible by its driver.
+ */
+static void
+pci_restore_bars(struct pci_dev *dev)
+{
+   int i, numres;
+
+   switch (dev->hdr_type) {
+   case PCI_HEADER_TYPE_NORMAL:
+   numres = 6;
+   break;
+   case PCI_HEADER_TYPE_BRIDGE:
+   numres = 2;
+   break;
+   case PCI_HEADER_TYPE_CARDBUS:
+   numres = 1;
+   break;
+   default:
+   /* Should never get here, but just in case... */
+   return;
+   }
+
+   for (i = 0; i < numres; i ++) {
+   struct pci_bus_region region;
+   u32 val;
+   int reg;
+
+   if (!dev->resource[i].flags)
+   continue;
+
+   pcibios_resource_to_bus(dev, , >resource[i]);
+
+   val = region.start
+   | (dev->resource[i].flags & PCI_REGION_FLAG_MASK);
+
+   reg = PCI_BASE_ADDRESS_0 + (i * 4);
+
+   pci_write_config_dword(dev, reg, val);
+
+   if ((val & (PCI_BASE_ADDRESS_SPACE
+ | PCI_BASE_ADDRESS_MEM_TYPE_MASK))
+== (PCI_BASE_ADDRESS_SPACE_MEMORY
+  | PCI_BASE_ADDRESS_MEM_TYPE_64)) {
+   pci_write_config_dword(dev, reg + 4, 0);
+   }
+   }
+}
+
+/**
  * pci_set_power_state - Set the power state of a PCI device
  * @dev: PCI device to be suspended
  * @state: PCI power state (D0, D1, D2, D3hot, D3cold) we're entering
@@ -239,7 +292,7 @@ pci_find_parent_resource(const struct pc
 int
 pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 {
-   int pm;
+   int pm, need_restore = 0;
u16 pmcsr, pmc;
 
/* bound the state we're entering */
@@ -278,14 +331,17 @@ pci_set_power_state(struct pci_dev *dev,
return -EIO;
}
 
+   pci_read_config_word(dev, pm + PCI_PM_CTRL, );
+
/* If we're in D3, force entire word to 0.
 * This doesn't affect PME_Status, disables PME_En, and
 * sets PowerState to 0.
 */
-   if (dev->current_state >= PCI_D3hot)
+   if (dev->current_state >= PCI_D3hot) {
+   if (!(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
+   need_restore = 1;
pmcsr = 0;
-   else {
-   pci_read_config_word(dev, pm + PCI_PM_CTRL, );
+   } else {
pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
pmcsr |= state;
}
@@ -301,6 +357,16 @@ pci_set_power_state(struct pci_dev *dev,
udelay(200);
dev->current_state = state;
 
+   /* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT
+* INTERFACE SPECIFICATION, REV. 1.2", a device transitioning
+* from D3hot to D0 _may_ perform an internal reset, thereby
+* going to "D0 Uninitialized" rather than "D0 Initialized".
+* In that case, we need to restore at least the BARs so that
+* the device will be accessible to its driver.
+*/
+   if (need_restore)
+   pci_restore_bars(dev);
+
return 0;
 }
 
diff --git a/include/linux/pci.h b/include/linux/pci.h
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -225,6 +225,7 @@
 #define  PCI_PM_CAP_PME_D3cold  0x8000  /* PME# from D3 (cold) */
 #define PCI_PM_CTRL4   /* PM control and status 

[patch 2.6.13-rc2] pci: restore BAR values in pci_set_power_state for D3hot-D0

2005-07-07 Thread John W. Linville
Some PCI devices lose all configuration (including BARs) when
transitioning from D3hot-D0.  This leaves such a device in an
inaccessible state.  The patch below causes the BARs to be restored
when enabling such a device, so that its driver will be able to
access it.

Signed-off-by: John W. Linville [EMAIL PROTECTED]
---
Some firmware leaves devices in D3hot after a (re)boot.  Most drivers
call pci_enable_device very early, so devices left in D3hot that lose
configuration during the D3hot-D0 transition will be inaccessible to
their drivers.

Drivers could be modified to account for this, but it would
be difficult to know which drivers need modification.  This is
especially true since often many devices are covered by the same
driver.  It likely would be necessary to replicate code across dozens
of drivers.

The patch below should trigger only when transitioning from D3hot-D0
(or at boot), and only for devices that have the no soft reset bit
cleared in the PM control register.  I believe it is safe to include as
part of the PCI infrastructure.

 drivers/pci/pci.c   |   74 +---
 include/linux/pci.h |1 
 2 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -222,6 +222,59 @@ pci_find_parent_resource(const struct pc
 }
 
 /**
+ * pci_restore_bars - restore a devices BAR values (e.g. after wake-up)
+ * @dev: PCI device to have its BARs restored
+ *
+ * Restore the BAR values for a given device, so as to make it
+ * accessible by its driver.
+ */
+static void
+pci_restore_bars(struct pci_dev *dev)
+{
+   int i, numres;
+
+   switch (dev-hdr_type) {
+   case PCI_HEADER_TYPE_NORMAL:
+   numres = 6;
+   break;
+   case PCI_HEADER_TYPE_BRIDGE:
+   numres = 2;
+   break;
+   case PCI_HEADER_TYPE_CARDBUS:
+   numres = 1;
+   break;
+   default:
+   /* Should never get here, but just in case... */
+   return;
+   }
+
+   for (i = 0; i  numres; i ++) {
+   struct pci_bus_region region;
+   u32 val;
+   int reg;
+
+   if (!dev-resource[i].flags)
+   continue;
+
+   pcibios_resource_to_bus(dev, region, dev-resource[i]);
+
+   val = region.start
+   | (dev-resource[i].flags  PCI_REGION_FLAG_MASK);
+
+   reg = PCI_BASE_ADDRESS_0 + (i * 4);
+
+   pci_write_config_dword(dev, reg, val);
+
+   if ((val  (PCI_BASE_ADDRESS_SPACE
+ | PCI_BASE_ADDRESS_MEM_TYPE_MASK))
+== (PCI_BASE_ADDRESS_SPACE_MEMORY
+  | PCI_BASE_ADDRESS_MEM_TYPE_64)) {
+   pci_write_config_dword(dev, reg + 4, 0);
+   }
+   }
+}
+
+/**
  * pci_set_power_state - Set the power state of a PCI device
  * @dev: PCI device to be suspended
  * @state: PCI power state (D0, D1, D2, D3hot, D3cold) we're entering
@@ -239,7 +292,7 @@ pci_find_parent_resource(const struct pc
 int
 pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 {
-   int pm;
+   int pm, need_restore = 0;
u16 pmcsr, pmc;
 
/* bound the state we're entering */
@@ -278,14 +331,17 @@ pci_set_power_state(struct pci_dev *dev,
return -EIO;
}
 
+   pci_read_config_word(dev, pm + PCI_PM_CTRL, pmcsr);
+
/* If we're in D3, force entire word to 0.
 * This doesn't affect PME_Status, disables PME_En, and
 * sets PowerState to 0.
 */
-   if (dev-current_state = PCI_D3hot)
+   if (dev-current_state = PCI_D3hot) {
+   if (!(pmcsr  PCI_PM_CTRL_NO_SOFT_RESET))
+   need_restore = 1;
pmcsr = 0;
-   else {
-   pci_read_config_word(dev, pm + PCI_PM_CTRL, pmcsr);
+   } else {
pmcsr = ~PCI_PM_CTRL_STATE_MASK;
pmcsr |= state;
}
@@ -301,6 +357,16 @@ pci_set_power_state(struct pci_dev *dev,
udelay(200);
dev-current_state = state;
 
+   /* According to section 5.4.1 of the PCI BUS POWER MANAGEMENT
+* INTERFACE SPECIFICATION, REV. 1.2, a device transitioning
+* from D3hot to D0 _may_ perform an internal reset, thereby
+* going to D0 Uninitialized rather than D0 Initialized.
+* In that case, we need to restore at least the BARs so that
+* the device will be accessible to its driver.
+*/
+   if (need_restore)
+   pci_restore_bars(dev);
+
return 0;
 }
 
diff --git a/include/linux/pci.h b/include/linux/pci.h
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -225,6 +225,7 @@
 #define  PCI_PM_CAP_PME_D3cold  0x8000  /* PME# from D3 (cold) */
 #define PCI_PM_CTRL4   /* PM control and status register */
 

Re: [linux-pm] [patch 2.6.13-rc2] pci: restore BAR values in pci_set_power_state for D3hot-D0

2005-07-07 Thread david-b
 Some PCI devices lose all configuration (including BARs) when
 transitioning from D3hot-D0.  This leaves such a device in an
 inaccessible state.  The patch below causes the BARs to be restored
 when enabling such a device, so that its driver will be able to
 access it.

Hmm, I wonder if I missed something in previous email, but exactly
why isn't this the responsibility of the driver for that device?
It's only one of several similar issues, and not necessarily the
dominant one.

We had to address this D3hot-D0uninitialized issue for various USB
HCDs, in conjunction with similar problems wherein BIOS or swsusp
may also have stuck their nasty little fingers in the middle of the
power state transitions.  (And similarly, the variability of system
sleep states putting a USB controller into D3hot or D3cold... not
always with system wakeup capabilities.)

There, it was relatively straightforward to NOT involve the PCI layer;
and given the complications with BIOS, legacy PCI hardware (without
PCI PM support), and swsusp (plus different types of hardware support
even for hardware that does support PCI PM) more or less essential not
to do so.  Though to be sure, it did involve PCI-specific usbcore glue
code in hcd-pci.c; the PCI PM framework seemed to maybe expect less
variation in system behavior than seems routine with USB controllers.
But all that's just to condition things so the HCDs more or less see
a limited and sane set of states in their resume() methods.

- Dave

p.s. Until I sort out some mailer issues, it seems like my email
  is getting filtered from many lists; remember that for followups.

-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/