Example #1
0
static void
loopbackread(void *a)
{
	Ipifc *ifc;
	Block *bp;
	LB *lb;

	ifc = a;
	lb = ifc->arg;
	lb->readp = up;	/* hide identity under a rock for unbind */
	if(waserror()){
		lb->readp = 0;
		pexit("hangup", 1);
	}
	for(;;){
		bp = qbread(lb->q, Maxtu);
		if(bp == nil)
			continue;
		ifc->in++;
		if(!canrlock(ifc)){
			freeb(bp);
			continue;
		}
		if(waserror()){
			runlock(ifc);
			nexterror();
		}
		if(ifc->lifc == nil)
			freeb(bp);
		else
			ipiput4(lb->f, ifc, bp);
		runlock(ifc);
		poperror();
	}
}
Example #2
0
/*
 *  called when a process writes to an interface's 'data'
 */
static void
ipifckick(void *x)
{
	Proc *up = externup();
	Conv *c = x;
	Block *bp;
	Ipifc *ifc;

	bp = qget(c->wq);
	if(bp == nil)
		return;

	ifc = (Ipifc*)c->ptcl;
	if(!canrlock(ifc)){
		freeb(bp);
		return;
	}
	if(waserror()){
		runlock(ifc);
		nexterror();
	}
	if(ifc->medium == nil || ifc->medium->pktin == nil)
		freeb(bp);
	else
		(*ifc->medium->pktin)(c->p->f, ifc, bp);
	runlock(ifc);
	poperror();
}
Example #3
0
static int
smscreceive(Dev *ep)
{
	Block *b;
	uint hd;
	int n;

	if(Doburst)
		b = allocb(Hsburst*512);
	else
		b = allocb(Maxpkt+4);
	if((n = read(ep->dfd, b->wp, b->lim - b->base)) < 0){
		freeb(b);
		return -1;
	}
	b->wp += n;
	while(BLEN(b) >= 4){
		hd = GET4(b->rp);
		b->rp += 4;
		n = hd >> 16;
		if(n > BLEN(b))
			break;
		if((hd & Rxerror) == 0){
			if(n == BLEN(b)){
				etheriq(b, 1);
				return 0;
			}
			etheriq(copyblock(b, n), 1);
		}
		b->rp += (n + 3) & ~3;
	}
	freeb(b);
	return 0;
}
Example #4
0
File: ipifc.c Project: 7perl/akaros
/*
 *  called when a process writes to an interface's 'data'
 */
static void ipifckick(void *x)
{
	ERRSTACK(1);
	struct conv *c = x;
	struct block *bp;
	struct Ipifc *ifc;

	bp = qget(c->wq);
	if (bp == NULL)
		return;

	ifc = (struct Ipifc *)c->ptcl;
	if (!canrlock(&ifc->rwlock)) {
		freeb(bp);
		return;
	}
	if (waserror()) {
		runlock(&ifc->rwlock);
		nexterror();
	}
	if (ifc->m == NULL || ifc->m->pktin == NULL)
		freeb(bp);
	else
		(*ifc->m->pktin) (c->p->f, ifc, bp);
	runlock(&ifc->rwlock);
	poperror();
}
Example #5
0
/*
 *  make sure the first block has at least n bytes
 */
