1*70025d76Sjohnny /* 2*70025d76Sjohnny * CDDL HEADER START 3*70025d76Sjohnny * 4*70025d76Sjohnny * The contents of this file are subject to the terms of the 5*70025d76Sjohnny * Common Development and Distribution License, Version 1.0 only 6*70025d76Sjohnny * (the "License"). You may not use this file except in compliance 7*70025d76Sjohnny * with the License. 8*70025d76Sjohnny * 9*70025d76Sjohnny * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*70025d76Sjohnny * or http://www.opensolaris.org/os/licensing. 11*70025d76Sjohnny * See the License for the specific language governing permissions 12*70025d76Sjohnny * and limitations under the License. 13*70025d76Sjohnny * 14*70025d76Sjohnny * When distributing Covered Code, include this CDDL HEADER in each 15*70025d76Sjohnny * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*70025d76Sjohnny * If applicable, add the following below this CDDL HEADER, with the 17*70025d76Sjohnny * fields enclosed by brackets "[]" replaced with your own identifying 18*70025d76Sjohnny * information: Portions Copyright [yyyy] [name of copyright owner] 19*70025d76Sjohnny * 20*70025d76Sjohnny * CDDL HEADER END 21*70025d76Sjohnny */ 22*70025d76Sjohnny /* 23*70025d76Sjohnny * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*70025d76Sjohnny * Use is subject to license terms. 25*70025d76Sjohnny */ 26*70025d76Sjohnny 27*70025d76Sjohnny #pragma ident "%Z%%M% %I% %E% SMI" 28*70025d76Sjohnny 29*70025d76Sjohnny #include <stdio.h> 30*70025d76Sjohnny #include <stdlib.h> 31*70025d76Sjohnny #include <unistd.h> 32*70025d76Sjohnny #include <strings.h> 33*70025d76Sjohnny #include <errno.h> 34*70025d76Sjohnny #include <sys/param.h> 35*70025d76Sjohnny #include <sys/systeminfo.h> 36*70025d76Sjohnny #include <sys/sysevent/eventdefs.h> 37*70025d76Sjohnny #include <sys/sysevent/dr.h> 38*70025d76Sjohnny #include <syslog.h> 39*70025d76Sjohnny #include <libnvpair.h> 40*70025d76Sjohnny #include <stdarg.h> 41*70025d76Sjohnny #include <assert.h> 42*70025d76Sjohnny #include <sys/stat.h> 43*70025d76Sjohnny #include <dlfcn.h> 44*70025d76Sjohnny #include <pcidr.h> 45*70025d76Sjohnny #include <pcidr_cfga.h> 46*70025d76Sjohnny 47*70025d76Sjohnny 48*70025d76Sjohnny PCIDR_PLUGIN_PROTO(attrlistp, optp) 49*70025d76Sjohnny { 50*70025d76Sjohnny char *fn = PCIDR_PLUGIN_SYMSTR; 51*70025d76Sjohnny int rv = 0; 52*70025d76Sjohnny char *cfga_errstr = NULL; 53*70025d76Sjohnny char *str, *apid; 54*70025d76Sjohnny cfga_list_data_t *cfga_listp = NULL; 55*70025d76Sjohnny cfga_cmd_t cmd; 56*70025d76Sjohnny int cfga_list_len; 57*70025d76Sjohnny pcidr_attrs_t dr; 58*70025d76Sjohnny 59*70025d76Sjohnny pcidr_set_logopt(&optp->logopt); 60*70025d76Sjohnny 61*70025d76Sjohnny if (pcidr_get_attrs(attrlistp, &dr) != 0 || 62*70025d76Sjohnny pcidr_check_attrs(&dr) != 0) { 63*70025d76Sjohnny dprint(DWARN, "%s: invalid or missing attributes\n", fn); 64*70025d76Sjohnny return (EINVAL); 65*70025d76Sjohnny } 66*70025d76Sjohnny 67*70025d76Sjohnny /* 68*70025d76Sjohnny * get state of APID; enforce the cfgadm pci plugin implementation of 69*70025d76Sjohnny * returning one matching AP per supplied apid string 70*70025d76Sjohnny */ 71*70025d76Sjohnny rv = config_list_ext(1, &dr.dr_ap_id, &cfga_listp, &cfga_list_len, 72*70025d76Sjohnny NULL, NULL, &cfga_errstr, CFGA_FLAG_LIST_ALL); 73*70025d76Sjohnny if (rv != CFGA_OK) { 74*70025d76Sjohnny str = pcidr_cfga_err_name(rv); 75*70025d76Sjohnny if (str == NULL) 76*70025d76Sjohnny str = "unrecognized rv!"; 77*70025d76Sjohnny dprint(DDEBUG, "%s: config_list_ext() on apid = \"%s\" " 78*70025d76Sjohnny "failed: rv = %d (%s)", fn, dr.dr_ap_id, rv, str); 79*70025d76Sjohnny 80*70025d76Sjohnny if (cfga_errstr != NULL) { 81*70025d76Sjohnny dprint(DDEBUG, ", error string = \"%s\"", 82*70025d76Sjohnny cfga_errstr); 83*70025d76Sjohnny free(cfga_errstr); 84*70025d76Sjohnny } 85*70025d76Sjohnny dprint(DDEBUG, "\n"); 86*70025d76Sjohnny rv = EINVAL; 87*70025d76Sjohnny goto OUT; 88*70025d76Sjohnny } 89*70025d76Sjohnny if (cfga_list_len != 1) { 90*70025d76Sjohnny dprint(DWARN, "%s: invalid condition - more than one AP was " 91*70025d76Sjohnny "found for the APID \"%s\"\n", fn, dr.dr_ap_id); 92*70025d76Sjohnny rv = EINVAL; 93*70025d76Sjohnny goto OUT; 94*70025d76Sjohnny } 95*70025d76Sjohnny 96*70025d76Sjohnny /* 97*70025d76Sjohnny * perform DR 98*70025d76Sjohnny */ 99*70025d76Sjohnny dprint(DINFO, "%s: showing info and performing DR on APID(s) " 100*70025d76Sjohnny "matching \"%s\"\n", fn, dr.dr_ap_id); 101*70025d76Sjohnny 102*70025d76Sjohnny cmd = CFGA_CMD_NONE; 103*70025d76Sjohnny dprint(DINFO, "===========================================\n", fn); 104*70025d76Sjohnny pcidr_print_cfga(DINFO, &cfga_listp[0], " .. "); 105*70025d76Sjohnny apid = cfga_listp[0].ap_phys_id; 106*70025d76Sjohnny 107*70025d76Sjohnny if (strcmp(dr.dr_req_type, DR_REQ_OUTGOING_RES) == 0) { 108*70025d76Sjohnny cmd = CFGA_CMD_DISCONNECT; 109*70025d76Sjohnny dprint(DINFO, "%s: disconnecting ...\n", fn, apid); 110*70025d76Sjohnny 111*70025d76Sjohnny rv = pcidr_cfga_do_cmd(cmd, &cfga_listp[0]); 112*70025d76Sjohnny if (rv < 0) { 113*70025d76Sjohnny dprint(DINFO, "%s: disconnect FAILED\n", fn); 114*70025d76Sjohnny rv = EIO; 115*70025d76Sjohnny } 116*70025d76Sjohnny else 117*70025d76Sjohnny dprint(DINFO, "%s: disconnect OK\n", fn); 118*70025d76Sjohnny 119*70025d76Sjohnny goto OUT; 120*70025d76Sjohnny } 121*70025d76Sjohnny if (strcmp(dr.dr_req_type, DR_REQ_INCOMING_RES) == 0) { 122*70025d76Sjohnny cmd = CFGA_CMD_CONFIGURE; 123*70025d76Sjohnny dprint(DINFO, "%s: configuring ...\n", fn, apid); 124*70025d76Sjohnny 125*70025d76Sjohnny rv = pcidr_cfga_do_cmd(cmd, &cfga_listp[0]); 126*70025d76Sjohnny if (rv < 0) { 127*70025d76Sjohnny dprint(DINFO, "%s: configure FAILED\n", fn); 128*70025d76Sjohnny rv = EIO; 129*70025d76Sjohnny } else 130*70025d76Sjohnny dprint(DINFO, "%s: configure OK\n", fn); 131*70025d76Sjohnny 132*70025d76Sjohnny goto OUT; 133*70025d76Sjohnny } 134*70025d76Sjohnny 135*70025d76Sjohnny /* we should not get here if pcidr_check_attrs() is correct */ 136*70025d76Sjohnny dprint(DWARN, "%s: invalid dr_req_type = %s\n", fn, dr.dr_req_type); 137*70025d76Sjohnny assert(cmd != CFGA_CMD_NONE); 138*70025d76Sjohnny return (EINVAL); 139*70025d76Sjohnny /*NOTREACHED*/ 140*70025d76Sjohnny OUT: 141*70025d76Sjohnny if (cfga_listp != NULL) 142*70025d76Sjohnny free(cfga_listp); 143*70025d76Sjohnny return (rv); 144*70025d76Sjohnny } 145