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
)