Hi,
(i'll discuss this on suspend-devel, we can take the rest back into cc: once
the coding issues are solved :-)
On Mon, Dec 18, 2006 at 09:00:41PM +0100, Rafael J. Wysocki wrote:
> > Index: s2ram.c
> > ===================================================================
> > RCS file: /cvsroot/suspend/suspend/s2ram.c,v
> > retrieving revision 1.45
> > diff -u -p -r1.45 s2ram.c
> > --- s2ram.c 20 Sep 2006 16:23:51 -0000 1.45
> > +++ s2ram.c 18 Dec 2006 16:44:47 -0000
> > @@ -11,12 +11,16 @@
> > #include <errno.h>
> > #include <string.h>
> >
> > +#include <pci/pci.h>
> > +
> > #define S2RAM
> > #include "vbetool/vbetool.h"
> > #include "vt.h"
> > #include "s2ram.h"
> >
> > static void *vbe_buffer;
> > +unsigned char vga_pci_state[256];
> > +struct pci_dev vga_dev;
> > @@ -143,6 +149,35 @@ int s2ram_check(int id)
> > return ret;
> > }
> >
> > +struct pci_dev find_vga(void)
> > +{
> > + struct pci_access *pacc;
> > + struct pci_dev *dev;
> > +
> > + pacc = pci_alloc(); /* Get the pci_access structure */
> > + pci_init(pacc); /* Initialize the PCI library */
> > + pci_scan_bus(pacc); /* We want to get the list of devices */
> > +
> > + for (dev=pacc->devices; dev; dev=dev->next) {
> > + pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_CLASS);
> > + if (dev->device_class == 0x300)
> > + break;
> > + }
> > + pci_cleanup(pacc);
> > +
> > + return *dev;
> > +}
>
> Hm, I'd rather return the pointer (eg. so that the structure can be freed).
Ok (hopefully :-)
> > +void save_vga_pci(struct pci_dev dev)
>
> A pointer here?
>
> > +{
> > + pci_read_block(&dev, 0, vga_pci_state, 256);
> > +}
> > +
> > +void restore_vga_pci(struct pci_dev dev)
>
> And here?
>
> > +{
> > + pci_write_block(&dev, 0, vga_pci_state, 256);
> > +}
> > +
> > /* warning: we have to be on a text console when calling this */
> > int s2ram_hacks(void)
> > {
> > @@ -171,6 +206,12 @@ int s2ram_hacks(void)
> > printf("Calling radeon_cmd_light(0)\n");
> > radeon_cmd_light(0);
> > }
> > + if (flags & PCI_SAVE) {
> > + vga_dev = find_vga();
>
> Could vga_dev be a pointer?
>
> > + printf("saving PCI config of device %02x:%02x.%d\n",
> > + vga_dev.bus, vga_dev.dev, vga_dev.func);
> > + save_vga_pci(vga_dev);
> > + }
> >
> > return 0;
> > }
> > @@ -216,6 +257,11 @@ int s2ram_do(void)
> >
> > void s2ram_resume(void)
> > {
> > + if (flags & PCI_SAVE) {
> > + printf("saving PCI config of device %02x:%02x.%d\n",
> > + vga_dev.bus, vga_dev.dev, vga_dev.func);
> > + restore_vga_pci(vga_dev);
> > + }
> > // FIXME: can we call vbetool_init() multiple times without cleaning up?
> > if (flags & VBE_POST) {
> > vbetool_init();
I tested this by just immediately returning in s2ram_do() and so doing a
"dry" test, without actually suspending (and by write()-ing vga_pci_state to
stderr and comparing to /proc and sysfs, to make sure it actually reads some-
thing from the PCI device. During first tests, my X server crashed, so it
seems to also write something to the PCI config space... :-).
But then, my machine does work without it anyway, so this was not a real
"function test".
Miroslav, could you maybe try this patch if it actually helps? You'd need
to use the all-new option "-v" in addition to what you have been using until
now.
Version 2:
Index: s2ram.c
===================================================================
RCS file: /cvsroot/suspend/suspend/s2ram.c,v
retrieving revision 1.45
diff -u -p -r1.45 s2ram.c
--- s2ram.c 20 Sep 2006 16:23:51 -0000 1.45
+++ s2ram.c 18 Dec 2006 20:42:10 -0000
@@ -11,12 +11,16 @@
#include <errno.h>
#include <string.h>
+#include <pci/pci.h>
+
#define S2RAM
#include "vbetool/vbetool.h"
#include "vt.h"
#include "s2ram.h"
static void *vbe_buffer;
+unsigned char vga_pci_state[256];
+struct pci_dev *vga_dev;
/* Flags set from whitelist */
static int flags, vbe_mode = -1;
char bios_version[1024], sys_vendor[1024], sys_product[1024],
sys_version[1024];
@@ -36,6 +40,7 @@ char bios_version[1024], sys_vendor[1024
#define UNSURE 0x20 /* unverified entries from acpi-support 0.59 */
#define NOFB 0x40 /* must not use a frame buffer */
#define VBE_MODE 0x80 /* machine needs "vbetool vbemode get / set" */
+#define PCI_SAVE 0x100 /* we need to save the VGA PCI registers */
#include "whitelist.c"
@@ -67,14 +72,15 @@ void machine_known(int i)
" bios_version = '%s'\n", i,
whitelist[i].sys_vendor, whitelist[i].sys_product,
whitelist[i].sys_version, whitelist[i].bios_version);
- printf("Fixes: 0x%x %s%s%s%s%s%s%s\n", flags,
+ printf("Fixes: 0x%x %s%s%s%s%s%s%s%s\n", flags,
(flags & VBE_SAVE) ? "VBE_SAVE " : "",
(flags & VBE_POST) ? "VBE_POST " : "",
(flags & VBE_MODE) ? "VBE_MODE " : "",
(flags & RADEON_OFF) ? "RADEON_OFF " : "",
(flags & S3_BIOS) ? "S3_BIOS " : "",
(flags & S3_MODE) ? "S3_MODE " : "",
- (flags & NOFB) ? "NOFB " : "");
+ (flags & NOFB) ? "NOFB " : "",
+ (flags & PCI_SAVE) ? "PCI_SAVE " : "");
if (flags & UNSURE)
printf("Machine is in the whitelist but perhaps using "
"vbetool unnecessarily.\n"
@@ -143,6 +149,35 @@ int s2ram_check(int id)
return ret;
}
+struct pci_dev *find_vga(void)
+{
+ struct pci_access *pacc;
+ struct pci_dev *dev;
+
+ pacc = pci_alloc(); /* Get the pci_access structure */
+ pci_init(pacc); /* Initialize the PCI library */
+ pci_scan_bus(pacc); /* We want to get the list of devices */
+
+ for (dev=pacc->devices; dev; dev=dev->next) {
+ pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_CLASS);
+ if (dev->device_class == 0x300)
+ break;
+ }
+ pci_cleanup(pacc);
+
+ return dev;
+}
+
+void save_vga_pci(struct pci_dev *dev)
+{
+ pci_read_block(dev, 0, vga_pci_state, 256);
+}
+
+void restore_vga_pci(struct pci_dev *dev)
+{
+ pci_write_block(dev, 0, vga_pci_state, 256);
+}
+
/* warning: we have to be on a text console when calling this */
int s2ram_hacks(void)
{
@@ -171,6 +206,12 @@ int s2ram_hacks(void)
printf("Calling radeon_cmd_light(0)\n");
radeon_cmd_light(0);
}
+ if (flags & PCI_SAVE) {
+ vga_dev = find_vga();
+ printf("saving PCI config of device %02x:%02x.%d\n",
+ vga_dev->bus, vga_dev->dev, vga_dev->func);
+ save_vga_pci(vga_dev);
+ }
return 0;
}
@@ -216,6 +257,11 @@ int s2ram_do(void)
void s2ram_resume(void)
{
+ if (flags & PCI_SAVE) {
+ printf("restoring PCI config of device %02x:%02x.%d\n",
+ vga_dev->bus, vga_dev->dev, vga_dev->func);
+ restore_vga_pci(vga_dev);
+ }
// FIXME: can we call vbetool_init() multiple times without cleaning up?
if (flags & VBE_POST) {
vbetool_init();
@@ -260,6 +306,7 @@ static void usage(void)
" -a, --acpi_sleep: set the acpi_sleep parameter before "
"suspend\n"
" 1=s3_bios, 2=s3_mode, 3=both\n"
+ " -v, --pci_save: save the PCI config space for the VGA
card.\n"
"\n");
exit(1);
}
@@ -278,10 +325,11 @@ int main(int argc, char *argv[])
{ "radeontool", no_argument, NULL, 'r'},
{ "identify", no_argument, NULL, 'i'},
{ "acpi_sleep", required_argument, NULL, 'a'},
+ { "pci_save", no_argument, NULL, 'v'},
{ NULL, 0, NULL, 0 }
};
- while ((i = getopt_long(argc, argv, "nhfspmria:", options, NULL)) !=
-1) {
+ while ((i = getopt_long(argc, argv, "nhfspmriva:", options, NULL)) !=
-1) {
switch (i) {
case 'h':
usage();
@@ -311,6 +359,9 @@ int main(int argc, char *argv[])
case 'a':
flags |= (atoi(optarg) & (S3_BIOS | S3_MODE));
break;
+ case 'v':
+ flags |= PCI_SAVE;
+ break;
default:
usage();
break;
--
Stefan Seyfried \ "I didn't want to write for pay. I
QA / R&D Team Mobile Devices \ wanted to be paid for what I write."
SUSE LINUX Products GmbH, Nürnberg \ -- Leonard Cohen
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Suspend-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/suspend-devel