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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [isdn/] [sc/] [command.c] - Blame information for rev 199

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 *  $Id: command.c,v 1.1.1.1 2001-09-10 07:44:19 simons Exp $
3
 *  Copyright (C) 1996  SpellCaster Telecommunications Inc.
4
 *
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.
9
 *
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.
14
 *
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.
18
 *
19
 *  For more information, please contact gpl-info@spellcast.com or write:
20
 *
21
 *     SpellCaster Telecommunications Inc.
22
 *     5621 Finch Avenue East, Unit #3
23
 *     Scarborough, Ontario  Canada
24
 *     M1B 2T9
25
 *     +1 (416) 297-8565
26
 *     +1 (416) 297-6433 Facsimile
27
 */
28
 
29
#define __NO_VERSION__
30
#include "includes.h"           /* This must be first */
31
#include "hardware.h"
32
#include "message.h"
33
#include "card.h"
34
#include "scioc.h"
35
 
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);
48
int lock(void);
49
int unlock(void);
50
int acceptb(int card, unsigned long channel);
51
 
52
extern int cinst;
53
extern board *adapter[];
54
 
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 *,
61
                RspMessage *, int);
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 *);
65
 
66
#ifdef DEBUG
67
/*
68
 * Translate command codes to strings
69
 */
70
static char *commands[] = { "ISDN_CMD_IOCTL",
71
                            "ISDN_CMD_DIAL",
72
                            "ISDN_CMD_ACCEPTB",
73
                            "ISDN_CMD_ACCEPTB",
74
                            "ISDN_CMD_HANGUP",
75
                            "ISDN_CMD_CLREAZ",
76
                            "ISDN_CMD_SETEAZ",
77
                            "ISDN_CMD_GETEAZ",
78
                            "ISDN_CMD_SETSIL",
79
                            "ISDN_CMD_GETSIL",
80
                            "ISDN_CMD_SETL2",
81
                            "ISDN_CMD_GETL2",
82
                            "ISDN_CMD_SETL3",
83
                            "ISDN_CMD_GETL3",
84
                            "ISDN_CMD_LOCK",
85
                            "ISDN_CMD_UNLOCK",
86
                            "ISDN_CMD_SUSPEND",
87
                            "ISDN_CMD_RESUME" };
88
 
89
/*
90
 * Translates ISDN4Linux protocol codes to strings for debug messages
91
 */
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",
96
                            "ISDN_PROTO_L2_HDLC",
97
                            "ISDN_PROTO_L2_TRANS" };
98
#endif
99
 
100
int get_card_from_id(int driver)
101
{
102
        int i;
103
 
104
        for(i = 0 ; i < cinst ; i++) {
105
                if(adapter[i]->driverId == driver)
106
                        return i;
107
        }
108
        return -NODEV;
109
}
110
 
111
/*
112
 * command
113
 */
114
 
115
int command(isdn_ctrl *cmd)
116
{
117
        int card;
118
 
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);
122
                return -ENODEV;
123
        }
124
 
125
        pr_debug("%s: Received %s command from Link Layer\n",
126
                adapter[card]->devicename, commands[cmd->command]);
127
 
128
        /*
129
         * Dispatch the command
130
         */
131
        switch(cmd->command) {
132
        case ISDN_CMD_IOCTL:
133
        {
134
                unsigned long   cmdptr;
135
                scs_ioctl       ioc;
136
                int             err;
137
 
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);
143
                        return err;
144
                }
145
                return sc_ioctl(card, &ioc);
146
        }
147
        case ISDN_CMD_DIAL:
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);
165
        case ISDN_CMD_SETL2:
166
                return setl2(card, cmd->arg);
167
        case ISDN_CMD_GETL2:
168
                return getl2(card, cmd->arg);
169
        case ISDN_CMD_SETL3:
170
                return setl3(card, cmd->arg);
171
        case ISDN_CMD_GETL3:
172
                return getl3(card, cmd->arg);
173
        case ISDN_CMD_LOCK:
174
                return lock();
175
        case ISDN_CMD_UNLOCK:
176
                return unlock();
177
        default:
178
                return -EINVAL;
179
        }
180
        return 0;
181
}
182
 
183
/*
184
 * Confirm our ability to communicate with the board.  This test assumes no
185
 * other message activity is present
186
 */
