dsp_cmx.c revision 3bd69ad197a4a3d0085a5dc3b5796111bf176b12
1/* 2 * Audio crossconnecting/conferrencing (hardware level). 3 * 4 * Copyright 2002 by Andreas Eversberg (jolly@eversberg.eu) 5 * 6 * This software may be used and distributed according to the terms 7 * of the GNU General Public License, incorporated herein by reference. 8 * 9 */ 10 11/* 12 * The process of adding and removing parties to/from a conference: 13 * 14 * There is a chain of struct dsp_conf which has one or more members in a chain 15 * of struct dsp_conf_member. 16 * 17 * After a party is added, the conference is checked for hardware capability. 18 * Also if a party is removed, the conference is checked again. 19 * 20 * There are 3 different solutions: -1 = software, 0 = hardware-crossconnect 21 * 1-n = hardware-conference. The n will give the conference number. 22 * 23 * Depending on the change after removal or insertion of a party, hardware 24 * commands are given. 25 * 26 * The current solution is stored within the struct dsp_conf entry. 27 */ 28 29/* 30 * HOW THE CMX WORKS: 31 * 32 * There are 3 types of interaction: One member is alone, in this case only 33 * data flow from upper to lower layer is done. 34 * Two members will also exchange their data so they are crossconnected. 35 * Three or more members will be added in a conference and will hear each 36 * other but will not receive their own speech (echo) if not enabled. 37 * 38 * Features of CMX are: 39 * - Crossconnecting or even conference, if more than two members are together. 40 * - Force mixing of transmit data with other crossconnect/conference members. 41 * - Echo generation to benchmark the delay of audio processing. 42 * - Use hardware to minimize cpu load, disable FIFO load and minimize delay. 43 * - Dejittering and clock generation. 44 * 45 * There are 2 buffers: 46 * 47 * 48 * RX-Buffer 49 * R W 50 * | | 51 * ----------------+-------------+------------------- 52 * 53 * The rx-buffer is a ring buffer used to store the received data for each 54 * individual member. This is only the case if data needs to be dejittered 55 * or in case of a conference where different clocks require reclocking. 56 * The transmit-clock (R) will read the buffer. 57 * If the clock overruns the write-pointer, we will have a buffer underrun. 58 * If the write pointer always has a certain distance from the transmit- 59 * clock, we will have a delay. The delay will dynamically be increased and 60 * reduced. 61 * 62 * 63 * TX-Buffer 64 * R W 65 * | | 66 * -----------------+--------+----------------------- 67 * 68 * The tx-buffer is a ring buffer to queue the transmit data from user space 69 * until it will be mixed or sent. There are two pointers, R and W. If the write 70 * pointer W would reach or overrun R, the buffer would overrun. In this case 71 * (some) data is dropped so that it will not overrun. 72 * Additionally a dynamic dejittering can be enabled. this allows data from 73 * user space that have jitter and different clock source. 74 * 75 * 76 * Clock: 77 * 78 * A Clock is not required, if the data source has exactly one clock. In this 79 * case the data source is forwarded to the destination. 80 * 81 * A Clock is required, because the data source 82 * - has multiple clocks. 83 * - has no usable clock due to jitter or packet loss (VoIP). 84 * In this case the system's clock is used. The clock resolution depends on 85 * the jiffie resolution. 86 * 87 * If a member joins a conference: 88 * 89 * - If a member joins, its rx_buff is set to silence and change read pointer 90 * to transmit clock. 91 * 92 * The procedure of received data from card is explained in cmx_receive. 93 * The procedure of received data from user space is explained in cmx_transmit. 94 * The procedure of transmit data to card is cmx_send. 95 * 96 * 97 * Interaction with other features: 98 * 99 * DTMF: 100 * DTMF decoding is done before the data is crossconnected. 101 * 102 * Volume change: 103 * Changing rx-volume is done before the data is crossconnected. The tx-volume 104 * must be changed whenever data is transmitted to the card by the cmx. 105 * 106 * Tones: 107 * If a tone is enabled, it will be processed whenever data is transmitted to 108 * the card. It will replace the tx-data from the user space. 109 * If tones are generated by hardware, this conference member is removed for 110 * this time. 111 * 112 * Disable rx-data: 113 * If cmx is realized in hardware, rx data will be disabled if requested by 114 * the upper layer. If dtmf decoding is done by software and enabled, rx data 115 * will not be diabled but blocked to the upper layer. 116 * 117 * HFC conference engine: 118 * If it is possible to realize all features using hardware, hardware will be 119 * used if not forbidden by control command. Disabling rx-data provides 120 * absolutely traffic free audio processing. (except for the quick 1-frame 121 * upload of a tone loop, only once for a new tone) 122 * 123 */ 124 125/* delay.h is required for hw_lock.h */ 126 127#include <linux/delay.h> 128#include <linux/mISDNif.h> 129#include <linux/mISDNdsp.h> 130#include "core.h" 131#include "dsp.h" 132/* 133 * debugging of multi party conference, 134 * by using conference even with two members 135 */ 136 137/* #define CMX_CONF_DEBUG */ 138 139/*#define CMX_DEBUG * massive read/write pointer output */ 140/*#define CMX_TX_DEBUG * massive read/write on tx-buffer with content */ 141 142static inline int 143count_list_member(struct list_head *head) 144{ 145 int cnt = 0; 146 struct list_head *m; 147 148 list_for_each(m, head) 149 cnt++; 150 return cnt; 151} 152 153/* 154 * debug cmx memory structure 155 */ 156void 157dsp_cmx_debug(struct dsp *dsp) 158{ 159 struct dsp_conf *conf; 160 struct dsp_conf_member *member; 161 struct dsp *odsp; 162 163 printk(KERN_DEBUG "-----Current DSP\n"); 164 list_for_each_entry(odsp, &dsp_ilist, list) { 165 printk(KERN_DEBUG "* %s echo=%d txmix=%d", 166 odsp->name, odsp->echo, odsp->tx_mix); 167 if (odsp->conf) 168 printk(" (Conf %d)", odsp->conf->id); 169 if (dsp == odsp) 170 printk(" *this*"); 171 printk("\n"); 172 } 173 printk(KERN_DEBUG "-----Current Conf:\n"); 174 list_for_each_entry(conf, &conf_ilist, list) { 175 printk(KERN_DEBUG "* Conf %d (%p)\n", conf->id, conf); 176 list_for_each_entry(member, &conf->mlist, list) { 177 printk(KERN_DEBUG 178 " - member = %s (slot_tx %d, bank_tx %d, " 179 "slot_rx %d, bank_rx %d hfc_conf %d)%s\n", 180 member->dsp->name, member->dsp->pcm_slot_tx, 181 member->dsp->pcm_bank_tx, member->dsp->pcm_slot_rx, 182 member->dsp->pcm_bank_rx, member->dsp->hfc_conf, 183 (member->dsp == dsp) ? " *this*" : ""); 184 } 185 } 186 printk(KERN_DEBUG "-----end\n"); 187} 188 189/* 190 * search conference 191 */ 192static struct dsp_conf * 193dsp_cmx_search_conf(u32 id) 194{ 195 struct dsp_conf *conf; 196 197 if (!id) { 198 printk(KERN_WARNING "%s: conference ID is 0.\n", __func__); 199 return NULL; 200 } 201 202 /* search conference */ 203 list_for_each_entry(conf, &conf_ilist, list) 204 if (conf->id == id) 205 return conf; 206 207 return NULL; 208} 209 210 211/* 212 * add member to conference 213 */ 214static int 215dsp_cmx_add_conf_member(struct dsp *dsp, struct dsp_conf *conf) 216{ 217 struct dsp_conf_member *member; 218 219 if (!conf || !dsp) { 220 printk(KERN_WARNING "%s: conf or dsp is 0.\n", __func__); 221 return -EINVAL; 222 } 223 if (dsp->member) { 224 printk(KERN_WARNING "%s: dsp is already member in a conf.\n", 225 __func__); 226 return -EINVAL; 227 } 228 229 if (dsp->conf) { 230 printk(KERN_WARNING "%s: dsp is already in a conf.\n", 231 __func__); 232 return -EINVAL; 233 } 234 235 member = kzalloc(sizeof(struct dsp_conf_member), GFP_ATOMIC); 236 if (!member) { 237 printk(KERN_ERR "kmalloc struct dsp_conf_member failed\n"); 238 return -ENOMEM; 239 } 240 member->dsp = dsp; 241 /* clear rx buffer */ 242 memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff)); 243 dsp->rx_init = 1; /* rx_W and rx_R will be adjusted on first frame */ 244 dsp->rx_W = 0; 245 dsp->rx_R = 0; 246 247 list_add_tail(&member->list, &conf->mlist); 248 249 dsp->conf = conf; 250 dsp->member = member; 251 252 return 0; 253} 254 255 256/* 257 * del member from conference 258 */ 259int 260dsp_cmx_del_conf_member(struct dsp *dsp) 261{ 262 struct dsp_conf_member *member; 263 264 if (!dsp) { 265 printk(KERN_WARNING "%s: dsp is 0.\n", 266 __func__); 267 return -EINVAL; 268 } 269 270 if (!dsp->conf) { 271 printk(KERN_WARNING "%s: dsp is not in a conf.\n", 272 __func__); 273 return -EINVAL; 274 } 275 276 if (list_empty(&dsp->conf->mlist)) { 277 printk(KERN_WARNING "%s: dsp has linked an empty conf.\n", 278 __func__); 279 return -EINVAL; 280 } 281 282 /* find us in conf */ 283 list_for_each_entry(member, &dsp->conf->mlist, list) { 284 if (member->dsp == dsp) { 285 list_del(&member->list); 286 dsp->conf = NULL; 287 dsp->member = NULL; 288 kfree(member); 289 return 0; 290 } 291 } 292 printk(KERN_WARNING 293 "%s: dsp is not present in its own conf_meber list.\n", 294 __func__); 295 296 return -EINVAL; 297} 298 299 300/* 301 * new conference 302 */ 303static struct dsp_conf 304*dsp_cmx_new_conf(u32 id) 305{ 306 struct dsp_conf *conf; 307 308 if (!id) { 309 printk(KERN_WARNING "%s: id is 0.\n", 310 __func__); 311 return NULL; 312 } 313 314 conf = kzalloc(sizeof(struct dsp_conf), GFP_ATOMIC); 315 if (!conf) { 316 printk(KERN_ERR "kmalloc struct dsp_conf failed\n"); 317 return NULL; 318 } 319 INIT_LIST_HEAD(&conf->mlist); 320 conf->id = id; 321 322 list_add_tail(&conf->list, &conf_ilist); 323 324 return conf; 325} 326 327 328/* 329 * del conference 330 */ 331int 332dsp_cmx_del_conf(struct dsp_conf *conf) 333{ 334 if (!conf) { 335 printk(KERN_WARNING "%s: conf is null.\n", 336 __func__); 337 return -EINVAL; 338 } 339 340 if (!list_empty(&conf->mlist)) { 341 printk(KERN_WARNING "%s: conf not empty.\n", 342 __func__); 343 return -EINVAL; 344 } 345 list_del(&conf->list); 346 kfree(conf); 347 348 return 0; 349} 350 351 352/* 353 * send HW message to hfc card 354 */ 355static void 356dsp_cmx_hw_message(struct dsp *dsp, u32 message, u32 param1, u32 param2, 357 u32 param3, u32 param4) 358{ 359 struct mISDN_ctrl_req cq; 360 361 memset(&cq, 0, sizeof(cq)); 362 cq.op = message; 363 cq.p1 = param1 | (param2 << 8); 364 cq.p2 = param3 | (param4 << 8); 365 if (dsp->ch.peer) 366 dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq); 367} 368 369 370/* 371 * do hardware update and set the software/hardware flag 372 * 373 * either a conference or a dsp instance can be given 374 * if only dsp instance is given, the instance is not associated with a conf 375 * and therefore removed. if a conference is given, the dsp is expected to 376 * be member of that conference. 377 */ 378void 379dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp) 380{ 381 struct dsp_conf_member *member, *nextm; 382 struct dsp *finddsp; 383 int memb = 0, i, ii, i1, i2; 384 int freeunits[8]; 385 u_char freeslots[256]; 386 int same_hfc = -1, same_pcm = -1, current_conf = -1, 387 all_conf = 1; 388 389 /* dsp gets updated (no conf) */ 390 if (!conf) { 391 if (!dsp) 392 return; 393 if (dsp_debug & DEBUG_DSP_CMX) 394 printk(KERN_DEBUG "%s checking dsp %s\n", 395 __func__, dsp->name); 396one_member: 397 /* remove HFC conference if enabled */ 398 if (dsp->hfc_conf >= 0) { 399 if (dsp_debug & DEBUG_DSP_CMX) 400 printk(KERN_DEBUG 401 "%s removing %s from HFC conf %d " 402 "because dsp is split\n", __func__, 403 dsp->name, dsp->hfc_conf); 404 dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_CONF_SPLIT, 405 0, 0, 0, 0); 406 dsp->hfc_conf = -1; 407 } 408 /* process hw echo */ 409 if (dsp->features.pcm_banks < 1) 410 return; 411 if (!dsp->echo) { 412 /* NO ECHO: remove PCM slot if assigned */ 413 if (dsp->pcm_slot_tx >= 0 || dsp->pcm_slot_rx >= 0) { 414 if (dsp_debug & DEBUG_DSP_CMX) 415 printk(KERN_DEBUG "%s removing %s from" 416 " PCM slot %d (TX) %d (RX) because" 417 " dsp is split (no echo)\n", 418 __func__, dsp->name, 419 dsp->pcm_slot_tx, dsp->pcm_slot_rx); 420 dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_DISC, 421 0, 0, 0, 0); 422 dsp->pcm_slot_tx = -1; 423 dsp->pcm_bank_tx = -1; 424 dsp->pcm_slot_rx = -1; 425 dsp->pcm_bank_rx = -1; 426 } 427 return; 428 } 429 /* ECHO: already echo */ 430 if (dsp->pcm_slot_tx >= 0 && dsp->pcm_slot_rx < 0 && 431 dsp->pcm_bank_tx == 2 && dsp->pcm_bank_rx == 2) 432 return; 433 /* ECHO: if slot already assigned */ 434 if (dsp->pcm_slot_tx >= 0) { 435 dsp->pcm_slot_rx = dsp->pcm_slot_tx; 436 dsp->pcm_bank_tx = 2; /* 2 means loop */ 437 dsp->pcm_bank_rx = 2; 438 if (dsp_debug & DEBUG_DSP_CMX) 439 printk(KERN_DEBUG 440 "%s refresh %s for echo using slot %d\n", 441 __func__, dsp->name, 442 dsp->pcm_slot_tx); 443 dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN, 444 dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2); 445 return; 446 } 447 /* ECHO: find slot */ 448 dsp->pcm_slot_tx = -1; 449 dsp->pcm_slot_rx = -1; 450 memset(freeslots, 1, sizeof(freeslots)); 451 list_for_each_entry(finddsp, &dsp_ilist, list) { 452 if (finddsp->features.pcm_id == dsp->features.pcm_id) { 453 if (finddsp->pcm_slot_rx >= 0 && 454 finddsp->pcm_slot_rx < sizeof(freeslots)) 455 freeslots[finddsp->pcm_slot_rx] = 0; 456 if (finddsp->pcm_slot_tx >= 0 && 457 finddsp->pcm_slot_tx < sizeof(freeslots)) 458 freeslots[finddsp->pcm_slot_tx] = 0; 459 } 460 } 461 i = 0; 462 ii = dsp->features.pcm_slots; 463 while (i < ii) { 464 if (freeslots[i]) 465 break; 466 i++; 467 } 468 if (i == ii) { 469 if (dsp_debug & DEBUG_DSP_CMX) 470 printk(KERN_DEBUG 471 "%s no slot available for echo\n", 472 __func__); 473 /* no more slots available */ 474 return; 475 } 476 /* assign free slot */ 477 dsp->pcm_slot_tx = i; 478 dsp->pcm_slot_rx = i; 479 dsp->pcm_bank_tx = 2; /* loop */ 480 dsp->pcm_bank_rx = 2; 481 if (dsp_debug & DEBUG_DSP_CMX) 482 printk(KERN_DEBUG 483 "%s assign echo for %s using slot %d\n", 484 __func__, dsp->name, dsp->pcm_slot_tx); 485 dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN, 486 dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2); 487 return; 488 } 489 490 /* conf gets updated (all members) */ 491 if (dsp_debug & DEBUG_DSP_CMX) 492 printk(KERN_DEBUG "%s checking conference %d\n", 493 __func__, conf->id); 494 495 if (list_empty(&conf->mlist)) { 496 printk(KERN_ERR "%s: conference whithout members\n", 497 __func__); 498 return; 499 } 500 member = list_entry(conf->mlist.next, struct dsp_conf_member, list); 501 same_hfc = member->dsp->features.hfc_id; 502 same_pcm = member->dsp->features.pcm_id; 503 /* check all members in our conference */ 504 list_for_each_entry(member, &conf->mlist, list) { 505 /* check if member uses mixing */ 506 if (member->dsp->tx_mix) { 507 if (dsp_debug & DEBUG_DSP_CMX) 508 printk(KERN_DEBUG 509 "%s dsp %s cannot form a conf, because " 510 "tx_mix is turned on\n", __func__, 511 member->dsp->name); 512conf_software: 513 list_for_each_entry(member, &conf->mlist, list) { 514 dsp = member->dsp; 515 /* remove HFC conference if enabled */ 516 if (dsp->hfc_conf >= 0) { 517 if (dsp_debug & DEBUG_DSP_CMX) 518 printk(KERN_DEBUG 519 "%s removing %s from HFC " 520 "conf %d because not " 521 "possible with hardware\n", 522 __func__, 523 dsp->name, 524 dsp->hfc_conf); 525 dsp_cmx_hw_message(dsp, 526 MISDN_CTRL_HFC_CONF_SPLIT, 527 0, 0, 0, 0); 528 dsp->hfc_conf = -1; 529 } 530 /* remove PCM slot if assigned */ 531 if (dsp->pcm_slot_tx >= 0 || 532 dsp->pcm_slot_rx >= 0) { 533 if (dsp_debug & DEBUG_DSP_CMX) 534 printk(KERN_DEBUG "%s removing " 535 "%s from PCM slot %d (TX)" 536 " slot %d (RX) because not" 537 " possible with hardware\n", 538 __func__, 539 dsp->name, 540 dsp->pcm_slot_tx, 541 dsp->pcm_slot_rx); 542 dsp_cmx_hw_message(dsp, 543 MISDN_CTRL_HFC_PCM_DISC, 544 0, 0, 0, 0); 545 dsp->pcm_slot_tx = -1; 546 dsp->pcm_bank_tx = -1; 547 dsp->pcm_slot_rx = -1; 548 dsp->pcm_bank_rx = -1; 549 } 550 } 551 conf->hardware = 0; 552 conf->software = 1; 553 return; 554 } 555 /* check if member has echo turned on */ 556 if (member->dsp->echo) { 557 if (dsp_debug & DEBUG_DSP_CMX) 558 printk(KERN_DEBUG 559 "%s dsp %s cannot form a conf, because " 560 "echo is turned on\n", __func__, 561 member->dsp->name); 562 goto conf_software; 563 } 564 /* check if member has tx_mix turned on */ 565 if (member->dsp->tx_mix) { 566 if (dsp_debug & DEBUG_DSP_CMX) 567 printk(KERN_DEBUG 568 "%s dsp %s cannot form a conf, because " 569 "tx_mix is turned on\n", 570 __func__, member->dsp->name); 571 goto conf_software; 572 } 573 /* check if member changes volume at an not suppoted level */ 574 if (member->dsp->tx_volume) { 575 if (dsp_debug & DEBUG_DSP_CMX) 576 printk(KERN_DEBUG 577 "%s dsp %s cannot form a conf, because " 578 "tx_volume is changed\n", 579 __func__, member->dsp->name); 580 goto conf_software; 581 } 582 if (member->dsp->rx_volume) { 583 if (dsp_debug & DEBUG_DSP_CMX) 584 printk(KERN_DEBUG 585 "%s dsp %s cannot form a conf, because " 586 "rx_volume is changed\n", 587 __func__, member->dsp->name); 588 goto conf_software; 589 } 590 /* check if tx-data turned on */ 591 if (member->dsp->tx_data) { 592 if (dsp_debug & DEBUG_DSP_CMX) 593 printk(KERN_DEBUG 594 "%s dsp %s cannot form a conf, because " 595 "tx_data is turned on\n", 596 __func__, member->dsp->name); 597 goto conf_software; 598 } 599 /* check if pipeline exists */ 600 if (member->dsp->pipeline.inuse) { 601 if (dsp_debug & DEBUG_DSP_CMX) 602 printk(KERN_DEBUG 603 "%s dsp %s cannot form a conf, because " 604 "pipeline exists\n", __func__, 605 member->dsp->name); 606 goto conf_software; 607 } 608 /* check if encryption is enabled */ 609 if (member->dsp->bf_enable) { 610 if (dsp_debug & DEBUG_DSP_CMX) 611 printk(KERN_DEBUG "%s dsp %s cannot form a " 612 "conf, because encryption is enabled\n", 613 __func__, member->dsp->name); 614 goto conf_software; 615 } 616 /* check if member is on a card with PCM support */ 617 if (member->dsp->features.pcm_id < 0) { 618 if (dsp_debug & DEBUG_DSP_CMX) 619 printk(KERN_DEBUG 620 "%s dsp %s cannot form a conf, because " 621 "dsp has no PCM bus\n", 622 __func__, member->dsp->name); 623 goto conf_software; 624 } 625 /* check if relations are on the same PCM bus */ 626 if (member->dsp->features.pcm_id != same_pcm) { 627 if (dsp_debug & DEBUG_DSP_CMX) 628 printk(KERN_DEBUG 629 "%s dsp %s cannot form a conf, because " 630 "dsp is on a different PCM bus than the " 631 "first dsp\n", 632 __func__, member->dsp->name); 633 goto conf_software; 634 } 635 /* determine if members are on the same hfc chip */ 636 if (same_hfc != member->dsp->features.hfc_id) 637 same_hfc = -1; 638 /* if there are members already in a conference */ 639 if (current_conf < 0 && member->dsp->hfc_conf >= 0) 640 current_conf = member->dsp->hfc_conf; 641 /* if any member is not in a conference */ 642 if (member->dsp->hfc_conf < 0) 643 all_conf = 0; 644 645 memb++; 646 } 647 648 /* if no member, this is an error */ 649 if (memb < 1) 650 return; 651 652 /* one member */ 653 if (memb == 1) { 654 if (dsp_debug & DEBUG_DSP_CMX) 655 printk(KERN_DEBUG 656 "%s conf %d cannot form a HW conference, " 657 "because dsp is alone\n", __func__, conf->id); 658 conf->hardware = 0; 659 conf->software = 0; 660 member = list_entry(conf->mlist.next, struct dsp_conf_member, 661 list); 662 dsp = member->dsp; 663 goto one_member; 664 } 665 666 /* 667 * ok, now we are sure that all members are on the same pcm. 668 * now we will see if we have only two members, so we can do 669 * crossconnections, which don't have any limitations. 670 */ 671 672 /* if we have only two members */ 673 if (memb == 2) { 674 member = list_entry(conf->mlist.next, struct dsp_conf_member, 675 list); 676 nextm = list_entry(member->list.next, struct dsp_conf_member, 677 list); 678 /* remove HFC conference if enabled */ 679 if (member->dsp->hfc_conf >= 0) { 680 if (dsp_debug & DEBUG_DSP_CMX) 681 printk(KERN_DEBUG 682 "%s removing %s from HFC conf %d because " 683 "two parties require only a PCM slot\n", 684 __func__, member->dsp->name, 685 member->dsp->hfc_conf); 686 dsp_cmx_hw_message(member->dsp, 687 MISDN_CTRL_HFC_CONF_SPLIT, 0, 0, 0, 0); 688 member->dsp->hfc_conf = -1; 689 } 690 if (nextm->dsp->hfc_conf >= 0) { 691 if (dsp_debug & DEBUG_DSP_CMX) 692 printk(KERN_DEBUG 693 "%s removing %s from HFC conf %d because " 694 "two parties require only a PCM slot\n", 695 __func__, nextm->dsp->name, 696 nextm->dsp->hfc_conf); 697 dsp_cmx_hw_message(nextm->dsp, 698 MISDN_CTRL_HFC_CONF_SPLIT, 0, 0, 0, 0); 699 nextm->dsp->hfc_conf = -1; 700 } 701 /* if members have two banks (and not on the same chip) */ 702 if (member->dsp->features.pcm_banks > 1 && 703 nextm->dsp->features.pcm_banks > 1 && 704 member->dsp->features.hfc_id != 705 nextm->dsp->features.hfc_id) { 706 /* if both members have same slots with crossed banks */ 707 if (member->dsp->pcm_slot_tx >= 0 && 708 member->dsp->pcm_slot_rx >= 0 && 709 nextm->dsp->pcm_slot_tx >= 0 && 710 nextm->dsp->pcm_slot_rx >= 0 && 711 nextm->dsp->pcm_slot_tx == 712 member->dsp->pcm_slot_rx && 713 nextm->dsp->pcm_slot_rx == 714 member->dsp->pcm_slot_tx && 715 nextm->dsp->pcm_slot_tx == 716 member->dsp->pcm_slot_tx && 717 member->dsp->pcm_bank_tx != 718 member->dsp->pcm_bank_rx && 719 nextm->dsp->pcm_bank_tx != 720 nextm->dsp->pcm_bank_rx) { 721 /* all members have same slot */ 722 if (dsp_debug & DEBUG_DSP_CMX) 723 printk(KERN_DEBUG 724 "%s dsp %s & %s stay joined on " 725 "PCM slot %d bank %d (TX) bank %d " 726 "(RX) (on different chips)\n", 727 __func__, 728 member->dsp->name, 729 nextm->dsp->name, 730 member->dsp->pcm_slot_tx, 731 member->dsp->pcm_bank_tx, 732 member->dsp->pcm_bank_rx); 733 conf->hardware = 0; 734 conf->software = 1; 735 return; 736 } 737 /* find a new slot */ 738 memset(freeslots, 1, sizeof(freeslots)); 739 list_for_each_entry(dsp, &dsp_ilist, list) { 740 if (dsp != member->dsp && 741 dsp != nextm->dsp && 742 member->dsp->features.pcm_id == 743 dsp->features.pcm_id) { 744 if (dsp->pcm_slot_rx >= 0 && 745 dsp->pcm_slot_rx < 746 sizeof(freeslots)) 747 freeslots[dsp->pcm_slot_rx] = 0; 748 if (dsp->pcm_slot_tx >= 0 && 749 dsp->pcm_slot_tx < 750 sizeof(freeslots)) 751 freeslots[dsp->pcm_slot_tx] = 0; 752 } 753 } 754 i = 0; 755 ii = member->dsp->features.pcm_slots; 756 while (i < ii) { 757 if (freeslots[i]) 758 break; 759 i++; 760 } 761 if (i == ii) { 762 if (dsp_debug & DEBUG_DSP_CMX) 763 printk(KERN_DEBUG 764 "%s no slot available for " 765 "%s & %s\n", __func__, 766 member->dsp->name, 767 nextm->dsp->name); 768 /* no more slots available */ 769 goto conf_software; 770 } 771 /* assign free slot */ 772 member->dsp->pcm_slot_tx = i; 773 member->dsp->pcm_slot_rx = i; 774 nextm->dsp->pcm_slot_tx = i; 775 nextm->dsp->pcm_slot_rx = i; 776 member->dsp->pcm_bank_rx = 0; 777 member->dsp->pcm_bank_tx = 1; 778 nextm->dsp->pcm_bank_rx = 1; 779 nextm->dsp->pcm_bank_tx = 0; 780 if (dsp_debug & DEBUG_DSP_CMX) 781 printk(KERN_DEBUG 782 "%s adding %s & %s to new PCM slot %d " 783 "(TX and RX on different chips) because " 784 "both members have not same slots\n", 785 __func__, 786 member->dsp->name, 787 nextm->dsp->name, 788 member->dsp->pcm_slot_tx); 789 dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN, 790 member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx, 791 member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx); 792 dsp_cmx_hw_message(nextm->dsp, MISDN_CTRL_HFC_PCM_CONN, 793 nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx, 794 nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx); 795 conf->hardware = 1; 796 conf->software = 0; 797 return; 798 /* if members have one bank (or on the same chip) */ 799 } else { 800 /* if both members have different crossed slots */ 801 if (member->dsp->pcm_slot_tx >= 0 && 802 member->dsp->pcm_slot_rx >= 0 && 803 nextm->dsp->pcm_slot_tx >= 0 && 804 nextm->dsp->pcm_slot_rx >= 0 && 805 nextm->dsp->pcm_slot_tx == 806 member->dsp->pcm_slot_rx && 807 nextm->dsp->pcm_slot_rx == 808 member->dsp->pcm_slot_tx && 809 member->dsp->pcm_slot_tx != 810 member->dsp->pcm_slot_rx && 811 member->dsp->pcm_bank_tx == 0 && 812 member->dsp->pcm_bank_rx == 0 && 813 nextm->dsp->pcm_bank_tx == 0 && 814 nextm->dsp->pcm_bank_rx == 0) { 815 /* all members have same slot */ 816 if (dsp_debug & DEBUG_DSP_CMX) 817 printk(KERN_DEBUG 818 "%s dsp %s & %s stay joined on PCM " 819 "slot %d (TX) %d (RX) on same chip " 820 "or one bank PCM)\n", __func__, 821 member->dsp->name, 822 nextm->dsp->name, 823 member->dsp->pcm_slot_tx, 824 member->dsp->pcm_slot_rx); 825 conf->hardware = 0; 826 conf->software = 1; 827 return; 828 } 829 /* find two new slot */ 830 memset(freeslots, 1, sizeof(freeslots)); 831 list_for_each_entry(dsp, &dsp_ilist, list) { 832 if (dsp != member->dsp && 833 dsp != nextm->dsp && 834 member->dsp->features.pcm_id == 835 dsp->features.pcm_id) { 836 if (dsp->pcm_slot_rx >= 0 && 837 dsp->pcm_slot_rx < 838 sizeof(freeslots)) 839 freeslots[dsp->pcm_slot_rx] = 0; 840 if (dsp->pcm_slot_tx >= 0 && 841 dsp->pcm_slot_tx < 842 sizeof(freeslots)) 843 freeslots[dsp->pcm_slot_tx] = 0; 844 } 845 } 846 i1 = 0; 847 ii = member->dsp->features.pcm_slots; 848 while (i1 < ii) { 849 if (freeslots[i1]) 850 break; 851 i1++; 852 } 853 if (i1 == ii) { 854 if (dsp_debug & DEBUG_DSP_CMX) 855 printk(KERN_DEBUG 856 "%s no slot available " 857 "for %s & %s\n", __func__, 858 member->dsp->name, 859 nextm->dsp->name); 860 /* no more slots available */ 861 goto conf_software; 862 } 863 i2 = i1+1; 864 while (i2 < ii) { 865 if (freeslots[i2]) 866 break; 867 i2++; 868 } 869 if (i2 == ii) { 870 if (dsp_debug & DEBUG_DSP_CMX) 871 printk(KERN_DEBUG 872 "%s no slot available " 873 "for %s & %s\n", 874 __func__, 875 member->dsp->name, 876 nextm->dsp->name); 877 /* no more slots available */ 878 goto conf_software; 879 } 880 /* assign free slots */ 881 member->dsp->pcm_slot_tx = i1; 882 member->dsp->pcm_slot_rx = i2; 883 nextm->dsp->pcm_slot_tx = i2; 884 nextm->dsp->pcm_slot_rx = i1; 885 member->dsp->pcm_bank_rx = 0; 886 member->dsp->pcm_bank_tx = 0; 887 nextm->dsp->pcm_bank_rx = 0; 888 nextm->dsp->pcm_bank_tx = 0; 889 if (dsp_debug & DEBUG_DSP_CMX) 890 printk(KERN_DEBUG 891 "%s adding %s & %s to new PCM slot %d " 892 "(TX) %d (RX) on same chip or one bank " 893 "PCM, because both members have not " 894 "crossed slots\n", __func__, 895 member->dsp->name, 896 nextm->dsp->name, 897 member->dsp->pcm_slot_tx, 898 member->dsp->pcm_slot_rx); 899 dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN, 900 member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx, 901 member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx); 902 dsp_cmx_hw_message(nextm->dsp, MISDN_CTRL_HFC_PCM_CONN, 903 nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx, 904 nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx); 905 conf->hardware = 1; 906 conf->software = 0; 907 return; 908 } 909 } 910 911 /* 912 * if we have more than two, we may check if we have a conference 913 * unit available on the chip. also all members must be on the same 914 */ 915 916 /* if not the same HFC chip */ 917 if (same_hfc < 0) { 918 if (dsp_debug & DEBUG_DSP_CMX) 919 printk(KERN_DEBUG 920 "%s conference %d cannot be formed, because " 921 "members are on different chips or not " 922 "on HFC chip\n", 923 __func__, conf->id); 924 goto conf_software; 925 } 926 927 /* for more than two members.. */ 928 929 /* in case of hdlc, we change to software */ 930 if (dsp->hdlc) 931 goto conf_software; 932 933 /* if all members already have the same conference */ 934 if (all_conf) 935 return; 936 937 /* 938 * if there is an existing conference, but not all members have joined 939 */ 940 if (current_conf >= 0) { 941join_members: 942 list_for_each_entry(member, &conf->mlist, list) { 943 /* join to current conference */ 944 if (member->dsp->hfc_conf == current_conf) 945 continue; 946 /* get a free timeslot first */ 947 memset(freeslots, 1, sizeof(freeslots)); 948 list_for_each_entry(dsp, &dsp_ilist, list) { 949 /* 950 * not checking current member, because 951 * slot will be overwritten. 952 */ 953 if ( 954 dsp != member->dsp && 955 /* dsp must be on the same PCM */ 956 member->dsp->features.pcm_id == 957 dsp->features.pcm_id) { 958 /* dsp must be on a slot */ 959 if (dsp->pcm_slot_tx >= 0 && 960 dsp->pcm_slot_tx < 961 sizeof(freeslots)) 962 freeslots[dsp->pcm_slot_tx] = 0; 963 if (dsp->pcm_slot_rx >= 0 && 964 dsp->pcm_slot_rx < 965 sizeof(freeslots)) 966 freeslots[dsp->pcm_slot_rx] = 0; 967 } 968 } 969 i = 0; 970 ii = member->dsp->features.pcm_slots; 971 while (i < ii) { 972 if (freeslots[i]) 973 break; 974 i++; 975 } 976 if (i == ii) { 977 /* no more slots available */ 978 if (dsp_debug & DEBUG_DSP_CMX) 979 printk(KERN_DEBUG 980 "%s conference %d cannot be formed," 981 " because no slot free\n", 982 __func__, conf->id); 983 goto conf_software; 984 } 985 if (dsp_debug & DEBUG_DSP_CMX) 986 printk(KERN_DEBUG 987 "%s changing dsp %s to HW conference " 988 "%d slot %d\n", __func__, 989 member->dsp->name, current_conf, i); 990 /* assign free slot & set PCM & join conf */ 991 member->dsp->pcm_slot_tx = i; 992 member->dsp->pcm_slot_rx = i; 993 member->dsp->pcm_bank_tx = 2; /* loop */ 994 member->dsp->pcm_bank_rx = 2; 995 member->dsp->hfc_conf = current_conf; 996 dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN, 997 i, 2, i, 2); 998 dsp_cmx_hw_message(member->dsp, 999 MISDN_CTRL_HFC_CONF_JOIN, current_conf, 0, 0, 0); 1000 } 1001 return; 1002 } 1003 1004 /* 1005 * no member is in a conference yet, so we find a free one 1006 */ 1007 memset(freeunits, 1, sizeof(freeunits)); 1008 list_for_each_entry(dsp, &dsp_ilist, list) { 1009 /* dsp must be on the same chip */ 1010 if (dsp->features.hfc_id == same_hfc && 1011 /* dsp must have joined a HW conference */ 1012 dsp->hfc_conf >= 0 && 1013 /* slot must be within range */ 1014 dsp->hfc_conf < 8) 1015 freeunits[dsp->hfc_conf] = 0; 1016 } 1017 i = 0; 1018 ii = 8; 1019 while (i < ii) { 1020 if (freeunits[i]) 1021 break; 1022 i++; 1023 } 1024 if (i == ii) { 1025 /* no more conferences available */ 1026 if (dsp_debug & DEBUG_DSP_CMX) 1027 printk(KERN_DEBUG 1028 "%s conference %d cannot be formed, because " 1029 "no conference number free\n", 1030 __func__, conf->id); 1031 goto conf_software; 1032 } 1033 /* join all members */ 1034 current_conf = i; 1035 goto join_members; 1036} 1037 1038 1039/* 1040 * conf_id != 0: join or change conference 1041 * conf_id == 0: split from conference if not already 1042 */ 1043int 1044dsp_cmx_conf(struct dsp *dsp, u32 conf_id) 1045{ 1046 int err; 1047 struct dsp_conf *conf; 1048 struct dsp_conf_member *member; 1049 1050 /* if conference doesn't change */ 1051 if (dsp->conf_id == conf_id) 1052 return 0; 1053 1054 /* first remove us from current conf */ 1055 if (dsp->conf_id) { 1056 if (dsp_debug & DEBUG_DSP_CMX) 1057 printk(KERN_DEBUG "removing us from conference %d\n", 1058 dsp->conf->id); 1059 /* remove us from conf */ 1060 conf = dsp->conf; 1061 err = dsp_cmx_del_conf_member(dsp); 1062 if (err) 1063 return err; 1064 dsp->conf_id = 0; 1065 1066 /* update hardware */ 1067 dsp_cmx_hardware(NULL, dsp); 1068 1069 /* conf now empty? */ 1070 if (list_empty(&conf->mlist)) { 1071 if (dsp_debug & DEBUG_DSP_CMX) 1072 printk(KERN_DEBUG 1073 "conference is empty, so we remove it.\n"); 1074 err = dsp_cmx_del_conf(conf); 1075 if (err) 1076 return err; 1077 } else { 1078 /* update members left on conf */ 1079 dsp_cmx_hardware(conf, NULL); 1080 } 1081 } 1082 1083 /* if split */ 1084 if (!conf_id) 1085 return 0; 1086 1087 /* now add us to conf */ 1088 if (dsp_debug & DEBUG_DSP_CMX) 1089 printk(KERN_DEBUG "searching conference %d\n", 1090 conf_id); 1091 conf = dsp_cmx_search_conf(conf_id); 1092 if (!conf) { 1093 if (dsp_debug & DEBUG_DSP_CMX) 1094 printk(KERN_DEBUG 1095 "conference doesn't exist yet, creating.\n"); 1096 /* the conference doesn't exist, so we create */ 1097 conf = dsp_cmx_new_conf(conf_id); 1098 if (!conf) 1099 return -EINVAL; 1100 } else if (!list_empty(&conf->mlist)) { 1101 member = list_entry(conf->mlist.next, struct dsp_conf_member, 1102 list); 1103 if (dsp->hdlc && !member->dsp->hdlc) { 1104 if (dsp_debug & DEBUG_DSP_CMX) 1105 printk(KERN_DEBUG 1106 "cannot join transparent conference.\n"); 1107 return -EINVAL; 1108 } 1109 if (!dsp->hdlc && member->dsp->hdlc) { 1110 if (dsp_debug & DEBUG_DSP_CMX) 1111 printk(KERN_DEBUG 1112 "cannot join hdlc conference.\n"); 1113 return -EINVAL; 1114 } 1115 } 1116 /* add conference member */ 1117 err = dsp_cmx_add_conf_member(dsp, conf); 1118 if (err) 1119 return err; 1120 dsp->conf_id = conf_id; 1121 1122 /* if we are alone, we do nothing! */ 1123 if (list_empty(&conf->mlist)) { 1124 if (dsp_debug & DEBUG_DSP_CMX) 1125 printk(KERN_DEBUG 1126 "we are alone in this conference, so exit.\n"); 1127 /* update hardware */ 1128 dsp_cmx_hardware(NULL, dsp); 1129 return 0; 1130 } 1131 1132 /* update members on conf */ 1133 dsp_cmx_hardware(conf, NULL); 1134 1135 return 0; 1136} 1137 1138 1139/* 1140 * audio data is received from card 1141 */ 1142void 1143dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb) 1144{ 1145 u8 *d, *p; 1146 int len = skb->len; 1147 struct mISDNhead *hh = mISDN_HEAD_P(skb); 1148 int w, i, ii; 1149 1150 /* check if we have sompen */ 1151 if (len < 1) 1152 return; 1153 1154 /* half of the buffer should be larger than maximum packet size */ 1155 if (len >= CMX_BUFF_HALF) { 1156 printk(KERN_ERR 1157 "%s line %d: packet from card is too large (%d bytes). " 1158 "please make card send smaller packets OR increase " 1159 "CMX_BUFF_SIZE\n", __FILE__, __LINE__, len); 1160 return; 1161 } 1162 1163 /* 1164 * initialize pointers if not already - 1165 * also add delay if requested by PH_SIGNAL 1166 */ 1167 if (dsp->rx_init) { 1168 dsp->rx_init = 0; 1169 if (dsp->features.unordered) { 1170 dsp->rx_R = (hh->id & CMX_BUFF_MASK); 1171 if (dsp->cmx_delay) 1172 dsp->rx_W = (dsp->rx_R + dsp->cmx_delay) 1173 & CMX_BUFF_MASK; 1174 else 1175 dsp->rx_W = (dsp->rx_R + (dsp_poll >> 1)) 1176 & CMX_BUFF_MASK; 1177 } else { 1178 dsp->rx_R = 0; 1179 if (dsp->cmx_delay) 1180 dsp->rx_W = dsp->cmx_delay; 1181 else 1182 dsp->rx_W = dsp_poll >> 1; 1183 } 1184 } 1185 /* if frame contains time code, write directly */ 1186 if (dsp->features.unordered) { 1187 dsp->rx_W = (hh->id & CMX_BUFF_MASK); 1188 /* printk(KERN_DEBUG "%s %08x\n", dsp->name, hh->id); */ 1189 } 1190 /* 1191 * if we underrun (or maybe overrun), 1192 * we set our new read pointer, and write silence to buffer 1193 */ 1194 if (((dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK) >= CMX_BUFF_HALF) { 1195 if (dsp_debug & DEBUG_DSP_CLOCK) 1196 printk(KERN_DEBUG 1197 "cmx_receive(dsp=%lx): UNDERRUN (or overrun the " 1198 "maximum delay), adjusting read pointer! " 1199 "(inst %s)\n", (u_long)dsp, dsp->name); 1200 /* flush rx buffer and set delay to dsp_poll / 2 */ 1201 if (dsp->features.unordered) { 1202 dsp->rx_R = (hh->id & CMX_BUFF_MASK); 1203 if (dsp->cmx_delay) 1204 dsp->rx_W = (dsp->rx_R + dsp->cmx_delay) 1205 & CMX_BUFF_MASK; 1206 dsp->rx_W = (dsp->rx_R + (dsp_poll >> 1)) 1207 & CMX_BUFF_MASK; 1208 } else { 1209 dsp->rx_R = 0; 1210 if (dsp->cmx_delay) 1211 dsp->rx_W = dsp->cmx_delay; 1212 else 1213 dsp->rx_W = dsp_poll >> 1; 1214 } 1215 memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff)); 1216 } 1217 /* if we have reached double delay, jump back to middle */ 1218 if (dsp->cmx_delay) 1219 if (((dsp->rx_W - dsp->rx_R) & CMX_BUFF_MASK) >= 1220 (dsp->cmx_delay << 1)) { 1221 if (dsp_debug & DEBUG_DSP_CLOCK) 1222 printk(KERN_DEBUG 1223 "cmx_receive(dsp=%lx): OVERRUN (because " 1224 "twice the delay is reached), adjusting " 1225 "read pointer! (inst %s)\n", 1226 (u_long)dsp, dsp->name); 1227 /* flush buffer */ 1228 if (dsp->features.unordered) { 1229 dsp->rx_R = (hh->id & CMX_BUFF_MASK); 1230 dsp->rx_W = (dsp->rx_R + dsp->cmx_delay) 1231 & CMX_BUFF_MASK; 1232 } else { 1233 dsp->rx_R = 0; 1234 dsp->rx_W = dsp->cmx_delay; 1235 } 1236 memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff)); 1237 } 1238 1239 /* show where to write */ 1240#ifdef CMX_DEBUG 1241 printk(KERN_DEBUG 1242 "cmx_receive(dsp=%lx): rx_R(dsp)=%05x rx_W(dsp)=%05x len=%d %s\n", 1243 (u_long)dsp, dsp->rx_R, dsp->rx_W, len, dsp->name); 1244#endif 1245 1246 /* write data into rx_buffer */ 1247 p = skb->data; 1248 d = dsp->rx_buff; 1249 w = dsp->rx_W; 1250 i = 0; 1251 ii = len; 1252 while (i < ii) { 1253 d[w++ & CMX_BUFF_MASK] = *p++; 1254 i++; 1255 } 1256 1257 /* increase write-pointer */ 1258 dsp->rx_W = ((dsp->rx_W+len) & CMX_BUFF_MASK); 1259} 1260 1261 1262/* 1263 * send (mixed) audio data to card and control jitter 1264 */ 1265static void 1266dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members) 1267{ 1268 struct dsp_conf *conf = dsp->conf; 1269 struct dsp *member, *other; 1270 register s32 sample; 1271 u8 *d, *p, *q, *o_q; 1272 struct sk_buff *nskb, *txskb; 1273 int r, rr, t, tt, o_r, o_rr; 1274 int preload = 0; 1275 struct mISDNhead *hh, *thh; 1276 1277 /* don't process if: */ 1278 if (!dsp->b_active) { /* if not active */ 1279 dsp->last_tx = 0; 1280 return; 1281 } 1282 if (dsp->pcm_slot_tx >= 0 && /* connected to pcm slot */ 1283 dsp->tx_R == dsp->tx_W && /* AND no tx-data */ 1284 !(dsp->tone.tone && dsp->tone.software)) { /* AND not soft tones */ 1285 dsp->last_tx = 0; 1286 return; 1287 } 1288 1289#ifdef CMX_DEBUG 1290 printk(KERN_DEBUG 1291 "SEND members=%d dsp=%s, conf=%p, rx_R=%05x rx_W=%05x\n", 1292 members, dsp->name, conf, dsp->rx_R, dsp->rx_W); 1293#endif 1294 1295 /* preload if we have delay set */ 1296 if (dsp->cmx_delay && !dsp->last_tx) { 1297 preload = len; 1298 if (preload < 128) 1299 preload = 128; 1300 } 1301 1302 /* PREPARE RESULT */ 1303 nskb = mI_alloc_skb(len + preload, GFP_ATOMIC); 1304 if (!nskb) { 1305 printk(KERN_ERR 1306 "FATAL ERROR in mISDN_dsp.o: cannot alloc %d bytes\n", 1307 len + preload); 1308 return; 1309 } 1310 hh = mISDN_HEAD_P(nskb); 1311 hh->prim = PH_DATA_REQ; 1312 hh->id = 0; 1313 dsp->last_tx = 1; 1314 1315 /* set pointers, indexes and stuff */ 1316 member = dsp; 1317 p = dsp->tx_buff; /* transmit data */ 1318 q = dsp->rx_buff; /* received data */ 1319 d = skb_put(nskb, preload + len); /* result */ 1320 t = dsp->tx_R; /* tx-pointers */ 1321 tt = dsp->tx_W; 1322 r = dsp->rx_R; /* rx-pointers */ 1323 rr = (r + len) & CMX_BUFF_MASK; 1324 1325 /* preload with silence, if required */ 1326 if (preload) { 1327 memset(d, dsp_silence, preload); 1328 d += preload; 1329 } 1330 1331 /* PROCESS TONES/TX-DATA ONLY */ 1332 if (dsp->tone.tone && dsp->tone.software) { 1333 /* -> copy tone */ 1334 dsp_tone_copy(dsp, d, len); 1335 dsp->tx_R = 0; /* clear tx buffer */ 1336 dsp->tx_W = 0; 1337 goto send_packet; 1338 } 1339 /* if we have tx-data but do not use mixing */ 1340 if (!dsp->tx_mix && t != tt) { 1341 /* -> send tx-data and continue when not enough */ 1342#ifdef CMX_TX_DEBUG 1343 sprintf(debugbuf, "TX sending (%04x-%04x)%p: ", t, tt, p); 1344#endif 1345 while (r != rr && t != tt) { 1346#ifdef CMX_TX_DEBUG 1347 if (strlen(debugbuf) < 48) 1348 sprintf(debugbuf+strlen(debugbuf), " %02x", p[t]); 1349#endif 1350 *d++ = p[t]; /* write tx_buff */ 1351 t = (t+1) & CMX_BUFF_MASK; 1352 r = (r+1) & CMX_BUFF_MASK; 1353 } 1354 if (r == rr) { 1355 dsp->tx_R = t; 1356#ifdef CMX_TX_DEBUG 1357 printk(KERN_DEBUG "%s\n", debugbuf); 1358#endif 1359 goto send_packet; 1360 } 1361 } 1362#ifdef CMX_TX_DEBUG 1363 printk(KERN_DEBUG "%s\n", debugbuf); 1364#endif 1365 1366 /* PROCESS DATA (one member / no conf) */ 1367 if (!conf || members <= 1) { 1368 /* -> if echo is NOT enabled */ 1369 if (!dsp->echo) { 1370 /* -> send tx-data if available or use 0-volume */ 1371 while (r != rr && t != tt) { 1372 *d++ = p[t]; /* write tx_buff */ 1373 t = (t+1) & CMX_BUFF_MASK; 1374 r = (r+1) & CMX_BUFF_MASK; 1375 } 1376 if (r != rr) { 1377 if (dsp_debug & DEBUG_DSP_CLOCK) 1378 printk(KERN_DEBUG "%s: RX empty\n", 1379 __func__); 1380 memset(d, dsp_silence, (rr-r)&CMX_BUFF_MASK); 1381 } 1382 /* -> if echo is enabled */ 1383 } else { 1384 /* 1385 * -> mix tx-data with echo if available, 1386 * or use echo only 1387 */ 1388 while (r != rr && t != tt) { 1389 *d++ = dsp_audio_mix_law[(p[t]<<8)|q[r]]; 1390 t = (t+1) & CMX_BUFF_MASK; 1391 r = (r+1) & CMX_BUFF_MASK; 1392 } 1393 while (r != rr) { 1394 *d++ = q[r]; /* echo */ 1395 r = (r+1) & CMX_BUFF_MASK; 1396 } 1397 } 1398 dsp->tx_R = t; 1399 goto send_packet; 1400 } 1401 /* PROCESS DATA (two members) */ 1402#ifdef CMX_CONF_DEBUG 1403 if (0) { 1404#else 1405 if (members == 2) { 1406#endif 1407 /* "other" becomes other party */ 1408 other = (list_entry(conf->mlist.next, 1409 struct dsp_conf_member, list))->dsp; 1410 if (other == member) 1411 other = (list_entry(conf->mlist.prev, 1412 struct dsp_conf_member, list))->dsp; 1413 o_q = other->rx_buff; /* received data */ 1414 o_rr = (other->rx_R + len) & CMX_BUFF_MASK; 1415 /* end of rx-pointer */ 1416 o_r = (o_rr - rr + r) & CMX_BUFF_MASK; 1417 /* start rx-pointer at current read position*/ 1418 /* -> if echo is NOT enabled */ 1419 if (!dsp->echo) { 1420 /* 1421 * -> copy other member's rx-data, 1422 * if tx-data is available, mix 1423 */ 1424 while (o_r != o_rr && t != tt) { 1425 *d++ = dsp_audio_mix_law[(p[t]<<8)|o_q[o_r]]; 1426 t = (t+1) & CMX_BUFF_MASK; 1427 o_r = (o_r+1) & CMX_BUFF_MASK; 1428 } 1429 while (o_r != o_rr) { 1430 *d++ = o_q[o_r]; 1431 o_r = (o_r+1) & CMX_BUFF_MASK; 1432 } 1433 /* -> if echo is enabled */ 1434 } else { 1435 /* 1436 * -> mix other member's rx-data with echo, 1437 * if tx-data is available, mix 1438 */ 1439 while (r != rr && t != tt) { 1440 sample = dsp_audio_law_to_s32[p[t]] + 1441 dsp_audio_law_to_s32[q[r]] + 1442 dsp_audio_law_to_s32[o_q[o_r]]; 1443 if (sample < -32768) 1444 sample = -32768; 1445 else if (sample > 32767) 1446 sample = 32767; 1447 *d++ = dsp_audio_s16_to_law[sample & 0xffff]; 1448 /* tx-data + rx_data + echo */ 1449 t = (t+1) & CMX_BUFF_MASK; 1450 r = (r+1) & CMX_BUFF_MASK; 1451 o_r = (o_r+1) & CMX_BUFF_MASK; 1452 } 1453 while (r != rr) { 1454 *d++ = dsp_audio_mix_law[(q[r]<<8)|o_q[o_r]]; 1455 r = (r+1) & CMX_BUFF_MASK; 1456 o_r = (o_r+1) & CMX_BUFF_MASK; 1457 } 1458 } 1459 dsp->tx_R = t; 1460 goto send_packet; 1461 } 1462#ifdef DSP_NEVER_DEFINED 1463 } 1464#endif 1465 /* PROCESS DATA (three or more members) */ 1466 /* -> if echo is NOT enabled */ 1467 if (!dsp->echo) { 1468 /* 1469 * -> substract rx-data from conf-data, 1470 * if tx-data is available, mix 1471 */ 1472 while (r != rr && t != tt) { 1473 sample = dsp_audio_law_to_s32[p[t]] + *c++ - 1474 dsp_audio_law_to_s32[q[r]]; 1475 if (sample < -32768) 1476 sample = -32768; 1477 else if (sample > 32767) 1478 sample = 32767; 1479 *d++ = dsp_audio_s16_to_law[sample & 0xffff]; 1480 /* conf-rx+tx */ 1481 r = (r+1) & CMX_BUFF_MASK; 1482 t = (t+1) & CMX_BUFF_MASK; 1483 } 1484 while (r != rr) { 1485 sample = *c++ - dsp_audio_law_to_s32[q[r]]; 1486 if (sample < -32768) 1487 sample = -32768; 1488 else if (sample > 32767) 1489 sample = 32767; 1490 *d++ = dsp_audio_s16_to_law[sample & 0xffff]; 1491 /* conf-rx */ 1492 r = (r+1) & CMX_BUFF_MASK; 1493 } 1494 /* -> if echo is enabled */ 1495 } else { 1496 /* 1497 * -> encode conf-data, if tx-data 1498 * is available, mix 1499 */ 1500 while (r != rr && t != tt) { 1501 sample = dsp_audio_law_to_s32[p[t]] + *c++; 1502 if (sample < -32768) 1503 sample = -32768; 1504 else if (sample > 32767) 1505 sample = 32767; 1506 *d++ = dsp_audio_s16_to_law[sample & 0xffff]; 1507 /* conf(echo)+tx */ 1508 t = (t+1) & CMX_BUFF_MASK; 1509 r = (r+1) & CMX_BUFF_MASK; 1510 } 1511 while (r != rr) { 1512 sample = *c++; 1513 if (sample < -32768) 1514 sample = -32768; 1515 else if (sample > 32767) 1516 sample = 32767; 1517 *d++ = dsp_audio_s16_to_law[sample & 0xffff]; 1518 /* conf(echo) */ 1519 r = (r+1) & CMX_BUFF_MASK; 1520 } 1521 } 1522 dsp->tx_R = t; 1523 goto send_packet; 1524 1525send_packet: 1526 /* 1527 * send tx-data if enabled - don't filter, 1528 * becuase we want what we send, not what we filtered 1529 */ 1530 if (dsp->tx_data) { 1531 /* PREPARE RESULT */ 1532 txskb = mI_alloc_skb(len, GFP_ATOMIC); 1533 if (!txskb) { 1534 printk(KERN_ERR 1535 "FATAL ERROR in mISDN_dsp.o: " 1536 "cannot alloc %d bytes\n", len); 1537 } else { 1538 thh = mISDN_HEAD_P(txskb); 1539 thh->prim = DL_DATA_REQ; 1540 thh->id = 0; 1541 memcpy(skb_put(txskb, len), nskb->data+preload, len); 1542 /* queue (trigger later) */ 1543 skb_queue_tail(&dsp->sendq, txskb); 1544 } 1545 } 1546 /* adjust volume */ 1547 if (dsp->tx_volume) 1548 dsp_change_volume(nskb, dsp->tx_volume); 1549 /* pipeline */ 1550 if (dsp->pipeline.inuse) 1551 dsp_pipeline_process_tx(&dsp->pipeline, nskb->data, nskb->len); 1552 /* crypt */ 1553 if (dsp->bf_enable) 1554 dsp_bf_encrypt(dsp, nskb->data, nskb->len); 1555 /* queue and trigger */ 1556 skb_queue_tail(&dsp->sendq, nskb); 1557 schedule_work(&dsp->workq); 1558} 1559 1560static u32 jittercount; /* counter for jitter check */; 1561struct timer_list dsp_spl_tl; 1562u32 dsp_spl_jiffies; /* calculate the next time to fire */ 1563static u16 dsp_count; /* last sample count */ 1564static int dsp_count_valid ; /* if we have last sample count */ 1565 1566void 1567dsp_cmx_send(void *arg) 1568{ 1569 struct dsp_conf *conf; 1570 struct dsp_conf_member *member; 1571 struct dsp *dsp; 1572 int mustmix, members; 1573 s32 mixbuffer[MAX_POLL+100], *c; 1574 u8 *p, *q; 1575 int r, rr; 1576 int jittercheck = 0, delay, i; 1577 u_long flags; 1578 u16 length, count; 1579 1580 /* lock */ 1581 spin_lock_irqsave(&dsp_lock, flags); 1582 1583 if (!dsp_count_valid) { 1584 dsp_count = mISDN_clock_get(); 1585 length = dsp_poll; 1586 dsp_count_valid = 1; 1587 } else { 1588 count = mISDN_clock_get(); 1589 length = count - dsp_count; 1590 dsp_count = count; 1591 } 1592 if (length > MAX_POLL + 100) 1593 length = MAX_POLL + 100; 1594 /* printk(KERN_DEBUG "len=%d dsp_count=0x%x\n", length, dsp_count); */ 1595 1596 /* 1597 * check if jitter needs to be checked (this is every second) 1598 */ 1599 jittercount += length; 1600 if (jittercount >= 8000) { 1601 jittercount -= 8000; 1602 jittercheck = 1; 1603 } 1604 1605 /* loop all members that do not require conference mixing */ 1606 list_for_each_entry(dsp, &dsp_ilist, list) { 1607 if (dsp->hdlc) 1608 continue; 1609 conf = dsp->conf; 1610 mustmix = 0; 1611 members = 0; 1612 if (conf) { 1613 members = count_list_member(&conf->mlist); 1614#ifdef CMX_CONF_DEBUG 1615 if (conf->software && members > 1) 1616#else 1617 if (conf->software && members > 2) 1618#endif 1619 mustmix = 1; 1620 } 1621 1622 /* transmission required */ 1623 if (!mustmix) { 1624 dsp_cmx_send_member(dsp, length, mixbuffer, members); 1625 1626 /* 1627 * unused mixbuffer is given to prevent a 1628 * potential null-pointer-bug 1629 */ 1630 } 1631 } 1632 1633 /* loop all members that require conference mixing */ 1634 list_for_each_entry(conf, &conf_ilist, list) { 1635 /* count members and check hardware */ 1636 members = count_list_member(&conf->mlist); 1637#ifdef CMX_CONF_DEBUG 1638 if (conf->software && members > 1) { 1639#else 1640 if (conf->software && members > 2) { 1641#endif 1642 /* check for hdlc conf */ 1643 member = list_entry(conf->mlist.next, 1644 struct dsp_conf_member, list); 1645 if (member->dsp->hdlc) 1646 continue; 1647 /* mix all data */ 1648 memset(mixbuffer, 0, length*sizeof(s32)); 1649 list_for_each_entry(member, &conf->mlist, list) { 1650 dsp = member->dsp; 1651 /* get range of data to mix */ 1652 c = mixbuffer; 1653 q = dsp->rx_buff; 1654 r = dsp->rx_R; 1655 rr = (r + length) & CMX_BUFF_MASK; 1656 /* add member's data */ 1657 while (r != rr) { 1658 *c++ += dsp_audio_law_to_s32[q[r]]; 1659 r = (r+1) & CMX_BUFF_MASK; 1660 } 1661 } 1662 1663 /* process each member */ 1664 list_for_each_entry(member, &conf->mlist, list) { 1665 /* transmission */ 1666 dsp_cmx_send_member(member->dsp, length, 1667 mixbuffer, members); 1668 } 1669 } 1670 } 1671 1672 /* delete rx-data, increment buffers, change pointers */ 1673 list_for_each_entry(dsp, &dsp_ilist, list) { 1674 if (dsp->hdlc) 1675 continue; 1676 p = dsp->rx_buff; 1677 q = dsp->tx_buff; 1678 r = dsp->rx_R; 1679 /* move receive pointer when receiving */ 1680 if (!dsp->rx_is_off) { 1681 rr = (r + length) & CMX_BUFF_MASK; 1682 /* delete rx-data */ 1683 while (r != rr) { 1684 p[r] = dsp_silence; 1685 r = (r+1) & CMX_BUFF_MASK; 1686 } 1687 /* increment rx-buffer pointer */ 1688 dsp->rx_R = r; /* write incremented read pointer */ 1689 } 1690 1691 /* check current rx_delay */ 1692 delay = (dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK; 1693 if (delay >= CMX_BUFF_HALF) 1694 delay = 0; /* will be the delay before next write */ 1695 /* check for lower delay */ 1696 if (delay < dsp->rx_delay[0]) 1697 dsp->rx_delay[0] = delay; 1698 /* check current tx_delay */ 1699 delay = (dsp->tx_W-dsp->tx_R) & CMX_BUFF_MASK; 1700 if (delay >= CMX_BUFF_HALF) 1701 delay = 0; /* will be the delay before next write */ 1702 /* check for lower delay */ 1703 if (delay < dsp->tx_delay[0]) 1704 dsp->tx_delay[0] = delay; 1705 if (jittercheck) { 1706 /* find the lowest of all rx_delays */ 1707 delay = dsp->rx_delay[0]; 1708 i = 1; 1709 while (i < MAX_SECONDS_JITTER_CHECK) { 1710 if (delay > dsp->rx_delay[i]) 1711 delay = dsp->rx_delay[i]; 1712 i++; 1713 } 1714 /* 1715 * remove rx_delay only if we have delay AND we 1716 * have not preset cmx_delay AND 1717 * the delay is greater dsp_poll 1718 */ 1719 if (delay > dsp_poll && !dsp->cmx_delay) { 1720 if (dsp_debug & DEBUG_DSP_CLOCK) 1721 printk(KERN_DEBUG 1722 "%s lowest rx_delay of %d bytes for" 1723 " dsp %s are now removed.\n", 1724 __func__, delay, 1725 dsp->name); 1726 r = dsp->rx_R; 1727 rr = (r + delay - (dsp_poll >> 1)) 1728 & CMX_BUFF_MASK; 1729 /* delete rx-data */ 1730 while (r != rr) { 1731 p[r] = dsp_silence; 1732 r = (r+1) & CMX_BUFF_MASK; 1733 } 1734 /* increment rx-buffer pointer */ 1735 dsp->rx_R = r; 1736 /* write incremented read pointer */ 1737 } 1738 /* find the lowest of all tx_delays */ 1739 delay = dsp->tx_delay[0]; 1740 i = 1; 1741 while (i < MAX_SECONDS_JITTER_CHECK) { 1742 if (delay > dsp->tx_delay[i]) 1743 delay = dsp->tx_delay[i]; 1744 i++; 1745 } 1746 /* 1747 * remove delay only if we have delay AND we 1748 * have enabled tx_dejitter 1749 */ 1750 if (delay > dsp_poll && dsp->tx_dejitter) { 1751 if (dsp_debug & DEBUG_DSP_CLOCK) 1752 printk(KERN_DEBUG 1753 "%s lowest tx_delay of %d bytes for" 1754 " dsp %s are now removed.\n", 1755 __func__, delay, 1756 dsp->name); 1757 r = dsp->tx_R; 1758 rr = (r + delay - (dsp_poll >> 1)) 1759 & CMX_BUFF_MASK; 1760 /* delete tx-data */ 1761 while (r != rr) { 1762 q[r] = dsp_silence; 1763 r = (r+1) & CMX_BUFF_MASK; 1764 } 1765 /* increment rx-buffer pointer */ 1766 dsp->tx_R = r; 1767 /* write incremented read pointer */ 1768 } 1769 /* scroll up delays */ 1770 i = MAX_SECONDS_JITTER_CHECK - 1; 1771 while (i) { 1772 dsp->rx_delay[i] = dsp->rx_delay[i-1]; 1773 dsp->tx_delay[i] = dsp->tx_delay[i-1]; 1774 i--; 1775 } 1776 dsp->tx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */ 1777 dsp->rx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */ 1778 } 1779 } 1780 1781 /* if next event would be in the past ... */ 1782 if ((s32)(dsp_spl_jiffies+dsp_tics-jiffies) <= 0) 1783 dsp_spl_jiffies = jiffies + 1; 1784 else 1785 dsp_spl_jiffies += dsp_tics; 1786 1787 dsp_spl_tl.expires = dsp_spl_jiffies; 1788 add_timer(&dsp_spl_tl); 1789 1790 /* unlock */ 1791 spin_unlock_irqrestore(&dsp_lock, flags); 1792} 1793 1794/* 1795 * audio data is transmitted from upper layer to the dsp 1796 */ 1797void 1798dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb) 1799{ 1800 u_int w, ww; 1801 u8 *d, *p; 1802 int space; /* todo: , l = skb->len; */ 1803#ifdef CMX_TX_DEBUG 1804 char debugbuf[256] = ""; 1805#endif 1806 1807 /* check if there is enough space, and then copy */ 1808 w = dsp->tx_W; 1809 ww = dsp->tx_R; 1810 p = dsp->tx_buff; 1811 d = skb->data; 1812 space = (ww - w - 1) & CMX_BUFF_MASK; 1813 /* write-pointer should not overrun nor reach read pointer */ 1814 if (space < skb->len) { 1815 /* write to the space we have left */ 1816 ww = (ww - 1) & CMX_BUFF_MASK; /* end one byte prior tx_R */ 1817 if (dsp_debug & DEBUG_DSP_CLOCK) 1818 printk(KERN_DEBUG "%s: TX overflow space=%d skb->len=" 1819 "%d, w=0x%04x, ww=0x%04x\n", __func__, space, 1820 skb->len, w, ww); 1821 } else 1822 /* write until all byte are copied */ 1823 ww = (w + skb->len) & CMX_BUFF_MASK; 1824 dsp->tx_W = ww; 1825 1826 /* show current buffer */ 1827#ifdef CMX_DEBUG 1828 printk(KERN_DEBUG 1829 "cmx_transmit(dsp=%lx) %d bytes to 0x%x-0x%x. %s\n", 1830 (u_long)dsp, (ww-w)&CMX_BUFF_MASK, w, ww, dsp->name); 1831#endif 1832 1833 /* copy transmit data to tx-buffer */ 1834#ifdef CMX_TX_DEBUG 1835 sprintf(debugbuf, "TX getting (%04x-%04x)%p: ", w, ww, p); 1836#endif 1837 while (w != ww) { 1838#ifdef CMX_TX_DEBUG 1839 if (strlen(debugbuf) < 48) 1840 sprintf(debugbuf+strlen(debugbuf), " %02x", *d); 1841#endif 1842 p[w] = *d++; 1843 w = (w+1) & CMX_BUFF_MASK; 1844 } 1845#ifdef CMX_TX_DEBUG 1846 printk(KERN_DEBUG "%s\n", debugbuf); 1847#endif 1848 1849} 1850 1851/* 1852 * hdlc data is received from card and sent to all members. 1853 */ 1854void 1855dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb) 1856{ 1857 struct sk_buff *nskb = NULL; 1858 struct dsp_conf_member *member; 1859 struct mISDNhead *hh; 1860 1861 /* not if not active */ 1862 if (!dsp->b_active) 1863 return; 1864 1865 /* check if we have sompen */ 1866 if (skb->len < 1) 1867 return; 1868 1869 /* no conf */ 1870 if (!dsp->conf) { 1871 /* in case of hardware (echo) */ 1872 if (dsp->pcm_slot_tx >= 0) 1873 return; 1874 if (dsp->echo) 1875 nskb = skb_clone(skb, GFP_ATOMIC); 1876 if (nskb) { 1877 hh = mISDN_HEAD_P(nskb); 1878 hh->prim = PH_DATA_REQ; 1879 hh->id = 0; 1880 skb_queue_tail(&dsp->sendq, nskb); 1881 schedule_work(&dsp->workq); 1882 } 1883 return; 1884 } 1885 /* in case of hardware conference */ 1886 if (dsp->conf->hardware) 1887 return; 1888 list_for_each_entry(member, &dsp->conf->mlist, list) { 1889 if (dsp->echo || member->dsp != dsp) { 1890 nskb = skb_clone(skb, GFP_ATOMIC); 1891 if (nskb) { 1892 hh = mISDN_HEAD_P(nskb); 1893 hh->prim = PH_DATA_REQ; 1894 hh->id = 0; 1895 skb_queue_tail(&member->dsp->sendq, nskb); 1896 schedule_work(&member->dsp->workq); 1897 } 1898 } 1899 } 1900} 1901 1902 1903