コード例 #1
0
ファイル: netmap.c プロジェクト: 8tab/qemu
/* Complete a previous send (backend --> guest) and enable the
   fd_read callback. */
static void netmap_send_completed(NetClientState *nc, ssize_t len)
{
    NetmapState *s = DO_UPCAST(NetmapState, nc, nc);

    netmap_read_poll(s, true);
}
コード例 #2
0
/* Callback function that's called when the guest sends us data */
static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
{
	VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
	ssize_t ret;
	struct session_op sess;
	struct crypt_op crypt;
	uint32_t sess_id;
	struct crypto_data *cr_data = (struct crypto_data*)buf;

	if (!vcon->chr) {
	/* If there's no backend, we can just say we consumed all data. */
		return len;
	}


	switch (cr_data->cmd) {
	case CIOCGSESSION:

		sess = cr_data->op.sess;

		sess.key = cr_data->keyp;
		printf("cr_data->op.sess.ses: %u\n", cr_data->op.sess.ses);
		ret = ioctl(port->cr_info->cfd, CIOCGSESSION, &sess);

		if (ret) {
	                perror("ioctl(CIOCGSESSION)");
	                return 1;
		}

		cr_data->op.sess.ses = sess.ses;

		printf("1cr_data->op.sess.ses: %u\n", cr_data->op.sess.ses);
		virtio_serial_write(port, (const uint8_t *)cr_data , sizeof(struct crypto_data));
		
		break;

	case CIOCCRYPT:

		crypt = cr_data->op.crypt;
	
		crypt.src = cr_data->srcp;
		crypt.dst = cr_data->dstp;
		crypt.iv = cr_data->ivp;
		printf("cr_data->op.crypt.dstp[0]: %u\n", cr_data->dstp[0]);
		ret = ioctl(port->cr_info->cfd, CIOCCRYPT, &crypt);

		if (ret) {
	                perror("ioctl(CIOCCRYPT)");
	                return 1;

		}

		memcpy(cr_data->dstp, crypt.dst, crypt.len);

		printf("1cr_data->op.crypt.dstp[0]: %u\n", cr_data->dstp[0]);
		virtio_serial_write(port, (const uint8_t *)cr_data , sizeof(struct crypto_data));
		
		break;	

	case CIOCFSESSION:

		sess_id = cr_data->op.sess_id;
	
		printf("0cr_data->op.sess_id: %d\n", cr_data->op.sess_id);
		ret = ioctl(port->cr_info->cfd, CIOCFSESSION, &sess_id);

		if (ret) {
	                perror("ioctl(CIOCFSESSION)");
	                return 1;
		}

		cr_data->op.sess_id = sess_id;

		printf("1cr_data->op.sess_id: %d\n", cr_data->op.sess_id);
		virtio_serial_write(port, (const uint8_t *)cr_data , sizeof(struct crypto_data));

		break;

        default:
	 	qemu_chr_fe_write(vcon->chr, buf, len);
                return -EINVAL;
	}

	if (ret < 0) {
        /*
         * Ideally we'd get a better error code than just -1, but
         * that's what the chardev interface gives us right now.  If
         * we had a finer-grained message, like -EPIPE, we could close
         * this connection.  Absent such error messages, the most we
         * can do is to return 0 here.
         *
         * This will prevent stray -1 values to go to
         * virtio-serial-bus.c and cause abort()s in
         * do_flush_queued_data().
         */
		ret = 0;
	}

	return ret;
}
コード例 #3
0
ファイル: smc91c111.c プロジェクト: TheLoneRanger14/vmxray
static void smc91c111_cleanup(VLANClientState *nc)
{
    smc91c111_state *s = DO_UPCAST(NICState, nc, nc)->opaque;

    s->nic = NULL;
}
コード例 #4
0
ファイル: spapr_llan.c プロジェクト: ft-/ox820-qemu
static int spapr_vlan_can_receive(VLANClientState *nc)
{
    VIOsPAPRVLANDevice *dev = DO_UPCAST(NICState, nc, nc)->opaque;

    return (dev->isopen && dev->rx_bufs > 0);
}
コード例 #5
0
ファイル: scsi-generic.c プロジェクト: iazhuo/qemu
/* Return a pointer to the data buffer.  */
static uint8_t *scsi_get_buf(SCSIRequest *req)
{
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);

    return r->buf;
}
コード例 #6
0
ファイル: xen_pt.c プロジェクト: nshalman/qemu
static uint32_t xen_pt_pci_read_config(PCIDevice *d, uint32_t addr, int len)
{
    XenPCIPassthroughState *s = DO_UPCAST(XenPCIPassthroughState, dev, d);
    uint32_t val = 0;
    XenPTRegGroup *reg_grp_entry = NULL;
    XenPTReg *reg_entry = NULL;
    int rc = 0;
    int emul_len = 0;
    uint32_t find_addr = addr;

    if (xen_pt_pci_config_access_check(d, addr, len)) {
        goto exit;
    }

    /* find register group entry */
    reg_grp_entry = xen_pt_find_reg_grp(s, addr);
    if (reg_grp_entry) {
        /* check 0-Hardwired register group */
        if (reg_grp_entry->reg_grp->grp_type == XEN_PT_GRP_TYPE_HARDWIRED) {
            /* no need to emulate, just return 0 */
            val = 0;
            goto exit;
        }
    }

    /* read I/O device register value */
    rc = xen_host_pci_get_block(&s->real_device, addr, (uint8_t *)&val, len);
    if (rc < 0) {
        XEN_PT_ERR(d, "pci_read_block failed. return value: %d.\n", rc);
        memset(&val, 0xff, len);
    }

    /* just return the I/O device register value for
     * passthrough type register group */
    if (reg_grp_entry == NULL) {
        goto exit;
    }

    /* adjust the read value to appropriate CFC-CFF window */
    val <<= (addr & 3) << 3;
    emul_len = len;

    /* loop around the guest requested size */
    while (emul_len > 0) {
        /* find register entry to be emulated */
        reg_entry = xen_pt_find_reg(reg_grp_entry, find_addr);
        if (reg_entry) {
            XenPTRegInfo *reg = reg_entry->reg;
            uint32_t real_offset = reg_grp_entry->base_offset + reg->offset;
            uint32_t valid_mask = 0xFFFFFFFF >> ((4 - emul_len) << 3);
            uint8_t *ptr_val = NULL;

            valid_mask <<= (find_addr - real_offset) << 3;
            ptr_val = (uint8_t *)&val + (real_offset & 3);

            /* do emulation based on register size */
            switch (reg->size) {
            case 1:
                if (reg->u.b.read) {
                    rc = reg->u.b.read(s, reg_entry, ptr_val, valid_mask);
                }
                break;
            case 2:
                if (reg->u.w.read) {
                    rc = reg->u.w.read(s, reg_entry,
                                       (uint16_t *)ptr_val, valid_mask);
                }
                break;
            case 4:
                if (reg->u.dw.read) {
                    rc = reg->u.dw.read(s, reg_entry,
                                        (uint32_t *)ptr_val, valid_mask);
                }
                break;
            }

            if (rc < 0) {
                xen_shutdown_fatal_error("Internal error: Invalid read "
                                         "emulation. (%s, rc: %d)\n",
                                         __func__, rc);
                return 0;
            }

            /* calculate next address to find */
            emul_len -= reg->size;
            if (emul_len > 0) {
                find_addr = real_offset + reg->size;
            }
        } else {
            /* nothing to do with passthrough type register,
             * continue to find next byte */
            emul_len--;
            find_addr++;
        }
    }
コード例 #7
0
ファイル: esp.c プロジェクト: Blopeur/qemu-heca
static void sysbus_esp_hard_reset(DeviceState *dev)
{
    SysBusESPState *sysbus = DO_UPCAST(SysBusESPState, busdev.qdev, dev);
    esp_hard_reset(&sysbus->esp);
}
コード例 #8
0
ファイル: dp8393x.c プロジェクト: mithleshvrts/qemu-kvm-rhel6
static ssize_t nic_receive(VLANClientState *nc, const uint8_t * buf, size_t size)
{
    dp8393xState *s = DO_UPCAST(NICState, nc, nc)->opaque;
    uint16_t data[10];
    int packet_type;
    uint32_t available, address;
    int width, rx_len = size;
    uint32_t checksum;

    width = (s->regs[SONIC_DCR] & SONIC_DCR_DW) ? 2 : 1;

    s->regs[SONIC_RCR] &= ~(SONIC_RCR_PRX | SONIC_RCR_LBK | SONIC_RCR_FAER |
        SONIC_RCR_CRCR | SONIC_RCR_LPKT | SONIC_RCR_BC | SONIC_RCR_MC);

    packet_type = receive_filter(s, buf, size);
    if (packet_type < 0) {
        DPRINTF("packet not for netcard\n");
        return -1;
    }

    /* XXX: Check byte ordering */

    /* Check for EOL */
    if (s->regs[SONIC_LLFA] & 0x1) {
        /* Are we still in resource exhaustion? */
        size = sizeof(uint16_t) * 1 * width;
        address = ((s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA]) + sizeof(uint16_t) * 5 * width;
        s->memory_rw(s->mem_opaque, address, (uint8_t*)data, size, 0);
        if (data[0 * width] & 0x1) {
            /* Still EOL ; stop reception */
            return -1;
        } else {
            s->regs[SONIC_CRDA] = s->regs[SONIC_LLFA];
        }
    }

    /* Save current position */
    s->regs[SONIC_TRBA1] = s->regs[SONIC_CRBA1];
    s->regs[SONIC_TRBA0] = s->regs[SONIC_CRBA0];

    /* Calculate the ethernet checksum */
#ifdef SONIC_CALCULATE_RXCRC
    checksum = cpu_to_le32(crc32(0, buf, rx_len));
#else
    checksum = 0;
#endif

    /* Put packet into RBA */
    DPRINTF("Receive packet at %08x\n", (s->regs[SONIC_CRBA1] << 16) | s->regs[SONIC_CRBA0]);
    address = (s->regs[SONIC_CRBA1] << 16) | s->regs[SONIC_CRBA0];
    s->memory_rw(s->mem_opaque, address, (uint8_t*)buf, rx_len, 1);
    address += rx_len;
    s->memory_rw(s->mem_opaque, address, (uint8_t*)&checksum, 4, 1);
    rx_len += 4;
    s->regs[SONIC_CRBA1] = address >> 16;
    s->regs[SONIC_CRBA0] = address & 0xffff;
    available = (s->regs[SONIC_RBWC1] << 16) | s->regs[SONIC_RBWC0];
    available -= rx_len / 2;
    s->regs[SONIC_RBWC1] = available >> 16;
    s->regs[SONIC_RBWC0] = available & 0xffff;

    /* Update status */
    if (((s->regs[SONIC_RBWC1] << 16) | s->regs[SONIC_RBWC0]) < s->regs[SONIC_EOBC]) {
        s->regs[SONIC_RCR] |= SONIC_RCR_LPKT;
    }
    s->regs[SONIC_RCR] |= packet_type;
    s->regs[SONIC_RCR] |= SONIC_RCR_PRX;
    if (s->loopback_packet) {
        s->regs[SONIC_RCR] |= SONIC_RCR_LBK;
        s->loopback_packet = 0;
    }

    /* Write status to memory */
    DPRINTF("Write status at %08x\n", (s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA]);
    data[0 * width] = s->regs[SONIC_RCR]; /* status */
    data[1 * width] = rx_len; /* byte count */
    data[2 * width] = s->regs[SONIC_TRBA0]; /* pkt_ptr0 */
    data[3 * width] = s->regs[SONIC_TRBA1]; /* pkt_ptr1 */
    data[4 * width] = s->regs[SONIC_RSC]; /* seq_no */
    size = sizeof(uint16_t) * 5 * width;
    s->memory_rw(s->mem_opaque, (s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA], (uint8_t *)data, size, 1);

    /* Move to next descriptor */
    size = sizeof(uint16_t) * width;
    s->memory_rw(s->mem_opaque,
        ((s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA]) + sizeof(uint16_t) * 5 * width,
        (uint8_t *)data, size, 0);
    s->regs[SONIC_LLFA] = data[0 * width];
    if (s->regs[SONIC_LLFA] & 0x1) {
        /* EOL detected */
        s->regs[SONIC_ISR] |= SONIC_ISR_RDE;
    } else {
        data[0 * width] = 0; /* in_use */
        s->memory_rw(s->mem_opaque,
            ((s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA]) + sizeof(uint16_t) * 6 * width,
            (uint8_t *)data, size, 1);
        s->regs[SONIC_CRDA] = s->regs[SONIC_LLFA];
        s->regs[SONIC_ISR] |= SONIC_ISR_PKTRX;
        s->regs[SONIC_RSC] = (s->regs[SONIC_RSC] & 0xff00) | (((s->regs[SONIC_RSC] & 0x00ff) + 1) & 0x00ff);

        if (s->regs[SONIC_RCR] & SONIC_RCR_LPKT) {
            /* Read next RRA */
            do_read_rra(s);
        }
    }

    /* Done */
    dp8393x_update_irq(s);

    return size;
}
コード例 #9
0
ファイル: mc146818rtc.c プロジェクト: bboozzoo/qemu-power
void rtc_set_memory(ISADevice *dev, int addr, int val)
{
    RTCState *s = DO_UPCAST(RTCState, dev, dev);
    if (addr >= 0 && addr <= 127)
        s->cmos_data[addr] = val;
}
コード例 #10
0
ファイル: tap.c プロジェクト: emaste/qemu-devel-1.4.0
VHostNetState *tap_get_vhost_net(NetClientState *nc)
{
    TAPState *s = DO_UPCAST(TAPState, nc, nc);
    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP);
    return s->vhost_net;
}
コード例 #11
0
ファイル: xilinx_spi.c プロジェクト: cardoe/qemu
static void xlx_spi_reset(DeviceState *d)
{
    xlx_spi_do_reset(DO_UPCAST(XilinxSPI, busdev.qdev, d));
}
コード例 #12
0
ファイル: tap.c プロジェクト: emaste/qemu-devel-1.4.0
int tap_get_fd(NetClientState *nc)
{
    TAPState *s = DO_UPCAST(TAPState, nc, nc);
    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP);
    return s->fd;
}
コード例 #13
0
ファイル: tap.c プロジェクト: emaste/qemu-devel-1.4.0
static void tap_poll(NetClientState *nc, bool enable)
{
    TAPState *s = DO_UPCAST(TAPState, nc, nc);
    tap_read_poll(s, enable);
    tap_write_poll(s, enable);
}
コード例 #14
0
ファイル: tap.c プロジェクト: emaste/qemu-devel-1.4.0
static void tap_send_completed(NetClientState *nc, ssize_t len)
{
    TAPState *s = DO_UPCAST(TAPState, nc, nc);
    tap_read_poll(s, true);
}
コード例 #15
0
ファイル: vhost-user.c プロジェクト: Isaac-Lozano/qemu
VHostNetState *vhost_user_get_vhost_net(NetClientState *nc)
{
    VhostUserState *s = DO_UPCAST(VhostUserState, nc, nc);
    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
    return s->vhost_net;
}
コード例 #16
0
ファイル: mc146818rtc.c プロジェクト: bboozzoo/qemu-power
void rtc_set_date(ISADevice *dev, const struct tm *tm)
{
    RTCState *s = DO_UPCAST(RTCState, dev, dev);
    s->current_tm = *tm;
    rtc_copy_date(s);
}
コード例 #17
0
ファイル: vhost-user.c プロジェクト: Isaac-Lozano/qemu
uint64_t vhost_user_get_acked_features(NetClientState *nc)
{
    VhostUserState *s = DO_UPCAST(VhostUserState, nc, nc);
    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
    return s->acked_features;
}
コード例 #18
0
/* Callback function that's called when the guest sends us data */
static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
{
    VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);

    return qemu_chr_write(vcon->chr, buf, len);
}
コード例 #19
0
ファイル: xen_pt.c プロジェクト: nshalman/qemu
static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr,
                                    uint32_t val, int len)
{
    XenPCIPassthroughState *s = DO_UPCAST(XenPCIPassthroughState, dev, d);
    int index = 0;
    XenPTRegGroup *reg_grp_entry = NULL;
    int rc = 0;
    uint32_t read_val = 0;
    int emul_len = 0;
    XenPTReg *reg_entry = NULL;
    uint32_t find_addr = addr;
    XenPTRegInfo *reg = NULL;

    if (xen_pt_pci_config_access_check(d, addr, len)) {
        return;
    }

    XEN_PT_LOG_CONFIG(d, addr, val, len);

    /* check unused BAR register */
    index = xen_pt_bar_offset_to_index(addr);
    if ((index >= 0) && (val > 0 && val < XEN_PT_BAR_ALLF) &&
            (s->bases[index].bar_flag == XEN_PT_BAR_FLAG_UNUSED)) {
        XEN_PT_WARN(d, "Guest attempt to set address to unused Base Address "
                    "Register. (addr: 0x%02x, len: %d)\n", addr, len);
    }

    /* find register group entry */
    reg_grp_entry = xen_pt_find_reg_grp(s, addr);
    if (reg_grp_entry) {
        /* check 0-Hardwired register group */
        if (reg_grp_entry->reg_grp->grp_type == XEN_PT_GRP_TYPE_HARDWIRED) {
            /* ignore silently */
            XEN_PT_WARN(d, "Access to 0-Hardwired register. "
                        "(addr: 0x%02x, len: %d)\n", addr, len);
            return;
        }
    }

    rc = xen_host_pci_get_block(&s->real_device, addr,
                                (uint8_t *)&read_val, len);
    if (rc < 0) {
        XEN_PT_ERR(d, "pci_read_block failed. return value: %d.\n", rc);
        memset(&read_val, 0xff, len);
    }

    /* pass directly to the real device for passthrough type register group */
    if (reg_grp_entry == NULL) {
        goto out;
    }

    memory_region_transaction_begin();
    pci_default_write_config(d, addr, val, len);

    /* adjust the read and write value to appropriate CFC-CFF window */
    read_val <<= (addr & 3) << 3;
    val <<= (addr & 3) << 3;
    emul_len = len;

    /* loop around the guest requested size */
    while (emul_len > 0) {
        /* find register entry to be emulated */
        reg_entry = xen_pt_find_reg(reg_grp_entry, find_addr);
        if (reg_entry) {
            reg = reg_entry->reg;
            uint32_t real_offset = reg_grp_entry->base_offset + reg->offset;
            uint32_t valid_mask = 0xFFFFFFFF >> ((4 - emul_len) << 3);
            uint8_t *ptr_val = NULL;

            valid_mask <<= (find_addr - real_offset) << 3;
            ptr_val = (uint8_t *)&val + (real_offset & 3);

            /* do emulation based on register size */
            switch (reg->size) {
            case 1:
                if (reg->u.b.write) {
                    rc = reg->u.b.write(s, reg_entry, ptr_val,
                                        read_val >> ((real_offset & 3) << 3),
                                        valid_mask);
                }
                break;
            case 2:
                if (reg->u.w.write) {
                    rc = reg->u.w.write(s, reg_entry, (uint16_t *)ptr_val,
                                        (read_val >> ((real_offset & 3) << 3)),
                                        valid_mask);
                }
                break;
            case 4:
                if (reg->u.dw.write) {
                    rc = reg->u.dw.write(s, reg_entry, (uint32_t *)ptr_val,
                                         (read_val >> ((real_offset & 3) << 3)),
                                         valid_mask);
                }
                break;
            }
コード例 #20
0
/* Callback function that's called when the guest closes the port */
static void guest_close(VirtIOSerialPort *port)
{
    VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);

    qemu_chr_guest_close(vcon->chr);
}
コード例 #21
0
ファイル: fw_cfg.c プロジェクト: BernardXiong/qemu
static void fw_cfg_reset(DeviceState *d)
{
    FWCfgState *s = DO_UPCAST(FWCfgState, busdev.qdev, d);

    fw_cfg_select(s, 0);
}
コード例 #22
0
ファイル: tap-win32.c プロジェクト: AnselZhangGit/qemu_stm32
static ssize_t tap_receive(NetClientState *nc, const uint8_t *buf, size_t size)
{
    TAPState *s = DO_UPCAST(TAPState, nc, nc);

    return tap_win32_write(s->handle, buf, size);
}
コード例 #23
0
ファイル: spapr_llan.c プロジェクト: ft-/ox820-qemu
static ssize_t spapr_vlan_receive(VLANClientState *nc, const uint8_t *buf,
                                  size_t size)
{
    VIOsPAPRDevice *sdev = DO_UPCAST(NICState, nc, nc)->opaque;
    VIOsPAPRVLANDevice *dev = (VIOsPAPRVLANDevice *)sdev;
    vlan_bd_t rxq_bd = ldq_tce(sdev, dev->buf_list + VLAN_RXQ_BD_OFF);
    vlan_bd_t bd;
    int buf_ptr = dev->use_buf_ptr;
    uint64_t handle;
    uint8_t control;

    dprintf("spapr_vlan_receive() [%s] rx_bufs=%d\n", sdev->qdev.id,
            dev->rx_bufs);

    if (!dev->isopen) {
        return -1;
    }

    if (!dev->rx_bufs) {
        return -1;
    }

    do {
        buf_ptr += 8;
        if (buf_ptr >= SPAPR_VIO_TCE_PAGE_SIZE) {
            buf_ptr = VLAN_RX_BDS_OFF;
        }

        bd = ldq_tce(sdev, dev->buf_list + buf_ptr);
        dprintf("use_buf_ptr=%d bd=0x%016llx\n",
                buf_ptr, (unsigned long long)bd);
    } while ((!(bd & VLAN_BD_VALID) || (VLAN_BD_LEN(bd) < (size + 8)))
             && (buf_ptr != dev->use_buf_ptr));

    if (!(bd & VLAN_BD_VALID) || (VLAN_BD_LEN(bd) < (size + 8))) {
        /* Failed to find a suitable buffer */
        return -1;
    }

    /* Remove the buffer from the pool */
    dev->rx_bufs--;
    dev->use_buf_ptr = buf_ptr;
    stq_tce(sdev, dev->buf_list + dev->use_buf_ptr, 0);

    dprintf("Found buffer: ptr=%d num=%d\n", dev->use_buf_ptr, dev->rx_bufs);

    /* Transfer the packet data */
    if (spapr_tce_dma_write(sdev, VLAN_BD_ADDR(bd) + 8, buf, size) < 0) {
        return -1;
    }

    dprintf("spapr_vlan_receive: DMA write completed\n");

    /* Update the receive queue */
    control = VLAN_RXQC_TOGGLE | VLAN_RXQC_VALID;
    if (rxq_bd & VLAN_BD_TOGGLE) {
        control ^= VLAN_RXQC_TOGGLE;
    }

    handle = ldq_tce(sdev, VLAN_BD_ADDR(bd));
    stq_tce(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr + 8, handle);
    stw_tce(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr + 4, size);
    sth_tce(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr + 2, 8);
    stb_tce(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr, control);

    dprintf("wrote rxq entry (ptr=0x%llx): 0x%016llx 0x%016llx\n",
            (unsigned long long)dev->rxq_ptr,
            (unsigned long long)ldq_tce(sdev, VLAN_BD_ADDR(rxq_bd) +
                                        dev->rxq_ptr),
            (unsigned long long)ldq_tce(sdev, VLAN_BD_ADDR(rxq_bd) +
                                        dev->rxq_ptr + 8));

    dev->rxq_ptr += 16;
    if (dev->rxq_ptr >= VLAN_BD_LEN(rxq_bd)) {
        dev->rxq_ptr = 0;
        stq_tce(sdev, dev->buf_list + VLAN_RXQ_BD_OFF, rxq_bd ^ VLAN_BD_TOGGLE);
    }

    if (sdev->signal_state & 1) {
        qemu_irq_pulse(sdev->qirq);
    }

    return size;
}
コード例 #24
0
ファイル: qdev.c プロジェクト: AlexWWW/qemu-linaro-clone
int ide_get_bios_chs_trans(BusState *bus, int unit)
{
    return DO_UPCAST(IDEBus, qbus, bus)->ifs[unit].chs_trans;
}
コード例 #25
0
ファイル: scsi-generic.c プロジェクト: iazhuo/qemu
static void scsi_free_request(SCSIRequest *req)
{
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);

    g_free(r->buf);
}
コード例 #26
0
ファイル: lance.c プロジェクト: ft-/ox820-qemu
static void lance_reset(DeviceState *dev)
{
    SysBusPCNetState *d = DO_UPCAST(SysBusPCNetState, busdev.qdev, dev);

    pcnet_h_reset(&d->state);
}
コード例 #27
0
ファイル: smc91c111.c プロジェクト: TheLoneRanger14/vmxray
static ssize_t smc91c111_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
{
    smc91c111_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
    int status;
    int packetsize;
    uint32_t crc;
    int packetnum;
    uint8_t *p;

    if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST))
        return -1;
    /* Short packets are padded with zeros.  Receiving a packet
       < 64 bytes long is considered an error condition.  */
    if (size < 64)
        packetsize = 64;
    else
        packetsize = (size & ~1);
    packetsize += 6;
    crc = (s->rcr & RCR_STRIP_CRC) == 0;
    if (crc)
        packetsize += 4;
    /* TODO: Flag overrun and receive errors.  */
    if (packetsize > 2048)
        return -1;
    packetnum = smc91c111_allocate_packet(s);
    if (packetnum == 0x80)
        return -1;
    s->rx_fifo[s->rx_fifo_len++] = packetnum;

    p = &s->data[packetnum][0];
    /* ??? Multicast packets?  */
    status = 0;
    if (size > 1518)
        status |= RS_TOOLONG;
    if (size & 1)
        status |= RS_ODDFRAME;
    *(p++) = status & 0xff;
    *(p++) = status >> 8;
    *(p++) = packetsize & 0xff;
    *(p++) = packetsize >> 8;
    memcpy(p, buf, size & ~1);
    p += (size & ~1);
    /* Pad short packets.  */
    if (size < 64) {
        int pad;

        if (size & 1)
            *(p++) = buf[size - 1];
        pad = 64 - size;
        memset(p, 0, pad);
        p += pad;
        size = 64;
    }
    /* It's not clear if the CRC should go before or after the last byte in
       odd sized packets.  Linux disables the CRC, so that's no help.
       The pictures in the documentation show the CRC aligned on a 16-bit
       boundary before the last odd byte, so that's what we do.  */
    if (crc) {
        crc = crc32(~0, buf, size);
        *(p++) = crc & 0xff; crc >>= 8;
        *(p++) = crc & 0xff; crc >>= 8;
        *(p++) = crc & 0xff; crc >>= 8;
        *(p++) = crc & 0xff; crc >>= 8;
    }
    if (size & 1) {
        *(p++) = buf[size - 1];
        *(p++) = 0x60;
    } else {
        *(p++) = 0;
        *(p++) = 0x40;
    }
    /* TODO: Raise early RX interrupt?  */
    s->int_level |= INT_RCV;
    smc91c111_update(s);

    return size;
}
コード例 #28
0
ファイル: lance.c プロジェクト: ft-/ox820-qemu
static void lance_cleanup(VLANClientState *nc)
{
    PCNetState *d = DO_UPCAST(NICState, nc, nc)->opaque;

    pcnet_common_cleanup(d);
}
コード例 #29
0
ファイル: xilinx_ethlite.c プロジェクト: JonahAragon/qemu
static void eth_cleanup(NetClientState *nc)
{
    struct xlx_ethlite *s = DO_UPCAST(NICState, nc, nc)->opaque;

    s->nic = NULL;
}
コード例 #30
0
ファイル: netmap.c プロジェクト: 8tab/qemu
static ssize_t netmap_receive_iov(NetClientState *nc,
                    const struct iovec *iov, int iovcnt)
{
    NetmapState *s = DO_UPCAST(NetmapState, nc, nc);
    struct netmap_ring *ring = s->tx;
    uint32_t last;
    uint32_t idx;
    uint8_t *dst;
    int j;
    uint32_t i;

    if (unlikely(!ring)) {
        /* Drop the packet. */
        return iov_size(iov, iovcnt);
    }

    last = i = ring->cur;

    if (nm_ring_space(ring) < iovcnt) {
        /* Not enough netmap slots. */
        netmap_write_poll(s, true);
        return 0;
    }

    for (j = 0; j < iovcnt; j++) {
        int iov_frag_size = iov[j].iov_len;
        int offset = 0;
        int nm_frag_size;

        /* Split each iovec fragment over more netmap slots, if
           necessary. */
        while (iov_frag_size) {
            nm_frag_size = MIN(iov_frag_size, ring->nr_buf_size);

            if (unlikely(nm_ring_empty(ring))) {
                /* We run out of netmap slots while splitting the
                   iovec fragments. */
                netmap_write_poll(s, true);
                return 0;
            }

            idx = ring->slot[i].buf_idx;
            dst = (uint8_t *)NETMAP_BUF(ring, idx);

            ring->slot[i].len = nm_frag_size;
            ring->slot[i].flags = NS_MOREFRAG;
            pkt_copy(iov[j].iov_base + offset, dst, nm_frag_size);

            last = i;
            i = nm_ring_next(ring, i);

            offset += nm_frag_size;
            iov_frag_size -= nm_frag_size;
        }
    }
    /* The last slot must not have NS_MOREFRAG set. */
    ring->slot[last].flags &= ~NS_MOREFRAG;

    /* Now update ring->cur and ring->head. */
    ring->cur = ring->head = i;

    ioctl(s->nmd->fd, NIOCTXSYNC, NULL);

    return iov_size(iov, iovcnt);
}