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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (C) Eicon Technology Corporation, 2000.
  3.  *
  4.  * Eicon File Revision :    1.12  
  5.  *
  6.  * This software may be used and distributed according to the terms
  7.  * of the GNU General Public License, incorporated herein by reference.
  8.  *
  9.  */
  10. #define __NO_VERSION__
  11. #include <linux/module.h>
  12. #include <linux/kernel.h>
  13. #include <linux/poll.h>
  14. #include <linux/fs.h>
  15. #include <linux/slab.h>
  16. #undef N_DATA
  17. #include "adapter.h"
  18. #include "divas.h"
  19. #include "divalog.h"
  20. extern int DivasCardNext;
  21. void UxPause(long ms);
  22. int DivasGetMem(mem_block_t *);
  23. #define DIA_IOCTL_UNLOCK 12
  24. void UnlockDivas(void);
  25. int do_ioctl(struct inode *pDivasInode, struct file *pDivasFile, 
  26.  unsigned int command, unsigned long arg)
  27. {
  28. byte *pUserCards, card_i;
  29. word wCardNum;
  30. switch (command)
  31. {
  32. case DIA_IOCTL_CONFIG:
  33. {
  34. dia_config_t DivaConfig;
  35. if (copy_from_user(&DivaConfig, (void *)arg, sizeof(dia_config_t)))
  36. return -EFAULT;
  37. DivasCardConfig(&DivaConfig);
  38. return 0;
  39. }
  40. case DIA_IOCTL_DETECT:
  41. pUserCards = (byte *) arg;
  42. if (!verify_area(VERIFY_WRITE, pUserCards, 20))
  43. {
  44. if(__put_user(DivasCardNext, pUserCards++))
  45. return -EFAULT;
  46. for (card_i=1; card_i < 20; card_i++)
  47. {
  48. if(__put_user((byte) DivasCards[card_i - 1].cfg.card_type, pUserCards++))
  49. return -EFAULT;
  50. }
  51. }
  52. else return -EFAULT;
  53. return 0;
  54. case DIA_IOCTL_START:
  55. {
  56. dia_start_t DivaStart;
  57. if (copy_from_user(&DivaStart, (void *)arg, sizeof(dia_start_t)))
  58. return -EFAULT;
  59. return DivasCardStart(DivaStart.card_id);
  60. }
  61. case DIA_IOCTL_FLAVOUR:
  62. return 0;
  63. case DIA_IOCTL_LOAD:
  64. {
  65. dia_load_t DivaLoad;
  66. if(copy_from_user(&DivaLoad, (void *)arg, sizeof(dia_load_t)))
  67. return -EFAULT;
  68. if (!verify_area(VERIFY_READ, DivaLoad.code,DivaLoad.length))
  69. {
  70. if (DivasCardLoad(&DivaLoad))
  71. {
  72. printk(KERN_WARNING "Divas: Error loading DIVA Server adaptern");
  73. return -EINVAL;
  74. }
  75. return 0;
  76. }
  77. return -EFAULT;
  78. }
  79. case DIA_IOCTL_LOG:
  80. {
  81. dia_log_t DivaLog;
  82. if (copy_from_user(&DivaLog, (void *) arg, sizeof(dia_log_t)))
  83. return -EFAULT;
  84. DivasLog(&DivaLog);
  85. return 0;
  86. }
  87. case DIA_IOCTL_XLOG_REQ:
  88. if(get_user(wCardNum, (word *) arg))
  89. return -EFAULT;
  90. DivasXlogReq(wCardNum);
  91. return 0;
  92. case DIA_IOCTL_GET_NUM:
  93. if(put_user(DivasCardNext, (int *)arg))
  94. return -EFAULT;
  95. return 0;
  96. case DIA_IOCTL_GET_LIST:
  97. {
  98. dia_card_list_t cards;
  99. DPRINTF(("divas: DIA_IOCTL_GET_LIST"));
  100. DivasGetList(&cards);
  101. if(copy_to_user((void *)arg, &cards, sizeof(cards)))
  102. return -EFAULT;
  103. return 0;
  104. }
  105. case DIA_IOCTL_GET_MEM:
  106. {
  107. mem_block_t mem_block;
  108. if (copy_from_user(&mem_block, (void *)arg, sizeof(mem_block_t)))
  109. return -EFAULT;
  110. DivasGetMem(&mem_block);
  111. return 0;
  112. }
  113. case DIA_IOCTL_UNLOCK:
  114. UnlockDivas();
  115. return 0;
  116. default:
  117. return -EINVAL;
  118. }
  119. return -EINVAL;
  120. }
  121. unsigned int do_poll(struct file *pFile, struct poll_table_struct *pPollTable)
  122. {
  123. word wMask = 0;
  124. if (!DivasLogFifoEmpty())
  125. wMask |= POLLIN | POLLRDNORM;
  126. return wMask;
  127. }
  128. ssize_t do_read(struct file *pFile, char *pUserBuffer, size_t BufferSize, loff_t *pOffset)
  129. {
  130. klog_t *pClientLogBuffer = (klog_t *) pUserBuffer;
  131. klog_t *pHeadItem;
  132. if (BufferSize < sizeof(klog_t))
  133. {
  134. printk(KERN_WARNING "Divas: Divalog buffer specifed a size that is too small (%d - %d required)n",
  135. BufferSize, sizeof(klog_t));
  136. return -EIO;
  137. }
  138. pHeadItem = (klog_t *) DivasLogFifoRead();
  139. if (pHeadItem)
  140. {
  141. memcpy(pClientLogBuffer, pHeadItem, sizeof(klog_t));
  142. kfree(pHeadItem);
  143. return sizeof(klog_t);
  144. }
  145. return 0;
  146. }
  147. static int private_usage_count;
  148. int do_open(struct inode *pInode, struct file *pFile)
  149. {
  150. MOD_INC_USE_COUNT;
  151. #ifdef MODULE
  152. private_usage_count++;
  153. #endif
  154. return 0;
  155. }
  156. int do_release(struct inode *pInode, struct file *pFile)
  157. {
  158. MOD_DEC_USE_COUNT;
  159. #ifdef MODULE
  160. private_usage_count--;
  161. #endif
  162. return 0;
  163. }
  164. void UnlockDivas(void)
  165. {
  166. while (private_usage_count > 0)
  167. {
  168. private_usage_count--;
  169. MOD_DEC_USE_COUNT;
  170. }
  171. }