OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [isdn/] [sc/] [command.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/* $Id: command.c,v 1.4.10.1 2001/09/23 22:24:59 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
 
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
 
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);
33
 
34
#ifdef DEBUG
35
/*
36
 * Translate command codes to strings
37
 */
38
static char *commands[] = { "ISDN_CMD_IOCTL",
39
                            "ISDN_CMD_DIAL",
40
                            "ISDN_CMD_ACCEPTB",
41
                            "ISDN_CMD_ACCEPTB",
42
                            "ISDN_CMD_HANGUP",
43
                            "ISDN_CMD_CLREAZ",
44
                            "ISDN_CMD_SETEAZ",
45
                            NULL,
46
                            NULL,
47
                            NULL,
48
                            "ISDN_CMD_SETL2",
49
                            NULL,
50
                            "ISDN_CMD_SETL3",
51
                            NULL,
52
                            NULL,
53
                            NULL,
54
                            NULL,
55
                            NULL, };
56
 
57
/*
58
 * Translates ISDN4Linux protocol codes to strings for debug messages
59
 */
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",
64
                            "ISDN_PROTO_L2_HDLC",
65
                            "ISDN_PROTO_L2_TRANS" };
66
#endif
67
 
68
int get_card_from_id(int driver)
69
{
70
        int i;
71
 
72
        for(i = 0 ; i < cinst ; i++) {
73
                if(sc_adapter[i]->driverId == driver)
74
                        return i;
75
        }
76
        return -ENODEV;
77
}
78
 
79
/*
80
 * command
81
 */
82
 
83
int command(isdn_ctrl *cmd)
84
{
85
        int card;
86
 
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);
90
                return -ENODEV;
91
        }
92
 
93
        /*
94
         * Dispatch the command
95
         */
96
        switch(cmd->command) {
97
        case ISDN_CMD_IOCTL:
98
        {
99
                unsigned long   cmdptr;
100
                scs_ioctl       ioc;
101
 
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);
107
                        return -EFAULT;
108
                }
109
                return sc_ioctl(card, &ioc);
110
        }
111
        case ISDN_CMD_DIAL:
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);
123
        case ISDN_CMD_SETL2:
124
                return setl2(card, cmd->arg);
125
        case ISDN_CMD_SETL3:
126
                return setl3(card, cmd->arg);
127
        default:
128
                return -EINVAL;
129
        }
130
        return 0;
131
}
132
 
133
/*
134
 * start the onboard firmware
135
 */
136
int startproc(int card)
137
{
138
        int status;
139
 
140
        if(!IS_VALID_CARD(card)) {
141
                pr_debug("Invalid param: %d is not a valid card id\n", card);
142
                return -ENODEV;
143
        }
144
 
145
        /*
146
         * send start msg
147
         */
148
        status = sendmessage(card, CMPID,cmReqType2,
149
                          cmReqClass0,
150
                          cmReqStartProc,
151
                          0,0,NULL);
152
        pr_debug("%s: Sent startProc\n", sc_adapter[card]->devicename);
153
 
154
        return status;
155
}
156
 
157
 
158
/*
159
 * Dials the number passed in
160
 */
161
static int dial(int card, unsigned long channel, setup_parm setup)
162
{
163
        int status;
164
        char Phone[48];
165
 
166
        if(!IS_VALID_CARD(card)) {
167
                pr_debug("Invalid param: %d is not a valid card id\n", card);
168
                return -ENODEV;
169
        }
170
 
171
        /*extract ISDN number to dial from eaz/msn string*/
172
        strcpy(Phone,setup.phone);
173
 
174
        /*send the connection message*/
175
        status = sendmessage(card, CEPID,ceReqTypePhy,
176
                                ceReqClass1,
177
                                ceReqPhyConnect,
178
                                (unsigned char) channel+1,
179
                                strlen(Phone),
180
                                (unsigned int *) Phone);
181
 
182
        pr_debug("%s: Dialing %s on channel %lu\n",
183
                sc_adapter[card]->devicename, Phone, channel+1);
184
 
185
        return status;
186
}
187
 
188
/*
189
 * Answer an incoming call
190
 */
191
static int answer(int card, unsigned long channel)
192
{
193
        if(!IS_VALID_CARD(card)) {
194
                pr_debug("Invalid param: %d is not a valid card id\n", card);
195
                return -ENODEV;
196
        }
197
 
198
        if(setup_buffers(card, channel+1)) {
199
                hangup(card, channel+1);
200
                return -ENOBUFS;
201
        }
202
 
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);
206
        return 0;
