summaryrefslogtreecommitdiff
path: root/drivers/isdn/hardware/mISDN/mISDNipac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/hardware/mISDN/mISDNipac.c')
-rw-r--r--drivers/isdn/hardware/mISDN/mISDNipac.c95
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;
}