2 * $Id: command.c,v 1.4 1997/03/30 16:51:34 calle Exp $
3 * Copyright (C) 1996 SpellCaster Telecommunications Inc.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 * For more information, please contact gpl-info@spellcast.com or write:
21 * SpellCaster Telecommunications Inc.
22 * 5621 Finch Avenue East, Unit #3
23 * Scarborough, Ontario Canada
26 * +1 (416) 297-6433 Facsimile
29 #define __NO_VERSION__
30 #include "includes.h" /* This must be first */
36 int dial(int card
, unsigned long channel
, setup_parm setup
);
37 int hangup(int card
, unsigned long channel
);
38 int answer(int card
, unsigned long channel
);
39 int clreaz(int card
, unsigned long channel
);
40 int seteaz(int card
, unsigned long channel
, char *);
41 int geteaz(int card
, unsigned long channel
, char *);
42 int setsil(int card
, unsigned long channel
, char *);
43 int getsil(int card
, unsigned long channel
, char *);
44 int setl2(int card
, unsigned long arg
);
45 int getl2(int card
, unsigned long arg
);
46 int setl3(int card
, unsigned long arg
);
47 int getl3(int card
, unsigned long arg
);
50 int acceptb(int card
, unsigned long channel
);
53 extern board
*adapter
[];
55 extern int sc_ioctl(int, scs_ioctl
*);
56 extern int setup_buffers(int, int, unsigned int);
57 extern int indicate_status(int, int,ulong
,char*);
58 extern void check_reset(unsigned long);
59 extern int send_and_receive(int, unsigned int, unsigned char, unsigned char,
60 unsigned char, unsigned char, unsigned char, unsigned char *,
62 extern int sendmessage(int, unsigned int, unsigned int, unsigned int,
63 unsigned int, unsigned int, unsigned int, unsigned int *);
64 extern inline void pullphone(char *, char *);
68 * Translate command codes to strings
70 static char *commands
[] = { "ISDN_CMD_IOCTL",
90 * Translates ISDN4Linux protocol codes to strings for debug messages
92 static char *l3protos
[] = { "ISDN_PROTO_L3_TRANS" };
93 static char *l2protos
[] = { "ISDN_PROTO_L2_X75I",
94 "ISDN_PROTO_L2_X75UI",
95 "ISDN_PROTO_L2_X75BUI",
97 "ISDN_PROTO_L2_TRANS" };
100 int get_card_from_id(int driver
)
104 for(i
= 0 ; i
< cinst
; i
++) {
105 if(adapter
[i
]->driverId
== driver
)
115 int command(isdn_ctrl
*cmd
)
119 card
= get_card_from_id(cmd
->driver
);
120 if(!IS_VALID_CARD(card
)) {
121 pr_debug("Invalid param: %d is not a valid card id\n", card
);
125 pr_debug("%s: Received %s command from Link Layer\n",
126 adapter
[card
]->devicename
, commands
[cmd
->command
]);
129 * Dispatch the command
131 switch(cmd
->command
) {
134 unsigned long cmdptr
;
138 memcpy(&cmdptr
, cmd
->parm
.num
, sizeof(unsigned long));
139 if((err
= copy_from_user(&ioc
, (scs_ioctl
*) cmdptr
,
140 sizeof(scs_ioctl
)))) {
141 pr_debug("%s: Failed to verify user space 0x%x\n",
142 adapter
[card
]->devicename
, cmdptr
);
145 return sc_ioctl(card
, &ioc
);
148 return dial(card
, cmd
->arg
, cmd
->parm
.setup
);
149 case ISDN_CMD_HANGUP
:
150 return hangup(card
, cmd
->arg
);
151 case ISDN_CMD_ACCEPTD
:
152 return answer(card
, cmd
->arg
);
153 case ISDN_CMD_ACCEPTB
:
154 return acceptb(card
, cmd
->arg
);
155 case ISDN_CMD_CLREAZ
:
156 return clreaz(card
, cmd
->arg
);
157 case ISDN_CMD_SETEAZ
:
158 return seteaz(card
, cmd
->arg
, cmd
->parm
.num
);
159 case ISDN_CMD_GETEAZ
:
160 return geteaz(card
, cmd
->arg
, cmd
->parm
.num
);
161 case ISDN_CMD_SETSIL
:
162 return setsil(card
, cmd
->arg
, cmd
->parm
.num
);
163 case ISDN_CMD_GETSIL
:
164 return getsil(card
, cmd
->arg
, cmd
->parm
.num
);
166 return setl2(card
, cmd
->arg
);
168 return getl2(card
, cmd
->arg
);
170 return setl3(card
, cmd
->arg
);
172 return getl3(card
, cmd
->arg
);
175 case ISDN_CMD_UNLOCK
:
184 * Confirm our ability to communicate with the board. This test assumes no
185 * other message activity is present
187 int loopback(int card
)
191 static char testmsg
[] = "Test Message";
194 if(!IS_VALID_CARD(card
)) {
195 pr_debug("Invalid param: %d is not a valid card id\n", card
);
199 pr_debug("%s: Sending loopback message\n", adapter
[card
]->devicename
);
203 * Send the loopback message to confirm that memory transfer is
206 status
= send_and_receive(card
, CMPID
, cmReqType1
,
210 (unsigned char) strlen(testmsg
),
211 (unsigned char *)testmsg
,
212 &rspmsg
, SAR_TIMEOUT
);
216 pr_debug("%s: Loopback message successfully sent\n",
217 adapter
[card
]->devicename
);
218 if(strcmp(rspmsg
.msg_data
.byte_array
, testmsg
)) {
219 pr_debug("%s: Loopback return != sent\n",
220 adapter
[card
]->devicename
);
226 pr_debug("%s: Send loopback message failed\n",
227 adapter
[card
]->devicename
);
234 * start the onboard firmware
236 int startproc(int card
)
240 if(!IS_VALID_CARD(card
)) {
241 pr_debug("Invalid param: %d is not a valid card id\n", card
);
248 status
= sendmessage(card
, CMPID
,cmReqType2
,
252 pr_debug("%s: Sent startProc\n", adapter
[card
]->devicename
);
258 int loadproc(int card
, char *data
)
265 * Dials the number passed in
267 int dial(int card
, unsigned long channel
, setup_parm setup
)
272 if(!IS_VALID_CARD(card
)) {
273 pr_debug("Invalid param: %d is not a valid card id\n", card
);
277 /*extract ISDN number to dial from eaz/msn string*/
278 strcpy(Phone
,setup
.phone
);
280 /*send the connection message*/
281 status
= sendmessage(card
, CEPID
,ceReqTypePhy
,
284 (unsigned char) channel
+1,
286 (unsigned int *) Phone
);
288 pr_debug("%s: Dialing %s on channel %d\n",
289 adapter
[card
]->devicename
, Phone
, channel
+1);
295 * Answer an incoming call
297 int answer(int card
, unsigned long channel
)
299 if(!IS_VALID_CARD(card
)) {
300 pr_debug("Invalid param: %d is not a valid card id\n", card
);
304 if(setup_buffers(card
, channel
+1, BUFFER_SIZE
)) {
305 hangup(card
, channel
+1);
309 indicate_status(card
, ISDN_STAT_BCONN
,channel
,NULL
);
310 pr_debug("%s: Answered incoming call on channel %s\n",
311 adapter
[card
]->devicename
, channel
+1);
316 * Hangup up the call on specified channel
318 int hangup(int card
, unsigned long channel
)
322 if(!IS_VALID_CARD(card
)) {
323 pr_debug("Invalid param: %d is not a valid card id\n", card
);
327 status
= sendmessage(card
, CEPID
, ceReqTypePhy
,
330 (unsigned char) channel
+1,
333 pr_debug("%s: Sent HANGUP message to channel %d\n",
334 adapter
[card
]->devicename
, channel
+1);
339 * Set the layer 2 protocol (X.25, HDLC, Raw)
341 int setl2(int card
, unsigned long arg
)
344 int protocol
,channel
;
346 if(!IS_VALID_CARD(card
)) {
347 pr_debug("Invalid param: %d is not a valid card id\n", card
);
351 channel
= arg
& 0xff;
352 adapter
[card
]->channel
[channel
].l2_proto
= protocol
;
353 pr_debug("%s: Level 2 protocol for channel %d set to %s from %d\n",
354 adapter
[card
]->devicename
, channel
+1,l2protos
[adapter
[card
]->channel
[channel
].l2_proto
],protocol
);
357 * check that the adapter is also set to the correct protocol
359 pr_debug("%s: Sending GetFrameFormat for channel %d\n",
360 adapter
[card
]->devicename
, channel
+1);
361 status
= sendmessage(card
, CEPID
, ceReqTypeCall
,
363 ceReqCallGetFrameFormat
,
364 (unsigned char)channel
+1,
366 (unsigned int *) protocol
);
373 * Get the layer 2 protocol
375 int getl2(int card
, unsigned long channel
) {
377 if(!IS_VALID_CARD(card
)) {
378 pr_debug("Invalid param: %d is not a valid card id\n", card
);
382 pr_debug("%s: Level 2 protocol for channel %d reported as %s\n",
383 adapter
[card
]->devicename
, channel
+1,
384 l2protos
[adapter
[card
]->channel
[channel
].l2_proto
]);
386 return adapter
[card
]->channel
[channel
].l2_proto
;
390 * Set the layer 3 protocol
392 int setl3(int card
, unsigned long channel
)
394 int protocol
= channel
>> 8;
396 if(!IS_VALID_CARD(card
)) {
397 pr_debug("Invalid param: %d is not a valid card id\n", card
);
401 adapter
[card
]->channel
[channel
].l3_proto
= protocol
;
402 pr_debug("%s: Level 3 protocol for channel %d set to %s\n",
403 adapter
[card
]->devicename
, channel
+1, l3protos
[protocol
]);
408 * Get the layer 3 protocol
410 int getl3(int card
, unsigned long arg
)
412 if(!IS_VALID_CARD(card
)) {
413 pr_debug("Invalid param: %d is not a valid card id\n", card
);
417 pr_debug("%s: Level 3 protocol for channel %d reported as %s\n",
418 adapter
[card
]->devicename
, arg
+1,
419 l3protos
[adapter
[card
]->channel
[arg
].l3_proto
]);
420 return adapter
[card
]->channel
[arg
].l3_proto
;
424 int acceptb(int card
, unsigned long channel
)
426 if(!IS_VALID_CARD(card
)) {
427 pr_debug("Invalid param: %d is not a valid card id\n", card
);
431 if(setup_buffers(card
, channel
+1, BUFFER_SIZE
))
433 hangup(card
, channel
+1);
437 pr_debug("%s: B-Channel connection accepted on channel %d\n",
438 adapter
[card
]->devicename
, channel
+1);
439 indicate_status(card
, ISDN_STAT_BCONN
, channel
, NULL
);
443 int clreaz(int card
, unsigned long arg
)
445 if(!IS_VALID_CARD(card
)) {
446 pr_debug("Invalid param: %d is not a valid card id\n", card
);
450 strcpy(adapter
[card
]->channel
[arg
].eazlist
, "");
451 adapter
[card
]->channel
[arg
].eazclear
= 1;
452 pr_debug("%s: EAZ List cleared for channel %d\n",
453 adapter
[card
]->devicename
, arg
+1);
457 int seteaz(int card
, unsigned long arg
, char *num
)
459 if(!IS_VALID_CARD(card
)) {
460 pr_debug("Invalid param: %d is not a valid card id\n", card
);
464 strcpy(adapter
[card
]->channel
[arg
].eazlist
, num
);
465 adapter
[card
]->channel
[arg
].eazclear
= 0;
466 pr_debug("%s: EAZ list for channel %d set to: %s\n",
467 adapter
[card
]->devicename
, arg
+1,
468 adapter
[card
]->channel
[arg
].eazlist
);
472 int geteaz(int card
, unsigned long arg
, char *num
)
474 if(!IS_VALID_CARD(card
)) {
475 pr_debug("Invalid param: %d is not a valid card id\n", card
);
479 strcpy(num
, adapter
[card
]->channel
[arg
].eazlist
);
480 pr_debug("%s: EAZ List for channel %d reported: %s\n",
481 adapter
[card
]->devicename
, arg
+1,
482 adapter
[card
]->channel
[arg
].eazlist
);
486 int setsil(int card
, unsigned long arg
, char *num
)
488 if(!IS_VALID_CARD(card
)) {
489 pr_debug("Invalid param: %d is not a valid card id\n", card
);
493 strcpy(adapter
[card
]->channel
[arg
].sillist
, num
);
494 pr_debug("%s: Service Indicators for channel %d set: %s\n",
495 adapter
[card
]->devicename
, arg
+1,
496 adapter
[card
]->channel
[arg
].sillist
);
500 int getsil(int card
, unsigned long arg
, char *num
)
502 if(!IS_VALID_CARD(card
)) {
503 pr_debug("Invalid param: %d is not a valid card id\n", card
);
507 strcpy(num
, adapter
[card
]->channel
[arg
].sillist
);
508 pr_debug("%s: SIL for channel %d reported: %s\n",
509 adapter
[card
]->devicename
, arg
+1,
510 adapter
[card
]->channel
[arg
].sillist
);
531 if(!IS_VALID_CARD(card
)) {
532 pr_debug("Invalid param: %d is not a valid card id\n", card
);
536 indicate_status(card
, ISDN_STAT_STOP
, 0, NULL
);
538 if(adapter
[card
]->EngineUp
) {
539 del_timer(&adapter
[card
]->stat_timer
);
542 adapter
[card
]->EngineUp
= 0;
546 init_timer(&adapter
[card
]->reset_timer
);
547 adapter
[card
]->reset_timer
.function
= check_reset
;
548 adapter
[card
]->reset_timer
.data
= card
;
549 adapter
[card
]->reset_timer
.expires
= jiffies
+ CHECKRESET_TIME
;
550 add_timer(&adapter
[card
]->reset_timer
);
551 restore_flags(flags
);
553 outb(0x1,adapter
[card
]->ioport
[SFT_RESET
]);
555 pr_debug("%s: Adapter Reset\n", adapter
[card
]->devicename
);
559 void flushreadfifo (int card
)
561 while(inb(adapter
[card
]->ioport
[FIFO_STATUS
]) & RF_HAS_DATA
)
562 inb(adapter
[card
]->ioport
[FIFO_READ
]);