Ejemplo n.º 1
0
int udp_port_unreach(in_addr_t __faddr, uint16_t __fport, 
					 in_addr_t __laddr, uint16_t __lport)
{
	struct udp_pcb * up;

	up = (struct udp_pcb *)pcb_wildlookup(__faddr, __fport, 
										  __laddr, __lport, &__udp__.active);
	if (up == NULL) {
		DCC_LOG4(LOG_TRACE, "not found: %I:%d > %I:%d", 
				 __laddr, ntohs(__lport), __faddr, ntohs(__lport));
		return -1;
	}

	/* set the error flag */
	up->u_icmp_err = 1;

	/* unconnect the PCB */
	up->u_faddr = INADDR_ANY;
	up->u_fport = 0;

	/* notify the application */
	__os_cond_signal(up->u_rcv_cond);

	return 0;
}
Ejemplo n.º 2
0
int mbuf_alloc_check(void)
{
	struct mbuf * m;
	int ret = 0;
	int n;

	__os_mutex_lock(__mbufs__.mutex);

	n = 0;
	m = __mbufs__.free.first;

	/* count the free blocks */
	while (m != NULL) {
		n++;
		m = m->next;
	}

	if ((n + __mbufs__.used) != __mbufs__.max) {
		DCC_LOG4(LOG_ERROR, "used=%d max=%d free=%d avail=%d",
			   __mbufs__.used, __mbufs__.max, 
			   __mbufs__.max - __mbufs__.used, n);
		ret = -1;
	}

	__os_mutex_unlock(__mbufs__.mutex);

	return ret;
}
Ejemplo n.º 3
0
void __attribute__((noreturn)) serial_recv_task(struct vcom * vcom)
{
	struct serial_dev * serial = vcom->serial;
	struct usb_cdc_class * cdc = vcom->cdc;
	uint8_t buf[VCOM_BUF_SIZE];
	int len;

	DCC_LOG1(LOG_TRACE, "[%d] started.", thinkos_thread_self());

	/* wait for line configuration */
	usb_cdc_acm_lc_wait(cdc);

	/* enable serial */
	serial_enable(serial);

	for (;;) {
		len = serial_read(serial, buf, VCOM_BUF_SIZE, 1000);
		if (len > 0) {
//			dbg_write(buf, len);
			if (vcom->mode == VCOM_MODE_CONVERTER) {
				led_flash(LED_AMBER, 50);
				usb_cdc_write(cdc, buf, len);
			}
			if (vcom->mode == VCOM_MODE_SDU_TRACE) {
				led_flash(LED_AMBER, 50);
				sdu_decode(buf, len);
			}
#if RAW_TRACE
			if (len == 1)
				DCC_LOG1(LOG_TRACE, "RX: %02x", buf[0]);
			else if (len == 2)
				DCC_LOG2(LOG_TRACE, "RX: %02x %02x", 
						 buf[0], buf[1]);
			else if (len == 3)
				DCC_LOG3(LOG_TRACE, "RX: %02x %02x %02x", 
						 buf[0], buf[1], buf[2]);
			else if (len == 4)
				DCC_LOG4(LOG_TRACE, "RX: %02x %02x %02x %02x", 
						 buf[0], buf[1], buf[2], buf[3]);
			else if (len == 5)
				DCC_LOG5(LOG_TRACE, "RX: %02x %02x %02x %02x %02x", 
						 buf[0], buf[1], buf[2], buf[3], buf[4]);
			else if (len == 6)
				DCC_LOG6(LOG_TRACE, "RX: %02x %02x %02x %02x %02x %02x", 
						 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
			else if (len == 7)
				DCC_LOG7(LOG_TRACE, "RX: %02x %02x %02x %02x %02x %02x %02x ",
						 buf[0], buf[1], buf[2], buf[3], 
						 buf[4], buf[5], buf[6]);
			else
				DCC_LOG8(LOG_TRACE, "RX: %02x %02x %02x %02x %02x %02x "
						 "%02x %02x ...", buf[0], buf[1], buf[2], buf[3], 
						 buf[4], buf[5], buf[6], buf[7]);
#endif
#if SDU_TRACE
			RX(buf, len);
#endif
		}
	}
}
Ejemplo n.º 4
0
int raw_input(struct ifnet * __if, struct iphdr * __ip, int __len)
{
	struct pcb_link * q;
	struct raw_pcb * raw;
	int n;

	q = (struct pcb_link *)&__raw__.active.first;

	DCC_LOG4(LOG_TRACE, "%I > %I prot=%d (%d) ", 
			 __ip->saddr, __ip->daddr, __ip->proto, __len); 

	while ((q = q->next)) {
		raw = (struct raw_pcb *)&q->pcb;

		if (raw->r_protocol != __ip->proto)
			continue;

		raw->r_faddr = __ip->saddr;
		raw->r_laddr = __ip->daddr;

		n = MIN(NET_RAW_RCV_BUF_LEN, __len);	
		memcpy(raw->r_buf, __ip, n);
		raw->r_len = n;

		DCC_LOG2(LOG_TRACE, "<%0x> signal ---> %d", raw, raw->r_cond); 

		thinkos_cond_signal(raw->r_cond);

		return 0;
	}

	return -1;
} 
Ejemplo n.º 5
0
void __attribute__((noreturn)) usb_recv_task(struct vcom * vcom)
{
	struct serial_dev * serial = vcom->serial;
	usb_cdc_class_t * cdc = vcom->cdc;
	uint8_t buf[VCOM_BUF_SIZE];
	int len;

	DCC_LOG1(LOG_TRACE, "[%d] started.", thinkos_thread_self());
	DCC_LOG2(LOG_TRACE, "vcom->%p, cdc->%p", vcom, cdc);

	for (;;) {
		len = usb_cdc_read(cdc, buf, VCOM_BUF_SIZE, 1000);
		if (vcom->mode == VCOM_MODE_CONVERTER) {
			if (len > 0) {
				led_flash(LED_RED, 50);
				serial_write(serial, buf, len);
#if RAW_TRACE
				if (len == 1)
					DCC_LOG1(LOG_TRACE, "TX: %02x", buf[0]);
				else if (len == 2)
					DCC_LOG2(LOG_TRACE, "TX: %02x %02x", 
							 buf[0], buf[1]);
				else if (len == 3)
					DCC_LOG3(LOG_TRACE, "TX: %02x %02x %02x", 
							 buf[0], buf[1], buf[2]);
				else if (len == 4)
					DCC_LOG4(LOG_TRACE, "TX: %02x %02x %02x %02x", 
							 buf[0], buf[1], buf[2], buf[3]);
				else if (len == 5)
					DCC_LOG5(LOG_TRACE, "TX: %02x %02x %02x %02x %02x", 
							 buf[0], buf[1], buf[2], buf[3], buf[4]);
				else if (len == 6)
					DCC_LOG6(LOG_TRACE, "TX: %02x %02x %02x %02x %02x %02x", 
							 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
				else if (len == 7)
					DCC_LOG7(LOG_TRACE, "TX: %02x %02x %02x %02x %02x %02x %02x ",
							 buf[0], buf[1], buf[2], buf[3], 
							 buf[4], buf[5], buf[6]);
				else
					DCC_LOG8(LOG_TRACE, "TX: %02x %02x %02x %02x %02x %02x "
							 "%02x %02x ...", buf[0], buf[1], buf[2], buf[3], 
							 buf[4], buf[5], buf[6], buf[7]);
#endif
#if SDU_TRACE
				TX(buf, len);
#endif
				//			dbg_write(buf, len);
			}
		} else {
			// forward to service input
			vcom_service_input(vcom, buf, len);
		}
	}
}
Ejemplo n.º 6
0
void __thinkos_thread_init(unsigned int thread_id, uint32_t sp, 
						   void * task, void * arg)
{
	struct thinkos_context * ctx;
	uint32_t pc;

	pc = (uint32_t)task;
	sp &= 0xfffffff8; /* 64bits alignemnt */


	sp -= sizeof(struct thinkos_context);
	ctx = (struct thinkos_context *)sp;

	__thinkos_memset32(ctx, 0, sizeof(struct thinkos_context));

	ctx->r0 = (uint32_t)arg;
#if THINKOS_ENABLE_EXIT
	ctx->lr = (uint32_t)__exit_stub;
#else
	ctx->lr = (uint32_t)__thinkos_thread_exit;
#endif
	ctx->pc = pc;
	ctx->xpsr = CM_EPSR_T; /* set the thumb bit */
	thinkos_rt.ctx[thread_id] = ctx;

#if THINKOS_ENABLE_PAUSE
	/* insert into the paused list */
	__bit_mem_wr(&thinkos_rt.wq_paused, thread_id, 1);  
#endif

	DCC_LOG4(LOG_TRACE, "thread_id=%d sp=%08x lr=%08x pc=%08x", 
			 thread_id, sp, ctx->lr, ctx->pc);
	DCC_LOG4(LOG_MSG, "r0=%08x r1=%08x r2=%08x r3=%08x", 
			 ctx->r0, ctx->r1, ctx->r2, ctx->r3);
	DCC_LOG3(LOG_MSG, "msp=%08x psp=%08x ctrl=%02x", 
			 cm3_msp_get(), cm3_psp_get(), cm3_control_get());
}
Ejemplo n.º 7
0
struct tcp_pcb * tcp_accept(const struct tcp_pcb * __mux)
{
	struct tcp_listen_pcb * mux = (struct tcp_listen_pcb *)__mux;
	struct tcp_pcb * tp;

	if (__mux == NULL)
		DCC_LOG(LOG_WARNING, "NULL pointer");

	DCC_LOG1(LOG_INFO, "<%04x> waiting...", (int)mux);

	if (thinkos_sem_wait(mux->t_sem) < 0) {
		DCC_LOG2(LOG_ERROR, "<%04x> thinkos_sem_wait(%d) failed!", 
				 (int)mux, mux->t_sem);
		return NULL;
	}

	tcpip_net_lock();

	if (mux->t_state != TCPS_LISTEN) {
		DCC_LOG1(LOG_WARNING, "<%04x> invalid state!", (int)mux);
		tp = NULL;
	} else {
		unsigned int tail;

		tail = mux->t_tail;

		tp = (struct tcp_pcb *)mux->t_backlog[tail++];

		/* wrap */
		if (tail == mux->t_max)
			tail = 0;

		mux->t_tail = tail;

#ifdef ENABLE_SANITY
		if (tp == NULL)
			DCC_LOG(LOG_PANIC, "NULL pointer");
#endif

		DCC_LOG4(LOG_INFO, "<%04x> --> <%04x> %I:%d", (int)mux, 
				 (int)tp, tp->t_faddr, ntohs(tp->t_fport));
//		thinkos_sleep(100);
	}

	tcpip_net_unlock();

	return tp;
}
Ejemplo n.º 8
0
uint32_t calc32(int op, uint32_t x, uint32_t y)
{
	uint32_t z = 0;

	switch (op) { 
	case ADD:
		z = x + y; 
		break;
	case SUB:
		z = x - y; 
		break;
	case AND:
		z = x & y; 
		break;
	case OR:
		z = x | y; 
		break;
	case XOR:
		z = x ^ y; 
		break;
	case SHL:
		z = x << y; 
		break;
	case SHR:
		z = x >> y; 
		break;
	case MUL:
		z = x * y; 
		break;
	case DIV:
		z = x / y; 
		break;
	case MOD:
		z = x % y; 
		break;
	}

	DCC_LOG4(LOG_TRACE, "%d %s %d = %d", x, op_sym[op], y, z);

	return z;
}
Ejemplo n.º 9
0
Archivo: var.c Proyecto: k0059/yard-ice
int var_global_add(int mod_id, const char * name, int type, int var_id)
{
	struct var_def * var;

	if (var_cnt == VAR_GLOBAL_MAX) {
		DCC_LOG(LOG_WARNING, "no more room for global variables!");
		return -1;
	}

	var = &var_tab[var_cnt++];

	var->name = (char *)name;
	var->type = type;
	var->mod_id = mod_id;
	var->id = var_id;

	DCC_LOG4(LOG_TRACE, "name:'%s.%s' type:%s id:%d", module_name(mod_id),
		  name, type_name(type), var_id);

	return 0;
}
Ejemplo n.º 10
0
usb_cdc_class_t * usb_cdc_init(const usb_dev_t * usb,
                               const uint8_t * const str[],
                               unsigned int strcnt)
{
    struct usb_cdc_acm_dev * dev = &usb_cdc_rt;
    usb_class_t * cl =  (usb_class_t *)dev;

    /* initialize USB device */
    dev->usb = (usb_dev_t *)usb;

#ifndef CDC_RX_SEM_NO
    dev->rx_sem = thinkos_sem_alloc(0);
#endif
#ifndef CDC_TX_DONE_NO
    dev->tx_done = thinkos_flag_alloc();
#endif
#ifndef CDC_TX_LOCK_NO
    dev->tx_lock = thinkos_flag_alloc();
#endif
#ifndef CDC_CTL_FLAG_NO
    dev->ctl_flag = thinkos_flag_alloc();
#endif

    dev->rx_cnt = 0;
    dev->rx_pos = 0;
    dev->str = str;
    dev->strcnt = strcnt;

    DCC_LOG4(LOG_INFO, "tx_done=%d tx_lock=%d rx_sem=%d ctl_flag=%d",
             TX_DONE, TX_LOCK, RX_SEM, CTL_FLAG);

    thinkos_flag_clr(TX_DONE);
    thinkos_flag_clr(TX_LOCK);
    thinkos_flag_clr(CTL_FLAG);

    usb_dev_init(dev->usb, cl, &usb_cdc_ev);

    return (usb_cdc_class_t *)dev;
}
Ejemplo n.º 11
0
unsigned int jtag3ctrl_set_speed(unsigned int freq)
{
	uint32_t brg_freq;
	uint32_t brg_fmax;
	uint32_t brg_fmin;
	uint32_t tap_freq;
	uint32_t cfg;
	uint32_t clk;
	int32_t div;
	int sel;
	int err;
	int min = INT_MAX;
	int best_sel;

	brg_fmax = jtag_clk_tab[15] / 2;
	brg_freq = freq * 2;

	if (brg_freq > brg_fmax) {
		brg_freq = brg_fmax;
	}

	brg_fmin = jtag_clk_tab[0] / 0x10000;
	if (brg_freq < brg_fmin) {
		brg_freq = brg_fmin;
	}

	DCC_LOG1(LOG_INFO, "brg freq=%d", brg_freq);

	/* find the best matching frequency, but never bigger than
	   the desired frequency */
	best_sel = -1;
	for (sel = 0; sel <= 15; sel++) {
		clk = jtag_clk_tab[sel];
		div = ((clk + (brg_freq / 2)) / brg_freq) - 2;
		/* range checking */
		if (div < 0)
			div = 0;
		if (div >= 0xffff)
			div = 0xfffe;

		err = brg_freq - (clk / (div + 2));

		DCC_LOG3(LOG_INFO, "clk=%d div=%d err=%d", clk, (div + 2), 
				 brg_freq - (clk / (div + 2)));

		if ((err >= 0) && (err < min)) {
			min = err;
			best_sel = sel;
			if (err == 0)
				break;
		}
	}

	if (best_sel < 0)
		best_sel = 0;

	clk = jtag_clk_tab[best_sel];
	div = ((clk + (brg_freq / 2)) / brg_freq) - 2;
	/* range checking */
	if (div < 0)
		div = 0;
	if (div >= 0xffff)
		div = 0xfffe;

	/* select the clock source */
	cfg = reg_rd(REG_CFG) & ~CFG_CLK_SEL(0xf);
	reg_wr(REG_CFG, cfg | CFG_CLK_SEL(best_sel));
	/* configure the brg divisor */
	reg_wr(REG_BRG_DIV, div);

	brg_freq = clk / (div + 2);
	tap_freq = brg_freq / 2;

	DCC_LOG2(LOG_INFO, "sel: %d div: %d", best_sel, div + 2);

	DCC_LOG4(LOG_TRACE, "clk=%d.%06d MHz, TAP freq: %d.%06d MHz", 
		clk / 1000000, clk % 1000000, 
		tap_freq / 1000000, tap_freq % 1000000); 

	return tap_freq;
}
Ejemplo n.º 12
0
int tcp_input(struct ifnet * __if, struct iphdr * iph, 
			   struct tcphdr * th, int len)
{
	struct tcp_listen_pcb * mux;
	struct tcp_pcb * tp;
#if (ENABLE_NET_TCP_CHECKSUM)
	unsigned int sum;
#endif
	int ti_len;
	int acked = 0;
	int ourfinisacked = 0;
	int needoutput = 0;
	unsigned int optlen;
	int tiflags;
	int todrop;
	uint32_t snd_una;
	uint32_t snd_nxt;
	uint32_t snd_max;
	uint32_t ti_seq;
	uint32_t ti_ack;
	int rcv_wnd;
	int tiwin;
	int hdrlen;
	uint8_t * data;
	int ret;

#if (ENABLE_TCPDUMP)
	tcp_dump(iph, th, TCPDUMP_RX);
#endif

	/* get TCP options, if any */
	optlen = ((th->th_off << 2) - sizeof(struct tcphdr));
	hdrlen = sizeof(struct tcphdr) + optlen;

	data = (uint8_t *)&th->th_opt[optlen];
	ti_len = len - hdrlen;
	
#if (ENABLE_NET_TCP_CHECKSUM)
	/* initialize checksum */
	sum = htons(len) + (IPPROTO_TCP << 8);
	sum = in_chksum(sum, &iph->saddr,  8);
	sum = in_chksum(sum, th,  hdrlen);

	if (ti_len) {
		sum = in_chksum(sum, data, ti_len);
	}

	if (sum != 0x0000ffff) {
		DCC_LOG3(LOG_WARNING, "checksum error: 0x%04x hdrlen=%d, len=%d", 
				 sum, hdrlen, len);
		TCP_PROTO_STAT_ADD(rx_err, 1);
		goto drop;
	}
#endif

	tiflags = th->th_flags;
	/* convert TCP protocol specific fields to host format */
	tiwin = ntohs(th->th_win);
	ti_seq = ntohl(th->th_seq);
	ti_ack = ntohl(th->th_ack);

	TCP_PROTO_STAT_ADD(rx_ok, 1);

	/* Serch in active list first */
	if ((tp = tcp_active_lookup(iph->saddr, th->th_sport, 
								iph->daddr, th->th_dport)) == NULL) {
		/* lookup into listening pcb list */
		if ((mux = tcp_listen_lookup(iph->saddr, th->th_sport, 
									 iph->daddr, th->th_dport)) == NULL) {
			DCC_LOG(LOG_WARNING, "invalid peer ???");
			goto dropwithreset;
		}

		if ((tiflags & TH_ACK)) {
			DCC_LOG(LOG_WARNING, "listen ACK ?");
			goto dropwithreset;
		}

		if (ti_len != 0) {
			DCC_LOG(LOG_WARNING, "ti_len != 0");
			goto dropwithreset;
		}

		/* Completion of Passive Open
		   Ref.: TCP/IP Illustrated Volume 2, pg. 942 */
		if (!(tiflags & TH_SYN)) {
			DCC_LOG(LOG_WARNING, "listen !SYN ?");
			goto drop;
		}
	
		/* In the LISTEN state, we check for incoming SYN segments,
		   creates a new PCB, and responds with a SYN|ACK. */
		if ((tiflags & TH_RST)) {
			DCC_LOG(LOG_WARNING, "listen RST?");
			goto drop;
		}

		if ((tp = tcp_passive_open(mux, iph, th, optlen)) == NULL) {
			DCC_LOG(LOG_WARNING, "tcp_passive_open()");
			goto dropwithreset;
		}

		/* schedule output */
		tcp_output_sched(tp);

		/* packet handled */
		return 0;
	}

	DCC_LOG1(LOG_MSG, "<%05x> active", (int)tp);

	snd_una = tp->snd_seq;
	snd_nxt = tp->snd_seq + tp->snd_off;
	snd_max = tp->snd_seq + tp->snd_max;

 	/* Remove acknowledged bytes from the send buffer */
	/* Wakeup processes waiting on send buffer */

	/* Segment received on a connection.
	   Reset the idle detection timer 
	   Ref.: TCP/IP Illustrated Volume 2, pg. 932  */
	tp->t_conn_tmr = tcp_idle_det_tmo;
	if (tp->t_flags & TF_IDLE) {
		/* exits from the idle state */
		tp->t_flags &= ~TF_IDLE;
		DCC_LOG1(LOG_INFO, "<%05x> IDLE exit", (int)tp);		
	}

#if 0
	/* Process options, we don't need to check if the socket is 
	   in the LISTEN state, because only active (non LISTENING) sockets
	   will actually fall into this code. 
	   XXX: options after connection stablished ??? 
	 */
	if (optlen)
		tcp_parse_options(tp, th, th->th_opt, optlen);
#endif

	/* Ref.: TCP/IP Illustrated Volume 2, pg. 934  */
#if (TCP_ENABLE_HEADER_PREDICTION)
	if ((tp->t_state == TCPS_ESTABLISHED) &&
		(tiflags & (TH_SYN | TH_FIN | TH_RST | TH_URG | TH_ACK)) == TH_ACK &&
		(ti_seq == tp->rcv_nxt) && 
		(tiwin) && 
		(tiwin == tp->snd_wnd) && 
		(snd_nxt == snd_max)) {

		if (ti_len == 0) {

			if (SEQ_GT(ti_ack, snd_una) &&
				SEQ_LEQ(ti_ack, snd_max)) {
				acked = ti_ack - snd_una;
			
				DCC_LOG(LOG_INFO, "header prediction, ACK ...");

				mbuf_queue_trim(&tp->snd_q, acked);
				snd_una = ti_ack;

				tp->snd_seq = snd_una;
				tp->snd_off = snd_nxt - tp->snd_seq;
				tp->snd_max = snd_max - tp->snd_seq;

				if (snd_una == snd_max) {
					tp->t_rxmt_tmr = 0;
					tp->t_rxmt_cnt = 0;
					DCC_LOG(LOG_INFO, "acked all data, rxmt tmr stopped");
				} else {
					if (tp->t_rxmt_tmr == 0) {
						DCC_LOG(LOG_INFO, 
								"not all data acked restart rxmt tmr");
						tp->t_rxmt_tmr = tcp_rxmtintvl[tp->t_rxmt_cnt / 2];
					}
				}

				thinkos_cond_broadcast(tp->t_cond);

				if (tp->snd_q.len) {
					/* schedule output */
					tcp_output_sched(tp);
				}

				return 0;
			}
		} else {
			if ((ti_ack == snd_una) && 
				ti_len <= (tcp_maxrcv - tp->rcv_q.len)) {
				int len;

				DCC_LOG1(LOG_INFO, "header prediction, data (%d)", ti_len);

				/* append data */
				len = mbuf_queue_add(&tp->rcv_q, data, ti_len);
				tp->rcv_nxt += len;
				thinkos_cond_broadcast(tp->t_cond);

				if (len != ti_len) {
					DCC_LOG1(LOG_WARNING, "<%05x> no more mbufs", (int)tp);
					tp->t_flags |= TF_ACKNOW;
					/* schedule output */
					tcp_output_sched(tp);
				} else {
					tp->t_flags |= TF_DELACK;
				}

				return 0;
			 }
		}
	}

#endif /* TCP_ENABLE_HEADER_PREDICTION */

	/* Slow path input processing
	   Ref.: TCP/IP Illustrated Volume 2, pg. 941  */

	/* TODO: Drop TCP, IP headers and TCP options. 
		Well, only if these structures were dynamic allocated... */
	
	if (ti_len == 0) {
		DCC_LOG(LOG_INFO, "slow path ACK");
	} else {
		DCC_LOG1(LOG_INFO, "slow path (%d)", ti_len);
	}

	/* Calculate the amount of space in receive window,
	   and then do TCP input processing.
	   Receive window is amount of space in rcv queue,
	   but not less than advertise window.
	   Ref.: TCP/IP Illustrated Volume 2, pg. 941  */
	{
		int win;
		
		/* space left in the input queue */
		win = tcp_maxrcv - tp->rcv_q.len;
		
		if (win <= 0) {
			win = 0;
			DCC_LOG(LOG_INFO, "receive buffer full!");
		}


//		rcv_wnd = MAX(win, tp->rcv_adv_wnd);
		rcv_wnd = win;

		DCC_LOG3(LOG_INFO, "adv_wnd=%d rcv_wnd=%d win=%d", 
				tp->rcv_adv_wnd, rcv_wnd, win);
	} 

	if (tp->t_state == TCPS_SYN_SENT) {
		/* response to an active open. 
		   Ref.: TCP/IP Illustrated Volume 2, pg. 947  */

		/* Common proccessing for receipt of SYN. 
		   Ref.: TCP/IP Illustrated Volume 2, pg. 950 */
		if ((tiflags & TH_RST)) {
			goto close;
		}

		if (!(tiflags & TH_SYN)) {
			DCC_LOG(LOG_WARNING, "SYN_SENT SYN ?");
			/* TODO: reset */
			goto close_and_reset;
		}

		if (!(tiflags & TH_ACK)) {
			DCC_LOG(LOG_WARNING, "SYN_SENT ACK ?");
			/* TODO: reset */
			goto close_and_reset;
		}

		if (ti_len != 0) {
			DCC_LOG(LOG_WARNING, "ti_len != 0");
			/* TODO: reset */
			goto close_and_reset;
		}

		/* update the send sequence */
		tp->snd_seq++;
		if (tp->snd_seq != ti_ack) {
			DCC_LOG3(LOG_WARNING, "<%05x> tp->snd_seq(%d) != ti_ack(%d)",
					 (int)tp, tp->snd_seq, ti_ack);
			/* TODO: reset */
			goto close_and_reset;
		}
		tp->snd_off--;
		tp->snd_max--;
//		tp->snd_off = 0;
//		tp->snd_max = 0;

		if (optlen)
			tcp_parse_options(tp, th, th->th_opt, optlen);

		/* Advance tp->ti_seq to correspond to first data byte. */
		ti_seq++;
		if (ti_len > rcv_wnd) {
			DCC_LOG3(LOG_WARNING, "<%05x> ti_len(%d) > rcv_wnd(%d)", 
				(int)tp, ti_len, rcv_wnd);
		/* TODO: if data, trim to stay within window. */
			ti_len = rcv_wnd;
		}

		/* update the sequence number */
		tp->rcv_nxt = ti_seq;

		/* update the window size */
		tp->snd_wnd = ntohs(th->th_win);

		tp->t_state = TCPS_ESTABLISHED;
		DCC_LOG1(LOG_INFO, "<%05x> [ESTABLISHED]", (int)tp);
		/* TODO: initialization of receive urgent pointer
		tcp->rcv_up = ti_seq; */
		/* XXX: */ 
		tp->t_flags |= TF_ACKNOW;
		thinkos_cond_broadcast(tp->t_cond);

		goto step6;

close_and_reset:
		tp->t_state = TCPS_CLOSED;
		pcb_move((struct pcb *)tp, &__tcp__.active, &__tcp__.closed);
		DCC_LOG1(LOG_INFO, "<%05x> [CLOSED]", (int)tp);

		/* XXX: discard the data */
		mbuf_queue_free(&tp->snd_q);
		mbuf_queue_free(&tp->rcv_q);

		/* notify the upper layer */
		thinkos_cond_broadcast(tp->t_cond);

		goto dropwithreset;	
	}

/* States other than LISTEN or SYN_SENT 
   First check timestamp, if present.
   Then check that at least some bytes of segment are within
   receive window.  If segment begins before rcv_nxt,
   drop leading data (and SYN); if nothing left, just ti_ack. */

	/* Trim Segment so Data is Within Window
	   Ref.: TCP/IP Illustrated Volume 2, pg. 954 */
	todrop = tp->rcv_nxt - ti_seq;
	if (todrop > 0) {
		if (tiflags & TH_SYN) {
			DCC_LOG(LOG_INFO, "SYN");
			tiflags &= ~TH_SYN;
			ti_seq++;
			todrop--;
		}
		if ((todrop > ti_len) || 
		   ((todrop == ti_len) && ((tiflags & TH_FIN) == 0))) {
			tiflags &= ~TH_FIN;
			tp->t_flags |= TF_ACKNOW;
			todrop = ti_len;		
		}

		DCC_LOG4(LOG_WARNING, "<%05x> drop: len=%d drop=%d rem=%d!", 
			(int)tp, ti_len, todrop, ti_len - todrop);

		/* adjust the data pointer */
		data += todrop;

		ti_seq += todrop;
		ti_len -= todrop;

		/* TODO: adjust the urgent pointer */
	} 

	/* FIXME: only reset the connection if there are no more 
		application to handle the incomming data, half-close */
	if ((tp->t_state > TCPS_FIN_WAIT_1) && (ti_len)) { 
		DCC_LOG1(LOG_INFO, "<%05x> segment received after FIN", (int)tp);
		/* TODO: stat */
		goto dropwithreset;	
	}

	/* If segment ends after window, drop trailing data
	   and (PUSH and FIN); if nothing left, just ACK.
	   Ref.: TCP/IP Illustrated Volume 2, pg. 958 */
	todrop = (ti_seq + ti_len) - (tp->rcv_nxt + rcv_wnd);

	DCC_LOG4(LOG_INFO, "ti_seq=%u ti_len=%d rcv_nxt=%u rcv_wnd=%d", 
			ti_seq,  ti_len, tp->rcv_nxt, rcv_wnd);
	/* */

	if (todrop > 0) {
//		TCP_LOG(tp, "tcp_input: trailing data drop");
		if (todrop >= ti_len) {

	   		/* 
			 * If a new connection request is received 
			 * while in TIME_WAIT, drop the old connection ...
			 * Ref.: TCP/IP Illustrated Volume 2, pg. 958 
			if ((tiflags & TH_SYN) && (tp->t_state == TCPS_TIMEWAIT) &&
			   (SEQ_GT(ti_seq, tp->rcv_nxt))) {
				__tcp__.iss += tcp_issincr;
				tcp_rst(tp);
				goto findpcb;
			} */

			if ((rcv_wnd == 0) && (ti_seq == tp->rcv_nxt)) {
				tp->t_flags |= TF_ACKNOW;
			} else
				goto dropafterack;
		}

		DCC_LOG2(LOG_WARNING, "<%05x> data drop: %d!", (int)tp, todrop);
		ti_len -= todrop;
		tiflags &= ~(TH_PSH | TH_FIN);
	}

	/* If the RST bit is set eximine the state: ...
	   Ref.: TCP/IP Illustrated Volume 2, pg. 964 */
	if ((tiflags & TH_RST)) {
		DCC_LOG1(LOG_WARNING, "<%05x> RST received", (int)tp);
		switch(tp->t_state) {
		case TCPS_SYN_RCVD:
//			tp->errno = ECONNREFUSED;
			goto close;
		case TCPS_ESTABLISHED:
		case TCPS_CLOSE_WAIT:
//			tp->errno = ECONNRESET;
close:
			/* discard the data */
			mbuf_queue_free(&tp->snd_q);
			mbuf_queue_free(&tp->rcv_q);

			tp->t_state = TCPS_CLOSED;
			pcb_move((struct pcb *)tp, &__tcp__.active, &__tcp__.closed);
			DCC_LOG1(LOG_INFO, "<%05x> [CLOSED]", (int)tp);

			/* notify the upper layer */
			thinkos_cond_broadcast(tp->t_cond);
			/* PCBs in the close state should be cleared by the application */
			goto drop;

		case TCPS_FIN_WAIT_1:
		case TCPS_FIN_WAIT_2:
		case TCPS_CLOSING:
		case TCPS_LAST_ACK:
		case TCPS_TIME_WAIT:
			/* Our side was already closed */
			tcp_pcb_free(tp);
			goto drop;
		}
	}

	/* If a SYN is in the window, then this is an 
	   error and we send an RST and drop the connection.
	   Ref.: TCP/IP Illustrated Volume 2, pg. 965 */
	if ((tiflags & TH_SYN)) {
		DCC_LOG1(LOG_WARNING, "<%05x> the SYN bit is set inside the window", 
			(int)tp);
		goto dropwithreset;
	}

	/* If the ACK bit is off we drop the segment and return. */
	if ((!(tiflags & TH_ACK))) {
		DCC_LOG1(LOG_WARNING, "<%05x> the ACK bit is off", (int)tp);
		goto drop;
	}
	
/*
 * ACK processing.
 * Ref.: TCP/IP Illustrated Volume 2, pg. 969 
 *
 */

	DCC_LOG4(LOG_INFO, "ack=%u una=%u nxt=%u max=%u", 
			 ti_ack, snd_una, snd_nxt, snd_max);

	switch(tp->t_state) {
	case TCPS_SYN_RCVD:
		if (SEQ_GT(snd_una, ti_ack) || 
			SEQ_GT(ti_ack, snd_max)) {
			DCC_LOG1(LOG_WARNING, 
					 "<%05x> ti_ack < snd_una || snd_max < ti_ack", 
					 (int)tp);
			goto dropwithreset;
		}
		tp->t_state = TCPS_ESTABLISHED;
		tp->snd_off--;
		tp->snd_max--;
		DCC_LOG1(LOG_INFO, "<%05x> SYN ackd [ESTABLISHED]", (int)tp);
		/* notify the upper layer*/
//		thinkos_cond_signal(tp->t_cond);

		/* TODO: tcp reassembly
		tcp_reass(tp); */
	case TCPS_ESTABLISHED:
	case TCPS_FIN_WAIT_1:
	case TCPS_FIN_WAIT_2:
	case TCPS_CLOSE_WAIT:
	case TCPS_CLOSING:
	case TCPS_LAST_ACK:
	case TCPS_TIME_WAIT:
		/* TODO: tcp reassembly
		   tcp_reass(tp); */
		if (SEQ_LEQ(ti_ack, snd_una)) {
			/* TODO: check for completly duplicated ACKs.
			   Ref.: TCP/IP Illustrated Volume 2, pg. 971 */
			if ((ti_len == 0) && (tiwin == tp->snd_wnd)) {
				if ((tp->t_rxmt_tmr == 0) || ti_ack != snd_una) {
//					dupacks = 0;
				} else {
					DCC_LOG2(LOG_INFO, "duplicated ACK. ti_ack=%u snd_una=%u", 
							 ti_ack, snd_una);
				}
			} else {
//				dupacks = 0;
			}
			break;
		}

		/* Check out of range ACK */
		/*  Ref.: TCP/IP Illustrated Volume 2, pg. 974 */
		if (SEQ_GT(ti_ack, snd_max)) {
			/* TODO:
			   tcpstat.tcps_rcvacktoomuch++;
			 */
			DCC_LOG3(LOG_WARNING, "(%04x) out of range ACK. "
				"th_ack=%u > snd_max=%u !", 
				(int)tp, ti_ack, snd_max);
			goto dropafterack;	
		}

		acked = ti_ack - snd_una;

		/* TODO:
		   tcpstat.tcps_rcvackpack++;
		   tcpstat.tcps_rcvackbyte += acked;		
		 */

		DCC_LOG1(LOG_INFO, "acked=%d", acked);

		/* If all outstanding data is acked, stop retransmit timer else
		   restarts it ....
		   Ref.: TCP/IP Illustrated Volume 2, pg. 976 */
		if (ti_ack == snd_max) {
			tp->t_rxmt_tmr = 0;
			tp->t_rxmt_cnt = 0;
			needoutput = 1;
			DCC_LOG(LOG_INFO, "acked all data, rxmt tmr stopped");
		} else {
			/* TODO: peristent timer */
//			if (tp->t_persist_tmr == 0) {
				DCC_LOG(LOG_INFO, "not all data acked restart rxmt tmr");
				tp->t_rxmt_tmr = tcp_rxmtintvl[tp->t_rxmt_cnt / 2];
//			}
		}

		/* TODO:
		   tcpstat.tcps_rcvackpack++;
		   tcpstat.tcps_rcvackbyte += acked;		
		 */

		/* TODO: remove acknowledged data from send buffer 
		   Ref.: TCP/IP Illustrated Volume 2, pg. 978 */
		/* FIXME: send buffer bytes count */
		if (acked > tp->snd_q.len) {
			mbuf_queue_trim(&tp->snd_q, tp->snd_q.len);
			ourfinisacked = 1;
		} else {
			/* TODO: estimate the send window */
			mbuf_queue_trim(&tp->snd_q, acked);
			ourfinisacked = 0;
		}

		/* awaken a thread waiting on the send buffer ... */
		thinkos_cond_broadcast(tp->t_cond);

		snd_una = ti_ack;

		if (SEQ_LT(snd_nxt, snd_una)) {
			snd_nxt = snd_una;
		}

		tp->snd_seq = snd_una;
		tp->snd_off = snd_nxt - tp->snd_seq;
		tp->snd_max = snd_max - tp->snd_seq;

		DCC_LOG4(LOG_INFO, "<%05x> snd_seq=%u snd_max=%u snd_q.len=%d", 
			(int)tp, tp->snd_seq, snd_max, tp->snd_q.len); 

		switch(tp->t_state) {
		case TCPS_FIN_WAIT_1:
			if (ourfinisacked) {
				/* FIXME: If we can't receive any more data..
				   Ref.: TCP/IP Illustrated Volume 2, pg. 979 */
				tp->t_conn_tmr = 4 * tcp_msl;
				tp->t_state = TCPS_FIN_WAIT_2;
				DCC_LOG1(LOG_INFO, "<%05x> [FIN_WAIT_2]", (int)tp);
			}
			break;
		case TCPS_CLOSING:
			if (ourfinisacked) {
				mbuf_queue_free(&tp->snd_q);
				mbuf_queue_free(&tp->rcv_q);
				tp->t_state = TCPS_TIME_WAIT;
				DCC_LOG1(LOG_INFO, "<%05x> [TIME_WAIT]", (int)tp);
				tp->t_rxmt_tmr = 0;
				tp->t_conn_tmr = 2 * tcp_msl;
				DCC_LOG1(LOG_INFO, "stop rxmt tmr, start 2MSL tmr: %d",
						 tp->t_conn_tmr);
			}
			break;
		case TCPS_LAST_ACK:
			if (ourfinisacked) {
				tcp_pcb_free(tp);
				goto drop;
			}
			break;

		case TCPS_TIME_WAIT:
			/* restart the finack timer 
			   Ref.: TCP/IP Illustrated Volume 2, pg. 981 */
			tp->t_conn_tmr = 2 * tcp_msl;
			goto dropafterack;
		}
		break;
	}

	DCC_LOG4(LOG_INFO, "<%05x> recvd=%d acked=%d rcv_q.len=%d", (int)tp, 
		ti_len, acked, tp->rcv_q.len);
step6:
	/* Update window information 
	   Ref.: TCP/IP Illustrated Volume 2, pg. 982 */
	DCC_LOG(LOG_MSG, "setp6");
	
//	if ((tiflags & TH_ACK) && (tiwin > tp->snd_wnd)) {
	if ((tiflags & TH_ACK) && (tiwin != tp->snd_wnd)) {
		/* Keep track of pure window updates */
		/* TODO: TCP Statistics */
		/* TODO: Update window information */
		DCC_LOG1(LOG_INFO, "window update, win=%d", tiwin);
		tp->snd_wnd = tiwin;
		needoutput = 1;
	}

	/* TODO: Urgent mode processing */
	/* Process the segment text, 
	   merging it into the TCP sequencing queue,
dodata:
	   ...
	   Ref.: TCP/IP Illustrated Volume 2, pg. 988 */
	if ((ti_len || (tiflags & TH_FIN)) && 
		TCPS_HAVERCVDFIN(tp->t_state) == 0) {

		if ((ti_seq == tp->rcv_nxt) && (tp->t_state == TCPS_ESTABLISHED)) {

			/* append data */
			int n;

			tp->t_flags |= TF_DELACK;

			n = mbuf_queue_add(&tp->rcv_q, data, ti_len);
			if (n != ti_len) {
				DCC_LOG2(LOG_WARNING, "no more mbufs, %d != %d", n, ti_len);
			}
			ti_len = n;

			tp->rcv_nxt += ti_len;
			/* TODO: statistics */

			tiflags &= TH_FIN;

//			if (tp->rcv_q.len == ti_len) {
//				DCC_LOG3(LOG_INFO, "<%05x> rcvd %d, signaling %d ...", 
//					(int)tp, ti_len, tp->t_cond);
			/* 
			 * notify the upper layer of the data arrival...
			 */
			thinkos_cond_signal(tp->t_cond);
//			} else {
//				DCC_LOG2(LOG_INFO, "<%05x> rcvd %d", (int)tp, ti_len);
//			}

		} else {
			/* TODO: half-close */
			/* TODO: reassembly */
//			m = mlink_free(m);
			if (tp->t_state == TCPS_ESTABLISHED) {
//				DCC_LOG(LOG_WARNING, "out of order, drop!");
				DCC_LOG(LOG_WARNING, "out of order, drop");
				TCP_PROTO_STAT_ADD(rx_drop, 1);
			}
			tp->t_flags |= TF_ACKNOW;
		}
	} else {
		DCC_LOG(LOG_INFO, "!!!!!!!!!");
		tiflags &= ~TH_FIN;
	}

	/* FIN Processing */
	if (tiflags & TH_FIN) {
		if (TCPS_HAVERCVDFIN(tp->t_state) == 0) {
			tp->t_flags |= TF_ACKNOW;
			tp->rcv_nxt++;
		}
		switch(tp->t_state) {
		case TCPS_SYN_RCVD:
		case TCPS_ESTABLISHED:
			tp->t_state = TCPS_CLOSE_WAIT;
			DCC_LOG1(LOG_INFO, "<%05x> [CLOSE_WAIT]", (int)tp);
			/* notify the application that our peer 
			   has closed its side. Sockets: marks 
			   the socket as write-only */
			if (tp->rcv_q.len == 0) {
				thinkos_cond_broadcast(tp->t_cond);
			}
			break;
		case TCPS_FIN_WAIT_1:
			tp->t_state = TCPS_CLOSING;
			DCC_LOG1(LOG_INFO, "<%05x> [CLOSING]", (int)tp);
			break;
		case TCPS_FIN_WAIT_2:
			mbuf_queue_free(&tp->rcv_q);
			mbuf_queue_free(&tp->snd_q);
			tp->t_state = TCPS_TIME_WAIT;
			DCC_LOG1(LOG_INFO, "<%05x> [TIME_WAIT]", (int)tp);
			tp->t_rxmt_tmr = 0;
			tp->t_conn_tmr = 2 * tcp_msl;
			DCC_LOG1(LOG_INFO, "stop rxmt tmr, start 2MSL tmr: %d",
					 tp->t_conn_tmr);
			break;
		case TCPS_TIME_WAIT:
			/* restart the counter */
			tp->t_conn_tmr = 2 * tcp_msl;
			break;
		}
	}

	/* Final Processing */
	if (needoutput || (tp->t_flags & TF_ACKNOW)) {
		if (needoutput) {
			DCC_LOG(LOG_INFO, "needoutput, call tcp_out.");
		}
		if (tp->t_flags & TF_ACKNOW) {
			DCC_LOG(LOG_INFO, "ACKNOW set, call tcp_out.");
		}
		/* schedule output */
		tcp_output_sched(tp);
	}
	return 0;

dropafterack:
	DCC_LOG1(LOG_INFO, "<%05x> drop and ACK", (int)tp);

	if (tiflags & TH_RST)
		goto drop;

	tp->t_flags |= TF_ACKNOW;
	/* schedule output */
	tcp_output_sched(tp);
	return 0;

dropwithreset:
	DCC_LOG1(LOG_TRACE, "<%05x> drop and RST", (int)tp);

	ret = 0;
	/* TODO: check for a broadcast/multicast */
	if (!(tiflags & TH_RST)) {
		if (tiflags & TH_ACK) {
			ret = tcp_respond(iph, th, 0, ti_ack, TH_RST);
		} else if (tiflags & TH_SYN) {
				ti_len++;
			ret = tcp_respond(iph, th, ti_seq + ti_len, 0, TH_ACK | TH_RST);
		}
	}
	TCP_PROTO_STAT_ADD(rx_drop, 1);
	return ret;

drop:
	DCC_LOG(LOG_TRACE, "drop");
	TCP_PROTO_STAT_ADD(rx_drop, 1);

	return 0;
}
Ejemplo n.º 13
0
int usb_cdc_read(usb_cdc_class_t * cl, void * buf,
                 unsigned int len, unsigned int msec)
{
    struct usb_cdc_acm_dev * dev = (struct usb_cdc_acm_dev *)cl;
    int ret;
    int n;

    DCC_LOG2(LOG_INFO, "len=%d msec=%d", len, msec);

    if ((n = dev->rx_cnt - dev->rx_pos) > 0) {
        DCC_LOG(LOG_INFO, "read from intern buffer");
        goto read_from_buffer;
    };

    usb_dev_ep_nak(dev->usb, dev->out_ep, false);

    if ((ret = thinkos_sem_timedwait(RX_SEM, msec)) < 0) {
        if (ret == THINKOS_ETIMEDOUT) {
            DCC_LOG(LOG_INFO, "timeout!!");
        }
        return ret;
    }

    if (len >= CDC_EP_IN_MAX_PKT_SIZE) {
        n = usb_dev_ep_pkt_recv(dev->usb, dev->out_ep, buf, len);
        DCC_LOG1(LOG_INFO, "wakeup, pkt rcv extern buffer: %d bytes", n);
        return n;
    }

    n = usb_dev_ep_pkt_recv(dev->usb, dev->out_ep,
                            dev->rx_buf, CDC_EP_IN_MAX_PKT_SIZE);
    DCC_LOG1(LOG_INFO, "wakeup, pkt rcv intern buffer: %d bytes", n);

    {
        char * s = (char *)dev->rx_buf;
        (void)s;

        if (n == 1)
            DCC_LOG1(LOG_INFO, "%02x", s[0]);
        else if (n == 2)
            DCC_LOG2(LOG_INFO, "%02x %02x", s[0], s[1]);
        else if (n == 3)
            DCC_LOG3(LOG_INFO, "%02x %02x %02x", s[0], s[1], s[2]);
        else if (n == 4)
            DCC_LOG4(LOG_INFO, "%02x %02x %02x %02x",
                     s[0], s[1], s[2], s[3]);
        else if (n == 5)
            DCC_LOG5(LOG_INFO, "%02x %02x %02x %02x %02x",
                     s[0], s[1], s[2], s[3], s[4]);
        else if (n == 6)
            DCC_LOG6(LOG_INFO, "%02x %02x %02x %02x %02x %02x",
                     s[0], s[1], s[2], s[3], s[4], s[5]);
        else if (n == 7)
            DCC_LOG7(LOG_INFO, "%02x %02x %02x %02x %02x %02x %02x",
                     s[0], s[1], s[2], s[3], s[4], s[5], s[6]);
        else if (n == 8)
            DCC_LOG8(LOG_INFO, "%02x %02x %02x %02x %02x %02x %02x %02x",
                     s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7]);
        else
            DCC_LOG8(LOG_INFO, "%02x %02x %02x %02x %02x %02x %02x %02x ...",
                     s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7]);
    }


    dev->rx_pos = 0;
    dev->rx_cnt = n;

read_from_buffer:
    DCC_LOG(LOG_INFO, "reading from buffer");
    /* get data from the rx buffer if not empty */
    n = MIN(n, len);
    memcpy(buf, &dev->rx_buf[dev->rx_pos], n);

    dev->rx_pos += n;
    return n;

#if 0
    {
        int rem;
        uint8_t * cp = (uint8_t *)buf;

        rem = n;

        while (rem > 4) {
            DCC_LOG4(LOG_INFO, "%02x %02x %02x %02x",
                     cp[0], cp[1], cp[2], cp[3]);
            rem -= 4;
            cp += 4;
        }

        switch (rem) {
        case 3:
            DCC_LOG3(LOG_INFO, "%02x %02x %02x", cp[0], cp[1], cp[2]);
            break;
        case 2:
            DCC_LOG2(LOG_INFO, "%02x %02x", cp[0], cp[1]);
            break;
        case 1:
            if ((*cp) >= ' ') {
                DCC_LOG1(LOG_INFO, "'%c'", cp[0]);
            } else {
                DCC_LOG1(LOG_INFO, "%02x", cp[0]);
            }
            break;
        }
    }
#endif

}
Ejemplo n.º 14
0
/***********************************************************************
 ICE Driver Methods
 ***********************************************************************/
