linux/drivers/isdn/hardware/mISDN/mISDNipac.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * isac.c   ISAC specific routines
   4 *
   5 * Author       Karsten Keil <keil@isdn4linux.de>
   6 *
   7 * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
   8 */
   9
  10#include <linux/irqreturn.h>
  11#include <linux/slab.h>
  12#include <linux/module.h>
  13#include <linux/mISDNhw.h>
  14#include "ipac.h"
  15
  16
  17#define DBUSY_TIMER_VALUE       80
  18#define ARCOFI_USE              1
  19
  20#define ISAC_REV                "2.0"
  21
  22MODULE_AUTHOR("Karsten Keil");
  23MODULE_VERSION(ISAC_REV);
  24MODULE_LICENSE("GPL v2");
  25
  26#define ReadISAC(is, o)         (is->read_reg(is->dch.hw, o + is->off))
  27#define WriteISAC(is, o, v)     (is->write_reg(is->dch.hw, o + is->off, v))
  28#define ReadHSCX(h, o)          (h->ip->read_reg(h->ip->hw, h->off + o))
  29#define WriteHSCX(h, o, v)      (h->ip->write_reg(h->ip->hw, h->off + o, v))
  30#define ReadIPAC(ip, o)         (ip->read_reg(ip->hw, o))
  31#define WriteIPAC(ip, o, v)     (ip->write_reg(ip->hw, o, v))
  32
  33static inline void
  34ph_command(struct isac_hw *isac, u8 command)
  35{
  36        pr_debug("%s: ph_command %x\n", isac->name, command);
  37        if (isac->type & IPAC_TYPE_ISACX)
  38                WriteISAC(isac, ISACX_CIX0, (command << 4) | 0xE);
  39        else
  40                WriteISAC(isac, ISAC_CIX0, (command << 2) | 3);
  41}
  42
  43static void
  44isac_ph_state_change(struct isac_hw *isac)
  45{
  46        switch (isac->state) {
  47        case (ISAC_IND_RS):
  48        case (ISAC_IND_EI):
  49                ph_command(isac, ISAC_CMD_DUI);
  50        }
  51        schedule_event(&isac->dch, FLG_PHCHANGE);
  52}
  53
  54static void
  55isac_ph_state_bh(struct dchannel *dch)
  56{
  57        struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
  58
  59        switch (isac->state) {
  60        case ISAC_IND_RS:
  61        case ISAC_IND_EI:
  62                dch->state = 0;
  63                l1_event(dch->l1, HW_RESET_IND);
  64                break;
  65        case ISAC_IND_DID:
  66                dch->state = 3;
  67                l1_event(dch->l1, HW_DEACT_CNF);
  68                break;
  69        case ISAC_IND_DR:
  70        case ISAC_IND_DR6:
  71                dch->state = 3;
  72                l1_event(dch->l1, HW_DEACT_IND);
  73                break;
  74        case ISAC_IND_PU:
  75                dch->state = 4;
  76                l1_event(dch->l1, HW_POWERUP_IND);
  77                break;
  78        case ISAC_IND_RSY:
  79                if (dch->state <= 5) {
  80                        dch->state = 5;
  81                        l1_event(dch->l1, ANYSIGNAL);
  82                } else {
  83                        dch->state = 8;
  84                        l1_event(dch->l1, LOSTFRAMING);
  85                }
  86                break;
  87        case ISAC_IND_ARD:
  88                dch->state = 6;
  89                l1_event(dch->l1, INFO2);
  90                break;
  91        case ISAC_IND_AI8:
  92                dch->state = 7;
  93                l1_event(dch->l1, INFO4_P8);
  94                break;
  95        case ISAC_IND_AI10:
  96                dch->state = 7;
  97                l1_event(dch->l1, INFO4_P10);
  98                break;
  99        }
 100        pr_debug("%s: TE newstate %x\n", isac->name, dch->state);
 101}
 102
 103static void
 104isac_empty_fifo(struct isac_hw *isac, int count)
 105{
 106        u8 *ptr;
 107
 108        pr_debug("%s: %s  %d\n", isac->name, __func__, count);
 109
 110        if (!isac->dch.rx_skb) {
 111                isac->dch.rx_skb = mI_alloc_skb(isac->dch.maxlen, GFP_ATOMIC);
 112                if (!isac->dch.rx_skb) {
 113                        pr_info("%s: D receive out of memory\n", isac->name);
 114                        WriteISAC(isac, ISAC_CMDR, 0x80);
 115                        return;
 116                }
 117        }
 118        if ((isac->dch.rx_skb->len + count) >= isac->dch.maxlen) {
 119                pr_debug("%s: %s overrun %d\n", isac->name, __func__,
 120                         isac->dch.rx_skb->len + count);
 121                WriteISAC(isac, ISAC_CMDR, 0x80);
 122                return;
 123        }
 124        ptr = skb_put(isac->dch.rx_skb, count);
 125        isac->read_fifo(isac->dch.hw, isac->off, ptr, count);
 126        WriteISAC(isac, ISAC_CMDR, 0x80);
 127        if (isac->dch.debug & DEBUG_HW_DFIFO) {
 128                char    pfx[MISDN_MAX_IDLEN + 16];
 129
 130                snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-recv %s %d ",
 131                         isac->name, count);
 132                print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count);
 133        }
 134}
 135
 136static void
 137isac_fill_fifo(struct isac_hw *isac)
 138{
 139        int count, more;
 140        u8 *ptr;
 141
 142        if (!isac->dch.tx_skb)
 143                return;
 144        count = isac->dch.tx_skb->len - isac->dch.tx_idx;
 145        if (count <= 0)
 146                return;
 147
 148        more = 0;
 149        if (count > 32) {
 150                more = !0;
 151                count = 32;
 152        }
 153        pr_debug("%s: %s  %d\n", isac->name, __func__, count);
 154        ptr = isac->dch.tx_skb->data + isac->dch.tx_idx;
 155        isac->dch.tx_idx += count;
 156        isac->write_fifo(isac->dch.hw, isac->off, ptr, count);
 157        WriteISAC(isac, ISAC_CMDR, more ? 0x8 : 0xa);
 158        if (test_and_set_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) {
 159                pr_debug("%s: %s dbusytimer running\n", isac->name, __func__);
 160                del_timer(&isac->dch.timer);
 161        }
 162        isac->dch.timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
 163        add_timer(&isac->dch.timer);
 164        if (isac->dch.debug & DEBUG_HW_DFIFO) {
 165                char    pfx[MISDN_MAX_IDLEN + 16];
 166
 167                snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-send %s %d ",
 168                         isac->name, count);
 169                print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count);
 170        }
 171}
 172
 173static void
 174isac_rme_irq(struct isac_hw *isac)
 175{
 176        u8 val, count;
 177
 178        val = ReadISAC(isac, ISAC_RSTA);
 179        if ((val & 0x70) != 0x20) {
 180                if (val & 0x40) {
 181                        pr_debug("%s: ISAC RDO\n", isac->name);
 182#ifdef ERROR_STATISTIC
 183                        isac->dch.err_rx++;
 184#endif
 185                }
 186                if (!(val & 0x20)) {
 187                        pr_debug("%s: ISAC CRC error\n", isac->name);
 188#ifdef ERROR_STATISTIC
 189                        isac->dch.err_crc++;
 190#endif
 191                }
 192                WriteISAC(isac, ISAC_CMDR, 0x80);
 193                if (isac->dch.rx_skb)
 194                        dev_kfree_skb(isac->dch.rx_skb);
 195                isac->dch.rx_skb = NULL;
 196        } else {
 197                count = ReadISAC(isac, ISAC_RBCL) & 0x1f;
 198                if (count == 0)
 199                        count = 32;
 200                isac_empty_fifo(isac, count);
 201                recv_Dchannel(&isac->dch);
 202        }
 203}
 204
 205static void
 206isac_xpr_irq(struct isac_hw *isac)
 207{
 208        if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags))
 209                del_timer(&isac->dch.timer);
 210        if (isac->dch.tx_skb && isac->dch.tx_idx < isac->dch.tx_skb->len) {
 211                isac_fill_fifo(isac);
 212        } else {
 213                if (isac->dch.tx_skb)
 214                        dev_kfree_skb(isac->dch.tx_skb);
 215                if (get_next_dframe(&isac->dch))
 216                        isac_fill_fifo(isac);
 217        }
 218}
 219
 220static void
 221isac_retransmit(struct isac_hw *isac)
 222{
 223        if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags))
 224                del_timer(&isac->dch.timer);
 225        if (test_bit(FLG_TX_BUSY, &isac->dch.Flags)) {
 226                /* Restart frame */
 227                isac->dch.tx_idx = 0;
 228                isac_fill_fifo(isac);
 229        } else if (isac->dch.tx_skb) { /* should not happen */
 230                pr_info("%s: tx_skb exist but not busy\n", isac->name);
 231                test_and_set_bit(FLG_TX_BUSY, &isac->dch.Flags);
 232                isac->dch.tx_idx = 0;
 233                isac_fill_fifo(isac);
 234        } else {
 235                pr_info("%s: ISAC XDU no TX_BUSY\n", isac->name);
 236                if (get_next_dframe(&isac->dch))
 237                        isac_fill_fifo(isac);
 238        }
 239}
 240
 241static void
 242isac_mos_irq(struct isac_hw *isac)
 243{
 244        u8 val;
 245        int ret;
 246
 247        val = ReadISAC(isac, ISAC_MOSR);
 248        pr_debug("%s: ISAC MOSR %02x\n", isac->name, val);
 249#if ARCOFI_USE
 250        if (val & 0x08) {
 251                if (!isac->mon_rx) {
 252                        isac->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC);
 253                        if (!isac->mon_rx) {
 254                                pr_info("%s: ISAC MON RX out of memory!\n",
 255                                        isac->name);
 256                                isac->mocr &= 0xf0;
 257                                isac->mocr |= 0x0a;
 258                                WriteISAC(isac, ISAC_MOCR, isac->mocr);
 259                                goto afterMONR0;
 260                        } else
 261                                isac->mon_rxp = 0;
 262                }
 263                if (isac->mon_rxp >= MAX_MON_FRAME) {
 264                        isac->mocr &= 0xf0;
 265                        isac->mocr |= 0x0a;
 266                        WriteISAC(isac, ISAC_MOCR, isac->mocr);
 267                        isac->mon_rxp = 0;
 268                        pr_debug("%s: ISAC MON RX overflow!\n", isac->name);
 269                        goto afterMONR0;
 270                }
 271                isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR0);
 272                pr_debug("%s: ISAC MOR0 %02x\n", isac->name,
 273                         isac->mon_rx[isac->mon_rxp - 1]);
 274                if (isac->mon_rxp == 1) {
 275                        isac->mocr |= 0x04;
 276                        WriteISAC(isac, ISAC_MOCR, isac->mocr);
 277                }
 278        }
 279afterMONR0:
 280        if (val & 0x80) {
 281                if (!isac->mon_rx) {
 282                        isac->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC);
 283                        if (!isac->mon_rx) {
 284                                pr_info("%s: ISAC MON RX out of memory!\n",
 285                                        isac->name);
 286                                isac->mocr &= 0x0f;
 287                                isac->mocr |= 0xa0;
 288                                WriteISAC(isac, ISAC_MOCR, isac->mocr);
 289                                goto afterMONR1;
 290                        } else
 291                                isac->mon_rxp = 0;
 292                }
 293                if (isac->mon_rxp >= MAX_MON_FRAME) {
 294                        isac->mocr &= 0x0f;
 295                        isac->mocr |= 0xa0;
 296                        WriteISAC(isac, ISAC_MOCR, isac->mocr);
 297                        isac->mon_rxp = 0;
 298                        pr_debug("%s: ISAC MON RX overflow!\n", isac->name);
 299                        goto afterMONR1;
 300                }
 301                isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR1);
 302                pr_debug("%s: ISAC MOR1 %02x\n", isac->name,
 303                         isac->mon_rx[isac->mon_rxp - 1]);
 304                isac->mocr |= 0x40;
 305                WriteISAC(isac, ISAC_MOCR, isac->mocr);
 306        }
 307afterMONR1:
 308        if (val & 0x04) {
 309                isac->mocr &= 0xf0;
 310                WriteISAC(isac, ISAC_MOCR, isac->mocr);
 311                isac->mocr |= 0x0a;
 312                WriteISAC(isac, ISAC_MOCR, isac->mocr);
 313                if (isac->monitor) {
 314                        ret = isac->monitor(isac->dch.hw, MONITOR_RX_0,
 315                                            isac->mon_rx, isac->mon_rxp);
 316                        if (ret)
 317                                kfree(isac->mon_rx);
 318                } else {
 319                        pr_info("%s: MONITOR 0 received %d but no user\n",
 320                                isac->name, isac->mon_rxp);
 321                        kfree(isac->mon_rx);
 322                }
 323                isac->mon_rx = NULL;
 324                isac->mon_rxp = 0;
 325        }
 326        if (val & 0x40) {
 327                isac->mocr &= 0x0f;
 328                WriteISAC(isac, ISAC_MOCR, isac->mocr);
 329                isac->mocr |= 0xa0;
 330                WriteISAC(isac, ISAC_MOCR, isac->mocr);
 331                if (isac->monitor) {
 332                        ret = isac->monitor(isac->dch.hw, MONITOR_RX_1,
 333                                            isac->mon_rx, isac->mon_rxp);
 334                        if (ret)
 335                                kfree(isac->mon_rx);
 336                } else {
 337                        pr_info("%s: MONITOR 1 received %d but no user\n",
 338                                isac->name, isac->mon_rxp);
 339                        kfree(isac->mon_rx);
 340                }
 341                isac->mon_rx = NULL;
 342                isac->mon_rxp = 0;
 343        }
 344        if (val & 0x02) {
 345                if ((!isac->mon_tx) || (isac->mon_txc &&
 346                                        (isac->mon_txp >= isac->mon_txc) && !(val & 0x08))) {
 347                        isac->mocr &= 0xf0;
 348                        WriteISAC(isac, ISAC_MOCR, isac->mocr);
 349                        isac->mocr |= 0x0a;
 350                        WriteISAC(isac, ISAC_MOCR, isac->mocr);
 351                        if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
 352                                if (isac->monitor)
 353                                        isac->monitor(isac->dch.hw,
 354                                                      MONITOR_TX_0, NULL, 0);
 355                        }
 356                        kfree(isac->mon_tx);
 357                        isac->mon_tx = NULL;
 358                        isac->mon_txc = 0;
 359                        isac->mon_txp = 0;
 360                        goto AfterMOX0;
 361                }
 362                if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
 363                        if (isac->monitor)
 364                                isac->monitor(isac->dch.hw,
 365                                              MONITOR_TX_0, NULL, 0);
 366                        kfree(isac->mon_tx);
 367                        isac->mon_tx = NULL;
 368                        isac->mon_txc = 0;
 369                        isac->mon_txp = 0;
 370                        goto AfterMOX0;
 371                }
 372                WriteISAC(isac, ISAC_MOX0, isac->mon_tx[isac->mon_txp++]);
 373                pr_debug("%s: ISAC %02x -> MOX0\n", isac->name,
 374                         isac->mon_tx[isac->mon_txp - 1]);
 375        }
 376AfterMOX0:
 377        if (val & 0x20) {
 378                if ((!isac->mon_tx) || (isac->mon_txc &&
 379                                        (isac->mon_txp >= isac->mon_txc) && !(val & 0x80))) {
 380                        isac->mocr &= 0x0f;
 381                        WriteISAC(isac, ISAC_MOCR, isac->mocr);
 382                        isac->mocr |= 0xa0;
 383                        WriteISAC(isac, ISAC_MOCR, isac->mocr);
 384                        if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
 385                                if (isac->monitor)
 386                                        isac->monitor(isac->dch.hw,
 387                                                      MONITOR_TX_1, NULL, 0);
 388                        }
 389                        kfree(isac->mon_tx);
 390                        isac->mon_tx = NULL;
 391                        isac->mon_txc = 0;
 392                        isac->mon_txp = 0;
 393                        goto AfterMOX1;
 394                }
 395                if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
 396                        if (isac->monitor)
 397                                isac->monitor(isac->dch.hw,
 398                                              MONITOR_TX_1, NULL, 0);
 399                        kfree(isac->mon_tx);
 400                        isac->mon_tx = NULL;
 401                        isac->mon_txc = 0;
 402                        isac->mon_txp = 0;
 403                        goto AfterMOX1;
 404                }
 405                WriteISAC(isac, ISAC_MOX1, isac->mon_tx[isac->mon_txp++]);
 406                pr_debug("%s: ISAC %02x -> MOX1\n", isac->name,
 407                         isac->mon_tx[isac->mon_txp - 1]);
 408        }
 409AfterMOX1:
 410        val = 0; /* dummy to avoid warning */
 411#endif
 412}
 413
 414static void
 415isac_cisq_irq(struct isac_hw *isac) {
 416        u8 val;
 417
 418        val = ReadISAC(isac, ISAC_CIR0);
 419        pr_debug("%s: ISAC CIR0 %02X\n", isac->name, val);
 420        if (val & 2) {
 421                pr_debug("%s: ph_state change %x->%x\n", isac->name,
 422                         isac->state, (val >> 2) & 0xf);
 423                isac->state = (val >> 2) & 0xf;
 424                isac_ph_state_change(isac);
 425        }
 426        if (val & 1) {
 427                val = ReadISAC(isac, ISAC_CIR1);
 428                pr_debug("%s: ISAC CIR1 %02X\n", isac->name, val);
 429        }
 430}
 431
 432static void
 433isacsx_cic_irq(struct isac_hw *isac)
 434{
 435        u8 val;
 436
 437        val = ReadISAC(isac, ISACX_CIR0);
 438        pr_debug("%s: ISACX CIR0 %02X\n", isac->name, val);
 439        if (val & ISACX_CIR0_CIC0) {
 440                pr_debug("%s: ph_state change %x->%x\n", isac->name,
 441                         isac->state, val >> 4);
 442                isac->state = val >> 4;
 443                isac_ph_state_change(isac);
 444        }
 445}
 446
 447static void
 448isacsx_rme_irq(struct isac_hw *isac)
 449{
 450        int count;
 451        u8 val;
 452
 453        val = ReadISAC(isac, ISACX_RSTAD);
 454        if ((val & (ISACX_RSTAD_VFR |
 455                    ISACX_RSTAD_RDO |
 456                    ISACX_RSTAD_CRC |
 457                    ISACX_RSTAD_RAB))
 458            != (ISACX_RSTAD_VFR | ISACX_RSTAD_CRC)) {
 459                pr_debug("%s: RSTAD %#x, dropped\n", isac->name, val);
 460#ifdef ERROR_STATISTIC
 461                if (val & ISACX_RSTAD_CRC)
 462                        isac->dch.err_rx++;
 463                else
 464                        isac->dch.err_crc++;
 465#endif
 466                WriteISAC(isac, ISACX_CMDRD, ISACX_CMDRD_RMC);
 467                if (isac->dch.rx_skb)
 468                        dev_kfree_skb(isac->dch.rx_skb);
 469                isac->dch.rx_skb = NULL;
 470        } else {
 471                count = ReadISAC(isac, ISACX_RBCLD) & 0x1f;
 472                if (count == 0)
 473                        count = 32;
 474                isac_empty_fifo(isac, count);
 475                if (isac->dch.rx_skb) {
 476                        skb_trim(isac->dch.rx_skb, isac->dch.rx_skb->len - 1);
 477                        pr_debug("%s: dchannel received %d\n", isac->name,
 478                                 isac->dch.rx_skb->len);
 479                        recv_Dchannel(&isac->dch);
 480                }
 481        }
 482}
 483
 484irqreturn_t
 485mISDNisac_irq(struct isac_hw *isac, u8 val)
 486{
 487        if (unlikely(!val))
 488                return IRQ_NONE;
 489        pr_debug("%s: ISAC interrupt %02x\n", isac->name, val);
 490        if (isac->type & IPAC_TYPE_ISACX) {
 491                if (val & ISACX__CIC)
 492                        isacsx_cic_irq(isac);
 493                if (val & ISACX__ICD) {
 494                        val = ReadISAC(isac, ISACX_ISTAD);
 495                        pr_debug("%s: ISTAD %02x\n", isac->name, val);
 496                        if (val & ISACX_D_XDU) {
 497                                pr_debug("%s: ISAC XDU\n", isac->name);
 498#ifdef ERROR_STATISTIC
 499                                isac->dch.err_tx++;
 500#endif
 501                                isac_retransmit(isac);
 502                        }
 503                        if (val & ISACX_D_XMR) {
 504                                pr_debug("%s: ISAC XMR\n", isac->name);
 505#ifdef ERROR_STATISTIC
 506                                isac->dch.err_tx++;
 507#endif
 508                                isac_retransmit(isac);
 509                        }
 510                        if (val & ISACX_D_XPR)
 511                                isac_xpr_irq(isac);
 512                        if (val & ISACX_D_RFO) {
 513                                pr_debug("%s: ISAC RFO\n", isac->name);
 514                                WriteISAC(isac, ISACX_CMDRD, ISACX_CMDRD_RMC);
 515                        }
 516                        if (val & ISACX_D_RME)
 517                                isacsx_rme_irq(isac);
 518                        if (val & ISACX_D_RPF)
 519                                isac_empty_fifo(isac, 0x20);
 520                }
 521        } else {
 522                if (val & 0x80) /* RME */
 523                        isac_rme_irq(isac);
 524                if (val & 0x40) /* RPF */
 525                        isac_empty_fifo(isac, 32);
 526                if (val & 0x10) /* XPR */
 527                        isac_xpr_irq(isac);
 528                if (val & 0x04) /* CISQ */
 529                        isac_cisq_irq(isac);
 530                if (val & 0x20) /* RSC - never */
 531                        pr_debug("%s: ISAC RSC interrupt\n", isac->name);
 532                if (val & 0x02) /* SIN - never */
 533                        pr_debug("%s: ISAC SIN interrupt\n", isac->name);
 534                if (val & 0x01) {       /* EXI */
 535                        val = ReadISAC(isac, ISAC_EXIR);
 536                        pr_debug("%s: ISAC EXIR %02x\n", isac->name, val);
 537                        if (val & 0x80) /* XMR */
 538                                pr_debug("%s: ISAC XMR\n", isac->name);
 539                        if (val & 0x40) { /* XDU */
 540                                pr_debug("%s: ISAC XDU\n", isac->name);
 541#ifdef ERROR_STATISTIC
 542                                isac->dch.err_tx++;
 543#endif
 544                                isac_retransmit(isac);
 545                        }
 546                        if (val & 0x04) /* MOS */
 547                                isac_mos_irq(isac);
 548                }
 549        }
 550        return IRQ_HANDLED;
 551}
 552EXPORT_SYMBOL(mISDNisac_irq);
 553
 554static int
 555isac_l1hw(struct mISDNchannel *ch, struct sk_buff *skb)
 556{
 557        struct mISDNdevice      *dev = container_of(ch, struct mISDNdevice, D);
 558        struct dchannel         *dch = container_of(dev, struct dchannel, dev);
 559        struct isac_hw          *isac = container_of(dch, struct isac_hw, dch);
 560        int                     ret = -EINVAL;
 561        struct mISDNhead        *hh = mISDN_HEAD_P(skb);
 562        u32                     id;
 563        u_long                  flags;
 564
 565        switch (hh->prim) {
 566        case PH_DATA_REQ:
 567                spin_lock_irqsave(isac->hwlock, flags);
 568                ret = dchannel_senddata(dch, skb);
 569                if (ret > 0) { /* direct TX */
 570                        id = hh->id; /* skb can be freed */
 571                        isac_fill_fifo(isac);
 572                        ret = 0;
 573                        spin_unlock_irqrestore(isac->hwlock, flags);
 574                        queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
 575                } else
 576                        spin_unlock_irqrestore(isac->hwlock, flags);
 577                return ret;
 578        case PH_ACTIVATE_REQ:
 579                ret = l1_event(dch->l1, hh->prim);
 580                break;
 581        case PH_DEACTIVATE_REQ:
 582                test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
 583                ret = l1_event(dch->l1, hh->prim);
 584                break;
 585        }
 586
 587        if (!ret)
 588                dev_kfree_skb(skb);
 589        return ret;
 590}
 591
 592static int
 593isac_ctrl(struct isac_hw *isac, u32 cmd, unsigned long para)
 594{
 595        u8 tl = 0;
 596        unsigned long flags;
 597        int ret = 0;
 598
 599        switch (cmd) {
 600        case HW_TESTLOOP:
 601                spin_lock_irqsave(isac->hwlock, flags);
 602                if (!(isac->type & IPAC_TYPE_ISACX)) {
 603                        /* TODO: implement for IPAC_TYPE_ISACX */
 604                        if (para & 1) /* B1 */
 605                                tl |= 0x0c;
 606                        else if (para & 2) /* B2 */
 607                                tl |= 0x3;
 608                        /* we only support IOM2 mode */
 609                        WriteISAC(isac, ISAC_SPCR, tl);
 610                        if (tl)
 611                                WriteISAC(isac, ISAC_ADF1, 0x8);
 612                        else
 613                                WriteISAC(isac, ISAC_ADF1, 0x0);
 614                }
 615                spin_unlock_irqrestore(isac->hwlock, flags);
 616                break;
 617        case HW_TIMER3_VALUE:
 618                ret = l1_event(isac->dch.l1, HW_TIMER3_VALUE | (para & 0xff));
 619                break;
 620        default:
 621                pr_debug("%s: %s unknown command %x %lx\n", isac->name,
 622                         __func__, cmd, para);
 623                ret = -1;
 624        }
 625        return ret;
 626}
 627
 628static int
 629isac_l1cmd(struct dchannel *dch, u32 cmd)
 630{
 631        struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
 632        u_long flags;
 633
 634        pr_debug("%s: cmd(%x) state(%02x)\n", isac->name, cmd, isac->state);
 635        switch (cmd) {
 636        case INFO3_P8:
 637                spin_lock_irqsave(isac->hwlock, flags);
 638                ph_command(isac, ISAC_CMD_AR8);
 639                spin_unlock_irqrestore(isac->hwlock, flags);
 640                break;
 641        case INFO3_P10:
 642                spin_lock_irqsave(isac->hwlock, flags);
 643                ph_command(isac, ISAC_CMD_AR10);
 644                spin_unlock_irqrestore(isac->hwlock, flags);
 645                break;
 646        case HW_RESET_REQ:
 647                spin_lock_irqsave(isac->hwlock, flags);
 648                if ((isac->state == ISAC_IND_EI) ||
 649                    (isac->state == ISAC_IND_DR) ||
 650                    (isac->state == ISAC_IND_DR6) ||
 651                    (isac->state == ISAC_IND_RS))
 652                        ph_command(isac, ISAC_CMD_TIM);
 653                else
 654                        ph_command(isac, ISAC_CMD_RS);
 655                spin_unlock_irqrestore(isac->hwlock, flags);
 656                break;
 657        case HW_DEACT_REQ:
 658                skb_queue_purge(&dch->squeue);
 659                if (dch->tx_skb) {
 660                        dev_kfree_skb(dch->tx_skb);
 661                        dch->tx_skb = NULL;
 662                }
 663                dch->tx_idx = 0;
 664                if (dch->rx_skb) {
 665                        dev_kfree_skb(dch->rx_skb);
 666                        dch->rx_skb = NULL;
 667                }
 668                test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
 669                if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
 670                        del_timer(&dch->timer);
 671                break;
 672        case HW_POWERUP_REQ:
 673                spin_lock_irqsave(isac->hwlock, flags);
 674                ph_command(isac, ISAC_CMD_TIM);
 675                spin_unlock_irqrestore(isac->hwlock, flags);
 676                break;
 677        case PH_ACTIVATE_IND:
 678                test_and_set_bit(FLG_ACTIVE, &dch->Flags);
 679                _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
 680                            GFP_ATOMIC);
 681                break;
 682        case PH_DEACTIVATE_IND:
 683                test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
 684                _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
 685                            GFP_ATOMIC);
 686                break;
 687        default:
 688                pr_debug("%s: %s unknown command %x\n", isac->name,
 689                         __func__, cmd);
 690                return -1;
 691        }
 692        return 0;
 693}
 694
 695static void
 696isac_release(struct isac_hw *isac)
 697{
 698        if (isac->type & IPAC_TYPE_ISACX)
 699                WriteISAC(isac, ISACX_MASK, 0xff);
 700        else
 701                WriteISAC(isac, ISAC_MASK, 0xff);
 702        if (isac->dch.timer.function != NULL) {
 703                del_timer(&isac->dch.timer);
 704                isac->dch.timer.function = NULL;
 705        }
 706        kfree(isac->mon_rx);
 707        isac->mon_rx = NULL;
 708        kfree(isac->mon_tx);
 709        isac->mon_tx = NULL;
 710        if (isac->dch.l1)
 711                l1_event(isac->dch.l1, CLOSE_CHANNEL);
 712        mISDN_freedchannel(&isac->dch);
 713}
 714
 715static void
 716dbusy_timer_handler(struct timer_list *t)
 717{
 718        struct isac_hw *isac = from_timer(isac, t, dch.timer);
 719        int rbch, star;
 720        u_long flags;
 721
 722        if (test_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) {
 723                spin_lock_irqsave(isac->hwlock, flags);
 724                rbch = ReadISAC(isac, ISAC_RBCH);
 725                star = ReadISAC(isac, ISAC_STAR);
 726                pr_debug("%s: D-Channel Busy RBCH %02x STAR %02x\n",
 727                         isac->name, rbch, star);
 728                if (rbch & ISAC_RBCH_XAC) /* D-Channel Busy */
 729                        test_and_set_bit(FLG_L1_BUSY, &isac->dch.Flags);
 730                else {
 731                        /* discard frame; reset transceiver */
 732                        test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags);
 733                        if (isac->dch.tx_idx)
 734                                isac->dch.tx_idx = 0;
 735                        else
 736                                pr_info("%s: ISAC D-Channel Busy no tx_idx\n",
 737                                        isac->name);
 738                        /* Transmitter reset */
 739                        WriteISAC(isac, ISAC_CMDR, 0x01);
 740                }
 741                spin_unlock_irqrestore(isac->hwlock, flags);
 742        }
 743}
 744
 745static int
 746open_dchannel_caller(struct isac_hw *isac, struct channel_req *rq, void *caller)
 747{
 748        pr_debug("%s: %s dev(%d) open from %p\n", isac->name, __func__,
 749                 isac->dch.dev.id, caller);
 750        if (rq->protocol != ISDN_P_TE_S0)
 751                return -EINVAL;
 752        if (rq->adr.channel == 1)
 753                /* E-Channel not supported */
 754                return -EINVAL;
 755        rq->ch = &isac->dch.dev.D;
 756        rq->ch->protocol = rq->protocol;
 757        if (isac->dch.state == 7)
 758                _queue_data(rq->ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
 759                            0, NULL, GFP_KERNEL);
 760        return 0;
 761}
 762
 763static int
 764open_dchannel(struct isac_hw *isac, struct channel_req *rq)
 765{
 766        return open_dchannel_caller(isac, rq, __builtin_return_address(0));
 767}
 768
 769static const char *ISACVer[] =
 770{"2086/2186 V1.1", "2085 B1", "2085 B2",
 771 "2085 V2.3"};
 772
 773static int
 774isac_init(struct isac_hw *isac)
 775{
 776        u8 val;
 777        int err = 0;
 778
 779        if (!isac->dch.l1) {
 780                err = create_l1(&isac->dch, isac_l1cmd);
 781                if (err)
 782                        return err;
 783        }
 784        isac->mon_tx = NULL;
 785        isac->mon_rx = NULL;
 786        timer_setup(&isac->dch.timer, dbusy_timer_handler, 0);
 787        isac->mocr = 0xaa;
 788        if (isac->type & IPAC_TYPE_ISACX) {
 789                /* Disable all IRQ */
 790                WriteISAC(isac, ISACX_MASK, 0xff);
 791                val = ReadISAC(isac, ISACX_STARD);
 792                pr_debug("%s: ISACX STARD %x\n", isac->name, val);
 793                val = ReadISAC(isac, ISACX_ISTAD);
 794                pr_debug("%s: ISACX ISTAD %x\n", isac->name, val);
 795                val = ReadISAC(isac, ISACX_ISTA);
 796                pr_debug("%s: ISACX ISTA %x\n", isac->name, val);
 797                /* clear LDD */
 798                WriteISAC(isac, ISACX_TR_CONF0, 0x00);
 799                /* enable transmitter */
 800                WriteISAC(isac, ISACX_TR_CONF2, 0x00);
 801                /* transparent mode 0, RAC, stop/go */
 802                WriteISAC(isac, ISACX_MODED, 0xc9);
 803                /* all HDLC IRQ unmasked */
 804                val = ReadISAC(isac, ISACX_ID);
 805                if (isac->dch.debug & DEBUG_HW)
 806                        pr_notice("%s: ISACX Design ID %x\n",
 807                                  isac->name, val & 0x3f);
 808                val = ReadISAC(isac, ISACX_CIR0);
 809                pr_debug("%s: ISACX CIR0 %02X\n", isac->name, val);
 810                isac->state = val >> 4;
 811                isac_ph_state_change(isac);
 812                ph_command(isac, ISAC_CMD_RS);
 813                WriteISAC(isac, ISACX_MASK, IPACX__ON);
 814                WriteISAC(isac, ISACX_MASKD, 0x00);
 815        } else { /* old isac */
 816                WriteISAC(isac, ISAC_MASK, 0xff);
 817                val = ReadISAC(isac, ISAC_STAR);
 818                pr_debug("%s: ISAC STAR %x\n", isac->name, val);
 819                val = ReadISAC(isac, ISAC_MODE);
 820                pr_debug("%s: ISAC MODE %x\n", isac->name, val);
 821                val = ReadISAC(isac, ISAC_ADF2);
 822                pr_debug("%s: ISAC ADF2 %x\n", isac->name, val);
 823                val = ReadISAC(isac, ISAC_ISTA);
 824                pr_debug("%s: ISAC ISTA %x\n", isac->name, val);
 825                if (val & 0x01) {
 826                        val = ReadISAC(isac, ISAC_EXIR);
 827                        pr_debug("%s: ISAC EXIR %x\n", isac->name, val);
 828                }
 829                val = ReadISAC(isac, ISAC_RBCH);
 830                if (isac->dch.debug & DEBUG_HW)
 831                        pr_notice("%s: ISAC version (%x): %s\n", isac->name,
 832                                  val, ISACVer[(val >> 5) & 3]);
 833                isac->type |= ((val >> 5) & 3);
 834                if (!isac->adf2)
 835                        isac->adf2 = 0x80;
 836                if (!(isac->adf2 & 0x80)) { /* only IOM 2 Mode */
 837                        pr_info("%s: only support IOM2 mode but adf2=%02x\n",
 838                                isac->name, isac->adf2);
 839                        isac_release(isac);
 840                        return -EINVAL;
 841                }
 842                WriteISAC(isac, ISAC_ADF2, isac->adf2);
 843                WriteISAC(isac, ISAC_SQXR, 0x2f);
 844                WriteISAC(isac, ISAC_SPCR, 0x00);
 845                WriteISAC(isac, ISAC_STCR, 0x70);
 846                WriteISAC(isac, ISAC_MODE, 0xc9);
 847                WriteISAC(isac, ISAC_TIMR, 0x00);
 848                WriteISAC(isac, ISAC_ADF1, 0x00);
 849                val = ReadISAC(isac, ISAC_CIR0);
 850                pr_debug("%s: ISAC CIR0 %x\n", isac->name, val);
 851                isac->state = (val >> 2) & 0xf;
 852                isac_ph_state_change(isac);
 853                ph_command(isac, ISAC_CMD_RS);
 854                WriteISAC(isac, ISAC_MASK, 0);
 855        }
 856        return err;
 857}
 858
 859int
 860mISDNisac_init(struct isac_hw *isac, void *hw)
 861{
 862        mISDN_initdchannel(&isac->dch, MAX_DFRAME_LEN_L1, isac_ph_state_bh);
 863        isac->dch.hw = hw;
 864        isac->dch.dev.D.send = isac_l1hw;
 865        isac->init = isac_init;
 866        isac->release = isac_release;
 867        isac->ctrl = isac_ctrl;
 868        isac->open = open_dchannel;
 869        isac->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0);
 870        isac->dch.dev.nrbchan = 2;
 871        return 0;
 872}
 873EXPORT_SYMBOL(mISDNisac_init);
 874
 875static void
 876waitforCEC(struct hscx_hw *hx)
 877{
 878        u8 starb, to = 50;
 879
 880        while (to) {
 881                starb = ReadHSCX(hx, IPAC_STARB);
 882                if (!(starb & 0x04))
 883                        break;
 884                udelay(1);
 885                to--;
 886        }
 887        if (to < 50)
 888                pr_debug("%s: B%1d CEC %d us\n", hx->ip->name, hx->bch.nr,
 889                         50 - to);
 890        if (!to)
 891                pr_info("%s: B%1d CEC timeout\n", hx->ip->name, hx->bch.nr);
 892}
 893
 894
 895static void
 896waitforXFW(struct hscx_hw *hx)
 897{
 898        u8 starb, to = 50;
 899
 900        while (to) {
 901                starb = ReadHSCX(hx, IPAC_STARB);
 902                if ((starb & 0x44) == 0x40)
 903                        break;
 904                udelay(1);
 905                to--;
 906        }
 907        if (to < 50)
 908                pr_debug("%s: B%1d XFW %d us\n", hx->ip->name, hx->bch.nr,
 909                         50 - to);
 910        if (!to)
 911                pr_info("%s: B%1d XFW timeout\n", hx->ip->name, hx->bch.nr);
 912}
 913
 914static void
 915hscx_cmdr(struct hscx_hw *hx, u8 cmd)
 916{
 917        if (hx->ip->type & IPAC_TYPE_IPACX)
 918                WriteHSCX(hx, IPACX_CMDRB, cmd);
 919        else {
 920                waitforCEC(hx);
 921                WriteHSCX(hx, IPAC_CMDRB, cmd);
 922        }
 923}
 924
 925static void
 926hscx_empty_fifo(struct hscx_hw *hscx, u8 count)
 927{
 928        u8 *p;
 929        int maxlen;
 930
 931        pr_debug("%s: B%1d %d\n", hscx->ip->name, hscx->bch.nr, count);
 932        if (test_bit(FLG_RX_OFF, &hscx->bch.Flags)) {
 933                hscx->bch.dropcnt += count;
 934                hscx_cmdr(hscx, 0x80); /* RMC */
 935                return;
 936        }
 937        maxlen = bchannel_get_rxbuf(&hscx->bch, count);
 938        if (maxlen < 0) {
 939                hscx_cmdr(hscx, 0x80); /* RMC */
 940                if (hscx->bch.rx_skb)
 941                        skb_trim(hscx->bch.rx_skb, 0);
 942                pr_warning("%s.B%d: No bufferspace for %d bytes\n",
 943                           hscx->ip->name, hscx->bch.nr, count);
 944                return;
 945        }
 946        p = skb_put(hscx->bch.rx_skb, count);
 947
 948        if (hscx->ip->type & IPAC_TYPE_IPACX)
 949                hscx->ip->read_fifo(hscx->ip->hw,
 950                                    hscx->off + IPACX_RFIFOB, p, count);
 951        else
 952                hscx->ip->read_fifo(hscx->ip->hw,
 953                                    hscx->off, p, count);
 954
 955        hscx_cmdr(hscx, 0x80); /* RMC */
 956
 957        if (hscx->bch.debug & DEBUG_HW_BFIFO) {
 958                snprintf(hscx->log, 64, "B%1d-recv %s %d ",
 959                         hscx->bch.nr, hscx->ip->name, count);
 960                print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count);
 961        }
 962}
 963
 964static void
 965hscx_fill_fifo(struct hscx_hw *hscx)
 966{
 967        int count, more;
 968        u8 *p;
 969
 970        if (!hscx->bch.tx_skb) {
 971                if (!test_bit(FLG_TX_EMPTY, &hscx->bch.Flags))
 972                        return;
 973                count = hscx->fifo_size;
 974                more = 1;
 975                p = hscx->log;
 976                memset(p, hscx->bch.fill[0], count);
 977        } else {
 978                count = hscx->bch.tx_skb->len - hscx->bch.tx_idx;
 979                if (count <= 0)
 980                        return;
 981                p = hscx->bch.tx_skb->data + hscx->bch.tx_idx;
 982
 983                more = test_bit(FLG_TRANSPARENT, &hscx->bch.Flags) ? 1 : 0;
 984                if (count > hscx->fifo_size) {
 985                        count = hscx->fifo_size;
 986                        more = 1;
 987                }
 988                pr_debug("%s: B%1d %d/%d/%d\n", hscx->ip->name, hscx->bch.nr,
 989                         count, hscx->bch.tx_idx, hscx->bch.tx_skb->len);
 990                hscx->bch.tx_idx += count;
 991        }
 992        if (hscx->ip->type & IPAC_TYPE_IPACX)
 993                hscx->ip->write_fifo(hscx->ip->hw,
 994                                     hscx->off + IPACX_XFIFOB, p, count);
 995        else {
 996                waitforXFW(hscx);
 997                hscx->ip->write_fifo(hscx->ip->hw,
 998                                     hscx->off, p, count);
 999        }
1000        hscx_cmdr(hscx, more ? 0x08 : 0x0a);
1001
1002        if (hscx->bch.tx_skb && (hscx->bch.debug & DEBUG_HW_BFIFO)) {
1003                snprintf(hscx->log, 64, "B%1d-send %s %d ",
1004                         hscx->bch.nr, hscx->ip->name, count);
1005                print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count);
1006        }
1007}
1008
1009static void
1010hscx_xpr(struct hscx_hw *hx)
1011{
1012        if (hx->bch.tx_skb && hx->bch.tx_idx < hx->bch.tx_skb->len) {
1013                hscx_fill_fifo(hx);
1014        } else {
1015                if (hx->bch.tx_skb)
1016                        dev_kfree_skb(hx->bch.tx_skb);
1017                if (get_next_bframe(&hx->bch)) {
1018                        hscx_fill_fifo(hx);
1019                        test_and_clear_bit(FLG_TX_EMPTY, &hx->bch.Flags);
1020                } else if (test_bit(FLG_TX_EMPTY, &hx->bch.Flags)) {
1021                        hscx_fill_fifo(hx);
1022                }
1023        }
1024}
1025
1026static void
1027ipac_rme(struct hscx_hw *hx)
1028{
1029        int count;
1030        u8 rstab;
1031
1032        if (hx->ip->type & IPAC_TYPE_IPACX)
1033                rstab = ReadHSCX(hx, IPACX_RSTAB);
1034        else
1035                rstab = ReadHSCX(hx, IPAC_RSTAB);
1036        pr_debug("%s: B%1d RSTAB %02x\n", hx->ip->name, hx->bch.nr, rstab);
1037        if ((rstab & 0xf0) != 0xa0) {
1038                /* !(VFR && !RDO && CRC && !RAB) */
1039                if (!(rstab & 0x80)) {
1040                        if (hx->bch.debug & DEBUG_HW_BCHANNEL)
1041                                pr_notice("%s: B%1d invalid frame\n",
1042                                          hx->ip->name, hx->bch.nr);
1043                }
1044                if (rstab & 0x40) {
1045                        if (hx->bch.debug & DEBUG_HW_BCHANNEL)
1046                                pr_notice("%s: B%1d RDO proto=%x\n",
1047                                          hx->ip->name, hx->bch.nr,
1048                                          hx->bch.state);
1049                }
1050                if (!(rstab & 0x20)) {
1051                        if (hx->bch.debug & DEBUG_HW_BCHANNEL)
1052                                pr_notice("%s: B%1d CRC error\n",
1053                                          hx->ip->name, hx->bch.nr);
1054                }
1055                hscx_cmdr(hx, 0x80); /* Do RMC */
1056                return;
1057        }
1058        if (hx->ip->type & IPAC_TYPE_IPACX)
1059                count = ReadHSCX(hx, IPACX_RBCLB);
1060        else
1061                count = ReadHSCX(hx, IPAC_RBCLB);
1062        count &= (hx->fifo_size - 1);
1063        if (count == 0)
1064                count = hx->fifo_size;
1065        hscx_empty_fifo(hx, count);
1066        if (!hx->bch.rx_skb)
1067                return;
1068        if (hx->bch.rx_skb->len < 2) {
1069                pr_debug("%s: B%1d frame to short %d\n",
1070                         hx->ip->name, hx->bch.nr, hx->bch.rx_skb->len);
1071                skb_trim(hx->bch.rx_skb, 0);
1072        } else {
1073                skb_trim(hx->bch.rx_skb, hx->bch.rx_skb->len - 1);
1074                recv_Bchannel(&hx->bch, 0, false);
1075        }
1076}
1077
1078static void
1079ipac_irq(struct hscx_hw *hx, u8 ista)
1080{
1081        u8 istab, m, exirb = 0;
1082
1083        if (hx->ip->type & IPAC_TYPE_IPACX)
1084                istab = ReadHSCX(hx, IPACX_ISTAB);
1085        else if (hx->ip->type & IPAC_TYPE_IPAC) {
1086                istab = ReadHSCX(hx, IPAC_ISTAB);
1087                m = (hx->bch.nr & 1) ? IPAC__EXA : IPAC__EXB;
1088                if (m & ista) {
1089                        exirb = ReadHSCX(hx, IPAC_EXIRB);
1090                        pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
1091                                 hx->bch.nr, exirb);
1092                }
1093        } else if (hx->bch.nr & 2) { /* HSCX B */
1094                if (ista & (HSCX__EXA | HSCX__ICA))
1095                        ipac_irq(&hx->ip->hscx[0], ista);
1096                if (ista & HSCX__EXB) {
1097                        exirb = ReadHSCX(hx, IPAC_EXIRB);
1098                        pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
1099                                 hx->bch.nr, exirb);
1100                }
1101                istab = ista & 0xF8;
1102        } else { /* HSCX A */
1103                istab = ReadHSCX(hx, IPAC_ISTAB);
1104                if (ista & HSCX__EXA) {
1105                        exirb = ReadHSCX(hx, IPAC_EXIRB);
1106                        pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
1107                                 hx->bch.nr, exirb);
1108                }
1109                istab = istab & 0xF8;
1110        }
1111        if (exirb & IPAC_B_XDU)
1112                istab |= IPACX_B_XDU;
1113        if (exirb & IPAC_B_RFO)
1114                istab |= IPACX_B_RFO;
1115        pr_debug("%s: B%1d ISTAB %02x\n", hx->ip->name, hx->bch.nr, istab);
1116
1117        if (!test_bit(FLG_ACTIVE, &hx->bch.Flags))
1118                return;
1119
1120        if (istab & IPACX_B_RME)
1121                ipac_rme(hx);
1122
1123        if (istab & IPACX_B_RPF) {
1124                hscx_empty_fifo(hx, hx->fifo_size);
1125                if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags))
1126                        recv_Bchannel(&hx->bch, 0, false);
1127        }
1128
1129        if (istab & IPACX_B_RFO) {
1130                pr_debug("%s: B%1d RFO error\n", hx->ip->name, hx->bch.nr);
1131                hscx_cmdr(hx, 0x40);    /* RRES */
1132        }
1133
1134        if (istab & IPACX_B_XPR)
1135                hscx_xpr(hx);
1136
1137        if (istab & IPACX_B_XDU) {
1138                if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) {
1139                        if (test_bit(FLG_FILLEMPTY, &hx->bch.Flags))
1140                                test_and_set_bit(FLG_TX_EMPTY, &hx->bch.Flags);
1141                        hscx_xpr(hx);
1142                        return;
1143                }
1144                pr_debug("%s: B%1d XDU error at len %d\n", hx->ip->name,
1145                         hx->bch.nr, hx->bch.tx_idx);
1146                hx->bch.tx_idx = 0;
1147                hscx_cmdr(hx, 0x01);    /* XRES */
1148        }
1149}
1150
1151irqreturn_t
1152mISDNipac_irq(struct ipac_hw *ipac, int maxloop)
1153{
1154        int cnt = maxloop + 1;
1155        u8 ista, istad;
1156        struct isac_hw  *isac = &ipac->isac;
1157
1158        if (ipac->type & IPAC_TYPE_IPACX) {
1159                ista = ReadIPAC(ipac, ISACX_ISTA);
1160                while (ista && --cnt) {
1161                        pr_debug("%s: ISTA %02x\n", ipac->name, ista);
1162                        if (ista & IPACX__ICA)
1163                                ipac_irq(&ipac->hscx[0], ista);
1164                        if (ista & IPACX__ICB)
1165                                ipac_irq(&ipac->hscx[1], ista);
1166                        if (ista & (ISACX__ICD | ISACX__CIC))
1167                                mISDNisac_irq(&ipac->isac, ista);
1168                        ista = ReadIPAC(ipac, ISACX_ISTA);
1169                }
1170        } else if (ipac->type & IPAC_TYPE_IPAC) {
1171                ista = ReadIPAC(ipac, IPAC_ISTA);
1172                while (ista && --cnt) {
1173                        pr_debug("%s: ISTA %02x\n", ipac->name, ista);
1174                        if (ista & (IPAC__ICD | IPAC__EXD)) {
1175                                istad = ReadISAC(isac, ISAC_ISTA);
1176                                pr_debug("%s: ISTAD %02x\n", ipac->name, istad);
1177                                if (istad & IPAC_D_TIN2)
1178                                        pr_debug("%s TIN2 irq\n", ipac->name);
1179                                if (ista & IPAC__EXD)
1180                                        istad |= 1; /* ISAC EXI */
1181                                mISDNisac_irq(isac, istad);
1182                        }
1183                        if (ista & (IPAC__ICA | IPAC__EXA))
1184                                ipac_irq(&ipac->hscx[0], ista);
1185                        if (ista & (IPAC__ICB | IPAC__EXB))
1186                                ipac_irq(&ipac->hscx[1], ista);
1187                        ista = ReadIPAC(ipac, IPAC_ISTA);
1188                }
1189        } else if (ipac->type & IPAC_TYPE_HSCX) {
1190                while (--cnt) {
1191                        ista = ReadIPAC(ipac, IPAC_ISTAB + ipac->hscx[1].off);
1192                        pr_debug("%s: B2 ISTA %02x\n", ipac->name, ista);
1193                        if (ista)
1194                                ipac_irq(&ipac->hscx[1], ista);
1195                        istad = ReadISAC(isac, ISAC_ISTA);
1196                        pr_debug("%s: ISTAD %02x\n", ipac->name, istad);
1197                        if (istad)
1198                                mISDNisac_irq(isac, istad);
1199                        if (0 == (ista | istad))
1200                                break;
1201                }
1202        }
1203        if (cnt > maxloop) /* only for ISAC/HSCX without PCI IRQ test */
1204                return IRQ_NONE;
1205        if (cnt < maxloop)
1206                pr_debug("%s: %d irqloops cpu%d\n", ipac->name,
1207                         maxloop - cnt, smp_processor_id());
1208        if (maxloop && !cnt)
1209                pr_notice("%s: %d IRQ LOOP cpu%d\n", ipac->name,
1210                          maxloop, smp_processor_id());
1211        return IRQ_HANDLED;
1212}
1213EXPORT_SYMBOL(mISDNipac_irq);
1214
1215static int
1216hscx_mode(struct hscx_hw *hscx, u32 bprotocol)
1217{
1218        pr_debug("%s: HSCX %c protocol %x-->%x ch %d\n", hscx->ip->name,
1219                 '@' + hscx->bch.nr, hscx->bch.state, bprotocol, hscx->bch.nr);
1220        if (hscx->ip->type & IPAC_TYPE_IPACX) {
1221                if (hscx->bch.nr & 1) { /* B1 and ICA */
1222                        WriteIPAC(hscx->ip, ISACX_BCHA_TSDP_BC1, 0x80);
1223                        WriteIPAC(hscx->ip, ISACX_BCHA_CR, 0x88);
1224                } else { /* B2 and ICB */
1225                        WriteIPAC(hscx->ip, ISACX_BCHB_TSDP_BC1, 0x81);
1226                        WriteIPAC(hscx->ip, ISACX_BCHB_CR, 0x88);
1227                }
1228                switch (bprotocol) {
1229                case ISDN_P_NONE: /* init */
1230                        WriteHSCX(hscx, IPACX_MODEB, 0xC0);     /* rec off */
1231                        WriteHSCX(hscx, IPACX_EXMB,  0x30);     /* std adj. */
1232                        WriteHSCX(hscx, IPACX_MASKB, 0xFF);     /* ints off */
1233                        hscx_cmdr(hscx, 0x41);
1234                        test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
1235                        test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1236                        break;
1237                case ISDN_P_B_RAW:
1238                        WriteHSCX(hscx, IPACX_MODEB, 0x88);     /* ex trans */
1239                        WriteHSCX(hscx, IPACX_EXMB,  0x00);     /* trans */
1240                        hscx_cmdr(hscx, 0x41);
1241                        WriteHSCX(hscx, IPACX_MASKB, IPACX_B_ON);
1242                        test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1243                        break;
1244                case ISDN_P_B_HDLC:
1245                        WriteHSCX(hscx, IPACX_MODEB, 0xC0);     /* trans */
1246                        WriteHSCX(hscx, IPACX_EXMB,  0x00);     /* hdlc,crc */
1247                        hscx_cmdr(hscx, 0x41);
1248                        WriteHSCX(hscx, IPACX_MASKB, IPACX_B_ON);
1249                        test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
1250                        break;
1251                default:
1252                        pr_info("%s: protocol not known %x\n", hscx->ip->name,
1253                                bprotocol);
1254                        return -ENOPROTOOPT;
1255                }
1256        } else if (hscx->ip->type & IPAC_TYPE_IPAC) { /* IPAC */
1257                WriteHSCX(hscx, IPAC_CCR1, 0x82);
1258                WriteHSCX(hscx, IPAC_CCR2, 0x30);
1259                WriteHSCX(hscx, IPAC_XCCR, 0x07);
1260                WriteHSCX(hscx, IPAC_RCCR, 0x07);
1261                WriteHSCX(hscx, IPAC_TSAX, hscx->slot);
1262                WriteHSCX(hscx, IPAC_TSAR, hscx->slot);
1263                switch (bprotocol) {
1264                case ISDN_P_NONE:
1265                        WriteHSCX(hscx, IPAC_TSAX, 0x1F);
1266                        WriteHSCX(hscx, IPAC_TSAR, 0x1F);
1267                        WriteHSCX(hscx, IPAC_MODEB, 0x84);
1268                        WriteHSCX(hscx, IPAC_CCR1, 0x82);
1269                        WriteHSCX(hscx, IPAC_MASKB, 0xFF);      /* ints off */
1270                        test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
1271                        test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1272                        break;
1273                case ISDN_P_B_RAW:
1274                        WriteHSCX(hscx, IPAC_MODEB, 0xe4);      /* ex trans */
1275                        WriteHSCX(hscx, IPAC_CCR1, 0x82);
1276                        hscx_cmdr(hscx, 0x41);
1277                        WriteHSCX(hscx, IPAC_MASKB, 0);
1278                        test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1279                        break;
1280                case ISDN_P_B_HDLC:
1281                        WriteHSCX(hscx, IPAC_MODEB, 0x8c);
1282                        WriteHSCX(hscx, IPAC_CCR1, 0x8a);
1283                        hscx_cmdr(hscx, 0x41);
1284                        WriteHSCX(hscx, IPAC_MASKB, 0);
1285                        test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
1286                        break;
1287                default:
1288                        pr_info("%s: protocol not known %x\n", hscx->ip->name,
1289                                bprotocol);
1290                        return -ENOPROTOOPT;
1291                }
1292        } else if (hscx->ip->type & IPAC_TYPE_HSCX) { /* HSCX */
1293                WriteHSCX(hscx, IPAC_CCR1, 0x85);
1294                WriteHSCX(hscx, IPAC_CCR2, 0x30);
1295                WriteHSCX(hscx, IPAC_XCCR, 0x07);
1296                WriteHSCX(hscx, IPAC_RCCR, 0x07);
1297                WriteHSCX(hscx, IPAC_TSAX, hscx->slot);
1298                WriteHSCX(hscx, IPAC_TSAR, hscx->slot);
1299                switch (bprotocol) {
1300                case ISDN_P_NONE:
1301                        WriteHSCX(hscx, IPAC_TSAX, 0x1F);
1302                        WriteHSCX(hscx, IPAC_TSAR, 0x1F);
1303                        WriteHSCX(hscx, IPAC_MODEB, 0x84);
1304                        WriteHSCX(hscx, IPAC_CCR1, 0x85);
1305                        WriteHSCX(hscx, IPAC_MASKB, 0xFF);      /* ints off */
1306                        test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
1307                        test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1308                        break;
1309                case ISDN_P_B_RAW:
1310                        WriteHSCX(hscx, IPAC_MODEB, 0xe4);      /* ex trans */
1311                        WriteHSCX(hscx, IPAC_CCR1, 0x85);
1312                        hscx_cmdr(hscx, 0x41);
1313                        WriteHSCX(hscx, IPAC_MASKB, 0);
1314                        test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1315                        break;
1316                case ISDN_P_B_HDLC:
1317                        WriteHSCX(hscx, IPAC_MODEB, 0x8c);
1318                        WriteHSCX(hscx, IPAC_CCR1, 0x8d);
1319                        hscx_cmdr(hscx, 0x41);
1320                        WriteHSCX(hscx, IPAC_MASKB, 0);
1321                        test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
1322                        break;
1323                default:
1324                        pr_info("%s: protocol not known %x\n", hscx->ip->name,
1325                                bprotocol);
1326                        return -ENOPROTOOPT;
1327                }
1328        } else
1329                return -EINVAL;
1330        hscx->bch.state = bprotocol;
1331        return 0;
1332}
1333
1334static int
1335hscx_l2l1(struct mISDNchannel *ch, struct sk_buff *skb)
1336{
1337        struct bchannel *bch = container_of(ch, struct bchannel, ch);
1338        struct hscx_hw  *hx = container_of(bch, struct hscx_hw, bch);
1339        int ret = -EINVAL;
1340        struct mISDNhead *hh = mISDN_HEAD_P(skb);
1341        unsigned long flags;
1342
1343        switch (hh->prim) {
1344        case PH_DATA_REQ:
1345                spin_lock_irqsave(hx->ip->hwlock, flags);
1346                ret = bchannel_senddata(bch, skb);
1347                if (ret > 0) { /* direct TX */
1348                        ret = 0;
1349                        hscx_fill_fifo(hx);
1350                }
1351                spin_unlock_irqrestore(hx->ip->hwlock, flags);
1352                return ret;
1353        case PH_ACTIVATE_REQ:
1354                spin_lock_irqsave(hx->ip->hwlock, flags);
1355                if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
1356                        ret = hscx_mode(hx, ch->protocol);
1357                else
1358                        ret = 0;
1359                spin_unlock_irqrestore(hx->ip->hwlock, flags);
1360                if (!ret)
1361                        _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
1362                                    NULL, GFP_KERNEL);
1363                break;
1364        case PH_DEACTIVATE_REQ:
1365                spin_lock_irqsave(hx->ip->hwlock, flags);
1366                mISDN_clear_bchannel(bch);
1367                hscx_mode(hx, ISDN_P_NONE);
1368                spin_unlock_irqrestore(hx->ip->hwlock, flags);
1369                _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
1370                            NULL, GFP_KERNEL);
1371                ret = 0;
1372                break;
1373        default:
1374                pr_info("%s: %s unknown prim(%x,%x)\n",
1375                        hx->ip->name, __func__, hh->prim, hh->id);
1376                ret = -EINVAL;
1377        }
1378        if (!ret)
1379                dev_kfree_skb(skb);
1380        return ret;
1381}
1382
1383static int
1384channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
1385{
1386        return mISDN_ctrl_bchannel(bch, cq);
1387}
1388
1389static int
1390hscx_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
1391{
1392        struct bchannel *bch = container_of(ch, struct bchannel, ch);
1393        struct hscx_hw  *hx = container_of(bch, struct hscx_hw, bch);
1394        int ret = -EINVAL;
1395        u_long flags;
1396
1397        pr_debug("%s: %s cmd:%x %p\n", hx->ip->name, __func__, cmd, arg);
1398        switch (cmd) {
1399        case CLOSE_CHANNEL:
1400                test_and_clear_bit(FLG_OPEN, &bch->Flags);
1401                cancel_work_sync(&bch->workq);
1402                spin_lock_irqsave(hx->ip->hwlock, flags);
1403                mISDN_clear_bchannel(bch);
1404                hscx_mode(hx, ISDN_P_NONE);
1405                spin_unlock_irqrestore(hx->ip->hwlock, flags);
1406                ch->protocol = ISDN_P_NONE;
1407                ch->peer = NULL;
1408                module_put(hx->ip->owner);
1409                ret = 0;
1410                break;
1411        case CONTROL_CHANNEL:
1412                ret = channel_bctrl(bch, arg);
1413                break;
1414        default:
1415                pr_info("%s: %s unknown prim(%x)\n",
1416                        hx->ip->name, __func__, cmd);
1417        }
1418        return ret;
1419}
1420
1421static void
1422free_ipac(struct ipac_hw *ipac)
1423{
1424        isac_release(&ipac->isac);
1425}
1426
1427static const char *HSCXVer[] =
1428{"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7",
1429 "?8", "?9", "?10", "?11", "?12", "?13", "?14", "???"};
1430
1431
1432
1433static void
1434hscx_init(struct hscx_hw *hx)
1435{
1436        u8 val;
1437
1438        WriteHSCX(hx, IPAC_RAH2, 0xFF);
1439        WriteHSCX(hx, IPAC_XBCH, 0x00);
1440        WriteHSCX(hx, IPAC_RLCR, 0x00);
1441
1442        if (hx->ip->type & IPAC_TYPE_HSCX) {
1443                WriteHSCX(hx, IPAC_CCR1, 0x85);
1444                val = ReadHSCX(hx, HSCX_VSTR);
1445                pr_debug("%s: HSCX VSTR %02x\n", hx->ip->name, val);
1446                if (hx->bch.debug & DEBUG_HW)
1447                        pr_notice("%s: HSCX version %s\n", hx->ip->name,
1448                                  HSCXVer[val & 0x0f]);
1449        } else
1450                WriteHSCX(hx, IPAC_CCR1, 0x82);
1451        WriteHSCX(hx, IPAC_CCR2, 0x30);
1452        WriteHSCX(hx, IPAC_XCCR, 0x07);
1453        WriteHSCX(hx, IPAC_RCCR, 0x07);
1454}
1455
1456static int
1457ipac_init(struct ipac_hw *ipac)
1458{
1459        u8 val;
1460
1461        if (ipac->type & IPAC_TYPE_HSCX) {
1462                hscx_init(&ipac->hscx[0]);
1463                hscx_init(&ipac->hscx[1]);
1464                val = ReadIPAC(ipac, IPAC_ID);
1465        } else if (ipac->type & IPAC_TYPE_IPAC) {
1466                hscx_init(&ipac->hscx[0]);
1467                hscx_init(&ipac->hscx[1]);
1468                WriteIPAC(ipac, IPAC_MASK, IPAC__ON);
1469                val = ReadIPAC(ipac, IPAC_CONF);
1470                /* conf is default 0, but can be overwritten by card setup */
1471                pr_debug("%s: IPAC CONF %02x/%02x\n", ipac->name,
1472                         val, ipac->conf);
1473                WriteIPAC(ipac, IPAC_CONF, ipac->conf);
1474                val = ReadIPAC(ipac, IPAC_ID);
1475                if (ipac->hscx[0].bch.debug & DEBUG_HW)
1476                        pr_notice("%s: IPAC Design ID %02x\n", ipac->name, val);
1477        }
1478        /* nothing special for IPACX to do here */
1479        return isac_init(&ipac->isac);
1480}
1481
1482static int
1483open_bchannel(struct ipac_hw *ipac, struct channel_req *rq)
1484{
1485        struct bchannel         *bch;
1486
1487        if (rq->adr.channel == 0 || rq->adr.channel > 2)
1488                return -EINVAL;
1489        if (rq->protocol == ISDN_P_NONE)
1490                return -EINVAL;
1491        bch = &ipac->hscx[rq->adr.channel - 1].bch;
1492        if (test_and_set_bit(FLG_OPEN, &bch->Flags))
1493                return -EBUSY; /* b-channel can be only open once */
1494        test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
1495        bch->ch.protocol = rq->protocol;
1496        rq->ch = &bch->ch;
1497        return 0;
1498}
1499
1500static int
1501channel_ctrl(struct ipac_hw *ipac, struct mISDN_ctrl_req *cq)
1502{
1503        int     ret = 0;
1504
1505        switch (cq->op) {
1506        case MISDN_CTRL_GETOP:
1507                cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_L1_TIMER3;
1508                break;
1509        case MISDN_CTRL_LOOP:
1510                /* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
1511                if (cq->channel < 0 || cq->channel > 3) {
1512                        ret = -EINVAL;
1513                        break;
1514                }
1515                ret = ipac->ctrl(ipac, HW_TESTLOOP, cq->channel);
1516                break;
1517        case MISDN_CTRL_L1_TIMER3:
1518                ret = ipac->isac.ctrl(&ipac->isac, HW_TIMER3_VALUE, cq->p1);
1519                break;
1520        default:
1521                pr_info("%s: unknown CTRL OP %x\n", ipac->name, cq->op);
1522                ret = -EINVAL;
1523                break;
1524        }
1525        return ret;
1526}
1527
1528static int
1529ipac_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
1530{
1531        struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
1532        struct dchannel *dch = container_of(dev, struct dchannel, dev);
1533        struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
1534        struct ipac_hw *ipac = container_of(isac, struct ipac_hw, isac);
1535        struct channel_req *rq;
1536        int err = 0;
1537
1538        pr_debug("%s: DCTRL: %x %p\n", ipac->name, cmd, arg);
1539        switch (cmd) {
1540        case OPEN_CHANNEL:
1541                rq = arg;
1542                if (rq->protocol == ISDN_P_TE_S0)
1543                        err = open_dchannel_caller(isac, rq, __builtin_return_address(0));
1544                else
1545                        err = open_bchannel(ipac, rq);
1546                if (err)
1547                        break;
1548                if (!try_module_get(ipac->owner))
1549                        pr_info("%s: cannot get module\n", ipac->name);
1550                break;
1551        case CLOSE_CHANNEL:
1552                pr_debug("%s: dev(%d) close from %p\n", ipac->name,
1553                         dch->dev.id, __builtin_return_address(0));
1554                module_put(ipac->owner);
1555                break;
1556        case CONTROL_CHANNEL:
1557                err = channel_ctrl(ipac, arg);
1558                break;
1559        default:
1560                pr_debug("%s: unknown DCTRL command %x\n", ipac->name, cmd);
1561                return -EINVAL;
1562        }
1563        return err;
1564}
1565
1566u32
1567mISDNipac_init(struct ipac_hw *ipac, void *hw)
1568{
1569        u32 ret;
1570        u8 i;
1571
1572        ipac->hw = hw;
1573        if (ipac->isac.dch.debug & DEBUG_HW)
1574                pr_notice("%s: ipac type %x\n", ipac->name, ipac->type);
1575        if (ipac->type & IPAC_TYPE_HSCX) {
1576                ipac->isac.type = IPAC_TYPE_ISAC;
1577                ipac->hscx[0].off = 0;
1578                ipac->hscx[1].off = 0x40;
1579                ipac->hscx[0].fifo_size = 32;
1580                ipac->hscx[1].fifo_size = 32;
1581        } else if (ipac->type & IPAC_TYPE_IPAC) {
1582                ipac->isac.type = IPAC_TYPE_IPAC | IPAC_TYPE_ISAC;
1583                ipac->hscx[0].off = 0;
1584                ipac->hscx[1].off = 0x40;
1585                ipac->hscx[0].fifo_size = 64;
1586                ipac->hscx[1].fifo_size = 64;
1587        } else if (ipac->type & IPAC_TYPE_IPACX) {
1588                ipac->isac.type = IPAC_TYPE_IPACX | IPAC_TYPE_ISACX;
1589                ipac->hscx[0].off = IPACX_OFF_ICA;
1590                ipac->hscx[1].off = IPACX_OFF_ICB;
1591                ipac->hscx[0].fifo_size = 64;
1592                ipac->hscx[1].fifo_size = 64;
1593        } else
1594                return 0;
1595
1596        mISDNisac_init(&ipac->isac, hw);
1597
1598        ipac->isac.dch.dev.D.ctrl = ipac_dctrl;
1599
1600        for (i = 0; i < 2; i++) {
1601                ipac->hscx[i].bch.nr = i + 1;
1602                set_channelmap(i + 1, ipac->isac.dch.dev.channelmap);
1603                list_add(&ipac->hscx[i].bch.ch.list,
1604                         &ipac->isac.dch.dev.bchannels);
1605                mISDN_initbchannel(&ipac->hscx[i].bch, MAX_DATA_MEM,
1606                                   ipac->hscx[i].fifo_size);
1607                ipac->hscx[i].bch.ch.nr = i + 1;
1608                ipac->hscx[i].bch.ch.send = &hscx_l2l1;
1609                ipac->hscx[i].bch.ch.ctrl = hscx_bctrl;
1610                ipac->hscx[i].bch.hw = hw;
1611                ipac->hscx[i].ip = ipac;
1612                /* default values for IOM time slots
1613                 * can be overwritten by card */
1614                ipac->hscx[i].slot = (i == 0) ? 0x2f : 0x03;
1615        }
1616
1617        ipac->init = ipac_init;
1618        ipac->release = free_ipac;
1619
1620        ret =   (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
1621                (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
1622        return ret;
1623}
1624EXPORT_SYMBOL(mISDNipac_init);
1625
1626static int __init
1627isac_mod_init(void)
1628{
1629        pr_notice("mISDNipac module version %s\n", ISAC_REV);
1630        return 0;
1631}
1632
1633static void __exit
1634isac_mod_cleanup(void)
1635{
1636        pr_notice("mISDNipac module unloaded\n");
1637}
1638module_init(isac_mod_init);
1639module_exit(isac_mod_cleanup);
1640