Ejemplo n.º 1
0
Archivo: devuart.c Proyecto: 8l/inferno
/*
 *  all uarts must be uartsetup() by this point or inside of uartinstall()
 */
static void
uartreset(void)
{
	int i;
	Dirtab *dp;

	uartinstall();

	ndir = 1+3*nuart;
	uartdir = xalloc(ndir * sizeof(Dirtab));
	dp = uartdir;
	strcpy(dp->name, ".");
	mkqid(&dp->qid, 0, 0, QTDIR);
	dp->length = 0;
	dp->perm = DMDIR|0555;
	dp++;
	for(i = 0; i < nuart; i++){
		/* 3 directory entries per port */
		strcpy(dp->name, uart[i]->name);
		dp->qid.path = NETQID(i, Ndataqid);
		dp->perm = 0660;
		dp++;
		sprint(dp->name, "%sctl", uart[i]->name);
		dp->qid.path = NETQID(i, Nctlqid);
		dp->perm = 0660;
		dp++;
		sprint(dp->name, "%sstatus", uart[i]->name);
		dp->qid.path = NETQID(i, Nstatqid);
		dp->perm = 0444;
		dp++;
	}
}
Ejemplo n.º 2
0
static void
eiainit(void)
{
	int i, nports;
	Dirtab *dp;
	struct stat sb;

#ifdef buildsysdev
	buildsysdev();
#endif

	/* check to see which ports exist by trying to stat them */
	nports = 0;
	for (i=0; i < nelem(sysdev); i++) {
		if(stat(sysdev[i], &sb) < 0)
			break;

		nports++;
	}

	if (!nports)
		return;

	ndir = Nqid*nports+1;
	dp = eiadir = malloc(ndir*sizeof(Dirtab));
	if(dp == 0)
		panic("eiainit");
	strcpy(dp->name, ".");
	dp->qid.path = 0;
	dp->qid.type = QTDIR;
	dp->perm = DMDIR|0555;
	dp++;
	eia = malloc(nports*sizeof(Eia));
	if(eia == 0)
		panic("eiainit");
	for(i = 0; i < nports; i++) {
		sprint(dp->name, "%s%d", Devname, i);
		dp->qid.path = NETQID(i, Ndataqid);
		dp->perm = 0660;
		dp++;
		sprint(dp->name, "%s%dctl", Devname, i);
		dp->qid.path = NETQID(i, Nctlqid);
		dp->perm = 0660;
		dp++;
		sprint(dp->name, "%s%dstatus", Devname, i);
		dp->qid.path = NETQID(i, Nstatqid);
		dp->perm = 0660;
		dp++;
		eia[i].frame = eia[i].overrun = 0;
		eia[i].restore = eia[i].dtr = eia[i].rts = eia[i].cts = 0;
	}
}
Ejemplo n.º 3
0
static int
pipegen(Chan *c, char*, Dirtab *tab, int ntab, int i, Dir *dp)
{
	Qid q;
	int len;
	Pipe *p;

	if(i == DEVDOTDOT){
		devdir(c, c->qid, "#|", 0, eve, DMDIR|0555, dp);
		return 1;
	}
	i++;	/* skip . */
	if(tab==0 || i>=ntab)
		return -1;

	tab += i;
	p = c->aux;
	switch((ulong)tab->qid.path){
	case Qdata0:
		len = qlen(p->q[0]);
		break;
	case Qdata1:
		len = qlen(p->q[1]);
		break;
	default:
		len = tab->length;
		break;
	}
	mkqid(&q, NETQID(NETID(c->qid.path), tab->qid.path), 0, QTFILE);
	devdir(c, q, tab->name, len, eve, p->perm, dp);
	return 1;
}
Ejemplo n.º 4
0
static int
pipegen(Chan *c, char *name, Dirtab *tab, int ntab, int i, Dir *dp)
{
	int id, len;
	Qid qid;
	Pipe *p;

	USED(name);
	if(i == DEVDOTDOT){
		devdir(c, c->qid, "#|", 0, eve, 0555, dp);
		return 1;
	}
	i++;	/* skip . */
	if(tab==0 || i>=ntab)
		return -1;
	tab += i;
	p = c->aux;
	switch(NETTYPE(tab->qid.path)){
	case Qdata0:
		len = qlen(p->q[0]);
		break;
	case Qdata1:
		len = qlen(p->q[1]);
		break;
	default:
		len = tab->length;
		break;
	}
	id = NETID(c->qid.path);
	qid.path = NETQID(id, tab->qid.path);
	qid.vers = 0;
	qid.type = QTFILE;
	devdir(c, qid, tab->name, len, eve, tab->perm, dp);
	return 1;
}
Ejemplo n.º 5
0
/*
 *  create a pipe, no streams are created until an open
 */
