1 /* $Id: command.c,v 1.4.10.1 2001/09/23 22:24:59 kai Exp $
3 * Copyright (C) 1996 SpellCaster Telecommunications Inc.
5 * This software may be used and distributed according to the terms
6 * of the GNU General Public License, incorporated herein by reference.
8 * For more information, please contact gpl-info@spellcast.com or write:
10 * SpellCaster Telecommunications Inc.
11 * 5621 Finch Avenue East, Unit #3
12 * Scarborough, Ontario Canada
15 * +1 (416) 297-6433 Facsimile
18 #include <linux/module.h>
19 #include "includes.h" /* This must be first */
25 static int dial(int card
, unsigned long channel
, setup_parm setup
);
26 static int hangup(int card
, unsigned long channel
);
27 static int answer(int card
, unsigned long channel
);
28 static int clreaz(int card
, unsigned long channel
);
29 static int seteaz(int card
, unsigned long channel
, char *);
30 static int setl2(int card
, unsigned long arg
);
31 static int setl3(int card
, unsigned long arg
);
32 static int acceptb(int card
, unsigned long channel
);
36 * Translate command codes to strings
38 static char *commands
[] = { "ISDN_CMD_IOCTL",
58 * Translates ISDN4Linux protocol codes to strings for debug messages
60 static char *l3protos
[] = { "ISDN_PROTO_L3_TRANS" };
61 static char *l2protos
[] = { "ISDN_PROTO_L2_X75I",
62 "ISDN_PROTO_L2_X75UI",
63 "ISDN_PROTO_L2_X75BUI",
65 "ISDN_PROTO_L2_TRANS" };
68 int get_card_from_id(int driver
)
72 for (i
= 0; i
< cinst
; i
++) {
73 if (sc_adapter
[i
]->driverId
== driver
)
83 int command(isdn_ctrl
*cmd
)
87 card
= get_card_from_id(cmd
->driver
);
88 if (!IS_VALID_CARD(card
)) {
89 pr_debug("Invalid param: %d is not a valid card id\n", card
);
94 * Dispatch the command
96 switch (cmd
->command
) {
102 memcpy(&cmdptr
, cmd
->parm
.num
, sizeof(unsigned long));
103 if (copy_from_user(&ioc
, (scs_ioctl __user
*)cmdptr
,
104 sizeof(scs_ioctl
))) {
105 pr_debug("%s: Failed to verify user space 0x%lx\n",
106 sc_adapter
[card
]->devicename
, cmdptr
);
109 return sc_ioctl(card
, &ioc
);
112 return dial(card
, cmd
->arg
, cmd
->parm
.setup
);
113 case ISDN_CMD_HANGUP
:
114 return hangup(card
, cmd
->arg
);
115 case ISDN_CMD_ACCEPTD
:
116 return answer(card
, cmd
->arg
);
117 case ISDN_CMD_ACCEPTB
:
118 return acceptb(card
, cmd
->arg
);
119 case ISDN_CMD_CLREAZ
:
120 return clreaz(card
, cmd
->arg
);
121 case ISDN_CMD_SETEAZ
:
122 return seteaz(card
, cmd
->arg
, cmd
->parm
.num
);
124 return setl2(card
, cmd
->arg
);
126 return setl3(card
, cmd
->arg
);
134 * start the onboard firmware
136 int startproc(int card
)
140 if (!IS_VALID_CARD(card
)) {
141 pr_debug("Invalid param: %d is not a valid card id\n", card
);
148 status
= sendmessage(card
, CMPID
, cmReqType2
,
152 pr_debug("%s: Sent startProc\n", sc_adapter
[card
]->devicename
);
159 * Dials the number passed in
161 static int dial(int card
, unsigned long channel
, setup_parm setup
)
166 if (!IS_VALID_CARD(card
)) {
167 pr_debug("Invalid param: %d is not a valid card id\n", card
);
171 /*extract ISDN number to dial from eaz/msn string*/
172 strcpy(Phone
, setup
.phone
);
174 /*send the connection message*/
175 status
= sendmessage(card
, CEPID
, ceReqTypePhy
,
178 (unsigned char)channel
+ 1,
180 (unsigned int *)Phone
);
182 pr_debug("%s: Dialing %s on channel %lu\n",
183 sc_adapter
[card
]->devicename
, Phone
, channel
+ 1);
189 * Answer an incoming call
191 static int answer(int card
, unsigned long channel
)
193 if (!IS_VALID_CARD(card
)) {
194 pr_debug("Invalid param: %d is not a valid card id\n", card
);
198 if (setup_buffers(card
, channel
+ 1)) {
199 hangup(card
, channel
+ 1);
203 indicate_status(card
, ISDN_STAT_BCONN
, channel
, NULL
);
204 pr_debug("%s: Answered incoming call on channel %lu\n",
205 sc_adapter
[card
]->devicename
, channel
+ 1);
210 * Hangup up the call on specified channel
212 static int hangup(int card
, unsigned long channel
)
216 if (!IS_VALID_CARD(card
)) {
217 pr_debug("Invalid param: %d is not a valid card id\n", card
);
221 status
= sendmessage(card
, CEPID
, ceReqTypePhy
,
224 (unsigned char)channel
+ 1,
227 pr_debug("%s: Sent HANGUP message to channel %lu\n",
228 sc_adapter
[card
]->devicename
, channel
+ 1);
233 * Set the layer 2 protocol (X.25, HDLC, Raw)
235 static int setl2(int card
, unsigned long arg
)
238 int protocol
, channel
;
240 if (!IS_VALID_CARD(card
)) {
241 pr_debug("Invalid param: %d is not a valid card id\n", card
);
245 channel
= arg
& 0xff;
246 sc_adapter
[card
]->channel
[channel
].l2_proto
= protocol
;
249 * check that the adapter is also set to the correct protocol
251 pr_debug("%s: Sending GetFrameFormat for channel %d\n",
252 sc_adapter
[card
]->devicename
, channel
+ 1);
253 status
= sendmessage(card
, CEPID
, ceReqTypeCall
,
255 ceReqCallGetFrameFormat
,
256 (unsigned char)channel
+ 1,
258 (unsigned int *)protocol
);
265 * Set the layer 3 protocol
267 static int setl3(int card
, unsigned long channel
)
269 int protocol
= channel
>> 8;
271 if (!IS_VALID_CARD(card
)) {
272 pr_debug("Invalid param: %d is not a valid card id\n", card
);
276 sc_adapter
[card
]->channel
[channel
].l3_proto
= protocol
;
280 static int acceptb(int card
, unsigned long channel
)
282 if (!IS_VALID_CARD(card
)) {
283 pr_debug("Invalid param: %d is not a valid card id\n", card
);
287 if (setup_buffers(card
, channel
+ 1))
289 hangup(card
, channel
+ 1);
293 pr_debug("%s: B-Channel connection accepted on channel %lu\n",
294 sc_adapter
[card
]->devicename
, channel
+ 1);
295 indicate_status(card
, ISDN_STAT_BCONN
, channel
, NULL
);
299 static int clreaz(int card
, unsigned long arg
)
301 if (!IS_VALID_CARD(card
)) {
302 pr_debug("Invalid param: %d is not a valid card id\n", card
);
306 strcpy(sc_adapter
[card
]->channel
[arg
].eazlist
, "");
307 sc_adapter
[card
]->channel
[arg
].eazclear
= 1;
308 pr_debug("%s: EAZ List cleared for channel %lu\n",
309 sc_adapter
[card
]->devicename
, arg
+ 1);
313 static int seteaz(int card
, unsigned long arg
, char *num
)
315 if (!IS_VALID_CARD(card
)) {
316 pr_debug("Invalid param: %d is not a valid card id\n", card
);
320 strcpy(sc_adapter
[card
]->channel
[arg
].eazlist
, num
);
321 sc_adapter
[card
]->channel
[arg
].eazclear
= 0;
322 pr_debug("%s: EAZ list for channel %lu set to: %s\n",
323 sc_adapter
[card
]->devicename
, arg
+ 1,
324 sc_adapter
[card
]->channel
[arg
].eazlist
);
332 if (!IS_VALID_CARD(card
)) {
333 pr_debug("Invalid param: %d is not a valid card id\n", card
);
337 indicate_status(card
, ISDN_STAT_STOP
, 0, NULL
);
339 if (sc_adapter
[card
]->EngineUp
) {
340 del_timer(&sc_adapter
[card
]->stat_timer
);
343 sc_adapter
[card
]->EngineUp
= 0;
345 spin_lock_irqsave(&sc_adapter
[card
]->lock
, flags
);
346 init_timer(&sc_adapter
[card
]->reset_timer
);
347 sc_adapter
[card
]->reset_timer
.function
= sc_check_reset
;
348 sc_adapter
[card
]->reset_timer
.data
= card
;
349 sc_adapter
[card
]->reset_timer
.expires
= jiffies
+ CHECKRESET_TIME
;
350 add_timer(&sc_adapter
[card
]->reset_timer
);
351 spin_unlock_irqrestore(&sc_adapter
[card
]->lock
, flags
);
353 outb(0x1, sc_adapter
[card
]->ioport
[SFT_RESET
]);
355 pr_debug("%s: Adapter Reset\n", sc_adapter
[card
]->devicename
);
359 void flushreadfifo(int card
)
361 while (inb(sc_adapter
[card
]->ioport
[FIFO_STATUS
]) & RF_HAS_DATA
)
362 inb(sc_adapter
[card
]->ioport
[FIFO_READ
]);