Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 25 Jan 2011 13:55:53 -0500
From:      John Baldwin <jhb@freebsd.org>
To:        freebsd-hackers@freebsd.org, philip-freebsd1@soeberg.net
Cc:        Warner Losh <imp@freebsd.org>
Subject:   Re: pci_suspend/pci_resume of custom pcie board
Message-ID:  <201101251355.53944.jhb@freebsd.org>
In-Reply-To: <4D3EE287.3010203@soeberg.net>
References:  <4D3EE287.3010203@soeberg.net>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tuesday, January 25, 2011 9:47:35 am Philip Soeberg wrote:
> Hi,
> 
> I'm in a particular problem where I need to set my custom pcie adapter 
> into d3hot power-mode and a couple of seconds later reset it back to d0.
> The board has an FPGA directly attached to the pcie interface, and as I 
> need to re-configure the FPGA on the fly, I have to ensure the datalink 
> layer between the upstream bridge and my device is idle to prevent any 
> hickups.
> 
> On linux I simply do a pci_save_state(device) followed by 
> pci_set_power_state(device, d3hot), then after my magic on my board, I 
> do the reverse: pci_set_power_state(device, d0) followed by 
> pci_restore_state(device).
> 
> On FreeBSD, say 8, I've found the pci_set_powerstate function, which is 
> documented in PCI(9), but that function does not save nor restore the 
> config space.
> 
> I've tried, just for the fun of it, to go via pci_cfg_save(device, 
> dinfo, 0) with dinfo being device_get_ivars(device) and then 
> subsequently restoring the config space back via pci_cfg_restore(), but 
> since both those functions are declared in <dev/pci/pci_private.h> I'm 
> not sure if I'm supposed to use those directly or not.. Besides, I'm not 
> really having any luck with that approach.
> 
> Reading high and low on the net suggest that not all too many driver 
> devs are concerned with suspend/resume operation of their device, and if 
> they are, leave it to user-space to decide when to suspend/resume a 
> device.. I would like to be able to save off my device' config space, 
> put it to sleep (d3hot), wake it back up (d0) and restore the device' 
> config space directly from the device' own driver..
> 
> Anyone who can help me with this?

Use this:

	pci_cfg_save(dev, dinfo, 0);
	pci_set_powerstate(dev, PCI_POWERSTATE_D3);

	/* do stuff */

	/* Will set state to D0. */
	pci_cfg_restore(dev, dinfo);

We probably should create some wrapper routines (pci_save_state() and 
pci_restore_state() would be fine) that hide the 'dinfo' detail as that isn't 
something device drivers should have to know.

-- 
John Baldwin



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201101251355.53944.jhb>