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