Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.30 593 lines 15 kB view raw
1/* 2 * Copyright (C) 1996 SpellCaster Telecommunications Inc. 3 * 4 * This software may be used and distributed according to the terms 5 * of the GNU General Public License, incorporated herein by reference. 6 * 7 */ 8 9#include "includes.h" 10#include "hardware.h" 11#include "message.h" 12#include "card.h" 13#include "scioc.h" 14 15static int GetStatus(int card, boardInfo *); 16 17/* 18 * Process private IOCTL messages (typically from scctrl) 19 */ 20int sc_ioctl(int card, scs_ioctl *data) 21{ 22 int status; 23 RspMessage *rcvmsg; 24 char *spid; 25 char *dn; 26 char switchtype; 27 char speed; 28 29 rcvmsg = kmalloc(sizeof(RspMessage), GFP_KERNEL); 30 if (!rcvmsg) 31 return -ENOMEM; 32 33 switch(data->command) { 34 case SCIOCRESET: /* Perform a hard reset of the adapter */ 35 { 36 pr_debug("%s: SCIOCRESET: ioctl received\n", 37 sc_adapter[card]->devicename); 38 sc_adapter[card]->StartOnReset = 0; 39 kfree(rcvmsg); 40 return reset(card); 41 } 42 43 case SCIOCLOAD: 44 { 45 char *srec; 46 47 srec = kmalloc(SCIOC_SRECSIZE, GFP_KERNEL); 48 if (!srec) { 49 kfree(rcvmsg); 50 return -ENOMEM; 51 } 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); 57 kfree(rcvmsg); 58 kfree(srec); 59 return -1; 60 } 61 62 /* 63 * Get the SRec from user space 64 */ 65 if (copy_from_user(srec, data->dataptr, SCIOC_SRECSIZE)) { 66 kfree(rcvmsg); 67 kfree(srec); 68 return -EFAULT; 69 } 70 71 status = send_and_receive(card, CMPID, cmReqType2, cmReqClass0, cmReqLoadProc, 72 0, SCIOC_SRECSIZE, srec, rcvmsg, SAR_TIMEOUT); 73 kfree(rcvmsg); 74 kfree(srec); 75 76 if(status) { 77 pr_debug("%s: SCIOCLOAD: command failed, status = %d\n", 78 sc_adapter[card]->devicename, status); 79 return -1; 80 } 81 else { 82 pr_debug("%s: SCIOCLOAD: command successful\n", 83 sc_adapter[card]->devicename); 84 return 0; 85 } 86 } 87 88 case SCIOCSTART: 89 { 90 kfree(rcvmsg); 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); 96 return -1; 97 } 98 99 sc_adapter[card]->StartOnReset = 1; 100 startproc(card); 101 return 0; 102 } 103 104 case SCIOCSETSWITCH: 105 { 106 pr_debug("%s: SCIOSETSWITCH: ioctl received\n", 107 sc_adapter[card]->devicename); 108 109 /* 110 * Get the switch type from user space 111 */ 112 if (copy_from_user(&switchtype, data->dataptr, sizeof(char))) { 113 kfree(rcvmsg); 114 return -EFAULT; 115 } 116 117 pr_debug("%s: SCIOCSETSWITCH: setting switch type to %d\n", 118 sc_adapter[card]->devicename, 119 switchtype); 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); 125 kfree(rcvmsg); 126 return 0; 127 } 128 else { 129 pr_debug("%s: SCIOCSETSWITCH: command failed (status = %d)\n", 130 sc_adapter[card]->devicename, status); 131 kfree(rcvmsg); 132 return status; 133 } 134 } 135 136 case SCIOCGETSWITCH: 137 { 138 pr_debug("%s: SCIOGETSWITCH: ioctl received\n", 139 sc_adapter[card]->devicename); 140 141 /* 142 * Get the switch type from the board 143 */ 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); 149 } 150 else { 151 pr_debug("%s: SCIOCGETSWITCH: command failed (status = %d)\n", 152 sc_adapter[card]->devicename, status); 153 kfree(rcvmsg); 154 return status; 155 } 156 157 switchtype = rcvmsg->msg_data.byte_array[0]; 158 159 /* 160 * Package the switch type and send to user space 161 */ 162 if (copy_to_user(data->dataptr, &switchtype, 163 sizeof(char))) { 164 kfree(rcvmsg); 165 return -EFAULT; 166 } 167 168 kfree(rcvmsg); 169 return 0; 170 } 171 172 case SCIOCGETSPID: 173 { 174 pr_debug("%s: SCIOGETSPID: ioctl received\n", 175 sc_adapter[card]->devicename); 176 177 spid = kmalloc(SCIOC_SPIDSIZE, GFP_KERNEL); 178 if (!spid) { 179 kfree(rcvmsg); 180 return -ENOMEM; 181 } 182 /* 183 * Get the spid from the board 184 */ 185 status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, ceReqCallGetSPID, 186 data->channel, 0, NULL, rcvmsg, SAR_TIMEOUT); 187 if (!status) { 188 pr_debug("%s: SCIOCGETSPID: command successful\n", 189 sc_adapter[card]->devicename); 190 } else { 191 pr_debug("%s: SCIOCGETSPID: command failed (status = %d)\n", 192 sc_adapter[card]->devicename, status); 193 kfree(spid); 194 kfree(rcvmsg); 195 return status; 196 } 197 strcpy(spid, rcvmsg->msg_data.byte_array); 198 199 /* 200 * Package the switch type and send to user space 201 */ 202 if (copy_to_user(data->dataptr, spid, SCIOC_SPIDSIZE)) { 203 kfree(spid); 204 kfree(rcvmsg); 205 return -EFAULT; 206 } 207 208 kfree(spid); 209 kfree(rcvmsg); 210 return 0; 211 } 212 213 case SCIOCSETSPID: 214 { 215 pr_debug("%s: DCBIOSETSPID: ioctl received\n", 216 sc_adapter[card]->devicename); 217 218 spid = kmalloc(SCIOC_SPIDSIZE, GFP_KERNEL); 219 if(!spid) { 220 kfree(rcvmsg); 221 return -ENOMEM; 222 } 223 224 /* 225 * Get the spid from user space 226 */ 227 if (copy_from_user(spid, data->dataptr, SCIOC_SPIDSIZE)) { 228 kfree(rcvmsg); 229 kfree(spid); 230 return -EFAULT; 231 } 232 233 pr_debug("%s: SCIOCSETSPID: setting channel %d spid to %s\n", 234 sc_adapter[card]->devicename, data->channel, spid); 235 status = send_and_receive(card, CEPID, ceReqTypeCall, 236 ceReqClass0, ceReqCallSetSPID, data->channel, 237 strlen(spid), spid, rcvmsg, SAR_TIMEOUT); 238 if(!status && !(rcvmsg->rsp_status)) { 239 pr_debug("%s: SCIOCSETSPID: command successful\n", 240 sc_adapter[card]->devicename); 241 kfree(rcvmsg); 242 kfree(spid); 243 return 0; 244 } 245 else { 246 pr_debug("%s: SCIOCSETSPID: command failed (status = %d)\n", 247 sc_adapter[card]->devicename, status); 248 kfree(rcvmsg); 249 kfree(spid); 250 return status; 251 } 252 } 253 254 case SCIOCGETDN: 255 { 256 pr_debug("%s: SCIOGETDN: ioctl received\n", 257 sc_adapter[card]->devicename); 258 259 /* 260 * Get the dn from the board 261 */ 262 status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, ceReqCallGetMyNumber, 263 data->channel, 0, NULL, rcvmsg, SAR_TIMEOUT); 264 if (!status) { 265 pr_debug("%s: SCIOCGETDN: command successful\n", 266 sc_adapter[card]->devicename); 267 } 268 else { 269 pr_debug("%s: SCIOCGETDN: command failed (status = %d)\n", 270 sc_adapter[card]->devicename, status); 271 kfree(rcvmsg); 272 return status; 273 } 274 275 dn = kmalloc(SCIOC_DNSIZE, GFP_KERNEL); 276 if (!dn) { 277 kfree(rcvmsg); 278 return -ENOMEM; 279 } 280 strcpy(dn, rcvmsg->msg_data.byte_array); 281 kfree(rcvmsg); 282 283 /* 284 * Package the dn and send to user space 285 */ 286 if (copy_to_user(data->dataptr, dn, SCIOC_DNSIZE)) { 287 kfree(dn); 288 return -EFAULT; 289 } 290 kfree(dn); 291 return 0; 292 } 293 294 case SCIOCSETDN: 295 { 296 pr_debug("%s: SCIOSETDN: ioctl received\n", 297 sc_adapter[card]->devicename); 298 299 dn = kmalloc(SCIOC_DNSIZE, GFP_KERNEL); 300 if (!dn) { 301 kfree(rcvmsg); 302 return -ENOMEM; 303 } 304 /* 305 * Get the spid from user space 306 */ 307 if (copy_from_user(dn, data->dataptr, SCIOC_DNSIZE)) { 308 kfree(rcvmsg); 309 kfree(dn); 310 return -EFAULT; 311 } 312 313 pr_debug("%s: SCIOCSETDN: setting channel %d dn to %s\n", 314 sc_adapter[card]->devicename, data->channel, dn); 315 status = send_and_receive(card, CEPID, ceReqTypeCall, 316 ceReqClass0, ceReqCallSetMyNumber, data->channel, 317 strlen(dn),dn,rcvmsg, SAR_TIMEOUT); 318 if(!status && !(rcvmsg->rsp_status)) { 319 pr_debug("%s: SCIOCSETDN: command successful\n", 320 sc_adapter[card]->devicename); 321 kfree(rcvmsg); 322 kfree(dn); 323 return 0; 324 } 325 else { 326 pr_debug("%s: SCIOCSETDN: command failed (status = %d)\n", 327 sc_adapter[card]->devicename, status); 328 kfree(rcvmsg); 329 kfree(dn); 330 return status; 331 } 332 } 333 334 case SCIOCTRACE: 335 336 pr_debug("%s: SCIOTRACE: ioctl received\n", 337 sc_adapter[card]->devicename); 338/* sc_adapter[card]->trace = !sc_adapter[card]->trace; 339 pr_debug("%s: SCIOCTRACE: tracing turned %s\n", 340 sc_adapter[card]->devicename, 341 sc_adapter[card]->trace ? "ON" : "OFF"); */ 342 break; 343 344 case SCIOCSTAT: 345 { 346 boardInfo *bi; 347 348 pr_debug("%s: SCIOSTAT: ioctl received\n", 349 sc_adapter[card]->devicename); 350 351 bi = kmalloc (sizeof(boardInfo), GFP_KERNEL); 352 if (!bi) { 353 kfree(rcvmsg); 354 return -ENOMEM; 355 } 356 357 kfree(rcvmsg); 358 GetStatus(card, bi); 359 360 if (copy_to_user(data->dataptr, bi, sizeof(boardInfo))) { 361 kfree(bi); 362 return -EFAULT; 363 } 364 365 kfree(bi); 366 return 0; 367 } 368 369 case SCIOCGETSPEED: 370 { 371 pr_debug("%s: SCIOGETSPEED: ioctl received\n", 372 sc_adapter[card]->devicename); 373 374 /* 375 * Get the speed from the board 376 */ 377 status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, 378 ceReqCallGetCallType, data->channel, 0, NULL, rcvmsg, SAR_TIMEOUT); 379 if (!status && !(rcvmsg->rsp_status)) { 380 pr_debug("%s: SCIOCGETSPEED: command successful\n", 381 sc_adapter[card]->devicename); 382 } 383 else { 384 pr_debug("%s: SCIOCGETSPEED: command failed (status = %d)\n", 385 sc_adapter[card]->devicename, status); 386 kfree(rcvmsg); 387 return status; 388 } 389 390 speed = rcvmsg->msg_data.byte_array[0]; 391 392 kfree(rcvmsg); 393 394 /* 395 * Package the switch type and send to user space 396 */ 397 398 if (copy_to_user(data->dataptr, &speed, sizeof(char))) 399 return -EFAULT; 400 401 return 0; 402 } 403 404 case SCIOCSETSPEED: 405 pr_debug("%s: SCIOCSETSPEED: ioctl received\n", 406 sc_adapter[card]->devicename); 407 break; 408 409 case SCIOCLOOPTST: 410 pr_debug("%s: SCIOCLOOPTST: ioctl received\n", 411 sc_adapter[card]->devicename); 412 break; 413 414 default: 415 kfree(rcvmsg); 416 return -1; 417 } 418 419 kfree(rcvmsg); 420 return 0; 421} 422 423static int GetStatus(int card, boardInfo *bi) 424{ 425 RspMessage rcvmsg; 426 int i, status; 427 428 /* 429 * Fill in some of the basic info about the board 430 */ 431 bi->modelid = sc_adapter[card]->model; 432 strcpy(bi->serial_no, sc_adapter[card]->hwconfig.serial_no); 433 strcpy(bi->part_no, sc_adapter[card]->hwconfig.part_no); 434 bi->iobase = sc_adapter[card]->iobase; 435 bi->rambase = sc_adapter[card]->rambase; 436 bi->irq = sc_adapter[card]->interrupt; 437 bi->ramsize = sc_adapter[card]->hwconfig.ram_size; 438 bi->interface = sc_adapter[card]->hwconfig.st_u_sense; 439 strcpy(bi->load_ver, sc_adapter[card]->load_ver); 440 strcpy(bi->proc_ver, sc_adapter[card]->proc_ver); 441 442 /* 443 * Get the current PhyStats and LnkStats 444 */ 445 status = send_and_receive(card, CEPID, ceReqTypePhy, ceReqClass2, 446 ceReqPhyStatus, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT); 447 if(!status) { 448 if(sc_adapter[card]->model < PRI_BOARD) { 449 bi->l1_status = rcvmsg.msg_data.byte_array[2]; 450 for(i = 0 ; i < BRI_CHANNELS ; i++) 451 bi->status.bristats[i].phy_stat = 452 rcvmsg.msg_data.byte_array[i]; 453 } 454 else { 455 bi->l1_status = rcvmsg.msg_data.byte_array[0]; 456 bi->l2_status = rcvmsg.msg_data.byte_array[1]; 457 for(i = 0 ; i < PRI_CHANNELS ; i++) 458 bi->status.pristats[i].phy_stat = 459 rcvmsg.msg_data.byte_array[i+2]; 460 } 461 } 462 463 /* 464 * Get the call types for each channel 465 */ 466 for (i = 0 ; i < sc_adapter[card]->nChannels ; i++) { 467 status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, 468 ceReqCallGetCallType, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT); 469 if(!status) { 470 if (sc_adapter[card]->model == PRI_BOARD) { 471 bi->status.pristats[i].call_type = 472 rcvmsg.msg_data.byte_array[0]; 473 } 474 else { 475 bi->status.bristats[i].call_type = 476 rcvmsg.msg_data.byte_array[0]; 477 } 478 } 479 } 480 481 /* 482 * If PRI, get the call states and service states for each channel 483 */ 484 if (sc_adapter[card]->model == PRI_BOARD) { 485 /* 486 * Get the call states 487 */ 488 status = send_and_receive(card, CEPID, ceReqTypeStat, ceReqClass2, 489 ceReqPhyChCallState, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT); 490 if(!status) { 491 for( i = 0 ; i < PRI_CHANNELS ; i++ ) 492 bi->status.pristats[i].call_state = 493 rcvmsg.msg_data.byte_array[i]; 494 } 495 496 /* 497 * Get the service states 498 */ 499 status = send_and_receive(card, CEPID, ceReqTypeStat, ceReqClass2, 500 ceReqPhyChServState, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT); 501 if(!status) { 502 for( i = 0 ; i < PRI_CHANNELS ; i++ ) 503 bi->status.pristats[i].serv_state = 504 rcvmsg.msg_data.byte_array[i]; 505 } 506 507 /* 508 * Get the link stats for the channels 509 */ 510 for (i = 1 ; i <= PRI_CHANNELS ; i++) { 511 status = send_and_receive(card, CEPID, ceReqTypeLnk, ceReqClass0, 512 ceReqLnkGetStats, i, 0, NULL, &rcvmsg, SAR_TIMEOUT); 513 if (!status) { 514 bi->status.pristats[i-1].link_stats.tx_good = 515 (unsigned long)rcvmsg.msg_data.byte_array[0]; 516 bi->status.pristats[i-1].link_stats.tx_bad = 517 (unsigned long)rcvmsg.msg_data.byte_array[4]; 518 bi->status.pristats[i-1].link_stats.rx_good = 519 (unsigned long)rcvmsg.msg_data.byte_array[8]; 520 bi->status.pristats[i-1].link_stats.rx_bad = 521 (unsigned long)rcvmsg.msg_data.byte_array[12]; 522 } 523 } 524 525 /* 526 * Link stats for the D channel 527 */ 528 status = send_and_receive(card, CEPID, ceReqTypeLnk, ceReqClass0, 529 ceReqLnkGetStats, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT); 530 if (!status) { 531 bi->dch_stats.tx_good = (unsigned long)rcvmsg.msg_data.byte_array[0]; 532 bi->dch_stats.tx_bad = (unsigned long)rcvmsg.msg_data.byte_array[4]; 533 bi->dch_stats.rx_good = (unsigned long)rcvmsg.msg_data.byte_array[8]; 534 bi->dch_stats.rx_bad = (unsigned long)rcvmsg.msg_data.byte_array[12]; 535 } 536 537 return 0; 538 } 539 540 /* 541 * If BRI or POTS, Get SPID, DN and call types for each channel 542 */ 543 544 /* 545 * Get the link stats for the channels 546 */ 547 status = send_and_receive(card, CEPID, ceReqTypeLnk, ceReqClass0, 548 ceReqLnkGetStats, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT); 549 if (!status) { 550 bi->dch_stats.tx_good = (unsigned long)rcvmsg.msg_data.byte_array[0]; 551 bi->dch_stats.tx_bad = (unsigned long)rcvmsg.msg_data.byte_array[4]; 552 bi->dch_stats.rx_good = (unsigned long)rcvmsg.msg_data.byte_array[8]; 553 bi->dch_stats.rx_bad = (unsigned long)rcvmsg.msg_data.byte_array[12]; 554 bi->status.bristats[0].link_stats.tx_good = 555 (unsigned long)rcvmsg.msg_data.byte_array[16]; 556 bi->status.bristats[0].link_stats.tx_bad = 557 (unsigned long)rcvmsg.msg_data.byte_array[20]; 558 bi->status.bristats[0].link_stats.rx_good = 559 (unsigned long)rcvmsg.msg_data.byte_array[24]; 560 bi->status.bristats[0].link_stats.rx_bad = 561 (unsigned long)rcvmsg.msg_data.byte_array[28]; 562 bi->status.bristats[1].link_stats.tx_good = 563 (unsigned long)rcvmsg.msg_data.byte_array[32]; 564 bi->status.bristats[1].link_stats.tx_bad = 565 (unsigned long)rcvmsg.msg_data.byte_array[36]; 566 bi->status.bristats[1].link_stats.rx_good = 567 (unsigned long)rcvmsg.msg_data.byte_array[40]; 568 bi->status.bristats[1].link_stats.rx_bad = 569 (unsigned long)rcvmsg.msg_data.byte_array[44]; 570 } 571 572 /* 573 * Get the SPIDs 574 */ 575 for (i = 0 ; i < BRI_CHANNELS ; i++) { 576 status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, 577 ceReqCallGetSPID, i+1, 0, NULL, &rcvmsg, SAR_TIMEOUT); 578 if (!status) 579 strcpy(bi->status.bristats[i].spid, rcvmsg.msg_data.byte_array); 580 } 581 582 /* 583 * Get the DNs 584 */ 585 for (i = 0 ; i < BRI_CHANNELS ; i++) { 586 status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, 587 ceReqCallGetMyNumber, i+1, 0, NULL, &rcvmsg, SAR_TIMEOUT); 588 if (!status) 589 strcpy(bi->status.bristats[i].dn, rcvmsg.msg_data.byte_array); 590 } 591 592 return 0; 593}