static uint32_t multibuf_stream_read(struct vsf_stream_t *stream, struct vsf_buffer_t *buffer) { struct vsf_mbufstream_t *mbufstream = (struct vsf_mbufstream_t *)stream; uint8_t *buf = vsf_multibuf_get_payload(&mbufstream->mem.multibuf); uint32_t rsize = 0, cur_size, remain_size = buffer->size; while ((buf != NULL) && (remain_size > 0)) { cur_size = mbufstream->mem.multibuf.size - mbufstream->mem.rpos; cur_size = min(cur_size, remain_size); memcpy(&buffer->buffer[rsize], &buf[mbufstream->mem.rpos], cur_size); rsize += cur_size; remain_size -= cur_size; mbufstream->mem.rpos += cur_size; if (mbufstream->mem.rpos >= mbufstream->mem.multibuf.size) { vsf_multibuf_pop(&mbufstream->mem.multibuf); buf = vsf_multibuf_get_payload(&mbufstream->mem.multibuf); mbufstream->mem.rpos = 0; } } return rsize; }
static vsf_err_t vsf_malstream_write_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt) { struct vsf_malstream_t *malstream = (struct vsf_malstream_t *)pt->user_data; struct vsfmal_t *mal = malstream->mal; struct vsf_stream_t *stream = (struct vsf_stream_t *)malstream->mbufstream; uint64_t cur_addr; vsf_err_t err; vsfsm_pt_begin(pt); mal->op_block_size = mal->drv->block_size(mal, malstream->addr, 0, VSFMAL_OP_WRITE); if (mal->op_block_size != malstream->mbufstream->mem.multibuf.size) { return VSFERR_BUG; } mal->pt.user_data = mal; malstream->offset = 0; while (malstream->offset < malstream->size) { while (stream_get_data_size(stream) < mal->op_block_size) { vsfsm_pt_wfe(pt, VSF_MALSTREAM_ON_INOUT); } mal->pt.state = 0; vsfsm_pt_entry(pt); cur_addr = malstream->addr + malstream->offset; err = mal->drv->write(&mal->pt, evt, cur_addr, vsf_multibuf_get_payload(&malstream->mbufstream->mem.multibuf), mal->op_block_size); if (err > 0) return err; else if (err < 0) goto end; vsf_multibuf_pop(&malstream->mbufstream->mem.multibuf); malstream->offset += mal->op_block_size; if (malstream->offset >= malstream->size) { // fix before callback stream->callback_tx.on_inout = NULL; } if (stream->tx_ready && (stream->callback_tx.on_inout != NULL)) { stream->callback_tx.on_inout(stream->callback_tx.param); } } end: if (malstream->cb.on_finish != NULL) { malstream->cb.on_finish(malstream->cb.param); } vsfsm_pt_end(pt); return VSFERR_NONE; }