cregit-Linux how code gets into the kernel

Release 4.11 drivers/isdn/hisax/diva.c

/* $Id: diva.c,v 1.33.2.6 2004/02/11 13:21:33 keil Exp $
 *
 * low level stuff for Eicon.Diehl Diva Family ISDN cards
 *
 * Author       Karsten Keil
 * Copyright    by Karsten Keil      <keil@isdn4linux.de>
 *
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 * For changes and modifications please read
 * Documentation/isdn/HiSax.cert
 *
 * Thanks to Eicon Technology for documents and information
 *
 */

#include <linux/init.h>
#include "hisax.h"
#include "isac.h"
#include "hscx.h"
#include "ipac.h"
#include "ipacx.h"
#include "isdnl1.h"
#include <linux/pci.h>
#include <linux/isapnp.h>


static const char *Diva_revision = "$Revision: 1.33.2.6 $";


#define byteout(addr, val) outb(val, addr)

#define bytein(addr) inb(addr)


#define DIVA_HSCX_DATA		0

#define DIVA_HSCX_ADR		4

#define DIVA_ISA_ISAC_DATA	2

#define DIVA_ISA_ISAC_ADR	6

#define DIVA_ISA_CTRL		7

#define DIVA_IPAC_ADR		0

#define DIVA_IPAC_DATA		1


#define DIVA_PCI_ISAC_DATA	8

#define DIVA_PCI_ISAC_ADR	0xc

#define DIVA_PCI_CTRL		0x10

/* SUB Types */

#define DIVA_ISA	1

#define DIVA_PCI	2

#define DIVA_IPAC_ISA	3

#define DIVA_IPAC_PCI	4

#define DIVA_IPACX_PCI	5

/* CTRL (Read) */

#define DIVA_IRQ_STAT	0x01

#define DIVA_EEPROM_SDA	0x02

/* CTRL (Write) */

#define DIVA_IRQ_REQ	0x01

#define DIVA_RESET	0x08

#define DIVA_EEPROM_CLK	0x40

#define DIVA_PCI_LED_A	0x10

#define DIVA_PCI_LED_B	0x20

#define DIVA_ISA_LED_A	0x20

#define DIVA_ISA_LED_B	0x40

#define DIVA_IRQ_CLR	0x80

/* Siemens PITA */

#define PITA_MISC_REG		0x1c
#ifdef __BIG_ENDIAN

#define PITA_PARA_SOFTRESET	0x00000001

#define PITA_SER_SOFTRESET	0x00000002

#define PITA_PARA_MPX_MODE	0x00000004

#define PITA_INT0_ENABLE	0x00000200
#else

#define PITA_PARA_SOFTRESET	0x01000000

#define PITA_SER_SOFTRESET	0x02000000

#define PITA_PARA_MPX_MODE	0x04000000

#define PITA_INT0_ENABLE	0x00020000
#endif

#define PITA_INT0_STATUS	0x02


static inline u_char readreg(unsigned int ale, unsigned int adr, u_char off) { register u_char ret; byteout(ale, off); ret = bytein(adr); return (ret); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)3585.37%150.00%
Andrew Morton614.63%150.00%
Total41100.00%2100.00%


static inline void readfifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) { byteout(ale, off); insb(adr, data, size); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)2970.73%133.33%
Andrew Morton921.95%133.33%
Kai Germaschewski37.32%133.33%
Total41100.00%3100.00%


static inline void writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) { byteout(ale, off); byteout(adr, data); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)3188.57%150.00%
Andrew Morton411.43%150.00%
Total35100.00%2100.00%


static inline void writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) { byteout(ale, off); outsb(adr, data, size); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)3995.12%150.00%
Andrew Morton24.88%150.00%
Total41100.00%2100.00%


static inline u_char memreadreg(unsigned long adr, u_char off) { return (*((unsigned char *) (((unsigned int *)adr) + off))); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)2463.16%150.00%
Andrew Morton1436.84%150.00%
Total38100.00%2100.00%


static inline void memwritereg(unsigned long adr, u_char off, u_char data) { register u_char *p; p = (unsigned char *)(((unsigned int *)adr) + off); *p = data; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)2655.32%150.00%
Andrew Morton2144.68%150.00%
Total47100.00%2100.00%

/* Interface functions */
static u_char ReadISAC(struct IsdnCardState *cs, u_char offset) { return (readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset)); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)3386.84%150.00%
Andrew Morton513.16%150.00%
Total38100.00%2100.00%


static void WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) { writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset, value); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)3792.50%150.00%
Andrew Morton37.50%150.00%
Total40100.00%2100.00%


static void ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) { readfifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0, data, size); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)4195.35%150.00%
Andrew Morton24.65%150.00%
Total43100.00%2100.00%


static void WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) { writefifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0, data, size); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)4195.35%150.00%
Andrew Morton24.65%150.00%
Total43100.00%2100.00%


static u_char ReadISAC_IPAC(struct IsdnCardState *cs, u_char offset) { return (readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset + 0x80)); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)3280.00%150.00%
Andrew Morton820.00%150.00%
Total40100.00%2100.00%


static void WriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value) { writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset | 0x80, value); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)3583.33%150.00%
Andrew Morton716.67%150.00%
Total42100.00%2100.00%


static void ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size) { readfifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0x80, data, size); }

Contributors

PersonTokensPropCommitsCommitProp
Kai Germaschewski3888.37%150.00%
Andrew Morton511.63%150.00%
Total43100.00%2100.00%


static void WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size) { writefifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0x80, data, size); }

Contributors

PersonTokensPropCommitsCommitProp
Kai Germaschewski3888.37%150.00%
Andrew Morton511.63%150.00%
Total43100.00%2100.00%


static u_char ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) { return (readreg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, offset + (hscx ? 0x40 : 0))); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)2346.94%250.00%
Andrew Morton1836.73%125.00%
Kai Germaschewski816.33%125.00%
Total49100.00%4100.00%


static void WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) { writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, offset + (hscx ? 0x40 : 0), value); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)2752.94%250.00%
Andrew Morton1631.37%125.00%
Kai Germaschewski815.69%125.00%
Total51100.00%4100.00%


