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>
20 * Write a DWORD into the board memory.
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);
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.
41 * to: the destination address (in the board memory)
42 * from: the source address (in the kernel memory)
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 ! */
52 page = ((u32)to) | TPAM_PAGE_SIZE;
53 offset = ((u32)to) & TPAM_PAGE_SIZE;
54 count = n < TPAM_PAGE_SIZE - offset
56 : TPAM_PAGE_SIZE - offset;
58 /* set the page register */
59 writel(page, card->bar0 + TPAM_PAGE_REGISTER);
62 memcpy_toio((void *)(card->bar0 + offset), from, count);
71 * Read a DWORD from the board memory.
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);
85 return readl(card->bar0 + (((u32)addr) & TPAM_PAGE_SIZE));
89 * Read n bytes from the board memory.
92 * to: the destination address (in the kernel memory)
93 * from: the source address (in the board memory)
96 void copy_from_pam(tpam_card *card, void *to, const void *from, u32 n) {
97 u32 page, offset, count;
100 page = ((u32)from) | TPAM_PAGE_SIZE;
101 offset = ((u32)from) & TPAM_PAGE_SIZE;
102 count = n < TPAM_PAGE_SIZE - offset
104 : TPAM_PAGE_SIZE - offset;
106 /* set the page register */
107 writel(page, card->bar0 + TPAM_PAGE_REGISTER);
110 memcpy_fromio(to, (void *)(card->bar0 + offset), count);
119 * Read n bytes from the board memory and writes them into the user memory.
122 * to: the destination address (in the userspace memory)
123 * from: the source address (in the board memory)
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) {
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");
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);
159 /* release allocated memory */
160 free_page((u32)page);
165 * Read n bytes from the user memory and writes them into the board memory.
168 * to: the destination address (in the board memory)
169 * from: the source address (in the userspace memory)
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) {
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");
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);
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);
205 /* release allocated memory */
206 free_page((u32)page);
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)
227 if (address < TPAM_RESERVEDAREA2_START)
228 return (address + len <= TPAM_RESERVEDAREA2_START) ? 0 : -1;
230 if (address <= TPAM_RESERVEDAREA2_END)
233 if (address < TPAM_RESERVEDAREA3_START)
234 return (address + len <= TPAM_RESERVEDAREA3_START) ? 0 : -1;
236 if (address <= TPAM_RESERVEDAREA3_END)
239 if (address < TPAM_RESERVEDAREA4_START)
240 return (address + len <= TPAM_RESERVEDAREA4_START) ? 0 : -1;
242 if (address <= TPAM_RESERVEDAREA4_END)