Ejemplo n.º 1
0
vsf_err_t vsfmal_write(struct vsfsm_pt_t *pt, vsfsm_evt_t evt, uint64_t addr,
					uint8_t *buff, uint32_t size)
{
	struct vsfmal_t *mal = (struct vsfmal_t *)pt->user_data;
	uint32_t offset;
	vsf_err_t err;

	vsfsm_pt_begin(pt);
	mal->op_block_size = mal->drv->block_size(mal, addr, size, VSFMAL_OP_WRITE);
	mal->offset = 0;

	while (mal->offset < size)
	{
		mal->pt.user_data = mal;
		mal->pt.state = 0;
		vsfsm_pt_entry(pt);
		offset = mal->offset;
		err = mal->drv->write(&mal->pt, evt, addr + offset, buff + offset,
								mal->op_block_size);
		if (err != 0) return err;

		mal->offset += mal->op_block_size;
	}
	vsfsm_pt_end(pt);
	return VSFERR_NONE;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
static vsf_err_t
vsfip_telnetd_session_rx_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt)
{
	struct vsfip_telnetd_session_t *session =
								(struct vsfip_telnetd_session_t *)pt->user_data;
	uint32_t len;
	vsf_err_t err;

	vsfsm_pt_begin(pt);

	session->caller_rxpt.sm = pt->sm;
	while (!session->disconnect)
	{
		session->caller_rxpt.state = 0;
		vsfsm_pt_entry(pt);
		err = vsfip_tcp_recv(&session->caller_rxpt, evt, session->so,
								&session->so->remote_sockaddr, &session->inbuf);
		if (err > 0) return err; else if (err < 0)
		{
			session->disconnect = true;
			// fake on_in event, just to wakeup tx_thread to exit
			vsfip_telnetd_session_stream_on_in(session);
			break;
		}

		while (session->inbuf->app.size > 0)
		{
			len = stream_write(session->stream_rx, &session->inbuf->app);
			if (!len && vsfsm_sem_pend(&session->stream_rx_sem, pt->sm))
			{
				vsfsm_pt_wfe(pt, VSFIP_TELNETD_EVT_STREAM_OUT);
				continue;
			}
			session->inbuf->app.buffer += len;
			session->inbuf->app.size -= len;
		}
		vsfip_buffer_release(session->inbuf);
	}

	vsfsm_pt_end(pt);
	return VSFERR_NONE;
}
Ejemplo n.º 4
0
static vsf_err_t
vsfip_telnetd_session_tx_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt)
{
	struct vsfip_telnetd_session_t *session =
								(struct vsfip_telnetd_session_t *)pt->user_data;
	uint32_t len;
	vsf_err_t err;

	vsfsm_pt_begin(pt);

	session->caller_txpt.sm = pt->sm;
	while (!session->disconnect)
	{
		len = stream_get_data_size(session->stream_tx);
		if (!len && vsfsm_sem_pend(&session->stream_tx_sem, pt->sm))
		{
			vsfsm_pt_wfe(pt, VSFIP_TELNETD_EVT_STREAM_IN);
			if (session->disconnect)
				break;
			continue;
		}

	retry_alloc_buf:
		session->outbuf = VSFIP_TCPBUF_GET(len);
		if (NULL == session->outbuf)
		{
			vsfsm_pt_delay(pt, 5);
			if (session->disconnect)
				break;
			goto retry_alloc_buf;
		}

		session->outbuf->app.size =
					stream_read(session->stream_tx, &session->outbuf->app);
		if (!session->outbuf->app.size)
		{
			vsfip_buffer_release(session->outbuf);
			continue;
		}

		session->caller_txpt.state = 0;
		vsfsm_pt_entry(pt);
		err = vsfip_tcp_send(&session->caller_txpt, evt, session->so,
						&session->so->remote_sockaddr, session->outbuf, false);
		if (err > 0) return err; else if (err < 0)
		{
			session->disconnect = true;
		}
	}

	// close tcp socket
	session->caller_txpt.state = 0;
	vsfsm_pt_entry(pt);
	err = vsfip_tcp_close(&session->caller_txpt, evt, session->so);
	if (err > 0) return err;

	// close socket no matter if tcp closed OK or not
	vsfip_close(session->so);
	session->connected = false;

	vsfsm_pt_end(pt);
	return VSFERR_NONE;
}
Ejemplo n.º 5
0
static vsf_err_t vsfip_telnetd_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt)
{
	struct vsfip_telnetd_t *telnetd = (struct vsfip_telnetd_t *)pt->user_data;
	vsf_err_t err = VSFERR_NONE;
	int i;

	vsfsm_pt_begin(pt);

	telnetd->caller_pt.sm = pt->sm;
	telnetd->so = vsfip_socket(AF_INET, IPPROTO_TCP);
	if (NULL == telnetd->so)
	{
		return VSFERR_FAIL;
	}

	if ((vsfip_bind(telnetd->so, telnetd->port) != 0) ||
		(vsfip_listen(telnetd->so, telnetd->session_num) != 0))
	{
		err = VSFERR_FAIL;
		goto fail_socket_connect;
	}

	while (1)
	{
		telnetd->caller_pt.state = 0;
		vsfsm_pt_entry(pt);
		err = vsfip_tcp_accept(&telnetd->caller_pt, evt, telnetd->so,
								&telnetd->cur_session);
		if (err > 0) return err; else if (err < 0)
		{
			continue;
		}

		// get session
		for (i = 0; i < telnetd->session_num; i++)
		{
			if (!telnetd->sessions[i].connected)
			{
				struct vsfip_telnetd_session_t *session = &telnetd->sessions[i];

				session->connected = true;
				session->disconnect = false;
				session->so = telnetd->cur_session;

				session->stream_rx->callback_tx.param = session;
				session->stream_rx->callback_tx.on_inout =
											vsfip_telnetd_session_stream_on_out;
				session->stream_tx->callback_rx.param = session;
				session->stream_tx->callback_rx.on_inout =
											vsfip_telnetd_session_stream_on_in;
				stream_connect_tx(session->stream_rx);
				stream_connect_rx(session->stream_tx);

				vsfsm_sem_init(&session->stream_tx_sem, 0,
											VSFIP_TELNETD_EVT_STREAM_IN);
				vsfsm_sem_init(&session->stream_rx_sem, 0,
												VSFIP_TELNETD_EVT_STREAM_OUT);

				session->txpt.thread = vsfip_telnetd_session_tx_thread;
				session->txpt.user_data = session;
				session->rxpt.thread = vsfip_telnetd_session_rx_thread;
				session->rxpt.user_data = session;
				vsfsm_pt_init(&session->txsm, &session->txpt);
				vsfsm_pt_init(&session->rxsm, &session->rxpt);
				break;
			}
		}
		if (i == telnetd->session_num)
		{
			telnetd->caller_pt.state = 0;
			vsfsm_pt_entry(pt);
			err = vsfip_tcp_close(&telnetd->caller_pt, evt,
										telnetd->cur_session);
			if (err > 0) return err;
			vsfip_close(telnetd->cur_session);
		}
	}

fail_socket_connect:
	vsfip_close(telnetd->so);
	telnetd->so = NULL;

	vsfsm_pt_end(pt);
	return VSFERR_NONE;
}
Ejemplo n.º 6
0
Archivo: vsfos.c Proyecto: hank-fan/vsf
// vsfos
static vsf_err_t vsfos_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt)
{
	struct vsfos_modifs_t *ifs = (struct vsfos_modifs_t *)pt->user_data;
	vsf_err_t err;

	vsfsm_pt_begin(pt);

	vsfhal_core_init(NULL);
	vsfhal_tickclk_init();
	vsfhal_tickclk_start();

	// timer
	VSFPOOL_INIT(&ifs->vsftimer_pool, struct vsftimer_t, VSFOSCFG_VSFSM_PENDSVQ_LEN);
	vsftimer_init(&ifs->vsftimer_memop);
	vsfhal_tickclk_config_cb(vsfos_tickclk_callback_int, NULL);

	// file
	VSFPOOL_INIT(&ifs->vfsfile_pool, struct vsfile_vfsfile_t, VSFOSCFG_VFS_NO);
	vsfile_init(&ifs->fs.memop);

	ifs->caller_pt.state = 0;
	vsfsm_pt_entry(pt);
	err = vsfile_addfile(&ifs->caller_pt, evt, NULL, "msc_root", VSFILE_ATTR_DIRECTORY);
	if (err != 0) return err;

	ifs->caller_pt.state = 0;
	vsfsm_pt_entry(pt);
	err = vsfile_getfile(&ifs->caller_pt, evt, NULL, "/msc_root", &ifs->file);
	if (err != 0) return err;

	ifs->caller_pt.state = 0;
	ifs->caller_pt.user_data = &ifs->mal.fakefat32;
	err = vsfile_mount(&ifs->caller_pt, evt, (struct vsfile_fsop_t *)&fakefat32_fs_op, ifs->file);
	if (err != 0) return err;

	// vsfip
	{
		struct vsfip_buffer_t *buffer;
		int i;

		buffer = &ifs->tcpip.buffer_pool.buffer[0];
		for (i = 0; i < VSFOSCFG_VSFIP_BUFFER_NUM; i++)
		{
			buffer->buffer = ifs->tcpip.buffer_mem[i];
			buffer++;
		}
	}
	VSFPOOL_INIT(&ifs->tcpip.buffer_pool, struct vsfip_buffer_t, VSFOSCFG_VSFIP_BUFFER_NUM);
	VSFPOOL_INIT(&ifs->tcpip.socket_pool, struct vsfip_socket_t, VSFOSCFG_VSFIP_SOCKET_NUM);
	VSFPOOL_INIT(&ifs->tcpip.tcppcb_pool, struct vsfip_tcppcb_t, VSFOSCFG_VSFIP_TCPPCB_NUM);
	vsfip_init((struct vsfip_mem_op_t *)&ifs->tcpip.mem_op);

	STREAM_INIT(&ifs->usbd.cdc.stream_rx);
	STREAM_INIT(&ifs->usbd.cdc.stream_tx);

	vsfscsi_init(&ifs->mal.scsi_dev);
	vsfusbd_device_init(&ifs->usbd.device);
	vsfshell_init(&ifs->shell);
	vsfos_busybox_init(&ifs->shell);

	if ((ifs->hwcfg->usbd.pullup.port != IFS_DUMMY_PORT) && (vsfhal_gpio_if != NULL))
	{
		uint8_t port = ifs->hwcfg->usbd.pullup.port;
		uint8_t pin = ifs->hwcfg->usbd.pullup.pin;
		vsfhal_gpio_init(port);
		vsfhal_gpio_clear(port, 1 << pin);
		vsfhal_gpio_config_pin(port, pin, GPIO_OUTPP);
	}
	ifs->usbd.device.drv->disconnect();

	vsfsm_pt_delay(pt, 200);

	if ((ifs->hwcfg->usbd.pullup.port != IFS_DUMMY_PORT) && (vsfhal_gpio_if != NULL))
	{
		uint8_t port = ifs->hwcfg->usbd.pullup.port;
		uint8_t pin = ifs->hwcfg->usbd.pullup.pin;
		vsfhal_gpio_set(port, 1 << pin);
	}
	ifs->usbd.device.drv->connect();

	while (1)
	{
		vsfsm_pt_delay(pt, 1000);
		asm("nop");
		vsfsm_pt_delay(pt, 1000);
		asm("nop");
		vsfsm_pt_delay(pt, 1000);
		asm("nop");
		vsfsm_pt_delay(pt, 1000);
		asm("nop");
		vsfsm_pt_delay(pt, 1000);
		asm("nop");
		vsfsm_pt_delay(pt, 1000);
		asm("nop");
	}

	vsfsm_pt_end(pt);
	return VSFERR_NONE;
}