示例#1
0
static irqreturn_t
gazel_interrupt(int intno, void *dev_id)
{
#define MAXCOUNT 5
	struct IsdnCardState *cs = dev_id;
	u_char valisac, valhscx;
	int count = 0;
	u_long flags;

	spin_lock_irqsave(&cs->lock, flags);
	do {
		valhscx = ReadHSCX(cs, 1, HSCX_ISTA);
		if (valhscx)
			hscx_int_main(cs, valhscx);
		valisac = ReadISAC(cs, ISAC_ISTA);
		if (valisac)
			isac_interrupt(cs, valisac);
		count++;
	} while ((valhscx || valisac) && (count < MAXCOUNT));

	WriteHSCX(cs, 0, HSCX_MASK, 0xFF);
	WriteHSCX(cs, 1, HSCX_MASK, 0xFF);
	WriteISAC(cs, ISAC_MASK, 0xFF);
	WriteISAC(cs, ISAC_MASK, 0x0);
	WriteHSCX(cs, 0, HSCX_MASK, 0x0);
	WriteHSCX(cs, 1, HSCX_MASK, 0x0);
	spin_unlock_irqrestore(&cs->lock, flags);
	return IRQ_HANDLED;
}
示例#2
0
static irqreturn_t
avm_a1p_interrupt(int intno, void *dev_id)
{
	struct IsdnCardState *cs = dev_id;
	u_char val, sval;
	u_long flags;

	spin_lock_irqsave(&cs->lock, flags);
	while ((sval = (~bytein(cs->hw.avm.cfg_reg+ASL0_OFFSET) & ASL0_R_IRQPENDING))) {
		if (cs->debug & L1_DEB_INTSTAT)
			debugl1(cs, "avm IntStatus %x", sval);
		if (sval & ASL0_R_HSCX) {
                        val = ReadHSCX(cs, 1, HSCX_ISTA);
			if (val)
				hscx_int_main(cs, val);
		}
		if (sval & ASL0_R_ISAC) {
			val = ReadISAC(cs, ISAC_ISTA);
			if (val)
				isac_interrupt(cs, val);
		}
	}
	WriteHSCX(cs, 0, HSCX_MASK, 0xff);
	WriteHSCX(cs, 1, HSCX_MASK, 0xff);
	WriteISAC(cs, ISAC_MASK, 0xff);
	WriteISAC(cs, ISAC_MASK, 0x00);
	WriteHSCX(cs, 0, HSCX_MASK, 0x00);
	WriteHSCX(cs, 1, HSCX_MASK, 0x00);
	spin_unlock_irqrestore(&cs->lock, flags);
	return IRQ_HANDLED;
}
示例#3
0
void
isac_empty_fifo(struct isac_hw *isac, int count)
{
	u8 *ptr;

	pr_debug("%s: %s  %d\n", isac->name, __func__, count);

	if (!isac->dch.rx_skb) {
		isac->dch.rx_skb = mI_alloc_skb(isac->dch.maxlen, GFP_ATOMIC);
		if (!isac->dch.rx_skb) {
			pr_info("%s: D receive out of memory\n", isac->name);
			WriteISAC(isac, ISAC_CMDR, 0x80);
			return;
		}
	}
	if ((isac->dch.rx_skb->len + count) >= isac->dch.maxlen) {
		pr_debug("%s: %s overrun %d\n", isac->name, __func__,
			    isac->dch.rx_skb->len + count);
		WriteISAC(isac, ISAC_CMDR, 0x80);
		return;
	}
	ptr = skb_put(isac->dch.rx_skb, count);
	isac->read_fifo(isac->dch.hw, isac->off, ptr, count);
	WriteISAC(isac, ISAC_CMDR, 0x80);
	if (isac->dch.debug & DEBUG_HW_DFIFO) {
		char	pfx[MISDN_MAX_IDLEN + 16];

		snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-recv %s %d ",
			isac->name, count);
		print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count);
	}
}
示例#4
0
static void
gazel_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
#define MAXCOUNT 5
    struct IsdnCardState *cs = dev_id;
    u_char valisac, valhscx;
    int count = 0;

    if (!cs) {
        printk(KERN_WARNING "Gazel: Spurious interrupt!\n");
        return;
    }
    do {
        valhscx = ReadHSCX(cs, 1, HSCX_ISTA);
        if (valhscx)
            hscx_int_main(cs, valhscx);
        valisac = ReadISAC(cs, ISAC_ISTA);
        if (valisac)
            isac_interrupt(cs, valisac);
        count++;
    } while ((valhscx || valisac) && (count < MAXCOUNT));

    WriteHSCX(cs, 0, HSCX_MASK, 0xFF);
    WriteHSCX(cs, 1, HSCX_MASK, 0xFF);
    WriteISAC(cs, ISAC_MASK, 0xFF);
    WriteISAC(cs, ISAC_MASK, 0x0);
    WriteHSCX(cs, 0, HSCX_MASK, 0x0);
    WriteHSCX(cs, 1, HSCX_MASK, 0x0);
}
示例#5
0
static void
avm_a1p_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
	struct IsdnCardState *cs = dev_id;
	u_char val, sval;

	if (!cs) {
		printk(KERN_WARNING "AVM A1 PCMCIA: Spurious interrupt!\n");
		return;
	}
	while ((sval = (~bytein(cs->hw.avm.cfg_reg+ASL0_OFFSET) & ASL0_R_IRQPENDING))) {
		if (cs->debug & L1_DEB_INTSTAT)
			debugl1(cs, "avm IntStatus %x", sval);
		if (sval & ASL0_R_HSCX) {
                        val = ReadHSCX(cs, 1, HSCX_ISTA);
			if (val)
				hscx_int_main(cs, val);
		}
		if (sval & ASL0_R_ISAC) {
			val = ReadISAC(cs, ISAC_ISTA);
			if (val)
				isac_interrupt(cs, val);
		}
	}
	WriteHSCX(cs, 0, HSCX_MASK, 0xff);
	WriteHSCX(cs, 1, HSCX_MASK, 0xff);
	WriteISAC(cs, ISAC_MASK, 0xff);
	WriteISAC(cs, ISAC_MASK, 0x00);
	WriteHSCX(cs, 0, HSCX_MASK, 0x00);
	WriteHSCX(cs, 1, HSCX_MASK, 0x00);
}
示例#6
0
static inline void
ph_command(struct isac_hw *isac, u8 command)
{
	pr_debug("%s: ph_command %x\n", isac->name, command);
	if (isac->type & IPAC_TYPE_ISACX)
		WriteISAC(isac, ISACX_CIX0, (command << 4) | 0xE);
	else
		WriteISAC(isac, ISAC_CIX0, (command << 2) | 3);
}
示例#7
0
static void
isac_rme_irq(struct isac_hw *isac)
{
	u8 val, count;

	val = ReadISAC(isac, ISAC_RSTA);
	if ((val & 0x70) != 0x20) {
		if (val & 0x40) {
			pr_debug("%s: ISAC RDO\n", isac->name);
#ifdef ERROR_STATISTIC
			isac->dch.err_rx++;
#endif
		}
		if (!(val & 0x20)) {
			pr_debug("%s: ISAC CRC error\n", isac->name);
#ifdef ERROR_STATISTIC
			isac->dch.err_crc++;
#endif
		}
		WriteISAC(isac, ISAC_CMDR, 0x80);
		if (isac->dch.rx_skb)
			dev_kfree_skb(isac->dch.rx_skb);
		isac->dch.rx_skb = NULL;
	} else {
		count = ReadISAC(isac, ISAC_RBCL) & 0x1f;
		if (count == 0)
			count = 32;
		isac_empty_fifo(isac, count);
		recv_Dchannel(&isac->dch);
	}
}
示例#8
0
static irqreturn_t
gazel_interrupt_ipac(int intno, void *dev_id)
{
	struct IsdnCardState *cs = dev_id;
	u_char ista, val;
	int count = 0;
	u_long flags;
	
	spin_lock_irqsave(&cs->lock, flags);
	ista = ReadISAC(cs, IPAC_ISTA - 0x80);
	do {
		if (ista & 0x0f) {
			val = ReadHSCX(cs, 1, HSCX_ISTA);
			if (ista & 0x01)
				val |= 0x01;
			if (ista & 0x04)
				val |= 0x02;
			if (ista & 0x08)
				val |= 0x04;
			if (val) {
				hscx_int_main(cs, val);
			}
		}
		if (ista & 0x20) {
			val = 0xfe & ReadISAC(cs, ISAC_ISTA);
			if (val) {
				isac_interrupt(cs, val);
			}
		}
		if (ista & 0x10) {
			val = 0x01;
			isac_interrupt(cs, val);
		}
		ista = ReadISAC(cs, IPAC_ISTA - 0x80);
		count++;
	}
	while ((ista & 0x3f) && (count < MAXCOUNT));

	WriteISAC(cs, IPAC_MASK - 0x80, 0xFF);
	WriteISAC(cs, IPAC_MASK - 0x80, 0xC0);
	spin_unlock_irqrestore(&cs->lock, flags);
	return IRQ_HANDLED;
}
示例#9
0
static void
gazel_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
{
    struct IsdnCardState *cs = dev_id;
    u_char ista, val;
    int count = 0;

    if (!cs) {
        printk(KERN_WARNING "Gazel: Spurious interrupt!\n");
        return;
    }
    ista = ReadISAC(cs, IPAC_ISTA - 0x80);
    do {
        if (ista & 0x0f) {
            val = ReadHSCX(cs, 1, HSCX_ISTA);
            if (ista & 0x01)
                val |= 0x01;
            if (ista & 0x04)
                val |= 0x02;
            if (ista & 0x08)
                val |= 0x04;
            if (val) {
                hscx_int_main(cs, val);
            }
        }
        if (ista & 0x20) {
            val = 0xfe & ReadISAC(cs, ISAC_ISTA);
            if (val) {
                isac_interrupt(cs, val);
            }
        }
        if (ista & 0x10) {
            val = 0x01;
            isac_interrupt(cs, val);
        }
        ista = ReadISAC(cs, IPAC_ISTA - 0x80);
        count++;
    }
    while ((ista & 0x3f) && (count < MAXCOUNT));

    WriteISAC(cs, IPAC_MASK - 0x80, 0xFF);
    WriteISAC(cs, IPAC_MASK - 0x80, 0xC0);
}
示例#10
0
文件: rule19a.c 项目: 9060/spdiff
static void
gazel_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
{
	struct IsdnCardState *cs = dev_id;
	u_char ista, val;
	int count = 0;

	if (!cs) {
		printk(KERN_WARNING "Gazel: Spurious interrupt!\n");
		return;
	}
	do {
		if (ista & 0x10) {
			val = 0x01;
			isac_interrupt(cs, val);
		}
	}
	while ((ista & 0x3f) && (count < MAXCOUNT));

	WriteISAC(cs, IPAC_MASK - 0x80, 0xFF);
	WriteISAC(cs, IPAC_MASK - 0x80, 0xC0);
}
示例#11
0
static void
isac_fill_fifo(struct isac_hw *isac)
{
	int count, more;
	u8 *ptr;

	if (!isac->dch.tx_skb)
		return;
	count = isac->dch.tx_skb->len - isac->dch.tx_idx;
	if (count <= 0)
		return;

	more = 0;
	if (count > 32) {
		more = !0;
		count = 32;
	}
	pr_debug("%s: %s  %d\n", isac->name, __func__, count);
	ptr = isac->dch.tx_skb->data + isac->dch.tx_idx;
	isac->dch.tx_idx += count;
	isac->write_fifo(isac->dch.hw, isac->off, ptr, count);
	WriteISAC(isac, ISAC_CMDR, more ? 0x8 : 0xa);
	if (test_and_set_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) {
		pr_debug("%s: %s dbusytimer running\n", isac->name, __func__);
		del_timer(&isac->dch.timer);
	}
	init_timer(&isac->dch.timer);
	isac->dch.timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
	add_timer(&isac->dch.timer);
	if (isac->dch.debug & DEBUG_HW_DFIFO) {
		char	pfx[MISDN_MAX_IDLEN + 16];

		snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-send %s %d ",
			isac->name, count);
		print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count);
	}
}
示例#12
0
static int
reset_gazel(struct IsdnCardState *cs)
{
	unsigned long plxcntrl, addr = cs->hw.gazel.cfg_reg;

	switch (cs->subtyp) {
		case R647:
			writereg(addr, 0, 0);
			HZDELAY(10);
			writereg(addr, 0, 1);
			HZDELAY(2);
			break;
		case R685:
			plxcntrl = inl(addr + PLX_CNTRL);
			plxcntrl |= (RESET_9050 + RESET_GAZEL);
			outl(plxcntrl, addr + PLX_CNTRL);
			plxcntrl &= ~(RESET_9050 + RESET_GAZEL);
			HZDELAY(4);
			outl(plxcntrl, addr + PLX_CNTRL);
			HZDELAY(10);
			outb(INT_ISAC_EN + INT_HSCX_EN + INT_PCI_EN, addr + PLX_INCSR);
			break;
		case R753:
			plxcntrl = inl(addr + PLX_CNTRL);
			plxcntrl |= (RESET_9050 + RESET_GAZEL);
			outl(plxcntrl, addr + PLX_CNTRL);
			plxcntrl &= ~(RESET_9050 + RESET_GAZEL);
			WriteISAC(cs, IPAC_POTA2 - 0x80, 0x20);
			HZDELAY(4);
			outl(plxcntrl, addr + PLX_CNTRL);
			HZDELAY(10);
			WriteISAC(cs, IPAC_POTA2 - 0x80, 0x00);
			WriteISAC(cs, IPAC_ACFG - 0x80, 0xff);
			WriteISAC(cs, IPAC_AOE - 0x80, 0x0);
			WriteISAC(cs, IPAC_MASK - 0x80, 0xff);
			WriteISAC(cs, IPAC_CONF - 0x80, 0x1);
			outb(INT_IPAC_EN + INT_PCI_EN, addr + PLX_INCSR);
			WriteISAC(cs, IPAC_MASK - 0x80, 0xc0);
			break;
		case R742:
			WriteISAC(cs, IPAC_POTA2 - 0x80, 0x20);
			HZDELAY(4);
			WriteISAC(cs, IPAC_POTA2 - 0x80, 0x00);
			WriteISAC(cs, IPAC_ACFG - 0x80, 0xff);
			WriteISAC(cs, IPAC_AOE - 0x80, 0x0);
			WriteISAC(cs, IPAC_MASK - 0x80, 0xff);
			WriteISAC(cs, IPAC_CONF - 0x80, 0x1);
			WriteISAC(cs, IPAC_MASK - 0x80, 0xc0);
			break;
	}
	return (0);
}
示例#13
0
static void
isac_mos_irq(struct isac_hw *isac)
{
	u8 val;
	int ret;

	val = ReadISAC(isac, ISAC_MOSR);
	pr_debug("%s: ISAC MOSR %02x\n", isac->name, val);
#if ARCOFI_USE
	if (val & 0x08) {
		if (!isac->mon_rx) {
			isac->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC);
			if (!isac->mon_rx) {
				pr_info("%s: ISAC MON RX out of memory!\n",
					isac->name);
				isac->mocr &= 0xf0;
				isac->mocr |= 0x0a;
				WriteISAC(isac, ISAC_MOCR, isac->mocr);
				goto afterMONR0;
			} else
				isac->mon_rxp = 0;
		}
		if (isac->mon_rxp >= MAX_MON_FRAME) {
			isac->mocr &= 0xf0;
			isac->mocr |= 0x0a;
			WriteISAC(isac, ISAC_MOCR, isac->mocr);
			isac->mon_rxp = 0;
			pr_debug("%s: ISAC MON RX overflow!\n", isac->name);
			goto afterMONR0;
		}
		isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR0);
		pr_debug("%s: ISAC MOR0 %02x\n", isac->name,
			isac->mon_rx[isac->mon_rxp - 1]);
		if (isac->mon_rxp == 1) {
			isac->mocr |= 0x04;
			WriteISAC(isac, ISAC_MOCR, isac->mocr);
		}
	}
