| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | #include <linux/suspend.h> | 
 | 2 | #include <linux/utsname.h> | 
 | 3 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 4 | struct swsusp_info { | 
 | 5 | 	struct new_utsname	uts; | 
 | 6 | 	u32			version_code; | 
 | 7 | 	unsigned long		num_physpages; | 
 | 8 | 	int			cpus; | 
 | 9 | 	unsigned long		image_pages; | 
| Rafael J. Wysocki | 7088a5c | 2006-01-06 00:13:05 -0800 | [diff] [blame] | 10 | 	unsigned long		pages; | 
| Rafael J. Wysocki | 6e1819d | 2006-03-23 03:00:03 -0800 | [diff] [blame] | 11 | 	unsigned long		size; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 12 | } __attribute__((aligned(PAGE_SIZE))); | 
 | 13 |  | 
 | 14 |  | 
 | 15 |  | 
 | 16 | #ifdef CONFIG_SOFTWARE_SUSPEND | 
 | 17 | extern int pm_suspend_disk(void); | 
 | 18 |  | 
 | 19 | #else | 
 | 20 | static inline int pm_suspend_disk(void) | 
 | 21 | { | 
 | 22 | 	return -EPERM; | 
 | 23 | } | 
 | 24 | #endif | 
| Stephen Hemminger | a6d7098 | 2006-12-06 20:34:35 -0800 | [diff] [blame] | 25 |  | 
 | 26 | extern struct mutex pm_mutex; | 
 | 27 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 28 | #define power_attr(_name) \ | 
 | 29 | static struct subsys_attribute _name##_attr = {	\ | 
 | 30 | 	.attr	= {				\ | 
 | 31 | 		.name = __stringify(_name),	\ | 
 | 32 | 		.mode = 0644,			\ | 
 | 33 | 	},					\ | 
 | 34 | 	.show	= _name##_show,			\ | 
 | 35 | 	.store	= _name##_store,		\ | 
 | 36 | } | 
 | 37 |  | 
 | 38 | extern struct subsystem power_subsys; | 
 | 39 |  | 
| Rafael J. Wysocki | 25761b6 | 2005-10-30 14:59:56 -0800 | [diff] [blame] | 40 | /* References to section boundaries */ | 
 | 41 | extern const void __nosave_begin, __nosave_end; | 
 | 42 |  | 
| Rafael J. Wysocki | 853609b | 2006-02-01 03:05:07 -0800 | [diff] [blame] | 43 | /* Preferred image size in bytes (default 500 MB) */ | 
 | 44 | extern unsigned long image_size; | 
| Rafael J. Wysocki | f577eb3 | 2006-03-23 02:59:59 -0800 | [diff] [blame] | 45 | extern int in_suspend; | 
| Rafael J. Wysocki | 61159a3 | 2006-03-23 03:00:00 -0800 | [diff] [blame] | 46 | extern dev_t swsusp_resume_device; | 
| Rafael J. Wysocki | 9a154d9 | 2006-12-06 20:34:12 -0800 | [diff] [blame] | 47 | extern sector_t swsusp_resume_block; | 
| Rafael J. Wysocki | f577eb3 | 2006-03-23 02:59:59 -0800 | [diff] [blame] | 48 |  | 
| Rafael J. Wysocki | 25761b6 | 2005-10-30 14:59:56 -0800 | [diff] [blame] | 49 | extern asmlinkage int swsusp_arch_suspend(void); | 
 | 50 | extern asmlinkage int swsusp_arch_resume(void); | 
 | 51 |  | 
