2 * Copyright (C) 1996 SpellCaster Telecommunications Inc.
4 * This software may be used and distributed according to the terms
5 * of the GNU General Public License, incorporated herein by reference.
15 extern int indicate_status(int, int, unsigned long, char *);
16 extern int startproc(int);
17 extern int loadproc(int, char *record
);
18 extern int reset(int);
19 extern int send_and_receive(int, unsigned int, unsigned char,unsigned char,
20 unsigned char,unsigned char,
21 unsigned char, unsigned char *, RspMessage
*, int);
23 extern board
*sc_adapter
[];
26 int GetStatus(int card
, boardInfo
*);
29 * Process private IOCTL messages (typically from scctrl)
31 int sc_ioctl(int card
, scs_ioctl
*data
)
40 rcvmsg
= kmalloc(sizeof(RspMessage
), GFP_KERNEL
);
44 switch(data
->command
) {
45 case SCIOCRESET
: /* Perform a hard reset of the adapter */
47 pr_debug("%s: SCIOCRESET: ioctl received\n",
48 sc_adapter
[card
]->devicename
);
49 sc_adapter
[card
]->StartOnReset
= 0;
57 srec
= kmalloc(SCIOC_SRECSIZE
, GFP_KERNEL
);
62 pr_debug("%s: SCIOLOAD: ioctl received\n",
63 sc_adapter
[card
]->devicename
);
64 if(sc_adapter
[card
]->EngineUp
) {
65 pr_debug("%s: SCIOCLOAD: command failed, LoadProc while engine running.\n",
66 sc_adapter
[card
]->devicename
);
73 * Get the SRec from user space
75 if (copy_from_user(srec
, data
->dataptr
, sizeof(srec
))) {
81 status
= send_and_receive(card
, CMPID
, cmReqType2
, cmReqClass0
, cmReqLoadProc
,
82 0, sizeof(srec
), srec
, rcvmsg
, SAR_TIMEOUT
);
87 pr_debug("%s: SCIOCLOAD: command failed, status = %d\n",
88 sc_adapter
[card
]->devicename
, status
);
92 pr_debug("%s: SCIOCLOAD: command successful\n",
93 sc_adapter
[card
]->devicename
);
100 pr_debug("%s: SCIOSTART: ioctl received\n",
101 sc_adapter
[card
]->devicename
);
102 if(sc_adapter
[card
]->EngineUp
) {
103 pr_debug("%s: SCIOCSTART: command failed, engine already running.\n",
104 sc_adapter
[card
]->devicename
);
108 sc_adapter
[card
]->StartOnReset
= 1;
115 pr_debug("%s: SCIOSETSWITCH: ioctl received\n",
116 sc_adapter
[card
]->devicename
);
119 * Get the switch type from user space
121 if (copy_from_user(&switchtype
, data
->dataptr
, sizeof(char))) {
126 pr_debug("%s: SCIOCSETSWITCH: setting switch type to %d\n",
127 sc_adapter
[card
]->devicename
,
129 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
, ceReqCallSetSwitchType
,
130 0, sizeof(char),&switchtype
, rcvmsg
, SAR_TIMEOUT
);
131 if(!status
&& !(rcvmsg
->rsp_status
)) {
132 pr_debug("%s: SCIOCSETSWITCH: command successful\n",
133 sc_adapter
[card
]->devicename
);
138 pr_debug("%s: SCIOCSETSWITCH: command failed (status = %d)\n",
139 sc_adapter
[card
]->devicename
, status
);
147 pr_debug("%s: SCIOGETSWITCH: ioctl received\n",
148 sc_adapter
[card
]->devicename
);
151 * Get the switch type from the board
153 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
,
154 ceReqCallGetSwitchType
, 0, 0, NULL
, rcvmsg
, SAR_TIMEOUT
);
155 if (!status
&& !(rcvmsg
->rsp_status
)) {
156 pr_debug("%s: SCIOCGETSWITCH: command successful\n",
157 sc_adapter
[card
]->devicename
);
160 pr_debug("%s: SCIOCGETSWITCH: command failed (status = %d)\n",
161 sc_adapter
[card
]->devicename
, status
);
166 switchtype
= rcvmsg
->msg_data
.byte_array
[0];
169 * Package the switch type and send to user space
171 if (copy_to_user(data
->dataptr
, &switchtype
,
183 pr_debug("%s: SCIOGETSPID: ioctl received\n",
184 sc_adapter
[card
]->devicename
);
186 spid
= kmalloc(SCIOC_SPIDSIZE
, GFP_KERNEL
);
192 * Get the spid from the board
194 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
, ceReqCallGetSPID
,
195 data
->channel
, 0, NULL
, rcvmsg
, SAR_TIMEOUT
);
197 pr_debug("%s: SCIOCGETSPID: command successful\n",
198 sc_adapter
[card
]->devicename
);
201 pr_debug("%s: SCIOCGETSPID: command failed (status = %d)\n",
202 sc_adapter
[card
]->devicename
, status
);
206 strcpy(spid
, rcvmsg
->msg_data
.byte_array
);
209 * Package the switch type and send to user space
211 if (copy_to_user(data
->dataptr
, spid
, SCIOC_SPIDSIZE
)) {
224 pr_debug("%s: DCBIOSETSPID: ioctl received\n",
225 sc_adapter
[card
]->devicename
);
227 spid
= kmalloc(SCIOC_SPIDSIZE
, GFP_KERNEL
);
234 * Get the spid from user space
236 if (copy_from_user(spid
, data
->dataptr
, SCIOC_SPIDSIZE
)) {
241 pr_debug("%s: SCIOCSETSPID: setting channel %d spid to %s\n",
242 sc_adapter
[card
]->devicename
, data
->channel
, spid
);
243 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
,
244 ceReqClass0
, ceReqCallSetSPID
, data
->channel
,
245 strlen(spid
), spid
, rcvmsg
, SAR_TIMEOUT
);
246 if(!status
&& !(rcvmsg
->rsp_status
)) {
247 pr_debug("%s: SCIOCSETSPID: command successful\n",
248 sc_adapter
[card
]->devicename
);
254 pr_debug("%s: SCIOCSETSPID: command failed (status = %d)\n",
255 sc_adapter
[card
]->devicename
, status
);
264 pr_debug("%s: SCIOGETDN: ioctl received\n",
265 sc_adapter
[card
]->devicename
);
268 * Get the dn from the board
270 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
, ceReqCallGetMyNumber
,
271 data
->channel
, 0, NULL
, rcvmsg
, SAR_TIMEOUT
);
273 pr_debug("%s: SCIOCGETDN: command successful\n",
274 sc_adapter
[card
]->devicename
);
277 pr_debug("%s: SCIOCGETDN: command failed (status = %d)\n",
278 sc_adapter
[card
]->devicename
, status
);
283 dn
= kmalloc(SCIOC_DNSIZE
, GFP_KERNEL
);
288 strcpy(dn
, rcvmsg
->msg_data
.byte_array
);
292 * Package the dn and send to user space
294 if (copy_to_user(data
->dataptr
, dn
, SCIOC_DNSIZE
)) {
304 pr_debug("%s: SCIOSETDN: ioctl received\n",
305 sc_adapter
[card
]->devicename
);
307 dn
= kmalloc(SCIOC_DNSIZE
, GFP_KERNEL
);
313 * Get the spid from user space
315 if (copy_from_user(dn
, data
->dataptr
, SCIOC_DNSIZE
)) {
321 pr_debug("%s: SCIOCSETDN: setting channel %d dn to %s\n",
322 sc_adapter
[card
]->devicename
, data
->channel
, dn
);
323 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
,
324 ceReqClass0
, ceReqCallSetMyNumber
, data
->channel
,
325 strlen(dn
),dn
,rcvmsg
, SAR_TIMEOUT
);
326 if(!status
&& !(rcvmsg
->rsp_status
)) {
327 pr_debug("%s: SCIOCSETDN: command successful\n",
328 sc_adapter
[card
]->devicename
);
334 pr_debug("%s: SCIOCSETDN: command failed (status = %d)\n",
335 sc_adapter
[card
]->devicename
, status
);
344 pr_debug("%s: SCIOTRACE: ioctl received\n",
345 sc_adapter
[card
]->devicename
);
346 /* sc_adapter[card]->trace = !sc_adapter[card]->trace;
347 pr_debug("%s: SCIOCTRACE: tracing turned %s\n",
348 sc_adapter[card]->devicename,
349 sc_adapter[card]->trace ? "ON" : "OFF"); */
356 pr_debug("%s: SCIOSTAT: ioctl received\n",
357 sc_adapter
[card
]->devicename
);
359 bi
= kmalloc (sizeof(boardInfo
), GFP_KERNEL
);
368 if (copy_to_user(data
->dataptr
, bi
, sizeof(boardInfo
))) {
379 pr_debug("%s: SCIOGETSPEED: ioctl received\n",
380 sc_adapter
[card
]->devicename
);
383 * Get the speed from the board
385 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
,
386 ceReqCallGetCallType
, data
->channel
, 0, NULL
, rcvmsg
, SAR_TIMEOUT
);
387 if (!status
&& !(rcvmsg
->rsp_status
)) {
388 pr_debug("%s: SCIOCGETSPEED: command successful\n",
389 sc_adapter
[card
]->devicename
);
392 pr_debug("%s: SCIOCGETSPEED: command failed (status = %d)\n",
393 sc_adapter
[card
]->devicename
, status
);
398 speed
= rcvmsg
->msg_data
.byte_array
[0];
403 * Package the switch type and send to user space
406 if (copy_to_user(data
->dataptr
, &speed
, sizeof(char)))
413 pr_debug("%s: SCIOCSETSPEED: ioctl received\n",
414 sc_adapter
[card
]->devicename
);
418 pr_debug("%s: SCIOCLOOPTST: ioctl received\n",
419 sc_adapter
[card
]->devicename
);
431 int GetStatus(int card
, boardInfo
*bi
)
437 * Fill in some of the basic info about the board
439 bi
->modelid
= sc_adapter
[card
]->model
;
440 strcpy(bi
->serial_no
, sc_adapter
[card
]->hwconfig
.serial_no
);
441 strcpy(bi
->part_no
, sc_adapter
[card
]->hwconfig
.part_no
);
442 bi
->iobase
= sc_adapter
[card
]->iobase
;
443 bi
->rambase
= sc_adapter
[card
]->rambase
;
444 bi
->irq
= sc_adapter
[card
]->interrupt
;
445 bi
->ramsize
= sc_adapter
[card
]->hwconfig
.ram_size
;
446 bi
->interface
= sc_adapter
[card
]->hwconfig
.st_u_sense
;
447 strcpy(bi
->load_ver
, sc_adapter
[card
]->load_ver
);
448 strcpy(bi
->proc_ver
, sc_adapter
[card
]->proc_ver
);
451 * Get the current PhyStats and LnkStats
453 status
= send_and_receive(card
, CEPID
, ceReqTypePhy
, ceReqClass2
,
454 ceReqPhyStatus
, 0, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
456 if(sc_adapter
[card
]->model
< PRI_BOARD
) {
457 bi
->l1_status
= rcvmsg
.msg_data
.byte_array
[2];
458 for(i
= 0 ; i
< BRI_CHANNELS
; i
++)
459 bi
->status
.bristats
[i
].phy_stat
=
460 rcvmsg
.msg_data
.byte_array
[i
];
463 bi
->l1_status
= rcvmsg
.msg_data
.byte_array
[0];
464 bi
->l2_status
= rcvmsg
.msg_data
.byte_array
[1];
465 for(i
= 0 ; i
< PRI_CHANNELS
; i
++)
466 bi
->status
.pristats
[i
].phy_stat
=
467 rcvmsg
.msg_data
.byte_array
[i
+2];
472 * Get the call types for each channel
474 for (i
= 0 ; i
< sc_adapter
[card
]->nChannels
; i
++) {
475 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
,
476 ceReqCallGetCallType
, 0, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
478 if (sc_adapter
[card
]->model
== PRI_BOARD
) {
479 bi
->status
.pristats
[i
].call_type
=
480 rcvmsg
.msg_data
.byte_array
[0];
483 bi
->status
.bristats
[i
].call_type
=
484 rcvmsg
.msg_data
.byte_array
[0];
490 * If PRI, get the call states and service states for each channel
492 if (sc_adapter
[card
]->model
== PRI_BOARD
) {
494 * Get the call states
496 status
= send_and_receive(card
, CEPID
, ceReqTypeStat
, ceReqClass2
,
497 ceReqPhyChCallState
, 0, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
499 for( i
= 0 ; i
< PRI_CHANNELS
; i
++ )
500 bi
->status
.pristats
[i
].call_state
=
501 rcvmsg
.msg_data
.byte_array
[i
];
505 * Get the service states
507 status
= send_and_receive(card
, CEPID
, ceReqTypeStat
, ceReqClass2
,
508 ceReqPhyChServState
, 0, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
510 for( i
= 0 ; i
< PRI_CHANNELS
; i
++ )
511 bi
->status
.pristats
[i
].serv_state
=
512 rcvmsg
.msg_data
.byte_array
[i
];
516 * Get the link stats for the channels
518 for (i
= 1 ; i
<= PRI_CHANNELS
; i
++) {
519 status
= send_and_receive(card
, CEPID
, ceReqTypeLnk
, ceReqClass0
,
520 ceReqLnkGetStats
, i
, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
522 bi
->status
.pristats
[i
-1].link_stats
.tx_good
=
523 (unsigned long)rcvmsg
.msg_data
.byte_array
[0];
524 bi
->status
.pristats
[i
-1].link_stats
.tx_bad
=
525 (unsigned long)rcvmsg
.msg_data
.byte_array
[4];
526 bi
->status
.pristats
[i
-1].link_stats
.rx_good
=
527 (unsigned long)rcvmsg
.msg_data
.byte_array
[8];
528 bi
->status
.pristats
[i
-1].link_stats
.rx_bad
=
529 (unsigned long)rcvmsg
.msg_data
.byte_array
[12];
534 * Link stats for the D channel
536 status
= send_and_receive(card
, CEPID
, ceReqTypeLnk
, ceReqClass0
,
537 ceReqLnkGetStats
, 0, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
539 bi
->dch_stats
.tx_good
= (unsigned long)rcvmsg
.msg_data
.byte_array
[0];
540 bi
->dch_stats
.tx_bad
= (unsigned long)rcvmsg
.msg_data
.byte_array
[4];
541 bi
->dch_stats
.rx_good
= (unsigned long)rcvmsg
.msg_data
.byte_array
[8];
542 bi
->dch_stats
.rx_bad
= (unsigned long)rcvmsg
.msg_data
.byte_array
[12];
549 * If BRI or POTS, Get SPID, DN and call types for each channel
553 * Get the link stats for the channels
555 status
= send_and_receive(card
, CEPID
, ceReqTypeLnk
, ceReqClass0
,
556 ceReqLnkGetStats
, 0, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
558 bi
->dch_stats
.tx_good
= (unsigned long)rcvmsg
.msg_data
.byte_array
[0];
559 bi
->dch_stats
.tx_bad
= (unsigned long)rcvmsg
.msg_data
.byte_array
[4];
560 bi
->dch_stats
.rx_good
= (unsigned long)rcvmsg
.msg_data
.byte_array
[8];
561 bi
->dch_stats
.rx_bad
= (unsigned long)rcvmsg
.msg_data
.byte_array
[12];
562 bi
->status
.bristats
[0].link_stats
.tx_good
=
563 (unsigned long)rcvmsg
.msg_data
.byte_array
[16];
564 bi
->status
.bristats
[0].link_stats
.tx_bad
=
565 (unsigned long)rcvmsg
.msg_data
.byte_array
[20];
566 bi
->status
.bristats
[0].link_stats
.rx_good
=
567 (unsigned long)rcvmsg
.msg_data
.byte_array
[24];
568 bi
->status
.bristats
[0].link_stats
.rx_bad
=
569 (unsigned long)rcvmsg
.msg_data
.byte_array
[28];
570 bi
->status
.bristats
[1].link_stats
.tx_good
=
571 (unsigned long)rcvmsg
.msg_data
.byte_array
[32];
572 bi
->status
.bristats
[1].link_stats
.tx_bad
=
573 (unsigned long)rcvmsg
.msg_data
.byte_array
[36];
574 bi
->status
.bristats
[1].link_stats
.rx_good
=
575 (unsigned long)rcvmsg
.msg_data
.byte_array
[40];
576 bi
->status
.bristats
[1].link_stats
.rx_bad
=
577 (unsigned long)rcvmsg
.msg_data
.byte_array
[44];
583 for (i
= 0 ; i
< BRI_CHANNELS
; i
++) {
584 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
,
585 ceReqCallGetSPID
, i
+1, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
587 strcpy(bi
->status
.bristats
[i
].spid
, rcvmsg
.msg_data
.byte_array
);
593 for (i
= 0 ; i
< BRI_CHANNELS
; i
++) {
594 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
,
595 ceReqCallGetMyNumber
, i
+1, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
597 strcpy(bi
->status
.bristats
[i
].dn
, rcvmsg
.msg_data
.byte_array
);