示例#1
0
static void
loopbackclose(Chan *c)
{
	Loop *lb;
	int ref, chan;

	lb = c->aux;

	qlock(lb);

	/*
	 * closing either side hangs up the stream
	 */
	if((c->flag & COPEN) && TYPE(c->qid.path) == Qdata){
		chan = ID(c->qid.path);
		if(--lb->link[chan].ref == 0){
			qhangup(lb->link[chan ^ 1].oq, nil);
			looper(lb);
		}
	}


	/*
	 *  if both sides are closed, they are reusable
	 */
	if(lb->link[0].ref == 0 && lb->link[1].ref == 0){
		for(chan = 0; chan < 2; chan++){
			closelink(&lb->link[chan], 0);
			qreopen(lb->link[chan].iq);
			qreopen(lb->link[chan].oq);
			qsetlimit(lb->link[chan].oq, lb->link[chan].limit);
			qsetlimit(lb->link[chan].iq, lb->link[chan].limit);
		}
	}
	ref = --lb->ref;
	if(ref == 0)
		freelb(lb);
	qunlock(lb);
}
示例#2
0
static long
loopbackwrite(Chan *c, void *va, long n, vlong off)
{
	Loop *lb;
	Link *link;
	Cmdbuf *volatile cb;
	Block *volatile bp;
	vlong d0, d0ns;
	long dn, dnns;

	switch(TYPE(c->qid.path)){
	case Qdata:
		bp = allocb(n);
		if(waserror()){
			freeb(bp);
			nexterror();
		}
		memmove(bp->wp, va, n);
		poperror();
		bp->wp += n;
		return loopbackbwrite(c, bp, off);
	case Qctl:
		lb = c->aux;
		link = &lb->link[ID(c->qid.path)];
		cb = parsecmd(va, n);
		if(waserror()){
			free(cb);
			nexterror();
		}
		if(cb->nf < 1)
			error("short control request");
		if(strcmp(cb->f[0], "delay") == 0){
			if(cb->nf != 3)
				error("usage: delay latency bytedelay");
			d0ns = strtoll(cb->f[1], nil, 10);
			dnns = strtol(cb->f[2], nil, 10);

			/*
			 * it takes about 20000 cycles on a pentium ii
			 * to run pushlink; perhaps this should be accounted.
			 */

			ilock(link);
			link->delay0ns = d0ns;
			link->delaynns = dnns;
			iunlock(link);
		}else if(strcmp(cb->f[0], "indrop") == 0){
			if(cb->nf != 2)
				error("usage: indrop [01]");
			ilock(link);
			link->indrop = strtol(cb->f[1], nil, 0) != 0;
			iunlock(link);
		}else if(strcmp(cb->f[0], "droprate") == 0){
			if(cb->nf != 2)
				error("usage: droprate ofn");
			ilock(link);
			link->droprate = strtol(cb->f[1], nil, 0);
			iunlock(link);
		}else if(strcmp(cb->f[0], "limit") == 0){
			if(cb->nf != 2)
				error("usage: limit maxqsize");
			ilock(link);
			link->limit = strtol(cb->f[1], nil, 0);
			qsetlimit(link->oq, link->limit);
			qsetlimit(link->iq, link->limit);
			iunlock(link);
		}else if(strcmp(cb->f[0], "reset") == 0){
			if(cb->nf != 1)
				error("usage: reset");
			ilock(link);
			link->packets = 0;
			link->bytes = 0;
			link->indrop = 0;
			link->soverflows = 0;
			link->drops = 0;
			iunlock(link);
		}else
			error("unknown control request");
		poperror();
		free(cb);
		break;
	default:
		error(Eperm);
	}

	return n;
}
示例#3
0
int
uartctl(Uart *p, char *cmd)
{
	char *f[16];
	int i, n, nf;

	nf = tokenize(cmd, f, nelem(f));
	for(i = 0; i < nf; i++){
		if(strncmp(f[i], "break", 5) == 0){
			(*p->phys->dobreak)(p, 0);
			continue;
		}

		n = atoi(f[i]+1);
		switch(*f[i]){
		case 'B':
		case 'b':
			uartdrainoutput(p);
			if((*p->phys->baud)(p, n) < 0)
				return -1;
			break;
		case 'C':
		case 'c':
			p->hup_dcd = n;
			break;
		case 'D':
		case 'd':
			uartdrainoutput(p);
			(*p->phys->dtr)(p, n);
			break;
		case 'E':
		case 'e':
			p->hup_dsr = n;
			break;
		case 'F':
		case 'f':
			if(p->oq != nil)
				qflush(p->oq);
			break;
		case 'H':
		case 'h':
			if(p->iq != nil)
				qhangup(p->iq, 0);
			if(p->oq != nil)
				qhangup(p->oq, 0);
			break;
		case 'I':
		case 'i':
			uartdrainoutput(p);
			(*p->phys->fifo)(p, n);
			break;
		case 'K':
		case 'k':
			uartdrainoutput(p);
			(*p->phys->dobreak)(p, n);
			break;
		case 'L':
		case 'l':
			uartdrainoutput(p);
			if((*p->phys->bits)(p, n) < 0)
				return -1;
			break;
		case 'M':
		case 'm':
			uartdrainoutput(p);
			(*p->phys->modemctl)(p, n);
			break;
		case 'N':
		case 'n':
			if(p->oq != nil)
				qnoblock(p->oq, n);
			break;
		case 'P':
		case 'p':
			uartdrainoutput(p);
			if((*p->phys->parity)(p, *(f[i]+1)) < 0)
				return -1;
			break;
		case 'Q':
		case 'q':
			if(p->iq != nil)
				qsetlimit(p->iq, n);
			if(p->oq != nil)
				qsetlimit(p->oq, n);
			break;
		case 'R':
		case 'r':
			uartdrainoutput(p);
			(*p->phys->rts)(p, n);
			break;
		case 'S':
		case 's':
			uartdrainoutput(p);
			if((*p->phys->stop)(p, n) < 0)
				return -1;
			break;
		case 'W':
		case 'w':
			if(uarttimer == nil || n < 1)
				return -1;
			uarttimer->tns = (int64_t)n * 100000LL;
			break;
		case 'X':
		case 'x':
			if(p->enabled){
				ilock(&p->tlock);
				p->xonoff = n;
				iunlock(&p->tlock);
			}
			break;
		}
	}
	return 0;
}
示例#4
0
文件: devuart.c 项目: 8l/inferno
static void
uartctl(Uart *p, char *cmd)
{
	int i, n;

	/* let output drain for a while (up to 4 secs) */
	for(i = 0; i < 200 && (qlen(p->oq) || (readstatus(p) & USTAT_TC) == 0); i++)
		tsleep(&up->sleep, return0, 0, 20);

	if(strncmp(cmd, "break", 5) == 0){
		uartbreak(p, 0);
		return;
	}

	n = atoi(cmd+1);
	switch(*cmd){
	case 'B':
	case 'b':
		if(n <= 0) 
			error(Ebadarg);
		p->bps = n;
		uartset(p);
		break;
	case 'f':
	case 'F':
		qflush(p->oq);
		break;
	case 'H':
	case 'h':
		qhangup(p->iq, 0);
		qhangup(p->oq, 0);
		break;
	case 'L':
	case 'l':
		if(n < 7 || n > 8)
			error(Ebadarg);
		p->bits = n;
		uartset(p);
		break;
	case 'n':
	case 'N':
		qnoblock(p->oq, n);
		break;
	case 'P':
	case 'p':
		p->parity = *(cmd+1);
		uartset(p);
		break;
	case 'K':
	case 'k':
		uartbreak(p, n);
		break;
	case 'Q':
	case 'q':
		qsetlimit(p->iq, n);
		qsetlimit(p->oq, n);
		break;
	case 's':
	case 'S':
		if(n < 1 || n > 2)
			error(Ebadarg);
		p->stop = n;
		uartset(p);
		break;
	}
}