Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 9 Jan 2013 10:15:39 +0100
From:      Hans Petter Selasky <hselasky@c2i.net>
To:        Andreas Longwitz <longwitz@incore.de>
Cc:        freebsd-isdn@freebsd.org
Subject:   Re: ISDN4BSD (HPS version) is going into ports
Message-ID:  <201301091015.39124.hselasky@c2i.net>
In-Reply-To: <50ECAEBB.3030604@incore.de>
References:  <509E87EF.9070607@incore.de> <201212021043.53151.hselasky@c2i.net> <50ECAEBB.3030604@incore.de>

next in thread | previous in thread | raw e-mail | index | archive | help
--Boundary-00=_7UT7Qc0cZWUWRf1
Content-Type: Text/Plain;
  charset="iso-8859-15"
Content-Transfer-Encoding: 7bit

On Wednesday 09 January 2013 00:41:47 Andreas Longwitz wrote:
> Hans Petter Selasky wrote:
> 
> Hi,
> 
> i have continued to get my AVM Fritz!Card version 2 PCI card working
> with isdn4bsd using isdnd and there is some progress: D-channel works
> correct now with isdn4bsd 2.0.6 and the following patch:
> 
> --- i4b_filter.h.orig   2009-01-09 20:07:38.000000000 +0100
> +++ i4b_filter.h        2013-01-08 18:23:01.000000000 +0100
> @@ -158,6 +158,12 @@
>          (f->buf_len)     -= (io_len);
>          (f->Z_chip)      -= (io_len);
> 
> +        /* Hack:  <AVM Fritz!Card version 2 PCI> is ihfc1 */
> +        if((FIFO_NO(f) == d1r) && sc->sc_nametmp[4] == '1' ) {
> +           (f->buf_ptr)     -= 1;
> +           (f->buf_len)     += 1;
> +       }
> +
>         return;
>  }

Can you try the attached patch instead? And revert the one above?

> 
> I have analyzed the i4b_ifpi2_pci.c source from FreeBSD 6 (nearly
> identical to the NetBSD source ifpci2.c) and found that your patch
> brings us a step forward to the way the BSD-source ifpci2.c works.
> But there are some more differences between isdn4bsd and BSD:
> 
> 1. Access to the PCI bus via mem in isdn4bsd, via I/O port in BSD.
> 2. DELAY times on startup is different: 4 ms in isdn4bsd, 10 ms in BSD
> 3. Initializing the chip is more expansive in BSD, otherwise the
>    register cmdrd is only used in isdn4bsd.
> 4. In avm_pci_fifo_reset() we write two single bytes, but BSD does one
>    (atomic) four byte read. Particularly we do not write the HSCX_LEN
>    byte between the both written bytes (must set to 0 ?)
> 5. In avm_pci_b_status_read() - analog to 4. - we read two single bytes,
>    BSD (atomic) four bytes.
> 6. After an interrupt BSD checks explicit HSCX_INT_MASK before working,
>    Afterwords the use of HSCX_INT_RPR and HSCX_INT_XPR seems a little
>    bit different to me.
> 7. isdn4bsd and BSD both set HSCX_MODE_TRANS at startup, but BSD changes
>    this to HSCX_MODE_ITF_FLAG (ITF: interframe time fill) at the moment
>    a B-channel is coming up. Simultaneously the HSCX_CMD_RRS bit is
>    dropped (RRS = ?).

There is no specific reason. Some of this programming was guessed based on 
other drivers and common thinking in this area.

Please fix if something is wrong. However, note that my driver only uses 
transparent mode and HDLC emulation. This makes the driver much simpler.

> 
> Especially the last point does not have a counterpart in isdn4bsd - or I
> am wrong ?

--HPS

--Boundary-00=_7UT7Qc0cZWUWRf1
Content-Type: text/x-patch;
  charset="iso-8859-15";
  name="avm_pci.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
	filename="avm_pci.diff"