187
int loopback(int card)
188
{
189
 
190
        int status;
191
        static char testmsg[] = "Test Message";
192
        RspMessage rspmsg;
193
 
194
        if(!IS_VALID_CARD(card)) {
195
                pr_debug("Invalid param: %d is not a valid card id\n", card);
196
                return -ENODEV;
197
        }
198
 
199
        pr_debug("%s: Sending loopback message\n", adapter[card]->devicename);
200
 
201
 
202
        /*
203
         * Send the loopback message to confirm that memory transfer is
204
         * operational
205
         */
206
        status = send_and_receive(card, CMPID, cmReqType1,
207
                                  cmReqClass0,
208
                                  cmReqMsgLpbk,
209
                                  0,
210
                                  (unsigned char) strlen(testmsg),
211
                                  (unsigned char *)testmsg,
212
                                  &rspmsg, SAR_TIMEOUT);
213
 
214
 
215
        if (!status) {
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);
221
                        return -EIO;
222
                }
223
                return 0;
224
        }
225
        else {
226
                pr_debug("%s: Send loopback message failed\n",
227
                        adapter[card]->devicename);
228
                return -EIO;
229
        }
230
 
231
}
232
 
233
/*
234
 * start the onboard firmware
235
 */
236
int startproc(int card)
237
{
238
        int status;
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
 
245
        /*
246
         * send start msg
247
         */
248
        status = sendmessage(card, CMPID,cmReqType2,
249
                          cmReqClass0,
250
                          cmReqStartProc,
251
                          0,0,0);
252
        pr_debug("%s: Sent startProc\n", adapter[card]->devicename);
253
 
254
        return status;
255
}
256
 
257
 
258
int loadproc(int card, char *data)
259
{
260
        return -1;
261
}
262
 
263
 
264
/*
265
 * Dials the number passed in
266
 */
267
int dial(int card, unsigned long channel, setup_parm setup)
268
{
269
        int status;
270
        char Phone[48];
271
 
272
        if(!IS_VALID_CARD(card)) {
273
                pr_debug("Invalid param: %d is not a valid card id\n", card);
274
                return -ENODEV;
275
        }
276
 
277
        /*extract ISDN number to dial from eaz/msn string*/
278
        strcpy(Phone,setup.phone);
279
 
280
        /*send the connection message*/
281
        status = sendmessage(card, CEPID,ceReqTypePhy,
282
                                ceReqClass1,
283
                                ceReqPhyConnect,
284
                                (unsigned char) channel+1,
285
                                strlen(Phone),
286
                                (unsigned int *) Phone);
287
 
288
        pr_debug("%s: Dialing %s on channel %d\n",
289
                adapter[card]->devicename, Phone, channel+1);
290
 
291
        return status;
292
}
293
 
294
/*
295
 * Answer an incoming call
296
 */
297
int answer(int card, unsigned long channel)
298
{
299
        if(!IS_VALID_CARD(card)) {
300
                pr_debug("Invalid param: %d is not a valid card id\n", card);
301
                return -ENODEV;
302
        }
303
 
304
        if(setup_buffers(card, channel+1, BUFFER_SIZE)) {
305
                hangup(card, channel+1);
306
                return -ENOBUFS;
307
        }
308
 
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);
312
        return 0;
313
}
314
 
315
/*
316
 * Hangup up the call on specified channel
317
 */
318
int hangup(int card, unsigned long channel)
319
{
320
        int status;
321
 
322
        if(!IS_VALID_CARD(card)) {
323
                pr_debug("Invalid param: %d is not a valid card id\n", card);
324
                return -ENODEV;
325
        }
326
 
327
        status = sendmessage(card, CEPID, ceReqTypePhy,
328
                                                 ceReqClass1,
329
                                                 ceReqPhyDisconnect,
330
                                                 (unsigned char) channel+1,
331
                                                 0,
332
                                                 NULL);
333
        pr_debug("%s: Sent HANGUP message to channel %d\n",
334
                adapter[card]->devicename, channel+1);
335
        return status;
336
}
337
 
338
/*
339
 * Set the layer 2 protocol (X.25, HDLC, Raw)
340
 */
341
int setl2(int card, unsigned long arg)
342
{
343
        int status =0;
344
        int protocol,channel;
345
 
346
        if(!IS_VALID_CARD(card)) {
347
                pr_debug("Invalid param: %d is not a valid card id\n", card);
348
                return -ENODEV;
349
        }
350
        protocol = arg >> 8;
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);
355
 
356
        /*
357
         * check that the adapter is also set to the correct protocol
358
         */
359
        pr_debug("%s: Sending GetFrameFormat for channel %d\n",
360
                adapter[card]->devicename, channel+1);
361
        status = sendmessage(card, CEPID, ceReqTypeCall,
362
                                ceReqClass0,
363
                                ceReqCallGetFrameFormat,
364
                                (unsigned char)channel+1,
365
                                1,
366
                                (unsigned int *) protocol);