207
}
208
 
209
/*
210
 * Hangup up the call on specified channel
211
 */
212
static int hangup(int card, unsigned long channel)
213
{
214
        int status;
215
 
216
        if(!IS_VALID_CARD(card)) {
217
                pr_debug("Invalid param: %d is not a valid card id\n", card);
218
                return -ENODEV;
219
        }
220
 
221
        status = sendmessage(card, CEPID, ceReqTypePhy,
222
                                                 ceReqClass1,
223
                                                 ceReqPhyDisconnect,
224
                                                 (unsigned char) channel+1,
225
                                                 0,
226
                                                 NULL);
227
        pr_debug("%s: Sent HANGUP message to channel %lu\n",
228
                sc_adapter[card]->devicename, channel+1);
229
        return status;
230
}
231
 
232
/*
233
 * Set the layer 2 protocol (X.25, HDLC, Raw)
234
 */
235
static int setl2(int card, unsigned long arg)
236
{
237
        int status =0;
238
        int protocol,channel;
239
 
240
        if(!IS_VALID_CARD(card)) {
241
                pr_debug("Invalid param: %d is not a valid card id\n", card);
242
                return -ENODEV;
243
        }
244
        protocol = arg >> 8;
245
        channel = arg & 0xff;
246
        sc_adapter[card]->channel[channel].l2_proto = protocol;
247
 
248
        /*
249
         * check that the adapter is also set to the correct protocol
250
         */
251
        pr_debug("%s: Sending GetFrameFormat for channel %d\n",
252
                sc_adapter[card]->devicename, channel+1);
253
        status = sendmessage(card, CEPID, ceReqTypeCall,
254
                                ceReqClass0,
255
                                ceReqCallGetFrameFormat,
256
                                (unsigned char)channel+1,
257
                                1,
258
                                (unsigned int *) protocol);
259
        if(status)
260
                return status;
261
        return 0;
262
}
263
 
264
/*
265
 * Set the layer 3 protocol
266
 */
267
static int setl3(int card, unsigned long channel)
268
{
269
        int protocol = channel >> 8;
270
 
271
        if(!IS_VALID_CARD(card)) {
272
                pr_debug("Invalid param: %d is not a valid card id\n", card);
273
                return -ENODEV;
274
        }
275
 
276
        sc_adapter[card]->channel[channel].l3_proto = protocol;
277
        return 0;
278
}
279
 
280
static int acceptb(int card, unsigned long channel)
281
{
282
        if(!IS_VALID_CARD(card)) {
283
                pr_debug("Invalid param: %d is not a valid card id\n", card);
284
                return -ENODEV;
285
        }
286
 
287
        if(setup_buffers(card, channel+1))
288
        {
289
                hangup(card, channel+1);
290
                return -ENOBUFS;
291
        }
292
 
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);
296
        return 0;
297
}
298
 
299
static int clreaz(int card, unsigned long arg)
300
{
301
        if(!IS_VALID_CARD(card)) {
302
                pr_debug("Invalid param: %d is not a valid card id\n", card);
303
                return -ENODEV;
304
        }
305
 
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);
310
        return 0;
311
}
312
 
313
static int seteaz(int card, unsigned long arg, char *num)
314
{
315
        if(!IS_VALID_CARD(card)) {
316
                pr_debug("Invalid param: %d is not a valid card id\n", card);
317
                return -ENODEV;
318
        }
319
 
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);
325
        return 0;
326
}
327
 
328
int reset(int card)
329
{
330
        unsigned long flags;
331
 
332
        if(!IS_VALID_CARD(card)) {
333
                pr_debug("Invalid param: %d is not a valid card id\n", card);
334
                return -ENODEV;
335
        }
336
 
337
        indicate_status(card, ISDN_STAT_STOP, 0, NULL);
338
 
339
        if(sc_adapter[card]->EngineUp) {
340
                del_timer(&sc_adapter[card]->stat_timer);
341
        }
342
 
343
        sc_adapter[card]->EngineUp = 0;
344
 
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);
352
 
353
        outb(0x1,sc_adapter[card]->ioport[SFT_RESET]);
354
 
355
        pr_debug("%s: Adapter Reset\n", sc_adapter[card]->devicename);
356
        return 0;
357
}
358
 
359
void flushreadfifo (int card)
360
{
361
        while(inb(sc_adapter[card]->ioport[FIFO_STATUS]) & RF_HAS_DATA)
362
                inb(sc_adapter[card]->ioport[FIFO_READ]);
363
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.