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#include <linux/swapops.h>
35
36#ifdef CONFIG_STRAM_SWAP
37#define MAJOR_NR Z2RAM_MAJOR
38#define do_z2_request do_stram_request
39#define DEVICE_NR(device) (minor(device))
40#include <linux/blk.h>
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 = -1;
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 {
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_kernel(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
965
966void __init stram_swap_setup(char *str, int *ints)
967{
968 if (ints[0] >= 1)
969 max_swap_size = ((ints[1] < 0 ? 0 : ints[1]) * 1024) & PAGE_MASK;
970}
971
972
973
974
975
976
977static int stram_sizes[14] = {
978 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
979static int refcnt = 0;
980
981static void do_stram_request(request_queue_t *q)
982{
983 void *start;
984 unsigned long len;
985
986 while (1) {
987 struct request *req;
988 if (blk_queue_empty(QUEUE))
989 return;
990
991 req = CURRENT;
992 start = swap_start + (req->sector << 9);
993 len = req->current_nr_sectors << 9;
994 if ((start + len) > swap_end) {
995 printk( KERN_ERR "stram: bad access beyond end of device: "
996 "block=%ld, count=%ld\n",
997 req->sector,
998 req->current_nr_sectors );
999 end_request(req, 0);
1000 continue;
1001 }
1002
1003 if (req->cmd == READ) {
1004 memcpy(req->buffer, start, len);
1005#ifdef DO_PROC
1006 stat_swap_read += N_PAGES(len);
1007#endif
1008 }
1009 else {
1010 memcpy(start, req->buffer, len);
1011#ifdef DO_PROC
1012 stat_swap_write += N_PAGES(len);
1013#endif
1014 }
1015 end_request(req, 1);
1016 }
1017}
1018
1019
1020static int stram_open( struct inode *inode, struct file *filp )
1021{
1022 if (filp != MAGIC_FILE_P) {
1023 printk( KERN_NOTICE "Only kernel can open ST-RAM device\n" );
1024 return( -EPERM );
1025 }
1026 if (MINOR(inode->i_rdev) != STRAM_MINOR)
1027 return( -ENXIO );
1028 if (refcnt)
1029 return( -EBUSY );
1030 ++refcnt;
1031 return( 0 );
1032}
1033
1034static int stram_release( struct inode *inode, struct file *filp )
1035{
1036 if (filp != MAGIC_FILE_P) {
1037 printk( KERN_NOTICE "Only kernel can close ST-RAM device\n" );
1038 return( -EPERM );
1039 }
1040 if (refcnt > 0)
1041 --refcnt;
1042 return( 0 );
1043}
1044
1045
1046static struct block_device_operations stram_fops = {
1047 .open = stram_open,
1048 .release = stram_release,
1049};
1050
1051int __init stram_device_init(void)
1052{
1053
1054 if (!MACH_IS_ATARI)
1055
1056 return( -ENXIO );
1057
1058 if (!max_swap_size)
1059
1060 return( -ENXIO );
1061
1062 if (register_blkdev( STRAM_MAJOR, "stram", &stram_fops)) {
1063 printk( KERN_ERR "stram: Unable to get major %d\n", STRAM_MAJOR );
1064 return( -ENXIO );
1065 }
1066
1067 blk_init_queue(BLK_DEFAULT_QUEUE(STRAM_MAJOR), do_stram_request);
1068 stram_sizes[STRAM_MINOR] = (swap_end - swap_start)/1024;
1069 blk_size[STRAM_MAJOR] = stram_sizes;
1070 register_disk(NULL, MKDEV(STRAM_MAJOR, STRAM_MINOR), 1, &stram_fops,
1071 (swap_end-swap_start)>>9);
1072 return( 0 );
1073}
1074
1075
1076
1077
1078
1079
1080
1081
1082static void reserve_region(void *start, void *end)
1083{
1084 reserve_bootmem (virt_to_phys(start), end - start);
1085}
1086
1087#endif
1088
1089
1090
1091
1092
1093
1094
1095
1096static BLOCK *add_region( void *addr, unsigned long size )
1097{
1098 BLOCK **p, *n = NULL;
1099 int i;
1100
1101 for( i = 0; i < N_STATIC_BLOCKS; ++i ) {
1102 if (static_blocks[i].flags & BLOCK_FREE) {
1103 n = &static_blocks[i];
1104 n->flags = 0;
1105 break;
1106 }
1107 }
1108 if (!n && mem_init_done) {
1109
1110
1111 n = kmalloc( sizeof(BLOCK), GFP_KERNEL );
1112 if (n)
1113 n->flags = BLOCK_KMALLOCED;
1114 }
1115 if (!n) {
1116 printk( KERN_ERR "Out of memory for ST-RAM descriptor blocks\n" );
1117 return( NULL );
1118 }
1119 n->start = addr;
1120 n->size = size;
1121
1122 for( p = &alloc_list; *p; p = &((*p)->next) )
1123 if ((*p)->start > addr) break;
1124 n->next = *p;
1125 *p = n;
1126
1127 return( n );
1128}
1129
1130
1131
1132static BLOCK *find_region( void *addr )
1133{
1134 BLOCK *p;
1135
1136 for( p = alloc_list; p; p = p->next ) {
1137 if (p->start == addr)
1138 return( p );
1139 if (p->start > addr)
1140 break;
1141 }
1142 return( NULL );
1143}
1144
1145
1146
1147static int remove_region( BLOCK *block )
1148{
1149 BLOCK **p;
1150
1151 for( p = &alloc_list; *p; p = &((*p)->next) )
1152 if (*p == block) break;
1153 if (!*p)
1154 return( 0 );
1155
1156 *p = block->next;
1157 if (block->flags & BLOCK_KMALLOCED)
1158 kfree( block );
1159 else
1160 block->flags |= BLOCK_FREE;
1161 return( 1 );
1162}
1163
1164
1165
1166
1167
1168
1169
1170#ifdef DO_PROC
1171
1172#define PRINT_PROC(fmt,args...) len += sprintf( buf+len, fmt, ##args )
1173
1174int get_stram_list( char *buf )
1175{
1176 int len = 0;
1177 BLOCK *p;
1178#ifdef CONFIG_STRAM_SWAP
1179 int i;
1180 unsigned short *map = stram_swap_info->swap_map;
1181 unsigned long max = stram_swap_info->max;
1182 unsigned free = 0, used = 0, rsvd = 0;
1183#endif
1184
1185#ifdef CONFIG_STRAM_SWAP
1186 if (max_swap_size) {
1187 for( i = 1; i < max; ++i ) {
1188 if (!map[i])
1189 ++free;
1190 else if (map[i] == SWAP_MAP_BAD)
1191 ++rsvd;
1192 else
1193 ++used;
1194 }
1195 PRINT_PROC(
1196 "Total ST-RAM: %8u kB\n"
1197 "Total ST-RAM swap: %8lu kB\n"
1198 "Free swap: %8u kB\n"
1199 "Used swap: %8u kB\n"
1200 "Allocated swap: %8u kB\n"
1201 "Swap Reads: %8u\n"
1202 "Swap Writes: %8u\n"
1203 "Swap Forced Reads: %8u\n",
1204 (stram_end - stram_start) >> 10,
1205 (max-1) << (PAGE_SHIFT-10),
1206 free << (PAGE_SHIFT-10),
1207 used << (PAGE_SHIFT-10),
1208 rsvd << (PAGE_SHIFT-10),
1209 stat_swap_read,
1210 stat_swap_write,
1211 stat_swap_force );
1212 }
1213 else {
1214#endif
1215 PRINT_PROC( "ST-RAM swapping disabled\n" );
1216 PRINT_PROC("Total ST-RAM: %8u kB\n",
1217 (stram_end - stram_start) >> 10);
1218#ifdef CONFIG_STRAM_SWAP
1219 }
1220#endif
1221
1222 PRINT_PROC( "Allocated regions:\n" );
1223 for( p = alloc_list; p; p = p->next ) {
1224 if (len + 50 >= PAGE_SIZE)
1225 break;
1226 PRINT_PROC("0x%08lx-0x%08lx: %s (",
1227 virt_to_phys(p->start),
1228 virt_to_phys(p->start+p->size-1),
1229 p->owner);
1230 if (p->flags & BLOCK_GFP)
1231 PRINT_PROC( "page-alloced)\n" );
1232 else if (p->flags & BLOCK_INSWAP)
1233 PRINT_PROC( "in swap)\n" );
1234 else
1235 PRINT_PROC( "??)\n" );
1236 }
1237
1238 return( len );
1239}
1240
1241#endif
1242
1243
1244
1245
1246
1247
1248
1249
1250