afterMONR0:
	if (val & 0x80) {
		if (!isac->mon_rx) {
			isac->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC);
			if (!isac->mon_rx) {
				pr_info("%s: ISAC MON RX out of memory!\n",
					isac->name);
				isac->mocr &= 0x0f;
				isac->mocr |= 0xa0;
				WriteISAC(isac, ISAC_MOCR, isac->mocr);
				goto afterMONR1;
			} else
				isac->mon_rxp = 0;
		}
		if (isac->mon_rxp >= MAX_MON_FRAME) {
			isac->mocr &= 0x0f;
			isac->mocr |= 0xa0;
			WriteISAC(isac, ISAC_MOCR, isac->mocr);
			isac->mon_rxp = 0;
			pr_debug("%s: ISAC MON RX overflow!\n", isac->name);
			goto afterMONR1;
		}
		isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR1);
		pr_debug("%s: ISAC MOR1 %02x\n", isac->name,
			isac->mon_rx[isac->mon_rxp - 1]);
		isac->mocr |= 0x40;
		WriteISAC(isac, ISAC_MOCR, isac->mocr);
	}
afterMONR1:
	if (val & 0x04) {
		isac->mocr &= 0xf0;
		WriteISAC(isac, ISAC_MOCR, isac->mocr);
		isac->mocr |= 0x0a;
		WriteISAC(isac, ISAC_MOCR, isac->mocr);
		if (isac->monitor) {
			ret = isac->monitor(isac->dch.hw, MONITOR_RX_0,
				isac->mon_rx, isac->mon_rxp);
			if (ret)
				kfree(isac->mon_rx);
		} else {
			pr_info("%s: MONITOR 0 received %d but no user\n",
				isac->name, isac->mon_rxp);
			kfree(isac->mon_rx);
		}
		isac->mon_rx = NULL;
		isac->mon_rxp = 0;
	}
	if (val & 0x40) {
		isac->mocr &= 0x0f;
		WriteISAC(isac, ISAC_MOCR, isac->mocr);
		isac->mocr |= 0xa0;
		WriteISAC(isac, ISAC_MOCR, isac->mocr);
		if (isac->monitor) {
			ret = isac->monitor(isac->dch.hw, MONITOR_RX_1,
				isac->mon_rx, isac->mon_rxp);
			if (ret)
				kfree(isac->mon_rx);
		} else {
			pr_info("%s: MONITOR 1 received %d but no user\n",
				isac->name, isac->mon_rxp);
			kfree(isac->mon_rx);
		}
		isac->mon_rx = NULL;
		isac->mon_rxp = 0;
	}
	if (val & 0x02) {
		if ((!isac->mon_tx) || (isac->mon_txc &&
			(isac->mon_txp >= isac->mon_txc) && !(val & 0x08))) {
			isac->mocr &= 0xf0;
			WriteISAC(isac, ISAC_MOCR, isac->mocr);
			isac->mocr |= 0x0a;
			WriteISAC(isac, ISAC_MOCR, isac->mocr);
			if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
				if (isac->monitor)
					ret = isac->monitor(isac->dch.hw,
						MONITOR_TX_0, NULL, 0);
			}
			kfree(isac->mon_tx);
			isac->mon_tx = NULL;
			isac->mon_txc = 0;
			isac->mon_txp = 0;
			goto AfterMOX0;
		}
		if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
			if (isac->monitor)
				ret = isac->monitor(isac->dch.hw,
					MONITOR_TX_0, NULL, 0);
			kfree(isac->mon_tx);
			isac->mon_tx = NULL;
			isac->mon_txc = 0;
			isac->mon_txp = 0;
			goto AfterMOX0;
		}
		WriteISAC(isac, ISAC_MOX0, isac->mon_tx[isac->mon_txp++]);
		pr_debug("%s: ISAC %02x -> MOX0\n", isac->name,
			isac->mon_tx[isac->mon_txp - 1]);
	}