Block*
pullupblock(Block *bp, int n)
{
	int i;
	Block *nbp;

	/*
	 *  this should almost always be true, it's
	 *  just to avoid every caller checking.
	 */
	if(BLEN(bp) >= n)
		return bp;

	/*
	 *  if not enough room in the first block,
	 *  add another to the front of the list.
	 */
	if(bp->lim - bp->rp < n){
		nbp = allocb(n);
		nbp->next = bp;
		bp = nbp;
	}

	/*
	 *  copy bytes from the trailing blocks into the first
	 */
	n -= BLEN(bp);
	while(nbp = bp->next){
		i = BLEN(nbp);
		if(i > n) {
			memmove(bp->wp, nbp->rp, n);
			pullupblockcnt++;
			bp->wp += n;
			nbp->rp += n;
			QDEBUG checkb(bp, "pullupblock 1");
			return bp;
		} else {
			/* shouldn't happen but why crash if it does */
			if(i < 0){
				print("pullup negative length packet, called from %#p\n",
					getcallerpc(&bp));
				i = 0;
			}
			memmove(bp->wp, nbp->rp, i);
			pullupblockcnt++;
			bp->wp += i;
			bp->next = nbp->next;
			nbp->next = 0;
			freeb(nbp);
			n -= i;
			if(n == 0){
				QDEBUG checkb(bp, "pullupblock 2");
				return bp;
			}
		}
	}
	freeb(bp);
	return 0;
}
Example #6
0
static void filter_process ( MSFilter *f ) {
    isac_encoder_struct_t* obj = (isac_encoder_struct_t*)f->data;

    mblk_t *im;
    mblk_t *om=NULL;
    u_int8_t* input_buf = NULL;
    WebRtc_Word16 ret;
    static int out_count = 0;

    // get the input data and put it into our buffered input
    while( (im = ms_queue_get( f->inputs[0] ) ) != NULL ) {
        ms_bufferizer_put( obj->bufferizer, im );
    }

    // feed the encoder with 160 16bit samples, until it has reached enough data
    // to produce a packet
    while( ms_bufferizer_get_avail(obj->bufferizer) > ISAC_SAMPLES_PER_ENCODE*2 ){

        om = allocb( WebRtcIsacfix_GetNewFrameLen(obj->isac), 0 );
        if(!input_buf) input_buf = ms_malloc( ISAC_SAMPLES_PER_ENCODE*2 );
        ms_bufferizer_read(obj->bufferizer, input_buf, ISAC_SAMPLES_PER_ENCODE*2);

        ret = WebRtcIsacfix_Encode(obj->isac,
                                   (const WebRtc_Word16*)input_buf,
                                   (WebRtc_Word16*)om->b_wptr);

        if( ret < 0) {

            ms_error( "WebRtcIsacfix_Encode error: %d", WebRtcIsacfix_GetErrorCode(obj->isac) );
            freeb(om);

        } else if( ret == 0 ) {
            // Encode() buffered the input, not yet able to produce a packet, continue feeding it
            // 160 samples per-call
            obj->ts += ISAC_SAMPLES_PER_ENCODE;
            freeb(om);

        } else {

            // a new packet has been encoded, send it
            obj->ts += ISAC_SAMPLES_PER_ENCODE;
            om->b_wptr += ret;
            out_count++;
//            ms_message("packet %d out, samples %d", out_count, obj->ts);

            mblk_set_timestamp_info( om, obj->ts );
            ms_queue_put(f->outputs[0], om);

            om = NULL;
        }

    }

    if( input_buf ){
        ms_free(input_buf);
    }
}
Example #7
0
static int32_t *
svc_clts_kgetres(SVCXPRT *clone_xprt, int size)
{
	/* LINTED pointer alignment */
	struct udp_data *ud = (struct udp_data *)clone_xprt->xp_p2buf;
	XDR *xdrs = &clone_xprt->xp_xdrout;
	mblk_t *mp;
	int32_t *buf;
	struct rpc_msg rply;

	/*
	 * Allocate an initial mblk for the response data.
	 */
	while ((mp = allocb(UD_INITSIZE, BPRI_LO)) == NULL) {
		if (strwaitbuf(UD_INITSIZE, BPRI_LO)) {
			return (FALSE);
		}
	}

	mp->b_cont = NULL;

	/*
	 * Initialize the XDR decode stream.  Additional mblks
	 * will be allocated if necessary.  They will be UD_MAXSIZE
	 * sized.
	 */
	xdrmblk_init(xdrs, mp, XDR_ENCODE, UD_MAXSIZE);

	/*
	 * Leave some space for protocol headers.
	 */
	(void) XDR_SETPOS(xdrs, 512);
	mp->b_rptr += 512;

	/*
	 * Assume a successful RPC since most of them are.
	 */
	rply.rm_xid = clone_xprt->xp_xid;
	rply.rm_direction = REPLY;
	rply.rm_reply.rp_stat = MSG_ACCEPTED;
	rply.acpted_rply.ar_verf = clone_xprt->xp_verf;
	rply.acpted_rply.ar_stat = SUCCESS;

	if (!xdr_replymsg_hdr(xdrs, &rply)) {
		freeb(mp);
		return (NULL);
	}

	buf = XDR_INLINE(xdrs, size);

	if (buf == NULL)
		freeb(mp);
	else
		ud->ud_resp->b_cont = mp;

	return (buf);
}
/*
 * Returns 1 if the caller should stop processing messages
 */
