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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: command.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 <linux/module.h>
  19. #include "includes.h" /* This must be first */
  20. #include "hardware.h"
  21. #include "message.h"
  22. #include "card.h"
  23. #include "scioc.h"
  24. int dial(int card, unsigned long channel, setup_parm setup);
  25. int hangup(int card, unsigned long channel);
  26. int answer(int card, unsigned long channel);
  27. int clreaz(int card, unsigned long channel);
  28. int seteaz(int card, unsigned long channel, char *);
  29. int geteaz(int card, unsigned long channel, char *);
  30. int setsil(int card, unsigned long channel, char *);
  31. int getsil(int card, unsigned long channel, char *);
  32. int setl2(int card, unsigned long arg);
  33. int getl2(int card, unsigned long arg);
  34. int setl3(int card, unsigned long arg);
  35. int getl3(int card, unsigned long arg);
  36. int lock(void);
  37. int unlock(void);
  38. int acceptb(int card, unsigned long channel);
  39. extern int cinst;
  40. extern board *adapter[];
  41. extern int sc_ioctl(int, scs_ioctl *);
  42. extern int setup_buffers(int, int, unsigned int);
  43. extern int indicate_status(int, int,ulong,char*);
  44. extern void check_reset(unsigned long);
  45. extern int send_and_receive(int, unsigned int, unsigned char, unsigned char,
  46.                 unsigned char, unsigned char, unsigned char, unsigned char *,
  47.                 RspMessage *, int);
  48. extern int sendmessage(int, unsigned int, unsigned int, unsigned int,
  49.                 unsigned int, unsigned int, unsigned int, unsigned int *);
  50. extern inline void pullphone(char *, char *);
  51. #ifdef DEBUG
  52. /*
  53.  * Translate command codes to strings
  54.  */
  55. static char *commands[] = { "ISDN_CMD_IOCTL",
  56.     "ISDN_CMD_DIAL",
  57.     "ISDN_CMD_ACCEPTB",
  58.     "ISDN_CMD_ACCEPTB",
  59.     "ISDN_CMD_HANGUP",
  60.     "ISDN_CMD_CLREAZ",
  61.     "ISDN_CMD_SETEAZ",
  62.     "ISDN_CMD_GETEAZ",
  63.     "ISDN_CMD_SETSIL",
  64.     "ISDN_CMD_GETSIL",
  65.     "ISDN_CMD_SETL2",
  66.     "ISDN_CMD_GETL2",
  67.     "ISDN_CMD_SETL3",
  68.     "ISDN_CMD_GETL3",
  69.     "ISDN_CMD_LOCK",
  70.     "ISDN_CMD_UNLOCK",
  71.     "ISDN_CMD_SUSPEND",
  72.     "ISDN_CMD_RESUME" };
  73. /*
  74.  * Translates ISDN4Linux protocol codes to strings for debug messages
  75.  */
  76. static char *l3protos[] = { "ISDN_PROTO_L3_TRANS" };
  77. static char *l2protos[] = { "ISDN_PROTO_L2_X75I",
  78.     "ISDN_PROTO_L2_X75UI",
  79.     "ISDN_PROTO_L2_X75BUI",
  80.     "ISDN_PROTO_L2_HDLC",
  81.     "ISDN_PROTO_L2_TRANS" };
  82. #endif
  83. int get_card_from_id(int driver)
  84. {
  85. int i;
  86. for(i = 0 ; i < cinst ; i++) {
  87. if(adapter[i]->driverId == driver)
  88. return i;
  89. }
  90. return -NODEV;
  91. }
  92. /* 
  93.  * command
  94.  */
  95. int command(isdn_ctrl *cmd)
  96. {
  97. int card;
  98. card = get_card_from_id(cmd->driver);
  99. if(!IS_VALID_CARD(card)) {
  100. pr_debug("Invalid param: %d is not a valid card idn", card);
  101. return -ENODEV;
  102. }
  103. pr_debug("%s: Received %s command from Link Layern",
  104. adapter[card]->devicename, commands[cmd->command]);
  105. /*
  106.  * Dispatch the command
  107.  */
  108. switch(cmd->command) {
  109. case ISDN_CMD_IOCTL:
  110. {
  111. unsigned long  cmdptr;
  112. scs_ioctl ioc;
  113. int err;
  114. memcpy(&cmdptr, cmd->parm.num, sizeof(unsigned long));
  115. if((err = copy_from_user(&ioc, (scs_ioctl *) cmdptr, 
  116. sizeof(scs_ioctl)))) {
  117. pr_debug("%s: Failed to verify user space 0x%xn",
  118. adapter[card]->devicename, cmdptr);
  119. return err;
  120. }
  121. return sc_ioctl(card, &ioc);
  122. }
  123. case ISDN_CMD_DIAL:
  124. return dial(card, cmd->arg, cmd->parm.setup);
  125. case ISDN_CMD_HANGUP:
  126. return hangup(card, cmd->arg);
  127. case ISDN_CMD_ACCEPTD:
  128. return answer(card, cmd->arg);
  129. case ISDN_CMD_ACCEPTB:
  130. return acceptb(card, cmd->arg);
  131. case ISDN_CMD_CLREAZ:
  132. return clreaz(card, cmd->arg);
  133. case ISDN_CMD_SETEAZ:
  134. return seteaz(card, cmd->arg, cmd->parm.num);
  135. case ISDN_CMD_GETEAZ:
  136. return geteaz(card, cmd->arg, cmd->parm.num);
  137. case ISDN_CMD_SETSIL:
  138. return setsil(card, cmd->arg, cmd->parm.num);
  139. case ISDN_CMD_GETSIL:
  140. return getsil(card, cmd->arg, cmd->parm.num);
  141. case ISDN_CMD_SETL2:
  142. return setl2(card, cmd->arg);
  143. case ISDN_CMD_GETL2:
  144. return getl2(card, cmd->arg);
  145. case ISDN_CMD_SETL3:
  146. return setl3(card, cmd->arg);
  147. case ISDN_CMD_GETL3:
  148. return getl3(card, cmd->arg);
  149. case ISDN_CMD_LOCK:
  150. return lock();
  151. case ISDN_CMD_UNLOCK:
  152. return unlock();
  153. default:
  154. return -EINVAL;
  155. }
  156. return 0;
  157. }
  158. /*
  159.  * Confirm our ability to communicate with the board.  This test assumes no
  160.  * other message activity is present
  161.  */
  162. int loopback(int card) 
  163. {
  164. int status;
  165. static char testmsg[] = "Test Message";
  166. RspMessage rspmsg;
  167. if(!IS_VALID_CARD(card)) {
  168. pr_debug("Invalid param: %d is not a valid card idn", card);
  169. return -ENODEV;
  170. }
  171. pr_debug("%s: Sending loopback messagen", adapter[card]->devicename);
  172. /*
  173.  * Send the loopback message to confirm that memory transfer is
  174.  * operational
  175.  */
  176. status = send_and_receive(card, CMPID, cmReqType1,
  177.   cmReqClass0,
  178.   cmReqMsgLpbk,
  179.   0,
  180.   (unsigned char) strlen(testmsg),
  181.   (unsigned char *)testmsg,
  182.   &rspmsg, SAR_TIMEOUT);
  183. if (!status) {
  184. pr_debug("%s: Loopback message successfully sentn",
  185. adapter[card]->devicename);
  186. if(strcmp(rspmsg.msg_data.byte_array, testmsg)) {
  187. pr_debug("%s: Loopback return != sentn",
  188. adapter[card]->devicename);
  189. return -EIO;
  190. }
  191. return 0;
  192. }
  193. else {
  194. pr_debug("%s: Send loopback message failedn",
  195. adapter[card]->devicename);
  196. return -EIO;
  197. }
  198. }
  199. /*
  200.  * start the onboard firmware
  201.  */
  202. int startproc(int card) 
  203. {
  204. int status;
  205. if(!IS_VALID_CARD(card)) {
  206. pr_debug("Invalid param: %d is not a valid card idn", card);
  207. return -ENODEV;
  208. }
  209. /*
  210.  * send start msg 
  211.  */
  212.         status = sendmessage(card, CMPID,cmReqType2,
  213.   cmReqClass0,
  214.   cmReqStartProc,
  215.   0,0,0);
  216. pr_debug("%s: Sent startProcn", adapter[card]->devicename);
  217. return status;
  218. }
  219. int loadproc(int card, char *data) 
  220. {
  221. return -1;
  222. }
  223. /*
  224.  * Dials the number passed in 
  225.  */
  226. int dial(int card, unsigned long channel, setup_parm setup) 
  227. {
  228. int status;
  229. char Phone[48];
  230.   
  231. if(!IS_VALID_CARD(card)) {
  232. pr_debug("Invalid param: %d is not a valid card idn", card);
  233. return -ENODEV;
  234. }
  235. /*extract ISDN number to dial from eaz/msn string*/ 
  236. strcpy(Phone,setup.phone); 
  237. /*send the connection message*/
  238. status = sendmessage(card, CEPID,ceReqTypePhy,
  239. ceReqClass1,
  240. ceReqPhyConnect,
  241. (unsigned char) channel+1, 
  242. strlen(Phone),
  243. (unsigned int *) Phone);
  244. pr_debug("%s: Dialing %s on channel %dn",
  245. adapter[card]->devicename, Phone, channel+1);
  246. return status;
  247. }
  248. /*
  249.  * Answer an incoming call 
  250.  */
  251. int answer(int card, unsigned long channel) 
  252. {
  253. if(!IS_VALID_CARD(card)) {
  254. pr_debug("Invalid param: %d is not a valid card idn", card);
  255. return -ENODEV;
  256. }
  257. if(setup_buffers(card, channel+1, BUFFER_SIZE)) {
  258. hangup(card, channel+1);
  259. return -ENOBUFS;
  260. }
  261. indicate_status(card, ISDN_STAT_BCONN,channel,NULL);
  262. pr_debug("%s: Answered incoming call on channel %sn",
  263. adapter[card]->devicename, channel+1);
  264. return 0;
  265. }
  266. /*
  267.  * Hangup up the call on specified channel
  268.  */
  269. int hangup(int card, unsigned long channel) 
  270. {
  271. int status;
  272. if(!IS_VALID_CARD(card)) {
  273. pr_debug("Invalid param: %d is not a valid card idn", card);
  274. return -ENODEV;
  275. }
  276. status = sendmessage(card, CEPID, ceReqTypePhy,
  277.  ceReqClass1,
  278.  ceReqPhyDisconnect,
  279.  (unsigned char) channel+1,
  280.  0,
  281.  NULL);
  282. pr_debug("%s: Sent HANGUP message to channel %dn",
  283. adapter[card]->devicename, channel+1);
  284. return status;
  285. }
  286. /*
  287.  * Set the layer 2 protocol (X.25, HDLC, Raw)
  288.  */
  289. int setl2(int card, unsigned long arg) 
  290. {
  291. int status =0;
  292. int protocol,channel;
  293. if(!IS_VALID_CARD(card)) {
  294. pr_debug("Invalid param: %d is not a valid card idn", card);
  295. return -ENODEV;
  296. }
  297. protocol = arg >> 8;
  298. channel = arg & 0xff;
  299. adapter[card]->channel[channel].l2_proto = protocol;
  300. pr_debug("%s: Level 2 protocol for channel %d set to %s from %dn",
  301. adapter[card]->devicename, channel+1,l2protos[adapter[card]->channel[channel].l2_proto],protocol);
  302. /*
  303.  * check that the adapter is also set to the correct protocol
  304.  */
  305. pr_debug("%s: Sending GetFrameFormat for channel %dn",
  306. adapter[card]->devicename, channel+1);
  307. status = sendmessage(card, CEPID, ceReqTypeCall,
  308.   ceReqClass0,
  309.   ceReqCallGetFrameFormat,
  310.   (unsigned char)channel+1,
  311.   1,
  312.   (unsigned int *) protocol);
  313. if(status) 
  314. return status;
  315. return 0;
  316. }
  317. /*
  318.  * Get the layer 2 protocol
  319.  */
  320. int getl2(int card, unsigned long channel) {
  321. if(!IS_VALID_CARD(card)) {
  322. pr_debug("Invalid param: %d is not a valid card idn", card);
  323. return -ENODEV;
  324. }
  325. pr_debug("%s: Level 2 protocol for channel %d reported as %sn",
  326. adapter[card]->devicename, channel+1,
  327. l2protos[adapter[card]->channel[channel].l2_proto]);
  328. return adapter[card]->channel[channel].l2_proto;
  329. }
  330. /*
  331.  * Set the layer 3 protocol
  332.  */
  333. int setl3(int card, unsigned long channel) 
  334. {
  335. int protocol = channel >> 8;
  336. if(!IS_VALID_CARD(card)) {
  337. pr_debug("Invalid param: %d is not a valid card idn", card);
  338. return -ENODEV;
  339. }
  340. adapter[card]->channel[channel].l3_proto = protocol;
  341. pr_debug("%s: Level 3 protocol for channel %d set to %sn",
  342. adapter[card]->devicename, channel+1, l3protos[protocol]);
  343. return 0;
  344. }
  345. /*
  346.  * Get the layer 3 protocol
  347.  */
  348. int getl3(int card, unsigned long arg) 
  349. {
  350. if(!IS_VALID_CARD(card)) {
  351. pr_debug("Invalid param: %d is not a valid card idn", card);
  352. return -ENODEV;
  353. }
  354. pr_debug("%s: Level 3 protocol for channel %d reported as %sn",
  355. adapter[card]->devicename, arg+1,
  356. l3protos[adapter[card]->channel[arg].l3_proto]);
  357. return adapter[card]->channel[arg].l3_proto;
  358. }
  359. int acceptb(int card, unsigned long channel)
  360. {
  361. if(!IS_VALID_CARD(card)) {
  362. pr_debug("Invalid param: %d is not a valid card idn", card);
  363. return -ENODEV;
  364. }
  365. if(setup_buffers(card, channel+1, BUFFER_SIZE))
  366. {
  367. hangup(card, channel+1);
  368. return -ENOBUFS;
  369. }
  370. pr_debug("%s: B-Channel connection accepted on channel %dn",
  371. adapter[card]->devicename, channel+1);
  372. indicate_status(card, ISDN_STAT_BCONN, channel, NULL);
  373. return 0;
  374. }
  375. int clreaz(int card, unsigned long arg)
  376. {
  377. if(!IS_VALID_CARD(card)) {
  378. pr_debug("Invalid param: %d is not a valid card idn", card);
  379. return -ENODEV;
  380. }
  381. strcpy(adapter[card]->channel[arg].eazlist, "");
  382. adapter[card]->channel[arg].eazclear = 1;
  383. pr_debug("%s: EAZ List cleared for channel %dn",
  384. adapter[card]->devicename, arg+1);
  385. return 0;
  386. }
  387. int seteaz(int card, unsigned long arg, char *num)
  388. {
  389. if(!IS_VALID_CARD(card)) {
  390. pr_debug("Invalid param: %d is not a valid card idn", card);
  391. return -ENODEV;
  392. }
  393. strcpy(adapter[card]->channel[arg].eazlist, num);
  394. adapter[card]->channel[arg].eazclear = 0;
  395. pr_debug("%s: EAZ list for channel %d set to: %sn",
  396. adapter[card]->devicename, arg+1,
  397. adapter[card]->channel[arg].eazlist);
  398. return 0;
  399. }
  400. int geteaz(int card, unsigned long arg, char *num)
  401. {
  402. if(!IS_VALID_CARD(card)) {
  403. pr_debug("Invalid param: %d is not a valid card idn", card);
  404. return -ENODEV;
  405. }
  406. strcpy(num, adapter[card]->channel[arg].eazlist);
  407. pr_debug("%s: EAZ List for channel %d reported: %sn",
  408. adapter[card]->devicename, arg+1,
  409. adapter[card]->channel[arg].eazlist);
  410. return 0;
  411. }
  412. int setsil(int card, unsigned long arg, char *num)
  413. {
  414. if(!IS_VALID_CARD(card)) {
  415. pr_debug("Invalid param: %d is not a valid card idn", card);
  416. return -ENODEV;
  417. }
  418. strcpy(adapter[card]->channel[arg].sillist, num);
  419. pr_debug("%s: Service Indicators for channel %d set: %sn",
  420. adapter[card]->devicename, arg+1,
  421. adapter[card]->channel[arg].sillist);
  422. return 0;
  423. }
  424. int getsil(int card, unsigned long arg, char *num)
  425. {
  426. if(!IS_VALID_CARD(card)) {
  427. pr_debug("Invalid param: %d is not a valid card idn", card);
  428. return -ENODEV;
  429. }
  430. strcpy(num, adapter[card]->channel[arg].sillist);
  431. pr_debug("%s: SIL for channel %d reported: %sn",
  432. adapter[card]->devicename, arg+1,
  433. adapter[card]->channel[arg].sillist);
  434. return 0;
  435. }
  436. int lock()
  437. {
  438. MOD_INC_USE_COUNT;
  439. return 0;
  440. }
  441. int unlock()
  442. {
  443. MOD_DEC_USE_COUNT;
  444. return 0;
  445. }
  446. int reset(int card)
  447. {
  448. unsigned long flags;
  449. if(!IS_VALID_CARD(card)) {
  450. pr_debug("Invalid param: %d is not a valid card idn", card);
  451. return -ENODEV;
  452. }
  453. indicate_status(card, ISDN_STAT_STOP, 0, NULL);
  454. if(adapter[card]->EngineUp) {
  455. del_timer(&adapter[card]->stat_timer);
  456. }
  457. adapter[card]->EngineUp = 0;
  458. save_flags(flags);
  459. cli();
  460. init_timer(&adapter[card]->reset_timer);
  461. adapter[card]->reset_timer.function = check_reset;
  462. adapter[card]->reset_timer.data = card;
  463. adapter[card]->reset_timer.expires = jiffies + CHECKRESET_TIME;
  464. add_timer(&adapter[card]->reset_timer);
  465. restore_flags(flags);
  466. outb(0x1,adapter[card]->ioport[SFT_RESET]); 
  467. pr_debug("%s: Adapter Resetn", adapter[card]->devicename);
  468. return 0;
  469. }
  470. void flushreadfifo (int card)
  471. {
  472. while(inb(adapter[card]->ioport[FIFO_STATUS]) & RF_HAS_DATA)
  473. inb(adapter[card]->ioport[FIFO_READ]);
  474. }