aboutsummaryrefslogtreecommitdiff
path: root/drivers/isdn/hardware/mISDN/hfcmulti.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/hardware/mISDN/hfcmulti.c')
-rw-r--r--drivers/isdn/hardware/mISDN/hfcmulti.c2488
1 files changed, 1376 insertions, 1112 deletions
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index 0b28141e43b..28543d79518 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -103,22 +103,34 @@
* Omit this value, if all cards are interconnected or none is connected.
* If unsure, don't give this parameter.
*
- * dslot:
- * NOTE: only one poll value must be given for every card.
- * Also this value must be given for non-E1 cards. If omitted, the E1
- * card has D-channel on time slot 16, which is default.
- * If 1..15 or 17..31, an alternate time slot is used for D-channel.
- * In this case, the application must be able to handle this.
- * If -1 is given, the D-channel is disabled and all 31 slots can be used
- * for B-channel. (only for specific applications)
+ * dmask and bmask:
+ * NOTE: One dmask value must be given for every HFC-E1 card.
+ * If omitted, the E1 card has D-channel on time slot 16, which is default.
+ * dmask is a 32 bit mask. The bit must be set for an alternate time slot.
+ * If multiple bits are set, multiple virtual card fragments are created.
+ * For each bit set, a bmask value must be given. Each bit on the bmask
+ * value stands for a B-channel. The bmask may not overlap with dmask or
+ * with other bmask values for that card.
+ * Example: dmask=0x00020002 bmask=0x0000fffc,0xfffc0000
+ * This will create one fragment with D-channel on slot 1 with
+ * B-channels on slots 2..15, and a second fragment with D-channel
+ * on slot 17 with B-channels on slot 18..31. Slot 16 is unused.
+ * If bit 0 is set (dmask=0x00000001) the D-channel is on slot 0 and will
+ * not function.
+ * Example: dmask=0x00000001 bmask=0xfffffffe
+ * This will create a port with all 31 usable timeslots as
+ * B-channels.
+ * If no bits are set on bmask, no B-channel is created for that fragment.
+ * Example: dmask=0xfffffffe bmask=0,0,0,0.... (31 0-values for bmask)
+ * This will create 31 ports with one D-channel only.
* If you don't know how to use it, you don't need it!
*
* iomode:
* NOTE: only one mode value must be given for every card.
* -> See hfc_multi.h for HFC_IO_MODE_* values
* By default, the IO mode is pci memory IO (MEMIO).
- * Some cards requre specific IO mode, so it cannot be changed.
- * It may be usefull to set IO mode to register io (REGIO) to solve
+ * Some cards require specific IO mode, so it cannot be changed.
+ * It may be useful to set IO mode to register io (REGIO) to solve
* PCI bridge problems.
* If unsure, don't give this parameter.
*
@@ -139,6 +151,10 @@
* Selects interface with clock source for mISDN and applications.
* Set to card number starting with 1. Set to -1 to disable.
* By default, the first card is used as clock source.
+ *
+ * hwid:
+ * NOTE: only one hwid value must be given once
+ * Enable special embedded devices with XHFC controllers.
*/
/*
@@ -148,15 +164,17 @@
#define HFC_MULTI_VERSION "2.03"
+#include <linux/interrupt.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/mISDNhw.h>
#include <linux/mISDNdsp.h>
/*
-#define IRQCOUNT_DEBUG
-#define IRQ_DEBUG
+ #define IRQCOUNT_DEBUG
+ #define IRQ_DEBUG
*/
#include "hfc_multi.h"
@@ -166,6 +184,7 @@
#define MAX_CARDS 8
#define MAX_PORTS (8 * MAX_CARDS)
+#define MAX_FRAGS (32 * MAX_CARDS)
static LIST_HEAD(HFClist);
static spinlock_t HFClock; /* global hfc list lock */
@@ -197,7 +216,8 @@ static int nt_t1_count[] = { 3840, 1920, 960, 480, 240, 120, 60, 30 };
static uint type[MAX_CARDS];
static int pcm[MAX_CARDS];
-static int dslot[MAX_CARDS];
+static uint dmask[MAX_CARDS];
+static uint bmask[MAX_FRAGS];
static uint iomode[MAX_CARDS];
static uint port[MAX_PORTS];
static uint debug;
@@ -206,8 +226,13 @@ static int clock;
static uint timer;
static uint clockdelay_te = CLKDEL_TE;
static uint clockdelay_nt = CLKDEL_NT;
+#define HWID_NONE 0
+#define HWID_MINIP4 1
+#define HWID_MINIP8 2
+#define HWID_MINIP16 3
+static uint hwid = HWID_NONE;
-static int HFC_cnt, Port_cnt, PCM_cnt = 99;
+static int HFC_cnt, E1_cnt, bmask_cnt, Port_cnt, PCM_cnt = 99;
MODULE_AUTHOR("Andreas Eversberg");
MODULE_LICENSE("GPL");
@@ -220,26 +245,28 @@ module_param(clockdelay_te, uint, S_IRUGO | S_IWUSR);
module_param(clockdelay_nt, uint, S_IRUGO | S_IWUSR);
module_param_array(type, uint, NULL, S_IRUGO | S_IWUSR);
module_param_array(pcm, int, NULL, S_IRUGO | S_IWUSR);
-module_param_array(dslot, int, NULL, S_IRUGO | S_IWUSR);
+module_param_array(dmask, uint, NULL, S_IRUGO | S_IWUSR);
+module_param_array(bmask, uint, NULL, S_IRUGO | S_IWUSR);
module_param_array(iomode, uint, NULL, S_IRUGO | S_IWUSR);
module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR);
+module_param(hwid, uint, S_IRUGO | S_IWUSR); /* The hardware ID */
#ifdef HFC_REGISTER_DEBUG
-#define HFC_outb(hc, reg, val) \
+#define HFC_outb(hc, reg, val) \
(hc->HFC_outb(hc, reg, val, __func__, __LINE__))
-#define HFC_outb_nodebug(hc, reg, val) \
+#define HFC_outb_nodebug(hc, reg, val) \
(hc->HFC_outb_nodebug(hc, reg, val, __func__, __LINE__))
-#define HFC_inb(hc, reg) \
+#define HFC_inb(hc, reg) \
(hc->HFC_inb(hc, reg, __func__, __LINE__))
-#define HFC_inb_nodebug(hc, reg) \
+#define HFC_inb_nodebug(hc, reg) \
(hc->HFC_inb_nodebug(hc, reg, __func__, __LINE__))
-#define HFC_inw(hc, reg) \
+#define HFC_inw(hc, reg) \
(hc->HFC_inw(hc, reg, __func__, __LINE__))
-#define HFC_inw_nodebug(hc, reg) \
+#define HFC_inw_nodebug(hc, reg) \
(hc->HFC_inw_nodebug(hc, reg, __func__, __LINE__))
-#define HFC_wait(hc) \
+#define HFC_wait(hc) \
(hc->HFC_wait(hc, __func__, __LINE__))
-#define HFC_wait_nodebug(hc) \
+#define HFC_wait_nodebug(hc) \
(hc->HFC_wait_nodebug(hc, __func__, __LINE__))
#else
#define HFC_outb(hc, reg, val) (hc->HFC_outb(hc, reg, val))
@@ -252,92 +279,98 @@ module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR);
#define HFC_wait_nodebug(hc) (hc->HFC_wait_nodebug(hc))
#endif
+#ifdef CONFIG_MISDN_HFCMULTI_8xx
+#include "hfc_multi_8xx.h"
+#endif
+
/* HFC_IO_MODE_PCIMEM */
static void
#ifdef HFC_REGISTER_DEBUG
HFC_outb_pcimem(struct hfc_multi *hc, u_char reg, u_char val,
const char *function, int line)
#else
-HFC_outb_pcimem(struct hfc_multi *hc, u_char reg, u_char val)
+ HFC_outb_pcimem(struct hfc_multi *hc, u_char reg, u_char val)
#endif
{
- writeb(val, (hc->pci_membase)+reg);
+ writeb(val, hc->pci_membase + reg);
}
static u_char
#ifdef HFC_REGISTER_DEBUG
HFC_inb_pcimem(struct hfc_multi *hc, u_char reg, const char *function, int line)
#else
-HFC_inb_pcimem(struct hfc_multi *hc, u_char reg)
+ HFC_inb_pcimem(struct hfc_multi *hc, u_char reg)
#endif
{
- return readb((hc->pci_membase)+reg);
+ return readb(hc->pci_membase + reg);
}
static u_short
#ifdef HFC_REGISTER_DEBUG
HFC_inw_pcimem(struct hfc_multi *hc, u_char reg, const char *function, int line)
#else
-HFC_inw_pcimem(struct hfc_multi *hc, u_char reg)
+ HFC_inw_pcimem(struct hfc_multi *hc, u_char reg)
#endif
{
- return readw((hc->pci_membase)+reg);
+ return readw(hc->pci_membase + reg);
}
static void
#ifdef HFC_REGISTER_DEBUG
HFC_wait_pcimem(struct hfc_multi *hc, const char *function, int line)
#else
-HFC_wait_pcimem(struct hfc_multi *hc)
+ HFC_wait_pcimem(struct hfc_multi *hc)
#endif
{
- while (readb((hc->pci_membase)+R_STATUS) & V_BUSY);
+ while (readb(hc->pci_membase + R_STATUS) & V_BUSY)
+ cpu_relax();
}
/* HFC_IO_MODE_REGIO */
static void
#ifdef HFC_REGISTER_DEBUG
HFC_outb_regio(struct hfc_multi *hc, u_char reg, u_char val,
- const char *function, int line)
+ const char *function, int line)
#else
-HFC_outb_regio(struct hfc_multi *hc, u_char reg, u_char val)
+ HFC_outb_regio(struct hfc_multi *hc, u_char reg, u_char val)
#endif
{
- outb(reg, (hc->pci_iobase)+4);
+ outb(reg, hc->pci_iobase + 4);
outb(val, hc->pci_iobase);
}
static u_char
#ifdef HFC_REGISTER_DEBUG
HFC_inb_regio(struct hfc_multi *hc, u_char reg, const char *function, int line)
#else
-HFC_inb_regio(struct hfc_multi *hc, u_char reg)
+ HFC_inb_regio(struct hfc_multi *hc, u_char reg)
#endif
{
- outb(reg, (hc->pci_iobase)+4);
+ outb(reg, hc->pci_iobase + 4);
return inb(hc->pci_iobase);
}
static u_short
#ifdef HFC_REGISTER_DEBUG
HFC_inw_regio(struct hfc_multi *hc, u_char reg, const char *function, int line)
#else
-HFC_inw_regio(struct hfc_multi *hc, u_char reg)
+ HFC_inw_regio(struct hfc_multi *hc, u_char reg)
#endif
{
- outb(reg, (hc->pci_iobase)+4);
+ outb(reg, hc->pci_iobase + 4);
return inw(hc->pci_iobase);
}
static void
#ifdef HFC_REGISTER_DEBUG
HFC_wait_regio(struct hfc_multi *hc, const char *function, int line)
#else
-HFC_wait_regio(struct hfc_multi *hc)
+ HFC_wait_regio(struct hfc_multi *hc)
#endif
{
- outb(R_STATUS, (hc->pci_iobase)+4);
- while (inb(hc->pci_iobase) & V_BUSY);
+ outb(R_STATUS, hc->pci_iobase + 4);
+ while (inb(hc->pci_iobase) & V_BUSY)
+ cpu_relax();
}
#ifdef HFC_REGISTER_DEBUG
static void
HFC_outb_debug(struct hfc_multi *hc, u_char reg, u_char val,
- const char *function, int line)
+ const char *function, int line)
{
char regname[256] = "", bits[9] = "xxxxxxxx";
int i;
@@ -350,17 +383,17 @@ HFC_outb_debug(struct hfc_multi *hc, u_char reg, u_char val,
if (regname[0] == '\0')
strcpy(regname, "register");
- bits[7] = '0'+(!!(val&1));
- bits[6] = '0'+(!!(val&2));
- bits[5] = '0'+(!!(val&4));
- bits[4] = '0'+(!!(val&8));
- bits[3] = '0'+(!!(val&16));
- bits[2] = '0'+(!!(val&32));
- bits[1] = '0'+(!!(val&64));
- bits[0] = '0'+(!!(val&128));
+ bits[7] = '0' + (!!(val & 1));
+ bits[6] = '0' + (!!(val & 2));
+ bits[5] = '0' + (!!(val & 4));
+ bits[4] = '0' + (!!(val & 8));
+ bits[3] = '0' + (!!(val & 16));
+ bits[2] = '0' + (!!(val & 32));
+ bits[1] = '0' + (!!(val & 64));
+ bits[0] = '0' + (!!(val & 128));
printk(KERN_DEBUG
- "HFC_outb(chip %d, %02x=%s, 0x%02x=%s); in %s() line %d\n",
- hc->id, reg, regname, val, bits, function, line);
+ "HFC_outb(chip %d, %02x=%s, 0x%02x=%s); in %s() line %d\n",
+ hc->id, reg, regname, val, bits, function, line);
HFC_outb_nodebug(hc, reg, val);
}
static u_char
@@ -380,17 +413,17 @@ HFC_inb_debug(struct hfc_multi *hc, u_char reg, const char *function, int line)
if (regname[0] == '\0')
strcpy(regname, "register");
- bits[7] = '0'+(!!(val&1));
- bits[6] = '0'+(!!(val&2));
- bits[5] = '0'+(!!(val&4));
- bits[4] = '0'+(!!(val&8));
- bits[3] = '0'+(!!(val&16));
- bits[2] = '0'+(!!(val&32));
- bits[1] = '0'+(!!(val&64));
- bits[0] = '0'+(!!(val&128));
+ bits[7] = '0' + (!!(val & 1));
+ bits[6] = '0' + (!!(val & 2));
+ bits[5] = '0' + (!!(val & 4));
+ bits[4] = '0' + (!!(val & 8));
+ bits[3] = '0' + (!!(val & 16));
+ bits[2] = '0' + (!!(val & 32));
+ bits[1] = '0' + (!!(val & 64));
+ bits[0] = '0' + (!!(val & 128));
printk(KERN_DEBUG
- "HFC_inb(chip %d, %02x=%s) = 0x%02x=%s; in %s() line %d\n",
- hc->id, reg, regname, val, bits, function, line);
+ "HFC_inb(chip %d, %02x=%s) = 0x%02x=%s; in %s() line %d\n",
+ hc->id, reg, regname, val, bits, function, line);
return val;
}
static u_short
@@ -411,15 +444,15 @@ HFC_inw_debug(struct hfc_multi *hc, u_char reg, const char *function, int line)
strcpy(regname, "register");
printk(KERN_DEBUG
- "HFC_inw(chip %d, %02x=%s) = 0x%04x; in %s() line %d\n",
- hc->id, reg, regname, val, function, line);
+ "HFC_inw(chip %d, %02x=%s) = 0x%04x; in %s() line %d\n",
+ hc->id, reg, regname, val, function, line);
return val;
}
static void
HFC_wait_debug(struct hfc_multi *hc, const char *function, int line)
{
printk(KERN_DEBUG "HFC_wait(chip %d); in %s() line %d\n",
- hc->id, function, line);
+ hc->id, function, line);
HFC_wait_nodebug(hc);
}
#endif
@@ -428,13 +461,13 @@ HFC_wait_debug(struct hfc_multi *hc, const char *function, int line)
static void
write_fifo_regio(struct hfc_multi *hc, u_char *data, int len)
{
- outb(A_FIFO_DATA0, (hc->pci_iobase)+4);
- while (len>>2) {
+ outb(A_FIFO_DATA0, (hc->pci_iobase) + 4);
+ while (len >> 2) {
outl(cpu_to_le32(*(u32 *)data), hc->pci_iobase);
data += 4;
len -= 4;
}
- while (len>>1) {
+ while (len >> 1) {
outw(cpu_to_le16(*(u16 *)data), hc->pci_iobase);
data += 2;
len -= 2;
@@ -449,15 +482,15 @@ write_fifo_regio(struct hfc_multi *hc, u_char *data, int len)
static void
write_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len)
{
- while (len>>2) {
+ while (len >> 2) {
writel(cpu_to_le32(*(u32 *)data),
- hc->pci_membase + A_FIFO_DATA0);
+ hc->pci_membase + A_FIFO_DATA0);
data += 4;
len -= 4;
}
- while (len>>1) {
+ while (len >> 1) {
writew(cpu_to_le16(*(u16 *)data),
- hc->pci_membase + A_FIFO_DATA0);
+ hc->pci_membase + A_FIFO_DATA0);
data += 2;
len -= 2;
}
@@ -467,17 +500,18 @@ write_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len)
len--;
}
}
+
/* read fifo data (REGIO) */
static void
read_fifo_regio(struct hfc_multi *hc, u_char *data, int len)
{
- outb(A_FIFO_DATA0, (hc->pci_iobase)+4);
- while (len>>2) {
+ outb(A_FIFO_DATA0, (hc->pci_iobase) + 4);
+ while (len >> 2) {
*(u32 *)data = le32_to_cpu(inl(hc->pci_iobase));
data += 4;
len -= 4;
}
- while (len>>1) {
+ while (len >> 1) {
*(u16 *)data = le16_to_cpu(inw(hc->pci_iobase));
data += 2;
len -= 2;
@@ -493,13 +527,13 @@ read_fifo_regio(struct hfc_multi *hc, u_char *data, int len)
static void
read_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len)
{
- while (len>>2) {
+ while (len >> 2) {
*(u32 *)data =
le32_to_cpu(readl(hc->pci_membase + A_FIFO_DATA0));
data += 4;
len -= 4;
}
- while (len>>1) {
+ while (len >> 1) {
*(u16 *)data =
le16_to_cpu(readw(hc->pci_membase + A_FIFO_DATA0));
data += 2;
@@ -512,7 +546,6 @@ read_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len)
}
}
-
static void
enable_hwirq(struct hfc_multi *hc)
{
@@ -589,7 +622,7 @@ writepcibridge(struct hfc_multi *hc, unsigned char address, unsigned char data)
outw(cipv, hc->pci_iobase + 4);
/* define a 32 bit dword with 4 identical bytes for write sequence */
datav = data | ((__u32) data << 8) | ((__u32) data << 16) |
- ((__u32) data << 24);
+ ((__u32) data << 24);
/*
* write this 32 bit dword to the bridge data port
@@ -681,7 +714,7 @@ vpm_in(struct hfc_multi *c, int which, unsigned short addr)
inline void
vpm_out(struct hfc_multi *c, int which, unsigned short addr,
- unsigned char data)
+ unsigned char data)
{
vpm_write_address(c, addr);
@@ -699,11 +732,11 @@ vpm_out(struct hfc_multi *c, int which, unsigned short addr,
disablepcibridge(c);
{
- unsigned char regin;
- regin = vpm_in(c, which, addr);
- if (regin != data)
- printk(KERN_DEBUG "Wrote 0x%x to register 0x%x but got back "
- "0x%x\n", data, addr, regin);
+ unsigned char regin;
+ regin = vpm_in(c, which, addr);
+ if (regin != data)
+ printk(KERN_DEBUG "Wrote 0x%x to register 0x%x but got back "
+ "0x%x\n", data, addr, regin);
}
}
@@ -835,16 +868,16 @@ vpm_echocan_on(struct hfc_multi *hc, int ch, int taps)
#ifdef TXADJ
skb = _alloc_mISDN_skb(PH_CONTROL_IND, HFC_VOL_CHANGE_TX,
- sizeof(int), &txadj, GFP_ATOMIC);
+ sizeof(int), &txadj, GFP_ATOMIC);
if (skb)
recv_Bchannel_skb(bch, skb);
#endif
- timeslot = ((ch/4)*8) + ((ch%4)*4) + 1;
+ timeslot = ((ch / 4) * 8) + ((ch % 4) * 4) + 1;
unit = ch % 4;
printk(KERN_NOTICE "vpm_echocan_on called taps [%d] on timeslot %d\n",
- taps, timeslot);
+ taps, timeslot);
vpm_out(hc, unit, timeslot, 0x7e);
}
@@ -868,16 +901,16 @@ vpm_echocan_off(struct hfc_multi *hc, int ch)
#ifdef TXADJ
skb = _alloc_mISDN_skb(PH_CONTROL_IND, HFC_VOL_CHANGE_TX,
- sizeof(int), &txadj, GFP_ATOMIC);
+ sizeof(int), &txadj, GFP_ATOMIC);
if (skb)
recv_Bchannel_skb(bch, skb);
#endif
- timeslot = ((ch/4)*8) + ((ch%4)*4) + 1;
+ timeslot = ((ch / 4) * 8) + ((ch % 4) * 4) + 1;
unit = ch % 4;
printk(KERN_NOTICE "vpm_echocan_off called on timeslot %d\n",
- timeslot);
+ timeslot);
/* FILLME */
vpm_out(hc, unit, timeslot, 0x01);
}
@@ -886,7 +919,7 @@ vpm_echocan_off(struct hfc_multi *hc, int ch)
/*
* Speech Design resync feature
* NOTE: This is called sometimes outside interrupt handler.
- * We must lock irqsave, so no other interrupt (other card) will occurr!
+ * We must lock irqsave, so no other interrupt (other card) will occur!
* Also multiple interrupts may nest, so must lock each access (lists, card)!
*/
static inline void
@@ -902,7 +935,7 @@ hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm)
if (debug & DEBUG_HFCMULTI_PLXSD)
printk(KERN_DEBUG "%s: RESYNC(syncmaster=0x%p)\n",
- __func__, syncmaster);
+ __func__, syncmaster);
/* select new master */
if (newmaster) {
@@ -928,10 +961,10 @@ hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm)
writel(pv, plx_acc_32);
if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) {
pcmmaster = hc;
- if (hc->type == 1) {
+ if (hc->ctype == HFC_TYPE_E1) {
if (debug & DEBUG_HFCMULTI_PLXSD)
printk(KERN_DEBUG
- "Schedule SYNC_I\n");
+ "Schedule SYNC_I\n");
hc->e1_resync |= 1; /* get SYNC_I */
}
}
@@ -942,14 +975,15 @@ hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm)
hc = newmaster;
if (debug & DEBUG_HFCMULTI_PLXSD)
printk(KERN_DEBUG "id=%d (0x%p) = syncronized with "
- "interface.\n", hc->id, hc);
+ "interface.\n", hc->id, hc);
/* Enable new sync master */
plx_acc_32 = hc->plx_membase + PLX_GPIOC;
pv = readl(plx_acc_32);
pv |= PLX_SYNC_O_EN;
writel(pv, plx_acc_32);
/* switch to jatt PLL, if not disabled by RX_SYNC */
- if (hc->type == 1 && !test_bit(HFC_CHIP_RX_SYNC, &hc->chip)) {
+ if (hc->ctype == HFC_TYPE_E1
+ && !test_bit(HFC_CHIP_RX_SYNC, &hc->chip)) {
if (debug & DEBUG_HFCMULTI_PLXSD)
printk(KERN_DEBUG "Schedule jatt PLL\n");
hc->e1_resync |= 2; /* switch to jatt */
@@ -959,20 +993,20 @@ hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm)
hc = pcmmaster;
if (debug & DEBUG_HFCMULTI_PLXSD)
printk(KERN_DEBUG
- "id=%d (0x%p) = PCM master syncronized "
- "with QUARTZ\n", hc->id, hc);
- if (hc->type == 1) {
+ "id=%d (0x%p) = PCM master syncronized "
+ "with QUARTZ\n", hc->id, hc);
+ if (hc->ctype == HFC_TYPE_E1) {
/* Use the crystal clock for the PCM
master card */
if (debug & DEBUG_HFCMULTI_PLXSD)
printk(KERN_DEBUG
- "Schedule QUARTZ for HFC-E1\n");
+ "Schedule QUARTZ for HFC-E1\n");
hc->e1_resync |= 4; /* switch quartz */
} else {
if (debug & DEBUG_HFCMULTI_PLXSD)
printk(KERN_DEBUG
- "QUARTZ is automatically "
- "enabled by HFC-%dS\n", hc->type);
+ "QUARTZ is automatically "
+ "enabled by HFC-%dS\n", hc->ctype);
}
plx_acc_32 = hc->plx_membase + PLX_GPIOC;
pv = readl(plx_acc_32);
@@ -981,7 +1015,7 @@ hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm)
} else
if (!rm)
printk(KERN_ERR "%s no pcm master, this MUST "
- "not happen!\n", __func__);
+ "not happen!\n", __func__);
}
syncmaster = newmaster;
@@ -996,17 +1030,17 @@ plxsd_checksync(struct hfc_multi *hc, int rm)
if (hc->syncronized) {
if (syncmaster == NULL) {
if (debug & DEBUG_HFCMULTI_PLXSD)
- printk(KERN_WARNING "%s: GOT sync on card %d"
- " (id=%d)\n", __func__, hc->id + 1,
- hc->id);
+ printk(KERN_DEBUG "%s: GOT sync on card %d"
+ " (id=%d)\n", __func__, hc->id + 1,
+ hc->id);
hfcmulti_resync(hc, hc, rm);
}
} else {
if (syncmaster == hc) {
if (debug & DEBUG_HFCMULTI_PLXSD)
- printk(KERN_WARNING "%s: LOST sync on card %d"
- " (id=%d)\n", __func__, hc->id + 1,
- hc->id);
+ printk(KERN_DEBUG "%s: LOST sync on card %d"
+ " (id=%d)\n", __func__, hc->id + 1,
+ hc->id);
hfcmulti_resync(hc, NULL, rm);
}
}
@@ -1038,7 +1072,7 @@ release_io_hfcmulti(struct hfc_multi *hc)
if (test_bit(HFC_CHIP_PLXSD, &hc->chip) && hc->plx_membase) {
if (debug & DEBUG_HFCMULTI_PLXSD)
printk(KERN_DEBUG "%s: release PLXSD card %d\n",
- __func__, hc->id + 1);
+ __func__, hc->id + 1);
spin_lock_irqsave(&plx_lock, plx_flags);
plx_acc_32 = hc->plx_membase + PLX_GPIOC;
writel(PLX_GPIOC_INIT, plx_acc_32);
@@ -1053,20 +1087,23 @@ release_io_hfcmulti(struct hfc_multi *hc)
pv &= ~PLX_DSP_RES_N;
writel(pv, plx_acc_32);
if (debug & DEBUG_HFCMULTI_INIT)
- printk(KERN_WARNING "%s: PCM off: PLX_GPIO=%x\n",
- __func__, pv);
+ printk(KERN_DEBUG "%s: PCM off: PLX_GPIO=%x\n",
+ __func__, pv);
spin_unlock_irqrestore(&plx_lock, plx_flags);
}
/* disable memory mapped ports / io ports */
test_and_clear_bit(HFC_CHIP_PLXSD, &hc->chip); /* prevent resync */
- pci_write_config_word(hc->pci_dev, PCI_COMMAND, 0);
+ if (hc->pci_dev)
+ pci_write_config_word(hc->pci_dev, PCI_COMMAND, 0);
if (hc->pci_membase)
iounmap(hc->pci_membase);
if (hc->plx_membase)
iounmap(hc->plx_membase);
if (hc->pci_iobase)
release_region(hc->pci_iobase, 8);
+ if (hc->xhfc_membase)
+ iounmap((void *)hc->xhfc_membase);
if (hc->pci_dev) {
pci_disable_device(hc->pci_dev);
@@ -1100,29 +1137,31 @@ init_chip(struct hfc_multi *hc)
/* revision check */
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: entered\n", __func__);
- val = HFC_inb(hc, R_CHIP_ID)>>4;
- if (val != 0x8 && val != 0xc && val != 0xe) {
+ val = HFC_inb(hc, R_CHIP_ID);
+ if ((val >> 4) != 0x8 && (val >> 4) != 0xc && (val >> 4) != 0xe &&
+ (val >> 1) != 0x31) {
printk(KERN_INFO "HFC_multi: unknown CHIP_ID:%x\n", (u_int)val);
err = -EIO;
goto out;
}
rev = HFC_inb(hc, R_CHIP_RV);
printk(KERN_INFO
- "HFC_multi: detected HFC with chip ID=0x%lx revision=%ld%s\n",
- val, rev, (rev == 0) ? " (old FIFO handling)" : "");
- if (rev == 0) {
+ "HFC_multi: detected HFC with chip ID=0x%lx revision=%ld%s\n",
+ val, rev, (rev == 0 && (hc->ctype != HFC_TYPE_XHFC)) ?
+ " (old FIFO handling)" : "");
+ if (hc->ctype != HFC_TYPE_XHFC && rev == 0) {
test_and_set_bit(HFC_CHIP_REVISION0, &hc->chip);
printk(KERN_WARNING
- "HFC_multi: NOTE: Your chip is revision 0, "
- "ask Cologne Chip for update. Newer chips "
- "have a better FIFO handling. Old chips "
- "still work but may have slightly lower "
- "HDLC transmit performance.\n");
+ "HFC_multi: NOTE: Your chip is revision 0, "
+ "ask Cologne Chip for update. Newer chips "
+ "have a better FIFO handling. Old chips "
+ "still work but may have slightly lower "
+ "HDLC transmit performance.\n");
}
if (rev > 1) {
printk(KERN_WARNING "HFC_multi: WARNING: This driver doesn't "
- "consider chip revision = %ld. The chip / "
- "bridge may not work.\n", rev);
+ "consider chip revision = %ld. The chip / "
+ "bridge may not work.\n", rev);
}
/* set s-ram size */
@@ -1132,8 +1171,8 @@ init_chip(struct hfc_multi *hc)
hc->DTMFbase = 0x1000;
if (test_bit(HFC_CHIP_EXRAM_128, &hc->chip)) {
if (debug & DEBUG_HFCMULTI_INIT)
- printk(KERN_DEBUG "%s: changing to 128K extenal RAM\n",
- __func__);
+ printk(KERN_DEBUG "%s: changing to 128K external RAM\n",
+ __func__);
hc->hw.r_ctrl |= V_EXT_RAM;
hc->hw.r_ram_sz = 1;
hc->Flen = 0x20;
@@ -1143,8 +1182,8 @@ init_chip(struct hfc_multi *hc)
}
if (test_bit(HFC_CHIP_EXRAM_512, &hc->chip)) {
if (debug & DEBUG_HFCMULTI_INIT)
- printk(KERN_DEBUG "%s: changing to 512K extenal RAM\n",
- __func__);
+ printk(KERN_DEBUG "%s: changing to 512K external RAM\n",
+ __func__);
hc->hw.r_ctrl |= V_EXT_RAM;
hc->hw.r_ram_sz = 2;
hc->Flen = 0x20;
@@ -1152,6 +1191,12 @@ init_chip(struct hfc_multi *hc)
hc->Zlen = 8000;
hc->DTMFbase = 0x2000;
}
+ if (hc->ctype == HFC_TYPE_XHFC) {
+ hc->Flen = 0x8;
+ hc->Zmin = 0x0;
+ hc->Zlen = 64;
+ hc->DTMFbase = 0x0;
+ }
hc->max_trans = poll << 1;
if (hc->max_trans > hc->Zlen)
hc->max_trans = hc->Zlen;
@@ -1160,7 +1205,7 @@ init_chip(struct hfc_multi *hc)
if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
if (debug & DEBUG_HFCMULTI_PLXSD)
printk(KERN_DEBUG "%s: initializing PLXSD card %d\n",
- __func__, hc->id + 1);
+ __func__, hc->id + 1);
spin_lock_irqsave(&plx_lock, plx_flags);
plx_acc_32 = hc->plx_membase + PLX_GPIOC;
writel(PLX_GPIOC_INIT, plx_acc_32);
@@ -1176,8 +1221,8 @@ init_chip(struct hfc_multi *hc)
writel(pv, plx_acc_32);
spin_unlock_irqrestore(&plx_lock, plx_flags);
if (debug & DEBUG_HFCMULTI_INIT)
- printk(KERN_WARNING "%s: slave/term: PLX_GPIO=%x\n",
- __func__, pv);
+ printk(KERN_DEBUG "%s: slave/term: PLX_GPIO=%x\n",
+ __func__, pv);
/*
* If we are the 3rd PLXSD card or higher, we must turn
* termination of last PLXSD card off.
@@ -1195,8 +1240,8 @@ init_chip(struct hfc_multi *hc)
if (plx_count >= 3) {
if (debug & DEBUG_HFCMULTI_PLXSD)
printk(KERN_DEBUG "%s: card %d is between, so "
- "we disable termination\n",
- __func__, plx_last_hc->id + 1);
+ "we disable termination\n",
+ __func__, plx_last_hc->id + 1);
spin_lock_irqsave(&plx_lock, plx_flags);
plx_acc_32 = plx_last_hc->plx_membase + PLX_GPIOC;
pv = readl(plx_acc_32);
@@ -1204,13 +1249,17 @@ init_chip(struct hfc_multi *hc)
writel(pv, plx_acc_32);
spin_unlock_irqrestore(&plx_lock, plx_flags);
if (debug & DEBUG_HFCMULTI_INIT)
- printk(KERN_WARNING "%s: term off: PLX_GPIO=%x\n",
- __func__, pv);
+ printk(KERN_DEBUG
+ "%s: term off: PLX_GPIO=%x\n",
+ __func__, pv);
}
spin_unlock_irqrestore(&HFClock, hfc_flags);
hc->hw.r_pcm_md0 = V_F0_LEN; /* shift clock for DSP */
}
+ if (test_bit(HFC_CHIP_EMBSD, &hc->chip))
+ hc->hw.r_pcm_md0 = V_F0_LEN; /* shift clock for DSP */
+
/* we only want the real Z2 read-pointer for revision > 0 */
if (!test_bit(HFC_CHIP_REVISION0, &hc->chip))
hc->hw.r_ram_sz |= V_FZ_MD;
@@ -1219,30 +1268,39 @@ init_chip(struct hfc_multi *hc)
if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: setting PCM into slave mode\n",
- __func__);
+ __func__);
} else
- if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip) && !plxsd_master) {
- if (debug & DEBUG_HFCMULTI_INIT)
- printk(KERN_DEBUG "%s: setting PCM into master mode\n",
- __func__);
- hc->hw.r_pcm_md0 |= V_PCM_MD;
- } else {
- if (debug & DEBUG_HFCMULTI_INIT)
- printk(KERN_DEBUG "%s: performing PCM auto detect\n",
- __func__);
- }
+ if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip) && !plxsd_master) {
+ if (debug & DEBUG_HFCMULTI_INIT)
+ printk(KERN_DEBUG "%s: setting PCM into master mode\n",
+ __func__);
+ hc->hw.r_pcm_md0 |= V_PCM_MD;
+ } else {
+ if (debug & DEBUG_HFCMULTI_INIT)
+ printk(KERN_DEBUG "%s: performing PCM auto detect\n",
+ __func__);
+ }
/* soft reset */
HFC_outb(hc, R_CTRL, hc->hw.r_ctrl);
- HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz);
+ if (hc->ctype == HFC_TYPE_XHFC)
+ HFC_outb(hc, 0x0C /* R_FIFO_THRES */,
+ 0x11 /* 16 Bytes TX/RX */);
+ else
+ HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz);
HFC_outb(hc, R_FIFO_MD, 0);
- hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES | V_RLD_EPR;
+ if (hc->ctype == HFC_TYPE_XHFC)
+ hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES;
+ else
+ hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES
+ | V_RLD_EPR;
HFC_outb(hc, R_CIRM, hc->hw.r_cirm);
udelay(100);
hc->hw.r_cirm = 0;
HFC_outb(hc, R_CIRM, hc->hw.r_cirm);
udelay(100);
- HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz);
+ if (hc->ctype != HFC_TYPE_XHFC)
+ HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz);
/* Speech Design PLX bridge pcm and sync mode */
if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
@@ -1254,14 +1312,14 @@ init_chip(struct hfc_multi *hc)
pv |= PLX_MASTER_EN | PLX_SLAVE_EN_N;
pv |= PLX_SYNC_O_EN;
if (debug & DEBUG_HFCMULTI_INIT)
- printk(KERN_WARNING "%s: master: PLX_GPIO=%x\n",
- __func__, pv);
+ printk(KERN_DEBUG "%s: master: PLX_GPIO=%x\n",
+ __func__, pv);
} else {
pv &= ~(PLX_MASTER_EN | PLX_SLAVE_EN_N);
pv &= ~PLX_SYNC_O_EN;
if (debug & DEBUG_HFCMULTI_INIT)
- printk(KERN_WARNING "%s: slave: PLX_GPIO=%x\n",
- __func__, pv);
+ printk(KERN_DEBUG "%s: slave: PLX_GPIO=%x\n",
+ __func__, pv);
}
writel(pv, plx_acc_32);
spin_unlock_irqrestore(&plx_lock, plx_flags);
@@ -1278,13 +1336,16 @@ init_chip(struct hfc_multi *hc)
HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0xa0);
if (test_bit(HFC_CHIP_PLXSD, &hc->chip))
HFC_outb(hc, R_PCM_MD2, V_SYNC_SRC); /* sync via SYNC_I / O */
+ else if (test_bit(HFC_CHIP_EMBSD, &hc->chip))
+ HFC_outb(hc, R_PCM_MD2, 0x10); /* V_C2O_EN */
else
HFC_outb(hc, R_PCM_MD2, 0x00); /* sync from interface */
HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00);
for (i = 0; i < 256; i++) {
HFC_outb_nodebug(hc, R_SLOT, i);
HFC_outb_nodebug(hc, A_SL_CFG, 0);
- HFC_outb_nodebug(hc, A_CONF, 0);
+ if (hc->ctype != HFC_TYPE_XHFC)
+ HFC_outb_nodebug(hc, A_CONF, 0);
hc->slot_owner[i] = -1;
}
@@ -1292,10 +1353,13 @@ init_chip(struct hfc_multi *hc)
if (test_bit(HFC_CHIP_CLOCK2, &hc->chip)) {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG
- "%s: setting double clock\n", __func__);
+ "%s: setting double clock\n", __func__);
HFC_outb(hc, R_BRG_PCM_CFG, V_PCM_CLK);
}
+ if (test_bit(HFC_CHIP_EMBSD, &hc->chip))
+ HFC_outb(hc, 0x02 /* R_CLK_CFG */, 0x40 /* V_CLKO_OFF */);
+
/* B410P GPIO */
if (test_bit(HFC_CHIP_B410P, &hc->chip)) {
printk(KERN_NOTICE "Setting GPIOs\n");
@@ -1311,48 +1375,48 @@ init_chip(struct hfc_multi *hc)
val += HFC_inb(hc, R_F0_CNTH) << 8;
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG
- "HFC_multi F0_CNT %ld after reset\n", val);
+ "HFC_multi F0_CNT %ld after reset\n", val);
spin_unlock_irqrestore(&hc->lock, flags);
set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout((HZ/100)?:1); /* Timeout minimum 10ms */
+ schedule_timeout((HZ / 100) ? : 1); /* Timeout minimum 10ms */
spin_lock_irqsave(&hc->lock, flags);
val2 = HFC_inb(hc, R_F0_CNTL);
val2 += HFC_inb(hc, R_F0_CNTH) << 8;
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG
- "HFC_multi F0_CNT %ld after 10 ms (1st try)\n",
- val2);
- if (val2 >= val+8) { /* 1 ms */
+ "HFC_multi F0_CNT %ld after 10 ms (1st try)\n",
+ val2);
+ if (val2 >= val + 8) { /* 1 ms */
/* it counts, so we keep the pcm mode */
if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip))
printk(KERN_INFO "controller is PCM bus MASTER\n");
else
- if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip))
- printk(KERN_INFO "controller is PCM bus SLAVE\n");
- else {
- test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip);
- printk(KERN_INFO "controller is PCM bus SLAVE "
- "(auto detected)\n");
- }
+ if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip))
+ printk(KERN_INFO "controller is PCM bus SLAVE\n");
+ else {
+ test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip);
+ printk(KERN_INFO "controller is PCM bus SLAVE "
+ "(auto detected)\n");
+ }
} else {
/* does not count */
if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) {
-controller_fail:
+ controller_fail:
printk(KERN_ERR "HFC_multi ERROR, getting no 125us "
- "pulse. Seems that controller fails.\n");
+ "pulse. Seems that controller fails.\n");
err = -EIO;
goto out;
}
if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) {
printk(KERN_INFO "controller is PCM bus SLAVE "
- "(ignoring missing PCM clock)\n");
+ "(ignoring missing PCM clock)\n");
} else {
/* only one pcm master */
if (test_bit(HFC_CHIP_PLXSD, &hc->chip)
- && plxsd_master) {
+ && plxsd_master) {
printk(KERN_ERR "HFC_multi ERROR, no clock "
- "on another Speech Design card found. "
- "Please be sure to connect PCM cable.\n");
+ "on another Speech Design card found. "
+ "Please be sure to connect PCM cable.\n");
err = -EIO;
goto out;
}
@@ -1366,25 +1430,25 @@ controller_fail:
writel(pv, plx_acc_32);
spin_unlock_irqrestore(&plx_lock, plx_flags);
if (debug & DEBUG_HFCMULTI_INIT)
- printk(KERN_WARNING "%s: master: PLX_GPIO"
- "=%x\n", __func__, pv);
+ printk(KERN_DEBUG "%s: master: "
+ "PLX_GPIO=%x\n", __func__, pv);
}
hc->hw.r_pcm_md0 |= V_PCM_MD;
HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00);
spin_unlock_irqrestore(&hc->lock, flags);
set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout((HZ/100)?:1); /* Timeout min. 10ms */
+ schedule_timeout((HZ / 100) ?: 1); /* Timeout min. 10ms */
spin_lock_irqsave(&hc->lock, flags);
val2 = HFC_inb(hc, R_F0_CNTL);
val2 += HFC_inb(hc, R_F0_CNTH) << 8;
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "HFC_multi F0_CNT %ld after "
- "10 ms (2nd try)\n", val2);
- if (val2 >= val+8) { /* 1 ms */
+ "10 ms (2nd try)\n", val2);
+ if (val2 >= val + 8) { /* 1 ms */
test_and_set_bit(HFC_CHIP_PCM_MASTER,
- &hc->chip);
+ &hc->chip);
printk(KERN_INFO "controller is PCM bus MASTER "
- "(auto detected)\n");
+ "(auto detected)\n");
} else
goto controller_fail;
}
@@ -1401,22 +1465,22 @@ controller_fail:
writel(pv, plx_acc_32);
spin_unlock_irqrestore(&plx_lock, plx_flags);
if (debug & DEBUG_HFCMULTI_INIT)
- printk(KERN_WARNING "%s: reset off: PLX_GPIO=%x\n",
- __func__, pv);
+ printk(KERN_DEBUG "%s: reset off: PLX_GPIO=%x\n",
+ __func__, pv);
}
/* pcm id */
if (hc->pcm)
printk(KERN_INFO "controller has given PCM BUS ID %d\n",
- hc->pcm);
+ hc->pcm);
else {
if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)
- || test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
+ || test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
PCM_cnt++; /* SD has proprietary bridging */
}
hc->pcm = PCM_cnt;
printk(KERN_INFO "controller has PCM BUS ID %d "
- "(auto selected)\n", hc->pcm);
+ "(auto selected)\n", hc->pcm);
}
/* set up timer */
@@ -1424,14 +1488,14 @@ controller_fail:
hc->hw.r_irqmsk_misc |= V_TI_IRQMSK;
/* set E1 state machine IRQ */
- if (hc->type == 1)
+ if (hc->ctype == HFC_TYPE_E1)
hc->hw.r_irqmsk_misc |= V_STA_IRQMSK;
/* set DTMF detection */
if (test_bit(HFC_CHIP_DTMF, &hc->chip)) {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: enabling DTMF detection "
- "for all B-channel\n", __func__);
+ "for all B-channel\n", __func__);
hc->hw.r_dtmf = V_DTMF_EN | V_DTMF_STOP;
if (test_bit(HFC_CHIP_ULAW, &hc->chip))
hc->hw.r_dtmf |= V_ULAW_SEL;
@@ -1444,7 +1508,8 @@ controller_fail:
r_conf_en = V_CONF_EN | V_ULAW;
else
r_conf_en = V_CONF_EN;
- HFC_outb(hc, R_CONF_EN, r_conf_en);
+ if (hc->ctype != HFC_TYPE_XHFC)
+ HFC_outb(hc, R_CONF_EN, r_conf_en);
/* setting leds */
switch (hc->leds) {
@@ -1468,21 +1533,28 @@ controller_fail:
break;
}
+ if (test_bit(HFC_CHIP_EMBSD, &hc->chip)) {
+ hc->hw.r_st_sync = 0x10; /* V_AUTO_SYNCI */
+ HFC_outb(hc, R_ST_SYNC, hc->hw.r_st_sync);
+ }
+
/* set master clock */
if (hc->masterclk >= 0) {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: setting ST master clock "
- "to port %d (0..%d)\n",
- __func__, hc->masterclk, hc->ports-1);
- hc->hw.r_st_sync = hc->masterclk | V_AUTO_SYNC;
+ "to port %d (0..%d)\n",
+ __func__, hc->masterclk, hc->ports - 1);
+ hc->hw.r_st_sync |= (hc->masterclk | V_AUTO_SYNC);
HFC_outb(hc, R_ST_SYNC, hc->hw.r_st_sync);
}
+
+
/* setting misc irq */
HFC_outb(hc, R_IRQMSK_MISC, hc->hw.r_irqmsk_misc);
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "r_irqmsk_misc.2: 0x%x\n",
- hc->hw.r_irqmsk_misc);
+ hc->hw.r_irqmsk_misc);
/* RAM access test */
HFC_outb(hc, R_RAM_ADDR0, 0);
@@ -1490,7 +1562,7 @@ controller_fail:
HFC_outb(hc, R_RAM_ADDR2, 0);
for (i = 0; i < 256; i++) {
HFC_outb_nodebug(hc, R_RAM_ADDR0, i);
- HFC_outb_nodebug(hc, R_RAM_DATA, ((i*3)&0xff));
+ HFC_outb_nodebug(hc, R_RAM_DATA, ((i * 3) & 0xff));
}
for (i = 0; i < 256; i++) {
HFC_outb_nodebug(hc, R_RAM_ADDR0, i);
@@ -1498,8 +1570,8 @@ controller_fail:
rval = HFC_inb_nodebug(hc, R_INT_DATA);
if (rval != ((i * 3) & 0xff)) {
printk(KERN_DEBUG
- "addr:%x val:%x should:%x\n", i, rval,
- (i * 3) & 0xff);
+ "addr:%x val:%x should:%x\n", i, rval,
+ (i * 3) & 0xff);
err++;
}
}
@@ -1528,9 +1600,9 @@ hfcmulti_watchdog(struct hfc_multi *hc)
if (hc->wdcount > 10) {
hc->wdcount = 0;
hc->wdbyte = hc->wdbyte == V_GPIO_OUT2 ?
- V_GPIO_OUT3 : V_GPIO_OUT2;
+ V_GPIO_OUT3 : V_GPIO_OUT2;
- /* printk("Sending Watchdog Kill %x\n",hc->wdbyte); */
+ /* printk("Sending Watchdog Kill %x\n",hc->wdbyte); */
HFC_outb(hc, R_GPIO_EN0, V_GPIO_EN2 | V_GPIO_EN3);
HFC_outb(hc, R_GPIO_OUT0, hc->wdbyte);
}
@@ -1550,43 +1622,49 @@ hfcmulti_leds(struct hfc_multi *hc)
struct dchannel *dch;
int led[4];
- hc->ledcount += poll;
- if (hc->ledcount > 4096) {
- hc->ledcount -= 4096;
- hc->ledstate = 0xAFFEAFFE;
- }
-
switch (hc->leds) {
case 1: /* HFC-E1 OEM */
- /* 2 red blinking: NT mode deactivate
- * 2 red steady: TE mode deactivate
- * left green: L1 active
- * left red: frame sync, but no L1
- * right green: L2 active
+ /* 2 red steady: LOS
+ * 1 red steady: L1 not active
+ * 2 green steady: L1 active
+ * 1st green flashing: activity on TX
+ * 2nd green flashing: activity on RX
*/
- if (hc->chan[hc->dslot].sync != 2) { /* no frame sync */
- if (hc->chan[hc->dslot].dch->dev.D.protocol
- != ISDN_P_NT_E1) {
- led[0] = 1;
+ led[0] = 0;
+ led[1] = 0;
+ led[2] = 0;
+ led[3] = 0;
+ dch = hc->chan[hc->dnum[0]].dch;
+ if (dch) {
+ if (hc->chan[hc->dnum[0]].los)
led[1] = 1;
- } else if (hc->ledcount>>11) {
+ if (hc->e1_state != 1) {
led[0] = 1;
- led[1] = 1;
+ hc->flash[2] = 0;
+ hc->flash[3] = 0;
} else {
- led[0] = 0;
- led[1] = 0;
+ led[2] = 1;
+ led[3] = 1;
+ if (!hc->flash[2] && hc->activity_tx)
+ hc->flash[2] = poll;
+ if (!hc->flash[3] && hc->activity_rx)
+ hc->flash[3] = poll;
+ if (hc->flash[2] && hc->flash[2] < 1024)
+ led[2] = 0;
+ if (hc->flash[3] && hc->flash[3] < 1024)
+ led[3] = 0;
+ if (hc->flash[2] >= 2048)
+ hc->flash[2] = 0;
+ if (hc->flash[3] >= 2048)
+ hc->flash[3] = 0;
+ if (hc->flash[2])
+ hc->flash[2] += poll;
+ if (hc->flash[3])
+ hc->flash[3] += poll;
}
- led[2] = 0;
- led[3] = 0;
- } else { /* with frame sync */
- /* TODO make it work */
- led[0] = 0;
- led[1] = 0;
- led[2] = 0;
- led[3] = 1;
}
leds = (led[0] | (led[1]<<2) | (led[2]<<1) | (led[3]<<3))^0xF;
- /* leds are inverted */
+ /* leds are inverted */
if (leds != (int)hc->ledstate) {
HFC_outb_nodebug(hc, R_GPIO_OUT1, leds);
hc->ledstate = leds;
@@ -1594,9 +1672,9 @@ hfcmulti_leds(struct hfc_multi *hc)
break;
case 2: /* HFC-4S OEM */
- /* red blinking = PH_DEACTIVATE NT Mode
- * red steady = PH_DEACTIVATE TE Mode
- * green steady = PH_ACTIVATE
+ /* red steady: PH_DEACTIVATE
+ * green steady: PH_ACTIVATE
+ * green flashing: activity on TX
*/
for (i = 0; i < 4; i++) {
state = 0;
@@ -1612,17 +1690,20 @@ hfcmulti_leds(struct hfc_multi *hc)
if (state) {
if (state == active) {
led[i] = 1; /* led green */
- } else
- if (dch->dev.D.protocol == ISDN_P_TE_S0)
- /* TE mode: led red */
- led[i] = 2;
- else
- if (hc->ledcount>>11)
- /* led red */
- led[i] = 2;
- else
- /* led off */
- led[i] = 0;
+ hc->activity_tx |= hc->activity_rx;
+ if (!hc->flash[i] &&
+ (hc->activity_tx & (1 << i)))
+ hc->flash[i] = poll;
+ if (hc->flash[i] && hc->flash[i] < 1024)
+ led[i] = 0; /* led off */
+ if (hc->flash[i] >= 2048)
+ hc->flash[i] = 0;
+ if (hc->flash[i])
+ hc->flash[i] += poll;
+ } else {
+ led[i] = 2; /* led red */
+ hc->flash[i] = 0;
+ }
} else
led[i] = 0; /* led off */
}
@@ -1643,9 +1724,9 @@ hfcmulti_leds(struct hfc_multi *hc)
}
} else {
leds = ((led[3] > 0) << 0) | ((led[1] > 0) << 1) |
- ((led[0] > 0) << 2) | ((led[2] > 0) << 3) |
- ((led[3] & 1) << 4) | ((led[1] & 1) << 5) |
- ((led[0] & 1) << 6) | ((led[2] & 1) << 7);
+ ((led[0] > 0) << 2) | ((led[2] > 0) << 3) |
+ ((led[3] & 1) << 4) | ((led[1] & 1) << 5) |
+ ((led[0] & 1) << 6) | ((led[2] & 1) << 7);
if (leds != (int)hc->ledstate) {
HFC_outb_nodebug(hc, R_GPIO_EN1, leds & 0x0F);
HFC_outb_nodebug(hc, R_GPIO_OUT1, leds >> 4);
@@ -1655,9 +1736,9 @@ hfcmulti_leds(struct hfc_multi *hc)
break;
case 3: /* HFC 1S/2S Beronet */
- /* red blinking = PH_DEACTIVATE NT Mode
- * red steady = PH_DEACTIVATE TE Mode
- * green steady = PH_ACTIVATE
+ /* red steady: PH_DEACTIVATE
+ * green steady: PH_ACTIVATE
+ * green flashing: activity on TX
*/
for (i = 0; i < 2; i++) {
state = 0;
@@ -1673,35 +1754,39 @@ hfcmulti_leds(struct hfc_multi *hc)
if (state) {
if (state == active) {
led[i] = 1; /* led green */
- } else
- if (dch->dev.D.protocol == ISDN_P_TE_S0)
- /* TE mode: led red */
- led[i] = 2;
- else
- if (hc->ledcount >> 11)
- /* led red */
- led[i] = 2;
- else
- /* led off */
- led[i] = 0;
+ hc->activity_tx |= hc->activity_rx;
+ if (!hc->flash[i] &&
+ (hc->activity_tx & (1 << i)))
+ hc->flash[i] = poll;
+ if (hc->flash[i] < 1024)
+ led[i] = 0; /* led off */
+ if (hc->flash[i] >= 2048)
+ hc->flash[i] = 0;
+ if (hc->flash[i])
+ hc->flash[i] += poll;
+ } else {
+ led[i] = 2; /* led red */
+ hc->flash[i] = 0;
+ }
} else
led[i] = 0; /* led off */
}
-
-
- leds = (led[0] > 0) | ((led[1] > 0)<<1) | ((led[0]&1)<<2)
- | ((led[1]&1)<<3);
+ leds = (led[0] > 0) | ((led[1] > 0) << 1) | ((led[0]&1) << 2)
+ | ((led[1]&1) << 3);
if (leds != (int)hc->ledstate) {
HFC_outb_nodebug(hc, R_GPIO_EN1,
- ((led[0] > 0) << 2) | ((led[1] > 0) << 3));
+ ((led[0] > 0) << 2) | ((led[1] > 0) << 3));
HFC_outb_nodebug(hc, R_GPIO_OUT1,
- ((led[0] & 1) << 2) | ((led[1] & 1) << 3));
+ ((led[0] & 1) << 2) | ((led[1] & 1) << 3));
hc->ledstate = leds;
}
break;
case 8: /* HFC 8S+ Beronet */
- lled = 0;
-
+ /* off: PH_DEACTIVATE
+ * steady: PH_ACTIVATE
+ * flashing: activity on TX
+ */
+ lled = 0xff; /* leds off */
for (i = 0; i < 8; i++) {
state = 0;
active = -1;
@@ -1715,19 +1800,25 @@ hfcmulti_leds(struct hfc_multi *hc)
}
if (state) {
if (state == active) {
- lled |= 0 << i;
+ lled &= ~(1 << i); /* led on */
+ hc->activity_tx |= hc->activity_rx;
+ if (!hc->flash[i] &&
+ (hc->activity_tx & (1 << i)))
+ hc->flash[i] = poll;
+ if (hc->flash[i] < 1024)
+ lled |= 1 << i; /* led off */
+ if (hc->flash[i] >= 2048)
+ hc->flash[i] = 0;
+ if (hc->flash[i])
+ hc->flash[i] += poll;
} else
- if (hc->ledcount >> 11)
- lled |= 0 << i;
- else
- lled |= 1 << i;
- } else
- lled |= 1 << i;
+ hc->flash[i] = 0;
+ }
}
leddw = lled << 24 | lled << 16 | lled << 8 | lled;
if (leddw != hc->ledstate) {
/* HFC_outb(hc, R_BRG_PCM_CFG, 1);
- HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x3); */
+ HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x3); */
/* was _io before */
HFC_outb_nodebug(hc, R_BRG_PCM_CFG, 1 | V_PCM_CLK);
outw(0x4000, hc->pci_iobase + 4);
@@ -1737,6 +1828,8 @@ hfcmulti_leds(struct hfc_multi *hc)
}
break;
}
+ hc->activity_tx = 0;
+ hc->activity_rx = 0;
}
/*
* read dtmf coefficients
@@ -1769,16 +1862,16 @@ hfcmulti_dtmf(struct hfc_multi *hc)
continue;
if (debug & DEBUG_HFCMULTI_DTMF)
printk(KERN_DEBUG "%s: dtmf channel %d:",
- __func__, ch);
+ __func__, ch);
coeff = &(hc->chan[ch].coeff[hc->chan[ch].coeff_count * 16]);
dtmf = 1;
for (co = 0; co < 8; co++) {
/* read W(n-1) coefficient */
- addr = hc->DTMFbase + ((co<<7) | (ch<<2));
+ addr = hc->DTMFbase + ((co << 7) | (ch << 2));
HFC_outb_nodebug(hc, R_RAM_ADDR0, addr);
- HFC_outb_nodebug(hc, R_RAM_ADDR1, addr>>8);
- HFC_outb_nodebug(hc, R_RAM_ADDR2, (addr>>16)
- | V_ADDR_INC);
+ HFC_outb_nodebug(hc, R_RAM_ADDR1, addr >> 8);
+ HFC_outb_nodebug(hc, R_RAM_ADDR2, (addr >> 16)
+ | V_ADDR_INC);
w_float = HFC_inb_nodebug(hc, R_RAM_DATA);
w_float |= (HFC_inb_nodebug(hc, R_RAM_DATA) << 8);
if (debug & DEBUG_HFCMULTI_DTMF)
@@ -1788,14 +1881,14 @@ hfcmulti_dtmf(struct hfc_multi *hc)
mantissa = w_float & 0x0fff;
if (w_float & 0x8000)
mantissa |= 0xfffff000;
- exponent = (w_float>>12) & 0x7;
+ exponent = (w_float >> 12) & 0x7;
if (exponent) {
mantissa ^= 0x1000;
- mantissa <<= (exponent-1);
+ mantissa <<= (exponent - 1);
}
/* store coefficient */
- coeff[co<<1] = mantissa;
+ coeff[co << 1] = mantissa;
/* read W(n) coefficient */
w_float = HFC_inb_nodebug(hc, R_RAM_DATA);
@@ -1807,27 +1900,27 @@ hfcmulti_dtmf(struct hfc_multi *hc)
mantissa = w_float & 0x0fff;
if (w_float & 0x8000)
mantissa |= 0xfffff000;
- exponent = (w_float>>12) & 0x7;
+ exponent = (w_float >> 12) & 0x7;
if (exponent) {
mantissa ^= 0x1000;
- mantissa <<= (exponent-1);
+ mantissa <<= (exponent - 1);
}
/* store coefficient */
- coeff[(co<<1)|1] = mantissa;
+ coeff[(co << 1) | 1] = mantissa;
}
if (debug & DEBUG_HFCMULTI_DTMF)
- printk("%s: DTMF ready %08x %08x %08x %08x "
- "%08x %08x %08x %08x\n", __func__,
- coeff[0], coeff[1], coeff[2], coeff[3],
- coeff[4], coeff[5], coeff[6], coeff[7]);
+ printk(" DTMF ready %08x %08x %08x %08x "
+ "%08x %08x %08x %08x\n",
+ coeff[0], coeff[1], coeff[2], coeff[3],
+ coeff[4], coeff[5], coeff[6], coeff[7]);
hc->chan[ch].coeff_count++;
if (hc->chan[ch].coeff_count == 8) {
hc->chan[ch].coeff_count = 0;
skb = mI_alloc_skb(512, GFP_ATOMIC);
if (!skb) {
- printk(KERN_WARNING "%s: No memory for skb\n",
- __func__);
+ printk(KERN_DEBUG "%s: No memory for skb\n",
+ __func__);
continue;
}
hh = mISDN_HEAD_P(skb);
@@ -1909,8 +2002,8 @@ next_frame:
while (f2 != (temp = HFC_inb_nodebug(hc, A_F2))) {
if (debug & DEBUG_HFCMULTI_FIFO)
printk(KERN_DEBUG
- "%s(card %d): reread f2 because %d!=%d\n",
- __func__, hc->id + 1, temp, f2);
+ "%s(card %d): reread f2 because %d!=%d\n",
+ __func__, hc->id + 1, temp, f2);
f2 = temp; /* repeat until F2 is equal */
}
Fspace = f2 - f1 - 1;
@@ -1929,7 +2022,7 @@ next_frame:
Fspace = 1;
}
/* one frame only for ST D-channels, to allow resending */
- if (hc->type != 1 && dch) {
+ if (hc->ctype != HFC_TYPE_E1 && dch) {
if (f1 != f2)
Fspace = 0;
}
@@ -1942,9 +2035,12 @@ next_frame:
while (z2 != (temp = (HFC_inw_nodebug(hc, A_Z2) - hc->Zmin))) {
if (debug & DEBUG_HFCMULTI_FIFO)
printk(KERN_DEBUG "%s(card %d): reread z2 because "
- "%d!=%d\n", __func__, hc->id + 1, temp, z2);
+ "%d!=%d\n", __func__, hc->id + 1, temp, z2);
z2 = temp; /* repeat unti Z2 is equal */
}
+ hc->chan[ch].Zfill = z1 - z2;
+ if (hc->chan[ch].Zfill < 0)
+ hc->chan[ch].Zfill += hc->Zlen;
Zspace = z2 - z1;
if (Zspace <= 0)
Zspace += hc->Zlen;
@@ -1963,18 +2059,28 @@ next_frame:
*txpending && slot_tx >= 0) {
if (debug & DEBUG_HFCMULTI_MODE)
printk(KERN_DEBUG
- "%s: reconnecting PCM due to no "
- "more FIFO data: channel %d "
- "slot_tx %d\n",
- __func__, ch, slot_tx);
+ "%s: reconnecting PCM due to no "
+ "more FIFO data: channel %d "
+ "slot_tx %d\n",
+ __func__, ch, slot_tx);
/* connect slot */
- HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 |
- V_HDLC_TRP | V_IFF);
- HFC_outb_nodebug(hc, R_FIFO, ch<<1 | 1);
+ if (hc->ctype == HFC_TYPE_XHFC)
+ HFC_outb(hc, A_CON_HDLC, 0xc0
+ | 0x07 << 2 | V_HDLC_TRP | V_IFF);
+ /* Enable FIFO, no interrupt */
+ else
+ HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 |
+ V_HDLC_TRP | V_IFF);
+ HFC_outb_nodebug(hc, R_FIFO, ch << 1 | 1);
HFC_wait_nodebug(hc);
- HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 |
- V_HDLC_TRP | V_IFF);
- HFC_outb_nodebug(hc, R_FIFO, ch<<1);
+ if (hc->ctype == HFC_TYPE_XHFC)
+ HFC_outb(hc, A_CON_HDLC, 0xc0
+ | 0x07 << 2 | V_HDLC_TRP | V_IFF);
+ /* Enable FIFO, no interrupt */
+ else
+ HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 |
+ V_HDLC_TRP | V_IFF);
+ HFC_outb_nodebug(hc, R_FIFO, ch << 1);
HFC_wait_nodebug(hc);
}
*txpending = 0;
@@ -1984,10 +2090,10 @@ next_frame:
/* "fill fifo if empty" feature */
if (bch && test_bit(FLG_FILLEMPTY, &bch->Flags)
- && !test_bit(FLG_HDLC, &bch->Flags) && z2 == z1) {
+ && !test_bit(FLG_HDLC, &bch->Flags) && z2 == z1) {
if (debug & DEBUG_HFCMULTI_FILL)
printk(KERN_DEBUG "%s: buffer empty, so we have "
- "underrun\n", __func__);
+ "underrun\n", __func__);
/* fill buffer, to prevent future underrun */
hc->write_fifo(hc, hc->silence_data, poll >> 1);
Zspace -= (poll >> 1);
@@ -1995,23 +2101,36 @@ next_frame:
/* if audio data and connected slot */
if (bch && (!test_bit(FLG_HDLC, &bch->Flags)) && (!*txpending)
- && slot_tx >= 0) {
+ && slot_tx >= 0) {
if (debug & DEBUG_HFCMULTI_MODE)
printk(KERN_DEBUG "%s: disconnecting PCM due to "
- "FIFO data: channel %d slot_tx %d\n",
- __func__, ch, slot_tx);
+ "FIFO data: channel %d slot_tx %d\n",
+ __func__, ch, slot_tx);
/* disconnect slot */
- HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 | V_HDLC_TRP | V_IFF);
- HFC_outb_nodebug(hc, R_FIFO, ch<<1 | 1);
+ if (hc->ctype == HFC_TYPE_XHFC)
+ HFC_outb(hc, A_CON_HDLC, 0x80
+ | 0x07 << 2 | V_HDLC_TRP | V_IFF);
+ /* Enable FIFO, no interrupt */
+ else
+ HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 |
+ V_HDLC_TRP | V_IFF);
+ HFC_outb_nodebug(hc, R_FIFO, ch << 1 | 1);
HFC_wait_nodebug(hc);
- HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 | V_HDLC_TRP | V_IFF);
- HFC_outb_nodebug(hc, R_FIFO, ch<<1);
+ if (hc->ctype == HFC_TYPE_XHFC)
+ HFC_outb(hc, A_CON_HDLC, 0x80
+ | 0x07 << 2 | V_HDLC_TRP | V_IFF);
+ /* Enable FIFO, no interrupt */
+ else
+ HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 |
+ V_HDLC_TRP | V_IFF);
+ HFC_outb_nodebug(hc, R_FIFO, ch << 1);
HFC_wait_nodebug(hc);
}
*txpending = 1;
/* show activity */
- hc->activity[hc->chan[ch].port] = 1;
+ if (dch)
+ hc->activity_tx |= 1 << hc->chan[ch].port;
/* fill fifo to what we have left */
ii = len;
@@ -2025,12 +2144,13 @@ next_frame:
ii = Zspace + i;
if (debug & DEBUG_HFCMULTI_FIFO)
printk(KERN_DEBUG "%s(card %d): fifo(%d) has %d bytes space "
- "left (z1=%04x, z2=%04x) sending %d of %d bytes %s\n",
- __func__, hc->id + 1, ch, Zspace, z1, z2, ii-i, len-i,
- temp ? "HDLC":"TRANS");
+ "left (z1=%04x, z2=%04x) sending %d of %d bytes %s\n",
+ __func__, hc->id + 1, ch, Zspace, z1, z2, ii-i, len-i,
+ temp ? "HDLC" : "TRANS");
/* Have to prep the audio data */
hc->write_fifo(hc, d, ii - i);
+ hc->chan[ch].Zfill += ii - i;
*idxp = ii;
/* if not all data has been written */
@@ -2046,13 +2166,9 @@ next_frame:
HFC_wait_nodebug(hc);
}
- /* send confirm, since get_net_bframe will not do it with trans */
- if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags))
- confirm_Bsend(bch);
-
- /* check for next frame */
dev_kfree_skb(*sp);
- if (bch && get_next_bframe(bch)) { /* hdlc is confirmed here */
+ /* check for next frame */
+ if (bch && get_next_bframe(bch)) {
len = (*sp)->len;
goto next_frame;
}
@@ -2080,24 +2196,20 @@ hfcmulti_rx(struct hfc_multi *hc, int ch)
int f1 = 0, f2 = 0; /* = 0, to make GCC happy */
int again = 0;
struct bchannel *bch;
- struct dchannel *dch;
+ struct dchannel *dch = NULL;
struct sk_buff *skb, **sp = NULL;
int maxlen;
bch = hc->chan[ch].bch;
- dch = hc->chan[ch].dch;
- if ((!dch) && (!bch))
- return;
- if (dch) {
+ if (bch) {
+ if (!test_bit(FLG_ACTIVE, &bch->Flags))
+ return;
+ } else if (hc->chan[ch].dch) {
+ dch = hc->chan[ch].dch;
if (!test_bit(FLG_ACTIVE, &dch->Flags))
return;
- sp = &dch->rx_skb;
- maxlen = dch->maxlen;
} else {
- if (!test_bit(FLG_ACTIVE, &bch->Flags))
- return;
- sp = &bch->rx_skb;
- maxlen = bch->maxlen;
+ return;
}
next_frame:
/* on first AND before getting next valid frame, R_FIFO must be written
@@ -2106,22 +2218,25 @@ next_frame:
(hc->chan[ch].protocol == ISDN_P_B_RAW) &&
(hc->chan[ch].slot_rx < 0) &&
(hc->chan[ch].slot_tx < 0))
- HFC_outb_nodebug(hc, R_FIFO, 0x20 | (ch<<1) | 1);
+ HFC_outb_nodebug(hc, R_FIFO, 0x20 | (ch << 1) | 1);
else
- HFC_outb_nodebug(hc, R_FIFO, (ch<<1)|1);
+ HFC_outb_nodebug(hc, R_FIFO, (ch << 1) | 1);
HFC_wait_nodebug(hc);
/* ignore if rx is off BUT change fifo (above) to start pending TX */
- if (hc->chan[ch].rx_off)
+ if (hc->chan[ch].rx_off) {
+ if (bch)
+ bch->dropcnt += poll; /* not exact but fair enough */
return;
+ }
if (dch || test_bit(FLG_HDLC, &bch->Flags)) {
f1 = HFC_inb_nodebug(hc, A_F1);
while (f1 != (temp = HFC_inb_nodebug(hc, A_F1))) {
if (debug & DEBUG_HFCMULTI_FIFO)
printk(KERN_DEBUG
- "%s(card %d): reread f1 because %d!=%d\n",
- __func__, hc->id + 1, temp, f1);
+ "%s(card %d): reread f1 because %d!=%d\n",
+ __func__, hc->id + 1, temp, f1);
f1 = temp; /* repeat until F1 is equal */
}
f2 = HFC_inb_nodebug(hc, A_F2);
@@ -2130,7 +2245,7 @@ next_frame:
while (z1 != (temp = (HFC_inw_nodebug(hc, A_Z1) - hc->Zmin))) {
if (debug & DEBUG_HFCMULTI_FIFO)
printk(KERN_DEBUG "%s(card %d): reread z2 because "
- "%d!=%d\n", __func__, hc->id + 1, temp, z2);
+ "%d!=%d\n", __func__, hc->id + 1, temp, z2);
z1 = temp; /* repeat until Z1 is equal */
}
z2 = HFC_inw_nodebug(hc, A_Z2) - hc->Zmin;
@@ -2144,31 +2259,45 @@ next_frame:
if (Zsize <= 0)
return;
- if (*sp == NULL) {
- *sp = mI_alloc_skb(maxlen + 3, GFP_ATOMIC);
- if (*sp == NULL) {
- printk(KERN_DEBUG "%s: No mem for rx_skb\n",
- __func__);
+ if (bch) {
+ maxlen = bchannel_get_rxbuf(bch, Zsize);
+ if (maxlen < 0) {
+ pr_warning("card%d.B%d: No bufferspace for %d bytes\n",
+ hc->id + 1, bch->nr, Zsize);
return;
}
+ sp = &bch->rx_skb;
+ maxlen = bch->maxlen;
+ } else { /* Dchannel */
+ sp = &dch->rx_skb;
+ maxlen = dch->maxlen + 3;
+ if (*sp == NULL) {
+ *sp = mI_alloc_skb(maxlen, GFP_ATOMIC);
+ if (*sp == NULL) {
+ pr_warning("card%d: No mem for dch rx_skb\n",
+ hc->id + 1);
+ return;
+ }
+ }
}
/* show activity */
- hc->activity[hc->chan[ch].port] = 1;
+ if (dch)
+ hc->activity_rx |= 1 << hc->chan[ch].port;
/* empty fifo with what we have */
if (dch || test_bit(FLG_HDLC, &bch->Flags)) {
if (debug & DEBUG_HFCMULTI_FIFO)
printk(KERN_DEBUG "%s(card %d): fifo(%d) reading %d "
- "bytes (z1=%04x, z2=%04x) HDLC %s (f1=%d, f2=%d) "
- "got=%d (again %d)\n", __func__, hc->id + 1, ch,
- Zsize, z1, z2, (f1 == f2) ? "fragment" : "COMPLETE",
- f1, f2, Zsize + (*sp)->len, again);
+ "bytes (z1=%04x, z2=%04x) HDLC %s (f1=%d, f2=%d) "
+ "got=%d (again %d)\n", __func__, hc->id + 1, ch,
+ Zsize, z1, z2, (f1 == f2) ? "fragment" : "COMPLETE",
+ f1, f2, Zsize + (*sp)->len, again);
/* HDLC */
- if ((Zsize + (*sp)->len) > (maxlen + 3)) {
+ if ((Zsize + (*sp)->len) > maxlen) {
if (debug & DEBUG_HFCMULTI_FIFO)
printk(KERN_DEBUG
- "%s(card %d): hdlc-frame too large.\n",
- __func__, hc->id + 1);
+ "%s(card %d): hdlc-frame too large.\n",
+ __func__, hc->id + 1);
skb_trim(*sp, 0);
HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F);
HFC_wait_nodebug(hc);
@@ -2185,8 +2314,8 @@ next_frame:
if ((*sp)->len < 4) {
if (debug & DEBUG_HFCMULTI_FIFO)
printk(KERN_DEBUG
- "%s(card %d): Frame below minimum "
- "size\n", __func__, hc->id + 1);
+ "%s(card %d): Frame below minimum "
+ "size\n", __func__, hc->id + 1);
skb_trim(*sp, 0);
goto next_frame;
}
@@ -2194,7 +2323,7 @@ next_frame:
if ((*sp)->data[(*sp)->len - 1]) {
if (debug & DEBUG_HFCMULTI_CRC)
printk(KERN_DEBUG
- "%s: CRC-error\n", __func__);
+ "%s: CRC-error\n", __func__);
skb_trim(*sp, 0);
goto next_frame;
}
@@ -2204,11 +2333,11 @@ next_frame:
*sp = mI_alloc_skb(skb->len, GFP_ATOMIC);
if (*sp) {
memcpy(skb_put(*sp, skb->len),
- skb->data, skb->len);
+ skb->data, skb->len);
skb_trim(skb, 0);
} else {
printk(KERN_DEBUG "%s: No mem\n",
- __func__);
+ __func__);
*sp = skb;
skb = NULL;
}
@@ -2217,7 +2346,7 @@ next_frame:
}
if (debug & DEBUG_HFCMULTI_FIFO) {
printk(KERN_DEBUG "%s(card %d):",
- __func__, hc->id + 1);
+ __func__, hc->id + 1);
temp = 0;
while (temp < (*sp)->len)
printk(" %02x", (*sp)->data[temp++]);
@@ -2226,7 +2355,7 @@ next_frame:
if (dch)
recv_Dchannel(dch);
else
- recv_Bchannel(bch);
+ recv_Bchannel(bch, MISDN_ID_ANY, false);
*sp = skb;
again++;
goto next_frame;
@@ -2234,32 +2363,14 @@ next_frame:
/* there is an incomplete frame */
} else {
/* transparent */
- if (Zsize > skb_tailroom(*sp))
- Zsize = skb_tailroom(*sp);
hc->read_fifo(hc, skb_put(*sp, Zsize), Zsize);
- if (((*sp)->len) < MISDN_COPY_SIZE) {
- skb = *sp;
- *sp = mI_alloc_skb(skb->len, GFP_ATOMIC);
- if (*sp) {
- memcpy(skb_put(*sp, skb->len),
- skb->data, skb->len);
- skb_trim(skb, 0);
- } else {
- printk(KERN_DEBUG "%s: No mem\n", __func__);
- *sp = skb;
- skb = NULL;
- }
- } else {
- skb = NULL;
- }
if (debug & DEBUG_HFCMULTI_FIFO)
printk(KERN_DEBUG
- "%s(card %d): fifo(%d) reading %d bytes "
- "(z1=%04x, z2=%04x) TRANS\n",
- __func__, hc->id + 1, ch, Zsize, z1, z2);
+ "%s(card %d): fifo(%d) reading %d bytes "
+ "(z1=%04x, z2=%04x) TRANS\n",
+ __func__, hc->id + 1, ch, Zsize, z1, z2);
/* only bch is transparent */
- recv_Bchannel(bch);
- *sp = skb;
+ recv_Bchannel(bch, hc->chan[ch].Zfill, false);
}
}
@@ -2279,7 +2390,7 @@ signal_state_up(struct dchannel *dch, int info, char *msg)
id = TEI_SAPI | (GROUP_TEI << 8); /* manager address */
skb = _alloc_mISDN_skb(MPH_INFORMATION_IND, id, sizeof(data), &data,
- GFP_ATOMIC);
+ GFP_ATOMIC);
if (!skb)
return;
recv_Dchannel_skb(dch, skb);
@@ -2312,10 +2423,10 @@ handle_timer_irq(struct hfc_multi *hc)
if (hc->e1_resync & 4) {
if (debug & DEBUG_HFCMULTI_PLXSD)
printk(KERN_DEBUG
- "Enable QUARTZ for HFC-E1\n");
+ "Enable QUARTZ for HFC-E1\n");
/* set jatt to quartz */
HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC
- | V_JATT_OFF);
+ | V_JATT_OFF);
/* switch to JATT, in case it is not already */
HFC_outb(hc, R_SYNC_OUT, 0);
}
@@ -2323,7 +2434,7 @@ handle_timer_irq(struct hfc_multi *hc)
spin_unlock_irqrestore(&HFClock, flags);
}
- if (hc->type != 1 || hc->e1_state == 1)
+ if (hc->ctype != HFC_TYPE_E1 || hc->e1_state == 1)
for (ch = 0; ch <= 31; ch++) {
if (hc->created[hc->chan[ch].port]) {
hfcmulti_tx(hc, ch);
@@ -2334,80 +2445,80 @@ handle_timer_irq(struct hfc_multi *hc)
dch = hc->chan[ch].dch;
if (!(--hc->chan[ch].nt_timer)) {
schedule_event(dch,
- FLG_PHCHANGE);
+ FLG_PHCHANGE);
if (debug &
DEBUG_HFCMULTI_STATE)
printk(KERN_DEBUG
- "%s: nt_timer at "
- "state %x\n",
- __func__,
- dch->state);
+ "%s: nt_timer at "
+ "state %x\n",
+ __func__,
+ dch->state);
}
}
}
}
- if (hc->type == 1 && hc->created[0]) {
- dch = hc->chan[hc->dslot].dch;
- if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) {
- /* LOS */
- temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_SIG_LOS;
- if (!temp && hc->chan[hc->dslot].los)
+ if (hc->ctype == HFC_TYPE_E1 && hc->created[0]) {
+ dch = hc->chan[hc->dnum[0]].dch;
+ /* LOS */
+ temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_SIG_LOS;
+ hc->chan[hc->dnum[0]].los = temp;
+ if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[0]].cfg)) {
+ if (!temp && hc->chan[hc->dnum[0]].los)
signal_state_up(dch, L1_SIGNAL_LOS_ON,
- "LOS detected");
- if (temp && !hc->chan[hc->dslot].los)
+ "LOS detected");
+ if (temp && !hc->chan[hc->dnum[0]].los)
signal_state_up(dch, L1_SIGNAL_LOS_OFF,
- "LOS gone");
- hc->chan[hc->dslot].los = temp;
+ "LOS gone");
}
- if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dslot].cfg)) {
+ if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dnum[0]].cfg)) {
/* AIS */
temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_AIS;
- if (!temp && hc->chan[hc->dslot].ais)
+ if (!temp && hc->chan[hc->dnum[0]].ais)
signal_state_up(dch, L1_SIGNAL_AIS_ON,
- "AIS detected");
- if (temp && !hc->chan[hc->dslot].ais)
+ "AIS detected");
+ if (temp && !hc->chan[hc->dnum[0]].ais)
signal_state_up(dch, L1_SIGNAL_AIS_OFF,
- "AIS gone");
- hc->chan[hc->dslot].ais = temp;
+ "AIS gone");
+ hc->chan[hc->dnum[0]].ais = temp;
}
- if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dslot].cfg)) {
+ if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dnum[0]].cfg)) {
/* SLIP */
temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_RX;
- if (!temp && hc->chan[hc->dslot].slip_rx)
+ if (!temp && hc->chan[hc->dnum[0]].slip_rx)
signal_state_up(dch, L1_SIGNAL_SLIP_RX,
- " bit SLIP detected RX");
- hc->chan[hc->dslot].slip_rx = temp;
+ " bit SLIP detected RX");
+ hc->chan[hc->dnum[0]].slip_rx = temp;
temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_TX;
- if (!temp && hc->chan[hc->dslot].slip_tx)
+ if (!temp && hc->chan[hc->dnum[0]].slip_tx)
signal_state_up(dch, L1_SIGNAL_SLIP_TX,
- " bit SLIP detected TX");
- hc->chan[hc->dslot].slip_tx = temp;
+ " bit SLIP detected TX");
+ hc->chan[hc->dnum[0]].slip_tx = temp;
}
- if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dslot].cfg)) {
+ if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dnum[0]].cfg)) {
/* RDI */
temp = HFC_inb_nodebug(hc, R_RX_SL0_0) & V_A;
- if (!temp && hc->chan[hc->dslot].rdi)
+ if (!temp && hc->chan[hc->dnum[0]].rdi)
signal_state_up(dch, L1_SIGNAL_RDI_ON,
- "RDI detected");
- if (temp && !hc->chan[hc->dslot].rdi)
+ "RDI detected");
+ if (temp && !hc->chan[hc->dnum[0]].rdi)
signal_state_up(dch, L1_SIGNAL_RDI_OFF,
- "RDI gone");
- hc->chan[hc->dslot].rdi = temp;
+ "RDI gone");
+ hc->chan[hc->dnum[0]].rdi = temp;
}
temp = HFC_inb_nodebug(hc, R_JATT_DIR);
- switch (hc->chan[hc->dslot].sync) {
+ switch (hc->chan[hc->dnum[0]].sync) {
case 0:
if ((temp & 0x60) == 0x60) {
if (debug & DEBUG_HFCMULTI_SYNC)
printk(KERN_DEBUG
- "%s: (id=%d) E1 now "
- "in clock sync\n",
- __func__, hc->id);
+ "%s: (id=%d) E1 now "
+ "in clock sync\n",
+ __func__, hc->id);
HFC_outb(hc, R_RX_OFF,
- hc->chan[hc->dslot].jitter | V_RX_INIT);
+ hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
HFC_outb(hc, R_TX_OFF,
- hc->chan[hc->dslot].jitter | V_RX_INIT);
- hc->chan[hc->dslot].sync = 1;
+ hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
+ hc->chan[hc->dnum[0]].sync = 1;
goto check_framesync;
}
break;
@@ -2415,41 +2526,41 @@ handle_timer_irq(struct hfc_multi *hc)
if ((temp & 0x60) != 0x60) {
if (debug & DEBUG_HFCMULTI_SYNC)
printk(KERN_DEBUG
- "%s: (id=%d) E1 "
- "lost clock sync\n",
- __func__, hc->id);
- hc->chan[hc->dslot].sync = 0;
+ "%s: (id=%d) E1 "
+ "lost clock sync\n",
+ __func__, hc->id);
+ hc->chan[hc->dnum[0]].sync = 0;
break;
}
-check_framesync:
+ check_framesync:
temp = HFC_inb_nodebug(hc, R_SYNC_STA);
if (temp == 0x27) {
if (debug & DEBUG_HFCMULTI_SYNC)
printk(KERN_DEBUG
- "%s: (id=%d) E1 "
- "now in frame sync\n",
- __func__, hc->id);
- hc->chan[hc->dslot].sync = 2;
+ "%s: (id=%d) E1 "
+ "now in frame sync\n",
+ __func__, hc->id);
+ hc->chan[hc->dnum[0]].sync = 2;
}
break;
case 2:
if ((temp & 0x60) != 0x60) {
if (debug & DEBUG_HFCMULTI_SYNC)
printk(KERN_DEBUG
- "%s: (id=%d) E1 lost "
- "clock & frame sync\n",
- __func__, hc->id);
- hc->chan[hc->dslot].sync = 0;
+ "%s: (id=%d) E1 lost "
+ "clock & frame sync\n",
+ __func__, hc->id);
+ hc->chan[hc->dnum[0]].sync = 0;
break;
}
temp = HFC_inb_nodebug(hc, R_SYNC_STA);
if (temp != 0x27) {
if (debug & DEBUG_HFCMULTI_SYNC)
printk(KERN_DEBUG
- "%s: (id=%d) E1 "
- "lost frame sync\n",
- __func__, hc->id);
- hc->chan[hc->dslot].sync = 1;
+ "%s: (id=%d) E1 "
+ "lost frame sync\n",
+ __func__, hc->id);
+ hc->chan[hc->dnum[0]].sync = 1;
}
break;
}
@@ -2476,30 +2587,30 @@ ph_state_irq(struct hfc_multi *hc, u_char r_irq_statech)
dch = hc->chan[ch].dch;
if (r_irq_statech & 1) {
HFC_outb_nodebug(hc, R_ST_SEL,
- hc->chan[ch].port);
+ hc->chan[ch].port);
/* undocumented: delay after R_ST_SEL */
udelay(1);
/* undocumented: status changes during read */
st_status = HFC_inb_nodebug(hc, A_ST_RD_STATE);
while (st_status != (temp =
- HFC_inb_nodebug(hc, A_ST_RD_STATE))) {
+ HFC_inb_nodebug(hc, A_ST_RD_STATE))) {
if (debug & DEBUG_HFCMULTI_STATE)
printk(KERN_DEBUG "%s: reread "
- "STATE because %d!=%d\n",
- __func__, temp,
- st_status);
+ "STATE because %d!=%d\n",
+ __func__, temp,
+ st_status);
st_status = temp; /* repeat */
}
/* Speech Design TE-sync indication */
if (test_bit(HFC_CHIP_PLXSD, &hc->chip) &&
- dch->dev.D.protocol == ISDN_P_TE_S0) {
+ dch->dev.D.protocol == ISDN_P_TE_S0) {
if (st_status & V_FR_SYNC_ST)
hc->syncronized |=
- (1 << hc->chan[ch].port);
+ (1 << hc->chan[ch].port);
else
hc->syncronized &=
- ~(1 << hc->chan[ch].port);
+ ~(1 << hc->chan[ch].port);
}
dch->state = st_status & 0x0f;
if (dch->dev.D.protocol == ISDN_P_NT_S0)
@@ -2508,19 +2619,19 @@ ph_state_irq(struct hfc_multi *hc, u_char r_irq_statech)
active = 7;
if (dch->state == active) {
HFC_outb_nodebug(hc, R_FIFO,
- (ch << 1) | 1);
+ (ch << 1) | 1);
HFC_wait_nodebug(hc);
HFC_outb_nodebug(hc,
- R_INC_RES_FIFO, V_RES_F);
+ R_INC_RES_FIFO, V_RES_F);
HFC_wait_nodebug(hc);
dch->tx_idx = 0;
}
schedule_event(dch, FLG_PHCHANGE);
if (debug & DEBUG_HFCMULTI_STATE)
printk(KERN_DEBUG
- "%s: S/T newstate %x port %d\n",
- __func__, dch->state,
- hc->chan[ch].port);
+ "%s: S/T newstate %x port %d\n",
+ __func__, dch->state,
+ hc->chan[ch].port);
}
r_irq_statech >>= 1;
}
@@ -2582,7 +2693,7 @@ hfcmulti_interrupt(int intno, void *dev_id)
{
#ifdef IRQCOUNT_DEBUG
static int iq1 = 0, iq2 = 0, iq3 = 0, iq4 = 0,
- iq5 = 0, iq6 = 0, iqcnt = 0;
+ iq5 = 0, iq6 = 0, iqcnt = 0;
#endif
struct hfc_multi *hc = dev_id;
struct dchannel *dch;
@@ -2590,7 +2701,7 @@ hfcmulti_interrupt(int intno, void *dev_id)
int i;
void __iomem *plx_acc;
u_short wval;
- u_char e1_syncsta, temp;
+ u_char e1_syncsta, temp, temp2;
u_long flags;
if (!hc) {
@@ -2603,10 +2714,13 @@ hfcmulti_interrupt(int intno, void *dev_id)
#ifdef IRQ_DEBUG
if (irqsem)
printk(KERN_ERR "irq for card %d during irq from "
- "card %d, this is no bug.\n", hc->id + 1, irqsem);
+ "card %d, this is no bug.\n", hc->id + 1, irqsem);
irqsem = hc->id + 1;
#endif
-
+#ifdef CONFIG_MISDN_HFCMULTI_8xx
+ if (hc->immap->im_cpm.cp_pbdat & hc->pb_irqmsk)
+ goto irq_notforus;
+#endif
if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
spin_lock_irqsave(&plx_lock, flags);
plx_acc = hc->plx_membase + PLX_INTCSR;
@@ -2633,20 +2747,20 @@ hfcmulti_interrupt(int intno, void *dev_id)
iq6++;
if (iqcnt++ > 5000) {
printk(KERN_ERR "iq1:%x iq2:%x iq3:%x iq4:%x iq5:%x iq6:%x\n",
- iq1, iq2, iq3, iq4, iq5, iq6);
+ iq1, iq2, iq3, iq4, iq5, iq6);
iqcnt = 0;
}
#endif
if (!r_irq_statech &&
!(status & (V_DTMF_STA | V_LOST_STA | V_EXT_IRQSTA |
- V_MISC_IRQSTA | V_FR_IRQSTA))) {
+ V_MISC_IRQSTA | V_FR_IRQSTA))) {
/* irq is not for us */
goto irq_notforus;
}
hc->irqcnt++;
if (r_irq_statech) {
- if (hc->type != 1)
+ if (hc->ctype != HFC_TYPE_E1)
ph_state_irq(hc, r_irq_statech);
}
if (status & V_EXT_IRQSTA)
@@ -2660,35 +2774,38 @@ hfcmulti_interrupt(int intno, void *dev_id)
r_irq_misc = HFC_inb_nodebug(hc, R_IRQ_MISC);
r_irq_misc &= hc->hw.r_irqmsk_misc; /* ignore disabled irqs */
if (r_irq_misc & V_STA_IRQ) {
- if (hc->type == 1) {
+ if (hc->ctype == HFC_TYPE_E1) {
/* state machine */
- dch = hc->chan[hc->dslot].dch;
+ dch = hc->chan[hc->dnum[0]].dch;
e1_syncsta = HFC_inb_nodebug(hc, R_SYNC_STA);
if (test_bit(HFC_CHIP_PLXSD, &hc->chip)
- && hc->e1_getclock) {
+ && hc->e1_getclock) {
if (e1_syncsta & V_FR_SYNC_E1)
hc->syncronized = 1;
else
hc->syncronized = 0;
}
/* undocumented: status changes during read */
- dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA);
- while (dch->state != (temp =
- HFC_inb_nodebug(hc, R_E1_RD_STA))) {
+ temp = HFC_inb_nodebug(hc, R_E1_RD_STA);
+ while (temp != (temp2 =
+ HFC_inb_nodebug(hc, R_E1_RD_STA))) {
if (debug & DEBUG_HFCMULTI_STATE)
printk(KERN_DEBUG "%s: reread "
- "STATE because %d!=%d\n",
- __func__, temp,
- dch->state);
- dch->state = temp; /* repeat */
+ "STATE because %d!=%d\n",
+ __func__, temp, temp2);
+ temp = temp2; /* repeat */
}
- dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA)
- & 0x7;
- schedule_event(dch, FLG_PHCHANGE);
+ /* broadcast state change to all fragments */
if (debug & DEBUG_HFCMULTI_STATE)
printk(KERN_DEBUG
- "%s: E1 (id=%d) newstate %x\n",
- __func__, hc->id, dch->state);
+ "%s: E1 (id=%d) newstate %x\n",
+ __func__, hc->id, temp & 0x7);
+ for (i = 0; i < hc->ports; i++) {
+ dch = hc->chan[hc->dnum[i]].dch;
+ dch->state = temp & 0x7;
+ schedule_event(dch, FLG_PHCHANGE);
+ }
+
if (test_bit(HFC_CHIP_PLXSD, &hc->chip))
plxsd_checksync(hc, 0);
}
@@ -2699,14 +2816,14 @@ hfcmulti_interrupt(int intno, void *dev_id)
handle_timer_irq(hc);
}
- if (r_irq_misc & V_DTMF_IRQ) {
+ if (r_irq_misc & V_DTMF_IRQ)
hfcmulti_dtmf(hc);
- }
+
if (r_irq_misc & V_IRQ_PROC) {
static int irq_proc_cnt;
if (!irq_proc_cnt++)
- printk(KERN_WARNING "%s: got V_IRQ_PROC -"
- " this should not happen\n", __func__);
+ printk(KERN_DEBUG "%s: got V_IRQ_PROC -"
+ " this should not happen\n", __func__);
}
}
@@ -2755,41 +2872,42 @@ hfcmulti_dbusy_timer(struct hfc_multi *hc)
*/
static int
mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
- int bank_tx, int slot_rx, int bank_rx)
+ int bank_tx, int slot_rx, int bank_rx)
{
int flow_tx = 0, flow_rx = 0, routing = 0;
int oslot_tx, oslot_rx;
int conf;
if (ch < 0 || ch > 31)
- return EINVAL;
+ return -EINVAL;
oslot_tx = hc->chan[ch].slot_tx;
oslot_rx = hc->chan[ch].slot_rx;
conf = hc->chan[ch].conf;
if (debug & DEBUG_HFCMULTI_MODE)
printk(KERN_DEBUG
- "%s: card %d channel %d protocol %x slot old=%d new=%d "
- "bank new=%d (TX) slot old=%d new=%d bank new=%d (RX)\n",
- __func__, hc->id, ch, protocol, oslot_tx, slot_tx,
- bank_tx, oslot_rx, slot_rx, bank_rx);
+ "%s: card %d channel %d protocol %x slot old=%d new=%d "
+ "bank new=%d (TX) slot old=%d new=%d bank new=%d (RX)\n",
+ __func__, hc->id, ch, protocol, oslot_tx, slot_tx,
+ bank_tx, oslot_rx, slot_rx, bank_rx);
if (oslot_tx >= 0 && slot_tx != oslot_tx) {
/* remove from slot */
if (debug & DEBUG_HFCMULTI_MODE)
printk(KERN_DEBUG "%s: remove from slot %d (TX)\n",
- __func__, oslot_tx);
- if (hc->slot_owner[oslot_tx<<1] == ch) {
+ __func__, oslot_tx);
+ if (hc->slot_owner[oslot_tx << 1] == ch) {
HFC_outb(hc, R_SLOT, oslot_tx << 1);
HFC_outb(hc, A_SL_CFG, 0);
- HFC_outb(hc, A_CONF, 0);
- hc->slot_owner[oslot_tx<<1] = -1;
+ if (hc->ctype != HFC_TYPE_XHFC)
+ HFC_outb(hc, A_CONF, 0);
+ hc->slot_owner[oslot_tx << 1] = -1;
} else {
if (debug & DEBUG_HFCMULTI_MODE)
printk(KERN_DEBUG
- "%s: we are not owner of this tx slot "
- "anymore, channel %d is.\n",
- __func__, hc->slot_owner[oslot_tx<<1]);
+ "%s: we are not owner of this tx slot "
+ "anymore, channel %d is.\n",
+ __func__, hc->slot_owner[oslot_tx << 1]);
}
}
@@ -2797,8 +2915,8 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
/* remove from slot */
if (debug & DEBUG_HFCMULTI_MODE)
printk(KERN_DEBUG
- "%s: remove from slot %d (RX)\n",
- __func__, oslot_rx);
+ "%s: remove from slot %d (RX)\n",
+ __func__, oslot_rx);
if (hc->slot_owner[(oslot_rx << 1) | 1] == ch) {
HFC_outb(hc, R_SLOT, (oslot_rx << 1) | V_SL_DIR);
HFC_outb(hc, A_SL_CFG, 0);
@@ -2806,10 +2924,10 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
} else {
if (debug & DEBUG_HFCMULTI_MODE)
printk(KERN_DEBUG
- "%s: we are not owner of this rx slot "
- "anymore, channel %d is.\n",
- __func__,
- hc->slot_owner[(oslot_rx << 1) | 1]);
+ "%s: we are not owner of this rx slot "
+ "anymore, channel %d is.\n",
+ __func__,
+ hc->slot_owner[(oslot_rx << 1) | 1]);
}
}
@@ -2830,12 +2948,14 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
routing = 0x40; /* loop */
if (debug & DEBUG_HFCMULTI_MODE)
printk(KERN_DEBUG "%s: put channel %d to slot %d bank"
- " %d flow %02x routing %02x conf %d (TX)\n",
- __func__, ch, slot_tx, bank_tx,
- flow_tx, routing, conf);
+ " %d flow %02x routing %02x conf %d (TX)\n",
+ __func__, ch, slot_tx, bank_tx,
+ flow_tx, routing, conf);
HFC_outb(hc, R_SLOT, slot_tx << 1);
- HFC_outb(hc, A_SL_CFG, (ch<<1) | routing);
- HFC_outb(hc, A_CONF, (conf < 0) ? 0 : (conf | V_CONF_SL));
+ HFC_outb(hc, A_SL_CFG, (ch << 1) | routing);
+ if (hc->ctype != HFC_TYPE_XHFC)
+ HFC_outb(hc, A_CONF,
+ (conf < 0) ? 0 : (conf | V_CONF_SL));
hc->slot_owner[slot_tx << 1] = ch;
hc->chan[ch].slot_tx = slot_tx;
hc->chan[ch].bank_tx = bank_tx;
@@ -2852,17 +2972,17 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
else
flow_rx = 0xc0; /* ST->(FIFO,PCM) */
/* put on slot */
- routing = bank_rx?0x80:0xc0; /* reversed */
+ routing = bank_rx ? 0x80 : 0xc0; /* reversed */
if (conf >= 0 || bank_rx > 1)
routing = 0x40; /* loop */
if (debug & DEBUG_HFCMULTI_MODE)
printk(KERN_DEBUG "%s: put channel %d to slot %d bank"
- " %d flow %02x routing %02x conf %d (RX)\n",
- __func__, ch, slot_rx, bank_rx,
- flow_rx, routing, conf);
- HFC_outb(hc, R_SLOT, (slot_rx<<1) | V_SL_DIR);
- HFC_outb(hc, A_SL_CFG, (ch<<1) | V_CH_DIR | routing);
- hc->slot_owner[(slot_rx<<1)|1] = ch;
+ " %d flow %02x routing %02x conf %d (RX)\n",
+ __func__, ch, slot_rx, bank_rx,
+ flow_rx, routing, conf);
+ HFC_outb(hc, R_SLOT, (slot_rx << 1) | V_SL_DIR);
+ HFC_outb(hc, A_SL_CFG, (ch << 1) | V_CH_DIR | routing);
+ hc->slot_owner[(slot_rx << 1) | 1] = ch;
hc->chan[ch].slot_rx = slot_rx;
hc->chan[ch].bank_rx = bank_rx;
}
@@ -2878,26 +2998,26 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
HFC_wait(hc);
/* disable RX fifo */
- HFC_outb(hc, R_FIFO, (ch<<1)|1);
+ HFC_outb(hc, R_FIFO, (ch << 1) | 1);
HFC_wait(hc);
HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00);
HFC_outb(hc, A_SUBCH_CFG, 0);
HFC_outb(hc, A_IRQ_MSK, 0);
HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
HFC_wait(hc);
- if (hc->chan[ch].bch && hc->type != 1) {
+ if (hc->chan[ch].bch && hc->ctype != HFC_TYPE_E1) {
hc->hw.a_st_ctrl0[hc->chan[ch].port] &=
- ((ch & 0x3) == 0)? ~V_B1_EN: ~V_B2_EN;
+ ((ch & 0x3) == 0) ? ~V_B1_EN : ~V_B2_EN;
HFC_outb(hc, R_ST_SEL, hc->chan[ch].port);
/* undocumented: delay after R_ST_SEL */
udelay(1);
HFC_outb(hc, A_ST_CTRL0,
- hc->hw.a_st_ctrl0[hc->chan[ch].port]);
+ hc->hw.a_st_ctrl0[hc->chan[ch].port]);
}
if (hc->chan[ch].bch) {
test_and_clear_bit(FLG_HDLC, &hc->chan[ch].bch->Flags);
test_and_clear_bit(FLG_TRANSPARENT,
- &hc->chan[ch].bch->Flags);
+ &hc->chan[ch].bch->Flags);
}
break;
case (ISDN_P_B_RAW): /* B-channel */
@@ -2907,20 +3027,20 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
(hc->chan[ch].slot_tx < 0)) {
printk(KERN_DEBUG
- "Setting B-channel %d to echo cancelable "
- "state on PCM slot %d\n", ch,
- ((ch / 4) * 8) + ((ch % 4) * 4) + 1);
+ "Setting B-channel %d to echo cancelable "
+ "state on PCM slot %d\n", ch,
+ ((ch / 4) * 8) + ((ch % 4) * 4) + 1);
printk(KERN_DEBUG
- "Enabling pass through for channel\n");
+ "Enabling pass through for channel\n");
vpm_out(hc, ch, ((ch / 4) * 8) +
- ((ch % 4) * 4) + 1, 0x01);
+ ((ch % 4) * 4) + 1, 0x01);
/* rx path */
/* S/T -> PCM */
HFC_outb(hc, R_FIFO, (ch << 1));
HFC_wait(hc);
HFC_outb(hc, A_CON_HDLC, 0xc0 | V_HDLC_TRP | V_IFF);
HFC_outb(hc, R_SLOT, (((ch / 4) * 8) +
- ((ch % 4) * 4) + 1) << 1);
+ ((ch % 4) * 4) + 1) << 1);
HFC_outb(hc, A_SL_CFG, 0x80 | (ch << 1));
/* PCM -> FIFO */
@@ -2929,10 +3049,12 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
HFC_outb(hc, A_CON_HDLC, 0x20 | V_HDLC_TRP | V_IFF);
HFC_outb(hc, A_SUBCH_CFG, 0);
HFC_outb(hc, A_IRQ_MSK, 0);
- HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
- HFC_wait(hc);
+ if (hc->chan[ch].protocol != protocol) {
+ HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
+ HFC_wait(hc);
+ }
HFC_outb(hc, R_SLOT, ((((ch / 4) * 8) +
- ((ch % 4) * 4) + 1) << 1) | 1);
+ ((ch % 4) * 4) + 1) << 1) | 1);
HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1) | 1);
/* tx path */
@@ -2941,7 +3063,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
HFC_wait(hc);
HFC_outb(hc, A_CON_HDLC, 0xc0 | V_HDLC_TRP | V_IFF);
HFC_outb(hc, R_SLOT, ((((ch / 4) * 8) +
- ((ch % 4) * 4)) << 1) | 1);
+ ((ch % 4) * 4)) << 1) | 1);
HFC_outb(hc, A_SL_CFG, 0x80 | 0x40 | (ch << 1) | 1);
/* FIFO -> PCM */
@@ -2950,46 +3072,63 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
HFC_outb(hc, A_CON_HDLC, 0x20 | V_HDLC_TRP | V_IFF);
HFC_outb(hc, A_SUBCH_CFG, 0);
HFC_outb(hc, A_IRQ_MSK, 0);
- HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
- HFC_wait(hc);
+ if (hc->chan[ch].protocol != protocol) {
+ HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
+ HFC_wait(hc);
+ }
/* tx silence */
HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
HFC_outb(hc, R_SLOT, (((ch / 4) * 8) +
- ((ch % 4) * 4)) << 1);
+ ((ch % 4) * 4)) << 1);
HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1));
} else {
/* enable TX fifo */
HFC_outb(hc, R_FIFO, ch << 1);
HFC_wait(hc);
- HFC_outb(hc, A_CON_HDLC, flow_tx | 0x00 |
- V_HDLC_TRP | V_IFF);
+ if (hc->ctype == HFC_TYPE_XHFC)
+ HFC_outb(hc, A_CON_HDLC, flow_tx | 0x07 << 2 |
+ V_HDLC_TRP | V_IFF);
+ /* Enable FIFO, no interrupt */
+ else
+ HFC_outb(hc, A_CON_HDLC, flow_tx | 0x00 |
+ V_HDLC_TRP | V_IFF);
HFC_outb(hc, A_SUBCH_CFG, 0);
HFC_outb(hc, A_IRQ_MSK, 0);
- HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
- HFC_wait(hc);
+ if (hc->chan[ch].protocol != protocol) {
+ HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
+ HFC_wait(hc);
+ }
/* tx silence */
HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
/* enable RX fifo */
- HFC_outb(hc, R_FIFO, (ch<<1)|1);
+ HFC_outb(hc, R_FIFO, (ch << 1) | 1);
HFC_wait(hc);
- HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00 | V_HDLC_TRP);
+ if (hc->ctype == HFC_TYPE_XHFC)
+ HFC_outb(hc, A_CON_HDLC, flow_rx | 0x07 << 2 |
+ V_HDLC_TRP);
+ /* Enable FIFO, no interrupt*/
+ else
+ HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00 |
+ V_HDLC_TRP);
HFC_outb(hc, A_SUBCH_CFG, 0);
HFC_outb(hc, A_IRQ_MSK, 0);
- HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
- HFC_wait(hc);
+ if (hc->chan[ch].protocol != protocol) {
+ HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
+ HFC_wait(hc);
+ }
}
- if (hc->type != 1) {
+ if (hc->ctype != HFC_TYPE_E1) {
hc->hw.a_st_ctrl0[hc->chan[ch].port] |=
- ((ch & 0x3) == 0) ? V_B1_EN : V_B2_EN;
+ ((ch & 0x3) == 0) ? V_B1_EN : V_B2_EN;
HFC_outb(hc, R_ST_SEL, hc->chan[ch].port);
/* undocumented: delay after R_ST_SEL */
udelay(1);
HFC_outb(hc, A_ST_CTRL0,
- hc->hw.a_st_ctrl0[hc->chan[ch].port]);
+ hc->hw.a_st_ctrl0[hc->chan[ch].port]);
}
if (hc->chan[ch].bch)
test_and_set_bit(FLG_TRANSPARENT,
- &hc->chan[ch].bch->Flags);
+ &hc->chan[ch].bch->Flags);
break;
case (ISDN_P_B_HDLC): /* B-channel */
case (ISDN_P_TE_S0): /* D-channel */
@@ -2997,9 +3136,9 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
case (ISDN_P_TE_E1):
case (ISDN_P_NT_E1):
/* enable TX fifo */
- HFC_outb(hc, R_FIFO, ch<<1);
+ HFC_outb(hc, R_FIFO, ch << 1);
HFC_wait(hc);
- if (hc->type == 1 || hc->chan[ch].bch) {
+ if (hc->ctype == HFC_TYPE_E1 || hc->chan[ch].bch) {
/* E1 or B-channel */
HFC_outb(hc, A_CON_HDLC, flow_tx | 0x04);
HFC_outb(hc, A_SUBCH_CFG, 0);
@@ -3012,10 +3151,10 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
HFC_wait(hc);
/* enable RX fifo */
- HFC_outb(hc, R_FIFO, (ch<<1)|1);
+ HFC_outb(hc, R_FIFO, (ch << 1) | 1);
HFC_wait(hc);
HFC_outb(hc, A_CON_HDLC, flow_rx | 0x04);
- if (hc->type == 1 || hc->chan[ch].bch)
+ if (hc->ctype == HFC_TYPE_E1 || hc->chan[ch].bch)
HFC_outb(hc, A_SUBCH_CFG, 0); /* full 8 bits */
else
HFC_outb(hc, A_SUBCH_CFG, 2); /* 2 bits dchannel */
@@ -3024,20 +3163,20 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
HFC_wait(hc);
if (hc->chan[ch].bch) {
test_and_set_bit(FLG_HDLC, &hc->chan[ch].bch->Flags);
- if (hc->type != 1) {
+ if (hc->ctype != HFC_TYPE_E1) {
hc->hw.a_st_ctrl0[hc->chan[ch].port] |=
- ((ch&0x3) == 0) ? V_B1_EN : V_B2_EN;
+ ((ch & 0x3) == 0) ? V_B1_EN : V_B2_EN;
HFC_outb(hc, R_ST_SEL, hc->chan[ch].port);
/* undocumented: delay after R_ST_SEL */
udelay(1);
HFC_outb(hc, A_ST_CTRL0,
- hc->hw.a_st_ctrl0[hc->chan[ch].port]);
+ hc->hw.a_st_ctrl0[hc->chan[ch].port]);
}
}
break;
default:
printk(KERN_DEBUG "%s: protocol not known %x\n",
- __func__, protocol);
+ __func__, protocol);
hc->chan[ch].protocol = ISDN_P_NONE;
return -ENOPROTOOPT;
}
@@ -3052,9 +3191,9 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
static void
hfcmulti_pcm(struct hfc_multi *hc, int ch, int slot_tx, int bank_tx,
- int slot_rx, int bank_rx)
+ int slot_rx, int bank_rx)
{
- if (slot_rx < 0 || slot_rx < 0 || bank_tx < 0 || bank_rx < 0) {
+ if (slot_tx < 0 || slot_rx < 0 || bank_tx < 0 || bank_rx < 0) {
/* disable PCM */
mode_hfcmulti(hc, ch, hc->chan[ch].protocol, -1, 0, -1, 0);
return;
@@ -3062,7 +3201,7 @@ hfcmulti_pcm(struct hfc_multi *hc, int ch, int slot_tx, int bank_tx,
/* enable pcm */
mode_hfcmulti(hc, ch, hc->chan[ch].protocol, slot_tx, bank_tx,
- slot_rx, bank_rx);
+ slot_rx, bank_rx);
}
/*
@@ -3077,8 +3216,8 @@ hfcmulti_conf(struct hfc_multi *hc, int ch, int num)
else
hc->chan[ch].conf = -1;
mode_hfcmulti(hc, ch, hc->chan[ch].protocol, hc->chan[ch].slot_tx,
- hc->chan[ch].bank_tx, hc->chan[ch].slot_rx,
- hc->chan[ch].bank_rx);
+ hc->chan[ch].bank_tx, hc->chan[ch].slot_rx,
+ hc->chan[ch].bank_rx);
}
@@ -3104,11 +3243,11 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
case HW_RESET_REQ:
/* start activation */
spin_lock_irqsave(&hc->lock, flags);
- if (hc->type == 1) {
+ if (hc->ctype == HFC_TYPE_E1) {
if (debug & DEBUG_HFCMULTI_MSG)
printk(KERN_DEBUG
- "%s: HW_RESET_REQ no BRI\n",
- __func__);
+ "%s: HW_RESET_REQ no BRI\n",
+ __func__);
} else {
HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port);
/* undocumented: delay after R_ST_SEL */
@@ -3116,8 +3255,8 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
HFC_outb(hc, A_ST_WR_STATE, V_ST_LD_STA | 3); /* F3 */
udelay(6); /* wait at least 5,21us */
HFC_outb(hc, A_ST_WR_STATE, 3);
- HFC_outb(hc, A_ST_WR_STATE, 3 | (V_ST_ACT*3));
- /* activate */
+ HFC_outb(hc, A_ST_WR_STATE, 3 | (V_ST_ACT * 3));
+ /* activate */
}
spin_unlock_irqrestore(&hc->lock, flags);
l1_event(dch->l1, HW_POWERUP_IND);
@@ -3125,20 +3264,20 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
case HW_DEACT_REQ:
/* start deactivation */
spin_lock_irqsave(&hc->lock, flags);
- if (hc->type == 1) {
+ if (hc->ctype == HFC_TYPE_E1) {
if (debug & DEBUG_HFCMULTI_MSG)
printk(KERN_DEBUG
- "%s: HW_DEACT_REQ no BRI\n",
- __func__);
+ "%s: HW_DEACT_REQ no BRI\n",
+ __func__);
} else {
HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port);
/* undocumented: delay after R_ST_SEL */
udelay(1);
- HFC_outb(hc, A_ST_WR_STATE, V_ST_ACT*2);
- /* deactivate */
+ HFC_outb(hc, A_ST_WR_STATE, V_ST_ACT * 2);
+ /* deactivate */
if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
hc->syncronized &=
- ~(1 << hc->chan[dch->slot].port);
+ ~(1 << hc->chan[dch->slot].port);
plxsd_checksync(hc, 0);
}
}
@@ -3159,11 +3298,11 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
break;
case HW_POWERUP_REQ:
spin_lock_irqsave(&hc->lock, flags);
- if (hc->type == 1) {
+ if (hc->ctype == HFC_TYPE_E1) {
if (debug & DEBUG_HFCMULTI_MSG)
printk(KERN_DEBUG
- "%s: HW_POWERUP_REQ no BRI\n",
- __func__);
+ "%s: HW_POWERUP_REQ no BRI\n",
+ __func__);
} else {
HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port);
/* undocumented: delay after R_ST_SEL */
@@ -3177,17 +3316,17 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
case PH_ACTIVATE_IND:
test_and_set_bit(FLG_ACTIVE, &dch->Flags);
_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
- GFP_ATOMIC);
+ GFP_ATOMIC);
break;
case PH_DEACTIVATE_IND:
test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
- GFP_ATOMIC);
+ GFP_ATOMIC);
break;
default:
if (dch->debug & DEBUG_HW)
printk(KERN_DEBUG "%s: unknown command %x\n",
- __func__, cmd);
+ __func__, cmd);
return -1;
}
return 0;
@@ -3232,27 +3371,27 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
ret = 0;
if (debug & DEBUG_HFCMULTI_MSG)
printk(KERN_DEBUG
- "%s: PH_ACTIVATE port %d (0..%d)\n",
- __func__, hc->chan[dch->slot].port,
- hc->ports-1);
+ "%s: PH_ACTIVATE port %d (0..%d)\n",
+ __func__, hc->chan[dch->slot].port,
+ hc->ports - 1);
/* start activation */
- if (hc->type == 1) {
+ if (hc->ctype == HFC_TYPE_E1) {
ph_state_change(dch);
if (debug & DEBUG_HFCMULTI_STATE)
printk(KERN_DEBUG
- "%s: E1 report state %x \n",
- __func__, dch->state);
+ "%s: E1 report state %x \n",
+ __func__, dch->state);
} else {
HFC_outb(hc, R_ST_SEL,
- hc->chan[dch->slot].port);
+ hc->chan[dch->slot].port);
/* undocumented: delay after R_ST_SEL */
udelay(1);
HFC_outb(hc, A_ST_WR_STATE, V_ST_LD_STA | 1);
- /* G1 */
+ /* G1 */
udelay(6); /* wait at least 5,21us */
HFC_outb(hc, A_ST_WR_STATE, 1);
HFC_outb(hc, A_ST_WR_STATE, 1 |
- (V_ST_ACT*3)); /* activate */
+ (V_ST_ACT * 3)); /* activate */
dch->state = 1;
}
spin_unlock_irqrestore(&hc->lock, flags);
@@ -3265,22 +3404,22 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
spin_lock_irqsave(&hc->lock, flags);
if (debug & DEBUG_HFCMULTI_MSG)
printk(KERN_DEBUG
- "%s: PH_DEACTIVATE port %d (0..%d)\n",
- __func__, hc->chan[dch->slot].port,
- hc->ports-1);
+ "%s: PH_DEACTIVATE port %d (0..%d)\n",
+ __func__, hc->chan[dch->slot].port,
+ hc->ports - 1);
/* start deactivation */
- if (hc->type == 1) {
+ if (hc->ctype == HFC_TYPE_E1) {
if (debug & DEBUG_HFCMULTI_MSG)
printk(KERN_DEBUG
- "%s: PH_DEACTIVATE no BRI\n",
- __func__);
+ "%s: PH_DEACTIVATE no BRI\n",
+ __func__);
} else {
HFC_outb(hc, R_ST_SEL,
- hc->chan[dch->slot].port);
+ hc->chan[dch->slot].port);
/* undocumented: delay after R_ST_SEL */
udelay(1);
HFC_outb(hc, A_ST_WR_STATE, V_ST_ACT * 2);
- /* deactivate */
+ /* deactivate */
dch->state = 1;
}
skb_queue_purge(&dch->squeue);
@@ -3318,22 +3457,8 @@ deactivate_bchannel(struct bchannel *bch)
u_long flags;
spin_lock_irqsave(&hc->lock, flags);
- if (test_and_clear_bit(FLG_TX_NEXT, &bch->Flags)) {
- dev_kfree_skb(bch->next_skb);
- bch->next_skb = NULL;
- }
- if (bch->tx_skb) {
- dev_kfree_skb(bch->tx_skb);
- bch->tx_skb = NULL;
- }
- bch->tx_idx = 0;
- if (bch->rx_skb) {
- dev_kfree_skb(bch->rx_skb);
- bch->rx_skb = NULL;
- }
+ mISDN_clear_bchannel(bch);
hc->chan[bch->slot].coeff_count = 0;
- test_and_clear_bit(FLG_ACTIVE, &bch->Flags);
- test_and_clear_bit(FLG_TX_BUSY, &bch->Flags);
hc->chan[bch->slot].rx_off = 0;
hc->chan[bch->slot].conf = -1;
mode_hfcmulti(hc, bch->slot, ISDN_P_NONE, -1, 0, -1, 0);
@@ -3347,8 +3472,7 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
struct hfc_multi *hc = bch->hw;
int ret = -EINVAL;
struct mISDNhead *hh = mISDN_HEAD_P(skb);
- unsigned int id;
- u_long flags;
+ unsigned long flags;
switch (hh->prim) {
case PH_DATA_REQ:
@@ -3357,45 +3481,39 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
spin_lock_irqsave(&hc->lock, flags);
ret = bchannel_senddata(bch, skb);
if (ret > 0) { /* direct TX */
- id = hh->id; /* skb can be freed */
hfcmulti_tx(hc, bch->slot);
ret = 0;
/* start fifo */
HFC_outb_nodebug(hc, R_FIFO, 0);
HFC_wait_nodebug(hc);
- if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) {
- spin_unlock_irqrestore(&hc->lock, flags);
- queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
- } else
- spin_unlock_irqrestore(&hc->lock, flags);
- } else
- spin_unlock_irqrestore(&hc->lock, flags);
+ }
+ spin_unlock_irqrestore(&hc->lock, flags);
return ret;
case PH_ACTIVATE_REQ:
if (debug & DEBUG_HFCMULTI_MSG)
printk(KERN_DEBUG "%s: PH_ACTIVATE ch %d (0..32)\n",
- __func__, bch->slot);
+ __func__, bch->slot);
spin_lock_irqsave(&hc->lock, flags);
/* activate B-channel if not already activated */
if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) {
hc->chan[bch->slot].txpending = 0;
ret = mode_hfcmulti(hc, bch->slot,
- ch->protocol,
- hc->chan[bch->slot].slot_tx,
- hc->chan[bch->slot].bank_tx,
- hc->chan[bch->slot].slot_rx,
- hc->chan[bch->slot].bank_rx);
+ ch->protocol,
+ hc->chan[bch->slot].slot_tx,
+ hc->chan[bch->slot].bank_tx,
+ hc->chan[bch->slot].slot_rx,
+ hc->chan[bch->slot].bank_rx);
if (!ret) {
if (ch->protocol == ISDN_P_B_RAW && !hc->dtmf
- && test_bit(HFC_CHIP_DTMF, &hc->chip)) {
+ && test_bit(HFC_CHIP_DTMF, &hc->chip)) {
/* start decoder */
hc->dtmf = 1;
if (debug & DEBUG_HFCMULTI_DTMF)
printk(KERN_DEBUG
- "%s: start dtmf decoder\n",
- __func__);
+ "%s: start dtmf decoder\n",
+ __func__);
HFC_outb(hc, R_DTMF, hc->hw.r_dtmf |
- V_RST_DTMF);
+ V_RST_DTMF);
}
}
} else
@@ -3403,28 +3521,28 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
spin_unlock_irqrestore(&hc->lock, flags);
if (!ret)
_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0, NULL,
- GFP_KERNEL);
+ GFP_KERNEL);
break;
case PH_CONTROL_REQ:
spin_lock_irqsave(&hc->lock, flags);
switch (hh->id) {
case HFC_SPL_LOOP_ON: /* set sample loop */
if (debug & DEBUG_HFCMULTI_MSG)
- printk(KERN_DEBUG
- "%s: HFC_SPL_LOOP_ON (len = %d)\n",
- __func__, skb->len);
+ printk(KERN_DEBUG
+ "%s: HFC_SPL_LOOP_ON (len = %d)\n",
+ __func__, skb->len);
ret = 0;
break;
case HFC_SPL_LOOP_OFF: /* set silence */
if (debug & DEBUG_HFCMULTI_MSG)
printk(KERN_DEBUG "%s: HFC_SPL_LOOP_OFF\n",
- __func__);
+ __func__);
ret = 0;
break;
default:
printk(KERN_ERR
- "%s: unknown PH_CONTROL_REQ info %x\n",
- __func__, hh->id);
+ "%s: unknown PH_CONTROL_REQ info %x\n",
+ __func__, hh->id);
ret = -EINVAL;
}
spin_unlock_irqrestore(&hc->lock, flags);
@@ -3432,7 +3550,7 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
case PH_DEACTIVATE_REQ:
deactivate_bchannel(bch); /* locked there */
_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0, NULL,
- GFP_KERNEL);
+ GFP_KERNEL);
ret = 0;
break;
}
@@ -3459,10 +3577,11 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
switch (cq->op) {
case MISDN_CTRL_GETOP:
- cq->op = MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP
- | MISDN_CTRL_RX_OFF | MISDN_CTRL_FILL_EMPTY;
+ ret = mISDN_ctrl_bchannel(bch, cq);
+ cq->op |= MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP;
break;
case MISDN_CTRL_RX_OFF: /* turn off / on rx stream */
+ ret = mISDN_ctrl_bchannel(bch, cq);
hc->chan[bch->slot].rx_off = !!cq->p1;
if (!hc->chan[bch->slot].rx_off) {
/* reset fifo on rx on */
@@ -3473,22 +3592,23 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
}
if (debug & DEBUG_HFCMULTI_MSG)
printk(KERN_DEBUG "%s: RX_OFF request (nr=%d off=%d)\n",
- __func__, bch->nr, hc->chan[bch->slot].rx_off);
+ __func__, bch->nr, hc->chan[bch->slot].rx_off);
break;
- case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */
- test_and_set_bit(FLG_FILLEMPTY, &bch->Flags);
- if (debug & DEBUG_HFCMULTI_MSG)
- printk(KERN_DEBUG "%s: FILL_EMPTY request (nr=%d "
- "off=%d)\n", __func__, bch->nr, !!cq->p1);
+ case MISDN_CTRL_FILL_EMPTY:
+ ret = mISDN_ctrl_bchannel(bch, cq);
+ hc->silence = bch->fill[0];
+ memset(hc->silence_data, hc->silence, sizeof(hc->silence_data));
break;
case MISDN_CTRL_HW_FEATURES: /* fill features structure */
if (debug & DEBUG_HFCMULTI_MSG)
printk(KERN_DEBUG "%s: HW_FEATURE request\n",
- __func__);
+ __func__);
/* create confirm */
features->hfc_id = hc->id;
if (test_bit(HFC_CHIP_DTMF, &hc->chip))
features->hfc_dtmf = 1;
+ if (test_bit(HFC_CHIP_CONF, &hc->chip))
+ features->hfc_conf = 1;
features->hfc_loops = 0;
if (test_bit(HFC_CHIP_B410P, &hc->chip)) {
features->hfc_echocanhw = 1;
@@ -3505,40 +3625,40 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
bank_rx = cq->p2 >> 8;
if (debug & DEBUG_HFCMULTI_MSG)
printk(KERN_DEBUG
- "%s: HFC_PCM_CONN slot %d bank %d (TX) "
- "slot %d bank %d (RX)\n",
- __func__, slot_tx, bank_tx,
- slot_rx, bank_rx);
+ "%s: HFC_PCM_CONN slot %d bank %d (TX) "
+ "slot %d bank %d (RX)\n",
+ __func__, slot_tx, bank_tx,
+ slot_rx, bank_rx);
if (slot_tx < hc->slots && bank_tx <= 2 &&
slot_rx < hc->slots && bank_rx <= 2)
hfcmulti_pcm(hc, bch->slot,
- slot_tx, bank_tx, slot_rx, bank_rx);
+ slot_tx, bank_tx, slot_rx, bank_rx);
else {
printk(KERN_WARNING
- "%s: HFC_PCM_CONN slot %d bank %d (TX) "
- "slot %d bank %d (RX) out of range\n",
- __func__, slot_tx, bank_tx,
- slot_rx, bank_rx);
+ "%s: HFC_PCM_CONN slot %d bank %d (TX) "
+ "slot %d bank %d (RX) out of range\n",
+ __func__, slot_tx, bank_tx,
+ slot_rx, bank_rx);
ret = -EINVAL;
}
break;
case MISDN_CTRL_HFC_PCM_DISC: /* release interface from pcm timeslot */
if (debug & DEBUG_HFCMULTI_MSG)
printk(KERN_DEBUG "%s: HFC_PCM_DISC\n",
- __func__);
+ __func__);
hfcmulti_pcm(hc, bch->slot, -1, 0, -1, 0);
break;
case MISDN_CTRL_HFC_CONF_JOIN: /* join conference (0..7) */
num = cq->p1 & 0xff;
if (debug & DEBUG_HFCMULTI_MSG)
printk(KERN_DEBUG "%s: HFC_CONF_JOIN conf %d\n",
- __func__, num);
+ __func__, num);
if (num <= 7)
hfcmulti_conf(hc, bch->slot, num);
else {
printk(KERN_WARNING
- "%s: HW_CONF_JOIN conf %d out of range\n",
- __func__, num);
+ "%s: HW_CONF_JOIN conf %d out of range\n",
+ __func__, num);
ret = -EINVAL;
}
break;
@@ -3559,16 +3679,14 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
case MISDN_CTRL_HFC_ECHOCAN_OFF:
if (debug & DEBUG_HFCMULTI_MSG)
printk(KERN_DEBUG "%s: HFC_ECHOCAN_OFF\n",
- __func__);
+ __func__);
if (test_bit(HFC_CHIP_B410P, &hc->chip))
vpm_echocan_off(hc, bch->slot);
else
ret = -EINVAL;
break;
default:
- printk(KERN_WARNING "%s: unknown Op %x\n",
- __func__, cq->op);
- ret = -EINVAL;
+ ret = mISDN_ctrl_bchannel(bch, cq);
break;
}
return ret;
@@ -3584,12 +3702,11 @@ hfcm_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
if (bch->debug & DEBUG_HW)
printk(KERN_DEBUG "%s: cmd:%x %p\n",
- __func__, cmd, arg);
+ __func__, cmd, arg);
switch (cmd) {
case CLOSE_CHANNEL:
test_and_clear_bit(FLG_OPEN, &bch->Flags);
- if (test_bit(FLG_ACTIVE, &bch->Flags))
- deactivate_bchannel(bch); /* locked there */
+ deactivate_bchannel(bch); /* locked there */
ch->protocol = ISDN_P_NONE;
ch->peer = NULL;
module_put(THIS_MODULE);
@@ -3602,7 +3719,7 @@ hfcm_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
break;
default:
printk(KERN_WARNING "%s: unknown prim(%x)\n",
- __func__, cmd);
+ __func__, cmd);
}
return err;
}
@@ -3619,40 +3736,40 @@ ph_state_change(struct dchannel *dch)
int ch, i;
if (!dch) {
- printk(KERN_WARNING "%s: ERROR given dch is NULL\n",
- __func__);
+ printk(KERN_WARNING "%s: ERROR given dch is NULL\n", __func__);
return;
}
hc = dch->hw;
ch = dch->slot;
- if (hc->type == 1) {
+ if (hc->ctype == HFC_TYPE_E1) {
if (dch->dev.D.protocol == ISDN_P_TE_E1) {
if (debug & DEBUG_HFCMULTI_STATE)
printk(KERN_DEBUG
- "%s: E1 TE (id=%d) newstate %x\n",
- __func__, hc->id, dch->state);
+ "%s: E1 TE (id=%d) newstate %x\n",
+ __func__, hc->id, dch->state);
} else {
if (debug & DEBUG_HFCMULTI_STATE)
printk(KERN_DEBUG
- "%s: E1 NT (id=%d) newstate %x\n",
- __func__, hc->id, dch->state);
+ "%s: E1 NT (id=%d) newstate %x\n",
+ __func__, hc->id, dch->state);
}
switch (dch->state) {
case (1):
if (hc->e1_state != 1) {
- for (i = 1; i <= 31; i++) {
- /* reset fifos on e1 activation */
- HFC_outb_nodebug(hc, R_FIFO, (i << 1) | 1);
- HFC_wait_nodebug(hc);
- HFC_outb_nodebug(hc,
- R_INC_RES_FIFO, V_RES_F);
- HFC_wait_nodebug(hc);
- }
+ for (i = 1; i <= 31; i++) {
+ /* reset fifos on e1 activation */
+ HFC_outb_nodebug(hc, R_FIFO,
+ (i << 1) | 1);
+ HFC_wait_nodebug(hc);
+ HFC_outb_nodebug(hc, R_INC_RES_FIFO,
+ V_RES_F);
+ HFC_wait_nodebug(hc);
+ }
}
test_and_set_bit(FLG_ACTIVE, &dch->Flags);
_queue_data(&dch->dev.D, PH_ACTIVATE_IND,
- MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
+ MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
break;
default:
@@ -3660,15 +3777,15 @@ ph_state_change(struct dchannel *dch)
return;
test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
_queue_data(&dch->dev.D, PH_DEACTIVATE_IND,
- MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
+ MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
}
hc->e1_state = dch->state;
} else {
if (dch->dev.D.protocol == ISDN_P_TE_S0) {
if (debug & DEBUG_HFCMULTI_STATE)
printk(KERN_DEBUG
- "%s: S/T TE newstate %x\n",
- __func__, dch->state);
+ "%s: S/T TE newstate %x\n",
+ __func__, dch->state);
switch (dch->state) {
case (0):
l1_event(dch->l1, HW_RESET_IND);
@@ -3690,38 +3807,38 @@ ph_state_change(struct dchannel *dch)
} else {
if (debug & DEBUG_HFCMULTI_STATE)
printk(KERN_DEBUG "%s: S/T NT newstate %x\n",
- __func__, dch->state);
+ __func__, dch->state);
switch (dch->state) {
case (2):
if (hc->chan[ch].nt_timer == 0) {
hc->chan[ch].nt_timer = -1;
HFC_outb(hc, R_ST_SEL,
- hc->chan[ch].port);
+ hc->chan[ch].port);
/* undocumented: delay after R_ST_SEL */
udelay(1);
HFC_outb(hc, A_ST_WR_STATE, 4 |
- V_ST_LD_STA); /* G4 */
+ V_ST_LD_STA); /* G4 */
udelay(6); /* wait at least 5,21us */
HFC_outb(hc, A_ST_WR_STATE, 4);
dch->state = 4;
} else {
/* one extra count for the next event */
hc->chan[ch].nt_timer =
- nt_t1_count[poll_timer] + 1;
+ nt_t1_count[poll_timer] + 1;
HFC_outb(hc, R_ST_SEL,
- hc->chan[ch].port);
+ hc->chan[ch].port);
/* undocumented: delay after R_ST_SEL */
udelay(1);
/* allow G2 -> G3 transition */
HFC_outb(hc, A_ST_WR_STATE, 2 |
- V_SET_G2_G3);
+ V_SET_G2_G3);
}
break;
case (1):
hc->chan[ch].nt_timer = -1;
test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
_queue_data(&dch->dev.D, PH_DEACTIVATE_IND,
- MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
+ MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
break;
case (4):
hc->chan[ch].nt_timer = -1;
@@ -3730,7 +3847,7 @@ ph_state_change(struct dchannel *dch)
hc->chan[ch].nt_timer = -1;
test_and_set_bit(FLG_ACTIVE, &dch->Flags);
_queue_data(&dch->dev.D, PH_ACTIVATE_IND,
- MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
+ MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
break;
}
}
@@ -3751,31 +3868,37 @@ hfcmulti_initmode(struct dchannel *dch)
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: entered\n", __func__);
- if (hc->type == 1) {
- hc->chan[hc->dslot].slot_tx = -1;
- hc->chan[hc->dslot].slot_rx = -1;
- hc->chan[hc->dslot].conf = -1;
- if (hc->dslot) {
- mode_hfcmulti(hc, hc->dslot, dch->dev.D.protocol,
- -1, 0, -1, 0);
+ i = dch->slot;
+ pt = hc->chan[i].port;
+ if (hc->ctype == HFC_TYPE_E1) {
+ /* E1 */
+ hc->chan[hc->dnum[pt]].slot_tx = -1;
+ hc->chan[hc->dnum[pt]].slot_rx = -1;
+ hc->chan[hc->dnum[pt]].conf = -1;
+ if (hc->dnum[pt]) {
+ mode_hfcmulti(hc, dch->slot, dch->dev.D.protocol,
+ -1, 0, -1, 0);
dch->timer.function = (void *) hfcmulti_dbusy_timer;
dch->timer.data = (long) dch;
init_timer(&dch->timer);
}
for (i = 1; i <= 31; i++) {
- if (i == hc->dslot)
+ if (!((1 << i) & hc->bmask[pt])) /* skip unused chan */
continue;
hc->chan[i].slot_tx = -1;
hc->chan[i].slot_rx = -1;
hc->chan[i].conf = -1;
mode_hfcmulti(hc, i, ISDN_P_NONE, -1, 0, -1, 0);
}
- /* E1 */
- if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) {
+ }
+ if (hc->ctype == HFC_TYPE_E1 && pt == 0) {
+ /* E1, port 0 */
+ dch = hc->chan[hc->dnum[0]].dch;
+ if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[0]].cfg)) {
HFC_outb(hc, R_LOS0, 255); /* 2 ms */
HFC_outb(hc, R_LOS1, 255); /* 512 ms */
}
- if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dslot].cfg)) {
+ if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dnum[0]].cfg)) {
HFC_outb(hc, R_RX0, 0);
hc->hw.r_tx0 = 0 | V_OUT_EN;
} else {
@@ -3788,24 +3911,24 @@ hfcmulti_initmode(struct dchannel *dch)
HFC_outb(hc, R_TX_FR0, 0x00);
HFC_outb(hc, R_TX_FR1, 0xf8);
- if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg))
+ if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[0]].cfg))
HFC_outb(hc, R_TX_FR2, V_TX_MF | V_TX_E | V_NEG_E);
HFC_outb(hc, R_RX_FR0, V_AUTO_RESYNC | V_AUTO_RECO | 0);
- if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg))
+ if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[0]].cfg))
HFC_outb(hc, R_RX_FR1, V_RX_MF | V_RX_MF_SYNC);
if (dch->dev.D.protocol == ISDN_P_NT_E1) {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: E1 port is NT-mode\n",
- __func__);
+ __func__);
r_e1_wr_sta = 0; /* G0 */
hc->e1_getclock = 0;
} else {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: E1 port is TE-mode\n",
- __func__);
+ __func__);
r_e1_wr_sta = 0; /* F0 */
hc->e1_getclock = 1;
}
@@ -3821,26 +3944,26 @@ hfcmulti_initmode(struct dchannel *dch)
/* SLAVE (clock master) */
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG
- "%s: E1 port is clock master "
- "(clock from PCM)\n", __func__);
+ "%s: E1 port is clock master "
+ "(clock from PCM)\n", __func__);
HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC | V_PCM_SYNC);
} else {
if (hc->e1_getclock) {
/* MASTER (clock slave) */
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG
- "%s: E1 port is clock slave "
- "(clock to PCM)\n", __func__);
+ "%s: E1 port is clock slave "
+ "(clock to PCM)\n", __func__);
HFC_outb(hc, R_SYNC_CTRL, V_SYNC_OFFS);
} else {
/* MASTER (clock master) */
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: E1 port is "
- "clock master "
- "(clock from QUARTZ)\n",
- __func__);
+ "clock master "
+ "(clock from QUARTZ)\n",
+ __func__);
HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC |
- V_PCM_SYNC | V_JATT_OFF);
+ V_PCM_SYNC | V_JATT_OFF);
HFC_outb(hc, R_SYNC_OUT, 0);
}
}
@@ -3856,13 +3979,14 @@ hfcmulti_initmode(struct dchannel *dch)
hc->syncronized = 0;
plxsd_checksync(hc, 0);
}
- } else {
- i = dch->slot;
+ }
+ if (hc->ctype != HFC_TYPE_E1) {
+ /* ST */
hc->chan[i].slot_tx = -1;
hc->chan[i].slot_rx = -1;
hc->chan[i].conf = -1;
mode_hfcmulti(hc, i, dch->dev.D.protocol, -1, 0, -1, 0);
- dch->timer.function = (void *)hfcmulti_dbusy_timer;
+ dch->timer.function = (void *) hfcmulti_dbusy_timer;
dch->timer.data = (long) dch;
init_timer(&dch->timer);
hc->chan[i - 2].slot_tx = -1;
@@ -3873,8 +3997,6 @@ hfcmulti_initmode(struct dchannel *dch)
hc->chan[i - 1].slot_rx = -1;
hc->chan[i - 1].conf = -1;
mode_hfcmulti(hc, i - 1, ISDN_P_NONE, -1, 0, -1, 0);
- /* ST */
- pt = hc->chan[i].port;
/* select interface */
HFC_outb(hc, R_ST_SEL, pt);
/* undocumented: delay after R_ST_SEL */
@@ -3882,8 +4004,8 @@ hfcmulti_initmode(struct dchannel *dch)
if (dch->dev.D.protocol == ISDN_P_NT_S0) {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG
- "%s: ST port %d is NT-mode\n",
- __func__, pt);
+ "%s: ST port %d is NT-mode\n",
+ __func__, pt);
/* clock delay */
HFC_outb(hc, A_ST_CLK_DLY, clockdelay_nt);
a_st_wr_state = 1; /* G1 */
@@ -3891,8 +4013,8 @@ hfcmulti_initmode(struct dchannel *dch)
} else {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG
- "%s: ST port %d is TE-mode\n",
- __func__, pt);
+ "%s: ST port %d is TE-mode\n",
+ __func__, pt);
/* clock delay */
HFC_outb(hc, A_ST_CLK_DLY, clockdelay_te);
a_st_wr_state = 2; /* F2 */
@@ -3900,6 +4022,11 @@ hfcmulti_initmode(struct dchannel *dch)
}
if (!test_bit(HFC_CFG_NONCAP_TX, &hc->chan[i].cfg))
hc->hw.a_st_ctrl0[pt] |= V_TX_LI;
+ if (hc->ctype == HFC_TYPE_XHFC) {
+ hc->hw.a_st_ctrl0[pt] |= 0x40 /* V_ST_PU_CTRL */;
+ HFC_outb(hc, 0x35 /* A_ST_CTRL3 */,
+ 0x7c << 1 /* V_ST_PULSE */);
+ }
/* line setup */
HFC_outb(hc, A_ST_CTRL0, hc->hw.a_st_ctrl0[pt]);
/* disable E-channel */
@@ -3920,7 +4047,7 @@ hfcmulti_initmode(struct dchannel *dch)
/* unset sync on port */
if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
hc->syncronized &=
- ~(1 << hc->chan[dch->slot].port);
+ ~(1 << hc->chan[dch->slot].port);
plxsd_checksync(hc, 0);
}
}
@@ -3931,24 +4058,24 @@ hfcmulti_initmode(struct dchannel *dch)
static int
open_dchannel(struct hfc_multi *hc, struct dchannel *dch,
- struct channel_req *rq)
+ struct channel_req *rq)
{
int err = 0;
u_long flags;
if (debug & DEBUG_HW_OPEN)
printk(KERN_DEBUG "%s: dev(%d) open from %p\n", __func__,
- dch->dev.id, __builtin_return_address(0));
+ dch->dev.id, __builtin_return_address(0));
if (rq->protocol == ISDN_P_NONE)
return -EINVAL;
if ((dch->dev.D.protocol != ISDN_P_NONE) &&
(dch->dev.D.protocol != rq->protocol)) {
- if (debug & DEBUG_HFCMULTI_MODE)
- printk(KERN_WARNING "%s: change protocol %x to %x\n",
- __func__, dch->dev.D.protocol, rq->protocol);
+ if (debug & DEBUG_HFCMULTI_MODE)
+ printk(KERN_DEBUG "%s: change protocol %x to %x\n",
+ __func__, dch->dev.D.protocol, rq->protocol);
}
- if ((dch->dev.D.protocol == ISDN_P_TE_S0)
- && (rq->protocol != ISDN_P_TE_S0))
+ if ((dch->dev.D.protocol == ISDN_P_TE_S0) &&
+ (rq->protocol != ISDN_P_TE_S0))
l1_event(dch->l1, CLOSE_CHANNEL);
if (dch->dev.D.protocol != rq->protocol) {
if (rq->protocol == ISDN_P_TE_S0) {
@@ -3961,14 +4088,9 @@ open_dchannel(struct hfc_multi *hc, struct dchannel *dch,
hfcmulti_initmode(dch);
spin_unlock_irqrestore(&hc->lock, flags);
}
-
- if (((rq->protocol == ISDN_P_NT_S0) && (dch->state == 3)) ||
- ((rq->protocol == ISDN_P_TE_S0) && (dch->state == 7)) ||
- ((rq->protocol == ISDN_P_NT_E1) && (dch->state == 1)) ||
- ((rq->protocol == ISDN_P_TE_E1) && (dch->state == 1))) {
+ if (test_bit(FLG_ACTIVE, &dch->Flags))
_queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY,
- 0, NULL, GFP_KERNEL);
- }
+ 0, NULL, GFP_KERNEL);
rq->ch = &dch->dev.D;
if (!try_module_get(THIS_MODULE))
printk(KERN_WARNING "%s:cannot get module\n", __func__);
@@ -3977,7 +4099,7 @@ open_dchannel(struct hfc_multi *hc, struct dchannel *dch,
static int
open_bchannel(struct hfc_multi *hc, struct dchannel *dch,
- struct channel_req *rq)
+ struct channel_req *rq)
{
struct bchannel *bch;
int ch;
@@ -3986,19 +4108,18 @@ open_bchannel(struct hfc_multi *hc, struct dchannel *dch,
return -EINVAL;
if (rq->protocol == ISDN_P_NONE)
return -EINVAL;
- if (hc->type == 1)
+ if (hc->ctype == HFC_TYPE_E1)
ch = rq->adr.channel;
else
ch = (rq->adr.channel - 1) + (dch->slot - 2);
bch = hc->chan[ch].bch;
if (!bch) {
printk(KERN_ERR "%s:internal error ch %d has no bch\n",
- __func__, ch);
+ __func__, ch);
return -EINVAL;
}
if (test_and_set_bit(FLG_OPEN, &bch->Flags))
return -EBUSY; /* b-channel can be only open once */
- test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
bch->ch.protocol = rq->protocol;
hc->chan[ch].rx_off = 0;
rq->ch = &bch->ch;
@@ -4013,15 +4134,48 @@ open_bchannel(struct hfc_multi *hc, struct dchannel *dch,
static int
channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq)
{
+ struct hfc_multi *hc = dch->hw;
int ret = 0;
+ int wd_mode, wd_cnt;
switch (cq->op) {
case MISDN_CTRL_GETOP:
- cq->op = 0;
+ cq->op = MISDN_CTRL_HFC_OP | MISDN_CTRL_L1_TIMER3;
+ break;
+ case MISDN_CTRL_HFC_WD_INIT: /* init the watchdog */
+ wd_cnt = cq->p1 & 0xf;
+ wd_mode = !!(cq->p1 >> 4);
+ if (debug & DEBUG_HFCMULTI_MSG)
+ printk(KERN_DEBUG "%s: MISDN_CTRL_HFC_WD_INIT mode %s"
+ ", counter 0x%x\n", __func__,
+ wd_mode ? "AUTO" : "MANUAL", wd_cnt);
+ /* set the watchdog timer */
+ HFC_outb(hc, R_TI_WD, poll_timer | (wd_cnt << 4));
+ hc->hw.r_bert_wd_md = (wd_mode ? V_AUTO_WD_RES : 0);
+ if (hc->ctype == HFC_TYPE_XHFC)
+ hc->hw.r_bert_wd_md |= 0x40 /* V_WD_EN */;
+ /* init the watchdog register and reset the counter */
+ HFC_outb(hc, R_BERT_WD_MD, hc->hw.r_bert_wd_md | V_WD_RES);
+ if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
+ /* enable the watchdog output for Speech-Design */
+ HFC_outb(hc, R_GPIO_SEL, V_GPIO_SEL7);
+ HFC_outb(hc, R_GPIO_EN1, V_GPIO_EN15);
+ HFC_outb(hc, R_GPIO_OUT1, 0);
+ HFC_outb(hc, R_GPIO_OUT1, V_GPIO_OUT15);
+ }
+ break;
+ case MISDN_CTRL_HFC_WD_RESET: /* reset the watchdog counter */
+ if (debug & DEBUG_HFCMULTI_MSG)
+ printk(KERN_DEBUG "%s: MISDN_CTRL_HFC_WD_RESET\n",
+ __func__);
+ HFC_outb(hc, R_BERT_WD_MD, hc->hw.r_bert_wd_md | V_WD_RES);
+ break;
+ case MISDN_CTRL_L1_TIMER3:
+ ret = l1_event(dch->l1, HW_TIMER3_VALUE | (cq->p1 & 0xff));
break;
default:
printk(KERN_WARNING "%s: unknown Op %x\n",
- __func__, cq->op);
+ __func__, cq->op);
ret = -EINVAL;
break;
}
@@ -4040,14 +4194,14 @@ hfcm_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
if (dch->debug & DEBUG_HW)
printk(KERN_DEBUG "%s: cmd:%x %p\n",
- __func__, cmd, arg);
+ __func__, cmd, arg);
switch (cmd) {
case OPEN_CHANNEL:
rq = arg;
switch (rq->protocol) {
case ISDN_P_TE_S0:
case ISDN_P_NT_S0:
- if (hc->type == 1) {
+ if (hc->ctype == HFC_TYPE_E1) {
err = -EINVAL;
break;
}
@@ -4055,7 +4209,7 @@ hfcm_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
break;
case ISDN_P_TE_E1:
case ISDN_P_NT_E1:
- if (hc->type != 1) {
+ if (hc->ctype != HFC_TYPE_E1) {
err = -EINVAL;
break;
}
@@ -4070,8 +4224,8 @@ hfcm_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
case CLOSE_CHANNEL:
if (debug & DEBUG_HW_OPEN)
printk(KERN_DEBUG "%s: dev(%d) close from %p\n",
- __func__, dch->dev.id,
- __builtin_return_address(0));
+ __func__, dch->dev.id,
+ __builtin_return_address(0));
module_put(THIS_MODULE);
break;
case CONTROL_CHANNEL:
@@ -4082,7 +4236,7 @@ hfcm_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
default:
if (dch->debug & DEBUG_HW)
printk(KERN_DEBUG "%s: unknown command %x\n",
- __func__, cmd);
+ __func__, cmd);
err = -EINVAL;
}
return err;
@@ -4122,31 +4276,31 @@ init_card(struct hfc_multi *hc)
disable_hwirq(hc);
spin_unlock_irqrestore(&hc->lock, flags);
- if (request_irq(hc->pci_dev->irq, hfcmulti_interrupt, IRQF_SHARED,
- "HFC-multi", hc)) {
+ if (request_irq(hc->irq, hfcmulti_interrupt, IRQF_SHARED,
+ "HFC-multi", hc)) {
printk(KERN_WARNING "mISDN: Could not get interrupt %d.\n",
- hc->pci_dev->irq);
+ hc->irq);
+ hc->irq = 0;
return -EIO;
}
- hc->irq = hc->pci_dev->irq;
if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
spin_lock_irqsave(&plx_lock, plx_flags);
plx_acc = hc->plx_membase + PLX_INTCSR;
writew((PLX_INTCSR_PCIINT_ENABLE | PLX_INTCSR_LINTI1_ENABLE),
- plx_acc); /* enable PCI & LINT1 irq */
+ plx_acc); /* enable PCI & LINT1 irq */
spin_unlock_irqrestore(&plx_lock, plx_flags);
}
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: IRQ %d count %d\n",
- __func__, hc->irq, hc->irqcnt);
+ __func__, hc->irq, hc->irqcnt);
err = init_chip(hc);
if (err)
goto error;
/*
* Finally enable IRQ output
- * this is only allowed, if an IRQ routine is allready
+ * this is only allowed, if an IRQ routine is already
* established for this HFC, so don't do that earlier
*/
spin_lock_irqsave(&hc->lock, flags);
@@ -4154,14 +4308,14 @@ init_card(struct hfc_multi *hc)
spin_unlock_irqrestore(&hc->lock, flags);
/* printk(KERN_DEBUG "no master irq set!!!\n"); */
set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout((100*HZ)/1000); /* Timeout 100ms */
+ schedule_timeout((100 * HZ) / 1000); /* Timeout 100ms */
/* turn IRQ off until chip is completely initialized */
spin_lock_irqsave(&hc->lock, flags);
disable_hwirq(hc);
spin_unlock_irqrestore(&hc->lock, flags);
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: IRQ %d count %d\n",
- __func__, hc->irq, hc->irqcnt);
+ __func__, hc->irq, hc->irqcnt);
if (hc->irqcnt) {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: done\n", __func__);
@@ -4174,7 +4328,7 @@ init_card(struct hfc_multi *hc)
}
printk(KERN_ERR "HFC PCI: IRQ(%d) getting no interrupts during init.\n",
- hc->irq);
+ hc->irq);
err = -EIO;
@@ -4187,7 +4341,7 @@ error:
}
if (debug & DEBUG_HFCMULTI_INIT)
- printk(KERN_WARNING "%s: free irq %d\n", __func__, hc->irq);
+ printk(KERN_DEBUG "%s: free irq %d\n", __func__, hc->irq);
if (hc->irq) {
free_irq(hc->irq, hc);
hc->irq = 0;
@@ -4204,13 +4358,13 @@ error:
static int
setup_pci(struct hfc_multi *hc, struct pci_dev *pdev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *ent)
{
struct hm_map *m = (struct hm_map *)ent->driver_data;
printk(KERN_INFO
- "HFC-multi: card manufacturer: '%s' card name: '%s' clock: %s\n",
- m->vendor_name, m->card_name, m->clock2 ? "double" : "normal");
+ "HFC-multi: card manufacturer: '%s' card name: '%s' clock: %s\n",
+ m->vendor_name, m->card_name, m->clock2 ? "double" : "normal");
hc->pci_dev = pdev;
if (m->clock2)
@@ -4235,6 +4389,10 @@ setup_pci(struct hfc_multi *hc, struct pci_dev *pdev,
hc->ledstate = 0xAFFEAFFE;
hc->opticalsupport = m->opticalsupport;
+ hc->pci_iobase = 0;
+ hc->pci_membase = NULL;
+ hc->plx_membase = NULL;
+
/* set memory access methods */
if (m->io_mode) /* use mode from card config */
hc->io_mode = m->io_mode;
@@ -4242,50 +4400,18 @@ setup_pci(struct hfc_multi *hc, struct pci_dev *pdev,
case HFC_IO_MODE_PLXSD:
test_and_set_bit(HFC_CHIP_PLXSD, &hc->chip);
hc->slots = 128; /* required */
- /* fall through */
- case HFC_IO_MODE_PCIMEM:
hc->HFC_outb = HFC_outb_pcimem;
hc->HFC_inb = HFC_inb_pcimem;
hc->HFC_inw = HFC_inw_pcimem;
hc->HFC_wait = HFC_wait_pcimem;
hc->read_fifo = read_fifo_pcimem;
hc->write_fifo = write_fifo_pcimem;
- break;
- case HFC_IO_MODE_REGIO:
- hc->HFC_outb = HFC_outb_regio;
- hc->HFC_inb = HFC_inb_regio;
- hc->HFC_inw = HFC_inw_regio;
- hc->HFC_wait = HFC_wait_regio;
- hc->read_fifo = read_fifo_regio;
- hc->write_fifo = write_fifo_regio;
- break;
- default:
- printk(KERN_WARNING "HFC-multi: Invalid IO mode.\n");
- pci_disable_device(hc->pci_dev);
- return -EIO;
- }
- hc->HFC_outb_nodebug = hc->HFC_outb;
- hc->HFC_inb_nodebug = hc->HFC_inb;
- hc->HFC_inw_nodebug = hc->HFC_inw;
- hc->HFC_wait_nodebug = hc->HFC_wait;
-#ifdef HFC_REGISTER_DEBUG
- hc->HFC_outb = HFC_outb_debug;
- hc->HFC_inb = HFC_inb_debug;
- hc->HFC_inw = HFC_inw_debug;
- hc->HFC_wait = HFC_wait_debug;
-#endif
- hc->pci_iobase = 0;
- hc->pci_membase = NULL;
- hc->plx_membase = NULL;
-
- switch (hc->io_mode) {
- case HFC_IO_MODE_PLXSD:
hc->plx_origmembase = hc->pci_dev->resource[0].start;
/* MEMBASE 1 is PLX PCI Bridge */
if (!hc->plx_origmembase) {
printk(KERN_WARNING
- "HFC-multi: No IO-Memory for PCI PLX bridge found\n");
+ "HFC-multi: No IO-Memory for PCI PLX bridge found\n");
pci_disable_device(hc->pci_dev);
return -EIO;
}
@@ -4293,20 +4419,20 @@ setup_pci(struct hfc_multi *hc, struct pci_dev *pdev,
hc->plx_membase = ioremap(hc->plx_origmembase, 0x80);
if (!hc->plx_membase) {
printk(KERN_WARNING
- "HFC-multi: failed to remap plx address space. "
- "(internal error)\n");
+ "HFC-multi: failed to remap plx address space. "
+ "(internal error)\n");
pci_disable_device(hc->pci_dev);
return -EIO;
}
printk(KERN_INFO
- "HFC-multi: plx_membase:%#lx plx_origmembase:%#lx\n",
- (u_long)hc->plx_membase, hc->plx_origmembase);
+ "HFC-multi: plx_membase:%#lx plx_origmembase:%#lx\n",
+ (u_long)hc->plx_membase, hc->plx_origmembase);
hc->pci_origmembase = hc->pci_dev->resource[2].start;
- /* MEMBASE 1 is PLX PCI Bridge */
+ /* MEMBASE 1 is PLX PCI Bridge */
if (!hc->pci_origmembase) {
printk(KERN_WARNING
- "HFC-multi: No IO-Memory for PCI card found\n");
+ "HFC-multi: No IO-Memory for PCI card found\n");
pci_disable_device(hc->pci_dev);
return -EIO;
}
@@ -4314,23 +4440,29 @@ setup_pci(struct hfc_multi *hc, struct pci_dev *pdev,
hc->pci_membase = ioremap(hc->pci_origmembase, 0x400);
if (!hc->pci_membase) {
printk(KERN_WARNING "HFC-multi: failed to remap io "
- "address space. (internal error)\n");
+ "address space. (internal error)\n");
pci_disable_device(hc->pci_dev);
return -EIO;
}
printk(KERN_INFO
- "card %d: defined at MEMBASE %#lx (%#lx) IRQ %d HZ %d "
- "leds-type %d\n",
- hc->id, (u_long)hc->pci_membase, hc->pci_origmembase,
- hc->pci_dev->irq, HZ, hc->leds);
+ "card %d: defined at MEMBASE %#lx (%#lx) IRQ %d HZ %d "
+ "leds-type %d\n",
+ hc->id, (u_long)hc->pci_membase, hc->pci_origmembase,
+ hc->pci_dev->irq, HZ, hc->leds);
pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO);
break;
case HFC_IO_MODE_PCIMEM:
+ hc->HFC_outb = HFC_outb_pcimem;
+ hc->HFC_inb = HFC_inb_pcimem;
+ hc->HFC_inw = HFC_inw_pcimem;
+ hc->HFC_wait = HFC_wait_pcimem;
+ hc->read_fifo = read_fifo_pcimem;
+ hc->write_fifo = write_fifo_pcimem;
hc->pci_origmembase = hc->pci_dev->resource[1].start;
if (!hc->pci_origmembase) {
printk(KERN_WARNING
- "HFC-multi: No IO-Memory for PCI card found\n");
+ "HFC-multi: No IO-Memory for PCI card found\n");
pci_disable_device(hc->pci_dev);
return -EIO;
}
@@ -4338,37 +4470,43 @@ setup_pci(struct hfc_multi *hc, struct pci_dev *pdev,
hc->pci_membase = ioremap(hc->pci_origmembase, 256);
if (!hc->pci_membase) {
printk(KERN_WARNING
- "HFC-multi: failed to remap io address space. "
- "(internal error)\n");
+ "HFC-multi: failed to remap io address space. "
+ "(internal error)\n");
pci_disable_device(hc->pci_dev);
return -EIO;
}
- printk(KERN_INFO "card %d: defined at MEMBASE %#lx (%#lx) IRQ %d "
- "HZ %d leds-type %d\n", hc->id, (u_long)hc->pci_membase,
- hc->pci_origmembase, hc->pci_dev->irq, HZ, hc->leds);
+ printk(KERN_INFO "card %d: defined at MEMBASE %#lx (%#lx) IRQ "
+ "%d HZ %d leds-type %d\n", hc->id, (u_long)hc->pci_membase,
+ hc->pci_origmembase, hc->pci_dev->irq, HZ, hc->leds);
pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO);
break;
case HFC_IO_MODE_REGIO:
+ hc->HFC_outb = HFC_outb_regio;
+ hc->HFC_inb = HFC_inb_regio;
+ hc->HFC_inw = HFC_inw_regio;
+ hc->HFC_wait = HFC_wait_regio;
+ hc->read_fifo = read_fifo_regio;
+ hc->write_fifo = write_fifo_regio;
hc->pci_iobase = (u_int) hc->pci_dev->resource[0].start;
if (!hc->pci_iobase) {
printk(KERN_WARNING
- "HFC-multi: No IO for PCI card found\n");
+ "HFC-multi: No IO for PCI card found\n");
pci_disable_device(hc->pci_dev);
return -EIO;
}
if (!request_region(hc->pci_iobase, 8, "hfcmulti")) {
printk(KERN_WARNING "HFC-multi: failed to request "
- "address space at 0x%08lx (internal error)\n",
- hc->pci_iobase);
+ "address space at 0x%08lx (internal error)\n",
+ hc->pci_iobase);
pci_disable_device(hc->pci_dev);
return -EIO;
}
printk(KERN_INFO
- "%s %s: defined at IOBASE %#x IRQ %d HZ %d leds-type %d\n",
- m->vendor_name, m->card_name, (u_int) hc->pci_iobase,
- hc->pci_dev->irq, HZ, hc->leds);
+ "%s %s: defined at IOBASE %#x IRQ %d HZ %d leds-type %d\n",
+ m->vendor_name, m->card_name, (u_int) hc->pci_iobase,
+ hc->pci_dev->irq, HZ, hc->leds);
pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_REGIO);
break;
default:
@@ -4401,17 +4539,17 @@ release_port(struct hfc_multi *hc, struct dchannel *dch)
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: entered for port %d\n",
- __func__, pt + 1);
+ __func__, pt + 1);
if (pt >= hc->ports) {
printk(KERN_WARNING "%s: ERROR port out of range (%d).\n",
- __func__, pt + 1);
+ __func__, pt + 1);
return;
}
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: releasing port=%d\n",
- __func__, pt + 1);
+ __func__, pt + 1);
if (dch->dev.D.protocol == ISDN_P_TE_S0)
l1_event(dch->l1, CLOSE_CHANNEL);
@@ -4430,7 +4568,7 @@ release_port(struct hfc_multi *hc, struct dchannel *dch)
dch->timer.function = NULL;
}
- if (hc->type == 1) { /* E1 */
+ if (hc->ctype == HFC_TYPE_E1) { /* E1 */
/* remove sync */
if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
hc->syncronized = 0;
@@ -4438,11 +4576,13 @@ release_port(struct hfc_multi *hc, struct dchannel *dch)
}
/* free channels */
for (i = 0; i <= 31; i++) {
+ if (!((1 << i) & hc->bmask[pt])) /* skip unused chan */
+ continue;
if (hc->chan[i].bch) {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG
- "%s: free port %d channel %d\n",
- __func__, hc->chan[i].port+1, i);
+ "%s: free port %d channel %d\n",
+ __func__, hc->chan[i].port + 1, i);
pb = hc->chan[i].bch;
hc->chan[i].bch = NULL;
spin_unlock_irqrestore(&hc->lock, flags);
@@ -4456,16 +4596,16 @@ release_port(struct hfc_multi *hc, struct dchannel *dch)
/* remove sync */
if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
hc->syncronized &=
- ~(1 << hc->chan[ci].port);
+ ~(1 << hc->chan[ci].port);
plxsd_checksync(hc, 1);
}
/* free channels */
if (hc->chan[ci - 2].bch) {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG
- "%s: free port %d channel %d\n",
- __func__, hc->chan[ci - 2].port+1,
- ci - 2);
+ "%s: free port %d channel %d\n",
+ __func__, hc->chan[ci - 2].port + 1,
+ ci - 2);
pb = hc->chan[ci - 2].bch;
hc->chan[ci - 2].bch = NULL;
spin_unlock_irqrestore(&hc->lock, flags);
@@ -4477,9 +4617,9 @@ release_port(struct hfc_multi *hc, struct dchannel *dch)
if (hc->chan[ci - 1].bch) {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG
- "%s: free port %d channel %d\n",
- __func__, hc->chan[ci - 1].port+1,
- ci - 1);
+ "%s: free port %d channel %d\n",
+ __func__, hc->chan[ci - 1].port + 1,
+ ci - 1);
pb = hc->chan[ci - 1].bch;
hc->chan[ci - 1].bch = NULL;
spin_unlock_irqrestore(&hc->lock, flags);
@@ -4493,7 +4633,8 @@ release_port(struct hfc_multi *hc, struct dchannel *dch)
spin_unlock_irqrestore(&hc->lock, flags);
if (debug & DEBUG_HFCMULTI_INIT)
- printk(KERN_DEBUG "%s: free port %d channel D\n", __func__, pt);
+ printk(KERN_DEBUG "%s: free port %d channel D(%d)\n", __func__,
+ pt+1, ci);
mISDN_freedchannel(dch);
kfree(dch);
@@ -4508,222 +4649,235 @@ release_card(struct hfc_multi *hc)
int ch;
if (debug & DEBUG_HFCMULTI_INIT)
- printk(KERN_WARNING "%s: release card (%d) entered\n",
- __func__, hc->id);
+ printk(KERN_DEBUG "%s: release card (%d) entered\n",
+ __func__, hc->id);
/* unregister clock source */
if (hc->iclock)
mISDN_unregister_clock(hc->iclock);
- /* disable irq */
+ /* disable and free irq */
spin_lock_irqsave(&hc->lock, flags);
disable_hwirq(hc);
spin_unlock_irqrestore(&hc->lock, flags);
udelay(1000);
+ if (hc->irq) {
+ if (debug & DEBUG_HFCMULTI_INIT)
+ printk(KERN_DEBUG "%s: free irq %d (hc=%p)\n",
+ __func__, hc->irq, hc);
+ free_irq(hc->irq, hc);
+ hc->irq = 0;
- /* dimm leds */
- if (hc->leds)
- hfcmulti_leds(hc);
+ }
/* disable D-channels & B-channels */
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: disable all channels (d and b)\n",
- __func__);
+ __func__);
for (ch = 0; ch <= 31; ch++) {
if (hc->chan[ch].dch)
release_port(hc, hc->chan[ch].dch);
}
- /* release hardware & irq */
- if (hc->irq) {
- if (debug & DEBUG_HFCMULTI_INIT)
- printk(KERN_WARNING "%s: free irq %d\n",
- __func__, hc->irq);
- free_irq(hc->irq, hc);
- hc->irq = 0;
+ /* dimm leds */
+ if (hc->leds)
+ hfcmulti_leds(hc);
- }
+ /* release hardware */
release_io_hfcmulti(hc);
if (debug & DEBUG_HFCMULTI_INIT)
- printk(KERN_WARNING "%s: remove instance from list\n",
- __func__);
+ printk(KERN_DEBUG "%s: remove instance from list\n",
+ __func__);
list_del(&hc->list);
if (debug & DEBUG_HFCMULTI_INIT)
- printk(KERN_WARNING "%s: delete instance\n", __func__);
+ printk(KERN_DEBUG "%s: delete instance\n", __func__);
if (hc == syncmaster)
syncmaster = NULL;
kfree(hc);
if (debug & DEBUG_HFCMULTI_INIT)
- printk(KERN_WARNING "%s: card successfully removed\n",
- __func__);
+ printk(KERN_DEBUG "%s: card successfully removed\n",
+ __func__);
}
-static int
-init_e1_port(struct hfc_multi *hc, struct hm_map *m)
+static void
+init_e1_port_hw(struct hfc_multi *hc, struct hm_map *m)
{
- struct dchannel *dch;
- struct bchannel *bch;
- int ch, ret = 0;
- char name[MISDN_MAX_IDLEN];
-
- dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL);
- if (!dch)
- return -ENOMEM;
- dch->debug = debug;
- mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, ph_state_change);
- dch->hw = hc;
- dch->dev.Dprotocols = (1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1);
- dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
- (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
- dch->dev.D.send = handle_dmsg;
- dch->dev.D.ctrl = hfcm_dctrl;
- dch->dev.nrbchan = (hc->dslot)?30:31;
- dch->slot = hc->dslot;
- hc->chan[hc->dslot].dch = dch;
- hc->chan[hc->dslot].port = 0;
- hc->chan[hc->dslot].nt_timer = -1;
- for (ch = 1; ch <= 31; ch++) {
- if (ch == hc->dslot) /* skip dchannel */
- continue;
- bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL);
- if (!bch) {
- printk(KERN_ERR "%s: no memory for bchannel\n",
- __func__);
- ret = -ENOMEM;
- goto free_chan;
- }
- hc->chan[ch].coeff = kzalloc(512, GFP_KERNEL);
- if (!hc->chan[ch].coeff) {
- printk(KERN_ERR "%s: no memory for coeffs\n",
- __func__);
- ret = -ENOMEM;
- kfree(bch);
- goto free_chan;
- }
- bch->nr = ch;
- bch->slot = ch;
- bch->debug = debug;
- mISDN_initbchannel(bch, MAX_DATA_MEM);
- bch->hw = hc;
- bch->ch.send = handle_bmsg;
- bch->ch.ctrl = hfcm_bctrl;
- bch->ch.nr = ch;
- list_add(&bch->ch.list, &dch->dev.bchannels);
- hc->chan[ch].bch = bch;
- hc->chan[ch].port = 0;
- set_channelmap(bch->nr, dch->dev.channelmap);
- }
/* set optical line type */
if (port[Port_cnt] & 0x001) {
if (!m->opticalsupport) {
printk(KERN_INFO
- "This board has no optical "
- "support\n");
+ "This board has no optical "
+ "support\n");
} else {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG
- "%s: PORT set optical "
- "interfacs: card(%d) "
- "port(%d)\n",
- __func__,
- HFC_cnt + 1, 1);
+ "%s: PORT set optical "
+ "interfacs: card(%d) "
+ "port(%d)\n",
+ __func__,
+ HFC_cnt + 1, 1);
test_and_set_bit(HFC_CFG_OPTICAL,
- &hc->chan[hc->dslot].cfg);
+ &hc->chan[hc->dnum[0]].cfg);
}
}
/* set LOS report */
if (port[Port_cnt] & 0x004) {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: PORT set "
- "LOS report: card(%d) port(%d)\n",
- __func__, HFC_cnt + 1, 1);
+ "LOS report: card(%d) port(%d)\n",
+ __func__, HFC_cnt + 1, 1);
test_and_set_bit(HFC_CFG_REPORT_LOS,
- &hc->chan[hc->dslot].cfg);
+ &hc->chan[hc->dnum[0]].cfg);
}
/* set AIS report */
if (port[Port_cnt] & 0x008) {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: PORT set "
- "AIS report: card(%d) port(%d)\n",
- __func__, HFC_cnt + 1, 1);
+ "AIS report: card(%d) port(%d)\n",
+ __func__, HFC_cnt + 1, 1);
test_and_set_bit(HFC_CFG_REPORT_AIS,
- &hc->chan[hc->dslot].cfg);
+ &hc->chan[hc->dnum[0]].cfg);
}
/* set SLIP report */
if (port[Port_cnt] & 0x010) {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG
- "%s: PORT set SLIP report: "
- "card(%d) port(%d)\n",
- __func__, HFC_cnt + 1, 1);
+ "%s: PORT set SLIP report: "
+ "card(%d) port(%d)\n",
+ __func__, HFC_cnt + 1, 1);
test_and_set_bit(HFC_CFG_REPORT_SLIP,
- &hc->chan[hc->dslot].cfg);
+ &hc->chan[hc->dnum[0]].cfg);
}
/* set RDI report */
if (port[Port_cnt] & 0x020) {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG
- "%s: PORT set RDI report: "
- "card(%d) port(%d)\n",
- __func__, HFC_cnt + 1, 1);
+ "%s: PORT set RDI report: "
+ "card(%d) port(%d)\n",
+ __func__, HFC_cnt + 1, 1);
test_and_set_bit(HFC_CFG_REPORT_RDI,
- &hc->chan[hc->dslot].cfg);
+ &hc->chan[hc->dnum[0]].cfg);
}
/* set CRC-4 Mode */
if (!(port[Port_cnt] & 0x100)) {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: PORT turn on CRC4 report:"
- " card(%d) port(%d)\n",
- __func__, HFC_cnt + 1, 1);
+ " card(%d) port(%d)\n",
+ __func__, HFC_cnt + 1, 1);
test_and_set_bit(HFC_CFG_CRC4,
- &hc->chan[hc->dslot].cfg);
+ &hc->chan[hc->dnum[0]].cfg);
} else {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: PORT turn off CRC4"
- " report: card(%d) port(%d)\n",
- __func__, HFC_cnt + 1, 1);
+ " report: card(%d) port(%d)\n",
+ __func__, HFC_cnt + 1, 1);
}
/* set forced clock */
if (port[Port_cnt] & 0x0200) {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: PORT force getting clock from "
- "E1: card(%d) port(%d)\n",
- __func__, HFC_cnt + 1, 1);
+ "E1: card(%d) port(%d)\n",
+ __func__, HFC_cnt + 1, 1);
test_and_set_bit(HFC_CHIP_E1CLOCK_GET, &hc->chip);
} else
- if (port[Port_cnt] & 0x0400) {
- if (debug & DEBUG_HFCMULTI_INIT)
- printk(KERN_DEBUG "%s: PORT force putting clock to "
- "E1: card(%d) port(%d)\n",
- __func__, HFC_cnt + 1, 1);
- test_and_set_bit(HFC_CHIP_E1CLOCK_PUT, &hc->chip);
- }
+ if (port[Port_cnt] & 0x0400) {
+ if (debug & DEBUG_HFCMULTI_INIT)
+ printk(KERN_DEBUG "%s: PORT force putting clock to "
+ "E1: card(%d) port(%d)\n",
+ __func__, HFC_cnt + 1, 1);
+ test_and_set_bit(HFC_CHIP_E1CLOCK_PUT, &hc->chip);
+ }
/* set JATT PLL */
if (port[Port_cnt] & 0x0800) {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: PORT disable JATT PLL on "
- "E1: card(%d) port(%d)\n",
- __func__, HFC_cnt + 1, 1);
+ "E1: card(%d) port(%d)\n",
+ __func__, HFC_cnt + 1, 1);
test_and_set_bit(HFC_CHIP_RX_SYNC, &hc->chip);
}
/* set elastic jitter buffer */
if (port[Port_cnt] & 0x3000) {
- hc->chan[hc->dslot].jitter = (port[Port_cnt]>>12) & 0x3;
+ hc->chan[hc->dnum[0]].jitter = (port[Port_cnt]>>12) & 0x3;
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG
- "%s: PORT set elastic "
- "buffer to %d: card(%d) port(%d)\n",
- __func__, hc->chan[hc->dslot].jitter,
- HFC_cnt + 1, 1);
+ "%s: PORT set elastic "
+ "buffer to %d: card(%d) port(%d)\n",
+ __func__, hc->chan[hc->dnum[0]].jitter,
+ HFC_cnt + 1, 1);
} else
- hc->chan[hc->dslot].jitter = 2; /* default */
- snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1);
+ hc->chan[hc->dnum[0]].jitter = 2; /* default */
+}
+
+static int
+init_e1_port(struct hfc_multi *hc, struct hm_map *m, int pt)
+{
+ struct dchannel *dch;
+ struct bchannel *bch;
+ int ch, ret = 0;
+ char name[MISDN_MAX_IDLEN];
+ int bcount = 0;
+
+ dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL);
+ if (!dch)
+ return -ENOMEM;
+ dch->debug = debug;
+ mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, ph_state_change);
+ dch->hw = hc;
+ dch->dev.Dprotocols = (1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1);
+ dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
+ (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
+ dch->dev.D.send = handle_dmsg;
+ dch->dev.D.ctrl = hfcm_dctrl;
+ dch->slot = hc->dnum[pt];
+ hc->chan[hc->dnum[pt]].dch = dch;
+ hc->chan[hc->dnum[pt]].port = pt;
+ hc->chan[hc->dnum[pt]].nt_timer = -1;
+ for (ch = 1; ch <= 31; ch++) {
+ if (!((1 << ch) & hc->bmask[pt])) /* skip unused channel */
+ continue;
+ bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL);
+ if (!bch) {
+ printk(KERN_ERR "%s: no memory for bchannel\n",
+ __func__);
+ ret = -ENOMEM;
+ goto free_chan;
+ }
+ hc->chan[ch].coeff = kzalloc(512, GFP_KERNEL);
+ if (!hc->chan[ch].coeff) {
+ printk(KERN_ERR "%s: no memory for coeffs\n",
+ __func__);
+ ret = -ENOMEM;
+ kfree(bch);
+ goto free_chan;
+ }
+ bch->nr = ch;
+ bch->slot = ch;
+ bch->debug = debug;
+ mISDN_initbchannel(bch, MAX_DATA_MEM, poll >> 1);
+ bch->hw = hc;
+ bch->ch.send = handle_bmsg;
+ bch->ch.ctrl = hfcm_bctrl;
+ bch->ch.nr = ch;
+ list_add(&bch->ch.list, &dch->dev.bchannels);
+ hc->chan[ch].bch = bch;
+ hc->chan[ch].port = pt;
+ set_channelmap(bch->nr, dch->dev.channelmap);
+ bcount++;
+ }
+ dch->dev.nrbchan = bcount;
+ if (pt == 0)
+ init_e1_port_hw(hc, m);
+ if (hc->ports > 1)
+ snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d-%d",
+ HFC_cnt + 1, pt+1);
+ else
+ snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1);
ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name);
if (ret)
goto free_chan;
- hc->created[0] = 1;
+ hc->created[pt] = 1;
return ret;
free_chan:
release_port(hc, dch);
@@ -4746,7 +4900,7 @@ init_multi_port(struct hfc_multi *hc, int pt)
dch->hw = hc;
dch->dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0);
dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
- (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
+ (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
dch->dev.D.send = handle_dmsg;
dch->dev.D.ctrl = hfcm_dctrl;
dch->dev.nrbchan = 2;
@@ -4759,14 +4913,14 @@ init_multi_port(struct hfc_multi *hc, int pt)
bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL);
if (!bch) {
printk(KERN_ERR "%s: no memory for bchannel\n",
- __func__);
+ __func__);
ret = -ENOMEM;
goto free_chan;
}
hc->chan[i + ch].coeff = kzalloc(512, GFP_KERNEL);
if (!hc->chan[i + ch].coeff) {
printk(KERN_ERR "%s: no memory for coeffs\n",
- __func__);
+ __func__);
ret = -ENOMEM;
kfree(bch);
goto free_chan;
@@ -4774,7 +4928,7 @@ init_multi_port(struct hfc_multi *hc, int pt)
bch->nr = ch + 1;
bch->slot = i + ch;
bch->debug = debug;
- mISDN_initbchannel(bch, MAX_DATA_MEM);
+ mISDN_initbchannel(bch, MAX_DATA_MEM, poll >> 1);
bch->hw = hc;
bch->ch.send = handle_bmsg;
bch->ch.ctrl = hfcm_bctrl;
@@ -4788,22 +4942,22 @@ init_multi_port(struct hfc_multi *hc, int pt)
if (port[Port_cnt] & 0x001) {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG
- "%s: PROTOCOL set master clock: "
- "card(%d) port(%d)\n",
- __func__, HFC_cnt + 1, pt + 1);
+ "%s: PROTOCOL set master clock: "
+ "card(%d) port(%d)\n",
+ __func__, HFC_cnt + 1, pt + 1);
if (dch->dev.D.protocol != ISDN_P_TE_S0) {
printk(KERN_ERR "Error: Master clock "
- "for port(%d) of card(%d) is only"
- " possible with TE-mode\n",
- pt + 1, HFC_cnt + 1);
+ "for port(%d) of card(%d) is only"
+ " possible with TE-mode\n",
+ pt + 1, HFC_cnt + 1);
ret = -EINVAL;
goto free_chan;
}
if (hc->masterclk >= 0) {
printk(KERN_ERR "Error: Master clock "
- "for port(%d) of card(%d) already "
- "defined for port(%d)\n",
- pt + 1, HFC_cnt + 1, hc->masterclk+1);
+ "for port(%d) of card(%d) already "
+ "defined for port(%d)\n",
+ pt + 1, HFC_cnt + 1, hc->masterclk + 1);
ret = -EINVAL;
goto free_chan;
}
@@ -4813,25 +4967,31 @@ init_multi_port(struct hfc_multi *hc, int pt)
if (port[Port_cnt] & 0x002) {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG
- "%s: PROTOCOL set non capacitive "
- "transmitter: card(%d) port(%d)\n",
- __func__, HFC_cnt + 1, pt + 1);
+ "%s: PROTOCOL set non capacitive "
+ "transmitter: card(%d) port(%d)\n",
+ __func__, HFC_cnt + 1, pt + 1);
test_and_set_bit(HFC_CFG_NONCAP_TX,
- &hc->chan[i + 2].cfg);
+ &hc->chan[i + 2].cfg);
}
/* disable E-channel */
if (port[Port_cnt] & 0x004) {
- if (debug & DEBUG_HFCMULTI_INIT)
+ if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG
- "%s: PROTOCOL disable E-channel: "
- "card(%d) port(%d)\n",
- __func__, HFC_cnt + 1, pt + 1);
+ "%s: PROTOCOL disable E-channel: "
+ "card(%d) port(%d)\n",
+ __func__, HFC_cnt + 1, pt + 1);
test_and_set_bit(HFC_CFG_DIS_ECHANNEL,
- &hc->chan[i + 2].cfg);
+ &hc->chan[i + 2].cfg);
+ }
+ if (hc->ctype == HFC_TYPE_XHFC) {
+ snprintf(name, MISDN_MAX_IDLEN - 1, "xhfc.%d-%d",
+ HFC_cnt + 1, pt + 1);
+ ret = mISDN_register_device(&dch->dev, NULL, name);
+ } else {
+ snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-%ds.%d-%d",
+ hc->ctype, HFC_cnt + 1, pt + 1);
+ ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name);
}
- snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-%ds.%d-%d",
- hc->type, HFC_cnt + 1, pt + 1);
- ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name);
if (ret)
goto free_chan;
hc->created[pt] = 1;
@@ -4842,34 +5002,35 @@ free_chan:
}
static int
-hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
+hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
- struct hm_map *m = (struct hm_map *)ent->driver_data;
int ret_err = 0;
int pt;
struct hfc_multi *hc;
u_long flags;
u_char dips = 0, pmj = 0; /* dip settings, port mode Jumpers */
- int i;
+ int i, ch;
+ u_int maskcheck;
if (HFC_cnt >= MAX_CARDS) {
printk(KERN_ERR "too many cards (max=%d).\n",
- MAX_CARDS);
+ MAX_CARDS);
return -EINVAL;
}
if ((type[HFC_cnt] & 0xff) && (type[HFC_cnt] & 0xff) != m->type) {
printk(KERN_WARNING "HFC-MULTI: Card '%s:%s' type %d found but "
- "type[%d] %d was supplied as module parameter\n",
- m->vendor_name, m->card_name, m->type, HFC_cnt,
- type[HFC_cnt] & 0xff);
+ "type[%d] %d was supplied as module parameter\n",
+ m->vendor_name, m->card_name, m->type, HFC_cnt,
+ type[HFC_cnt] & 0xff);
printk(KERN_WARNING "HFC-MULTI: Load module without parameters "
- "first, to see cards and their types.");
+ "first, to see cards and their types.");
return -EINVAL;
}
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: Registering %s:%s chip type %d (0x%x)\n",
- __func__, m->vendor_name, m->card_name, m->type,
- type[HFC_cnt]);
+ __func__, m->vendor_name, m->card_name, m->type,
+ type[HFC_cnt]);
/* allocate card+fifo structure */
hc = kzalloc(sizeof(struct hfc_multi), GFP_KERNEL);
@@ -4879,21 +5040,42 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
}
spin_lock_init(&hc->lock);
hc->mtyp = m;
- hc->type = m->type;
+ hc->ctype = m->type;
hc->ports = m->ports;
hc->id = HFC_cnt;
hc->pcm = pcm[HFC_cnt];
hc->io_mode = iomode[HFC_cnt];
- if (dslot[HFC_cnt] < 0 && hc->type == 1) {
- hc->dslot = 0;
- printk(KERN_INFO "HFC-E1 card has disabled D-channel, but "
- "31 B-channels\n");
- } if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32 && hc->type == 1) {
- hc->dslot = dslot[HFC_cnt];
- printk(KERN_INFO "HFC-E1 card has alternating D-channel on "
- "time slot %d\n", dslot[HFC_cnt]);
- } else
- hc->dslot = 16;
+ if (hc->ctype == HFC_TYPE_E1 && dmask[E1_cnt]) {
+ /* fragment card */
+ pt = 0;
+ maskcheck = 0;
+ for (ch = 0; ch <= 31; ch++) {
+ if (!((1 << ch) & dmask[E1_cnt]))
+ continue;
+ hc->dnum[pt] = ch;
+ hc->bmask[pt] = bmask[bmask_cnt++];
+ if ((maskcheck & hc->bmask[pt])
+ || (dmask[E1_cnt] & hc->bmask[pt])) {
+ printk(KERN_INFO
+ "HFC-E1 #%d has overlapping B-channels on fragment #%d\n",
+ E1_cnt + 1, pt);
+ kfree(hc);
+ return -EINVAL;
+ }
+ maskcheck |= hc->bmask[pt];
+ printk(KERN_INFO
+ "HFC-E1 #%d uses D-channel on slot %d and a B-channel map of 0x%08x\n",
+ E1_cnt + 1, ch, hc->bmask[pt]);
+ pt++;
+ }
+ hc->ports = pt;
+ }
+ if (hc->ctype == HFC_TYPE_E1 && !dmask[E1_cnt]) {
+ /* default card layout */
+ hc->dnum[0] = 16;
+ hc->bmask[0] = 0xfffefffe;
+ hc->ports = 1;
+ }
/* set chip specific features */
hc->masterclk = -1;
@@ -4904,14 +5086,18 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
hc->silence = 0x2a; /* alaw silence */
if ((poll >> 1) > sizeof(hc->silence_data)) {
printk(KERN_ERR "HFCMULTI error: silence_data too small, "
- "please fix\n");
+ "please fix\n");
+ kfree(hc);
return -EINVAL;
}
for (i = 0; i < (poll >> 1); i++)
hc->silence_data[i] = hc->silence;
- if (!(type[HFC_cnt] & 0x200))
- test_and_set_bit(HFC_CHIP_DTMF, &hc->chip);
+ if (hc->ctype != HFC_TYPE_XHFC) {
+ if (!(type[HFC_cnt] & 0x200))
+ test_and_set_bit(HFC_CHIP_DTMF, &hc->chip);
+ test_and_set_bit(HFC_CHIP_CONF, &hc->chip);
+ }
if (type[HFC_cnt] & 0x800)
test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip);
@@ -4935,8 +5121,18 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
printk(KERN_NOTICE "Watchdog enabled\n");
}
- /* setup pci, hc->slots may change due to PLXSD */
- ret_err = setup_pci(hc, pdev, ent);
+ if (pdev && ent)
+ /* setup pci, hc->slots may change due to PLXSD */
+ ret_err = setup_pci(hc, pdev, ent);
+ else
+#ifdef CONFIG_MISDN_HFCMULTI_8xx
+ ret_err = setup_embedded(hc, m);
+#else
+ {
+ printk(KERN_WARNING "Embedded IO Mode not selected\n");
+ ret_err = -EIO;
+ }
+#endif
if (ret_err) {
if (hc == syncmaster)
syncmaster = NULL;
@@ -4944,32 +5140,52 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
return ret_err;
}
- /* crate channels */
+ hc->HFC_outb_nodebug = hc->HFC_outb;
+ hc->HFC_inb_nodebug = hc->HFC_inb;
+ hc->HFC_inw_nodebug = hc->HFC_inw;
+ hc->HFC_wait_nodebug = hc->HFC_wait;
+#ifdef HFC_REGISTER_DEBUG
+ hc->HFC_outb = HFC_outb_debug;
+ hc->HFC_inb = HFC_inb_debug;
+ hc->HFC_inw = HFC_inw_debug;
+ hc->HFC_wait = HFC_wait_debug;
+#endif
+ /* create channels */
for (pt = 0; pt < hc->ports; pt++) {
if (Port_cnt >= MAX_PORTS) {
printk(KERN_ERR "too many ports (max=%d).\n",
- MAX_PORTS);
+ MAX_PORTS);
ret_err = -EINVAL;
goto free_card;
}
- if (hc->type == 1)
- ret_err = init_e1_port(hc, m);
+ if (hc->ctype == HFC_TYPE_E1)
+ ret_err = init_e1_port(hc, m, pt);
else
ret_err = init_multi_port(hc, pt);
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG
- "%s: Registering D-channel, card(%d) port(%d)"
- "result %d\n",
- __func__, HFC_cnt + 1, pt, ret_err);
+ "%s: Registering D-channel, card(%d) port(%d) "
+ "result %d\n",
+ __func__, HFC_cnt + 1, pt + 1, ret_err);
if (ret_err) {
while (pt) { /* release already registered ports */
pt--;
- release_port(hc, hc->chan[(pt << 2) + 2].dch);
+ if (hc->ctype == HFC_TYPE_E1)
+ release_port(hc,
+ hc->chan[hc->dnum[pt]].dch);
+ else
+ release_port(hc,
+ hc->chan[(pt << 2) + 2].dch);
}
goto free_card;
}
- Port_cnt++;
+ if (hc->ctype != HFC_TYPE_E1)
+ Port_cnt++; /* for each S0 port */
+ }
+ if (hc->ctype == HFC_TYPE_E1) {
+ Port_cnt++; /* for each E1 port */
+ E1_cnt++;
}
/* disp switches */
@@ -4991,7 +5207,7 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
pmj = ~pmj & 0xf;
printk(KERN_INFO "%s: %s DIPs(0x%x) jumpers(0x%x)\n",
- m->vendor_name, m->card_name, dips, pmj);
+ m->vendor_name, m->card_name, dips, pmj);
break;
case DIP_8S:
/*
@@ -5013,16 +5229,16 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
/* disable PCI auxbridge function */
HFC_outb(hc, R_BRG_PCM_CFG, V_PCM_CLK);
printk(KERN_INFO "%s: %s DIPs(0x%x)\n",
- m->vendor_name, m->card_name, dips);
+ m->vendor_name, m->card_name, dips);
break;
case DIP_E1:
/*
* get DIP Setting for beroNet E1 cards
* DIP Setting: collect GPI 4/5/6/7 (R_GPI_IN0)
*/
- dips = (~HFC_inb(hc, R_GPI_IN0) & 0xF0)>>4;
+ dips = (~HFC_inb(hc, R_GPI_IN0) & 0xF0) >> 4;
printk(KERN_INFO "%s: %s DIPs(0x%x)\n",
- m->vendor_name, m->card_name, dips);
+ m->vendor_name, m->card_name, dips);
break;
}
@@ -5036,6 +5252,7 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
hc->iclock = mISDN_register_clock("HFCMulti", 0, clockctl, hc);
/* initialize hardware */
+ hc->irq = (m->irq) ? : hc->pci_dev->irq;
ret_err = init_card(hc);
if (ret_err) {
printk(KERN_ERR "init card returns %d\n", ret_err);
@@ -5057,16 +5274,16 @@ free_card:
return ret_err;
}
-static void __devexit hfc_remove_pci(struct pci_dev *pdev)
+static void hfc_remove_pci(struct pci_dev *pdev)
{
struct hfc_multi *card = pci_get_drvdata(pdev);
u_long flags;
if (debug)
printk(KERN_INFO "removing hfc_multi card vendor:%x "
- "device:%x subvendor:%x subdevice:%x\n",
- pdev->vendor, pdev->device,
- pdev->subsystem_vendor, pdev->subsystem_device);
+ "device:%x subvendor:%x subdevice:%x\n",
+ pdev->vendor, pdev->device,
+ pdev->subsystem_vendor, pdev->subsystem_device);
if (card) {
spin_lock_irqsave(&HFClock, flags);
@@ -5074,8 +5291,8 @@ static void __devexit hfc_remove_pci(struct pci_dev *pdev)
spin_unlock_irqrestore(&HFClock, flags);
} else {
if (debug)
- printk(KERN_WARNING "%s: drvdata allready removed\n",
- __func__);
+ printk(KERN_DEBUG "%s: drvdata already removed\n",
+ __func__);
}
}
@@ -5086,127 +5303,139 @@ static void __devexit hfc_remove_pci(struct pci_dev *pdev)
#define VENDOR_PRIM "PrimuX"
static const struct hm_map hfcm_map[] = {
-/*0*/ {VENDOR_BN, "HFC-1S Card (mini PCI)", 4, 1, 1, 3, 0, DIP_4S, 0},
-/*1*/ {VENDOR_BN, "HFC-2S Card", 4, 2, 1, 3, 0, DIP_4S, 0},
-/*2*/ {VENDOR_BN, "HFC-2S Card (mini PCI)", 4, 2, 1, 3, 0, DIP_4S, 0},
-/*3*/ {VENDOR_BN, "HFC-4S Card", 4, 4, 1, 2, 0, DIP_4S, 0},
-/*4*/ {VENDOR_BN, "HFC-4S Card (mini PCI)", 4, 4, 1, 2, 0, 0, 0},
-/*5*/ {VENDOR_CCD, "HFC-4S Eval (old)", 4, 4, 0, 0, 0, 0, 0},
-/*6*/ {VENDOR_CCD, "HFC-4S IOB4ST", 4, 4, 1, 2, 0, DIP_4S, 0},
-/*7*/ {VENDOR_CCD, "HFC-4S", 4, 4, 1, 2, 0, 0, 0},
-/*8*/ {VENDOR_DIG, "HFC-4S Card", 4, 4, 0, 2, 0, 0, HFC_IO_MODE_REGIO},
-/*9*/ {VENDOR_CCD, "HFC-4S Swyx 4xS0 SX2 QuadBri", 4, 4, 1, 2, 0, 0, 0},
-/*10*/ {VENDOR_JH, "HFC-4S (junghanns 2.0)", 4, 4, 1, 2, 0, 0, 0},
-/*11*/ {VENDOR_PRIM, "HFC-2S Primux Card", 4, 2, 0, 0, 0, 0, 0},
-
-/*12*/ {VENDOR_BN, "HFC-8S Card", 8, 8, 1, 0, 0, 0, 0},
-/*13*/ {VENDOR_BN, "HFC-8S Card (+)", 8, 8, 1, 8, 0, DIP_8S,
- HFC_IO_MODE_REGIO},
-/*14*/ {VENDOR_CCD, "HFC-8S Eval (old)", 8, 8, 0, 0, 0, 0, 0},
-/*15*/ {VENDOR_CCD, "HFC-8S IOB4ST Recording", 8, 8, 1, 0, 0, 0, 0},
-
-/*16*/ {VENDOR_CCD, "HFC-8S IOB8ST", 8, 8, 1, 0, 0, 0, 0},
-/*17*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0},
-/*18*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0},
-
-/*19*/ {VENDOR_BN, "HFC-E1 Card", 1, 1, 0, 1, 0, DIP_E1, 0},
-/*20*/ {VENDOR_BN, "HFC-E1 Card (mini PCI)", 1, 1, 0, 1, 0, 0, 0},
-/*21*/ {VENDOR_BN, "HFC-E1+ Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0},
-/*22*/ {VENDOR_BN, "HFC-E1 Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0},
-
-/*23*/ {VENDOR_CCD, "HFC-E1 Eval (old)", 1, 1, 0, 0, 0, 0, 0},
-/*24*/ {VENDOR_CCD, "HFC-E1 IOB1E1", 1, 1, 0, 1, 0, 0, 0},
-/*25*/ {VENDOR_CCD, "HFC-E1", 1, 1, 0, 1, 0, 0, 0},
-
-/*26*/ {VENDOR_CCD, "HFC-4S Speech Design", 4, 4, 0, 0, 0, 0,
- HFC_IO_MODE_PLXSD},
-/*27*/ {VENDOR_CCD, "HFC-E1 Speech Design", 1, 1, 0, 0, 0, 0,
- HFC_IO_MODE_PLXSD},
-/*28*/ {VENDOR_CCD, "HFC-4S OpenVox", 4, 4, 1, 0, 0, 0, 0},
-/*29*/ {VENDOR_CCD, "HFC-2S OpenVox", 4, 2, 1, 0, 0, 0, 0},
-/*30*/ {VENDOR_CCD, "HFC-8S OpenVox", 8, 8, 1, 0, 0, 0, 0},
+ /*0*/ {VENDOR_BN, "HFC-1S Card (mini PCI)", 4, 1, 1, 3, 0, DIP_4S, 0, 0},
+ /*1*/ {VENDOR_BN, "HFC-2S Card", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
+ /*2*/ {VENDOR_BN, "HFC-2S Card (mini PCI)", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
+ /*3*/ {VENDOR_BN, "HFC-4S Card", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
+ /*4*/ {VENDOR_BN, "HFC-4S Card (mini PCI)", 4, 4, 1, 2, 0, 0, 0, 0},
+ /*5*/ {VENDOR_CCD, "HFC-4S Eval (old)", 4, 4, 0, 0, 0, 0, 0, 0},
+ /*6*/ {VENDOR_CCD, "HFC-4S IOB4ST", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
+ /*7*/ {VENDOR_CCD, "HFC-4S", 4, 4, 1, 2, 0, 0, 0, 0},
+ /*8*/ {VENDOR_DIG, "HFC-4S Card", 4, 4, 0, 2, 0, 0, HFC_IO_MODE_REGIO, 0},
+ /*9*/ {VENDOR_CCD, "HFC-4S Swyx 4xS0 SX2 QuadBri", 4, 4, 1, 2, 0, 0, 0, 0},
+ /*10*/ {VENDOR_JH, "HFC-4S (junghanns 2.0)", 4, 4, 1, 2, 0, 0, 0, 0},
+ /*11*/ {VENDOR_PRIM, "HFC-2S Primux Card", 4, 2, 0, 0, 0, 0, 0, 0},
+
+ /*12*/ {VENDOR_BN, "HFC-8S Card", 8, 8, 1, 0, 0, 0, 0, 0},
+ /*13*/ {VENDOR_BN, "HFC-8S Card (+)", 8, 8, 1, 8, 0, DIP_8S,
+ HFC_IO_MODE_REGIO, 0},
+ /*14*/ {VENDOR_CCD, "HFC-8S Eval (old)", 8, 8, 0, 0, 0, 0, 0, 0},
+ /*15*/ {VENDOR_CCD, "HFC-8S IOB4ST Recording", 8, 8, 1, 0, 0, 0, 0, 0},
+
+ /*16*/ {VENDOR_CCD, "HFC-8S IOB8ST", 8, 8, 1, 0, 0, 0, 0, 0},
+ /*17*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0, 0},
+ /*18*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0, 0},
+
+ /*19*/ {VENDOR_BN, "HFC-E1 Card", 1, 1, 0, 1, 0, DIP_E1, 0, 0},
+ /*20*/ {VENDOR_BN, "HFC-E1 Card (mini PCI)", 1, 1, 0, 1, 0, 0, 0, 0},
+ /*21*/ {VENDOR_BN, "HFC-E1+ Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0, 0},
+ /*22*/ {VENDOR_BN, "HFC-E1 Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0, 0},
+
+ /*23*/ {VENDOR_CCD, "HFC-E1 Eval (old)", 1, 1, 0, 0, 0, 0, 0, 0},
+ /*24*/ {VENDOR_CCD, "HFC-E1 IOB1E1", 1, 1, 0, 1, 0, 0, 0, 0},
+ /*25*/ {VENDOR_CCD, "HFC-E1", 1, 1, 0, 1, 0, 0, 0, 0},
+
+ /*26*/ {VENDOR_CCD, "HFC-4S Speech Design", 4, 4, 0, 0, 0, 0,
+ HFC_IO_MODE_PLXSD, 0},
+ /*27*/ {VENDOR_CCD, "HFC-E1 Speech Design", 1, 1, 0, 0, 0, 0,
+ HFC_IO_MODE_PLXSD, 0},
+ /*28*/ {VENDOR_CCD, "HFC-4S OpenVox", 4, 4, 1, 0, 0, 0, 0, 0},
+ /*29*/ {VENDOR_CCD, "HFC-2S OpenVox", 4, 2, 1, 0, 0, 0, 0, 0},
+ /*30*/ {VENDOR_CCD, "HFC-8S OpenVox", 8, 8, 1, 0, 0, 0, 0, 0},
+ /*31*/ {VENDOR_CCD, "XHFC-4S Speech Design", 5, 4, 0, 0, 0, 0,
+ HFC_IO_MODE_EMBSD, XHFC_IRQ},
+ /*32*/ {VENDOR_JH, "HFC-8S (junghanns)", 8, 8, 1, 0, 0, 0, 0, 0},
+ /*33*/ {VENDOR_BN, "HFC-2S Beronet Card PCIe", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
+ /*34*/ {VENDOR_BN, "HFC-4S Beronet Card PCIe", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
};
#undef H
#define H(x) ((unsigned long)&hfcm_map[x])
-static struct pci_device_id hfmultipci_ids[] __devinitdata = {
+static struct pci_device_id hfmultipci_ids[] = {
/* Cards with HFC-4S Chip */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_BN1SM, 0, 0, H(0)}, /* BN1S mini PCI */
+ PCI_SUBDEVICE_ID_CCD_BN1SM, 0, 0, H(0)}, /* BN1S mini PCI */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_BN2S, 0, 0, H(1)}, /* BN2S */
+ PCI_SUBDEVICE_ID_CCD_BN2S, 0, 0, H(1)}, /* BN2S */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_BN2SM, 0, 0, H(2)}, /* BN2S mini PCI */
+ PCI_SUBDEVICE_ID_CCD_BN2SM, 0, 0, H(2)}, /* BN2S mini PCI */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_BN4S, 0, 0, H(3)}, /* BN4S */
+ PCI_SUBDEVICE_ID_CCD_BN4S, 0, 0, H(3)}, /* BN4S */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_BN4SM, 0, 0, H(4)}, /* BN4S mini PCI */
+ PCI_SUBDEVICE_ID_CCD_BN4SM, 0, 0, H(4)}, /* BN4S mini PCI */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
- PCI_DEVICE_ID_CCD_HFC4S, 0, 0, H(5)}, /* Old Eval */
+ PCI_DEVICE_ID_CCD_HFC4S, 0, 0, H(5)}, /* Old Eval */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_IOB4ST, 0, 0, H(6)}, /* IOB4ST */
+ PCI_SUBDEVICE_ID_CCD_IOB4ST, 0, 0, H(6)}, /* IOB4ST */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_HFC4S, 0, 0, H(7)}, /* 4S */
+ PCI_SUBDEVICE_ID_CCD_HFC4S, 0, 0, H(7)}, /* 4S */
{ PCI_VENDOR_ID_DIGIUM, PCI_DEVICE_ID_DIGIUM_HFC4S,
- PCI_VENDOR_ID_DIGIUM, PCI_DEVICE_ID_DIGIUM_HFC4S, 0, 0, H(8)},
+ PCI_VENDOR_ID_DIGIUM, PCI_DEVICE_ID_DIGIUM_HFC4S, 0, 0, H(8)},
+ { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
+ PCI_SUBDEVICE_ID_CCD_SWYX4S, 0, 0, H(9)}, /* 4S Swyx */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_SWYX4S, 0, 0, H(9)}, /* 4S Swyx */
+ PCI_SUBDEVICE_ID_CCD_JH4S20, 0, 0, H(10)},
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_JH4S20, 0, 0, H(10)},
+ PCI_SUBDEVICE_ID_CCD_PMX2S, 0, 0, H(11)}, /* Primux */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_PMX2S, 0, 0, H(11)}, /* Primux */
+ PCI_SUBDEVICE_ID_CCD_OV4S, 0, 0, H(28)}, /* OpenVox 4 */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_OV4S, 0, 0, H(28)}, /* OpenVox 4 */
+ PCI_SUBDEVICE_ID_CCD_OV2S, 0, 0, H(29)}, /* OpenVox 2 */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_OV2S, 0, 0, H(29)}, /* OpenVox 2 */
+ 0xb761, 0, 0, H(33)}, /* BN2S PCIe */
+ { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
+ 0xb762, 0, 0, H(34)}, /* BN4S PCIe */
/* Cards with HFC-8S Chip */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_BN8S, 0, 0, H(12)}, /* BN8S */
+ PCI_SUBDEVICE_ID_CCD_BN8S, 0, 0, H(12)}, /* BN8S */
+ { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
+ PCI_SUBDEVICE_ID_CCD_BN8SP, 0, 0, H(13)}, /* BN8S+ */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_BN8SP, 0, 0, H(13)}, /* BN8S+ */
+ PCI_DEVICE_ID_CCD_HFC8S, 0, 0, H(14)}, /* old Eval */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
- PCI_DEVICE_ID_CCD_HFC8S, 0, 0, H(14)}, /* old Eval */
+ PCI_SUBDEVICE_ID_CCD_IOB8STR, 0, 0, H(15)}, /* IOB8ST Recording */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_IOB8STR, 0, 0, H(15)}, /* IOB8ST Recording */
+ PCI_SUBDEVICE_ID_CCD_IOB8ST, 0, 0, H(16)}, /* IOB8ST */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_IOB8ST, 0, 0, H(16)}, /* IOB8ST */
+ PCI_SUBDEVICE_ID_CCD_IOB8ST_1, 0, 0, H(17)}, /* IOB8ST */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_IOB8ST_1, 0, 0, H(17)}, /* IOB8ST */
+ PCI_SUBDEVICE_ID_CCD_HFC8S, 0, 0, H(18)}, /* 8S */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_HFC8S, 0, 0, H(18)}, /* 8S */
+ PCI_SUBDEVICE_ID_CCD_OV8S, 0, 0, H(30)}, /* OpenVox 8 */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_OV8S, 0, 0, H(30)}, /* OpenVox 8 */
+ PCI_SUBDEVICE_ID_CCD_JH8S, 0, 0, H(32)}, /* Junganns 8S */
/* Cards with HFC-E1 Chip */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_BNE1, 0, 0, H(19)}, /* BNE1 */
+ PCI_SUBDEVICE_ID_CCD_BNE1, 0, 0, H(19)}, /* BNE1 */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_BNE1M, 0, 0, H(20)}, /* BNE1 mini PCI */
+ PCI_SUBDEVICE_ID_CCD_BNE1M, 0, 0, H(20)}, /* BNE1 mini PCI */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_BNE1DP, 0, 0, H(21)}, /* BNE1 + (Dual) */
+ PCI_SUBDEVICE_ID_CCD_BNE1DP, 0, 0, H(21)}, /* BNE1 + (Dual) */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_BNE1D, 0, 0, H(22)}, /* BNE1 (Dual) */
+ PCI_SUBDEVICE_ID_CCD_BNE1D, 0, 0, H(22)}, /* BNE1 (Dual) */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
- PCI_DEVICE_ID_CCD_HFCE1, 0, 0, H(23)}, /* Old Eval */
+ PCI_DEVICE_ID_CCD_HFCE1, 0, 0, H(23)}, /* Old Eval */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_IOB1E1, 0, 0, H(24)}, /* IOB1E1 */
+ PCI_SUBDEVICE_ID_CCD_IOB1E1, 0, 0, H(24)}, /* IOB1E1 */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_HFCE1, 0, 0, H(25)}, /* E1 */
+ PCI_SUBDEVICE_ID_CCD_HFCE1, 0, 0, H(25)}, /* E1 */
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_SPD4S, 0, 0, H(26)}, /* PLX PCI Bridge */
+ PCI_SUBDEVICE_ID_CCD_SPD4S, 0, 0, H(26)}, /* PLX PCI Bridge */
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_CCD,
- PCI_SUBDEVICE_ID_CCD_SPDE1, 0, 0, H(27)}, /* PLX PCI Bridge */
- { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_ANY_ID, PCI_ANY_ID,
- 0, 0, 0},
- { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_ANY_ID, PCI_ANY_ID,
- 0, 0, 0},
- { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_ANY_ID, PCI_ANY_ID,
- 0, 0, 0},
+ PCI_SUBDEVICE_ID_CCD_SPDE1, 0, 0, H(27)}, /* PLX PCI Bridge */
+
+ { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
+ PCI_SUBDEVICE_ID_CCD_JHSE1, 0, 0, H(25)}, /* Junghanns E1 */
+
+ { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_HFC4S), 0 },
+ { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_HFC8S), 0 },
+ { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_HFCE1), 0 },
{0, }
};
#undef H
@@ -5220,18 +5449,19 @@ hfcmulti_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
int ret;
if (m == NULL && ent->vendor == PCI_VENDOR_ID_CCD && (
- ent->device == PCI_DEVICE_ID_CCD_HFC4S ||
- ent->device == PCI_DEVICE_ID_CCD_HFC8S ||
- ent->device == PCI_DEVICE_ID_CCD_HFCE1)) {
+ ent->device == PCI_DEVICE_ID_CCD_HFC4S ||
+ ent->device == PCI_DEVICE_ID_CCD_HFC8S ||
+ ent->device == PCI_DEVICE_ID_CCD_HFCE1)) {
printk(KERN_ERR
- "Unknown HFC multiport controller (vendor:%x device:%x "
- "subvendor:%x subdevice:%x)\n", ent->vendor, ent->device,
- ent->subvendor, ent->subdevice);
+ "Unknown HFC multiport controller (vendor:%04x device:%04x "
+ "subvendor:%04x subdevice:%04x)\n", pdev->vendor,
+ pdev->device, pdev->subsystem_vendor,
+ pdev->subsystem_device);
printk(KERN_ERR
- "Please contact the driver maintainer for support.\n");
+ "Please contact the driver maintainer for support.\n");
return -ENODEV;
}
- ret = hfcmulti_init(pdev, ent);
+ ret = hfcmulti_init(m, pdev, ent);
if (ret)
return ret;
HFC_cnt++;
@@ -5242,7 +5472,7 @@ hfcmulti_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
static struct pci_driver hfcmultipci_driver = {
.name = "hfc_multi",
.probe = hfcmulti_probe,
- .remove = __devexit_p(hfc_remove_pci),
+ .remove = hfc_remove_pci,
.id_table = hfmultipci_ids,
};
@@ -5261,6 +5491,8 @@ static int __init
HFCmulti_init(void)
{
int err;
+ int i, xhfc = 0;
+ struct hm_map m;
printk(KERN_INFO "mISDN: HFC-multi driver %s\n", HFC_MULTI_VERSION);
@@ -5299,7 +5531,7 @@ HFCmulti_init(void)
break;
default:
printk(KERN_ERR
- "%s: Wrong poll value (%d).\n", __func__, poll);
+ "%s: Wrong poll value (%d).\n", __func__, poll);
err = -EINVAL;
return err;
@@ -5308,11 +5540,43 @@ HFCmulti_init(void)
if (!clock)
clock = 1;
+ /* Register the embedded devices.
+ * This should be done before the PCI cards registration */
+ switch (hwid) {
+ case HWID_MINIP4:
+ xhfc = 1;
+ m = hfcm_map[31];
+ break;
+ case HWID_MINIP8:
+ xhfc = 2;
+ m = hfcm_map[31];
+ break;
+ case HWID_MINIP16:
+ xhfc = 4;
+ m = hfcm_map[31];
+ break;
+ default:
+ xhfc = 0;
+ }
+
+ for (i = 0; i < xhfc; ++i) {
+ err = hfcmulti_init(&m, NULL, NULL);
+ if (err) {
+ printk(KERN_ERR "error registering embedded driver: "
+ "%x\n", err);
+ return err;
+ }
+ HFC_cnt++;
+ printk(KERN_INFO "%d devices registered\n", HFC_cnt);
+ }
+
+ /* Register the PCI cards */
err = pci_register_driver(&hfcmultipci_driver);
if (err < 0) {
printk(KERN_ERR "error registering pci driver: %x\n", err);
return err;
}
+
return 0;
}