Ejemplo n.º 1
0
/*---------------------------------------------------------------------------*
 *	Timer T4 start
 *---------------------------------------------------------------------------*/
static void
T4_start(struct isic_softc *sc)
{
	NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc));
	sc->sc_I430T4 = 1;

	START_TIMER(sc->sc_T4_callout, timer4_expired, sc, hz);
}
Ejemplo n.º 2
0
/*---------------------------------------------------------------------------*
 *	I.430 Timer T3 expire function
 *---------------------------------------------------------------------------*/
static void
timer3_expired(struct isic_softc *sc)
{
	if(sc->sc_I430T3)
	{
		NDBGL1(L1_T_ERR, "state = %s", isic_printstate(sc));
		sc->sc_I430T3 = 0;

		/* XXX try some recovery here XXX */
		switch(sc->sc_cardtyp) {
#if NNISACSX > 0
			case CARD_TYPEP_AVMA1PCIV2:
				isic_isacsx_recover(sc);
				break;
#endif /* NNISACSX > 0 */
			default:
#if NNISAC > 0
				isic_recover(sc);
#endif /* NNISAC > 0 */
				break;
		}

		sc->sc_init_tries++;	/* increment retry count */

/*XXX*/		if(sc->sc_init_tries > 4)
		{
			int s = splnet();

			sc->sc_init_tries = 0;

			if(sc->sc_obuf2 != NULL)
			{
				i4b_Dfreembuf(sc->sc_obuf2);
				sc->sc_obuf2 = NULL;
			}
			if(sc->sc_obuf != NULL)
			{
				i4b_Dfreembuf(sc->sc_obuf);
				sc->sc_obuf = NULL;
				sc->sc_freeflag = 0;
				sc->sc_op = NULL;
				sc->sc_ol = 0;
			}

			splx(s);

			isdn_layer2_status_ind(&sc->sc_l2, sc->sc_l3token, STI_NOL1ACC, 0);
		}

		isic_next_state(sc, EV_T3);
	}
	else
	{
		NDBGL1(L1_T_ERR, "expired without starting it ....");
	}
}
Ejemplo n.º 3
0
/*---------------------------------------------------------------------------*
 *	Timer T4 stop
 *---------------------------------------------------------------------------*/
static void
T4_stop(struct isic_softc *sc)
{
	NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc));

	if(sc->sc_I430T4)
	{
		sc->sc_I430T4 = 0;
		STOP_TIMER(sc->sc_T4_callout, timer4_expired, sc);
	}
}
Ejemplo n.º 4
0
/*---------------------------------------------------------------------------*
 *	I.430 Timer T3 stop
 *---------------------------------------------------------------------------*/
static void
T3_stop(struct isic_softc *sc)
{
	NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc));

	sc->sc_init_tries = 0;	/* init connect retry count */

	if(sc->sc_I430T3)
	{
		sc->sc_I430T3 = 0;
		STOP_TIMER(sc->sc_T3_callout, timer3_expired, sc);
	}
}
Ejemplo n.º 5
0
/*---------------------------------------------------------------------------*
 *	Timer T4 expire function
 *---------------------------------------------------------------------------*/
static void
timer4_expired(struct isic_softc *sc)
{
	if(sc->sc_I430T4)
	{
		NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc));
		sc->sc_I430T4 = 0;
		isdn_layer2_status_ind(&sc->sc_l2, sc->sc_l3token, STI_PDEACT, 0);
	}
	else
	{
		NDBGL1(L1_T_ERR, "expired without starting it ....");
	}
}
Ejemplo n.º 6
0
/*---------------------------------------------------------------------------*
 *	execute a layer 1 command
 *---------------------------------------------------------------------------*/
