diff options
Diffstat (limited to 'drivers/isdn/hardware/mISDN/mISDNipac.c')
| -rw-r--r-- | drivers/isdn/hardware/mISDN/mISDNipac.c | 95 |
1 files changed, 42 insertions, 53 deletions
diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c index ccd7d851be26..a34ea6058960 100644 --- a/drivers/isdn/hardware/mISDN/mISDNipac.c +++ b/drivers/isdn/hardware/mISDN/mISDNipac.c @@ -1,23 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * isac.c ISAC specific routines * * Author Karsten Keil <keil@isdn4linux.de> * * Copyright 2009 by Karsten Keil <keil@isdn4linux.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * */ #include <linux/irqreturn.h> @@ -34,6 +21,7 @@ MODULE_AUTHOR("Karsten Keil"); MODULE_VERSION(ISAC_REV); +MODULE_DESCRIPTION("mISDN driver for ISAC specific functions"); MODULE_LICENSE("GPL v2"); #define ReadISAC(is, o) (is->read_reg(is->dch.hw, o + is->off)) @@ -80,6 +68,7 @@ isac_ph_state_bh(struct dchannel *dch) l1_event(dch->l1, HW_DEACT_CNF); break; case ISAC_IND_DR: + case ISAC_IND_DR6: dch->state = 3; l1_event(dch->l1, HW_DEACT_IND); break; @@ -112,7 +101,7 @@ isac_ph_state_bh(struct dchannel *dch) pr_debug("%s: TE newstate %x\n", isac->name, dch->state); } -void +static void isac_empty_fifo(struct isac_hw *isac, int count) { u8 *ptr; @@ -169,9 +158,8 @@ isac_fill_fifo(struct isac_hw *isac) WriteISAC(isac, ISAC_CMDR, more ? 0x8 : 0xa); if (test_and_set_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) { pr_debug("%s: %s dbusytimer running\n", isac->name, __func__); - del_timer(&isac->dch.timer); + timer_delete(&isac->dch.timer); } - init_timer(&isac->dch.timer); isac->dch.timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000); add_timer(&isac->dch.timer); if (isac->dch.debug & DEBUG_HW_DFIFO) { @@ -203,8 +191,7 @@ isac_rme_irq(struct isac_hw *isac) #endif } WriteISAC(isac, ISAC_CMDR, 0x80); - if (isac->dch.rx_skb) - dev_kfree_skb(isac->dch.rx_skb); + dev_kfree_skb(isac->dch.rx_skb); isac->dch.rx_skb = NULL; } else { count = ReadISAC(isac, ISAC_RBCL) & 0x1f; @@ -219,12 +206,11 @@ static void isac_xpr_irq(struct isac_hw *isac) { if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) - del_timer(&isac->dch.timer); + timer_delete(&isac->dch.timer); if (isac->dch.tx_skb && isac->dch.tx_idx < isac->dch.tx_skb->len) { isac_fill_fifo(isac); } else { - if (isac->dch.tx_skb) - dev_kfree_skb(isac->dch.tx_skb); + dev_kfree_skb(isac->dch.tx_skb); if (get_next_dframe(&isac->dch)) isac_fill_fifo(isac); } @@ -234,7 +220,7 @@ static void isac_retransmit(struct isac_hw *isac) { if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) - del_timer(&isac->dch.timer); + timer_delete(&isac->dch.timer); if (test_bit(FLG_TX_BUSY, &isac->dch.Flags)) { /* Restart frame */ isac->dch.tx_idx = 0; @@ -363,8 +349,8 @@ afterMONR1: WriteISAC(isac, ISAC_MOCR, isac->mocr); if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) { if (isac->monitor) - ret = isac->monitor(isac->dch.hw, - MONITOR_TX_0, NULL, 0); + isac->monitor(isac->dch.hw, + MONITOR_TX_0, NULL, 0); } kfree(isac->mon_tx); isac->mon_tx = NULL; @@ -374,8 +360,8 @@ afterMONR1: } if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) { if (isac->monitor) - ret = isac->monitor(isac->dch.hw, - MONITOR_TX_0, NULL, 0); + isac->monitor(isac->dch.hw, + MONITOR_TX_0, NULL, 0); kfree(isac->mon_tx); isac->mon_tx = NULL; isac->mon_txc = 0; @@ -396,8 +382,8 @@ AfterMOX0: WriteISAC(isac, ISAC_MOCR, isac->mocr); if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) { if (isac->monitor) - ret = isac->monitor(isac->dch.hw, - MONITOR_TX_1, NULL, 0); + isac->monitor(isac->dch.hw, + MONITOR_TX_1, NULL, 0); } kfree(isac->mon_tx); isac->mon_tx = NULL; @@ -407,8 +393,8 @@ AfterMOX0: } if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) { if (isac->monitor) - ret = isac->monitor(isac->dch.hw, - MONITOR_TX_1, NULL, 0); + isac->monitor(isac->dch.hw, + MONITOR_TX_1, NULL, 0); kfree(isac->mon_tx); isac->mon_tx = NULL; isac->mon_txc = 0; @@ -477,8 +463,7 @@ isacsx_rme_irq(struct isac_hw *isac) isac->dch.err_crc++; #endif WriteISAC(isac, ISACX_CMDRD, ISACX_CMDRD_RMC); - if (isac->dch.rx_skb) - dev_kfree_skb(isac->dch.rx_skb); + dev_kfree_skb(isac->dch.rx_skb); isac->dch.rx_skb = NULL; } else { count = ReadISAC(isac, ISACX_RBCLD) & 0x1f; @@ -660,6 +645,7 @@ isac_l1cmd(struct dchannel *dch, u32 cmd) spin_lock_irqsave(isac->hwlock, flags); if ((isac->state == ISAC_IND_EI) || (isac->state == ISAC_IND_DR) || + (isac->state == ISAC_IND_DR6) || (isac->state == ISAC_IND_RS)) ph_command(isac, ISAC_CMD_TIM); else @@ -679,7 +665,7 @@ isac_l1cmd(struct dchannel *dch, u32 cmd) } test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags)) - del_timer(&dch->timer); + timer_delete(&dch->timer); break; case HW_POWERUP_REQ: spin_lock_irqsave(isac->hwlock, flags); @@ -709,10 +695,10 @@ isac_release(struct isac_hw *isac) { if (isac->type & IPAC_TYPE_ISACX) WriteISAC(isac, ISACX_MASK, 0xff); - else + else if (isac->type != 0) WriteISAC(isac, ISAC_MASK, 0xff); if (isac->dch.timer.function != NULL) { - del_timer(&isac->dch.timer); + timer_delete(&isac->dch.timer); isac->dch.timer.function = NULL; } kfree(isac->mon_rx); @@ -725,8 +711,9 @@ isac_release(struct isac_hw *isac) } static void -dbusy_timer_handler(struct isac_hw *isac) +dbusy_timer_handler(struct timer_list *t) { + struct isac_hw *isac = timer_container_of(isac, t, dch.timer); int rbch, star; u_long flags; @@ -754,10 +741,10 @@ dbusy_timer_handler(struct isac_hw *isac) } static int -open_dchannel(struct isac_hw *isac, struct channel_req *rq) +open_dchannel_caller(struct isac_hw *isac, struct channel_req *rq, void *caller) { pr_debug("%s: %s dev(%d) open from %p\n", isac->name, __func__, - isac->dch.dev.id, __builtin_return_address(1)); + isac->dch.dev.id, caller); if (rq->protocol != ISDN_P_TE_S0) return -EINVAL; if (rq->adr.channel == 1) @@ -771,6 +758,12 @@ open_dchannel(struct isac_hw *isac, struct channel_req *rq) return 0; } +static int +open_dchannel(struct isac_hw *isac, struct channel_req *rq) +{ + return open_dchannel_caller(isac, rq, __builtin_return_address(0)); +} + static const char *ISACVer[] = {"2086/2186 V1.1", "2085 B1", "2085 B2", "2085 V2.3"}; @@ -788,9 +781,7 @@ isac_init(struct isac_hw *isac) } isac->mon_tx = NULL; isac->mon_rx = NULL; - isac->dch.timer.function = (void *) dbusy_timer_handler; - isac->dch.timer.data = (long)isac; - init_timer(&isac->dch.timer); + timer_setup(&isac->dch.timer, dbusy_timer_handler, 0); isac->mocr = 0xaa; if (isac->type & IPAC_TYPE_ISACX) { /* Disable all IRQ */ @@ -946,8 +937,8 @@ hscx_empty_fifo(struct hscx_hw *hscx, u8 count) hscx_cmdr(hscx, 0x80); /* RMC */ if (hscx->bch.rx_skb) skb_trim(hscx->bch.rx_skb, 0); - pr_warning("%s.B%d: No bufferspace for %d bytes\n", - hscx->ip->name, hscx->bch.nr, count); + pr_warn("%s.B%d: No bufferspace for %d bytes\n", + hscx->ip->name, hscx->bch.nr, count); return; } p = skb_put(hscx->bch.rx_skb, count); @@ -1019,8 +1010,7 @@ hscx_xpr(struct hscx_hw *hx) if (hx->bch.tx_skb && hx->bch.tx_idx < hx->bch.tx_skb->len) { hscx_fill_fifo(hx); } else { - if (hx->bch.tx_skb) - dev_kfree_skb(hx->bch.tx_skb); + dev_kfree_skb(hx->bch.tx_skb); if (get_next_bframe(&hx->bch)) { hscx_fill_fifo(hx); test_and_clear_bit(FLG_TX_EMPTY, &hx->bch.Flags); @@ -1073,7 +1063,7 @@ ipac_rme(struct hscx_hw *hx) if (!hx->bch.rx_skb) return; if (hx->bch.rx_skb->len < 2) { - pr_debug("%s: B%1d frame to short %d\n", + pr_debug("%s: B%1d frame too short %d\n", hx->ip->name, hx->bch.nr, hx->bch.rx_skb->len); skb_trim(hx->bch.rx_skb, 0); } else { @@ -1164,7 +1154,7 @@ mISDNipac_irq(struct ipac_hw *ipac, int maxloop) if (ipac->type & IPAC_TYPE_IPACX) { ista = ReadIPAC(ipac, ISACX_ISTA); - while (ista && cnt--) { + while (ista && --cnt) { pr_debug("%s: ISTA %02x\n", ipac->name, ista); if (ista & IPACX__ICA) ipac_irq(&ipac->hscx[0], ista); @@ -1176,7 +1166,7 @@ mISDNipac_irq(struct ipac_hw *ipac, int maxloop) } } else if (ipac->type & IPAC_TYPE_IPAC) { ista = ReadIPAC(ipac, IPAC_ISTA); - while (ista && cnt--) { + while (ista && --cnt) { pr_debug("%s: ISTA %02x\n", ipac->name, ista); if (ista & (IPAC__ICD | IPAC__EXD)) { istad = ReadISAC(isac, ISAC_ISTA); @@ -1194,7 +1184,7 @@ mISDNipac_irq(struct ipac_hw *ipac, int maxloop) ista = ReadIPAC(ipac, IPAC_ISTA); } } else if (ipac->type & IPAC_TYPE_HSCX) { - while (cnt) { + while (--cnt) { ista = ReadIPAC(ipac, IPAC_ISTAB + ipac->hscx[1].off); pr_debug("%s: B2 ISTA %02x\n", ipac->name, ista); if (ista) @@ -1205,7 +1195,6 @@ mISDNipac_irq(struct ipac_hw *ipac, int maxloop) mISDNisac_irq(isac, istad); if (0 == (ista | istad)) break; - cnt--; } } if (cnt > maxloop) /* only for ISAC/HSCX without PCI IRQ test */ @@ -1548,7 +1537,7 @@ ipac_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg) case OPEN_CHANNEL: rq = arg; if (rq->protocol == ISDN_P_TE_S0) - err = open_dchannel(isac, rq); + err = open_dchannel_caller(isac, rq, __builtin_return_address(0)); else err = open_bchannel(ipac, rq); if (err) @@ -1618,7 +1607,7 @@ mISDNipac_init(struct ipac_hw *ipac, void *hw) ipac->hscx[i].bch.hw = hw; ipac->hscx[i].ip = ipac; /* default values for IOM time slots - * can be overwriten by card */ + * can be overwritten by card */ ipac->hscx[i].slot = (i == 0) ? 0x2f : 0x03; } |