static int
mouse8042_process_data_msg(queue_t *q, mblk_t *mp, struct mouse_state *state)
{
	mblk_t *bp;
	mblk_t *next;

	bp = mp;
	do {
		while (bp->b_rptr < bp->b_wptr) {
			/*
			 * Detect an attempt to reset the mouse.  Lock out any
			 * further mouse writes until the reset has completed.
			 */
			if (*bp->b_rptr == MSERESET) {

				/*
				 * If we couldn't allocate memory and we
				 * we couldn't register a bufcall,
				 * mouse8042_initiate_reset returns 0 and
				 * has already used the message to send an
				 * error reply back upstream, so there is no
				 * need to deallocate or put this message back
				 * on the queue.
				 */
				if (mouse8042_initiate_reset(q, bp, state) == 0)
					return (1);

				/*
				 * If there's no data remaining in this block,
				 * free this block and put the following blocks
				 * of this message back on the queue. If putting
				 * the rest of the message back on the queue
				 * fails, free the the message.
				 */
				if (MBLKL(bp) == 0) {
					next = bp->b_cont;
					freeb(bp);
					bp = next;
				}
				if (bp != NULL) {
					if (!putbq(q, bp))
						freemsg(bp);
				}

				return (1);

			}
			ddi_put8(state->ms_handle,
			    state->ms_addr + I8042_INT_OUTPUT_DATA,
			    *bp->b_rptr++);
		}
		next = bp->b_cont;
		freeb(bp);
	} while ((bp = next) != NULL);

	return (0);
}
Example #9
0
File: qio.c Project: mtaufen/akaros
/*
 *  pad a block to the front (or the back if size is negative)
 */
struct block *padblock(struct block *bp, int size)
{
	int n;
	struct block *nbp;
	uint8_t bcksum = bp->flag & BCKSUM_FLAGS;
	uint16_t checksum_start = bp->checksum_start;
	uint16_t checksum_offset = bp->checksum_offset;
	uint16_t mss = bp->mss;

