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.
16 extern int indicate_status(int, int, unsigned long, char *);
17 extern int startproc(int);
18 extern int loadproc(int, char *record);
19 extern int reset(int);
20 extern int send_and_receive(int, unsigned int, unsigned char,unsigned char,
21 unsigned char,unsigned char,
22 unsigned char, unsigned char *, RspMessage *, int);
24 extern board *adapter[];
27 int GetStatus(int card, boardInfo *);
30 * Process private IOCTL messages (typically from scctrl)
32 int sc_ioctl(int card, scs_ioctl *data)
34 switch(data->command) {
35 case SCIOCRESET: /* Perform a hard reset of the adapter */
37 pr_debug("%s: SCIOCRESET: ioctl received\n", adapter[card]->devicename);
38 adapter[card]->StartOnReset = 0;
45 char srec[SCIOC_SRECSIZE];
48 pr_debug("%s: SCIOLOAD: ioctl received\n", adapter[card]->devicename);
49 if(adapter[card]->EngineUp) {
50 pr_debug("%s: SCIOCLOAD: command failed, LoadProc while engine running.\n",
51 adapter[card]->devicename);
56 * Get the SRec from user space
58 if ((err = copy_from_user(srec, (char *) data->dataptr, sizeof(srec))))
61 status = send_and_receive(card, CMPID, cmReqType2, cmReqClass0, cmReqLoadProc,
62 0, sizeof(srec), srec, &rcvmsg, SAR_TIMEOUT);
64 pr_debug("%s: SCIOCLOAD: command failed, status = %d\n",
65 adapter[card]->devicename, status);
69 pr_debug("%s: SCIOCLOAD: command successful\n", adapter[card]->devicename);
76 pr_debug("%s: SCIOSTART: ioctl received\n", adapter[card]->devicename);
77 if(adapter[card]->EngineUp) {
78 pr_debug("%s: SCIOCSTART: command failed, engine already running.\n",
79 adapter[card]->devicename);
83 adapter[card]->StartOnReset = 1;
94 pr_debug("%s: SCIOSETSWITCH: ioctl received\n", adapter[card]->devicename);
97 * Get the switch type from user space
99 if ((err = copy_from_user(&switchtype, (char *) data->dataptr, sizeof(char))))
102 pr_debug("%s: SCIOCSETSWITCH: setting switch type to %d\n", adapter[card]->devicename,
104 status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, ceReqCallSetSwitchType,
105 0, sizeof(char),&switchtype,&rcvmsg, SAR_TIMEOUT);
106 if(!status && !rcvmsg.rsp_status) {
107 pr_debug("%s: SCIOCSETSWITCH: command successful\n", adapter[card]->devicename);
111 pr_debug("%s: SCIOCSETSWITCH: command failed (status = %d)\n",
112 adapter[card]->devicename, status);
123 pr_debug("%s: SCIOGETSWITCH: ioctl received\n", adapter[card]->devicename);
126 * Get the switch type from the board
128 status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0,
129 ceReqCallGetSwitchType, 0, 0, 0, &rcvmsg, SAR_TIMEOUT);
130 if (!status && !rcvmsg.rsp_status) {
131 pr_debug("%s: SCIOCGETSWITCH: command successful\n", adapter[card]->devicename);
134 pr_debug("%s: SCIOCGETSWITCH: command failed (status = %d)\n",
135 adapter[card]->devicename, status);
139 switchtype = rcvmsg.msg_data.byte_array[0];
142 * Package the switch type and send to user space
144 if ((err = copy_to_user((char *) data->dataptr, &switchtype, sizeof(char))))
153 char spid[SCIOC_SPIDSIZE];
156 pr_debug("%s: SCIOGETSPID: ioctl received\n", adapter[card]->devicename);
159 * Get the spid from the board
161 status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, ceReqCallGetSPID,
162 data->channel, 0, 0, &rcvmsg, SAR_TIMEOUT);
164 pr_debug("%s: SCIOCGETSPID: command successful\n", adapter[card]->devicename);
167 pr_debug("%s: SCIOCGETSPID: command failed (status = %d)\n",
168 adapter[card]->devicename, status);
171 strcpy(spid, rcvmsg.msg_data.byte_array);
174 * Package the switch type and send to user space
176 if ((err = copy_to_user((char *) data->dataptr, spid, sizeof(spid))))
185 char spid[SCIOC_SPIDSIZE];
188 pr_debug("%s: DCBIOSETSPID: ioctl received\n", adapter[card]->devicename);
191 * Get the spid from user space
193 if ((err = copy_from_user(spid, (char *) data->dataptr, sizeof(spid))))
196 pr_debug("%s: SCIOCSETSPID: setting channel %d spid to %s\n",
197 adapter[card]->devicename, data->channel, spid);
198 status = send_and_receive(card, CEPID, ceReqTypeCall,
199 ceReqClass0, ceReqCallSetSPID, data->channel,
200 strlen(spid), spid, &rcvmsg, SAR_TIMEOUT);
201 if(!status && !rcvmsg.rsp_status) {
202 pr_debug("%s: SCIOCSETSPID: command successful\n",
203 adapter[card]->devicename);
207 pr_debug("%s: SCIOCSETSPID: command failed (status = %d)\n",
208 adapter[card]->devicename, status);
216 char dn[SCIOC_DNSIZE];
219 pr_debug("%s: SCIOGETDN: ioctl received\n", adapter[card]->devicename);
222 * Get the dn from the board
224 status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, ceReqCallGetMyNumber,
225 data->channel, 0, 0, &rcvmsg, SAR_TIMEOUT);
227 pr_debug("%s: SCIOCGETDN: command successful\n", adapter[card]->devicename);
230 pr_debug("%s: SCIOCGETDN: command failed (status = %d)\n",
231 adapter[card]->devicename, status);
235 strcpy(dn, rcvmsg.msg_data.byte_array);
238 * Package the dn and send to user space
240 if ((err = copy_to_user((char *) data->dataptr, dn, sizeof(dn))))
249 char dn[SCIOC_DNSIZE];
252 pr_debug("%s: SCIOSETDN: ioctl received\n", adapter[card]->devicename);
255 * Get the spid from user space
257 if ((err = copy_from_user(dn, (char *) data->dataptr, sizeof(dn))))
260 pr_debug("%s: SCIOCSETDN: setting channel %d dn to %s\n",
261 adapter[card]->devicename, data->channel, dn);
262 status = send_and_receive(card, CEPID, ceReqTypeCall,
263 ceReqClass0, ceReqCallSetMyNumber, data->channel,
264 strlen(dn),dn,&rcvmsg, SAR_TIMEOUT);
265 if(!status && !rcvmsg.rsp_status) {
266 pr_debug("%s: SCIOCSETDN: command successful\n",
267 adapter[card]->devicename);
271 pr_debug("%s: SCIOCSETDN: command failed (status = %d)\n",
272 adapter[card]->devicename, status);
279 pr_debug("%s: SCIOTRACE: ioctl received\n", adapter[card]->devicename);
280 /* adapter[card]->trace = !adapter[card]->trace;
281 pr_debug("%s: SCIOCTRACE: tracing turned %s\n", adapter[card]->devicename,
282 adapter[card]->trace ? "ON" : "OFF"); */
290 pr_debug("%s: SCIOSTAT: ioctl received\n", adapter[card]->devicename);
291 GetStatus(card, &bi);
293 if ((err = copy_to_user((boardInfo *) data->dataptr, &bi, sizeof(boardInfo))))
305 pr_debug("%s: SCIOGETSPEED: ioctl received\n", adapter[card]->devicename);
308 * Get the speed from the board
310 status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0,
311 ceReqCallGetCallType, data->channel, 0, 0, &rcvmsg, SAR_TIMEOUT);
312 if (!status && !rcvmsg.rsp_status) {
313 pr_debug("%s: SCIOCGETSPEED: command successful\n",
314 adapter[card]->devicename);
317 pr_debug("%s: SCIOCGETSPEED: command failed (status = %d)\n",
318 adapter[card]->devicename, status);
322 speed = rcvmsg.msg_data.byte_array[0];
325 * Package the switch type and send to user space
327 if ((err = copy_to_user((char *) data->dataptr, &speed, sizeof(char))))
334 pr_debug("%s: SCIOCSETSPEED: ioctl received\n", adapter[card]->devicename);
338 pr_debug("%s: SCIOCLOOPTST: ioctl received\n", adapter[card]->devicename);
348 int GetStatus(int card, boardInfo *bi)
354 * Fill in some of the basic info about the board
356 bi->modelid = adapter[card]->model;
357 strcpy(bi->serial_no, adapter[card]->hwconfig.serial_no);
358 strcpy(bi->part_no, adapter[card]->hwconfig.part_no);
359 bi->iobase = adapter[card]->iobase;
360 bi->rambase = adapter[card]->rambase;
361 bi->irq = adapter[card]->interrupt;
362 bi->ramsize = adapter[card]->hwconfig.ram_size;
363 bi->interface = adapter[card]->hwconfig.st_u_sense;
364 strcpy(bi->load_ver, adapter[card]->load_ver);
365 strcpy(bi->proc_ver, adapter[card]->proc_ver);
368 * Get the current PhyStats and LnkStats
370 status = send_and_receive(card, CEPID, ceReqTypePhy, ceReqClass2,
371 ceReqPhyStatus, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);
373 if(adapter[card]->model < PRI_BOARD) {
374 bi->l1_status = rcvmsg.msg_data.byte_array[2];
375 for(i = 0 ; i < BRI_CHANNELS ; i++)
376 bi->status.bristats[i].phy_stat =
377 rcvmsg.msg_data.byte_array[i];
380 bi->l1_status = rcvmsg.msg_data.byte_array[0];
381 bi->l2_status = rcvmsg.msg_data.byte_array[1];
382 for(i = 0 ; i < PRI_CHANNELS ; i++)
383 bi->status.pristats[i].phy_stat =
384 rcvmsg.msg_data.byte_array[i+2];
389 * Get the call types for each channel
391 for (i = 0 ; i < adapter[card]->nChannels ; i++) {
392 status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0,
393 ceReqCallGetCallType, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);
395 if (adapter[card]->model == PRI_BOARD) {
396 bi->status.pristats[i].call_type =
397 rcvmsg.msg_data.byte_array[0];
400 bi->status.bristats[i].call_type =
401 rcvmsg.msg_data.byte_array[0];
407 * If PRI, get the call states and service states for each channel
409 if (adapter[card]->model == PRI_BOARD) {
411 * Get the call states
413 status = send_and_receive(card, CEPID, ceReqTypeStat, ceReqClass2,
414 ceReqPhyChCallState, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);
416 for( i = 0 ; i < PRI_CHANNELS ; i++ )
417 bi->status.pristats[i].call_state =
418 rcvmsg.msg_data.byte_array[i];
422 * Get the service states
424 status = send_and_receive(card, CEPID, ceReqTypeStat, ceReqClass2,
425 ceReqPhyChServState, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);
427 for( i = 0 ; i < PRI_CHANNELS ; i++ )
428 bi->status.pristats[i].serv_state =
429 rcvmsg.msg_data.byte_array[i];
433 * Get the link stats for the channels
435 for (i = 1 ; i <= PRI_CHANNELS ; i++) {
436 status = send_and_receive(card, CEPID, ceReqTypeLnk, ceReqClass0,
437 ceReqLnkGetStats, i, 0, NULL, &rcvmsg, SAR_TIMEOUT);
439 bi->status.pristats[i-1].link_stats.tx_good =
440 (unsigned long)rcvmsg.msg_data.byte_array[0];
441 bi->status.pristats[i-1].link_stats.tx_bad =
442 (unsigned long)rcvmsg.msg_data.byte_array[4];
443 bi->status.pristats[i-1].link_stats.rx_good =
444 (unsigned long)rcvmsg.msg_data.byte_array[8];
445 bi->status.pristats[i-1].link_stats.rx_bad =
446 (unsigned long)rcvmsg.msg_data.byte_array[12];
451 * Link stats for the D channel
453 status = send_and_receive(card, CEPID, ceReqTypeLnk, ceReqClass0,
454 ceReqLnkGetStats, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);
456 bi->dch_stats.tx_good = (unsigned long)rcvmsg.msg_data.byte_array[0];
457 bi->dch_stats.tx_bad = (unsigned long)rcvmsg.msg_data.byte_array[4];
458 bi->dch_stats.rx_good = (unsigned long)rcvmsg.msg_data.byte_array[8];
459 bi->dch_stats.rx_bad = (unsigned long)rcvmsg.msg_data.byte_array[12];
466 * If BRI or POTS, Get SPID, DN and call types for each channel
470 * Get the link stats for the channels
472 status = send_and_receive(card, CEPID, ceReqTypeLnk, ceReqClass0,
473 ceReqLnkGetStats, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);
475 bi->dch_stats.tx_good = (unsigned long)rcvmsg.msg_data.byte_array[0];
476 bi->dch_stats.tx_bad = (unsigned long)rcvmsg.msg_data.byte_array[4];
477 bi->dch_stats.rx_good = (unsigned long)rcvmsg.msg_data.byte_array[8];
478 bi->dch_stats.rx_bad = (unsigned long)rcvmsg.msg_data.byte_array[12];
479 bi->status.bristats[0].link_stats.tx_good =
480 (unsigned long)rcvmsg.msg_data.byte_array[16];
481 bi->status.bristats[0].link_stats.tx_bad =
482 (unsigned long)rcvmsg.msg_data.byte_array[20];
483 bi->status.bristats[0].link_stats.rx_good =
484 (unsigned long)rcvmsg.msg_data.byte_array[24];
485 bi->status.bristats[0].link_stats.rx_bad =
486 (unsigned long)rcvmsg.msg_data.byte_array[28];
487 bi->status.bristats[1].link_stats.tx_good =
488 (unsigned long)rcvmsg.msg_data.byte_array[32];
489 bi->status.bristats[1].link_stats.tx_bad =
490 (unsigned long)rcvmsg.msg_data.byte_array[36];
491 bi->status.bristats[1].link_stats.rx_good =
492 (unsigned long)rcvmsg.msg_data.byte_array[40];
493 bi->status.bristats[1].link_stats.rx_bad =
494 (unsigned long)rcvmsg.msg_data.byte_array[44];
500 for (i = 0 ; i < BRI_CHANNELS ; i++) {
501 status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0,
502 ceReqCallGetSPID, i+1, 0, NULL, &rcvmsg, SAR_TIMEOUT);
504 strcpy(bi->status.bristats[i].spid, rcvmsg.msg_data.byte_array);
510 for (i = 0 ; i < BRI_CHANNELS ; i++) {
511 status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0,
512 ceReqCallGetMyNumber, i+1, 0, NULL, &rcvmsg, SAR_TIMEOUT);
514 strcpy(bi->status.bristats[i].dn, rcvmsg.msg_data.byte_array);