AfterMOX0:
	if (val & 0x20) {
		if ((!isac->mon_tx) || (isac->mon_txc &&
			(isac->mon_txp >= isac->mon_txc) && !(val & 0x80))) {
			isac->mocr &= 0x0f;
			WriteISAC(isac, ISAC_MOCR, isac->mocr);
			isac->mocr |= 0xa0;
			WriteISAC(isac, ISAC_MOCR, isac->mocr);
			if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
				if (isac->monitor)
					ret = isac->monitor(isac->dch.hw,
						MONITOR_TX_1, NULL, 0);
			}
			kfree(isac->mon_tx);
			isac->mon_tx = NULL;
			isac->mon_txc = 0;
			isac->mon_txp = 0;
			goto AfterMOX1;
		}
		if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
			if (isac->monitor)
				ret = isac->monitor(isac->dch.hw,
					MONITOR_TX_1, NULL, 0);
			kfree(isac->mon_tx);
			isac->mon_tx = NULL;
			isac->mon_txc = 0;
			isac->mon_txp = 0;
			goto AfterMOX1;
		}
		WriteISAC(isac, ISAC_MOX1, isac->mon_tx[isac->mon_txp++]);
		pr_debug("%s: ISAC %02x -> MOX1\n", isac->name,
			isac->mon_tx[isac->mon_txp - 1]);
	}
AfterMOX1:
	val = 0; /* dummy to avoid warning */
#endif
}