1 /* $NetBSD: ifpci.c,v 1.29 2009/11/26 15:17:10 njoly Exp $ */
3 * Copyright (c) 1999 Gary Jennejohn. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the author nor the names of any co-contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 * 4. Altered versions must be plainly marked as such, and must not be
18 * misrepresented as being the original software and/or documentation.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 *---------------------------------------------------------------------------
33 * a lot of code was borrowed from i4b_bchan.c and i4b_hscx.c
34 *---------------------------------------------------------------------------
36 * Fritz!Card PCI driver
37 * ------------------------------------------------
39 * $Id: ifpci.c,v 1.30 2009/12/06 23:14:05 dyoung Exp $
41 * last edit-date: [Fri Jan 5 11:38:58 2001]
43 *---------------------------------------------------------------------------*/
45 #include <sys/cdefs.h>
46 __KERNEL_RCSID(0, "$NetBSD: ifpci.c,v 1.29 2009/11/26 15:17:10 njoly Exp $");
49 #include <sys/param.h>
50 #include <sys/ioctl.h>
51 #include <sys/kernel.h>
52 #include <sys/systm.h>
56 #include <sys/device.h>
58 #include <sys/socket.h>
61 #include <sys/callout.h>
63 #include <dev/pci/pcireg.h>
64 #include <dev/pci/pcivar.h>
65 #include <dev/pci/pcidevs.h>
66 #include <netisdn/i4b_debug.h>
67 #include <netisdn/i4b_ioctl.h>
69 #include <netisdn/i4b_global.h>
70 #include <netisdn/i4b_l2.h>
71 #include <netisdn/i4b_l1l2.h>
72 #include <netisdn/i4b_trace.h>
73 #include <netisdn/i4b_mbuf.h>
75 #include <dev/ic/isic_l1.h>
76 #include <dev/ic/isac.h>
77 #include <dev/ic/hscx.h>
79 #include <dev/pci/isic_pci.h>
81 /* PCI config map to use (only one in this driver) */
82 #define FRITZPCI_PORT0_IO_MAPOFF PCI_MAPREG_START+4
83 #define FRITZPCI_PORT0_MEM_MAPOFF PCI_MAPREG_START
85 static isdn_link_t
*avma1pp_ret_linktab(void *token
, int channel
);
86 static void avma1pp_set_link(void *token
, int channel
, const struct isdn_l4_driver_functions
*l4_driver
, void *l4_driver_softc
);
88 void n_connect_request(struct call_desc
*cd
);
89 void n_connect_response(struct call_desc
*cd
, int response
, int cause
);
90 void n_disconnect_request(struct call_desc
*cd
, int cause
);
91 void n_alert_request(struct call_desc
*cd
);
92 void n_mgmt_command(struct isdn_l3_driver
*drv
, int cmd
, void *parm
);
94 extern const struct isdn_layer1_isdnif_driver isic_std_driver
;
96 const struct isdn_l3_driver_functions
102 n_disconnect_request
,
110 struct isic_softc sc_isic
; /* parent class */
112 /* PCI-specific goo */
113 void *sc_ih
; /* interrupt handler */
116 pci_chipset_tag_t sc_pc
;
120 static void avma1pp_disable(struct isic_softc
*);
121 static int isic_hscx_fifo(l1_bchan_state_t
*chan
, struct isic_softc
*sc
);
123 static int avma1pp_intr(void*);
124 static void avma1pp_read_fifo(struct isic_softc
*sc
, int what
, void *buf
, size_t size
);
125 static void avma1pp_write_fifo(struct isic_softc
*sc
, int what
, const void *buf
, size_t size
);
126 static void avma1pp_write_reg(struct isic_softc
*sc
, int what
, bus_size_t offs
, u_int8_t data
);
127 static u_int8_t
avma1pp_read_reg(struct isic_softc
*sc
, int what
, bus_size_t offs
);
128 static void hscx_write_fifo(int chan
, const void *buf
, size_t len
, struct isic_softc
*sc
);
129 static void hscx_read_fifo(int chan
, void *buf
, size_t len
, struct isic_softc
*sc
);
130 static void hscx_write_reg(int chan
, u_int off
, u_int val
, struct isic_softc
*sc
);
131 static u_char
hscx_read_reg(int chan
, u_int off
, struct isic_softc
*sc
);
132 static u_int
hscx_read_reg_int(int chan
, u_int off
, struct isic_softc
*sc
);
133 static void avma1pp_bchannel_stat(isdn_layer1token
, int h_chan
, bchan_statistics_t
*bsp
);
134 static void avma1pp_map_int(struct ifpci_softc
*sc
, struct pci_attach_args
*pa
);
135 static void avma1pp_bchannel_setup(isdn_layer1token
, int h_chan
, int bprot
, int activate
);
136 static void avma1pp_init_linktab(struct isic_softc
*);
137 static int ifpci_match(device_t parent
, cfdata_t match
, void *aux
);
138 static void ifpci_attach(device_t parent
, device_t self
, void *aux
);
139 static int ifpci_detach(device_t self
, int flags
);
140 static int ifpci_activate(device_t self
, enum devact act
);
142 CFATTACH_DECL(ifpci
, sizeof(struct ifpci_softc
),
143 ifpci_match
, ifpci_attach
, ifpci_detach
, ifpci_activate
);
145 /*---------------------------------------------------------------------------*
146 * AVM PCI Fritz!Card special registers
147 *---------------------------------------------------------------------------*/
150 * register offsets from i/o base
152 #define STAT0_OFFSET 0x02
153 #define STAT1_OFFSET 0x03
154 #define ADDR_REG_OFFSET 0x04
155 /*#define MODREG_OFFSET 0x06
156 #define VERREG_OFFSET 0x07*/
158 /* these 2 are used to select an ISAC register set */
159 #define ISAC_LO_REG_OFFSET 0x04
160 #define ISAC_HI_REG_OFFSET 0x06
162 /* offset higher than this goes to the HI register set */
163 #define MAX_LO_REG_OFFSET 0x2f
165 /* mask for the offset */
166 #define ISAC_REGSET_MASK 0x0f
168 /* the offset from the base to the ISAC registers */
169 #define ISAC_REG_OFFSET 0x10
171 /* the offset from the base to the ISAC FIFO */
172 #define ISAC_FIFO 0x02
174 /* not really the HSCX, but sort of */
175 #define HSCX_FIFO 0x00
176 #define HSCX_STAT 0x04
179 * AVM PCI Status Latch 0 read only bits
181 #define ASL_IRQ_ISAC 0x01 /* ISAC interrupt, active low */
182 #define ASL_IRQ_HSCX 0x02 /* HSX interrupt, active low */
183 #define ASL_IRQ_TIMER 0x04 /* Timer interrupt, active low */
184 #define ASL_IRQ_BCHAN ASL_IRQ_HSCX
185 /* actually active LOW */
186 #define ASL_IRQ_Pending (ASL_IRQ_ISAC | ASL_IRQ_HSCX | ASL_IRQ_TIMER)
189 * AVM Status Latch 0 write only bits
191 #define ASL_RESET_ALL 0x01 /* reset siemens IC's, active 1 */
192 #define ASL_TIMERDISABLE 0x02 /* active high */
193 #define ASL_TIMERRESET 0x04 /* active high */
194 #define ASL_ENABLE_INT 0x08 /* active high */
195 #define ASL_TESTBIT 0x10 /* active high */
198 * AVM Status Latch 1 write only bits
200 #define ASL1_INTSEL 0x0f /* active high */
201 #define ASL1_ENABLE_IOM 0x80 /* active high */
206 #define HSCX_MODE_ITF_FLG 0x01
207 #define HSCX_MODE_TRANS 0x02
208 #define HSCX_MODE_CCR_7 0x04
209 #define HSCX_MODE_CCR_16 0x08
210 #define HSCX_MODE_TESTLOOP 0x80
215 #define HSCX_STAT_RME 0x01
216 #define HSCX_STAT_RDO 0x10
217 #define HSCX_STAT_CRCVFRRAB 0x0E
218 #define HSCX_STAT_CRCVFR 0x06
219 #define HSCX_STAT_RML_MASK 0x3f00
222 * "HSCX" interrupt bits
224 #define HSCX_INT_XPR 0x80
225 #define HSCX_INT_XDU 0x40
226 #define HSCX_INT_RPR 0x20
227 #define HSCX_INT_MASK 0xE0
230 * "HSCX" command bits
232 #define HSCX_CMD_XRS 0x80
233 #define HSCX_CMD_XME 0x01
234 #define HSCX_CMD_RRS 0x20
235 #define HSCX_CMD_XML_MASK 0x3f00
238 * Commands and parameters are sent to the "HSCX" as a long, but the
239 * fields are handled as bytes.
242 * (prot << 16)|(txl << 8)|cmd
245 * prot = protocol to use
246 * txl = transmit length
247 * cmd = the command to be executed
249 * The fields are defined as u_char in struct isic_softc.
251 * Macro to coalesce the byte fields into a u_int
253 #define AVMA1PPSETCMDLONG(f) (f) = ((sc->avma1pp_cmd) | (sc->avma1pp_txl << 8) \
254 | (sc->avma1pp_prot << 16))
257 * to prevent deactivating the "HSCX" when both channels are active we
258 * define an HSCX_ACTIVE flag which is or'd into the channel's state
259 * flag in avma1pp_bchannel_setup upon active and cleared upon deactivation.
260 * It is set high to allow room for new flags.
262 #define HSCX_AVMA1PP_ACTIVE 0x1000
265 ifpci_match(device_t parent
, cfdata_t match
, void *aux
)
267 struct pci_attach_args
*pa
= aux
;
269 if (PCI_VENDOR(pa
->pa_id
) == PCI_VENDOR_AVM
&&
270 PCI_PRODUCT(pa
->pa_id
) == PCI_PRODUCT_AVM_FRITZ_CARD
)
276 ifpci_attach(device_t parent
, device_t self
, void *aux
)
278 struct ifpci_softc
*psc
= device_private(self
);
279 struct pci_attach_args
*pa
= aux
;
280 struct isic_softc
*sc
= &psc
->sc_isic
;
281 struct isdn_l3_driver
*drv
;
285 printf(": Fritz!PCI card\n");
288 callout_init(&sc
->sc_T3_callout
, 0);
289 callout_init(&sc
->sc_T4_callout
, 0);
291 /* setup io mappings */
292 sc
->sc_cardtyp
= CARD_TYPEP_AVMA1PCI
;
293 sc
->sc_num_mappings
= 1;
295 sc
->sc_maps
[0].size
= 0;
296 if (pci_mapreg_map(pa
, FRITZPCI_PORT0_MEM_MAPOFF
, PCI_MAPREG_TYPE_MEM
, 0,
297 &sc
->sc_maps
[0].t
, &sc
->sc_maps
[0].h
, &psc
->sc_base
, &psc
->sc_size
) != 0
298 && pci_mapreg_map(pa
, FRITZPCI_PORT0_IO_MAPOFF
, PCI_MAPREG_TYPE_IO
, 0,
299 &sc
->sc_maps
[0].t
, &sc
->sc_maps
[0].h
, &psc
->sc_base
, &psc
->sc_size
) != 0) {
300 aprint_error_dev(&sc
->sc_dev
, "can't map card\n");
304 /* setup access routines */
307 sc
->readreg
= avma1pp_read_reg
;
308 sc
->writereg
= avma1pp_write_reg
;
310 sc
->readfifo
= avma1pp_read_fifo
;
311 sc
->writefifo
= avma1pp_write_fifo
;
314 /* setup card type */
316 sc
->sc_cardtyp
= CARD_TYPEP_AVMA1PCI
;
318 /* setup IOM bus type */
320 sc
->sc_bustyp
= BUS_TYPE_IOM2
;
322 /* this is no IPAC based card */
324 sc
->sc_bfifolen
= HSCX_FIFO_LEN
;
326 /* setup interrupt mapping */
327 avma1pp_map_int(psc
, pa
);
330 /* the Linux driver does this to clear any pending ISAC interrupts */
331 /* see if it helps any - XXXX */
333 v
= ISAC_READ(I_STAR
);
334 v
= ISAC_READ(I_MODE
);
335 v
= ISAC_READ(I_ADF2
);
336 v
= ISAC_READ(I_ISTA
);
337 if (v
& ISAC_ISTA_EXI
)
339 v
= ISAC_READ(I_EXIR
);
341 v
= ISAC_READ(I_CIRR
);
342 ISAC_WRITE(I_MASK
, 0xff);
343 /* the Linux driver does this to clear any pending HSCX interrupts */
344 v
= hscx_read_reg_int(0, HSCX_STAT
, sc
);
345 v
= hscx_read_reg_int(1, HSCX_STAT
, sc
);
347 bus_space_write_1(sc
->sc_maps
[0].t
, sc
->sc_maps
[0].h
, STAT0_OFFSET
, ASL_RESET_ALL
|ASL_TIMERDISABLE
);
348 DELAY(SEC_DELAY
/100); /* 10 ms */
349 bus_space_write_1(sc
->sc_maps
[0].t
, sc
->sc_maps
[0].h
, STAT0_OFFSET
, ASL_TIMERRESET
|ASL_ENABLE_INT
|ASL_TIMERDISABLE
);
350 DELAY(SEC_DELAY
/100); /* 10 ms */
352 /* setup i4b infrastructure (have to roll our own here) */
354 /* sc->sc_isac_version = ((ISAC_READ(I_RBCH)) >> 5) & 0x03; */
355 printf("%s: ISAC %s (IOM-%c)\n", device_xname(&sc
->sc_dev
),
356 "2085 Version A1/A2 or 2086/2186 Version 1.1",
357 sc
->sc_bustyp
== BUS_TYPE_IOM1
? '1' : '2');
362 /* init the "HSCX" */
363 avma1pp_bchannel_setup(sc
, HSCX_CH_A
, BPROT_NONE
, 0);
365 avma1pp_bchannel_setup(sc
, HSCX_CH_B
, BPROT_NONE
, 0);
367 /* can't use the normal B-Channel stuff */
368 avma1pp_init_linktab(sc
);
370 /* set trace level */
372 sc
->sc_trace
= TRACE_OFF
;
374 sc
->sc_state
= ISAC_IDLE
;
386 sc
->sc_freeflag2
= 0;
388 /* init higher protocol layers */
389 drv
= isdn_attach_isdnif(device_xname(&sc
->sc_dev
),
390 "AVM Fritz!PCI", &sc
->sc_l2
, &ifpci_l3_driver
, NBCH_BRI
);
391 sc
->sc_l3token
= drv
;
392 sc
->sc_l2
.driver
= &isic_std_driver
;
393 sc
->sc_l2
.l1_token
= sc
;
395 isdn_layer2_status_ind(&sc
->sc_l2
, drv
, STI_ATTACH
, 1);
396 isdn_isdnif_ready(drv
->isdnif
);
400 ifpci_detach(device_t self
, int flags
)
402 struct ifpci_softc
*psc
= device_private(self
);
404 bus_space_unmap(psc
->sc_isic
.sc_maps
[0].t
, psc
->sc_isic
.sc_maps
[0].h
, psc
->sc_size
);
405 bus_space_free(psc
->sc_isic
.sc_maps
[0].t
, psc
->sc_isic
.sc_maps
[0].h
, psc
->sc_size
);
406 pci_intr_disestablish(psc
->sc_pc
, psc
->sc_ih
);
412 ifpci_activate(device_t self
, enum devact act
)
414 struct ifpci_softc
*psc
= device_private(self
);
417 case DVACT_DEACTIVATE
:
418 psc
->sc_isic
.sc_intr_valid
= ISIC_INTR_DYING
;
419 isdn_layer2_status_ind(&psc
->sc_isic
.sc_l2
, psc
->sc_isic
.sc_l3token
, STI_ATTACH
, 0);
420 isdn_detach_isdnif(psc
->sc_isic
.sc_l3token
);
421 psc
->sc_isic
.sc_l3token
= NULL
;
428 /*---------------------------------------------------------------------------*
429 * AVM read fifo routines
430 *---------------------------------------------------------------------------*/
433 avma1pp_read_fifo(struct isic_softc
*sc
, int what
, void *buf
, size_t size
)
437 bus_space_write_1(sc
->sc_maps
[0].t
, sc
->sc_maps
[0].h
, ADDR_REG_OFFSET
, ISAC_FIFO
);
438 bus_space_read_multi_1(sc
->sc_maps
[0].t
, sc
->sc_maps
[0].h
, ISAC_REG_OFFSET
, buf
, size
);
440 case ISIC_WHAT_HSCXA
:
441 hscx_read_fifo(0, buf
, size
, sc
);
443 case ISIC_WHAT_HSCXB
:
444 hscx_read_fifo(1, buf
, size
, sc
);
450 hscx_read_fifo(int chan
, void *buf
, size_t len
, struct isic_softc
*sc
)
455 bus_space_write_4(sc
->sc_maps
[0].t
, sc
->sc_maps
[0].h
, ADDR_REG_OFFSET
, chan
);
456 ip
= (u_int32_t
*)buf
;
458 /* what if len isn't a multiple of sizeof(int) and buf is */
462 *ip
++ = bus_space_read_4(sc
->sc_maps
[0].t
, sc
->sc_maps
[0].h
, ISAC_REG_OFFSET
);
467 /*---------------------------------------------------------------------------*
468 * AVM write fifo routines
469 *---------------------------------------------------------------------------*/
472 avma1pp_write_fifo(struct isic_softc
*sc
, int what
, const void *buf
, size_t size
)
476 bus_space_write_1(sc
->sc_maps
[0].t
, sc
->sc_maps
[0].h
, ADDR_REG_OFFSET
, ISAC_FIFO
);
477 bus_space_write_multi_1(sc
->sc_maps
[0].t
, sc
->sc_maps
[0].h
, ISAC_REG_OFFSET
, buf
, size
);
479 case ISIC_WHAT_HSCXA
:
480 hscx_write_fifo(0, buf
, size
, sc
);
482 case ISIC_WHAT_HSCXB
:
483 hscx_write_fifo(1, buf
, size
, sc
);
489 hscx_write_fifo(int chan
, const void *buf
, size_t len
, struct isic_softc
*sc
)
493 l1_bchan_state_t
*Bchan
= &sc
->sc_chan
[chan
];
495 sc
->avma1pp_cmd
&= ~HSCX_CMD_XME
;
497 if (Bchan
->out_mbuf_cur
== NULL
)
499 if (Bchan
->bprot
!= BPROT_NONE
)
500 sc
->avma1pp_cmd
|= HSCX_CMD_XME
;
502 if (len
!= sc
->sc_bfifolen
)
503 sc
->avma1pp_txl
= len
;
505 cnt
= 0; /* borrow cnt */
506 AVMA1PPSETCMDLONG(cnt
);
507 hscx_write_reg(chan
, HSCX_STAT
, cnt
, sc
);
509 ip
= (const u_int32_t
*)buf
;
513 bus_space_write_4(sc
->sc_maps
[0].t
, sc
->sc_maps
[0].h
, ISAC_REG_OFFSET
, *ip
);
519 /*---------------------------------------------------------------------------*
520 * AVM write register routines
521 *---------------------------------------------------------------------------*/
524 avma1pp_write_reg(struct isic_softc
*sc
, int what
, bus_size_t offs
, u_int8_t data
)
529 reg_bank
= (offs
> MAX_LO_REG_OFFSET
) ? ISAC_HI_REG_OFFSET
:ISAC_LO_REG_OFFSET
;
530 /* set the register bank */
531 bus_space_write_1(sc
->sc_maps
[0].t
, sc
->sc_maps
[0].h
, ADDR_REG_OFFSET
, reg_bank
);
532 bus_space_write_1(sc
->sc_maps
[0].t
, sc
->sc_maps
[0].h
, ISAC_REG_OFFSET
+ (offs
& ISAC_REGSET_MASK
), data
);
534 case ISIC_WHAT_HSCXA
:
535 hscx_write_reg(0, offs
, data
, sc
);
537 case ISIC_WHAT_HSCXB
:
538 hscx_write_reg(1, offs
, data
, sc
);
544 hscx_write_reg(int chan
, u_int off
, u_int val
, struct isic_softc
*sc
)
549 /* point at the correct channel */
550 bus_space_write_4(sc
->sc_maps
[0].t
, sc
->sc_maps
[0].h
, ADDR_REG_OFFSET
, chan
);
551 bus_space_write_4(sc
->sc_maps
[0].t
, sc
->sc_maps
[0].h
, ISAC_REG_OFFSET
+ off
, val
);
554 /*---------------------------------------------------------------------------*
555 * AVM read register routines
556 *---------------------------------------------------------------------------*/
559 avma1pp_read_reg(struct isic_softc
*sc
, int what
, bus_size_t offs
)
564 reg_bank
= (offs
> MAX_LO_REG_OFFSET
) ? ISAC_HI_REG_OFFSET
:ISAC_LO_REG_OFFSET
;
565 /* set the register bank */
566 bus_space_write_1(sc
->sc_maps
[0].t
, sc
->sc_maps
[0].h
, ADDR_REG_OFFSET
, reg_bank
);
567 return(bus_space_read_1(sc
->sc_maps
[0].t
, sc
->sc_maps
[0].h
, ISAC_REG_OFFSET
+
568 (offs
& ISAC_REGSET_MASK
)));
569 case ISIC_WHAT_HSCXA
:
570 return hscx_read_reg(0, offs
, sc
);
571 case ISIC_WHAT_HSCXB
:
572 return hscx_read_reg(1, offs
, sc
);
578 hscx_read_reg(int chan
, u_int off
, struct isic_softc
*sc
)
580 return(hscx_read_reg_int(chan
, off
, sc
) & 0xff);
584 * need to be able to return an int because the RBCH is in the 2nd
588 hscx_read_reg_int(int chan
, u_int off
, struct isic_softc
*sc
)
593 /* point at the correct channel */
594 bus_space_write_4(sc
->sc_maps
[0].t
, sc
->sc_maps
[0].h
, ADDR_REG_OFFSET
, chan
);
595 return(bus_space_read_4(sc
->sc_maps
[0].t
, sc
->sc_maps
[0].h
, ISAC_REG_OFFSET
+ off
));
599 * this is the real interrupt routine
602 avma1pp_hscx_intr(int h_chan
, u_int stat
, struct isic_softc
*sc
)
604 register l1_bchan_state_t
*chan
= &sc
->sc_chan
[h_chan
];
608 NDBGL1(L1_H_IRQ
, "%#x", stat
);
610 if((stat
& HSCX_INT_XDU
) && (chan
->bprot
!= BPROT_NONE
))/* xmit data underrun */
613 NDBGL1(L1_H_XFRERR
, "xmit data underrun");
614 /* abort the transmission */
616 sc
->avma1pp_cmd
|= HSCX_CMD_XRS
;
617 AVMA1PPSETCMDLONG(param
);
618 hscx_write_reg(h_chan
, HSCX_STAT
, param
, sc
);
619 sc
->avma1pp_cmd
&= ~HSCX_CMD_XRS
;
620 AVMA1PPSETCMDLONG(param
);
621 hscx_write_reg(h_chan
, HSCX_STAT
, param
, sc
);
623 if (chan
->out_mbuf_head
!= NULL
) /* don't continue to transmit this buffer */
625 i4b_Bfreembuf(chan
->out_mbuf_head
);
626 chan
->out_mbuf_cur
= chan
->out_mbuf_head
= NULL
;
631 * The following is based on examination of the Linux driver.
633 * The logic here is different than with a "real" HSCX; all kinds
634 * of information (interrupt/status bits) are in stat.
635 * HSCX_INT_RPR indicates a receive interrupt
636 * HSCX_STAT_RDO indicates an overrun condition, abort -
637 * otherwise read the bytes ((stat & HSCX_STZT_RML_MASK) >> 8)
638 * HSCX_STAT_RME indicates end-of-frame and apparently any
639 * CRC/framing errors are only reported in this state.
640 * if ((stat & HSCX_STAT_CRCVFRRAB) != HSCX_STAT_CRCVFR)
644 if(stat
& HSCX_INT_RPR
)
646 register int fifo_data_len
;
648 /* always have to read the FIFO, so use a scratch buffer */
649 u_char scrbuf
[HSCX_FIFO_LEN
];
651 if(stat
& HSCX_STAT_RDO
)
654 NDBGL1(L1_H_XFRERR
, "receive data overflow");
659 * check whether we're receiving data for an inactive B-channel
660 * and discard it. This appears to happen for telephony when
661 * both B-channels are active and one is deactivated. Since
662 * it is not really possible to deactivate the channel in that
663 * case (the ASIC seems to deactivate _both_ channels), the
664 * "deactivated" channel keeps receiving data which can lead
665 * to exhaustion of mbufs and a kernel panic.
667 * This is a hack, but it's the only solution I can think of
668 * without having the documentation for the ASIC.
671 if (chan
->state
== HSCX_IDLE
)
673 NDBGL1(L1_H_XFRERR
, "toss data from %d", h_chan
);
677 fifo_data_len
= ((stat
& HSCX_STAT_RML_MASK
) >> 8);
679 if(fifo_data_len
== 0)
680 fifo_data_len
= sc
->sc_bfifolen
;
682 /* ALWAYS read data from HSCX fifo */
684 HSCX_RDFIFO(h_chan
, scrbuf
, fifo_data_len
);
685 chan
->rxcount
+= fifo_data_len
;
687 /* all error conditions checked, now decide and take action */
691 if(chan
->in_mbuf
== NULL
)
693 if((chan
->in_mbuf
= i4b_Bgetmbuf(BCH_MAX_DATALEN
)) == NULL
)
694 panic("L1 avma1pp_hscx_intr: RME, cannot allocate mbuf!");
695 chan
->in_cbptr
= chan
->in_mbuf
->m_data
;
699 if((chan
->in_len
+ fifo_data_len
) <= BCH_MAX_DATALEN
)
701 /* OK to copy the data */
702 memcpy(chan
->in_cbptr
, scrbuf
, fifo_data_len
);
703 chan
->in_cbptr
+= fifo_data_len
;
704 chan
->in_len
+= fifo_data_len
;
706 /* setup mbuf data length */
708 chan
->in_mbuf
->m_len
= chan
->in_len
;
709 chan
->in_mbuf
->m_pkthdr
.len
= chan
->in_len
;
711 if(sc
->sc_trace
& TRACE_B_RX
)
713 struct i4b_trace_hdr hdr
;
714 hdr
.type
= (h_chan
== HSCX_CH_A
? TRC_CH_B1
: TRC_CH_B2
);
716 hdr
.count
= ++sc
->sc_trace_bcount
;
717 isdn_layer2_trace_ind(&sc
->sc_l2
, sc
->sc_l3token
, &hdr
, chan
->in_mbuf
->m_len
, chan
->in_mbuf
->m_data
);
720 if (stat
& HSCX_STAT_RME
)
722 if((stat
& HSCX_STAT_CRCVFRRAB
) == HSCX_STAT_CRCVFR
)
724 (*chan
->l4_driver
->bch_rx_data_ready
)(chan
->l4_driver_softc
);
727 /* mark buffer ptr as unused */
729 chan
->in_mbuf
= NULL
;
730 chan
->in_cbptr
= NULL
;
736 NDBGL1(L1_H_XFRERR
, "CRC/RAB");
737 if (chan
->in_mbuf
!= NULL
)
739 i4b_Bfreembuf(chan
->in_mbuf
);
740 chan
->in_mbuf
= NULL
;
741 chan
->in_cbptr
= NULL
;
746 } /* END enough space in mbuf */
749 if(chan
->bprot
== BPROT_NONE
)
751 /* setup mbuf data length */
753 chan
->in_mbuf
->m_len
= chan
->in_len
;
754 chan
->in_mbuf
->m_pkthdr
.len
= chan
->in_len
;
756 if(sc
->sc_trace
& TRACE_B_RX
)
758 struct i4b_trace_hdr hdr
;
759 hdr
.type
= (h_chan
== HSCX_CH_A
? TRC_CH_B1
: TRC_CH_B2
);
761 hdr
.count
= ++sc
->sc_trace_bcount
;
762 isdn_layer2_trace_ind(&sc
->sc_l2
, sc
->sc_l3token
, &hdr
, chan
->in_mbuf
->m_len
, chan
->in_mbuf
->m_data
);
765 if(!(isdn_bchan_silence(chan
->in_mbuf
->m_data
, chan
->in_mbuf
->m_len
)))
768 /* move rx'd data to rx queue */
770 if (!(IF_QFULL(&chan
->rx_queue
)))
772 IF_ENQUEUE(&chan
->rx_queue
, chan
->in_mbuf
);
776 i4b_Bfreembuf(chan
->in_mbuf
);
779 /* signal upper layer that data are available */
780 (*chan
->l4_driver
->bch_rx_data_ready
)(chan
->l4_driver_softc
);
782 /* alloc new buffer */
784 if((chan
->in_mbuf
= i4b_Bgetmbuf(BCH_MAX_DATALEN
)) == NULL
)
785 panic("L1 avma1pp_hscx_intr: RPF, cannot allocate new mbuf!");
787 /* setup new data ptr */
789 chan
->in_cbptr
= chan
->in_mbuf
->m_data
;
791 /* OK to copy the data */
792 memcpy(chan
->in_cbptr
, scrbuf
, fifo_data_len
);
794 chan
->in_cbptr
+= fifo_data_len
;
795 chan
->in_len
= fifo_data_len
;
797 chan
->rxcount
+= fifo_data_len
;
801 NDBGL1(L1_H_XFRERR
, "RAWHDLC rx buffer overflow in RPF, in_len=%d", chan
->in_len
);
802 chan
->in_cbptr
= chan
->in_mbuf
->m_data
;
806 } /* if(error == 0) */
809 /* land here for RDO */
810 if (chan
->in_mbuf
!= NULL
)
812 i4b_Bfreembuf(chan
->in_mbuf
);
813 chan
->in_mbuf
= NULL
;
814 chan
->in_cbptr
= NULL
;
818 sc
->avma1pp_cmd
|= HSCX_CMD_RRS
;
819 AVMA1PPSETCMDLONG(param
);
820 hscx_write_reg(h_chan
, HSCX_STAT
, param
, sc
);
821 sc
->avma1pp_cmd
&= ~HSCX_CMD_RRS
;
822 AVMA1PPSETCMDLONG(param
);
823 hscx_write_reg(h_chan
, HSCX_STAT
, param
, sc
);
828 /* transmit fifo empty, new data can be written to fifo */
830 if(stat
& HSCX_INT_XPR
)
833 * for a description what is going on here, please have
834 * a look at isic_bchannel_start() in i4b_bchan.c !
837 NDBGL1(L1_H_IRQ
, "%s: chan %d - XPR, Tx Fifo Empty!", device_xname(&sc
->sc_dev
), h_chan
);
839 if(chan
->out_mbuf_cur
== NULL
) /* last frame is transmitted */
841 IF_DEQUEUE(&chan
->tx_queue
, chan
->out_mbuf_head
);
843 if(chan
->out_mbuf_head
== NULL
)
845 chan
->state
&= ~HSCX_TX_ACTIVE
;
846 (*chan
->l4_driver
->bch_tx_queue_empty
)(chan
->l4_driver_softc
);
850 chan
->state
|= HSCX_TX_ACTIVE
;
851 chan
->out_mbuf_cur
= chan
->out_mbuf_head
;
852 chan
->out_mbuf_cur_ptr
= chan
->out_mbuf_cur
->m_data
;
853 chan
->out_mbuf_cur_len
= chan
->out_mbuf_cur
->m_len
;
855 if(sc
->sc_trace
& TRACE_B_TX
)
857 struct i4b_trace_hdr hdr
;
858 hdr
.type
= (h_chan
== HSCX_CH_A
? TRC_CH_B1
: TRC_CH_B2
);
860 hdr
.count
= ++sc
->sc_trace_bcount
;
861 isdn_layer2_trace_ind(&sc
->sc_l2
, sc
->sc_l3token
, &hdr
, chan
->out_mbuf_cur
->m_len
, chan
->out_mbuf_cur
->m_data
);
864 if(chan
->bprot
== BPROT_NONE
)
866 if(!(isdn_bchan_silence(chan
->out_mbuf_cur
->m_data
, chan
->out_mbuf_cur
->m_len
)))
876 isic_hscx_fifo(chan
, sc
);
879 /* call timeout handling routine */
881 if(activity
== ACT_RX
|| activity
== ACT_TX
)
882 (*chan
->l4_driver
->bch_activity
)(chan
->l4_driver_softc
, activity
);
886 * this is the main routine which checks each channel and then calls
887 * the real interrupt routine as appropriate
890 avma1pp_hscx_int_handler(struct isic_softc
*sc
)
894 /* has to be a u_int because the byte count is in the 2nd byte */
895 stat
= hscx_read_reg_int(0, HSCX_STAT
, sc
);
896 if (stat
& HSCX_INT_MASK
)
897 avma1pp_hscx_intr(0, stat
, sc
);
898 stat
= hscx_read_reg_int(1, HSCX_STAT
, sc
);
899 if (stat
& HSCX_INT_MASK
)
900 avma1pp_hscx_intr(1, stat
, sc
);
904 avma1pp_disable(struct isic_softc
*sc
)
906 bus_space_write_1(sc
->sc_maps
[0].t
, sc
->sc_maps
[0].h
, STAT0_OFFSET
, ASL_RESET_ALL
|ASL_TIMERDISABLE
);
910 avma1pp_intr(void *parm
)
912 struct isic_softc
*sc
= parm
;
917 if (sc
->sc_intr_valid
!= ISIC_INTR_VALID
)
920 stat
= bus_space_read_1(sc
->sc_maps
[0].t
, sc
->sc_maps
[0].h
, STAT0_OFFSET
);
921 NDBGL1(L1_H_IRQ
, "stat %x", stat
);
922 /* was there an interrupt from this card ? */
923 if ((stat
& ASL_IRQ_Pending
) == ASL_IRQ_Pending
)
925 /* interrupts are low active */
926 if (!(stat
& ASL_IRQ_TIMER
))
927 NDBGL1(L1_H_IRQ
, "timer interrupt ???");
928 if (!(stat
& ASL_IRQ_HSCX
))
930 NDBGL1(L1_H_IRQ
, "HSCX");
931 avma1pp_hscx_int_handler(sc
);
934 if (!(stat
& ASL_IRQ_ISAC
))
936 NDBGL1(L1_H_IRQ
, "ISAC");
938 /* get isac irq status */
939 u_int8_t isac_irq_stat
= ISAC_READ(I_ISTA
);
942 isic_isac_irq(sc
, isac_irq_stat
);
950 avma1pp_map_int(struct ifpci_softc
*psc
, struct pci_attach_args
*pa
)
952 struct isic_softc
*sc
= &psc
->sc_isic
;
953 pci_chipset_tag_t pc
= pa
->pa_pc
;
954 pci_intr_handle_t ih
;
957 /* Map and establish the interrupt. */
958 if (pci_intr_map(pa
, &ih
)) {
959 aprint_error_dev(&sc
->sc_dev
, "couldn't map interrupt\n");
964 intrstr
= pci_intr_string(pc
, ih
);
965 psc
->sc_ih
= pci_intr_establish(pc
, ih
, IPL_NET
, avma1pp_intr
, sc
);
966 if (psc
->sc_ih
== NULL
) {
967 aprint_error_dev(&sc
->sc_dev
, "couldn't establish interrupt");
969 aprint_error(" at %s", intrstr
);
974 aprint_normal_dev(&sc
->sc_dev
, "interrupting at %s\n", intrstr
);
978 avma1pp_hscx_init(struct isic_softc
*sc
, int h_chan
, int activate
)
980 l1_bchan_state_t
*chan
= &sc
->sc_chan
[h_chan
];
983 NDBGL1(L1_BCHAN
, "%s: channel=%d, %s",
984 device_xname(&sc
->sc_dev
), h_chan
, activate
? "activate" : "deactivate");
988 /* only deactivate if both channels are idle */
989 if (sc
->sc_chan
[HSCX_CH_A
].state
!= HSCX_IDLE
||
990 sc
->sc_chan
[HSCX_CH_B
].state
!= HSCX_IDLE
)
994 sc
->avma1pp_cmd
= HSCX_CMD_XRS
|HSCX_CMD_RRS
;
995 sc
->avma1pp_prot
= HSCX_MODE_TRANS
;
996 AVMA1PPSETCMDLONG(param
);
997 hscx_write_reg(h_chan
, HSCX_STAT
, param
, sc
);
1000 if(chan
->bprot
== BPROT_RHDLC
)
1002 NDBGL1(L1_BCHAN
, "BPROT_RHDLC");
1004 /* HDLC Frames, transparent mode 0 */
1005 sc
->avma1pp_cmd
= HSCX_CMD_XRS
|HSCX_CMD_RRS
;
1006 sc
->avma1pp_prot
= HSCX_MODE_ITF_FLG
;
1007 AVMA1PPSETCMDLONG(param
);
1008 hscx_write_reg(h_chan
, HSCX_STAT
, param
, sc
);
1009 sc
->avma1pp_cmd
= HSCX_CMD_XRS
;
1010 AVMA1PPSETCMDLONG(param
);
1011 hscx_write_reg(h_chan
, HSCX_STAT
, param
, sc
);
1012 sc
->avma1pp_cmd
= 0;
1016 NDBGL1(L1_BCHAN
, "BPROT_NONE??");
1018 /* Raw Telephony, extended transparent mode 1 */
1019 sc
->avma1pp_cmd
= HSCX_CMD_XRS
|HSCX_CMD_RRS
;
1020 sc
->avma1pp_prot
= HSCX_MODE_TRANS
;
1021 AVMA1PPSETCMDLONG(param
);
1022 hscx_write_reg(h_chan
, HSCX_STAT
, param
, sc
);
1023 sc
->avma1pp_cmd
= HSCX_CMD_XRS
;
1024 AVMA1PPSETCMDLONG(param
);
1025 hscx_write_reg(h_chan
, HSCX_STAT
, param
, sc
);
1026 sc
->avma1pp_cmd
= 0;
1031 avma1pp_bchannel_setup(isdn_layer1token t
, int h_chan
, int bprot
, int activate
)
1033 struct isic_softc
*sc
= (struct isic_softc
*)t
;
1034 l1_bchan_state_t
*chan
= &sc
->sc_chan
[h_chan
];
1041 chan
->state
= HSCX_IDLE
;
1042 avma1pp_hscx_init(sc
, h_chan
, activate
);
1045 NDBGL1(L1_BCHAN
, "%s: channel=%d, %s",
1046 device_xname(&sc
->sc_dev
), h_chan
, activate
? "activate" : "deactivate");
1050 chan
->channel
= h_chan
; /* B channel */
1051 chan
->bprot
= bprot
; /* B channel protocol */
1052 chan
->state
= HSCX_IDLE
; /* B channel state */
1056 i4b_Bcleanifq(&chan
->rx_queue
); /* clean rx queue */
1058 chan
->rx_queue
.ifq_maxlen
= IFQ_MAXLEN
;
1060 chan
->rxcount
= 0; /* reset rx counter */
1062 i4b_Bfreembuf(chan
->in_mbuf
); /* clean rx mbuf */
1064 chan
->in_mbuf
= NULL
; /* reset mbuf ptr */
1065 chan
->in_cbptr
= NULL
; /* reset mbuf curr ptr */
1066 chan
->in_len
= 0; /* reset mbuf data len */
1068 /* transmitter part */
1070 i4b_Bcleanifq(&chan
->tx_queue
); /* clean tx queue */
1072 chan
->tx_queue
.ifq_maxlen
= IFQ_MAXLEN
;
1074 chan
->txcount
= 0; /* reset tx counter */
1076 i4b_Bfreembuf(chan
->out_mbuf_head
); /* clean tx mbuf */
1078 chan
->out_mbuf_head
= NULL
; /* reset head mbuf ptr */
1079 chan
->out_mbuf_cur
= NULL
; /* reset current mbuf ptr */
1080 chan
->out_mbuf_cur_ptr
= NULL
; /* reset current mbuf data ptr */
1081 chan
->out_mbuf_cur_len
= 0; /* reset current mbuf data cnt */
1086 avma1pp_hscx_init(sc
, h_chan
, activate
);
1087 chan
->state
|= HSCX_AVMA1PP_ACTIVE
;
1094 avma1pp_bchannel_start(isdn_layer1token t
, int h_chan
)
1096 struct isic_softc
*sc
= (struct isic_softc
*)t
;
1097 register l1_bchan_state_t
*chan
= &sc
->sc_chan
[h_chan
];
1101 s
= splnet(); /* enter critical section */
1102 if(chan
->state
& HSCX_TX_ACTIVE
) /* already running ? */
1105 return; /* yes, leave */
1108 /* get next mbuf from queue */
1110 IF_DEQUEUE(&chan
->tx_queue
, chan
->out_mbuf_head
);
1112 if(chan
->out_mbuf_head
== NULL
) /* queue empty ? */
1114 splx(s
); /* leave critical section */
1115 return; /* yes, exit */
1118 /* init current mbuf values */
1120 chan
->out_mbuf_cur
= chan
->out_mbuf_head
;
1121 chan
->out_mbuf_cur_len
= chan
->out_mbuf_cur
->m_len
;
1122 chan
->out_mbuf_cur_ptr
= chan
->out_mbuf_cur
->m_data
;
1124 /* activity indicator for timeout handling */
1126 if(chan
->bprot
== BPROT_NONE
)
1128 if(!(isdn_bchan_silence(chan
->out_mbuf_cur
->m_data
, chan
->out_mbuf_cur
->m_len
)))
1136 chan
->state
|= HSCX_TX_ACTIVE
; /* we start transmitting */
1138 if(sc
->sc_trace
& TRACE_B_TX
) /* if trace, send mbuf to trace dev */
1140 struct i4b_trace_hdr hdr
;
1141 hdr
.type
= (h_chan
== HSCX_CH_A
? TRC_CH_B1
: TRC_CH_B2
);
1143 hdr
.count
= ++sc
->sc_trace_bcount
;
1144 isdn_layer2_trace_ind(&sc
->sc_l2
, sc
->sc_l3token
, &hdr
, chan
->out_mbuf_cur
->m_len
, chan
->out_mbuf_cur
->m_data
);
1147 isic_hscx_fifo(chan
, sc
);
1149 /* call timeout handling routine */
1151 if(activity
== ACT_RX
|| activity
== ACT_TX
)
1152 (*chan
->l4_driver
->bch_activity
)(chan
->l4_driver_softc
, activity
);
1157 /*---------------------------------------------------------------------------*
1158 * return the address of isic drivers linktab
1159 *---------------------------------------------------------------------------*/
1160 static isdn_link_t
*
1161 avma1pp_ret_linktab(void *token
, int channel
)
1163 struct l2_softc
*l2sc
= token
;
1164 struct isic_softc
*sc
= l2sc
->l1_token
;
1166 l1_bchan_state_t
*chan
= &sc
->sc_chan
[channel
];
1168 return(&chan
->isdn_linktab
);
1171 /*---------------------------------------------------------------------------*
1172 * set the driver linktab in the b channel softc
1173 *---------------------------------------------------------------------------*/
1175 avma1pp_set_link(void *token
, int channel
, const struct isdn_l4_driver_functions
*l4_driver
, void *l4_driver_softc
)
1177 struct l2_softc
*l2sc
= token
;
1178 struct isic_softc
*sc
= l2sc
->l1_token
;
1179 l1_bchan_state_t
*chan
= &sc
->sc_chan
[channel
];
1181 chan
->l4_driver
= l4_driver
;
1182 chan
->l4_driver_softc
= l4_driver_softc
;
1185 static const struct isdn_l4_bchannel_functions
1186 avma1pp_l4_bchannel_functions
= {
1187 avma1pp_bchannel_setup
,
1188 avma1pp_bchannel_start
,
1189 avma1pp_bchannel_stat
1192 /*---------------------------------------------------------------------------*
1193 * initialize our local linktab
1194 *---------------------------------------------------------------------------*/
1196 avma1pp_init_linktab(struct isic_softc
*sc
)
1198 l1_bchan_state_t
*chan
= &sc
->sc_chan
[HSCX_CH_A
];
1199 isdn_link_t
*lt
= &chan
->isdn_linktab
;
1203 lt
->channel
= HSCX_CH_A
;
1204 lt
->bchannel_driver
= &avma1pp_l4_bchannel_functions
;
1205 lt
->tx_queue
= &chan
->tx_queue
;
1207 /* used by non-HDLC data transfers, i.e. telephony drivers */
1208 lt
->rx_queue
= &chan
->rx_queue
;
1210 /* used by HDLC data transfers, i.e. ipr and isp drivers */
1211 lt
->rx_mbuf
= &chan
->in_mbuf
;
1213 chan
= &sc
->sc_chan
[HSCX_CH_B
];
1214 lt
= &chan
->isdn_linktab
;
1217 lt
->channel
= HSCX_CH_B
;
1218 lt
->bchannel_driver
= &avma1pp_l4_bchannel_functions
;
1219 lt
->tx_queue
= &chan
->tx_queue
;
1221 /* used by non-HDLC data transfers, i.e. telephony drivers */
1222 lt
->rx_queue
= &chan
->rx_queue
;
1224 /* used by HDLC data transfers, i.e. ipr and isp drivers */
1225 lt
->rx_mbuf
= &chan
->in_mbuf
;
1229 * use this instead of isic_bchannel_stat in i4b_bchan.c because it's static
1232 avma1pp_bchannel_stat(isdn_layer1token t
, int h_chan
, bchan_statistics_t
*bsp
)
1234 struct isic_softc
*sc
= (struct isic_softc
*)t
;
1235 l1_bchan_state_t
*chan
= &sc
->sc_chan
[h_chan
];
1240 bsp
->outbytes
= chan
->txcount
;
1241 bsp
->inbytes
= chan
->rxcount
;
1249 /*---------------------------------------------------------------------------*
1250 * fill HSCX fifo with data from the current mbuf
1251 * Put this here until it can go into i4b_hscx.c
1252 *---------------------------------------------------------------------------*/
1254 isic_hscx_fifo(l1_bchan_state_t
*chan
, struct isic_softc
*sc
)
1260 /* using a scratch buffer simplifies writing to the FIFO */
1261 u_char scrbuf
[HSCX_FIFO_LEN
];
1267 * fill the HSCX tx fifo with data from the current mbuf. if
1268 * current mbuf holds less data than HSCX fifo length, try to
1269 * get the next mbuf from (a possible) mbuf chain. if there is
1270 * not enough data in a single mbuf or in a chain, then this
1271 * is the last mbuf and we tell the HSCX that it has to send
1272 * CRC and closing flag
1275 while(chan
->out_mbuf_cur
&& len
!= sc
->sc_bfifolen
)
1277 nextlen
= min(chan
->out_mbuf_cur_len
, sc
->sc_bfifolen
- len
);
1280 printf("i:mh=%p, mc=%p, mcp=%p, mcl=%d l=%d nl=%d # ",
1281 chan
->out_mbuf_head
,
1283 chan
->out_mbuf_cur_ptr
,
1284 chan
->out_mbuf_cur_len
,
1289 cmd
|= HSCX_CMDR_XTF
;
1290 /* collect the data in the scratch buffer */
1291 for (i
= 0; i
< nextlen
; i
++)
1292 scrbuf
[i
+ len
] = chan
->out_mbuf_cur_ptr
[i
];
1295 chan
->txcount
+= nextlen
;
1297 chan
->out_mbuf_cur_ptr
+= nextlen
;
1298 chan
->out_mbuf_cur_len
-= nextlen
;
1300 if(chan
->out_mbuf_cur_len
== 0)
1302 if((chan
->out_mbuf_cur
= chan
->out_mbuf_cur
->m_next
) != NULL
)
1304 chan
->out_mbuf_cur_ptr
= chan
->out_mbuf_cur
->m_data
;
1305 chan
->out_mbuf_cur_len
= chan
->out_mbuf_cur
->m_len
;
1307 if(sc
->sc_trace
& TRACE_B_TX
)
1309 struct i4b_trace_hdr hdr
;
1310 hdr
.type
= (chan
->channel
== HSCX_CH_A
? TRC_CH_B1
: TRC_CH_B2
);
1312 hdr
.count
= ++sc
->sc_trace_bcount
;
1313 isdn_layer2_trace_ind(&sc
->sc_l2
, sc
->sc_l3token
, &hdr
, chan
->out_mbuf_cur
->m_len
, chan
->out_mbuf_cur
->m_data
);
1318 if (chan
->bprot
!= BPROT_NONE
)
1319 cmd
|= HSCX_CMDR_XME
;
1320 i4b_Bfreembuf(chan
->out_mbuf_head
);
1321 chan
->out_mbuf_head
= NULL
;
1325 /* write what we have from the scratch buf to the HSCX fifo */
1327 HSCX_WRFIFO(chan
->channel
, scrbuf
, len
);