plan 9 kernel history: overview | file list | diff list

1990/0321/gnot/devdk.c (diff list | history)

1990/0312/sys/src/9/gnot/devdk.c:287,2931990/0315/sys/src/9/gnot/devdk.c:287,293 (short | long)
1990/0312    
	line = bp->rptr[0] | (bp->rptr[1]<<8); 
	bp->rptr += 2; 
	if(line<0 || line>=dp->lines){ 
		print("dkmuxiput bad line %d\n", line); 
1990/0315    
		DPRINT("dkmuxiput bad line %d\n", line); 
1990/0312    
		freeb(bp); 
		return; 
	} 
1990/0312/sys/src/9/gnot/devdk.c:297,3081990/0315/sys/src/9/gnot/devdk.c:297,308
1990/0312    
		if(lp->rq) 
			PUTNEXT(lp->rq, bp); 
		else{ 
			print("dkmuxiput unopened line %d\n", line); 
1990/0315    
			DPRINT("dkmuxiput unopened line %d\n", line); 
1990/0312    
			freeb(bp); 
		} 
		qunlock(lp); 
	} else { 
		print("dkmuxiput unopened line %d\n", line); 
1990/0315    
		DPRINT("dkmuxiput unopened line %d\n", line); 
1990/0312    
		freeb(bp); 
	} 
} 
1990/0312/sys/src/9/gnot/devdk.c:412,4171990/0315/sys/src/9/gnot/devdk.c:412,419
1990/0312    
 
	if(bp->base && bp->rptr - bp->base >= 2) 
		bp->rptr -= 2; 
1990/0315    
	else 
		panic("dkoput"); 
1990/0312    
	bp->rptr[0] = line; 
	bp->rptr[1] = line>>8; 
 
1990/0312/sys/src/9/gnot/devdk.c:574,5801990/0315/sys/src/9/gnot/devdk.c:576,581
1990/0312    
{ 
	Chan *c; 
	Dk *dp; 
print("attach\n"); 
 
	/* 
	 *  find a multiplexor with the same name 
1990/0312/sys/src/9/gnot/devdk.c:581,5871990/0315/sys/src/9/gnot/devdk.c:582,587
1990/0312    
	 */ 
	for(dp = dk; dp < &dk[Ndk]; dp++){ 
		qlock(dp); 
print("name %s %lux\n", dp->name, dp->wq); 
		if(dp->wq && strcmp(spec, dp->name)==0) { 
			dp->ref++; 
			qunlock(dp); 
1990/0312/sys/src/9/gnot/devdk.c:593,5991990/0315/sys/src/9/gnot/devdk.c:593,598
1990/0312    
		error(0, Enoifc); 
	c = devattach('k', spec); 
	c->dev = dp - dk; 
print("attach done\n"); 
	return c; 
} 
 
1990/0312/sys/src/9/gnot/devdk.c:1115,11271990/0315/sys/src/9/gnot/devdk.c:1114,1126
1990/0312    
		 *  for the call to come in on). 
		 */ 
		if(!canqlock(lp)){ 
			print("DKbusy1\n"); 
1990/0315    
			DPRINT("DKbusy1\n"); 
1990/0312    
			dkanswer(c, lineno, DKbusy); 
			continue; 
		} else { 
			if(lp->state != Lclosed){ 
				qunlock(lp); 
				print("DKbusy2 %ux\n", lp->state); 
1990/0315    
				DPRINT("DKbusy2 %ux\n", lp->state); 
1990/0312    
				dkanswer(c, lineno, DKbusy); 
				continue; 
			} 
1990/0315/sys/src/9/gnot/devdk.c:644,6511990/0319/sys/src/9/gnot/devdk.c:644,658 (short | long)
1990/0312    
	Dk *dp; 
	int line; 
 
	if(c->qid == Dcloneqid){ 
1990/0319    
	if(c->qid & CHDIR){ 
1990/0312    
		/* 
1990/0319    
		 *  directories are read only 
		 */ 
		if(omode != OREAD) 
			error(0, Ebadarg); 
	} else switch(STREAMTYPE(c->qid)){ 
	case Dcloneqid: 
		/* 
1990/0312    
		 *  get an unused device and open it's control file 
		 */ 
		dp = &dk[c->dev]; 
1990/0315/sys/src/9/gnot/devdk.c:665,6711990/0319/sys/src/9/gnot/devdk.c:672,679
1990/0312    
			error(0, Enodev); 
		streamopen(c, &dkinfo); 
		pushq(c->stream, &urpinfo); 
	} else if(STREAMTYPE(c->qid) == Dlistenqid){ 
1990/0319    
		break; 
	case Dlistenqid: 
1990/0312    
		/* 
		 *  listen for a call and open the control file for the 
		 *  channel on which the call arrived. 
1990/0315/sys/src/9/gnot/devdk.c:675,6871990/0319/sys/src/9/gnot/devdk.c:683,707
1990/0312    
		streamopen(c, &dkinfo); 
		pushq(c->stream, &urpinfo); 
		dkwindow(c); 
	} else if(c->qid != CHDIR){ 
1990/0319    
		break; 
	case Daddrqid: 
	case Draddrqid: 
	case Duserqid: 
	case Dotherqid: 
1990/0312    
		/* 
1990/0319    
		 *  read only files 
		 */ 
		if(omode != OREAD) 
			error(0, Ebadarg); 
		break; 
	default: 
		/* 
1990/0312    
		 *  open whatever c points to, make sure it has an urp 
		 */ 
		streamopen(c, &dkinfo); 
		if(strcmp(c->stream->procq->next->info->name, "urp")!=0) 
			pushq(c->stream, &urpinfo); 
1990/0319    
		break; 
1990/0312    
	} 
 
	c->mode = openmode(omode); 
1990/0315/sys/src/9/gnot/devdk.c:702,7081990/0319/sys/src/9/gnot/devdk.c:722,728
1990/0312    
	Dk *dp; 
 
	/* real closing happens in lancestclose */ 
	if(c->qid != CHDIR) 
1990/0319    
	if(c->stream) 
1990/0312    
		streamclose(c); 
 
	dp = &dk[c->dev]; 
1990/0315/sys/src/9/gnot/devdk.c:714,7301990/0319/sys/src/9/gnot/devdk.c:734,753
1990/0312    
long	  
dkread(Chan *c, void *a, long n) 
{ 
	int t; 
	Line *lp; 
 
	t = STREAMTYPE(c->qid); 
	if(t>=Slowqid || t==Dlineqid) 
1990/0319    
	if(c->stream) 
1990/0312    
		return streamread(c, a, n); 
	if(c->qid == CHDIR) 
		return devdirread(c, a, n, dkdir, dk[c->dev].lines, devgen); 
 
1990/0319    
	if(c->qid & CHDIR){ 
		if(c->qid == CHDIR) 
			return devdirread(c, a, n, dkdir, dk[c->dev].lines, devgen); 
		else 
			return devdirread(c, a, n, dksubdir, Nsubdir, streamgen); 
	} 
 
1990/0312    
	lp = &dk[c->dev].line[STREAMID(c->qid)]; 
	switch(t){ 
1990/0319    
	switch(STREAMTYPE(c->qid)){ 
1990/0312    
	case Daddrqid: 
		return stringread(c, a, n, lp->addr); 
	case Draddrqid: 
1990/0315/sys/src/9/gnot/devdk.c:781,7891990/0319/sys/src/9/gnot/devdk.c:804,809
1990/0312    
			return streamwrite(c, a, n, 0); 
		return n; 
	} 
                 
	if(t >= Slowqid) 
		return streamwrite(c, a, n, 0); 
 
	error(0, Eperm); 
} 
1990/0319/sys/src/9/gnot/devdk.c:538,5431990/0321/sys/src/9/gnot/devdk.c:538,545 (short | long)
1990/0312    
void 
dkreset(void) 
{ 
1990/0321    
	newqinfo(&dkmuxinfo); 
	newqinfo(&urpinfo); 
1990/0312    
} 
 
/* 
1990/0321/sys/src/9/gnot/devdk.c:417,4231990/0331/sys/src/9/gnot/devdk.c:417,427 (short | long)
1990/0312    
	bp->rptr[0] = line; 
	bp->rptr[1] = line>>8; 
 
	PUTNEXT(dp->wq, bp); 
1990/0331    
	if(dp->wq->len >= Streamhi){ 
		print("dkoput free\n"); 
		freeb(bp); 
	} else 
		PUTNEXT(dp->wq, bp); 
1990/0312    
} 
 
/* 
1990/0331/sys/src/9/gnot/devdk.c:417,4271990/0403/sys/src/9/gnot/devdk.c:417,423 (short | long)
1990/0312    
	bp->rptr[0] = line; 
	bp->rptr[1] = line>>8; 
 
1990/0331    
	if(dp->wq->len >= Streamhi){ 
		print("dkoput free\n"); 
		freeb(bp); 
	} else 
		PUTNEXT(dp->wq, bp); 
1990/0403    
	PUTNEXT(dp->wq, bp); 
1990/0312    
} 
 
/* 
1990/0331/sys/src/9/gnot/devdk.c:1132,11371990/0403/sys/src/9/gnot/devdk.c:1128,1135
1990/0312    
		 */ 
		if(ts == lp->timestamp){ 
			print("dklisten: repeat timestamp %d\n", lineno); 
1990/0403    
			if(lp->state != Lconnected) 
				dkanswer(c, lineno, DKbusy); 
1990/0312    
			continue; 
		} 
	 
1990/0403/sys/src/9/gnot/devdk.c:329,3341990/05313/sys/src/9/gnot/devdk.c:329,336 (short | long)
1990/0312    
	q->other->ptr = q->ptr = lp = &dp->line[s->id]; 
	lp->dp = dp; 
	lp->rq = q; 
1990/05313    
	if(lp->state == Lclosed) 
		lp->state = Lopened; 
1990/0312    
} 
 
/* 
1990/0403/sys/src/9/gnot/devdk.c:417,4231990/05313/sys/src/9/gnot/devdk.c:419,429
1990/0312    
	bp->rptr[0] = line; 
	bp->rptr[1] = line>>8; 
 
1990/0403    
	PUTNEXT(dp->wq, bp); 
1990/05313    
	if(QFULL(dp->wq->next)){ 
		print("dk wq full\n"); 
		freeb(bp); 
	} else 
		PUTNEXT(dp->wq, bp); 
1990/0312    
} 
 
/* 
1990/0403/sys/src/9/gnot/devdk.c:666,6721990/05313/sys/src/9/gnot/devdk.c:672,677
1990/0312    
					continue; 
				} 
				c->qid = STREAMQID(lp-dp->line, Sctlqid); 
				qunlock(lp); 
				break; 
			} 
		} 
1990/0403/sys/src/9/gnot/devdk.c:674,6791990/05313/sys/src/9/gnot/devdk.c:679,685
1990/0312    
			error(0, Enodev); 
		streamopen(c, &dkinfo); 
		pushq(c->stream, &urpinfo); 
1990/05313    
		qunlock(lp); 
1990/0319    
		break; 
	case Dlistenqid: 
1990/0312    
		/* 
1990/0403/sys/src/9/gnot/devdk.c:723,7291990/05313/sys/src/9/gnot/devdk.c:729,735
1990/0312    
{ 
	Dk *dp; 
 
	/* real closing happens in lancestclose */ 
1990/05313    
	/* real closing happens in dkstclose */ 
1990/0319    
	if(c->stream) 
1990/0312    
		streamclose(c); 
 
1990/0403/sys/src/9/gnot/devdk.c:895,9011990/05313/sys/src/9/gnot/devdk.c:901,907
1990/0312    
	/* 
	 *  only dial on virgin lines 
	 */ 
	if(lp->state != Lclosed) 
1990/05313    
	if(lp->state != Lopened) 
1990/0312    
		error(0, Ebadarg); 
 
	DPRINT("dkcall(line=%d, type=%d, dest=%s)\n", line, type, addr); 
1990/0403/sys/src/9/gnot/devdk.c:1198,12031990/05313/sys/src/9/gnot/devdk.c:1204,1210
1990/0312    
		DPRINT("dklisten returns %d\n", lineno); 
		return lineno; 
	} 
1990/05313    
	panic("dklisten terminates strangely\n"); 
1990/0312    
} 
 
/* 
1990/05313/sys/src/9/gnot/devdk.c:66,721990/0617/sys/src/9/gnot/devdk.c:66,72 (short | long)
1990/0312    
#define	  D_OK		1		/* not used */ 
#define	  D_OPEN	2		/* (dkmux to host) connection established */ 
#define	  D_FAIL	3		/* (dkmux to host) connection failed */ 
#define	T_CHG	3		/* linege the status of a connection */ 
1990/0617    
#define	T_CHG	3		/* change the status of a connection */ 
1990/0312    
#define	  D_CLOSE	1		/* close the connection */ 
#define	  D_ISCLOSED	2		/* (dkmux to host) confirm a close */ 
#define	  D_CLOSEALL	3		/* (dkmux to host) close all connections */ 
1990/05313/sys/src/9/gnot/devdk.c:1003,10091990/0617/sys/src/9/gnot/devdk.c:1003,1009
1990/0312    
	} 
 
	/* 
	 *  linege state if serving 
1990/0617    
	 *  change state if serving 
1990/0312    
	 */ 
	if(type == D_SERV){ 
		lp->state = Llistening; 
1990/05313/sys/src/9/gnot/devdk.c:1075,10811990/0617/sys/src/9/gnot/devdk.c:1075,1083
1990/0312    
		n = streamread(dc, dialstr, sizeof(dialstr)-1); 
		DPRINT("returns %d\n", n); 
		if(n <= 0) 
1990/0617    
{print("bad n\n"); 
1990/0312    
			error(0, Eio); 
1990/0617    
} 
1990/0312    
		dialstr[n] = 0; 
		DPRINT("dialstr = %s\n", dialstr); 
 
1990/05313/sys/src/9/gnot/devdk.c:1085,10901990/0617/sys/src/9/gnot/devdk.c:1087,1093
1990/0312    
		n = getfields(dialstr, line, 12, '\n'); 
		if (n < 2) { 
			DPRINT("bad dialstr from dk (1 line)\n"); 
1990/0617    
print("bad dialstr %d '%s'\n", n, dialstr); 
1990/0312    
			error(0, Eio); 
		} 
 
1990/05313/sys/src/9/gnot/devdk.c:1289,12941990/0617/sys/src/9/gnot/devdk.c:1292,1302
1990/0312    
	int i; 
 
	dp = (Dk *)a; 
1990/0617    
 
	/* 
	 *  tell datakit we've rebooted. It should close all channels. 
	 */ 
	dkmesg(dp, T_CHG, D_CLOSEALL, 0, 0); 
1990/0312    
 
	/* 
	 *  loop forever listening 
1990/0617/sys/src/9/gnot/devdk.c:123,1281990/0707/sys/src/9/gnot/devdk.c:123,129 (short | long)
1990/0312    
	int	ncsc;		/* csc line number */ 
	Chan	*csc;		/* common signalling line */ 
	Line	line[Nline]; 
1990/0707    
	int	restart; 
1990/0312    
}; 
static Dk dk[Ndk]; 
 