static Chan*
pipeattach(char *spec)
{
	Pipe *p;
	Chan *c;

	c = devattach('|', spec);
	p = malloc(sizeof(Pipe));
	if(p == 0)
		exhausted("memory");
	p->ref = 1;

	p->q[0] = qopen(conf.pipeqsize, 0, 0, 0);
	if(p->q[0] == 0){
		free(p);
		exhausted("memory");
	}
	p->q[1] = qopen(conf.pipeqsize, 0, 0, 0);
	if(p->q[1] == 0){
		free(p->q[0]);
		free(p);
		exhausted("memory");
	}

	lock(&pipealloc.lk);
	p->path = ++pipealloc.path;
	unlock(&pipealloc.lk);

	mkqid(&c->qid, NETQID(2*p->path, Qdir), 0, QTDIR);
	c->aux = p;
	c->dev = 0;
	return c;
}
Ejemplo n.º 6
0
/*
 *  create a pipe, no streams are created until an open
 */
static struct chan *pipeattach(char *spec)
{
	ERRSTACK(2);
	Pipe *p;
	struct chan *c;

	c = devattach(devname(), spec);
	p = kzmalloc(sizeof(Pipe), 0);
	if (p == 0)
		error(ENOMEM, ERROR_FIXME);
	if (waserror()) {
		freepipe(p);
		nexterror();
	}
	p->pipedir = kzmalloc(sizeof(pipedir), 0);
	if (p->pipedir == 0)
		error(ENOMEM, ERROR_FIXME);
	memmove(p->pipedir, pipedir, sizeof(pipedir));
	kstrdup(&p->user, current->user);
	kref_init(&p->ref, pipe_release, 1);
	qlock_init(&p->qlock);

	p->q[0] = qopen(pipealloc.pipeqsize, Qcoalesce, 0, 0);
	if (p->q[0] == 0)
		error(ENOMEM, ERROR_FIXME);
	p->q[1] = qopen(pipealloc.pipeqsize, Qcoalesce, 0, 0);
	if (p->q[1] == 0)
		error(ENOMEM, ERROR_FIXME);
	poperror();

	spin_lock(&(&pipealloc)->lock);
	p->path = ++pipealloc.path;
	spin_unlock(&(&pipealloc)->lock);

	c->qid.path = NETQID(2 * p->path, Qdir);
	c->qid.vers = 0;
	c->qid.type = QTDIR;
	c->aux = p;
	c->dev = 0;

	/* taps. */
	SLIST_INIT(&p->data_taps[0]);	/* already = 0; set to be futureproof */
	SLIST_INIT(&p->data_taps[1]);
	spinlock_init(&p->tap_lock);
	return c;
}
Ejemplo n.º 7
0
Chan*
netifopen(Netif *nif, Chan *c, int omode)
{
	Proc *up = externup();
	int id;
	Netfile *f;

	id = 0;
	if(c->qid.type & QTDIR){
		if(omode != OREAD)
			error(Eperm);
	} else {
		switch(NETTYPE(c->qid.path)){
		case Ndataqid:
		case Nctlqid:
			id = NETID(c->qid.path);
			openfile(nif, id);
			break;
		case Ncloneqid:
			id = openfile(nif, -1);
			c->qid.path = NETQID(id, Nctlqid);
			break;
		default:
			if(omode != OREAD)
				error(Ebadarg);
		}
		switch(NETTYPE(c->qid.path)){
		case Ndataqid:
		case Nctlqid:
			f = nif->f[id];
			if(netown(f, up->user, omode&7) < 0){
				netifclose(nif, c);
				error(Eperm);
			}
			break;
		}
	}
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	c->iounit = qiomaxatomic;
	return c;
}
Ejemplo n.º 8
0
/*
 *  create a pipe, no streams are created until an open
 */
