initial commit with v2.6.9
[linux-2.6.9-moxart.git] / drivers / isdn / tpam / tpam_memory.c
blobae690b7ced17f150f655fa0036ef9ac23233a974
1 /* $Id: tpam_memory.c,v 1.1.2.2 2001/09/23 22:25:03 kai Exp $
3 * Turbo PAM ISDN driver for Linux. (Kernel Driver - Board Memory Access)
5 * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, AlcĂ´ve
7 * This software may be used and distributed according to the terms
8 * of the GNU General Public License, incorporated herein by reference.
10 * For all support questions please contact: <support@auvertech.fr>
14 #include <linux/pci.h>
15 #include <asm/io.h>
17 #include "tpam.h"
20 * Write a DWORD into the board memory.
22 * card: the board
23 * addr: the address (in the board memory)
24 * val: the value to put into the memory.
26 void copy_to_pam_dword(tpam_card *card, const void *addr, u32 val) {
28 /* set the page register */
29 writel(((unsigned long)addr) | TPAM_PAGE_SIZE,
30 card->bar0 + TPAM_PAGE_REGISTER);
32 /* write the value */
33 writel(val, card->bar0 + (((unsigned long)addr) & TPAM_PAGE_SIZE));
37 * Write n bytes into the board memory. The count of bytes will be rounded
38 * up to a multiple of 4.
40 * card: the board
41 * to: the destination address (in the board memory)
42 * from: the source address (in the kernel memory)
43 * n: number of bytes
45 void copy_to_pam(tpam_card *card, void *to, const void *from, u32 n) {
46 u32 page, offset, count;
48 /* need to write in dword ! */
49 while (n & 3) n++;
51 while (n) {
52 page = ((u32)to) | TPAM_PAGE_SIZE;
53 offset = ((u32)to) & TPAM_PAGE_SIZE;
54 count = n < TPAM_PAGE_SIZE - offset
55 ? n
56 : TPAM_PAGE_SIZE - offset;
58 /* set the page register */
59 writel(page, card->bar0 + TPAM_PAGE_REGISTER);
61 /* copy the data */
62 memcpy_toio((void *)(card->bar0 + offset), from, count);
64 from += count;
65 to += count;
66 n -= count;
71 * Read a DWORD from the board memory.
73 * card: the board
74 * addr: the address (in the board memory)
76 * Return: the value read into the memory.
78 u32 copy_from_pam_dword(tpam_card *card, const void *addr) {
80 /* set the page register */
81 writel(((u32)addr) | TPAM_PAGE_SIZE,
82 card->bar0 + TPAM_PAGE_REGISTER);
84 /* read the data */
85 return readl(card->bar0 + (((u32)addr) & TPAM_PAGE_SIZE));
89 * Read n bytes from the board memory.
91 * card: the board
92 * to: the destination address (in the kernel memory)
93 * from: the source address (in the board memory)
94 * n: number of bytes
96 void copy_from_pam(tpam_card *card, void *to, const void *from, u32 n) {
97 u32 page, offset, count;
99 while (n) {
100 page = ((u32)from) | TPAM_PAGE_SIZE;
101 offset = ((u32)from) & TPAM_PAGE_SIZE;
102 count = n < TPAM_PAGE_SIZE - offset
103 ? n
104 : TPAM_PAGE_SIZE - offset;
106 /* set the page register */
107 writel(page, card->bar0 + TPAM_PAGE_REGISTER);
109 /* read the data */
110 memcpy_fromio(to, (void *)(card->bar0 + offset), count);
112 from += count;
113 to += count;
114 n -= count;
119 * Read n bytes from the board memory and writes them into the user memory.
121 * card: the board
122 * to: the destination address (in the userspace memory)
123 * from: the source address (in the board memory)
124 * n: number of bytes
126 * Return: 0 if OK, <0 if error.
128 int copy_from_pam_to_user(tpam_card *card, void __user *to, const void *from, u32 n) {
129 void *page;
130 u32 count;
132 /* allocate a free page for the data transfer */
133 if (!(page = (void *)__get_free_page(GFP_KERNEL))) {
134 printk(KERN_ERR "TurboPAM(copy_from_pam_to_user): "
135 "get_free_page failed\n");
136 return -ENOMEM;
139 while (n) {
140 count = n < PAGE_SIZE ? n : PAGE_SIZE;
142 /* copy data from the board into the kernel memory */
143 spin_lock_irq(&card->lock);
144 copy_from_pam(card, page, from, count);
145 spin_unlock_irq(&card->lock);
147 /* copy it from the kernel memory into the user memory */
148 if (copy_to_user(to, page, count)) {
150 /* this can fail... */
151 free_page((u32)page);
152 return -EFAULT;
154 from += count;
155 to += count;
156 n -= count;
159 /* release allocated memory */
160 free_page((u32)page);
161 return 0;
165 * Read n bytes from the user memory and writes them into the board memory.
167 * card: the board
168 * to: the destination address (in the board memory)
169 * from: the source address (in the userspace memory)
170 * n: number of bytes
172 * Return: 0 if OK, <0 if error.
174 int copy_from_user_to_pam(tpam_card *card, void *to, const void __user *from, u32 n) {
175 void *page;
176 u32 count;
178 /* allocate a free page for the data transfer */
179 if (!(page = (void *)__get_free_page(GFP_KERNEL))) {
180 printk(KERN_ERR "TurboPAM(copy_from_user_to_pam): "
181 "get_free_page failed\n");
182 return -ENOMEM;
185 while (n) {
186 count = n < PAGE_SIZE ? n : PAGE_SIZE;
188 /* copy data from the user memory into the kernel memory */
189 if (copy_from_user(page, from, count)) {
190 /* this can fail... */
191 free_page((u32)page);
192 return -EFAULT;
195 /* copy it from the kernel memory into the board memory */
196 spin_lock_irq(&card->lock);
197 copy_to_pam(card, to, page, count);
198 spin_unlock_irq(&card->lock);
200 from += count;
201 to += count;
202 n -= count;
205 /* release allocated memory */
206 free_page((u32)page);
207 return 0;
211 * Verify if we have the permission to read or writes len bytes at the
212 * address address from/to the board memory.
214 * address: the start address (in the board memory)
215 * len: number of bytes
217 * Return: 0 if OK, <0 if error.
219 int tpam_verify_area(u32 address, u32 len) {
221 if (address < TPAM_RESERVEDAREA1_START)
222 return (address + len <= TPAM_RESERVEDAREA1_START) ? 0 : -1;
224 if (address <= TPAM_RESERVEDAREA1_END)
225 return -1;
227 if (address < TPAM_RESERVEDAREA2_START)
228 return (address + len <= TPAM_RESERVEDAREA2_START) ? 0 : -1;
230 if (address <= TPAM_RESERVEDAREA2_END)
231 return -1;
233 if (address < TPAM_RESERVEDAREA3_START)
234 return (address + len <= TPAM_RESERVEDAREA3_START) ? 0 : -1;
236 if (address <= TPAM_RESERVEDAREA3_END)
237 return -1;
239 if (address < TPAM_RESERVEDAREA4_START)
240 return (address + len <= TPAM_RESERVEDAREA4_START) ? 0 : -1;
242 if (address <= TPAM_RESERVEDAREA4_END)
243 return -1;
245 return 0;