	QDEBUG checkb(bp, "padblock 1");
	if (size >= 0) {
		if (bp->rp - bp->base >= size) {
			bp->checksum_start += size;
			bp->rp -= size;
			return bp;
		}

		PANIC_EXTRA(bp);
		if (bp->next)
			panic("padblock %p", getcallerpc(&bp));
		n = BLEN(bp);
		padblockcnt++;
		nbp = block_alloc(size + n, MEM_WAIT);
		nbp->rp += size;
		nbp->wp = nbp->rp;
		memmove(nbp->wp, bp->rp, n);
		nbp->wp += n;
		freeb(bp);
		nbp->rp -= size;
	} else {
		size = -size;

		PANIC_EXTRA(bp);

		if (bp->next)
			panic("padblock %p", getcallerpc(&bp));

		if (bp->lim - bp->wp >= size)
			return bp;

		n = BLEN(bp);
		padblockcnt++;
		nbp = block_alloc(size + n, MEM_WAIT);
		memmove(nbp->wp, bp->rp, n);
		nbp->wp += n;
		freeb(bp);
	}
	if (bcksum) {
		nbp->flag |= bcksum;
		nbp->checksum_start = checksum_start;
		nbp->checksum_offset = checksum_offset;
		nbp->mss = mss;
	}
	QDEBUG checkb(nbp, "padblock 1");
	return nbp;
}
Example #10
0
static char*
initring(Ctlr *ctlr)
{
	RXQ *rx;
	TXQ *tx;
	int i, q;

	rx = &ctlr->rx;
	if(rx->b == nil)
		rx->b = malloc(sizeof(Block*) * Nrx);
	if(rx->p == nil)
		rx->p = mallocalign(sizeof(u32int) * Nrx, 16 * 1024, 0, 0);
	if(rx->b == nil || rx->p == nil)
		return "no memory for rx ring";
	for(i = 0; i<Nrx; i++){
		rx->p[i] = 0;
		if(rx->b[i] != nil){
			freeb(rx->b[i]);
			rx->b[i] = nil;
		}
		if(rbplant(ctlr, i) < 0)
			return "no memory for rx descriptors";
	}
	rx->i = 0;

	if(ctlr->shared == nil)
		ctlr->shared = mallocalign(4096, 4096, 0, 0);
	if(ctlr->shared == nil)
		return "no memory for shared buffer";
	memset(ctlr->shared, 0, 4096);

	for(q=0; q<nelem(ctlr->tx); q++){
		tx = &ctlr->tx[q];
		if(tx->b == nil)
			tx->b = malloc(sizeof(Block*) * Ntx);
		if(tx->d == nil)
			tx->d = mallocalign(Tdscsize * Ntx, 16 * 1024, 0, 0);
		if(tx->c == nil)
			tx->c = mallocalign(Tcmdsize * Ntx, 4, 0, 0);
		if(tx->b == nil || tx->d == nil || tx->c == nil)
			return "no memory for tx ring";
		memset(tx->d, 0, Tdscsize * Ntx);
		memset(tx->c, 0, Tcmdsize * Ntx);
		for(i=0; i<Ntx; i++){
			if(tx->b[i] != nil){
				freeb(tx->b[i]);
				tx->b[i] = nil;
			}
		}
		ctlr->shared->txbase[q] = PCIWADDR(tx->d);
		tx->i = 0;
		tx->n = 0;
		tx->lastcmd = 0;
	}
	return nil;
}
Example #11
0
static void
receive(Ether *ether)
{
	int i;
	ulong n;
	Block *b;
	Ctlr *ctlr = ether->ctlr;
	Rx *r;

	ethercheck(ether);
	for (i = Nrx-2; i > 0; i--) {
		r = &ctlr->rx[ctlr->rxhead];	/* *r is uncached */
		assert(((uintptr)r & (Descralign - 1)) == 0);
		if(r->cs & RCSdmaown)		/* descriptor busy? */
			break;

		b = ctlr->rxb[ctlr->rxhead];	/* got input buffer? */
		if (b == nil)
			panic("ether1116: nil ctlr->rxb[ctlr->rxhead] "
				"in receive");
		ctlr->rxb[ctlr->rxhead] = nil;
		ctlr->rxhead = NEXT(ctlr->rxhead, Nrx);

		if((r->cs & (RCSfirst|RCSlast)) != (RCSfirst|RCSlast)) {
			ctlr->nofirstlast++;	/* partial packet */
			freeb(b);
			continue;
		}
		if(r->cs & RCSmacerr) {
			freeb(b);
			continue;
		}

		n = r->countsize >> 16;		/* TODO includes 2 pad bytes? */
		assert(n >= 2 && n < 2048);

		/* clear any cached packet or part thereof */
		l2cacheuinvse(b->rp, n+2);
		cachedinvse(b->rp, n+2);
		b->wp = b->rp + n;
		/*
		 * skip hardware padding intended to align ipv4 address
		 * in memory (mv-s104860-u0 §8.3.4.1)
		 */
		b->rp += 2;
		etheriq(ether, b, 1);
		etheractive(ether);
		if (i % (Nrx / 2) == 0) {
			rxreplenish(ctlr);
			rxkick(ctlr);
		}
	}
	rxreplenish(ctlr);
	rxkick(ctlr);
}
Example #12
0
/**
 * ptem_qopen - STREAMS module open routine
 * @q: read queue
 * @devp: number of device
 * @oflag: flags to open(2s) call
 * @sflag: STREAMS flag
 * @crp: credentials pointer
 *
 * When ptem is pushed successfully, it assigns this Stream as a controlling
 * terminal if one has not already been assigend by sending a M_SETOPTS
 * message to the Stream head with the SO_ISTTY flag set.  (The Stream head
 * determines whether the process already has a controlling tty.)  If,
 * however, the O_NOCTTY flag was set to open (and appears in oflag as
 * FNOCTTY), then no controlling tty should be assigned.  It is the job of the
 * Stream head to detect this too.
 *
 * When the module is pushed, if we are using old TTY semantics we need to
 * send SO_NDELON to the Stream head in an M_SETOPTS.  It is typical to change
 * the Stream head water marks and packet sizes using SO_MINPSZ, SO_MAXPSZ,
 * SO_HIWAT and SO_LOWAT in the M_SETOPTS.
 *
 * As we don't know (and can't query) the state of the Stream head, we need to
 * set several options that should be correct if the Stream head started in
 * the default state (which it might not have).  SO_MREADOFF should be set as
 * we default to canonical mode and do not want read notifications.  Also
 * RMSGN mode to SO_RDOPT for canonical mode (RNORM for non-canonical).
 * SO_NODELIM should probably be set, but see the discussion under
 * M_SETOPTS(9).  SO_WROFF should be set to zero.  We may or may not want to
 * set the SO_STRHOLD feature.  Do not set it for now and see if we can get a
 * performance gain from it.
 */