static Chan*
pipeattach(char *spec)
{
	Pipe *p;
	Chan *c;

	c = devattach('|', spec);
	p = malloc(sizeof(Pipe));
	if(p == 0)
		error(Enomem);
	if(waserror()){
		freepipe(p);
		nexterror();
	}
	p->pipedir = malloc(sizeof(pipedir));
	if (p->pipedir == 0)
		error(Enomem);
	memmove(p->pipedir, pipedir, sizeof(pipedir));
	kstrdup(&p->user, up->env->user);
	p->ref = 1;

	p->q[0] = qopen(pipealloc.pipeqsize, 0, 0, 0);
	if(p->q[0] == 0)
		error(Enomem);
	p->q[1] = qopen(pipealloc.pipeqsize, 0, 0, 0);
	if(p->q[1] == 0)
		error(Enomem);
	poperror();

	lock(&pipealloc.l);
	p->path = ++pipealloc.path;
	unlock(&pipealloc.l);

	c->qid.path = NETQID(2*p->path, Qdir);
	c->qid.vers = 0;
	c->qid.type = QTDIR;
	c->aux = p;
	c->dev = 0;
	return c;
}
Ejemplo n.º 9
0
struct chan *netifopen(struct ether *nif, struct chan *c, int omode)
{
	int id;
	struct netfile *f;

	id = 0;
	if (c->qid.type & QTDIR) {
		if (!IS_RDONLY(omode))
			error(Eperm);
	} else {
		switch (NETTYPE(c->qid.path)) {
			case Ndataqid:
			case Nctlqid:
				id = NETID(c->qid.path);
				openfile(nif, id);
				break;
			case Ncloneqid:
				id = openfile(nif, -1);
				c->qid.path = NETQID(id, Nctlqid);
				break;
			default:
				if (!IS_RDONLY(omode))
					error(Ebadarg);
		}
		switch (NETTYPE(c->qid.path)) {
			case Ndataqid:
			case Nctlqid:
				f = nif->f[id];
				if (netown(f, current->user, omode & 7) < 0)
					error(Eperm);
				break;
		}
	}
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	c->iounit = qiomaxatomic;
	return c;
}
Ejemplo n.º 10
0
/*
 *  create a pipe, no streams are created until an open
 */
static Chan*
pipeattach(char *spec)
{
	Pipe *p;
	Chan *c;

	c = devattach('|', spec);
	if(waserror()){
		chanfree(c);
		nexterror();
	}
	p = malloc(sizeof(Pipe));
	if(p == 0)
		exhausted("memory");
	p->ref = 1;

	p->q[0] = qopen(conf.pipeqsize, 0, 0, 0);
	if(p->q[0] == 0){
		free(p);
		exhausted("memory");
	}
	p->q[1] = qopen(conf.pipeqsize, 0, 0, 0);
	if(p->q[1] == 0){
		qfree(p->q[0]);
		free(p);
		exhausted("memory");
	}
	poperror();

	lock(&pipealloc);
	p->path = ++pipealloc.path;
	unlock(&pipealloc);
	p->perm = pipedir[Qdata0].perm;

	mkqid(&c->qid, NETQID(2*p->path, Qdir), 0, QTDIR);
	c->aux = p;
	c->dev = 0;
	return c;
}
Ejemplo n.º 11
0
/*
 *  generate a 3 level directory
 */
