15084Sjohnlev /*
25084Sjohnlev * CDDL HEADER START
35084Sjohnlev *
45084Sjohnlev * The contents of this file are subject to the terms of the
55084Sjohnlev * Common Development and Distribution License (the "License").
65084Sjohnlev * You may not use this file except in compliance with the License.
75084Sjohnlev *
85084Sjohnlev * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95084Sjohnlev * or http://www.opensolaris.org/os/licensing.
105084Sjohnlev * See the License for the specific language governing permissions
115084Sjohnlev * and limitations under the License.
125084Sjohnlev *
135084Sjohnlev * When distributing Covered Code, include this CDDL HEADER in each
145084Sjohnlev * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155084Sjohnlev * If applicable, add the following below this CDDL HEADER, with the
165084Sjohnlev * fields enclosed by brackets "[]" replaced with your own identifying
175084Sjohnlev * information: Portions Copyright [yyyy] [name of copyright owner]
185084Sjohnlev *
195084Sjohnlev * CDDL HEADER END
205084Sjohnlev */
215084Sjohnlev
225084Sjohnlev /*
23*7862SRichard.Bean@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
245084Sjohnlev * Use is subject to license terms.
255084Sjohnlev */
265084Sjohnlev
275084Sjohnlev #include <sys/types.h>
285084Sjohnlev #include <sys/hypervisor.h>
295084Sjohnlev #include <sys/sunndi.h>
305084Sjohnlev #include <sys/sunddi.h>
315084Sjohnlev #include <sys/ddi_subrdefs.h>
325084Sjohnlev #include <sys/bootconf.h>
335084Sjohnlev #include <sys/psw.h>
345084Sjohnlev #include <sys/modctl.h>
355084Sjohnlev #include <sys/errno.h>
365084Sjohnlev #include <sys/reboot.h>
375084Sjohnlev #include <sys/hypervisor.h>
385084Sjohnlev #include <xen/sys/xenbus_comms.h>
395084Sjohnlev #include <xen/sys/xenbus_impl.h>
405084Sjohnlev #include <xen/sys/xendev.h>
415084Sjohnlev
425084Sjohnlev extern int xen_boot_debug;
435084Sjohnlev
445084Sjohnlev /*
455084Sjohnlev * Internal structures and functions
465084Sjohnlev */
475084Sjohnlev int xendev_nounload = 0;
485084Sjohnlev void xendev_enumerate(int);
495084Sjohnlev
505084Sjohnlev /*
515084Sjohnlev * Interface routines
525084Sjohnlev */
535084Sjohnlev
545084Sjohnlev static struct modlmisc modlmisc = {
55*7862SRichard.Bean@Sun.COM &mod_miscops, "virtual device probe"
565084Sjohnlev };
575084Sjohnlev
585084Sjohnlev static struct modlinkage modlinkage = {
595084Sjohnlev MODREV_1, (void *)&modlmisc, NULL
605084Sjohnlev };
615084Sjohnlev
625084Sjohnlev int
_init(void)635084Sjohnlev _init(void)
645084Sjohnlev {
655084Sjohnlev int err;
665084Sjohnlev
675084Sjohnlev if ((err = mod_install(&modlinkage)) != 0)
685084Sjohnlev return (err);
695084Sjohnlev
705084Sjohnlev impl_bus_add_probe(xendev_enumerate);
715084Sjohnlev return (0);
725084Sjohnlev }
735084Sjohnlev
745084Sjohnlev int
_fini(void)755084Sjohnlev _fini(void)
765084Sjohnlev {
775084Sjohnlev int err;
785084Sjohnlev
795084Sjohnlev if (xendev_nounload)
805084Sjohnlev return (EBUSY);
815084Sjohnlev
825084Sjohnlev if ((err = mod_remove(&modlinkage)) != 0)
835084Sjohnlev return (err);
845084Sjohnlev
855084Sjohnlev impl_bus_delete_probe(xendev_enumerate);
865084Sjohnlev return (0);
875084Sjohnlev }
885084Sjohnlev
895084Sjohnlev int
_info(struct modinfo * modinfop)905084Sjohnlev _info(struct modinfo *modinfop)
915084Sjohnlev {
925084Sjohnlev return (mod_info(&modlinkage, modinfop));
935084Sjohnlev }
945084Sjohnlev
955084Sjohnlev
965084Sjohnlev /*
975084Sjohnlev * This functions is invoked twice, first time with reprogram=0 to
985084Sjohnlev * set up the xpvd portion of the device tree. The second time is
995084Sjohnlev * ignored.
1005084Sjohnlev */
1015084Sjohnlev void
xendev_enumerate(int reprogram)1025084Sjohnlev xendev_enumerate(int reprogram)
1035084Sjohnlev {
1045084Sjohnlev dev_info_t *dip;
1055084Sjohnlev
1065084Sjohnlev if (reprogram != 0)
1075084Sjohnlev return;
1085084Sjohnlev
1095084Sjohnlev ndi_devi_alloc_sleep(ddi_root_node(), "xpvd",
1105084Sjohnlev (pnode_t)DEVI_SID_NODEID, &dip);
1115084Sjohnlev
1125084Sjohnlev (void) ndi_devi_bind_driver(dip, 0);
1135084Sjohnlev
1145084Sjohnlev /*
1155084Sjohnlev * Too early to enumerate split device drivers in domU
1165084Sjohnlev * since we need to create taskq thread during enumeration.
1175084Sjohnlev * So, we only enumerate softdevs and console here.
1185084Sjohnlev */
1195084Sjohnlev xendev_enum_all(dip, B_TRUE);
1205084Sjohnlev }
121