aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/ftape/lowlevel/ftape-buffer.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/char/ftape/lowlevel/ftape-buffer.c
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/char/ftape/lowlevel/ftape-buffer.c')
-rw-r--r--drivers/char/ftape/lowlevel/ftape-buffer.c129
1 files changed, 129 insertions, 0 deletions
diff --git a/drivers/char/ftape/lowlevel/ftape-buffer.c b/drivers/char/ftape/lowlevel/ftape-buffer.c
new file mode 100644
index 00000000000..54af20cd9a2
--- /dev/null
+++ b/drivers/char/ftape/lowlevel/ftape-buffer.c
@@ -0,0 +1,129 @@
1/*
2 * Copyright (C) 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/lowlevel/ftape-buffer.c,v $
20 * $Revision: 1.3 $
21 * $Date: 1997/10/16 23:33:11 $
22 *
23 * This file contains the allocator/dealloctor for ftape's dynamic dma
24 * buffer.
25 */
26
27#include <linux/slab.h>
28#include <linux/mm.h>
29#include <linux/mman.h>
30#include <asm/dma.h>
31
32#include <linux/ftape.h>
33#include "../lowlevel/ftape-rw.h"
34#include "../lowlevel/ftape-read.h"
35#include "../lowlevel/ftape-tracing.h"
36
37/* DMA'able memory allocation stuff.
38 */
39
40static inline void *dmaalloc(size_t size)
41{
42 unsigned long addr;
43
44 if (size == 0) {
45 return NULL;
46 }
47 addr = __get_dma_pages(GFP_KERNEL, get_order(size));
48 if (addr) {
49 struct page *page;
50
51 for (page = virt_to_page(addr); page < virt_to_page(addr+size); page++)
52 SetPageReserved(page);
53 }
54 return (void *)addr;
55}
56
57static inline void dmafree(void *addr, size_t size)
58{
59 if (size > 0) {
60 struct page *page;
61
62 for (page = virt_to_page((unsigned long)addr);
63 page < virt_to_page((unsigned long)addr+size); page++)
64 ClearPageReserved(page);
65 free_pages((unsigned long) addr, get_order(size));
66 }
67}
68
69static int add_one_buffer(void)
70{
71 TRACE_FUN(ft_t_flow);
72
73 if (ft_nr_buffers >= FT_MAX_NR_BUFFERS) {
74 TRACE_EXIT -ENOMEM;
75 }
76 ft_buffer[ft_nr_buffers] = kmalloc(sizeof(buffer_struct), GFP_KERNEL);
77 if (ft_buffer[ft_nr_buffers] == NULL) {
78 TRACE_EXIT -ENOMEM;
79 }
80 memset(ft_buffer[ft_nr_buffers], 0, sizeof(buffer_struct));
81 ft_buffer[ft_nr_buffers]->address = dmaalloc(FT_BUFF_SIZE);
82 if (ft_buffer[ft_nr_buffers]->address == NULL) {
83 kfree(ft_buffer[ft_nr_buffers]);
84 ft_buffer[ft_nr_buffers] = NULL;
85 TRACE_EXIT -ENOMEM;
86 }
87 ft_nr_buffers ++;
88 TRACE(ft_t_info, "buffer nr #%d @ %p, dma area @ %p",
89 ft_nr_buffers,
90 ft_buffer[ft_nr_buffers-1],
91 ft_buffer[ft_nr_buffers-1]->address);
92 TRACE_EXIT 0;
93}
94
95static void del_one_buffer(void)
96{
97 TRACE_FUN(ft_t_flow);
98 if (ft_nr_buffers > 0) {
99 TRACE(ft_t_info, "releasing buffer nr #%d @ %p, dma area @ %p",
100 ft_nr_buffers,
101 ft_buffer[ft_nr_buffers-1],
102 ft_buffer[ft_nr_buffers-1]->address);
103 ft_nr_buffers --;
104 dmafree(ft_buffer[ft_nr_buffers]->address, FT_BUFF_SIZE);
105 kfree(ft_buffer[ft_nr_buffers]);
106 ft_buffer[ft_nr_buffers] = NULL;
107 }
108 TRACE_EXIT;
109}
110
111int ftape_set_nr_buffers(int cnt)
112{
113 int delta = cnt - ft_nr_buffers;
114 TRACE_FUN(ft_t_flow);
115
116 if (delta > 0) {
117 while (delta--) {
118 if (add_one_buffer() < 0) {
119 TRACE_EXIT -ENOMEM;
120 }
121 }
122 } else if (delta < 0) {
123 while (delta++) {
124 del_one_buffer();
125 }
126 }
127 ftape_zap_read_buffers();
128 TRACE_EXIT 0;
129}