static int
netifgen(Chan *c, char* j, Dirtab *vp, int n, int i, Dir *dp)
{
	Proc *up = externup();
	Qid q;
	Netif *nif = (Netif*)vp;
	Netfile *f;
	int t;
	int perm;
	char *o;

	q.type = QTFILE;
	q.vers = 0;

	/* top level directory contains the name of the network */
	if(c->qid.path == 0){
		switch(i){
		case DEVDOTDOT:
			q.path = 0;
			q.type = QTDIR;
			devdir(c, q, ".", 0, eve, 0555, dp);
			break;
		case 0:
			q.path = N2ndqid;
			q.type = QTDIR;
			strcpy(up->genbuf, nif->name);
			devdir(c, q, up->genbuf, 0, eve, 0555, dp);
			break;
		default:
			return -1;
		}
		return 1;
	}

	/* second level contains clone plus all the conversations */
	t = NETTYPE(c->qid.path);
	if(t == N2ndqid || t == Ncloneqid || t == Naddrqid
	|| t == Nstatqid || t == Nifstatqid || t == Nmtuqid){
		switch(i) {
		case DEVDOTDOT:
			q.type = QTDIR;
			q.path = 0;
			devdir(c, q, ".", 0, eve, DMDIR|0555, dp);
			break;
		case 0:
			q.path = Ncloneqid;
			devdir(c, q, "clone", 0, eve, 0666, dp);
			break;
		case 1:
			q.path = Naddrqid;
			devdir(c, q, "addr", 0, eve, 0666, dp);
			break;
		case 2:
			q.path = Nstatqid;
			devdir(c, q, "stats", 0, eve, 0444, dp);
			break;
		case 3:
			q.path = Nifstatqid;
			devdir(c, q, "ifstats", 0, eve, 0444, dp);
			break;
		case 4:
			q.path = Nmtuqid;
			devdir(c, q, "mtu", 0, eve, 0444, dp);
			break;
		default:
			i -= 5;
			if(i >= nif->nfile)
				return -1;
			if(nif->f[i] == 0)
				return 0;
			q.type = QTDIR;
			q.path = NETQID(i, N3rdqid);
			snprint(up->genbuf, sizeof up->genbuf, "%d", i);
			devdir(c, q, up->genbuf, 0, eve, DMDIR|0555, dp);
			break;
		}
		return 1;
	}

	/* third level */
	f = nif->f[NETID(c->qid.path)];
	if(f == 0)
		return 0;
	if(*f->owner){
		o = f->owner;
		perm = f->mode;
	} else {
		o = eve;
		perm = 0666;
	}
	switch(i){
	case DEVDOTDOT:
		q.type = QTDIR;
		q.path = N2ndqid;
		strcpy(up->genbuf, nif->name);
		devdir(c, q, up->genbuf, 0, eve, DMDIR|0555, dp);
		break;
	case 0:
		q.path = NETQID(NETID(c->qid.path), Ndataqid);
		devdir(c, q, "data", 0, o, perm, dp);
		break;
	case 1:
		q.path = NETQID(NETID(c->qid.path), Nctlqid);
		devdir(c, q, "ctl", 0, o, perm, dp);
		break;
	case 2:
		q.path = NETQID(NETID(c->qid.path), Nstatqid);
		devdir(c, q, "stats", 0, eve, 0444, dp);
		break;
	case 3:
		q.path = NETQID(NETID(c->qid.path), Ntypeqid);
		devdir(c, q, "type", 0, eve, 0444, dp);
		break;
	case 4:
		q.path = NETQID(NETID(c->qid.path), Nifstatqid);
		devdir(c, q, "ifstats", 0, eve, 0444, dp);
		break;
	default:
		return -1;
	}
	return 1;
}
Ejemplo n.º 12
0
/*
 *  generate a 3 level directory
 */