static streamscall int
ptem_qopen(queue_t *q, dev_t *devp, int oflag, int sflag, cred_t *crp)
{
	if (q->q_ptr)
		return (0);	/* already open */
	if (sflag == MODOPEN && WR(q)->q_next != NULL) {
		struct stroptions *so;
		struct ptem *p;
		mblk_t *mp, *hp;

		if (!(hp = allocb(0, BPRI_WAITOK)))
			goto openfail;

		/* zero-length message block is good as it is */

		if (!(mp = allocb(sizeof(*so), BPRI_WAITOK))) {
			freeb(hp);
			goto openfail;
		}

		/* I don't really know what the point of this is, ldterm() will do this again.
		   Everything except the read options and SO_ISTTY the water marks and SO_READOPT
		   are defaults. */
		mp->b_datap->db_type = M_SETOPTS;
		so = (struct stroptions *) mp->b_rptr;
		mp->b_wptr += sizeof(*so);
		so->so_flags = SO_ISTTY;

		if (!(p = kmem_alloc(sizeof(*p), KM_SLEEP))) {
			freeb(mp);
			freeb(hp);
			goto openfail;
		}

		bzero(p, sizeof(*p));
		p->zero = hp;
		p->c.c_iflag = BRKINT | ICRNL | IXON | ISTRIP | IXANY;
		p->c.c_oflag = OPOST | ONLCR | TAB3;
		p->c.c_cflag = 0;
		p->c.c_lflag = ISIG | ICANON | ECHO | ECHOK;

		q->q_ptr = WR(q)->q_ptr = (void *) p;
		qprocson(q);

		putnext(q, mp);
		return (0);
	}
      openfail:
	return (OPENFAIL);
}
Example #13
0
long devbwrite(struct chan *c, struct block *bp, uint32_t offset)
{
    ERRSTACK(1);
    long n;

    if (waserror()) {
        freeb(bp);
        nexterror();
    }
    n = devtab[c->type].write(c, bp->rp, BLEN(bp), offset);
    poperror();
    freeb(bp);

    return n;
}
Example #14
0
long
devbwrite(Chan *c, Block *bp, ulong offset)
{
	long n;

	if(waserror()) {
		freeb(bp);
		nexterror();
	}
	n = devtab[c->type]->write(c, bp->rp, BLEN(bp), offset);
	poperror();
	freeb(bp);

	return n;
}
Example #15
0
File: qio.c Project: mtaufen/akaros
/* Returns a block with the remaining contents of b all in the main body of the
 * returned block.  Replace old references to b with the returned value (which
 * may still be 'b', if no change was needed. */
struct block *linearizeblock(struct block *b)
{
	struct block *newb;
	size_t len;
	struct extra_bdata *ebd;

	if (!b->extra_len)
		return b;

	newb = block_alloc(BLEN(b), MEM_WAIT);
	len = BHLEN(b);
	memcpy(newb->wp, b->rp, len);
	newb->wp += len;
	len = b->extra_len;
	for (int i = 0; (i < b->nr_extra_bufs) && len; i++) {
		ebd = &b->extra_data[i];
		if (!ebd->base || !ebd->len)
			continue;
		memcpy(newb->wp, (void*)(ebd->base + ebd->off), ebd->len);
		newb->wp += ebd->len;
		len -= ebd->len;
	}
	/* TODO: any other flags that need copied over? */
	if (b->flag & BCKSUM_FLAGS) {
		newb->flag |= (b->flag & BCKSUM_FLAGS);
		newb->checksum_start = b->checksum_start;
		newb->checksum_offset = b->checksum_offset;
		newb->mss = b->mss;
	}
	freeb(b);
	return newb;
}
Example #16
0
/*
 *  N_EXDATA_IND
 *  -------------------------------------------------------------------------
 *  This is translated into SUA messages and fed to the state machines.
 */
