1
2
3
4
5
6
7
8
9
10
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/slab.h>
20#include <linux/vmalloc.h>
21#include <linux/pagemap.h>
22#include <linux/shm.h>
23#include <linux/bootmem.h>
24
25#include <asm/setup.h>
26#include <asm/machdep.h>
27#include <asm/page.h>
28#include <asm/pgtable.h>
29#include <asm/atarihw.h>
30#include <asm/atari_stram.h>
31#include <asm/io.h>
32#include <asm/semaphore.h>
33
34
35#ifdef CONFIG_STRAM_SWAP
36#define MAJOR_NR Z2RAM_MAJOR
37#define do_z2_request do_stram_request
38#include <linux/blk.h>
39#undef DEVICE_NAME
40#define DEVICE_NAME "stram"
41#endif
42
43#undef DEBUG
44
45#ifdef DEBUG
46#define DPRINTK(fmt,args...) printk( fmt, ##args )
47#else
48#define DPRINTK(fmt,args...)
49#endif
50
51#if defined(CONFIG_PROC_FS) && defined(CONFIG_STRAM_PROC)
52
53#define DO_PROC
54#include <linux/proc_fs.h>
55#endif
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132#ifdef CONFIG_STRAM_SWAP
133#define ALIGN_IF_SWAP(x) PAGE_ALIGN(x)
134#else
135#define ALIGN_IF_SWAP(x) (x)
136#endif
137
138
139#define SWAP_NR(addr) (((addr) - swap_start) >> PAGE_SHIFT)
140
141
142#define SWAP_ADDR(nr) (swap_start + ((nr) << PAGE_SHIFT))
143
144
145#define N_PAGES(n) ((n) >> PAGE_SHIFT)
146
147
148
149
150#define MAX_STRAM_FRACTION_NOM 1
151#define MAX_STRAM_FRACTION_DENOM 3
152
153
154static void *stram_start, *stram_end;
155
156
157
158static int mem_init_done = 0;
159
160
161static int kernel_in_stram;
162
163typedef struct stram_block {
164 struct stram_block *next;
165 void *start;
166 unsigned long size;
167 unsigned flags;
168 const char *owner;
169} BLOCK;
170
171
172#define BLOCK_FREE 0x01
173#define BLOCK_KMALLOCED 0x02
174#define BLOCK_GFP 0x08
175#define BLOCK_INSWAP 0x10
176
177
178static BLOCK *alloc_list = NULL;
179
180
181
182
183
184#define N_STATIC_BLOCKS 20
185static BLOCK static_blocks[N_STATIC_BLOCKS];
186
187#ifdef CONFIG_STRAM_SWAP
188
189
190
191
192
193static int max_swap_size = 0;
194
195
196static void *swap_start, *swap_end;
197
198
199static struct swap_info_struct *stram_swap_info;
200
201
202static int stram_swap_type;
203
204
205static DECLARE_MUTEX(stram_swap_sem);
206
207
208
209
210
211#define STRAM_MAJOR Z2RAM_MAJOR
212#define STRAM_MINOR 13
213
214
215#define MAGIC_FILE_P (struct file *)0xffffdead
216
217#ifdef DO_PROC
218static unsigned stat_swap_read = 0;
219static unsigned stat_swap_write = 0;
220static unsigned stat_swap_force = 0;
221#endif
222
223#endif
224
225
226
227#ifdef CONFIG_STRAM_SWAP
228static int swap_init(void *start_mem, void *swap_data);
229static void *get_stram_region( unsigned long n_pages );
230static void free_stram_region( unsigned long offset, unsigned long n_pages
231 );
232static int in_some_region(void *addr);
233static unsigned long find_free_region( unsigned long n_pages, unsigned long
234 *total_free, unsigned long
235 *region_free );
236static void do_stram_request(request_queue_t *);
237static int stram_open( struct inode *inode, struct file *filp );
238static int stram_release( struct inode *inode, struct file *filp );
239static void reserve_region(void *start, void *end);
240#endif
241static BLOCK *add_region( void *addr, unsigned long size );
242static BLOCK *find_region( void *addr );
243static int remove_region( BLOCK *block );
244
245
246
247
248
249
250
251
252
253
254
255
256void __init atari_stram_init(void)
257{
258 int i;
259
260
261 for( i = 0; i < N_STATIC_BLOCKS; ++i )
262 static_blocks[i].flags = BLOCK_FREE;
263
264
265
266 stram_start = phys_to_virt(0);
267 kernel_in_stram = (stram_start == 0);
268
269 for( i = 0; i < m68k_num_memory; ++i ) {
270 if (m68k_memory[i].addr == 0) {
271
272 stram_end = stram_start + m68k_memory[i].size;
273 return;
274 }
275 }
276
277 panic( "atari_stram_init: no ST-RAM found!" );
278}
279
280
281
282
283
284
285void __init atari_stram_reserve_pages(void *start_mem)
286{
287#ifdef CONFIG_STRAM_SWAP
288
289
290 if (max_swap_size < 0)
291
292
293
294
295
296 max_swap_size =
297 (!MACH_IS_HADES &&
298 (N_PAGES(stram_end-stram_start)*MAX_STRAM_FRACTION_DENOM <=
299 ((unsigned long)high_memory>>PAGE_SHIFT)*MAX_STRAM_FRACTION_NOM)) ? 16*1024*1024 : 0;
300 DPRINTK( "atari_stram_reserve_pages: max_swap_size = %d\n", max_swap_size );
301#endif
302
303
304
305 if (!kernel_in_stram)
306 reserve_bootmem (0, PAGE_SIZE);
307
308#ifdef CONFIG_STRAM_SWAP
309 if (max_swap_size) {
310 void *swap_data;
311
312 start_mem = (void *) PAGE_ALIGN ((unsigned long) start_mem);
313
314
315
316 swap_start = !kernel_in_stram ? stram_start + PAGE_SIZE : start_mem;
317
318
319
320 swap_start -= PAGE_SIZE;
321 swap_end = stram_end;
322 if (swap_end-swap_start > max_swap_size)
323 swap_end = swap_start + max_swap_size;
324 DPRINTK( "atari_stram_reserve_pages: swapping enabled; "
325 "swap=%p-%p\n", swap_start, swap_end);
326
327
328
329
330 swap_data = start_mem;
331 start_mem += ((SWAP_NR(swap_end) + PAGE_SIZE/2 - 1)
332 >> (PAGE_SHIFT-1)) << PAGE_SHIFT;
333
334 if (swap_start + PAGE_SIZE == swap_data)
335 swap_start = start_mem - PAGE_SIZE;
336
337 if (!swap_init( start_mem, swap_data )) {
338 printk( KERN_ERR "ST-RAM swap space initialization failed\n" );
339 max_swap_size = 0;
340 return;
341 }
342
343 reserve_region(swap_data, start_mem);
344
345 reserve_region(swap_start + PAGE_SIZE, swap_end);
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362 mach_max_dma_address = 0xffffffff;
363 }
364#endif
365}
366
367void atari_stram_mem_init_hook (void)
368{
369 mem_init_done = 1;
370}
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393void *atari_stram_alloc(long size, const char *owner)
394{
395 void *addr = NULL;
396 BLOCK *block;
397 int flags;
398
399 DPRINTK("atari_stram_alloc(size=%08lx,owner=%s)\n", size, owner);
400
401 size = ALIGN_IF_SWAP(size);
402 DPRINTK( "atari_stram_alloc: rounded size = %08lx\n", size );
403#ifdef CONFIG_STRAM_SWAP
404 if (max_swap_size) {
405
406
407 DPRINTK( "atari_stram_alloc: after mem_init, swapping ok, "
408 "calling get_region\n" );
409 addr = get_stram_region( N_PAGES(size) );
410 flags = BLOCK_INSWAP;
411 }
412 else
413#endif
414 if (!mem_init_done)
415 return alloc_bootmem_low(size);
416 else {
417
418
419 addr = (void *)__get_dma_pages(GFP_KERNEL, get_order(size));
420 flags = BLOCK_GFP;
421 DPRINTK( "atari_stram_alloc: after mem_init, swapping off, "
422 "get_pages=%p\n", addr );
423 }
424
425 if (addr) {
426 if (!(block = add_region( addr, size ))) {
427
428 DPRINTK( "atari_stram_alloc: out of mem for BLOCK -- "
429 "freeing again\n" );
430#ifdef CONFIG_STRAM_SWAP
431 if (flags == BLOCK_INSWAP)
432 free_stram_region( SWAP_NR(addr), N_PAGES(size) );
433 else
434#endif
435 free_pages((unsigned long)addr, get_order(size));
436 return( NULL );
437 }
438 block->owner = owner;
439 block->flags |= flags;
440 }
441 return( addr );
442}
443
444void atari_stram_free( void *addr )
445
446{
447 BLOCK *block;
448
449 DPRINTK( "atari_stram_free(addr=%p)\n", addr );
450
451 if (!(block = find_region( addr ))) {
452 printk( KERN_ERR "Attempt to free non-allocated ST-RAM block at %p "
453 "from %p\n", addr, __builtin_return_address(0) );
454 return;
455 }
456 DPRINTK( "atari_stram_free: found block (%p): size=%08lx, owner=%s, "
457 "flags=%02x\n", block, block->size, block->owner, block->flags );
458
459#ifdef CONFIG_STRAM_SWAP
460 if (!max_swap_size) {
461#endif
462 if (block->flags & BLOCK_GFP) {
463 DPRINTK("atari_stram_free: is kmalloced, order_size=%d\n",
464 get_order(block->size));
465 free_pages((unsigned long)addr, get_order(block->size));
466 }
467 else
468 goto fail;
469#ifdef CONFIG_STRAM_SWAP
470 }
471 else if (block->flags & BLOCK_INSWAP) {
472 DPRINTK( "atari_stram_free: is swap-alloced\n" );
473 free_stram_region( SWAP_NR(block->start), N_PAGES(block->size) );
474 }
475 else
476 goto fail;
477#endif
478 remove_region( block );
479 return;
480
481 fail:
482 printk( KERN_ERR "atari_stram_free: cannot free block at %p "
483 "(called from %p)\n", addr, __builtin_return_address(0) );
484}
485
486
487#ifdef CONFIG_STRAM_SWAP
488
489
490
491
492
493
494
495
496
497
498
499static int __init swap_init(void *start_mem, void *swap_data)
500{
501 static struct dentry fake_dentry;
502 static struct vfsmount fake_vfsmnt;
503 struct swap_info_struct *p;
504 struct inode swap_inode;
505 unsigned int type;
506 void *addr;
507 int i, j, k, prev;
508
509 DPRINTK("swap_init(start_mem=%p, swap_data=%p)\n",
510 start_mem, swap_data);
511
512
513
514 if (swap_end - swap_start < 2*PAGE_SIZE) {
515 printk( KERN_WARNING "stram_swap_init: swap space too small\n" );
516 return( 0 );
517 }
518
519
520 for( p = swap_info, type = 0; type < nr_swapfiles; type++, p++ )
521 if (!(p->flags & SWP_USED))
522 break;
523 if (type >= MAX_SWAPFILES) {
524 printk( KERN_WARNING "stram_swap_init: max. number of "
525 "swap devices exhausted\n" );
526 return( 0 );
527 }
528 if (type >= nr_swapfiles)
529 nr_swapfiles = type+1;
530
531 stram_swap_info = p;
532 stram_swap_type = type;
533
534
535 fake_dentry.d_parent = &fake_dentry;
536 fake_dentry.d_name.name = "stram (internal)";
537 fake_dentry.d_name.len = 16;
538 fake_vfsmnt.mnt_parent = &fake_vfsmnt;
539
540 p->flags = SWP_USED;
541 p->swap_file = &fake_dentry;
542 p->swap_vfsmnt = &fake_vfsmnt;
543 p->swap_device = 0;
544 p->swap_map = swap_data;
545 p->cluster_nr = 0;
546 p->next = -1;
547 p->prio = 0x7ff0;
548
549
550
551
552 p->swap_device = MKDEV( STRAM_MAJOR, STRAM_MINOR );
553 swap_inode.i_rdev = p->swap_device;
554 stram_open( &swap_inode, MAGIC_FILE_P );
555 p->max = SWAP_NR(swap_end);
556
557
558
559 j = 0;
560 k = 0;
561 p->lowest_bit = 0;
562 p->highest_bit = 0;
563 for( i = 1, addr = SWAP_ADDR(1); i < p->max;
564 i++, addr += PAGE_SIZE ) {
565 if (in_some_region( addr )) {
566 p->swap_map[i] = SWAP_MAP_BAD;
567 ++k;
568 }
569 else if (kernel_in_stram && addr < start_mem ) {
570 p->swap_map[i] = SWAP_MAP_BAD;
571 }
572 else {
573 p->swap_map[i] = 0;
574 ++j;
575 if (!p->lowest_bit) p->lowest_bit = i;
576 p->highest_bit = i;
577 }
578 }
579
580 p->swap_map[0] = SWAP_MAP_BAD;
581
582
583 p->pages = j + k;
584 swap_list_lock();
585 nr_swap_pages += j;
586 p->flags = SWP_WRITEOK;
587
588
589 prev = -1;
590 for (i = swap_list.head; i >= 0; i = swap_info[i].next) {
591 if (p->prio >= swap_info[i].prio) {
592 break;
593 }
594 prev = i;
595 }
596 p->next = i;
597 if (prev < 0) {
598 swap_list.head = swap_list.next = p - swap_info;
599 } else {
600 swap_info[prev].next = p - swap_info;
601 }
602 swap_list_unlock();
603
604 printk( KERN_INFO "Using %dk (%d pages) of ST-RAM as swap space.\n",
605 p->pages << 2, p->pages );
606 return( 1 );
607}
608
609
610
611
612
613
614
615
616
617
618
619static inline void unswap_pte(struct vm_area_struct * vma, unsigned long
620 address, pte_t *dir, swp_entry_t entry,
621 struct page *page)
622{
623 pte_t pte = *dir;
624
625 if (pte_none(pte))
626 return;
627 if (pte_present(pte)) {
628
629
630
631 if (pte_page(pte) != page)
632 return;
633
634 set_pte(dir, pte_mkdirty(pte));
635 return;
636 }
637 if (pte_val(pte) != entry.val)
638 return;
639
640 DPRINTK("unswap_pte: replacing entry %08lx by new page %p",
641 entry.val, page);
642 set_pte(dir, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
643 swap_free(entry);
644 get_page(page);
645 ++vma->vm_mm->rss;
646}
647
648static inline void unswap_pmd(struct vm_area_struct * vma, pmd_t *dir,
649 unsigned long address, unsigned long size,
650 unsigned long offset, swp_entry_t entry,
651 struct page *page)
652{
653 pte_t * pte;
654 unsigned long end;
655
656 if (pmd_none(*dir))
657 return;
658 if (pmd_bad(*dir)) {
659 pmd_ERROR(*dir);
660 pmd_clear(dir);
661 return;
662 }
663 pte = pte_offset(dir, address);
664 offset += address & PMD_MASK;
665 address &= ~PMD_MASK;
666 end = address + size;
667 if (end > PMD_SIZE)
668 end = PMD_SIZE;
669 do {
670 unswap_pte(vma, offset+address-vma->vm_start, pte, entry, page);
671 address += PAGE_SIZE;
672 pte++;
673 } while (address < end);
674}
675
676static inline void unswap_pgd(struct vm_area_struct * vma, pgd_t *dir,
677 unsigned long address, unsigned long size,
678 swp_entry_t entry, struct page *page)
679{
680 pmd_t * pmd;
681 unsigned long offset, end;
682
683 if (pgd_none(*dir))
684 return;
685 if (pgd_bad(*dir)) {
686 pgd_ERROR(*dir);
687 pgd_clear(dir);
688 return;
689 }
690 pmd = pmd_offset(dir, address);
691 offset = address & PGDIR_MASK;
692 address &= ~PGDIR_MASK;
693 end = address + size;
694 if (end > PGDIR_SIZE)
695 end = PGDIR_SIZE;
696 do {
697 unswap_pmd(vma, pmd, address, end - address, offset, entry,
698 page);
699 address = (address + PMD_SIZE) & PMD_MASK;
700 pmd++;
701 } while (address < end);
702}
703
704static void unswap_vma(struct vm_area_struct * vma, pgd_t *pgdir,
705 swp_entry_t entry, struct page *page)
706{
707 unsigned long start = vma->vm_start, end = vma->vm_end;
708
709 do {
710 unswap_pgd(vma, pgdir, start, end - start, entry, page);
711 start = (start + PGDIR_SIZE) & PGDIR_MASK;
712 pgdir++;
713 } while (start < end);
714}
715
716static void unswap_process(struct mm_struct * mm, swp_entry_t entry,
717 struct page *page)
718{
719 struct vm_area_struct* vma;
720
721
722
723
724 if (!mm)
725 return;
726 for (vma = mm->mmap; vma; vma = vma->vm_next) {
727 pgd_t * pgd = pgd_offset(mm, vma->vm_start);
728 unswap_vma(vma, pgd, entry, page);
729 }
730}
731
732
733static int unswap_by_read(unsigned short *map, unsigned long max,
734 unsigned long start, unsigned long n_pages)
735{
736 struct task_struct *p;
737 struct page *page;
738 swp_entry_t entry;
739 unsigned long i;
740
741 DPRINTK( "unswapping %lu..%lu by reading in\n",
742 start, start+n_pages-1 );
743
744 for( i = start; i < start+n_pages; ++i ) {
745 if (map[i] == SWAP_MAP_BAD) {
746 printk( KERN_ERR "get_stram_region: page %lu already "
747 "reserved??\n", i );
748 continue;
749 }
750
751 if (map[i]) {
752 entry = SWP_ENTRY(stram_swap_type, i);
753 DPRINTK("unswap: map[i=%lu]=%u nr_swap=%u\n",
754 i, map[i], nr_swap_pages);
755
756 swap_device_lock(stram_swap_info);
757 map[i]++;
758 swap_device_unlock(stram_swap_info);
759
760
761
762 page = read_swap_cache_async(entry);
763 if (!page) {
764 swap_free(entry);
765 return -ENOMEM;
766 }
767 read_lock(&tasklist_lock);
768 for_each_task(p)
769 unswap_process(p->mm, entry, page);
770 read_unlock(&tasklist_lock);
771 shmem_unuse(entry, page);
772
773
774 if (PageSwapCache(page))
775 delete_from_swap_cache(page);
776 __free_page(page);
777 #ifdef DO_PROC
778 stat_swap_force++;
779 #endif
780 }
781
782 DPRINTK( "unswap: map[i=%lu]=%u nr_swap=%u\n",
783 i, map[i], nr_swap_pages );
784 swap_list_lock();
785 swap_device_lock(stram_swap_info);
786 map[i] = SWAP_MAP_BAD;
787 if (stram_swap_info->lowest_bit == i)
788 stram_swap_info->lowest_bit++;
789 if (stram_swap_info->highest_bit == i)
790 stram_swap_info->highest_bit--;
791 --nr_swap_pages;
792 swap_device_unlock(stram_swap_info);
793 swap_list_unlock();
794 }
795
796 return 0;
797}
798
799
800
801
802static void *get_stram_region( unsigned long n_pages )
803{
804 unsigned short *map = stram_swap_info->swap_map;
805 unsigned long max = stram_swap_info->max;
806 unsigned long start, total_free, region_free;
807 int err;
808 void *ret = NULL;
809
810 DPRINTK( "get_stram_region(n_pages=%lu)\n", n_pages );
811
812 down(&stram_swap_sem);
813
814
815 stram_swap_info->flags = SWP_USED;
816
817
818
819 if (!(start = find_free_region( n_pages, &total_free, ®ion_free )))
820 goto end;
821 DPRINTK( "get_stram_region: region starts at %lu, has %lu free pages\n",
822 start, region_free );
823
824 err = unswap_by_read(map, max, start, n_pages);
825 if (err)
826 goto end;
827
828 ret = SWAP_ADDR(start);
829 end:
830
831 stram_swap_info->flags = SWP_WRITEOK;
832 up(&stram_swap_sem);
833 DPRINTK( "get_stram_region: returning %p\n", ret );
834 return( ret );
835}
836
837
838
839
840
841static void free_stram_region( unsigned long offset, unsigned long n_pages )
842{
843 unsigned short *map = stram_swap_info->swap_map;
844
845 DPRINTK( "free_stram_region(offset=%lu,n_pages=%lu)\n", offset, n_pages );
846
847 if (offset < 1 || offset + n_pages > stram_swap_info->max) {
848 printk( KERN_ERR "free_stram_region: Trying to free non-ST-RAM\n" );
849 return;
850 }
851
852 swap_list_lock();
853 swap_device_lock(stram_swap_info);
854
855 for( ; n_pages > 0; ++offset, --n_pages ) {
856 if (map[offset] != SWAP_MAP_BAD)
857 printk( KERN_ERR "free_stram_region: Swap page %lu was not "
858 "reserved\n", offset );
859 map[offset] = 0;
860 }
861
862
863 if (offset < stram_swap_info->lowest_bit)
864 stram_swap_info->lowest_bit = offset;
865 if (offset+n_pages-1 > stram_swap_info->highest_bit)
866 stram_swap_info->highest_bit = offset+n_pages-1;
867 if (stram_swap_info->prio > swap_info[swap_list.next].prio)
868 swap_list.next = swap_list.head;
869 nr_swap_pages += n_pages;
870 swap_device_unlock(stram_swap_info);
871 swap_list_unlock();
872}
873
874
875
876
877
878
879
880
881static int in_some_region(void *addr)
882{
883 BLOCK *p;
884
885 for( p = alloc_list; p; p = p->next ) {
886 if (p->start <= addr && addr < p->start + p->size)
887 return( 1 );
888 }
889 return( 0 );
890}
891
892
893static unsigned long find_free_region(unsigned long n_pages,
894 unsigned long *total_free,
895 unsigned long *region_free)
896{
897 unsigned short *map = stram_swap_info->swap_map;
898 unsigned long max = stram_swap_info->max;
899 unsigned long head, tail, max_start;
900 long nfree, max_free;
901
902
903 head = 1;
904 max_start = 0;
905 max_free = -1;
906 *total_free = 0;
907
908 start_over:
909
910 nfree = 0;
911 for( tail = head; tail-head < n_pages && tail < max; ++tail ) {
912 if (map[tail] == SWAP_MAP_BAD) {
913 head = tail+1;
914 goto start_over;
915 }
916 if (!map[tail]) {
917 ++nfree;
918 ++*total_free;
919 }
920 }
921 if (tail-head < n_pages)
922 goto out;
923 if (nfree > max_free) {
924 max_start = head;
925 max_free = nfree;
926 if (max_free >= n_pages)
927
928 goto out;
929 }
930
931
932
933 while( tail < max ) {
934 nfree -= (map[head++] == 0);
935 if (map[tail] == SWAP_MAP_BAD) {
936 head = tail+1;
937 goto start_over;
938 }
939 if (!map[tail]) {
940 ++nfree;
941 ++*total_free;
942 }
943 ++tail;
944 if (nfree > max_free) {
945 max_start = head;
946 max_free = nfree;
947 if (max_free >= n_pages)
948
949 goto out;
950 }
951 }
952
953 out:
954 if (max_free < 0) {
955 printk( KERN_NOTICE "get_stram_region: ST-RAM too full or fragmented "
956 "-- can't allocate %lu pages\n", n_pages );
957 return( 0 );
958 }
959
960 *region_free = max_free;
961 return( max_start );
962}
963
964#ifdef CONFIG_STRAM_SWAP
965
966
967void __init stram_swap_setup(char *str)
968{
969 int ints[3];
970 get_options(str, ARRAY_SIZE(ints), ints);
971 if (ints[0] >= 1) {
972 if (ints[1] == 1) {
973
974 max_swap_size = -1;
975 if (ints[0] == 2) {
976 max_swap_size = ((ints[2] < 0 ? 0 : ints[2]) * 1024) & PAGE_MASK;
977 }
978 }
979 else if (ints[1] == 0) {
980
981 max_swap_size = 0;
982 }
983 else {
984 printk( KERN_WARNING "stram_swap=%d - invalid value\n", ints[1] );
985 }
986 }
987}
988
989#endif
990
991
992
993
994
995
996static int stram_blocksizes[14] = {
997 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4096 };
998static int stram_sizes[14] = {
999 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1000static int refcnt = 0;
1001
1002static void do_stram_request(request_queue_t *q)
1003{
1004 void *start;
1005 unsigned long len;
1006
1007 while (1) {
1008 INIT_REQUEST;
1009
1010 start = swap_start + (CURRENT->sector << 9);
1011 len = CURRENT->current_nr_sectors << 9;
1012 if ((start + len) > swap_end) {
1013 printk( KERN_ERR "stram: bad access beyond end of device: "
1014 "block=%ld, count=%ld\n",
1015 CURRENT->sector,
1016 CURRENT->current_nr_sectors );
1017 end_request( 0 );
1018 continue;
1019 }
1020
1021 if (CURRENT->cmd == READ) {
1022 memcpy(CURRENT->buffer, start, len);
1023#ifdef DO_PROC
1024 stat_swap_read += N_PAGES(len);
1025#endif
1026 }
1027 else {
1028 memcpy(start, CURRENT->buffer, len);
1029#ifdef DO_PROC
1030 stat_swap_write += N_PAGES(len);
1031#endif
1032 }
1033 end_request( 1 );
1034 }
1035}
1036
1037
1038static int stram_open( struct inode *inode, struct file *filp )
1039{
1040 if (filp != MAGIC_FILE_P) {
1041 printk( KERN_NOTICE "Only kernel can open ST-RAM device\n" );
1042 return( -EPERM );
1043 }
1044 if (MINOR(inode->i_rdev) != STRAM_MINOR)
1045 return( -ENXIO );
1046 if (refcnt)
1047 return( -EBUSY );
1048 ++refcnt;
1049 return( 0 );
1050}
1051
1052static int stram_release( struct inode *inode, struct file *filp )
1053{
1054 if (filp != MAGIC_FILE_P) {
1055 printk( KERN_NOTICE "Only kernel can close ST-RAM device\n" );
1056 return( -EPERM );
1057 }
1058 if (refcnt > 0)
1059 --refcnt;
1060 return( 0 );
1061}
1062
1063
1064static struct block_device_operations stram_fops = {
1065 open: stram_open,
1066 release: stram_release,
1067};
1068
1069int __init stram_device_init(void)
1070{
1071
1072 if (!MACH_IS_ATARI)
1073
1074 return( -ENXIO );
1075
1076 if (!max_swap_size)
1077
1078 return( -ENXIO );
1079
1080 if (register_blkdev( STRAM_MAJOR, "stram", &stram_fops)) {
1081 printk( KERN_ERR "stram: Unable to get major %d\n", STRAM_MAJOR );
1082 return( -ENXIO );
1083 }
1084
1085 blk_init_queue(BLK_DEFAULT_QUEUE(STRAM_MAJOR), do_stram_request);
1086 blksize_size[STRAM_MAJOR] = stram_blocksizes;
1087 stram_sizes[STRAM_MINOR] = (swap_end - swap_start)/1024;
1088 blk_size[STRAM_MAJOR] = stram_sizes;
1089 register_disk(NULL, MKDEV(STRAM_MAJOR, STRAM_MINOR), 1, &stram_fops,
1090 (swap_end-swap_start)>>9);
1091 return( 0 );
1092}
1093
1094
1095
1096
1097
1098
1099
1100
1101static void reserve_region(void *start, void *end)
1102{
1103 reserve_bootmem (virt_to_phys(start), end - start);
1104}
1105
1106#endif
1107
1108
1109
1110
1111
1112
1113
1114
1115static BLOCK *add_region( void *addr, unsigned long size )
1116{
1117 BLOCK **p, *n = NULL;
1118 int i;
1119
1120 for( i = 0; i < N_STATIC_BLOCKS; ++i ) {
1121 if (static_blocks[i].flags & BLOCK_FREE) {
1122 n = &static_blocks[i];
1123 n->flags = 0;
1124 break;
1125 }
1126 }
1127 if (!n && mem_init_done) {
1128
1129
1130 n = kmalloc( sizeof(BLOCK), GFP_KERNEL );
1131 if (n)
1132 n->flags = BLOCK_KMALLOCED;
1133 }
1134 if (!n) {
1135 printk( KERN_ERR "Out of memory for ST-RAM descriptor blocks\n" );
1136 return( NULL );
1137 }
1138 n->start = addr;
1139 n->size = size;
1140
1141 for( p = &alloc_list; *p; p = &((*p)->next) )
1142 if ((*p)->start > addr) break;
1143 n->next = *p;
1144 *p = n;
1145
1146 return( n );
1147}
1148
1149
1150
1151static BLOCK *find_region( void *addr )
1152{
1153 BLOCK *p;
1154
1155 for( p = alloc_list; p; p = p->next ) {
1156 if (p->start == addr)
1157 return( p );
1158 if (p->start > addr)
1159 break;
1160 }
1161 return( NULL );
1162}
1163
1164
1165
1166static int remove_region( BLOCK *block )
1167{
1168 BLOCK **p;
1169
1170 for( p = &alloc_list; *p; p = &((*p)->next) )
1171 if (*p == block) break;
1172 if (!*p)
1173 return( 0 );
1174
1175 *p = block->next;
1176 if (block->flags & BLOCK_KMALLOCED)
1177 kfree( block );
1178 else
1179 block->flags |= BLOCK_FREE;
1180 return( 1 );
1181}
1182
1183
1184
1185
1186
1187
1188
1189#ifdef DO_PROC
1190
1191#define PRINT_PROC(fmt,args...) len += sprintf( buf+len, fmt, ##args )
1192
1193int get_stram_list( char *buf )
1194{
1195 int len = 0;
1196 BLOCK *p;
1197#ifdef CONFIG_STRAM_SWAP
1198 int i;
1199 unsigned short *map = stram_swap_info->swap_map;
1200 unsigned long max = stram_swap_info->max;
1201 unsigned free = 0, used = 0, rsvd = 0;
1202#endif
1203
1204#ifdef CONFIG_STRAM_SWAP
1205 if (max_swap_size) {
1206 for( i = 1; i < max; ++i ) {
1207 if (!map[i])
1208 ++free;
1209 else if (map[i] == SWAP_MAP_BAD)
1210 ++rsvd;
1211 else
1212 ++used;
1213 }
1214 PRINT_PROC(
1215 "Total ST-RAM: %8u kB\n"
1216 "Total ST-RAM swap: %8lu kB\n"
1217 "Free swap: %8u kB\n"
1218 "Used swap: %8u kB\n"
1219 "Allocated swap: %8u kB\n"
1220 "Swap Reads: %8u\n"
1221 "Swap Writes: %8u\n"
1222 "Swap Forced Reads: %8u\n",
1223 (stram_end - stram_start) >> 10,
1224 (max-1) << (PAGE_SHIFT-10),
1225 free << (PAGE_SHIFT-10),
1226 used << (PAGE_SHIFT-10),
1227 rsvd << (PAGE_SHIFT-10),
1228 stat_swap_read,
1229 stat_swap_write,
1230 stat_swap_force );
1231 }
1232 else {
1233#endif
1234 PRINT_PROC( "ST-RAM swapping disabled\n" );
1235 PRINT_PROC("Total ST-RAM: %8u kB\n",
1236 (stram_end - stram_start) >> 10);
1237#ifdef CONFIG_STRAM_SWAP
1238 }
1239#endif
1240
1241 PRINT_PROC( "Allocated regions:\n" );
1242 for( p = alloc_list; p; p = p->next ) {
1243 if (len + 50 >= PAGE_SIZE)
1244 break;
1245 PRINT_PROC("0x%08lx-0x%08lx: %s (",
1246 virt_to_phys(p->start),
1247 virt_to_phys(p->start+p->size-1),
1248 p->owner);
1249 if (p->flags & BLOCK_GFP)
1250 PRINT_PROC( "page-alloced)\n" );
1251 else if (p->flags & BLOCK_INSWAP)
1252 PRINT_PROC( "in swap)\n" );
1253 else
1254 PRINT_PROC( "??)\n" );
1255 }
1256
1257 return( len );
1258}
1259
1260#endif
1261
1262
1263
1264
1265
1266
1267
1268
1269