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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* $Id: hscx.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  2.  *
  3.  * HSCX specific routines
  4.  *
  5.  * Author       Karsten Keil
  6.  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
  7.  * 
  8.  * This software may be used and distributed according to the terms
  9.  * of the GNU General Public License, incorporated herein by reference.
  10.  *
  11.  */
  12. #define __NO_VERSION__
  13. #include <linux/init.h>
  14. #include "hisax.h"
  15. #include "hscx.h"
  16. #include "isac.h"
  17. #include "isdnl1.h"
  18. #include <linux/interrupt.h>
  19. static char *HSCXVer[] __initdata =
  20. {"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7",
  21.  "?8", "?9", "?10", "?11", "?12", "?13", "?14", "???"};
  22. int __init
  23. HscxVersion(struct IsdnCardState *cs, char *s)
  24. {
  25. int verA, verB;
  26. verA = cs->BC_Read_Reg(cs, 0, HSCX_VSTR) & 0xf;
  27. verB = cs->BC_Read_Reg(cs, 1, HSCX_VSTR) & 0xf;
  28. printk(KERN_INFO "%s HSCX version A: %s  B: %sn", s,
  29.        HSCXVer[verA], HSCXVer[verB]);
  30. if ((verA == 0) | (verA == 0xf) | (verB == 0) | (verB == 0xf))
  31. return (1);
  32. else
  33. return (0);
  34. }
  35. void
  36. modehscx(struct BCState *bcs, int mode, int bc)
  37. {
  38. struct IsdnCardState *cs = bcs->cs;
  39. int hscx = bcs->hw.hscx.hscx;
  40. if (cs->debug & L1_DEB_HSCX)
  41. debugl1(cs, "hscx %c mode %d ichan %d",
  42. 'A' + hscx, mode, bc);
  43. bcs->mode = mode;
  44. bcs->channel = bc;
  45. cs->BC_Write_Reg(cs, hscx, HSCX_XAD1, 0xFF);
  46. cs->BC_Write_Reg(cs, hscx, HSCX_XAD2, 0xFF);
  47. cs->BC_Write_Reg(cs, hscx, HSCX_RAH2, 0xFF);
  48. cs->BC_Write_Reg(cs, hscx, HSCX_XBCH, 0x0);
  49. cs->BC_Write_Reg(cs, hscx, HSCX_RLCR, 0x0);
  50. cs->BC_Write_Reg(cs, hscx, HSCX_CCR1,
  51. test_bit(HW_IPAC, &cs->HW_Flags) ? 0x82 : 0x85);
  52. cs->BC_Write_Reg(cs, hscx, HSCX_CCR2, 0x30);
  53. cs->BC_Write_Reg(cs, hscx, HSCX_XCCR, 7);
  54. cs->BC_Write_Reg(cs, hscx, HSCX_RCCR, 7);
  55. /* Switch IOM 1 SSI */
  56. if (test_bit(HW_IOM1, &cs->HW_Flags) && (hscx == 0))
  57. bc = 1 - bc;
  58. if (bc == 0) {
  59. cs->BC_Write_Reg(cs, hscx, HSCX_TSAX,
  60.       test_bit(HW_IOM1, &cs->HW_Flags) ? 0x7 : bcs->hw.hscx.tsaxr0);
  61. cs->BC_Write_Reg(cs, hscx, HSCX_TSAR,
  62.       test_bit(HW_IOM1, &cs->HW_Flags) ? 0x7 : bcs->hw.hscx.tsaxr0);
  63. } else {
  64. cs->BC_Write_Reg(cs, hscx, HSCX_TSAX, bcs->hw.hscx.tsaxr1);
  65. cs->BC_Write_Reg(cs, hscx, HSCX_TSAR, bcs->hw.hscx.tsaxr1);
  66. }
  67. switch (mode) {
  68. case (L1_MODE_NULL):
  69. cs->BC_Write_Reg(cs, hscx, HSCX_TSAX, 0x1f);
  70. cs->BC_Write_Reg(cs, hscx, HSCX_TSAR, 0x1f);
  71. cs->BC_Write_Reg(cs, hscx, HSCX_MODE, 0x84);
  72. break;
  73. case (L1_MODE_TRANS):
  74. cs->BC_Write_Reg(cs, hscx, HSCX_MODE, 0xe4);
  75. break;
  76. case (L1_MODE_HDLC):
  77. cs->BC_Write_Reg(cs, hscx, HSCX_CCR1,
  78. test_bit(HW_IPAC, &cs->HW_Flags) ? 0x8a : 0x8d);
  79. cs->BC_Write_Reg(cs, hscx, HSCX_MODE, 0x8c);
  80. break;
  81. }
  82. if (mode)
  83. cs->BC_Write_Reg(cs, hscx, HSCX_CMDR, 0x41);
  84. cs->BC_Write_Reg(cs, hscx, HSCX_ISTA, 0x00);
  85. }
  86. void
  87. hscx_sched_event(struct BCState *bcs, int event)
  88. {
  89. bcs->event |= 1 << event;
  90. queue_task(&bcs->tqueue, &tq_immediate);
  91. mark_bh(IMMEDIATE_BH);
  92. }
  93. void
  94. hscx_l2l1(struct PStack *st, int pr, void *arg)
  95. {
  96. struct sk_buff *skb = arg;
  97. long flags;
  98. switch (pr) {
  99. case (PH_DATA | REQUEST):
  100. save_flags(flags);
  101. cli();
  102. if (st->l1.bcs->tx_skb) {
  103. skb_queue_tail(&st->l1.bcs->squeue, skb);
  104. restore_flags(flags);
  105. } else {
  106. st->l1.bcs->tx_skb = skb;
  107. test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
  108. st->l1.bcs->hw.hscx.count = 0;
  109. restore_flags(flags);
  110. st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
  111. }
  112. break;
  113. case (PH_PULL | INDICATION):
  114. if (st->l1.bcs->tx_skb) {
  115. printk(KERN_WARNING "hscx_l2l1: this shouldn't happenn");
  116. break;
  117. }
  118. test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
  119. st->l1.bcs->tx_skb = skb;
  120. st->l1.bcs->hw.hscx.count = 0;
  121. st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
  122. break;
  123. case (PH_PULL | REQUEST):
  124. if (!st->l1.bcs->tx_skb) {
  125. test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
  126. st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
  127. } else
  128. test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
  129. break;
  130. case (PH_ACTIVATE | REQUEST):
  131. test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
  132. modehscx(st->l1.bcs, st->l1.mode, st->l1.bc);
  133. l1_msg_b(st, pr, arg);
  134. break;
  135. case (PH_DEACTIVATE | REQUEST):
  136. l1_msg_b(st, pr, arg);
  137. break;
  138. case (PH_DEACTIVATE | CONFIRM):
  139. test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
  140. test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
  141. modehscx(st->l1.bcs, 0, st->l1.bc);
  142. st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
  143. break;
  144. }
  145. }
  146. void
  147. close_hscxstate(struct BCState *bcs)
  148. {
  149. modehscx(bcs, 0, bcs->channel);
  150. if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
  151. if (bcs->hw.hscx.rcvbuf) {
  152. kfree(bcs->hw.hscx.rcvbuf);
  153. bcs->hw.hscx.rcvbuf = NULL;
  154. }
  155. if (bcs->blog) {
  156. kfree(bcs->blog);
  157. bcs->blog = NULL;
  158. }
  159. skb_queue_purge(&bcs->rqueue);
  160. skb_queue_purge(&bcs->squeue);
  161. if (bcs->tx_skb) {
  162. dev_kfree_skb_any(bcs->tx_skb);
  163. bcs->tx_skb = NULL;
  164. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  165. }
  166. }
  167. }
  168. int
  169. open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs)
  170. {
  171. if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
  172. if (!(bcs->hw.hscx.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
  173. printk(KERN_WARNING
  174. "HiSax: No memory for hscx.rcvbufn");
  175. test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
  176. return (1);
  177. }
  178. if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
  179. printk(KERN_WARNING
  180. "HiSax: No memory for bcs->blogn");
  181. test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
  182. kfree(bcs->hw.hscx.rcvbuf);
  183. bcs->hw.hscx.rcvbuf = NULL;
  184. return (2);
  185. }
  186. skb_queue_head_init(&bcs->rqueue);
  187. skb_queue_head_init(&bcs->squeue);
  188. }
  189. bcs->tx_skb = NULL;
  190. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  191. bcs->event = 0;
  192. bcs->hw.hscx.rcvidx = 0;
  193. bcs->tx_cnt = 0;
  194. return (0);
  195. }
  196. int
  197. setstack_hscx(struct PStack *st, struct BCState *bcs)
  198. {
  199. bcs->channel = st->l1.bc;
  200. if (open_hscxstate(st->l1.hardware, bcs))
  201. return (-1);
  202. st->l1.bcs = bcs;
  203. st->l2.l2l1 = hscx_l2l1;
  204. setstack_manager(st);
  205. bcs->st = st;
  206. setstack_l1_B(st);
  207. return (0);
  208. }
  209. void __init
  210. clear_pending_hscx_ints(struct IsdnCardState *cs)
  211. {
  212. int val, eval;
  213. val = cs->BC_Read_Reg(cs, 1, HSCX_ISTA);
  214. debugl1(cs, "HSCX B ISTA %x", val);
  215. if (val & 0x01) {
  216. eval = cs->BC_Read_Reg(cs, 1, HSCX_EXIR);
  217. debugl1(cs, "HSCX B EXIR %x", eval);
  218. }
  219. if (val & 0x02) {
  220. eval = cs->BC_Read_Reg(cs, 0, HSCX_EXIR);
  221. debugl1(cs, "HSCX A EXIR %x", eval);
  222. }
  223. val = cs->BC_Read_Reg(cs, 0, HSCX_ISTA);
  224. debugl1(cs, "HSCX A ISTA %x", val);
  225. val = cs->BC_Read_Reg(cs, 1, HSCX_STAR);
  226. debugl1(cs, "HSCX B STAR %x", val);
  227. val = cs->BC_Read_Reg(cs, 0, HSCX_STAR);
  228. debugl1(cs, "HSCX A STAR %x", val);
  229. /* disable all IRQ */
  230. cs->BC_Write_Reg(cs, 0, HSCX_MASK, 0xFF);
  231. cs->BC_Write_Reg(cs, 1, HSCX_MASK, 0xFF);
  232. }
  233. void __init
  234. inithscx(struct IsdnCardState *cs)
  235. {
  236. cs->bcs[0].BC_SetStack = setstack_hscx;
  237. cs->bcs[1].BC_SetStack = setstack_hscx;
  238. cs->bcs[0].BC_Close = close_hscxstate;
  239. cs->bcs[1].BC_Close = close_hscxstate;
  240. cs->bcs[0].hw.hscx.hscx = 0;
  241. cs->bcs[1].hw.hscx.hscx = 1;
  242. cs->bcs[0].hw.hscx.tsaxr0 = 0x2f;
  243. cs->bcs[0].hw.hscx.tsaxr1 = 3;
  244. cs->bcs[1].hw.hscx.tsaxr0 = 0x2f;
  245. cs->bcs[1].hw.hscx.tsaxr1 = 3;
  246. modehscx(cs->bcs, 0, 0);
  247. modehscx(cs->bcs + 1, 0, 0);
  248. }
  249. void __init
  250. inithscxisac(struct IsdnCardState *cs, int part)
  251. {
  252. if (part & 1) {
  253. clear_pending_isac_ints(cs);
  254. clear_pending_hscx_ints(cs);
  255. initisac(cs);
  256. inithscx(cs);
  257. }
  258. if (part & 2) {
  259. /* Reenable all IRQ */
  260. cs->writeisac(cs, ISAC_MASK, 0);
  261. cs->BC_Write_Reg(cs, 0, HSCX_MASK, 0);
  262. cs->BC_Write_Reg(cs, 1, HSCX_MASK, 0);
  263. /* RESET Receiver and Transmitter */
  264. cs->writeisac(cs, ISAC_CMDR, 0x41);
  265. }
  266. }