From 8cc4723f8401c24060e3ada5149d1d19450b4829 Mon Sep 17 00:00:00 2001 From: Kai Germaschewski Date: Thu, 6 Mar 2003 13:23:06 -0600 Subject: [PATCH] ISDN/HiSax: Remove amd7930.c This has been around for many years but was never finished. No need to carry it on to yet another stable kernel. --- drivers/isdn/hisax/amd7930.c | 717 ----------------------------------- 1 file changed, 717 deletions(-) delete mode 100644 drivers/isdn/hisax/amd7930.c diff --git a/drivers/isdn/hisax/amd7930.c b/drivers/isdn/hisax/amd7930.c deleted file mode 100644 index e39d75fe1e35e..0000000000000 --- a/drivers/isdn/hisax/amd7930.c +++ /dev/null @@ -1,717 +0,0 @@ -/* $Id: amd7930.c,v 1.5.6.4 2001/09/23 22:24:46 kai Exp $ - * - * HiSax ISDN driver - chip specific routines for AMD 7930 - * - * Author Brent Baccala - * Copyright by Brent Baccala - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * - Existing ISDN HiSax driver provides all the smarts - * - it compiles, runs, talks to an isolated phone switch, connects - * to a Cisco, pings go through - * - AMD 7930 support only (no DBRI yet) - * - no US NI-1 support (may not work on US phone system - untested) - * - periodic packet loss, apparently due to lost interrupts - * - ISDN sometimes freezes, requiring reboot before it will work again - * - * The code is unreliable enough to be consider alpha - * - * This file is (c) under GNU General Public License - * - * Advanced Micro Devices' Am79C30A is an ISDN/audio chip used in the - * SparcStation 1+. The chip provides microphone and speaker interfaces - * which provide mono-channel audio at 8K samples per second via either - * 8-bit A-law or 8-bit mu-law encoding. Also, the chip features an - * ISDN BRI Line Interface Unit (LIU), I.430 S/T physical interface, - * which performs basic D channel LAPD processing and provides raw - * B channel data. The digital audio channel, the two ISDN B channels, - * and two 64 Kbps channels to the microprocessor are all interconnected - * via a multiplexer. - * - * This driver interfaces to the Linux HiSax ISDN driver, which performs - * all high-level Q.921 and Q.931 ISDN functions. The file is not - * itself a hardware driver; rather it uses functions exported by - * the AMD7930 driver in the sparcaudio subsystem (drivers/sbus/audio), - * allowing the chip to be simultaneously used for both audio and ISDN data. - * The hardware driver does _no_ buffering, but provides several callbacks - * which are called during interrupt service and should therefore run quickly. - * - * D channel transmission is performed by passing the hardware driver the - * address and size of an skb's data area, then waiting for a callback - * to signal successful transmission of the packet. A task is then - * queued to notify the HiSax driver that another packet may be transmitted. - * - * D channel reception is quite simple, mainly because of: - * 1) the slow speed of the D channel - 16 kbps, and - * 2) the presence of an 8- or 32-byte (depending on chip version) FIFO - * to buffer the D channel data on the chip - * Worst case scenario of back-to-back packets with the 8 byte buffer - * at 16 kbps yields an service time of 4 ms - long enough to preclude - * the need for fancy buffering. We queue a background task that copies - * data out of the receive buffer into an skb, and the hardware driver - * simply does nothing until we're done with the receive buffer and - * reset it for a new packet. - * - * B channel processing is more complex, because of: - * 1) the faster speed - 64 kbps, - * 2) the lack of any on-chip buffering (it interrupts for every byte), and - * 3) the lack of any chip support for HDLC encapsulation - * - * The HiSax driver can put each B channel into one of three modes - - * L1_MODE_NULL (channel disabled), L1_MODE_TRANS (transparent data relay), - * and L1_MODE_HDLC (HDLC encapsulation by low-level driver). - * L1_MODE_HDLC is the most common, used for almost all "pure" digital - * data sessions. L1_MODE_TRANS is used for ISDN audio. - * - * HDLC B channel transmission is performed via a large buffer into - * which the skb is copied while performing HDLC bit-stuffing. A CRC - * is computed and attached to the end of the buffer, which is then - * passed to the low-level routines for raw transmission. Once - * transmission is complete, the hardware driver is set to enter HDLC - * idle by successive transmission of mark (all 1) bytes, waiting for - * the ISDN driver to prepare another packet for transmission and - * deliver it. - * - * HDLC B channel reception is performed via an X-byte ring buffer - * divided into N sections of X/N bytes each. Defaults: X=256 bytes, N=4. - * As the hardware driver notifies us that each section is full, we - * hand it the next section and schedule a background task to peruse - * the received section, bit-by-bit, with an HDLC decoder. As - * packets are detected, they are copied into a large buffer while - * decoding HDLC bit-stuffing. The ending CRC is verified, and if - * it is correct, we alloc a new skb of the correct length (which we - * now know), copy the packet into it, and hand it to the upper layers. - * Optimization: for large packets, we hand the buffer (which also - * happens to be an skb) directly to the upper layer after an skb_trim, - * and alloc a new large buffer for future packets, thus avoiding a copy. - * Then we return to HDLC processing; state is saved between calls. - * - */ - -#include "hisax.h" -#include "../../sbus/audio/amd7930.h" -#include "isac.h" -#include "isdnl1.h" -#include "rawhdlc.h" -#include - -static const char *amd7930_revision = "$Revision: 1.5.6.4 $"; - -#define RCV_BUFSIZE 1024 /* Size of raw receive buffer in bytes */ -#define RCV_BUFBLKS 4 /* Number of blocks to divide buffer into - * (must divide RCV_BUFSIZE) */ - -static void Bchan_fill_fifo(struct BCState *, struct sk_buff *); - -static void -Bchan_xmt_bh(void *data) -{ - struct BCState *bcs = data; - struct sk_buff *skb; - - if (bcs->hw.amd7930.tx_skb != NULL) { - dev_kfree_skb(bcs->hw.amd7930.tx_skb); - bcs->hw.amd7930.tx_skb = NULL; - } - xmit_ready_b(bcs); -} - -static void -Bchan_xmit_callback(struct BCState *bcs) -{ - schedule_work(&bcs->hw.amd7930.xmt_work); -} - -/* B channel transmission: two modes (three, if you count L1_MODE_NULL) - * - * L1_MODE_HDLC - We need to do HDLC encapsulation before transmiting - * the packet (i.e. make_raw_hdlc_data). Since this can be a - * time-consuming operation, our completion callback just schedules - * a bottom half to do encapsulation for the next packet. In between, - * the link will just idle - * - * L1_MODE_TRANS - Data goes through, well, transparent. No HDLC encap, - * and we can't just let the link idle, so the "bottom half" actually - * gets called during the top half (it's our callback routine in this case), - * but it's a lot faster now since we don't call make_raw_hdlc_data - */ - -static void -Bchan_fill_fifo(struct BCState *bcs, struct sk_buff *skb) -{ - struct IsdnCardState *cs = bcs->cs; - int len; - - if ((cs->debug & L1_DEB_HSCX) || (cs->debug & L1_DEB_HSCX_FIFO)) { - char tmp[1024]; - char *t = tmp; - - t += sprintf(t, "amd7930_fill_fifo %c cnt %d", - bcs->channel ? 'B' : 'A', skb->len); - if (cs->debug & L1_DEB_HSCX_FIFO) - QuickHex(t, skb->data, skb->len); - debugl1(cs, tmp); - } - - if (bcs->mode == L1_MODE_HDLC) { - len = make_raw_hdlc_data(skb->data, skb->len, - bcs->hw.amd7930.tx_buff, RAW_BUFMAX); - if (len > 0) - amd7930_bxmit(0, bcs->channel, - bcs->hw.amd7930.tx_buff, len, - (void *) &Bchan_xmit_callback, - (void *) bcs); - dev_kfree_skb(skb); - } else if (bcs->mode == L1_MODE_TRANS) { - amd7930_bxmit(0, bcs->channel, - bcs->hw.amd7930.tx_buff, skb->len, - (void *) &Bchan_xmt_bh, - (void *) bcs); - bcs->hw.amd7930.tx_skb = skb; - } else { - dev_kfree_skb(skb); - } -} - -static void -Bchan_mode(struct BCState *bcs, int mode, int bc) -{ - struct IsdnCardState *cs = bcs->cs; - - if (cs->debug & L1_DEB_HSCX) { - char tmp[40]; - sprintf(tmp, "AMD 7930 mode %d bchan %d/%d", - mode, bc, bcs->channel); - debugl1(cs, tmp); - } - bcs->mode = mode; -} - -/* Bchan_l2l1 is the entry point for upper layer routines that want to - * transmit on the B channel. PH_DATA_REQ is a normal packet that - * we either start transmitting (if idle) or queue (if busy). - * PH_PULL_REQ can be called to request a callback message (PH_PULL_CNF) - * once the link is idle. After a "pull" callback, the upper layer - * routines can use PH_PULL_IND to send data. - */ - -static void -Bchan_l2l1(struct PStack *st, int pr, void *arg) -{ - struct sk_buff *skb = arg; - - switch (pr) { - case (PH_DATA_REQ): - if (test_bit(BC_FLG_BUSY, &st->l1.bcs->Flag)) { - skb_queue_tail(&st->l1.bcs->squeue, skb); - } else { - test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag); - Bchan_fill_fifo(st->l1.bcs, skb); - } - break; - case (PH_PULL_IND): - if (test_bit(BC_FLG_BUSY, &st->l1.bcs->Flag)) { - printk(KERN_WARNING "amd7930: this shouldn't happen\n"); - break; - } - test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag); - Bchan_fill_fifo(st->l1.bcs, skb); - break; - case (PH_PULL_REQ): - if (!test_bit(BC_FLG_BUSY, &st->l1.bcs->Flag)) { - clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - st->l1.l1l2(st, PH_PULL_CNF, NULL); - } else - set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - } -} - -/* Receiver callback and bottom half - decodes HDLC at leisure (if - * L1_MODE_HDLC) and passes newly received skb on via bcs->rqueue. If - * a large packet is received, stick rv_skb (the buffer that the - * packet has been decoded into) on the receive queue and alloc a new - * (large) skb to act as buffer for future receives. If a small - * packet is received, leave rv_skb alone, alloc a new skb of the - * correct size, and copy the packet into it - */ - -static void -Bchan_recv_callback(struct BCState *bcs) -{ - struct amd7930_hw *hw = &bcs->hw.amd7930; - - hw->rv_buff_in += RCV_BUFSIZE/RCV_BUFBLKS; - hw->rv_buff_in %= RCV_BUFSIZE; - - if (hw->rv_buff_in != hw->rv_buff_out) { - amd7930_brecv(0, bcs->channel, - hw->rv_buff + hw->rv_buff_in, - RCV_BUFSIZE/RCV_BUFBLKS, - (void *) &Bchan_recv_callback, (void *) bcs); - } - - schedule_work(&hw->rcv_work); -} - -static void -Bchan_rcv_bh(void *data) -{ - struct BCState *bcs = data; - struct IsdnCardState *cs = bcs->cs; - struct amd7930_hw *hw = &bcs->hw.amd7930; - struct sk_buff *skb; - int len; - - if (cs->debug & L1_DEB_HSCX) { - char tmp[1024]; - - sprintf(tmp, "amd7930_Bchan_rcv (%d/%d)", - hw->rv_buff_in, hw->rv_buff_out); - debugl1(cs, tmp); - QuickHex(tmp, hw->rv_buff + hw->rv_buff_out, - RCV_BUFSIZE/RCV_BUFBLKS); - debugl1(cs, tmp); - } - - do { - if (bcs->mode == L1_MODE_HDLC) { - while ((len = read_raw_hdlc_data(hw->hdlc_state, - hw->rv_buff + hw->rv_buff_out, RCV_BUFSIZE/RCV_BUFBLKS, - hw->rv_skb->tail, HSCX_BUFMAX))) { - if (len > 0 && (cs->debug & L1_DEB_HSCX_FIFO)) { - char tmp[1024]; - char *t = tmp; - - t += sprintf(t, "amd7930_Bchan_rcv %c cnt %d", bcs->channel ? 'B' : 'A', len); - QuickHex(t, hw->rv_skb->tail, len); - debugl1(cs, tmp); - } - - if (len > HSCX_BUFMAX/2) { - /* Large packet received */ - - if (!(skb = dev_alloc_skb(HSCX_BUFMAX))) { - printk(KERN_WARNING "amd7930: receive out of memory"); - } else { - skb_put(hw->rv_skb, len); - skb_queue_tail(&bcs->rqueue, hw->rv_skb); - hw->rv_skb = skb; - bcs->event |= 1 << B_RCVBUFREADY; - schedule_work(&bcs->work); - } - } else if (len > 0) { - /* Small packet received */ - - if (!(skb = dev_alloc_skb(len))) { - printk(KERN_WARNING "amd7930: receive out of memory\n"); - } else { - memcpy(skb_put(skb, len), hw->rv_skb->tail, len); - skb_queue_tail(&bcs->rqueue, skb); - bcs->event |= 1 << B_RCVBUFREADY; - schedule_work(&bcs->work); - } - } else { - /* Reception Error */ - /* printk("amd7930: B channel receive error\n"); */ - } - } - } else if (bcs->mode == L1_MODE_TRANS) { - if (!(skb = dev_alloc_skb(RCV_BUFSIZE/RCV_BUFBLKS))) { - printk(KERN_WARNING "amd7930: receive out of memory\n"); - } else { - memcpy(skb_put(skb, RCV_BUFSIZE/RCV_BUFBLKS), - hw->rv_buff + hw->rv_buff_out, - RCV_BUFSIZE/RCV_BUFBLKS); - skb_queue_tail(&bcs->rqueue, skb); - bcs->event |= 1 << B_RCVBUFREADY; - schedule_work(&bcs->work); - } - } - - if (hw->rv_buff_in == hw->rv_buff_out) { - /* Buffer was filled up - need to restart receiver */ - amd7930_brecv(0, bcs->channel, - hw->rv_buff + hw->rv_buff_in, - RCV_BUFSIZE/RCV_BUFBLKS, - (void *) &Bchan_recv_callback, - (void *) bcs); - } - - hw->rv_buff_out += RCV_BUFSIZE/RCV_BUFBLKS; - hw->rv_buff_out %= RCV_BUFSIZE; - - } while (hw->rv_buff_in != hw->rv_buff_out); -} - -static void -Bchan_close(struct BCState *bcs) -{ - struct sk_buff *skb; - - Bchan_mode(bcs, 0, 0); - amd7930_bclose(0, bcs->channel); - - if (test_bit(BC_FLG_INIT, &bcs->Flag)) { - skb_queue_purge(&bcs->rqueue); - skb_queue_purge(&bcs->squeue); - } - test_and_clear_bit(BC_FLG_INIT, &bcs->Flag); -} - -static int -Bchan_open(struct BCState *bcs) -{ - struct amd7930_hw *hw = &bcs->hw.amd7930; - - if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { - skb_queue_head_init(&bcs->rqueue); - skb_queue_head_init(&bcs->squeue); - } - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - - amd7930_bopen(0, bcs->channel, 0xff); - hw->rv_buff_in = 0; - hw->rv_buff_out = 0; - hw->tx_skb = NULL; - init_hdlc_state(hw->hdlc_state, 0); - amd7930_brecv(0, bcs->channel, - hw->rv_buff + hw->rv_buff_in, RCV_BUFSIZE/RCV_BUFBLKS, - (void *) &Bchan_recv_callback, (void *) bcs); - - bcs->event = 0; - bcs->tx_cnt = 0; - return (0); -} - -static void -Bchan_init(struct BCState *bcs) -{ - if (!(bcs->hw.amd7930.tx_buff = kmalloc(RAW_BUFMAX, GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for amd7930.tx_buff\n"); - return; - } - if (!(bcs->hw.amd7930.rv_buff = kmalloc(RCV_BUFSIZE, GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for amd7930.rv_buff\n"); - return; - } - if (!(bcs->hw.amd7930.rv_skb = dev_alloc_skb(HSCX_BUFMAX))) { - printk(KERN_WARNING - "HiSax: No memory for amd7930.rv_skb\n"); - return; - } - if (!(bcs->hw.amd7930.hdlc_state = kmalloc(sizeof(struct hdlc_state), - GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for amd7930.hdlc_state\n"); - return; - } - - INIT_WORK(&bcs->hw.amd7930.rcv_work, &Bchan_rcv_bh, bcs); - INIT_WORK(&bcs->hw.amd7930.xmt_work, &Bchan_xmt_bh, bcs); -} - -static void -Bchan_manl1(struct PStack *st, int pr, - void *arg) -{ - switch (pr) { - case (PH_ACTIVATE_REQ): - test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag); - Bchan_mode(st->l1.bcs, st->l1.mode, st->l1.bc); - st->l1.l1man(st, PH_ACTIVATE_CNF, NULL); - break; - case (PH_DEACTIVATE_REQ): - if (!test_bit(BC_FLG_BUSY, &st->l1.bcs->Flag)) - Bchan_mode(st->l1.bcs, 0, 0); - test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag); - break; - } -} - -int -setstack_amd7930(struct PStack *st, struct BCState *bcs) -{ - if (Bchan_open(bcs)) - return (-1); - st->l1.bcs = bcs; - st->l2.l2l1 = Bchan_l2l1; - st->ma.manl1 = Bchan_manl1; - setstack_manager(st); - bcs->st = st; - return (0); -} - - -static void -amd7930_drecv_callback(void *arg, int error, unsigned int count) -{ - struct IsdnCardState *cs = (struct IsdnCardState *) arg; - static struct work_struct task; - struct sk_buff *skb; - - /* NOTE: This function is called directly from an interrupt handler */ - - if (1) { - if (!(skb = alloc_skb(count, GFP_ATOMIC))) - printk(KERN_WARNING "HiSax: D receive out of memory\n"); - else { - memcpy(skb_put(skb, count), cs->rcvbuf, count); - skb_queue_tail(&cs->rq, skb); - } - - INIT_WORK(&task, (void *) DChannel_proc_rcv, (void *) cs); - schedule_work(&task); - } - - if (cs->debug & L1_DEB_ISAC_FIFO) { - char tmp[128]; - char *t = tmp; - - t += sprintf(t, "amd7930 Drecv cnt %d", count); - if (error) t += sprintf(t, " ERR %x", error); - QuickHex(t, cs->rcvbuf, count); - debugl1(cs, tmp); - } - - amd7930_drecv(0, cs->rcvbuf, MAX_DFRAME_LEN, - &amd7930_drecv_callback, cs); -} - -static void -amd7930_dxmit_callback(void *arg, int error) -{ - struct IsdnCardState *cs = (struct IsdnCardState *) arg; - static struct work_struct task; - - /* NOTE: This function is called directly from an interrupt handler */ - - /* may wish to do retransmission here, if error indicates collision */ - - if (cs->debug & L1_DEB_ISAC_FIFO) { - char tmp[128]; - char *t = tmp; - - t += sprintf(t, "amd7930 Dxmit cnt %d", cs->tx_skb->len); - if (error) t += sprintf(t, " ERR %x", error); - QuickHex(t, cs->tx_skb->data, cs->tx_skb->len); - debugl1(cs, tmp); - } - - cs->tx_skb = NULL; - - INIT_WORK(&task, (void *) DChannel_proc_xmt, (void *) cs); - schedule_work(&task); -} - -static void -amd7930_Dchan_l2l1(struct PStack *st, int pr, void *arg) -{ - struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; - struct sk_buff *skb = arg; - char str[64]; - - switch (pr) { - case (PH_DATA_REQ): - if (cs->tx_skb) { - skb_queue_tail(&cs->sq, skb); -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA Queued", 0); -#endif - } else { - if ((cs->dlogflag) && (!(skb->data[2] & 1))) { - /* I-FRAME */ - LogFrame(cs, skb->data, skb->len); - sprintf(str, "Q.931 frame user->network tei %d", st->l2.tei); - dlogframe(cs, skb->data+4, skb->len-4, - str); - } - cs->tx_skb = skb; - cs->tx_cnt = 0; -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA", 0); -#endif - amd7930_dxmit(0, skb->data, skb->len, - &amd7930_dxmit_callback, cs); - } - break; - case (PH_PULL_IND): - if (cs->tx_skb) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, " l2l1 tx_skb exist this shouldn't happen"); - skb_queue_tail(&cs->sq, skb); - break; - } - if ((cs->dlogflag) && (!(skb->data[2] & 1))) { /* I-FRAME */ - LogFrame(cs, skb->data, skb->len); - sprintf(str, "Q.931 frame user->network tei %d", st->l2.tei); - dlogframe(cs, skb->data + 4, skb->len - 4, - str); - } - cs->tx_skb = skb; - cs->tx_cnt = 0; -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - Logl2Frame(cs, skb, "PH_DATA_PULLED", 0); -#endif - amd7930_dxmit(0, cs->tx_skb->data, cs->tx_skb->len, - &amd7930_dxmit_callback, cs); - break; - case (PH_PULL_REQ): -#ifdef L2FRAME_DEBUG /* psa */ - if (cs->debug & L1_DEB_LAPD) - debugl1(cs, "-> PH_REQUEST_PULL"); -#endif - if (!cs->tx_skb) { - test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - st->l1.l1l2(st, PH_PULL_CNF, NULL); - } else - test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); - break; - } -} - -int -setDstack_amd7930(struct PStack *st, struct IsdnCardState *cs) -{ - st->l2.l2l1 = amd7930_Dchan_l2l1; - if (! cs->rcvbuf) { - printk("setDstack_amd7930: No cs->rcvbuf!\n"); - } else { - amd7930_drecv(0, cs->rcvbuf, MAX_DFRAME_LEN, - &amd7930_drecv_callback, cs); - } - return (0); -} - -static void -manl1_msg(struct IsdnCardState *cs, int msg, void *arg) { - struct PStack *st; - - st = cs->stlist; - while (st) { - st->ma.manl1(st, msg, arg); - st = st->next; - } -} - -static void -amd7930_new_ph(struct IsdnCardState *cs) -{ - switch (amd7930_get_liu_state(0)) { - case 3: - manl1_msg(cs, PH_POWERUP_CNF, NULL); - break; - - case 7: - manl1_msg(cs, PH_I4_P8_IND, NULL); - break; - - case 8: - manl1_msg(cs, PH_RSYNC_IND, NULL); - break; - } -} - -/* amd7930 LIU state change callback */ - -static void -amd7930_liu_callback(struct IsdnCardState *cs) -{ - static struct work_struct task; - - if (!cs) - return; - - if (cs->debug & L1_DEB_ISAC) { - char tmp[32]; - sprintf(tmp, "amd7930_liu state %d", amd7930_get_liu_state(0)); - debugl1(cs, tmp); - } - - INIT_WORK(&task, (void *) &amd7930_new_ph, (void *) cs); - schedule_work(&task); -} - -void -amd7930_l1cmd(struct IsdnCardState *cs, int msg, void *arg) -{ - u8 val; - char tmp[32]; - - if (cs->debug & L1_DEB_ISAC) { - char tmp[32]; - sprintf(tmp, "amd7930_l1cmd msg %x", msg); - debugl1(cs, tmp); - } - - switch(msg) { - case PH_RESET_REQ: - if (amd7930_get_liu_state(0) <= 3) - amd7930_liu_activate(0,0); - else - amd7930_liu_deactivate(0); - break; - case PH_ENABLE_REQ: - break; - case PH_INFO3_REQ: - amd7930_liu_activate(0,0); - break; - case PH_TESTLOOP_REQ: - break; - default: - if (cs->debug & L1_DEB_WARN) { - sprintf(tmp, "amd7930_l1cmd unknown %4x", msg); - debugl1(cs, tmp); - } - break; - } -} - -static void init_amd7930(struct IsdnCardState *cs) -{ - Bchan_init(&cs->bcs[0]); - Bchan_init(&cs->bcs[1]); - cs->bcs[0].BC_SetStack = setstack_amd7930; - cs->bcs[1].BC_SetStack = setstack_amd7930; - cs->bcs[0].BC_Close = Bchan_close; - cs->bcs[1].BC_Close = Bchan_close; - Bchan_mode(cs->bcs, 0, 0); - Bchan_mode(cs->bcs + 1, 0, 0); -} - -static int -amd7930_init(struct IsdnCardState *cs) -{ - cs->l1cmd = amd7930_l1cmd; - amd7930_liu_init(0, &amd7930_liu_callback, (void *)cs); - init_amd7930(cs); - return 0; -} - -static struct card_ops amd7930_ops = { - .init = amd7930_init, -}; - -int __init -setup_amd7930(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, amd7930_revision); - printk(KERN_INFO "HiSax: AMD7930 driver Rev. %s\n", HiSax_getrev(tmp)); - - cs->irq = amd7930_get_irqnum(0); - if (cs->irq == 0) - return 0; - - cs->card_ops = &amd7930_ops; - return 1; -} -- 2.53.0