Example #1
0
ulong
procpagecount(Proc *p)
{
	Segment *s;
	ulong pages;
	int i;

	eqlock(&p->seglock);
	if(waserror()){
		qunlock(&p->seglock);
		nexterror();
	}
	pages = 0;
	for(i=0; i<NSEG; i++){
		if((s = p->seg[i]) != nil){
			eqlock(s);
			pages += mcountseg(s);
			qunlock(s);
		}
	}
	qunlock(&p->seglock);
	poperror();

	return pages;
}
Example #2
0
static long
audioread(Chan *c, void *a, long n, vlong off)
{
	Audiochan *ac;
	Audio *adev;
	long (*fn)(Audio *, void *, long, vlong);

	ac = c->aux;
	adev = ac->adev;

	fn = nil;
	switch((ulong)c->qid.path){
	case Qdir:
		audiodir[Qaudio].length = adev->buffered ? adev->buffered(adev) : 0;
		return devdirread(c, a, n, audiodir, nelem(audiodir), devgen);
	case Qaudio:
		fn = adev->read;
		break;
	case Qaudiostat:
		fn = adev->status;
		break;
	case Qvolume:
		fn = adev->volread;
		break;
	}
	if(fn == nil)
		error(Egreg);

	eqlock(ac);
	if(waserror()){
		qunlock(ac);
		nexterror();
	}
	switch((ulong)c->qid.path){
	case Qaudiostat:
	case Qvolume:
		/* generate the text on first read */
		if(ac->data == nil || off == 0){
			long l;

			ac->data = nil;
			l = fn(adev, ac->buf, sizeof(ac->buf)-1, 0);
			if(l < 0)
				l = 0;
			ac->buf[l] = 0;
			ac->data = ac->buf;
		}
		/* then serve all requests from buffer */
		n = readstr(off, a, n, ac->data);
		break;

	default:
		n = fn(adev, a, n, off);
	}
	qunlock(ac);
	poperror();
	return n;
}
Example #3
0
static void
wpiattach(Ether *edev)
{
	FWImage *fw;
	Ctlr *ctlr;
	char *err;

	ctlr = edev->ctlr;
	eqlock(ctlr);
	if(waserror()){
		print("#l%d: %s\n", edev->ctlrno, up->errstr);
		if(ctlr->power)
			poweroff(ctlr);
		qunlock(ctlr);
		nexterror();
	}
	if(ctlr->attached == 0){
		if((csr32r(ctlr, Gpc) & RfKill) == 0)
			error("wifi disabled by switch");

		if(ctlr->wifi == nil){
			ctlr->wifi = wifiattach(edev, transmit);
			ctlr->wifi->rates = wpirates;
		}

		if(ctlr->fw == nil){
			fw = readfirmware();
			print("#l%d: firmware: %ux, size: %ux+%ux+%ux+%ux+%ux\n",
				edev->ctlrno, fw->version,
				fw->main.text.size, fw->main.data.size,
				fw->init.text.size, fw->init.data.size,
				fw->boot.text.size);
			ctlr->fw = fw;
		}

		if((err = reset(ctlr)) != nil)
			error(err);
		if((err = boot(ctlr)) != nil)
			error(err);

		ctlr->bcastnodeid = -1;
		ctlr->bssnodeid = -1;
		ctlr->channel = 1;
		ctlr->aid = 0;

		setoptions(edev);

		ctlr->attached = 1;

		kproc("wpirecover", wpirecover, edev);
	}
	qunlock(ctlr);
	poperror();
}
Example #4
0
/*
 *  get next block from a queue (up to a limit)
 */