static int
n_exdata_ind(queue_t *q, mblk_t *pdu)
{
	int err;
	mblk_t *mp;
	N_exdata_ind_t *p;

	p = (N_exdata_ind_t *) pdu->b_rptr;
	if (p->DATA_xfer_flags & N_MORE_DATA_FLAG) {
		int err;

		if ((err = lm_event_ind(q, pdu)))
			return (err);
		if ((err = m3ua_sp_down(q)))
			return (err);
		qdisable(q);
		return (0);
	}
	mp = pdu->b_cont;
	mp->b_band = 1;
	freeb(pdu);
	if ((err = m3ua_recv_msg(q, mp)))
		return (err);
	return (0);
}
Example #17
0
static void
discover(int major, int minor)
{
	Aoehdr *h;
	Block *b;
	Netlink *nl, *e;

	nl = netlinks.nl;
	e = nl + nelem(netlinks.nl);
	for(; nl < e; nl++){
		if(nl->cc == nil)
			continue;
		b = allocb(ETHERMINTU);
		if(waserror()){
			freeb(b);
			nexterror();
		}
		b->wp = b->rp + ETHERMINTU;
		memset(b->rp, 0, ETHERMINTU);
		h = (Aoehdr*)b->rp;
		memset(h->dst, 0xff, sizeof h->dst);
		memmove(h->src, nl->ea, sizeof h->src);
		hnputs(h->type, Aoetype);
		h->verflag = Aoever << 4;
		hnputs(h->major, major);
		h->minor = minor;
		h->cmd = ACconfig;
		poperror();
		/* send b down the queue */
		devtab[nl->dc->type]->bwrite(nl->dc, b, 0);
	}
}
Example #18
0
/*
 *  N_DATA_IND
 *  -------------------------------------------------------------------------
 *  This is translated into SUA messages and fed to the state machines.
 */
static int
n_data_ind(queue_t *q, mblk_t *pdu)
{
	int err;
	mblk_t *mp;
	N_data_ind_t *p;

	p = (N_data_ind_t *) pdu->b_rptr;
	if (p->DATA_xfer_flags & N_MORE_DATA_FLAG) {
		/* aaargh! */
		/* give it to management */
		if ((err = lm_event_ind(q, pdu)))
			return (err);
		if ((err = m3ua_sp_down(q)))
			return (err);
		qdisable(q);
		return (0);
	}
	if (p->DATA_xfer_flags & N_RC_FLAG) {
		/* need to send receipt confirmation */
		if (!(mp = n_datack_ind()))
			return (-ENOBUFS);
		qreply(q, mp);
	}
	/* only need the M_DATA block */
	mp = pdu->b_cont;
	mp->b_band = 0;
	freeb(pdu);
	if ((err = m3ua_recv_msg(q, mp)))
		return (err);
	return (0);
}
Example #19
0
File: rudp.c Project: Shamar/harvey
/*
 *  called with ucb locked (and c locked if user initiated close)
 */
void
relhangup(Conv *c, Reliable *r)
{
	int n;
	Block *bp;
	char hup[ERRMAX];

	n = snprint(hup, sizeof(hup), "hangup %I!%d", r->addr, r->port);
	qproduce(c->eq, hup, n);

	/*
	 *  dump any unacked outgoing messages
	 */
	for(bp = r->unacked; bp != nil; bp = r->unacked){
		r->unacked = bp->list;
		bp->list = nil;
		freeb(bp);
	}

	r->rcvgen = 0;
	r->rcvseq = 0;
	r->acksent = 0;
	if(generation == Hangupgen)
		generation++;
	r->sndgen = generation++;
	r->sndseq = 0;
	r->ackrcvd = 0;
	r->xmits = 0;
	r->timeout = 0;
	wakeup(&r->vous);
}
Example #20
0
static long
loopoput(Loop *lb, Link *link, Block *volatile bp)
{
	long n;

	n = BLEN(bp);

	/* make it a single block with space for the loopback timing header */
	if(waserror()){
		freeb(bp);
		nexterror();
	}
	bp = padblock(bp, Tmsize);
	if(bp->next)
		bp = concatblock(bp);
	if(BLEN(bp) < lb->minmtu)
		bp = adjustblock(bp, lb->minmtu);
	poperror();
	ptime(bp->rp, todget(nil));

	link->packets++;
	link->bytes += n;

	qbwrite(link->oq, bp);

	looper(lb);
	return n;
}
Example #21
0
File: qio.c Project: mtaufen/akaros
/*
 *  throw away up to count bytes from a
 *  list of blocks.  Return count of bytes
 *  thrown away.
 */
