1843e1988Sjohnlev /* 2843e1988Sjohnlev * CDDL HEADER START 3843e1988Sjohnlev * 4843e1988Sjohnlev * The contents of this file are subject to the terms of the 5843e1988Sjohnlev * Common Development and Distribution License (the "License"). 6843e1988Sjohnlev * You may not use this file except in compliance with the License. 7843e1988Sjohnlev * 8843e1988Sjohnlev * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9843e1988Sjohnlev * or http://www.opensolaris.org/os/licensing. 10843e1988Sjohnlev * See the License for the specific language governing permissions 11843e1988Sjohnlev * and limitations under the License. 12843e1988Sjohnlev * 13843e1988Sjohnlev * When distributing Covered Code, include this CDDL HEADER in each 14843e1988Sjohnlev * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15843e1988Sjohnlev * If applicable, add the following below this CDDL HEADER, with the 16843e1988Sjohnlev * fields enclosed by brackets "[]" replaced with your own identifying 17843e1988Sjohnlev * information: Portions Copyright [yyyy] [name of copyright owner] 18843e1988Sjohnlev * 19843e1988Sjohnlev * CDDL HEADER END 20843e1988Sjohnlev */ 21843e1988Sjohnlev 22843e1988Sjohnlev /* 23*7f0b8309SEdward Pilatowicz * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24843e1988Sjohnlev * Use is subject to license terms. 25843e1988Sjohnlev */ 26843e1988Sjohnlev 27843e1988Sjohnlev /* 28843e1988Sjohnlev * Talks to Xen Store to figure out what devices we have. 29843e1988Sjohnlev * 30843e1988Sjohnlev * Copyright (C) 2005 Rusty Russell, IBM Corporation 31843e1988Sjohnlev * Copyright (C) 2005 Mike Wray, Hewlett-Packard 32843e1988Sjohnlev * Copyright (C) 2005 XenSource Ltd 33843e1988Sjohnlev * 34843e1988Sjohnlev * This file may be distributed separately from the Linux kernel, or 35843e1988Sjohnlev * incorporated into other software packages, subject to the following license: 36843e1988Sjohnlev * 37843e1988Sjohnlev * Permission is hereby granted, free of charge, to any person obtaining a copy 38843e1988Sjohnlev * of this source file (the "Software"), to deal in the Software without 39843e1988Sjohnlev * restriction, including without limitation the rights to use, copy, modify, 40843e1988Sjohnlev * merge, publish, distribute, sublicense, and/or sell copies of the Software, 41843e1988Sjohnlev * and to permit persons to whom the Software is furnished to do so, subject to 42843e1988Sjohnlev * the following conditions: 43843e1988Sjohnlev * 44843e1988Sjohnlev * The above copyright notice and this permission notice shall be included in 45843e1988Sjohnlev * all copies or substantial portions of the Software. 46843e1988Sjohnlev * 47843e1988Sjohnlev * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 48843e1988Sjohnlev * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 49843e1988Sjohnlev * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 50843e1988Sjohnlev * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 51843e1988Sjohnlev * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 52843e1988Sjohnlev * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 53843e1988Sjohnlev * IN THE SOFTWARE. 54843e1988Sjohnlev */ 55843e1988Sjohnlev 56551bc2a6Smrj #ifdef XPV_HVM_DRIVER 57551bc2a6Smrj #include <sys/xpv_support.h> 58551bc2a6Smrj #endif 59843e1988Sjohnlev #include <sys/hypervisor.h> 60843e1988Sjohnlev #include <xen/sys/xenbus_impl.h> 61843e1988Sjohnlev #include <xen/sys/xenbus_comms.h> 62843e1988Sjohnlev #include <xen/public/io/xs_wire.h> 63843e1988Sjohnlev 64843e1988Sjohnlev static int 65843e1988Sjohnlev read_otherend_details(struct xenbus_device *xendev, 66843e1988Sjohnlev char *id_node, char *path_node) 67843e1988Sjohnlev { 68843e1988Sjohnlev int err = xenbus_gather(XBT_NULL, xendev->nodename, 69843e1988Sjohnlev id_node, "%i", &xendev->otherend_id, path_node, NULL, 70843e1988Sjohnlev &xendev->otherend, NULL); 71843e1988Sjohnlev if (err) { 72843e1988Sjohnlev xenbus_dev_fatal(xendev, err, 73843e1988Sjohnlev "reading other end details from %s", xendev->nodename); 74843e1988Sjohnlev return (err); 75843e1988Sjohnlev } 76843e1988Sjohnlev if (strlen(xendev->otherend) == 0 || 77*7f0b8309SEdward Pilatowicz !xenbus_exists_dir(xendev->otherend, "")) { 78843e1988Sjohnlev xenbus_dev_fatal(xendev, X_ENOENT, "missing other end from %s", 79843e1988Sjohnlev xendev->nodename); 80843e1988Sjohnlev kmem_free((void *)xendev->otherend, 81843e1988Sjohnlev strlen(xendev->otherend) + 1); 82843e1988Sjohnlev xendev->otherend = NULL; 83843e1988Sjohnlev return (X_ENOENT); 84843e1988Sjohnlev } 85843e1988Sjohnlev 86843e1988Sjohnlev return (0); 87843e1988Sjohnlev } 88843e1988Sjohnlev 89843e1988Sjohnlev 90843e1988Sjohnlev static int 91843e1988Sjohnlev read_backend_details(struct xenbus_device *xendev) 92843e1988Sjohnlev { 93843e1988Sjohnlev return (read_otherend_details(xendev, "backend-id", "backend")); 94843e1988Sjohnlev } 95843e1988Sjohnlev 96843e1988Sjohnlev 97843e1988Sjohnlev static int 98843e1988Sjohnlev read_frontend_details(struct xenbus_device *xendev) 99843e1988Sjohnlev { 100843e1988Sjohnlev return (read_otherend_details(xendev, "frontend-id", "frontend")); 101843e1988Sjohnlev } 102843e1988Sjohnlev 103843e1988Sjohnlev 104843e1988Sjohnlev static void 105843e1988Sjohnlev free_otherend_details(struct xenbus_device *dev) 106843e1988Sjohnlev { 107843e1988Sjohnlev if (dev->otherend != NULL) { 108843e1988Sjohnlev kmem_free((void *)dev->otherend, strlen(dev->otherend) + 1); 109843e1988Sjohnlev dev->otherend = NULL; 110843e1988Sjohnlev } 111843e1988Sjohnlev } 112843e1988Sjohnlev 113843e1988Sjohnlev 114843e1988Sjohnlev static void 115843e1988Sjohnlev free_otherend_watch(struct xenbus_device *dev) 116843e1988Sjohnlev { 117843e1988Sjohnlev if (dev->otherend_watch.node) { 118843e1988Sjohnlev unregister_xenbus_watch(&dev->otherend_watch); 119843e1988Sjohnlev kmem_free((void *)dev->otherend_watch.node, 120843e1988Sjohnlev strlen(dev->otherend_watch.node) + 1); 121843e1988Sjohnlev dev->otherend_watch.node = NULL; 122843e1988Sjohnlev } 123843e1988Sjohnlev } 124843e1988Sjohnlev 125843e1988Sjohnlev 126843e1988Sjohnlev /*ARGSUSED2*/ 127843e1988Sjohnlev static void 128843e1988Sjohnlev otherend_changed(struct xenbus_watch *watch, const char **vec, unsigned int len) 129843e1988Sjohnlev { 130843e1988Sjohnlev struct xenbus_device *dev = watch->dev; 131843e1988Sjohnlev XenbusState state; 132843e1988Sjohnlev 133843e1988Sjohnlev /* 134843e1988Sjohnlev * Protect us against watches firing on old details when the otherend 135843e1988Sjohnlev * details change, say immediately after a resume. 136843e1988Sjohnlev */ 137843e1988Sjohnlev if (!dev->otherend || 138843e1988Sjohnlev strncmp(dev->otherend, vec[XS_WATCH_PATH], strlen(dev->otherend))) { 139843e1988Sjohnlev #if 0 140843e1988Sjohnlev printf("Ignoring watch at %s", vec[XS_WATCH_PATH]); 141843e1988Sjohnlev #endif 142843e1988Sjohnlev return; 143843e1988Sjohnlev } 144843e1988Sjohnlev 145843e1988Sjohnlev state = xenbus_read_driver_state(dev->otherend); 146843e1988Sjohnlev 147843e1988Sjohnlev #if 0 148843e1988Sjohnlev printf("state is %d, %s, %s", 149843e1988Sjohnlev state, dev->otherend_watch.node, vec[XS_WATCH_PATH]); 150843e1988Sjohnlev #endif 151843e1988Sjohnlev if (dev->otherend_changed) 152843e1988Sjohnlev dev->otherend_changed(dev, state); 153843e1988Sjohnlev } 154843e1988Sjohnlev 155843e1988Sjohnlev 156843e1988Sjohnlev int 157843e1988Sjohnlev talk_to_otherend(struct xenbus_device *dev) 158843e1988Sjohnlev { 159843e1988Sjohnlev int err; 160843e1988Sjohnlev 161843e1988Sjohnlev free_otherend_watch(dev); 162843e1988Sjohnlev free_otherend_details(dev); 163843e1988Sjohnlev 164843e1988Sjohnlev if (dev->frontend) 165843e1988Sjohnlev err = read_backend_details(dev); 166843e1988Sjohnlev else 167843e1988Sjohnlev err = read_frontend_details(dev); 168843e1988Sjohnlev if (err) 169843e1988Sjohnlev return (err); 170843e1988Sjohnlev 171843e1988Sjohnlev dev->otherend_watch.dev = dev; 172843e1988Sjohnlev return (xenbus_watch_path2(dev, dev->otherend, "state", 173843e1988Sjohnlev &dev->otherend_watch, otherend_changed)); 174843e1988Sjohnlev } 175843e1988Sjohnlev 176843e1988Sjohnlev 177843e1988Sjohnlev /* 178843e1988Sjohnlev * Local variables: 179843e1988Sjohnlev * c-file-style: "solaris" 180843e1988Sjohnlev * indent-tabs-mode: t 181843e1988Sjohnlev * c-indent-level: 8 182843e1988Sjohnlev * c-basic-offset: 8 183843e1988Sjohnlev * tab-width: 8 184843e1988Sjohnlev * End: 185843e1988Sjohnlev */ 186