void rbuf_abort_new(struct ring_buf *r) { struct rbuf_buf *cur; if( inc_index(r->tail) != r->head ){ cur = &(r->rb[r->tail]); rbuf_free_buf(&r->rb[r->head]); } }
int rbuf_append(struct ring_buf *r,char *in_buf,int size,int end_flag) { struct rbuf_buf *cur; if( inc_index(r->tail) != r->head ){ cur = &(r->rb[r->tail]); if( cur->used == MAX_SBUFS ){ rbuf_free_buf(cur); return -ENOMEM; } if( !(cur->ptr[cur->used] = malloc(size)) ) return -ENOMEM; memcpy(cur->ptr[cur->used],in_buf,size); cur->size[cur->used] = size; cur->used++; if( end_flag ) r->tail = inc_index(r->tail); return 0; } return -1; }
void rbuf_free(struct ring_buf *r) { int i = 0; struct rbuf_buf *cur; while( r->head != r->tail ){ cur = &(r->rb[r->head]); rbuf_free_buf(cur); r->head = inc_index(r->head); i++; } free(r); }
static void mxc_udc_queue_update(u8 epnum, u8 *data, u32 len, u32 tx) { mxc_ep_t *ep; struct ep_queue_item *tqi, *head, *last; int send = 0; int in; head = last = NULL; in = ep_is_in(epnum, tx); ep = mxc_udc.mxc_ep + (epnum * 2 + in); DBG("epnum = %d, in = %d\n", epnum, in); do { tqi = ep->ep_dtd[ep->index]; DBG("%s, index = %d, tqi = %p\n", __func__, ep->index, tqi); while (mxc_tqi_is_busy(tqi)) ; mxc_tqi_init_page(tqi); DBG("%s, line = %d, len = %d\n", __func__, __LINE__, len); inc_index(ep->index); send = MIN(len, 0x1000); if (data) { memcpy((void *)tqi->page_vir, (void *)data, send); _dump_buf(tqi->page_vir, send); } if (!head) last = head = tqi; else { last->next_item_ptr = tqi->item_dma; last->next_item_vir = tqi; last = tqi; } if (!tx) tqi->reserved[0] = send; /* we set IOS for every dtd */ tqi->info = ((send << 16) | (1 << 15) | (1 << 7)); data += send; len -= send; } while (len); last->next_item_ptr = 0x1; /* end */ if (ep->tail) { ep->tail->next_item_ptr = head->item_dma; ep->tail->next_item_vir = head; if (mxc_ep_xfer_is_working(ep, in)) { DBG("ep is working\n"); goto out; } } mxc_update_qh(ep, head, in); out: ep->tail = last; }
static void mxc_udc_ep_recv(u8 epnum) { mxc_ep_t *ep = mxc_udc.mxc_ep + (epnum * 2 + USB_RECV); struct ep_queue_item *tqi; while (1) { u32 nbytes; tqi = ep->ep_dtd[ep->done]; if (mxc_udc_tqi_empty(tqi)) break; nbytes = _mxc_ep_recv_data(epnum, tqi); usbd_rcv_complete(ep->epi, nbytes, 0); inc_index(ep->done); if (ep->done == ep->index) break; } }
void write_load(item_t *item) { if (!item) return; if (item->addressing == addressing_immediate) write_line("LOAD R%d, %d", register_index, item->value); else if (item->addressing == addressing_direct) write_line("LOAD R%d, [%.4X]", register_index, item->address); else if (item->addressing == addressing_indirect) { write_line("LOAD R%d, [R%d]", item->index, item->index); item->addressing = addressing_register; return; } else return; // TODO: Devo verificar e apontar erro ou deixar como está? item->addressing = addressing_register; item->index = register_index; inc_index(1); }
int rbuf_get_cur(struct ring_buf *r,char **out_buf) { struct rbuf_buf *cur; int size,offset = 0; int i; if( r->head != r->tail ){ cur = &(r->rb[r->head]); size = rbuf_count_size(cur); if( !(*out_buf = malloc(size)) ){ return -1; } offset = 0; for(i=0;i<cur->used;i++){ memcpy(*out_buf+offset,cur->ptr[i],cur->size[i]); offset += cur->size[i]; } rbuf_free_buf(&r->rb[r->head]); r->head = inc_index(r->head); return size; } return -1; }
static void mxc_udc_queue_update(u8 epnum, u8 *data, u32 len, u32 tx) { struct mxc_ep_t *ep; struct ep_queue_item *tqi, *head, *last; int send = 0; int in; head = last = NULL; in = ep_is_in(epnum, tx); ep = mxc_udc.mxc_ep + (epnum * 2 + in); DBG("epnum = %d, in = %d\n", epnum, in); do { tqi = ep->ep_dtd[ep->index]; DBG("%s, index = %d, tqi = %p\n", __func__, ep->index, tqi); while (mxc_tqi_is_busy(tqi)) ; mxc_tqi_init_page(tqi); DBG("%s, line = %d, len = %d\n", __func__, __LINE__, len); inc_index(ep->index); send = MIN(len, ep->max_pkt_size); if (data) { memcpy((void *)tqi->page_vir, (void *)data, send); _dump_buf((u8 *)(tqi->page_vir), send); flush_dcache_range((unsigned long)(tqi->page_vir), CACHE_ALIGNED_END(tqi->page_vir, send)); } if (!head) last = head = tqi; else { last->next_item_ptr = virt_to_phys(tqi); last->next_item_vir = tqi; last = tqi; } if (!tx) tqi->reserved[0] = send; /* we set IOC for every dtd */ tqi->info = ((send << 16) | (1 << 15) | (1 << 7)); data += send; len -= send; flush_dcache_range((unsigned long)tqi, CACHE_ALIGNED_END(tqi, sizeof(struct ep_queue_item))); } while (len); last->next_item_ptr = 0x1; /* end */ flush_dcache_range((unsigned long)last, CACHE_ALIGNED_END(last, sizeof(struct ep_queue_item))); if (ep->tail) { ep->tail->next_item_ptr = virt_to_phys(head); ep->tail->next_item_vir = head; flush_dcache_range((unsigned long)(ep->tail), CACHE_ALIGNED_END(ep->tail, sizeof(struct ep_queue_item))); if (mxc_ep_xfer_is_working(ep, in)) { DBG("ep is working\n"); goto out; } } mxc_update_qh(ep, head, in); out: ep->tail = last; }