Index: src/sys/i4b/layer1/ihfc3/i4b_avm_pci.h
===================================================================
--- src/sys/i4b/layer1/ihfc3/i4b_avm_pci.h	(revision 2522)
+++ src/sys/i4b/layer1/ihfc3/i4b_avm_pci.h	(working copy)
@@ -113,9 +113,19 @@
 
 	if(reg & 0x80)
 	{
+	    IHFC_LEN_T x;
+
+	    /* sanity check */
+	    if (len > (sizeof(sc->sc_buffer) / 4))
+		len = (sizeof(sc->sc_buffer) / 4);
+
 	    /* ISAC-SX REGISTER */
 	    bus_space_write_4(t, h, REG_ISACSX_INDEX, (reg & 0x7F));
-	    bus_space_read_multi_1(t, h, REG_ISACSX_DATA, ptr, len);
+	    bus_space_read_multi_4(t, h, REG_ISACSX_DATA,
+		(u_int32_t *)sc->sc_buffer, len);
+
+	    for (x = 0; x != len; x++)
+		ptr[x] = ((u_int32_t *)sc->sc_buffer)[x];
 	}
 	else
 	{
@@ -130,6 +140,24 @@
 	if(FIFO_NO(f) == d1r)
 	{
 	    avm_pci_chip_read(sc,(f->fm.h.Zdata),ptr,len);
+
+	    sc->sc_d1r_fifo_keep_len -= len;
+
+	    /*
+	     * The RSTAD register is always appended to every frame.
+	     * Remove that byte.
+	     */
+	    if (sc->sc_d1r_fifo_keep_len == 0 &&
+		sc->sc_d1r_fifo_strip_len != 0) {
+		IPAC_BUS_VAR(sc);
+
+		if (len == 0) {
+			bus_space_write_4(t, h, REG_ISACSX_INDEX,
+			    (f->fm.h.Zdata & 0x7F));
+		}
+		bus_space_read_4(t, h, REG_ISACSX_DATA);
+		sc->sc_d1r_fifo_strip_len = 0;
+	    }
 	}
 	else
 	{
@@ -148,9 +176,19 @@
 
 	if(reg & 0x80)
 	{
+	    IHFC_LEN_T x;
+
+	    /* sanity check */
+	    if (len > (sizeof(sc->sc_buffer) / 4))
+		len = (sizeof(sc->sc_buffer) / 4);
+
+	    for (x = 0; x != len; x++)
+		((u_int32_t *)sc->sc_buffer)[x] = ptr[x];
+
 	    /* ISAC-SX REGISTER */
 	    bus_space_write_4(t, h, REG_ISACSX_INDEX, (reg & 0x7F));
-	    bus_space_write_multi_1(t, h, REG_ISACSX_DATA, ptr, len);
+	    bus_space_write_multi_4(t, h, REG_ISACSX_DATA,
+		(u_int32_t *)sc->sc_buffer, len);
 	}
 	else
 	{
@@ -214,9 +252,6 @@
 avm_pci_b_status_read(ihfc_sc_t *sc, ihfc_fifo_t *f, u_int8_t offset)
 {
 	IPAC_BUS_VAR(sc);
-
-	/* allocate a buffer on the stack */
-	u_int8_t buffer[0x40 + 0x10] __aligned(4);
 	u_int8_t temp;
 
 	/* read status */
@@ -258,9 +293,9 @@
 
 	    /* read FIFO */
 	    bus_space_read_multi_4(t, h, offset + HSCX_FIFO, 
-				   (void *)&buffer[0], (temp+3)/4);
+		(u_int32_t *)sc->sc_buffer, (temp + 3) / 4);
 
-	    (f+receive)->Z_ptr = &buffer[0];
+	    (f+receive)->Z_ptr = (u_int8_t *)sc->sc_buffer;
 	    (f+receive)->Z_chip = temp;
 
 	    /* call filter */
@@ -280,7 +315,7 @@
 	    temp = 32;
 
 	    (f+transmit)->i_ista &= ~(I_ISTA_ERR|I_ISTA_XPR);
-	    (f+transmit)->Z_ptr = &buffer[0];
+	    (f+transmit)->Z_ptr = (u_int8_t *)sc->sc_buffer;
 	    (f+transmit)->Z_chip = temp;
 
 	    /* call filter */
@@ -300,9 +335,16 @@
 	    /* update state */
 	    (f+transmit)->state &= ~(ST_FRAME_ERROR|ST_FRAME_END);
 
+	    /* write FIFO length */
+	    bus_space_write_1(t, h, offset + HSCX_LEN, 0);
+
+	    /* write FIFO command */
+	    bus_space_write_1(t, h, offset + HSCX_STAT,
+		HSCX_CMD_XME);
+
 	    /* write FIFO */
 	    bus_space_write_multi_4(t, h, offset + HSCX_FIFO, 
-				    (void *)&buffer[0], (temp+3)/4);
+		(u_int32_t *)sc->sc_buffer, (temp + 3) / 4);
 	}
 	return;
 }
@@ -345,6 +387,14 @@
 		    avm_pci_chip_read(sc, REG_isacsx_rbcld, &temp, 1);
 		    sc->sc_fifo[d1r].Z_chip = temp;
 
+		    if (temp != 0) {
+			sc->sc_d1r_fifo_strip_len = 1;
+			sc->sc_d1r_fifo_keep_len = temp - 1;
+		    } else {
+			sc->sc_d1r_fifo_strip_len = 0;
+			sc->sc_d1r_fifo_keep_len = 0;
+		    }
+
 		    /* read RSTA (ISAC) */
 		    avm_pci_chip_read(sc, REG_isacsx_rstad, &temp, 1);
 		    sc->sc_fifo[d1r].F_chip = temp;
Index: src/sys/i4b/layer1/ihfc3/i4b_ihfc2.h
===================================================================
--- src/sys/i4b/layer1/ihfc3/i4b_ihfc2.h	(revision 2522)
+++ src/sys/i4b/layer1/ihfc3/i4b_ihfc2.h	(working copy)
@@ -2583,7 +2583,7 @@
 	struct usb_callout	sc_pollout_timr;      /* T50 ms  */
 	struct usb_callout	sc_pollout_timr_wait; /* T125 us */
 
-	u_int8_t		sc_buffer[1024];
+	u_int8_t		sc_buffer[1024] __aligned(4);
   
 	struct sc_fifo *	sc_fifo_select_last; /* used by 
 						      * FIFO_SELECT(,) 
@@ -2600,6 +2600,9 @@
 
 	u_int16_t		sc_f0_counter_offset;
 	u_int32_t		sc_f0_counter_last;
+
+	u_int8_t		sc_d1r_fifo_strip_len;
+	u_int8_t		sc_d1r_fifo_keep_len;
 };
 
 /*---------------------------------------------------------------------------*

--Boundary-00=_7UT7Qc0cZWUWRf1--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201301091015.39124.hselasky>