Deleted Added
full compact
32c32
< __FBSDID("$FreeBSD: head/sys/dev/fatm/if_fatm.c 118168 2003-07-29 14:00:59Z harti $");
---
> __FBSDID("$FreeBSD: head/sys/dev/fatm/if_fatm.c 118208 2003-07-30 14:20:00Z harti $");
50a51
> #include <vm/uma.h>
523,525c524,530
< if (sc->vccs != NULL)
< for (i = 0; i <= FORE_MAX_VCC; i++)
< sc->vccs[i].flags = 0;
---
> 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;
> }
> }
1449c1454
< int stat, mlen, drop;
---
> int stat, mlen;
1457a1463
> struct card_vcc *vc;
1472d1477
< drop = 0;
1512,1513c1517,1519
< drop = 1;
< else if ((sc->vccs[vci].flags & FATM_VCC_OPEN) == 0) {
---
> vc = NULL;
> else if ((vc = sc->vccs[vci]) == NULL ||
> !(sc->vccs[vci]->vflags & FATM_VCC_OPEN)) {
1515c1521
< drop = 1;
---
> vc = NULL;
1519c1525
< pt, mlen, drop ? "dropped" : ""));
---
> pt, mlen, vc == NULL ? "dropped" : ""));
1521c1527
< if (drop) {
---
> if (vc == NULL) {
1524c1530
< ATM_PH_FLAGS(&aph) = sc->vccs[vci].flags & 0xff;
---
> ATM_PH_FLAGS(&aph) = vc->param.flags;
1531c1537,1540
< atm_input(ifp, &aph, m0, sc->vccs[vci].rxhand);
---
> vc->ipackets++;
> vc->ibytes += m0->m_pkthdr.len;
>
> atm_input(ifp, &aph, m0, vc->rxhand);
1898c1907
< fatm_tx(struct fatm_softc *sc, struct mbuf *m, u_int vpi, u_int vci, u_int mlen)
---
> fatm_tx(struct fatm_softc *sc, struct mbuf *m, struct card_vcc *vc, u_int mlen)
1951c1960
< aal = (sc->vccs[vci].aal == ATMIO_AAL_5) ? 5 : 0;
---
> aal = (vc->param.aal == ATMIO_AAL_5) ? 5 : 0;
1964c1973,1974
< H_SETDESC(tpd->atm_header, TDX_MKHDR(vpi, vci, 0, 0));
---
> H_SETDESC(tpd->atm_header, TDX_MKHDR(vc->param.vpi,
> vc->param.vci, 0, 0));
1966c1976
< if (sc->vccs[vci].traffic == ATMIO_TRAFFIC_UBR)
---
> if (vc->param.traffic == ATMIO_TRAFFIC_UBR)
1972c1982
< if (rate_table[i].cell_rate < sc->vccs[vci].pcr)
---
> if (rate_table[i].cell_rate < vc->param.tparam.pcr)
1989a2000,2001
> vc->obytes += m->m_pkthdr.len;
> vc->opackets++;
2002a2015
> struct card_vcc *vc;
2051,2052c2064,2065
< if (!VC_OK(sc, vpi, vci) ||
< !(sc->vccs[vci].flags & FATM_VCC_OPEN)) {
---
> if (!VC_OK(sc, vpi, vci) || (vc = sc->vccs[vci]) == NULL ||
> !(vc->vflags & FATM_VCC_OPEN)) {
2057c2070
< if (fatm_tx(sc, m, vpi, vci, mlen)) {
---
> if (fatm_tx(sc, m, vc, mlen)) {
2066,2111d2078
< * Return a table of all currently open VCCs.
< */
< static struct atmio_vcctable *
< get_vccs(struct fatm_softc *sc, int flags)
< {
< struct atmio_vcctable *vccs;
< struct atmio_vcc *v;
< u_int i, alloc;
<
< alloc = 10;
< vccs = NULL;
< for (;;) {
< vccs = reallocf(vccs,
< sizeof(*vccs) + alloc * sizeof(vccs->vccs[0]),
< M_DEVBUF, flags);
< if (vccs == NULL)
< return (NULL);
<
< vccs->count = 0;
< FATM_LOCK(sc);
< v = vccs->vccs;
< for (i = 0; i < (1U << sc->ifatm.mib.vci_bits); i++) {
< if (sc->vccs[i].flags & FATM_VCC_OPEN) {
< if (vccs->count++ == alloc) {
< alloc *= 2;
< break;
< }
< v->vpi = 0;
< v->vci = i;
< v->flags = sc->vccs[i].flags;
< v->aal = sc->vccs[i].aal;
< v->traffic = sc->vccs[i].traffic;
< bzero(&v->tparam, sizeof(v->tparam));
< v->tparam.pcr = sc->vccs[i].pcr;
< v++;
< }
< }
< if (i == (1U << sc->ifatm.mib.vci_bits))
< break;
< FATM_UNLOCK(sc);
< }
< FATM_UNLOCK(sc);
< return (vccs);
< }
<
< /*
2156c2123,2124
< * Start to open a VCC. This just initiates the operation.
---
> * The VC has been opened/closed and somebody has been waiting for this.
> * Wake him up.
2158,2161c2126,2127
< static int
< fatm_start_open_vcc(struct fatm_softc *sc, u_int vpi, u_int vci, u_int aal,
< u_int traffic, u_int pcr, u_int flags, void *rxhand,
< void (*func)(struct fatm_softc *, struct cmdqueue *), struct cmdqueue **qp)
---
> static void
> fatm_cmd_complete(struct fatm_softc *sc, struct cmdqueue *q)
2163,2165d2128
< int error;
< uint32_t cmd;
< struct cmdqueue *q;
2167c2130,2136
< error = 0;
---
> H_SYNCSTAT_POSTREAD(sc, q->q.statp);
> if (H_GETSTAT(q->q.statp) & FATM_STAT_ERROR) {
> sc->istats.get_stat_errors++;
> q->error = EIO;
> }
> wakeup(q);
> }
2169,2176c2138,2145
< if (!(sc->ifatm.ifnet.if_flags & IFF_RUNNING))
< return (EIO);
< if (!VC_OK(sc, vpi, vci) ||
< (aal != ATMIO_AAL_0 && aal != ATMIO_AAL_5) ||
< (traffic != ATMIO_TRAFFIC_UBR && traffic != ATMIO_TRAFFIC_CBR))
< return (EINVAL);
< if (sc->vccs[vci].flags & FATM_VCC_BUSY)
< return (EBUSY);
---
> /*
> * Open complete
> */
> static void
> fatm_open_finish(struct fatm_softc *sc, struct card_vcc *vc)
> {
> vc->vflags &= ~FATM_VCC_TRY_OPEN;
> vc->vflags |= FATM_VCC_OPEN;
2178,2196c2147,2151
< /* Command and buffer strategy */
< cmd = FATM_OP_ACTIVATE_VCIN | FATM_OP_INTERRUPT_SEL | (0 << 16);
< if (aal == ATMIO_AAL_0)
< cmd |= (0 << 8);
< else
< cmd |= (5 << 8);
<
< if ((q = fatm_start_vcc(sc, vpi, vci, cmd, 1, func)) == NULL)
< return (EIO);
< if (qp != NULL)
< *qp = q;
<
< sc->vccs[vci].aal = aal;
< sc->vccs[vci].flags = flags | FATM_VCC_TRY_OPEN;
< sc->vccs[vci].rxhand = rxhand;
< sc->vccs[vci].pcr = pcr;
< sc->vccs[vci].traffic = traffic;
<
< return (0);
---
> /* inform management if this is not an NG
> * VCC or it's an NG PVC. */
> if (!(vc->param.flags & ATMIO_FLAG_NG) ||
> (vc->param.flags & ATMIO_FLAG_PVC))
> ATMEV_SEND_VCC_CHANGED(&sc->ifatm, 0, vc->param.vci, 1);
2200c2155
< * Initiate closing a VCC
---
> * The VC that we have tried to open asynchronuosly has been opened.
2202,2204c2157,2158
< static int
< fatm_start_close_vcc(struct fatm_softc *sc, u_int vpi, u_int vci,
< void (*func)(struct fatm_softc *, struct cmdqueue *), struct cmdqueue **qp)
---
> static void
> fatm_open_complete(struct fatm_softc *sc, struct cmdqueue *q)
2206,2207c2160,2161
< int error;
< struct cmdqueue *q;
---
> u_int vci;
> struct card_vcc *vc;
2209,2228c2163,2173
< error = 0;
<
< if (!(sc->ifatm.ifnet.if_flags & IFF_RUNNING))
< return (EIO);
< if (!VC_OK(sc, vpi, vci))
< return (EINVAL);
< if (!(sc->vccs[vci].flags & (FATM_VCC_OPEN | FATM_VCC_TRY_OPEN)))
< return (ENOENT);
<
< if ((q = fatm_start_vcc(sc, vpi, vci,
< FATM_OP_DEACTIVATE_VCIN | FATM_OP_INTERRUPT_SEL, 1, func)) == NULL)
< return (EIO);
<
< if (qp != NULL)
< *qp = q;
<
< sc->vccs[vci].flags &= ~(FATM_VCC_OPEN | FATM_VCC_TRY_OPEN);
< sc->vccs[vci].flags |= FATM_VCC_TRY_CLOSE;
<
< return (0);
---
> vci = GETVCI(READ4(sc, q->q.card + FATMOC_ACTIN_VPVC));
> vc = sc->vccs[vci];
> H_SYNCSTAT_POSTREAD(sc, q->q.statp);
> if (H_GETSTAT(q->q.statp) & FATM_STAT_ERROR) {
> sc->istats.get_stat_errors++;
> sc->vccs[vci] = NULL;
> uma_zfree(sc->vcc_zone, vc);
> if_printf(&sc->ifatm.ifnet, "opening VCI %u failed\n", vci);
> return;
> }
> fatm_open_finish(sc, vc);
2250,2251c2195
< * The VC has been opened/closed and somebody has been waiting for this.
< * Wake him up.
---
> * Start to open a VCC. This just initiates the operation.
2253,2267d2196
< static void
< fatm_cmd_complete(struct fatm_softc *sc, struct cmdqueue *q)
< {
<
< H_SYNCSTAT_POSTREAD(sc, q->q.statp);
< if (H_GETSTAT(q->q.statp) & FATM_STAT_ERROR) {
< sc->istats.get_stat_errors++;
< q->error = EIO;
< }
< wakeup(q);
< }
<
< /*
< * Open a vcc and wait for completion
< */
2269,2270c2198
< fatm_open_vcc(struct fatm_softc *sc, u_int vpi, u_int vci, u_int flags,
< u_int aal, u_int traffic, u_int pcr, void *rxhand)
---
> fatm_open_vcc(struct fatm_softc *sc, struct atmio_openvcc *op, int wait)
2271a2200
> uint32_t cmd;
2273a2203
> struct card_vcc *vc;
2274a2205,2220
> /*
> * Check parameters
> */
> if ((op->param.flags & ATMIO_FLAG_NOTX) &&
> (op->param.flags & ATMIO_FLAG_NORX))
> return (EINVAL);
>
> if (!VC_OK(sc, op->param.vpi, op->param.vci))
> return (EINVAL);
> if (op->param.aal != ATMIO_AAL_0 && op->param.aal != ATMIO_AAL_5)
> return (EINVAL);
>
> vc = uma_zalloc(sc->vcc_zone, M_NOWAIT | M_ZERO);
> if (vc == NULL)
> return (ENOMEM);
>
2278,2282c2224,2226
< error = fatm_start_open_vcc(sc, vpi, vci, aal, traffic, pcr,
< flags, rxhand, fatm_cmd_complete, &q);
< if (error != 0) {
< FATM_UNLOCK(sc);
< return (error);
---
> if (!(sc->ifatm.ifnet.if_flags & IFF_RUNNING)) {
> error = EIO;
> goto done;
2284c2228,2233
< error = fatm_waitvcc(sc, q);
---
> if (sc->vccs[op->param.vci] != NULL) {
> error = EBUSY;
> goto done;
> }
> vc->param = op->param;
> vc->rxhand = op->rxhand;
2286,2289c2235
< if (error == 0) {
< sc->vccs[vci].flags &= ~FATM_VCC_TRY_OPEN;
< sc->vccs[vci].flags |= FATM_VCC_OPEN;
< sc->open_vccs++;
---
> switch (op->param.traffic) {
2291,2297c2237,2238
< /* inform management if this is not an NG
< * VCC or it's an NG PVC. */
< if (!(sc->vccs[vci].flags & ATMIO_FLAG_NG) ||
< (sc->vccs[vci].flags & ATMIO_FLAG_PVC))
< ATMEV_SEND_VCC_CHANGED(&sc->ifatm, 0, vci, 1);
< } else
< bzero(&sc->vccs[vci], sizeof(sc->vccs[vci]));
---
> case ATMIO_TRAFFIC_UBR:
> break;
2299,2301c2240,2246
< FATM_UNLOCK(sc);
< return (error);
< }
---
> case ATMIO_TRAFFIC_CBR:
> if (op->param.tparam.pcr == 0 ||
> op->param.tparam.pcr > sc->ifatm.mib.pcr) {
> error = EINVAL;
> goto done;
> }
> break;
2303,2310c2248,2254
< /*
< * Close a VCC synchronuosly
< */
< static int
< fatm_close_vcc(struct fatm_softc *sc, u_int vpi, u_int vci)
< {
< int error;
< struct cmdqueue *q;
---
> default:
> error = EINVAL;
> goto done;
> return (EINVAL);
> }
> vc->ibytes = vc->obytes = 0;
> vc->ipackets = vc->opackets = 0;
2312c2256,2261
< error = 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);
2314,2318c2263,2267
< FATM_LOCK(sc);
< error = fatm_start_close_vcc(sc, vpi, vci, fatm_cmd_complete, &q);
< if (error != 0) {
< FATM_UNLOCK(sc);
< return (error);
---
> q = fatm_start_vcc(sc, op->param.vpi, op->param.vci, cmd, 1,
> wait ? fatm_cmd_complete : fatm_open_complete);
> if (q == NULL) {
> error = EIO;
> goto done;
2320d2268
< error = fatm_waitvcc(sc, q);
2322,2327c2270,2272
< if (error == 0) {
< /* inform management of this is not an NG
< * VCC or it's an NG PVC. */
< if (!(sc->vccs[vci].flags & ATMIO_FLAG_NG) ||
< (sc->vccs[vci].flags & ATMIO_FLAG_PVC))
< ATMEV_SEND_VCC_CHANGED(&sc->ifatm, 0, vci, 0);
---
> vc->vflags = FATM_VCC_TRY_OPEN;
> sc->vccs[op->param.vci] = vc;
> sc->open_vccs++;
2329,2330c2274,2281
< bzero(&sc->vccs[vci], sizeof(sc->vccs[vci]));
< sc->open_vccs--;
---
> if (wait) {
> error = fatm_waitvcc(sc, q);
> if (error != 0) {
> sc->vccs[op->param.vci] = NULL;
> sc->open_vccs--;
> goto done;
> }
> fatm_open_finish(sc, vc);
2332a2284,2287
> /* don't free below */
> vc = NULL;
>
> done:
2333a2289,2290
> if (vc != NULL)
> uma_zfree(sc->vcc_zone, vc);
2338c2295
< * The VC has been opened.
---
> * Finish close
2341c2298
< fatm_open_complete(struct fatm_softc *sc, struct cmdqueue *q)
---
> fatm_close_finish(struct fatm_softc *sc, struct card_vcc *vc)
2343c2300,2304
< u_int vci;
---
> /* inform management of this is not an NG
> * VCC or it's an NG PVC. */
> if (!(vc->param.flags & ATMIO_FLAG_NG) ||
> (vc->param.flags & ATMIO_FLAG_PVC))
> ATMEV_SEND_VCC_CHANGED(&sc->ifatm, 0, vc->param.vci, 0);
2345,2352c2306,2307
< vci = GETVCI(READ4(sc, q->q.card + FATMOC_ACTIN_VPVC));
< H_SYNCSTAT_POSTREAD(sc, q->q.statp);
< if (H_GETSTAT(q->q.statp) & FATM_STAT_ERROR) {
< sc->istats.get_stat_errors++;
< bzero(&sc->vccs[vci], sizeof(sc->vccs[vci]));
< if_printf(&sc->ifatm.ifnet, "opening VCI %u failed\n", vci);
< return;
< }
---
> sc->vccs[vc->param.vci] = NULL;
> sc->open_vccs--;
2354,2362c2309
< sc->vccs[vci].flags &= ~FATM_VCC_TRY_OPEN;
< sc->vccs[vci].flags |= FATM_VCC_OPEN;
< sc->open_vccs++;
<
< /* inform management if this is not an NG
< * VCC or it's an NG PVC. */
< if (!(sc->vccs[vci].flags & ATMIO_FLAG_NG) ||
< (sc->vccs[vci].flags & ATMIO_FLAG_PVC))
< ATMEV_SEND_VCC_CHANGED(&sc->ifatm, 0, vci, 1);
---
> uma_zfree(sc->vcc_zone, vc);
2371a2319
> struct card_vcc *vc;
2373a2322
> vc = sc->vccs[vci];
2382,2389c2331
< /* inform management of this is not an NG
< * VCC or it's an NG PVC. */
< if (!(sc->vccs[vci].flags & ATMIO_FLAG_NG) ||
< (sc->vccs[vci].flags & ATMIO_FLAG_PVC))
< ATMEV_SEND_VCC_CHANGED(&sc->ifatm, 0, vci, 0);
<
< bzero(&sc->vccs[vci], sizeof(sc->vccs[vci]));
< sc->open_vccs--;
---
> fatm_close_finish(sc, vc);
2393c2335
< * Open a vcc but don't wait.
---
> * Initiate closing a VCC
2396,2397c2338
< fatm_open_vcc_nowait(struct fatm_softc *sc, u_int vpi, u_int vci, u_int flags,
< u_int aal, void *rxhand)
---
> fatm_close_vcc(struct fatm_softc *sc, struct atmio_closevcc *cl, int wait)
2399a2341,2342
> struct cmdqueue *q;
> struct card_vcc *vc;
2401,2406c2344,2345
< FATM_LOCK(sc);
< error = fatm_start_open_vcc(sc, vpi, vci, aal, ATMIO_TRAFFIC_UBR, 0,
< flags, rxhand, fatm_open_complete, NULL);
< FATM_UNLOCK(sc);
< return (error);
< }
---
> if (!VC_OK(sc, cl->vpi, cl->vci))
> return (EINVAL);
2408,2414c2347
< /*
< * Close a VCC but don't wait
< */
< static int
< fatm_close_vcc_nowait(struct fatm_softc *sc, u_int vpi, u_int vci)
< {
< int error;
---
> error = 0;
2417c2350,2379
< error = fatm_start_close_vcc(sc, vpi, vci, fatm_close_complete, NULL);
---
> if (!(sc->ifatm.ifnet.if_flags & IFF_RUNNING)) {
> error = EIO;
> goto done;
> }
> vc = sc->vccs[cl->vci];
> if (vc == NULL || !(vc->vflags & (FATM_VCC_OPEN | FATM_VCC_TRY_OPEN))) {
> error = ENOENT;
> goto done;
> }
>
> q = fatm_start_vcc(sc, cl->vpi, cl->vci,
> FATM_OP_DEACTIVATE_VCIN | FATM_OP_INTERRUPT_SEL, 1,
> wait ? fatm_cmd_complete : fatm_close_complete);
> if (q == NULL) {
> error = EIO;
> goto done;
> }
>
> vc->vflags &= ~(FATM_VCC_OPEN | FATM_VCC_TRY_OPEN);
> vc->vflags |= FATM_VCC_TRY_CLOSE;
>
> if (wait) {
> error = fatm_waitvcc(sc, q);
> if (error != 0)
> goto done;
>
> fatm_close_finish(sc, vc);
> }
>
> done:
2435a2398,2399
> struct atmio_openvcc ena;
> struct atmio_closevcc dis;
2441,2444c2405,2414
< error = fatm_open_vcc_nowait(sc, ATM_PH_VPI(&pa->aph),
< ATM_PH_VCI(&pa->aph), ATM_PH_FLAGS(&pa->aph),
< (ATM_PH_FLAGS(&pa->aph) & ATM_PH_AAL5) ? ATMIO_AAL_5 :
< ATMIO_AAL_0, pa->rxhand);
---
> bzero(&ena, sizeof(ena));
> ena.param.flags = ATM_PH_FLAGS(&pa->aph) &
> (ATM_PH_AAL5 | ATM_PH_LLCSNAP);
> ena.param.vpi = ATM_PH_VPI(&pa->aph);
> ena.param.vci = ATM_PH_VCI(&pa->aph);
> ena.param.aal = (ATM_PH_FLAGS(&pa->aph) & ATM_PH_AAL5) ?
> ATMIO_AAL_5 : ATMIO_AAL_0;
> ena.param.traffic = ATMIO_TRAFFIC_UBR;
> ena.rxhand = pa->rxhand;
> error = fatm_open_vcc(sc, &ena, 0);
2448,2449c2418,2421
< error = fatm_close_vcc_nowait(sc, ATM_PH_VPI(&pa->aph),
< ATM_PH_VCI(&pa->aph));
---
> bzero(&dis, sizeof(dis));
> dis.vpi = ATM_PH_VPI(&pa->aph);
> dis.vci = ATM_PH_VCI(&pa->aph);
> error = fatm_close_vcc(sc, &dis, 0);
2453,2455c2425
< error = fatm_open_vcc(sc, op->param.vpi, op->param.vci,
< op->param.flags, op->param.aal, op->param.traffic,
< op->param.tparam.pcr, op->rxhand);
---
> error = fatm_open_vcc(sc, op, 1);
2459c2429
< error = fatm_close_vcc(sc, cl->vpi, cl->vci);
---
> error = fatm_close_vcc(sc, cl, 1);
2504,2508c2474,2475
< vtab = get_vccs(sc, M_WAITOK);
< if (vtab == NULL) {
< error = ENOMEM;
< break;
< }
---
> vtab = atm_getvccs((struct atmio_vcc **)sc->vccs,
> FORE_MAX_VCC + 1, sc->open_vccs, &sc->mtx, 1);
2515c2482,2483
< vtab = get_vccs(sc, M_NOWAIT);
---
> vtab = atm_getvccs((struct atmio_vcc **)sc->vccs,
> FORE_MAX_VCC + 1, sc->open_vccs, &sc->mtx, 0);
2577,2578c2545,2550
< free(sc->rbufs, M_DEVBUF);
< free(sc->vccs, M_DEVBUF);
---
> if (sc->rbufs != NULL)
> free(sc->rbufs, M_DEVBUF);
> if (sc->vccs != NULL)
> free(sc->vccs, M_DEVBUF);
> if (sc->vcc_zone != NULL)
> uma_zdestroy(sc->vcc_zone);
2580,2584c2552,2561
< free(sc->l1queue.chunk, M_DEVBUF);
< free(sc->s1queue.chunk, M_DEVBUF);
< free(sc->rxqueue.chunk, M_DEVBUF);
< free(sc->txqueue.chunk, M_DEVBUF);
< free(sc->cmdqueue.chunk, M_DEVBUF);
---
> if (sc->l1queue.chunk != NULL)
> free(sc->l1queue.chunk, M_DEVBUF);
> if (sc->s1queue.chunk != NULL)
> free(sc->s1queue.chunk, M_DEVBUF);
> if (sc->rxqueue.chunk != NULL)
> free(sc->rxqueue.chunk, M_DEVBUF);
> if (sc->txqueue.chunk != NULL)
> free(sc->txqueue.chunk, M_DEVBUF);
> if (sc->cmdqueue.chunk != NULL)
> free(sc->cmdqueue.chunk, M_DEVBUF);
2972c2949
< sc->vccs = malloc((FORE_MAX_VCC + 1) * sizeof(struct card_vcc),
---
> sc->vccs = malloc((FORE_MAX_VCC + 1) * sizeof(sc->vccs[0]),
2973a2951,2956
> sc->vcc_zone = uma_zcreate("FATM vccs", sizeof(struct card_vcc),
> NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
> if (sc->vcc_zone == NULL) {
> error = ENOMEM;
> goto fail;
> }