Path: blob/master/drivers/isdn/hardware/mISDN/hfcmulti.c
15112 views
/*1* hfcmulti.c low level driver for hfc-4s/hfc-8s/hfc-e1 based cards2*3* Author Andreas Eversberg ([email protected])4* ported to mqueue mechanism:5* Peter Sprenger (sprengermoving-bytes.de)6*7* inspired by existing hfc-pci driver:8* Copyright 1999 by Werner Cornelius ([email protected])9* Copyright 2008 by Karsten Keil ([email protected])10* Copyright 2008 by Andreas Eversberg ([email protected])11*12* This program is free software; you can redistribute it and/or modify13* it under the terms of the GNU General Public License as published by14* the Free Software Foundation; either version 2, or (at your option)15* any later version.16*17* This program is distributed in the hope that it will be useful,18* but WITHOUT ANY WARRANTY; without even the implied warranty of19* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the20* GNU General Public License for more details.21*22* You should have received a copy of the GNU General Public License23* along with this program; if not, write to the Free Software24* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.25*26*27* Thanks to Cologne Chip AG for this great controller!28*/2930/*31* module parameters:32* type:33* By default (0), the card is automatically detected.34* Or use the following combinations:35* Bit 0-7 = 0x00001 = HFC-E1 (1 port)36* or Bit 0-7 = 0x00004 = HFC-4S (4 ports)37* or Bit 0-7 = 0x00008 = HFC-8S (8 ports)38* Bit 8 = 0x00100 = uLaw (instead of aLaw)39* Bit 9 = 0x00200 = Disable DTMF detect on all B-channels via hardware40* Bit 10 = spare41* Bit 11 = 0x00800 = Force PCM bus into slave mode. (otherwhise auto)42* or Bit 12 = 0x01000 = Force PCM bus into master mode. (otherwhise auto)43* Bit 13 = spare44* Bit 14 = 0x04000 = Use external ram (128K)45* Bit 15 = 0x08000 = Use external ram (512K)46* Bit 16 = 0x10000 = Use 64 timeslots instead of 3247* or Bit 17 = 0x20000 = Use 128 timeslots instead of anything else48* Bit 18 = spare49* Bit 19 = 0x80000 = Send the Watchdog a Signal (Dual E1 with Watchdog)50* (all other bits are reserved and shall be 0)51* example: 0x20204 one HFC-4S with dtmf detection and 128 timeslots on PCM52* bus (PCM master)53*54* port: (optional or required for all ports on all installed cards)55* HFC-4S/HFC-8S only bits:56* Bit 0 = 0x001 = Use master clock for this S/T interface57* (ony once per chip).58* Bit 1 = 0x002 = transmitter line setup (non capacitive mode)59* Don't use this unless you know what you are doing!60* Bit 2 = 0x004 = Disable E-channel. (No E-channel processing)61* example: 0x0001,0x0000,0x0000,0x0000 one HFC-4S with master clock62* received from port 163*64* HFC-E1 only bits:65* Bit 0 = 0x0001 = interface: 0=copper, 1=optical66* Bit 1 = 0x0002 = reserved (later for 32 B-channels transparent mode)67* Bit 2 = 0x0004 = Report LOS68* Bit 3 = 0x0008 = Report AIS69* Bit 4 = 0x0010 = Report SLIP70* Bit 5 = 0x0020 = Report RDI71* Bit 8 = 0x0100 = Turn off CRC-4 Multiframe Mode, use double frame72* mode instead.73* Bit 9 = 0x0200 = Force get clock from interface, even in NT mode.74* or Bit 10 = 0x0400 = Force put clock to interface, even in TE mode.75* Bit 11 = 0x0800 = Use direct RX clock for PCM sync rather than PLL.76* (E1 only)77* Bit 12-13 = 0xX000 = elastic jitter buffer (1-3), Set both bits to 078* for default.79* (all other bits are reserved and shall be 0)80*81* debug:82* NOTE: only one debug value must be given for all cards83* enable debugging (see hfc_multi.h for debug options)84*85* poll:86* NOTE: only one poll value must be given for all cards87* Give the number of samples for each fifo process.88* By default 128 is used. Decrease to reduce delay, increase to89* reduce cpu load. If unsure, don't mess with it!90* Valid is 8, 16, 32, 64, 128, 256.91*92* pcm:93* NOTE: only one pcm value must be given for every card.94* The PCM bus id tells the mISDNdsp module about the connected PCM bus.95* By default (0), the PCM bus id is 100 for the card that is PCM master.96* If multiple cards are PCM master (because they are not interconnected),97* each card with PCM master will have increasing PCM id.98* All PCM busses with the same ID are expected to be connected and have99* common time slots slots.100* Only one chip of the PCM bus must be master, the others slave.101* -1 means no support of PCM bus not even.102* Omit this value, if all cards are interconnected or none is connected.103* If unsure, don't give this parameter.104*105* dslot:106* NOTE: only one dslot value must be given for every card.107* Also this value must be given for non-E1 cards. If omitted, the E1108* card has D-channel on time slot 16, which is default.109* If 1..15 or 17..31, an alternate time slot is used for D-channel.110* In this case, the application must be able to handle this.111* If -1 is given, the D-channel is disabled and all 31 slots can be used112* for B-channel. (only for specific applications)113* If you don't know how to use it, you don't need it!114*115* iomode:116* NOTE: only one mode value must be given for every card.117* -> See hfc_multi.h for HFC_IO_MODE_* values118* By default, the IO mode is pci memory IO (MEMIO).119* Some cards require specific IO mode, so it cannot be changed.120* It may be useful to set IO mode to register io (REGIO) to solve121* PCI bridge problems.122* If unsure, don't give this parameter.123*124* clockdelay_nt:125* NOTE: only one clockdelay_nt value must be given once for all cards.126* Give the value of the clock control register (A_ST_CLK_DLY)127* of the S/T interfaces in NT mode.128* This register is needed for the TBR3 certification, so don't change it.129*130* clockdelay_te:131* NOTE: only one clockdelay_te value must be given once132* Give the value of the clock control register (A_ST_CLK_DLY)133* of the S/T interfaces in TE mode.134* This register is needed for the TBR3 certification, so don't change it.135*136* clock:137* NOTE: only one clock value must be given once138* Selects interface with clock source for mISDN and applications.139* Set to card number starting with 1. Set to -1 to disable.140* By default, the first card is used as clock source.141*142* hwid:143* NOTE: only one hwid value must be given once144* Enable special embedded devices with XHFC controllers.145*/146147/*148* debug register access (never use this, it will flood your system log)149* #define HFC_REGISTER_DEBUG150*/151152#define HFC_MULTI_VERSION "2.03"153154#include <linux/module.h>155#include <linux/slab.h>156#include <linux/pci.h>157#include <linux/delay.h>158#include <linux/mISDNhw.h>159#include <linux/mISDNdsp.h>160161/*162#define IRQCOUNT_DEBUG163#define IRQ_DEBUG164*/165166#include "hfc_multi.h"167#ifdef ECHOPREP168#include "gaintab.h"169#endif170171#define MAX_CARDS 8172#define MAX_PORTS (8 * MAX_CARDS)173174static LIST_HEAD(HFClist);175static spinlock_t HFClock; /* global hfc list lock */176177static void ph_state_change(struct dchannel *);178179static struct hfc_multi *syncmaster;180static int plxsd_master; /* if we have a master card (yet) */181static spinlock_t plx_lock; /* may not acquire other lock inside */182183#define TYP_E1 1184#define TYP_4S 4185#define TYP_8S 8186187static int poll_timer = 6; /* default = 128 samples = 16ms */188/* number of POLL_TIMER interrupts for G2 timeout (ca 1s) */189static int nt_t1_count[] = { 3840, 1920, 960, 480, 240, 120, 60, 30 };190#define CLKDEL_TE 0x0f /* CLKDEL in TE mode */191#define CLKDEL_NT 0x6c /* CLKDEL in NT mode192(0x60 MUST be included!) */193194#define DIP_4S 0x1 /* DIP Switches for Beronet 1S/2S/4S cards */195#define DIP_8S 0x2 /* DIP Switches for Beronet 8S+ cards */196#define DIP_E1 0x3 /* DIP Switches for Beronet E1 cards */197198/*199* module stuff200*/201202static uint type[MAX_CARDS];203static int pcm[MAX_CARDS];204static int dslot[MAX_CARDS];205static uint iomode[MAX_CARDS];206static uint port[MAX_PORTS];207static uint debug;208static uint poll;209static int clock;210static uint timer;211static uint clockdelay_te = CLKDEL_TE;212static uint clockdelay_nt = CLKDEL_NT;213#define HWID_NONE 0214#define HWID_MINIP4 1215#define HWID_MINIP8 2216#define HWID_MINIP16 3217static uint hwid = HWID_NONE;218219static int HFC_cnt, Port_cnt, PCM_cnt = 99;220221MODULE_AUTHOR("Andreas Eversberg");222MODULE_LICENSE("GPL");223MODULE_VERSION(HFC_MULTI_VERSION);224module_param(debug, uint, S_IRUGO | S_IWUSR);225module_param(poll, uint, S_IRUGO | S_IWUSR);226module_param(clock, int, S_IRUGO | S_IWUSR);227module_param(timer, uint, S_IRUGO | S_IWUSR);228module_param(clockdelay_te, uint, S_IRUGO | S_IWUSR);229module_param(clockdelay_nt, uint, S_IRUGO | S_IWUSR);230module_param_array(type, uint, NULL, S_IRUGO | S_IWUSR);231module_param_array(pcm, int, NULL, S_IRUGO | S_IWUSR);232module_param_array(dslot, int, NULL, S_IRUGO | S_IWUSR);233module_param_array(iomode, uint, NULL, S_IRUGO | S_IWUSR);234module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR);235module_param(hwid, uint, S_IRUGO | S_IWUSR); /* The hardware ID */236237#ifdef HFC_REGISTER_DEBUG238#define HFC_outb(hc, reg, val) \239(hc->HFC_outb(hc, reg, val, __func__, __LINE__))240#define HFC_outb_nodebug(hc, reg, val) \241(hc->HFC_outb_nodebug(hc, reg, val, __func__, __LINE__))242#define HFC_inb(hc, reg) \243(hc->HFC_inb(hc, reg, __func__, __LINE__))244#define HFC_inb_nodebug(hc, reg) \245(hc->HFC_inb_nodebug(hc, reg, __func__, __LINE__))246#define HFC_inw(hc, reg) \247(hc->HFC_inw(hc, reg, __func__, __LINE__))248#define HFC_inw_nodebug(hc, reg) \249(hc->HFC_inw_nodebug(hc, reg, __func__, __LINE__))250#define HFC_wait(hc) \251(hc->HFC_wait(hc, __func__, __LINE__))252#define HFC_wait_nodebug(hc) \253(hc->HFC_wait_nodebug(hc, __func__, __LINE__))254#else255#define HFC_outb(hc, reg, val) (hc->HFC_outb(hc, reg, val))256#define HFC_outb_nodebug(hc, reg, val) (hc->HFC_outb_nodebug(hc, reg, val))257#define HFC_inb(hc, reg) (hc->HFC_inb(hc, reg))258#define HFC_inb_nodebug(hc, reg) (hc->HFC_inb_nodebug(hc, reg))259#define HFC_inw(hc, reg) (hc->HFC_inw(hc, reg))260#define HFC_inw_nodebug(hc, reg) (hc->HFC_inw_nodebug(hc, reg))261#define HFC_wait(hc) (hc->HFC_wait(hc))262#define HFC_wait_nodebug(hc) (hc->HFC_wait_nodebug(hc))263#endif264265#ifdef CONFIG_MISDN_HFCMULTI_8xx266#include "hfc_multi_8xx.h"267#endif268269/* HFC_IO_MODE_PCIMEM */270static void271#ifdef HFC_REGISTER_DEBUG272HFC_outb_pcimem(struct hfc_multi *hc, u_char reg, u_char val,273const char *function, int line)274#else275HFC_outb_pcimem(struct hfc_multi *hc, u_char reg, u_char val)276#endif277{278writeb(val, hc->pci_membase + reg);279}280static u_char281#ifdef HFC_REGISTER_DEBUG282HFC_inb_pcimem(struct hfc_multi *hc, u_char reg, const char *function, int line)283#else284HFC_inb_pcimem(struct hfc_multi *hc, u_char reg)285#endif286{287return readb(hc->pci_membase + reg);288}289static u_short290#ifdef HFC_REGISTER_DEBUG291HFC_inw_pcimem(struct hfc_multi *hc, u_char reg, const char *function, int line)292#else293HFC_inw_pcimem(struct hfc_multi *hc, u_char reg)294#endif295{296return readw(hc->pci_membase + reg);297}298static void299#ifdef HFC_REGISTER_DEBUG300HFC_wait_pcimem(struct hfc_multi *hc, const char *function, int line)301#else302HFC_wait_pcimem(struct hfc_multi *hc)303#endif304{305while (readb(hc->pci_membase + R_STATUS) & V_BUSY)306cpu_relax();307}308309/* HFC_IO_MODE_REGIO */310static void311#ifdef HFC_REGISTER_DEBUG312HFC_outb_regio(struct hfc_multi *hc, u_char reg, u_char val,313const char *function, int line)314#else315HFC_outb_regio(struct hfc_multi *hc, u_char reg, u_char val)316#endif317{318outb(reg, hc->pci_iobase + 4);319outb(val, hc->pci_iobase);320}321static u_char322#ifdef HFC_REGISTER_DEBUG323HFC_inb_regio(struct hfc_multi *hc, u_char reg, const char *function, int line)324#else325HFC_inb_regio(struct hfc_multi *hc, u_char reg)326#endif327{328outb(reg, hc->pci_iobase + 4);329return inb(hc->pci_iobase);330}331static u_short332#ifdef HFC_REGISTER_DEBUG333HFC_inw_regio(struct hfc_multi *hc, u_char reg, const char *function, int line)334#else335HFC_inw_regio(struct hfc_multi *hc, u_char reg)336#endif337{338outb(reg, hc->pci_iobase + 4);339return inw(hc->pci_iobase);340}341static void342#ifdef HFC_REGISTER_DEBUG343HFC_wait_regio(struct hfc_multi *hc, const char *function, int line)344#else345HFC_wait_regio(struct hfc_multi *hc)346#endif347{348outb(R_STATUS, hc->pci_iobase + 4);349while (inb(hc->pci_iobase) & V_BUSY)350cpu_relax();351}352353#ifdef HFC_REGISTER_DEBUG354static void355HFC_outb_debug(struct hfc_multi *hc, u_char reg, u_char val,356const char *function, int line)357{358char regname[256] = "", bits[9] = "xxxxxxxx";359int i;360361i = -1;362while (hfc_register_names[++i].name) {363if (hfc_register_names[i].reg == reg)364strcat(regname, hfc_register_names[i].name);365}366if (regname[0] == '\0')367strcpy(regname, "register");368369bits[7] = '0' + (!!(val & 1));370bits[6] = '0' + (!!(val & 2));371bits[5] = '0' + (!!(val & 4));372bits[4] = '0' + (!!(val & 8));373bits[3] = '0' + (!!(val & 16));374bits[2] = '0' + (!!(val & 32));375bits[1] = '0' + (!!(val & 64));376bits[0] = '0' + (!!(val & 128));377printk(KERN_DEBUG378"HFC_outb(chip %d, %02x=%s, 0x%02x=%s); in %s() line %d\n",379hc->id, reg, regname, val, bits, function, line);380HFC_outb_nodebug(hc, reg, val);381}382static u_char383HFC_inb_debug(struct hfc_multi *hc, u_char reg, const char *function, int line)384{385char regname[256] = "", bits[9] = "xxxxxxxx";386u_char val = HFC_inb_nodebug(hc, reg);387int i;388389i = 0;390while (hfc_register_names[i++].name)391;392while (hfc_register_names[++i].name) {393if (hfc_register_names[i].reg == reg)394strcat(regname, hfc_register_names[i].name);395}396if (regname[0] == '\0')397strcpy(regname, "register");398399bits[7] = '0' + (!!(val & 1));400bits[6] = '0' + (!!(val & 2));401bits[5] = '0' + (!!(val & 4));402bits[4] = '0' + (!!(val & 8));403bits[3] = '0' + (!!(val & 16));404bits[2] = '0' + (!!(val & 32));405bits[1] = '0' + (!!(val & 64));406bits[0] = '0' + (!!(val & 128));407printk(KERN_DEBUG408"HFC_inb(chip %d, %02x=%s) = 0x%02x=%s; in %s() line %d\n",409hc->id, reg, regname, val, bits, function, line);410return val;411}412static u_short413HFC_inw_debug(struct hfc_multi *hc, u_char reg, const char *function, int line)414{415char regname[256] = "";416u_short val = HFC_inw_nodebug(hc, reg);417int i;418419i = 0;420while (hfc_register_names[i++].name)421;422while (hfc_register_names[++i].name) {423if (hfc_register_names[i].reg == reg)424strcat(regname, hfc_register_names[i].name);425}426if (regname[0] == '\0')427strcpy(regname, "register");428429printk(KERN_DEBUG430"HFC_inw(chip %d, %02x=%s) = 0x%04x; in %s() line %d\n",431hc->id, reg, regname, val, function, line);432return val;433}434static void435HFC_wait_debug(struct hfc_multi *hc, const char *function, int line)436{437printk(KERN_DEBUG "HFC_wait(chip %d); in %s() line %d\n",438hc->id, function, line);439HFC_wait_nodebug(hc);440}441#endif442443/* write fifo data (REGIO) */444static void445write_fifo_regio(struct hfc_multi *hc, u_char *data, int len)446{447outb(A_FIFO_DATA0, (hc->pci_iobase)+4);448while (len>>2) {449outl(cpu_to_le32(*(u32 *)data), hc->pci_iobase);450data += 4;451len -= 4;452}453while (len>>1) {454outw(cpu_to_le16(*(u16 *)data), hc->pci_iobase);455data += 2;456len -= 2;457}458while (len) {459outb(*data, hc->pci_iobase);460data++;461len--;462}463}464/* write fifo data (PCIMEM) */465static void466write_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len)467{468while (len>>2) {469writel(cpu_to_le32(*(u32 *)data),470hc->pci_membase + A_FIFO_DATA0);471data += 4;472len -= 4;473}474while (len>>1) {475writew(cpu_to_le16(*(u16 *)data),476hc->pci_membase + A_FIFO_DATA0);477data += 2;478len -= 2;479}480while (len) {481writeb(*data, hc->pci_membase + A_FIFO_DATA0);482data++;483len--;484}485}486487/* read fifo data (REGIO) */488static void489read_fifo_regio(struct hfc_multi *hc, u_char *data, int len)490{491outb(A_FIFO_DATA0, (hc->pci_iobase)+4);492while (len>>2) {493*(u32 *)data = le32_to_cpu(inl(hc->pci_iobase));494data += 4;495len -= 4;496}497while (len>>1) {498*(u16 *)data = le16_to_cpu(inw(hc->pci_iobase));499data += 2;500len -= 2;501}502while (len) {503*data = inb(hc->pci_iobase);504data++;505len--;506}507}508509/* read fifo data (PCIMEM) */510static void511read_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len)512{513while (len>>2) {514*(u32 *)data =515le32_to_cpu(readl(hc->pci_membase + A_FIFO_DATA0));516data += 4;517len -= 4;518}519while (len>>1) {520*(u16 *)data =521le16_to_cpu(readw(hc->pci_membase + A_FIFO_DATA0));522data += 2;523len -= 2;524}525while (len) {526*data = readb(hc->pci_membase + A_FIFO_DATA0);527data++;528len--;529}530}531532static void533enable_hwirq(struct hfc_multi *hc)534{535hc->hw.r_irq_ctrl |= V_GLOB_IRQ_EN;536HFC_outb(hc, R_IRQ_CTRL, hc->hw.r_irq_ctrl);537}538539static void540disable_hwirq(struct hfc_multi *hc)541{542hc->hw.r_irq_ctrl &= ~((u_char)V_GLOB_IRQ_EN);543HFC_outb(hc, R_IRQ_CTRL, hc->hw.r_irq_ctrl);544}545546#define NUM_EC 2547#define MAX_TDM_CHAN 32548549550inline void551enablepcibridge(struct hfc_multi *c)552{553HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x3); /* was _io before */554}555556inline void557disablepcibridge(struct hfc_multi *c)558{559HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x2); /* was _io before */560}561562inline unsigned char563readpcibridge(struct hfc_multi *hc, unsigned char address)564{565unsigned short cipv;566unsigned char data;567568if (!hc->pci_iobase)569return 0;570571/* slow down a PCI read access by 1 PCI clock cycle */572HFC_outb(hc, R_CTRL, 0x4); /*was _io before*/573574if (address == 0)575cipv = 0x4000;576else577cipv = 0x5800;578579/* select local bridge port address by writing to CIP port */580/* data = HFC_inb(c, cipv); * was _io before */581outw(cipv, hc->pci_iobase + 4);582data = inb(hc->pci_iobase);583584/* restore R_CTRL for normal PCI read cycle speed */585HFC_outb(hc, R_CTRL, 0x0); /* was _io before */586587return data;588}589590inline void591writepcibridge(struct hfc_multi *hc, unsigned char address, unsigned char data)592{593unsigned short cipv;594unsigned int datav;595596if (!hc->pci_iobase)597return;598599if (address == 0)600cipv = 0x4000;601else602cipv = 0x5800;603604/* select local bridge port address by writing to CIP port */605outw(cipv, hc->pci_iobase + 4);606/* define a 32 bit dword with 4 identical bytes for write sequence */607datav = data | ((__u32) data << 8) | ((__u32) data << 16) |608((__u32) data << 24);609610/*611* write this 32 bit dword to the bridge data port612* this will initiate a write sequence of up to 4 writes to the same613* address on the local bus interface the number of write accesses614* is undefined but >=1 and depends on the next PCI transaction615* during write sequence on the local bus616*/617outl(datav, hc->pci_iobase);618}619620inline void621cpld_set_reg(struct hfc_multi *hc, unsigned char reg)622{623/* Do data pin read low byte */624HFC_outb(hc, R_GPIO_OUT1, reg);625}626627inline void628cpld_write_reg(struct hfc_multi *hc, unsigned char reg, unsigned char val)629{630cpld_set_reg(hc, reg);631632enablepcibridge(hc);633writepcibridge(hc, 1, val);634disablepcibridge(hc);635636return;637}638639inline unsigned char640cpld_read_reg(struct hfc_multi *hc, unsigned char reg)641{642unsigned char bytein;643644cpld_set_reg(hc, reg);645646/* Do data pin read low byte */647HFC_outb(hc, R_GPIO_OUT1, reg);648649enablepcibridge(hc);650bytein = readpcibridge(hc, 1);651disablepcibridge(hc);652653return bytein;654}655656inline void657vpm_write_address(struct hfc_multi *hc, unsigned short addr)658{659cpld_write_reg(hc, 0, 0xff & addr);660cpld_write_reg(hc, 1, 0x01 & (addr >> 8));661}662663inline unsigned short664vpm_read_address(struct hfc_multi *c)665{666unsigned short addr;667unsigned short highbit;668669addr = cpld_read_reg(c, 0);670highbit = cpld_read_reg(c, 1);671672addr = addr | (highbit << 8);673674return addr & 0x1ff;675}676677inline unsigned char678vpm_in(struct hfc_multi *c, int which, unsigned short addr)679{680unsigned char res;681682vpm_write_address(c, addr);683684if (!which)685cpld_set_reg(c, 2);686else687cpld_set_reg(c, 3);688689enablepcibridge(c);690res = readpcibridge(c, 1);691disablepcibridge(c);692693cpld_set_reg(c, 0);694695return res;696}697698inline void699vpm_out(struct hfc_multi *c, int which, unsigned short addr,700unsigned char data)701{702vpm_write_address(c, addr);703704enablepcibridge(c);705706if (!which)707cpld_set_reg(c, 2);708else709cpld_set_reg(c, 3);710711writepcibridge(c, 1, data);712713cpld_set_reg(c, 0);714715disablepcibridge(c);716717{718unsigned char regin;719regin = vpm_in(c, which, addr);720if (regin != data)721printk(KERN_DEBUG "Wrote 0x%x to register 0x%x but got back "722"0x%x\n", data, addr, regin);723}724725}726727728static void729vpm_init(struct hfc_multi *wc)730{731unsigned char reg;732unsigned int mask;733unsigned int i, x, y;734unsigned int ver;735736for (x = 0; x < NUM_EC; x++) {737/* Setup GPIO's */738if (!x) {739ver = vpm_in(wc, x, 0x1a0);740printk(KERN_DEBUG "VPM: Chip %d: ver %02x\n", x, ver);741}742743for (y = 0; y < 4; y++) {744vpm_out(wc, x, 0x1a8 + y, 0x00); /* GPIO out */745vpm_out(wc, x, 0x1ac + y, 0x00); /* GPIO dir */746vpm_out(wc, x, 0x1b0 + y, 0x00); /* GPIO sel */747}748749/* Setup TDM path - sets fsync and tdm_clk as inputs */750reg = vpm_in(wc, x, 0x1a3); /* misc_con */751vpm_out(wc, x, 0x1a3, reg & ~2);752753/* Setup Echo length (256 taps) */754vpm_out(wc, x, 0x022, 1);755vpm_out(wc, x, 0x023, 0xff);756757/* Setup timeslots */758vpm_out(wc, x, 0x02f, 0x00);759mask = 0x02020202 << (x * 4);760761/* Setup the tdm channel masks for all chips */762for (i = 0; i < 4; i++)763vpm_out(wc, x, 0x33 - i, (mask >> (i << 3)) & 0xff);764765/* Setup convergence rate */766printk(KERN_DEBUG "VPM: A-law mode\n");767reg = 0x00 | 0x10 | 0x01;768vpm_out(wc, x, 0x20, reg);769printk(KERN_DEBUG "VPM reg 0x20 is %x\n", reg);770/*vpm_out(wc, x, 0x20, (0x00 | 0x08 | 0x20 | 0x10)); */771772vpm_out(wc, x, 0x24, 0x02);773reg = vpm_in(wc, x, 0x24);774printk(KERN_DEBUG "NLP Thresh is set to %d (0x%x)\n", reg, reg);775776/* Initialize echo cans */777for (i = 0; i < MAX_TDM_CHAN; i++) {778if (mask & (0x00000001 << i))779vpm_out(wc, x, i, 0x00);780}781782/*783* ARM arch at least disallows a udelay of784* more than 2ms... it gives a fake "__bad_udelay"785* reference at link-time.786* long delays in kernel code are pretty sucky anyway787* for now work around it using 5 x 2ms instead of 1 x 10ms788*/789790udelay(2000);791udelay(2000);792udelay(2000);793udelay(2000);794udelay(2000);795796/* Put in bypass mode */797for (i = 0; i < MAX_TDM_CHAN; i++) {798if (mask & (0x00000001 << i))799vpm_out(wc, x, i, 0x01);800}801802/* Enable bypass */803for (i = 0; i < MAX_TDM_CHAN; i++) {804if (mask & (0x00000001 << i))805vpm_out(wc, x, 0x78 + i, 0x01);806}807808}809}810811#ifdef UNUSED812static void813vpm_check(struct hfc_multi *hctmp)814{815unsigned char gpi2;816817gpi2 = HFC_inb(hctmp, R_GPI_IN2);818819if ((gpi2 & 0x3) != 0x3)820printk(KERN_DEBUG "Got interrupt 0x%x from VPM!\n", gpi2);821}822#endif /* UNUSED */823824825/*826* Interface to enable/disable the HW Echocan827*828* these functions are called within a spin_lock_irqsave on829* the channel instance lock, so we are not disturbed by irqs830*831* we can later easily change the interface to make other832* things configurable, for now we configure the taps833*834*/835836static void837vpm_echocan_on(struct hfc_multi *hc, int ch, int taps)838{839unsigned int timeslot;840unsigned int unit;841struct bchannel *bch = hc->chan[ch].bch;842#ifdef TXADJ843int txadj = -4;844struct sk_buff *skb;845#endif846if (hc->chan[ch].protocol != ISDN_P_B_RAW)847return;848849if (!bch)850return;851852#ifdef TXADJ853skb = _alloc_mISDN_skb(PH_CONTROL_IND, HFC_VOL_CHANGE_TX,854sizeof(int), &txadj, GFP_ATOMIC);855if (skb)856recv_Bchannel_skb(bch, skb);857#endif858859timeslot = ((ch/4)*8) + ((ch%4)*4) + 1;860unit = ch % 4;861862printk(KERN_NOTICE "vpm_echocan_on called taps [%d] on timeslot %d\n",863taps, timeslot);864865vpm_out(hc, unit, timeslot, 0x7e);866}867868static void869vpm_echocan_off(struct hfc_multi *hc, int ch)870{871unsigned int timeslot;872unsigned int unit;873struct bchannel *bch = hc->chan[ch].bch;874#ifdef TXADJ875int txadj = 0;876struct sk_buff *skb;877#endif878879if (hc->chan[ch].protocol != ISDN_P_B_RAW)880return;881882if (!bch)883return;884885#ifdef TXADJ886skb = _alloc_mISDN_skb(PH_CONTROL_IND, HFC_VOL_CHANGE_TX,887sizeof(int), &txadj, GFP_ATOMIC);888if (skb)889recv_Bchannel_skb(bch, skb);890#endif891892timeslot = ((ch/4)*8) + ((ch%4)*4) + 1;893unit = ch % 4;894895printk(KERN_NOTICE "vpm_echocan_off called on timeslot %d\n",896timeslot);897/* FILLME */898vpm_out(hc, unit, timeslot, 0x01);899}900901902/*903* Speech Design resync feature904* NOTE: This is called sometimes outside interrupt handler.905* We must lock irqsave, so no other interrupt (other card) will occur!906* Also multiple interrupts may nest, so must lock each access (lists, card)!907*/908static inline void909hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm)910{911struct hfc_multi *hc, *next, *pcmmaster = NULL;912void __iomem *plx_acc_32;913u_int pv;914u_long flags;915916spin_lock_irqsave(&HFClock, flags);917spin_lock(&plx_lock); /* must be locked inside other locks */918919if (debug & DEBUG_HFCMULTI_PLXSD)920printk(KERN_DEBUG "%s: RESYNC(syncmaster=0x%p)\n",921__func__, syncmaster);922923/* select new master */924if (newmaster) {925if (debug & DEBUG_HFCMULTI_PLXSD)926printk(KERN_DEBUG "using provided controller\n");927} else {928list_for_each_entry_safe(hc, next, &HFClist, list) {929if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {930if (hc->syncronized) {931newmaster = hc;932break;933}934}935}936}937938/* Disable sync of all cards */939list_for_each_entry_safe(hc, next, &HFClist, list) {940if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {941plx_acc_32 = hc->plx_membase + PLX_GPIOC;942pv = readl(plx_acc_32);943pv &= ~PLX_SYNC_O_EN;944writel(pv, plx_acc_32);945if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) {946pcmmaster = hc;947if (hc->ctype == HFC_TYPE_E1) {948if (debug & DEBUG_HFCMULTI_PLXSD)949printk(KERN_DEBUG950"Schedule SYNC_I\n");951hc->e1_resync |= 1; /* get SYNC_I */952}953}954}955}956957if (newmaster) {958hc = newmaster;959if (debug & DEBUG_HFCMULTI_PLXSD)960printk(KERN_DEBUG "id=%d (0x%p) = syncronized with "961"interface.\n", hc->id, hc);962/* Enable new sync master */963plx_acc_32 = hc->plx_membase + PLX_GPIOC;964pv = readl(plx_acc_32);965pv |= PLX_SYNC_O_EN;966writel(pv, plx_acc_32);967/* switch to jatt PLL, if not disabled by RX_SYNC */968if (hc->ctype == HFC_TYPE_E1969&& !test_bit(HFC_CHIP_RX_SYNC, &hc->chip)) {970if (debug & DEBUG_HFCMULTI_PLXSD)971printk(KERN_DEBUG "Schedule jatt PLL\n");972hc->e1_resync |= 2; /* switch to jatt */973}974} else {975if (pcmmaster) {976hc = pcmmaster;977if (debug & DEBUG_HFCMULTI_PLXSD)978printk(KERN_DEBUG979"id=%d (0x%p) = PCM master syncronized "980"with QUARTZ\n", hc->id, hc);981if (hc->ctype == HFC_TYPE_E1) {982/* Use the crystal clock for the PCM983master card */984if (debug & DEBUG_HFCMULTI_PLXSD)985printk(KERN_DEBUG986"Schedule QUARTZ for HFC-E1\n");987hc->e1_resync |= 4; /* switch quartz */988} else {989if (debug & DEBUG_HFCMULTI_PLXSD)990printk(KERN_DEBUG991"QUARTZ is automatically "992"enabled by HFC-%dS\n", hc->ctype);993}994plx_acc_32 = hc->plx_membase + PLX_GPIOC;995pv = readl(plx_acc_32);996pv |= PLX_SYNC_O_EN;997writel(pv, plx_acc_32);998} else999if (!rm)1000printk(KERN_ERR "%s no pcm master, this MUST "1001"not happen!\n", __func__);1002}1003syncmaster = newmaster;10041005spin_unlock(&plx_lock);1006spin_unlock_irqrestore(&HFClock, flags);1007}10081009/* This must be called AND hc must be locked irqsave!!! */1010inline void1011plxsd_checksync(struct hfc_multi *hc, int rm)1012{1013if (hc->syncronized) {1014if (syncmaster == NULL) {1015if (debug & DEBUG_HFCMULTI_PLXSD)1016printk(KERN_DEBUG "%s: GOT sync on card %d"1017" (id=%d)\n", __func__, hc->id + 1,1018hc->id);1019hfcmulti_resync(hc, hc, rm);1020}1021} else {1022if (syncmaster == hc) {1023if (debug & DEBUG_HFCMULTI_PLXSD)1024printk(KERN_DEBUG "%s: LOST sync on card %d"1025" (id=%d)\n", __func__, hc->id + 1,1026hc->id);1027hfcmulti_resync(hc, NULL, rm);1028}1029}1030}103110321033/*1034* free hardware resources used by driver1035*/1036static void1037release_io_hfcmulti(struct hfc_multi *hc)1038{1039void __iomem *plx_acc_32;1040u_int pv;1041u_long plx_flags;10421043if (debug & DEBUG_HFCMULTI_INIT)1044printk(KERN_DEBUG "%s: entered\n", __func__);10451046/* soft reset also masks all interrupts */1047hc->hw.r_cirm |= V_SRES;1048HFC_outb(hc, R_CIRM, hc->hw.r_cirm);1049udelay(1000);1050hc->hw.r_cirm &= ~V_SRES;1051HFC_outb(hc, R_CIRM, hc->hw.r_cirm);1052udelay(1000); /* instead of 'wait' that may cause locking */10531054/* release Speech Design card, if PLX was initialized */1055if (test_bit(HFC_CHIP_PLXSD, &hc->chip) && hc->plx_membase) {1056if (debug & DEBUG_HFCMULTI_PLXSD)1057printk(KERN_DEBUG "%s: release PLXSD card %d\n",1058__func__, hc->id + 1);1059spin_lock_irqsave(&plx_lock, plx_flags);1060plx_acc_32 = hc->plx_membase + PLX_GPIOC;1061writel(PLX_GPIOC_INIT, plx_acc_32);1062pv = readl(plx_acc_32);1063/* Termination off */1064pv &= ~PLX_TERM_ON;1065/* Disconnect the PCM */1066pv |= PLX_SLAVE_EN_N;1067pv &= ~PLX_MASTER_EN;1068pv &= ~PLX_SYNC_O_EN;1069/* Put the DSP in Reset */1070pv &= ~PLX_DSP_RES_N;1071writel(pv, plx_acc_32);1072if (debug & DEBUG_HFCMULTI_INIT)1073printk(KERN_DEBUG "%s: PCM off: PLX_GPIO=%x\n",1074__func__, pv);1075spin_unlock_irqrestore(&plx_lock, plx_flags);1076}10771078/* disable memory mapped ports / io ports */1079test_and_clear_bit(HFC_CHIP_PLXSD, &hc->chip); /* prevent resync */1080if (hc->pci_dev)1081pci_write_config_word(hc->pci_dev, PCI_COMMAND, 0);1082if (hc->pci_membase)1083iounmap(hc->pci_membase);1084if (hc->plx_membase)1085iounmap(hc->plx_membase);1086if (hc->pci_iobase)1087release_region(hc->pci_iobase, 8);1088if (hc->xhfc_membase)1089iounmap((void *)hc->xhfc_membase);10901091if (hc->pci_dev) {1092pci_disable_device(hc->pci_dev);1093pci_set_drvdata(hc->pci_dev, NULL);1094}1095if (debug & DEBUG_HFCMULTI_INIT)1096printk(KERN_DEBUG "%s: done\n", __func__);1097}10981099/*1100* function called to reset the HFC chip. A complete software reset of chip1101* and fifos is done. All configuration of the chip is done.1102*/11031104static int1105init_chip(struct hfc_multi *hc)1106{1107u_long flags, val, val2 = 0, rev;1108int i, err = 0;1109u_char r_conf_en, rval;1110void __iomem *plx_acc_32;1111u_int pv;1112u_long plx_flags, hfc_flags;1113int plx_count;1114struct hfc_multi *pos, *next, *plx_last_hc;11151116spin_lock_irqsave(&hc->lock, flags);1117/* reset all registers */1118memset(&hc->hw, 0, sizeof(struct hfcm_hw));11191120/* revision check */1121if (debug & DEBUG_HFCMULTI_INIT)1122printk(KERN_DEBUG "%s: entered\n", __func__);1123val = HFC_inb(hc, R_CHIP_ID);1124if ((val >> 4) != 0x8 && (val >> 4) != 0xc && (val >> 4) != 0xe &&1125(val >> 1) != 0x31) {1126printk(KERN_INFO "HFC_multi: unknown CHIP_ID:%x\n", (u_int)val);1127err = -EIO;1128goto out;1129}1130rev = HFC_inb(hc, R_CHIP_RV);1131printk(KERN_INFO1132"HFC_multi: detected HFC with chip ID=0x%lx revision=%ld%s\n",1133val, rev, (rev == 0 && (hc->ctype != HFC_TYPE_XHFC)) ?1134" (old FIFO handling)" : "");1135if (hc->ctype != HFC_TYPE_XHFC && rev == 0) {1136test_and_set_bit(HFC_CHIP_REVISION0, &hc->chip);1137printk(KERN_WARNING1138"HFC_multi: NOTE: Your chip is revision 0, "1139"ask Cologne Chip for update. Newer chips "1140"have a better FIFO handling. Old chips "1141"still work but may have slightly lower "1142"HDLC transmit performance.\n");1143}1144if (rev > 1) {1145printk(KERN_WARNING "HFC_multi: WARNING: This driver doesn't "1146"consider chip revision = %ld. The chip / "1147"bridge may not work.\n", rev);1148}11491150/* set s-ram size */1151hc->Flen = 0x10;1152hc->Zmin = 0x80;1153hc->Zlen = 384;1154hc->DTMFbase = 0x1000;1155if (test_bit(HFC_CHIP_EXRAM_128, &hc->chip)) {1156if (debug & DEBUG_HFCMULTI_INIT)1157printk(KERN_DEBUG "%s: changing to 128K extenal RAM\n",1158__func__);1159hc->hw.r_ctrl |= V_EXT_RAM;1160hc->hw.r_ram_sz = 1;1161hc->Flen = 0x20;1162hc->Zmin = 0xc0;1163hc->Zlen = 1856;1164hc->DTMFbase = 0x2000;1165}1166if (test_bit(HFC_CHIP_EXRAM_512, &hc->chip)) {1167if (debug & DEBUG_HFCMULTI_INIT)1168printk(KERN_DEBUG "%s: changing to 512K extenal RAM\n",1169__func__);1170hc->hw.r_ctrl |= V_EXT_RAM;1171hc->hw.r_ram_sz = 2;1172hc->Flen = 0x20;1173hc->Zmin = 0xc0;1174hc->Zlen = 8000;1175hc->DTMFbase = 0x2000;1176}1177if (hc->ctype == HFC_TYPE_XHFC) {1178hc->Flen = 0x8;1179hc->Zmin = 0x0;1180hc->Zlen = 64;1181hc->DTMFbase = 0x0;1182}1183hc->max_trans = poll << 1;1184if (hc->max_trans > hc->Zlen)1185hc->max_trans = hc->Zlen;11861187/* Speech Design PLX bridge */1188if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {1189if (debug & DEBUG_HFCMULTI_PLXSD)1190printk(KERN_DEBUG "%s: initializing PLXSD card %d\n",1191__func__, hc->id + 1);1192spin_lock_irqsave(&plx_lock, plx_flags);1193plx_acc_32 = hc->plx_membase + PLX_GPIOC;1194writel(PLX_GPIOC_INIT, plx_acc_32);1195pv = readl(plx_acc_32);1196/* The first and the last cards are terminating the PCM bus */1197pv |= PLX_TERM_ON; /* hc is currently the last */1198/* Disconnect the PCM */1199pv |= PLX_SLAVE_EN_N;1200pv &= ~PLX_MASTER_EN;1201pv &= ~PLX_SYNC_O_EN;1202/* Put the DSP in Reset */1203pv &= ~PLX_DSP_RES_N;1204writel(pv, plx_acc_32);1205spin_unlock_irqrestore(&plx_lock, plx_flags);1206if (debug & DEBUG_HFCMULTI_INIT)1207printk(KERN_DEBUG "%s: slave/term: PLX_GPIO=%x\n",1208__func__, pv);1209/*1210* If we are the 3rd PLXSD card or higher, we must turn1211* termination of last PLXSD card off.1212*/1213spin_lock_irqsave(&HFClock, hfc_flags);1214plx_count = 0;1215plx_last_hc = NULL;1216list_for_each_entry_safe(pos, next, &HFClist, list) {1217if (test_bit(HFC_CHIP_PLXSD, &pos->chip)) {1218plx_count++;1219if (pos != hc)1220plx_last_hc = pos;1221}1222}1223if (plx_count >= 3) {1224if (debug & DEBUG_HFCMULTI_PLXSD)1225printk(KERN_DEBUG "%s: card %d is between, so "1226"we disable termination\n",1227__func__, plx_last_hc->id + 1);1228spin_lock_irqsave(&plx_lock, plx_flags);1229plx_acc_32 = plx_last_hc->plx_membase + PLX_GPIOC;1230pv = readl(plx_acc_32);1231pv &= ~PLX_TERM_ON;1232writel(pv, plx_acc_32);1233spin_unlock_irqrestore(&plx_lock, plx_flags);1234if (debug & DEBUG_HFCMULTI_INIT)1235printk(KERN_DEBUG1236"%s: term off: PLX_GPIO=%x\n",1237__func__, pv);1238}1239spin_unlock_irqrestore(&HFClock, hfc_flags);1240hc->hw.r_pcm_md0 = V_F0_LEN; /* shift clock for DSP */1241}12421243if (test_bit(HFC_CHIP_EMBSD, &hc->chip))1244hc->hw.r_pcm_md0 = V_F0_LEN; /* shift clock for DSP */12451246/* we only want the real Z2 read-pointer for revision > 0 */1247if (!test_bit(HFC_CHIP_REVISION0, &hc->chip))1248hc->hw.r_ram_sz |= V_FZ_MD;12491250/* select pcm mode */1251if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) {1252if (debug & DEBUG_HFCMULTI_INIT)1253printk(KERN_DEBUG "%s: setting PCM into slave mode\n",1254__func__);1255} else1256if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip) && !plxsd_master) {1257if (debug & DEBUG_HFCMULTI_INIT)1258printk(KERN_DEBUG "%s: setting PCM into master mode\n",1259__func__);1260hc->hw.r_pcm_md0 |= V_PCM_MD;1261} else {1262if (debug & DEBUG_HFCMULTI_INIT)1263printk(KERN_DEBUG "%s: performing PCM auto detect\n",1264__func__);1265}12661267/* soft reset */1268HFC_outb(hc, R_CTRL, hc->hw.r_ctrl);1269if (hc->ctype == HFC_TYPE_XHFC)1270HFC_outb(hc, 0x0C /* R_FIFO_THRES */,12710x11 /* 16 Bytes TX/RX */);1272else1273HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz);1274HFC_outb(hc, R_FIFO_MD, 0);1275if (hc->ctype == HFC_TYPE_XHFC)1276hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES;1277else1278hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES1279| V_RLD_EPR;1280HFC_outb(hc, R_CIRM, hc->hw.r_cirm);1281udelay(100);1282hc->hw.r_cirm = 0;1283HFC_outb(hc, R_CIRM, hc->hw.r_cirm);1284udelay(100);1285if (hc->ctype != HFC_TYPE_XHFC)1286HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz);12871288/* Speech Design PLX bridge pcm and sync mode */1289if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {1290spin_lock_irqsave(&plx_lock, plx_flags);1291plx_acc_32 = hc->plx_membase + PLX_GPIOC;1292pv = readl(plx_acc_32);1293/* Connect PCM */1294if (hc->hw.r_pcm_md0 & V_PCM_MD) {1295pv |= PLX_MASTER_EN | PLX_SLAVE_EN_N;1296pv |= PLX_SYNC_O_EN;1297if (debug & DEBUG_HFCMULTI_INIT)1298printk(KERN_DEBUG "%s: master: PLX_GPIO=%x\n",1299__func__, pv);1300} else {1301pv &= ~(PLX_MASTER_EN | PLX_SLAVE_EN_N);1302pv &= ~PLX_SYNC_O_EN;1303if (debug & DEBUG_HFCMULTI_INIT)1304printk(KERN_DEBUG "%s: slave: PLX_GPIO=%x\n",1305__func__, pv);1306}1307writel(pv, plx_acc_32);1308spin_unlock_irqrestore(&plx_lock, plx_flags);1309}13101311/* PCM setup */1312HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x90);1313if (hc->slots == 32)1314HFC_outb(hc, R_PCM_MD1, 0x00);1315if (hc->slots == 64)1316HFC_outb(hc, R_PCM_MD1, 0x10);1317if (hc->slots == 128)1318HFC_outb(hc, R_PCM_MD1, 0x20);1319HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0xa0);1320if (test_bit(HFC_CHIP_PLXSD, &hc->chip))1321HFC_outb(hc, R_PCM_MD2, V_SYNC_SRC); /* sync via SYNC_I / O */1322else if (test_bit(HFC_CHIP_EMBSD, &hc->chip))1323HFC_outb(hc, R_PCM_MD2, 0x10); /* V_C2O_EN */1324else1325HFC_outb(hc, R_PCM_MD2, 0x00); /* sync from interface */1326HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00);1327for (i = 0; i < 256; i++) {1328HFC_outb_nodebug(hc, R_SLOT, i);1329HFC_outb_nodebug(hc, A_SL_CFG, 0);1330if (hc->ctype != HFC_TYPE_XHFC)1331HFC_outb_nodebug(hc, A_CONF, 0);1332hc->slot_owner[i] = -1;1333}13341335/* set clock speed */1336if (test_bit(HFC_CHIP_CLOCK2, &hc->chip)) {1337if (debug & DEBUG_HFCMULTI_INIT)1338printk(KERN_DEBUG1339"%s: setting double clock\n", __func__);1340HFC_outb(hc, R_BRG_PCM_CFG, V_PCM_CLK);1341}13421343if (test_bit(HFC_CHIP_EMBSD, &hc->chip))1344HFC_outb(hc, 0x02 /* R_CLK_CFG */, 0x40 /* V_CLKO_OFF */);13451346/* B410P GPIO */1347if (test_bit(HFC_CHIP_B410P, &hc->chip)) {1348printk(KERN_NOTICE "Setting GPIOs\n");1349HFC_outb(hc, R_GPIO_SEL, 0x30);1350HFC_outb(hc, R_GPIO_EN1, 0x3);1351udelay(1000);1352printk(KERN_NOTICE "calling vpm_init\n");1353vpm_init(hc);1354}13551356/* check if R_F0_CNT counts (8 kHz frame count) */1357val = HFC_inb(hc, R_F0_CNTL);1358val += HFC_inb(hc, R_F0_CNTH) << 8;1359if (debug & DEBUG_HFCMULTI_INIT)1360printk(KERN_DEBUG1361"HFC_multi F0_CNT %ld after reset\n", val);1362spin_unlock_irqrestore(&hc->lock, flags);1363set_current_state(TASK_UNINTERRUPTIBLE);1364schedule_timeout((HZ/100)?:1); /* Timeout minimum 10ms */1365spin_lock_irqsave(&hc->lock, flags);1366val2 = HFC_inb(hc, R_F0_CNTL);1367val2 += HFC_inb(hc, R_F0_CNTH) << 8;1368if (debug & DEBUG_HFCMULTI_INIT)1369printk(KERN_DEBUG1370"HFC_multi F0_CNT %ld after 10 ms (1st try)\n",1371val2);1372if (val2 >= val+8) { /* 1 ms */1373/* it counts, so we keep the pcm mode */1374if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip))1375printk(KERN_INFO "controller is PCM bus MASTER\n");1376else1377if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip))1378printk(KERN_INFO "controller is PCM bus SLAVE\n");1379else {1380test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip);1381printk(KERN_INFO "controller is PCM bus SLAVE "1382"(auto detected)\n");1383}1384} else {1385/* does not count */1386if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) {1387controller_fail:1388printk(KERN_ERR "HFC_multi ERROR, getting no 125us "1389"pulse. Seems that controller fails.\n");1390err = -EIO;1391goto out;1392}1393if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) {1394printk(KERN_INFO "controller is PCM bus SLAVE "1395"(ignoring missing PCM clock)\n");1396} else {1397/* only one pcm master */1398if (test_bit(HFC_CHIP_PLXSD, &hc->chip)1399&& plxsd_master) {1400printk(KERN_ERR "HFC_multi ERROR, no clock "1401"on another Speech Design card found. "1402"Please be sure to connect PCM cable.\n");1403err = -EIO;1404goto out;1405}1406/* retry with master clock */1407if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {1408spin_lock_irqsave(&plx_lock, plx_flags);1409plx_acc_32 = hc->plx_membase + PLX_GPIOC;1410pv = readl(plx_acc_32);1411pv |= PLX_MASTER_EN | PLX_SLAVE_EN_N;1412pv |= PLX_SYNC_O_EN;1413writel(pv, plx_acc_32);1414spin_unlock_irqrestore(&plx_lock, plx_flags);1415if (debug & DEBUG_HFCMULTI_INIT)1416printk(KERN_DEBUG "%s: master: "1417"PLX_GPIO=%x\n", __func__, pv);1418}1419hc->hw.r_pcm_md0 |= V_PCM_MD;1420HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00);1421spin_unlock_irqrestore(&hc->lock, flags);1422set_current_state(TASK_UNINTERRUPTIBLE);1423schedule_timeout((HZ/100)?:1); /* Timeout min. 10ms */1424spin_lock_irqsave(&hc->lock, flags);1425val2 = HFC_inb(hc, R_F0_CNTL);1426val2 += HFC_inb(hc, R_F0_CNTH) << 8;1427if (debug & DEBUG_HFCMULTI_INIT)1428printk(KERN_DEBUG "HFC_multi F0_CNT %ld after "1429"10 ms (2nd try)\n", val2);1430if (val2 >= val+8) { /* 1 ms */1431test_and_set_bit(HFC_CHIP_PCM_MASTER,1432&hc->chip);1433printk(KERN_INFO "controller is PCM bus MASTER "1434"(auto detected)\n");1435} else1436goto controller_fail;1437}1438}14391440/* Release the DSP Reset */1441if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {1442if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip))1443plxsd_master = 1;1444spin_lock_irqsave(&plx_lock, plx_flags);1445plx_acc_32 = hc->plx_membase + PLX_GPIOC;1446pv = readl(plx_acc_32);1447pv |= PLX_DSP_RES_N;1448writel(pv, plx_acc_32);1449spin_unlock_irqrestore(&plx_lock, plx_flags);1450if (debug & DEBUG_HFCMULTI_INIT)1451printk(KERN_DEBUG "%s: reset off: PLX_GPIO=%x\n",1452__func__, pv);1453}14541455/* pcm id */1456if (hc->pcm)1457printk(KERN_INFO "controller has given PCM BUS ID %d\n",1458hc->pcm);1459else {1460if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)1461|| test_bit(HFC_CHIP_PLXSD, &hc->chip)) {1462PCM_cnt++; /* SD has proprietary bridging */1463}1464hc->pcm = PCM_cnt;1465printk(KERN_INFO "controller has PCM BUS ID %d "1466"(auto selected)\n", hc->pcm);1467}14681469/* set up timer */1470HFC_outb(hc, R_TI_WD, poll_timer);1471hc->hw.r_irqmsk_misc |= V_TI_IRQMSK;14721473/* set E1 state machine IRQ */1474if (hc->ctype == HFC_TYPE_E1)1475hc->hw.r_irqmsk_misc |= V_STA_IRQMSK;14761477/* set DTMF detection */1478if (test_bit(HFC_CHIP_DTMF, &hc->chip)) {1479if (debug & DEBUG_HFCMULTI_INIT)1480printk(KERN_DEBUG "%s: enabling DTMF detection "1481"for all B-channel\n", __func__);1482hc->hw.r_dtmf = V_DTMF_EN | V_DTMF_STOP;1483if (test_bit(HFC_CHIP_ULAW, &hc->chip))1484hc->hw.r_dtmf |= V_ULAW_SEL;1485HFC_outb(hc, R_DTMF_N, 102 - 1);1486hc->hw.r_irqmsk_misc |= V_DTMF_IRQMSK;1487}14881489/* conference engine */1490if (test_bit(HFC_CHIP_ULAW, &hc->chip))1491r_conf_en = V_CONF_EN | V_ULAW;1492else1493r_conf_en = V_CONF_EN;1494if (hc->ctype != HFC_TYPE_XHFC)1495HFC_outb(hc, R_CONF_EN, r_conf_en);14961497/* setting leds */1498switch (hc->leds) {1499case 1: /* HFC-E1 OEM */1500if (test_bit(HFC_CHIP_WATCHDOG, &hc->chip))1501HFC_outb(hc, R_GPIO_SEL, 0x32);1502else1503HFC_outb(hc, R_GPIO_SEL, 0x30);15041505HFC_outb(hc, R_GPIO_EN1, 0x0f);1506HFC_outb(hc, R_GPIO_OUT1, 0x00);15071508HFC_outb(hc, R_GPIO_EN0, V_GPIO_EN2 | V_GPIO_EN3);1509break;15101511case 2: /* HFC-4S OEM */1512case 3:1513HFC_outb(hc, R_GPIO_SEL, 0xf0);1514HFC_outb(hc, R_GPIO_EN1, 0xff);1515HFC_outb(hc, R_GPIO_OUT1, 0x00);1516break;1517}15181519if (test_bit(HFC_CHIP_EMBSD, &hc->chip)) {1520hc->hw.r_st_sync = 0x10; /* V_AUTO_SYNCI */1521HFC_outb(hc, R_ST_SYNC, hc->hw.r_st_sync);1522}15231524/* set master clock */1525if (hc->masterclk >= 0) {1526if (debug & DEBUG_HFCMULTI_INIT)1527printk(KERN_DEBUG "%s: setting ST master clock "1528"to port %d (0..%d)\n",1529__func__, hc->masterclk, hc->ports-1);1530hc->hw.r_st_sync |= (hc->masterclk | V_AUTO_SYNC);1531HFC_outb(hc, R_ST_SYNC, hc->hw.r_st_sync);1532}1533153415351536/* setting misc irq */1537HFC_outb(hc, R_IRQMSK_MISC, hc->hw.r_irqmsk_misc);1538if (debug & DEBUG_HFCMULTI_INIT)1539printk(KERN_DEBUG "r_irqmsk_misc.2: 0x%x\n",1540hc->hw.r_irqmsk_misc);15411542/* RAM access test */1543HFC_outb(hc, R_RAM_ADDR0, 0);1544HFC_outb(hc, R_RAM_ADDR1, 0);1545HFC_outb(hc, R_RAM_ADDR2, 0);1546for (i = 0; i < 256; i++) {1547HFC_outb_nodebug(hc, R_RAM_ADDR0, i);1548HFC_outb_nodebug(hc, R_RAM_DATA, ((i*3)&0xff));1549}1550for (i = 0; i < 256; i++) {1551HFC_outb_nodebug(hc, R_RAM_ADDR0, i);1552HFC_inb_nodebug(hc, R_RAM_DATA);1553rval = HFC_inb_nodebug(hc, R_INT_DATA);1554if (rval != ((i * 3) & 0xff)) {1555printk(KERN_DEBUG1556"addr:%x val:%x should:%x\n", i, rval,1557(i * 3) & 0xff);1558err++;1559}1560}1561if (err) {1562printk(KERN_DEBUG "aborting - %d RAM access errors\n", err);1563err = -EIO;1564goto out;1565}15661567if (debug & DEBUG_HFCMULTI_INIT)1568printk(KERN_DEBUG "%s: done\n", __func__);1569out:1570spin_unlock_irqrestore(&hc->lock, flags);1571return err;1572}157315741575/*1576* control the watchdog1577*/1578static void1579hfcmulti_watchdog(struct hfc_multi *hc)1580{1581hc->wdcount++;15821583if (hc->wdcount > 10) {1584hc->wdcount = 0;1585hc->wdbyte = hc->wdbyte == V_GPIO_OUT2 ?1586V_GPIO_OUT3 : V_GPIO_OUT2;15871588/* printk("Sending Watchdog Kill %x\n",hc->wdbyte); */1589HFC_outb(hc, R_GPIO_EN0, V_GPIO_EN2 | V_GPIO_EN3);1590HFC_outb(hc, R_GPIO_OUT0, hc->wdbyte);1591}1592}1593159415951596/*1597* output leds1598*/1599static void1600hfcmulti_leds(struct hfc_multi *hc)1601{1602unsigned long lled;1603unsigned long leddw;1604int i, state, active, leds;1605struct dchannel *dch;1606int led[4];16071608hc->ledcount += poll;1609if (hc->ledcount > 4096) {1610hc->ledcount -= 4096;1611hc->ledstate = 0xAFFEAFFE;1612}16131614switch (hc->leds) {1615case 1: /* HFC-E1 OEM */1616/* 2 red blinking: NT mode deactivate1617* 2 red steady: TE mode deactivate1618* left green: L1 active1619* left red: frame sync, but no L11620* right green: L2 active1621*/1622if (hc->chan[hc->dslot].sync != 2) { /* no frame sync */1623if (hc->chan[hc->dslot].dch->dev.D.protocol1624!= ISDN_P_NT_E1) {1625led[0] = 1;1626led[1] = 1;1627} else if (hc->ledcount>>11) {1628led[0] = 1;1629led[1] = 1;1630} else {1631led[0] = 0;1632led[1] = 0;1633}1634led[2] = 0;1635led[3] = 0;1636} else { /* with frame sync */1637/* TODO make it work */1638led[0] = 0;1639led[1] = 0;1640led[2] = 0;1641led[3] = 1;1642}1643leds = (led[0] | (led[1]<<2) | (led[2]<<1) | (led[3]<<3))^0xF;1644/* leds are inverted */1645if (leds != (int)hc->ledstate) {1646HFC_outb_nodebug(hc, R_GPIO_OUT1, leds);1647hc->ledstate = leds;1648}1649break;16501651case 2: /* HFC-4S OEM */1652/* red blinking = PH_DEACTIVATE NT Mode1653* red steady = PH_DEACTIVATE TE Mode1654* green steady = PH_ACTIVATE1655*/1656for (i = 0; i < 4; i++) {1657state = 0;1658active = -1;1659dch = hc->chan[(i << 2) | 2].dch;1660if (dch) {1661state = dch->state;1662if (dch->dev.D.protocol == ISDN_P_NT_S0)1663active = 3;1664else1665active = 7;1666}1667if (state) {1668if (state == active) {1669led[i] = 1; /* led green */1670} else1671if (dch->dev.D.protocol == ISDN_P_TE_S0)1672/* TE mode: led red */1673led[i] = 2;1674else1675if (hc->ledcount>>11)1676/* led red */1677led[i] = 2;1678else1679/* led off */1680led[i] = 0;1681} else1682led[i] = 0; /* led off */1683}1684if (test_bit(HFC_CHIP_B410P, &hc->chip)) {1685leds = 0;1686for (i = 0; i < 4; i++) {1687if (led[i] == 1) {1688/*green*/1689leds |= (0x2 << (i * 2));1690} else if (led[i] == 2) {1691/*red*/1692leds |= (0x1 << (i * 2));1693}1694}1695if (leds != (int)hc->ledstate) {1696vpm_out(hc, 0, 0x1a8 + 3, leds);1697hc->ledstate = leds;1698}1699} else {1700leds = ((led[3] > 0) << 0) | ((led[1] > 0) << 1) |1701((led[0] > 0) << 2) | ((led[2] > 0) << 3) |1702((led[3] & 1) << 4) | ((led[1] & 1) << 5) |1703((led[0] & 1) << 6) | ((led[2] & 1) << 7);1704if (leds != (int)hc->ledstate) {1705HFC_outb_nodebug(hc, R_GPIO_EN1, leds & 0x0F);1706HFC_outb_nodebug(hc, R_GPIO_OUT1, leds >> 4);1707hc->ledstate = leds;1708}1709}1710break;17111712case 3: /* HFC 1S/2S Beronet */1713/* red blinking = PH_DEACTIVATE NT Mode1714* red steady = PH_DEACTIVATE TE Mode1715* green steady = PH_ACTIVATE1716*/1717for (i = 0; i < 2; i++) {1718state = 0;1719active = -1;1720dch = hc->chan[(i << 2) | 2].dch;1721if (dch) {1722state = dch->state;1723if (dch->dev.D.protocol == ISDN_P_NT_S0)1724active = 3;1725else1726active = 7;1727}1728if (state) {1729if (state == active) {1730led[i] = 1; /* led green */1731} else1732if (dch->dev.D.protocol == ISDN_P_TE_S0)1733/* TE mode: led red */1734led[i] = 2;1735else1736if (hc->ledcount >> 11)1737/* led red */1738led[i] = 2;1739else1740/* led off */1741led[i] = 0;1742} else1743led[i] = 0; /* led off */1744}174517461747leds = (led[0] > 0) | ((led[1] > 0)<<1) | ((led[0]&1)<<2)1748| ((led[1]&1)<<3);1749if (leds != (int)hc->ledstate) {1750HFC_outb_nodebug(hc, R_GPIO_EN1,1751((led[0] > 0) << 2) | ((led[1] > 0) << 3));1752HFC_outb_nodebug(hc, R_GPIO_OUT1,1753((led[0] & 1) << 2) | ((led[1] & 1) << 3));1754hc->ledstate = leds;1755}1756break;1757case 8: /* HFC 8S+ Beronet */1758lled = 0;17591760for (i = 0; i < 8; i++) {1761state = 0;1762active = -1;1763dch = hc->chan[(i << 2) | 2].dch;1764if (dch) {1765state = dch->state;1766if (dch->dev.D.protocol == ISDN_P_NT_S0)1767active = 3;1768else1769active = 7;1770}1771if (state) {1772if (state == active) {1773lled |= 0 << i;1774} else1775if (hc->ledcount >> 11)1776lled |= 0 << i;1777else1778lled |= 1 << i;1779} else1780lled |= 1 << i;1781}1782leddw = lled << 24 | lled << 16 | lled << 8 | lled;1783if (leddw != hc->ledstate) {1784/* HFC_outb(hc, R_BRG_PCM_CFG, 1);1785HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x3); */1786/* was _io before */1787HFC_outb_nodebug(hc, R_BRG_PCM_CFG, 1 | V_PCM_CLK);1788outw(0x4000, hc->pci_iobase + 4);1789outl(leddw, hc->pci_iobase);1790HFC_outb_nodebug(hc, R_BRG_PCM_CFG, V_PCM_CLK);1791hc->ledstate = leddw;1792}1793break;1794}1795}1796/*1797* read dtmf coefficients1798*/17991800static void1801hfcmulti_dtmf(struct hfc_multi *hc)1802{1803s32 *coeff;1804u_int mantissa;1805int co, ch;1806struct bchannel *bch = NULL;1807u8 exponent;1808int dtmf = 0;1809int addr;1810u16 w_float;1811struct sk_buff *skb;1812struct mISDNhead *hh;18131814if (debug & DEBUG_HFCMULTI_DTMF)1815printk(KERN_DEBUG "%s: dtmf detection irq\n", __func__);1816for (ch = 0; ch <= 31; ch++) {1817/* only process enabled B-channels */1818bch = hc->chan[ch].bch;1819if (!bch)1820continue;1821if (!hc->created[hc->chan[ch].port])1822continue;1823if (!test_bit(FLG_TRANSPARENT, &bch->Flags))1824continue;1825if (debug & DEBUG_HFCMULTI_DTMF)1826printk(KERN_DEBUG "%s: dtmf channel %d:",1827__func__, ch);1828coeff = &(hc->chan[ch].coeff[hc->chan[ch].coeff_count * 16]);1829dtmf = 1;1830for (co = 0; co < 8; co++) {1831/* read W(n-1) coefficient */1832addr = hc->DTMFbase + ((co<<7) | (ch<<2));1833HFC_outb_nodebug(hc, R_RAM_ADDR0, addr);1834HFC_outb_nodebug(hc, R_RAM_ADDR1, addr>>8);1835HFC_outb_nodebug(hc, R_RAM_ADDR2, (addr>>16)1836| V_ADDR_INC);1837w_float = HFC_inb_nodebug(hc, R_RAM_DATA);1838w_float |= (HFC_inb_nodebug(hc, R_RAM_DATA) << 8);1839if (debug & DEBUG_HFCMULTI_DTMF)1840printk(" %04x", w_float);18411842/* decode float (see chip doc) */1843mantissa = w_float & 0x0fff;1844if (w_float & 0x8000)1845mantissa |= 0xfffff000;1846exponent = (w_float>>12) & 0x7;1847if (exponent) {1848mantissa ^= 0x1000;1849mantissa <<= (exponent-1);1850}18511852/* store coefficient */1853coeff[co<<1] = mantissa;18541855/* read W(n) coefficient */1856w_float = HFC_inb_nodebug(hc, R_RAM_DATA);1857w_float |= (HFC_inb_nodebug(hc, R_RAM_DATA) << 8);1858if (debug & DEBUG_HFCMULTI_DTMF)1859printk(" %04x", w_float);18601861/* decode float (see chip doc) */1862mantissa = w_float & 0x0fff;1863if (w_float & 0x8000)1864mantissa |= 0xfffff000;1865exponent = (w_float>>12) & 0x7;1866if (exponent) {1867mantissa ^= 0x1000;1868mantissa <<= (exponent-1);1869}18701871/* store coefficient */1872coeff[(co<<1)|1] = mantissa;1873}1874if (debug & DEBUG_HFCMULTI_DTMF)1875printk(" DTMF ready %08x %08x %08x %08x "1876"%08x %08x %08x %08x\n",1877coeff[0], coeff[1], coeff[2], coeff[3],1878coeff[4], coeff[5], coeff[6], coeff[7]);1879hc->chan[ch].coeff_count++;1880if (hc->chan[ch].coeff_count == 8) {1881hc->chan[ch].coeff_count = 0;1882skb = mI_alloc_skb(512, GFP_ATOMIC);1883if (!skb) {1884printk(KERN_DEBUG "%s: No memory for skb\n",1885__func__);1886continue;1887}1888hh = mISDN_HEAD_P(skb);1889hh->prim = PH_CONTROL_IND;1890hh->id = DTMF_HFC_COEF;1891memcpy(skb_put(skb, 512), hc->chan[ch].coeff, 512);1892recv_Bchannel_skb(bch, skb);1893}1894}18951896/* restart DTMF processing */1897hc->dtmf = dtmf;1898if (dtmf)1899HFC_outb_nodebug(hc, R_DTMF, hc->hw.r_dtmf | V_RST_DTMF);1900}190119021903/*1904* fill fifo as much as possible1905*/19061907static void1908hfcmulti_tx(struct hfc_multi *hc, int ch)1909{1910int i, ii, temp, len = 0;1911int Zspace, z1, z2; /* must be int for calculation */1912int Fspace, f1, f2;1913u_char *d;1914int *txpending, slot_tx;1915struct bchannel *bch;1916struct dchannel *dch;1917struct sk_buff **sp = NULL;1918int *idxp;19191920bch = hc->chan[ch].bch;1921dch = hc->chan[ch].dch;1922if ((!dch) && (!bch))1923return;19241925txpending = &hc->chan[ch].txpending;1926slot_tx = hc->chan[ch].slot_tx;1927if (dch) {1928if (!test_bit(FLG_ACTIVE, &dch->Flags))1929return;1930sp = &dch->tx_skb;1931idxp = &dch->tx_idx;1932} else {1933if (!test_bit(FLG_ACTIVE, &bch->Flags))1934return;1935sp = &bch->tx_skb;1936idxp = &bch->tx_idx;1937}1938if (*sp)1939len = (*sp)->len;19401941if ((!len) && *txpending != 1)1942return; /* no data */19431944if (test_bit(HFC_CHIP_B410P, &hc->chip) &&1945(hc->chan[ch].protocol == ISDN_P_B_RAW) &&1946(hc->chan[ch].slot_rx < 0) &&1947(hc->chan[ch].slot_tx < 0))1948HFC_outb_nodebug(hc, R_FIFO, 0x20 | (ch << 1));1949else1950HFC_outb_nodebug(hc, R_FIFO, ch << 1);1951HFC_wait_nodebug(hc);19521953if (*txpending == 2) {1954/* reset fifo */1955HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F);1956HFC_wait_nodebug(hc);1957HFC_outb(hc, A_SUBCH_CFG, 0);1958*txpending = 1;1959}1960next_frame:1961if (dch || test_bit(FLG_HDLC, &bch->Flags)) {1962f1 = HFC_inb_nodebug(hc, A_F1);1963f2 = HFC_inb_nodebug(hc, A_F2);1964while (f2 != (temp = HFC_inb_nodebug(hc, A_F2))) {1965if (debug & DEBUG_HFCMULTI_FIFO)1966printk(KERN_DEBUG1967"%s(card %d): reread f2 because %d!=%d\n",1968__func__, hc->id + 1, temp, f2);1969f2 = temp; /* repeat until F2 is equal */1970}1971Fspace = f2 - f1 - 1;1972if (Fspace < 0)1973Fspace += hc->Flen;1974/*1975* Old FIFO handling doesn't give us the current Z2 read1976* pointer, so we cannot send the next frame before the fifo1977* is empty. It makes no difference except for a slightly1978* lower performance.1979*/1980if (test_bit(HFC_CHIP_REVISION0, &hc->chip)) {1981if (f1 != f2)1982Fspace = 0;1983else1984Fspace = 1;1985}1986/* one frame only for ST D-channels, to allow resending */1987if (hc->ctype != HFC_TYPE_E1 && dch) {1988if (f1 != f2)1989Fspace = 0;1990}1991/* F-counter full condition */1992if (Fspace == 0)1993return;1994}1995z1 = HFC_inw_nodebug(hc, A_Z1) - hc->Zmin;1996z2 = HFC_inw_nodebug(hc, A_Z2) - hc->Zmin;1997while (z2 != (temp = (HFC_inw_nodebug(hc, A_Z2) - hc->Zmin))) {1998if (debug & DEBUG_HFCMULTI_FIFO)1999printk(KERN_DEBUG "%s(card %d): reread z2 because "2000"%d!=%d\n", __func__, hc->id + 1, temp, z2);2001z2 = temp; /* repeat unti Z2 is equal */2002}2003hc->chan[ch].Zfill = z1 - z2;2004if (hc->chan[ch].Zfill < 0)2005hc->chan[ch].Zfill += hc->Zlen;2006Zspace = z2 - z1;2007if (Zspace <= 0)2008Zspace += hc->Zlen;2009Zspace -= 4; /* keep not too full, so pointers will not overrun */2010/* fill transparent data only to maxinum transparent load (minus 4) */2011if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags))2012Zspace = Zspace - hc->Zlen + hc->max_trans;2013if (Zspace <= 0) /* no space of 4 bytes */2014return;20152016/* if no data */2017if (!len) {2018if (z1 == z2) { /* empty */2019/* if done with FIFO audio data during PCM connection */2020if (bch && (!test_bit(FLG_HDLC, &bch->Flags)) &&2021*txpending && slot_tx >= 0) {2022if (debug & DEBUG_HFCMULTI_MODE)2023printk(KERN_DEBUG2024"%s: reconnecting PCM due to no "2025"more FIFO data: channel %d "2026"slot_tx %d\n",2027__func__, ch, slot_tx);2028/* connect slot */2029if (hc->ctype == HFC_TYPE_XHFC)2030HFC_outb(hc, A_CON_HDLC, 0xc02031| 0x07 << 2 | V_HDLC_TRP | V_IFF);2032/* Enable FIFO, no interrupt */2033else2034HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 |2035V_HDLC_TRP | V_IFF);2036HFC_outb_nodebug(hc, R_FIFO, ch<<1 | 1);2037HFC_wait_nodebug(hc);2038if (hc->ctype == HFC_TYPE_XHFC)2039HFC_outb(hc, A_CON_HDLC, 0xc02040| 0x07 << 2 | V_HDLC_TRP | V_IFF);2041/* Enable FIFO, no interrupt */2042else2043HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 |2044V_HDLC_TRP | V_IFF);2045HFC_outb_nodebug(hc, R_FIFO, ch<<1);2046HFC_wait_nodebug(hc);2047}2048*txpending = 0;2049}2050return; /* no data */2051}20522053/* "fill fifo if empty" feature */2054if (bch && test_bit(FLG_FILLEMPTY, &bch->Flags)2055&& !test_bit(FLG_HDLC, &bch->Flags) && z2 == z1) {2056if (debug & DEBUG_HFCMULTI_FILL)2057printk(KERN_DEBUG "%s: buffer empty, so we have "2058"underrun\n", __func__);2059/* fill buffer, to prevent future underrun */2060hc->write_fifo(hc, hc->silence_data, poll >> 1);2061Zspace -= (poll >> 1);2062}20632064/* if audio data and connected slot */2065if (bch && (!test_bit(FLG_HDLC, &bch->Flags)) && (!*txpending)2066&& slot_tx >= 0) {2067if (debug & DEBUG_HFCMULTI_MODE)2068printk(KERN_DEBUG "%s: disconnecting PCM due to "2069"FIFO data: channel %d slot_tx %d\n",2070__func__, ch, slot_tx);2071/* disconnect slot */2072if (hc->ctype == HFC_TYPE_XHFC)2073HFC_outb(hc, A_CON_HDLC, 0x802074| 0x07 << 2 | V_HDLC_TRP | V_IFF);2075/* Enable FIFO, no interrupt */2076else2077HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 |2078V_HDLC_TRP | V_IFF);2079HFC_outb_nodebug(hc, R_FIFO, ch<<1 | 1);2080HFC_wait_nodebug(hc);2081if (hc->ctype == HFC_TYPE_XHFC)2082HFC_outb(hc, A_CON_HDLC, 0x802083| 0x07 << 2 | V_HDLC_TRP | V_IFF);2084/* Enable FIFO, no interrupt */2085else2086HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 |2087V_HDLC_TRP | V_IFF);2088HFC_outb_nodebug(hc, R_FIFO, ch<<1);2089HFC_wait_nodebug(hc);2090}2091*txpending = 1;20922093/* show activity */2094hc->activity[hc->chan[ch].port] = 1;20952096/* fill fifo to what we have left */2097ii = len;2098if (dch || test_bit(FLG_HDLC, &bch->Flags))2099temp = 1;2100else2101temp = 0;2102i = *idxp;2103d = (*sp)->data + i;2104if (ii - i > Zspace)2105ii = Zspace + i;2106if (debug & DEBUG_HFCMULTI_FIFO)2107printk(KERN_DEBUG "%s(card %d): fifo(%d) has %d bytes space "2108"left (z1=%04x, z2=%04x) sending %d of %d bytes %s\n",2109__func__, hc->id + 1, ch, Zspace, z1, z2, ii-i, len-i,2110temp ? "HDLC" : "TRANS");21112112/* Have to prep the audio data */2113hc->write_fifo(hc, d, ii - i);2114hc->chan[ch].Zfill += ii - i;2115*idxp = ii;21162117/* if not all data has been written */2118if (ii != len) {2119/* NOTE: fifo is started by the calling function */2120return;2121}21222123/* if all data has been written, terminate frame */2124if (dch || test_bit(FLG_HDLC, &bch->Flags)) {2125/* increment f-counter */2126HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_INC_F);2127HFC_wait_nodebug(hc);2128}21292130/* send confirm, since get_net_bframe will not do it with trans */2131if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags))2132confirm_Bsend(bch);21332134/* check for next frame */2135dev_kfree_skb(*sp);2136if (bch && get_next_bframe(bch)) { /* hdlc is confirmed here */2137len = (*sp)->len;2138goto next_frame;2139}2140if (dch && get_next_dframe(dch)) {2141len = (*sp)->len;2142goto next_frame;2143}21442145/*2146* now we have no more data, so in case of transparent,2147* we set the last byte in fifo to 'silence' in case we will get2148* no more data at all. this prevents sending an undefined value.2149*/2150if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags))2151HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);2152}215321542155/* NOTE: only called if E1 card is in active state */2156static void2157hfcmulti_rx(struct hfc_multi *hc, int ch)2158{2159int temp;2160int Zsize, z1, z2 = 0; /* = 0, to make GCC happy */2161int f1 = 0, f2 = 0; /* = 0, to make GCC happy */2162int again = 0;2163struct bchannel *bch;2164struct dchannel *dch;2165struct sk_buff *skb, **sp = NULL;2166int maxlen;21672168bch = hc->chan[ch].bch;2169dch = hc->chan[ch].dch;2170if ((!dch) && (!bch))2171return;2172if (dch) {2173if (!test_bit(FLG_ACTIVE, &dch->Flags))2174return;2175sp = &dch->rx_skb;2176maxlen = dch->maxlen;2177} else {2178if (!test_bit(FLG_ACTIVE, &bch->Flags))2179return;2180sp = &bch->rx_skb;2181maxlen = bch->maxlen;2182}2183next_frame:2184/* on first AND before getting next valid frame, R_FIFO must be written2185to. */2186if (test_bit(HFC_CHIP_B410P, &hc->chip) &&2187(hc->chan[ch].protocol == ISDN_P_B_RAW) &&2188(hc->chan[ch].slot_rx < 0) &&2189(hc->chan[ch].slot_tx < 0))2190HFC_outb_nodebug(hc, R_FIFO, 0x20 | (ch<<1) | 1);2191else2192HFC_outb_nodebug(hc, R_FIFO, (ch<<1)|1);2193HFC_wait_nodebug(hc);21942195/* ignore if rx is off BUT change fifo (above) to start pending TX */2196if (hc->chan[ch].rx_off)2197return;21982199if (dch || test_bit(FLG_HDLC, &bch->Flags)) {2200f1 = HFC_inb_nodebug(hc, A_F1);2201while (f1 != (temp = HFC_inb_nodebug(hc, A_F1))) {2202if (debug & DEBUG_HFCMULTI_FIFO)2203printk(KERN_DEBUG2204"%s(card %d): reread f1 because %d!=%d\n",2205__func__, hc->id + 1, temp, f1);2206f1 = temp; /* repeat until F1 is equal */2207}2208f2 = HFC_inb_nodebug(hc, A_F2);2209}2210z1 = HFC_inw_nodebug(hc, A_Z1) - hc->Zmin;2211while (z1 != (temp = (HFC_inw_nodebug(hc, A_Z1) - hc->Zmin))) {2212if (debug & DEBUG_HFCMULTI_FIFO)2213printk(KERN_DEBUG "%s(card %d): reread z2 because "2214"%d!=%d\n", __func__, hc->id + 1, temp, z2);2215z1 = temp; /* repeat until Z1 is equal */2216}2217z2 = HFC_inw_nodebug(hc, A_Z2) - hc->Zmin;2218Zsize = z1 - z2;2219if ((dch || test_bit(FLG_HDLC, &bch->Flags)) && f1 != f2)2220/* complete hdlc frame */2221Zsize++;2222if (Zsize < 0)2223Zsize += hc->Zlen;2224/* if buffer is empty */2225if (Zsize <= 0)2226return;22272228if (*sp == NULL) {2229*sp = mI_alloc_skb(maxlen + 3, GFP_ATOMIC);2230if (*sp == NULL) {2231printk(KERN_DEBUG "%s: No mem for rx_skb\n",2232__func__);2233return;2234}2235}2236/* show activity */2237hc->activity[hc->chan[ch].port] = 1;22382239/* empty fifo with what we have */2240if (dch || test_bit(FLG_HDLC, &bch->Flags)) {2241if (debug & DEBUG_HFCMULTI_FIFO)2242printk(KERN_DEBUG "%s(card %d): fifo(%d) reading %d "2243"bytes (z1=%04x, z2=%04x) HDLC %s (f1=%d, f2=%d) "2244"got=%d (again %d)\n", __func__, hc->id + 1, ch,2245Zsize, z1, z2, (f1 == f2) ? "fragment" : "COMPLETE",2246f1, f2, Zsize + (*sp)->len, again);2247/* HDLC */2248if ((Zsize + (*sp)->len) > (maxlen + 3)) {2249if (debug & DEBUG_HFCMULTI_FIFO)2250printk(KERN_DEBUG2251"%s(card %d): hdlc-frame too large.\n",2252__func__, hc->id + 1);2253skb_trim(*sp, 0);2254HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F);2255HFC_wait_nodebug(hc);2256return;2257}22582259hc->read_fifo(hc, skb_put(*sp, Zsize), Zsize);22602261if (f1 != f2) {2262/* increment Z2,F2-counter */2263HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_INC_F);2264HFC_wait_nodebug(hc);2265/* check size */2266if ((*sp)->len < 4) {2267if (debug & DEBUG_HFCMULTI_FIFO)2268printk(KERN_DEBUG2269"%s(card %d): Frame below minimum "2270"size\n", __func__, hc->id + 1);2271skb_trim(*sp, 0);2272goto next_frame;2273}2274/* there is at least one complete frame, check crc */2275if ((*sp)->data[(*sp)->len - 1]) {2276if (debug & DEBUG_HFCMULTI_CRC)2277printk(KERN_DEBUG2278"%s: CRC-error\n", __func__);2279skb_trim(*sp, 0);2280goto next_frame;2281}2282skb_trim(*sp, (*sp)->len - 3);2283if ((*sp)->len < MISDN_COPY_SIZE) {2284skb = *sp;2285*sp = mI_alloc_skb(skb->len, GFP_ATOMIC);2286if (*sp) {2287memcpy(skb_put(*sp, skb->len),2288skb->data, skb->len);2289skb_trim(skb, 0);2290} else {2291printk(KERN_DEBUG "%s: No mem\n",2292__func__);2293*sp = skb;2294skb = NULL;2295}2296} else {2297skb = NULL;2298}2299if (debug & DEBUG_HFCMULTI_FIFO) {2300printk(KERN_DEBUG "%s(card %d):",2301__func__, hc->id + 1);2302temp = 0;2303while (temp < (*sp)->len)2304printk(" %02x", (*sp)->data[temp++]);2305printk("\n");2306}2307if (dch)2308recv_Dchannel(dch);2309else2310recv_Bchannel(bch, MISDN_ID_ANY);2311*sp = skb;2312again++;2313goto next_frame;2314}2315/* there is an incomplete frame */2316} else {2317/* transparent */2318if (Zsize > skb_tailroom(*sp))2319Zsize = skb_tailroom(*sp);2320hc->read_fifo(hc, skb_put(*sp, Zsize), Zsize);2321if (((*sp)->len) < MISDN_COPY_SIZE) {2322skb = *sp;2323*sp = mI_alloc_skb(skb->len, GFP_ATOMIC);2324if (*sp) {2325memcpy(skb_put(*sp, skb->len),2326skb->data, skb->len);2327skb_trim(skb, 0);2328} else {2329printk(KERN_DEBUG "%s: No mem\n", __func__);2330*sp = skb;2331skb = NULL;2332}2333} else {2334skb = NULL;2335}2336if (debug & DEBUG_HFCMULTI_FIFO)2337printk(KERN_DEBUG2338"%s(card %d): fifo(%d) reading %d bytes "2339"(z1=%04x, z2=%04x) TRANS\n",2340__func__, hc->id + 1, ch, Zsize, z1, z2);2341/* only bch is transparent */2342recv_Bchannel(bch, hc->chan[ch].Zfill);2343*sp = skb;2344}2345}234623472348/*2349* Interrupt handler2350*/2351static void2352signal_state_up(struct dchannel *dch, int info, char *msg)2353{2354struct sk_buff *skb;2355int id, data = info;23562357if (debug & DEBUG_HFCMULTI_STATE)2358printk(KERN_DEBUG "%s: %s\n", __func__, msg);23592360id = TEI_SAPI | (GROUP_TEI << 8); /* manager address */23612362skb = _alloc_mISDN_skb(MPH_INFORMATION_IND, id, sizeof(data), &data,2363GFP_ATOMIC);2364if (!skb)2365return;2366recv_Dchannel_skb(dch, skb);2367}23682369static inline void2370handle_timer_irq(struct hfc_multi *hc)2371{2372int ch, temp;2373struct dchannel *dch;2374u_long flags;23752376/* process queued resync jobs */2377if (hc->e1_resync) {2378/* lock, so e1_resync gets not changed */2379spin_lock_irqsave(&HFClock, flags);2380if (hc->e1_resync & 1) {2381if (debug & DEBUG_HFCMULTI_PLXSD)2382printk(KERN_DEBUG "Enable SYNC_I\n");2383HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC);2384/* disable JATT, if RX_SYNC is set */2385if (test_bit(HFC_CHIP_RX_SYNC, &hc->chip))2386HFC_outb(hc, R_SYNC_OUT, V_SYNC_E1_RX);2387}2388if (hc->e1_resync & 2) {2389if (debug & DEBUG_HFCMULTI_PLXSD)2390printk(KERN_DEBUG "Enable jatt PLL\n");2391HFC_outb(hc, R_SYNC_CTRL, V_SYNC_OFFS);2392}2393if (hc->e1_resync & 4) {2394if (debug & DEBUG_HFCMULTI_PLXSD)2395printk(KERN_DEBUG2396"Enable QUARTZ for HFC-E1\n");2397/* set jatt to quartz */2398HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC2399| V_JATT_OFF);2400/* switch to JATT, in case it is not already */2401HFC_outb(hc, R_SYNC_OUT, 0);2402}2403hc->e1_resync = 0;2404spin_unlock_irqrestore(&HFClock, flags);2405}24062407if (hc->ctype != HFC_TYPE_E1 || hc->e1_state == 1)2408for (ch = 0; ch <= 31; ch++) {2409if (hc->created[hc->chan[ch].port]) {2410hfcmulti_tx(hc, ch);2411/* fifo is started when switching to rx-fifo */2412hfcmulti_rx(hc, ch);2413if (hc->chan[ch].dch &&2414hc->chan[ch].nt_timer > -1) {2415dch = hc->chan[ch].dch;2416if (!(--hc->chan[ch].nt_timer)) {2417schedule_event(dch,2418FLG_PHCHANGE);2419if (debug &2420DEBUG_HFCMULTI_STATE)2421printk(KERN_DEBUG2422"%s: nt_timer at "2423"state %x\n",2424__func__,2425dch->state);2426}2427}2428}2429}2430if (hc->ctype == HFC_TYPE_E1 && hc->created[0]) {2431dch = hc->chan[hc->dslot].dch;2432if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) {2433/* LOS */2434temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_SIG_LOS;2435if (!temp && hc->chan[hc->dslot].los)2436signal_state_up(dch, L1_SIGNAL_LOS_ON,2437"LOS detected");2438if (temp && !hc->chan[hc->dslot].los)2439signal_state_up(dch, L1_SIGNAL_LOS_OFF,2440"LOS gone");2441hc->chan[hc->dslot].los = temp;2442}2443if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dslot].cfg)) {2444/* AIS */2445temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_AIS;2446if (!temp && hc->chan[hc->dslot].ais)2447signal_state_up(dch, L1_SIGNAL_AIS_ON,2448"AIS detected");2449if (temp && !hc->chan[hc->dslot].ais)2450signal_state_up(dch, L1_SIGNAL_AIS_OFF,2451"AIS gone");2452hc->chan[hc->dslot].ais = temp;2453}2454if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dslot].cfg)) {2455/* SLIP */2456temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_RX;2457if (!temp && hc->chan[hc->dslot].slip_rx)2458signal_state_up(dch, L1_SIGNAL_SLIP_RX,2459" bit SLIP detected RX");2460hc->chan[hc->dslot].slip_rx = temp;2461temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_TX;2462if (!temp && hc->chan[hc->dslot].slip_tx)2463signal_state_up(dch, L1_SIGNAL_SLIP_TX,2464" bit SLIP detected TX");2465hc->chan[hc->dslot].slip_tx = temp;2466}2467if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dslot].cfg)) {2468/* RDI */2469temp = HFC_inb_nodebug(hc, R_RX_SL0_0) & V_A;2470if (!temp && hc->chan[hc->dslot].rdi)2471signal_state_up(dch, L1_SIGNAL_RDI_ON,2472"RDI detected");2473if (temp && !hc->chan[hc->dslot].rdi)2474signal_state_up(dch, L1_SIGNAL_RDI_OFF,2475"RDI gone");2476hc->chan[hc->dslot].rdi = temp;2477}2478temp = HFC_inb_nodebug(hc, R_JATT_DIR);2479switch (hc->chan[hc->dslot].sync) {2480case 0:2481if ((temp & 0x60) == 0x60) {2482if (debug & DEBUG_HFCMULTI_SYNC)2483printk(KERN_DEBUG2484"%s: (id=%d) E1 now "2485"in clock sync\n",2486__func__, hc->id);2487HFC_outb(hc, R_RX_OFF,2488hc->chan[hc->dslot].jitter | V_RX_INIT);2489HFC_outb(hc, R_TX_OFF,2490hc->chan[hc->dslot].jitter | V_RX_INIT);2491hc->chan[hc->dslot].sync = 1;2492goto check_framesync;2493}2494break;2495case 1:2496if ((temp & 0x60) != 0x60) {2497if (debug & DEBUG_HFCMULTI_SYNC)2498printk(KERN_DEBUG2499"%s: (id=%d) E1 "2500"lost clock sync\n",2501__func__, hc->id);2502hc->chan[hc->dslot].sync = 0;2503break;2504}2505check_framesync:2506temp = HFC_inb_nodebug(hc, R_SYNC_STA);2507if (temp == 0x27) {2508if (debug & DEBUG_HFCMULTI_SYNC)2509printk(KERN_DEBUG2510"%s: (id=%d) E1 "2511"now in frame sync\n",2512__func__, hc->id);2513hc->chan[hc->dslot].sync = 2;2514}2515break;2516case 2:2517if ((temp & 0x60) != 0x60) {2518if (debug & DEBUG_HFCMULTI_SYNC)2519printk(KERN_DEBUG2520"%s: (id=%d) E1 lost "2521"clock & frame sync\n",2522__func__, hc->id);2523hc->chan[hc->dslot].sync = 0;2524break;2525}2526temp = HFC_inb_nodebug(hc, R_SYNC_STA);2527if (temp != 0x27) {2528if (debug & DEBUG_HFCMULTI_SYNC)2529printk(KERN_DEBUG2530"%s: (id=%d) E1 "2531"lost frame sync\n",2532__func__, hc->id);2533hc->chan[hc->dslot].sync = 1;2534}2535break;2536}2537}25382539if (test_bit(HFC_CHIP_WATCHDOG, &hc->chip))2540hfcmulti_watchdog(hc);25412542if (hc->leds)2543hfcmulti_leds(hc);2544}25452546static void2547ph_state_irq(struct hfc_multi *hc, u_char r_irq_statech)2548{2549struct dchannel *dch;2550int ch;2551int active;2552u_char st_status, temp;25532554/* state machine */2555for (ch = 0; ch <= 31; ch++) {2556if (hc->chan[ch].dch) {2557dch = hc->chan[ch].dch;2558if (r_irq_statech & 1) {2559HFC_outb_nodebug(hc, R_ST_SEL,2560hc->chan[ch].port);2561/* undocumented: delay after R_ST_SEL */2562udelay(1);2563/* undocumented: status changes during read */2564st_status = HFC_inb_nodebug(hc, A_ST_RD_STATE);2565while (st_status != (temp =2566HFC_inb_nodebug(hc, A_ST_RD_STATE))) {2567if (debug & DEBUG_HFCMULTI_STATE)2568printk(KERN_DEBUG "%s: reread "2569"STATE because %d!=%d\n",2570__func__, temp,2571st_status);2572st_status = temp; /* repeat */2573}25742575/* Speech Design TE-sync indication */2576if (test_bit(HFC_CHIP_PLXSD, &hc->chip) &&2577dch->dev.D.protocol == ISDN_P_TE_S0) {2578if (st_status & V_FR_SYNC_ST)2579hc->syncronized |=2580(1 << hc->chan[ch].port);2581else2582hc->syncronized &=2583~(1 << hc->chan[ch].port);2584}2585dch->state = st_status & 0x0f;2586if (dch->dev.D.protocol == ISDN_P_NT_S0)2587active = 3;2588else2589active = 7;2590if (dch->state == active) {2591HFC_outb_nodebug(hc, R_FIFO,2592(ch << 1) | 1);2593HFC_wait_nodebug(hc);2594HFC_outb_nodebug(hc,2595R_INC_RES_FIFO, V_RES_F);2596HFC_wait_nodebug(hc);2597dch->tx_idx = 0;2598}2599schedule_event(dch, FLG_PHCHANGE);2600if (debug & DEBUG_HFCMULTI_STATE)2601printk(KERN_DEBUG2602"%s: S/T newstate %x port %d\n",2603__func__, dch->state,2604hc->chan[ch].port);2605}2606r_irq_statech >>= 1;2607}2608}2609if (test_bit(HFC_CHIP_PLXSD, &hc->chip))2610plxsd_checksync(hc, 0);2611}26122613static void2614fifo_irq(struct hfc_multi *hc, int block)2615{2616int ch, j;2617struct dchannel *dch;2618struct bchannel *bch;2619u_char r_irq_fifo_bl;26202621r_irq_fifo_bl = HFC_inb_nodebug(hc, R_IRQ_FIFO_BL0 + block);2622j = 0;2623while (j < 8) {2624ch = (block << 2) + (j >> 1);2625dch = hc->chan[ch].dch;2626bch = hc->chan[ch].bch;2627if (((!dch) && (!bch)) || (!hc->created[hc->chan[ch].port])) {2628j += 2;2629continue;2630}2631if (dch && (r_irq_fifo_bl & (1 << j)) &&2632test_bit(FLG_ACTIVE, &dch->Flags)) {2633hfcmulti_tx(hc, ch);2634/* start fifo */2635HFC_outb_nodebug(hc, R_FIFO, 0);2636HFC_wait_nodebug(hc);2637}2638if (bch && (r_irq_fifo_bl & (1 << j)) &&2639test_bit(FLG_ACTIVE, &bch->Flags)) {2640hfcmulti_tx(hc, ch);2641/* start fifo */2642HFC_outb_nodebug(hc, R_FIFO, 0);2643HFC_wait_nodebug(hc);2644}2645j++;2646if (dch && (r_irq_fifo_bl & (1 << j)) &&2647test_bit(FLG_ACTIVE, &dch->Flags)) {2648hfcmulti_rx(hc, ch);2649}2650if (bch && (r_irq_fifo_bl & (1 << j)) &&2651test_bit(FLG_ACTIVE, &bch->Flags)) {2652hfcmulti_rx(hc, ch);2653}2654j++;2655}2656}26572658#ifdef IRQ_DEBUG2659int irqsem;2660#endif2661static irqreturn_t2662hfcmulti_interrupt(int intno, void *dev_id)2663{2664#ifdef IRQCOUNT_DEBUG2665static int iq1 = 0, iq2 = 0, iq3 = 0, iq4 = 0,2666iq5 = 0, iq6 = 0, iqcnt = 0;2667#endif2668struct hfc_multi *hc = dev_id;2669struct dchannel *dch;2670u_char r_irq_statech, status, r_irq_misc, r_irq_oview;2671int i;2672void __iomem *plx_acc;2673u_short wval;2674u_char e1_syncsta, temp;2675u_long flags;26762677if (!hc) {2678printk(KERN_ERR "HFC-multi: Spurious interrupt!\n");2679return IRQ_NONE;2680}26812682spin_lock(&hc->lock);26832684#ifdef IRQ_DEBUG2685if (irqsem)2686printk(KERN_ERR "irq for card %d during irq from "2687"card %d, this is no bug.\n", hc->id + 1, irqsem);2688irqsem = hc->id + 1;2689#endif2690#ifdef CONFIG_MISDN_HFCMULTI_8xx2691if (hc->immap->im_cpm.cp_pbdat & hc->pb_irqmsk)2692goto irq_notforus;2693#endif2694if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {2695spin_lock_irqsave(&plx_lock, flags);2696plx_acc = hc->plx_membase + PLX_INTCSR;2697wval = readw(plx_acc);2698spin_unlock_irqrestore(&plx_lock, flags);2699if (!(wval & PLX_INTCSR_LINTI1_STATUS))2700goto irq_notforus;2701}27022703status = HFC_inb_nodebug(hc, R_STATUS);2704r_irq_statech = HFC_inb_nodebug(hc, R_IRQ_STATECH);2705#ifdef IRQCOUNT_DEBUG2706if (r_irq_statech)2707iq1++;2708if (status & V_DTMF_STA)2709iq2++;2710if (status & V_LOST_STA)2711iq3++;2712if (status & V_EXT_IRQSTA)2713iq4++;2714if (status & V_MISC_IRQSTA)2715iq5++;2716if (status & V_FR_IRQSTA)2717iq6++;2718if (iqcnt++ > 5000) {2719printk(KERN_ERR "iq1:%x iq2:%x iq3:%x iq4:%x iq5:%x iq6:%x\n",2720iq1, iq2, iq3, iq4, iq5, iq6);2721iqcnt = 0;2722}2723#endif27242725if (!r_irq_statech &&2726!(status & (V_DTMF_STA | V_LOST_STA | V_EXT_IRQSTA |2727V_MISC_IRQSTA | V_FR_IRQSTA))) {2728/* irq is not for us */2729goto irq_notforus;2730}2731hc->irqcnt++;2732if (r_irq_statech) {2733if (hc->ctype != HFC_TYPE_E1)2734ph_state_irq(hc, r_irq_statech);2735}2736if (status & V_EXT_IRQSTA)2737; /* external IRQ */2738if (status & V_LOST_STA) {2739/* LOST IRQ */2740HFC_outb(hc, R_INC_RES_FIFO, V_RES_LOST); /* clear irq! */2741}2742if (status & V_MISC_IRQSTA) {2743/* misc IRQ */2744r_irq_misc = HFC_inb_nodebug(hc, R_IRQ_MISC);2745r_irq_misc &= hc->hw.r_irqmsk_misc; /* ignore disabled irqs */2746if (r_irq_misc & V_STA_IRQ) {2747if (hc->ctype == HFC_TYPE_E1) {2748/* state machine */2749dch = hc->chan[hc->dslot].dch;2750e1_syncsta = HFC_inb_nodebug(hc, R_SYNC_STA);2751if (test_bit(HFC_CHIP_PLXSD, &hc->chip)2752&& hc->e1_getclock) {2753if (e1_syncsta & V_FR_SYNC_E1)2754hc->syncronized = 1;2755else2756hc->syncronized = 0;2757}2758/* undocumented: status changes during read */2759dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA);2760while (dch->state != (temp =2761HFC_inb_nodebug(hc, R_E1_RD_STA))) {2762if (debug & DEBUG_HFCMULTI_STATE)2763printk(KERN_DEBUG "%s: reread "2764"STATE because %d!=%d\n",2765__func__, temp,2766dch->state);2767dch->state = temp; /* repeat */2768}2769dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA)2770& 0x7;2771schedule_event(dch, FLG_PHCHANGE);2772if (debug & DEBUG_HFCMULTI_STATE)2773printk(KERN_DEBUG2774"%s: E1 (id=%d) newstate %x\n",2775__func__, hc->id, dch->state);2776if (test_bit(HFC_CHIP_PLXSD, &hc->chip))2777plxsd_checksync(hc, 0);2778}2779}2780if (r_irq_misc & V_TI_IRQ) {2781if (hc->iclock_on)2782mISDN_clock_update(hc->iclock, poll, NULL);2783handle_timer_irq(hc);2784}27852786if (r_irq_misc & V_DTMF_IRQ)2787hfcmulti_dtmf(hc);27882789if (r_irq_misc & V_IRQ_PROC) {2790static int irq_proc_cnt;2791if (!irq_proc_cnt++)2792printk(KERN_DEBUG "%s: got V_IRQ_PROC -"2793" this should not happen\n", __func__);2794}27952796}2797if (status & V_FR_IRQSTA) {2798/* FIFO IRQ */2799r_irq_oview = HFC_inb_nodebug(hc, R_IRQ_OVIEW);2800for (i = 0; i < 8; i++) {2801if (r_irq_oview & (1 << i))2802fifo_irq(hc, i);2803}2804}28052806#ifdef IRQ_DEBUG2807irqsem = 0;2808#endif2809spin_unlock(&hc->lock);2810return IRQ_HANDLED;28112812irq_notforus:2813#ifdef IRQ_DEBUG2814irqsem = 0;2815#endif2816spin_unlock(&hc->lock);2817return IRQ_NONE;2818}281928202821/*2822* timer callback for D-chan busy resolution. Currently no function2823*/28242825static void2826hfcmulti_dbusy_timer(struct hfc_multi *hc)2827{2828}282928302831/*2832* activate/deactivate hardware for selected channels and mode2833*2834* configure B-channel with the given protocol2835* ch eqals to the HFC-channel (0-31)2836* ch is the number of channel (0-4,4-7,8-11,12-15,16-19,20-23,24-27,28-312837* for S/T, 1-31 for E1)2838* the hdlc interrupts will be set/unset2839*/2840static int2841mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,2842int bank_tx, int slot_rx, int bank_rx)2843{2844int flow_tx = 0, flow_rx = 0, routing = 0;2845int oslot_tx, oslot_rx;2846int conf;28472848if (ch < 0 || ch > 31)2849return -EINVAL;2850oslot_tx = hc->chan[ch].slot_tx;2851oslot_rx = hc->chan[ch].slot_rx;2852conf = hc->chan[ch].conf;28532854if (debug & DEBUG_HFCMULTI_MODE)2855printk(KERN_DEBUG2856"%s: card %d channel %d protocol %x slot old=%d new=%d "2857"bank new=%d (TX) slot old=%d new=%d bank new=%d (RX)\n",2858__func__, hc->id, ch, protocol, oslot_tx, slot_tx,2859bank_tx, oslot_rx, slot_rx, bank_rx);28602861if (oslot_tx >= 0 && slot_tx != oslot_tx) {2862/* remove from slot */2863if (debug & DEBUG_HFCMULTI_MODE)2864printk(KERN_DEBUG "%s: remove from slot %d (TX)\n",2865__func__, oslot_tx);2866if (hc->slot_owner[oslot_tx<<1] == ch) {2867HFC_outb(hc, R_SLOT, oslot_tx << 1);2868HFC_outb(hc, A_SL_CFG, 0);2869if (hc->ctype != HFC_TYPE_XHFC)2870HFC_outb(hc, A_CONF, 0);2871hc->slot_owner[oslot_tx<<1] = -1;2872} else {2873if (debug & DEBUG_HFCMULTI_MODE)2874printk(KERN_DEBUG2875"%s: we are not owner of this tx slot "2876"anymore, channel %d is.\n",2877__func__, hc->slot_owner[oslot_tx<<1]);2878}2879}28802881if (oslot_rx >= 0 && slot_rx != oslot_rx) {2882/* remove from slot */2883if (debug & DEBUG_HFCMULTI_MODE)2884printk(KERN_DEBUG2885"%s: remove from slot %d (RX)\n",2886__func__, oslot_rx);2887if (hc->slot_owner[(oslot_rx << 1) | 1] == ch) {2888HFC_outb(hc, R_SLOT, (oslot_rx << 1) | V_SL_DIR);2889HFC_outb(hc, A_SL_CFG, 0);2890hc->slot_owner[(oslot_rx << 1) | 1] = -1;2891} else {2892if (debug & DEBUG_HFCMULTI_MODE)2893printk(KERN_DEBUG2894"%s: we are not owner of this rx slot "2895"anymore, channel %d is.\n",2896__func__,2897hc->slot_owner[(oslot_rx << 1) | 1]);2898}2899}29002901if (slot_tx < 0) {2902flow_tx = 0x80; /* FIFO->ST */2903/* disable pcm slot */2904hc->chan[ch].slot_tx = -1;2905hc->chan[ch].bank_tx = 0;2906} else {2907/* set pcm slot */2908if (hc->chan[ch].txpending)2909flow_tx = 0x80; /* FIFO->ST */2910else2911flow_tx = 0xc0; /* PCM->ST */2912/* put on slot */2913routing = bank_tx ? 0xc0 : 0x80;2914if (conf >= 0 || bank_tx > 1)2915routing = 0x40; /* loop */2916if (debug & DEBUG_HFCMULTI_MODE)2917printk(KERN_DEBUG "%s: put channel %d to slot %d bank"2918" %d flow %02x routing %02x conf %d (TX)\n",2919__func__, ch, slot_tx, bank_tx,2920flow_tx, routing, conf);2921HFC_outb(hc, R_SLOT, slot_tx << 1);2922HFC_outb(hc, A_SL_CFG, (ch<<1) | routing);2923if (hc->ctype != HFC_TYPE_XHFC)2924HFC_outb(hc, A_CONF,2925(conf < 0) ? 0 : (conf | V_CONF_SL));2926hc->slot_owner[slot_tx << 1] = ch;2927hc->chan[ch].slot_tx = slot_tx;2928hc->chan[ch].bank_tx = bank_tx;2929}2930if (slot_rx < 0) {2931/* disable pcm slot */2932flow_rx = 0x80; /* ST->FIFO */2933hc->chan[ch].slot_rx = -1;2934hc->chan[ch].bank_rx = 0;2935} else {2936/* set pcm slot */2937if (hc->chan[ch].txpending)2938flow_rx = 0x80; /* ST->FIFO */2939else2940flow_rx = 0xc0; /* ST->(FIFO,PCM) */2941/* put on slot */2942routing = bank_rx ? 0x80 : 0xc0; /* reversed */2943if (conf >= 0 || bank_rx > 1)2944routing = 0x40; /* loop */2945if (debug & DEBUG_HFCMULTI_MODE)2946printk(KERN_DEBUG "%s: put channel %d to slot %d bank"2947" %d flow %02x routing %02x conf %d (RX)\n",2948__func__, ch, slot_rx, bank_rx,2949flow_rx, routing, conf);2950HFC_outb(hc, R_SLOT, (slot_rx<<1) | V_SL_DIR);2951HFC_outb(hc, A_SL_CFG, (ch<<1) | V_CH_DIR | routing);2952hc->slot_owner[(slot_rx<<1)|1] = ch;2953hc->chan[ch].slot_rx = slot_rx;2954hc->chan[ch].bank_rx = bank_rx;2955}29562957switch (protocol) {2958case (ISDN_P_NONE):2959/* disable TX fifo */2960HFC_outb(hc, R_FIFO, ch << 1);2961HFC_wait(hc);2962HFC_outb(hc, A_CON_HDLC, flow_tx | 0x00 | V_IFF);2963HFC_outb(hc, A_SUBCH_CFG, 0);2964HFC_outb(hc, A_IRQ_MSK, 0);2965HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);2966HFC_wait(hc);2967/* disable RX fifo */2968HFC_outb(hc, R_FIFO, (ch<<1)|1);2969HFC_wait(hc);2970HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00);2971HFC_outb(hc, A_SUBCH_CFG, 0);2972HFC_outb(hc, A_IRQ_MSK, 0);2973HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);2974HFC_wait(hc);2975if (hc->chan[ch].bch && hc->ctype != HFC_TYPE_E1) {2976hc->hw.a_st_ctrl0[hc->chan[ch].port] &=2977((ch & 0x3) == 0) ? ~V_B1_EN : ~V_B2_EN;2978HFC_outb(hc, R_ST_SEL, hc->chan[ch].port);2979/* undocumented: delay after R_ST_SEL */2980udelay(1);2981HFC_outb(hc, A_ST_CTRL0,2982hc->hw.a_st_ctrl0[hc->chan[ch].port]);2983}2984if (hc->chan[ch].bch) {2985test_and_clear_bit(FLG_HDLC, &hc->chan[ch].bch->Flags);2986test_and_clear_bit(FLG_TRANSPARENT,2987&hc->chan[ch].bch->Flags);2988}2989break;2990case (ISDN_P_B_RAW): /* B-channel */29912992if (test_bit(HFC_CHIP_B410P, &hc->chip) &&2993(hc->chan[ch].slot_rx < 0) &&2994(hc->chan[ch].slot_tx < 0)) {29952996printk(KERN_DEBUG2997"Setting B-channel %d to echo cancelable "2998"state on PCM slot %d\n", ch,2999((ch / 4) * 8) + ((ch % 4) * 4) + 1);3000printk(KERN_DEBUG3001"Enabling pass through for channel\n");3002vpm_out(hc, ch, ((ch / 4) * 8) +3003((ch % 4) * 4) + 1, 0x01);3004/* rx path */3005/* S/T -> PCM */3006HFC_outb(hc, R_FIFO, (ch << 1));3007HFC_wait(hc);3008HFC_outb(hc, A_CON_HDLC, 0xc0 | V_HDLC_TRP | V_IFF);3009HFC_outb(hc, R_SLOT, (((ch / 4) * 8) +3010((ch % 4) * 4) + 1) << 1);3011HFC_outb(hc, A_SL_CFG, 0x80 | (ch << 1));30123013/* PCM -> FIFO */3014HFC_outb(hc, R_FIFO, 0x20 | (ch << 1) | 1);3015HFC_wait(hc);3016HFC_outb(hc, A_CON_HDLC, 0x20 | V_HDLC_TRP | V_IFF);3017HFC_outb(hc, A_SUBCH_CFG, 0);3018HFC_outb(hc, A_IRQ_MSK, 0);3019HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);3020HFC_wait(hc);3021HFC_outb(hc, R_SLOT, ((((ch / 4) * 8) +3022((ch % 4) * 4) + 1) << 1) | 1);3023HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1) | 1);30243025/* tx path */3026/* PCM -> S/T */3027HFC_outb(hc, R_FIFO, (ch << 1) | 1);3028HFC_wait(hc);3029HFC_outb(hc, A_CON_HDLC, 0xc0 | V_HDLC_TRP | V_IFF);3030HFC_outb(hc, R_SLOT, ((((ch / 4) * 8) +3031((ch % 4) * 4)) << 1) | 1);3032HFC_outb(hc, A_SL_CFG, 0x80 | 0x40 | (ch << 1) | 1);30333034/* FIFO -> PCM */3035HFC_outb(hc, R_FIFO, 0x20 | (ch << 1));3036HFC_wait(hc);3037HFC_outb(hc, A_CON_HDLC, 0x20 | V_HDLC_TRP | V_IFF);3038HFC_outb(hc, A_SUBCH_CFG, 0);3039HFC_outb(hc, A_IRQ_MSK, 0);3040HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);3041HFC_wait(hc);3042/* tx silence */3043HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);3044HFC_outb(hc, R_SLOT, (((ch / 4) * 8) +3045((ch % 4) * 4)) << 1);3046HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1));3047} else {3048/* enable TX fifo */3049HFC_outb(hc, R_FIFO, ch << 1);3050HFC_wait(hc);3051if (hc->ctype == HFC_TYPE_XHFC)3052HFC_outb(hc, A_CON_HDLC, flow_tx | 0x07 << 2 |3053V_HDLC_TRP | V_IFF);3054/* Enable FIFO, no interrupt */3055else3056HFC_outb(hc, A_CON_HDLC, flow_tx | 0x00 |3057V_HDLC_TRP | V_IFF);3058HFC_outb(hc, A_SUBCH_CFG, 0);3059HFC_outb(hc, A_IRQ_MSK, 0);3060HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);3061HFC_wait(hc);3062/* tx silence */3063HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);3064/* enable RX fifo */3065HFC_outb(hc, R_FIFO, (ch<<1)|1);3066HFC_wait(hc);3067if (hc->ctype == HFC_TYPE_XHFC)3068HFC_outb(hc, A_CON_HDLC, flow_rx | 0x07 << 2 |3069V_HDLC_TRP);3070/* Enable FIFO, no interrupt*/3071else3072HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00 |3073V_HDLC_TRP);3074HFC_outb(hc, A_SUBCH_CFG, 0);3075HFC_outb(hc, A_IRQ_MSK, 0);3076HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);3077HFC_wait(hc);3078}3079if (hc->ctype != HFC_TYPE_E1) {3080hc->hw.a_st_ctrl0[hc->chan[ch].port] |=3081((ch & 0x3) == 0) ? V_B1_EN : V_B2_EN;3082HFC_outb(hc, R_ST_SEL, hc->chan[ch].port);3083/* undocumented: delay after R_ST_SEL */3084udelay(1);3085HFC_outb(hc, A_ST_CTRL0,3086hc->hw.a_st_ctrl0[hc->chan[ch].port]);3087}3088if (hc->chan[ch].bch)3089test_and_set_bit(FLG_TRANSPARENT,3090&hc->chan[ch].bch->Flags);3091break;3092case (ISDN_P_B_HDLC): /* B-channel */3093case (ISDN_P_TE_S0): /* D-channel */3094case (ISDN_P_NT_S0):3095case (ISDN_P_TE_E1):3096case (ISDN_P_NT_E1):3097/* enable TX fifo */3098HFC_outb(hc, R_FIFO, ch<<1);3099HFC_wait(hc);3100if (hc->ctype == HFC_TYPE_E1 || hc->chan[ch].bch) {3101/* E1 or B-channel */3102HFC_outb(hc, A_CON_HDLC, flow_tx | 0x04);3103HFC_outb(hc, A_SUBCH_CFG, 0);3104} else {3105/* D-Channel without HDLC fill flags */3106HFC_outb(hc, A_CON_HDLC, flow_tx | 0x04 | V_IFF);3107HFC_outb(hc, A_SUBCH_CFG, 2);3108}3109HFC_outb(hc, A_IRQ_MSK, V_IRQ);3110HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);3111HFC_wait(hc);3112/* enable RX fifo */3113HFC_outb(hc, R_FIFO, (ch<<1)|1);3114HFC_wait(hc);3115HFC_outb(hc, A_CON_HDLC, flow_rx | 0x04);3116if (hc->ctype == HFC_TYPE_E1 || hc->chan[ch].bch)3117HFC_outb(hc, A_SUBCH_CFG, 0); /* full 8 bits */3118else3119HFC_outb(hc, A_SUBCH_CFG, 2); /* 2 bits dchannel */3120HFC_outb(hc, A_IRQ_MSK, V_IRQ);3121HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);3122HFC_wait(hc);3123if (hc->chan[ch].bch) {3124test_and_set_bit(FLG_HDLC, &hc->chan[ch].bch->Flags);3125if (hc->ctype != HFC_TYPE_E1) {3126hc->hw.a_st_ctrl0[hc->chan[ch].port] |=3127((ch&0x3) == 0) ? V_B1_EN : V_B2_EN;3128HFC_outb(hc, R_ST_SEL, hc->chan[ch].port);3129/* undocumented: delay after R_ST_SEL */3130udelay(1);3131HFC_outb(hc, A_ST_CTRL0,3132hc->hw.a_st_ctrl0[hc->chan[ch].port]);3133}3134}3135break;3136default:3137printk(KERN_DEBUG "%s: protocol not known %x\n",3138__func__, protocol);3139hc->chan[ch].protocol = ISDN_P_NONE;3140return -ENOPROTOOPT;3141}3142hc->chan[ch].protocol = protocol;3143return 0;3144}314531463147/*3148* connect/disconnect PCM3149*/31503151static void3152hfcmulti_pcm(struct hfc_multi *hc, int ch, int slot_tx, int bank_tx,3153int slot_rx, int bank_rx)3154{3155if (slot_tx < 0 || slot_rx < 0 || bank_tx < 0 || bank_rx < 0) {3156/* disable PCM */3157mode_hfcmulti(hc, ch, hc->chan[ch].protocol, -1, 0, -1, 0);3158return;3159}31603161/* enable pcm */3162mode_hfcmulti(hc, ch, hc->chan[ch].protocol, slot_tx, bank_tx,3163slot_rx, bank_rx);3164}31653166/*3167* set/disable conference3168*/31693170static void3171hfcmulti_conf(struct hfc_multi *hc, int ch, int num)3172{3173if (num >= 0 && num <= 7)3174hc->chan[ch].conf = num;3175else3176hc->chan[ch].conf = -1;3177mode_hfcmulti(hc, ch, hc->chan[ch].protocol, hc->chan[ch].slot_tx,3178hc->chan[ch].bank_tx, hc->chan[ch].slot_rx,3179hc->chan[ch].bank_rx);3180}318131823183/*3184* set/disable sample loop3185*/31863187/* NOTE: this function is experimental and therefore disabled */31883189/*3190* Layer 1 callback function3191*/3192static int3193hfcm_l1callback(struct dchannel *dch, u_int cmd)3194{3195struct hfc_multi *hc = dch->hw;3196u_long flags;31973198switch (cmd) {3199case INFO3_P8:3200case INFO3_P10:3201break;3202case HW_RESET_REQ:3203/* start activation */3204spin_lock_irqsave(&hc->lock, flags);3205if (hc->ctype == HFC_TYPE_E1) {3206if (debug & DEBUG_HFCMULTI_MSG)3207printk(KERN_DEBUG3208"%s: HW_RESET_REQ no BRI\n",3209__func__);3210} else {3211HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port);3212/* undocumented: delay after R_ST_SEL */3213udelay(1);3214HFC_outb(hc, A_ST_WR_STATE, V_ST_LD_STA | 3); /* F3 */3215udelay(6); /* wait at least 5,21us */3216HFC_outb(hc, A_ST_WR_STATE, 3);3217HFC_outb(hc, A_ST_WR_STATE, 3 | (V_ST_ACT*3));3218/* activate */3219}3220spin_unlock_irqrestore(&hc->lock, flags);3221l1_event(dch->l1, HW_POWERUP_IND);3222break;3223case HW_DEACT_REQ:3224/* start deactivation */3225spin_lock_irqsave(&hc->lock, flags);3226if (hc->ctype == HFC_TYPE_E1) {3227if (debug & DEBUG_HFCMULTI_MSG)3228printk(KERN_DEBUG3229"%s: HW_DEACT_REQ no BRI\n",3230__func__);3231} else {3232HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port);3233/* undocumented: delay after R_ST_SEL */3234udelay(1);3235HFC_outb(hc, A_ST_WR_STATE, V_ST_ACT*2);3236/* deactivate */3237if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {3238hc->syncronized &=3239~(1 << hc->chan[dch->slot].port);3240plxsd_checksync(hc, 0);3241}3242}3243skb_queue_purge(&dch->squeue);3244if (dch->tx_skb) {3245dev_kfree_skb(dch->tx_skb);3246dch->tx_skb = NULL;3247}3248dch->tx_idx = 0;3249if (dch->rx_skb) {3250dev_kfree_skb(dch->rx_skb);3251dch->rx_skb = NULL;3252}3253test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);3254if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))3255del_timer(&dch->timer);3256spin_unlock_irqrestore(&hc->lock, flags);3257break;3258case HW_POWERUP_REQ:3259spin_lock_irqsave(&hc->lock, flags);3260if (hc->ctype == HFC_TYPE_E1) {3261if (debug & DEBUG_HFCMULTI_MSG)3262printk(KERN_DEBUG3263"%s: HW_POWERUP_REQ no BRI\n",3264__func__);3265} else {3266HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port);3267/* undocumented: delay after R_ST_SEL */3268udelay(1);3269HFC_outb(hc, A_ST_WR_STATE, 3 | 0x10); /* activate */3270udelay(6); /* wait at least 5,21us */3271HFC_outb(hc, A_ST_WR_STATE, 3); /* activate */3272}3273spin_unlock_irqrestore(&hc->lock, flags);3274break;3275case PH_ACTIVATE_IND:3276test_and_set_bit(FLG_ACTIVE, &dch->Flags);3277_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,3278GFP_ATOMIC);3279break;3280case PH_DEACTIVATE_IND:3281test_and_clear_bit(FLG_ACTIVE, &dch->Flags);3282_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,3283GFP_ATOMIC);3284break;3285default:3286if (dch->debug & DEBUG_HW)3287printk(KERN_DEBUG "%s: unknown command %x\n",3288__func__, cmd);3289return -1;3290}3291return 0;3292}32933294/*3295* Layer2 -> Layer 1 Transfer3296*/32973298static int3299handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)3300{3301struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);3302struct dchannel *dch = container_of(dev, struct dchannel, dev);3303struct hfc_multi *hc = dch->hw;3304struct mISDNhead *hh = mISDN_HEAD_P(skb);3305int ret = -EINVAL;3306unsigned int id;3307u_long flags;33083309switch (hh->prim) {3310case PH_DATA_REQ:3311if (skb->len < 1)3312break;3313spin_lock_irqsave(&hc->lock, flags);3314ret = dchannel_senddata(dch, skb);3315if (ret > 0) { /* direct TX */3316id = hh->id; /* skb can be freed */3317hfcmulti_tx(hc, dch->slot);3318ret = 0;3319/* start fifo */3320HFC_outb(hc, R_FIFO, 0);3321HFC_wait(hc);3322spin_unlock_irqrestore(&hc->lock, flags);3323queue_ch_frame(ch, PH_DATA_CNF, id, NULL);3324} else3325spin_unlock_irqrestore(&hc->lock, flags);3326return ret;3327case PH_ACTIVATE_REQ:3328if (dch->dev.D.protocol != ISDN_P_TE_S0) {3329spin_lock_irqsave(&hc->lock, flags);3330ret = 0;3331if (debug & DEBUG_HFCMULTI_MSG)3332printk(KERN_DEBUG3333"%s: PH_ACTIVATE port %d (0..%d)\n",3334__func__, hc->chan[dch->slot].port,3335hc->ports-1);3336/* start activation */3337if (hc->ctype == HFC_TYPE_E1) {3338ph_state_change(dch);3339if (debug & DEBUG_HFCMULTI_STATE)3340printk(KERN_DEBUG3341"%s: E1 report state %x \n",3342__func__, dch->state);3343} else {3344HFC_outb(hc, R_ST_SEL,3345hc->chan[dch->slot].port);3346/* undocumented: delay after R_ST_SEL */3347udelay(1);3348HFC_outb(hc, A_ST_WR_STATE, V_ST_LD_STA | 1);3349/* G1 */3350udelay(6); /* wait at least 5,21us */3351HFC_outb(hc, A_ST_WR_STATE, 1);3352HFC_outb(hc, A_ST_WR_STATE, 1 |3353(V_ST_ACT*3)); /* activate */3354dch->state = 1;3355}3356spin_unlock_irqrestore(&hc->lock, flags);3357} else3358ret = l1_event(dch->l1, hh->prim);3359break;3360case PH_DEACTIVATE_REQ:3361test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);3362if (dch->dev.D.protocol != ISDN_P_TE_S0) {3363spin_lock_irqsave(&hc->lock, flags);3364if (debug & DEBUG_HFCMULTI_MSG)3365printk(KERN_DEBUG3366"%s: PH_DEACTIVATE port %d (0..%d)\n",3367__func__, hc->chan[dch->slot].port,3368hc->ports-1);3369/* start deactivation */3370if (hc->ctype == HFC_TYPE_E1) {3371if (debug & DEBUG_HFCMULTI_MSG)3372printk(KERN_DEBUG3373"%s: PH_DEACTIVATE no BRI\n",3374__func__);3375} else {3376HFC_outb(hc, R_ST_SEL,3377hc->chan[dch->slot].port);3378/* undocumented: delay after R_ST_SEL */3379udelay(1);3380HFC_outb(hc, A_ST_WR_STATE, V_ST_ACT * 2);3381/* deactivate */3382dch->state = 1;3383}3384skb_queue_purge(&dch->squeue);3385if (dch->tx_skb) {3386dev_kfree_skb(dch->tx_skb);3387dch->tx_skb = NULL;3388}3389dch->tx_idx = 0;3390if (dch->rx_skb) {3391dev_kfree_skb(dch->rx_skb);3392dch->rx_skb = NULL;3393}3394test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);3395if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))3396del_timer(&dch->timer);3397#ifdef FIXME3398if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))3399dchannel_sched_event(&hc->dch, D_CLEARBUSY);3400#endif3401ret = 0;3402spin_unlock_irqrestore(&hc->lock, flags);3403} else3404ret = l1_event(dch->l1, hh->prim);3405break;3406}3407if (!ret)3408dev_kfree_skb(skb);3409return ret;3410}34113412static void3413deactivate_bchannel(struct bchannel *bch)3414{3415struct hfc_multi *hc = bch->hw;3416u_long flags;34173418spin_lock_irqsave(&hc->lock, flags);3419mISDN_clear_bchannel(bch);3420hc->chan[bch->slot].coeff_count = 0;3421hc->chan[bch->slot].rx_off = 0;3422hc->chan[bch->slot].conf = -1;3423mode_hfcmulti(hc, bch->slot, ISDN_P_NONE, -1, 0, -1, 0);3424spin_unlock_irqrestore(&hc->lock, flags);3425}34263427static int3428handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)3429{3430struct bchannel *bch = container_of(ch, struct bchannel, ch);3431struct hfc_multi *hc = bch->hw;3432int ret = -EINVAL;3433struct mISDNhead *hh = mISDN_HEAD_P(skb);3434unsigned int id;3435u_long flags;34363437switch (hh->prim) {3438case PH_DATA_REQ:3439if (!skb->len)3440break;3441spin_lock_irqsave(&hc->lock, flags);3442ret = bchannel_senddata(bch, skb);3443if (ret > 0) { /* direct TX */3444id = hh->id; /* skb can be freed */3445hfcmulti_tx(hc, bch->slot);3446ret = 0;3447/* start fifo */3448HFC_outb_nodebug(hc, R_FIFO, 0);3449HFC_wait_nodebug(hc);3450if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) {3451spin_unlock_irqrestore(&hc->lock, flags);3452queue_ch_frame(ch, PH_DATA_CNF, id, NULL);3453} else3454spin_unlock_irqrestore(&hc->lock, flags);3455} else3456spin_unlock_irqrestore(&hc->lock, flags);3457return ret;3458case PH_ACTIVATE_REQ:3459if (debug & DEBUG_HFCMULTI_MSG)3460printk(KERN_DEBUG "%s: PH_ACTIVATE ch %d (0..32)\n",3461__func__, bch->slot);3462spin_lock_irqsave(&hc->lock, flags);3463/* activate B-channel if not already activated */3464if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) {3465hc->chan[bch->slot].txpending = 0;3466ret = mode_hfcmulti(hc, bch->slot,3467ch->protocol,3468hc->chan[bch->slot].slot_tx,3469hc->chan[bch->slot].bank_tx,3470hc->chan[bch->slot].slot_rx,3471hc->chan[bch->slot].bank_rx);3472if (!ret) {3473if (ch->protocol == ISDN_P_B_RAW && !hc->dtmf3474&& test_bit(HFC_CHIP_DTMF, &hc->chip)) {3475/* start decoder */3476hc->dtmf = 1;3477if (debug & DEBUG_HFCMULTI_DTMF)3478printk(KERN_DEBUG3479"%s: start dtmf decoder\n",3480__func__);3481HFC_outb(hc, R_DTMF, hc->hw.r_dtmf |3482V_RST_DTMF);3483}3484}3485} else3486ret = 0;3487spin_unlock_irqrestore(&hc->lock, flags);3488if (!ret)3489_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0, NULL,3490GFP_KERNEL);3491break;3492case PH_CONTROL_REQ:3493spin_lock_irqsave(&hc->lock, flags);3494switch (hh->id) {3495case HFC_SPL_LOOP_ON: /* set sample loop */3496if (debug & DEBUG_HFCMULTI_MSG)3497printk(KERN_DEBUG3498"%s: HFC_SPL_LOOP_ON (len = %d)\n",3499__func__, skb->len);3500ret = 0;3501break;3502case HFC_SPL_LOOP_OFF: /* set silence */3503if (debug & DEBUG_HFCMULTI_MSG)3504printk(KERN_DEBUG "%s: HFC_SPL_LOOP_OFF\n",3505__func__);3506ret = 0;3507break;3508default:3509printk(KERN_ERR3510"%s: unknown PH_CONTROL_REQ info %x\n",3511__func__, hh->id);3512ret = -EINVAL;3513}3514spin_unlock_irqrestore(&hc->lock, flags);3515break;3516case PH_DEACTIVATE_REQ:3517deactivate_bchannel(bch); /* locked there */3518_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0, NULL,3519GFP_KERNEL);3520ret = 0;3521break;3522}3523if (!ret)3524dev_kfree_skb(skb);3525return ret;3526}35273528/*3529* bchannel control function3530*/3531static int3532channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)3533{3534int ret = 0;3535struct dsp_features *features =3536(struct dsp_features *)(*((u_long *)&cq->p1));3537struct hfc_multi *hc = bch->hw;3538int slot_tx;3539int bank_tx;3540int slot_rx;3541int bank_rx;3542int num;35433544switch (cq->op) {3545case MISDN_CTRL_GETOP:3546cq->op = MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP3547| MISDN_CTRL_RX_OFF | MISDN_CTRL_FILL_EMPTY;3548break;3549case MISDN_CTRL_RX_OFF: /* turn off / on rx stream */3550hc->chan[bch->slot].rx_off = !!cq->p1;3551if (!hc->chan[bch->slot].rx_off) {3552/* reset fifo on rx on */3553HFC_outb_nodebug(hc, R_FIFO, (bch->slot << 1) | 1);3554HFC_wait_nodebug(hc);3555HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F);3556HFC_wait_nodebug(hc);3557}3558if (debug & DEBUG_HFCMULTI_MSG)3559printk(KERN_DEBUG "%s: RX_OFF request (nr=%d off=%d)\n",3560__func__, bch->nr, hc->chan[bch->slot].rx_off);3561break;3562case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */3563test_and_set_bit(FLG_FILLEMPTY, &bch->Flags);3564if (debug & DEBUG_HFCMULTI_MSG)3565printk(KERN_DEBUG "%s: FILL_EMPTY request (nr=%d "3566"off=%d)\n", __func__, bch->nr, !!cq->p1);3567break;3568case MISDN_CTRL_HW_FEATURES: /* fill features structure */3569if (debug & DEBUG_HFCMULTI_MSG)3570printk(KERN_DEBUG "%s: HW_FEATURE request\n",3571__func__);3572/* create confirm */3573features->hfc_id = hc->id;3574if (test_bit(HFC_CHIP_DTMF, &hc->chip))3575features->hfc_dtmf = 1;3576if (test_bit(HFC_CHIP_CONF, &hc->chip))3577features->hfc_conf = 1;3578features->hfc_loops = 0;3579if (test_bit(HFC_CHIP_B410P, &hc->chip)) {3580features->hfc_echocanhw = 1;3581} else {3582features->pcm_id = hc->pcm;3583features->pcm_slots = hc->slots;3584features->pcm_banks = 2;3585}3586break;3587case MISDN_CTRL_HFC_PCM_CONN: /* connect to pcm timeslot (0..N) */3588slot_tx = cq->p1 & 0xff;3589bank_tx = cq->p1 >> 8;3590slot_rx = cq->p2 & 0xff;3591bank_rx = cq->p2 >> 8;3592if (debug & DEBUG_HFCMULTI_MSG)3593printk(KERN_DEBUG3594"%s: HFC_PCM_CONN slot %d bank %d (TX) "3595"slot %d bank %d (RX)\n",3596__func__, slot_tx, bank_tx,3597slot_rx, bank_rx);3598if (slot_tx < hc->slots && bank_tx <= 2 &&3599slot_rx < hc->slots && bank_rx <= 2)3600hfcmulti_pcm(hc, bch->slot,3601slot_tx, bank_tx, slot_rx, bank_rx);3602else {3603printk(KERN_WARNING3604"%s: HFC_PCM_CONN slot %d bank %d (TX) "3605"slot %d bank %d (RX) out of range\n",3606__func__, slot_tx, bank_tx,3607slot_rx, bank_rx);3608ret = -EINVAL;3609}3610break;3611case MISDN_CTRL_HFC_PCM_DISC: /* release interface from pcm timeslot */3612if (debug & DEBUG_HFCMULTI_MSG)3613printk(KERN_DEBUG "%s: HFC_PCM_DISC\n",3614__func__);3615hfcmulti_pcm(hc, bch->slot, -1, 0, -1, 0);3616break;3617case MISDN_CTRL_HFC_CONF_JOIN: /* join conference (0..7) */3618num = cq->p1 & 0xff;3619if (debug & DEBUG_HFCMULTI_MSG)3620printk(KERN_DEBUG "%s: HFC_CONF_JOIN conf %d\n",3621__func__, num);3622if (num <= 7)3623hfcmulti_conf(hc, bch->slot, num);3624else {3625printk(KERN_WARNING3626"%s: HW_CONF_JOIN conf %d out of range\n",3627__func__, num);3628ret = -EINVAL;3629}3630break;3631case MISDN_CTRL_HFC_CONF_SPLIT: /* split conference */3632if (debug & DEBUG_HFCMULTI_MSG)3633printk(KERN_DEBUG "%s: HFC_CONF_SPLIT\n", __func__);3634hfcmulti_conf(hc, bch->slot, -1);3635break;3636case MISDN_CTRL_HFC_ECHOCAN_ON:3637if (debug & DEBUG_HFCMULTI_MSG)3638printk(KERN_DEBUG "%s: HFC_ECHOCAN_ON\n", __func__);3639if (test_bit(HFC_CHIP_B410P, &hc->chip))3640vpm_echocan_on(hc, bch->slot, cq->p1);3641else3642ret = -EINVAL;3643break;36443645case MISDN_CTRL_HFC_ECHOCAN_OFF:3646if (debug & DEBUG_HFCMULTI_MSG)3647printk(KERN_DEBUG "%s: HFC_ECHOCAN_OFF\n",3648__func__);3649if (test_bit(HFC_CHIP_B410P, &hc->chip))3650vpm_echocan_off(hc, bch->slot);3651else3652ret = -EINVAL;3653break;3654default:3655printk(KERN_WARNING "%s: unknown Op %x\n",3656__func__, cq->op);3657ret = -EINVAL;3658break;3659}3660return ret;3661}36623663static int3664hfcm_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)3665{3666struct bchannel *bch = container_of(ch, struct bchannel, ch);3667struct hfc_multi *hc = bch->hw;3668int err = -EINVAL;3669u_long flags;36703671if (bch->debug & DEBUG_HW)3672printk(KERN_DEBUG "%s: cmd:%x %p\n",3673__func__, cmd, arg);3674switch (cmd) {3675case CLOSE_CHANNEL:3676test_and_clear_bit(FLG_OPEN, &bch->Flags);3677if (test_bit(FLG_ACTIVE, &bch->Flags))3678deactivate_bchannel(bch); /* locked there */3679ch->protocol = ISDN_P_NONE;3680ch->peer = NULL;3681module_put(THIS_MODULE);3682err = 0;3683break;3684case CONTROL_CHANNEL:3685spin_lock_irqsave(&hc->lock, flags);3686err = channel_bctrl(bch, arg);3687spin_unlock_irqrestore(&hc->lock, flags);3688break;3689default:3690printk(KERN_WARNING "%s: unknown prim(%x)\n",3691__func__, cmd);3692}3693return err;3694}36953696/*3697* handle D-channel events3698*3699* handle state change event3700*/3701static void3702ph_state_change(struct dchannel *dch)3703{3704struct hfc_multi *hc;3705int ch, i;37063707if (!dch) {3708printk(KERN_WARNING "%s: ERROR given dch is NULL\n", __func__);3709return;3710}3711hc = dch->hw;3712ch = dch->slot;37133714if (hc->ctype == HFC_TYPE_E1) {3715if (dch->dev.D.protocol == ISDN_P_TE_E1) {3716if (debug & DEBUG_HFCMULTI_STATE)3717printk(KERN_DEBUG3718"%s: E1 TE (id=%d) newstate %x\n",3719__func__, hc->id, dch->state);3720} else {3721if (debug & DEBUG_HFCMULTI_STATE)3722printk(KERN_DEBUG3723"%s: E1 NT (id=%d) newstate %x\n",3724__func__, hc->id, dch->state);3725}3726switch (dch->state) {3727case (1):3728if (hc->e1_state != 1) {3729for (i = 1; i <= 31; i++) {3730/* reset fifos on e1 activation */3731HFC_outb_nodebug(hc, R_FIFO,3732(i << 1) | 1);3733HFC_wait_nodebug(hc);3734HFC_outb_nodebug(hc, R_INC_RES_FIFO,3735V_RES_F);3736HFC_wait_nodebug(hc);3737}3738}3739test_and_set_bit(FLG_ACTIVE, &dch->Flags);3740_queue_data(&dch->dev.D, PH_ACTIVATE_IND,3741MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);3742break;37433744default:3745if (hc->e1_state != 1)3746return;3747test_and_clear_bit(FLG_ACTIVE, &dch->Flags);3748_queue_data(&dch->dev.D, PH_DEACTIVATE_IND,3749MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);3750}3751hc->e1_state = dch->state;3752} else {3753if (dch->dev.D.protocol == ISDN_P_TE_S0) {3754if (debug & DEBUG_HFCMULTI_STATE)3755printk(KERN_DEBUG3756"%s: S/T TE newstate %x\n",3757__func__, dch->state);3758switch (dch->state) {3759case (0):3760l1_event(dch->l1, HW_RESET_IND);3761break;3762case (3):3763l1_event(dch->l1, HW_DEACT_IND);3764break;3765case (5):3766case (8):3767l1_event(dch->l1, ANYSIGNAL);3768break;3769case (6):3770l1_event(dch->l1, INFO2);3771break;3772case (7):3773l1_event(dch->l1, INFO4_P8);3774break;3775}3776} else {3777if (debug & DEBUG_HFCMULTI_STATE)3778printk(KERN_DEBUG "%s: S/T NT newstate %x\n",3779__func__, dch->state);3780switch (dch->state) {3781case (2):3782if (hc->chan[ch].nt_timer == 0) {3783hc->chan[ch].nt_timer = -1;3784HFC_outb(hc, R_ST_SEL,3785hc->chan[ch].port);3786/* undocumented: delay after R_ST_SEL */3787udelay(1);3788HFC_outb(hc, A_ST_WR_STATE, 4 |3789V_ST_LD_STA); /* G4 */3790udelay(6); /* wait at least 5,21us */3791HFC_outb(hc, A_ST_WR_STATE, 4);3792dch->state = 4;3793} else {3794/* one extra count for the next event */3795hc->chan[ch].nt_timer =3796nt_t1_count[poll_timer] + 1;3797HFC_outb(hc, R_ST_SEL,3798hc->chan[ch].port);3799/* undocumented: delay after R_ST_SEL */3800udelay(1);3801/* allow G2 -> G3 transition */3802HFC_outb(hc, A_ST_WR_STATE, 2 |3803V_SET_G2_G3);3804}3805break;3806case (1):3807hc->chan[ch].nt_timer = -1;3808test_and_clear_bit(FLG_ACTIVE, &dch->Flags);3809_queue_data(&dch->dev.D, PH_DEACTIVATE_IND,3810MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);3811break;3812case (4):3813hc->chan[ch].nt_timer = -1;3814break;3815case (3):3816hc->chan[ch].nt_timer = -1;3817test_and_set_bit(FLG_ACTIVE, &dch->Flags);3818_queue_data(&dch->dev.D, PH_ACTIVATE_IND,3819MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);3820break;3821}3822}3823}3824}38253826/*3827* called for card mode init message3828*/38293830static void3831hfcmulti_initmode(struct dchannel *dch)3832{3833struct hfc_multi *hc = dch->hw;3834u_char a_st_wr_state, r_e1_wr_sta;3835int i, pt;38363837if (debug & DEBUG_HFCMULTI_INIT)3838printk(KERN_DEBUG "%s: entered\n", __func__);38393840if (hc->ctype == HFC_TYPE_E1) {3841hc->chan[hc->dslot].slot_tx = -1;3842hc->chan[hc->dslot].slot_rx = -1;3843hc->chan[hc->dslot].conf = -1;3844if (hc->dslot) {3845mode_hfcmulti(hc, hc->dslot, dch->dev.D.protocol,3846-1, 0, -1, 0);3847dch->timer.function = (void *) hfcmulti_dbusy_timer;3848dch->timer.data = (long) dch;3849init_timer(&dch->timer);3850}3851for (i = 1; i <= 31; i++) {3852if (i == hc->dslot)3853continue;3854hc->chan[i].slot_tx = -1;3855hc->chan[i].slot_rx = -1;3856hc->chan[i].conf = -1;3857mode_hfcmulti(hc, i, ISDN_P_NONE, -1, 0, -1, 0);3858}3859/* E1 */3860if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) {3861HFC_outb(hc, R_LOS0, 255); /* 2 ms */3862HFC_outb(hc, R_LOS1, 255); /* 512 ms */3863}3864if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dslot].cfg)) {3865HFC_outb(hc, R_RX0, 0);3866hc->hw.r_tx0 = 0 | V_OUT_EN;3867} else {3868HFC_outb(hc, R_RX0, 1);3869hc->hw.r_tx0 = 1 | V_OUT_EN;3870}3871hc->hw.r_tx1 = V_ATX | V_NTRI;3872HFC_outb(hc, R_TX0, hc->hw.r_tx0);3873HFC_outb(hc, R_TX1, hc->hw.r_tx1);3874HFC_outb(hc, R_TX_FR0, 0x00);3875HFC_outb(hc, R_TX_FR1, 0xf8);38763877if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg))3878HFC_outb(hc, R_TX_FR2, V_TX_MF | V_TX_E | V_NEG_E);38793880HFC_outb(hc, R_RX_FR0, V_AUTO_RESYNC | V_AUTO_RECO | 0);38813882if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg))3883HFC_outb(hc, R_RX_FR1, V_RX_MF | V_RX_MF_SYNC);38843885if (dch->dev.D.protocol == ISDN_P_NT_E1) {3886if (debug & DEBUG_HFCMULTI_INIT)3887printk(KERN_DEBUG "%s: E1 port is NT-mode\n",3888__func__);3889r_e1_wr_sta = 0; /* G0 */3890hc->e1_getclock = 0;3891} else {3892if (debug & DEBUG_HFCMULTI_INIT)3893printk(KERN_DEBUG "%s: E1 port is TE-mode\n",3894__func__);3895r_e1_wr_sta = 0; /* F0 */3896hc->e1_getclock = 1;3897}3898if (test_bit(HFC_CHIP_RX_SYNC, &hc->chip))3899HFC_outb(hc, R_SYNC_OUT, V_SYNC_E1_RX);3900else3901HFC_outb(hc, R_SYNC_OUT, 0);3902if (test_bit(HFC_CHIP_E1CLOCK_GET, &hc->chip))3903hc->e1_getclock = 1;3904if (test_bit(HFC_CHIP_E1CLOCK_PUT, &hc->chip))3905hc->e1_getclock = 0;3906if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) {3907/* SLAVE (clock master) */3908if (debug & DEBUG_HFCMULTI_INIT)3909printk(KERN_DEBUG3910"%s: E1 port is clock master "3911"(clock from PCM)\n", __func__);3912HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC | V_PCM_SYNC);3913} else {3914if (hc->e1_getclock) {3915/* MASTER (clock slave) */3916if (debug & DEBUG_HFCMULTI_INIT)3917printk(KERN_DEBUG3918"%s: E1 port is clock slave "3919"(clock to PCM)\n", __func__);3920HFC_outb(hc, R_SYNC_CTRL, V_SYNC_OFFS);3921} else {3922/* MASTER (clock master) */3923if (debug & DEBUG_HFCMULTI_INIT)3924printk(KERN_DEBUG "%s: E1 port is "3925"clock master "3926"(clock from QUARTZ)\n",3927__func__);3928HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC |3929V_PCM_SYNC | V_JATT_OFF);3930HFC_outb(hc, R_SYNC_OUT, 0);3931}3932}3933HFC_outb(hc, R_JATT_ATT, 0x9c); /* undoc register */3934HFC_outb(hc, R_PWM_MD, V_PWM0_MD);3935HFC_outb(hc, R_PWM0, 0x50);3936HFC_outb(hc, R_PWM1, 0xff);3937/* state machine setup */3938HFC_outb(hc, R_E1_WR_STA, r_e1_wr_sta | V_E1_LD_STA);3939udelay(6); /* wait at least 5,21us */3940HFC_outb(hc, R_E1_WR_STA, r_e1_wr_sta);3941if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {3942hc->syncronized = 0;3943plxsd_checksync(hc, 0);3944}3945} else {3946i = dch->slot;3947hc->chan[i].slot_tx = -1;3948hc->chan[i].slot_rx = -1;3949hc->chan[i].conf = -1;3950mode_hfcmulti(hc, i, dch->dev.D.protocol, -1, 0, -1, 0);3951dch->timer.function = (void *)hfcmulti_dbusy_timer;3952dch->timer.data = (long) dch;3953init_timer(&dch->timer);3954hc->chan[i - 2].slot_tx = -1;3955hc->chan[i - 2].slot_rx = -1;3956hc->chan[i - 2].conf = -1;3957mode_hfcmulti(hc, i - 2, ISDN_P_NONE, -1, 0, -1, 0);3958hc->chan[i - 1].slot_tx = -1;3959hc->chan[i - 1].slot_rx = -1;3960hc->chan[i - 1].conf = -1;3961mode_hfcmulti(hc, i - 1, ISDN_P_NONE, -1, 0, -1, 0);3962/* ST */3963pt = hc->chan[i].port;3964/* select interface */3965HFC_outb(hc, R_ST_SEL, pt);3966/* undocumented: delay after R_ST_SEL */3967udelay(1);3968if (dch->dev.D.protocol == ISDN_P_NT_S0) {3969if (debug & DEBUG_HFCMULTI_INIT)3970printk(KERN_DEBUG3971"%s: ST port %d is NT-mode\n",3972__func__, pt);3973/* clock delay */3974HFC_outb(hc, A_ST_CLK_DLY, clockdelay_nt);3975a_st_wr_state = 1; /* G1 */3976hc->hw.a_st_ctrl0[pt] = V_ST_MD;3977} else {3978if (debug & DEBUG_HFCMULTI_INIT)3979printk(KERN_DEBUG3980"%s: ST port %d is TE-mode\n",3981__func__, pt);3982/* clock delay */3983HFC_outb(hc, A_ST_CLK_DLY, clockdelay_te);3984a_st_wr_state = 2; /* F2 */3985hc->hw.a_st_ctrl0[pt] = 0;3986}3987if (!test_bit(HFC_CFG_NONCAP_TX, &hc->chan[i].cfg))3988hc->hw.a_st_ctrl0[pt] |= V_TX_LI;3989if (hc->ctype == HFC_TYPE_XHFC) {3990hc->hw.a_st_ctrl0[pt] |= 0x40 /* V_ST_PU_CTRL */;3991HFC_outb(hc, 0x35 /* A_ST_CTRL3 */,39920x7c << 1 /* V_ST_PULSE */);3993}3994/* line setup */3995HFC_outb(hc, A_ST_CTRL0, hc->hw.a_st_ctrl0[pt]);3996/* disable E-channel */3997if ((dch->dev.D.protocol == ISDN_P_NT_S0) ||3998test_bit(HFC_CFG_DIS_ECHANNEL, &hc->chan[i].cfg))3999HFC_outb(hc, A_ST_CTRL1, V_E_IGNO);4000else4001HFC_outb(hc, A_ST_CTRL1, 0);4002/* enable B-channel receive */4003HFC_outb(hc, A_ST_CTRL2, V_B1_RX_EN | V_B2_RX_EN);4004/* state machine setup */4005HFC_outb(hc, A_ST_WR_STATE, a_st_wr_state | V_ST_LD_STA);4006udelay(6); /* wait at least 5,21us */4007HFC_outb(hc, A_ST_WR_STATE, a_st_wr_state);4008hc->hw.r_sci_msk |= 1 << pt;4009/* state machine interrupts */4010HFC_outb(hc, R_SCI_MSK, hc->hw.r_sci_msk);4011/* unset sync on port */4012if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {4013hc->syncronized &=4014~(1 << hc->chan[dch->slot].port);4015plxsd_checksync(hc, 0);4016}4017}4018if (debug & DEBUG_HFCMULTI_INIT)4019printk("%s: done\n", __func__);4020}402140224023static int4024open_dchannel(struct hfc_multi *hc, struct dchannel *dch,4025struct channel_req *rq)4026{4027int err = 0;4028u_long flags;40294030if (debug & DEBUG_HW_OPEN)4031printk(KERN_DEBUG "%s: dev(%d) open from %p\n", __func__,4032dch->dev.id, __builtin_return_address(0));4033if (rq->protocol == ISDN_P_NONE)4034return -EINVAL;4035if ((dch->dev.D.protocol != ISDN_P_NONE) &&4036(dch->dev.D.protocol != rq->protocol)) {4037if (debug & DEBUG_HFCMULTI_MODE)4038printk(KERN_DEBUG "%s: change protocol %x to %x\n",4039__func__, dch->dev.D.protocol, rq->protocol);4040}4041if ((dch->dev.D.protocol == ISDN_P_TE_S0) &&4042(rq->protocol != ISDN_P_TE_S0))4043l1_event(dch->l1, CLOSE_CHANNEL);4044if (dch->dev.D.protocol != rq->protocol) {4045if (rq->protocol == ISDN_P_TE_S0) {4046err = create_l1(dch, hfcm_l1callback);4047if (err)4048return err;4049}4050dch->dev.D.protocol = rq->protocol;4051spin_lock_irqsave(&hc->lock, flags);4052hfcmulti_initmode(dch);4053spin_unlock_irqrestore(&hc->lock, flags);4054}40554056if (((rq->protocol == ISDN_P_NT_S0) && (dch->state == 3)) ||4057((rq->protocol == ISDN_P_TE_S0) && (dch->state == 7)) ||4058((rq->protocol == ISDN_P_NT_E1) && (dch->state == 1)) ||4059((rq->protocol == ISDN_P_TE_E1) && (dch->state == 1))) {4060_queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY,40610, NULL, GFP_KERNEL);4062}4063rq->ch = &dch->dev.D;4064if (!try_module_get(THIS_MODULE))4065printk(KERN_WARNING "%s:cannot get module\n", __func__);4066return 0;4067}40684069static int4070open_bchannel(struct hfc_multi *hc, struct dchannel *dch,4071struct channel_req *rq)4072{4073struct bchannel *bch;4074int ch;40754076if (!test_channelmap(rq->adr.channel, dch->dev.channelmap))4077return -EINVAL;4078if (rq->protocol == ISDN_P_NONE)4079return -EINVAL;4080if (hc->ctype == HFC_TYPE_E1)4081ch = rq->adr.channel;4082else4083ch = (rq->adr.channel - 1) + (dch->slot - 2);4084bch = hc->chan[ch].bch;4085if (!bch) {4086printk(KERN_ERR "%s:internal error ch %d has no bch\n",4087__func__, ch);4088return -EINVAL;4089}4090if (test_and_set_bit(FLG_OPEN, &bch->Flags))4091return -EBUSY; /* b-channel can be only open once */4092test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);4093bch->ch.protocol = rq->protocol;4094hc->chan[ch].rx_off = 0;4095rq->ch = &bch->ch;4096if (!try_module_get(THIS_MODULE))4097printk(KERN_WARNING "%s:cannot get module\n", __func__);4098return 0;4099}41004101/*4102* device control function4103*/4104static int4105channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq)4106{4107struct hfc_multi *hc = dch->hw;4108int ret = 0;4109int wd_mode, wd_cnt;41104111switch (cq->op) {4112case MISDN_CTRL_GETOP:4113cq->op = MISDN_CTRL_HFC_OP;4114break;4115case MISDN_CTRL_HFC_WD_INIT: /* init the watchdog */4116wd_cnt = cq->p1 & 0xf;4117wd_mode = !!(cq->p1 >> 4);4118if (debug & DEBUG_HFCMULTI_MSG)4119printk(KERN_DEBUG "%s: MISDN_CTRL_HFC_WD_INIT mode %s"4120", counter 0x%x\n", __func__,4121wd_mode ? "AUTO" : "MANUAL", wd_cnt);4122/* set the watchdog timer */4123HFC_outb(hc, R_TI_WD, poll_timer | (wd_cnt << 4));4124hc->hw.r_bert_wd_md = (wd_mode ? V_AUTO_WD_RES : 0);4125if (hc->ctype == HFC_TYPE_XHFC)4126hc->hw.r_bert_wd_md |= 0x40 /* V_WD_EN */;4127/* init the watchdog register and reset the counter */4128HFC_outb(hc, R_BERT_WD_MD, hc->hw.r_bert_wd_md | V_WD_RES);4129if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {4130/* enable the watchdog output for Speech-Design */4131HFC_outb(hc, R_GPIO_SEL, V_GPIO_SEL7);4132HFC_outb(hc, R_GPIO_EN1, V_GPIO_EN15);4133HFC_outb(hc, R_GPIO_OUT1, 0);4134HFC_outb(hc, R_GPIO_OUT1, V_GPIO_OUT15);4135}4136break;4137case MISDN_CTRL_HFC_WD_RESET: /* reset the watchdog counter */4138if (debug & DEBUG_HFCMULTI_MSG)4139printk(KERN_DEBUG "%s: MISDN_CTRL_HFC_WD_RESET\n",4140__func__);4141HFC_outb(hc, R_BERT_WD_MD, hc->hw.r_bert_wd_md | V_WD_RES);4142break;4143default:4144printk(KERN_WARNING "%s: unknown Op %x\n",4145__func__, cq->op);4146ret = -EINVAL;4147break;4148}4149return ret;4150}41514152static int4153hfcm_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)4154{4155struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);4156struct dchannel *dch = container_of(dev, struct dchannel, dev);4157struct hfc_multi *hc = dch->hw;4158struct channel_req *rq;4159int err = 0;4160u_long flags;41614162if (dch->debug & DEBUG_HW)4163printk(KERN_DEBUG "%s: cmd:%x %p\n",4164__func__, cmd, arg);4165switch (cmd) {4166case OPEN_CHANNEL:4167rq = arg;4168switch (rq->protocol) {4169case ISDN_P_TE_S0:4170case ISDN_P_NT_S0:4171if (hc->ctype == HFC_TYPE_E1) {4172err = -EINVAL;4173break;4174}4175err = open_dchannel(hc, dch, rq); /* locked there */4176break;4177case ISDN_P_TE_E1:4178case ISDN_P_NT_E1:4179if (hc->ctype != HFC_TYPE_E1) {4180err = -EINVAL;4181break;4182}4183err = open_dchannel(hc, dch, rq); /* locked there */4184break;4185default:4186spin_lock_irqsave(&hc->lock, flags);4187err = open_bchannel(hc, dch, rq);4188spin_unlock_irqrestore(&hc->lock, flags);4189}4190break;4191case CLOSE_CHANNEL:4192if (debug & DEBUG_HW_OPEN)4193printk(KERN_DEBUG "%s: dev(%d) close from %p\n",4194__func__, dch->dev.id,4195__builtin_return_address(0));4196module_put(THIS_MODULE);4197break;4198case CONTROL_CHANNEL:4199spin_lock_irqsave(&hc->lock, flags);4200err = channel_dctrl(dch, arg);4201spin_unlock_irqrestore(&hc->lock, flags);4202break;4203default:4204if (dch->debug & DEBUG_HW)4205printk(KERN_DEBUG "%s: unknown command %x\n",4206__func__, cmd);4207err = -EINVAL;4208}4209return err;4210}42114212static int4213clockctl(void *priv, int enable)4214{4215struct hfc_multi *hc = priv;42164217hc->iclock_on = enable;4218return 0;4219}42204221/*4222* initialize the card4223*/42244225/*4226* start timer irq, wait some time and check if we have interrupts.4227* if not, reset chip and try again.4228*/4229static int4230init_card(struct hfc_multi *hc)4231{4232int err = -EIO;4233u_long flags;4234void __iomem *plx_acc;4235u_long plx_flags;42364237if (debug & DEBUG_HFCMULTI_INIT)4238printk(KERN_DEBUG "%s: entered\n", __func__);42394240spin_lock_irqsave(&hc->lock, flags);4241/* set interrupts but leave global interrupt disabled */4242hc->hw.r_irq_ctrl = V_FIFO_IRQ;4243disable_hwirq(hc);4244spin_unlock_irqrestore(&hc->lock, flags);42454246if (request_irq(hc->irq, hfcmulti_interrupt, IRQF_SHARED,4247"HFC-multi", hc)) {4248printk(KERN_WARNING "mISDN: Could not get interrupt %d.\n",4249hc->irq);4250hc->irq = 0;4251return -EIO;4252}42534254if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {4255spin_lock_irqsave(&plx_lock, plx_flags);4256plx_acc = hc->plx_membase + PLX_INTCSR;4257writew((PLX_INTCSR_PCIINT_ENABLE | PLX_INTCSR_LINTI1_ENABLE),4258plx_acc); /* enable PCI & LINT1 irq */4259spin_unlock_irqrestore(&plx_lock, plx_flags);4260}42614262if (debug & DEBUG_HFCMULTI_INIT)4263printk(KERN_DEBUG "%s: IRQ %d count %d\n",4264__func__, hc->irq, hc->irqcnt);4265err = init_chip(hc);4266if (err)4267goto error;4268/*4269* Finally enable IRQ output4270* this is only allowed, if an IRQ routine is already4271* established for this HFC, so don't do that earlier4272*/4273spin_lock_irqsave(&hc->lock, flags);4274enable_hwirq(hc);4275spin_unlock_irqrestore(&hc->lock, flags);4276/* printk(KERN_DEBUG "no master irq set!!!\n"); */4277set_current_state(TASK_UNINTERRUPTIBLE);4278schedule_timeout((100*HZ)/1000); /* Timeout 100ms */4279/* turn IRQ off until chip is completely initialized */4280spin_lock_irqsave(&hc->lock, flags);4281disable_hwirq(hc);4282spin_unlock_irqrestore(&hc->lock, flags);4283if (debug & DEBUG_HFCMULTI_INIT)4284printk(KERN_DEBUG "%s: IRQ %d count %d\n",4285__func__, hc->irq, hc->irqcnt);4286if (hc->irqcnt) {4287if (debug & DEBUG_HFCMULTI_INIT)4288printk(KERN_DEBUG "%s: done\n", __func__);42894290return 0;4291}4292if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) {4293printk(KERN_INFO "ignoring missing interrupts\n");4294return 0;4295}42964297printk(KERN_ERR "HFC PCI: IRQ(%d) getting no interrupts during init.\n",4298hc->irq);42994300err = -EIO;43014302error:4303if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {4304spin_lock_irqsave(&plx_lock, plx_flags);4305plx_acc = hc->plx_membase + PLX_INTCSR;4306writew(0x00, plx_acc); /*disable IRQs*/4307spin_unlock_irqrestore(&plx_lock, plx_flags);4308}43094310if (debug & DEBUG_HFCMULTI_INIT)4311printk(KERN_DEBUG "%s: free irq %d\n", __func__, hc->irq);4312if (hc->irq) {4313free_irq(hc->irq, hc);4314hc->irq = 0;4315}43164317if (debug & DEBUG_HFCMULTI_INIT)4318printk(KERN_DEBUG "%s: done (err=%d)\n", __func__, err);4319return err;4320}43214322/*4323* find pci device and set it up4324*/43254326static int4327setup_pci(struct hfc_multi *hc, struct pci_dev *pdev,4328const struct pci_device_id *ent)4329{4330struct hm_map *m = (struct hm_map *)ent->driver_data;43314332printk(KERN_INFO4333"HFC-multi: card manufacturer: '%s' card name: '%s' clock: %s\n",4334m->vendor_name, m->card_name, m->clock2 ? "double" : "normal");43354336hc->pci_dev = pdev;4337if (m->clock2)4338test_and_set_bit(HFC_CHIP_CLOCK2, &hc->chip);43394340if (ent->device == 0xB410) {4341test_and_set_bit(HFC_CHIP_B410P, &hc->chip);4342test_and_set_bit(HFC_CHIP_PCM_MASTER, &hc->chip);4343test_and_clear_bit(HFC_CHIP_PCM_SLAVE, &hc->chip);4344hc->slots = 32;4345}43464347if (hc->pci_dev->irq <= 0) {4348printk(KERN_WARNING "HFC-multi: No IRQ for PCI card found.\n");4349return -EIO;4350}4351if (pci_enable_device(hc->pci_dev)) {4352printk(KERN_WARNING "HFC-multi: Error enabling PCI card.\n");4353return -EIO;4354}4355hc->leds = m->leds;4356hc->ledstate = 0xAFFEAFFE;4357hc->opticalsupport = m->opticalsupport;43584359hc->pci_iobase = 0;4360hc->pci_membase = NULL;4361hc->plx_membase = NULL;43624363/* set memory access methods */4364if (m->io_mode) /* use mode from card config */4365hc->io_mode = m->io_mode;4366switch (hc->io_mode) {4367case HFC_IO_MODE_PLXSD:4368test_and_set_bit(HFC_CHIP_PLXSD, &hc->chip);4369hc->slots = 128; /* required */4370hc->HFC_outb = HFC_outb_pcimem;4371hc->HFC_inb = HFC_inb_pcimem;4372hc->HFC_inw = HFC_inw_pcimem;4373hc->HFC_wait = HFC_wait_pcimem;4374hc->read_fifo = read_fifo_pcimem;4375hc->write_fifo = write_fifo_pcimem;4376hc->plx_origmembase = hc->pci_dev->resource[0].start;4377/* MEMBASE 1 is PLX PCI Bridge */43784379if (!hc->plx_origmembase) {4380printk(KERN_WARNING4381"HFC-multi: No IO-Memory for PCI PLX bridge found\n");4382pci_disable_device(hc->pci_dev);4383return -EIO;4384}43854386hc->plx_membase = ioremap(hc->plx_origmembase, 0x80);4387if (!hc->plx_membase) {4388printk(KERN_WARNING4389"HFC-multi: failed to remap plx address space. "4390"(internal error)\n");4391pci_disable_device(hc->pci_dev);4392return -EIO;4393}4394printk(KERN_INFO4395"HFC-multi: plx_membase:%#lx plx_origmembase:%#lx\n",4396(u_long)hc->plx_membase, hc->plx_origmembase);43974398hc->pci_origmembase = hc->pci_dev->resource[2].start;4399/* MEMBASE 1 is PLX PCI Bridge */4400if (!hc->pci_origmembase) {4401printk(KERN_WARNING4402"HFC-multi: No IO-Memory for PCI card found\n");4403pci_disable_device(hc->pci_dev);4404return -EIO;4405}44064407hc->pci_membase = ioremap(hc->pci_origmembase, 0x400);4408if (!hc->pci_membase) {4409printk(KERN_WARNING "HFC-multi: failed to remap io "4410"address space. (internal error)\n");4411pci_disable_device(hc->pci_dev);4412return -EIO;4413}44144415printk(KERN_INFO4416"card %d: defined at MEMBASE %#lx (%#lx) IRQ %d HZ %d "4417"leds-type %d\n",4418hc->id, (u_long)hc->pci_membase, hc->pci_origmembase,4419hc->pci_dev->irq, HZ, hc->leds);4420pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO);4421break;4422case HFC_IO_MODE_PCIMEM:4423hc->HFC_outb = HFC_outb_pcimem;4424hc->HFC_inb = HFC_inb_pcimem;4425hc->HFC_inw = HFC_inw_pcimem;4426hc->HFC_wait = HFC_wait_pcimem;4427hc->read_fifo = read_fifo_pcimem;4428hc->write_fifo = write_fifo_pcimem;4429hc->pci_origmembase = hc->pci_dev->resource[1].start;4430if (!hc->pci_origmembase) {4431printk(KERN_WARNING4432"HFC-multi: No IO-Memory for PCI card found\n");4433pci_disable_device(hc->pci_dev);4434return -EIO;4435}44364437hc->pci_membase = ioremap(hc->pci_origmembase, 256);4438if (!hc->pci_membase) {4439printk(KERN_WARNING4440"HFC-multi: failed to remap io address space. "4441"(internal error)\n");4442pci_disable_device(hc->pci_dev);4443return -EIO;4444}4445printk(KERN_INFO "card %d: defined at MEMBASE %#lx (%#lx) IRQ "4446"%d HZ %d leds-type %d\n", hc->id, (u_long)hc->pci_membase,4447hc->pci_origmembase, hc->pci_dev->irq, HZ, hc->leds);4448pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO);4449break;4450case HFC_IO_MODE_REGIO:4451hc->HFC_outb = HFC_outb_regio;4452hc->HFC_inb = HFC_inb_regio;4453hc->HFC_inw = HFC_inw_regio;4454hc->HFC_wait = HFC_wait_regio;4455hc->read_fifo = read_fifo_regio;4456hc->write_fifo = write_fifo_regio;4457hc->pci_iobase = (u_int) hc->pci_dev->resource[0].start;4458if (!hc->pci_iobase) {4459printk(KERN_WARNING4460"HFC-multi: No IO for PCI card found\n");4461pci_disable_device(hc->pci_dev);4462return -EIO;4463}44644465if (!request_region(hc->pci_iobase, 8, "hfcmulti")) {4466printk(KERN_WARNING "HFC-multi: failed to request "4467"address space at 0x%08lx (internal error)\n",4468hc->pci_iobase);4469pci_disable_device(hc->pci_dev);4470return -EIO;4471}44724473printk(KERN_INFO4474"%s %s: defined at IOBASE %#x IRQ %d HZ %d leds-type %d\n",4475m->vendor_name, m->card_name, (u_int) hc->pci_iobase,4476hc->pci_dev->irq, HZ, hc->leds);4477pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_REGIO);4478break;4479default:4480printk(KERN_WARNING "HFC-multi: Invalid IO mode.\n");4481pci_disable_device(hc->pci_dev);4482return -EIO;4483}44844485pci_set_drvdata(hc->pci_dev, hc);44864487/* At this point the needed PCI config is done */4488/* fifos are still not enabled */4489return 0;4490}449144924493/*4494* remove port4495*/44964497static void4498release_port(struct hfc_multi *hc, struct dchannel *dch)4499{4500int pt, ci, i = 0;4501u_long flags;4502struct bchannel *pb;45034504ci = dch->slot;4505pt = hc->chan[ci].port;45064507if (debug & DEBUG_HFCMULTI_INIT)4508printk(KERN_DEBUG "%s: entered for port %d\n",4509__func__, pt + 1);45104511if (pt >= hc->ports) {4512printk(KERN_WARNING "%s: ERROR port out of range (%d).\n",4513__func__, pt + 1);4514return;4515}45164517if (debug & DEBUG_HFCMULTI_INIT)4518printk(KERN_DEBUG "%s: releasing port=%d\n",4519__func__, pt + 1);45204521if (dch->dev.D.protocol == ISDN_P_TE_S0)4522l1_event(dch->l1, CLOSE_CHANNEL);45234524hc->chan[ci].dch = NULL;45254526if (hc->created[pt]) {4527hc->created[pt] = 0;4528mISDN_unregister_device(&dch->dev);4529}45304531spin_lock_irqsave(&hc->lock, flags);45324533if (dch->timer.function) {4534del_timer(&dch->timer);4535dch->timer.function = NULL;4536}45374538if (hc->ctype == HFC_TYPE_E1) { /* E1 */4539/* remove sync */4540if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {4541hc->syncronized = 0;4542plxsd_checksync(hc, 1);4543}4544/* free channels */4545for (i = 0; i <= 31; i++) {4546if (hc->chan[i].bch) {4547if (debug & DEBUG_HFCMULTI_INIT)4548printk(KERN_DEBUG4549"%s: free port %d channel %d\n",4550__func__, hc->chan[i].port+1, i);4551pb = hc->chan[i].bch;4552hc->chan[i].bch = NULL;4553spin_unlock_irqrestore(&hc->lock, flags);4554mISDN_freebchannel(pb);4555kfree(pb);4556kfree(hc->chan[i].coeff);4557spin_lock_irqsave(&hc->lock, flags);4558}4559}4560} else {4561/* remove sync */4562if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {4563hc->syncronized &=4564~(1 << hc->chan[ci].port);4565plxsd_checksync(hc, 1);4566}4567/* free channels */4568if (hc->chan[ci - 2].bch) {4569if (debug & DEBUG_HFCMULTI_INIT)4570printk(KERN_DEBUG4571"%s: free port %d channel %d\n",4572__func__, hc->chan[ci - 2].port+1,4573ci - 2);4574pb = hc->chan[ci - 2].bch;4575hc->chan[ci - 2].bch = NULL;4576spin_unlock_irqrestore(&hc->lock, flags);4577mISDN_freebchannel(pb);4578kfree(pb);4579kfree(hc->chan[ci - 2].coeff);4580spin_lock_irqsave(&hc->lock, flags);4581}4582if (hc->chan[ci - 1].bch) {4583if (debug & DEBUG_HFCMULTI_INIT)4584printk(KERN_DEBUG4585"%s: free port %d channel %d\n",4586__func__, hc->chan[ci - 1].port+1,4587ci - 1);4588pb = hc->chan[ci - 1].bch;4589hc->chan[ci - 1].bch = NULL;4590spin_unlock_irqrestore(&hc->lock, flags);4591mISDN_freebchannel(pb);4592kfree(pb);4593kfree(hc->chan[ci - 1].coeff);4594spin_lock_irqsave(&hc->lock, flags);4595}4596}45974598spin_unlock_irqrestore(&hc->lock, flags);45994600if (debug & DEBUG_HFCMULTI_INIT)4601printk(KERN_DEBUG "%s: free port %d channel D\n", __func__, pt);4602mISDN_freedchannel(dch);4603kfree(dch);46044605if (debug & DEBUG_HFCMULTI_INIT)4606printk(KERN_DEBUG "%s: done!\n", __func__);4607}46084609static void4610release_card(struct hfc_multi *hc)4611{4612u_long flags;4613int ch;46144615if (debug & DEBUG_HFCMULTI_INIT)4616printk(KERN_DEBUG "%s: release card (%d) entered\n",4617__func__, hc->id);46184619/* unregister clock source */4620if (hc->iclock)4621mISDN_unregister_clock(hc->iclock);46224623/* disable irq */4624spin_lock_irqsave(&hc->lock, flags);4625disable_hwirq(hc);4626spin_unlock_irqrestore(&hc->lock, flags);4627udelay(1000);46284629/* dimm leds */4630if (hc->leds)4631hfcmulti_leds(hc);46324633/* disable D-channels & B-channels */4634if (debug & DEBUG_HFCMULTI_INIT)4635printk(KERN_DEBUG "%s: disable all channels (d and b)\n",4636__func__);4637for (ch = 0; ch <= 31; ch++) {4638if (hc->chan[ch].dch)4639release_port(hc, hc->chan[ch].dch);4640}46414642/* release hardware & irq */4643if (hc->irq) {4644if (debug & DEBUG_HFCMULTI_INIT)4645printk(KERN_DEBUG "%s: free irq %d\n",4646__func__, hc->irq);4647free_irq(hc->irq, hc);4648hc->irq = 0;46494650}4651release_io_hfcmulti(hc);46524653if (debug & DEBUG_HFCMULTI_INIT)4654printk(KERN_DEBUG "%s: remove instance from list\n",4655__func__);4656list_del(&hc->list);46574658if (debug & DEBUG_HFCMULTI_INIT)4659printk(KERN_DEBUG "%s: delete instance\n", __func__);4660if (hc == syncmaster)4661syncmaster = NULL;4662kfree(hc);4663if (debug & DEBUG_HFCMULTI_INIT)4664printk(KERN_DEBUG "%s: card successfully removed\n",4665__func__);4666}46674668static int4669init_e1_port(struct hfc_multi *hc, struct hm_map *m)4670{4671struct dchannel *dch;4672struct bchannel *bch;4673int ch, ret = 0;4674char name[MISDN_MAX_IDLEN];46754676dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL);4677if (!dch)4678return -ENOMEM;4679dch->debug = debug;4680mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, ph_state_change);4681dch->hw = hc;4682dch->dev.Dprotocols = (1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1);4683dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |4684(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));4685dch->dev.D.send = handle_dmsg;4686dch->dev.D.ctrl = hfcm_dctrl;4687dch->dev.nrbchan = (hc->dslot) ? 30 : 31;4688dch->slot = hc->dslot;4689hc->chan[hc->dslot].dch = dch;4690hc->chan[hc->dslot].port = 0;4691hc->chan[hc->dslot].nt_timer = -1;4692for (ch = 1; ch <= 31; ch++) {4693if (ch == hc->dslot) /* skip dchannel */4694continue;4695bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL);4696if (!bch) {4697printk(KERN_ERR "%s: no memory for bchannel\n",4698__func__);4699ret = -ENOMEM;4700goto free_chan;4701}4702hc->chan[ch].coeff = kzalloc(512, GFP_KERNEL);4703if (!hc->chan[ch].coeff) {4704printk(KERN_ERR "%s: no memory for coeffs\n",4705__func__);4706ret = -ENOMEM;4707kfree(bch);4708goto free_chan;4709}4710bch->nr = ch;4711bch->slot = ch;4712bch->debug = debug;4713mISDN_initbchannel(bch, MAX_DATA_MEM);4714bch->hw = hc;4715bch->ch.send = handle_bmsg;4716bch->ch.ctrl = hfcm_bctrl;4717bch->ch.nr = ch;4718list_add(&bch->ch.list, &dch->dev.bchannels);4719hc->chan[ch].bch = bch;4720hc->chan[ch].port = 0;4721set_channelmap(bch->nr, dch->dev.channelmap);4722}4723/* set optical line type */4724if (port[Port_cnt] & 0x001) {4725if (!m->opticalsupport) {4726printk(KERN_INFO4727"This board has no optical "4728"support\n");4729} else {4730if (debug & DEBUG_HFCMULTI_INIT)4731printk(KERN_DEBUG4732"%s: PORT set optical "4733"interfacs: card(%d) "4734"port(%d)\n",4735__func__,4736HFC_cnt + 1, 1);4737test_and_set_bit(HFC_CFG_OPTICAL,4738&hc->chan[hc->dslot].cfg);4739}4740}4741/* set LOS report */4742if (port[Port_cnt] & 0x004) {4743if (debug & DEBUG_HFCMULTI_INIT)4744printk(KERN_DEBUG "%s: PORT set "4745"LOS report: card(%d) port(%d)\n",4746__func__, HFC_cnt + 1, 1);4747test_and_set_bit(HFC_CFG_REPORT_LOS,4748&hc->chan[hc->dslot].cfg);4749}4750/* set AIS report */4751if (port[Port_cnt] & 0x008) {4752if (debug & DEBUG_HFCMULTI_INIT)4753printk(KERN_DEBUG "%s: PORT set "4754"AIS report: card(%d) port(%d)\n",4755__func__, HFC_cnt + 1, 1);4756test_and_set_bit(HFC_CFG_REPORT_AIS,4757&hc->chan[hc->dslot].cfg);4758}4759/* set SLIP report */4760if (port[Port_cnt] & 0x010) {4761if (debug & DEBUG_HFCMULTI_INIT)4762printk(KERN_DEBUG4763"%s: PORT set SLIP report: "4764"card(%d) port(%d)\n",4765__func__, HFC_cnt + 1, 1);4766test_and_set_bit(HFC_CFG_REPORT_SLIP,4767&hc->chan[hc->dslot].cfg);4768}4769/* set RDI report */4770if (port[Port_cnt] & 0x020) {4771if (debug & DEBUG_HFCMULTI_INIT)4772printk(KERN_DEBUG4773"%s: PORT set RDI report: "4774"card(%d) port(%d)\n",4775__func__, HFC_cnt + 1, 1);4776test_and_set_bit(HFC_CFG_REPORT_RDI,4777&hc->chan[hc->dslot].cfg);4778}4779/* set CRC-4 Mode */4780if (!(port[Port_cnt] & 0x100)) {4781if (debug & DEBUG_HFCMULTI_INIT)4782printk(KERN_DEBUG "%s: PORT turn on CRC4 report:"4783" card(%d) port(%d)\n",4784__func__, HFC_cnt + 1, 1);4785test_and_set_bit(HFC_CFG_CRC4,4786&hc->chan[hc->dslot].cfg);4787} else {4788if (debug & DEBUG_HFCMULTI_INIT)4789printk(KERN_DEBUG "%s: PORT turn off CRC4"4790" report: card(%d) port(%d)\n",4791__func__, HFC_cnt + 1, 1);4792}4793/* set forced clock */4794if (port[Port_cnt] & 0x0200) {4795if (debug & DEBUG_HFCMULTI_INIT)4796printk(KERN_DEBUG "%s: PORT force getting clock from "4797"E1: card(%d) port(%d)\n",4798__func__, HFC_cnt + 1, 1);4799test_and_set_bit(HFC_CHIP_E1CLOCK_GET, &hc->chip);4800} else4801if (port[Port_cnt] & 0x0400) {4802if (debug & DEBUG_HFCMULTI_INIT)4803printk(KERN_DEBUG "%s: PORT force putting clock to "4804"E1: card(%d) port(%d)\n",4805__func__, HFC_cnt + 1, 1);4806test_and_set_bit(HFC_CHIP_E1CLOCK_PUT, &hc->chip);4807}4808/* set JATT PLL */4809if (port[Port_cnt] & 0x0800) {4810if (debug & DEBUG_HFCMULTI_INIT)4811printk(KERN_DEBUG "%s: PORT disable JATT PLL on "4812"E1: card(%d) port(%d)\n",4813__func__, HFC_cnt + 1, 1);4814test_and_set_bit(HFC_CHIP_RX_SYNC, &hc->chip);4815}4816/* set elastic jitter buffer */4817if (port[Port_cnt] & 0x3000) {4818hc->chan[hc->dslot].jitter = (port[Port_cnt]>>12) & 0x3;4819if (debug & DEBUG_HFCMULTI_INIT)4820printk(KERN_DEBUG4821"%s: PORT set elastic "4822"buffer to %d: card(%d) port(%d)\n",4823__func__, hc->chan[hc->dslot].jitter,4824HFC_cnt + 1, 1);4825} else4826hc->chan[hc->dslot].jitter = 2; /* default */4827snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1);4828ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name);4829if (ret)4830goto free_chan;4831hc->created[0] = 1;4832return ret;4833free_chan:4834release_port(hc, dch);4835return ret;4836}48374838static int4839init_multi_port(struct hfc_multi *hc, int pt)4840{4841struct dchannel *dch;4842struct bchannel *bch;4843int ch, i, ret = 0;4844char name[MISDN_MAX_IDLEN];48454846dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL);4847if (!dch)4848return -ENOMEM;4849dch->debug = debug;4850mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, ph_state_change);4851dch->hw = hc;4852dch->dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0);4853dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |4854(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));4855dch->dev.D.send = handle_dmsg;4856dch->dev.D.ctrl = hfcm_dctrl;4857dch->dev.nrbchan = 2;4858i = pt << 2;4859dch->slot = i + 2;4860hc->chan[i + 2].dch = dch;4861hc->chan[i + 2].port = pt;4862hc->chan[i + 2].nt_timer = -1;4863for (ch = 0; ch < dch->dev.nrbchan; ch++) {4864bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL);4865if (!bch) {4866printk(KERN_ERR "%s: no memory for bchannel\n",4867__func__);4868ret = -ENOMEM;4869goto free_chan;4870}4871hc->chan[i + ch].coeff = kzalloc(512, GFP_KERNEL);4872if (!hc->chan[i + ch].coeff) {4873printk(KERN_ERR "%s: no memory for coeffs\n",4874__func__);4875ret = -ENOMEM;4876kfree(bch);4877goto free_chan;4878}4879bch->nr = ch + 1;4880bch->slot = i + ch;4881bch->debug = debug;4882mISDN_initbchannel(bch, MAX_DATA_MEM);4883bch->hw = hc;4884bch->ch.send = handle_bmsg;4885bch->ch.ctrl = hfcm_bctrl;4886bch->ch.nr = ch + 1;4887list_add(&bch->ch.list, &dch->dev.bchannels);4888hc->chan[i + ch].bch = bch;4889hc->chan[i + ch].port = pt;4890set_channelmap(bch->nr, dch->dev.channelmap);4891}4892/* set master clock */4893if (port[Port_cnt] & 0x001) {4894if (debug & DEBUG_HFCMULTI_INIT)4895printk(KERN_DEBUG4896"%s: PROTOCOL set master clock: "4897"card(%d) port(%d)\n",4898__func__, HFC_cnt + 1, pt + 1);4899if (dch->dev.D.protocol != ISDN_P_TE_S0) {4900printk(KERN_ERR "Error: Master clock "4901"for port(%d) of card(%d) is only"4902" possible with TE-mode\n",4903pt + 1, HFC_cnt + 1);4904ret = -EINVAL;4905goto free_chan;4906}4907if (hc->masterclk >= 0) {4908printk(KERN_ERR "Error: Master clock "4909"for port(%d) of card(%d) already "4910"defined for port(%d)\n",4911pt + 1, HFC_cnt + 1, hc->masterclk+1);4912ret = -EINVAL;4913goto free_chan;4914}4915hc->masterclk = pt;4916}4917/* set transmitter line to non capacitive */4918if (port[Port_cnt] & 0x002) {4919if (debug & DEBUG_HFCMULTI_INIT)4920printk(KERN_DEBUG4921"%s: PROTOCOL set non capacitive "4922"transmitter: card(%d) port(%d)\n",4923__func__, HFC_cnt + 1, pt + 1);4924test_and_set_bit(HFC_CFG_NONCAP_TX,4925&hc->chan[i + 2].cfg);4926}4927/* disable E-channel */4928if (port[Port_cnt] & 0x004) {4929if (debug & DEBUG_HFCMULTI_INIT)4930printk(KERN_DEBUG4931"%s: PROTOCOL disable E-channel: "4932"card(%d) port(%d)\n",4933__func__, HFC_cnt + 1, pt + 1);4934test_and_set_bit(HFC_CFG_DIS_ECHANNEL,4935&hc->chan[i + 2].cfg);4936}4937if (hc->ctype == HFC_TYPE_XHFC) {4938snprintf(name, MISDN_MAX_IDLEN - 1, "xhfc.%d-%d",4939HFC_cnt + 1, pt + 1);4940ret = mISDN_register_device(&dch->dev, NULL, name);4941} else {4942snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-%ds.%d-%d",4943hc->ctype, HFC_cnt + 1, pt + 1);4944ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name);4945}4946if (ret)4947goto free_chan;4948hc->created[pt] = 1;4949return ret;4950free_chan:4951release_port(hc, dch);4952return ret;4953}49544955static int4956hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,4957const struct pci_device_id *ent)4958{4959int ret_err = 0;4960int pt;4961struct hfc_multi *hc;4962u_long flags;4963u_char dips = 0, pmj = 0; /* dip settings, port mode Jumpers */4964int i;49654966if (HFC_cnt >= MAX_CARDS) {4967printk(KERN_ERR "too many cards (max=%d).\n",4968MAX_CARDS);4969return -EINVAL;4970}4971if ((type[HFC_cnt] & 0xff) && (type[HFC_cnt] & 0xff) != m->type) {4972printk(KERN_WARNING "HFC-MULTI: Card '%s:%s' type %d found but "4973"type[%d] %d was supplied as module parameter\n",4974m->vendor_name, m->card_name, m->type, HFC_cnt,4975type[HFC_cnt] & 0xff);4976printk(KERN_WARNING "HFC-MULTI: Load module without parameters "4977"first, to see cards and their types.");4978return -EINVAL;4979}4980if (debug & DEBUG_HFCMULTI_INIT)4981printk(KERN_DEBUG "%s: Registering %s:%s chip type %d (0x%x)\n",4982__func__, m->vendor_name, m->card_name, m->type,4983type[HFC_cnt]);49844985/* allocate card+fifo structure */4986hc = kzalloc(sizeof(struct hfc_multi), GFP_KERNEL);4987if (!hc) {4988printk(KERN_ERR "No kmem for HFC-Multi card\n");4989return -ENOMEM;4990}4991spin_lock_init(&hc->lock);4992hc->mtyp = m;4993hc->ctype = m->type;4994hc->ports = m->ports;4995hc->id = HFC_cnt;4996hc->pcm = pcm[HFC_cnt];4997hc->io_mode = iomode[HFC_cnt];4998if (dslot[HFC_cnt] < 0 && hc->ctype == HFC_TYPE_E1) {4999hc->dslot = 0;5000printk(KERN_INFO "HFC-E1 card has disabled D-channel, but "5001"31 B-channels\n");5002}5003if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 325004&& hc->ctype == HFC_TYPE_E1) {5005hc->dslot = dslot[HFC_cnt];5006printk(KERN_INFO "HFC-E1 card has alternating D-channel on "5007"time slot %d\n", dslot[HFC_cnt]);5008} else5009hc->dslot = 16;50105011/* set chip specific features */5012hc->masterclk = -1;5013if (type[HFC_cnt] & 0x100) {5014test_and_set_bit(HFC_CHIP_ULAW, &hc->chip);5015hc->silence = 0xff; /* ulaw silence */5016} else5017hc->silence = 0x2a; /* alaw silence */5018if ((poll >> 1) > sizeof(hc->silence_data)) {5019printk(KERN_ERR "HFCMULTI error: silence_data too small, "5020"please fix\n");5021return -EINVAL;5022}5023for (i = 0; i < (poll >> 1); i++)5024hc->silence_data[i] = hc->silence;50255026if (hc->ctype != HFC_TYPE_XHFC) {5027if (!(type[HFC_cnt] & 0x200))5028test_and_set_bit(HFC_CHIP_DTMF, &hc->chip);5029test_and_set_bit(HFC_CHIP_CONF, &hc->chip);5030}50315032if (type[HFC_cnt] & 0x800)5033test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip);5034if (type[HFC_cnt] & 0x1000) {5035test_and_set_bit(HFC_CHIP_PCM_MASTER, &hc->chip);5036test_and_clear_bit(HFC_CHIP_PCM_SLAVE, &hc->chip);5037}5038if (type[HFC_cnt] & 0x4000)5039test_and_set_bit(HFC_CHIP_EXRAM_128, &hc->chip);5040if (type[HFC_cnt] & 0x8000)5041test_and_set_bit(HFC_CHIP_EXRAM_512, &hc->chip);5042hc->slots = 32;5043if (type[HFC_cnt] & 0x10000)5044hc->slots = 64;5045if (type[HFC_cnt] & 0x20000)5046hc->slots = 128;5047if (type[HFC_cnt] & 0x80000) {5048test_and_set_bit(HFC_CHIP_WATCHDOG, &hc->chip);5049hc->wdcount = 0;5050hc->wdbyte = V_GPIO_OUT2;5051printk(KERN_NOTICE "Watchdog enabled\n");5052}50535054if (pdev && ent)5055/* setup pci, hc->slots may change due to PLXSD */5056ret_err = setup_pci(hc, pdev, ent);5057else5058#ifdef CONFIG_MISDN_HFCMULTI_8xx5059ret_err = setup_embedded(hc, m);5060#else5061{5062printk(KERN_WARNING "Embedded IO Mode not selected\n");5063ret_err = -EIO;5064}5065#endif5066if (ret_err) {5067if (hc == syncmaster)5068syncmaster = NULL;5069kfree(hc);5070return ret_err;5071}50725073hc->HFC_outb_nodebug = hc->HFC_outb;5074hc->HFC_inb_nodebug = hc->HFC_inb;5075hc->HFC_inw_nodebug = hc->HFC_inw;5076hc->HFC_wait_nodebug = hc->HFC_wait;5077#ifdef HFC_REGISTER_DEBUG5078hc->HFC_outb = HFC_outb_debug;5079hc->HFC_inb = HFC_inb_debug;5080hc->HFC_inw = HFC_inw_debug;5081hc->HFC_wait = HFC_wait_debug;5082#endif5083/* create channels */5084for (pt = 0; pt < hc->ports; pt++) {5085if (Port_cnt >= MAX_PORTS) {5086printk(KERN_ERR "too many ports (max=%d).\n",5087MAX_PORTS);5088ret_err = -EINVAL;5089goto free_card;5090}5091if (hc->ctype == HFC_TYPE_E1)5092ret_err = init_e1_port(hc, m);5093else5094ret_err = init_multi_port(hc, pt);5095if (debug & DEBUG_HFCMULTI_INIT)5096printk(KERN_DEBUG5097"%s: Registering D-channel, card(%d) port(%d)"5098"result %d\n",5099__func__, HFC_cnt + 1, pt, ret_err);51005101if (ret_err) {5102while (pt) { /* release already registered ports */5103pt--;5104release_port(hc, hc->chan[(pt << 2) + 2].dch);5105}5106goto free_card;5107}5108Port_cnt++;5109}51105111/* disp switches */5112switch (m->dip_type) {5113case DIP_4S:5114/*5115* Get DIP setting for beroNet 1S/2S/4S cards5116* DIP Setting: (collect GPIO 13/14/15 (R_GPIO_IN1) +5117* GPI 19/23 (R_GPI_IN2))5118*/5119dips = ((~HFC_inb(hc, R_GPIO_IN1) & 0xE0) >> 5) |5120((~HFC_inb(hc, R_GPI_IN2) & 0x80) >> 3) |5121(~HFC_inb(hc, R_GPI_IN2) & 0x08);51225123/* Port mode (TE/NT) jumpers */5124pmj = ((HFC_inb(hc, R_GPI_IN3) >> 4) & 0xf);51255126if (test_bit(HFC_CHIP_B410P, &hc->chip))5127pmj = ~pmj & 0xf;51285129printk(KERN_INFO "%s: %s DIPs(0x%x) jumpers(0x%x)\n",5130m->vendor_name, m->card_name, dips, pmj);5131break;5132case DIP_8S:5133/*5134* Get DIP Setting for beroNet 8S0+ cards5135* Enable PCI auxbridge function5136*/5137HFC_outb(hc, R_BRG_PCM_CFG, 1 | V_PCM_CLK);5138/* prepare access to auxport */5139outw(0x4000, hc->pci_iobase + 4);5140/*5141* some dummy reads are required to5142* read valid DIP switch data5143*/5144dips = inb(hc->pci_iobase);5145dips = inb(hc->pci_iobase);5146dips = inb(hc->pci_iobase);5147dips = ~inb(hc->pci_iobase) & 0x3F;5148outw(0x0, hc->pci_iobase + 4);5149/* disable PCI auxbridge function */5150HFC_outb(hc, R_BRG_PCM_CFG, V_PCM_CLK);5151printk(KERN_INFO "%s: %s DIPs(0x%x)\n",5152m->vendor_name, m->card_name, dips);5153break;5154case DIP_E1:5155/*5156* get DIP Setting for beroNet E1 cards5157* DIP Setting: collect GPI 4/5/6/7 (R_GPI_IN0)5158*/5159dips = (~HFC_inb(hc, R_GPI_IN0) & 0xF0)>>4;5160printk(KERN_INFO "%s: %s DIPs(0x%x)\n",5161m->vendor_name, m->card_name, dips);5162break;5163}51645165/* add to list */5166spin_lock_irqsave(&HFClock, flags);5167list_add_tail(&hc->list, &HFClist);5168spin_unlock_irqrestore(&HFClock, flags);51695170/* use as clock source */5171if (clock == HFC_cnt + 1)5172hc->iclock = mISDN_register_clock("HFCMulti", 0, clockctl, hc);51735174/* initialize hardware */5175hc->irq = (m->irq) ? : hc->pci_dev->irq;5176ret_err = init_card(hc);5177if (ret_err) {5178printk(KERN_ERR "init card returns %d\n", ret_err);5179release_card(hc);5180return ret_err;5181}51825183/* start IRQ and return */5184spin_lock_irqsave(&hc->lock, flags);5185enable_hwirq(hc);5186spin_unlock_irqrestore(&hc->lock, flags);5187return 0;51885189free_card:5190release_io_hfcmulti(hc);5191if (hc == syncmaster)5192syncmaster = NULL;5193kfree(hc);5194return ret_err;5195}51965197static void __devexit hfc_remove_pci(struct pci_dev *pdev)5198{5199struct hfc_multi *card = pci_get_drvdata(pdev);5200u_long flags;52015202if (debug)5203printk(KERN_INFO "removing hfc_multi card vendor:%x "5204"device:%x subvendor:%x subdevice:%x\n",5205pdev->vendor, pdev->device,5206pdev->subsystem_vendor, pdev->subsystem_device);52075208if (card) {5209spin_lock_irqsave(&HFClock, flags);5210release_card(card);5211spin_unlock_irqrestore(&HFClock, flags);5212} else {5213if (debug)5214printk(KERN_DEBUG "%s: drvdata already removed\n",5215__func__);5216}5217}52185219#define VENDOR_CCD "Cologne Chip AG"5220#define VENDOR_BN "beroNet GmbH"5221#define VENDOR_DIG "Digium Inc."5222#define VENDOR_JH "Junghanns.NET GmbH"5223#define VENDOR_PRIM "PrimuX"52245225static const struct hm_map hfcm_map[] = {5226/*0*/ {VENDOR_BN, "HFC-1S Card (mini PCI)", 4, 1, 1, 3, 0, DIP_4S, 0, 0},5227/*1*/ {VENDOR_BN, "HFC-2S Card", 4, 2, 1, 3, 0, DIP_4S, 0, 0},5228/*2*/ {VENDOR_BN, "HFC-2S Card (mini PCI)", 4, 2, 1, 3, 0, DIP_4S, 0, 0},5229/*3*/ {VENDOR_BN, "HFC-4S Card", 4, 4, 1, 2, 0, DIP_4S, 0, 0},5230/*4*/ {VENDOR_BN, "HFC-4S Card (mini PCI)", 4, 4, 1, 2, 0, 0, 0, 0},5231/*5*/ {VENDOR_CCD, "HFC-4S Eval (old)", 4, 4, 0, 0, 0, 0, 0, 0},5232/*6*/ {VENDOR_CCD, "HFC-4S IOB4ST", 4, 4, 1, 2, 0, DIP_4S, 0, 0},5233/*7*/ {VENDOR_CCD, "HFC-4S", 4, 4, 1, 2, 0, 0, 0, 0},5234/*8*/ {VENDOR_DIG, "HFC-4S Card", 4, 4, 0, 2, 0, 0, HFC_IO_MODE_REGIO, 0},5235/*9*/ {VENDOR_CCD, "HFC-4S Swyx 4xS0 SX2 QuadBri", 4, 4, 1, 2, 0, 0, 0, 0},5236/*10*/ {VENDOR_JH, "HFC-4S (junghanns 2.0)", 4, 4, 1, 2, 0, 0, 0, 0},5237/*11*/ {VENDOR_PRIM, "HFC-2S Primux Card", 4, 2, 0, 0, 0, 0, 0, 0},52385239/*12*/ {VENDOR_BN, "HFC-8S Card", 8, 8, 1, 0, 0, 0, 0, 0},5240/*13*/ {VENDOR_BN, "HFC-8S Card (+)", 8, 8, 1, 8, 0, DIP_8S,5241HFC_IO_MODE_REGIO, 0},5242/*14*/ {VENDOR_CCD, "HFC-8S Eval (old)", 8, 8, 0, 0, 0, 0, 0, 0},5243/*15*/ {VENDOR_CCD, "HFC-8S IOB4ST Recording", 8, 8, 1, 0, 0, 0, 0, 0},52445245/*16*/ {VENDOR_CCD, "HFC-8S IOB8ST", 8, 8, 1, 0, 0, 0, 0, 0},5246/*17*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0, 0},5247/*18*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0, 0},52485249/*19*/ {VENDOR_BN, "HFC-E1 Card", 1, 1, 0, 1, 0, DIP_E1, 0, 0},5250/*20*/ {VENDOR_BN, "HFC-E1 Card (mini PCI)", 1, 1, 0, 1, 0, 0, 0, 0},5251/*21*/ {VENDOR_BN, "HFC-E1+ Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0, 0},5252/*22*/ {VENDOR_BN, "HFC-E1 Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0, 0},52535254/*23*/ {VENDOR_CCD, "HFC-E1 Eval (old)", 1, 1, 0, 0, 0, 0, 0, 0},5255/*24*/ {VENDOR_CCD, "HFC-E1 IOB1E1", 1, 1, 0, 1, 0, 0, 0, 0},5256/*25*/ {VENDOR_CCD, "HFC-E1", 1, 1, 0, 1, 0, 0, 0, 0},52575258/*26*/ {VENDOR_CCD, "HFC-4S Speech Design", 4, 4, 0, 0, 0, 0,5259HFC_IO_MODE_PLXSD, 0},5260/*27*/ {VENDOR_CCD, "HFC-E1 Speech Design", 1, 1, 0, 0, 0, 0,5261HFC_IO_MODE_PLXSD, 0},5262/*28*/ {VENDOR_CCD, "HFC-4S OpenVox", 4, 4, 1, 0, 0, 0, 0, 0},5263/*29*/ {VENDOR_CCD, "HFC-2S OpenVox", 4, 2, 1, 0, 0, 0, 0, 0},5264/*30*/ {VENDOR_CCD, "HFC-8S OpenVox", 8, 8, 1, 0, 0, 0, 0, 0},5265/*31*/ {VENDOR_CCD, "XHFC-4S Speech Design", 5, 4, 0, 0, 0, 0,5266HFC_IO_MODE_EMBSD, XHFC_IRQ},5267/*32*/ {VENDOR_JH, "HFC-8S (junghanns)", 8, 8, 1, 0, 0, 0, 0, 0},5268/*33*/ {VENDOR_BN, "HFC-2S Beronet Card PCIe", 4, 2, 1, 3, 0, DIP_4S, 0, 0},5269/*34*/ {VENDOR_BN, "HFC-4S Beronet Card PCIe", 4, 4, 1, 2, 0, DIP_4S, 0, 0},5270};52715272#undef H5273#define H(x) ((unsigned long)&hfcm_map[x])5274static struct pci_device_id hfmultipci_ids[] __devinitdata = {52755276/* Cards with HFC-4S Chip */5277{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,5278PCI_SUBDEVICE_ID_CCD_BN1SM, 0, 0, H(0)}, /* BN1S mini PCI */5279{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,5280PCI_SUBDEVICE_ID_CCD_BN2S, 0, 0, H(1)}, /* BN2S */5281{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,5282PCI_SUBDEVICE_ID_CCD_BN2SM, 0, 0, H(2)}, /* BN2S mini PCI */5283{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,5284PCI_SUBDEVICE_ID_CCD_BN4S, 0, 0, H(3)}, /* BN4S */5285{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,5286PCI_SUBDEVICE_ID_CCD_BN4SM, 0, 0, H(4)}, /* BN4S mini PCI */5287{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,5288PCI_DEVICE_ID_CCD_HFC4S, 0, 0, H(5)}, /* Old Eval */5289{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,5290PCI_SUBDEVICE_ID_CCD_IOB4ST, 0, 0, H(6)}, /* IOB4ST */5291{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,5292PCI_SUBDEVICE_ID_CCD_HFC4S, 0, 0, H(7)}, /* 4S */5293{ PCI_VENDOR_ID_DIGIUM, PCI_DEVICE_ID_DIGIUM_HFC4S,5294PCI_VENDOR_ID_DIGIUM, PCI_DEVICE_ID_DIGIUM_HFC4S, 0, 0, H(8)},5295{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,5296PCI_SUBDEVICE_ID_CCD_SWYX4S, 0, 0, H(9)}, /* 4S Swyx */5297{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,5298PCI_SUBDEVICE_ID_CCD_JH4S20, 0, 0, H(10)},5299{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,5300PCI_SUBDEVICE_ID_CCD_PMX2S, 0, 0, H(11)}, /* Primux */5301{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,5302PCI_SUBDEVICE_ID_CCD_OV4S, 0, 0, H(28)}, /* OpenVox 4 */5303{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,5304PCI_SUBDEVICE_ID_CCD_OV2S, 0, 0, H(29)}, /* OpenVox 2 */5305{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,53060xb761, 0, 0, H(33)}, /* BN2S PCIe */5307{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,53080xb762, 0, 0, H(34)}, /* BN4S PCIe */53095310/* Cards with HFC-8S Chip */5311{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,5312PCI_SUBDEVICE_ID_CCD_BN8S, 0, 0, H(12)}, /* BN8S */5313{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,5314PCI_SUBDEVICE_ID_CCD_BN8SP, 0, 0, H(13)}, /* BN8S+ */5315{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,5316PCI_DEVICE_ID_CCD_HFC8S, 0, 0, H(14)}, /* old Eval */5317{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,5318PCI_SUBDEVICE_ID_CCD_IOB8STR, 0, 0, H(15)}, /* IOB8ST Recording */5319{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,5320PCI_SUBDEVICE_ID_CCD_IOB8ST, 0, 0, H(16)}, /* IOB8ST */5321{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,5322PCI_SUBDEVICE_ID_CCD_IOB8ST_1, 0, 0, H(17)}, /* IOB8ST */5323{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,5324PCI_SUBDEVICE_ID_CCD_HFC8S, 0, 0, H(18)}, /* 8S */5325{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,5326PCI_SUBDEVICE_ID_CCD_OV8S, 0, 0, H(30)}, /* OpenVox 8 */5327{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,5328PCI_SUBDEVICE_ID_CCD_JH8S, 0, 0, H(32)}, /* Junganns 8S */532953305331/* Cards with HFC-E1 Chip */5332{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,5333PCI_SUBDEVICE_ID_CCD_BNE1, 0, 0, H(19)}, /* BNE1 */5334{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,5335PCI_SUBDEVICE_ID_CCD_BNE1M, 0, 0, H(20)}, /* BNE1 mini PCI */5336{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,5337PCI_SUBDEVICE_ID_CCD_BNE1DP, 0, 0, H(21)}, /* BNE1 + (Dual) */5338{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,5339PCI_SUBDEVICE_ID_CCD_BNE1D, 0, 0, H(22)}, /* BNE1 (Dual) */53405341{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,5342PCI_DEVICE_ID_CCD_HFCE1, 0, 0, H(23)}, /* Old Eval */5343{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,5344PCI_SUBDEVICE_ID_CCD_IOB1E1, 0, 0, H(24)}, /* IOB1E1 */5345{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,5346PCI_SUBDEVICE_ID_CCD_HFCE1, 0, 0, H(25)}, /* E1 */53475348{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_CCD,5349PCI_SUBDEVICE_ID_CCD_SPD4S, 0, 0, H(26)}, /* PLX PCI Bridge */5350{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_CCD,5351PCI_SUBDEVICE_ID_CCD_SPDE1, 0, 0, H(27)}, /* PLX PCI Bridge */53525353{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,5354PCI_SUBDEVICE_ID_CCD_JHSE1, 0, 0, H(25)}, /* Junghanns E1 */53555356{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_HFC4S), 0 },5357{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_HFC8S), 0 },5358{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_HFCE1), 0 },5359{0, }5360};5361#undef H53625363MODULE_DEVICE_TABLE(pci, hfmultipci_ids);53645365static int5366hfcmulti_probe(struct pci_dev *pdev, const struct pci_device_id *ent)5367{5368struct hm_map *m = (struct hm_map *)ent->driver_data;5369int ret;53705371if (m == NULL && ent->vendor == PCI_VENDOR_ID_CCD && (5372ent->device == PCI_DEVICE_ID_CCD_HFC4S ||5373ent->device == PCI_DEVICE_ID_CCD_HFC8S ||5374ent->device == PCI_DEVICE_ID_CCD_HFCE1)) {5375printk(KERN_ERR5376"Unknown HFC multiport controller (vendor:%04x device:%04x "5377"subvendor:%04x subdevice:%04x)\n", pdev->vendor,5378pdev->device, pdev->subsystem_vendor,5379pdev->subsystem_device);5380printk(KERN_ERR5381"Please contact the driver maintainer for support.\n");5382return -ENODEV;5383}5384ret = hfcmulti_init(m, pdev, ent);5385if (ret)5386return ret;5387HFC_cnt++;5388printk(KERN_INFO "%d devices registered\n", HFC_cnt);5389return 0;5390}53915392static struct pci_driver hfcmultipci_driver = {5393.name = "hfc_multi",5394.probe = hfcmulti_probe,5395.remove = __devexit_p(hfc_remove_pci),5396.id_table = hfmultipci_ids,5397};53985399static void __exit5400HFCmulti_cleanup(void)5401{5402struct hfc_multi *card, *next;54035404/* get rid of all devices of this driver */5405list_for_each_entry_safe(card, next, &HFClist, list)5406release_card(card);5407pci_unregister_driver(&hfcmultipci_driver);5408}54095410static int __init5411HFCmulti_init(void)5412{5413int err;5414int i, xhfc = 0;5415struct hm_map m;54165417printk(KERN_INFO "mISDN: HFC-multi driver %s\n", HFC_MULTI_VERSION);54185419#ifdef IRQ_DEBUG5420printk(KERN_DEBUG "%s: IRQ_DEBUG IS ENABLED!\n", __func__);5421#endif54225423spin_lock_init(&HFClock);5424spin_lock_init(&plx_lock);54255426if (debug & DEBUG_HFCMULTI_INIT)5427printk(KERN_DEBUG "%s: init entered\n", __func__);54285429switch (poll) {5430case 0:5431poll_timer = 6;5432poll = 128;5433break;5434case 8:5435poll_timer = 2;5436break;5437case 16:5438poll_timer = 3;5439break;5440case 32:5441poll_timer = 4;5442break;5443case 64:5444poll_timer = 5;5445break;5446case 128:5447poll_timer = 6;5448break;5449case 256:5450poll_timer = 7;5451break;5452default:5453printk(KERN_ERR5454"%s: Wrong poll value (%d).\n", __func__, poll);5455err = -EINVAL;5456return err;54575458}54595460if (!clock)5461clock = 1;54625463/* Register the embedded devices.5464* This should be done before the PCI cards registration */5465switch (hwid) {5466case HWID_MINIP4:5467xhfc = 1;5468m = hfcm_map[31];5469break;5470case HWID_MINIP8:5471xhfc = 2;5472m = hfcm_map[31];5473break;5474case HWID_MINIP16:5475xhfc = 4;5476m = hfcm_map[31];5477break;5478default:5479xhfc = 0;5480}54815482for (i = 0; i < xhfc; ++i) {5483err = hfcmulti_init(&m, NULL, NULL);5484if (err) {5485printk(KERN_ERR "error registering embedded driver: "5486"%x\n", err);5487return err;5488}5489HFC_cnt++;5490printk(KERN_INFO "%d devices registered\n", HFC_cnt);5491}54925493/* Register the PCI cards */5494err = pci_register_driver(&hfcmultipci_driver);5495if (err < 0) {5496printk(KERN_ERR "error registering pci driver: %x\n", err);5497return err;5498}54995500return 0;5501}550255035504module_init(HFCmulti_init);5505module_exit(HFCmulti_cleanup);550655075508