static vmm_irq_return_t omap_uart_irq_handler(int irq_no, void *dev) { u16 iir, lsr; struct omap_uart_port *port = (struct omap_uart_port *)dev; iir = omap_serial_in(port, UART_IIR); if (iir & UART_IIR_NO_INT) return VMM_IRQ_NONE; lsr = omap_serial_in(port, UART_LSR); /* Handle RX FIFO not empty */ if (iir & (UART_IIR_RLSI | UART_IIR_RTO | UART_IIR_RDI)) { if (lsr & UART_LSR_DR) { /* Mask RX interrupts till RX FIFO is empty */ port->ier &= ~(UART_IER_RDI | UART_IER_RLSI); /* Signal work completion to sleeping thread */ vmm_completion_complete(&port->read_possible); } else if (lsr & (UART_LSR_OE | UART_LSR_PE | UART_LSR_BI | UART_LSR_FE) ) { while(1); } } /* Handle TX FIFO not full */ if ((lsr & UART_LSR_THRE) && (iir & UART_IIR_THRI)) { /* Mask TX interrupts till TX FIFO is full */ port->ier &= ~UART_IER_THRI; /* Signal work completion to sleeping thread */ vmm_completion_complete(&port->write_possible); } omap_serial_out(port, UART_IER, port->ier); return VMM_IRQ_HANDLED; }
static int uip_switch2port_xfer(struct vmm_netport *port, struct vmm_mbuf *mbuf) { struct uip_port_state *s = &uip_port_state; int rc = VMM_OK; unsigned long flags; #ifdef UIP_DEBUG char tname[30]; #endif u8 *dstmac = ether_dstmac(mtod(mbuf, u8 *)); /* do not accept frames which do not have either * our MAC or broadcast MAC */ DPRINTF("UIP received frame with MAC[%s]", ethaddr_to_str(tname, srcmac)); if(compare_ether_addr(dstmac, port->macaddr) && !is_broadcast_ether_addr(dstmac)) { /* Reject packets addressed for someone else */ DPRINTF(" and rejected \n"); return VMM_EFAIL; } else { DPRINTF(" and accepted \n"); } vmm_spin_lock_irqsave(&s->lock, flags); list_add_tail(&mbuf->m_list, &s->rxbuf); vmm_spin_unlock_irqrestore(&s->lock, flags); vmm_completion_complete(&s->rx_possible); return rc; }
/** * Callback to notify reception of a ICMP_ECHO_REPLY */ void uip_ping_callback(struct vmm_icmp_echo_reply *reply) { if(uip_ping_reply) { memcpy(uip_ping_reply, reply, sizeof(struct vmm_icmp_echo_reply)); vmm_completion_complete(&uip_ping_done); } }
static void blockdev_rw_failed(struct vmm_request *req) { struct blockdev_rw *rw = req->priv; if (!rw) { return; } rw->failed = TRUE; vmm_completion_complete(&rw->done); }
static int mutex4_worker_thread_main(void *data) { int i; for (i = 0; i < NUM_LOOPS; i++) { /* Acquire wake mutex */ vmm_mutex_lock(&mutex1); /* Release wake mutex */ vmm_mutex_unlock(&mutex1); } /* Signal work done completion */ vmm_completion_complete(&work_done); return 0; }
static u8_t ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *addr) { struct ip_hdr *iphdr; struct icmp_echo_hdr *iecho; LWIP_UNUSED_ARG(arg); LWIP_UNUSED_ARG(pcb); LWIP_UNUSED_ARG(addr); LWIP_ASSERT("p != NULL", p != NULL); if ((p->tot_len >= (PBUF_IP_HLEN + sizeof(struct icmp_echo_hdr)))) { iphdr = (struct ip_hdr *)p->payload; iecho = (struct icmp_echo_hdr *)(p->payload + (IPH_HL(iphdr) * 4)); if ((lns.ping_reply != NULL) && (iecho->id == PING_ID) && (iecho->seqno == htons(lns.ping_seq_num))) { lns.ping_recv_tstamp = vmm_timer_timestamp(); lns.ping_reply->ripaddr[0] = ip4_addr1(&lns.ping_addr); lns.ping_reply->ripaddr[1] = ip4_addr2(&lns.ping_addr); lns.ping_reply->ripaddr[2] = ip4_addr3(&lns.ping_addr); lns.ping_reply->ripaddr[3] = ip4_addr4(&lns.ping_addr); lns.ping_reply->ttl = IPH_TTL(iphdr); lns.ping_reply->len = p->tot_len - (IPH_HL(iphdr) * 4); lns.ping_reply->seqno = lns.ping_seq_num; vmm_completion_complete(&lns.ping_done); /* Free the pbuf */ pbuf_free(p); /* Eat the packet. lwIP should not process it. */ return 1; } } /* Don't eat the packet. Let lwIP process it. */ return 0; }
static void imx_rxint(struct imx_port *port) { port->mask &= ~UCR1_RRDYEN; vmm_writel(port->mask, (void *)port->base + UCR1); vmm_completion_complete(&port->read_possible); }
static void urb_request_complete(struct urb *u) { struct vmm_completion *uc = u->context; vmm_completion_complete(uc); }
/*-----------------------------------------------------------------------------------*/ void uip_arp_arpin(void) { if(uip_len < sizeof(struct arp_hdr)) { uip_len = 0; return; } uip_len = 0; switch(BUF->opcode) { case HTONS(ARP_HINT): /* Please note this is not a valid ARP type, this is just a * hint to implement prefetch/refresh of ARP mapping */ /* This is a valid hint if we are the source of this request, * the requested ipaddr is in dipaddress */ if(uip_ipaddr_cmp(BUF->sipaddr, uip_hostaddr)) { /* We first try to check for the destination address * in our ARP table */ if(uip_arp_update(BUF->dipaddr, &broadcast_ethaddr)) { /* If the destination address was not in our ARP table, * we send out an ARP request for the same */ memset(BUF->ethhdr.dest.addr, 0xff, 6); BUF->opcode = HTONS(ARP_REQUEST); /* The other ARP fields of incoming hint are * supposed to be same as ARP broadcast except * the opcode field */ uip_len = sizeof(struct arp_hdr); } } break; case HTONS(ARP_REQUEST): /* ARP request. If it asked for our address, we send out a reply. */ if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) { /* First, we register the one who made the request in our ARP table, since it is likely that we will do more communication with this host in the future. */ uip_arp_update(BUF->sipaddr, &BUF->shwaddr); BUF->opcode = HTONS(ARP_REPLY); memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6); memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6); memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6); memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6); BUF->dipaddr[0] = BUF->sipaddr[0]; BUF->dipaddr[1] = BUF->sipaddr[1]; BUF->sipaddr[0] = uip_hostaddr[0]; BUF->sipaddr[1] = uip_hostaddr[1]; BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP); uip_len = sizeof(struct arp_hdr); } break; case HTONS(ARP_REPLY): /* ARP reply. We insert or update the ARP table if it was meant for us. */ if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) { uip_arp_update(BUF->sipaddr, &BUF->shwaddr); vmm_completion_complete(&uip_arp_prefetch_done); } break; } return; }
/*-----------------------------------------------------------------------------------*/ static int uip_arp_update(u16 *ipaddr, const struct uip_eth_addr *ethaddr) { register struct arp_entry *tabptr; /* Walk through the ARP mapping table and try to find an entry to update. If none is found, the IP -> MAC address mapping is inserted in the ARP table. */ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { tabptr = &arp_table[i]; /* Only check those entries that are actually in use. */ if(tabptr->ipaddr[0] != 0 && tabptr->ipaddr[1] != 0) { /* Check if the source IP address of the incoming packet * matches the IP address in this ARP table entry. */ if(ipaddr[0] == tabptr->ipaddr[0] && ipaddr[1] == tabptr->ipaddr[1]) { /* If the ethaddr is not broadcast addr, we * update this old entry */ if(memcmp(ethaddr->addr, broadcast_ethaddr.addr, 6)) { memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); } else { /* Also notify anyone waiting for this arp_prefetch */ vmm_completion_complete(&uip_arp_prefetch_done); } tabptr->time = arptime; return 0; } } } /* If we get here, no existing ARP table entry was found */ /* If the ethaddr is broadcast address, we return with failure */ if(!memcmp(ethaddr->addr, broadcast_ethaddr.addr, 6)) { return 1; } /* Otherwise we create one mapping */ /* First, we try to find an unused entry in the ARP table. */ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { tabptr = &arp_table[i]; if(tabptr->ipaddr[0] == 0 && tabptr->ipaddr[1] == 0) { break; } } /* If no unused entry is found, we try to find the oldest entry and throw it away. */ if(i == UIP_ARPTAB_SIZE) { tmpage = 0; c = 0; for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { tabptr = &arp_table[i]; if(arptime - tabptr->time > tmpage) { tmpage = arptime - tabptr->time; c = i; } } i = c; tabptr = &arp_table[i]; } /* Now, i is the ARP table entry which we will fill with the new information. */ memcpy(tabptr->ipaddr, ipaddr, 4); memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); tabptr->time = arptime; return 0; }