Beispiel #1
0
static void
virtio_net_config(ether_addr_t * addr)
{
	u32_t mac14;
	u32_t mac56;
	int i;

	if (virtio_host_supports(net_dev, VIRTIO_NET_F_MAC)) {
		dprintf(("Mac set by host: "));
		mac14 = virtio_sread32(net_dev, 0);
		mac56 = virtio_sread32(net_dev, 4);
		memcpy(&addr->ea_addr[0], &mac14, 4);
		memcpy(&addr->ea_addr[4], &mac56, 2);

		for (i = 0; i < 6; i++)
			dprintf(("%02x%s", addr->ea_addr[i],
					 i == 5 ? "\n" : ":"));
	} else {
		dput(("No mac"));
	}

	if (virtio_host_supports(net_dev, VIRTIO_NET_F_STATUS)) {
		dput(("Current Status %x", (u32_t)virtio_sread16(net_dev, 6)));
	} else {
		dput(("No status"));
	}

	if (virtio_host_supports(net_dev, VIRTIO_NET_F_CTRL_VQ))
		dput(("Host supports control channel"));

	if (virtio_host_supports(net_dev, VIRTIO_NET_F_CTRL_RX))
		dput(("Host supports control channel for RX"));
}
Beispiel #2
0
static int
virtio_net_config(void)
{
	u32_t mac14;
	u32_t mac56;
	int i;

	if (virtio_host_supports(net_dev, VIRTIO_NET_F_MAC)) {
		dprintf(("Mac set by host: "));
		mac14 = virtio_sread32(net_dev, 0);
		mac56 = virtio_sread32(net_dev, 4);
		*(u32_t*)virtio_net_mac = mac14;
		*(u16_t*)(virtio_net_mac + 4) = mac56;

		for (i = 0; i < 6; i++)
			printf("%02x%s", virtio_net_mac[i],
					 i == 5 ? "\n" : ":");
	} else {
		dput(("No mac"));
	}

	if (virtio_host_supports(net_dev, VIRTIO_NET_F_STATUS)) {
		dput(("Current Status %x", (u32_t)virtio_sread16(net_dev, 6)));
	} else {
		dput(("No status"));
	}

	if (virtio_host_supports(net_dev, VIRTIO_NET_F_CTRL_VQ))
		dput(("Host supports control channel"));

	if (virtio_host_supports(net_dev, VIRTIO_NET_F_CTRL_RX))
		dput(("Host supports control channel for RX"));

	return OK;
}
Beispiel #3
0
static int
virtio_blk_open(dev_t minor, int access)
{
	struct device *dev = virtio_blk_part(minor);

	/* Check if this device exists */
	if (!dev)
		return ENXIO;

	/* Read only devices should only be mounted... read-only */
	if ((access & W_BIT) && virtio_host_supports(blk_dev, VIRTIO_BLK_F_RO))
		return EACCES;

	/* Partition magic when opened the first time or re-opened after
	 * being fully closed
	 */
	if (open_count == 0) {
		memset(part, 0, sizeof(part));
		memset(subpart, 0, sizeof(subpart));
		part[0].dv_size = blk_config.capacity * VIRTIO_BLK_BLOCK_SIZE;
		partition(&virtio_blk_dtab, 0, P_PRIMARY, 0 /* ATAPI */);
		blockdriver_mt_set_workers(0, VIRTIO_BLK_NUM_THREADS);
	}

	open_count++;
	return OK;
}
Beispiel #4
0
static int
virtio_blk_flush(void)
{
	struct vumap_phys phys[2];
	size_t phys_cnt = sizeof(phys) / sizeof(phys[0]);

	/* Which thread is doing this request? */
	thread_id_t tid = blockdriver_mt_get_tid();

	/* Host may not support flushing */
	if (!virtio_host_supports(blk_dev, VIRTIO_BLK_F_FLUSH))
		return EOPNOTSUPP;

	/* Prepare the header */
	memset(&hdrs_vir[tid], 0, sizeof(hdrs_vir[0]));
	hdrs_vir[tid].type = VIRTIO_BLK_T_FLUSH;

	/* Let this be a barrier if the host supports it */
	if (virtio_host_supports(blk_dev, VIRTIO_BLK_F_BARRIER))
		hdrs_vir[tid].type |= VIRTIO_BLK_T_BARRIER;

	/* Header and status for the queue */
	phys[0].vp_addr = hdrs_phys + tid * sizeof(hdrs_vir[0]);
	phys[0].vp_size = sizeof(hdrs_vir[0]);
	phys[1].vp_addr = status_phys + tid * sizeof(status_vir[0]);
	phys[1].vp_size = 1;

	/* Status always needs write access */
	phys[1].vp_addr |= 1;

	/* Send flush request to queue */
	virtio_to_queue(blk_dev, 0, phys, phys_cnt, &tid);

	blockdriver_mt_sleep();

	/* All was good */
	if (mystatus(tid) == VIRTIO_BLK_S_OK)
		return OK;

	/* Error path */
	dprintf(("ERROR status=%02x op=flush t=%d", mystatus(tid), tid));

	return virtio_blk_status2error(mystatus(tid));
}
Beispiel #5
0
static void
virtio_blk_geometry(dev_t minor, struct partition *entry)
{
	/* Only for the drive */
	if (minor != 0)
		return;

	/* Only if the host supports it */
	if(!virtio_host_supports(blk_dev, VIRTIO_BLK_F_GEOMETRY))
		return;

	entry->cylinders = blk_config.geometry.cylinders;
	entry->heads = blk_config.geometry.heads;
	entry->sectors = blk_config.geometry.sectors;
}
Beispiel #6
0
static int
virtio_net_probe(unsigned int skip)
{
	/* virtio-net has at least 2 queues */
	int queues = 2;
	net_dev= virtio_setup_device(0x00001, name, netf,
				     sizeof(netf) / sizeof(netf[0]),
				     1 /* threads */, skip);
	if (net_dev == NULL)
		return ENXIO;

	/* If the host supports the control queue, allocate it as well */
	if (virtio_host_supports(net_dev, VIRTIO_NET_F_CTRL_VQ))
		queues += 1;

	if (virtio_alloc_queues(net_dev, queues) != OK) {
		virtio_free_device(net_dev);
		return ENOMEM;
	}

	return OK;
}
Beispiel #7
0
static int
virtio_blk_feature_setup(void)
{
	/* Feature setup for virtio-blk
	 *
	 * FIXME: Besides the geometry, everything is just debug output
	 * FIXME2: magic numbers
	 */
	if (virtio_host_supports(blk_dev, VIRTIO_BLK_F_SEG_MAX)) {
		blk_config.seg_max = virtio_sread32(blk_dev, 12);
		dprintf(("Seg Max: %d", blk_config.seg_max));
	}

	if (virtio_host_supports(blk_dev, VIRTIO_BLK_F_GEOMETRY)) {
		blk_config.geometry.cylinders = virtio_sread16(blk_dev, 16);
		blk_config.geometry.heads = virtio_sread8(blk_dev, 18);
		blk_config.geometry.sectors = virtio_sread8(blk_dev, 19);

		dprintf(("Geometry: cyl=%d heads=%d sectors=%d",
					blk_config.geometry.cylinders,
					blk_config.geometry.heads,
					blk_config.geometry.sectors));
	}

	if (virtio_host_supports(blk_dev, VIRTIO_BLK_F_SIZE_MAX))
		dprintf(("Has size max"));

	if (virtio_host_supports(blk_dev, VIRTIO_BLK_F_FLUSH))
		dprintf(("Supports flushing"));

	if (virtio_host_supports(blk_dev, VIRTIO_BLK_F_BLK_SIZE)) {
		blk_config.blk_size = virtio_sread32(blk_dev, 20);
		dprintf(("Block Size: %d", blk_config.blk_size));
	}

	if (virtio_host_supports(blk_dev, VIRTIO_BLK_F_BARRIER))
		dprintf(("Supports barrier"));

	return 0;
}