diff options
Diffstat (limited to 'drivers/char/ftape/zftape/zftape-buffers.c')
-rw-r--r-- | drivers/char/ftape/zftape/zftape-buffers.c | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/drivers/char/ftape/zftape/zftape-buffers.c b/drivers/char/ftape/zftape/zftape-buffers.c new file mode 100644 index 000000000000..da06f138334e --- /dev/null +++ b/drivers/char/ftape/zftape/zftape-buffers.c | |||
@@ -0,0 +1,149 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1995-1997 Claus-Justus Heine. | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; see the file COPYING. If not, write to | ||
16 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
17 | |||
18 | * | ||
19 | * $Source: /homes/cvs/ftape-stacked/ftape/zftape/zftape-buffers.c,v $ | ||
20 | * $Revision: 1.2 $ | ||
21 | * $Date: 1997/10/05 19:18:59 $ | ||
22 | * | ||
23 | * This file contains the dynamic buffer allocation routines | ||
24 | * of zftape | ||
25 | */ | ||
26 | |||
27 | #include <linux/errno.h> | ||
28 | #include <linux/mm.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/delay.h> | ||
31 | |||
32 | #include <linux/zftape.h> | ||
33 | |||
34 | #include <linux/vmalloc.h> | ||
35 | |||
36 | #include "../zftape/zftape-init.h" | ||
37 | #include "../zftape/zftape-eof.h" | ||
38 | #include "../zftape/zftape-ctl.h" | ||
39 | #include "../zftape/zftape-write.h" | ||
40 | #include "../zftape/zftape-read.h" | ||
41 | #include "../zftape/zftape-rw.h" | ||
42 | #include "../zftape/zftape-vtbl.h" | ||
43 | |||
44 | /* global variables | ||
45 | */ | ||
46 | |||
47 | /* local varibales | ||
48 | */ | ||
49 | static unsigned int used_memory; | ||
50 | static unsigned int peak_memory; | ||
51 | |||
52 | void zft_memory_stats(void) | ||
53 | { | ||
54 | TRACE_FUN(ft_t_flow); | ||
55 | |||
56 | TRACE(ft_t_noise, "Memory usage (vmalloc allocations):\n" | ||
57 | KERN_INFO "total allocated: %d\n" | ||
58 | KERN_INFO "peak allocation: %d", | ||
59 | used_memory, peak_memory); | ||
60 | peak_memory = used_memory; | ||
61 | TRACE_EXIT; | ||
62 | } | ||
63 | |||
64 | int zft_vcalloc_once(void *new, size_t size) | ||
65 | { | ||
66 | TRACE_FUN(ft_t_flow); | ||
67 | if (zft_vmalloc_once(new, size) < 0) { | ||
68 | TRACE_EXIT -ENOMEM; | ||
69 | } | ||
70 | memset(*(void **)new, '\0', size); | ||
71 | TRACE_EXIT 0; | ||
72 | } | ||
73 | int zft_vmalloc_once(void *new, size_t size) | ||
74 | { | ||
75 | TRACE_FUN(ft_t_flow); | ||
76 | |||
77 | if (*(void **)new != NULL || size == 0) { | ||
78 | TRACE_EXIT 0; | ||
79 | } | ||
80 | if ((*(void **)new = vmalloc(size)) == NULL) { | ||
81 | TRACE_EXIT -ENOMEM; | ||
82 | } | ||
83 | used_memory += size; | ||
84 | if (peak_memory < used_memory) { | ||
85 | peak_memory = used_memory; | ||
86 | } | ||
87 | TRACE_ABORT(0, ft_t_noise, | ||
88 | "allocated buffer @ %p, %d bytes", *(void **)new, size); | ||
89 | } | ||
90 | int zft_vmalloc_always(void *new, size_t size) | ||
91 | { | ||
92 | TRACE_FUN(ft_t_flow); | ||
93 | |||
94 | zft_vfree(new, size); | ||
95 | TRACE_EXIT zft_vmalloc_once(new, size); | ||
96 | } | ||
97 | void zft_vfree(void *old, size_t size) | ||
98 | { | ||
99 | TRACE_FUN(ft_t_flow); | ||
100 | |||
101 | if (*(void **)old) { | ||
102 | vfree(*(void **)old); | ||
103 | used_memory -= size; | ||
104 | TRACE(ft_t_noise, "released buffer @ %p, %d bytes", | ||
105 | *(void **)old, size); | ||
106 | *(void **)old = NULL; | ||
107 | } | ||
108 | TRACE_EXIT; | ||
109 | } | ||
110 | |||
111 | void *zft_kmalloc(size_t size) | ||
112 | { | ||
113 | void *new; | ||
114 | |||
115 | while ((new = kmalloc(size, GFP_KERNEL)) == NULL) { | ||
116 | msleep_interruptible(100); | ||
117 | } | ||
118 | memset(new, 0, size); | ||
119 | used_memory += size; | ||
120 | if (peak_memory < used_memory) { | ||
121 | peak_memory = used_memory; | ||
122 | } | ||
123 | return new; | ||
124 | } | ||
125 | |||
126 | void zft_kfree(void *old, size_t size) | ||
127 | { | ||
128 | kfree(old); | ||
129 | used_memory -= size; | ||
130 | } | ||
131 | |||
132 | /* there are some more buffers that are allocated on demand. | ||
133 | * cleanup_module() calles this function to be sure to have released | ||
134 | * them | ||
135 | */ | ||
136 | void zft_uninit_mem(void) | ||
137 | { | ||
138 | TRACE_FUN(ft_t_flow); | ||
139 | |||
140 | zft_vfree(&zft_hseg_buf, FT_SEGMENT_SIZE); | ||
141 | zft_vfree(&zft_deblock_buf, FT_SEGMENT_SIZE); zft_deblock_segment = -1; | ||
142 | zft_free_vtbl(); | ||
143 | if (zft_cmpr_lock(0 /* don't load */) == 0) { | ||
144 | (*zft_cmpr_ops->cleanup)(); | ||
145 | (*zft_cmpr_ops->reset)(); /* unlock it again */ | ||
146 | } | ||
147 | zft_memory_stats(); | ||
148 | TRACE_EXIT; | ||
149 | } | ||