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(); } }
/* * 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(); }
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; }
/* * 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(); }
/* * 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; }
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); } }
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); }
/* * 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; }
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; }
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); }
/** * 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); }
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; }
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; }
/* 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; }
/* * 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); }
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); } }
/* * 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); }
/* * 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); }
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; }
/* * 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; }
/* * 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; }
/* * 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; }
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; }
/* 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; } } }
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; }
/* * 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; }
~AndroidReaderContext(){ if (frame != 0) { freeb(frame); } ms_yuv_buf_allocator_free(allocator); ms_mutex_destroy(&mutex); };
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; }