11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* $Id: avm_pci.c,v 1.29.2.4 2004/02/11 13:21:32 keil Exp $ 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * low level stuff for AVM Fritz!PCI and ISA PnP isdn cards 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Author Karsten Keil 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright by Karsten Keil <keil@isdn4linux.de> 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This software may be used and distributed according to the terms 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of the GNU General Public License, incorporated herein by reference. 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Thanks to AVM, Berlin for information 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "hisax.h" 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "isac.h" 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "isdnl1.h" 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pci.h> 205a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/isapnp.h> 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/interrupt.h> 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const char *avm_pci_rev = "$Revision: 1.29.2.4 $"; 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AVM_FRITZ_PCI 1 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AVM_FRITZ_PNP 2 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_FIFO 0x0 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_STATUS 0x4 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AVM_HDLC_1 0x00 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AVM_HDLC_2 0x01 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AVM_ISAC_FIFO 0x02 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AVM_ISAC_REG_LOW 0x04 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AVM_ISAC_REG_HIGH 0x06 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AVM_STATUS0_IRQ_ISAC 0x01 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AVM_STATUS0_IRQ_HDLC 0x02 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AVM_STATUS0_IRQ_TIMER 0x04 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AVM_STATUS0_IRQ_MASK 0x07 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AVM_STATUS0_RESET 0x01 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AVM_STATUS0_DIS_TIMER 0x02 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AVM_STATUS0_RES_TIMER 0x04 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AVM_STATUS0_ENA_IRQ 0x08 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AVM_STATUS0_TESTBIT 0x10 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AVM_STATUS1_INT_SEL 0x0f 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AVM_STATUS1_ENA_IOM 0x80 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_MODE_ITF_FLG 0x01 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_MODE_TRANS 0x02 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_MODE_CCR_7 0x04 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_MODE_CCR_16 0x08 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_MODE_TESTLOOP 0x80 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_INT_XPR 0x80 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_INT_XDU 0x40 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_INT_RPR 0x20 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_INT_MASK 0xE0 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_STAT_RME 0x01 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_STAT_RDO 0x10 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_STAT_CRCVFRRAB 0x0E 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_STAT_CRCVFR 0x06 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_STAT_RML_MASK 0x3f00 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_CMD_XRS 0x80 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_CMD_XME 0x01 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_CMD_RRS 0x20 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_CMD_XML_MASK 0x3f00 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Interface functions */ 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u_char 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsReadISAC(struct IsdnCardState *cs, u_char offset) 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register u_char idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW; 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register u_char val; 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(idx, cs->hw.avm.cfg_reg + 4); 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = inb(cs->hw.avm.isac + (offset & 0xf)); 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (val); 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsWriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register u_char idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW; 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(idx, cs->hw.avm.cfg_reg + 4); 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(value, cs->hw.avm.isac + (offset & 0xf)); 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 98475be4d85a274d0961593db41cf85689db1d583cJoe PerchesReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(AVM_ISAC_FIFO, cs->hw.avm.cfg_reg + 4); 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds insb(cs->hw.avm.isac, data, size); 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 105475be4d85a274d0961593db41cf85689db1d583cJoe PerchesWriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(AVM_ISAC_FIFO, cs->hw.avm.cfg_reg + 4); 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outsb(cs->hw.avm.isac, data, size); 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline u_int 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsReadHDLCPCI(struct IsdnCardState *cs, int chan, u_char offset) 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register u_int idx = chan ? AVM_HDLC_2 : AVM_HDLC_1; 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register u_int val; 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outl(idx, cs->hw.avm.cfg_reg + 4); 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = inl(cs->hw.avm.isac + offset); 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (val); 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsWriteHDLCPCI(struct IsdnCardState *cs, int chan, u_char offset, u_int value) 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register u_int idx = chan ? AVM_HDLC_2 : AVM_HDLC_1; 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outl(idx, cs->hw.avm.cfg_reg + 4); 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outl(value, cs->hw.avm.isac + offset); 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline u_char 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsReadHDLCPnP(struct IsdnCardState *cs, int chan, u_char offset) 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register u_char idx = chan ? AVM_HDLC_2 : AVM_HDLC_1; 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register u_char val; 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(idx, cs->hw.avm.cfg_reg + 4); 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = inb(cs->hw.avm.isac + offset); 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (val); 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsWriteHDLCPnP(struct IsdnCardState *cs, int chan, u_char offset, u_char value) 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register u_char idx = chan ? AVM_HDLC_2 : AVM_HDLC_1; 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(idx, cs->hw.avm.cfg_reg + 4); 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(value, cs->hw.avm.isac + offset); 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u_char 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsReadHDLC_s(struct IsdnCardState *cs, int chan, u_char offset) 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 154475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (0xff & ReadHDLCPCI(cs, chan, offset)); 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsWriteHDLC_s(struct IsdnCardState *cs, int chan, u_char offset, u_char value) 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds WriteHDLCPCI(cs, chan, offset, value); 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct BCState *Sel_BCS(struct IsdnCardState *cs, int channel) 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->bcs[0].mode && (cs->bcs[0].channel == channel)) 167475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (&cs->bcs[0]); 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (cs->bcs[1].mode && (cs->bcs[1].channel == channel)) 169475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (&cs->bcs[1]); 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 171475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (NULL); 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 174672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic void 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldswrite_ctrl(struct BCState *bcs, int which) { 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bcs->cs->debug & L1_DEB_HSCX) 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(bcs->cs, "hdlc %c wr%x ctrl %x", 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 'A' + bcs->channel, which, bcs->hw.hdlc.ctrl.ctrl); 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bcs->cs->subtyp == AVM_FRITZ_PCI) { 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds WriteHDLCPCI(bcs->cs, bcs->channel, HDLC_STATUS, bcs->hw.hdlc.ctrl.ctrl); 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (which & 4) 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS + 2, 185475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->hw.hdlc.ctrl.sr.mode); 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (which & 2) 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS + 1, 188475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->hw.hdlc.ctrl.sr.xml); 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (which & 1) 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS, 191475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->hw.hdlc.ctrl.sr.cmd); 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 195672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic void 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodehdlc(struct BCState *bcs, int mode, int bc) 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct IsdnCardState *cs = bcs->cs; 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int hdlc = bcs->channel; 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_HSCX) 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hdlc %c mode %d --> %d ichan %d --> %d", 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 'A' + hdlc, bcs->mode, mode, hdlc, bc); 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->hw.hdlc.ctrl.ctrl = 0; 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (mode) { 206475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (-1): /* used for init */ 207475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->mode = 1; 208475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->channel = bc; 209475be4d85a274d0961593db41cf85689db1d583cJoe Perches bc = 0; 210475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (L1_MODE_NULL): 211475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (bcs->mode == L1_MODE_NULL) 212475be4d85a274d0961593db41cf85689db1d583cJoe Perches return; 213475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS; 214475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_TRANS; 215475be4d85a274d0961593db41cf85689db1d583cJoe Perches write_ctrl(bcs, 5); 216475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->mode = L1_MODE_NULL; 217475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->channel = bc; 218475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 219475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (L1_MODE_TRANS): 220475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->mode = mode; 221475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->channel = bc; 222475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS; 223475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_TRANS; 224475be4d85a274d0961593db41cf85689db1d583cJoe Perches write_ctrl(bcs, 5); 225475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS; 226475be4d85a274d0961593db41cf85689db1d583cJoe Perches write_ctrl(bcs, 1); 227475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->hw.hdlc.ctrl.sr.cmd = 0; 228475be4d85a274d0961593db41cf85689db1d583cJoe Perches schedule_event(bcs, B_XMTBUFREADY); 229475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 230475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (L1_MODE_HDLC): 231475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->mode = mode; 232475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->channel = bc; 233475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS; 234475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_ITF_FLG; 235475be4d85a274d0961593db41cf85689db1d583cJoe Perches write_ctrl(bcs, 5); 236475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS; 237475be4d85a274d0961593db41cf85689db1d583cJoe Perches write_ctrl(bcs, 1); 238475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->hw.hdlc.ctrl.sr.cmd = 0; 239475be4d85a274d0961593db41cf85689db1d583cJoe Perches schedule_event(bcs, B_XMTBUFREADY); 240475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldshdlc_empty_fifo(struct BCState *bcs, int count) 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register u_int *ptr; 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char *p; 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char idx = bcs->channel ? AVM_HDLC_2 : AVM_HDLC_1; 250475be4d85a274d0961593db41cf85689db1d583cJoe Perches int cnt = 0; 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct IsdnCardState *cs = bcs->cs; 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hdlc_empty_fifo %d", count); 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bcs->hw.hdlc.rcvidx + count > HSCX_BUFMAX) { 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_WARN) 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hdlc_empty_fifo: incoming packet too large"); 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p = bcs->hw.hdlc.rcvbuf + bcs->hw.hdlc.rcvidx; 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr = (u_int *)p; 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->hw.hdlc.rcvidx += count; 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->subtyp == AVM_FRITZ_PCI) { 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outl(idx, cs->hw.avm.cfg_reg + 4); 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (cnt < count) { 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef __powerpc__ 267475be4d85a274d0961593db41cf85689db1d583cJoe Perches *ptr++ = in_be32((unsigned *)(cs->hw.avm.isac + _IO_BASE)); 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ptr++ = inl(cs->hw.avm.isac); 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* __powerpc__ */ 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cnt += 4; 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(idx, cs->hw.avm.cfg_reg + 4); 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (cnt < count) { 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *p++ = inb(cs->hw.avm.isac); 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cnt++; 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_HSCX_FIFO) { 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *t = bcs->blog; 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->subtyp == AVM_FRITZ_PNP) 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p = (u_char *) ptr; 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds t += sprintf(t, "hdlc_empty_fifo %c cnt %d", 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->channel ? 'B' : 'A', count); 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds QuickHex(t, p, count); 28835a4a5733b0a8290de39558b82896ab795b108a7Kees Cook debugl1(cs, "%s", bcs->blog); 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldshdlc_fill_fifo(struct BCState *bcs) 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct IsdnCardState *cs = bcs->cs; 296475be4d85a274d0961593db41cf85689db1d583cJoe Perches int count, cnt = 0; 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int fifo_size = 32; 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char *p; 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_int *ptr; 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hdlc_fill_fifo"); 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!bcs->tx_skb) 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bcs->tx_skb->len <= 0) 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_XME; 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bcs->tx_skb->len > fifo_size) { 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count = fifo_size; 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count = bcs->tx_skb->len; 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bcs->mode != L1_MODE_TRANS) 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_XME; 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) 3179920239c90d5f6dadfb44325abf3568a5e3fd827Joe Perches debugl1(cs, "hdlc_fill_fifo %d/%u", count, bcs->tx_skb->len); 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p = bcs->tx_skb->data; 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr = (u_int *)p; 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_pull(bcs->tx_skb, count); 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->tx_cnt -= count; 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->hw.hdlc.count += count; 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->hw.hdlc.ctrl.sr.xml = ((count == fifo_size) ? 0 : count); 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_ctrl(bcs, 3); /* sets the correct index too */ 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->subtyp == AVM_FRITZ_PCI) { 326475be4d85a274d0961593db41cf85689db1d583cJoe Perches while (cnt < count) { 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef __powerpc__ 328475be4d85a274d0961593db41cf85689db1d583cJoe Perches out_be32((unsigned *)(cs->hw.avm.isac + _IO_BASE), *ptr++); 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outl(*ptr++, cs->hw.avm.isac); 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* __powerpc__ */ 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cnt += 4; 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 335475be4d85a274d0961593db41cf85689db1d583cJoe Perches while (cnt < count) { 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(*p++, cs->hw.avm.isac); 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cnt++; 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug & L1_DEB_HSCX_FIFO) { 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *t = bcs->blog; 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->subtyp == AVM_FRITZ_PNP) 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p = (u_char *) ptr; 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds t += sprintf(t, "hdlc_fill_fifo %c cnt %d", 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->channel ? 'B' : 'A', count); 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds QuickHex(t, p, count); 34835a4a5733b0a8290de39558b82896ab795b108a7Kees Cook debugl1(cs, "%s", bcs->blog); 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 352858119e159384308a5dde67776691a2ebf70df0fArjan van de Venstatic void 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsHDLC_irq(struct BCState *bcs, u_int stat) { 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int len; 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb; 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bcs->cs->debug & L1_DEB_HSCX) 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(bcs->cs, "ch%d stat %#x", bcs->channel, stat); 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (stat & HDLC_INT_RPR) { 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (stat & HDLC_STAT_RDO) { 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bcs->cs->debug & L1_DEB_HSCX) 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(bcs->cs, "RDO"); 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(bcs->cs, "ch%d stat %#x", bcs->channel, stat); 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->hw.hdlc.ctrl.sr.xml = 0; 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_RRS; 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_ctrl(bcs, 1); 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_RRS; 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_ctrl(bcs, 1); 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->hw.hdlc.rcvidx = 0; 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 372475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (!(len = (stat & HDLC_STAT_RML_MASK) >> 8)) 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = 32; 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hdlc_empty_fifo(bcs, len); 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((stat & HDLC_STAT_RME) || (bcs->mode == L1_MODE_TRANS)) { 376475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (((stat & HDLC_STAT_CRCVFRRAB) == HDLC_STAT_CRCVFR) || 377475be4d85a274d0961593db41cf85689db1d583cJoe Perches (bcs->mode == L1_MODE_TRANS)) { 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(skb = dev_alloc_skb(bcs->hw.hdlc.rcvidx))) 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "HDLC: receive out of memory\n"); 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(skb_put(skb, bcs->hw.hdlc.rcvidx), 382475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->hw.hdlc.rcvbuf, bcs->hw.hdlc.rcvidx); 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_tail(&bcs->rqueue, skb); 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->hw.hdlc.rcvidx = 0; 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds schedule_event(bcs, B_RCVBUFREADY); 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bcs->cs->debug & L1_DEB_HSCX) 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(bcs->cs, "invalid frame"); 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(bcs->cs, "ch%d invalid frame %#x", bcs->channel, stat); 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->hw.hdlc.rcvidx = 0; 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (stat & HDLC_INT_XDU) { 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Here we lost an TX interrupt, so 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * restart transmitting the whole frame. 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bcs->tx_skb) { 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_push(bcs->tx_skb, bcs->hw.hdlc.count); 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->tx_cnt += bcs->hw.hdlc.count; 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->hw.hdlc.count = 0; 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bcs->cs->debug & L1_DEB_WARN) 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(bcs->cs, "ch%d XDU", bcs->channel); 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (bcs->cs->debug & L1_DEB_WARN) 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(bcs->cs, "ch%d XDU without skb", bcs->channel); 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->hw.hdlc.ctrl.sr.xml = 0; 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_XRS; 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_ctrl(bcs, 1); 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_XRS; 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_ctrl(bcs, 1); 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hdlc_fill_fifo(bcs); 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (stat & HDLC_INT_XPR) { 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bcs->tx_skb) { 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bcs->tx_skb->len) { 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hdlc_fill_fifo(bcs); 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 421475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && 422475be4d85a274d0961593db41cf85689db1d583cJoe Perches (PACKET_NOACK != bcs->tx_skb->pkt_type)) { 423475be4d85a274d0961593db41cf85689db1d583cJoe Perches u_long flags; 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&bcs->aclock, flags); 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->ackcnt += bcs->hw.hdlc.count; 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&bcs->aclock, flags); 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds schedule_event(bcs, B_ACKPENDING); 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb_irq(bcs->tx_skb); 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->hw.hdlc.count = 0; 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->tx_skb = NULL; 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->hw.hdlc.count = 0; 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hdlc_fill_fifo(bcs); 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds schedule_event(bcs, B_XMTBUFREADY); 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 445672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline void 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsHDLC_irq_main(struct IsdnCardState *cs) 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_int stat; 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct BCState *bcs; 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->subtyp == AVM_FRITZ_PCI) { 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stat = ReadHDLCPCI(cs, 0, HDLC_STATUS); 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stat = ReadHDLCPnP(cs, 0, HDLC_STATUS); 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (stat & HDLC_INT_RPR) 456475be4d85a274d0961593db41cf85689db1d583cJoe Perches stat |= (ReadHDLCPnP(cs, 0, HDLC_STATUS + 1)) << 8; 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (stat & HDLC_INT_MASK) { 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(bcs = Sel_BCS(cs, 0))) { 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug) 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hdlc spurious channel 0 IRQ"); 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds HDLC_irq(bcs, stat); 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->subtyp == AVM_FRITZ_PCI) { 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stat = ReadHDLCPCI(cs, 1, HDLC_STATUS); 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stat = ReadHDLCPnP(cs, 1, HDLC_STATUS); 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (stat & HDLC_INT_RPR) 470475be4d85a274d0961593db41cf85689db1d583cJoe Perches stat |= (ReadHDLCPnP(cs, 1, HDLC_STATUS + 1)) << 8; 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (stat & HDLC_INT_MASK) { 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(bcs = Sel_BCS(cs, 1))) { 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->debug) 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "hdlc spurious channel 1 IRQ"); 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds HDLC_irq(bcs, stat); 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 481672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic void 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldshdlc_l2l1(struct PStack *st, int pr, void *arg) 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct BCState *bcs = st->l1.bcs; 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_long flags; 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (pr) { 489475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_DATA | REQUEST): 490475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_lock_irqsave(&bcs->cs->lock, flags); 491475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (bcs->tx_skb) { 492475be4d85a274d0961593db41cf85689db1d583cJoe Perches skb_queue_tail(&bcs->squeue, skb); 493475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else { 494475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->tx_skb = skb; 495475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); 496475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->hw.hdlc.count = 0; 497475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->cs->BC_Send_Data(bcs); 498475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 499475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_unlock_irqrestore(&bcs->cs->lock, flags); 500475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 501475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_PULL | INDICATION): 502475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_lock_irqsave(&bcs->cs->lock, flags); 503475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (bcs->tx_skb) { 504475be4d85a274d0961593db41cf85689db1d583cJoe Perches printk(KERN_WARNING "hdlc_l2l1: this shouldn't happen\n"); 505475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else { 506475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); 507475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->tx_skb = skb; 508475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->hw.hdlc.count = 0; 509475be4d85a274d0961593db41cf85689db1d583cJoe Perches bcs->cs->BC_Send_Data(bcs); 510475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 511475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_unlock_irqrestore(&bcs->cs->lock, flags); 512475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 513475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_PULL | REQUEST): 514475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (!bcs->tx_skb) { 515475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); 516475be4d85a274d0961593db41cf85689db1d583cJoe Perches st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); 517475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else 518475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); 519475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 520475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_ACTIVATE | REQUEST): 521475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_lock_irqsave(&bcs->cs->lock, flags); 522475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag); 523475be4d85a274d0961593db41cf85689db1d583cJoe Perches modehdlc(bcs, st->l1.mode, st->l1.bc); 524475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_unlock_irqrestore(&bcs->cs->lock, flags); 525475be4d85a274d0961593db41cf85689db1d583cJoe Perches l1_msg_b(st, pr, arg); 526475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 527475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_DEACTIVATE | REQUEST): 528475be4d85a274d0961593db41cf85689db1d583cJoe Perches l1_msg_b(st, pr, arg); 529475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 530475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_DEACTIVATE | CONFIRM): 531475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_lock_irqsave(&bcs->cs->lock, flags); 532475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag); 533475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 534475be4d85a274d0961593db41cf85689db1d583cJoe Perches modehdlc(bcs, 0, st->l1.bc); 535475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_unlock_irqrestore(&bcs->cs->lock, flags); 536475be4d85a274d0961593db41cf85689db1d583cJoe Perches st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL); 537475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 541672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic void 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsclose_hdlcstate(struct BCState *bcs) 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds modehdlc(bcs, 0, 0); 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { 5463c7208f253571ee5f157b98f0e315b5172afe092Jesper Juhl kfree(bcs->hw.hdlc.rcvbuf); 5473c7208f253571ee5f157b98f0e315b5172afe092Jesper Juhl bcs->hw.hdlc.rcvbuf = NULL; 5483c7208f253571ee5f157b98f0e315b5172afe092Jesper Juhl kfree(bcs->blog); 5493c7208f253571ee5f157b98f0e315b5172afe092Jesper Juhl bcs->blog = NULL; 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&bcs->rqueue); 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&bcs->squeue); 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bcs->tx_skb) { 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb_any(bcs->tx_skb); 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->tx_skb = NULL; 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 560672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic int 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsopen_hdlcstate(struct IsdnCardState *cs, struct BCState *bcs) 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(bcs->hw.hdlc.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) { 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "HiSax: No memory for hdlc.rcvbuf\n"); 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (1); 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) { 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING 571475be4d85a274d0961593db41cf85689db1d583cJoe Perches "HiSax: No memory for bcs->blog\n"); 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(BC_FLG_INIT, &bcs->Flag); 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(bcs->hw.hdlc.rcvbuf); 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->hw.hdlc.rcvbuf = NULL; 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (2); 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_head_init(&bcs->rqueue); 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_head_init(&bcs->squeue); 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->tx_skb = NULL; 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->event = 0; 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->hw.hdlc.rcvidx = 0; 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->tx_cnt = 0; 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 588672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic int 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssetstack_hdlc(struct PStack *st, struct BCState *bcs) 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->channel = st->l1.bc; 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (open_hdlcstate(st->l1.hardware, bcs)) 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-1); 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l1.bcs = bcs; 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1 = hdlc_l2l1; 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds setstack_manager(st); 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bcs->st = st; 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds setstack_l1_B(st); 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 602672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk#if 0 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid __init 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsclear_pending_hdlc_ints(struct IsdnCardState *cs) 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_int val; 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cs->subtyp == AVM_FRITZ_PCI) { 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = ReadHDLCPCI(cs, 0, HDLC_STATUS); 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "HDLC 1 STA %x", val); 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = ReadHDLCPCI(cs, 1, HDLC_STATUS); 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "HDLC 2 STA %x", val); 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = ReadHDLCPnP(cs, 0, HDLC_STATUS); 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "HDLC 1 STA %x", val); 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 1); 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "HDLC 1 RML %x", val); 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 2); 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "HDLC 1 MODE %x", val); 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 3); 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "HDLC 1 VIN %x", val); 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = ReadHDLCPnP(cs, 1, HDLC_STATUS); 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "HDLC 2 STA %x", val); 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 1); 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "HDLC 2 RML %x", val); 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 2); 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "HDLC 2 MODE %x", val); 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 3); 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debugl1(cs, "HDLC 2 VIN %x", val); 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 632672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk#endif /* 0 */ 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 63467eb5db5874076db01febed5a1a9281628fa9fb4Karsten Keilstatic void 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsinithdlc(struct IsdnCardState *cs) 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->bcs[0].BC_SetStack = setstack_hdlc; 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->bcs[1].BC_SetStack = setstack_hdlc; 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->bcs[0].BC_Close = close_hdlcstate; 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->bcs[1].BC_Close = close_hdlcstate; 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds modehdlc(cs->bcs, -1, 0); 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds modehdlc(cs->bcs + 1, -1, 1); 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic irqreturn_t 6467d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsavm_pcipnp_interrupt(int intno, void *dev_id) 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct IsdnCardState *cs = dev_id; 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_long flags; 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char val; 6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char sval; 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&cs->lock, flags); 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sval = inb(cs->hw.avm.cfg_reg + 2); 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK) { 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* possible a shared IRQ reqest */ 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&cs->lock, flags); 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return IRQ_NONE; 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(sval & AVM_STATUS0_IRQ_ISAC)) { 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = ReadISAC(cs, ISAC_ISTA); 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds isac_interrupt(cs, val); 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(sval & AVM_STATUS0_IRQ_HDLC)) { 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds HDLC_irq_main(cs); 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds WriteISAC(cs, ISAC_MASK, 0xFF); 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds WriteISAC(cs, ISAC_MASK, 0x0); 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&cs->lock, flags); 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return IRQ_HANDLED; 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsreset_avmpcipnp(struct IsdnCardState *cs) 6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "AVM PCI/PnP: reset\n"); 6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(AVM_STATUS0_RESET | AVM_STATUS0_DIS_TIMER, cs->hw.avm.cfg_reg + 2); 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mdelay(10); 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER | AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2); 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(AVM_STATUS1_ENA_IOM | cs->irq, cs->hw.avm.cfg_reg + 3); 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mdelay(10); 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "AVM PCI/PnP: S1 %x\n", inb(cs->hw.avm.cfg_reg + 3)); 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsAVM_card_msg(struct IsdnCardState *cs, int mt, void *arg) 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_long flags; 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (mt) { 691475be4d85a274d0961593db41cf85689db1d583cJoe Perches case CARD_RESET: 692475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_lock_irqsave(&cs->lock, flags); 693475be4d85a274d0961593db41cf85689db1d583cJoe Perches reset_avmpcipnp(cs); 694475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_unlock_irqrestore(&cs->lock, flags); 695475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (0); 696475be4d85a274d0961593db41cf85689db1d583cJoe Perches case CARD_RELEASE: 697475be4d85a274d0961593db41cf85689db1d583cJoe Perches outb(0, cs->hw.avm.cfg_reg + 2); 698475be4d85a274d0961593db41cf85689db1d583cJoe Perches release_region(cs->hw.avm.cfg_reg, 32); 699475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (0); 700475be4d85a274d0961593db41cf85689db1d583cJoe Perches case CARD_INIT: 701475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_lock_irqsave(&cs->lock, flags); 702475be4d85a274d0961593db41cf85689db1d583cJoe Perches reset_avmpcipnp(cs); 703475be4d85a274d0961593db41cf85689db1d583cJoe Perches clear_pending_isac_ints(cs); 704475be4d85a274d0961593db41cf85689db1d583cJoe Perches initisac(cs); 705475be4d85a274d0961593db41cf85689db1d583cJoe Perches inithdlc(cs); 706475be4d85a274d0961593db41cf85689db1d583cJoe Perches outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER, 707475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->hw.avm.cfg_reg + 2); 708475be4d85a274d0961593db41cf85689db1d583cJoe Perches WriteISAC(cs, ISAC_MASK, 0); 709475be4d85a274d0961593db41cf85689db1d583cJoe Perches outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER | 710475be4d85a274d0961593db41cf85689db1d583cJoe Perches AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2); 711475be4d85a274d0961593db41cf85689db1d583cJoe Perches /* RESET Receiver and Transmitter */ 712475be4d85a274d0961593db41cf85689db1d583cJoe Perches WriteISAC(cs, ISAC_CMDR, 0x41); 713475be4d85a274d0961593db41cf85689db1d583cJoe Perches spin_unlock_irqrestore(&cs->lock, flags); 714475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (0); 715475be4d85a274d0961593db41cf85689db1d583cJoe Perches case CARD_TEST: 716475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (0); 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 718475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (0); 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 721ed5a84cdf593e54969518e82762786fbe1284ce4Greg Kroah-Hartmanstatic int avm_setup_rest(struct IsdnCardState *cs) 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_int val, ver; 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10; 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!request_region(cs->hw.avm.cfg_reg, 32, 727475be4d85a274d0961593db41cf85689db1d583cJoe Perches (cs->subtyp == AVM_FRITZ_PCI) ? "avm PCI" : "avm PnP")) { 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING 7292fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik "HiSax: Fritz!PCI/PNP config port %x-%x already in use\n", 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.avm.cfg_reg, 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->hw.avm.cfg_reg + 31); 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cs->subtyp) { 735475be4d85a274d0961593db41cf85689db1d583cJoe Perches case AVM_FRITZ_PCI: 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = inl(cs->hw.avm.cfg_reg); 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "AVM PCI: stat %#x\n", val); 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "AVM PCI: Class %X Rev %d\n", 739475be4d85a274d0961593db41cf85689db1d583cJoe Perches val & 0xff, (val >> 8) & 0xff); 7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->BC_Read_Reg = &ReadHDLC_s; 7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->BC_Write_Reg = &WriteHDLC_s; 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 743475be4d85a274d0961593db41cf85689db1d583cJoe Perches case AVM_FRITZ_PNP: 7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = inb(cs->hw.avm.cfg_reg); 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ver = inb(cs->hw.avm.cfg_reg + 1); 7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "AVM PnP: Class %X Rev %d\n", val, ver); 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->BC_Read_Reg = &ReadHDLCPnP; 7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->BC_Write_Reg = &WriteHDLCPnP; 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 750475be4d85a274d0961593db41cf85689db1d583cJoe Perches default: 751475be4d85a274d0961593db41cf85689db1d583cJoe Perches printk(KERN_WARNING "AVM unknown subtype %d\n", cs->subtyp); 752475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (0); 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "HiSax: %s config irq:%d base:0x%X\n", 755475be4d85a274d0961593db41cf85689db1d583cJoe Perches (cs->subtyp == AVM_FRITZ_PCI) ? "AVM Fritz!PCI" : "AVM Fritz!PnP", 756475be4d85a274d0961593db41cf85689db1d583cJoe Perches cs->irq, cs->hw.avm.cfg_reg); 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds setup_isac(cs); 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->readisac = &ReadISAC; 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->writeisac = &WriteISAC; 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->readisacfifo = &ReadISACfifo; 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->writeisacfifo = &WriteISACfifo; 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->BC_Send_Data = &hdlc_fill_fifo; 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->cardmsg = &AVM_card_msg; 7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->irq_func = &avm_pcipnp_interrupt; 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cs->writeisac(cs, ISAC_MASK, 0xFF); 7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ISACVersion(cs, (cs->subtyp == AVM_FRITZ_PCI) ? "AVM PCI:" : "AVM PnP:"); 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (1); 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7702fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 7712fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik#ifndef __ISAPNP__ 7722fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 773ed5a84cdf593e54969518e82762786fbe1284ce4Greg Kroah-Hartmanstatic int avm_pnp_setup(struct IsdnCardState *cs) 7742fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik{ 775475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (1); /* no-op: success */ 7762fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik} 7772fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 7782fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik#else 7792fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 780ed5a84cdf593e54969518e82762786fbe1284ce4Greg Kroah-Hartmanstatic struct pnp_card *pnp_avm_c = NULL; 7812fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 782ed5a84cdf593e54969518e82762786fbe1284ce4Greg Kroah-Hartmanstatic int avm_pnp_setup(struct IsdnCardState *cs) 7832fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik{ 7842fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik struct pnp_dev *pnp_avm_d = NULL; 7852fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 7862fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik if (!isapnp_present()) 787475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (1); /* no-op: success */ 7882fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 7892fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik if ((pnp_avm_c = pnp_find_card( 790475be4d85a274d0961593db41cf85689db1d583cJoe Perches ISAPNP_VENDOR('A', 'V', 'M'), 791475be4d85a274d0961593db41cf85689db1d583cJoe Perches ISAPNP_FUNCTION(0x0900), pnp_avm_c))) { 7922fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik if ((pnp_avm_d = pnp_find_dev(pnp_avm_c, 793475be4d85a274d0961593db41cf85689db1d583cJoe Perches ISAPNP_VENDOR('A', 'V', 'M'), 794475be4d85a274d0961593db41cf85689db1d583cJoe Perches ISAPNP_FUNCTION(0x0900), pnp_avm_d))) { 7952fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik int err; 7962fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 7972fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik pnp_disable_dev(pnp_avm_d); 7982fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik err = pnp_activate_dev(pnp_avm_d); 799475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (err < 0) { 8002fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", 801475be4d85a274d0961593db41cf85689db1d583cJoe Perches __func__, err); 802475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (0); 8032fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik } 8042fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik cs->hw.avm.cfg_reg = 8052fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik pnp_port_start(pnp_avm_d, 0); 8062fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik cs->irq = pnp_irq(pnp_avm_d, 0); 8072fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik if (!cs->irq) { 8082fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik printk(KERN_ERR "FritzPnP:No IRQ\n"); 809475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (0); 8102fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik } 8112fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik if (!cs->hw.avm.cfg_reg) { 8122fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik printk(KERN_ERR "FritzPnP:No IO address\n"); 813475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (0); 8142fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik } 8152fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik cs->subtyp = AVM_FRITZ_PNP; 8162fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 8172fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik return (2); /* goto 'ready' label */ 8182fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik } 8192fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik } 8202fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 8212fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik return (1); 8222fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik} 8232fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 8242fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik#endif /* __ISAPNP__ */ 8252fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 82641a68a748bbc61f5bcea999e33ba72926dfbe6f7Tilman Schmidt#ifndef CONFIG_PCI 8272fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 828ed5a84cdf593e54969518e82762786fbe1284ce4Greg Kroah-Hartmanstatic int avm_pci_setup(struct IsdnCardState *cs) 8292fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik{ 830475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (1); /* no-op: success */ 8312fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik} 8322fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 8332fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik#else 8342fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 835ed5a84cdf593e54969518e82762786fbe1284ce4Greg Kroah-Hartmanstatic struct pci_dev *dev_avm = NULL; 8362fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 837ed5a84cdf593e54969518e82762786fbe1284ce4Greg Kroah-Hartmanstatic int avm_pci_setup(struct IsdnCardState *cs) 8382fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik{ 83941a68a748bbc61f5bcea999e33ba72926dfbe6f7Tilman Schmidt if ((dev_avm = hisax_find_pci_device(PCI_VENDOR_ID_AVM, 840475be4d85a274d0961593db41cf85689db1d583cJoe Perches PCI_DEVICE_ID_AVM_A1, dev_avm))) { 8412fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 8422fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik if (pci_enable_device(dev_avm)) 843475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (0); 8442fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 8452fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik cs->irq = dev_avm->irq; 8462fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik if (!cs->irq) { 8472fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik printk(KERN_ERR "FritzPCI: No IRQ for PCI card found\n"); 848475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (0); 8492fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik } 8502fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 8512fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik cs->hw.avm.cfg_reg = pci_resource_start(dev_avm, 1); 8522fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik if (!cs->hw.avm.cfg_reg) { 8532fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik printk(KERN_ERR "FritzPCI: No IO-Adr for PCI card found\n"); 854475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (0); 8552fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik } 8562fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 8572fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik cs->subtyp = AVM_FRITZ_PCI; 8582fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik } else { 8592fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik printk(KERN_WARNING "FritzPCI: No PCI card found\n"); 860475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (0); 8612fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik } 8622fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 8632fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik cs->irq_flags |= IRQF_SHARED; 8642fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 8652fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik return (1); 8662fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik} 8672fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 86841a68a748bbc61f5bcea999e33ba72926dfbe6f7Tilman Schmidt#endif /* CONFIG_PCI */ 8692fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 870ed5a84cdf593e54969518e82762786fbe1284ce4Greg Kroah-Hartmanint setup_avm_pcipnp(struct IsdnCard *card) 8712fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik{ 8722fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik struct IsdnCardState *cs = card->cs; 8732fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik char tmp[64]; 8742fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik int rc; 8752fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 8762fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik strcpy(tmp, avm_pci_rev); 8772fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik printk(KERN_INFO "HiSax: AVM PCI driver Rev. %s\n", HiSax_getrev(tmp)); 8782fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 8792fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik if (cs->typ != ISDN_CTYPE_FRITZPCI) 8802fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik return (0); 8812fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 8822fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik if (card->para[1]) { 8832fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik /* old manual method */ 8842fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik cs->hw.avm.cfg_reg = card->para[1]; 8852fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik cs->irq = card->para[0]; 8862fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik cs->subtyp = AVM_FRITZ_PNP; 8872fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik goto ready; 8882fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik } 8892fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 8902fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik rc = avm_pnp_setup(cs); 8912fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik if (rc < 1) 8922fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik return (0); 8932fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik if (rc == 2) 8942fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik goto ready; 8952fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 8962fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik rc = avm_pci_setup(cs); 8972fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik if (rc < 1) 8982fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik return (0); 8992fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik 9002fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzikready: 9012fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik return avm_setup_rest(cs); 9022fbde4c0923f53bca9975a46059b5c481a3551baJeff Garzik} 903