if_fatm.c (118168) | if_fatm.c (118208) |
---|---|
1/* 2 * Copyright (c) 2001-2003 3 * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 15 unchanged lines hidden (view full) --- 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * Author: Hartmut Brandt <harti@freebsd.org> 28 * 29 * Fore PCA200E driver for NATM 30 */ 31#include <sys/cdefs.h> | 1/* 2 * Copyright (c) 2001-2003 3 * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 15 unchanged lines hidden (view full) --- 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * Author: Hartmut Brandt <harti@freebsd.org> 28 * 29 * Fore PCA200E driver for NATM 30 */ 31#include <sys/cdefs.h> |
32__FBSDID("$FreeBSD: head/sys/dev/fatm/if_fatm.c 118168 2003-07-29 14:00:59Z harti $"); | 32__FBSDID("$FreeBSD: head/sys/dev/fatm/if_fatm.c 118208 2003-07-30 14:20:00Z harti $"); |
33 34#include "opt_inet.h" 35#include "opt_natm.h" 36 37#include <sys/types.h> 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/malloc.h> 41#include <sys/kernel.h> 42#include <sys/bus.h> 43#include <sys/errno.h> 44#include <sys/conf.h> 45#include <sys/module.h> 46#include <sys/queue.h> 47#include <sys/syslog.h> 48#include <sys/endian.h> 49#include <sys/sysctl.h> 50#include <sys/condvar.h> | 33 34#include "opt_inet.h" 35#include "opt_natm.h" 36 37#include <sys/types.h> 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/malloc.h> 41#include <sys/kernel.h> 42#include <sys/bus.h> 43#include <sys/errno.h> 44#include <sys/conf.h> 45#include <sys/module.h> 46#include <sys/queue.h> 47#include <sys/syslog.h> 48#include <sys/endian.h> 49#include <sys/sysctl.h> 50#include <sys/condvar.h> |
51#include <vm/uma.h> |
|
51 52#include <sys/sockio.h> 53#include <sys/mbuf.h> 54#include <sys/socket.h> 55 56#include <net/if.h> 57#include <net/if_media.h> 58#include <net/if_atm.h> --- 456 unchanged lines hidden (view full) --- 515 wakeup(q); 516 } 517 } 518 utopia_reset_media(&sc->utopia); 519 } 520 sc->small_cnt = sc->large_cnt = 0; 521 522 /* Reset vcc info */ | 52 53#include <sys/sockio.h> 54#include <sys/mbuf.h> 55#include <sys/socket.h> 56 57#include <net/if.h> 58#include <net/if_media.h> 59#include <net/if_atm.h> --- 456 unchanged lines hidden (view full) --- 516 wakeup(q); 517 } 518 } 519 utopia_reset_media(&sc->utopia); 520 } 521 sc->small_cnt = sc->large_cnt = 0; 522 523 /* Reset vcc info */ |
523 if (sc->vccs != NULL) 524 for (i = 0; i <= FORE_MAX_VCC; i++) 525 sc->vccs[i].flags = 0; | 524 if (sc->vccs != NULL) { 525 for (i = 0; i < FORE_MAX_VCC + 1; i++) 526 if (sc->vccs[i] != NULL) { 527 uma_zfree(sc->vcc_zone, sc->vccs[i]); 528 sc->vccs[i] = NULL; 529 } 530 } |
526 527 sc->open_vccs = 0; 528} 529 530/* 531 * Load the firmware into the board and save the entry point. 532 */ 533static uint32_t --- 907 unchanged lines hidden (view full) --- 1441 * Check the receive queue. Send any received PDU up the protocol stack 1442 * (except when there was an error or the VCI appears to be closed. In this 1443 * case discard the PDU). 1444 */ 1445static void 1446fatm_intr_drain_rx(struct fatm_softc *sc) 1447{ 1448 struct rxqueue *q; | 531 532 sc->open_vccs = 0; 533} 534 535/* 536 * Load the firmware into the board and save the entry point. 537 */ 538static uint32_t --- 907 unchanged lines hidden (view full) --- 1446 * Check the receive queue. Send any received PDU up the protocol stack 1447 * (except when there was an error or the VCI appears to be closed. In this 1448 * case discard the PDU). 1449 */ 1450static void 1451fatm_intr_drain_rx(struct fatm_softc *sc) 1452{ 1453 struct rxqueue *q; |
1449 int stat, mlen, drop; | 1454 int stat, mlen; |
1450 u_int i; 1451 uint32_t h; 1452 struct mbuf *last, *m0; 1453 struct rpd *rpd; 1454 struct rbuf *rb; 1455 u_int vci, vpi, pt; 1456 struct atm_pseudohdr aph; 1457 struct ifnet *ifp; | 1455 u_int i; 1456 uint32_t h; 1457 struct mbuf *last, *m0; 1458 struct rpd *rpd; 1459 struct rbuf *rb; 1460 u_int vci, vpi, pt; 1461 struct atm_pseudohdr aph; 1462 struct ifnet *ifp; |
1463 struct card_vcc *vc; |
|
1458 1459 for (;;) { 1460 q = GET_QUEUE(sc->rxqueue, struct rxqueue, sc->rxqueue.tail); 1461 1462 H_SYNCSTAT_POSTREAD(sc, q->q.statp); 1463 stat = H_GETSTAT(q->q.statp); 1464 1465 if ((stat & FATM_STAT_COMPLETE) == 0) 1466 break; 1467 1468 rpd = (struct rpd *)q->q.ioblk; 1469 H_SYNCQ_POSTREAD(&sc->rxq_mem, rpd, RPD_SIZE); 1470 1471 rpd->nseg = le32toh(rpd->nseg); | 1464 1465 for (;;) { 1466 q = GET_QUEUE(sc->rxqueue, struct rxqueue, sc->rxqueue.tail); 1467 1468 H_SYNCSTAT_POSTREAD(sc, q->q.statp); 1469 stat = H_GETSTAT(q->q.statp); 1470 1471 if ((stat & FATM_STAT_COMPLETE) == 0) 1472 break; 1473 1474 rpd = (struct rpd *)q->q.ioblk; 1475 H_SYNCQ_POSTREAD(&sc->rxq_mem, rpd, RPD_SIZE); 1476 1477 rpd->nseg = le32toh(rpd->nseg); |
1472 drop = 0; | |
1473 mlen = 0; 1474 m0 = last = 0; 1475 for (i = 0; i < rpd->nseg; i++) { 1476 rb = sc->rbufs + rpd->segment[i].handle; 1477 if (m0 == NULL) { 1478 m0 = last = rb->m; 1479 } else { 1480 last->m_next = rb->m; --- 23 unchanged lines hidden (view full) --- 1504 vpi = (h >> 20) & 0xff; 1505 vci = (h >> 4 ) & 0xffff; 1506 pt = (h >> 1 ) & 0x7; 1507 1508 /* 1509 * Locate the VCC this packet belongs to 1510 */ 1511 if (!VC_OK(sc, vpi, vci)) | 1478 mlen = 0; 1479 m0 = last = 0; 1480 for (i = 0; i < rpd->nseg; i++) { 1481 rb = sc->rbufs + rpd->segment[i].handle; 1482 if (m0 == NULL) { 1483 m0 = last = rb->m; 1484 } else { 1485 last->m_next = rb->m; --- 23 unchanged lines hidden (view full) --- 1509 vpi = (h >> 20) & 0xff; 1510 vci = (h >> 4 ) & 0xffff; 1511 pt = (h >> 1 ) & 0x7; 1512 1513 /* 1514 * Locate the VCC this packet belongs to 1515 */ 1516 if (!VC_OK(sc, vpi, vci)) |
1512 drop = 1; 1513 else if ((sc->vccs[vci].flags & FATM_VCC_OPEN) == 0) { | 1517 vc = NULL; 1518 else if ((vc = sc->vccs[vci]) == NULL || 1519 !(sc->vccs[vci]->vflags & FATM_VCC_OPEN)) { |
1514 sc->istats.rx_closed++; | 1520 sc->istats.rx_closed++; |
1515 drop = 1; | 1521 vc = NULL; |
1516 } 1517 1518 DBG(sc, RCV, ("RCV: vc=%u.%u pt=%u mlen=%d %s", vpi, vci, | 1522 } 1523 1524 DBG(sc, RCV, ("RCV: vc=%u.%u pt=%u mlen=%d %s", vpi, vci, |
1519 pt, mlen, drop ? "dropped" : "")); | 1525 pt, mlen, vc == NULL ? "dropped" : "")); |
1520 | 1526 |
1521 if (drop) { | 1527 if (vc == NULL) { |
1522 m_freem(m0); 1523 } else { | 1528 m_freem(m0); 1529 } else { |
1524 ATM_PH_FLAGS(&aph) = sc->vccs[vci].flags & 0xff; | 1530 ATM_PH_FLAGS(&aph) = vc->param.flags; |
1525 ATM_PH_VPI(&aph) = vpi; 1526 ATM_PH_SETVCI(&aph, vci); 1527 1528 ifp = &sc->ifatm.ifnet; 1529 ifp->if_ipackets++; 1530 | 1531 ATM_PH_VPI(&aph) = vpi; 1532 ATM_PH_SETVCI(&aph, vci); 1533 1534 ifp = &sc->ifatm.ifnet; 1535 ifp->if_ipackets++; 1536 |
1531 atm_input(ifp, &aph, m0, sc->vccs[vci].rxhand); | 1537 vc->ipackets++; 1538 vc->ibytes += m0->m_pkthdr.len; 1539 1540 atm_input(ifp, &aph, m0, vc->rxhand); |
1532 } 1533 1534 H_SETSTAT(q->q.statp, FATM_STAT_FREE); 1535 H_SYNCSTAT_PREWRITE(sc, q->q.statp); 1536 1537 WRITE4(sc, q->q.card, q->q.card_ioblk); 1538 BARRIER_W(sc); 1539 --- 350 unchanged lines hidden (view full) --- 1890} 1891 1892/* 1893 * Start output. 1894 * 1895 * Note, that we update the internal statistics without the lock here. 1896 */ 1897static int | 1541 } 1542 1543 H_SETSTAT(q->q.statp, FATM_STAT_FREE); 1544 H_SYNCSTAT_PREWRITE(sc, q->q.statp); 1545 1546 WRITE4(sc, q->q.card, q->q.card_ioblk); 1547 BARRIER_W(sc); 1548 --- 350 unchanged lines hidden (view full) --- 1899} 1900 1901/* 1902 * Start output. 1903 * 1904 * Note, that we update the internal statistics without the lock here. 1905 */ 1906static int |
1898fatm_tx(struct fatm_softc *sc, struct mbuf *m, u_int vpi, u_int vci, u_int mlen) | 1907fatm_tx(struct fatm_softc *sc, struct mbuf *m, struct card_vcc *vc, u_int mlen) |
1899{ 1900 struct txqueue *q; 1901 u_int nblks; 1902 int error, aal, nsegs; 1903 struct tpd *tpd; 1904 1905 /* 1906 * Get a queue element. --- 36 unchanged lines hidden (view full) --- 1943 } 1944 nsegs = tpd->spec; 1945 1946 bus_dmamap_sync(sc->tx_tag, q->map, BUS_DMASYNC_PREWRITE); 1947 1948 /* 1949 * OK. Now go and do it. 1950 */ | 1908{ 1909 struct txqueue *q; 1910 u_int nblks; 1911 int error, aal, nsegs; 1912 struct tpd *tpd; 1913 1914 /* 1915 * Get a queue element. --- 36 unchanged lines hidden (view full) --- 1952 } 1953 nsegs = tpd->spec; 1954 1955 bus_dmamap_sync(sc->tx_tag, q->map, BUS_DMASYNC_PREWRITE); 1956 1957 /* 1958 * OK. Now go and do it. 1959 */ |
1951 aal = (sc->vccs[vci].aal == ATMIO_AAL_5) ? 5 : 0; | 1960 aal = (vc->param.aal == ATMIO_AAL_5) ? 5 : 0; |
1952 1953 H_SETSTAT(q->q.statp, FATM_STAT_PENDING); 1954 H_SYNCSTAT_PREWRITE(sc, q->q.statp); 1955 q->m = m; 1956 1957 /* 1958 * If the transmit queue is almost full, schedule a 1959 * transmit interrupt so that transmit descriptors can 1960 * be recycled. 1961 */ 1962 H_SETDESC(tpd->spec, TDX_MKSPEC((sc->txcnt >= 1963 (4 * FATM_TX_QLEN) / 5), aal, nsegs, mlen)); | 1961 1962 H_SETSTAT(q->q.statp, FATM_STAT_PENDING); 1963 H_SYNCSTAT_PREWRITE(sc, q->q.statp); 1964 q->m = m; 1965 1966 /* 1967 * If the transmit queue is almost full, schedule a 1968 * transmit interrupt so that transmit descriptors can 1969 * be recycled. 1970 */ 1971 H_SETDESC(tpd->spec, TDX_MKSPEC((sc->txcnt >= 1972 (4 * FATM_TX_QLEN) / 5), aal, nsegs, mlen)); |
1964 H_SETDESC(tpd->atm_header, TDX_MKHDR(vpi, vci, 0, 0)); | 1973 H_SETDESC(tpd->atm_header, TDX_MKHDR(vc->param.vpi, 1974 vc->param.vci, 0, 0)); |
1965 | 1975 |
1966 if (sc->vccs[vci].traffic == ATMIO_TRAFFIC_UBR) | 1976 if (vc->param.traffic == ATMIO_TRAFFIC_UBR) |
1967 H_SETDESC(tpd->stream, 0); 1968 else { 1969 u_int i; 1970 1971 for (i = 0; i < RATE_TABLE_SIZE; i++) | 1977 H_SETDESC(tpd->stream, 0); 1978 else { 1979 u_int i; 1980 1981 for (i = 0; i < RATE_TABLE_SIZE; i++) |
1972 if (rate_table[i].cell_rate < sc->vccs[vci].pcr) | 1982 if (rate_table[i].cell_rate < vc->param.tparam.pcr) |
1973 break; 1974 if (i > 0) 1975 i--; 1976 H_SETDESC(tpd->stream, rate_table[i].ratio); 1977 } 1978 H_SYNCQ_PREWRITE(&sc->txq_mem, tpd, TPD_SIZE); 1979 1980 nblks = TDX_SEGS2BLKS(nsegs); 1981 1982 DBG(sc, XMIT, ("XMIT: mlen=%d spec=0x%x nsegs=%d blocks=%d", 1983 mlen, le32toh(tpd->spec), nsegs, nblks)); 1984 1985 WRITE4(sc, q->q.card + 0, q->q.card_ioblk | nblks); 1986 BARRIER_W(sc); 1987 1988 sc->txcnt++; 1989 sc->ifatm.ifnet.if_opackets++; | 1983 break; 1984 if (i > 0) 1985 i--; 1986 H_SETDESC(tpd->stream, rate_table[i].ratio); 1987 } 1988 H_SYNCQ_PREWRITE(&sc->txq_mem, tpd, TPD_SIZE); 1989 1990 nblks = TDX_SEGS2BLKS(nsegs); 1991 1992 DBG(sc, XMIT, ("XMIT: mlen=%d spec=0x%x nsegs=%d blocks=%d", 1993 mlen, le32toh(tpd->spec), nsegs, nblks)); 1994 1995 WRITE4(sc, q->q.card + 0, q->q.card_ioblk | nblks); 1996 BARRIER_W(sc); 1997 1998 sc->txcnt++; 1999 sc->ifatm.ifnet.if_opackets++; |
2000 vc->obytes += m->m_pkthdr.len; 2001 vc->opackets++; |
|
1990 1991 NEXT_QUEUE_ENTRY(sc->txqueue.head, FATM_TX_QLEN); 1992 1993 return (0); 1994} 1995 1996static void 1997fatm_start(struct ifnet *ifp) 1998{ 1999 struct atm_pseudohdr aph; 2000 struct fatm_softc *sc; 2001 struct mbuf *m; 2002 u_int mlen, vpi, vci; | 2002 2003 NEXT_QUEUE_ENTRY(sc->txqueue.head, FATM_TX_QLEN); 2004 2005 return (0); 2006} 2007 2008static void 2009fatm_start(struct ifnet *ifp) 2010{ 2011 struct atm_pseudohdr aph; 2012 struct fatm_softc *sc; 2013 struct mbuf *m; 2014 u_int mlen, vpi, vci; |
2015 struct card_vcc *vc; |
|
2003 2004 sc = (struct fatm_softc *)ifp->if_softc; 2005 2006 while (1) { 2007 IF_DEQUEUE(&ifp->if_snd, m); 2008 if (m == NULL) 2009 break; 2010 --- 32 unchanged lines hidden (view full) --- 2043 * From here on we need the softc 2044 */ 2045 FATM_LOCK(sc); 2046 if (!(ifp->if_flags & IFF_RUNNING)) { 2047 FATM_UNLOCK(sc); 2048 m_freem(m); 2049 break; 2050 } | 2016 2017 sc = (struct fatm_softc *)ifp->if_softc; 2018 2019 while (1) { 2020 IF_DEQUEUE(&ifp->if_snd, m); 2021 if (m == NULL) 2022 break; 2023 --- 32 unchanged lines hidden (view full) --- 2056 * From here on we need the softc 2057 */ 2058 FATM_LOCK(sc); 2059 if (!(ifp->if_flags & IFF_RUNNING)) { 2060 FATM_UNLOCK(sc); 2061 m_freem(m); 2062 break; 2063 } |
2051 if (!VC_OK(sc, vpi, vci) || 2052 !(sc->vccs[vci].flags & FATM_VCC_OPEN)) { | 2064 if (!VC_OK(sc, vpi, vci) || (vc = sc->vccs[vci]) == NULL || 2065 !(vc->vflags & FATM_VCC_OPEN)) { |
2053 FATM_UNLOCK(sc); 2054 m_freem(m); 2055 continue; 2056 } | 2066 FATM_UNLOCK(sc); 2067 m_freem(m); 2068 continue; 2069 } |
2057 if (fatm_tx(sc, m, vpi, vci, mlen)) { | 2070 if (fatm_tx(sc, m, vc, mlen)) { |
2058 FATM_UNLOCK(sc); 2059 break; 2060 } 2061 FATM_UNLOCK(sc); 2062 } 2063} 2064 2065/* | 2071 FATM_UNLOCK(sc); 2072 break; 2073 } 2074 FATM_UNLOCK(sc); 2075 } 2076} 2077 2078/* |
2066 * Return a table of all currently open VCCs. 2067 */ 2068static struct atmio_vcctable * 2069get_vccs(struct fatm_softc *sc, int flags) 2070{ 2071 struct atmio_vcctable *vccs; 2072 struct atmio_vcc *v; 2073 u_int i, alloc; 2074 2075 alloc = 10; 2076 vccs = NULL; 2077 for (;;) { 2078 vccs = reallocf(vccs, 2079 sizeof(*vccs) + alloc * sizeof(vccs->vccs[0]), 2080 M_DEVBUF, flags); 2081 if (vccs == NULL) 2082 return (NULL); 2083 2084 vccs->count = 0; 2085 FATM_LOCK(sc); 2086 v = vccs->vccs; 2087 for (i = 0; i < (1U << sc->ifatm.mib.vci_bits); i++) { 2088 if (sc->vccs[i].flags & FATM_VCC_OPEN) { 2089 if (vccs->count++ == alloc) { 2090 alloc *= 2; 2091 break; 2092 } 2093 v->vpi = 0; 2094 v->vci = i; 2095 v->flags = sc->vccs[i].flags; 2096 v->aal = sc->vccs[i].aal; 2097 v->traffic = sc->vccs[i].traffic; 2098 bzero(&v->tparam, sizeof(v->tparam)); 2099 v->tparam.pcr = sc->vccs[i].pcr; 2100 v++; 2101 } 2102 } 2103 if (i == (1U << sc->ifatm.mib.vci_bits)) 2104 break; 2105 FATM_UNLOCK(sc); 2106 } 2107 FATM_UNLOCK(sc); 2108 return (vccs); 2109} 2110 2111/* | |
2112 * VCC managment 2113 * 2114 * This may seem complicated. The reason for this is, that we need an 2115 * asynchronuous open/close for the NATM VCCs because our ioctl handler 2116 * is called with the radix node head of the routing table locked. Therefor 2117 * we cannot sleep there and wait for the open/close to succeed. For this 2118 * reason we just initiate the operation from the ioctl. 2119 */ --- 28 unchanged lines hidden (view full) --- 2148 BARRIER_W(sc); 2149 WRITE4(sc, q->q.card + FATMOC_OP, cmd); 2150 BARRIER_W(sc); 2151 2152 return (q); 2153} 2154 2155/* | 2079 * VCC managment 2080 * 2081 * This may seem complicated. The reason for this is, that we need an 2082 * asynchronuous open/close for the NATM VCCs because our ioctl handler 2083 * is called with the radix node head of the routing table locked. Therefor 2084 * we cannot sleep there and wait for the open/close to succeed. For this 2085 * reason we just initiate the operation from the ioctl. 2086 */ --- 28 unchanged lines hidden (view full) --- 2115 BARRIER_W(sc); 2116 WRITE4(sc, q->q.card + FATMOC_OP, cmd); 2117 BARRIER_W(sc); 2118 2119 return (q); 2120} 2121 2122/* |
2156 * Start to open a VCC. This just initiates the operation. | 2123 * The VC has been opened/closed and somebody has been waiting for this. 2124 * Wake him up. |
2157 */ | 2125 */ |
2158static int 2159fatm_start_open_vcc(struct fatm_softc *sc, u_int vpi, u_int vci, u_int aal, 2160 u_int traffic, u_int pcr, u_int flags, void *rxhand, 2161 void (*func)(struct fatm_softc *, struct cmdqueue *), struct cmdqueue **qp) | 2126static void 2127fatm_cmd_complete(struct fatm_softc *sc, struct cmdqueue *q) |
2162{ | 2128{ |
2163 int error; 2164 uint32_t cmd; 2165 struct cmdqueue *q; | |
2166 | 2129 |
2167 error = 0; | 2130 H_SYNCSTAT_POSTREAD(sc, q->q.statp); 2131 if (H_GETSTAT(q->q.statp) & FATM_STAT_ERROR) { 2132 sc->istats.get_stat_errors++; 2133 q->error = EIO; 2134 } 2135 wakeup(q); 2136} |
2168 | 2137 |
2169 if (!(sc->ifatm.ifnet.if_flags & IFF_RUNNING)) 2170 return (EIO); 2171 if (!VC_OK(sc, vpi, vci) || 2172 (aal != ATMIO_AAL_0 && aal != ATMIO_AAL_5) || 2173 (traffic != ATMIO_TRAFFIC_UBR && traffic != ATMIO_TRAFFIC_CBR)) 2174 return (EINVAL); 2175 if (sc->vccs[vci].flags & FATM_VCC_BUSY) 2176 return (EBUSY); | 2138/* 2139 * Open complete 2140 */ 2141static void 2142fatm_open_finish(struct fatm_softc *sc, struct card_vcc *vc) 2143{ 2144 vc->vflags &= ~FATM_VCC_TRY_OPEN; 2145 vc->vflags |= FATM_VCC_OPEN; |
2177 | 2146 |
2178 /* Command and buffer strategy */ 2179 cmd = FATM_OP_ACTIVATE_VCIN | FATM_OP_INTERRUPT_SEL | (0 << 16); 2180 if (aal == ATMIO_AAL_0) 2181 cmd |= (0 << 8); 2182 else 2183 cmd |= (5 << 8); 2184 2185 if ((q = fatm_start_vcc(sc, vpi, vci, cmd, 1, func)) == NULL) 2186 return (EIO); 2187 if (qp != NULL) 2188 *qp = q; 2189 2190 sc->vccs[vci].aal = aal; 2191 sc->vccs[vci].flags = flags | FATM_VCC_TRY_OPEN; 2192 sc->vccs[vci].rxhand = rxhand; 2193 sc->vccs[vci].pcr = pcr; 2194 sc->vccs[vci].traffic = traffic; 2195 2196 return (0); | 2147 /* inform management if this is not an NG 2148 * VCC or it's an NG PVC. */ 2149 if (!(vc->param.flags & ATMIO_FLAG_NG) || 2150 (vc->param.flags & ATMIO_FLAG_PVC)) 2151 ATMEV_SEND_VCC_CHANGED(&sc->ifatm, 0, vc->param.vci, 1); |
2197} 2198 2199/* | 2152} 2153 2154/* |
2200 * Initiate closing a VCC | 2155 * The VC that we have tried to open asynchronuosly has been opened. |
2201 */ | 2156 */ |
2202static int 2203fatm_start_close_vcc(struct fatm_softc *sc, u_int vpi, u_int vci, 2204 void (*func)(struct fatm_softc *, struct cmdqueue *), struct cmdqueue **qp) | 2157static void 2158fatm_open_complete(struct fatm_softc *sc, struct cmdqueue *q) |
2205{ | 2159{ |
2206 int error; 2207 struct cmdqueue *q; | 2160 u_int vci; 2161 struct card_vcc *vc; |
2208 | 2162 |
2209 error = 0; 2210 2211 if (!(sc->ifatm.ifnet.if_flags & IFF_RUNNING)) 2212 return (EIO); 2213 if (!VC_OK(sc, vpi, vci)) 2214 return (EINVAL); 2215 if (!(sc->vccs[vci].flags & (FATM_VCC_OPEN | FATM_VCC_TRY_OPEN))) 2216 return (ENOENT); 2217 2218 if ((q = fatm_start_vcc(sc, vpi, vci, 2219 FATM_OP_DEACTIVATE_VCIN | FATM_OP_INTERRUPT_SEL, 1, func)) == NULL) 2220 return (EIO); 2221 2222 if (qp != NULL) 2223 *qp = q; 2224 2225 sc->vccs[vci].flags &= ~(FATM_VCC_OPEN | FATM_VCC_TRY_OPEN); 2226 sc->vccs[vci].flags |= FATM_VCC_TRY_CLOSE; 2227 2228 return (0); | 2163 vci = GETVCI(READ4(sc, q->q.card + FATMOC_ACTIN_VPVC)); 2164 vc = sc->vccs[vci]; 2165 H_SYNCSTAT_POSTREAD(sc, q->q.statp); 2166 if (H_GETSTAT(q->q.statp) & FATM_STAT_ERROR) { 2167 sc->istats.get_stat_errors++; 2168 sc->vccs[vci] = NULL; 2169 uma_zfree(sc->vcc_zone, vc); 2170 if_printf(&sc->ifatm.ifnet, "opening VCI %u failed\n", vci); 2171 return; 2172 } 2173 fatm_open_finish(sc, vc); |
2229} 2230 2231/* 2232 * Wait on the queue entry until the VCC is opened/closed. 2233 */ 2234static int 2235fatm_waitvcc(struct fatm_softc *sc, struct cmdqueue *q) 2236{ --- 5 unchanged lines hidden (view full) --- 2242 error = msleep(q, &sc->mtx, PZERO | PCATCH, "fatm_vci", hz); 2243 2244 if (error != 0) 2245 return (error); 2246 return (q->error); 2247} 2248 2249/* | 2174} 2175 2176/* 2177 * Wait on the queue entry until the VCC is opened/closed. 2178 */ 2179static int 2180fatm_waitvcc(struct fatm_softc *sc, struct cmdqueue *q) 2181{ --- 5 unchanged lines hidden (view full) --- 2187 error = msleep(q, &sc->mtx, PZERO | PCATCH, "fatm_vci", hz); 2188 2189 if (error != 0) 2190 return (error); 2191 return (q->error); 2192} 2193 2194/* |
2250 * The VC has been opened/closed and somebody has been waiting for this. 2251 * Wake him up. | 2195 * Start to open a VCC. This just initiates the operation. |
2252 */ | 2196 */ |
2253static void 2254fatm_cmd_complete(struct fatm_softc *sc, struct cmdqueue *q) 2255{ 2256 2257 H_SYNCSTAT_POSTREAD(sc, q->q.statp); 2258 if (H_GETSTAT(q->q.statp) & FATM_STAT_ERROR) { 2259 sc->istats.get_stat_errors++; 2260 q->error = EIO; 2261 } 2262 wakeup(q); 2263} 2264 2265/* 2266 * Open a vcc and wait for completion 2267 */ | |
2268static int | 2197static int |
2269fatm_open_vcc(struct fatm_softc *sc, u_int vpi, u_int vci, u_int flags, 2270 u_int aal, u_int traffic, u_int pcr, void *rxhand) | 2198fatm_open_vcc(struct fatm_softc *sc, struct atmio_openvcc *op, int wait) |
2271{ | 2199{ |
2200 uint32_t cmd; |
|
2272 int error; 2273 struct cmdqueue *q; | 2201 int error; 2202 struct cmdqueue *q; |
2203 struct card_vcc *vc; |
|
2274 | 2204 |
2205 /* 2206 * Check parameters 2207 */ 2208 if ((op->param.flags & ATMIO_FLAG_NOTX) && 2209 (op->param.flags & ATMIO_FLAG_NORX)) 2210 return (EINVAL); 2211 2212 if (!VC_OK(sc, op->param.vpi, op->param.vci)) 2213 return (EINVAL); 2214 if (op->param.aal != ATMIO_AAL_0 && op->param.aal != ATMIO_AAL_5) 2215 return (EINVAL); 2216 2217 vc = uma_zalloc(sc->vcc_zone, M_NOWAIT | M_ZERO); 2218 if (vc == NULL) 2219 return (ENOMEM); 2220 |
|
2275 error = 0; 2276 2277 FATM_LOCK(sc); | 2221 error = 0; 2222 2223 FATM_LOCK(sc); |
2278 error = fatm_start_open_vcc(sc, vpi, vci, aal, traffic, pcr, 2279 flags, rxhand, fatm_cmd_complete, &q); 2280 if (error != 0) { 2281 FATM_UNLOCK(sc); 2282 return (error); | 2224 if (!(sc->ifatm.ifnet.if_flags & IFF_RUNNING)) { 2225 error = EIO; 2226 goto done; |
2283 } | 2227 } |
2284 error = fatm_waitvcc(sc, q); | 2228 if (sc->vccs[op->param.vci] != NULL) { 2229 error = EBUSY; 2230 goto done; 2231 } 2232 vc->param = op->param; 2233 vc->rxhand = op->rxhand; |
2285 | 2234 |
2286 if (error == 0) { 2287 sc->vccs[vci].flags &= ~FATM_VCC_TRY_OPEN; 2288 sc->vccs[vci].flags |= FATM_VCC_OPEN; 2289 sc->open_vccs++; | 2235 switch (op->param.traffic) { |
2290 | 2236 |
2291 /* inform management if this is not an NG 2292 * VCC or it's an NG PVC. */ 2293 if (!(sc->vccs[vci].flags & ATMIO_FLAG_NG) || 2294 (sc->vccs[vci].flags & ATMIO_FLAG_PVC)) 2295 ATMEV_SEND_VCC_CHANGED(&sc->ifatm, 0, vci, 1); 2296 } else 2297 bzero(&sc->vccs[vci], sizeof(sc->vccs[vci])); | 2237 case ATMIO_TRAFFIC_UBR: 2238 break; |
2298 | 2239 |
2299 FATM_UNLOCK(sc); 2300 return (error); 2301} | 2240 case ATMIO_TRAFFIC_CBR: 2241 if (op->param.tparam.pcr == 0 || 2242 op->param.tparam.pcr > sc->ifatm.mib.pcr) { 2243 error = EINVAL; 2244 goto done; 2245 } 2246 break; |
2302 | 2247 |
2303/* 2304 * Close a VCC synchronuosly 2305 */ 2306static int 2307fatm_close_vcc(struct fatm_softc *sc, u_int vpi, u_int vci) 2308{ 2309 int error; 2310 struct cmdqueue *q; | 2248 default: 2249 error = EINVAL; 2250 goto done; 2251 return (EINVAL); 2252 } 2253 vc->ibytes = vc->obytes = 0; 2254 vc->ipackets = vc->opackets = 0; |
2311 | 2255 |
2312 error = 0; | 2256 /* Command and buffer strategy */ 2257 cmd = FATM_OP_ACTIVATE_VCIN | FATM_OP_INTERRUPT_SEL | (0 << 16); 2258 if (op->param.aal == ATMIO_AAL_0) 2259 cmd |= (0 << 8); 2260 else 2261 cmd |= (5 << 8); |
2313 | 2262 |
2314 FATM_LOCK(sc); 2315 error = fatm_start_close_vcc(sc, vpi, vci, fatm_cmd_complete, &q); 2316 if (error != 0) { 2317 FATM_UNLOCK(sc); 2318 return (error); | 2263 q = fatm_start_vcc(sc, op->param.vpi, op->param.vci, cmd, 1, 2264 wait ? fatm_cmd_complete : fatm_open_complete); 2265 if (q == NULL) { 2266 error = EIO; 2267 goto done; |
2319 } | 2268 } |
2320 error = fatm_waitvcc(sc, q); | |
2321 | 2269 |
2322 if (error == 0) { 2323 /* inform management of this is not an NG 2324 * VCC or it's an NG PVC. */ 2325 if (!(sc->vccs[vci].flags & ATMIO_FLAG_NG) || 2326 (sc->vccs[vci].flags & ATMIO_FLAG_PVC)) 2327 ATMEV_SEND_VCC_CHANGED(&sc->ifatm, 0, vci, 0); | 2270 vc->vflags = FATM_VCC_TRY_OPEN; 2271 sc->vccs[op->param.vci] = vc; 2272 sc->open_vccs++; |
2328 | 2273 |
2329 bzero(&sc->vccs[vci], sizeof(sc->vccs[vci])); 2330 sc->open_vccs--; | 2274 if (wait) { 2275 error = fatm_waitvcc(sc, q); 2276 if (error != 0) { 2277 sc->vccs[op->param.vci] = NULL; 2278 sc->open_vccs--; 2279 goto done; 2280 } 2281 fatm_open_finish(sc, vc); |
2331 } 2332 | 2282 } 2283 |
2284 /* don't free below */ 2285 vc = NULL; 2286 2287 done: |
|
2333 FATM_UNLOCK(sc); | 2288 FATM_UNLOCK(sc); |
2289 if (vc != NULL) 2290 uma_zfree(sc->vcc_zone, vc); |
|
2334 return (error); 2335} 2336 2337/* | 2291 return (error); 2292} 2293 2294/* |
2338 * The VC has been opened. | 2295 * Finish close |
2339 */ 2340static void | 2296 */ 2297static void |
2341fatm_open_complete(struct fatm_softc *sc, struct cmdqueue *q) | 2298fatm_close_finish(struct fatm_softc *sc, struct card_vcc *vc) |
2342{ | 2299{ |
2343 u_int vci; | 2300 /* inform management of this is not an NG 2301 * VCC or it's an NG PVC. */ 2302 if (!(vc->param.flags & ATMIO_FLAG_NG) || 2303 (vc->param.flags & ATMIO_FLAG_PVC)) 2304 ATMEV_SEND_VCC_CHANGED(&sc->ifatm, 0, vc->param.vci, 0); |
2344 | 2305 |
2345 vci = GETVCI(READ4(sc, q->q.card + FATMOC_ACTIN_VPVC)); 2346 H_SYNCSTAT_POSTREAD(sc, q->q.statp); 2347 if (H_GETSTAT(q->q.statp) & FATM_STAT_ERROR) { 2348 sc->istats.get_stat_errors++; 2349 bzero(&sc->vccs[vci], sizeof(sc->vccs[vci])); 2350 if_printf(&sc->ifatm.ifnet, "opening VCI %u failed\n", vci); 2351 return; 2352 } | 2306 sc->vccs[vc->param.vci] = NULL; 2307 sc->open_vccs--; |
2353 | 2308 |
2354 sc->vccs[vci].flags &= ~FATM_VCC_TRY_OPEN; 2355 sc->vccs[vci].flags |= FATM_VCC_OPEN; 2356 sc->open_vccs++; 2357 2358 /* inform management if this is not an NG 2359 * VCC or it's an NG PVC. */ 2360 if (!(sc->vccs[vci].flags & ATMIO_FLAG_NG) || 2361 (sc->vccs[vci].flags & ATMIO_FLAG_PVC)) 2362 ATMEV_SEND_VCC_CHANGED(&sc->ifatm, 0, vci, 1); | 2309 uma_zfree(sc->vcc_zone, vc); |
2363} 2364 2365/* 2366 * The VC has been closed. 2367 */ 2368static void 2369fatm_close_complete(struct fatm_softc *sc, struct cmdqueue *q) 2370{ 2371 u_int vci; | 2310} 2311 2312/* 2313 * The VC has been closed. 2314 */ 2315static void 2316fatm_close_complete(struct fatm_softc *sc, struct cmdqueue *q) 2317{ 2318 u_int vci; |
2319 struct card_vcc *vc; |
|
2372 2373 vci = GETVCI(READ4(sc, q->q.card + FATMOC_ACTIN_VPVC)); | 2320 2321 vci = GETVCI(READ4(sc, q->q.card + FATMOC_ACTIN_VPVC)); |
2322 vc = sc->vccs[vci]; |
|
2374 H_SYNCSTAT_POSTREAD(sc, q->q.statp); 2375 if (H_GETSTAT(q->q.statp) & FATM_STAT_ERROR) { 2376 sc->istats.get_stat_errors++; 2377 /* keep the VCC in that state */ 2378 if_printf(&sc->ifatm.ifnet, "closing VCI %u failed\n", vci); 2379 return; 2380 } 2381 | 2323 H_SYNCSTAT_POSTREAD(sc, q->q.statp); 2324 if (H_GETSTAT(q->q.statp) & FATM_STAT_ERROR) { 2325 sc->istats.get_stat_errors++; 2326 /* keep the VCC in that state */ 2327 if_printf(&sc->ifatm.ifnet, "closing VCI %u failed\n", vci); 2328 return; 2329 } 2330 |
2382 /* inform management of this is not an NG 2383 * VCC or it's an NG PVC. */ 2384 if (!(sc->vccs[vci].flags & ATMIO_FLAG_NG) || 2385 (sc->vccs[vci].flags & ATMIO_FLAG_PVC)) 2386 ATMEV_SEND_VCC_CHANGED(&sc->ifatm, 0, vci, 0); 2387 2388 bzero(&sc->vccs[vci], sizeof(sc->vccs[vci])); 2389 sc->open_vccs--; | 2331 fatm_close_finish(sc, vc); |
2390} 2391 2392/* | 2332} 2333 2334/* |
2393 * Open a vcc but don't wait. | 2335 * Initiate closing a VCC |
2394 */ 2395static int | 2336 */ 2337static int |
2396fatm_open_vcc_nowait(struct fatm_softc *sc, u_int vpi, u_int vci, u_int flags, 2397 u_int aal, void *rxhand) | 2338fatm_close_vcc(struct fatm_softc *sc, struct atmio_closevcc *cl, int wait) |
2398{ 2399 int error; | 2339{ 2340 int error; |
2341 struct cmdqueue *q; 2342 struct card_vcc *vc; |
|
2400 | 2343 |
2401 FATM_LOCK(sc); 2402 error = fatm_start_open_vcc(sc, vpi, vci, aal, ATMIO_TRAFFIC_UBR, 0, 2403 flags, rxhand, fatm_open_complete, NULL); 2404 FATM_UNLOCK(sc); 2405 return (error); 2406} | 2344 if (!VC_OK(sc, cl->vpi, cl->vci)) 2345 return (EINVAL); |
2407 | 2346 |
2408/* 2409 * Close a VCC but don't wait 2410 */ 2411static int 2412fatm_close_vcc_nowait(struct fatm_softc *sc, u_int vpi, u_int vci) 2413{ 2414 int error; | 2347 error = 0; |
2415 2416 FATM_LOCK(sc); | 2348 2349 FATM_LOCK(sc); |
2417 error = fatm_start_close_vcc(sc, vpi, vci, fatm_close_complete, NULL); | 2350 if (!(sc->ifatm.ifnet.if_flags & IFF_RUNNING)) { 2351 error = EIO; 2352 goto done; 2353 } 2354 vc = sc->vccs[cl->vci]; 2355 if (vc == NULL || !(vc->vflags & (FATM_VCC_OPEN | FATM_VCC_TRY_OPEN))) { 2356 error = ENOENT; 2357 goto done; 2358 } 2359 2360 q = fatm_start_vcc(sc, cl->vpi, cl->vci, 2361 FATM_OP_DEACTIVATE_VCIN | FATM_OP_INTERRUPT_SEL, 1, 2362 wait ? fatm_cmd_complete : fatm_close_complete); 2363 if (q == NULL) { 2364 error = EIO; 2365 goto done; 2366 } 2367 2368 vc->vflags &= ~(FATM_VCC_OPEN | FATM_VCC_TRY_OPEN); 2369 vc->vflags |= FATM_VCC_TRY_CLOSE; 2370 2371 if (wait) { 2372 error = fatm_waitvcc(sc, q); 2373 if (error != 0) 2374 goto done; 2375 2376 fatm_close_finish(sc, vc); 2377 } 2378 2379 done: |
2418 FATM_UNLOCK(sc); 2419 return (error); 2420} 2421 2422/* 2423 * IOCTL handler 2424 */ 2425static int 2426fatm_ioctl(struct ifnet *ifp, u_long cmd, caddr_t arg) 2427{ 2428 int error; 2429 struct fatm_softc *sc = ifp->if_softc; 2430 struct ifaddr *ifa = (struct ifaddr *)arg; 2431 struct ifreq *ifr = (struct ifreq *)arg; 2432 struct atmio_closevcc *cl = (struct atmio_closevcc *)arg; 2433 struct atmio_openvcc *op = (struct atmio_openvcc *)arg; 2434 struct atm_pseudoioctl *pa = (struct atm_pseudoioctl *)arg; 2435 struct atmio_vcctable *vtab; | 2380 FATM_UNLOCK(sc); 2381 return (error); 2382} 2383 2384/* 2385 * IOCTL handler 2386 */ 2387static int 2388fatm_ioctl(struct ifnet *ifp, u_long cmd, caddr_t arg) 2389{ 2390 int error; 2391 struct fatm_softc *sc = ifp->if_softc; 2392 struct ifaddr *ifa = (struct ifaddr *)arg; 2393 struct ifreq *ifr = (struct ifreq *)arg; 2394 struct atmio_closevcc *cl = (struct atmio_closevcc *)arg; 2395 struct atmio_openvcc *op = (struct atmio_openvcc *)arg; 2396 struct atm_pseudoioctl *pa = (struct atm_pseudoioctl *)arg; 2397 struct atmio_vcctable *vtab; |
2398 struct atmio_openvcc ena; 2399 struct atmio_closevcc dis; |
|
2436 2437 error = 0; 2438 switch (cmd) { 2439 2440 case SIOCATMENA: /* internal NATM use */ | 2400 2401 error = 0; 2402 switch (cmd) { 2403 2404 case SIOCATMENA: /* internal NATM use */ |
2441 error = fatm_open_vcc_nowait(sc, ATM_PH_VPI(&pa->aph), 2442 ATM_PH_VCI(&pa->aph), ATM_PH_FLAGS(&pa->aph), 2443 (ATM_PH_FLAGS(&pa->aph) & ATM_PH_AAL5) ? ATMIO_AAL_5 : 2444 ATMIO_AAL_0, pa->rxhand); | 2405 bzero(&ena, sizeof(ena)); 2406 ena.param.flags = ATM_PH_FLAGS(&pa->aph) & 2407 (ATM_PH_AAL5 | ATM_PH_LLCSNAP); 2408 ena.param.vpi = ATM_PH_VPI(&pa->aph); 2409 ena.param.vci = ATM_PH_VCI(&pa->aph); 2410 ena.param.aal = (ATM_PH_FLAGS(&pa->aph) & ATM_PH_AAL5) ? 2411 ATMIO_AAL_5 : ATMIO_AAL_0; 2412 ena.param.traffic = ATMIO_TRAFFIC_UBR; 2413 ena.rxhand = pa->rxhand; 2414 error = fatm_open_vcc(sc, &ena, 0); |
2445 break; 2446 2447 case SIOCATMDIS: /* internal NATM use */ | 2415 break; 2416 2417 case SIOCATMDIS: /* internal NATM use */ |
2448 error = fatm_close_vcc_nowait(sc, ATM_PH_VPI(&pa->aph), 2449 ATM_PH_VCI(&pa->aph)); | 2418 bzero(&dis, sizeof(dis)); 2419 dis.vpi = ATM_PH_VPI(&pa->aph); 2420 dis.vci = ATM_PH_VCI(&pa->aph); 2421 error = fatm_close_vcc(sc, &dis, 0); |
2450 break; 2451 2452 case SIOCATMOPENVCC: | 2422 break; 2423 2424 case SIOCATMOPENVCC: |
2453 error = fatm_open_vcc(sc, op->param.vpi, op->param.vci, 2454 op->param.flags, op->param.aal, op->param.traffic, 2455 op->param.tparam.pcr, op->rxhand); | 2425 error = fatm_open_vcc(sc, op, 1); |
2456 break; 2457 2458 case SIOCATMCLOSEVCC: | 2426 break; 2427 2428 case SIOCATMCLOSEVCC: |
2459 error = fatm_close_vcc(sc, cl->vpi, cl->vci); | 2429 error = fatm_close_vcc(sc, cl, 1); |
2460 break; 2461 2462 case SIOCSIFADDR: 2463 FATM_LOCK(sc); 2464 ifp->if_flags |= IFF_UP; 2465 if (!(ifp->if_flags & IFF_RUNNING)) 2466 fatm_init_locked(sc); 2467 switch (ifa->ifa_addr->sa_family) { --- 28 unchanged lines hidden (view full) --- 2496 if (ifp->if_flags & IFF_RUNNING) 2497 error = ifmedia_ioctl(ifp, ifr, &sc->media, cmd); 2498 else 2499 error = EINVAL; 2500 break; 2501 2502 case SIOCATMGVCCS: 2503 /* return vcc table */ | 2430 break; 2431 2432 case SIOCSIFADDR: 2433 FATM_LOCK(sc); 2434 ifp->if_flags |= IFF_UP; 2435 if (!(ifp->if_flags & IFF_RUNNING)) 2436 fatm_init_locked(sc); 2437 switch (ifa->ifa_addr->sa_family) { --- 28 unchanged lines hidden (view full) --- 2466 if (ifp->if_flags & IFF_RUNNING) 2467 error = ifmedia_ioctl(ifp, ifr, &sc->media, cmd); 2468 else 2469 error = EINVAL; 2470 break; 2471 2472 case SIOCATMGVCCS: 2473 /* return vcc table */ |
2504 vtab = get_vccs(sc, M_WAITOK); 2505 if (vtab == NULL) { 2506 error = ENOMEM; 2507 break; 2508 } | 2474 vtab = atm_getvccs((struct atmio_vcc **)sc->vccs, 2475 FORE_MAX_VCC + 1, sc->open_vccs, &sc->mtx, 1); |
2509 error = copyout(vtab, ifr->ifr_data, sizeof(*vtab) + 2510 vtab->count * sizeof(vtab->vccs[0])); 2511 free(vtab, M_DEVBUF); 2512 break; 2513 2514 case SIOCATMGETVCCS: /* internal netgraph use */ | 2476 error = copyout(vtab, ifr->ifr_data, sizeof(*vtab) + 2477 vtab->count * sizeof(vtab->vccs[0])); 2478 free(vtab, M_DEVBUF); 2479 break; 2480 2481 case SIOCATMGETVCCS: /* internal netgraph use */ |
2515 vtab = get_vccs(sc, M_NOWAIT); | 2482 vtab = atm_getvccs((struct atmio_vcc **)sc->vccs, 2483 FORE_MAX_VCC + 1, sc->open_vccs, &sc->mtx, 0); |
2516 if (vtab == NULL) { 2517 error = ENOMEM; 2518 break; 2519 } 2520 *(void **)arg = vtab; 2521 break; 2522 2523 default: --- 45 unchanged lines hidden (view full) --- 2569 } 2570 } 2571 2572 while ((rb = LIST_FIRST(&sc->rbuf_free)) != NULL) { 2573 bus_dmamap_destroy(sc->rbuf_tag, rb->map); 2574 LIST_REMOVE(rb, link); 2575 } 2576 | 2484 if (vtab == NULL) { 2485 error = ENOMEM; 2486 break; 2487 } 2488 *(void **)arg = vtab; 2489 break; 2490 2491 default: --- 45 unchanged lines hidden (view full) --- 2537 } 2538 } 2539 2540 while ((rb = LIST_FIRST(&sc->rbuf_free)) != NULL) { 2541 bus_dmamap_destroy(sc->rbuf_tag, rb->map); 2542 LIST_REMOVE(rb, link); 2543 } 2544 |
2577 free(sc->rbufs, M_DEVBUF); 2578 free(sc->vccs, M_DEVBUF); | 2545 if (sc->rbufs != NULL) 2546 free(sc->rbufs, M_DEVBUF); 2547 if (sc->vccs != NULL) 2548 free(sc->vccs, M_DEVBUF); 2549 if (sc->vcc_zone != NULL) 2550 uma_zdestroy(sc->vcc_zone); |
2579 | 2551 |
2580 free(sc->l1queue.chunk, M_DEVBUF); 2581 free(sc->s1queue.chunk, M_DEVBUF); 2582 free(sc->rxqueue.chunk, M_DEVBUF); 2583 free(sc->txqueue.chunk, M_DEVBUF); 2584 free(sc->cmdqueue.chunk, M_DEVBUF); | 2552 if (sc->l1queue.chunk != NULL) 2553 free(sc->l1queue.chunk, M_DEVBUF); 2554 if (sc->s1queue.chunk != NULL) 2555 free(sc->s1queue.chunk, M_DEVBUF); 2556 if (sc->rxqueue.chunk != NULL) 2557 free(sc->rxqueue.chunk, M_DEVBUF); 2558 if (sc->txqueue.chunk != NULL) 2559 free(sc->txqueue.chunk, M_DEVBUF); 2560 if (sc->cmdqueue.chunk != NULL) 2561 free(sc->cmdqueue.chunk, M_DEVBUF); |
2585 2586 destroy_dma_memory(&sc->reg_mem); 2587 destroy_dma_memory(&sc->sadi_mem); 2588 destroy_dma_memory(&sc->prom_mem); 2589#ifdef TEST_DMA_SYNC 2590 destroy_dma_memoryX(&sc->s1q_mem); 2591 destroy_dma_memoryX(&sc->l1q_mem); 2592 destroy_dma_memoryX(&sc->rxq_mem); --- 371 unchanged lines hidden (view full) --- 2964 M_DEVBUF, M_ZERO | M_WAITOK); 2965 sc->rxqueue.chunk = malloc(FATM_RX_QLEN * sizeof(struct rxqueue), 2966 M_DEVBUF, M_ZERO | M_WAITOK); 2967 sc->s1queue.chunk = malloc(SMALL_SUPPLY_QLEN * sizeof(struct supqueue), 2968 M_DEVBUF, M_ZERO | M_WAITOK); 2969 sc->l1queue.chunk = malloc(LARGE_SUPPLY_QLEN * sizeof(struct supqueue), 2970 M_DEVBUF, M_ZERO | M_WAITOK); 2971 | 2562 2563 destroy_dma_memory(&sc->reg_mem); 2564 destroy_dma_memory(&sc->sadi_mem); 2565 destroy_dma_memory(&sc->prom_mem); 2566#ifdef TEST_DMA_SYNC 2567 destroy_dma_memoryX(&sc->s1q_mem); 2568 destroy_dma_memoryX(&sc->l1q_mem); 2569 destroy_dma_memoryX(&sc->rxq_mem); --- 371 unchanged lines hidden (view full) --- 2941 M_DEVBUF, M_ZERO | M_WAITOK); 2942 sc->rxqueue.chunk = malloc(FATM_RX_QLEN * sizeof(struct rxqueue), 2943 M_DEVBUF, M_ZERO | M_WAITOK); 2944 sc->s1queue.chunk = malloc(SMALL_SUPPLY_QLEN * sizeof(struct supqueue), 2945 M_DEVBUF, M_ZERO | M_WAITOK); 2946 sc->l1queue.chunk = malloc(LARGE_SUPPLY_QLEN * sizeof(struct supqueue), 2947 M_DEVBUF, M_ZERO | M_WAITOK); 2948 |
2972 sc->vccs = malloc((FORE_MAX_VCC + 1) * sizeof(struct card_vcc), | 2949 sc->vccs = malloc((FORE_MAX_VCC + 1) * sizeof(sc->vccs[0]), |
2973 M_DEVBUF, M_ZERO | M_WAITOK); | 2950 M_DEVBUF, M_ZERO | M_WAITOK); |
2951 sc->vcc_zone = uma_zcreate("FATM vccs", sizeof(struct card_vcc), 2952 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); 2953 if (sc->vcc_zone == NULL) { 2954 error = ENOMEM; 2955 goto fail; 2956 } |
|
2974 2975 /* 2976 * Allocate memory for the receive buffer headers. The total number 2977 * of headers should probably also include the maximum number of 2978 * buffers on the receive queue. 2979 */ 2980 sc->rbuf_total = SMALL_POOL_SIZE + LARGE_POOL_SIZE; 2981 sc->rbufs = malloc(sc->rbuf_total * sizeof(struct rbuf), --- 94 unchanged lines hidden --- | 2957 2958 /* 2959 * Allocate memory for the receive buffer headers. The total number 2960 * of headers should probably also include the maximum number of 2961 * buffers on the receive queue. 2962 */ 2963 sc->rbuf_total = SMALL_POOL_SIZE + LARGE_POOL_SIZE; 2964 sc->rbufs = malloc(sc->rbuf_total * sizeof(struct rbuf), --- 94 unchanged lines hidden --- |