| Rafael J. Wysocki | 72a97e0 | 2006-01-06 00:13:46 -0800 | [diff] [blame] | 52 | extern unsigned int count_data_pages(void); | 
| Rafael J. Wysocki | f577eb3 | 2006-03-23 02:59:59 -0800 | [diff] [blame] | 53 |  | 
| Rafael J. Wysocki | fb13a28 | 2006-09-25 23:32:46 -0700 | [diff] [blame] | 54 | /** | 
 | 55 |  *	Auxiliary structure used for reading the snapshot image data and | 
 | 56 |  *	metadata from and writing them to the list of page backup entries | 
 | 57 |  *	(PBEs) which is the main data structure of swsusp. | 
 | 58 |  * | 
 | 59 |  *	Using struct snapshot_handle we can transfer the image, including its | 
 | 60 |  *	metadata, as a continuous sequence of bytes with the help of | 
 | 61 |  *	snapshot_read_next() and snapshot_write_next(). | 
 | 62 |  * | 
 | 63 |  *	The code that writes the image to a storage or transfers it to | 
 | 64 |  *	the user land is required to use snapshot_read_next() for this | 
 | 65 |  *	purpose and it should not make any assumptions regarding the internal | 
 | 66 |  *	structure of the image.  Similarly, the code that reads the image from | 
 | 67 |  *	a storage or transfers it from the user land is required to use | 
 | 68 |  *	snapshot_write_next(). | 
 | 69 |  * | 
 | 70 |  *	This may allow us to change the internal structure of the image | 
 | 71 |  *	in the future with considerably less effort. | 
 | 72 |  */ | 
 | 73 |  | 
| Rafael J. Wysocki | f577eb3 | 2006-03-23 02:59:59 -0800 | [diff] [blame] | 74 | struct snapshot_handle { | 
| Rafael J. Wysocki | fb13a28 | 2006-09-25 23:32:46 -0700 | [diff] [blame] | 75 | 	loff_t		offset;	/* number of the last byte ready for reading | 
 | 76 | 				 * or writing in the sequence | 
 | 77 | 				 */ | 
 | 78 | 	unsigned int	cur;	/* number of the block of PAGE_SIZE bytes the | 
 | 79 | 				 * next operation will refer to (ie. current) | 
 | 80 | 				 */ | 
 | 81 | 	unsigned int	cur_offset;	/* offset with respect to the current | 
 | 82 | 					 * block (for the next operation) | 
 | 83 | 					 */ | 
 | 84 | 	unsigned int	prev;	/* number of the block of PAGE_SIZE bytes that | 
 | 85 | 				 * was the current one previously | 
 | 86 | 				 */ | 
| Rafael J. Wysocki | fb13a28 | 2006-09-25 23:32:46 -0700 | [diff] [blame] | 87 | 	void		*buffer;	/* address of the block to read from | 
 | 88 | 					 * or write to | 
 | 89 | 					 */ | 
 | 90 | 	unsigned int	buf_offset;	/* location to read from or write to, | 
 | 91 | 					 * given as a displacement from 'buffer' | 
 | 92 | 					 */ | 
 | 93 | 	int		sync_read;	/* Set to one to notify the caller of | 
 | 94 | 					 * snapshot_write_next() that it may | 
 | 95 | 					 * need to call wait_on_bio_chain() | 
 | 96 | 					 */ | 
| Rafael J. Wysocki | f577eb3 | 2006-03-23 02:59:59 -0800 | [diff] [blame] | 97 | }; | 
 | 98 |  | 
| Rafael J. Wysocki | fb13a28 | 2006-09-25 23:32:46 -0700 | [diff] [blame] | 99 | /* This macro returns the address from/to which the caller of | 
 | 100 |  * snapshot_read_next()/snapshot_write_next() is allowed to | 
 | 101 |  * read/write data after the function returns | 
 | 102 |  */ | 
| Rafael J. Wysocki | f577eb3 | 2006-03-23 02:59:59 -0800 | [diff] [blame] | 103 | #define data_of(handle)	((handle).buffer + (handle).buf_offset) | 
 | 104 |  | 
| Rafael J. Wysocki | b788db7 | 2006-09-25 23:32:54 -0700 | [diff] [blame] | 105 | extern unsigned int snapshot_additional_pages(struct zone *zone); | 
| Rafael J. Wysocki | f577eb3 | 2006-03-23 02:59:59 -0800 | [diff] [blame] | 106 | extern int snapshot_read_next(struct snapshot_handle *handle, size_t count); | 
 | 107 | extern int snapshot_write_next(struct snapshot_handle *handle, size_t count); | 