void
isic_isacsx_l1_cmd(struct isic_softc *sc, int command)
{
	u_char cmd;

#ifdef I4B_SMP_WORKAROUND

	/* XXXXXXXXXXXXXXXXXXX */

	/*
	 * patch from Wolfgang Helbig:
	 *
	 * Here is a patch that makes i4b work on an SMP:
	 * The card (TELES 16.3) didn't interrupt on an SMP machine.
	 * This is a gross workaround, but anyway it works *and* provides
	 * some information as how to finally fix this problem.
	 */

	HSCX_WRITE(0, H_MASK, 0xff);
	HSCX_WRITE(1, H_MASK, 0xff);
	ISAC_WRITE(I_MASKD, 0xff);
	ISAC_WRITE(I_MASK, 0xff);
	DELAY(100);
	HSCX_WRITE(0, H_MASK, HSCX_A_IMASK);
	HSCX_WRITE(1, H_MASK, HSCX_B_IMASK);
	ISAC_WRITE(I_MASKD, isacsx_imaskd);
	ISAC_WRITE(I_MASK, isacsx_imask);

	/* XXXXXXXXXXXXXXXXXXX */

#endif /* I4B_SMP_WORKAROUND */

	if(command < 0 || command > CMD_ILL)
	{
		NDBGL1(L1_I_ERR, "illegal cmd 0x%x in state %s", command, isic_printstate(sc));
		return;
	}

	cmd = ISACSX_CIX0_LOW;

	switch(command)
	{
		case CMD_TIM:
			NDBGL1(L1_I_CICO, "tx TIM in state %s", isic_printstate(sc));
			cmd |= (ISACSX_CIX0_CTIM << 4);
			break;

		case CMD_RS:
			NDBGL1(L1_I_CICO, "tx RS in state %s", isic_printstate(sc));
			cmd |= (ISACSX_CIX0_CRS << 4);
			break;

		case CMD_AR8:
			NDBGL1(L1_I_CICO, "tx AR8 in state %s", isic_printstate(sc));
			cmd |= (ISACSX_CIX0_CAR8 << 4);
			break;

		case CMD_AR10:
			NDBGL1(L1_I_CICO, "tx AR10 in state %s", isic_printstate(sc));
			cmd |= (ISACSX_CIX0_CAR10 << 4);
			break;

		case CMD_DIU:
			NDBGL1(L1_I_CICO, "tx DIU in state %s", isic_printstate(sc));
			cmd |= (ISACSX_CIX0_CDIU << 4);
			break;
	}
	ISAC_WRITE(I_CIX0, cmd);
}
Ejemplo n.º 7
0
/*---------------------------------------------------------------------------*
 *	ISACSX L1 Indication handler
 *---------------------------------------------------------------------------*/
static void
isic_isacsx_ind_hdlr(register struct isic_softc *sc, int ind)
{
	register int event;

	switch(ind)
	{
		case ISACSX_CIR0_IAI8:
			NDBGL1(L1_I_CICO, "rx AI8 in state %s", isic_printstate(sc));
			if(sc->sc_bustyp == BUS_TYPE_IOM2)
				isic_isacsx_l1_cmd(sc, CMD_AR8);
			event = EV_INFO48;
			isdn_layer2_status_ind(&sc->sc_l2, sc->sc_l3token, STI_L1STAT, LAYER_ACTIVE);
			break;

		case ISACSX_CIR0_IAI10:
			NDBGL1(L1_I_CICO, "rx AI10 in state %s", isic_printstate(sc));
			if(sc->sc_bustyp == BUS_TYPE_IOM2)
				isic_isacsx_l1_cmd(sc, CMD_AR10);
			event = EV_INFO410;
			isdn_layer2_status_ind(&sc->sc_l2, sc->sc_l3token, STI_L1STAT, LAYER_ACTIVE);
			break;

		case ISACSX_CIR0_IRSY:
			NDBGL1(L1_I_CICO, "rx RSY in state %s", isic_printstate(sc));
			event = EV_RSY;
			break;

		case ISACSX_CIR0_IPU:
			NDBGL1(L1_I_CICO, "rx PU in state %s", isic_printstate(sc));
			event = EV_PU;
			break;

		case ISACSX_CIR0_IDR:
			NDBGL1(L1_I_CICO, "rx DR in state %s", isic_printstate(sc));
			isic_isacsx_l1_cmd(sc, CMD_DIU);
			event = EV_DR;
			break;

		case ISACSX_CIR0_IDID:
			NDBGL1(L1_I_CICO, "rx DID in state %s", isic_printstate(sc));
			event = EV_INFO0;
			isdn_layer2_status_ind(&sc->sc_l2, sc->sc_l3token, STI_L1STAT, LAYER_IDLE);
			break;

		case ISACSX_CIR0_IDIS:
			NDBGL1(L1_I_CICO, "rx DIS in state %s", isic_printstate(sc));
			event = EV_DIS;
			break;

		case ISACSX_CIR0_IEI:
			NDBGL1(L1_I_CICO, "rx EI in state %s", isic_printstate(sc));
			isic_isacsx_l1_cmd(sc, CMD_DIU);
			event = EV_EI;
			break;

		case ISACSX_CIR0_IARD:
			NDBGL1(L1_I_CICO, "rx ARD in state %s", isic_printstate(sc));
			event = EV_INFO2;
			break;

		case ISACSX_CIR0_ITI:
			NDBGL1(L1_I_CICO, "rx TI in state %s", isic_printstate(sc));
			event = EV_INFO0;
			break;

		case ISACSX_CIR0_IATI:
			NDBGL1(L1_I_CICO, "rx ATI in state %s", isic_printstate(sc));
			event = EV_INFO0;
			break;

		case ISACSX_CIR0_ISD:
			NDBGL1(L1_I_CICO, "rx SD in state %s", isic_printstate(sc));
			event = EV_INFO0;
			break;

		default:
			NDBGL1(L1_I_ERR, "UNKNOWN Indication 0x%x in state %s", ind, isic_printstate(sc));
			event = EV_INFO0;
			break;
	}
	isic_next_state(sc, event);
}
Ejemplo n.º 8
0
/*---------------------------------------------------------------------------*
 *
 *	L2 -> L1: PH-DATA-REQUEST
 *	=========================
 *
 *	parms:
 *		token		softc of physical driver
 *		m		mbuf containing L2 frame to be sent out
 *		freeflag	MBUF_FREE: free mbuf here after having sent
 *						it out
 *				MBUF_DONTFREE: mbuf is freed by Layer 2
 *	returns:
 *		==0	fail, nothing sent out
 *		!=0	ok, frame sent out
 *
 *---------------------------------------------------------------------------*/