static u_char MemReadISAC_IPAC(struct IsdnCardState *cs, u_char offset) { return (memreadreg(cs->hw.diva.cfg_reg, offset + 0x80)); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)1856.25%250.00%
Andrew Morton1134.38%125.00%
Kai Germaschewski39.38%125.00%
Total32100.00%4100.00%


static void MemWriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value) { memwritereg(cs->hw.diva.cfg_reg, offset | 0x80, value); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)1750.00%133.33%
Andrew Morton926.47%133.33%
Kai Germaschewski823.53%133.33%
Total34100.00%3100.00%


static void MemReadISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size) { while (size--) *data++ = memreadreg(cs->hw.diva.cfg_reg, 0x80); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)2152.50%150.00%
Andrew Morton1947.50%150.00%
Total40100.00%2100.00%


static void MemWriteISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size) { while (size--) memwritereg(cs->hw.diva.cfg_reg, 0x80, *data++); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)2562.50%150.00%
Andrew Morton1537.50%150.00%
Total40100.00%2100.00%


static u_char MemReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) { return (memreadreg(cs->hw.diva.cfg_reg, offset + (hscx ? 0x40 : 0))); }

Contributors

PersonTokensPropCommitsCommitProp
Kai Germaschewski2356.10%266.67%
Andrew Morton1843.90%133.33%
Total41100.00%3100.00%


static void MemWriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) { memwritereg(cs->hw.diva.cfg_reg, offset + (hscx ? 0x40 : 0), value); }

Contributors

PersonTokensPropCommitsCommitProp
Kai Germaschewski2762.79%266.67%
Andrew Morton1637.21%133.33%
Total43100.00%3100.00%

/* IO-Functions for IPACX type cards */
static u_char MemReadISAC_IPACX(struct IsdnCardState *cs, u_char offset) { return (memreadreg(cs->hw.diva.cfg_reg, offset)); }

Contributors

PersonTokensPropCommitsCommitProp
Kai Germaschewski2583.33%150.00%
Andrew Morton516.67%150.00%
Total30100.00%2100.00%


static void MemWriteISAC_IPACX(struct IsdnCardState *cs, u_char offset, u_char value) { memwritereg(cs->hw.diva.cfg_reg, offset, value); }

Contributors

PersonTokensPropCommitsCommitProp
Kai Germaschewski2990.62%150.00%
Andrew Morton39.38%150.00%
Total32100.00%2100.00%


static void MemReadISACfifo_IPACX(struct IsdnCardState *cs, u_char *data, int size) { while (size--) *data++ = memreadreg(cs->hw.diva.cfg_reg, 0); }

Contributors

PersonTokensPropCommitsCommitProp
Kai Germaschewski3895.00%150.00%
Andrew Morton25.00%150.00%
Total40100.00%2100.00%


static void MemWriteISACfifo_IPACX(struct IsdnCardState *cs, u_char *data, int size) { while (size--) memwritereg(cs->hw.diva.cfg_reg, 0, *data++); }

Contributors

PersonTokensPropCommitsCommitProp
Kai Germaschewski3895.00%150.00%
Andrew Morton25.00%150.00%
Total40100.00%2100.00%


static u_char MemReadHSCX_IPACX(struct IsdnCardState *cs, int hscx, u_char offset) { return (memreadreg(cs->hw.diva.cfg_reg, offset + (hscx ? IPACX_OFF_B2 : IPACX_OFF_B1))); }

Contributors

PersonTokensPropCommitsCommitProp
Kai Germaschewski3687.80%150.00%
Andrew Morton512.20%150.00%
Total41100.00%2100.00%


static void MemWriteHSCX_IPACX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) { memwritereg(cs->hw.diva.cfg_reg, offset + (hscx ? IPACX_OFF_B2 : IPACX_OFF_B1), value); }

Contributors

PersonTokensPropCommitsCommitProp
Kai Germaschewski4093.02%150.00%
Andrew Morton36.98%150.00%
Total43100.00%2100.00%

/* * fast interrupt HSCX stuff goes here */ #define READHSCX(cs, nr, reg) readreg(cs->hw.diva.hscx_adr, \ cs->hw.diva.hscx, reg + (nr ? 0x40 : 0)) #define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.diva.hscx_adr, \ cs->hw.diva.hscx, reg + (nr ? 0x40 : 0), data) #define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.diva.hscx_adr, \ cs->hw.diva.hscx, (nr ? 0x40 : 0), ptr, cnt) #define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.diva.hscx_adr, \ cs->hw.diva.hscx, (nr ? 0x40 : 0), ptr, cnt) #include "hscx_irq.c"
static irqreturn_t diva_interrupt(int intno, void *dev_id) { struct IsdnCardState *cs = dev_id; u_char val, sval; u_long flags; int cnt = 5; spin_lock_irqsave(&cs->lock, flags); while (((sval = bytein(cs->hw.diva.ctrl)) & DIVA_IRQ_REQ) && cnt) { val = readreg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_ISTA + 0x40); if (val) hscx_int_main(cs, val); val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_ISTA); if (val) isac_interrupt(cs, val); cnt--; } if (!cnt) printk(KERN_WARNING "Diva: IRQ LOOP\n"); writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK, 0xFF); writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK + 0x40, 0xFF); writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_MASK, 0xFF); writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_MASK, 0x0); writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK, 0x0); writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK + 0x40, 0x0); spin_unlock_irqrestore(&cs->lock, flags); return IRQ_HANDLED; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)13243.00%337.50%
Andrew Morton13243.00%225.00%
Kai Germaschewski4314.01%337.50%
Total307100.00%8100.00%


static irqreturn_t diva_irq_ipac_isa(int intno, void *dev_id) { struct IsdnCardState *cs = dev_id; u_char ista, val; u_long flags; int icnt = 5; spin_lock_irqsave(&cs->lock, flags); ista = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ISTA); Start_IPACISA: if (cs->debug & L1_DEB_IPAC) debugl1(cs, "IPAC ISTA %02X", ista); if (ista & 0x0f) { val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, HSCX_ISTA + 0x40); 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 & readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_ISTA + 0x80); if (val) { isac_interrupt(cs, val); } } if (ista & 0x10) { val = 0x01; isac_interrupt(cs, val); } ista = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ISTA); if ((ista & 0x3f) && icnt) { icnt--; goto Start_IPACISA; } if (!icnt) printk(KERN_WARNING "DIVA IPAC IRQ LOOP\n"); writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xFF); writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xC0); spin_unlock_irqrestore(&cs->lock, flags); return IRQ_HANDLED; }