1990/0617/sys/src/9/gnot/devdk.c:427,4361990/0707/sys/src/9/gnot/devdk.c:428,438
1990/0312    
} 
 
/* 
 *  configure a datakit multiplexor.  this takes 3 arguments separated 
1990/0707    
 *  configure a datakit multiplexor.  this takes 4 arguments separated 
1990/0312    
 *  by spaces: 
 *	the line number of the common signalling channel (must be > 0) 
 *	the number of lines in the device (optional) 
1990/0707    
 *	the word `restart' or `norestart' (optional/default==restart) 
1990/0312    
 *	the name of the dk (optional) 
 * 
 *  we can configure only once 
1990/0617/sys/src/9/gnot/devdk.c:439,4451990/0707/sys/src/9/gnot/devdk.c:441,447
1990/0312    
dkmuxconfig(Dk *dp, Block *bp) 
{ 
	Chan *c; 
	char *fields[3]; 
1990/0707    
	char *fields[4]; 
1990/0312    
	int n; 
	char buf[64]; 
	static int dktimeron; 
1990/0617/sys/src/9/gnot/devdk.c:452,4611990/0707/sys/src/9/gnot/devdk.c:454,467
1990/0312    
	/* 
	 *  parse 
	 */ 
	n = getfields((char *)bp->rptr, fields, 3, ' '); 
1990/0707    
	dp->restart = 1; 
	n = getfields((char *)bp->rptr, fields, 4, ' '); 