static int _pullblock(struct block **bph, int count, int free)
{
	struct block *bp;
	int n, bytes;

	bytes = 0;
	if (bph == NULL)
		return 0;

	while (*bph != NULL && count != 0) {
		bp = *bph;

		n = MIN(BHLEN(bp), count);
		bytes += n;
		count -= n;
		bp->rp += n;
		n = pullext(bp, count);
		bytes += n;
		count -= n;
		QDEBUG checkb(bp, "pullblock ");
		if (BLEN(bp) == 0 && (free || count)) {
			*bph = bp->next;
			bp->next = NULL;
			freeb(bp);
		}
	}
	return bytes;
}
Example #22
0
/*
 *  write to a queue.  only Maxatomic bytes at a time is atomic.
 */
int
qwrite(Queue *q, void *vp, int len)
{
	int n, sofar;
	Block *b;
	uchar *p = vp;

	QDEBUG if(!islo())
		print("qwrite hi %#p\n", getcallerpc(&q));

	sofar = 0;
	do {
		n = len-sofar;
		if(n > Maxatomic)
			n = Maxatomic;

		b = allocb(n);
		setmalloctag(b, (up->text[0]<<24)|(up->text[1]<<16)|(up->text[2]<<8)|up->text[3]);
		if(waserror()){
			freeb(b);
			nexterror();
		}
		memmove(b->wp, p+sofar, n);
		poperror();
		b->wp += n;

		qbwrite(q, b);

		sofar += n;
	} while(sofar < len && (q->state & Qmsg) == 0);

	return len;
}
Example #23
0
File: qio.c Project: 8l/inferno
/*
 *  write to a queue.  only Maxatomic bytes at a time is atomic.
 */
int
qwrite(Queue *q, void *vp, int len)
{
	int n, sofar;
	Block *b;
	uchar *p = vp;

	sofar = 0;
	do {
		n = len-sofar;
		if(n > Maxatomic)
			n = Maxatomic;

		b = allocb(n);
		setmalloctag(b, getcallerpc(&q));
		if(waserror()){
			freeb(b);
			nexterror();
		}
		memmove(b->wp, p+sofar, n);
		poperror();
		b->wp += n;

		qbwrite(q, b);

		sofar += n;
	} while(sofar < len && (q->state & Qmsg) == 0);

	return len;
}
Example #24
0
File: ether.c Project: 8l/inferno
int
etherrxpkt(int ctlrno, Etherpkt *pkt, int timo)
{
	int n;
	Ctlr *ctlr;
	Block *b;
	ulong start;

	if((ctlr = attach(ctlrno)) == 0)
		return 0;

	start = m->ticks;
	while((b = qget(ctlr->iq)) == 0){
		if(TK2MS(m->ticks - start) >= timo){
			/*
			print("ether%d: rx timeout\n", ctlrno);
			 */
			return 0;
		}
		//delay(1);
	}

	n = BLEN(b);
	memmove(pkt, b->rp, n);
	freeb(b);

	return n;
}
Example #25
0
File: qio.c Project: mtaufen/akaros
/* Helper and front-end for __try_qbread: extracts and returns a list of blocks
 * containing up to len bytes.  It may contain less than len even if q has more
 * data.
 *
 * Returns 0 if the q is closed or would require blocking and !CAN_BLOCK.
 *
 * Technically, there's a weird corner case with !Qcoalesce and Qmsg where you
 * could get a zero length block back. */
static struct block *__qbread(struct queue *q, size_t len, int qio_flags,
                              int mem_flags)
{
	struct block *ret = 0;
	struct block *spare = 0;

	while (1) {
		switch (__try_qbread(q, len, qio_flags, &ret, spare)) {
		case QBR_OK:
		case QBR_FAIL:
			if (spare && (ret != spare))
				freeb(spare);
			return ret;
		case QBR_SPARE:
			assert(!spare);
			/* Due to some nastiness, we need a fresh block so we can read out
			 * anything from the queue.  'len' seems like a reasonable amount.
			 * Maybe we can get away with less. */
			spare = block_alloc(len, mem_flags);
			if (!spare)
				return 0;
			break;
		case QBR_AGAIN:
			/* if the first block is 0 and we are Qcoalesce, then we'll need to
			 * try again.  We bounce out of __try so we can perform the "is
			 * there a block" logic again from the top. */
			break;
		}
	}
}
Example #26
0
Block*
adjustblock(Block* bp, int len)
{
	int n;
	Block *nbp;

	if(len < 0){
		freeb(bp);
		return nil;
	}

	if(bp->rp+len > bp->lim){
		nbp = copyblock(bp, len);
		freeblist(bp);
		QDEBUG checkb(nbp, "adjustblock 1");

		return nbp;
	}

	n = BLEN(bp);
	if(len > n)
		memset(bp->wp, 0, len-n);
	bp->wp = bp->rp+len;
	QDEBUG checkb(bp, "adjustblock 2");

	return bp;
}
Example #27
0
/*
 *  throw away up to count bytes from a
 *  list of blocks.  Return count of bytes
 *  thrown away.
 */