| Rafael J. Wysocki | 8357376 | 2006-12-06 20:34:18 -0800 | [diff] [blame] | 108 | extern void snapshot_write_finalize(struct snapshot_handle *handle); | 
| Rafael J. Wysocki | b788db7 | 2006-09-25 23:32:54 -0700 | [diff] [blame] | 109 | extern int snapshot_image_loaded(struct snapshot_handle *handle); | 
| Rafael J. Wysocki | 61159a3 | 2006-03-23 03:00:00 -0800 | [diff] [blame] | 110 |  | 
| Rafael J. Wysocki | 37b2ba1 | 2006-12-06 20:34:15 -0800 | [diff] [blame] | 111 | /* | 
 | 112 |  * This structure is used to pass the values needed for the identification | 
 | 113 |  * of the resume swap area from a user space to the kernel via the | 
 | 114 |  * SNAPSHOT_SET_SWAP_AREA ioctl | 
 | 115 |  */ | 
 | 116 | struct resume_swap_area { | 
 | 117 | 	loff_t offset; | 
 | 118 | 	u_int32_t dev; | 
 | 119 | } __attribute__((packed)); | 
 | 120 |  | 
| Rafael J. Wysocki | 6e1819d | 2006-03-23 03:00:03 -0800 | [diff] [blame] | 121 | #define SNAPSHOT_IOC_MAGIC	'3' | 
 | 122 | #define SNAPSHOT_FREEZE			_IO(SNAPSHOT_IOC_MAGIC, 1) | 
 | 123 | #define SNAPSHOT_UNFREEZE		_IO(SNAPSHOT_IOC_MAGIC, 2) | 
 | 124 | #define SNAPSHOT_ATOMIC_SNAPSHOT	_IOW(SNAPSHOT_IOC_MAGIC, 3, void *) | 
 | 125 | #define SNAPSHOT_ATOMIC_RESTORE		_IO(SNAPSHOT_IOC_MAGIC, 4) | 
 | 126 | #define SNAPSHOT_FREE			_IO(SNAPSHOT_IOC_MAGIC, 5) | 
 | 127 | #define SNAPSHOT_SET_IMAGE_SIZE		_IOW(SNAPSHOT_IOC_MAGIC, 6, unsigned long) | 
 | 128 | #define SNAPSHOT_AVAIL_SWAP		_IOR(SNAPSHOT_IOC_MAGIC, 7, void *) | 
 | 129 | #define SNAPSHOT_GET_SWAP_PAGE		_IOR(SNAPSHOT_IOC_MAGIC, 8, void *) | 
 | 130 | #define SNAPSHOT_FREE_SWAP_PAGES	_IO(SNAPSHOT_IOC_MAGIC, 9) | 
 | 131 | #define SNAPSHOT_SET_SWAP_FILE		_IOW(SNAPSHOT_IOC_MAGIC, 10, unsigned int) | 
| Luca Tettamanti | 9b23820 | 2006-03-23 03:00:09 -0800 | [diff] [blame] | 132 | #define SNAPSHOT_S2RAM			_IO(SNAPSHOT_IOC_MAGIC, 11) | 
| Stefan Seyfried | 3592695 | 2006-12-06 20:34:06 -0800 | [diff] [blame] | 133 | #define SNAPSHOT_PMOPS			_IOW(SNAPSHOT_IOC_MAGIC, 12, unsigned int) | 
| Rafael J. Wysocki | 37b2ba1 | 2006-12-06 20:34:15 -0800 | [diff] [blame] | 134 | #define SNAPSHOT_SET_SWAP_AREA		_IOW(SNAPSHOT_IOC_MAGIC, 13, \ | 
 | 135 | 							struct resume_swap_area) | 
 | 136 | #define SNAPSHOT_IOC_MAXNR	13 | 