1990/0312    
	switch(n){ 
1990/0707    
	case 4: 
		strncpy(dp->name, fields[3], sizeof(dp->name)); 
1990/0312    
	case 3: 
		strncpy(dp->name, fields[2], sizeof(dp->name)); 
1990/0707    
		if(strcmp(fields[2], "restart")!=0) 
			dp->restart = 0; 
1990/0312    
	case 2: 
		dp->lines = strtoul(fields[1], 0, 0); 
	case 1: 
1990/0617/sys/src/9/gnot/devdk.c:893,8981990/0707/sys/src/9/gnot/devdk.c:899,905
1990/0312    
	Dk *dp; 
	Line *lp; 
	Chan *dc; 
1990/0707    
	char *bang, *dot; 
1990/0312    
 
	line = STREAMID(c->qid); 
	dp = &dk[c->dev]; 
1990/0617/sys/src/9/gnot/devdk.c:907,9131990/0707/sys/src/9/gnot/devdk.c:914,922
1990/0312    
	DPRINT("dkcall(line=%d, type=%d, dest=%s)\n", line, type, addr); 
 
	/* 
	 *  build dial string (guard against new lines) 
1990/0707    
	 *  build dial string 
	 *	- guard against new lines 
	 *	- change ! into . to delimit service 
1990/0312    
	 */ 
	if(strchr(addr, '\n')) 
		error(0, Ebadarg); 
1990/0617/sys/src/9/gnot/devdk.c:914,9191990/0707/sys/src/9/gnot/devdk.c:923,934
1990/0312    
	if(strlen(addr)+strlen(u->p->pgrp->user)+2 >= sizeof(dialstr)) 
		error(0, Ebadarg); 
	strcpy(dialstr, addr); 
1990/0707    
	bang = strchr(dialstr, '!'); 
	if(bang){ 
		dot = strchr(dialstr, '.'); 
		if(dot==0 || dot > bang) 
			*bang = '.'; 
	} 
1990/0312    
	switch(type){ 
	case Dial: 
		t_val = T_SRV; 
1990/0617/sys/src/9/gnot/devdk.c:1296,13011990/0707/sys/src/9/gnot/devdk.c:1311,1318
1990/0617    
	/* 
	 *  tell datakit we've rebooted. It should close all channels. 
	 */ 
1990/0707    
	if(dp->restart) 
		dkmesg(dp, T_ALIVE, D_RESTART, 0, 0); 
1990/0617    
	dkmesg(dp, T_CHG, D_CLOSEALL, 0, 0); 
1990/0312    
 
	/* 
1990/0707/sys/src/9/gnot/devdk.c:551,5571990/0717/sys/src/9/gnot/devdk.c:551,557 (short | long)
1990/0312    
dkreset(void) 
{ 
1990/0321    
	newqinfo(&dkmuxinfo); 
	newqinfo(&urpinfo); 
1990/0717    
	urpreset(); 
1990/0312    
} 
 
/* 
1990/0717/sys/src/9/gnot/devdk.c:456,4611990/0725/sys/src/9/gnot/devdk.c:456,462 (short | long)
1990/0312    
	 */ 
1990/0707    
	dp->restart = 1; 
	n = getfields((char *)bp->rptr, fields, 4, ' '); 
1990/0725    
	strcpy(dp->name, "dk"); 
1990/0312    
	switch(n){ 
1990/0707    
	case 4: 
		strncpy(dp->name, fields[3], sizeof(dp->name)); 
1990/0717/sys/src/9/gnot/devdk.c:494,5001990/0725/sys/src/9/gnot/devdk.c:495,501
1990/0312    
	/* 
	 *  start a process to deal with it 
	 */ 
	sprint(buf, "**csckproc%d**", dp->ncsc); 
1990/0725    
	sprint(buf, "csckproc%d", dp->ncsc); 
1990/0312    
	kproc(buf, dkcsckproc, dp); 
	poperror(); 
 
1990/0717/sys/src/9/gnot/devdk.c:503,5091990/0725/sys/src/9/gnot/devdk.c:504,510
1990/0312    
	 */ 
	if(dktimeron == 0){ 
		dktimeron = 1; 
		kproc("**dktimer**", dktimer, 0); 
1990/0725    
		kproc("dktimer", dktimer, 0); 
1990/0312    
	} 
} 
 
1990/0717/sys/src/9/gnot/devdk.c:592,5991990/0725/sys/src/9/gnot/devdk.c:593,602
1990/0312    
	Dk *dp; 
 
	/* 
	 *  find a multiplexor with the same name 
1990/0725    
	 *  find a multiplexor with the same name (default dk) 
1990/0312    
	 */ 
1990/0725    
	if(*spec == 0) 
		spec = "dk"; 
1990/0312    
	for(dp = dk; dp < &dk[Ndk]; dp++){ 
		qlock(dp); 
		if(dp->wq && strcmp(spec, dp->name)==0) { 
1990/0725/sys/src/9/gnot/devdk.c:456,4621990/0726/sys/src/9/gnot/devdk.c:456,461 (short | long)
1990/0312    
	 */ 
1990/0707    
	dp->restart = 1; 
	n = getfields((char *)bp->rptr, fields, 4, ' '); 
1990/0725    
	strcpy(dp->name, "dk"); 
1990/0312    
	switch(n){ 
1990/0707    
	case 4: 
		strncpy(dp->name, fields[3], sizeof(dp->name)); 
1990/0725/sys/src/9/gnot/devdk.c:495,5011990/0726/sys/src/9/gnot/devdk.c:494,500
1990/0312    
	/* 
	 *  start a process to deal with it 
	 */ 
1990/0725    
	sprint(buf, "csckproc%d", dp->ncsc); 
1990/0726    
	sprint(buf, "**csckproc%d**", dp->ncsc); 
1990/0312    
	kproc(buf, dkcsckproc, dp); 
	poperror(); 
 
1990/0725/sys/src/9/gnot/devdk.c:504,5101990/0726/sys/src/9/gnot/devdk.c:503,509
1990/0312    
	 */ 
	if(dktimeron == 0){ 
		dktimeron = 1; 
1990/0725    
		kproc("dktimer", dktimer, 0); 
1990/0726    
		kproc("**dktimer**", dktimer, 0); 
1990/0312    
	} 
} 
 
1990/0725/sys/src/9/gnot/devdk.c:593,6021990/0726/sys/src/9/gnot/devdk.c:592,599
1990/0312    
	Dk *dp; 
 
	/* 
1990/0725    
	 *  find a multiplexor with the same name (default dk) 
1990/0726    
	 *  find a multiplexor with the same name 
1990/0312    
	 */ 
1990/0725    
	if(*spec == 0) 
		spec = "dk"; 
1990/0312    
	for(dp = dk; dp < &dk[Ndk]; dp++){ 
		qlock(dp); 
		if(dp->wq && strcmp(spec, dp->name)==0) { 
1990/0726/sys/src/9/gnot/devdk.c:456,4611990/0728/sys/src/9/gnot/devdk.c:456,462 (short | long)
1990/0312    
	 */ 
1990/0707    
	dp->restart = 1; 
	n = getfields((char *)bp->rptr, fields, 4, ' '); 
1990/0728    
	strcpy(dp->name, "dk"); 
1990/0312    
	switch(n){ 
1990/0707    
	case 4: 
		strncpy(dp->name, fields[3], sizeof(dp->name)); 
1990/0726/sys/src/9/gnot/devdk.c:494,5001990/0728/sys/src/9/gnot/devdk.c:495,501
1990/0312    
	/* 
	 *  start a process to deal with it 
	 */ 
1990/0726    
	sprint(buf, "**csckproc%d**", dp->ncsc); 
1990/0728    
	sprint(buf, "csckproc%d", dp->ncsc); 
1990/0312    
	kproc(buf, dkcsckproc, dp); 
	poperror(); 
 
1990/0726/sys/src/9/gnot/devdk.c:503,5091990/0728/sys/src/9/gnot/devdk.c:504,510
1990/0312    
	 */ 
	if(dktimeron == 0){ 
		dktimeron = 1; 
1990/0726    
		kproc("**dktimer**", dktimer, 0); 
1990/0728    
		kproc("dktimer", dktimer, 0); 
1990/0312    
	} 
} 
 
1990/0726/sys/src/9/gnot/devdk.c:592,5991990/0728/sys/src/9/gnot/devdk.c:593,602
1990/0312    
	Dk *dp; 
 
	/* 
1990/0726    
	 *  find a multiplexor with the same name 
1990/0728    
	 *  find a multiplexor with the same name (default dk) 
1990/0312    
	 */ 
1990/0728    
	if(*spec == 0) 
		spec = "dk"; 
1990/0312    
	for(dp = dk; dp < &dk[Ndk]; dp++){ 
		qlock(dp); 
		if(dp->wq && strcmp(spec, dp->name)==0) { 
1990/0726/sys/src/9/gnot/devdk.c:859,8661990/0728/sys/src/9/gnot/devdk.c:862,871
1990/0312    
 
	if(dp->csc == 0) 
		return -1; 
	if(waserror()) 
1990/0728    
	if(waserror()){ 
		print("dkmesg: error\n"); 
1990/0312    
		return -1; 
1990/0728    
	} 
1990/0312    
	d.type = type; 
	d.srv = srv; 
	d.param0l = p0; 
1990/0726/sys/src/9/gnot/devdk.c:1477,14831990/0728/sys/src/9/gnot/devdk.c:1482,1489
1990/0312    
	Dk *dp; 
	Line *lp; 
 
	waserror(); 
1990/0728    
	while(waserror()) 
		print("dktimer: error\n"); 
1990/0312    
 
	for(;;){ 
		/* 
1990/0728/sys/src/9/gnot/devdk.c:6,141990/08101/sys/src/9/gnot/devdk.c:6,15 (short | long)
1990/0312    
#include	"io.h" 
#include	"errno.h" 
 
#define NOW (MACHP(0)->ticks) 
#define DPRINT if(0) 
1990/08101    
#define	DPRINT	if(0)	/*kprint*/ 
1990/0312    
 
1990/08101    
#define	NOW	(MACHP(0)->ticks) 
 
1990/0312    
enum { 
	/* 
	 *  configuration parameters 
1990/0728/sys/src/9/gnot/devdk.c:477,4821990/08101/sys/src/9/gnot/devdk.c:478,485
1990/0312    
		dp->lines = 16; 
		error(0, Ebadarg); 
	} 
1990/08101    
	DPRINT("dkmuxconfig: ncsc=%d, lines=%d, restart=%d, name=\"%s\"\n", 
		dp->ncsc, dp->lines, dp->restart, dp->name); 
1990/0312    
 
	/* 
	 *  open a stream for the csc and push urp onto it 
1990/0728/sys/src/9/gnot/devdk.c:495,5011990/08101/sys/src/9/gnot/devdk.c:498,504
1990/0312    
	/* 
	 *  start a process to deal with it 
	 */ 
1990/0728    
	sprint(buf, "csckproc%d", dp->ncsc); 
1990/08101    
	sprint(buf, "csc.%s.%d", dp->name, dp->ncsc); 
1990/0312    
	kproc(buf, dkcsckproc, dp); 
	poperror(); 
 
1990/0728/sys/src/9/gnot/devdk.c:1316,13231990/08101/sys/src/9/gnot/devdk.c:1319,1329
1990/0617    
	/* 
	 *  tell datakit we've rebooted. It should close all channels. 
	 */ 
1990/0707    
	if(dp->restart) 
1990/08101    
	if(dp->restart) { 
		DPRINT("dkcsckproc: restart %s\n", dp->name); 
1990/0707    
		dkmesg(dp, T_ALIVE, D_RESTART, 0, 0); 
1990/08101    
	} 
	DPRINT("dkcsckproc: closeall %s\n", dp->name); 
1990/0617    
	dkmesg(dp, T_CHG, D_CLOSEALL, 0, 0); 
1990/0312    
 
	/* 
1990/08101/sys/src/9/gnot/devdk.c:125,1301990/08163/sys/src/9/gnot/devdk.c:125,131 (short | long)
1990/0312    
	Chan	*csc;		/* common signalling line */ 
	Line	line[Nline]; 
1990/0707    
	int	restart; 
1990/08163    
	int	urpwindow; 
1990/0312    
}; 
static Dk dk[Ndk]; 
 
1990/08101/sys/src/9/gnot/devdk.c:429,4401990/08163/sys/src/9/gnot/devdk.c:430,442
1990/0312    
} 
 
/* 
1990/0707    
 *  configure a datakit multiplexor.  this takes 4 arguments separated 
1990/08163    
 *  configure a datakit multiplexor.  this takes 5 arguments separated 
1990/0312    
 *  by spaces: 
 *	the line number of the common signalling channel (must be > 0) 
 *	the number of lines in the device (optional) 
1990/0707    
 *	the word `restart' or `norestart' (optional/default==restart) 
1990/0312    
 *	the name of the dk (optional) 
1990/08163    
 *	the name of the dk (default==dk) 
 *	the urp window size (default==WS_2K) 
1990/0312    
 * 
 *  we can configure only once 
 */ 
1990/08101/sys/src/9/gnot/devdk.c:442,4481990/08163/sys/src/9/gnot/devdk.c:444,450
1990/0312    
dkmuxconfig(Dk *dp, Block *bp) 
{ 
	Chan *c; 
1990/0707    
	char *fields[4]; 
1990/08163    
	char *fields[5]; 
1990/0312    
	int n; 
	char buf[64]; 
	static int dktimeron; 
1990/08101/sys/src/9/gnot/devdk.c:456,4641990/08163/sys/src/9/gnot/devdk.c:458,469
1990/0312    
	 *  parse 
	 */ 
1990/0707    
	dp->restart = 1; 
	n = getfields((char *)bp->rptr, fields, 4, ' '); 
1990/08163    
	n = getfields((char *)bp->rptr, fields, 5, ' '); 
1990/0728    
	strcpy(dp->name, "dk"); 
1990/08163    
	dp->urpwindow = WS_2K; 
1990/0312    
	switch(n){ 
1990/08163    
	case 5: 
		dp->urpwindow = strtoul(fields[4], 0, 0); 
1990/0707    
	case 4: 
		strncpy(dp->name, fields[3], sizeof(dp->name)); 
1990/0312    
	case 3: 
1990/08101/sys/src/9/gnot/devdk.c:978,9841990/08163/sys/src/9/gnot/devdk.c:983,989
1990/0312    
	 *  tell the controller we want to make a call 
	 */ 
	DPRINT("dialout\n"); 
	dkmesg(dp, t_val, d_val, line, W_WINDOW(WS_2K,WS_2K,2)); 
1990/08163    
	dkmesg(dp, t_val, d_val, line, W_WINDOW(dp->urpwindow,dp->urpwindow,2)); 
1990/0312    
 
	/* 
	 *  if redial, wait for a dial tone (otherwise we might send 
1990/08163/sys/src/9/gnot/devdk.c:397,4031990/0905/sys/src/9/gnot/devdk.c:397,404 (short | long)
1990/0312    
/* 
 *  we assume that each put is a message. 
 * 
 *  add a 2 byte channel number to the start of each message 
1990/0905    
 *  add a 2 byte channel number to the start of each message, 
 *  low order byte first. 
1990/0312    
 */ 
static void 
dkoput(Queue *q, Block *bp) 
1990/08163/sys/src/9/gnot/devdk.c:415,4241990/0905/sys/src/9/gnot/devdk.c:416,422
1990/0312    
	dp = lp->dp; 
	line = lp - dp->line; 
 
	if(bp->base && bp->rptr - bp->base >= 2) 
		bp->rptr -= 2; 
1990/0315    
	else 
		panic("dkoput"); 
1990/0905    
	bp = padb(bp, 2); 
1990/0312    
	bp->rptr[0] = line; 
	bp->rptr[1] = line>>8; 
 
1990/0905/sys/src/9/gnot/devdk.c:558,5641990/0911/sys/src/9/gnot/devdk.c:558,563 (short | long)
1990/0312    
dkreset(void) 
{ 
1990/0321    
	newqinfo(&dkmuxinfo); 
1990/0717    
	urpreset(); 
1990/0312    
} 
 
/* 
1990/0911/sys/src/9/gnot/devdk.c:499,5041990/1004/sys/src/9/gnot/devdk.c:499,512 (short | long)
1990/0312    
	dp->csc = c; 
 
	/* 
1990/1004    
	 *  tell datakit we've rebooted. It should close all channels. 
	 */ 
	if(dp->restart) { 
		DPRINT("dkmuxconfig: restart %s\n", dp->name); 
		dkmesg(dp, T_ALIVE, D_RESTART, 0, 0); 
	} 
 
	/* 
1990/0312    
	 *  start a process to deal with it 
	 */ 
1990/08101    
	sprint(buf, "csc.%s.%d", dp->name, dp->ncsc); 
1990/0911/sys/src/9/gnot/devdk.c:1100,11081990/1004/sys/src/9/gnot/devdk.c:1108,1114
1990/0312    
		n = streamread(dc, dialstr, sizeof(dialstr)-1); 
		DPRINT("returns %d\n", n); 
		if(n <= 0) 
1990/0617    
{print("bad n\n"); 
1990/0312    
			error(0, Eio); 
1990/0617    
} 
1990/0312    
		dialstr[n] = 0; 
		DPRINT("dialstr = %s\n", dialstr); 
 
1990/0911/sys/src/9/gnot/devdk.c:1112,11181990/1004/sys/src/9/gnot/devdk.c:1118,1123
1990/0312    
		n = getfields(dialstr, line, 12, '\n'); 
		if (n < 2) { 
			DPRINT("bad dialstr from dk (1 line)\n"); 
1990/0617    
print("bad dialstr %d '%s'\n", n, dialstr); 
1990/0312    
			error(0, Eio); 
		} 
 
1990/0911/sys/src/9/gnot/devdk.c:1317,13321990/1004/sys/src/9/gnot/devdk.c:1322,1327
1990/0312    
	int i; 
 
	dp = (Dk *)a; 
1990/0617    
                 
	/* 
	 *  tell datakit we've rebooted. It should close all channels. 
	 */ 
1990/08101    
	if(dp->restart) { 
		DPRINT("dkcsckproc: restart %s\n", dp->name); 
1990/0707    
		dkmesg(dp, T_ALIVE, D_RESTART, 0, 0); 
1990/08101    
	} 
	DPRINT("dkcsckproc: closeall %s\n", dp->name); 
1990/0617    
	dkmesg(dp, T_CHG, D_CLOSEALL, 0, 0); 
1990/0312    
 
	/* 
	 *  loop forever listening 
1990/1004/sys/src/9/gnot/devdk.c:118,1241990/1018/sys/src/9/gnot/devdk.c:118,124 (short | long)
1990/0312    
struct Dk { 
	QLock; 
	int	ref; 
	char	name[64];	/* dk name */	 
1990/1018    
	char	name[64];	/* dk name */ 
1990/0312    
	Queue	*wq;		/* dk output queue */ 
	int	lines;		/* number of lines */ 
	int	ncsc;		/* csc line number */ 
1990/1004/sys/src/9/gnot/devdk.c:420,4301990/1018/sys/src/9/gnot/devdk.c:420,427
1990/0312    
	bp->rptr[0] = line; 
	bp->rptr[1] = line>>8; 
 
1990/05313    
	if(QFULL(dp->wq->next)){ 
		print("dk wq full\n"); 
		freeb(bp); 
	} else 
		PUTNEXT(dp->wq, bp); 
1990/1018    
	FLOWCTL(dp->wq); 
	PUTNEXT(dp->wq, bp); 
1990/0312    
} 
 
/* 
1990/1018/sys/src/9/gnot/devdk.c:206,2111990/1020/sys/src/9/gnot/devdk.c:206,212 (short | long)
1990/0312    
dkmuxopen(Queue *q, Stream *s) 
{ 
	Dk *dp; 
1990/1020    
	Line *lp; 
1990/0312    
	int i; 
 
	for(dp = dk; dp < &dk[Ndk]; dp++){ 
1990/1018/sys/src/9/gnot/devdk.c:222,2271990/1020/sys/src/9/gnot/devdk.c:223,231
1990/0312    
			dp->lines = 16; 
			dp->name[0] = 0; 
			dp->wq = WR(q); 
1990/1020    
			for(lp = dp->line; lp < &dp->line[Nline]; lp++) 
				if(lp->state != 0) 
					panic("dkmuxopen l %d s %lux", lp-dp->line, lp->state); 
1990/0312    
			qunlock(dp); 
			return; 
		} 
1990/1018/sys/src/9/gnot/devdk.c:1368,13821990/1020/sys/src/9/gnot/devdk.c:1372,1386
1990/0312    
{ 
	Line *lp; 
 
	if (line <= 0 || line >= dp->lines) { 
		/* tell controller this line is not in use */ 
		dkmesg(dp, T_CHG, D_CLOSE, line, 0); 
		return; 
	} 
	lp = &dp->line[line]; 
	switch (dialp->srv) { 
 
	case D_CLOSE:		/* remote shutdown */ 
1990/1020    
		if (line <= 0 || line >= dp->lines) { 
			/* tell controller this line is not in use */ 
			dkmesg(dp, T_CHG, D_CLOSE, line, 0); 
			return; 
		} 
		lp = &dp->line[line]; 
1990/0312    
		switch (lp->state) { 
 
		case Ldialing: 
1990/1018/sys/src/9/gnot/devdk.c:1407,14121990/1020/sys/src/9/gnot/devdk.c:1411,1422
1990/0312    
		break; 
	 
	case D_ISCLOSED:	/* acknowledging a local shutdown */ 
1990/1020    
		if (line <= 0 || line >= dp->lines) { 
			/* tell controller this line is not in use */ 
			dkmesg(dp, T_CHG, D_CLOSE, line, 0); 
			return; 
		} 
		lp = &dp->line[line]; 
1990/0312    
		switch (lp->state) { 
		case Llclose: 
		case Lclosed: 
1990/1018/sys/src/9/gnot/devdk.c:1421,14261990/1020/sys/src/9/gnot/devdk.c:1431,1466
1990/0312    
		} 
		break; 
 
1990/1020    
	case D_CLOSEALL: 
		for(line = dp->ncsc+1; line < dp->lines; line++){ 
			lp = &dp->line[line]; 
			switch (lp->state) { 
	 
			case Ldialing: 
				/* simulate a failed connection */ 
				dkreplymesg(dp, (Dkmsg *)0, line); 
				lp->state = Lrclose; 
				break; 
	 
			case Lrclose: 
			case Lconnected: 
			case Llistening: 
			case Lackwait: 
				dkhangup(lp); 
				lp->state = Lrclose; 
				break; 
	 
			case Lopened: 
				break; 
	 
			case Llclose: 
			case Lclosed: 
				lp->state = Lclosed; 
				break; 
			} 
		} 
		break; 
 
1990/0312    
	default: 
		print("unrecognized T_CHG\n"); 
	} 
1990/1018/sys/src/9/gnot/devdk.c:1503,15091990/1020/sys/src/9/gnot/devdk.c:1543,1549
1990/0312    
			 *  remind controller of dead lines and 
			 *  timeout calls that take to long 
			 */ 
			for (i=0; i<dp->lines; i++){ 
1990/1020    
			for (i=dp->ncsc+1; i<dp->lines; i++){ 
1990/0312    
				lp = &dp->line[i]; 
				switch(lp->state){ 
				case Llclose: 
1990/1020/sys/src/9/gnot/devdk.c:206,2121990/1022/sys/src/9/gnot/devdk.c:206,211 (short | long)
1990/0312    
dkmuxopen(Queue *q, Stream *s) 
{ 
	Dk *dp; 
1990/1020    
	Line *lp; 
1990/0312    
	int i; 
 
	for(dp = dk; dp < &dk[Ndk]; dp++){ 
1990/1020/sys/src/9/gnot/devdk.c:223,2311990/1022/sys/src/9/gnot/devdk.c:222,227
1990/0312    
			dp->lines = 16; 
			dp->name[0] = 0; 
			dp->wq = WR(q); 
1990/1020    
			for(lp = dp->line; lp < &dp->line[Nline]; lp++) 
				if(lp->state != 0) 
					panic("dkmuxopen l %d s %lux", lp-dp->line, lp->state); 
1990/0312    
			qunlock(dp); 
			return; 
		} 
1990/1022/sys/src/9/gnot/devdk.c:116,1251990/1024/sys/src/9/gnot/devdk.c:116,125 (short | long)
1990/0312    
 *  dkmux line discipline is pushed onto. 
 */ 
struct Dk { 
	QLock; 
	int	ref; 
1990/1024    
	Lock; 
1990/1018    
	char	name[64];	/* dk name */ 
1990/0312    
	Queue	*wq;		/* dk output queue */ 
1990/1024    
	Stream	*s; 
1990/0312    
	int	lines;		/* number of lines */ 
	int	ncsc;		/* csc line number */ 
	Chan	*csc;		/* common signalling line */ 
1990/1022/sys/src/9/gnot/devdk.c:189,1941990/1024/sys/src/9/gnot/devdk.c:189,195
1990/0312    
static void	dkchgmesg(Dk*, Dkmsg*, int); 
static void	dkreplymesg(Dk*, Dkmsg*, int); 
Chan*		dkopen(Chan*, int); 
1990/1024    
static void	dkhangup(Line*); 
1990/0312    
 
/* 
 *  the datakit multiplexor stream module definition 
1990/1022/sys/src/9/gnot/devdk.c:201,2061990/1024/sys/src/9/gnot/devdk.c:202,208
1990/0312    
 
/* 
 *  a new dkmux.  find a free dk structure and assign it to this queue. 
1990/1024    
 *  when we get though here dp->s is meaningful and the name is set to "/". 
1990/0312    
 */ 
static void 
dkmuxopen(Queue *q, Stream *s) 
1990/1022/sys/src/9/gnot/devdk.c:209,2191990/1024/sys/src/9/gnot/devdk.c:211,221
1990/0312    
	int i; 
 
	for(dp = dk; dp < &dk[Ndk]; dp++){ 
		if(dp->wq == 0){ 
			qlock(dp); 
			if(dp->wq) { 
1990/1024    
		if(dp->name[0]==0){ 
			lock(dp); 
			if(dp->name[0]){ 
1990/0312    
				/* someone was faster than us */ 
				qunlock(dp); 
1990/1024    
				unlock(dp); 
1990/0312    
				continue; 
			} 
			q->ptr = q->other->ptr = (void *)dp; 
1990/1022/sys/src/9/gnot/devdk.c:220,2281990/1024/sys/src/9/gnot/devdk.c:222,231
1990/0312    
			dp->csc = 0; 
			dp->ncsc = 4; 
			dp->lines = 16; 
			dp->name[0] = 0; 
1990/1024    
			strcpy(dp->name, "/"); 
1990/0312    
			dp->wq = WR(q); 
			qunlock(dp); 
1990/1024    
			dp->s = s; 
			unlock(dp); 
1990/0312    
			return; 
		} 
	} 
1990/1022/sys/src/9/gnot/devdk.c:236,2481990/1024/sys/src/9/gnot/devdk.c:239,260
1990/0312    
dkmuxclose(Queue *q) 
{ 
	Dk *dp; 
1990/1024    
	int i; 
1990/0312    
 
	dp = (Dk *)q->ptr; 
	qlock(dp); 
	if(dp->csc) 
		close(dp->csc); 
	dp->wq = 0; 
	qunlock(dp); 
1990/1024    
 
	/* 
	 *  if we're the last user of the stream, 
	 *  free the Dk structure 
	 */ 
	if(dp->s->inuse == 1) 
		dp->name[0] = 0; 
 
	/* 
	 *  hang up all datakit connections 
	 */ 
	for(i=dp->ncsc; i < dp->lines; i++) 
		dkhangup(&dp->line[i]); 
1990/0312    
} 
 
/* 
1990/1022/sys/src/9/gnot/devdk.c:272,2781990/1024/sys/src/9/gnot/devdk.c:284,290
1990/0312    
 * 
 *  Simplifying assumption:  one put == one message && the channel number 
 *	is in the first block.  If this isn't true, demultiplexing will not 
  *	work. 
1990/1024    
 *	work. 
1990/0312    
 */ 
static void 
dkmuxiput(Queue *q, Block *bp) 
1990/1022/sys/src/9/gnot/devdk.c:608,6281990/1024/sys/src/9/gnot/devdk.c:620,664
1990/0728    
	if(*spec == 0) 
		spec = "dk"; 
1990/0312    
	for(dp = dk; dp < &dk[Ndk]; dp++){ 
		qlock(dp); 
		if(dp->wq && strcmp(spec, dp->name)==0) { 
			dp->ref++; 
			qunlock(dp); 
1990/1024    
		lock(dp); 
		if(strcmp(spec, dp->name)==0) 
1990/0312    
			break; 
		} 
		qunlock(dp); 
1990/1024    
		unlock(dp); 
1990/0312    
	} 
	if(dp == &dk[Ndk]) 
		error(0, Enoifc); 
1990/1024    
 
	/* 
	 *  don't let the multiplexed stream disappear under us 
	 */ 
	if(streamenter(dp->s) < 0){ 
		/* 
		 *  it's closing down, forget it 
		 */ 
		unlock(dp); 
		error(0, Ehungup); 
	} 
 
	/* 
	 *  return the new channel 
	 */ 
	if(waserror()){ 
		if(streamexit(dp->s, 0) == 0) 
			dp->name[0] = 0; 
		unlock(dp); 
		nexterror(); 
	} 
1990/0312    
	c = devattach('k', spec); 
	c->dev = dp - dk; 
1990/1024    
	unlock(dp); 
	poperror(); 
1990/0312    
	return c; 
} 
 
1990/1024    
/* 
 *  clone as long as the multiplexed channel is not closing 
 *  down 
 */ 
1990/0312    
Chan* 
dkclone(Chan *c, Chan *nc) 
{ 
1990/1022/sys/src/9/gnot/devdk.c:629,6371990/1024/sys/src/9/gnot/devdk.c:665,672
1990/0312    
	Dk *dp; 
 
	dp = &dk[c->dev]; 
	qlock(dp); 
	dp->ref++; 
	qunlock(dp); 
1990/1024    
	if(streamenter(dp->s) < 0) 
		error(0, Ehungup); 
1990/0312    
	return devclone(c, nc); 
} 
 
1990/1022/sys/src/9/gnot/devdk.c:679,6881990/1024/sys/src/9/gnot/devdk.c:714,723
1990/0319    
			error(0, Ebadarg); 
	} else switch(STREAMTYPE(c->qid)){ 
	case Dcloneqid: 
1990/1024    
		dp = &dk[c->dev]; 
1990/0319    
		/* 
1990/0312    
		 *  get an unused device and open it's control file 
		 */ 
		dp = &dk[c->dev]; 
		end = &dp->line[dp->lines]; 
		for(lp = &dp->line[dp->ncsc+1]; lp < end; lp++){ 
			if(lp->state == Lclosed && canqlock(lp)){ 
1990/1022/sys/src/9/gnot/devdk.c:752,7611990/1024/sys/src/9/gnot/devdk.c:787,799
1990/0319    
	if(c->stream) 
1990/0312    
		streamclose(c); 
 
1990/1024    
	/* 
	 *  Let go of the mulitplexed stream.  If we're the last out, 
	 *  free dp. 
	 */ 
1990/0312    
	dp = &dk[c->dev]; 
	qlock(dp); 
	dp->ref--; 
	qunlock(dp); 
1990/1024    
	if(streamexit(dp->s, 0) == 0) 
		dp->name[0] = 0; 
1990/0312    
} 
 
long	  
1990/1022/sys/src/9/gnot/devdk.c:1320,13251990/1024/sys/src/9/gnot/devdk.c:1358,1374
1990/0312    
 
	dp = (Dk *)a; 
 
1990/1024    
	if(waserror()){ 
		Chan *csc; 
 
		csc = dp->csc; 
		lock(dp); 
		dp->csc = 0; 
		unlock(dp); 
		close(csc); 
		return; 
	} 
 
1990/0312    
	/* 
	 *  loop forever listening 
	 */ 
1990/1022/sys/src/9/gnot/devdk.c:1326,13311990/1024/sys/src/9/gnot/devdk.c:1375,1382
1990/0312    
	for(;;){ 
		n = streamread(dp->csc, (char *)&d, (long)sizeof(d)); 
		if(n != sizeof(d)){ 
1990/1024    
			if(n == 0) 
				error(0, Ehungup); 
1990/0312    
			print("strange csc message %d\n", n); 
			continue; 
		} 
1990/1022/sys/src/9/gnot/devdk.c:1527,15341990/1024/sys/src/9/gnot/devdk.c:1578,1589
1990/0312    
		 */ 
		for(dki=0; dki<Ndk; dki++){ 
			dp = &dk[dki]; 
			if(dp->csc==0) 
1990/1024    
			if(!canlock(dp)) 
1990/0312    
				continue; 
1990/1024    
			if(dp->csc==0){ 
				unlock(dp); 
				continue; 
			} 
1990/0312    
 
			/* 
			 * send keep alive 
1990/1022/sys/src/9/gnot/devdk.c:1553,15581990/1024/sys/src/9/gnot/devdk.c:1608,1614
1990/0312    
					break; 
				} 
			} 
1990/1024    
			unlock(dp); 
1990/0312    
		} 
		tsleep(&dkt, fuckit, 0, 7500); 
	} 
1990/1024/sys/src/9/gnot/devdk.c:117,1331990/1026/sys/src/9/gnot/devdk.c:117,136 (short | long)
1990/0312    
 */ 
struct Dk { 
1990/1024    
	Lock; 
1990/1026    
	int	opened; 
1990/1018    
	char	name[64];	/* dk name */ 
1990/0312    
	Queue	*wq;		/* dk output queue */ 
1990/1024    
	Stream	*s; 
1990/0312    
	int	lines;		/* number of lines */ 
	int	ncsc;		/* csc line number */ 
	Chan	*csc;		/* common signalling line */ 
1990/1026    
	Chan	*csc; 
1990/0312    
	Line	line[Nline]; 
1990/0707    
	int	restart; 
1990/08163    
	int	urpwindow; 
1990/1026    
	Rendez	timer; 
1990/0312    
}; 
static Dk dk[Ndk]; 
1990/1026    
static Lock dklock; 
1990/0312    
 
/* 
 *  conversation states (for Line.state) 
1990/1024/sys/src/9/gnot/devdk.c:178,1851990/1026/sys/src/9/gnot/devdk.c:181,189
1990/0312    
 *  predeclared 
 */ 
Chan*		dkattach(char*); 
static void	dkmuxconfig(Dk*, Block*); 
static int	dkmesg(Dk*, int, int, int, int); 
1990/1026    
static void	dkmuxconfig(Queue*, Block*); 
static Chan*	dkopenline(Dk*, int); 
static int	dkmesg(Chan*, int, int, int, int); 
1990/0312    
static void	dkcsckproc(void*); 
static int	dklisten(Chan*); 
static void	dkanswer(Chan*, int, int); 
1990/1024/sys/src/9/gnot/devdk.c:186,1921990/1026/sys/src/9/gnot/devdk.c:190,196
1990/0312    
static void	dkwindow(Chan*); 
static void	dkcall(int, Chan*, char*, char*, char*); 
static void	dktimer(void*); 
static void	dkchgmesg(Dk*, Dkmsg*, int); 
1990/1026    
static void	dkchgmesg(Chan*, Dk*, Dkmsg*, int); 
1990/0312    
static void	dkreplymesg(Dk*, Dkmsg*, int); 
Chan*		dkopen(Chan*, int); 
1990/1024    
static void	dkhangup(Line*); 
1990/1024/sys/src/9/gnot/devdk.c:201,2381990/1026/sys/src/9/gnot/devdk.c:205,253
1990/0312    
Qinfo dkmuxinfo = { dkmuxiput, dkmuxoput, dkmuxopen, dkmuxclose, "dkmux" }; 
 
/* 
 *  a new dkmux.  find a free dk structure and assign it to this queue. 
1990/1024    
 *  when we get though here dp->s is meaningful and the name is set to "/". 
1990/0312    
 */ 
static void 
dkmuxopen(Queue *q, Stream *s) 
1990/1026    
 *  Look for a dk struct with a name.  If none exists,  create one. 
 */  
static Dk * 
dkalloc(char *name) 
1990/0312    
{ 
	Dk *dp; 
	int i; 
1990/1026    
	Dk *freep; 
1990/0312    
 
1990/1026    
	lock(&dklock); 
	freep = 0; 
1990/0312    
	for(dp = dk; dp < &dk[Ndk]; dp++){ 
1990/1024    
		if(dp->name[0]==0){ 
			lock(dp); 
			if(dp->name[0]){ 
1990/0312    
				/* someone was faster than us */ 
1990/1024    
				unlock(dp); 
1990/0312    
				continue; 
			} 
			q->ptr = q->other->ptr = (void *)dp; 
			dp->csc = 0; 
			dp->ncsc = 4; 
			dp->lines = 16; 
1990/1024    
			strcpy(dp->name, "/"); 
1990/0312    
			dp->wq = WR(q); 
1990/1024    
			dp->s = s; 
			unlock(dp); 
1990/0312    
			return; 
1990/1026    
		if(strcmp(name, dp->name) == 0){ 
			unlock(&dklock); 
			return dp; 
1990/0312    
		} 
1990/1026    
		if(dp->name[0] == 0) 
			freep = dp; 
1990/0312    
	} 
	error(0, Enoifc); 
1990/1026    
	if(freep == 0){ 
		unlock(&dklock); 
		error(0, Enoifc); 
	} 
	dp = freep; 
	dp->opened = 0; 
	dp->s = 0; 
	dp->ncsc = 1; 
	strncpy(dp->name, name, sizeof(freep->name)); 
	unlock(&dklock); 
	return dp; 
1990/0312    
} 
 
/* 
1990/1026    
 *  a new dkmux.  find a free dk structure and assign it to this queue. 
 *  when we get though here dp->s is meaningful and the name is set to "/". 
 */ 
static void 
dkmuxopen(Queue *q, Stream *s) 
{ 
	RD(q)->ptr = s; 
	WR(q)->ptr = 0; 
} 
 
/* 
1990/0312    
 *  close down a dkmux 
 */ 
static void 
1990/1024/sys/src/9/gnot/devdk.c:241,2541990/1026/sys/src/9/gnot/devdk.c:256,272
1990/0312    
	Dk *dp; 
1990/1024    
	int i; 
1990/0312    
 
	dp = (Dk *)q->ptr; 
1990/1026    
	dp = WR(q)->ptr; 
	if(dp == 0) 
		return; 
1990/1024    
 
	/* 
	 *  if we're the last user of the stream, 
	 *  free the Dk structure 
1990/1026    
	 *  disallow new dkstopens() on this line. 
	 *  the lock syncs with dkstopen(). 
1990/1024    
	 */ 
	if(dp->s->inuse == 1) 
		dp->name[0] = 0; 
1990/1026    
	lock(dp); 
	dp->opened = 0; 
	unlock(dp); 
1990/1024    
 
	/* 
	 *  hang up all datakit connections 
1990/1024/sys/src/9/gnot/devdk.c:255,2601990/1026/sys/src/9/gnot/devdk.c:273,283
1990/1024    
	 */ 
	for(i=dp->ncsc; i < dp->lines; i++) 
		dkhangup(&dp->line[i]); 
1990/1026    
 
	/* 
	 *  wakeup the timer so it can die 
	 */ 
	wakeup(&dp->timer); 
1990/0312    
} 
 
/* 
1990/1024/sys/src/9/gnot/devdk.c:263,2741990/1026/sys/src/9/gnot/devdk.c:286,294
1990/0312    
static void 
dkmuxoput(Queue *q, Block *bp) 
{ 
	Dk *dp; 
                 
	dp = (Dk *)q->ptr; 
	if(bp->type != M_DATA){ 
		if(streamparse("config", bp)) 
			dkmuxconfig(dp, bp); 
1990/1026    
			dkmuxconfig(q, bp); 
1990/0312    
		else 
			PUTNEXT(q, bp); 
		return; 
1990/1024/sys/src/9/gnot/devdk.c:293,2981990/1026/sys/src/9/gnot/devdk.c:313,326
1990/0312    
	Line *lp; 
	int line; 
 
1990/1026    
	/* 
	 *  not configured yet 
	 */ 
	if(q->other->ptr == 0){ 
		freeb(bp); 
		return; 
	} 
 
1990/0312    
	dp = (Dk *)q->ptr; 
	if(bp->type != M_DATA){ 
		PUTNEXT(q, bp); 
1990/1024/sys/src/9/gnot/devdk.c:341,3461990/1026/sys/src/9/gnot/devdk.c:369,380
1990/0312    
	Line *lp; 
 
	dp = &dk[s->dev]; 
1990/1026    
	lock(dp); 
	if(dp->opened==0 || streamenter(dp->s)<0){ 
		unlock(dp); 
		error(0, Ehungup); 
	} 
	unlock(dp); 
1990/0312    
	q->other->ptr = q->ptr = lp = &dp->line[s->id]; 
	lp->dp = dp; 
	lp->rq = q; 
1990/1024/sys/src/9/gnot/devdk.c:356,3661990/1026/sys/src/9/gnot/devdk.c:390,421
1990/0312    
{ 
	Dk *dp; 
	Line *lp; 
1990/1026    
	Chan *c; 
1990/0312    
 
	lp = (Line *)q->ptr; 
	dp = lp->dp; 
 
	/* 
1990/1026    
	 *  decrement ref count on mux'd line 
	 */ 
	streamexit(dp->s, 0); 
 
	/* 
	 *  don't tell controller about closing down the csc 
	 */ 
	if(lp - dp->line == dp->ncsc) 
		goto out; 
 
	c = 0; 
	if(waserror()){ 
		if(c) 
			close(c); 
		lp->state = Lclosed; 
		goto out; 
	}	 
	c = dkopenline(dp, dp->ncsc); 
 
	/* 
1990/0312    
	 *  shake hands with dk 
	 */ 
	switch(lp->state){ 
1990/1024/sys/src/9/gnot/devdk.c:369,3901990/1026/sys/src/9/gnot/devdk.c:424,445
1990/0312    
		break; 
 
	case Lrclose: 
		dkmesg(dp, T_CHG, D_CLOSE, lp - dp->line, 0); 
1990/1026    
		dkmesg(c, T_CHG, D_CLOSE, lp - dp->line, 0); 
1990/0312    
		lp->state = Lclosed; 
		break; 
 
	case Lackwait: 
		dkmesg(dp, T_CHG, D_CLOSE, lp - dp->line, 0); 
1990/1026    
		dkmesg(c, T_CHG, D_CLOSE, lp - dp->line, 0); 
1990/0312    
		lp->state = Llclose; 
		break; 
 
	case Llistening: 
		dkmesg(dp, T_CHG, D_CLOSE, lp - dp->line, 0); 
1990/1026    
		dkmesg(c, T_CHG, D_CLOSE, lp - dp->line, 0); 
1990/0312    
		lp->state = Llclose; 
		break; 
 
	case Lconnected: 
		dkmesg(dp, T_CHG, D_CLOSE, lp - dp->line, 0); 
1990/1026    
		dkmesg(c, T_CHG, D_CLOSE, lp - dp->line, 0); 
1990/0312    
		lp->state = Llclose; 
		break; 
 
1990/1024/sys/src/9/gnot/devdk.c:391,3971990/1026/sys/src/9/gnot/devdk.c:446,455
1990/0312    
	case Lopened: 
		lp->state = Lclosed; 
	} 
1990/1026    
	poperror(); 
	close(c); 
1990/0312    
 
1990/1026    
out: 
1990/0312    
	qlock(lp); 
	lp->rq = 0; 
	qunlock(lp); 
1990/1024/sys/src/9/gnot/devdk.c:448,4851990/1026/sys/src/9/gnot/devdk.c:506,553
1990/0312    
 *  we can configure only once 
 */ 
static void 
dkmuxconfig(Dk *dp, Block *bp) 
1990/1026    
dkmuxconfig(Queue *q, Block *bp) 
1990/0312    
{ 
	Chan *c; 
1990/1026    
	Dk *dp; 
1990/08163    
	char *fields[5]; 
1990/0312    
	int n; 
	char buf[64]; 
	static int dktimeron; 
1990/1026    
	char name[NAMELEN]; 
	int lines; 
	int ncsc; 
	int restart; 
	int window; 
1990/0312    
 
	if(dp->csc != 0){ 
1990/1026    
	if(WR(q)->ptr){ 
1990/0312    
		freeb(bp); 
		error(0, Ebadarg); 
1990/1026    
		error(0, Egreg); 
1990/0312    
	} 
 
	/* 
1990/1026    
	 *  defaults 
	 */ 
	ncsc = 1; 
	restart = 1; 
	lines = 16; 
	window = WS_2K; 
	strcpy(name, "dk"); 
 
	/* 
1990/0312    
	 *  parse 
	 */ 
1990/0707    
	dp->restart = 1; 
1990/08163    
	n = getfields((char *)bp->rptr, fields, 5, ' '); 
1990/0728    
	strcpy(dp->name, "dk"); 
1990/08163    
	dp->urpwindow = WS_2K; 
1990/0312    
	switch(n){ 
1990/08163    
	case 5: 
		dp->urpwindow = strtoul(fields[4], 0, 0); 
1990/1026    
		window = strtoul(fields[4], 0, 0); 
1990/0707    
	case 4: 
		strncpy(dp->name, fields[3], sizeof(dp->name)); 
1990/1026    
		strncpy(name, fields[3], sizeof(name)); 
1990/0312    
	case 3: 
1990/0707    
		if(strcmp(fields[2], "restart")!=0) 
			dp->restart = 0; 
1990/1026    
			restart = 0; 
1990/0312    
	case 2: 
		dp->lines = strtoul(fields[1], 0, 0); 
1990/1026    
		lines = strtoul(fields[1], 0, 0); 
1990/0312    
	case 1: 
		dp->ncsc = strtoul(fields[0], 0, 0); 
1990/1026    
		ncsc = strtoul(fields[0], 0, 0); 
1990/0312    
		break; 
	default: 
		freeb(bp); 
1990/1024/sys/src/9/gnot/devdk.c:486,5341990/1026/sys/src/9/gnot/devdk.c:554,607
1990/0312    
		error(0, Ebadarg); 
	} 
	freeb(bp); 
	if(dp->ncsc <= 0 || dp->lines <= dp->ncsc){ 
		dp->lines = 16; 
1990/1026    
	if(ncsc <= 0 || lines <= ncsc) 
1990/0312    
		error(0, Ebadarg); 
	} 
1990/08101    
	DPRINT("dkmuxconfig: ncsc=%d, lines=%d, restart=%d, name=\"%s\"\n", 
		dp->ncsc, dp->lines, dp->restart, dp->name); 
1990/0312    
 
	/* 
	 *  open a stream for the csc and push urp onto it 
1990/1026    
	 *  set up 
1990/0312    
	 */ 
	c = 0; 
	if(waserror()){ 
		if(c) 
			close(c); 
		nexterror(); 
1990/1026    
	dp = dkalloc(name); 
	lock(dp); 
	if(dp->opened){ 
		unlock(dp); 
		error(0, Ebadarg); 
1990/0312    
	} 
	c = dkattach(dp->name); 
	c->qid = STREAMQID(dp->ncsc, Sdataqid); 
	dkopen(c, ORDWR); 
	dp->csc = c; 
1990/1026    
	dp->ncsc = ncsc; 
	dp->lines = lines; 
	dp->restart = restart; 
	dp->urpwindow = window; 
	dp->s = RD(q)->ptr; 
	q->ptr = q->other->ptr = dp; 
	dp->opened = 1; 
	dp->wq = WR(q); 
	unlock(dp); 
1990/0312    
 
	/* 
1990/1026    
	 *  open csc here so that boot, dktimer, and dkcsckproc aren't 
	 *  all fighting for it at once. 
	 */ 
	dp->csc = dkopenline(dp, dp->ncsc); 
 
	/* 
1990/1004    
	 *  tell datakit we've rebooted. It should close all channels. 
1990/1026    
	 *  do this here to get it done before trying to open a channel. 
1990/1004    
	 */ 
	if(dp->restart) { 
		DPRINT("dkmuxconfig: restart %s\n", dp->name); 
		dkmesg(dp, T_ALIVE, D_RESTART, 0, 0); 
1990/1026    
		DPRINT("dktimer: restart %s\n", dp->name); 
		dkmesg(dp->csc, T_ALIVE, D_RESTART, 0, 0); 
1990/1004    
	} 
 
	/* 
1990/0312    
	 *  start a process to deal with it 
1990/1026    
	 *  start a process to listen to csc messages 
1990/0312    
	 */ 
1990/08101    
	sprint(buf, "csc.%s.%d", dp->name, dp->ncsc); 
1990/0312    
	kproc(buf, dkcsckproc, dp); 
	poperror(); 
 
	/* 
	 *  start a keepalive process if one doesn't exist 
1990/1026    
	 *  start a keepalive process 
1990/0312    
	 */ 
	if(dktimeron == 0){ 
		dktimeron = 1; 
1990/0728    
		kproc("dktimer", dktimer, 0); 
1990/0312    
	} 
1990/1026    
	sprint(buf, "timer.%s.%d", dp->name, dp->ncsc); 
	kproc(buf, dktimer, dp); 
1990/0312    
} 
 
/* 
1990/1024/sys/src/9/gnot/devdk.c:619,6721990/1026/sys/src/9/gnot/devdk.c:692,710
1990/0312    
	 */ 
1990/0728    
	if(*spec == 0) 
		spec = "dk"; 
1990/0312    
	for(dp = dk; dp < &dk[Ndk]; dp++){ 
1990/1024    
		lock(dp); 
		if(strcmp(spec, dp->name)==0) 
1990/0312    
			break; 
1990/1024    
		unlock(dp); 
1990/0312    
	} 
	if(dp == &dk[Ndk]) 
		error(0, Enoifc); 
1990/1026    
	dp = dkalloc(spec); 
1990/1024    
 
	/* 
	 *  don't let the multiplexed stream disappear under us 
	 */ 
	if(streamenter(dp->s) < 0){ 
		/* 
		 *  it's closing down, forget it 
		 */ 
		unlock(dp); 
		error(0, Ehungup); 
	} 
                 
	/* 
	 *  return the new channel 
	 */ 
	if(waserror()){ 
		if(streamexit(dp->s, 0) == 0) 
			dp->name[0] = 0; 
		unlock(dp); 
		nexterror(); 
	} 
1990/0312    
	c = devattach('k', spec); 
	c->dev = dp - dk; 
1990/1024    
	unlock(dp); 
	poperror(); 
1990/0312    
	return c; 
} 
 
1990/1024    
/* 
 *  clone as long as the multiplexed channel is not closing 
 *  down 
 */ 
1990/0312    
Chan* 
dkclone(Chan *c, Chan *nc) 
{ 
	Dk *dp; 
                 
	dp = &dk[c->dev]; 
1990/1024    
	if(streamenter(dp->s) < 0) 
		error(0, Ehungup); 
1990/0312    
	return devclone(c, nc); 
} 
 
1990/1024/sys/src/9/gnot/devdk.c:783,7991990/1026/sys/src/9/gnot/devdk.c:821,828
1990/0312    
{ 
	Dk *dp; 
 
1990/05313    
	/* real closing happens in dkstclose */ 
1990/0319    
	if(c->stream) 
1990/0312    
		streamclose(c); 
                 
1990/1024    
	/* 
	 *  Let go of the mulitplexed stream.  If we're the last out, 
	 *  free dp. 
	 */ 
1990/0312    
	dp = &dk[c->dev]; 
1990/1024    
	if(streamexit(dp->s, 0) == 0) 
		dp->name[0] = 0; 
1990/0312    
} 
 
long	  
1990/1024/sys/src/9/gnot/devdk.c:900,9151990/1026/sys/src/9/gnot/devdk.c:929,963
1990/0312    
} 
 
/* 
1990/1026    
 *  open the common signalling channel 
 */ 
static Chan* 
dkopenline(Dk *dp, int line) 
{ 
	Chan *c; 
 
	c = 0; 
	if(waserror()){ 
		if(c) 
			close(c); 
		nexterror(); 
	} 
	c = dkattach(dp->name); 
	c->qid = STREAMQID(line, Sdataqid); 
	dkopen(c, ORDWR); 
	poperror(); 
 
	return c; 
} 
 
/* 
1990/0312    
 *  send a message to the datakit on the common signaling line 
 */ 
static int 
dkmesg(Dk *dp, int type, int srv, int p0, int p1) 
1990/1026    
dkmesg(Chan *c, int type, int srv, int p0, int p1) 
1990/0312    
{ 
	Dkmsg d; 
	Block *bp; 
 
	if(dp->csc == 0) 
		return -1; 
1990/0728    
	if(waserror()){ 
		print("dkmesg: error\n"); 
1990/0312    
		return -1; 
1990/1024/sys/src/9/gnot/devdk.c:926,9321990/1026/sys/src/9/gnot/devdk.c:974,980
1990/0312    
	d.param3h = 0; 
	d.param4l = 0; 
	d.param4h = 0; 
	streamwrite(dp->csc, (char *)&d, sizeof(Dkmsg), 1); 
1990/1026    
	streamwrite(c, (char *)&d, sizeof(Dkmsg), 1); 
1990/0312    
	poperror(); 
	return 0; 
} 
1990/1024/sys/src/9/gnot/devdk.c:952,9591990/1026/sys/src/9/gnot/devdk.c:1000,1008
1990/0312    
	Dk *dp; 
	Line *lp; 
	Chan *dc; 
1990/1026    
	Chan *csc; 
1990/0707    
	char *bang, *dot; 
1990/0312    
                 
1990/1026    
	 
1990/0312    
	line = STREAMID(c->qid); 
	dp = &dk[c->dev]; 
	lp = &dp->line[line]; 
1990/1024/sys/src/9/gnot/devdk.c:1006,10211990/1026/sys/src/9/gnot/devdk.c:1055,1076
1990/0312    
	} 
 
	/* 
	 *  open the data file 
1990/1026    
	 *  close temporary channels on error 
1990/0312    
	 */ 
	dc = dkattach(dp->name); 
1990/1026    
	dc = 0; 
	csc = 0; 
1990/0312    
	if(waserror()){ 
		close(dc); 
1990/1026    
		if(csc) 
			close(csc); 
		if(dc) 
			close(dc); 
1990/0312    
		nexterror(); 
	} 
	dc->qid = STREAMQID(line, Sdataqid); 
	dkopen(dc, ORDWR); 
 
1990/1026    
	/* 
	 *  open the data file 
	 */ 
	dc = dkopenline(dp, line); 
1990/0312    
	lp->calltolive = 4; 
	lp->state = Ldialing; 
 
1990/1024/sys/src/9/gnot/devdk.c:1023,10291990/1026/sys/src/9/gnot/devdk.c:1078,1087
1990/0312    
	 *  tell the controller we want to make a call 
	 */ 
	DPRINT("dialout\n"); 
1990/08163    
	dkmesg(dp, t_val, d_val, line, W_WINDOW(dp->urpwindow,dp->urpwindow,2)); 
1990/1026    
	csc = dkopenline(dp, dp->ncsc); 
	dkmesg(csc, t_val, d_val, line, W_WINDOW(dp->urpwindow,dp->urpwindow,2)); 
	close(csc); 
	csc = 0; 
1990/0312    
 
	/* 
	 *  if redial, wait for a dial tone (otherwise we might send 
1990/1024/sys/src/9/gnot/devdk.c:1354,13711990/1026/sys/src/9/gnot/devdk.c:1412,1422
1990/0312    
	Dk *dp; 
	Dkmsg d; 
	int line; 
	int i; 
 
	dp = (Dk *)a; 
1990/1026    
	dp = a; 
1990/0312    
 
1990/1024    
	if(waserror()){ 
		Chan *csc; 
                 
		csc = dp->csc; 
		lock(dp); 
		dp->csc = 0; 
		unlock(dp); 
		close(csc); 
1990/1026    
		close(dp->csc); 
1990/1024    
		return; 
	} 
 
1990/1024/sys/src/9/gnot/devdk.c:1385,13911990/1026/sys/src/9/gnot/devdk.c:1436,1442
1990/0312    
		switch (d.type) { 
 
		case T_CHG:	/* controller wants to close a line */ 
			dkchgmesg(dp, &d, line); 
1990/1026    
			dkchgmesg(dp->csc, dp, &d, line); 
1990/0312    
			break; 
		 
		case T_REPLY:	/* reply to a dial request */ 
1990/1024/sys/src/9/gnot/devdk.c:1415,14211990/1026/sys/src/9/gnot/devdk.c:1466,1472
1990/0312    
 *  datakit requests or confirms closing a line 
 */ 
static void 
dkchgmesg(Dk *dp, Dkmsg *dialp, int line) 
1990/1026    
dkchgmesg(Chan *c, Dk *dp, Dkmsg *dialp, int line) 
1990/0312    
{ 
	Line *lp; 
 
1990/1024/sys/src/9/gnot/devdk.c:1424,14301990/1026/sys/src/9/gnot/devdk.c:1475,1481
1990/0312    
	case D_CLOSE:		/* remote shutdown */ 
1990/1020    
		if (line <= 0 || line >= dp->lines) { 
			/* tell controller this line is not in use */ 
			dkmesg(dp, T_CHG, D_CLOSE, line, 0); 
1990/1026    
			dkmesg(c, T_CHG, D_CLOSE, line, 0); 
1990/1020    
			return; 
		} 
		lp = &dp->line[line]; 
1990/1024/sys/src/9/gnot/devdk.c:1445,14571990/1026/sys/src/9/gnot/devdk.c:1496,1508
1990/0312    
			break; 
 
		case Lopened: 
			dkmesg(dp, T_CHG, D_CLOSE, line, 0); 
1990/1026    
			dkmesg(c, T_CHG, D_CLOSE, line, 0); 
1990/0312    
			break; 
 
		case Llclose: 
		case Lclosed: 
			dkhangup(lp); 
			dkmesg(dp, T_CHG, D_CLOSE, line, 0); 
1990/1026    
			dkmesg(c, T_CHG, D_CLOSE, line, 0); 
1990/0312    
			lp->state = Lclosed; 
			break; 
		} 
1990/1024/sys/src/9/gnot/devdk.c:1460,14661990/1026/sys/src/9/gnot/devdk.c:1511,1517
1990/0312    
	case D_ISCLOSED:	/* acknowledging a local shutdown */ 
1990/1020    
		if (line <= 0 || line >= dp->lines) { 
			/* tell controller this line is not in use */ 
			dkmesg(dp, T_CHG, D_CLOSE, line, 0); 
1990/1026    
			dkmesg(c, T_CHG, D_CLOSE, line, 0); 
1990/1020    
			return; 
		} 
		lp = &dp->line[line]; 
1990/1024/sys/src/9/gnot/devdk.c:1554,15671990/1026/sys/src/9/gnot/devdk.c:1605,1613
1990/0312    
} 
 
/* 
 *  15-second timer for all interfaces 
1990/1026    
 *  send a I'm alive message every 7.5 seconds and remind the dk of 
 *  any closed channels it hasn't acknowledged. 
1990/0312    
 */ 
static Rendez dkt; 
static int 
fuckit(void *a) 
{ 
	return 0; 
} 
static void 
dktimer(void *a) 
{ 
1990/1024/sys/src/9/gnot/devdk.c:1568,16151990/1026/sys/src/9/gnot/devdk.c:1614,1661
1990/0312    
	int dki, i; 
	Dk *dp; 
	Line *lp; 
1990/1026    
	Chan *c; 
1990/0312    
 
1990/0728    
	while(waserror()) 
		print("dktimer: error\n"); 
1990/1026    
	c = 0; 
	if(waserror()){ 
		if(c) 
			close(c); 
		return; 
	} 
1990/0312    
 
1990/1026    
	/* 
	 *  open csc 
	 */ 
	dp = (Dk *)a; 
	c = dkopenline(dp, dp->ncsc); 
 
1990/0312    
	for(;;){ 
1990/1026    
		if(dp->opened==0) 
			error(0, Ehungup); 
 
1990/0312    
		/* 
		 *  loop through the active dks 
1990/1026    
		 * send keep alive 
1990/0312    
		 */ 
		for(dki=0; dki<Ndk; dki++){ 
			dp = &dk[dki]; 
1990/1024    
			if(!canlock(dp)) 
1990/0312    
				continue; 
1990/1024    
			if(dp->csc==0){ 
				unlock(dp); 
				continue; 
			} 
1990/1026    
		dkmesg(c, T_ALIVE, D_CONTINUE, 0, 0); 
1990/0312    
 
			/* 
			 * send keep alive 
			 */ 
			dkmesg(dp, T_ALIVE, D_CONTINUE, 0, 0); 
1990/1026    
		/* 
		 *  remind controller of dead lines and 
		 *  timeout calls that take to long 
		 */ 
		for (i=dp->ncsc+1; i<dp->lines; i++){ 
			lp = &dp->line[i]; 
			switch(lp->state){ 
			case Llclose: 
				dkmesg(c, T_CHG, D_CLOSE, i, 0); 
				break; 
1990/0312    
 
			/* 
			 *  remind controller of dead lines and 
			 *  timeout calls that take to long 
			 */ 
1990/1020    
			for (i=dp->ncsc+1; i<dp->lines; i++){ 
1990/0312    
				lp = &dp->line[i]; 
				switch(lp->state){ 
				case Llclose: 
					dkmesg(dp, T_CHG, D_CLOSE, i, 0); 
1990/1026    
			case Ldialing: 
				if(lp->calltolive==0 || --lp->calltolive!=0) 
1990/0312    
					break; 
                 
				case Ldialing: 
					if(lp->calltolive==0 || --lp->calltolive!=0) 
						break; 
					dkreplymesg(dp, (Dkmsg *)0, i); 
					break; 
				} 
1990/1026    
				dkreplymesg(dp, (Dkmsg *)0, i); 
				break; 
1990/0312    
			} 
1990/1024    
			unlock(dp); 
1990/0312    
		} 
		tsleep(&dkt, fuckit, 0, 7500); 
1990/1026    
		tsleep(&dp->timer, return0, 0, 7500); 
1990/0312    
	} 
} 
1990/1026/sys/src/9/gnot/devdk.c:369,3741990/1101/sys/src/9/gnot/devdk.c:369,376 (short | long)
1990/0312    
	Line *lp; 
 
	dp = &dk[s->dev]; 
1990/1101    
	q->other->ptr = q->ptr = lp = &dp->line[s->id]; 
	lp->dp = dp; 
1990/1026    
	lock(dp); 
	if(dp->opened==0 || streamenter(dp->s)<0){ 
		unlock(dp); 
1990/1026/sys/src/9/gnot/devdk.c:375,3851990/1101/sys/src/9/gnot/devdk.c:377,385
1990/1026    
		error(0, Ehungup); 
	} 
	unlock(dp); 
1990/0312    
	q->other->ptr = q->ptr = lp = &dp->line[s->id]; 
	lp->dp = dp; 
	lp->rq = q; 
1990/05313    
	if(lp->state == Lclosed) 
1990/1101    
	if(lp->state==Lclosed) 
1990/05313    
		lp->state = Lopened; 
1990/1101    
	lp->rq = q; 
1990/0312    
} 
 
/* 
1990/1026/sys/src/9/gnot/devdk.c:396,4161990/1101/sys/src/9/gnot/devdk.c:396,429
1990/0312    
	dp = lp->dp; 
 
	/* 
1990/1101    
	 *  if we never got going, we're done 
	 */ 
	if(lp->rq == 0){ 
		lp->state = Lclosed;  
		return; 
	} 
 
	/* 
1990/1026    
	 *  decrement ref count on mux'd line 
	 */ 
	streamexit(dp->s, 0); 
 
	/* 
	 *  don't tell controller about closing down the csc 
1990/1101    
	 *  these states don't need the datakit 
1990/1026    
	 */ 
	if(lp - dp->line == dp->ncsc) 
1990/1101    
	switch(lp->state){ 
	case Lclosed: 
	case Llclose: 
	case Lopened: 
		lp->state = Lclosed; 
1990/1026    
		goto out; 
1990/1101    
	} 
1990/1026    
 
	c = 0; 
	if(waserror()){ 
1990/1101    
		lp->state = Lclosed; 
1990/1026    
		if(c) 
			close(c); 
		lp->state = Lclosed; 
		goto out; 
	}	 
	c = dkopenline(dp, dp->ncsc); 
1990/1026/sys/src/9/gnot/devdk.c:419,4281990/1101/sys/src/9/gnot/devdk.c:432,437
1990/0312    
	 *  shake hands with dk 
	 */ 
	switch(lp->state){ 
	case Lclosed: 
	case Llclose: 
		break; 
                 
	case Lrclose: 
1990/1026    
		dkmesg(c, T_CHG, D_CLOSE, lp - dp->line, 0); 
1990/0312    
		lp->state = Lclosed; 
1990/1026/sys/src/9/gnot/devdk.c:442,4501990/1101/sys/src/9/gnot/devdk.c:451,456
1990/1026    
		dkmesg(c, T_CHG, D_CLOSE, lp - dp->line, 0); 
1990/0312    
		lp->state = Llclose; 
		break; 
                 
	case Lopened: 
		lp->state = Lclosed; 
	} 
1990/1026    
	poperror(); 
	close(c); 
1990/1026/sys/src/9/gnot/devdk.c:769,7771990/1101/sys/src/9/gnot/devdk.c:775,784
1990/0312    
		} 
		if(lp == end) 
			error(0, Enodev); 
1990/1101    
		lp->state = Lopened; 
		qunlock(lp); 
1990/0312    
		streamopen(c, &dkinfo); 
		pushq(c->stream, &urpinfo); 
1990/05313    
		qunlock(lp); 
1990/0319    
		break; 
	case Dlistenqid: 
1990/0312    
		/* 
1990/1026/sys/src/9/gnot/devdk.c:819,8261990/1101/sys/src/9/gnot/devdk.c:826,831
1990/0312    
void	  
dkclose(Chan *c) 
{ 
	Dk *dp; 
                 
1990/0319    
	if(c->stream) 
1990/0312    
		streamclose(c); 
} 
1990/1026/sys/src/9/gnot/devdk.c:1183,11951990/1101/sys/src/9/gnot/devdk.c:1188,1198
1990/0312    
	/* 
	 *  open the data file 
	 */ 
	dc = dkattach(dp->name); 
1990/1101    
	dc = dkopenline(dp, STREAMID(c->qid)); 
1990/0312    
	if(waserror()){ 
		close(dc); 
		nexterror(); 
	} 
	dc->qid = STREAMQID(STREAMID(c->qid), Sdataqid); 
	dkopen(dc, ORDWR); 
 
	/* 
	 *  wait for a call in 
1990/1026/sys/src/9/gnot/devdk.c:1448,14581990/1101/sys/src/9/gnot/devdk.c:1451,1458
1990/0312    
			break; 
		 
		case T_RESTART:	/* datakit reboot */ 
			print("dk restart\n"); 
			if(line >=0 && line<dp->lines){ 
				print("maxlines=%d\n", line+1); 
1990/1101    
			if(line >=0 && line<dp->lines) 
1990/0312    
				dp->lines=line+1; 
			} 
			break; 
		 
		default: 
1990/1026/sys/src/9/gnot/devdk.c:1530,15351990/1101/sys/src/9/gnot/devdk.c:1530,1538
1990/0312    
		break; 
 
1990/1020    
	case D_CLOSEALL: 
1990/1101    
		/* 
		 *  datakit wants us to close all lines 
		 */ 
1990/1020    
		for(line = dp->ncsc+1; line < dp->lines; line++){ 
			lp = &dp->line[line]; 
			switch (lp->state) { 
1990/1026/sys/src/9/gnot/devdk.c:1544,15511990/1101/sys/src/9/gnot/devdk.c:1547,1554
1990/1020    
			case Lconnected: 
			case Llistening: 
			case Lackwait: 
				dkhangup(lp); 
				lp->state = Lrclose; 
1990/1101    
				dkhangup(lp); 
1990/1020    
				break; 
	 
			case Lopened: 
1990/1026/sys/src/9/gnot/devdk.c:1618,16231990/1101/sys/src/9/gnot/devdk.c:1621,1641
1990/0312    
 
1990/1026    
	c = 0; 
	if(waserror()){ 
1990/1101    
		/* 
		 *  hang up any calls waiting for the dk 
		 */ 
		for (i=dp->ncsc+1; i<dp->lines; i++){ 
			lp = &dp->line[i]; 
			switch(lp->state){ 
			case Llclose: 
				lp->state = Lclosed; 
				break; 
 
			case Ldialing: 
				dkreplymesg(dp, (Dkmsg *)0, i); 
				break; 
			} 
		} 
1990/1026    
		if(c) 
			close(c); 
		return; 
1990/1101/sys/src/9/gnot/devdk.c:377,3851990/1104/sys/src/9/gnot/devdk.c:377,385 (short | long)
1990/1026    
		error(0, Ehungup); 
	} 
	unlock(dp); 
1990/1104    
	lp->rq = q; 
1990/1101    
	if(lp->state==Lclosed) 
1990/05313    
		lp->state = Lopened; 
1990/1101    
	lp->rq = q; 
1990/0312    
} 
 
/* 
1990/1104/sys/src/9/gnot/devdk.c:202,2081990/11151/sys/src/9/gnot/devdk.c:202,215 (short | long)
1990/0312    
static void dkmuxclose(Queue *); 
static void dkmuxoput(Queue *, Block *); 
static void dkmuxiput(Queue *, Block *); 
Qinfo dkmuxinfo = { dkmuxiput, dkmuxoput, dkmuxopen, dkmuxclose, "dkmux" }; 
1990/11151    
Qinfo dkmuxinfo = 
{ 
	dkmuxiput, 
	dkmuxoput, 
	dkmuxopen, 
	dkmuxclose, 
	"dkmux" 
}; 
1990/0312    
 
/* 
1990/1026    
 *  Look for a dk struct with a name.  If none exists,  create one. 
1990/1104/sys/src/9/gnot/devdk.c:357,3631990/11151/sys/src/9/gnot/devdk.c:364,377
1990/0312    
static void dkstclose(Queue *); 
static void dkoput(Queue *, Block *); 
static void dkiput(Queue *, Block *); 
Qinfo dkinfo = { dkiput, dkoput, dkstopen, dkstclose, "dk" }; 
1990/11151    
Qinfo dkinfo = 
{ 
	dkiput, 
	dkoput, 
	dkstopen, 
	dkstclose, 
	"dk" 
}; 
1990/0312    
 
/* 
 *  open and save a pointer to the conversation 
Too many diffs (26 > 25). Stopping.


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)