static int
netifgen(struct chan *c, char *unused_char_p_t, struct dirtab *vp,
		 int unused_int, int i, struct dir *dp)
{
	struct qid q;
	struct ether *nif = (struct ether *)vp;
	struct netfile *f;
	int perm;
	char *o;

	q.type = QTFILE;
	q.vers = 0;

	/* top level directory contains the name of the network */
	if (c->qid.path == 0) {
		switch (i) {
			case DEVDOTDOT:
				q.path = 0;
				q.type = QTDIR;
				devdir(c, q, ".", 0, eve, 0555, dp);
				break;
			case 0:
				q.path = N2ndqid;
				q.type = QTDIR;
				strncpy(get_cur_genbuf(), nif->name, GENBUF_SZ);
				devdir(c, q, get_cur_genbuf(), 0, eve, 0555, dp);
				break;
			default:
				return -1;
		}
		return 1;
	}

	/* second level contains clone plus all the conversations.
	 *
	 * This ancient comment is from plan9.  Inferno and nxm both had issues
	 * here.  You couldn't ls /net/ether0/ when it didn't have any convs.  There
	 * were also issues with nxm where you couldn't stat ether0/x/stats
	 * properly.
	 *
	 * The issue is that if we handle things like Nstatqid, then we will never
	 * pass it down to the third level. And since we just set the path ==
	 * Nstatqid, we won't have the NETID muxed in. If someone isn't trying to
	 * generate a chan, but instead is looking it up (devwalk generates, devstat
	 * already has the chan), then they are also looking for a devdir with path
	 * containing ID << 5. So if you stat ether0/1/ifstats, devstat is looking
	 * for path 41, but we return path 9 (41 = 32 + 9). (these numbers are
	 * before we tracked NETID + 1).
	 *
	 * We (akaros and plan9) had a big if here, that would catch things that do
	 * not exist in the subdirs of a netif. Things like clone make sense here.
	 * I guess addr too, though that seems to be added since the original
	 * comment. You can see what the 3rd level was expecting to parse by looking
	 * farther down in the code.
	 *
	 * The root of the problem was that the old code couldn't tell the
	 * difference between no netid and netid 0. Now, we determine if we're at
	 * the second level by the lack of a netid, instead of trying to enumerate
	 * the qid types that the second level could have. The latter approach
	 * allowed for something like ether0/1/stats, but we couldn't actually
	 * devstat ether0/stats directly. It's worth noting that there is no
	 * difference to the content of ether0/stats and ether0/x/stats (when you
	 * read), but they have different chan qids.
	 *
	 * Here's the old if block:
	 t = NETTYPE(c->qid.path);
	 if (t == N2ndqid || t == Ncloneqid || t == Naddrqid) {
	 */
	if (NETID(c->qid.path) == -1) {
		switch (i) {
			case DEVDOTDOT:
				q.type = QTDIR;
				q.path = 0;
				devdir(c, q, ".", 0, eve, DMDIR | 0555, dp);
				break;
			case 0:
				q.path = Ncloneqid;
				devdir(c, q, "clone", 0, eve, 0666, dp);
				break;
			case 1:
				q.path = Naddrqid;
				devdir(c, q, "addr", 0, eve, 0666, dp);
				break;
			case 2:
				q.path = Nstatqid;
				devdir(c, q, "stats", 0, eve, 0444, dp);
				break;
			case 3:
				q.path = Nifstatqid;
				devdir(c, q, "ifstats", 0, eve, 0444, dp);
				break;
			default:
				i -= 4;
				if (i >= nif->nfile)
					return -1;
				if (nif->f[i] == 0)
					return 0;
				q.type = QTDIR;
				q.path = NETQID(i, N3rdqid);
				snprintf(get_cur_genbuf(), GENBUF_SZ, "%d", i);
				devdir(c, q, get_cur_genbuf(), 0, eve, DMDIR | 0555, dp);
				break;
		}
		return 1;
	}

	/* third level */
	f = nif->f[NETID(c->qid.path)];
	if (f == 0)
		return 0;
	if (*f->owner) {
		o = f->owner;
		perm = f->mode;
	} else {
		o = eve;
		perm = 0666;
	}
	switch (i) {
		case DEVDOTDOT:
			q.type = QTDIR;
			q.path = N2ndqid;
			strncpy(get_cur_genbuf(), nif->name, GENBUF_SZ);
			devdir(c, q, get_cur_genbuf(), 0, eve, DMDIR | 0555, dp);
			break;
		case 0:
			q.path = NETQID(NETID(c->qid.path), Ndataqid);
			devdir(c, q, "data", 0, o, perm, dp);
			break;
		case 1:
			q.path = NETQID(NETID(c->qid.path), Nctlqid);
			devdir(c, q, "ctl", 0, o, perm, dp);
			break;
		case 2:
			q.path = NETQID(NETID(c->qid.path), Nstatqid);
			devdir(c, q, "stats", 0, eve, 0444, dp);
			break;
		case 3:
			q.path = NETQID(NETID(c->qid.path), Ntypeqid);
			devdir(c, q, "type", 0, eve, 0444, dp);
			break;
		case 4:
			q.path = NETQID(NETID(c->qid.path), Nifstatqid);
			devdir(c, q, "ifstats", 0, eve, 0444, dp);
			break;
		default:
			return -1;
	}
	return 1;
}
Ejemplo n.º 13
0
/*
 *  set up the '#t' directory
 */
