tpam_memory.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:6k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* $Id: tpam_memory.c,v 1.1.2.1 2001/11/20 14:19:37 kai Exp $
  2.  *
  3.  * Turbo PAM ISDN driver for Linux. (Kernel Driver - Board Memory Access)
  4.  *
  5.  * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alc魐e
  6.  *
  7.  * This software may be used and distributed according to the terms
  8.  * of the GNU General Public License, incorporated herein by reference.
  9.  *
  10.  * For all support questions please contact: <support@auvertech.fr>
  11.  *
  12.  */
  13. #include <linux/pci.h>
  14. #include <asm/io.h>
  15. #include "tpam.h"
  16. /*
  17.  * Write a DWORD into the board memory.
  18.  *
  19.  *  card: the board
  20.  *  addr: the address (in the board memory)
  21.  *  val: the value to put into the memory.
  22.  */
  23. void copy_to_pam_dword(tpam_card *card, const void *addr, u32 val) {
  24. /* set the page register */
  25. writel(((unsigned long)addr) | TPAM_PAGE_SIZE, 
  26.        card->bar0 + TPAM_PAGE_REGISTER);
  27. /* write the value */
  28. writel(val, card->bar0 + (((u32)addr) & TPAM_PAGE_SIZE));
  29. }
  30. /*
  31.  * Write n bytes into the board memory. The count of bytes will be rounded
  32.  * up to a multiple of 4.
  33.  *
  34.  *  card: the board
  35.  *  to: the destination address (in the board memory)
  36.  *  from: the source address (in the kernel memory)
  37.  *  n: number of bytes
  38.  */
  39. void copy_to_pam(tpam_card *card, void *to, const void *from, u32 n) {
  40. u32 page, offset, count;
  41. /* need to write in dword ! */
  42. while (n & 3) n++;
  43. while (n) {
  44. page = ((u32)to) | TPAM_PAGE_SIZE;
  45. offset = ((u32)to) & TPAM_PAGE_SIZE;
  46. count = n < TPAM_PAGE_SIZE - offset
  47. ? n
  48. : TPAM_PAGE_SIZE - offset;
  49. /* set the page register */
  50. writel(page, card->bar0 + TPAM_PAGE_REGISTER);
  51. /* copy the data */
  52. memcpy_toio((void *)(card->bar0 + offset), from, count);
  53. from += count;
  54. to += count;
  55. n -= count;
  56. }
  57. }
  58. /*
  59.  * Read a DWORD from the board memory.
  60.  *
  61.  *  card: the board
  62.  *  addr: the address (in the board memory)
  63.  *
  64.  * Return: the value read into the memory.
  65.  */
  66. u32 copy_from_pam_dword(tpam_card *card, const void *addr) {
  67. /* set the page register */
  68. writel(((u32)addr) | TPAM_PAGE_SIZE, 
  69.        card->bar0 + TPAM_PAGE_REGISTER);
  70. /* read the data */
  71. return readl(card->bar0 + (((u32)addr) & TPAM_PAGE_SIZE));
  72. }
  73. /*
  74.  * Read n bytes from the board memory.
  75.  *
  76.  *  card: the board
  77.  *  to: the destination address (in the kernel memory)
  78.  *  from: the source address (in the board memory)
  79.  *  n: number of bytes
  80.  */
  81. void copy_from_pam(tpam_card *card, void *to, const void *from, u32 n) {
  82. u32 page, offset, count;
  83. while (n) {
  84. page = ((u32)from) | TPAM_PAGE_SIZE;
  85. offset = ((u32)from) & TPAM_PAGE_SIZE;
  86. count = n < TPAM_PAGE_SIZE - offset 
  87. ? n 
  88. : TPAM_PAGE_SIZE - offset;
  89. /* set the page register */
  90. writel(page, card->bar0 + TPAM_PAGE_REGISTER);
  91. /* read the data */
  92. memcpy_fromio(to, (void *)(card->bar0 + offset), count);
  93. from += count;
  94. to += count;
  95. n -= count;
  96. }
  97. }
  98. /*
  99.  * Read n bytes from the board memory and writes them into the user memory.
  100.  *
  101.  *  card: the board
  102.  *  to: the destination address (in the userspace memory)
  103.  *  from: the source address (in the board memory)
  104.  *  n: number of bytes
  105.  *
  106.  * Return: 0 if OK, <0 if error.
  107.  */
  108. int copy_from_pam_to_user(tpam_card *card, void *to, const void *from, u32 n) {
  109. void *page;
  110. u32 count;
  111. /* allocate a free page for the data transfer */
  112. if (!(page = (void *)__get_free_page(GFP_KERNEL))) {
  113. printk(KERN_ERR "TurboPAM(copy_from_pam_to_user): "
  114.        "get_free_page failedn");
  115. return -ENOMEM;
  116. }
  117. while (n) {
  118. count = n < PAGE_SIZE ? n : PAGE_SIZE;
  119. /* copy data from the board into the kernel memory */
  120. spin_lock_irq(&card->lock);
  121. copy_from_pam(card, page, from, count);
  122. spin_unlock_irq(&card->lock);
  123. /* copy it from the kernel memory into the user memory */
  124. if (copy_to_user(to, page, count)) {
  125. /* this can fail... */
  126. free_page((u32)page);
  127. return -EFAULT;
  128. }
  129. from += count;
  130. to += count;
  131. n -= count;
  132. }
  133. /* release allocated memory */
  134. free_page((u32)page);
  135. return 0;
  136. }
  137. /*
  138.  * Read n bytes from the user memory and writes them into the board memory.
  139.  *
  140.  *  card: the board
  141.  *  to: the destination address (in the board memory)
  142.  *  from: the source address (in the userspace memory)
  143.  *  n: number of bytes
  144.  *
  145.  * Return: 0 if OK, <0 if error.
  146.  */
  147. int copy_from_user_to_pam(tpam_card *card, void *to, const void *from, u32 n) {
  148. void *page;
  149. u32 count;
  150. /* allocate a free page for the data transfer */
  151. if (!(page = (void *)__get_free_page(GFP_KERNEL))) {
  152. printk(KERN_ERR "TurboPAM(copy_from_user_to_pam): "
  153.        "get_free_page failedn");
  154. return -ENOMEM;
  155. }
  156. while (n) {
  157. count = n < PAGE_SIZE ? n : PAGE_SIZE;
  158. /* copy data from the user memory into the kernel memory */
  159. if (copy_from_user(page, from, count)) {
  160. /* this can fail... */
  161. free_page((u32)page);
  162. return -EFAULT;
  163. }
  164. /* copy it from the kernel memory into the board memory */
  165. spin_lock_irq(&card->lock);
  166. copy_to_pam(card, to, page, count);
  167. spin_unlock_irq(&card->lock);
  168. from += count;
  169. to += count;
  170. n -= count;
  171. }
  172. /* release allocated memory */
  173. free_page((u32)page);
  174. return 0;
  175. }
  176. /*
  177.  * Verify if we have the permission to read or writes len bytes at the
  178.  * address address from/to the board memory.
  179.  *
  180.  *  address: the start address (in the board memory)
  181.  *  len: number of bytes
  182.  *
  183.  * Return: 0 if OK, <0 if error.
  184.  */
  185. int tpam_verify_area(u32 address, u32 len) {
  186. if (address < TPAM_RESERVEDAREA1_START)
  187. return (address + len <= TPAM_RESERVEDAREA1_START) ? 0 : -1;
  188. if (address <= TPAM_RESERVEDAREA1_END)
  189. return -1;
  190. if (address < TPAM_RESERVEDAREA2_START)
  191. return (address + len <= TPAM_RESERVEDAREA2_START) ? 0 : -1;
  192. if (address <= TPAM_RESERVEDAREA2_END)
  193. return -1;
  194. if (address < TPAM_RESERVEDAREA3_START)
  195. return (address + len <= TPAM_RESERVEDAREA3_START) ? 0 : -1;
  196. if (address <= TPAM_RESERVEDAREA3_END)
  197. return -1;
  198. if (address < TPAM_RESERVEDAREA4_START)
  199. return (address + len <= TPAM_RESERVEDAREA4_START) ? 0 : -1;
  200. if (address <= TPAM_RESERVEDAREA4_END)
  201. return -1;
  202. return 0;
  203. }