int
pullblock(Block **bph, int count)
{
	Block *bp;
	int n, bytes;

	bytes = 0;
	if(bph == nil)
		return 0;

	while(*bph != nil && count != 0) {
		bp = *bph;
		n = BLEN(bp);
		if(count < n)
			n = count;
		bytes += n;
		count -= n;
		bp->rp += n;
		QDEBUG checkb(bp, "pullblock ");
		if(BLEN(bp) == 0) {
			*bph = bp->next;
			bp->next = nil;
			freeb(bp);
		}
	}
	return bytes;
}
/*ARGSUSED*/
void
sctp_asconf_free_cxmit(sctp_t *sctp, sctp_chunk_hdr_t *ch)
{
	mblk_t		*mp;
	mblk_t		*mp1;
	sctp_cl_ainfo_t	*ainfo;

	if (sctp->sctp_cxmit_list == NULL) {
		/* Nothing pending */
		return;
	}

	mp = sctp->sctp_cxmit_list;
	while (mp != NULL) {
		mp1 = mp->b_cont;
		mp->b_cont = NULL;
		if (mp->b_prev != NULL) {
			ainfo = (sctp_cl_ainfo_t *)mp->b_prev;
			mp->b_prev = NULL;
			kmem_free(ainfo->sctp_cl_alist, ainfo->sctp_cl_asize);
			kmem_free(ainfo->sctp_cl_dlist, ainfo->sctp_cl_dsize);
			kmem_free(ainfo, sizeof (*ainfo));
		}
		freeb(mp);
		mp = mp1;
	}
	sctp->sctp_cxmit_list = NULL;
}
Example #29
0
	~AndroidReaderContext(){
		if (frame != 0) {
			freeb(frame);
		}
		ms_yuv_buf_allocator_free(allocator);
		ms_mutex_destroy(&mutex);
	};
Example #30
0
static long
ctltrans(Ep *ep, uchar *req, long n)
{
	Hostchan *hc;
	Epio *epio;
	Block *b;
	uchar *data;
	int datalen;

	epio = ep->aux;
	if(epio->cb != nil){
		freeb(epio->cb);
		epio->cb = nil;
	}
	if(n < Rsetuplen)
		error(Ebadlen);
	if(req[Rtype] & Rd2h){
		datalen = GET2(req+Rcount);
		if(datalen <= 0 || datalen > Maxctllen)
			error(Ebadlen);
		/* XXX cache madness */
               	epio->cb = b = allocb(ROUND(datalen, ep->maxpkt) + CACHELINESZ);
               	b->wp = (uchar*)ROUND((uintptr)b->wp, CACHELINESZ);
		//epio->cb = b = allocb(ROUND(datalen, ep->maxpkt));
		//assert(((uintptr)b->wp & (BLOCKALIGN-1)) == 0);
		memset(b->wp, 0x55, b->lim - b->wp);
		cachedwbinvse(b->wp, b->lim - b->wp);
		data = b->wp;
	}else{
		b = nil;
		datalen = n - Rsetuplen;
		data = req + Rsetuplen;
	}
	hc = chanalloc(ep);
	if(waserror()){
		chanrelease(ep, hc);
		if(strcmp(up->env->errstr, Estalled) == 0)
			return 0;
		nexterror();
	}
	chansetup(hc, ep);
	chanio(ep, hc, Epout, SETUP, req, Rsetuplen);
	if(req[Rtype] & Rd2h){
		if(ep->dev->hub <= 1){
			ep->toggle[Read] = DATA1;
			b->wp += multitrans(ep, hc, Read, data, datalen);
		}else
			b->wp += chanio(ep, hc, Epin, DATA1, data, datalen);
		chanio(ep, hc, Epout, DATA1, nil, 0);
		n = Rsetuplen;
	}else{
		if(datalen > 0)
			chanio(ep, hc, Epout, DATA1, data, datalen);
		chanio(ep, hc, Epin, DATA1, nil, 0);
		n = Rsetuplen + datalen;
	}
	chanrelease(ep, hc);
	poperror();
	return n;
}