Implement the ioctl that returns a list of currently open VCCs.

This commit is contained in:
harti 2003-06-13 13:50:38 +00:00
parent b070cce27b
commit 4e6a5b6856

View File

@ -1457,6 +1457,55 @@ en_init(struct en_softc *sc)
/*
* Ioctls
*/
/*
* Return a table of all currently open VCCs.
*/
static struct atmio_vcctable *
en_get_vccs(struct en_softc *sc, int flags)
{
struct atmio_vcctable *vccs;
struct atmio_vcc *v;
u_int vci, alloc, slot;
alloc = 10;
vccs = NULL;
do {
vccs = reallocf(vccs,
sizeof(*vccs) + alloc * sizeof(vccs->vccs[0]),
M_TEMP, flags);
if (vccs == NULL)
return (NULL);
vccs->count = 0;
v = vccs->vccs;
EN_LOCK(sc);
for (vci = 0; vci < MID_N_VC; vci++) {
if ((slot = sc->rxvc2slot[vci]) == RX_NONE ||
(sc->rxslot[slot].oth_flags &
(ENOTHER_FREE | ENOTHER_DRAIN)) != 0)
continue;
if (vccs->count++ == alloc) {
alloc *= 2;
break;
}
bzero(v, sizeof(*v));
v->flags = ATMIO_FLAG_PVC | sc->rxslot[slot].atm_flags;
v->vpi = 0;
v->vci = vci;
if (sc->rxslot[slot].atm_flags & ATM_PH_AAL5)
v->aal = ATMIO_AAL_5;
else
v->aal = ATMIO_AAL_0;
v->traffic = ATMIO_TRAFFIC_UBR;
v->tparam.pcr = sc->ifatm.mib.pcr;
v++;
}
EN_UNLOCK(sc);
} while (vci < MID_N_VC);
return (vccs);
}
/*
* en_ioctl: handle ioctl requests
@ -1476,6 +1525,7 @@ en_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
struct ifaddr *ifa = (struct ifaddr *)data;
struct ifreq *ifr = (struct ifreq *)data;
struct atm_pseudoioctl *api = (struct atm_pseudoioctl *)data;
struct atmio_vcctable *vtab;
int error = 0;
switch (cmd) {
@ -1538,6 +1588,26 @@ en_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
error = ifmedia_ioctl(ifp, ifr, &sc->media, cmd);
break;
case SIOCATMGETVCCS: /* internal netgraph use */
vtab = en_get_vccs(sc, M_NOWAIT);
if (vtab == NULL) {
error = ENOMEM;
break;
}
*(void **)data = vtab;
break;
case SIOCATMGVCCS: /* return vcc table */
vtab = en_get_vccs(sc, M_WAITOK);
if (vtab == NULL) {
error = ENOMEM;
break;
}
error = copyout(vtab, ifr->ifr_data, sizeof(*vtab) +
vtab->count * sizeof(vtab->vccs[0]));
free(vtab, M_DEVBUF);
break;
default:
error = EINVAL;
break;