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