replaced outdated driver for kernels 2.4.20 and higher
This commit is contained in:
parent
215c508126
commit
687a87f360
|
@ -104,7 +104,10 @@ if [ "$CONFIG_ISDN_DRV_HISAX" != "n" ]; then
|
|||
|
||||
dep_tristate 'Sedlbauer PCMCIA cards' CONFIG_HISAX_SEDLBAUER_CS $CONFIG_PCMCIA
|
||||
dep_tristate 'ELSA PCMCIA MicroLink cards' CONFIG_HISAX_ELSA_CS $CONFIG_PCMCIA
|
||||
dep_tristate 'Colognechip HFC-USB support' CONFIG_HISAX_HFC_USB_CS $CONFIG_HISAX $CONFIG_USB
|
||||
dep_tristate 'Cologne Chip AG HFC-S USB support (EXPERIMENTAL)' CONFIG_HISAX_HFC_USB_CS $CONFIG_HISAX $CONFIG_USB
|
||||
if [ "$CONFIG_HISAX_HFCUSB_CS" != "n" ]; then
|
||||
bool ' skip module usage counting (not recommended)' CONFIG_HFC_USB_SKIP_MOD_COUNTING
|
||||
fi
|
||||
dep_tristate 'ST5481 USB ISDN modem (EXPERIMENTAL)' CONFIG_HISAX_ST5481 $CONFIG_HISAX $CONFIG_USB $CONFIG_EXPERIMENTAL
|
||||
dep_tristate 'Fritz!PCIv2 support (EXPERIMENTAL)' CONFIG_HISAX_FRITZ_PCIPNP $CONFIG_HISAX $CONFIG_EXPERIMENTAL
|
||||
|
||||
|
|
|
@ -10,11 +10,12 @@ export-objs := config.o fsm.o hisax_isac.o
|
|||
|
||||
# Multipart objects.
|
||||
|
||||
list-multi := hisax.o hisax_st5481.o
|
||||
list-multi := hisax.o hisax_st5481.o hfc_usb.o
|
||||
hisax-objs := config.o isdnl1.o tei.o isdnl2.o isdnl3.o \
|
||||
lmgr.o q931.o callc.o fsm.o cert.o
|
||||
hisax_st5481-objs := st5481_init.o st5481_usb.o st5481_d.o st5481_b.o \
|
||||
st5481_hdlc.o
|
||||
hfc_usb-objs := hfc_usb.o
|
||||
|
||||
# Optional parts of multipart objects.
|
||||
hisax-objs-$(CONFIG_HISAX_EURO) += l3dss1.o
|
||||
|
@ -41,7 +42,6 @@ hisax-objs-$(CONFIG_HISAX_NETJET_U) += nj_u.o netjet.o icc.o
|
|||
hisax-objs-$(CONFIG_HISAX_HFCS) += hfcscard.o hfc_2bds0.o
|
||||
hisax-objs-$(CONFIG_HISAX_HFC_PCI) += hfc_pci.o
|
||||
hisax-objs-$(CONFIG_HISAX_HFC_SX) += hfc_sx.o
|
||||
hisax-objs-$(CONFIG_HISAX_HFC_USB) += hfc_usbr.o
|
||||
hisax-objs-$(CONFIG_HISAX_NICCY) += niccy.o isac.o arcofi.o hscx.o
|
||||
hisax-objs-$(CONFIG_HISAX_ISURF) += isurf.o isac.o arcofi.o isar.o
|
||||
hisax-objs-$(CONFIG_HISAX_HSTSAPHIR) += saphir.o isac.o arcofi.o hscx.o
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,471 +0,0 @@
|
|||
/* $Id$
|
||||
|
||||
* hfc_usb.c low level driver for CCD´s hfc-usb single chip controllers
|
||||
* type approval valid for HFC-S USB based TAs
|
||||
*
|
||||
* Author Werner Cornelius (werner@isdn-development.de)
|
||||
*
|
||||
* Copyright 2001 by Werner Cornelius (werner@isdn4linux.de)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#define __NO_VERSION__
|
||||
#include <linux/init.h>
|
||||
#include "hisax.h"
|
||||
#include "isdnl1.h"
|
||||
#include "hisax_loadable.h"
|
||||
|
||||
extern const char *CardType[];
|
||||
|
||||
static const char *hfcusb_revision = "$Revision$";
|
||||
|
||||
/*********************************/
|
||||
/* schedule a new b_channel task */
|
||||
/*********************************/
|
||||
static void
|
||||
hfcusb_sched_event(struct BCState *bcs, int event)
|
||||
{
|
||||
bcs->event |= 1 << event;
|
||||
queue_task(&bcs->tqueue, &tq_immediate);
|
||||
mark_bh(IMMEDIATE_BH);
|
||||
}
|
||||
|
||||
/************************************************/
|
||||
/* select a b-channel entry matching and active */
|
||||
/************************************************/
|
||||
static
|
||||
struct BCState *
|
||||
Sel_BCS(struct IsdnCardState *cs, int channel)
|
||||
{
|
||||
if (cs->bcs[0].mode && (cs->bcs[0].channel == channel))
|
||||
return (&cs->bcs[0]);
|
||||
else if (cs->bcs[1].mode && (cs->bcs[1].channel == channel))
|
||||
return (&cs->bcs[1]);
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
/* transfer function (D-channel from l2 to l1 */
|
||||
/**********************************************/
|
||||
static void
|
||||
hfcusb_d_l2l1(struct PStack *st, int pr, void *arg)
|
||||
{
|
||||
struct IsdnCardState *cs = st->l1.hardware;
|
||||
struct hisax_drvreg *drv = cs->hw.hfcusb.drv;
|
||||
|
||||
if (drv) {
|
||||
switch (pr) {
|
||||
case (PH_DATA | REQUEST):
|
||||
case (PH_PULL | INDICATION):
|
||||
cs->hw.hfcusb.dch_tx_busy = 1;
|
||||
break;
|
||||
case (PH_PULL | REQUEST):
|
||||
if (!cs->hw.hfcusb.dch_tx_busy) {
|
||||
test_and_clear_bit(FLG_L1_PULL_REQ,
|
||||
&st->l1.Flags);
|
||||
st->l1.l1l2(st, PH_PULL | CONFIRM,
|
||||
NULL);
|
||||
} else
|
||||
test_and_set_bit(FLG_L1_PULL_REQ,
|
||||
&st->l1.Flags);
|
||||
return;
|
||||
}
|
||||
drv->dch_l2l1(drv, pr, arg);
|
||||
} else
|
||||
debugl1(cs, "hfcusb l2l1 called without existing driver");
|
||||
} /* hfcusb_d_l2l1 */
|
||||
|
||||
/*****************************/
|
||||
/* E-channel receive routine */
|
||||
/*****************************/
|
||||
static void
|
||||
EChannel_proc_rcv(struct IsdnCardState *cs)
|
||||
{
|
||||
u_char *ptr;
|
||||
struct sk_buff *skb;
|
||||
struct hisax_drvreg *usbdrv =
|
||||
(struct hisax_drvreg *) cs->hw.hfcusb.drv;
|
||||
|
||||
|
||||
while ((skb = skb_dequeue(&usbdrv->erq)) != NULL) {
|
||||
if (cs->debug & DEB_DLOG_HEX) {
|
||||
ptr = cs->dlog;
|
||||
if ((skb->len) < MAX_DLOG_SPACE / 3 - 10) {
|
||||
*ptr++ = 'E';
|
||||
*ptr++ = 'C';
|
||||
*ptr++ = 'H';
|
||||
*ptr++ = 'O';
|
||||
*ptr++ = ':';
|
||||
ptr += QuickHex(ptr, skb->data, skb->len);
|
||||
ptr--;
|
||||
*ptr++ = '\n';
|
||||
*ptr = 0;
|
||||
HiSax_putstatus(cs, NULL, cs->dlog);
|
||||
} else
|
||||
HiSax_putstatus(cs, "LogEcho: ",
|
||||
"warning Frame too big (%d)",
|
||||
skb->len);
|
||||
}
|
||||
dev_kfree_skb_any(skb);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************/
|
||||
/* transfer function called from L1 to L2 */
|
||||
/******************************************/
|
||||
static void
|
||||
hfcusb_d_l1l2(void *cs1, int pr, void *arg)
|
||||
{
|
||||
struct IsdnCardState *cs = (struct IsdnCardState *) cs1;
|
||||
|
||||
switch (pr) {
|
||||
case (PH_DATA | INDICATION):
|
||||
if (!((int) arg))
|
||||
DChannel_proc_rcv(cs);
|
||||
else
|
||||
EChannel_proc_rcv(cs);
|
||||
break;
|
||||
|
||||
case (PH_DATA | CONFIRM):
|
||||
cs->hw.hfcusb.dch_tx_busy = 0;
|
||||
DChannel_proc_xmt(cs);
|
||||
break;
|
||||
|
||||
case (PH_ACTIVATE | INDICATION):
|
||||
case (PH_ACTIVATE | CONFIRM):
|
||||
cs->stlist->l1.l1l2(cs->stlist, pr, arg);
|
||||
if (cs->debug & L1_DEB_ISAC)
|
||||
debugl1(cs, "layer 1 activated");
|
||||
break;
|
||||
|
||||
case (PH_DEACTIVATE | INDICATION):
|
||||
case (PH_DEACTIVATE | CONFIRM):
|
||||
cs->stlist->l1.l1l2(cs->stlist, pr, arg);
|
||||
if (cs->debug & L1_DEB_ISAC)
|
||||
debugl1(cs, "layer 1 deactivated");
|
||||
break;
|
||||
|
||||
default:
|
||||
debugl1(cs, "unknown l1 msg 0x%x ", pr);
|
||||
}
|
||||
} /* hfcusb_d_l1l2 */
|
||||
|
||||
|
||||
/******************************************/
|
||||
/* transfer function called from L1 to L2 */
|
||||
/******************************************/
|
||||
static void
|
||||
hfcusb_b_l1l2(void *cs1, int chan, int pr, void *arg)
|
||||
{
|
||||
struct IsdnCardState *cs = (struct IsdnCardState *) cs1;
|
||||
struct BCState *bcs = Sel_BCS(cs, chan);
|
||||
|
||||
switch (pr) {
|
||||
case (PH_DATA | INDICATION):
|
||||
if (!bcs)
|
||||
return;
|
||||
hfcusb_sched_event(bcs, B_RCVBUFREADY);
|
||||
break;
|
||||
|
||||
case (PH_DATA | CONFIRM):
|
||||
if (!bcs)
|
||||
return;
|
||||
bcs->tx_cnt -= bcs->tx_skb->len;
|
||||
if (bcs->st->lli.l1writewakeup &&
|
||||
(PACKET_NOACK != bcs->tx_skb->pkt_type))
|
||||
bcs->st->lli.l1writewakeup(bcs->st,
|
||||
bcs->tx_skb->
|
||||
len);
|
||||
dev_kfree_skb_any(bcs->tx_skb);
|
||||
bcs->tx_skb = skb_dequeue(&bcs->squeue);
|
||||
break;
|
||||
|
||||
case (PH_ACTIVATE | INDICATION):
|
||||
case (PH_ACTIVATE | CONFIRM):
|
||||
cs->stlist->l1.l1l2(cs->stlist, pr, arg);
|
||||
if (cs->debug & L1_DEB_ISAC)
|
||||
debugl1(cs, "layer 1 activated");
|
||||
break;
|
||||
|
||||
case (PH_DEACTIVATE | INDICATION):
|
||||
case (PH_DEACTIVATE | CONFIRM):
|
||||
cs->stlist->l1.l1l2(cs->stlist, pr, arg);
|
||||
if (cs->debug & L1_DEB_ISAC)
|
||||
debugl1(cs, "layer 1 deactivated");
|
||||
break;
|
||||
|
||||
default:
|
||||
debugl1(cs, "unknown l1 b msg 0x%x ", pr);
|
||||
}
|
||||
} /* hfcusb_b_l1l2 */
|
||||
|
||||
|
||||
/***********************************************/
|
||||
/* called during init setting l1 stack pointer */
|
||||
/***********************************************/
|
||||
void
|
||||
setstack_hfcusb(struct PStack *st, struct IsdnCardState *cs)
|
||||
{
|
||||
st->l2.l2l1 = hfcusb_d_l2l1;
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
/* send B-channel data if not blocked */
|
||||
/**************************************/
|
||||
static void
|
||||
hfcusb_send_data(struct BCState *bcs)
|
||||
{
|
||||
struct IsdnCardState *cs = bcs->cs;
|
||||
struct hisax_drvreg *drv =
|
||||
(struct hisax_drvreg *) cs->hw.hfcusb.drv;
|
||||
|
||||
if (!drv)
|
||||
return;
|
||||
drv->bch_l2l1(drv->argl1, bcs->channel, PH_DATA | REQUEST,
|
||||
bcs->tx_skb);
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/* activate/deactivate hardware for selected channels and mode */
|
||||
/***************************************************************/
|
||||
void
|
||||
mode_hfcusb(struct BCState *bcs, int mode, int bc)
|
||||
{
|
||||
struct IsdnCardState *cs = bcs->cs;
|
||||
struct hisax_drvreg *drv = cs->hw.hfcusb.drv;
|
||||
|
||||
if (!drv)
|
||||
return;
|
||||
if (cs->debug & L1_DEB_HSCX)
|
||||
debugl1(cs, "HFCUSB bchannel mode %d bchan %d/%d",
|
||||
mode, bc, bcs->channel);
|
||||
bcs->mode = mode;
|
||||
bcs->channel = bc;
|
||||
if (mode) {
|
||||
drv->bsk[bc] = &bcs->tx_skb;
|
||||
drv->brq[bc] = &bcs->rqueue;
|
||||
}
|
||||
drv->bch_l2l1(drv->argl1, bc, PH_ACTIVATE | REQUEST,
|
||||
(void *) mode);
|
||||
if (!mode) {
|
||||
drv->bsk[bc] = NULL;
|
||||
drv->brq[bc] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************/
|
||||
/* Layer2 -> Layer 1 Transfer */
|
||||
/******************************/
|
||||
static void
|
||||
hfcusb_b_l2l1(struct PStack *st, int pr, void *arg)
|
||||
{
|
||||
struct sk_buff *skb = arg;
|
||||
struct hisax_drvreg *drv = st->l1.bcs->cs->hw.hfcusb.drv;
|
||||
long flags;
|
||||
|
||||
switch (pr) {
|
||||
case (PH_DATA | REQUEST):
|
||||
save_flags(flags);
|
||||
cli();
|
||||
if (st->l1.bcs->tx_skb) {
|
||||
skb_queue_tail(&st->l1.bcs->squeue, skb);
|
||||
restore_flags(flags);
|
||||
} else {
|
||||
st->l1.bcs->tx_skb = skb;
|
||||
st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
|
||||
restore_flags(flags);
|
||||
}
|
||||
break;
|
||||
case (PH_PULL | INDICATION):
|
||||
if (st->l1.bcs->tx_skb) {
|
||||
printk(KERN_WARNING
|
||||
"hfc_l2l1: this shouldn't happen\n");
|
||||
break;
|
||||
}
|
||||
save_flags(flags);
|
||||
cli();
|
||||
st->l1.bcs->tx_skb = skb;
|
||||
st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
|
||||
restore_flags(flags);
|
||||
break;
|
||||
case (PH_PULL | REQUEST):
|
||||
if (!st->l1.bcs->tx_skb) {
|
||||
test_and_clear_bit(FLG_L1_PULL_REQ,
|
||||
&st->l1.Flags);
|
||||
st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
|
||||
} else
|
||||
test_and_set_bit(FLG_L1_PULL_REQ,
|
||||
&st->l1.Flags);
|
||||
break;
|
||||
case (PH_ACTIVATE | REQUEST):
|
||||
if (drv) {
|
||||
test_and_set_bit(BC_FLG_ACTIV,
|
||||
&st->l1.bcs->Flag);
|
||||
mode_hfcusb(st->l1.bcs, st->l1.mode,
|
||||
st->l1.bc);
|
||||
l1_msg_b(st, pr, arg);
|
||||
}
|
||||
break;
|
||||
case (PH_DEACTIVATE | REQUEST):
|
||||
l1_msg_b(st, pr, arg);
|
||||
break;
|
||||
case (PH_DEACTIVATE | CONFIRM):
|
||||
test_and_clear_bit(BC_FLG_ACTIV,
|
||||
&st->l1.bcs->Flag);
|
||||
test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
|
||||
mode_hfcusb(st->l1.bcs, 0, st->l1.bc);
|
||||
st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************/
|
||||
/* deactivate B-channel access and queues */
|
||||
/******************************************/
|
||||
static void
|
||||
close_hfcusb(struct BCState *bcs)
|
||||
{
|
||||
mode_hfcusb(bcs, 0, bcs->channel);
|
||||
if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
|
||||
skb_queue_purge(&bcs->rqueue);
|
||||
skb_queue_purge(&bcs->squeue);
|
||||
if (bcs->tx_skb) {
|
||||
dev_kfree_skb_any(bcs->tx_skb);
|
||||
bcs->tx_skb = NULL;
|
||||
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************/
|
||||
/* init B-channel queues and control */
|
||||
/*************************************/
|
||||
static int
|
||||
open_hfcusbstate(struct IsdnCardState *cs, struct BCState *bcs)
|
||||
{
|
||||
if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
|
||||
skb_queue_head_init(&bcs->rqueue);
|
||||
skb_queue_head_init(&bcs->squeue);
|
||||
}
|
||||
bcs->tx_skb = NULL;
|
||||
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
|
||||
bcs->event = 0;
|
||||
bcs->tx_cnt = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*********************************/
|
||||
/* inits the stack for B-channel */
|
||||
/*********************************/
|
||||
static int
|
||||
setstack_2b(struct PStack *st, struct BCState *bcs)
|
||||
{
|
||||
bcs->channel = st->l1.bc;
|
||||
if (open_hfcusbstate(st->l1.hardware, bcs))
|
||||
return (-1);
|
||||
st->l1.bcs = bcs;
|
||||
st->l2.l2l1 = hfcusb_b_l2l1;
|
||||
setstack_manager(st);
|
||||
bcs->st = st;
|
||||
setstack_l1_B(st);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/********************************/
|
||||
/* called for card init message */
|
||||
/********************************/
|
||||
void __devinit
|
||||
inithfcusb(struct IsdnCardState *cs)
|
||||
{
|
||||
cs->setstack_d = setstack_hfcusb;
|
||||
cs->BC_Send_Data = &hfcusb_send_data;
|
||||
cs->bcs[0].BC_SetStack = setstack_2b;
|
||||
cs->bcs[1].BC_SetStack = setstack_2b;
|
||||
cs->bcs[0].BC_Close = close_hfcusb;
|
||||
cs->bcs[1].BC_Close = close_hfcusb;
|
||||
mode_hfcusb(cs->bcs, 0, 0);
|
||||
mode_hfcusb(cs->bcs + 1, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************/
|
||||
/* handle card messages from control layer */
|
||||
/*******************************************/
|
||||
static int
|
||||
hfcusb_card_msg(struct IsdnCardState *cs, int mt, void *arg)
|
||||
{
|
||||
if (cs->debug & L1_DEB_ISAC)
|
||||
debugl1(cs, "HFCUSB: card_msg %x", mt);
|
||||
switch (mt) {
|
||||
case CARD_INIT:
|
||||
inithfcusb(cs);
|
||||
return (0);
|
||||
case CARD_RELEASE:
|
||||
case CARD_RESET:
|
||||
case CARD_TEST:
|
||||
return (0);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
HiSax_closecard(int cardnr);
|
||||
/*****************************/
|
||||
/* release a driver instance */
|
||||
/* called when hardware is */
|
||||
/* no longer present. */
|
||||
/*****************************/
|
||||
static void
|
||||
release_hfcdrv(void *arg)
|
||||
{
|
||||
struct IsdnCardState *cs = (struct IsdnCardState *) arg;
|
||||
|
||||
cs->hw.hfcusb.drv = NULL; /* disable any further use of driver */
|
||||
HiSax_closecard(cs->cardnr);
|
||||
} /* release_hfcdrv */
|
||||
|
||||
/*********************************************/
|
||||
/* called once when a new device is detected */
|
||||
/* initialises local data */
|
||||
/*********************************************/
|
||||
int
|
||||
setup_hfc_usb(struct IsdnCard *card)
|
||||
{
|
||||
struct IsdnCardState *cs = card->cs;
|
||||
char tmp[64];
|
||||
struct hisax_drvreg *usbdrv =
|
||||
(struct hisax_drvreg *) cs->hw.hfcusb.drv;
|
||||
|
||||
if (!usbdrv)
|
||||
return (0); /* no driver data present */
|
||||
|
||||
strcpy(tmp, hfcusb_revision);
|
||||
printk(KERN_INFO "HiSax: HFC-USB driver Rev. %s\n",
|
||||
HiSax_getrev(tmp));
|
||||
|
||||
usbdrv->release_driver = &release_hfcdrv; /* release routine */
|
||||
usbdrv->arg_hisax = (void *) cs; /* parameter for calling */
|
||||
usbdrv->dch_l1l2 = &hfcusb_d_l1l2; /* access from L1 to HiSax */
|
||||
usbdrv->bch_l1l2 = &hfcusb_b_l1l2;
|
||||
usbdrv->drq = &cs->rq;
|
||||
usbdrv->dsq = &cs->sq;
|
||||
cs->cardmsg = &hfcusb_card_msg;
|
||||
return (1); /* success */
|
||||
}
|
Loading…
Reference in New Issue