Contributors

PersonTokensPropCommitsCommitProp
Andrew Morton20861.72%120.00%
Linus Torvalds (pre-git)10631.45%240.00%
Kai Germaschewski236.82%240.00%
Total337100.00%5100.00%


static inline void MemwaitforCEC(struct IsdnCardState *cs, int hscx) { int to = 50; while ((MemReadHSCX(cs, hscx, HSCX_STAR) & 0x04) && to) { udelay(1); to--; } if (!to) printk(KERN_WARNING "HiSax: waitforCEC timeout\n"); }

Contributors

PersonTokensPropCommitsCommitProp
Andrew Morton3356.90%133.33%
Linus Torvalds (pre-git)2543.10%266.67%
Total58100.00%3100.00%


static inline void MemwaitforXFW(struct IsdnCardState *cs, int hscx) { int to = 50; while (((MemReadHSCX(cs, hscx, HSCX_STAR) & 0x44) != 0x40) && to) { udelay(1); to--; } if (!to) printk(KERN_WARNING "HiSax: waitforXFW timeout\n"); }

Contributors

PersonTokensPropCommitsCommitProp
Andrew Morton4572.58%120.00%
Linus Torvalds (pre-git)1625.81%360.00%
Roel Kluin11.61%120.00%
Total62100.00%5100.00%


static inline void MemWriteHSCXCMDR(struct IsdnCardState *cs, int hscx, u_char data) { MemwaitforCEC(cs, hscx); MemWriteHSCX(cs, hscx, HSCX_CMDR, data); }

Contributors

PersonTokensPropCommitsCommitProp
Andrew Morton1747.22%125.00%
Kai Germaschewski1438.89%125.00%
Linus Torvalds (pre-git)513.89%250.00%
Total36100.00%4100.00%


static void Memhscx_empty_fifo(struct BCState *bcs, int count) { u_char *ptr; struct IsdnCardState *cs = bcs->cs; int cnt; if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) debugl1(cs, "hscx_empty_fifo"); if (bcs->hw.hscx.rcvidx + count > HSCX_BUFMAX) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "hscx_empty_fifo: incoming packet too large"); MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x80); bcs->hw.hscx.rcvidx = 0; return; } ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx; cnt = count; while (cnt--) *ptr++ = memreadreg(cs->hw.diva.cfg_reg, bcs->hw.hscx.hscx ? 0x40 : 0); MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x80); ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx; bcs->hw.hscx.rcvidx += count; if (cs->debug & L1_DEB_HSCX_FIFO) { char *t = bcs->blog; t += sprintf(t, "hscx_empty_fifo %c cnt %d", bcs->hw.hscx.hscx ? 'B' : 'A', count); QuickHex(t, ptr, count); debugl1(cs, "%s", bcs->blog); } }

Contributors

PersonTokensPropCommitsCommitProp
Andrew Morton18267.16%111.11%
Kai Germaschewski7326.94%555.56%
Linus Torvalds (pre-git)145.17%222.22%
Kees Cook20.74%111.11%
Total271100.00%9100.00%


static void Memhscx_fill_fifo(struct BCState *bcs) { struct IsdnCardState *cs = bcs->cs; int more, count, cnt; int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags) ? 64 : 32; u_char *ptr, *p; if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) debugl1(cs, "hscx_fill_fifo"); if (!bcs->tx_skb) return; if (bcs->tx_skb->len <= 0) return; more = (bcs->mode == L1_MODE_TRANS) ? 1 : 0; if (bcs->tx_skb->len > fifo_size) { more = !0; count = fifo_size; } else count = bcs->tx_skb->len; cnt = count; MemwaitforXFW(cs, bcs->hw.hscx.hscx); p = ptr = bcs->tx_skb->data; skb_pull(bcs->tx_skb, count); bcs->tx_cnt -= count; bcs->hw.hscx.count += count; while (cnt--) memwritereg(cs->hw.diva.cfg_reg, bcs->hw.hscx.hscx ? 0x40 : 0, *p++); MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, more ? 0x8 : 0xa); if (cs->debug & L1_DEB_HSCX_FIFO) { char *t = bcs->blog; t += sprintf(t, "hscx_fill_fifo %c cnt %d", bcs->hw.hscx.hscx ? 'B' : 'A', count); QuickHex(t, ptr, count); debugl1(cs, "%s", bcs->blog); } }

Contributors

PersonTokensPropCommitsCommitProp
Andrew Morton22373.36%114.29%
Linus Torvalds (pre-git)5919.41%457.14%
Kai Germaschewski206.58%114.29%
Kees Cook20.66%114.29%
Total304100.00%7100.00%


