70025d765b044c6d8594bb965a2247a61e991a99johnny/*
70025d765b044c6d8594bb965a2247a61e991a99johnny * CDDL HEADER START
70025d765b044c6d8594bb965a2247a61e991a99johnny *
70025d765b044c6d8594bb965a2247a61e991a99johnny * The contents of this file are subject to the terms of the
70025d765b044c6d8594bb965a2247a61e991a99johnny * Common Development and Distribution License, Version 1.0 only
70025d765b044c6d8594bb965a2247a61e991a99johnny * (the "License"). You may not use this file except in compliance
70025d765b044c6d8594bb965a2247a61e991a99johnny * with the License.
70025d765b044c6d8594bb965a2247a61e991a99johnny *
70025d765b044c6d8594bb965a2247a61e991a99johnny * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
70025d765b044c6d8594bb965a2247a61e991a99johnny * or http://www.opensolaris.org/os/licensing.
70025d765b044c6d8594bb965a2247a61e991a99johnny * See the License for the specific language governing permissions
70025d765b044c6d8594bb965a2247a61e991a99johnny * and limitations under the License.
70025d765b044c6d8594bb965a2247a61e991a99johnny *
70025d765b044c6d8594bb965a2247a61e991a99johnny * When distributing Covered Code, include this CDDL HEADER in each
70025d765b044c6d8594bb965a2247a61e991a99johnny * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
70025d765b044c6d8594bb965a2247a61e991a99johnny * If applicable, add the following below this CDDL HEADER, with the
70025d765b044c6d8594bb965a2247a61e991a99johnny * fields enclosed by brackets "[]" replaced with your own identifying
70025d765b044c6d8594bb965a2247a61e991a99johnny * information: Portions Copyright [yyyy] [name of copyright owner]
70025d765b044c6d8594bb965a2247a61e991a99johnny *
70025d765b044c6d8594bb965a2247a61e991a99johnny * CDDL HEADER END
70025d765b044c6d8594bb965a2247a61e991a99johnny */
70025d765b044c6d8594bb965a2247a61e991a99johnny/*
70025d765b044c6d8594bb965a2247a61e991a99johnny * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
70025d765b044c6d8594bb965a2247a61e991a99johnny * Use is subject to license terms.
70025d765b044c6d8594bb965a2247a61e991a99johnny */
70025d765b044c6d8594bb965a2247a61e991a99johnny
70025d765b044c6d8594bb965a2247a61e991a99johnny#pragma ident "%Z%%M% %I% %E% SMI"
70025d765b044c6d8594bb965a2247a61e991a99johnny
70025d765b044c6d8594bb965a2247a61e991a99johnny#include <stdio.h>
70025d765b044c6d8594bb965a2247a61e991a99johnny#include <stdlib.h>
70025d765b044c6d8594bb965a2247a61e991a99johnny#include <unistd.h>
70025d765b044c6d8594bb965a2247a61e991a99johnny#include <strings.h>
70025d765b044c6d8594bb965a2247a61e991a99johnny#include <errno.h>
70025d765b044c6d8594bb965a2247a61e991a99johnny#include <sys/param.h>
70025d765b044c6d8594bb965a2247a61e991a99johnny#include <sys/systeminfo.h>
70025d765b044c6d8594bb965a2247a61e991a99johnny#include <sys/sysevent/eventdefs.h>
70025d765b044c6d8594bb965a2247a61e991a99johnny#include <sys/sysevent/dr.h>
70025d765b044c6d8594bb965a2247a61e991a99johnny#include <syslog.h>
70025d765b044c6d8594bb965a2247a61e991a99johnny#include <libnvpair.h>
70025d765b044c6d8594bb965a2247a61e991a99johnny#include <stdarg.h>
70025d765b044c6d8594bb965a2247a61e991a99johnny#include <assert.h>
70025d765b044c6d8594bb965a2247a61e991a99johnny#include <sys/stat.h>
70025d765b044c6d8594bb965a2247a61e991a99johnny#include <dlfcn.h>
70025d765b044c6d8594bb965a2247a61e991a99johnny#include <pcidr.h>
70025d765b044c6d8594bb965a2247a61e991a99johnny#include <pcidr_cfga.h>
70025d765b044c6d8594bb965a2247a61e991a99johnny
70025d765b044c6d8594bb965a2247a61e991a99johnny
70025d765b044c6d8594bb965a2247a61e991a99johnnyPCIDR_PLUGIN_PROTO(attrlistp, optp)
70025d765b044c6d8594bb965a2247a61e991a99johnny{
70025d765b044c6d8594bb965a2247a61e991a99johnny char *fn = PCIDR_PLUGIN_SYMSTR;
70025d765b044c6d8594bb965a2247a61e991a99johnny int rv = 0;
70025d765b044c6d8594bb965a2247a61e991a99johnny char *cfga_errstr = NULL;
70025d765b044c6d8594bb965a2247a61e991a99johnny char *str, *apid;
70025d765b044c6d8594bb965a2247a61e991a99johnny cfga_list_data_t *cfga_listp = NULL;
70025d765b044c6d8594bb965a2247a61e991a99johnny cfga_cmd_t cmd;
70025d765b044c6d8594bb965a2247a61e991a99johnny int cfga_list_len;
70025d765b044c6d8594bb965a2247a61e991a99johnny pcidr_attrs_t dr;
70025d765b044c6d8594bb965a2247a61e991a99johnny
70025d765b044c6d8594bb965a2247a61e991a99johnny pcidr_set_logopt(&optp->logopt);
70025d765b044c6d8594bb965a2247a61e991a99johnny
70025d765b044c6d8594bb965a2247a61e991a99johnny if (pcidr_get_attrs(attrlistp, &dr) != 0 ||
70025d765b044c6d8594bb965a2247a61e991a99johnny pcidr_check_attrs(&dr) != 0) {
70025d765b044c6d8594bb965a2247a61e991a99johnny dprint(DWARN, "%s: invalid or missing attributes\n", fn);
70025d765b044c6d8594bb965a2247a61e991a99johnny return (EINVAL);
70025d765b044c6d8594bb965a2247a61e991a99johnny }
70025d765b044c6d8594bb965a2247a61e991a99johnny
70025d765b044c6d8594bb965a2247a61e991a99johnny /*
70025d765b044c6d8594bb965a2247a61e991a99johnny * get state of APID; enforce the cfgadm pci plugin implementation of
70025d765b044c6d8594bb965a2247a61e991a99johnny * returning one matching AP per supplied apid string
70025d765b044c6d8594bb965a2247a61e991a99johnny */
70025d765b044c6d8594bb965a2247a61e991a99johnny rv = config_list_ext(1, &dr.dr_ap_id, &cfga_listp, &cfga_list_len,
70025d765b044c6d8594bb965a2247a61e991a99johnny NULL, NULL, &cfga_errstr, CFGA_FLAG_LIST_ALL);
70025d765b044c6d8594bb965a2247a61e991a99johnny if (rv != CFGA_OK) {
70025d765b044c6d8594bb965a2247a61e991a99johnny str = pcidr_cfga_err_name(rv);
70025d765b044c6d8594bb965a2247a61e991a99johnny if (str == NULL)
70025d765b044c6d8594bb965a2247a61e991a99johnny str = "unrecognized rv!";
70025d765b044c6d8594bb965a2247a61e991a99johnny dprint(DDEBUG, "%s: config_list_ext() on apid = \"%s\" "
70025d765b044c6d8594bb965a2247a61e991a99johnny "failed: rv = %d (%s)", fn, dr.dr_ap_id, rv, str);
70025d765b044c6d8594bb965a2247a61e991a99johnny
70025d765b044c6d8594bb965a2247a61e991a99johnny if (cfga_errstr != NULL) {
70025d765b044c6d8594bb965a2247a61e991a99johnny dprint(DDEBUG, ", error string = \"%s\"",
70025d765b044c6d8594bb965a2247a61e991a99johnny cfga_errstr);
70025d765b044c6d8594bb965a2247a61e991a99johnny free(cfga_errstr);
70025d765b044c6d8594bb965a2247a61e991a99johnny }
70025d765b044c6d8594bb965a2247a61e991a99johnny dprint(DDEBUG, "\n");
70025d765b044c6d8594bb965a2247a61e991a99johnny rv = EINVAL;
70025d765b044c6d8594bb965a2247a61e991a99johnny goto OUT;
70025d765b044c6d8594bb965a2247a61e991a99johnny }
70025d765b044c6d8594bb965a2247a61e991a99johnny if (cfga_list_len != 1) {
70025d765b044c6d8594bb965a2247a61e991a99johnny dprint(DWARN, "%s: invalid condition - more than one AP was "
70025d765b044c6d8594bb965a2247a61e991a99johnny "found for the APID \"%s\"\n", fn, dr.dr_ap_id);
70025d765b044c6d8594bb965a2247a61e991a99johnny rv = EINVAL;
70025d765b044c6d8594bb965a2247a61e991a99johnny goto OUT;
70025d765b044c6d8594bb965a2247a61e991a99johnny }
70025d765b044c6d8594bb965a2247a61e991a99johnny
70025d765b044c6d8594bb965a2247a61e991a99johnny /*
70025d765b044c6d8594bb965a2247a61e991a99johnny * perform DR
70025d765b044c6d8594bb965a2247a61e991a99johnny */
70025d765b044c6d8594bb965a2247a61e991a99johnny dprint(DINFO, "%s: showing info and performing DR on APID(s) "
70025d765b044c6d8594bb965a2247a61e991a99johnny "matching \"%s\"\n", fn, dr.dr_ap_id);
70025d765b044c6d8594bb965a2247a61e991a99johnny
70025d765b044c6d8594bb965a2247a61e991a99johnny cmd = CFGA_CMD_NONE;
70025d765b044c6d8594bb965a2247a61e991a99johnny dprint(DINFO, "===========================================\n", fn);
70025d765b044c6d8594bb965a2247a61e991a99johnny pcidr_print_cfga(DINFO, &cfga_listp[0], " .. ");
70025d765b044c6d8594bb965a2247a61e991a99johnny apid = cfga_listp[0].ap_phys_id;
70025d765b044c6d8594bb965a2247a61e991a99johnny
70025d765b044c6d8594bb965a2247a61e991a99johnny if (strcmp(dr.dr_req_type, DR_REQ_OUTGOING_RES) == 0) {
70025d765b044c6d8594bb965a2247a61e991a99johnny cmd = CFGA_CMD_DISCONNECT;
70025d765b044c6d8594bb965a2247a61e991a99johnny dprint(DINFO, "%s: disconnecting ...\n", fn, apid);
70025d765b044c6d8594bb965a2247a61e991a99johnny
70025d765b044c6d8594bb965a2247a61e991a99johnny rv = pcidr_cfga_do_cmd(cmd, &cfga_listp[0]);
70025d765b044c6d8594bb965a2247a61e991a99johnny if (rv < 0) {
70025d765b044c6d8594bb965a2247a61e991a99johnny dprint(DINFO, "%s: disconnect FAILED\n", fn);
70025d765b044c6d8594bb965a2247a61e991a99johnny rv = EIO;
70025d765b044c6d8594bb965a2247a61e991a99johnny }
70025d765b044c6d8594bb965a2247a61e991a99johnny else
70025d765b044c6d8594bb965a2247a61e991a99johnny dprint(DINFO, "%s: disconnect OK\n", fn);
70025d765b044c6d8594bb965a2247a61e991a99johnny
70025d765b044c6d8594bb965a2247a61e991a99johnny goto OUT;
70025d765b044c6d8594bb965a2247a61e991a99johnny }
70025d765b044c6d8594bb965a2247a61e991a99johnny if (strcmp(dr.dr_req_type, DR_REQ_INCOMING_RES) == 0) {
70025d765b044c6d8594bb965a2247a61e991a99johnny cmd = CFGA_CMD_CONFIGURE;
70025d765b044c6d8594bb965a2247a61e991a99johnny dprint(DINFO, "%s: configuring ...\n", fn, apid);
70025d765b044c6d8594bb965a2247a61e991a99johnny
70025d765b044c6d8594bb965a2247a61e991a99johnny rv = pcidr_cfga_do_cmd(cmd, &cfga_listp[0]);
70025d765b044c6d8594bb965a2247a61e991a99johnny if (rv < 0) {
70025d765b044c6d8594bb965a2247a61e991a99johnny dprint(DINFO, "%s: configure FAILED\n", fn);
70025d765b044c6d8594bb965a2247a61e991a99johnny rv = EIO;
70025d765b044c6d8594bb965a2247a61e991a99johnny } else
70025d765b044c6d8594bb965a2247a61e991a99johnny dprint(DINFO, "%s: configure OK\n", fn);
70025d765b044c6d8594bb965a2247a61e991a99johnny
70025d765b044c6d8594bb965a2247a61e991a99johnny goto OUT;
70025d765b044c6d8594bb965a2247a61e991a99johnny }
70025d765b044c6d8594bb965a2247a61e991a99johnny
70025d765b044c6d8594bb965a2247a61e991a99johnny /* we should not get here if pcidr_check_attrs() is correct */
70025d765b044c6d8594bb965a2247a61e991a99johnny dprint(DWARN, "%s: invalid dr_req_type = %s\n", fn, dr.dr_req_type);
70025d765b044c6d8594bb965a2247a61e991a99johnny assert(cmd != CFGA_CMD_NONE);
70025d765b044c6d8594bb965a2247a61e991a99johnny return (EINVAL);
70025d765b044c6d8594bb965a2247a61e991a99johnny /*NOTREACHED*/
70025d765b044c6d8594bb965a2247a61e991a99johnnyOUT:
70025d765b044c6d8594bb965a2247a61e991a99johnny if (cfga_listp != NULL)
70025d765b044c6d8594bb965a2247a61e991a99johnny free(cfga_listp);
70025d765b044c6d8594bb965a2247a61e991a99johnny return (rv);
70025d765b044c6d8594bb965a2247a61e991a99johnny}