Bring the daic driver into the new ISDN world order.

Enable active card support in the ISDN subsystem. (Had been disabled since
it couldn't be tested before.)
This commit is contained in:
martin 2002-03-22 09:54:15 +00:00
parent 131f75b62b
commit 9cea4a0ab0
6 changed files with 211 additions and 190 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997,1999,2001 Martin Husemann <martin@duskware.de>
* Copyright (c) 1997-2002 Martin Husemann <martin@duskware.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: daic.c,v 1.6 2001/11/15 09:48:06 lukem Exp $");
__KERNEL_RCSID(0, "$NetBSD: daic.c,v 1.7 2002/03/22 09:54:15 martin Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -67,24 +67,27 @@ struct cfdriver daic_cd = {
/* local function prototypes */
static char * cardtypename __P((int cardtype));
static int daic_download __P((int unit, int portcount, struct isdn_dr_prot *data));
static int daic_diagnostic __P((int unit, struct isdn_diagnostic_request *req));
static int daic_download __P((void *, int portcount, struct isdn_dr_prot *data));
static int daic_diagnostic __P((void *, struct isdn_diagnostic_request *req));
static void daic_connect_request(unsigned int);
static void daic_connect_response(unsigned int, int, int);
static void daic_disconnect_request(unsigned int, int);
static int daic_reset __P((bus_space_tag_t bus, bus_space_handle_t io, int port, int quiet));
static int daic_handle_intr __P((struct daic *sc, int port));
static int daic_register_port(struct daic *sc, int port);
static void daic_request(struct daic *sc, int port, u_int req, u_int id, bus_size_t parmsize, const u_int8_t *parms);
static u_int daic_assign(struct daic *sc, int port, u_int instance, bus_size_t parmsize, const u_int8_t *parms);
static void daic_indicate_ind(struct daic *sc, int port);
static void daic_bch_config(int unit, int channel, int bprot, int updown);
static void daic_bch_tx_start(int unit, int channel);
static void daic_set_linktab(int unit, int channel, drvr_link_t *dlt);
static isdn_link_t *daic_ret_linktab(int unit, int channel);
static int daic_reset __P((bus_space_tag_t bus, bus_space_handle_t io, int port, int *memsize));
static int daic_handle_intr __P((struct daic_softc *sc, int port));
static int daic_register_port(struct daic_softc *sc, int port);
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);
static u_int daic_assign(struct daic_softc *sc, int port, u_int instance, bus_size_t parmsize, const u_int8_t *parms);
static void daic_indicate_ind(struct daic_softc *sc, int port);
static void daic_bch_config(void *, int channel, int bprot, int updown);
static void daic_bch_tx_start(void *, int channel);
static void daic_set_link(void *softc, int channel,
const struct isdn_l4_driver_functions *l4_driver, void *l4_inst );
static void daic_mgmt_command(int bri, int cmd, void *parm);
static isdn_link_t *daic_ret_linktab(void *softc, int channel);
#ifdef DAIC_DEBUG
static void daic_dump_request(struct daic *sc, int port, u_int req, u_int id, bus_size_t parmsize, u_int8_t *parms);
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);
#endif
/* static data */
@ -122,16 +125,6 @@ static u_int8_t parm_global_assign[] = {
0x00
};
/*---------------------------------------------------------------------------*
* structure mapping one isdn port (a 'unit') to an sc/port pair
*---------------------------------------------------------------------------*/
struct daic_unit_map {
struct daic *sc;
int port;
};
static struct daic_unit_map *unit_map = NULL;
static int next_unit = 0;
/*---------------------------------------------------------------------------*
* Return the name of a card with given cardtype
*---------------------------------------------------------------------------*/
@ -155,7 +148,7 @@ daic_probe(bus, io)
bus_space_tag_t bus;
bus_space_handle_t io;
{
return daic_reset(bus, io, 0, 1);
return (daic_reset(bus, io, 0, NULL) > 0);
}
/*---------------------------------------------------------------------------*
@ -164,25 +157,27 @@ daic_probe(bus, io)
void
daic_attach(self, sc)
struct device *self;
struct daic *sc;
struct daic_softc *sc;
{
int i, num_ports;
num_ports = sc->sc_cardtype == DAIC_TYPE_QUAD ? 4 : 1;
int i, num_ports, memsize = 0;
/* init sc */
memset(sc->sc_assign_res, 0, sizeof sc->sc_assign_res);
memset(sc->sc_assign, 0, sizeof sc->sc_assign);
for (i = 0; i < num_ports; i++) {
sc->sc_state[i] = DAIC_STATE_COLD;
}
memset(sc->sc_port, 0, sizeof sc->sc_port);
memset(sc->sc_con, 0, sizeof sc->sc_con);
sc->sc_cardtype = -1;
/* init card */
sc->sc_cardtype = daic_reset(sc->sc_iot, sc->sc_ioh, 0, 0);
if (sc->sc_cardtype >= 0)
for (i = 0; i < num_ports; i++)
sc->sc_state[i] = DAIC_STATE_DOWNLOAD;
sc->sc_cardtype = daic_reset(sc->sc_iot, sc->sc_ioh, 0, &memsize);
if (sc->sc_cardtype == 0) {
printf(": unknown card, can not attach.\n");
return;
}
printf(": EICON.Diehl %s\n", cardtypename(sc->sc_cardtype));
printf("%s: %d kByte on board RAM\n", sc->sc_dev.dv_xname, memsize);
num_ports = sc->sc_cardtype == DAIC_TYPE_QUAD ? 4 : 1;
for (i = 0; i < num_ports; i++)
sc->sc_port[i].du_state = DAIC_STATE_DOWNLOAD;
/* register all ports this card has */
for (i = 0; i < num_ports; i++)
@ -194,10 +189,11 @@ daic_attach(self, sc)
*---------------------------------------------------------------------------*/
static int
daic_handle_intr(sc, port)
struct daic *sc;
struct daic_softc *sc;
int port;
{
struct outcallentry *assoc;
struct daic_unit * du = &sc->sc_port[port];
int off = port * DAIC_ISA_MEMSIZE;
u_int8_t rc, rcid;
u_int8_t ind, indid;
@ -208,10 +204,10 @@ daic_handle_intr(sc, port)
return 0; /* nope, exit */
/* is the card in running state yet? */
if (sc->sc_state[port] == DAIC_STATE_TESTING) {
if (du->du_state == DAIC_STATE_TESTING) {
bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_RC+off, 0);
sc->sc_state[port] = DAIC_STATE_RUNNING;
wakeup(&sc->sc_state[port]);
du->du_state = DAIC_STATE_RUNNING;
wakeup(du);
goto done;
}
@ -223,37 +219,37 @@ daic_handle_intr(sc, port)
/* maybe an assign answer (positive or negative) */
if (rc == DAIC_RC_ASSIGN_OK) {
sc->sc_assign_res[port] = rcid;
du->du_assign_res = rcid;
/* assing rc is special, we tell the card it's done */
bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_REQ+off, 0);
bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_RC+off, 0);
/* we handle some types of assigns to global dchannel id's automaticaly */
if (sc->sc_assign[port] & DAIC_ASSIGN_GLOBAL) {
sc->sc_global_dchan[port] = rcid;
sc->sc_assign[port] &= ~(DAIC_ASSIGN_GLOBAL|DAIC_ASSIGN_PENDING);
if (sc->sc_assign[port] & DAIC_ASSIGN_SLEEPING) {
sc->sc_assign[port] = 0;
wakeup(&sc->sc_assign_res[port]);
if (du->du_assign & DAIC_ASSIGN_GLOBAL) {
du->du_global_dchan = rcid;
du->du_assign &= ~(DAIC_ASSIGN_GLOBAL|DAIC_ASSIGN_PENDING);
if (du->du_assign & DAIC_ASSIGN_SLEEPING) {
du->du_assign = 0;
wakeup(&du->du_assign_res);
}
} else {
wakeup(&sc->sc_assign[port]);
wakeup(&du->du_assign);
}
goto check_ind;
} else if ((rc & DAIC_RC_ASSIGN_MASK) == DAIC_RC_ASSIGN_RC) {
printf("%s: assign request failed, error 0x%02x: %s\n",
sc->sc_dev.dv_xname, rc & DAIC_RC_ERRMASK,
err_codes[rc & DAIC_RC_ERRMASK]);
sc->sc_assign_res[port] = 0;
du->du_assign_res = 0;
/* assing rc is special, we tell the card it's done */
bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_REQ+off, 0);
bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_RC+off, 0);
/* that's it */
wakeup(&sc->sc_assign[port]);
wakeup(&du->du_assign);
goto check_ind;
}
if (rcid == sc->sc_global_dchan[port]) {
sc->sc_request_res[port] = rc;
wakeup(&sc->sc_request_res[port]);
if (rcid == du->du_global_dchan) {
du->du_request_res = rc;
wakeup(&du->du_request_res);
goto req_done;
}
for (chan = 0; chan < 2; chan++) {
@ -267,7 +263,7 @@ daic_handle_intr(sc, port)
goto req_done;
}
}
for (assoc = sc->sc_outcalls[port].tqh_first; assoc; assoc = assoc->queue.tqe_next) {
TAILQ_FOREACH(assoc, &sc->sc_outcalls[port], queue) {
if (rcid == assoc->dchan_id) {
assoc->rc = rc;
wakeup(assoc);
@ -290,7 +286,7 @@ check_ind:
if (!ind) goto done;
/* incoming call routed to global dchannel task? */
if (indid == sc->sc_global_dchan[port]) {
if (indid == du->du_global_dchan) {
if (ind == DAIC_IND_INDICATE) {
daic_indicate_ind(sc, port);
} else if (ind == DAIC_IND_INFO) {
@ -327,7 +323,7 @@ check_ind:
}
}
for (assoc = sc->sc_outcalls[port].tqh_first; assoc; assoc = assoc->queue.tqe_next) {
TAILQ_FOREACH(assoc, &sc->sc_outcalls[port], queue) {
if (indid == assoc->dchan_id) {
printf("%s: D-Channel indication 0x%02x for outgoing call with cdid %d\n",
sc->sc_dev.dv_xname, ind, assoc->cdid);
@ -353,7 +349,7 @@ done:
*---------------------------------------------------------------------------*/
int
daic_intr(sc)
struct daic *sc;
struct daic_softc *sc;
{
int handeld = 0;
if (sc->sc_cardtype == DAIC_TYPE_QUAD) {
@ -369,11 +365,13 @@ daic_intr(sc)
* Download primary protocol microcode to on-board processor
*---------------------------------------------------------------------------*/
static int
daic_download(unit, count, data)
int unit, count;
daic_download(token, count, data)
void *token;
int count;
struct isdn_dr_prot *data;
{
struct daic *sc = unit_map[unit].sc;
struct daic_unit *du = token;
struct daic_softc *sc = du->du_sc;
int i;
if (sc->sc_cardtype != DAIC_TYPE_QUAD)
@ -445,19 +443,19 @@ daic_download(unit, count, data)
break;
}
splx(x);
tsleep(&sc->sc_state[i], 0, "daic protocol init", hz/25);
tsleep(&sc->sc_port[i].du_state, 0, "daic protocol init", hz/25);
x = splnet();
}
/* real check: send an invalid request and wait for an interrupt */
sc->sc_state[i] = DAIC_STATE_TESTING;
sc->sc_port[i].du_state = DAIC_STATE_TESTING;
bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_RC+off, 0);
bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_REQID+off, 0xff);
bus_space_write_1(sc->sc_iot, sc->sc_ioh, DAIC_COM_REQ+off, 1);
splx(x);
tsleep(&sc->sc_state[i], 0, "daic irq test", 2*hz);
tsleep(&sc->sc_port[i].du_state, 0, "daic irq test", 2*hz);
x = splnet();
if (sc->sc_state[i] != DAIC_STATE_RUNNING) {
if (sc->sc_port[i].du_state != DAIC_STATE_RUNNING) {
splx(x);
printf("%s: download interrupt test timeout\n",
sc->sc_dev.dv_xname);
@ -470,20 +468,20 @@ daic_download(unit, count, data)
splx(x);
/* assign global d-channel id for that port */
sc->sc_global_dchan[i] =
sc->sc_port[i].du_global_dchan =
daic_assign(sc, i, DAIC_GLOBALID_DCHAN,
sizeof parm_global_assign, parm_global_assign);
/* send an INDICATE request to get incoming calls on this id */
x = splnet();
VOIDREQ(sc, i, DAIC_REQ_INDICATE, sc->sc_global_dchan[i]);
VOIDREQ(sc, i, DAIC_REQ_INDICATE, sc->sc_port[i].du_global_dchan);
splx(x);
tsleep(&sc->sc_request_res[i], 0, "daic request", 0);
tsleep(&sc->sc_port[i].du_request_res, 0, "daic request", 0);
x = splnet();
if (sc->sc_request_res[i] != DAIC_RC_OK) {
if (sc->sc_port[i].du_request_res != DAIC_RC_OK) {
printf("%s: INDICATE request error (0x%02x): %s\n",
sc->sc_dev.dv_xname, sc->sc_request_res[i],
err_codes[sc->sc_request_res[i] & DAIC_RC_ERRMASK]);
sc->sc_dev.dv_xname, sc->sc_port[i].du_request_res,
err_codes[sc->sc_port[i].du_request_res & DAIC_RC_ERRMASK]);
splx(x);
return EIO;
}
@ -498,13 +496,14 @@ daic_download(unit, count, data)
* or -1 if no known card is detected.
*---------------------------------------------------------------------------*/
static int
daic_reset(bus, io, port, quiet)
daic_reset(bus, io, port, memsize)
bus_space_tag_t bus;
bus_space_handle_t io;
int port, quiet;
int port;
int *memsize;
{
int memsize = 0, cardtype = -1;
int i, off = port * DAIC_ISA_MEMSIZE;
int cardtype, mem, quiet = memsize == NULL; /* no output if we are only probing */
/* clear any pending interrupt */
bus_space_read_1(bus, io, DAIC_IRQ+off);
@ -538,10 +537,9 @@ daic_reset(bus, io, port, quiet)
/* fetch info from primary bootstrap code */
cardtype = bus_space_read_1(bus, io, DAIC_BOOT_CARD+off);
memsize = bus_space_read_1(bus, io, DAIC_BOOT_MSIZE+off);
/* done, output info */
if (!quiet) printf(": EICON.Diehl-%s (%d kB RAM)\n", cardtypename(cardtype), memsize << 4);
mem = bus_space_read_1(bus, io, DAIC_BOOT_MSIZE+off) << 4;
if (memsize)
*memsize = mem;
return cardtype;
}
@ -552,12 +550,13 @@ daic_reset(bus, io, port, quiet)
* userland, but hey, this is only a diagnostic tool...
*---------------------------------------------------------------------------*/
static int
daic_diagnostic(unit, req)
int unit;
daic_diagnostic(token, req)
void *token;
struct isdn_diagnostic_request *req;
{
struct daic *sc = unit_map[unit].sc;
int port = unit_map[unit].port;
struct daic_unit *du = token;
struct daic_softc *sc = du->du_sc;
int port = du->du_port;
int off = port * DAIC_ISA_MEMSIZE;
int rc, cnt;
int s, err = 0;
@ -604,11 +603,11 @@ daic_diagnostic(unit, req)
/* check state and switch to DIAGNOSTIC */
s = splnet();
if (sc->sc_state[port] != DAIC_STATE_RUNNING) {
if (sc->sc_port[port].du_state != DAIC_STATE_RUNNING) {
splx(s);
return EWOULDBLOCK;
}
sc->sc_state[port] = DAIC_STATE_DIAGNOSTIC;
sc->sc_port[port].du_state = DAIC_STATE_DIAGNOSTIC;
splx(s);
/* set new request */
@ -639,48 +638,53 @@ daic_diagnostic(unit, req)
done: /* back to normal state */
s = splnet();
sc->sc_state[port] = DAIC_STATE_RUNNING;
sc->sc_port[port].du_state = DAIC_STATE_RUNNING;
splx(s);
return err;
}
static void daic_stat(void *port, int channel, bchan_statistics_t *bsp)
{
}
static const struct isdn_l4_bchannel_functions
daic_l4_driver = {
daic_bch_config,
daic_bch_tx_start,
daic_stat
};
/*---------------------------------------------------------------------------*
* Register one port and attach it to the upper layers
*---------------------------------------------------------------------------*/
static int
daic_register_port(struct daic *sc, int port)
daic_register_port(struct daic_softc *sc, int port)
{
int chan;
int unit = next_unit++;
/* XXX */
static int next_bri = 0;
int bri = next_bri++;
sc->sc_port[port].du_bri = bri;
sc->sc_port[port].du_port = port;
sc->sc_port[port].du_sc = sc;
/* make sure this hardware driver type is known to layer 4 */
ctrl_types[CTRL_DAIC].set_linktab = daic_set_linktab;
ctrl_types[CTRL_DAIC].set_l4_driver = daic_set_link;
ctrl_types[CTRL_DAIC].get_linktab = daic_ret_linktab;
/* attach a new unit */
if (unit_map) {
struct daic_unit_map *temp = malloc(next_unit*sizeof(struct daic_unit_map), 0, M_DEVBUF);
memcpy(temp, unit_map, unit*sizeof(struct daic_unit_map));
free(unit_map, M_DEVBUF);
unit_map = temp;
} else {
unit_map = malloc(sizeof(struct daic_unit_map), 0, M_DEVBUF);
next_unit = 0;
}
next_unit++;
unit_map[unit].sc = sc;
unit_map[unit].port = port;
/* setup function pointers */
ctrl_desc[nctrl].N_CONNECT_REQUEST = daic_connect_request;
ctrl_desc[nctrl].N_CONNECT_RESPONSE = daic_connect_response;
ctrl_desc[nctrl].N_DISCONNECT_REQUEST = daic_disconnect_request;
ctrl_desc[nctrl].N_DOWNLOAD = daic_download;
ctrl_desc[nctrl].N_DIAGNOSTICS = daic_diagnostic;
ctrl_desc[nctrl].N_MGMT_COMMAND = daic_mgmt_command;
/* init type and unit */
ctrl_desc[nctrl].unit = unit;
ctrl_desc[nctrl].l1_token = &sc->sc_port[port];
ctrl_desc[nctrl].bri = bri;
ctrl_desc[nctrl].ctrl_type = CTRL_DAIC;
ctrl_desc[nctrl].card_type = sc->sc_cardtype + 1;
@ -688,31 +692,30 @@ daic_register_port(struct daic *sc, int port)
ctrl_desc[nctrl].dl_est = DL_DOWN;
ctrl_desc[nctrl].bch_state[0] = BCH_ST_FREE;
ctrl_desc[nctrl].bch_state[1] = BCH_ST_FREE;
sc->sc_ctrl[port] = nctrl++;
nctrl++;
/* initialize linktabs for this port */
for (chan = 0; chan < 2; chan++) {
isdn_link_t *lt = &sc->sc_con[port*2+chan].isdn_linktab;
lt->unit = unit;
lt->l1token = &sc->sc_port[port];
lt->channel = chan;
lt->bch_config = daic_bch_config;
lt->bch_tx_start = daic_bch_tx_start;
lt->tx_queue = &sc->sc_con[port*2+chan].tx_queue;
lt->rx_queue = &sc->sc_con[port*2+chan].rx_queue;
}
TAILQ_INIT(&sc->sc_outcalls[port]);
return unit;
return bri;
}
/*---------------------------------------------------------------------------*
* return the address of daic drivers linktab
*---------------------------------------------------------------------------*/
static isdn_link_t *
daic_ret_linktab(int unit, int channel)
daic_ret_linktab(void *token, int channel)
{
struct daic *sc = unit_map[unit].sc;
int port = unit_map[unit].port;
struct daic_unit *du = token;
struct daic_softc *sc = du->du_sc;
int port = du->du_port;
struct daic_connection *con = &sc->sc_con[port*2+channel];
return(&con->isdn_linktab);
@ -722,13 +725,15 @@ daic_ret_linktab(int unit, int channel)
* set the driver linktab in the b channel softc
*---------------------------------------------------------------------------*/
static void
daic_set_linktab(int unit, int channel, drvr_link_t *dlt)
daic_set_link(void *token, int channel, const struct isdn_l4_driver_functions *l4_driver, void *l4_inst)
{
struct daic *sc = unit_map[unit].sc;
int port = unit_map[unit].port;
struct daic_unit *du = token;
struct daic_softc *sc = du->du_sc;
int port = du->du_port;
struct daic_connection *con = &sc->sc_con[port*2+channel];
con->drvr_linktab = dlt;
con->l4_driver = l4_driver;
con->l4_driver_softc = l4_inst;
}
/*---------------------------------------------------------------------------*
@ -736,7 +741,7 @@ daic_set_linktab(int unit, int channel, drvr_link_t *dlt)
*---------------------------------------------------------------------------*/
static void
daic_request(
struct daic *sc, /* ourself */
struct daic_softc *sc, /* ourself */
int port, /* and the port on this card */
u_int req, /* the request to send */
u_int id, /* id of communication task */
@ -764,7 +769,7 @@ daic_request(
*---------------------------------------------------------------------------*/
static u_int
daic_assign(
struct daic *sc, /* our state and port no */
struct daic_softc *sc, /* our state and port no */
int port,
u_int classid, /* Diehl calls this "global instance id" */
bus_size_t parmsize, /* sizeof paramter arra */
@ -777,30 +782,30 @@ daic_assign(
/* there only may be one assignment running concurrently */
x = splnet();
for (;;) {
if (!(sc->sc_assign[port] & DAIC_ASSIGN_PENDING))
if (!(sc->sc_port[port].du_assign & DAIC_ASSIGN_PENDING))
break; /* we got it! */
/* somebody else is assigning, record state and sleep */
sc->sc_assign[port] |= DAIC_ASSIGN_SLEEPING;
tsleep(&sc->sc_assign_res[port], 0, wchan, 0);
sc->sc_port[port].du_assign |= DAIC_ASSIGN_SLEEPING;
tsleep(&sc->sc_port[port].du_assign_res, 0, wchan, 0);
}
/* put parameters and request to card */
sc->sc_assign[port] |= DAIC_ASSIGN_PENDING;
sc->sc_port[port].du_assign |= DAIC_ASSIGN_PENDING;
daic_request(sc, port, DAIC_REQ_ASSIGN, classid, parmsize, parms);
/* wait for completition of assignment by the card */
tsleep(&sc->sc_assign[port], 0, wchan, 0);
id = sc->sc_assign_res[port];
tsleep(&sc->sc_port[port].du_assign, 0, wchan, 0);
id = sc->sc_port[port].du_assign_res;
/* have we lost our global dchannel id in the meantime? */
if (sc->sc_assign[port] & DAIC_ASSIGN_NOGLOBAL) {
if (sc->sc_port[port].du_assign & DAIC_ASSIGN_NOGLOBAL) {
/* start an assign request and let the result
be handled by the interrupt handler - we don't
have to wait for it here. As the assign lock
isn't freed, we don't wake up others... */
sc->sc_assign[port] &= ~DAIC_ASSIGN_NOGLOBAL;
sc->sc_assign[port] |= DAIC_ASSIGN_PENDING|DAIC_ASSIGN_GLOBAL;
sc->sc_port[port].du_assign &= ~DAIC_ASSIGN_NOGLOBAL;
sc->sc_port[port].du_assign |= DAIC_ASSIGN_PENDING|DAIC_ASSIGN_GLOBAL;
daic_request(sc, port, DAIC_REQ_ASSIGN, DAIC_GLOBALID_DCHAN,
sizeof parm_global_assign, parm_global_assign);
splx(x);
@ -810,11 +815,11 @@ daic_assign(
/* XXX - review this, can't remember why I did it this complicated */
/* unlock and wakup others, if any */
if (sc->sc_assign[port] & DAIC_ASSIGN_SLEEPING) {
sc->sc_assign[port] = 0;
wakeup(&sc->sc_assign_res[port]);
if (sc->sc_port[port].du_assign & DAIC_ASSIGN_SLEEPING) {
sc->sc_port[port].du_assign = 0;
wakeup(&sc->sc_port[port].du_assign_res);
} else
sc->sc_assign[port] = 0;
sc->sc_port[port].du_assign = 0;
splx(x);
return id;
@ -825,7 +830,7 @@ daic_assign(
* Debug output of request parameters
*---------------------------------------------------------------------------*/
static void
daic_dump_request(struct daic *sc, int port, u_int req, u_int id, bus_size_t parmsize, u_int8_t *parms)
daic_dump_request(struct daic_softc *sc, int port, u_int req, u_int id, bus_size_t parmsize, u_int8_t *parms)
{
int i;
printf("%s: request 0x%02x to task id 0x%02x:",
@ -845,7 +850,7 @@ daic_dump_request(struct daic *sc, int port, u_int req, u_int id, bus_size_t par
* context.
*---------------------------------------------------------------------------*/
static void
daic_indicate_ind(struct daic *sc, int port)
daic_indicate_ind(struct daic_softc *sc, int port)
{
int offset = port*DAIC_ISA_MEMSIZE;
int i;
@ -854,7 +859,6 @@ daic_indicate_ind(struct daic *sc, int port)
/* get and init new calldescriptor */
cd = reserve_cd(); /* cdid filled in */
cd->controller = sc->sc_ctrl[port];
cd->bprot = BPROT_NONE;
cd->cause_in = 0;
cd->cause_out = 0;
@ -865,7 +869,6 @@ daic_indicate_ind(struct daic *sc, int port)
cd->cr = -1;
cd->crflag = CRF_DEST;
cd->ilt = NULL; /* reset link tab ptrs */
cd->dlt = NULL;
i = 0;
for (;;) {
@ -920,20 +923,20 @@ daic_indicate_ind(struct daic *sc, int port)
i += ielen;
}
cd->event = EV_SETUP;
ctrl_desc[cd->controller].bch_state[cd->channelid] = BCH_ST_RSVD;
/* ctrl_desc[cd->controller].bch_state[cd->channelid] = BCH_ST_RSVD; */
/* record the dchannel id for this call and the call descriptor */
sc->sc_con[port*2+cd->channelid].dchan_inst = sc->sc_global_dchan[port];
sc->sc_con[port*2+cd->channelid].dchan_inst = sc->sc_port[port].du_global_dchan;
sc->sc_con[port*2+cd->channelid].cdid = cd->cdid;
/* this task is busy now, we need a new global dchan id */
if (sc->sc_assign[port] & DAIC_ASSIGN_PENDING) {
if (sc->sc_port[port].du_assign & DAIC_ASSIGN_PENDING) {
/* argh - can't assign right now */
sc->sc_assign[port] |= DAIC_ASSIGN_NOGLOBAL;
sc->sc_port[port].du_assign |= DAIC_ASSIGN_NOGLOBAL;
} else {
/* yeah - can request the assign right away, but let the
interrupt handler autohandle the result */
sc->sc_assign[port] |= DAIC_ASSIGN_PENDING|DAIC_ASSIGN_GLOBAL;
sc->sc_port[port].du_assign |= DAIC_ASSIGN_PENDING|DAIC_ASSIGN_GLOBAL;
daic_request(sc, port, DAIC_REQ_ASSIGN, DAIC_GLOBALID_DCHAN,
sizeof parm_global_assign, parm_global_assign);
}
@ -957,8 +960,9 @@ daic_connect_request(unsigned int cdid)
{
u_int8_t id, cpn[TELNO_MAX+4], parms[TELNO_MAX+16], *p;
call_desc_t *cd = cd_by_cdid(cdid);
struct daic *sc = unit_map[cd->driver_unit].sc;
int port = unit_map[cd->driver_unit].port;
struct daic_unit *du = cd->ilt->l1token;
struct daic_softc *sc = du->du_sc;
int port = du->du_port;
int x, len;
struct outcallentry *assoc;
@ -1047,7 +1051,7 @@ static void daic_disconnect_request(unsigned int cdid, int cause)
/*---------------------------------------------------------------------------*
* TODO:
*---------------------------------------------------------------------------*/
static void daic_bch_config(int unit, int channel, int bprot, int updown)
static void daic_bch_config(void *token, int channel, int bprot, int updown)
{
printf("daic: bch_config\n");
}
@ -1055,8 +1059,15 @@ static void daic_bch_config(int unit, int channel, int bprot, int updown)
/*---------------------------------------------------------------------------*
* TODO:
*---------------------------------------------------------------------------*/
static void daic_bch_tx_start(int unit, int channel)
static void daic_bch_tx_start(void *token, int channel)
{
printf("daic: bch_tx_start\n");
}
/*---------------------------------------------------------------------------*
* TODO:
*---------------------------------------------------------------------------*/
static void
daic_mgmt_command(int bri, int cmd, void *parm)
{
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997,2001 Martin Husemann <martin@duskware.de>
* Copyright (c) 1997-2002 Martin Husemann <martin@duskware.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -46,16 +46,45 @@ struct daic_connection {
struct ifqueue tx_queue; /* outgoing data */
struct ifqueue rx_queue; /* incoming data */
isdn_link_t isdn_linktab; /* description of ourself */
drvr_link_t *drvr_linktab; /* application driver using us */
const struct isdn_l4_driver_functions
*l4_driver; /* layer 4 driver */
void *l4_driver_softc; /* layer 4 driver instance */
u_int8_t dchan_inst; /* d-channel instance */
u_int8_t dchan_rc; /* return code for dchannel requests */
u_int8_t bchan_inst; /* b-channel instance */
u_int8_t bchan_rc; /* return code for bchannel requests */
};
/*
* One BRI as exposed to the upper layers, with all the internal management
* information we need for it. A pointer to this is passed as the driver
* token.
*/
struct daic_unit {
struct daic_softc *du_sc; /* pointer to softc */
int du_bri; /* global bri number of this port */
int du_port; /* port number (on multi BRI cards) */
int du_state; /* state of board, see below */
#define DAIC_STATE_COLD 0 /* nothing happened to the board */
#define DAIC_STATE_DOWNLOAD 1 /* the card is waiting for protocol code */
#define DAIC_STATE_TESTING 2 /* waiting for first interrupt from card */
#define DAIC_STATE_RUNNING 3 /* the protocol is running */
#define DAIC_STATE_DIAGNOSTIC 4 /* temporary disabled for diagnostics */
int du_assign; /* allocate new protocol instance */
#define DAIC_ASSIGN_PENDING 1 /* we are awaiting a new ID */
#define DAIC_ASSIGN_SLEEPING 2 /* somebody sleeping, wakeup after we got the ID */
#define DAIC_ASSIGN_GLOBAL 4 /* result is a global d-channel id */
#define DAIC_ASSIGN_NOGLOBAL 8 /* need to assign a global d-channel id */
u_int8_t du_global_dchan; /* handle of global dchannel instance */
u_int8_t du_request_res; /* result of requests */
u_int8_t du_assign_res; /* result of assigns */
};
/* superclass of all softc structs for attachments, you should
* always be able to cast an attachments struct device *self to this. */
struct daic {
struct daic_softc {
struct device sc_dev;
bus_space_tag_t sc_iot; /* bus identifier */
bus_space_handle_t sc_ioh; /* mem handle */
@ -65,27 +94,11 @@ struct daic {
#define DAIC_TYPE_SCOM 2
#define DAIC_TYPE_QUAD 3
int sc_ctrl[DAIC_MAX_PORT]; /* upper layer controller number */
int sc_state[DAIC_MAX_PORT]; /* state of board, see below */
#define DAIC_STATE_COLD 0 /* nothing happened to the board */
#define DAIC_STATE_DOWNLOAD 1 /* the card is waiting for protocol code */
#define DAIC_STATE_TESTING 2 /* waiting for first interrupt from card */
#define DAIC_STATE_RUNNING 3 /* the protocol is running */
#define DAIC_STATE_DIAGNOSTIC 4 /* temporary disabled for diagnostics */
int sc_assign[DAIC_MAX_PORT]; /* allocating new protocol instance */
#define DAIC_ASSIGN_PENDING 1 /* we are awaiting a new ID */
#define DAIC_ASSIGN_SLEEPING 2 /* somebody sleeping, wakeup after we got the ID */
#define DAIC_ASSIGN_GLOBAL 4 /* result is a global d-channel id */
#define DAIC_ASSIGN_NOGLOBAL 8 /* need to assign a global d-channel id */
u_int8_t sc_global_dchan[DAIC_MAX_PORT]; /* handle of global dchannel instance */
u_int8_t sc_request_res[DAIC_MAX_PORT]; /* result of requests */
u_int8_t sc_assign_res[DAIC_MAX_PORT]; /* result of assigns */
struct daic_unit sc_port[DAIC_MAX_PORT];
/* one record for each b-channel we could handle concurrently */
struct daic_connection sc_con[DAIC_MAX_ACTIVE];
/* a tailq of ougoing calls no yet assigned to any b-channel */
TAILQ_HEAD(outcallhead, outcallentry) sc_outcalls[DAIC_MAX_PORT];
};
@ -94,8 +107,8 @@ struct daic {
* functions exported from MI part
*/
extern int daic_probe __P((bus_space_tag_t bus, bus_space_handle_t io));
extern void daic_attach __P((struct device *self, struct daic *sc));
extern int daic_intr __P((struct daic *));
extern void daic_attach __P((struct device *self, struct daic_softc *sc));
extern int daic_intr __P((struct daic_softc *));
#endif
#endif

View File

@ -24,7 +24,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: daic_isa.c,v 1.4 2001/11/15 09:48:09 lukem Exp $");
__KERNEL_RCSID(0, "$NetBSD: daic_isa.c,v 1.5 2002/03/22 09:54:17 martin Exp $");
#include <sys/param.h>
#include <sys/errno.h>
@ -48,7 +48,7 @@ __KERNEL_RCSID(0, "$NetBSD: daic_isa.c,v 1.4 2001/11/15 09:48:09 lukem Exp $");
/* driver state */
struct daic_isa_softc {
struct daic sc_daic; /* MI driver state */
struct daic_softc sc_daic; /* MI driver state */
void *sc_ih; /* interrupt handler */
};
@ -85,13 +85,16 @@ daic_isa_probe(parent, cf, aux)
int card;
/* We need some controller memory to comunicate! */
if (ia->ia_maddr == MADDRUNK || ia->ia_msize == -1)
if (ia->ia_iomem[0].ir_addr == 0 || ia->ia_iomem[0].ir_size == -1)
goto bad;
/* Map card RAM. */
ia->ia_msize = DAIC_ISA_MEMSIZE;
ia->ia_iosize = 0;
if (bus_space_map(memt, ia->ia_maddr, ia->ia_msize,
ia->ia_iomem[0].ir_size = DAIC_ISA_MEMSIZE;
ia->ia_nio = 0;
ia->ia_ndrq = 0;
ia->ia_nirq = 1;
ia->ia_niomem = 1;
if (bus_space_map(memt, ia->ia_iomem[0].ir_addr, ia->ia_iomem[0].ir_size,
0, &memh))
goto bad;
@ -100,7 +103,7 @@ daic_isa_probe(parent, cf, aux)
if (card < 0)
goto bad;
if (card == DAIC_TYPE_QUAD)
ia->ia_msize = DAIC_ISA_QUADSIZE;
ia->ia_iomem[0].ir_size = DAIC_ISA_QUADSIZE;
bus_space_unmap(memt, memh, DAIC_ISA_MEMSIZE);
return 1;
@ -122,7 +125,7 @@ daic_isa_attach(parent, self, aux)
bus_space_handle_t memh;
/* Map card RAM. */
if (bus_space_map(memt, ia->ia_maddr, ia->ia_msize,
if (bus_space_map(memt, ia->ia_iomem[0].ir_addr, ia->ia_iomem[0].ir_size,
0, &memh))
return;
@ -132,7 +135,7 @@ daic_isa_attach(parent, self, aux)
/* MI initialization of card */
daic_attach(self, &sc->sc_daic);
sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq, IST_EDGE,
IPL_NET, daic_isa_intr, sc);
}

View File

@ -27,7 +27,7 @@
* i4b_i4bdrv.c - i4b userland interface driver
* --------------------------------------------
*
* $Id: i4b_i4bdrv.c,v 1.12 2002/03/17 20:54:05 martin Exp $
* $Id: i4b_i4bdrv.c,v 1.13 2002/03/22 09:54:17 martin Exp $
*
* $FreeBSD$
*
@ -36,7 +36,7 @@
*---------------------------------------------------------------------------*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: i4b_i4bdrv.c,v 1.12 2002/03/17 20:54:05 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: i4b_i4bdrv.c,v 1.13 2002/03/22 09:54:17 martin Exp $");
#include "isdn.h"
@ -699,7 +699,6 @@ isdnioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
}
/* Download request */
#if 0 /* XXX */
case I4B_CTRL_DOWNLOAD:
{
struct isdn_dr_prot *prots = NULL, *prots2 = NULL;
@ -741,7 +740,7 @@ isdnioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
}
error = ctrl_desc[r->controller].N_DOWNLOAD(
ctrl_desc[r->controller].unit,
ctrl_desc[r->controller].l1_token,
r->numprotos, prots2);
download_done:
@ -817,7 +816,7 @@ download_done:
}
}
error = ctrl_desc[r->controller].N_DIAGNOSTICS(r->controller, &req);
error = ctrl_desc[r->controller].N_DIAGNOSTICS(ctrl_desc[r->controller].l1_token, &req);
if(!error && req.out_param_len)
error = copyout(req.out_param, r->out_param, req.out_param_len);
@ -831,7 +830,6 @@ diag_done:
break;
}
#endif
/* default */

View File

@ -27,7 +27,7 @@
* i4b_l3l4.h - layer 3 / layer 4 interface
* ------------------------------------------
*
* $Id: i4b_l3l4.h,v 1.5 2002/03/17 20:54:05 martin Exp $
* $Id: i4b_l3l4.h,v 1.6 2002/03/22 09:54:17 martin Exp $
*
* $FreeBSD$
*
@ -258,10 +258,8 @@ typedef struct
void (*N_CONNECT_RESPONSE) (unsigned int, int, int);
void (*N_DISCONNECT_REQUEST) (unsigned int, int);
void (*N_ALERT_REQUEST) (unsigned int);
#if 0
int (*N_DOWNLOAD) (void*, int numprotos, struct isdn_dr_prot *protocols);
int (*N_DIAGNOSTICS) (void*, struct isdn_diagnostic_request*);
#endif
void (*N_MGMT_COMMAND) (int bri, int cmd, void *);
} ctrl_desc_t;

View File

@ -27,7 +27,7 @@
* i4b_l4if.c - Layer 3 interface to Layer 4
* -------------------------------------------
*
* $Id: i4b_l4if.c,v 1.5 2002/03/19 20:10:45 martin Exp $
* $Id: i4b_l4if.c,v 1.6 2002/03/22 09:54:18 martin Exp $
*
* $FreeBSD$
*
@ -36,7 +36,7 @@
*---------------------------------------------------------------------------*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: i4b_l4if.c,v 1.5 2002/03/19 20:10:45 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: i4b_l4if.c,v 1.6 2002/03/22 09:54:18 martin Exp $");
#ifdef __FreeBSD__
#include "i4bq931.h"
@ -108,10 +108,8 @@ i4b_mdl_status_ind(int bri, int status, int parm)
ctrl_desc[nctrl].N_CONNECT_RESPONSE = n_connect_response;
ctrl_desc[nctrl].N_DISCONNECT_REQUEST = n_disconnect_request;
ctrl_desc[nctrl].N_ALERT_REQUEST = n_alert_request;
#if 0
ctrl_desc[nctrl].N_DOWNLOAD = NULL; /* only used by active cards */
ctrl_desc[nctrl].N_DIAGNOSTICS = NULL; /* only used by active cards */
#endif
ctrl_desc[nctrl].N_MGMT_COMMAND = n_mgmt_command;
/* init type and unit */