static void Memhscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx) { u_char r; struct BCState *bcs = cs->bcs + hscx; struct sk_buff *skb; int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags) ? 64 : 32; int count; if (!test_bit(BC_FLG_INIT, &bcs->Flag)) return; if (val & 0x80) { /* RME */ r = MemReadHSCX(cs, hscx, HSCX_RSTA); if ((r & 0xf0) != 0xa0) { if (!(r & 0x80)) if (cs->debug & L1_DEB_WARN) debugl1(cs, "HSCX invalid frame"); if ((r & 0x40) && bcs->mode) if (cs->debug & L1_DEB_WARN) debugl1(cs, "HSCX RDO mode=%d", bcs->mode); if (!(r & 0x20)) if (cs->debug & L1_DEB_WARN) debugl1(cs, "HSCX CRC error"); MemWriteHSCXCMDR(cs, hscx, 0x80); } else { count = MemReadHSCX(cs, hscx, HSCX_RBCL) & ( test_bit(HW_IPAC, &cs->HW_Flags) ? 0x3f : 0x1f); if (count == 0) count = fifo_size; Memhscx_empty_fifo(bcs, count); if ((count = bcs->hw.hscx.rcvidx - 1) > 0) { if (cs->debug & L1_DEB_HSCX_FIFO) debugl1(cs, "HX Frame %d", count); if (!(skb = dev_alloc_skb(count))) printk(KERN_WARNING "HSCX: receive out of memory\n"); else { memcpy(skb_put(skb, count), bcs->hw.hscx.rcvbuf, count); skb_queue_tail(&bcs->rqueue, skb); } } } bcs->hw.hscx.rcvidx = 0; schedule_event(bcs, B_RCVBUFREADY); } if (val & 0x40) { /* RPF */ Memhscx_empty_fifo(bcs, fifo_size); if (bcs->mode == L1_MODE_TRANS) { /* receive audio data */ if (!(skb = dev_alloc_skb(fifo_size))) printk(KERN_WARNING "HiSax: receive out of memory\n"); else { memcpy(skb_put(skb, fifo_size), bcs->hw.hscx.rcvbuf, fifo_size); skb_queue_tail(&bcs->rqueue, skb); } bcs->hw.hscx.rcvidx = 0; schedule_event(bcs, B_RCVBUFREADY); } } if (val & 0x10) { /* XPR */ if (bcs->tx_skb) { if (bcs->tx_skb->len) { Memhscx_fill_fifo(bcs); return; } else { if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && (PACKET_NOACK != bcs->tx_skb->pkt_type)) { u_long flags; spin_lock_irqsave(&bcs->aclock, flags); bcs->ackcnt += bcs->hw.hscx.count; spin_unlock_irqrestore(&bcs->aclock, flags); schedule_event(bcs, B_ACKPENDING); } dev_kfree_skb_irq(bcs->tx_skb); bcs->hw.hscx.count = 0; bcs->tx_skb = NULL; } } if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { bcs->hw.hscx.count = 0; test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); Memhscx_fill_fifo(bcs); } else { test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); schedule_event(bcs, B_XMTBUFREADY); } } }

Contributors

PersonTokensPropCommitsCommitProp
Andrew Morton47575.52%220.00%
Kai Germaschewski11017.49%330.00%
Linus Torvalds (pre-git)325.09%440.00%
Jaroslav Kysela121.91%110.00%
Total629100.00%10100.00%


static inline void Memhscx_int_main(struct IsdnCardState *cs, u_char val) { u_char exval; struct BCState *bcs; if (val & 0x01) { // EXB bcs = cs->bcs + 1; exval = MemReadHSCX(cs, 1, HSCX_EXIR); if (exval & 0x40) { if (bcs->mode == 1) Memhscx_fill_fifo(bcs); else { /* Here we lost an TX interrupt, so * restart transmitting the whole frame. */ if (bcs->tx_skb) { skb_push(bcs->tx_skb, bcs->hw.hscx.count); bcs->tx_cnt += bcs->hw.hscx.count; bcs->hw.hscx.count = 0; } MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x01); if (cs->debug & L1_DEB_WARN) debugl1(cs, "HSCX B EXIR %x Lost TX", exval); } } else if (cs->debug & L1_DEB_HSCX) debugl1(cs, "HSCX B EXIR %x", exval); } if (val & 0xf8) { if (cs->debug & L1_DEB_HSCX) debugl1(cs, "HSCX B interrupt %x", val); Memhscx_interrupt(cs, val, 1); } if (val & 0x02) { // EXA bcs = cs->bcs; exval = MemReadHSCX(cs, 0, HSCX_EXIR); if (exval & 0x40) { if (bcs->mode == L1_MODE_TRANS) Memhscx_fill_fifo(bcs); else { /* Here we lost an TX interrupt, so * restart transmitting the whole frame. */ if (bcs->tx_skb) { skb_push(bcs->tx_skb, bcs->hw.hscx.count); bcs->tx_cnt += bcs->hw.hscx.count; bcs->hw.hscx.count = 0; } MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x01); if (cs->debug & L1_DEB_WARN) debugl1(cs, "HSCX A EXIR %x Lost TX", exval); } } else if (cs->debug & L1_DEB_HSCX) debugl1(cs, "HSCX A EXIR %x", exval); } if (val & 0x04) { // ICA exval = MemReadHSCX(cs, 0, HSCX_ISTA); if (cs->debug & L1_DEB_HSCX) debugl1(cs, "HSCX A interrupt %x", exval); Memhscx_interrupt(cs, exval, 0); } }

Contributors

PersonTokensPropCommitsCommitProp
Andrew Morton30476.57%116.67%
Kai Germaschewski7418.64%116.67%
Linus Torvalds (pre-git)174.28%350.00%
Joe Perches20.50%116.67%
Total397100.00%6100.00%


static irqreturn_t diva_irq_ipac_pci(int intno, void *dev_id) { struct IsdnCardState *cs = dev_id; u_char ista, val; int icnt = 5; u_char *cfg; u_long flags; spin_lock_irqsave(&cs->lock, flags); cfg = (u_char *) cs->hw.diva.pci_cfg; val = *cfg; if (!(val & PITA_INT0_STATUS)) { spin_unlock_irqrestore(&cs->lock, flags); return IRQ_NONE; /* other shared IRQ */ } *cfg = PITA_INT0_STATUS; /* Reset pending INT0 */ ista = memreadreg(cs->hw.diva.cfg_reg, IPAC_ISTA); Start_IPACPCI: if (cs->debug & L1_DEB_IPAC) debugl1(cs, "IPAC ISTA %02X", ista); if (ista & 0x0f) { val = memreadreg(cs->hw.diva.cfg_reg, HSCX_ISTA + 0x40); if (ista & 0x01) val |= 0x01; if (ista & 0x04) val |= 0x02; if (ista & 0x08) val |= 0x04; if (val) Memhscx_int_main(cs, val); } if (ista & 0x20) { val = 0xfe & memreadreg(cs->hw.diva.cfg_reg, ISAC_ISTA + 0x80); if (val) { isac_interrupt(cs, val); } } if (ista & 0x10) { val = 0x01; isac_interrupt(cs, val); } ista = memreadreg(cs->hw.diva.cfg_reg, IPAC_ISTA); if ((ista & 0x3f) && icnt) { icnt--; goto Start_IPACPCI; } if (!icnt) printk(KERN_WARNING "DIVA IPAC PCI IRQ LOOP\n"); memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xFF); memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xC0); spin_unlock_irqrestore(&cs->lock, flags); return IRQ_HANDLED; }