static int cm3ice_comm_sync(cm3ice_ctrl_t * ctrl, ice_comm_t * comm)
{
	jtag_tap_t * tap = ctrl->tap;

	/* Reload the COMM address */
	if (jtag_mem_ap_rd32(tap, 8 * 4, 
						 &ctrl->comm_addr) != JTAG_ADI_ACK_OK_FAULT) {
		DCC_LOG(LOG_WARNING, "jtag_mem_ap_rd32() failed!"); 
		return ICE_ST_FAULT;
	}

	if ((ctrl->comm_addr == 0x00000000) || (ctrl->comm_addr == 0xffffffff)) {
		DCC_LOG1(LOG_INFO, "comm block not found! comm_addr=0x%08x", 
				 ctrl->comm_addr);
		return 0;
	}

	DCC_LOG1(LOG_TRACE, "COMM=0x%08x", ctrl->comm_addr);

	/* get the state of the device's COMM buffer */
	jtag_mem_ap_read(tap, ctrl->comm_addr, &ctrl->cc, 8);

	DCC_LOG4(LOG_TRACE, "COMM: dbg=%d dev=%d tx_tail=%d tx_head=%d", 
			 ctrl->cc.rw.dbg, ctrl->cc.ro.dev, 
			 ctrl->cc.rw.tx_tail, ctrl->cc.ro.tx_head);

	if (ctrl->cc.ro.dev == DEV_CONNECTED) {
		if (ctrl->cc.rw.dbg == DBG_CONNECTED) {
			DCC_LOG(LOG_TRACE, "COMM already connected...");
			return 0;
		}
		if (ctrl->cc.rw.dbg != DBG_SYNC) {
			DCC_LOG1(LOG_WARNING, 
					 "DEV=CONNECTED, DBG!=(SYNC|CONNECTED) %02x??", 
					 ctrl->cc.rw.dbg);
			return 0;
		}
		DCC_LOG(LOG_TRACE, "COMM: [CONNECTED]"); 

		ctrl->cc.rw.dbg = DBG_CONNECTED;
		/* update the state of the buffer */
		if (jtag_mem_ap_wr32(tap, ctrl->comm_addr + 4, 
							 ctrl->cc.rw.u32) != JTAG_ADI_ACK_OK_FAULT) {
			DCC_LOG(LOG_WARNING, "jtag_mem_ap_wr32() failed!"); 
			return ICE_ST_FAULT;
		}
		return 0;
	}

	if (ctrl->cc.ro.dev == DEV_SYNC) {
		if (ctrl->cc.rw.dbg == DBG_SYNC) {
			DCC_LOG(LOG_TRACE, "DEV=SYNC, DBG=SYNC, wating ....");
			return 0;
		}	
		if (ctrl->cc.rw.dbg == DBG_CONNECTED) {
			DCC_LOG(LOG_WARNING, "DEV=SYNC, DBG=CONNECTED ???");
		}
		DCC_LOG(LOG_TRACE, "COMM: [SYNC]"); 
		ctrl->cc.rw.dbg = DBG_SYNC;
		/* ensure the buffer is flushed */
		ctrl->cc.rw.tx_tail = 0;
		ctrl->cc.rw.rx_head = 0;
		/* update the state of the buffer */
		if (jtag_mem_ap_wr32(tap, ctrl->comm_addr + 4, 
							 ctrl->cc.rw.u32) != JTAG_ADI_ACK_OK_FAULT) {
			DCC_LOG(LOG_WARNING, "jtag_mem_ap_wr32() failed!"); 
			return ICE_ST_FAULT;
		}

		return 0;
	}

	DCC_LOG(LOG_INFO, "COMM: [IDLE]");

	return 0;
}
Ejemplo n.º 15
0
void module_contorl_seq(struct ss_device * dev, uint32_t ctl)
{
	device_led_default(dev, ctl);

	switch (ctl & 0x7) {
	case 0:/* 0 0 0 */
		/* Outputs:         1  2  3  5 */
		dev->out1 = 1; /* Pulse */
		dev->out2 = 1; 
		dev->out3 = 1;
		dev->out5 = 1;
		DCC_LOG(LOG_MSG, "Pu 1  1  1");
		break;
	case 4: /* 0 0 1 */
		dev->out1 = 1; /* Pulse */
		dev->out3 = 1;
		dev->out5 = 1;
		DCC_LOG(LOG_MSG, "Pu NC 1  1");
		break;
	case 2: /* 0 1 0 */
		dev->out1 = 0;
		dev->out2 = 1;
		dev->out3 = 1;
		dev->out5 = 1;
		DCC_LOG(LOG_MSG, "0  1  1  1");
		break;
	case 6: /* 0 1 1 */
		dev->out1 = 0;
		dev->out3 = 1;
		dev->out5 = 1;
		DCC_LOG(LOG_MSG, "0  NC 1  1");
		break;
	case 1: /* 1 0 0 */
		dev->out1 = 1; /* Pulse */
		dev->out3 = 0;
		dev->out5 = 0;
		DCC_LOG(LOG_MSG, "Pu NC 0  0");
		break;
	case 5: /* 1 0 1 */
		dev->out1 = 0; /* Pulse */
		dev->out2 = 0;
		dev->out3 = 1; /* Pulse */
		dev->out5 = 1; /* Pulse */
		DCC_LOG(LOG_MSG, "Pu 0  Pu Pu");
		break;
	case 3: /* 1 1 0 */
		dev->out1 = 0;
		dev->out2 = 0;
		dev->out5 = 0;
		DCC_LOG(LOG_MSG, "0  NC 0  0");
		break;
	case 7: /* 1 1 1 */
		dev->out1 = 0;
		dev->out2 = 0;
		dev->out3 = 1; /* Pulse */
		dev->out5 = 1; /* Pulse */
		DCC_LOG(LOG_MSG, "0  0  Pu Pu");
		break;
	}

	DCC_LOG4(LOG_INFO, "%d %d %d %d",
			 dev->out1, dev->out2, dev->out3, dev->out5);
}