static int
isic_std_ph_data_req(isdn_layer1token token, struct mbuf *m, int freeflag)
{
	struct isic_softc *sc = (struct isic_softc*)token;
	u_char cmd;
	int s;

	if (m == NULL)			/* failsafe */
		return (0);

	s = splnet();

	if(sc->sc_I430state == ST_F3)	/* layer 1 not running ? */
	{
		NDBGL1(L1_I_ERR, "still in state F3!");
		isic_std_ph_activate_req(token);
	}

	if(sc->sc_state & ISAC_TX_ACTIVE)
	{
		if(sc->sc_obuf2 == NULL)
		{
			sc->sc_obuf2 = m;		/* save mbuf ptr */

			if(freeflag)
				sc->sc_freeflag2 = 1;	/* IRQ must mfree */
			else
				sc->sc_freeflag2 = 0;	/* IRQ must not mfree */

			NDBGL1(L1_I_MSG, "using 2nd ISAC TX buffer, state = %s", isic_printstate(sc));

			if(sc->sc_trace & TRACE_D_TX)
			{
				i4b_trace_hdr hdr;
				hdr.type = TRC_CH_D;
				hdr.dir = FROM_TE;
				hdr.count = ++sc->sc_trace_dcount;
				isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, m->m_len, m->m_data);
			}
			splx(s);
			return(1);
		}

		NDBGL1(L1_I_ERR, "No Space in TX FIFO, state = %s", isic_printstate(sc));

		if(freeflag == MBUF_FREE)
			i4b_Dfreembuf(m);

		splx(s);
		return (0);
	}

	if(sc->sc_trace & TRACE_D_TX)
	{
		i4b_trace_hdr hdr;
		hdr.type = TRC_CH_D;
		hdr.dir = FROM_TE;
		hdr.count = ++sc->sc_trace_dcount;
		isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, m->m_len, m->m_data);
	}

	sc->sc_state |= ISAC_TX_ACTIVE;	/* set transmitter busy flag */

	NDBGL1(L1_I_MSG, "ISAC_TX_ACTIVE set");

	sc->sc_freeflag = 0;		/* IRQ must NOT mfree */

	ISAC_WRFIFO(m->m_data, min(m->m_len, ISAC_FIFO_LEN)); /* output to TX fifo */

	if(m->m_len > ISAC_FIFO_LEN)	/* message > 32 bytes ? */
	{
		sc->sc_obuf = m;	/* save mbuf ptr */
		sc->sc_op = m->m_data + ISAC_FIFO_LEN; 	/* ptr for irq hdl */
		sc->sc_ol = m->m_len - ISAC_FIFO_LEN;	/* length for irq hdl */

		if(freeflag)
			sc->sc_freeflag = 1;	/* IRQ must mfree */

		cmd = ISAC_CMDR_XTF;
	}
	else
	{
		sc->sc_obuf = NULL;
		sc->sc_op = NULL;
		sc->sc_ol = 0;

		if(freeflag)
			i4b_Dfreembuf(m);

		cmd = ISAC_CMDR_XTF | ISAC_CMDR_XME;
  	}

	ISAC_WRITE(I_CMDR, cmd);
	ISACCMDRWRDELAY();

	splx(s);

	return(1);
}
Ejemplo n.º 9
0
/*---------------------------------------------------------------------------*
 *
 *	L2 -> L1: PH-DATA-REQUEST
 *	=========================
 *
 *	parms:
 *		unit		physical interface unit number
 *		m		mbuf containing L2 frame to be sent out
 *		freeflag	MBUF_FREE: free mbuf here after having sent
 *						it out
 *				MBUF_DONTFREE: mbuf is freed by Layer 2
 *	returns:
 *		==0	fail, nothing sent out
 *		!=0	ok, frame sent out
 *
 *---------------------------------------------------------------------------*/
