Implement the ioctl that returns a list of currently open VCCs.
This commit is contained in:
parent
b070cce27b
commit
4e6a5b6856
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user