Mercurial > hvf > hvf
view cp/guest/attach.c @ 653:0d289341e756
cp: maintain a circular buffer of Channel Report Words
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Thu, 29 Mar 2012 17:42:13 -0400 |
parents | dad0b2bc37c0 |
children |
line wrap: on
line source
/* * (C) Copyright 2007-2012 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> * * This file is released under the GPLv2. See the COPYING file for more * details. */ #include <circbuf.h> #include <vcpu.h> #include <guest.h> #include <sclp.h> static void guest_append_crw(struct virt_sys *sys, struct crw *crw) { insert_circbuf(&sys->crws, crw); } int guest_attach(struct virt_sys *sys, u64 rdev, u64 vdev) { struct directory_vdev dv = { .type = VDEV_DED, .vdev = vdev, .u.dedicate.rdev = rdev, }; struct virt_device *cur; struct crw crw; int found; int ret; u64 sch; mutex_lock(&sys->virt_devs_lock); /* are we supposed to pick a vdev number? */ if (vdev == -1) { /* TODO: this is a super-stupid algorithm - fix it */ for(vdev=0x0000; vdev<=0xffff; vdev++) { found = 0; list_for_each_entry(cur, &sys->virt_devs, devices) { if (cur->pmcw.dev_num == vdev) { found = 1; break; } } if (!found) break; } if (found) goto out_err; dv.vdev = vdev; } /* pick a subchannel number * TODO: this is a super-stupid algorithm - fix it */ for(sch=0x10000; sch<=0x1ffff; sch++) { found = 0; list_for_each_entry(cur, &sys->virt_devs, devices) { if (cur->sch == sch) { found = 1; break; } } if (!found) break; } if (found) goto out_err; memset(&crw, 0, sizeof(struct crw)); crw.rsc = 0x3; crw.erc = 0x4; crw.id = sch & ~0x10000; /* add the device */ ret = alloc_virt_dev(sys, &dv, sch); if (!ret) guest_append_crw(sys, &crw); mutex_unlock(&sys->virt_devs_lock); return ret; out_err: mutex_unlock(&sys->virt_devs_lock); return -EBUSY; }