interrupt.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:7k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: interrupt.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  2.  *
  3.  * Copyright (C) 1996  SpellCaster Telecommunications Inc.
  4.  *
  5.  * This software may be used and distributed according to the terms
  6.  * of the GNU General Public License, incorporated herein by reference.
  7.  *
  8.  * For more information, please contact gpl-info@spellcast.com or write:
  9.  *
  10.  *     SpellCaster Telecommunications Inc.
  11.  *     5621 Finch Avenue East, Unit #3
  12.  *     Scarborough, Ontario  Canada
  13.  *     M1B 2T9
  14.  *     +1 (416) 297-8565
  15.  *     +1 (416) 297-6433 Facsimile
  16.  */
  17. #define __NO_VERSION__
  18. #include "includes.h"
  19. #include "hardware.h"
  20. #include "message.h"
  21. #include "card.h"
  22. extern int indicate_status(int, int, ulong, char *);
  23. extern void check_phystat(unsigned long);
  24. extern int receivemessage(int, RspMessage *);
  25. extern int sendmessage(int, unsigned int, unsigned int, unsigned int,
  26.         unsigned int, unsigned int, unsigned int, unsigned int *);
  27. extern void rcvpkt(int, RspMessage *);
  28. extern int cinst;
  29. extern board *adapter[];
  30. int get_card_from_irq(int irq)
  31. {
  32. int i;
  33. for(i = 0 ; i < cinst ; i++) {
  34. if(adapter[i]->interrupt == irq)
  35. return i;
  36. }
  37. return -1;
  38. }
  39. /*
  40.  * 
  41.  */
  42. void interrupt_handler(int interrupt, void * cardptr, struct pt_regs *regs ) {
  43. RspMessage rcvmsg;
  44. int channel;
  45. int card;
  46. card = get_card_from_irq(interrupt);
  47. if(!IS_VALID_CARD(card)) {
  48. pr_debug("Invalid param: %d is not a valid card idn", card);
  49. return;
  50. }
  51. pr_debug("%s: Entered Interrupt handlern", adapter[card]->devicename);
  52.   /*
  53.  * Pull all of the waiting messages off the response queue
  54.  */
  55. while (!receivemessage(card, &rcvmsg)) {
  56. /*
  57.  * Push the message to the adapter structure for
  58.  * send_and_receive to snoop
  59.  */
  60. if(adapter[card]->want_async_messages)
  61. memcpy(&(adapter[card]->async_msg), &rcvmsg, sizeof(RspMessage));
  62. channel = (unsigned int) rcvmsg.phy_link_no;
  63. /*
  64.  * Trap Invalid request messages
  65.  */
  66. if(IS_CM_MESSAGE(rcvmsg, 0, 0, Invalid)) {
  67. pr_debug("%s: Invalid request Message, rsp_status = %dn", 
  68. adapter[card]->devicename, rcvmsg.rsp_status);
  69. break;
  70. }
  71. /*
  72.  * Check for a linkRead message
  73.  */
  74. if (IS_CE_MESSAGE(rcvmsg, Lnk, 1, Read))
  75. {
  76. pr_debug("%s: Received packet 0x%x bytes long at 0x%xn",
  77. adapter[card]->devicename,
  78. rcvmsg.msg_data.response.msg_len,
  79. rcvmsg.msg_data.response.buff_offset);
  80. rcvpkt(card, &rcvmsg);
  81. continue;
  82. }
  83. /*
  84.  * Handle a write acknoledgement
  85.  */
  86. if(IS_CE_MESSAGE(rcvmsg, Lnk, 1, Write)) {
  87. pr_debug("%s: Packet Send ACK on channel %dn", adapter[card]->devicename,
  88. rcvmsg.phy_link_no);
  89. adapter[card]->channel[rcvmsg.phy_link_no-1].free_sendbufs++;
  90. continue;
  91. }
  92. /*
  93.  * Handle a connection message
  94.  */
  95. if (IS_CE_MESSAGE(rcvmsg, Phy, 1, Connect)) 
  96. {
  97. unsigned int callid;
  98. setup_parm setup;
  99. pr_debug("%s: Connect message: line %d: status %d: cause 0x%xn",
  100. adapter[card]->devicename,
  101. rcvmsg.phy_link_no,
  102. rcvmsg.rsp_status,
  103. rcvmsg.msg_data.byte_array[2]);
  104. memcpy(&callid,rcvmsg.msg_data.byte_array,sizeof(int));
  105. if(callid>=0x8000 && callid<=0xFFFF)
  106. {
  107. pr_debug("%s: Got Dial-Out Rspn", adapter[card]->devicename);
  108. indicate_status(card, ISDN_STAT_DCONN,
  109. (unsigned long)rcvmsg.phy_link_no-1,NULL);
  110. }
  111. else if(callid>=0x0000 && callid<=0x7FFF)
  112. {
  113. pr_debug("%s: Got Incoming Calln", adapter[card]->devicename);
  114. strcpy(setup.phone,&(rcvmsg.msg_data.byte_array[4]));
  115. strcpy(setup.eazmsn,adapter[card]->channel[rcvmsg.phy_link_no-1].dn);
  116. setup.si1 = 7;
  117. setup.si2 = 0;
  118. setup.plan = 0;
  119. setup.screen = 0;
  120. indicate_status(card, ISDN_STAT_ICALL,(unsigned long)rcvmsg.phy_link_no-1,(char *)&setup);
  121. indicate_status(card, ISDN_STAT_DCONN,(unsigned long)rcvmsg.phy_link_no-1,NULL);
  122. }
  123. continue;
  124. }
  125. /*
  126.  * Handle a disconnection message
  127.  */
  128. if (IS_CE_MESSAGE(rcvmsg, Phy, 1, Disconnect)) 
  129. {
  130. pr_debug("%s: disconnect message: line %d: status %d: cause 0x%xn",
  131. adapter[card]->devicename,
  132. rcvmsg.phy_link_no,
  133. rcvmsg.rsp_status,
  134.   rcvmsg.msg_data.byte_array[2]);
  135. indicate_status(card, ISDN_STAT_BHUP,(unsigned long)rcvmsg.phy_link_no-1,NULL);
  136. indicate_status(card, ISDN_STAT_DHUP,(unsigned long)rcvmsg.phy_link_no-1,NULL);
  137. continue;
  138. }
  139. /*
  140.  * Handle a startProc engine up message
  141.  */
  142. if (IS_CM_MESSAGE(rcvmsg, 5, 0, MiscEngineUp)) {
  143. pr_debug("%s: Received EngineUp messagen", adapter[card]->devicename);
  144. adapter[card]->EngineUp = 1;
  145. sendmessage(card, CEPID,ceReqTypeCall,ceReqClass0,ceReqCallGetMyNumber,1,0,NULL);
  146. sendmessage(card, CEPID,ceReqTypeCall,ceReqClass0,ceReqCallGetMyNumber,2,0,NULL);
  147. init_timer(&adapter[card]->stat_timer);
  148. adapter[card]->stat_timer.function = check_phystat;
  149. adapter[card]->stat_timer.data = card;
  150. adapter[card]->stat_timer.expires = jiffies + CHECKSTAT_TIME;
  151. add_timer(&adapter[card]->stat_timer);
  152. continue;
  153. }
  154. /*
  155.  * Start proc response
  156.  */
  157. if (IS_CM_MESSAGE(rcvmsg, 2, 0, StartProc)) {
  158. pr_debug("%s: StartProc Response Status %dn", adapter[card]->devicename,
  159. rcvmsg.rsp_status);
  160. continue;
  161. }
  162. /*
  163.  * Handle a GetMyNumber Rsp
  164.  */
  165. if (IS_CE_MESSAGE(rcvmsg,Call,0,GetMyNumber)){
  166. strcpy(adapter[card]->channel[rcvmsg.phy_link_no-1].dn,rcvmsg.msg_data.byte_array);
  167. continue;
  168. }
  169. /*
  170.  * PhyStatus response
  171.  */
  172. if(IS_CE_MESSAGE(rcvmsg, Phy, 2, Status)) {
  173. unsigned int b1stat, b2stat;
  174. /*
  175.  * Covert the message data to the adapter->phystat code
  176.  */
  177. b1stat = (unsigned int) rcvmsg.msg_data.byte_array[0];
  178. b2stat = (unsigned int) rcvmsg.msg_data.byte_array[1];
  179. adapter[card]->nphystat = (b2stat >> 8) | b1stat; /* endian?? */
  180. pr_debug("%s: PhyStat is 0x%2xn", adapter[card]->devicename,
  181. adapter[card]->nphystat);
  182. continue;
  183. }
  184. /* 
  185.  * Handle a GetFramFormat
  186.  */
  187. if(IS_CE_MESSAGE(rcvmsg, Call, 0, GetFrameFormat)) {
  188. if(rcvmsg.msg_data.byte_array[0] != HDLC_PROTO) {
  189. unsigned int proto = HDLC_PROTO;
  190. /*
  191.  * Set board format to HDLC if it wasn't already
  192.  */
  193. pr_debug("%s: current frame format: 0x%x, will change to HDLCn",
  194. adapter[card]->devicename,
  195. rcvmsg.msg_data.byte_array[0]);
  196. sendmessage(card, CEPID, ceReqTypeCall,
  197. ceReqClass0,
  198. ceReqCallSetFrameFormat,
  199. (unsigned char) channel +1,
  200. 1,&proto);
  201. }
  202. continue;
  203. }
  204. /*
  205.  * Hmm...
  206.  */
  207. pr_debug("%s: Received unhandled message (%d,%d,%d) link %dn",
  208. adapter[card]->devicename, rcvmsg.type, rcvmsg.class, rcvmsg.code, 
  209. rcvmsg.phy_link_no);
  210. } /* while */
  211. pr_debug("%s: Exiting Interrupt Handlern", adapter[card]->devicename);
  212. }