Block*
qbread(Queue *q, int len)
{
	Block *b, *nb;
	int n;

	eqlock(&q->rlock);
	if(waserror()){
		qunlock(&q->rlock);
		nexterror();
	}

	ilock(q);
	switch(qwait(q)){
	case 0:
		/* queue closed */
		iunlock(q);
		qunlock(&q->rlock);
		poperror();
		return nil;
	case -1:
		/* multiple reads on a closed queue */
		iunlock(q);
		error(q->err);
	}

	/* if we get here, there's at least one block in the queue */
	b = qremove(q);
	n = BLEN(b);

	/* split block if it's too big and this is not a message queue */
	nb = b;
	if(n > len){
		if((q->state&Qmsg) == 0){
			n -= len;
			b = allocb(n);
			memmove(b->wp, nb->rp+len, n);
			b->wp += n;
			qputback(q, b);
		}
		nb->wp = nb->rp + len;
	}

	/* restart producer */
	qwakeup_iunlock(q);

	poperror();
	qunlock(&q->rlock);
	return nb;
}
Example #5
0
static long
audiowrite(Chan *c, void *a, long n, vlong off)
{
	Audiochan *ac;
	Audio *adev;
	long (*fn)(Audio *, void *, long, vlong);

	ac = c->aux;
	adev = ac->adev;

	fn = nil;
	switch((ulong)c->qid.path){
	case Qaudio:
		fn = adev->write;
		break;
	case Qaudioctl:
		fn = adev->ctl;
		break;
	case Qvolume:
		fn = adev->volwrite;
		break;
	}
	if(fn == nil)
		error(Egreg);

	eqlock(ac);
	if(waserror()){
		qunlock(ac);
		nexterror();
	}
	switch((ulong)c->qid.path){
	case Qaudioctl:
	case Qvolume:
		if(n >= sizeof(ac->buf))
			error(Etoobig);

		/* copy data to audiochan buffer so it can be modified */
		ac->data = nil;
		memmove(ac->buf, a, n);
		ac->buf[n] = 0;
		a = ac->buf;
		off = 0;
	}
	n = fn(adev, a, n, off);
	qunlock(ac);
	poperror();
	return n;
}
Example #6
0
/*
 *  flow control, wait for queue to get below the limit
 */
static void
qflow(Queue *q)
{
	for(;;){
		if(q->noblock || qnotfull(q))
			break;

		ilock(q);
		q->state |= Qflow;
		iunlock(q);

		eqlock(&q->wlock);
		if(waserror()){
			qunlock(&q->wlock);
			nexterror();
		}
		sleep(&q->wr, qnotfull, q);
		qunlock(&q->wlock);
		poperror();
	}
}
Example #7
0
/*
 *  read a queue.  if no data is queued, post a Block
 *  and wait on its Rendez.
 */
long
qread(Queue *q, void *vp, int len)
{
	Block *b, *first, **l;
	int m, n;

	eqlock(&q->rlock);
	if(waserror()){
		qunlock(&q->rlock);
		nexterror();
	}

	ilock(q);
again:
	switch(qwait(q)){
	case 0:
		/* queue closed */
		iunlock(q);
		qunlock(&q->rlock);
		poperror();
		return 0;
	case -1:
		/* multiple reads on a closed queue */
		iunlock(q);
		error(q->err);
	}

	/* if we get here, there's at least one block in the queue */
	if(q->state & Qcoalesce){
		/* when coalescing, 0 length blocks just go away */
		b = q->bfirst;
		m = BLEN(b);
		if(m <= 0){
			freeb(qremove(q));
			goto again;
		}

		/*  grab the first block plus as many
		 *  following blocks as will partially
		 *  fit in the read.
		 */
		n = 0;
		l = &first;
		for(;;) {
			*l = qremove(q);
			l = &b->next;
			n += m;
			if(n >= len || (b = q->bfirst) == nil)
				break;
			m = BLEN(b);
		}
	} else {
		first = qremove(q);
		n = BLEN(first);
	}

	/* copy to user space outside of the ilock */
	iunlock(q);
	b = bl2mem(vp, first, len);
	ilock(q);

	/* take care of any left over partial block */
	if(b != nil){
		n -= BLEN(b);
		if(q->state & Qmsg)
			freeb(b);
		else
			qputback(q, b);
	}

	/* restart producer */
	qwakeup_iunlock(q);

	poperror();
	qunlock(&q->rlock);
	return n;
}