static void
uartreset(void)
{
	int i;
	Dirtab *dp;
	Uart *p, *tail;

	tail = nil;
	for(i = 0; physuart[i] != nil; i++){
		if(physuart[i]->pnp == nil)
			continue;
		if((p = physuart[i]->pnp()) == nil)
			continue;
		if(uartlist != nil)
			tail->next = p;
		else
			uartlist = p;
		for(tail = p; tail->next != nil; tail = tail->next)
			uartnuart++;
		uartnuart++;
	}

	if(uartnuart)
		uart = xalloc(uartnuart*sizeof(Uart*));

	uartndir = 1 + 3*uartnuart;
	uartdir = xalloc(uartndir * sizeof(Dirtab));
	if (uart == nil || uartdir == nil)
		panic("uartreset: no memory");
	dp = uartdir;
	strcpy(dp->name, ".");
	mkqid(&dp->qid, 0, 0, QTDIR);
	dp->length = 0;
	dp->perm = DMDIR|0555;
	dp++;
	p = uartlist;
	for(i = 0; i < uartnuart; i++){
		/* 3 directory entries per port */
		snprint(dp->name, sizeof dp->name, "eia%d", i);
		dp->qid.path = NETQID(i, Ndataqid);
		dp->perm = 0660;
		dp++;
		snprint(dp->name, sizeof dp->name, "eia%dctl", i);
		dp->qid.path = NETQID(i, Nctlqid);
		dp->perm = 0660;
		dp++;
		snprint(dp->name, sizeof dp->name, "eia%dstatus", i);
		dp->qid.path = NETQID(i, Nstatqid);
		dp->perm = 0444;
		dp++;

		uart[i] = p;
		p->dev = i;
		if(p->console || p->special){
			if(uartenable(p) != nil){
				if(p->console && up)
					serialoq = p->oq;
				p->opens++;
			}
		}
		p = p->next;
	}

	if(uartnuart){
		/*
		 * at 115200 baud, the 1024 char buffer takes 56 ms to process,
		 * processing it every 22 ms should be fine.
		 */
		uarttimer = addclock0link(uartclock, 22);
	}
}
Ejemplo n.º 14
0
static void
eiainit(void)
{
	int     i,x;
	byte    ports;   //bitmask of active host ports
	int     nports;  //number of active host ports
	int     max;     //number of highest port
	Dirtab *dp;

	// setup the timeouts; choose carefully
	timeouts.ReadIntervalTimeout = 2;
	timeouts.ReadTotalTimeoutMultiplier = 0;
	timeouts.ReadTotalTimeoutConstant = 200;
	timeouts.WriteTotalTimeoutMultiplier = 0;
	timeouts.WriteTotalTimeoutConstant = 400;

	// check to see which ports exist by trying to open them
	// keep results in a bitmask
	ports = nports = max = 0;
	for(i=0; (sysdev[i] != NULL) && (i<8); i++) {
		HANDLE comfh = CreateFile(sysdev[i], 0, 0, NULL,	/* no security attrs */
			OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

		if(comfh != INVALID_HANDLE_VALUE) {
			ports |= 1<<i;   
			CloseHandle(comfh);
			nports++;
			max = i;
		}
	}

	if(nports == 0)
		return;  //no ports

	// allocate directory table and eia structure
	// for each active port.
	ndir = Nqid*nports+1;
	dp = eiadir = malloc(ndir*sizeof(Dirtab));
	if(dp == 0)
		panic("eiainit");
	eia = malloc(nports*sizeof(Eia));
	if(eia == 0) {
		free(dp);
		panic("eiainit");
	}

	// fill in the directory table and initialize
	// the eia structure.  skip inactive ports.
	sprint(dp->name, ".");
	dp->qid.path = 0;
	dp->qid.type = QTDIR;
	dp->perm = DMDIR|0555;
	dp++;
	x = 0;  // index in eia[]
	for(i = 0; i <= max; i++) {
		if( (ports & (1<<i)) == 0)
			continue;  //port 'i' is not active
		sprint(dp->name, "eia%d", i);
		dp->qid.path = NETQID(x, Ndataqid);
		dp->perm = 0660;
		dp++;
		sprint(dp->name, "eia%dctl", i);
		dp->qid.path = NETQID(x, Nctlqid);
		dp->perm = 0660;
		dp++;
		sprint(dp->name, "eia%dstatus", i);
		dp->qid.path = NETQID(x, Nstatqid);
		dp->perm = 0660;
		dp++;
		// init the eia structure
		eia[x].restore = 0;
		eia[x].id = i;
		x++;
	}
}