4bac220845f606f60663ed6f3a2b88caa00ae87enarayan/*
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * CDDL HEADER START
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan *
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * The contents of this file are subject to the terms of the
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * Common Development and Distribution License (the "License").
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * You may not use this file except in compliance with the License.
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan *
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * or http://www.opensolaris.org/os/licensing.
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * See the License for the specific language governing permissions
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * and limitations under the License.
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan *
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * When distributing Covered Code, include this CDDL HEADER in each
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * If applicable, add the following below this CDDL HEADER, with the
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * fields enclosed by brackets "[]" replaced with your own identifying
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * information: Portions Copyright [yyyy] [name of copyright owner]
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan *
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * CDDL HEADER END
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan */
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan/*
66ea84940ca8687745ad2a165ef9bf49ec13996fVikram Hegde * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * Use is subject to license terms.
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan */
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan/*
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * Implements auxiliary routines declared in pcp_utils.h to facilitate
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * finding the appropriate communication transport & device path for a
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * given service. This supports the transition from the legacy service channel
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * transport (glvc) to the logical domain channel (vldc) transport native
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * to platforms running Logical Domains (LDoms).
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan */
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan#include <fcntl.h>
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan#include <sys/types.h>
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan#include <sys/stat.h>
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan#include <strings.h>
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan#include <stdlib.h>
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan#include <libgen.h>
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan#include <unistd.h>
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan#include <stdio.h>
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan#include <libdevinfo.h>
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan#include "pcp_utils.h"
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayantypedef enum { false = 0, true = 1 } bool_t;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan#define SERVICE_PREFIX "SUNW,sun4v-"
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan#define DEVICES_DIR "/devices"
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan#define GLVC ":glvc"
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan#define VCHAN "virtual-channel@"
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan#define VCHAN_C "virtual-channel-client@"
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan/*
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * The mechanism to relate a service to a device path is different for
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * vldc and glvc, due to the way the device pathnames are encoded:
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * Sample service: sunvts
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * Service Name: SUNW,sun4v-sunvts
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * GLVC device path:
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * "/devices/virtual-devices@100/sunvts@a:glvc"
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * VLDC device path:
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * "/devices/virtual-devices@100/channel-devices@200/virtual-channel@3:sunvts"
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan *
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * As VLDC is the communication mechanism used in an LDoms environment, it is
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * the preferred channel, and its existence is checked for first.
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan */
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan/*
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * Extract from dev_path the "service name" portion.
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * For vldc, the service corresponds to the minor name of the device path
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * (e.g. virtual-channel@3:sunvts for sunvts). If service is non-NULL, it must
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * match the extracted service name for the function to succeed.
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * The service name is returned in match (if non-NULL), and the function
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * itself returns true on success; false on failure.
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan */
4bac220845f606f60663ed6f3a2b88caa00ae87enarayanstatic bool_t
4bac220845f606f60663ed6f3a2b88caa00ae87enarayanget_vldc_svc_name(char *dev_path, char *service, char **match)
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan{
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan bool_t ret = false;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan char *pathname = strdup(dev_path);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan char *devname, *s;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if (NULL == pathname)
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan return (false);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan devname = basename(pathname);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan s = strrchr(devname, ':');
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if (s++ == NULL) {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan goto end;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan }
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if ((strncmp(devname, VCHAN, strlen(VCHAN)) == 0) ||
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan (strncmp(devname, VCHAN_C, strlen(VCHAN_C)) == 0)) {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan /*
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * If in addition, a service string is specified to
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * be matched, do a comparison
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan */
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if (service != NULL) {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if (strcmp(s, service) == 0) {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if (match)
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan *match = strdup(s);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan ret = true;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan goto end;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan } else {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan ret = false;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan goto end;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan }
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan } else if (match) {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan *match = strdup(s);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan }
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan ret = true;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan goto end;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan }
4bac220845f606f60663ed6f3a2b88caa00ae87enarayanend:
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan free(pathname);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan return (ret);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan}
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan/*
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * Extract from dev_path the "service name" portion.
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * For glvc, the service corresponds to the node name of the device path
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * (e.g. sunvts@a:glvc for sunvts). If service is non-NULL, it must
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * match the extracted service name for the function to succeed.
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * The service name is returned in match (if non-NULL), and the function
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * itself returns true on success; false on failure.
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan */
4bac220845f606f60663ed6f3a2b88caa00ae87enarayanstatic bool_t
4bac220845f606f60663ed6f3a2b88caa00ae87enarayanget_glvc_svc_name(char *dev_path, char *service, char **match)
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan{
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan bool_t ret = true;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan char *pathname = strdup(dev_path);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan char *devname, *substr, *t;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan int len;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if (NULL == pathname)
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan return (false);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan devname = basename(pathname);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan substr = strstr(devname, GLVC);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if (!((substr != NULL) && (strcmp(substr, GLVC) == 0))) {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan ret = false;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan goto end;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan }
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if ((t = strrchr(devname, '@')) == NULL) {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan ret = false;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan goto end;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan }
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan len = t - devname;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan /*
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * If a service string is specified, check if there
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * is a match
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan */
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if ((service != NULL) && (strncmp(devname, service, len) != 0))
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan ret = false;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if ((ret == true) && (match != NULL)) {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan *match = calloc(len + 1, 1);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if (*match)
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan (void) strncpy(*match, devname, len);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan }
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayanend:
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan free(pathname);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan return (ret);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan}
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan/*
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * This routine accepts either a prefixed service name or a legacy full
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * pathname (which might not even exist in the filesystem), and in either case
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * returns a canonical service name. If the parameter is neither a service
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * name (i.e. with a "SUNW,sun4v-" prefix), nor a path to a legacy glvc or
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * vldc device, NULL is returned.
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan */
4bac220845f606f60663ed6f3a2b88caa00ae87enarayanchar *
4bac220845f606f60663ed6f3a2b88caa00ae87enarayanplatsvc_extract_svc_name(char *devname)
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan{
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan char *sname = NULL;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan char *vldc_path, *glvc_path;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan /*
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * First check whether a service name
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan */
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if (strncmp(devname, SERVICE_PREFIX, strlen(SERVICE_PREFIX)) == 0) {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan sname = strdup(devname + strlen(SERVICE_PREFIX));
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan return (sname);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan }
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan /*
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * Not a service name, check if it's a valid pathname
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan */
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if (!(devname[0] == '/' || devname[0] == '.')) {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan return (NULL);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan }
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan /*
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * Ideally, we should only check for a valid glvc pathname,
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * requiring all vldc access to be only via service names. But
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * to prevent a flag day with code that's already passing in
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * vldc full pathnames (e.g. sunMC), we allow them here.
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan */
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if (get_vldc_svc_name(devname, NULL, &vldc_path) == true) {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan return (vldc_path);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan } else if (get_glvc_svc_name(devname, NULL, &glvc_path) == true) {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan return (glvc_path);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan }
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan return (NULL);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan}
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan/*
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * Walk all "service" device nodes to find the one with the
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * matching glvc minor name
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan */
4bac220845f606f60663ed6f3a2b88caa00ae87enarayanstatic char *
4bac220845f606f60663ed6f3a2b88caa00ae87enarayansvc_name_to_glvc_dev_path(char *service)
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan{
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan di_node_t root_node, service_node;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan char *glvc_path;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan char *minor_name;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan di_minor_t minor;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan char *dev_path = NULL;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if (service == NULL)
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan return (NULL);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
3af08d828975d7e2581b6829e0eecff14d87a483lm /* Ensure that the 'glvc' driver is loaded */
66ea84940ca8687745ad2a165ef9bf49ec13996fVikram Hegde root_node = di_init_driver("glvc", DINFOCPYALL);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if (root_node == DI_NODE_NIL) {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan return (dev_path);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan }
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan service_node = di_drv_first_node("glvc", root_node);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan while (service_node != DI_NODE_NIL) {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan /* Make sure node name matches service name */
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if (strcmp(service, di_node_name(service_node)) == 0) {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan /* Walk minor nodes */
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan minor = di_minor_next(service_node, DI_NODE_NIL);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan while (minor != DI_NODE_NIL) {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan glvc_path = di_devfs_minor_path(minor);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan minor_name = di_minor_name(minor);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if (strcmp(minor_name, "glvc") == 0) {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan dev_path = malloc(strlen(glvc_path) +
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan strlen(DEVICES_DIR) + 1);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan (void) strcpy(dev_path, DEVICES_DIR);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan (void) strcat(dev_path, glvc_path);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan di_devfs_path_free(glvc_path);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan break;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan }
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan di_devfs_path_free(glvc_path);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan minor = di_minor_next(service_node, minor);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan }
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan }
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if (dev_path != NULL)
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan break;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan service_node = di_drv_next_node(service_node);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan }
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan di_fini(root_node);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan return (dev_path);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan}
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan/*
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * Walk all vldc device nodes to find the one with the
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * matching minor name
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan */
4bac220845f606f60663ed6f3a2b88caa00ae87enarayanstatic char *
4bac220845f606f60663ed6f3a2b88caa00ae87enarayansvc_name_to_vldc_dev_path(char *service)
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan{
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan di_node_t root_node, vldc_node;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan char *vldc_path;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan char *minor_name;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan di_minor_t minor;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan char *dev_path = NULL;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
9404882939d18ddd3c94a5bd3da7a0449c195a5dranenc /* Ensure that the 'vldc' driver is loaded */
66ea84940ca8687745ad2a165ef9bf49ec13996fVikram Hegde root_node = di_init_driver("vldc", DINFOCPYALL);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if (root_node == DI_NODE_NIL) {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan return (dev_path);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan }
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan vldc_node = di_drv_first_node("vldc", root_node);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan while (vldc_node != DI_NODE_NIL) {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan /* Walk minor nodes */
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan minor = di_minor_next(vldc_node, DI_NODE_NIL);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan while (minor != DI_NODE_NIL) {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan vldc_path = di_devfs_minor_path(minor);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan minor_name = di_minor_name(minor);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if (strcmp(minor_name, service) == 0) {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan dev_path = malloc(strlen(vldc_path) +
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan strlen(DEVICES_DIR) + 1);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan (void) strcpy(dev_path, DEVICES_DIR);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan (void) strcat(dev_path, vldc_path);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan di_devfs_path_free(vldc_path);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan break;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan }
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan di_devfs_path_free(vldc_path);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan minor = di_minor_next(vldc_node, minor);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan }
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if (dev_path != NULL)
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan break;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan vldc_node = di_drv_next_node(vldc_node);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan }
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan di_fini(root_node);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan return (dev_path);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan}
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan/*
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * Given a service name or a full legacy pathname, return
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * the full pathname to the appropriate vldc or glvc device.
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan */
4bac220845f606f60663ed6f3a2b88caa00ae87enarayanchar *
4bac220845f606f60663ed6f3a2b88caa00ae87enarayanplatsvc_name_to_path(char *svc_or_path, pcp_xport_t *type)
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan{
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan char *pathn_p;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan char *service;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if ((service = platsvc_extract_svc_name(svc_or_path)) == NULL)
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan return (NULL);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan /*
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * First lookup vldc nodes
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan */
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan pathn_p = svc_name_to_vldc_dev_path(service);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if (pathn_p != NULL) {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan *type = VLDC_STREAMING;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan } else {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan /*
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan * If no vldc, try to find a glvc node
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan */
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan pathn_p = svc_name_to_glvc_dev_path(service);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan if (pathn_p != NULL) {
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan *type = GLVC_NON_STREAM;
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan }
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan }
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan free(service);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan return (pathn_p);
4bac220845f606f60663ed6f3a2b88caa00ae87enarayan}