1*fcf3ce44SJohn Forte /* 2*fcf3ce44SJohn Forte * CDDL HEADER START 3*fcf3ce44SJohn Forte * 4*fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5*fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6*fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7*fcf3ce44SJohn Forte * 8*fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10*fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11*fcf3ce44SJohn Forte * and limitations under the License. 12*fcf3ce44SJohn Forte * 13*fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14*fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16*fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17*fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18*fcf3ce44SJohn Forte * 19*fcf3ce44SJohn Forte * CDDL HEADER END 20*fcf3ce44SJohn Forte */ 21*fcf3ce44SJohn Forte /* 22*fcf3ce44SJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*fcf3ce44SJohn Forte * Use is subject to license terms. 24*fcf3ce44SJohn Forte */ 25*fcf3ce44SJohn Forte 26*fcf3ce44SJohn Forte 27*fcf3ce44SJohn Forte /*LINTLIBRARY*/ 28*fcf3ce44SJohn Forte 29*fcf3ce44SJohn Forte 30*fcf3ce44SJohn Forte /* 31*fcf3ce44SJohn Forte * This module is part of the photon library 32*fcf3ce44SJohn Forte */ 33*fcf3ce44SJohn Forte 34*fcf3ce44SJohn Forte /* 35*fcf3ce44SJohn Forte * I18N message number ranges 36*fcf3ce44SJohn Forte * This file: 8000 - 8499 37*fcf3ce44SJohn Forte * Shared common messages: 1 - 1999 38*fcf3ce44SJohn Forte */ 39*fcf3ce44SJohn Forte 40*fcf3ce44SJohn Forte /* Includes */ 41*fcf3ce44SJohn Forte #include <stdlib.h> 42*fcf3ce44SJohn Forte #include <stdio.h> 43*fcf3ce44SJohn Forte #include <sys/file.h> 44*fcf3ce44SJohn Forte #include <sys/types.h> 45*fcf3ce44SJohn Forte #include <sys/param.h> 46*fcf3ce44SJohn Forte #include <fcntl.h> 47*fcf3ce44SJohn Forte #include <unistd.h> 48*fcf3ce44SJohn Forte #include <errno.h> 49*fcf3ce44SJohn Forte #include <string.h> 50*fcf3ce44SJohn Forte #include <sys/scsi/scsi.h> 51*fcf3ce44SJohn Forte #include <nl_types.h> 52*fcf3ce44SJohn Forte #include <strings.h> 53*fcf3ce44SJohn Forte #include <sys/ddi.h> /* for max */ 54*fcf3ce44SJohn Forte #include <l_common.h> 55*fcf3ce44SJohn Forte #include <stgcom.h> 56*fcf3ce44SJohn Forte #include <l_error.h> 57*fcf3ce44SJohn Forte #include <a_state.h> 58*fcf3ce44SJohn Forte #include <a5k.h> 59*fcf3ce44SJohn Forte 60*fcf3ce44SJohn Forte 61*fcf3ce44SJohn Forte 62*fcf3ce44SJohn Forte /* Defines */ 63*fcf3ce44SJohn Forte #define VERBPRINT if (verbose) (void) printf 64*fcf3ce44SJohn Forte 65*fcf3ce44SJohn Forte 66*fcf3ce44SJohn Forte /* 67*fcf3ce44SJohn Forte * take all paths supplied by dl offline. 68*fcf3ce44SJohn Forte * 69*fcf3ce44SJohn Forte * RETURNS: 70*fcf3ce44SJohn Forte * 0 = No error. 71*fcf3ce44SJohn Forte * *bsy_res_flag_p: 1 = The device is "busy". 72*fcf3ce44SJohn Forte * 73*fcf3ce44SJohn Forte * In pre-2.6 we just return success 74*fcf3ce44SJohn Forte */ 75*fcf3ce44SJohn Forte static int 76*fcf3ce44SJohn Forte d_offline_drive(struct dlist *dl, int *bsy_res_flag_p, int verbose) 77*fcf3ce44SJohn Forte { 78*fcf3ce44SJohn Forte char dev_path1[MAXPATHLEN]; 79*fcf3ce44SJohn Forte devctl_hdl_t devhdl; 80*fcf3ce44SJohn Forte 81*fcf3ce44SJohn Forte 82*fcf3ce44SJohn Forte /* for each path attempt to take it offline */ 83*fcf3ce44SJohn Forte for (; dl != NULL; dl = dl->next) { 84*fcf3ce44SJohn Forte 85*fcf3ce44SJohn Forte /* save a copy of the pathname */ 86*fcf3ce44SJohn Forte (void) strcpy(dev_path1, dl->dev_path); 87*fcf3ce44SJohn Forte 88*fcf3ce44SJohn Forte /* attempt to acquire the device */ 89*fcf3ce44SJohn Forte if ((devhdl = devctl_device_acquire(dev_path1, 90*fcf3ce44SJohn Forte DC_EXCL)) == NULL) { 91*fcf3ce44SJohn Forte if (errno != EBUSY) { 92*fcf3ce44SJohn Forte return (L_ACQUIRE_FAIL); 93*fcf3ce44SJohn Forte } 94*fcf3ce44SJohn Forte } 95*fcf3ce44SJohn Forte 96*fcf3ce44SJohn Forte /* attempt to offline the drive */ 97*fcf3ce44SJohn Forte if (devctl_device_offline(devhdl) != 0) { 98*fcf3ce44SJohn Forte *bsy_res_flag_p = 1; 99*fcf3ce44SJohn Forte (void) devctl_release(devhdl); 100*fcf3ce44SJohn Forte return (0); 101*fcf3ce44SJohn Forte } 102*fcf3ce44SJohn Forte 103*fcf3ce44SJohn Forte E_DPRINTF(" d_offline_drive: Offline succeeded:/n " 104*fcf3ce44SJohn Forte "%s\n", dev_path1); 105*fcf3ce44SJohn Forte /* offline succeeded -- release handle acquired above */ 106*fcf3ce44SJohn Forte (void) devctl_release(devhdl); 107*fcf3ce44SJohn Forte } 108*fcf3ce44SJohn Forte return (0); 109*fcf3ce44SJohn Forte } 110*fcf3ce44SJohn Forte 111*fcf3ce44SJohn Forte 112*fcf3ce44SJohn Forte 113*fcf3ce44SJohn Forte 114*fcf3ce44SJohn Forte /* 115*fcf3ce44SJohn Forte * Check to see if any of the disks that are attached 116*fcf3ce44SJohn Forte * to the selected port on this backplane are reserved or busy. 117*fcf3ce44SJohn Forte * 118*fcf3ce44SJohn Forte * INPUTS: 119*fcf3ce44SJohn Forte * RETURNS: 120*fcf3ce44SJohn Forte * 0 = No error. 121*fcf3ce44SJohn Forte * *bsy_res_flag_p: 1 = The device is "busy". 122*fcf3ce44SJohn Forte */ 123*fcf3ce44SJohn Forte 124*fcf3ce44SJohn Forte int 125*fcf3ce44SJohn Forte l_check_busy_reserv_bp(char *ses_path, int front_flag, 126*fcf3ce44SJohn Forte int port_a_flag, int *bsy_res_flag_p, int verbose) 127*fcf3ce44SJohn Forte { 128*fcf3ce44SJohn Forte int err, i; 129*fcf3ce44SJohn Forte L_state *l_state = NULL; 130*fcf3ce44SJohn Forte struct dlist *p_list; 131*fcf3ce44SJohn Forte 132*fcf3ce44SJohn Forte if ((l_state = (L_state *)calloc(1, sizeof (L_state))) == NULL) { 133*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 134*fcf3ce44SJohn Forte } 135*fcf3ce44SJohn Forte 136*fcf3ce44SJohn Forte if (err = l_get_status(ses_path, l_state, verbose)) { 137*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 138*fcf3ce44SJohn Forte return (err); 139*fcf3ce44SJohn Forte } 140*fcf3ce44SJohn Forte for (i = 0; i < (int)l_state->total_num_drv/2; i++) { 141*fcf3ce44SJohn Forte if ((front_flag && 142*fcf3ce44SJohn Forte (l_state->drv_front[i].g_disk_state.d_state_flags[port_a_flag] & 143*fcf3ce44SJohn Forte L_RESERVED)) || (!front_flag && 144*fcf3ce44SJohn Forte (l_state->drv_rear[i].g_disk_state.d_state_flags[port_a_flag] & 145*fcf3ce44SJohn Forte L_RESERVED))) { 146*fcf3ce44SJohn Forte *bsy_res_flag_p = 1; 147*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 148*fcf3ce44SJohn Forte return (0); 149*fcf3ce44SJohn Forte } 150*fcf3ce44SJohn Forte } 151*fcf3ce44SJohn Forte 152*fcf3ce44SJohn Forte for (i = 0; i < (int)l_state->total_num_drv/2; i++) { 153*fcf3ce44SJohn Forte /* Get list of all paths to the requested port. */ 154*fcf3ce44SJohn Forte if (front_flag) { 155*fcf3ce44SJohn Forte if (port_a_flag) { 156*fcf3ce44SJohn Forte if ((err = g_get_port_multipath( 157*fcf3ce44SJohn Forte l_state->drv_front[i].g_disk_state.port_a_wwn_s, 158*fcf3ce44SJohn Forte &p_list, verbose)) != 0) { 159*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 160*fcf3ce44SJohn Forte return (err); 161*fcf3ce44SJohn Forte } 162*fcf3ce44SJohn Forte } else { 163*fcf3ce44SJohn Forte if ((err = g_get_port_multipath( 164*fcf3ce44SJohn Forte l_state->drv_front[i].g_disk_state.port_b_wwn_s, 165*fcf3ce44SJohn Forte &p_list, verbose)) != 0) { 166*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 167*fcf3ce44SJohn Forte return (err); 168*fcf3ce44SJohn Forte } 169*fcf3ce44SJohn Forte } 170*fcf3ce44SJohn Forte } else { 171*fcf3ce44SJohn Forte if (port_a_flag) { 172*fcf3ce44SJohn Forte if ((err = g_get_port_multipath( 173*fcf3ce44SJohn Forte l_state->drv_rear[i].g_disk_state.port_a_wwn_s, 174*fcf3ce44SJohn Forte &p_list, verbose)) != 0) { 175*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 176*fcf3ce44SJohn Forte return (err); 177*fcf3ce44SJohn Forte } 178*fcf3ce44SJohn Forte } else { 179*fcf3ce44SJohn Forte if ((err = g_get_port_multipath( 180*fcf3ce44SJohn Forte l_state->drv_rear[i].g_disk_state.port_b_wwn_s, 181*fcf3ce44SJohn Forte &p_list, verbose)) != 0) { 182*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 183*fcf3ce44SJohn Forte return (err); 184*fcf3ce44SJohn Forte } 185*fcf3ce44SJohn Forte } 186*fcf3ce44SJohn Forte } 187*fcf3ce44SJohn Forte if (err = d_offline_drive(p_list, 188*fcf3ce44SJohn Forte bsy_res_flag_p, verbose)) { 189*fcf3ce44SJohn Forte (void) g_free_multipath(p_list); 190*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 191*fcf3ce44SJohn Forte return (err); 192*fcf3ce44SJohn Forte } 193*fcf3ce44SJohn Forte (void) g_free_multipath(p_list); 194*fcf3ce44SJohn Forte } 195*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 196*fcf3ce44SJohn Forte return (0); 197*fcf3ce44SJohn Forte } 198*fcf3ce44SJohn Forte 199*fcf3ce44SJohn Forte 200*fcf3ce44SJohn Forte 201*fcf3ce44SJohn Forte /* 202*fcf3ce44SJohn Forte * Request the enclosure services controller (IB) 203*fcf3ce44SJohn Forte * to set the LRC (Loop Redundancy Circuit) to the 204*fcf3ce44SJohn Forte * bypassed/enabled state for the backplane specified by 205*fcf3ce44SJohn Forte * the a and f flag and the enclosure or pathname. 206*fcf3ce44SJohn Forte */ 207*fcf3ce44SJohn Forte int 208*fcf3ce44SJohn Forte l_bp_bypass_enable(char *ses_path, int bypass_flag, int port_a_flag, 209*fcf3ce44SJohn Forte int front_flag, int force_flag, int verbose) 210*fcf3ce44SJohn Forte { 211*fcf3ce44SJohn Forte 212*fcf3ce44SJohn Forte int fd, i; 213*fcf3ce44SJohn Forte int nobj = 0; 214*fcf3ce44SJohn Forte ses_objarg obj; 215*fcf3ce44SJohn Forte ses_object *all_objp = NULL, *all_objp_save = NULL; 216*fcf3ce44SJohn Forte int found = 0; 217*fcf3ce44SJohn Forte Bp_elem_st *bp; 218*fcf3ce44SJohn Forte char msg[MAXPATHLEN]; 219*fcf3ce44SJohn Forte int bsy_res_flag = 0; 220*fcf3ce44SJohn Forte int err; 221*fcf3ce44SJohn Forte 222*fcf3ce44SJohn Forte if (ses_path == NULL) { 223*fcf3ce44SJohn Forte return (L_NO_SES_PATH); 224*fcf3ce44SJohn Forte } 225*fcf3ce44SJohn Forte 226*fcf3ce44SJohn Forte /* 227*fcf3ce44SJohn Forte * Check for reservation and busy for all disks on this 228*fcf3ce44SJohn Forte * backplane. 229*fcf3ce44SJohn Forte */ 230*fcf3ce44SJohn Forte 231*fcf3ce44SJohn Forte if (!force_flag && bypass_flag) { 232*fcf3ce44SJohn Forte if (err = l_check_busy_reserv_bp(ses_path, 233*fcf3ce44SJohn Forte front_flag, port_a_flag, &bsy_res_flag, verbose)) { 234*fcf3ce44SJohn Forte return (err); 235*fcf3ce44SJohn Forte } 236*fcf3ce44SJohn Forte if (bsy_res_flag) { 237*fcf3ce44SJohn Forte return (L_BP_BUSY_RESERVED); 238*fcf3ce44SJohn Forte } 239*fcf3ce44SJohn Forte } 240*fcf3ce44SJohn Forte 241*fcf3ce44SJohn Forte 242*fcf3ce44SJohn Forte if ((fd = g_object_open(ses_path, O_NDELAY | O_RDWR)) == -1) { 243*fcf3ce44SJohn Forte return (errno); 244*fcf3ce44SJohn Forte } 245*fcf3ce44SJohn Forte 246*fcf3ce44SJohn Forte if (ioctl(fd, SESIOC_GETNOBJ, (caddr_t)&nobj) < 0) { 247*fcf3ce44SJohn Forte (void) close(fd); 248*fcf3ce44SJohn Forte return (errno); 249*fcf3ce44SJohn Forte } 250*fcf3ce44SJohn Forte if (nobj == 0) { 251*fcf3ce44SJohn Forte (void) close(fd); 252*fcf3ce44SJohn Forte return (L_IB_NO_ELEM_FOUND); 253*fcf3ce44SJohn Forte } 254*fcf3ce44SJohn Forte 255*fcf3ce44SJohn Forte E_DPRINTF(" l_ib_bypass_bp: Number of SES objects: 0x%x\n", 256*fcf3ce44SJohn Forte nobj); 257*fcf3ce44SJohn Forte 258*fcf3ce44SJohn Forte /* alloc some memory for the objmap */ 259*fcf3ce44SJohn Forte if ((all_objp = g_zalloc((nobj + 1) * sizeof (ses_object))) == NULL) { 260*fcf3ce44SJohn Forte (void) close(fd); 261*fcf3ce44SJohn Forte return (errno); 262*fcf3ce44SJohn Forte } 263*fcf3ce44SJohn Forte 264*fcf3ce44SJohn Forte all_objp_save = all_objp; 265*fcf3ce44SJohn Forte 266*fcf3ce44SJohn Forte if (ioctl(fd, SESIOC_GETOBJMAP, (caddr_t)all_objp) < 0) { 267*fcf3ce44SJohn Forte (void) close(fd); 268*fcf3ce44SJohn Forte (void) g_destroy_data(all_objp_save); 269*fcf3ce44SJohn Forte return (errno); 270*fcf3ce44SJohn Forte } 271*fcf3ce44SJohn Forte 272*fcf3ce44SJohn Forte for (i = 0; i < nobj; i++, all_objp++) { 273*fcf3ce44SJohn Forte E_DPRINTF(" ID 0x%x\t Element type 0x%x\n", 274*fcf3ce44SJohn Forte all_objp->obj_id, all_objp->elem_type); 275*fcf3ce44SJohn Forte if (all_objp->elem_type == ELM_TYP_BP) { 276*fcf3ce44SJohn Forte found++; 277*fcf3ce44SJohn Forte break; 278*fcf3ce44SJohn Forte } 279*fcf3ce44SJohn Forte } 280*fcf3ce44SJohn Forte 281*fcf3ce44SJohn Forte if (found == 0) { 282*fcf3ce44SJohn Forte (void) close(fd); 283*fcf3ce44SJohn Forte (void) g_destroy_data(all_objp_save); 284*fcf3ce44SJohn Forte return (L_NO_BP_ELEM_FOUND); 285*fcf3ce44SJohn Forte } 286*fcf3ce44SJohn Forte 287*fcf3ce44SJohn Forte /* 288*fcf3ce44SJohn Forte * We found the backplane element. 289*fcf3ce44SJohn Forte */ 290*fcf3ce44SJohn Forte 291*fcf3ce44SJohn Forte 292*fcf3ce44SJohn Forte if (verbose) { 293*fcf3ce44SJohn Forte /* Get the status for backplane #0 */ 294*fcf3ce44SJohn Forte obj.obj_id = all_objp->obj_id; 295*fcf3ce44SJohn Forte if (ioctl(fd, SESIOC_GETOBJSTAT, (caddr_t)&obj) < 0) { 296*fcf3ce44SJohn Forte (void) close(fd); 297*fcf3ce44SJohn Forte (void) g_destroy_data(all_objp_save); 298*fcf3ce44SJohn Forte return (errno); 299*fcf3ce44SJohn Forte } 300*fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(8000, 301*fcf3ce44SJohn Forte " Front backplane status: ")); 302*fcf3ce44SJohn Forte bp = (struct bp_element_status *)&obj.cstat[0]; 303*fcf3ce44SJohn Forte l_element_msg_string(bp->code, msg); 304*fcf3ce44SJohn Forte (void) fprintf(stdout, "%s\n", msg); 305*fcf3ce44SJohn Forte if (bp->byp_a_enabled || bp->en_bypass_a) { 306*fcf3ce44SJohn Forte (void) fprintf(stdout, " "); 307*fcf3ce44SJohn Forte (void) fprintf(stdout, 308*fcf3ce44SJohn Forte MSGSTR(130, "Bypass A enabled")); 309*fcf3ce44SJohn Forte (void) fprintf(stdout, ".\n"); 310*fcf3ce44SJohn Forte } 311*fcf3ce44SJohn Forte if (bp->byp_b_enabled || bp->en_bypass_b) { 312*fcf3ce44SJohn Forte (void) fprintf(stdout, " "); 313*fcf3ce44SJohn Forte (void) fprintf(stdout, 314*fcf3ce44SJohn Forte MSGSTR(129, "Bypass B enabled")); 315*fcf3ce44SJohn Forte (void) fprintf(stdout, ".\n"); 316*fcf3ce44SJohn Forte } 317*fcf3ce44SJohn Forte 318*fcf3ce44SJohn Forte all_objp++; 319*fcf3ce44SJohn Forte obj.obj_id = all_objp->obj_id; 320*fcf3ce44SJohn Forte all_objp--; 321*fcf3ce44SJohn Forte if (ioctl(fd, SESIOC_GETOBJSTAT, (caddr_t)&obj) < 0) { 322*fcf3ce44SJohn Forte (void) close(fd); 323*fcf3ce44SJohn Forte (void) g_destroy_data(all_objp_save); 324*fcf3ce44SJohn Forte return (errno); 325*fcf3ce44SJohn Forte } 326*fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(8001, 327*fcf3ce44SJohn Forte " Rear backplane status: ")); 328*fcf3ce44SJohn Forte bp = (struct bp_element_status *)&obj.cstat[0]; 329*fcf3ce44SJohn Forte l_element_msg_string(bp->code, msg); 330*fcf3ce44SJohn Forte (void) fprintf(stdout, "%s\n", msg); 331*fcf3ce44SJohn Forte if (bp->byp_a_enabled || bp->en_bypass_a) { 332*fcf3ce44SJohn Forte (void) fprintf(stdout, " "); 333*fcf3ce44SJohn Forte (void) fprintf(stdout, 334*fcf3ce44SJohn Forte MSGSTR(130, "Bypass A enabled")); 335*fcf3ce44SJohn Forte (void) fprintf(stdout, ".\n"); 336*fcf3ce44SJohn Forte } 337*fcf3ce44SJohn Forte if (bp->byp_b_enabled || bp->en_bypass_b) { 338*fcf3ce44SJohn Forte (void) fprintf(stdout, " "); 339*fcf3ce44SJohn Forte (void) fprintf(stdout, 340*fcf3ce44SJohn Forte MSGSTR(129, "Bypass B enabled")); 341*fcf3ce44SJohn Forte (void) fprintf(stdout, ".\n"); 342*fcf3ce44SJohn Forte } 343*fcf3ce44SJohn Forte } 344*fcf3ce44SJohn Forte 345*fcf3ce44SJohn Forte /* Get the current status */ 346*fcf3ce44SJohn Forte if (!front_flag) { 347*fcf3ce44SJohn Forte all_objp++; 348*fcf3ce44SJohn Forte } 349*fcf3ce44SJohn Forte obj.obj_id = all_objp->obj_id; 350*fcf3ce44SJohn Forte if (ioctl(fd, SESIOC_GETOBJSTAT, (caddr_t)&obj) < 0) { 351*fcf3ce44SJohn Forte (void) close(fd); 352*fcf3ce44SJohn Forte (void) g_destroy_data(all_objp_save); 353*fcf3ce44SJohn Forte return (errno); 354*fcf3ce44SJohn Forte } 355*fcf3ce44SJohn Forte /* Do the requested action. */ 356*fcf3ce44SJohn Forte bp = (struct bp_element_status *)&obj.cstat[0]; 357*fcf3ce44SJohn Forte bp->select = 1; 358*fcf3ce44SJohn Forte bp->code = 0; 359*fcf3ce44SJohn Forte if (port_a_flag) { 360*fcf3ce44SJohn Forte bp->en_bypass_a = bypass_flag; 361*fcf3ce44SJohn Forte } else { 362*fcf3ce44SJohn Forte bp->en_bypass_b = bypass_flag; 363*fcf3ce44SJohn Forte } 364*fcf3ce44SJohn Forte if (getenv("_LUX_E_DEBUG") != NULL) { 365*fcf3ce44SJohn Forte (void) printf(" Sending this structure to ID 0x%x" 366*fcf3ce44SJohn Forte " of type 0x%x\n", 367*fcf3ce44SJohn Forte obj.obj_id, all_objp->elem_type); 368*fcf3ce44SJohn Forte for (i = 0; i < 4; i++) { 369*fcf3ce44SJohn Forte (void) printf(" Byte %d 0x%x\n", i, 370*fcf3ce44SJohn Forte obj.cstat[i]); 371*fcf3ce44SJohn Forte } 372*fcf3ce44SJohn Forte } 373*fcf3ce44SJohn Forte 374*fcf3ce44SJohn Forte if (ioctl(fd, SESIOC_SETOBJSTAT, (caddr_t)&obj) < 0) { 375*fcf3ce44SJohn Forte (void) close(fd); 376*fcf3ce44SJohn Forte (void) g_destroy_data(all_objp_save); 377*fcf3ce44SJohn Forte return (errno); 378*fcf3ce44SJohn Forte } 379*fcf3ce44SJohn Forte 380*fcf3ce44SJohn Forte (void) g_destroy_data(all_objp_save); 381*fcf3ce44SJohn Forte (void) close(fd); 382*fcf3ce44SJohn Forte 383*fcf3ce44SJohn Forte return (0); 384*fcf3ce44SJohn Forte } 385*fcf3ce44SJohn Forte 386*fcf3ce44SJohn Forte 387*fcf3ce44SJohn Forte 388*fcf3ce44SJohn Forte 389*fcf3ce44SJohn Forte /* 390*fcf3ce44SJohn Forte * This function will request the enclosure services 391*fcf3ce44SJohn Forte * controller (IB) to set the LRC (Loop Redundancy Circuit) to the 392*fcf3ce44SJohn Forte * bypassed/enabled state for the device specified by the 393*fcf3ce44SJohn Forte * enclosure,dev or pathname and the port specified by the a 394*fcf3ce44SJohn Forte * flag. 395*fcf3ce44SJohn Forte */ 396*fcf3ce44SJohn Forte 397*fcf3ce44SJohn Forte int 398*fcf3ce44SJohn Forte l_dev_bypass_enable(struct path_struct *path_struct, int bypass_flag, 399*fcf3ce44SJohn Forte int force_flag, int port_a_flag, int verbose) 400*fcf3ce44SJohn Forte { 401*fcf3ce44SJohn Forte gfc_map_t map; 402*fcf3ce44SJohn Forte char ses_path[MAXPATHLEN]; 403*fcf3ce44SJohn Forte uchar_t *page_buf; 404*fcf3ce44SJohn Forte int err, fd, front_index, rear_index, offset; 405*fcf3ce44SJohn Forte int pathcnt = 1; 406*fcf3ce44SJohn Forte unsigned short page_len; 407*fcf3ce44SJohn Forte struct device_element *elem; 408*fcf3ce44SJohn Forte L_state *l_state = NULL; 409*fcf3ce44SJohn Forte struct device_element status; 410*fcf3ce44SJohn Forte int bsy_flag = 0, i, f_flag; 411*fcf3ce44SJohn Forte struct dlist *p_list; 412*fcf3ce44SJohn Forte char temppath[MAXPATHLEN]; 413*fcf3ce44SJohn Forte mp_pathlist_t pathlist; 414*fcf3ce44SJohn Forte int p_pw = 0, p_on = 0, p_st = 0; 415*fcf3ce44SJohn Forte L_inquiry inq; 416*fcf3ce44SJohn Forte 417*fcf3ce44SJohn Forte if (path_struct == NULL) { 418*fcf3ce44SJohn Forte return (L_INVALID_PATH_FORMAT); 419*fcf3ce44SJohn Forte } 420*fcf3ce44SJohn Forte 421*fcf3ce44SJohn Forte if ((l_state = (L_state *)calloc(1, sizeof (L_state))) == NULL) { 422*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 423*fcf3ce44SJohn Forte } 424*fcf3ce44SJohn Forte map.dev_addr = (gfc_port_dev_info_t *)NULL; 425*fcf3ce44SJohn Forte (void) strcpy(temppath, path_struct->p_physical_path); 426*fcf3ce44SJohn Forte if ((strstr(path_struct->p_physical_path, SCSI_VHCI) != NULL) && 427*fcf3ce44SJohn Forte (!g_get_pathlist(temppath, &pathlist))) { 428*fcf3ce44SJohn Forte pathcnt = pathlist.path_count; 429*fcf3ce44SJohn Forte p_pw = p_on = p_st = 0; 430*fcf3ce44SJohn Forte for (i = 0; i < pathcnt; i++) { 431*fcf3ce44SJohn Forte if (pathlist.path_info[i].path_state < 432*fcf3ce44SJohn Forte MAXPATHSTATE) { 433*fcf3ce44SJohn Forte if (strstr(pathlist.path_info[i]. 434*fcf3ce44SJohn Forte path_addr, 435*fcf3ce44SJohn Forte path_struct->argv) != NULL) { 436*fcf3ce44SJohn Forte p_pw = i; 437*fcf3ce44SJohn Forte break; 438*fcf3ce44SJohn Forte } 439*fcf3ce44SJohn Forte if (pathlist.path_info[i].path_state == 440*fcf3ce44SJohn Forte MDI_PATHINFO_STATE_ONLINE) { 441*fcf3ce44SJohn Forte p_on = i; 442*fcf3ce44SJohn Forte } 443*fcf3ce44SJohn Forte if (pathlist.path_info[i].path_state == 444*fcf3ce44SJohn Forte MDI_PATHINFO_STATE_STANDBY) { 445*fcf3ce44SJohn Forte p_st = i; 446*fcf3ce44SJohn Forte } 447*fcf3ce44SJohn Forte } 448*fcf3ce44SJohn Forte } 449*fcf3ce44SJohn Forte if (strstr(pathlist.path_info[p_pw].path_addr, 450*fcf3ce44SJohn Forte path_struct->argv) != NULL) { 451*fcf3ce44SJohn Forte /* matching input pwwn */ 452*fcf3ce44SJohn Forte (void) strcpy(temppath, 453*fcf3ce44SJohn Forte pathlist.path_info[p_pw].path_hba); 454*fcf3ce44SJohn Forte } else if (pathlist.path_info[p_on].path_state == 455*fcf3ce44SJohn Forte MDI_PATHINFO_STATE_ONLINE) { 456*fcf3ce44SJohn Forte /* on_line path */ 457*fcf3ce44SJohn Forte (void) strcpy(temppath, 458*fcf3ce44SJohn Forte pathlist.path_info[p_on].path_hba); 459*fcf3ce44SJohn Forte } else { 460*fcf3ce44SJohn Forte /* standby or path0 */ 461*fcf3ce44SJohn Forte (void) strcpy(temppath, 462*fcf3ce44SJohn Forte pathlist.path_info[p_st].path_hba); 463*fcf3ce44SJohn Forte } 464*fcf3ce44SJohn Forte free(pathlist.path_info); 465*fcf3ce44SJohn Forte (void) strcat(temppath, FC_CTLR); 466*fcf3ce44SJohn Forte } 467*fcf3ce44SJohn Forte 468*fcf3ce44SJohn Forte /* 469*fcf3ce44SJohn Forte * Need to get a valid location, front/rear & slot. 470*fcf3ce44SJohn Forte * 471*fcf3ce44SJohn Forte * The path_struct will return a valid slot 472*fcf3ce44SJohn Forte * and the IB path or a disk path. 473*fcf3ce44SJohn Forte */ 474*fcf3ce44SJohn Forte 475*fcf3ce44SJohn Forte if (!path_struct->ib_path_flag) { 476*fcf3ce44SJohn Forte if (err = g_get_dev_map(temppath, &map, verbose)) { 477*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 478*fcf3ce44SJohn Forte return (err); 479*fcf3ce44SJohn Forte } 480*fcf3ce44SJohn Forte if (err = l_get_ses_path(path_struct->p_physical_path, 481*fcf3ce44SJohn Forte ses_path, &map, verbose)) { 482*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 483*fcf3ce44SJohn Forte free((void *)map.dev_addr); 484*fcf3ce44SJohn Forte return (err); 485*fcf3ce44SJohn Forte } 486*fcf3ce44SJohn Forte } else { 487*fcf3ce44SJohn Forte (void) strcpy(ses_path, path_struct->p_physical_path); 488*fcf3ce44SJohn Forte } 489*fcf3ce44SJohn Forte if (!path_struct->slot_valid) { 490*fcf3ce44SJohn Forte if ((map.dev_addr == (gfc_port_dev_info_t *)NULL) && 491*fcf3ce44SJohn Forte ((err = g_get_dev_map(temppath, 492*fcf3ce44SJohn Forte &map, verbose)) != 0)) { 493*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 494*fcf3ce44SJohn Forte return (err); 495*fcf3ce44SJohn Forte } 496*fcf3ce44SJohn Forte if ((err = l_get_ses_path(path_struct->p_physical_path, 497*fcf3ce44SJohn Forte ses_path, &map, verbose)) != 0) { 498*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 499*fcf3ce44SJohn Forte free((void *)map.dev_addr); 500*fcf3ce44SJohn Forte return (err); 501*fcf3ce44SJohn Forte } 502*fcf3ce44SJohn Forte if ((err = l_get_status(ses_path, l_state, verbose)) != 0) { 503*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 504*fcf3ce44SJohn Forte free((void *)map.dev_addr); 505*fcf3ce44SJohn Forte return (err); 506*fcf3ce44SJohn Forte } 507*fcf3ce44SJohn Forte 508*fcf3ce44SJohn Forte /* We are passing the disks path */ 509*fcf3ce44SJohn Forte if ((err = l_get_slot(path_struct, l_state, verbose)) != 0) { 510*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 511*fcf3ce44SJohn Forte free((void *)map.dev_addr); 512*fcf3ce44SJohn Forte return (err); 513*fcf3ce44SJohn Forte } 514*fcf3ce44SJohn Forte } 515*fcf3ce44SJohn Forte 516*fcf3ce44SJohn Forte if (map.dev_addr != (gfc_port_dev_info_t *)NULL) { 517*fcf3ce44SJohn Forte free((void *)map.dev_addr); 518*fcf3ce44SJohn Forte } 519*fcf3ce44SJohn Forte 520*fcf3ce44SJohn Forte if ((page_buf = (uchar_t *)malloc(MAX_REC_DIAG_LENGTH)) == NULL) { 521*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 522*fcf3ce44SJohn Forte return (errno); 523*fcf3ce44SJohn Forte } 524*fcf3ce44SJohn Forte 525*fcf3ce44SJohn Forte if ((fd = g_object_open(ses_path, O_NDELAY | O_RDWR)) == -1) { 526*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 527*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 528*fcf3ce44SJohn Forte return (errno); 529*fcf3ce44SJohn Forte } 530*fcf3ce44SJohn Forte 531*fcf3ce44SJohn Forte if (err = l_get_envsen_page(fd, page_buf, MAX_REC_DIAG_LENGTH, 532*fcf3ce44SJohn Forte L_PAGE_2, verbose)) { 533*fcf3ce44SJohn Forte (void) close(fd); 534*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 535*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 536*fcf3ce44SJohn Forte return (err); 537*fcf3ce44SJohn Forte } 538*fcf3ce44SJohn Forte 539*fcf3ce44SJohn Forte page_len = (page_buf[2] << 8 | page_buf[3]) + HEADER_LEN; 540*fcf3ce44SJohn Forte 541*fcf3ce44SJohn Forte /* Get index to the disk we are interested in */ 542*fcf3ce44SJohn Forte if (err = l_get_status(ses_path, l_state, verbose)) { 543*fcf3ce44SJohn Forte (void) close(fd); 544*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 545*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 546*fcf3ce44SJohn Forte return (err); 547*fcf3ce44SJohn Forte } 548*fcf3ce44SJohn Forte /* 549*fcf3ce44SJohn Forte * Now that we have the status check to see if 550*fcf3ce44SJohn Forte * busy or reserved, if bypassing. 551*fcf3ce44SJohn Forte */ 552*fcf3ce44SJohn Forte if ((!(force_flag | path_struct->ib_path_flag)) && 553*fcf3ce44SJohn Forte bypass_flag) { 554*fcf3ce44SJohn Forte i = path_struct->slot; 555*fcf3ce44SJohn Forte f_flag = path_struct->f_flag; 556*fcf3ce44SJohn Forte 557*fcf3ce44SJohn Forte /* 558*fcf3ce44SJohn Forte * Check for reservation and busy 559*fcf3ce44SJohn Forte */ 560*fcf3ce44SJohn Forte if ((f_flag && 561*fcf3ce44SJohn Forte (l_state->drv_front[i].g_disk_state.d_state_flags[port_a_flag] & 562*fcf3ce44SJohn Forte L_RESERVED)) || (!f_flag && 563*fcf3ce44SJohn Forte (l_state->drv_rear[i].g_disk_state.d_state_flags[port_a_flag] & 564*fcf3ce44SJohn Forte L_RESERVED))) { 565*fcf3ce44SJohn Forte (void) close(fd); 566*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 567*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 568*fcf3ce44SJohn Forte return (L_BP_RESERVED); 569*fcf3ce44SJohn Forte } 570*fcf3ce44SJohn Forte if (f_flag) { 571*fcf3ce44SJohn Forte if (port_a_flag) { 572*fcf3ce44SJohn Forte if ((err = g_get_port_multipath( 573*fcf3ce44SJohn Forte l_state->drv_front[i].g_disk_state.port_a_wwn_s, 574*fcf3ce44SJohn Forte &p_list, verbose)) != 0) { 575*fcf3ce44SJohn Forte (void) close(fd); 576*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 577*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 578*fcf3ce44SJohn Forte return (err); 579*fcf3ce44SJohn Forte } 580*fcf3ce44SJohn Forte } else { 581*fcf3ce44SJohn Forte if ((err = g_get_port_multipath( 582*fcf3ce44SJohn Forte l_state->drv_front[i].g_disk_state.port_b_wwn_s, 583*fcf3ce44SJohn Forte &p_list, verbose)) != 0) { 584*fcf3ce44SJohn Forte (void) close(fd); 585*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 586*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 587*fcf3ce44SJohn Forte return (err); 588*fcf3ce44SJohn Forte } 589*fcf3ce44SJohn Forte } 590*fcf3ce44SJohn Forte } else { 591*fcf3ce44SJohn Forte if (port_a_flag) { 592*fcf3ce44SJohn Forte if ((err = g_get_port_multipath( 593*fcf3ce44SJohn Forte l_state->drv_rear[i].g_disk_state.port_a_wwn_s, 594*fcf3ce44SJohn Forte &p_list, verbose)) != 0) { 595*fcf3ce44SJohn Forte (void) close(fd); 596*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 597*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 598*fcf3ce44SJohn Forte return (err); 599*fcf3ce44SJohn Forte } 600*fcf3ce44SJohn Forte } else { 601*fcf3ce44SJohn Forte if ((err = g_get_port_multipath( 602*fcf3ce44SJohn Forte l_state->drv_rear[i].g_disk_state.port_b_wwn_s, 603*fcf3ce44SJohn Forte &p_list, verbose)) != 0) { 604*fcf3ce44SJohn Forte (void) close(fd); 605*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 606*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 607*fcf3ce44SJohn Forte return (err); 608*fcf3ce44SJohn Forte } 609*fcf3ce44SJohn Forte } 610*fcf3ce44SJohn Forte } 611*fcf3ce44SJohn Forte if (err = d_offline_drive(p_list, 612*fcf3ce44SJohn Forte &bsy_flag, verbose)) { 613*fcf3ce44SJohn Forte (void) g_free_multipath(p_list); 614*fcf3ce44SJohn Forte (void) close(fd); 615*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 616*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 617*fcf3ce44SJohn Forte return (err); 618*fcf3ce44SJohn Forte } 619*fcf3ce44SJohn Forte (void) g_free_multipath(p_list); 620*fcf3ce44SJohn Forte if (bsy_flag) { 621*fcf3ce44SJohn Forte (void) close(fd); 622*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 623*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 624*fcf3ce44SJohn Forte return (L_BP_BUSY); 625*fcf3ce44SJohn Forte } 626*fcf3ce44SJohn Forte } 627*fcf3ce44SJohn Forte 628*fcf3ce44SJohn Forte if (err = l_get_disk_element_index(l_state, &front_index, 629*fcf3ce44SJohn Forte &rear_index)) { 630*fcf3ce44SJohn Forte (void) close(fd); 631*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 632*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 633*fcf3ce44SJohn Forte return (err); 634*fcf3ce44SJohn Forte } 635*fcf3ce44SJohn Forte 636*fcf3ce44SJohn Forte if (g_get_inquiry(ses_path, &inq)) { 637*fcf3ce44SJohn Forte return (L_SCSI_ERROR); 638*fcf3ce44SJohn Forte } 639*fcf3ce44SJohn Forte 640*fcf3ce44SJohn Forte /* Skip global element */ 641*fcf3ce44SJohn Forte front_index++; 642*fcf3ce44SJohn Forte if ((strncmp((char *)&inq.inq_pid[0], DAK_OFF_NAME, 643*fcf3ce44SJohn Forte strlen(DAK_OFF_NAME)) == 0) || 644*fcf3ce44SJohn Forte (strncmp((char *)&inq.inq_pid[0], DAK_PROD_STR, 645*fcf3ce44SJohn Forte strlen(DAK_PROD_STR)) == 0)) { 646*fcf3ce44SJohn Forte rear_index += (MAX_DRIVES_DAK/2) + 1; 647*fcf3ce44SJohn Forte } else { 648*fcf3ce44SJohn Forte rear_index++; 649*fcf3ce44SJohn Forte } 650*fcf3ce44SJohn Forte 651*fcf3ce44SJohn Forte if (path_struct->f_flag) { 652*fcf3ce44SJohn Forte offset = (8 + (front_index + path_struct->slot)*4); 653*fcf3ce44SJohn Forte } else { 654*fcf3ce44SJohn Forte offset = (8 + (rear_index + path_struct->slot)*4); 655*fcf3ce44SJohn Forte } 656*fcf3ce44SJohn Forte 657*fcf3ce44SJohn Forte elem = (struct device_element *)(page_buf + offset); 658*fcf3ce44SJohn Forte /* 659*fcf3ce44SJohn Forte * now do requested action. 660*fcf3ce44SJohn Forte */ 661*fcf3ce44SJohn Forte bcopy((const void *)elem, (void *)&status, 662*fcf3ce44SJohn Forte sizeof (struct device_element)); /* save status */ 663*fcf3ce44SJohn Forte bzero(elem, sizeof (struct device_element)); 664*fcf3ce44SJohn Forte elem->select = 1; 665*fcf3ce44SJohn Forte elem->dev_off = status.dev_off; 666*fcf3ce44SJohn Forte elem->en_bypass_a = status.en_bypass_a; 667*fcf3ce44SJohn Forte elem->en_bypass_b = status.en_bypass_b; 668*fcf3ce44SJohn Forte 669*fcf3ce44SJohn Forte /* Do requested action */ 670*fcf3ce44SJohn Forte if (port_a_flag) { 671*fcf3ce44SJohn Forte elem->en_bypass_a = bypass_flag; 672*fcf3ce44SJohn Forte } else { 673*fcf3ce44SJohn Forte elem->en_bypass_b = bypass_flag; 674*fcf3ce44SJohn Forte } 675*fcf3ce44SJohn Forte 676*fcf3ce44SJohn Forte if (getenv("_LUX_E_DEBUG") != NULL) { 677*fcf3ce44SJohn Forte g_dump(" l_dev_bypass_enable: Updating LRC circuit state:\n" 678*fcf3ce44SJohn Forte " Device Status Element ", 679*fcf3ce44SJohn Forte (uchar_t *)elem, sizeof (struct device_element), 680*fcf3ce44SJohn Forte HEX_ONLY); 681*fcf3ce44SJohn Forte (void) fprintf(stdout, " for device at location:" 682*fcf3ce44SJohn Forte " enclosure:%s slot:%d %s\n", 683*fcf3ce44SJohn Forte l_state->ib_tbl.enclosure_name, 684*fcf3ce44SJohn Forte path_struct->slot, 685*fcf3ce44SJohn Forte path_struct->f_flag ? "front" : "rear"); 686*fcf3ce44SJohn Forte } 687*fcf3ce44SJohn Forte if (err = g_scsi_send_diag_cmd(fd, 688*fcf3ce44SJohn Forte (uchar_t *)page_buf, page_len)) { 689*fcf3ce44SJohn Forte (void) close(fd); 690*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 691*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 692*fcf3ce44SJohn Forte return (err); 693*fcf3ce44SJohn Forte } 694*fcf3ce44SJohn Forte 695*fcf3ce44SJohn Forte (void) close(fd); 696*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 697*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 698*fcf3ce44SJohn Forte return (0); 699*fcf3ce44SJohn Forte } 700*fcf3ce44SJohn Forte 701*fcf3ce44SJohn Forte 702*fcf3ce44SJohn Forte 703*fcf3ce44SJohn Forte /* 704*fcf3ce44SJohn Forte * Issue a Loop Port enable Primitive sequence 705*fcf3ce44SJohn Forte * to the device specified by the pathname. 706*fcf3ce44SJohn Forte */ 707*fcf3ce44SJohn Forte int 708*fcf3ce44SJohn Forte d_p_enable(char *path, int verbose) 709*fcf3ce44SJohn Forte /*ARGSUSED*/ 710*fcf3ce44SJohn Forte { 711*fcf3ce44SJohn Forte 712*fcf3ce44SJohn Forte return (0); 713*fcf3ce44SJohn Forte } 714*fcf3ce44SJohn Forte 715*fcf3ce44SJohn Forte /* 716*fcf3ce44SJohn Forte * Issue a Loop Port Bypass Primitive sequence 717*fcf3ce44SJohn Forte * to the device specified by the pathname. This requests the 718*fcf3ce44SJohn Forte * device to set its L_Port into the bypass mode. 719*fcf3ce44SJohn Forte */ 720*fcf3ce44SJohn Forte int 721*fcf3ce44SJohn Forte d_p_bypass(char *path, int verbose) 722*fcf3ce44SJohn Forte /*ARGSUSED*/ 723*fcf3ce44SJohn Forte { 724*fcf3ce44SJohn Forte 725*fcf3ce44SJohn Forte return (0); 726*fcf3ce44SJohn Forte } 727