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 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Copyright (c) 2014 by Delphix. All rights reserved.
29 */
30
31 /*
32 * Xen virtual device driver interfaces
33 */
34
35 /*
36 * todo:
37 * + name space clean up:
38 * xvdi_* - public xen interfaces, for use by all leaf drivers
39 * xd_* - public xen data structures
40 * i_xvdi_* - implementation private functions
41 * xendev_* - xendev driver interfaces, both internal and in cb_ops/bus_ops
42 * + add mdb dcmds to dump ring status
43 * + implement xvdi_xxx to wrap xenbus_xxx read/write function
44 * + convert (xendev_ring_t *) into xvdi_ring_handle_t
45 */
46 #include <sys/conf.h>
47 #include <sys/param.h>
48 #include <sys/kmem.h>
235 for (i = 0, xdcp = xdci; i < NXDC; i++, xdcp++)
236 if (xdcp->devclass == devclass)
237 return (xdcp);
238
239 return (NULL);
240 }
241
242 int
243 xvdi_init_dev(dev_info_t *dip)
244 {
245 xendev_devclass_t devcls;
246 int vdevnum;
247 domid_t domid;
248 struct xendev_ppd *pdp;
249 i_xd_cfg_t *xdcp;
250 boolean_t backend;
251 char xsnamebuf[TYPICALMAXPATHLEN];
252 char *xsname;
253 void *prop_str;
254 unsigned int prop_len;
255 char unitaddr[8];
256
257 devcls = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
258 DDI_PROP_DONTPASS, "devclass", XEN_INVAL);
259 vdevnum = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
260 DDI_PROP_DONTPASS, "vdev", VDEV_NOXS);
261 domid = (domid_t)ddi_prop_get_int(DDI_DEV_T_ANY, dip,
262 DDI_PROP_DONTPASS, "domain", DOMID_SELF);
263
264 backend = (domid != DOMID_SELF);
265 xdcp = i_xvdi_devclass2cfg(devcls);
266 if (xdcp->device_type != NULL)
267 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip,
268 "device_type", xdcp->device_type);
269
270 pdp = kmem_zalloc(sizeof (*pdp), KM_SLEEP);
271 pdp->xd_domain = domid;
272 pdp->xd_vdevnum = vdevnum;
273 pdp->xd_devclass = devcls;
274 pdp->xd_evtchn = INVALID_EVTCHN;
275 list_create(&pdp->xd_xb_watches, sizeof (xd_xb_watches_t),
316 pdp->xd_xsdev.nodename = i_ddi_strdup(xsname, KM_SLEEP);
317 pdp->xd_xsdev.devicetype = xdcp->xsdev;
318 pdp->xd_xsdev.frontend = (backend ? 0 : 1);
319 pdp->xd_xsdev.data = dip;
320 pdp->xd_xsdev.otherend_id = (backend ? domid : -1);
321 if (i_xvdi_add_watches(dip) != DDI_SUCCESS) {
322 cmn_err(CE_WARN, "xvdi_init_dev: "
323 "cannot add watches for %s", xsname);
324 xvdi_uninit_dev(dip);
325 return (DDI_FAILURE);
326 }
327
328 if (backend)
329 return (DDI_SUCCESS);
330
331 /*
332 * The unit-address for frontend devices is the name of the
333 * of the xenstore node containing the device configuration
334 * and is contained in the 'vdev' property.
335 * VIF devices are named using an incrementing integer.
336 * VBD devices are either named using the 16-bit dev_t value
337 * for linux 'hd' and 'xvd' devices, or a simple integer value
338 * in the range 0..767. 768 is the base value of the linux
339 * dev_t namespace, the dev_t value for 'hda'.
340 */
341 (void) snprintf(unitaddr, sizeof (unitaddr), "%d", vdevnum);
342 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, "unit-address",
343 unitaddr);
344
345 switch (devcls) {
346 case XEN_VNET:
347 if (xenbus_read(XBT_NULL, xsname, "mac", (void *)&prop_str,
348 &prop_len) != 0)
349 break;
350 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, "mac",
351 prop_str);
352 kmem_free(prop_str, prop_len);
353 break;
354 case XEN_VBLK:
355 /*
356 * cache a copy of the otherend name
|
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 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Copyright (c) 2014 by Delphix. All rights reserved.
29 * Copyright 2018 Nexenta Systems, Inc.
30 */
31
32 /*
33 * Xen virtual device driver interfaces
34 */
35
36 /*
37 * todo:
38 * + name space clean up:
39 * xvdi_* - public xen interfaces, for use by all leaf drivers
40 * xd_* - public xen data structures
41 * i_xvdi_* - implementation private functions
42 * xendev_* - xendev driver interfaces, both internal and in cb_ops/bus_ops
43 * + add mdb dcmds to dump ring status
44 * + implement xvdi_xxx to wrap xenbus_xxx read/write function
45 * + convert (xendev_ring_t *) into xvdi_ring_handle_t
46 */
47 #include <sys/conf.h>
48 #include <sys/param.h>
49 #include <sys/kmem.h>
236 for (i = 0, xdcp = xdci; i < NXDC; i++, xdcp++)
237 if (xdcp->devclass == devclass)
238 return (xdcp);
239
240 return (NULL);
241 }
242
243 int
244 xvdi_init_dev(dev_info_t *dip)
245 {
246 xendev_devclass_t devcls;
247 int vdevnum;
248 domid_t domid;
249 struct xendev_ppd *pdp;
250 i_xd_cfg_t *xdcp;
251 boolean_t backend;
252 char xsnamebuf[TYPICALMAXPATHLEN];
253 char *xsname;
254 void *prop_str;
255 unsigned int prop_len;
256 char unitaddr[16];
257
258 devcls = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
259 DDI_PROP_DONTPASS, "devclass", XEN_INVAL);
260 vdevnum = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
261 DDI_PROP_DONTPASS, "vdev", VDEV_NOXS);
262 domid = (domid_t)ddi_prop_get_int(DDI_DEV_T_ANY, dip,
263 DDI_PROP_DONTPASS, "domain", DOMID_SELF);
264
265 backend = (domid != DOMID_SELF);
266 xdcp = i_xvdi_devclass2cfg(devcls);
267 if (xdcp->device_type != NULL)
268 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip,
269 "device_type", xdcp->device_type);
270
271 pdp = kmem_zalloc(sizeof (*pdp), KM_SLEEP);
272 pdp->xd_domain = domid;
273 pdp->xd_vdevnum = vdevnum;
274 pdp->xd_devclass = devcls;
275 pdp->xd_evtchn = INVALID_EVTCHN;
276 list_create(&pdp->xd_xb_watches, sizeof (xd_xb_watches_t),
317 pdp->xd_xsdev.nodename = i_ddi_strdup(xsname, KM_SLEEP);
318 pdp->xd_xsdev.devicetype = xdcp->xsdev;
319 pdp->xd_xsdev.frontend = (backend ? 0 : 1);
320 pdp->xd_xsdev.data = dip;
321 pdp->xd_xsdev.otherend_id = (backend ? domid : -1);
322 if (i_xvdi_add_watches(dip) != DDI_SUCCESS) {
323 cmn_err(CE_WARN, "xvdi_init_dev: "
324 "cannot add watches for %s", xsname);
325 xvdi_uninit_dev(dip);
326 return (DDI_FAILURE);
327 }
328
329 if (backend)
330 return (DDI_SUCCESS);
331
332 /*
333 * The unit-address for frontend devices is the name of the
334 * of the xenstore node containing the device configuration
335 * and is contained in the 'vdev' property.
336 * VIF devices are named using an incrementing integer.
337 * VBD devices are either named using the 32-bit dev_t value
338 * for linux 'hd' and 'xvd' devices, or a simple integer value
339 * in the range 0..767. 768 is the base value of the linux
340 * dev_t namespace, the dev_t value for 'hda'.
341 */
342 (void) snprintf(unitaddr, sizeof (unitaddr), "%d", vdevnum);
343 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, "unit-address",
344 unitaddr);
345
346 switch (devcls) {
347 case XEN_VNET:
348 if (xenbus_read(XBT_NULL, xsname, "mac", (void *)&prop_str,
349 &prop_len) != 0)
350 break;
351 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, "mac",
352 prop_str);
353 kmem_free(prop_str, prop_len);
354 break;
355 case XEN_VBLK:
356 /*
357 * cache a copy of the otherend name
|