Make pcmcia cards detach properly.

Notify userland of attaching/detaching cards.
This partly fixes PR 15951.
This commit is contained in:
martin 2002-03-25 12:07:33 +00:00
parent e242265100
commit a994533d0a
8 changed files with 121 additions and 38 deletions

View File

@ -27,14 +27,14 @@
* i4b_isac.c - i4b siemens isdn chipset driver ISAC handler * i4b_isac.c - i4b siemens isdn chipset driver ISAC handler
* --------------------------------------------------------- * ---------------------------------------------------------
* *
* $Id: isac.c,v 1.4 2002/03/24 20:35:45 martin Exp $ * $Id: isac.c,v 1.5 2002/03/25 12:07:33 martin Exp $
* *
* last edit-date: [Fri Jan 5 11:36:10 2001] * last edit-date: [Fri Jan 5 11:36:10 2001]
* *
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: isac.c,v 1.4 2002/03/24 20:35:45 martin Exp $"); __KERNEL_RCSID(0, "$NetBSD: isac.c,v 1.5 2002/03/25 12:07:33 martin Exp $");
#ifdef __FreeBSD__ #ifdef __FreeBSD__
#include "opt_i4b.h" #include "opt_i4b.h"
@ -92,7 +92,7 @@ static void isic_isac_ind_hdlr(register struct isic_softc *sc, int ind);
/*---------------------------------------------------------------------------* /*---------------------------------------------------------------------------*
* ISAC interrupt service routine * ISAC interrupt service routine
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/
void int
isic_isac_irq(struct isic_softc *sc, int ista) isic_isac_irq(struct isic_softc *sc, int ista)
{ {
register u_char c = 0; register u_char c = 0;
@ -100,7 +100,12 @@ isic_isac_irq(struct isic_softc *sc, int ista)
if(ista & ISAC_ISTA_EXI) /* extended interrupt */ if(ista & ISAC_ISTA_EXI) /* extended interrupt */
{ {
c |= isic_isac_exir_hdlr(sc, ISAC_READ(I_EXIR)); u_int8_t exirstat = ISAC_READ(I_EXIR);
if ((ista & ~ISAC_IMASK) && exirstat == 0xff) {
/* bogus - might be a detaching pcmcia card */
return (1);
}
c |= isic_isac_exir_hdlr(sc, exirstat);
} }
if(ista & ISAC_ISTA_RME) /* receive message end */ if(ista & ISAC_ISTA_RME) /* receive message end */
@ -150,7 +155,7 @@ isic_isac_irq(struct isic_softc *sc, int ista)
ISAC_WRITE(I_CMDR, ISAC_CMDR_RMC|ISAC_CMDR_RRES); ISAC_WRITE(I_CMDR, ISAC_CMDR_RMC|ISAC_CMDR_RRES);
ISACCMDRWRDELAY(); ISACCMDRWRDELAY();
return; return (0);
} }
rest = (ISAC_READ(I_RBCL) & (ISAC_FIFO_LEN-1)); rest = (ISAC_READ(I_RBCL) & (ISAC_FIFO_LEN-1));
@ -320,6 +325,8 @@ isic_isac_irq(struct isic_softc *sc, int ista)
ISAC_WRITE(I_CMDR, c); ISAC_WRITE(I_CMDR, c);
ISACCMDRWRDELAY(); ISACCMDRWRDELAY();
} }
return (0);
} }
/*---------------------------------------------------------------------------* /*---------------------------------------------------------------------------*

View File

@ -27,14 +27,14 @@
* i4b_isic.c - global isic stuff * i4b_isic.c - global isic stuff
* ============================== * ==============================
* *
* $Id: isic.c,v 1.4 2002/03/24 20:35:46 martin Exp $ * $Id: isic.c,v 1.5 2002/03/25 12:07:33 martin Exp $
* *
* last edit-date: [Fri Jan 5 11:36:10 2001] * last edit-date: [Fri Jan 5 11:36:10 2001]
* *
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: isic.c,v 1.4 2002/03/24 20:35:46 martin Exp $"); __KERNEL_RCSID(0, "$NetBSD: isic.c,v 1.5 2002/03/25 12:07:33 martin Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/ioccom.h> #include <sys/ioccom.h>
@ -132,7 +132,8 @@ isicintr(void *arg)
if(isac_irq_stat) if(isac_irq_stat)
{ {
isic_isac_irq(sc, isac_irq_stat); /* isac handler */ if (isic_isac_irq(sc, isac_irq_stat)) /* isac handler */
break; /* bad IRQ */
was_isac_irq = 1; was_isac_irq = 1;
} }
} }
@ -192,7 +193,8 @@ isicintr(void *arg)
if(ipac_irq_stat & IPAC_ISTA_EXD) if(ipac_irq_stat & IPAC_ISTA_EXD)
{ {
/* force ISAC interrupt handling */ /* force ISAC interrupt handling */
isic_isac_irq(sc, ISAC_ISTA_EXI); if (isic_isac_irq(sc, ISAC_ISTA_EXI))
break; /* bad IRQ */
was_ipac_irq = 1; was_ipac_irq = 1;
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: isic_l1.h,v 1.4 2002/03/24 20:35:47 martin Exp $ */ /* $NetBSD: isic_l1.h,v 1.5 2002/03/25 12:07:33 martin Exp $ */
/* /*
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved. * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
@ -206,7 +206,7 @@ struct isic_softc
int sc_init_tries; /* no of out tries to access S0 */ int sc_init_tries; /* no of out tries to access S0 */
int sc_maddr; /* some stupid ISA cards need this */ int sc_maddr; /* some stupid ISA cards need this */
u_char sc_isac_mask; /* ISAC IRQ mask */ u_char sc_isac_mask; /* ISAC IRQ mask */
#define ISAC_IMASK (sc->sc_isac_mask) #define ISAC_IMASK (sc->sc_isac_mask)
@ -340,7 +340,7 @@ extern void isic_hscx_cmd __P(( struct isic_softc *sc, int h_chan, unsigned char
extern void isic_hscx_waitxfw __P(( struct isic_softc *sc, int h_chan )); extern void isic_hscx_waitxfw __P(( struct isic_softc *sc, int h_chan ));
extern void isic_init_linktab __P((struct isic_softc *sc)); extern void isic_init_linktab __P((struct isic_softc *sc));
extern int isic_isac_init __P((struct isic_softc *sc)); extern int isic_isac_init __P((struct isic_softc *sc));
extern void isic_isac_irq __P((struct isic_softc *sc, int r)); extern int isic_isac_irq __P((struct isic_softc *sc, int r));
extern void isic_isac_l1_cmd __P((struct isic_softc *sc, int command)); extern void isic_isac_l1_cmd __P((struct isic_softc *sc, int command));
extern void isic_next_state __P((struct isic_softc *sc, int event)); extern void isic_next_state __P((struct isic_softc *sc, int event));
extern char * isic_printstate __P((struct isic_softc *sc)); extern char * isic_printstate __P((struct isic_softc *sc));

View File

@ -33,7 +33,7 @@
* isic_pcmcia.c - pcmcia bus frontend for i4b_isic driver * isic_pcmcia.c - pcmcia bus frontend for i4b_isic driver
* ------------------------------------------------------- * -------------------------------------------------------
* *
* $Id: isic_pcmcia.c,v 1.6 2002/03/24 20:35:54 martin Exp $ * $Id: isic_pcmcia.c,v 1.7 2002/03/25 12:07:33 martin Exp $
* *
* last edit-date: [Fri Jan 5 11:39:32 2001] * last edit-date: [Fri Jan 5 11:39:32 2001]
* *
@ -42,7 +42,7 @@
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: isic_pcmcia.c,v 1.6 2002/03/24 20:35:54 martin Exp $"); __KERNEL_RCSID(0, "$NetBSD: isic_pcmcia.c,v 1.7 2002/03/25 12:07:33 martin Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/errno.h> #include <sys/errno.h>
@ -94,9 +94,11 @@ static int isic_pcmcia_match __P((struct device *, struct cfdata *, void *));
static void isic_pcmcia_attach __P((struct device *, struct device *, void *)); static void isic_pcmcia_attach __P((struct device *, struct device *, void *));
static const struct isic_pcmcia_card_entry * find_matching_card __P((struct pcmcia_attach_args *pa)); static const struct isic_pcmcia_card_entry * find_matching_card __P((struct pcmcia_attach_args *pa));
static int isic_pcmcia_isdn_attach __P((struct isic_softc *sc, const char*)); static int isic_pcmcia_isdn_attach __P((struct isic_softc *sc, const char*));
static int isic_pcmcia_detach(struct device *self, int flags);
struct cfattach isic_pcmcia_ca = { struct cfattach isic_pcmcia_ca = {
sizeof(struct pcmcia_isic_softc), isic_pcmcia_match, isic_pcmcia_attach sizeof(struct pcmcia_isic_softc), isic_pcmcia_match,
isic_pcmcia_attach, isic_pcmcia_detach
}; };
struct isic_pcmcia_card_entry { struct isic_pcmcia_card_entry {
@ -244,6 +246,22 @@ isic_pcmcia_attach(parent, self, aux)
splx(s); splx(s);
} }
static int
isic_pcmcia_detach(self, flags)
struct device *self;
int flags;
{
struct pcmcia_isic_softc *psc = (struct pcmcia_isic_softc *)self;
pcmcia_function_disable(psc->sc_pf);
pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
pcmcia_intr_disestablish(psc->sc_pf, psc->sc_ih);
isic_detach_bri(&psc->sc_isic);
return (0);
}
/*---------------------------------------------------------------------------* /*---------------------------------------------------------------------------*
* card independend attach for pcmicia cards * card independend attach for pcmicia cards
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/

View File

@ -27,7 +27,7 @@
* i4b_ioctl.h - messages kernel <--> userland * i4b_ioctl.h - messages kernel <--> userland
* ------------------------------------------- * -------------------------------------------
* *
* $Id: i4b_ioctl.h,v 1.5 2002/03/24 20:35:57 martin Exp $ * $Id: i4b_ioctl.h,v 1.6 2002/03/25 12:07:34 martin Exp $
* *
* $FreeBSD$ * $FreeBSD$
* *
@ -211,6 +211,7 @@ typedef struct {
#define MSG_IFSTATE_CHANGED_IND 'o' #define MSG_IFSTATE_CHANGED_IND 'o'
#define MSG_DIALOUTNUMBER_IND 'p' #define MSG_DIALOUTNUMBER_IND 'p'
#define MSG_PACKET_IND 'q' #define MSG_PACKET_IND 'q'
#define MSG_CONTR_EV_IND 'r'
int cdid; /* call descriptor id */ int cdid; /* call descriptor id */
} msg_hdr_t; } msg_hdr_t;
@ -411,6 +412,17 @@ typedef struct {
int numactive; /* number of active connections */ int numactive; /* number of active connections */
} msg_pdeact_ind_t; } msg_pdeact_ind_t;
/*---------------------------------------------------------------------------*
* connect indication
* indicates incoming connection
*---------------------------------------------------------------------------*/
typedef struct {
msg_hdr_t header; /* common header */
int controller; /* controller number */
int event;
#define CTRL_EV_IND_DETACH 0
#define CTRL_EV_IND_ATTACH 1
} msg_ctrl_ev_ind_t;
/*===========================================================================* /*===========================================================================*
*===========================================================================* *===========================================================================*

View File

@ -1,4 +1,4 @@
/* $NetBSD: i4b_l2.c,v 1.7 2002/03/24 20:35:58 martin Exp $ */ /* $NetBSD: i4b_l2.c,v 1.8 2002/03/25 12:07:34 martin Exp $ */
/* /*
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved. * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
@ -29,7 +29,7 @@
* i4b_l2.c - ISDN layer 2 (Q.921) * i4b_l2.c - ISDN layer 2 (Q.921)
* ------------------------------- * -------------------------------
* *
* $Id: i4b_l2.c,v 1.7 2002/03/24 20:35:58 martin Exp $ * $Id: i4b_l2.c,v 1.8 2002/03/25 12:07:34 martin Exp $
* *
* $FreeBSD$ * $FreeBSD$
* *
@ -38,7 +38,7 @@
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: i4b_l2.c,v 1.7 2002/03/24 20:35:58 martin Exp $"); __KERNEL_RCSID(0, "$NetBSD: i4b_l2.c,v 1.8 2002/03/25 12:07:34 martin Exp $");
#ifdef __FreeBSD__ #ifdef __FreeBSD__
#include "i4bq921.h" #include "i4bq921.h"
@ -226,6 +226,9 @@ isdn_layer2_status_ind(l2_softc_t *l2sc, int status, int parm)
switch(status) switch(status)
{ {
case STI_ATTACH: case STI_ATTACH:
if (parm == 0) /* detach */
break;
l2sc->i_queue.ifq_maxlen = IQUEUE_MAXLEN; l2sc->i_queue.ifq_maxlen = IQUEUE_MAXLEN;
l2sc->ua_frame = NULL; l2sc->ua_frame = NULL;
memset(&l2sc->stat, 0, sizeof(lapdstat_t)); memset(&l2sc->stat, 0, sizeof(lapdstat_t));

View File

@ -27,7 +27,7 @@
* i4b_l3l4.h - layer 3 / layer 4 interface * i4b_l3l4.h - layer 3 / layer 4 interface
* ------------------------------------------ * ------------------------------------------
* *
* $Id: i4b_l3l4.h,v 1.7 2002/03/24 20:36:00 martin Exp $ * $Id: i4b_l3l4.h,v 1.8 2002/03/25 12:07:34 martin Exp $
* *
* $FreeBSD$ * $FreeBSD$
* *
@ -242,7 +242,7 @@ struct isdn_l3_driver_functions {
* is just one of those BRIs) * is just one of those BRIs)
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/
struct isdn_l3_driver { struct isdn_l3_driver {
SIMPLEQ_ENTRY(isdn_l3_driver) l3drvq; SLIST_ENTRY(isdn_l3_driver) l3drvq;
void* l1_token; /* softc of hardware driver, actually void* l1_token; /* softc of hardware driver, actually
* this is the l2_softc (!!) for * this is the l2_softc (!!) for
* passive cards, and something else * passive cards, and something else

View File

@ -27,7 +27,7 @@
* i4b_l4.c - kernel interface to userland * i4b_l4.c - kernel interface to userland
* ----------------------------------------- * -----------------------------------------
* *
* $Id: i4b_l4.c,v 1.12 2002/03/24 20:36:00 martin Exp $ * $Id: i4b_l4.c,v 1.13 2002/03/25 12:07:34 martin Exp $
* *
* $FreeBSD$ * $FreeBSD$
* *
@ -36,7 +36,7 @@
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: i4b_l4.c,v 1.12 2002/03/24 20:36:00 martin Exp $"); __KERNEL_RCSID(0, "$NetBSD: i4b_l4.c,v 1.13 2002/03/25 12:07:34 martin Exp $");
#include "isdn.h" #include "isdn.h"
#include "irip.h" #include "irip.h"
@ -74,13 +74,15 @@ __KERNEL_RCSID(0, "$NetBSD: i4b_l4.c,v 1.12 2002/03/24 20:36:00 martin Exp $");
#include <netisdn/i4b_l3.h> #include <netisdn/i4b_l3.h>
#include <netisdn/i4b_l4.h> #include <netisdn/i4b_l4.h>
static void i4b_l4_contr_ev_ind(int controller, int attach);
unsigned int i4b_l4_debug = L4_DEBUG_DEFAULT; unsigned int i4b_l4_debug = L4_DEBUG_DEFAULT;
/* /*
* BRIs (in userland sometimes called "controllers", but one controller * BRIs (in userland sometimes called "controllers", but one controller
* may have multiple BRIs, for example daic QUAD cards attach four BRIs). * may have multiple BRIs, for example daic QUAD cards attach four BRIs).
*/ */
static SIMPLEQ_HEAD(, isdn_l3_driver) bri_list = SIMPLEQ_HEAD_INITIALIZER(bri_list); static SLIST_HEAD(, isdn_l3_driver) bri_list = SLIST_HEAD_INITIALIZER(bri_list);
static int next_bri = 0; static int next_bri = 0;
/* /*
@ -90,12 +92,13 @@ struct isdn_l3_driver *
isdn_attach_bri(const char *devname, const char *cardname, isdn_attach_bri(const char *devname, const char *cardname,
void *l1_token, const struct isdn_l3_driver_functions *l3driver) void *l1_token, const struct isdn_l3_driver_functions *l3driver)
{ {
int s = splnet();
int l, bri = next_bri++; int l, bri = next_bri++;
struct isdn_l3_driver *new_ctrl; struct isdn_l3_driver *new_ctrl;
new_ctrl = malloc(sizeof(*new_ctrl), M_DEVBUF, 0); new_ctrl = malloc(sizeof(*new_ctrl), M_DEVBUF, 0);
memset(new_ctrl, 0, sizeof *new_ctrl); memset(new_ctrl, 0, sizeof *new_ctrl);
SIMPLEQ_INSERT_HEAD(&bri_list, new_ctrl, l3drvq); SLIST_INSERT_HEAD(&bri_list, new_ctrl, l3drvq);
new_ctrl->bri = bri; new_ctrl->bri = bri;
l = strlen(devname); l = strlen(devname);
new_ctrl->devname = malloc(l+1, M_DEVBUF, 0); new_ctrl->devname = malloc(l+1, M_DEVBUF, 0);
@ -112,6 +115,9 @@ isdn_attach_bri(const char *devname, const char *cardname,
new_ctrl->bch_state[1] = BCH_ST_FREE; new_ctrl->bch_state[1] = BCH_ST_FREE;
printf("BRI %d at %s\n", bri, devname); printf("BRI %d at %s\n", bri, devname);
i4b_l4_contr_ev_ind(bri, 1);
splx(s);
return new_ctrl; return new_ctrl;
} }
@ -122,8 +128,23 @@ isdn_attach_bri(const char *devname, const char *cardname,
int int
isdn_detach_bri(const struct isdn_l3_driver *l3drv) isdn_detach_bri(const struct isdn_l3_driver *l3drv)
{ {
/* XXX - not yet implemented*/ struct isdn_l3_driver *sc;
printf("BRI %d detached\n", l3drv->bri); int s = splnet();
int bri = l3drv->bri;
int max;
i4b_l4_contr_ev_ind(bri, 0);
SLIST_REMOVE(&bri_list, l3drv, isdn_l3_driver, l3drvq);
max = -1;
SLIST_FOREACH(sc, &bri_list, l3drvq)
if (sc->bri > max)
max = sc->bri;
next_bri = max+1;
splx(s);
printf("BRI %d detached\n", bri);
return 1; return 1;
} }
@ -132,7 +153,7 @@ isdn_find_l3_by_bri(int bri)
{ {
struct isdn_l3_driver *sc; struct isdn_l3_driver *sc;
SIMPLEQ_FOREACH(sc, &bri_list, l3drvq) SLIST_FOREACH(sc, &bri_list, l3drvq)
if (sc->bri == bri) if (sc->bri == bri)
return sc; return sc;
return NULL; return NULL;
@ -144,7 +165,7 @@ int isdn_count_bri(int *mbri)
int count = 0; int count = 0;
int maxbri = -1; int maxbri = -1;
SIMPLEQ_FOREACH(sc, &bri_list, l3drvq) { SLIST_FOREACH(sc, &bri_list, l3drvq) {
count++; count++;
if (sc->bri > maxbri) if (sc->bri > maxbri)
maxbri = sc->bri; maxbri = sc->bri;
@ -181,7 +202,7 @@ i4b_l4_daemon_attached(void)
struct isdn_l3_driver *d; struct isdn_l3_driver *d;
int x = splnet(); int x = splnet();
SIMPLEQ_FOREACH(d, &bri_list, l3drvq) SLIST_FOREACH(d, &bri_list, l3drvq)
{ {
d->l3driver->N_MGMT_COMMAND(d->bri, CMR_DOPEN, 0); d->l3driver->N_MGMT_COMMAND(d->bri, CMR_DOPEN, 0);
} }
@ -197,7 +218,7 @@ i4b_l4_daemon_detached(void)
struct isdn_l3_driver *d; struct isdn_l3_driver *d;
int x = splnet(); int x = splnet();
SIMPLEQ_FOREACH(d, &bri_list, l3drvq) SLIST_FOREACH(d, &bri_list, l3drvq)
{ {
d->l3driver->N_MGMT_COMMAND(d->bri, CMR_DCLOSE, 0); d->l3driver->N_MGMT_COMMAND(d->bri, CMR_DCLOSE, 0);
} }
@ -220,14 +241,14 @@ static time_t i4b_get_idletime(call_desc_t *cd);
static int next_l4_driver_id = 0; static int next_l4_driver_id = 0;
struct l4_driver_desc { struct l4_driver_desc {
SIMPLEQ_ENTRY(l4_driver_desc) l4drvq; SLIST_ENTRY(l4_driver_desc) l4drvq;
char name[L4DRIVER_NAME_SIZ]; char name[L4DRIVER_NAME_SIZ];
int driver_id; int driver_id;
const struct isdn_l4_driver_functions *driver; const struct isdn_l4_driver_functions *driver;
int units; int units;
}; };
static SIMPLEQ_HEAD(, l4_driver_desc) l4_driver_registry static SLIST_HEAD(, l4_driver_desc) l4_driver_registry
= SIMPLEQ_HEAD_INITIALIZER(l4_driver_registry); = SLIST_HEAD_INITIALIZER(l4_driver_registry);
int isdn_l4_driver_attach(const char *name, int units, const struct isdn_l4_driver_functions *driver) int isdn_l4_driver_attach(const char *name, int units, const struct isdn_l4_driver_functions *driver)
{ {
@ -240,7 +261,7 @@ int isdn_l4_driver_attach(const char *name, int units, const struct isdn_l4_driv
new_driver->driver_id = next_l4_driver_id++; new_driver->driver_id = next_l4_driver_id++;
new_driver->driver = driver; new_driver->driver = driver;
new_driver->units = units; new_driver->units = units;
SIMPLEQ_INSERT_HEAD(&l4_driver_registry, new_driver, l4drvq); SLIST_INSERT_HEAD(&l4_driver_registry, new_driver, l4drvq);
return new_driver->driver_id; return new_driver->driver_id;
} }
@ -253,7 +274,7 @@ int isdn_l4_driver_detatch(const char *name)
const struct isdn_l4_driver_functions *isdn_l4_find_driver(const char *name, int unit) const struct isdn_l4_driver_functions *isdn_l4_find_driver(const char *name, int unit)
{ {
struct l4_driver_desc * d; struct l4_driver_desc * d;
SIMPLEQ_FOREACH(d, &l4_driver_registry, l4drvq) SLIST_FOREACH(d, &l4_driver_registry, l4drvq)
if (strcmp(d->name, name) == 0) { if (strcmp(d->name, name) == 0) {
return d->driver; return d->driver;
} }
@ -263,7 +284,7 @@ const struct isdn_l4_driver_functions *isdn_l4_find_driver(const char *name, int
int isdn_l4_find_driverid(const char *name) int isdn_l4_find_driverid(const char *name)
{ {
struct l4_driver_desc * d; struct l4_driver_desc * d;
SIMPLEQ_FOREACH(d, &l4_driver_registry, l4drvq) SLIST_FOREACH(d, &l4_driver_registry, l4drvq)
if (strcmp(d->name, name) == 0) { if (strcmp(d->name, name) == 0) {
return d->driver_id; return d->driver_id;
} }
@ -273,7 +294,7 @@ int isdn_l4_find_driverid(const char *name)
const struct isdn_l4_driver_functions *isdn_l4_get_driver(int driver_id, int unit) const struct isdn_l4_driver_functions *isdn_l4_get_driver(int driver_id, int unit)
{ {
struct l4_driver_desc * d; struct l4_driver_desc * d;
SIMPLEQ_FOREACH(d, &l4_driver_registry, l4drvq) SLIST_FOREACH(d, &l4_driver_registry, l4drvq)
if (d->driver_id == driver_id) { if (d->driver_id == driver_id) {
return d->driver; return d->driver;
} }
@ -760,6 +781,26 @@ i4b_l4_packet_ind(int driver, int driver_unit, int dir, struct mbuf *pkt)
} }
} }
/*---------------------------------------------------------------------------*
* send MSG_CONTR_EV_IND message to userland
*---------------------------------------------------------------------------*/
static void
i4b_l4_contr_ev_ind(int controller, int attach)
{
struct mbuf *m;
if((m = i4b_Dgetmbuf(sizeof(msg_ctrl_ev_ind_t))) != NULL)
{
msg_ctrl_ev_ind_t *ev = (msg_ctrl_ev_ind_t *)m->m_data;
ev->header.type = MSG_CONTR_EV_IND;
ev->header.cdid = -1;
ev->controller = controller;
ev->event = attach;
i4bputqueue(m);
}
}
/*---------------------------------------------------------------------------* /*---------------------------------------------------------------------------*
* link a driver(unit) to a B-channel(controller,unit,channel) * link a driver(unit) to a B-channel(controller,unit,channel)
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/