Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / dev / pci / ifpci2.c
blobc8429f7162fc1350d2557e5ff219d85c720deb14
1 /* $NetBSD: ifpci2.c,v 1.18 2009/11/26 15:17:10 njoly Exp $ */
2 /*
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
7 * are met:
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
30 * SUCH DAMAGE.
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: ifpci2.c,v 1.19 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: ifpci2.c,v 1.18 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>
53 #include <sys/mbuf.h>
55 #include <sys/bus.h>
56 #include <sys/device.h>
58 #include <sys/socket.h>
59 #include <net/if.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/isacsx.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 *avma1pp2_ret_linktab(void *token, int channel);
86 static void avma1pp2_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
97 ifpci2_l3_driver = {
98 avma1pp2_ret_linktab,
99 avma1pp2_set_link,
100 n_connect_request,
101 n_connect_response,
102 n_disconnect_request,
103 n_alert_request,
104 NULL,
105 NULL,
106 n_mgmt_command
109 struct ifpci_softc {
110 struct isic_softc sc_isic; /* parent class */
112 /* PCI-specific goo */
113 void *sc_ih; /* interrupt handler */
114 bus_addr_t sc_base;
115 bus_size_t sc_size;
116 pci_chipset_tag_t sc_pc;
119 /* prototypes */
120 static void avma1pp2_disable(struct isic_softc *);
121 static int isic_hscx_fifo(l1_bchan_state_t *chan, struct isic_softc *sc);
123 static int avma1pp2_intr(void*);
124 static void avma1pp2_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size);
125 static void avma1pp2_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size);
126 static void avma1pp2_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data);
127 static u_int8_t avma1pp2_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 val, struct isic_softc *sc);
131 static u_char hscx_read_reg(int chan, struct isic_softc *sc);
132 static u_int hscx_read_reg_int(int chan, struct isic_softc *sc);
133 static void avma1pp2_bchannel_stat(isdn_layer1token, int h_chan, bchan_statistics_t *bsp);
134 static void avma1pp2_map_int(struct ifpci_softc *sc, struct pci_attach_args *pa);
135 static void avma1pp2_bchannel_setup(isdn_layer1token, int h_chan, int bprot, int activate);
136 static void avma1pp2_init_linktab(struct isic_softc *);
137 static int ifpci2_match(device_t parent, cfdata_t match, void *aux);
138 static void ifpci2_attach(device_t parent, device_t self, void *aux);
139 static int ifpci2_detach(device_t self, int flags);
140 static int ifpci2_activate(device_t self, enum devact act);
142 CFATTACH_DECL(ifritz, sizeof(struct ifpci_softc),
143 ifpci2_match, ifpci2_attach, ifpci2_detach, ifpci2_activate);
145 /*---------------------------------------------------------------------------*
146 * AVM PCI Fritz!Card V. 2 special registers
147 *---------------------------------------------------------------------------*/
150 * AVM PCI Status Latch 0 read only bits
152 #define ASL_IRQ_ISAC 0x01 /* ISAC interrupt, active high */
153 #define ASL_IRQ_HSCX 0x02 /* HSX interrupt, active high */
154 #define ASL_IRQ_TIMER 0x04 /* Timer interrupt, active high */
155 #define ASL_IRQ_BCHAN ASL_IRQ_HSCX
156 /* actually active high */
157 #define ASL_IRQ_Pending (ASL_IRQ_ISAC | ASL_IRQ_HSCX | ASL_IRQ_TIMER)
160 * AVM PCI Status Latch 0 read only bits
162 #define ASL_RESET 0x01
163 #define ASL_TIMERRESET 0x04
164 #define ASL_ENABLE_INT 0x08
167 * "HSCX" status bits
169 #define HSCX_STAT_RME 0x01
170 #define HSCX_STAT_RDO 0x10
171 #define HSCX_STAT_CRCVFRRAB 0x0E
172 #define HSCX_STAT_CRCVFR 0x06
173 #define HSCX_STAT_RML_MASK 0x3f00
176 * "HSCX" interrupt bits
178 #define HSCX_INT_XPR 0x80
179 #define HSCX_INT_XDU 0x40
180 #define HSCX_INT_RPR 0x20
181 #define HSCX_INT_MASK 0xE0
184 * "HSCX" command bits
186 #define HSCX_CMD_XRS 0x80
187 #define HSCX_CMD_XME 0x01
188 #define HSCX_CMD_RRS 0x20
189 #define HSCX_CMD_XML_MASK 0x3f00
191 /* "HSCX" mode bits */
192 #define HSCX_MODE_ITF_FLG 0x01
193 #define HSCX_MODE_TRANS 0x02
195 /* offsets to various registers in the ASIC, evidently */
196 #define STAT0_OFFSET 0x02
198 #define HSCX_FIFO1 0x10
199 #define HSCX_FIFO2 0x18
201 #define HSCX_STAT1 0x14
202 #define HSCX_STAT2 0x1c
204 #define ISACSX_INDEX 0x04
205 #define ISACSX_DATA 0x08
208 * Commands and parameters are sent to the "HSCX" as a long, but the
209 * fields are handled as bytes.
211 * The long contains:
212 * (prot << 16)|(txl << 8)|cmd
214 * where:
215 * prot = protocol to use
216 * txl = transmit length
217 * cmd = the command to be executed
219 * The fields are defined as u_char in struct l1_softc.
221 * Macro to coalesce the byte fields into a u_int
223 #define AVMA1PPSETCMDLONG(f) (f) = ((sc->avma1pp_cmd) | (sc->avma1pp_txl << 8) \
224 | (sc->avma1pp_prot << 16))
227 * to prevent deactivating the "HSCX" when both channels are active we
228 * define an HSCX_ACTIVE flag which is or'd into the channel's state
229 * flag in avma1pp2_bchannel_setup upon active and cleared upon deactivation.
230 * It is set high to allow room for new flags.
232 #define HSCX_AVMA1PP_ACTIVE 0x1000
234 static int
235 ifpci2_match(device_t parent, cfdata_t match, void *aux)
237 struct pci_attach_args *pa = aux;
239 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_AVM &&
240 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AVM_FRITZ_PCI_V2_ISDN)
241 return 1;
242 return 0;
245 static void
246 ifpci2_attach(device_t parent, device_t self, void *aux)
248 struct ifpci_softc *psc = device_private(self);
249 struct pci_attach_args *pa = aux;
250 struct isic_softc *sc = &psc->sc_isic;
251 struct isdn_l3_driver *drv;
252 u_int v;
254 /* announce */
255 printf(": Fritz!PCI V2 card\n");
257 /* initialize sc */
258 callout_init(&sc->sc_T3_callout, 0);
259 callout_init(&sc->sc_T4_callout, 0);
261 /* setup io mappings */
262 sc->sc_num_mappings = 1;
263 MALLOC_MAPS(sc);
264 sc->sc_maps[0].size = 0;
265 if (pci_mapreg_map(pa, FRITZPCI_PORT0_IO_MAPOFF, PCI_MAPREG_TYPE_IO, 0,
266 &sc->sc_maps[0].t, &sc->sc_maps[0].h, &psc->sc_base, &psc->sc_size) != 0) {
267 aprint_error_dev(&sc->sc_dev, "can't map card\n");
268 return;
271 /* setup access routines */
273 sc->clearirq = NULL;
274 sc->readreg = avma1pp2_read_reg;
275 sc->writereg = avma1pp2_write_reg;
277 sc->readfifo = avma1pp2_read_fifo;
278 sc->writefifo = avma1pp2_write_fifo;
281 /* setup card type */
283 sc->sc_cardtyp = CARD_TYPEP_AVMA1PCIV2;
285 /* setup IOM bus type */
287 sc->sc_bustyp = BUS_TYPE_IOM2;
289 /* this is no IPAC based card */
290 sc->sc_ipac = 0;
291 sc->sc_bfifolen = HSCX_FIFO_LEN;
293 /* setup interrupt mapping */
294 avma1pp2_map_int(psc, pa);
296 /* init the card */
298 v = bus_space_read_4(sc->sc_maps[0].t, sc->sc_maps[0].h, 0);
299 bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET, 0);
300 DELAY(SEC_DELAY/20); /* 50 ms */
301 bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET, ASL_RESET);
302 DELAY(SEC_DELAY/20); /* 50 ms */
303 bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET, 0);
304 DELAY(SEC_DELAY/20); /* 50 ms */
306 bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET, ASL_TIMERRESET);
307 DELAY(SEC_DELAY/100); /* 10 ms */
308 bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET, ASL_ENABLE_INT);
309 DELAY(SEC_DELAY/100); /* 10 ms */
311 /* setup i4b infrastructure (have to roll our own here) */
313 /* sc->sc_isac_version = ((ISAC_READ(I_RBCH)) >> 5) & 0x03; */
314 printf("%s: ISACSX %s\n", device_xname(&sc->sc_dev), "PSB3186");
316 /* init the ISAC */
317 isic_isacsx_init(sc);
319 v = ISAC_READ(I_CIR0); /* Leo: reset generates status change */
321 /* init the "HSCX" */
322 avma1pp2_bchannel_setup(sc, HSCX_CH_A, BPROT_NONE, 0);
324 avma1pp2_bchannel_setup(sc, HSCX_CH_B, BPROT_NONE, 0);
326 /* can't use the normal B-Channel stuff */
327 avma1pp2_init_linktab(sc);
329 /* set trace level */
331 sc->sc_trace = TRACE_OFF;
333 sc->sc_state = ISAC_IDLE;
335 sc->sc_ibuf = NULL;
336 sc->sc_ib = NULL;
337 sc->sc_ilen = 0;
339 sc->sc_obuf = NULL;
340 sc->sc_op = NULL;
341 sc->sc_ol = 0;
342 sc->sc_freeflag = 0;
344 sc->sc_obuf2 = NULL;
345 sc->sc_freeflag2 = 0;
347 /* init higher protocol layers */
348 drv = isdn_attach_isdnif(device_xname(&sc->sc_dev),
349 "AVM Fritz!PCI V2", &sc->sc_l2, &ifpci2_l3_driver, NBCH_BRI);
350 sc->sc_l3token = drv;
351 sc->sc_l2.driver = &isic_std_driver;
352 sc->sc_l2.l1_token = sc;
353 sc->sc_l2.drv = drv;
354 isdn_layer2_status_ind(&sc->sc_l2, drv, STI_ATTACH, 1);
355 isdn_isdnif_ready(drv->isdnif);
358 static int
359 ifpci2_detach(device_t self, int flags)
361 struct ifpci_softc *psc = device_private(self);
363 bus_space_unmap(psc->sc_isic.sc_maps[0].t, psc->sc_isic.sc_maps[0].h, psc->sc_size);
364 bus_space_free(psc->sc_isic.sc_maps[0].t, psc->sc_isic.sc_maps[0].h, psc->sc_size);
365 pci_intr_disestablish(psc->sc_pc, psc->sc_ih);
367 return (0);
371 ifpci2_activate(device_t self, enum devact act)
373 struct ifpci_softc *psc = device_private(self);
375 switch (act) {
376 case DVACT_DEACTIVATE:
377 psc->sc_isic.sc_intr_valid = ISIC_INTR_DYING;
378 isdn_layer2_status_ind(&psc->sc_isic.sc_l2, psc->sc_isic.sc_l3token, STI_ATTACH, 0);
379 isdn_detach_isdnif(psc->sc_isic.sc_l3token);
380 psc->sc_isic.sc_l3token = NULL;
381 return 0;
382 default:
383 return EOPNOTSUPP;
387 /*---------------------------------------------------------------------------*
388 * AVM read fifo routines
389 *---------------------------------------------------------------------------*/
391 static void
392 avma1pp2_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size)
394 int i;
396 switch (what) {
397 case ISIC_WHAT_ISAC:
398 bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ISACSX_INDEX, 0);
399 /* evidently each byte must be read as a long */
400 for (i = 0; i < size; i++)
401 ((u_int8_t *)buf)[i] = (u_int8_t)bus_space_read_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ISACSX_DATA);
402 break;
403 case ISIC_WHAT_HSCXA:
404 hscx_read_fifo(0, buf, size, sc);
405 break;
406 case ISIC_WHAT_HSCXB:
407 hscx_read_fifo(1, buf, size, sc);
408 break;
412 static void
413 hscx_read_fifo(int chan, void *buf, size_t len, struct isic_softc *sc)
415 int dataoff;
417 dataoff = chan ? HSCX_FIFO2 : HSCX_FIFO1;
418 bus_space_read_multi_stream_4(sc->sc_maps[0].t, sc->sc_maps[0].h,
419 dataoff, buf, len/4);
420 if (__predict_false((len&3)>0)) {
421 uint32_t tmp;
423 buf = ((unsigned char*)buf) + (len & ~3u);
424 len &= 3u;
425 tmp = bus_space_read_stream_4(sc->sc_maps[0].t,
426 sc->sc_maps[0].h, dataoff);
427 memcpy(buf, &tmp, len);
431 /*---------------------------------------------------------------------------*
432 * AVM write fifo routines
433 *---------------------------------------------------------------------------*/
435 static void
436 avma1pp2_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size)
438 int i;
440 switch (what) {
441 case ISIC_WHAT_ISAC:
442 bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ISACSX_INDEX, 0);
443 /* evidently each byte must be written as a long */
444 for (i = 0; i < size; i++)
445 bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ISACSX_DATA, ((const unsigned char *)buf)[i]);
446 break;
447 case ISIC_WHAT_HSCXA:
448 hscx_write_fifo(0, buf, size, sc);
449 break;
450 case ISIC_WHAT_HSCXB:
451 hscx_write_fifo(1, buf, size, sc);
452 break;
456 static void
457 hscx_write_fifo(int chan, const void *buf, size_t len, struct isic_softc *sc)
459 size_t cnt;
460 int dataoff;
461 l1_bchan_state_t *Bchan = &sc->sc_chan[chan];
463 dataoff = chan ? HSCX_FIFO2 : HSCX_FIFO1;
465 sc->avma1pp_cmd &= ~HSCX_CMD_XME;
466 sc->avma1pp_txl = 0;
467 if (Bchan->out_mbuf_cur == NULL)
469 if (Bchan->bprot != BPROT_NONE)
470 sc->avma1pp_cmd |= HSCX_CMD_XME;
472 if (len != sc->sc_bfifolen)
473 sc->avma1pp_txl = len;
475 cnt = 0; /* borrow cnt */
476 AVMA1PPSETCMDLONG(cnt);
477 hscx_write_reg(chan, cnt, sc);
479 bus_space_write_multi_stream_4(sc->sc_maps[0].t, sc->sc_maps[0].h,
480 dataoff, buf, (len+3)/4);
481 if (__predict_false((len&3)>0)) {
482 uint32_t tmp;
484 buf = (const unsigned char*)buf + (len & ~3u);
485 len &= 3u;
486 memset(&tmp, 0, sizeof(tmp));
487 memcpy(&tmp, buf, len);
488 bus_space_write_stream_4(sc->sc_maps[0].t, sc->sc_maps[0].h,
489 dataoff, tmp);
493 /*---------------------------------------------------------------------------*
494 * AVM write register routines
495 *---------------------------------------------------------------------------*/
497 static void
498 avma1pp2_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data)
500 switch (what) {
501 case ISIC_WHAT_ISAC:
502 bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ISACSX_INDEX, offs);
503 bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ISACSX_DATA, data);
504 break;
505 case ISIC_WHAT_HSCXA:
506 hscx_write_reg(0, data, sc);
507 break;
508 case ISIC_WHAT_HSCXB:
509 hscx_write_reg(1, data, sc);
510 break;
514 static void
515 hscx_write_reg(int chan, u_int val, struct isic_softc *sc)
517 u_int off;
519 off = (chan == 0 ? HSCX_STAT1 : HSCX_STAT2);
520 bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h, off, val);
523 /*---------------------------------------------------------------------------*
524 * AVM read register routines
525 *---------------------------------------------------------------------------*/
527 static u_int8_t
528 avma1pp2_read_reg(struct isic_softc *sc, int what, bus_size_t offs)
530 u_int8_t val;
532 switch (what) {
533 case ISIC_WHAT_ISAC:
534 bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ISACSX_INDEX, offs);
535 val = (u_int8_t)bus_space_read_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ISACSX_DATA);
536 return(val);
537 case ISIC_WHAT_HSCXA:
538 return hscx_read_reg(0, sc);
539 case ISIC_WHAT_HSCXB:
540 return hscx_read_reg(1, sc);
542 return 0;
545 static u_char
546 hscx_read_reg(int chan, struct isic_softc *sc)
548 return(hscx_read_reg_int(chan, sc) & 0xff);
552 * need to be able to return an int because the RBCH is in the 2nd
553 * byte.
555 static u_int
556 hscx_read_reg_int(int chan, struct isic_softc *sc)
558 u_int off;
560 off = (chan == 0 ? HSCX_STAT1 : HSCX_STAT2);
561 return(bus_space_read_4(sc->sc_maps[0].t, sc->sc_maps[0].h, off));
565 * this is the real interrupt routine
567 static void
568 avma1pp2_hscx_intr(int h_chan, u_int stat, struct isic_softc *sc)
570 register l1_bchan_state_t *chan = &sc->sc_chan[h_chan];
571 int activity = -1;
572 u_int param = 0;
574 NDBGL1(L1_H_IRQ, "%#x", stat);
576 if((stat & HSCX_INT_XDU) && (chan->bprot != BPROT_NONE))/* xmit data underrun */
578 chan->stat_XDU++;
579 NDBGL1(L1_H_XFRERR, "xmit data underrun");
580 /* abort the transmission */
581 sc->avma1pp_txl = 0;
582 sc->avma1pp_cmd |= HSCX_CMD_XRS;
583 AVMA1PPSETCMDLONG(param);
584 hscx_write_reg(h_chan, param, sc);
585 sc->avma1pp_cmd &= ~HSCX_CMD_XRS;
586 AVMA1PPSETCMDLONG(param);
587 hscx_write_reg(h_chan, param, sc);
589 if (chan->out_mbuf_head != NULL) /* don't continue to transmit this buffer */
591 i4b_Bfreembuf(chan->out_mbuf_head);
592 chan->out_mbuf_cur = chan->out_mbuf_head = NULL;
597 * The following is based on examination of the Linux driver.
599 * The logic here is different than with a "real" HSCX; all kinds
600 * of information (interrupt/status bits) are in stat.
601 * HSCX_INT_RPR indicates a receive interrupt
602 * HSCX_STAT_RDO indicates an overrun condition, abort -
603 * otherwise read the bytes ((stat & HSCX_STZT_RML_MASK) >> 8)
604 * HSCX_STAT_RME indicates end-of-frame and apparently any
605 * CRC/framing errors are only reported in this state.
606 * if ((stat & HSCX_STAT_CRCVFRRAB) != HSCX_STAT_CRCVFR)
607 * CRC/framing error
610 if(stat & HSCX_INT_RPR)
612 register int fifo_data_len;
613 int error = 0;
614 /* always have to read the FIFO, so use a scratch buffer */
615 u_char scrbuf[HSCX_FIFO_LEN];
617 if(stat & HSCX_STAT_RDO)
619 chan->stat_RDO++;
620 NDBGL1(L1_H_XFRERR, "receive data overflow");
621 error++;
625 * check whether we're receiving data for an inactive B-channel
626 * and discard it. This appears to happen for telephony when
627 * both B-channels are active and one is deactivated. Since
628 * it is not really possible to deactivate the channel in that
629 * case (the ASIC seems to deactivate _both_ channels), the
630 * "deactivated" channel keeps receiving data which can lead
631 * to exhaustion of mbufs and a kernel panic.
633 * This is a hack, but it's the only solution I can think of
634 * without having the documentation for the ASIC.
635 * GJ - 28 Nov 1999
637 if (chan->state == HSCX_IDLE)
639 NDBGL1(L1_H_XFRERR, "toss data from %d", h_chan);
640 error++;
643 fifo_data_len = ((stat & HSCX_STAT_RML_MASK) >> 8);
645 if(fifo_data_len == 0)
646 fifo_data_len = sc->sc_bfifolen;
648 /* ALWAYS read data from HSCX fifo */
650 HSCX_RDFIFO(h_chan, scrbuf, fifo_data_len);
651 chan->rxcount += fifo_data_len;
653 /* all error conditions checked, now decide and take action */
655 if(error == 0)
657 if(chan->in_mbuf == NULL)
659 if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL)
660 panic("L1 avma1pp2_hscx_intr: RME, cannot allocate mbuf!");
661 chan->in_cbptr = chan->in_mbuf->m_data;
662 chan->in_len = 0;
665 if((chan->in_len + fifo_data_len) <= BCH_MAX_DATALEN)
667 /* OK to copy the data */
668 memcpy(chan->in_cbptr, scrbuf, fifo_data_len);
669 chan->in_cbptr += fifo_data_len;
670 chan->in_len += fifo_data_len;
672 /* setup mbuf data length */
674 chan->in_mbuf->m_len = chan->in_len;
675 chan->in_mbuf->m_pkthdr.len = chan->in_len;
677 if(sc->sc_trace & TRACE_B_RX)
679 struct i4b_trace_hdr hdr;
680 hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
681 hdr.dir = FROM_NT;
682 hdr.count = ++sc->sc_trace_bcount;
683 isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data);
686 if (stat & HSCX_STAT_RME)
688 if((stat & HSCX_STAT_CRCVFRRAB) == HSCX_STAT_CRCVFR)
690 (*chan->l4_driver->bch_rx_data_ready)(chan->l4_driver_softc);
691 activity = ACT_RX;
693 /* mark buffer ptr as unused */
695 chan->in_mbuf = NULL;
696 chan->in_cbptr = NULL;
697 chan->in_len = 0;
699 else
701 chan->stat_CRC++;
702 NDBGL1(L1_H_XFRERR, "CRC/RAB");
703 if (chan->in_mbuf != NULL)
705 i4b_Bfreembuf(chan->in_mbuf);
706 chan->in_mbuf = NULL;
707 chan->in_cbptr = NULL;
708 chan->in_len = 0;
712 } /* END enough space in mbuf */
713 else
715 if(chan->bprot == BPROT_NONE)
717 /* setup mbuf data length */
719 chan->in_mbuf->m_len = chan->in_len;
720 chan->in_mbuf->m_pkthdr.len = chan->in_len;
722 if(sc->sc_trace & TRACE_B_RX)
724 struct i4b_trace_hdr hdr;
725 hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
726 hdr.dir = FROM_NT;
727 hdr.count = ++sc->sc_trace_bcount;
728 isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data);
731 if(!(isdn_bchan_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len)))
732 activity = ACT_RX;
734 /* move rx'd data to rx queue */
736 if (!(IF_QFULL(&chan->rx_queue)))
738 IF_ENQUEUE(&chan->rx_queue, chan->in_mbuf);
740 else
742 i4b_Bfreembuf(chan->in_mbuf);
745 /* signal upper layer that data are available */
746 (*chan->l4_driver->bch_rx_data_ready)(chan->l4_driver_softc);
748 /* alloc new buffer */
750 if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL)
751 panic("L1 avma1pp2_hscx_intr: RPF, cannot allocate new mbuf!");
753 /* setup new data ptr */
755 chan->in_cbptr = chan->in_mbuf->m_data;
757 /* OK to copy the data */
758 memcpy(chan->in_cbptr, scrbuf, fifo_data_len);
760 chan->in_cbptr += fifo_data_len;
761 chan->in_len = fifo_data_len;
763 chan->rxcount += fifo_data_len;
765 else
767 NDBGL1(L1_H_XFRERR, "RAWHDLC rx buffer overflow in RPF, in_len=%d", chan->in_len);
768 chan->in_cbptr = chan->in_mbuf->m_data;
769 chan->in_len = 0;
772 } /* if(error == 0) */
773 else
775 /* land here for RDO */
776 if (chan->in_mbuf != NULL)
778 i4b_Bfreembuf(chan->in_mbuf);
779 chan->in_mbuf = NULL;
780 chan->in_cbptr = NULL;
781 chan->in_len = 0;
783 sc->avma1pp_txl = 0;
784 sc->avma1pp_cmd |= HSCX_CMD_RRS;
785 AVMA1PPSETCMDLONG(param);
786 hscx_write_reg(h_chan, param, sc);
787 sc->avma1pp_cmd &= ~HSCX_CMD_RRS;
788 AVMA1PPSETCMDLONG(param);
789 hscx_write_reg(h_chan, param, sc);
794 /* transmit fifo empty, new data can be written to fifo */
796 if(stat & HSCX_INT_XPR)
799 * for a description what is going on here, please have
800 * a look at isic_bchannel_start() in i4b_bchan.c !
803 NDBGL1(L1_H_IRQ, "%s: chan %d - XPR, Tx Fifo Empty!", device_xname(&sc->sc_dev), h_chan);
805 if(chan->out_mbuf_cur == NULL) /* last frame is transmitted */
807 IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head);
809 if(chan->out_mbuf_head == NULL)
811 chan->state &= ~HSCX_TX_ACTIVE;
812 (*chan->l4_driver->bch_tx_queue_empty)(chan->l4_driver_softc);
814 else
816 chan->state |= HSCX_TX_ACTIVE;
817 chan->out_mbuf_cur = chan->out_mbuf_head;
818 chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
819 chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
821 if(sc->sc_trace & TRACE_B_TX)
823 struct i4b_trace_hdr hdr;
824 hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
825 hdr.dir = FROM_TE;
826 hdr.count = ++sc->sc_trace_bcount;
827 isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
830 if(chan->bprot == BPROT_NONE)
832 if(!(isdn_bchan_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len)))
833 activity = ACT_TX;
835 else
837 activity = ACT_TX;
842 isic_hscx_fifo(chan, sc);
845 /* call timeout handling routine */
847 if(activity == ACT_RX || activity == ACT_TX)
848 (*chan->l4_driver->bch_activity)(chan->l4_driver_softc, activity);
852 * this is the main routine which checks each channel and then calls
853 * the real interrupt routine as appropriate
855 static void
856 avma1pp2_hscx_int_handler(struct isic_softc *sc)
858 u_int stat;
860 /* has to be a u_int because the byte count is in the 2nd byte */
861 stat = hscx_read_reg_int(0, sc);
862 if (stat & HSCX_INT_MASK)
863 avma1pp2_hscx_intr(0, stat, sc);
864 stat = hscx_read_reg_int(1, sc);
865 if (stat & HSCX_INT_MASK)
866 avma1pp2_hscx_intr(1, stat, sc);
869 static void
870 avma1pp2_disable(struct isic_softc *sc)
872 /* could be still be wrong, but seems to prevent hangs */
873 bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET, 0x00);
876 static int
877 avma1pp2_intr(void *parm)
879 struct isic_softc *sc = parm;
880 int ret = 0;
881 #define OURS ret = 1
882 u_char stat;
884 if (sc->sc_intr_valid != ISIC_INTR_VALID)
885 return 0;
887 stat = bus_space_read_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET);
888 NDBGL1(L1_H_IRQ, "stat %x", stat);
889 /* was there an interrupt from this card ? */
890 if ((stat & ASL_IRQ_Pending) == 0)
891 return 0; /* no */
892 /* For slow machines loop as long as an interrupt is active */
893 for (; ((stat & ASL_IRQ_Pending) != 0) ;)
895 /* interrupts are high active */
896 if (stat & ASL_IRQ_TIMER)
897 NDBGL1(L1_H_IRQ, "timer interrupt ???");
898 if (stat & ASL_IRQ_HSCX)
900 NDBGL1(L1_H_IRQ, "HSCX");
901 avma1pp2_hscx_int_handler(sc);
903 if (stat & ASL_IRQ_ISAC)
905 u_char isacsx_irq_stat;
907 NDBGL1(L1_H_IRQ, "ISAC");
908 for(;;)
910 /* ISTA tells us whether it was a C/I or HDLC int. */
911 isacsx_irq_stat = ISAC_READ(I_ISTA);
913 if(isacsx_irq_stat)
914 isic_isacsx_irq(sc, isacsx_irq_stat); /* isac handler */
915 else
916 break;
920 * XXX: Leo: Note that Linux doesn't do this mask
921 * frobbing...
923 ISAC_WRITE(I_MASKD, 0xff);
924 ISAC_WRITE(I_MASK, 0xff);
926 DELAY(100);
928 ISAC_WRITE(I_MASKD, isacsx_imaskd);
929 ISAC_WRITE(I_MASK, isacsx_imask);
932 stat = bus_space_read_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET);
933 NDBGL1(L1_H_IRQ, "stat %x", stat);
934 OURS;
936 return ret;
939 static void
940 avma1pp2_map_int(struct ifpci_softc *psc, struct pci_attach_args *pa)
942 struct isic_softc *sc = &psc->sc_isic;
943 pci_chipset_tag_t pc = pa->pa_pc;
944 pci_intr_handle_t ih;
945 const char *intrstr;
947 /* Map and establish the interrupt. */
948 if (pci_intr_map(pa, &ih)) {
949 aprint_error_dev(&sc->sc_dev, "couldn't map interrupt\n");
950 avma1pp2_disable(sc);
951 return;
953 psc->sc_pc = pc;
954 intrstr = pci_intr_string(pc, ih);
955 psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, avma1pp2_intr, sc);
956 if (psc->sc_ih == NULL) {
957 aprint_error_dev(&sc->sc_dev, "couldn't establish interrupt");
958 if (intrstr != NULL)
959 aprint_error(" at %s", intrstr);
960 aprint_error("\n");
961 avma1pp2_disable(sc);
962 return;
964 aprint_normal_dev(&sc->sc_dev, "interrupting at %s\n", intrstr);
967 static void
968 avma1pp2_hscx_init(struct isic_softc *sc, int h_chan, int activate)
970 l1_bchan_state_t *chan = &sc->sc_chan[h_chan];
971 u_int param = 0;
973 NDBGL1(L1_BCHAN, "%s: channel=%d, %s",
974 device_xname(&sc->sc_dev), h_chan, activate ? "activate" : "deactivate");
975 sc->avma1pp_cmd = sc->avma1pp_prot = sc->avma1pp_txl = 0;
977 if (activate == 0)
979 /* only deactivate if both channels are idle */
980 if (sc->sc_chan[HSCX_CH_A].state != HSCX_IDLE ||
981 sc->sc_chan[HSCX_CH_B].state != HSCX_IDLE)
983 return;
985 sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS;
986 sc->avma1pp_prot = HSCX_MODE_TRANS;
987 AVMA1PPSETCMDLONG(param);
988 hscx_write_reg(h_chan, param, sc);
989 return;
991 if(chan->bprot == BPROT_RHDLC)
993 NDBGL1(L1_BCHAN, "BPROT_RHDLC");
995 /* HDLC Frames, transparent mode 0 */
996 sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS;
997 sc->avma1pp_prot = HSCX_MODE_ITF_FLG;
998 AVMA1PPSETCMDLONG(param);
999 hscx_write_reg(h_chan, param, sc);
1000 sc->avma1pp_cmd = HSCX_CMD_XRS;
1001 AVMA1PPSETCMDLONG(param);
1002 hscx_write_reg(h_chan, param, sc);
1003 sc->avma1pp_cmd = 0;
1005 else
1007 NDBGL1(L1_BCHAN, "BPROT_NONE??");
1009 /* Raw Telephony, extended transparent mode 1 */
1010 sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS;
1011 sc->avma1pp_prot = HSCX_MODE_TRANS;
1012 AVMA1PPSETCMDLONG(param);
1013 hscx_write_reg(h_chan, param, sc);
1014 sc->avma1pp_cmd = HSCX_CMD_XRS;
1015 AVMA1PPSETCMDLONG(param);
1016 hscx_write_reg(h_chan, param, sc);
1017 sc->avma1pp_cmd = 0;
1021 static void
1022 avma1pp2_bchannel_setup(isdn_layer1token t, int h_chan, int bprot, int activate)
1024 struct isic_softc *sc = (struct isic_softc*)t;
1025 l1_bchan_state_t *chan = &sc->sc_chan[h_chan];
1027 int s = splnet();
1029 if(activate == 0)
1031 /* deactivation */
1032 chan->state = HSCX_IDLE;
1033 avma1pp2_hscx_init(sc, h_chan, activate);
1036 NDBGL1(L1_BCHAN, "%s: channel=%d, %s",
1037 device_xname(&sc->sc_dev), h_chan, activate ? "activate" : "deactivate");
1039 /* general part */
1041 chan->channel = h_chan; /* B channel */
1042 chan->bprot = bprot; /* B channel protocol */
1043 chan->state = HSCX_IDLE; /* B channel state */
1045 /* receiver part */
1047 i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */
1049 chan->rx_queue.ifq_maxlen = IFQ_MAXLEN;
1051 chan->rxcount = 0; /* reset rx counter */
1053 i4b_Bfreembuf(chan->in_mbuf); /* clean rx mbuf */
1055 chan->in_mbuf = NULL; /* reset mbuf ptr */
1056 chan->in_cbptr = NULL; /* reset mbuf curr ptr */
1057 chan->in_len = 0; /* reset mbuf data len */
1059 /* transmitter part */
1061 i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */
1063 chan->tx_queue.ifq_maxlen = IFQ_MAXLEN;
1065 chan->txcount = 0; /* reset tx counter */
1067 i4b_Bfreembuf(chan->out_mbuf_head); /* clean tx mbuf */
1069 chan->out_mbuf_head = NULL; /* reset head mbuf ptr */
1070 chan->out_mbuf_cur = NULL; /* reset current mbuf ptr */
1071 chan->out_mbuf_cur_ptr = NULL; /* reset current mbuf data ptr */
1072 chan->out_mbuf_cur_len = 0; /* reset current mbuf data cnt */
1074 if(activate != 0)
1076 /* activation */
1077 avma1pp2_hscx_init(sc, h_chan, activate);
1078 chan->state |= HSCX_AVMA1PP_ACTIVE;
1081 splx(s);
1084 static void
1085 avma1pp2_bchannel_start(isdn_layer1token t, int h_chan)
1087 struct isic_softc *sc = (struct isic_softc*)t;
1088 register l1_bchan_state_t *chan = &sc->sc_chan[h_chan];
1089 int s;
1090 int activity = -1;
1092 s = splnet(); /* enter critical section */
1093 if(chan->state & HSCX_TX_ACTIVE) /* already running ? */
1095 splx(s);
1096 return; /* yes, leave */
1099 /* get next mbuf from queue */
1101 IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head);
1103 if(chan->out_mbuf_head == NULL) /* queue empty ? */
1105 splx(s); /* leave critical section */
1106 return; /* yes, exit */
1109 /* init current mbuf values */
1111 chan->out_mbuf_cur = chan->out_mbuf_head;
1112 chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
1113 chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
1115 /* activity indicator for timeout handling */
1117 if(chan->bprot == BPROT_NONE)
1119 if(!(isdn_bchan_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len)))
1120 activity = ACT_TX;
1122 else
1124 activity = ACT_TX;
1127 chan->state |= HSCX_TX_ACTIVE; /* we start transmitting */
1129 if(sc->sc_trace & TRACE_B_TX) /* if trace, send mbuf to trace dev */
1131 struct i4b_trace_hdr hdr;
1132 hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
1133 hdr.dir = FROM_TE;
1134 hdr.count = ++sc->sc_trace_bcount;
1135 isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
1138 isic_hscx_fifo(chan, sc);
1140 /* call timeout handling routine */
1142 if(activity == ACT_RX || activity == ACT_TX)
1143 (*chan->l4_driver->bch_activity)(chan->l4_driver_softc, activity);
1145 splx(s);
1148 /*---------------------------------------------------------------------------*
1149 * return the address of isic drivers linktab
1150 *---------------------------------------------------------------------------*/
1151 static isdn_link_t *
1152 avma1pp2_ret_linktab(void *token, int channel)
1154 struct l2_softc *l2sc = token;
1155 struct isic_softc *sc = l2sc->l1_token;
1157 l1_bchan_state_t *chan = &sc->sc_chan[channel];
1159 return(&chan->isdn_linktab);
1162 /*---------------------------------------------------------------------------*
1163 * set the driver linktab in the b channel softc
1164 *---------------------------------------------------------------------------*/
1165 static void
1166 avma1pp2_set_link(void *token, int channel, const struct isdn_l4_driver_functions *l4_driver, void *l4_driver_softc)
1168 struct l2_softc *l2sc = token;
1169 struct isic_softc *sc = l2sc->l1_token;
1170 l1_bchan_state_t *chan = &sc->sc_chan[channel];
1172 chan->l4_driver = l4_driver;
1173 chan->l4_driver_softc = l4_driver_softc;
1176 static const struct isdn_l4_bchannel_functions
1177 avma1pp2_l4_bchannel_functions = {
1178 avma1pp2_bchannel_setup,
1179 avma1pp2_bchannel_start,
1180 avma1pp2_bchannel_stat
1183 /*---------------------------------------------------------------------------*
1184 * initialize our local linktab
1185 *---------------------------------------------------------------------------*/
1186 static void
1187 avma1pp2_init_linktab(struct isic_softc *sc)
1189 l1_bchan_state_t *chan = &sc->sc_chan[HSCX_CH_A];
1190 isdn_link_t *lt = &chan->isdn_linktab;
1192 /* local setup */
1193 lt->l1token = sc;
1194 lt->channel = HSCX_CH_A;
1195 lt->bchannel_driver = &avma1pp2_l4_bchannel_functions;
1196 lt->tx_queue = &chan->tx_queue;
1198 /* used by non-HDLC data transfers, i.e. telephony drivers */
1199 lt->rx_queue = &chan->rx_queue;
1201 /* used by HDLC data transfers, i.e. ipr and isp drivers */
1202 lt->rx_mbuf = &chan->in_mbuf;
1204 chan = &sc->sc_chan[HSCX_CH_B];
1205 lt = &chan->isdn_linktab;
1207 lt->l1token = sc;
1208 lt->channel = HSCX_CH_B;
1209 lt->bchannel_driver = &avma1pp2_l4_bchannel_functions;
1210 lt->tx_queue = &chan->tx_queue;
1212 /* used by non-HDLC data transfers, i.e. telephony drivers */
1213 lt->rx_queue = &chan->rx_queue;
1215 /* used by HDLC data transfers, i.e. ipr and isp drivers */
1216 lt->rx_mbuf = &chan->in_mbuf;
1220 * use this instead of isic_bchannel_stat in i4b_bchan.c because it's static
1222 static void
1223 avma1pp2_bchannel_stat(isdn_layer1token t, int h_chan, bchan_statistics_t *bsp)
1225 struct isic_softc *sc = (struct isic_softc*)t;
1226 l1_bchan_state_t *chan = &sc->sc_chan[h_chan];
1227 int s;
1229 s = splnet();
1231 bsp->outbytes = chan->txcount;
1232 bsp->inbytes = chan->rxcount;
1234 chan->txcount = 0;
1235 chan->rxcount = 0;
1237 splx(s);
1240 /*---------------------------------------------------------------------------*
1241 * fill HSCX fifo with data from the current mbuf
1242 * Put this here until it can go into i4b_hscx.c
1243 *---------------------------------------------------------------------------*/
1244 static int
1245 isic_hscx_fifo(l1_bchan_state_t *chan, struct isic_softc *sc)
1247 int len;
1248 int nextlen;
1249 int i;
1250 int cmd;
1251 /* using a scratch buffer simplifies writing to the FIFO */
1252 u_char scrbuf[HSCX_FIFO_LEN];
1254 len = 0;
1255 cmd = 0;
1258 * fill the HSCX tx fifo with data from the current mbuf. if
1259 * current mbuf holds less data than HSCX fifo length, try to
1260 * get the next mbuf from (a possible) mbuf chain. if there is
1261 * not enough data in a single mbuf or in a chain, then this
1262 * is the last mbuf and we tell the HSCX that it has to send
1263 * CRC and closing flag
1266 while(chan->out_mbuf_cur && len != sc->sc_bfifolen)
1268 nextlen = min(chan->out_mbuf_cur_len, sc->sc_bfifolen - len);
1270 #ifdef NOTDEF
1271 printf("i:mh=%p, mc=%p, mcp=%p, mcl=%d l=%d nl=%d # ",
1272 chan->out_mbuf_head,
1273 chan->out_mbuf_cur,
1274 chan->out_mbuf_cur_ptr,
1275 chan->out_mbuf_cur_len,
1276 len,
1277 nextlen);
1278 #endif
1280 cmd |= HSCX_CMDR_XTF;
1281 /* collect the data in the scratch buffer */
1282 for (i = 0; i < nextlen; i++)
1283 scrbuf[i + len] = chan->out_mbuf_cur_ptr[i];
1285 len += nextlen;
1286 chan->txcount += nextlen;
1288 chan->out_mbuf_cur_ptr += nextlen;
1289 chan->out_mbuf_cur_len -= nextlen;
1291 if(chan->out_mbuf_cur_len == 0)
1293 if((chan->out_mbuf_cur = chan->out_mbuf_cur->m_next) != NULL)
1295 chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
1296 chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
1298 if(sc->sc_trace & TRACE_B_TX)
1300 struct i4b_trace_hdr hdr;
1301 hdr.type = (chan->channel == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
1302 hdr.dir = FROM_TE;
1303 hdr.count = ++sc->sc_trace_bcount;
1304 isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
1307 else
1309 if (chan->bprot != BPROT_NONE)
1310 cmd |= HSCX_CMDR_XME;
1311 i4b_Bfreembuf(chan->out_mbuf_head);
1312 chan->out_mbuf_head = NULL;
1316 /* write what we have from the scratch buf to the HSCX fifo */
1317 if (len != 0)
1318 HSCX_WRFIFO(chan->channel, scrbuf, len);
1319 return(cmd);