int
isic_ph_data_req(int unit, struct mbuf *m, int freeflag)
{
	u_char cmd;
	int s;
	struct l1_softc *sc = &l1_sc[unit];

#ifdef NOTDEF
	NDBGL1(L1_PRIM, "unit %d, freeflag=%d", unit, freeflag);
#endif

	if(m == NULL)			/* failsafe */
		return (0);

	s = SPLI4B();

	if(sc->sc_I430state == ST_F3)	/* layer 1 not running ? */
	{
		NDBGL1(L1_I_ERR, "still in state F3!");
		isic_ph_activate_req(unit);
	}

	if(sc->sc_state & ISAC_TX_ACTIVE)
	{
		if(sc->sc_obuf2 == NULL)
		{
			sc->sc_obuf2 = m;		/* save mbuf ptr */

			if(freeflag)
				sc->sc_freeflag2 = 1;	/* IRQ must mfree */
			else
				sc->sc_freeflag2 = 0;	/* IRQ must not mfree */

			NDBGL1(L1_I_MSG, "using 2nd ISAC TX buffer, state = %s", isic_printstate(sc));

			if(sc->sc_trace & TRACE_D_TX)
			{
				i4b_trace_hdr_t hdr;
				hdr.unit = L0ISICUNIT(unit);
				hdr.type = TRC_CH_D;
				hdr.dir = FROM_TE;
				hdr.count = ++sc->sc_trace_dcount;
				MICROTIME(hdr.time);
				i4b_l1_trace_ind(&hdr, m->m_len, m->m_data);
			}
			splx(s);
			return(1);
		}

		NDBGL1(L1_I_ERR, "No Space in TX FIFO, state = %s", isic_printstate(sc));
	
		if(freeflag == MBUF_FREE)
			i4b_Dfreembuf(m);			
	
		splx(s);
		return (0);
	}

	if(sc->sc_trace & TRACE_D_TX)
	{
		i4b_trace_hdr_t hdr;
		hdr.unit = L0ISICUNIT(unit);
		hdr.type = TRC_CH_D;
		hdr.dir = FROM_TE;
		hdr.count = ++sc->sc_trace_dcount;
		MICROTIME(hdr.time);
		i4b_l1_trace_ind(&hdr, m->m_len, m->m_data);
	}
	
	sc->sc_state |= ISAC_TX_ACTIVE;	/* set transmitter busy flag */

	NDBGL1(L1_I_MSG, "ISAC_TX_ACTIVE set");

	sc->sc_freeflag = 0;		/* IRQ must NOT mfree */
	
	ISAC_WRFIFO(m->m_data, min(m->m_len, ISAC_FIFO_LEN)); /* output to TX fifo */

	if(m->m_len > ISAC_FIFO_LEN)	/* message > 32 bytes ? */
	{
		sc->sc_obuf = m;	/* save mbuf ptr */
		sc->sc_op = m->m_data + ISAC_FIFO_LEN; 	/* ptr for irq hdl */
		sc->sc_ol = m->m_len - ISAC_FIFO_LEN;	/* length for irq hdl */

		if(freeflag)
			sc->sc_freeflag = 1;	/* IRQ must mfree */
		
		cmd = ISAC_CMDR_XTF;
	}
	else
	{
		sc->sc_obuf = NULL;
		sc->sc_op = NULL;
		sc->sc_ol = 0;

		if(freeflag)
			i4b_Dfreembuf(m);

		cmd = ISAC_CMDR_XTF | ISAC_CMDR_XME;
  	}

	ISAC_WRITE(I_CMDR, cmd);
	ISACCMDRWRDELAY();

	splx(s);
	
	return(1);
}