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 static int GetStatus(int card
, boardInfo
*);
18 * Process private IOCTL messages (typically from scctrl)
20 int sc_ioctl(int card
, scs_ioctl
*data
)
29 rcvmsg
= kmalloc(sizeof(RspMessage
), GFP_KERNEL
);
33 switch (data
->command
) {
34 case SCIOCRESET
: /* Perform a hard reset of the adapter */
36 pr_debug("%s: SCIOCRESET: ioctl received\n",
37 sc_adapter
[card
]->devicename
);
38 sc_adapter
[card
]->StartOnReset
= 0;
47 srec
= kmalloc(SCIOC_SRECSIZE
, GFP_KERNEL
);
52 pr_debug("%s: SCIOLOAD: ioctl received\n",
53 sc_adapter
[card
]->devicename
);
54 if (sc_adapter
[card
]->EngineUp
) {
55 pr_debug("%s: SCIOCLOAD: command failed, LoadProc while engine running.\n",
56 sc_adapter
[card
]->devicename
);
63 * Get the SRec from user space
65 if (copy_from_user(srec
, data
->dataptr
, SCIOC_SRECSIZE
)) {
71 status
= send_and_receive(card
, CMPID
, cmReqType2
, cmReqClass0
, cmReqLoadProc
,
72 0, SCIOC_SRECSIZE
, srec
, rcvmsg
, SAR_TIMEOUT
);
77 pr_debug("%s: SCIOCLOAD: command failed, status = %d\n",
78 sc_adapter
[card
]->devicename
, status
);
82 pr_debug("%s: SCIOCLOAD: command successful\n",
83 sc_adapter
[card
]->devicename
);
91 pr_debug("%s: SCIOSTART: ioctl received\n",
92 sc_adapter
[card
]->devicename
);
93 if (sc_adapter
[card
]->EngineUp
) {
94 pr_debug("%s: SCIOCSTART: command failed, engine already running.\n",
95 sc_adapter
[card
]->devicename
);
99 sc_adapter
[card
]->StartOnReset
= 1;
106 pr_debug("%s: SCIOSETSWITCH: ioctl received\n",
107 sc_adapter
[card
]->devicename
);
110 * Get the switch type from user space
112 if (copy_from_user(&switchtype
, data
->dataptr
, sizeof(char))) {
117 pr_debug("%s: SCIOCSETSWITCH: setting switch type to %d\n",
118 sc_adapter
[card
]->devicename
,
120 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
, ceReqCallSetSwitchType
,
121 0, sizeof(char), &switchtype
, rcvmsg
, SAR_TIMEOUT
);
122 if (!status
&& !(rcvmsg
->rsp_status
)) {
123 pr_debug("%s: SCIOCSETSWITCH: command successful\n",
124 sc_adapter
[card
]->devicename
);
129 pr_debug("%s: SCIOCSETSWITCH: command failed (status = %d)\n",
130 sc_adapter
[card
]->devicename
, status
);
138 pr_debug("%s: SCIOGETSWITCH: ioctl received\n",
139 sc_adapter
[card
]->devicename
);
142 * Get the switch type from the board
144 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
,
145 ceReqCallGetSwitchType
, 0, 0, NULL
, rcvmsg
, SAR_TIMEOUT
);
146 if (!status
&& !(rcvmsg
->rsp_status
)) {
147 pr_debug("%s: SCIOCGETSWITCH: command successful\n",
148 sc_adapter
[card
]->devicename
);
151 pr_debug("%s: SCIOCGETSWITCH: command failed (status = %d)\n",
152 sc_adapter
[card
]->devicename
, status
);
157 switchtype
= rcvmsg
->msg_data
.byte_array
[0];
160 * Package the switch type and send to user space
162 if (copy_to_user(data
->dataptr
, &switchtype
,
174 pr_debug("%s: SCIOGETSPID: ioctl received\n",
175 sc_adapter
[card
]->devicename
);
177 spid
= kzalloc(SCIOC_SPIDSIZE
, GFP_KERNEL
);
183 * Get the spid from the board
185 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
, ceReqCallGetSPID
,
186 data
->channel
, 0, NULL
, rcvmsg
, SAR_TIMEOUT
);
188 pr_debug("%s: SCIOCGETSPID: command successful\n",
189 sc_adapter
[card
]->devicename
);
191 pr_debug("%s: SCIOCGETSPID: command failed (status = %d)\n",
192 sc_adapter
[card
]->devicename
, status
);
197 strlcpy(spid
, rcvmsg
->msg_data
.byte_array
, SCIOC_SPIDSIZE
);
200 * Package the switch type and send to user space
202 if (copy_to_user(data
->dataptr
, spid
, SCIOC_SPIDSIZE
)) {
215 pr_debug("%s: DCBIOSETSPID: ioctl received\n",
216 sc_adapter
[card
]->devicename
);
219 * Get the spid from user space
221 spid
= memdup_user(data
->dataptr
, SCIOC_SPIDSIZE
);
224 return PTR_ERR(spid
);
227 pr_debug("%s: SCIOCSETSPID: setting channel %d spid to %s\n",
228 sc_adapter
[card
]->devicename
, data
->channel
, spid
);
229 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
,
230 ceReqClass0
, ceReqCallSetSPID
, data
->channel
,
231 strlen(spid
), spid
, rcvmsg
, SAR_TIMEOUT
);
232 if (!status
&& !(rcvmsg
->rsp_status
)) {
233 pr_debug("%s: SCIOCSETSPID: command successful\n",
234 sc_adapter
[card
]->devicename
);
240 pr_debug("%s: SCIOCSETSPID: command failed (status = %d)\n",
241 sc_adapter
[card
]->devicename
, status
);
250 pr_debug("%s: SCIOGETDN: ioctl received\n",
251 sc_adapter
[card
]->devicename
);
254 * Get the dn from the board
256 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
, ceReqCallGetMyNumber
,
257 data
->channel
, 0, NULL
, rcvmsg
, SAR_TIMEOUT
);
259 pr_debug("%s: SCIOCGETDN: command successful\n",
260 sc_adapter
[card
]->devicename
);
263 pr_debug("%s: SCIOCGETDN: command failed (status = %d)\n",
264 sc_adapter
[card
]->devicename
, status
);
269 dn
= kzalloc(SCIOC_DNSIZE
, GFP_KERNEL
);
274 strlcpy(dn
, rcvmsg
->msg_data
.byte_array
, SCIOC_DNSIZE
);
278 * Package the dn and send to user space
280 if (copy_to_user(data
->dataptr
, dn
, SCIOC_DNSIZE
)) {
290 pr_debug("%s: SCIOSETDN: ioctl received\n",
291 sc_adapter
[card
]->devicename
);
294 * Get the spid from user space
296 dn
= memdup_user(data
->dataptr
, SCIOC_DNSIZE
);
302 pr_debug("%s: SCIOCSETDN: setting channel %d dn to %s\n",
303 sc_adapter
[card
]->devicename
, data
->channel
, dn
);
304 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
,
305 ceReqClass0
, ceReqCallSetMyNumber
, data
->channel
,
306 strlen(dn
), dn
, rcvmsg
, SAR_TIMEOUT
);
307 if (!status
&& !(rcvmsg
->rsp_status
)) {
308 pr_debug("%s: SCIOCSETDN: command successful\n",
309 sc_adapter
[card
]->devicename
);
315 pr_debug("%s: SCIOCSETDN: command failed (status = %d)\n",
316 sc_adapter
[card
]->devicename
, status
);
325 pr_debug("%s: SCIOTRACE: ioctl received\n",
326 sc_adapter
[card
]->devicename
);
327 /* sc_adapter[card]->trace = !sc_adapter[card]->trace;
328 pr_debug("%s: SCIOCTRACE: tracing turned %s\n",
329 sc_adapter[card]->devicename,
330 sc_adapter[card]->trace ? "ON" : "OFF"); */
337 pr_debug("%s: SCIOSTAT: ioctl received\n",
338 sc_adapter
[card
]->devicename
);
340 bi
= kzalloc(sizeof(boardInfo
), GFP_KERNEL
);
349 if (copy_to_user(data
->dataptr
, bi
, sizeof(boardInfo
))) {
360 pr_debug("%s: SCIOGETSPEED: ioctl received\n",
361 sc_adapter
[card
]->devicename
);
364 * Get the speed from the board
366 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
,
367 ceReqCallGetCallType
, data
->channel
, 0, NULL
, rcvmsg
, SAR_TIMEOUT
);
368 if (!status
&& !(rcvmsg
->rsp_status
)) {
369 pr_debug("%s: SCIOCGETSPEED: command successful\n",
370 sc_adapter
[card
]->devicename
);
373 pr_debug("%s: SCIOCGETSPEED: command failed (status = %d)\n",
374 sc_adapter
[card
]->devicename
, status
);
379 speed
= rcvmsg
->msg_data
.byte_array
[0];
384 * Package the switch type and send to user space
387 if (copy_to_user(data
->dataptr
, &speed
, sizeof(char)))
394 pr_debug("%s: SCIOCSETSPEED: ioctl received\n",
395 sc_adapter
[card
]->devicename
);
399 pr_debug("%s: SCIOCLOOPTST: ioctl received\n",
400 sc_adapter
[card
]->devicename
);
412 static int GetStatus(int card
, boardInfo
*bi
)
418 * Fill in some of the basic info about the board
420 bi
->modelid
= sc_adapter
[card
]->model
;
421 strcpy(bi
->serial_no
, sc_adapter
[card
]->hwconfig
.serial_no
);
422 strcpy(bi
->part_no
, sc_adapter
[card
]->hwconfig
.part_no
);
423 bi
->iobase
= sc_adapter
[card
]->iobase
;
424 bi
->rambase
= sc_adapter
[card
]->rambase
;
425 bi
->irq
= sc_adapter
[card
]->interrupt
;
426 bi
->ramsize
= sc_adapter
[card
]->hwconfig
.ram_size
;
427 bi
->interface
= sc_adapter
[card
]->hwconfig
.st_u_sense
;
428 strcpy(bi
->load_ver
, sc_adapter
[card
]->load_ver
);
429 strcpy(bi
->proc_ver
, sc_adapter
[card
]->proc_ver
);
432 * Get the current PhyStats and LnkStats
434 status
= send_and_receive(card
, CEPID
, ceReqTypePhy
, ceReqClass2
,
435 ceReqPhyStatus
, 0, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
437 if (sc_adapter
[card
]->model
< PRI_BOARD
) {
438 bi
->l1_status
= rcvmsg
.msg_data
.byte_array
[2];
439 for (i
= 0; i
< BRI_CHANNELS
; i
++)
440 bi
->status
.bristats
[i
].phy_stat
=
441 rcvmsg
.msg_data
.byte_array
[i
];
444 bi
->l1_status
= rcvmsg
.msg_data
.byte_array
[0];
445 bi
->l2_status
= rcvmsg
.msg_data
.byte_array
[1];
446 for (i
= 0; i
< PRI_CHANNELS
; i
++)
447 bi
->status
.pristats
[i
].phy_stat
=
448 rcvmsg
.msg_data
.byte_array
[i
+ 2];
453 * Get the call types for each channel
455 for (i
= 0; i
< sc_adapter
[card
]->nChannels
; i
++) {
456 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
,
457 ceReqCallGetCallType
, 0, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
459 if (sc_adapter
[card
]->model
== PRI_BOARD
) {
460 bi
->status
.pristats
[i
].call_type
=
461 rcvmsg
.msg_data
.byte_array
[0];
464 bi
->status
.bristats
[i
].call_type
=
465 rcvmsg
.msg_data
.byte_array
[0];
471 * If PRI, get the call states and service states for each channel
473 if (sc_adapter
[card
]->model
== PRI_BOARD
) {
475 * Get the call states
477 status
= send_and_receive(card
, CEPID
, ceReqTypeStat
, ceReqClass2
,
478 ceReqPhyChCallState
, 0, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
480 for (i
= 0; i
< PRI_CHANNELS
; i
++)
481 bi
->status
.pristats
[i
].call_state
=
482 rcvmsg
.msg_data
.byte_array
[i
];
486 * Get the service states
488 status
= send_and_receive(card
, CEPID
, ceReqTypeStat
, ceReqClass2
,
489 ceReqPhyChServState
, 0, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
491 for (i
= 0; i
< PRI_CHANNELS
; i
++)
492 bi
->status
.pristats
[i
].serv_state
=
493 rcvmsg
.msg_data
.byte_array
[i
];
497 * Get the link stats for the channels
499 for (i
= 1; i
<= PRI_CHANNELS
; i
++) {
500 status
= send_and_receive(card
, CEPID
, ceReqTypeLnk
, ceReqClass0
,
501 ceReqLnkGetStats
, i
, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
503 bi
->status
.pristats
[i
- 1].link_stats
.tx_good
=
504 (unsigned long)rcvmsg
.msg_data
.byte_array
[0];
505 bi
->status
.pristats
[i
- 1].link_stats
.tx_bad
=
506 (unsigned long)rcvmsg
.msg_data
.byte_array
[4];
507 bi
->status
.pristats
[i
- 1].link_stats
.rx_good
=
508 (unsigned long)rcvmsg
.msg_data
.byte_array
[8];
509 bi
->status
.pristats
[i
- 1].link_stats
.rx_bad
=
510 (unsigned long)rcvmsg
.msg_data
.byte_array
[12];
515 * Link stats for the D channel
517 status
= send_and_receive(card
, CEPID
, ceReqTypeLnk
, ceReqClass0
,
518 ceReqLnkGetStats
, 0, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
520 bi
->dch_stats
.tx_good
= (unsigned long)rcvmsg
.msg_data
.byte_array
[0];
521 bi
->dch_stats
.tx_bad
= (unsigned long)rcvmsg
.msg_data
.byte_array
[4];
522 bi
->dch_stats
.rx_good
= (unsigned long)rcvmsg
.msg_data
.byte_array
[8];
523 bi
->dch_stats
.rx_bad
= (unsigned long)rcvmsg
.msg_data
.byte_array
[12];
530 * If BRI or POTS, Get SPID, DN and call types for each channel
534 * Get the link stats for the channels
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];
543 bi
->status
.bristats
[0].link_stats
.tx_good
=
544 (unsigned long)rcvmsg
.msg_data
.byte_array
[16];
545 bi
->status
.bristats
[0].link_stats
.tx_bad
=
546 (unsigned long)rcvmsg
.msg_data
.byte_array
[20];
547 bi
->status
.bristats
[0].link_stats
.rx_good
=
548 (unsigned long)rcvmsg
.msg_data
.byte_array
[24];
549 bi
->status
.bristats
[0].link_stats
.rx_bad
=
550 (unsigned long)rcvmsg
.msg_data
.byte_array
[28];
551 bi
->status
.bristats
[1].link_stats
.tx_good
=
552 (unsigned long)rcvmsg
.msg_data
.byte_array
[32];
553 bi
->status
.bristats
[1].link_stats
.tx_bad
=
554 (unsigned long)rcvmsg
.msg_data
.byte_array
[36];
555 bi
->status
.bristats
[1].link_stats
.rx_good
=
556 (unsigned long)rcvmsg
.msg_data
.byte_array
[40];
557 bi
->status
.bristats
[1].link_stats
.rx_bad
=
558 (unsigned long)rcvmsg
.msg_data
.byte_array
[44];
564 for (i
= 0; i
< BRI_CHANNELS
; i
++) {
565 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
,
566 ceReqCallGetSPID
, i
+ 1, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
568 strcpy(bi
->status
.bristats
[i
].spid
, rcvmsg
.msg_data
.byte_array
);
574 for (i
= 0; i
< BRI_CHANNELS
; i
++) {
575 status
= send_and_receive(card
, CEPID
, ceReqTypeCall
, ceReqClass0
,
576 ceReqCallGetMyNumber
, i
+ 1, 0, NULL
, &rcvmsg
, SAR_TIMEOUT
);
578 strcpy(bi
->status
.bristats
[i
].dn
, rcvmsg
.msg_data
.byte_array
);