367
        if(status)
368
                return status;
369
        return 0;
370
}
371
 
372
/*
373
 * Get the layer 2 protocol
374
 */
375
int getl2(int card, unsigned long channel) {
376
 
377
        if(!IS_VALID_CARD(card)) {
378
                pr_debug("Invalid param: %d is not a valid card id\n", card);
379
                return -ENODEV;
380
        }
381
 
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]);
385
 
386
        return adapter[card]->channel[channel].l2_proto;
387
}
388
 
389
/*
390
 * Set the layer 3 protocol
391
 */
392
int setl3(int card, unsigned long channel)
393
{
394
        int protocol = channel >> 8;
395
 
396
        if(!IS_VALID_CARD(card)) {
397
                pr_debug("Invalid param: %d is not a valid card id\n", card);
398
                return -ENODEV;
399
        }
400
 
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]);
404
        return 0;
405
}
406
 
407
/*
408
 * Get the layer 3 protocol
409
 */
410
int getl3(int card, unsigned long arg)
411
{
412
        if(!IS_VALID_CARD(card)) {
413
                pr_debug("Invalid param: %d is not a valid card id\n", card);
414
                return -ENODEV;
415
        }
416
 
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;
421
}
422
 
423
 
424
int acceptb(int card, unsigned long channel)
425
{
426
        if(!IS_VALID_CARD(card)) {
427
                pr_debug("Invalid param: %d is not a valid card id\n", card);
428
                return -ENODEV;
429
        }
430
 
431
        if(setup_buffers(card, channel+1, BUFFER_SIZE))
432
        {
433
                hangup(card, channel+1);
434
                return -ENOBUFS;
435
        }
436
 
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);
440
        return 0;
441
}
442
 
443
int clreaz(int card, unsigned long arg)
444
{
445
        if(!IS_VALID_CARD(card)) {
446
                pr_debug("Invalid param: %d is not a valid card id\n", card);
447
                return -ENODEV;
448
        }
449
 
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);
454
        return 0;
455
}
456
 
457
int seteaz(int card, unsigned long arg, char *num)
458
{
459
        if(!IS_VALID_CARD(card)) {
460
                pr_debug("Invalid param: %d is not a valid card id\n", card);
461
                return -ENODEV;
462
        }
463
 
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);
469
        return 0;
470
}
471
 
472
int geteaz(int card, unsigned long arg, char *num)
473
{
474
        if(!IS_VALID_CARD(card)) {
475
                pr_debug("Invalid param: %d is not a valid card id\n", card);
476
                return -ENODEV;
477
        }
478
 
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);
483
        return 0;
484
}
485
 
486
int setsil(int card, unsigned long arg, char *num)
487
{
488
        if(!IS_VALID_CARD(card)) {
489
                pr_debug("Invalid param: %d is not a valid card id\n", card);
490
                return -ENODEV;
491
        }
492
 
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);
497
        return 0;
498
}
499
 
500
int getsil(int card, unsigned long arg, char *num)
501
{
502
        if(!IS_VALID_CARD(card)) {
503
                pr_debug("Invalid param: %d is not a valid card id\n", card);
504
                return -ENODEV;
505
        }
506
 
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);
511
        return 0;
512
}
513
 
514
 
515
int lock()
516
{
517
        MOD_INC_USE_COUNT;
518
        return 0;
519
}
520
 
521
int unlock()
522
{
523
        MOD_DEC_USE_COUNT;
524
        return 0;
525
}
526
 
527
int reset(int card)
528
{
529
        unsigned long flags;
530
 
531
        if(!IS_VALID_CARD(card)) {
532
                pr_debug("Invalid param: %d is not a valid card id\n", card);
533
                return -ENODEV;
534
        }
535
 
536
        indicate_status(card, ISDN_STAT_STOP, 0, NULL);
537
 
538
        if(adapter[card]->EngineUp) {
539
                del_timer(&adapter[card]->stat_timer);
540
        }
541
 
542
        adapter[card]->EngineUp = 0;
543
 
544
        save_flags(flags);
545
        cli();
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);
552
 
553
        outb(0x1,adapter[card]->ioport[SFT_RESET]);
554
 
555
        pr_debug("%s: Adapter Reset\n", adapter[card]->devicename);
556
        return 0;
557
}
558
 
559
void flushreadfifo (int card)
560
{
561
        while(inb(adapter[card]->ioport[FIFO_STATUS]) & RF_HAS_DATA)
562
                inb(adapter[card]->ioport[FIFO_READ]);
563
}

powered by: WebSVN 2.1.0

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