diff options
author | David S. Miller <davem@davemloft.net> | 2019-06-03 02:48:58 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-06-03 02:48:58 +0200 |
commit | 8a7e8ff8ce8ae7d34ed979f41b572bfe7cab421c (patch) | |
tree | 7084e209ef4e21a9b92075cf445a617ecf190ee7 /drivers/isdn/hardware | |
parent | Merge branch 'mscc-ocelot-tc-flower' (diff) | |
parent | isdn: move capi drivers to staging (diff) | |
download | linux-8a7e8ff8ce8ae7d34ed979f41b572bfe7cab421c.tar.xz linux-8a7e8ff8ce8ae7d34ed979f41b572bfe7cab421c.zip |
Merge tag 'isdn-removal' of https://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground
Arnd Bergmann says:
====================
isdn: deprecate non-mISDN drivers
When isdn4linux came up in the context of another patch series, I
remembered that we had discussed removing it a while ago.
It turns out that the suggestion from Karsten Keil wa to remove I4L
in 2018 after the last public ISDN networks are shut down. This has
happened now (with a very small number of exceptions), so I guess it's
time to try again.
We currently have three ISDN stacks in the kernel: the original
isdn4linux (with the hisax driver), the newer CAPI (with four drivers),
and finally the mISDN stack (supporting roughly the same hardware as
hisax).
As far as I can tell, anyone using ISDN with mainline kernel drivers in
the past few years uses mISDN, and this is typically used for voice-only
PBX installations that don't require a public network.
The older stacks support additional features for data networks, but those
typically make no sense any more if there is no network to connect to.
My proposal for this time is to kill off isdn4linux entirely, as it seems
to have been unusable for quite a while. This code has been abandoned
for many years and it does cause problems for treewide maintenance as
it tends to do everything that we try to stop doing.
Birger Harzenetter mentioned that is is still using i4l in order to
make use of the 'divert' feature that is not part of mISDN, but has
otherwise moved on to mISDN for normal operation, like apparently
everyone else.
CAPI in turn is not quite as obsolete, but two of the drivers (avm
and hysdn) don't seem to be used at all, while another one (gigaset)
will stop being maintained as Paul Bolle is no longer able to
test it after the network gets shut down in September.
All three are now moved into drivers/staging to let others speak
up in case there are remaining users.
This leaves Bluetooth CMTP as the only remaining user of CAPI, but
Marcel Holtmann wishes to keep maintaining it.
For the discussion on version 1, see [2]
Unfortunately, Karsten Keil as the maintainer has not participated in
the discussion.
Arnd
[1] https://patchwork.kernel.org/patch/8484861/#17900371
[2] https://listserv.isdn4linux.de/pipermail/isdn4linux/2019-April/thread.html
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/isdn/hardware')
-rw-r--r-- | drivers/isdn/hardware/Kconfig | 8 | ||||
-rw-r--r-- | drivers/isdn/hardware/Makefile | 1 | ||||
-rw-r--r-- | drivers/isdn/hardware/avm/Kconfig | 65 | ||||
-rw-r--r-- | drivers/isdn/hardware/avm/Makefile | 12 | ||||
-rw-r--r-- | drivers/isdn/hardware/avm/avm_cs.c | 166 | ||||
-rw-r--r-- | drivers/isdn/hardware/avm/avmcard.h | 581 | ||||
-rw-r--r-- | drivers/isdn/hardware/avm/b1.c | 804 | ||||
-rw-r--r-- | drivers/isdn/hardware/avm/b1dma.c | 981 | ||||
-rw-r--r-- | drivers/isdn/hardware/avm/b1isa.c | 243 | ||||
-rw-r--r-- | drivers/isdn/hardware/avm/b1pci.c | 416 | ||||
-rw-r--r-- | drivers/isdn/hardware/avm/b1pcmcia.c | 224 | ||||
-rw-r--r-- | drivers/isdn/hardware/avm/c4.c | 1317 | ||||
-rw-r--r-- | drivers/isdn/hardware/avm/t1isa.c | 594 | ||||
-rw-r--r-- | drivers/isdn/hardware/avm/t1pci.c | 259 | ||||
-rw-r--r-- | drivers/isdn/hardware/mISDN/Kconfig | 7 | ||||
-rw-r--r-- | drivers/isdn/hardware/mISDN/Makefile | 2 | ||||
-rw-r--r-- | drivers/isdn/hardware/mISDN/isdnhdlc.c | 617 | ||||
-rw-r--r-- | drivers/isdn/hardware/mISDN/isdnhdlc.h | 69 | ||||
-rw-r--r-- | drivers/isdn/hardware/mISDN/netjet.c | 2 |
19 files changed, 694 insertions, 5674 deletions
diff --git a/drivers/isdn/hardware/Kconfig b/drivers/isdn/hardware/Kconfig deleted file mode 100644 index 0d609b5fcf01..000000000000 --- a/drivers/isdn/hardware/Kconfig +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# ISDN hardware drivers -# -comment "CAPI hardware drivers" - -source "drivers/isdn/hardware/avm/Kconfig" - diff --git a/drivers/isdn/hardware/Makefile b/drivers/isdn/hardware/Makefile index a43760a0a4f5..96f9eb2e46ba 100644 --- a/drivers/isdn/hardware/Makefile +++ b/drivers/isdn/hardware/Makefile @@ -3,5 +3,4 @@ # Object files in subdirectories -obj-$(CONFIG_CAPI_AVM) += avm/ obj-$(CONFIG_MISDN) += mISDN/ diff --git a/drivers/isdn/hardware/avm/Kconfig b/drivers/isdn/hardware/avm/Kconfig deleted file mode 100644 index 81483db067bb..000000000000 --- a/drivers/isdn/hardware/avm/Kconfig +++ /dev/null @@ -1,65 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# ISDN AVM drivers -# - -menuconfig CAPI_AVM - bool "Active AVM cards" - help - Enable support for AVM active ISDN cards. - -if CAPI_AVM - -config ISDN_DRV_AVMB1_B1ISA - tristate "AVM B1 ISA support" - depends on ISA - help - Enable support for the ISA version of the AVM B1 card. - -config ISDN_DRV_AVMB1_B1PCI - tristate "AVM B1 PCI support" - depends on PCI - help - Enable support for the PCI version of the AVM B1 card. - -config ISDN_DRV_AVMB1_B1PCIV4 - bool "AVM B1 PCI V4 support" - depends on ISDN_DRV_AVMB1_B1PCI - help - Enable support for the V4 version of AVM B1 PCI card. - -config ISDN_DRV_AVMB1_T1ISA - tristate "AVM T1/T1-B ISA support" - depends on ISA - help - Enable support for the AVM T1 T1B card. - Note: This is a PRI card and handle 30 B-channels. - -config ISDN_DRV_AVMB1_B1PCMCIA - tristate "AVM B1/M1/M2 PCMCIA support" - depends on PCMCIA - help - Enable support for the PCMCIA version of the AVM B1 card. - -config ISDN_DRV_AVMB1_AVM_CS - tristate "AVM B1/M1/M2 PCMCIA cs module" - depends on ISDN_DRV_AVMB1_B1PCMCIA - help - Enable the PCMCIA client driver for the AVM B1/M1/M2 - PCMCIA cards. - -config ISDN_DRV_AVMB1_T1PCI - tristate "AVM T1/T1-B PCI support" - depends on PCI - help - Enable support for the AVM T1 T1B card. - Note: This is a PRI card and handle 30 B-channels. - -config ISDN_DRV_AVMB1_C4 - tristate "AVM C4/C2 support" - depends on PCI - help - Enable support for the AVM C4/C2 PCI cards. - These cards handle 4/2 BRI ISDN lines (8/4 channels). - -endif # CAPI_AVM diff --git a/drivers/isdn/hardware/avm/Makefile b/drivers/isdn/hardware/avm/Makefile deleted file mode 100644 index 3830a0573fcc..000000000000 --- a/drivers/isdn/hardware/avm/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# Makefile for the AVM ISDN device drivers - -# Each configuration option enables a list of files. - -obj-$(CONFIG_ISDN_DRV_AVMB1_B1ISA) += b1isa.o b1.o -obj-$(CONFIG_ISDN_DRV_AVMB1_B1PCI) += b1pci.o b1.o b1dma.o -obj-$(CONFIG_ISDN_DRV_AVMB1_B1PCMCIA) += b1pcmcia.o b1.o -obj-$(CONFIG_ISDN_DRV_AVMB1_AVM_CS) += avm_cs.o -obj-$(CONFIG_ISDN_DRV_AVMB1_T1ISA) += t1isa.o b1.o -obj-$(CONFIG_ISDN_DRV_AVMB1_T1PCI) += t1pci.o b1.o b1dma.o -obj-$(CONFIG_ISDN_DRV_AVMB1_C4) += c4.o b1.o diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c deleted file mode 100644 index 62b8030ee331..000000000000 --- a/drivers/isdn/hardware/avm/avm_cs.c +++ /dev/null @@ -1,166 +0,0 @@ -/* $Id: avm_cs.c,v 1.4.6.3 2001/09/23 22:24:33 kai Exp $ - * - * A PCMCIA client driver for AVM B1/M1/M2 - * - * Copyright 1999 by Carsten Paeth <calle@calle.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/ptrace.h> -#include <linux/string.h> -#include <linux/tty.h> -#include <linux/serial.h> -#include <linux/major.h> -#include <asm/io.h> - -#include <pcmcia/cistpl.h> -#include <pcmcia/ciscode.h> -#include <pcmcia/ds.h> -#include <pcmcia/cisreg.h> - -#include <linux/skbuff.h> -#include <linux/capi.h> -#include <linux/b1lli.h> -#include <linux/b1pcmcia.h> - -/*====================================================================*/ - -MODULE_DESCRIPTION("CAPI4Linux: PCMCIA client driver for AVM B1/M1/M2"); -MODULE_AUTHOR("Carsten Paeth"); -MODULE_LICENSE("GPL"); - -/*====================================================================*/ - -static int avmcs_config(struct pcmcia_device *link); -static void avmcs_release(struct pcmcia_device *link); -static void avmcs_detach(struct pcmcia_device *p_dev); - -static int avmcs_probe(struct pcmcia_device *p_dev) -{ - /* General socket configuration */ - p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; - p_dev->config_index = 1; - p_dev->config_regs = PRESENT_OPTION; - - return avmcs_config(p_dev); -} /* avmcs_attach */ - - -static void avmcs_detach(struct pcmcia_device *link) -{ - avmcs_release(link); -} /* avmcs_detach */ - -static int avmcs_configcheck(struct pcmcia_device *p_dev, void *priv_data) -{ - p_dev->resource[0]->end = 16; - p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; - p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; - - return pcmcia_request_io(p_dev); -} - -static int avmcs_config(struct pcmcia_device *link) -{ - int i = -1; - char devname[128]; - int cardtype; - int (*addcard)(unsigned int port, unsigned irq); - - devname[0] = 0; - if (link->prod_id[1]) - strlcpy(devname, link->prod_id[1], sizeof(devname)); - - /* - * find IO port - */ - if (pcmcia_loop_config(link, avmcs_configcheck, NULL)) - return -ENODEV; - - do { - if (!link->irq) { - /* undo */ - pcmcia_disable_device(link); - break; - } - - /* - * configure the PCMCIA socket - */ - i = pcmcia_enable_device(link); - if (i != 0) { - pcmcia_disable_device(link); - break; - } - - } while (0); - - if (devname[0]) { - char *s = strrchr(devname, ' '); - if (!s) - s = devname; - else s++; - if (strcmp("M1", s) == 0) { - cardtype = AVM_CARDTYPE_M1; - } else if (strcmp("M2", s) == 0) { - cardtype = AVM_CARDTYPE_M2; - } else { - cardtype = AVM_CARDTYPE_B1; - } - } else - cardtype = AVM_CARDTYPE_B1; - - /* If any step failed, release any partially configured state */ - if (i != 0) { - avmcs_release(link); - return -ENODEV; - } - - - switch (cardtype) { - case AVM_CARDTYPE_M1: addcard = b1pcmcia_addcard_m1; break; - case AVM_CARDTYPE_M2: addcard = b1pcmcia_addcard_m2; break; - default: - case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break; - } - if ((i = (*addcard)(link->resource[0]->start, link->irq)) < 0) { - dev_err(&link->dev, - "avm_cs: failed to add AVM-Controller at i/o %#x, irq %d\n", - (unsigned int) link->resource[0]->start, link->irq); - avmcs_release(link); - return -ENODEV; - } - return 0; - -} /* avmcs_config */ - - -static void avmcs_release(struct pcmcia_device *link) -{ - b1pcmcia_delcard(link->resource[0]->start, link->irq); - pcmcia_disable_device(link); -} /* avmcs_release */ - - -static const struct pcmcia_device_id avmcs_ids[] = { - PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN-Controller B1", 0x95d42008, 0x845dc335), - PCMCIA_DEVICE_PROD_ID12("AVM", "Mobile ISDN-Controller M1", 0x95d42008, 0x81e10430), - PCMCIA_DEVICE_PROD_ID12("AVM", "Mobile ISDN-Controller M2", 0x95d42008, 0x18e8558a), - PCMCIA_DEVICE_NULL -}; -MODULE_DEVICE_TABLE(pcmcia, avmcs_ids); - -static struct pcmcia_driver avmcs_driver = { - .owner = THIS_MODULE, - .name = "avm_cs", - .probe = avmcs_probe, - .remove = avmcs_detach, - .id_table = avmcs_ids, -}; -module_pcmcia_driver(avmcs_driver); diff --git a/drivers/isdn/hardware/avm/avmcard.h b/drivers/isdn/hardware/avm/avmcard.h deleted file mode 100644 index cdfa89c71997..000000000000 --- a/drivers/isdn/hardware/avm/avmcard.h +++ /dev/null @@ -1,581 +0,0 @@ -/* $Id: avmcard.h,v 1.1.4.1.2.1 2001/12/21 15:00:17 kai Exp $ - * - * Copyright 1999 by Carsten Paeth <calle@calle.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#ifndef _AVMCARD_H_ -#define _AVMCARD_H_ - -#include <linux/spinlock.h> -#include <linux/list.h> -#include <linux/interrupt.h> - -#define AVMB1_PORTLEN 0x1f -#define AVM_MAXVERSION 8 -#define AVM_NCCI_PER_CHANNEL 4 - -/* - * Versions - */ - -#define VER_DRIVER 0 -#define VER_CARDTYPE 1 -#define VER_HWID 2 -#define VER_SERIAL 3 -#define VER_OPTION 4 -#define VER_PROTO 5 -#define VER_PROFILE 6 -#define VER_CAPI 7 - -enum avmcardtype { - avm_b1isa, - avm_b1pci, - avm_b1pcmcia, - avm_m1, - avm_m2, - avm_t1isa, - avm_t1pci, - avm_c4, - avm_c2 -}; - -typedef struct avmcard_dmabuf { - long size; - u8 *dmabuf; - dma_addr_t dmaaddr; -} avmcard_dmabuf; - -typedef struct avmcard_dmainfo { - u32 recvlen; - avmcard_dmabuf recvbuf; - - avmcard_dmabuf sendbuf; - struct sk_buff_head send_queue; - - struct pci_dev *pcidev; -} avmcard_dmainfo; - -typedef struct avmctrl_info { - char cardname[32]; - - int versionlen; - char versionbuf[1024]; - char *version[AVM_MAXVERSION]; - - char infobuf[128]; /* for function procinfo */ - - struct avmcard *card; - struct capi_ctr capi_ctrl; - - struct list_head ncci_head; -} avmctrl_info; - -typedef struct avmcard { - char name[32]; - - spinlock_t lock; - unsigned int port; - unsigned irq; - unsigned long membase; - enum avmcardtype cardtype; - unsigned char revision; - unsigned char class; - int cardnr; /* for t1isa */ - - char msgbuf[128]; /* capimsg msg part */ - char databuf[2048]; /* capimsg data part */ - - void __iomem *mbase; - volatile u32 csr; - avmcard_dmainfo *dma; - - struct avmctrl_info *ctrlinfo; - - u_int nr_controllers; - u_int nlogcontr; - struct list_head list; -} avmcard; - -extern int b1_irq_table[16]; - -/* - * LLI Messages to the ISDN-ControllerISDN Controller - */ - -#define SEND_POLL 0x72 /* - * after load <- RECEIVE_POLL - */ -#define SEND_INIT 0x11 /* - * first message <- RECEIVE_INIT - * int32 NumApplications int32 - * NumNCCIs int32 BoardNumber - */ -#define SEND_REGISTER 0x12 /* - * register an application int32 - * ApplIDId int32 NumMessages - * int32 NumB3Connections int32 - * NumB3Blocks int32 B3Size - * - * AnzB3Connection != 0 && - * AnzB3Blocks >= 1 && B3Size >= 1 - */ -#define SEND_RELEASE 0x14 /* - * deregister an application int32 - * ApplID - */ -#define SEND_MESSAGE 0x15 /* - * send capi-message int32 length - * capi-data ... - */ -#define SEND_DATA_B3_REQ 0x13 /* - * send capi-data-message int32 - * MsgLength capi-data ... int32 - * B3Length data .... - */ - -#define SEND_CONFIG 0x21 /* - */ - -#define SEND_POLLACK 0x73 /* T1 Watchdog */ - -/* - * LLI Messages from the ISDN-ControllerISDN Controller - */ - -#define RECEIVE_POLL 0x32 /* - * <- after SEND_POLL - */ -#define RECEIVE_INIT 0x27 /* - * <- after SEND_INIT int32 length - * byte total length b1struct board - * driver revision b1struct card - * type b1struct reserved b1struct - * serial number b1struct driver - * capability b1struct d-channel - * protocol b1struct CAPI-2.0 - * profile b1struct capi version - */ -#define RECEIVE_MESSAGE 0x21 /* - * <- after SEND_MESSAGE int32 - * AppllID int32 Length capi-data - * .... - */ -#define RECEIVE_DATA_B3_IND 0x22 /* - * received data int32 AppllID - * int32 Length capi-data ... - * int32 B3Length data ... - */ -#define RECEIVE_START 0x23 /* - * Handshake - */ -#define RECEIVE_STOP 0x24 /* - * Handshake - */ -#define RECEIVE_NEW_NCCI 0x25 /* - * int32 AppllID int32 NCCI int32 - * WindowSize - */ -#define RECEIVE_FREE_NCCI 0x26 /* - * int32 AppllID int32 NCCI - */ -#define RECEIVE_RELEASE 0x26 /* - * int32 AppllID int32 0xffffffff - */ -#define RECEIVE_TASK_READY 0x31 /* - * int32 tasknr - * int32 Length Taskname ... - */ -#define RECEIVE_DEBUGMSG 0x71 /* - * int32 Length message - * - */ -#define RECEIVE_POLLDWORD 0x75 /* t1pci in dword mode */ - -#define WRITE_REGISTER 0x00 -#define READ_REGISTER 0x01 - -/* - * port offsets - */ - -#define B1_READ 0x00 -#define B1_WRITE 0x01 -#define B1_INSTAT 0x02 -#define B1_OUTSTAT 0x03 -#define B1_ANALYSE 0x04 -#define B1_REVISION 0x05 -#define B1_RESET 0x10 - - -#define B1_STAT0(cardtype) ((cardtype) == avm_m1 ? 0x81200000l : 0x80A00000l) -#define B1_STAT1(cardtype) (0x80E00000l) - -/* ---------------------------------------------------------------- */ - -static inline unsigned char b1outp(unsigned int base, - unsigned short offset, - unsigned char value) -{ - outb(value, base + offset); - return inb(base + B1_ANALYSE); -} - - -static inline int b1_rx_full(unsigned int base) -{ - return inb(base + B1_INSTAT) & 0x1; -} - -static inline unsigned char b1_get_byte(unsigned int base) -{ - unsigned long stop = jiffies + 1 * HZ; /* maximum wait time 1 sec */ - while (!b1_rx_full(base) && time_before(jiffies, stop)); - if (b1_rx_full(base)) - return inb(base + B1_READ); - printk(KERN_CRIT "b1lli(0x%x): rx not full after 1 second\n", base); - return 0; -} - -static inline unsigned int b1_get_word(unsigned int base) -{ - unsigned int val = 0; - val |= b1_get_byte(base); - val |= (b1_get_byte(base) << 8); - val |= (b1_get_byte(base) << 16); - val |= (b1_get_byte(base) << 24); - return val; -} - -static inline int b1_tx_empty(unsigned int base) -{ - return inb(base + B1_OUTSTAT) & 0x1; -} - -static inline void b1_put_byte(unsigned int base, unsigned char val) -{ - while (!b1_tx_empty(base)); - b1outp(base, B1_WRITE, val); -} - -static inline int b1_save_put_byte(unsigned int base, unsigned char val) -{ - unsigned long stop = jiffies + 2 * HZ; - while (!b1_tx_empty(base) && time_before(jiffies, stop)); - if (!b1_tx_empty(base)) return -1; - b1outp(base, B1_WRITE, val); - return 0; -} - -static inline void b1_put_word(unsigned int base, unsigned int val) -{ - b1_put_byte(base, val & 0xff); - b1_put_byte(base, (val >> 8) & 0xff); - b1_put_byte(base, (val >> 16) & 0xff); - b1_put_byte(base, (val >> 24) & 0xff); -} - -static inline unsigned int b1_get_slice(unsigned int base, - unsigned char *dp) -{ - unsigned int len, i; - - len = i = b1_get_word(base); - while (i-- > 0) *dp++ = b1_get_byte(base); - return len; -} - -static inline void b1_put_slice(unsigned int base, - unsigned char *dp, unsigned int len) -{ - unsigned i = len; - b1_put_word(base, i); - while (i-- > 0) - b1_put_byte(base, *dp++); -} - -static void b1_wr_reg(unsigned int base, - unsigned int reg, - unsigned int value) -{ - b1_put_byte(base, WRITE_REGISTER); - b1_put_word(base, reg); - b1_put_word(base, value); -} - -static inline unsigned int b1_rd_reg(unsigned int base, - unsigned int reg) -{ - b1_put_byte(base, READ_REGISTER); - b1_put_word(base, reg); - return b1_get_word(base); - -} - -static inline void b1_reset(unsigned int base) -{ - b1outp(base, B1_RESET, 0); - mdelay(55 * 2); /* 2 TIC's */ - - b1outp(base, B1_RESET, 1); - mdelay(55 * 2); /* 2 TIC's */ - - b1outp(base, B1_RESET, 0); - mdelay(55 * 2); /* 2 TIC's */ -} - -static inline unsigned char b1_disable_irq(unsigned int base) -{ - return b1outp(base, B1_INSTAT, 0x00); -} - -/* ---------------------------------------------------------------- */ - -static inline void b1_set_test_bit(unsigned int base, - enum avmcardtype cardtype, - int onoff) -{ - b1_wr_reg(base, B1_STAT0(cardtype), onoff ? 0x21 : 0x20); -} - -static inline int b1_get_test_bit(unsigned int base, - enum avmcardtype cardtype) -{ - return (b1_rd_reg(base, B1_STAT0(cardtype)) & 0x01) != 0; -} - -/* ---------------------------------------------------------------- */ - -#define T1_FASTLINK 0x00 -#define T1_SLOWLINK 0x08 - -#define T1_READ B1_READ -#define T1_WRITE B1_WRITE -#define T1_INSTAT B1_INSTAT -#define T1_OUTSTAT B1_OUTSTAT -#define T1_IRQENABLE 0x05 -#define T1_FIFOSTAT 0x06 -#define T1_RESETLINK 0x10 -#define T1_ANALYSE 0x11 -#define T1_IRQMASTER 0x12 -#define T1_IDENT 0x17 -#define T1_RESETBOARD 0x1f - -#define T1F_IREADY 0x01 -#define T1F_IHALF 0x02 -#define T1F_IFULL 0x04 -#define T1F_IEMPTY 0x08 -#define T1F_IFLAGS 0xF0 - -#define T1F_OREADY 0x10 -#define T1F_OHALF 0x20 -#define T1F_OEMPTY 0x40 -#define T1F_OFULL 0x80 -#define T1F_OFLAGS 0xF0 - -/* there are HEMA cards with 1k and 4k FIFO out */ -#define FIFO_OUTBSIZE 256 -#define FIFO_INPBSIZE 512 - -#define HEMA_VERSION_ID 0 -#define HEMA_PAL_ID 0 - -static inline void t1outp(unsigned int base, - unsigned short offset, - unsigned char value) -{ - outb(value, base + offset); -} - -static inline unsigned char t1inp(unsigned int base, - unsigned short offset) -{ - return inb(base + offset); -} - -static inline int t1_isfastlink(unsigned int base) -{ - return (inb(base + T1_IDENT) & ~0x82) == 1; -} - -static inline unsigned char t1_fifostatus(unsigned int base) -{ - return inb(base + T1_FIFOSTAT); -} - -static inline unsigned int t1_get_slice(unsigned int base, - unsigned char *dp) -{ - unsigned int len, i; -#ifdef FASTLINK_DEBUG - unsigned wcnt = 0, bcnt = 0; -#endif - - len = i = b1_get_word(base); - if (t1_isfastlink(base)) { - int status; - while (i > 0) { - status = t1_fifostatus(base) & (T1F_IREADY | T1F_IHALF); - if (i >= FIFO_INPBSIZE) status |= T1F_IFULL; - - switch (status) { - case T1F_IREADY | T1F_IHALF | T1F_IFULL: - insb(base + B1_READ, dp, FIFO_INPBSIZE); - dp += FIFO_INPBSIZE; - i -= FIFO_INPBSIZE; -#ifdef FASTLINK_DEBUG - wcnt += FIFO_INPBSIZE; -#endif - break; - case T1F_IREADY | T1F_IHALF: - insb(base + B1_READ, dp, i); -#ifdef FASTLINK_DEBUG - wcnt += i; -#endif - dp += i; - i = 0; - break; - default: - *dp++ = b1_get_byte(base); - i--; -#ifdef FASTLINK_DEBUG - bcnt++; -#endif - break; - } - } -#ifdef FASTLINK_DEBUG - if (wcnt) - printk(KERN_DEBUG "b1lli(0x%x): get_slice l=%d w=%d b=%d\n", - base, len, wcnt, bcnt); -#endif - } else { - while (i-- > 0) - *dp++ = b1_get_byte(base); - } - return len; -} - -static inline void t1_put_slice(unsigned int base, - unsigned char *dp, unsigned int len) -{ - unsigned i = len; - b1_put_word(base, i); - if (t1_isfastlink(base)) { - int status; - while (i > 0) { - status = t1_fifostatus(base) & (T1F_OREADY | T1F_OHALF); - if (i >= FIFO_OUTBSIZE) status |= T1F_OEMPTY; - switch (status) { - case T1F_OREADY | T1F_OHALF | T1F_OEMPTY: - outsb(base + B1_WRITE, dp, FIFO_OUTBSIZE); - dp += FIFO_OUTBSIZE; - i -= FIFO_OUTBSIZE; - break; - case T1F_OREADY | T1F_OHALF: - outsb(base + B1_WRITE, dp, i); - dp += i; - i = 0; - break; - default: - b1_put_byte(base, *dp++); - i--; - break; - } - } - } else { - while (i-- > 0) - b1_put_byte(base, *dp++); - } -} - -static inline void t1_disable_irq(unsigned int base) -{ - t1outp(base, T1_IRQMASTER, 0x00); -} - -static inline void t1_reset(unsigned int base) -{ - /* reset T1 Controller */ - b1_reset(base); - /* disable irq on HEMA */ - t1outp(base, B1_INSTAT, 0x00); - t1outp(base, B1_OUTSTAT, 0x00); - t1outp(base, T1_IRQMASTER, 0x00); - /* reset HEMA board configuration */ - t1outp(base, T1_RESETBOARD, 0xf); -} - -static inline void b1_setinterrupt(unsigned int base, unsigned irq, - enum avmcardtype cardtype) -{ - switch (cardtype) { - case avm_t1isa: - t1outp(base, B1_INSTAT, 0x00); - t1outp(base, B1_INSTAT, 0x02); - t1outp(base, T1_IRQMASTER, 0x08); - break; - case avm_b1isa: - b1outp(base, B1_INSTAT, 0x00); - b1outp(base, B1_RESET, b1_irq_table[irq]); - b1outp(base, B1_INSTAT, 0x02); - break; - default: - case avm_m1: - case avm_m2: - case avm_b1pci: - b1outp(base, B1_INSTAT, 0x00); - b1outp(base, B1_RESET, 0xf0); - b1outp(base, B1_INSTAT, 0x02); - break; - case avm_c4: - case avm_t1pci: - b1outp(base, B1_RESET, 0xf0); - break; - } -} - -/* b1.c */ -avmcard *b1_alloc_card(int nr_controllers); -void b1_free_card(avmcard *card); -int b1_detect(unsigned int base, enum avmcardtype cardtype); -void b1_getrevision(avmcard *card); -int b1_load_t4file(avmcard *card, capiloaddatapart *t4file); -int b1_load_config(avmcard *card, capiloaddatapart *config); -int b1_loaded(avmcard *card); - -int b1_load_firmware(struct capi_ctr *ctrl, capiloaddata *data); -void b1_reset_ctr(struct capi_ctr *ctrl); -void b1_register_appl(struct capi_ctr *ctrl, u16 appl, - capi_register_params *rp); -void b1_release_appl(struct capi_ctr *ctrl, u16 appl); -u16 b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb); -void b1_parse_version(avmctrl_info *card); -irqreturn_t b1_interrupt(int interrupt, void *devptr); - -int b1_proc_show(struct seq_file *m, void *v); - -avmcard_dmainfo *avmcard_dma_alloc(char *name, struct pci_dev *, - long rsize, long ssize); -void avmcard_dma_free(avmcard_dmainfo *); - -/* b1dma.c */ -int b1pciv4_detect(avmcard *card); -int t1pci_detect(avmcard *card); -void b1dma_reset(avmcard *card); -irqreturn_t b1dma_interrupt(int interrupt, void *devptr); - -int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data); -void b1dma_reset_ctr(struct capi_ctr *ctrl); -void b1dma_remove_ctr(struct capi_ctr *ctrl); -void b1dma_register_appl(struct capi_ctr *ctrl, - u16 appl, - capi_register_params *rp); -void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl); -u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb); -int b1dma_proc_show(struct seq_file *m, void *v); - -#endif /* _AVMCARD_H_ */ diff --git a/drivers/isdn/hardware/avm/b1.c b/drivers/isdn/hardware/avm/b1.c deleted file mode 100644 index 40ca1e8fa09f..000000000000 --- a/drivers/isdn/hardware/avm/b1.c +++ /dev/null @@ -1,804 +0,0 @@ -/* $Id: b1.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $ - * - * Common module for AVM B1 cards. - * - * Copyright 1999 by Carsten Paeth <calle@calle.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/pci.h> -#include <linux/proc_fs.h> -#include <linux/seq_file.h> -#include <linux/skbuff.h> -#include <linux/delay.h> -#include <linux/mm.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/capi.h> -#include <linux/kernelcapi.h> -#include <linux/slab.h> -#include <asm/io.h> -#include <linux/init.h> -#include <linux/uaccess.h> -#include <linux/netdevice.h> -#include <linux/isdn/capilli.h> -#include "avmcard.h" -#include <linux/isdn/capicmd.h> -#include <linux/isdn/capiutil.h> - -static char *revision = "$Revision: 1.1.2.2 $"; - -/* ------------------------------------------------------------- */ - -MODULE_DESCRIPTION("CAPI4Linux: Common support for active AVM cards"); -MODULE_AUTHOR("Carsten Paeth"); -MODULE_LICENSE("GPL"); - -/* ------------------------------------------------------------- */ - -int b1_irq_table[16] = -{0, - 0, - 0, - 192, /* irq 3 */ - 32, /* irq 4 */ - 160, /* irq 5 */ - 96, /* irq 6 */ - 224, /* irq 7 */ - 0, - 64, /* irq 9 */ - 80, /* irq 10 */ - 208, /* irq 11 */ - 48, /* irq 12 */ - 0, - 0, - 112, /* irq 15 */ -}; - -/* ------------------------------------------------------------- */ - -avmcard *b1_alloc_card(int nr_controllers) -{ - avmcard *card; - avmctrl_info *cinfo; - int i; - - card = kzalloc(sizeof(*card), GFP_KERNEL); - if (!card) - return NULL; - - cinfo = kcalloc(nr_controllers, sizeof(*cinfo), GFP_KERNEL); - if (!cinfo) { - kfree(card); - return NULL; - } - - card->ctrlinfo = cinfo; - for (i = 0; i < nr_controllers; i++) { - INIT_LIST_HEAD(&cinfo[i].ncci_head); - cinfo[i].card = card; - } - spin_lock_init(&card->lock); - card->nr_controllers = nr_controllers; - - return card; -} - -/* ------------------------------------------------------------- */ - -void b1_free_card(avmcard *card) -{ - kfree(card->ctrlinfo); - kfree(card); -} - -/* ------------------------------------------------------------- */ - -int b1_detect(unsigned int base, enum avmcardtype cardtype) -{ - int onoff, i; - - /* - * Statusregister 0000 00xx - */ - if ((inb(base + B1_INSTAT) & 0xfc) - || (inb(base + B1_OUTSTAT) & 0xfc)) - return 1; - /* - * Statusregister 0000 001x - */ - b1outp(base, B1_INSTAT, 0x2); /* enable irq */ - /* b1outp(base, B1_OUTSTAT, 0x2); */ - if ((inb(base + B1_INSTAT) & 0xfe) != 0x2 - /* || (inb(base + B1_OUTSTAT) & 0xfe) != 0x2 */) - return 2; - /* - * Statusregister 0000 000x - */ - b1outp(base, B1_INSTAT, 0x0); /* disable irq */ - b1outp(base, B1_OUTSTAT, 0x0); - if ((inb(base + B1_INSTAT) & 0xfe) - || (inb(base + B1_OUTSTAT) & 0xfe)) - return 3; - - for (onoff = !0, i = 0; i < 10; i++) { - b1_set_test_bit(base, cardtype, onoff); - if (b1_get_test_bit(base, cardtype) != onoff) - return 4; - onoff = !onoff; - } - - if (cardtype == avm_m1) - return 0; - - if ((b1_rd_reg(base, B1_STAT1(cardtype)) & 0x0f) != 0x01) - return 5; - - return 0; -} - -void b1_getrevision(avmcard *card) -{ - card->class = inb(card->port + B1_ANALYSE); - card->revision = inb(card->port + B1_REVISION); -} - -#define FWBUF_SIZE 256 -int b1_load_t4file(avmcard *card, capiloaddatapart *t4file) -{ - unsigned char buf[FWBUF_SIZE]; - unsigned char *dp; - int i, left; - unsigned int base = card->port; - - dp = t4file->data; - left = t4file->len; - while (left > FWBUF_SIZE) { - if (t4file->user) { - if (copy_from_user(buf, dp, FWBUF_SIZE)) - return -EFAULT; - } else { - memcpy(buf, dp, FWBUF_SIZE); - } - for (i = 0; i < FWBUF_SIZE; i++) - if (b1_save_put_byte(base, buf[i]) < 0) { - printk(KERN_ERR "%s: corrupted firmware file ?\n", - card->name); - return -EIO; - } - left -= FWBUF_SIZE; - dp += FWBUF_SIZE; - } - if (left) { - if (t4file->user) { - if (copy_from_user(buf, dp, left)) - return -EFAULT; - } else { - memcpy(buf, dp, left); - } - for (i = 0; i < left; i++) - if (b1_save_put_byte(base, buf[i]) < 0) { - printk(KERN_ERR "%s: corrupted firmware file ?\n", - card->name); - return -EIO; - } - } - return 0; -} - -int b1_load_config(avmcard *card, capiloaddatapart *config) -{ - unsigned char buf[FWBUF_SIZE]; - unsigned char *dp; - unsigned int base = card->port; - int i, j, left; - - dp = config->data; - left = config->len; - if (left) { - b1_put_byte(base, SEND_CONFIG); - b1_put_word(base, 1); - b1_put_byte(base, SEND_CONFIG); - b1_put_word(base, left); - } - while (left > FWBUF_SIZE) { - if (config->user) { - if (copy_from_user(buf, dp, FWBUF_SIZE)) - return -EFAULT; - } else { - memcpy(buf, dp, FWBUF_SIZE); - } - for (i = 0; i < FWBUF_SIZE; ) { - b1_put_byte(base, SEND_CONFIG); - for (j = 0; j < 4; j++) { - b1_put_byte(base, buf[i++]); - } - } - left -= FWBUF_SIZE; - dp += FWBUF_SIZE; - } - if (left) { - if (config->user) { - if (copy_from_user(buf, dp, left)) - return -EFAULT; - } else { - memcpy(buf, dp, left); - } - for (i = 0; i < left; ) { - b1_put_byte(base, SEND_CONFIG); - for (j = 0; j < 4; j++) { - if (i < left) - b1_put_byte(base, buf[i++]); - else - b1_put_byte(base, 0); - } - } - } - return 0; -} - -int b1_loaded(avmcard *card) -{ - unsigned int base = card->port; - unsigned long stop; - unsigned char ans; - unsigned long tout = 2; - - for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) { - if (b1_tx_empty(base)) - break; - } - if (!b1_tx_empty(base)) { - printk(KERN_ERR "%s: b1_loaded: tx err, corrupted t4 file ?\n", - card->name); - return 0; - } - b1_put_byte(base, SEND_POLL); - for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) { - if (b1_rx_full(base)) { - if ((ans = b1_get_byte(base)) == RECEIVE_POLL) { - return 1; - } - printk(KERN_ERR "%s: b1_loaded: got 0x%x, firmware not running\n", - card->name, ans); - return 0; - } - } - printk(KERN_ERR "%s: b1_loaded: firmware not running\n", card->name); - return 0; -} - -/* ------------------------------------------------------------- */ - -int b1_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - avmcard *card = cinfo->card; - unsigned int port = card->port; - unsigned long flags; - int retval; - - b1_reset(port); - - if ((retval = b1_load_t4file(card, &data->firmware))) { - b1_reset(port); - printk(KERN_ERR "%s: failed to load t4file!!\n", - card->name); - return retval; - } - - b1_disable_irq(port); - - if (data->configuration.len > 0 && data->configuration.data) { - if ((retval = b1_load_config(card, &data->configuration))) { - b1_reset(port); - printk(KERN_ERR "%s: failed to load config!!\n", - card->name); - return retval; - } - } - - if (!b1_loaded(card)) { - printk(KERN_ERR "%s: failed to load t4file.\n", card->name); - return -EIO; - } - - spin_lock_irqsave(&card->lock, flags); - b1_setinterrupt(port, card->irq, card->cardtype); - b1_put_byte(port, SEND_INIT); - b1_put_word(port, CAPI_MAXAPPL); - b1_put_word(port, AVM_NCCI_PER_CHANNEL * 2); - b1_put_word(port, ctrl->cnr - 1); - spin_unlock_irqrestore(&card->lock, flags); - - return 0; -} - -void b1_reset_ctr(struct capi_ctr *ctrl) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - avmcard *card = cinfo->card; - unsigned int port = card->port; - unsigned long flags; - - b1_reset(port); - b1_reset(port); - - memset(cinfo->version, 0, sizeof(cinfo->version)); - spin_lock_irqsave(&card->lock, flags); - capilib_release(&cinfo->ncci_head); - spin_unlock_irqrestore(&card->lock, flags); - capi_ctr_down(ctrl); -} - -void b1_register_appl(struct capi_ctr *ctrl, - u16 appl, - capi_register_params *rp) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - avmcard *card = cinfo->card; - unsigned int port = card->port; - unsigned long flags; - int nconn, want = rp->level3cnt; - - if (want > 0) nconn = want; - else nconn = ctrl->profile.nbchannel * -want; - if (nconn == 0) nconn = ctrl->profile.nbchannel; - - spin_lock_irqsave(&card->lock, flags); - b1_put_byte(port, SEND_REGISTER); - b1_put_word(port, appl); - b1_put_word(port, 1024 * (nconn + 1)); - b1_put_word(port, nconn); - b1_put_word(port, rp->datablkcnt); - b1_put_word(port, rp->datablklen); - spin_unlock_irqrestore(&card->lock, flags); -} - -void b1_release_appl(struct capi_ctr *ctrl, u16 appl) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - avmcard *card = cinfo->card; - unsigned int port = card->port; - unsigned long flags; - - spin_lock_irqsave(&card->lock, flags); - capilib_release_appl(&cinfo->ncci_head, appl); - b1_put_byte(port, SEND_RELEASE); - b1_put_word(port, appl); - spin_unlock_irqrestore(&card->lock, flags); -} - -u16 b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - avmcard *card = cinfo->card; - unsigned int port = card->port; - unsigned long flags; - u16 len = CAPIMSG_LEN(skb->data); - u8 cmd = CAPIMSG_COMMAND(skb->data); - u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data); - u16 dlen, retval; - - spin_lock_irqsave(&card->lock, flags); - if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) { - retval = capilib_data_b3_req(&cinfo->ncci_head, - CAPIMSG_APPID(skb->data), - CAPIMSG_NCCI(skb->data), - CAPIMSG_MSGID(skb->data)); - if (retval != CAPI_NOERROR) { - spin_unlock_irqrestore(&card->lock, flags); - return retval; - } - - dlen = CAPIMSG_DATALEN(skb->data); - - b1_put_byte(port, SEND_DATA_B3_REQ); - b1_put_slice(port, skb->data, len); - b1_put_slice(port, skb->data + len, dlen); - } else { - b1_put_byte(port, SEND_MESSAGE); - b1_put_slice(port, skb->data, len); - } - spin_unlock_irqrestore(&card->lock, flags); - - dev_kfree_skb_any(skb); - return CAPI_NOERROR; -} - -/* ------------------------------------------------------------- */ - -void b1_parse_version(avmctrl_info *cinfo) -{ - struct capi_ctr *ctrl = &cinfo->capi_ctrl; - avmcard *card = cinfo->card; - capi_profile *profp; - u8 *dversion; - u8 flag; - int i, j; - - for (j = 0; j < AVM_MAXVERSION; j++) - cinfo->version[j] = ""; - for (i = 0, j = 0; - j < AVM_MAXVERSION && i < cinfo->versionlen; - j++, i += cinfo->versionbuf[i] + 1) - cinfo->version[j] = &cinfo->versionbuf[i + 1]; - - strlcpy(ctrl->serial, cinfo->version[VER_SERIAL], sizeof(ctrl->serial)); - memcpy(&ctrl->profile, cinfo->version[VER_PROFILE], sizeof(capi_profile)); - strlcpy(ctrl->manu, "AVM GmbH", sizeof(ctrl->manu)); - dversion = cinfo->version[VER_DRIVER]; - ctrl->version.majorversion = 2; - ctrl->version.minorversion = 0; - ctrl->version.majormanuversion = (((dversion[0] - '0') & 0xf) << 4); - ctrl->version.majormanuversion |= ((dversion[2] - '0') & 0xf); - ctrl->version.minormanuversion = (dversion[3] - '0') << 4; - ctrl->version.minormanuversion |= - (dversion[5] - '0') * 10 + ((dversion[6] - '0') & 0xf); - - profp = &ctrl->profile; - - flag = ((u8 *)(profp->manu))[1]; - switch (flag) { - case 0: if (cinfo->version[VER_CARDTYPE]) - strcpy(cinfo->cardname, cinfo->version[VER_CARDTYPE]); - else strcpy(cinfo->cardname, "B1"); - break; - case 3: strcpy(cinfo->cardname, "PCMCIA B"); break; - case 4: strcpy(cinfo->cardname, "PCMCIA M1"); break; - case 5: strcpy(cinfo->cardname, "PCMCIA M2"); break; - case 6: strcpy(cinfo->cardname, "B1 V3.0"); break; - case 7: strcpy(cinfo->cardname, "B1 PCI"); break; - default: sprintf(cinfo->cardname, "AVM?%u", (unsigned int)flag); break; - } - printk(KERN_NOTICE "%s: card %d \"%s\" ready.\n", - card->name, ctrl->cnr, cinfo->cardname); - - flag = ((u8 *)(profp->manu))[3]; - if (flag) - printk(KERN_NOTICE "%s: card %d Protocol:%s%s%s%s%s%s%s\n", - card->name, - ctrl->cnr, - (flag & 0x01) ? " DSS1" : "", - (flag & 0x02) ? " CT1" : "", - (flag & 0x04) ? " VN3" : "", - (flag & 0x08) ? " NI1" : "", - (flag & 0x10) ? " AUSTEL" : "", - (flag & 0x20) ? " ESS" : "", - (flag & 0x40) ? " 1TR6" : "" - ); - - flag = ((u8 *)(profp->manu))[5]; - if (flag) - printk(KERN_NOTICE "%s: card %d Linetype:%s%s%s%s\n", - card->name, - ctrl->cnr, - (flag & 0x01) ? " point to point" : "", - (flag & 0x02) ? " point to multipoint" : "", - (flag & 0x08) ? " leased line without D-channel" : "", - (flag & 0x04) ? " leased line with D-channel" : "" - ); -} - -/* ------------------------------------------------------------- */ - -irqreturn_t b1_interrupt(int interrupt, void *devptr) -{ - avmcard *card = devptr; - avmctrl_info *cinfo = &card->ctrlinfo[0]; - struct capi_ctr *ctrl = &cinfo->capi_ctrl; - unsigned char b1cmd; - struct sk_buff *skb; - - unsigned ApplId; - unsigned MsgLen; - unsigned DataB3Len; - unsigned NCCI; - unsigned WindowSize; - unsigned long flags; - - spin_lock_irqsave(&card->lock, flags); - - if (!b1_rx_full(card->port)) { - spin_unlock_irqrestore(&card->lock, flags); - return IRQ_NONE; - } - - b1cmd = b1_get_byte(card->port); - - switch (b1cmd) { - - case RECEIVE_DATA_B3_IND: - - ApplId = (unsigned) b1_get_word(card->port); - MsgLen = b1_get_slice(card->port, card->msgbuf); - DataB3Len = b1_get_slice(card->port, card->databuf); - spin_unlock_irqrestore(&card->lock, flags); - - if (MsgLen < 30) { /* not CAPI 64Bit */ - memset(card->msgbuf + MsgLen, 0, 30-MsgLen); - MsgLen = 30; - CAPIMSG_SETLEN(card->msgbuf, 30); - } - if (!(skb = alloc_skb(DataB3Len + MsgLen, GFP_ATOMIC))) { - printk(KERN_ERR "%s: incoming packet dropped\n", - card->name); - } else { - skb_put_data(skb, card->msgbuf, MsgLen); - skb_put_data(skb, card->databuf, DataB3Len); - capi_ctr_handle_message(ctrl, ApplId, skb); - } - break; - - case RECEIVE_MESSAGE: - - ApplId = (unsigned) b1_get_word(card->port); - MsgLen = b1_get_slice(card->port, card->msgbuf); - if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) { - printk(KERN_ERR "%s: incoming packet dropped\n", - card->name); - spin_unlock_irqrestore(&card->lock, flags); - } else { - skb_put_data(skb, card->msgbuf, MsgLen); - if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF) - capilib_data_b3_conf(&cinfo->ncci_head, ApplId, - CAPIMSG_NCCI(skb->data), - CAPIMSG_MSGID(skb->data)); - spin_unlock_irqrestore(&card->lock, flags); - capi_ctr_handle_message(ctrl, ApplId, skb); - } - break; - - case RECEIVE_NEW_NCCI: - - ApplId = b1_get_word(card->port); - NCCI = b1_get_word(card->port); - WindowSize = b1_get_word(card->port); - capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize); - spin_unlock_irqrestore(&card->lock, flags); - break; - - case RECEIVE_FREE_NCCI: - - ApplId = b1_get_word(card->port); - NCCI = b1_get_word(card->port); - if (NCCI != 0xffffffff) - capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI); - spin_unlock_irqrestore(&card->lock, flags); - break; - - case RECEIVE_START: - /* b1_put_byte(card->port, SEND_POLLACK); */ - spin_unlock_irqrestore(&card->lock, flags); - capi_ctr_resume_output(ctrl); - break; - - case RECEIVE_STOP: - spin_unlock_irqrestore(&card->lock, flags); - capi_ctr_suspend_output(ctrl); - break; - - case RECEIVE_INIT: - - cinfo->versionlen = b1_get_slice(card->port, cinfo->versionbuf); - spin_unlock_irqrestore(&card->lock, flags); - b1_parse_version(cinfo); - printk(KERN_INFO "%s: %s-card (%s) now active\n", - card->name, - cinfo->version[VER_CARDTYPE], - cinfo->version[VER_DRIVER]); - capi_ctr_ready(ctrl); - break; - - case RECEIVE_TASK_READY: - ApplId = (unsigned) b1_get_word(card->port); - MsgLen = b1_get_slice(card->port, card->msgbuf); - spin_unlock_irqrestore(&card->lock, flags); - card->msgbuf[MsgLen] = 0; - while (MsgLen > 0 - && (card->msgbuf[MsgLen - 1] == '\n' - || card->msgbuf[MsgLen - 1] == '\r')) { - card->msgbuf[MsgLen - 1] = 0; - MsgLen--; - } - printk(KERN_INFO "%s: task %d \"%s\" ready.\n", - card->name, ApplId, card->msgbuf); - break; - - case RECEIVE_DEBUGMSG: - MsgLen = b1_get_slice(card->port, card->msgbuf); - spin_unlock_irqrestore(&card->lock, flags); - card->msgbuf[MsgLen] = 0; - while (MsgLen > 0 - && (card->msgbuf[MsgLen - 1] == '\n' - || card->msgbuf[MsgLen - 1] == '\r')) { - card->msgbuf[MsgLen - 1] = 0; - MsgLen--; - } - printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf); - break; - - case 0xff: - spin_unlock_irqrestore(&card->lock, flags); - printk(KERN_ERR "%s: card removed ?\n", card->name); - return IRQ_NONE; - default: - spin_unlock_irqrestore(&card->lock, flags); - printk(KERN_ERR "%s: b1_interrupt: 0x%x ???\n", - card->name, b1cmd); - return IRQ_HANDLED; - } - return IRQ_HANDLED; -} - -/* ------------------------------------------------------------- */ -int b1_proc_show(struct seq_file *m, void *v) -{ - struct capi_ctr *ctrl = m->private; - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - avmcard *card = cinfo->card; - u8 flag; - char *s; - - seq_printf(m, "%-16s %s\n", "name", card->name); - seq_printf(m, "%-16s 0x%x\n", "io", card->port); - seq_printf(m, "%-16s %d\n", "irq", card->irq); - switch (card->cardtype) { - case avm_b1isa: s = "B1 ISA"; break; - case avm_b1pci: s = "B1 PCI"; break; - case avm_b1pcmcia: s = "B1 PCMCIA"; break; - case avm_m1: s = "M1"; break; - case avm_m2: s = "M2"; break; - case avm_t1isa: s = "T1 ISA (HEMA)"; break; - case avm_t1pci: s = "T1 PCI"; break; - case avm_c4: s = "C4"; break; - case avm_c2: s = "C2"; break; - default: s = "???"; break; - } - seq_printf(m, "%-16s %s\n", "type", s); - if (card->cardtype == avm_t1isa) - seq_printf(m, "%-16s %d\n", "cardnr", card->cardnr); - if ((s = cinfo->version[VER_DRIVER]) != NULL) - seq_printf(m, "%-16s %s\n", "ver_driver", s); - if ((s = cinfo->version[VER_CARDTYPE]) != NULL) - seq_printf(m, "%-16s %s\n", "ver_cardtype", s); - if ((s = cinfo->version[VER_SERIAL]) != NULL) - seq_printf(m, "%-16s %s\n", "ver_serial", s); - - if (card->cardtype != avm_m1) { - flag = ((u8 *)(ctrl->profile.manu))[3]; - if (flag) - seq_printf(m, "%-16s%s%s%s%s%s%s%s\n", - "protocol", - (flag & 0x01) ? " DSS1" : "", - (flag & 0x02) ? " CT1" : "", - (flag & 0x04) ? " VN3" : "", - (flag & 0x08) ? " NI1" : "", - (flag & 0x10) ? " AUSTEL" : "", - (flag & 0x20) ? " ESS" : "", - (flag & 0x40) ? " 1TR6" : "" - ); - } - if (card->cardtype != avm_m1) { - flag = ((u8 *)(ctrl->profile.manu))[5]; - if (flag) - seq_printf(m, "%-16s%s%s%s%s\n", - "linetype", - (flag & 0x01) ? " point to point" : "", - (flag & 0x02) ? " point to multipoint" : "", - (flag & 0x08) ? " leased line without D-channel" : "", - (flag & 0x04) ? " leased line with D-channel" : "" - ); - } - seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname); - - return 0; -} -EXPORT_SYMBOL(b1_proc_show); - -/* ------------------------------------------------------------- */ - -#ifdef CONFIG_PCI - -avmcard_dmainfo * -avmcard_dma_alloc(char *name, struct pci_dev *pdev, long rsize, long ssize) -{ - avmcard_dmainfo *p; - void *buf; - - p = kzalloc(sizeof(avmcard_dmainfo), GFP_KERNEL); - if (!p) { - printk(KERN_WARNING "%s: no memory.\n", name); - goto err; - } - - p->recvbuf.size = rsize; - buf = pci_alloc_consistent(pdev, rsize, &p->recvbuf.dmaaddr); - if (!buf) { - printk(KERN_WARNING "%s: allocation of receive dma buffer failed.\n", name); - goto err_kfree; - } - p->recvbuf.dmabuf = buf; - - p->sendbuf.size = ssize; - buf = pci_alloc_consistent(pdev, ssize, &p->sendbuf.dmaaddr); - if (!buf) { - printk(KERN_WARNING "%s: allocation of send dma buffer failed.\n", name); - goto err_free_consistent; - } - - p->sendbuf.dmabuf = buf; - skb_queue_head_init(&p->send_queue); - - return p; - -err_free_consistent: - pci_free_consistent(p->pcidev, p->recvbuf.size, - p->recvbuf.dmabuf, p->recvbuf.dmaaddr); -err_kfree: - kfree(p); -err: - return NULL; -} - -void avmcard_dma_free(avmcard_dmainfo *p) -{ - pci_free_consistent(p->pcidev, p->recvbuf.size, - p->recvbuf.dmabuf, p->recvbuf.dmaaddr); - pci_free_consistent(p->pcidev, p->sendbuf.size, - p->sendbuf.dmabuf, p->sendbuf.dmaaddr); - skb_queue_purge(&p->send_queue); - kfree(p); -} - -EXPORT_SYMBOL(avmcard_dma_alloc); -EXPORT_SYMBOL(avmcard_dma_free); - -#endif - -EXPORT_SYMBOL(b1_irq_table); - -EXPORT_SYMBOL(b1_alloc_card); -EXPORT_SYMBOL(b1_free_card); -EXPORT_SYMBOL(b1_detect); -EXPORT_SYMBOL(b1_getrevision); -EXPORT_SYMBOL(b1_load_t4file); -EXPORT_SYMBOL(b1_load_config); -EXPORT_SYMBOL(b1_loaded); -EXPORT_SYMBOL(b1_load_firmware); -EXPORT_SYMBOL(b1_reset_ctr); -EXPORT_SYMBOL(b1_register_appl); -EXPORT_SYMBOL(b1_release_appl); -EXPORT_SYMBOL(b1_send_message); - -EXPORT_SYMBOL(b1_parse_version); -EXPORT_SYMBOL(b1_interrupt); - -static int __init b1_init(void) -{ - char *p; - char rev[32]; - - if ((p = strchr(revision, ':')) != NULL && p[1]) { - strlcpy(rev, p + 2, 32); - if ((p = strchr(rev, '$')) != NULL && p > rev) - *(p - 1) = 0; - } else - strcpy(rev, "1.0"); - - printk(KERN_INFO "b1: revision %s\n", rev); - - return 0; -} - -static void __exit b1_exit(void) -{ -} - -module_init(b1_init); -module_exit(b1_exit); diff --git a/drivers/isdn/hardware/avm/b1dma.c b/drivers/isdn/hardware/avm/b1dma.c deleted file mode 100644 index 6a3dc9937ce5..000000000000 --- a/drivers/isdn/hardware/avm/b1dma.c +++ /dev/null @@ -1,981 +0,0 @@ -/* $Id: b1dma.c,v 1.1.2.3 2004/02/10 01:07:12 keil Exp $ - * - * Common module for AVM B1 cards that support dma with AMCC - * - * Copyright 2000 by Carsten Paeth <calle@calle.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/proc_fs.h> -#include <linux/seq_file.h> -#include <linux/skbuff.h> -#include <linux/delay.h> -#include <linux/mm.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/capi.h> -#include <linux/kernelcapi.h> -#include <linux/gfp.h> -#include <asm/io.h> -#include <linux/init.h> -#include <linux/uaccess.h> -#include <linux/netdevice.h> -#include <linux/isdn/capilli.h> -#include "avmcard.h" -#include <linux/isdn/capicmd.h> -#include <linux/isdn/capiutil.h> - -static char *revision = "$Revision: 1.1.2.3 $"; - -#undef AVM_B1DMA_DEBUG - -/* ------------------------------------------------------------- */ - -MODULE_DESCRIPTION("CAPI4Linux: DMA support for active AVM cards"); -MODULE_AUTHOR("Carsten Paeth"); -MODULE_LICENSE("GPL"); - -static bool suppress_pollack = 0; -module_param(suppress_pollack, bool, 0); - -/* ------------------------------------------------------------- */ - -static void b1dma_dispatch_tx(avmcard *card); - -/* ------------------------------------------------------------- */ - -/* S5933 */ - -#define AMCC_RXPTR 0x24 -#define AMCC_RXLEN 0x28 -#define AMCC_TXPTR 0x2c -#define AMCC_TXLEN 0x30 - -#define AMCC_INTCSR 0x38 -# define EN_READ_TC_INT 0x00008000L -# define EN_WRITE_TC_INT 0x00004000L -# define EN_TX_TC_INT EN_READ_TC_INT -# define EN_RX_TC_INT EN_WRITE_TC_INT -# define AVM_FLAG 0x30000000L - -# define ANY_S5933_INT 0x00800000L -# define READ_TC_INT 0x00080000L -# define WRITE_TC_INT 0x00040000L -# define TX_TC_INT READ_TC_INT -# define RX_TC_INT WRITE_TC_INT -# define MASTER_ABORT_INT 0x00100000L -# define TARGET_ABORT_INT 0x00200000L -# define BUS_MASTER_INT 0x00200000L -# define ALL_INT 0x000C0000L - -#define AMCC_MCSR 0x3c -# define A2P_HI_PRIORITY 0x00000100L -# define EN_A2P_TRANSFERS 0x00000400L -# define P2A_HI_PRIORITY 0x00001000L -# define EN_P2A_TRANSFERS 0x00004000L -# define RESET_A2P_FLAGS 0x04000000L -# define RESET_P2A_FLAGS 0x02000000L - -/* ------------------------------------------------------------- */ - -static inline void b1dma_writel(avmcard *card, u32 value, int off) -{ - writel(value, card->mbase + off); -} - -static inline u32 b1dma_readl(avmcard *card, int off) -{ - return readl(card->mbase + off); -} - -/* ------------------------------------------------------------- */ - -static inline int b1dma_tx_empty(unsigned int port) -{ - return inb(port + 0x03) & 0x1; -} - -static inline int b1dma_rx_full(unsigned int port) -{ - return inb(port + 0x02) & 0x1; -} - -static int b1dma_tolink(avmcard *card, void *buf, unsigned int len) -{ - unsigned long stop = jiffies + 1 * HZ; /* maximum wait time 1 sec */ - unsigned char *s = (unsigned char *)buf; - while (len--) { - while (!b1dma_tx_empty(card->port) - && time_before(jiffies, stop)); - if (!b1dma_tx_empty(card->port)) - return -1; - t1outp(card->port, 0x01, *s++); - } - return 0; -} - -static int b1dma_fromlink(avmcard *card, void *buf, unsigned int len) -{ - unsigned long stop = jiffies + 1 * HZ; /* maximum wait time 1 sec */ - unsigned char *s = (unsigned char *)buf; - while (len--) { - while (!b1dma_rx_full(card->port) - && time_before(jiffies, stop)); - if (!b1dma_rx_full(card->port)) - return -1; - *s++ = t1inp(card->port, 0x00); - } - return 0; -} - -static int WriteReg(avmcard *card, u32 reg, u8 val) -{ - u8 cmd = 0x00; - if (b1dma_tolink(card, &cmd, 1) == 0 - && b1dma_tolink(card, ®, 4) == 0) { - u32 tmp = val; - return b1dma_tolink(card, &tmp, 4); - } - return -1; -} - -static u8 ReadReg(avmcard *card, u32 reg) -{ - u8 cmd = 0x01; - if (b1dma_tolink(card, &cmd, 1) == 0 - && b1dma_tolink(card, ®, 4) == 0) { - u32 tmp; - if (b1dma_fromlink(card, &tmp, 4) == 0) - return (u8)tmp; - } - return 0xff; -} - -/* ------------------------------------------------------------- */ - -static inline void _put_byte(void **pp, u8 val) -{ - u8 *s = *pp; - *s++ = val; - *pp = s; -} - -static inline void _put_word(void **pp, u32 val) -{ - u8 *s = *pp; - *s++ = val & 0xff; - *s++ = (val >> 8) & 0xff; - *s++ = (val >> 16) & 0xff; - *s++ = (val >> 24) & 0xff; - *pp = s; -} - -static inline void _put_slice(void **pp, unsigned char *dp, unsigned int len) -{ - unsigned i = len; - _put_word(pp, i); - while (i-- > 0) - _put_byte(pp, *dp++); -} - -static inline u8 _get_byte(void **pp) -{ - u8 *s = *pp; - u8 val; - val = *s++; - *pp = s; - return val; -} - -static inline u32 _get_word(void **pp) -{ - u8 *s = *pp; - u32 val; - val = *s++; - val |= (*s++ << 8); - val |= (*s++ << 16); - val |= (*s++ << 24); - *pp = s; - return val; -} - -static inline u32 _get_slice(void **pp, unsigned char *dp) -{ - unsigned int len, i; - - len = i = _get_word(pp); - while (i-- > 0) *dp++ = _get_byte(pp); - return len; -} - -/* ------------------------------------------------------------- */ - -void b1dma_reset(avmcard *card) -{ - card->csr = 0x0; - b1dma_writel(card, card->csr, AMCC_INTCSR); - b1dma_writel(card, 0, AMCC_MCSR); - b1dma_writel(card, 0, AMCC_RXLEN); - b1dma_writel(card, 0, AMCC_TXLEN); - - t1outp(card->port, 0x10, 0x00); - t1outp(card->port, 0x07, 0x00); - - b1dma_writel(card, 0, AMCC_MCSR); - mdelay(10); - b1dma_writel(card, 0x0f000000, AMCC_MCSR); /* reset all */ - mdelay(10); - b1dma_writel(card, 0, AMCC_MCSR); - if (card->cardtype == avm_t1pci) - mdelay(42); - else - mdelay(10); -} - -/* ------------------------------------------------------------- */ - -static int b1dma_detect(avmcard *card) -{ - b1dma_writel(card, 0, AMCC_MCSR); - mdelay(10); - b1dma_writel(card, 0x0f000000, AMCC_MCSR); /* reset all */ - mdelay(10); - b1dma_writel(card, 0, AMCC_MCSR); - mdelay(42); - - b1dma_writel(card, 0, AMCC_RXLEN); - b1dma_writel(card, 0, AMCC_TXLEN); - card->csr = 0x0; - b1dma_writel(card, card->csr, AMCC_INTCSR); - - if (b1dma_readl(card, AMCC_MCSR) != 0x000000E6) - return 1; - - b1dma_writel(card, 0xffffffff, AMCC_RXPTR); - b1dma_writel(card, 0xffffffff, AMCC_TXPTR); - if (b1dma_readl(card, AMCC_RXPTR) != 0xfffffffc - || b1dma_readl(card, AMCC_TXPTR) != 0xfffffffc) - return 2; - - b1dma_writel(card, 0x0, AMCC_RXPTR); - b1dma_writel(card, 0x0, AMCC_TXPTR); - if (b1dma_readl(card, AMCC_RXPTR) != 0x0 - || b1dma_readl(card, AMCC_TXPTR) != 0x0) - return 3; - - t1outp(card->port, 0x10, 0x00); - t1outp(card->port, 0x07, 0x00); - - t1outp(card->port, 0x02, 0x02); - t1outp(card->port, 0x03, 0x02); - - if ((t1inp(card->port, 0x02) & 0xFE) != 0x02 - || t1inp(card->port, 0x3) != 0x03) - return 4; - - t1outp(card->port, 0x02, 0x00); - t1outp(card->port, 0x03, 0x00); - - if ((t1inp(card->port, 0x02) & 0xFE) != 0x00 - || t1inp(card->port, 0x3) != 0x01) - return 5; - - return 0; -} - -int t1pci_detect(avmcard *card) -{ - int ret; - - if ((ret = b1dma_detect(card)) != 0) - return ret; - - /* Transputer test */ - - if (WriteReg(card, 0x80001000, 0x11) != 0 - || WriteReg(card, 0x80101000, 0x22) != 0 - || WriteReg(card, 0x80201000, 0x33) != 0 - || WriteReg(card, 0x80301000, 0x44) != 0) - return 6; - - if (ReadReg(card, 0x80001000) != 0x11 - || ReadReg(card, 0x80101000) != 0x22 - || ReadReg(card, 0x80201000) != 0x33 - || ReadReg(card, 0x80301000) != 0x44) - return 7; - - if (WriteReg(card, 0x80001000, 0x55) != 0 - || WriteReg(card, 0x80101000, 0x66) != 0 - || WriteReg(card, 0x80201000, 0x77) != 0 - || WriteReg(card, 0x80301000, 0x88) != 0) - return 8; - - if (ReadReg(card, 0x80001000) != 0x55 - || ReadReg(card, 0x80101000) != 0x66 - || ReadReg(card, 0x80201000) != 0x77 - || ReadReg(card, 0x80301000) != 0x88) - return 9; - - return 0; -} - -int b1pciv4_detect(avmcard *card) -{ - int ret, i; - - if ((ret = b1dma_detect(card)) != 0) - return ret; - - for (i = 0; i < 5; i++) { - if (WriteReg(card, 0x80A00000, 0x21) != 0) - return 6; - if ((ReadReg(card, 0x80A00000) & 0x01) != 0x01) - return 7; - } - for (i = 0; i < 5; i++) { - if (WriteReg(card, 0x80A00000, 0x20) != 0) - return 8; - if ((ReadReg(card, 0x80A00000) & 0x01) != 0x00) - return 9; - } - - return 0; -} - -static void b1dma_queue_tx(avmcard *card, struct sk_buff *skb) -{ - unsigned long flags; - - spin_lock_irqsave(&card->lock, flags); - - skb_queue_tail(&card->dma->send_queue, skb); - - if (!(card->csr & EN_TX_TC_INT)) { - b1dma_dispatch_tx(card); - b1dma_writel(card, card->csr, AMCC_INTCSR); - } - - spin_unlock_irqrestore(&card->lock, flags); -} - -/* ------------------------------------------------------------- */ - -static void b1dma_dispatch_tx(avmcard *card) -{ - avmcard_dmainfo *dma = card->dma; - struct sk_buff *skb; - u8 cmd, subcmd; - u16 len; - u32 txlen; - void *p; - - skb = skb_dequeue(&dma->send_queue); - - len = CAPIMSG_LEN(skb->data); - - if (len) { - cmd = CAPIMSG_COMMAND(skb->data); - subcmd = CAPIMSG_SUBCOMMAND(skb->data); - - p = dma->sendbuf.dmabuf; - - if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) { - u16 dlen = CAPIMSG_DATALEN(skb->data); - _put_byte(&p, SEND_DATA_B3_REQ); - _put_slice(&p, skb->data, len); - _put_slice(&p, skb->data + len, dlen); - } else { - _put_byte(&p, SEND_MESSAGE); - _put_slice(&p, skb->data, len); - } - txlen = (u8 *)p - (u8 *)dma->sendbuf.dmabuf; -#ifdef AVM_B1DMA_DEBUG - printk(KERN_DEBUG "tx: put msg len=%d\n", txlen); -#endif - } else { - txlen = skb->len - 2; -#ifdef AVM_B1DMA_POLLDEBUG - if (skb->data[2] == SEND_POLLACK) - printk(KERN_INFO "%s: send ack\n", card->name); -#endif -#ifdef AVM_B1DMA_DEBUG - printk(KERN_DEBUG "tx: put 0x%x len=%d\n", - skb->data[2], txlen); -#endif - skb_copy_from_linear_data_offset(skb, 2, dma->sendbuf.dmabuf, - skb->len - 2); - } - txlen = (txlen + 3) & ~3; - - b1dma_writel(card, dma->sendbuf.dmaaddr, AMCC_TXPTR); - b1dma_writel(card, txlen, AMCC_TXLEN); - - card->csr |= EN_TX_TC_INT; - - dev_kfree_skb_any(skb); -} - -/* ------------------------------------------------------------- */ - -static void queue_pollack(avmcard *card) -{ - struct sk_buff *skb; - void *p; - - skb = alloc_skb(3, GFP_ATOMIC); - if (!skb) { - printk(KERN_CRIT "%s: no memory, lost poll ack\n", - card->name); - return; - } - p = skb->data; - _put_byte(&p, 0); - _put_byte(&p, 0); - _put_byte(&p, SEND_POLLACK); - skb_put(skb, (u8 *)p - (u8 *)skb->data); - - b1dma_queue_tx(card, skb); -} - -/* ------------------------------------------------------------- */ - -static void b1dma_handle_rx(avmcard *card) -{ - avmctrl_info *cinfo = &card->ctrlinfo[0]; - avmcard_dmainfo *dma = card->dma; - struct capi_ctr *ctrl = &cinfo->capi_ctrl; - struct sk_buff *skb; - void *p = dma->recvbuf.dmabuf + 4; - u32 ApplId, MsgLen, DataB3Len, NCCI, WindowSize; - u8 b1cmd = _get_byte(&p); - -#ifdef AVM_B1DMA_DEBUG - printk(KERN_DEBUG "rx: 0x%x %lu\n", b1cmd, (unsigned long)dma->recvlen); -#endif - - switch (b1cmd) { - case RECEIVE_DATA_B3_IND: - - ApplId = (unsigned) _get_word(&p); - MsgLen = _get_slice(&p, card->msgbuf); - DataB3Len = _get_slice(&p, card->databuf); - - if (MsgLen < 30) { /* not CAPI 64Bit */ - memset(card->msgbuf + MsgLen, 0, 30 - MsgLen); - MsgLen = 30; - CAPIMSG_SETLEN(card->msgbuf, 30); - } - if (!(skb = alloc_skb(DataB3Len + MsgLen, GFP_ATOMIC))) { - printk(KERN_ERR "%s: incoming packet dropped\n", - card->name); - } else { - skb_put_data(skb, card->msgbuf, MsgLen); - skb_put_data(skb, card->databuf, DataB3Len); - capi_ctr_handle_message(ctrl, ApplId, skb); - } - break; - - case RECEIVE_MESSAGE: - - ApplId = (unsigned) _get_word(&p); - MsgLen = _get_slice(&p, card->msgbuf); - if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) { - printk(KERN_ERR "%s: incoming packet dropped\n", - card->name); - } else { - skb_put_data(skb, card->msgbuf, MsgLen); - if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF) { - spin_lock(&card->lock); - capilib_data_b3_conf(&cinfo->ncci_head, ApplId, - CAPIMSG_NCCI(skb->data), - CAPIMSG_MSGID(skb->data)); - spin_unlock(&card->lock); - } - capi_ctr_handle_message(ctrl, ApplId, skb); - } - break; - - case RECEIVE_NEW_NCCI: - - ApplId = _get_word(&p); - NCCI = _get_word(&p); - WindowSize = _get_word(&p); - spin_lock(&card->lock); - capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize); - spin_unlock(&card->lock); - break; - - case RECEIVE_FREE_NCCI: - - ApplId = _get_word(&p); - NCCI = _get_word(&p); - - if (NCCI != 0xffffffff) { - spin_lock(&card->lock); - capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI); - spin_unlock(&card->lock); - } - break; - - case RECEIVE_START: -#ifdef AVM_B1DMA_POLLDEBUG - printk(KERN_INFO "%s: receive poll\n", card->name); -#endif - if (!suppress_pollack) - queue_pollack(card); - capi_ctr_resume_output(ctrl); - break; - - case RECEIVE_STOP: - capi_ctr_suspend_output(ctrl); - break; - - case RECEIVE_INIT: - - cinfo->versionlen = _get_slice(&p, cinfo->versionbuf); - b1_parse_version(cinfo); - printk(KERN_INFO "%s: %s-card (%s) now active\n", - card->name, - cinfo->version[VER_CARDTYPE], - cinfo->version[VER_DRIVER]); - capi_ctr_ready(ctrl); - break; - - case RECEIVE_TASK_READY: - ApplId = (unsigned) _get_word(&p); - MsgLen = _get_slice(&p, card->msgbuf); - card->msgbuf[MsgLen] = 0; - while (MsgLen > 0 - && (card->msgbuf[MsgLen - 1] == '\n' - || card->msgbuf[MsgLen - 1] == '\r')) { - card->msgbuf[MsgLen - 1] = 0; - MsgLen--; - } - printk(KERN_INFO "%s: task %d \"%s\" ready.\n", - card->name, ApplId, card->msgbuf); - break; - - case RECEIVE_DEBUGMSG: - MsgLen = _get_slice(&p, card->msgbuf); - card->msgbuf[MsgLen] = 0; - while (MsgLen > 0 - && (card->msgbuf[MsgLen - 1] == '\n' - || card->msgbuf[MsgLen - 1] == '\r')) { - card->msgbuf[MsgLen - 1] = 0; - MsgLen--; - } - printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf); - break; - - default: - printk(KERN_ERR "%s: b1dma_interrupt: 0x%x ???\n", - card->name, b1cmd); - return; - } -} - -/* ------------------------------------------------------------- */ - -static void b1dma_handle_interrupt(avmcard *card) -{ - u32 status; - u32 newcsr; - - spin_lock(&card->lock); - - status = b1dma_readl(card, AMCC_INTCSR); - if ((status & ANY_S5933_INT) == 0) { - spin_unlock(&card->lock); - return; - } - - newcsr = card->csr | (status & ALL_INT); - if (status & TX_TC_INT) newcsr &= ~EN_TX_TC_INT; - if (status & RX_TC_INT) newcsr &= ~EN_RX_TC_INT; - b1dma_writel(card, newcsr, AMCC_INTCSR); - - if ((status & RX_TC_INT) != 0) { - struct avmcard_dmainfo *dma = card->dma; - u32 rxlen; - if (card->dma->recvlen == 0) { - rxlen = b1dma_readl(card, AMCC_RXLEN); - if (rxlen == 0) { - dma->recvlen = *((u32 *)dma->recvbuf.dmabuf); - rxlen = (dma->recvlen + 3) & ~3; - b1dma_writel(card, dma->recvbuf.dmaaddr + 4, AMCC_RXPTR); - b1dma_writel(card, rxlen, AMCC_RXLEN); -#ifdef AVM_B1DMA_DEBUG - } else { - printk(KERN_ERR "%s: rx not complete (%d).\n", - card->name, rxlen); -#endif - } - } else { - spin_unlock(&card->lock); - b1dma_handle_rx(card); - dma->recvlen = 0; - spin_lock(&card->lock); - b1dma_writel(card, dma->recvbuf.dmaaddr, AMCC_RXPTR); - b1dma_writel(card, 4, AMCC_RXLEN); - } - } - - if ((status & TX_TC_INT) != 0) { - if (skb_queue_empty(&card->dma->send_queue)) - card->csr &= ~EN_TX_TC_INT; - else - b1dma_dispatch_tx(card); - } - b1dma_writel(card, card->csr, AMCC_INTCSR); - - spin_unlock(&card->lock); -} - -irqreturn_t b1dma_interrupt(int interrupt, void *devptr) -{ - avmcard *card = devptr; - - b1dma_handle_interrupt(card); - return IRQ_HANDLED; -} - -/* ------------------------------------------------------------- */ - -static int b1dma_loaded(avmcard *card) -{ - unsigned long stop; - unsigned char ans; - unsigned long tout = 2; - unsigned int base = card->port; - - for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) { - if (b1_tx_empty(base)) - break; - } - if (!b1_tx_empty(base)) { - printk(KERN_ERR "%s: b1dma_loaded: tx err, corrupted t4 file ?\n", - card->name); - return 0; - } - b1_put_byte(base, SEND_POLLACK); - for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) { - if (b1_rx_full(base)) { - if ((ans = b1_get_byte(base)) == RECEIVE_POLLDWORD) { - return 1; - } - printk(KERN_ERR "%s: b1dma_loaded: got 0x%x, firmware not running in dword mode\n", card->name, ans); - return 0; - } - } - printk(KERN_ERR "%s: b1dma_loaded: firmware not running\n", card->name); - return 0; -} - -/* ------------------------------------------------------------- */ - -static void b1dma_send_init(avmcard *card) -{ - struct sk_buff *skb; - void *p; - - skb = alloc_skb(15, GFP_ATOMIC); - if (!skb) { - printk(KERN_CRIT "%s: no memory, lost register appl.\n", - card->name); - return; - } - p = skb->data; - _put_byte(&p, 0); - _put_byte(&p, 0); - _put_byte(&p, SEND_INIT); - _put_word(&p, CAPI_MAXAPPL); - _put_word(&p, AVM_NCCI_PER_CHANNEL * 30); - _put_word(&p, card->cardnr - 1); - skb_put(skb, (u8 *)p - (u8 *)skb->data); - - b1dma_queue_tx(card, skb); -} - -int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - avmcard *card = cinfo->card; - int retval; - - b1dma_reset(card); - - if ((retval = b1_load_t4file(card, &data->firmware))) { - b1dma_reset(card); - printk(KERN_ERR "%s: failed to load t4file!!\n", - card->name); - return retval; - } - - if (data->configuration.len > 0 && data->configuration.data) { - if ((retval = b1_load_config(card, &data->configuration))) { - b1dma_reset(card); - printk(KERN_ERR "%s: failed to load config!!\n", - card->name); - return retval; - } - } - - if (!b1dma_loaded(card)) { - b1dma_reset(card); - printk(KERN_ERR "%s: failed to load t4file.\n", card->name); - return -EIO; - } - - card->csr = AVM_FLAG; - b1dma_writel(card, card->csr, AMCC_INTCSR); - b1dma_writel(card, EN_A2P_TRANSFERS | EN_P2A_TRANSFERS | A2P_HI_PRIORITY | - P2A_HI_PRIORITY | RESET_A2P_FLAGS | RESET_P2A_FLAGS, - AMCC_MCSR); - t1outp(card->port, 0x07, 0x30); - t1outp(card->port, 0x10, 0xF0); - - card->dma->recvlen = 0; - b1dma_writel(card, card->dma->recvbuf.dmaaddr, AMCC_RXPTR); - b1dma_writel(card, 4, AMCC_RXLEN); - card->csr |= EN_RX_TC_INT; - b1dma_writel(card, card->csr, AMCC_INTCSR); - - b1dma_send_init(card); - - return 0; -} - -void b1dma_reset_ctr(struct capi_ctr *ctrl) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - avmcard *card = cinfo->card; - unsigned long flags; - - spin_lock_irqsave(&card->lock, flags); - b1dma_reset(card); - - memset(cinfo->version, 0, sizeof(cinfo->version)); - capilib_release(&cinfo->ncci_head); - spin_unlock_irqrestore(&card->lock, flags); - capi_ctr_down(ctrl); -} - -/* ------------------------------------------------------------- */ - -void b1dma_register_appl(struct capi_ctr *ctrl, - u16 appl, - capi_register_params *rp) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - avmcard *card = cinfo->card; - struct sk_buff *skb; - int want = rp->level3cnt; - int nconn; - void *p; - - if (want > 0) nconn = want; - else nconn = ctrl->profile.nbchannel * -want; - if (nconn == 0) nconn = ctrl->profile.nbchannel; - - skb = alloc_skb(23, GFP_ATOMIC); - if (!skb) { - printk(KERN_CRIT "%s: no memory, lost register appl.\n", - card->name); - return; - } - p = skb->data; - _put_byte(&p, 0); - _put_byte(&p, 0); - _put_byte(&p, SEND_REGISTER); - _put_word(&p, appl); - _put_word(&p, 1024 * (nconn + 1)); - _put_word(&p, nconn); - _put_word(&p, rp->datablkcnt); - _put_word(&p, rp->datablklen); - skb_put(skb, (u8 *)p - (u8 *)skb->data); - - b1dma_queue_tx(card, skb); -} - -/* ------------------------------------------------------------- */ - -void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - avmcard *card = cinfo->card; - struct sk_buff *skb; - void *p; - unsigned long flags; - - spin_lock_irqsave(&card->lock, flags); - capilib_release_appl(&cinfo->ncci_head, appl); - spin_unlock_irqrestore(&card->lock, flags); - - skb = alloc_skb(7, GFP_ATOMIC); - if (!skb) { - printk(KERN_CRIT "%s: no memory, lost release appl.\n", - card->name); - return; - } - p = skb->data; - _put_byte(&p, 0); - _put_byte(&p, 0); - _put_byte(&p, SEND_RELEASE); - _put_word(&p, appl); - - skb_put(skb, (u8 *)p - (u8 *)skb->data); - - b1dma_queue_tx(card, skb); -} - -/* ------------------------------------------------------------- */ - -u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - avmcard *card = cinfo->card; - u16 retval = CAPI_NOERROR; - - if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) { - unsigned long flags; - spin_lock_irqsave(&card->lock, flags); - retval = capilib_data_b3_req(&cinfo->ncci_head, - CAPIMSG_APPID(skb->data), - CAPIMSG_NCCI(skb->data), - CAPIMSG_MSGID(skb->data)); - spin_unlock_irqrestore(&card->lock, flags); - } - if (retval == CAPI_NOERROR) - b1dma_queue_tx(card, skb); - - return retval; -} - -/* ------------------------------------------------------------- */ - -int b1dma_proc_show(struct seq_file *m, void *v) -{ - struct capi_ctr *ctrl = m->private; - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - avmcard *card = cinfo->card; - u8 flag; - char *s; - u32 txoff, txlen, rxoff, rxlen, csr; - unsigned long flags; - - seq_printf(m, "%-16s %s\n", "name", card->name); - seq_printf(m, "%-16s 0x%x\n", "io", card->port); - seq_printf(m, "%-16s %d\n", "irq", card->irq); - seq_printf(m, "%-16s 0x%lx\n", "membase", card->membase); - switch (card->cardtype) { - case avm_b1isa: s = "B1 ISA"; break; - case avm_b1pci: s = "B1 PCI"; break; - case avm_b1pcmcia: s = "B1 PCMCIA"; break; - case avm_m1: s = "M1"; break; - case avm_m2: s = "M2"; break; - case avm_t1isa: s = "T1 ISA (HEMA)"; break; - case avm_t1pci: s = "T1 PCI"; break; - case avm_c4: s = "C4"; break; - case avm_c2: s = "C2"; break; - default: s = "???"; break; - } - seq_printf(m, "%-16s %s\n", "type", s); - if ((s = cinfo->version[VER_DRIVER]) != NULL) - seq_printf(m, "%-16s %s\n", "ver_driver", s); - if ((s = cinfo->version[VER_CARDTYPE]) != NULL) - seq_printf(m, "%-16s %s\n", "ver_cardtype", s); - if ((s = cinfo->version[VER_SERIAL]) != NULL) - seq_printf(m, "%-16s %s\n", "ver_serial", s); - - if (card->cardtype != avm_m1) { - flag = ((u8 *)(ctrl->profile.manu))[3]; - if (flag) - seq_printf(m, "%-16s%s%s%s%s%s%s%s\n", - "protocol", - (flag & 0x01) ? " DSS1" : "", - (flag & 0x02) ? " CT1" : "", - (flag & 0x04) ? " VN3" : "", - (flag & 0x08) ? " NI1" : "", - (flag & 0x10) ? " AUSTEL" : "", - (flag & 0x20) ? " ESS" : "", - (flag & 0x40) ? " 1TR6" : "" - ); - } - if (card->cardtype != avm_m1) { - flag = ((u8 *)(ctrl->profile.manu))[5]; - if (flag) - seq_printf(m, "%-16s%s%s%s%s\n", - "linetype", - (flag & 0x01) ? " point to point" : "", - (flag & 0x02) ? " point to multipoint" : "", - (flag & 0x08) ? " leased line without D-channel" : "", - (flag & 0x04) ? " leased line with D-channel" : "" - ); - } - seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname); - - - spin_lock_irqsave(&card->lock, flags); - - txoff = (dma_addr_t)b1dma_readl(card, AMCC_TXPTR)-card->dma->sendbuf.dmaaddr; - txlen = b1dma_readl(card, AMCC_TXLEN); - - rxoff = (dma_addr_t)b1dma_readl(card, AMCC_RXPTR)-card->dma->recvbuf.dmaaddr; - rxlen = b1dma_readl(card, AMCC_RXLEN); - - csr = b1dma_readl(card, AMCC_INTCSR); - - spin_unlock_irqrestore(&card->lock, flags); - - seq_printf(m, "%-16s 0x%lx\n", "csr (cached)", (unsigned long)card->csr); - seq_printf(m, "%-16s 0x%lx\n", "csr", (unsigned long)csr); - seq_printf(m, "%-16s %lu\n", "txoff", (unsigned long)txoff); - seq_printf(m, "%-16s %lu\n", "txlen", (unsigned long)txlen); - seq_printf(m, "%-16s %lu\n", "rxoff", (unsigned long)rxoff); - seq_printf(m, "%-16s %lu\n", "rxlen", (unsigned long)rxlen); - - return 0; -} -EXPORT_SYMBOL(b1dma_proc_show); - -/* ------------------------------------------------------------- */ - -EXPORT_SYMBOL(b1dma_reset); -EXPORT_SYMBOL(t1pci_detect); -EXPORT_SYMBOL(b1pciv4_detect); -EXPORT_SYMBOL(b1dma_interrupt); - -EXPORT_SYMBOL(b1dma_load_firmware); -EXPORT_SYMBOL(b1dma_reset_ctr); -EXPORT_SYMBOL(b1dma_register_appl); -EXPORT_SYMBOL(b1dma_release_appl); -EXPORT_SYMBOL(b1dma_send_message); - -static int __init b1dma_init(void) -{ - char *p; - char rev[32]; - - if ((p = strchr(revision, ':')) != NULL && p[1]) { - strlcpy(rev, p + 2, sizeof(rev)); - if ((p = strchr(rev, '$')) != NULL && p > rev) - *(p - 1) = 0; - } else - strcpy(rev, "1.0"); - - printk(KERN_INFO "b1dma: revision %s\n", rev); - - return 0; -} - -static void __exit b1dma_exit(void) -{ -} - -module_init(b1dma_init); -module_exit(b1dma_exit); diff --git a/drivers/isdn/hardware/avm/b1isa.c b/drivers/isdn/hardware/avm/b1isa.c deleted file mode 100644 index cdfea72e0ef6..000000000000 --- a/drivers/isdn/hardware/avm/b1isa.c +++ /dev/null @@ -1,243 +0,0 @@ -/* $Id: b1isa.c,v 1.1.2.3 2004/02/10 01:07:12 keil Exp $ - * - * Module for AVM B1 ISA-card. - * - * Copyright 1999 by Carsten Paeth <calle@calle.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/skbuff.h> -#include <linux/delay.h> -#include <linux/mm.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/capi.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <asm/io.h> -#include <linux/isdn/capicmd.h> -#include <linux/isdn/capiutil.h> -#include <linux/isdn/capilli.h> -#include "avmcard.h" - -/* ------------------------------------------------------------- */ - -static char *revision = "$Revision: 1.1.2.3 $"; - -/* ------------------------------------------------------------- */ - -MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM B1 ISA card"); -MODULE_AUTHOR("Carsten Paeth"); -MODULE_LICENSE("GPL"); - -/* ------------------------------------------------------------- */ - -static void b1isa_remove(struct pci_dev *pdev) -{ - avmctrl_info *cinfo = pci_get_drvdata(pdev); - avmcard *card; - - if (!cinfo) - return; - - card = cinfo->card; - - b1_reset(card->port); - b1_reset(card->port); - - detach_capi_ctr(&cinfo->capi_ctrl); - free_irq(card->irq, card); - release_region(card->port, AVMB1_PORTLEN); - b1_free_card(card); -} - -/* ------------------------------------------------------------- */ - -static char *b1isa_procinfo(struct capi_ctr *ctrl); - -static int b1isa_probe(struct pci_dev *pdev) -{ - avmctrl_info *cinfo; - avmcard *card; - int retval; - - card = b1_alloc_card(1); - if (!card) { - printk(KERN_WARNING "b1isa: no memory.\n"); - retval = -ENOMEM; - goto err; - } - - cinfo = card->ctrlinfo; - - card->port = pci_resource_start(pdev, 0); - card->irq = pdev->irq; - card->cardtype = avm_b1isa; - sprintf(card->name, "b1isa-%x", card->port); - - if (card->port != 0x150 && card->port != 0x250 - && card->port != 0x300 && card->port != 0x340) { - printk(KERN_WARNING "b1isa: invalid port 0x%x.\n", card->port); - retval = -EINVAL; - goto err_free; - } - if (b1_irq_table[card->irq & 0xf] == 0) { - printk(KERN_WARNING "b1isa: irq %d not valid.\n", card->irq); - retval = -EINVAL; - goto err_free; - } - if (!request_region(card->port, AVMB1_PORTLEN, card->name)) { - printk(KERN_WARNING "b1isa: ports 0x%03x-0x%03x in use.\n", - card->port, card->port + AVMB1_PORTLEN); - retval = -EBUSY; - goto err_free; - } - retval = request_irq(card->irq, b1_interrupt, 0, card->name, card); - if (retval) { - printk(KERN_ERR "b1isa: unable to get IRQ %d.\n", card->irq); - goto err_release_region; - } - b1_reset(card->port); - if ((retval = b1_detect(card->port, card->cardtype)) != 0) { - printk(KERN_NOTICE "b1isa: NO card at 0x%x (%d)\n", - card->port, retval); - retval = -ENODEV; - goto err_free_irq; - } - b1_reset(card->port); - b1_getrevision(card); - - cinfo->capi_ctrl.owner = THIS_MODULE; - cinfo->capi_ctrl.driver_name = "b1isa"; - cinfo->capi_ctrl.driverdata = cinfo; - cinfo->capi_ctrl.register_appl = b1_register_appl; - cinfo->capi_ctrl.release_appl = b1_release_appl; - cinfo->capi_ctrl.send_message = b1_send_message; - cinfo->capi_ctrl.load_firmware = b1_load_firmware; - cinfo->capi_ctrl.reset_ctr = b1_reset_ctr; - cinfo->capi_ctrl.procinfo = b1isa_procinfo; - cinfo->capi_ctrl.proc_show = b1_proc_show; - strcpy(cinfo->capi_ctrl.name, card->name); - - retval = attach_capi_ctr(&cinfo->capi_ctrl); - if (retval) { - printk(KERN_ERR "b1isa: attach controller failed.\n"); - goto err_free_irq; - } - - printk(KERN_INFO "b1isa: AVM B1 ISA at i/o %#x, irq %d, revision %d\n", - card->port, card->irq, card->revision); - - pci_set_drvdata(pdev, cinfo); - return 0; - -err_free_irq: - free_irq(card->irq, card); -err_release_region: - release_region(card->port, AVMB1_PORTLEN); -err_free: - b1_free_card(card); -err: - return retval; -} - -static char *b1isa_procinfo(struct capi_ctr *ctrl) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - - if (!cinfo) - return ""; - sprintf(cinfo->infobuf, "%s %s 0x%x %d r%d", - cinfo->cardname[0] ? cinfo->cardname : "-", - cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-", - cinfo->card ? cinfo->card->port : 0x0, - cinfo->card ? cinfo->card->irq : 0, - cinfo->card ? cinfo->card->revision : 0 - ); - return cinfo->infobuf; -} - -/* ------------------------------------------------------------- */ - -#define MAX_CARDS 4 -static struct pci_dev isa_dev[MAX_CARDS]; -static int io[MAX_CARDS]; -static int irq[MAX_CARDS]; - -module_param_hw_array(io, int, ioport, NULL, 0); -module_param_hw_array(irq, int, irq, NULL, 0); -MODULE_PARM_DESC(io, "I/O base address(es)"); -MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)"); - -static int b1isa_add_card(struct capi_driver *driver, capicardparams *data) -{ - int i; - - for (i = 0; i < MAX_CARDS; i++) { - if (isa_dev[i].resource[0].start) - continue; - - isa_dev[i].resource[0].start = data->port; - isa_dev[i].irq = data->irq; - - if (b1isa_probe(&isa_dev[i]) == 0) - return 0; - } - return -ENODEV; -} - -static struct capi_driver capi_driver_b1isa = { - .name = "b1isa", - .revision = "1.0", - .add_card = b1isa_add_card, -}; - -static int __init b1isa_init(void) -{ - char *p; - char rev[32]; - int i; - - if ((p = strchr(revision, ':')) != NULL && p[1]) { - strlcpy(rev, p + 2, 32); - if ((p = strchr(rev, '$')) != NULL && p > rev) - *(p - 1) = 0; - } else - strcpy(rev, "1.0"); - - for (i = 0; i < MAX_CARDS; i++) { - if (!io[i]) - break; - - isa_dev[i].resource[0].start = io[i]; - isa_dev[i].irq = irq[i]; - - if (b1isa_probe(&isa_dev[i]) != 0) - return -ENODEV; - } - - strlcpy(capi_driver_b1isa.revision, rev, 32); - register_capi_driver(&capi_driver_b1isa); - printk(KERN_INFO "b1isa: revision %s\n", rev); - - return 0; -} - -static void __exit b1isa_exit(void) -{ - int i; - - for (i = 0; i < MAX_CARDS; i++) { - if (isa_dev[i].resource[0].start) - b1isa_remove(&isa_dev[i]); - } - unregister_capi_driver(&capi_driver_b1isa); -} - -module_init(b1isa_init); -module_exit(b1isa_exit); diff --git a/drivers/isdn/hardware/avm/b1pci.c b/drivers/isdn/hardware/avm/b1pci.c deleted file mode 100644 index b76b57a82c02..000000000000 --- a/drivers/isdn/hardware/avm/b1pci.c +++ /dev/null @@ -1,416 +0,0 @@ -/* $Id: b1pci.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $ - * - * Module for AVM B1 PCI-card. - * - * Copyright 1999 by Carsten Paeth <calle@calle.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/skbuff.h> -#include <linux/delay.h> -#include <linux/mm.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/pci.h> -#include <linux/capi.h> -#include <asm/io.h> -#include <linux/init.h> -#include <linux/isdn/capicmd.h> -#include <linux/isdn/capiutil.h> -#include <linux/isdn/capilli.h> -#include "avmcard.h" - -/* ------------------------------------------------------------- */ - -static char *revision = "$Revision: 1.1.2.2 $"; - -/* ------------------------------------------------------------- */ - -static struct pci_device_id b1pci_pci_tbl[] = { - { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_B1, PCI_ANY_ID, PCI_ANY_ID }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(pci, b1pci_pci_tbl); -MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM B1 PCI card"); -MODULE_AUTHOR("Carsten Paeth"); -MODULE_LICENSE("GPL"); - -/* ------------------------------------------------------------- */ - -static char *b1pci_procinfo(struct capi_ctr *ctrl) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - - if (!cinfo) - return ""; - sprintf(cinfo->infobuf, "%s %s 0x%x %d r%d", - cinfo->cardname[0] ? cinfo->cardname : "-", - cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-", - cinfo->card ? cinfo->card->port : 0x0, - cinfo->card ? cinfo->card->irq : 0, - cinfo->card ? cinfo->card->revision : 0 - ); - return cinfo->infobuf; -} - -/* ------------------------------------------------------------- */ - -static int b1pci_probe(struct capicardparams *p, struct pci_dev *pdev) -{ - avmcard *card; - avmctrl_info *cinfo; - int retval; - - card = b1_alloc_card(1); - if (!card) { - printk(KERN_WARNING "b1pci: no memory.\n"); - retval = -ENOMEM; - goto err; - } - - cinfo = card->ctrlinfo; - sprintf(card->name, "b1pci-%x", p->port); - card->port = p->port; - card->irq = p->irq; - card->cardtype = avm_b1pci; - - if (!request_region(card->port, AVMB1_PORTLEN, card->name)) { - printk(KERN_WARNING "b1pci: ports 0x%03x-0x%03x in use.\n", - card->port, card->port + AVMB1_PORTLEN); - retval = -EBUSY; - goto err_free; - } - b1_reset(card->port); - retval = b1_detect(card->port, card->cardtype); - if (retval) { - printk(KERN_NOTICE "b1pci: NO card at 0x%x (%d)\n", - card->port, retval); - retval = -ENODEV; - goto err_release_region; - } - b1_reset(card->port); - b1_getrevision(card); - - retval = request_irq(card->irq, b1_interrupt, IRQF_SHARED, card->name, card); - if (retval) { - printk(KERN_ERR "b1pci: unable to get IRQ %d.\n", card->irq); - retval = -EBUSY; - goto err_release_region; - } - - cinfo->capi_ctrl.driver_name = "b1pci"; - cinfo->capi_ctrl.driverdata = cinfo; - cinfo->capi_ctrl.register_appl = b1_register_appl; - cinfo->capi_ctrl.release_appl = b1_release_appl; - cinfo->capi_ctrl.send_message = b1_send_message; - cinfo->capi_ctrl.load_firmware = b1_load_firmware; - cinfo->capi_ctrl.reset_ctr = b1_reset_ctr; - cinfo->capi_ctrl.procinfo = b1pci_procinfo; - cinfo->capi_ctrl.proc_show = b1_proc_show; - strcpy(cinfo->capi_ctrl.name, card->name); - cinfo->capi_ctrl.owner = THIS_MODULE; - - retval = attach_capi_ctr(&cinfo->capi_ctrl); - if (retval) { - printk(KERN_ERR "b1pci: attach controller failed.\n"); - goto err_free_irq; - } - - if (card->revision >= 4) { - printk(KERN_INFO "b1pci: AVM B1 PCI V4 at i/o %#x, irq %d, revision %d (no dma)\n", - card->port, card->irq, card->revision); - } else { - printk(KERN_INFO "b1pci: AVM B1 PCI at i/o %#x, irq %d, revision %d\n", - card->port, card->irq, card->revision); - } - - pci_set_drvdata(pdev, card); - return 0; - -err_free_irq: - free_irq(card->irq, card); -err_release_region: - release_region(card->port, AVMB1_PORTLEN); -err_free: - b1_free_card(card); -err: - return retval; -} - -static void b1pci_remove(struct pci_dev *pdev) -{ - avmcard *card = pci_get_drvdata(pdev); - avmctrl_info *cinfo = card->ctrlinfo; - unsigned int port = card->port; - - b1_reset(port); - b1_reset(port); - - detach_capi_ctr(&cinfo->capi_ctrl); - free_irq(card->irq, card); - release_region(card->port, AVMB1_PORTLEN); - b1_free_card(card); -} - -#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4 -/* ------------------------------------------------------------- */ - -static char *b1pciv4_procinfo(struct capi_ctr *ctrl) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - - if (!cinfo) - return ""; - sprintf(cinfo->infobuf, "%s %s 0x%x %d 0x%lx r%d", - cinfo->cardname[0] ? cinfo->cardname : "-", - cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-", - cinfo->card ? cinfo->card->port : 0x0, - cinfo->card ? cinfo->card->irq : 0, - cinfo->card ? cinfo->card->membase : 0, - cinfo->card ? cinfo->card->revision : 0 - ); - return cinfo->infobuf; -} - -/* ------------------------------------------------------------- */ - -static int b1pciv4_probe(struct capicardparams *p, struct pci_dev *pdev) -{ - avmcard *card; - avmctrl_info *cinfo; - int retval; - - card = b1_alloc_card(1); - if (!card) { - printk(KERN_WARNING "b1pci: no memory.\n"); - retval = -ENOMEM; - goto err; - } - - card->dma = avmcard_dma_alloc("b1pci", pdev, 2048 + 128, 2048 + 128); - if (!card->dma) { - printk(KERN_WARNING "b1pci: dma alloc.\n"); - retval = -ENOMEM; - goto err_free; - } - - cinfo = card->ctrlinfo; - sprintf(card->name, "b1pciv4-%x", p->port); - card->port = p->port; - card->irq = p->irq; - card->membase = p->membase; - card->cardtype = avm_b1pci; - - if (!request_region(card->port, AVMB1_PORTLEN, card->name)) { - printk(KERN_WARNING "b1pci: ports 0x%03x-0x%03x in use.\n", - card->port, card->port + AVMB1_PORTLEN); - retval = -EBUSY; - goto err_free_dma; - } - - card->mbase = ioremap(card->membase, 64); - if (!card->mbase) { - printk(KERN_NOTICE "b1pci: can't remap memory at 0x%lx\n", - card->membase); - retval = -ENOMEM; - goto err_release_region; - } - - b1dma_reset(card); - - retval = b1pciv4_detect(card); - if (retval) { - printk(KERN_NOTICE "b1pci: NO card at 0x%x (%d)\n", - card->port, retval); - retval = -ENODEV; - goto err_unmap; - } - b1dma_reset(card); - b1_getrevision(card); - - retval = request_irq(card->irq, b1dma_interrupt, IRQF_SHARED, card->name, card); - if (retval) { - printk(KERN_ERR "b1pci: unable to get IRQ %d.\n", - card->irq); - retval = -EBUSY; - goto err_unmap; - } - - cinfo->capi_ctrl.owner = THIS_MODULE; - cinfo->capi_ctrl.driver_name = "b1pciv4"; - cinfo->capi_ctrl.driverdata = cinfo; - cinfo->capi_ctrl.register_appl = b1dma_register_appl; - cinfo->capi_ctrl.release_appl = b1dma_release_appl; - cinfo->capi_ctrl.send_message = b1dma_send_message; - cinfo->capi_ctrl.load_firmware = b1dma_load_firmware; - cinfo->capi_ctrl.reset_ctr = b1dma_reset_ctr; - cinfo->capi_ctrl.procinfo = b1pciv4_procinfo; - cinfo->capi_ctrl.proc_show = b1dma_proc_show; - strcpy(cinfo->capi_ctrl.name, card->name); - - retval = attach_capi_ctr(&cinfo->capi_ctrl); - if (retval) { - printk(KERN_ERR "b1pci: attach controller failed.\n"); - goto err_free_irq; - } - card->cardnr = cinfo->capi_ctrl.cnr; - - printk(KERN_INFO "b1pci: AVM B1 PCI V4 at i/o %#x, irq %d, mem %#lx, revision %d (dma)\n", - card->port, card->irq, card->membase, card->revision); - - pci_set_drvdata(pdev, card); - return 0; - -err_free_irq: - free_irq(card->irq, card); -err_unmap: - iounmap(card->mbase); -err_release_region: - release_region(card->port, AVMB1_PORTLEN); -err_free_dma: - avmcard_dma_free(card->dma); -err_free: - b1_free_card(card); -err: - return retval; - -} - -static void b1pciv4_remove(struct pci_dev *pdev) -{ - avmcard *card = pci_get_drvdata(pdev); - avmctrl_info *cinfo = card->ctrlinfo; - - b1dma_reset(card); - - detach_capi_ctr(&cinfo->capi_ctrl); - free_irq(card->irq, card); - iounmap(card->mbase); - release_region(card->port, AVMB1_PORTLEN); - avmcard_dma_free(card->dma); - b1_free_card(card); -} - -#endif /* CONFIG_ISDN_DRV_AVMB1_B1PCIV4 */ - -static int b1pci_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct capicardparams param; - int retval; - - if (pci_enable_device(pdev) < 0) { - printk(KERN_ERR "b1pci: failed to enable AVM-B1\n"); - return -ENODEV; - } - param.irq = pdev->irq; - - if (pci_resource_start(pdev, 2)) { /* B1 PCI V4 */ -#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4 - pci_set_master(pdev); -#endif - param.membase = pci_resource_start(pdev, 0); - param.port = pci_resource_start(pdev, 2); - - printk(KERN_INFO "b1pci: PCI BIOS reports AVM-B1 V4 at i/o %#x, irq %d, mem %#x\n", - param.port, param.irq, param.membase); -#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4 - retval = b1pciv4_probe(¶m, pdev); -#else - retval = b1pci_probe(¶m, pdev); -#endif - if (retval != 0) { - printk(KERN_ERR "b1pci: no AVM-B1 V4 at i/o %#x, irq %d, mem %#x detected\n", - param.port, param.irq, param.membase); - } - } else { - param.membase = 0; - param.port = pci_resource_start(pdev, 1); - - printk(KERN_INFO "b1pci: PCI BIOS reports AVM-B1 at i/o %#x, irq %d\n", - param.port, param.irq); - retval = b1pci_probe(¶m, pdev); - if (retval != 0) { - printk(KERN_ERR "b1pci: no AVM-B1 at i/o %#x, irq %d detected\n", - param.port, param.irq); - } - } - return retval; -} - -static void b1pci_pci_remove(struct pci_dev *pdev) -{ -#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4 - avmcard *card = pci_get_drvdata(pdev); - - if (card->dma) - b1pciv4_remove(pdev); - else - b1pci_remove(pdev); -#else - b1pci_remove(pdev); -#endif -} - -static struct pci_driver b1pci_pci_driver = { - .name = "b1pci", - .id_table = b1pci_pci_tbl, - .probe = b1pci_pci_probe, - .remove = b1pci_pci_remove, -}; - -static struct capi_driver capi_driver_b1pci = { - .name = "b1pci", - .revision = "1.0", -}; -#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4 -static struct capi_driver capi_driver_b1pciv4 = { - .name = "b1pciv4", - .revision = "1.0", -}; -#endif - -static int __init b1pci_init(void) -{ - char *p; - char rev[32]; - int err; - - if ((p = strchr(revision, ':')) != NULL && p[1]) { - strlcpy(rev, p + 2, 32); - if ((p = strchr(rev, '$')) != NULL && p > rev) - *(p - 1) = 0; - } else - strcpy(rev, "1.0"); - - - err = pci_register_driver(&b1pci_pci_driver); - if (!err) { - strlcpy(capi_driver_b1pci.revision, rev, 32); - register_capi_driver(&capi_driver_b1pci); -#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4 - strlcpy(capi_driver_b1pciv4.revision, rev, 32); - register_capi_driver(&capi_driver_b1pciv4); -#endif - printk(KERN_INFO "b1pci: revision %s\n", rev); - } - return err; -} - -static void __exit b1pci_exit(void) -{ - unregister_capi_driver(&capi_driver_b1pci); -#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4 - unregister_capi_driver(&capi_driver_b1pciv4); -#endif - pci_unregister_driver(&b1pci_pci_driver); -} - -module_init(b1pci_init); -module_exit(b1pci_exit); diff --git a/drivers/isdn/hardware/avm/b1pcmcia.c b/drivers/isdn/hardware/avm/b1pcmcia.c deleted file mode 100644 index 3aca16e62902..000000000000 --- a/drivers/isdn/hardware/avm/b1pcmcia.c +++ /dev/null @@ -1,224 +0,0 @@ -/* $Id: b1pcmcia.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $ - * - * Module for AVM B1/M1/M2 PCMCIA-card. - * - * Copyright 1999 by Carsten Paeth <calle@calle.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/skbuff.h> -#include <linux/delay.h> -#include <linux/mm.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/init.h> -#include <asm/io.h> -#include <linux/capi.h> -#include <linux/b1pcmcia.h> -#include <linux/isdn/capicmd.h> -#include <linux/isdn/capiutil.h> -#include <linux/isdn/capilli.h> -#include "avmcard.h" - -/* ------------------------------------------------------------- */ - -static char *revision = "$Revision: 1.1.2.2 $"; - -/* ------------------------------------------------------------- */ - -MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM PCMCIA cards"); -MODULE_AUTHOR("Carsten Paeth"); -MODULE_LICENSE("GPL"); - -/* ------------------------------------------------------------- */ - -static void b1pcmcia_remove_ctr(struct capi_ctr *ctrl) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - avmcard *card = cinfo->card; - unsigned int port = card->port; - - b1_reset(port); - b1_reset(port); - - detach_capi_ctr(ctrl); - free_irq(card->irq, card); - b1_free_card(card); -} - -/* ------------------------------------------------------------- */ - -static LIST_HEAD(cards); - -static char *b1pcmcia_procinfo(struct capi_ctr *ctrl); - -static int b1pcmcia_add_card(unsigned int port, unsigned irq, - enum avmcardtype cardtype) -{ - avmctrl_info *cinfo; - avmcard *card; - char *cardname; - int retval; - - card = b1_alloc_card(1); - if (!card) { - printk(KERN_WARNING "b1pcmcia: no memory.\n"); - retval = -ENOMEM; - goto err; - } - cinfo = card->ctrlinfo; - - switch (cardtype) { - case avm_m1: sprintf(card->name, "m1-%x", port); break; - case avm_m2: sprintf(card->name, "m2-%x", port); break; - default: sprintf(card->name, "b1pcmcia-%x", port); break; - } - card->port = port; - card->irq = irq; - card->cardtype = cardtype; - - retval = request_irq(card->irq, b1_interrupt, IRQF_SHARED, card->name, card); - if (retval) { - printk(KERN_ERR "b1pcmcia: unable to get IRQ %d.\n", - card->irq); - retval = -EBUSY; - goto err_free; - } - b1_reset(card->port); - if ((retval = b1_detect(card->port, card->cardtype)) != 0) { - printk(KERN_NOTICE "b1pcmcia: NO card at 0x%x (%d)\n", - card->port, retval); - retval = -ENODEV; - goto err_free_irq; - } - b1_reset(card->port); - b1_getrevision(card); - - cinfo->capi_ctrl.owner = THIS_MODULE; - cinfo->capi_ctrl.driver_name = "b1pcmcia"; - cinfo->capi_ctrl.driverdata = cinfo; - cinfo->capi_ctrl.register_appl = b1_register_appl; - cinfo->capi_ctrl.release_appl = b1_release_appl; - cinfo->capi_ctrl.send_message = b1_send_message; - cinfo->capi_ctrl.load_firmware = b1_load_firmware; - cinfo->capi_ctrl.reset_ctr = b1_reset_ctr; - cinfo->capi_ctrl.procinfo = b1pcmcia_procinfo; - cinfo->capi_ctrl.proc_show = b1_proc_show; - strcpy(cinfo->capi_ctrl.name, card->name); - - retval = attach_capi_ctr(&cinfo->capi_ctrl); - if (retval) { - printk(KERN_ERR "b1pcmcia: attach controller failed.\n"); - goto err_free_irq; - } - switch (cardtype) { - case avm_m1: cardname = "M1"; break; - case avm_m2: cardname = "M2"; break; - default: cardname = "B1 PCMCIA"; break; - } - - printk(KERN_INFO "b1pcmcia: AVM %s at i/o %#x, irq %d, revision %d\n", - cardname, card->port, card->irq, card->revision); - - list_add(&card->list, &cards); - return cinfo->capi_ctrl.cnr; - -err_free_irq: - free_irq(card->irq, card); -err_free: - b1_free_card(card); -err: - return retval; -} - -/* ------------------------------------------------------------- */ - -static char *b1pcmcia_procinfo(struct capi_ctr *ctrl) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - - if (!cinfo) - return ""; - sprintf(cinfo->infobuf, "%s %s 0x%x %d r%d", - cinfo->cardname[0] ? cinfo->cardname : "-", - cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-", - cinfo->card ? cinfo->card->port : 0x0, - cinfo->card ? cinfo->card->irq : 0, - cinfo->card ? cinfo->card->revision : 0 - ); - return cinfo->infobuf; -} - -/* ------------------------------------------------------------- */ - -int b1pcmcia_addcard_b1(unsigned int port, unsigned irq) -{ - return b1pcmcia_add_card(port, irq, avm_b1pcmcia); -} - -int b1pcmcia_addcard_m1(unsigned int port, unsigned irq) -{ - return b1pcmcia_add_card(port, irq, avm_m1); -} - -int b1pcmcia_addcard_m2(unsigned int port, unsigned irq) -{ - return b1pcmcia_add_card(port, irq, avm_m2); -} - -int b1pcmcia_delcard(unsigned int port, unsigned irq) -{ - struct list_head *l; - avmcard *card; - - list_for_each(l, &cards) { - card = list_entry(l, avmcard, list); - if (card->port == port && card->irq == irq) { - b1pcmcia_remove_ctr(&card->ctrlinfo[0].capi_ctrl); - return 0; - } - } - return -ESRCH; -} - -EXPORT_SYMBOL(b1pcmcia_addcard_b1); -EXPORT_SYMBOL(b1pcmcia_addcard_m1); -EXPORT_SYMBOL(b1pcmcia_addcard_m2); -EXPORT_SYMBOL(b1pcmcia_delcard); - -static struct capi_driver capi_driver_b1pcmcia = { - .name = "b1pcmcia", - .revision = "1.0", -}; - -static int __init b1pcmcia_init(void) -{ - char *p; - char rev[32]; - - if ((p = strchr(revision, ':')) != NULL && p[1]) { - strlcpy(rev, p + 2, 32); - if ((p = strchr(rev, '$')) != NULL && p > rev) - *(p - 1) = 0; - } else - strcpy(rev, "1.0"); - - strlcpy(capi_driver_b1pcmcia.revision, rev, 32); - register_capi_driver(&capi_driver_b1pcmcia); - printk(KERN_INFO "b1pci: revision %s\n", rev); - - return 0; -} - -static void __exit b1pcmcia_exit(void) -{ - unregister_capi_driver(&capi_driver_b1pcmcia); -} - -module_init(b1pcmcia_init); -module_exit(b1pcmcia_exit); diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c deleted file mode 100644 index ac72cd204c4d..000000000000 --- a/drivers/isdn/hardware/avm/c4.c +++ /dev/null @@ -1,1317 +0,0 @@ -/* $Id: c4.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $ - * - * Module for AVM C4 & C2 card. - * - * Copyright 1999 by Carsten Paeth <calle@calle.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/proc_fs.h> -#include <linux/seq_file.h> -#include <linux/skbuff.h> -#include <linux/delay.h> -#include <linux/mm.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/pci.h> -#include <linux/capi.h> -#include <linux/kernelcapi.h> -#include <linux/init.h> -#include <linux/gfp.h> -#include <asm/io.h> -#include <linux/uaccess.h> -#include <linux/netdevice.h> -#include <linux/isdn/capicmd.h> -#include <linux/isdn/capiutil.h> -#include <linux/isdn/capilli.h> -#include "avmcard.h" - -#undef AVM_C4_DEBUG -#undef AVM_C4_POLLDEBUG - -/* ------------------------------------------------------------- */ - -static char *revision = "$Revision: 1.1.2.2 $"; - -/* ------------------------------------------------------------- */ - -static bool suppress_pollack; - -static const struct pci_device_id c4_pci_tbl[] = { - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_C4, 0, 0, (unsigned long)4 }, - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_C2, 0, 0, (unsigned long)2 }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(pci, c4_pci_tbl); -MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM C2/C4 cards"); -MODULE_AUTHOR("Carsten Paeth"); -MODULE_LICENSE("GPL"); -module_param(suppress_pollack, bool, 0); - -/* ------------------------------------------------------------- */ - -static void c4_dispatch_tx(avmcard *card); - -/* ------------------------------------------------------------- */ - -#define DC21285_DRAM_A0MR 0x40000000 -#define DC21285_DRAM_A1MR 0x40004000 -#define DC21285_DRAM_A2MR 0x40008000 -#define DC21285_DRAM_A3MR 0x4000C000 - -#define CAS_OFFSET 0x88 - -#define DC21285_ARMCSR_BASE 0x42000000 - -#define PCI_OUT_INT_STATUS 0x30 -#define PCI_OUT_INT_MASK 0x34 -#define MAILBOX_0 0x50 -#define MAILBOX_1 0x54 -#define MAILBOX_2 0x58 -#define MAILBOX_3 0x5C -#define DOORBELL 0x60 -#define DOORBELL_SETUP 0x64 - -#define CHAN_1_CONTROL 0x90 -#define CHAN_2_CONTROL 0xB0 -#define DRAM_TIMING 0x10C -#define DRAM_ADDR_SIZE_0 0x110 -#define DRAM_ADDR_SIZE_1 0x114 -#define DRAM_ADDR_SIZE_2 0x118 -#define DRAM_ADDR_SIZE_3 0x11C -#define SA_CONTROL 0x13C -#define XBUS_CYCLE 0x148 -#define XBUS_STROBE 0x14C -#define DBELL_PCI_MASK 0x150 -#define DBELL_SA_MASK 0x154 - -#define SDRAM_SIZE 0x1000000 - -/* ------------------------------------------------------------- */ - -#define MBOX_PEEK_POKE MAILBOX_0 - -#define DBELL_ADDR 0x01 -#define DBELL_DATA 0x02 -#define DBELL_RNWR 0x40 -#define DBELL_INIT 0x80 - -/* ------------------------------------------------------------- */ - -#define MBOX_UP_ADDR MAILBOX_0 -#define MBOX_UP_LEN MAILBOX_1 -#define MBOX_DOWN_ADDR MAILBOX_2 -#define MBOX_DOWN_LEN MAILBOX_3 - -#define DBELL_UP_HOST 0x00000100 -#define DBELL_UP_ARM 0x00000200 -#define DBELL_DOWN_HOST 0x00000400 -#define DBELL_DOWN_ARM 0x00000800 -#define DBELL_RESET_HOST 0x40000000 -#define DBELL_RESET_ARM 0x80000000 - -/* ------------------------------------------------------------- */ - -#define DRAM_TIMING_DEF 0x001A01A5 -#define DRAM_AD_SZ_DEF0 0x00000045 -#define DRAM_AD_SZ_NULL 0x00000000 - -#define SA_CTL_ALLRIGHT 0x64AA0271 - -#define INIT_XBUS_CYCLE 0x100016DB -#define INIT_XBUS_STROBE 0xF1F1F1F1 - -/* ------------------------------------------------------------- */ - -#define RESET_TIMEOUT (15 * HZ) /* 15 sec */ -#define PEEK_POKE_TIMEOUT (HZ / 10) /* 0.1 sec */ - -/* ------------------------------------------------------------- */ - -#define c4outmeml(addr, value) writel(value, addr) -#define c4inmeml(addr) readl(addr) -#define c4outmemw(addr, value) writew(value, addr) -#define c4inmemw(addr) readw(addr) -#define c4outmemb(addr, value) writeb(value, addr) -#define c4inmemb(addr) readb(addr) - -/* ------------------------------------------------------------- */ - -static inline int wait_for_doorbell(avmcard *card, unsigned long t) -{ - unsigned long stop; - - stop = jiffies + t; - while (c4inmeml(card->mbase + DOORBELL) != 0xffffffff) { - if (!time_before(jiffies, stop)) - return -1; - mb(); - } - return 0; -} - -static int c4_poke(avmcard *card, unsigned long off, unsigned long value) -{ - - if (wait_for_doorbell(card, HZ / 10) < 0) - return -1; - - c4outmeml(card->mbase + MBOX_PEEK_POKE, off); - c4outmeml(card->mbase + DOORBELL, DBELL_ADDR); - - if (wait_for_doorbell(card, HZ / 10) < 0) - return -1; - - c4outmeml(card->mbase + MBOX_PEEK_POKE, value); - c4outmeml(card->mbase + DOORBELL, DBELL_DATA | DBELL_ADDR); - - return 0; -} - -static int c4_peek(avmcard *card, unsigned long off, unsigned long *valuep) -{ - if (wait_for_doorbell(card, HZ / 10) < 0) - return -1; - - c4outmeml(card->mbase + MBOX_PEEK_POKE, off); - c4outmeml(card->mbase + DOORBELL, DBELL_RNWR | DBELL_ADDR); - - if (wait_for_doorbell(card, HZ / 10) < 0) - return -1; - - *valuep = c4inmeml(card->mbase + MBOX_PEEK_POKE); - - return 0; -} - -/* ------------------------------------------------------------- */ - -static int c4_load_t4file(avmcard *card, capiloaddatapart *t4file) -{ - u32 val; - unsigned char *dp; - u_int left; - u32 loadoff = 0; - - dp = t4file->data; - left = t4file->len; - while (left >= sizeof(u32)) { - if (t4file->user) { - if (copy_from_user(&val, dp, sizeof(val))) - return -EFAULT; - } else { - memcpy(&val, dp, sizeof(val)); - } - if (c4_poke(card, loadoff, val)) { - printk(KERN_ERR "%s: corrupted firmware file ?\n", - card->name); - return -EIO; - } - left -= sizeof(u32); - dp += sizeof(u32); - loadoff += sizeof(u32); - } - if (left) { - val = 0; - if (t4file->user) { - if (copy_from_user(&val, dp, left)) - return -EFAULT; - } else { - memcpy(&val, dp, left); - } - if (c4_poke(card, loadoff, val)) { - printk(KERN_ERR "%s: corrupted firmware file ?\n", - card->name); - return -EIO; - } - } - return 0; -} - -/* ------------------------------------------------------------- */ - -static inline void _put_byte(void **pp, u8 val) -{ - u8 *s = *pp; - *s++ = val; - *pp = s; -} - -static inline void _put_word(void **pp, u32 val) -{ - u8 *s = *pp; - *s++ = val & 0xff; - *s++ = (val >> 8) & 0xff; - *s++ = (val >> 16) & 0xff; - *s++ = (val >> 24) & 0xff; - *pp = s; -} - -static inline void _put_slice(void **pp, unsigned char *dp, unsigned int len) -{ - unsigned i = len; - _put_word(pp, i); - while (i-- > 0) - _put_byte(pp, *dp++); -} - -static inline u8 _get_byte(void **pp) -{ - u8 *s = *pp; - u8 val; - val = *s++; - *pp = s; - return val; -} - -static inline u32 _get_word(void **pp) -{ - u8 *s = *pp; - u32 val; - val = *s++; - val |= (*s++ << 8); - val |= (*s++ << 16); - val |= (*s++ << 24); - *pp = s; - return val; -} - -static inline u32 _get_slice(void **pp, unsigned char *dp) -{ - unsigned int len, i; - - len = i = _get_word(pp); - while (i-- > 0) *dp++ = _get_byte(pp); - return len; -} - -/* ------------------------------------------------------------- */ - -static void c4_reset(avmcard *card) -{ - unsigned long stop; - - c4outmeml(card->mbase + DOORBELL, DBELL_RESET_ARM); - - stop = jiffies + HZ * 10; - while (c4inmeml(card->mbase + DOORBELL) != 0xffffffff) { - if (!time_before(jiffies, stop)) - return; - c4outmeml(card->mbase + DOORBELL, DBELL_ADDR); - mb(); - } - - c4_poke(card, DC21285_ARMCSR_BASE + CHAN_1_CONTROL, 0); - c4_poke(card, DC21285_ARMCSR_BASE + CHAN_2_CONTROL, 0); -} - -/* ------------------------------------------------------------- */ - -static int c4_detect(avmcard *card) -{ - unsigned long stop, dummy; - - c4outmeml(card->mbase + PCI_OUT_INT_MASK, 0x0c); - if (c4inmeml(card->mbase + PCI_OUT_INT_MASK) != 0x0c) - return 1; - - c4outmeml(card->mbase + DOORBELL, DBELL_RESET_ARM); - - stop = jiffies + HZ * 10; - while (c4inmeml(card->mbase + DOORBELL) != 0xffffffff) { - if (!time_before(jiffies, stop)) - return 2; - c4outmeml(card->mbase + DOORBELL, DBELL_ADDR); - mb(); - } - - c4_poke(card, DC21285_ARMCSR_BASE + CHAN_1_CONTROL, 0); - c4_poke(card, DC21285_ARMCSR_BASE + CHAN_2_CONTROL, 0); - - c4outmeml(card->mbase + MAILBOX_0, 0x55aa55aa); - if (c4inmeml(card->mbase + MAILBOX_0) != 0x55aa55aa) return 3; - - c4outmeml(card->mbase + MAILBOX_0, 0xaa55aa55); - if (c4inmeml(card->mbase + MAILBOX_0) != 0xaa55aa55) return 4; - - if (c4_poke(card, DC21285_ARMCSR_BASE + DBELL_SA_MASK, 0)) return 5; - if (c4_poke(card, DC21285_ARMCSR_BASE + DBELL_PCI_MASK, 0)) return 6; - if (c4_poke(card, DC21285_ARMCSR_BASE + SA_CONTROL, SA_CTL_ALLRIGHT)) - return 7; - if (c4_poke(card, DC21285_ARMCSR_BASE + XBUS_CYCLE, INIT_XBUS_CYCLE)) - return 8; - if (c4_poke(card, DC21285_ARMCSR_BASE + XBUS_STROBE, INIT_XBUS_STROBE)) - return 8; - if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_TIMING, 0)) return 9; - - mdelay(1); - - if (c4_peek(card, DC21285_DRAM_A0MR, &dummy)) return 10; - if (c4_peek(card, DC21285_DRAM_A1MR, &dummy)) return 11; - if (c4_peek(card, DC21285_DRAM_A2MR, &dummy)) return 12; - if (c4_peek(card, DC21285_DRAM_A3MR, &dummy)) return 13; - - if (c4_poke(card, DC21285_DRAM_A0MR + CAS_OFFSET, 0)) return 14; - if (c4_poke(card, DC21285_DRAM_A1MR + CAS_OFFSET, 0)) return 15; - if (c4_poke(card, DC21285_DRAM_A2MR + CAS_OFFSET, 0)) return 16; - if (c4_poke(card, DC21285_DRAM_A3MR + CAS_OFFSET, 0)) return 17; - - mdelay(1); - - if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_TIMING, DRAM_TIMING_DEF)) - return 18; - - if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_ADDR_SIZE_0, DRAM_AD_SZ_DEF0)) - return 19; - if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_ADDR_SIZE_1, DRAM_AD_SZ_NULL)) - return 20; - if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_ADDR_SIZE_2, DRAM_AD_SZ_NULL)) - return 21; - if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_ADDR_SIZE_3, DRAM_AD_SZ_NULL)) - return 22; - - /* Transputer test */ - - if (c4_poke(card, 0x000000, 0x11111111) - || c4_poke(card, 0x400000, 0x22222222) - || c4_poke(card, 0x800000, 0x33333333) - || c4_poke(card, 0xC00000, 0x44444444)) - return 23; - - if (c4_peek(card, 0x000000, &dummy) || dummy != 0x11111111 - || c4_peek(card, 0x400000, &dummy) || dummy != 0x22222222 - || c4_peek(card, 0x800000, &dummy) || dummy != 0x33333333 - || c4_peek(card, 0xC00000, &dummy) || dummy != 0x44444444) - return 24; - - if (c4_poke(card, 0x000000, 0x55555555) - || c4_poke(card, 0x400000, 0x66666666) - || c4_poke(card, 0x800000, 0x77777777) - || c4_poke(card, 0xC00000, 0x88888888)) - return 25; - - if (c4_peek(card, 0x000000, &dummy) || dummy != 0x55555555 - || c4_peek(card, 0x400000, &dummy) || dummy != 0x66666666 - || c4_peek(card, 0x800000, &dummy) || dummy != 0x77777777 - || c4_peek(card, 0xC00000, &dummy) || dummy != 0x88888888) - return 26; - - return 0; -} - -/* ------------------------------------------------------------- */ - -static void c4_dispatch_tx(avmcard *card) -{ - avmcard_dmainfo *dma = card->dma; - struct sk_buff *skb; - u8 cmd, subcmd; - u16 len; - u32 txlen; - void *p; - - - if (card->csr & DBELL_DOWN_ARM) { /* tx busy */ - return; - } - - skb = skb_dequeue(&dma->send_queue); - if (!skb) { -#ifdef AVM_C4_DEBUG - printk(KERN_DEBUG "%s: tx underrun\n", card->name); -#endif - return; - } - - len = CAPIMSG_LEN(skb->data); - - if (len) { - cmd = CAPIMSG_COMMAND(skb->data); - subcmd = CAPIMSG_SUBCOMMAND(skb->data); - - p = dma->sendbuf.dmabuf; - - if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) { - u16 dlen = CAPIMSG_DATALEN(skb->data); - _put_byte(&p, SEND_DATA_B3_REQ); - _put_slice(&p, skb->data, len); - _put_slice(&p, skb->data + len, dlen); - } else { - _put_byte(&p, SEND_MESSAGE); - _put_slice(&p, skb->data, len); - } - txlen = (u8 *)p - (u8 *)dma->sendbuf.dmabuf; -#ifdef AVM_C4_DEBUG - printk(KERN_DEBUG "%s: tx put msg len=%d\n", card->name, txlen); -#endif - } else { - txlen = skb->len - 2; -#ifdef AVM_C4_POLLDEBUG - if (skb->data[2] == SEND_POLLACK) - printk(KERN_INFO "%s: ack to c4\n", card->name); -#endif -#ifdef AVM_C4_DEBUG - printk(KERN_DEBUG "%s: tx put 0x%x len=%d\n", - card->name, skb->data[2], txlen); -#endif - skb_copy_from_linear_data_offset(skb, 2, dma->sendbuf.dmabuf, - skb->len - 2); - } - txlen = (txlen + 3) & ~3; - - c4outmeml(card->mbase + MBOX_DOWN_ADDR, dma->sendbuf.dmaaddr); - c4outmeml(card->mbase + MBOX_DOWN_LEN, txlen); - - card->csr |= DBELL_DOWN_ARM; - - c4outmeml(card->mbase + DOORBELL, DBELL_DOWN_ARM); - - dev_kfree_skb_any(skb); -} - -/* ------------------------------------------------------------- */ - -static void queue_pollack(avmcard *card) -{ - struct sk_buff *skb; - void *p; - - skb = alloc_skb(3, GFP_ATOMIC); - if (!skb) { - printk(KERN_CRIT "%s: no memory, lost poll ack\n", - card->name); - return; - } - p = skb->data; - _put_byte(&p, 0); - _put_byte(&p, 0); - _put_byte(&p, SEND_POLLACK); - skb_put(skb, (u8 *)p - (u8 *)skb->data); - - skb_queue_tail(&card->dma->send_queue, skb); - c4_dispatch_tx(card); -} - -/* ------------------------------------------------------------- */ - -static void c4_handle_rx(avmcard *card) -{ - avmcard_dmainfo *dma = card->dma; - struct capi_ctr *ctrl; - avmctrl_info *cinfo; - struct sk_buff *skb; - void *p = dma->recvbuf.dmabuf; - u32 ApplId, MsgLen, DataB3Len, NCCI, WindowSize; - u8 b1cmd = _get_byte(&p); - u32 cidx; - - -#ifdef AVM_C4_DEBUG - printk(KERN_DEBUG "%s: rx 0x%x len=%lu\n", card->name, - b1cmd, (unsigned long)dma->recvlen); -#endif - - switch (b1cmd) { - case RECEIVE_DATA_B3_IND: - - ApplId = (unsigned) _get_word(&p); - MsgLen = _get_slice(&p, card->msgbuf); - DataB3Len = _get_slice(&p, card->databuf); - cidx = CAPIMSG_CONTROLLER(card->msgbuf)-card->cardnr; - if (cidx >= card->nlogcontr) cidx = 0; - ctrl = &card->ctrlinfo[cidx].capi_ctrl; - - if (MsgLen < 30) { /* not CAPI 64Bit */ - memset(card->msgbuf + MsgLen, 0, 30 - MsgLen); - MsgLen = 30; - CAPIMSG_SETLEN(card->msgbuf, 30); - } - if (!(skb = alloc_skb(DataB3Len + MsgLen, GFP_ATOMIC))) { - printk(KERN_ERR "%s: incoming packet dropped\n", - card->name); - } else { - skb_put_data(skb, card->msgbuf, MsgLen); - skb_put_data(skb, card->databuf, DataB3Len); - capi_ctr_handle_message(ctrl, ApplId, skb); - } - break; - - case RECEIVE_MESSAGE: - - ApplId = (unsigned) _get_word(&p); - MsgLen = _get_slice(&p, card->msgbuf); - cidx = CAPIMSG_CONTROLLER(card->msgbuf)-card->cardnr; - if (cidx >= card->nlogcontr) cidx = 0; - cinfo = &card->ctrlinfo[cidx]; - ctrl = &card->ctrlinfo[cidx].capi_ctrl; - - if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) { - printk(KERN_ERR "%s: incoming packet dropped\n", - card->name); - } else { - skb_put_data(skb, card->msgbuf, MsgLen); - if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF) - capilib_data_b3_conf(&cinfo->ncci_head, ApplId, - CAPIMSG_NCCI(skb->data), - CAPIMSG_MSGID(skb->data)); - - capi_ctr_handle_message(ctrl, ApplId, skb); - } - break; - - case RECEIVE_NEW_NCCI: - - ApplId = _get_word(&p); - NCCI = _get_word(&p); - WindowSize = _get_word(&p); - cidx = (NCCI & 0x7f) - card->cardnr; - if (cidx >= card->nlogcontr) cidx = 0; - - capilib_new_ncci(&card->ctrlinfo[cidx].ncci_head, ApplId, NCCI, WindowSize); - - break; - - case RECEIVE_FREE_NCCI: - - ApplId = _get_word(&p); - NCCI = _get_word(&p); - - if (NCCI != 0xffffffff) { - cidx = (NCCI & 0x7f) - card->cardnr; - if (cidx >= card->nlogcontr) cidx = 0; - capilib_free_ncci(&card->ctrlinfo[cidx].ncci_head, ApplId, NCCI); - } - break; - - case RECEIVE_START: -#ifdef AVM_C4_POLLDEBUG - printk(KERN_INFO "%s: poll from c4\n", card->name); -#endif - if (!suppress_pollack) - queue_pollack(card); - for (cidx = 0; cidx < card->nr_controllers; cidx++) { - ctrl = &card->ctrlinfo[cidx].capi_ctrl; - capi_ctr_resume_output(ctrl); - } - break; - - case RECEIVE_STOP: - for (cidx = 0; cidx < card->nr_controllers; cidx++) { - ctrl = &card->ctrlinfo[cidx].capi_ctrl; - capi_ctr_suspend_output(ctrl); - } - break; - - case RECEIVE_INIT: - - cidx = card->nlogcontr; - if (cidx >= card->nr_controllers) { - printk(KERN_ERR "%s: card with %d controllers ??\n", - card->name, cidx + 1); - break; - } - card->nlogcontr++; - cinfo = &card->ctrlinfo[cidx]; - ctrl = &cinfo->capi_ctrl; - cinfo->versionlen = _get_slice(&p, cinfo->versionbuf); - b1_parse_version(cinfo); - printk(KERN_INFO "%s: %s-card (%s) now active\n", - card->name, - cinfo->version[VER_CARDTYPE], - cinfo->version[VER_DRIVER]); - capi_ctr_ready(&cinfo->capi_ctrl); - break; - - case RECEIVE_TASK_READY: - ApplId = (unsigned) _get_word(&p); - MsgLen = _get_slice(&p, card->msgbuf); - card->msgbuf[MsgLen] = 0; - while (MsgLen > 0 - && (card->msgbuf[MsgLen - 1] == '\n' - || card->msgbuf[MsgLen - 1] == '\r')) { - card->msgbuf[MsgLen - 1] = 0; - MsgLen--; - } - printk(KERN_INFO "%s: task %d \"%s\" ready.\n", - card->name, ApplId, card->msgbuf); - break; - - case RECEIVE_DEBUGMSG: - MsgLen = _get_slice(&p, card->msgbuf); - card->msgbuf[MsgLen] = 0; - while (MsgLen > 0 - && (card->msgbuf[MsgLen - 1] == '\n' - || card->msgbuf[MsgLen - 1] == '\r')) { - card->msgbuf[MsgLen - 1] = 0; - MsgLen--; - } - printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf); - break; - - default: - printk(KERN_ERR "%s: c4_interrupt: 0x%x ???\n", - card->name, b1cmd); - return; - } -} - -/* ------------------------------------------------------------- */ - -static irqreturn_t c4_handle_interrupt(avmcard *card) -{ - unsigned long flags; - u32 status; - - spin_lock_irqsave(&card->lock, flags); - status = c4inmeml(card->mbase + DOORBELL); - - if (status & DBELL_RESET_HOST) { - u_int i; - c4outmeml(card->mbase + PCI_OUT_INT_MASK, 0x0c); - spin_unlock_irqrestore(&card->lock, flags); - if (card->nlogcontr == 0) - return IRQ_HANDLED; - printk(KERN_ERR "%s: unexpected reset\n", card->name); - for (i = 0; i < card->nr_controllers; i++) { - avmctrl_info *cinfo = &card->ctrlinfo[i]; - memset(cinfo->version, 0, sizeof(cinfo->version)); - spin_lock_irqsave(&card->lock, flags); - capilib_release(&cinfo->ncci_head); - spin_unlock_irqrestore(&card->lock, flags); - capi_ctr_down(&cinfo->capi_ctrl); - } - card->nlogcontr = 0; - return IRQ_HANDLED; - } - - status &= (DBELL_UP_HOST | DBELL_DOWN_HOST); - if (!status) { - spin_unlock_irqrestore(&card->lock, flags); - return IRQ_HANDLED; - } - c4outmeml(card->mbase + DOORBELL, status); - - if ((status & DBELL_UP_HOST) != 0) { - card->dma->recvlen = c4inmeml(card->mbase + MBOX_UP_LEN); - c4outmeml(card->mbase + MBOX_UP_LEN, 0); - c4_handle_rx(card); - card->dma->recvlen = 0; - c4outmeml(card->mbase + MBOX_UP_LEN, card->dma->recvbuf.size); - c4outmeml(card->mbase + DOORBELL, DBELL_UP_ARM); - } - - if ((status & DBELL_DOWN_HOST) != 0) { - card->csr &= ~DBELL_DOWN_ARM; - c4_dispatch_tx(card); - } else if (card->csr & DBELL_DOWN_HOST) { - if (c4inmeml(card->mbase + MBOX_DOWN_LEN) == 0) { - card->csr &= ~DBELL_DOWN_ARM; - c4_dispatch_tx(card); - } - } - spin_unlock_irqrestore(&card->lock, flags); - return IRQ_HANDLED; -} - -static irqreturn_t c4_interrupt(int interrupt, void *devptr) -{ - avmcard *card = devptr; - - return c4_handle_interrupt(card); -} - -/* ------------------------------------------------------------- */ - -static void c4_send_init(avmcard *card) -{ - struct sk_buff *skb; - void *p; - unsigned long flags; - - skb = alloc_skb(15, GFP_ATOMIC); - if (!skb) { - printk(KERN_CRIT "%s: no memory, lost register appl.\n", - card->name); - return; - } - p = skb->data; - _put_byte(&p, 0); - _put_byte(&p, 0); - _put_byte(&p, SEND_INIT); - _put_word(&p, CAPI_MAXAPPL); - _put_word(&p, AVM_NCCI_PER_CHANNEL * 30); - _put_word(&p, card->cardnr - 1); - skb_put(skb, (u8 *)p - (u8 *)skb->data); - - skb_queue_tail(&card->dma->send_queue, skb); - spin_lock_irqsave(&card->lock, flags); - c4_dispatch_tx(card); - spin_unlock_irqrestore(&card->lock, flags); -} - -static int queue_sendconfigword(avmcard *card, u32 val) -{ - struct sk_buff *skb; - unsigned long flags; - void *p; - - skb = alloc_skb(3 + 4, GFP_ATOMIC); - if (!skb) { - printk(KERN_CRIT "%s: no memory, send config\n", - card->name); - return -ENOMEM; - } - p = skb->data; - _put_byte(&p, 0); - _put_byte(&p, 0); - _put_byte(&p, SEND_CONFIG); - _put_word(&p, val); - skb_put(skb, (u8 *)p - (u8 *)skb->data); - - skb_queue_tail(&card->dma->send_queue, skb); - spin_lock_irqsave(&card->lock, flags); - c4_dispatch_tx(card); - spin_unlock_irqrestore(&card->lock, flags); - return 0; -} - -static int queue_sendconfig(avmcard *card, char cval[4]) -{ - struct sk_buff *skb; - unsigned long flags; - void *p; - - skb = alloc_skb(3 + 4, GFP_ATOMIC); - if (!skb) { - printk(KERN_CRIT "%s: no memory, send config\n", - card->name); - return -ENOMEM; - } - p = skb->data; - _put_byte(&p, 0); - _put_byte(&p, 0); - _put_byte(&p, SEND_CONFIG); - _put_byte(&p, cval[0]); - _put_byte(&p, cval[1]); - _put_byte(&p, cval[2]); - _put_byte(&p, cval[3]); - skb_put(skb, (u8 *)p - (u8 *)skb->data); - - skb_queue_tail(&card->dma->send_queue, skb); - - spin_lock_irqsave(&card->lock, flags); - c4_dispatch_tx(card); - spin_unlock_irqrestore(&card->lock, flags); - return 0; -} - -static int c4_send_config(avmcard *card, capiloaddatapart *config) -{ - u8 val[4]; - unsigned char *dp; - u_int left; - int retval; - - if ((retval = queue_sendconfigword(card, 1)) != 0) - return retval; - if ((retval = queue_sendconfigword(card, config->len)) != 0) - return retval; - - dp = config->data; - left = config->len; - while (left >= sizeof(u32)) { - if (config->user) { - if (copy_from_user(val, dp, sizeof(val))) - return -EFAULT; - } else { - memcpy(val, dp, sizeof(val)); - } - if ((retval = queue_sendconfig(card, val)) != 0) - return retval; - left -= sizeof(val); - dp += sizeof(val); - } - if (left) { - memset(val, 0, sizeof(val)); - if (config->user) { - if (copy_from_user(&val, dp, left)) - return -EFAULT; - } else { - memcpy(&val, dp, left); - } - if ((retval = queue_sendconfig(card, val)) != 0) - return retval; - } - - return 0; -} - -static int c4_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - avmcard *card = cinfo->card; - int retval; - - if ((retval = c4_load_t4file(card, &data->firmware))) { - printk(KERN_ERR "%s: failed to load t4file!!\n", - card->name); - c4_reset(card); - return retval; - } - - card->csr = 0; - c4outmeml(card->mbase + MBOX_UP_LEN, 0); - c4outmeml(card->mbase + MBOX_DOWN_LEN, 0); - c4outmeml(card->mbase + DOORBELL, DBELL_INIT); - mdelay(1); - c4outmeml(card->mbase + DOORBELL, - DBELL_UP_HOST | DBELL_DOWN_HOST | DBELL_RESET_HOST); - - c4outmeml(card->mbase + PCI_OUT_INT_MASK, 0x08); - - card->dma->recvlen = 0; - c4outmeml(card->mbase + MBOX_UP_ADDR, card->dma->recvbuf.dmaaddr); - c4outmeml(card->mbase + MBOX_UP_LEN, card->dma->recvbuf.size); - c4outmeml(card->mbase + DOORBELL, DBELL_UP_ARM); - - if (data->configuration.len > 0 && data->configuration.data) { - retval = c4_send_config(card, &data->configuration); - if (retval) { - printk(KERN_ERR "%s: failed to set config!!\n", - card->name); - c4_reset(card); - return retval; - } - } - - c4_send_init(card); - - return 0; -} - - -static void c4_reset_ctr(struct capi_ctr *ctrl) -{ - avmcard *card = ((avmctrl_info *)(ctrl->driverdata))->card; - avmctrl_info *cinfo; - u_int i; - unsigned long flags; - - spin_lock_irqsave(&card->lock, flags); - - c4_reset(card); - - spin_unlock_irqrestore(&card->lock, flags); - - for (i = 0; i < card->nr_controllers; i++) { - cinfo = &card->ctrlinfo[i]; - memset(cinfo->version, 0, sizeof(cinfo->version)); - capi_ctr_down(&cinfo->capi_ctrl); - } - card->nlogcontr = 0; -} - -static void c4_remove(struct pci_dev *pdev) -{ - avmcard *card = pci_get_drvdata(pdev); - avmctrl_info *cinfo; - u_int i; - - if (!card) - return; - - c4_reset(card); - - for (i = 0; i < card->nr_controllers; i++) { - cinfo = &card->ctrlinfo[i]; - detach_capi_ctr(&cinfo->capi_ctrl); - } - - free_irq(card->irq, card); - iounmap(card->mbase); - release_region(card->port, AVMB1_PORTLEN); - avmcard_dma_free(card->dma); - pci_set_drvdata(pdev, NULL); - b1_free_card(card); -} - -/* ------------------------------------------------------------- */ - - -static void c4_register_appl(struct capi_ctr *ctrl, - u16 appl, - capi_register_params *rp) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - avmcard *card = cinfo->card; - struct sk_buff *skb; - int want = rp->level3cnt; - unsigned long flags; - int nconn; - void *p; - - if (ctrl->cnr == card->cardnr) { - - if (want > 0) nconn = want; - else nconn = ctrl->profile.nbchannel * 4 * -want; - if (nconn == 0) nconn = ctrl->profile.nbchannel * 4; - - skb = alloc_skb(23, GFP_ATOMIC); - if (!skb) { - printk(KERN_CRIT "%s: no memory, lost register appl.\n", - card->name); - return; - } - p = skb->data; - _put_byte(&p, 0); - _put_byte(&p, 0); - _put_byte(&p, SEND_REGISTER); - _put_word(&p, appl); - _put_word(&p, 1024 * (nconn + 1)); - _put_word(&p, nconn); - _put_word(&p, rp->datablkcnt); - _put_word(&p, rp->datablklen); - skb_put(skb, (u8 *)p - (u8 *)skb->data); - - skb_queue_tail(&card->dma->send_queue, skb); - - spin_lock_irqsave(&card->lock, flags); - c4_dispatch_tx(card); - spin_unlock_irqrestore(&card->lock, flags); - } -} - -/* ------------------------------------------------------------- */ - -static void c4_release_appl(struct capi_ctr *ctrl, u16 appl) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - avmcard *card = cinfo->card; - unsigned long flags; - struct sk_buff *skb; - void *p; - - spin_lock_irqsave(&card->lock, flags); - capilib_release_appl(&cinfo->ncci_head, appl); - spin_unlock_irqrestore(&card->lock, flags); - - if (ctrl->cnr == card->cardnr) { - skb = alloc_skb(7, GFP_ATOMIC); - if (!skb) { - printk(KERN_CRIT "%s: no memory, lost release appl.\n", - card->name); - return; - } - p = skb->data; - _put_byte(&p, 0); - _put_byte(&p, 0); - _put_byte(&p, SEND_RELEASE); - _put_word(&p, appl); - - skb_put(skb, (u8 *)p - (u8 *)skb->data); - skb_queue_tail(&card->dma->send_queue, skb); - spin_lock_irqsave(&card->lock, flags); - c4_dispatch_tx(card); - spin_unlock_irqrestore(&card->lock, flags); - } -} - -/* ------------------------------------------------------------- */ - - -static u16 c4_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - avmcard *card = cinfo->card; - u16 retval = CAPI_NOERROR; - unsigned long flags; - - spin_lock_irqsave(&card->lock, flags); - if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) { - retval = capilib_data_b3_req(&cinfo->ncci_head, - CAPIMSG_APPID(skb->data), - CAPIMSG_NCCI(skb->data), - CAPIMSG_MSGID(skb->data)); - } - if (retval == CAPI_NOERROR) { - skb_queue_tail(&card->dma->send_queue, skb); - c4_dispatch_tx(card); - } - spin_unlock_irqrestore(&card->lock, flags); - return retval; -} - -/* ------------------------------------------------------------- */ - -static char *c4_procinfo(struct capi_ctr *ctrl) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - - if (!cinfo) - return ""; - sprintf(cinfo->infobuf, "%s %s 0x%x %d 0x%lx", - cinfo->cardname[0] ? cinfo->cardname : "-", - cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-", - cinfo->card ? cinfo->card->port : 0x0, - cinfo->card ? cinfo->card->irq : 0, - cinfo->card ? cinfo->card->membase : 0 - ); - return cinfo->infobuf; -} - -static int c4_proc_show(struct seq_file *m, void *v) -{ - struct capi_ctr *ctrl = m->private; - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - avmcard *card = cinfo->card; - u8 flag; - char *s; - - seq_printf(m, "%-16s %s\n", "name", card->name); - seq_printf(m, "%-16s 0x%x\n", "io", card->port); - seq_printf(m, "%-16s %d\n", "irq", card->irq); - seq_printf(m, "%-16s 0x%lx\n", "membase", card->membase); - switch (card->cardtype) { - case avm_b1isa: s = "B1 ISA"; break; - case avm_b1pci: s = "B1 PCI"; break; - case avm_b1pcmcia: s = "B1 PCMCIA"; break; - case avm_m1: s = "M1"; break; - case avm_m2: s = "M2"; break; - case avm_t1isa: s = "T1 ISA (HEMA)"; break; - case avm_t1pci: s = "T1 PCI"; break; - case avm_c4: s = "C4"; break; - case avm_c2: s = "C2"; break; - default: s = "???"; break; - } - seq_printf(m, "%-16s %s\n", "type", s); - if ((s = cinfo->version[VER_DRIVER]) != NULL) - seq_printf(m, "%-16s %s\n", "ver_driver", s); - if ((s = cinfo->version[VER_CARDTYPE]) != NULL) - seq_printf(m, "%-16s %s\n", "ver_cardtype", s); - if ((s = cinfo->version[VER_SERIAL]) != NULL) - seq_printf(m, "%-16s %s\n", "ver_serial", s); - - if (card->cardtype != avm_m1) { - flag = ((u8 *)(ctrl->profile.manu))[3]; - if (flag) - seq_printf(m, "%-16s%s%s%s%s%s%s%s\n", - "protocol", - (flag & 0x01) ? " DSS1" : "", - (flag & 0x02) ? " CT1" : "", - (flag & 0x04) ? " VN3" : "", - (flag & 0x08) ? " NI1" : "", - (flag & 0x10) ? " AUSTEL" : "", - (flag & 0x20) ? " ESS" : "", - (flag & 0x40) ? " 1TR6" : "" - ); - } - if (card->cardtype != avm_m1) { - flag = ((u8 *)(ctrl->profile.manu))[5]; - if (flag) - seq_printf(m, "%-16s%s%s%s%s\n", - "linetype", - (flag & 0x01) ? " point to point" : "", - (flag & 0x02) ? " point to multipoint" : "", - (flag & 0x08) ? " leased line without D-channel" : "", - (flag & 0x04) ? " leased line with D-channel" : "" - ); - } - seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname); - - return 0; -} - -/* ------------------------------------------------------------- */ - -static int c4_add_card(struct capicardparams *p, struct pci_dev *dev, - int nr_controllers) -{ - avmcard *card; - avmctrl_info *cinfo; - int retval; - int i; - - card = b1_alloc_card(nr_controllers); - if (!card) { - printk(KERN_WARNING "c4: no memory.\n"); - retval = -ENOMEM; - goto err; - } - card->dma = avmcard_dma_alloc("c4", dev, 2048 + 128, 2048 + 128); - if (!card->dma) { - printk(KERN_WARNING "c4: no memory.\n"); - retval = -ENOMEM; - goto err_free; - } - - sprintf(card->name, "c%d-%x", nr_controllers, p->port); - card->port = p->port; - card->irq = p->irq; - card->membase = p->membase; - card->cardtype = (nr_controllers == 4) ? avm_c4 : avm_c2; - - if (!request_region(card->port, AVMB1_PORTLEN, card->name)) { - printk(KERN_WARNING "c4: ports 0x%03x-0x%03x in use.\n", - card->port, card->port + AVMB1_PORTLEN); - retval = -EBUSY; - goto err_free_dma; - } - - card->mbase = ioremap(card->membase, 128); - if (card->mbase == NULL) { - printk(KERN_NOTICE "c4: can't remap memory at 0x%lx\n", - card->membase); - retval = -EIO; - goto err_release_region; - } - - retval = c4_detect(card); - if (retval != 0) { - printk(KERN_NOTICE "c4: NO card at 0x%x error(%d)\n", - card->port, retval); - retval = -EIO; - goto err_unmap; - } - c4_reset(card); - - retval = request_irq(card->irq, c4_interrupt, IRQF_SHARED, card->name, card); - if (retval) { - printk(KERN_ERR "c4: unable to get IRQ %d.\n", card->irq); - retval = -EBUSY; - goto err_unmap; - } - - for (i = 0; i < nr_controllers; i++) { - cinfo = &card->ctrlinfo[i]; - cinfo->capi_ctrl.owner = THIS_MODULE; - cinfo->capi_ctrl.driver_name = "c4"; - cinfo->capi_ctrl.driverdata = cinfo; - cinfo->capi_ctrl.register_appl = c4_register_appl; - cinfo->capi_ctrl.release_appl = c4_release_appl; - cinfo->capi_ctrl.send_message = c4_send_message; - cinfo->capi_ctrl.load_firmware = c4_load_firmware; - cinfo->capi_ctrl.reset_ctr = c4_reset_ctr; - cinfo->capi_ctrl.procinfo = c4_procinfo; - cinfo->capi_ctrl.proc_show = c4_proc_show; - strcpy(cinfo->capi_ctrl.name, card->name); - - retval = attach_capi_ctr(&cinfo->capi_ctrl); - if (retval) { - printk(KERN_ERR "c4: attach controller failed (%d).\n", i); - for (i--; i >= 0; i--) { - cinfo = &card->ctrlinfo[i]; - detach_capi_ctr(&cinfo->capi_ctrl); - } - goto err_free_irq; - } - if (i == 0) - card->cardnr = cinfo->capi_ctrl.cnr; - } - - printk(KERN_INFO "c4: AVM C%d at i/o %#x, irq %d, mem %#lx\n", - nr_controllers, card->port, card->irq, - card->membase); - pci_set_drvdata(dev, card); - return 0; - -err_free_irq: - free_irq(card->irq, card); -err_unmap: - iounmap(card->mbase); -err_release_region: - release_region(card->port, AVMB1_PORTLEN); -err_free_dma: - avmcard_dma_free(card->dma); -err_free: - b1_free_card(card); -err: - return retval; -} - -/* ------------------------------------------------------------- */ - -static int c4_probe(struct pci_dev *dev, const struct pci_device_id *ent) -{ - int nr = ent->driver_data; - int retval = 0; - struct capicardparams param; - - if (pci_enable_device(dev) < 0) { - printk(KERN_ERR "c4: failed to enable AVM-C%d\n", nr); - return -ENODEV; - } - pci_set_master(dev); - - param.port = pci_resource_start(dev, 1); - param.irq = dev->irq; - param.membase = pci_resource_start(dev, 0); - - printk(KERN_INFO "c4: PCI BIOS reports AVM-C%d at i/o %#x, irq %d, mem %#x\n", - nr, param.port, param.irq, param.membase); - - retval = c4_add_card(¶m, dev, nr); - if (retval != 0) { - printk(KERN_ERR "c4: no AVM-C%d at i/o %#x, irq %d detected, mem %#x\n", - nr, param.port, param.irq, param.membase); - pci_disable_device(dev); - return -ENODEV; - } - return 0; -} - -static struct pci_driver c4_pci_driver = { - .name = "c4", - .id_table = c4_pci_tbl, - .probe = c4_probe, - .remove = c4_remove, -}; - -static struct capi_driver capi_driver_c2 = { - .name = "c2", - .revision = "1.0", -}; - -static struct capi_driver capi_driver_c4 = { - .name = "c4", - .revision = "1.0", -}; - -static int __init c4_init(void) -{ - char *p; - char rev[32]; - int err; - - if ((p = strchr(revision, ':')) != NULL && p[1]) { - strlcpy(rev, p + 2, 32); - if ((p = strchr(rev, '$')) != NULL && p > rev) - *(p - 1) = 0; - } else - strcpy(rev, "1.0"); - - err = pci_register_driver(&c4_pci_driver); - if (!err) { - strlcpy(capi_driver_c2.revision, rev, 32); - register_capi_driver(&capi_driver_c2); - strlcpy(capi_driver_c4.revision, rev, 32); - register_capi_driver(&capi_driver_c4); - printk(KERN_INFO "c4: revision %s\n", rev); - } - return err; -} - -static void __exit c4_exit(void) -{ - unregister_capi_driver(&capi_driver_c2); - unregister_capi_driver(&capi_driver_c4); - pci_unregister_driver(&c4_pci_driver); -} - -module_init(c4_init); -module_exit(c4_exit); diff --git a/drivers/isdn/hardware/avm/t1isa.c b/drivers/isdn/hardware/avm/t1isa.c deleted file mode 100644 index 2153619c5b31..000000000000 --- a/drivers/isdn/hardware/avm/t1isa.c +++ /dev/null @@ -1,594 +0,0 @@ -/* $Id: t1isa.c,v 1.1.2.3 2004/02/10 01:07:12 keil Exp $ - * - * Module for AVM T1 HEMA-card. - * - * Copyright 1999 by Carsten Paeth <calle@calle.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/skbuff.h> -#include <linux/delay.h> -#include <linux/mm.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/capi.h> -#include <linux/netdevice.h> -#include <linux/kernelcapi.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <linux/gfp.h> -#include <asm/io.h> -#include <linux/isdn/capicmd.h> -#include <linux/isdn/capiutil.h> -#include <linux/isdn/capilli.h> -#include "avmcard.h" - -/* ------------------------------------------------------------- */ - -static char *revision = "$Revision: 1.1.2.3 $"; - -/* ------------------------------------------------------------- */ - -MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM T1 HEMA ISA card"); -MODULE_AUTHOR("Carsten Paeth"); -MODULE_LICENSE("GPL"); - -/* ------------------------------------------------------------- */ - -static int hema_irq_table[16] = -{0, - 0, - 0, - 0x80, /* irq 3 */ - 0, - 0x90, /* irq 5 */ - 0, - 0xA0, /* irq 7 */ - 0, - 0xB0, /* irq 9 */ - 0xC0, /* irq 10 */ - 0xD0, /* irq 11 */ - 0xE0, /* irq 12 */ - 0, - 0, - 0xF0, /* irq 15 */ -}; - -static int t1_detectandinit(unsigned int base, unsigned irq, int cardnr) -{ - unsigned char cregs[8]; - unsigned char reverse_cardnr; - unsigned char dummy; - int i; - - reverse_cardnr = ((cardnr & 0x01) << 3) | ((cardnr & 0x02) << 1) - | ((cardnr & 0x04) >> 1) | ((cardnr & 0x08) >> 3); - cregs[0] = (HEMA_VERSION_ID << 4) | (reverse_cardnr & 0xf); - cregs[1] = 0x00; /* fast & slow link connected to CON1 */ - cregs[2] = 0x05; /* fast link 20MBit, slow link 20 MBit */ - cregs[3] = 0; - cregs[4] = 0x11; /* zero wait state */ - cregs[5] = hema_irq_table[irq & 0xf]; - cregs[6] = 0; - cregs[7] = 0; - - /* - * no one else should use the ISA bus in this moment, - * but no function there to prevent this :-( - * save_flags(flags); cli(); - */ - - /* board reset */ - t1outp(base, T1_RESETBOARD, 0xf); - mdelay(100); - dummy = t1inp(base, T1_FASTLINK + T1_OUTSTAT); /* first read */ - - /* write config */ - dummy = (base >> 4) & 0xff; - for (i = 1; i <= 0xf; i++) t1outp(base, i, dummy); - t1outp(base, HEMA_PAL_ID & 0xf, dummy); - t1outp(base, HEMA_PAL_ID >> 4, cregs[0]); - for (i = 1; i < 7; i++) t1outp(base, 0, cregs[i]); - t1outp(base, ((base >> 4)) & 0x3, cregs[7]); - /* restore_flags(flags); */ - - mdelay(100); - t1outp(base, T1_FASTLINK + T1_RESETLINK, 0); - t1outp(base, T1_SLOWLINK + T1_RESETLINK, 0); - mdelay(10); - t1outp(base, T1_FASTLINK + T1_RESETLINK, 1); - t1outp(base, T1_SLOWLINK + T1_RESETLINK, 1); - mdelay(100); - t1outp(base, T1_FASTLINK + T1_RESETLINK, 0); - t1outp(base, T1_SLOWLINK + T1_RESETLINK, 0); - mdelay(10); - t1outp(base, T1_FASTLINK + T1_ANALYSE, 0); - mdelay(5); - t1outp(base, T1_SLOWLINK + T1_ANALYSE, 0); - - if (t1inp(base, T1_FASTLINK + T1_OUTSTAT) != 0x1) /* tx empty */ - return 1; - if (t1inp(base, T1_FASTLINK + T1_INSTAT) != 0x0) /* rx empty */ - return 2; - if (t1inp(base, T1_FASTLINK + T1_IRQENABLE) != 0x0) - return 3; - if ((t1inp(base, T1_FASTLINK + T1_FIFOSTAT) & 0xf0) != 0x70) - return 4; - if ((t1inp(base, T1_FASTLINK + T1_IRQMASTER) & 0x0e) != 0) - return 5; - if ((t1inp(base, T1_FASTLINK + T1_IDENT) & 0x7d) != 1) - return 6; - if (t1inp(base, T1_SLOWLINK + T1_OUTSTAT) != 0x1) /* tx empty */ - return 7; - if ((t1inp(base, T1_SLOWLINK + T1_IRQMASTER) & 0x0e) != 0) - return 8; - if ((t1inp(base, T1_SLOWLINK + T1_IDENT) & 0x7d) != 0) - return 9; - return 0; -} - -static irqreturn_t t1isa_interrupt(int interrupt, void *devptr) -{ - avmcard *card = devptr; - avmctrl_info *cinfo = &card->ctrlinfo[0]; - struct capi_ctr *ctrl = &cinfo->capi_ctrl; - unsigned char b1cmd; - struct sk_buff *skb; - - unsigned ApplId; - unsigned MsgLen; - unsigned DataB3Len; - unsigned NCCI; - unsigned WindowSize; - unsigned long flags; - - spin_lock_irqsave(&card->lock, flags); - - while (b1_rx_full(card->port)) { - - b1cmd = b1_get_byte(card->port); - - switch (b1cmd) { - - case RECEIVE_DATA_B3_IND: - - ApplId = (unsigned) b1_get_word(card->port); - MsgLen = t1_get_slice(card->port, card->msgbuf); - DataB3Len = t1_get_slice(card->port, card->databuf); - spin_unlock_irqrestore(&card->lock, flags); - - if (MsgLen < 30) { /* not CAPI 64Bit */ - memset(card->msgbuf + MsgLen, 0, 30 - MsgLen); - MsgLen = 30; - CAPIMSG_SETLEN(card->msgbuf, 30); - } - if (!(skb = alloc_skb(DataB3Len + MsgLen, GFP_ATOMIC))) { - printk(KERN_ERR "%s: incoming packet dropped\n", - card->name); - } else { - skb_put_data(skb, card->msgbuf, MsgLen); - skb_put_data(skb, card->databuf, DataB3Len); - capi_ctr_handle_message(ctrl, ApplId, skb); - } - break; - - case RECEIVE_MESSAGE: - - ApplId = (unsigned) b1_get_word(card->port); - MsgLen = t1_get_slice(card->port, card->msgbuf); - if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) { - spin_unlock_irqrestore(&card->lock, flags); - printk(KERN_ERR "%s: incoming packet dropped\n", - card->name); - } else { - skb_put_data(skb, card->msgbuf, MsgLen); - if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3) - capilib_data_b3_conf(&cinfo->ncci_head, ApplId, - CAPIMSG_NCCI(skb->data), - CAPIMSG_MSGID(skb->data)); - spin_unlock_irqrestore(&card->lock, flags); - capi_ctr_handle_message(ctrl, ApplId, skb); - } - break; - - case RECEIVE_NEW_NCCI: - - ApplId = b1_get_word(card->port); - NCCI = b1_get_word(card->port); - WindowSize = b1_get_word(card->port); - capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize); - spin_unlock_irqrestore(&card->lock, flags); - break; - - case RECEIVE_FREE_NCCI: - - ApplId = b1_get_word(card->port); - NCCI = b1_get_word(card->port); - if (NCCI != 0xffffffff) - capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI); - spin_unlock_irqrestore(&card->lock, flags); - break; - - case RECEIVE_START: - b1_put_byte(card->port, SEND_POLLACK); - spin_unlock_irqrestore(&card->lock, flags); - capi_ctr_resume_output(ctrl); - break; - - case RECEIVE_STOP: - spin_unlock_irqrestore(&card->lock, flags); - capi_ctr_suspend_output(ctrl); - break; - - case RECEIVE_INIT: - - cinfo->versionlen = t1_get_slice(card->port, cinfo->versionbuf); - spin_unlock_irqrestore(&card->lock, flags); - b1_parse_version(cinfo); - printk(KERN_INFO "%s: %s-card (%s) now active\n", - card->name, - cinfo->version[VER_CARDTYPE], - cinfo->version[VER_DRIVER]); - capi_ctr_ready(ctrl); - break; - - case RECEIVE_TASK_READY: - ApplId = (unsigned) b1_get_word(card->port); - MsgLen = t1_get_slice(card->port, card->msgbuf); - spin_unlock_irqrestore(&card->lock, flags); - card->msgbuf[MsgLen] = 0; - while (MsgLen > 0 - && (card->msgbuf[MsgLen - 1] == '\n' - || card->msgbuf[MsgLen - 1] == '\r')) { - card->msgbuf[MsgLen - 1] = 0; - MsgLen--; - } - printk(KERN_INFO "%s: task %d \"%s\" ready.\n", - card->name, ApplId, card->msgbuf); - break; - - case RECEIVE_DEBUGMSG: - MsgLen = t1_get_slice(card->port, card->msgbuf); - spin_unlock_irqrestore(&card->lock, flags); - card->msgbuf[MsgLen] = 0; - while (MsgLen > 0 - && (card->msgbuf[MsgLen - 1] == '\n' - || card->msgbuf[MsgLen - 1] == '\r')) { - card->msgbuf[MsgLen - 1] = 0; - MsgLen--; - } - printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf); - break; - - - case 0xff: - spin_unlock_irqrestore(&card->lock, flags); - printk(KERN_ERR "%s: card reseted ?\n", card->name); - return IRQ_HANDLED; - default: - spin_unlock_irqrestore(&card->lock, flags); - printk(KERN_ERR "%s: b1_interrupt: 0x%x ???\n", - card->name, b1cmd); - return IRQ_NONE; - } - } - return IRQ_HANDLED; -} - -/* ------------------------------------------------------------- */ - -static int t1isa_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - avmcard *card = cinfo->card; - unsigned int port = card->port; - unsigned long flags; - int retval; - - t1_disable_irq(port); - b1_reset(port); - - if ((retval = b1_load_t4file(card, &data->firmware))) { - b1_reset(port); - printk(KERN_ERR "%s: failed to load t4file!!\n", - card->name); - return retval; - } - - if (data->configuration.len > 0 && data->configuration.data) { - if ((retval = b1_load_config(card, &data->configuration))) { - b1_reset(port); - printk(KERN_ERR "%s: failed to load config!!\n", - card->name); - return retval; - } - } - - if (!b1_loaded(card)) { - printk(KERN_ERR "%s: failed to load t4file.\n", card->name); - return -EIO; - } - - spin_lock_irqsave(&card->lock, flags); - b1_setinterrupt(port, card->irq, card->cardtype); - b1_put_byte(port, SEND_INIT); - b1_put_word(port, CAPI_MAXAPPL); - b1_put_word(port, AVM_NCCI_PER_CHANNEL * 30); - b1_put_word(port, ctrl->cnr - 1); - spin_unlock_irqrestore(&card->lock, flags); - - return 0; -} - -static void t1isa_reset_ctr(struct capi_ctr *ctrl) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - avmcard *card = cinfo->card; - unsigned int port = card->port; - unsigned long flags; - - t1_disable_irq(port); - b1_reset(port); - b1_reset(port); - - memset(cinfo->version, 0, sizeof(cinfo->version)); - spin_lock_irqsave(&card->lock, flags); - capilib_release(&cinfo->ncci_head); - spin_unlock_irqrestore(&card->lock, flags); - capi_ctr_down(ctrl); -} - -static void t1isa_remove(struct pci_dev *pdev) -{ - avmctrl_info *cinfo = pci_get_drvdata(pdev); - avmcard *card; - - if (!cinfo) - return; - - card = cinfo->card; - - t1_disable_irq(card->port); - b1_reset(card->port); - b1_reset(card->port); - t1_reset(card->port); - - detach_capi_ctr(&cinfo->capi_ctrl); - free_irq(card->irq, card); - release_region(card->port, AVMB1_PORTLEN); - b1_free_card(card); -} - -/* ------------------------------------------------------------- */ - -static u16 t1isa_send_message(struct capi_ctr *ctrl, struct sk_buff *skb); -static char *t1isa_procinfo(struct capi_ctr *ctrl); - -static int t1isa_probe(struct pci_dev *pdev, int cardnr) -{ - avmctrl_info *cinfo; - avmcard *card; - int retval; - - card = b1_alloc_card(1); - if (!card) { - printk(KERN_WARNING "t1isa: no memory.\n"); - retval = -ENOMEM; - goto err; - } - - cinfo = card->ctrlinfo; - card->port = pci_resource_start(pdev, 0); - card->irq = pdev->irq; - card->cardtype = avm_t1isa; - card->cardnr = cardnr; - sprintf(card->name, "t1isa-%x", card->port); - - if (!(((card->port & 0x7) == 0) && ((card->port & 0x30) != 0x30))) { - printk(KERN_WARNING "t1isa: invalid port 0x%x.\n", card->port); - retval = -EINVAL; - goto err_free; - } - if (hema_irq_table[card->irq & 0xf] == 0) { - printk(KERN_WARNING "t1isa: irq %d not valid.\n", card->irq); - retval = -EINVAL; - goto err_free; - } - if (!request_region(card->port, AVMB1_PORTLEN, card->name)) { - printk(KERN_INFO "t1isa: ports 0x%03x-0x%03x in use.\n", - card->port, card->port + AVMB1_PORTLEN); - retval = -EBUSY; - goto err_free; - } - retval = request_irq(card->irq, t1isa_interrupt, 0, card->name, card); - if (retval) { - printk(KERN_INFO "t1isa: unable to get IRQ %d.\n", card->irq); - retval = -EBUSY; - goto err_release_region; - } - - if ((retval = t1_detectandinit(card->port, card->irq, card->cardnr)) != 0) { - printk(KERN_INFO "t1isa: NO card at 0x%x (%d)\n", - card->port, retval); - retval = -ENODEV; - goto err_free_irq; - } - t1_disable_irq(card->port); - b1_reset(card->port); - - cinfo->capi_ctrl.owner = THIS_MODULE; - cinfo->capi_ctrl.driver_name = "t1isa"; - cinfo->capi_ctrl.driverdata = cinfo; - cinfo->capi_ctrl.register_appl = b1_register_appl; - cinfo->capi_ctrl.release_appl = b1_release_appl; - cinfo->capi_ctrl.send_message = t1isa_send_message; - cinfo->capi_ctrl.load_firmware = t1isa_load_firmware; - cinfo->capi_ctrl.reset_ctr = t1isa_reset_ctr; - cinfo->capi_ctrl.procinfo = t1isa_procinfo; - cinfo->capi_ctrl.proc_show = b1_proc_show; - strcpy(cinfo->capi_ctrl.name, card->name); - - retval = attach_capi_ctr(&cinfo->capi_ctrl); - if (retval) { - printk(KERN_INFO "t1isa: attach controller failed.\n"); - goto err_free_irq; - } - - printk(KERN_INFO "t1isa: AVM T1 ISA at i/o %#x, irq %d, card %d\n", - card->port, card->irq, card->cardnr); - - pci_set_drvdata(pdev, cinfo); - return 0; - -err_free_irq: - free_irq(card->irq, card); -err_release_region: - release_region(card->port, AVMB1_PORTLEN); -err_free: - b1_free_card(card); -err: - return retval; -} - -static u16 t1isa_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - avmcard *card = cinfo->card; - unsigned int port = card->port; - unsigned long flags; - u16 len = CAPIMSG_LEN(skb->data); - u8 cmd = CAPIMSG_COMMAND(skb->data); - u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data); - u16 dlen, retval; - - spin_lock_irqsave(&card->lock, flags); - if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) { - retval = capilib_data_b3_req(&cinfo->ncci_head, - CAPIMSG_APPID(skb->data), - CAPIMSG_NCCI(skb->data), - CAPIMSG_MSGID(skb->data)); - if (retval != CAPI_NOERROR) { - spin_unlock_irqrestore(&card->lock, flags); - return retval; - } - dlen = CAPIMSG_DATALEN(skb->data); - - b1_put_byte(port, SEND_DATA_B3_REQ); - t1_put_slice(port, skb->data, len); - t1_put_slice(port, skb->data + len, dlen); - } else { - b1_put_byte(port, SEND_MESSAGE); - t1_put_slice(port, skb->data, len); - } - spin_unlock_irqrestore(&card->lock, flags); - dev_kfree_skb_any(skb); - return CAPI_NOERROR; -} -/* ------------------------------------------------------------- */ - -static char *t1isa_procinfo(struct capi_ctr *ctrl) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - - if (!cinfo) - return ""; - sprintf(cinfo->infobuf, "%s %s 0x%x %d %d", - cinfo->cardname[0] ? cinfo->cardname : "-", - cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-", - cinfo->card ? cinfo->card->port : 0x0, - cinfo->card ? cinfo->card->irq : 0, - cinfo->card ? cinfo->card->cardnr : 0 - ); - return cinfo->infobuf; -} - - -/* ------------------------------------------------------------- */ - -#define MAX_CARDS 4 -static struct pci_dev isa_dev[MAX_CARDS]; -static int io[MAX_CARDS]; -static int irq[MAX_CARDS]; -static int cardnr[MAX_CARDS]; - -module_param_hw_array(io, int, ioport, NULL, 0); -module_param_hw_array(irq, int, irq, NULL, 0); -module_param_array(cardnr, int, NULL, 0); -MODULE_PARM_DESC(io, "I/O base address(es)"); -MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)"); -MODULE_PARM_DESC(cardnr, "Card number(s) (as jumpered)"); - -static int t1isa_add_card(struct capi_driver *driver, capicardparams *data) -{ - int i; - - for (i = 0; i < MAX_CARDS; i++) { - if (isa_dev[i].resource[0].start) - continue; - - isa_dev[i].resource[0].start = data->port; - isa_dev[i].irq = data->irq; - - if (t1isa_probe(&isa_dev[i], data->cardnr) == 0) - return 0; - } - return -ENODEV; -} - -static struct capi_driver capi_driver_t1isa = { - .name = "t1isa", - .revision = "1.0", - .add_card = t1isa_add_card, -}; - -static int __init t1isa_init(void) -{ - char rev[32]; - char *p; - int i; - - if ((p = strchr(revision, ':')) != NULL && p[1]) { - strlcpy(rev, p + 2, 32); - if ((p = strchr(rev, '$')) != NULL && p > rev) - *(p - 1) = 0; - } else - strcpy(rev, "1.0"); - - for (i = 0; i < MAX_CARDS; i++) { - if (!io[i]) - break; - - isa_dev[i].resource[0].start = io[i]; - isa_dev[i].irq = irq[i]; - - if (t1isa_probe(&isa_dev[i], cardnr[i]) != 0) - return -ENODEV; - } - - strlcpy(capi_driver_t1isa.revision, rev, 32); - register_capi_driver(&capi_driver_t1isa); - printk(KERN_INFO "t1isa: revision %s\n", rev); - - return 0; -} - -static void __exit t1isa_exit(void) -{ - int i; - - unregister_capi_driver(&capi_driver_t1isa); - for (i = 0; i < MAX_CARDS; i++) { - if (!io[i]) - break; - - t1isa_remove(&isa_dev[i]); - } -} - -module_init(t1isa_init); -module_exit(t1isa_exit); diff --git a/drivers/isdn/hardware/avm/t1pci.c b/drivers/isdn/hardware/avm/t1pci.c deleted file mode 100644 index f5ed1d5004c9..000000000000 --- a/drivers/isdn/hardware/avm/t1pci.c +++ /dev/null @@ -1,259 +0,0 @@ -/* $Id: t1pci.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $ - * - * Module for AVM T1 PCI-card. - * - * Copyright 1999 by Carsten Paeth <calle@calle.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/skbuff.h> -#include <linux/delay.h> -#include <linux/mm.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/pci.h> -#include <linux/capi.h> -#include <linux/init.h> -#include <asm/io.h> -#include <linux/isdn/capicmd.h> -#include <linux/isdn/capiutil.h> -#include <linux/isdn/capilli.h> -#include "avmcard.h" - -#undef CONFIG_T1PCI_DEBUG -#undef CONFIG_T1PCI_POLLDEBUG - -/* ------------------------------------------------------------- */ -static char *revision = "$Revision: 1.1.2.2 $"; -/* ------------------------------------------------------------- */ - -static struct pci_device_id t1pci_pci_tbl[] = { - { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_T1, PCI_ANY_ID, PCI_ANY_ID }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(pci, t1pci_pci_tbl); -MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM T1 PCI card"); -MODULE_AUTHOR("Carsten Paeth"); -MODULE_LICENSE("GPL"); - -/* ------------------------------------------------------------- */ - -static char *t1pci_procinfo(struct capi_ctr *ctrl); - -static int t1pci_add_card(struct capicardparams *p, struct pci_dev *pdev) -{ - avmcard *card; - avmctrl_info *cinfo; - int retval; - - card = b1_alloc_card(1); - if (!card) { - printk(KERN_WARNING "t1pci: no memory.\n"); - retval = -ENOMEM; - goto err; - } - - card->dma = avmcard_dma_alloc("t1pci", pdev, 2048 + 128, 2048 + 128); - if (!card->dma) { - printk(KERN_WARNING "t1pci: no memory.\n"); - retval = -ENOMEM; - goto err_free; - } - - cinfo = card->ctrlinfo; - sprintf(card->name, "t1pci-%x", p->port); - card->port = p->port; - card->irq = p->irq; - card->membase = p->membase; - card->cardtype = avm_t1pci; - - if (!request_region(card->port, AVMB1_PORTLEN, card->name)) { - printk(KERN_WARNING "t1pci: ports 0x%03x-0x%03x in use.\n", - card->port, card->port + AVMB1_PORTLEN); - retval = -EBUSY; - goto err_free_dma; - } - - card->mbase = ioremap(card->membase, 64); - if (!card->mbase) { - printk(KERN_NOTICE "t1pci: can't remap memory at 0x%lx\n", - card->membase); - retval = -EIO; - goto err_release_region; - } - - b1dma_reset(card); - - retval = t1pci_detect(card); - if (retval != 0) { - if (retval < 6) - printk(KERN_NOTICE "t1pci: NO card at 0x%x (%d)\n", - card->port, retval); - else - printk(KERN_NOTICE "t1pci: card at 0x%x, but cable not connected or T1 has no power (%d)\n", - card->port, retval); - retval = -EIO; - goto err_unmap; - } - b1dma_reset(card); - - retval = request_irq(card->irq, b1dma_interrupt, IRQF_SHARED, card->name, card); - if (retval) { - printk(KERN_ERR "t1pci: unable to get IRQ %d.\n", card->irq); - retval = -EBUSY; - goto err_unmap; - } - - cinfo->capi_ctrl.owner = THIS_MODULE; - cinfo->capi_ctrl.driver_name = "t1pci"; - cinfo->capi_ctrl.driverdata = cinfo; - cinfo->capi_ctrl.register_appl = b1dma_register_appl; - cinfo->capi_ctrl.release_appl = b1dma_release_appl; - cinfo->capi_ctrl.send_message = b1dma_send_message; - cinfo->capi_ctrl.load_firmware = b1dma_load_firmware; - cinfo->capi_ctrl.reset_ctr = b1dma_reset_ctr; - cinfo->capi_ctrl.procinfo = t1pci_procinfo; - cinfo->capi_ctrl.proc_show = b1dma_proc_show; - strcpy(cinfo->capi_ctrl.name, card->name); - - retval = attach_capi_ctr(&cinfo->capi_ctrl); - if (retval) { - printk(KERN_ERR "t1pci: attach controller failed.\n"); - retval = -EBUSY; - goto err_free_irq; - } - card->cardnr = cinfo->capi_ctrl.cnr; - - printk(KERN_INFO "t1pci: AVM T1 PCI at i/o %#x, irq %d, mem %#lx\n", - card->port, card->irq, card->membase); - - pci_set_drvdata(pdev, card); - return 0; - -err_free_irq: - free_irq(card->irq, card); -err_unmap: - iounmap(card->mbase); -err_release_region: - release_region(card->port, AVMB1_PORTLEN); -err_free_dma: - avmcard_dma_free(card->dma); -err_free: - b1_free_card(card); -err: - return retval; -} - -/* ------------------------------------------------------------- */ - -static void t1pci_remove(struct pci_dev *pdev) -{ - avmcard *card = pci_get_drvdata(pdev); - avmctrl_info *cinfo = card->ctrlinfo; - - b1dma_reset(card); - - detach_capi_ctr(&cinfo->capi_ctrl); - free_irq(card->irq, card); - iounmap(card->mbase); - release_region(card->port, AVMB1_PORTLEN); - avmcard_dma_free(card->dma); - b1_free_card(card); -} - -/* ------------------------------------------------------------- */ - -static char *t1pci_procinfo(struct capi_ctr *ctrl) -{ - avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); - - if (!cinfo) - return ""; - sprintf(cinfo->infobuf, "%s %s 0x%x %d 0x%lx", - cinfo->cardname[0] ? cinfo->cardname : "-", - cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-", - cinfo->card ? cinfo->card->port : 0x0, - cinfo->card ? cinfo->card->irq : 0, - cinfo->card ? cinfo->card->membase : 0 - ); - return cinfo->infobuf; -} - -/* ------------------------------------------------------------- */ - -static int t1pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) -{ - struct capicardparams param; - int retval; - - if (pci_enable_device(dev) < 0) { - printk(KERN_ERR "t1pci: failed to enable AVM-T1-PCI\n"); - return -ENODEV; - } - pci_set_master(dev); - - param.port = pci_resource_start(dev, 1); - param.irq = dev->irq; - param.membase = pci_resource_start(dev, 0); - - printk(KERN_INFO "t1pci: PCI BIOS reports AVM-T1-PCI at i/o %#x, irq %d, mem %#x\n", - param.port, param.irq, param.membase); - - retval = t1pci_add_card(¶m, dev); - if (retval != 0) { - printk(KERN_ERR "t1pci: no AVM-T1-PCI at i/o %#x, irq %d detected, mem %#x\n", - param.port, param.irq, param.membase); - pci_disable_device(dev); - return -ENODEV; - } - return 0; -} - -static struct pci_driver t1pci_pci_driver = { - .name = "t1pci", - .id_table = t1pci_pci_tbl, - .probe = t1pci_probe, - .remove = t1pci_remove, -}; - -static struct capi_driver capi_driver_t1pci = { - .name = "t1pci", - .revision = "1.0", -}; - -static int __init t1pci_init(void) -{ - char *p; - char rev[32]; - int err; - - if ((p = strchr(revision, ':')) != NULL && p[1]) { - strlcpy(rev, p + 2, 32); - if ((p = strchr(rev, '$')) != NULL && p > rev) - *(p - 1) = 0; - } else - strcpy(rev, "1.0"); - - err = pci_register_driver(&t1pci_pci_driver); - if (!err) { - strlcpy(capi_driver_t1pci.revision, rev, 32); - register_capi_driver(&capi_driver_t1pci); - printk(KERN_INFO "t1pci: revision %s\n", rev); - } - return err; -} - -static void __exit t1pci_exit(void) -{ - unregister_capi_driver(&capi_driver_t1pci); - pci_unregister_driver(&t1pci_pci_driver); -} - -module_init(t1pci_init); -module_exit(t1pci_exit); diff --git a/drivers/isdn/hardware/mISDN/Kconfig b/drivers/isdn/hardware/mISDN/Kconfig index a7a34a85b970..304f50c08da2 100644 --- a/drivers/isdn/hardware/mISDN/Kconfig +++ b/drivers/isdn/hardware/mISDN/Kconfig @@ -79,11 +79,14 @@ config MISDN_NETJET depends on PCI depends on TTY select MISDN_IPAC - select ISDN_HDLC - select ISDN_I4L + select MISDN_HDLC help Enable support for Traverse Technologies NETJet PCI cards. +config MISDN_HDLC + tristate + select CRC_CCITT + select BITREVERSE config MISDN_IPAC tristate diff --git a/drivers/isdn/hardware/mISDN/Makefile b/drivers/isdn/hardware/mISDN/Makefile index 422f9fd8ab9a..3f50f8c4753f 100644 --- a/drivers/isdn/hardware/mISDN/Makefile +++ b/drivers/isdn/hardware/mISDN/Makefile @@ -15,3 +15,5 @@ obj-$(CONFIG_MISDN_NETJET) += netjet.o # chip modules obj-$(CONFIG_MISDN_IPAC) += mISDNipac.o obj-$(CONFIG_MISDN_ISAR) += mISDNisar.o + +obj-$(CONFIG_MISDN_HDLC) += isdnhdlc.o diff --git a/drivers/isdn/hardware/mISDN/isdnhdlc.c b/drivers/isdn/hardware/mISDN/isdnhdlc.c new file mode 100644 index 000000000000..9fea16ed3dd8 --- /dev/null +++ b/drivers/isdn/hardware/mISDN/isdnhdlc.c @@ -0,0 +1,617 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * isdnhdlc.c -- General purpose ISDN HDLC decoder. + * + * Copyright (C) + * 2009 Karsten Keil <keil@b1-systems.de> + * 2002 Wolfgang Mües <wolfgang@iksw-muees.de> + * 2001 Frode Isaksen <fisaksen@bewan.com> + * 2001 Kai Germaschewski <kai.germaschewski@gmx.de> + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/crc-ccitt.h> +#include <linux/bitrev.h> +#include "isdnhdlc.h" + +/*-------------------------------------------------------------------*/ + +MODULE_AUTHOR("Wolfgang Mües <wolfgang@iksw-muees.de>, " + "Frode Isaksen <fisaksen@bewan.com>, " + "Kai Germaschewski <kai.germaschewski@gmx.de>"); +MODULE_DESCRIPTION("General purpose ISDN HDLC decoder"); +MODULE_LICENSE("GPL"); + +/*-------------------------------------------------------------------*/ + +enum { + HDLC_FAST_IDLE, HDLC_GET_FLAG_B0, HDLC_GETFLAG_B1A6, HDLC_GETFLAG_B7, + HDLC_GET_DATA, HDLC_FAST_FLAG +}; + +enum { + HDLC_SEND_DATA, HDLC_SEND_CRC1, HDLC_SEND_FAST_FLAG, + HDLC_SEND_FIRST_FLAG, HDLC_SEND_CRC2, HDLC_SEND_CLOSING_FLAG, + HDLC_SEND_IDLE1, HDLC_SEND_FAST_IDLE, HDLC_SENDFLAG_B0, + HDLC_SENDFLAG_B1A6, HDLC_SENDFLAG_B7, STOPPED, HDLC_SENDFLAG_ONE +}; + +void isdnhdlc_rcv_init(struct isdnhdlc_vars *hdlc, u32 features) +{ + memset(hdlc, 0, sizeof(struct isdnhdlc_vars)); + hdlc->state = HDLC_GET_DATA; + if (features & HDLC_56KBIT) + hdlc->do_adapt56 = 1; + if (features & HDLC_BITREVERSE) + hdlc->do_bitreverse = 1; +} +EXPORT_SYMBOL(isdnhdlc_out_init); + +void isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, u32 features) +{ + memset(hdlc, 0, sizeof(struct isdnhdlc_vars)); + if (features & HDLC_DCHANNEL) { + hdlc->dchannel = 1; + hdlc->state = HDLC_SEND_FIRST_FLAG; + } else { + hdlc->dchannel = 0; + hdlc->state = HDLC_SEND_FAST_FLAG; + hdlc->ffvalue = 0x7e; + } + hdlc->cbin = 0x7e; + if (features & HDLC_56KBIT) { + hdlc->do_adapt56 = 1; + hdlc->state = HDLC_SENDFLAG_B0; + } else + hdlc->data_bits = 8; + if (features & HDLC_BITREVERSE) + hdlc->do_bitreverse = 1; +} +EXPORT_SYMBOL(isdnhdlc_rcv_init); + +static int +check_frame(struct isdnhdlc_vars *hdlc) +{ + int status; + + if (hdlc->dstpos < 2) /* too small - framing error */ + status = -HDLC_FRAMING_ERROR; + else if (hdlc->crc != 0xf0b8) /* crc error */ + status = -HDLC_CRC_ERROR; + else { + /* remove CRC */ + hdlc->dstpos -= 2; + /* good frame */ + status = hdlc->dstpos; + } + return status; +} + +/* + isdnhdlc_decode - decodes HDLC frames from a transparent bit stream. + + The source buffer is scanned for valid HDLC frames looking for + flags (01111110) to indicate the start of a frame. If the start of + the frame is found, the bit stuffing is removed (0 after 5 1's). + When a new flag is found, the complete frame has been received + and the CRC is checked. + If a valid frame is found, the function returns the frame length + excluding the CRC with the bit HDLC_END_OF_FRAME set. + If the beginning of a valid frame is found, the function returns + the length. + If a framing error is found (too many 1s and not a flag) the function + returns the length with the bit HDLC_FRAMING_ERROR set. + If a CRC error is found the function returns the length with the + bit HDLC_CRC_ERROR set. + If the frame length exceeds the destination buffer size, the function + returns the length with the bit HDLC_LENGTH_ERROR set. + + src - source buffer + slen - source buffer length + count - number of bytes removed (decoded) from the source buffer + dst _ destination buffer + dsize - destination buffer size + returns - number of decoded bytes in the destination buffer and status + flag. +*/ +int isdnhdlc_decode(struct isdnhdlc_vars *hdlc, const u8 *src, int slen, + int *count, u8 *dst, int dsize) +{ + int status = 0; + + static const unsigned char fast_flag[] = { + 0x00, 0x00, 0x00, 0x20, 0x30, 0x38, 0x3c, 0x3e, 0x3f + }; + + static const unsigned char fast_flag_value[] = { + 0x00, 0x7e, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f + }; + + static const unsigned char fast_abort[] = { + 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff + }; + +#define handle_fast_flag(h) \ + do { \ + if (h->cbin == fast_flag[h->bit_shift]) { \ + h->ffvalue = fast_flag_value[h->bit_shift]; \ + h->state = HDLC_FAST_FLAG; \ + h->ffbit_shift = h->bit_shift; \ + h->bit_shift = 1; \ + } else { \ + h->state = HDLC_GET_DATA; \ + h->data_received = 0; \ + } \ + } while (0) + +#define handle_abort(h) \ + do { \ + h->shift_reg = fast_abort[h->ffbit_shift - 1]; \ + h->hdlc_bits1 = h->ffbit_shift - 2; \ + if (h->hdlc_bits1 < 0) \ + h->hdlc_bits1 = 0; \ + h->data_bits = h->ffbit_shift - 1; \ + h->state = HDLC_GET_DATA; \ + h->data_received = 0; \ + } while (0) + + *count = slen; + + while (slen > 0) { + if (hdlc->bit_shift == 0) { + /* the code is for bitreverse streams */ + if (hdlc->do_bitreverse == 0) + hdlc->cbin = bitrev8(*src++); + else + hdlc->cbin = *src++; + slen--; + hdlc->bit_shift = 8; + if (hdlc->do_adapt56) + hdlc->bit_shift--; + } + + switch (hdlc->state) { + case STOPPED: + return 0; + case HDLC_FAST_IDLE: + if (hdlc->cbin == 0xff) { + hdlc->bit_shift = 0; + break; + } + hdlc->state = HDLC_GET_FLAG_B0; + hdlc->hdlc_bits1 = 0; + hdlc->bit_shift = 8; + break; + case HDLC_GET_FLAG_B0: + if (!(hdlc->cbin & 0x80)) { + hdlc->state = HDLC_GETFLAG_B1A6; + hdlc->hdlc_bits1 = 0; + } else { + if ((!hdlc->do_adapt56) && + (++hdlc->hdlc_bits1 >= 8) && + (hdlc->bit_shift == 1)) + hdlc->state = HDLC_FAST_IDLE; + } + hdlc->cbin <<= 1; + hdlc->bit_shift--; + break; + case HDLC_GETFLAG_B1A6: + if (hdlc->cbin & 0x80) { + hdlc->hdlc_bits1++; + if (hdlc->hdlc_bits1 == 6) + hdlc->state = HDLC_GETFLAG_B7; + } else + hdlc->hdlc_bits1 = 0; + hdlc->cbin <<= 1; + hdlc->bit_shift--; + break; + case HDLC_GETFLAG_B7: + if (hdlc->cbin & 0x80) { + hdlc->state = HDLC_GET_FLAG_B0; + } else { + hdlc->state = HDLC_GET_DATA; + hdlc->crc = 0xffff; + hdlc->shift_reg = 0; + hdlc->hdlc_bits1 = 0; + hdlc->data_bits = 0; + hdlc->data_received = 0; + } + hdlc->cbin <<= 1; + hdlc->bit_shift--; + break; + case HDLC_GET_DATA: + if (hdlc->cbin & 0x80) { + hdlc->hdlc_bits1++; + switch (hdlc->hdlc_bits1) { + case 6: + break; + case 7: + if (hdlc->data_received) + /* bad frame */ + status = -HDLC_FRAMING_ERROR; + if (!hdlc->do_adapt56) { + if (hdlc->cbin == fast_abort + [hdlc->bit_shift + 1]) { + hdlc->state = + HDLC_FAST_IDLE; + hdlc->bit_shift = 1; + break; + } + } else + hdlc->state = HDLC_GET_FLAG_B0; + break; + default: + hdlc->shift_reg >>= 1; + hdlc->shift_reg |= 0x80; + hdlc->data_bits++; + break; + } + } else { + switch (hdlc->hdlc_bits1) { + case 5: + break; + case 6: + if (hdlc->data_received) + status = check_frame(hdlc); + hdlc->crc = 0xffff; + hdlc->shift_reg = 0; + hdlc->data_bits = 0; + if (!hdlc->do_adapt56) + handle_fast_flag(hdlc); + else { + hdlc->state = HDLC_GET_DATA; + hdlc->data_received = 0; + } + break; + default: + hdlc->shift_reg >>= 1; + hdlc->data_bits++; + break; + } + hdlc->hdlc_bits1 = 0; + } + if (status) { + hdlc->dstpos = 0; + *count -= slen; + hdlc->cbin <<= 1; + hdlc->bit_shift--; + return status; + } + if (hdlc->data_bits == 8) { + hdlc->data_bits = 0; + hdlc->data_received = 1; + hdlc->crc = crc_ccitt_byte(hdlc->crc, + hdlc->shift_reg); + + /* good byte received */ + if (hdlc->dstpos < dsize) + dst[hdlc->dstpos++] = hdlc->shift_reg; + else { + /* frame too long */ + status = -HDLC_LENGTH_ERROR; + hdlc->dstpos = 0; + } + } + hdlc->cbin <<= 1; + hdlc->bit_shift--; + break; + case HDLC_FAST_FLAG: + if (hdlc->cbin == hdlc->ffvalue) { + hdlc->bit_shift = 0; + break; + } else { + if (hdlc->cbin == 0xff) { + hdlc->state = HDLC_FAST_IDLE; + hdlc->bit_shift = 0; + } else if (hdlc->ffbit_shift == 8) { + hdlc->state = HDLC_GETFLAG_B7; + break; + } else + handle_abort(hdlc); + } + break; + default: + break; + } + } + *count -= slen; + return 0; +} +EXPORT_SYMBOL(isdnhdlc_decode); +/* + isdnhdlc_encode - encodes HDLC frames to a transparent bit stream. + + The bit stream starts with a beginning flag (01111110). After + that each byte is added to the bit stream with bit stuffing added + (0 after 5 1's). + When the last byte has been removed from the source buffer, the + CRC (2 bytes is added) and the frame terminates with the ending flag. + For the dchannel, the idle character (all 1's) is also added at the end. + If this function is called with empty source buffer (slen=0), flags or + idle character will be generated. + + src - source buffer + slen - source buffer length + count - number of bytes removed (encoded) from source buffer + dst _ destination buffer + dsize - destination buffer size + returns - number of encoded bytes in the destination buffer +*/ +int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const u8 *src, u16 slen, + int *count, u8 *dst, int dsize) +{ + static const unsigned char xfast_flag_value[] = { + 0x7e, 0x3f, 0x9f, 0xcf, 0xe7, 0xf3, 0xf9, 0xfc, 0x7e + }; + + int len = 0; + + *count = slen; + + /* special handling for one byte frames */ + if ((slen == 1) && (hdlc->state == HDLC_SEND_FAST_FLAG)) + hdlc->state = HDLC_SENDFLAG_ONE; + while (dsize > 0) { + if (hdlc->bit_shift == 0) { + if (slen && !hdlc->do_closing) { + hdlc->shift_reg = *src++; + slen--; + if (slen == 0) + /* closing sequence, CRC + flag(s) */ + hdlc->do_closing = 1; + hdlc->bit_shift = 8; + } else { + if (hdlc->state == HDLC_SEND_DATA) { + if (hdlc->data_received) { + hdlc->state = HDLC_SEND_CRC1; + hdlc->crc ^= 0xffff; + hdlc->bit_shift = 8; + hdlc->shift_reg = + hdlc->crc & 0xff; + } else if (!hdlc->do_adapt56) + hdlc->state = + HDLC_SEND_FAST_FLAG; + else + hdlc->state = + HDLC_SENDFLAG_B0; + } + + } + } + + switch (hdlc->state) { + case STOPPED: + while (dsize--) + *dst++ = 0xff; + return dsize; + case HDLC_SEND_FAST_FLAG: + hdlc->do_closing = 0; + if (slen == 0) { + /* the code is for bitreverse streams */ + if (hdlc->do_bitreverse == 0) + *dst++ = bitrev8(hdlc->ffvalue); + else + *dst++ = hdlc->ffvalue; + len++; + dsize--; + break; + } + /* fall through */ + case HDLC_SENDFLAG_ONE: + if (hdlc->bit_shift == 8) { + hdlc->cbin = hdlc->ffvalue >> + (8 - hdlc->data_bits); + hdlc->state = HDLC_SEND_DATA; + hdlc->crc = 0xffff; + hdlc->hdlc_bits1 = 0; + hdlc->data_received = 1; + } + break; + case HDLC_SENDFLAG_B0: + hdlc->do_closing = 0; + hdlc->cbin <<= 1; + hdlc->data_bits++; + hdlc->hdlc_bits1 = 0; + hdlc->state = HDLC_SENDFLAG_B1A6; + break; + case HDLC_SENDFLAG_B1A6: + hdlc->cbin <<= 1; + hdlc->data_bits++; + hdlc->cbin++; + if (++hdlc->hdlc_bits1 == 6) + hdlc->state = HDLC_SENDFLAG_B7; + break; + case HDLC_SENDFLAG_B7: + hdlc->cbin <<= 1; + hdlc->data_bits++; + if (slen == 0) { + hdlc->state = HDLC_SENDFLAG_B0; + break; + } + if (hdlc->bit_shift == 8) { + hdlc->state = HDLC_SEND_DATA; + hdlc->crc = 0xffff; + hdlc->hdlc_bits1 = 0; + hdlc->data_received = 1; + } + break; + case HDLC_SEND_FIRST_FLAG: + hdlc->data_received = 1; + if (hdlc->data_bits == 8) { + hdlc->state = HDLC_SEND_DATA; + hdlc->crc = 0xffff; + hdlc->hdlc_bits1 = 0; + break; + } + hdlc->cbin <<= 1; + hdlc->data_bits++; + if (hdlc->shift_reg & 0x01) + hdlc->cbin++; + hdlc->shift_reg >>= 1; + hdlc->bit_shift--; + if (hdlc->bit_shift == 0) { + hdlc->state = HDLC_SEND_DATA; + hdlc->crc = 0xffff; + hdlc->hdlc_bits1 = 0; + } + break; + case HDLC_SEND_DATA: + hdlc->cbin <<= 1; + hdlc->data_bits++; + if (hdlc->hdlc_bits1 == 5) { + hdlc->hdlc_bits1 = 0; + break; + } + if (hdlc->bit_shift == 8) + hdlc->crc = crc_ccitt_byte(hdlc->crc, + hdlc->shift_reg); + if (hdlc->shift_reg & 0x01) { + hdlc->hdlc_bits1++; + hdlc->cbin++; + hdlc->shift_reg >>= 1; + hdlc->bit_shift--; + } else { + hdlc->hdlc_bits1 = 0; + hdlc->shift_reg >>= 1; + hdlc->bit_shift--; + } + break; + case HDLC_SEND_CRC1: + hdlc->cbin <<= 1; + hdlc->data_bits++; + if (hdlc->hdlc_bits1 == 5) { + hdlc->hdlc_bits1 = 0; + break; + } + if (hdlc->shift_reg & 0x01) { + hdlc->hdlc_bits1++; + hdlc->cbin++; + hdlc->shift_reg >>= 1; + hdlc->bit_shift--; + } else { + hdlc->hdlc_bits1 = 0; + hdlc->shift_reg >>= 1; + hdlc->bit_shift--; + } + if (hdlc->bit_shift == 0) { + hdlc->shift_reg = (hdlc->crc >> 8); + hdlc->state = HDLC_SEND_CRC2; + hdlc->bit_shift = 8; + } + break; + case HDLC_SEND_CRC2: + hdlc->cbin <<= 1; + hdlc->data_bits++; + if (hdlc->hdlc_bits1 == 5) { + hdlc->hdlc_bits1 = 0; + break; + } + if (hdlc->shift_reg & 0x01) { + hdlc->hdlc_bits1++; + hdlc->cbin++; + hdlc->shift_reg >>= 1; + hdlc->bit_shift--; + } else { + hdlc->hdlc_bits1 = 0; + hdlc->shift_reg >>= 1; + hdlc->bit_shift--; + } + if (hdlc->bit_shift == 0) { + hdlc->shift_reg = 0x7e; + hdlc->state = HDLC_SEND_CLOSING_FLAG; + hdlc->bit_shift = 8; + } + break; + case HDLC_SEND_CLOSING_FLAG: + hdlc->cbin <<= 1; + hdlc->data_bits++; + if (hdlc->hdlc_bits1 == 5) { + hdlc->hdlc_bits1 = 0; + break; + } + if (hdlc->shift_reg & 0x01) + hdlc->cbin++; + hdlc->shift_reg >>= 1; + hdlc->bit_shift--; + if (hdlc->bit_shift == 0) { + hdlc->ffvalue = + xfast_flag_value[hdlc->data_bits]; + if (hdlc->dchannel) { + hdlc->ffvalue = 0x7e; + hdlc->state = HDLC_SEND_IDLE1; + hdlc->bit_shift = 8-hdlc->data_bits; + if (hdlc->bit_shift == 0) + hdlc->state = + HDLC_SEND_FAST_IDLE; + } else { + if (!hdlc->do_adapt56) { + hdlc->state = + HDLC_SEND_FAST_FLAG; + hdlc->data_received = 0; + } else { + hdlc->state = HDLC_SENDFLAG_B0; + hdlc->data_received = 0; + } + /* Finished this frame, send flags */ + if (dsize > 1) + dsize = 1; + } + } + break; + case HDLC_SEND_IDLE1: + hdlc->do_closing = 0; + hdlc->cbin <<= 1; + hdlc->cbin++; + hdlc->data_bits++; + hdlc->bit_shift--; + if (hdlc->bit_shift == 0) { + hdlc->state = HDLC_SEND_FAST_IDLE; + hdlc->bit_shift = 0; + } + break; + case HDLC_SEND_FAST_IDLE: + hdlc->do_closing = 0; + hdlc->cbin = 0xff; + hdlc->data_bits = 8; + if (hdlc->bit_shift == 8) { + hdlc->cbin = 0x7e; + hdlc->state = HDLC_SEND_FIRST_FLAG; + } else { + /* the code is for bitreverse streams */ + if (hdlc->do_bitreverse == 0) + *dst++ = bitrev8(hdlc->cbin); + else + *dst++ = hdlc->cbin; + hdlc->bit_shift = 0; + hdlc->data_bits = 0; + len++; + dsize = 0; + } + break; + default: + break; + } + if (hdlc->do_adapt56) { + if (hdlc->data_bits == 7) { + hdlc->cbin <<= 1; + hdlc->cbin++; + hdlc->data_bits++; + } + } + if (hdlc->data_bits == 8) { + /* the code is for bitreverse streams */ + if (hdlc->do_bitreverse == 0) + *dst++ = bitrev8(hdlc->cbin); + else + *dst++ = hdlc->cbin; + hdlc->data_bits = 0; + len++; + dsize--; + } + } + *count -= slen; + + return len; +} +EXPORT_SYMBOL(isdnhdlc_encode); diff --git a/drivers/isdn/hardware/mISDN/isdnhdlc.h b/drivers/isdn/hardware/mISDN/isdnhdlc.h new file mode 100644 index 000000000000..fe2c1279c139 --- /dev/null +++ b/drivers/isdn/hardware/mISDN/isdnhdlc.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * hdlc.h -- General purpose ISDN HDLC decoder. + * + * Implementation of a HDLC decoder/encoder in software. + * Necessary because some ISDN devices don't have HDLC + * controllers. + * + * Copyright (C) + * 2009 Karsten Keil <keil@b1-systems.de> + * 2002 Wolfgang Mües <wolfgang@iksw-muees.de> + * 2001 Frode Isaksen <fisaksen@bewan.com> + * 2001 Kai Germaschewski <kai.germaschewski@gmx.de> + */ + +#ifndef __ISDNHDLC_H__ +#define __ISDNHDLC_H__ + +struct isdnhdlc_vars { + int bit_shift; + int hdlc_bits1; + int data_bits; + int ffbit_shift; /* encoding only */ + int state; + int dstpos; + + u16 crc; + + u8 cbin; + u8 shift_reg; + u8 ffvalue; + + /* set if transferring data */ + u32 data_received:1; + /* set if D channel (send idle instead of flags) */ + u32 dchannel:1; + /* set if 56K adaptation */ + u32 do_adapt56:1; + /* set if in closing phase (need to send CRC + flag) */ + u32 do_closing:1; + /* set if data is bitreverse */ + u32 do_bitreverse:1; +}; + +/* Feature Flags */ +#define HDLC_56KBIT 0x01 +#define HDLC_DCHANNEL 0x02 +#define HDLC_BITREVERSE 0x04 + +/* + The return value from isdnhdlc_decode is + the frame length, 0 if no complete frame was decoded, + or a negative error number +*/ +#define HDLC_FRAMING_ERROR 1 +#define HDLC_CRC_ERROR 2 +#define HDLC_LENGTH_ERROR 3 + +extern void isdnhdlc_rcv_init(struct isdnhdlc_vars *hdlc, u32 features); + +extern int isdnhdlc_decode(struct isdnhdlc_vars *hdlc, const u8 *src, + int slen, int *count, u8 *dst, int dsize); + +extern void isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, u32 features); + +extern int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const u8 *src, + u16 slen, int *count, u8 *dst, int dsize); + +#endif /* __ISDNHDLC_H__ */ diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c index 2b317cb63d06..93a2d361eda5 100644 --- a/drivers/isdn/hardware/mISDN/netjet.c +++ b/drivers/isdn/hardware/mISDN/netjet.c @@ -29,7 +29,7 @@ #include "ipac.h" #include "iohelper.h" #include "netjet.h" -#include <linux/isdn/hdlc.h> +#include "isdnhdlc.h" #define NETJET_REV "2.0" |