# CONFIG_SCSI_QLOGIC_FAS is not set
CONFIG_SCSI_QLOGIC_ISP=y
# CONFIG_SCSI_SEAGATE is not set
+# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_T128 is not set
# CONFIG_SCSI_U14_34F is not set
# CONFIG_SCSI_ULTRASTOR is not set
static unsigned long previous_irqholder;
-#undef INIT_STUCK
-#define INIT_STUCK 100000000
-
-#undef STUCK
-#define STUCK \
-if (!--stuck) {printk("wait_on_irq CPU#%d stuck at %08lx, waiting for %08lx (local=%d, global=%d)\n", cpu, where, previous_irqholder, local_count, atomic_read(&global_irq_count)); stuck = INIT_STUCK; }
-
static inline void wait_on_irq(int cpu, unsigned long where)
{
- int stuck = INIT_STUCK;
int local_count = local_irq_count[cpu];
/* Are we the only one in an interrupt context? */
* their things before trying to get the lock again.
*/
for (;;) {
- STUCK;
check_smp_invalidate(cpu);
if (atomic_read(&global_irq_count))
continue;
if (global_irq_lock)
continue;
- if (!set_bit(0,&global_irq_lock))
+ if (!test_and_set_bit(0,&global_irq_lock))
break;
}
atomic_add(local_count, &global_irq_count);
}
}
-#undef INIT_STUCK
-#define INIT_STUCK 10000000
-
-#undef STUCK
-#define STUCK \
-if (!--stuck) {printk("get_irqlock stuck at %08lx, waiting for %08lx\n", where, previous_irqholder); stuck = INIT_STUCK;}
-
static inline void get_irqlock(int cpu, unsigned long where)
{
- int stuck = INIT_STUCK;
-
- if (set_bit(0,&global_irq_lock)) {
+ if (test_and_set_bit(0,&global_irq_lock)) {
/* do we already hold the lock? */
if ((unsigned char) cpu == global_irq_holder)
return;
/* Uhhuh.. Somebody else got it. Wait.. */
do {
do {
- STUCK;
check_smp_invalidate(cpu);
} while (test_bit(0,&global_irq_lock));
- } while (set_bit(0,&global_irq_lock));
+ } while (test_and_set_bit(0,&global_irq_lock));
}
/*
* Ok, we got the lock bit.
current->priority = -100;
while(1)
{
- if(cpu_data[hard_smp_processor_id()].hlt_works_ok &&
+ if(cpu_data[smp_processor_id()].hlt_works_ok &&
!hlt_counter && !need_resched)
__asm("hlt");
/*
smp_callin();
while (!smp_commenced)
barrier();
- cpu_idle(NULL);
+ return cpu_idle(NULL);
}
/*
unsigned long flags;
unsigned long cfg;
unsigned long target_map;
- int p=hard_smp_processor_id();
+ int p=smp_processor_id();
int irq;
int ct=0;
void smp_flush_tlb(void)
{
unsigned long flags;
- if(smp_activated && hard_smp_processor_id()!=active_kernel_processor) {
- printk("CPU #%d:Attempted flush tlb IPI when not AKP(=%d)\n",hard_smp_processor_id(),active_kernel_processor);
+ if(smp_activated && smp_processor_id()!=active_kernel_processor) {
+ printk("CPU #%d:Attempted flush tlb IPI when not AKP(=%d)\n",smp_processor_id(),active_kernel_processor);
*(char *)0=0;
}
/* printk("SMI-");*/
void smp_local_timer_interrupt(struct pt_regs * regs)
{
- int cpu = hard_smp_processor_id();
+ int cpu = smp_processor_id();
/*
* The profiling function is SMP safe. (nothing can mess
*/
asmlinkage void smp_reschedule_interrupt(void)
{
- int cpu = hard_smp_processor_id();
+ int cpu = smp_processor_id();
ack_APIC_irq();
/*
*/
asmlinkage void smp_invalidate_interrupt(void)
{
- if (clear_bit(hard_smp_processor_id(), &smp_invalidate_needed))
+ if (test_and_clear_bit(smp_processor_id(), &smp_invalidate_needed))
local_flush_tlb();
ack_APIC_irq ();
*/
asmlinkage void smp_stop_cpu_interrupt(void)
{
- if (cpu_data[hard_smp_processor_id()].hlt_works_ok)
+ if (cpu_data[smp_processor_id()].hlt_works_ok)
for(;;) __asm__("hlt");
for (;;) ;
}
__initfunc(void setup_APIC_clock (void))
{
- int cpu = hard_smp_processor_id();
+ int cpu = smp_processor_id();
unsigned long flags;
static volatile int calibration_lock;
* to do this part of the setup only once ... and it fits
* here best ]
*/
- if (!set_bit(0,&calibration_lock)) {
+ if (!test_and_set_bit(0,&calibration_lock)) {
calibration_result=calibrate_APIC_clock();
/*
*/
int setup_profiling_timer (unsigned int multiplier)
{
- int cpu = hard_smp_processor_id();
+ int cpu = smp_processor_id();
unsigned long flags;
/*
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
+#include <linux/delay.h>
#include <asm/system.h>
#include <asm/uaccess.h>
unlock_kernel();
}
-void enable_NMI(void)
+static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
+{
+ printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n");
+ printk("You probably have a hardware problem with your RAM chips\n");
+}
+
+static void io_check_error(unsigned char reason, struct pt_regs * regs)
{
- unsigned char reason;
unsigned long i;
- reason = inb(0x61);
- printk("NMI reason = %02x\n", reason);
+ printk("NMI: IOCK error (debug interrupt?)\n");
+ show_registers(regs);
+
+ /* Re-enable the IOCK line, wait for a few seconds */
reason |= 8;
outb(reason, 0x61);
- i = 400000000;
- while (--i) ;
+ i = 2000;
+ while (--i) udelay(1000);
reason &= ~8;
outb(reason, 0x61);
}
+static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
+{
+ printk("Uhhuh. NMI received for unknown reason %02x.\n", reason);
+ printk("Dazed and confused, but trying to continue\n");
+ printk("Do you have a strange power saving mode enabled?\n");
+}
+
asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
{
- show_registers(regs);
-#ifdef CONFIG_SMP_NMI_INVAL
- smp_flush_tlb_rcv();
-#else
-#ifndef CONFIG_IGNORE_NMI
- printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n");
- printk("You probably have a hardware problem with your RAM chips or a\n");
- printk("power saving mode enabled.\n");
-#endif
-#endif
- enable_NMI();
+ unsigned char reason = inb(0x61);
+
+ if (reason & 0x80)
+ mem_parity_error(reason, regs);
+ if (reason & 0x40)
+ io_check_error(reason, regs);
+ if (!(reason & 0xc0))
+ unknown_nmi_error(reason, regs);
}
asmlinkage void do_debug(struct pt_regs * regs, long error_code)
if (!tty)
return;
- if (clear_bit(Cy_EVENT_HANGUP, &info->event)) {
+ if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) {
tty_hangup(info->tty);
wake_up_interruptible(&info->open_wait);
info->flags &= ~(ASYNC_NORMAL_ACTIVE|
ASYNC_CALLOUT_ACTIVE);
}
- if (clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) {
+ if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) {
wake_up_interruptible(&info->open_wait);
}
- if (clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) {
+ if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) {
if((tty->flags & (1<< TTY_DO_WRITE_WAKEUP))
&& tty->ldisc.write_wakeup){
(tty->ldisc.write_wakeup)(tty);
if (tty && tty->driver_data)
{
- if (clear_bit(EPCA_EVENT_HANGUP, &ch->event))
+ if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event))
{ /* Begin if clear_bit */
tty_hangup(tty);
if (!tty)
return;
- if (clear_bit(ESP_EVENT_WRITE_WAKEUP, &info->event)) {
+ if (test_and_clear_bit(ESP_EVENT_WRITE_WAKEUP, &info->event)) {
if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
tty->ldisc.write_wakeup)
(tty->ldisc.write_wakeup)(tty);
set_bit(ST_GETSIGS, &portp->state);
if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig, sizeof(asysigs_t), 1)) < 0)
return(rc);
- if (clear_bit(ST_GETSIGS, &portp->state))
+ if (test_and_clear_bit(ST_GETSIGS, &portp->state))
portp->sigs = stli_mktiocm(portp->asig.sigvalue);
stli_mkasysigs(&portp->asig, 1, 1);
if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0)) < 0)
keycode &= 0x7f;
if (up_flag) {
rep = 0;
- if(!clear_bit(keycode, key_down)) {
+ if(!test_and_clear_bit(keycode, key_down)) {
/* unexpected, but this can happen:
maybe this was a key release for a FOCUS 9000
PF key; if we want to see it, we have to clear
if (up_flag) {
rep = 0;
- if(!clear_bit(keycode, key_down)) {
+ if(!test_and_clear_bit(keycode, key_down)) {
/* unexpected, but this can happen:
maybe this was a key release for a FOCUS 9000
PF key; if we want to see it, we have to clear
up_flag = 0;
}
} else
- rep = set_bit(keycode, key_down);
+ rep = test_and_set_bit(keycode, key_down);
if (kbd->kbdmode == VC_MEDIUMRAW) {
/* soon keycodes will require more than one byte */
return;
if (tty->driver.unthrottle &&
- clear_bit(TTY_THROTTLED, &tty->flags))
+ test_and_clear_bit(TTY_THROTTLED, &tty->flags))
tty->driver.unthrottle(tty);
if (tty->link->packet) {
tty->ctrl_status |= TIOCPKT_FLUSHREAD;
if ((tty->read_cnt >= TTY_THRESHOLD_THROTTLE) &&
tty->driver.throttle &&
- !set_bit(TTY_THROTTLED, &tty->flags))
+ !test_and_set_bit(TTY_THROTTLED, &tty->flags))
tty->driver.throttle(tty);
}
if (!tty->read_cnt) {
break;
}
- eol = clear_bit(tty->read_tail,
+ eol = test_and_clear_bit(tty->read_tail,
&tty->read_flags);
c = tty->read_buf[tty->read_tail];
tty->read_tail = ((tty->read_tail+1) &
low-level driver know. */
if (tty->driver.unthrottle &&
(tty->read_cnt <= TTY_THRESHOLD_UNTHROTTLE)
- && clear_bit(TTY_THROTTLED, &tty->flags))
+ && test_and_clear_bit(TTY_THROTTLED, &tty->flags))
tty->driver.unthrottle(tty);
if (b - buf >= minimum || !nr)
size = b - buf;
if (size && nr)
clear_bit(TTY_PUSH, &tty->flags);
- if (!size && clear_bit(TTY_PUSH, &tty->flags))
+ if (!size && test_and_clear_bit(TTY_PUSH, &tty->flags))
goto do_it_again;
if (!size && !retval)
clear_bit(TTY_PUSH, &tty->flags);
if(info && info->magic == PCXX_MAGIC) {
struct tty_struct *tty = info->tty;
if (tty && tty->driver_data) {
- if(clear_bit(PCXE_EVENT_HANGUP, &info->event)) {
+ if(test_and_clear_bit(PCXE_EVENT_HANGUP, &info->event)) {
tty_hangup(tty);
wake_up_interruptible(&info->open_wait);
info->asyncflags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
if(!(tty = port->tty))
return;
- if (clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
+ if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
tty->ldisc.write_wakeup)
(tty->ldisc.write_wakeup)(tty);
if (!tty)
return;
- if (clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+ if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
tty->ldisc.write_wakeup)
(tty->ldisc.write_wakeup)(tty);
bool 'Support audio via ISDN' CONFIG_ISDN_AUDIO
dep_tristate 'ICN 2B and 4B support' CONFIG_ISDN_DRV_ICN $CONFIG_ISDN
dep_tristate 'PCBIT-D support' CONFIG_ISDN_DRV_PCBIT $CONFIG_ISDN
-dep_tristate 'Teles/NICCY1016PC/Creatix support' CONFIG_ISDN_DRV_TELES $CONFIG_ISDN
dep_tristate 'HiSax SiemensChipSet driver support' CONFIG_ISDN_DRV_HISAX $CONFIG_ISDN
if [ "$CONFIG_ISDN_DRV_HISAX" != "n" ]; then
bool 'HiSax Support for Teles 16.0/8.0' CONFIG_HISAX_16_0
SUB_DIRS :=
MOD_SUB_DIRS :=
-ALL_SUB_DIRS := icn teles pcbit hisax
+ALL_SUB_DIRS := icn pcbit hisax
L_OBJS :=
LX_OBJS :=
endif
endif
-ifeq ($(CONFIG_ISDN_DRV_TELES),y)
- L_OBJS += teles/teles.o
- SUB_DIRS += teles
- MOD_SUB_DIRS += teles
-else
- ifeq ($(CONFIG_ISDN_DRV_TELES),m)
- MOD_SUB_DIRS += teles
- endif
-endif
-
ifeq ($(CONFIG_ISDN_DRV_HISAX),y)
L_OBJS += hisax/hisax.o
SUB_DIRS += hisax
+++ /dev/null
-L_OBJS :=
-M_OBJS :=
-O_OBJS := mod.o card.o config.o buffers.o tei.o isdnl2.o isdnl3.o \
-llglue.o q931.o callc.o fsm.o
-
-O_TARGET :=
-ifeq ($(CONFIG_ISDN_DRV_TELES),y)
- O_TARGET += teles.o
-else
- ifeq ($(CONFIG_ISDN_DRV_TELES),m)
- O_TARGET += teles.o
- M_OBJS += teles.o
- endif
-endif
-
-include $(TOPDIR)/Rules.make
-
+++ /dev/null
-/* $Id: buffers.c,v 1.3 1996/05/31 00:56:53 fritz Exp $
- *
- * $Log: buffers.c,v $
- * Revision 1.3 1996/05/31 00:56:53 fritz
- * removed cli() from BufPoolAdd, since it is called
- * with interrupts off anyway.
- *
- * Revision 1.2 1996/04/29 22:48:14 fritz
- * Removed compatibility-macros. No longer needed.
- *
- * Revision 1.1 1996/04/13 10:19:28 fritz
- * Initial revision
- *
- *
- */
-#define __NO_VERSION__
-#include "teles.h"
-#include <linux/mm.h>
-#include <linux/malloc.h>
-
-
-void
-BufPoolInit(struct BufPool *bp, int order, int bpps,
- int maxpages)
-{
-#ifdef DEBUG_MAGIC
- generateerror
- bp->magic = 010167;
-#endif
-
-#if 0
- printk(KERN_DEBUG "BufPoolInit bp %x\n", bp);
-#endif
-
- bp->freelist = NULL;
- bp->pageslist = NULL;
- bp->pageorder = order;
- bp->pagescount = 0;
- bp->bpps = bpps;
- bp->bufsize = BUFFER_SIZE(order, bpps);
- bp->maxpages = maxpages;
-}
-
-int
-BufPoolAdd(struct BufPool *bp, int priority)
-{
- struct Pages *ptr;
- byte *bptr;
- int i;
- struct BufHeader *bh = NULL, *prev, *first;
-
-#if 0
- printk(KERN_DEBUG "BufPoolAdd bp %x\n", bp);
-#endif
-
- ptr = (struct Pages *) __get_free_pages(priority, bp->pageorder, 0);
- if (!ptr) {
- printk(KERN_WARNING "BufPoolAdd couldn't get pages!\n");
- return (-1);
- }
-#if 0
- printk(KERN_DEBUG "Order %d pages allocated at %x\n", bp->pageorder, ptr);
-#endif
-
- ptr->next = bp->pageslist;
- bp->pageslist = ptr;
- bp->pagescount++;
-
- bptr = (byte *) ptr + sizeof(struct Pages *);
-
- i = bp->bpps;
- first = (struct BufHeader *) bptr;
- prev = NULL;
- while (i--) {
- bh = (struct BufHeader *) bptr;
-#ifdef DEBUG_MAGIC
- bh->magic = 020167;
-#endif
- bh->next = prev;
- prev = bh;
- bh->bp = bp;
- bptr += PART_SIZE(bp->pageorder, bp->bpps);
- }
-
- first->next = bp->freelist;
- bp->freelist = bh;
- return (0);
-}
-
-void
-BufPoolFree(struct BufPool *bp)
-{
- struct Pages *p;
-
-#if 0
- printk(KERN_DEBUG "BufPoolFree bp %x\n", bp);
-#endif
-
- while (bp->pagescount--) {
- p = bp->pageslist->next;
- free_pages((unsigned long) bp->pageslist, bp->pageorder);
-#if 0
- printk(KERN_DEBUG "Free pages %x order %d\n", bp->pageslist, bp->pageorder);
-#endif
- bp->pageslist = p;
- }
-}
-
-int
-BufPoolGet(struct BufHeader **bh,
- struct BufPool *bp, int priority, void *heldby, int where)
-{
- long flags;
- int i;
-
-#ifdef DEBUG_MAGIC
- if (bp->magic != 010167) {
- printk(KERN_DEBUG "BufPoolGet: not a BufHeader\n");
- return (-1);
- }
-#endif
-
- save_flags(flags);
- cli();
- i = 0;
- while (!0) {
- if (bp->freelist) {
- *bh = bp->freelist;
- bp->freelist = bp->freelist->next;
- (*bh)->heldby = heldby;
- (*bh)->where = where;
- restore_flags(flags);
- return (0);
- }
- if ((i == 0) && (bp->pagescount < bp->maxpages)) {
- if (BufPoolAdd(bp, priority)) {
- restore_flags(flags);
- return -1;
- }
- i++;
- } else {
- *bh = NULL;
- restore_flags(flags);
- return (-1);
- }
- }
-
-}
-
-void
-BufPoolRelease(struct BufHeader *bh)
-{
- struct BufPool *bp;
- long flags;
-
-#ifdef DEBUG_MAGIC
- if (bh->magic != 020167) {
- printk(KERN_DEBUG "BufPoolRelease: not a BufHeader\n");
- printk(KERN_DEBUG "called from %x\n", __builtin_return_address(0));
- return;
- }
-#endif
-
- bp = bh->bp;
-
-#ifdef DEBUG_MAGIC
- if (bp->magic != 010167) {
- printk(KERN_DEBUG "BufPoolRelease: not a BufPool\n");
- return;
- }
-#endif
-
- save_flags(flags);
- cli();
- bh->next = bp->freelist;
- bp->freelist = bh;
- restore_flags(flags);
-}
-
-void
-BufQueueLink(struct BufQueue *bq,
- struct BufHeader *bh)
-{
- unsigned long flags;
-
- save_flags(flags);
- cli();
- if (!bq->head)
- bq->head = bh;
- if (bq->tail)
- bq->tail->next = bh;
- bq->tail = bh;
- bh->next = NULL;
- restore_flags(flags);
-}
-
-void
-BufQueueLinkFront(struct BufQueue *bq,
- struct BufHeader *bh)
-{
- unsigned long flags;
-
- save_flags(flags);
- cli();
- bh->next = bq->head;
- bq->head = bh;
- if (!bq->tail)
- bq->tail = bh;
- restore_flags(flags);
-}
-
-int
-BufQueueUnlink(struct BufHeader **bh, struct BufQueue *bq)
-{
- long flags;
-
- save_flags(flags);
- cli();
-
- if (bq->head) {
- if (bq->tail == bq->head)
- bq->tail = NULL;
- *bh = bq->head;
- bq->head = (*bh)->next;
- restore_flags(flags);
- return (0);
- } else {
- restore_flags(flags);
- return (-1);
- }
-}
-
-void
-BufQueueInit(struct BufQueue *bq)
-{
-#ifdef DEBUG_MAGIC
- bq->magic = 030167;
-#endif
- bq->head = NULL;
- bq->tail = NULL;
-}
-
-void
-BufQueueRelease(struct BufQueue *bq)
-{
- struct BufHeader *bh;
-
- while (bq->head) {
- BufQueueUnlink(&bh, bq);
- BufPoolRelease(bh);
- }
-}
-
-int
-BufQueueLength(struct BufQueue *bq)
-{
- int i = 0;
- struct BufHeader *bh;
-
- bh = bq->head;
- while (bh) {
- i++;
- bh = bh->next;
- }
- return (i);
-}
-
-void
-BufQueueDiscard(struct BufQueue *q, int pr, void *heldby,
- int releasetoo)
-{
- long flags;
- struct BufHeader *sp;
-
- save_flags(flags);
- cli();
-
- while (!0) {
- sp = q->head;
- if (!sp)
- break;
- if ((sp->primitive == pr) && (sp->heldby == heldby)) {
- q->head = sp->next;
- if (q->tail == sp)
- q->tail = NULL;
- if (releasetoo)
- BufPoolRelease(sp);
- } else
- break;
- }
-
- sp = q->head;
- if (sp)
- while (sp->next) {
- if ((sp->next->primitive == pr) && (sp->next->heldby == heldby)) {
- if (q->tail == sp->next)
- q->tail = sp;
- if (releasetoo)
- BufPoolRelease(sp->next);
- sp->next = sp->next->next;
- } else
- sp = sp->next;
- }
- restore_flags(flags);
-}
-
-void
-Sfree(byte * ptr)
-{
-#if 0
- printk(KERN_DEBUG "Sfree %x\n", ptr);
-#endif
- kfree(ptr);
-}
-
-byte *
-Smalloc(int size, int pr, char *why)
-{
- byte *p;
-
- p = (byte *) kmalloc(size, pr);
-#if 0
- printk(KERN_DEBUG "Smalloc %s size %d res %x\n", why, size, p);
-#endif
- return (p);
-}
+++ /dev/null
-/* $Id: callc.c,v 1.16 1997/02/11 01:39:46 keil Exp $
- *
- * $Log: callc.c,v $
- * Revision 1.16 1997/02/11 01:39:46 keil
- * Changed setup-interface (incoming and outgoing)
- *
- * Revision 1.15 1996/11/23 11:32:20 keil
- * windowsize = 7 X.75 bugfix Thanks to Martin Maurer
- *
- * Revision 1.14 1996/10/22 23:14:14 fritz
- * Changes for compatibility to 2.0.X and 2.1.X kernels.
- *
- * Revision 1.13 1996/06/24 17:15:55 fritz
- * corrected return code of teles_writebuf()
- *
- * Revision 1.12 1996/06/12 16:15:33 fritz
- * Extended user-configurable debugging flags.
- *
- * Revision 1.11 1996/06/07 12:32:20 fritz
- * More changes to support suspend/resume.
- *
- * Revision 1.10 1996/06/06 21:24:21 fritz
- * Started adding support for suspend/resume.
- *
- * Revision 1.9 1996/05/31 12:23:57 jdenoud
- * Jan: added channel open check to teles_writebuf
- *
- * Revision 1.8 1996/05/31 01:00:38 fritz
- * Changed return code of teles_writebuf, when out of memory.
- *
- * Revision 1.7 1996/05/17 03:40:37 fritz
- * General cleanup.
- *
- * Revision 1.6 1996/05/10 22:42:07 fritz
- * Added entry for EV_RELEASE_CNF in ST_OUT (if no D-Channel avail.)
- *
- * Revision 1.5 1996/05/06 10:16:15 fritz
- * Added voice stuff.
- *
- * Revision 1.4 1996/04/30 22:04:05 isdn4dev
- * improved callback Karsten Keil
- *
- * Revision 1.3 1996/04/30 10:04:19 fritz
- * Started voice support.
- * Added printk() to debug-switcher for easier
- * synchronization between printk()'s and output
- * of /dev/isdnctrl.
- *
- * Revision 1.2 1996/04/20 16:42:29 fritz
- * Changed statemachine to allow reject of incoming calls.
- *
- * Revision 1.1 1996/04/13 10:20:59 fritz
- * Initial revision
- *
- *
- */
-#define __NO_VERSION__
-#include "teles.h"
-
-extern struct IsdnCard cards[];
-extern int nrcards;
-extern int drid;
-extern isdn_if iif;
-extern void teles_mod_dec_use_count(void);
-extern void teles_mod_inc_use_count(void);
-
-static int init_ds(int chan, int incoming);
-static void release_ds(int chan);
-
-static struct Fsm callcfsm =
-{NULL, 0, 0}, lcfsm =
-{NULL, 0, 0};
-
-struct Channel *chanlist;
-static int chancount = 0;
-unsigned int debugflags = 0;
-
-#define TMR_DCHAN_EST 2000
-
-static void
-stat_debug(struct Channel *chanp, char *s)
-{
- char tmp[100], tm[32];
-
- jiftime(tm, jiffies);
- sprintf(tmp, "%s Channel %d HL->LL %s\n", tm, chanp->chan, s);
- teles_putstatus(tmp);
-}
-
-enum {
- ST_NULL, /* 0 inactive */
- ST_OUT, /* 1 outgoing, awaiting SETUP confirm */
- ST_CLEAR, /* 2 call release, awaiting RELEASE confirm */
- ST_OUT_W, /* 3 outgoing, awaiting d-channel establishment */
- ST_REL_W, /* 4 awaiting d-channel release */
- ST_IN_W, /* 5 incoming, awaiting d-channel establishment */
- ST_IN, /* 6 incoming call received */
- ST_IN_SETUP, /* 7 incoming, SETUP response sent */
- ST_IN_DACT, /* 8 incoming connected, no b-channel prot. */
- ST_OUT_ESTB, /* 10 outgoing connected, awaiting b-channel prot. estbl. */
- ST_ACTIVE, /* 11 active, b channel prot. established */
- ST_BC_HANGUP, /* 12 call clear. (initiator), awaiting b channel prot. rel. */
- ST_PRO_W, /* 13 call clear. (initiator), DISCONNECT req. sent */
- ST_ANT_W, /* 14 call clear. (receiver), awaiting DISCONNECT ind. */
- ST_DISC_BC_HANGUP, /* d channel gone, wait for b channel deactivation */
- ST_OUT_W_HANGUP, /* Outgoing waiting for D-Channel hangup received */
- ST_D_ERR, /* d channel released while active */
-};
-
-#define STATE_COUNT (ST_D_ERR+1)
-
-static char *strState[] =
-{
- "ST_NULL",
- "ST_OUT",
- "ST_CLEAR",
- "ST_OUT_W",
- "ST_REL_W",
- "ST_IN_W",
- "ST_IN",
- "ST_IN_SETUP",
- "ST_IN_DACT",
- "ST_OUT_ESTB",
- "ST_ACTIVE",
- "ST_BC_HANGUP",
- "ST_PRO_W",
- "ST_ANT_W",
- "ST_DISC_BC_HANGUP",
- "ST_OUT_W_HANGUP",
- "ST_D_ERR",
-};
-
-enum {
- EV_DIAL, /* 0 */
- EV_SETUP_CNF, /* 1 */
- EV_ACCEPTB, /* 2 */
- EV_DISCONNECT_CNF, /* 5 */
- EV_DISCONNECT_IND, /* 6 */
- EV_RELEASE_CNF, /* 7 */
- EV_DLEST, /* 8 */
- EV_DLRL, /* 9 */
- EV_SETUP_IND, /* 10 */
- EV_RELEASE_IND, /* 11 */
- EV_ACCEPTD, /* 12 */
- EV_SETUP_CMPL_IND, /* 13 */
- EV_BC_EST, /* 14 */
- EV_WRITEBUF, /* 15 */
- EV_DATAIN, /* 16 */
- EV_HANGUP, /* 17 */
- EV_BC_REL, /* 18 */
- EV_CINF, /* 19 */
- EV_SUSPEND, /* 20 */
- EV_RESUME, /* 21 */
-};
-
-#define EVENT_COUNT (EV_CINF+1)
-
-static char *strEvent[] =
-{
- "EV_DIAL",
- "EV_SETUP_CNF",
- "EV_ACCEPTB",
- "EV_DISCONNECT_CNF",
- "EV_DISCONNECT_IND",
- "EV_RELEASE_CNF",
- "EV_DLEST",
- "EV_DLRL",
- "EV_SETUP_IND",
- "EV_RELEASE_IND",
- "EV_ACCEPTD",
- "EV_SETUP_CMPL_IND",
- "EV_BC_EST",
- "EV_WRITEBUF",
- "EV_DATAIN",
- "EV_HANGUP",
- "EV_BC_REL",
- "EV_CINF",
- "EV_SUSPEND",
- "EV_RESUME",
-};
-
-enum {
- ST_LC_NULL,
- ST_LC_ACTIVATE_WAIT,
- ST_LC_DELAY,
- ST_LC_ESTABLISH_WAIT,
- ST_LC_CONNECTED,
- ST_LC_RELEASE_WAIT,
-};
-
-#define LC_STATE_COUNT (ST_LC_RELEASE_WAIT+1)
-
-static char *strLcState[] =
-{
- "ST_LC_NULL",
- "ST_LC_ACTIVATE_WAIT",
- "ST_LC_DELAY",
- "ST_LC_ESTABLISH_WAIT",
- "ST_LC_CONNECTED",
- "ST_LC_RELEASE_WAIT",
-};
-
-enum {
- EV_LC_ESTABLISH,
- EV_LC_PH_ACTIVATE,
- EV_LC_PH_DEACTIVATE,
- EV_LC_DL_ESTABLISH,
- EV_LC_TIMER,
- EV_LC_DL_RELEASE,
- EV_LC_RELEASE,
-};
-
-#define LC_EVENT_COUNT (EV_LC_RELEASE+1)
-
-static char *strLcEvent[] =
-{
- "EV_LC_ESTABLISH",
- "EV_LC_PH_ACTIVATE",
- "EV_LC_PH_DEACTIVATE",
- "EV_LC_DL_ESTABLISH",
- "EV_LC_TIMER",
- "EV_LC_DL_RELEASE",
- "EV_LC_RELEASE",
-};
-
-#define LC_D 0
-#define LC_B 1
-
-/*
- * Dial out
- */
-static void
-r1(struct FsmInst *fi, int event, void *arg)
-{
- isdn_ctrl *ic = arg;
- struct Channel *chanp = fi->userdata;
-
- chanp->para.setup = ic->parm.setup;
- if (!strcmp(chanp->para.setup.eazmsn, "0"))
- chanp->para.setup.eazmsn[0] = '\0';
-
- chanp->l2_active_protocol = chanp->l2_protocol;
- chanp->incoming = 0;
- chanp->lc_b.l2_start = !0;
-
- switch (chanp->l2_active_protocol) {
- case (ISDN_PROTO_L2_X75I):
- chanp->lc_b.l2_establish = !0;
- break;
- case (ISDN_PROTO_L2_HDLC):
- case (ISDN_PROTO_L2_TRANS):
- chanp->lc_b.l2_establish = 0;
- break;
- default:
- printk(KERN_WARNING "r1 unknown protocol\n");
- break;
- }
-
- FsmChangeState(fi, ST_OUT_W);
- FsmEvent(&chanp->lc_d.lcfi, EV_LC_ESTABLISH, NULL);
-}
-
-static void
-ll_hangup(struct Channel *chanp, int bchantoo)
-{
- isdn_ctrl ic;
-
- if (bchantoo) {
- if (chanp->debug & 1)
- stat_debug(chanp, "STAT_BHUP");
- ic.driver = drid;
- ic.command = ISDN_STAT_BHUP;
- ic.arg = chanp->chan;
- iif.statcallb(&ic);
- }
- if (chanp->debug & 1)
- stat_debug(chanp, "STAT_DHUP");
- ic.driver = drid;
- ic.command = ISDN_STAT_DHUP;
- ic.arg = chanp->chan;
- iif.statcallb(&ic);
-}
-
-static void
-r2(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
-
- chanp->is.l4.l4l3(&chanp->is, CC_RELEASE_REQ, NULL);
-
- FsmChangeState(fi, ST_CLEAR);
- ll_hangup(chanp, 0);
-}
-
-
-static void
-r2_1(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
-
- chanp->is.l4.l4l3(&chanp->is, CC_DISCONNECT_REQ, NULL);
-
- FsmChangeState(fi, ST_OUT_W_HANGUP);
-}
-
-
-static void
-r2_2(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
-
- FsmChangeState(fi, ST_REL_W);
- FsmEvent(&chanp->lc_d.lcfi, EV_LC_RELEASE, NULL);
- ll_hangup(chanp, 0);
-}
-
-
-static void
-r3(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
-
- FsmEvent(&chanp->lc_d.lcfi, EV_LC_RELEASE, NULL);
- FsmChangeState(fi, ST_REL_W);
-}
-
-
-static void
-r3_1(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
-
- chanp->is.l4.l4l3(&chanp->is,CC_DLRL,NULL);
-
- FsmEvent(&chanp->lc_d.lcfi, EV_LC_RELEASE, NULL);
- FsmChangeState(fi, ST_REL_W);
- ll_hangup(chanp, 0);
-}
-
-
-static void
-r4(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp=fi->userdata;
-
- chanp->is.l4.l4l3(&chanp->is,CC_DLRL,NULL);
- FsmChangeState(fi, ST_NULL);
-}
-
-static void
-r5(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
-
- chanp->para.callref = chanp->outcallref;
-
- chanp->outcallref++;
- if (chanp->outcallref == 128)
- chanp->outcallref = 64;
-
- chanp->is.l4.l4l3(&chanp->is, CC_SETUP_REQ, NULL);
-
- FsmChangeState(fi, ST_OUT);
-}
-
-static void
-r6(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
-
- FsmChangeState(fi, ST_IN_W);
- FsmEvent(&chanp->lc_d.lcfi, EV_LC_ESTABLISH, NULL);
-}
-
-static void
-r7(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
- isdn_ctrl ic;
-
- /*
- * Report incoming calls only once to linklevel, use octet 3 of
- * channel identification information element. (it's value
- * is copied to chanp->para.bchannel in l3s12(), file isdnl3.c)
- */
- if (((chanp->chan & 1) + 1) & chanp->para.bchannel) {
- chanp->is.l4.l4l3(&chanp->is, CC_ALERTING_REQ, NULL);
- FsmChangeState(fi, ST_IN);
- if (chanp->debug & 1)
- stat_debug(chanp, "STAT_ICALL");
- ic.driver = drid;
- ic.command = ISDN_STAT_ICALL;
- ic.arg = chanp->chan;
- /*
- * No need to return "unknown" for calls without OAD,
- * cause that's handled in linklevel now (replaced by '0')
- */
- ic.parm.setup = chanp->para.setup;
- iif.statcallb(&ic);
- } else {
- chanp->is.l4.l4l3(&chanp->is,CC_DLRL,NULL);
- FsmEvent(&chanp->lc_d.lcfi, EV_LC_RELEASE, NULL);
- FsmChangeState(fi, ST_REL_W);
- }
-}
-
-static void
-r8(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
-
- FsmChangeState(fi, ST_IN_SETUP);
- chanp->is.l4.l4l3(&chanp->is, CC_SETUP_RSP, NULL);
-
-}
-
-static void
-r9(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
-
- FsmChangeState(fi, ST_IN_DACT);
-
- chanp->l2_active_protocol = chanp->l2_protocol;
- chanp->incoming = !0;
- chanp->lc_b.l2_start = 0;
-
- switch (chanp->l2_active_protocol) {
- case (ISDN_PROTO_L2_X75I):
- chanp->lc_b.l2_establish = !0;
- break;
- case (ISDN_PROTO_L2_HDLC):
- case (ISDN_PROTO_L2_TRANS):
- chanp->lc_b.l2_establish = 0;
- break;
- default:
- printk(KERN_WARNING "r9 unknown protocol\n");
- break;
- }
-
- init_ds(chanp->chan, !0);
-
- FsmEvent(&chanp->lc_b.lcfi, EV_LC_ESTABLISH, NULL);
-}
-
-static void
-r10(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
-
- FsmChangeState(fi, ST_OUT_ESTB);
-
- init_ds(chanp->chan, 0);
- FsmEvent(&chanp->lc_b.lcfi, EV_LC_ESTABLISH, NULL);
-
-}
-
-static void
-r12(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
- isdn_ctrl ic;
-
- FsmChangeState(fi, ST_ACTIVE);
- chanp->data_open = !0;
-
- if (chanp->debug & 1)
- stat_debug(chanp, "STAT_DCONN");
- ic.driver = drid;
- ic.command = ISDN_STAT_DCONN;
- ic.arg = chanp->chan;
- iif.statcallb(&ic);
-
- if (chanp->debug & 1)
- stat_debug(chanp, "STAT_BCONN");
- ic.driver = drid;
- ic.command = ISDN_STAT_BCONN;
- ic.arg = chanp->chan;
- iif.statcallb(&ic);
-}
-
-static void
-r15(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
-
- chanp->data_open = 0;
- FsmChangeState(fi, ST_BC_HANGUP);
- FsmEvent(&chanp->lc_b.lcfi, EV_LC_RELEASE, NULL);
-}
-
-static void
-r16(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
-
- release_ds(chanp->chan);
-
- FsmChangeState(fi, ST_PRO_W);
- chanp->is.l4.l4l3(&chanp->is, CC_DISCONNECT_REQ, NULL);
-}
-
-static void
-r17(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
-
- chanp->data_open = 0;
- release_ds(chanp->chan);
-
- FsmChangeState(fi, ST_ANT_W);
-}
-
-
-static void
-r17_1(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
-
- chanp->data_open = 0;
- release_ds(chanp->chan);
-
- chanp->is.l4.l4l3(&chanp->is,CC_DLRL,NULL);
-
- FsmEvent(&chanp->lc_d.lcfi,EV_LC_RELEASE,NULL);
-
- FsmChangeState(fi, ST_NULL);
-
- ll_hangup(chanp,!0);
-}
-
-static void
-r18(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
-
- FsmChangeState(fi, ST_REL_W);
- FsmEvent(&chanp->lc_d.lcfi, EV_LC_RELEASE, NULL);
-
- ll_hangup(chanp, !0);
-}
-
-static void
-r19(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
-
- FsmChangeState(fi, ST_CLEAR);
-
- chanp->is.l4.l4l3(&chanp->is, CC_RELEASE_REQ, NULL);
-
- ll_hangup(chanp, !0);
-}
-
-static void
-r20(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
-
- chanp->is.l4.l4l3(&chanp->is,CC_DLRL,NULL);
-
- FsmEvent(&chanp->lc_d.lcfi,EV_LC_RELEASE,NULL);
-
- FsmChangeState(fi, ST_NULL);
-
- ll_hangup(chanp, 0);
-}
-
-
-static void
-r21(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
-
- chanp->data_open = 0;
- FsmChangeState(fi, ST_DISC_BC_HANGUP);
- FsmEvent(&chanp->lc_b.lcfi, EV_LC_RELEASE, NULL);
-}
-
-static void
-r22(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
-
- release_ds(chanp->chan);
-
- FsmChangeState(fi, ST_CLEAR);
-
- chanp->is.l4.l4l3(&chanp->is, CC_RELEASE_REQ, NULL);
-
- ll_hangup(chanp, !0);
-}
-
-static void
-r23(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
-
- release_ds(chanp->chan);
-
- FsmChangeState(fi, ST_PRO_W);
- chanp->is.l4.l4l3(&chanp->is, CC_DISCONNECT_REQ, NULL);
-}
-
-static void
-r23_1(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
-
- release_ds(chanp->chan);
-
- chanp->is.l4.l4l3(&chanp->is, CC_DLRL,NULL);
-
- FsmEvent(&chanp->lc_d.lcfi, EV_LC_RELEASE,NULL);
-
- FsmChangeState(fi, ST_NULL);
-
- ll_hangup(chanp,!0);
-}
-
-static void
-r24(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
-
- chanp->data_open = 0;
- FsmChangeState(fi, ST_D_ERR);
- FsmEvent(&chanp->lc_b.lcfi, EV_LC_RELEASE, NULL);
-}
-
-static void
-r25(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
-
- release_ds(chanp->chan);
-
- FsmChangeState(fi, ST_NULL);
-
- ll_hangup(chanp, !0);
-}
-
-static void
-r26(struct FsmInst *fi, int event, void *arg)
-{
- struct Channel *chanp = fi->userdata;
- isdn_ctrl ic;
-
-
- ic.driver = drid;
- ic.command = ISDN_STAT_CINF;
- ic.arg = chanp->chan;
- sprintf(ic.parm.num, "%d", chanp->para.chargeinfo);
- iif.statcallb(&ic);
-}
-
-
-
-static struct FsmNode fnlist[] =
-{
- {ST_NULL, EV_DIAL, r1},
- {ST_OUT_W, EV_DLEST, r5},
- {ST_OUT_W, EV_DLRL, r20},
- {ST_OUT_W, EV_RELEASE_CNF, r2_2 },
- {ST_OUT, EV_DISCONNECT_IND, r2},
- {ST_OUT, EV_SETUP_CNF, r10},
- {ST_OUT, EV_HANGUP, r2_1},
- {ST_OUT, EV_RELEASE_IND, r20},
- {ST_OUT, EV_RELEASE_CNF, r20},
- {ST_OUT, EV_DLRL, r2_2},
- {ST_OUT_W_HANGUP, EV_RELEASE_IND, r2_2},
- {ST_OUT_W_HANGUP, EV_DLRL, r20},
- {ST_CLEAR, EV_RELEASE_CNF, r3},
- {ST_CLEAR, EV_DLRL, r20},
- {ST_REL_W, EV_DLRL, r4},
- {ST_NULL, EV_SETUP_IND, r6},
- {ST_IN_W, EV_DLEST, r7},
- {ST_IN_W, EV_DLRL, r3_1},
- {ST_IN, EV_DLRL, r3_1},
- {ST_IN, EV_HANGUP, r2_1},
- {ST_IN, EV_RELEASE_IND, r2_2},
- {ST_IN, EV_RELEASE_CNF, r2_2},
- {ST_IN, EV_ACCEPTD, r8},
- {ST_IN_SETUP, EV_HANGUP, r2_1},
- {ST_IN_SETUP, EV_SETUP_CMPL_IND, r9},
- {ST_IN_SETUP, EV_RELEASE_IND, r2_2},
- {ST_IN_SETUP, EV_DISCONNECT_IND, r2},
- {ST_IN_SETUP, EV_DLRL, r20},
- {ST_OUT_ESTB, EV_BC_EST, r12},
- {ST_OUT_ESTB, EV_BC_REL, r23},
- {ST_OUT_ESTB, EV_DLRL, r23_1},
- {ST_IN_DACT, EV_BC_EST, r12},
- {ST_IN_DACT, EV_BC_REL, r17},
- {ST_IN_DACT, EV_DLRL, r17_1},
- {ST_ACTIVE, EV_HANGUP, r15},
- {ST_ACTIVE, EV_BC_REL, r17},
- {ST_ACTIVE, EV_DISCONNECT_IND, r21},
- {ST_ACTIVE, EV_DLRL, r24},
- {ST_ACTIVE, EV_CINF, r26},
- {ST_ACTIVE, EV_RELEASE_IND, r17},
- {ST_BC_HANGUP, EV_BC_REL, r16},
- {ST_BC_HANGUP, EV_DISCONNECT_IND, r21},
- {ST_PRO_W, EV_RELEASE_IND, r18},
- {ST_ANT_W, EV_DISCONNECT_IND, r19},
- {ST_DISC_BC_HANGUP, EV_BC_REL, r22},
- {ST_D_ERR, EV_BC_REL, r25},
-};
-
-#define FNCOUNT (sizeof(fnlist)/sizeof(struct FsmNode))
-
-static void
-lc_r1(struct FsmInst *fi, int event, void *arg)
-{
- struct LcFsm *lf = fi->userdata;
-
- FsmChangeState(fi, ST_LC_ACTIVATE_WAIT);
- FsmAddTimer(&lf->act_timer, 1000, EV_LC_TIMER, NULL, 50);
- lf->st->ma.manl1(lf->st, PH_ACTIVATE, NULL);
-
-}
-
-static void
-lc_r6(struct FsmInst *fi, int event, void *arg)
-{
- struct LcFsm *lf = fi->userdata;
-
- FsmDelTimer(&lf->act_timer, 50);
- FsmChangeState(fi, ST_LC_DELAY);
- FsmAddTimer(&lf->act_timer, 40, EV_LC_TIMER, NULL, 51);
-}
-
-static void
-lc_r2(struct FsmInst *fi, int event, void *arg)
-{
- struct LcFsm *lf = fi->userdata;
-
- if (lf->l2_establish) {
- FsmChangeState(fi, ST_LC_ESTABLISH_WAIT);
- if (lf->l2_start)
- lf->st->ma.manl2(lf->st, DL_ESTABLISH, NULL);
- } else {
- FsmChangeState(fi, ST_LC_CONNECTED);
- lf->lccall(lf, LC_ESTABLISH, NULL);
- }
-}
-
-static void
-lc_r3(struct FsmInst *fi, int event, void *arg)
-{
- struct LcFsm *lf = fi->userdata;
-
- FsmChangeState(fi, ST_LC_CONNECTED);
- lf->lccall(lf, LC_ESTABLISH, NULL);
-}
-
-static void
-lc_r4(struct FsmInst *fi, int event, void *arg)
-{
- struct LcFsm *lf = fi->userdata;
-
- if (lf->l2_establish) {
- FsmChangeState(fi, ST_LC_RELEASE_WAIT);
- lf->st->ma.manl2(lf->st, DL_RELEASE, NULL);
- } else {
- FsmChangeState(fi, ST_LC_NULL);
- lf->st->ma.manl1(lf->st, PH_DEACTIVATE, NULL);
- lf->lccall(lf, LC_RELEASE, NULL);
- }
-}
-
-static void
-lc_r5(struct FsmInst *fi, int event, void *arg)
-{
- struct LcFsm *lf = fi->userdata;
-
- FsmChangeState(fi, ST_LC_NULL);
- lf->st->ma.manl1(lf->st, PH_DEACTIVATE, NULL);
- lf->lccall(lf, LC_RELEASE, NULL);
-}
-
-static struct FsmNode LcFnList[] =
-{
- {ST_LC_NULL, EV_LC_ESTABLISH, lc_r1},
- {ST_LC_ACTIVATE_WAIT, EV_LC_PH_ACTIVATE, lc_r6},
- {ST_LC_DELAY, EV_LC_TIMER, lc_r2},
- {ST_LC_ESTABLISH_WAIT, EV_LC_DL_ESTABLISH, lc_r3},
- {ST_LC_CONNECTED, EV_LC_RELEASE, lc_r4},
- {ST_LC_CONNECTED, EV_LC_DL_RELEASE, lc_r5},
- {ST_LC_RELEASE_WAIT, EV_LC_DL_RELEASE, lc_r5},
- {ST_LC_ACTIVATE_WAIT, EV_LC_TIMER, lc_r5},
- {ST_LC_ESTABLISH_WAIT, EV_LC_DL_RELEASE, lc_r5},
-};
-
-#define LC_FN_COUNT (sizeof(LcFnList)/sizeof(struct FsmNode))
-
-void
-CallcNew(void)
-{
- callcfsm.state_count = STATE_COUNT;
- callcfsm.event_count = EVENT_COUNT;
- callcfsm.strEvent = strEvent;
- callcfsm.strState = strState;
- FsmNew(&callcfsm, fnlist, FNCOUNT);
-
- lcfsm.state_count = LC_STATE_COUNT;
- lcfsm.event_count = LC_EVENT_COUNT;
- lcfsm.strEvent = strLcEvent;
- lcfsm.strState = strLcState;
- FsmNew(&lcfsm, LcFnList, LC_FN_COUNT);
-}
-
-void
-CallcFree(void)
-{
- FsmFree(&lcfsm);
- FsmFree(&callcfsm);
-}
-
-static void
-release_ds(int chan)
-{
- struct PStack *st = &chanlist[chan].ds;
- struct IsdnCardState *sp;
- struct HscxState *hsp;
-
- sp = st->l1.hardware;
- hsp = sp->hs + chanlist[chan].hscx;
-
- close_hscxstate(hsp);
-
- switch (chanlist[chan].l2_active_protocol) {
- case (ISDN_PROTO_L2_X75I):
- releasestack_isdnl2(st);
- break;
- case (ISDN_PROTO_L2_HDLC):
- case (ISDN_PROTO_L2_TRANS):
- releasestack_transl2(st);
- break;
- }
-}
-
-static void
-cc_l1man(struct PStack *st, int pr, void *arg)
-{
- struct Channel *chanp = (struct Channel *) st->l4.userdata;
-
- switch (pr) {
- case (PH_ACTIVATE):
- FsmEvent(&chanp->lc_d.lcfi, EV_LC_PH_ACTIVATE, NULL);
- break;
- case (PH_DEACTIVATE):
- FsmEvent(&chanp->lc_d.lcfi, EV_LC_PH_DEACTIVATE, NULL);
- break;
- }
-}
-
-static void
-cc_l2man(struct PStack *st, int pr, void *arg)
-{
- struct Channel *chanp = (struct Channel *) st->l4.userdata;
-
- switch (pr) {
- case (DL_ESTABLISH):
- FsmEvent(&chanp->lc_d.lcfi, EV_LC_DL_ESTABLISH, NULL);
- break;
- case (DL_RELEASE):
- FsmEvent(&chanp->lc_d.lcfi, EV_LC_DL_RELEASE, NULL);
- break;
- }
-}
-
-static void
-dcc_l1man(struct PStack *st, int pr, void *arg)
-{
- struct Channel *chanp = (struct Channel *) st->l4.userdata;
-
- switch (pr) {
- case (PH_ACTIVATE):
- FsmEvent(&chanp->lc_b.lcfi, EV_LC_PH_ACTIVATE, NULL);
- break;
- case (PH_DEACTIVATE):
- FsmEvent(&chanp->lc_b.lcfi, EV_LC_PH_DEACTIVATE, NULL);
- break;
- }
-}
-
-static void
-dcc_l2man(struct PStack *st, int pr, void *arg)
-{
- struct Channel *chanp = (struct Channel *) st->l4.userdata;
-
- switch (pr) {
- case (DL_ESTABLISH):
- FsmEvent(&chanp->lc_b.lcfi, EV_LC_DL_ESTABLISH, NULL);
- break;
- case (DL_RELEASE):
- FsmEvent(&chanp->lc_b.lcfi, EV_LC_DL_RELEASE, NULL);
- break;
- }
-}
-
-static void
-ll_handler(struct PStack *st, int pr,
- struct BufHeader *ibh)
-{
- struct Channel *chanp = (struct Channel *) st->l4.userdata;
-
- switch (pr) {
- case (CC_DISCONNECT_IND):
- FsmEvent(&chanp->fi, EV_DISCONNECT_IND, NULL);
- break;
- case (CC_RELEASE_CNF):
- FsmEvent(&chanp->fi, EV_RELEASE_CNF, NULL);
- break;
- case (CC_SETUP_IND):
- FsmEvent(&chanp->fi, EV_SETUP_IND, NULL);
- break;
- case (CC_RELEASE_IND):
- FsmEvent(&chanp->fi, EV_RELEASE_IND, NULL);
- break;
- case (CC_SETUP_COMPLETE_IND):
- FsmEvent(&chanp->fi, EV_SETUP_CMPL_IND, NULL);
- break;
- case (CC_SETUP_CNF):
- FsmEvent(&chanp->fi, EV_SETUP_CNF, NULL);
- break;
- case (CC_INFO_CHARGE):
- FsmEvent(&chanp->fi, EV_CINF, NULL);
- break;
- }
-}
-
-static void
-init_is(int chan, unsigned int ces)
-{
- struct PStack *st = &(chanlist[chan].is);
- struct IsdnCardState *sp = chanlist[chan].sp;
- char tmp[128];
-
- setstack_teles(st, sp);
-
- st->l2.sap = 0;
-
- st->l2.tei = 255;
-
- st->l2.ces = ces;
- st->l2.extended = !0;
- st->l2.laptype = LAPD;
- st->l2.window = 1;
- st->l2.orig = !0;
- st->l2.t200 = 1000; /* 1000 milliseconds */
- if (st->protocol == ISDN_PTYPE_1TR6) {
- st->l2.n200 = 3; /* try 3 times */
- st->l2.t203 = 10000; /* 10000 milliseconds */
- } else {
- st->l2.n200 = 4; /* try 4 times */
- st->l2.t203 = 5000; /* 5000 milliseconds */
- }
-
- sprintf(tmp, "Channel %d q.921", chan);
- setstack_isdnl2(st, tmp);
- setstack_isdnl3(st);
- st->l2.debug = 2;
- st->l3.debug = 2;
- st->l2.debug = 0xff;
- st->l3.debug = 0xff;
- st->l4.userdata = chanlist + chan;
- st->l4.l2writewakeup = NULL;
-
- st->l3.l3l4 = ll_handler;
- st->l1.l1man = cc_l1man;
- st->l2.l2man = cc_l2man;
-
- st->pa = &chanlist[chan].para;
- teles_addlist(sp, st);
-}
-
-static void
-callc_debug(struct FsmInst *fi, char *s)
-{
- char str[80], tm[32];
- struct Channel *chanp = fi->userdata;
-
- jiftime(tm, jiffies);
- sprintf(str, "%s Channel %d callc %s\n", tm, chanp->chan, s);
- teles_putstatus(str);
-}
-
-static void
-lc_debug(struct FsmInst *fi, char *s)
-{
- char str[256], tm[32];
- struct LcFsm *lf = fi->userdata;
-
- jiftime(tm, jiffies);
- sprintf(str, "%s Channel %d lc %s\n", tm, lf->ch->chan, s);
- teles_putstatus(str);
-}
-
-static void
-dlc_debug(struct FsmInst *fi, char *s)
-{
- char str[256], tm[32];
- struct LcFsm *lf = fi->userdata;
-
- jiftime(tm, jiffies);
- sprintf(str, "%s Channel %d dlc %s\n", tm, lf->ch->chan, s);
- teles_putstatus(str);
-}
-
-static void
-lccall_d(struct LcFsm *lf, int pr, void *arg)
-{
- struct Channel *chanp = lf->ch;
-
- switch (pr) {
- case (LC_ESTABLISH):
- FsmEvent(&chanp->fi, EV_DLEST, NULL);
- break;
- case (LC_RELEASE):
- FsmEvent(&chanp->fi, EV_DLRL, NULL);
- break;
- }
-}
-
-static void
-lccall_b(struct LcFsm *lf, int pr, void *arg)
-{
- struct Channel *chanp = lf->ch;
-
- switch (pr) {
- case (LC_ESTABLISH):
- FsmEvent(&chanp->fi, EV_BC_EST, NULL);
- break;
- case (LC_RELEASE):
- FsmEvent(&chanp->fi, EV_BC_REL, NULL);
- break;
- }
-}
-
-static void
-init_chan(int chan, int cardnr, int hscx,
- unsigned int ces)
-{
- struct IsdnCard *card = cards + cardnr;
- struct Channel *chanp = chanlist + chan;
-
- chanp->sp = card->sp;
- chanp->hscx = hscx;
- chanp->chan = chan;
- chanp->incoming = 0;
- chanp->debug = 0;
- init_is(chan, ces);
-
- chanp->fi.fsm = &callcfsm;
- chanp->fi.state = ST_NULL;
- chanp->fi.debug = 0;
- chanp->fi.userdata = chanp;
- chanp->fi.printdebug = callc_debug;
-
- chanp->lc_d.lcfi.fsm = &lcfsm;
- chanp->lc_d.lcfi.state = ST_LC_NULL;
- chanp->lc_d.lcfi.debug = 0;
- chanp->lc_d.lcfi.userdata = &chanp->lc_d;
- chanp->lc_d.lcfi.printdebug = lc_debug;
- chanp->lc_d.type = LC_D;
- chanp->lc_d.ch = chanp;
- chanp->lc_d.st = &chanp->is;
- chanp->lc_d.l2_establish = !0;
- chanp->lc_d.l2_start = !0;
- chanp->lc_d.lccall = lccall_d;
- FsmInitTimer(&chanp->lc_d.lcfi, &chanp->lc_d.act_timer);
-
- chanp->lc_b.lcfi.fsm = &lcfsm;
- chanp->lc_b.lcfi.state = ST_LC_NULL;
- chanp->lc_b.lcfi.debug = 0;
- chanp->lc_b.lcfi.userdata = &chanp->lc_b;
- chanp->lc_b.lcfi.printdebug = dlc_debug;
- chanp->lc_b.type = LC_B;
- chanp->lc_b.ch = chanp;
- chanp->lc_b.st = &chanp->ds;
- chanp->lc_b.l2_establish = !0;
- chanp->lc_b.l2_start = !0;
- chanp->lc_b.lccall = lccall_b;
- FsmInitTimer(&chanp->lc_b.lcfi, &chanp->lc_b.act_timer);
-
- chanp->outcallref = 64;
- chanp->data_open = 0;
-}
-
-int
-CallcNewChan(void)
-{
- int i, ces, c;
-
- chancount = 0;
- for (i = 0; i < nrcards; i++)
- if (cards[i].sp)
- chancount += 2;
-
- chanlist = (struct Channel *) Smalloc(sizeof(struct Channel) *
- chancount, GFP_KERNEL, "chanlist");
-
- c = 0;
- ces = randomces();
- for (i = 0; i < nrcards; i++)
- if (cards[i].sp) {
- init_chan(c++, i, 1, ces++);
- ces %= 0xffff;
- init_chan(c++, i, 0, ces++);
- ces %= 0xffff;
- }
- printk(KERN_INFO "channels %d\n", chancount);
- return (chancount);
-
-}
-
-static void
-release_is(int chan)
-{
- struct PStack *st = &chanlist[chan].is;
-
- releasestack_isdnl2(st);
- teles_rmlist(st->l1.hardware, st);
- BufQueueRelease(&st->l2.i_queue);
-}
-
-void
-CallcFreeChan(void)
-{
- int i;
-
- for (i = 0; i < chancount; i++)
- release_is(i);
- Sfree((void *) chanlist);
-}
-
-static void
-lldata_handler(struct PStack *st, int pr,
- void *arg)
-{
- struct Channel *chanp = (struct Channel *) st->l4.userdata;
- byte *ptr;
- int size;
- struct BufHeader *ibh = arg;
-
- switch (pr) {
- case (DL_DATA):
- if (chanp->data_open) {
- ptr = DATAPTR(ibh);
- ptr += chanp->ds.l2.ihsize;
- size = ibh->datasize - chanp->ds.l2.ihsize;
- iif.rcvcallb(drid, chanp->chan, ptr, size);
- }
- BufPoolRelease(ibh);
- break;
- default:
- printk(KERN_WARNING "lldata_handler unknown primitive\n");
- break;
- }
-}
-
-static void
-lltrans_handler(struct PStack *st, int pr,
- struct BufHeader *ibh)
-{
- struct Channel *chanp = (struct Channel *) st->l4.userdata;
- byte *ptr;
-
- switch (pr) {
- case (PH_DATA):
- if (chanp->data_open) {
- ptr = DATAPTR(ibh);
- iif.rcvcallb(drid, chanp->chan, ptr, ibh->datasize);
- }
- BufPoolRelease(ibh);
- break;
- default:
- printk(KERN_WARNING "lltrans_handler unknown primitive\n");
- break;
- }
-}
-
-static void
-ll_writewakeup(struct PStack *st)
-{
- struct Channel *chanp = st->l4.userdata;
- isdn_ctrl ic;
-
- ic.driver = drid;
- ic.command = ISDN_STAT_BSENT;
- ic.arg = chanp->chan;
- iif.statcallb(&ic);
-}
-
-static int
-init_ds(int chan, int incoming)
-{
- struct PStack *st = &(chanlist[chan].ds);
- struct IsdnCardState *sp = (struct IsdnCardState *)
- chanlist[chan].is.l1.hardware;
- struct HscxState *hsp = sp->hs + chanlist[chan].hscx;
- char tmp[128];
-
- st->l1.hardware = sp;
-
- hsp->mode = 2;
- hsp->transbufsize = 4000;
-
- if (setstack_hscx(st, hsp))
- return (-1);
-
- st->l2.extended = 0;
- st->l2.laptype = LAPB;
- st->l2.orig = !incoming;
- st->l2.t200 = 1000; /* 1000 milliseconds */
- st->l2.window = 7;
- st->l2.n200 = 4; /* try 4 times */
- st->l2.t203 = 5000; /* 5000 milliseconds */
-
- st->l2.debug = 0xff;
- st->l3.debug = 0xff;
- switch (chanlist[chan].l2_active_protocol) {
- case (ISDN_PROTO_L2_X75I):
- sprintf(tmp, "Channel %d x.75", chan);
- setstack_isdnl2(st, tmp);
- st->l2.l2l3 = lldata_handler;
- st->l1.l1man = dcc_l1man;
- st->l2.l2man = dcc_l2man;
- st->l4.userdata = chanlist + chan;
- st->l4.l1writewakeup = NULL;
- st->l4.l2writewakeup = ll_writewakeup;
- st->l2.l2m.debug = debugflags & 16;
- st->ma.manl2(st, MDL_NOTEIPROC, NULL);
- st->l1.hscxmode = 2; /* Packet-Mode ? */
- st->l1.hscxchannel = chanlist[chan].para.bchannel - 1;
- break;
- case (ISDN_PROTO_L2_HDLC):
- st->l1.l1l2 = lltrans_handler;
- st->l1.l1man = dcc_l1man;
- st->l4.userdata = chanlist + chan;
- st->l4.l1writewakeup = ll_writewakeup;
- st->l1.hscxmode = 2;
- st->l1.hscxchannel = chanlist[chan].para.bchannel - 1;
- break;
- case (ISDN_PROTO_L2_TRANS):
- st->l1.l1l2 = lltrans_handler;
- st->l1.l1man = dcc_l1man;
- st->l4.userdata = chanlist + chan;
- st->l4.l1writewakeup = ll_writewakeup;
- st->l1.hscxmode = 1;
- st->l1.hscxchannel = chanlist[chan].para.bchannel - 1;
- break;
- }
-
- return (0);
-
-}
-
-static void
-channel_report(int i)
-{
-}
-
-static void
-command_debug(struct Channel *chanp, char *s)
-{
- char tmp[64], tm[32];
-
- jiftime(tm, jiffies);
- sprintf(tmp, "%s Channel %d LL->HL %s\n", tm, chanp->chan, s);
- teles_putstatus(tmp);
-}
-
-static void
-distr_debug(void)
-{
- int i;
-
- for (i = 0; i < chancount; i++) {
- chanlist[i].debug = debugflags & 1;
- chanlist[i].fi.debug = debugflags & 2;
- chanlist[i].is.l2.l2m.debug = debugflags & 8;
- chanlist[i].ds.l2.l2m.debug = debugflags & 16;
- }
- for (i = 0; i < nrcards; i++)
- if (cards[i].sp) {
- cards[i].sp->dlogflag = debugflags & 4;
- cards[i].sp->debug = debugflags & 32;
- }
-}
-
-int
-teles_command(isdn_ctrl * ic)
-{
- struct Channel *chanp;
- char tmp[64];
- int i;
- unsigned int num;
-
- switch (ic->command) {
- case (ISDN_CMD_SETEAZ):
- chanp = chanlist + ic->arg;
- if (chanp->debug & 1)
- command_debug(chanp, "SETEAZ");
- return (0);
- case (ISDN_CMD_DIAL):
- chanp = chanlist + (ic->arg & 0xff);
- if (chanp->debug & 1) {
- sprintf(tmp, "DIAL %s -> %s (%d,%d)",
- ic->parm.setup.eazmsn, ic->parm.setup.phone,
- ic->parm.setup.si1, ic->parm.setup.si2);
- command_debug(chanp, tmp);
- }
- FsmEvent(&chanp->fi, EV_DIAL, ic);
- return (0);
- case (ISDN_CMD_ACCEPTB):
- chanp = chanlist + ic->arg;
- if (chanp->debug & 1)
- command_debug(chanp, "ACCEPTB");
- FsmEvent(&chanp->fi, EV_ACCEPTB, NULL);
- break;
- case (ISDN_CMD_ACCEPTD):
- chanp = chanlist + ic->arg;
- if (chanp->debug & 1)
- command_debug(chanp, "ACCEPTD");
- FsmEvent(&chanp->fi, EV_ACCEPTD, NULL);
- break;
- case (ISDN_CMD_HANGUP):
- chanp = chanlist + ic->arg;
- if (chanp->debug & 1)
- command_debug(chanp, "HANGUP");
- FsmEvent(&chanp->fi, EV_HANGUP, NULL);
- break;
- case (ISDN_CMD_SUSPEND):
- chanp = chanlist + ic->arg;
- if (chanp->debug & 1) {
- sprintf(tmp, "SUSPEND %s", ic->parm.num);
- command_debug(chanp, tmp);
- }
- FsmEvent(&chanp->fi, EV_SUSPEND, ic);
- break;
- case (ISDN_CMD_RESUME):
- chanp = chanlist + ic->arg;
- if (chanp->debug & 1) {
- sprintf(tmp, "RESUME %s", ic->parm.num);
- command_debug(chanp, tmp);
- }
- FsmEvent(&chanp->fi, EV_RESUME, ic);
- break;
- case (ISDN_CMD_LOCK):
- teles_mod_inc_use_count();
- break;
- case (ISDN_CMD_UNLOCK):
- teles_mod_dec_use_count();
- break;
- case (ISDN_CMD_IOCTL):
- switch (ic->arg) {
- case (0):
- for (i = 0; i < nrcards; i++)
- if (cards[i].sp)
- teles_reportcard(i);
- for (i = 0; i < chancount; i++)
- channel_report(i);
- break;
- case (1):
- debugflags = *(unsigned int *) ic->parm.num;
- distr_debug();
- sprintf(tmp, "debugging flags set to %x\n", debugflags);
- teles_putstatus(tmp);
- printk(KERN_DEBUG "%s", tmp);
- break;
- case (2):
- num = *(unsigned int *) ic->parm.num;
- i = num >> 8;
- if (i >= chancount)
- break;
- chanp = chanlist + i;
- chanp->impair = num & 0xff;
- if (chanp->debug & 1) {
- sprintf(tmp, "IMPAIR %x", chanp->impair);
- command_debug(chanp, tmp);
- }
- break;
- }
- break;
- case (ISDN_CMD_SETL2):
- chanp = chanlist + (ic->arg & 0xff);
- if (chanp->debug & 1) {
- sprintf(tmp, "SETL2 %ld", ic->arg >> 8);
- command_debug(chanp, tmp);
- }
- chanp->l2_protocol = ic->arg >> 8;
- break;
- default:
- break;
- }
-
- return (0);
-}
-
-int
-teles_writebuf(int id, int chan, const u_char * buf, int count, int user)
-{
- struct Channel *chanp = chanlist + chan;
- struct PStack *st = &chanp->ds;
- struct BufHeader *ibh;
- int err, i;
- byte *ptr;
-
- if (!chanp->data_open) {
- printk(KERN_DEBUG "teles_writebuf: channel not open\n");
- return -EIO;
- }
-
- err = BufPoolGet(&ibh, st->l1.sbufpool, GFP_ATOMIC, st, 21);
- if (err)
- /* Must return 0 here, since this is not an error
- * but a temporary lack of resources.
- */
- return 0;
-
- ptr = DATAPTR(ibh);
- if (chanp->lc_b.l2_establish)
- i = st->l2.ihsize;
- else
- i = 0;
-
- if ((count+i) > BUFFER_SIZE(HSCX_SBUF_ORDER, HSCX_SBUF_BPPS)) {
- printk(KERN_WARNING "teles_writebuf: packet too large!\n");
- return (-EINVAL);
- }
-
- ptr += i;
-
- if (user)
- copy_from_user(ptr, buf, count);
- else
- memcpy(ptr, buf, count);
- ibh->datasize = count + i;
-
- if (chanp->data_open) {
- if (chanp->lc_b.l2_establish)
- chanp->ds.l3.l3l2(&chanp->ds, DL_DATA, ibh);
- else
- chanp->ds.l2.l2l1(&chanp->ds, PH_DATA, ibh);
- return (count);
- } else {
- BufPoolRelease(ibh);
- return (0);
- }
-
-}
+++ /dev/null
-/* $Id: card.c,v 1.16 1996/10/22 23:14:16 fritz Exp $
- *
- * card.c low level stuff for the Teles S0 isdn card
- *
- * Author Jan den Ouden
- *
- * Beat Doebeli log all D channel traffic
- *
- * $Log: card.c,v $
- * Revision 1.16 1996/10/22 23:14:16 fritz
- * Changes for compatibility to 2.0.X and 2.1.X kernels.
- *
- * Revision 1.15 1996/09/29 19:41:56 fritz
- * Bugfix: ignore unknown frames.
- *
- * Revision 1.14 1996/09/23 01:53:49 fritz
- * Bugfix: discard unknown frames (non-EDSS1 and non-1TR6).
- *
- * Revision 1.13 1996/07/18 11:21:24 jdenoud
- * Use small buffers for incoming audio data
- *
- * Revision 1.12 1996/06/24 17:16:52 fritz
- * Added check for misconfigured membase.
- *
- * Revision 1.11 1996/06/14 03:30:37 fritz
- * Added recovery from EXIR 40 interrupt.
- * Some cleanup.
- *
- * Revision 1.10 1996/06/11 14:57:20 hipp
- * minor changes to ensure, that SKBs are sent in the right order
- *
- * Revision 1.9 1996/06/06 14:42:09 fritz
- * Bugfix: forgot hsp-> in last change.
- *
- * Revision 1.7 1996/05/31 01:02:21 fritz
- * Cosmetic changes.
- *
- * Revision 1.6 1996/05/26 14:58:10 fritz
- * Bugfix: Did not show port correctly, when no card found.
- *
- * Revision 1.5 1996/05/17 03:45:02 fritz
- * Made error messages more clearly.
- * Bugfix: Only 31 bytes of 32-byte audio frames
- * have been transfered to upper layers.
- *
- * Revision 1.4 1996/05/06 10:17:57 fritz
- * Added voice-send stuff
- * (Not reporting EXIR when in voice-mode, since it's normal).
- *
- * Revision 1.3 1996/04/30 22:02:40 isdn4dev
- * Bugfixes for 16.3
- * -improved IO allocation
- * -fix second B channel problem
- * -correct ph_command patch
- *
- * Revision 1.2 1996/04/30 10:00:59 fritz
- * Bugfix: Added ph_command(8) for 16.3.
- * Bugfix: Ports did not get registered correctly
- * when using a 16.3.
- * Started voice support.
- * Some experimental changes of waitforXFW().
- *
- * Revision 1.1 1996/04/13 10:22:42 fritz
- * Initial revision
- *
- *
- */
-
-#define __NO_VERSION__
-#include "teles.h"
-#include "proto.h"
-
-#define INCLUDE_INLINE_FUNCS
-#include <linux/tqueue.h>
-#include <linux/interrupt.h>
-
-#undef DCHAN_VERBOSE
-
-extern void tei_handler(struct PStack *st, byte pr,
- struct BufHeader *ibh);
-extern struct IsdnCard cards[];
-extern int nrcards;
-
-#define byteout(addr,val) outb_p(val,addr)
-#define bytein(addr) inb_p(addr)
-
-static inline byte
-readisac_0(byte * cardm, byte offset)
-{
- return readb(cardm + 0x100 + ((offset & 1) ? 0x1ff : 0) + offset);
-}
-
-static inline byte
-readisac_3(int iobase, byte offset)
-{
- return (bytein(iobase - 0x420 + offset));
-}
-
-#define READISAC(mbase,ibase,ofs) \
- ((mbase)?readisac_0(mbase,ofs):readisac_3(ibase,ofs))
-
-static inline void
-writeisac_0(byte * cardm, byte offset, byte value)
-{
- writeb(value, cardm + 0x100 + ((offset & 1) ? 0x1ff : 0) + offset);
-}
-
-static inline void
-writeisac_3(int iobase, byte offset, byte value)
-{
- byteout(iobase - 0x420 + offset, value);
-}
-
-#define WRITEISAC(mbase,ibase,ofs,val) \
- ((mbase)?writeisac_0(mbase,ofs,val):writeisac_3(ibase,ofs,val))
-
-static inline void
-readisac_s(int iobase, byte offset, byte * dest, int count)
-{
- insb(iobase - 0x420 + offset, dest, count);
-}
-
-static inline void
-writeisac_s(int iobase, byte offset, byte * src, int count)
-{
- outsb(iobase - 0x420 + offset, src, count);
-}
-
-static inline byte
-readhscx_0(byte * base, byte hscx, byte offset)
-{
- return readb(base + 0x180 + ((offset & 1) ? 0x1FF : 0) +
- ((hscx & 1) ? 0x40 : 0) + offset);
-}
-
-static inline byte
-readhscx_3(int iobase, byte hscx, byte offset)
-{
- return (bytein(iobase - (hscx ? 0x820 : 0xc20) + offset));
-}
-
-#define READHSCX(mbase,ibase,hscx,ofs) \
- ((mbase)?readhscx_0(mbase,hscx,ofs):readhscx_3(ibase,hscx,ofs))
-
-static inline void
-writehscx_0(byte * base, byte hscx, byte offset, byte data)
-{
- writeb(data, base + 0x180 + ((offset & 1) ? 0x1FF : 0) +
- ((hscx & 1) ? 0x40 : 0) + offset);
-}
-
-static inline void
-writehscx_3(int iobase, byte hscx, byte offset, byte data)
-{
- byteout(iobase - (hscx ? 0x820 : 0xc20) + offset, data);
-}
-
-static inline void
-readhscx_s(int iobase, byte hscx, byte offset, byte * dest, int count)
-{
- insb(iobase - (hscx ? 0x820 : 0xc20) + offset, dest, count);
-}
-
-static inline void
-writehscx_s(int iobase, byte hscx, byte offset, byte * src, int count)
-{
- outsb(iobase - (hscx ? 0x820 : 0xc20) + offset, src, count);
-}
-
-#define ISAC_MASK 0x20
-#define ISAC_ISTA 0x20
-#define ISAC_STAR 0x21
-#define ISAC_CMDR 0x21
-#define ISAC_EXIR 0x24
-
-#define ISAC_RBCH 0x2a
-
-#define ISAC_ADF2 0x39
-#define ISAC_SPCR 0x30
-#define ISAC_ADF1 0x38
-#define ISAC_CIX0 0x31
-#define ISAC_STCR 0x37
-#define ISAC_MODE 0x22
-#define ISAC_RSTA 0x27
-#define ISAC_RBCL 0x25
-#define ISAC_TIMR 0x23
-#define ISAC_SQXR 0x3b
-
-#define HSCX_ISTA 0x20
-#define HSCX_CCR1 0x2f
-#define HSCX_CCR2 0x2c
-#define HSCX_TSAR 0x31
-#define HSCX_TSAX 0x30
-#define HSCX_XCCR 0x32
-#define HSCX_RCCR 0x33
-#define HSCX_MODE 0x22
-#define HSCX_CMDR 0x21
-#define HSCX_EXIR 0x24
-#define HSCX_XAD1 0x24
-#define HSCX_XAD2 0x25
-#define HSCX_RAH2 0x27
-#define HSCX_RSTA 0x27
-#define HSCX_TIMR 0x23
-#define HSCX_STAR 0x21
-#define HSCX_RBCL 0x25
-#define HSCX_XBCH 0x2d
-#define HSCX_VSTR 0x2e
-#define HSCX_RLCR 0x2e
-#define HSCX_MASK 0x20
-
-static inline void
-waitforCEC_0(byte * base, byte hscx)
-{
- long to = 10;
-
- while ((readhscx_0(base, hscx, HSCX_STAR) & 0x04) && to) {
- udelay(5);
- to--;
- }
- if (!to)
- printk(KERN_WARNING "waitforCEC timeout\n");
-}
-
-static inline void
-waitforCEC_3(int iobase, byte hscx)
-{
- long to = 10;
-
- while ((readhscx_3(iobase, hscx, HSCX_STAR) & 0x04) && to) {
- udelay(5);
- to--;
- }
- if (!to)
- printk(KERN_WARNING "waitforCEC timeout\n");
-}
-
-static inline void
-waitforXFW_0(byte * base, byte hscx)
-{
- long to = 20;
-
- while ((!(readhscx_0(base, hscx, HSCX_STAR) & 0x44)==0x40) && to) {
- udelay(5);
- to--;
- }
- if (!to)
- printk(KERN_WARNING "waitforXFW timeout\n");
-}
-
-static inline void
-waitforXFW_3(int iobase, byte hscx)
-{
- long to = 20;
-
- while ((!(readhscx_3(iobase, hscx, HSCX_STAR) & 0x44)==0x40) && to) {
- udelay(5);
- to--;
- }
- if (!to)
- printk(KERN_WARNING "waitforXFW timeout\n");
-}
-
-static inline void
-writehscxCMDR_0(byte * base, byte hscx, byte data)
-{
- long flags;
-
- save_flags(flags);
- cli();
- waitforCEC_0(base, hscx);
- writehscx_0(base, hscx, HSCX_CMDR, data);
- restore_flags(flags);
-}
-
-static inline void
-writehscxCMDR_3(int iobase, byte hscx, byte data)
-{
- long flags;
-
- save_flags(flags);
- cli();
- waitforCEC_3(iobase, hscx);
- writehscx_3(iobase, hscx, HSCX_CMDR, data);
- restore_flags(flags);
-}
-
-#define WRITEHSCX_CMDR(mbase,ibase,hscx,data) \
- ((mbase)?writehscxCMDR_0(mbase,hscx,data):writehscxCMDR_3(ibase,hscx,data))
-
-/*
- * fast interrupt here
- */
-
-#define ISAC_RCVBUFREADY 0
-#define ISAC_XMTBUFREADY 1
-#define ISAC_PHCHANGE 2
-
-#define HSCX_RCVBUFREADY 0
-#define HSCX_XMTBUFREADY 1
-
-void
-teles_hscxreport(struct IsdnCardState *sp, int hscx)
-{
- printk(KERN_DEBUG "HSCX %d\n", hscx);
- if (sp->membase) {
- printk(KERN_DEBUG " ISTA %x\n", readhscx_0(sp->membase,
- hscx, HSCX_ISTA));
- printk(KERN_DEBUG " STAR %x\n", readhscx_0(sp->membase,
- hscx, HSCX_STAR));
- printk(KERN_DEBUG " EXIR %x\n", readhscx_0(sp->membase,
- hscx, HSCX_EXIR));
- } else {
- printk(KERN_DEBUG " ISTA %x\n", readhscx_3(sp->iobase,
- hscx, HSCX_ISTA));
- printk(KERN_DEBUG " STAR %x\n", readhscx_3(sp->iobase,
- hscx, HSCX_STAR));
- printk(KERN_DEBUG " EXIR %x\n", readhscx_3(sp->iobase,
- hscx, HSCX_EXIR));
- }
-}
-
-void
-teles_report(struct IsdnCardState *sp)
-{
- printk(KERN_DEBUG "ISAC\n");
- if (sp->membase) {
- printk(KERN_DEBUG " ISTA %x\n", readisac_0(sp->membase,
- ISAC_ISTA));
- printk(KERN_DEBUG " STAR %x\n", readisac_0(sp->membase,
- ISAC_STAR));
- printk(KERN_DEBUG " EXIR %x\n", readisac_0(sp->membase,
- ISAC_EXIR));
- } else {
- printk(KERN_DEBUG " ISTA %x\n", readisac_3(sp->iobase,
- ISAC_ISTA));
- printk(KERN_DEBUG " STAR %x\n", readisac_3(sp->iobase,
- ISAC_STAR));
- printk(KERN_DEBUG " EXIR %x\n", readisac_3(sp->iobase,
- ISAC_EXIR));
- }
- teles_hscxreport(sp, 0);
- teles_hscxreport(sp, 1);
-}
-
-/*
- * HSCX stuff goes here
- */
-
-static void
-hscx_sched_event(struct HscxState *hsp, int event)
-{
- hsp->event |= 1 << event;
- queue_task_irq_off(&hsp->tqueue, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
-}
-
-static void
-hscx_empty_fifo(struct HscxState *hsp, int count)
-{
- byte *ptr;
- struct BufHeader *ibh = hsp->rcvibh;
-
- if (hsp->sp->debug)
- printk(KERN_DEBUG "hscx_empty_fifo\n");
-
- if (hsp->rcvptr + count > BUFFER_SIZE(HSCX_RBUF_ORDER,
- HSCX_RBUF_BPPS)) {
- printk(KERN_WARNING
- "hscx_empty_fifo: incoming packet too large\n");
- WRITEHSCX_CMDR(hsp->membase, hsp->iobase, hsp->hscx, 0x80);
- return;
- }
- ptr = DATAPTR(ibh);
- ptr += hsp->rcvptr;
-
- hsp->rcvptr += count;
- if (hsp->membase) {
- while (count--)
- *ptr++ = readhscx_0(hsp->membase, hsp->hscx, 0x0);
- writehscxCMDR_0(hsp->membase, hsp->hscx, 0x80);
- } else {
- readhscx_s(hsp->iobase, hsp->hscx, 0x3e, ptr, count);
- writehscxCMDR_3(hsp->iobase, hsp->hscx, 0x80);
- }
-}
-
-static void
-hscx_fill_fifo(struct HscxState *hsp)
-{
- struct BufHeader *ibh;
- int more, count;
- byte *ptr;
-
- if (hsp->sp->debug)
- printk(KERN_DEBUG "hscx_fill_fifo\n");
-
- ibh = hsp->xmtibh;
- if (!ibh)
- return;
-
- count = ibh->datasize - hsp->sendptr;
- if (count <= 0)
- return;
-
- more = (hsp->mode == 1)?1:0;
- if (count > 32) {
- more = !0;
- count = 32;
- }
- ptr = DATAPTR(ibh);
- ptr += hsp->sendptr;
- hsp->sendptr += count;
-
-#ifdef BCHAN_VERBOSE
- {
- int i;
- printk(KERN_DEBUG "hscx_fill_fifo ");
- for (i = 0; i < count; i++)
- printk(" %2x", ptr[i]);
- printk("\n");
- }
-#endif
- if (hsp->membase) {
- waitforXFW_0(hsp->membase, hsp->hscx);
- while (count--)
- writehscx_0(hsp->membase, hsp->hscx, 0x0, *ptr++);
- writehscxCMDR_0(hsp->membase, hsp->hscx, more ? 0x8 : 0xa);
- } else {
- waitforXFW_3(hsp->iobase, hsp->hscx);
- writehscx_s(hsp->iobase, hsp->hscx, 0x3e, ptr, count);
- writehscxCMDR_3(hsp->iobase, hsp->hscx, more ? 0x8 : 0xa);
- }
-}
-
-static inline void
-hscx_interrupt(struct IsdnCardState *sp, byte val, byte hscx)
-{
- byte r;
- struct HscxState *hsp = sp->hs + hscx;
- int count, err;
-
- if (!hsp->init)
- return;
-
- if (val & 0x80) { /* RME */
-
- r = READHSCX(hsp->membase, sp->iobase, hsp->hscx, HSCX_RSTA);
- if ((r & 0xf0) != 0xa0) {
- if (!r & 0x80)
- printk(KERN_WARNING
- "Teles: HSCX invalid frame\n");
- if ((r & 0x40) && hsp->mode)
- printk(KERN_WARNING "Teles: HSCX RDO mode=%d\n",hsp->mode);
- if (!r & 0x20)
- printk(KERN_WARNING "Teles: HSCX CRC error\n");
- if (hsp->rcvibh)
- BufPoolRelease(hsp->rcvibh);
- hsp->rcvibh = NULL;
- WRITEHSCX_CMDR(hsp->membase, hsp->iobase, hsp->hscx,
- 0x80);
- goto afterRME;
- }
- if (!hsp->rcvibh)
- if (BufPoolGet(&hsp->rcvibh, &hsp->rbufpool,
- GFP_ATOMIC, (void *) 1, 1)) {
- printk(KERN_WARNING
- "HSCX RME out of buffers at %ld\n",
- jiffies);
- WRITEHSCX_CMDR(hsp->membase, hsp->iobase,
- hsp->hscx, 0x80);
- goto afterRME;
- } else
- hsp->rcvptr = 0;
-
- count = READHSCX(hsp->membase, sp->iobase, hsp->hscx,
- HSCX_RBCL) & 0x1f;
- if (count == 0)
- count = 32;
- hscx_empty_fifo(hsp, count);
- hsp->rcvibh->datasize = hsp->rcvptr - 1;
- BufQueueLink(&hsp->rq, hsp->rcvibh);
- hsp->rcvibh = NULL;
- hscx_sched_event(hsp, HSCX_RCVBUFREADY);
- }
- afterRME:
- if (val & 0x40) { /* RPF */
- if (!hsp->rcvibh) {
- if (hsp->mode == 1)
- err=BufPoolGet(&hsp->rcvibh, &hsp->smallpool,
- GFP_ATOMIC, (void *)1, 2);
- else
- err=BufPoolGet(&hsp->rcvibh, &hsp->rbufpool,
- GFP_ATOMIC, (void *)1, 2);
-
- if (err) {
- printk(KERN_WARNING
- "HSCX RPF out of buffers at %ld\n",
- jiffies);
- WRITEHSCX_CMDR(hsp->membase, hsp->iobase,
- hsp->hscx, 0x80);
- goto afterRPF;
- } else
- hsp->rcvptr = 0;
- }
-
- hscx_empty_fifo(hsp, 32);
- if (hsp->mode == 1) {
- /* receive audio data */
- hsp->rcvibh->datasize = hsp->rcvptr;
- BufQueueLink(&hsp->rq, hsp->rcvibh);
- hsp->rcvibh = NULL;
- hscx_sched_event(hsp, HSCX_RCVBUFREADY);
- }
-
- }
- afterRPF:
- if (val & 0x10) { /* XPR */
- if (hsp->xmtibh)
- if (hsp->xmtibh->datasize > hsp->sendptr) {
- hscx_fill_fifo(hsp);
- goto afterXPR;
- } else {
- if (hsp->releasebuf)
- BufPoolRelease(hsp->xmtibh);
- hsp->sendptr = 0;
- if (hsp->st->l4.l1writewakeup)
- hsp->st->l4.l1writewakeup(hsp->st);
- hsp->xmtibh = NULL;
- }
- if (!BufQueueUnlink(&hsp->xmtibh, &hsp->sq)) {
- hsp->releasebuf = !0;
- hscx_fill_fifo(hsp);
- } else
- hscx_sched_event(hsp, HSCX_XMTBUFREADY);
- }
- afterXPR:
-}
-
-/*
- * ISAC stuff goes here
- */
-
-static void
-isac_sched_event(struct IsdnCardState *sp, int event)
-{
- sp->event |= 1 << event;
- queue_task_irq_off(&sp->tqueue, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
-}
-
-static void
-empty_fifo(struct IsdnCardState *sp, int count)
-{
- byte *ptr;
- struct BufHeader *ibh = sp->rcvibh;
-
- if (sp->debug)
- printk(KERN_DEBUG "empty_fifo\n");
-
- if (sp->rcvptr >= 3072) {
- printk(KERN_WARNING "empty_fifo rcvptr %d\n", sp->rcvptr);
- return;
- }
- ptr = DATAPTR(ibh);
- ptr += sp->rcvptr;
- sp->rcvptr += count;
-
- if (sp->membase) {
-#ifdef DCHAN_VERBOSE
- printk(KERN_DEBUG "empty_fifo ");
- while (count--) {
- *ptr = readisac_0(sp->membase, 0x0);
- printk("%2x ", *ptr);
- ptr++;
- }
- printk("\n");
-#else
- while (count--)
- *ptr++ = readisac_0(sp->membase, 0x0);
-#endif
- writeisac_0(sp->membase, ISAC_CMDR, 0x80);
- } else {
-#ifdef DCHAN_VERBOSE
- int i;
- printk(KERN_DEBUG "empty_fifo ");
- readisac_s(sp->iobase, 0x3e, ptr, count);
- for (i = 0; i < count; i++)
- printk("%2x ", ptr[i]);
- printk("\n");
-#else
- readisac_s(sp->iobase, 0x3e, ptr, count);
-#endif
- writeisac_3(sp->iobase, ISAC_CMDR, 0x80);
- }
-}
-
-static void
-fill_fifo(struct IsdnCardState *sp)
-{
- struct BufHeader *ibh;
- int count, more;
- byte *ptr;
-
- if (sp->debug)
- printk(KERN_DEBUG "fill_fifo\n");
-
- ibh = sp->xmtibh;
- if (!ibh)
- return;
-
- count = ibh->datasize - sp->sendptr;
- if (count <= 0)
- return;
- if (count >= 3072)
- return;
-
- more = 0;
- if (count > 32) {
- more = !0;
- count = 32;
- }
- ptr = DATAPTR(ibh);
- ptr += sp->sendptr;
- sp->sendptr += count;
-
- if (sp->membase) {
-#ifdef DCHAN_VERBOSE
- printk(KERN_DEBUG "fill_fifo ");
- while (count--) {
- writeisac_0(sp->membase, 0x0, *ptr);
- printk("%2x ", *ptr);
- ptr++;
- }
- printk("\n");
-#else
- while (count--)
- writeisac_0(sp->membase, 0x0, *ptr++);
-#endif
- writeisac_0(sp->membase, ISAC_CMDR, more ? 0x8 : 0xa);
- } else {
-#ifdef DCHAN_VERBOSE
- int i;
- writeisac_s(sp->iobase, 0x3e, ptr, count);
- printk(KERN_DEBUG "fill_fifo ");
- for (i = 0; i < count; i++)
- printk("%2x ", ptr[i]);
- printk("\n");
-#else
- writeisac_s(sp->iobase, 0x3e, ptr, count);
-#endif
- writeisac_3(sp->iobase, ISAC_CMDR, more ? 0x8 : 0xa);
- }
-}
-
-static int
-act_wanted(struct IsdnCardState *sp)
-{
- struct PStack *st;
-
- st = sp->stlist;
- while (st)
- if (st->l1.act_state)
- return (!0);
- else
- st = st->next;
- return (0);
-}
-
-static void
-ph_command(struct IsdnCardState *sp, unsigned int command)
-{
- printk(KERN_DEBUG "ph_command %d\n", command);
- WRITEISAC(sp->membase, sp->iobase, ISAC_CIX0, (command << 2) | 3);
-}
-
-static void
-isac_new_ph(struct IsdnCardState *sp)
-{
- int enq;
-
- enq = act_wanted(sp);
-
- switch (sp->ph_state) {
- case (0):
- case (6):
- if (enq)
- ph_command(sp, 0);
- else
- ph_command(sp, 15);
- break;
- case (7):
- if (enq)
- ph_command(sp, 9);
- break;
- case (12):
- ph_command(sp, 8);
- sp->ph_active = 5;
- isac_sched_event(sp, ISAC_PHCHANGE);
- if (!sp->xmtibh)
- if (!BufQueueUnlink(&sp->xmtibh, &sp->sq))
- sp->sendptr = 0;
- if (sp->xmtibh)
- fill_fifo(sp);
- break;
- case (13):
- ph_command(sp, 9);
- sp->ph_active = 5;
- isac_sched_event(sp, ISAC_PHCHANGE);
- if (!sp->xmtibh)
- if (!BufQueueUnlink(&sp->xmtibh, &sp->sq))
- sp->sendptr = 0;
- if (sp->xmtibh)
- fill_fifo(sp);
- break;
- case (4):
- case (8):
- break;
- default:
- sp->ph_active = 0;
- break;
- }
-}
-
-static void
-teles_interrupt(int intno, void *dev_id, struct pt_regs *regs)
-{
- byte val, r, exval;
- struct IsdnCardState *sp;
- unsigned int count;
- struct HscxState *hsp;
-
- sp = (struct IsdnCardState *) irq2dev_map[intno];
-
- if (!sp) {
- printk(KERN_WARNING "Teles: Spurious interrupt!\n");
- return;
- }
- val = READHSCX(sp->membase, sp->iobase, 1, HSCX_ISTA);
-
- if (val & 0x01) {
- hsp = sp->hs + 1;
- exval = READHSCX(sp->membase, sp->iobase, 1, HSCX_EXIR);
- if (exval == 0x40) {
- if (hsp->mode == 1)
- hscx_fill_fifo(hsp);
- else {
- /* Here we lost an TX interrupt, so
- * restart transmitting the whole frame.
- */
- hsp->sendptr = 0;
- WRITEHSCX_CMDR(hsp->membase, hsp->iobase,
- hsp->hscx, 0x01);
- printk(KERN_DEBUG "HSCX B EXIR %x\n", exval);
- }
- } else
- printk(KERN_WARNING "HSCX B EXIR %x\n", exval);
- }
- if (val & 0xf8) {
- if (sp->debug)
- printk(KERN_DEBUG "HSCX B interrupt %x\n", val);
- hscx_interrupt(sp, val, 1);
- }
- if (val & 0x02) {
- hsp = sp->hs;
- exval = READHSCX(sp->membase, sp->iobase, 0, HSCX_EXIR);
- if (exval == 0x40) {
- if (hsp->mode == 1)
- hscx_fill_fifo(hsp);
- else {
- /* Here we lost an TX interrupt, so
- * restart transmitting the whole frame.
- */
- hsp->sendptr = 0;
- WRITEHSCX_CMDR(hsp->membase, hsp->iobase,
- hsp->hscx, 0x01);
- printk(KERN_DEBUG "HSCX A EXIR %x\n", exval);
- }
- } else
- printk(KERN_WARNING "HSCX A EXIR %x\n", exval);
- }
- if (val & 0x04) {
- val = READHSCX(sp->membase, sp->iobase, 0, HSCX_ISTA);
- if (sp->debug)
- printk(KERN_DEBUG "HSCX A interrupt %x\n",
- val);
- hscx_interrupt(sp, val, 0);
- }
-
- val = READISAC(sp->membase, sp->iobase, ISAC_ISTA);
-
- if (sp->debug)
- printk(KERN_DEBUG "ISAC interrupt %x\n", val);
-
- if (val & 0x80) { /* RME */
-
- r = READISAC(sp->membase, sp->iobase, ISAC_RSTA);
- if ((r & 0x70) != 0x20) {
- if (r & 0x40)
- printk(KERN_WARNING "Teles: ISAC RDO\n");
- if (!r & 0x20)
- printk(KERN_WARNING "Teles: ISAC CRC error\n");
- if (sp->rcvibh)
- BufPoolRelease(sp->rcvibh);
- sp->rcvibh = NULL;
- WRITEISAC(sp->membase, sp->iobase, ISAC_CMDR, 0x80);
- goto afterRME;
- }
- if (!sp->rcvibh)
- if (BufPoolGet(&(sp->rcvibh), &(sp->rbufpool),
- GFP_ATOMIC,
- (void *) 1, 3)) {
- printk(KERN_WARNING
- "ISAC RME out of buffers!\n");
- WRITEISAC(sp->membase, sp->iobase,
- ISAC_CMDR, 0x80);
- goto afterRME;
- } else
- sp->rcvptr = 0;
-
- count = READISAC(sp->membase, sp->iobase, ISAC_RBCL) & 0x1f;
- if (count == 0)
- count = 32;
- empty_fifo(sp, count);
- sp->rcvibh->datasize = sp->rcvptr;
- BufQueueLink(&(sp->rq), sp->rcvibh);
- sp->rcvibh = NULL;
- isac_sched_event(sp, ISAC_RCVBUFREADY);
- }
- afterRME:
- if (val & 0x40) { /* RPF */
- if (!sp->rcvibh)
- if (BufPoolGet(&(sp->rcvibh), &(sp->rbufpool),
- GFP_ATOMIC,
- (void *) 1, 4)) {
- printk(KERN_WARNING
- "ISAC RME out of buffers!\n");
- WRITEISAC(sp->membase, sp->iobase,
- ISAC_CMDR, 0x80);
- goto afterRPF;
- } else
- sp->rcvptr = 0;
- empty_fifo(sp, 32);
- }
- afterRPF:
- if (val & 0x20) {
- }
- if (val & 0x10) { /* XPR */
- if (sp->xmtibh)
- if (sp->xmtibh->datasize > sp->sendptr) {
- fill_fifo(sp);
- goto afterXPR;
- } else {
- if (sp->releasebuf)
- BufPoolRelease(sp->xmtibh);
- sp->xmtibh = NULL;
- sp->sendptr = 0;
- }
- if (!BufQueueUnlink(&sp->xmtibh, &sp->sq)) {
- sp->releasebuf = !0;
- fill_fifo(sp);
- } else
- isac_sched_event(sp, ISAC_XMTBUFREADY);
- }
- afterXPR:
- if (val & 0x04) { /* CISQ */
- sp->ph_state = (READISAC(sp->membase, sp->iobase, ISAC_CIX0)
- >> 2) & 0xf;
- printk(KERN_DEBUG "l1state %d\n", sp->ph_state);
- isac_new_ph(sp);
- }
- if (sp->membase) {
- writeisac_0(sp->membase, ISAC_MASK, 0xFF);
- writehscx_0(sp->membase, 0, HSCX_MASK, 0xFF);
- writehscx_0(sp->membase, 1, HSCX_MASK, 0xFF);
- writeisac_0(sp->membase, ISAC_MASK, 0x0);
- writehscx_0(sp->membase, 0, HSCX_MASK, 0x0);
- writehscx_0(sp->membase, 1, HSCX_MASK, 0x0);
- } else {
- writeisac_3(sp->iobase, ISAC_MASK, 0xFF);
- writehscx_3(sp->iobase, 0, HSCX_MASK, 0xFF);
- writehscx_3(sp->iobase, 1, HSCX_MASK, 0xFF);
- writeisac_3(sp->iobase, ISAC_MASK, 0x0);
- writehscx_3(sp->iobase, 0, HSCX_MASK, 0x0);
- writehscx_3(sp->iobase, 1, HSCX_MASK, 0x0);
- }
-}
-
-/*
- * soft interrupt
- */
-
-static void
-act_ivated(struct IsdnCardState *sp)
-{
- struct PStack *st;
-
- st = sp->stlist;
- while (st) {
- if (st->l1.act_state == 1) {
- st->l1.act_state = 2;
- st->l1.l1man(st, PH_ACTIVATE, NULL);
- }
- st = st->next;
- }
-}
-
-static void
-process_new_ph(struct IsdnCardState *sp)
-{
- if (sp->ph_active == 5)
- act_ivated(sp);
-}
-
-static void
-process_xmt(struct IsdnCardState *sp)
-{
- struct PStack *stptr;
-
- if (sp->xmtibh)
- return;
-
- stptr = sp->stlist;
- while (stptr != NULL)
- if (stptr->l1.requestpull) {
- stptr->l1.requestpull = 0;
- stptr->l1.l1l2(stptr, PH_PULL_ACK, NULL);
- break;
- } else
- stptr = stptr->next;
-}
-
-static void
-process_rcv(struct IsdnCardState *sp)
-{
- struct BufHeader *ibh, *cibh;
- struct PStack *stptr;
- byte *ptr;
- int found, broadc;
- char tmp[64];
-
- while (!BufQueueUnlink(&ibh, &sp->rq)) {
- stptr = sp->stlist;
- ptr = DATAPTR(ibh);
- broadc = (ptr[1] >> 1) == 127;
-
- if (broadc && sp->dlogflag && (!(ptr[0] >> 2)))
- dlogframe(sp, ptr + 3, ibh->datasize - 3,
- "Q.931 frame network->user broadcast");
-
- if (broadc) {
- while (stptr != NULL) {
- if ((ptr[0] >> 2) == stptr->l2.sap)
- if (!BufPoolGet(&cibh, &sp->rbufpool, GFP_ATOMIC,
- (void *) 1, 5)) {
- memcpy(DATAPTR(cibh), DATAPTR(ibh), ibh->datasize);
- cibh->datasize = ibh->datasize;
- stptr->l1.l1l2(stptr, PH_DATA, cibh);
- } else
- printk(KERN_WARNING "isdn broadcast buffer shortage\n");
- stptr = stptr->next;
- }
- BufPoolRelease(ibh);
- } else {
- found = 0;
- while (stptr != NULL)
- if (((ptr[0] >> 2) == stptr->l2.sap) &&
- ((ptr[1] >> 1) == stptr->l2.tei)) {
- stptr->l1.l1l2(stptr, PH_DATA, ibh);
- found = !0;
- break;
- } else
- stptr = stptr->next;
- if (!found) {
- /* BD 10.10.95
- * Print out D-Channel msg not processed
- * by isdn4linux
- */
-
- if ((!(ptr[0] >> 2)) && (!(ptr[2] & 0x01))) {
- sprintf(tmp, "Q.931 frame network->user with tei %d (not for us)", ptr[1] >> 1);
- dlogframe(sp, ptr + 4, ibh->datasize - 4, tmp);
- }
- BufPoolRelease(ibh);
- }
- }
-
- }
-
-}
-
-static void
-isac_bh(struct IsdnCardState *sp)
-{
- if (!sp)
- return;
-
- if (clear_bit(ISAC_PHCHANGE, &sp->event))
- process_new_ph(sp);
- if (clear_bit(ISAC_RCVBUFREADY, &sp->event))
- process_rcv(sp);
- if (clear_bit(ISAC_XMTBUFREADY, &sp->event))
- process_xmt(sp);
-}
-
-
-static void
-hscx_process_xmt(struct HscxState *hsp)
-{
- struct PStack *st = hsp->st;
-
- if (hsp->xmtibh)
- return;
-
- if (st->l1.requestpull) {
- st->l1.requestpull = 0;
- st->l1.l1l2(st, PH_PULL_ACK, NULL);
- }
- if (!hsp->active)
- if ((!hsp->xmtibh) && (!hsp->sq.head))
- modehscx(hsp, 0, 0);
-}
-
-static void
-hscx_process_rcv(struct HscxState *hsp)
-{
- struct BufHeader *ibh;
-
-#ifdef DEBUG_MAGIC
- if (hsp->magic != 301270) {
- printk(KERN_DEBUG "hscx_process_rcv magic not 301270\n");
- return;
- }
-#endif
- while (!BufQueueUnlink(&ibh, &hsp->rq)) {
- hsp->st->l1.l1l2(hsp->st, PH_DATA, ibh);
- }
-}
-
-static void
-hscx_bh(struct HscxState *hsp)
-{
-
- if (!hsp)
- return;
-
- if (clear_bit(HSCX_RCVBUFREADY, &hsp->event))
- hscx_process_rcv(hsp);
- if (clear_bit(HSCX_XMTBUFREADY, &hsp->event))
- hscx_process_xmt(hsp);
-
-}
-
-/*
- * interrupt stuff ends here
- */
-
-static void
-restart_ph(struct IsdnCardState *sp)
-{
- switch (sp->ph_active) {
- case (0):
- if (sp->ph_state == 6)
- ph_command(sp, 0);
- else
- ph_command(sp, 1);
- sp->ph_active = 1;
- break;
- }
-}
-
-static void
-initisac(byte * cardmem, int iobase)
-{
- if (cardmem) {
- writeisac_0(cardmem, ISAC_MASK, 0xff);
- writeisac_0(cardmem, ISAC_ADF2, 0x0);
- writeisac_0(cardmem, ISAC_SPCR, 0xa);
- writeisac_0(cardmem, ISAC_ADF1, 0x2);
- writeisac_0(cardmem, ISAC_STCR, 0x70);
- writeisac_0(cardmem, ISAC_MODE, 0xc9);
- writeisac_0(cardmem, ISAC_CMDR, 0x41);
- writeisac_0(cardmem, ISAC_CIX0, (1 << 2) | 3);
- } else {
- writeisac_3(iobase, ISAC_MASK, 0xff);
- writeisac_3(iobase, ISAC_ADF2, 0x80);
- writeisac_3(iobase, ISAC_SQXR, 0x2f);
- writeisac_3(iobase, ISAC_SPCR, 0x00);
- writeisac_3(iobase, ISAC_ADF1, 0x02);
- writeisac_3(iobase, ISAC_STCR, 0x70);
- writeisac_3(iobase, ISAC_MODE, 0xc9);
- writeisac_3(iobase, ISAC_TIMR, 0x00);
- writeisac_3(iobase, ISAC_ADF1, 0x00);
- writeisac_3(iobase, ISAC_CMDR, 0x41);
- writeisac_3(iobase, ISAC_CIX0, (1 << 2) | 3);
- }
-}
-
-static int
-checkcard(int cardnr)
-{
- int timout;
- byte cfval, val;
- struct IsdnCard *card = cards + cardnr;
-
- if (card->membase)
- if ((unsigned long)card->membase < 0x10000) {
- (unsigned long)card->membase <<= 4;
- printk(KERN_INFO
- "Teles membase configured DOSish, assuming 0x%lx\n",
- (unsigned long)card->membase);
- }
- if (!card->iobase) {
- if (card->membase) {
- printk(KERN_NOTICE
- "Teles 8 assumed, mem: %lx irq: %d proto: %s\n",
- (long) card->membase, card->interrupt,
- (card->protocol == ISDN_PTYPE_1TR6) ?
- "1TR6" : "EDSS1");
- printk(KERN_INFO "HSCX version A:%x B:%x\n",
- readhscx_0(card->membase, 0, HSCX_VSTR) & 0xf,
- readhscx_0(card->membase, 1, HSCX_VSTR) & 0xf);
- }
- } else {
- switch (card->iobase) {
- case 0x180:
- case 0x280:
- case 0x380:
- card->iobase |= 0xc00;
- break;
- }
- if (card->membase) { /* 16.0 */
- if (check_region(card->iobase, 8)) {
- printk(KERN_WARNING
- "teles: ports %x-%x already in use\n",
- card->iobase,
- card->iobase + 8 );
- return -1;
- }
- } else { /* 16.3 */
- if (check_region(card->iobase, 16)) {
- printk(KERN_WARNING
- "teles: 16.3 ports %x-%x already in use\n",
- card->iobase,
- card->iobase + 16 );
- return -1;
- }
- if (check_region((card->iobase - 0xc00) , 32)) {
- printk(KERN_WARNING
- "teles: 16.3 ports %x-%x already in use\n",
- card->iobase - 0xc00,
- card->iobase - 0xc00 + 32);
- return -1;
- }
- if (check_region((card->iobase - 0x800) , 32)) {
- printk(KERN_WARNING
- "teles: 16.3 ports %x-%x already in use\n",
- card->iobase - 0x800,
- card->iobase - 0x800 + 32);
- return -1;
- }
- if (check_region((card->iobase - 0x400) , 32)) {
- printk(KERN_WARNING
- "teles: 16.3 ports %x-%x already in use\n",
- card->iobase - 0x400,
- card->iobase - 0x400 + 32);
- return -1;
- }
- }
- switch (card->interrupt) {
- case 2:
- cfval = 0x00;
- break;
- case 3:
- cfval = 0x02;
- break;
- case 4:
- cfval = 0x04;
- break;
- case 5:
- cfval = 0x06;
- break;
- case 10:
- cfval = 0x08;
- break;
- case 11:
- cfval = 0x0A;
- break;
- case 12:
- cfval = 0x0C;
- break;
- case 15:
- cfval = 0x0E;
- break;
- default:
- cfval = 0x00;
- break;
- }
- if (card->membase) {
- cfval |= (((unsigned int) card->membase >> 9) & 0xF0);
- }
- if (bytein(card->iobase + 0) != 0x51) {
- printk(KERN_INFO "XXX Byte at %x is %x\n",
- card->iobase + 0,
- bytein(card->iobase + 0));
- return -2;
- }
- if (bytein(card->iobase + 1) != 0x93) {
- printk(KERN_INFO "XXX Byte at %x is %x\n",
- card->iobase + 1,
- bytein(card->iobase + 1));
- return -2;
- }
- val = bytein(card->iobase + 2); /* 0x1e=without AB
- * 0x1f=with AB
- * 0x1c 16.3 ???
- */
- if (val != 0x1c && val != 0x1e && val != 0x1f) {
- printk(KERN_INFO "XXX Byte at %x is %x\n",
- card->iobase + 2,
- bytein(card->iobase + 2));
- return -2;
- }
- if (card->membase) { /* 16.0 */
- request_region(card->iobase, 8, "teles 16.0");
- } else {
- request_region(card->iobase, 16, "teles 16.3");
- request_region(card->iobase - 0xC00, 32, "teles HSCX0");
- request_region(card->iobase - 0x800, 32, "teles HSCX1");
- request_region(card->iobase - 0x400, 32, "teles ISAC");
- }
- cli();
- timout = jiffies + (HZ / 10) + 1;
- byteout(card->iobase + 4, cfval);
- sti();
- while (jiffies <= timout);
-
- cli();
- timout = jiffies + (HZ / 10) + 1;
- byteout(card->iobase + 4, cfval | 1);
- sti();
- while (jiffies <= timout);
-
- if (card->membase)
- printk(KERN_NOTICE
- "Teles 16.0 found, io: %x mem: %lx irq: %d proto: %s\n",
- card->iobase, (long) card->membase,
- card->interrupt,
- (card->protocol == ISDN_PTYPE_1TR6) ?
- "1TR6" : "EDSS1");
- else
- printk(KERN_NOTICE
- "Teles 16.3 found, io: %x irq: %d proto: %s\n",
- card->iobase, card->interrupt,
- (card->protocol == ISDN_PTYPE_1TR6) ?
- "1TR6" : "EDSS1");
- printk(KERN_INFO "HSCX version A:%x B:%x\n",
- READHSCX(card->membase, card->iobase, 0,
- HSCX_VSTR) & 0xf,
- READHSCX(card->membase, card->iobase, 1,
- HSCX_VSTR) & 0xf);
-
- }
- if (card->membase) {
- cli();
- timout = jiffies + (HZ / 5) + 1;
- writeb(0, card->membase + 0x80);
- sti();
- while (jiffies <= timout);
-
- cli();
- writeb(1, card->membase + 0x80);
- timout = jiffies + (HZ / 5) + 1;
- sti();
- while (jiffies <= timout);
- }
- return (0);
-}
-
-void
-modehscx(struct HscxState *hs, int mode,
- int ichan)
-{
- struct IsdnCardState *sp = hs->sp;
- int hscx = hs->hscx;
-
- printk(KERN_DEBUG "modehscx hscx %d mode %d ichan %d\n",
- hscx, mode, ichan);
-
- hs->mode = mode;
- if (sp->membase) {
- /* What's that ??? KKeil */
- if (hscx == 0)
- ichan = 1 - ichan; /* raar maar waar... */
- writehscx_0(sp->membase, hscx, HSCX_CCR1, 0x85);
- writehscx_0(sp->membase, hscx, HSCX_XAD1, 0xFF);
- writehscx_0(sp->membase, hscx, HSCX_XAD2, 0xFF);
- writehscx_0(sp->membase, hscx, HSCX_RAH2, 0xFF);
- writehscx_0(sp->membase, hscx, HSCX_XBCH, 0x0);
-
- switch (mode) {
- case (0):
- writehscx_0(sp->membase, hscx, HSCX_CCR2, 0x30);
- writehscx_0(sp->membase, hscx, HSCX_TSAX, 0xff);
- writehscx_0(sp->membase, hscx, HSCX_TSAR, 0xff);
- writehscx_0(sp->membase, hscx, HSCX_XCCR, 7);
- writehscx_0(sp->membase, hscx, HSCX_RCCR, 7);
- writehscx_0(sp->membase, hscx, HSCX_MODE, 0x84);
- break;
- case (1):
- if (ichan == 0) {
- writehscx_0(sp->membase, hscx, HSCX_CCR2, 0x30);
- writehscx_0(sp->membase, hscx, HSCX_TSAX, 0x7);
- writehscx_0(sp->membase, hscx, HSCX_TSAR, 0x7);
- writehscx_0(sp->membase, hscx, HSCX_XCCR, 7);
- writehscx_0(sp->membase, hscx, HSCX_RCCR, 7);
- } else {
- writehscx_0(sp->membase, hscx, HSCX_CCR2, 0x30);
- writehscx_0(sp->membase, hscx, HSCX_TSAX, 0x3);
- writehscx_0(sp->membase, hscx, HSCX_TSAR, 0x3);
- writehscx_0(sp->membase, hscx, HSCX_XCCR, 7);
- writehscx_0(sp->membase, hscx, HSCX_RCCR, 7);
- }
- writehscx_0(sp->membase, hscx, HSCX_MODE, 0xe4);
- writehscx_0(sp->membase, hscx, HSCX_CMDR, 0x41);
- break;
- case (2):
- if (ichan == 0) {
- writehscx_0(sp->membase, hscx, HSCX_CCR2, 0x30);
- writehscx_0(sp->membase, hscx, HSCX_TSAX, 0x7);
- writehscx_0(sp->membase, hscx, HSCX_TSAR, 0x7);
- writehscx_0(sp->membase, hscx, HSCX_XCCR, 7);
- writehscx_0(sp->membase, hscx, HSCX_RCCR, 7);
- } else {
- writehscx_0(sp->membase, hscx, HSCX_CCR2, 0x30);
- writehscx_0(sp->membase, hscx, HSCX_TSAX, 0x3);
- writehscx_0(sp->membase, hscx, HSCX_TSAR, 0x3);
- writehscx_0(sp->membase, hscx, HSCX_XCCR, 7);
- writehscx_0(sp->membase, hscx, HSCX_RCCR, 7);
- }
- writehscx_0(sp->membase, hscx, HSCX_MODE, 0x8c);
- writehscx_0(sp->membase, hscx, HSCX_CMDR, 0x41);
- break;
- }
- writehscx_0(sp->membase, hscx, HSCX_ISTA, 0x00);
- } else {
- writehscx_3(sp->iobase, hscx, HSCX_CCR1, 0x85);
- writehscx_3(sp->iobase, hscx, HSCX_XAD1, 0xFF);
- writehscx_3(sp->iobase, hscx, HSCX_XAD2, 0xFF);
- writehscx_3(sp->iobase, hscx, HSCX_RAH2, 0xFF);
- writehscx_3(sp->iobase, hscx, HSCX_XBCH, 0x00);
- writehscx_3(sp->iobase, hscx, HSCX_RLCR, 0x00);
-
- switch (mode) {
- case (0):
- writehscx_3(sp->iobase, hscx, HSCX_CCR2, 0x30);
- writehscx_3(sp->iobase, hscx, HSCX_TSAX, 0xff);
- writehscx_3(sp->iobase, hscx, HSCX_TSAR, 0xff);
- writehscx_3(sp->iobase, hscx, HSCX_XCCR, 7);
- writehscx_3(sp->iobase, hscx, HSCX_RCCR, 7);
- writehscx_3(sp->iobase, hscx, HSCX_MODE, 0x84);
- break;
- case (1):
- if (ichan == 0) {
- writehscx_3(sp->iobase, hscx, HSCX_CCR2, 0x30);
- writehscx_3(sp->iobase, hscx, HSCX_TSAX, 0x2f);
- writehscx_3(sp->iobase, hscx, HSCX_TSAR, 0x2f);
- writehscx_3(sp->iobase, hscx, HSCX_XCCR, 7);
- writehscx_3(sp->iobase, hscx, HSCX_RCCR, 7);
- } else {
- writehscx_3(sp->iobase, hscx, HSCX_CCR2, 0x30);
- writehscx_3(sp->iobase, hscx, HSCX_TSAX, 0x3);
- writehscx_3(sp->iobase, hscx, HSCX_TSAR, 0x3);
- writehscx_3(sp->iobase, hscx, HSCX_XCCR, 7);
- writehscx_3(sp->iobase, hscx, HSCX_RCCR, 7);
- }
- writehscx_3(sp->iobase, hscx, HSCX_MODE, 0xe4);
- writehscx_3(sp->iobase, hscx, HSCX_CMDR, 0x41);
- break;
- case (2):
- if (ichan == 0) {
- writehscx_3(sp->iobase, hscx, HSCX_CCR2, 0x30);
- writehscx_3(sp->iobase, hscx, HSCX_TSAX, 0x2f);
- writehscx_3(sp->iobase, hscx, HSCX_TSAR, 0x2f);
- writehscx_3(sp->iobase, hscx, HSCX_XCCR, 7);
- writehscx_3(sp->iobase, hscx, HSCX_RCCR, 7);
- } else {
- writehscx_3(sp->iobase, hscx, HSCX_CCR2, 0x30);
- writehscx_3(sp->iobase, hscx, HSCX_TSAX, 0x3);
- writehscx_3(sp->iobase, hscx, HSCX_TSAR, 0x3);
- writehscx_3(sp->iobase, hscx, HSCX_XCCR, 7);
- writehscx_3(sp->iobase, hscx, HSCX_RCCR, 7);
- }
- writehscx_3(sp->iobase, hscx, HSCX_MODE, 0x8c);
- writehscx_3(sp->iobase, hscx, HSCX_CMDR, 0x41);
- break;
- }
- writehscx_3(sp->iobase, hscx, HSCX_ISTA, 0x00);
- }
-}
-
-void
-teles_addlist(struct IsdnCardState *sp,
- struct PStack *st)
-{
- st->next = sp->stlist;
- sp->stlist = st;
-}
-
-void
-teles_rmlist(struct IsdnCardState *sp,
- struct PStack *st)
-{
- struct PStack *p;
-
- if (sp->stlist == st)
- sp->stlist = st->next;
- else {
- p = sp->stlist;
- while (p)
- if (p->next == st) {
- p->next = st->next;
- return;
- } else
- p = p->next;
- }
-}
-
-
-static void
-teles_l2l1(struct PStack *st, int pr,
- struct BufHeader *ibh)
-{
- struct IsdnCardState *sp = (struct IsdnCardState *)
- st->l1.hardware;
-
-
- switch (pr) {
- case (PH_DATA):
- if (sp->xmtibh)
- BufQueueLink(&sp->sq, ibh);
- else {
- sp->xmtibh = ibh;
- sp->sendptr = 0;
- sp->releasebuf = !0;
- fill_fifo(sp);
- }
- break;
- case (PH_DATA_PULLED):
- if (sp->xmtibh) {
- printk(KERN_DEBUG "teles_l2l1: this shouldn't happen\n");
- break;
- }
- sp->xmtibh = ibh;
- sp->sendptr = 0;
- sp->releasebuf = 0;
- fill_fifo(sp);
- break;
- case (PH_REQUEST_PULL):
- if (!sp->xmtibh) {
- st->l1.requestpull = 0;
- st->l1.l1l2(st, PH_PULL_ACK, NULL);
- } else
- st->l1.requestpull = !0;
- break;
- }
-}
-
-static void
-check_ph_act(struct IsdnCardState *sp)
-{
- struct PStack *st = sp->stlist;
-
- while (st) {
- if (st->l1.act_state)
- return;
- st = st->next;
- }
- sp->ph_active = 0;
-}
-
-static void
-teles_manl1(struct PStack *st, int pr,
- void *arg)
-{
- struct IsdnCardState *sp = (struct IsdnCardState *)
- st->l1.hardware;
- long flags;
-
- switch (pr) {
- case (PH_ACTIVATE):
- save_flags(flags);
- cli();
- if (sp->ph_active == 5) {
- st->l1.act_state = 2;
- restore_flags(flags);
- st->l1.l1man(st, PH_ACTIVATE, NULL);
- } else {
- st->l1.act_state = 1;
- if (sp->ph_active == 0)
- restart_ph(sp);
- restore_flags(flags);
- }
- break;
- case (PH_DEACTIVATE):
- st->l1.act_state = 0;
- check_ph_act(sp);
- break;
- }
-}
-
-static void
-teles_l2l1discardq(struct PStack *st, int pr,
- void *heldby, int releasetoo)
-{
- struct IsdnCardState *sp = (struct IsdnCardState *) st->l1.hardware;
-
-#ifdef DEBUG_MAGIC
- if (sp->magic != 301271) {
- printk(KERN_DEBUG "isac_discardq magic not 301271\n");
- return;
- }
-#endif
-
- BufQueueDiscard(&sp->sq, pr, heldby, releasetoo);
-}
-
-void
-setstack_teles(struct PStack *st, struct IsdnCardState *sp)
-{
- st->l1.hardware = sp;
- st->l1.sbufpool = &(sp->sbufpool);
- st->l1.rbufpool = &(sp->rbufpool);
- st->l1.smallpool = &(sp->smallpool);
- st->protocol = sp->teistack->protocol;
-
- setstack_tei(st);
-
- st->l1.stlistp = &(sp->stlist);
- st->l1.act_state = 0;
- st->l2.l2l1 = teles_l2l1;
- st->l2.l2l1discardq = teles_l2l1discardq;
- st->ma.manl1 = teles_manl1;
- st->l1.requestpull = 0;
-}
-
-void
-init_hscxstate(struct IsdnCardState *sp,
- int hscx)
-{
- struct HscxState *hsp = sp->hs + hscx;
-
- hsp->sp = sp;
- hsp->hscx = hscx;
- hsp->membase = sp->membase;
- hsp->iobase = sp->iobase;
-
- hsp->tqueue.next = 0;
- hsp->tqueue.sync = 0;
- hsp->tqueue.routine = (void *) (void *) hscx_bh;
- hsp->tqueue.data = hsp;
-
- hsp->inuse = 0;
- hsp->init = 0;
- hsp->active = 0;
-
-#ifdef DEBUG_MAGIC
- hsp->magic = 301270;
-#endif
-}
-
-void
-initcard(int cardnr)
-{
- struct IsdnCardState *sp;
- struct IsdnCard *card = cards + cardnr;
-
- sp = (struct IsdnCardState *)
- Smalloc(sizeof(struct IsdnCardState), GFP_KERNEL,
- "struct IsdnCardState");
-
- sp->membase = card->membase;
- sp->iobase = card->iobase;
- sp->cardnr = cardnr;
-
- BufPoolInit(&sp->sbufpool, ISAC_SBUF_ORDER, ISAC_SBUF_BPPS,
- ISAC_SBUF_MAXPAGES);
- BufPoolInit(&sp->rbufpool, ISAC_RBUF_ORDER, ISAC_RBUF_BPPS,
- ISAC_RBUF_MAXPAGES);
- BufPoolInit(&sp->smallpool, ISAC_SMALLBUF_ORDER, ISAC_SMALLBUF_BPPS,
- ISAC_SMALLBUF_MAXPAGES);
-
- sp->dlogspace = Smalloc(4096, GFP_KERNEL, "dlogspace");
-
- initisac(card->membase, card->iobase);
-
- sp->rcvibh = NULL;
- sp->rcvptr = 0;
- sp->xmtibh = NULL;
- sp->sendptr = 0;
- sp->event = 0;
- sp->tqueue.next = 0;
- sp->tqueue.sync = 0;
- sp->tqueue.routine = (void *) (void *) isac_bh;
- sp->tqueue.data = sp;
-
- BufQueueInit(&sp->rq);
- BufQueueInit(&sp->sq);
-
- sp->stlist = NULL;
-
- sp->ph_active = 0;
-
- sp->dlogflag = 0;
- sp->debug = 0;
-
- sp->releasebuf = 0;
-#ifdef DEBUG_MAGIC
- sp->magic = 301271;
-#endif
-
- cards[sp->cardnr].sp = sp;
-
- init_hscxstate(sp, 0);
- init_hscxstate(sp, 1);
-
- modehscx(sp->hs, 0, 0);
- modehscx(sp->hs + 1, 0, 0);
-
- WRITEISAC(sp->membase, sp->iobase, ISAC_MASK, 0x0);
-}
-
-static int
-get_irq(int cardnr)
-{
- struct IsdnCard *card = cards + cardnr;
- long flags;
-
- save_flags(flags);
- cli();
- if (request_irq(card->interrupt, &teles_interrupt,
- SA_INTERRUPT, "teles", NULL)) {
- printk(KERN_WARNING "Teles couldn't get interrupt %d\n",
- card->interrupt);
- restore_flags(flags);
- return (!0);
- }
- irq2dev_map[card->interrupt] = (void *) card->sp;
- restore_flags(flags);
- return (0);
-}
-
-static void
-release_irq(int cardnr)
-{
- struct IsdnCard *card = cards + cardnr;
-
- irq2dev_map[card->interrupt] = NULL;
- free_irq(card->interrupt, NULL);
-}
-
-void
-close_hscxstate(struct HscxState *hs)
-{
- modehscx(hs, 0, 0);
- hs->inuse = 0;
-
- if (hs->init) {
- BufPoolFree(&hs->smallpool);
- BufPoolFree(&hs->rbufpool);
- BufPoolFree(&hs->sbufpool);
- }
- hs->init = 0;
-}
-
-void
-closecard(int cardnr)
-{
- struct IsdnCardState *sp = cards[cardnr].sp;
-
- cards[cardnr].sp = NULL;
-
- Sfree(sp->dlogspace);
-
- BufPoolFree(&sp->smallpool);
- BufPoolFree(&sp->rbufpool);
- BufPoolFree(&sp->sbufpool);
-
- close_hscxstate(sp->hs + 1);
- close_hscxstate(sp->hs);
-
- if (cards[cardnr].iobase)
- if (cards[cardnr].membase) { /* 16.0 */
- release_region(cards[cardnr].iobase, 8);
- } else {
- release_region(cards[cardnr].iobase, 16);
- release_region(cards[cardnr].iobase - 0xC00, 32);
- release_region(cards[cardnr].iobase - 0x800, 32);
- release_region(cards[cardnr].iobase - 0x400, 32);
- }
-
- Sfree((void *) sp);
-}
-
-void
-teles_shiftcards(int idx)
-{
- int i;
-
- for (i = idx; i < 15; i++)
- memcpy(&cards[i],&cards[i+1],sizeof(cards[i]));
-}
-
-int
-teles_inithardware(void)
-{
- int foundcards = 0;
- int i = 0;
-
- while (i < nrcards) {
- if (!cards[i].protocol)
- break;
- switch (checkcard(i)) {
- case (0):
- initcard(i);
- if (get_irq(i)) {
- closecard(i);
- teles_shiftcards(i);
- } else {
- foundcards++;
- i++;
- }
- break;
- case (-1):
- teles_shiftcards(i);
- break;
- case (-2):
- release_region(cards[i].iobase, 8);
- printk(KERN_WARNING "NO Teles card found at 0x%x!\n", cards[i].iobase);
- teles_shiftcards(i);
- break;
- }
- }
- return foundcards;
-}
-
-void
-teles_closehardware(void)
-{
- int i;
-
- for (i = 0; i < nrcards; i++)
- if (cards[i].sp) {
- release_irq(i);
- closecard(i);
- }
-}
-
-static void
-hscx_l2l1(struct PStack *st, int pr,
- struct BufHeader *ibh)
-{
- struct IsdnCardState *sp = (struct IsdnCardState *)
- st->l1.hardware;
- struct HscxState *hsp = sp->hs + st->l1.hscx;
- long flags;
-
- switch (pr) {
- case (PH_DATA):
- save_flags(flags);
- cli();
- if (hsp->xmtibh) {
- BufQueueLink(&hsp->sq, ibh);
- restore_flags(flags);
- }
- else {
- restore_flags(flags);
- hsp->xmtibh = ibh;
- hsp->sendptr = 0;
- hsp->releasebuf = !0;
- hscx_fill_fifo(hsp);
- }
- break;
- case (PH_DATA_PULLED):
- if (hsp->xmtibh) {
- printk(KERN_DEBUG "hscx_l2l1: this shouldn't happen\n");
- break;
- }
- hsp->xmtibh = ibh;
- hsp->sendptr = 0;
- hsp->releasebuf = 0;
- hscx_fill_fifo(hsp);
- break;
- case (PH_REQUEST_PULL):
- if (!hsp->xmtibh) {
- st->l1.requestpull = 0;
- st->l1.l1l2(st, PH_PULL_ACK, NULL);
- } else
- st->l1.requestpull = !0;
- break;
- }
-
-}
-
-extern struct IsdnBuffers *tracebuf;
-
-static void
-hscx_l2l1discardq(struct PStack *st, int pr, void *heldby,
- int releasetoo)
-{
- struct IsdnCardState *sp = (struct IsdnCardState *)
- st->l1.hardware;
- struct HscxState *hsp = sp->hs + st->l1.hscx;
-
-#ifdef DEBUG_MAGIC
- if (hsp->magic != 301270) {
- printk(KERN_DEBUG "hscx_discardq magic not 301270\n");
- return;
- }
-#endif
-
- BufQueueDiscard(&hsp->sq, pr, heldby, releasetoo);
-}
-
-static int
-open_hscxstate(struct IsdnCardState *sp,
- int hscx)
-{
- struct HscxState *hsp = sp->hs + hscx;
-
- if (!hsp->init) {
- BufPoolInit(&hsp->sbufpool, HSCX_SBUF_ORDER, HSCX_SBUF_BPPS,
- HSCX_SBUF_MAXPAGES);
- BufPoolInit(&hsp->rbufpool, HSCX_RBUF_ORDER, HSCX_RBUF_BPPS,
- HSCX_RBUF_MAXPAGES);
- BufPoolInit(&hsp->smallpool, HSCX_SMALLBUF_ORDER, HSCX_SMALLBUF_BPPS,
- HSCX_SMALLBUF_MAXPAGES);
- }
- hsp->init = !0;
-
- BufQueueInit(&hsp->rq);
- BufQueueInit(&hsp->sq);
-
- hsp->releasebuf = 0;
- hsp->rcvibh = NULL;
- hsp->xmtibh = NULL;
- hsp->rcvptr = 0;
- hsp->sendptr = 0;
- hsp->event = 0;
- return (0);
-}
-
-static void
-hscx_manl1(struct PStack *st, int pr,
- void *arg)
-{
- struct IsdnCardState *sp = (struct IsdnCardState *)
- st->l1.hardware;
- struct HscxState *hsp = sp->hs + st->l1.hscx;
-
- switch (pr) {
- case (PH_ACTIVATE):
- hsp->active = !0;
- modehscx(hsp, st->l1.hscxmode, st->l1.hscxchannel);
- st->l1.l1man(st, PH_ACTIVATE, NULL);
- break;
- case (PH_DEACTIVATE):
- if (!hsp->xmtibh)
- modehscx(hsp, 0, 0);
-
- hsp->active = 0;
- break;
- }
-}
-
-int
-setstack_hscx(struct PStack *st, struct HscxState *hs)
-{
- if (open_hscxstate(st->l1.hardware, hs->hscx))
- return (-1);
-
- st->l1.hscx = hs->hscx;
- st->l2.l2l1 = hscx_l2l1;
- st->ma.manl1 = hscx_manl1;
- st->l2.l2l1discardq = hscx_l2l1discardq;
-
- st->l1.sbufpool = &hs->sbufpool;
- st->l1.rbufpool = &hs->rbufpool;
- st->l1.smallpool = &hs->smallpool;
- st->l1.act_state = 0;
- st->l1.requestpull = 0;
-
- hs->st = st;
- return (0);
-}
-
-void
-teles_reportcard(int cardnr)
-{
- printk(KERN_DEBUG "teles_reportcard\n");
-}
+++ /dev/null
-/* $Id: config.c,v 1.1 1996/04/13 10:23:11 fritz Exp $
- *
- * $Log: config.c,v $
- * Revision 1.1 1996/04/13 10:23:11 fritz
- * Initial revision
- *
- *
- */
-#define __NO_VERSION__
-#include <linux/types.h>
-#include <linux/stddef.h>
-#include <linux/timer.h>
-#include "teles.h"
-
-/*
- * This structure array contains one entry per card. An entry looks
- * like this:
- *
- * { membase,irq,portbase,protocol,NULL }
- *
- * protocol can be either ISDN_PTYPE_EURO or ISDN_PTYPE_1TR6
- *
- * Cards which don't have an io port (Teles 8 bit cards for
- * example) can be entered with io port 0x0
- *
- * For the Teles 16.3, membase has to be set to 0.
- *
- */
-
-struct IsdnCard cards[] =
-{
- {(byte *) 0xd0000, 15, 0xd80, ISDN_PTYPE_EURO, NULL}, /* example */
- {NULL, 0, 0, 0, NULL},
- {NULL, 0, 0, 0, NULL},
- {NULL, 0, 0, 0, NULL},
- {NULL, 0, 0, 0, NULL},
- {NULL, 0, 0, 0, NULL},
- {NULL, 0, 0, 0, NULL},
- {NULL, 0, 0, 0, NULL},
- {NULL, 0, 0, 0, NULL},
- {NULL, 0, 0, 0, NULL},
- {NULL, 0, 0, 0, NULL},
- {NULL, 0, 0, 0, NULL},
- {NULL, 0, 0, 0, NULL},
- {NULL, 0, 0, 0, NULL},
- {NULL, 0, 0, 0, NULL},
- {NULL, 0, 0, 0, NULL},
-};
+++ /dev/null
-/* $Id: fsm.c,v 1.3 1997/02/16 01:04:12 fritz Exp $
- *
- * $Log: fsm.c,v $
- * Revision 1.3 1997/02/16 01:04:12 fritz
- * Bugfix: Changed timer handling caused hang with 2.1.X
- *
- * Revision 1.2 1996/04/29 22:49:57 fritz
- * Removed compatibility-macros.
- *
- * Revision 1.1 1996/04/13 10:23:41 fritz
- * Initial revision
- *
- *
- */
-#define __NO_VERSION__
-#include "teles.h"
-
-void
-FsmNew(struct Fsm *fsm,
- struct FsmNode *fnlist, int fncount)
-{
- int i;
-
- fsm->jumpmatrix = (int *) Smalloc(4L * fsm->state_count * fsm->event_count,
- GFP_KERNEL, "Fsm jumpmatrix");
- memset(fsm->jumpmatrix, 0, 4L * fsm->state_count * fsm->event_count);
-
- for (i = 0; i < fncount; i++)
- fsm->jumpmatrix[fsm->state_count * fnlist[i].event +
- fnlist[i].state] = (int) fnlist[i].routine;
-}
-
-void
-FsmFree(struct Fsm *fsm)
-{
- Sfree((void *) fsm->jumpmatrix);
-}
-
-int
-FsmEvent(struct FsmInst *fi, int event, void *arg)
-{
- void (*r) (struct FsmInst *, int, void *);
- char str[80];
-
- r = (void (*)) fi->fsm->jumpmatrix[fi->fsm->state_count * event + fi->state];
- if (r) {
- if (fi->debug) {
- sprintf(str, "State %s Event %s",
- fi->fsm->strState[fi->state],
- fi->fsm->strEvent[event]);
- fi->printdebug(fi, str);
- }
- r(fi, event, arg);
- return (0);
- } else {
- if (fi->debug) {
- sprintf(str, "State %s Event %s no routine",
- fi->fsm->strState[fi->state],
- fi->fsm->strEvent[event]);
- fi->printdebug(fi, str);
- }
- return (!0);
- }
-}
-
-void
-FsmChangeState(struct FsmInst *fi, int newstate)
-{
- char str[80];
-
- fi->state = newstate;
- if (fi->debug) {
- sprintf(str, "ChangeState %s",
- fi->fsm->strState[newstate]);
- fi->printdebug(fi, str);
- }
-}
-
-static void
-FsmExpireTimer(struct FsmTimer *ft)
-{
- FsmEvent(ft->fi, ft->event, ft->arg);
-}
-
-void
-FsmInitTimer(struct FsmInst *fi, struct FsmTimer *ft)
-{
- ft->fi = fi;
- ft->tl.function = (void *) FsmExpireTimer;
- ft->tl.data = (long) ft;
- init_timer(&ft->tl);
-}
-
-void
-FsmDelTimer(struct FsmTimer *ft, int where)
-{
-#if 0
- if (ft->fi->debug) {
- sprintf(str, "FsmDelTimer %lx %d", ft, where);
- ft->fi->printdebug(ft->fi, str);
- }
-#endif
-
- del_timer(&ft->tl);
-}
-
-int
-FsmAddTimer(struct FsmTimer *ft,
- int millisec, int event, void *arg, int where)
-{
-
-#if 0
- if (ft->fi->debug) {
- sprintf(str, "FsmAddTimer %lx %d %d", ft, millisec, where);
- ft->fi->printdebug(ft->fi, str);
- }
-#endif
-
- if (ft->tl.next || ft->tl.prev) {
- printk(KERN_WARNING "FsmAddTimer: timer already active!\n");
- return -1;
- }
- init_timer(&ft->tl);
- ft->event = event;
- ft->arg = arg;
- ft->tl.expires = jiffies + (millisec * HZ) / 1000;
- add_timer(&ft->tl);
- return 0;
-}
-
-int
-FsmTimerRunning(struct FsmTimer *ft)
-{
- return (ft->tl.next != NULL);
-}
-
-void
-jiftime(char *s, long mark)
-{
- s += 8;
-
- *s-- = '\0';
- *s-- = mark % 10 + '0';
- mark /= 10;
- *s-- = mark % 10 + '0';
- mark /= 10;
- *s-- = '.';
- *s-- = mark % 10 + '0';
- mark /= 10;
- *s-- = mark % 6 + '0';
- mark /= 6;
- *s-- = ':';
- *s-- = mark % 10 + '0';
- mark /= 10;
- *s-- = mark % 10 + '0';
-}
+++ /dev/null
-/* $Id: isdnl2.c,v 1.3 1996/11/23 11:32:57 keil Exp $
- *
- * $Log: isdnl2.c,v $
- * Revision 1.3 1996/11/23 11:32:57 keil
- * X.75 bugfixies; Thanks to Martin Maurer
- *
- * Revision 1.2 1996/05/17 03:46:15 fritz
- * General cleanup.
- *
- * Revision 1.1 1996/04/13 10:24:16 fritz
- * Initial revision
- *
- *
- */
-#define __NO_VERSION__
-#include "teles.h"
-
-#define TIMER_1 2000
-
-static void l2m_debug(struct FsmInst *fi, char *s);
-
-struct Fsm l2fsm =
-{NULL, 0, 0};
-
-enum {
- ST_L2_1,
- ST_L2_3,
- ST_L2_4,
- ST_L2_5,
- ST_L2_6,
- ST_L2_7,
- ST_L2_8,
-};
-
-#define L2_STATE_COUNT (ST_L2_8+1)
-
-static char *strL2State[] =
-{
- "ST_L2_1",
- "ST_L2_3",
- "ST_L2_4",
- "ST_L2_5",
- "ST_L2_6",
- "ST_L2_7",
- "ST_L2_8",
-};
-
-enum {
- EV_L2_UI,
- EV_L2_SABMX,
- EV_L2_UA,
- EV_L2_DISC,
- EV_L2_I,
- EV_L2_RR,
- EV_L2_REJ,
- EV_L2_FRMR,
- EV_L2_DL_DATA,
- EV_L2_DL_ESTABLISH,
- EV_L2_MDL_ASSIGN,
- EV_L2_DL_UNIT_DATA,
- EV_L2_DL_RELEASE,
- EV_L2_MDL_NOTEIPROC,
- EV_L2_T200,
- EV_L2_ACK_PULL,
- EV_L2_T203,
- EV_L2_RNR,
-};
-
-#define L2_EVENT_COUNT (EV_L2_RNR+1)
-
-static char *strL2Event[] =
-{
- "EV_L2_UI",
- "EV_L2_SABMX",
- "EV_L2_UA",
- "EV_L2_DISC",
- "EV_L2_I",
- "EV_L2_RR",
- "EV_L2_REJ",
- "EV_L2_FRMR",
- "EV_L2_DL_DATA",
- "EV_L2_DL_ESTABLISH",
- "EV_L2_MDL_ASSIGN",
- "EV_L2_DL_UNIT_DATA",
- "EV_L2_DL_RELEASE",
- "EV_L2_MDL_NOTEIPROC",
- "EV_L2_T200",
- "EV_L2_ACK_PULL",
- "EV_L2_T203",
- "EV_L2_RNR",
-};
-
-int errcount = 0;
-
-static int l2addrsize(struct Layer2 *tsp);
-
-static int
-cansend(struct PStack *st)
-{
- int p1;
-
- p1 = (st->l2.va + st->l2.window) % (st->l2.extended ? 128 : 8);
- return (st->l2.vs != p1);
-}
-
-static void
-discard_i_queue(struct PStack *st)
-{
- struct BufHeader *ibh;
-
- while (!BufQueueUnlink(&ibh, &st->l2.i_queue))
- BufPoolRelease(ibh);
-}
-
-int
-l2headersize(struct Layer2 *tsp, int UI)
-{
- return ((tsp->extended && (!UI) ? 2 : 1) + (tsp->laptype == LAPD ? 2 : 1));
-}
-
-int
-l2addrsize(struct Layer2 *tsp)
-{
- return (tsp->laptype == LAPD ? 2 : 1);
-}
-
-static int
-sethdraddr(struct Layer2 *tsp,
- struct BufHeader *ibh, int rsp)
-{
- byte *ptr = DATAPTR(ibh);
- int crbit;
-
- if (tsp->laptype == LAPD) {
- crbit = rsp;
- if (!tsp->orig)
- crbit = !crbit;
- *ptr++ = (tsp->sap << 2) | (crbit ? 2 : 0);
- *ptr++ = (tsp->tei << 1) | 1;
- return (2);
- } else {
- crbit = rsp;
- if (tsp->orig)
- crbit = !crbit;
- if (crbit)
- *ptr++ = 1;
- else
- *ptr++ = 3;
- return (1);
- }
-}
-
-static void
-enqueue_ui(struct PStack *st,
- struct BufHeader *ibh)
-{
- st->l2.l2l1(st, PH_DATA, ibh);
-}
-
-static void
-enqueue_super(struct PStack *st,
- struct BufHeader *ibh)
-{
- st->l2.l2l1(st, PH_DATA, ibh);
-}
-
-static int
-legalnr(struct PStack *st, int nr)
-{
- struct Layer2 *l2 = &st->l2;
- int lnr, lvs;
-
- lvs = (l2->vs >= l2->va) ? l2->vs : (l2->vs + l2->extended ? 128 : 8);
- lnr = (nr >= l2->va) ? nr : (nr + l2->extended ? 128 : 8);
- return (lnr <= lvs);
-}
-
-static void
-setva(struct PStack *st, int nr)
-{
- struct Layer2 *l2 = &st->l2;
-
- if (l2->va != nr) {
- while (l2->va != nr) {
- l2->va = (l2->va + 1) % (l2->extended ? 128 : 8);
- BufPoolRelease(l2->windowar[l2->sow]);
- l2->sow = (l2->sow + 1) % l2->window;
- }
- if (st->l4.l2writewakeup)
- st->l4.l2writewakeup(st);
- }
-}
-
-static void
-l2s1(struct FsmInst *fi, int event, void *arg)
-{
- struct PStack *st = fi->userdata;
-
- st->l2.l2tei(st, MDL_ASSIGN, (void *)st->l2.ces);
- FsmChangeState(fi, ST_L2_3);
-}
-
-static void
-l2s2(struct FsmInst *fi, int event, void *arg)
-{
- struct PStack *st = fi->userdata;
- struct BufHeader *ibh = arg;
-
- byte *ptr;
- int i;
-
- i = sethdraddr(&(st->l2), ibh, 0);
- ptr = DATAPTR(ibh);
- ptr += i;
- *ptr = 0x3;
-
- enqueue_ui(st, ibh);
-}
-
-static void
-l2s3(struct FsmInst *fi, int event, void *arg)
-{
- struct PStack *st = fi->userdata;
- struct BufHeader *ibh = arg;
-
- st->l2.l2l3(st, DL_UNIT_DATA, ibh);
-}
-
-static void
-establishlink(struct FsmInst *fi)
-{
- struct PStack *st = fi->userdata;
- struct BufHeader *ibh;
- int i;
- byte *ptr;
-
- FsmChangeState(fi, ST_L2_5);
- st->l2.rc = 0;
-
- if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 1))
- if (st->l2.l2m.debug)
- l2m_debug(&st->l2.l2m, "FAT 1");
-
-
- if (BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 15))
- return;
- i = sethdraddr(&st->l2, ibh, 0);
- ptr = DATAPTR(ibh);
- ptr += i;
- if (st->l2.extended)
- *ptr = 0x7f;
- else
- *ptr = 0x3f;
- ibh->datasize = i + 1;
-
- enqueue_super(st, ibh);
-}
-
-static void
-l2s11(struct FsmInst *fi, int event, void *arg)
-{
- establishlink(fi);
-}
-
-static void
-l2s13(struct FsmInst *fi, int event, void *arg)
-{
- struct PStack *st = fi->userdata;
- struct Channel *chanp = st->l4.userdata;
- byte *ptr;
- struct BufHeader *ibh;
- int i;
-
- FsmChangeState(fi, ST_L2_6);
-
- FsmDelTimer(&st->l2.t203_timer, 1);
- if (st->l2.t200_running) {
- FsmDelTimer(&st->l2.t200_timer, 2);
- st->l2.t200_running = 0;
- }
- st->l2.rc = 0;
- if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 2))
- if (st->l2.l2m.debug)
- l2m_debug(&st->l2.l2m, "FAT 2");
-
-
- if ((chanp->impair == 2) && (st->l2.laptype == LAPB))
- goto nodisc;
-
- if (BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 9))
- return;
- i = sethdraddr(&(st->l2), ibh, 0);
- ptr = DATAPTR(ibh);
- ptr += i;
- *ptr = 0x53;
- ibh->datasize = i + 1;
- enqueue_super(st, ibh);
-
- nodisc:
- discard_i_queue(st);
-}
-
-static void
-l2s12(struct FsmInst *fi, int event, void *arg)
-{
- struct PStack *st = fi->userdata;
- struct BufHeader *ibh = arg;
- byte *ptr;
- int i;
-
- BufPoolRelease(ibh);
- st->l2.vs = 0;
- st->l2.va = 0;
- st->l2.vr = 0;
- st->l2.sow = 0;
- FsmChangeState(fi, ST_L2_7);
- if (FsmAddTimer(&st->l2.t203_timer, st->l2.t203, EV_L2_T203, NULL, 3))
- if (st->l2.l2m.debug)
- l2m_debug(&st->l2.l2m, "FAT 3");
-
- st->l2.l2man(st, DL_ESTABLISH, NULL);
-
- if (BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 10))
- return;
- i = sethdraddr(&(st->l2), ibh, !0);
- ptr = DATAPTR(ibh);
- ptr += i;
- *ptr = 0x73;
- ibh->datasize = i + 1;
- enqueue_super(st, ibh);
-
-}
-
-static void
-l2s14(struct FsmInst *fi, int event, void *arg)
-{
- struct PStack *st = fi->userdata;
- struct BufHeader *ibh = arg;
- struct Channel *chanp = st->l4.userdata;
- byte *ptr;
- int i, p;
-
- ptr = DATAPTR(ibh);
- ptr += l2addrsize(&(st->l2));
- p = (*ptr) & 0x10;
- BufPoolRelease(ibh);
-
- FsmChangeState(fi, ST_L2_4);
-
- FsmDelTimer(&st->l2.t203_timer, 3);
- if (st->l2.t200_running) {
- FsmDelTimer(&st->l2.t200_timer, 4);
- st->l2.t200_running = 0;
- }
- if ((chanp->impair == 1) && (st->l2.laptype == LAPB))
- goto noresponse;
-
- if (BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 11))
- return;
- i = sethdraddr(&(st->l2), ibh, 0);
- ptr = DATAPTR(ibh);
- ptr += i;
- *ptr = 0x63 | (p ? 0x10 : 0x0);
- ibh->datasize = i + 1;
- enqueue_super(st, ibh);
-
- noresponse:
- st->l2.l2man(st, DL_RELEASE, NULL);
-
-}
-
-static void
-l2s5(struct FsmInst *fi, int event, void *arg)
-{
- struct PStack *st = fi->userdata;
- struct BufHeader *ibh = arg;
- int f;
- byte *data;
-
- data = DATAPTR(ibh);
- data += l2addrsize(&(st->l2));
-
- f = *data & 0x10;
- BufPoolRelease(ibh);
-
- if (f) {
- st->l2.vs = 0;
- st->l2.va = 0;
- st->l2.vr = 0;
- st->l2.sow = 0;
- FsmChangeState(fi, ST_L2_7);
-
- FsmDelTimer(&st->l2.t200_timer, 5);
- if (FsmAddTimer(&st->l2.t203_timer, st->l2.t203, EV_L2_T203, NULL, 4))
- if (st->l2.l2m.debug)
- l2m_debug(&st->l2.l2m, "FAT 4");
-
-
- st->l2.l2man(st, DL_ESTABLISH, NULL);
- }
-}
-
-static void
-l2s15(struct FsmInst *fi, int event, void *arg)
-{
- struct PStack *st = fi->userdata;
- struct BufHeader *ibh = arg;
- int f;
- byte *data;
-
- data = DATAPTR(ibh);
- data += l2addrsize(&st->l2);
-
- f = *data & 0x10;
- BufPoolRelease(ibh);
-
- if (f) {
- FsmDelTimer(&st->l2.t200_timer, 6);
- FsmChangeState(fi, ST_L2_4);
- st->l2.l2man(st, DL_RELEASE, NULL);
- }
-}
-
-static void
-l2s6(struct FsmInst *fi, int event, void *arg)
-{
- struct PStack *st = fi->userdata;
- struct Channel *chanp = st->l4.userdata;
- struct BufHeader *ibh = arg;
- int p, i, seq, rsp;
- byte *ptr;
- struct Layer2 *l2;
-
- l2 = &st->l2;
- ptr = DATAPTR(ibh);
-
- if (l2->laptype == LAPD) {
- rsp = ptr[0] & 0x2;
- if (l2->orig)
- rsp = !rsp;
- } else {
- rsp = ptr[0] == 0x3;
- if (l2->orig)
- rsp = !rsp;
- }
-
- ptr += l2addrsize(l2);
-
- if (l2->extended) {
- p = (ptr[1] & 0x1) == 0x1;
- seq = ptr[1] >> 1;
- } else {
- p = (ptr[0] & 0x10);
- seq = (ptr[0] >> 5) & 0x7;
- }
- BufPoolRelease(ibh);
-
- if ((chanp->impair == 4) && (st->l2.laptype == LAPB))
- goto noresp;
-
- if ((!rsp) && p) {
- if (!BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 12)) {
- i = sethdraddr(l2, ibh, !0);
- ptr = DATAPTR(ibh);
- ptr += i;
-
- if (l2->extended) {
- *ptr++ = 0x1;
- *ptr++ = (l2->vr << 1) | (p ? 1 : 0);
- i += 2;
- } else {
- *ptr++ = (l2->vr << 5) | 0x1 | (p ? 0x10 : 0x0);
- i += 1;
- }
- ibh->datasize = i;
- enqueue_super(st, ibh);
- }
- }
- noresp:
- if (legalnr(st, seq))
- if (seq == st->l2.vs) {
- setva(st, seq);
- FsmDelTimer(&st->l2.t200_timer, 7);
- st->l2.t200_running = 0;
- FsmDelTimer(&st->l2.t203_timer, 8);
- if (FsmAddTimer(&st->l2.t203_timer, st->l2.t203, EV_L2_T203, NULL, 5))
- if (st->l2.l2m.debug)
- l2m_debug(&st->l2.l2m, "FAT 5");
-
- if (st->l2.i_queue.head)
- st->l2.l2l1(st, PH_REQUEST_PULL, NULL);
- } else if (st->l2.va != seq) {
- setva(st, seq);
- FsmDelTimer(&st->l2.t200_timer, 9);
- if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 6))
- if (st->l2.l2m.debug)
- l2m_debug(&st->l2.l2m, "FAT 6");
-
- if (st->l2.i_queue.head)
- st->l2.l2l1(st, PH_REQUEST_PULL, NULL);
- }
-}
-
-static void
-l2s7(struct FsmInst *fi, int event, void *arg)
-{
- struct PStack *st = fi->userdata;
- struct BufHeader *ibh = arg;
- int i;
- byte *ptr;
- struct IsdnCardState *sp = st->l1.hardware;
- char str[64];
-
- i = sethdraddr(&st->l2, ibh, 0);
- ptr = DATAPTR(ibh);
-
- if (st->l2.laptype == LAPD)
- if (sp->dlogflag) {
- sprintf(str, "Q.931 frame user->network tei %d", st->l2.tei);
- dlogframe(sp, ptr + st->l2.ihsize, ibh->datasize - st->l2.ihsize,
- str);
- }
- BufQueueLink(&st->l2.i_queue, ibh);
-
- st->l2.l2l1(st, PH_REQUEST_PULL, NULL);
-}
-
-static void
-l2s8(struct FsmInst *fi, int event, void *arg)
-{
- struct PStack *st = fi->userdata;
- struct Channel *chanp = st->l4.userdata;
- struct BufHeader *ibh = arg;
- byte *ptr;
- struct BufHeader *ibh2;
- struct IsdnCardState *sp = st->l1.hardware;
- struct Layer2 *l2 = &(st->l2);
- int i, p, seq, nr, wasok;
- char str[64];
-
- ptr = DATAPTR(ibh);
- ptr += l2addrsize(l2);
- if (l2->extended) {
- p = (ptr[1] & 0x1) == 0x1;
- seq = ptr[0] >> 1;
- nr = (ptr[1] >> 1) & 0x7f;
- } else {
- p = (ptr[0] & 0x10);
- seq = (ptr[0] >> 1) & 0x7;
- nr = (ptr[0] >> 5) & 0x7;
- }
-
- if (l2->vr == seq) {
- wasok = !0;
-
- l2->vr = (l2->vr + 1) % (l2->extended ? 128 : 8);
- l2->rejexp = 0;
-
- ptr = DATAPTR(ibh);
- if (st->l2.laptype == LAPD)
- if (sp->dlogflag) {
- sprintf(str, "Q.931 frame network->user tei %d", st->l2.tei);
- dlogframe(st->l1.hardware, ptr + l2->ihsize,
- ibh->datasize - l2->ihsize, str);
- }
- label8_1:
- if ((chanp->impair == 3) && (st->l2.laptype == LAPB))
- goto noRR;
-
- if (!BufPoolGet(&ibh2, st->l1.smallpool, GFP_ATOMIC, (void *) st, 13)) {
- i = sethdraddr(&(st->l2), ibh2, !0);
- ptr = DATAPTR(ibh2);
- ptr += i;
-
- if (l2->extended) {
- *ptr++ = 0x1;
- *ptr++ = (l2->vr << 1) | (p ? 1 : 0);
- i += 2;
- } else {
- *ptr++ = (l2->vr << 5) | 0x1 | (p ? 0x10 : 0x0);
- i += 1;
- }
- ibh2->datasize = i;
- enqueue_super(st, ibh2);
- noRR:
- }
- } else {
- /* n(s)!=v(r) */
- wasok = 0;
- BufPoolRelease(ibh);
- if (st->l2.rejexp) {
- if (p)
- goto label8_1;
- } else {
- st->l2.rejexp = !0;
- if (!BufPoolGet(&ibh2, st->l1.smallpool, GFP_ATOMIC, (void *) st, 14)) {
- i = sethdraddr(&(st->l2), ibh2, p);
- ptr = DATAPTR(ibh2);
- ptr += i;
-
- if (l2->extended) {
- *ptr++ = 0x9;
- *ptr++ = (l2->vr << 1) | (p ? 1 : 0);
- i += 2;
- } else {
- *ptr++ = (l2->vr << 5) | 0x9 | (p ? 0x10 : 0x0);
- i += 1;
- }
- ibh2->datasize = i;
- enqueue_super(st, ibh2);
- }
- }
- }
-
- if (legalnr(st, nr))
- if (nr == st->l2.vs) {
- setva(st, nr);
- FsmDelTimer(&st->l2.t200_timer, 10);
- st->l2.t200_running = 0;
- FsmDelTimer(&st->l2.t203_timer, 11);
- if (FsmAddTimer(&st->l2.t203_timer, st->l2.t203, EV_L2_T203, NULL, 7))
- if (st->l2.l2m.debug)
- l2m_debug(&st->l2.l2m, "FAT 5");
-
- if (st->l2.i_queue.head)
- st->l2.l2l1(st, PH_REQUEST_PULL, NULL);
- } else if (nr != st->l2.va) {
- setva(st, nr);
- FsmDelTimer(&st->l2.t200_timer, 12);
- if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 8))
- if (st->l2.l2m.debug)
- l2m_debug(&st->l2.l2m, "FAT 6");
-
- if (st->l2.i_queue.head)
- st->l2.l2l1(st, PH_REQUEST_PULL, NULL);
- }
- if (wasok)
- st->l2.l2l3(st, DL_DATA, ibh);
-
-}
-
-static void
-l2s17(struct FsmInst *fi, int event, void *arg)
-{
- struct PStack *st = fi->userdata;
-
- st->l2.tei = (int) arg;
- establishlink(fi);
-}
-
-static void
-enquiry_response(struct PStack *st)
-{
- struct BufHeader *ibh2;
- int i;
- byte *ptr;
- struct Layer2 *l2;
-
- l2 = &st->l2;
- if (!BufPoolGet(&ibh2, st->l1.smallpool, GFP_ATOMIC, (void *) st, 16)) {
- i = sethdraddr(&(st->l2), ibh2, !0);
- ptr = DATAPTR(ibh2);
- ptr += i;
-
- if (l2->extended) {
- *ptr++ = 0x1;
- *ptr++ = (l2->vr << 1) | 0x1;
- i += 2;
- } else {
- *ptr++ = (l2->vr << 5) | 0x1 | 0x10;
- i += 1;
- }
- ibh2->datasize = i;
- enqueue_super(st, ibh2);
- }
-}
-
-static void
-invoke_retransmission(struct PStack *st, int nr)
-{
- struct Layer2 *l2 = &st->l2;
- int p1;
-
- if (l2->vs != nr) {
- while (l2->vs != nr) {
-
- l2->vs = l2->vs - 1;
- if (l2->vs < 0)
- l2->vs += l2->extended ? 128 : 8;
-
- p1 = l2->vs - l2->va;
- if (p1 < 0)
- p1 += l2->extended ? 128 : 8;
- p1 = (p1 + l2->sow) % l2->window;
-
- BufQueueLinkFront(&l2->i_queue, l2->windowar[p1]);
- }
- st->l2.l2l1(st, PH_REQUEST_PULL, NULL);
- }
-}
-
-static void
-l2s16(struct FsmInst *fi, int event, void *arg)
-{
- struct PStack *st = fi->userdata;
- struct BufHeader *ibh = arg;
- int p, seq, rsp;
- byte *ptr;
- struct Layer2 *l2;
-
- l2 = &(st->l2);
- ptr = DATAPTR(ibh);
-
- if (l2->laptype == LAPD) {
- rsp = ptr[0] & 0x2;
- if (l2->orig)
- rsp = !rsp;
- } else {
- rsp = ptr[0] == 0x3;
- if (l2->orig)
- rsp = !rsp;
- }
-
-
- ptr += l2addrsize(l2);
-
- if (l2->extended) {
- p = (ptr[1] & 0x1) == 0x1;
- seq = ptr[1] >> 1;
- } else {
- p = (ptr[0] & 0x10);
- seq = (ptr[0] >> 5) & 0x7;
- }
- BufPoolRelease(ibh);
-
- if ((!rsp) && p)
- enquiry_response(st);
-
- if (!legalnr(st, seq))
- return;
-
- setva(st, seq);
- invoke_retransmission(st, seq);
-
-}
-
-static void
-l2s19(struct FsmInst *fi, int event, void *arg)
-{
- FsmChangeState(fi, ST_L2_4);
-}
-
-static void
-l2s20(struct FsmInst *fi, int event, void *arg)
-{
- struct PStack *st = fi->userdata;
- int i;
- struct BufHeader *ibh;
- byte *ptr;
-
- if (st->l2.rc == st->l2.n200) {
- FsmChangeState(fi, ST_L2_4);
- st->l2.l2man(st, DL_RELEASE, NULL);
- } else {
- st->l2.rc++;
-
- if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 9))
- if (st->l2.l2m.debug)
- l2m_debug(&st->l2.l2m, "FAT 7");
-
- if (BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 15))
- return;
-
- i = sethdraddr(&st->l2, ibh, 0);
- ptr = DATAPTR(ibh);
- ptr += i;
- if (st->l2.extended)
- *ptr = 0x7f;
- else
- *ptr = 0x3f;
- ibh->datasize = i + 1;
- enqueue_super(st, ibh);
- }
-}
-
-static void
-l2s21(struct FsmInst *fi, int event, void *arg)
-{
- struct PStack *st = fi->userdata;
- struct Channel *chanp = st->l4.userdata;
- int i;
- struct BufHeader *ibh;
- byte *ptr;
-
- if (st->l2.rc == st->l2.n200) {
- FsmChangeState(fi, ST_L2_4);
- st->l2.l2man(st, DL_RELEASE, NULL);
- } else {
- st->l2.rc++;
-
- if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 10))
- if (st->l2.l2m.debug)
- l2m_debug(&st->l2.l2m, "FAT 8");
-
-
- if ((chanp->impair == 2) && (st->l2.laptype == LAPB))
- goto nodisc;
-
- if (BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 15))
- return;
-
- i = sethdraddr(&st->l2, ibh, 0);
- ptr = DATAPTR(ibh);
- ptr += i;
- *ptr = 0x53;
- ibh->datasize = i + 1;
- enqueue_super(st, ibh);
- nodisc:
-
- }
-}
-
-static void
-l2s22(struct FsmInst *fi, int event, void *arg)
-{
- struct PStack *st = fi->userdata;
- struct BufHeader *ibh;
- struct Layer2 *l2 = &st->l2;
- byte *ptr;
- int p1;
-
- if (!cansend(st))
- return;
-
- if (BufQueueUnlink(&ibh, &l2->i_queue))
- return;
-
-
- p1 = l2->vs - l2->va;
- if (p1 < 0)
- p1 += l2->extended ? 128 : 8;
- p1 = (p1 + l2->sow) % l2->window;
- l2->windowar[p1] = ibh;
-
- ptr = DATAPTR(ibh);
- ptr += l2addrsize(l2);
-
- if (l2->extended) {
- *ptr++ = l2->vs << 1;
- *ptr++ = (l2->vr << 1) | 0x1;
- l2->vs = (l2->vs + 1) % 128;
- } else {
- *ptr++ = (l2->vr << 5) | (l2->vs << 1);
- l2->vs = (l2->vs + 1) % 8;
- }
-
- st->l2.l2l1(st, PH_DATA_PULLED, ibh);
-
- if (!st->l2.t200_running) {
- FsmDelTimer(&st->l2.t203_timer, 13);
- if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 11))
- if (st->l2.l2m.debug)
- l2m_debug(&st->l2.l2m, "FAT 9");
-
- st->l2.t200_running = !0;
- }
- if (l2->i_queue.head && cansend(st))
- st->l2.l2l1(st, PH_REQUEST_PULL, NULL);
-
-}
-
-static void
-transmit_enquiry(struct PStack *st)
-{
- struct BufHeader *ibh;
- byte *ptr;
-
- if (!BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 12)) {
- ptr = DATAPTR(ibh);
- ptr += sethdraddr(&st->l2, ibh, 0);
-
- if (st->l2.extended) {
- *ptr++ = 0x1;
- *ptr++ = (st->l2.vr << 1) | 1;
- } else {
- *ptr++ = (st->l2.vr << 5) | 0x11;
- }
- ibh->datasize = ptr - DATAPTR(ibh);
- enqueue_super(st, ibh);
- if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 12))
- if (st->l2.l2m.debug)
- l2m_debug(&st->l2.l2m, "FAT 10");
-
- st->l2.t200_running = !0;
- }
-}
-
-static void
-l2s23(struct FsmInst *fi, int event, void *arg)
-{
- struct PStack *st = fi->userdata;
-
- st->l2.t200_running = 0;
-
- st->l2.rc = 1;
- FsmChangeState(fi, ST_L2_8);
- transmit_enquiry(st);
-}
-
-static void
-l2s24(struct FsmInst *fi, int event, void *arg)
-{
- struct PStack *st = fi->userdata;
- struct BufHeader *ibh = arg;
- int p, seq, rsp;
- byte *ptr;
- struct Layer2 *l2;
-
- l2 = &st->l2;
- ptr = DATAPTR(ibh);
-
- if (l2->laptype == LAPD) {
- rsp = ptr[0] & 0x2;
- if (l2->orig)
- rsp = !rsp;
- } else {
- rsp = ptr[0] == 0x3;
- if (l2->orig)
- rsp = !rsp;
- }
-
-
- ptr += l2addrsize(l2);
-
- if (l2->extended) {
- p = (ptr[1] & 0x1) == 0x1;
- seq = ptr[1] >> 1;
- } else {
- p = (ptr[0] & 0x10);
- seq = (ptr[0] >> 5) & 0x7;
- }
- BufPoolRelease(ibh);
-
- if (rsp && p) {
- if (legalnr(st, seq)) {
- FsmChangeState(fi, ST_L2_7);
- setva(st, seq);
- if (st->l2.t200_running) {
- FsmDelTimer(&st->l2.t200_timer, 14);
- st->l2.t200_running = 0;
- }
- if (FsmAddTimer(&st->l2.t203_timer, st->l2.t203, EV_L2_T203, NULL, 13))
- if (st->l2.l2m.debug)
- l2m_debug(&st->l2.l2m, "FAT 11");
-
- invoke_retransmission(st, seq);
- }
- } else {
- if (!rsp && p)
- enquiry_response(st);
- if (legalnr(st, seq)) {
- setva(st, seq);
- }
- }
-}
-
-static void
-l2s25(struct FsmInst *fi, int event, void *arg)
-{
- struct PStack *st = fi->userdata;
-
- st->l2.rc = 0;
- FsmChangeState(fi, ST_L2_8);
- transmit_enquiry(st);
-}
-
-static void
-l2s26(struct FsmInst *fi, int event, void *arg)
-{
- struct PStack *st = fi->userdata;
-
- if (st->l2.rc == st->l2.n200) {
- l2s13(fi, event, NULL);
- } else {
- st->l2.rc++;
- transmit_enquiry(st);
- }
-}
-
-static void
-l2s27(struct FsmInst *fi, int event, void *arg)
-{
- struct PStack *st = fi->userdata;
- struct BufHeader *ibh = arg;
- byte *ptr;
- int i, p, est;
-
- ptr = DATAPTR(ibh);
- ptr += l2addrsize(&st->l2);
-
- if (st->l2.extended)
- p = ptr[1] & 0x1;
- else
- p = ptr[0] & 0x10;
-
- BufPoolRelease(ibh);
-
- if (BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 10))
- return;
- i = sethdraddr(&st->l2, ibh, 0);
- ptr = DATAPTR(ibh);
- ptr += i;
- *ptr = 0x63 | p;
- ibh->datasize = i + 1;
- enqueue_super(st, ibh);
-
- if (st->l2.vs != st->l2.va) {
- discard_i_queue(st);
- est = !0;
- } else
- est = 0;
-
- FsmDelTimer(&st->l2.t200_timer, 15);
- st->l2.t200_running = 0;
-
- if (FsmAddTimer(&st->l2.t203_timer, st->l2.t203, EV_L2_T203, NULL, 3))
- if (st->l2.l2m.debug)
- l2m_debug(&st->l2.l2m, "FAT 12");
-
- st->l2.vs = 0;
- st->l2.va = 0;
- st->l2.vr = 0;
- st->l2.sow = 0;
-
-
- if (est)
- st->l2.l2man(st, DL_ESTABLISH, NULL);
-
-}
-
-static void
-l2s28(struct FsmInst *fi, int event, void *arg)
-{
- struct PStack *st = fi->userdata;
- struct BufHeader *ibh = arg;
- byte *ptr;
- char tmp[64];
-
- ptr = DATAPTR(ibh);
- ptr += l2addrsize(&st->l2);
- ptr++;
-
- if (st->l2.l2m.debug) {
- if (st->l2.extended)
- sprintf(tmp, "FRMR information %2x %2x %2x %2x %2x",
- ptr[0], ptr[1], ptr[2], ptr[3], ptr[4]);
- else
- sprintf(tmp, "FRMR information %2x %2x %2x",
- ptr[0], ptr[1], ptr[2]);
-
- l2m_debug(&st->l2.l2m, tmp);
- }
- BufPoolRelease(ibh);
-}
-
-static int
-IsUI(byte * data, int ext)
-{
- return ((data[0] & 0xef) == 0x3);
-}
-
-static int
-IsUA(byte * data, int ext)
-{
- return ((data[0] & 0xef) == 0x63);
-}
-
-static int
-IsDISC(byte * data, int ext)
-{
- return ((data[0] & 0xef) == 0x43);
-}
-
-static int
-IsRR(byte * data, int ext)
-{
- if (ext)
- return (data[0] == 0x1);
- else
- return ((data[0] & 0xf) == 1);
-}
-
-static int
-IsI(byte * data, int ext)
-{
- return ((data[0] & 0x1) == 0x0);
-}
-
-static int
-IsSABMX(byte * data, int ext)
-{
- return (ext ? data[0] == 0x7f : data[0] == 0x3f);
-}
-
-static int
-IsREJ(byte * data, int ext)
-{
- return (ext ? data[0] == 0x9 : (data[0] & 0xf) == 0x9);
-}
-
-static int
-IsFRMR(byte * data, int ext)
-{
- return ((data[0] & 0xef) == 0x87);
-}
-
-static int
-IsRNR(byte * data, int ext)
-{
- if (ext)
- return (data[0] == 0x5);
- else
- return ((data[0] & 0xf) == 5);
-}
-
-static struct FsmNode L2FnList[] =
-{
- {ST_L2_1, EV_L2_DL_ESTABLISH, l2s1},
- {ST_L2_1, EV_L2_MDL_NOTEIPROC, l2s19},
- {ST_L2_3, EV_L2_MDL_ASSIGN, l2s17},
- {ST_L2_4, EV_L2_DL_UNIT_DATA, l2s2},
- {ST_L2_4, EV_L2_DL_ESTABLISH, l2s11},
- {ST_L2_7, EV_L2_DL_UNIT_DATA, l2s2},
- {ST_L2_7, EV_L2_DL_DATA, l2s7},
- {ST_L2_7, EV_L2_DL_RELEASE, l2s13},
- {ST_L2_7, EV_L2_ACK_PULL, l2s22},
- {ST_L2_8, EV_L2_DL_RELEASE, l2s13},
-
- {ST_L2_1, EV_L2_UI, l2s3},
- {ST_L2_4, EV_L2_UI, l2s3},
- {ST_L2_4, EV_L2_SABMX, l2s12},
- {ST_L2_5, EV_L2_UA, l2s5},
- {ST_L2_6, EV_L2_UA, l2s15},
- {ST_L2_7, EV_L2_UI, l2s3},
- {ST_L2_7, EV_L2_DISC, l2s14},
- {ST_L2_7, EV_L2_I, l2s8},
- {ST_L2_7, EV_L2_RR, l2s6},
- {ST_L2_7, EV_L2_REJ, l2s16},
- {ST_L2_7, EV_L2_SABMX, l2s27},
- {ST_L2_7, EV_L2_FRMR, l2s28},
- {ST_L2_8, EV_L2_RR, l2s24},
- {ST_L2_8, EV_L2_DISC, l2s14},
- {ST_L2_8, EV_L2_FRMR, l2s28},
-
- {ST_L2_5, EV_L2_T200, l2s20},
- {ST_L2_6, EV_L2_T200, l2s21},
- {ST_L2_7, EV_L2_T200, l2s23},
- {ST_L2_7, EV_L2_T203, l2s25},
- {ST_L2_8, EV_L2_T200, l2s26},
-};
-
-#define L2_FN_COUNT (sizeof(L2FnList)/sizeof(struct FsmNode))
-
-static void
-isdnl2_l1l2(struct PStack *st, int pr, struct BufHeader *arg)
-{
- struct BufHeader *ibh;
- byte *datap;
- int ret = !0;
-
- switch (pr) {
- case (PH_DATA):
-
- ibh = arg;
- datap = DATAPTR(ibh);
- datap += l2addrsize(&st->l2);
-
- if (IsI(datap, st->l2.extended))
- ret = FsmEvent(&st->l2.l2m, EV_L2_I, ibh);
- else if (IsRR(datap, st->l2.extended))
- ret = FsmEvent(&st->l2.l2m, EV_L2_RR, ibh);
- else if (IsUI(datap, st->l2.extended))
- ret = FsmEvent(&st->l2.l2m, EV_L2_UI, ibh);
- else if (IsSABMX(datap, st->l2.extended))
- ret = FsmEvent(&st->l2.l2m, EV_L2_SABMX, ibh);
- else if (IsUA(datap, st->l2.extended))
- ret = FsmEvent(&st->l2.l2m, EV_L2_UA, ibh);
- else if (IsDISC(datap, st->l2.extended))
- ret = FsmEvent(&st->l2.l2m, EV_L2_DISC, ibh);
- else if (IsREJ(datap, st->l2.extended))
- ret = FsmEvent(&st->l2.l2m, EV_L2_REJ, ibh);
- else if (IsFRMR(datap, st->l2.extended))
- ret = FsmEvent(&st->l2.l2m, EV_L2_FRMR, ibh);
- else if (IsRNR(datap, st->l2.extended))
- ret = FsmEvent(&st->l2.l2m, EV_L2_RNR, ibh);
-
- if (ret)
- BufPoolRelease(ibh);
-
- break;
- case (PH_PULL_ACK):
- FsmEvent(&st->l2.l2m, EV_L2_ACK_PULL, arg);
- break;
- }
-}
-
-static void
-isdnl2_l3l2(struct PStack *st, int pr,
- void *arg)
-{
- switch (pr) {
- case (DL_DATA):
- if (FsmEvent(&st->l2.l2m, EV_L2_DL_DATA, arg))
- BufPoolRelease((struct BufHeader *) arg);
- break;
- case (DL_UNIT_DATA):
- if (FsmEvent(&st->l2.l2m, EV_L2_DL_UNIT_DATA, arg))
- BufPoolRelease((struct BufHeader *) arg);
- break;
- }
-}
-
-static void
-isdnl2_manl2(struct PStack *st, int pr,
- void *arg)
-{
- switch (pr) {
- case (DL_ESTABLISH):
- FsmEvent(&st->l2.l2m, EV_L2_DL_ESTABLISH, arg);
- break;
- case (DL_RELEASE):
- FsmEvent(&st->l2.l2m, EV_L2_DL_RELEASE, arg);
- break;
- case (MDL_NOTEIPROC):
- FsmEvent(&st->l2.l2m, EV_L2_MDL_NOTEIPROC, NULL);
- break;
- }
-}
-
-static void
-isdnl2_teil2(struct PStack *st, int pr,
- void *arg)
-{
- switch (pr) {
- case (MDL_ASSIGN):
- FsmEvent(&st->l2.l2m, EV_L2_MDL_ASSIGN, arg);
- break;
- }
-}
-
-void
-releasestack_isdnl2(struct PStack *st)
-{
- FsmDelTimer(&st->l2.t200_timer, 15);
- FsmDelTimer(&st->l2.t203_timer, 16);
-}
-
-static void
-l2m_debug(struct FsmInst *fi, char *s)
-{
- struct PStack *st = fi->userdata;
- char tm[32], str[256];
-
- jiftime(tm, jiffies);
- sprintf(str, "%s %s %s\n", tm, st->l2.debug_id, s);
- teles_putstatus(str);
-}
-
-
-void
-setstack_isdnl2(struct PStack *st, char *debug_id)
-{
- st->l1.l1l2 = isdnl2_l1l2;
- st->l3.l3l2 = isdnl2_l3l2;
- st->ma.manl2 = isdnl2_manl2;
- st->ma.teil2 = isdnl2_teil2;
-
- st->l2.uihsize = l2headersize(&st->l2, !0);
- st->l2.ihsize = l2headersize(&st->l2, 0);
- BufQueueInit(&(st->l2.i_queue));
- st->l2.rejexp = 0;
- st->l2.debug = 1;
-
- st->l2.l2m.fsm = &l2fsm;
- st->l2.l2m.state = ST_L2_1;
- st->l2.l2m.debug = 0;
- st->l2.l2m.userdata = st;
- st->l2.l2m.printdebug = l2m_debug;
- strcpy(st->l2.debug_id, debug_id);
-
- FsmInitTimer(&st->l2.l2m, &st->l2.t200_timer);
- FsmInitTimer(&st->l2.l2m, &st->l2.t203_timer);
- st->l2.t200_running = 0;
-}
-
-void
-setstack_transl2(struct PStack *st)
-{
-}
-
-void
-releasestack_transl2(struct PStack *st)
-{
-}
-
-void
-Isdnl2New(void)
-{
- l2fsm.state_count = L2_STATE_COUNT;
- l2fsm.event_count = L2_EVENT_COUNT;
- l2fsm.strEvent = strL2Event;
- l2fsm.strState = strL2State;
- FsmNew(&l2fsm, L2FnList, L2_FN_COUNT);
-}
-
-void
-Isdnl2Free(void)
-{
- FsmFree(&l2fsm);
-}
+++ /dev/null
-/* $Id: isdnl3.c,v 1.13 1997/02/16 12:12:51 fritz Exp $
- *
- * $Log: isdnl3.c,v $
- * Revision 1.13 1997/02/16 12:12:51 fritz
- * Bugfix: SI2 was nont initialized on incoming calls.
- *
- * Revision 1.12 1997/02/11 01:39:20 keil
- * Changed setup-interface (incoming and outgoing)
- *
- * Revision 1.11 1996/09/29 19:41:58 fritz
- * Bugfix: ignore unknown frames.
- *
- * Revision 1.10 1996/09/25 18:32:43 keil
- * response for STATUS_ENQ message added
- *
- * Revision 1.9 1996/06/06 14:22:27 fritz
- * Changed level of "non-digital call..." message, since
- * with audio support, this is quite normal.
- *
- * Revision 1.8 1996/06/03 20:35:04 fritz
- * Fixed typos.
- *
- * Revision 1.7 1996/06/03 20:03:39 fritz
- * Fixed typos.
- *
- * Revision 1.6 1996/05/21 11:33:50 keil
- * Adding SETUP_ACKNOWLEDGE as answer of a SETUP message.
- *
- * Revision 1.5 1996/05/18 01:37:16 fritz
- * Added spelling corrections and some minor changes
- * to stay in sync with kernel.
- *
- * Revision 1.4 1996/05/17 03:46:16 fritz
- * General cleanup.
- *
- * Revision 1.3 1996/04/30 21:57:53 isdn4dev
- * remove some debugging code, improve callback Karsten Keil
- *
- * Revision 1.2 1996/04/20 16:45:05 fritz
- * Changed to report all incoming calls to Linklevel, not just those
- * with Service 7.
- * Misc. typos
- *
- * Revision 1.1 1996/04/13 10:24:45 fritz
- * Initial revision
- *
- *
- */
-#define __NO_VERSION__
-#define P_1TR6
-#include "teles.h"
-#include "l3_1TR6.h"
-#define DEBUG_1TR6 0
-
-static void
-i_down(struct PStack *st,
- struct BufHeader *ibh)
-{
- st->l3.l3l2(st, DL_DATA, ibh);
-}
-
-static void
-newl3state(struct PStack *st, int state)
-{
- st->l3.state = state;
- if (DEBUG_1TR6 > 4)
- printk(KERN_INFO "isdnl3: bc:%d cr:%x new state %d\n",
- st->pa->bchannel, st->pa->callref, state);
-
-}
-
-static void
-l3_message(struct PStack *st, int mt)
-{
- struct BufHeader *dibh;
- byte *p;
- int size;
-
- BufPoolGet(&dibh, st->l1.sbufpool, GFP_ATOMIC, (void *) st, 18);
- p = DATAPTR(dibh);
- p += st->l2.ihsize;
- size = st->l2.ihsize;
-
- *p++ = 0x8;
- *p++ = 0x1;
- *p++ = st->l3.callref;
- *p++ = mt;
- size += 4;
-
- dibh->datasize = size;
- i_down(st, dibh);
-}
-
-static void
-l3s3(struct PStack *st, byte pr, void *arg)
-{
- l3_message(st, MT_RELEASE);
- newl3state(st, 19);
-}
-
-static void
-l3s4(struct PStack *st, byte pr, void *arg)
-{
- struct BufHeader *ibh = arg;
-
- BufPoolRelease(ibh);
- newl3state(st, 0);
- st->l3.l3l4(st, CC_RELEASE_CNF, NULL);
-}
-
-static void
-l3s4_1(struct PStack *st, byte pr, void *arg)
-{
- struct BufHeader *ibh = arg;
-
- BufPoolRelease(ibh);
- newl3state(st, 19);
- l3_message(st, MT_RELEASE);
- st->l3.l3l4(st, CC_RELEASE_CNF, NULL);
-}
-
-static void
-l3s5(struct PStack *st, byte pr,
- void *arg)
-{
- struct BufHeader *dibh;
- byte *p;
- char *teln;
-
- st->l3.callref = st->pa->callref;
- BufPoolGet(&dibh, st->l1.sbufpool, GFP_ATOMIC, (void *) st, 19);
- p = DATAPTR(dibh);
- p += st->l2.ihsize;
-
- *p++ = 0x8;
- *p++ = 0x1;
- *p++ = st->l3.callref;
- *p++ = MT_SETUP;
- *p++ = 0xa1;
-
- /*
- * Set Bearer Capability, Map info from 1TR6-convention to EDSS1
- */
- switch (st->pa->setup.si1) {
- case 1: /* Telephony */
- *p++ = 0x4; /* BC-IE-code */
- *p++ = 0x3; /* Length */
- *p++ = 0x90; /* Coding Std. national, 3.1 kHz audio */
- *p++ = 0x90; /* Circuit-Mode 64kbps */
- *p++ = 0xa3; /* A-Law Audio */
- break;
- case 5: /* Datatransmission 64k, BTX */
- case 7: /* Datatransmission 64k */
- default:
- *p++ = 0x4; /* BC-IE-code */
- *p++ = 0x2; /* Length */
- *p++ = 0x88; /* Coding Std. nat., unrestr. dig. Inform. */
- *p++ = 0x90; /* Packet-Mode 64kbps */
- break;
- }
- /*
- * What about info2? Mapping to High-Layer-Compatibility?
- */
- if (st->pa->setup.eazmsn[0] != '\0') {
- *p++ = 0x6c;
- *p++ = strlen(st->pa->setup.eazmsn) + 1;
- /* Classify as AnyPref. */
- *p++ = 0x81; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
- teln = st->pa->setup.eazmsn;
- while (*teln)
- *p++ = *teln++ & 0x7f;
- }
- *p++ = 0x70;
- *p++ = strlen(st->pa->setup.phone) + 1;
- /* Classify as AnyPref. */
- *p++ = 0x81; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
-
- teln = st->pa->setup.phone;
- while (*teln)
- *p++ = *teln++ & 0x7f;
-
-
- dibh->datasize = p - DATAPTR(dibh);
-
- newl3state(st, 1);
- i_down(st, dibh);
-
-}
-
-static void
-l3s6(struct PStack *st, byte pr, void *arg)
-{
- byte *p;
- struct BufHeader *ibh = arg;
-
- p = DATAPTR(ibh);
- if ((p = findie(p + st->l2.ihsize, ibh->datasize - st->l2.ihsize,
- 0x18, 0))) {
- st->pa->bchannel = p[2] & 0x3;
- } else
- printk(KERN_WARNING "octect 3 not found\n");
-
- BufPoolRelease(ibh);
- newl3state(st, 3);
- st->l3.l3l4(st, CC_PROCEEDING_IND, NULL);
-}
-
-static void
-l3s7(struct PStack *st, byte pr, void *arg)
-{
- struct BufHeader *ibh = arg;
-
- BufPoolRelease(ibh);
- newl3state(st, 12);
- st->l3.l3l4(st, CC_DISCONNECT_IND, NULL);
-}
-
-static void
-l3s8(struct PStack *st, byte pr, void *arg)
-{
- struct BufHeader *ibh = arg;
-
- BufPoolRelease(ibh);
- st->l3.l3l4(st, CC_SETUP_CNF, NULL);
- newl3state(st, 10);
-}
-
-static void
-l3s11(struct PStack *st, byte pr, void *arg)
-{
- struct BufHeader *ibh = arg;
-
- BufPoolRelease(ibh);
- newl3state(st, 4);
- st->l3.l3l4(st, CC_ALERTING_IND, NULL);
-}
-
-static void
-l3s12(struct PStack *st, byte pr, void *arg)
-{
- byte *p;
- int bcfound = 0;
- struct BufHeader *ibh = arg;
-
- p = DATAPTR(ibh);
- p += st->l2.uihsize;
- st->pa->callref = getcallref(p);
- st->l3.callref = 0x80 + st->pa->callref;
-
- /*
- * Channel Identification
- */
- p = DATAPTR(ibh);
- if ((p = findie(p + st->l2.uihsize, ibh->datasize - st->l2.uihsize,
- 0x18, 0))) {
- st->pa->bchannel = p[2] & 0x3;
- bcfound++ ;
- } else
- printk(KERN_WARNING "l3s12: Channel ident not found\n");
-
- p = DATAPTR(ibh);
- if (st->protocol == ISDN_PTYPE_1TR6) {
- if ((p = findie(p + st->l2.uihsize, ibh->datasize - st->l2.uihsize, 0x01, 6))) {
- st->pa->setup.si1 = p[2];
- st->pa->setup.si2 = p[3];
- } else
- printk(KERN_WARNING "l3s12(1TR6): ServiceIndicator not found\n");
- } else {
- /*
- * Bearer Capabilities
- */
- if ((p = findie(p + st->l2.uihsize, ibh->datasize - st->l2.uihsize, 0x04, 0))) {
- st->pa->setup.si2 = 0;
- switch (p[2] & 0x1f) {
- case 0x00:
- /* Speech */
- case 0x10:
- /* 3.1 Khz audio */
- st->pa->setup.si1 = 1;
- break;
- case 0x08:
- /* Unrestricted digital information */
- st->pa->setup.si1 = 7;
- break;
- case 0x09:
- /* Restricted digital information */
- st->pa->setup.si1 = 2;
- break;
- case 0x11:
- /* Unrestr. digital information with tones/announcements */
- st->pa->setup.si1 = 3;
- break;
- case 0x18:
- /* Video */
- st->pa->setup.si1 = 4;
- break;
- default:
- st->pa->setup.si1 = 0;
- }
- } else
- printk(KERN_WARNING "l3s12: Bearer capabilities not found\n");
- }
-
- p = DATAPTR(ibh);
- if ((p = findie(p + st->l2.uihsize, ibh->datasize - st->l2.uihsize,
- 0x70, 0)))
- iecpy(st->pa->setup.eazmsn, p, 1);
- else
- strcpy(st->pa->setup.eazmsn, "");
-
- p = DATAPTR(ibh);
- if ((p = findie(p + st->l2.uihsize, ibh->datasize - st->l2.uihsize,
- 0x6c, 0))) {
- st->pa->setup.plan = p[2];
- if (st->protocol == ISDN_PTYPE_1TR6) {
- iecpy(st->pa->setup.phone, p, 1);
- } else {
- st->pa->setup.screen = p[3];
- iecpy(st->pa->setup.phone, p, 2);
- }
- } else
- strcpy(st->pa->setup.phone, "");
- BufPoolRelease(ibh);
-
- if (bcfound) {
- if (st->pa->setup.si1 != 7) {
- printk(KERN_DEBUG "non-digital call: %s -> %s\n",
- st->pa->setup.phone,
- st->pa->setup.eazmsn);
- }
- newl3state(st, 6);
- st->l3.l3l4(st, CC_SETUP_IND, NULL);
- }
-}
-
-static void
-l3s13(struct PStack *st, byte pr, void *arg)
-{
- newl3state(st, 0);
-}
-
-static void
-l3s16(struct PStack *st, byte pr,
- void *arg)
-{
- st->l3.callref = 0x80 + st->pa->callref;
- l3_message(st, MT_CONNECT);
- newl3state(st, 8);
-}
-
-static void
-l3s17(struct PStack *st, byte pr, void *arg)
-{
- struct BufHeader *ibh = arg;
-
- BufPoolRelease(ibh);
- st->l3.l3l4(st, CC_SETUP_COMPLETE_IND, NULL);
- newl3state(st, 10);
-}
-
-static void
-l3s18(struct PStack *st, byte pr, void *arg)
-{
- struct BufHeader *dibh;
- byte *p;
- int size;
-
- BufPoolGet(&dibh, st->l1.sbufpool, GFP_ATOMIC, (void *) st, 20);
- p = DATAPTR(dibh);
- p += st->l2.ihsize;
- size = st->l2.ihsize;
-
- *p++ = 0x8;
- *p++ = 0x1;
- *p++ = st->l3.callref;
- *p++ = MT_DISCONNECT;
- size += 4;
-
- *p++ = IE_CAUSE;
- *p++ = 0x2;
- *p++ = 0x80;
- *p++ = 0x90;
- size += 4;
-
- dibh->datasize = size;
- i_down(st, dibh);
-
- newl3state(st, 11);
-}
-
-static void
-l3s19(struct PStack *st, byte pr, void *arg)
-{
- struct BufHeader *ibh = arg;
-
- BufPoolRelease(ibh);
- newl3state(st, 0);
- l3_message(st, MT_RELEASE_COMPLETE);
- st->l3.l3l4(st, CC_RELEASE_IND, NULL);
-}
-
-static void
-l3s20(struct PStack *st, byte pr,
- void *arg)
-{
- l3_message(st, MT_ALERTING);
- newl3state(st, 7);
-}
-
-static void
-l3s21(struct PStack *st, byte pr, void *arg)
-{
- struct BufHeader *dibh=arg;
- byte *p;
- int size;
-
- BufPoolRelease(dibh);
-
- BufPoolGet(&dibh, st->l1.sbufpool, GFP_ATOMIC, (void *) st, 20);
- p = DATAPTR(dibh);
- p += st->l2.ihsize;
- size = st->l2.ihsize;
-
- *p++ = 0x8;
- *p++ = 0x1;
- *p++ = st->l3.callref;
- *p++ = MT_STATUS;
- size += 4;
-
- *p++ = IE_CAUSE;
- *p++ = 0x2;
- *p++ = 0x80;
- *p++ = 0x9E; /* answer status enquire */
- size += 4;
-
- *p++ = 0x14; /* CallState */
- *p++ = 0x1;
- *p++ = st->l3.state & 0x3f; /* ISO L3 CallState */
- size += 3;
-
- dibh->datasize = size;
- i_down(st, dibh);
-
-}
-
-struct stateentry {
- int state;
- byte primitive;
- void (*rout) (struct PStack *, byte, void *);
-};
-
-static struct stateentry downstatelist[] =
-{
- {0,CC_SETUP_REQ,l3s5},
- {1,CC_DISCONNECT_REQ,l3s18},
- {1,CC_RELEASE_REQ,l3s3},
- {1,CC_DLRL,l3s13},
- {3,CC_DISCONNECT_REQ,l3s18},
- {3,CC_RELEASE_REQ,l3s3},
- {3,CC_DLRL,l3s13},
- {4,CC_RELEASE_REQ,l3s3},
- {4,CC_DISCONNECT_REQ,l3s18},
- {4,CC_DLRL,l3s13},
- {6,CC_RELEASE_REQ,l3s3},
- {6,CC_DISCONNECT_REQ,l3s18},
- {6,CC_ALERTING_REQ,l3s20},
- {6,CC_DLRL,l3s13},
- {7,CC_RELEASE_REQ,l3s3},
- {7,CC_SETUP_RSP,l3s16},
- {7,CC_DLRL,l3s13},
- {8,CC_RELEASE_REQ,l3s3},
- {8,CC_DISCONNECT_REQ,l3s18},
- {8,CC_DLRL,l3s13},
- {10,CC_DISCONNECT_REQ,l3s18},
- {10,CC_RELEASE_REQ,l3s3},
- {10,CC_DLRL,l3s13},
- {11,CC_RELEASE_REQ,l3s3},
- {12,CC_RELEASE_REQ,l3s3},
- {19,CC_DLRL,l3s13},
-};
-
-static int downsllen = sizeof(downstatelist) /
-sizeof(struct stateentry);
-
-static struct stateentry datastatelist[] =
-{
- {0,MT_STATUS_ENQUIRY,l3s21},
- {0,MT_SETUP,l3s12},
- {1,MT_STATUS_ENQUIRY,l3s21},
- {1,MT_CALL_PROCEEDING,l3s6},
- {1,MT_SETUP_ACKNOWLEDGE,l3s6},
- {1,MT_RELEASE_COMPLETE,l3s4},
- {1,MT_RELEASE,l3s19},
- {1,MT_DISCONNECT,l3s7},
- {3,MT_STATUS_ENQUIRY,l3s21},
- {3,MT_DISCONNECT,l3s7},
- {3,MT_CONNECT,l3s8},
- {3,MT_ALERTING,l3s11},
- {3,MT_RELEASE,l3s19},
- {3,MT_RELEASE_COMPLETE,l3s4},
- {4,MT_STATUS_ENQUIRY,l3s21},
- {4,MT_CONNECT,l3s8},
- {4,MT_DISCONNECT,l3s7},
- {4,MT_RELEASE,l3s19},
- {4,MT_RELEASE_COMPLETE,l3s4},
- {8,MT_STATUS_ENQUIRY,l3s21},
- {6,MT_SETUP,l3s12},
- {8,MT_STATUS_ENQUIRY,l3s21},
- {7,MT_RELEASE,l3s19},
- {7,MT_RELEASE_COMPLETE,l3s4_1},
- {7,MT_DISCONNECT,l3s7},
- {8,MT_STATUS_ENQUIRY,l3s21},
- {8,MT_RELEASE,l3s19},
- {8,MT_CONNECT_ACKNOWLEDGE,l3s17},
- {8,MT_DISCONNECT,l3s7},
- {8,MT_RELEASE_COMPLETE,l3s4_1},
- {10,MT_STATUS_ENQUIRY,l3s21},
- {10,MT_DISCONNECT,l3s7},
- {10,MT_RELEASE,l3s19},
- {10,MT_RELEASE_COMPLETE,l3s4_1},
- {11,MT_STATUS_ENQUIRY,l3s21},
- {11,MT_RELEASE,l3s19},
- {11,MT_RELEASE_COMPLETE,l3s4},
- {19,MT_STATUS_ENQUIRY,l3s21},
- {19,MT_RELEASE_COMPLETE,l3s4},
-};
-
-static int datasllen = sizeof(datastatelist) /
-sizeof(struct stateentry);
-
-#ifdef P_1TR6
-#include "l3_1TR6.c"
-#endif
-
-static void
-l3up(struct PStack *st,
- int pr, void *arg)
-{
- int i, mt, size;
- byte *ptr;
- struct BufHeader *ibh = arg;
-
- if (pr == DL_DATA) {
- ptr = DATAPTR(ibh);
- ptr += st->l2.ihsize;
- size = ibh->datasize - st->l2.ihsize;
- mt = ptr[3];
- switch (ptr[0]) {
-#ifdef P_1TR6
- case PROTO_DIS_N0:
- BufPoolRelease(ibh);
- break;
- case PROTO_DIS_N1:
- for (i = 0; i < datasl_1tr6t_len; i++)
- if ((st->l3.state == datastatelist_1tr6t[i].state) &&
- (mt == datastatelist_1tr6t[i].primitive))
- break;
- if (i == datasl_1tr6t_len) {
- BufPoolRelease(ibh);
- if (DEBUG_1TR6 > 0)
- printk(KERN_INFO "isdnl3up unhandled 1tr6 state %d MT %x\n",
- st->l3.state, mt);
- } else
- datastatelist_1tr6t[i].rout(st, pr, ibh);
- break;
-#endif
- case PROTO_EURO: /* E-DSS1 */
- for (i = 0; i < datasllen; i++)
- if ((st->l3.state == datastatelist[i].state) &&
- (mt == datastatelist[i].primitive))
- break;
- if (i == datasllen) {
- BufPoolRelease(ibh);
- if (DEBUG_1TR6 > 0)
- printk(KERN_INFO "isdnl3up unhandled E-DSS1 state %d MT %x\n",
- st->l3.state, mt);
- } else
- datastatelist[i].rout(st, pr, ibh);
- break;
- default:
- BufPoolRelease(ibh);
- break;
- }
- } else if (pr == DL_UNIT_DATA) {
- ptr = DATAPTR(ibh);
- ptr += st->l2.uihsize;
- size = ibh->datasize - st->l2.uihsize;
- mt = ptr[3];
- switch (ptr[0]) {
-#ifdef P_1TR6
- case PROTO_DIS_N0:
- BufPoolRelease(ibh);
- break;
- case PROTO_DIS_N1:
- for (i = 0; i < datasl_1tr6t_len; i++)
- if ((st->l3.state == datastatelist_1tr6t[i].state) &&
- (mt == datastatelist_1tr6t[i].primitive))
- break;
- if (i == datasl_1tr6t_len) {
- if (DEBUG_1TR6 > 0) {
- printk(KERN_INFO "isdnl3up unhandled 1tr6 state %d MT %x\n"
- ,st->l3.state, mt);
- }
- BufPoolRelease(ibh);
- } else
- datastatelist_1tr6t[i].rout(st, pr, ibh);
- break;
-#endif
- case PROTO_EURO: /* E-DSS1 */
- for (i = 0; i < datasllen; i++)
- if ((st->l3.state == datastatelist[i].state) &&
- (mt == datastatelist[i].primitive))
- break;
- if (i == datasllen) {
- BufPoolRelease(ibh);
- if (DEBUG_1TR6 > 0)
- printk(KERN_INFO "isdnl3up unhandled E-DSS1 state %d MT %x\n",
- st->l3.state, mt);
- } else
- datastatelist[i].rout(st, pr, ibh);
- break;
- default:
- BufPoolRelease(ibh);
- break;
- }
- }
-}
-
-static void
-l3down(struct PStack *st,
- int pr, void *arg)
-{
- int i;
- struct BufHeader *ibh = arg;
-
- switch (st->protocol) {
-#ifdef P_1TR6
- case ISDN_PTYPE_1TR6:
- for (i = 0; i < downsl_1tr6t_len; i++)
- if ((st->l3.state == downstatelist_1tr6t[i].state) &&
- (pr == downstatelist_1tr6t[i].primitive))
- break;
- if (i == downsl_1tr6t_len) {
- if (DEBUG_1TR6 > 0) {
- printk(KERN_INFO "isdnl3down unhandled 1tr6 state %d primitive %x\n", st->l3.state, pr);
- }
- } else
- downstatelist_1tr6t[i].rout(st, pr, ibh);
- break;
-#endif
- default:
- for (i = 0; i < downsllen; i++)
- if ((st->l3.state == downstatelist[i].state) &&
- (pr == downstatelist[i].primitive))
- break;
- if (i == downsllen) {
- if (DEBUG_1TR6 > 0) {
- printk(KERN_INFO "isdnl3down unhandled E-DSS1 state %d primitive %x\n", st->l3.state, pr);
- }
- } else
- downstatelist[i].rout(st, pr, ibh);
- }
-}
-
-void
-setstack_isdnl3(struct PStack *st)
-{
- st->l4.l4l3 = l3down;
- st->l2.l2l3 = l3up;
- st->l3.state = 0;
- st->l3.callref = 0;
- st->l3.debug = 0;
-}
+++ /dev/null
-/* $Id: l3_1TR6.c,v 1.7 1997/02/11 01:38:55 keil Exp $
- *
- * $Log: l3_1TR6.c,v $
- * Revision 1.7 1997/02/11 01:38:55 keil
- * Changed setup-interface (incoming and outgoing)
- *
- * Revision 1.6 1996/09/25 18:34:57 keil
- * missing states in 1TR6 Statemachine added
- *
- * Revision 1.5 1996/09/23 01:53:51 fritz
- * Bugfix: discard unknown frames (non-EDSS1 and non-1TR6).
- *
- * Revision 1.4 1996/06/06 14:22:28 fritz
- * Changed level of "non-digital call..." message, since
- * with audio support, this is quite normal.
- *
- * Revision 1.3 1996/04/30 21:54:42 isdn4dev
- * SPV, callback , remove some debugging code Karsten Keil
- *
- * Revision 1.2 1996/04/20 16:47:23 fritz
- * Changed statemachine to allow reject of an incoming call.
- * Report all incoming calls, not just those with Service = 7.
- * Misc. typos
- *
- * Revision 1.1 1996/04/13 10:25:16 fritz
- * Initial revision
- *
- *
- */
-
-#include "proto.h"
-
-static void
-l3_1TR6_message(struct PStack *st, int mt, int pd)
-{
- struct BufHeader *dibh;
- byte *p;
-
- BufPoolGet(&dibh, st->l1.sbufpool, GFP_ATOMIC, (void *) st, 18);
- p = DATAPTR(dibh);
- p += st->l2.ihsize;
-
- *p++ = pd;
- *p++ = 0x1;
- *p++ = st->l3.callref;
- *p++ = mt;
-
- dibh->datasize = p - DATAPTR(dibh);
- i_down(st, dibh);
-}
-
-static void
-l3_1tr6_setup(struct PStack *st, byte pr, void *arg)
-{
- struct BufHeader *dibh;
- byte *p;
- char *teln;
-
- st->l3.callref = st->pa->callref;
- BufPoolGet(&dibh, st->l1.sbufpool, GFP_ATOMIC, (void *) st, 19);
- p = DATAPTR(dibh);
- p += st->l2.ihsize;
-
- *p++ = PROTO_DIS_N1;
- *p++ = 0x1;
- *p++ = st->l3.callref;
- *p++ = MT_N1_SETUP;
-
- if ('S' == (st->pa->setup.phone[0] & 0x5f)) { /* SPV ??? */
- /* NSF SPV */
- *p++ = WE0_netSpecFac;
- *p++ = 4; /* Laenge */
- *p++ = 0;
- *p++ = FAC_SPV; /* SPV */
- *p++ = st->pa->setup.si1; /* 0 for all Services */
- *p++ = st->pa->setup.si2; /* 0 for all Services */
- *p++ = WE0_netSpecFac;
- *p++ = 4; /* Laenge */
- *p++ = 0;
- *p++ = FAC_Activate; /* aktiviere SPV (default) */
- *p++ = st->pa->setup.si1; /* 0 for all Services */
- *p++ = st->pa->setup.si2; /* 0 for all Services */
- }
- if (st->pa->setup.eazmsn[0]) {
- *p++ = WE0_origAddr;
- *p++ = strlen(st->pa->setup.eazmsn) + 1;
- /* Classify as AnyPref. */
- *p++ = 0x81; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
- teln = st->pa->setup.eazmsn;
- while (*teln)
- *p++ = *teln++ & 0x7f;
- }
- *p++ = WE0_destAddr;
- teln = st->pa->setup.phone;
- if ('S' != (st->pa->setup.phone[0] & 0x5f)) { /* Keine SPV ??? */
- *p++ = strlen(st->pa->setup.phone) + 1;
- st->pa->spv = 0;
- } else { /* SPV */
- *p++ = strlen(st->pa->setup.phone);
- teln++; /* skip S */
- st->pa->spv = 1;
- }
- /* Classify as AnyPref. */
- *p++ = 0x81; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
- while (*teln)
- *p++ = *teln++ & 0x7f;
-
- *p++ = WE_Shift_F6;
- /* Codesatz 6 fuer Service */
- *p++ = WE6_serviceInd;
- *p++ = 2; /* len=2 info,info2 */
- *p++ = st->pa->setup.si1;
- *p++ = st->pa->setup.si2;
-
- dibh->datasize = p - DATAPTR(dibh);
-
- newl3state(st, 1);
- i_down(st, dibh);
-
-}
-
-static void
-l3_1tr6_tu_setup(struct PStack *st, byte pr, void *arg)
-{
- byte *p;
- struct BufHeader *ibh = arg;
-
- p = DATAPTR(ibh);
- p += st->l2.uihsize;
- st->pa->callref = getcallref(p);
- st->l3.callref = 0x80 + st->pa->callref;
-
- /* Channel Identification */
- p = DATAPTR(ibh);
- if ((p = findie(p + st->l2.uihsize, ibh->datasize - st->l2.uihsize,
- WE0_chanID, 0))) {
- st->pa->bchannel = p[2] & 0x3;
- } else
- printk(KERN_INFO "l3tu_setup: Channel ident not found\n");
-
- p = DATAPTR(ibh);
-
- if ((p = findie(p + st->l2.uihsize, ibh->datasize - st->l2.uihsize, WE6_serviceInd, 6))) {
- st->pa->setup.si1 = p[2];
- st->pa->setup.si2 = p[3];
- } else
- printk(KERN_INFO "l3s12(1TR6): ServiceIndicator not found\n");
-
- p = DATAPTR(ibh);
- if ((p = findie(p + st->l2.uihsize, ibh->datasize - st->l2.uihsize,
- WE0_destAddr, 0)))
- iecpy(st->pa->setup.eazmsn, p, 1);
- else
- strcpy(st->pa->setup.eazmsn, "");
-
- p = DATAPTR(ibh);
- if ((p = findie(p + st->l2.uihsize, ibh->datasize - st->l2.uihsize,
- WE0_origAddr, 0))) {
- iecpy(st->pa->setup.phone, p, 1);
- } else
- strcpy(st->pa->setup.phone, "");
-
- p = DATAPTR(ibh);
- st->pa->spv = 0;
- if ((p = findie(p + st->l2.uihsize, ibh->datasize - st->l2.uihsize,
- WE0_netSpecFac, 0))) {
- if ((FAC_SPV == p[3]) || (FAC_Activate == p[3]))
- st->pa->spv = 1;
- }
- BufPoolRelease(ibh);
-
- /* Signal all services, linklevel takes care of Service-Indicator */
- if (st->pa->setup.si1 != 7) {
- printk(KERN_DEBUG "non-digital call: %s -> %s\n",
- st->pa->setup.phone,
- st->pa->setup.eazmsn);
- }
- newl3state(st, 6);
- st->l3.l3l4(st, CC_SETUP_IND, NULL);
-}
-
-static void
-l3_1tr6_tu_setup_ack(struct PStack *st, byte pr, void *arg)
-{
- byte *p;
- struct BufHeader *ibh = arg;
-
- p = DATAPTR(ibh);
- if ((p = findie(p + st->l2.ihsize, ibh->datasize - st->l2.ihsize,
- WE0_chanID, 0))) {
- st->pa->bchannel = p[2] & 0x3;
- } else
- printk(KERN_INFO "octect 3 not found\n");
-
-
- BufPoolRelease(ibh);
- newl3state(st, 2);
-}
-
-static void
-l3_1tr6_tu_call_sent(struct PStack *st, byte pr, void *arg)
-{
- byte *p;
- struct BufHeader *ibh = arg;
-
- p = DATAPTR(ibh);
- if ((p = findie(p + st->l2.ihsize, ibh->datasize - st->l2.ihsize,
- WE0_chanID, 0))) {
- st->pa->bchannel = p[2] & 0x3;
- } else
- printk(KERN_INFO "octect 3 not found\n");
-
- BufPoolRelease(ibh);
- newl3state(st, 3);
- st->l3.l3l4(st, CC_PROCEEDING_IND, NULL);
-}
-
-static void
-l3_1tr6_tu_alert(struct PStack *st, byte pr, void *arg)
-{
- byte *p;
- struct BufHeader *ibh = arg;
-
-
- p = DATAPTR(ibh);
- if ((p = findie(p + st->l2.ihsize, ibh->datasize - st->l2.ihsize,
- WE6_statusCalled, 6))) {
- if (DEBUG_1TR6 > 2)
- printk(KERN_INFO "status called %x\n", p[2]);
- } else if (DEBUG_1TR6 > 0)
- printk(KERN_INFO "statusCalled not found\n");
-
- BufPoolRelease(ibh);
- newl3state(st, 4);
- st->l3.l3l4(st, CC_ALERTING_IND, NULL);
-}
-
-static void
-l3_1tr6_tu_info(struct PStack *st, byte pr, void *arg)
-{
- byte *p;
- int i,tmpcharge=0;
- char a_charge[8];
- struct BufHeader *ibh = arg;
-
- p = DATAPTR(ibh);
- if ((p = findie(p + st->l2.ihsize, ibh->datasize - st->l2.ihsize,
- WE6_chargingInfo, 6))) {
- iecpy(a_charge, p, 1);
- for (i = 0; i < strlen (a_charge); i++) {
- tmpcharge *= 10;
- tmpcharge += a_charge[i] & 0xf;
- }
- if (tmpcharge > st->pa->chargeinfo) {
- st->pa->chargeinfo = tmpcharge;
- st->l3.l3l4 (st, CC_INFO_CHARGE, NULL);
- }
- if (DEBUG_1TR6 > 2)
- printk(KERN_INFO "chargingInfo %d\n", st->pa->chargeinfo);
- } else if (DEBUG_1TR6 > 2)
- printk(KERN_INFO "chargingInfo not found\n");
-
- BufPoolRelease(ibh);
-}
-
-static void
-l3_1tr6_tu_info_s2(struct PStack *st, byte pr, void *arg)
-{
- byte *p;
- int i;
- struct BufHeader *ibh = arg;
-
- if (DEBUG_1TR6 > 4) {
- p = DATAPTR(ibh);
- for (i = 0; i < ibh->datasize; i++) {
- printk(KERN_INFO "Info DATA %x\n", p[i]);
- }
- }
- BufPoolRelease(ibh);
-}
-
-static void
-l3_1tr6_tu_connect(struct PStack *st, byte pr, void *arg)
-{
- struct BufHeader *ibh = arg;
-
- st->pa->chargeinfo=0;
- BufPoolRelease(ibh);
- st->l3.l3l4(st, CC_SETUP_CNF, NULL);
- newl3state(st, 10);
-}
-
-static void
-l3_1tr6_tu_rel(struct PStack *st, byte pr, void *arg)
-{
- struct BufHeader *ibh = arg;
-
- BufPoolRelease(ibh);
- l3_1TR6_message(st, MT_N1_REL_ACK, PROTO_DIS_N1);
- st->l3.l3l4(st, CC_RELEASE_IND, NULL);
- newl3state(st, 0);
-}
-
-static void
-l3_1tr6_tu_rel_ack(struct PStack *st, byte pr, void *arg)
-{
- struct BufHeader *ibh = arg;
-
- BufPoolRelease(ibh);
- newl3state(st, 0);
- st->l3.l3l4(st, CC_RELEASE_CNF, NULL);
-}
-
-static void
-l3_1tr6_tu_disc(struct PStack *st, byte pr, void *arg)
-{
- struct BufHeader *ibh = arg;
- byte *p;
- int i,tmpcharge=0;
- char a_charge[8];
-
- p = DATAPTR(ibh);
- if ((p = findie(p + st->l2.ihsize, ibh->datasize - st->l2.ihsize,
- WE6_chargingInfo, 6))) {
- iecpy(a_charge, p, 1);
- for (i = 0; i < strlen (a_charge); i++) {
- tmpcharge *= 10;
- tmpcharge += a_charge[i] & 0xf;
- }
- if (tmpcharge > st->pa->chargeinfo) {
- st->pa->chargeinfo = tmpcharge;
- st->l3.l3l4 (st, CC_INFO_CHARGE, NULL);
- }
- if (DEBUG_1TR6 > 2)
- printk(KERN_INFO "chargingInfo %d\n", st->pa->chargeinfo);
- } else if (DEBUG_1TR6 > 2)
- printk(KERN_INFO "chargingInfo not found\n");
-
- p = DATAPTR(ibh);
- if ((p = findie(p + st->l2.ihsize, ibh->datasize - st->l2.ihsize,
- WE0_cause, 0))) {
- if (p[1] > 0) {
- st->pa->cause = p[2];
- } else {
- st->pa->cause = 0;
- }
- if (DEBUG_1TR6 > 1)
- printk(KERN_INFO "Cause %x\n", st->pa->cause);
- } else if (DEBUG_1TR6 > 0)
- printk(KERN_INFO "Cause not found\n");
-
- BufPoolRelease(ibh);
- newl3state(st, 12);
- st->l3.l3l4(st, CC_DISCONNECT_IND, NULL);
-}
-
-
-static void
-l3_1tr6_tu_connect_ack(struct PStack *st, byte pr, void *arg)
-{
- struct BufHeader *ibh = arg;
-
- BufPoolRelease(ibh);
- st->pa->chargeinfo = 0;
- st->l3.l3l4(st, CC_SETUP_COMPLETE_IND, NULL);
- newl3state(st, 10);
-}
-
-static void
-l3_1tr6_alert(struct PStack *st, byte pr,
- void *arg)
-{
- l3_1TR6_message(st, MT_N1_ALERT, PROTO_DIS_N1);
- newl3state(st, 7);
-}
-
-static void
-l3_1tr6_conn(struct PStack *st, byte pr,
- void *arg)
-{
- struct BufHeader *dibh;
- byte *p;
-
- st->l3.callref = 0x80 + st->pa->callref;
-
- BufPoolGet(&dibh, st->l1.sbufpool, GFP_ATOMIC, (void *) st, 20);
- p = DATAPTR(dibh);
- p += st->l2.ihsize;
-
- *p++ = PROTO_DIS_N1;
- *p++ = 0x1;
- *p++ = st->l3.callref;
- *p++ = MT_N1_CONN;
-
- if (st->pa->spv) { /* SPV ??? */
- /* NSF SPV */
- *p++ = WE0_netSpecFac;
- *p++ = 4; /* Laenge */
- *p++ = 0;
- *p++ = FAC_SPV; /* SPV */
- *p++ = st->pa->setup.si1;
- *p++ = st->pa->setup.si2;
- *p++ = WE0_netSpecFac;
- *p++ = 4; /* Laenge */
- *p++ = 0;
- *p++ = FAC_Activate; /* aktiviere SPV */
- *p++ = st->pa->setup.si1;
- *p++ = st->pa->setup.si2;
- }
- dibh->datasize = p - DATAPTR(dibh);
-
- i_down(st, dibh);
-
- newl3state(st, 8);
-}
-
-static void
-l3_1tr6_reset(struct PStack *st, byte pr, void *arg)
-{
- newl3state(st, 0);
-}
-
-static void
-l3_1tr6_disconn_req(struct PStack *st, byte pr, void *arg)
-{
- struct BufHeader *dibh;
- byte *p;
- byte rejflg;
-
- BufPoolGet(&dibh, st->l1.sbufpool, GFP_ATOMIC, (void *) st, 21);
- p = DATAPTR(dibh);
- p += st->l2.ihsize;
-
- *p++ = PROTO_DIS_N1;
- *p++ = 0x1;
- *p++ = st->l3.callref;
- *p++ = MT_N1_DISC;
-
- if (st->l3.state == 7) {
- rejflg = 1;
- *p++ = WE0_cause; /* Anruf abweisen */
- *p++ = 0x01; /* Laenge = 1 */
- *p++ = CAUSE_CallRejected;
- } else {
- rejflg = 0;
- *p++ = WE0_cause;
- *p++ = 0x0; /* Laenge = 0 normales Ausloesen */
- }
-
- dibh->datasize = p - DATAPTR(dibh);
-
- i_down(st, dibh);
-
- newl3state(st, 11);
-}
-
-static void
-l3_1tr6_rel_req(struct PStack *st, byte pr, void *arg)
-{
- l3_1TR6_message(st, MT_N1_REL, PROTO_DIS_N1);
- newl3state(st, 19);
-}
-
-static struct stateentry downstatelist_1tr6t[] =
-{
- {0, CC_SETUP_REQ, l3_1tr6_setup},
- {1, CC_DISCONNECT_REQ, l3_1tr6_disconn_req},
- {1, CC_RELEASE_REQ, l3_1tr6_rel_req},
- {1, CC_DLRL, l3_1tr6_reset},
- {2, CC_DISCONNECT_REQ, l3_1tr6_disconn_req},
- {2, CC_RELEASE_REQ, l3_1tr6_rel_req},
- {2, CC_DLRL, l3_1tr6_reset},
- {3, CC_DISCONNECT_REQ, l3_1tr6_disconn_req},
- {3, CC_RELEASE_REQ, l3_1tr6_rel_req},
- {3, CC_DLRL, l3_1tr6_reset},
- {4, CC_DISCONNECT_REQ, l3_1tr6_disconn_req},
- {4, CC_RELEASE_REQ, l3_1tr6_rel_req},
- {4, CC_DLRL, l3_1tr6_reset},
- {6, CC_REJECT_REQ, l3_1tr6_reset},
- {6, CC_RELEASE_REQ, l3_1tr6_rel_req},
- {6, CC_SETUP_RSP, l3_1tr6_conn},
- {6, CC_ALERTING_REQ, l3_1tr6_alert},
- {6, CC_DLRL, l3_1tr6_reset},
- {7, CC_SETUP_RSP, l3_1tr6_conn},
- {7, CC_RELEASE_REQ, l3_1tr6_rel_req},
- {7, CC_DISCONNECT_REQ, l3_1tr6_disconn_req},
- {7, CC_DLRL, l3_1tr6_reset},
- {8, CC_DISCONNECT_REQ, l3_1tr6_disconn_req},
- {8, CC_RELEASE_REQ, l3_1tr6_rel_req},
- {8, CC_DLRL, l3_1tr6_reset},
- {10, CC_DISCONNECT_REQ, l3_1tr6_disconn_req},
- {10, CC_RELEASE_REQ, l3_1tr6_rel_req},
- {10, CC_DLRL, l3_1tr6_reset},
- {12, CC_RELEASE_REQ, l3_1tr6_rel_req},
- {12, CC_DLRL, l3_1tr6_reset},
- {19, CC_DLRL, l3_1tr6_reset},
-};
-
-static int downsl_1tr6t_len = sizeof(downstatelist_1tr6t) /
-sizeof(struct stateentry);
-
-static struct stateentry datastatelist_1tr6t[] =
-{
- {0, MT_N1_SETUP, l3_1tr6_tu_setup},
- {0, MT_N1_REL, l3_1tr6_tu_rel},
- {1, MT_N1_SETUP_ACK, l3_1tr6_tu_setup_ack},
- {1, MT_N1_CALL_SENT, l3_1tr6_tu_call_sent},
- {1, MT_N1_REL, l3_1tr6_tu_rel},
- {1, MT_N1_DISC, l3_1tr6_tu_disc},
- {2, MT_N1_CALL_SENT, l3_1tr6_tu_call_sent},
- {2, MT_N1_ALERT, l3_1tr6_tu_alert},
- {2, MT_N1_CONN, l3_1tr6_tu_connect},
- {2, MT_N1_REL, l3_1tr6_tu_rel},
- {2, MT_N1_DISC, l3_1tr6_tu_disc},
- {2, MT_N1_INFO, l3_1tr6_tu_info_s2},
- {3, MT_N1_ALERT, l3_1tr6_tu_alert},
- {3, MT_N1_CONN, l3_1tr6_tu_connect},
- {3, MT_N1_REL, l3_1tr6_tu_rel},
- {3, MT_N1_DISC, l3_1tr6_tu_disc},
- {4, MT_N1_ALERT, l3_1tr6_tu_alert},
- {4, MT_N1_CONN, l3_1tr6_tu_connect},
- {4, MT_N1_REL, l3_1tr6_tu_rel},
- {4, MT_N1_DISC, l3_1tr6_tu_disc},
- {7, MT_N1_REL, l3_1tr6_tu_rel},
- {7, MT_N1_DISC, l3_1tr6_tu_disc},
- {8, MT_N1_REL, l3_1tr6_tu_rel},
- {8, MT_N1_DISC, l3_1tr6_tu_disc},
- {8, MT_N1_CONN_ACK, l3_1tr6_tu_connect_ack},
- {10, MT_N1_REL, l3_1tr6_tu_rel},
- {10, MT_N1_DISC, l3_1tr6_tu_disc},
- {10, MT_N1_INFO, l3_1tr6_tu_info},
- {11, MT_N1_REL, l3_1tr6_tu_rel},
- {12, MT_N1_REL, l3_1tr6_tu_rel},
- {19, MT_N1_REL_ACK, l3_1tr6_tu_rel_ack}
-};
-
-static int datasl_1tr6t_len = sizeof(datastatelist_1tr6t) /
-sizeof(struct stateentry);
+++ /dev/null
-/* $Id: l3_1TR6.h,v 1.4 1996/09/23 01:53:52 fritz Exp $
- *
- * $Log: l3_1TR6.h,v $
- * Revision 1.4 1996/09/23 01:53:52 fritz
- * Bugfix: discard unknown frames (non-EDSS1 and non-1TR6).
- *
- * Revision 1.3 1996/04/30 21:53:48 isdn4dev
- * Bugs, SPV, Logging in q931.c Karsten Keil
- *
- * Revision 1.1 1996/04/13 10:25:42 fritz
- * Initial revision
- *
- *
- */
-#ifndef l3_1TR6
-#define l3_1TR6
-
-/*
- * MsgType N0
- */
-#define MT_N0_REG_IND 0x61
-#define MT_N0_CANC_IND 0x62
-#define MT_N0_FAC_STA 0x63
-#define MT_N0_STA_ACK 0x64
-#define MT_N0_STA_REJ 0x65
-#define MT_N0_FAC_INF 0x66
-#define MT_N0_INF_ACK 0x67
-#define MT_N0_INF_REJ 0x68
-#define MT_N0_CLOSE 0x75
-#define MT_N0_CLO_ACK 0x77
-
-
-/*
- * MsgType N1
- */
-
-#define MT_N1_ESC 0x00
-#define MT_N1_ALERT 0x01
-#define MT_N1_CALL_SENT 0x02
-#define MT_N1_CONN 0x07
-#define MT_N1_CONN_ACK 0x0F
-#define MT_N1_SETUP 0x05
-#define MT_N1_SETUP_ACK 0x0D
-#define MT_N1_RES 0x26
-#define MT_N1_RES_ACK 0x2E
-#define MT_N1_RES_REJ 0x22
-#define MT_N1_SUSP 0x25
-#define MT_N1_SUSP_ACK 0x2D
-#define MT_N1_SUSP_REJ 0x21
-#define MT_N1_USER_INFO 0x20
-#define MT_N1_DET 0x40
-#define MT_N1_DISC 0x45
-#define MT_N1_REL 0x4D
-#define MT_N1_REL_ACK 0x5A
-#define MT_N1_CANC_ACK 0x6E
-#define MT_N1_CANC_REJ 0x67
-#define MT_N1_CON_CON 0x69
-#define MT_N1_FAC 0x60
-#define MT_N1_FAC_ACK 0x68
-#define MT_N1_FAC_CAN 0x66
-#define MT_N1_FAC_REG 0x64
-#define MT_N1_FAC_REJ 0x65
-#define MT_N1_INFO 0x6D
-#define MT_N1_REG_ACK 0x6C
-#define MT_N1_REG_REJ 0x6F
-#define MT_N1_STAT 0x63
-
-
-
-/*
- * W Elemente
- */
-
-#define WE_Shift_F0 0x90
-#define WE_Shift_F6 0x96
-#define WE_Shift_OF0 0x98
-#define WE_Shift_OF6 0x9E
-
-#define WE0_cause 0x08
-#define WE0_connAddr 0x0C
-#define WE0_callID 0x10
-#define WE0_chanID 0x18
-#define WE0_netSpecFac 0x20
-#define WE0_display 0x28
-#define WE0_keypad 0x2C
-#define WE0_origAddr 0x6C
-#define WE0_destAddr 0x70
-#define WE0_userInfo 0x7E
-
-#define WE0_moreData 0xA0
-#define WE0_congestLevel 0xB0
-
-#define WE6_serviceInd 0x01
-#define WE6_chargingInfo 0x02
-#define WE6_date 0x03
-#define WE6_facSelect 0x05
-#define WE6_facStatus 0x06
-#define WE6_statusCalled 0x07
-#define WE6_addTransAttr 0x08
-
-/*
- * FacCodes
- */
-#define FAC_Sperre 0x01
-#define FAC_Sperre_All 0x02
-#define FAC_Sperre_Fern 0x03
-#define FAC_Sperre_Intl 0x04
-#define FAC_Sperre_Interk 0x05
-
-#define FAC_Forward1 0x02
-#define FAC_Forward2 0x03
-#define FAC_Konferenz 0x06
-#define FAC_GrabBchan 0x0F
-#define FAC_Reactivate 0x10
-#define FAC_Konferenz3 0x11
-#define FAC_Dienstwechsel1 0x12
-#define FAC_Dienstwechsel2 0x13
-#define FAC_NummernIdent 0x14
-#define FAC_GBG 0x15
-#define FAC_DisplayUebergeben 0x17
-#define FAC_DisplayUmgeleitet 0x1A
-#define FAC_Unterdruecke 0x1B
-#define FAC_Deactivate 0x1E
-#define FAC_Activate 0x1D
-#define FAC_SPV 0x1F
-#define FAC_Rueckwechsel 0x23
-#define FAC_Umleitung 0x24
-
-/*
- * Cause codes
- */
-#define CAUSE_InvCRef 0x01
-#define CAUSE_BearerNotImpl 0x03
-#define CAUSE_CIDunknown 0x07
-#define CAUSE_CIDinUse 0x08
-#define CAUSE_NoChans 0x0A
-#define CAUSE_FacNotImpl 0x10
-#define CAUSE_FacNotSubscr 0x11
-#define CAUSE_OutgoingBarred 0x20
-#define CAUSE_UserAccessBusy 0x21
-#define CAUSE_NegativeGBG 0x22
-#define CAUSE_UnknownGBG 0x23
-#define CAUSE_NoSPVknown 0x25
-#define CAUSE_DestNotObtain 0x35
-#define CAUSE_NumberChanged 0x38
-#define CAUSE_OutOfOrder 0x39
-#define CAUSE_NoUserResponse 0x3A
-#define CAUSE_UserBusy 0x3B
-#define CAUSE_IncomingBarred 0x3D
-#define CAUSE_CallRejected 0x3E
-#define CAUSE_NetworkCongestion 0x59
-#define CAUSE_RemoteUser 0x5A
-#define CAUSE_LocalProcErr 0x70
-#define CAUSE_RemoteProcErr 0x71
-#define CAUSE_RemoteUserSuspend 0x72
-#define CAUSE_RemoteUserResumed 0x73
-#define CAUSE_UserInfoDiscarded 0x7F
-
-
-#endif
+++ /dev/null
-/* $Id: llglue.c,v 1.7 1996/10/22 23:14:17 fritz Exp $
- *
- * $Log: llglue.c,v $
- * Revision 1.7 1996/10/22 23:14:17 fritz
- * Changes for compatibility to 2.0.X and 2.1.X kernels.
- *
- * Revision 1.6 1996/06/03 20:03:39 fritz
- * Fixed typos.
- *
- * Revision 1.5 1996/05/31 00:58:47 fritz
- * Errata: Reverted change from rev 1.4.
- *
- * Revision 1.4 1996/05/26 14:59:57 fritz
- * Bugfix: maxbufsize had been set without respect to possible X.75 header.
- *
- * Revision 1.3 1996/05/01 14:19:57 fritz
- * Added ISDN_FEATURE_L2_TRANS
- *
- * Revision 1.2 1996/04/29 23:01:46 fritz
- * Added driverId and channel to readstatus().
- *
- * Revision 1.1 1996/04/13 10:26:29 fritz
- * Initial revision
- *
- *
- */
-#define __NO_VERSION__
-#include "teles.h"
-#include <linux/malloc.h>
-#include <linux/timer.h>
-
-
-extern struct Channel *chanlist;
-int drid;
-char *teles_id = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
-
-isdn_if iif;
-
-#define TELES_STATUS_BUFSIZE 4096
-static byte *teles_status_buf = NULL;
-static byte *teles_status_read = NULL;
-static byte *teles_status_write = NULL;
-static byte *teles_status_end = NULL;
-
-int
-teles_readstatus(byte * buf, int len, int user, int id, int channel)
-{
- int count;
- byte *p;
-
- for (p = buf, count = 0; count < len; p++, count++) {
- if (user)
- put_user(*teles_status_read++, p);
- else
- *p++ = *teles_status_read++;
- if (teles_status_read > teles_status_end)
- teles_status_read = teles_status_buf;
- }
- return count;
-}
-
-void
-teles_putstatus(char *buf)
-{
- long flags;
- int len, count, i;
- byte *p;
- isdn_ctrl ic;
-
- save_flags(flags);
- cli();
- count = 0;
- len = strlen(buf);
- for (p = buf, i = len; i > 0; i--, p++) {
- *teles_status_write++ = *p;
- if (teles_status_write > teles_status_end)
- teles_status_write = teles_status_buf;
- count++;
- }
- restore_flags(flags);
- if (count) {
- ic.command = ISDN_STAT_STAVAIL;
- ic.driver = drid;
- ic.arg = count;
- iif.statcallb(&ic);
- }
-}
-
-
-int
-ll_init(void)
-{
- isdn_ctrl ic;
-
- teles_status_buf = Smalloc(TELES_STATUS_BUFSIZE,
- GFP_KERNEL, "teles_status_buf");
- if (!teles_status_buf) {
- printk(KERN_ERR "teles: Could not allocate status-buffer\n");
- return (-EIO);
- } else {
- teles_status_read = teles_status_buf;
- teles_status_write = teles_status_buf;
- teles_status_end = teles_status_buf + TELES_STATUS_BUFSIZE - 1;
- }
-
- iif.channels = CallcNewChan();
- iif.maxbufsize = BUFFER_SIZE(HSCX_SBUF_ORDER, HSCX_SBUF_BPPS);
- iif.features =
- ISDN_FEATURE_L2_X75I |
- ISDN_FEATURE_L2_HDLC |
- ISDN_FEATURE_L2_TRANS |
- ISDN_FEATURE_L3_TRANS |
- ISDN_FEATURE_P_1TR6 |
- ISDN_FEATURE_P_EURO;
-
- iif.command = teles_command;
- iif.writebuf = teles_writebuf;
- iif.writecmd = NULL;
- iif.readstat = teles_readstatus;
- strncpy(iif.id, teles_id, sizeof(iif.id) - 1);
-
- register_isdn(&iif);
- drid = iif.channels;
-
- ic.driver = drid;
- ic.command = ISDN_STAT_RUN;
- iif.statcallb(&ic);
- return 0;
-}
-
-void
-ll_stop(void)
-{
- isdn_ctrl ic;
-
- ic.command = ISDN_STAT_STOP;
- ic.driver = drid;
- iif.statcallb(&ic);
-
- CallcFreeChan();
-}
-
-void
-ll_unload(void)
-{
- isdn_ctrl ic;
-
- ic.command = ISDN_STAT_UNLOAD;
- ic.driver = drid;
- iif.statcallb(&ic);
-}
+++ /dev/null
-/* $Id: mod.c,v 1.3 1997/02/14 12:23:31 fritz Exp $
- *
- * $Log: mod.c,v $
- * Revision 1.3 1997/02/14 12:23:31 fritz
- * Added support for new insmod parameter handling.
- *
- * Revision 1.2 1997/02/10 11:45:14 fritz
- * More changes for Kernel 2.1.X compatibility.
- *
- * Revision 1.1 1996/04/13 10:27:02 fritz
- * Initial revision
- *
- *
- */
-#include "teles.h"
-
-extern struct IsdnCard cards[];
-extern char *teles_id;
-
-int nrcards;
-
-typedef struct {
- byte *membase;
- int interrupt;
- unsigned int iobase;
- unsigned int protocol;
-} io_type;
-
-io_type io[] =
-{
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
-};
-
-#ifdef MODULE
-#if (LINUX_VERSION_CODE > 0x020111)
-MODULE_PARM(io, "1-64i");
-MODULE_PARM(teles_id, "s");
-#endif
-#endif
-
-void
-teles_mod_dec_use_count(void)
-{
- MOD_DEC_USE_COUNT;
-}
-
-void
-teles_mod_inc_use_count(void)
-{
- MOD_INC_USE_COUNT;
-}
-
-#ifdef MODULE
-#define teles_init init_module
-#else
-void teles_setup(char *str, int *ints)
-{
- int i, j, argc;
- static char sid[20];
-
- argc = ints[0];
- i = 0;
- j = 1;
- while (argc && (i<16)) {
- if (argc) {
- io[i].iobase = ints[j];
- j++; argc--;
- }
- if (argc) {
- io[i].interrupt = ints[j];
- j++; argc--;
- }
- if (argc) {
- io[i].membase = (byte *)ints[j];
- j++; argc--;
- }
- if (argc) {
- io[i].protocol = ints[j];
- j++; argc--;
- }
- i++;
- }
- if (strlen(str)) {
- strcpy(sid,str);
- teles_id = sid;
- }
-}
-#endif
-
-int
-teles_init(void)
-{
- int i;
-
- nrcards = 0;
- for (i = 0; i < 16; i++) {
- if (io[i].protocol) {
- cards[i].membase = io[i].membase;
- cards[i].interrupt = io[i].interrupt;
- cards[i].iobase = io[i].iobase;
- cards[i].protocol = io[i].protocol;
- }
- }
- for (i = 0; i < 16; i++)
- if (cards[i].protocol)
- nrcards++;
- printk(KERN_DEBUG "teles: Total %d card%s defined\n",
- nrcards, (nrcards > 1) ? "s" : "");
- if (teles_inithardware()) {
- /* Install only, if at least one card found */
- Isdnl2New();
- TeiNew();
- CallcNew();
- ll_init();
-
- /* No symbols to export, hide all symbols */
-
-#ifdef MODULE
-#if (LINUX_VERSION_CODE < 0x020111)
- register_symtab(NULL);
-#else
- EXPORT_NO_SYMBOLS;
-#endif
- printk(KERN_NOTICE "Teles module installed\n");
-#endif
- return (0);
- } else
- return -EIO;
-}
-
-#ifdef MODULE
-void
-cleanup_module(void)
-{
-
- ll_stop();
- TeiFree();
- Isdnl2Free();
- CallcFree();
- teles_closehardware();
- ll_unload();
- printk(KERN_NOTICE "Teles module removed\n");
-
-}
-#endif
+++ /dev/null
-/* $Id: proto.h,v 1.1 1996/09/23 01:53:52 fritz Exp $
- *
- * not much now - just the l3 proto discriminator
- *
- * $Log: proto.h,v $
- * Revision 1.1 1996/09/23 01:53:52 fritz
- * Bugfix: discard unknown frames (non-EDSS1 and non-1TR6).
- *
- */
-
-#ifndef PROTO_H
-#define PROTO_H
-
-#define PROTO_EURO 0x08
-#define PROTO_DIS_N0 0x40
-#define PROTO_DIS_N1 0x41
-
-#endif
+++ /dev/null
-/* $Id: q931.c,v 1.6 1996/09/23 01:53:53 fritz Exp $
- *
- * q931.c code to decode ITU Q.931 call control messages
- *
- * Author Jan den Ouden
- *
- * Changelog
- *
- * Pauline Middelink general improvements
- *
- * Beat Doebeli cause texts, display information element
- *
- * Karsten Keil cause texts, display information element for 1TR6
- *
- *
- * $Log: q931.c,v $
- * Revision 1.6 1996/09/23 01:53:53 fritz
- * Bugfix: discard unknown frames (non-EDSS1 and non-1TR6).
- *
- * Revision 1.5 1996/06/03 20:03:40 fritz
- * Fixed typos.
- *
- * Revision 1.4 1996/05/17 03:46:17 fritz
- * General cleanup.
- *
- * Revision 1.3 1996/04/30 22:06:50 isdn4dev
- * logging 1TR6 messages correctly Karsten Keil
- *
- * Revision 1.2 1996/04/20 16:48:19 fritz
- * Misc. typos
- *
- * Revision 1.1 1996/04/13 10:27:49 fritz
- * Initial revision
- *
- *
- */
-
-
-#define __NO_VERSION__
-#include "teles.h"
-#include "proto.h"
-#include "l3_1TR6.h"
-
-byte *
-findie(byte * p, int size, byte ie, int wanted_set)
-{
- int l, codeset, maincodeset;
- byte *pend = p + size;
-
- /* skip protocol discriminator, callref and message type */
- p++;
- l = (*p++) & 0xf;
- p += l;
- p++;
- codeset = 0;
- maincodeset = 0;
- /* while there are bytes left... */
- while (p < pend) {
- if ((*p & 0xf0) == 0x90) {
- codeset = *p & 0x07;
- if (!(*p & 0x08))
- maincodeset = codeset;
- }
- if (*p & 0x80)
- p++;
- else {
- if (codeset == wanted_set) {
- if (*p == ie)
- return (p);
- if (*p > ie)
- return (NULL);
- }
- p++;
- l = *p++;
- p += l;
- codeset = maincodeset;
- }
- }
- return (NULL);
-}
-
-void
-iecpy(byte * dest, byte * iestart, int ieoffset)
-{
- byte *p;
- int l;
-
- p = iestart + ieoffset + 2;
- l = iestart[1] - ieoffset;
- while (l--)
- *dest++ = *p++;
- *dest++ = '\0';
-}
-
-int
-getcallref(byte * p)
-{
- p++; /* prot discr */
- p++; /* callref length */
- return (*p); /* assuming one-byte callref */
-}
-
-/*
- * According to Table 4-2/Q.931
- */
-static
-struct MessageType {
- byte nr;
- char *descr;
-} mtlist[] = {
-
- {
- 0x1, "ALERTING"
- },
- {
- 0x2, "CALL PROCEEDING"
- },
- {
- 0x7, "CONNECT"
- },
- {
- 0xf, "CONNECT ACKNOWLEDGE"
- },
- {
- 0x3, "PROGRESS"
- },
- {
- 0x5, "SETUP"
- },
- {
- 0xd, "SETUP ACKNOWLEDGE"
- },
- {
- 0x26, "RESUME"
- },
- {
- 0x2e, "RESUME ACKNOWLEDGE"
- },
- {
- 0x22, "RESUME REJECT"
- },
- {
- 0x25, "SUSPEND"
- },
- {
- 0x2d, "SUSPEND ACKNOWLEDGE"
- },
- {
- 0x21, "SUSPEND REJECT"
- },
- {
- 0x20, "USER INFORMATION"
- },
- {
- 0x45, "DISCONNECT"
- },
- {
- 0x4d, "RELEASE"
- },
- {
- 0x5a, "RELEASE COMPLETE"
- },
- {
- 0x46, "RESTART"
- },
- {
- 0x4e, "RESTART ACKNOWLEDGE"
- },
- {
- 0x60, "SEGMENT"
- },
- {
- 0x79, "CONGESTION CONTROL"
- },
- {
- 0x7b, "INFORMATION"
- },
- {
- 0x62, "FACILITY"
- },
- {
- 0x6e, "NOTIFY"
- },
- {
- 0x7d, "STATUS"
- },
- {
- 0x75, "STATUS ENQUIRY"
- }
-};
-
-#define MTSIZE sizeof(mtlist)/sizeof(struct MessageType)
-
-static
-struct MessageType mt_n0[] =
-{
- {MT_N0_REG_IND, "REGister INDication"},
- {MT_N0_CANC_IND, "CANCel INDication"},
- {MT_N0_FAC_STA, "FACility STAtus"},
- {MT_N0_STA_ACK, "STAtus ACKnowledge"},
- {MT_N0_STA_REJ, "STAtus REJect"},
- {MT_N0_FAC_INF, "FACility INFormation"},
- {MT_N0_INF_ACK, "INFormation ACKnowledge"},
- {MT_N0_INF_REJ, "INFormation REJect"},
- {MT_N0_CLOSE, "CLOSE"},
- {MT_N0_CLO_ACK, "CLOse ACKnowledge"}
-};
-
-int mt_n0_len = (sizeof(mt_n0) / sizeof(struct MessageType));
-
-static
-struct MessageType mt_n1[] =
-{
- {MT_N1_ESC, "ESCape"},
- {MT_N1_ALERT, "ALERT"},
- {MT_N1_CALL_SENT, "CALL SENT"},
- {MT_N1_CONN, "CONNect"},
- {MT_N1_CONN_ACK, "CONNect ACKnowledge"},
- {MT_N1_SETUP, "SETUP"},
- {MT_N1_SETUP_ACK, "SETUP ACKnowledge"},
- {MT_N1_RES, "RESume"},
- {MT_N1_RES_ACK, "RESume ACKnowledge"},
- {MT_N1_RES_REJ, "RESume REJect"},
- {MT_N1_SUSP, "SUSPend"},
- {MT_N1_SUSP_ACK, "SUSPend ACKnowledge"},
- {MT_N1_SUSP_REJ, "SUSPend REJect"},
- {MT_N1_USER_INFO, "USER INFO"},
- {MT_N1_DET, "DETach"},
- {MT_N1_DISC, "DISConnect"},
- {MT_N1_REL, "RELease"},
- {MT_N1_REL_ACK, "RELease ACKnowledge"},
- {MT_N1_CANC_ACK, "CANCel ACKnowledge"},
- {MT_N1_CANC_REJ, "CANCel REJect"},
- {MT_N1_CON_CON, "CONgestion CONtrol"},
- {MT_N1_FAC, "FACility"},
- {MT_N1_FAC_ACK, "FACility ACKnowledge"},
- {MT_N1_FAC_CAN, "FACility CANcel"},
- {MT_N1_FAC_REG, "FACility REGister"},
- {MT_N1_FAC_REJ, "FACility REJect"},
- {MT_N1_INFO, "INFOrmation"},
- {MT_N1_REG_ACK, "REGister ACKnowledge"},
- {MT_N1_REG_REJ, "REGister REJect"},
- {MT_N1_STAT, "STATus"}
-};
-
-int mt_n1_len = (sizeof(mt_n1) / sizeof(struct MessageType));
-
-static struct MessageType fac_1tr6[] =
-{
- {FAC_Sperre, "Sperre"},
- {FAC_Forward1, "Forward 1"},
- {FAC_Forward2, "Forward 2"},
- {FAC_Konferenz, "Konferenz"},
- {FAC_GrabBchan, "Grab Bchannel"},
- {FAC_Reactivate, "Reactivate"},
- {FAC_Konferenz3, "Dreier Konferenz"},
- {FAC_Dienstwechsel1, "Einseitiger Dienstwechsel"},
- {FAC_Dienstwechsel2, "Zweiseitiger Dienstwechsel"},
- {FAC_NummernIdent, "Rufnummer-Identifizierung"},
- {FAC_GBG, "GBG"},
- {FAC_DisplayUebergeben, "Display Uebergeben"},
- {FAC_DisplayUmgeleitet, "Display Umgeleitet"},
- {FAC_Unterdruecke, "Unterdruecke Rufnummer"},
- {FAC_Deactivate, "Deactivate"},
- {FAC_Activate, "Activate"},
- {FAC_SPV, "SPV"},
- {FAC_Rueckwechsel, "Rueckwechsel"},
- {FAC_Umleitung, "Umleitung"}
-};
-int fac_1tr6_len = (sizeof(fac_1tr6) / sizeof(struct MessageType));
-
-
-
-static int
-prbits(char *dest, byte b, int start, int len)
-{
- char *dp = dest;
-
- b = b << (8 - start);
- while (len--) {
- if (b & 0x80)
- *dp++ = '1';
- else
- *dp++ = '0';
- b = b << 1;
- }
- return (dp - dest);
-}
-
-static
-byte *
-skipext(byte * p)
-{
- while (!(*p++ & 0x80));
- return (p);
-}
-
-/*
- * Cause Values According to Q.850
- * edescr: English description
- * ddescr: German description used by Swissnet II (Swiss Telecom
- * not yet written...
- */
-
-static
-struct CauseValue {
- byte nr;
- char *edescr;
- char *ddescr;
-} cvlist[] = {
-
- {
- 0x01, "Unallocated (unassigned) number", "Nummer nicht zugeteilt"
- },
- {
- 0x02, "No route to specified transit network", ""
- },
- {
- 0x03, "No route to destination", ""
- },
- {
- 0x04, "Send special information tone", ""
- },
- {
- 0x05, "Misdialled trunk prefix", ""
- },
- {
- 0x06, "Channel unacceptable", "Kanal nicht akzeptierbar"
- },
- {
- 0x07, "Channel awarded and being delivered in an established channel", ""
- },
- {
- 0x08, "Preemption", ""
- },
- {
- 0x09, "Preemption - circuit reserved for reuse", ""
- },
- {
- 0x10, "Normal call clearing", "Normale Ausloesung"
- },
- {
- 0x11, "User busy", "TNB besetzt"
- },
- {
- 0x12, "No user responding", ""
- },
- {
- 0x13, "No answer from user (user alerted)", ""
- },
- {
- 0x14, "Subscriber absent", ""
- },
- {
- 0x15, "Call rejected", ""
- },
- {
- 0x16, "Number changed", ""
- },
- {
- 0x1a, "non-selected user clearing", ""
- },
- {
- 0x1b, "Destination out of order", ""
- },
- {
- 0x1c, "Invalid number format (address incomplete)", ""
- },
- {
- 0x1d, "Facility rejected", ""
- },
- {
- 0x1e, "Response to Status enquiry", ""
- },
- {
- 0x1f, "Normal, unspecified", ""
- },
- {
- 0x22, "No circuit/channel available", ""
- },
- {
- 0x26, "Network out of order", ""
- },
- {
- 0x27, "Permanent frame mode connection out-of-service", ""
- },
- {
- 0x28, "Permanent frame mode connection operational", ""
- },
- {
- 0x29, "Temporary failure", ""
- },
- {
- 0x2a, "Switching equipment congestion", ""
- },
- {
- 0x2b, "Access information discarded", ""
- },
- {
- 0x2c, "Requested circuit/channel not available", ""
- },
- {
- 0x2e, "Precedence call blocked", ""
- },
- {
- 0x2f, "Resource unavailable, unspecified", ""
- },
- {
- 0x31, "Quality of service unavailable", ""
- },
- {
- 0x32, "Requested facility not subscribed", ""
- },
- {
- 0x35, "Outgoing calls barred within CUG", ""
- },
- {
- 0x37, "Incoming calls barred within CUG", ""
- },
- {
- 0x39, "Bearer capability not authorized", ""
- },
- {
- 0x3a, "Bearer capability not presently available", ""
- },
- {
- 0x3e, "Inconsistency in designated outgoing access information and subscriber class ", " "
- },
- {
- 0x3f, "Service or option not available, unspecified", ""
- },
- {
- 0x41, "Bearer capability not implemented", ""
- },
- {
- 0x42, "Channel type not implemented", ""
- },
- {
- 0x43, "Requested facility not implemented", ""
- },
- {
- 0x44, "Only restricted digital information bearer capability is available", ""
- },
- {
- 0x4f, "Service or option not implemented", ""
- },
- {
- 0x51, "Invalid call reference value", ""
- },
- {
- 0x52, "Identified channel does not exist", ""
- },
- {
- 0x53, "A suspended call exists, but this call identity does not", ""
- },
- {
- 0x54, "Call identity in use", ""
- },
- {
- 0x55, "No call suspended", ""
- },
- {
- 0x56, "Call having the requested call identity has been cleared", ""
- },
- {
- 0x57, "User not member of CUG", ""
- },
- {
- 0x58, "Incompatible destination", ""
- },
- {
- 0x5a, "Non-existent CUG", ""
- },
- {
- 0x5b, "Invalid transit network selection", ""
- },
- {
- 0x5f, "Invalid message, unspecified", ""
- },
- {
- 0x60, "Mandatory information element is missing", ""
- },
- {
- 0x61, "Message type non-existent or not implemented", ""
- },
- {
- 0x62, "Message not compatible with call state or message type non-existent or not implemented ", " "
- },
- {
- 0x63, "Information element/parameter non-existent or not implemented", ""
- },
- {
- 0x64, "Invalid information element contents", ""
- },
- {
- 0x65, "Message not compatible with call state", ""
- },
- {
- 0x66, "Recovery on timer expiry", ""
- },
- {
- 0x67, "Parameter non-existent or not implemented - passed on", ""
- },
- {
- 0x6e, "Message with unrecognized parameter discarded", ""
- },
- {
- 0x6f, "Protocol error, unspecified", ""
- },
- {
- 0x7f, "Interworking, unspecified", ""
- },
-};
-
-#define CVSIZE sizeof(cvlist)/sizeof(struct CauseValue)
-
-static
-int
-prcause(char *dest, byte * p)
-{
- byte *end;
- char *dp = dest;
- int i, cause;
-
- end = p + p[1] + 1;
- p += 2;
- dp += sprintf(dp, " coding ");
- dp += prbits(dp, *p, 7, 2);
- dp += sprintf(dp, " location ");
- dp += prbits(dp, *p, 4, 4);
- *dp++ = '\n';
- p = skipext(p);
-
- cause = 0x7f & *p++;
-
- /* locate cause value */
- for (i = 0; i < CVSIZE; i++)
- if (cvlist[i].nr == cause)
- break;
-
- /* display cause value if it exists */
- if (i == CVSIZE)
- dp += sprintf(dp, "Unknown cause type %x!\n", cause);
- else
- dp += sprintf(dp, " cause value %x : %s \n", cause, cvlist[i].edescr);
-
- while (!0) {
- if (p > end)
- break;
- dp += sprintf(dp, " diag attribute %d ", *p++ & 0x7f);
- dp += sprintf(dp, " rej %d ", *p & 0x7f);
- if (*p & 0x80) {
- *dp++ = '\n';
- break;
- } else
- dp += sprintf(dp, " av %d\n", (*++p) & 0x7f);
- }
- return (dp - dest);
-
-}
-
-static
-struct MessageType cause_1tr6[] =
-{
- {CAUSE_InvCRef, "Invalid Call Reference"},
- {CAUSE_BearerNotImpl, "Bearer Service Not Implemented"},
- {CAUSE_CIDunknown, "Caller Identity unknown"},
- {CAUSE_CIDinUse, "Caller Identity in Use"},
- {CAUSE_NoChans, "No Channels available"},
- {CAUSE_FacNotImpl, "Facility Not Implemented"},
- {CAUSE_FacNotSubscr, "Facility Not Subscribed"},
- {CAUSE_OutgoingBarred, "Outgoing calls barred"},
- {CAUSE_UserAccessBusy, "User Access Busy"},
- {CAUSE_NegativeGBG, "Negative GBG"},
- {CAUSE_UnknownGBG, "Unknown GBG"},
- {CAUSE_NoSPVknown, "No SPV known"},
- {CAUSE_DestNotObtain, "Destination not obtainable"},
- {CAUSE_NumberChanged, "Number changed"},
- {CAUSE_OutOfOrder, "Out Of Order"},
- {CAUSE_NoUserResponse, "No User Response"},
- {CAUSE_UserBusy, "User Busy"},
- {CAUSE_IncomingBarred, "Incoming Barred"},
- {CAUSE_CallRejected, "Call Rejected"},
- {CAUSE_NetworkCongestion, "Network Congestion"},
- {CAUSE_RemoteUser, "Remote User initiated"},
- {CAUSE_LocalProcErr, "Local Procedure Error"},
- {CAUSE_RemoteProcErr, "Remote Procedure Error"},
- {CAUSE_RemoteUserSuspend, "Remote User Suspend"},
- {CAUSE_RemoteUserResumed, "Remote User Resumed"},
- {CAUSE_UserInfoDiscarded, "User Info Discarded"}
-};
-
-int cause_1tr6_len = (sizeof(cause_1tr6) / sizeof(struct MessageType));
-
-static int
-prcause_1tr6(char *dest, byte * p)
-{
- char *dp = dest;
- int i, cause;
-
- p++;
- if (0 == *p) {
- dp += sprintf(dp, " OK (cause length=0)\n");
- return (dp - dest);
- } else if (*p > 1) {
- dp += sprintf(dp, " coding ");
- dp += prbits(dp, p[2], 7, 2);
- dp += sprintf(dp, " location ");
- dp += prbits(dp, p[2], 4, 4);
- *dp++ = '\n';
- }
- p++;
- cause = 0x7f & *p;
-
- /* locate cause value */
- for (i = 0; i < cause_1tr6_len; i++)
- if (cause_1tr6[i].nr == cause)
- break;
-
- /* display cause value if it exists */
- if (i == cause_1tr6_len)
- dp += sprintf(dp, "Unknown cause type %x!\n", cause);
- else
- dp += sprintf(dp, " cause value %x : %s \n", cause, cause_1tr6[i].descr);
-
- return (dp - dest);
-
-}
-
-static int
-prchident(char *dest, byte * p) {
- char *dp = dest;
-
- p += 2;
- dp += sprintf(dp, " octet 3 ");
- dp += prbits(dp, *p, 8, 8);
- *dp++ = '\n';
- return (dp - dest);
-}
-
-static int
-prcalled(char *dest, byte * p) {
- int l;
- char *dp = dest;
-
- p++;
- l = *p++ - 1;
- dp += sprintf(dp, " octet 3 ");
- dp += prbits(dp, *p++, 8, 8);
- *dp++ = '\n';
- dp += sprintf(dp, " number digits ");
- while (l--)
- *dp++ = *p++;
- *dp++ = '\n';
- return (dp - dest);
-}
-static int
-prcalling(char *dest, byte * p) {
- int l;
- char *dp = dest;
-
- p++;
- l = *p++ - 1;
- dp += sprintf(dp, " octet 3 ");
- dp += prbits(dp, *p, 8, 8);
- *dp++ = '\n';
- if (!(*p & 0x80)) {
- dp += sprintf(dp, " octet 3a ");
- dp += prbits(dp, *++p, 8, 8);
- *dp++ = '\n';
- l--;
- };
- p++;
-
- dp += sprintf(dp, " number digits ");
- while (l--)
- *dp++ = *p++;
- *dp++ = '\n';
- return (dp - dest);
-}
-
-static
-int
-prbearer(char *dest, byte * p)
-{
- char *dp = dest, ch;
-
- p += 2;
- dp += sprintf(dp, " octet 3 ");
- dp += prbits(dp, *p++, 8, 8);
- *dp++ = '\n';
- dp += sprintf(dp, " octet 4 ");
- dp += prbits(dp, *p, 8, 8);
- *dp++ = '\n';
- if ((*p++ & 0x1f) == 0x18) {
- dp += sprintf(dp, " octet 4.1 ");
- dp += prbits(dp, *p++, 8, 8);
- *dp++ = '\n';
- }
- /* check for user information layer 1 */
- if ((*p & 0x60) == 0x20) {
- ch = ' ';
- do {
- dp += sprintf(dp, " octet 5%c ", ch);
- dp += prbits(dp, *p, 8, 8);
- *dp++ = '\n';
- if (ch == ' ')
- ch = 'a';
- else
- ch++;
- }
- while (!(*p++ & 0x80));
- }
- /* check for user information layer 2 */
- if ((*p & 0x60) == 0x40) {
- dp += sprintf(dp, " octet 6 ");
- dp += prbits(dp, *p++, 8, 8);
- *dp++ = '\n';
- }
- /* check for user information layer 3 */
- if ((*p & 0x60) == 0x60) {
- dp += sprintf(dp, " octet 7 ");
- dp += prbits(dp, *p++, 8, 8);
- *dp++ = '\n';
- }
- return (dp - dest);
-}
-
-static int
-general(char *dest, byte * p) {
- char *dp = dest;
- char ch = ' ';
- int l, octet = 3;
-
- p++;
- l = *p++;
- /* Iterate over all octets in the information element */
- while (l--) {
- dp += sprintf(dp, " octet %d%c ", octet, ch);
- dp += prbits(dp, *p++, 8, 8);
- *dp++ = '\n';
-
- /* last octet in group? */
- if (*p & 0x80) {
- octet++;
- ch = ' ';
- } else if (ch == ' ')
- ch = 'a';
- else
- ch++;
- }
- return (dp - dest);
-}
-
-static int
-prcharge(char *dest, byte * p) {
- char *dp = dest;
- int l;
-
- p++;
- l = *p++ - 1;
- dp += sprintf(dp, " GEA ");
- dp += prbits(dp, *p++, 8, 8);
- dp += sprintf(dp, " Anzahl: ");
- /* Iterate over all octets in the * information element */
- while (l--)
- *dp++ = *p++;
- *dp++ = '\n';
- return (dp - dest);
-}
-static int
-prtext(char *dest, byte * p) {
- char *dp = dest;
- int l;
-
- p++;
- l = *p++;
- dp += sprintf(dp, " ");
- /* Iterate over all octets in the * information element */
- while (l--)
- *dp++ = *p++;
- *dp++ = '\n';
- return (dp - dest);
-}
-static int
-display(char *dest, byte * p) {
- char *dp = dest;
- char ch = ' ';
- int l, octet = 3;
-
- p++;
- l = *p++;
- /* Iterate over all octets in the * display-information element */
- dp += sprintf(dp, " \"");
- while (l--) {
- dp += sprintf(dp, "%c", *p++);
-
- /* last octet in group? */
- if (*p & 0x80) {
- octet++;
- ch = ' ';
- } else if (ch == ' ')
- ch = 'a';
-
- else
- ch++;
- }
- *dp++ = '\"';
- *dp++ = '\n';
- return (dp - dest);
-}
-
-int
-prfacility(char *dest, byte * p)
-{
- char *dp = dest;
- int l, l2;
-
- p++;
- l = *p++;
- dp += sprintf(dp, " octet 3 ");
- dp += prbits(dp, *p++, 8, 8);
- dp += sprintf(dp, "\n");
- l -= 1;
-
- while (l > 0) {
- dp += sprintf(dp, " octet 4 ");
- dp += prbits(dp, *p++, 8, 8);
- dp += sprintf(dp, "\n");
- dp += sprintf(dp, " octet 5 %d\n", l2 = *p++ & 0x7f);
- l -= 2;
- dp += sprintf(dp, " contents ");
- while (l2--) {
- dp += sprintf(dp, "%2x ", *p++);
- l--;
- }
- dp += sprintf(dp, "\n");
- }
-
- return (dp - dest);
-}
-
-static
-struct InformationElement {
- byte nr;
- char *descr;
- int (*f) (char *, byte *);
-} ielist[] = {
-
- {
- 0x00, "Segmented message", general
- },
- {
- 0x04, "Bearer capability", prbearer
- },
- {
- 0x08, "Cause", prcause
- },
- {
- 0x10, "Call identity", general
- },
- {
- 0x14, "Call state", general
- },
- {
- 0x18, "Channel identification", prchident
- },
- {
- 0x1c, "Facility", prfacility
- },
- {
- 0x1e, "Progress indicator", general
- },
- {
- 0x20, "Network-specific facilities", general
- },
- {
- 0x27, "Notification indicator", general
- },
- {
- 0x28, "Display", display
- },
- {
- 0x29, "Date/Time", general
- },
- {
- 0x2c, "Keypad facility", general
- },
- {
- 0x34, "Signal", general
- },
- {
- 0x40, "Information rate", general
- },
- {
- 0x42, "End-to-end delay", general
- },
- {
- 0x43, "Transit delay selection and indication", general
- },
- {
- 0x44, "Packet layer binary parameters", general
- },
- {
- 0x45, "Packet layer window size", general
- },
- {
- 0x46, "Packet size", general
- },
- {
- 0x47, "Closed user group", general
- },
- {
- 0x4a, "Reverse charge indication", general
- },
- {
- 0x6c, "Calling party number", prcalling
- },
- {
- 0x6d, "Calling party subaddress", general
- },
- {
- 0x70, "Called party number", prcalled
- },
- {
- 0x71, "Called party subaddress", general
- },
- {
- 0x74, "Redirecting number", general
- },
- {
- 0x78, "Transit network selection", general
- },
- {
- 0x79, "Restart indicator", general
- },
- {
- 0x7c, "Low layer compatibility", general
- },
- {
- 0x7d, "High layer compatibility", general
- },
- {
- 0x7e, "User-user", general
- },
- {
- 0x7f, "Escape for extension", general
- },
-};
-
-
-#define IESIZE sizeof(ielist)/sizeof(struct InformationElement)
-
-static struct InformationElement we_0[] =
-{
- {WE0_cause, "Cause", prcause_1tr6},
- {WE0_connAddr, "Connecting Address", prcalled},
- {WE0_callID, "Call IDentity", general},
- {WE0_chanID, "Channel IDentity", general},
- {WE0_netSpecFac, "Network Specific Facility", general},
- {WE0_display, "Display", general},
- {WE0_keypad, "Keypad", general},
- {WE0_origAddr, "Origination Address", prcalled},
- {WE0_destAddr, "Destination Address", prcalled},
- {WE0_userInfo, "User Info", general}
-};
-
-static int we_0_len = (sizeof(we_0) / sizeof(struct InformationElement));
-
-static struct InformationElement we_6[] =
-{
- {WE6_serviceInd, "Service Indicator", general},
- {WE6_chargingInfo, "Charging Information", prcharge},
- {WE6_date, "Date", prtext},
- {WE6_facSelect, "Facility Select", general},
- {WE6_facStatus, "Facility Status", general},
- {WE6_statusCalled, "Status Called", general},
- {WE6_addTransAttr, "Additional Transmission Attributes", general}
-};
-static int we_6_len = (sizeof(we_6) / sizeof(struct InformationElement));
-
-void
-dlogframe(struct IsdnCardState *sp, byte * buf, int size, char *comment) {
- byte *bend = buf + size;
- char *dp;
- int i, cs = 0, cs_old = 0, cs_fest = 0;
-
- /* display header */
- dp = sp->dlogspace;
- dp += sprintf(dp, "%s\n", comment);
-
- {
- byte *p = buf;
- dp += sprintf(dp, "hex: ");
- while (p < bend)
- dp += sprintf(dp, "%02x ", *p++);
- dp += sprintf(dp, "\n");
- teles_putstatus(sp->dlogspace);
- dp = sp->dlogspace;
- }
- if ((0xfe & buf[0]) == PROTO_DIS_N0) { /* 1TR6 */
- /* locate message type */
- if (buf[0] == PROTO_DIS_N0) { /* N0 */
- for (i = 0; i < mt_n0_len; i++)
- if (mt_n0[i].nr == buf[3])
- break;
- /* display message type iff it exists */
- if (i == mt_n0_len)
- dp += sprintf(dp, "Unknown message type N0 %x!\n", buf[3]);
- else
- dp += sprintf(dp, "call reference %d size %d message type %s\n",
- buf[2], size, mt_n0[i].descr);
- } else { /* N1 */
- for (i = 0; i < mt_n1_len; i++)
- if (mt_n1[i].nr == buf[3])
- break;
- /* display message type iff it exists */
- if (i == mt_n1_len)
- dp += sprintf(dp, "Unknown message type N1 %x!\n", buf[3]);
- else
- dp += sprintf(dp, "call reference %d size %d message type %s\n",
- buf[2], size, mt_n1[i].descr);
- }
-
- /* display each information element */
- buf += 4;
- while (buf < bend) {
- /* Is it a single octet information element? */
- if (*buf & 0x80) {
- switch ((*buf >> 4) & 7) {
- case 1:
- dp += sprintf(dp, " Shift %x\n", *buf & 0xf);
- cs_old = cs;
- cs = *buf & 7;
- cs_fest = *buf & 8;
- break;
- case 3:
- dp += sprintf(dp, " Congestion level %x\n", *buf & 0xf);
- break;
- case 2:
- if (*buf == 0xa0) {
- dp += sprintf(dp, " More data\n");
- break;
- }
- if (*buf == 0xa1) {
- dp += sprintf(dp, " Sending complete\n");
- }
- break;
- /* fall through */
- default:
- dp += sprintf(dp, " Reserved %x\n", *buf);
- break;
- }
- buf++;
- continue;
- }
- /* No, locate it in the table */
- if (cs == 0) {
- for (i = 0; i < we_0_len; i++)
- if (*buf == we_0[i].nr)
- break;
-
- /* When found, give appropriate msg */
- if (i != we_0_len) {
- dp += sprintf(dp, " %s\n", we_0[i].descr);
- dp += we_0[i].f(dp, buf);
- } else
- dp += sprintf(dp, " Codeset %d attribute %x attribute size %d\n", cs, *buf, buf[1]);
- } else if (cs == 6) {
- for (i = 0; i < we_6_len; i++)
- if (*buf == we_6[i].nr)
- break;
-
- /* When found, give appropriate msg */
- if (i != we_6_len) {
- dp += sprintf(dp, " %s\n", we_6[i].descr);
- dp += we_6[i].f(dp, buf);
- } else
- dp += sprintf(dp, " Codeset %d attribute %x attribute size %d\n", cs, *buf, buf[1]);
- } else
- dp += sprintf(dp, " Unknown Codeset %d attribute %x attribute size %d\n", cs, *buf, buf[1]);
- /* Skip to next element */
- if (cs_fest == 8) {
- cs = cs_old;
- cs_old = 0;
- cs_fest = 0;
- }
- buf += buf[1] + 2;
- }
- } else if (buf[0]==PROTO_EURO) { /* EURO */
- /* locate message type */
- for (i = 0; i < MTSIZE; i++)
- if (mtlist[i].nr == buf[3])
- break;
-
- /* display message type iff it exists */
- if (i == MTSIZE)
- dp += sprintf(dp, "Unknown message type %x!\n", buf[3]);
- else
- dp += sprintf(dp, "call reference %d size %d message type %s\n",
- buf[2], size, mtlist[i].descr);
-
- /* display each information element */
- buf += 4;
- while (buf < bend) {
- /* Is it a single octet information element? */
- if (*buf & 0x80) {
- switch ((*buf >> 4) & 7) {
- case 1:
- dp += sprintf(dp, " Shift %x\n", *buf & 0xf);
- break;
- case 3:
- dp += sprintf(dp, " Congestion level %x\n", *buf & 0xf);
- break;
- case 5:
- dp += sprintf(dp, " Repeat indicator %x\n", *buf & 0xf);
- break;
- case 2:
- if (*buf == 0xa0) {
- dp += sprintf(dp, " More data\n");
- break;
- }
- if (*buf == 0xa1) {
- dp += sprintf(dp, " Sending complete\n");
- }
- break;
- /* fall through */
- default:
- dp += sprintf(dp, " Reserved %x\n", *buf);
- break;
- }
- buf++;
- continue;
- }
- /* No, locate it in the table */
- for (i = 0; i < IESIZE; i++)
- if (*buf == ielist[i].nr)
- break;
-
- /* When not found, give appropriate msg */
- if (i != IESIZE) {
- dp += sprintf(dp, " %s\n", ielist[i].descr);
- dp += ielist[i].f(dp, buf);
- } else
- dp += sprintf(dp, " attribute %x attribute size %d\n", *buf, buf[1]);
-
- /* Skip to next element */
- buf += buf[1] + 2;
- }
- }
- else dp += sprintf(dp,"Unnown frame type %.2x, ignored\n",buf[0]);
-
- dp += sprintf(dp, "\n");
- teles_putstatus(sp->dlogspace);
-}
+++ /dev/null
-/* $Id: tei.c,v 1.1 1996/04/13 10:28:25 fritz Exp $
- *
- * $Log: tei.c,v $
- * Revision 1.1 1996/04/13 10:28:25 fritz
- * Initial revision
- *
- *
- */
-#define __NO_VERSION__
-#include "teles.h"
-
-extern struct IsdnCard cards[];
-extern int nrcards;
-
-static struct PStack *
-findces(struct PStack *st, int ces)
-{
- struct PStack *ptr = *(st->l1.stlistp);
-
- while (ptr)
- if (ptr->l2.ces == ces)
- return (ptr);
- else
- ptr = ptr->next;
- return (NULL);
-}
-
-static struct PStack *
-findtei(struct PStack *st, int tei)
-{
- struct PStack *ptr = *(st->l1.stlistp);
-
- if (tei == 127)
- return (NULL);
-
- while (ptr)
- if (ptr->l2.tei == tei)
- return (ptr);
- else
- ptr = ptr->next;
- return (NULL);
-}
-
-void
-tei_handler(struct PStack *st,
- byte pr, struct BufHeader *ibh)
-{
- byte *bp;
- unsigned int tces;
- struct PStack *otsp, *ptr;
- unsigned int data;
-
- if (st->l2.debug)
- printk(KERN_DEBUG "teihandler %d\n", pr);
-
- switch (pr) {
- case (MDL_ASSIGN):
- data = (unsigned int) ibh;
- BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 6);
- if (!ibh)
- return;
- bp = DATAPTR(ibh);
- bp += st->l2.uihsize;
- bp[0] = 0xf;
- bp[1] = data >> 8;
- bp[2] = data & 0xff;
- bp[3] = 0x1;
- bp[4] = 0xff;
- ibh->datasize = 8;
- st->l3.l3l2(st, DL_UNIT_DATA, ibh);
- break;
- case (DL_UNIT_DATA):
- bp = DATAPTR(ibh);
- bp += 3;
- if (bp[0] != 0xf)
- break;
- switch (bp[3]) {
- case (2):
- tces = (bp[1] << 8) | bp[2];
- BufPoolRelease(ibh);
- if (st->l3.debug)
- printk(KERN_DEBUG "tei identity assigned for %d=%d\n", tces,
- bp[4] >> 1);
- if ((otsp = findces(st, tces)))
- otsp->ma.teil2(otsp, MDL_ASSIGN,
- (void *)(bp[4] >> 1));
- break;
- case (4):
- if (st->l3.debug)
- printk(KERN_DEBUG "checking identity for %d\n", bp[4] >> 1);
- if (bp[4] >> 1 == 0x7f) {
- BufPoolRelease(ibh);
- ptr = *(st->l1.stlistp);
- while (ptr) {
- if ((ptr->l2.tei & 0x7f) != 0x7f) {
- if (BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 7))
- break;
- bp = DATAPTR(ibh);
- bp += 3;
- bp[0] = 0xf;
- bp[1] = ptr->l2.ces >> 8;
- bp[2] = ptr->l2.ces & 0xff;
- bp[3] = 0x5;
- bp[4] = (ptr->l2.tei << 1) | 1;
- ibh->datasize = 8;
- st->l3.l3l2(st, DL_UNIT_DATA, ibh);
- }
- ptr = ptr->next;
- }
- } else {
- otsp = findtei(st, bp[4] >> 1);
- BufPoolRelease(ibh);
- if (!otsp)
- break;
- if (st->l3.debug)
- printk(KERN_DEBUG "ces is %d\n", otsp->l2.ces);
- if (BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 7))
- break;
- bp = DATAPTR(ibh);
- bp += 3;
- bp[0] = 0xf;
- bp[1] = otsp->l2.ces >> 8;
- bp[2] = otsp->l2.ces & 0xff;
- bp[3] = 0x5;
- bp[4] = (otsp->l2.tei << 1) | 1;
- ibh->datasize = 8;
- st->l3.l3l2(st, DL_UNIT_DATA, ibh);
- }
- break;
- default:
- BufPoolRelease(ibh);
- if (st->l3.debug)
- printk(KERN_DEBUG "tei message unknown %d ai %d\n", bp[3], bp[4] >> 1);
- }
- break;
- default:
- printk(KERN_WARNING "tei handler unknown primitive %d\n", pr);
- break;
- }
-}
-
-unsigned int
-randomces(void)
-{
- int x = jiffies & 0xffff;
-
- return (x);
-}
-
-static void
-tei_man(struct PStack *sp, int i, void *v)
-{
- printk(KERN_DEBUG "tei_man\n");
-}
-
-static void
-tei_l2tei(struct PStack *st, int pr, void *arg)
-{
- struct IsdnCardState *sp = st->l1.hardware;
-
- tei_handler(sp->teistack, pr, arg);
-}
-
-void
-setstack_tei(struct PStack *st)
-{
- st->l2.l2tei = tei_l2tei;
-}
-
-static void
-init_tei(struct IsdnCardState *sp, int protocol)
-{
- struct PStack *st;
- char tmp[128];
-
-#define DIRTY_HACK_AGAINST_SIGSEGV
-
- st = (struct PStack *) Smalloc(sizeof(struct PStack), GFP_KERNEL,
- "struct PStack");
-
-#ifdef DIRTY_HACK_AGAINST_SIGSEGV
- sp->teistack = st; /* struct is not initialized yet */
- sp->teistack->protocol = protocol; /* struct is not initialized yet */
-#endif /* DIRTY_HACK_AGAINST_SIGSEGV */
-
-
- setstack_teles(st, sp);
-
- st->l2.extended = !0;
- st->l2.laptype = LAPD;
- st->l2.window = 1;
- st->l2.orig = !0;
- st->protocol = protocol;
-
-/*
- * the following is not necessary for tei mng. (broadcast only)
- */
-
- st->l2.t200 = 500; /* 500 milliseconds */
- st->l2.n200 = 4; /* try 4 times */
-
- st->l2.sap = 63;
- st->l2.tei = 127;
-
- sprintf(tmp, "Card %d tei ", sp->cardnr);
- setstack_isdnl2(st, tmp);
- st->l2.debug = 0;
- st->l3.debug = 0;
-
- st->ma.manl2(st, MDL_NOTEIPROC, NULL);
-
- st->l2.l2l3 = (void *) tei_handler;
- st->l1.l1man = tei_man;
- st->l2.l2man = tei_man;
- st->l4.l2writewakeup = NULL;
-
- teles_addlist(sp, st);
- sp->teistack = st;
-}
-
-static void
-release_tei(struct IsdnCardState *sp)
-{
- struct PStack *st = sp->teistack;
-
- teles_rmlist(sp, st);
- Sfree((void *) st);
-}
-
-void
-TeiNew(void)
-{
- int i;
-
- for (i = 0; i < nrcards; i++)
- if (cards[i].sp)
- init_tei(cards[i].sp, cards[i].protocol);
-}
-
-void
-TeiFree(void)
-{
- int i;
-
- for (i = 0; i < nrcards; i++)
- if (cards[i].sp)
- release_tei(cards[i].sp);
-}
+++ /dev/null
-/* $Id: teles.h,v 1.3 1997/02/11 01:40:36 keil Exp $
- *
- * $Log: teles.h,v $
- * Revision 1.3 1997/02/11 01:40:36 keil
- * New Param structure
- *
- * Revision 1.2 1996/04/30 21:52:04 isdn4dev
- * SPV for 1TR6 - Karsten
- *
- * Revision 1.1 1996/04/13 10:29:00 fritz
- * Initial revision
- *
- *
- */
-#include <linux/module.h>
-#include <linux/version.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/major.h>
-#include <asm/segment.h>
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/malloc.h>
-#include <linux/mm.h>
-#include <linux/mman.h>
-#include <linux/ioport.h>
-#include <linux/timer.h>
-#include <linux/wait.h>
-#include <linux/isdnif.h>
-#include <linux/tty.h>
-
-#define PH_ACTIVATE 1
-#define PH_DATA 2
-#define PH_DEACTIVATE 3
-
-#define MDL_ASSIGN 4
-#define DL_UNIT_DATA 5
-#define SC_STARTUP 6
-#define CC_ESTABLISH 7
-#define DL_ESTABLISH 8
-#define DL_DATA 9
-#define CC_S_STATUS_ENQ 10
-
-#define CC_CONNECT 15
-#define CC_CONNECT_ACKNOWLEDGE 16
-#define CO_EOF 17
-#define SC_DISCONNECT 18
-#define CO_DTMF 19
-#define DL_RELEASE 20
-
-#define CO_ALARM 22
-#define CC_REJECT 23
-
-#define CC_SETUP_REQ 24
-#define CC_SETUP_CNF 25
-#define CC_SETUP_IND 26
-#define CC_SETUP_RSP 27
-#define CC_SETUP_COMPLETE_IND 28
-
-#define CC_DISCONNECT_REQ 29
-#define CC_DISCONNECT_IND 30
-
-#define CC_RELEASE_CNF 31
-#define CC_RELEASE_IND 32
-#define CC_RELEASE_REQ 33
-
-#define CC_REJECT_REQ 34
-
-#define CC_PROCEEDING_IND 35
-
-#define CC_DLRL 36
-#define CC_DLEST 37
-
-#define CC_ALERTING_REQ 38
-#define CC_ALERTING_IND 39
-
-#define DL_STOP 40
-#define DL_START 41
-
-#define MDL_NOTEIPROC 46
-
-#define LC_ESTABLISH 47
-#define LC_RELEASE 48
-
-#define PH_REQUEST_PULL 49
-#define PH_PULL_ACK 50
-#define PH_DATA_PULLED 51
-#define CC_INFO_CHARGE 52
-
-/*
- * Message-Types
- */
-
-#define MT_ALERTING 0x01
-#define MT_CALL_PROCEEDING 0x02
-#define MT_CONNECT 0x07
-#define MT_CONNECT_ACKNOWLEDGE 0x0f
-#define MT_PROGRESS 0x03
-#define MT_SETUP 0x05
-#define MT_SETUP_ACKNOWLEDGE 0x0d
-#define MT_RESUME 0x26
-#define MT_RESUME_ACKNOWLEDGE 0x2e
-#define MT_RESUME_REJECT 0x22
-#define MT_SUSPEND 0x25
-#define MT_SUSPEND_ACKNOWLEDGE 0x2d
-#define MT_SUSPEND_REJECT 0x21
-#define MT_USER_INFORMATION 0x20
-#define MT_DISCONNECT 0x45
-#define MT_RELEASE 0x4d
-#define MT_RELEASE_COMPLETE 0x5a
-#define MT_RESTART 0x46
-#define MT_RESTART_ACKNOWLEDGE 0x4e
-#define MT_SEGMENT 0x60
-#define MT_CONGESTION_CONTROL 0x79
-#define MT_INFORMATION 0x7b
-#define MT_FACILITY 0x62
-#define MT_NOTIFY 0x6e
-#define MT_STATUS 0x7d
-#define MT_STATUS_ENQUIRY 0x75
-
-#define IE_CAUSE 0x08
-
-struct HscxIoctlArg {
- int channel;
- int mode;
- int transbufsize;
-};
-
-#ifdef __KERNEL__
-
-#undef DEBUG_MAGIC
-
-#define HSCX_SBUF_ORDER 1
-#define HSCX_SBUF_BPPS 2
-#define HSCX_SBUF_MAXPAGES 3
-
-#define HSCX_RBUF_ORDER 1
-#define HSCX_RBUF_BPPS 2
-#define HSCX_RBUF_MAXPAGES 3
-
-#define HSCX_SMALLBUF_ORDER 0
-#define HSCX_SMALLBUF_BPPS 40
-#define HSCX_SMALLBUF_MAXPAGES 1
-
-#define ISAC_SBUF_ORDER 0
-#define ISAC_SBUF_BPPS 16
-#define ISAC_SBUF_MAXPAGES 1
-
-#define ISAC_RBUF_ORDER 0
-#define ISAC_RBUF_BPPS 16
-#define ISAC_RBUF_MAXPAGES 1
-
-#define ISAC_SMALLBUF_ORDER 0
-#define ISAC_SMALLBUF_BPPS 40
-#define ISAC_SMALLBUF_MAXPAGES 1
-
-#define byte unsigned char
-
-#define MAX_WINDOW 8
-
-byte *Smalloc(int size, int pr, char *why);
-void Sfree(byte * ptr);
-
-/*
- * Statemachine
- */
-struct Fsm {
- int *jumpmatrix;
- int state_count, event_count;
- char **strEvent, **strState;
-};
-
-struct FsmInst {
- struct Fsm *fsm;
- int state;
- int debug;
- void *userdata;
- int userint;
- void (*printdebug) (struct FsmInst *, char *);
-};
-
-struct FsmNode {
- int state, event;
- void (*routine) (struct FsmInst *, int, void *);
-};
-
-struct FsmTimer {
- struct FsmInst *fi;
- struct timer_list tl;
- int event;
- void *arg;
-};
-
-struct BufHeader {
-#ifdef DEBUG_MAGIC
- int magic;
-#endif
- struct BufHeader *next;
- struct BufPool *bp;
- int datasize;
- byte primitive, where;
- void *heldby;
-};
-
-struct Pages {
- struct Pages *next;
-};
-
-struct BufPool {
-#ifdef DEBUG_MAGIC
- int magic;
-#endif
- struct BufHeader *freelist;
- struct Pages *pageslist;
- int pageorder;
- int pagescount;
- int bpps;
- int bufsize;
- int maxpages;
-};
-
-struct BufQueue {
-#ifdef DEBUG_MAGIC
- int magic;
-#endif
- struct BufHeader *head, *tail;
-};
-
-struct Layer1 {
- void *hardware;
- int hscx;
- struct BufPool *sbufpool, *rbufpool, *smallpool;
- struct PStack **stlistp;
- int act_state;
- void (*l1l2) (struct PStack *, int, struct BufHeader *);
- void (*l1man) (struct PStack *, int, void *);
- int hscxmode, hscxchannel, requestpull;
-};
-
-struct Layer2 {
- int sap, tei, ces;
- int extended, laptype;
- int uihsize, ihsize;
- int vs, va, vr;
- struct BufQueue i_queue;
- int window, orig;
- int rejexp;
- int debug;
- struct BufHeader *windowar[MAX_WINDOW];
- int sow;
- struct FsmInst l2m;
- void (*l2l1) (struct PStack *, int, struct BufHeader *);
- void (*l2l1discardq) (struct PStack *, int, void *, int);
- void (*l2man) (struct PStack *, int, void *);
- void (*l2l3) (struct PStack *, int, void *);
- void (*l2tei) (struct PStack *, int, void *);
- struct FsmTimer t200_timer, t203_timer;
- int t200, n200, t203;
- int rc, t200_running;
- char debug_id[32];
-};
-
-struct Layer3 {
- void (*l3l4) (struct PStack *, int, struct BufHeader *);
- void (*l3l2) (struct PStack *, int, void *);
- int state, callref;
- int debug;
-};
-
-struct Layer4 {
- void (*l4l3) (struct PStack *, int, void *);
- void *userdata;
- void (*l1writewakeup) (struct PStack *);
- void (*l2writewakeup) (struct PStack *);
-};
-
-struct Management {
- void (*manl1) (struct PStack *, int, void *);
- void (*manl2) (struct PStack *, int, void *);
- void (*teil2) (struct PStack *, int, void *);
-};
-
-struct Param {
- int cause;
- int bchannel;
- int callref; /* TEI-Number */
- setup_parm setup; /* from isdnif.h numbers and Serviceindicator */
- int chargeinfo; /* Charge Info - only for 1tr6 in
- * the moment
- */
- int spv; /* SPV Flag */
-};
-
-struct PStack {
- struct PStack *next;
- struct Layer1 l1;
- struct Layer2 l2;
- struct Layer3 l3;
- struct Layer4 l4;
- struct Management ma;
- struct Param *pa;
- int protocol; /* EDSS1 or 1TR6 */
-};
-
-struct HscxState {
- byte *membase;
- int iobase;
- int inuse, init, active;
- struct BufPool sbufpool, rbufpool, smallpool;
- struct IsdnCardState *sp;
- int hscx, mode;
- int transbufsize, receive;
- struct BufHeader *rcvibh, *xmtibh;
- int rcvptr, sendptr;
- struct PStack *st;
- struct tq_struct tqueue;
- int event;
- struct BufQueue rq, sq;
- int releasebuf;
-#ifdef DEBUG_MAGIC
- int magic; /* 301270 */
-#endif
-};
-
-struct IsdnCardState {
-#ifdef DEBUG_MAGIC
- int magic;
-#endif
- byte *membase;
- int iobase;
- struct BufPool sbufpool, rbufpool, smallpool;
- struct PStack *stlist;
- struct BufHeader *xmtibh, *rcvibh;
- int rcvptr, sendptr;
- int event;
- struct tq_struct tqueue;
- int ph_active;
- struct BufQueue rq, sq;
-
- int cardnr, ph_state;
- struct PStack *teistack;
- struct HscxState hs[2];
-
- int dlogflag;
- char *dlogspace;
- int debug;
- int releasebuf;
-};
-
-struct IsdnCard {
- byte *membase;
- int interrupt;
- unsigned int iobase;
- int protocol; /* EDSS1 or 1TR6 */
- struct IsdnCardState *sp;
-};
-
-#define DATAPTR(x) ((byte *)x+sizeof(struct BufHeader))
-
-#define LAPD 0
-#define LAPB 1
-
-void BufPoolInit(struct BufPool *bp, int order, int bpps,
- int maxpages);
-int BufPoolAdd(struct BufPool *bp, int priority);
-void BufPoolFree(struct BufPool *bp);
-int BufPoolGet(struct BufHeader **bh,
- struct BufPool *bp, int priority, void *heldby, int where);
-void BufPoolRelease(struct BufHeader *bh);
-void BufQueueLink(struct BufQueue *bq,
- struct BufHeader *bh);
-int BufQueueUnlink(struct BufHeader **bh, struct BufQueue *bq);
-void BufQueueInit(struct BufQueue *bq);
-void BufQueueRelease(struct BufQueue *bq);
-void BufQueueDiscard(struct BufQueue *q, int pr, void *heldby,
- int releasetoo);
-int BufQueueLength(struct BufQueue *bq);
-void BufQueueLinkFront(struct BufQueue *bq,
- struct BufHeader *bh);
-
-void l2down(struct PStack *st,
- byte pr, struct BufHeader *ibh);
-void l2up(struct PStack *st,
- byte pr, struct BufHeader *ibh);
-void acceptph(struct PStack *st,
- struct BufHeader *ibh);
-void setstack_isdnl2(struct PStack *st, char *debug_id);
-int teles_inithardware(void);
-void teles_closehardware(void);
-
-void setstack_teles(struct PStack *st, struct IsdnCardState *sp);
-unsigned int randomces(void);
-void setstack_isdnl3(struct PStack *st);
-void teles_addlist(struct IsdnCardState *sp,
- struct PStack *st);
-void releasestack_isdnl2(struct PStack *st);
-void teles_rmlist(struct IsdnCardState *sp,
- struct PStack *st);
-void newcallref(struct PStack *st);
-
-int ll_init(void);
-void ll_stop(void), ll_unload(void);
-int setstack_hscx(struct PStack *st, struct HscxState *hs);
-void modehscx(struct HscxState *hs, int mode, int ichan);
-byte *findie(byte * p, int size, byte ie, int wanted_set);
-int getcallref(byte * p);
-
-void FsmNew(struct Fsm *fsm,
- struct FsmNode *fnlist, int fncount);
-void FsmFree(struct Fsm *fsm);
-int FsmEvent(struct FsmInst *fi,
- int event, void *arg);
-void FsmChangeState(struct FsmInst *fi,
- int newstate);
-void FsmInitTimer(struct FsmInst *fi, struct FsmTimer *ft);
-int FsmAddTimer(struct FsmTimer *ft,
- int millisec, int event, void *arg, int where);
-void FsmDelTimer(struct FsmTimer *ft, int where);
-int FsmTimerRunning(struct FsmTimer *ft);
-void jiftime(char *s, long mark);
-
-void CallcNew(void);
-void CallcFree(void);
-int CallcNewChan(void);
-void CallcFreeChan(void);
-int teles_command(isdn_ctrl * ic);
-int teles_writebuf(int id, int chan, const u_char * buf, int count, int user);
-void teles_putstatus(char *buf);
-void teles_reportcard(int cardnr);
-int ListLength(struct BufHeader *ibh);
-void dlogframe(struct IsdnCardState *sp, byte * p, int size, char *comment);
-void iecpy(byte * dest, byte * iestart, int ieoffset);
-void setstack_transl2(struct PStack *st);
-void releasestack_transl2(struct PStack *st);
-void close_hscxstate(struct HscxState *);
-void setstack_tei(struct PStack *st);
-
-struct LcFsm {
- struct FsmInst lcfi;
- int type;
- struct Channel *ch;
- void (*lccall) (struct LcFsm *, int, void *);
- struct PStack *st;
- int l2_establish;
- int l2_start;
- struct FsmTimer act_timer;
- char debug_id[32];
-};
-
-struct Channel {
- struct PStack ds, is;
- struct IsdnCardState *sp;
- int hscx;
- int chan;
- int incoming;
- struct FsmInst fi;
- struct LcFsm lc_d, lc_b;
- struct Param para;
- int debug;
-#ifdef DEBUG_MAGIC
- int magic; /* 301272 */
-#endif
- int l2_protocol, l2_active_protocol;
- int l2_primitive, l2_headersize;
- int data_open;
- int outcallref;
- int impair;
-};
-
-#define PART_SIZE(order,bpps) (( (PAGE_SIZE<<order) -\
- sizeof(void *))/bpps)
-#define BUFFER_SIZE(order,bpps) (PART_SIZE(order,bpps)-\
- sizeof(struct BufHeader))
-
-#endif
-
-void Isdnl2New(void);
-void Isdnl2Free(void);
-void TeiNew(void);
-void TeiFree(void);
-
-
-
-
* Avoid timer-based retransmission conflicts.
*/
- if (set_bit(0, (void*)&dev->tbusy) != 0)
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
{
restore_flags(flags);
printk("%s: Transmitter access conflict.\n", dev->name);
return FALSE;
/* Avoid contention */
- if (set_bit(1, &adapter->send_pcb_semaphore)) {
+ if (test_and_set_bit(1, &adapter->send_pcb_semaphore)) {
if (elp_debug >= 3) {
printk("%s: send_pcb entered while threaded\n", dev->name);
}
}
if (pcb->command == CMD_RECEIVE_PACKET_COMPLETE) {
- if (set_bit(0, (void *) &adapter->busy)) {
+ if (test_and_set_bit(0, (void *) &adapter->busy)) {
if (backlog_next(adapter->rx_backlog.in) == adapter->rx_backlog.out) {
set_hsf(dev, HSF_PCB_NAK);
printk("%s: PCB rejected, transfer in progress and backlog full\n", dev->name);
}
/* if this happens, we die */
- if (set_bit(0, (void *) &adapter->dmaing))
+ if (test_and_set_bit(0, (void *) &adapter->dmaing))
printk("%s: rx blocked, DMA in progress, dir %d\n", dev->name, adapter->current_dma.direction);
skb->dev = dev;
*/
unsigned int nlen = (((skb->len < 60) ? 60 : skb->len) + 1) & (~1);
- if (set_bit(0, (void *) &adapter->busy)) {
+ if (test_and_set_bit(0, (void *) &adapter->busy)) {
if (elp_debug >= 2)
printk("%s: transmit blocked\n", dev->name);
return FALSE;
return FALSE;
}
/* if this happens, we die */
- if (set_bit(0, (void *) &adapter->dmaing))
+ if (test_and_set_bit(0, (void *) &adapter->dmaing))
printk("%s: tx: DMA %d in progress\n", dev->name, adapter->current_dma.direction);
adapter->current_dma.direction = 1;
if (elp_debug >= 3)
printk("%s: request to send packet of length %d\n", dev->name, (int) skb->len);
- if (set_bit(0, (void *) &dev->tbusy)) {
+ if (test_and_set_bit(0, (void *) &dev->tbusy)) {
printk("%s: transmitter access conflict\n", dev->name);
return 1;
}
}
/* Block a timer-based transmit from overlapping. */
- if (set_bit(0, (void*)&dev->tbusy) != 0)
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
printk("%s: Transmitter access conflict.\n", dev->name);
else
{
#endif
#endif
/* Avoid timer-based retransmission conflicts. */
- if (set_bit(0, (void*)&dev->tbusy) != 0)
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
printk("%s: Transmitter access conflict.\n", dev->name);
else {
lp->stats.tx_bytes+=skb->len;
return 0;
}
- if (set_bit(0, (void*)&dev->tbusy) != 0) {
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
printk("%s: Transmitter access conflict.\n", dev->name);
} else {
memcpy((char *)p->xmit_cbuffs[p->xmit_count],(char *)(skb->data),skb->len);
/* Block a timer-based transmit from overlapping. This could better be
done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
If this ever occurs the queue layer is doing something evil! */
- if (set_bit(0, (void*)&dev->tbusy) != 0) {
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
printk("%s: Transmitter access conflict.\n", dev->name);
return 1;
}
#ifdef OLD_METHOD
dev->tbusy = 1;
#else
- if (set_bit (0, (void *) &dev->tbusy) != 0) {
+ if (test_and_set_bit (0, (void *) &dev->tbusy) != 0) {
printk ("Transmitter access conflict.\n");
return -1;
}
/* Block a timer-based transmit from overlapping. This could better be
done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
- if (set_bit(0, (void*)&dev->tbusy) != 0)
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
printk("%s: Transmitter access conflict.\n", dev->name);
else
{
/* Block a timer-based transmit from overlapping. This could better be
done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
- if (set_bit(0, (void*)&dev->tbusy) != 0)
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
{
BUGMSG(D_NORMAL,"transmitter called with busy bit set! (status=%Xh, inTX=%d, tickssofar=%ld)\n",
ARCSTATUS,lp->intx,jiffies-dev->trans_start);
/* Block a timer-based transmit from overlapping. This could better be
done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
- if (set_bit(0, (void*)&dev->tbusy) != 0) {
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
printk("%s: Transmitter access conflict.\n", dev->name);
return(1);
}
- if (set_bit(0, (void*)&priv->lock) != 0) {
+ if (test_and_set_bit(0, (void*)&priv->lock) != 0) {
if (ariadne_debug > 0)
printk("%s: tx queue lock!.\n", dev->name);
/* don't clear dev->tbusy flag. */
/* Block a timer-based transmit from overlapping. This could better be
done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
- if (set_bit(0, (void*)&dev->tbusy) != 0)
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
printk("%s: Transmitter access conflict.\n", dev->name);
else {
short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
/* Block a timer-based transmit from overlapping. This could better be
done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
- if (set_bit( 0, (void*)&dev->tbusy ) != 0) {
+ if (test_and_set_bit( 0, (void*)&dev->tbusy ) != 0) {
DPRINTK( 0, ( "%s: Transmitter access conflict.\n", dev->name ));
return 1;
}
- if (set_bit( 0, (void*)&lp->lock ) != 0) {
+ if (test_and_set_bit( 0, (void*)&lp->lock ) != 0) {
DPRINTK( 0, ( "%s: tx queue lock!.\n", dev->name ));
/* don't clear dev->tbusy flag. */
return 1;
/* Block a timer-based transmit from overlapping. This could better be
done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
- if (set_bit(0, (void*)&dev->tbusy) != 0)
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
printk("%s: Transmitter access conflict.\n", dev->name);
else {
short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
/* Block a timer-based transmit from overlapping. This could better be
done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
- if (set_bit(0, (void*)&dev->tbusy) != 0)
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
printk("%s: Transmitter access conflict.\n", dev->name);
else {
struct net_local *lp = (struct net_local *)dev->priv;
Copyright 1994, 1995 Digital Equipment Corporation.
- This software may be used and distributed according to the terms of
- the GNU Public License, incorporated herein by reference.
+ Testing resources for this driver have been made available
+ in part by NASA Ames Research Center (mjacob@nas.nasa.gov).
+
+ The author may be reached at davies@maniac.ultranet.com.
+
+ 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 of the License, or (at your
+ option) any later version.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ 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.
Originally, this driver was written for the Digital Equipment
Corporation series of EtherWORKS ethernet cards:
DE450 TP/COAX/AUI PCI
DE500 10/100 PCI Fasternet
- but it will now attempt to support all cards which conform to the
- Digital Semiconductor SROM Specification. The driver currently
+ but it will now attempt to support all cards which conform to the
+ Digital Semiconductor SROM Specification. The driver currently
recognises the following chips:
DC21040 (no SROM)
SMC8432
SMC9332 (w/new SROM)
ZNYX31[45]
+ ZNYX346 10/100 4 port (can act as a 10/100 bridge!)
The driver has been tested on a relatively busy network using the DE425,
DE434, DE435 and DE500 cards and benchmarked with 'ttcp': it transferred
measurement. Their error is +/-20k on a quiet (private) network and also
depend on what load the CPU has.
- The author may be reached at davies@maniac.ultranet.com.
-
=========================================================================
- This driver has been written substantially from scratch, although its
+ This driver has been written substantially from scratch, although its
inheritance of style and stack interface from 'ewrk3.c' and in turn from
Donald Becker's 'lance.c' should be obvious. With the module autoload of
- every usable DECchip board, I pinched Donald's 'next_module' field to
+ every usable DECchip board, I pinched Donald's 'next_module' field to
link my modules together.
Upto 15 EISA cards can be supported under this driver, limited primarily
1) copy de4x5.c from the /linux/drivers/net directory to your favourite
temporary directory.
2) for fixed autoprobes (not recommended), edit the source code near
- line 4927 to reflect the I/O address you're using, or assign these when
+ line 5005 to reflect the I/O address you're using, or assign these when
loading by:
insmod de4x5 io=0xghh where g = bus number
By default, the driver will now autodetect any DECchip based card.
Should you have a need to restrict the driver to DIGITAL only cards, you
can compile with a DEC_ONLY define, or if loading as a module, use the
- 'dec_only=1' parameter.
+ 'dec_only=1' parameter.
I've changed the timing routines to use the kernel timer and scheduling
functions so that the hangs and other assorted problems that occurred
(quad 21041 MAC) cards also appear to work despite their incorrectly
wired IRQs.
+ I have added a temporary fix for interrupt problems when some SCSI cards
+ share the same interrupt as the DECchip based cards. The problem occurs
+ because the SCSI card wants to grab the interrupt as a fast interrupt
+ (runs the service routine with interrupts turned off) vs. this card
+ which really needs to run the service routine with interrupts turned on.
+ This driver will now add the interrupt service routine as a fast
+ interrupt if it is bounced from the slow interrupt. THIS IS NOT A
+ RECOMMENDED WAY TO RUN THE DRIVER and has been done for a limited time
+ until people sort out their compatibility issues and the kernel
+ interrupt service code is fixed. YOU SHOULD SEPARATE OUT THE FAST
+ INTERRUPT CARDS FROM THE SLOW INTERRUPT CARDS to ensure that they do not
+ run on the same interrupt. PCMCIA/CardBus is another can of worms...
+
TO DO:
------
0.442 9-Sep-96 Include AUI in dc21041 media printout. Bug reported
by <bhat@mundook.cs.mu.OZ.AU>
0.45 8-Dec-96 Include endian functions for PPC use, from work
- by <cort@cs.nmt.edu>.
+ by <cort@cs.nmt.edu> and <g.thomas@opengroup.org>.
0.451 28-Dec-96 Added fix to allow autoprobe for modules after
suggestion from <mjacob@feral.com>.
0.5 30-Jan-97 Added SROM decoding functions.
Added attempt to use an SMC9332 with broken SROM.
Added fix for ZYNX multi-mac cards that didn't
get their IRQs wired correctly.
+ 0.51 13-Feb-97 Added endian fixes for the SROM accesses from
+ <paubert@iram.es>
+ Fix init_connection() to remove extra device reset.
+ Fix MAC/PHY reset ordering in dc21140m_autoconf().
+ Fix initialisation problem with lp->timeout in
+ typeX_infoblock() from <paubert@iram.es>.
+ Fix MII PHY reset problem from work done by
+ <paubert@iram.es>.
+ 0.52 26-Apr-97 Some changes may not credit the right people -
+ a disk crash meant I lost some mail.
+ Change RX interrupt routine to drop rather than
+ defer packets to avoid hang reported by
+ <g.thomas@opengroup.org>.
+ Fix srom_exec() to return for COMPACT and type 1
+ infoblocks.
+ Added DC21142 and DC21143 functions.
+ Added byte counters from <phil@tazenda.demon.co.uk>
+ Added SA_INTERRUPT temporary fix from
+ <mjacob@feral.com>.
=========================================================================
*/
-static const char *version = "de4x5.c:V0.5 97/1/30 davies@maniac.ultranet.com\n";
+static const char *version = "de4x5.c:V0.52 1997/4/26 davies@maniac.ultranet.com\n";
#include <linux/module.h>
#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/dma.h>
-#include <asm/uaccess.h>
#include <asm/byteorder.h>
+#include <asm/unaligned.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#define c_char const char
+#include <linux/version.h>
+#if LINUX_VERSION_CODE < ((2 << 16) | (1 << 8))
+#define net_device_stats enet_statistics
+#define copy_to_user(a,b,c) memcpy_tofs(a,b,c)
+#define copy_from_user(a,b,c) memcpy_fromfs(a,b,c)
+#define le16_to_cpu(a) cpu_to_le16(a)
+#define le32_to_cpu(a) cpu_to_le32(a)
+#ifdef __powerpc__
+#define cpu_to_le16(a) ((((a) & 0x00ffU) << 8) | (((a) & 0xff00U) >> 8))
+#define cpu_to_le32(a) ((((a) & 0x000000ffU) << 24) |\
+ (((a) & 0x0000ff00U) << 8) |\
+ (((a) & 0x00ff0000U) >> 8) |\
+ (((a) & 0xff000000U) >> 24))
+#else
+#define cpu_to_le16(a) (a)
+#define cpu_to_le32(a) (a)
+#endif /* __powerpc__ */
+#include <asm/segment.h>
+#else
+#include <asm/uaccess.h>
+#endif /* LINUX_VERSION_CODE */
+#define TWIDDLE(a) (u_short)le16_to_cpu(get_unaligned((u_short *)(a)))
+
/*
** MII Information
*/
struct phy_table {
- int reset; /* Hard reset required? */
- int id; /* IEEE OUI */
+ int reset; /* Hard reset required? */
+ int id; /* IEEE OUI */
int ta; /* One cycle TA time - 802.3u is confusing here */
- struct { /* Non autonegotiation (parallel) speed det. */
+ struct { /* Non autonegotiation (parallel) speed det. */
int reg;
int mask;
int value;
};
struct mii_phy {
- int reset; /* Hard reset required? */
- int id; /* IEEE OUI */
- int ta; /* One cycle TA time */
+ int reset; /* Hard reset required? */
+ int id; /* IEEE OUI */
+ int ta; /* One cycle TA time */
struct { /* Non autonegotiation (parallel) speed det. */
int reg;
int mask;
int value;
} spd;
- int addr; /* MII address for the PHY */
- u_char *gep; /* Start of GEP sequence block in SROM */
- u_char *rst; /* Start of reset sequence in SROM */
- u_int mc; /* Media Capabilities */
- u_int ana; /* NWay Advertisement */
- u_int fdx; /* Full DupleX capabilites for each media */
- u_int ttm; /* Transmit Threshold Mode for each media */
+ int addr; /* MII address for the PHY */
+ u_char *gep; /* Start of GEP sequence block in SROM */
+ u_char *rst; /* Start of reset sequence in SROM */
+ u_int mc; /* Media Capabilities */
+ u_int ana; /* NWay Advertisement */
+ u_int fdx; /* Full DupleX capabilites for each media */
+ u_int ttm; /* Transmit Threshold Mode for each media */
};
#define DE4X5_MAX_PHY 8 /* Allow upto 8 attached PHY devices per board */
+struct sia_phy {
+ u_char mc; /* Media Code */
+ u_char ext; /* csr13-15 valid when set */
+ int csr13; /* SIA Connectivity Register */
+ int csr14; /* SIA TX/RX Register */
+ int csr15; /* SIA General Register */
+ int gepc; /* SIA GEP Control Information */
+ int gep; /* SIA GEP Data */
+};
+
/*
** Define the know universe of PHY devices that can be
** recognised by this driver
static struct phy_table phy_info[] = {
{0, NATIONAL_TX, 1, {0x19, 0x40, 0x00}}, /* National TX */
{1, BROADCOM_T4, 1, {0x10, 0x02, 0x02}}, /* Broadcom T4 */
- {0, SEEQ_T4 , 1, {0x12, 0x10, 0x10}}, /* SEEQ T4 */
- {0, CYPRESS_T4 , 1, {0x05, 0x20, 0x20}} /* Cypress T4 */
+ {0, SEEQ_T4 , 1, {0x12, 0x10, 0x10}}, /* SEEQ T4 */
+ {0, CYPRESS_T4 , 1, {0x05, 0x20, 0x20}} /* Cypress T4 */
};
/*
0x00,0x18,}
};
-#undef DE4X5_VERBOSE /* define to get more verbose startup messages */
#ifdef DE4X5_DEBUG
static int de4x5_debug = DE4X5_DEBUG;
int setup_f; /* Setup frame filtering type */
int local_state; /* State within a 'media' state */
struct mii_phy phy[DE4X5_MAX_PHY]; /* List of attached PHY devices */
+ struct sia_phy sia; /* SIA PHY Information */
int active; /* Index to active PHY device */
int mii_cnt; /* Number of attached PHY's */
int timeout; /* Scheduling counter */
static void yawn(struct device *dev, int state);
static int de4x5_dev_index(char *s);
static void link_modules(struct device *dev, struct device *tmp);
-#ifdef MODULE
-static struct device *unlink_modules(struct device *p);
-#endif
static void de4x5_dbg_open(struct device *dev);
static void de4x5_dbg_mii(struct device *dev, int k);
static void de4x5_dbg_media(struct device *dev);
#ifdef MODULE
int init_module(void);
void cleanup_module(void);
+static struct device *unlink_modules(struct device *p);
static int autoprobed = 0, loading_module = 1;
# else
static int autoprobed = 0, loading_module = 0;
PCI_CFDA_PSM, WAKEUP);
}
de4x5_ms_delay(10);
-
+
RESET_DE4X5;
if ((inl(DE4X5_STS) & (STS_TS | STS_RS)) != 0) {
lp->chipset = bus.chipset;
lp->cache.priv = tmp;
lp->cache.gepc = GEP_INIT;
+ lp->asBit = GEP_SLNK;
+ lp->asPolarity = GEP_SLNK;
+ lp->asBitValid = TRUE;
lp->timeout = -1;
lp->useSROM = useSROM;
memcpy((char *)&lp->srom,(char *)&bus.srom,sizeof(struct de4x5_srom));
printk(" and requires IRQ%d (provided by %s).\n", dev->irq,
((lp->bus == PCI) ? "PCI BIOS" : "EISA CNFG"));
-
-#ifdef DE4X5_VERBOSE
- printk("%s: INFOLEAF_SIZE: %ld, COMPACT: %ld\n", dev->name,
- INFOLEAF_SIZE, COMPACT);
-#endif
}
if (de4x5_debug & DEBUG_VERSION) {
if (request_irq(dev->irq, (void *)de4x5_interrupt, SA_SHIRQ,
lp->adapter_name, dev)) {
- printk("de4x5_open(): Requested IRQ%d is busy\n",dev->irq);
- status = -EAGAIN;
- } else {
- dev->tbusy = 0;
- dev->start = 1;
- dev->interrupt = UNMASK_INTERRUPTS;
- dev->trans_start = jiffies;
-
- START_DE4X5;
-
- de4x5_setup_intr(dev);
+ printk("de4x5_open(): Requested IRQ%d is busy - attemping FAST/SHARE...", dev->irq);
+ if (request_irq(dev->irq, de4x5_interrupt, SA_INTERRUPT | SA_SHIRQ,
+ lp->adapter_name, dev)) {
+ printk("\n Cannot get IRQ- reconfigure your hardware.\n");
+ disable_ast(dev);
+ de4x5_free_rx_buffs(dev);
+ de4x5_free_tx_buffs(dev);
+ yawn(dev, SLEEP);
+ lp->state = CLOSED;
+ return -EAGAIN;
+ } else {
+ printk("\n Succeeded, but you should reconfigure your hardware to avoid this.\n");
+ printk("WARNING: there may be IRQ related problems in heavily loaded systems.\n");
+ }
}
+ dev->tbusy = 0;
+ dev->start = 1;
+ dev->interrupt = UNMASK_INTERRUPTS;
+ dev->trans_start = jiffies;
+
+ START_DE4X5;
+
+ de4x5_setup_intr(dev);
if (de4x5_debug & DEBUG_OPEN) {
printk("\tsts: 0x%08x\n", inl(DE4X5_STS));
sti();
/* Test if cache is already locked - requeue skb if so */
- if (set_bit(0, (void *)&lp->cache.lock) && !dev->interrupt) return -1;
+ if (test_and_set_bit(0, (void *)&lp->cache.lock) && !dev->interrupt) return -1;
/* Transmit descriptor ring full or stale skb */
if (dev->tbusy || lp->tx_skb[lp->tx_new]) {
printk("%s: transmit busy, lost media or stale skb found:\n STS:%08x\n tbusy:%ld\n IMR:%08x\n OMR:%08x\n Stale skb: %s\n",dev->name, inl(DE4X5_STS), dev->tbusy, inl(DE4X5_IMR), inl(DE4X5_OMR), (lp->tx_skb[lp->tx_new] ? "YES" : "NO"));
}
} else if (skb->len > 0) {
- /* Update the byte counter */
- lp->stats.tx_bytes += skb->len;
-
/* If we already have stuff queued locally, use that first */
if (lp->cache.skb && !dev->interrupt) {
de4x5_put_cache(dev, skb);
cli();
set_bit(0, (void*)&dev->tbusy);
load_packet(dev, skb->data, TD_IC | TD_LS | TD_FS | skb->len, skb);
+#if LINUX_VERSION_CODE >= ((2 << 16) | (1 << 8))
+ lp->stats.tx_bytes += skb->len;
+#endif
outl(POLL_DEMAND, DE4X5_TPD);/* Start the TX */
lp->tx_new = (++lp->tx_new) % lp->txRingSize;
}
if (skb) de4x5_putb_cache(dev, skb);
}
-
+
lp->cache.lock = 0;
return status;
if (dev->interrupt)
printk("%s: Re-entering the interrupt handler.\n", dev->name);
-
+
DISABLE_IRQs; /* Ensure non re-entrancy */
+#if LINUX_VERSION_CODE >= ((2 << 16) | (1 << 8))
synchronize_irq();
+#endif
dev->interrupt = MASK_INTERRUPTS;
for (limit=0; limit<8; limit++) {
}
/* Load the TX ring with any locally stored packets */
- if (!set_bit(0, (void *)&lp->cache.lock)) {
- if (lp->cache.skb && !dev->tbusy && lp->tx_enable) {
+ if (!test_and_set_bit(0, (void *)&lp->cache.lock)) {
+ while (lp->cache.skb && !dev->tbusy && lp->tx_enable) {
de4x5_queue_pkt(de4x5_get_cache(dev), dev);
}
lp->cache.lock = 0;
if ((skb = de4x5_alloc_rx_buff(dev, entry, pkt_len)) == NULL) {
printk("%s: Insufficient memory; nuking packet.\n",
dev->name);
- lp->stats.rx_dropped++; /* Really, deferred. */
- break;
- }
- de4x5_dbg_rx(skb, pkt_len);
+ lp->stats.rx_dropped++;
+ } else {
+ de4x5_dbg_rx(skb, pkt_len);
- /* Push up the protocol stack */
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
+ /* Push up the protocol stack */
+ skb->protocol=eth_type_trans(skb,dev);
+ netif_rx(skb);
- /* Update stats */
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += pkt_len;
- de4x5_local_stats(dev, skb->data, pkt_len);
+ /* Update stats */
+ lp->stats.rx_packets++;
+#if LINUX_VERSION_CODE >= ((2 << 16) | (1 << 8))
+ lp->stats.rx_bytes += pkt_len;
+#endif
+ de4x5_local_stats(dev, skb->data, pkt_len);
+ }
}
/* Change buffer ownership for this frame, back to the adapter */
if ((omr & OMR_TR) < OMR_TR) {
omr += 0x4000;
} else {
- if (omr & OMR_TTM)
- omr &= ~OMR_TTM;
- else
- omr |= OMR_SF;
+ omr |= OMR_SF;
}
outl(omr | OMR_ST | OMR_SR, DE4X5_OMR);
}
return 0;
}
-static struct net_device_stats *de4x5_get_stats(struct device *dev)
+static struct net_device_stats *
+de4x5_get_stats(struct device *dev)
{
struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
u_long iobase = dev->base_addr;
{
u_char irq;
u_char pb, pbus, dev_num, dnum, dev_fn;
- u_short vendor, index, status;
+ u_short dev_id, vendor, index, status;
u_int class = DE4X5_CLASS_CODE;
u_int device, iobase;
struct bus_type *lp = &bus;
if ((!pbus && !dnum) || ((pbus == pb) && (dnum == dev_num))) {
device = 0;
pcibios_read_config_word(pb, PCI_DEVICE, PCI_VENDOR_ID, &vendor);
- pcibios_read_config_word(pb, PCI_DEVICE, PCI_DEVICE_ID, (u_short *)&device);
+ pcibios_read_config_word(pb, PCI_DEVICE, PCI_DEVICE_ID, &dev_id);
+ device = dev_id;
device <<= 8;
if (!(is_DC21040 || is_DC21041 || is_DC21140 || is_DC2114x)) {
continue;
return;
}
-#ifdef MODULE
-static struct device *
-unlink_modules(struct device *p)
-{
- struct device *next = NULL;
-
- if (p->priv) { /* Private areas allocated? */
- struct de4x5_private *lp = (struct de4x5_private *)p->priv;
-
- next = lp->next_module;
- if (lp->cache.buf) { /* MAC buffers allocated? */
- kfree(lp->cache.buf); /* Free the MAC buffers */
- }
- kfree(lp->cache.priv); /* Free the private area */
- release_region(p->base_addr, (lp->bus == PCI ?
- DE4X5_PCI_TOTAL_SIZE :
- DE4X5_EISA_TOTAL_SIZE));
- }
- unregister_netdev(p);
- kfree(p); /* Free the device structure */
-
- return next;
-}
-#endif
-
/*
** Auto configure the media here rather than setting the port at compile
** time. This routine is called by de4x5_init() and when a loss of media is
lp->media = prev_state;
} else {
lp->media = INIT;
+ lp->tcount++;
}
}
switch(lp->media) {
case INIT:
- DISABLE_IRQs;
- lp->tx_enable = FALSE;
- lp->linkOK = 0;
-/* lp->timeout = -1;*/
+ if (lp->timeout < 0) {
+ DISABLE_IRQs;
+ lp->tx_enable = FALSE;
+ lp->linkOK = 0;
+ de4x5_save_skbs(dev); /* Save non transmitted skb's */
+ }
if ((next_tick = de4x5_reset_phy(dev)) < 0) {
next_tick &= ~TIMER_CB;
} else {
- de4x5_save_skbs(dev); /* Save non transmitted skb's */
if (lp->useSROM) {
srom_map_media(dev);
+ srom_exec(dev, lp->phy[lp->active].gep);
+ if (lp->infoblock_media == ANS) {
+ ana = lp->phy[lp->active].ana | MII_ANA_CSMA;
+ mii_wr(ana, MII_ANA, lp->phy[lp->active].addr, DE4X5_MII);
+ }
} else {
lp->tmp = MII_SR_ASSC; /* Fake out the MII speed set */
SET_10Mb;
de4x5_dbg_media(dev);
lp->c_media = lp->media; /* Stop scrolling media messages */
}
- de4x5_restore_skbs(dev);
+
cli();
- de4x5_rx(dev);
+ de4x5_restore_skbs(dev);
de4x5_setup_intr(dev);
lp->tx_enable = YES;
dev->tbusy = 0;
}
/*
-** General PHY reset function.
+** General PHY reset function. Some MII devices don't reset correctly
+** since their MII address pins can float at voltages that are dependent
+** on the signal pin use. Do a double reset to ensure a reset.
*/
static int
de4x5_reset_phy(struct device *dev)
if (lp->useSROM) {
if (lp->phy[lp->active].rst) { /* MII device specific reset */
srom_exec(dev, lp->phy[lp->active].rst);
+ srom_exec(dev, lp->phy[lp->active].rst);
} else if (lp->rst) { /* Type 5 infoblock reset */
srom_exec(dev, lp->rst);
+ srom_exec(dev, lp->rst);
}
} else {
PHY_HARD_RESET;
{
struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
u_long iobase = dev->base_addr;
+ int i;
s32 omr;
if (lp->cache.save_cnt) {
STOP_DE4X5;
- de4x5_cache_state(dev, DE4X5_SAVE_STATE);
- de4x5_sw_reset(dev);
- de4x5_cache_state(dev, DE4X5_RESTORE_STATE);
+ outl(virt_to_bus(lp->rx_ring), DE4X5_RRBA);
+ outl(virt_to_bus(lp->tx_ring), DE4X5_TRBA);
+
+ lp->rx_new = lp->rx_old = 0;
+ lp->tx_new = lp->tx_old = 0;
+
+ for (i = 0; i < lp->rxRingSize; i++) {
+ lp->rx_ring[i].status = cpu_to_le32(R_OWN);
+ }
+
+ for (i = 0; i < lp->txRingSize; i++) {
+ lp->tx_ring[i].status = cpu_to_le32(0);
+ }
+
+ barrier();
lp->cache.save_cnt--;
START_DE4X5;
}
if (lp->chipset == DC21040) {
outl(0, aprom_addr); /* Reset Ethernet Address ROM Pointer */
} else { /* Read new srom */
- short *p = (short *)&lp->srom;
+ u_short tmp, *p = (short *)&lp->srom;
for (i=0; i<(sizeof(struct de4x5_srom)>>1); i++) {
- *p++ = srom_rd(aprom_addr, i);
+ tmp = srom_rd(aprom_addr, i);
+ *p++ = le16_to_cpu(tmp);
}
de4x5_dbg_srom((struct de4x5_srom *)&lp->srom);
}
}
}
- lp->infoleaf_offset = (u_short)*((u_short *)(p+1));
+ lp->infoleaf_offset = TWIDDLE(p+1);
return 0;
}
u_char *p = (u_char *)&lp->srom + lp->infoleaf_offset;
u_char count;
+ p+=2;
if (lp->chipset == DC21140) {
- p+=2;
lp->cache.gepc = (*p++ | GEP_CTRL);
outl(lp->cache.gepc, DE4X5_GEP);
- } else if (lp->chipset == DC21142) {
- p+=2;
- } else if (lp->chipset == DC21143) {
- p+=2;
}
/* Block count */
{
struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
u_long iobase = dev->base_addr;
- u_char count = *p++;
+ u_char count = (p ? *p++ : 0);
while (count--) {
if (lp->chipset == DC21140) {
}
}
- if (lp->media == INIT) {
+ if ((lp->media == INIT) && (lp->timeout < 0)) {
outl(lp->cache.gepc, DE4X5_GEP);
lp->infoblock_media = (*p++) & COMPACT_MC;
lp->cache.gep = *p++;
}
}
- if (lp->media == INIT) {
+ if ((lp->media == INIT) && (lp->timeout < 0)) {
outl(lp->cache.gepc, DE4X5_GEP);
p+=2;
lp->infoblock_media = (*p++) & BLOCK0_MC;
type1_infoblock(struct device *dev, u_char count, u_char *p)
{
struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- u_long iobase = dev->base_addr;
u_char len = (*p & BLOCK_LEN)+1;
- int ana;
/* Recursively figure out the info blocks */
if (--count > lp->tcount) {
}
}
+ p += 2;
if (lp->state == INITIALISED) {
- lp->ibn = 1; p += 2;
+ lp->ibn = 1;
lp->active = *p++;
lp->phy[lp->active].gep = (*p ? p : 0); p += (*p + 1);
lp->phy[lp->active].rst = (*p ? p : 0); p += (*p + 1);
- lp->phy[lp->active].mc = *(u_short *)p; p += 2;
- lp->phy[lp->active].ana = *(u_short *)p; p += 2;
- lp->phy[lp->active].fdx = *(u_short *)p; p += 2;
- lp->phy[lp->active].ttm = *(u_short *)p;
+ lp->phy[lp->active].mc = TWIDDLE(p); p += 2;
+ lp->phy[lp->active].ana = TWIDDLE(p); p += 2;
+ lp->phy[lp->active].fdx = TWIDDLE(p); p += 2;
+ lp->phy[lp->active].ttm = TWIDDLE(p);
return 0;
- } else if (lp->media == INIT) {
- if (lp->phy[lp->active].gep) {
- srom_exec(dev, lp->phy[lp->active].gep);
- }
- ana = lp->phy[lp->active].ana | MII_ANA_CSMA;
- mii_wr(ana, MII_ANA, lp->phy[lp->active].addr, DE4X5_MII);
+ } else if ((lp->media == INIT) && (lp->timeout < 0)) {
+ lp->ibn = 1;
+ lp->active = *p;
lp->infoblock_csr6 = OMR_PS | OMR_HBD;
lp->useMII = TRUE;
lp->infoblock_media = ANS;
lp->active = *p++;
lp->phy[lp->active].gep = (*p ? p : 0); p += (*p + 1);
lp->phy[lp->active].rst = (*p ? p : 0); p += (*p + 1);
- lp->phy[lp->active].mc = *(u_short *)p; p += 2;
- lp->phy[lp->active].ana = *(u_short *)p; p += 2;
- lp->phy[lp->active].fdx = *(u_short *)p; p += 2;
- lp->phy[lp->active].ttm = *(u_short *)p;
+ lp->phy[lp->active].mc = TWIDDLE(p); p += 2;
+ lp->phy[lp->active].ana = TWIDDLE(p); p += 2;
+ lp->phy[lp->active].fdx = TWIDDLE(p); p += 2;
+ lp->phy[lp->active].ttm = TWIDDLE(p);
return 0;
} else if (lp->media == INIT) {
p+=2;
u_long iobase = dev->base_addr;
int i, j, status = 0;
s32 omr;
- struct {
- u8 *addr;
- u16 *sval;
- u32 *lval;
+ union {
+ u8 addr[144];
+ u16 sval[72];
+ u32 lval[36];
} tmp;
-
- tmp.addr = tmp.sval = tmp.lval = kmalloc(HASH_TABLE_LEN * ETH_ALEN, GFP_KERNEL);
- if (!tmp.addr){
- printk("%s ioctl: memory squeeze.\n", dev->name);
- return -ENOMEM;
- }
-
+
switch(ioc->cmd) {
case DE4X5_GET_HWADDR: /* Get the hardware address */
ioc->len = ETH_ALEN;
}
build_setup_frame(dev, PHYS_ADDR_ONLY);
/* Set up the descriptor and give ownership to the card */
- while (set_bit(0, (void *)&dev->tbusy) != 0);/* Wait for lock to free*/
+ while (test_and_set_bit(0, (void *)&dev->tbusy) != 0);/* Wait for lock to free*/
load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET |
SETUP_FRAME_LEN, NULL);
lp->tx_new = (++lp->tx_new) % lp->txRingSize;
break;
case DE4X5_GET_MCA: /* Get the multicast address table */
- ioc->len = (HASH_TABLE_LEN >> 3);
- status = verify_area(VERIFY_WRITE, ioc->data, ioc->len);
- if (!status) {
- copy_to_user(ioc->data, lp->setup_frame, ioc->len);
- }
-
break;
case DE4X5_SET_MCA: /* Set a multicast address */
- if (suser()) {
- /******* FIX ME! ********/
- if (ioc->len != HASH_TABLE_LEN) { /* MCA changes */
- if (!(status = verify_area(VERIFY_READ, (void *)ioc->data, ETH_ALEN * ioc->len))) {
- copy_from_user(tmp.addr, ioc->data, ETH_ALEN * ioc->len);
- set_multicast_list(dev);
- }
- } else {
- set_multicast_list(dev);
- }
- } else {
- status = -EPERM;
- }
-
break;
case DE4X5_CLR_MCA: /* Clear all multicast addresses */
- if (suser()) {
- /******* FIX ME! ********/
- set_multicast_list(dev);
- } else {
- status = -EPERM;
- }
-
break;
- case DE4X5_MCA_EN: /* Enable pass all multicast addressing */
+ case DE4X5_MCA_EN: /* Enable pass all multicast addresses*/
if (suser()) {
omr = inl(DE4X5_OMR);
omr |= OMR_PM;
}
break;
-#define DE4X5_DUMP 0x0f /* Dump the DE4X5 Status */
+/*
+#define DE4X5_DUMP 0x0f / * Dump the DE4X5 Status * /
case DE4X5_DUMP:
j = 0;
}
break;
+*/
default:
status = -EOPNOTSUPP;
}
-
- kfree(tmp.addr);
-
+
return status;
}
return;
}
+
+static struct device *
+unlink_modules(struct device *p)
+{
+ struct device *next = NULL;
+
+ if (p->priv) { /* Private areas allocated? */
+ struct de4x5_private *lp = (struct de4x5_private *)p->priv;
+
+ next = lp->next_module;
+ if (lp->cache.buf) { /* MAC buffers allocated? */
+ kfree(lp->cache.buf); /* Free the MAC buffers */
+ }
+ kfree(lp->cache.priv); /* Free the private area */
+ release_region(p->base_addr, (lp->bus == PCI ?
+ DE4X5_PCI_TOTAL_SIZE :
+ DE4X5_EISA_TOTAL_SIZE));
+ }
+ unregister_netdev(p);
+ kfree(p); /* Free the device structure */
+
+ return next;
+}
+
#endif /* MODULE */
\f
#define CFCS_DST 0x06000000 /* DEVSEL Timing (S) */
#define CFCS_DPR 0x01000000 /* Data Parity Report (S) */
#define CFCS_FBB 0x00800000 /* Fast Back-To-Back (S) */
-#define CFCS_SLE 0x00000100 /* System Error Enable (C) */
+#define CFCS_SEE 0x00000100 /* System Error Enable (C) */
#define CFCS_PER 0x00000040 /* Parity Error Response (C) */
#define CFCS_MO 0x00000004 /* Master Operation (C) */
#define CFCS_MSA 0x00000002 /* Memory Space Access (C) */
*/
#define CFRV_BC 0xff000000 /* Base Class */
#define CFRV_SC 0x00ff0000 /* Subclass */
-#define CFRV_SN 0x000000f0 /* Step Number */
-#define CFRV_RN 0x0000000f /* Revision Number */
+#define CFRV_RN 0x000000f0 /* Revision Number */
+#define CFRV_SN 0x0000000f /* Step Number */
#define BASE_CLASS 0x02000000 /* Indicates Network Controller */
#define SUB_CLASS 0x00000000 /* Indicates Ethernet Controller */
#define STEP_NUMBER 0x00000020 /* Increments for future chips */
#define CBIO_MASK 0xffffff80 /* Base I/O Address Mask */
#define CBIO_IOSI 0x00000001 /* I/O Space Indicator (RO, value is 1) */
+/*
+** PCI Configuration Card Information Structure Register (PCI_CCIS)
+*/
+#define CCIS_ROMI 0xf0000000 /* ROM Image */
+#define CCIS_ASO 0x0ffffff8 /* Address Space Offset */
+#define CCIS_ASI 0x00000007 /* Address Space Indicator */
+
+/*
+** PCI Configuration Subsystem ID Register (PCI_SSID)
+*/
+#define SSID_SSID 0xffff0000 /* Subsystem ID */
+#define SSID_SVID 0x0000ffff /* Subsystem Vendor ID */
+
/*
** PCI Configuration Expansion ROM Base Address Register (PCI_CBER)
*/
#define CBER_MASK 0xfffffc00 /* Expansion ROM Base Address Mask */
#define CBER_ROME 0x00000001 /* ROM Enable */
+/*
+** PCI Configuration Interrupt Register (PCI_CFIT)
+*/
+#define CFIT_MXLT 0xff000000 /* MAX_LAT Value (0.25us periods) */
+#define CFIT_MNGT 0x00ff0000 /* MIN_GNT Value (0.25us periods) */
+#define CFIT_IRQP 0x0000ff00 /* Interrupt Pin */
+#define CFIT_IRQL 0x000000ff /* Interrupt Line */
+
/*
** PCI Configuration Power Management Area Register (PCI_CFPM)
*/
/*
** DC21040 Bus Mode Register (DE4X5_BMR)
*/
+#define BMR_RML 0x00200000 /* [Memory] Read Multiple */
#define BMR_DBO 0x00100000 /* Descriptor Byte Ordering (Endian) */
#define BMR_TAP 0x000e0000 /* Transmit Automatic Polling */
#define BMR_DAS 0x00010000 /* Diagnostic Address Space */
#define BMR_BAR 0x00000002 /* Bus ARbitration */
#define BMR_SWR 0x00000001 /* Software Reset */
+ /* Timings here are for 10BASE-T/AUI only*/
#define TAP_NOPOLL 0x00000000 /* No automatic polling */
#define TAP_200US 0x00020000 /* TX automatic polling every 200us */
#define TAP_800US 0x00040000 /* TX automatic polling every 800us */
#define TRBA 0xfffffffc /* TX Descriptor List Start Address */
/*
-** DC21040 Status Register (DE4X5_STS)
+** Status Register (DE4X5_STS)
*/
+#define STS_GPI 0x04000000 /* General Purpose Port Interrupt */
#define STS_BE 0x03800000 /* Bus Error Bits */
#define STS_TS 0x00700000 /* Transmit Process State */
#define STS_RS 0x000e0000 /* Receive Process State */
#define STS_NIS 0x00010000 /* Normal Interrupt Summary */
#define STS_AIS 0x00008000 /* Abnormal Interrupt Summary */
#define STS_ER 0x00004000 /* Early Receive */
+#define STS_FBE 0x00002000 /* Fatal Bus Error */
#define STS_SE 0x00002000 /* System Error */
#define STS_LNF 0x00001000 /* Link Fail */
#define STS_FD 0x00000800 /* Full-Duplex Short Frame Received */
#define STS_TM 0x00000800 /* Timer Expired (DC21041) */
+#define STS_ETI 0x00000400 /* Early Transmit Interupt */
#define STS_AT 0x00000400 /* AUI/TP Pin */
#define STS_RWT 0x00000200 /* Receive Watchdog Time-Out */
#define STS_RPS 0x00000100 /* Receive Process Stopped */
#define STS_RI 0x00000040 /* Receive Interrupt */
#define STS_UNF 0x00000020 /* Transmit Underflow */
#define STS_LNP 0x00000010 /* Link Pass */
+#define STS_ANC 0x00000010 /* Autonegotiation Complete */
#define STS_TJT 0x00000008 /* Transmit Jabber Time-Out */
#define STS_TU 0x00000004 /* Transmit Buffer Unavailable */
#define STS_TPS 0x00000002 /* Transmit Process Stopped */
#define INT_CANCEL 0x0001ffff /* For zeroing all interrupt sources */
/*
-** DC21040 Operation Mode Register (DE4X5_OMR)
+** Operation Mode Register (DE4X5_OMR)
*/
+#define OMR_SC 0x80000000 /* Special Capture Effect Enable */
+#define OMR_RA 0x40000000 /* Receive All */
#define OMR_SDP 0x02000000 /* SD Polarity - MUST BE ASSERTED */
#define OMR_SCR 0x01000000 /* Scrambler Mode */
#define OMR_PCS 0x00800000 /* PCS Function */
#define OMR_SR 0x00000002 /* Start/Stop Receive */
#define OMR_HP 0x00000001 /* Hash/Perfect Receive Filtering Mode */
-#define TR_72 0x00000000 /* Threshold set to 72 bytes */
-#define TR_96 0x00004000 /* Threshold set to 96 bytes */
-#define TR_128 0x00008000 /* Threshold set to 128 bytes */
-#define TR_160 0x0000c000 /* Threshold set to 160 bytes */
+#define TR_72 0x00000000 /* Threshold set to 72 (128) bytes */
+#define TR_96 0x00004000 /* Threshold set to 96 (256) bytes */
+#define TR_128 0x00008000 /* Threshold set to 128 (512) bytes */
+#define TR_160 0x0000c000 /* Threshold set to 160 (1024) bytes */
/*
** DC21040 Interrupt Mask Register (DE4X5_IMR)
*/
+#define IMR_GPM 0x04000000 /* General Purpose Port Mask */
#define IMR_NIM 0x00010000 /* Normal Interrupt Summary Mask */
#define IMR_AIM 0x00008000 /* Abnormal Interrupt Summary Mask */
#define IMR_ERM 0x00004000 /* Early Receive Mask */
+#define IMR_FBM 0x00002000 /* Fatal Bus Error Mask */
#define IMR_SEM 0x00002000 /* System Error Mask */
#define IMR_LFM 0x00001000 /* Link Fail Mask */
#define IMR_FDM 0x00000800 /* Full-Duplex (Short Frame) Mask */
#define IMR_TMM 0x00000800 /* Timer Expired Mask (DC21041) */
+#define IMR_ETM 0x00000400 /* Early Transmit Interrupt Mask */
#define IMR_ATM 0x00000400 /* AUI/TP Switch Mask */
#define IMR_RWM 0x00000200 /* Receive Watchdog Time-Out Mask */
#define IMR_RSM 0x00000100 /* Receive Stopped Mask */
#define IMR_RUM 0x00000080 /* Receive Buffer Unavailable Mask */
#define IMR_RIM 0x00000040 /* Receive Interrupt Mask */
#define IMR_UNM 0x00000020 /* Underflow Interrupt Mask */
+#define IMR_ANM 0x00000010 /* Autonegotiation Complete Mask */
#define IMR_LPM 0x00000010 /* Link Pass */
#define IMR_TJM 0x00000008 /* Transmit Time-Out Jabber Mask */
#define IMR_TUM 0x00000004 /* Transmit Buffer Unavailable Mask */
#define IMR_TIM 0x00000001 /* Transmit Interrupt Mask */
/*
-** DC21040 Missed Frames Counter (DE4X5_MFC)
-*/
-#define MFC_OVFL 0x00010000 /* Missed Frames Counter Overflow Bit */
-#define MFC_CNTR 0x0000ffff /* Missed Frames Counter Bits */
-
-/*
-** DC21140 Missed Frames and FIFO Overflow Counters (DE4X5_MFC)
+** Missed Frames and FIFO Overflow Counters (DE4X5_MFC)
*/
#define MFC_FOCO 0x10000000 /* FIFO Overflow Counter Overflow Bit */
#define MFC_FOC 0x0ffe0000 /* FIFO Overflow Counter Bits */
** MII Management Auto Negotiation Advertisement Register
*/
#define MII_ANA_TAF 0x03e0 /* Technology Ability Field */
-#define MII_ANA_T4AM 0x0400 /* T4 Technology Ability Mask */
+#define MII_ANA_T4AM 0x0200 /* T4 Technology Ability Mask */
#define MII_ANA_TXAM 0x0180 /* TX Technology Ability Mask */
#define MII_ANA_FDAM 0x0140 /* Full Duplex Technology Ability Mask */
#define MII_ANA_HDAM 0x02a0 /* Half Duplex Technology Ability Mask */
#define MII_ANLPA_ACK 0x4000 /* Remote Acknowledge */
#define MII_ANLPA_RF 0x2000 /* Remote Fault */
#define MII_ANLPA_TAF 0x03e0 /* Technology Ability Field */
-#define MII_ANLPA_T4AM 0x0400 /* T4 Technology Ability Mask */
+#define MII_ANLPA_T4AM 0x0200 /* T4 Technology Ability Mask */
#define MII_ANLPA_TXAM 0x0180 /* TX Technology Ability Mask */
#define MII_ANLPA_FDAM 0x0140 /* Full Duplex Technology Ability Mask */
#define MII_ANLPA_HDAM 0x02a0 /* Half Duplex Technology Ability Mask */
#define SROM_100BASEFF 0x0008 /* 100BASE-FX full duplex */
#define BLOCK_LEN 0x7f /* Extended blocks length mask */
+#define EXT_FIELD 0x40 /* Extended blocks extension field bit */
+#define MEDIA_CODE 0x3f /* Extended blocks media code mask */
/*
** SROM Compact Format Block Masks
#define GEP_CTRL 0x00000100 /* GEP control bit */
/*
-** DC21040 SIA Status Register (DE4X5_SISR)
+** SIA Status Register (DE4X5_SISR)
*/
#define SISR_LPC 0xffff0000 /* Link Partner's Code Word */
#define SISR_LPN 0x00008000 /* Link Partner Negotiable */
#define SISR_ANS 0x00007000 /* Auto Negotiation Arbitration State */
-#define SISR_NSN 0x00000800 /* Non Stable NLPs Detected */
+#define SISR_NSN 0x00000800 /* Non Stable NLPs Detected (DC21041) */
+#define SISR_TRF 0x00000800 /* Transmit Remote Fault */
+#define SISR_NSND 0x00000400 /* Non Stable NLPs Detected (DC21142) */
#define SISR_ANR_FDS 0x00000400 /* Auto Negotiate Restart/Full Duplex Sel.*/
+#define SISR_TRA 0x00000200 /* 10BASE-T Receive Port Activity */
#define SISR_NRA 0x00000200 /* Non Selected Port Receive Activity */
+#define SISR_ARA 0x00000100 /* AUI Receive Port Activity */
#define SISR_SRA 0x00000100 /* Selected Port Receive Activity */
#define SISR_DAO 0x00000080 /* PLL All One */
#define SISR_DAZ 0x00000040 /* PLL All Zero */
#define SISR_LKF 0x00000004 /* Link Fail Status */
#define SISR_NCR 0x00000002 /* Network Connection Error */
#define SISR_PAUI 0x00000001 /* AUI_TP Indication */
-#define SIA_RESET 0x00000000 /* SIA Reset */
+#define SISR_MRA 0x00000001 /* MII Receive Port Activity */
#define ANS_NDIS 0x00000000 /* Nway disable */
#define ANS_TDIS 0x00001000 /* Transmit Disable */
#define ANS_LCHK 0x00006000 /* Link Check */
/*
-** DC21040 SIA Connectivity Register (DE4X5_SICR)
+** SIA Connectivity Register (DE4X5_SICR)
*/
#define SICR_SDM 0xffff0000 /* SIA Diagnostics Mode */
#define SICR_OE57 0x00008000 /* Output Enable 5 6 7 */
#define SICR_SIM 0x00000040 /* Serial Interface Input Multiplexer */
#define SICR_ENI 0x00000020 /* Encoder Input Multiplexer */
#define SICR_EDP 0x00000010 /* SIA PLL External Input Enable */
-#define SICR_AUI 0x00000008 /* 10Base-T or AUI */
+#define SICR_AUI 0x00000008 /* 10Base-T (0) or AUI (1) */
#define SICR_CAC 0x00000004 /* CSR Auto Configuration */
#define SICR_PS 0x00000002 /* Pin AUI/TP Selection */
#define SICR_SRL 0x00000001 /* SIA Reset */
-#define SICR_RESET 0xffff0000 /* Reset value for SICR */
+#define SIA_RESET 0x00000000 /* SIA Reset Value */
/*
-** DC21040 SIA Transmit and Receive Register (DE4X5_STRR)
+** SIA Transmit and Receive Register (DE4X5_STRR)
*/
#define STRR_TAS 0x00008000 /* 10Base-T/AUI Autosensing Enable */
#define STRR_SPP 0x00004000 /* Set Polarity Plus */
#define STRR_RESET 0xffffffff /* Reset value for STRR */
/*
-** DC21040 SIA General Register (DE4X5_SIGR)
-*/
+** SIA General Register (DE4X5_SIGR)
+*/
+#define SIGR_RMI 0x40000000 /* Receive Match Interrupt */
+#define SIGR_GI1 0x20000000 /* General Port Interrupt 1 */
+#define SIGR_GI0 0x10000000 /* General Port Interrupt 0 */
+#define SIGR_CWE 0x08000000 /* Control Write Enable */
+#define SIGR_RME 0x04000000 /* Receive Match Enable */
+#define SIGR_GEI1 0x02000000 /* GEP Interrupt Enable on Port 1 */
+#define SIGR_GEI0 0x01000000 /* GEP Interrupt Enable on Port 0 */
+#define SIGR_LGS3 0x00800000 /* LED/GEP3 Select */
+#define SIGR_LGS2 0x00400000 /* LED/GEP2 Select */
+#define SIGR_LGS1 0x00200000 /* LED/GEP1 Select */
+#define SIGR_LGS0 0x00100000 /* LED/GEP0 Select */
+#define SIGR_MD 0x000f0000 /* General Purpose Mode and Data */
#define SIGR_LV2 0x00008000 /* General Purpose LED2 value */
#define SIGR_LE2 0x00004000 /* General Purpose LED2 enable */
#define SIGR_FRL 0x00002000 /* Force Receiver Low */
** Receive Descriptor Bit Summary
*/
#define R_OWN 0x80000000 /* Own Bit */
-#define RD_FL 0x7fff0000 /* Frame Length */
+#define RD_FF 0x40000000 /* Filtering Fail */
+#define RD_FL 0x3fff0000 /* Frame Length */
#define RD_ES 0x00008000 /* Error Summary */
#define RD_LE 0x00004000 /* Length Error */
#define RD_DT 0x00003000 /* Data Type */
#define RD_CS 0x00000040 /* Collision Seen */
#define RD_FT 0x00000020 /* Frame Type */
#define RD_RJ 0x00000010 /* Receive Watchdog */
+#define RD_RE 0x00000008 /* Report on MII Error */
#define RD_DB 0x00000004 /* Dribbling Bit */
#define RD_CE 0x00000002 /* CRC Error */
#define RD_OF 0x00000001 /* Overflow */
#define TD_TCH 0x01000000 /* Second Address Chained */
#define TD_DPD 0x00800000 /* Disabled Padding */
#define TD_FT0 0x00400000 /* Filtering Type */
-#define TD_RBS2 0x003ff800 /* Buffer 2 Size */
-#define TD_RBS1 0x000007ff /* Buffer 1 Size */
+#define TD_TBS2 0x003ff800 /* Buffer 2 Size */
+#define TD_TBS1 0x000007ff /* Buffer 1 Size */
#define PERFECT_F 0x00000000
#define HASH_F TD_FT0
#define INVERSE_F TD_FT1
-#define HASH_O_F TD_FT1| TD_F0
+#define HASH_O_F (TD_FT1 | TD_F0)
/*
** Media / mode state machine definitions
*/
-#define NC 0x0000 /* No Connection */
-#define TP 0x0001 /* 10Base-T */
-#define TP_NW 0x0002 /* 10Base-T with Nway */
-#define BNC 0x0004 /* Thinwire */
-#define AUI 0x0008 /* Thickwire */
+#define NC 0x0000 /* No Connection */
+#define TP 0x0001 /* 10Base-T */
+#define TP_NW 0x0002 /* 10Base-T with Nway */
+#define BNC 0x0004 /* Thinwire */
+#define AUI 0x0008 /* Thickwire */
#define BNC_AUI 0x0010 /* BNC/AUI on DC21040 indistinguishable */
-#define ANS 0x0020 /* Intermediate AutoNegotiation State */
-#define ANS_1 0x0021 /* Intermediate AutoNegotiation State */
-
-#define _10Mb 0x0040 /* 10Mb/s Ethernet */
-#define _100Mb 0x0080 /* 100Mb/s Ethernet */
-#define SPD_DET 0x0100 /* Parallel speed detection */
-#define INIT 0x0200 /* Initial state */
-#define EXT_SIA 0x0400 /* External SIA for motherboard chip */
-#define ANS_SUSPECT 0x0802 /* Suspect the ANS (TP) port is down */
-#define TP_SUSPECT 0x0803 /* Suspect the TP port is down */
-#define BNC_AUI_SUSPECT 0x0804 /* Suspect the BNC or AUI port is down */
-#define EXT_SIA_SUSPECT 0x0805 /* Suspect the EXT SIA port is down */
-#define BNC_SUSPECT 0x0806 /* Suspect the BNC port is down */
-#define AUI_SUSPECT 0x0807 /* Suspect the AUI port is down */
-
-#define AUTO 0x4000 /* Auto sense the media or speed */
-#define TIMER_CB 0x80000000 /* Timer callback detection */
+#define ANS 0x0020 /* Intermediate AutoNegotiation State */
+#define _10Mb 0x0040 /* 10Mb/s Ethernet */
+#define _100Mb 0x0080 /* 100Mb/s Ethernet */
+#define SPD_DET 0x0100 /* Parallel speed detection */
+#define INIT 0x0200 /* Initial state */
+#define EXT_SIA 0x0400 /* External SIA for motherboard chip */
+#define ANS_SUSPECT 0x0802 /* Suspect the ANS (TP) port is down */
+#define TP_SUSPECT 0x0803 /* Suspect the TP port is down */
+#define BNC_AUI_SUSPECT 0x0804 /* Suspect the BNC or AUI port is down */
+#define EXT_SIA_SUSPECT 0x0805 /* Suspect the EXT SIA port is down */
+#define BNC_SUSPECT 0x0806 /* Suspect the BNC port is down */
+#define AUI_SUSPECT 0x0807 /* Suspect the AUI port is down */
+#define MII 0x1000 /* MII on the 21143 */
+
+#define AUTO 0x4000 /* Auto sense the media or speed */
+#define TIMER_CB 0x80000000 /* Timer callback detection */
/*
** DE4X5 DEBUG Options
#define POLL_DEMAND 1
#define LOST_MEDIA_THRESHOLD 3
-#define LOST_MEDIA (lp->lostMedia > LOST_MEDIA_THRESHOLD)
#define MASK_INTERRUPTS 1
#define UNMASK_INTERRUPTS 0
}\
omr |= ((lp->fdx ? OMR_FDX : 0) | OMR_TTM);\
outl(omr, DE4X5_OMR);\
- lp->cache.gep = 0;\
+ if (!lp->useSROM) lp->cache.gep = 0;\
} else if (lp->useSROM && !lp->useMII) {\
omr = (inl(DE4X5_OMR) & ~(OMR_PS | OMR_HBD | OMR_TTM | OMR_PCS | OMR_SCR | OMR_FDX));\
omr |= (lp->fdx ? OMR_FDX : 0);\
}\
if (fdx) omr |= OMR_FDX;\
outl(omr, DE4X5_OMR);\
- lp->cache.gep = 0;\
+ if (!lp->useSROM) lp->cache.gep = 0;\
} else if (lp->useSROM && !lp->useMII) {\
omr = (inl(DE4X5_OMR) & ~(OMR_PS | OMR_HBD | OMR_TTM | OMR_PCS | OMR_SCR | OMR_FDX));\
omr |= (lp->fdx ? OMR_FDX : 0);\
mii_wr(MII_CR_100|MII_CR_ASSE, MII_CR, lp->phy[lp->active].addr, DE4X5_MII);\
omr = (inl(DE4X5_OMR) & ~(OMR_TTM | OMR_PCS | OMR_SCR | OMR_FDX));\
outl(omr, DE4X5_OMR);\
- lp->cache.gep = 0;\
} else if (lp->useSROM && !lp->useMII) {\
omr = (inl(DE4X5_OMR) & ~(OMR_TTM | OMR_PCS | OMR_SCR | OMR_FDX));\
outl(omr, DE4X5_OMR);\
** Recognised commands for the driver
*/
#define DE4X5_GET_HWADDR 0x01 /* Get the hardware address */
-#define DE4X5_SET_HWADDR 0x02 /* Get the hardware address */
+#define DE4X5_SET_HWADDR 0x02 /* Set the hardware address */
#define DE4X5_SET_PROM 0x03 /* Set Promiscuous Mode */
#define DE4X5_CLR_PROM 0x04 /* Clear Promiscuous Mode */
#define DE4X5_SAY_BOO 0x05 /* Say "Boo!" to the kernel log file */
dev_tint(dev);
} else if (skb->len > 0) {
/* Enforce 1 process per h/w access */
- if (set_bit(0, (void*)&dev->tbusy) != 0) {
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
printk("%s: Transmitter access conflict.\n", dev->name);
status = -1;
} else {
dlp = dev->priv;
- if (set_bit(0, (void*)&dev->tbusy) != 0)
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
printk(KERN_WARNING "%s: transmitter access conflict.\n", dev->name);
else
{
}
/* Block a timer-based transmit from overlapping. */
- if (set_bit(0, (void*)&dev->tbusy) != 0)
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
printk("%s: Transmitter access conflict.\n", dev->name);
else {
short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
/* Block a timer-based transmit from overlapping. This could better be
done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
If this ever occurs the queue layer is doing something evil! */
- if (set_bit(0, (void*)&dev->tbusy) != 0) {
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
int tickssofar = jiffies - dev->trans_start;
if (tickssofar < TX_TIMEOUT - 2)
return 1;
}
}
- if (set_bit(0,(void *)&dev->tbusy))
+ if (test_and_set_bit(0,(void *)&dev->tbusy))
{
lp->stats.tx_dropped++;
}
/* Turn off TX interrupts */
outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
- if(set_bit(0, (void *)&dev->tbusy) != 0)
+ if(test_and_set_bit(0, (void *)&dev->tbusy) != 0)
printk("%s: Transmitter access conflict.\n", dev->name);
else {
short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
** Block a timer-based transmit from overlapping. This could better be
** done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
*/
- if (set_bit(0, (void*)&dev->tbusy) != 0)
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
printk("%s: Transmitter access conflict.\n", dev->name);
DISABLE_IRQs; /* So that the page # remains correct */
/*
** Set up shared memory window and pointer into the window
*/
- while (set_bit(0, (void *)&lp->lock) != 0); /* Wait for lock to free */
+ while (test_and_set_bit(0, (void *)&lp->lock) != 0); /* Wait for lock to free */
if (lp->shmem_length == IO_ONLY) {
outb(page, EWRK3_IOPR);
} else if (lp->shmem_length == SHMEM_2K) {
** Preempt any process using the current page register. Check for
** an existing lock to reduce time taken in I/O transactions.
*/
- if ((tmpLock = set_bit(0, (void *)&lp->lock)) == 1) { /* Assert lock */
+ if ((tmpLock = test_and_set_bit(0, (void *)&lp->lock)) == 1) { /* Assert lock */
if (lp->shmem_length == IO_ONLY) { /* Get existing page */
tmpPage = inb(EWRK3_IOPR);
} else {
u16 hashcode;
s32 crc, poly = CRC_POLYNOMIAL_LE;
- while (set_bit(0, (void *)&lp->lock) != 0); /* Wait for lock to free */
+ while (test_and_set_bit(0, (void *)&lp->lock) != 0); /* Wait for lock to free */
if (lp->shmem_length == IO_ONLY) {
outb(0, EWRK3_IOPR);
break;
case EWRK3_GET_MCA: /* Get the multicast address table */
if (!(status = verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {
- while (set_bit(0, (void *)&lp->lock) != 0); /* Wait for lock to free */
+ while (test_and_set_bit(0, (void *)&lp->lock) != 0); /* Wait for lock to free */
if (lp->shmem_length == IO_ONLY) {
outb(0, EWRK3_IOPR);
outw(PAGE0_HTE, EWRK3_PIR1);
/* Block a timer-based transmit from overlapping. This could better be
done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
- if (set_bit(0, (void*)&dev->tbusy) != 0)
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
printk("%s: Transmitter access conflict.\n", dev->name);
else {
short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
if (!s || s->magic != HDLCDRV_MAGIC)
return;
- if (set_bit(0, &s->hdlcrx.in_hdlc_rx))
+ if (test_and_set_bit(0, &s->hdlcrx.in_hdlc_rx))
return;
while (!hdlcdrv_hbuf_empty(&s->hdlcrx.hbuf)) {
if (!s || s->magic != HDLCDRV_MAGIC)
return;
- if (set_bit(0, &s->hdlctx.in_hdlc_tx))
+ if (test_and_set_bit(0, &s->hdlctx.in_hdlc_tx))
return;
for (;;) {
if (s->hdlctx.numbits >= 16) {
return 0;
}
- if (set_bit(0,(void *)&dev->tbusy)!=0)
+ if (test_and_set_bit(0,(void *)&dev->tbusy)!=0)
DPRINTK("Transmitter access conflict\n");
else {
/* Save skb; we'll need it when the adapter asks for the data */
/* Block a timer-based transmit from overlapping. This could better be
done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
- if (set_bit(0, (void*)&dev->tbusy) != 0) {
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
printk("%s: Transmitter access conflict.\n", dev->name);
return 1;
}
- if (set_bit(0, (void*)&lp->lock) != 0) {
+ if (test_and_set_bit(0, (void*)&lp->lock) != 0) {
if (lance_debug > 0)
printk("%s: tx queue lock!.\n", dev->name);
/* don't clear dev->tbusy flag. */
break;
/* Not in use ? */
- if (!set_bit(AXF_INUSE, &axp->ctrl.flags))
+ if (!test_and_set_bit(AXF_INUSE, &axp->ctrl.flags))
break;
}
if (ax->xbuff)
kfree(ax->xbuff);
ax->xbuff = NULL;
- if (!clear_bit(AXF_INUSE, &ax->flags))
+ if (!test_and_clear_bit(AXF_INUSE, &ax->flags))
printk(KERN_ERR "%s: ax_free for already free unit.\n", ax->dev->name);
}
/* Set the "sending" flag. This must be atomic, hence the ASM. */
static inline void ax_lock(struct ax_disp *ax)
{
- if (set_bit(0, (void *)&ax->dev->tbusy))
+ if (test_and_set_bit(0, (void *)&ax->dev->tbusy))
printk(KERN_ERR "%s: trying to lock already locked device!\n", ax->dev->name);
}
/* Clear the "sending" flag. This must be atomic, hence the ASM. */
static inline void ax_unlock(struct ax_disp *ax)
{
- if (!clear_bit(0, (void *)&ax->dev->tbusy))
+ if (!test_and_clear_bit(0, (void *)&ax->dev->tbusy))
printk(KERN_ERR "%s: trying to unlock already unlocked device!\n", ax->dev->name);
}
/* Read the characters out of the buffer */
while (count--) {
if (fp != NULL && *fp++) {
- if (!set_bit(AXF_ERROR, &ax->flags))
+ if (!test_and_set_bit(AXF_ERROR, &ax->flags))
ax->rx_errors++;
cp++;
continue;
if (test_bit(AXF_KEEPTEST, &ax->flags))
clear_bit(AXF_KEEPTEST, &ax->flags);
- if (!clear_bit(AXF_ERROR, &ax->flags) && (ax->rcount > 2))
+ if (!test_and_clear_bit(AXF_ERROR, &ax->flags) && (ax->rcount > 2))
ax_bump(ax);
clear_bit(AXF_ESCAPE, &ax->flags);
set_bit(AXF_ESCAPE, &ax->flags);
return;
case ESC_ESC:
- if (clear_bit(AXF_ESCAPE, &ax->flags))
+ if (test_and_clear_bit(AXF_ESCAPE, &ax->flags))
s = ESC;
break;
case ESC_END:
- if (clear_bit(AXF_ESCAPE, &ax->flags))
+ if (test_and_clear_bit(AXF_ESCAPE, &ax->flags))
s = END;
break;
}
return 0;
}
- if(set_bit(0, (void *) &dev->tbusy) != 0) {
+ if(test_and_set_bit(0, (void *) &dev->tbusy) != 0) {
DTX(("tbusy, maybe a race? returning 1\n"));
printk("%s: Transmitter access conflict.\n", dev->name);
return 1;
return 0;
}
- if (set_bit(0, (void*)&dev->tbusy)) {
+ if (test_and_set_bit(0, (void*)&dev->tbusy)) {
printk("%s: Transmitter access conflict.\n", dev->name);
return 1;
}
#if(NUM_XMIT_BUFFS > 1)
- else if(set_bit(0,(void *) &p->lock)) {
+ else if(test_and_set_bit(0,(void *) &p->lock)) {
printk("%s: Queue was locked\n",dev->name);
return 1;
}
return;
}
- if(set_bit(0,(int *) &dev->interrupt)) {
+ if(test_and_set_bit(0,(int *) &dev->interrupt)) {
printk("ni65: oops .. interrupt while proceeding interrupt\n");
return;
}
dev->trans_start = jiffies;
}
- if (set_bit(0, (void*)&dev->tbusy) != 0) {
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
printk(KERN_ERR "%s: Transmitter access conflict.\n", dev->name);
return 1;
}
- if (set_bit(0, (void*)&p->lock)) {
+ if (test_and_set_bit(0, (void*)&p->lock)) {
printk(KERN_ERR "%s: Queue was locked.\n", dev->name);
return 1;
}
/* Block a timer-based transmit from overlapping. This could better be
done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
- if (set_bit(0, (void*)&dev->tbusy) != 0) {
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
printk("%s: Transmitter access conflict.\n", dev->name);
return 1;
}
- if (set_bit(0, (void*)&lp->lock) != 0) {
+ if (test_and_set_bit(0, (void*)&lp->lock) != 0) {
if (pcnet32_debug > 0)
printk("%s: tx queue lock!.\n", dev->name);
/* don't clear dev->tbusy flag. */
return 0;
}
- if (set_bit(0, (void*)&dev->tbusy) != 0) {
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
printk("%s: Transmitter access conflict.\n", dev->name);
return 1;
}
* The total length includes the protocol data.
* Lock the user information buffer.
*/
- if (set_bit (0, &ppp->ubuf->locked)) {
+ if (test_and_set_bit (0, &ppp->ubuf->locked)) {
if (ppp->flags & SC_DEBUG)
printk (KERN_DEBUG
"ppp_us_queue: can't get lock\n");
if (!ppp || ppp->magic != PPP_MAGIC || !ppp->inuse)
return 0;
- if (set_bit (0, &ppp->ubuf->locked) != 0) {
+ if (test_and_set_bit (0, &ppp->ubuf->locked) != 0) {
if (ppp->flags & SC_DEBUG)
printk (KERN_DEBUG
"ppp_tty_read: sleeping(ubuf)\n");
poll_wait(&ppp->write_wait, wait);
/* Must lock the user buffer area while checking. */
- if(set_bit(0, &ppp->ubuf->locked) == 0) {
+ if(test_and_set_bit(0, &ppp->ubuf->locked) == 0) {
if(ppp->ubuf->head != ppp->ubuf->tail)
mask |= POLLIN | POLLRDNORM;
clear_bit(0, &ppp->ubuf->locked);
while (ctl) {
ppp = ctl2ppp (ctl);
- if (!set_bit(0, &ppp->inuse)) {
+ if (!test_and_set_bit(0, &ppp->inuse)) {
if (ppp->sc_xfer == pid_value) {
ppp->sc_xfer = 0;
return (ppp);
while (ctl) {
ppp = ctl2ppp (ctl);
- if (!set_bit(0, &ppp->inuse))
+ if (!test_and_set_bit(0, &ppp->inuse))
return (ppp);
ctl = ctl->next;
if (++if_num == max_dev)
if (skb == NULL)
return(0);
- if (set_bit(0, (void*)&dev->tbusy) != 0)
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
printk(KERN_WARNING "%s: transmitter access conflict.\n", dev->name);
else
{
if (dev->start)
return -EBUSY /* only one open is allowed */
;
- if (set_bit(0, (void*)&card->wandev.critical))
+ if (test_and_set_bit(0, (void*)&card->wandev.critical))
return -EAGAIN;
;
if (!card->open_cnt)
fr_channel_t* chan = dev->priv;
sdla_t* card = chan->card;
- if (set_bit(0, (void*)&card->wandev.critical))
+ if (test_and_set_bit(0, (void*)&card->wandev.critical))
return -EAGAIN;
;
dev->start = 0;
sdla_t* card = chan->card;
int retry = 0;
- if (set_bit(0, (void*)&card->wandev.critical))
+ if (test_and_set_bit(0, (void*)&card->wandev.critical))
{
#ifdef _DEBUG_
printk(KERN_INFO "%s: if_send() hit critical section!\n",
return 1;
}
- if (set_bit(0, (void*)&dev->tbusy))
+ if (test_and_set_bit(0, (void*)&dev->tbusy))
{
#ifdef _DEBUG_
printk(KERN_INFO "%s: Tx collision on interface %s!\n",
if (dev->start)
return -EBUSY /* only one open is allowed */
;
- if (set_bit(0, (void*)&card->wandev.critical))
+ if (test_and_set_bit(0, (void*)&card->wandev.critical))
return -EAGAIN;
;
if ((card->hw.fwid == SFID_PPP502) ? config502(card) : config508(card))
{
sdla_t* card = dev->priv;
- if (set_bit(0, (void*)&card->wandev.critical))
+ if (test_and_set_bit(0, (void*)&card->wandev.critical))
return -EAGAIN;
;
dev->start = 0;
sdla_t* card = dev->priv;
int retry = 0;
- if (set_bit(0, (void*)&card->wandev.critical))
+ if (test_and_set_bit(0, (void*)&card->wandev.critical))
{
#ifdef _DEBUG_
printk(KERN_INFO "%s: if_send() hit critical section!\n",
return 1;
}
- if (set_bit(0, (void*)&dev->tbusy))
+ if (test_and_set_bit(0, (void*)&dev->tbusy))
{
#ifdef _DEBUG_
printk(KERN_INFO "%s: Tx collision on interface %s!\n",
if (dev->start)
return -EBUSY /* only one open is allowed */
;
- if (set_bit(0, (void*)&card->wandev.critical))
+ if (test_and_set_bit(0, (void*)&card->wandev.critical))
return -EAGAIN;
;
x25_channel_t* chan = dev->priv;
sdla_t* card = chan->card;
- if (set_bit(0, (void*)&card->wandev.critical))
+ if (test_and_set_bit(0, (void*)&card->wandev.critical))
return -EAGAIN;
;
dev->start = 0;
sdla_t* card = chan->card;
int retry = 0, queued = 0;
- if (set_bit(0, (void*)&card->wandev.critical))
+ if (test_and_set_bit(0, (void*)&card->wandev.critical))
{
#ifdef _DEBUG_
printk(KERN_INFO "%s: if_send() hit critical section!\n",
return 1;
}
- if (set_bit(0, (void*)&dev->tbusy))
+ if (test_and_set_bit(0, (void*)&dev->tbusy))
{
#ifdef _DEBUG_
printk(KERN_INFO "%s: Tx collision on interface %s!\n",
if (wandev->state == WAN_UNCONFIGURED)
return 0
;
- if (set_bit(0, (void*)&wandev->critical))
+ if (test_and_set_bit(0, (void*)&wandev->critical))
return -EAGAIN
;
card = wandev->private;
if (wandev->state == WAN_UNCONFIGURED)
return -ENODEV
;
- if (set_bit(0, (void*)&wandev->critical))
+ if (test_and_set_bit(0, (void*)&wandev->critical))
return -EAGAIN
;
switch (cmd)
sdla_t* card = &card_array[i];
if ((card->wandev.state != WAN_UNCONFIGURED) && card->poll &&
- !set_bit(0, (void*)&card->wandev.critical))
+ !test_and_set_bit(0, (void*)&card->wandev.critical))
{
card->poll(card);
card->wandev.critical = 0;
/* Block a timer-based transmit from overlapping. This could better be
done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
- if (set_bit(0, (void*)&dev->tbusy) != 0)
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
printk("%s: Transmitter access conflict.\n", dev->name);
else {
short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
* This means check if we are already in.
*/
- if (set_bit(0, (void *) &dev->tbusy) != 0) /* dev->tbusy already set ? */
+ if (test_and_set_bit(0, (void *) &dev->tbusy) != 0) /* dev->tbusy already set ? */
{
printk("%s: Transmitter access conflict.\n", dev->name);
}
* Block a timer-based transmit from overlapping. This could better be
* done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
*/
- if (set_bit(0, (void*)&dev->tbusy) != 0)
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name);
else {
short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
if (slp == NULL)
break;
/* Not in use ? */
- if (!set_bit(SLF_INUSE, &slp->ctrl.flags))
+ if (!test_and_set_bit(SLF_INUSE, &slp->ctrl.flags))
break;
}
/* SLP is set.. */
sl->slcomp = NULL;
#endif
- if (!clear_bit(SLF_INUSE, &sl->flags)) {
+ if (!test_and_clear_bit(SLF_INUSE, &sl->flags)) {
printk("%s: sl_free for already free unit.\n", sl->dev->name);
}
}
static inline void
sl_lock(struct slip *sl)
{
- if (set_bit(0, (void *) &sl->dev->tbusy)) {
+ if (test_and_set_bit(0, (void *) &sl->dev->tbusy)) {
printk("%s: trying to lock already locked device!\n", sl->dev->name);
}
}
static inline void
sl_unlock(struct slip *sl)
{
- if (!clear_bit(0, (void *)&sl->dev->tbusy)) {
+ if (!test_and_clear_bit(0, (void *)&sl->dev->tbusy)) {
printk("%s: trying to unlock already unlocked device!\n", sl->dev->name);
}
}
/* Read the characters out of the buffer */
while (count--) {
if (fp && *fp++) {
- if (!set_bit(SLF_ERROR, &sl->flags)) {
+ if (!test_and_set_bit(SLF_ERROR, &sl->flags)) {
sl->rx_errors++;
}
cp++;
if (test_bit(SLF_KEEPTEST, &sl->flags))
clear_bit(SLF_KEEPTEST, &sl->flags);
- if (!clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2)) {
+ if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2)) {
sl_bump(sl);
}
clear_bit(SLF_ESCAPE, &sl->flags);
set_bit(SLF_ESCAPE, &sl->flags);
return;
case ESC_ESC:
- if (clear_bit(SLF_ESCAPE, &sl->flags)) {
+ if (test_and_clear_bit(SLF_ESCAPE, &sl->flags)) {
s = ESC;
}
break;
case ESC_END:
- if (clear_bit(SLF_ESCAPE, &sl->flags)) {
+ if (test_and_clear_bit(SLF_ESCAPE, &sl->flags)) {
s = END;
}
break;
if (test_bit(SLF_KEEPTEST, &sl->flags))
clear_bit(SLF_KEEPTEST, &sl->flags);
- if (!clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2)) {
+ if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2)) {
sl_bump(sl);
}
sl->rcount = 0;
/* Block a timer-based transmit from overlapping. This could better be
done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
- if (set_bit(0, (void*)&dev->tbusy) != 0) {
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
printk(KERN_WARNING CARDNAME": Transmitter access conflict.\n");
dev_kfree_skb (skb, FREE_WRITE);
} else {
*/
strip_info->idle_timer.expires = jiffies + HZ;
add_timer(&strip_info->idle_timer);
- if (!clear_bit(0, (void *)&strip_info->dev.tbusy))
+ if (!test_and_clear_bit(0, (void *)&strip_info->dev.tbusy))
printk(KERN_ERR "%s: trying to unlock already unlocked device!\n",
strip_info->dev.name);
}
printk(KERN_ERR "%s: xmit call when iface is down\n", dev->name);
return(1);
}
- if (set_bit(0, (void *) &strip_info->dev.tbusy)) return(1);
+ if (test_and_set_bit(0, (void *) &strip_info->dev.tbusy)) return(1);
del_timer(&strip_info->idle_timer);
/* See if someone has been ifconfigging */
}
}
- if(set_bit(0, (void *) &dev->tbusy) != 0) {
+ if(test_and_set_bit(0, (void *) &dev->tbusy) != 0) {
printk("happy meal: Transmitter access conflict.\n");
return 1;
}
return 0;
}
- if(set_bit(0, (void *) &dev->tbusy) != 0) {
+ if(test_and_set_bit(0, (void *) &dev->tbusy) != 0) {
printk("happy meal: Transmitter access conflict.\n");
return 1;
}
}
/* Block a timer-based transmit from overlapping. */
- if (set_bit (0, (void *) &dev->tbusy) != 0) {
+ if (test_and_set_bit (0, (void *) &dev->tbusy) != 0) {
printk ("Transmitter access conflict.\n");
return -1;
}
if(dev->tbusy)
return 1;
- if(set_bit(0, (void *) &dev->tbusy) != 0) {
+ if(test_and_set_bit(0, (void *) &dev->tbusy) != 0) {
printk("%s: Transmitter access conflict.\n", dev->name);
return 1;
}
if(dev->tbusy)
return 1;
- if(set_bit(0, (void *) &dev->tbusy) != 0) {
+ if(test_and_set_bit(0, (void *) &dev->tbusy) != 0) {
printk("%s: Transmitter access conflict.\n", dev->name);
return 1;
}
/* Block a timer-based transmit from overlapping. This could better be
done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
If this ever occurs the queue layer is doing something evil! */
- if (set_bit(0, (void*)&dev->tbusy) != 0) {
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
printk("%s: Transmitter access conflict.\n", dev->name);
return 1;
}
net_local * lp = (net_local *)dev->priv;
/* Check if we can do it now ! */
- if(!(dev->start) || (set_bit(0, (void *)&dev->tbusy) != 0))
+ if(!(dev->start) || (test_and_set_bit(0, (void *)&dev->tbusy) != 0))
{
lp->reconfig_82586 = 1;
#ifdef DEBUG_CONFIG_INFO
* Block a timer-based transmit from overlapping.
* In other words, prevent reentering this routine.
*/
- if(set_bit(0, (void *)&dev->tbusy) != 0)
+ if(test_and_set_bit(0, (void *)&dev->tbusy) != 0)
#ifdef DEBUG_TX_ERROR
printk(KERN_INFO "%s: Transmitter access conflict.\n", dev->name);
#endif
if (slp == NULL)
break;
/* Not in use ? */
- if (!set_bit(SLF_INUSE, &slp->ctrl.flags))
+ if (!test_and_set_bit(SLF_INUSE, &slp->ctrl.flags))
break;
}
/* SLP is set.. */
}
sl->xbuff = NULL;
- if (!clear_bit(SLF_INUSE, &sl->flags)) {
+ if (!test_and_clear_bit(SLF_INUSE, &sl->flags)) {
printk("%s: x25_asy_free for already free unit.\n", sl->dev->name);
}
}
static inline void x25_asy_lock(struct x25_asy *sl)
{
- if (set_bit(0, (void *) &sl->dev->tbusy))
+ if (test_and_set_bit(0, (void *) &sl->dev->tbusy))
printk("%s: trying to lock already locked device!\n", sl->dev->name);
}
static inline void x25_asy_unlock(struct x25_asy *sl)
{
- if (!clear_bit(0, (void *)&sl->dev->tbusy))
+ if (!test_and_clear_bit(0, (void *)&sl->dev->tbusy))
printk("%s: trying to unlock already unlocked device!\n", sl->dev->name);
}
/* Read the characters out of the buffer */
while (count--) {
if (fp && *fp++) {
- if (!set_bit(SLF_ERROR, &sl->flags)) {
+ if (!test_and_set_bit(SLF_ERROR, &sl->flags)) {
sl->rx_errors++;
}
cp++;
switch(s)
{
case X25_END:
- if (!clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2))
+ if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2))
{
x25_asy_bump(sl);
}
case X25_ESCAPE(X25_ESC):
case X25_ESCAPE(X25_END):
- if (clear_bit(SLF_ESCAPE, &sl->flags))
+ if (test_and_clear_bit(SLF_ESCAPE, &sl->flags))
s = X25_UNESCAPE(s);
break;
}
/* Block a timer-based transmit from overlapping. This could better be
done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
- if (set_bit(0, (void*)&dev->tbusy) != 0)
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name);
else {
short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
fi
dep_tristate 'PAS16 SCSI support' CONFIG_SCSI_PAS16 $CONFIG_SCSI
dep_tristate 'Qlogic FAS SCSI support' CONFIG_SCSI_QLOGIC_FAS $CONFIG_SCSI
-if [ "$CONFIG_PCI" = "y"]; then
+if [ "$CONFIG_PCI" = "y" ]; then
dep_tristate 'Qlogic ISP SCSI support' CONFIG_SCSI_QLOGIC_ISP $CONFIG_SCSI
fi
dep_tristate 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE $CONFIG_SCSI
-if [ "$CONFIG_PCI" = "y" -a "$CONFIG_SCSI_AM53C974" != "y"]; then
+if [ "$CONFIG_PCI" = "y" -a "$CONFIG_SCSI_AM53C974" != "y" ]; then
dep_tristate 'Tekram DC-390(T) (AMD PCscsi) SCSI support' CONFIG_SCSI_DC390T $CONFIG_SCSI
fi
dep_tristate 'Trantor T128/T128F/T228 SCSI support' CONFIG_SCSI_T128 $CONFIG_SCSI
/* Run the hooks that have to be done when a page I/O has completed. */
static inline void after_unlock_page (struct page * page)
{
- if (clear_bit(PG_decr_after, &page->flags))
+ if (test_and_clear_bit(PG_decr_after, &page->flags))
atomic_dec(&nr_async_pages);
- if (clear_bit(PG_free_after, &page->flags))
+ if (test_and_clear_bit(PG_free_after, &page->flags))
__free_page(page);
- if (clear_bit(PG_swap_unlock_after, &page->flags))
+ if (test_and_clear_bit(PG_swap_unlock_after, &page->flags))
swap_after_unlock_page(page->swap_unlock_entry);
}
page->offset);
req->wb_flags |= NFS_WRITE_WANTLOCK;
- if (!set_bit(PG_locked, &page->flags)) {
+ if (!test_and_set_bit(PG_locked, &page->flags)) {
transfer_page_lock(req);
} else {
printk(KERN_WARNING "NFS oops in %s: can't lock page!\n",
if (!WB_HAVELOCK(req))
req->wb_flags |= NFS_WRITE_WANTLOCK;
- if (WB_WANTLOCK(req) && set_bit(PG_locked, &page->flags)) {
+ if (WB_WANTLOCK(req) && test_and_set_bit(PG_locked, &page->flags)) {
dprintk("NFS: page already locked in writeback_lock!\n");
task->tk_timeout = 2 * HZ;
rpc_sleep_on(&write_queue, task, NULL, NULL);
int i;
for (i = 1; i < 256; i++) {
- if (!set_bit(i,unnamed_dev_in_use))
+ if (!test_and_set_bit(i,unnamed_dev_in_use))
return MKDEV(UNNAMED_MAJOR, i);
}
return 0;
{
if (!dev || MAJOR(dev) != UNNAMED_MAJOR)
return;
- if (clear_bit(MINOR(dev), unnamed_dev_in_use))
+ if (test_and_clear_bit(MINOR(dev), unnamed_dev_in_use))
return;
printk("VFS: put_unnamed_dev: freeing unused device %s\n",
kdevname(dev));
* bit 0 is the LSB of addr; bit 64 is the LSB of (addr+1).
*/
-extern __inline__ unsigned long set_bit(unsigned long nr, void * addr)
+extern __inline__ void set_bit(unsigned long nr, void * addr)
+{
+ unsigned long oldbit;
+ unsigned long temp;
+ unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
+
+ __asm__ __volatile__(
+ "1: ldl_l %0,%1\n"
+ " and %0,%3,%2\n"
+ " bne %2,2f\n"
+ " xor %0,%3,%0\n"
+ " stl_c %0,%1\n"
+ " beq %0,3f\n"
+ "2:\n"
+ ".section .text2,\"ax\"\n"
+ "3: br 1b\n"
+ ".previous"
+ :"=&r" (temp), "=m" (*m), "=&r" (oldbit)
+ :"Ir" (1UL << (nr & 31)), "m" (*m));
+}
+
+extern __inline__ void clear_bit(unsigned long nr, void * addr)
+{
+ unsigned long oldbit;
+ unsigned long temp;
+ unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
+
+ __asm__ __volatile__(
+ "1: ldl_l %0,%1\n"
+ " and %0,%3,%2\n\t"
+ " beq %2,2f\n\t"
+ " xor %0,%3,%0\n\t"
+ " stl_c %0,%1\n\t"
+ " beq %0,3f\n"
+ "2:\n"
+ ".section .text2,\"ax\"\n"
+ "3: br 1b\n"
+ ".previous"
+ :"=&r" (temp), "=m" (*m), "=&r" (oldbit)
+ :"Ir" (1UL << (nr & 31)), "m" (*m));
+}
+
+extern __inline__ void change_bit(unsigned long nr, void * addr)
+{
+ unsigned long temp;
+ unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
+
+ __asm__ __volatile__(
+ "1: ldl_l %0,%1\n"
+ " xor %0,%2,%0\n\t"
+ " stl_c %0,%1\n\t"
+ " beq %0,3f\n"
+ ".section .text2,\"ax\"\n"
+ "3: br 1b\n"
+ ".previous"
+ :"=&r" (temp), "=m" (*m)
+ :"Ir" (1UL << (nr & 31)), "m" (*m));
+}
+
+extern __inline__ unsigned long test_and_set_bit(unsigned long nr, void * addr)
{
unsigned long oldbit;
unsigned long temp;
return oldbit != 0;
}
-extern __inline__ unsigned long clear_bit(unsigned long nr, void * addr)
+extern __inline__ unsigned long test_and_clear_bit(unsigned long nr, void * addr)
{
unsigned long oldbit;
unsigned long temp;
return oldbit != 0;
}
-extern __inline__ unsigned long change_bit(unsigned long nr, void * addr)
+extern __inline__ unsigned long test_and_change_bit(unsigned long nr, void * addr)
{
unsigned long oldbit;
unsigned long temp;
#ifdef __KERNEL__
-#define ext2_set_bit set_bit
-#define ext2_clear_bit clear_bit
+#define ext2_set_bit test_and_set_bit
+#define ext2_clear_bit test_and_clear_bit
#define ext2_test_bit test_bit
#define ext2_find_first_zero_bit find_first_zero_bit
#define ext2_find_next_zero_bit find_next_zero_bit
/* Bitmap functions for the minix filesystem. */
-#define minix_set_bit(nr,addr) set_bit(nr,addr)
-#define minix_clear_bit(nr,addr) clear_bit(nr,addr)
+#define minix_set_bit(nr,addr) test_and_set_bit(nr,addr)
+#define minix_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
#define minix_test_bit(nr,addr) test_bit(nr,addr)
#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
#define ADDR (*(struct __dummy *) addr)
#define CONST_ADDR (*(const struct __dummy *) addr)
-extern __inline__ int set_bit(int nr, volatile void * addr)
+extern __inline__ void set_bit(int nr, volatile void * addr)
+{
+ __asm__ __volatile__( LOCK_PREFIX
+ "btsl %1,%0"
+ :"=m" (ADDR)
+ :"ir" (nr));
+}
+
+extern __inline__ void clear_bit(int nr, volatile void * addr)
+{
+ __asm__ __volatile__( LOCK_PREFIX
+ "btrl %1,%0"
+ :"=m" (ADDR)
+ :"ir" (nr));
+}
+
+extern __inline__ void change_bit(int nr, volatile void * addr)
+{
+ __asm__ __volatile__( LOCK_PREFIX
+ "btcl %1,%0"
+ :"=m" (ADDR)
+ :"ir" (nr));
+}
+
+extern __inline__ int test_and_set_bit(int nr, volatile void * addr)
{
int oldbit;
return oldbit;
}
-extern __inline__ int clear_bit(int nr, volatile void * addr)
+extern __inline__ int test_and_clear_bit(int nr, volatile void * addr)
{
int oldbit;
return oldbit;
}
-extern __inline__ int change_bit(int nr, volatile void * addr)
+extern __inline__ int test_and_change_bit(int nr, volatile void * addr)
{
int oldbit;
#ifdef __KERNEL__
-#define ext2_set_bit set_bit
-#define ext2_clear_bit clear_bit
+#define ext2_set_bit test_and_set_bit
+#define ext2_clear_bit test_and_clear_bit
#define ext2_test_bit test_bit
#define ext2_find_first_zero_bit find_first_zero_bit
#define ext2_find_next_zero_bit find_next_zero_bit
/* Bitmap functions for the minix filesystem. */
-#define minix_set_bit(nr,addr) set_bit(nr,addr)
-#define minix_clear_bit(nr,addr) clear_bit(nr,addr)
+#define minix_set_bit(nr,addr) test_and_set_bit(nr,addr)
+#define minix_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
#define minix_test_bit(nr,addr) test_bit(nr,addr)
#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
* first constant multiplications gets optimized away if the delay is
* a constant)
*/
-extern __inline__ void udelay(unsigned long usecs)
+extern __inline__ void __udelay(unsigned long usecs, unsigned long lps)
{
usecs *= 0x000010c6; /* 2**32 / 1000000 */
__asm__("mull %0"
:"=d" (usecs)
-#ifdef __SMP__
- :"a" (usecs),"0" (cpu_data[hard_smp_processor_id()].udelay_val)
-#else
- :"a" (usecs),"0" (loops_per_sec)
-#endif
+ :"a" (usecs),"0" (lps)
:"ax");
__delay(usecs);
}
+#ifdef __SMP__
+#define __udelay_val cpu_data[smp_processor_id()].udelay_val
+#else
+#define __udelay_val loops_per_sec
+#endif
+
+#define udelay(usecs) __udelay((usecs),__udelay_val)
+
+
extern __inline__ unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c)
{
__asm__("mull %1 ; divl %2"
#include <linux/tasks.h>
extern unsigned int local_irq_count[NR_CPUS];
-#define in_interrupt() (local_irq_count[hard_smp_processor_id()] != 0)
+#define in_interrupt() (local_irq_count[smp_processor_id()] != 0)
#ifndef __SMP__
extern inline void mark_buffer_clean(struct buffer_head * bh)
{
- if (clear_bit(BH_Dirty, &bh->b_state)) {
+ if (test_and_clear_bit(BH_Dirty, &bh->b_state)) {
if (bh->b_list == BUF_DIRTY)
refile_buffer(bh);
}
extern inline void mark_buffer_dirty(struct buffer_head * bh, int flag)
{
- if (!set_bit(BH_Dirty, &bh->b_state)) {
+ if (!test_and_set_bit(BH_Dirty, &bh->b_state)) {
set_writetime(bh, flag);
if (bh->b_list != BUF_DIRTY)
refile_buffer(bh);
extern inline void lock_buffer(struct buffer_head * bh)
{
- while (set_bit(BH_Lock, &bh->b_state))
+ while (test_and_set_bit(BH_Lock, &bh->b_state))
__wait_on_buffer(bh);
}
extern __inline__ void queue_task(struct tq_struct *bh_pointer,
task_queue *bh_list)
{
- if (!set_bit(0,&bh_pointer->sync)) {
+ if (!test_and_set_bit(0,&bh_pointer->sync)) {
unsigned long flags;
spin_lock_irqsave(&tqueue_lock, flags);
bh_pointer->next = *bh_list;
msg_level = -1;
}
__restore_flags(flags);
-#if 0 /* debugging - avoid this if we're deadlocked */
wake_up_interruptible(&log_wait);
-#endif
return i;
}
static inline void add_to_runqueue(struct task_struct * p)
{
-#if 1 /* sanity tests */
- if (p->next_run || p->prev_run) {
- printk("task already on run-queue\n");
- return;
- }
-#endif
if (p->counter > current->counter + 3)
need_resched = 1;
nr_running++;
struct task_struct *next = p->next_run;
struct task_struct *prev = p->prev_run;
-#if 1 /* sanity tests */
- if (!next || !prev) {
- printk("task not on run-queue\n");
- return;
- }
-#endif
- if (!p->pid) {
- static int nr = 0;
- if (nr < 5) {
- nr++;
- printk("idle task may not sleep\n");
- }
- return;
- }
nr_running--;
next->prev_run = prev;
prev->next_run = next;
#define TVN_MASK (TVN_SIZE - 1)
#define TVR_MASK (TVR_SIZE - 1)
-#define SLOW_BUT_DEBUGGING_TIMERS 0
-
struct timer_vec {
int index;
struct timer_list *vec[TVN_SIZE];
unsigned long flags;
spin_lock_irqsave(&timerlist_lock, flags);
-#if SLOW_BUT_DEBUGGING_TIMERS
- if (timer->next || timer->prev) {
- printk("add_timer() called with non-zero list from %p\n",
- __builtin_return_address(0));
- goto out;
- }
-#endif
internal_add_timer(timer);
-#if SLOW_BUT_DEBUGGING_TIMERS
-out:
-#endif
spin_unlock_irqrestore(&timerlist_lock, flags);
}
void wake_up(struct wait_queue **q)
{
struct wait_queue *next;
- struct wait_queue *head;
read_lock(&waitqueue_lock);
if (q && (next = *q)) {
+ struct wait_queue *head;
+
head = WAIT_QUEUE_HEAD(q);
while (next != head) {
struct task_struct *p = next->task;
next = next->next;
- if (p != NULL) {
- if ((p->state == TASK_UNINTERRUPTIBLE) ||
- (p->state == TASK_INTERRUPTIBLE))
- wake_up_process(p);
- }
- if (next)
- continue;
- printk("wait_queue is bad (eip = %p)\n",
- __builtin_return_address(0));
- printk(" q = %p\n",q);
- printk(" *q = %p\n",*q);
- break;
+ if ((p->state == TASK_UNINTERRUPTIBLE) ||
+ (p->state == TASK_INTERRUPTIBLE))
+ wake_up_process(p);
}
}
read_unlock(&waitqueue_lock);
void wake_up_interruptible(struct wait_queue **q)
{
struct wait_queue *next;
- struct wait_queue *head;
read_lock(&waitqueue_lock);
if (q && (next = *q)) {
+ struct wait_queue *head;
+
head = WAIT_QUEUE_HEAD(q);
while (next != head) {
struct task_struct *p = next->task;
next = next->next;
- if (p != NULL) {
- if (p->state == TASK_INTERRUPTIBLE)
- wake_up_process(p);
- }
- if (next)
- continue;
- printk("wait_queue is bad (eip = %p)\n",
- __builtin_return_address(0));
- printk(" q = %p\n",q);
- printk(" *q = %p\n",*q);
- break;
+ if (p->state == TASK_INTERRUPTIBLE)
+ wake_up_process(p);
}
}
read_unlock(&waitqueue_lock);
if (!p)
return;
- if (current == task[0])
- panic("task[0] trying to sleep");
current->state = state;
write_lock_irqsave(&waitqueue_lock, flags);
__add_wait_queue(p, &wait);
write_unlock(&waitqueue_lock);
- sti();
schedule();
write_lock_irq(&waitqueue_lock);
__remove_wait_queue(p, &wait);
switch (atomic_read(&page->count)) {
case 1:
/* If it has been referenced recently, don't free it */
- if (clear_bit(PG_referenced, &page->flags))
+ if (test_and_clear_bit(PG_referenced, &page->flags))
break;
/* is it a page cache page? */
}
lockit:
- while (set_bit(PG_locked, &page->flags))
+ while (test_and_set_bit(PG_locked, &page->flags))
wait_on_page(page);
/*
map_nr &= mask;
nr_free_pages -= mask;
while (mask + (1 << (NR_MEM_LISTS-1))) {
- if (!change_bit(index, area->map))
+ if (!test_and_change_bit(index, area->map))
break;
remove_mem_queue(list(map_nr ^ -mask));
mask <<= 1;
return;
}
/* Make sure we are the only process doing I/O with this swap page. */
- while (set_bit(offset,p->swap_lockmap)) {
+ while (test_and_set_bit(offset,p->swap_lockmap)) {
run_task_queue(&tq_disk);
sleep_on(&lock_queue);
}
} else
printk("rw_swap_page: no swap file or device\n");
atomic_dec(&page->count);
- if (offset && !clear_bit(offset,p->swap_lockmap))
+ if (offset && !test_and_clear_bit(offset,p->swap_lockmap))
printk("rw_swap_page: lock already cleared\n");
wake_up(&lock_queue);
}
printk("swap_after_unlock_page: weirdness\n");
return;
}
- if (!clear_bit(offset,p->swap_lockmap))
+ if (!test_and_clear_bit(offset,p->swap_lockmap))
printk("swap_after_unlock_page: lock already cleared\n");
wake_up(&lock_queue);
}
panic("ll_rw_page: bad block dev cmd, must be R/W");
}
page = mem_map + MAP_NR(buffer);
- if (set_bit(PG_locked, &page->flags))
+ if (test_and_set_bit(PG_locked, &page->flags))
panic ("ll_rw_page: page already locked");
brw_page(rw, page, dev, &block, PAGE_SIZE, 0);
}
int i;
struct file **fp = scm->fp->fp;
- if (fdnum > fdmax)
+ if (fdnum < fdmax)
fdmax = fdnum;
for (i=0, cmfptr=(int*)cm->cmsg_data; i<fdmax; i++, cmfptr++)
break;
current->files->fd[new_fd] = fp[i];
err = put_user(new_fd, cmfptr);
- cmfptr++;
}
if (i > 0)