2 * Copyright (C) 1997 Claus-Justus Heine
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)
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.
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.
19 * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-buffer.c,v $
21 * $Date: 1997/10/16 23:33:11 $
23 * This file contains the allocator/dealloctor for ftape's dynamic dma
27 #include <asm/segment.h>
28 #include <linux/malloc.h>
30 #include <linux/mman.h>
31 #include <linux/wrapper.h>
34 #include <linux/ftape.h>
35 #include "../lowlevel/ftape-rw.h"
36 #include "../lowlevel/ftape-read.h"
37 #include "../lowlevel/ftape-tracing.h"
39 /* DMA'able memory allocation stuff.
42 /* Pure 2^n version of get_order */
43 static inline int __get_order(size_t size
)
47 size
= (size
-1) >> (PAGE_SHIFT
-1);
56 static inline void *dmaalloc(size_t size
)
63 addr
= __get_dma_pages(GFP_KERNEL
, __get_order(size
));
67 for (i
= MAP_NR(addr
); i
< MAP_NR(addr
+size
); i
++) {
74 static inline void dmafree(void *addr
, size_t size
)
79 for (i
= MAP_NR((unsigned long)addr
);
80 i
< MAP_NR((unsigned long)addr
+size
); i
++) {
81 mem_map_unreserve (i
);
83 free_pages((unsigned long) addr
, __get_order(size
));
87 static int add_one_buffer(void)
91 if (ft_nr_buffers
>= FT_MAX_NR_BUFFERS
) {
94 ft_buffer
[ft_nr_buffers
] = kmalloc(sizeof(buffer_struct
), GFP_KERNEL
);
95 if (ft_buffer
[ft_nr_buffers
] == NULL
) {
98 memset(ft_buffer
[ft_nr_buffers
], 0, sizeof(buffer_struct
));
99 ft_buffer
[ft_nr_buffers
]->address
= dmaalloc(FT_BUFF_SIZE
);
100 if (ft_buffer
[ft_nr_buffers
]->address
== NULL
) {
101 kfree(ft_buffer
[ft_nr_buffers
]);
102 ft_buffer
[ft_nr_buffers
] = NULL
;
106 TRACE(ft_t_info
, "buffer nr #%d @ %p, dma area @ %p",
108 ft_buffer
[ft_nr_buffers
-1],
109 ft_buffer
[ft_nr_buffers
-1]->address
);
113 static void del_one_buffer(void)
115 TRACE_FUN(ft_t_flow
);
116 if (ft_nr_buffers
> 0) {
117 TRACE(ft_t_info
, "releasing buffer nr #%d @ %p, dma area @ %p",
119 ft_buffer
[ft_nr_buffers
-1],
120 ft_buffer
[ft_nr_buffers
-1]->address
);
122 dmafree(ft_buffer
[ft_nr_buffers
]->address
, FT_BUFF_SIZE
);
123 kfree(ft_buffer
[ft_nr_buffers
]);
124 ft_buffer
[ft_nr_buffers
] = NULL
;
129 int ftape_set_nr_buffers(int cnt
)
131 int delta
= cnt
- ft_nr_buffers
;
132 TRACE_FUN(ft_t_flow
);
136 if (add_one_buffer() < 0) {
140 } else if (delta
< 0) {
145 ftape_zap_read_buffers();