view cp/drivers/vdevice.c @ 618:535aec703236

cp: define a FIXME macro that leaves a sclp message There are far too many fixmes in the code. Sadly, the compiler simply discards them. This usually isn't an issue until one accidentally hits a "weird" bug which just turns out to be an unhandled (but documented) case in another part of the code. Using a macro instead of a comment will let the compiler string-ify the text, and then at runtime use SCLP to print it out. This will immediatelly point at problem areas. So, keep an eye on SCLP from now on :) Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Tue, 13 Dec 2011 22:20:50 -0500
parents 31525cf0c76b
children
line wrap: on
line source

/*
 * (C) Copyright 2007-2011  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
 *
 * This file is released under the GPLv2.  See the COPYING file for more
 * details.
 */

#include <slab.h>
#include <list.h>
#include <vcpu.h>
#include <vdevice.h>

static int __setup_vdev_ded(struct virt_sys *sys,
			    struct directory_vdev *dirdev,
			    struct virt_device *vdev)
{
	struct device *rdev;
	int ret;

	rdev = find_device_by_ccuu(dirdev->u.dedicate.rdev);
	if (IS_ERR(rdev))
		return PTR_ERR(rdev);

	mutex_lock(&rdev->lock);

	if (rdev->in_use) {
		ret = -EBUSY;
		goto out;
	}

	rdev->in_use = 1;

	vdev->u.dedicate.rdev = rdev;
	vdev->type = rdev->type;
	vdev->model = rdev->model;

	ret = 0;

out:
	mutex_unlock(&rdev->lock);
	return ret;
}

static LOCK_CLASS(vdev_lc);

/* assumes sys->virt_devs_lock is held */
int alloc_virt_dev(struct virt_sys *sys, struct directory_vdev *dirdev,
		   u32 sch)
{
	struct virt_device *vdev;
	int ret = 0;

	vdev = malloc(sizeof(struct virt_device), ZONE_NORMAL);
	if (!vdev)
		return -ENOMEM;

	mutex_init(&vdev->lock, &vdev_lc);

	vdev->vtype = dirdev->type;
	vdev->sch = sch;
	vdev->pmcw.v = 1;
	vdev->pmcw.dev_num = dirdev->vdev;
	vdev->pmcw.lpm = 0x80;
	vdev->pmcw.pim = 0x80;
	vdev->pmcw.pom = 0xff;
	vdev->pmcw.pam = 0x80;

	switch(dirdev->type) {
		case VDEV_CONS:
			/* CONS is really just a special case of SPOOL */
			vdev->u.spool.file = NULL;
			vdev->u.spool.ops = &spool_cons_ops;
			vdev->type = 0x3215;
			vdev->model = 0;
			break;
		case VDEV_SPOOL:
			vdev->u.spool.file = NULL;
			vdev->u.spool.ops = NULL;
			vdev->type = dirdev->u.spool.type;
			vdev->model = dirdev->u.spool.model;
			break;
		case VDEV_DED:
			ret = __setup_vdev_ded(sys, dirdev, vdev);
			break;
		case VDEV_MDISK:
			vdev->type = 0x3390;
			vdev->model = 3;
			FIXME("hook it up to mdisk driver");
			break;
		case VDEV_LINK:
		case VDEV_INVAL:
			ret = -EINVAL;
			break;
	}

	if (!ret)
		list_add_tail(&vdev->devices, &sys->virt_devs);
	else
		free(vdev);

	return ret;
}