Hi, following the submission of the kernel patch, here is my try at an implementation in userspace:
Note that we could get rid of that platform_mode variable if we had the possibility to specify defaults in the struct config_par (without resorting to platform_mode i would have had multiple incarnations of if (strcmp(shutdown_method, "reboot") || strcmp(shutdown_method, "shutdown")) foo; which i wanted to avoid). Would a patch for this be something of interest? Index: suspend.c =================================================================== RCS file: /cvsroot/suspend/suspend/suspend.c,v retrieving revision 1.57 diff -u -p -r1.57 suspend.c --- suspend.c 24 Sep 2006 08:09:59 -0000 1.57 +++ suspend.c 25 Sep 2006 16:42:54 -0000 @@ -48,6 +48,7 @@ static char resume_dev_name[MAX_STR_LEN] static unsigned long pref_image_size = IMAGE_SIZE; static int suspend_loglevel = SUSPEND_LOGLEVEL; static char compute_checksum; +static int platform_mode; #ifdef CONFIG_COMPRESS static char compress; #else @@ -659,13 +660,19 @@ static int reset_signature(int fd) } #endif -static void suspend_shutdown(void) +static void suspend_shutdown(int dev) { - /* todo: platform, S3 */ + /* todo: S3 */ if (!strcmp(shutdown_method, "reboot")) reboot(); - else - power_off(); + else if (platform_mode) { + /* !reboot && !shutdown => platform is default */ + int ret = platform_enter(dev); + if (ret < 0) + fprintf(stderr, "suspend: pm_ops->enter returned" + " error %d, calling power_off\n", ret); + } + power_off(); /* Signature is on disk, it is very dangerous to continue now. * We'd do resume with stale caches on next boot. */ fprintf(stderr,"Powerdown failed. That's impossible.\n"); @@ -699,6 +706,17 @@ int suspend_system(int snapshot_fd, int if (error) goto Unfreeze; + /* platform mode is !shutdown and !reboot... */ + platform_mode = (strcmp(shutdown_method, "shutdown") || + strcmp(shutdown_method, "reboot")); + + if (platform_mode) { + int ret = platform_prepare(snapshot_fd); + if (ret < 0) + fprintf(stderr, "suspend: pm_ops->prepare returned " + "error %d\n", ret); + } + printf("suspend: Snapshotting system\n"); attempts = 2; do { @@ -709,6 +727,12 @@ int suspend_system(int snapshot_fd, int if (!atomic_snapshot(snapshot_fd, &in_suspend)) { if (!in_suspend) { free_snapshot(snapshot_fd); + if (platform_mode) { + int ret = platform_finish(snapshot_fd); + if (ret < 0) + fprintf(stderr, "suspend: pm_ops->finish " + "returned error %d\n", ret); + } break; } error = write_image(snapshot_fd, resume_fd); @@ -716,14 +740,14 @@ int suspend_system(int snapshot_fd, int splash.progress(100); #ifdef CONFIG_BOTH if (!s2ram) { - suspend_shutdown(); + suspend_shutdown(snapshot_fd); } else { /* If we die (and allow system to continue) between * now and reset_signature(), very bad things will * happen. */ error = suspend_to_ram(snapshot_fd); if (error) - suspend_shutdown(); + suspend_shutdown(snapshot_fd); reset_signature(resume_fd); free_swap_pages(snapshot_fd); free_snapshot(snapshot_fd); @@ -731,7 +755,7 @@ int suspend_system(int snapshot_fd, int goto Unfreeze; } #else - suspend_shutdown(); + suspend_shutdown(snapshot_fd); #endif } else { free_swap_pages(snapshot_fd); Index: swsusp.h =================================================================== RCS file: /cvsroot/suspend/suspend/swsusp.h,v retrieving revision 1.27 diff -u -p -r1.27 swsusp.h --- swsusp.h 24 Sep 2006 08:09:59 -0000 1.27 +++ swsusp.h 25 Sep 2006 16:42:54 -0000 @@ -26,7 +26,12 @@ #define SNAPSHOT_FREE_SWAP_PAGES _IO(SNAPSHOT_IOC_MAGIC, 9) #define SNAPSHOT_SET_SWAP_FILE _IOW(SNAPSHOT_IOC_MAGIC, 10, unsigned int) #define SNAPSHOT_S2RAM _IO(SNAPSHOT_IOC_MAGIC, 11) -#define SNAPSHOT_IOC_MAXNR 11 +#define SNAPSHOT_PMOPS _IOW(SNAPSHOT_IOC_MAGIC, 12, unsigned int) +#define SNAPSHOT_IOC_MAXNR 12 + +#define PMOPS_PREPARE 1 +#define PMOPS_ENTER 2 +#define PMOPS_FINISH 3 #define LINUX_REBOOT_MAGIC1 0xfee1dead #define LINUX_REBOOT_MAGIC2 672274793 @@ -99,6 +104,21 @@ static inline int atomic_restore(int dev return ioctl(dev, SNAPSHOT_ATOMIC_RESTORE, 0); } +static inline int platform_prepare(int dev) +{ + return ioctl (dev, SNAPSHOT_PMOPS, PMOPS_FINISH); +} + +static inline int platform_enter(int dev) +{ + return ioctl (dev, SNAPSHOT_PMOPS, PMOPS_FINISH); +} + +static inline int platform_finish(int dev) +{ + return ioctl (dev, SNAPSHOT_PMOPS, PMOPS_FINISH); +} + static inline int free_snapshot(int dev) { return ioctl(dev, SNAPSHOT_FREE, 0); -- 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 Suspend-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/suspend-devel