| Stefan Seyfried | 3592695 | 2006-12-06 20:34:06 -0800 | [diff] [blame] | 137 |  | 
 | 138 | #define PMOPS_PREPARE	1 | 
 | 139 | #define PMOPS_ENTER	2 | 
 | 140 | #define PMOPS_FINISH	3 | 
| Rafael J. Wysocki | 6e1819d | 2006-03-23 03:00:03 -0800 | [diff] [blame] | 141 |  | 
| Rafael J. Wysocki | 61159a3 | 2006-03-23 03:00:00 -0800 | [diff] [blame] | 142 | /** | 
 | 143 |  *	The bitmap is used for tracing allocated swap pages | 
 | 144 |  * | 
 | 145 |  *	The entire bitmap consists of a number of bitmap_page | 
 | 146 |  *	structures linked with the help of the .next member. | 
 | 147 |  *	Thus each page can be allocated individually, so we only | 
 | 148 |  *	need to make 0-order memory allocations to create | 
 | 149 |  *	the bitmap. | 
 | 150 |  */ | 
 | 151 |  | 
 | 152 | #define BITMAP_PAGE_SIZE	(PAGE_SIZE - sizeof(void *)) | 
 | 153 | #define BITMAP_PAGE_CHUNKS	(BITMAP_PAGE_SIZE / sizeof(long)) | 
 | 154 | #define BITS_PER_CHUNK		(sizeof(long) * 8) | 
 | 155 | #define BITMAP_PAGE_BITS	(BITMAP_PAGE_CHUNKS * BITS_PER_CHUNK) | 
 | 156 |  | 
 | 157 | struct bitmap_page { | 
 | 158 | 	unsigned long		chunks[BITMAP_PAGE_CHUNKS]; | 
 | 159 | 	struct bitmap_page	*next; | 
 | 160 | }; | 
 | 161 |  | 
 | 162 | extern void free_bitmap(struct bitmap_page *bitmap); | 
 | 163 | extern struct bitmap_page *alloc_bitmap(unsigned int nr_bits); | 
| Rafael J. Wysocki | 3aef83e | 2006-12-06 20:34:10 -0800 | [diff] [blame] | 164 | extern sector_t alloc_swapdev_block(int swap, struct bitmap_page *bitmap); | 
| Rafael J. Wysocki | 61159a3 | 2006-03-23 03:00:00 -0800 | [diff] [blame] | 165 | extern void free_all_swap_pages(int swap, struct bitmap_page *bitmap); | 
 | 166 |  | 
| Randy Dunlap | 74c7e2e | 2006-03-23 03:00:01 -0800 | [diff] [blame] | 167 | extern int swsusp_check(void); | 
| Rafael J. Wysocki | 61159a3 | 2006-03-23 03:00:00 -0800 | [diff] [blame] | 168 | extern int swsusp_shrink_memory(void); | 
| Randy Dunlap | 74c7e2e | 2006-03-23 03:00:01 -0800 | [diff] [blame] | 169 | extern void swsusp_free(void); | 
| Rafael J. Wysocki | 61159a3 | 2006-03-23 03:00:00 -0800 | [diff] [blame] | 170 | extern int swsusp_suspend(void); | 
 | 171 | extern int swsusp_resume(void); | 
| Randy Dunlap | 74c7e2e | 2006-03-23 03:00:01 -0800 | [diff] [blame] | 172 | extern int swsusp_read(void); | 
 | 173 | extern int swsusp_write(void); | 
 | 174 | extern void swsusp_close(void); | 
| Luca Tettamanti | 9b23820 | 2006-03-23 03:00:09 -0800 | [diff] [blame] | 175 | extern int suspend_enter(suspend_state_t state); | 
| Rafael J. Wysocki | 0d3a9ab | 2006-12-06 20:34:32 -0800 | [diff] [blame] | 176 |  | 
 | 177 | struct timeval; | 
 | 178 | extern void swsusp_show_speed(struct timeval *, struct timeval *, | 
 | 179 | 				unsigned int, char *); |