Import 2.1.118
[davej-history.git] / arch / m68k / atari / stram.c
blobd11011c5efee6bcf4384f321aee95ace511f03c8
1 /*
2 * arch/m68k/atari/stram.c: Functions for ST-RAM allocations
4 * Copyright 1994-97 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
8 * for more details.
9 */
11 #include <linux/config.h>
12 #include <linux/types.h>
13 #include <linux/kernel.h>
14 #include <linux/mm.h>
15 #include <linux/kdev_t.h>
16 #include <linux/major.h>
17 #include <linux/init.h>
18 #include <linux/swap.h>
19 #include <linux/malloc.h>
20 #include <linux/vmalloc.h>
21 #include <linux/pagemap.h>
22 #include <asm/setup.h>
23 #include <asm/machdep.h>
24 #include <asm/page.h>
25 #include <asm/pgtable.h>
26 #include <asm/atarihw.h>
27 #include <asm/atari_stram.h>
30 #ifdef CONFIG_STRAM_SWAP
31 #define MAJOR_NR Z2RAM_MAJOR
32 #include <linux/blk.h>
33 #undef DEVICE_NAME
34 #define DEVICE_NAME "stram"
35 #endif
37 #undef DEBUG
39 #ifdef DEBUG
40 #define DPRINTK(fmt,args...) printk( fmt, ##args )
41 #else
42 #define DPRINTK(fmt,args...)
43 #endif
45 #if defined(CONFIG_PROC_FS) && defined(CONFIG_STRAM_PROC)
46 /* abbrev for the && above... */
47 #define DO_PROC
48 #include <linux/proc_fs.h>
49 #endif
51 /* Pre-swapping comments:
53 * ++roman:
55 * New version of ST-Ram buffer allocation. Instead of using the
56 * 1 MB - 4 KB that remain when the ST-Ram chunk starts at $1000
57 * (1 MB granularity!), such buffers are reserved like this:
59 * - If the kernel resides in ST-Ram anyway, we can take the buffer
60 * from behind the current kernel data space the normal way
61 * (incrementing start_mem).
63 * - If the kernel is in TT-Ram, stram_init() initializes start and
64 * end of the available region. Buffers are allocated from there
65 * and mem_init() later marks the such used pages as reserved.
66 * Since each TT-Ram chunk is at least 4 MB in size, I hope there
67 * won't be an overrun of the ST-Ram region by normal kernel data
68 * space.
70 * For that, ST-Ram may only be allocated while kernel initialization
71 * is going on, or exactly: before mem_init() is called. There is also
72 * no provision now for freeing ST-Ram buffers. It seems that isn't
73 * really needed.
78 * New Nov 1997: Use ST-RAM as swap space!
80 * In the past, there were often problems with modules that require ST-RAM
81 * buffers. Such drivers have to use __get_dma_pages(), which unfortunately
82 * often isn't very successful in allocating more than 1 page :-( [1] The net
83 * result was that most of the time you couldn't insmod such modules (ataflop,
84 * ACSI, SCSI on Falcon, Atari internal framebuffer, not to speak of acsi_slm,
85 * which needs a 1 MB buffer... :-).
87 * To overcome this limitation, ST-RAM can now be turned into a very
88 * high-speed swap space. If a request for an ST-RAM buffer comes, the kernel
89 * now tries to unswap some pages on that swap device to make some free (and
90 * contiguous) space. This works much better in comparison to
91 * __get_dma_pages(), since used swap pages can be selectively freed by either
92 * moving them to somewhere else in swap space, or by reading them back into
93 * system memory. Ok, there operation of unswapping isn't really cheap (for
94 * each page, one has to go through the page tables of all processes), but it
95 * doesn't happen that often (only when allocation ST-RAM, i.e. when loading a
96 * module that needs ST-RAM). But it at least makes it possible to load such
97 * modules!
99 * It could also be that overall system performance increases a bit due to
100 * ST-RAM swapping, since slow ST-RAM isn't used anymore for holding data or
101 * executing code in. It's then just a (very fast, compared to disk) back
102 * storage for not-so-often needed data. (But this effect must be compared
103 * with the loss of total memory...) Don't know if the effect is already
104 * visible on a TT, where the speed difference between ST- and TT-RAM isn't
105 * that dramatic, but it should on machines where TT-RAM is really much faster
106 * (e.g. Afterburner).
108 * [1]: __get_free_pages() does a fine job if you only want one page, but if
109 * you want more (contiguous) pages, it can give you such a block only if
110 * there's already a free one. The algorithm can't try to free buffers or swap
111 * out something in order to make more free space, since all that page-freeing
112 * mechanisms work "target-less", i.e. they just free something, but not in a
113 * specific place. I.e., __get_free_pages() can't do anything to free
114 * *adjacent* pages :-( This situation becomes even worse for DMA memory,
115 * since the freeing algorithms are also blind to DMA capability of pages.
118 #ifdef CONFIG_STRAM_SWAP
119 #define ALIGN_IF_SWAP(x) PAGE_ALIGN(x)
120 #else
121 #define ALIGN_IF_SWAP(x) (x)
122 #endif
124 /* map entry for reserved swap page (used as buffer) */
125 #define SWP_RSVD 0x80
127 /* get index of swap page at address 'addr' */
128 #define SWAP_NR(addr) (((unsigned long)(addr)-swap_start) >> PAGE_SHIFT)
130 /* get address of swap page #'nr' */
131 #define SWAP_ADDR(nr) ((void *)(swap_start + ((nr)<<PAGE_SHIFT)))
133 /* get number of pages for 'n' bytes (already page-aligned) */
134 #define N_PAGES(n) ((n) >> PAGE_SHIFT)
136 /* The following two numbers define the maximum fraction of ST-RAM in total
137 * memory, below that the kernel would automatically use ST-RAM as swap
138 * space. This decision can be overriden with stram_swap= */
139 #define MAX_STRAM_FRACTION_NOM 1
140 #define MAX_STRAM_FRACTION_DENOM 3
142 /* Start and end of the (pre-mem_init) reserved ST-RAM region */
143 static unsigned long rsvd_stram_beg, rsvd_stram_end;
145 /* Start and end (virtual) of ST-RAM */
146 static unsigned long stram_start, stram_end;
148 /* set after memory_init() executed and allocations via start_mem aren't
149 * possible anymore */
150 static int mem_init_done = 0;
152 /* set if kernel is in ST-RAM */
153 static int kernel_in_stram;
155 typedef struct stram_block {
156 struct stram_block *next;
157 unsigned long start;
158 unsigned long size;
159 unsigned flags;
160 const char *owner;
161 } BLOCK;
163 /* values for flags field */
164 #define BLOCK_FREE 0x01 /* free structure in the BLOCKs pool */
165 #define BLOCK_KMALLOCED 0x02 /* structure allocated by kmalloc() */
166 #define BLOCK_STATIC 0x04 /* pre-mem_init() allocated block */
167 #define BLOCK_GFP 0x08 /* block allocated with __get_dma_pages() */
168 #define BLOCK_INSWAP 0x10 /* block allocated in swap space */
170 /* list of allocated blocks */
171 static BLOCK *alloc_list = NULL;
173 /* We can't always use kmalloc() to allocate BLOCK structures, since
174 * stram_alloc() can be called rather early. So we need some pool of
175 * statically allocated structures. 20 of them is more than enough, so in most
176 * cases we never should need to call kmalloc(). */
177 #define N_STATIC_BLOCKS 20
178 static BLOCK static_blocks[N_STATIC_BLOCKS];
180 #ifdef CONFIG_STRAM_SWAP
181 /* max. number of bytes to use for swapping
182 * 0 = no ST-RAM swapping
183 * -1 = do swapping (to whole ST-RAM) if it's less than MAX_STRAM_FRACTION of
184 * total memory
186 static int max_swap_size = -1;
188 /* start and end of swapping area */
189 static unsigned long swap_start, swap_end;
191 /* The ST-RAM's swap info structure */
192 static struct swap_info_struct *stram_swap_info;
194 /* The ST-RAM's swap type */
195 static int stram_swap_type;
197 /* major and minor device number of the ST-RAM device; for the major, we use
198 * the same as Amiga z2ram, which is really similar and impossible on Atari,
199 * and for the minor a relatively odd number to avoid the user creating and
200 * using that device. */
201 #define STRAM_MAJOR Z2RAM_MAJOR
202 #define STRAM_MINOR 13
204 /* Some impossible pointer value */
205 #define MAGIC_FILE_P (struct file *)0xffffdead
207 #ifdef DO_PROC
208 static unsigned stat_swap_read = 0;
209 static unsigned stat_swap_write = 0;
210 static unsigned stat_swap_move = 0;
211 static unsigned stat_swap_force = 0;
212 #endif /* DO_PROC */
214 #endif /* CONFIG_STRAM_SWAP */
216 /***************************** Prototypes *****************************/
218 #ifdef CONFIG_STRAM_SWAP
219 static int swap_init( unsigned long start_mem, unsigned long swap_data );
220 static inline int unswap_pte( struct vm_area_struct * vma, unsigned long
221 address, pte_t *dir, unsigned long entry,
222 unsigned long page, int isswap );
223 static inline int unswap_pmd( struct vm_area_struct * vma, pmd_t *dir,
224 unsigned long address, unsigned long size,
225 unsigned long offset, unsigned long entry,
226 unsigned long page, int isswap );
227 static inline int unswap_pgd( struct vm_area_struct * vma, pgd_t *dir,
228 unsigned long address, unsigned long size,
229 unsigned long entry, unsigned long page, int
230 isswap );
231 static int unswap_vma( struct vm_area_struct * vma, pgd_t *pgdir, unsigned
232 long entry, unsigned long page, int isswap );
233 static int unswap_process( struct mm_struct * mm, unsigned long entry,
234 unsigned long page, int isswap );
235 static int unswap_by_move( unsigned char *map, unsigned long max, unsigned
236 long start, unsigned long n_pages );
237 static int unswap_by_read( unsigned char *map, unsigned long max, unsigned
238 long start, unsigned long n_pages );
239 static void *get_stram_region( unsigned long n_pages );
240 static void free_stram_region( unsigned long offset, unsigned long n_pages
242 static int in_some_region( unsigned long addr );
243 static unsigned long find_free_region( unsigned long n_pages, unsigned long
244 *total_free, unsigned long
245 *region_free );
246 static void do_stram_request( void );
247 static int stram_open( struct inode *inode, struct file *filp );
248 static int stram_release( struct inode *inode, struct file *filp );
249 static void do_z2_request( void );
250 #endif
251 static int get_gfp_order( unsigned long size );
252 static void reserve_region( unsigned long addr, unsigned long end );
253 static BLOCK *add_region( void *addr, unsigned long size );
254 static BLOCK *find_region( void *addr );
255 static int remove_region( BLOCK *block );
257 /************************* End of Prototypes **************************/
260 /* ------------------------------------------------------------------------ */
261 /* Public Interface */
262 /* ------------------------------------------------------------------------ */
265 * This init function is called very early by atari/config.c
266 * It initializes some internal variables needed for stram_alloc()
268 __initfunc(void atari_stram_init( void ))
270 int i;
272 /* initialize static blocks */
273 for( i = 0; i < N_STATIC_BLOCKS; ++i )
274 static_blocks[i].flags = BLOCK_FREE;
276 /* determine whether kernel code resides in ST-RAM (then ST-RAM is the
277 * first memory block at virtual 0x0) */
278 stram_start = PTOV( 0 );
279 kernel_in_stram = (stram_start == 0);
281 for( i = 0; i < m68k_num_memory; ++i ) {
282 if (m68k_memory[i].addr == 0) {
283 /* skip first 2kB or page (supervisor-only!) */
284 rsvd_stram_beg = stram_start + ALIGN_IF_SWAP(0x800);
285 rsvd_stram_end = rsvd_stram_beg;
286 stram_end = stram_start + m68k_memory[i].size;
287 return;
290 /* Should never come here! (There is always ST-Ram!) */
291 panic( "atari_stram_init: no ST-RAM found!" );
296 * This function is called from mem_init() to reserve the pages needed for
297 * ST-RAM management.
299 __initfunc(void atari_stram_reserve_pages( unsigned long start_mem ))
301 #ifdef CONFIG_STRAM_SWAP
302 /* if max_swap_size is negative (i.e. no stram_swap= option given),
303 * determine at run time whether to use ST-RAM swapping */
304 if (max_swap_size < 0)
305 /* Use swapping if ST-RAM doesn't make up more than MAX_STRAM_FRACTION
306 * of total memory. In that case, the max. size is set to 16 MB,
307 * because ST-RAM can never be bigger than that.
308 * Also, never use swapping on a Hades, there's no separate ST-RAM in
309 * that machine. */
310 max_swap_size =
311 (!MACH_IS_HADES &&
312 (N_PAGES(stram_end-stram_start)*MAX_STRAM_FRACTION_DENOM <=
313 max_mapnr*MAX_STRAM_FRACTION_NOM)) ? 16*1024*1024 : 0;
314 DPRINTK( "atari_stram_reserve_pages: max_swap_size = %d\n", max_swap_size );
315 #endif
317 /* always reserve first page of ST-RAM, the first 2 kB are
318 * supervisor-only! */
319 set_bit( PG_reserved, &mem_map[MAP_NR(stram_start)].flags );
321 #ifdef CONFIG_STRAM_SWAP
322 if (!max_swap_size) {
323 fallback:
324 #endif
325 DPRINTK( "atari_stram_reserve_pages: swapping disabled\n" );
326 if (!kernel_in_stram) {
327 /* Reserve all pages that have been marked by pre-mem_init
328 * stram_alloc() (e.g. for the screen memory). */
329 reserve_region( rsvd_stram_beg, rsvd_stram_end );
330 DPRINTK( "atari_stram_reserve_pages: reseverved %08lx-%08lx\n",
331 rsvd_stram_beg, rsvd_stram_end );
333 /* else (kernel in ST-RAM): nothing to do, ST-RAM buffers are
334 * kernel data */
335 #ifdef CONFIG_STRAM_SWAP
337 else {
338 unsigned long swap_data;
339 BLOCK *p;
341 /* determine first page to use as swap:
342 * if the kernel is in TT-RAM, this is the first page of (usable)
343 * ST-RAM; else if there were already some allocations (probable...),
344 * use the lowest address of these (the list is sorted by address!);
345 * otherwise just use the end of kernel data (= start_mem) */
346 swap_start = !kernel_in_stram ? stram_start + PAGE_SIZE :
347 alloc_list ? alloc_list->start :
348 start_mem;
349 /* decrement by one page, rest of kernel assumes that first swap page
350 * is always reserved and maybe doesn't handle SWP_ENTRY == 0
351 * correctly */
352 swap_start -= PAGE_SIZE;
353 swap_end = stram_end;
354 if (swap_end-swap_start > max_swap_size)
355 swap_end = swap_start + max_swap_size;
356 DPRINTK( "atari_stram_reserve_pages: swapping enabled; "
357 "swap=%08lx-%08lx\n", swap_start, swap_end );
359 /* reserve some amount of memory for maintainance of swapping itself:
360 * 1 page for the lockmap, and one page for each 4096 (PAGE_SIZE) swap
361 * pages. (1 byte for each page) */
362 swap_data = start_mem;
363 start_mem += PAGE_ALIGN(SWAP_NR(swap_end)) + PAGE_SIZE;
364 /* correct swap_start if necessary */
365 if (swap_start == swap_data)
366 swap_start = start_mem;
368 if (!swap_init( start_mem, swap_data )) {
369 printk( KERN_ERR "ST-RAM swap space initialization failed\n" );
370 max_swap_size = 0;
371 goto fallback;
373 /* reserve region for swapping meta-data */
374 reserve_region( swap_data, start_mem );
375 /* reserve swapping area itself */
376 reserve_region( swap_start+PAGE_SIZE, swap_end );
378 /* Formerly static areas have been included in the swap area. */
379 for( p = alloc_list; p; p = p->next ) {
380 if (p->flags & BLOCK_STATIC)
381 p->flags = (p->flags & ~BLOCK_STATIC) | BLOCK_INSWAP;
385 * If the whole ST-RAM is used for swapping, there are no allocatable
386 * dma pages left. But unfortunately, some shared parts of the kernel
387 * (particularily the SCSI mid-level) call __get_dma_pages()
388 * unconditionally :-( These calls then fail, and scsi.c even doesn't
389 * check for NULL return values and just crashes. The quick fix for
390 * this (instead of doing much clean up work in the SCSI code) is to
391 * pretend all pages are DMA-able by setting mach_max_dma_address to
392 * ULONG_MAX. This doesn't change any functionality so far, since
393 * get_dma_pages() shouldn't be used on Atari anyway anymore (better
394 * use atari_stram_alloc()), and the Atari SCSI drivers don't need DMA
395 * memory. But unfortunately there's now no kind of warning (even not
396 * a NULL return value) if you use get_dma_pages() nevertheless :-(
397 * You just will get non-DMA-able memory...
399 mach_max_dma_address = 0xffffffff;
402 * Ok, num_physpages needs not be really exact, but it's better to
403 * subtract the pages set aside for swapping.
405 num_physpages -= SWAP_NR(swap_end)-1;
407 #endif
409 mem_init_done = 1;
414 * This is main public interface: somehow allocate a ST-RAM block
415 * There are three strategies:
417 * - If we're before mem_init(), we have to make a static allocation. The
418 * region is taken in the kernel data area (if the kernel is in ST-RAM) or
419 * from the start of ST-RAM (if the kernel is in TT-RAM) and added to the
420 * rsvd_stram_* region. The ST-RAM is somewhere in the middle of kernel
421 * address space in the latter case.
423 * - If mem_init() already has been called and ST-RAM swapping is enabled,
424 * try to get the memory from the (pseudo) swap-space, either free already
425 * or by moving some other pages out of the swap.
427 * - If mem_init() already has been called, and ST-RAM swapping is not
428 * enabled, the only possibility is to try with __get_dma_pages(). This has
429 * the disadvantage that it's very hard to get more than 1 page, and it is
430 * likely to fail :-(
433 void *atari_stram_alloc( long size, unsigned long *start_mem,
434 const char *owner )
436 void *addr = NULL;
437 BLOCK *block;
438 int flags;
440 DPRINTK( "atari_stram_alloc(size=%08lx,*start_mem=%08lx,owner=%s)\n",
441 size, start_mem ? *start_mem : 0xffffffff, owner );
443 if (start_mem && mem_init_done) {
444 printk( KERN_ERR "atari_stram_alloc called with start_mem!=NULL "
445 "after mem_init() from %p\n", __builtin_return_address(0) );
446 return( NULL );
448 if (!start_mem && !mem_init_done) {
449 printk( KERN_ERR "atari_stram_alloc called with start_mem==NULL "
450 "before mem_init() from %p\n", __builtin_return_address(0) );
451 return( NULL );
454 size = ALIGN_IF_SWAP(size);
455 DPRINTK( "atari_stram_alloc: rounded size = %08lx\n", size );
456 if (!mem_init_done) {
457 /* before mem_init(): allocate "statically", i.e. either in the kernel
458 * data space (current end in *start_mem), or at the end of currently
459 * reserved ST-RAM. */
460 if (kernel_in_stram) {
461 /* Get memory from kernel data space */
462 *start_mem = ALIGN_IF_SWAP(*start_mem);
463 addr = (void *)*start_mem;
464 *start_mem += size;
465 DPRINTK( "atari_stram_alloc: pre-mem_init and k/ST: "
466 "shifted start_mem to %08lx, addr=%p\n",
467 *start_mem, addr );
469 else {
470 /* Get memory from rsvd_stram_beg */
471 if (rsvd_stram_end + size < stram_end) {
472 addr = (void *) rsvd_stram_end;
473 rsvd_stram_end += size;
474 DPRINTK( "atari_stram_alloc: pre-mem_init and k/TT: "
475 "shifted rsvd_stram_end to %08lx, addr=%p\n",
476 rsvd_stram_end, addr );
479 flags = BLOCK_STATIC;
481 #ifdef CONFIG_STRAM_SWAP
482 else if (max_swap_size) {
483 /* If swapping is active (can only be the case after mem_init()!):
484 * make some free space in the swap "device". */
485 DPRINTK( "atari_stram_alloc: after mem_init, swapping ok, "
486 "calling get_region\n" );
487 addr = get_stram_region( N_PAGES(size) );
488 flags = BLOCK_INSWAP;
490 #endif
491 else {
492 /* After mem_init() and no swapping: can only resort to
493 * __get_dma_pages() */
494 addr = (void *)__get_dma_pages(GFP_KERNEL, get_gfp_order(size));
495 flags = BLOCK_GFP;
496 DPRINTK( "atari_stram_alloc: after mem_init, swapping off, "
497 "get_pages=%p\n", addr );
500 if (addr) {
501 if (!(block = add_region( addr, size ))) {
502 /* out of memory for BLOCK structure :-( */
503 DPRINTK( "atari_stram_alloc: out of mem for BLOCK -- "
504 "freeing again\n" );
505 if (flags == BLOCK_STATIC)
506 rsvd_stram_end -= size;
507 #ifdef CONFIG_STRAM_SWAP
508 else if (flags == BLOCK_INSWAP)
509 free_stram_region( SWAP_NR(addr), N_PAGES(size) );
510 #endif
511 else
512 free_pages( (unsigned long)addr, get_gfp_order(size));
513 return( NULL );
515 block->owner = owner;
516 block->flags |= flags;
518 return( addr );
521 void atari_stram_free( void *addr )
524 BLOCK *block;
526 DPRINTK( "atari_stram_free(addr=%p)\n", addr );
528 if (!(block = find_region( addr ))) {
529 printk( KERN_ERR "Attempt to free non-allocated ST-RAM block at %p "
530 "from %p\n", addr, __builtin_return_address(0) );
531 return;
533 DPRINTK( "atari_stram_free: found block (%p): size=%08lx, owner=%s, "
534 "flags=%02x\n", block, block->size, block->owner, block->flags );
536 #ifdef CONFIG_STRAM_SWAP
537 if (!max_swap_size) {
538 #endif
539 if (block->flags & BLOCK_GFP) {
540 DPRINTK( "atari_stram_free: is kmalloced, order_size=%d\n",
541 get_gfp_order(block->size) );
542 free_pages( (unsigned long)addr, get_gfp_order(block->size) );
544 else
545 goto fail;
546 #ifdef CONFIG_STRAM_SWAP
548 else if (block->flags & (BLOCK_INSWAP|BLOCK_STATIC)) {
549 DPRINTK( "atari_stram_free: is swap-alloced\n" );
550 free_stram_region( SWAP_NR(block->start), N_PAGES(block->size) );
552 else
553 goto fail;
554 #endif
555 remove_region( block );
556 return;
558 fail:
559 printk( KERN_ERR "atari_stram_free: cannot free block at %p "
560 "(called from %p)\n", addr, __builtin_return_address(0) );
564 #ifdef CONFIG_STRAM_SWAP
567 /* ------------------------------------------------------------------------ */
568 /* Main Swapping Functions */
569 /* ------------------------------------------------------------------------ */
573 * Initialize ST-RAM swap device
574 * (lots copied and modified from sys_swapon() in mm/swapfile.c)
576 __initfunc(static int swap_init( unsigned long start_mem,
577 unsigned long swap_data ))
579 static struct dentry fake_dentry[3];
580 struct swap_info_struct *p;
581 struct inode swap_inode;
582 unsigned int type;
583 unsigned long addr;
584 int i, j, k, prev;
586 DPRINTK( "swap_init(start_mem=%08lx, swap_data=%08lx)\n",
587 start_mem, swap_data );
589 /* need at least one page for swapping to (and this also isn't very
590 * much... :-) */
591 if (swap_end - swap_start < 2*PAGE_SIZE) {
592 printk( KERN_WARNING "stram_swap_init: swap space too small\n" );
593 return( 0 );
596 /* find free slot in swap_info */
597 for( p = swap_info, type = 0; type < nr_swapfiles; type++, p++ )
598 if (!(p->flags & SWP_USED))
599 break;
600 if (type >= MAX_SWAPFILES) {
601 printk( KERN_WARNING "stram_swap_init: max. number of "
602 "swap devices exhausted\n" );
603 return( 0 );
605 if (type >= nr_swapfiles)
606 nr_swapfiles = type+1;
608 stram_swap_info = p;
609 stram_swap_type = type;
611 /* fake some dir cache entries to give us some name in /dev/swaps */
612 fake_dentry[0].d_covers = &fake_dentry[1];
613 fake_dentry[0].d_parent = &fake_dentry[0];
614 fake_dentry[1].d_parent = &fake_dentry[2];
615 fake_dentry[1].d_name.name = "stram (internal)";
616 fake_dentry[1].d_name.len = 16;
617 fake_dentry[2].d_covers = &fake_dentry[2];
618 fake_dentry[2].d_parent = &fake_dentry[2];
620 p->flags = SWP_USED;
621 p->swap_file = &fake_dentry[0];
622 p->swap_device = 0;
623 p->swap_lockmap = (unsigned char *)(swap_data);
624 p->swap_map = (unsigned char *)(swap_data + PAGE_SIZE);
625 p->cluster_nr = 0;
626 p->next = -1;
627 p->prio = 0x7ff0; /* a rather high priority, but not the higest
628 * to give the user a chance to override */
630 /* call stram_open() directly, avoids at least the overhead in
631 * constructing a dummy file structure... */
632 p->swap_device = MKDEV( STRAM_MAJOR, STRAM_MINOR );
633 swap_inode.i_rdev = p->swap_device;
634 stram_open( &swap_inode, MAGIC_FILE_P );
635 p->max = SWAP_NR(swap_end);
637 /* initialize lockmap */
638 memset( p->swap_lockmap, 0, PAGE_SIZE );
640 /* initialize swap_map: set regions that are already allocated or belong
641 * to kernel data space to SWP_RSVD, otherwise to free */
642 j = 0; /* # of free pages */
643 k = 0; /* # of already allocated pages (from pre-mem_init stram_alloc()) */
644 p->lowest_bit = 0;
645 p->highest_bit = 0;
646 for( i = 1, addr = (unsigned long)SWAP_ADDR(1); i < p->max;
647 i++, addr += PAGE_SIZE ) {
648 if (in_some_region( addr )) {
649 p->swap_map[i] = SWP_RSVD;
650 ++k;
652 else if (kernel_in_stram && addr < start_mem ) {
653 p->swap_map[i] = SWP_RSVD;
655 else {
656 p->swap_map[i] = 0;
657 ++j;
658 if (!p->lowest_bit) p->lowest_bit = i;
659 p->highest_bit = i;
662 /* first page always reserved (and doesn't really belong to swap space) */
663 p->swap_map[0] = SWP_RSVD;
665 /* now swapping to this device ok */
666 p->pages = j + k;
667 nr_swap_pages += j;
668 p->flags = SWP_WRITEOK;
670 /* insert swap space into swap_list */
671 prev = -1;
672 for (i = swap_list.head; i >= 0; i = swap_info[i].next) {
673 if (p->prio >= swap_info[i].prio) {
674 break;
676 prev = i;
678 p->next = i;
679 if (prev < 0) {
680 swap_list.head = swap_list.next = p - swap_info;
681 } else {
682 swap_info[prev].next = p - swap_info;
685 printk( KERN_INFO "Using %dk (%d pages) of ST-RAM as swap space.\n",
686 p->pages << 2, p->pages );
687 return( 1 );
692 * The swap entry has been read in advance, and we return 1 to indicate
693 * that the page has been used or is no longer needed.
695 static inline int unswap_pte( struct vm_area_struct * vma, unsigned long
696 address, pte_t *dir, unsigned long entry,
697 unsigned long page, int isswap )
699 pte_t pte = *dir;
701 if (pte_none(pte))
702 return 0;
703 if (pte_present(pte)) {
704 struct page *pg;
705 unsigned long page_nr = MAP_NR(pte_page(pte));
706 unsigned long pg_swap_entry;
708 if (page_nr >= max_mapnr)
709 return 0;
710 pg = mem_map + page_nr;
711 if (!(pg_swap_entry = in_swap_cache(pg)))
712 return 0;
713 if (pg_swap_entry != entry)
714 return 0;
715 if (isswap) {
716 DPRINTK( "unswap_pte: page %08lx = entry %08lx was in swap cache; "
717 "exchanging to %08lx\n",
718 page_address(pg), entry, page );
719 pg->offset = page;
720 swap_free(entry);
721 return 1;
723 else {
724 DPRINTK( "unswap_pte: page %08lx = entry %08lx was in swap cache; "
725 "deleted there\n", page_address(pg), entry );
726 delete_from_swap_cache(pg);
727 set_pte(dir, pte_mkdirty(pte));
728 free_page(page);
729 return 1;
732 if (pte_val(pte) != entry)
733 return 0;
735 if (isswap) {
736 DPRINTK( "unswap_pte: replacing entry %08lx by %08lx", entry, page );
737 set_pte(dir, __pte(page));
739 else {
740 DPRINTK( "unswap_pte: replacing entry %08lx by new page %08lx",
741 entry, page );
742 set_pte(dir, pte_mkwrite(pte_mkdirty(mk_pte(page,vma->vm_page_prot))));
743 ++vma->vm_mm->rss;
745 swap_free(entry);
746 return 1;
749 static inline int unswap_pmd( struct vm_area_struct * vma, pmd_t *dir,
750 unsigned long address, unsigned long size,
751 unsigned long offset, unsigned long entry,
752 unsigned long page, int isswap )
754 pte_t * pte;
755 unsigned long end;
757 if (pmd_none(*dir))
758 return 0;
759 if (pmd_bad(*dir)) {
760 printk("unswap_pmd: bad pmd (%08lx)\n", pmd_val(*dir));
761 pmd_clear(dir);
762 return 0;
764 pte = pte_offset(dir, address);
765 offset += address & PMD_MASK;
766 address &= ~PMD_MASK;
767 end = address + size;
768 if (end > PMD_SIZE)
769 end = PMD_SIZE;
770 do {
771 if (unswap_pte( vma, offset+address-vma->vm_start, pte, entry,
772 page, isswap ))
773 return 1;
774 address += PAGE_SIZE;
775 pte++;
776 } while (address < end);
777 return 0;
780 static inline int unswap_pgd( struct vm_area_struct * vma, pgd_t *dir,
781 unsigned long address, unsigned long size,
782 unsigned long entry, unsigned long page,
783 int isswap )
785 pmd_t * pmd;
786 unsigned long offset, end;
788 if (pgd_none(*dir))
789 return 0;
790 if (pgd_bad(*dir)) {
791 printk("unswap_pgd: bad pgd (%08lx)\n", pgd_val(*dir));
792 pgd_clear(dir);
793 return 0;
795 pmd = pmd_offset(dir, address);
796 offset = address & PGDIR_MASK;
797 address &= ~PGDIR_MASK;
798 end = address + size;
799 if (end > PGDIR_SIZE)
800 end = PGDIR_SIZE;
801 do {
802 if (unswap_pmd( vma, pmd, address, end - address, offset, entry,
803 page, isswap ))
804 return 1;
805 address = (address + PMD_SIZE) & PMD_MASK;
806 pmd++;
807 } while (address < end);
808 return 0;
811 static int unswap_vma( struct vm_area_struct * vma, pgd_t *pgdir,
812 unsigned long entry, unsigned long page, int isswap )
814 unsigned long start = vma->vm_start, end = vma->vm_end;
816 while( start < end ) {
817 if (unswap_pgd( vma, pgdir, start, end - start, entry, page, isswap ))
818 return 1;
819 start = (start + PGDIR_SIZE) & PGDIR_MASK;
820 pgdir++;
822 return 0;
825 static int unswap_process( struct mm_struct * mm, unsigned long entry,
826 unsigned long page, int isswap )
828 struct vm_area_struct* vma;
829 int retval = 0;
832 * Go through process' page directory.
834 if (!mm || mm == &init_mm)
835 return 0;
836 down(&mm->mmap_sem);
837 for( vma = mm->mmap; vma; vma = vma->vm_next ) {
838 pgd_t * pgd = pgd_offset(mm, vma->vm_start);
839 if (unswap_vma( vma, pgd, entry, page, isswap )) {
840 retval = 1;
841 break;
844 up(&mm->mmap_sem);
845 return retval;
849 static int unswap_by_move( unsigned char *map, unsigned long max,
850 unsigned long start, unsigned long n_pages )
852 struct task_struct *p;
853 unsigned long entry, rover = (start == 1) ? n_pages+1 : 1;
854 unsigned long i, j;
856 DPRINTK( "unswapping %lu..%lu by moving in swap\n",
857 start, start+n_pages-1 );
859 /* can free the allocated pages by moving them to other swap pages */
860 for( i = start; i < start+n_pages; ++i ) {
861 if (!map[i]) {
862 map[i] = SWP_RSVD;
863 DPRINTK( "unswap: page %lu was free\n", i );
864 continue;
866 else if (map[i] == SWP_RSVD) {
867 printk( KERN_ERR "get_stram_region: page %lu already "
868 "reserved??\n", i );
870 DPRINTK( "unswap: page %lu is alloced, count=%u\n", i, map[i] );
872 /* find a free page not in our region */
873 for( j = rover; j != rover-1; j = (j == max-1) ? 1 : j+1 ) {
874 if (j >= start && j < start+n_pages)
875 continue;
876 if (!map[j]) {
877 rover = j+1;
878 break;
881 if (j == rover-1) {
882 printk( KERN_ERR "get_stram_region: not enough free swap "
883 "pages now??\n" );
884 return( -ENOMEM );
886 DPRINTK( "unswap: map[i=%lu]=%u map[j=%lu]=%u nr_swap=%u\n",
887 i, map[i], j, map[j], nr_swap_pages );
889 --nr_swap_pages;
890 entry = SWP_ENTRY( stram_swap_type, j );
891 if (stram_swap_info->lowest_bit == j)
892 stram_swap_info->lowest_bit++;
893 if (stram_swap_info->highest_bit == j)
894 stram_swap_info->highest_bit--;
896 memcpy( SWAP_ADDR(j), SWAP_ADDR(i), PAGE_SIZE );
897 #ifdef DO_PROC
898 stat_swap_move++;
899 #endif
901 while( map[i] ) {
902 for_each_task(p) {
903 if (unswap_process( p->mm, SWP_ENTRY( stram_swap_type, i ),
904 entry, 1 )) {
905 map[j]++;
906 goto repeat;
909 if (map[i] && map[i] != 127) {
910 printk( KERN_ERR "get_stram_region: ST-RAM swap page %lu "
911 "not used by any process\n", i );
912 /* quit while loop and overwrite bad map entry */
913 break;
915 else if (!map[i]) {
916 /* somebody else must have swapped in that page, so free the
917 * new one (we're moving to) */
918 DPRINTK( "unswap: map[i] became 0, also clearing map[j]\n" );
919 map[j] = 0;
921 repeat:
924 DPRINTK( "unswap: map[i=%lu]=%u map[j=%lu]=%u nr_swap=%u\n",
925 i, map[i], j, map[j], nr_swap_pages );
926 map[i] = SWP_RSVD;
927 if (stram_swap_info->lowest_bit == i)
928 stram_swap_info->lowest_bit++;
929 if (stram_swap_info->highest_bit == i)
930 stram_swap_info->highest_bit--;
931 --nr_swap_pages;
933 return( 0 );
936 static int unswap_by_read( unsigned char *map, unsigned long max,
937 unsigned long start, unsigned long n_pages )
939 struct task_struct *p;
940 unsigned long entry, page = 0;
941 unsigned long i;
943 DPRINTK( "unswapping %lu..%lu by reading in\n",
944 start, start+n_pages-1 );
946 for( i = start; i < start+n_pages; ++i ) {
947 if (map[i] == SWP_RSVD) {
948 printk( KERN_ERR "get_stram_region: page %lu already "
949 "reserved??\n", i );
950 continue;
952 entry = SWP_ENTRY( stram_swap_type, i );
953 DPRINTK( "unswap: map[i=%lu]=%u nr_swap=%u\n",
954 i, map[i], nr_swap_pages );
956 while( map[i] ) {
957 if (!page && !(page = __get_free_page(GFP_KERNEL))) {
958 printk( KERN_NOTICE "get_stram_region: out of memory\n" );
959 return( -ENOMEM );
961 DPRINTK( "unswap: reading swap page %lu to %08lx\n", i, page );
962 rw_swap_page( READ, entry, (char *)page, 1 );
964 for_each_task(p) {
965 if (unswap_process( p->mm, entry, page, 0 )) {
966 page = 0;
967 #ifdef DO_PROC
968 stat_swap_force++;
969 #endif
970 break;
973 if (page) {
975 * If we couldn't find an entry, there are several
976 * possible reasons: someone else freed it first,
977 * we freed the last reference to an overflowed entry,
978 * or the system has lost track of the use counts.
980 if (map[i] && map[i] != SWP_RSVD-1)
981 printk( KERN_ERR "get_stram_region: swap entry %08lx "
982 "not used by any process\n", entry );
983 /* quit while loop and overwrite bad map entry */
984 if (!map[i]) {
985 DPRINTK( "unswap: map[i] became 0\n" );
987 break;
991 DPRINTK( "unswap: map[i=%lu]=%u nr_swap=%u\n",
992 i, map[i], nr_swap_pages );
993 map[i] = SWP_RSVD;
994 if (stram_swap_info->lowest_bit == i)
995 stram_swap_info->lowest_bit++;
996 if (stram_swap_info->highest_bit == i)
997 stram_swap_info->highest_bit--;
998 --nr_swap_pages;
1001 if (page)
1002 free_page(page);
1003 return( 0 );
1007 * reserve a region in ST-RAM swap space for an allocation
1009 static void *get_stram_region( unsigned long n_pages )
1011 unsigned char *map = stram_swap_info->swap_map;
1012 unsigned long max = stram_swap_info->max;
1013 unsigned long start, total_free, region_free;
1014 int err;
1015 void *ret = NULL;
1017 DPRINTK( "get_stram_region(n_pages=%lu)\n", n_pages );
1019 /* disallow writing to the swap device now */
1020 stram_swap_info->flags = SWP_USED;
1022 /* find a region of n_pages pages in the swap space including as much free
1023 * pages as possible (and excluding any already-reserved pages). */
1024 if (!(start = find_free_region( n_pages, &total_free, &region_free )))
1025 goto end;
1026 DPRINTK( "get_stram_region: region starts at %lu, has %lu free pages\n",
1027 start, region_free );
1029 err = ((total_free-region_free >= n_pages-region_free) ?
1030 unswap_by_move( map, max, start, n_pages ) :
1031 unswap_by_read( map, max, start, n_pages ));
1032 if (err)
1033 goto end;
1035 ret = SWAP_ADDR(start);
1036 end:
1037 /* allow using swap device again */
1038 stram_swap_info->flags = SWP_WRITEOK;
1039 DPRINTK( "get_stram_region: returning %p\n", ret );
1040 return( ret );
1045 * free a reserved region in ST-RAM swap space
1047 static void free_stram_region( unsigned long offset, unsigned long n_pages )
1049 unsigned char *map = stram_swap_info->swap_map;
1051 DPRINTK( "free_stram_region(offset=%lu,n_pages=%lu)\n", offset, n_pages );
1053 if (offset < 1 || offset + n_pages > stram_swap_info->max) {
1054 printk( KERN_ERR "free_stram_region: Trying to free non-ST-RAM\n" );
1055 return;
1058 /* un-reserve the freed pages */
1059 for( ; n_pages > 0; ++offset, --n_pages ) {
1060 if (map[offset] != SWP_RSVD)
1061 printk( KERN_ERR "free_stram_region: Swap page %lu was not "
1062 "reserved\n", offset );
1063 map[offset] = 0;
1066 /* update swapping meta-data */
1067 if (offset < stram_swap_info->lowest_bit)
1068 stram_swap_info->lowest_bit = offset;
1069 if (offset+n_pages-1 > stram_swap_info->highest_bit)
1070 stram_swap_info->highest_bit = offset+n_pages-1;
1071 if (stram_swap_info->prio > swap_info[swap_list.next].prio)
1072 swap_list.next = swap_list.head;
1073 nr_swap_pages += n_pages;
1077 /* ------------------------------------------------------------------------ */
1078 /* Utility Functions for Swapping */
1079 /* ------------------------------------------------------------------------ */
1082 /* is addr in some of the allocated regions? */
1083 static int in_some_region( unsigned long addr )
1085 BLOCK *p;
1087 for( p = alloc_list; p; p = p->next ) {
1088 if (p->start <= addr && addr < p->start + p->size)
1089 return( 1 );
1091 return( 0 );
1095 static unsigned long find_free_region( unsigned long n_pages,
1096 unsigned long *total_free,
1097 unsigned long *region_free )
1099 unsigned char *map = stram_swap_info->swap_map;
1100 unsigned long max = stram_swap_info->max;
1101 unsigned long head, tail, max_start;
1102 long nfree, max_free;
1104 /* first scan the swap space for a suitable place for the allocation */
1105 head = 1;
1106 max_start = 0;
1107 max_free = -1;
1108 *total_free = 0;
1110 start_over:
1111 /* increment tail until final window size reached, and count free pages */
1112 nfree = 0;
1113 for( tail = head; tail-head < n_pages && tail < max-n_pages; ++tail ) {
1114 if (map[tail] == SWP_RSVD) {
1115 head = tail+1;
1116 goto start_over;
1118 if (!map[tail]) {
1119 ++nfree;
1120 ++*total_free;
1123 if (tail-head < n_pages)
1124 goto out;
1125 if (nfree > max_free) {
1126 max_start = head;
1127 max_free = nfree;
1128 if (max_free >= n_pages)
1129 /* don't need more free pages... :-) */
1130 goto out;
1133 /* now shift the window and look for the area where as much pages as
1134 * possible are free */
1135 while( tail < max ) {
1136 nfree -= (map[head++] == 0);
1137 if (map[tail] == SWP_RSVD) {
1138 head = tail+1;
1139 goto start_over;
1141 if (!map[tail]) {
1142 ++nfree;
1143 ++*total_free;
1145 ++tail;
1146 if (nfree > max_free) {
1147 max_start = head;
1148 max_free = nfree;
1149 if (max_free >= n_pages)
1150 /* don't need more free pages... :-) */
1151 goto out;
1155 out:
1156 if (max_free < 0) {
1157 printk( KERN_NOTICE "get_stram_region: ST-RAM too full or fragmented "
1158 "-- can't allocate %lu pages\n", n_pages );
1159 return( 0 );
1162 *region_free = max_free;
1163 return( max_start );
1167 /* setup parameters from command line */
1168 __initfunc(void stram_swap_setup(char *str, int *ints))
1170 if (ints[0] >= 1)
1171 max_swap_size = ((ints[1] < 0 ? 0 : ints[1]) * 1024) & PAGE_MASK;
1175 /* ------------------------------------------------------------------------ */
1176 /* ST-RAM device */
1177 /* ------------------------------------------------------------------------ */
1179 static int stram_blocksizes[14] = {
1180 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4096 };
1181 static int stram_sizes[14] = {
1182 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1183 static int refcnt = 0;
1185 static void do_stram_request( void )
1187 unsigned long start, len;
1189 while( CURRENT ) {
1190 if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)
1191 panic("stram: request list destroyed");
1192 if (CURRENT->bh) {
1193 if (!buffer_locked(CURRENT->bh))
1194 panic("stram: block not locked");
1197 start = swap_start + (CURRENT->sector << 9);
1198 len = CURRENT->current_nr_sectors << 9;
1199 if ((start + len) > swap_end) {
1200 printk( KERN_ERR "stram: bad access beyond end of device: "
1201 "block=%ld, count=%ld\n",
1202 CURRENT->sector,
1203 CURRENT->current_nr_sectors );
1204 end_request( 0 );
1205 continue;
1208 if (CURRENT->cmd == READ) {
1209 memcpy( CURRENT->buffer, (char *)start, len );
1210 #ifdef DO_PROC
1211 stat_swap_read += N_PAGES(len);
1212 #endif
1214 else {
1215 memcpy( (char *)start, CURRENT->buffer, len );
1216 #ifdef DO_PROC
1217 stat_swap_write += N_PAGES(len);
1218 #endif
1220 end_request( 1 );
1225 static int stram_open( struct inode *inode, struct file *filp )
1227 if (filp != MAGIC_FILE_P) {
1228 printk( KERN_NOTICE "Only kernel can open ST-RAM device\n" );
1229 return( -EPERM );
1231 if (MINOR(inode->i_rdev) != STRAM_MINOR)
1232 return( -ENXIO );
1233 if (refcnt)
1234 return( -EBUSY );
1235 ++refcnt;
1236 return( 0 );
1239 static int stram_release( struct inode *inode, struct file *filp )
1241 if (filp != MAGIC_FILE_P) {
1242 printk( KERN_NOTICE "Only kernel can close ST-RAM device\n" );
1243 return( -EPERM );
1245 if (refcnt > 0)
1246 --refcnt;
1247 return( 0 );
1251 static struct file_operations stram_fops = {
1252 NULL, /* lseek - default */
1253 block_read, /* read - general block-dev read */
1254 block_write, /* write - general block-dev write */
1255 NULL, /* readdir - bad */
1256 NULL, /* select */
1257 NULL, /* ioctl */
1258 NULL, /* mmap */
1259 stram_open, /* open */
1260 NULL, /* flush */
1261 stram_release, /* release */
1262 block_fsync /* fsync */
1265 __initfunc(int stram_device_init(void))
1268 if (!MACH_IS_ATARI)
1269 /* no point in initializing this, I hope */
1270 return( -ENXIO );
1272 if (!max_swap_size)
1273 /* swapping not enabled */
1274 return( -ENXIO );
1276 if (register_blkdev( STRAM_MAJOR, "stram", &stram_fops)) {
1277 printk( KERN_ERR "stram: Unable to get major %d\n", STRAM_MAJOR );
1278 return( -ENXIO );
1281 blk_dev[STRAM_MAJOR].request_fn = do_stram_request;
1282 blksize_size[STRAM_MAJOR] = stram_blocksizes;
1283 stram_sizes[STRAM_MINOR] = (swap_end - swap_start)/1024;
1284 blk_size[STRAM_MAJOR] = stram_sizes;
1285 do_z2_request(); /* to avoid warning */
1286 return( 0 );
1289 /* to avoid warning */
1290 static void do_z2_request( void ) { }
1292 #endif /* CONFIG_STRAM_SWAP */
1295 /* ------------------------------------------------------------------------ */
1296 /* Misc Utility Functions */
1297 /* ------------------------------------------------------------------------ */
1300 /* return log2 of #pages for size */
1301 static int get_gfp_order( unsigned long size )
1303 int order;
1305 size = N_PAGES( size + PAGE_SIZE -1 );
1306 order = -1;
1307 do {
1308 size >>= 1;
1309 order++;
1310 } while (size);
1312 return( order );
1316 /* reserve a range of pages in mem_map[] */
1317 static void reserve_region( unsigned long addr, unsigned long end )
1319 mem_map_t *mapp = &mem_map[MAP_NR(addr)];
1321 for( ; addr < end; addr += PAGE_SIZE, ++mapp )
1322 set_bit( PG_reserved, &mapp->flags );
1327 /* ------------------------------------------------------------------------ */
1328 /* Region Management */
1329 /* ------------------------------------------------------------------------ */
1332 /* insert a region into the alloced list (sorted) */
1333 static BLOCK *add_region( void *addr, unsigned long size )
1335 BLOCK **p, *n = NULL;
1336 int i;
1338 for( i = 0; i < N_STATIC_BLOCKS; ++i ) {
1339 if (static_blocks[i].flags & BLOCK_FREE) {
1340 n = &static_blocks[i];
1341 n->flags = 0;
1342 break;
1345 if (!n && mem_init_done) {
1346 /* if statics block pool exhausted and we can call kmalloc() already
1347 * (after mem_init()), try that */
1348 n = kmalloc( sizeof(BLOCK), GFP_KERNEL );
1349 if (n)
1350 n->flags = BLOCK_KMALLOCED;
1352 if (!n) {
1353 printk( KERN_ERR "Out of memory for ST-RAM descriptor blocks\n" );
1354 return( NULL );
1356 n->start = (unsigned long)addr;
1357 n->size = size;
1359 for( p = &alloc_list; *p; p = &((*p)->next) )
1360 if ((*p)->start > (unsigned long)addr) break;
1361 n->next = *p;
1362 *p = n;
1364 return( n );
1368 /* find a region (by start addr) in the alloced list */
1369 static BLOCK *find_region( void *addr )
1371 BLOCK *p;
1373 for( p = alloc_list; p; p = p->next ) {
1374 if (p->start == (unsigned long)addr)
1375 return( p );
1376 if (p->start > (unsigned long)addr)
1377 break;
1379 return( NULL );
1383 /* remove a block from the alloced list */
1384 static int remove_region( BLOCK *block )
1386 BLOCK **p;
1388 for( p = &alloc_list; *p; p = &((*p)->next) )
1389 if (*p == block) break;
1390 if (!*p)
1391 return( 0 );
1393 *p = block->next;
1394 if (block->flags & BLOCK_KMALLOCED)
1395 kfree( block );
1396 else
1397 block->flags |= BLOCK_FREE;
1398 return( 1 );
1403 /* ------------------------------------------------------------------------ */
1404 /* /proc statistics file stuff */
1405 /* ------------------------------------------------------------------------ */
1407 #ifdef DO_PROC
1409 #define PRINT_PROC(fmt,args...) len += sprintf( buf+len, fmt, ##args )
1411 int get_stram_list( char *buf )
1413 int len = 0;
1414 BLOCK *p;
1415 #ifdef CONFIG_STRAM_SWAP
1416 int i;
1417 unsigned char *map = stram_swap_info->swap_map;
1418 unsigned long max = stram_swap_info->max;
1419 unsigned free = 0, used = 0, rsvd = 0;
1420 #endif
1422 #ifdef CONFIG_STRAM_SWAP
1423 if (max_swap_size) {
1424 for( i = 1; i < max; ++i ) {
1425 if (!map[i])
1426 ++free;
1427 else if (map[i] == SWP_RSVD)
1428 ++rsvd;
1429 else
1430 ++used;
1432 PRINT_PROC(
1433 "Total ST-RAM: %8lu kB\n"
1434 "Total ST-RAM swap: %8lu kB\n"
1435 "Free swap: %8u kB\n"
1436 "Used swap: %8u kB\n"
1437 "Allocated swap: %8u kB\n"
1438 "Swap Reads: %8u\n"
1439 "Swap Writes: %8u\n"
1440 "Swap Moves: %8u\n"
1441 "Swap Forced Reads: %8u\n",
1442 (stram_end - stram_start) >> 10,
1443 (max-1) << (PAGE_SHIFT-10),
1444 free << (PAGE_SHIFT-10),
1445 used << (PAGE_SHIFT-10),
1446 rsvd << (PAGE_SHIFT-10),
1447 stat_swap_read,
1448 stat_swap_write,
1449 stat_swap_move,
1450 stat_swap_force );
1452 else {
1453 #endif
1454 PRINT_PROC( "ST-RAM swapping disabled\n" );
1455 PRINT_PROC(
1456 "Total ST-RAM: %8lu kB\n"
1457 "Reserved ST-RAM: %8lu kB\n",
1458 (stram_end - stram_start) >> 10,
1459 (rsvd_stram_end - rsvd_stram_beg) >> 10 );
1460 #ifdef CONFIG_STRAM_SWAP
1462 #endif
1464 PRINT_PROC( "Allocated regions:\n" );
1465 for( p = alloc_list; p; p = p->next ) {
1466 if (len + 50 >= PAGE_SIZE)
1467 break;
1468 PRINT_PROC( "0x%08lx-0x%08lx: %s (",
1469 VTOP(p->start), VTOP(p->start+p->size-1), p->owner );
1470 if (p->flags & BLOCK_STATIC)
1471 PRINT_PROC( "static)\n" );
1472 else if (p->flags & BLOCK_GFP)
1473 PRINT_PROC( "page-alloced)\n" );
1474 else if (p->flags & BLOCK_INSWAP)
1475 PRINT_PROC( "in swap)\n" );
1476 else
1477 PRINT_PROC( "??)\n" );
1480 return( len );
1483 #endif
1487 * Local variables:
1488 * c-indent-level: 4
1489 * tab-width: 4
1490 * End: