linux/drivers/isdn/hisax/hfc_2bds0.c
<<
>>
Prefs
   1/* $Id: hfc_2bds0.c,v 1.18.2.6 2004/02/11 13:21:33 keil Exp $
   2 *
   3 * specific routines for CCD's HFC 2BDS0
   4 *
   5 * Author       Karsten Keil
   6 * Copyright    by Karsten Keil      <keil@isdn4linux.de>
   7 * 
   8 * This software may be used and distributed according to the terms
   9 * of the GNU General Public License, incorporated herein by reference.
  10 *
  11 */
  12
  13#include <linux/init.h>
  14#include <linux/sched.h>
  15#include <linux/slab.h>
  16#include "hisax.h"
  17#include "hfc_2bds0.h"
  18#include "isdnl1.h"
  19#include <linux/interrupt.h>
  20/*
  21#define KDEBUG_DEF
  22#include "kdebug.h"
  23*/
  24
  25#define byteout(addr,val) outb(val,addr)
  26#define bytein(addr) inb(addr)
  27
  28static void
  29dummyf(struct IsdnCardState *cs, u_char * data, int size)
  30{
  31        printk(KERN_WARNING "HiSax: hfcd dummy fifo called\n");
  32}
  33
  34static inline u_char
  35ReadReg(struct IsdnCardState *cs, int data, u_char reg)
  36{
  37        register u_char ret;
  38
  39        if (data) {
  40                if (cs->hw.hfcD.cip != reg) { 
  41                        cs->hw.hfcD.cip = reg;
  42                        byteout(cs->hw.hfcD.addr | 1, reg);
  43                }
  44                ret = bytein(cs->hw.hfcD.addr);
  45#ifdef HFC_REG_DEBUG
  46                if (cs->debug & L1_DEB_HSCX_FIFO && (data != 2))
  47                        debugl1(cs, "t3c RD %02x %02x", reg, ret);
  48#endif
  49        } else
  50                ret = bytein(cs->hw.hfcD.addr | 1);
  51        return (ret);
  52}
  53
  54static inline void
  55WriteReg(struct IsdnCardState *cs, int data, u_char reg, u_char value)
  56{
  57        if (cs->hw.hfcD.cip != reg) { 
  58                cs->hw.hfcD.cip = reg;
  59                byteout(cs->hw.hfcD.addr | 1, reg);
  60        }
  61        if (data)
  62                byteout(cs->hw.hfcD.addr, value);
  63#ifdef HFC_REG_DEBUG
  64        if (cs->debug & L1_DEB_HSCX_FIFO && (data != HFCD_DATA_NODEB))
  65                debugl1(cs, "t3c W%c %02x %02x", data ? 'D' : 'C', reg, value);
  66#endif
  67}
  68
  69/* Interface functions */
  70
  71static u_char
  72readreghfcd(struct IsdnCardState *cs, u_char offset)
  73{
  74        return(ReadReg(cs, HFCD_DATA, offset));
  75}
  76
  77static void
  78writereghfcd(struct IsdnCardState *cs, u_char offset, u_char value)
  79{
  80        WriteReg(cs, HFCD_DATA, offset, value);
  81}
  82
  83static inline int
  84WaitForBusy(struct IsdnCardState *cs)
  85{
  86        int to = 130;
  87
  88        while (!(ReadReg(cs, HFCD_DATA, HFCD_STAT) & HFCD_BUSY) && to) {
  89                udelay(1);
  90                to--;
  91        }
  92        if (!to)
  93                printk(KERN_WARNING "HiSax: WaitForBusy timeout\n");
  94        return (to);
  95}
  96
  97static inline int
  98WaitNoBusy(struct IsdnCardState *cs)
  99{
 100        int to = 130;
 101
 102        while ((ReadReg(cs, HFCD_STATUS, HFCD_STATUS) & HFCD_BUSY) && to) {
 103                udelay(1);
 104                to--;
 105        }
 106        if (!to) 
 107                printk(KERN_WARNING "HiSax: WaitNoBusy timeout\n");
 108        return (to);
 109}
 110
 111static int
 112SelFiFo(struct IsdnCardState *cs, u_char FiFo)
 113{
 114        u_char cip;
 115
 116        if (cs->hw.hfcD.fifo == FiFo)
 117                return(1);
 118        switch(FiFo) {
 119                case 0: cip = HFCB_FIFO | HFCB_Z1 | HFCB_SEND | HFCB_B1;
 120                        break;
 121                case 1: cip = HFCB_FIFO | HFCB_Z1 | HFCB_REC | HFCB_B1;
 122                        break;
 123                case 2: cip = HFCB_FIFO | HFCB_Z1 | HFCB_SEND | HFCB_B2;
 124                        break;
 125                case 3: cip = HFCB_FIFO | HFCB_Z1 | HFCB_REC | HFCB_B2;
 126                        break;
 127                case 4: cip = HFCD_FIFO | HFCD_Z1 | HFCD_SEND;
 128                        break;
 129                case 5: cip = HFCD_FIFO | HFCD_Z1 | HFCD_REC;
 130                        break;
 131                default:
 132                        debugl1(cs, "SelFiFo Error");
 133                        return(0);
 134        }
 135        cs->hw.hfcD.fifo = FiFo;
 136        WaitNoBusy(cs);
 137        cs->BC_Write_Reg(cs, HFCD_DATA, cip, 0);
 138        WaitForBusy(cs);
 139        return(2);
 140}
 141
 142static int
 143GetFreeFifoBytes_B(struct BCState *bcs)
 144{
 145        int s;
 146
 147        if (bcs->hw.hfc.f1 == bcs->hw.hfc.f2)
 148                return (bcs->cs->hw.hfcD.bfifosize);
 149        s = bcs->hw.hfc.send[bcs->hw.hfc.f1] - bcs->hw.hfc.send[bcs->hw.hfc.f2];
 150        if (s <= 0)
 151                s += bcs->cs->hw.hfcD.bfifosize;
 152        s = bcs->cs->hw.hfcD.bfifosize - s;
 153        return (s);
 154}
 155
 156static int
 157GetFreeFifoBytes_D(struct IsdnCardState *cs)
 158{
 159        int s;
 160
 161        if (cs->hw.hfcD.f1 == cs->hw.hfcD.f2)
 162                return (cs->hw.hfcD.dfifosize);
 163        s = cs->hw.hfcD.send[cs->hw.hfcD.f1] - cs->hw.hfcD.send[cs->hw.hfcD.f2];
 164        if (s <= 0)
 165                s += cs->hw.hfcD.dfifosize;
 166        s = cs->hw.hfcD.dfifosize - s;
 167        return (s);
 168}
 169
 170static int
 171ReadZReg(struct IsdnCardState *cs, u_char reg)
 172{
 173        int val;
 174
 175        WaitNoBusy(cs);
 176        val = 256 * ReadReg(cs, HFCD_DATA, reg | HFCB_Z_HIGH);
 177        WaitNoBusy(cs);
 178        val += ReadReg(cs, HFCD_DATA, reg | HFCB_Z_LOW);
 179        return (val);
 180}
 181
 182static struct sk_buff
 183*hfc_empty_fifo(struct BCState *bcs, int count)
 184{
 185        u_char *ptr;
 186        struct sk_buff *skb;
 187        struct IsdnCardState *cs = bcs->cs;
 188        int idx;
 189        int chksum;
 190        u_char stat, cip;
 191        
 192        if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
 193                debugl1(cs, "hfc_empty_fifo");
 194        idx = 0;
 195        if (count > HSCX_BUFMAX + 3) {
 196                if (cs->debug & L1_DEB_WARN)
 197                        debugl1(cs, "hfc_empty_fifo: incoming packet too large");
 198                cip = HFCB_FIFO | HFCB_FIFO_OUT | HFCB_REC | HFCB_CHANNEL(bcs->channel);
 199                while (idx++ < count) {
 200                        WaitNoBusy(cs);
 201                        ReadReg(cs, HFCD_DATA_NODEB, cip);
 202                }
 203                skb = NULL;
 204        } else if (count < 4) {
 205                if (cs->debug & L1_DEB_WARN)
 206                        debugl1(cs, "hfc_empty_fifo: incoming packet too small");
 207                cip = HFCB_FIFO | HFCB_FIFO_OUT | HFCB_REC | HFCB_CHANNEL(bcs->channel);
 208#ifdef ERROR_STATISTIC
 209                bcs->err_inv++;
 210#endif
 211                while ((idx++ < count) && WaitNoBusy(cs))
 212                        ReadReg(cs, HFCD_DATA_NODEB, cip);
 213                skb = NULL;
 214        } else if (!(skb = dev_alloc_skb(count - 3)))
 215                printk(KERN_WARNING "HFC: receive out of memory\n");
 216        else {
 217                ptr = skb_put(skb, count - 3);
 218                idx = 0;
 219                cip = HFCB_FIFO | HFCB_FIFO_OUT | HFCB_REC | HFCB_CHANNEL(bcs->channel);
 220                while (idx < (count - 3)) {
 221                        if (!WaitNoBusy(cs))
 222                                break;
 223                        *ptr = ReadReg(cs,  HFCD_DATA_NODEB, cip);
 224                        ptr++;
 225                        idx++;
 226                }
 227                if (idx != count - 3) {
 228                        debugl1(cs, "RFIFO BUSY error");
 229                        printk(KERN_WARNING "HFC FIFO channel %d BUSY Error\n", bcs->channel);
 230                        dev_kfree_skb_irq(skb);
 231                        skb = NULL;
 232                } else {
 233                        WaitNoBusy(cs);
 234                        chksum = (ReadReg(cs, HFCD_DATA, cip) << 8);
 235                        WaitNoBusy(cs);
 236                        chksum += ReadReg(cs, HFCD_DATA, cip);
 237                        WaitNoBusy(cs);
 238                        stat = ReadReg(cs, HFCD_DATA, cip);
 239                        if (cs->debug & L1_DEB_HSCX)
 240                                debugl1(cs, "hfc_empty_fifo %d chksum %x stat %x",
 241                                        bcs->channel, chksum, stat);
 242                        if (stat) {
 243                                debugl1(cs, "FIFO CRC error");
 244                                dev_kfree_skb_irq(skb);
 245                                skb = NULL;
 246#ifdef ERROR_STATISTIC
 247                                bcs->err_crc++;
 248#endif
 249                        }
 250                }
 251        }
 252        WaitForBusy(cs);
 253        WaitNoBusy(cs);
 254        stat = ReadReg(cs, HFCD_DATA, HFCB_FIFO | HFCB_F2_INC |
 255                HFCB_REC | HFCB_CHANNEL(bcs->channel));
 256        WaitForBusy(cs);
 257        return (skb);
 258}
 259
 260static void
 261hfc_fill_fifo(struct BCState *bcs)
 262{
 263        struct IsdnCardState *cs = bcs->cs;
 264        int idx, fcnt;
 265        int count;
 266        u_char cip;
 267
 268        if (!bcs->tx_skb)
 269                return;
 270        if (bcs->tx_skb->len <= 0)
 271                return;
 272        SelFiFo(cs, HFCB_SEND | HFCB_CHANNEL(bcs->channel)); 
 273        cip = HFCB_FIFO | HFCB_F1 | HFCB_SEND | HFCB_CHANNEL(bcs->channel);
 274        WaitNoBusy(cs);
 275        bcs->hw.hfc.f1 = ReadReg(cs, HFCD_DATA, cip);
 276        WaitNoBusy(cs);
 277        cip = HFCB_FIFO | HFCB_F2 | HFCB_SEND | HFCB_CHANNEL(bcs->channel);
 278        WaitNoBusy(cs);
 279        bcs->hw.hfc.f2 = ReadReg(cs, HFCD_DATA, cip);
 280        bcs->hw.hfc.send[bcs->hw.hfc.f1] = ReadZReg(cs, HFCB_FIFO | HFCB_Z1 | HFCB_SEND | HFCB_CHANNEL(bcs->channel));
 281        if (cs->debug & L1_DEB_HSCX)
 282                debugl1(cs, "hfc_fill_fifo %d f1(%d) f2(%d) z1(%x)",
 283                        bcs->channel, bcs->hw.hfc.f1, bcs->hw.hfc.f2,
 284                        bcs->hw.hfc.send[bcs->hw.hfc.f1]);
 285        fcnt = bcs->hw.hfc.f1 - bcs->hw.hfc.f2;
 286        if (fcnt < 0)
 287                fcnt += 32;
 288        if (fcnt > 30) {
 289                if (cs->debug & L1_DEB_HSCX)
 290                        debugl1(cs, "hfc_fill_fifo more as 30 frames");
 291                return;
 292        }
 293        count = GetFreeFifoBytes_B(bcs);
 294        if (cs->debug & L1_DEB_HSCX)
 295                debugl1(cs, "hfc_fill_fifo %d count(%u/%d),%lx",
 296                        bcs->channel, bcs->tx_skb->len,
 297                        count, current->state);
 298        if (count < bcs->tx_skb->len) {
 299                if (cs->debug & L1_DEB_HSCX)
 300                        debugl1(cs, "hfc_fill_fifo no fifo mem");
 301                return;
 302        }
 303        cip = HFCB_FIFO | HFCB_FIFO_IN | HFCB_SEND | HFCB_CHANNEL(bcs->channel);
 304        idx = 0;
 305        WaitForBusy(cs);
 306        WaitNoBusy(cs);
 307        WriteReg(cs, HFCD_DATA_NODEB, cip, bcs->tx_skb->data[idx++]);
 308        while (idx < bcs->tx_skb->len) {
 309                if (!WaitNoBusy(cs))
 310                        break;
 311                WriteReg(cs, HFCD_DATA_NODEB, cip, bcs->tx_skb->data[idx]);
 312                idx++;
 313        }
 314        if (idx != bcs->tx_skb->len) {
 315                debugl1(cs, "FIFO Send BUSY error");
 316                printk(KERN_WARNING "HFC S FIFO channel %d BUSY Error\n", bcs->channel);
 317        } else {
 318                bcs->tx_cnt -= bcs->tx_skb->len;
 319                if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
 320                        (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
 321                        u_long  flags;
 322                        spin_lock_irqsave(&bcs->aclock, flags);
 323                        bcs->ackcnt += bcs->tx_skb->len;
 324                        spin_unlock_irqrestore(&bcs->aclock, flags);
 325                        schedule_event(bcs, B_ACKPENDING);
 326                }
 327                dev_kfree_skb_any(bcs->tx_skb);
 328                bcs->tx_skb = NULL;
 329        }
 330        WaitForBusy(cs);
 331        WaitNoBusy(cs);
 332        ReadReg(cs, HFCD_DATA, HFCB_FIFO | HFCB_F1_INC | HFCB_SEND | HFCB_CHANNEL(bcs->channel));
 333        WaitForBusy(cs);
 334        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
 335        return;
 336}
 337
 338static void
 339hfc_send_data(struct BCState *bcs)
 340{
 341        struct IsdnCardState *cs = bcs->cs;
 342        
 343        if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 344                hfc_fill_fifo(bcs);
 345                test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 346        } else
 347                debugl1(cs,"send_data %d blocked", bcs->channel);
 348}
 349
 350static void
 351main_rec_2bds0(struct BCState *bcs)
 352{
 353        struct IsdnCardState *cs = bcs->cs;
 354        int z1, z2, rcnt;
 355        u_char f1, f2, cip;
 356        int receive, count = 5;
 357        struct sk_buff *skb;
 358
 359    Begin:
 360        count--;
 361        if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 362                debugl1(cs,"rec_data %d blocked", bcs->channel);
 363                return;
 364        }
 365        SelFiFo(cs, HFCB_REC | HFCB_CHANNEL(bcs->channel));
 366        cip = HFCB_FIFO | HFCB_F1 | HFCB_REC | HFCB_CHANNEL(bcs->channel);
 367        WaitNoBusy(cs);
 368        f1 = ReadReg(cs, HFCD_DATA, cip);
 369        cip = HFCB_FIFO | HFCB_F2 | HFCB_REC | HFCB_CHANNEL(bcs->channel);
 370        WaitNoBusy(cs);
 371        f2 = ReadReg(cs, HFCD_DATA, cip);
 372        if (f1 != f2) {
 373                if (cs->debug & L1_DEB_HSCX)
 374                        debugl1(cs, "hfc rec %d f1(%d) f2(%d)",
 375                                bcs->channel, f1, f2);
 376                z1 = ReadZReg(cs, HFCB_FIFO | HFCB_Z1 | HFCB_REC | HFCB_CHANNEL(bcs->channel));
 377                z2 = ReadZReg(cs, HFCB_FIFO | HFCB_Z2 | HFCB_REC | HFCB_CHANNEL(bcs->channel));
 378                rcnt = z1 - z2;
 379                if (rcnt < 0)
 380                        rcnt += cs->hw.hfcD.bfifosize;
 381                rcnt++;
 382                if (cs->debug & L1_DEB_HSCX)
 383                        debugl1(cs, "hfc rec %d z1(%x) z2(%x) cnt(%d)",
 384                                bcs->channel, z1, z2, rcnt);
 385                if ((skb = hfc_empty_fifo(bcs, rcnt))) {
 386                        skb_queue_tail(&bcs->rqueue, skb);
 387                        schedule_event(bcs, B_RCVBUFREADY);
 388                }
 389                rcnt = f1 -f2;
 390                if (rcnt<0)
 391                        rcnt += 32;
 392                if (rcnt>1)
 393                        receive = 1;
 394                else
 395                        receive = 0;
 396        } else
 397                receive = 0;
 398        test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 399        if (count && receive)
 400                goto Begin;     
 401        return;
 402}
 403
 404static void
 405mode_2bs0(struct BCState *bcs, int mode, int bc)
 406{
 407        struct IsdnCardState *cs = bcs->cs;
 408
 409        if (cs->debug & L1_DEB_HSCX)
 410                debugl1(cs, "HFCD bchannel mode %d bchan %d/%d",
 411                        mode, bc, bcs->channel);
 412        bcs->mode = mode;
 413        bcs->channel = bc;
 414        switch (mode) {
 415                case (L1_MODE_NULL):
 416                        if (bc) {
 417                                cs->hw.hfcD.conn |= 0x18;
 418                                cs->hw.hfcD.sctrl &= ~SCTRL_B2_ENA;
 419                        } else {
 420                                cs->hw.hfcD.conn |= 0x3;
 421                                cs->hw.hfcD.sctrl &= ~SCTRL_B1_ENA;
 422                        }
 423                        break;
 424                case (L1_MODE_TRANS):
 425                        if (bc) {
 426                                cs->hw.hfcD.ctmt |= 2;
 427                                cs->hw.hfcD.conn &= ~0x18;
 428                                cs->hw.hfcD.sctrl |= SCTRL_B2_ENA;
 429                        } else {
 430                                cs->hw.hfcD.ctmt |= 1;
 431                                cs->hw.hfcD.conn &= ~0x3;
 432                                cs->hw.hfcD.sctrl |= SCTRL_B1_ENA;
 433                        }
 434                        break;
 435                case (L1_MODE_HDLC):
 436                        if (bc) {
 437                                cs->hw.hfcD.ctmt &= ~2;
 438                                cs->hw.hfcD.conn &= ~0x18;
 439                                cs->hw.hfcD.sctrl |= SCTRL_B2_ENA;
 440                        } else {
 441                                cs->hw.hfcD.ctmt &= ~1;
 442                                cs->hw.hfcD.conn &= ~0x3;
 443                                cs->hw.hfcD.sctrl |= SCTRL_B1_ENA;
 444                        }
 445                        break;
 446        }
 447        WriteReg(cs, HFCD_DATA, HFCD_SCTRL, cs->hw.hfcD.sctrl);
 448        WriteReg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcD.ctmt);
 449        WriteReg(cs, HFCD_DATA, HFCD_CONN, cs->hw.hfcD.conn);
 450}
 451
 452static void
 453hfc_l2l1(struct PStack *st, int pr, void *arg)
 454{
 455        struct BCState *bcs = st->l1.bcs;
 456        struct sk_buff *skb = arg;
 457        u_long flags;
 458
 459        switch (pr) {
 460                case (PH_DATA | REQUEST):
 461                        spin_lock_irqsave(&bcs->cs->lock, flags);
 462                        if (bcs->tx_skb) {
 463                                skb_queue_tail(&bcs->squeue, skb);
 464                        } else {
 465                                bcs->tx_skb = skb;
 466//                              test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
 467                                bcs->cs->BC_Send_Data(bcs);
 468                        }
 469                        spin_unlock_irqrestore(&bcs->cs->lock, flags);
 470                        break;
 471                case (PH_PULL | INDICATION):
 472                        spin_lock_irqsave(&bcs->cs->lock, flags);
 473                        if (bcs->tx_skb) {
 474                                printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n");
 475                        } else {
 476//                              test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
 477                                bcs->tx_skb = skb;
 478                                bcs->cs->BC_Send_Data(bcs);
 479                        }
 480                        spin_unlock_irqrestore(&bcs->cs->lock, flags);
 481                        break;
 482                case (PH_PULL | REQUEST):
 483                        if (!bcs->tx_skb) {
 484                                test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
 485                                st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
 486                        } else
 487                                test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
 488                        break;
 489                case (PH_ACTIVATE | REQUEST):
 490                        spin_lock_irqsave(&bcs->cs->lock, flags);
 491                        test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
 492                        mode_2bs0(bcs, st->l1.mode, st->l1.bc);
 493                        spin_unlock_irqrestore(&bcs->cs->lock, flags);
 494                        l1_msg_b(st, pr, arg);
 495                        break;
 496                case (PH_DEACTIVATE | REQUEST):
 497                        l1_msg_b(st, pr, arg);
 498                        break;
 499                case (PH_DEACTIVATE | CONFIRM):
 500                        spin_lock_irqsave(&bcs->cs->lock, flags);
 501                        test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
 502                        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
 503                        mode_2bs0(bcs, 0, st->l1.bc);
 504                        spin_unlock_irqrestore(&bcs->cs->lock, flags);
 505                        st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
 506                        break;
 507        }
 508}
 509
 510static void
 511close_2bs0(struct BCState *bcs)
 512{
 513        mode_2bs0(bcs, 0, bcs->channel);
 514        if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
 515                skb_queue_purge(&bcs->rqueue);
 516                skb_queue_purge(&bcs->squeue);
 517                if (bcs->tx_skb) {
 518                        dev_kfree_skb_any(bcs->tx_skb);
 519                        bcs->tx_skb = NULL;
 520                        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
 521                }
 522        }
 523}
 524
 525static int
 526open_hfcstate(struct IsdnCardState *cs, struct BCState *bcs)
 527{
 528        if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
 529                skb_queue_head_init(&bcs->rqueue);
 530                skb_queue_head_init(&bcs->squeue);
 531        }
 532        bcs->tx_skb = NULL;
 533        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
 534        bcs->event = 0;
 535        bcs->tx_cnt = 0;
 536        return (0);
 537}
 538
 539static int
 540setstack_2b(struct PStack *st, struct BCState *bcs)
 541{
 542        bcs->channel = st->l1.bc;
 543        if (open_hfcstate(st->l1.hardware, bcs))
 544                return (-1);
 545        st->l1.bcs = bcs;
 546        st->l2.l2l1 = hfc_l2l1;
 547        setstack_manager(st);
 548        bcs->st = st;
 549        setstack_l1_B(st);
 550        return (0);
 551}
 552
 553static void
 554hfcd_bh(struct work_struct *work)
 555{
 556        struct IsdnCardState *cs =
 557                container_of(work, struct IsdnCardState, tqueue);
 558
 559        if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
 560                switch (cs->dc.hfcd.ph_state) {
 561                        case (0):
 562                                l1_msg(cs, HW_RESET | INDICATION, NULL);
 563                                break;
 564                        case (3):
 565                                l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
 566                                break;
 567                        case (8):
 568                                l1_msg(cs, HW_RSYNC | INDICATION, NULL);
 569                                break;
 570                        case (6):
 571                                l1_msg(cs, HW_INFO2 | INDICATION, NULL);
 572                                break;
 573                        case (7):
 574                                l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
 575                                break;
 576                        default:
 577                                break;
 578                }
 579        }
 580        if (test_and_clear_bit(D_RCVBUFREADY, &cs->event))
 581                DChannel_proc_rcv(cs);
 582        if (test_and_clear_bit(D_XMTBUFREADY, &cs->event))
 583                DChannel_proc_xmt(cs);
 584}
 585
 586static
 587int receive_dmsg(struct IsdnCardState *cs)
 588{
 589        struct sk_buff *skb;
 590        int idx;
 591        int rcnt, z1, z2;
 592        u_char stat, cip, f1, f2;
 593        int chksum;
 594        int count=5;
 595        u_char *ptr;
 596
 597        if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 598                debugl1(cs, "rec_dmsg blocked");
 599                return(1);
 600        }
 601        SelFiFo(cs, 4 | HFCD_REC);
 602        cip = HFCD_FIFO | HFCD_F1 | HFCD_REC;
 603        WaitNoBusy(cs);
 604        f1 = cs->readisac(cs, cip) & 0xf;
 605        cip = HFCD_FIFO | HFCD_F2 | HFCD_REC;
 606        WaitNoBusy(cs);
 607        f2 = cs->readisac(cs, cip) & 0xf;
 608        while ((f1 != f2) && count--) {
 609                z1 = ReadZReg(cs, HFCD_FIFO | HFCD_Z1 | HFCD_REC);
 610                z2 = ReadZReg(cs, HFCD_FIFO | HFCD_Z2 | HFCD_REC);
 611                rcnt = z1 - z2;
 612                if (rcnt < 0)
 613                        rcnt += cs->hw.hfcD.dfifosize;
 614                rcnt++;
 615                if (cs->debug & L1_DEB_ISAC)
 616                        debugl1(cs, "hfcd recd f1(%d) f2(%d) z1(%x) z2(%x) cnt(%d)",
 617                                f1, f2, z1, z2, rcnt);
 618                idx = 0;
 619                cip = HFCD_FIFO | HFCD_FIFO_OUT | HFCD_REC;
 620                if (rcnt > MAX_DFRAME_LEN + 3) {
 621                        if (cs->debug & L1_DEB_WARN)
 622                                debugl1(cs, "empty_fifo d: incoming packet too large");
 623                        while (idx < rcnt) {
 624                                if (!(WaitNoBusy(cs)))
 625                                        break;
 626                                ReadReg(cs, HFCD_DATA_NODEB, cip);
 627                                idx++;
 628                        }
 629                } else if (rcnt < 4) {
 630                        if (cs->debug & L1_DEB_WARN)
 631                                debugl1(cs, "empty_fifo d: incoming packet too small");
 632                        while ((idx++ < rcnt) && WaitNoBusy(cs))
 633                                ReadReg(cs, HFCD_DATA_NODEB, cip);
 634                } else if ((skb = dev_alloc_skb(rcnt - 3))) {
 635                        ptr = skb_put(skb, rcnt - 3);
 636                        while (idx < (rcnt - 3)) {
 637                                if (!(WaitNoBusy(cs)))
 638                                        break;
 639                                *ptr = ReadReg(cs, HFCD_DATA_NODEB, cip);
 640                                idx++;
 641                                ptr++;
 642                        }
 643                        if (idx != (rcnt - 3)) {
 644                                debugl1(cs, "RFIFO D BUSY error");
 645                                printk(KERN_WARNING "HFC DFIFO channel BUSY Error\n");
 646                                dev_kfree_skb_irq(skb);
 647                                skb = NULL;
 648#ifdef ERROR_STATISTIC
 649                                cs->err_rx++;
 650#endif
 651                        } else {
 652                                WaitNoBusy(cs);
 653                                chksum = (ReadReg(cs, HFCD_DATA, cip) << 8);
 654                                WaitNoBusy(cs);
 655                                chksum += ReadReg(cs, HFCD_DATA, cip);
 656                                WaitNoBusy(cs);
 657                                stat = ReadReg(cs, HFCD_DATA, cip);
 658                                if (cs->debug & L1_DEB_ISAC)
 659                                        debugl1(cs, "empty_dfifo chksum %x stat %x",
 660                                                chksum, stat);
 661                                if (stat) {
 662                                        debugl1(cs, "FIFO CRC error");
 663                                        dev_kfree_skb_irq(skb);
 664                                        skb = NULL;
 665#ifdef ERROR_STATISTIC
 666                                        cs->err_crc++;
 667#endif
 668                                } else {
 669                                        skb_queue_tail(&cs->rq, skb);
 670                                        schedule_event(cs, D_RCVBUFREADY);
 671                                }
 672                        }
 673                } else
 674                        printk(KERN_WARNING "HFC: D receive out of memory\n");
 675                WaitForBusy(cs);
 676                cip = HFCD_FIFO | HFCD_F2_INC | HFCD_REC;
 677                WaitNoBusy(cs);
 678                stat = ReadReg(cs, HFCD_DATA, cip);
 679                WaitForBusy(cs);
 680                cip = HFCD_FIFO | HFCD_F2 | HFCD_REC;
 681                WaitNoBusy(cs);
 682                f2 = cs->readisac(cs, cip) & 0xf;
 683        }
 684        test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 685        return(1);
 686} 
 687
 688static void
 689hfc_fill_dfifo(struct IsdnCardState *cs)
 690{
 691        int idx, fcnt;
 692        int count;
 693        u_char cip;
 694
 695        if (!cs->tx_skb)
 696                return;
 697        if (cs->tx_skb->len <= 0)
 698                return;
 699
 700        SelFiFo(cs, 4 | HFCD_SEND);
 701        cip = HFCD_FIFO | HFCD_F1 | HFCD_SEND;
 702        WaitNoBusy(cs);
 703        cs->hw.hfcD.f1 = ReadReg(cs, HFCD_DATA, cip) & 0xf;
 704        WaitNoBusy(cs);
 705        cip = HFCD_FIFO | HFCD_F2 | HFCD_SEND;
 706        cs->hw.hfcD.f2 = ReadReg(cs, HFCD_DATA, cip) & 0xf;
 707        cs->hw.hfcD.send[cs->hw.hfcD.f1] = ReadZReg(cs, HFCD_FIFO | HFCD_Z1 | HFCD_SEND);
 708        if (cs->debug & L1_DEB_ISAC)
 709                debugl1(cs, "hfc_fill_Dfifo f1(%d) f2(%d) z1(%x)",
 710                        cs->hw.hfcD.f1, cs->hw.hfcD.f2,
 711                        cs->hw.hfcD.send[cs->hw.hfcD.f1]);
 712        fcnt = cs->hw.hfcD.f1 - cs->hw.hfcD.f2;
 713        if (fcnt < 0)
 714                fcnt += 16;
 715        if (fcnt > 14) {
 716                if (cs->debug & L1_DEB_HSCX)
 717                        debugl1(cs, "hfc_fill_Dfifo more as 14 frames");
 718                return;
 719        }
 720        count = GetFreeFifoBytes_D(cs);
 721        if (cs->debug & L1_DEB_ISAC)
 722                debugl1(cs, "hfc_fill_Dfifo count(%u/%d)",
 723                        cs->tx_skb->len, count);
 724        if (count < cs->tx_skb->len) {
 725                if (cs->debug & L1_DEB_ISAC)
 726                        debugl1(cs, "hfc_fill_Dfifo no fifo mem");
 727                return;
 728        }
 729        cip = HFCD_FIFO | HFCD_FIFO_IN | HFCD_SEND;
 730        idx = 0;
 731        WaitForBusy(cs);
 732        WaitNoBusy(cs);
 733        WriteReg(cs, HFCD_DATA_NODEB, cip, cs->tx_skb->data[idx++]);
 734        while (idx < cs->tx_skb->len) {
 735                if (!(WaitNoBusy(cs)))
 736                        break;
 737                WriteReg(cs, HFCD_DATA_NODEB, cip, cs->tx_skb->data[idx]);
 738                idx++;
 739        }
 740        if (idx != cs->tx_skb->len) {
 741                debugl1(cs, "DFIFO Send BUSY error");
 742                printk(KERN_WARNING "HFC S DFIFO channel BUSY Error\n");
 743        }
 744        WaitForBusy(cs);
 745        WaitNoBusy(cs);
 746        ReadReg(cs, HFCD_DATA, HFCD_FIFO | HFCD_F1_INC | HFCD_SEND);
 747        dev_kfree_skb_any(cs->tx_skb);
 748        cs->tx_skb = NULL;
 749        WaitForBusy(cs);
 750        return;
 751}
 752
 753static 
 754struct BCState *Sel_BCS(struct IsdnCardState *cs, int channel)
 755{
 756        if (cs->bcs[0].mode && (cs->bcs[0].channel == channel))
 757                return(&cs->bcs[0]);
 758        else if (cs->bcs[1].mode && (cs->bcs[1].channel == channel))
 759                return(&cs->bcs[1]);
 760        else
 761                return(NULL);
 762}
 763
 764void
 765hfc2bds0_interrupt(struct IsdnCardState *cs, u_char val)
 766{
 767        u_char exval;
 768        struct BCState *bcs;
 769        int count=15;
 770
 771        if (cs->debug & L1_DEB_ISAC)
 772                debugl1(cs, "HFCD irq %x %s", val,
 773                        test_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags) ?
 774                        "locked" : "unlocked");
 775        val &= cs->hw.hfcD.int_m1;
 776        if (val & 0x40) { /* TE state machine irq */
 777                exval = cs->readisac(cs, HFCD_STATES) & 0xf;
 778                if (cs->debug & L1_DEB_ISAC)
 779                        debugl1(cs, "ph_state chg %d->%d", cs->dc.hfcd.ph_state,
 780                                exval);
 781                cs->dc.hfcd.ph_state = exval;
 782                schedule_event(cs, D_L1STATECHANGE);
 783                val &= ~0x40;
 784        }
 785        while (val) {
 786                if (test_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 787                        cs->hw.hfcD.int_s1 |= val;
 788                        return;
 789                }
 790                if (cs->hw.hfcD.int_s1 & 0x18) {
 791                        exval = val;
 792                        val =  cs->hw.hfcD.int_s1;
 793                        cs->hw.hfcD.int_s1 = exval;
 794                }       
 795                if (val & 0x08) {
 796                        if (!(bcs=Sel_BCS(cs, 0))) {
 797                                if (cs->debug)
 798                                        debugl1(cs, "hfcd spurious 0x08 IRQ");
 799                        } else 
 800                                main_rec_2bds0(bcs);
 801                }
 802                if (val & 0x10) {
 803                        if (!(bcs=Sel_BCS(cs, 1))) {
 804                                if (cs->debug)
 805                                        debugl1(cs, "hfcd spurious 0x10 IRQ");
 806                        } else 
 807                                main_rec_2bds0(bcs);
 808                }
 809                if (val & 0x01) {
 810                        if (!(bcs=Sel_BCS(cs, 0))) {
 811                                if (cs->debug)
 812                                        debugl1(cs, "hfcd spurious 0x01 IRQ");
 813                        } else {
 814                                if (bcs->tx_skb) {
 815                                        if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 816                                                hfc_fill_fifo(bcs);
 817                                                test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 818                                        } else
 819                                                debugl1(cs,"fill_data %d blocked", bcs->channel);
 820                                } else {
 821                                        if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
 822                                                if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 823                                                        hfc_fill_fifo(bcs);
 824                                                        test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 825                                                } else
 826                                                        debugl1(cs,"fill_data %d blocked", bcs->channel);
 827                                        } else {
 828                                                schedule_event(bcs, B_XMTBUFREADY);
 829                                        }
 830                                }
 831                        }
 832                }
 833                if (val & 0x02) {
 834                        if (!(bcs=Sel_BCS(cs, 1))) {
 835                                if (cs->debug)
 836                                        debugl1(cs, "hfcd spurious 0x02 IRQ");
 837                        } else {
 838                                if (bcs->tx_skb) {
 839                                        if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 840                                                hfc_fill_fifo(bcs);
 841                                                test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 842                                        } else
 843                                                debugl1(cs,"fill_data %d blocked", bcs->channel);
 844                                } else {
 845                                        if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
 846                                                if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 847                                                        hfc_fill_fifo(bcs);
 848                                                        test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 849                                                } else
 850                                                        debugl1(cs,"fill_data %d blocked", bcs->channel);
 851                                        } else {
 852                                                schedule_event(bcs, B_XMTBUFREADY);
 853                                        }
 854                                }
 855                        }
 856                }
 857                if (val & 0x20) {       /* receive dframe */
 858                        receive_dmsg(cs);
 859                }
 860                if (val & 0x04) {       /* dframe transmitted */
 861                        if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
 862                                del_timer(&cs->dbusytimer);
 863                        if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
 864                                schedule_event(cs, D_CLEARBUSY);
 865                        if (cs->tx_skb) {
 866                                if (cs->tx_skb->len) {
 867                                        if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 868                                                hfc_fill_dfifo(cs);
 869                                                test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 870                                        } else {
 871                                                debugl1(cs, "hfc_fill_dfifo irq blocked");
 872                                        }
 873                                        goto afterXPR;
 874                                } else {
 875                                        dev_kfree_skb_irq(cs->tx_skb);
 876                                        cs->tx_cnt = 0;
 877                                        cs->tx_skb = NULL;
 878                                }
 879                        }
 880                        if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
 881                                cs->tx_cnt = 0;
 882                                if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 883                                        hfc_fill_dfifo(cs);
 884                                        test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 885                                } else {
 886                                        debugl1(cs, "hfc_fill_dfifo irq blocked");
 887                                }
 888                        } else
 889                                schedule_event(cs, D_XMTBUFREADY);
 890                }
 891      afterXPR:
 892                if (cs->hw.hfcD.int_s1 && count--) {
 893                        val = cs->hw.hfcD.int_s1;
 894                        cs->hw.hfcD.int_s1 = 0;
 895                        if (cs->debug & L1_DEB_ISAC)
 896                                debugl1(cs, "HFCD irq %x loop %d", val, 15-count);
 897                } else
 898                        val = 0;
 899        }
 900}
 901
 902static void
 903HFCD_l1hw(struct PStack *st, int pr, void *arg)
 904{
 905        struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
 906        struct sk_buff *skb = arg;
 907        u_long flags;
 908        
 909        switch (pr) {
 910                case (PH_DATA | REQUEST):
 911                        if (cs->debug & DEB_DLOG_HEX)
 912                                LogFrame(cs, skb->data, skb->len);
 913                        if (cs->debug & DEB_DLOG_VERBOSE)
 914                                dlogframe(cs, skb, 0);
 915                        spin_lock_irqsave(&cs->lock, flags);
 916                        if (cs->tx_skb) {
 917                                skb_queue_tail(&cs->sq, skb);
 918#ifdef L2FRAME_DEBUG            /* psa */
 919                                if (cs->debug & L1_DEB_LAPD)
 920                                        Logl2Frame(cs, skb, "PH_DATA Queued", 0);
 921#endif
 922                        } else {
 923                                cs->tx_skb = skb;
 924                                cs->tx_cnt = 0;
 925#ifdef L2FRAME_DEBUG            /* psa */
 926                                if (cs->debug & L1_DEB_LAPD)
 927                                        Logl2Frame(cs, skb, "PH_DATA", 0);
 928#endif
 929                                if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 930                                        hfc_fill_dfifo(cs);
 931                                        test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 932                                } else
 933                                        debugl1(cs, "hfc_fill_dfifo blocked");
 934
 935                        }
 936                        spin_unlock_irqrestore(&cs->lock, flags);
 937                        break;
 938                case (PH_PULL | INDICATION):
 939                        spin_lock_irqsave(&cs->lock, flags);
 940                        if (cs->tx_skb) {
 941                                if (cs->debug & L1_DEB_WARN)
 942                                        debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
 943                                skb_queue_tail(&cs->sq, skb);
 944                                spin_unlock_irqrestore(&cs->lock, flags);
 945                                break;
 946                        }
 947                        if (cs->debug & DEB_DLOG_HEX)
 948                                LogFrame(cs, skb->data, skb->len);
 949                        if (cs->debug & DEB_DLOG_VERBOSE)
 950                                dlogframe(cs, skb, 0);
 951                        cs->tx_skb = skb;
 952                        cs->tx_cnt = 0;
 953#ifdef L2FRAME_DEBUG            /* psa */
 954                        if (cs->debug & L1_DEB_LAPD)
 955                                Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
 956#endif
 957                        if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 958                                hfc_fill_dfifo(cs);
 959                                test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 960                        } else
 961                                debugl1(cs, "hfc_fill_dfifo blocked");
 962                        spin_unlock_irqrestore(&cs->lock, flags);
 963                        break;
 964                case (PH_PULL | REQUEST):
 965#ifdef L2FRAME_DEBUG            /* psa */
 966                        if (cs->debug & L1_DEB_LAPD)
 967                                debugl1(cs, "-> PH_REQUEST_PULL");
 968#endif
 969                        if (!cs->tx_skb) {
 970                                test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
 971                                st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
 972                        } else
 973                                test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
 974                        break;
 975                case (HW_RESET | REQUEST):
 976                        spin_lock_irqsave(&cs->lock, flags);
 977                        cs->writeisac(cs, HFCD_STATES, HFCD_LOAD_STATE | 3); /* HFC ST 3 */
 978                        udelay(6);
 979                        cs->writeisac(cs, HFCD_STATES, 3); /* HFC ST 2 */
 980                        cs->hw.hfcD.mst_m |= HFCD_MASTER;
 981                        cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m);
 982                        cs->writeisac(cs, HFCD_STATES, HFCD_ACTIVATE | HFCD_DO_ACTION);
 983                        spin_unlock_irqrestore(&cs->lock, flags);
 984                        l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
 985                        break;
 986                case (HW_ENABLE | REQUEST):
 987                        spin_lock_irqsave(&cs->lock, flags);
 988                        cs->writeisac(cs, HFCD_STATES, HFCD_ACTIVATE | HFCD_DO_ACTION);
 989                        spin_unlock_irqrestore(&cs->lock, flags);
 990                        break;
 991                case (HW_DEACTIVATE | REQUEST):
 992                        spin_lock_irqsave(&cs->lock, flags);
 993                        cs->hw.hfcD.mst_m &= ~HFCD_MASTER;
 994                        cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m);
 995                        spin_unlock_irqrestore(&cs->lock, flags);
 996                        break;
 997                case (HW_INFO3 | REQUEST):
 998                        spin_lock_irqsave(&cs->lock, flags);
 999                        cs->hw.hfcD.mst_m |= HFCD_MASTER;
1000                        cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m);
1001                        spin_unlock_irqrestore(&cs->lock, flags);
1002                        break;
1003                default:
1004                        if (cs->debug & L1_DEB_WARN)
1005                                debugl1(cs, "hfcd_l1hw unknown pr %4x", pr);
1006                        break;
1007        }
1008}
1009
1010static void
1011setstack_hfcd(struct PStack *st, struct IsdnCardState *cs)
1012{
1013        st->l1.l1hw = HFCD_l1hw;
1014}
1015
1016static void
1017hfc_dbusy_timer(struct IsdnCardState *cs)
1018{
1019}
1020
1021static unsigned int
1022*init_send_hfcd(int cnt)
1023{
1024        int i;
1025        unsigned *send;
1026
1027        if (!(send = kmalloc(cnt * sizeof(unsigned int), GFP_ATOMIC))) {
1028                printk(KERN_WARNING
1029                       "HiSax: No memory for hfcd.send\n");
1030                return(NULL);
1031        }
1032        for (i = 0; i < cnt; i++)
1033                send[i] = 0x1fff;
1034        return(send);
1035}
1036
1037void
1038init2bds0(struct IsdnCardState *cs)
1039{
1040        cs->setstack_d = setstack_hfcd;
1041        if (!cs->hw.hfcD.send)
1042                cs->hw.hfcD.send = init_send_hfcd(16);
1043        if (!cs->bcs[0].hw.hfc.send)
1044                cs->bcs[0].hw.hfc.send = init_send_hfcd(32);
1045        if (!cs->bcs[1].hw.hfc.send)
1046                cs->bcs[1].hw.hfc.send = init_send_hfcd(32);
1047        cs->BC_Send_Data = &hfc_send_data;
1048        cs->bcs[0].BC_SetStack = setstack_2b;
1049        cs->bcs[1].BC_SetStack = setstack_2b;
1050        cs->bcs[0].BC_Close = close_2bs0;
1051        cs->bcs[1].BC_Close = close_2bs0;
1052        mode_2bs0(cs->bcs, 0, 0);
1053        mode_2bs0(cs->bcs + 1, 0, 1);
1054}
1055
1056void
1057release2bds0(struct IsdnCardState *cs)
1058{
1059        kfree(cs->bcs[0].hw.hfc.send);
1060        cs->bcs[0].hw.hfc.send = NULL;
1061        kfree(cs->bcs[1].hw.hfc.send);
1062        cs->bcs[1].hw.hfc.send = NULL;
1063        kfree(cs->hw.hfcD.send);
1064        cs->hw.hfcD.send = NULL;
1065}
1066
1067void
1068set_cs_func(struct IsdnCardState *cs)
1069{
1070        cs->readisac = &readreghfcd;
1071        cs->writeisac = &writereghfcd;
1072        cs->readisacfifo = &dummyf;
1073        cs->writeisacfifo = &dummyf;
1074        cs->BC_Read_Reg = &ReadReg;
1075        cs->BC_Write_Reg = &WriteReg;
1076        cs->dbusytimer.function = (void *) hfc_dbusy_timer;
1077        cs->dbusytimer.data = (long) cs;
1078        init_timer(&cs->dbusytimer);
1079        INIT_WORK(&cs->tqueue, hfcd_bh);
1080}
1081