1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27
28/*
29 * Xen network backend - ioemu version.
30 *
31 * HVM guest domains use an emulated network device (typically the
32 * rtl8139) to access the physical network via IO emulation running in
33 * a backend domain (generally domain 0).
34 *
35 * The IO emulation code sends and receives packets using DLPI, usually
36 * through a virtual NIC (vnic).
37 *
38 * The creation of the relevant vnic to correspond to the network interface
39 * in the guest domain requires the use of 'hotplug' scripts in the backend
40 * domain. This driver ensures that the hotplug scripts are run when
41 * such guest domains are created.
42 *
43 * It is used as a result of the 'compatible' property associated with
44 * IO emulated devices. See /etc/driver_aliases and common/xen/os/xvdi.c.
45 */
46
47#ifdef DEBUG
48#define	XNBE_DEBUG 1
49#endif /* DEBUG */
50
51#include <sys/types.h>
52#include <sys/conf.h>
53#include <sys/sunddi.h>
54#include <sys/modctl.h>
55#include <xen/sys/xendev.h>
56#ifdef XNBE_DEBUG
57#include <sys/cmn_err.h>
58#endif /* XNBE_DEBUG */
59
60#ifdef XNBE_DEBUG
61int xnbe_debug = 0;
62#endif /* XNBE_DEBUG */
63
64static int
65xnbe_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
66{
67#ifdef XNBE_DEBUG
68	if (xnbe_debug > 0)
69		cmn_err(CE_NOTE, "xnbe_attach: dip 0x%p, cmd %d",
70		    (void *)dip, cmd);
71#endif /* XNBE_DEBUG */
72
73	switch (cmd) {
74	case DDI_ATTACH:
75		break;
76	case DDI_RESUME:
77		return (DDI_SUCCESS);
78	default:
79		return (DDI_FAILURE);
80	}
81
82	(void) xvdi_post_event(dip, XEN_HP_ADD);
83
84	return (DDI_SUCCESS);
85}
86
87static int
88xnbe_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
89{
90#ifdef XNBE_DEBUG
91	if (xnbe_debug > 0)
92		cmn_err(CE_NOTE, "detach: dip 0x%p, cmd %d",
93		    (void *)dip, cmd);
94#endif /* XNBE_DEBUG */
95
96	switch (cmd) {
97	case DDI_DETACH:
98		return (DDI_SUCCESS);
99	case DDI_SUSPEND:
100		return (DDI_SUCCESS);
101	default:
102		return (DDI_FAILURE);
103	}
104}
105
106static struct cb_ops cb_ops = {
107	nulldev,		/* open */
108	nulldev,		/* close */
109	nodev,			/* strategy */
110	nodev,			/* print */
111	nodev,			/* dump */
112	nodev,			/* read */
113	nodev,			/* write */
114	nodev,			/* ioctl */
115	nodev,			/* devmap */
116	nodev,			/* mmap */
117	nodev,			/* segmap */
118	nochpoll,		/* poll */
119	ddi_prop_op,		/* cb_prop_op */
120	0,			/* streamtab  */
121	D_NEW | D_MP | D_64BIT	/* Driver compatibility flag */
122};
123
124static struct dev_ops ops = {
125	DEVO_REV,		/* devo_rev */
126	0,			/* devo_refcnt  */
127	nulldev,		/* devo_getinfo */
128	nulldev,		/* devo_identify */
129	nulldev,		/* devo_probe */
130	xnbe_attach,		/* devo_attach */
131	xnbe_detach,		/* devo_detach */
132	nodev,			/* devo_reset */
133	&cb_ops,		/* devo_cb_ops */
134	(struct bus_ops *)0,	/* devo_bus_ops */
135	NULL,			/* devo_power */
136	ddi_quiesce_not_needed,		/* devo_quiesce */
137};
138
139static struct modldrv modldrv = {
140	&mod_driverops, "xnbe driver", &ops,
141};
142
143static struct modlinkage modlinkage = {
144	MODREV_1, &modldrv, NULL
145};
146
147int
148_init(void)
149{
150	return (mod_install(&modlinkage));
151}
152
153int
154_info(struct modinfo *modinfop)
155{
156	return (mod_info(&modlinkage, modinfop));
157}
158
159int
160_fini(void)
161{
162	return (mod_remove(&modlinkage));
163}
164