Contributors

PersonTokensPropCommitsCommitProp
Andrew Morton31591.84%150.00%
Kai Germaschewski288.16%150.00%
Total343100.00%2100.00%


static irqreturn_t diva_irq_ipacx_pci(int intno, void *dev_id) { struct IsdnCardState *cs = dev_id; u_char val; u_char *cfg; u_long flags; spin_lock_irqsave(&cs->lock, flags); cfg = (u_char *) cs->hw.diva.pci_cfg; val = *cfg; if (!(val & PITA_INT0_STATUS)) { spin_unlock_irqrestore(&cs->lock, flags); return IRQ_NONE; // other shared IRQ } interrupt_ipacx(cs); // handler for chip *cfg = PITA_INT0_STATUS; // Reset PLX interrupt spin_unlock_irqrestore(&cs->lock, flags); return IRQ_HANDLED; }

Contributors

PersonTokensPropCommitsCommitProp
Andrew Morton10192.66%150.00%
Kai Germaschewski87.34%150.00%
Total109100.00%2100.00%


static void release_io_diva(struct IsdnCardState *cs) { int bytecnt; if ((cs->subtyp == DIVA_IPAC_PCI) || (cs->subtyp == DIVA_IPACX_PCI)) { u_int *cfg = (unsigned int *)cs->hw.diva.pci_cfg; *cfg = 0; /* disable INT0/1 */ *cfg = 2; /* reset pending INT0 */ if (cs->hw.diva.cfg_reg) iounmap((void *)cs->hw.diva.cfg_reg); if (cs->hw.diva.pci_cfg) iounmap((void *)cs->hw.diva.pci_cfg); return; } else if (cs->subtyp != DIVA_IPAC_ISA) { del_timer(&cs->hw.diva.tl); if (cs->hw.diva.cfg_reg) byteout(cs->hw.diva.ctrl, 0); /* LED off, Reset */ } if ((cs->subtyp == DIVA_ISA) || (cs->subtyp == DIVA_IPAC_ISA)) bytecnt = 8; else bytecnt = 32; if (cs->hw.diva.cfg_reg) { release_region(cs->hw.diva.cfg_reg, bytecnt); } }

Contributors

PersonTokensPropCommitsCommitProp
Andrew Morton19290.14%133.33%
Amol Lad209.39%133.33%
Adrian Bunk10.47%133.33%
Total213100.00%3100.00%


static void iounmap_diva(struct IsdnCardState *cs) { if ((cs->subtyp == DIVA_IPAC_PCI) || (cs->subtyp == DIVA_IPACX_PCI)) { if (cs->hw.diva.cfg_reg) { iounmap((void *)cs->hw.diva.cfg_reg); cs->hw.diva.cfg_reg = 0; } if (cs->hw.diva.pci_cfg) { iounmap((void *)cs->hw.diva.pci_cfg); cs->hw.diva.pci_cfg = 0; } } return; }

Contributors

PersonTokensPropCommitsCommitProp
Amol Lad10498.11%150.00%
Andrew Morton21.89%150.00%
Total106100.00%2100.00%


static void reset_diva(struct IsdnCardState *cs) { if (cs->subtyp == DIVA_IPAC_ISA) { writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_POTA2, 0x20); mdelay(10); writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_POTA2, 0x00); mdelay(10); writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xc0); } else if (cs->subtyp == DIVA_IPAC_PCI) { unsigned int *ireg = (unsigned int *)(cs->hw.diva.pci_cfg + PITA_MISC_REG); *ireg = PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE; mdelay(10); *ireg = PITA_PARA_MPX_MODE; mdelay(10); memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xc0); } else if (cs->subtyp == DIVA_IPACX_PCI) { unsigned int *ireg = (unsigned int *)(cs->hw.diva.pci_cfg + PITA_MISC_REG); *ireg = PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE; mdelay(10); *ireg = PITA_PARA_MPX_MODE | PITA_SER_SOFTRESET; mdelay(10); MemWriteISAC_IPACX(cs, IPACX_MASK, 0xff); // Interrupts off } else { /* DIVA 2.0 */ cs->hw.diva.ctrl_reg = 0; /* Reset On */ byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); mdelay(10); cs->hw.diva.ctrl_reg |= DIVA_RESET; /* Reset Off */ byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); mdelay(10); if (cs->subtyp == DIVA_ISA) cs->hw.diva.ctrl_reg |= DIVA_ISA_LED_A; else { /* Workaround PCI9060 */ byteout(cs->hw.diva.pci_cfg + 0x69, 9); cs->hw.diva.ctrl_reg |= DIVA_PCI_LED_A; } byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); } }

Contributors

PersonTokensPropCommitsCommitProp
Andrew Morton37599.47%150.00%
Amol Lad20.53%150.00%
Total377100.00%2100.00%

#define DIVA_ASSIGN 1
static void diva_led_handler(struct IsdnCardState *cs) { int blink = 0; if ((cs->subtyp == DIVA_IPAC_ISA) || (cs->subtyp == DIVA_IPAC_PCI) || (cs->subtyp == DIVA_IPACX_PCI)) return; del_timer(&cs->hw.diva.tl); if (cs->hw.diva.status & DIVA_ASSIGN) cs->hw.diva.ctrl_reg |= (DIVA_ISA == cs->subtyp) ? DIVA_ISA_LED_A : DIVA_PCI_LED_A; else { cs->hw.diva.ctrl_reg ^= (DIVA_ISA == cs->subtyp) ? DIVA_ISA_LED_A : DIVA_PCI_LED_A; blink = 250; } if (cs->hw.diva.status & 0xf000) cs->hw.diva.ctrl_reg |= (DIVA_ISA == cs->subtyp) ? DIVA_ISA_LED_B : DIVA_PCI_LED_B; else if (cs->hw.diva.status & 0x0f00) { cs->hw.diva.ctrl_reg ^= (DIVA_ISA == cs->subtyp) ? DIVA_ISA_LED_B : DIVA_PCI_LED_B; blink = 500; } else cs->hw.diva.ctrl_reg &= ~((DIVA_ISA == cs->subtyp) ? DIVA_ISA_LED_B : DIVA_PCI_LED_B); byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); if (blink) { init_timer(&cs->hw.diva.tl); cs->hw.diva.tl.expires = jiffies + ((blink * HZ) / 1000); add_timer(&cs->hw.diva.tl); } }

