Home | History | Annotate | Line # | Download | only in ic
daic.c revision 1.31
      1 /*-
      2  * Copyright (c) 2002 The NetBSD Foundation, Inc.
      3  * All rights reserved.
      4  *
      5  * This code is derived from software contributed to The NetBSD Foundation
      6  * by Martin Husemann <martin (at) NetBSD.org>.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     27  * POSSIBILITY OF SUCH DAMAGE.
     28  *
     29  */
     30 
     31 #include <sys/cdefs.h>
     32 __KERNEL_RCSID(0, "$NetBSD: daic.c,v 1.30 2010/07/27 08:07:36 martin Exp $");
     33 
     34 /*
     35  * daic.c: MI driver for Diehl active ISDN cards (S, SX, SXn, SCOM, QUADRO)
     36  */
     37 
     38 #include <sys/param.h>
     39 #include <sys/systm.h>
     40 #include <sys/kernel.h>
     41 #include <sys/errno.h>
     42 #include <sys/ioctl.h>
     43 #include <sys/device.h>
     44 #include <sys/malloc.h>
     45 #include <sys/proc.h>
     46 #include <sys/socket.h>
     47 #include <net/if.h>
     48 
     49 #include <netisdn/i4b_ioctl.h>
     50 #include <netisdn/i4b_l3l4.h>
     51 #include <netisdn/i4b_isdnq931.h>
     52 #include <netisdn/i4b_q931.h>
     53 #include <netisdn/i4b_l3fsm.h>
     54 #include <netisdn/i4b_l4.h>
     55 
     56 #include <sys/bus.h>
     57 #include <dev/ic/daicvar.h>
     58 #include <dev/ic/daicreg.h>
     59 #include <dev/microcode/daic/dnload.h>
     60 
     61 #ifdef NetBSD1_3
     62 #if NetBSD1_3 < 2
     63 /* the device is MI, only the attach struct is in the bus
     64    dependent frontend. And only on old versions... */
     65 struct cfdriver daic_cd = {
     66 	NULL, "daic", DV_DULL
     67 };
     68 #endif
     69 #endif
     70 
     71 /* local function prototypes */
     72 static const char * cardtypename(int cardtype);
     73 static int daic_download(void *, int portcount, struct isdn_dr_prot *data);
     74 static int daic_diagnostic(void *, struct isdn_diagnostic_request *req);
     75 static void daic_connect_request(struct call_desc *cd);
     76 static void daic_connect_response(struct call_desc *cd, int, int);
     77 static void daic_disconnect_request(struct call_desc *cd, int);
     78 static int daic_reset(bus_space_tag_t bus, bus_space_handle_t io, int port, int *memsize);
     79 static int daic_handle_intr(struct daic_softc *sc, int port);
     80 static void daic_register_port(struct daic_softc *sc, int port);
     81 static void daic_request(struct daic_softc *sc, int port, u_int req, u_int id, bus_size_t parmsize, const u_int8_t *parms);
     82 static u_int daic_assign(struct daic_softc *sc, int port, u_int instance, bus_size_t parmsize, const u_int8_t *parms);
     83 static void daic_indicate_ind(struct daic_softc *sc, int port);
     84 static void daic_bch_config(void *, int channel, int bprot, int updown);
     85 static void daic_bch_tx_start(void *, int channel);
     86 static void daic_set_link(void *softc, int channel,
     87 	const struct isdn_l4_driver_functions *l4_driver, void *l4_inst );
     88 static void daic_mgmt_command(struct isdn_l3_driver *drv, int cmd, void *parm);
     89 static void daic_alert_request(struct call_desc *cd);
     90 
     91 static isdn_link_t *daic_ret_linktab(void *softc, int channel);
     92 
     93 #ifdef DAIC_DEBUG
     94 static void daic_dump_request(struct daic_softc *sc, int port, u_int req, u_int id, bus_size_t parmsize, u_int8_t *parms);
     95 #endif
     96 
     97 /* static data */
     98 static const char * const cardnames[] = {
     99 	"S", "SX", "SCOM", "QUADRO"
    100 };
    101 
    102 static const char * const err_codes[DAIC_RC_ERRMASK+1] = {
    103 	"NO ERROR",
    104 	"UNKNOWN COMMAND",
    105 	"WRONG COMMAND",
    106 	"WRONG ID",
    107 	"WRONG CH",
    108 	"UNKNOWN IE",
    109 	"WRONG IE",
    110 	"OUT OF RESOURCES"
    111 };
    112 
    113 /* fixed parameters */
    114 
    115 /* no parameters */
    116 static u_int8_t parm_none[] = { 0 };
    117 #define	VOIDREQ(sc,port,req,id)	daic_request(sc, port, req, id, sizeof parm_none, parm_none)
    118 
    119 /* assign request for the global d-channel instance */
    120 static u_int8_t parm_global_assign[] = {
    121 /*	BC	len	cap	rate	A-law	*/
    122 	0x04,	0x03,	0x80,	0x90,	0xa3,	/* 64k speech */
    123 	0x04,	0x02,	0x88,	0x90,		/* 64k data */
    124 	0x04,	0x03,	0x89,	0x90,	0xa3,	/* restricted digital info */
    125 	0x04,	0x03,	0x90,	0x90,	0xa3,	/* 3.1k speech */
    126 /*	shift6	SIN	len	service		*/
    127 	0x96,	0x01,	0x02,	0x00, 0x00,	/* any service */
    128 /*	end of parms */
    129 	0x00
    130 };
    131 
    132 /*---------------------------------------------------------------------------*
    133  *	Return the name of a card with given cardtype
    134  *---------------------------------------------------------------------------*/
    135 static const char *
    136 cardtypename(int cardtype)
    137 {
    138 	if (cardtype >= 0 && cardtype < (sizeof(cardnames) / sizeof(cardnames[0])))
    139 		return cardnames[cardtype];
    140 	else
    141 		return "unknown type";
    142 }
    143 
    144 /*---------------------------------------------------------------------------*
    145  * Probe for presence of device at given io space.
    146  * Return the card type (stupid ISA needs to know this in advance, to
    147  * calculate the share memory size).
    148  *---------------------------------------------------------------------------*/
    149 int
    150 daic_probe(bus_space_tag_t bus, bus_space_handle_t io)
    151 {
    152 	return (daic_reset(bus, io, 0, NULL));
    153 }
    154 
    155 /*---------------------------------------------------------------------------*
    156  * Attach and initialize the card at given io space.
    157  *---------------------------------------------------------------------------*/
    158 void
    159 daic_attach(device_t self, struct daic_softc *sc)
    160 {
    161 	int i, num_ports, memsize = 0;
    162 
    163 	/* init sc */
    164 	memset(sc->sc_port, 0, sizeof sc->sc_port);
    165 	memset(sc->sc_con, 0, sizeof sc->sc_con);
    166 	sc->sc_cardtype = -1;
    167 
    168 	/* init card */
    169 	sc->sc_cardtype = daic_reset(sc->sc_iot, sc->sc_ioh, 0, &memsize);
    170 	if (sc->sc_cardtype == 0) {
    171 		printf(": unknown card, can not attach.\n");
    172 		return;
    173 	}
    174 
    175 	printf("\n");
    176 	printf("%s: EICON.Diehl %s\n", device_xname(sc->sc_dev),
    177 	    cardtypename(sc->sc_cardtype));
    178 	printf("%s: %d kByte on board RAM\n", device_xname(sc->sc_dev), memsize);
    179 	num_ports = sc->sc_cardtype == DAIC_TYPE_QUAD ? 4 : 1;
    180 	for (i = 0; i < num_ports; i++)
    181 		sc->sc_port[i].du_state = DAIC_STATE_DOWNLOAD;
    182 
    183 	/* register all ports this card has */
    184 	for (i = 0; i < num_ports; i++)
    185 		daic_register_port(sc, i);
    186 }
    187 
    188 /*---------------------------------------------------------------------------*
    189  * handle interrupts for one port of the card
    190  *---------------------------------------------------------------------------*/
    191 static int
    192 daic_handle_intr(struct daic_softc *sc, int port)
    193 {
    194 	struct outcallentry *assoc;
    195 	struct daic_unit * du = &sc->sc_port[port];
    196 	int off = port * DAIC_ISA_MEMSIZE;
    197 	u_int8_t rc, rcid;
    198 	u_int8_t ind, indid;
    199 	int chan;
    200 
    201 	/* check if we caused the interrupt */
    202 	if (!bus_space_read_1(sc->sc_iot, sc->sc_ioh, DAIC_IRQ+off))
    203 		return 0;	/* nope, exit */
    204 
    205 	/* is the card in running state yet? */
    206 	if (du->du_state == DAIC_STATE_TESTING) {
    207 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_RC+off, 0);
    208 		du->du_state = DAIC_STATE_RUNNING;
    209 		wakeup(du);
    210 		goto done;
    211 	}
    212 
    213 	/* what caused the interrupt? */
    214 	/* (1) Check for a return code */
    215 	rc = bus_space_read_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_RC+off);
    216 	rcid = bus_space_read_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_RCID+off);
    217 	if (!rc) goto check_ind;
    218 
    219 	/* maybe an assign answer (positive or negative) */
    220 	if (rc == DAIC_RC_ASSIGN_OK) {
    221 		du->du_assign_res = rcid;
    222 		/* assing rc is special, we tell the card it's done */
    223 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_REQ+off, 0);
    224 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_RC+off, 0);
    225 		/* we handle some types of assigns to global dchannel id's automaticaly */
    226 		if (du->du_assign & DAIC_ASSIGN_GLOBAL) {
    227 			du->du_global_dchan = rcid;
    228 			du->du_assign &= ~(DAIC_ASSIGN_GLOBAL|DAIC_ASSIGN_PENDING);
    229 			if (du->du_assign & DAIC_ASSIGN_SLEEPING) {
    230 				du->du_assign = 0;
    231 				wakeup(&du->du_assign_res);
    232 			}
    233 		} else {
    234 			wakeup(&du->du_assign);
    235 		}
    236 		goto check_ind;
    237 	} else if ((rc & DAIC_RC_ASSIGN_MASK) == DAIC_RC_ASSIGN_RC) {
    238 		aprint_error_dev(sc->sc_dev, "assign request failed, error 0x%02x: %s\n",
    239 			rc & DAIC_RC_ERRMASK,
    240 			err_codes[rc & DAIC_RC_ERRMASK]);
    241 		du->du_assign_res = 0;
    242 		/* assing rc is special, we tell the card it's done */
    243 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_REQ+off, 0);
    244 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_RC+off, 0);
    245 		/* that's it */
    246 		wakeup(&du->du_assign);
    247 		goto check_ind;
    248 	}
    249 	if (rcid == du->du_global_dchan) {
    250 		du->du_request_res = rc;
    251 		wakeup(&du->du_request_res);
    252 		goto req_done;
    253 	}
    254 	for (chan = 0; chan < 2; chan++) {
    255 		if (rcid == sc->sc_con[port*2+chan].dchan_inst) {
    256 			sc->sc_con[port*2+chan].dchan_rc = rc;
    257 			wakeup(&sc->sc_con[port*2+chan].dchan_rc);
    258 			goto req_done;
    259 		} else if (rcid == sc->sc_con[port*2+chan].bchan_inst) {
    260 			sc->sc_con[port*2+chan].bchan_rc = rc;
    261 			wakeup(&sc->sc_con[port*2+chan].bchan_rc);
    262 			goto req_done;
    263 		}
    264 	}
    265 	TAILQ_FOREACH(assoc, &sc->sc_outcalls[port], queue) {
    266 		if (rcid == assoc->dchan_id) {
    267 			assoc->rc = rc;
    268 			wakeup(assoc);
    269 			goto req_done;
    270 		}
    271 	}
    272 
    273 	/* not found? */
    274 	printf("%s: unknown id 0x%02x got rc 0x%02x: %s\n",
    275 		device_xname(sc->sc_dev), rcid, rc,
    276 		err_codes[rc & DAIC_RC_ERRMASK]);
    277 
    278 req_done:
    279 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_RC+off, 0);
    280 
    281 check_ind:
    282 	/* (2) Check for an indication */
    283 	ind = bus_space_read_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_IND+off);
    284 	indid = bus_space_read_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_INDID+off);
    285 	if (!ind) goto done;
    286 
    287 	/* incoming call routed to global dchannel task? */
    288 	if (indid == du->du_global_dchan) {
    289 		if (ind == DAIC_IND_INDICATE) {
    290 			daic_indicate_ind(sc, port);
    291 		} else if (ind == DAIC_IND_INFO) {
    292 			int i;
    293 
    294 			printf("%s: got info indication\n",
    295 				device_xname(sc->sc_dev));
    296 
    297 			for (i = 0; i < 48; i++) {
    298 				if (!(i % 16))
    299 					printf("\n%02x:", i);
    300 				printf(" %02x", bus_space_read_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_RBUFFER+off+i));
    301 			}
    302 			printf("\n");
    303 		} else if (ind == DAIC_IND_HANGUP) {
    304 			printf("%s: got global HANGUP indication\n",
    305 				device_xname(sc->sc_dev));
    306 		} else {
    307 			printf("%s: unknown global indication: 0x%02x\n",
    308 				device_xname(sc->sc_dev), ind);
    309 		}
    310 		goto ind_done;
    311 	}
    312 
    313 	for (chan = 0; chan < 2; chan++) {
    314 		if (indid == sc->sc_con[port*2+chan].dchan_inst) {
    315 			printf("%s: D-Channel indication 0x%02x for channel %d\n",
    316 				device_xname(sc->sc_dev), ind, chan);
    317 			goto ind_done;
    318 		} else if (indid == sc->sc_con[port*2+chan].bchan_inst) {
    319 			printf("%s: B-Channel indication 0x%02x for channel %d\n",
    320 				device_xname(sc->sc_dev), ind, chan);
    321 			goto ind_done;
    322 		}
    323 	}
    324 
    325 	TAILQ_FOREACH(assoc, &sc->sc_outcalls[port], queue) {
    326 		if (indid == assoc->dchan_id) {
    327 			printf("%s: D-Channel indication 0x%02x for outgoing call with cdid %d\n",
    328 				device_xname(sc->sc_dev), ind, assoc->cdid);
    329 			goto ind_done;
    330 		}
    331 	}
    332 
    333 	/* not found - something's wrong! */
    334 	printf("%s: got ind 0x%02x for id 0x%02x\n", device_xname(sc->sc_dev), ind, indid);
    335 
    336 ind_done:
    337 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_IND+off, 0);
    338 
    339 done:
    340 	/* tell card we're ready for more... */
    341 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_IRQ+off, 0);
    342 
    343 	return 1;
    344 }
    345 
    346 /*---------------------------------------------------------------------------*
    347  * Handle interrupts
    348  *---------------------------------------------------------------------------*/
    349 int
    350 daic_intr(struct daic_softc *sc)
    351 {
    352 	int handeld = 0;
    353 	if (sc->sc_cardtype == DAIC_TYPE_QUAD) {
    354 		int i;
    355 		for (i = 0; i < 4; i++)
    356 			handeld |= daic_handle_intr(sc, i);
    357 	} else
    358 		handeld = daic_handle_intr(sc, 0);
    359 	return handeld;
    360 }
    361 
    362 /*---------------------------------------------------------------------------*
    363  * Download primary protocol microcode to on-board processor
    364  *---------------------------------------------------------------------------*/
    365 static int
    366 daic_download(void *token, int count, struct isdn_dr_prot *data)
    367 {
    368 	struct daic_unit *du = token;
    369 	struct daic_softc *sc = du->du_sc;
    370 	int i;
    371 
    372 	if (sc->sc_cardtype != DAIC_TYPE_QUAD)
    373 		count = 1;	/* XXX - or signal error ? */
    374 
    375 	for (i = 0; i < count; i++) {
    376 		int off = DAIC_ISA_MEMSIZE * i;
    377 		u_int8_t *p = data[i].microcode;
    378 		size_t s = data[i].bytecount;
    379 		u_int32_t sw_id;
    380 		int cnt, x;
    381 		for (p = data[i].microcode+4, cnt = 0; *p && cnt < 70; p++, cnt++)
    382 			;
    383 		sw_id = p[1] | (p[2] << 8) | (p[3] << 16) | (p[4] << 24);
    384 		if (sc->sc_cardtype == DAIC_TYPE_QUAD)
    385 			printf("%s port %d: downloading %s\n",
    386 				device_xname(sc->sc_dev), i, data[i].microcode+4);
    387 		else
    388 			printf("%s: downloading %s\n",
    389 				device_xname(sc->sc_dev), data[i].microcode+4);
    390 		x = splnet();
    391 		p = data[i].microcode;
    392 		while (s > 0) {
    393 		    size_t size = (s > 256) ? 256 : s;
    394 		    bus_space_write_region_1(sc->sc_iot, sc->sc_ioh, DAIC_BOOT_BUF+off, p, size);
    395 		    p += size;
    396 		    s -= size;
    397 		    bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_BOOT_CTRL+off, 1);
    398 		    splx(x);
    399 		    for (cnt = 0; cnt < 2*hz; cnt++) {
    400 		    	x = splnet();
    401 		    	if (bus_space_read_1(sc->sc_iot, sc->sc_ioh, DAIC_BOOT_CTRL+off) == 0)
    402 		    	    break;
    403 		    	splx(x);
    404 		    	tsleep(sc, 0, "daic download", 1);
    405 		    }
    406 	    	    if (bus_space_read_1(sc->sc_iot, sc->sc_ioh, DAIC_BOOT_CTRL+off) != 0) {
    407 	    	    	splx(x);
    408 	    	    	aprint_error_dev(sc->sc_dev, "download of microcode failed\n");
    409 	    	    	return EIO;
    410 	    	    }
    411 		}
    412 
    413 		/* configure microcode - no parameters yet - XXX */
    414 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_BOOT_TEI+off, 0);
    415 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_BOOT_NT2+off, 0);
    416 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_BOOT_ZERO+off, 0);
    417 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_BOOT_WATCHDOG+off, 0);
    418 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_BOOT_PERMANENT+off, 0);
    419 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_BOOT_XINTERFACE+off, 0);
    420 
    421 		/* start protocol */
    422 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_BOOT_CTRL+off, 2);
    423 
    424 		/* wait for signature */
    425 		for (cnt = 0; cnt < 2*hz; cnt++) {
    426 			u_int16_t signature;
    427 			signature = bus_space_read_2(sc->sc_iot, sc->sc_ioh, DAIC_BOOT_SIGNATURE+off);
    428 			if (signature == DAIC_SIGNATURE_VALUE)
    429 				break;
    430 			if (signature) {
    431 				if (signature != DAIC_SIGNATURE_VALUE) {
    432 					splx(x);
    433 					aprint_error_dev(sc->sc_dev, "microcode signature bad: should be %04x, is %04x\n",
    434 						DAIC_SIGNATURE_VALUE,signature);
    435 					return EIO;
    436 				}
    437 				break;
    438 			}
    439 			splx(x);
    440 			tsleep(&sc->sc_port[i].du_state, 0, "daic protocol init", hz/25);
    441 			x = splnet();
    442 		}
    443 
    444 		/* real check: send an invalid request and wait for an interrupt */
    445 		sc->sc_port[i].du_state = DAIC_STATE_TESTING;
    446 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_RC+off, 0);
    447 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_REQID+off, 0xff);
    448 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_REQ+off, 1);
    449 		splx(x);
    450 		tsleep(&sc->sc_port[i].du_state, 0, "daic irq test", 2*hz);
    451 		x = splnet();
    452 		if (sc->sc_port[i].du_state != DAIC_STATE_RUNNING) {
    453 			splx(x);
    454 			printf("%s: download interrupt test timeout\n",
    455 				device_xname(sc->sc_dev));
    456 			return EIO;
    457 		}
    458 
    459 		/* finish card configuration */
    460 		bus_space_write_4(sc->sc_iot, sc->sc_ioh, DAIC_SWID+off, sw_id);
    461 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_SET_CARD+off, sc->sc_cardtype);
    462 		splx(x);
    463 
    464 		/* assign global d-channel id for that port */
    465 		sc->sc_port[i].du_global_dchan =
    466 			daic_assign(sc, i, DAIC_GLOBALID_DCHAN,
    467 				sizeof parm_global_assign, parm_global_assign);
    468 
    469 		/* send an INDICATE request to get incoming calls on this id */
    470 		x = splnet();
    471 		VOIDREQ(sc, i, DAIC_REQ_INDICATE, sc->sc_port[i].du_global_dchan);
    472 		splx(x);
    473 		tsleep(&sc->sc_port[i].du_request_res, 0, "daic request", 0);
    474 		x = splnet();
    475 		if (sc->sc_port[i].du_request_res != DAIC_RC_OK) {
    476 			aprint_error_dev(sc->sc_dev, "INDICATE request error (0x%02x): %s\n",
    477 				sc->sc_port[i].du_request_res,
    478 				err_codes[sc->sc_port[i].du_request_res & DAIC_RC_ERRMASK]);
    479 			splx(x);
    480 			return EIO;
    481 		}
    482 		splx(x);
    483 	}
    484 	return 0;
    485 }
    486 
    487 /*---------------------------------------------------------------------------*
    488  *	Reset the card, download primary bootstrap, let it check the
    489  *	card and return the cardtype identified by the microcode
    490  *	or -1 if no known card is detected.
    491  *---------------------------------------------------------------------------*/
    492 static int
    493 daic_reset(bus_space_tag_t bus, bus_space_handle_t io, int port, int *memsize)
    494 {
    495 	int i, off = port * DAIC_ISA_MEMSIZE;
    496 	int cardtype, mem, quiet = memsize == NULL;	/* no output if we are only probing */
    497 
    498 	/* clear any pending interrupt */
    499 	bus_space_read_1(bus, io, DAIC_IRQ+off);
    500 	/* reset card */
    501 	bus_space_write_1(bus, io, DAIC_BOOT_SET_RESET+off, 0);
    502 
    503 	/* download primary bootstrap */
    504 	bus_space_set_region_1(bus, io, DAIC_BOOT_START+off, 0, DAIC_BOOT_CODE-DAIC_BOOT_START);
    505 	bus_space_write_region_1(bus, io, DAIC_BOOT_CODE+off, dnload, DAIC_BOOT_END-DAIC_BOOT_CODE+1);
    506 	if (bus_space_read_1(bus, io, DAIC_BOOT_CTRL+off)
    507 	  || bus_space_read_1(bus, io, DAIC_BOOT_EBIT+off)) {
    508 	  	if (!quiet) printf(": shared memory test failed!\n");
    509 	  	return -1;
    510 	}
    511 	/* let card perform memory test */
    512 	bus_space_write_1(bus, io, DAIC_BOOT_CTRL+off, DAIC_TEST_MEM);
    513 	/* and off we go... */
    514 	bus_space_write_1(bus, io, DAIC_BOOT_CLR_RESET+off, 0);
    515 	/* wait for response from bootstrap */
    516 	for (i = 0; i < 15000 && bus_space_read_1(bus, io, DAIC_BOOT_CTRL+off) != DAIC_TEST_RDY; i++)
    517 		DELAY(100);
    518 	if (i >= 15000) {
    519 		if (!quiet) printf(": on board processor test failed!\n");
    520 		return -1;
    521 	}
    522 	if (bus_space_read_1(bus, io, DAIC_BOOT_EBIT+off)) {
    523 		if (!quiet) printf(": on board memory test failed at %x\n",
    524 			bus_space_read_2(bus, io, DAIC_BOOT_ELOC+off));
    525 		return -1;
    526 	}
    527 
    528 	/* fetch info from primary bootstrap code */
    529 	cardtype = bus_space_read_1(bus, io, DAIC_BOOT_CARD+off);
    530 	mem = bus_space_read_1(bus, io, DAIC_BOOT_MSIZE+off) << 4;
    531 	if (memsize)
    532 		*memsize = mem;
    533 
    534 	return cardtype;
    535 }
    536 
    537 /*---------------------------------------------------------------------------*
    538  * Generic diagnostic interface - pass through the microcode data
    539  * without knowing too much about it. This passes a lot work to
    540  * userland, but hey, this is only a diagnostic tool...
    541  *---------------------------------------------------------------------------*/
    542 static int
    543 daic_diagnostic(void *token, struct isdn_diagnostic_request *req)
    544 {
    545 	struct daic_unit *du = token;
    546 	struct daic_softc *sc = du->du_sc;
    547 	int port = du->du_port;
    548 	int off = port * DAIC_ISA_MEMSIZE;
    549 	int rc, cnt;
    550 	int s, err = 0;
    551 
    552 	/* validate parameters */
    553 	if (req->cmd > DAIC_DIAG_MAXCMD) {
    554 		aprint_error_dev(sc->sc_dev, "daic_diagnostic: illegal cmd %d\n",
    555 			req->cmd);
    556 		return EIO;
    557 	}
    558 	if (req->out_param_len > (DAIC_DIAG_DATA_SIZE+1)) {
    559 		aprint_error_dev(sc->sc_dev, "daic_diagnostic: illegal out_param_len %d\n",
    560 			req->out_param_len);
    561 		return EIO;
    562 	}
    563 
    564 	/* XXX - only for debug */
    565 	if (req->cmd == 0x05) {
    566 		/* pass through request from userland */
    567 
    568 		u_int8_t id;
    569 		static u_int8_t parms[] = {
    570 			IEI_CALLID, 0x01, 0x81,
    571 			IEI_CALLINGPN, 7, NUMBER_TYPEPLAN, '9', '8', '9',  '0', '2', '0',
    572 			0x96, 0x01, 0x02, 0x01, 0x00,
    573 			0x00
    574 		};
    575 
    576 		/* create the d-channel task for this call */
    577 		printf("%s: assigning id for pass-through call\n", device_xname(sc->sc_dev));
    578 		id = daic_assign(sc, port, DAIC_GLOBALID_DCHAN, sizeof(parms), parms);
    579 		printf("%s: got id 0x%02x\n", device_xname(sc->sc_dev), id);
    580 
    581 #ifdef DAIC_DEBUG
    582 		daic_dump_request(sc, port, DAIC_REQ_CALL, id, req->in_param_len, req->in_param);
    583 #endif
    584 		daic_request(sc, port, DAIC_REQ_CALL, id, req->in_param_len, req->in_param);
    585 		return 0;
    586 	}
    587 
    588 	/* all these need an output parameter */
    589 	if (req->out_param == NULL)
    590 		return EIO;
    591 
    592 	/* check state and switch to DIAGNOSTIC */
    593 	s = splnet();
    594 	if (sc->sc_port[port].du_state != DAIC_STATE_RUNNING) {
    595 		splx(s);
    596 		return EWOULDBLOCK;
    597 	}
    598 	sc->sc_port[port].du_state = DAIC_STATE_DIAGNOSTIC;
    599 	splx(s);
    600 
    601 	/* set new request */
    602 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_DIAG_REQ+off, req->cmd);
    603 
    604 	/* sorry, no interrupt on completition - have to poll */
    605 	for (cnt = 0; cnt < 3*hz; cnt++) {
    606 		if (bus_space_read_1(sc->sc_iot, sc->sc_ioh, DAIC_DIAG_REQ+off) == 0
    607 		   && bus_space_read_1(sc->sc_iot, sc->sc_ioh, DAIC_DIAG_RC+off) != 0)
    608 			break;
    609 		tsleep(sc, 0, "daic diagnostic", 1);
    610 	}
    611 	rc = bus_space_read_1(sc->sc_iot, sc->sc_ioh, DAIC_DIAG_RC+off);
    612 	if (rc == 0) {
    613 		/* stop request and return error */
    614 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_DIAG_REQ+off, 0);
    615 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_DIAG_RC+off, 0);
    616 		err = EIO;
    617 		goto done;
    618 	}
    619 	/* out param gets rc and all the data */
    620 	if (req->out_param_len >= 2) {
    621 		((u_int8_t*)(req->out_param))[0] = (u_int8_t)rc;
    622 		bus_space_read_region_1(sc->sc_iot, sc->sc_ioh, DAIC_DIAG_DATA+off, ((u_int8_t*)req->out_param)+1, req->out_param_len-1);
    623 	}
    624 	/* acknowledge data */
    625 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_DIAG_RC+off, 0);
    626 
    627 done:	/* back to normal state */
    628 	s = splnet();
    629 	sc->sc_port[port].du_state = DAIC_STATE_RUNNING;
    630 	splx(s);
    631 
    632 	return err;
    633 }
    634 
    635 static void daic_stat(void *port, int channel, bchan_statistics_t *bsp)
    636 {
    637 }
    638 
    639 static const struct isdn_l4_bchannel_functions
    640 daic_l4_driver = {
    641 	daic_bch_config,
    642 	daic_bch_tx_start,
    643 	daic_stat
    644 };
    645 
    646 static const struct isdn_l3_driver_functions
    647 daic_l3_functions =  {
    648 	daic_ret_linktab,
    649 	daic_set_link,
    650 	daic_connect_request,
    651 	daic_connect_response,
    652 	daic_disconnect_request,
    653 	daic_alert_request,
    654 	daic_download,
    655 	daic_diagnostic,
    656 	daic_mgmt_command
    657 };
    658 
    659 /*---------------------------------------------------------------------------*
    660  *	Register one port and attach it to the upper layers
    661  *---------------------------------------------------------------------------*/
    662 static void
    663 daic_register_port(struct daic_softc *sc, int port)
    664 {
    665 	int chan;
    666 	char cardname[80], devname[80];
    667 	struct isdn_l3_driver * l3drv;
    668 
    669 	sc->sc_port[port].du_port = port;
    670 	sc->sc_port[port].du_sc = sc;
    671 
    672 	/* make sure this hardware driver type is known to layer 4 */
    673 	if (sc->sc_cardtype == DAIC_TYPE_QUAD)
    674 		snprintf(devname, sizeof(devname), "%s port %d",
    675 		    device_xname(sc->sc_dev), port);
    676 	else
    677 		strlcpy(devname, device_xname(sc->sc_dev), sizeof(devname));
    678 	snprintf(cardname, sizeof(cardname), "EICON.Diehl %s",
    679 	    cardtypename(sc->sc_cardtype));
    680 	l3drv = isdn_attach_isdnif(
    681 	    devname, cardname, &sc->sc_port[port], &daic_l3_functions,
    682 	    NBCH_BRI);
    683 	sc->sc_port[port].du_l3 = l3drv;
    684 
    685 	/* initialize linktabs for this port */
    686 	for (chan = 0; chan < 2; chan++) {
    687 		isdn_link_t *lt = &sc->sc_con[port*2+chan].isdn_linktab;
    688 		lt->l1token = &sc->sc_port[port];
    689 		lt->channel = chan;
    690 		lt->tx_queue = &sc->sc_con[port*2+chan].tx_queue;
    691 		lt->rx_queue = &sc->sc_con[port*2+chan].rx_queue;
    692 	}
    693 	TAILQ_INIT(&sc->sc_outcalls[port]);
    694 
    695 	isdn_isdnif_ready(l3drv->isdnif);
    696 }
    697 
    698 /*---------------------------------------------------------------------------*
    699  *	return the address of daic drivers linktab
    700  *---------------------------------------------------------------------------*/
    701 static isdn_link_t *
    702 daic_ret_linktab(void *token, int channel)
    703 {
    704 	struct daic_unit *du = token;
    705 	struct daic_softc *sc = du->du_sc;
    706 	int port = du->du_port;
    707 	struct daic_connection *con = &sc->sc_con[port*2+channel];
    708 
    709 	return(&con->isdn_linktab);
    710 }
    711 
    712 /*---------------------------------------------------------------------------*
    713  *	set the driver linktab in the b channel softc
    714  *---------------------------------------------------------------------------*/
    715 static void
    716 daic_set_link(void *token, int channel, const struct isdn_l4_driver_functions *l4_driver, void *l4_inst)
    717 {
    718 	struct daic_unit *du = token;
    719 	struct daic_softc *sc = du->du_sc;
    720 	int port = du->du_port;
    721 	struct daic_connection *con = &sc->sc_con[port*2+channel];
    722 
    723 	con->l4_driver = l4_driver;
    724 	con->l4_driver_softc = l4_inst;
    725 }
    726 
    727 /*---------------------------------------------------------------------------*
    728  *	Send a request to the card.
    729  *---------------------------------------------------------------------------*/
    730 static void
    731 daic_request(
    732 	struct daic_softc *sc,		/* ourself */
    733 	int port, 			/* and the port on this card */
    734 	u_int req, 			/* the request to send */
    735 	u_int id, 			/* id of communication task */
    736 	bus_size_t parmsize, 		/* size of parms including the terminating zero */
    737 	const u_int8_t *parms)		/* pointer to parms to pass */
    738 {
    739 	int off = port*DAIC_ISA_MEMSIZE;
    740 
    741 	/* spin while card is yet busy */
    742 	while (bus_space_read_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_REQ))
    743 		;	/* unlikely to happen with this driver */
    744 
    745 	/* output parameters */
    746 	bus_space_write_region_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_XBUFFER+off, parms, parmsize);
    747 
    748 	/* output request and id */
    749 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_REQID+off, id);
    750 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_REQ+off, req);
    751 }
    752 
    753 /*---------------------------------------------------------------------------*
    754  *	Assign a unique instance id for some communication class
    755  *	on the card. Only one assign request may be running on a
    756  *	port at any time, handle this and return the instance id.
    757  *---------------------------------------------------------------------------*/
    758 static u_int
    759 daic_assign(
    760 	struct daic_softc *sc,	/* our state and port no */
    761 	int port,
    762 	u_int classid,		/* Diehl calls this "global instance id" */
    763 	bus_size_t parmsize, 	/* sizeof parameter arra */
    764 	const u_int8_t *parms)	/* task instance parameters */
    765 {
    766 	static char wchan[] = "daic assign";
    767 	u_int8_t id;
    768 	int x;
    769 
    770 	/* there only may be one assignment running concurrently */
    771 		x = splnet();
    772 	for (;;) {
    773 		if (!(sc->sc_port[port].du_assign & DAIC_ASSIGN_PENDING))
    774 			break;	/* we got it! */
    775 
    776 		/* somebody else is assigning, record state and sleep */
    777 		sc->sc_port[port].du_assign |= DAIC_ASSIGN_SLEEPING;
    778 		tsleep(&sc->sc_port[port].du_assign_res, 0, wchan, 0);
    779 	}
    780 
    781 	/* put parameters and request to card */
    782 	sc->sc_port[port].du_assign |= DAIC_ASSIGN_PENDING;
    783 	daic_request(sc, port, DAIC_REQ_ASSIGN, classid, parmsize, parms);
    784 
    785 	/* wait for completition of assignment by the card */
    786 	tsleep(&sc->sc_port[port].du_assign, 0, wchan, 0);
    787 	id = sc->sc_port[port].du_assign_res;
    788 
    789 	/* have we lost our global dchannel id in the meantime? */
    790 	if (sc->sc_port[port].du_assign & DAIC_ASSIGN_NOGLOBAL) {
    791 		/* start an assign request and let the result
    792 		   be handled by the interrupt handler - we don't
    793 		   have to wait for it here. As the assign lock
    794 		   isn't freed, we don't wake up others... */
    795 		sc->sc_port[port].du_assign &= ~DAIC_ASSIGN_NOGLOBAL;
    796 		sc->sc_port[port].du_assign |= DAIC_ASSIGN_PENDING|DAIC_ASSIGN_GLOBAL;
    797 		daic_request(sc, port, DAIC_REQ_ASSIGN, DAIC_GLOBALID_DCHAN,
    798 			sizeof parm_global_assign, parm_global_assign);
    799 		splx(x);
    800 		return id;
    801 	}
    802 
    803 	/* XXX - review this, can't remember why I did it this complicated */
    804 
    805 	/* unlock and wakup others, if any */
    806 	if (sc->sc_port[port].du_assign & DAIC_ASSIGN_SLEEPING) {
    807 		sc->sc_port[port].du_assign = 0;
    808 		wakeup(&sc->sc_port[port].du_assign_res);
    809 	} else
    810 		sc->sc_port[port].du_assign = 0;
    811 	splx(x);
    812 
    813 	return id;
    814 }
    815 
    816 #ifdef DAIC_DEBUG
    817 /*---------------------------------------------------------------------------*
    818  *	Debug output of request parameters
    819  *---------------------------------------------------------------------------*/
    820 static void
    821 daic_dump_request(struct daic_softc *sc, int port, u_int req, u_int id, bus_size_t parmsize, u_int8_t *parms)
    822 {
    823 	int i;
    824 	printf("%s: request 0x%02x to task id 0x%02x:",
    825 		device_xname(sc->sc_dev), req, id);
    826 	for (i = 0; i < parmsize; i++) {
    827 		if (i % 16 == 0)
    828 			printf("\n%02x:", i);
    829 		printf(" %02x", parms[i]);
    830 	}
    831 	printf("\n");
    832 }
    833 #endif
    834 
    835 /*---------------------------------------------------------------------------*
    836  *	Decode parameters of an INDICATE indication from the card
    837  *	and pass them to layer 4. Called from within an interrupt
    838  *	context.
    839  *---------------------------------------------------------------------------*/
    840 static void
    841 daic_indicate_ind(struct daic_softc *sc, int port)
    842 {
    843 	int offset = port*DAIC_ISA_MEMSIZE;
    844 	int i;
    845 	u_int8_t ie, ielen;
    846 	call_desc_t *cd;
    847 
    848 	/* get and init new calldescriptor */
    849 	cd = reserve_cd();	/* cdid filled in */
    850 	cd->bprot = BPROT_NONE;
    851 	cd->cause_in = 0;
    852 	cd->cause_out = 0;
    853 	cd->dst_telno[0] = '\0';
    854 	cd->src_telno[0] = '\0';
    855 	cd->channelid = CHAN_NO;
    856 	cd->channelexcl = 0;
    857 	cd->cr = -1;
    858 	cd->crflag = CRF_DEST;
    859 	cd->ilt = NULL;		/* reset link tab ptrs */
    860 
    861 	i = 0;
    862 	for (;;) {
    863 		ie = bus_space_read_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_RBUFFER+offset+i);
    864 		if (!ie) break;
    865 		i++;
    866 		if (ie & 0x80) continue;
    867 		ielen = bus_space_read_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_RBUFFER+offset+i);
    868 		i++;
    869 		switch (ie) {
    870 		  case IEI_BEARERCAP:
    871 		  	ie = bus_space_read_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_RBUFFER+offset+i);
    872 		  	if (ie == 0x80 || ie == 0x89 || ie == 0x90)
    873 		  		cd->bprot = BPROT_NONE;
    874 		  	else if (ie == 0x88)
    875 		  		cd->bprot = BPROT_RHDLC;
    876 		  	break;
    877 		  case IEI_CALLINGPN:
    878 		  	{
    879 		  		int off;
    880 			  	ie = bus_space_read_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_RBUFFER+offset+i);
    881 			  	if (ie & 0x80)
    882 			  		off = 1;
    883 			  	else
    884 			  		off = 2;
    885 			  	bus_space_read_region_1(sc->sc_iot, sc->sc_ioh,
    886 					DAIC_COM_RBUFFER+offset+i+off, cd->src_telno,
    887 					ielen - off);
    888 				cd->src_telno[ielen-off+1] = '\0';
    889 			}
    890 		  	break;
    891 		  case IEI_CALLEDPN:
    892 		  	bus_space_read_region_1(sc->sc_iot, sc->sc_ioh,
    893 		  		DAIC_COM_RBUFFER+offset+i+1,
    894 				cd->dst_telno, ielen-1);
    895 			cd->dst_telno[ielen] = '\0';
    896 		  	break;
    897 		  case IEI_CHANNELID:
    898 		  	ie = bus_space_read_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_RBUFFER+offset+i);
    899 		  	if ((ie & 0xf4) != 0x80)
    900 		  		cd->channelid = CHAN_NO;
    901 		  	else {
    902 		  		switch(ie & 0x03) {
    903 		  		  case IE_CHAN_ID_NO:	cd->channelid = CHAN_NO; break;
    904 		  		  case IE_CHAN_ID_B1:	cd->channelid = CHAN_B1; break;
    905 		  		  case IE_CHAN_ID_B2:	cd->channelid = CHAN_B2; break;
    906 		  		  case IE_CHAN_ID_ANY:	cd->channelid = CHAN_ANY; break;
    907 		  		}
    908 		  		cd->channelexcl = (ie & 0x08) >> 3;
    909 		  	}
    910 		}
    911 		i += ielen;
    912 	}
    913 	cd->event = EV_SETUP;
    914 	/* ctrl_desc[cd->controller].bch_state[cd->channelid] = BCH_ST_RSVD; */
    915 
    916 	/* record the dchannel id for this call and the call descriptor */
    917 	sc->sc_con[port*2+cd->channelid].dchan_inst = sc->sc_port[port].du_global_dchan;
    918 	sc->sc_con[port*2+cd->channelid].cdid = cd->cdid;
    919 
    920 	/* this task is busy now, we need a new global dchan id */
    921 	if (sc->sc_port[port].du_assign & DAIC_ASSIGN_PENDING) {
    922 		/* argh - can't assign right now */
    923 		sc->sc_port[port].du_assign |= DAIC_ASSIGN_NOGLOBAL;
    924 	} else {
    925 		/* yeah - can request the assign right away, but let the
    926 		   interrupt handler autohandle the result */
    927 		sc->sc_port[port].du_assign |= DAIC_ASSIGN_PENDING|DAIC_ASSIGN_GLOBAL;
    928 		daic_request(sc, port, DAIC_REQ_ASSIGN, DAIC_GLOBALID_DCHAN,
    929 			sizeof parm_global_assign, parm_global_assign);
    930 	}
    931 
    932 	if (cd->bprot == BPROT_NONE)
    933 		printf("\nincoming voice call from \"%s\" to \"%s\"\n",
    934 			cd->src_telno, cd->dst_telno);
    935 	else
    936 		printf("\nincoming data call from \"%s\" to \"%s\"\n",
    937 			cd->src_telno, cd->dst_telno);
    938 
    939 	/* hand up call to layer 4 */
    940 	i4b_l4_connect_ind(cd);
    941 }
    942 
    943 /*---------------------------------------------------------------------------*
    944  *	Layer 4 request a call setup
    945  *---------------------------------------------------------------------------*/
    946 static void
    947 daic_connect_request(struct call_desc *cd)
    948 {
    949 	u_int8_t id, cpn[TELNO_MAX+4], parms[TELNO_MAX+16], *p;
    950 	struct daic_unit *du = cd->ilt->l1token;
    951 	struct daic_softc *sc = du->du_sc;
    952 	int port = du->du_port;
    953 	int x, len;
    954 	struct outcallentry *assoc;
    955 
    956 	/* to associate the cdid with the communication task
    957 	   we are going to create for this outgoing call,
    958 	   we maintain a queue of pending outgoing calls.
    959 	   As soon as a SETUP response is received, we move
    960 	   the association to the allocated b-channel. */
    961 
    962 	/* configure d-channel task parameters */
    963 	p = parms;
    964 	*p++ = IEI_CALLID; *p++ = 0x01;
    965 	if (cd->bprot == BPROT_NONE) {
    966 		*p++ = 0x82;
    967 	} else if (cd->bprot == BPROT_RHDLC) {
    968 		*p++ = 0x85;
    969 	} else {
    970 		printf("%s: daic_connect_request for unknown bchan protocol 0x%x\n",
    971 			device_xname(sc->sc_dev), cd->bprot);
    972 		return;
    973 	}
    974 	if (cd->src_telno[0]) {
    975 		*p++ = IEI_CALLINGPN;
    976 		*p++ = strlen(cd->src_telno)+1;
    977 		*p++ = NUMBER_TYPEPLAN;
    978 		strcpy(p, cd->src_telno);
    979 		p += strlen(p);
    980 	}
    981 	if (cd->channelid == CHAN_B1 || cd->channelid == CHAN_B2) {
    982 		*p++ = IEI_CHANNELID;
    983 		*p++ = 0x01;
    984 		*p++ = 0x81 + cd->channelid;
    985 	}
    986 	if (cd->bprot == BPROT_NONE) {
    987 		*p++ = 0x96;	/* shift6 */
    988 		*p++ = 0x01;	/* SIN */
    989 		*p++ = 0x02;	/* len */
    990 		*p++ = 0x01;	/* Telephony */
    991 		*p++ = 0x00;	/* add.info */
    992 	}
    993 	*p++ = 0;
    994 
    995 	/* create the d-channel task for this call */
    996 	id = daic_assign(sc, port, DAIC_GLOBALID_DCHAN, p - parms, parms);
    997 
    998 	/* map it to the call descriptor id */
    999 	assoc = malloc(sizeof(struct outcallentry), M_DEVBUF, 0);
   1000 	assoc->cdid = cd->cdid;
   1001 	assoc->dchan_id = id;
   1002 	x = splnet();
   1003 	TAILQ_INSERT_TAIL(&sc->sc_outcalls[port], assoc, queue);
   1004 
   1005 	/* send a call request */
   1006 	len = strlen(cd->dst_telno);
   1007 	cpn[0] = IEI_CALLEDPN;
   1008 	cpn[1] = len+1;
   1009 	cpn[2] = NUMBER_TYPEPLAN;
   1010 	strcpy(cpn+3, cd->dst_telno);
   1011 #ifdef DAIC_DEBUG
   1012 	daic_dump_request(sc, port, DAIC_REQ_CALL, id, len+4, cpn);
   1013 #endif
   1014 	daic_request(sc, port, DAIC_REQ_CALL, id, len+4, cpn);
   1015 	splx(x);
   1016 	tsleep(assoc, 0, "daic call", 0);
   1017 	if (assoc->rc != DAIC_RC_OK) {
   1018 		aprint_error_dev(sc->sc_dev, "call request failed, error 0x%02x: %s\n",
   1019 			assoc->rc & DAIC_RC_ERRMASK,
   1020 			err_codes[assoc->rc & DAIC_RC_ERRMASK]);
   1021 	}
   1022 }
   1023 
   1024 /*---------------------------------------------------------------------------*
   1025  *	TODO:
   1026  *---------------------------------------------------------------------------*/
   1027 static void daic_connect_response(struct call_desc *cd, int response, int cause)
   1028 {
   1029 }
   1030 
   1031 /*---------------------------------------------------------------------------*
   1032  *	TODO:
   1033  *---------------------------------------------------------------------------*/
   1034 static void daic_disconnect_request(struct call_desc *cd, int cause)
   1035 {
   1036 }
   1037 
   1038 /*---------------------------------------------------------------------------*
   1039  *	TODO:
   1040  *---------------------------------------------------------------------------*/
   1041 static void daic_bch_config(void *token, int channel, int bprot, int updown)
   1042 {
   1043 	printf("daic: bch_config\n");
   1044 }
   1045 
   1046 /*---------------------------------------------------------------------------*
   1047  *	TODO:
   1048  *---------------------------------------------------------------------------*/
   1049 static void daic_bch_tx_start(void *token, int channel)
   1050 {
   1051 	printf("daic: bch_tx_start\n");
   1052 }
   1053 
   1054 /*---------------------------------------------------------------------------*
   1055  *	TODO:
   1056  *---------------------------------------------------------------------------*/
   1057 static void
   1058 daic_mgmt_command(struct isdn_l3_driver *drv, int cmd, void *parm)
   1059 {
   1060 }
   1061 
   1062 /*---------------------------------------------------------------------------*
   1063  *	TODO:
   1064  *---------------------------------------------------------------------------*/
   1065 static void
   1066 daic_alert_request(struct call_desc *cd)
   1067 {
   1068 }
   1069 
   1070