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 reset(int);
18 extern int send_and_receive(int, unsigned int, unsigned char,unsigned char,
19 unsigned char,unsigned char,
20 unsigned char, unsigned char *, RspMessage
*, int);
22 extern board
*sc_adapter
[];
25 static int GetStatus(int card
, boardInfo
*);
28 * Process private IOCTL messages (typically from scctrl)
30 int sc_ioctl(int card
, scs_ioctl
*data
)
39 rcvmsg
= kmalloc(sizeof(RspMessage
), GFP_KERNEL
);
43 switch(data
->command
) {
44 case SCIOCRESET
: /* Perform a hard reset of the adapter */
46 pr_debug("%s: SCIOCRESET: ioctl received\n",
47 sc_adapter
[card
]->devicename
);
48 sc_adapter
[card
]->StartOnReset
= 0;
56 srec
= kmalloc(SCIOC_SRECSIZE
, GFP_KERNEL
);
61 pr_debug("%s: SCIOLOAD: ioctl received\n",
62 sc_adapter
[card
]->devicename
);
63 if(sc_adapter
[card
]->EngineUp
) {
64 pr_debug("%s: SCIOCLOAD: command failed, LoadProc while engine running.\n",
65 sc_adapter
[card
]->devicename
);
72 * Get the SRec from user space
74 if (copy_from_user(srec
, data
->dataptr
, sizeof(srec
))) {
80 status
= send_and_receive(card
, CMPID
, cmReqType2
, cmReqClass0
, cmReqLoadProc
,
81 0, sizeof(srec
), srec
, rcvmsg
, SAR_TIMEOUT
);
86 pr_debug("%s: SCIOCLOAD: command failed, status = %d\n",
87 sc_adapter
[card
]->devicename
, status
);
91 pr_debug("%s: SCIOCLOAD: command successful\n",
92 sc_adapter
[card
]->devicename
);
99 pr_debug("%s: SCIOSTART: ioctl received\n",
100 sc_adapter
[card
]->devicename
);
101 if(sc_adapter
[card
]->EngineUp
) {
102 pr_debug("%s: SCIOCSTART: command failed, engine already running.\n",
103 sc_adapter
[card
]->devicename
);
107 sc_adapter
[card
]->StartOnReset
= 1;
114 pr_debug("%s: SCIOSETSWITCH: ioctl received\n",
115 sc_adapter
[card
]->devicename
);
118 * Get the switch type from user space
120 if (copy_from_user(&switchtype
, data
->dataptr
, sizeof(char))) {
125 pr_debug("%s: SCIOCSETSWITCH: setting switch type to %d\n",
126 sc_adapter
[card
]->devicename
,
128 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
, ceReqCallSetSwitchType
,
129 0, sizeof(char),&switchtype
, rcvmsg
, SAR_TIMEOUT
);
130 if(!status
&& !(rcvmsg
->rsp_status
)) {
131 pr_debug("%s: SCIOCSETSWITCH: command successful\n",
132 sc_adapter
[card
]->devicename
);
137 pr_debug("%s: SCIOCSETSWITCH: command failed (status = %d)\n",
138 sc_adapter
[card
]->devicename
, status
);
146 pr_debug("%s: SCIOGETSWITCH: ioctl received\n",
147 sc_adapter
[card
]->devicename
);
150 * Get the switch type from the board
152 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
,
153 ceReqCallGetSwitchType
, 0, 0, NULL
, rcvmsg
, SAR_TIMEOUT
);
154 if (!status
&& !(rcvmsg
->rsp_status
)) {
155 pr_debug("%s: SCIOCGETSWITCH: command successful\n",
156 sc_adapter
[card
]->devicename
);
159 pr_debug("%s: SCIOCGETSWITCH: command failed (status = %d)\n",
160 sc_adapter
[card
]->devicename
, status
);
165 switchtype
= rcvmsg
->msg_data
.byte_array
[0];
168 * Package the switch type and send to user space
170 if (copy_to_user(data
->dataptr
, &switchtype
,
182 pr_debug("%s: SCIOGETSPID: ioctl received\n",
183 sc_adapter
[card
]->devicename
);
185 spid
= kmalloc(SCIOC_SPIDSIZE
, GFP_KERNEL
);
191 * Get the spid from the board
193 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
, ceReqCallGetSPID
,
194 data
->channel
, 0, NULL
, rcvmsg
, SAR_TIMEOUT
);
196 pr_debug("%s: SCIOCGETSPID: command successful\n",
197 sc_adapter
[card
]->devicename
);
200 pr_debug("%s: SCIOCGETSPID: command failed (status = %d)\n",
201 sc_adapter
[card
]->devicename
, status
);
205 strcpy(spid
, rcvmsg
->msg_data
.byte_array
);
208 * Package the switch type and send to user space
210 if (copy_to_user(data
->dataptr
, spid
, SCIOC_SPIDSIZE
)) {
223 pr_debug("%s: DCBIOSETSPID: ioctl received\n",
224 sc_adapter
[card
]->devicename
);
226 spid
= kmalloc(SCIOC_SPIDSIZE
, GFP_KERNEL
);
233 * Get the spid from user space
235 if (copy_from_user(spid
, data
->dataptr
, SCIOC_SPIDSIZE
)) {
240 pr_debug("%s: SCIOCSETSPID: setting channel %d spid to %s\n",
241 sc_adapter
[card
]->devicename
, data
->channel
, spid
);
242 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
,
243 ceReqClass0
, ceReqCallSetSPID
, data
->channel
,
244 strlen(spid
), spid
, rcvmsg
, SAR_TIMEOUT
);
245 if(!status
&& !(rcvmsg
->rsp_status
)) {
246 pr_debug("%s: SCIOCSETSPID: command successful\n",
247 sc_adapter
[card
]->devicename
);
253 pr_debug("%s: SCIOCSETSPID: command failed (status = %d)\n",
254 sc_adapter
[card
]->devicename
, status
);
263 pr_debug("%s: SCIOGETDN: ioctl received\n",
264 sc_adapter
[card
]->devicename
);
267 * Get the dn from the board
269 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
, ceReqCallGetMyNumber
,
270 data
->channel
, 0, NULL
, rcvmsg
, SAR_TIMEOUT
);
272 pr_debug("%s: SCIOCGETDN: command successful\n",
273 sc_adapter
[card
]->devicename
);
276 pr_debug("%s: SCIOCGETDN: command failed (status = %d)\n",
277 sc_adapter
[card
]->devicename
, status
);
282 dn
= kmalloc(SCIOC_DNSIZE
, GFP_KERNEL
);
287 strcpy(dn
, rcvmsg
->msg_data
.byte_array
);
291 * Package the dn and send to user space
293 if (copy_to_user(data
->dataptr
, dn
, SCIOC_DNSIZE
)) {
303 pr_debug("%s: SCIOSETDN: ioctl received\n",
304 sc_adapter
[card
]->devicename
);
306 dn
= kmalloc(SCIOC_DNSIZE
, GFP_KERNEL
);
312 * Get the spid from user space
314 if (copy_from_user(dn
, data
->dataptr
, SCIOC_DNSIZE
)) {
320 pr_debug("%s: SCIOCSETDN: setting channel %d dn to %s\n",
321 sc_adapter
[card
]->devicename
, data
->channel
, dn
);
322 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
,
323 ceReqClass0
, ceReqCallSetMyNumber
, data
->channel
,
324 strlen(dn
),dn
,rcvmsg
, SAR_TIMEOUT
);
325 if(!status
&& !(rcvmsg
->rsp_status
)) {
326 pr_debug("%s: SCIOCSETDN: command successful\n",
327 sc_adapter
[card
]->devicename
);
333 pr_debug("%s: SCIOCSETDN: command failed (status = %d)\n",
334 sc_adapter
[card
]->devicename
, status
);
343 pr_debug("%s: SCIOTRACE: ioctl received\n",
344 sc_adapter
[card
]->devicename
);
345 /* sc_adapter[card]->trace = !sc_adapter[card]->trace;
346 pr_debug("%s: SCIOCTRACE: tracing turned %s\n",
347 sc_adapter[card]->devicename,
348 sc_adapter[card]->trace ? "ON" : "OFF"); */
355 pr_debug("%s: SCIOSTAT: ioctl received\n",
356 sc_adapter
[card
]->devicename
);
358 bi
= kmalloc (sizeof(boardInfo
), GFP_KERNEL
);
367 if (copy_to_user(data
->dataptr
, bi
, sizeof(boardInfo
))) {
378 pr_debug("%s: SCIOGETSPEED: ioctl received\n",
379 sc_adapter
[card
]->devicename
);
382 * Get the speed from the board
384 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
,
385 ceReqCallGetCallType
, data
->channel
, 0, NULL
, rcvmsg
, SAR_TIMEOUT
);
386 if (!status
&& !(rcvmsg
->rsp_status
)) {
387 pr_debug("%s: SCIOCGETSPEED: command successful\n",
388 sc_adapter
[card
]->devicename
);
391 pr_debug("%s: SCIOCGETSPEED: command failed (status = %d)\n",
392 sc_adapter
[card
]->devicename
, status
);
397 speed
= rcvmsg
->msg_data
.byte_array
[0];
402 * Package the switch type and send to user space
405 if (copy_to_user(data
->dataptr
, &speed
, sizeof(char)))
412 pr_debug("%s: SCIOCSETSPEED: ioctl received\n",
413 sc_adapter
[card
]->devicename
);
417 pr_debug("%s: SCIOCLOOPTST: ioctl received\n",
418 sc_adapter
[card
]->devicename
);
430 static int GetStatus(int card
, boardInfo
*bi
)
436 * Fill in some of the basic info about the board
438 bi
->modelid
= sc_adapter
[card
]->model
;
439 strcpy(bi
->serial_no
, sc_adapter
[card
]->hwconfig
.serial_no
);
440 strcpy(bi
->part_no
, sc_adapter
[card
]->hwconfig
.part_no
);
441 bi
->iobase
= sc_adapter
[card
]->iobase
;
442 bi
->rambase
= sc_adapter
[card
]->rambase
;
443 bi
->irq
= sc_adapter
[card
]->interrupt
;
444 bi
->ramsize
= sc_adapter
[card
]->hwconfig
.ram_size
;
445 bi
->interface
= sc_adapter
[card
]->hwconfig
.st_u_sense
;
446 strcpy(bi
->load_ver
, sc_adapter
[card
]->load_ver
);
447 strcpy(bi
->proc_ver
, sc_adapter
[card
]->proc_ver
);
450 * Get the current PhyStats and LnkStats
452 status
= send_and_receive(card
, CEPID
, ceReqTypePhy
, ceReqClass2
,
453 ceReqPhyStatus
, 0, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
455 if(sc_adapter
[card
]->model
< PRI_BOARD
) {
456 bi
->l1_status
= rcvmsg
.msg_data
.byte_array
[2];
457 for(i
= 0 ; i
< BRI_CHANNELS
; i
++)
458 bi
->status
.bristats
[i
].phy_stat
=
459 rcvmsg
.msg_data
.byte_array
[i
];
462 bi
->l1_status
= rcvmsg
.msg_data
.byte_array
[0];
463 bi
->l2_status
= rcvmsg
.msg_data
.byte_array
[1];
464 for(i
= 0 ; i
< PRI_CHANNELS
; i
++)
465 bi
->status
.pristats
[i
].phy_stat
=
466 rcvmsg
.msg_data
.byte_array
[i
+2];
471 * Get the call types for each channel
473 for (i
= 0 ; i
< sc_adapter
[card
]->nChannels
; i
++) {
474 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
,
475 ceReqCallGetCallType
, 0, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
477 if (sc_adapter
[card
]->model
== PRI_BOARD
) {
478 bi
->status
.pristats
[i
].call_type
=
479 rcvmsg
.msg_data
.byte_array
[0];
482 bi
->status
.bristats
[i
].call_type
=
483 rcvmsg
.msg_data
.byte_array
[0];
489 * If PRI, get the call states and service states for each channel
491 if (sc_adapter
[card
]->model
== PRI_BOARD
) {
493 * Get the call states
495 status
= send_and_receive(card
, CEPID
, ceReqTypeStat
, ceReqClass2
,
496 ceReqPhyChCallState
, 0, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
498 for( i
= 0 ; i
< PRI_CHANNELS
; i
++ )
499 bi
->status
.pristats
[i
].call_state
=
500 rcvmsg
.msg_data
.byte_array
[i
];
504 * Get the service states
506 status
= send_and_receive(card
, CEPID
, ceReqTypeStat
, ceReqClass2
,
507 ceReqPhyChServState
, 0, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
509 for( i
= 0 ; i
< PRI_CHANNELS
; i
++ )
510 bi
->status
.pristats
[i
].serv_state
=
511 rcvmsg
.msg_data
.byte_array
[i
];
515 * Get the link stats for the channels
517 for (i
= 1 ; i
<= PRI_CHANNELS
; i
++) {
518 status
= send_and_receive(card
, CEPID
, ceReqTypeLnk
, ceReqClass0
,
519 ceReqLnkGetStats
, i
, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
521 bi
->status
.pristats
[i
-1].link_stats
.tx_good
=
522 (unsigned long)rcvmsg
.msg_data
.byte_array
[0];
523 bi
->status
.pristats
[i
-1].link_stats
.tx_bad
=
524 (unsigned long)rcvmsg
.msg_data
.byte_array
[4];
525 bi
->status
.pristats
[i
-1].link_stats
.rx_good
=
526 (unsigned long)rcvmsg
.msg_data
.byte_array
[8];
527 bi
->status
.pristats
[i
-1].link_stats
.rx_bad
=
528 (unsigned long)rcvmsg
.msg_data
.byte_array
[12];
533 * Link stats for the D channel
535 status
= send_and_receive(card
, CEPID
, ceReqTypeLnk
, ceReqClass0
,
536 ceReqLnkGetStats
, 0, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
538 bi
->dch_stats
.tx_good
= (unsigned long)rcvmsg
.msg_data
.byte_array
[0];
539 bi
->dch_stats
.tx_bad
= (unsigned long)rcvmsg
.msg_data
.byte_array
[4];
540 bi
->dch_stats
.rx_good
= (unsigned long)rcvmsg
.msg_data
.byte_array
[8];
541 bi
->dch_stats
.rx_bad
= (unsigned long)rcvmsg
.msg_data
.byte_array
[12];
548 * If BRI or POTS, Get SPID, DN and call types for each channel
552 * Get the link stats for the channels
554 status
= send_and_receive(card
, CEPID
, ceReqTypeLnk
, ceReqClass0
,
555 ceReqLnkGetStats
, 0, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
557 bi
->dch_stats
.tx_good
= (unsigned long)rcvmsg
.msg_data
.byte_array
[0];
558 bi
->dch_stats
.tx_bad
= (unsigned long)rcvmsg
.msg_data
.byte_array
[4];
559 bi
->dch_stats
.rx_good
= (unsigned long)rcvmsg
.msg_data
.byte_array
[8];
560 bi
->dch_stats
.rx_bad
= (unsigned long)rcvmsg
.msg_data
.byte_array
[12];
561 bi
->status
.bristats
[0].link_stats
.tx_good
=
562 (unsigned long)rcvmsg
.msg_data
.byte_array
[16];
563 bi
->status
.bristats
[0].link_stats
.tx_bad
=
564 (unsigned long)rcvmsg
.msg_data
.byte_array
[20];
565 bi
->status
.bristats
[0].link_stats
.rx_good
=
566 (unsigned long)rcvmsg
.msg_data
.byte_array
[24];
567 bi
->status
.bristats
[0].link_stats
.rx_bad
=
568 (unsigned long)rcvmsg
.msg_data
.byte_array
[28];
569 bi
->status
.bristats
[1].link_stats
.tx_good
=
570 (unsigned long)rcvmsg
.msg_data
.byte_array
[32];
571 bi
->status
.bristats
[1].link_stats
.tx_bad
=
572 (unsigned long)rcvmsg
.msg_data
.byte_array
[36];
573 bi
->status
.bristats
[1].link_stats
.rx_good
=
574 (unsigned long)rcvmsg
.msg_data
.byte_array
[40];
575 bi
->status
.bristats
[1].link_stats
.rx_bad
=
576 (unsigned long)rcvmsg
.msg_data
.byte_array
[44];
582 for (i
= 0 ; i
< BRI_CHANNELS
; i
++) {
583 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
,
584 ceReqCallGetSPID
, i
+1, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
586 strcpy(bi
->status
.bristats
[i
].spid
, rcvmsg
.msg_data
.byte_array
);
592 for (i
= 0 ; i
< BRI_CHANNELS
; i
++) {
593 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
,
594 ceReqCallGetMyNumber
, i
+1, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
596 strcpy(bi
->status
.bristats
[i
].dn
, rcvmsg
.msg_data
.byte_array
);