From 3593b9247891e48ec434b0410e5b25cbc4cd755f Mon Sep 17 00:00:00 2001 From: Hartmut Brandt Date: Thu, 7 Aug 2003 10:40:24 +0000 Subject: [PATCH] When configuring the interface down and up again try to re-open all connections that have been open (and were not closing) when the interface was stopped. This makes the behaviour of fatm(4) more like the behaviour of en(4). --- sys/dev/fatm/if_fatm.c | 109 ++++++++++++++++++++++++++------------ sys/dev/fatm/if_fatmvar.h | 1 + 2 files changed, 77 insertions(+), 33 deletions(-) diff --git a/sys/dev/fatm/if_fatm.c b/sys/dev/fatm/if_fatm.c index db8f8d1b1edc..f21ee9729584 100644 --- a/sys/dev/fatm/if_fatm.c +++ b/sys/dev/fatm/if_fatm.c @@ -113,6 +113,8 @@ static const struct utopia_methods fatm_utopia_methods = { (((VPI) & ~((1 << (SC)->ifatm.mib.vpi_bits) - 1)) == 0 && \ (VCI) != 0 && ((VCI) & ~((1 << (SC)->ifatm.mib.vci_bits) - 1)) == 0) +static int fatm_load_vc(struct fatm_softc *sc, struct card_vcc *vc); + /* * Probing is easy: step trough the list of known vendor and device * ids and compare. If one is found - it's our. @@ -449,7 +451,7 @@ fatm_reset(struct fatm_softc *sc) /* * Stop the card. Must be called WITH the lock held - * Reset, free transmit and receive buffers. Wakeup everybody that may sleep. + * Reset, free transmit and receive buffers. Wakeup everybody who may sleep. */ static void fatm_stop(struct fatm_softc *sc) @@ -522,14 +524,21 @@ fatm_stop(struct fatm_softc *sc) /* Reset vcc info */ if (sc->vccs != NULL) { - for (i = 0; i < FORE_MAX_VCC + 1; i++) + sc->open_vccs = 0; + for (i = 0; i < FORE_MAX_VCC + 1; i++) { if (sc->vccs[i] != NULL) { - uma_zfree(sc->vcc_zone, sc->vccs[i]); - sc->vccs[i] = NULL; + if ((sc->vccs[i]->vflags & (FATM_VCC_OPEN | + FATM_VCC_TRY_OPEN)) == 0) { + uma_zfree(sc->vcc_zone, sc->vccs[i]); + sc->vccs[i] = NULL; + } else { + sc->vccs[i]->vflags = 0; + sc->open_vccs++; + } } + } } - sc->open_vccs = 0; } /* @@ -1242,7 +1251,7 @@ static void fatm_init_locked(struct fatm_softc *sc) { struct rxqueue *q; - int i, c; + int i, c, error; uint32_t start; DBG(sc, INIT, ("initialize")); @@ -1335,6 +1344,18 @@ fatm_init_locked(struct fatm_softc *sc) ATMEV_SEND_IFSTATE_CHANGED(&sc->ifatm, sc->utopia.carrier == UTP_CARR_OK); + /* start all channels */ + for (i = 0; i < FORE_MAX_VCC + 1; i++) + if (sc->vccs[i] != NULL) { + sc->vccs[i]->vflags |= FATM_VCC_REOPEN; + error = fatm_load_vc(sc, sc->vccs[i]); + if (error != 0) { + if_printf(&sc->ifatm.ifnet, "reopening %u " + "failed: %d\n", i, error); + sc->vccs[i]->vflags &= ~FATM_VCC_REOPEN; + } + } + DBG(sc, INIT, ("done")); } @@ -2144,6 +2165,11 @@ fatm_open_finish(struct fatm_softc *sc, struct card_vcc *vc) vc->vflags &= ~FATM_VCC_TRY_OPEN; vc->vflags |= FATM_VCC_OPEN; + if (vc->vflags & FATM_VCC_REOPEN) { + vc->vflags &= ~FATM_VCC_REOPEN; + return; + } + /* inform management if this is not an NG * VCC or it's an NG PVC. */ if (!(vc->param.flags & ATMIO_FLAG_NG) || @@ -2197,9 +2223,7 @@ fatm_waitvcc(struct fatm_softc *sc, struct cmdqueue *q) static int fatm_open_vcc(struct fatm_softc *sc, struct atmio_openvcc *op) { - uint32_t cmd; int error; - struct cmdqueue *q; struct card_vcc *vc; /* @@ -2248,38 +2272,19 @@ fatm_open_vcc(struct fatm_softc *sc, struct atmio_openvcc *op) default: error = EINVAL; goto done; - return (EINVAL); } vc->ibytes = vc->obytes = 0; vc->ipackets = vc->opackets = 0; - /* Command and buffer strategy */ - cmd = FATM_OP_ACTIVATE_VCIN | FATM_OP_INTERRUPT_SEL | (0 << 16); - if (op->param.aal == ATMIO_AAL_0) - cmd |= (0 << 8); - else - cmd |= (5 << 8); - - q = fatm_start_vcc(sc, op->param.vpi, op->param.vci, cmd, 1, - (op->param.flags & ATMIO_FLAG_ASYNC) ? - fatm_open_complete : fatm_cmd_complete); - if (q == NULL) { - error = EIO; - goto done; - } - vc->vflags = FATM_VCC_TRY_OPEN; sc->vccs[op->param.vci] = vc; sc->open_vccs++; - if (!(op->param.flags & ATMIO_FLAG_ASYNC)) { - error = fatm_waitvcc(sc, q); - if (error != 0) { - sc->vccs[op->param.vci] = NULL; - sc->open_vccs--; - goto done; - } - fatm_open_finish(sc, vc); + error = fatm_load_vc(sc, vc); + if (error != NULL) { + sc->vccs[op->param.vci] = NULL; + sc->open_vccs--; + goto done; } /* don't free below */ @@ -2292,6 +2297,38 @@ fatm_open_vcc(struct fatm_softc *sc, struct atmio_openvcc *op) return (error); } +/* + * Try to initialize the given VC + */ +static int +fatm_load_vc(struct fatm_softc *sc, struct card_vcc *vc) +{ + uint32_t cmd; + struct cmdqueue *q; + int error; + + /* Command and buffer strategy */ + cmd = FATM_OP_ACTIVATE_VCIN | FATM_OP_INTERRUPT_SEL | (0 << 16); + if (vc->param.aal == ATMIO_AAL_0) + cmd |= (0 << 8); + else + cmd |= (5 << 8); + + q = fatm_start_vcc(sc, vc->param.vpi, vc->param.vci, cmd, 1, + (vc->param.flags & ATMIO_FLAG_ASYNC) ? + fatm_open_complete : fatm_cmd_complete); + if (q == NULL) + return (EIO); + + if (!(vc->param.flags & ATMIO_FLAG_ASYNC)) { + error = fatm_waitvcc(sc, q); + if (error != 0) + return (error); + fatm_open_finish(sc, vc); + } + return (0); +} + /* * Finish close */ @@ -2523,8 +2560,14 @@ fatm_detach(device_t dev) if (sc->rbufs != NULL) free(sc->rbufs, M_DEVBUF); - if (sc->vccs != NULL) + if (sc->vccs != NULL) { + for (i = 0; i < FORE_MAX_VCC + 1; i++) + if (sc->vccs[i] != NULL) { + uma_zfree(sc->vcc_zone, sc->vccs[i]); + sc->vccs[i] = NULL; + } free(sc->vccs, M_DEVBUF); + } if (sc->vcc_zone != NULL) uma_zdestroy(sc->vcc_zone); diff --git a/sys/dev/fatm/if_fatmvar.h b/sys/dev/fatm/if_fatmvar.h index 420584eee157..57df04183851 100644 --- a/sys/dev/fatm/if_fatmvar.h +++ b/sys/dev/fatm/if_fatmvar.h @@ -179,6 +179,7 @@ struct card_vcc { #define FATM_VCC_TRY_OPEN 0x00020000 /* is currently opening */ #define FATM_VCC_TRY_CLOSE 0x00040000 /* is currently closing */ #define FATM_VCC_BUSY 0x00070000 /* one of the above */ +#define FATM_VCC_REOPEN 0x00080000 /* reopening during init */ /* * Finally the softc structure