Commit a785c298 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/davem/sparc-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 12c32e9f c747c791
/*
* AMD 766/768 TCO Timer Driver
* (c) Copyright 2002 Zwane Mwaikambo <zwane@commfireservices.com>
* (c) Copyright 2002 Zwane Mwaikambo <zwane@holomorphy.com>
* All Rights Reserved.
*
* Parts from;
......@@ -34,35 +34,48 @@
#include <linux/init.h>
#include <linux/pci.h>
#define AMDTCO_MODULE_VER "build 20020601"
#define AMDTCO_MODULE_VER "build 20021116"
#define AMDTCO_MODULE_NAME "amd7xx_tco"
#define PFX AMDTCO_MODULE_NAME ": "
#define MAX_TIMEOUT 38 /* max of 38 seconds */
#define MAX_TIMEOUT 38 /* max of 38 seconds, although the system will only
* reset itself after the second timeout */
/* pmbase registers */
#define GLOBAL_SMI_REG 0x2a
#define TCO_EN (1 << 1) /* bit 1 in global SMI register */
#define TCO_RELOAD_REG 0x40 /* bits 0-5 are current count, 6-7 are reserved */
#define TCO_INITVAL_REG 0x41 /* bits 0-5 are value to load, 6-7 are reserved */
#define TCO_TIMEOUT_MASK 0x3f
#define TCO_STATUS1_REG 0x44
#define TCO_STATUS2_REG 0x46
#define NDTO_STS2 (1 << 1) /* we're interested in the second timeout */
#define BOOT_STS (1 << 2) /* will be set if NDTO_STS2 was set before reboot */
#define TCO_CTRL1_REG 0x48
#define TCO_HALT (1 << 11)
#define NO_REBOOT (1 << 10) /* in DevB:3x48 */
static char banner[] __initdata = KERN_INFO PFX AMDTCO_MODULE_VER;
static int timeout = 38;
static char banner[] __initdata = KERN_INFO PFX AMDTCO_MODULE_VER "\n";
static int timeout = MAX_TIMEOUT;
static u32 pmbase; /* PMxx I/O base */
static struct pci_dev *dev;
static struct semaphore open_sem;
spinlock_t amdtco_lock; /* only for device access */
static spinlock_t amdtco_lock; /* only for device access */
static int expect_close = 0;
MODULE_PARM(timeout, "i");
MODULE_PARM_DESC(timeout, "range is 0-38 seconds, default is 38");
static inline u8 seconds_to_ticks(int seconds)
{
/* the internal timer is stored as ticks which decrement
* every 0.6 seconds */
return (seconds * 10) / 6;
}
static inline int ticks_to_seconds(u8 ticks)
{
return (ticks * 6) / 10;
}
static inline int amdtco_status(void)
{
u16 reg;
......@@ -81,28 +94,19 @@ static inline int amdtco_status(void)
static inline void amdtco_ping(void)
{
u8 reg;
spin_lock(&amdtco_lock);
reg = inb(pmbase+TCO_RELOAD_REG);
outb(1 | reg, pmbase+TCO_RELOAD_REG);
spin_unlock(&amdtco_lock);
outb(1, pmbase+TCO_RELOAD_REG);
}
static inline int amdtco_gettimeout(void)
{
return inb(TCO_RELOAD_REG) & TCO_TIMEOUT_MASK;
u8 reg = inb(pmbase+TCO_RELOAD_REG) & TCO_TIMEOUT_MASK;
return ticks_to_seconds(reg);
}
static inline void amdtco_settimeout(unsigned int timeout)
{
u8 reg;
spin_lock(&amdtco_lock);
reg = inb(pmbase+TCO_INITVAL_REG);
reg |= timeout & TCO_TIMEOUT_MASK;
u8 reg = seconds_to_ticks(timeout) & TCO_TIMEOUT_MASK;
outb(reg, pmbase+TCO_INITVAL_REG);
spin_unlock(&amdtco_lock);
}
static inline void amdtco_global_enable(void)
......@@ -110,9 +114,12 @@ static inline void amdtco_global_enable(void)
u16 reg;
spin_lock(&amdtco_lock);
reg = inw(pmbase+GLOBAL_SMI_REG);
reg |= TCO_EN;
outw(reg, pmbase+GLOBAL_SMI_REG);
/* clear NO_REBOOT on DevB:3x48 p97 */
pci_read_config_word(dev, 0x48, &reg);
reg &= ~NO_REBOOT;
pci_write_config_word(dev, 0x48, reg);
spin_unlock(&amdtco_lock);
}
......@@ -146,10 +153,12 @@ static int amdtco_fop_open(struct inode *inode, struct file *file)
if (timeout > MAX_TIMEOUT)
timeout = MAX_TIMEOUT;
amdtco_disable();
amdtco_settimeout(timeout);
amdtco_global_enable();
amdtco_enable();
amdtco_ping();
printk(KERN_INFO PFX "Watchdog enabled, timeout = %d/%d seconds",
printk(KERN_INFO PFX "Watchdog enabled, timeout = %ds of %ds\n",
amdtco_gettimeout(), timeout);
return 0;
......@@ -198,7 +207,7 @@ static int amdtco_fop_ioctl(struct inode *inode, struct file *file, unsigned int
case WDIOC_GETTIMEOUT:
return put_user(amdtco_gettimeout(), (int *)arg);
case WDIOC_SETOPTIONS:
if (copy_from_user(&tmp, (int *)arg, sizeof tmp))
return -EFAULT;
......@@ -221,7 +230,7 @@ static int amdtco_fop_release(struct inode *inode, struct file *file)
printk(KERN_INFO PFX "Watchdog disabled\n");
} else {
amdtco_ping();
printk(KERN_CRIT PFX "Unexpected close!, timeout in %d seconds)\n", timeout);
printk(KERN_CRIT PFX "Unexpected close!, timeout in %d seconds\n", timeout);
}
up(&open_sem);
......@@ -249,10 +258,9 @@ static ssize_t amdtco_fop_write(struct file *file, const char *data, size_t len,
}
#endif
amdtco_ping();
return len;
}
return 0;
return len;
}
......@@ -357,6 +365,9 @@ static int __init amdtco_setup(char *str)
if (ints[0] > 0)
timeout = ints[1];
if (!timeout || timeout > MAX_TIMEOUT)
timeout = MAX_TIMEOUT;
return 1;
}
......@@ -366,8 +377,7 @@ __setup("amd7xx_tco=", amdtco_setup);
module_init(amdtco_init);
module_exit(amdtco_exit);
MODULE_AUTHOR("Zwane Mwaikambo <zwane@commfireservices.com>");
MODULE_AUTHOR("Zwane Mwaikambo <zwane@holomorphy.com>");
MODULE_DESCRIPTION("AMD 766/768 TCO Timer Driver");
MODULE_LICENSE("GPL");
EXPORT_NO_SYMBOLS;
......@@ -343,12 +343,16 @@ static int __devinit b1pci_pci_probe(struct pci_dev *pdev,
static void __devexit 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 = {
......
/* $Id: amd7930.c,v 1.5.6.4 2001/09/23 22:24:46 kai Exp $
*
* HiSax ISDN driver - chip specific routines for AMD 7930
*
* Author Brent Baccala
* Copyright by Brent Baccala <baccala@FreeSoft.org>
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*
* - Existing ISDN HiSax driver provides all the smarts
* - it compiles, runs, talks to an isolated phone switch, connects
* to a Cisco, pings go through
* - AMD 7930 support only (no DBRI yet)
* - no US NI-1 support (may not work on US phone system - untested)
* - periodic packet loss, apparently due to lost interrupts
* - ISDN sometimes freezes, requiring reboot before it will work again
*
* The code is unreliable enough to be consider alpha
*
* This file is (c) under GNU General Public License
*
* Advanced Micro Devices' Am79C30A is an ISDN/audio chip used in the
* SparcStation 1+. The chip provides microphone and speaker interfaces
* which provide mono-channel audio at 8K samples per second via either
* 8-bit A-law or 8-bit mu-law encoding. Also, the chip features an
* ISDN BRI Line Interface Unit (LIU), I.430 S/T physical interface,
* which performs basic D channel LAPD processing and provides raw
* B channel data. The digital audio channel, the two ISDN B channels,
* and two 64 Kbps channels to the microprocessor are all interconnected
* via a multiplexer.
*
* This driver interfaces to the Linux HiSax ISDN driver, which performs
* all high-level Q.921 and Q.931 ISDN functions. The file is not
* itself a hardware driver; rather it uses functions exported by
* the AMD7930 driver in the sparcaudio subsystem (drivers/sbus/audio),
* allowing the chip to be simultaneously used for both audio and ISDN data.
* The hardware driver does _no_ buffering, but provides several callbacks
* which are called during interrupt service and should therefore run quickly.
*
* D channel transmission is performed by passing the hardware driver the
* address and size of an skb's data area, then waiting for a callback
* to signal successful transmission of the packet. A task is then
* queued to notify the HiSax driver that another packet may be transmitted.
*
* D channel reception is quite simple, mainly because of:
* 1) the slow speed of the D channel - 16 kbps, and
* 2) the presence of an 8- or 32-byte (depending on chip version) FIFO
* to buffer the D channel data on the chip
* Worst case scenario of back-to-back packets with the 8 byte buffer
* at 16 kbps yields an service time of 4 ms - long enough to preclude
* the need for fancy buffering. We queue a background task that copies
* data out of the receive buffer into an skb, and the hardware driver
* simply does nothing until we're done with the receive buffer and
* reset it for a new packet.
*
* B channel processing is more complex, because of:
* 1) the faster speed - 64 kbps,
* 2) the lack of any on-chip buffering (it interrupts for every byte), and
* 3) the lack of any chip support for HDLC encapsulation
*
* The HiSax driver can put each B channel into one of three modes -
* L1_MODE_NULL (channel disabled), L1_MODE_TRANS (transparent data relay),
* and L1_MODE_HDLC (HDLC encapsulation by low-level driver).
* L1_MODE_HDLC is the most common, used for almost all "pure" digital
* data sessions. L1_MODE_TRANS is used for ISDN audio.
*
* HDLC B channel transmission is performed via a large buffer into
* which the skb is copied while performing HDLC bit-stuffing. A CRC
* is computed and attached to the end of the buffer, which is then
* passed to the low-level routines for raw transmission. Once
* transmission is complete, the hardware driver is set to enter HDLC
* idle by successive transmission of mark (all 1) bytes, waiting for
* the ISDN driver to prepare another packet for transmission and
* deliver it.
*
* HDLC B channel reception is performed via an X-byte ring buffer
* divided into N sections of X/N bytes each. Defaults: X=256 bytes, N=4.
* As the hardware driver notifies us that each section is full, we
* hand it the next section and schedule a background task to peruse
* the received section, bit-by-bit, with an HDLC decoder. As
* packets are detected, they are copied into a large buffer while
* decoding HDLC bit-stuffing. The ending CRC is verified, and if
* it is correct, we alloc a new skb of the correct length (which we
* now know), copy the packet into it, and hand it to the upper layers.
* Optimization: for large packets, we hand the buffer (which also
* happens to be an skb) directly to the upper layer after an skb_trim,
* and alloc a new large buffer for future packets, thus avoiding a copy.
* Then we return to HDLC processing; state is saved between calls.
*
*/
#include "hisax.h"
#include "../../sbus/audio/amd7930.h"
#include "isac.h"
#include "isdnl1.h"
#include "rawhdlc.h"
#include <linux/interrupt.h>
static const char *amd7930_revision = "$Revision: 1.5.6.4 $";
#define RCV_BUFSIZE 1024 /* Size of raw receive buffer in bytes */
#define RCV_BUFBLKS 4 /* Number of blocks to divide buffer into
* (must divide RCV_BUFSIZE) */
static void Bchan_fill_fifo(struct BCState *, struct sk_buff *);
static void
Bchan_xmt_bh(void *data)
{
struct BCState *bcs = data;
struct sk_buff *skb;
if (bcs->hw.amd7930.tx_skb != NULL) {
dev_kfree_skb(bcs->hw.amd7930.tx_skb);
bcs->hw.amd7930.tx_skb = NULL;
}
xmit_ready_b(bcs);
}
static void
Bchan_xmit_callback(struct BCState *bcs)
{
schedule_work(&bcs->hw.amd7930.xmt_work);
}
/* B channel transmission: two modes (three, if you count L1_MODE_NULL)
*
* L1_MODE_HDLC - We need to do HDLC encapsulation before transmiting
* the packet (i.e. make_raw_hdlc_data). Since this can be a
* time-consuming operation, our completion callback just schedules
* a bottom half to do encapsulation for the next packet. In between,
* the link will just idle
*
* L1_MODE_TRANS - Data goes through, well, transparent. No HDLC encap,
* and we can't just let the link idle, so the "bottom half" actually
* gets called during the top half (it's our callback routine in this case),
* but it's a lot faster now since we don't call make_raw_hdlc_data
*/
static void
Bchan_fill_fifo(struct BCState *bcs, struct sk_buff *skb)
{
struct IsdnCardState *cs = bcs->cs;
int len;
if ((cs->debug & L1_DEB_HSCX) || (cs->debug & L1_DEB_HSCX_FIFO)) {
char tmp[1024];
char *t = tmp;
t += sprintf(t, "amd7930_fill_fifo %c cnt %d",
bcs->channel ? 'B' : 'A', skb->len);
if (cs->debug & L1_DEB_HSCX_FIFO)
QuickHex(t, skb->data, skb->len);
debugl1(cs, tmp);
}
if (bcs->mode == L1_MODE_HDLC) {
len = make_raw_hdlc_data(skb->data, skb->len,
bcs->hw.amd7930.tx_buff, RAW_BUFMAX);
if (len > 0)
amd7930_bxmit(0, bcs->channel,
bcs->hw.amd7930.tx_buff, len,
(void *) &Bchan_xmit_callback,
(void *) bcs);
dev_kfree_skb(skb);
} else if (bcs->mode == L1_MODE_TRANS) {
amd7930_bxmit(0, bcs->channel,
bcs->hw.amd7930.tx_buff, skb->len,
(void *) &Bchan_xmt_bh,
(void *) bcs);
bcs->hw.amd7930.tx_skb = skb;
} else {
dev_kfree_skb(skb);
}
}
static void
Bchan_mode(struct BCState *bcs, int mode, int bc)
{
struct IsdnCardState *cs = bcs->cs;
if (cs->debug & L1_DEB_HSCX) {
char tmp[40];
sprintf(tmp, "AMD 7930 mode %d bchan %d/%d",
mode, bc, bcs->channel);
debugl1(cs, tmp);
}
bcs->mode = mode;
}
/* Bchan_l2l1 is the entry point for upper layer routines that want to
* transmit on the B channel. PH_DATA_REQ is a normal packet that
* we either start transmitting (if idle) or queue (if busy).
* PH_PULL_REQ can be called to request a callback message (PH_PULL_CNF)
* once the link is idle. After a "pull" callback, the upper layer
* routines can use PH_PULL_IND to send data.
*/
static void
Bchan_l2l1(struct PStack *st, int pr, void *arg)
{
struct sk_buff *skb = arg;
switch (pr) {
case (PH_DATA_REQ):
if (test_bit(BC_FLG_BUSY, &st->l1.bcs->Flag)) {
skb_queue_tail(&st->l1.bcs->squeue, skb);
} else {
test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
Bchan_fill_fifo(st->l1.bcs, skb);
}
break;
case (PH_PULL_IND):
if (test_bit(BC_FLG_BUSY, &st->l1.bcs->Flag)) {
printk(KERN_WARNING "amd7930: this shouldn't happen\n");
break;
}
test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
Bchan_fill_fifo(st->l1.bcs, skb);
break;
case (PH_PULL_REQ):
if (!test_bit(BC_FLG_BUSY, &st->l1.bcs->Flag)) {
clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
st->l1.l1l2(st, PH_PULL_CNF, NULL);
} else
set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
break;
}
}
/* Receiver callback and bottom half - decodes HDLC at leisure (if
* L1_MODE_HDLC) and passes newly received skb on via bcs->rqueue. If
* a large packet is received, stick rv_skb (the buffer that the
* packet has been decoded into) on the receive queue and alloc a new
* (large) skb to act as buffer for future receives. If a small
* packet is received, leave rv_skb alone, alloc a new skb of the
* correct size, and copy the packet into it
*/
static void
Bchan_recv_callback(struct BCState *bcs)
{
struct amd7930_hw *hw = &bcs->hw.amd7930;
hw->rv_buff_in += RCV_BUFSIZE/RCV_BUFBLKS;
hw->rv_buff_in %= RCV_BUFSIZE;
if (hw->rv_buff_in != hw->rv_buff_out) {
amd7930_brecv(0, bcs->channel,
hw->rv_buff + hw->rv_buff_in,
RCV_BUFSIZE/RCV_BUFBLKS,
(void *) &Bchan_recv_callback, (void *) bcs);
}
schedule_work(&hw->rcv_work);
}
static void
Bchan_rcv_bh(void *data)
{
struct BCState *bcs = data;
struct IsdnCardState *cs = bcs->cs;
struct amd7930_hw *hw = &bcs->hw.amd7930;
struct sk_buff *skb;
int len;
if (cs->debug & L1_DEB_HSCX) {
char tmp[1024];
sprintf(tmp, "amd7930_Bchan_rcv (%d/%d)",
hw->rv_buff_in, hw->rv_buff_out);
debugl1(cs, tmp);
QuickHex(tmp, hw->rv_buff + hw->rv_buff_out,
RCV_BUFSIZE/RCV_BUFBLKS);
debugl1(cs, tmp);
}
do {
if (bcs->mode == L1_MODE_HDLC) {
while ((len = read_raw_hdlc_data(hw->hdlc_state,
hw->rv_buff + hw->rv_buff_out, RCV_BUFSIZE/RCV_BUFBLKS,
hw->rv_skb->tail, HSCX_BUFMAX))) {
if (len > 0 && (cs->debug & L1_DEB_HSCX_FIFO)) {
char tmp[1024];
char *t = tmp;
t += sprintf(t, "amd7930_Bchan_rcv %c cnt %d", bcs->channel ? 'B' : 'A', len);
QuickHex(t, hw->rv_skb->tail, len);
debugl1(cs, tmp);
}
if (len > HSCX_BUFMAX/2) {
/* Large packet received */
if (!(skb = dev_alloc_skb(HSCX_BUFMAX))) {
printk(KERN_WARNING "amd7930: receive out of memory");
} else {
skb_put(hw->rv_skb, len);
skb_queue_tail(&bcs->rqueue, hw->rv_skb);
hw->rv_skb = skb;
bcs->event |= 1 << B_RCVBUFREADY;
schedule_work(&bcs->work);
}
} else if (len > 0) {
/* Small packet received */
if (!(skb = dev_alloc_skb(len))) {
printk(KERN_WARNING "amd7930: receive out of memory\n");
} else {
memcpy(skb_put(skb, len), hw->rv_skb->tail, len);
skb_queue_tail(&bcs->rqueue, skb);
bcs->event |= 1 << B_RCVBUFREADY;
schedule_work(&bcs->work);
}
} else {
/* Reception Error */
/* printk("amd7930: B channel receive error\n"); */
}
}
} else if (bcs->mode == L1_MODE_TRANS) {
if (!(skb = dev_alloc_skb(RCV_BUFSIZE/RCV_BUFBLKS))) {
printk(KERN_WARNING "amd7930: receive out of memory\n");
} else {
memcpy(skb_put(skb, RCV_BUFSIZE/RCV_BUFBLKS),
hw->rv_buff + hw->rv_buff_out,
RCV_BUFSIZE/RCV_BUFBLKS);
skb_queue_tail(&bcs->rqueue, skb);
bcs->event |= 1 << B_RCVBUFREADY;
schedule_work(&bcs->work);
}
}
if (hw->rv_buff_in == hw->rv_buff_out) {
/* Buffer was filled up - need to restart receiver */
amd7930_brecv(0, bcs->channel,
hw->rv_buff + hw->rv_buff_in,
RCV_BUFSIZE/RCV_BUFBLKS,
(void *) &Bchan_recv_callback,
(void *) bcs);
}
hw->rv_buff_out += RCV_BUFSIZE/RCV_BUFBLKS;
hw->rv_buff_out %= RCV_BUFSIZE;
} while (hw->rv_buff_in != hw->rv_buff_out);
}
static void
Bchan_close(struct BCState *bcs)
{
struct sk_buff *skb;
Bchan_mode(bcs, 0, 0);
amd7930_bclose(0, bcs->channel);
if (test_bit(BC_FLG_INIT, &bcs->Flag)) {
skb_queue_purge(&bcs->rqueue);
skb_queue_purge(&bcs->squeue);
}
test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
}
static int
Bchan_open(struct BCState *bcs)
{
struct amd7930_hw *hw = &bcs->hw.amd7930;
if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
skb_queue_head_init(&bcs->rqueue);
skb_queue_head_init(&bcs->squeue);
}
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
amd7930_bopen(0, bcs->channel, 0xff);
hw->rv_buff_in = 0;
hw->rv_buff_out = 0;
hw->tx_skb = NULL;
init_hdlc_state(hw->hdlc_state, 0);
amd7930_brecv(0, bcs->channel,
hw->rv_buff + hw->rv_buff_in, RCV_BUFSIZE/RCV_BUFBLKS,
(void *) &Bchan_recv_callback, (void *) bcs);
bcs->event = 0;
bcs->tx_cnt = 0;
return (0);
}
static void
Bchan_init(struct BCState *bcs)
{
if (!(bcs->hw.amd7930.tx_buff = kmalloc(RAW_BUFMAX, GFP_ATOMIC))) {
printk(KERN_WARNING
"HiSax: No memory for amd7930.tx_buff\n");
return;
}
if (!(bcs->hw.amd7930.rv_buff = kmalloc(RCV_BUFSIZE, GFP_ATOMIC))) {
printk(KERN_WARNING
"HiSax: No memory for amd7930.rv_buff\n");
return;
}
if (!(bcs->hw.amd7930.rv_skb = dev_alloc_skb(HSCX_BUFMAX))) {
printk(KERN_WARNING
"HiSax: No memory for amd7930.rv_skb\n");
return;
}
if (!(bcs->hw.amd7930.hdlc_state = kmalloc(sizeof(struct hdlc_state),
GFP_ATOMIC))) {
printk(KERN_WARNING
"HiSax: No memory for amd7930.hdlc_state\n");
return;
}
INIT_WORK(&bcs->hw.amd7930.rcv_work, &Bchan_rcv_bh, bcs);
INIT_WORK(&bcs->hw.amd7930.xmt_work, &Bchan_xmt_bh, bcs);
}
static void
Bchan_manl1(struct PStack *st, int pr,
void *arg)
{
switch (pr) {
case (PH_ACTIVATE_REQ):
test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
Bchan_mode(st->l1.bcs, st->l1.mode, st->l1.bc);
st->l1.l1man(st, PH_ACTIVATE_CNF, NULL);
break;
case (PH_DEACTIVATE_REQ):
if (!test_bit(BC_FLG_BUSY, &st->l1.bcs->Flag))
Bchan_mode(st->l1.bcs, 0, 0);
test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
break;
}
}
int
setstack_amd7930(struct PStack *st, struct BCState *bcs)
{
if (Bchan_open(bcs))
return (-1);
st->l1.bcs = bcs;
st->l2.l2l1 = Bchan_l2l1;
st->ma.manl1 = Bchan_manl1;
setstack_manager(st);
bcs->st = st;
return (0);
}
static void
amd7930_drecv_callback(void *arg, int error, unsigned int count)
{
struct IsdnCardState *cs = (struct IsdnCardState *) arg;
static struct work_struct task;
struct sk_buff *skb;
/* NOTE: This function is called directly from an interrupt handler */
if (1) {
if (!(skb = alloc_skb(count, GFP_ATOMIC)))
printk(KERN_WARNING "HiSax: D receive out of memory\n");
else {
memcpy(skb_put(skb, count), cs->rcvbuf, count);
skb_queue_tail(&cs->rq, skb);
}
INIT_WORK(&task, (void *) DChannel_proc_rcv, (void *) cs);
schedule_work(&task);
}
if (cs->debug & L1_DEB_ISAC_FIFO) {
char tmp[128];
char *t = tmp;
t += sprintf(t, "amd7930 Drecv cnt %d", count);
if (error) t += sprintf(t, " ERR %x", error);
QuickHex(t, cs->rcvbuf, count);
debugl1(cs, tmp);
}
amd7930_drecv(0, cs->rcvbuf, MAX_DFRAME_LEN,
&amd7930_drecv_callback, cs);
}
static void
amd7930_dxmit_callback(void *arg, int error)
{
struct IsdnCardState *cs = (struct IsdnCardState *) arg;
static struct work_struct task;
/* NOTE: This function is called directly from an interrupt handler */
/* may wish to do retransmission here, if error indicates collision */
if (cs->debug & L1_DEB_ISAC_FIFO) {
char tmp[128];
char *t = tmp;
t += sprintf(t, "amd7930 Dxmit cnt %d", cs->tx_skb->len);
if (error) t += sprintf(t, " ERR %x", error);
QuickHex(t, cs->tx_skb->data, cs->tx_skb->len);
debugl1(cs, tmp);
}
cs->tx_skb = NULL;
INIT_WORK(&task, (void *) DChannel_proc_xmt, (void *) cs);
schedule_work(&task);
}
static void
amd7930_Dchan_l2l1(struct PStack *st, int pr, void *arg)
{
struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
struct sk_buff *skb = arg;
char str[64];
switch (pr) {
case (PH_DATA_REQ):
if (cs->tx_skb) {
skb_queue_tail(&cs->sq, skb);
#ifdef L2FRAME_DEBUG /* psa */
if (cs->debug & L1_DEB_LAPD)
Logl2Frame(cs, skb, "PH_DATA Queued", 0);
#endif
} else {
if ((cs->dlogflag) && (!(skb->data[2] & 1))) {
/* I-FRAME */
LogFrame(cs, skb->data, skb->len);
sprintf(str, "Q.931 frame user->network tei %d", st->l2.tei);
dlogframe(cs, skb->data+4, skb->len-4,
str);
}
cs->tx_skb = skb;
cs->tx_cnt = 0;
#ifdef L2FRAME_DEBUG /* psa */
if (cs->debug & L1_DEB_LAPD)
Logl2Frame(cs, skb, "PH_DATA", 0);
#endif
amd7930_dxmit(0, skb->data, skb->len,
&amd7930_dxmit_callback, cs);
}
break;
case (PH_PULL_IND):
if (cs->tx_skb) {
if (cs->debug & L1_DEB_WARN)
debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
skb_queue_tail(&cs->sq, skb);
break;
}
if ((cs->dlogflag) && (!(skb->data[2] & 1))) { /* I-FRAME */
LogFrame(cs, skb->data, skb->len);
sprintf(str, "Q.931 frame user->network tei %d", st->l2.tei);
dlogframe(cs, skb->data + 4, skb->len - 4,
str);
}
cs->tx_skb = skb;
cs->tx_cnt = 0;
#ifdef L2FRAME_DEBUG /* psa */
if (cs->debug & L1_DEB_LAPD)
Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
#endif
amd7930_dxmit(0, cs->tx_skb->data, cs->tx_skb->len,
&amd7930_dxmit_callback, cs);
break;
case (PH_PULL_REQ):
#ifdef L2FRAME_DEBUG /* psa */
if (cs->debug & L1_DEB_LAPD)
debugl1(cs, "-> PH_REQUEST_PULL");
#endif
if (!cs->tx_skb) {
test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
st->l1.l1l2(st, PH_PULL_CNF, NULL);
} else
test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
break;
}
}
int
setDstack_amd7930(struct PStack *st, struct IsdnCardState *cs)
{
st->l2.l2l1 = amd7930_Dchan_l2l1;
if (! cs->rcvbuf) {
printk("setDstack_amd7930: No cs->rcvbuf!\n");
} else {
amd7930_drecv(0, cs->rcvbuf, MAX_DFRAME_LEN,
&amd7930_drecv_callback, cs);
}
return (0);
}
static void
manl1_msg(struct IsdnCardState *cs, int msg, void *arg) {
struct PStack *st;
st = cs->stlist;
while (st) {
st->ma.manl1(st, msg, arg);
st = st->next;
}
}
static void
amd7930_new_ph(struct IsdnCardState *cs)
{
switch (amd7930_get_liu_state(0)) {
case 3:
manl1_msg(cs, PH_POWERUP_CNF, NULL);
break;
case 7:
manl1_msg(cs, PH_I4_P8_IND, NULL);
break;
case 8:
manl1_msg(cs, PH_RSYNC_IND, NULL);
break;
}
}
/* amd7930 LIU state change callback */
static void
amd7930_liu_callback(struct IsdnCardState *cs)
{
static struct work_struct task;
if (!cs)
return;
if (cs->debug & L1_DEB_ISAC) {
char tmp[32];
sprintf(tmp, "amd7930_liu state %d", amd7930_get_liu_state(0));
debugl1(cs, tmp);
}
INIT_WORK(&task, (void *) &amd7930_new_ph, (void *) cs);
schedule_work(&task);
}
void
amd7930_l1cmd(struct IsdnCardState *cs, int msg, void *arg)
{
u8 val;
char tmp[32];
if (cs->debug & L1_DEB_ISAC) {
char tmp[32];
sprintf(tmp, "amd7930_l1cmd msg %x", msg);
debugl1(cs, tmp);
}
switch(msg) {
case PH_RESET_REQ:
if (amd7930_get_liu_state(0) <= 3)
amd7930_liu_activate(0,0);
else
amd7930_liu_deactivate(0);
break;
case PH_ENABLE_REQ:
break;
case PH_INFO3_REQ:
amd7930_liu_activate(0,0);
break;
case PH_TESTLOOP_REQ:
break;
default:
if (cs->debug & L1_DEB_WARN) {
sprintf(tmp, "amd7930_l1cmd unknown %4x", msg);
debugl1(cs, tmp);
}
break;
}
}
static void init_amd7930(struct IsdnCardState *cs)
{
Bchan_init(&cs->bcs[0]);
Bchan_init(&cs->bcs[1]);
cs->bcs[0].BC_SetStack = setstack_amd7930;
cs->bcs[1].BC_SetStack = setstack_amd7930;
cs->bcs[0].BC_Close = Bchan_close;
cs->bcs[1].BC_Close = Bchan_close;
Bchan_mode(cs->bcs, 0, 0);
Bchan_mode(cs->bcs + 1, 0, 0);
}
static int
amd7930_init(struct IsdnCardState *cs)
{
cs->l1cmd = amd7930_l1cmd;
amd7930_liu_init(0, &amd7930_liu_callback, (void *)cs);
init_amd7930(cs);
return 0;
}
static struct card_ops amd7930_ops = {
.init = amd7930_init,
};
int __init
setup_amd7930(struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
char tmp[64];
strcpy(tmp, amd7930_revision);
printk(KERN_INFO "HiSax: AMD7930 driver Rev. %s\n", HiSax_getrev(tmp));
cs->irq = amd7930_get_irqnum(0);
if (cs->irq == 0)
return 0;
cs->card_ops = &amd7930_ops;
return 1;
}
......@@ -231,6 +231,51 @@ static struct card_ops asuscom_ipac_ops = {
.irq_func = ipac_irq,
};
static int __init
asuscom_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
int rc;
u8 val;
printk(KERN_INFO "ISDNLink: defined at %#lx IRQ %lu\n",
card->para[1], card->para[0]);
cs->hw.asus.cfg_reg = card->para[1];
cs->irq = card->para[0];
rc = -EBUSY;
if (!request_io(&cs->rs, cs->hw.asus.cfg_reg, 8, "asuscom isdn"))
goto err;
rc = -ENODEV;
cs->hw.asus.adr = cs->hw.asus.cfg_reg + ASUS_IPAC_ALE;
val = readreg(cs, cs->hw.asus.cfg_reg + ASUS_IPAC_DATA, IPAC_ID);
if ((val == 1) || (val == 2)) {
cs->subtyp = ASUS_IPAC;
cs->card_ops = &asuscom_ipac_ops;
cs->hw.asus.isac = cs->hw.asus.cfg_reg + ASUS_IPAC_DATA;
if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops))
goto err;
} else {
cs->subtyp = ASUS_ISACHSCX;
cs->card_ops = &asuscom_ops;
cs->hw.asus.adr = cs->hw.asus.cfg_reg + ASUS_ADR;
cs->hw.asus.isac = cs->hw.asus.cfg_reg + ASUS_ISAC;
cs->hw.asus.hscx = cs->hw.asus.cfg_reg + ASUS_HSCX;
cs->hw.asus.u7 = cs->hw.asus.cfg_reg + ASUS_CTRL_U7;
cs->hw.asus.pots = cs->hw.asus.cfg_reg + ASUS_CTRL_POTS;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err;
}
printk(KERN_INFO "ISDNLink: resetting card\n");
cs->card_ops->reset(cs);
return 0;
err:
hisax_release_resources(cs);
return rc;
}
#ifdef __ISAPNP__
static struct isapnp_device_id asus_ids[] __initdata = {
{ ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1688),
......@@ -255,9 +300,6 @@ static struct pnp_card *pnp_c __devinitdata = NULL;
int __init
setup_asuscom(struct IsdnCard *card)
{
int bytecnt;
struct IsdnCardState *cs = card->cs;
u8 val;
char tmp[64];
strcpy(tmp, Asuscom_revision);
......@@ -310,36 +352,7 @@ setup_asuscom(struct IsdnCard *card)
}
}
#endif
bytecnt = 8;
cs->hw.asus.cfg_reg = card->para[1];
cs->irq = card->para[0];
if (!request_io(&cs->rs, cs->hw.asus.cfg_reg, bytecnt, "asuscom isdn"))
goto err;
printk(KERN_INFO "ISDNLink: defined at 0x%x IRQ %d\n",
cs->hw.asus.cfg_reg, cs->irq);
cs->hw.asus.adr = cs->hw.asus.cfg_reg + ASUS_IPAC_ALE;
val = readreg(cs, cs->hw.asus.cfg_reg + ASUS_IPAC_DATA, IPAC_ID);
if ((val == 1) || (val == 2)) {
cs->subtyp = ASUS_IPAC;
cs->card_ops = &asuscom_ipac_ops;
cs->hw.asus.isac = cs->hw.asus.cfg_reg + ASUS_IPAC_DATA;
if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops))
goto err;
} else {
cs->subtyp = ASUS_ISACHSCX;
cs->card_ops = &asuscom_ops;
cs->hw.asus.adr = cs->hw.asus.cfg_reg + ASUS_ADR;
cs->hw.asus.isac = cs->hw.asus.cfg_reg + ASUS_ISAC;
cs->hw.asus.hscx = cs->hw.asus.cfg_reg + ASUS_HSCX;
cs->hw.asus.u7 = cs->hw.asus.cfg_reg + ASUS_CTRL_U7;
cs->hw.asus.pots = cs->hw.asus.cfg_reg + ASUS_CTRL_POTS;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err;
}
printk(KERN_INFO "ISDNLink: resetting card\n");
cs->card_ops->reset(cs);
if (asuscom_probe(card->cs, card) < 0)
return 0;
return 1;
err:
hisax_release_resources(cs);
return 0;
}
......@@ -160,16 +160,16 @@ static struct card_ops avm_a1_ops = {
.irq_func = avm_a1_interrupt,
};
int __init
setup_avm_a1(struct IsdnCard *card)
static int __init
avm_a1_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
int rc;
u8 val;
struct IsdnCardState *cs = card->cs;
char tmp[64];
strcpy(tmp, avm_revision);
printk(KERN_INFO "HiSax: AVM driver Rev. %s\n", HiSax_getrev(tmp));
printk(KERN_INFO "AVM A1: defined at %#lx IRQ %lu\n",
card->para[1], card->para[0]);
rc = -EBUSY;
cs->hw.avm.cfg_reg = request_io(&cs->rs, card->para[1] + 0x1800, 8, "avm cfg");
if (!cs->hw.avm.cfg_reg) goto err;
cs->hw.avm.isac = request_io(&cs->rs, card->para[1] + 0x1400, 32, "HiSax isac");
......@@ -216,23 +216,24 @@ setup_avm_a1(struct IsdnCard *card)
printk(KERN_INFO "AVM A1: Byte at %x is %x\n",
cs->hw.avm.cfg_reg, val);
printk(KERN_INFO
"HiSax: %s config irq:%d cfg:0x%X\n",
CardType[cs->typ], cs->irq,
cs->hw.avm.cfg_reg);
printk(KERN_INFO
"HiSax: isac:0x%X/0x%X\n",
cs->hw.avm.isac + 32, cs->hw.avm.isacfifo);
printk(KERN_INFO
"HiSax: hscx A:0x%X/0x%X hscx B:0x%X/0x%X\n",
cs->hw.avm.hscx[0] + 32, cs->hw.avm.hscxfifo[0],
cs->hw.avm.hscx[1] + 32, cs->hw.avm.hscxfifo[1]);
cs->card_ops = &avm_a1_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err;
return 1;
return 0;
err:
hisax_release_resources(cs);
return 0;
return rc;
}
int __init
setup_avm_a1(struct IsdnCard *card)
{
char tmp[64];
strcpy(tmp, avm_revision);
printk(KERN_INFO "HiSax: AVM driver Rev. %s\n", HiSax_getrev(tmp));
if (avm_a1_probe(card->cs, card) < 0)
return 0;
return 1;
}
......@@ -215,20 +215,13 @@ static struct card_ops avm_a1p_ops = {
.irq_func = avm_a1p_interrupt,
};
int __devinit
setup_avm_a1_pcmcia(struct IsdnCard *card)
static int __init
avm_a1p_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
u8 model, vers;
struct IsdnCardState *cs = card->cs;
char tmp[64];
strcpy(tmp, avm_revision);
printk(KERN_INFO "HiSax: AVM A1 PCMCIA driver Rev. %s\n",
HiSax_getrev(tmp));
cs->hw.avm.cfg_reg = card->para[1];
cs->irq = card->para[0];
cs->hw.avm.cfg_reg = card->para[1];
outb(cs->hw.avm.cfg_reg+ASL1_OFFSET, ASL1_W_ENABLE_S0);
......@@ -244,11 +237,26 @@ setup_avm_a1_pcmcia(struct IsdnCard *card)
vers = bytein(cs->hw.avm.cfg_reg+VERREG_OFFSET);
printk(KERN_INFO "AVM A1 PCMCIA: io 0x%x irq %d model %d version %d\n",
cs->hw.avm.cfg_reg, cs->irq, model, vers);
cs->hw.avm.cfg_reg, cs->irq, model, vers);
cs->card_ops = &avm_a1p_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
return 0;
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
int __devinit
setup_avm_a1_pcmcia(struct IsdnCard *card)
{
char tmp[64];
strcpy(tmp, avm_revision);
printk(KERN_INFO "HiSax: AVM A1 PCMCIA driver Rev. %s\n",
HiSax_getrev(tmp));
if (avm_a1p_probe(card->cs, card))
return 0;
return 1;
}
......@@ -497,7 +497,7 @@ static struct bc_l1_ops hdlc_l1_ops = {
.close = close_hdlcstate,
};
void __init
static void __init
inithdlc(struct IsdnCardState *cs)
{
u_int val;
......@@ -596,6 +596,82 @@ static struct card_ops avm_pci_ops = {
.irq_func = avm_pcipnp_interrupt,
};
static int __init
avm_pcipnp_hw_init(struct IsdnCardState *cs)
{
cs->bc_hw_ops = &hdlc_hw_ops;
cs->bc_l1_ops = &hdlc_l1_ops;
cs->card_ops = &avm_pci_ops;
avm_pcipnp_reset(cs);
return isac_setup(cs, &isac_ops);
}
static int __init
avm_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
{
int rc;
u32 val;
printk(KERN_INFO "AVM PCI: defined at %#lx IRQ %u\n",
pci_resource_start(pdev, 1), pdev->irq);
rc = -EBUSY;
if (pci_enable_device(pdev))
goto err;
cs->subtyp = AVM_FRITZ_PCI;
cs->irq = pdev->irq;
cs->irq_flags |= SA_SHIRQ;
cs->hw.avm.cfg_reg = pci_resource_start(pdev, 1);
cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10;
if (!request_io(&cs->rs, cs->hw.avm.cfg_reg, 32, "avm PCI"))
goto err;
val = inl(cs->hw.avm.cfg_reg);
printk(KERN_INFO "AVM PCI: stat %#x\n", val);
printk(KERN_INFO "AVM PCI: Class %X Rev %d\n",
val & 0xff, (val>>8) & 0xff);
if (avm_pcipnp_hw_init(cs))
goto err;
return 0;
err:
hisax_release_resources(cs);
return rc;
}
static int __init
avm_pnp_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
int rc;
u8 val, ver;
printk(KERN_INFO "AVM PnP: defined at %#lx IRQ %lu\n",
card->para[1], card->para[0]);
cs->subtyp = AVM_FRITZ_PNP;
cs->irq = card->para[0];
cs->hw.avm.cfg_reg = card->para[1];
cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10;
rc = -EBUSY;
if (!request_io(&cs->rs, cs->hw.avm.cfg_reg, 32, "avm PnP"))
goto err;
val = inb(cs->hw.avm.cfg_reg);
ver = inb(cs->hw.avm.cfg_reg + 1);
printk(KERN_INFO "AVM PnP: Class %X Rev %d\n", val, ver);
if (avm_pcipnp_hw_init(cs))
goto err;
return 0;
err:
hisax_release_resources(cs);
return rc;
}
static struct pci_dev *dev_avm __initdata = NULL;
#ifdef __ISAPNP__
static struct pnp_card *card_avm __initdata = NULL;
......@@ -605,17 +681,15 @@ static struct pnp_dev *pnp_avm __initdata = NULL;
int __init
setup_avm_pcipnp(struct IsdnCard *card)
{
u_int val, ver;
struct IsdnCardState *cs = card->cs;
char tmp[64];
strcpy(tmp, avm_pci_rev);
printk(KERN_INFO "HiSax: AVM PCI driver Rev. %s\n", HiSax_getrev(tmp));
if (card->para[1]) {
/* old manual method */
cs->hw.avm.cfg_reg = card->para[1];
cs->irq = card->para[0];
cs->subtyp = AVM_FRITZ_PNP;
if (avm_pnp_probe(card->cs, card))
return 0;
return 1;
} else {
#ifdef __ISAPNP__
if (isapnp_present()) {
......@@ -647,69 +721,24 @@ setup_avm_pcipnp(struct IsdnCard *card)
pnp_device_detach(pnp_avm);
return(0);
}
cs->hw.avm.cfg_reg = pnp_port_start(pnp_avm, 0);
cs->irq = pnp_irq(pnp_avm, 0);
cs->subtyp = AVM_FRITZ_PNP;
goto ready;
card->para[1] = pnp_port_start(pnp_avm, 0);
card->para[0] = pnp_irq(pnp_avm, 0);
if (avm_pnp_probe(card->cs, card))
return 0;
return 1;
}
}
} else {
printk(KERN_INFO "FritzPnP: no ISA PnP present\n");
}
#endif
#if CONFIG_PCI
if ((dev_avm = pci_find_device(PCI_VENDOR_ID_AVM,
PCI_DEVICE_ID_AVM_A1, dev_avm))) {
cs->irq = dev_avm->irq;
if (!cs->irq) {
printk(KERN_ERR "FritzPCI: No IRQ for PCI card found\n");
return(0);
}
if (pci_enable_device(dev_avm))
return(0);
cs->hw.avm.cfg_reg = pci_resource_start(dev_avm, 1);
if (!cs->hw.avm.cfg_reg) {
printk(KERN_ERR "FritzPCI: No IO-Adr for PCI card found\n");
return(0);
}
cs->subtyp = AVM_FRITZ_PCI;
} else {
printk(KERN_WARNING "FritzPCI: No PCI card found\n");
return(0);
if (avm_pci_probe(card->cs, dev_avm))
return 0;
return 1;
}
cs->irq_flags |= SA_SHIRQ;
#endif /* CONFIG_PCI */
}
ready:
cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10;
if (!request_io(&cs->rs, cs->hw.avm.cfg_reg, 32,
cs->subtyp == AVM_FRITZ_PCI ? "avm PCI" : "avm PnP"))
goto err;
switch (cs->subtyp) {
case AVM_FRITZ_PCI:
val = inl(cs->hw.avm.cfg_reg);
printk(KERN_INFO "AVM PCI: stat %#x\n", val);
printk(KERN_INFO "AVM PCI: Class %X Rev %d\n",
val & 0xff, (val>>8) & 0xff);
break;
case AVM_FRITZ_PNP:
val = inb(cs->hw.avm.cfg_reg);
ver = inb(cs->hw.avm.cfg_reg + 1);
printk(KERN_INFO "AVM PnP: Class %X Rev %d\n", val, ver);
avm_pcipnp_reset(cs);
break;
}
printk(KERN_INFO "HiSax: %s config irq:%d base:0x%X\n",
(cs->subtyp == AVM_FRITZ_PCI) ? "AVM Fritz!PCI" : "AVM Fritz!PnP",
cs->irq, cs->hw.avm.cfg_reg);
cs->bc_hw_ops = &hdlc_hw_ops;
cs->bc_l1_ops = &hdlc_l1_ops;
cs->card_ops = &avm_pci_ops;
isac_setup(cs, &isac_ops);
return 1;
err:
hisax_release_resources(cs);
printk(KERN_WARNING "FritzPCI: No card found\n");
return 0;
}
......@@ -21,11 +21,11 @@
#include "bkm_ax.h"
extern const char *CardType[];
// FIXME needs per card lock
static spinlock_t bkm_a4t_lock = SPIN_LOCK_UNLOCKED;
const char *bkm_a4t_revision = "$Revision: 1.13.6.6 $";
static inline u8
readreg(unsigned int ale, unsigned long adr, u8 off)
{
......@@ -249,15 +249,57 @@ static struct card_ops bkm_a4t_ops = {
.irq_func = bkm_interrupt,
};
static int __init
bkm_a4t_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
{
I20_REGISTER_FILE *pI20_Regs;
int rc;
printk(KERN_INFO "BKM A4T: defined at %#lx IRQ %u\n",
pci_resource_start(pdev, 0), pdev->irq);
rc = -EBUSY;
if (pci_enable_device(pdev))
goto err;
cs->irq = pdev->irq;
cs->irq_flags |= SA_SHIRQ;
cs->hw.avm.cfg_reg = pci_resource_start(pdev, 1);
cs->hw.ax.base = (unsigned long)request_mmio(&cs->rs, pci_resource_start(pdev, 0), 4096, "Telekom A4T");
if (!cs->hw.ax.base)
goto err;
/* Check suspicious address */
// FIXME needs to use read[bl]
pI20_Regs = (I20_REGISTER_FILE *) (cs->hw.ax.base);
if ((pI20_Regs->i20IntStatus & 0x8EFFFFFF) != 0) {
printk(KERN_WARNING "HiSax: address %lx suspicious\n",
cs->hw.ax.base);
goto err;
}
cs->hw.ax.isac_adr = cs->hw.ax.base + PO_OFFSET;
cs->hw.ax.jade_adr = cs->hw.ax.base + PO_OFFSET;
cs->hw.ax.isac_ale = GCS_1;
cs->hw.ax.jade_ale = GCS_3;
reset_bkm(cs);
cs->card_ops = &bkm_a4t_ops;
isac_setup(cs, &isac_ops);
jade_setup(cs, &jade_ops);
return 0;
err:
hisax_release_resources(cs);
return rc;
}
static struct pci_dev *dev_a4t __initdata = NULL;
int __init
setup_bkm_a4t(struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
char tmp[64];
u_int pci_memaddr = 0, found = 0;
I20_REGISTER_FILE *pI20_Regs;
strcpy(tmp, bkm_a4t_revision);
printk(KERN_INFO "HiSax: T-Berkom driver Rev. %s\n", HiSax_getrev(tmp));
......@@ -268,49 +310,13 @@ setup_bkm_a4t(struct IsdnCard *card)
sub_vendor = dev_a4t->subsystem_vendor;
sub_sys = dev_a4t->subsystem_device;
if ((sub_sys == PCI_DEVICE_ID_BERKOM_A4T) && (sub_vendor == PCI_VENDOR_ID_BERKOM)) {
if (pci_enable_device(dev_a4t))
return(0);
found = 1;
pci_memaddr = pci_resource_start(dev_a4t, 0);
cs->irq = dev_a4t->irq;
break;
if (sub_sys == PCI_DEVICE_ID_BERKOM_A4T &&
sub_vendor == PCI_VENDOR_ID_BERKOM) {
if (bkm_a4t_probe(card->cs, dev_a4t))
return 0;
return 1;
}
}
if (!found) {
printk(KERN_WARNING "HiSax: %s: Card not found\n", CardType[card->typ]);
return (0);
}
if (!cs->irq) { /* IRQ range check ?? */
printk(KERN_WARNING "HiSax: %s: No IRQ\n", CardType[card->typ]);
return (0);
}
cs->hw.ax.base = (unsigned long)request_mmio(&cs->rs,pci_memaddr, 4096, "Telekom A4T");
if (!cs->hw.ax.base) {
printk(KERN_WARNING "HiSax: %s: No Memory base address\n", CardType[card->typ]);
return (0);
}
/* Check suspecious address */
pI20_Regs = (I20_REGISTER_FILE *) (cs->hw.ax.base);
if ((pI20_Regs->i20IntStatus & 0x8EFFFFFF) != 0) {
printk(KERN_WARNING "HiSax: %s address %lx-%lx suspecious\n",
CardType[card->typ], cs->hw.ax.base, cs->hw.ax.base + 4096);
hisax_release_resources(cs);
return (0);
}
cs->hw.ax.isac_adr = cs->hw.ax.base + PO_OFFSET;
cs->hw.ax.jade_adr = cs->hw.ax.base + PO_OFFSET;
cs->hw.ax.isac_ale = GCS_1;
cs->hw.ax.jade_ale = GCS_3;
printk(KERN_INFO "HiSax: %s: Card configured at 0x%lX IRQ %d\n",
CardType[card->typ], cs->hw.ax.base, cs->irq);
reset_bkm(cs);
cs->irq_flags |= SA_SHIRQ;
cs->card_ops = &bkm_a4t_ops;
isac_setup(cs, &isac_ops);
jade_setup(cs, &jade_ops);
return 1;
printk(KERN_WARNING "HiSax: %s: Card not found\n", CardType[card->typ]);
return 0;
}
......@@ -490,125 +490,36 @@ static int __init HiSax_setup(char *line)
__setup("hisax=", HiSax_setup);
#endif /* MODULES */
#if CARD_TELES0
extern int setup_teles0(struct IsdnCard *card);
#endif
#if CARD_TELES3
extern int setup_teles3(struct IsdnCard *card);
#endif
#if CARD_S0BOX
extern int setup_s0box(struct IsdnCard *card);
#endif
#if CARD_TELESPCI
extern int setup_telespci(struct IsdnCard *card);
#endif
#if CARD_AVM_A1
extern int setup_avm_a1(struct IsdnCard *card);
#endif
#if CARD_AVM_A1_PCMCIA
extern int setup_avm_a1_pcmcia(struct IsdnCard *card);
#endif
#if CARD_FRITZPCI
extern int setup_avm_pcipnp(struct IsdnCard *card);
#endif
#if CARD_ELSA
extern int setup_elsa(struct IsdnCard *card);
#endif
#if CARD_IX1MICROR2
extern int setup_ix1micro(struct IsdnCard *card);
#endif
#if CARD_DIEHLDIVA
extern int setup_diva(struct IsdnCard *card);
#endif
#if CARD_ASUSCOM
extern int setup_asuscom(struct IsdnCard *card);
#endif
#if CARD_TELEINT
extern int setup_TeleInt(struct IsdnCard *card);
#endif
#if CARD_SEDLBAUER
extern int setup_sedlbauer(struct IsdnCard *card);
#endif
#if CARD_SPORTSTER
extern int setup_sportster(struct IsdnCard *card);
#endif
#if CARD_MIC
extern int setup_mic(struct IsdnCard *card);
#endif
#if CARD_NETJET_S
extern int setup_netjet_s(struct IsdnCard *card);
#endif
#if CARD_HFCS
extern int setup_hfcs(struct IsdnCard *card);
#endif
#if CARD_HFC_PCI
extern int setup_hfcpci(struct IsdnCard *card);
#endif
#if CARD_HFC_SX
extern int setup_hfcsx(struct IsdnCard *card);
#endif
#if CARD_AMD7930
extern int setup_amd7930(struct IsdnCard *card);
#endif
#if CARD_NICCY
extern int setup_niccy(struct IsdnCard *card);
#endif
#if CARD_ISURF
extern int setup_isurf(struct IsdnCard *card);
#endif
#if CARD_HSTSAPHIR
extern int setup_saphir(struct IsdnCard *card);
#endif
#if CARD_TESTEMU
extern int setup_testemu(struct IsdnCard *card);
#endif
#if CARD_BKM_A4T
extern int setup_bkm_a4t(struct IsdnCard *card);
#endif
#if CARD_SCT_QUADRO
extern int setup_sct_quadro(struct IsdnCard *card);
#endif
#if CARD_GAZEL
extern int setup_gazel(struct IsdnCard *card);
#endif
#if CARD_W6692
extern int setup_w6692(struct IsdnCard *card);
#endif
#if CARD_NETJET_U
extern int setup_netjet_u(struct IsdnCard *card);
#endif
#if CARD_FN_ENTERNOW_PCI
extern int setup_enternow_pci(struct IsdnCard *card);
#endif
/*
* Find card with given driverId
......@@ -703,16 +614,16 @@ int jiftime(char *s, long mark)
return 8;
}
static u8 tmpbuf[HISAX_STATUS_BUFSIZE];
static char tmpbuf[HISAX_STATUS_BUFSIZE];
void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt,
void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt,
va_list args)
{
/* if head == NULL the fmt contains the full info */
unsigned long flags;
int count, i;
u8 *p;
char *p;
isdn_ctrl ic;
int len;
......@@ -727,7 +638,7 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt,
len = p - tmpbuf;
p = tmpbuf;
} else {
p = fmt;
p = (char *) fmt;
len = strlen(fmt);
}
if (!cs) {
......@@ -814,12 +725,6 @@ static void ll_unload(struct IsdnCardState *cs)
ic.command = ISDN_STAT_UNLOAD;
ic.driver = cs->myid;
cs->iif.statcallb(&ic);
if (cs->status_buf)
kfree(cs->status_buf);
cs->status_read = NULL;
cs->status_write = NULL;
cs->status_end = NULL;
kfree(cs->dlog);
}
static void closecard(int cardnr)
......@@ -893,59 +798,97 @@ static int __devinit init_card(struct IsdnCardState *cs)
return 3;
}
static struct IsdnCardState *
alloc_IsdnCardState(void)
{
struct IsdnCardState *cs;
cs = kmalloc(sizeof(*cs), GFP_ATOMIC); // FIXME
if (!cs)
goto err;
memset(cs, 0, sizeof(*cs));
cs->dlog = kmalloc(MAX_DLOG_SPACE, GFP_ATOMIC);
if (!cs->dlog)
goto err_cs;
cs->status_buf = kmalloc(HISAX_STATUS_BUFSIZE, GFP_ATOMIC);
if (!cs->status_buf)
goto err_dlog;
cs->rcvbuf = kmalloc(MAX_DFRAME_LEN_L1, GFP_ATOMIC);
if (!cs->rcvbuf)
goto err_status_buf;
cs->chanlimit = 2; /* maximum B-channel number */
cs->debug = L1_DEB_WARN;
cs->irq_flags = I4L_IRQ_FLAG;
cs->stlist = NULL;
cs->status_read = cs->status_buf;
cs->status_write = cs->status_buf;
cs->status_end = cs->status_buf + HISAX_STATUS_BUFSIZE - 1;
cs->rcvidx = 0;
cs->tx_skb = NULL;
cs->tx_cnt = 0;
cs->event = 0;
skb_queue_head_init(&cs->rq);
skb_queue_head_init(&cs->sq);
spin_lock_init(&cs->lock);
resources_init(&cs->rs);
return cs;
err_status_buf:
kfree(cs->status_buf);
err_dlog:
kfree(cs->dlog);
err_cs:
kfree(cs);
err:
return NULL;
}
static void
free_IsdnCardState(struct IsdnCardState *cs)
{
kfree(cs->rcvbuf);
kfree(cs->status_buf);
kfree(cs->dlog);
kfree(cs);
}
static int __devinit checkcard(int cardnr, char *id, int *busy_flag)
{
int ret = 0;
struct IsdnCard *card = cards + cardnr;
struct IsdnCardState *cs;
cs = kmalloc(sizeof(struct IsdnCardState), GFP_ATOMIC);
cs = alloc_IsdnCardState();
if (!cs) {
printk(KERN_WARNING
"HiSax: No memory for IsdnCardState(card %d)\n",
cardnr + 1);
goto out;
}
memset(cs, 0, sizeof(struct IsdnCardState));
card->cs = cs;
cs->chanlimit = 2; /* maximum B-channel number */
cs->logecho = 0; /* No echo logging */
cs->cardnr = cardnr;
cs->debug = L1_DEB_WARN;
cs->HW_Flags = 0;
cs->busy_flag = busy_flag;
cs->irq_flags = I4L_IRQ_FLAG;
#if TEI_PER_CARD
if (card->protocol == ISDN_PTYPE_NI1)
test_and_set_bit(FLG_TWO_DCHAN, &cs->HW_Flags);
#else
test_and_set_bit(FLG_TWO_DCHAN, &cs->HW_Flags);
#endif
cs->cardnr = cardnr;
cs->protocol = card->protocol;
cs->typ = card->typ;
cs->busy_flag = busy_flag;
if (card->typ <= 0 || card->typ > ISDN_CTYPE_COUNT) {
printk(KERN_WARNING
"HiSax: Card Type %d out of range\n", card->typ);
goto outf_cs;
}
if (!(cs->dlog = kmalloc(MAX_DLOG_SPACE, GFP_ATOMIC))) {
printk(KERN_WARNING
"HiSax: No memory for dlog(card %d)\n", cardnr + 1);
goto outf_cs;
}
if (!(cs->status_buf = kmalloc(HISAX_STATUS_BUFSIZE, GFP_ATOMIC))) {
printk(KERN_WARNING
"HiSax: No memory for status_buf(card %d)\n",
cardnr + 1);
goto outf_dlog;
}
cs->stlist = NULL;
cs->status_read = cs->status_buf;
cs->status_write = cs->status_buf;
cs->status_end = cs->status_buf + HISAX_STATUS_BUFSIZE - 1;
cs->typ = card->typ;
spin_lock_init(&cs->lock);
resources_init(&cs->rs);
SET_MODULE_OWNER(&cs->iif);
strcpy(cs->iif.id, id);
cs->iif.channels = 2;
......@@ -982,13 +925,13 @@ static int __devinit checkcard(int cardnr, char *id, int *busy_flag)
(card->protocol == ISDN_PTYPE_NI1) ? "NI1" :
"NONE", cs->iif.id, cs->myid);
switch (card->typ) {
#if CARD_TELES0
#ifdef CONFIG_HISAX_16_0
case ISDN_CTYPE_16_0:
case ISDN_CTYPE_8_0:
ret = setup_teles0(card);
break;
#endif
#if CARD_TELES3
#ifdef CONFIG_HISAX_16_3
case ISDN_CTYPE_16_3:
case ISDN_CTYPE_PNP:
case ISDN_CTYPE_TELESPCMCIA:
......@@ -996,32 +939,32 @@ static int __devinit checkcard(int cardnr, char *id, int *busy_flag)
ret = setup_teles3(card);
break;
#endif
#if CARD_S0BOX
#ifdef CONFIG_HISAX_S0BOX
case ISDN_CTYPE_S0BOX:
ret = setup_s0box(card);
break;
#endif
#if CARD_TELESPCI
#ifdef CONFIG_HISAX_TELESPCI
case ISDN_CTYPE_TELESPCI:
ret = setup_telespci(card);
break;
#endif
#if CARD_AVM_A1
#ifdef CONFIG_HISAX_AVM_A1
case ISDN_CTYPE_A1:
ret = setup_avm_a1(card);
break;
#endif
#if CARD_AVM_A1_PCMCIA
#ifdef CONFIG_HISAX_AVM_A1_PCMCIA
case ISDN_CTYPE_A1_PCMCIA:
ret = setup_avm_a1_pcmcia(card);
break;
#endif
#if CARD_FRITZPCI
#ifdef CONFIG_HISAX_FRITZPCI
case ISDN_CTYPE_FRITZPCI:
ret = setup_avm_pcipnp(card);
break;
#endif
#if CARD_ELSA
#ifdef CONFIG_HISAX_ELSA
case ISDN_CTYPE_ELSA:
case ISDN_CTYPE_ELSA_PNP:
case ISDN_CTYPE_ELSA_PCMCIA:
......@@ -1029,115 +972,115 @@ static int __devinit checkcard(int cardnr, char *id, int *busy_flag)
ret = setup_elsa(card);
break;
#endif
#if CARD_IX1MICROR2
#ifdef CONFIG_HISAX_IX1MICROR2
case ISDN_CTYPE_IX1MICROR2:
ret = setup_ix1micro(card);
break;
#endif
#if CARD_DIEHLDIVA
#ifdef CONFIG_HISAX_DIEHLDIVA
case ISDN_CTYPE_DIEHLDIVA:
ret = setup_diva(card);
break;
#endif
#if CARD_ASUSCOM
#ifdef CONFIG_HISAX_ASUSCOM
case ISDN_CTYPE_ASUSCOM:
ret = setup_asuscom(card);
break;
#endif
#if CARD_TELEINT
#ifdef CONFIG_HISAX_TELEINT
case ISDN_CTYPE_TELEINT:
ret = setup_TeleInt(card);
break;
#endif
#if CARD_SEDLBAUER
#ifdef CONFIG_HISAX_SEDLBAUER
case ISDN_CTYPE_SEDLBAUER:
case ISDN_CTYPE_SEDLBAUER_PCMCIA:
case ISDN_CTYPE_SEDLBAUER_FAX:
ret = setup_sedlbauer(card);
break;
#endif
#if CARD_SPORTSTER
#ifdef CONFIG_HISAX_SPORTSTER
case ISDN_CTYPE_SPORTSTER:
ret = setup_sportster(card);
break;
#endif
#if CARD_MIC
#ifdef CONFIG_HISAX_MIC
case ISDN_CTYPE_MIC:
ret = setup_mic(card);
break;
#endif
#if CARD_NETJET_S
#ifdef CONFIG_HISAX_NETJET
case ISDN_CTYPE_NETJET_S:
ret = setup_netjet_s(card);
break;
#endif
#if CARD_HFCS
#ifdef CONFIG_HISAX_HFCS
case ISDN_CTYPE_TELES3C:
case ISDN_CTYPE_ACERP10:
ret = setup_hfcs(card);
break;
#endif
#if CARD_HFC_PCI
#ifdef CONFIG_HISAX_HFC_PCI
case ISDN_CTYPE_HFC_PCI:
ret = setup_hfcpci(card);
break;
#endif
#if CARD_HFC_SX
#ifdef CONFIG_HISAX_HFC_SX
case ISDN_CTYPE_HFC_SX:
ret = setup_hfcsx(card);
break;
#endif
#if CARD_NICCY
#ifdef CONFIG_HISAX_NICCY
case ISDN_CTYPE_NICCY:
ret = setup_niccy(card);
break;
#endif
#if CARD_AMD7930
#ifdef CONFIG_HISAX_AMD7930
case ISDN_CTYPE_AMD7930:
ret = setup_amd7930(card);
break;
#endif
#if CARD_ISURF
#ifdef CONFIG_HISAX_ISURF
case ISDN_CTYPE_ISURF:
ret = setup_isurf(card);
break;
#endif
#if CARD_HSTSAPHIR
#ifdef CONFIG_HISAX_HSTSAPHIR
case ISDN_CTYPE_HSTSAPHIR:
ret = setup_saphir(card);
break;
#endif
#if CARD_TESTEMU
#ifdef CONFIG_HISAX_TESTEMU
case ISDN_CTYPE_TESTEMU:
ret = setup_testemu(card);
break;
#endif
#if CARD_BKM_A4T
#ifdef CONFIG_HISAX_BKM_A4T
case ISDN_CTYPE_BKM_A4T:
ret = setup_bkm_a4t(card);
break;
#endif
#if CARD_SCT_QUADRO
#ifdef CONFIG_HISAX_SCT_QUADRO
case ISDN_CTYPE_SCT_QUADRO:
ret = setup_sct_quadro(card);
break;
#endif
#if CARD_GAZEL
#ifdef CONFIG_HISAX_GAZEL
case ISDN_CTYPE_GAZEL:
ret = setup_gazel(card);
break;
#endif
#if CARD_W6692
#ifdef CONFIG_HISAX_W6692
case ISDN_CTYPE_W6692:
ret = setup_w6692(card);
break;
#endif
#if CARD_NETJET_U
#ifdef CONFIG_HISAX_NETJET_U
case ISDN_CTYPE_NETJET_U:
ret = setup_netjet_u(card);
break;
#endif
#if CARD_FN_ENTERNOW_PCI
#ifdef CONFIG_HISAX_ENTERNOW_PCI
case ISDN_CTYPE_ENTERNOW:
ret = setup_enternow_pci(card);
break;
......@@ -1156,19 +1099,6 @@ static int __devinit checkcard(int cardnr, char *id, int *busy_flag)
ll_unload(cs);
goto outf_cs;
}
if (!(cs->rcvbuf = kmalloc(MAX_DFRAME_LEN_L1, GFP_ATOMIC))) {
printk(KERN_WARNING "HiSax: No memory for isac rcvbuf\n");
ll_unload(cs);
goto outf_cs;
}
cs->rcvidx = 0;
cs->tx_skb = NULL;
cs->tx_cnt = 0;
cs->event = 0;
skb_queue_head_init(&cs->rq);
skb_queue_head_init(&cs->sq);
init_bcstate(cs, 0);
init_bcstate(cs, 1);
......@@ -1201,10 +1131,8 @@ static int __devinit checkcard(int cardnr, char *id, int *busy_flag)
ret = 1;
goto out;
outf_dlog:
kfree(cs->dlog);
outf_cs:
kfree(cs);
free_IsdnCardState(cs);
card->cs = NULL;
out:
return ret;
......@@ -1253,8 +1181,8 @@ int __devinit HiSax_inithardware(int *busy_flag)
i++;
} else {
printk(KERN_WARNING
"HiSax: Card %s not installed !\n",
CardType[cards[i].typ]);
"HiSax: Card type %d not installed !\n",
cards[i].typ);
HiSax_shiftcards(i);
nrcards--;
}
......
......@@ -362,7 +362,7 @@ diva_ipacx_pci_irq(int intno, void *dev_id, struct pt_regs *regs)
static void
diva_release(struct IsdnCardState *cs)
{
del_timer(&cs->hw.diva.tl);
del_timer_sync(&cs->hw.diva.tl);
if (cs->hw.diva.cfg_reg)
byteout(cs->hw.diva.ctrl, 0); /* LED off, Reset */
......@@ -515,6 +515,162 @@ static struct card_ops diva_ipacx_pci_ops = {
.irq_func = diva_ipacx_pci_irq,
};
static int __init
diva_ipac_probe(struct IsdnCardState *cs)
{
u8 val;
// request_io
val = readreg(cs->hw.diva.cfg_reg + DIVA_IPAC_ADR,
cs->hw.diva.cfg_reg + DIVA_IPAC_DATA, IPAC_ID);
printk(KERN_INFO "Diva: IPAC version %x\n", val);
return (val == 1 || val == 2);
}
static int __init
diva_ipac_isa_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
cs->subtyp = DIVA_IPAC_ISA;
cs->irq = card->para[0];
cs->hw.diva.cfg_reg = card->para[1];
cs->hw.diva.isac = card->para[1] + DIVA_IPAC_DATA;
cs->hw.diva.isac_adr = card->para[1] + DIVA_IPAC_ADR;
printk(KERN_INFO "Diva: %s card configured at %#lx IRQ %d\n",
"IPAC ISA", cs->hw.diva.cfg_reg, cs->irq);
if (!request_io(&cs->rs, cs->hw.diva.cfg_reg, 8, "diva isdn"))
goto err;
diva_ipac_isa_reset(cs);
cs->card_ops = &diva_ipac_isa_ops;
if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops))
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static int __init
diva_isac_isa_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
cs->subtyp = DIVA_ISA;
cs->irq = card->para[0];
cs->hw.diva.cfg_reg = card->para[1];
cs->hw.diva.ctrl = card->para[1] + DIVA_ISA_CTRL;
cs->hw.diva.isac = card->para[1] + DIVA_ISA_ISAC_DATA;
cs->hw.diva.hscx = card->para[1] + DIVA_HSCX_DATA;
cs->hw.diva.isac_adr = card->para[1] + DIVA_ISA_ISAC_ADR;
cs->hw.diva.hscx_adr = card->para[1] + DIVA_HSCX_ADR;
printk(KERN_INFO "Diva: %s card configured at %#lx IRQ %d\n",
"ISA", cs->hw.diva.cfg_reg, cs->irq);
if (!request_io(&cs->rs, cs->hw.diva.cfg_reg, 8, "diva isdn"))
goto err;
diva_reset(cs);
init_timer(&cs->hw.diva.tl);
cs->hw.diva.tl.function = (void *) diva_led_handler;
cs->hw.diva.tl.data = (long) cs;
cs->card_ops = &diva_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static int __init
diva_isa_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
int is_ipac;
cs->hw.diva.cfg_reg = card->para[1];
if (!request_io(&cs->rs, cs->hw.diva.cfg_reg, 8, "diva isdn"))
return -EBUSY;
is_ipac = diva_ipac_probe(cs);
hisax_release_resources(cs);
if (is_ipac)
return diva_ipac_isa_probe(cs, card);
else
return diva_isac_isa_probe(cs, card);
}
static int __init
diva_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
{
if (pci_enable_device(pdev))
goto err;
cs->subtyp = DIVA_PCI;
cs->irq = pdev->irq;
cs->irq_flags |= SA_SHIRQ;
cs->hw.diva.cfg_reg = pci_resource_start(pdev, 2);
cs->hw.diva.ctrl = cs->hw.diva.cfg_reg + DIVA_PCI_CTRL;
cs->hw.diva.isac = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_DATA;
cs->hw.diva.hscx = cs->hw.diva.cfg_reg + DIVA_HSCX_DATA;
cs->hw.diva.isac_adr = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_ADR;
cs->hw.diva.hscx_adr = cs->hw.diva.cfg_reg + DIVA_HSCX_ADR;
printk(KERN_INFO "Diva: %s card configured at %#lx IRQ %d\n",
"PCI", cs->hw.diva.cfg_reg, cs->irq);
printk(KERN_INFO "Diva: %s space at %#lx\n",
"PCI", cs->hw.diva.pci_cfg);
if (!request_io(&cs->rs, cs->hw.diva.cfg_reg, 32, "diva isdn"))
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static int __init
diva_ipac_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
{
if (pci_enable_device(pdev))
goto err;
cs->subtyp = DIVA_IPAC_PCI;
cs->irq = pdev->irq;
cs->irq_flags |= SA_SHIRQ;
cs->hw.diva.pci_cfg = (unsigned long)request_mmio(
&cs->rs, pci_resource_start(pdev, 0), 4096, "diva");
cs->hw.diva.cfg_reg = (unsigned long)request_mmio(
&cs->rs, pci_resource_start(pdev, 1), 4096, "diva");
printk(KERN_INFO "Diva: %s card configured at %#lx IRQ %d\n",
"IPAC PCI", cs->hw.diva.cfg_reg, cs->irq);
printk(KERN_INFO "Diva: %s space at %#lx\n",
"IPAC PCI", cs->hw.diva.pci_cfg);
diva_ipac_pci_reset(cs);
cs->card_ops = &diva_ipac_pci_ops;
if (ipac_setup(cs, &mem_ipac_dc_ops, &mem_ipac_bc_ops))
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static int __init
diva_ipacx_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
{
if (pci_enable_device(pdev))
goto err;
cs->subtyp = DIVA_IPACX_PCI;
cs->irq = pdev->irq;
cs->irq_flags |= SA_SHIRQ;
printk(KERN_INFO "Diva: %s card configured at %#lx IRQ %d\n",
"IPACX PCI", cs->hw.diva.cfg_reg, cs->irq);
printk(KERN_INFO "Diva: %s space at %#lx\n",
"IPACX PCI", cs->hw.diva.pci_cfg);
diva_ipacx_pci_reset(cs);
cs->card_ops = &diva_ipacx_pci_ops;
if (ipacx_setup(cs, &ipacx_dc_ops, &ipacx_bc_ops))
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static struct pci_dev *dev_diva __initdata = NULL;
static struct pci_dev *dev_diva_u __initdata = NULL;
static struct pci_dev *dev_diva201 __initdata = NULL;
......@@ -545,101 +701,60 @@ static struct isapnp_device_id *pdev = &diva_ids[0];
static struct pnp_card *pnp_c __devinitdata = NULL;
#endif
int __init
setup_diva(struct IsdnCard *card)
{
int bytecnt = 8;
u8 val;
struct IsdnCardState *cs = card->cs;
char tmp[64];
strcpy(tmp, Diva_revision);
printk(KERN_INFO "HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp));
if (card->para[1]) {
cs->hw.diva.ctrl_reg = 0;
cs->hw.diva.cfg_reg = card->para[1];
val = readreg(cs->hw.diva.cfg_reg + DIVA_IPAC_ADR,
cs->hw.diva.cfg_reg + DIVA_IPAC_DATA, IPAC_ID);
printk(KERN_INFO "Diva: IPAC version %x\n", val);
if ((val == 1) || (val==2)) {
cs->subtyp = DIVA_IPAC_ISA;
cs->hw.diva.ctrl = 0;
cs->hw.diva.isac = card->para[1] + DIVA_IPAC_DATA;
cs->hw.diva.hscx = card->para[1] + DIVA_IPAC_DATA;
cs->hw.diva.isac_adr = card->para[1] + DIVA_IPAC_ADR;
cs->hw.diva.hscx_adr = card->para[1] + DIVA_IPAC_ADR;
} else {
cs->subtyp = DIVA_ISA;
cs->hw.diva.ctrl = card->para[1] + DIVA_ISA_CTRL;
cs->hw.diva.isac = card->para[1] + DIVA_ISA_ISAC_DATA;
cs->hw.diva.hscx = card->para[1] + DIVA_HSCX_DATA;
cs->hw.diva.isac_adr = card->para[1] + DIVA_ISA_ISAC_ADR;
cs->hw.diva.hscx_adr = card->para[1] + DIVA_HSCX_ADR;
}
cs->irq = card->para[0];
} else {
if (diva_isa_probe(card->cs, card) < 0)
return 0;
return 1;
}
#ifdef __ISAPNP__
if (isapnp_present()) {
struct pnp_card *pb;
struct pnp_dev *pd;
while(pdev->card_vendor) {
if ((pb = pnp_find_card(pdev->card_vendor,
pdev->card_device,
pnp_c))) {
pnp_c = pb;
pd = NULL;
if ((pd = pnp_find_dev(pnp_c,
pdev->vendor,
pdev->function,
pd))) {
printk(KERN_INFO "HiSax: %s detected\n",
(char *)pdev->driver_data);
if (pnp_device_attach(pd) < 0) {
printk(KERN_ERR "Diva PnP: attach failed\n");
if (isapnp_present()) {
struct pnp_card *pb;
struct pnp_dev *pd;
while(pdev->card_vendor) {
if ((pb = pnp_find_card(pdev->card_vendor,
pdev->card_device, pnp_c))) {
pnp_c = pb;
pd = NULL;
if ((pd = pnp_find_dev(pnp_c,
pdev->vendor,
pdev->function,
pd))) {
printk(KERN_INFO "HiSax: %s detected\n",
(char *)pdev->driver_data);
if (pnp_device_attach(pd) < 0) {
printk(KERN_ERR "Diva PnP: attach failed\n");
return 0;
}
if (pnp_activate_dev(pd) < 0) {
printk(KERN_ERR "Diva PnP: activate failed\n");
pnp_device_detach(pd);
return 0;
}
if (!pnp_irq_valid(pd, 0) || !pnp_port_valid(pd, 0)) {
printk(KERN_ERR "Diva PnP:some resources are missing %ld/%lx\n",
pnp_irq(pd, 0), pnp_port_start(pd, 0));
pnp_device_detach(pd);
return(0);
}
card->para[1] = pnp_port_start(pd, 0);
card->para[0] = pnp_irq(pd, 0);
if (pdev->function == ISAPNP_FUNCTION(0xA1)) {
if (diva_ipac_isa_probe(cs->card, cs))
return 0;
}
if (pnp_activate_dev(pd) < 0) {
printk(KERN_ERR "Diva PnP: activate failed\n");
pnp_device_detach(pd);
return 1;
} else {
if (diva_isac_isa_probe(cs->card, cs))
return 0;
}
if (!pnp_irq_valid(pd, 0) || !pnp_port_valid(pd, 0)) {
printk(KERN_ERR "Diva PnP:some resources are missing %ld/%lx\n",
pnp_irq(pd, 0), pnp_port_start(pd, 0));
pnp_device_detach(pd);
return(0);
}
card->para[1] = pnp_port_start(pd, 0);
card->para[0] = pnp_irq(pd, 0);
cs->hw.diva.cfg_reg = card->para[1];
cs->irq = card->para[0];
if (pdev->function == ISAPNP_FUNCTION(0xA1)) {
cs->subtyp = DIVA_IPAC_ISA;
cs->hw.diva.ctrl = 0;
cs->hw.diva.isac =
card->para[1] + DIVA_IPAC_DATA;
cs->hw.diva.hscx =
card->para[1] + DIVA_IPAC_DATA;
cs->hw.diva.isac_adr =
card->para[1] + DIVA_IPAC_ADR;
cs->hw.diva.hscx_adr =
card->para[1] + DIVA_IPAC_ADR;
} else {
cs->subtyp = DIVA_ISA;
cs->hw.diva.ctrl =
card->para[1] + DIVA_ISA_CTRL;
cs->hw.diva.isac =
card->para[1] + DIVA_ISA_ISAC_DATA;
cs->hw.diva.hscx =
card->para[1] + DIVA_HSCX_DATA;
cs->hw.diva.isac_adr =
card->para[1] + DIVA_ISA_ISAC_ADR;
cs->hw.diva.hscx_adr =
card->para[1] + DIVA_HSCX_ADR;
}
goto ready;
return 1;
} else {
printk(KERN_ERR "Diva PnP: PnP error card found, no device\n");
return(0);
......@@ -652,111 +767,29 @@ setup_diva(struct IsdnCard *card)
printk(KERN_INFO "Diva PnP: no ISAPnP card found\n");
}
}
}
#endif
#if CONFIG_PCI
cs->subtyp = 0;
if ((dev_diva = pci_find_device(PCI_VENDOR_ID_EICON,
PCI_DEVICE_ID_EICON_DIVA20, dev_diva))) {
if (pci_enable_device(dev_diva))
return(0);
cs->subtyp = DIVA_PCI;
cs->irq = dev_diva->irq;
cs->hw.diva.cfg_reg = pci_resource_start(dev_diva, 2);
} else if ((dev_diva_u = pci_find_device(PCI_VENDOR_ID_EICON,
PCI_DEVICE_ID_EICON_DIVA20_U, dev_diva_u))) {
if (pci_enable_device(dev_diva_u))
return(0);
cs->subtyp = DIVA_PCI;
cs->irq = dev_diva_u->irq;
cs->hw.diva.cfg_reg = pci_resource_start(dev_diva_u, 2);
} else if ((dev_diva201 = pci_find_device(PCI_VENDOR_ID_EICON,
PCI_DEVICE_ID_EICON_DIVA201, dev_diva201))) {
if (pci_enable_device(dev_diva201))
return(0);
cs->subtyp = DIVA_IPAC_PCI;
cs->irq = dev_diva201->irq;
cs->hw.diva.pci_cfg = (unsigned long)request_mmio(&cs->rs, pci_resource_start(dev_diva201, 0), 4096, "diva");
cs->hw.diva.cfg_reg = (unsigned long)request_mmio(&cs->rs, pci_resource_start(dev_diva201, 1), 4096, "diva");
} else {
printk(KERN_WARNING "Diva: No PCI card found\n");
return(0);
}
if (!cs->irq) {
printk(KERN_WARNING "Diva: No IRQ for PCI card found\n");
goto err;
}
if (!cs->hw.diva.cfg_reg) {
printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n");
goto err;
}
cs->irq_flags |= SA_SHIRQ;
#endif /* CONFIG_PCI */
if ((cs->subtyp == DIVA_IPAC_PCI) ||
(cs->subtyp == DIVA_IPACX_PCI) ) {
cs->hw.diva.ctrl = 0;
cs->hw.diva.isac = 0;
cs->hw.diva.hscx = 0;
cs->hw.diva.isac_adr = 0;
cs->hw.diva.hscx_adr = 0;
bytecnt = 0;
} else {
cs->hw.diva.ctrl = cs->hw.diva.cfg_reg + DIVA_PCI_CTRL;
cs->hw.diva.isac = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_DATA;
cs->hw.diva.hscx = cs->hw.diva.cfg_reg + DIVA_HSCX_DATA;
cs->hw.diva.isac_adr = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_ADR;
cs->hw.diva.hscx_adr = cs->hw.diva.cfg_reg + DIVA_HSCX_ADR;
bytecnt = 32;
}
}
ready:
printk(KERN_INFO
"Diva: %s card configured at %#lx IRQ %d\n",
(cs->subtyp == DIVA_PCI) ? "PCI" :
(cs->subtyp == DIVA_ISA) ? "ISA" :
(cs->subtyp == DIVA_IPAC_ISA) ? "IPAC ISA" :
(cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI",
cs->hw.diva.cfg_reg, cs->irq);
if ((cs->subtyp == DIVA_IPAC_PCI) ||
(cs->subtyp == DIVA_IPACX_PCI) ||
(cs->subtyp == DIVA_PCI) )
printk(KERN_INFO "Diva: %s space at %#lx\n",
(cs->subtyp == DIVA_PCI) ? "PCI" :
(cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI",
cs->hw.diva.pci_cfg);
if ((cs->subtyp != DIVA_IPAC_PCI) &&
(cs->subtyp != DIVA_IPACX_PCI) ) {
if (!request_io(&cs->rs, cs->hw.diva.cfg_reg, bytecnt, "diva isdn"))
if ((dev_diva = pci_find_device(PCI_VENDOR_ID_EICON,
PCI_DEVICE_ID_EICON_DIVA20,
dev_diva))) {
if (diva_pci_probe(card->cs, dev_diva))
return 0;
return 1;
} else if ((dev_diva_u = pci_find_device(PCI_VENDOR_ID_EICON,
PCI_DEVICE_ID_EICON_DIVA20_U,
dev_diva_u))) {
if (diva_pci_probe(card->cs, dev_diva_u))
return 0;
return 1;
} else if ((dev_diva201 = pci_find_device(PCI_VENDOR_ID_EICON,
PCI_DEVICE_ID_EICON_DIVA201,
dev_diva201))) {
if (diva_ipac_pci_probe(card->cs, dev_diva201))
return 0;
return 1;
}
if (cs->subtyp == DIVA_IPAC_ISA) {
diva_ipac_isa_reset(cs);
cs->card_ops = &diva_ipac_isa_ops;
if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops))
goto err;
} else if (cs->subtyp == DIVA_IPAC_PCI) {
diva_ipac_pci_reset(cs);
cs->card_ops = &diva_ipac_pci_ops;
if (ipac_setup(cs, &mem_ipac_dc_ops, &mem_ipac_bc_ops))
goto err;
} else if (cs->subtyp == DIVA_IPACX_PCI) {
diva_ipacx_pci_reset(cs);
cs->card_ops = &diva_ipacx_pci_ops;
if (ipacx_setup(cs, &ipacx_dc_ops, &ipacx_bc_ops))
goto err;
} else { /* DIVA 2.0 */
diva_reset(cs);
cs->hw.diva.tl.function = (void *) diva_led_handler;
cs->hw.diva.tl.data = (long) cs;
init_timer(&cs->hw.diva.tl);
cs->card_ops = &diva_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err;
}
return 1;
err:
diva_release(cs);
printk(KERN_WARNING "Diva: No PCI card found\n");
#endif /* CONFIG_PCI */
return 0;
}
......@@ -690,7 +690,47 @@ static struct card_ops elsa_ipac_ops = {
.irq_func = elsa_interrupt_ipac,
};
static unsigned char
static void __init
elsa_arcofi_init(struct IsdnCardState *cs)
{
#if ARCOFI_USE
init_arcofi(cs);
#endif
}
static void __init
elsa_timer_init(struct IsdnCardState *cs)
{
cs->hw.elsa.tl.function = (void *) elsa_led_handler;
cs->hw.elsa.tl.data = (long) cs;
init_timer(&cs->hw.elsa.tl);
}
static int __init
elsa_timer_test(struct IsdnCardState *cs)
{
/* test timer */
byteout(cs->hw.elsa.trig, 0xff);
byteout(cs->hw.elsa.timer, 0);
if (!TimerRun(cs)) {
byteout(cs->hw.elsa.timer, 0); /* second attempt */
if (!TimerRun(cs)) {
printk(KERN_WARNING "Elsa: timer does not start\n");
goto err;
}
}
HZDELAY(10 * HZ / 1000); /* wait >=10 ms */
if (TimerRun(cs)) {
printk(KERN_WARNING "Elsa: timer does not run\n");
goto err;
}
printk(KERN_INFO "Elsa: timer OK; resetting card\n");
return 0;
err:
return -EBUSY;
}
static unsigned char __init
probe_elsa_adr(unsigned int adr, int typ)
{
int i, in1, in2, p16_1 = 0, p16_2 = 0, p8_1 = 0, p8_2 = 0, pc_1 = 0,
......@@ -699,15 +739,13 @@ probe_elsa_adr(unsigned int adr, int typ)
/* In case of the elsa pcmcia card, this region is in use,
reserved for us by the card manager. So we do not check it
here, it would fail. */
if (typ != ISDN_CTYPE_ELSA_PCMCIA && check_region(adr, 8)) {
printk(KERN_WARNING
"Elsa: Probing Port 0x%x: already in use\n",
adr);
return (0);
if (typ != ISDN_CTYPE_ELSA_PCMCIA && !request_region(adr, 8, "elsa")) {
printk(KERN_WARNING "Elsa: probing port 0x%x: in use\n", adr);
return 0;
}
for (i = 0; i < 16; i++) {
in1 = inb(adr + ELSA_CONFIG); /* 'toggelt' bei */
in2 = inb(adr + ELSA_CONFIG); /* jedem Zugriff */
in1 = inb(adr + ELSA_CONFIG); /* 'toggels' at */
in2 = inb(adr + ELSA_CONFIG); /* each access */
p16_1 += 0x04 & in1;
p16_2 += 0x04 & in2;
p8_1 += 0x02 & in1;
......@@ -717,6 +755,7 @@ probe_elsa_adr(unsigned int adr, int typ)
pfp_1 += 0x40 & in1;
pfp_2 += 0x40 & in2;
}
release_region(adr, 8);
printk(KERN_INFO "Elsa: Probing IO 0x%x", adr);
if (65 == ++p16_1 * ++p16_2) {
printk(" PCC-16/PCF found\n");
......@@ -736,18 +775,227 @@ probe_elsa_adr(unsigned int adr, int typ)
}
}
static unsigned int
probe_elsa(struct IsdnCardState *cs)
static int __init
elsa_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
int i;
unsigned int CARD_portlist[] =
{0x160, 0x170, 0x260, 0x360, 0};
for (i = 0; CARD_portlist[i]; i++) {
if ((cs->subtyp = probe_elsa_adr(CARD_portlist[i], cs->typ)))
u8 val;
int i, bytecnt = 8;
unsigned int CARD_portlist[] = {0x160, 0x170, 0x260, 0x360, 0};
cs->hw.elsa.base = card->para[0];
printk(KERN_INFO "Elsa: Microlink IO probing\n");
if (cs->hw.elsa.base) {
cs->subtyp = probe_elsa_adr(cs->hw.elsa.base, cs->typ);
if (!cs->subtyp) {
printk(KERN_WARNING "Elsa: no Microlink at %#lx\n",
cs->hw.elsa.base);
goto err;
}
} else {
for (i = 0; CARD_portlist[i]; i++) {
cs->subtyp = probe_elsa_adr(CARD_portlist[i], cs->typ);
if (cs->subtyp)
cs->hw.elsa.base = CARD_portlist[i];
break;
}
}
if (!cs->hw.elsa.base)
goto err;
cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG;
cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL;
cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE;
cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC;
cs->hw.elsa.itac = cs->hw.elsa.base + ELSA_ITAC;
cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX;
cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ;
cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER;
val = bytein(cs->hw.elsa.cfg);
if (cs->subtyp == ELSA_PC) {
const u8 CARD_IrqTab[8] = {7, 3, 5, 9, 0, 0, 0, 0};
cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PC) >> 2];
} else if (cs->subtyp == ELSA_PCC8) {
const u8 CARD_IrqTab[8] = {7, 3, 5, 9, 0, 0, 0, 0};
cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PCC8) >> 4];
} else {
const u8 CARD_IrqTab[8] = {15, 10, 15, 3, 11, 5, 11, 9};
cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX) >> 3];
}
val = bytein(cs->hw.elsa.ale) & ELSA_HW_RELEASE;
if (val < 3)
val |= 8;
val += 'A' - 3;
if (val == 'B' || val == 'C')
val ^= 1;
if ((cs->subtyp == ELSA_PCFPRO) && (val = 'G'))
val = 'C';
printk(KERN_INFO "Elsa: %s found at %#lx Rev.:%c IRQ %d\n",
Elsa_Types[cs->subtyp], cs->hw.elsa.base, val, cs->irq);
val = bytein(cs->hw.elsa.ale) & ELSA_S0_POWER_BAD;
if (val) {
printk(KERN_WARNING "Elsa: Microlink S0 bus power bad\n");
cs->hw.elsa.status |= ELSA_BAD_PWR;
}
return (CARD_portlist[i]);
switch (cs->subtyp) {
case ELSA_PCFPRO: bytecnt = 16; break;
}
if (!request_io(&cs->rs, cs->hw.elsa.base, bytecnt, "elsa isdn"))
goto err;
elsa_arcofi_init(cs);
elsa_timer_init(cs);
if (elsa_timer_test(cs))
goto err;
elsa_reset(cs);
cs->card_ops = &elsa_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err;
if (cs->subtyp == ELSA_PC) {
val = readitac(cs, ITAC_SYS);
printk(KERN_INFO "Elsa: ITAC version %s\n", ITACVer[val & 7]);
writeitac(cs, ITAC_ISEN, 0);
writeitac(cs, ITAC_RFIE, 0);
writeitac(cs, ITAC_XFIE, 0);
writeitac(cs, ITAC_SCIE, 0);
writeitac(cs, ITAC_STIE, 0);
}
return 0;
err:
elsa_release(cs);
return -EBUSY;
}
static int __init
elsa_qs_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
int bytecnt = 8;
cs->irq = card->para[0];
cs->hw.elsa.base = card->para[1];
cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG;
cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE;
cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC;
cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX;
cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ;
cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER;
cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL;
printk(KERN_INFO "Elsa: %s defined at %#lx IRQ %d\n",
Elsa_Types[cs->subtyp], cs->hw.elsa.base, cs->irq);
switch (cs->subtyp) {
case ELSA_QS3000: bytecnt = 16; break;
}
if (!request_io(&cs->rs, cs->hw.elsa.base, bytecnt, "elsa isdn"))
goto err;
elsa_arcofi_init(cs);
elsa_timer_init(cs);
if (elsa_timer_test(cs))
goto err;
elsa_reset(cs);
cs->card_ops = &elsa_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err;
return 0;
err:
elsa_release(cs);
return -EBUSY;
}
static int __init
elsa_qs1000_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
cs->subtyp = ELSA_QS1000;
return elsa_qs_probe(cs, card);
}
static int __init
elsa_qs3000_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
cs->subtyp = ELSA_QS3000;
return elsa_qs_probe(cs, card);
}
static int __init
elsa_pcmcia_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
u8 val;
cs->irq = card->para[0];
cs->hw.elsa.base = card->para[1];
cs->hw.elsa.ale = cs->hw.elsa.base + 0;
val = readreg(cs, cs->hw.elsa.base + 2, IPAC_ID);
if ((val == 1) || (val == 2)) { /* IPAC version 1.1/1.2 */
cs->subtyp = ELSA_PCMCIA_IPAC;
cs->hw.elsa.isac = cs->hw.elsa.base + 2;
} else {
cs->subtyp = ELSA_PCMCIA;
cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE_PCM;
cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC_PCM;
cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX;
}
cs->hw.elsa.timer = 0;
cs->hw.elsa.trig = 0;
cs->hw.elsa.ctrl = 0;
printk(KERN_INFO "Elsa: %s defined at %#lx IRQ %d\n",
Elsa_Types[cs->subtyp], cs->hw.elsa.base, cs->irq);
elsa_arcofi_init(cs);
elsa_reset(cs);
if (cs->subtyp == ELSA_PCMCIA_IPAC) {
cs->card_ops = &elsa_ipac_ops;
if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops))
goto err;
} else {
cs->card_ops = &elsa_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err;
}
return 0;
err:
elsa_release(cs);
return -EBUSY;
}
static int __init
elsa_qs_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev,
int subtyp)
{
int bytecnt = 2;
u8 pci_rev;
if (pci_enable_device(pdev))
goto err;
cs->subtyp = subtyp;
cs->irq = pdev->irq;
cs->irq_flags |= SA_SHIRQ;
cs->hw.elsa.cfg = pci_resource_start(pdev, 1);
cs->hw.elsa.base = pci_resource_start(pdev, 3);
pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev);
if (cs->hw.elsa.cfg & 0x80 && pci_rev == 1) {
printk(KERN_INFO "Elsa: PLX9050 rev1 workaround activated\n");
__set_bit(FLG_BUGGY_PLX9050, &cs->HW_Flags);
}
cs->hw.elsa.ale = cs->hw.elsa.base;
cs->hw.elsa.isac = cs->hw.elsa.base +1;
cs->hw.elsa.hscx = cs->hw.elsa.base +1;
printk(KERN_INFO "Elsa: %s defined at %#lx/%#x IRQ %d\n",
Elsa_Types[cs->subtyp], cs->hw.elsa.base, cs->hw.elsa.cfg,
cs->irq);
switch (cs->subtyp) {
case ELSA_QS3000PCI: bytecnt = 16; break;
}
if (!request_io(&cs->rs, cs->hw.elsa.base, bytecnt, "elsa isdn"))
goto err;
if (!request_io(&cs->rs, cs->hw.elsa.cfg, 0x80, "elsa isdn pci"))
goto err;
elsa_arcofi_init(cs);
elsa_timer_init(cs);
elsa_reset(cs);
cs->card_ops = &elsa_ipac_ops;
if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops))
goto err;
return 0;
err:
elsa_release(cs);
return -EBUSY;
}
static struct pci_dev *dev_qs1000 __devinitdata = NULL;
......@@ -771,83 +1019,21 @@ static struct pnp_card *pnp_c __devinitdata = NULL;
int __devinit
setup_elsa(struct IsdnCard *card)
{
int bytecnt;
u8 val, pci_rev;
struct IsdnCardState *cs = card->cs;
char tmp[64];
strcpy(tmp, Elsa_revision);
printk(KERN_INFO "HiSax: Elsa driver Rev. %s\n", HiSax_getrev(tmp));
cs->hw.elsa.ctrl_reg = 0;
cs->hw.elsa.status = 0;
cs->hw.elsa.MFlag = 0;
cs->subtyp = 0;
if (cs->typ == ISDN_CTYPE_ELSA) {
cs->hw.elsa.base = card->para[0];
printk(KERN_INFO "Elsa: Microlink IO probing\n");
if (cs->hw.elsa.base) {
if (!(cs->subtyp = probe_elsa_adr(cs->hw.elsa.base,
cs->typ))) {
printk(KERN_WARNING
"Elsa: no Elsa Microlink at %#lx\n",
cs->hw.elsa.base);
return (0);
}
} else
cs->hw.elsa.base = probe_elsa(cs);
if (cs->hw.elsa.base) {
cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG;
cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL;
cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE;
cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC;
cs->hw.elsa.itac = cs->hw.elsa.base + ELSA_ITAC;
cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX;
cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ;
cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER;
val = bytein(cs->hw.elsa.cfg);
if (cs->subtyp == ELSA_PC) {
const u8 CARD_IrqTab[8] =
{7, 3, 5, 9, 0, 0, 0, 0};
cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PC) >> 2];
} else if (cs->subtyp == ELSA_PCC8) {
const u8 CARD_IrqTab[8] =
{7, 3, 5, 9, 0, 0, 0, 0};
cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PCC8) >> 4];
} else {
const u8 CARD_IrqTab[8] =
{15, 10, 15, 3, 11, 5, 11, 9};
cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX) >> 3];
}
val = bytein(cs->hw.elsa.ale) & ELSA_HW_RELEASE;
if (val < 3)
val |= 8;
val += 'A' - 3;
if (val == 'B' || val == 'C')
val ^= 1;
if ((cs->subtyp == ELSA_PCFPRO) && (val = 'G'))
val = 'C';
printk(KERN_INFO
"Elsa: %s found at %#lx Rev.:%c IRQ %d\n",
Elsa_Types[cs->subtyp],
cs->hw.elsa.base,
val, cs->irq);
val = bytein(cs->hw.elsa.ale) & ELSA_S0_POWER_BAD;
if (val) {
printk(KERN_WARNING
"Elsa: Microlink S0 bus power bad\n");
cs->hw.elsa.status |= ELSA_BAD_PWR;
}
} else {
printk(KERN_WARNING
"No Elsa Microlink found\n");
return (0);
}
} else if (cs->typ == ISDN_CTYPE_ELSA_PNP) {
if (card->typ == ISDN_CTYPE_ELSA) {
if (elsa_probe(card->cs, card))
return 0;
return 1;
} else if (card->typ == ISDN_CTYPE_ELSA_PNP) {
#ifdef __ISAPNP__
if (!card->para[1] && isapnp_present()) {
struct pnp_card *pb;
struct pnp_dev *pd;
while(pdev->card_vendor) {
if ((pb = pnp_find_card(pdev->card_vendor,
pdev->card_device,
......@@ -878,10 +1064,15 @@ setup_elsa(struct IsdnCard *card)
}
card->para[1] = pnp_port_start(pd, 0);
card->para[0] = pnp_irq(pd, 0);
if (pdev->function == ISAPNP_FUNCTION(0x133))
cs->subtyp = ELSA_QS1000;
else
cs->subtyp = ELSA_QS3000;
if (pdev->function == ISAPNP_FUNCTION(0x133)) {
if (elsa_qs1000_probe(card->cs, card))
return 0;
return 1;
} else {
if (elsa_qs3000_probe(card->cs, card))
return 0;
return 1;
}
break;
} else {
printk(KERN_ERR "Elsa PnP: PnP error card found, no device\n");
......@@ -897,184 +1088,33 @@ setup_elsa(struct IsdnCard *card)
}
}
#endif
if (card->para[1] && card->para[0]) {
cs->hw.elsa.base = card->para[1];
cs->irq = card->para[0];
if (!cs->subtyp)
cs->subtyp = ELSA_QS1000;
} else {
printk(KERN_ERR "Elsa PnP: no parameter\n");
}
cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG;
cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE;
cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC;
cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX;
cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ;
cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER;
cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL;
printk(KERN_INFO
"Elsa: %s defined at %#lx IRQ %d\n",
Elsa_Types[cs->subtyp],
cs->hw.elsa.base,
cs->irq);
} else if (cs->typ == ISDN_CTYPE_ELSA_PCMCIA) {
cs->hw.elsa.base = card->para[1];
cs->irq = card->para[0];
cs->hw.elsa.ale = cs->hw.elsa.base + 0;
val = readreg(cs, cs->hw.elsa.base + 2, IPAC_ID);
if ((val == 1) || (val == 2)) { /* IPAC version 1.1/1.2 */
cs->subtyp = ELSA_PCMCIA_IPAC;
cs->hw.elsa.isac = cs->hw.elsa.base + 2;
cs->hw.elsa.hscx = cs->hw.elsa.base + 2;
} else {
cs->subtyp = ELSA_PCMCIA;
cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE_PCM;
cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC_PCM;
cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX;
}
cs->hw.elsa.timer = 0;
cs->hw.elsa.trig = 0;
cs->hw.elsa.ctrl = 0;
printk(KERN_INFO
"Elsa: %s defined at %#lx IRQ %d\n",
Elsa_Types[cs->subtyp],
cs->hw.elsa.base,
cs->irq);
} else if (cs->typ == ISDN_CTYPE_ELSA_PCI) {
if (elsa_qs1000_probe(card->cs, card))
return 0;
return 1;
} else if (card->typ == ISDN_CTYPE_ELSA_PCMCIA) {
if (elsa_pcmcia_probe(card->cs, card))
return 0;
return 1;
} else if (card->typ == ISDN_CTYPE_ELSA_PCI) {
#if CONFIG_PCI
cs->subtyp = 0;
if ((dev_qs1000 = pci_find_device(PCI_VENDOR_ID_ELSA,
PCI_DEVICE_ID_ELSA_MICROLINK, dev_qs1000))) {
if (pci_enable_device(dev_qs1000))
return(0);
cs->subtyp = ELSA_QS1000PCI;
cs->irq = dev_qs1000->irq;
cs->hw.elsa.cfg = pci_resource_start(dev_qs1000, 1);
cs->hw.elsa.base = pci_resource_start(dev_qs1000, 3);
pci_read_config_byte(dev_qs1000, PCI_REVISION_ID, &pci_rev);
if (elsa_qs_pci_probe(card->cs, dev_qs1000,
ELSA_QS1000PCI))
return 0;
return 1;
} else if ((dev_qs3000 = pci_find_device(PCI_VENDOR_ID_ELSA,
PCI_DEVICE_ID_ELSA_QS3000, dev_qs3000))) {
if (pci_enable_device(dev_qs3000))
return(0);
cs->subtyp = ELSA_QS3000PCI;
cs->irq = dev_qs3000->irq;
cs->hw.elsa.cfg = pci_resource_start(dev_qs3000, 1);
cs->hw.elsa.base = pci_resource_start(dev_qs3000, 3);
pci_read_config_byte(dev_qs1000, PCI_REVISION_ID, &pci_rev);
if (elsa_qs_pci_probe(card->cs, dev_qs3000,
ELSA_QS3000PCI))
return 0;
return 1;
} else {
printk(KERN_WARNING "Elsa: No PCI card found\n");
return(0);
}
if (!cs->irq) {
printk(KERN_WARNING "Elsa: No IRQ for PCI card found\n");
return(0);
return 0;
}
if (!(cs->hw.elsa.base && cs->hw.elsa.cfg)) {
printk(KERN_WARNING "Elsa: No IO-Adr for PCI card found\n");
return(0);
}
if (cs->hw.elsa.cfg & 0x80 && pci_rev == 1) {
printk(KERN_INFO "Elsa: PLX9050 rev1 workaround activated\n");
set_bit(FLG_BUGGY_PLX9050, &cs->HW_Flags);
}
cs->hw.elsa.ale = cs->hw.elsa.base;
cs->hw.elsa.isac = cs->hw.elsa.base +1;
cs->hw.elsa.hscx = cs->hw.elsa.base +1;
cs->hw.elsa.timer = 0;
cs->hw.elsa.trig = 0;
cs->irq_flags |= SA_SHIRQ;
printk(KERN_INFO
"Elsa: %s defined at %#lx/0x%x IRQ %d\n",
Elsa_Types[cs->subtyp],
cs->hw.elsa.base,
cs->hw.elsa.cfg,
cs->irq);
#endif /* CONFIG_PCI */
} else
return (0);
switch (cs->subtyp) {
case ELSA_PC:
case ELSA_PCC8:
case ELSA_PCC16:
case ELSA_QS1000:
case ELSA_PCMCIA:
case ELSA_PCMCIA_IPAC:
bytecnt = 8;
break;
case ELSA_PCFPRO:
case ELSA_PCF:
case ELSA_QS3000:
case ELSA_QS3000PCI:
bytecnt = 16;
break;
case ELSA_QS1000PCI:
bytecnt = 2;
break;
default:
printk(KERN_WARNING
"Unknown ELSA subtype %d\n", cs->subtyp);
return (0);
}
/* In case of the elsa pcmcia card, this region is in use,
reserved for us by the card manager. So we do not check it
here, it would fail. */
if (cs->typ != ISDN_CTYPE_ELSA_PCMCIA)
if (!request_io(&cs->rs, cs->hw.elsa.base, bytecnt, "elsa isdn"))
goto err;
if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI))
if (!request_io(&cs->rs, cs->hw.elsa.cfg, 0x80, "elsa isdn pci"))
goto err;
#if ARCOFI_USE
init_arcofi(cs);
#endif
cs->hw.elsa.tl.function = (void *) elsa_led_handler;
cs->hw.elsa.tl.data = (long) cs;
init_timer(&cs->hw.elsa.tl);
/* Teste Timer */
if (cs->hw.elsa.timer) {
byteout(cs->hw.elsa.trig, 0xff);
byteout(cs->hw.elsa.timer, 0);
if (!TimerRun(cs)) {
byteout(cs->hw.elsa.timer, 0); /* 2. Versuch */
if (!TimerRun(cs)) {
printk(KERN_WARNING
"Elsa: timer do not start\n");
goto err;
}
}
HZDELAY(1); /* wait >=10 ms */
if (TimerRun(cs)) {
printk(KERN_WARNING "Elsa: timer do not run down\n");
goto err;
}
printk(KERN_INFO "Elsa: timer OK; resetting card\n");
}
elsa_reset(cs);
if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI) || (cs->subtyp == ELSA_PCMCIA_IPAC)) {
cs->card_ops = &elsa_ipac_ops;
if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops))
goto err;
} else {
cs->card_ops = &elsa_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err;
}
if (cs->subtyp == ELSA_PC) {
val = readitac(cs, ITAC_SYS);
printk(KERN_INFO "Elsa: ITAC version %s\n", ITACVer[val & 7]);
writeitac(cs, ITAC_ISEN, 0);
writeitac(cs, ITAC_RFIE, 0);
writeitac(cs, ITAC_XFIE, 0);
writeitac(cs, ITAC_SCIE, 0);
writeitac(cs, ITAC_STIE, 0);
}
return 1;
err:
elsa_release(cs);
return 0;
}
......@@ -263,13 +263,65 @@ static struct card_ops enpci_ops = {
.irq_func = enpci_interrupt,
};
static int __init
enpci_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
{
if (pci_enable_device(pdev))
goto err;
cs->irq = pdev->irq;
cs->irq_flags |= SA_SHIRQ;
cs->hw.njet.base = pci_resource_start(pdev, 0);
if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "Fn_ISDN"))
goto err;
cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA;
cs->hw.njet.isac = cs->hw.njet.base + 0xC0; // Fenster zum AMD
/* Reset an */
cs->hw.njet.ctrl_reg = 0x07; // gendert von 0xff
OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
set_current_state(TASK_UNINTERRUPTIBLE);
/* 50 ms Pause */
schedule_timeout((50*HZ)/1000);
cs->hw.njet.ctrl_reg = 0x30; /* Reset Off and status read clear */
OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((10*HZ)/1000); /* Timeout 10ms */
cs->hw.njet.auxd = 0x00; // war 0xc0
cs->hw.njet.dmactrl = 0;
OutByte(cs->hw.njet.base + NETJET_AUXCTRL, ~TJ_AMD_IRQ);
OutByte(cs->hw.njet.base + NETJET_IRQMASK1, TJ_AMD_IRQ);
OutByte(cs->hw.njet.auxa, cs->hw.njet.auxd);
printk(KERN_INFO
"enter:now PCI: PCI card configured at 0x%lx IRQ %d\n",
cs->hw.njet.base, cs->irq);
reset_enpci(cs);
cs->hw.njet.last_is0 = 0;
cs->hw.njet.bc_activate = enpci_bc_activate;
cs->hw.njet.bc_deactivate = enpci_bc_deactivate;
amd7930_setup(cs, &amd7930_ops, &enpci_setIrqMask);
cs->card_ops = &enpci_ops;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static struct pci_dev *dev_netjet __initdata = NULL;
/* called by config.c */
int __init
setup_enternow_pci(struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
char tmp[64];
#ifdef __BIG_ENDIAN
......@@ -278,72 +330,22 @@ setup_enternow_pci(struct IsdnCard *card)
strcpy(tmp, enternow_pci_rev);
printk(KERN_INFO "HiSax: Formula-n Europe AG enter:now ISDN PCI driver Rev. %s\n", HiSax_getrev(tmp));
for ( ;; ) {
if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET,
PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) {
if (pci_enable_device(dev_netjet))
return(0);
cs->irq = dev_netjet->irq;
if (!cs->irq) {
printk(KERN_WARNING "enter:now PCI: No IRQ for PCI card found\n");
return(0);
}
cs->hw.njet.base = pci_resource_start(dev_netjet, 0);
if (!cs->hw.njet.base) {
printk(KERN_WARNING "enter:now PCI: No IO-Adr for PCI card found\n");
return(0);
}
/* checks Sub-Vendor ID because system crashes with Traverse-Card */
if ((dev_netjet->subsystem_vendor != 0x55) ||
(dev_netjet->subsystem_device != 0x02)) {
printk(KERN_WARNING "enter:now: You tried to load this driver with an incompatible TigerJet-card\n");
printk(KERN_WARNING "Use type=20 for Traverse NetJet PCI Card.\n");
return(0);
}
} else {
printk(KERN_WARNING "enter:now PCI: No PCI card found\n");
return(0);
dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET,
PCI_DEVICE_ID_TIGERJET_300, dev_netjet);
if (dev_netjet) {
if (dev_netjet->subsystem_vendor != 0x55 ||
dev_netjet->subsystem_device != 0x02) {
printk(KERN_WARNING "enter:now: You tried to load "
"this driver with an incompatible "
"TigerJet-card\n");
printk(KERN_WARNING "Use type=20 for Traverse "
"NetJet PCI Card.\n");
return 0;
}
cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA;
cs->hw.njet.isac = cs->hw.njet.base + 0xC0; // Fenster zum AMD
/* Reset an */
cs->hw.njet.ctrl_reg = 0x07; // gendert von 0xff
OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
set_current_state(TASK_UNINTERRUPTIBLE);
/* 50 ms Pause */
schedule_timeout((50*HZ)/1000);
cs->hw.njet.ctrl_reg = 0x30; /* Reset Off and status read clear */
OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((10*HZ)/1000); /* Timeout 10ms */
cs->hw.njet.auxd = 0x00; // war 0xc0
cs->hw.njet.dmactrl = 0;
OutByte(cs->hw.njet.base + NETJET_AUXCTRL, ~TJ_AMD_IRQ);
OutByte(cs->hw.njet.base + NETJET_IRQMASK1, TJ_AMD_IRQ);
OutByte(cs->hw.njet.auxa, cs->hw.njet.auxd);
break;
}
printk(KERN_INFO
"enter:now PCI: PCI card configured at 0x%lx IRQ %d\n",
cs->hw.njet.base, cs->irq);
if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "Fn_ISDN"))
if (enpci_probe(card->cs, dev_netjet))
return 1;
return 0;
reset_enpci(cs);
cs->hw.njet.last_is0 = 0;
cs->hw.njet.bc_activate = enpci_bc_activate;
cs->hw.njet.bc_deactivate = enpci_bc_deactivate;
amd7930_setup(cs, &amd7930_ops, &enpci_setIrqMask);
cs->irq_flags |= SA_SHIRQ;
cs->card_ops = &enpci_ops;
return 1;
}
printk(KERN_WARNING "enter:now PCI: No PCI card found\n");
return 0;
}
......@@ -294,60 +294,6 @@ gazel_init(struct IsdnCardState *cs)
inithscxisac(cs);
}
static int
r647_reserve_regions(struct IsdnCardState *cs)
{
int i, base = cs->hw.gazel.hscx[0];
for (i = 0; i < 0xc000; i += 0x1000) {
if (!request_io(&cs->rs, i + base, 16, "gazel"))
goto err;
}
if (!request_io(&cs->rs, 0xc000 + base, 1, "gazel"))
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static int
r685_reserve_regions(struct IsdnCardState *cs)
{
if (!request_io(&cs->rs, cs->hw.gazel.hscx[0], 0x100, "gazel"))
goto err;
if (!request_io(&cs->rs, cs->hw.gazel.cfg_reg, 0x80, "gazel"))
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static int
r742_reserve_regions(struct IsdnCardState *cs)
{
if (!request_io(&cs->rs, cs->hw.gazel.ipac, 0x8, "gazel"))
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static int
r753_reserve_regions(struct IsdnCardState *cs)
{
if (!request_io(&cs->rs, cs->hw.gazel.ipac, 0x8, "gazel"))
goto err;
if (!request_io(&cs->rs, cs->hw.gazel.cfg_reg, 0x80, "gazel"))
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static struct card_ops r647_ops = {
.init = gazel_init,
.reset = r647_reset,
......@@ -377,194 +323,213 @@ static struct card_ops r753_ops = {
};
static int __init
setup_gazelisa(struct IsdnCard *card, struct IsdnCardState *cs)
gazel647_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
printk(KERN_INFO "Gazel: ISA PnP card automatic recognition\n");
// we got an irq parameter, assume it is an ISA card
// R742 decodes address even in not started...
// R647 returns FF if not present or not started
// eventually needs improvment
cs->hw.gazel.ipac = card->para[1];
if (ipac_read(cs, IPAC_ID) == 1)
cs->subtyp = R742;
else
cs->subtyp = R647;
int i, base;
cs->subtyp = R647;
cs->irq = card->para[0];
cs->hw.gazel.cfg_reg = card->para[1] + 0xC000;
printk(KERN_INFO "Gazel: Card ISA R647/R648 found\n");
cs->dc.isac.adf2 = 0x87;
printk(KERN_INFO "Gazel: config irq:%d isac:0x%X cfg:0x%X\n",
cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg);
printk(KERN_INFO
"Gazel: hscx A:0x%X hscx B:0x%X\n",
cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]);
cs->hw.gazel.isac = card->para[1] + 0x8000;
cs->hw.gazel.hscx[0] = card->para[1];
cs->hw.gazel.hscx[1] = card->para[1] + 0x4000;
cs->irq = card->para[0];
cs->hw.gazel.isacfifo = cs->hw.gazel.isac;
cs->hw.gazel.hscxfifo[0] = cs->hw.gazel.hscx[0];
cs->hw.gazel.hscxfifo[1] = cs->hw.gazel.hscx[1];
switch (cs->subtyp) {
case R647:
printk(KERN_INFO "Gazel: Card ISA R647/R648 found\n");
cs->dc.isac.adf2 = 0x87;
printk(KERN_INFO
"Gazel: config irq:%d isac:0x%X cfg:0x%X\n",
cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg);
printk(KERN_INFO
"Gazel: hscx A:0x%X hscx B:0x%X\n",
cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]);
return r647_reserve_regions(cs);
case R742:
printk(KERN_INFO "Gazel: Card ISA R742 found\n");
printk(KERN_INFO
"Gazel: config irq:%d ipac:0x%X\n",
cs->irq, cs->hw.gazel.ipac);
return r742_reserve_regions(cs);
base = cs->hw.gazel.hscx[0];
for (i = 0; i < 0xc000; i += 0x1000) {
if (!request_io(&cs->rs, base + i, 16, "gazel"))
goto err;
}
if (!request_io(&cs->rs, 0xc000 + base, 1, "gazel"))
goto err;
cs->card_ops = &r647_ops;
if (hscxisac_setup(cs, &r647_isac_ops, &r647_hscx_ops))
goto err;
cs->card_ops->reset(cs);
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static struct pci_dev *dev_tel __initdata = NULL;
static int __init
setup_gazelpci(struct IsdnCardState *cs)
gazel742_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
u_int pci_ioaddr0 = 0, pci_ioaddr1 = 0;
u8 pci_irq = 0, found;
u_int nbseek, seekcard;
u8 pci_rev;
cs->subtyp = R742;
cs->irq = card->para[0];
cs->hw.gazel.cfg_reg = card->para[1] + 0xC000;
printk(KERN_WARNING "Gazel: PCI card automatic recognition\n");
printk(KERN_INFO "Gazel: Card ISA R742 found\n");
printk(KERN_INFO "Gazel: config irq:%d ipac:0x%X\n",
cs->irq, cs->hw.gazel.ipac);
found = 0;
if (!pci_present()) {
printk(KERN_WARNING "Gazel: No PCI bus present\n");
return 1;
}
seekcard = PCI_DEVICE_ID_PLX_R685;
for (nbseek = 0; nbseek < 3; nbseek++) {
if ((dev_tel = pci_find_device(PCI_VENDOR_ID_PLX, seekcard, dev_tel))) {
if (pci_enable_device(dev_tel))
return 1;
pci_irq = dev_tel->irq;
pci_ioaddr0 = pci_resource_start(dev_tel, 1);
pci_ioaddr1 = pci_resource_start(dev_tel, 2);
found = 1;
}
if (found)
break;
else {
switch (seekcard) {
case PCI_DEVICE_ID_PLX_R685:
seekcard = PCI_DEVICE_ID_PLX_R753;
break;
case PCI_DEVICE_ID_PLX_R753:
seekcard = PCI_DEVICE_ID_PLX_DJINN_ITOO;
break;
}
}
}
if (!found) {
printk(KERN_WARNING "Gazel: No PCI card found\n");
return -ENODEV;
}
if (!pci_irq) {
printk(KERN_WARNING "Gazel: No IRQ for PCI card found\n");
return -ENODEV;
}
cs->hw.gazel.pciaddr[0] = pci_ioaddr0;
cs->hw.gazel.pciaddr[1] = pci_ioaddr1;
pci_ioaddr1 &= 0xfffe;
cs->hw.gazel.cfg_reg = pci_ioaddr0 & 0xfffe;
cs->hw.gazel.ipac = pci_ioaddr1;
cs->hw.gazel.isac = pci_ioaddr1 + 0x80;
cs->hw.gazel.hscx[0] = pci_ioaddr1;
cs->hw.gazel.hscx[1] = pci_ioaddr1 + 0x40;
cs->hw.gazel.isacfifo = cs->hw.gazel.isac;
if (!request_io(&cs->rs, cs->hw.gazel.ipac, 0x8, "gazel"))
goto err;
cs->card_ops = &r742_ops;
if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops))
goto err;
cs->card_ops->reset(cs);
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static int __init
gazel685_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
{
if (pci_enable_device(pdev))
goto err;
cs->subtyp = R685;
cs->irq = pdev->irq;
cs->irq_flags |= SA_SHIRQ;
cs->hw.gazel.cfg_reg = pci_resource_start(pdev, 1);
cs->hw.gazel.isac = pci_resource_start(pdev, 2) + 0x80;
cs->hw.gazel.hscx[0] = pci_resource_start(pdev, 2);
cs->hw.gazel.hscx[1] = pci_resource_start(pdev, 2) + 0x40;
cs->hw.gazel.isacfifo = cs->hw.gazel.isac;
cs->hw.gazel.hscxfifo[0] = cs->hw.gazel.hscx[0];
cs->hw.gazel.hscxfifo[1] = cs->hw.gazel.hscx[1];
cs->irq = pci_irq;
cs->irq_flags |= SA_SHIRQ;
switch (seekcard) {
case PCI_DEVICE_ID_PLX_R685:
printk(KERN_INFO "Gazel: Card PCI R685 found\n");
cs->subtyp = R685;
cs->dc.isac.adf2 = 0x87;
printk(KERN_INFO
"Gazel: config irq:%d isac:0x%X cfg:0x%X\n",
cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg);
printk(KERN_INFO
"Gazel: hscx A:0x%X hscx B:0x%X\n",
cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]);
return r685_reserve_regions(cs);
case PCI_DEVICE_ID_PLX_R753:
case PCI_DEVICE_ID_PLX_DJINN_ITOO:
printk(KERN_INFO "Gazel: Card PCI R753 found\n");
cs->subtyp = R753;
printk(KERN_INFO
"Gazel: config irq:%d ipac:0x%X cfg:0x%X\n",
cs->irq, cs->hw.gazel.ipac, cs->hw.gazel.cfg_reg);
/*
* Erratum for PLX9050, revision 1:
* If bit 7 of BAR 0/1 is set, local config registers
* can not be read (write is okay)
*/
if (cs->hw.gazel.cfg_reg & 0x80) {
pci_read_config_byte(dev_tel, PCI_REVISION_ID, &pci_rev);
if (pci_rev == 1) {
printk(KERN_INFO "Gazel: PLX9050 rev1 workaround activated\n");
set_bit(FLG_BUGGY_PLX9050, &cs->HW_Flags);
}
cs->dc.isac.adf2 = 0x87;
if (!request_io(&cs->rs, cs->hw.gazel.hscx[0], 0x100, "gazel"))
goto err;
if (!request_io(&cs->rs, cs->hw.gazel.cfg_reg, 0x80, "gazel"))
goto err;
printk(KERN_INFO "Gazel: Card PCI R685 found\n");
printk(KERN_INFO "Gazel: config irq:%d isac:0x%X cfg:0x%X\n",
cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg);
printk(KERN_INFO "Gazel: hscx A:0x%X hscx B:0x%X\n",
cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]);
cs->card_ops = &r685_ops;
if (hscxisac_setup(cs, &r685_isac_ops, &r685_hscx_ops))
goto err;
cs->card_ops->reset(cs);
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static int __init
gazel753_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
{
u8 pci_rev;
if (pci_enable_device(pdev))
goto err;
cs->subtyp = R753;
cs->irq = pdev->irq;
cs->irq_flags |= SA_SHIRQ;
cs->hw.gazel.cfg_reg = pci_resource_start(pdev, 1);
cs->hw.gazel.ipac = pci_resource_start(pdev, 2);
if (!request_io(&cs->rs, cs->hw.gazel.ipac, 0x8, "gazel"))
goto err;
if (!request_io(&cs->rs, cs->hw.gazel.cfg_reg, 0x80, "gazel"))
goto err;
printk(KERN_INFO "Gazel: Card PCI R753 found\n");
printk(KERN_INFO "Gazel: config irq:%d ipac:0x%X cfg:0x%X\n",
cs->irq, cs->hw.gazel.ipac, cs->hw.gazel.cfg_reg);
/*
* Erratum for PLX9050, revision 1:
* If bit 7 of BAR 0/1 is set, local config registers
* can not be read (write is okay)
*/
if (cs->hw.gazel.cfg_reg & 0x80) {
pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev);
if (pci_rev == 1) {
printk(KERN_INFO "Gazel: PLX9050 rev1 workaround "
"activated\n");
__set_bit(FLG_BUGGY_PLX9050, &cs->HW_Flags);
}
return r753_reserve_regions(cs);
}
cs->card_ops = &r753_ops;
if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops))
goto err;
cs->card_ops->reset(cs);
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static struct pci_dev *dev_tel __initdata = NULL;
static u16 __initdata dev_id = PCI_DEVICE_ID_PLX_R685;
int __init
setup_gazel(struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
char tmp[64];
strcpy(tmp, gazel_revision);
printk(KERN_INFO "Gazel: Driver Revision %s\n", HiSax_getrev(tmp));
if (card->para[0]) {
if (setup_gazelisa(card, cs))
return (0);
} else {
if (setup_gazelpci(cs))
return (0);
printk(KERN_INFO "Gazel: ISA card automatic recognition\n");
// we got an irq parameter, assume it is an ISA card
// R742 decodes address even in not started...
// R647 returns FF if not present or not started
// eventually needs improvment
card->cs->hw.gazel.ipac = card->para[1];
if (ipac_read(card->cs, IPAC_ID) == 1) {
if (gazel742_probe(card->cs, card))
return 0;
} else {
if (gazel647_probe(card->cs, card))
return 0;
}
return 1;
}
switch (cs->subtyp) {
case R647:
case R685:
if (cs->subtyp == R647) {
cs->card_ops = &r647_ops;
if (hscxisac_setup(cs, &r647_isac_ops, &r647_hscx_ops))
goto err;
} else {
cs->card_ops = &r685_ops;
if (hscxisac_setup(cs, &r685_isac_ops, &r685_hscx_ops))
goto err;
for (;;) {
dev_tel = pci_find_device(PCI_VENDOR_ID_PLX, dev_id, dev_tel);
if (dev_tel) {
switch (dev_id) {
case PCI_DEVICE_ID_PLX_R685:
if (gazel685_probe(card->cs, dev_tel))
return 0;
return 1;
case PCI_DEVICE_ID_PLX_R753:
case PCI_DEVICE_ID_PLX_DJINN_ITOO:
if (gazel753_probe(card->cs, dev_tel))
return 0;
return 1;
}
}
cs->card_ops->reset(cs);
break;
case R742:
case R753:
if (cs->subtyp == R742) {
cs->card_ops = &r742_ops;
} else {
cs->card_ops = &r753_ops;
switch (dev_id) {
case PCI_DEVICE_ID_PLX_R685:
dev_id = PCI_DEVICE_ID_PLX_R753;
case PCI_DEVICE_ID_PLX_R753:
dev_id = PCI_DEVICE_ID_PLX_DJINN_ITOO;
default:
break;
}
if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops))
goto err;
cs->card_ops->reset(cs);
break;
}
return 1;
err:
hisax_release_resources(cs);
printk(KERN_WARNING "Gazel: No PCI card found\n");
return 0;
}
......@@ -1382,72 +1382,41 @@ static struct card_ops hfcpci_ops = {
};
/* this variable is used as card index when more than one cards are present */
static struct pci_dev *dev_hfcpci __initdata = NULL;
int __init
setup_hfcpci(struct IsdnCard *card)
static int __init
niccy_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev, int i)
{
struct IsdnCardState *cs = card->cs;
char tmp[64];
int i;
struct pci_dev *tmp_hfcpci = NULL;
int rc;
strcpy(tmp, hfcpci_revision);
printk(KERN_INFO "HiSax: HFC-PCI driver Rev. %s\n", HiSax_getrev(tmp));
cs->hw.hfcpci.int_s1 = 0;
cs->dc.hfcpci.ph_state = 0;
cs->hw.hfcpci.fifo = 255;
rc = -EBUSY;
if (pci_enable_device(pdev))
goto err;
i = 0;
while (id_list[i].vendor_id) {
tmp_hfcpci = pci_find_device(id_list[i].vendor_id,
id_list[i].device_id,
dev_hfcpci);
i++;
if (tmp_hfcpci) {
if (pci_enable_device(tmp_hfcpci))
continue;
pci_set_master(tmp_hfcpci);
if ((card->para[0]) && (card->para[0] != (tmp_hfcpci->resource[ 0].start & PCI_BASE_ADDRESS_IO_MASK)))
continue;
else
break;
}
}
pci_set_master(pdev);
cs->irq = pdev->irq;
cs->irq_flags |= SA_SHIRQ;
cs->hw.hfcpci.pdev = pdev;
cs->hw.hfcpci.pci_io = request_mmio(&cs->rs,
pci_resource_start(pdev, 1), 128,
"hfc_pci");
if (!cs->hw.hfcpci.pci_io)
goto err;
if (tmp_hfcpci) {
i--;
dev_hfcpci = tmp_hfcpci; /* old device */
cs->irq = dev_hfcpci->irq;
cs->hw.hfcpci.pdev = tmp_hfcpci;
if (!cs->irq) {
printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n");
return (0);
}
printk(KERN_INFO "HiSax: HFC-PCI card manufacturer: %s card name: %s\n", id_list[i].vendor_name, id_list[i].card_name);
} else {
printk(KERN_WARNING "HFC-PCI: No PCI card found\n");
return (0);
}
/* Allocate memory for FIFOS */
cs->hw.hfcpci.fifos = pci_alloc_consistent(tmp_hfcpci, 32768, &cs->hw.hfcpci.fifos_dma);
if (!cs->hw.hfcpci.fifos) {
printk(KERN_WARNING "HFC-PCI: Error allocating memory for FIFO!\n");
return 0;
}
rc = -ENOMEM;
cs->hw.hfcpci.fifos = pci_alloc_consistent(pdev, 32768,
&cs->hw.hfcpci.fifos_dma);
if (!cs->hw.hfcpci.fifos)
goto err;
pci_write_config_dword(cs->hw.hfcpci.pdev, 0x80,
(u_int)cs->hw.hfcpci.fifos_dma);
cs->hw.hfcpci.pci_io = request_mmio(&cs->rs, dev_hfcpci->resource[ 1].start, 256, "hfc_pci");
if (!cs->hw.hfcpci.pci_io)
goto err;
printk(KERN_INFO
"HFC-PCI: defined at mem %#x fifo %#x(%#x) IRQ %d HZ %d\n",
(u_int) cs->hw.hfcpci.pci_io,
(u_int) cs->hw.hfcpci.fifos,
(u_int) cs->hw.hfcpci.fifos_dma,
cs->irq, HZ);
printk(KERN_INFO "HiSax: HFC-PCI card manufacturer: %s name: %s\n",
id_list[i].vendor_name, id_list[i].card_name);
printk(KERN_INFO "HFC-PCI: defined at mem %#x fifo %#x(%#x) IRQ %d\n",
(u_int) cs->hw.hfcpci.pci_io, (u_int) cs->hw.hfcpci.fifos,
(u_int) cs->hw.hfcpci.fifos_dma, cs->irq);
printk("ChipID: %x\n", Read_hfc(cs, HFCPCI_CHIP_ID));
cs->hw.hfcpci.int_m2 = 0; /* disable alle interrupts */
cs->hw.hfcpci.int_m1 = 0;
......@@ -1456,17 +1425,46 @@ setup_hfcpci(struct IsdnCard *card)
/* At this point the needed PCI config is done */
/* fifos are still not enabled */
cs->irq_flags |= SA_SHIRQ;
init_timer(&cs->hw.hfcpci.timer);
cs->hw.hfcpci.timer.function = (void *) hfcpci_Timer;
cs->hw.hfcpci.timer.data = (long) cs;
init_timer(&cs->hw.hfcpci.timer);
hfcpci_reset(cs);
cs->auxcmd = &hfcpci_auxcmd;
cs->card_ops = &hfcpci_ops;
return 1;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
/* this variable is used as card index when more than one cards are present */
static struct pci_dev *dev_hfcpci __initdata = NULL;
int __init
setup_hfcpci(struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
char tmp[64];
int i;
struct pci_dev *tmp_hfcpci = NULL;
strcpy(tmp, hfcpci_revision);
printk(KERN_INFO "HiSax: HFC-PCI driver Rev. %s\n", HiSax_getrev(tmp));
cs->hw.hfcpci.int_s1 = 0;
cs->dc.hfcpci.ph_state = 0;
cs->hw.hfcpci.fifo = 255;
for (i = 0; id_list[i].vendor_id; i++) {
tmp_hfcpci = pci_find_device(id_list[i].vendor_id,
id_list[i].device_id,
dev_hfcpci);
if (!tmp_hfcpci)
continue;
if (niccy_pci_probe(card->cs, tmp_hfcpci, i) < 0)
return 0;
return 1;
}
return 0;
}
......@@ -1159,6 +1159,74 @@ static struct card_ops hfcsx_ops = {
.irq_func = hfcsx_interrupt,
};
static int __init
hfcsx_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
int rc;
char c;
cs->irq = card->para[0];
cs->hw.hfcsx.base = card->para[1] & 0xfffe;
cs->hw.hfcsx.fifo = 255;
cs->hw.hfcsx.int_s1 = 0;
cs->dc.hfcsx.ph_state = 0;
rc = -EBUSY;
if (!request_io(&cs->rs, cs->hw.hfcsx.base, 2, "HFCSX isdn"))
goto err;
rc = -ENODEV;
byteout(cs->hw.hfcsx.base, cs->hw.hfcsx.base & 0xFF);
byteout(cs->hw.hfcsx.base + 1, ((cs->hw.hfcsx.base >> 8) & 3) | 0x54);
udelay(10);
cs->hw.hfcsx.chip = Read_hfc(cs,HFCSX_CHIP_ID);
switch (cs->hw.hfcsx.chip >> 4) {
case 1:
c ='+';
break;
case 9:
c ='P';
break;
default:
printk(KERN_WARNING "HFC-SX: invalid chip id 0x%x\n",
cs->hw.hfcsx.chip >> 4);
goto err;
}
if (!ccd_sp_irqtab[cs->irq & 0xF]) {
printk(KERN_WARNING "HFC_SX: invalid irq %d specified\n",
cs->irq & 0xF);
goto err;
}
rc = -ENOMEM;
cs->hw.hfcsx.extra = kmalloc(sizeof(struct hfcsx_extra), GFP_ATOMIC);
if (!cs->hw.hfcsx.extra) {
printk(KERN_WARNING "HFC-SX: unable to allocate memory\n");
goto err;
}
printk(KERN_INFO "HFC-S%c chip detected at base 0x%x IRQ %d\n",
c, (u_int) cs->hw.hfcsx.base, cs->irq);
cs->hw.hfcsx.int_m2 = 0; /* disable alle interrupts */
cs->hw.hfcsx.int_m1 = 0;
Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2);
init_timer(&cs->hw.hfcsx.timer);
cs->hw.hfcsx.timer.function = (void *) hfcsx_Timer;
cs->hw.hfcsx.timer.data = (long) cs;
cs->hw.hfcsx.b_fifo_size = 0; /* fifo size still unknown */
cs->hw.hfcsx.cirm = ccd_sp_irqtab[cs->irq & 0xF]; /* RAM not eval. */
hfcsx_reset(cs);
cs->auxcmd = &hfcsx_auxcmd;
cs->card_ops = &hfcsx_ops;
return 0;
err:
hisax_release_resources(cs);
return rc;
}
#ifdef __ISAPNP__
static struct isapnp_device_id hfc_ids[] __initdata = {
{ ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2620),
......@@ -1174,7 +1242,6 @@ static struct pnp_card *pnp_c __devinitdata = NULL;
int __devinit
setup_hfcsx(struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
char tmp[64];
strcpy(tmp, hfcsx_revision);
......@@ -1227,62 +1294,7 @@ setup_hfcsx(struct IsdnCard *card)
}
}
#endif
cs->hw.hfcsx.base = card->para[1] & 0xfffe;
cs->irq = card->para[0];
cs->hw.hfcsx.int_s1 = 0;
cs->dc.hfcsx.ph_state = 0;
cs->hw.hfcsx.fifo = 255;
if (!request_io(&cs->rs, cs->hw.hfcsx.base, 2, "HFCSX isdn"))
if (hfcsx_probe(card->cs, card) < 0)
return 0;
byteout(cs->hw.hfcsx.base, cs->hw.hfcsx.base & 0xFF);
byteout(cs->hw.hfcsx.base + 1,
((cs->hw.hfcsx.base >> 8) & 3) | 0x54);
udelay(10);
cs->hw.hfcsx.chip = Read_hfc(cs,HFCSX_CHIP_ID);
switch (cs->hw.hfcsx.chip >> 4) {
case 1:
tmp[0] ='+';
break;
case 9:
tmp[0] ='P';
break;
default:
printk(KERN_WARNING "HFC-SX: invalid chip id 0x%x\n",
cs->hw.hfcsx.chip >> 4);
hisax_release_resources(cs);
return 0;
}
if (!ccd_sp_irqtab[cs->irq & 0xF]) {
printk(KERN_WARNING "HFC_SX: invalid irq %d specified\n",
cs->irq & 0xF);
hisax_release_resources(cs);
return 0;
}
cs->hw.hfcsx.extra = kmalloc(sizeof(struct hfcsx_extra),
GFP_ATOMIC);
if (!cs->hw.hfcsx.extra) {
hisax_release_resources(cs);
printk(KERN_WARNING "HFC-SX: unable to allocate memory\n");
return 0;
}
printk(KERN_INFO "HFC-S%c chip detected at base 0x%x IRQ %d HZ %d\n",
tmp[0], (u_int) cs->hw.hfcsx.base,
cs->irq, HZ);
cs->hw.hfcsx.int_m2 = 0; /* disable alle interrupts */
cs->hw.hfcsx.int_m1 = 0;
Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2);
cs->hw.hfcsx.timer.function = (void *) hfcsx_Timer;
cs->hw.hfcsx.timer.data = (long) cs;
cs->hw.hfcsx.b_fifo_size = 0; /* fifo size still unknown */
cs->hw.hfcsx.cirm = ccd_sp_irqtab[cs->irq & 0xF]; /* RAM not evaluated */
init_timer(&cs->hw.hfcsx.timer);
hfcsx_reset(cs);
cs->auxcmd = &hfcsx_auxcmd;
cs->card_ops = &hfcsx_ops;
return 1;
}
......@@ -133,6 +133,50 @@ static struct card_ops hfcs_ops = {
.irq_func = hfcs_interrupt,
};
static int __init
hfcs_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
cs->irq = card->para[0];
cs->hw.hfcD.addr = card->para[1];
if (!request_io(&cs->rs, cs->hw.hfcD.addr, 2, "HFCS isdn"))
goto err;
printk(KERN_INFO "HFCS: defined at 0x%x IRQ %d\n",
cs->hw.hfcD.addr, cs->irq);
cs->hw.hfcD.cip = 0;
cs->hw.hfcD.int_s1 = 0;
cs->hw.hfcD.send = NULL;
cs->bcs[0].hw.hfc.send = NULL;
cs->bcs[1].hw.hfc.send = NULL;
cs->hw.hfcD.dfifosize = 512;
cs->dc.hfcd.ph_state = 0;
cs->hw.hfcD.fifo = 255;
if (cs->typ == ISDN_CTYPE_TELES3C) {
cs->hw.hfcD.bfifosize = 1024 + 512;
/* Teles 16.3c IO ADR is 0x200 | YY0U (YY Bit 15/14 address) */
outb(0x00, cs->hw.hfcD.addr);
outb(0x56, cs->hw.hfcD.addr | 1);
} else if (cs->typ == ISDN_CTYPE_ACERP10) {
cs->hw.hfcD.bfifosize = 7*1024 + 512;
/* Acer P10 IO ADR is 0x300 */
outb(0x00, cs->hw.hfcD.addr);
outb(0x57, cs->hw.hfcD.addr | 1);
}
set_cs_func(cs);
init_timer(&cs->hw.hfcD.timer);
cs->hw.hfcD.timer.function = (void *) hfcs_Timer;
cs->hw.hfcD.timer.data = (long) cs;
hfcs_reset(cs);
cs->card_ops = &hfcs_ops;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
#ifdef __ISAPNP__
static struct isapnp_device_id hfc_ids[] __initdata = {
{ ISAPNP_VENDOR('A', 'N', 'X'), ISAPNP_FUNCTION(0x1114),
......@@ -166,7 +210,6 @@ static struct pnp_card *pnp_c __devinitdata = NULL;
int __init
setup_hfcs(struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
char tmp[64];
strcpy(tmp, hfcs_revision);
......@@ -220,42 +263,8 @@ setup_hfcs(struct IsdnCard *card)
}
}
#endif
cs->hw.hfcD.addr = card->para[1] & 0xfffe;
cs->irq = card->para[0];
cs->hw.hfcD.cip = 0;
cs->hw.hfcD.int_s1 = 0;
cs->hw.hfcD.send = NULL;
cs->bcs[0].hw.hfc.send = NULL;
cs->bcs[1].hw.hfc.send = NULL;
cs->hw.hfcD.dfifosize = 512;
cs->dc.hfcd.ph_state = 0;
cs->hw.hfcD.fifo = 255;
if (cs->typ == ISDN_CTYPE_TELES3C) {
cs->hw.hfcD.bfifosize = 1024 + 512;
} else if (cs->typ == ISDN_CTYPE_ACERP10) {
cs->hw.hfcD.bfifosize = 7*1024 + 512;
} else
return (0);
if (!request_io(&cs->rs, cs->hw.hfcD.addr, 2, "HFCS isdn"))
if (hfcs_probe(card->cs, card) < 0)
return 0;
printk(KERN_INFO
"HFCS: defined at 0x%x IRQ %d HZ %d\n",
cs->hw.hfcD.addr,
cs->irq, HZ);
if (cs->typ == ISDN_CTYPE_TELES3C) {
/* Teles 16.3c IO ADR is 0x200 | YY0U (YY Bit 15/14 address) */
outb(0x00, cs->hw.hfcD.addr);
outb(0x56, cs->hw.hfcD.addr | 1);
} else if (cs->typ == ISDN_CTYPE_ACERP10) {
/* Acer P10 IO ADR is 0x300 */
outb(0x00, cs->hw.hfcD.addr);
outb(0x57, cs->hw.hfcD.addr | 1);
}
set_cs_func(cs);
cs->hw.hfcD.timer.function = (void *) hfcs_Timer;
cs->hw.hfcD.timer.data = (long) cs;
init_timer(&cs->hw.hfcD.timer);
hfcs_reset(cs);
cs->card_ops = &hfcs_ops;
return (1);
return 1;
}
......@@ -782,7 +782,6 @@ struct bkm_hw {
struct gazel_hw {
unsigned int cfg_reg;
unsigned int pciaddr[2];
signed int ipac;
signed int isac;
signed int hscx[2];
......@@ -1073,264 +1072,17 @@ hisax_release_resources(struct IsdnCardState *cs);
#define ISDN_CTYPE_COUNT 41
#ifdef ISDN_CHIP_ISAC
#undef ISDN_CHIP_ISAC
#endif
#ifdef CONFIG_HISAX_16_0
#define CARD_TELES0 1
#ifndef ISDN_CHIP_ISAC
#define ISDN_CHIP_ISAC 1
#endif
#else
#define CARD_TELES0 0
#endif
#ifdef CONFIG_HISAX_16_3
#define CARD_TELES3 1
#ifndef ISDN_CHIP_ISAC
#define ISDN_CHIP_ISAC 1
#endif
#else
#define CARD_TELES3 0
#endif
#ifdef CONFIG_HISAX_TELESPCI
#define CARD_TELESPCI 1
#ifndef ISDN_CHIP_ISAC
#define ISDN_CHIP_ISAC 1
#endif
#else
#define CARD_TELESPCI 0
#endif
#ifdef CONFIG_HISAX_AVM_A1
#define CARD_AVM_A1 1
#ifndef ISDN_CHIP_ISAC
#define ISDN_CHIP_ISAC 1
#endif
#else
#define CARD_AVM_A1 0
#endif
#ifdef CONFIG_HISAX_AVM_A1_PCMCIA
#define CARD_AVM_A1_PCMCIA 1
#ifndef ISDN_CHIP_ISAC
#define ISDN_CHIP_ISAC 1
#endif
#else
#define CARD_AVM_A1_PCMCIA 0
#endif
#ifdef CONFIG_HISAX_FRITZPCI
#define CARD_FRITZPCI 1
#ifndef ISDN_CHIP_ISAC
#define ISDN_CHIP_ISAC 1
#endif
#else
#define CARD_FRITZPCI 0
#endif
#ifdef CONFIG_HISAX_ELSA
#define CARD_ELSA 1
#ifndef ISDN_CHIP_ISAC
#define ISDN_CHIP_ISAC 1
#endif
#else
#define CARD_ELSA 0
#endif
#ifdef CONFIG_HISAX_IX1MICROR2
#define CARD_IX1MICROR2 1
#ifndef ISDN_CHIP_ISAC
#define ISDN_CHIP_ISAC 1
#endif
#else
#define CARD_IX1MICROR2 0
#endif
#ifdef CONFIG_HISAX_DIEHLDIVA
#define CARD_DIEHLDIVA 1
#ifndef ISDN_CHIP_ISAC
#define ISDN_CHIP_ISAC 1
#endif
#else
#define CARD_DIEHLDIVA 0
#endif
#ifdef CONFIG_HISAX_ASUSCOM
#define CARD_ASUSCOM 1
#ifndef ISDN_CHIP_ISAC
#define ISDN_CHIP_ISAC 1
#endif
#else
#define CARD_ASUSCOM 0
#endif
#ifdef CONFIG_HISAX_TELEINT
#define CARD_TELEINT 1
#ifndef ISDN_CHIP_ISAC
#define ISDN_CHIP_ISAC 1
#endif
#else
#define CARD_TELEINT 0
#endif
#ifdef CONFIG_HISAX_SEDLBAUER
#define CARD_SEDLBAUER 1
#ifndef ISDN_CHIP_ISAC
#define ISDN_CHIP_ISAC 1
#endif
#else
#define CARD_SEDLBAUER 0
#endif
#ifdef CONFIG_HISAX_SPORTSTER
#define CARD_SPORTSTER 1
#ifndef ISDN_CHIP_ISAC
#define ISDN_CHIP_ISAC 1
#endif
#else
#define CARD_SPORTSTER 0
#endif
#ifdef CONFIG_HISAX_MIC
#define CARD_MIC 1
#ifndef ISDN_CHIP_ISAC
#define ISDN_CHIP_ISAC 1
#endif
#else
#define CARD_MIC 0
#endif
#ifdef CONFIG_HISAX_NETJET
#define CARD_NETJET_S 1
#ifndef ISDN_CHIP_ISAC
#define ISDN_CHIP_ISAC 1
#endif
#else
#define CARD_NETJET_S 0
#endif
#ifdef CONFIG_HISAX_HFCS
#define CARD_HFCS 1
#else
#define CARD_HFCS 0
#endif
#ifdef CONFIG_HISAX_HFC_PCI
#define CARD_HFC_PCI 1
#else
#define CARD_HFC_PCI 0
#endif
#ifdef CONFIG_HISAX_HFC_SX
#define CARD_HFC_SX 1
#else
#define CARD_HFC_SX 0
#endif
#ifdef CONFIG_HISAX_AMD7930
#define CARD_AMD7930 1
#else
#define CARD_AMD7930 0
#endif
#ifdef CONFIG_HISAX_NICCY
#define CARD_NICCY 1
#ifndef ISDN_CHIP_ISAC
#define ISDN_CHIP_ISAC 1
#endif
#else
#define CARD_NICCY 0
#endif
#ifdef CONFIG_HISAX_ISURF
#define CARD_ISURF 1
#ifndef ISDN_CHIP_ISAC
#define ISDN_CHIP_ISAC 1
#endif
#else
#define CARD_ISURF 0
#endif
#ifdef CONFIG_HISAX_S0BOX
#define CARD_S0BOX 1
#ifndef ISDN_CHIP_ISAC
#define ISDN_CHIP_ISAC 1
#endif
#else
#define CARD_S0BOX 0
#endif
#ifdef CONFIG_HISAX_HSTSAPHIR
#define CARD_HSTSAPHIR 1
#ifndef ISDN_CHIP_ISAC
#define ISDN_CHIP_ISAC 1
#endif
#else
#define CARD_HSTSAPHIR 0
#endif
#ifdef CONFIG_HISAX_TESTEMU
#define CARD_TESTEMU 1
#define ISDN_CTYPE_TESTEMU 99
#undef ISDN_CTYPE_COUNT
#define ISDN_CTYPE_COUNT ISDN_CTYPE_TESTEMU
#else
#define CARD_TESTEMU 0
#endif
#ifdef CONFIG_HISAX_BKM_A4T
#define CARD_BKM_A4T 1
#ifndef ISDN_CHIP_ISAC
#define ISDN_CHIP_ISAC 1
#endif
#else
#define CARD_BKM_A4T 0
#endif
#ifdef CONFIG_HISAX_SCT_QUADRO
#define CARD_SCT_QUADRO 1
#ifndef ISDN_CHIP_ISAC
#define ISDN_CHIP_ISAC 1
#endif
#else
#define CARD_SCT_QUADRO 0
#endif
#ifdef CONFIG_HISAX_GAZEL
#define CARD_GAZEL 1
#ifndef ISDN_CHIP_ISAC
#define ISDN_CHIP_ISAC 1
#endif
#else
#define CARD_GAZEL 0
#endif
#ifdef CONFIG_HISAX_W6692
#define CARD_W6692 1
#ifndef ISDN_CHIP_W6692
#define ISDN_CHIP_W6692 1
#endif
#else
#define CARD_W6692 0
#endif
#ifdef CONFIG_HISAX_NETJET_U
#define CARD_NETJET_U 1
#ifndef ISDN_CHIP_ICC
#define ISDN_CHIP_ICC 1
#endif
#ifndef HISAX_UINTERFACE
#define HISAX_UINTERFACE 1
#endif
#else
#define CARD_NETJET_U 0
#endif
#ifdef CONFIG_HISAX_ENTERNOW_PCI
#define CARD_FN_ENTERNOW_PCI 1
#endif
#define TEI_PER_CARD 1
......@@ -1402,7 +1154,7 @@ int jiftime(char *s, long mark);
int HiSax_command(isdn_ctrl * ic);
int HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb);
void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...);
void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, va_list args);
void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, va_list args);
void HiSax_reportcard(int cardnr, int sel);
int QuickHex(char *txt, u8 * p, int cnt);
void LogFrame(struct IsdnCardState *cs, u8 * p, int size);
......
......@@ -231,7 +231,7 @@ fcclassic_setup(struct fritz_adapter *adapter)
adapter->isac.write_isac = &fcclassic_write_isac;
adapter->isac.read_isac_fifo = &fcclassic_read_isac_fifo;
adapter->isac.write_isac_fifo = &fcclassic_write_isac_fifo;
isac_setup(&adapter->isac);
hisax_isac_setup(&adapter->isac);
for (i = 0; i < 2; i++) {
hscx_init(&adapter->hscx[i]);
adapter->hscx[i].priv = adapter;
......
......@@ -46,24 +46,22 @@ MODULE_PARM(debug, "i");
MODULE_AUTHOR("Kai Germaschewski <kai.germaschewski@gmx.de>/Karsten Keil <kkeil@suse.de>");
MODULE_DESCRIPTION("AVM Fritz!PCI/PnP ISDN driver");
// FIXME temporary hack until I sort out the new PnP stuff
#define __ISAPNP__
static struct pci_device_id fcpci_ids[] __devinitdata = {
{ PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1 , PCI_ANY_ID, PCI_ANY_ID,
0, 0, (unsigned long) "Fritz!Card PCI" },
{ PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1_V2, PCI_ANY_ID, PCI_ANY_ID,
0, 0, (unsigned long) "Fritz!Card PCI v2" },
{ }
{ .vendor = PCI_VENDOR_ID_AVM,
.device = PCI_DEVICE_ID_AVM_A1,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.driver_data = (unsigned long) "Fritz!Card PCI",
},
{ .vendor = PCI_VENDOR_ID_AVM,
.device = PCI_DEVICE_ID_AVM_A1_V2,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.driver_data = (unsigned long) "Fritz!Card PCI v2" },
{}
};
MODULE_DEVICE_TABLE(pci, fcpci_ids);
static struct pnp_card_device_id fcpnp_ids[] __devinitdata = {
{ .id = "AVM0900",
.driver_data = (unsigned long) "Fritz!Card PnP",
.devs = { { "AVM0900" } } }
};
MODULE_DEVICE_TABLE(pnp_card, fcpnp_ids);
MODULE_DEVICE_TABLE(pci, fcpci_ids);
static int protocol = 2; /* EURO-ISDN Default */
MODULE_PARM(protocol, "i");
......@@ -782,7 +780,7 @@ static int __devinit fcpcipnp_setup(struct fritz_adapter *adapter)
case AVM_FRITZ_PCI:
case AVM_FRITZ_PNP:
fcpci_init(adapter);
isac_setup(&adapter->isac);
hisax_isac_setup(&adapter->isac);
break;
}
val = adapter->read_hdlc_status(adapter, 0);
......@@ -908,10 +906,10 @@ static struct pci_driver fcpci_driver = {
.id_table = fcpci_ids,
};
#ifdef __ISAPNP__
#ifdef CONFIG_PNP_CARD
static int __devinit fcpnp_probe(struct pnp_card *card,
const struct pnp_card_device_id *card_id)
const struct pnp_card_id *card_id)
{
struct fritz_adapter *adapter;
struct pnp_dev *pnp_dev;
......@@ -957,6 +955,14 @@ static void __devexit fcpnp_remove(struct pnp_card *pcard)
delete_adapter(adapter);
}
static struct pnp_card_id fcpnp_ids[] __devinitdata = {
{ .id = "AVM0900",
.driver_data = (unsigned long) "Fritz!Card PnP",
.devs = { { "AVM0900" } },
},
{}
};
static struct pnpc_driver fcpnp_driver = {
.name = "fcpnp",
.probe = fcpnp_probe,
......@@ -968,7 +974,7 @@ static struct pnpc_driver fcpnp_driver = {
static int __init hisax_fcpcipnp_init(void)
{
int retval, pci_nr_found;
int retval = 0, pci_nr_found;
printk(KERN_INFO "hisax_fcpcipnp: Fritz!Card PCI/PCIv2/PnP ISDN driver v0.0.1\n");
......@@ -977,10 +983,8 @@ static int __init hisax_fcpcipnp_init(void)
goto out;
pci_nr_found = retval;
#ifdef __ISAPNP__
#ifdef CONFIG_PNP_CARD
retval = pnpc_register_driver(&fcpnp_driver);
#else
retval = 0;
#endif
if (retval < 0)
goto out_unregister_pci;
......@@ -988,14 +992,14 @@ static int __init hisax_fcpcipnp_init(void)
#if !defined(CONFIG_HOTPLUG) || defined(MODULE)
if (pci_nr_found + retval == 0) {
retval = -ENODEV;
goto out_unregister_isapnp;
goto out_unregister_pnp;
}
#endif
return 0;
#if !defined(CONFIG_HOTPLUG) || defined(MODULE)
out_unregister_isapnp:
#ifdef __ISAPNP__
out_unregister_pnp:
#ifdef CONFIG_PNP_CARD
pnpc_unregister_driver(&fcpnp_driver);
#endif
#endif
......@@ -1007,7 +1011,7 @@ static int __init hisax_fcpcipnp_init(void)
static void __exit hisax_fcpcipnp_exit(void)
{
#ifdef __ISAPNP__
#ifdef CONFIG_PNP_CARD
pnpc_unregister_driver(&fcpnp_driver);
#endif
pci_unregister_driver(&fcpci_driver);
......
......@@ -770,7 +770,7 @@ void isac_init(struct isac *isac)
FsmInitTimer(&isac->l1m, &isac->timer);
}
void isac_setup(struct isac *isac)
void hisax_isac_setup(struct isac *isac)
{
int val, eval;
......@@ -890,7 +890,7 @@ EXPORT_SYMBOL(isac_d_l2l1);
EXPORT_SYMBOL(isacsx_setup);
EXPORT_SYMBOL(isacsx_irq);
EXPORT_SYMBOL(isac_setup);
EXPORT_SYMBOL(hisax_isac_setup);
EXPORT_SYMBOL(isac_irq);
module_init(hisax_isac_init);
......
......@@ -36,7 +36,7 @@ struct isac {
void isac_init(struct isac *isac);
void isac_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg);
void isac_setup(struct isac *isac);
void hisax_isac_setup(struct isac *isac);
void isac_irq(struct isac *isac);
void isacsx_setup(struct isac *isac);
......
......@@ -126,7 +126,7 @@ static char *strL1Event[] =
};
void
debugl1(struct IsdnCardState *cs, char *fmt, ...)
debugl1(struct IsdnCardState *cs, const char *fmt, ...)
{
va_list args;
char tmp[8];
......
......@@ -28,7 +28,7 @@
#define B_LL_CONNECT 9
#define B_LL_OK 10
extern void debugl1(struct IsdnCardState *cs, char *fmt, ...);
extern void debugl1(struct IsdnCardState *cs, const char *fmt, ...);
extern void DChannel_proc_xmt(struct IsdnCardState *cs);
extern void DChannel_proc_rcv(struct IsdnCardState *cs);
extern void l1_msg(struct IsdnCardState *cs, int pr, void *arg);
......
......@@ -187,95 +187,92 @@ static struct card_ops isurf_ops = {
static struct pnp_card *pnp_surf __devinitdata = NULL;
#endif
int __init
setup_isurf(struct IsdnCard *card)
static int __init
isurf_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
unsigned long phymem;
char tmp[64];
strcpy(tmp, ISurf_revision);
printk(KERN_INFO "HiSax: ISurf driver Rev. %s\n", HiSax_getrev(tmp));
if (card->para[1] && card->para[2]) {
cs->hw.isurf.reset = card->para[1];
phymem = card->para[2];
cs->irq = card->para[0];
} else {
#ifdef __ISAPNP__
struct pnp_card *pb;
struct pnp_dev *pd;
phymem = card->para[2];
cs->hw.isurf.reset = card->para[1];
cs->irq = card->para[0];
if (isapnp_present()) {
cs->subtyp = 0;
if ((pb = pnp_find_card(
ISAPNP_VENDOR('S', 'I', 'E'),
ISAPNP_FUNCTION(0x0010), pnp_surf))) {
pnp_surf = pb;
pd = NULL;
if (!(pd = pnp_find_dev(pnp_surf,
ISAPNP_VENDOR('S', 'I', 'E'),
ISAPNP_FUNCTION(0x0010), pd))) {
printk(KERN_ERR "ISurfPnP: PnP error card found, no device\n");
return (0);
}
if (pnp_device_attach(pd) < 0) {
printk(KERN_ERR "ISurfPnP: attach failed\n");
return 0;
}
if (pnp_activate_dev(pd) < 0) {
printk(KERN_ERR "ISurfPnP: activate failed\n");
pnp_device_detach(pd);
return 0;
}
if (!pnp_irq_valid(pd, 0) || !pnp_port_valid(pd, 0) || !pnp_port_valid(pd, 1)) {
printk(KERN_ERR "ISurfPnP:some resources are missing %ld/%lx/%lx\n",
pnp_irq(pd, 0), pnp_port_start(pd, 0), pnp_port_start(pd, 1));
pnp_device_detach(pd);
return(0);
}
cs->hw.isurf.reset = pnp_port_start(pd, 0);
phymem = pnp_port_start(pd, 1);
cs->irq = pnp_irq(pd, 0);
} else {
printk(KERN_INFO "ISurfPnP: no ISAPnP card found\n");
return(0);
}
} else {
printk(KERN_INFO "ISurfPnP: no ISAPnP bus found\n");
return(0);
}
#else
printk(KERN_WARNING "HiSax: %s port/mem not set\n",
CardType[card->typ]);
return (0);
#endif
}
if (!request_io(&cs->rs, cs->hw.isurf.reset, 1, "isurf isdn"))
goto err;
cs->hw.isurf.isar = request_mmio(&cs->rs, phymem, ISURF_IOMEM_SIZE, "isurf iomem");
cs->hw.isurf.isar = request_mmio(&cs->rs, phymem, ISURF_IOMEM_SIZE,
"isurf iomem");
if (!cs->hw.isurf.isar)
goto err;
cs->hw.isurf.isac = cs->hw.isurf.isar + ISURF_ISAC_OFFSET;
printk(KERN_INFO
"ISurf: defined at 0x%x 0x%lx IRQ %d\n",
cs->hw.isurf.reset,
card->para[2],
cs->irq);
printk(KERN_INFO "ISurf: defined at 0x%x 0x%lx IRQ %d\n",
cs->hw.isurf.reset, phymem, cs->irq);
cs->auxcmd = &isurf_auxcmd;
cs->card_ops = &isurf_ops;
cs->bcs[0].hw.isar.reg = &cs->hw.isurf.isar_r;
cs->bcs[1].hw.isar.reg = &cs->hw.isurf.isar_r;
reset_isurf(cs, ISURF_RESET);
test_and_set_bit(HW_ISAR, &cs->HW_Flags);
__set_bit(HW_ISAR, &cs->HW_Flags);
isac_setup(cs, &isac_ops);
if (isar_setup(cs, &isar_ops))
goto err;
return 1;
return 0;
err:
hisax_release_resources(cs);
return 0;
return -EBUSY;
}
int __init
setup_isurf(struct IsdnCard *card)
{
char tmp[64];
strcpy(tmp, ISurf_revision);
printk(KERN_INFO "HiSax: ISurf driver Rev. %s\n", HiSax_getrev(tmp));
#ifdef __ISAPNP__
if (!card->para[1] || !card->para[2]) {
struct pnp_card *pb;
struct pnp_dev *pd;
cs->subtyp = 0;
if ((pb = pnp_find_card(
ISAPNP_VENDOR('S', 'I', 'E'),
ISAPNP_FUNCTION(0x0010), pnp_surf))) {
pnp_surf = pb;
pd = NULL;
if (!(pd = pnp_find_dev(pnp_surf,
ISAPNP_VENDOR('S', 'I', 'E'),
ISAPNP_FUNCTION(0x0010), pd))) {
printk(KERN_ERR "ISurfPnP: PnP error card found, no device\n");
return (0);
}
if (pnp_device_attach(pd) < 0) {
printk(KERN_ERR "ISurfPnP: attach failed\n");
return 0;
}
if (pnp_activate_dev(pd) < 0) {
printk(KERN_ERR "ISurfPnP: activate failed\n");
pnp_device_detach(pd);
return 0;
}
if (!pnp_irq_valid(pd, 0) || !pnp_port_valid(pd, 0) || !pnp_port_valid(pd, 1)) {
printk(KERN_ERR "ISurfPnP:some resources are missing %ld/%lx/%lx\n",
pnp_irq(pd, 0), pnp_port_start(pd, 0), pnp_port_start(pd, 1));
pnp_device_detach(pd);
return(0);
}
card->para[1] = pnp_port_start(pd, 0);
card->para[2] = pnp_port_start(pd, 1);
card->para[0] = pnp_irq(pd, 0);
} else {
printk(KERN_INFO "ISurfPnP: no ISAPnP card found\n");
return 0;
}
}
#endif
if (isurf_probe(card->cs, card) < 0)
return 0;
return 1;
}
......@@ -162,6 +162,29 @@ static struct card_ops ix1_ops = {
.irq_func = hscxisac_irq,
};
static int __init
ix1_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
cs->irq = card->para[0];
cs->hw.ix1.isac_ale = card->para[1] + ISAC_COMMAND_OFFSET;
cs->hw.ix1.isac = card->para[1] + ISAC_DATA_OFFSET;
cs->hw.ix1.hscx = card->para[1] + HSCX_DATA_OFFSET;
cs->hw.ix1.cfg_reg = card->para[1];
if (!request_io(&cs->rs, cs->hw.ix1.cfg_reg, 4, "ix1micro cfg"))
goto err;
printk(KERN_INFO "HiSax: %s config irq:%d io:0x%X\n",
CardType[cs->typ], cs->irq, cs->hw.ix1.cfg_reg);
ix1_reset(cs);
cs->card_ops = &ix1_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
#ifdef __ISAPNP__
static struct isapnp_device_id itk_ids[] __initdata = {
{ ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x25),
......@@ -181,14 +204,18 @@ static struct pnp_card *pnp_c __devinitdata = NULL;
int __init
setup_ix1micro(struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
char tmp[64];
strcpy(tmp, ix1_revision);
printk(KERN_INFO "HiSax: ITK IX1 driver Rev. %s\n", HiSax_getrev(tmp));
if (card->para[1]) {
if (ix1_probe(card->cs, card))
return 0;
return 1;
}
#ifdef __ISAPNP__
if (!card->para[1] && isapnp_present()) {
if (isapnp_present()) {
struct pnp_card *pb;
struct pnp_dev *pd;
......@@ -221,7 +248,9 @@ setup_ix1micro(struct IsdnCard *card)
}
card->para[1] = pnp_port_start(pd, 0);
card->para[0] = pnp_irq(pd, 0);
break;
if (ix1_probe(card->cs, card))
return 0;
return 1;
} else {
printk(KERN_ERR "ITK PnP: PnP error card found, no device\n");
}
......@@ -231,27 +260,8 @@ setup_ix1micro(struct IsdnCard *card)
}
if (!idev->card_vendor) {
printk(KERN_INFO "ITK PnP: no ISAPnP card found\n");
return(0);
}
}
#endif
/* IO-Ports */
cs->hw.ix1.isac_ale = card->para[1] + ISAC_COMMAND_OFFSET;
cs->hw.ix1.isac = card->para[1] + ISAC_DATA_OFFSET;
cs->hw.ix1.hscx = card->para[1] + HSCX_DATA_OFFSET;
cs->hw.ix1.cfg_reg = card->para[1];
cs->irq = card->para[0];
if (!request_io(&cs->rs, cs->hw.ix1.cfg_reg, 4, "ix1micro cfg"))
goto err;
printk(KERN_INFO "HiSax: %s config irq:%d io:0x%X\n",
CardType[cs->typ], cs->irq, cs->hw.ix1.cfg_reg);
ix1_reset(cs);
cs->card_ops = &ix1_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err;
return 1;
err:
hisax_release_resources(cs);
return 0;
}
......@@ -138,17 +138,11 @@ static struct card_ops mic_ops = {
.irq_func = hscxisac_irq,
};
int __init
setup_mic(struct IsdnCard *card)
static int __init
mic_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
char tmp[64];
strcpy(tmp, mic_revision);
printk(KERN_INFO "HiSax: mic driver Rev. %s\n", HiSax_getrev(tmp));
cs->hw.mic.cfg_reg = card->para[1];
cs->irq = card->para[0];
cs->hw.mic.cfg_reg = card->para[1];
cs->hw.mic.adr = cs->hw.mic.cfg_reg + MIC_ADR;
cs->hw.mic.isac = cs->hw.mic.cfg_reg + MIC_ISAC;
cs->hw.mic.hscx = cs->hw.mic.cfg_reg + MIC_HSCX;
......@@ -158,11 +152,25 @@ setup_mic(struct IsdnCard *card)
printk(KERN_INFO "mic: defined at 0x%x IRQ %d\n",
cs->hw.mic.cfg_reg, cs->irq);
cs->card_ops = &mic_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err;
return 1;
return 0;
err:
hisax_release_resources(cs);
return 0;
return -EBUSY;
}
int __init
setup_mic(struct IsdnCard *card)
{
char tmp[64];
strcpy(tmp, mic_revision);
printk(KERN_INFO "HiSax: mic driver Rev. %s\n", HiSax_getrev(tmp));
if (mic_probe(card->cs, card) < 0)
return 0;
return 1;
}
......@@ -199,6 +199,70 @@ static struct card_ops niccy_ops = {
.irq_func = niccy_interrupt,
};
static int __init
niccy_probe(struct IsdnCardState *cs)
{
printk(KERN_INFO "HiSax: %s %s config irq:%d data:0x%X ale:0x%X\n",
CardType[cs->typ], (cs->subtyp==1) ? "PnP":"PCI",
cs->irq, cs->hw.niccy.isac, cs->hw.niccy.isac_ale);
cs->card_ops = &niccy_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
return -EBUSY;
return 0;
}
static int __init
niccy_pnp_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
cs->subtyp = NICCY_PNP;
cs->irq = card->para[0];
cs->hw.niccy.isac = card->para[1] + ISAC_PNP;
cs->hw.niccy.hscx = card->para[1] + HSCX_PNP;
cs->hw.niccy.isac_ale = card->para[2] + ISAC_PNP;
cs->hw.niccy.hscx_ale = card->para[2] + HSCX_PNP;
cs->hw.niccy.cfg_reg = 0;
if (!request_io(&cs->rs, cs->hw.niccy.isac, 2, "niccy data"))
goto err;
if (!request_io(&cs->rs, cs->hw.niccy.isac_ale, 2, "niccy addr"))
goto err;
if (niccy_probe(cs) < 0)
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static int __init
niccy_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
{
u32 pci_ioaddr;
if (pci_enable_device(pdev))
goto err;
cs->subtyp = NICCY_PCI;
cs->irq = pdev->irq;
cs->irq_flags |= SA_SHIRQ;
cs->hw.niccy.cfg_reg = pci_resource_start(pdev, 0);
pci_ioaddr = pci_resource_start(pdev, 1);
cs->hw.niccy.isac = pci_ioaddr + ISAC_PCI_DATA;
cs->hw.niccy.isac_ale = pci_ioaddr + ISAC_PCI_ADDR;
cs->hw.niccy.hscx = pci_ioaddr + HSCX_PCI_DATA;
cs->hw.niccy.hscx_ale = pci_ioaddr + HSCX_PCI_ADDR;
if (!request_io(&cs->rs, cs->hw.niccy.isac, 4, "niccy"))
goto err;
if (!request_io(&cs->rs, cs->hw.niccy.cfg_reg, 0x40, "niccy pci"))
goto err;
if (niccy_probe(cs) < 0)
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static struct pci_dev *niccy_dev __initdata = NULL;
#ifdef __ISAPNP__
static struct pnp_card *pnp_c __devinitdata = NULL;
......@@ -207,7 +271,6 @@ static struct pnp_card *pnp_c __devinitdata = NULL;
int __init
setup_niccy(struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
char tmp[64];
strcpy(tmp, niccy_revision);
......@@ -252,66 +315,18 @@ setup_niccy(struct IsdnCard *card)
}
#endif
if (card->para[1]) {
cs->hw.niccy.isac = card->para[1] + ISAC_PNP;
cs->hw.niccy.hscx = card->para[1] + HSCX_PNP;
cs->hw.niccy.isac_ale = card->para[2] + ISAC_PNP;
cs->hw.niccy.hscx_ale = card->para[2] + HSCX_PNP;
cs->hw.niccy.cfg_reg = 0;
cs->subtyp = NICCY_PNP;
cs->irq = card->para[0];
if (!request_io(&cs->rs, cs->hw.niccy.isac, 2, "niccy data"))
goto err;
if (!request_io(&cs->rs, cs->hw.niccy.isac_ale, 2, "niccy addr"))
goto err;
if (niccy_pnp_probe(card->cs, card) < 0)
return 0;
return 1;
} else {
#if CONFIG_PCI
u_int pci_ioaddr;
cs->subtyp = 0;
if ((niccy_dev = pci_find_device(PCI_VENDOR_ID_SATSAGEM,
PCI_DEVICE_ID_SATSAGEM_NICCY, niccy_dev))) {
if (pci_enable_device(niccy_dev))
return(0);
/* get IRQ */
if (!niccy_dev->irq) {
printk(KERN_WARNING "Niccy: No IRQ for PCI card found\n");
return(0);
}
cs->irq = niccy_dev->irq;
cs->hw.niccy.cfg_reg = pci_resource_start(niccy_dev, 0);
if (!cs->hw.niccy.cfg_reg) {
printk(KERN_WARNING "Niccy: No IO-Adr for PCI cfg found\n");
return(0);
}
pci_ioaddr = pci_resource_start(niccy_dev, 1);
if (!pci_ioaddr) {
printk(KERN_WARNING "Niccy: No IO-Adr for PCI card found\n");
return(0);
}
cs->subtyp = NICCY_PCI;
} else {
printk(KERN_WARNING "Niccy: No PCI card found\n");
return(0);
if (niccy_pci_probe(card->cs, niccy_dev) < 0)
return 0;
return 1;
}
cs->irq_flags |= SA_SHIRQ;
cs->hw.niccy.isac = pci_ioaddr + ISAC_PCI_DATA;
cs->hw.niccy.isac_ale = pci_ioaddr + ISAC_PCI_ADDR;
cs->hw.niccy.hscx = pci_ioaddr + HSCX_PCI_DATA;
cs->hw.niccy.hscx_ale = pci_ioaddr + HSCX_PCI_ADDR;
if (!request_io(&cs->rs, cs->hw.niccy.isac, 4, "niccy"))
goto err;
if (!request_io(&cs->rs, cs->hw.niccy.cfg_reg, 0x40, "niccy pci"))
goto err;
#endif /* CONFIG_PCI */
}
printk(KERN_INFO "HiSax: %s %s config irq:%d data:0x%X ale:0x%X\n",
CardType[cs->typ], (cs->subtyp==1) ? "PnP":"PCI",
cs->irq, cs->hw.niccy.isac, cs->hw.niccy.isac_ale);
cs->card_ops = &niccy_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err;
return 1;
err:
niccy_release(cs);
return 0;
}
......@@ -106,96 +106,99 @@ static struct card_ops nj_s_ops = {
.irq_func = nj_s_interrupt,
};
static struct pci_dev *dev_netjet __initdata = NULL;
int __init
setup_netjet_s(struct IsdnCard *card)
static int __init
nj_s_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
{
struct IsdnCardState *cs = card->cs;
char tmp[64];
#ifdef __BIG_ENDIAN
#error "not running on big endian machines now"
#endif
strcpy(tmp, NETjet_S_revision);
printk(KERN_INFO "HiSax: Traverse Tech. NETjet-S driver Rev. %s\n", HiSax_getrev(tmp));
for ( ;; ) {
if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET,
PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) {
if (pci_enable_device(dev_netjet))
return(0);
pci_set_master(dev_netjet);
cs->irq = dev_netjet->irq;
if (!cs->irq) {
printk(KERN_WARNING "NETjet-S: No IRQ for PCI card found\n");
return(0);
}
cs->hw.njet.base = pci_resource_start(dev_netjet, 0);
if (!cs->hw.njet.base) {
printk(KERN_WARNING "NETjet-S: No IO-Adr for PCI card found\n");
return(0);
}
/* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG www.formula-n.com */
if ((dev_netjet->subsystem_vendor == 0x55) &&
(dev_netjet->subsystem_device == 0x02)) {
printk(KERN_WARNING "Netjet: You tried to load this driver with an incompatible TigerJet-card\n");
printk(KERN_WARNING "Use type=41 for Formula-n enter:now ISDN PCI and compatible\n");
return(0);
}
/* end new code */
cs->hw.njet.pdev = dev_netjet;
} else {
printk(KERN_WARNING "NETjet-S: No PCI card found\n");
return(0);
}
cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA;
cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF;
cs->hw.njet.ctrl_reg = 0xff; /* Reset On */
byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((10*HZ)/1000); /* Timeout 10ms */
cs->hw.njet.ctrl_reg = 0x00; /* Reset Off and status read clear */
byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
if (pci_enable_device(pdev))
goto err;
pci_set_master(pdev);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((10*HZ)/1000); /* Timeout 10ms */
cs->hw.njet.auxd = 0xC0;
cs->hw.njet.dmactrl = 0;
byteout(cs->hw.njet.base + NETJET_AUXCTRL, ~NETJET_ISACIRQ);
byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ);
byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
switch ( ( ( NETjet_ReadIC( cs, ISAC_RBCH ) >> 5 ) & 3 ) )
{
case 0 :
break;
cs->irq = pdev->irq;
cs->irq_flags |= SA_SHIRQ;
cs->hw.njet.pdev = pdev;
cs->hw.njet.base = pci_resource_start(pdev, 0);
if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "netjet-s isdn"))
return 0;
cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA;
cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF;
cs->hw.njet.ctrl_reg = 0xff; /* Reset On */
byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
case 3 :
printk( KERN_WARNING "NETjet-S: NETspider-U PCI card found\n" );
continue;
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((10*HZ)/1000); /* Timeout 10ms */
cs->hw.njet.ctrl_reg = 0x00; /* Reset Off and status read clear */
byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((10*HZ)/1000); /* Timeout 10ms */
cs->hw.njet.auxd = 0xC0;
cs->hw.njet.dmactrl = 0;
byteout(cs->hw.njet.auxa, 0);
byteout(cs->hw.njet.base + NETJET_AUXCTRL, ~NETJET_ISACIRQ);
byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ);
byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
default :
printk( KERN_WARNING "NETjet-S: No PCI card found\n" );
return 0;
}
break;
switch ((NETjet_ReadIC(cs, ISAC_RBCH) >> 5) & 3) {
case 0 :
break;
case 3 :
printk(KERN_WARNING "NETjet-S: NETspider-U PCI card found\n" );
goto err;
default :
printk(KERN_WARNING "NETjet-S: No PCI card found\n" );
goto err;
}
printk(KERN_INFO
"NETjet-S: PCI card configured at %#lx IRQ %d\n",
cs->hw.njet.base, cs->irq);
if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "netjet-s isdn"))
return 0;
nj_s_reset(cs);
cs->irq_flags |= SA_SHIRQ;
cs->card_ops = &nj_s_ops;
isac_setup(cs, &netjet_dc_ops);
return 1;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static struct pci_dev *dev_netjet __initdata = NULL;
int __init
setup_netjet_s(struct IsdnCard *card)
{
char tmp[64];
#ifdef __BIG_ENDIAN
#error "not running on big endian machines now"
#endif
strcpy(tmp, NETjet_S_revision);
printk(KERN_INFO "HiSax: Traverse Tech. NETjet-S driver Rev. %s\n",
HiSax_getrev(tmp));
dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET,
PCI_DEVICE_ID_TIGERJET_300, dev_netjet);
if (dev_netjet) {
/* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG www.formula-n.com */
if (dev_netjet->subsystem_vendor == 0x55 &&
dev_netjet->subsystem_device == 0x02) {
printk(KERN_WARNING "Netjet: You tried to load this "
"driver with an incompatible TigerJet-card\n");
printk(KERN_WARNING "Use type=41 for Formula-n "
"enter:now ISDN PCI and compatible\n");
return 0;
}
if (nj_s_probe(card->cs, dev_netjet))
return 1;
return 0;
}
printk(KERN_WARNING "NETjet-S: No PCI card found\n");
return 0;
}
......@@ -110,88 +110,85 @@ static struct card_ops nj_u_ops = {
.irq_func = nj_u_interrupt,
};
static int __init
nj_u_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
{
if (pci_enable_device(pdev))
goto err;
pci_set_master(pdev);
cs->irq = pdev->irq;
cs->irq_flags |= SA_SHIRQ;
cs->hw.njet.pdev = pdev;
cs->hw.njet.base = pci_resource_start(pdev, 0);
if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "netspider-u isdn"))
goto err;
cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA;
cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF;
cs->hw.njet.ctrl_reg = 0xff; /* Reset On */
byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((10*HZ)/1000); /* Timeout 10ms */
cs->hw.njet.ctrl_reg = 0x00; /* Reset Off and status read clear */
byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((10*HZ)/1000); /* Timeout 10ms */
cs->hw.njet.auxd = 0xC0;
cs->hw.njet.dmactrl = 0;
byteout(cs->hw.njet.base + NETJET_AUXCTRL, ~NETJET_ISACIRQ);
byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ);
byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
switch ((NETjet_ReadIC(cs, ICC_RBCH) >> 5) & 3) {
case 3:
break;
case 0:
printk(KERN_WARNING "NETspider-U: NETjet-S PCI card found\n" );
goto err;
default:
printk(KERN_WARNING "NETspider-U: No PCI card found\n" );
goto err;
}
printk(KERN_INFO "NETspider-U: PCI card configured at %#lx IRQ %d\n",
cs->hw.njet.base, cs->irq);
nj_u_reset(cs);
cs->card_ops = &nj_u_ops;
icc_setup(cs, &netjet_dc_ops);
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static struct pci_dev *dev_netjet __initdata = NULL;
int __init
setup_netjet_u(struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
char tmp[64];
#ifdef __BIG_ENDIAN
#error "not running on big endian machines now"
#endif
strcpy(tmp, NETjet_U_revision);
printk(KERN_INFO "HiSax: Traverse Tech. NETspider-U driver Rev. %s\n", HiSax_getrev(tmp));
for ( ;; ) {
if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET,
PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) {
if (pci_enable_device(dev_netjet))
return(0);
pci_set_master(dev_netjet);
cs->irq = dev_netjet->irq;
if (!cs->irq) {
printk(KERN_WARNING "NETspider-U: No IRQ for PCI card found\n");
return(0);
}
cs->hw.njet.base = pci_resource_start(dev_netjet, 0);
if (!cs->hw.njet.base) {
printk(KERN_WARNING "NETspider-U: No IO-Adr for PCI card found\n");
return(0);
}
cs->hw.njet.pdev = dev_netjet;
} else {
printk(KERN_WARNING "NETspider-U: No PCI card found\n");
return(0);
}
cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA;
cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF;
cs->hw.njet.ctrl_reg = 0xff; /* Reset On */
byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((10*HZ)/1000); /* Timeout 10ms */
cs->hw.njet.ctrl_reg = 0x00; /* Reset Off and status read clear */
byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((10*HZ)/1000); /* Timeout 10ms */
cs->hw.njet.auxd = 0xC0;
cs->hw.njet.dmactrl = 0;
byteout(cs->hw.njet.auxa, 0);
byteout(cs->hw.njet.base + NETJET_AUXCTRL, ~NETJET_ISACIRQ);
byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ);
byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
switch ( ( ( NETjet_ReadIC( cs, ICC_RBCH ) >> 5 ) & 3 ) )
{
case 3 :
break;
case 0 :
printk( KERN_WARNING "NETspider-U: NETjet-S PCI card found\n" );
continue;
default :
printk( KERN_WARNING "NETspider-U: No PCI card found\n" );
return 0;
}
break;
}
printk(KERN_INFO
"NETspider-U: PCI card configured at %#lx IRQ %d\n",
cs->hw.njet.base, cs->irq);
if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "netjet-s isdn"))
return 0;
printk(KERN_INFO "HiSax: Traverse Tech. NETspider-U driver Rev. %s\n",
HiSax_getrev(tmp));
nj_u_reset(cs);
cs->irq_flags |= SA_SHIRQ;
cs->card_ops = &nj_u_ops;
icc_setup(cs, &netjet_dc_ops);
return 1;
dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET,
PCI_DEVICE_ID_TIGERJET_300, dev_netjet);
if (dev_netjet) {
if (nj_u_probe(card->cs, dev_netjet))
return 1;
return 0;
}
printk(KERN_WARNING "NETspider-U: No PCI card found\n");
return 0;
}
......@@ -172,14 +172,9 @@ static struct card_ops s0box_ops = {
.irq_func = hscxisac_irq,
};
int __init
setup_s0box(struct IsdnCard *card)
static int __init
s0box_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
char tmp[64];
strcpy(tmp, s0box_revision);
printk(KERN_INFO "HiSax: S0Box IO driver Rev. %s\n", HiSax_getrev(tmp));
cs->hw.teles3.cfg_reg = card->para[1];
cs->hw.teles3.hscx[0] = -0x20;
cs->hw.teles3.hscx[1] = 0x0;
......@@ -200,8 +195,20 @@ setup_s0box(struct IsdnCard *card)
cs->card_ops = &s0box_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err;
return 1;
return 0;
err:
hisax_release_resources(cs);
return 0;
return -EBUSY;
}
int __init
setup_s0box(struct IsdnCard *card)
{
char tmp[64];
strcpy(tmp, s0box_revision);
printk(KERN_INFO "HiSax: S0Box IO driver Rev. %s\n", HiSax_getrev(tmp));
if (s0box_probe(card->cs, card))
return 0;
return 1;
}
......@@ -201,36 +201,21 @@ static struct card_ops saphir_ops = {
.irq_func = saphir_interrupt,
};
int __init
setup_saphir(struct IsdnCard *card)
static int __init
saphir_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
char tmp[64];
strcpy(tmp, saphir_rev);
printk(KERN_INFO "HiSax: HST Saphir driver Rev. %s\n", HiSax_getrev(tmp));
if (cs->typ != ISDN_CTYPE_HSTSAPHIR)
return (0);
init_timer(&cs->hw.saphir.timer);
/* IO-Ports */
cs->hw.saphir.cfg_reg = card->para[1];
cs->hw.saphir.isac = card->para[1] + ISAC_DATA;
cs->hw.saphir.hscx = card->para[1] + HSCX_DATA;
cs->hw.saphir.ale = card->para[1] + ADDRESS_REG;
cs->irq = card->para[0];
if (!request_io(&cs->rs, cs->hw.saphir.cfg_reg, 6, "saphir"))
goto err;
printk(KERN_INFO
"HiSax: %s config irq:%d io:0x%X\n",
CardType[cs->typ], cs->irq,
cs->hw.saphir.cfg_reg);
printk(KERN_INFO "HiSax: %s config irq:%d io:0x%X\n",
CardType[cs->typ], cs->irq, cs->hw.saphir.cfg_reg);
cs->hw.saphir.timer.function = (void *) SaphirWatchDog;
cs->hw.saphir.timer.data = (long) cs;
cs->hw.saphir.timer.expires = jiffies + 4*HZ;
add_timer(&cs->hw.saphir.timer);
if (saphir_reset(cs))
goto err;
......@@ -238,8 +223,27 @@ setup_saphir(struct IsdnCard *card)
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err;
return 1;
err:
saphir_release(cs);
init_timer(&cs->hw.saphir.timer);
cs->hw.saphir.timer.function = (void *) SaphirWatchDog;
cs->hw.saphir.timer.data = (long) cs;
cs->hw.saphir.timer.expires = jiffies + 4*HZ;
add_timer(&cs->hw.saphir.timer);
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
int __init
setup_saphir(struct IsdnCard *card)
{
char tmp[64];
strcpy(tmp, saphir_rev);
printk(KERN_INFO "HiSax: HST Saphir driver Rev. %s\n",
HiSax_getrev(tmp));
if (saphir_probe(card->cs, card) < 0)
return 0;
return 1;
}
......@@ -73,7 +73,6 @@ const char *Sedlbauer_Types[] =
#define SEDL_SPEEDFAX_PYRAMID 7
#define SEDL_SPEEDFAX_PCI 8
#define SEDL_CHIP_TEST 0
#define SEDL_CHIP_ISAC_HSCX 1
#define SEDL_CHIP_ISAC_ISAR 2
#define SEDL_CHIP_IPAC 3
......@@ -452,6 +451,241 @@ static struct card_ops sedlbauer_isar_ops = {
.irq_func = sedlbauer_isar_interrupt,
};
static int __init
sedl_ipac_probe(struct IsdnCardState *cs)
{
u8 val;
cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR;
val = readreg(cs, cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC, IPAC_ID);
printk(KERN_DEBUG "Sedlbauer: testing IPAC version %x\n", val);
return (val == 1 || val == 2);
}
static int __init
sedl_ipac_init(struct IsdnCardState *cs)
{
cs->card_ops = &sedlbauer_ipac_ops;
if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops))
return -ENODEV;
sedlbauer_reset(cs);
return 0;
}
static int __init
sedl_isac_isar_init(struct IsdnCardState *cs)
{
cs->bcs[0].hw.isar.reg = &cs->hw.sedl.isar;
cs->bcs[1].hw.isar.reg = &cs->hw.sedl.isar;
__set_bit(HW_ISAR, &cs->HW_Flags);
cs->card_ops = &sedlbauer_isar_ops;
cs->auxcmd = &isar_auxcmd;
isac_setup(cs, &isac_ops);
return isar_setup(cs, &isar_ops);
}
static int __init
sedl_isac_hscx_init(struct IsdnCardState *cs)
{
cs->card_ops = &sedlbauer_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
return -ENODEV;
sedlbauer_reset(cs);
return 0;
}
static int __init
sedl_card_win_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
cs->irq = card->para[0];
cs->hw.sedl.cfg_reg = card->para[1];
cs->hw.sedl.bus = SEDL_BUS_ISA;
if (!request_io(&cs->rs, cs->hw.sedl.cfg_reg, 8, "sedlbauer isdn"))
goto err;
if (sedl_ipac_probe(cs)) {
cs->subtyp = SEDL_SPEED_WIN2_PC104;
cs->hw.sedl.chip = SEDL_CHIP_IPAC;
cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR;
cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC;
if (sedl_ipac_init(cs))
goto err;
} else {
cs->subtyp = SEDL_SPEED_CARD_WIN;
cs->hw.sedl.chip = SEDL_CHIP_ISAC_HSCX;
cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ADR;
cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ISAC;
cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_HSCX;
cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_ON;
cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_OFF;
if (sedl_isac_hscx_init(cs))
goto err;
}
printk(KERN_INFO "Sedlbauer %s: defined at 0x%x-0x%x IRQ %d\n",
Sedlbauer_Types[cs->subtyp],
cs->hw.sedl.cfg_reg, cs->hw.sedl.cfg_reg + 8, cs->irq);
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static int __init
sedl_star_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
cs->hw.sedl.bus = SEDL_BUS_PCMCIA;
if (sedl_ipac_probe(cs)) {
cs->subtyp = SEDL_SPEED_STAR2;
cs->hw.sedl.chip = SEDL_CHIP_IPAC;
cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR;
cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC;
if (sedl_ipac_init(cs))
goto err;
} else {
cs->subtyp = SEDL_SPEED_STAR;
cs->hw.sedl.chip = SEDL_CHIP_ISAC_HSCX;
cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ADR;
cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ISAC;
cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_HSCX;
cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET;
cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET;
if (sedl_isac_hscx_init(cs))
goto err;
}
printk(KERN_INFO "Sedlbauer %s: defined at 0x%x-0x%x IRQ %d\n",
Sedlbauer_Types[cs->subtyp],
cs->hw.sedl.cfg_reg, cs->hw.sedl.cfg_reg + 8, cs->irq);
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static int __init
sedl_fax_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
cs->subtyp = SEDL_SPEED_FAX;
cs->hw.sedl.bus = SEDL_BUS_ISA;
cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
if (!request_io(&cs->rs, cs->hw.sedl.cfg_reg, 16, "sedlbauer isdn"))
goto err;
printk(KERN_INFO "Sedlbauer %s: defined at 0x%x-0x%x IRQ %d\n",
Sedlbauer_Types[cs->subtyp],
cs->hw.sedl.cfg_reg, cs->hw.sedl.cfg_reg + 16, cs->irq);
cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_ISAR_ISA_ADR;
cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_ISAR_ISA_ISAC;
cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_ISAR_ISA_ISAR;
cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_ISAR_ISA_ISAR_RESET_ON;
cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_ISAR_ISA_ISAR_RESET_OFF;
if (sedl_isac_isar_init(cs))
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static int __init
sedl_pci_init(struct IsdnCardState *cs, struct pci_dev *pdev)
{
cs->irq = pdev->irq;
cs->irq_flags |= SA_SHIRQ;
cs->hw.sedl.cfg_reg = pci_resource_start(pdev, 0);
cs->hw.sedl.bus = SEDL_BUS_PCI;
if (!request_io(&cs->rs, cs->hw.sedl.cfg_reg, 256, "sedlbauer isdn"))
return -EBUSY;
printk(KERN_INFO "Sedlbauer %s: defined at 0x%x-0x%x IRQ %d\n",
Sedlbauer_Types[cs->subtyp],
cs->hw.sedl.cfg_reg, cs->hw.sedl.cfg_reg + 256, cs->irq);
cs->hw.sedl.reset_on = SEDL_ISAR_PCI_ISAR_RESET_ON;
cs->hw.sedl.reset_off = SEDL_ISAR_PCI_ISAR_RESET_OFF;
byteout(cs->hw.sedl.cfg_reg, 0xff);
byteout(cs->hw.sedl.cfg_reg, 0x00);
byteout(cs->hw.sedl.cfg_reg+ 2, 0xdd);
byteout(cs->hw.sedl.cfg_reg+ 5, 0x02);
byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_on);
current->state = TASK_UNINTERRUPTIBLE;
schedule_timeout((10*HZ)/1000);
byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
return 0;
}
static int __init
sedl_fax_pyramid_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
{
if (pci_enable_device(pdev))
goto err;
cs->subtyp = SEDL_SPEEDFAX_PYRAMID;
cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
if (sedl_pci_init(cs, pdev))
goto err;
cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_ISAR_PCI_ADR;
cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_ISAR_PCI_ISAC;
cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_ISAR_PCI_ISAR;
if (sedl_isac_isar_init(cs))
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static int __init
sedl_fax_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
{
if (pci_enable_device(pdev))
goto err;
cs->subtyp = SEDL_SPEEDFAX_PCI;
cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
if (sedl_pci_init(cs, pdev))
goto err;
cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_ISAR_PCI_ADR;
cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_ISAR_PCI_ISAC;
cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_ISAR_PCI_ISAR;
if (sedl_isac_isar_init(cs))
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static int __init
sedl_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
{
if (pci_enable_device(pdev))
goto err;
cs->subtyp = SEDL_SPEED_PCI;
cs->hw.sedl.chip = SEDL_CHIP_IPAC;
if (sedl_pci_init(cs, pdev))
goto err;
cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_ADR;
cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC;
if (sedl_ipac_init(cs))
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static struct pci_dev *dev_sedl __devinitdata = NULL;
#ifdef __ISAPNP__
......@@ -472,265 +706,117 @@ static struct pnp_card *pnp_c __devinitdata = NULL;
int __devinit
setup_sedlbauer(struct IsdnCard *card)
{
int bytecnt, val;
struct IsdnCardState *cs = card->cs;
char tmp[64];
u16 sub_vendor_id, sub_id;
strcpy(tmp, Sedlbauer_revision);
printk(KERN_INFO "HiSax: Sedlbauer driver Rev. %s\n", HiSax_getrev(tmp));
printk(KERN_INFO "HiSax: Sedlbauer driver Rev. %s\n",
HiSax_getrev(tmp));
if (cs->typ == ISDN_CTYPE_SEDLBAUER) {
cs->subtyp = SEDL_SPEED_CARD_WIN;
cs->hw.sedl.bus = SEDL_BUS_ISA;
cs->hw.sedl.chip = SEDL_CHIP_TEST;
} else if (cs->typ == ISDN_CTYPE_SEDLBAUER_PCMCIA) {
cs->subtyp = SEDL_SPEED_STAR;
cs->hw.sedl.bus = SEDL_BUS_PCMCIA;
cs->hw.sedl.chip = SEDL_CHIP_TEST;
} else if (cs->typ == ISDN_CTYPE_SEDLBAUER_FAX) {
cs->subtyp = SEDL_SPEED_FAX;
cs->hw.sedl.bus = SEDL_BUS_ISA;
cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
} else
return (0);
bytecnt = 8;
if (card->para[1]) {
cs->hw.sedl.cfg_reg = card->para[1];
cs->irq = card->para[0];
if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
bytecnt = 16;
if (cs->typ == ISDN_CTYPE_SEDLBAUER) {
if (sedl_card_win_probe(card->cs, card) < 0)
return 0;
return 1;
} else if (cs->typ == ISDN_CTYPE_SEDLBAUER_PCMCIA) {
if (sedl_star_probe(card->cs, card) < 0)
return 0;
return 1;
} else if (cs->typ == ISDN_CTYPE_SEDLBAUER_FAX) {
if (sedl_fax_probe(card->cs, card) < 0)
return 0;
return 1;
}
} else {
}
#ifdef __ISAPNP__
if (isapnp_present()) {
struct pnp_card *pb;
struct pnp_dev *pd;
while(pdev->card_vendor) {
if ((pb = pnp_find_card(pdev->card_vendor,
pdev->card_device,
pnp_c))) {
pnp_c = pb;
pd = NULL;
if ((pd = pnp_find_dev(pnp_c,
pdev->vendor,
pdev->function,
pd))) {
printk(KERN_INFO "HiSax: %s detected\n",
(char *)pdev->driver_data);
if (pnp_device_attach(pd) < 0) {
printk(KERN_ERR "Sedlbauer PnP: attach failed\n");
return 0;
}
if (pnp_activate_dev(pd) < 0) {
printk(KERN_ERR "Sedlbauer PnP: activate failed\n");
pnp_device_detach(pd);
if (isapnp_present()) {
struct pnp_card *pb;
struct pnp_dev *pd;
while(pdev->card_vendor) {
if ((pb = pnp_find_card(pdev->card_vendor,
pdev->card_device,
pnp_c))) {
pnp_c = pb;
pd = NULL;
if ((pd = pnp_find_dev(pnp_c,
pdev->vendor,
pdev->function,
pd))) {
printk(KERN_INFO "HiSax: %s detected\n",
(char *)pdev->driver_data);
if (pnp_device_attach(pd) < 0) {
printk(KERN_ERR "Sedlbauer PnP: attach failed\n");
return 0;
}
if (pnp_activate_dev(pd) < 0) {
printk(KERN_ERR "Sedlbauer PnP: activate failed\n");
pnp_device_detach(pd);
return 0;
}
if (!pnp_irq_valid(pd, 0) || !pnp_port_valid(pd, 0)) {
printk(KERN_ERR "Sedlbauer PnP:some resources are missing %ld/%lx\n",
pnp_irq(pd, 0), pnp_port_start(pd, 0));
pnp_device_detach(pd);
goto err;
}
card->para[1] = pnp_port_start(pd, 0);
card->para[0] = pnp_irq(pd, 0);
cs->hw.sedl.cfg_reg = card->para[1];
cs->irq = card->para[0];
if (pdev->function == ISAPNP_FUNCTION(0x2)) {
if (sedl_fax_probe(card->cs, card))
return 0;
}
if (!pnp_irq_valid(pd, 0) || !pnp_port_valid(pd, 0)) {
printk(KERN_ERR "Sedlbauer PnP:some resources are missing %ld/%lx\n",
pnp_irq(pd, 0), pnp_port_start(pd, 0));
pnp_device_detach(pd);
goto err;
}
card->para[1] = pnp_port_start(pd, 0);
card->para[0] = pnp_irq(pd, 0);
cs->hw.sedl.cfg_reg = card->para[1];
cs->irq = card->para[0];
if (pdev->function == ISAPNP_FUNCTION(0x2)) {
cs->subtyp = SEDL_SPEED_FAX;
cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
bytecnt = 16;
} else {
cs->subtyp = SEDL_SPEED_CARD_WIN;
cs->hw.sedl.chip = SEDL_CHIP_TEST;
}
goto ready;
return 1;
} else {
printk(KERN_ERR "Sedlbauer PnP: PnP error card found, no device\n");
goto err;
if (sedl_card_win_probe(card->cs, card))
return 0;
return 1;
}
} else {
printk(KERN_ERR "Sedlbauer PnP: PnP error card found, no device\n");
goto err;
}
pdev++;
pnp_c=NULL;
}
if (!pdev->card_vendor) {
printk(KERN_INFO "Sedlbauer PnP: no ISAPnP card found\n");
}
pdev++;
pnp_c=NULL;
}
if (!pdev->card_vendor) {
printk(KERN_INFO "Sedlbauer PnP: no ISAPnP card found\n");
}
}
#endif
/* Probe for Sedlbauer speed pci */
#if CONFIG_PCI
if ((dev_sedl = pci_find_device(PCI_VENDOR_ID_TIGERJET,
PCI_DEVICE_ID_TIGERJET_100, dev_sedl))) {
if (pci_enable_device(dev_sedl))
goto err;
cs->irq = dev_sedl->irq;
if (!cs->irq) {
printk(KERN_WARNING "Sedlbauer: No IRQ for PCI card found\n");
goto err;
}
cs->hw.sedl.cfg_reg = pci_resource_start(dev_sedl, 0);
} else {
printk(KERN_WARNING "Sedlbauer: No PCI card found\n");
goto err;
}
cs->irq_flags |= SA_SHIRQ;
cs->hw.sedl.bus = SEDL_BUS_PCI;
dev_sedl = pci_find_device(PCI_VENDOR_ID_TIGERJET,
PCI_DEVICE_ID_TIGERJET_100, dev_sedl);
if (dev_sedl) {
sub_vendor_id = dev_sedl->subsystem_vendor;
sub_id = dev_sedl->subsystem_device;
printk(KERN_INFO "Sedlbauer: PCI subvendor:%x subid %x\n",
sub_vendor_id, sub_id);
printk(KERN_INFO "Sedlbauer: PCI base adr %#x\n",
cs->hw.sedl.cfg_reg);
sub_vendor_id, sub_id);
if (sub_id != PCI_SUB_ID_SEDLBAUER) {
printk(KERN_ERR "Sedlbauer: unknown sub id %#x\n", sub_id);
goto err;
return 0;
}
if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PYRAMID) {
cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
cs->subtyp = SEDL_SPEEDFAX_PYRAMID;
if (sedl_fax_pyramid_probe(cs, dev_sedl))
return 0;
return 1;
} else if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PCI) {
cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
cs->subtyp = SEDL_SPEEDFAX_PCI;
if (sedl_fax_pci_probe(cs, dev_sedl))
return 0;
return 1;
} else if (sub_vendor_id == PCI_SUBVENDOR_SEDLBAUER_PCI) {
cs->hw.sedl.chip = SEDL_CHIP_IPAC;
cs->subtyp = SEDL_SPEED_PCI;
} else {
printk(KERN_ERR "Sedlbauer: unknown sub vendor id %#x\n",
sub_vendor_id);
goto err;
}
bytecnt = 256;
cs->hw.sedl.reset_on = SEDL_ISAR_PCI_ISAR_RESET_ON;
cs->hw.sedl.reset_off = SEDL_ISAR_PCI_ISAR_RESET_OFF;
byteout(cs->hw.sedl.cfg_reg, 0xff);
byteout(cs->hw.sedl.cfg_reg, 0x00);
byteout(cs->hw.sedl.cfg_reg+ 2, 0xdd);
byteout(cs->hw.sedl.cfg_reg+ 5, 0x02);
byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_on);
current->state = TASK_UNINTERRUPTIBLE;
schedule_timeout((10*HZ)/1000);
byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
#endif /* CONFIG_PCI */
}
ready:
/* In case of the sedlbauer pcmcia card, this region is in use,
* reserved for us by the card manager. So we do not check it
* here, it would fail.
*/
if (cs->hw.sedl.bus != SEDL_BUS_PCMCIA) {
if (!request_io(&cs->rs, cs->hw.sedl.cfg_reg, bytecnt, "sedlbauer isdn"))
goto err;
}
printk(KERN_INFO
"Sedlbauer: defined at 0x%x-0x%x IRQ %d\n",
cs->hw.sedl.cfg_reg,
cs->hw.sedl.cfg_reg + bytecnt,
cs->irq);
/*
* testing ISA and PCMCIA Cards for IPAC, default is ISAC
* do not test for PCI card, because ports are different
* and PCI card uses only IPAC (for the moment)
*/
if (cs->hw.sedl.bus != SEDL_BUS_PCI) {
cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR;
val = readreg(cs, cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC,
IPAC_ID);
printk(KERN_DEBUG "Sedlbauer: testing IPAC version %x\n", val);
if ((val == 1) || (val == 2)) {
/* IPAC */
cs->subtyp = SEDL_SPEED_WIN2_PC104;
if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) {
cs->subtyp = SEDL_SPEED_STAR2;
}
cs->hw.sedl.chip = SEDL_CHIP_IPAC;
} else {
/* ISAC_HSCX oder ISAC_ISAR */
if (cs->hw.sedl.chip == SEDL_CHIP_TEST) {
cs->hw.sedl.chip = SEDL_CHIP_ISAC_HSCX;
}
}
}
/*
* hw.sedl.chip is now properly set
*/
printk(KERN_INFO "Sedlbauer: %s detected\n",
Sedlbauer_Types[cs->subtyp]);
if (cs->hw.sedl.chip == SEDL_CHIP_IPAC) {
if (cs->hw.sedl.bus == SEDL_BUS_PCI) {
cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_ADR;
cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC;
cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC;
} else {
cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR;
cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC;
cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC;
}
cs->card_ops = &sedlbauer_ipac_ops;
if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops))
goto err;
sedlbauer_reset(cs);
} else {
/* ISAC_HSCX oder ISAC_ISAR */
if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
if (cs->hw.sedl.bus == SEDL_BUS_PCI) {
cs->hw.sedl.adr = cs->hw.sedl.cfg_reg +
SEDL_ISAR_PCI_ADR;
cs->hw.sedl.isac = cs->hw.sedl.cfg_reg +
SEDL_ISAR_PCI_ISAC;
cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg +
SEDL_ISAR_PCI_ISAR;
} else {
cs->hw.sedl.adr = cs->hw.sedl.cfg_reg +
SEDL_ISAR_ISA_ADR;
cs->hw.sedl.isac = cs->hw.sedl.cfg_reg +
SEDL_ISAR_ISA_ISAC;
cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg +
SEDL_ISAR_ISA_ISAR;
cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg +
SEDL_ISAR_ISA_ISAR_RESET_ON;
cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg +
SEDL_ISAR_ISA_ISAR_RESET_OFF;
}
cs->bcs[0].hw.isar.reg = &cs->hw.sedl.isar;
cs->bcs[1].hw.isar.reg = &cs->hw.sedl.isar;
test_and_set_bit(HW_ISAR, &cs->HW_Flags);
cs->card_ops = &sedlbauer_isar_ops;
cs->auxcmd = &isar_auxcmd;
isac_setup(cs, &isac_ops);
if (isar_setup(cs, &isar_ops))
goto err;
} else {
if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) {
cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ADR;
cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ISAC;
cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_HSCX;
cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET;
cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET;
} else {
cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ADR;
cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ISAC;
cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_HSCX;
cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_ON;
cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_OFF;
}
cs->card_ops = &sedlbauer_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err;
sedlbauer_reset(cs);
if (sedl_pci_probe(cs, dev_sedl))
return 0;
return 1;
}
printk(KERN_ERR "Sedlbauer: unknown sub vendor id %#x\n",
sub_vendor_id);
return 0;
}
return 1;
err:
hisax_release_resources(cs);
#endif /* CONFIG_PCI */
return 0;
}
......@@ -189,42 +189,29 @@ get_io_range(struct IsdnCardState *cs)
}
return 0;
}
int __init
setup_sportster(struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
char tmp[64];
strcpy(tmp, sportster_revision);
printk(KERN_INFO "HiSax: USR Sportster driver Rev. %s\n", HiSax_getrev(tmp));
cs->hw.spt.cfg_reg = card->para[1];
static int __init
sportster_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
cs->irq = card->para[0];
cs->hw.spt.cfg_reg = card->para[1];
if (!get_io_range(cs))
return (0);
return -EBUSY;
cs->hw.spt.isac = cs->hw.spt.cfg_reg + SPORTSTER_ISAC;
cs->hw.spt.hscx[0] = cs->hw.spt.cfg_reg + SPORTSTER_HSCXA;
cs->hw.spt.hscx[1] = cs->hw.spt.cfg_reg + SPORTSTER_HSCXB;
switch(cs->irq) {
case 5: cs->hw.spt.res_irq = 1;
break;
case 7: cs->hw.spt.res_irq = 2;
break;
case 10:cs->hw.spt.res_irq = 3;
break;
case 11:cs->hw.spt.res_irq = 4;
break;
case 12:cs->hw.spt.res_irq = 5;
break;
case 14:cs->hw.spt.res_irq = 6;
break;
case 15:cs->hw.spt.res_irq = 7;
break;
default:sportster_release(cs);
printk(KERN_WARNING "Sportster: wrong IRQ\n");
return(0);
case 5: cs->hw.spt.res_irq = 1; break;
case 7: cs->hw.spt.res_irq = 2; break;
case 10:cs->hw.spt.res_irq = 3; break;
case 11:cs->hw.spt.res_irq = 4; break;
case 12:cs->hw.spt.res_irq = 5; break;
case 14:cs->hw.spt.res_irq = 6; break;
case 15:cs->hw.spt.res_irq = 7; break;
default:
printk(KERN_WARNING "Sportster: wrong IRQ\n");
goto err;
}
sportster_reset(cs);
printk(KERN_INFO "HiSax: %s config irq:%d cfg:0x%X\n",
......@@ -234,8 +221,22 @@ setup_sportster(struct IsdnCard *card)
cs->card_ops = &sportster_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err;
return 1;
err:
hisax_release_resources(cs);
return 0;
err:
sportster_release(cs);
return -EBUSY;
}
int __init
setup_sportster(struct IsdnCard *card)
{
char tmp[64];
strcpy(tmp, sportster_revision);
printk(KERN_INFO "HiSax: USR Sportster driver Rev. %s\n",
HiSax_getrev(tmp));
if (sportster_probe(card->cs, card) < 0)
return 0;
return 1;
}
......@@ -256,15 +256,9 @@ static struct card_ops teleint_ops = {
.irq_func = teleint_interrupt,
};
int __init
setup_TeleInt(struct IsdnCard *card)
static int __init
teleint_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
char tmp[64];
strcpy(tmp, TeleInt_revision);
printk(KERN_INFO "HiSax: TeleInt driver Rev. %s\n", HiSax_getrev(tmp));
cs->hw.hfc.addr = card->para[1] & 0x3fe;
cs->irq = card->para[0];
cs->hw.hfc.cirm = HFC_CIRM;
......@@ -284,42 +278,54 @@ setup_TeleInt(struct IsdnCard *card)
byteout(cs->hw.hfc.addr, cs->hw.hfc.addr & 0xff);
byteout(cs->hw.hfc.addr | 1, ((cs->hw.hfc.addr & 0x300) >> 8) | 0x54);
switch (cs->irq) {
case 3:
cs->hw.hfc.cirm |= HFC_INTA;
break;
case 4:
cs->hw.hfc.cirm |= HFC_INTB;
break;
case 5:
cs->hw.hfc.cirm |= HFC_INTC;
break;
case 7:
cs->hw.hfc.cirm |= HFC_INTD;
break;
case 10:
cs->hw.hfc.cirm |= HFC_INTE;
break;
case 11:
cs->hw.hfc.cirm |= HFC_INTF;
break;
default:
printk(KERN_WARNING "TeleInt: wrong IRQ\n");
goto err;
case 3:
cs->hw.hfc.cirm |= HFC_INTA;
break;
case 4:
cs->hw.hfc.cirm |= HFC_INTB;
break;
case 5:
cs->hw.hfc.cirm |= HFC_INTC;
break;
case 7:
cs->hw.hfc.cirm |= HFC_INTD;
break;
case 10:
cs->hw.hfc.cirm |= HFC_INTE;
break;
case 11:
cs->hw.hfc.cirm |= HFC_INTF;
break;
default:
printk(KERN_WARNING "TeleInt: wrong IRQ\n");
goto err;
}
byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.cirm);
byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.ctmt);
printk(KERN_INFO
"TeleInt: defined at 0x%x IRQ %d\n",
cs->hw.hfc.addr,
cs->irq);
printk(KERN_INFO "TeleInt: defined at 0x%x IRQ %d\n",
cs->hw.hfc.addr, cs->irq);
cs->card_ops = &teleint_ops;
teleint_reset(cs);
isac_setup(cs, &isac_ops);
hfc_setup(cs, &hfc_ops);
return 1;
err:
teleint_release(cs);
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
int __init
setup_TeleInt(struct IsdnCard *card)
{
char tmp[64];
strcpy(tmp, TeleInt_revision);
printk(KERN_INFO "HiSax: TeleInt driver Rev. %s\n", HiSax_getrev(tmp));
if (teleint_probe(card->cs, card) < 0)
return 0;
return 1;
}
......@@ -165,72 +165,95 @@ static struct card_ops teles0_ops = {
.irq_func = hscxisac_irq,
};
int __init
setup_teles0(struct IsdnCard *card)
static int __init
teles0_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
u8 val;
struct IsdnCardState *cs = card->cs;
char tmp[64];
strcpy(tmp, teles0_revision);
printk(KERN_INFO "HiSax: Teles 8.0/16.0 driver Rev. %s\n", HiSax_getrev(tmp));
if (cs->typ == ISDN_CTYPE_16_0)
cs->hw.teles0.cfg_reg = card->para[2];
else /* 8.0 */
cs->hw.teles0.cfg_reg = 0;
if (card->para[1] < 0x10000) {
card->para[1] <<= 4;
printk(KERN_INFO
"Teles0: membase configured DOSish, assuming 0x%lx\n",
(unsigned long) card->para[1]);
}
cs->irq = card->para[0];
if (cs->hw.teles0.cfg_reg) {
if (!request_io(&cs->rs, cs->hw.teles0.cfg_reg, 8, "teles cfg"))
goto err;
if ((val = bytein(cs->hw.teles0.cfg_reg + 0)) != 0x51) {
printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n",
cs->hw.teles0.cfg_reg + 0, val);
goto err;
}
if ((val = bytein(cs->hw.teles0.cfg_reg + 1)) != 0x93) {
printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n",
cs->hw.teles0.cfg_reg + 1, val);
goto err;
}
val = bytein(cs->hw.teles0.cfg_reg + 2);/* 0x1e=without AB
* 0x1f=with AB
* 0x1c 16.3 ???
*/
if (val != 0x1e && val != 0x1f) {
printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n",
cs->hw.teles0.cfg_reg + 2, val);
goto err;
}
}
/* 16.0 and 8.0 designed for IOM1 */
test_and_set_bit(HW_IOM1, &cs->HW_Flags);
cs->hw.teles0.phymem = card->para[1];
cs->hw.teles0.membase = request_mmio(&cs->rs, cs->hw.teles0.phymem, TELES_IOMEM_SIZE, "teles iomem");
cs->hw.teles0.membase = request_mmio(&cs->rs, cs->hw.teles0.phymem,
TELES_IOMEM_SIZE, "teles iomem");
if (!cs->hw.teles0.membase)
goto err;
return -EBUSY;
printk(KERN_INFO
"HiSax: %s config irq:%d mem:0x%p cfg:0x%X\n",
CardType[cs->typ], cs->irq,
cs->hw.teles0.membase, cs->hw.teles0.cfg_reg);
if (teles0_reset(cs)) {
printk(KERN_WARNING "Teles0: wrong IRQ\n");
goto err;
return -EBUSY;
}
cs->card_ops = &teles0_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err;
return 1;
return -EBUSY;
return 0;
}
static int __init
teles16_0_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
u8 val;
cs->hw.teles0.cfg_reg = card->para[2];
if (!request_io(&cs->rs, cs->hw.teles0.cfg_reg, 8, "teles cfg"))
goto err;
if ((val = bytein(cs->hw.teles0.cfg_reg + 0)) != 0x51) {
printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n",
cs->hw.teles0.cfg_reg + 0, val);
goto err;
}
if ((val = bytein(cs->hw.teles0.cfg_reg + 1)) != 0x93) {
printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n",
cs->hw.teles0.cfg_reg + 1, val);
goto err;
}
val = bytein(cs->hw.teles0.cfg_reg + 2);/* 0x1e=without AB
* 0x1f=with AB
* 0x1c 16.3 ???
*/
if (val != 0x1e && val != 0x1f) {
printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n",
cs->hw.teles0.cfg_reg + 2, val);
goto err;
}
if (teles0_probe(cs, card) < 0)
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static int __init
teles8_0_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
cs->hw.teles0.cfg_reg = 0;
if (teles0_probe(cs, card) < 0)
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
int __init
setup_teles0(struct IsdnCard *card)
{
char tmp[64];
strcpy(tmp, teles0_revision);
printk(KERN_INFO "HiSax: Teles 8.0/16.0 driver Rev. %s\n",
HiSax_getrev(tmp));
if (card->cs->typ == ISDN_CTYPE_16_0) {
if (teles16_0_probe(card->cs, card) < 0)
return 0;
} else {
if (teles8_0_probe(card->cs, card) < 0)
return 0;
}
return 1;
}
......@@ -176,6 +176,152 @@ static struct card_ops teles3_ops = {
.irq_func = hscxisac_irq,
};
static int
teles_hw_init(struct IsdnCardState *cs)
{
printk(KERN_INFO "HiSax: %s config irq:%d isac:0x%X cfg:0x%X\n",
CardType[cs->typ], cs->irq,
cs->hw.teles3.isac + 32, cs->hw.teles3.cfg_reg);
printk(KERN_INFO "HiSax: hscx A:0x%X hscx B:0x%X\n",
cs->hw.teles3.hscx[0] + 32, cs->hw.teles3.hscx[1] + 32);
if (teles3_reset(cs)) {
printk(KERN_WARNING "Teles3: wrong IRQ\n");
return -EBUSY;
}
cs->card_ops = &teles3_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
return -EBUSY;
return 0;
}
static void __init
teles_setup_io(struct IsdnCardState *cs, struct IsdnCard *card)
{
cs->irq = card->para[0];
cs->hw.teles3.isacfifo = cs->hw.teles3.isac + 0x3e;
cs->hw.teles3.hscxfifo[0] = cs->hw.teles3.hscx[0] + 0x3e;
cs->hw.teles3.hscxfifo[1] = cs->hw.teles3.hscx[1] + 0x3e;
}
static int __init
telespcmcia_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
cs->hw.teles3.cfg_reg = 0;
cs->hw.teles3.hscx[0] = card->para[1] - 0x20;
cs->hw.teles3.hscx[1] = card->para[1];
cs->hw.teles3.isac = card->para[1] + 0x20;
teles_setup_io(cs, card);
if (!request_io(&cs->rs, cs->hw.teles3.hscx[1], 96,
"HiSax Teles PCMCIA"))
goto err;
if (teles_hw_init(cs) < 0)
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static int __init
teles_request_io(struct IsdnCardState *cs)
{
if (!request_io(&cs->rs, cs->hw.teles3.isac + 32, 32, "HiSax isac"))
return -EBUSY;
if (!request_io(&cs->rs, cs->hw.teles3.hscx[0]+32, 32, "HiSax hscx A"))
return -EBUSY;
if (!request_io(&cs->rs, cs->hw.teles3.hscx[1]+32, 32, "HiSax hscx B"))
return -EBUSY;
return 0;
}
static int __init
teles16_3_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
u8 val;
cs->hw.teles3.cfg_reg = card->para[1];
switch (cs->hw.teles3.cfg_reg) {
case 0x180:
case 0x280:
case 0x380:
cs->hw.teles3.cfg_reg |= 0xc00;
break;
}
cs->hw.teles3.isac = cs->hw.teles3.cfg_reg - 0x420;
cs->hw.teles3.hscx[0] = cs->hw.teles3.cfg_reg - 0xc20;
cs->hw.teles3.hscx[1] = cs->hw.teles3.cfg_reg - 0x820;
teles_setup_io(cs, card);
if (!request_io(&cs->rs, cs->hw.teles3.cfg_reg, 8, "teles3 cfg"))
goto err;
if (teles_request_io(cs) < 0)
goto err;
if ((val = bytein(cs->hw.teles3.cfg_reg + 0)) != 0x51) {
printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n",
cs->hw.teles3.cfg_reg + 0, val);
goto err;
}
if ((val = bytein(cs->hw.teles3.cfg_reg + 1)) != 0x93) {
printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n",
cs->hw.teles3.cfg_reg + 1, val);
goto err;
}
/* 0x1e without AB, 0x1f with AB, 0x1c 16.3 ???,
* 0x39 16.3 1.1, 0x38 16.3 1.3, 0x46 16.3 with AB + Video */
val = bytein(cs->hw.teles3.cfg_reg + 2);
if (val != 0x46 && val != 0x39 && val != 0x38 &&
val != 0x1c && val != 0x1e && val != 0x1f) {
printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n",
cs->hw.teles3.cfg_reg + 2, val);
goto err;
}
if (teles_hw_init(cs) < 0)
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static int __init
compaq_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
cs->hw.teles3.cfg_reg = card->para[3];
cs->hw.teles3.isac = card->para[2] - 32;
cs->hw.teles3.hscx[0] = card->para[1] - 32;
cs->hw.teles3.hscx[1] = card->para[1];
teles_setup_io(cs, card);
if (!request_io(&cs->rs, cs->hw.teles3.cfg_reg, 1, "teles3 cfg"))
goto err;
if (teles_request_io(cs) < 0)
goto err;
if (teles_hw_init(cs) < 0)
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
static int __init
telespnp_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
cs->hw.teles3.cfg_reg = 0;
cs->hw.teles3.isac = card->para[1] - 32;
cs->hw.teles3.hscx[0] = card->para[2] - 32;
cs->hw.teles3.hscx[1] = card->para[2];
teles_setup_io(cs, card);
if (teles_request_io(cs) < 0)
goto err;
if (teles_hw_init(cs) < 0)
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
#ifdef __ISAPNP__
static struct isapnp_device_id teles_ids[] __initdata = {
{ ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2110),
......@@ -197,16 +343,10 @@ static struct pnp_card *pnp_c __devinitdata = NULL;
int __devinit
setup_teles3(struct IsdnCard *card)
{
u8 val;
struct IsdnCardState *cs = card->cs;
char tmp[64];
strcpy(tmp, teles3_revision);
printk(KERN_INFO "HiSax: Teles IO driver Rev. %s\n", HiSax_getrev(tmp));
if ((cs->typ != ISDN_CTYPE_16_3) && (cs->typ != ISDN_CTYPE_PNP)
&& (cs->typ != ISDN_CTYPE_TELESPCMCIA) && (cs->typ != ISDN_CTYPE_COMPAQ_ISA))
return (0);
#ifdef __ISAPNP__
if (!card->para[1] && isapnp_present()) {
struct pnp_card *pnp_card;
......@@ -258,100 +398,18 @@ setup_teles3(struct IsdnCard *card)
}
}
#endif
if (cs->typ == ISDN_CTYPE_16_3) {
cs->hw.teles3.cfg_reg = card->para[1];
switch (cs->hw.teles3.cfg_reg) {
case 0x180:
case 0x280:
case 0x380:
cs->hw.teles3.cfg_reg |= 0xc00;
break;
}
cs->hw.teles3.isac = cs->hw.teles3.cfg_reg - 0x420;
cs->hw.teles3.hscx[0] = cs->hw.teles3.cfg_reg - 0xc20;
cs->hw.teles3.hscx[1] = cs->hw.teles3.cfg_reg - 0x820;
} else if (cs->typ == ISDN_CTYPE_TELESPCMCIA) {
cs->hw.teles3.cfg_reg = 0;
cs->hw.teles3.hscx[0] = card->para[1] - 0x20;
cs->hw.teles3.hscx[1] = card->para[1];
cs->hw.teles3.isac = card->para[1] + 0x20;
} else if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
cs->hw.teles3.cfg_reg = card->para[3];
cs->hw.teles3.isac = card->para[2] - 32;
cs->hw.teles3.hscx[0] = card->para[1] - 32;
cs->hw.teles3.hscx[1] = card->para[1];
if (card->cs->typ == ISDN_CTYPE_16_3) {
if (teles16_3_probe(card->cs, card) < 0)
return 0;
} else if (card->cs->typ == ISDN_CTYPE_TELESPCMCIA) {
if (telespcmcia_probe(card->cs, card) < 0)
return 0;
} else if (card->cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
if (compaq_probe(card->cs, card) < 0)
return 0;
} else { /* PNP */
cs->hw.teles3.cfg_reg = 0;
cs->hw.teles3.isac = card->para[1] - 32;
cs->hw.teles3.hscx[0] = card->para[2] - 32;
cs->hw.teles3.hscx[1] = card->para[2];
}
cs->irq = card->para[0];
cs->hw.teles3.isacfifo = cs->hw.teles3.isac + 0x3e;
cs->hw.teles3.hscxfifo[0] = cs->hw.teles3.hscx[0] + 0x3e;
cs->hw.teles3.hscxfifo[1] = cs->hw.teles3.hscx[1] + 0x3e;
if (cs->typ == ISDN_CTYPE_TELESPCMCIA) {
if (!request_io(&cs->rs, cs->hw.teles3.hscx[1], 96, "HiSax Teles PCMCIA"))
goto err;
} else {
if (cs->hw.teles3.cfg_reg) {
if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
if (!request_io(&cs->rs, cs->hw.teles3.cfg_reg, 1, "teles3 cfg"))
goto err;
} else {
if (!request_io(&cs->rs, cs->hw.teles3.cfg_reg, 8, "teles3 cfg"))
goto err;
}
}
if (!request_io(&cs->rs, cs->hw.teles3.isac + 32, 32, "HiSax isac"))
goto err;
if (!request_io(&cs->rs, cs->hw.teles3.hscx[0] + 32, 32, "HiSax hscx A"))
goto err;
if (!request_io(&cs->rs, cs->hw.teles3.hscx[1] + 32, 32, "HiSax hscx B"))
goto err;
}
if ((cs->hw.teles3.cfg_reg) && (cs->typ != ISDN_CTYPE_COMPAQ_ISA)) {
if ((val = bytein(cs->hw.teles3.cfg_reg + 0)) != 0x51) {
printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n",
cs->hw.teles3.cfg_reg + 0, val);
goto err;
}
if ((val = bytein(cs->hw.teles3.cfg_reg + 1)) != 0x93) {
printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n",
cs->hw.teles3.cfg_reg + 1, val);
goto err;
}
val = bytein(cs->hw.teles3.cfg_reg + 2);/* 0x1e=without AB
* 0x1f=with AB
* 0x1c 16.3 ???
* 0x39 16.3 1.1
* 0x38 16.3 1.3
* 0x46 16.3 with AB + Video (Teles-Vision)
*/
if (val != 0x46 && val != 0x39 && val != 0x38 && val != 0x1c && val != 0x1e && val != 0x1f) {
printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n",
cs->hw.teles3.cfg_reg + 2, val);
goto err;
}
}
printk(KERN_INFO
"HiSax: %s config irq:%d isac:0x%X cfg:0x%X\n",
CardType[cs->typ], cs->irq,
cs->hw.teles3.isac + 32, cs->hw.teles3.cfg_reg);
printk(KERN_INFO
"HiSax: hscx A:0x%X hscx B:0x%X\n",
cs->hw.teles3.hscx[0] + 32, cs->hw.teles3.hscx[1] + 32);
if (teles3_reset(cs)) {
printk(KERN_WARNING "Teles3: wrong IRQ\n");
goto err;
if (telespnp_probe(card->cs, card) < 0)
return 0;
}
cs->card_ops = &teles3_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err;
return 1;
err:
hisax_release_resources(cs);
return 0;
}
......@@ -231,36 +231,23 @@ static struct card_ops telespci_ops = {
.irq_func = telespci_interrupt,
};
static struct pci_dev *dev_tel __initdata = NULL;
int __init
setup_telespci(struct IsdnCard *card)
static int __init
telespci_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
{
struct IsdnCardState *cs = card->cs;
char tmp[64];
int rc;
#ifdef __BIG_ENDIAN
#error "not running on big endian machines now"
#endif
strcpy(tmp, telespci_revision);
printk(KERN_INFO "HiSax: Teles/PCI driver Rev. %s\n", HiSax_getrev(tmp));
if ((dev_tel = pci_find_device (PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36120, dev_tel))) {
if (pci_enable_device(dev_tel))
return(0);
cs->irq = dev_tel->irq;
if (!cs->irq) {
printk(KERN_WARNING "Teles: No IRQ for PCI card found\n");
return(0);
}
cs->hw.teles0.membase = request_mmio(&cs->rs, pci_resource_start(dev_tel, 0), 4096, "telespci");
if (!cs->hw.teles0.membase)
goto err;
printk(KERN_INFO "Found: Zoran, base-address: 0x%lx, irq: 0x%x\n",
pci_resource_start(dev_tel, 0), dev_tel->irq);
} else {
printk(KERN_WARNING "TelesPCI: No PCI card found\n");
return(0);
}
printk(KERN_INFO "TelesPCI: defined at %#lx IRQ %d\n",
pci_resource_start(pdev, 0), pdev->irq);
rc = -EBUSY;
if (pci_enable_device(pdev))
goto err;
cs->irq = pdev->irq;
cs->irq_flags |= SA_SHIRQ;
cs->hw.teles0.membase = request_mmio(&cs->rs, pci_resource_start(pdev, 0), 4096, "telespci");
if (!cs->hw.teles0.membase)
goto err;
/* Initialize Zoran PCI controller */
writel(0x00000000, cs->hw.teles0.membase + 0x28);
......@@ -270,17 +257,36 @@ setup_telespci(struct IsdnCard *card)
writel(0x70000000, cs->hw.teles0.membase + 0x3C);
writel(0x61000000, cs->hw.teles0.membase + 0x40);
/* writel(0x00800000, cs->hw.teles0.membase + 0x200); */
printk(KERN_INFO
"HiSax: %s config irq:%d mem:%p\n",
CardType[cs->typ], cs->irq,
cs->hw.teles0.membase);
cs->irq_flags |= SA_SHIRQ;
cs->card_ops = &telespci_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err;
return 1;
return 0;
err:
hisax_release_resources(cs);
return rc;
}
static struct pci_dev *dev_tel __initdata = NULL;
int __init
setup_telespci(struct IsdnCard *card)
{
char tmp[64];
#ifdef __BIG_ENDIAN
#error "not running on big endian machines now"
#endif
strcpy(tmp, telespci_revision);
printk(KERN_INFO "HiSax: Teles/PCI driver Rev. %s\n",
HiSax_getrev(tmp));
dev_tel = pci_find_device(PCI_VENDOR_ID_ZORAN,
PCI_DEVICE_ID_ZORAN_36120, dev_tel);
if (dev_tel) {
if (telespci_probe(card->cs, dev_tel) < 0)
return 0;
return 1;
}
printk(KERN_WARNING "TelesPCI: No PCI card found\n");
return 0;
}
......@@ -669,11 +669,11 @@ static int id_idx ;
static struct pci_dev *dev_w6692 __initdata = NULL;
static int
w6692_setup(struct IsdnCardState *cs, struct dc_hw_ops *dc_ops,
struct bc_hw_ops *bc_ops)
w6692_hw_init(struct IsdnCardState *cs)
{
cs->dc_hw_ops = dc_ops;
cs->bc_hw_ops = bc_ops;
cs->card_ops = &w6692_ops;
cs->dc_hw_ops = &w6692_dc_hw_ops,
cs->bc_hw_ops = &w6692_bc_hw_ops;
dc_l1_init(cs, &w6692_dc_l1_ops);
cs->bc_l1_ops = &w6692_bc_l1_ops;
W6692Version(cs, "W6692:");
......@@ -685,14 +685,45 @@ w6692_setup(struct IsdnCardState *cs, struct dc_hw_ops *dc_ops,
return 0;
}
static int __init
w6692_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
{
int rc;
printk(KERN_INFO "W6692: %s %s at %#lx IRQ %d\n",
id_list[cs->subtyp].vendor_name, id_list[cs->subtyp].card_name,
pci_resource_start(pdev, 1), pdev->irq);
rc = -EBUSY;
if (pci_enable_device(pdev))
goto err;
/* USR ISDN PCI card TA need some special handling */
if (cs->subtyp == W6692_WINBOND) {
if (pdev->subsystem_vendor == W6692_SV_USR &&
pdev->subsystem_device == W6692_SD_USR) {
cs->subtyp = W6692_USR;
}
}
cs->irq = pdev->irq;
cs->irq_flags |= SA_SHIRQ;
cs->hw.w6692.iobase = pci_resource_start(pdev, 1);
if (!request_io(&cs->rs, cs->hw.w6692.iobase, 0x100,
id_list[cs->subtyp].card_name))
goto err;
w6692_hw_init(cs);
return 0;
err:
hisax_release_resources(cs);
return rc;
}
int __init
setup_w6692(struct IsdnCard *card)
{
struct IsdnCardState *cs = card->cs;
char tmp[64];
u8 found = 0;
u8 pci_irq = 0;
u_int pci_ioaddr = 0;
#ifdef __BIG_ENDIAN
#error "not running on big endian machines now"
......@@ -704,54 +735,13 @@ setup_w6692(struct IsdnCard *card)
id_list[id_idx].device_id,
dev_w6692);
if (dev_w6692) {
if (pci_enable_device(dev_w6692))
continue;
cs->subtyp = id_idx;
break;
card->cs->subtyp = id_idx;
if (w6692_probe(card->cs, dev_w6692) < 0)
return 0;
return 1;
}
id_idx++;
}
if (dev_w6692) {
found = 1;
pci_irq = dev_w6692->irq;
/* I think address 0 is allways the configuration area */
/* and address 1 is the real IO space KKe 03.09.99 */
pci_ioaddr = pci_resource_start(dev_w6692, 1);
/* USR ISDN PCI card TA need some special handling */
if (cs->subtyp == W6692_WINBOND) {
if ((W6692_SV_USR == dev_w6692->subsystem_vendor) &&
(W6692_SD_USR == dev_w6692->subsystem_device)) {
cs->subtyp = W6692_USR;
}
}
}
if (!found) {
printk(KERN_WARNING "W6692: No PCI card found\n");
return (0);
}
cs->irq = pci_irq;
if (!cs->irq) {
printk(KERN_WARNING "W6692: No IRQ for PCI card found\n");
return (0);
}
if (!pci_ioaddr) {
printk(KERN_WARNING "W6692: NO I/O Base Address found\n");
return (0);
}
cs->hw.w6692.iobase = pci_ioaddr;
printk(KERN_INFO "Found: %s %s, I/O base: 0x%x, irq: %d\n",
id_list[cs->subtyp].vendor_name, id_list[cs->subtyp].card_name,
pci_ioaddr, pci_irq);
if (!request_io(&cs->rs, cs->hw.w6692.iobase, 0x100, id_list[cs->subtyp].card_name))
return 0;
printk(KERN_INFO
"HiSax: %s config irq:%d I/O:%x\n",
id_list[cs->subtyp].card_name, cs->irq,
cs->hw.w6692.iobase);
cs->card_ops = &w6692_ops;
w6692_setup(cs, &w6692_dc_hw_ops, &w6692_bc_hw_ops);
cs->irq_flags |= SA_SHIRQ;
return (1);
printk(KERN_WARNING "W6692: No PCI card found\n");
return 0;
}
......@@ -85,7 +85,7 @@ config ISDN_TTY_FAX
config ISDN_X25
bool "X.25 PLP on top of ISDN"
depends on X25
depends on X25 && BROKEN
help
This feature provides the X.25 protocol over ISDN connections.
See <file:Documentation/isdn/README.x25> for more information
......
......@@ -58,6 +58,7 @@
#include "isdn_net.h"
#include "isdn_ppp.h"
#include "isdn_ciscohdlck.h"
#include "isdn_concap.h"
#define ISDN_NET_TX_TIMEOUT (20*HZ)
......
......@@ -867,7 +867,7 @@ isdn_ppp_strip_proto(struct sk_buff *skb, u16 *proto)
skb_pull(skb, 1);
} else {
if (skb->len < 2)
return -1;
return -EINVAL;
get_u16(skb->data, proto);
skb_pull(skb, 2);
}
......@@ -1037,7 +1037,7 @@ isdn_ppp_start_xmit(struct sk_buff *skb, struct net_device *ndev)
isdn_ppp_frame_log("xmit1", skb->data, skb->len, 32, ipppd->unit, -1);
ippp_push_proto(ind_ppp, skb, proto);
ippp_mp_xmit(idev, skb, proto);
ippp_mp_xmit(idev, skb);
return 0;
drop:
......
......@@ -91,12 +91,13 @@ ippp_mp_disconnected(isdn_net_dev *idev)
}
void
ippp_mp_xmit(isdn_net_dev *idev, struct sk_buff *skb, u16 proto)
ippp_mp_xmit(isdn_net_dev *idev, struct sk_buff *skb)
{
struct ind_ppp *ind_ppp = idev->ind_priv;
struct inl_ppp *inl_ppp = idev->mlp->inl_priv;
unsigned char *p;
long txseq;
u32 txseq;
u16 proto;
if (!(inl_ppp->mp_cfg & SC_MP_PROT)) {
return ippp_xmit(idev, skb);
......
......@@ -19,7 +19,7 @@
int ippp_mp_bind(isdn_net_dev *idev);
void ippp_mp_disconnected(isdn_net_dev *idev);
int ippp_mp_bundle(isdn_net_dev *idev, int val);
void ippp_mp_xmit(isdn_net_dev *idev, struct sk_buff *skb, u16 proto);
void ippp_mp_xmit(isdn_net_dev *idev, struct sk_buff *skb);
void ippp_mp_receive(isdn_net_dev *idev, struct sk_buff *skb, u16 proto);
#else
......@@ -42,9 +42,9 @@ ippp_mp_bundle(isdn_net_dev *idev, int val)
}
static inline void
ippp_mp_xmit(isdn_net_dev *idev, struct sk_buff *skb, u16 proto)
ippp_mp_xmit(isdn_net_dev *idev, struct sk_buff *skb)
{
ippp_xmit(idev, skb, proto);
ippp_xmit(idev, skb);
}
static inline void
......
......@@ -483,8 +483,6 @@ EXPORT_SYMBOL(task_nice);
EXPORT_SYMBOL_GPL(idle_cpu);
#if CONFIG_SMP
EXPORT_SYMBOL_GPL(set_cpus_allowed);
#endif
#if CONFIG_SMP || CONFIG_PREEMPT
EXPORT_SYMBOL(kernel_flag);
#endif
EXPORT_SYMBOL(jiffies);
......
......@@ -2426,7 +2426,7 @@ __init int migration_init(void)
#endif
#if CONFIG_SMP || CONFIG_PREEMPT
#if CONFIG_SMP
/*
* The 'big kernel lock'
*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment