void netfront_xmit(struct netfront_dev *dev, unsigned char* data,int len) { int flags; struct netif_tx_request *tx; RING_IDX i; int notify; unsigned short id; struct net_buffer* buf; void* page; #ifdef CONFIG_NETMAP if (dev->netmap) { netmap_netfront_xmit(dev->na, data, len); return; } #endif BUG_ON(len > PAGE_SIZE); down(&dev->tx_sem); local_irq_save(flags); id = get_id_from_freelist(dev->tx_freelist); local_irq_restore(flags); buf = &dev->tx_buffers[id]; page = buf->page; i = dev->tx.req_prod_pvt; tx = RING_GET_REQUEST(&dev->tx, i); memcpy(page,data,len); tx->gref = buf->gref; tx->offset=0; tx->size = len; tx->flags=0; tx->id = id; dev->tx.req_prod_pvt = i + 1; wmb(); RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&dev->tx, notify); if(notify) notify_remote_via_evtchn(dev->evtchn); local_irq_save(flags); network_tx_buf_gc(dev); local_irq_restore(flags); }
void netfront_select_handler(evtchn_port_t port, struct pt_regs *regs, void *data) { int flags; struct netfront_dev *dev = data; int fd = dev->fd; local_irq_save(flags); network_tx_buf_gc(dev); local_irq_restore(flags); if (fd != -1) files[fd].read = 1; wake_up(&netfront_queue); }
void netfront_xmit(struct netfront_dev *dev, unsigned char* data,int len) { int flags; struct netif_tx_request *tx; RING_IDX i; int notify; unsigned short id; struct net_buffer* buf; void* page; //printf("netfront_xmit\n"); //farewellkou BUG_ON(len > PAGE_SIZE); down(&dev->tx_sem); local_irq_save(flags); id = get_id_from_freelist(dev->tx_freelist); local_irq_restore(flags); buf = &dev->tx_buffers[id]; page = buf->page; if (!page) page = buf->page = (char*) alloc_page(); i = dev->tx.req_prod_pvt; tx = RING_GET_REQUEST(&dev->tx, i); memcpy(page,data,len); buf->gref = tx->gref = gnttab_grant_access(dev->dom,virt_to_mfn(page),1); tx->offset=0; tx->size = len; tx->flags=0; tx->id = id; dev->tx.req_prod_pvt = i + 1; wmb(); RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&dev->tx, notify); if(notify) notify_remote_via_evtchn(dev->evtchn); local_irq_save(flags); network_tx_buf_gc(dev); local_irq_restore(flags); }