Contributors

PersonTokensPropCommitsCommitProp
Andrew Morton280100.00%1100.00%
Total280100.00%1100.00%


static int Diva_card_msg(struct IsdnCardState *cs, int mt, void *arg) { u_int *ireg; u_long flags; switch (mt) { case CARD_RESET: spin_lock_irqsave(&cs->lock, flags); reset_diva(cs); spin_unlock_irqrestore(&cs->lock, flags); return (0); case CARD_RELEASE: release_io_diva(cs); return (0); case CARD_INIT: spin_lock_irqsave(&cs->lock, flags); reset_diva(cs); if (cs->subtyp == DIVA_IPACX_PCI) { ireg = (unsigned int *)cs->hw.diva.pci_cfg; *ireg = PITA_INT0_ENABLE; init_ipacx(cs, 3); // init chip and enable interrupts spin_unlock_irqrestore(&cs->lock, flags); return (0); } if (cs->subtyp == DIVA_IPAC_PCI) { ireg = (unsigned int *)cs->hw.diva.pci_cfg; *ireg = PITA_INT0_ENABLE; } inithscxisac(cs, 3); spin_unlock_irqrestore(&cs->lock, flags); return (0); case CARD_TEST: return (0); case (MDL_REMOVE | REQUEST): cs->hw.diva.status = 0; break; case (MDL_ASSIGN | REQUEST): cs->hw.diva.status |= DIVA_ASSIGN; break; case MDL_INFO_SETUP: if ((long)arg) cs->hw.diva.status |= 0x0200; else cs->hw.diva.status |= 0x0100; break; case MDL_INFO_CONN: if ((long)arg) cs->hw.diva.status |= 0x2000; else cs->hw.diva.status |= 0x1000; break; case MDL_INFO_REL: if ((long)arg) { cs->hw.diva.status &= ~0x2000; cs->hw.diva.status &= ~0x0200; } else { cs->hw.diva.status &= ~0x1000; cs->hw.diva.status &= ~0x0100; } break; } if ((cs->subtyp != DIVA_IPAC_ISA) && (cs->subtyp != DIVA_IPAC_PCI) && (cs->subtyp != DIVA_IPACX_PCI)) { spin_lock_irqsave(&cs->lock, flags); diva_led_handler(cs); spin_unlock_irqrestore(&cs->lock, flags); } return (0); }

Contributors

PersonTokensPropCommitsCommitProp
Andrew Morton426100.00%1100.00%
Total426100.00%1100.00%


static int setup_diva_common(struct IsdnCardState *cs) { int bytecnt; u_char val; if ((cs->subtyp == DIVA_ISA) || (cs->subtyp == DIVA_IPAC_ISA)) bytecnt = 8; else bytecnt = 32; printk(KERN_INFO "Diva: %s card configured at %#lx IRQ %d\n", (cs->subtyp == DIVA_PCI) ? "PCI" : (cs->subtyp == DIVA_ISA) ? "ISA" : (cs->subtyp == DIVA_IPAC_ISA) ? "IPAC ISA" : (cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI", cs->hw.diva.cfg_reg, cs->irq); if ((cs->subtyp == DIVA_IPAC_PCI) || (cs->subtyp == DIVA_IPACX_PCI) || (cs->subtyp == DIVA_PCI)) printk(KERN_INFO "Diva: %s space at %#lx\n", (cs->subtyp == DIVA_PCI) ? "PCI" : (cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI", cs->hw.diva.pci_cfg); if ((cs->subtyp != DIVA_IPAC_PCI) && (cs->subtyp != DIVA_IPACX_PCI)) { if (!request_region(cs->hw.diva.cfg_reg, bytecnt, "diva isdn")) { printk(KERN_WARNING "HiSax: %s config port %lx-%lx already in use\n", "diva", cs->hw.diva.cfg_reg, cs->hw.diva.cfg_reg + bytecnt); iounmap_diva(cs); return (0); } } cs->BC_Read_Reg = &ReadHSCX; cs->BC_Write_Reg = &WriteHSCX; cs->BC_Send_Data = &hscx_fill_fifo; cs->cardmsg = &Diva_card_msg; setup_isac(cs); if (cs->subtyp == DIVA_IPAC_ISA) { cs->readisac = &ReadISAC_IPAC; cs->writeisac = &WriteISAC_IPAC; cs->readisacfifo = &ReadISACfifo_IPAC; cs->writeisacfifo = &WriteISACfifo_IPAC; cs->irq_func = &diva_irq_ipac_isa; val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ID); printk(KERN_INFO "Diva: IPAC version %x\n", val); } else if (cs->subtyp == DIVA_IPAC_PCI) { cs->readisac = &MemReadISAC_IPAC; cs->writeisac = &MemWriteISAC_IPAC; cs->readisacfifo = &MemReadISACfifo_IPAC; cs->writeisacfifo = &MemWriteISACfifo_IPAC; cs->BC_Read_Reg = &MemReadHSCX; cs->BC_Write_Reg = &MemWriteHSCX; cs->BC_Send_Data = &Memhscx_fill_fifo; cs->irq_func = &diva_irq_ipac_pci; val = memreadreg(cs->hw.diva.cfg_reg, IPAC_ID); printk(KERN_INFO "Diva: IPAC version %x\n", val); } else if (cs->subtyp == DIVA_IPACX_PCI) { cs->readisac = &MemReadISAC_IPACX; cs->writeisac = &MemWriteISAC_IPACX; cs->readisacfifo = &MemReadISACfifo_IPACX; cs->writeisacfifo = &MemWriteISACfifo_IPACX; cs->BC_Read_Reg = &MemReadHSCX_IPACX; cs->BC_Write_Reg = &MemWriteHSCX_IPACX; cs->BC_Send_Data = NULL; // function located in ipacx module cs->irq_func = &diva_irq_ipacx_pci; printk(KERN_INFO "Diva: IPACX Design Id: %x\n", MemReadISAC_IPACX(cs, IPACX_ID) & 0x3F); } else { /* DIVA 2.0 */ cs->hw.diva.tl.function = (void *) diva_led_handler; cs->hw.diva.tl.data = (long) cs; init_timer(&cs->hw.diva.tl); cs->readisac = &ReadISAC; cs->writeisac = &WriteISAC; cs->readisacfifo = &ReadISACfifo; cs->writeisacfifo = &WriteISACfifo; cs->irq_func = &diva_interrupt; ISACVersion(cs, "Diva:"); if (HscxVersion(cs, "Diva:")) { printk(KERN_WARNING "Diva: wrong HSCX versions check IO address\n"); release_io_diva(cs); return (0); } } return (1); }

Contributors

PersonTokensPropCommitsCommitProp
Jeff Garzik43868.01%150.00%
Andrew Morton20631.99%150.00%
Total644100.00%2100.00%

#ifdef CONFIG_ISA
static int setup_diva_isa(struct IsdnCard *card) { struct IsdnCardState *cs = card->cs; u_char val; if (!card->para[1]) return (-1); /* card not found; continue search */ cs->hw.diva.ctrl_reg = 0; cs->hw.diva.cfg_reg = card->para[1]; val = readreg(cs->hw.diva.cfg_reg + DIVA_IPAC_ADR, cs->hw.diva.cfg_reg + DIVA_IPAC_DATA, IPAC_ID); printk(KERN_INFO "Diva: IPAC version %x\n", val); if ((val == 1) || (val == 2)) { cs->subtyp = DIVA_IPAC_ISA; cs->hw.diva.ctrl = 0; cs->hw.diva.isac = card->para[1] + DIVA_IPAC_DATA; cs->hw.diva.hscx = card->para[1] + DIVA_IPAC_DATA; cs->hw.diva.isac_adr = card->para[1] + DIVA_IPAC_ADR; cs->hw.diva.hscx_adr = card->para[1] + DIVA_IPAC_ADR; test_and_set_bit(HW_IPAC, &cs->HW_Flags); } else { cs->subtyp = DIVA_ISA; cs->hw.diva.ctrl = card->para[1] + DIVA_ISA_CTRL; cs->hw.diva.isac = card->para[1] + DIVA_ISA_ISAC_DATA; cs->hw.diva.hscx = card->para[1] + DIVA_HSCX_DATA; cs->hw.diva.isac_adr = card->para[1] + DIVA_ISA_ISAC_ADR; cs->hw.diva.hscx_adr = card->para[1] + DIVA_HSCX_ADR; } cs->irq = card->para[0]; return (1); /* card found */ }

Contributors

PersonTokensPropCommitsCommitProp
Andrew Morton23472.90%150.00%
Jeff Garzik8727.10%150.00%
Total321100.00%2100.00%

#else /* if !CONFIG_ISA */
static int setup_diva_isa(struct IsdnCard *card) { return (-1); /* card not found; continue search */ }

Contributors

PersonTokensPropCommitsCommitProp
Jeff Garzik1688.89%150.00%
Andrew Morton211.11%150.00%
Total18100.00%2100.00%

#endif /* CONFIG_ISA */ #ifdef __ISAPNP__ static struct isapnp_device_id diva_ids[] = { { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), (unsigned long) "Diva picola" }, { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x51), (unsigned long) "Diva picola" }, { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), (unsigned long) "Diva 2.0" }, { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x71), (unsigned long) "Diva 2.0" }, { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), (unsigned long) "Diva 2.01" }, { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0xA1), (unsigned long) "Diva 2.01" }, { 0, } }; static struct isapnp_device_id *ipid = &diva_ids[0]; static struct pnp_card *pnp_c = NULL;
static int setup_diva_isapnp(struct IsdnCard *card) { struct IsdnCardState *cs = card->cs; struct pnp_dev *pnp_d; if (!isapnp_present()) return (-1); /* card not found; continue search */ while (ipid->card_vendor) { if ((pnp_c = pnp_find_card(ipid->card_vendor, ipid->card_device, pnp_c))) { pnp_d = NULL; if ((pnp_d = pnp_find_dev(pnp_c, ipid->vendor, ipid->function, pnp_d))) { int err; printk(KERN_INFO "HiSax: %s detected\n", (char *)ipid->driver_data); pnp_disable_dev(pnp_d); err = pnp_activate_dev(pnp_d); if (err < 0) { printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", __func__, err); return (0); } card->para[1] = pnp_port_start(pnp_d, 0); card->para[0] = pnp_irq(pnp_d, 0); if (!card->para[0] || !card->para[1]) { printk(KERN_ERR "Diva PnP:some resources are missing %ld/%lx\n", card->para[0], card->para[1]); pnp_disable_dev(pnp_d); return (0); } cs->hw.diva.cfg_reg = card->para[1]; cs->irq = card->para[0]; if (ipid->function == ISAPNP_FUNCTION(0xA1)) { cs->subtyp = DIVA_IPAC_ISA; cs->hw.diva.ctrl = 0; cs->hw.diva.isac = card->para[1] + DIVA_IPAC_DATA; cs->hw.diva.hscx = card->para[1] + DIVA_IPAC_DATA; cs->hw.diva.isac_adr = card->para[1] + DIVA_IPAC_ADR; cs->hw.diva.hscx_adr = card->para[1] + DIVA_IPAC_ADR; test_and_set_bit(HW_IPAC, &cs->HW_Flags); } else { cs->subtyp = DIVA_ISA; cs->hw.diva.ctrl = card->para[1] + DIVA_ISA_CTRL; cs->hw.diva.isac = card->para[1] + DIVA_ISA_ISAC_DATA; cs->hw.diva.hscx = card->para[1] + DIVA_HSCX_DATA; cs->hw.diva.isac_adr = card->para[1] + DIVA_ISA_ISAC_ADR; cs->hw.diva.hscx_adr = card->para[1] + DIVA_HSCX_ADR; } return (1); /* card found */ } else { printk(KERN_ERR "Diva PnP: PnP error card found, no device\n"); return (0); } } ipid++; pnp_c = NULL; } return (-1); /* card not found; continue search */ }

Contributors

PersonTokensPropCommitsCommitProp
Jeff Garzik30262.27%125.00%
Andrew Morton17636.29%125.00%
Amol Lad61.24%125.00%
Harvey Harrison10.21%125.00%
Total485100.00%4100.00%

#else /* if !ISAPNP */
static int setup_diva_isapnp(struct IsdnCard *card) { return (-1); /* card not found; continue search */ }

Contributors

PersonTokensPropCommitsCommitProp
Jeff Garzik1794.44%150.00%
Andrew Morton15.56%150.00%
Total18100.00%2100.00%

#endif /* ISAPNP */ #ifdef CONFIG_PCI static struct pci_dev *dev_diva = NULL; static struct pci_dev *dev_diva_u = NULL; static struct pci_dev *dev_diva201 = NULL; static struct pci_dev *dev_diva202 = NULL;
static int setup_diva_pci(struct IsdnCard *card) { struct IsdnCardState *cs = card->cs; cs->subtyp = 0; if ((dev_diva = hisax_find_pci_device(PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA20, dev_diva))) { if (pci_enable_device(dev_diva)) return (0); cs->subtyp = DIVA_PCI; cs->irq = dev_diva->irq; cs->hw.diva.cfg_reg = pci_resource_start(dev_diva, 2); } else if ((dev_diva_u = hisax_find_pci_device(PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA20_U, dev_diva_u))) { if (pci_enable_device(dev_diva_u)) return (0); cs->subtyp = DIVA_PCI; cs->irq = dev_diva_u->irq; cs->hw.diva.cfg_reg = pci_resource_start(dev_diva_u, 2); } else if ((dev_diva201 = hisax_find_pci_device(PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA201, dev_diva201))) { if (pci_enable_device(dev_diva201)) return (0); cs->subtyp = DIVA_IPAC_PCI; cs->irq = dev_diva201->irq; cs->hw.diva.pci_cfg = (ulong) ioremap(pci_resource_start(dev_diva201, 0), 4096); cs->hw.diva.cfg_reg = (ulong) ioremap(pci_resource_start(dev_diva201, 1), 4096); } else if ((dev_diva202 = hisax_find_pci_device(PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA202, dev_diva202))) { if (pci_enable_device(dev_diva202)) return (0); cs->subtyp = DIVA_IPACX_PCI; cs->irq = dev_diva202->irq; cs->hw.diva.pci_cfg = (ulong) ioremap(pci_resource_start(dev_diva202, 0), 4096); cs->hw.diva.cfg_reg = (ulong) ioremap(pci_resource_start(dev_diva202, 1), 4096); } else { return (-1); /* card not found; continue search */ } if (!cs->irq) { printk(KERN_WARNING "Diva: No IRQ for PCI card found\n"); iounmap_diva(cs); return (0); } if (!cs->hw.diva.cfg_reg) { printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n"); iounmap_diva(cs); return (0); } cs->irq_flags |= IRQF_SHARED; if ((cs->subtyp == DIVA_IPAC_PCI) || (cs->subtyp == DIVA_IPACX_PCI)) { cs->hw.diva.ctrl = 0; cs->hw.diva.isac = 0; cs->hw.diva.hscx = 0; cs->hw.diva.isac_adr = 0; cs->hw.diva.hscx_adr = 0; test_and_set_bit(HW_IPAC, &cs->HW_Flags); } else { cs->hw.diva.ctrl = cs->hw.diva.cfg_reg + DIVA_PCI_CTRL; cs->hw.diva.isac = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_DATA; cs->hw.diva.hscx = cs->hw.diva.cfg_reg + DIVA_HSCX_DATA; cs->hw.diva.isac_adr = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_ADR; cs->hw.diva.hscx_adr = cs->hw.diva.cfg_reg + DIVA_HSCX_ADR; } return (1); /* card found */ }

Contributors

PersonTokensPropCommitsCommitProp
Jeff Garzik38266.78%111.11%
Andrew Morton13924.30%111.11%
Kai Germaschewski386.64%333.33%
Linus Torvalds (pre-git)71.22%222.22%
Tilman Schmidt40.70%111.11%
Amol Lad20.35%111.11%
Total572100.00%9100.00%

#else /* if !CONFIG_PCI */
static int setup_diva_pci(struct IsdnCard *card) { return (-1); /* card not found; continue search */ }

Contributors

PersonTokensPropCommitsCommitProp
Jeff Garzik18100.00%1100.00%
Total18100.00%1100.00%

#endif /* CONFIG_PCI */
int setup_diva(struct IsdnCard *card) { int rc, have_card = 0; struct IsdnCardState *cs = card->cs; char tmp[64]; strcpy(tmp, Diva_revision); printk(KERN_INFO "HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp)); if (cs->typ != ISDN_CTYPE_DIEHLDIVA) return (0); cs->hw.diva.status = 0; rc = setup_diva_isa(card); if (!rc) return rc; if (rc > 0) { have_card = 1; goto ready; } rc = setup_diva_isapnp(card); if (!rc) return rc; if (rc > 0) { have_card = 1; goto ready; } rc = setup_diva_pci(card); if (!rc) return rc; if (rc > 0) have_card = 1; ready: if (!have_card) { printk(KERN_WARNING "Diva: No ISA, ISAPNP or PCI card found\n"); return (0); } return setup_diva_common(card->cs); }

Contributors

PersonTokensPropCommitsCommitProp
Jeff Garzik15281.72%116.67%
Linus Torvalds (pre-git)158.06%116.67%
Andrew Morton158.06%116.67%
Kai Germaschewski31.61%233.33%
Greg Kroah-Hartman10.54%116.67%
Total186100.00%6100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Andrew Morton440653.61%38.57%
Jeff Garzik167420.37%12.86%
Linus Torvalds (pre-git)114213.90%720.00%
Kai Germaschewski82410.03%1440.00%
Amol Lad1341.63%12.86%
Jaroslav Kysela120.15%12.86%
Joe Perches80.10%12.86%
Tilman Schmidt70.09%12.86%
Kees Cook40.05%12.86%
Valdis Kletnieks20.02%12.86%
Adrian Bunk20.02%12.86%
Roel Kluin10.01%12.86%
Greg Kroah-Hartman10.01%12.86%
Harvey Harrison10.01%12.86%
Total8218100.00%35100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.