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 * I18N message number ranges 31*fcf3ce44SJohn Forte * This file: 9000 - 9499 32*fcf3ce44SJohn Forte * Shared common messages: 1 - 1999 33*fcf3ce44SJohn Forte */ 34*fcf3ce44SJohn Forte 35*fcf3ce44SJohn Forte /* 36*fcf3ce44SJohn Forte * This module is part of the photon library 37*fcf3ce44SJohn Forte */ 38*fcf3ce44SJohn Forte /* Includes */ 39*fcf3ce44SJohn Forte #include <stdlib.h> 40*fcf3ce44SJohn Forte #include <stdio.h> 41*fcf3ce44SJohn Forte #include <sys/file.h> 42*fcf3ce44SJohn Forte #include <sys/types.h> 43*fcf3ce44SJohn Forte #include <sys/stat.h> 44*fcf3ce44SJohn Forte #include <sys/param.h> 45*fcf3ce44SJohn Forte #include <fcntl.h> 46*fcf3ce44SJohn Forte #include <unistd.h> 47*fcf3ce44SJohn Forte #include <errno.h> 48*fcf3ce44SJohn Forte #include <string.h> 49*fcf3ce44SJohn Forte #include <assert.h> 50*fcf3ce44SJohn Forte #include <sys/scsi/scsi.h> 51*fcf3ce44SJohn Forte #include <dirent.h> /* for DIR */ 52*fcf3ce44SJohn Forte #include <sys/vtoc.h> 53*fcf3ce44SJohn Forte #include <sys/dkio.h> 54*fcf3ce44SJohn Forte #include <nl_types.h> 55*fcf3ce44SJohn Forte #include <strings.h> 56*fcf3ce44SJohn Forte #include <sys/ddi.h> /* for max */ 57*fcf3ce44SJohn Forte #include <l_common.h> 58*fcf3ce44SJohn Forte #include <stgcom.h> 59*fcf3ce44SJohn Forte #include <l_error.h> 60*fcf3ce44SJohn Forte #include <rom.h> 61*fcf3ce44SJohn Forte #include <exec.h> 62*fcf3ce44SJohn Forte #include <a_state.h> 63*fcf3ce44SJohn Forte #include <a5k.h> 64*fcf3ce44SJohn Forte 65*fcf3ce44SJohn Forte 66*fcf3ce44SJohn Forte /* Defines */ 67*fcf3ce44SJohn Forte #define PLNDEF "SUNW,pln" /* check if box name starts with 'c' */ 68*fcf3ce44SJohn Forte #define DOWNLOAD_RETRIES 60*5 /* 5 minutes */ 69*fcf3ce44SJohn Forte #define IBFIRMWARE_FILE "/usr/lib/locale/C/LC_MESSAGES/ibfirmware" 70*fcf3ce44SJohn Forte 71*fcf3ce44SJohn Forte /* Global variables */ 72*fcf3ce44SJohn Forte extern uchar_t g_switch_to_alpa[]; 73*fcf3ce44SJohn Forte extern uchar_t g_sf_alpa_to_switch[]; 74*fcf3ce44SJohn Forte 75*fcf3ce44SJohn Forte /* Forward declarations */ 76*fcf3ce44SJohn Forte static int pwr_up_down(char *, L_state *, int, int, int, int); 77*fcf3ce44SJohn Forte static int load_flds_if_enc_disk(char *, struct path_struct **); 78*fcf3ce44SJohn Forte static int copy_config_page(struct l_state_struct *, uchar_t *); 79*fcf3ce44SJohn Forte static void copy_page_7(struct l_state_struct *, uchar_t *); 80*fcf3ce44SJohn Forte static int l_get_node_status(char *, struct l_disk_state_struct *, 81*fcf3ce44SJohn Forte int *, WWN_list *, int); 82*fcf3ce44SJohn Forte static int check_file(int, int, uchar_t **, int); 83*fcf3ce44SJohn Forte static int check_dpm_file(int); 84*fcf3ce44SJohn Forte static int ib_download_code_cmd(int, int, int, uchar_t *, int, int); 85*fcf3ce44SJohn Forte static int dak_download_code_cmd(int, uchar_t *, int); 86*fcf3ce44SJohn Forte static void free_mp_dev_map(struct gfc_map_mp **); 87*fcf3ce44SJohn Forte static int get_mp_dev_map(char *, struct gfc_map_mp **, int); 88*fcf3ce44SJohn Forte 89*fcf3ce44SJohn Forte /* 90*fcf3ce44SJohn Forte * l_get_mode_pg() - Read all mode pages. 91*fcf3ce44SJohn Forte * 92*fcf3ce44SJohn Forte * RETURNS: 93*fcf3ce44SJohn Forte * 0 O.K. 94*fcf3ce44SJohn Forte * non-zero otherwise 95*fcf3ce44SJohn Forte * 96*fcf3ce44SJohn Forte * INPUTS: 97*fcf3ce44SJohn Forte * path pointer to device path 98*fcf3ce44SJohn Forte * pg_buf ptr to mode pages 99*fcf3ce44SJohn Forte * 100*fcf3ce44SJohn Forte */ 101*fcf3ce44SJohn Forte /*ARGSUSED*/ 102*fcf3ce44SJohn Forte int 103*fcf3ce44SJohn Forte l_get_mode_pg(char *path, uchar_t **pg_buf, int verbose) 104*fcf3ce44SJohn Forte { 105*fcf3ce44SJohn Forte Mode_header_10 *mode_header_ptr; 106*fcf3ce44SJohn Forte int status, size, fd; 107*fcf3ce44SJohn Forte 108*fcf3ce44SJohn Forte P_DPRINTF(" l_get_mode_pg: Reading Mode Sense pages.\n"); 109*fcf3ce44SJohn Forte 110*fcf3ce44SJohn Forte /* do not do mode sense if this is a tape device */ 111*fcf3ce44SJohn Forte /* mode sense will rewind the tape */ 112*fcf3ce44SJohn Forte if (strstr(path, SLSH_DRV_NAME_ST)) { 113*fcf3ce44SJohn Forte return (-1); 114*fcf3ce44SJohn Forte } 115*fcf3ce44SJohn Forte 116*fcf3ce44SJohn Forte /* open controller */ 117*fcf3ce44SJohn Forte if ((fd = g_object_open(path, O_NDELAY | O_RDWR)) == -1) 118*fcf3ce44SJohn Forte return (L_OPEN_PATH_FAIL); 119*fcf3ce44SJohn Forte 120*fcf3ce44SJohn Forte /* 121*fcf3ce44SJohn Forte * Read the first part of the page to get the page size 122*fcf3ce44SJohn Forte */ 123*fcf3ce44SJohn Forte size = 20; 124*fcf3ce44SJohn Forte if ((*pg_buf = (uchar_t *)g_zalloc(size)) == NULL) { 125*fcf3ce44SJohn Forte (void) close(fd); 126*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 127*fcf3ce44SJohn Forte } 128*fcf3ce44SJohn Forte /* read page */ 129*fcf3ce44SJohn Forte if (status = g_scsi_mode_sense_cmd(fd, *pg_buf, size, 130*fcf3ce44SJohn Forte 0, MODEPAGE_ALLPAGES)) { 131*fcf3ce44SJohn Forte (void) close(fd); 132*fcf3ce44SJohn Forte (void) g_destroy_data((char *)*pg_buf); 133*fcf3ce44SJohn Forte return (status); 134*fcf3ce44SJohn Forte } 135*fcf3ce44SJohn Forte /* Now get the size for all pages */ 136*fcf3ce44SJohn Forte mode_header_ptr = (struct mode_header_10_struct *)(void *)*pg_buf; 137*fcf3ce44SJohn Forte size = mode_header_ptr->length + sizeof (mode_header_ptr->length); 138*fcf3ce44SJohn Forte (void) g_destroy_data((char *)*pg_buf); 139*fcf3ce44SJohn Forte if ((*pg_buf = (uchar_t *)g_zalloc(size)) == NULL) { 140*fcf3ce44SJohn Forte (void) close(fd); 141*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 142*fcf3ce44SJohn Forte } 143*fcf3ce44SJohn Forte /* read all pages */ 144*fcf3ce44SJohn Forte if (status = g_scsi_mode_sense_cmd(fd, *pg_buf, size, 145*fcf3ce44SJohn Forte 0, MODEPAGE_ALLPAGES)) { 146*fcf3ce44SJohn Forte (void) close(fd); 147*fcf3ce44SJohn Forte (void) g_destroy_data((char *)*pg_buf); 148*fcf3ce44SJohn Forte return (status); 149*fcf3ce44SJohn Forte } 150*fcf3ce44SJohn Forte (void) close(fd); 151*fcf3ce44SJohn Forte return (0); 152*fcf3ce44SJohn Forte } 153*fcf3ce44SJohn Forte 154*fcf3ce44SJohn Forte 155*fcf3ce44SJohn Forte 156*fcf3ce44SJohn Forte /* 157*fcf3ce44SJohn Forte * Format QLA21xx status 158*fcf3ce44SJohn Forte * 159*fcf3ce44SJohn Forte * INPUTS: message buffer 160*fcf3ce44SJohn Forte * Count 161*fcf3ce44SJohn Forte * status 162*fcf3ce44SJohn Forte * 163*fcf3ce44SJohn Forte * OUTPUT: Message of this format in message buffer 164*fcf3ce44SJohn Forte * "status type: 0xstatus count" 165*fcf3ce44SJohn Forte */ 166*fcf3ce44SJohn Forte int 167*fcf3ce44SJohn Forte l_format_ifp_status_msg(char *status_msg_buf, int count, int status) 168*fcf3ce44SJohn Forte { 169*fcf3ce44SJohn Forte if (status_msg_buf == NULL) { 170*fcf3ce44SJohn Forte return (0); 171*fcf3ce44SJohn Forte } 172*fcf3ce44SJohn Forte 173*fcf3ce44SJohn Forte switch (status) { 174*fcf3ce44SJohn Forte case IFP_CMD_CMPLT: 175*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 176*fcf3ce44SJohn Forte MSGSTR(9000, "O.K. 0x%-2x" 177*fcf3ce44SJohn Forte " %d"), status, count); 178*fcf3ce44SJohn Forte break; 179*fcf3ce44SJohn Forte case IFP_CMD_INCOMPLETE: 180*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 181*fcf3ce44SJohn Forte MSGSTR(9001, "Cmd incomplete 0x%-2x" 182*fcf3ce44SJohn Forte " %d"), status, count); 183*fcf3ce44SJohn Forte break; 184*fcf3ce44SJohn Forte case IFP_CMD_DMA_DERR: 185*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 186*fcf3ce44SJohn Forte MSGSTR(9002, "DMA direction error 0x%-2x" 187*fcf3ce44SJohn Forte " %d"), status, count); 188*fcf3ce44SJohn Forte break; 189*fcf3ce44SJohn Forte case IFP_CMD_TRAN_ERR: 190*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 191*fcf3ce44SJohn Forte MSGSTR(9003, "Unspecified transport error 0x%-2x" 192*fcf3ce44SJohn Forte " %d"), status, count); 193*fcf3ce44SJohn Forte break; 194*fcf3ce44SJohn Forte case IFP_CMD_RESET: 195*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 196*fcf3ce44SJohn Forte MSGSTR(9004, "Reset aborted transport 0x%-2x" 197*fcf3ce44SJohn Forte " %d"), status, count); 198*fcf3ce44SJohn Forte break; 199*fcf3ce44SJohn Forte case IFP_CMD_ABORTED: 200*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 201*fcf3ce44SJohn Forte MSGSTR(9005, "Cmd aborted 0x%-2x" 202*fcf3ce44SJohn Forte " %d"), status, count); 203*fcf3ce44SJohn Forte break; 204*fcf3ce44SJohn Forte case IFP_CMD_TIMEOUT: 205*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 206*fcf3ce44SJohn Forte MSGSTR(9006, "Cmd Timeout 0x%-2x" 207*fcf3ce44SJohn Forte " %d"), status, count); 208*fcf3ce44SJohn Forte break; 209*fcf3ce44SJohn Forte case IFP_CMD_DATA_OVR: 210*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 211*fcf3ce44SJohn Forte MSGSTR(9007, "Data Overrun 0x%-2x" 212*fcf3ce44SJohn Forte " %d"), status, count); 213*fcf3ce44SJohn Forte break; 214*fcf3ce44SJohn Forte case IFP_CMD_ABORT_REJECTED: 215*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 216*fcf3ce44SJohn Forte MSGSTR(9008, "Target rejected abort msg 0x%-2x" 217*fcf3ce44SJohn Forte " %d"), status, count); 218*fcf3ce44SJohn Forte break; 219*fcf3ce44SJohn Forte case IFP_CMD_RESET_REJECTED: 220*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 221*fcf3ce44SJohn Forte MSGSTR(9009, "Target rejected reset msg 0x%-2x" 222*fcf3ce44SJohn Forte " %d"), status, count); 223*fcf3ce44SJohn Forte break; 224*fcf3ce44SJohn Forte case IFP_CMD_DATA_UNDER: 225*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 226*fcf3ce44SJohn Forte MSGSTR(9010, "Data underrun 0x%-2x" 227*fcf3ce44SJohn Forte " %d"), status, count); 228*fcf3ce44SJohn Forte break; 229*fcf3ce44SJohn Forte case IFP_CMD_QUEUE_FULL: 230*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 231*fcf3ce44SJohn Forte MSGSTR(9011, "Queue full SCSI status 0x%-2x" 232*fcf3ce44SJohn Forte " %d"), status, count); 233*fcf3ce44SJohn Forte break; 234*fcf3ce44SJohn Forte case IFP_CMD_PORT_UNAVAIL: 235*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 236*fcf3ce44SJohn Forte MSGSTR(9012, "Port unavailable 0x%-2x" 237*fcf3ce44SJohn Forte " %d"), status, count); 238*fcf3ce44SJohn Forte break; 239*fcf3ce44SJohn Forte case IFP_CMD_PORT_LOGGED_OUT: 240*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 241*fcf3ce44SJohn Forte MSGSTR(9013, "Port loged out 0x%-2x" 242*fcf3ce44SJohn Forte " %d"), status, count); 243*fcf3ce44SJohn Forte break; 244*fcf3ce44SJohn Forte case IFP_CMD_PORT_CONFIG_CHANGED: 245*fcf3ce44SJohn Forte /* Not enough packets for given request */ 246*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 247*fcf3ce44SJohn Forte MSGSTR(9014, "Port name changed 0x%-2x" 248*fcf3ce44SJohn Forte " %d"), status, count); 249*fcf3ce44SJohn Forte break; 250*fcf3ce44SJohn Forte default: 251*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 252*fcf3ce44SJohn Forte "%s 0x%-2x" 253*fcf3ce44SJohn Forte " %d", MSGSTR(4, "Unknown status"), 254*fcf3ce44SJohn Forte status, count); 255*fcf3ce44SJohn Forte 256*fcf3ce44SJohn Forte } /* End of switch() */ 257*fcf3ce44SJohn Forte 258*fcf3ce44SJohn Forte return (0); 259*fcf3ce44SJohn Forte 260*fcf3ce44SJohn Forte } 261*fcf3ce44SJohn Forte 262*fcf3ce44SJohn Forte 263*fcf3ce44SJohn Forte 264*fcf3ce44SJohn Forte /* 265*fcf3ce44SJohn Forte * Format Fibre Channel status 266*fcf3ce44SJohn Forte * 267*fcf3ce44SJohn Forte * INPUTS: message buffer 268*fcf3ce44SJohn Forte * Count 269*fcf3ce44SJohn Forte * status 270*fcf3ce44SJohn Forte * 271*fcf3ce44SJohn Forte * OUTPUT: Message of this format in message buffer 272*fcf3ce44SJohn Forte * "status type: 0xstatus count" 273*fcf3ce44SJohn Forte */ 274*fcf3ce44SJohn Forte int 275*fcf3ce44SJohn Forte l_format_fc_status_msg(char *status_msg_buf, int count, int status) 276*fcf3ce44SJohn Forte { 277*fcf3ce44SJohn Forte if (status_msg_buf == NULL) { 278*fcf3ce44SJohn Forte return (0); 279*fcf3ce44SJohn Forte } 280*fcf3ce44SJohn Forte 281*fcf3ce44SJohn Forte switch (status) { 282*fcf3ce44SJohn Forte case FCAL_STATUS_OK: 283*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 284*fcf3ce44SJohn Forte MSGSTR(9015, "O.K. 0x%-2x" 285*fcf3ce44SJohn Forte " %d"), status, count); 286*fcf3ce44SJohn Forte break; 287*fcf3ce44SJohn Forte case FCAL_STATUS_P_RJT: 288*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 289*fcf3ce44SJohn Forte MSGSTR(9016, "P_RJT (Frame Rejected) 0x%-2x" 290*fcf3ce44SJohn Forte " %d"), status, count); 291*fcf3ce44SJohn Forte break; 292*fcf3ce44SJohn Forte case FCAL_STATUS_F_RJT: 293*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 294*fcf3ce44SJohn Forte MSGSTR(9017, "F_RJT (Frame Rejected) 0x%-2x" 295*fcf3ce44SJohn Forte " %d"), status, count); 296*fcf3ce44SJohn Forte break; 297*fcf3ce44SJohn Forte case FCAL_STATUS_P_BSY: 298*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 299*fcf3ce44SJohn Forte MSGSTR(9018, "P_BSY (Port Busy) 0x%-2x" 300*fcf3ce44SJohn Forte " %d"), status, count); 301*fcf3ce44SJohn Forte break; 302*fcf3ce44SJohn Forte case FCAL_STATUS_F_BSY: 303*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 304*fcf3ce44SJohn Forte MSGSTR(9019, "F_BSY (Port Busy) 0x%-2x" 305*fcf3ce44SJohn Forte " %d"), status, count); 306*fcf3ce44SJohn Forte break; 307*fcf3ce44SJohn Forte case FCAL_STATUS_OLDPORT_ONLINE: 308*fcf3ce44SJohn Forte /* Should not happen. */ 309*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 310*fcf3ce44SJohn Forte MSGSTR(9020, "Old port Online 0x%-2x" 311*fcf3ce44SJohn Forte " %d"), status, count); 312*fcf3ce44SJohn Forte break; 313*fcf3ce44SJohn Forte case FCAL_STATUS_ERR_OFFLINE: 314*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 315*fcf3ce44SJohn Forte MSGSTR(9021, "Link Offline 0x%-2x" 316*fcf3ce44SJohn Forte " %d"), status, count); 317*fcf3ce44SJohn Forte break; 318*fcf3ce44SJohn Forte case FCAL_STATUS_TIMEOUT: 319*fcf3ce44SJohn Forte /* Should not happen. */ 320*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 321*fcf3ce44SJohn Forte MSGSTR(9022, "Sequence Timeout 0x%-2x" 322*fcf3ce44SJohn Forte " %d"), status, count); 323*fcf3ce44SJohn Forte break; 324*fcf3ce44SJohn Forte case FCAL_STATUS_ERR_OVERRUN: 325*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 326*fcf3ce44SJohn Forte MSGSTR(9023, "Sequence Payload Overrun 0x%-2x" 327*fcf3ce44SJohn Forte " %d"), status, count); 328*fcf3ce44SJohn Forte break; 329*fcf3ce44SJohn Forte case FCAL_STATUS_LOOP_ONLINE: 330*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 331*fcf3ce44SJohn Forte MSGSTR(9060, "Loop Online 0x%-2x" 332*fcf3ce44SJohn Forte " %d"), status, count); 333*fcf3ce44SJohn Forte break; 334*fcf3ce44SJohn Forte case FCAL_STATUS_OLD_PORT: 335*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 336*fcf3ce44SJohn Forte MSGSTR(9061, "Old port 0x%-2x" 337*fcf3ce44SJohn Forte " %d"), status, count); 338*fcf3ce44SJohn Forte break; 339*fcf3ce44SJohn Forte case FCAL_STATUS_AL_PORT: 340*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 341*fcf3ce44SJohn Forte MSGSTR(9062, "AL port 0x%-2x" 342*fcf3ce44SJohn Forte " %d"), status, count); 343*fcf3ce44SJohn Forte break; 344*fcf3ce44SJohn Forte case FCAL_STATUS_UNKNOWN_CQ_TYPE: 345*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 346*fcf3ce44SJohn Forte MSGSTR(9024, "Unknown request type 0x%-2x" 347*fcf3ce44SJohn Forte " %d"), status, count); 348*fcf3ce44SJohn Forte break; 349*fcf3ce44SJohn Forte case FCAL_STATUS_BAD_SEG_CNT: 350*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 351*fcf3ce44SJohn Forte MSGSTR(9025, "Bad segment count 0x%-2x" 352*fcf3ce44SJohn Forte " %d"), status, count); 353*fcf3ce44SJohn Forte break; 354*fcf3ce44SJohn Forte case FCAL_STATUS_MAX_XCHG_EXCEEDED: 355*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 356*fcf3ce44SJohn Forte MSGSTR(9026, "Maximum exchanges exceeded 0x%-2x" 357*fcf3ce44SJohn Forte " %d"), status, count); 358*fcf3ce44SJohn Forte break; 359*fcf3ce44SJohn Forte case FCAL_STATUS_BAD_XID: 360*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 361*fcf3ce44SJohn Forte MSGSTR(9027, "Bad exchange identifier 0x%-2x" 362*fcf3ce44SJohn Forte " %d"), status, count); 363*fcf3ce44SJohn Forte break; 364*fcf3ce44SJohn Forte case FCAL_STATUS_XCHG_BUSY: 365*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 366*fcf3ce44SJohn Forte MSGSTR(9028, "Duplicate exchange request 0x%-2x" 367*fcf3ce44SJohn Forte " %d"), status, count); 368*fcf3ce44SJohn Forte break; 369*fcf3ce44SJohn Forte case FCAL_STATUS_BAD_POOL_ID: 370*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 371*fcf3ce44SJohn Forte MSGSTR(9029, "Bad memory pool ID 0x%-2x" 372*fcf3ce44SJohn Forte " %d"), status, count); 373*fcf3ce44SJohn Forte break; 374*fcf3ce44SJohn Forte case FCAL_STATUS_INSUFFICIENT_CQES: 375*fcf3ce44SJohn Forte /* Not enough packets for given request */ 376*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 377*fcf3ce44SJohn Forte MSGSTR(9030, "Invalid # of segments for req 0x%-2x" 378*fcf3ce44SJohn Forte " %d"), status, count); 379*fcf3ce44SJohn Forte break; 380*fcf3ce44SJohn Forte case FCAL_STATUS_ALLOC_FAIL: 381*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 382*fcf3ce44SJohn Forte MSGSTR(9031, "Resource allocation failure 0x%-2x" 383*fcf3ce44SJohn Forte " %d"), status, count); 384*fcf3ce44SJohn Forte break; 385*fcf3ce44SJohn Forte case FCAL_STATUS_BAD_SID: 386*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 387*fcf3ce44SJohn Forte MSGSTR(9032, "Bad Source Identifier(S_ID) 0x%-2x" 388*fcf3ce44SJohn Forte " %d"), status, count); 389*fcf3ce44SJohn Forte break; 390*fcf3ce44SJohn Forte case FCAL_STATUS_NO_SEQ_INIT: 391*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 392*fcf3ce44SJohn Forte MSGSTR(9033, "No sequence initiative 0x%-2x" 393*fcf3ce44SJohn Forte " %d"), status, count); 394*fcf3ce44SJohn Forte break; 395*fcf3ce44SJohn Forte case FCAL_STATUS_BAD_DID: 396*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 397*fcf3ce44SJohn Forte MSGSTR(9034, "Bad Destination ID(D_ID) 0x%-2x" 398*fcf3ce44SJohn Forte " %d"), status, count); 399*fcf3ce44SJohn Forte break; 400*fcf3ce44SJohn Forte case FCAL_STATUS_ABORTED: 401*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 402*fcf3ce44SJohn Forte MSGSTR(9035, "Received BA_ACC from abort 0x%-2x" 403*fcf3ce44SJohn Forte " %d"), status, count); 404*fcf3ce44SJohn Forte break; 405*fcf3ce44SJohn Forte case FCAL_STATUS_ABORT_FAILED: 406*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 407*fcf3ce44SJohn Forte MSGSTR(9036, "Received BA_RJT from abort 0x%-2x" 408*fcf3ce44SJohn Forte " %d"), status, count); 409*fcf3ce44SJohn Forte break; 410*fcf3ce44SJohn Forte case FCAL_STATUS_DIAG_BUSY: 411*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 412*fcf3ce44SJohn Forte MSGSTR(9037, "Diagnostics currently busy 0x%-2x" 413*fcf3ce44SJohn Forte " %d"), status, count); 414*fcf3ce44SJohn Forte break; 415*fcf3ce44SJohn Forte case FCAL_STATUS_DIAG_INVALID: 416*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 417*fcf3ce44SJohn Forte MSGSTR(9038, "Diagnostics illegal request 0x%-2x" 418*fcf3ce44SJohn Forte " %d"), status, count); 419*fcf3ce44SJohn Forte break; 420*fcf3ce44SJohn Forte case FCAL_STATUS_INCOMPLETE_DMA_ERR: 421*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 422*fcf3ce44SJohn Forte MSGSTR(9039, "SBus DMA did not complete 0x%-2x" 423*fcf3ce44SJohn Forte " %d"), status, count); 424*fcf3ce44SJohn Forte break; 425*fcf3ce44SJohn Forte case FCAL_STATUS_CRC_ERR: 426*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 427*fcf3ce44SJohn Forte MSGSTR(9040, "CRC error detected 0x%-2x" 428*fcf3ce44SJohn Forte " %d"), status, count); 429*fcf3ce44SJohn Forte break; 430*fcf3ce44SJohn Forte case FCAL_STATUS_OPEN_FAIL: 431*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 432*fcf3ce44SJohn Forte MSGSTR(9063, "Open failure 0x%-2x" 433*fcf3ce44SJohn Forte " %d"), status, count); 434*fcf3ce44SJohn Forte break; 435*fcf3ce44SJohn Forte case FCAL_STATUS_ERROR: 436*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 437*fcf3ce44SJohn Forte MSGSTR(9041, "Invalid status error 0x%-2x" 438*fcf3ce44SJohn Forte " %d"), status, count); 439*fcf3ce44SJohn Forte break; 440*fcf3ce44SJohn Forte case FCAL_STATUS_ONLINE_TIMEOUT: 441*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 442*fcf3ce44SJohn Forte MSGSTR(9042, "Timed out before ONLINE 0x%-2x" 443*fcf3ce44SJohn Forte " %d"), status, count); 444*fcf3ce44SJohn Forte break; 445*fcf3ce44SJohn Forte default: 446*fcf3ce44SJohn Forte (void) sprintf(status_msg_buf, 447*fcf3ce44SJohn Forte "%s 0x%-2x" 448*fcf3ce44SJohn Forte " %d", MSGSTR(4, "Unknown status"), 449*fcf3ce44SJohn Forte status, count); 450*fcf3ce44SJohn Forte 451*fcf3ce44SJohn Forte } /* End of switch() */ 452*fcf3ce44SJohn Forte 453*fcf3ce44SJohn Forte return (0); 454*fcf3ce44SJohn Forte 455*fcf3ce44SJohn Forte } 456*fcf3ce44SJohn Forte 457*fcf3ce44SJohn Forte 458*fcf3ce44SJohn Forte 459*fcf3ce44SJohn Forte /* 460*fcf3ce44SJohn Forte * Get the indexes to the disk device elements in page 2, 461*fcf3ce44SJohn Forte * based on the locations found in page 1. 462*fcf3ce44SJohn Forte * 463*fcf3ce44SJohn Forte * RETURNS: 464*fcf3ce44SJohn Forte * 0 O.K. 465*fcf3ce44SJohn Forte * non-zero otherwise 466*fcf3ce44SJohn Forte */ 467*fcf3ce44SJohn Forte int 468*fcf3ce44SJohn Forte l_get_disk_element_index(struct l_state_struct *l_state, int *front_index, 469*fcf3ce44SJohn Forte int *rear_index) 470*fcf3ce44SJohn Forte { 471*fcf3ce44SJohn Forte int index = 0, front_flag = 0, local_front = 0, local_rear = 0; 472*fcf3ce44SJohn Forte int i, rear_flag = 0; 473*fcf3ce44SJohn Forte 474*fcf3ce44SJohn Forte if ((l_state == NULL) || (front_index == NULL) || 475*fcf3ce44SJohn Forte (rear_index == NULL)) { 476*fcf3ce44SJohn Forte return (L_INVALID_PATH_FORMAT); 477*fcf3ce44SJohn Forte } 478*fcf3ce44SJohn Forte 479*fcf3ce44SJohn Forte *front_index = *rear_index = 0; 480*fcf3ce44SJohn Forte /* Get the indexes to the disk device elements */ 481*fcf3ce44SJohn Forte for (i = 0; i < (int)l_state->ib_tbl.config.enc_num_elem; i++) { 482*fcf3ce44SJohn Forte if (l_state->ib_tbl.config.type_hdr[i].type == ELM_TYP_DD) { 483*fcf3ce44SJohn Forte if (front_flag) { 484*fcf3ce44SJohn Forte local_rear = index; 485*fcf3ce44SJohn Forte rear_flag = 1; 486*fcf3ce44SJohn Forte break; 487*fcf3ce44SJohn Forte } else { 488*fcf3ce44SJohn Forte local_front = index; 489*fcf3ce44SJohn Forte front_flag = 1; 490*fcf3ce44SJohn Forte } 491*fcf3ce44SJohn Forte } 492*fcf3ce44SJohn Forte index += l_state->ib_tbl.config.type_hdr[i].num; 493*fcf3ce44SJohn Forte index++; /* for global element */ 494*fcf3ce44SJohn Forte } 495*fcf3ce44SJohn Forte 496*fcf3ce44SJohn Forte D_DPRINTF(" l_get_disk_element_index:" 497*fcf3ce44SJohn Forte " Index to front disk elements 0x%x\n" 498*fcf3ce44SJohn Forte " l_get_disk_element_index:" 499*fcf3ce44SJohn Forte " Index to rear disk elements 0x%x\n", 500*fcf3ce44SJohn Forte local_front, local_rear); 501*fcf3ce44SJohn Forte 502*fcf3ce44SJohn Forte if (!front_flag && !rear_flag) { /* neither is found */ 503*fcf3ce44SJohn Forte return (L_RD_NO_DISK_ELEM); 504*fcf3ce44SJohn Forte } 505*fcf3ce44SJohn Forte *front_index = local_front; 506*fcf3ce44SJohn Forte *rear_index = local_rear; 507*fcf3ce44SJohn Forte return (0); 508*fcf3ce44SJohn Forte } 509*fcf3ce44SJohn Forte 510*fcf3ce44SJohn Forte 511*fcf3ce44SJohn Forte 512*fcf3ce44SJohn Forte /* 513*fcf3ce44SJohn Forte * l_led() manage the device led's 514*fcf3ce44SJohn Forte * 515*fcf3ce44SJohn Forte * RETURNS: 516*fcf3ce44SJohn Forte * 0 O.K. 517*fcf3ce44SJohn Forte * non-zero otherwise 518*fcf3ce44SJohn Forte */ 519*fcf3ce44SJohn Forte int 520*fcf3ce44SJohn Forte l_led(struct path_struct *path_struct, int led_action, 521*fcf3ce44SJohn Forte struct device_element *status, 522*fcf3ce44SJohn Forte int verbose) 523*fcf3ce44SJohn Forte { 524*fcf3ce44SJohn Forte gfc_map_t map; 525*fcf3ce44SJohn Forte char ses_path[MAXPATHLEN]; 526*fcf3ce44SJohn Forte uchar_t *page_buf; 527*fcf3ce44SJohn Forte int err, write, fd, front_index, rear_index, offset; 528*fcf3ce44SJohn Forte unsigned short page_len; 529*fcf3ce44SJohn Forte struct device_element *elem; 530*fcf3ce44SJohn Forte L_state *l_state; 531*fcf3ce44SJohn Forte int enc_type; 532*fcf3ce44SJohn Forte 533*fcf3ce44SJohn Forte if ((path_struct == NULL) || (status == NULL)) { 534*fcf3ce44SJohn Forte return (L_INVALID_PATH_FORMAT); 535*fcf3ce44SJohn Forte } 536*fcf3ce44SJohn Forte 537*fcf3ce44SJohn Forte /* 538*fcf3ce44SJohn Forte * Need to get a valid location, front/rear & slot. 539*fcf3ce44SJohn Forte * 540*fcf3ce44SJohn Forte * The path_struct will return a valid slot 541*fcf3ce44SJohn Forte * and the IB path or a disk path. 542*fcf3ce44SJohn Forte */ 543*fcf3ce44SJohn Forte 544*fcf3ce44SJohn Forte map.dev_addr = (gfc_port_dev_info_t *)NULL; 545*fcf3ce44SJohn Forte if (!path_struct->ib_path_flag) { 546*fcf3ce44SJohn Forte if ((err = g_get_dev_map(path_struct->p_physical_path, 547*fcf3ce44SJohn Forte &map, verbose)) != 0) 548*fcf3ce44SJohn Forte return (err); 549*fcf3ce44SJohn Forte if ((err = l_get_ses_path(path_struct->p_physical_path, 550*fcf3ce44SJohn Forte ses_path, &map, verbose)) != 0) { 551*fcf3ce44SJohn Forte free((void *)map.dev_addr); 552*fcf3ce44SJohn Forte return (err); 553*fcf3ce44SJohn Forte } 554*fcf3ce44SJohn Forte } else { 555*fcf3ce44SJohn Forte (void) strcpy(ses_path, path_struct->p_physical_path); 556*fcf3ce44SJohn Forte } 557*fcf3ce44SJohn Forte 558*fcf3ce44SJohn Forte if ((l_state = (L_state *)calloc(1, sizeof (L_state))) == NULL) { 559*fcf3ce44SJohn Forte free((void *)map.dev_addr); 560*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 561*fcf3ce44SJohn Forte } 562*fcf3ce44SJohn Forte 563*fcf3ce44SJohn Forte if (!path_struct->slot_valid) { 564*fcf3ce44SJohn Forte if ((map.dev_addr != NULL) && 565*fcf3ce44SJohn Forte (err = g_get_dev_map(path_struct->p_physical_path, 566*fcf3ce44SJohn Forte &map, verbose)) != 0) { 567*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 568*fcf3ce44SJohn Forte return (err); 569*fcf3ce44SJohn Forte } 570*fcf3ce44SJohn Forte if ((err = l_get_ses_path(path_struct->p_physical_path, 571*fcf3ce44SJohn Forte ses_path, &map, verbose)) != 0) { 572*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 573*fcf3ce44SJohn Forte free((void *)map.dev_addr); 574*fcf3ce44SJohn Forte return (err); 575*fcf3ce44SJohn Forte } 576*fcf3ce44SJohn Forte if ((err = l_get_status(ses_path, l_state, verbose)) != 0) { 577*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 578*fcf3ce44SJohn Forte free((void *)map.dev_addr); 579*fcf3ce44SJohn Forte return (err); 580*fcf3ce44SJohn Forte } 581*fcf3ce44SJohn Forte 582*fcf3ce44SJohn Forte /* We are passing the disks path */ 583*fcf3ce44SJohn Forte if (err = l_get_slot(path_struct, l_state, verbose)) { 584*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 585*fcf3ce44SJohn Forte free((void *)map.dev_addr); 586*fcf3ce44SJohn Forte return (err); 587*fcf3ce44SJohn Forte } 588*fcf3ce44SJohn Forte } 589*fcf3ce44SJohn Forte if (map.dev_addr != NULL) 590*fcf3ce44SJohn Forte free((void *)map.dev_addr); /* Not used anymore */ 591*fcf3ce44SJohn Forte 592*fcf3ce44SJohn Forte if ((page_buf = (uchar_t *)calloc(1, 593*fcf3ce44SJohn Forte MAX_REC_DIAG_LENGTH)) == NULL) { 594*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 595*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 596*fcf3ce44SJohn Forte } 597*fcf3ce44SJohn Forte 598*fcf3ce44SJohn Forte if ((fd = g_object_open(ses_path, O_NDELAY | O_RDWR)) == -1) { 599*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 600*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 601*fcf3ce44SJohn Forte return (L_OPEN_PATH_FAIL); 602*fcf3ce44SJohn Forte } 603*fcf3ce44SJohn Forte 604*fcf3ce44SJohn Forte if (err = l_get_envsen_page(fd, page_buf, MAX_REC_DIAG_LENGTH, 605*fcf3ce44SJohn Forte L_PAGE_2, verbose)) { 606*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 607*fcf3ce44SJohn Forte (void) close(fd); 608*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 609*fcf3ce44SJohn Forte return (err); 610*fcf3ce44SJohn Forte } 611*fcf3ce44SJohn Forte 612*fcf3ce44SJohn Forte page_len = (page_buf[2] << 8 | page_buf[3]) + HEADER_LEN; 613*fcf3ce44SJohn Forte 614*fcf3ce44SJohn Forte /* Get index to the disk we are interested in */ 615*fcf3ce44SJohn Forte if (err = l_get_status(ses_path, l_state, verbose)) { 616*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 617*fcf3ce44SJohn Forte (void) close(fd); 618*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 619*fcf3ce44SJohn Forte return (err); 620*fcf3ce44SJohn Forte } 621*fcf3ce44SJohn Forte 622*fcf3ce44SJohn Forte /* find enclosure type */ 623*fcf3ce44SJohn Forte if ((strncmp((char *)l_state->ib_tbl.config.prod_id, DAK_OFF_NAME, 624*fcf3ce44SJohn Forte strlen(DAK_OFF_NAME)) == 0) || 625*fcf3ce44SJohn Forte (strncmp((char *)l_state->ib_tbl.config.prod_id, DAK_PROD_STR, 626*fcf3ce44SJohn Forte strlen(DAK_PROD_STR)) == 0)) { 627*fcf3ce44SJohn Forte enc_type = DAK_ENC_TYPE; 628*fcf3ce44SJohn Forte } else { 629*fcf3ce44SJohn Forte enc_type = SENA_ENC_TYPE; 630*fcf3ce44SJohn Forte } 631*fcf3ce44SJohn Forte 632*fcf3ce44SJohn Forte /* Double check slot. */ 633*fcf3ce44SJohn Forte if (path_struct->slot >= l_state->total_num_drv/2) { 634*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 635*fcf3ce44SJohn Forte return (L_INVALID_SLOT); 636*fcf3ce44SJohn Forte } 637*fcf3ce44SJohn Forte 638*fcf3ce44SJohn Forte if (err = l_get_disk_element_index(l_state, &front_index, 639*fcf3ce44SJohn Forte &rear_index)) { 640*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 641*fcf3ce44SJohn Forte return (err); 642*fcf3ce44SJohn Forte } 643*fcf3ce44SJohn Forte 644*fcf3ce44SJohn Forte /* Skip global element */ 645*fcf3ce44SJohn Forte front_index++; 646*fcf3ce44SJohn Forte if (enc_type == DAK_ENC_TYPE) { 647*fcf3ce44SJohn Forte rear_index += l_state->total_num_drv/2 + 1; 648*fcf3ce44SJohn Forte } else { 649*fcf3ce44SJohn Forte rear_index++; 650*fcf3ce44SJohn Forte } 651*fcf3ce44SJohn Forte 652*fcf3ce44SJohn Forte if (path_struct->f_flag) { 653*fcf3ce44SJohn Forte offset = (8 + (front_index + path_struct->slot)*4); 654*fcf3ce44SJohn Forte } else { 655*fcf3ce44SJohn Forte offset = (8 + (rear_index + path_struct->slot)*4); 656*fcf3ce44SJohn Forte } 657*fcf3ce44SJohn Forte 658*fcf3ce44SJohn Forte elem = (struct device_element *)(page_buf + offset); 659*fcf3ce44SJohn Forte /* 660*fcf3ce44SJohn Forte * now do requested action. 661*fcf3ce44SJohn Forte */ 662*fcf3ce44SJohn Forte bcopy((const void *)elem, (void *)status, 663*fcf3ce44SJohn Forte sizeof (struct device_element)); /* save status */ 664*fcf3ce44SJohn Forte bzero(elem, sizeof (struct device_element)); 665*fcf3ce44SJohn Forte elem->select = 1; 666*fcf3ce44SJohn Forte elem->dev_off = status->dev_off; 667*fcf3ce44SJohn Forte elem->en_bypass_a = status->en_bypass_a; 668*fcf3ce44SJohn Forte elem->en_bypass_b = status->en_bypass_b; 669*fcf3ce44SJohn Forte write = 1; 670*fcf3ce44SJohn Forte 671*fcf3ce44SJohn Forte switch (led_action) { 672*fcf3ce44SJohn Forte case L_LED_STATUS: 673*fcf3ce44SJohn Forte write = 0; 674*fcf3ce44SJohn Forte break; 675*fcf3ce44SJohn Forte case L_LED_RQST_IDENTIFY: 676*fcf3ce44SJohn Forte elem->ident = 1; 677*fcf3ce44SJohn Forte if (verbose) { 678*fcf3ce44SJohn Forte if (enc_type == DAK_ENC_TYPE) { 679*fcf3ce44SJohn Forte (void) fprintf(stdout, 680*fcf3ce44SJohn Forte MSGSTR(9043, " Blinking LED for slot %d in enclosure" 681*fcf3ce44SJohn Forte " %s\n"), path_struct->f_flag ? path_struct->slot : 682*fcf3ce44SJohn Forte path_struct->slot + (MAX_DRIVES_DAK/2), 683*fcf3ce44SJohn Forte l_state->ib_tbl.enclosure_name); 684*fcf3ce44SJohn Forte } else { 685*fcf3ce44SJohn Forte (void) fprintf(stdout, 686*fcf3ce44SJohn Forte MSGSTR(9043, " Blinking LED for slot %d in enclosure" 687*fcf3ce44SJohn Forte " %s\n"), path_struct->slot, 688*fcf3ce44SJohn Forte l_state->ib_tbl.enclosure_name); 689*fcf3ce44SJohn Forte } 690*fcf3ce44SJohn Forte } 691*fcf3ce44SJohn Forte break; 692*fcf3ce44SJohn Forte case L_LED_OFF: 693*fcf3ce44SJohn Forte if (verbose) { 694*fcf3ce44SJohn Forte if (enc_type == DAK_ENC_TYPE) { 695*fcf3ce44SJohn Forte (void) fprintf(stdout, 696*fcf3ce44SJohn Forte MSGSTR(9044, 697*fcf3ce44SJohn Forte " Turning off LED for slot %d in enclosure" 698*fcf3ce44SJohn Forte " %s\n"), path_struct->f_flag ? path_struct->slot 699*fcf3ce44SJohn Forte : path_struct->slot + (MAX_DRIVES_DAK/2), 700*fcf3ce44SJohn Forte l_state->ib_tbl.enclosure_name); 701*fcf3ce44SJohn Forte } else { 702*fcf3ce44SJohn Forte (void) fprintf(stdout, 703*fcf3ce44SJohn Forte MSGSTR(9044, 704*fcf3ce44SJohn Forte " Turning off LED for slot %d in enclosure" 705*fcf3ce44SJohn Forte " %s\n"), path_struct->slot, 706*fcf3ce44SJohn Forte l_state->ib_tbl.enclosure_name); 707*fcf3ce44SJohn Forte } 708*fcf3ce44SJohn Forte } 709*fcf3ce44SJohn Forte break; 710*fcf3ce44SJohn Forte default: 711*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 712*fcf3ce44SJohn Forte return (L_INVALID_LED_RQST); 713*fcf3ce44SJohn Forte } /* End of switch */ 714*fcf3ce44SJohn Forte 715*fcf3ce44SJohn Forte if (write) { 716*fcf3ce44SJohn Forte if (getenv("_LUX_D_DEBUG") != NULL) { 717*fcf3ce44SJohn Forte g_dump(" l_led: Updating led state: " 718*fcf3ce44SJohn Forte "Device Status Element ", 719*fcf3ce44SJohn Forte (uchar_t *)elem, sizeof (struct device_element), 720*fcf3ce44SJohn Forte HEX_ONLY); 721*fcf3ce44SJohn Forte } 722*fcf3ce44SJohn Forte if (err = g_scsi_send_diag_cmd(fd, 723*fcf3ce44SJohn Forte (uchar_t *)page_buf, page_len)) { 724*fcf3ce44SJohn Forte (void) close(fd); 725*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 726*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 727*fcf3ce44SJohn Forte return (err); 728*fcf3ce44SJohn Forte } 729*fcf3ce44SJohn Forte 730*fcf3ce44SJohn Forte bzero(page_buf, MAX_REC_DIAG_LENGTH); 731*fcf3ce44SJohn Forte if (err = l_get_envsen_page(fd, page_buf, MAX_REC_DIAG_LENGTH, 732*fcf3ce44SJohn Forte L_PAGE_2, verbose)) { 733*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 734*fcf3ce44SJohn Forte (void) close(fd); 735*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 736*fcf3ce44SJohn Forte return (err); 737*fcf3ce44SJohn Forte } 738*fcf3ce44SJohn Forte elem = (struct device_element *)(page_buf + offset); 739*fcf3ce44SJohn Forte bcopy((const void *)elem, (void *)status, 740*fcf3ce44SJohn Forte sizeof (struct device_element)); 741*fcf3ce44SJohn Forte } 742*fcf3ce44SJohn Forte if (getenv("_LUX_D_DEBUG") != NULL) { 743*fcf3ce44SJohn Forte g_dump(" l_led: Device Status Element ", 744*fcf3ce44SJohn Forte (uchar_t *)status, sizeof (struct device_element), 745*fcf3ce44SJohn Forte HEX_ONLY); 746*fcf3ce44SJohn Forte } 747*fcf3ce44SJohn Forte 748*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 749*fcf3ce44SJohn Forte (void) close(fd); 750*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 751*fcf3ce44SJohn Forte return (0); 752*fcf3ce44SJohn Forte } 753*fcf3ce44SJohn Forte 754*fcf3ce44SJohn Forte 755*fcf3ce44SJohn Forte /* 756*fcf3ce44SJohn Forte * frees the previously alloced l_state 757*fcf3ce44SJohn Forte * structure. 758*fcf3ce44SJohn Forte * 759*fcf3ce44SJohn Forte * RETURNS: 760*fcf3ce44SJohn Forte * 0 O.K. 761*fcf3ce44SJohn Forte * non-zero otherwise 762*fcf3ce44SJohn Forte */ 763*fcf3ce44SJohn Forte int 764*fcf3ce44SJohn Forte l_free_lstate(L_state **l_state) 765*fcf3ce44SJohn Forte { 766*fcf3ce44SJohn Forte int i; 767*fcf3ce44SJohn Forte 768*fcf3ce44SJohn Forte if ((l_state == NULL) || (*l_state == NULL)) 769*fcf3ce44SJohn Forte return (0); 770*fcf3ce44SJohn Forte 771*fcf3ce44SJohn Forte for (i = 0; i < (int)(*l_state)->total_num_drv/2; i++) { 772*fcf3ce44SJohn Forte if ((*l_state)->drv_front[i].g_disk_state.multipath_list != NULL) 773*fcf3ce44SJohn Forte (void) g_free_multipath( 774*fcf3ce44SJohn Forte (*l_state)->drv_front[i].g_disk_state.multipath_list); 775*fcf3ce44SJohn Forte if ((*l_state)->drv_rear[i].g_disk_state.multipath_list != NULL) 776*fcf3ce44SJohn Forte (void) g_free_multipath( 777*fcf3ce44SJohn Forte (*l_state)->drv_rear[i].g_disk_state.multipath_list); 778*fcf3ce44SJohn Forte } 779*fcf3ce44SJohn Forte (void) g_destroy_data (*l_state); 780*fcf3ce44SJohn Forte l_state = NULL; 781*fcf3ce44SJohn Forte 782*fcf3ce44SJohn Forte return (0); 783*fcf3ce44SJohn Forte } 784*fcf3ce44SJohn Forte 785*fcf3ce44SJohn Forte 786*fcf3ce44SJohn Forte 787*fcf3ce44SJohn Forte /* 788*fcf3ce44SJohn Forte * Set the state of an individual disk 789*fcf3ce44SJohn Forte * in the Photon enclosure the powered 790*fcf3ce44SJohn Forte * up/down mode. The path must point to 791*fcf3ce44SJohn Forte * a disk or the ib_path_flag must be set. 792*fcf3ce44SJohn Forte * 793*fcf3ce44SJohn Forte * RETURNS: 794*fcf3ce44SJohn Forte * 0 O.K. 795*fcf3ce44SJohn Forte * non-zero otherwise 796*fcf3ce44SJohn Forte */ 797*fcf3ce44SJohn Forte int 798*fcf3ce44SJohn Forte l_dev_pwr_up_down(char *path_phys, struct path_struct *path_struct, 799*fcf3ce44SJohn Forte int power_off_flag, int verbose, int force_flag) 800*fcf3ce44SJohn Forte /*ARGSUSED*/ 801*fcf3ce44SJohn Forte { 802*fcf3ce44SJohn Forte gfc_map_t map; 803*fcf3ce44SJohn Forte char ses_path[MAXPATHLEN], dev_path[MAXPATHLEN]; 804*fcf3ce44SJohn Forte int slot, err = 0; 805*fcf3ce44SJohn Forte L_state *l_state = NULL; 806*fcf3ce44SJohn Forte struct l_disk_state_struct *drive; 807*fcf3ce44SJohn Forte struct dlist *dl, *dl1; 808*fcf3ce44SJohn Forte devctl_hdl_t devhdl; 809*fcf3ce44SJohn Forte WWN_list *wwn_list = NULL; 810*fcf3ce44SJohn Forte L_inquiry inq; 811*fcf3ce44SJohn Forte 812*fcf3ce44SJohn Forte if (path_struct == NULL) { 813*fcf3ce44SJohn Forte return (L_INVALID_PATH_FORMAT); 814*fcf3ce44SJohn Forte } 815*fcf3ce44SJohn Forte 816*fcf3ce44SJohn Forte dl = (struct dlist *)NULL; 817*fcf3ce44SJohn Forte map.dev_addr = (gfc_port_dev_info_t *)NULL; 818*fcf3ce44SJohn Forte 819*fcf3ce44SJohn Forte if (err = g_get_dev_map(path_struct->p_physical_path, 820*fcf3ce44SJohn Forte &map, verbose)) 821*fcf3ce44SJohn Forte return (err); 822*fcf3ce44SJohn Forte 823*fcf3ce44SJohn Forte if (err = l_get_ses_path(path_struct->p_physical_path, 824*fcf3ce44SJohn Forte ses_path, &map, verbose)) { 825*fcf3ce44SJohn Forte free((void *)map.dev_addr); 826*fcf3ce44SJohn Forte return (err); 827*fcf3ce44SJohn Forte } 828*fcf3ce44SJohn Forte free((void *)map.dev_addr); /* Not used anymore */ 829*fcf3ce44SJohn Forte 830*fcf3ce44SJohn Forte /* 831*fcf3ce44SJohn Forte * Check to see if we have a photon, and if not, don't allow 832*fcf3ce44SJohn Forte * this operation 833*fcf3ce44SJohn Forte */ 834*fcf3ce44SJohn Forte if (err = g_get_inquiry(ses_path, &inq)) { 835*fcf3ce44SJohn Forte return (err); 836*fcf3ce44SJohn Forte } 837*fcf3ce44SJohn Forte if (l_get_enc_type(inq) != SENA_ENC_TYPE) { 838*fcf3ce44SJohn Forte return (L_ENCL_INVALID_PATH); 839*fcf3ce44SJohn Forte } 840*fcf3ce44SJohn Forte /* 841*fcf3ce44SJohn Forte * OK, so we have a photon... we can continue 842*fcf3ce44SJohn Forte */ 843*fcf3ce44SJohn Forte 844*fcf3ce44SJohn Forte 845*fcf3ce44SJohn Forte if ((l_state = (L_state *)calloc(1, sizeof (L_state))) == NULL) { 846*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 847*fcf3ce44SJohn Forte } 848*fcf3ce44SJohn Forte 849*fcf3ce44SJohn Forte if (err = l_get_status(ses_path, l_state, verbose)) { 850*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 851*fcf3ce44SJohn Forte return (err); 852*fcf3ce44SJohn Forte } 853*fcf3ce44SJohn Forte 854*fcf3ce44SJohn Forte if (!path_struct->slot_valid) { 855*fcf3ce44SJohn Forte /* We are passing the disks path */ 856*fcf3ce44SJohn Forte if (err = l_get_slot(path_struct, l_state, verbose)) { 857*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 858*fcf3ce44SJohn Forte return (err); 859*fcf3ce44SJohn Forte } 860*fcf3ce44SJohn Forte } 861*fcf3ce44SJohn Forte 862*fcf3ce44SJohn Forte slot = path_struct->slot; 863*fcf3ce44SJohn Forte (void) strcpy(dev_path, path_struct->p_physical_path); 864*fcf3ce44SJohn Forte 865*fcf3ce44SJohn Forte /* 866*fcf3ce44SJohn Forte * Either front or rear drive 867*fcf3ce44SJohn Forte */ 868*fcf3ce44SJohn Forte if (path_struct->f_flag) { 869*fcf3ce44SJohn Forte drive = &l_state->drv_front[slot]; 870*fcf3ce44SJohn Forte } else { 871*fcf3ce44SJohn Forte drive = &l_state->drv_rear[slot]; 872*fcf3ce44SJohn Forte } 873*fcf3ce44SJohn Forte 874*fcf3ce44SJohn Forte /* 875*fcf3ce44SJohn Forte * Check for drive presence always 876*fcf3ce44SJohn Forte */ 877*fcf3ce44SJohn Forte if (drive->ib_status.code == S_NOT_INSTALLED) { 878*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 879*fcf3ce44SJohn Forte return (L_SLOT_EMPTY); 880*fcf3ce44SJohn Forte } 881*fcf3ce44SJohn Forte 882*fcf3ce44SJohn Forte /* 883*fcf3ce44SJohn Forte * Check disk state 884*fcf3ce44SJohn Forte * before the power off. 885*fcf3ce44SJohn Forte * 886*fcf3ce44SJohn Forte */ 887*fcf3ce44SJohn Forte if (power_off_flag && !force_flag) { 888*fcf3ce44SJohn Forte goto pre_pwr_dwn; 889*fcf3ce44SJohn Forte } else { 890*fcf3ce44SJohn Forte goto pwr_up_dwn; 891*fcf3ce44SJohn Forte } 892*fcf3ce44SJohn Forte 893*fcf3ce44SJohn Forte pre_pwr_dwn: 894*fcf3ce44SJohn Forte 895*fcf3ce44SJohn Forte /* 896*fcf3ce44SJohn Forte * Check whether disk 897*fcf3ce44SJohn Forte * is reserved by another 898*fcf3ce44SJohn Forte * host 899*fcf3ce44SJohn Forte */ 900*fcf3ce44SJohn Forte if ((drive->g_disk_state.d_state_flags[PORT_A] & L_RESERVED) || 901*fcf3ce44SJohn Forte (drive->g_disk_state.d_state_flags[PORT_B] & 902*fcf3ce44SJohn Forte L_RESERVED)) { 903*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 904*fcf3ce44SJohn Forte return (L_DEVICE_RESERVED); 905*fcf3ce44SJohn Forte } 906*fcf3ce44SJohn Forte 907*fcf3ce44SJohn Forte 908*fcf3ce44SJohn Forte if ((dl = (struct dlist *)g_zalloc(sizeof (struct dlist))) == NULL) { 909*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 910*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 911*fcf3ce44SJohn Forte } 912*fcf3ce44SJohn Forte 913*fcf3ce44SJohn Forte /* 914*fcf3ce44SJohn Forte * NOTE: It is not necessary to get the multipath list here as ------ 915*fcf3ce44SJohn Forte * we alread have it after getting the status earlier. 916*fcf3ce44SJohn Forte * - REWRITE - 917*fcf3ce44SJohn Forte */ 918*fcf3ce44SJohn Forte 919*fcf3ce44SJohn Forte /* 920*fcf3ce44SJohn Forte * Get path to all the FC disk and tape devices. 921*fcf3ce44SJohn Forte * 922*fcf3ce44SJohn Forte * I get this now and pass down for performance 923*fcf3ce44SJohn Forte * reasons. 924*fcf3ce44SJohn Forte * If for some reason the list can become invalid, 925*fcf3ce44SJohn Forte * i.e. device being offlined, then the list 926*fcf3ce44SJohn Forte * must be re-gotten. 927*fcf3ce44SJohn Forte */ 928*fcf3ce44SJohn Forte if (err = g_get_wwn_list(&wwn_list, verbose)) { 929*fcf3ce44SJohn Forte (void) g_destroy_data(dl); 930*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 931*fcf3ce44SJohn Forte return (err); /* Failure */ 932*fcf3ce44SJohn Forte } 933*fcf3ce44SJohn Forte 934*fcf3ce44SJohn Forte dl->dev_path = dev_path; 935*fcf3ce44SJohn Forte if ((err = g_get_multipath(dev_path, 936*fcf3ce44SJohn Forte &(dl->multipath), wwn_list, verbose)) != 0) { 937*fcf3ce44SJohn Forte (void) g_destroy_data(dl); 938*fcf3ce44SJohn Forte (void) g_free_wwn_list(&wwn_list); 939*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 940*fcf3ce44SJohn Forte return (err); 941*fcf3ce44SJohn Forte } 942*fcf3ce44SJohn Forte 943*fcf3ce44SJohn Forte for (dl1 = dl->multipath; dl1 != NULL; dl1 = dl1->next) { 944*fcf3ce44SJohn Forte if ((devhdl = devctl_device_acquire(dl1->dev_path, 945*fcf3ce44SJohn Forte DC_EXCL)) == NULL) { 946*fcf3ce44SJohn Forte if (errno != EBUSY) { 947*fcf3ce44SJohn Forte ER_DPRINTF("%s could not acquire" 948*fcf3ce44SJohn Forte " the device: %s\n\n", 949*fcf3ce44SJohn Forte strerror(errno), dl1->dev_path); 950*fcf3ce44SJohn Forte continue; 951*fcf3ce44SJohn Forte } 952*fcf3ce44SJohn Forte } 953*fcf3ce44SJohn Forte if (devctl_device_offline(devhdl) != 0) { 954*fcf3ce44SJohn Forte (void) devctl_release(devhdl); 955*fcf3ce44SJohn Forte (void) g_free_multipath(dl->multipath); 956*fcf3ce44SJohn Forte (void) g_destroy_data(dl); 957*fcf3ce44SJohn Forte (void) g_free_wwn_list(&wwn_list); 958*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 959*fcf3ce44SJohn Forte return (L_POWER_OFF_FAIL_BUSY); 960*fcf3ce44SJohn Forte } 961*fcf3ce44SJohn Forte (void) devctl_release(devhdl); 962*fcf3ce44SJohn Forte } 963*fcf3ce44SJohn Forte 964*fcf3ce44SJohn Forte pwr_up_dwn: 965*fcf3ce44SJohn Forte err = pwr_up_down(ses_path, l_state, path_struct->f_flag, 966*fcf3ce44SJohn Forte path_struct->slot, power_off_flag, verbose); 967*fcf3ce44SJohn Forte 968*fcf3ce44SJohn Forte if (dl != NULL) { 969*fcf3ce44SJohn Forte (void) g_free_multipath(dl->multipath); 970*fcf3ce44SJohn Forte (void) g_destroy_data(dl); 971*fcf3ce44SJohn Forte } 972*fcf3ce44SJohn Forte (void) g_free_wwn_list(&wwn_list); 973*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 974*fcf3ce44SJohn Forte if (err) { 975*fcf3ce44SJohn Forte return (err); 976*fcf3ce44SJohn Forte } 977*fcf3ce44SJohn Forte return (0); 978*fcf3ce44SJohn Forte } 979*fcf3ce44SJohn Forte 980*fcf3ce44SJohn Forte 981*fcf3ce44SJohn Forte 982*fcf3ce44SJohn Forte /* 983*fcf3ce44SJohn Forte * l_pho_pwr_up_down() Set the state of the Photon enclosure 984*fcf3ce44SJohn Forte * the powered up/down mode. 985*fcf3ce44SJohn Forte * The path must point to an IB. 986*fcf3ce44SJohn Forte * 987*fcf3ce44SJohn Forte * RETURNS: 988*fcf3ce44SJohn Forte * 0 O.K. 989*fcf3ce44SJohn Forte * non-zero otherwise 990*fcf3ce44SJohn Forte */ 991*fcf3ce44SJohn Forte int 992*fcf3ce44SJohn Forte l_pho_pwr_up_down(char *dev_name, char *path_phys, int power_off_flag, 993*fcf3ce44SJohn Forte int verbose, int force_flag) 994*fcf3ce44SJohn Forte { 995*fcf3ce44SJohn Forte L_state *l_state = NULL; 996*fcf3ce44SJohn Forte int i, err = 0; 997*fcf3ce44SJohn Forte struct dlist *dl, *dl1; 998*fcf3ce44SJohn Forte char dev_path[MAXPATHLEN]; 999*fcf3ce44SJohn Forte devctl_hdl_t devhdl; 1000*fcf3ce44SJohn Forte WWN_list *wwn_list = NULL; 1001*fcf3ce44SJohn Forte 1002*fcf3ce44SJohn Forte if (path_phys == NULL) { 1003*fcf3ce44SJohn Forte return (L_INVALID_PATH_FORMAT); 1004*fcf3ce44SJohn Forte } 1005*fcf3ce44SJohn Forte 1006*fcf3ce44SJohn Forte dl = (struct dlist *)NULL; 1007*fcf3ce44SJohn Forte if ((l_state = (L_state *)calloc(1, sizeof (L_state))) == NULL) { 1008*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 1009*fcf3ce44SJohn Forte } 1010*fcf3ce44SJohn Forte if (err = l_get_status(path_phys, l_state, verbose)) { 1011*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 1012*fcf3ce44SJohn Forte return (err); 1013*fcf3ce44SJohn Forte } 1014*fcf3ce44SJohn Forte if (power_off_flag && !force_flag) { 1015*fcf3ce44SJohn Forte goto pre_pwr_dwn; 1016*fcf3ce44SJohn Forte } else { 1017*fcf3ce44SJohn Forte goto pwr_up_dwn; 1018*fcf3ce44SJohn Forte } 1019*fcf3ce44SJohn Forte 1020*fcf3ce44SJohn Forte pre_pwr_dwn: 1021*fcf3ce44SJohn Forte 1022*fcf3ce44SJohn Forte /* 1023*fcf3ce44SJohn Forte * Check if any disk in this enclosure 1024*fcf3ce44SJohn Forte * is reserved by another host before 1025*fcf3ce44SJohn Forte * the power off. 1026*fcf3ce44SJohn Forte */ 1027*fcf3ce44SJohn Forte for (i = 0; i < l_state->total_num_drv/2; i++) { 1028*fcf3ce44SJohn Forte if ((l_state->drv_front[i].g_disk_state.d_state_flags[PORT_A] & 1029*fcf3ce44SJohn Forte L_RESERVED) || 1030*fcf3ce44SJohn Forte (l_state->drv_front[i].g_disk_state.d_state_flags[PORT_B] & 1031*fcf3ce44SJohn Forte L_RESERVED) || 1032*fcf3ce44SJohn Forte (l_state->drv_rear[i].g_disk_state.d_state_flags[PORT_A] & 1033*fcf3ce44SJohn Forte L_RESERVED) || 1034*fcf3ce44SJohn Forte (l_state->drv_rear[i].g_disk_state.d_state_flags[PORT_B] & 1035*fcf3ce44SJohn Forte L_RESERVED)) { 1036*fcf3ce44SJohn Forte return (L_DISKS_RESERVED); 1037*fcf3ce44SJohn Forte } 1038*fcf3ce44SJohn Forte } 1039*fcf3ce44SJohn Forte 1040*fcf3ce44SJohn Forte /* 1041*fcf3ce44SJohn Forte * Check if any disk in this enclosure 1042*fcf3ce44SJohn Forte * Get path to all the FC disk and tape devices. 1043*fcf3ce44SJohn Forte * 1044*fcf3ce44SJohn Forte * I get this now and pass down for performance 1045*fcf3ce44SJohn Forte * reasons. 1046*fcf3ce44SJohn Forte * If for some reason the list can become invalid, 1047*fcf3ce44SJohn Forte * i.e. device being offlined, then the list 1048*fcf3ce44SJohn Forte * must be re-gotten. 1049*fcf3ce44SJohn Forte */ 1050*fcf3ce44SJohn Forte if (err = g_get_wwn_list(&wwn_list, verbose)) { 1051*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 1052*fcf3ce44SJohn Forte return (err); /* Failure */ 1053*fcf3ce44SJohn Forte } 1054*fcf3ce44SJohn Forte for (i = 0; i < l_state->total_num_drv/2; i++) { 1055*fcf3ce44SJohn Forte if (*l_state->drv_front[i].g_disk_state.physical_path) { 1056*fcf3ce44SJohn Forte (void) memset(dev_path, 0, MAXPATHLEN); 1057*fcf3ce44SJohn Forte (void) strcpy(dev_path, 1058*fcf3ce44SJohn Forte (char *)&l_state->drv_front[i].g_disk_state.physical_path); 1059*fcf3ce44SJohn Forte 1060*fcf3ce44SJohn Forte if ((dl = (struct dlist *) 1061*fcf3ce44SJohn Forte g_zalloc(sizeof (struct dlist))) == NULL) { 1062*fcf3ce44SJohn Forte (void) g_free_wwn_list(&wwn_list); 1063*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 1064*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 1065*fcf3ce44SJohn Forte } 1066*fcf3ce44SJohn Forte dl->dev_path = dev_path; 1067*fcf3ce44SJohn Forte if (g_get_multipath(dev_path, &(dl->multipath), 1068*fcf3ce44SJohn Forte wwn_list, verbose) != 0) { 1069*fcf3ce44SJohn Forte (void) g_destroy_data(dl); 1070*fcf3ce44SJohn Forte continue; 1071*fcf3ce44SJohn Forte } 1072*fcf3ce44SJohn Forte 1073*fcf3ce44SJohn Forte for (dl1 = dl->multipath; 1074*fcf3ce44SJohn Forte dl1 != NULL; 1075*fcf3ce44SJohn Forte dl1 = dl1->next) { 1076*fcf3ce44SJohn Forte 1077*fcf3ce44SJohn Forte /* attempt to acquire the device */ 1078*fcf3ce44SJohn Forte if ((devhdl = devctl_device_acquire( 1079*fcf3ce44SJohn Forte dl1->dev_path, DC_EXCL)) == NULL) { 1080*fcf3ce44SJohn Forte if (errno != EBUSY) { 1081*fcf3ce44SJohn Forte ER_DPRINTF("%s: Could not " 1082*fcf3ce44SJohn Forte "acquire the device: %s\n\n", 1083*fcf3ce44SJohn Forte strerror(errno), 1084*fcf3ce44SJohn Forte dl1->dev_path); 1085*fcf3ce44SJohn Forte continue; 1086*fcf3ce44SJohn Forte } 1087*fcf3ce44SJohn Forte } 1088*fcf3ce44SJohn Forte 1089*fcf3ce44SJohn Forte /* attempt to offline the device */ 1090*fcf3ce44SJohn Forte if (devctl_device_offline(devhdl) != 0) { 1091*fcf3ce44SJohn Forte (void) devctl_release(devhdl); 1092*fcf3ce44SJohn Forte (void) g_free_multipath( 1093*fcf3ce44SJohn Forte dl->multipath); 1094*fcf3ce44SJohn Forte (void) g_destroy_data(dl); 1095*fcf3ce44SJohn Forte (void) g_free_wwn_list(&wwn_list); 1096*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 1097*fcf3ce44SJohn Forte return (L_POWER_OFF_FAIL_BUSY); 1098*fcf3ce44SJohn Forte } 1099*fcf3ce44SJohn Forte 1100*fcf3ce44SJohn Forte /* release handle acquired above */ 1101*fcf3ce44SJohn Forte (void) devctl_release(devhdl); 1102*fcf3ce44SJohn Forte } 1103*fcf3ce44SJohn Forte (void) g_free_multipath(dl->multipath); 1104*fcf3ce44SJohn Forte (void) g_destroy_data(dl); 1105*fcf3ce44SJohn Forte 1106*fcf3ce44SJohn Forte } 1107*fcf3ce44SJohn Forte if (*l_state->drv_rear[i].g_disk_state.physical_path) { 1108*fcf3ce44SJohn Forte (void) memset(dev_path, 0, MAXPATHLEN); 1109*fcf3ce44SJohn Forte (void) strcpy(dev_path, 1110*fcf3ce44SJohn Forte (char *)&l_state->drv_rear[i].g_disk_state.physical_path); 1111*fcf3ce44SJohn Forte 1112*fcf3ce44SJohn Forte if ((dl = (struct dlist *) 1113*fcf3ce44SJohn Forte g_zalloc(sizeof (struct dlist))) == NULL) { 1114*fcf3ce44SJohn Forte (void) g_free_wwn_list(&wwn_list); 1115*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 1116*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 1117*fcf3ce44SJohn Forte } 1118*fcf3ce44SJohn Forte dl->dev_path = dev_path; 1119*fcf3ce44SJohn Forte if (g_get_multipath(dev_path, &(dl->multipath), 1120*fcf3ce44SJohn Forte wwn_list, verbose) != 0) { 1121*fcf3ce44SJohn Forte (void) g_destroy_data(dl); 1122*fcf3ce44SJohn Forte continue; 1123*fcf3ce44SJohn Forte } 1124*fcf3ce44SJohn Forte 1125*fcf3ce44SJohn Forte 1126*fcf3ce44SJohn Forte for (dl1 = dl->multipath; 1127*fcf3ce44SJohn Forte dl1 != NULL; 1128*fcf3ce44SJohn Forte dl1 = dl1->next) { 1129*fcf3ce44SJohn Forte 1130*fcf3ce44SJohn Forte /* attempt to acquire the device */ 1131*fcf3ce44SJohn Forte if ((devhdl = devctl_device_acquire( 1132*fcf3ce44SJohn Forte dl1->dev_path, DC_EXCL)) == NULL) { 1133*fcf3ce44SJohn Forte if (errno != EBUSY) { 1134*fcf3ce44SJohn Forte ER_DPRINTF("%s: Could not " 1135*fcf3ce44SJohn Forte "acquire the device: %s\n\n", 1136*fcf3ce44SJohn Forte strerror(errno), 1137*fcf3ce44SJohn Forte dl1->dev_path); 1138*fcf3ce44SJohn Forte continue; 1139*fcf3ce44SJohn Forte } 1140*fcf3ce44SJohn Forte } 1141*fcf3ce44SJohn Forte /* attempt to offline the device */ 1142*fcf3ce44SJohn Forte if (devctl_device_offline(devhdl) != 0) { 1143*fcf3ce44SJohn Forte (void) devctl_release(devhdl); 1144*fcf3ce44SJohn Forte (void) g_free_multipath( 1145*fcf3ce44SJohn Forte dl->multipath); 1146*fcf3ce44SJohn Forte (void) g_destroy_data(dl); 1147*fcf3ce44SJohn Forte (void) g_free_wwn_list(&wwn_list); 1148*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 1149*fcf3ce44SJohn Forte return (L_POWER_OFF_FAIL_BUSY); 1150*fcf3ce44SJohn Forte } 1151*fcf3ce44SJohn Forte 1152*fcf3ce44SJohn Forte /* release handle acquired above */ 1153*fcf3ce44SJohn Forte (void) devctl_release(devhdl); 1154*fcf3ce44SJohn Forte } 1155*fcf3ce44SJohn Forte (void) g_free_multipath(dl->multipath); 1156*fcf3ce44SJohn Forte (void) g_destroy_data(dl); 1157*fcf3ce44SJohn Forte 1158*fcf3ce44SJohn Forte } 1159*fcf3ce44SJohn Forte } 1160*fcf3ce44SJohn Forte 1161*fcf3ce44SJohn Forte pwr_up_dwn: 1162*fcf3ce44SJohn Forte 1163*fcf3ce44SJohn Forte (void) g_free_wwn_list(&wwn_list); 1164*fcf3ce44SJohn Forte if ((err = pwr_up_down(path_phys, l_state, 0, -1, 1165*fcf3ce44SJohn Forte power_off_flag, verbose)) != 0) { 1166*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 1167*fcf3ce44SJohn Forte return (err); 1168*fcf3ce44SJohn Forte } 1169*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 1170*fcf3ce44SJohn Forte return (0); 1171*fcf3ce44SJohn Forte } 1172*fcf3ce44SJohn Forte 1173*fcf3ce44SJohn Forte 1174*fcf3ce44SJohn Forte /* 1175*fcf3ce44SJohn Forte * Set the state of the Photon enclosure or disk 1176*fcf3ce44SJohn Forte * powered up/down mode. 1177*fcf3ce44SJohn Forte * The path must point to an IB. 1178*fcf3ce44SJohn Forte * slot == -1 implies entire enclosure. 1179*fcf3ce44SJohn Forte * 1180*fcf3ce44SJohn Forte * RETURNS: 1181*fcf3ce44SJohn Forte * 0 O.K. 1182*fcf3ce44SJohn Forte * non-zero otherwise 1183*fcf3ce44SJohn Forte */ 1184*fcf3ce44SJohn Forte static int 1185*fcf3ce44SJohn Forte pwr_up_down(char *path_phys, L_state *l_state, int front, int slot, 1186*fcf3ce44SJohn Forte int power_off_flag, int verbose) 1187*fcf3ce44SJohn Forte { 1188*fcf3ce44SJohn Forte L_inquiry inq; 1189*fcf3ce44SJohn Forte int fd, status, err; 1190*fcf3ce44SJohn Forte uchar_t *page_buf; 1191*fcf3ce44SJohn Forte int front_index, rear_index, front_offset, rear_offset; 1192*fcf3ce44SJohn Forte unsigned short page_len; 1193*fcf3ce44SJohn Forte struct device_element *front_elem, *rear_elem; 1194*fcf3ce44SJohn Forte 1195*fcf3ce44SJohn Forte (void) memset(&inq, 0, sizeof (inq)); 1196*fcf3ce44SJohn Forte if ((fd = g_object_open(path_phys, O_NDELAY | O_RDONLY)) == -1) { 1197*fcf3ce44SJohn Forte return (L_OPEN_PATH_FAIL); 1198*fcf3ce44SJohn Forte } 1199*fcf3ce44SJohn Forte /* Verify it is a Photon */ 1200*fcf3ce44SJohn Forte if (status = g_scsi_inquiry_cmd(fd, 1201*fcf3ce44SJohn Forte (uchar_t *)&inq, sizeof (struct l_inquiry_struct))) { 1202*fcf3ce44SJohn Forte (void) close(fd); 1203*fcf3ce44SJohn Forte return (status); 1204*fcf3ce44SJohn Forte } 1205*fcf3ce44SJohn Forte if ((strstr((char *)inq.inq_pid, ENCLOSURE_PROD_ID) == 0) && 1206*fcf3ce44SJohn Forte (!(strncmp((char *)inq.inq_vid, "SUN ", 1207*fcf3ce44SJohn Forte sizeof (inq.inq_vid)) && 1208*fcf3ce44SJohn Forte ((inq.inq_dtype & DTYPE_MASK) == DTYPE_ESI)))) { 1209*fcf3ce44SJohn Forte (void) close(fd); 1210*fcf3ce44SJohn Forte return (L_ENCL_INVALID_PATH); 1211*fcf3ce44SJohn Forte } 1212*fcf3ce44SJohn Forte 1213*fcf3ce44SJohn Forte /* 1214*fcf3ce44SJohn Forte * To power up/down a Photon we use the Driver Off 1215*fcf3ce44SJohn Forte * bit in the global device control element. 1216*fcf3ce44SJohn Forte */ 1217*fcf3ce44SJohn Forte if ((page_buf = (uchar_t *)malloc(MAX_REC_DIAG_LENGTH)) == NULL) { 1218*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 1219*fcf3ce44SJohn Forte } 1220*fcf3ce44SJohn Forte if (err = l_get_envsen_page(fd, page_buf, MAX_REC_DIAG_LENGTH, 1221*fcf3ce44SJohn Forte L_PAGE_2, verbose)) { 1222*fcf3ce44SJohn Forte (void) close(fd); 1223*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 1224*fcf3ce44SJohn Forte return (err); 1225*fcf3ce44SJohn Forte } 1226*fcf3ce44SJohn Forte 1227*fcf3ce44SJohn Forte page_len = (page_buf[2] << 8 | page_buf[3]) + HEADER_LEN; 1228*fcf3ce44SJohn Forte 1229*fcf3ce44SJohn Forte /* Double check slot as convert_name only does gross check */ 1230*fcf3ce44SJohn Forte if (slot >= l_state->total_num_drv/2) { 1231*fcf3ce44SJohn Forte (void) close(fd); 1232*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 1233*fcf3ce44SJohn Forte return (L_INVALID_SLOT); 1234*fcf3ce44SJohn Forte } 1235*fcf3ce44SJohn Forte 1236*fcf3ce44SJohn Forte if (err = l_get_disk_element_index(l_state, &front_index, 1237*fcf3ce44SJohn Forte &rear_index)) { 1238*fcf3ce44SJohn Forte (void) close(fd); 1239*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 1240*fcf3ce44SJohn Forte return (err); 1241*fcf3ce44SJohn Forte } 1242*fcf3ce44SJohn Forte /* Skip global element */ 1243*fcf3ce44SJohn Forte front_index++; 1244*fcf3ce44SJohn Forte rear_index++; 1245*fcf3ce44SJohn Forte 1246*fcf3ce44SJohn Forte front_offset = (8 + (front_index + slot)*4); 1247*fcf3ce44SJohn Forte rear_offset = (8 + (rear_index + slot)*4); 1248*fcf3ce44SJohn Forte 1249*fcf3ce44SJohn Forte front_elem = (struct device_element *)(page_buf + front_offset); 1250*fcf3ce44SJohn Forte rear_elem = (struct device_element *)(page_buf + rear_offset); 1251*fcf3ce44SJohn Forte 1252*fcf3ce44SJohn Forte if (front || slot == -1) { 1253*fcf3ce44SJohn Forte /* 1254*fcf3ce44SJohn Forte * now do requested action. 1255*fcf3ce44SJohn Forte */ 1256*fcf3ce44SJohn Forte bzero(front_elem, sizeof (struct device_element)); 1257*fcf3ce44SJohn Forte /* Set/reset power off bit */ 1258*fcf3ce44SJohn Forte front_elem->dev_off = power_off_flag; 1259*fcf3ce44SJohn Forte front_elem->select = 1; 1260*fcf3ce44SJohn Forte } 1261*fcf3ce44SJohn Forte if (!front || slot == -1) { 1262*fcf3ce44SJohn Forte /* Now do rear */ 1263*fcf3ce44SJohn Forte bzero(rear_elem, sizeof (struct device_element)); 1264*fcf3ce44SJohn Forte /* Set/reset power off bit */ 1265*fcf3ce44SJohn Forte rear_elem->dev_off = power_off_flag; 1266*fcf3ce44SJohn Forte rear_elem->select = 1; 1267*fcf3ce44SJohn Forte } 1268*fcf3ce44SJohn Forte 1269*fcf3ce44SJohn Forte if (getenv("_LUX_D_DEBUG") != NULL) { 1270*fcf3ce44SJohn Forte if (front || slot == -1) { 1271*fcf3ce44SJohn Forte g_dump(" pwr_up_down: " 1272*fcf3ce44SJohn Forte "Front Device Status Element ", 1273*fcf3ce44SJohn Forte (uchar_t *)front_elem, 1274*fcf3ce44SJohn Forte sizeof (struct device_element), 1275*fcf3ce44SJohn Forte HEX_ONLY); 1276*fcf3ce44SJohn Forte } 1277*fcf3ce44SJohn Forte if (!front || slot == -1) { 1278*fcf3ce44SJohn Forte g_dump(" pwr_up_down: " 1279*fcf3ce44SJohn Forte "Rear Device Status Element ", 1280*fcf3ce44SJohn Forte (uchar_t *)rear_elem, 1281*fcf3ce44SJohn Forte sizeof (struct device_element), 1282*fcf3ce44SJohn Forte HEX_ONLY); 1283*fcf3ce44SJohn Forte } 1284*fcf3ce44SJohn Forte } 1285*fcf3ce44SJohn Forte if (err = g_scsi_send_diag_cmd(fd, 1286*fcf3ce44SJohn Forte (uchar_t *)page_buf, page_len)) { 1287*fcf3ce44SJohn Forte (void) close(fd); 1288*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 1289*fcf3ce44SJohn Forte return (err); 1290*fcf3ce44SJohn Forte } 1291*fcf3ce44SJohn Forte (void) close(fd); 1292*fcf3ce44SJohn Forte (void) g_destroy_data(page_buf); 1293*fcf3ce44SJohn Forte return (0); 1294*fcf3ce44SJohn Forte } 1295*fcf3ce44SJohn Forte 1296*fcf3ce44SJohn Forte /* 1297*fcf3ce44SJohn Forte * Set the password of the FPM by sending the password 1298*fcf3ce44SJohn Forte * in page 4 of the Send Diagnostic command. 1299*fcf3ce44SJohn Forte * 1300*fcf3ce44SJohn Forte * The path must point to an IB. 1301*fcf3ce44SJohn Forte * 1302*fcf3ce44SJohn Forte * The size of the password string must be <= 8 bytes. 1303*fcf3ce44SJohn Forte * The string can also be NULL. This is the way the user 1304*fcf3ce44SJohn Forte * chooses to not have a password. 1305*fcf3ce44SJohn Forte * 1306*fcf3ce44SJohn Forte * I then tell the photon by giving him 4 NULL bytes. 1307*fcf3ce44SJohn Forte * 1308*fcf3ce44SJohn Forte * RETURNS: 1309*fcf3ce44SJohn Forte * 0 O.K. 1310*fcf3ce44SJohn Forte * non-zero otherwise 1311*fcf3ce44SJohn Forte */ 1312*fcf3ce44SJohn Forte int 1313*fcf3ce44SJohn Forte l_new_password(char *path_phys, char *password) 1314*fcf3ce44SJohn Forte { 1315*fcf3ce44SJohn Forte Page4_name page4; 1316*fcf3ce44SJohn Forte L_inquiry inq; 1317*fcf3ce44SJohn Forte int fd, status; 1318*fcf3ce44SJohn Forte 1319*fcf3ce44SJohn Forte (void) memset(&inq, 0, sizeof (inq)); 1320*fcf3ce44SJohn Forte (void) memset(&page4, 0, sizeof (page4)); 1321*fcf3ce44SJohn Forte 1322*fcf3ce44SJohn Forte if ((fd = g_object_open(path_phys, O_NDELAY | O_RDONLY)) == -1) { 1323*fcf3ce44SJohn Forte return (L_OPEN_PATH_FAIL); 1324*fcf3ce44SJohn Forte } 1325*fcf3ce44SJohn Forte /* Verify it is a Photon */ 1326*fcf3ce44SJohn Forte if (status = g_scsi_inquiry_cmd(fd, 1327*fcf3ce44SJohn Forte (uchar_t *)&inq, sizeof (struct l_inquiry_struct))) { 1328*fcf3ce44SJohn Forte (void) close(fd); 1329*fcf3ce44SJohn Forte return (status); 1330*fcf3ce44SJohn Forte } 1331*fcf3ce44SJohn Forte if ((strstr((char *)inq.inq_pid, ENCLOSURE_PROD_ID) == 0) && 1332*fcf3ce44SJohn Forte (!(strncmp((char *)inq.inq_vid, "SUN ", 1333*fcf3ce44SJohn Forte sizeof (inq.inq_vid)) && 1334*fcf3ce44SJohn Forte ((inq.inq_dtype & DTYPE_MASK) == DTYPE_ESI)))) { 1335*fcf3ce44SJohn Forte (void) close(fd); 1336*fcf3ce44SJohn Forte return (L_ENCL_INVALID_PATH); 1337*fcf3ce44SJohn Forte } 1338*fcf3ce44SJohn Forte 1339*fcf3ce44SJohn Forte page4.page_code = L_PAGE_4; 1340*fcf3ce44SJohn Forte page4.page_len = (ushort_t)max((strlen(password) + 4), 8); 1341*fcf3ce44SJohn Forte /* Double check */ 1342*fcf3ce44SJohn Forte if (strlen(password) > 8) { 1343*fcf3ce44SJohn Forte return (L_INVALID_PASSWORD_LEN); 1344*fcf3ce44SJohn Forte } 1345*fcf3ce44SJohn Forte page4.string_code = L_PASSWORD; 1346*fcf3ce44SJohn Forte page4.enable = 1; 1347*fcf3ce44SJohn Forte (void) strcpy((char *)page4.name, password); 1348*fcf3ce44SJohn Forte 1349*fcf3ce44SJohn Forte if (status = g_scsi_send_diag_cmd(fd, (uchar_t *)&page4, 1350*fcf3ce44SJohn Forte page4.page_len + HEADER_LEN)) { 1351*fcf3ce44SJohn Forte (void) close(fd); 1352*fcf3ce44SJohn Forte return (status); 1353*fcf3ce44SJohn Forte } 1354*fcf3ce44SJohn Forte 1355*fcf3ce44SJohn Forte (void) close(fd); 1356*fcf3ce44SJohn Forte return (0); 1357*fcf3ce44SJohn Forte } 1358*fcf3ce44SJohn Forte 1359*fcf3ce44SJohn Forte 1360*fcf3ce44SJohn Forte 1361*fcf3ce44SJohn Forte /* 1362*fcf3ce44SJohn Forte * Set the name of the enclosure by sending the name 1363*fcf3ce44SJohn Forte * in page 4 of the Send Diagnostic command. 1364*fcf3ce44SJohn Forte * 1365*fcf3ce44SJohn Forte * The path must point to an IB. 1366*fcf3ce44SJohn Forte * 1367*fcf3ce44SJohn Forte * RETURNS: 1368*fcf3ce44SJohn Forte * 0 O.K. 1369*fcf3ce44SJohn Forte * non-zero otherwise 1370*fcf3ce44SJohn Forte */ 1371*fcf3ce44SJohn Forte int 1372*fcf3ce44SJohn Forte l_new_name(char *path_phys, char *name) 1373*fcf3ce44SJohn Forte { 1374*fcf3ce44SJohn Forte Page4_name page4; 1375*fcf3ce44SJohn Forte L_inquiry inq; 1376*fcf3ce44SJohn Forte int fd, status; 1377*fcf3ce44SJohn Forte 1378*fcf3ce44SJohn Forte if ((path_phys == NULL) || (name == NULL)) { 1379*fcf3ce44SJohn Forte return (L_INVALID_PATH_FORMAT); 1380*fcf3ce44SJohn Forte } 1381*fcf3ce44SJohn Forte 1382*fcf3ce44SJohn Forte (void) memset(&inq, 0, sizeof (inq)); 1383*fcf3ce44SJohn Forte (void) memset(&page4, 0, sizeof (page4)); 1384*fcf3ce44SJohn Forte 1385*fcf3ce44SJohn Forte if ((fd = g_object_open(path_phys, O_NDELAY | O_RDONLY)) == -1) { 1386*fcf3ce44SJohn Forte return (L_OPEN_PATH_FAIL); 1387*fcf3ce44SJohn Forte } 1388*fcf3ce44SJohn Forte /* Verify it is a Photon */ 1389*fcf3ce44SJohn Forte if (status = g_scsi_inquiry_cmd(fd, 1390*fcf3ce44SJohn Forte (uchar_t *)&inq, sizeof (struct l_inquiry_struct))) { 1391*fcf3ce44SJohn Forte (void) close(fd); 1392*fcf3ce44SJohn Forte return (status); 1393*fcf3ce44SJohn Forte } 1394*fcf3ce44SJohn Forte if ((strstr((char *)inq.inq_pid, ENCLOSURE_PROD_ID) == 0) && 1395*fcf3ce44SJohn Forte (!(strncmp((char *)inq.inq_vid, "SUN ", 1396*fcf3ce44SJohn Forte sizeof (inq.inq_vid)) && 1397*fcf3ce44SJohn Forte ((inq.inq_dtype & DTYPE_MASK) == DTYPE_ESI)))) { 1398*fcf3ce44SJohn Forte (void) close(fd); 1399*fcf3ce44SJohn Forte return (L_ENCL_INVALID_PATH); 1400*fcf3ce44SJohn Forte } 1401*fcf3ce44SJohn Forte 1402*fcf3ce44SJohn Forte page4.page_code = L_PAGE_4; 1403*fcf3ce44SJohn Forte page4.page_len = (ushort_t)((sizeof (struct page4_name) - 4)); 1404*fcf3ce44SJohn Forte page4.string_code = L_ENCL_NAME; 1405*fcf3ce44SJohn Forte page4.enable = 1; 1406*fcf3ce44SJohn Forte strncpy((char *)page4.name, name, sizeof (page4.name)); 1407*fcf3ce44SJohn Forte 1408*fcf3ce44SJohn Forte if (status = g_scsi_send_diag_cmd(fd, (uchar_t *)&page4, 1409*fcf3ce44SJohn Forte sizeof (page4))) { 1410*fcf3ce44SJohn Forte (void) close(fd); 1411*fcf3ce44SJohn Forte return (status); 1412*fcf3ce44SJohn Forte } 1413*fcf3ce44SJohn Forte 1414*fcf3ce44SJohn Forte /* 1415*fcf3ce44SJohn Forte * Check the name really changed. 1416*fcf3ce44SJohn Forte */ 1417*fcf3ce44SJohn Forte if (status = g_scsi_inquiry_cmd(fd, 1418*fcf3ce44SJohn Forte (uchar_t *)&inq, sizeof (struct l_inquiry_struct))) { 1419*fcf3ce44SJohn Forte (void) close(fd); 1420*fcf3ce44SJohn Forte return (status); 1421*fcf3ce44SJohn Forte } 1422*fcf3ce44SJohn Forte if (strncmp((char *)inq.inq_box_name, name, sizeof (page4.name)) != 0) { 1423*fcf3ce44SJohn Forte char name_buf[MAXNAMELEN]; 1424*fcf3ce44SJohn Forte (void) close(fd); 1425*fcf3ce44SJohn Forte strncpy((char *)name_buf, (char *)inq.inq_box_name, 1426*fcf3ce44SJohn Forte sizeof (inq.inq_box_name)); 1427*fcf3ce44SJohn Forte return (L_ENCL_NAME_CHANGE_FAIL); 1428*fcf3ce44SJohn Forte } 1429*fcf3ce44SJohn Forte 1430*fcf3ce44SJohn Forte (void) close(fd); 1431*fcf3ce44SJohn Forte return (0); 1432*fcf3ce44SJohn Forte } 1433*fcf3ce44SJohn Forte 1434*fcf3ce44SJohn Forte 1435*fcf3ce44SJohn Forte 1436*fcf3ce44SJohn Forte /* 1437*fcf3ce44SJohn Forte * Issue a Loop Port enable Primitive sequence 1438*fcf3ce44SJohn Forte * to the device specified by the pathname. 1439*fcf3ce44SJohn Forte */ 1440*fcf3ce44SJohn Forte int 1441*fcf3ce44SJohn Forte l_enable(char *path, int verbose) 1442*fcf3ce44SJohn Forte /*ARGSUSED*/ 1443*fcf3ce44SJohn Forte { 1444*fcf3ce44SJohn Forte 1445*fcf3ce44SJohn Forte return (0); 1446*fcf3ce44SJohn Forte } 1447*fcf3ce44SJohn Forte 1448*fcf3ce44SJohn Forte /* 1449*fcf3ce44SJohn Forte * Issue a Loop Port Bypass Primitive sequence 1450*fcf3ce44SJohn Forte * to the device specified by the pathname. This requests the 1451*fcf3ce44SJohn Forte * device to set its L_Port into the bypass mode. 1452*fcf3ce44SJohn Forte */ 1453*fcf3ce44SJohn Forte int 1454*fcf3ce44SJohn Forte l_bypass(char *path, int verbose) 1455*fcf3ce44SJohn Forte /*ARGSUSED*/ 1456*fcf3ce44SJohn Forte { 1457*fcf3ce44SJohn Forte 1458*fcf3ce44SJohn Forte return (0); 1459*fcf3ce44SJohn Forte } 1460*fcf3ce44SJohn Forte 1461*fcf3ce44SJohn Forte 1462*fcf3ce44SJohn Forte 1463*fcf3ce44SJohn Forte /* 1464*fcf3ce44SJohn Forte * Create a linked list of all the Photon enclosures that 1465*fcf3ce44SJohn Forte * are attached to this host. 1466*fcf3ce44SJohn Forte * 1467*fcf3ce44SJohn Forte * RETURN VALUES: 0 O.K. 1468*fcf3ce44SJohn Forte * 1469*fcf3ce44SJohn Forte * box_list pointer: 1470*fcf3ce44SJohn Forte * NULL: No enclosures found. 1471*fcf3ce44SJohn Forte * !NULL: Enclosures found 1472*fcf3ce44SJohn Forte * box_list points to a linked list of boxes. 1473*fcf3ce44SJohn Forte */ 1474*fcf3ce44SJohn Forte int 1475*fcf3ce44SJohn Forte l_get_box_list(struct box_list_struct **box_list_ptr, int verbose) 1476*fcf3ce44SJohn Forte { 1477*fcf3ce44SJohn Forte char *dev_name; 1478*fcf3ce44SJohn Forte DIR *dirp; 1479*fcf3ce44SJohn Forte struct dirent *entp; 1480*fcf3ce44SJohn Forte char namebuf[MAXPATHLEN]; 1481*fcf3ce44SJohn Forte struct stat sb; 1482*fcf3ce44SJohn Forte char *result = NULL; 1483*fcf3ce44SJohn Forte int fd, status; 1484*fcf3ce44SJohn Forte L_inquiry inq; 1485*fcf3ce44SJohn Forte Box_list *box_list, *l1, *l2; 1486*fcf3ce44SJohn Forte IB_page_config page1; 1487*fcf3ce44SJohn Forte uchar_t node_wwn[WWN_SIZE], port_wwn[WWN_SIZE]; 1488*fcf3ce44SJohn Forte int al_pa; 1489*fcf3ce44SJohn Forte 1490*fcf3ce44SJohn Forte if (box_list_ptr == NULL) { 1491*fcf3ce44SJohn Forte return (L_INVALID_PATH_FORMAT); 1492*fcf3ce44SJohn Forte } 1493*fcf3ce44SJohn Forte 1494*fcf3ce44SJohn Forte box_list = *box_list_ptr = NULL; 1495*fcf3ce44SJohn Forte if ((dev_name = (char *)g_zalloc(sizeof ("/dev/es"))) == NULL) { 1496*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 1497*fcf3ce44SJohn Forte } 1498*fcf3ce44SJohn Forte (void) sprintf((char *)dev_name, "/dev/es"); 1499*fcf3ce44SJohn Forte 1500*fcf3ce44SJohn Forte if (verbose) { 1501*fcf3ce44SJohn Forte (void) fprintf(stdout, 1502*fcf3ce44SJohn Forte MSGSTR(9045, 1503*fcf3ce44SJohn Forte " Searching directory %s for links to enclosures\n"), 1504*fcf3ce44SJohn Forte dev_name); 1505*fcf3ce44SJohn Forte } 1506*fcf3ce44SJohn Forte 1507*fcf3ce44SJohn Forte if ((dirp = opendir(dev_name)) == NULL) { 1508*fcf3ce44SJohn Forte (void) g_destroy_data(dev_name); 1509*fcf3ce44SJohn Forte /* No Photons found */ 1510*fcf3ce44SJohn Forte B_DPRINTF(" l_get_box_list: No Photons found\n"); 1511*fcf3ce44SJohn Forte return (0); 1512*fcf3ce44SJohn Forte } 1513*fcf3ce44SJohn Forte 1514*fcf3ce44SJohn Forte 1515*fcf3ce44SJohn Forte while ((entp = readdir(dirp)) != NULL) { 1516*fcf3ce44SJohn Forte if (strcmp(entp->d_name, ".") == 0 || 1517*fcf3ce44SJohn Forte strcmp(entp->d_name, "..") == 0) 1518*fcf3ce44SJohn Forte continue; 1519*fcf3ce44SJohn Forte 1520*fcf3ce44SJohn Forte (void) sprintf(namebuf, "%s/%s", dev_name, entp->d_name); 1521*fcf3ce44SJohn Forte 1522*fcf3ce44SJohn Forte if ((lstat(namebuf, &sb)) < 0) { 1523*fcf3ce44SJohn Forte ER_DPRINTF("Warning: Cannot stat %s\n", 1524*fcf3ce44SJohn Forte namebuf); 1525*fcf3ce44SJohn Forte continue; 1526*fcf3ce44SJohn Forte } 1527*fcf3ce44SJohn Forte 1528*fcf3ce44SJohn Forte if (!S_ISLNK(sb.st_mode)) { 1529*fcf3ce44SJohn Forte ER_DPRINTF("Warning: %s is not a symbolic link\n", 1530*fcf3ce44SJohn Forte namebuf); 1531*fcf3ce44SJohn Forte continue; 1532*fcf3ce44SJohn Forte } 1533*fcf3ce44SJohn Forte if ((result = g_get_physical_name_from_link(namebuf)) == NULL) { 1534*fcf3ce44SJohn Forte ER_DPRINTF(" Warning: Get physical name from" 1535*fcf3ce44SJohn Forte " link failed. Link=%s\n", namebuf); 1536*fcf3ce44SJohn Forte continue; 1537*fcf3ce44SJohn Forte } 1538*fcf3ce44SJohn Forte 1539*fcf3ce44SJohn Forte /* Found a SES card. */ 1540*fcf3ce44SJohn Forte B_DPRINTF(" l_get_box_list: Link to SES Card found: %s/%s\n", 1541*fcf3ce44SJohn Forte dev_name, entp->d_name); 1542*fcf3ce44SJohn Forte if ((fd = g_object_open(result, O_NDELAY | O_RDONLY)) == -1) { 1543*fcf3ce44SJohn Forte g_destroy_data(result); 1544*fcf3ce44SJohn Forte continue; /* Ignore errors */ 1545*fcf3ce44SJohn Forte } 1546*fcf3ce44SJohn Forte /* Get the box name */ 1547*fcf3ce44SJohn Forte if (status = g_scsi_inquiry_cmd(fd, 1548*fcf3ce44SJohn Forte (uchar_t *)&inq, sizeof (struct l_inquiry_struct))) { 1549*fcf3ce44SJohn Forte (void) close(fd); 1550*fcf3ce44SJohn Forte g_destroy_data(result); 1551*fcf3ce44SJohn Forte continue; /* Ignore errors */ 1552*fcf3ce44SJohn Forte } 1553*fcf3ce44SJohn Forte 1554*fcf3ce44SJohn Forte if ((strstr((char *)inq.inq_pid, ENCLOSURE_PROD_ID) != NULL) || 1555*fcf3ce44SJohn Forte (((inq.inq_dtype & DTYPE_MASK) == DTYPE_ESI) && 1556*fcf3ce44SJohn Forte (l_get_enc_type(inq) == DAK_ENC_TYPE))) { 1557*fcf3ce44SJohn Forte /* 1558*fcf3ce44SJohn Forte * Found Photon/Daktari 1559*fcf3ce44SJohn Forte */ 1560*fcf3ce44SJohn Forte 1561*fcf3ce44SJohn Forte /* Get the port WWN from the IB, page 1 */ 1562*fcf3ce44SJohn Forte if ((status = l_get_envsen_page(fd, (uchar_t *)&page1, 1563*fcf3ce44SJohn Forte sizeof (page1), 1, 0)) != NULL) { 1564*fcf3ce44SJohn Forte (void) close(fd); 1565*fcf3ce44SJohn Forte g_destroy_data(result); 1566*fcf3ce44SJohn Forte (void) g_destroy_data(dev_name); 1567*fcf3ce44SJohn Forte closedir(dirp); 1568*fcf3ce44SJohn Forte return (status); 1569*fcf3ce44SJohn Forte } 1570*fcf3ce44SJohn Forte 1571*fcf3ce44SJohn Forte /* 1572*fcf3ce44SJohn Forte * Build list of names. 1573*fcf3ce44SJohn Forte */ 1574*fcf3ce44SJohn Forte if ((l2 = (struct box_list_struct *) 1575*fcf3ce44SJohn Forte g_zalloc(sizeof (struct box_list_struct))) 1576*fcf3ce44SJohn Forte == NULL) { 1577*fcf3ce44SJohn Forte (void) close(fd); 1578*fcf3ce44SJohn Forte g_destroy_data(result); 1579*fcf3ce44SJohn Forte g_destroy_data(dev_name); 1580*fcf3ce44SJohn Forte closedir(dirp); 1581*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 1582*fcf3ce44SJohn Forte } 1583*fcf3ce44SJohn Forte 1584*fcf3ce44SJohn Forte /* Fill in structure */ 1585*fcf3ce44SJohn Forte (void) strcpy((char *)l2->b_physical_path, 1586*fcf3ce44SJohn Forte (char *)result); 1587*fcf3ce44SJohn Forte (void) strcpy((char *)l2->logical_path, 1588*fcf3ce44SJohn Forte (char *)namebuf); 1589*fcf3ce44SJohn Forte bcopy((void *)page1.enc_node_wwn, 1590*fcf3ce44SJohn Forte (void *)l2->b_node_wwn, WWN_SIZE); 1591*fcf3ce44SJohn Forte (void) sprintf(l2->b_node_wwn_s, 1592*fcf3ce44SJohn Forte "%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x", 1593*fcf3ce44SJohn Forte page1.enc_node_wwn[0], 1594*fcf3ce44SJohn Forte page1.enc_node_wwn[1], 1595*fcf3ce44SJohn Forte page1.enc_node_wwn[2], 1596*fcf3ce44SJohn Forte page1.enc_node_wwn[3], 1597*fcf3ce44SJohn Forte page1.enc_node_wwn[4], 1598*fcf3ce44SJohn Forte page1.enc_node_wwn[5], 1599*fcf3ce44SJohn Forte page1.enc_node_wwn[6], 1600*fcf3ce44SJohn Forte page1.enc_node_wwn[7]); 1601*fcf3ce44SJohn Forte strncpy((char *)l2->prod_id_s, 1602*fcf3ce44SJohn Forte (char *)inq.inq_pid, 1603*fcf3ce44SJohn Forte sizeof (inq.inq_pid)); 1604*fcf3ce44SJohn Forte strncpy((char *)l2->b_name, 1605*fcf3ce44SJohn Forte (char *)inq.inq_box_name, 1606*fcf3ce44SJohn Forte sizeof (inq.inq_box_name)); 1607*fcf3ce44SJohn Forte /* make sure null terminated */ 1608*fcf3ce44SJohn Forte l2->b_name[sizeof (l2->b_name) - 1] = NULL; 1609*fcf3ce44SJohn Forte 1610*fcf3ce44SJohn Forte /* 1611*fcf3ce44SJohn Forte * Now get the port WWN for the port 1612*fcf3ce44SJohn Forte * we are connected to. 1613*fcf3ce44SJohn Forte */ 1614*fcf3ce44SJohn Forte status = g_get_wwn(result, port_wwn, node_wwn, 1615*fcf3ce44SJohn Forte &al_pa, verbose); 1616*fcf3ce44SJohn Forte if (status == 0) { 1617*fcf3ce44SJohn Forte (void) sprintf(l2->b_port_wwn_s, 1618*fcf3ce44SJohn Forte "%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x", 1619*fcf3ce44SJohn Forte port_wwn[0], port_wwn[1], port_wwn[2], 1620*fcf3ce44SJohn Forte port_wwn[3], port_wwn[4], port_wwn[5], 1621*fcf3ce44SJohn Forte port_wwn[6], port_wwn[7]); 1622*fcf3ce44SJohn Forte bcopy((void *)port_wwn, 1623*fcf3ce44SJohn Forte (void *)l2->b_port_wwn, WWN_SIZE); 1624*fcf3ce44SJohn Forte 1625*fcf3ce44SJohn Forte B_DPRINTF(" l_get_box_list:" 1626*fcf3ce44SJohn Forte " Found enclosure named:%s\n", l2->b_name); 1627*fcf3ce44SJohn Forte 1628*fcf3ce44SJohn Forte if (box_list == NULL) { 1629*fcf3ce44SJohn Forte l1 = box_list = l2; 1630*fcf3ce44SJohn Forte } else { 1631*fcf3ce44SJohn Forte l2->box_prev = l1; 1632*fcf3ce44SJohn Forte l1 = l1->box_next = l2; 1633*fcf3ce44SJohn Forte } 1634*fcf3ce44SJohn Forte } else { 1635*fcf3ce44SJohn Forte (void) close(fd); 1636*fcf3ce44SJohn Forte g_destroy_data(result); 1637*fcf3ce44SJohn Forte (void) g_destroy_data(dev_name); 1638*fcf3ce44SJohn Forte (void) g_destroy_data(l2); 1639*fcf3ce44SJohn Forte closedir(dirp); 1640*fcf3ce44SJohn Forte return (status); 1641*fcf3ce44SJohn Forte } 1642*fcf3ce44SJohn Forte 1643*fcf3ce44SJohn Forte } 1644*fcf3ce44SJohn Forte g_destroy_data(result); 1645*fcf3ce44SJohn Forte (void) close(fd); 1646*fcf3ce44SJohn Forte *box_list_ptr = box_list; /* pass back ptr to list */ 1647*fcf3ce44SJohn Forte } 1648*fcf3ce44SJohn Forte (void) g_destroy_data(dev_name); 1649*fcf3ce44SJohn Forte closedir(dirp); 1650*fcf3ce44SJohn Forte return (0); 1651*fcf3ce44SJohn Forte } 1652*fcf3ce44SJohn Forte 1653*fcf3ce44SJohn Forte void 1654*fcf3ce44SJohn Forte l_free_box_list(struct box_list_struct **box_list) 1655*fcf3ce44SJohn Forte { 1656*fcf3ce44SJohn Forte Box_list *next = NULL; 1657*fcf3ce44SJohn Forte 1658*fcf3ce44SJohn Forte if (box_list == NULL) { 1659*fcf3ce44SJohn Forte return; 1660*fcf3ce44SJohn Forte } 1661*fcf3ce44SJohn Forte 1662*fcf3ce44SJohn Forte for (; *box_list != NULL; *box_list = next) { 1663*fcf3ce44SJohn Forte next = (*box_list)->box_next; 1664*fcf3ce44SJohn Forte (void) g_destroy_data(*box_list); 1665*fcf3ce44SJohn Forte } 1666*fcf3ce44SJohn Forte 1667*fcf3ce44SJohn Forte *box_list = NULL; 1668*fcf3ce44SJohn Forte } 1669*fcf3ce44SJohn Forte 1670*fcf3ce44SJohn Forte 1671*fcf3ce44SJohn Forte 1672*fcf3ce44SJohn Forte /* 1673*fcf3ce44SJohn Forte * Finds out if there are any other boxes 1674*fcf3ce44SJohn Forte * with the same name as "name". 1675*fcf3ce44SJohn Forte * 1676*fcf3ce44SJohn Forte * RETURNS: 1677*fcf3ce44SJohn Forte * 0 There are no other boxes with the same name. 1678*fcf3ce44SJohn Forte * >0 if duplicate names found 1679*fcf3ce44SJohn Forte */ 1680*fcf3ce44SJohn Forte /*ARGSUSED*/ 1681*fcf3ce44SJohn Forte int 1682*fcf3ce44SJohn Forte l_duplicate_names(Box_list *b_list, char wwn[], char *name, int verbose) 1683*fcf3ce44SJohn Forte { 1684*fcf3ce44SJohn Forte int dup_flag = 0; 1685*fcf3ce44SJohn Forte Box_list *box_list_ptr = NULL; 1686*fcf3ce44SJohn Forte 1687*fcf3ce44SJohn Forte if ((name == NULL) || (wwn == NULL)) 1688*fcf3ce44SJohn Forte return (0); 1689*fcf3ce44SJohn Forte 1690*fcf3ce44SJohn Forte box_list_ptr = b_list; 1691*fcf3ce44SJohn Forte while (box_list_ptr != NULL) { 1692*fcf3ce44SJohn Forte if ((strcmp(name, (const char *)box_list_ptr->b_name) == 0) && 1693*fcf3ce44SJohn Forte (strcmp(box_list_ptr->b_node_wwn_s, wwn) != 0)) { 1694*fcf3ce44SJohn Forte dup_flag++; 1695*fcf3ce44SJohn Forte break; 1696*fcf3ce44SJohn Forte } 1697*fcf3ce44SJohn Forte box_list_ptr = box_list_ptr->box_next; 1698*fcf3ce44SJohn Forte } 1699*fcf3ce44SJohn Forte return (dup_flag); 1700*fcf3ce44SJohn Forte } 1701*fcf3ce44SJohn Forte 1702*fcf3ce44SJohn Forte 1703*fcf3ce44SJohn Forte 1704*fcf3ce44SJohn Forte /* 1705*fcf3ce44SJohn Forte * Checks for a name conflict with an SSA cN type name. 1706*fcf3ce44SJohn Forte */ 1707*fcf3ce44SJohn Forte int 1708*fcf3ce44SJohn Forte l_get_conflict(char *name, char **result, int verbose) 1709*fcf3ce44SJohn Forte { 1710*fcf3ce44SJohn Forte char s[MAXPATHLEN]; 1711*fcf3ce44SJohn Forte char *p = NULL; 1712*fcf3ce44SJohn Forte char *pp = NULL; 1713*fcf3ce44SJohn Forte Box_list *box_list = NULL; 1714*fcf3ce44SJohn Forte int found_box = 0, err = 0; 1715*fcf3ce44SJohn Forte 1716*fcf3ce44SJohn Forte (void) strcpy(s, name); 1717*fcf3ce44SJohn Forte if ((*result = g_get_physical_name(s)) == NULL) { 1718*fcf3ce44SJohn Forte return (0); 1719*fcf3ce44SJohn Forte } 1720*fcf3ce44SJohn Forte if ((strstr((const char *)*result, PLNDEF)) == NULL) { 1721*fcf3ce44SJohn Forte (void) g_destroy_data(*result); 1722*fcf3ce44SJohn Forte *result = NULL; 1723*fcf3ce44SJohn Forte return (0); 1724*fcf3ce44SJohn Forte } 1725*fcf3ce44SJohn Forte P_DPRINTF(" l_get_conflict: Found " 1726*fcf3ce44SJohn Forte "SSA path using %s\n", s); 1727*fcf3ce44SJohn Forte /* Find path to IB */ 1728*fcf3ce44SJohn Forte if ((err = l_get_box_list(&box_list, verbose)) != 0) { 1729*fcf3ce44SJohn Forte return (err); /* Failure */ 1730*fcf3ce44SJohn Forte } 1731*fcf3ce44SJohn Forte /* 1732*fcf3ce44SJohn Forte * Valid cN type name found. 1733*fcf3ce44SJohn Forte */ 1734*fcf3ce44SJohn Forte while (box_list != NULL) { 1735*fcf3ce44SJohn Forte if ((strcmp((char *)s, 1736*fcf3ce44SJohn Forte (char *)box_list->b_name)) == 0) { 1737*fcf3ce44SJohn Forte found_box = 1; 1738*fcf3ce44SJohn Forte if (p == NULL) { 1739*fcf3ce44SJohn Forte if ((p = g_zalloc(strlen( 1740*fcf3ce44SJohn Forte box_list->b_physical_path) 1741*fcf3ce44SJohn Forte + 2)) == NULL) { 1742*fcf3ce44SJohn Forte (void) l_free_box_list(&box_list); 1743*fcf3ce44SJohn Forte return (errno); 1744*fcf3ce44SJohn Forte } 1745*fcf3ce44SJohn Forte } else { 1746*fcf3ce44SJohn Forte if ((pp = g_zalloc(strlen( 1747*fcf3ce44SJohn Forte box_list->b_physical_path) 1748*fcf3ce44SJohn Forte + strlen(p) 1749*fcf3ce44SJohn Forte + 2)) == NULL) { 1750*fcf3ce44SJohn Forte (void) l_free_box_list(&box_list); 1751*fcf3ce44SJohn Forte return (errno); 1752*fcf3ce44SJohn Forte } 1753*fcf3ce44SJohn Forte (void) strcpy(pp, p); 1754*fcf3ce44SJohn Forte (void) g_destroy_data(p); 1755*fcf3ce44SJohn Forte p = pp; 1756*fcf3ce44SJohn Forte } 1757*fcf3ce44SJohn Forte (void) strcat(p, box_list->b_physical_path); 1758*fcf3ce44SJohn Forte (void) strcat(p, "\n"); 1759*fcf3ce44SJohn Forte } 1760*fcf3ce44SJohn Forte box_list = box_list->box_next; 1761*fcf3ce44SJohn Forte } 1762*fcf3ce44SJohn Forte if (found_box) { 1763*fcf3ce44SJohn Forte D_DPRINTF("There is a conflict between the " 1764*fcf3ce44SJohn Forte "enclosure\nwith this name, %s, " 1765*fcf3ce44SJohn Forte "and a SSA name of the same form.\n" 1766*fcf3ce44SJohn Forte "Please use one of the following physical " 1767*fcf3ce44SJohn Forte "pathnames:\n%s\n%s\n", 1768*fcf3ce44SJohn Forte s, *result, p); 1769*fcf3ce44SJohn Forte 1770*fcf3ce44SJohn Forte (void) l_free_box_list(&box_list); 1771*fcf3ce44SJohn Forte (void) g_destroy_data(p); 1772*fcf3ce44SJohn Forte return (L_SSA_CONFLICT); /* failure */ 1773*fcf3ce44SJohn Forte } 1774*fcf3ce44SJohn Forte (void) l_free_box_list(&box_list); 1775*fcf3ce44SJohn Forte return (0); 1776*fcf3ce44SJohn Forte } 1777*fcf3ce44SJohn Forte 1778*fcf3ce44SJohn Forte /* 1779*fcf3ce44SJohn Forte * This function sets the "slot", "slot_valid" and "f_flag" fields of the 1780*fcf3ce44SJohn Forte * path_struct that is passed in IFF the device path passed in ("phys_path") 1781*fcf3ce44SJohn Forte * is a disk in an A5K or a Daktari. This is achieved by calling l_get_slot(). 1782*fcf3ce44SJohn Forte * 1783*fcf3ce44SJohn Forte * INPUT : 1784*fcf3ce44SJohn Forte * phys_path - physical path to a device 1785*fcf3ce44SJohn Forte * path_sturct - Pointer to pointer to a path_struct data structure 1786*fcf3ce44SJohn Forte * 1787*fcf3ce44SJohn Forte * OUTPUT : 1788*fcf3ce44SJohn Forte * if phys_path is that of an A5K/Daktari disk 1789*fcf3ce44SJohn Forte * path_struct->slot is set to the slot position in enclosure 1790*fcf3ce44SJohn Forte * path_struct->slot_valid is set to 1 1791*fcf3ce44SJohn Forte * path_struct->f_flag is set to 1 if in the front of an A5k 1792*fcf3ce44SJohn Forte * or if among the first 6 disks on a Daktari 1793*fcf3ce44SJohn Forte * else 1794*fcf3ce44SJohn Forte * they are left as they were 1795*fcf3ce44SJohn Forte * RETURNS: 1796*fcf3ce44SJohn Forte * 0 on SUCCESS 1797*fcf3ce44SJohn Forte * non-zero otherwise 1798*fcf3ce44SJohn Forte */ 1799*fcf3ce44SJohn Forte static int 1800*fcf3ce44SJohn Forte load_flds_if_enc_disk(char *phys_path, struct path_struct **path_struct) 1801*fcf3ce44SJohn Forte { 1802*fcf3ce44SJohn Forte int err = 0, verbose = 0; 1803*fcf3ce44SJohn Forte char ses_path[MAXPATHLEN]; 1804*fcf3ce44SJohn Forte gfc_map_t map; 1805*fcf3ce44SJohn Forte L_inquiry inq; 1806*fcf3ce44SJohn Forte L_state *l_state = NULL; 1807*fcf3ce44SJohn Forte 1808*fcf3ce44SJohn Forte if ((path_struct == NULL) || (*path_struct == NULL) || 1809*fcf3ce44SJohn Forte (phys_path == NULL) || (*phys_path == NULL)) { 1810*fcf3ce44SJohn Forte return (L_INVALID_PATH_FORMAT); 1811*fcf3ce44SJohn Forte } 1812*fcf3ce44SJohn Forte 1813*fcf3ce44SJohn Forte if ((strstr(phys_path, SLSH_DRV_NAME_SSD) == NULL) || 1814*fcf3ce44SJohn Forte (g_get_path_type(phys_path) == 0)) { 1815*fcf3ce44SJohn Forte /* 1816*fcf3ce44SJohn Forte * Don't proceed when not a disk device or if it is not a 1817*fcf3ce44SJohn Forte * valid FC device on which g_get_dev_map() can be done 1818*fcf3ce44SJohn Forte * (for example, g_get_dev_map() will fail on SSAs). 1819*fcf3ce44SJohn Forte * 1820*fcf3ce44SJohn Forte * Just return success 1821*fcf3ce44SJohn Forte */ 1822*fcf3ce44SJohn Forte return (0); 1823*fcf3ce44SJohn Forte } 1824*fcf3ce44SJohn Forte 1825*fcf3ce44SJohn Forte if ((*path_struct)->ib_path_flag) { 1826*fcf3ce44SJohn Forte /* 1827*fcf3ce44SJohn Forte * If this flag is set, l_get_slot() should not be called 1828*fcf3ce44SJohn Forte * So, no point in proceeding. Just return success. 1829*fcf3ce44SJohn Forte */ 1830*fcf3ce44SJohn Forte return (0); 1831*fcf3ce44SJohn Forte } 1832*fcf3ce44SJohn Forte 1833*fcf3ce44SJohn Forte if ((err = g_get_dev_map(phys_path, &map, verbose)) != 0) { 1834*fcf3ce44SJohn Forte return (err); 1835*fcf3ce44SJohn Forte } 1836*fcf3ce44SJohn Forte 1837*fcf3ce44SJohn Forte if ((err = l_get_ses_path(phys_path, ses_path, &map, verbose)) != 0) { 1838*fcf3ce44SJohn Forte (void) free(map.dev_addr); 1839*fcf3ce44SJohn Forte if (err == L_NO_SES_PATH) { 1840*fcf3ce44SJohn Forte /* 1841*fcf3ce44SJohn Forte * This is not an error since this could be a device 1842*fcf3ce44SJohn Forte * which does not have SES nodes 1843*fcf3ce44SJohn Forte */ 1844*fcf3ce44SJohn Forte return (0); 1845*fcf3ce44SJohn Forte } 1846*fcf3ce44SJohn Forte return (err); 1847*fcf3ce44SJohn Forte } 1848*fcf3ce44SJohn Forte 1849*fcf3ce44SJohn Forte /* 1850*fcf3ce44SJohn Forte * There is a SES path on the same FCA as the given disk. But if the 1851*fcf3ce44SJohn Forte * SES node is not of a photon/Daktari, we dont proceed 1852*fcf3ce44SJohn Forte */ 1853*fcf3ce44SJohn Forte if ((err = g_get_inquiry(ses_path, &inq)) != 0) { 1854*fcf3ce44SJohn Forte (void) free(map.dev_addr); 1855*fcf3ce44SJohn Forte return (err); 1856*fcf3ce44SJohn Forte } 1857*fcf3ce44SJohn Forte 1858*fcf3ce44SJohn Forte /* 1859*fcf3ce44SJohn Forte * only want to continue if this is a photon or a Daktari 1860*fcf3ce44SJohn Forte * 1861*fcf3ce44SJohn Forte * if product ID is not SENA or VID is not "SUN" (checks for photon) 1862*fcf3ce44SJohn Forte * and if enclosure type is not a Daktari, then I return 1863*fcf3ce44SJohn Forte */ 1864*fcf3ce44SJohn Forte if (((strstr((char *)inq.inq_pid, ENCLOSURE_PROD_ID) == 0) || 1865*fcf3ce44SJohn Forte (strncmp((char *)inq.inq_vid, "SUN ", 1866*fcf3ce44SJohn Forte sizeof (inq.inq_vid)) != 0)) && 1867*fcf3ce44SJohn Forte ((l_get_enc_type(inq) != DAK_ENC_TYPE))) { 1868*fcf3ce44SJohn Forte /* Not a photon/Daktari */ 1869*fcf3ce44SJohn Forte (void) free(map.dev_addr); 1870*fcf3ce44SJohn Forte return (0); 1871*fcf3ce44SJohn Forte } 1872*fcf3ce44SJohn Forte 1873*fcf3ce44SJohn Forte /* Now, set some fields that l_get_slot() uses and then call it */ 1874*fcf3ce44SJohn Forte if ((l_state = (L_state *)g_zalloc(sizeof (L_state))) == NULL) { 1875*fcf3ce44SJohn Forte (void) free(map.dev_addr); 1876*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 1877*fcf3ce44SJohn Forte } 1878*fcf3ce44SJohn Forte 1879*fcf3ce44SJohn Forte if ((err = l_get_ib_status(ses_path, l_state, verbose)) != 0) { 1880*fcf3ce44SJohn Forte (void) free(map.dev_addr); 1881*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 1882*fcf3ce44SJohn Forte return (err); 1883*fcf3ce44SJohn Forte } 1884*fcf3ce44SJohn Forte 1885*fcf3ce44SJohn Forte if ((err = l_get_slot(*path_struct, l_state, verbose)) != 0) { 1886*fcf3ce44SJohn Forte (void) free(map.dev_addr); 1887*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 1888*fcf3ce44SJohn Forte return (err); 1889*fcf3ce44SJohn Forte } 1890*fcf3ce44SJohn Forte 1891*fcf3ce44SJohn Forte (void) free(map.dev_addr); 1892*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 1893*fcf3ce44SJohn Forte return (0); 1894*fcf3ce44SJohn Forte } 1895*fcf3ce44SJohn Forte 1896*fcf3ce44SJohn Forte /* 1897*fcf3ce44SJohn Forte * convert box name or WWN or logical path to physical path. 1898*fcf3ce44SJohn Forte * 1899*fcf3ce44SJohn Forte * OUTPUT: 1900*fcf3ce44SJohn Forte * path_struct: 1901*fcf3ce44SJohn Forte * - This structure is used to return more detailed 1902*fcf3ce44SJohn Forte * information about the path. 1903*fcf3ce44SJohn Forte * - *p_physical_path 1904*fcf3ce44SJohn Forte * Normally this is the requested physical path. 1905*fcf3ce44SJohn Forte * If the requested path is not found then iff the 1906*fcf3ce44SJohn Forte * ib_path_flag is set this is the IB path. 1907*fcf3ce44SJohn Forte * - *argv 1908*fcf3ce44SJohn Forte * This is the argument variable input. e.g. Bob,f1 1909*fcf3ce44SJohn Forte * - slot_valid 1910*fcf3ce44SJohn Forte * - slot 1911*fcf3ce44SJohn Forte * This is the slot number that was entered when using 1912*fcf3ce44SJohn Forte * the box,[fr]slot format. It is only valid if the 1913*fcf3ce44SJohn Forte * slot_valid flag is set. 1914*fcf3ce44SJohn Forte * - f_flag 1915*fcf3ce44SJohn Forte * Front flag - If set, the requested device is located in the 1916*fcf3ce44SJohn Forte * front of the enclosure. 1917*fcf3ce44SJohn Forte * - ib_path_flag 1918*fcf3ce44SJohn Forte * If this flag is set it means a devices path was requested 1919*fcf3ce44SJohn Forte * but could not be found but an IB's path was found and 1920*fcf3ce44SJohn Forte * the p_physical_path points to that path. 1921*fcf3ce44SJohn Forte * - **phys_path 1922*fcf3ce44SJohn Forte * physical path to the device. 1923*fcf3ce44SJohn Forte * RETURNS: 1924*fcf3ce44SJohn Forte * - 0 if O.K. 1925*fcf3ce44SJohn Forte * - error otherwise. 1926*fcf3ce44SJohn Forte */ 1927*fcf3ce44SJohn Forte int 1928*fcf3ce44SJohn Forte l_convert_name(char *name, char **phys_path, 1929*fcf3ce44SJohn Forte struct path_struct **path_struct, int verbose) 1930*fcf3ce44SJohn Forte { 1931*fcf3ce44SJohn Forte char tmp_name[MAXPATHLEN], ses_path[MAXPATHLEN]; 1932*fcf3ce44SJohn Forte char *char_ptr, *ptr = NULL; 1933*fcf3ce44SJohn Forte char *result = NULL; 1934*fcf3ce44SJohn Forte char *env = NULL; 1935*fcf3ce44SJohn Forte char save_frd; /* which designator was it? */ 1936*fcf3ce44SJohn Forte int slot = 0, slot_flag = 0, found_box = 0, found_comma = 0; 1937*fcf3ce44SJohn Forte int err = 0, enc_type = 0; 1938*fcf3ce44SJohn Forte hrtime_t start_time, end_time; 1939*fcf3ce44SJohn Forte Box_list *box_list = NULL, *box_list_ptr = NULL; 1940*fcf3ce44SJohn Forte L_inquiry inq; 1941*fcf3ce44SJohn Forte L_state *l_state = NULL; 1942*fcf3ce44SJohn Forte Path_struct *path_ptr = NULL; 1943*fcf3ce44SJohn Forte WWN_list *wwn_list, *wwn_list_ptr; 1944*fcf3ce44SJohn Forte 1945*fcf3ce44SJohn Forte if ((name == NULL) || (phys_path == NULL) || 1946*fcf3ce44SJohn Forte (path_struct == NULL)) { 1947*fcf3ce44SJohn Forte return (L_INVALID_PATH_FORMAT); 1948*fcf3ce44SJohn Forte } 1949*fcf3ce44SJohn Forte 1950*fcf3ce44SJohn Forte if ((env = getenv("_LUX_T_DEBUG")) != NULL) { 1951*fcf3ce44SJohn Forte start_time = gethrtime(); 1952*fcf3ce44SJohn Forte } 1953*fcf3ce44SJohn Forte 1954*fcf3ce44SJohn Forte if ((*path_struct = path_ptr = (struct path_struct *) 1955*fcf3ce44SJohn Forte g_zalloc(sizeof (struct path_struct))) == NULL) { 1956*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 1957*fcf3ce44SJohn Forte } 1958*fcf3ce44SJohn Forte 1959*fcf3ce44SJohn Forte *phys_path = NULL; 1960*fcf3ce44SJohn Forte /* 1961*fcf3ce44SJohn Forte * If the path contains a "/" then assume 1962*fcf3ce44SJohn Forte * it is a logical or physical path as the 1963*fcf3ce44SJohn Forte * box name or wwn can not contain "/"s. 1964*fcf3ce44SJohn Forte */ 1965*fcf3ce44SJohn Forte if (strchr(name, '/') != NULL) { 1966*fcf3ce44SJohn Forte if ((result = g_get_physical_name(name)) == NULL) { 1967*fcf3ce44SJohn Forte return (L_NO_PHYS_PATH); 1968*fcf3ce44SJohn Forte } 1969*fcf3ce44SJohn Forte 1970*fcf3ce44SJohn Forte path_ptr->p_physical_path = result; 1971*fcf3ce44SJohn Forte /* 1972*fcf3ce44SJohn Forte * Make sure it's a disk or tape path 1973*fcf3ce44SJohn Forte */ 1974*fcf3ce44SJohn Forte if (strstr(name, DEV_RDIR) || strstr(name, SLSH_DRV_NAME_SSD) || 1975*fcf3ce44SJohn Forte strstr(name, DEV_TAPE_DIR) || 1976*fcf3ce44SJohn Forte strstr(name, SLSH_DRV_NAME_ST)) { 1977*fcf3ce44SJohn Forte if ((err = g_get_inquiry(result, &inq)) != 0) { 1978*fcf3ce44SJohn Forte (void) free(result); 1979*fcf3ce44SJohn Forte return (L_SCSI_ERROR); 1980*fcf3ce44SJohn Forte } 1981*fcf3ce44SJohn Forte /* 1982*fcf3ce44SJohn Forte * Check to see if it is not a 1983*fcf3ce44SJohn Forte * A5K/v880/v890 disk 1984*fcf3ce44SJohn Forte * 1985*fcf3ce44SJohn Forte */ 1986*fcf3ce44SJohn Forte if (!g_enclDiskChk((char *)inq.inq_vid, 1987*fcf3ce44SJohn Forte (char *)inq.inq_pid)) { 1988*fcf3ce44SJohn Forte path_ptr->argv = name; 1989*fcf3ce44SJohn Forte *phys_path = result; 1990*fcf3ce44SJohn Forte return (0); 1991*fcf3ce44SJohn Forte } 1992*fcf3ce44SJohn Forte } 1993*fcf3ce44SJohn Forte 1994*fcf3ce44SJohn Forte if (err = load_flds_if_enc_disk(result, path_struct)) { 1995*fcf3ce44SJohn Forte (void) free(result); 1996*fcf3ce44SJohn Forte return (err); 1997*fcf3ce44SJohn Forte } 1998*fcf3ce44SJohn Forte goto done; 1999*fcf3ce44SJohn Forte } 2000*fcf3ce44SJohn Forte 2001*fcf3ce44SJohn Forte (void) strcpy(tmp_name, name); 2002*fcf3ce44SJohn Forte if ((tmp_name[0] == 'c') && 2003*fcf3ce44SJohn Forte ((int)strlen(tmp_name) > 1) && ((int)strlen(tmp_name) < 5)) { 2004*fcf3ce44SJohn Forte if ((err = l_get_conflict(tmp_name, &result, verbose)) != 0) { 2005*fcf3ce44SJohn Forte if (result != NULL) { 2006*fcf3ce44SJohn Forte (void) g_destroy_data(result); 2007*fcf3ce44SJohn Forte } 2008*fcf3ce44SJohn Forte return (err); 2009*fcf3ce44SJohn Forte } 2010*fcf3ce44SJohn Forte if (result != NULL) { 2011*fcf3ce44SJohn Forte path_ptr->p_physical_path = result; 2012*fcf3ce44SJohn Forte if ((err = g_get_inquiry(result, &inq)) != 0) { 2013*fcf3ce44SJohn Forte (void) free(result); 2014*fcf3ce44SJohn Forte return (L_SCSI_ERROR); 2015*fcf3ce44SJohn Forte } 2016*fcf3ce44SJohn Forte /* 2017*fcf3ce44SJohn Forte * Check to see if it is a supported 2018*fcf3ce44SJohn Forte * A5K/v880/v890 storage subsystem disk 2019*fcf3ce44SJohn Forte */ 2020*fcf3ce44SJohn Forte if (g_enclDiskChk((char *)inq.inq_vid, 2021*fcf3ce44SJohn Forte (char *)inq.inq_pid)) { 2022*fcf3ce44SJohn Forte if (err = load_flds_if_enc_disk( 2023*fcf3ce44SJohn Forte result, path_struct)) { 2024*fcf3ce44SJohn Forte (void) free(result); 2025*fcf3ce44SJohn Forte return (err); 2026*fcf3ce44SJohn Forte } 2027*fcf3ce44SJohn Forte } 2028*fcf3ce44SJohn Forte goto done; 2029*fcf3ce44SJohn Forte } 2030*fcf3ce44SJohn Forte } 2031*fcf3ce44SJohn Forte 2032*fcf3ce44SJohn Forte /* 2033*fcf3ce44SJohn Forte * Check to see if we have a box or WWN name. 2034*fcf3ce44SJohn Forte * 2035*fcf3ce44SJohn Forte * If it contains a , then the format must be 2036*fcf3ce44SJohn Forte * box_name,f1 where f is front and 1 is the slot number 2037*fcf3ce44SJohn Forte * or it is a format like 2038*fcf3ce44SJohn Forte * ssd@w2200002037049adf,0:h,raw 2039*fcf3ce44SJohn Forte * or 2040*fcf3ce44SJohn Forte * SUNW,pln@a0000000,77791d:ctlr 2041*fcf3ce44SJohn Forte */ 2042*fcf3ce44SJohn Forte if (((char_ptr = strstr(tmp_name, ",")) != NULL) && 2043*fcf3ce44SJohn Forte ((*(char_ptr + 1) == 'f') || (*(char_ptr + 1) == 'r') || 2044*fcf3ce44SJohn Forte (*(char_ptr + 1) == 's'))) { 2045*fcf3ce44SJohn Forte char_ptr++; /* point to f/r */ 2046*fcf3ce44SJohn Forte if ((*char_ptr == 'f') || (*char_ptr == 's')) { 2047*fcf3ce44SJohn Forte path_ptr->f_flag = 1; 2048*fcf3ce44SJohn Forte } else if (*char_ptr != 'r') { 2049*fcf3ce44SJohn Forte return (L_INVALID_PATH_FORMAT); 2050*fcf3ce44SJohn Forte } 2051*fcf3ce44SJohn Forte save_frd = (char)*char_ptr; /* save it */ 2052*fcf3ce44SJohn Forte char_ptr++; 2053*fcf3ce44SJohn Forte slot = strtol(char_ptr, &ptr, 10); 2054*fcf3ce44SJohn Forte /* 2055*fcf3ce44SJohn Forte * NOTE: Need to double check the slot when we get 2056*fcf3ce44SJohn Forte * the number of the devices actually in the box. 2057*fcf3ce44SJohn Forte */ 2058*fcf3ce44SJohn Forte if ((slot < 0) || (ptr == char_ptr) || 2059*fcf3ce44SJohn Forte ((save_frd == 's' && slot >= MAX_DRIVES_DAK) || 2060*fcf3ce44SJohn Forte ((save_frd != 's' && slot >= (MAX_DRIVES_PER_BOX/2))))) { 2061*fcf3ce44SJohn Forte return (L_INVALID_SLOT); 2062*fcf3ce44SJohn Forte } 2063*fcf3ce44SJohn Forte /* Say slot valid. */ 2064*fcf3ce44SJohn Forte slot_flag = path_ptr->slot_valid = 1; 2065*fcf3ce44SJohn Forte if (save_frd == 's' && slot >= (MAX_DRIVES_DAK/2)) { 2066*fcf3ce44SJohn Forte path_ptr->slot = slot = slot % (MAX_DRIVES_DAK/2); 2067*fcf3ce44SJohn Forte path_ptr->f_flag = 0; 2068*fcf3ce44SJohn Forte } else 2069*fcf3ce44SJohn Forte path_ptr->slot = slot; 2070*fcf3ce44SJohn Forte } 2071*fcf3ce44SJohn Forte 2072*fcf3ce44SJohn Forte if (((char_ptr = strstr(tmp_name, ",")) != NULL) && 2073*fcf3ce44SJohn Forte ((*(char_ptr + 1) == 'f') || (*(char_ptr + 1) == 'r') || 2074*fcf3ce44SJohn Forte (*(char_ptr + 1) == 's'))) { 2075*fcf3ce44SJohn Forte *char_ptr = NULL; /* make just box name */ 2076*fcf3ce44SJohn Forte found_comma = 1; 2077*fcf3ce44SJohn Forte } 2078*fcf3ce44SJohn Forte /* Find path to IB */ 2079*fcf3ce44SJohn Forte if ((err = l_get_box_list(&box_list, verbose)) != 0) { 2080*fcf3ce44SJohn Forte (void) l_free_box_list(&box_list); 2081*fcf3ce44SJohn Forte return (err); 2082*fcf3ce44SJohn Forte } 2083*fcf3ce44SJohn Forte box_list_ptr = box_list; 2084*fcf3ce44SJohn Forte /* Look for box name. */ 2085*fcf3ce44SJohn Forte while (box_list != NULL) { 2086*fcf3ce44SJohn Forte if ((strcmp((char *)tmp_name, (char *)box_list->b_name)) == 0) { 2087*fcf3ce44SJohn Forte result = 2088*fcf3ce44SJohn Forte g_alloc_string(box_list->b_physical_path); 2089*fcf3ce44SJohn Forte L_DPRINTF(" l_convert_name:" 2090*fcf3ce44SJohn Forte " Found subsystem: name %s WWN %s\n", 2091*fcf3ce44SJohn Forte box_list->b_name, box_list->b_node_wwn_s); 2092*fcf3ce44SJohn Forte /* 2093*fcf3ce44SJohn Forte * Check for another box with this name. 2094*fcf3ce44SJohn Forte */ 2095*fcf3ce44SJohn Forte if (l_duplicate_names(box_list_ptr, 2096*fcf3ce44SJohn Forte box_list->b_node_wwn_s, 2097*fcf3ce44SJohn Forte (char *)box_list->b_name, 2098*fcf3ce44SJohn Forte verbose)) { 2099*fcf3ce44SJohn Forte (void) l_free_box_list(&box_list_ptr); 2100*fcf3ce44SJohn Forte (void) g_destroy_data(result); 2101*fcf3ce44SJohn Forte return (L_DUPLICATE_ENCLOSURES); 2102*fcf3ce44SJohn Forte } 2103*fcf3ce44SJohn Forte found_box = 1; 2104*fcf3ce44SJohn Forte break; 2105*fcf3ce44SJohn Forte } 2106*fcf3ce44SJohn Forte box_list = box_list->box_next; 2107*fcf3ce44SJohn Forte } 2108*fcf3ce44SJohn Forte /* 2109*fcf3ce44SJohn Forte * Check to see if we must get individual disks path. 2110*fcf3ce44SJohn Forte */ 2111*fcf3ce44SJohn Forte 2112*fcf3ce44SJohn Forte if (found_box && slot_flag) { 2113*fcf3ce44SJohn Forte if ((l_state = (L_state *)g_zalloc(sizeof (L_state))) == NULL) { 2114*fcf3ce44SJohn Forte (void) g_destroy_data(result); 2115*fcf3ce44SJohn Forte (void) l_free_box_list(&box_list_ptr); 2116*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 2117*fcf3ce44SJohn Forte } 2118*fcf3ce44SJohn Forte (void) strcpy(ses_path, result); 2119*fcf3ce44SJohn Forte if ((err = l_get_status(ses_path, l_state, 2120*fcf3ce44SJohn Forte verbose)) != 0) { 2121*fcf3ce44SJohn Forte (void) g_destroy_data(result); 2122*fcf3ce44SJohn Forte (void) g_destroy_data(l_state); 2123*fcf3ce44SJohn Forte (void) l_free_box_list(&box_list_ptr); 2124*fcf3ce44SJohn Forte return (err); 2125*fcf3ce44SJohn Forte } 2126*fcf3ce44SJohn Forte /* 2127*fcf3ce44SJohn Forte * Now double check the slot number. 2128*fcf3ce44SJohn Forte */ 2129*fcf3ce44SJohn Forte if (slot >= l_state->total_num_drv/2) { 2130*fcf3ce44SJohn Forte path_ptr->slot_valid = 0; 2131*fcf3ce44SJohn Forte (void) g_destroy_data(result); 2132*fcf3ce44SJohn Forte (void) l_free_box_list(&box_list_ptr); 2133*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 2134*fcf3ce44SJohn Forte return (L_INVALID_SLOT); 2135*fcf3ce44SJohn Forte } 2136*fcf3ce44SJohn Forte 2137*fcf3ce44SJohn Forte /* Only allow the single slot version for Daktari */ 2138*fcf3ce44SJohn Forte if (g_get_inquiry(ses_path, &inq)) { 2139*fcf3ce44SJohn Forte return (L_SCSI_ERROR); 2140*fcf3ce44SJohn Forte } 2141*fcf3ce44SJohn Forte enc_type = l_get_enc_type(inq); 2142*fcf3ce44SJohn Forte if (((enc_type == DAK_ENC_TYPE) && (save_frd != 's')) || 2143*fcf3ce44SJohn Forte ((enc_type != DAK_ENC_TYPE) && (save_frd == 's'))) { 2144*fcf3ce44SJohn Forte path_ptr->slot_valid = 0; 2145*fcf3ce44SJohn Forte (void) g_destroy_data(result); 2146*fcf3ce44SJohn Forte (void) l_free_box_list(&box_list_ptr); 2147*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 2148*fcf3ce44SJohn Forte return (L_INVALID_SLOT); 2149*fcf3ce44SJohn Forte } 2150*fcf3ce44SJohn Forte 2151*fcf3ce44SJohn Forte if (path_ptr->f_flag) { 2152*fcf3ce44SJohn Forte if (*l_state->drv_front[slot].g_disk_state.physical_path) { 2153*fcf3ce44SJohn Forte result = 2154*fcf3ce44SJohn Forte g_alloc_string(l_state->drv_front[slot].g_disk_state.physical_path); 2155*fcf3ce44SJohn Forte } else { 2156*fcf3ce44SJohn Forte /* Result is the IB path */ 2157*fcf3ce44SJohn Forte path_ptr->ib_path_flag = 1; 2158*fcf3ce44SJohn Forte path_ptr->p_physical_path = 2159*fcf3ce44SJohn Forte g_alloc_string(result); 2160*fcf3ce44SJohn Forte (void) g_destroy_data(result); 2161*fcf3ce44SJohn Forte result = NULL; 2162*fcf3ce44SJohn Forte } 2163*fcf3ce44SJohn Forte } else { 2164*fcf3ce44SJohn Forte if (*l_state->drv_rear[slot].g_disk_state.physical_path) { 2165*fcf3ce44SJohn Forte result = 2166*fcf3ce44SJohn Forte g_alloc_string(l_state->drv_rear[slot].g_disk_state.physical_path); 2167*fcf3ce44SJohn Forte } else { 2168*fcf3ce44SJohn Forte /* Result is the IB path */ 2169*fcf3ce44SJohn Forte path_ptr->ib_path_flag = 1; 2170*fcf3ce44SJohn Forte path_ptr->p_physical_path = 2171*fcf3ce44SJohn Forte g_alloc_string(result); 2172*fcf3ce44SJohn Forte (void) g_destroy_data(result); 2173*fcf3ce44SJohn Forte result = NULL; 2174*fcf3ce44SJohn Forte } 2175*fcf3ce44SJohn Forte } 2176*fcf3ce44SJohn Forte (void) l_free_lstate(&l_state); 2177*fcf3ce44SJohn Forte goto done; 2178*fcf3ce44SJohn Forte } 2179*fcf3ce44SJohn Forte if (found_box || found_comma) { 2180*fcf3ce44SJohn Forte goto done; 2181*fcf3ce44SJohn Forte } 2182*fcf3ce44SJohn Forte /* 2183*fcf3ce44SJohn Forte * No luck with the box name. 2184*fcf3ce44SJohn Forte * 2185*fcf3ce44SJohn Forte * Try WWN's 2186*fcf3ce44SJohn Forte */ 2187*fcf3ce44SJohn Forte /* Look for the SES's WWN */ 2188*fcf3ce44SJohn Forte box_list = box_list_ptr; 2189*fcf3ce44SJohn Forte while (box_list != NULL) { 2190*fcf3ce44SJohn Forte if (((strcasecmp((char *)tmp_name, 2191*fcf3ce44SJohn Forte (char *)box_list->b_port_wwn_s)) == 0) || 2192*fcf3ce44SJohn Forte ((strcasecmp((char *)tmp_name, 2193*fcf3ce44SJohn Forte (char *)box_list->b_node_wwn_s)) == 0)) { 2194*fcf3ce44SJohn Forte result = 2195*fcf3ce44SJohn Forte g_alloc_string(box_list->b_physical_path); 2196*fcf3ce44SJohn Forte L_DPRINTF(" l_convert_name:" 2197*fcf3ce44SJohn Forte " Found subsystem using the WWN" 2198*fcf3ce44SJohn Forte ": name %s WWN %s\n", 2199*fcf3ce44SJohn Forte box_list->b_name, box_list->b_node_wwn_s); 2200*fcf3ce44SJohn Forte goto done; 2201*fcf3ce44SJohn Forte } 2202*fcf3ce44SJohn Forte box_list = box_list->box_next; 2203*fcf3ce44SJohn Forte } 2204*fcf3ce44SJohn Forte /* Look for a device's WWN */ 2205*fcf3ce44SJohn Forte if (strlen(tmp_name) <= L_WWN_LENGTH) { 2206*fcf3ce44SJohn Forte if ((err = g_get_wwn_list(&wwn_list, verbose)) != 0) { 2207*fcf3ce44SJohn Forte (void) l_free_box_list(&box_list_ptr); 2208*fcf3ce44SJohn Forte return (err); 2209*fcf3ce44SJohn Forte } 2210*fcf3ce44SJohn Forte for (wwn_list_ptr = wwn_list; wwn_list_ptr != NULL; 2211*fcf3ce44SJohn Forte wwn_list_ptr = wwn_list_ptr->wwn_next) { 2212*fcf3ce44SJohn Forte if (((strcasecmp((char *)tmp_name, 2213*fcf3ce44SJohn Forte (char *)wwn_list_ptr->node_wwn_s)) == 0) || 2214*fcf3ce44SJohn Forte ((strcasecmp((char *)tmp_name, 2215*fcf3ce44SJohn Forte (char *)wwn_list_ptr->port_wwn_s)) == 0)) { 2216*fcf3ce44SJohn Forte /* 2217*fcf3ce44SJohn Forte * Found the device's WWN in the global WWN list. 2218*fcf3ce44SJohn Forte * It MAY be in a photon/Daktari. If it is, we'll set 2219*fcf3ce44SJohn Forte * additional fields in path_struct. 2220*fcf3ce44SJohn Forte */ 2221*fcf3ce44SJohn Forte result = g_alloc_string(wwn_list_ptr->physical_path); 2222*fcf3ce44SJohn Forte L_DPRINTF(" l_convert_name:" 2223*fcf3ce44SJohn Forte " Found device: WWN %s Path %s\n", 2224*fcf3ce44SJohn Forte tmp_name, wwn_list_ptr->logical_path); 2225*fcf3ce44SJohn Forte 2226*fcf3ce44SJohn Forte (void) g_free_wwn_list(&wwn_list); 2227*fcf3ce44SJohn Forte 2228*fcf3ce44SJohn Forte /* 2229*fcf3ce44SJohn Forte * Now check if it is a disk in an A5K and set 2230*fcf3ce44SJohn Forte * path_struct fields 2231*fcf3ce44SJohn Forte */ 2232*fcf3ce44SJohn Forte path_ptr->p_physical_path = result; 2233*fcf3ce44SJohn Forte if ((err = g_get_inquiry(result, &inq)) != 0) { 2234*fcf3ce44SJohn Forte (void) free(result); 2235*fcf3ce44SJohn Forte return (L_SCSI_ERROR); 2236*fcf3ce44SJohn Forte } 2237*fcf3ce44SJohn Forte /* 2238*fcf3ce44SJohn Forte * Check to see if it is a supported 2239*fcf3ce44SJohn Forte * A5K/v880/v890 storage subsystem disk 2240*fcf3ce44SJohn Forte */ 2241*fcf3ce44SJohn Forte if (g_enclDiskChk((char *)inq.inq_vid, 2242*fcf3ce44SJohn Forte (char *)inq.inq_pid)) { 2243*fcf3ce44SJohn Forte if (err = load_flds_if_enc_disk( 2244*fcf3ce44SJohn Forte result, path_struct)) { 2245*fcf3ce44SJohn Forte (void) free(result); 2246*fcf3ce44SJohn Forte return (err); 2247*fcf3ce44SJohn Forte } 2248*fcf3ce44SJohn Forte } 2249*fcf3ce44SJohn Forte goto done; 2250*fcf3ce44SJohn Forte } 2251*fcf3ce44SJohn Forte } 2252*fcf3ce44SJohn Forte } 2253*fcf3ce44SJohn Forte 2254*fcf3ce44SJohn Forte /* 2255*fcf3ce44SJohn Forte * Try again in case we were in the /dev 2256*fcf3ce44SJohn Forte * or /devices directory. 2257*fcf3ce44SJohn Forte */ 2258*fcf3ce44SJohn Forte result = g_get_physical_name(name); 2259*fcf3ce44SJohn Forte 2260*fcf3ce44SJohn Forte done: 2261*fcf3ce44SJohn Forte (void) l_free_box_list(&box_list_ptr); 2262*fcf3ce44SJohn Forte path_ptr->argv = name; 2263*fcf3ce44SJohn Forte if (result == NULL) { 2264*fcf3ce44SJohn Forte if (!path_ptr->ib_path_flag) 2265*fcf3ce44SJohn Forte return (-1); 2266*fcf3ce44SJohn Forte } else { 2267*fcf3ce44SJohn Forte path_ptr->p_physical_path = result; 2268*fcf3ce44SJohn Forte } 2269*fcf3ce44SJohn Forte 2270*fcf3ce44SJohn Forte L_DPRINTF(" l_convert_name: path_struct:\n\tphysical_path:\n\t %s\n" 2271*fcf3ce44SJohn Forte "\targv:\t\t%s" 2272*fcf3ce44SJohn Forte "\n\tslot_valid\t%d" 2273*fcf3ce44SJohn Forte "\n\tslot\t\t%d" 2274*fcf3ce44SJohn Forte "\n\tf_flag\t\t%d" 2275*fcf3ce44SJohn Forte "\n\tib_path_flag\t%d\n", 2276*fcf3ce44SJohn Forte path_ptr->p_physical_path, 2277*fcf3ce44SJohn Forte path_ptr->argv, 2278*fcf3ce44SJohn Forte path_ptr->slot_valid, 2279*fcf3ce44SJohn Forte path_ptr->slot, 2280*fcf3ce44SJohn Forte path_ptr->f_flag, 2281*fcf3ce44SJohn Forte path_ptr->ib_path_flag); 2282*fcf3ce44SJohn Forte if (env != NULL) { 2283*fcf3ce44SJohn Forte end_time = gethrtime(); 2284*fcf3ce44SJohn Forte (void) fprintf(stdout, " l_convert_name: " 2285*fcf3ce44SJohn Forte "Time = %lld millisec\n", 2286*fcf3ce44SJohn Forte (end_time - start_time)/1000000); 2287*fcf3ce44SJohn Forte } 2288*fcf3ce44SJohn Forte 2289*fcf3ce44SJohn Forte if (path_ptr->ib_path_flag) 2290*fcf3ce44SJohn Forte return (-1); 2291*fcf3ce44SJohn Forte *phys_path = result; 2292*fcf3ce44SJohn Forte return (0); 2293*fcf3ce44SJohn Forte } 2294*fcf3ce44SJohn Forte 2295*fcf3ce44SJohn Forte 2296*fcf3ce44SJohn Forte /* 2297*fcf3ce44SJohn Forte * Gets envsen information of an enclosure from IB 2298*fcf3ce44SJohn Forte * 2299*fcf3ce44SJohn Forte * RETURNS: 2300*fcf3ce44SJohn Forte * 0 O.K. 2301*fcf3ce44SJohn Forte * non-zero otherwise 2302*fcf3ce44SJohn Forte */ 2303*fcf3ce44SJohn Forte int 2304*fcf3ce44SJohn Forte l_get_envsen_page(int fd, uchar_t *buf, int buf_size, uchar_t page_code, 2305*fcf3ce44SJohn Forte int verbose) 2306*fcf3ce44SJohn Forte { 2307*fcf3ce44SJohn Forte Rec_diag_hdr hdr; 2308*fcf3ce44SJohn Forte uchar_t *pg; 2309*fcf3ce44SJohn Forte int size, new_size, status; 2310*fcf3ce44SJohn Forte 2311*fcf3ce44SJohn Forte if (buf == NULL) { 2312*fcf3ce44SJohn Forte return (L_INVALID_BUF_LEN); 2313*fcf3ce44SJohn Forte } 2314*fcf3ce44SJohn Forte 2315*fcf3ce44SJohn Forte if (verbose) { 2316*fcf3ce44SJohn Forte (void) fprintf(stdout, 2317*fcf3ce44SJohn Forte MSGSTR(9046, " Reading SES page %x\n"), page_code); 2318*fcf3ce44SJohn Forte } 2319*fcf3ce44SJohn Forte 2320*fcf3ce44SJohn Forte (void) memset(&hdr, 0, sizeof (struct rec_diag_hdr)); 2321*fcf3ce44SJohn Forte if (status = g_scsi_rec_diag_cmd(fd, (uchar_t *)&hdr, 2322*fcf3ce44SJohn Forte sizeof (struct rec_diag_hdr), page_code)) { 2323*fcf3ce44SJohn Forte return (status); 2324*fcf3ce44SJohn Forte } 2325*fcf3ce44SJohn Forte 2326*fcf3ce44SJohn Forte /* Check */ 2327*fcf3ce44SJohn Forte if ((hdr.page_code != page_code) || (hdr.page_len == 0)) { 2328*fcf3ce44SJohn Forte return (L_RD_PG_INVLD_CODE); 2329*fcf3ce44SJohn Forte } 2330*fcf3ce44SJohn Forte size = HEADER_LEN + hdr.page_len; 2331*fcf3ce44SJohn Forte /* 2332*fcf3ce44SJohn Forte * Because of a hardware restriction in the soc+ chip 2333*fcf3ce44SJohn Forte * the transfers must be word aligned. 2334*fcf3ce44SJohn Forte */ 2335*fcf3ce44SJohn Forte while (size & 0x03) { 2336*fcf3ce44SJohn Forte size++; 2337*fcf3ce44SJohn Forte if (size > buf_size) { 2338*fcf3ce44SJohn Forte return (L_RD_PG_MIN_BUFF); 2339*fcf3ce44SJohn Forte } 2340*fcf3ce44SJohn Forte P_DPRINTF(" l_get_envsen_page: Adjusting size of the " 2341*fcf3ce44SJohn Forte "g_scsi_rec_diag_cmd buffer.\n"); 2342*fcf3ce44SJohn Forte } 2343*fcf3ce44SJohn Forte 2344*fcf3ce44SJohn Forte if ((pg = (uchar_t *)g_zalloc(size)) == NULL) { 2345*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 2346*fcf3ce44SJohn Forte } 2347*fcf3ce44SJohn Forte 2348*fcf3ce44SJohn Forte P_DPRINTF(" l_get_envsen_page: Reading page %x of size 0x%x\n", 2349*fcf3ce44SJohn Forte page_code, size); 2350*fcf3ce44SJohn Forte if (status = g_scsi_rec_diag_cmd(fd, pg, size, page_code)) { 2351*fcf3ce44SJohn Forte (void) g_destroy_data((char *)pg); 2352*fcf3ce44SJohn Forte return (status); 2353*fcf3ce44SJohn Forte } 2354*fcf3ce44SJohn Forte 2355*fcf3ce44SJohn Forte new_size = MIN(size, buf_size); 2356*fcf3ce44SJohn Forte bcopy((const void *)pg, (void *)buf, (size_t)new_size); 2357*fcf3ce44SJohn Forte 2358*fcf3ce44SJohn Forte (void) g_destroy_data(pg); 2359*fcf3ce44SJohn Forte return (0); 2360*fcf3ce44SJohn Forte } 2361*fcf3ce44SJohn Forte 2362*fcf3ce44SJohn Forte 2363*fcf3ce44SJohn Forte 2364*fcf3ce44SJohn Forte /* 2365*fcf3ce44SJohn Forte * Get consolidated copy of all environmental information 2366*fcf3ce44SJohn Forte * into buf structure. 2367*fcf3ce44SJohn Forte * 2368*fcf3ce44SJohn Forte * RETURNS: 2369*fcf3ce44SJohn Forte * 0 O.K. 2370*fcf3ce44SJohn Forte * non-zero otherwise 2371*fcf3ce44SJohn Forte */ 2372*fcf3ce44SJohn Forte 2373*fcf3ce44SJohn Forte int 2374*fcf3ce44SJohn Forte l_get_envsen(char *path_phys, uchar_t *buf, int size, int verbose) 2375*fcf3ce44SJohn Forte { 2376*fcf3ce44SJohn Forte int fd, rval; 2377*fcf3ce44SJohn Forte uchar_t *page_list_ptr, page_code, *local_buf_ptr = buf; 2378*fcf3ce44SJohn Forte Rec_diag_hdr *hdr = (struct rec_diag_hdr *)(void *)buf; 2379*fcf3ce44SJohn Forte ushort_t num_pages; 2380*fcf3ce44SJohn Forte 2381*fcf3ce44SJohn Forte if ((path_phys == NULL) || (buf == NULL)) { 2382*fcf3ce44SJohn Forte return (L_INVALID_PATH_FORMAT); 2383*fcf3ce44SJohn Forte } 2384*fcf3ce44SJohn Forte 2385*fcf3ce44SJohn Forte page_code = L_PAGE_PAGE_LIST; 2386*fcf3ce44SJohn Forte 2387*fcf3ce44SJohn Forte /* open IB */ 2388*fcf3ce44SJohn Forte if ((fd = g_object_open(path_phys, O_NDELAY | O_RDONLY)) == -1) 2389*fcf3ce44SJohn Forte return (L_OPEN_PATH_FAIL); 2390*fcf3ce44SJohn Forte 2391*fcf3ce44SJohn Forte P_DPRINTF(" l_get_envsen: Getting list of supported" 2392*fcf3ce44SJohn Forte " pages from IB\n"); 2393*fcf3ce44SJohn Forte if (verbose) { 2394*fcf3ce44SJohn Forte (void) fprintf(stdout, 2395*fcf3ce44SJohn Forte MSGSTR(9047, " Getting list of supported pages from IB\n")); 2396*fcf3ce44SJohn Forte } 2397*fcf3ce44SJohn Forte 2398*fcf3ce44SJohn Forte /* Get page 0 */ 2399*fcf3ce44SJohn Forte if ((rval = l_get_envsen_page(fd, local_buf_ptr, 2400*fcf3ce44SJohn Forte size, page_code, verbose)) != NULL) { 2401*fcf3ce44SJohn Forte (void) close(fd); 2402*fcf3ce44SJohn Forte return (rval); 2403*fcf3ce44SJohn Forte } 2404*fcf3ce44SJohn Forte 2405*fcf3ce44SJohn Forte page_list_ptr = buf + HEADER_LEN + 1; /* +1 to skip page 0 */ 2406*fcf3ce44SJohn Forte 2407*fcf3ce44SJohn Forte num_pages = hdr->page_len - 1; 2408*fcf3ce44SJohn Forte 2409*fcf3ce44SJohn Forte /* 2410*fcf3ce44SJohn Forte * check whether the number of pages received 2411*fcf3ce44SJohn Forte * from IB are valid. SENA enclosure 2412*fcf3ce44SJohn Forte * supports only 8 pages of sense information. 2413*fcf3ce44SJohn Forte * According to SES specification dpANS X3.xxx-1997 2414*fcf3ce44SJohn Forte * X3T10/Project 1212-D/Rev 8a, the enclosure supported 2415*fcf3ce44SJohn Forte * pages can go upto L_MAX_POSSIBLE_PAGES (0xFF). 2416*fcf3ce44SJohn Forte * Return an error if no. of pages exceeds L_MAX_POSSIBLE_PAGES. 2417*fcf3ce44SJohn Forte * See if (num_pages >= L_MAX_POSSIBLE_PAGES) since 1 page (page 0) 2418*fcf3ce44SJohn Forte * was already subtracted from the total number of pages before. 2419*fcf3ce44SJohn Forte */ 2420*fcf3ce44SJohn Forte if (num_pages < 1 || num_pages >= L_MAX_POSSIBLE_PAGES) { 2421*fcf3ce44SJohn Forte return (L_INVALID_NO_OF_ENVSEN_PAGES); 2422*fcf3ce44SJohn Forte } 2423*fcf3ce44SJohn Forte /* 2424*fcf3ce44SJohn Forte * Buffer size of MAX_REC_DIAG_LENGTH can be small if the 2425*fcf3ce44SJohn Forte * number of pages exceed more than L_MAX_SENAIB_PAGES 2426*fcf3ce44SJohn Forte * but less than L_MAX_POSSIBLE_PAGES. 2427*fcf3ce44SJohn Forte */ 2428*fcf3ce44SJohn Forte if (size == MAX_REC_DIAG_LENGTH && 2429*fcf3ce44SJohn Forte num_pages >= L_MAX_SENAIB_PAGES) { 2430*fcf3ce44SJohn Forte return (L_INVALID_BUF_LEN); 2431*fcf3ce44SJohn Forte } 2432*fcf3ce44SJohn Forte /* Align buffer */ 2433*fcf3ce44SJohn Forte while (hdr->page_len & 0x03) { 2434*fcf3ce44SJohn Forte hdr->page_len++; 2435*fcf3ce44SJohn Forte } 2436*fcf3ce44SJohn Forte local_buf_ptr += HEADER_LEN + hdr->page_len; 2437*fcf3ce44SJohn Forte 2438*fcf3ce44SJohn Forte /* 2439*fcf3ce44SJohn Forte * Getting all pages and appending to buf 2440*fcf3ce44SJohn Forte */ 2441*fcf3ce44SJohn Forte for (; num_pages--; page_list_ptr++) { 2442*fcf3ce44SJohn Forte /* 2443*fcf3ce44SJohn Forte * The fifth byte of page 0 is the start 2444*fcf3ce44SJohn Forte * of the list of pages not including page 0. 2445*fcf3ce44SJohn Forte */ 2446*fcf3ce44SJohn Forte page_code = *page_list_ptr; 2447*fcf3ce44SJohn Forte 2448*fcf3ce44SJohn Forte if ((rval = l_get_envsen_page(fd, local_buf_ptr, 2449*fcf3ce44SJohn Forte size, page_code, verbose)) != NULL) { 2450*fcf3ce44SJohn Forte (void) close(fd); 2451*fcf3ce44SJohn Forte return (rval); 2452*fcf3ce44SJohn Forte } 2453*fcf3ce44SJohn Forte hdr = (struct rec_diag_hdr *)(void *)local_buf_ptr; 2454*fcf3ce44SJohn Forte local_buf_ptr += HEADER_LEN + hdr->page_len; 2455*fcf3ce44SJohn Forte } 2456*fcf3ce44SJohn Forte 2457*fcf3ce44SJohn Forte (void) close(fd); 2458*fcf3ce44SJohn Forte return (0); 2459*fcf3ce44SJohn Forte } 2460*fcf3ce44SJohn Forte 2461*fcf3ce44SJohn Forte 2462*fcf3ce44SJohn Forte 2463*fcf3ce44SJohn Forte /* 2464*fcf3ce44SJohn Forte * Get the individual disk status. 2465*fcf3ce44SJohn Forte * Path must be physical and point to a disk. 2466*fcf3ce44SJohn Forte * 2467*fcf3ce44SJohn Forte * This function updates the d_state_flags, port WWN's 2468*fcf3ce44SJohn Forte * and num_blocks for all accessiable ports 2469*fcf3ce44SJohn Forte * in l_disk_state->g_disk_state structure. 2470*fcf3ce44SJohn Forte * 2471*fcf3ce44SJohn Forte * RETURNS: 2472*fcf3ce44SJohn Forte * 0 O.K. 2473*fcf3ce44SJohn Forte * non-zero otherwise 2474*fcf3ce44SJohn Forte */ 2475*fcf3ce44SJohn Forte int 2476*fcf3ce44SJohn Forte l_get_disk_status(char *path, struct l_disk_state_struct *l_disk_state, 2477*fcf3ce44SJohn Forte WWN_list *wwn_list, int verbose) 2478*fcf3ce44SJohn Forte { 2479*fcf3ce44SJohn Forte struct dlist *ml; 2480*fcf3ce44SJohn Forte char path_a[MAXPATHLEN], path_b[MAXPATHLEN], ses_path[MAXPATHLEN]; 2481*fcf3ce44SJohn Forte gfc_map_t map; 2482*fcf3ce44SJohn Forte int path_a_found = 0, path_b_found = 0, local_port_a_flag; 2483*fcf3ce44SJohn Forte uchar_t node_wwn[WWN_SIZE], port_wwn[WWN_SIZE]; 2484*fcf3ce44SJohn Forte int al_pa, err, pathcnt = 1; 2485*fcf3ce44SJohn Forte int i = 0; 2486*fcf3ce44SJohn Forte char temppath[MAXPATHLEN]; 2487*fcf3ce44SJohn Forte mp_pathlist_t pathlist; 2488*fcf3ce44SJohn Forte char pwwn[WWN_S_LEN]; 2489*fcf3ce44SJohn Forte struct stat sbuf; 2490*fcf3ce44SJohn Forte 2491*fcf3ce44SJohn Forte if ((path == NULL) || (l_disk_state == NULL)) { 2492*fcf3ce44SJohn Forte return (L_INVALID_PATH_FORMAT); 2493*fcf3ce44SJohn Forte } 2494*fcf3ce44SJohn Forte 2495*fcf3ce44SJohn Forte /* Check device name */ 2496*fcf3ce44SJohn Forte if (stat(path, &sbuf) || (sbuf.st_rdev == NODEV)) { 2497*fcf3ce44SJohn Forte G_DPRINTF(" l_get_disk_status: invalid device %s\n", path); 2498*fcf3ce44SJohn Forte return (L_INVALID_PATH); 2499*fcf3ce44SJohn Forte } 2500*fcf3ce44SJohn Forte 2501*fcf3ce44SJohn Forte /* Initialize */ 2502*fcf3ce44SJohn Forte *path_a = *path_b = NULL; 2503*fcf3ce44SJohn Forte l_disk_state->g_disk_state.num_blocks = 0; 2504*fcf3ce44SJohn Forte 2505*fcf3ce44SJohn Forte /* Get paths. */ 2506*fcf3ce44SJohn Forte g_get_multipath(path, 2507*fcf3ce44SJohn Forte &(l_disk_state->g_disk_state.multipath_list), 2508*fcf3ce44SJohn Forte wwn_list, verbose); 2509*fcf3ce44SJohn Forte ml = l_disk_state->g_disk_state.multipath_list; 2510*fcf3ce44SJohn Forte if (ml == NULL) { 2511*fcf3ce44SJohn Forte l_disk_state->l_state_flag = L_NO_PATH_FOUND; 2512*fcf3ce44SJohn Forte G_DPRINTF(" l_get_disk_status: Error finding a " 2513*fcf3ce44SJohn Forte "multipath to the disk.\n"); 2514*fcf3ce44SJohn Forte return (0); 2515*fcf3ce44SJohn Forte } 2516*fcf3ce44SJohn Forte 2517*fcf3ce44SJohn Forte if (strstr(path, SCSI_VHCI) != NULL) { 2518*fcf3ce44SJohn Forte /* 2519*fcf3ce44SJohn Forte * It is an MPXIO Path 2520*fcf3ce44SJohn Forte */ 2521*fcf3ce44SJohn Forte (void) strcpy(temppath, path); 2522*fcf3ce44SJohn Forte if (g_get_pathlist(temppath, &pathlist)) { 2523*fcf3ce44SJohn Forte return (0); 2524*fcf3ce44SJohn Forte } 2525*fcf3ce44SJohn Forte pathcnt = pathlist.path_count; 2526*fcf3ce44SJohn Forte for (i = 0; i < pathcnt; i++) { 2527*fcf3ce44SJohn Forte /* 2528*fcf3ce44SJohn Forte * Skip inactive paths. 2529*fcf3ce44SJohn Forte * A path that is not in either 2530*fcf3ce44SJohn Forte * MDI_PATHINFO_STATE_ONLINE or 2531*fcf3ce44SJohn Forte * MDI_PATHINFO_STATE_STANDBY state is not 2532*fcf3ce44SJohn Forte * an active path. 2533*fcf3ce44SJohn Forte * 2534*fcf3ce44SJohn Forte * When a disk port is bypassed and mpxio is 2535*fcf3ce44SJohn Forte * enabled, the path_state for that path goes to the 2536*fcf3ce44SJohn Forte * offline state 2537*fcf3ce44SJohn Forte */ 2538*fcf3ce44SJohn Forte if (pathlist.path_info[i].path_state != 2539*fcf3ce44SJohn Forte MDI_PATHINFO_STATE_ONLINE && 2540*fcf3ce44SJohn Forte pathlist.path_info[i].path_state != 2541*fcf3ce44SJohn Forte MDI_PATHINFO_STATE_STANDBY) { 2542*fcf3ce44SJohn Forte continue; 2543*fcf3ce44SJohn Forte } 2544*fcf3ce44SJohn Forte (void) strncpy(pwwn, pathlist.path_info[i].path_addr, 2545*fcf3ce44SJohn Forte L_WWN_LENGTH); 2546*fcf3ce44SJohn Forte pwwn[L_WWN_LENGTH] = '\0'; 2547*fcf3ce44SJohn Forte if (!(path_a_found || path_b_found)) { 2548*fcf3ce44SJohn Forte if (pwwn[1] == '1') { 2549*fcf3ce44SJohn Forte local_port_a_flag = 1; 2550*fcf3ce44SJohn Forte } else { 2551*fcf3ce44SJohn Forte local_port_a_flag = 0; 2552*fcf3ce44SJohn Forte } 2553*fcf3ce44SJohn Forte } else if (path_a_found && 2554*fcf3ce44SJohn Forte (strstr(l_disk_state->g_disk_state.port_a_wwn_s, 2555*fcf3ce44SJohn Forte pwwn) == NULL)) { 2556*fcf3ce44SJohn Forte /* do port b */ 2557*fcf3ce44SJohn Forte local_port_a_flag = 0; 2558*fcf3ce44SJohn Forte } else if (path_b_found && 2559*fcf3ce44SJohn Forte (strstr(l_disk_state->g_disk_state.port_b_wwn_s, 2560*fcf3ce44SJohn Forte pwwn) == NULL)) { 2561*fcf3ce44SJohn Forte /* do port a */ 2562*fcf3ce44SJohn Forte local_port_a_flag = 1; 2563*fcf3ce44SJohn Forte } 2564*fcf3ce44SJohn Forte 2565*fcf3ce44SJohn Forte if (err = l_get_disk_port_status(path, 2566*fcf3ce44SJohn Forte l_disk_state, local_port_a_flag, verbose)) { 2567*fcf3ce44SJohn Forte return (err); 2568*fcf3ce44SJohn Forte } 2569*fcf3ce44SJohn Forte 2570*fcf3ce44SJohn Forte if (local_port_a_flag && (!path_a_found)) { 2571*fcf3ce44SJohn Forte (void) strcpy(l_disk_state-> 2572*fcf3ce44SJohn Forte g_disk_state.port_a_wwn_s, pwwn); 2573*fcf3ce44SJohn Forte l_disk_state->g_disk_state.port_a_valid++; 2574*fcf3ce44SJohn Forte path_a_found++; 2575*fcf3ce44SJohn Forte } 2576*fcf3ce44SJohn Forte 2577*fcf3ce44SJohn Forte if ((!local_port_a_flag) && (!path_b_found)) { 2578*fcf3ce44SJohn Forte (void) strcpy(l_disk_state-> 2579*fcf3ce44SJohn Forte g_disk_state.port_b_wwn_s, pwwn); 2580*fcf3ce44SJohn Forte l_disk_state->g_disk_state.port_b_valid++; 2581*fcf3ce44SJohn Forte path_b_found++; 2582*fcf3ce44SJohn Forte } 2583*fcf3ce44SJohn Forte } 2584*fcf3ce44SJohn Forte free(pathlist.path_info); 2585*fcf3ce44SJohn Forte return (0); 2586*fcf3ce44SJohn Forte } 2587*fcf3ce44SJohn Forte 2588*fcf3ce44SJohn Forte while (ml && (!(path_a_found && path_b_found))) { 2589*fcf3ce44SJohn Forte if (err = g_get_dev_map(ml->dev_path, &map, verbose)) { 2590*fcf3ce44SJohn Forte (void) g_free_multipath(ml); 2591*fcf3ce44SJohn Forte return (err); 2592*fcf3ce44SJohn Forte } 2593*fcf3ce44SJohn Forte if ((err = l_get_ses_path(ml->dev_path, ses_path, 2594*fcf3ce44SJohn Forte &map, verbose)) != 0) { 2595*fcf3ce44SJohn Forte (void) g_free_multipath(ml); 2596*fcf3ce44SJohn Forte free((void *)map.dev_addr); 2597*fcf3ce44SJohn Forte return (err); 2598*fcf3ce44SJohn Forte } 2599*fcf3ce44SJohn Forte free((void *)map.dev_addr); /* Not used anymore */ 2600*fcf3ce44SJohn Forte 2601*fcf3ce44SJohn Forte /* 2602*fcf3ce44SJohn Forte * Get the port, A or B, of the disk, 2603*fcf3ce44SJohn Forte * by passing the IB path. 2604*fcf3ce44SJohn Forte */ 2605*fcf3ce44SJohn Forte if (err = l_get_port(ses_path, &local_port_a_flag, verbose)) { 2606*fcf3ce44SJohn Forte (void) g_free_multipath(ml); 2607*fcf3ce44SJohn Forte return (err); 2608*fcf3ce44SJohn Forte } 2609*fcf3ce44SJohn Forte if (local_port_a_flag && (!path_a_found)) { 2610*fcf3ce44SJohn Forte G_DPRINTF(" l_get_disk_status: Path to Port A " 2611*fcf3ce44SJohn Forte "found: %s\n", ml->dev_path); 2612*fcf3ce44SJohn Forte if (err = l_get_disk_port_status(ml->dev_path, 2613*fcf3ce44SJohn Forte l_disk_state, local_port_a_flag, verbose)) { 2614*fcf3ce44SJohn Forte (void) g_free_multipath(ml); 2615*fcf3ce44SJohn Forte return (err); 2616*fcf3ce44SJohn Forte } 2617*fcf3ce44SJohn Forte if (err = g_get_wwn(ml->dev_path, 2618*fcf3ce44SJohn Forte port_wwn, node_wwn, 2619*fcf3ce44SJohn Forte &al_pa, verbose)) { 2620*fcf3ce44SJohn Forte (void) g_free_multipath(ml); 2621*fcf3ce44SJohn Forte return (err); 2622*fcf3ce44SJohn Forte } 2623*fcf3ce44SJohn Forte (void) sprintf(l_disk_state->g_disk_state.port_a_wwn_s, 2624*fcf3ce44SJohn Forte "%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x", 2625*fcf3ce44SJohn Forte port_wwn[0], port_wwn[1], port_wwn[2], port_wwn[3], 2626*fcf3ce44SJohn Forte port_wwn[4], port_wwn[5], port_wwn[6], port_wwn[7]); 2627*fcf3ce44SJohn Forte 2628*fcf3ce44SJohn Forte l_disk_state->g_disk_state.port_a_valid++; 2629*fcf3ce44SJohn Forte path_a_found++; 2630*fcf3ce44SJohn Forte } 2631*fcf3ce44SJohn Forte if ((!local_port_a_flag) && (!path_b_found)) { 2632*fcf3ce44SJohn Forte G_DPRINTF(" l_get_disk_status: Path to Port B " 2633*fcf3ce44SJohn Forte "found: %s\n", ml->dev_path); 2634*fcf3ce44SJohn Forte if (err = l_get_disk_port_status(ml->dev_path, 2635*fcf3ce44SJohn Forte l_disk_state, local_port_a_flag, verbose)) { 2636*fcf3ce44SJohn Forte return (err); 2637*fcf3ce44SJohn Forte } 2638*fcf3ce44SJohn Forte if (err = g_get_wwn(ml->dev_path, 2639*fcf3ce44SJohn Forte port_wwn, node_wwn, 2640*fcf3ce44SJohn Forte &al_pa, verbose)) { 2641*fcf3ce44SJohn Forte (void) g_free_multipath(ml); 2642*fcf3ce44SJohn Forte return (err); 2643*fcf3ce44SJohn Forte } 2644*fcf3ce44SJohn Forte (void) sprintf(l_disk_state->g_disk_state.port_b_wwn_s, 2645*fcf3ce44SJohn Forte "%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x", 2646*fcf3ce44SJohn Forte port_wwn[0], port_wwn[1], port_wwn[2], port_wwn[3], 2647*fcf3ce44SJohn Forte port_wwn[4], port_wwn[5], port_wwn[6], port_wwn[7]); 2648*fcf3ce44SJohn Forte 2649*fcf3ce44SJohn Forte l_disk_state->g_disk_state.port_b_valid++; 2650*fcf3ce44SJohn Forte path_b_found++; 2651*fcf3ce44SJohn Forte } 2652*fcf3ce44SJohn Forte ml = ml->next; 2653*fcf3ce44SJohn Forte } 2654*fcf3ce44SJohn Forte return (0); 2655*fcf3ce44SJohn Forte 2656*fcf3ce44SJohn Forte 2657*fcf3ce44SJohn Forte } 2658*fcf3ce44SJohn Forte 2659*fcf3ce44SJohn Forte 2660*fcf3ce44SJohn Forte 2661*fcf3ce44SJohn Forte /* 2662*fcf3ce44SJohn Forte * Check for Persistent Reservations. 2663*fcf3ce44SJohn Forte */ 2664*fcf3ce44SJohn Forte int 2665*fcf3ce44SJohn Forte l_persistent_check(int fd, struct l_disk_state_struct *l_disk_state, 2666*fcf3ce44SJohn Forte int verbose) 2667*fcf3ce44SJohn Forte { 2668*fcf3ce44SJohn Forte int status; 2669*fcf3ce44SJohn Forte Read_keys read_key_buf; 2670*fcf3ce44SJohn Forte Read_reserv read_reserv_buf; 2671*fcf3ce44SJohn Forte 2672*fcf3ce44SJohn Forte (void) memset(&read_key_buf, 0, sizeof (struct read_keys_struct)); 2673*fcf3ce44SJohn Forte if ((status = g_scsi_persistent_reserve_in_cmd(fd, 2674*fcf3ce44SJohn Forte (uchar_t *)&read_key_buf, sizeof (struct read_keys_struct), 2675*fcf3ce44SJohn Forte ACTION_READ_KEYS))) { 2676*fcf3ce44SJohn Forte return (status); 2677*fcf3ce44SJohn Forte } 2678*fcf3ce44SJohn Forte /* This means persistent reservations are supported by the disk. */ 2679*fcf3ce44SJohn Forte l_disk_state->g_disk_state.persistent_reserv_flag = 1; 2680*fcf3ce44SJohn Forte 2681*fcf3ce44SJohn Forte if (read_key_buf.rk_length) { 2682*fcf3ce44SJohn Forte l_disk_state->g_disk_state.persistent_registered = 1; 2683*fcf3ce44SJohn Forte } 2684*fcf3ce44SJohn Forte 2685*fcf3ce44SJohn Forte (void) memset(&read_reserv_buf, 0, 2686*fcf3ce44SJohn Forte sizeof (struct read_reserv_struct)); 2687*fcf3ce44SJohn Forte if ((status = g_scsi_persistent_reserve_in_cmd(fd, 2688*fcf3ce44SJohn Forte (uchar_t *)&read_reserv_buf, 2689*fcf3ce44SJohn Forte sizeof (struct read_reserv_struct), 2690*fcf3ce44SJohn Forte ACTION_READ_RESERV))) { 2691*fcf3ce44SJohn Forte return (status); 2692*fcf3ce44SJohn Forte } 2693*fcf3ce44SJohn Forte if (read_reserv_buf.rr_length) { 2694*fcf3ce44SJohn Forte l_disk_state->g_disk_state.persistent_active = 1; 2695*fcf3ce44SJohn Forte } 2696*fcf3ce44SJohn Forte if (verbose) { 2697*fcf3ce44SJohn Forte (void) fprintf(stdout, 2698*fcf3ce44SJohn Forte MSGSTR(9048, " Checking for Persistent " 2699*fcf3ce44SJohn Forte "Reservations:")); 2700*fcf3ce44SJohn Forte if (l_disk_state->g_disk_state.persistent_reserv_flag) { 2701*fcf3ce44SJohn Forte if (l_disk_state->g_disk_state.persistent_active != NULL) { 2702*fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(39, "Active")); 2703*fcf3ce44SJohn Forte } else { 2704*fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(9049, "Registered")); 2705*fcf3ce44SJohn Forte } 2706*fcf3ce44SJohn Forte } else { 2707*fcf3ce44SJohn Forte (void) fprintf(stdout, 2708*fcf3ce44SJohn Forte MSGSTR(87, 2709*fcf3ce44SJohn Forte "Not being used")); 2710*fcf3ce44SJohn Forte } 2711*fcf3ce44SJohn Forte (void) fprintf(stdout, "\n"); 2712*fcf3ce44SJohn Forte } 2713*fcf3ce44SJohn Forte return (0); 2714*fcf3ce44SJohn Forte } 2715*fcf3ce44SJohn Forte 2716*fcf3ce44SJohn Forte 2717*fcf3ce44SJohn Forte 2718*fcf3ce44SJohn Forte /* 2719*fcf3ce44SJohn Forte * Gets the disk status and 2720*fcf3ce44SJohn Forte * updates the l_disk_state_struct structure. 2721*fcf3ce44SJohn Forte * Checks for open fail, Reservation Conflicts, 2722*fcf3ce44SJohn Forte * Not Ready and so on. 2723*fcf3ce44SJohn Forte * 2724*fcf3ce44SJohn Forte * RETURNS: 2725*fcf3ce44SJohn Forte * 0 O.K. 2726*fcf3ce44SJohn Forte * non-zero otherwise 2727*fcf3ce44SJohn Forte */ 2728*fcf3ce44SJohn Forte int 2729*fcf3ce44SJohn Forte l_get_disk_port_status(char *path, struct l_disk_state_struct *l_disk_state, 2730*fcf3ce44SJohn Forte int port_a_flag, int verbose) 2731*fcf3ce44SJohn Forte { 2732*fcf3ce44SJohn Forte int fd, status = 0, local_state = 0; 2733*fcf3ce44SJohn Forte Read_capacity_data capacity; /* local read capacity buffer */ 2734*fcf3ce44SJohn Forte struct vtoc vtoc; 2735*fcf3ce44SJohn Forte 2736*fcf3ce44SJohn Forte if ((path == NULL) || (l_disk_state == NULL)) { 2737*fcf3ce44SJohn Forte return (L_INVALID_PATH_FORMAT); 2738*fcf3ce44SJohn Forte } 2739*fcf3ce44SJohn Forte 2740*fcf3ce44SJohn Forte /* 2741*fcf3ce44SJohn Forte * Try to open drive. 2742*fcf3ce44SJohn Forte */ 2743*fcf3ce44SJohn Forte if ((fd = g_object_open(path, O_RDONLY)) == -1) { 2744*fcf3ce44SJohn Forte if ((fd = g_object_open(path, 2745*fcf3ce44SJohn Forte O_RDONLY | O_NDELAY)) == -1) { 2746*fcf3ce44SJohn Forte G_DPRINTF(" l_get_disk_port_status: Error " 2747*fcf3ce44SJohn Forte "opening drive %s\n", path); 2748*fcf3ce44SJohn Forte local_state = L_OPEN_FAIL; 2749*fcf3ce44SJohn Forte } else { 2750*fcf3ce44SJohn Forte /* See if drive ready */ 2751*fcf3ce44SJohn Forte if (status = g_scsi_tur(fd)) { 2752*fcf3ce44SJohn Forte if ((status & L_SCSI_ERROR) && 2753*fcf3ce44SJohn Forte ((status & ~L_SCSI_ERROR) == STATUS_CHECK)) { 2754*fcf3ce44SJohn Forte /* 2755*fcf3ce44SJohn Forte * TBD 2756*fcf3ce44SJohn Forte * This is where I should figure out 2757*fcf3ce44SJohn Forte * if the device is Not Ready or whatever. 2758*fcf3ce44SJohn Forte */ 2759*fcf3ce44SJohn Forte local_state = L_NOT_READY; 2760*fcf3ce44SJohn Forte } else if ((status & L_SCSI_ERROR) && 2761*fcf3ce44SJohn Forte ((status & ~L_SCSI_ERROR) == 2762*fcf3ce44SJohn Forte STATUS_RESERVATION_CONFLICT)) { 2763*fcf3ce44SJohn Forte /* mark reserved */ 2764*fcf3ce44SJohn Forte local_state = L_RESERVED; 2765*fcf3ce44SJohn Forte } else { 2766*fcf3ce44SJohn Forte local_state = L_SCSI_ERR; 2767*fcf3ce44SJohn Forte } 2768*fcf3ce44SJohn Forte 2769*fcf3ce44SJohn Forte /* 2770*fcf3ce44SJohn Forte * There may not be a label on the drive - check 2771*fcf3ce44SJohn Forte */ 2772*fcf3ce44SJohn Forte } else if (ioctl(fd, DKIOCGVTOC, &vtoc) == 0) { 2773*fcf3ce44SJohn Forte /* 2774*fcf3ce44SJohn Forte * Sanity-check the vtoc 2775*fcf3ce44SJohn Forte */ 2776*fcf3ce44SJohn Forte if (vtoc.v_sanity != VTOC_SANE || 2777*fcf3ce44SJohn Forte vtoc.v_sectorsz != DEV_BSIZE) { 2778*fcf3ce44SJohn Forte local_state = L_NO_LABEL; 2779*fcf3ce44SJohn Forte G_DPRINTF(" l_get_disk_port_status: " 2780*fcf3ce44SJohn Forte "Checking vtoc - No Label found.\n"); 2781*fcf3ce44SJohn Forte } 2782*fcf3ce44SJohn Forte } else if (errno != ENOTSUP) { 2783*fcf3ce44SJohn Forte I_DPRINTF("\t- DKIOCGVTOC ioctl failed: " 2784*fcf3ce44SJohn Forte " invalid geometry\n"); 2785*fcf3ce44SJohn Forte local_state = L_NO_LABEL; 2786*fcf3ce44SJohn Forte } 2787*fcf3ce44SJohn Forte } 2788*fcf3ce44SJohn Forte } 2789*fcf3ce44SJohn Forte /* 2790*fcf3ce44SJohn Forte * Need an extra check for tape devices 2791*fcf3ce44SJohn Forte * read capacity should not be run on tape devices. 2792*fcf3ce44SJohn Forte * It will always return Not Readable 2793*fcf3ce44SJohn Forte */ 2794*fcf3ce44SJohn Forte if (((local_state == 0) || (local_state == L_NO_LABEL)) && 2795*fcf3ce44SJohn Forte ! (strstr(path, SLSH_DRV_NAME_ST))) { 2796*fcf3ce44SJohn Forte 2797*fcf3ce44SJohn Forte if (status = g_scsi_read_capacity_cmd(fd, (uchar_t *)&capacity, 2798*fcf3ce44SJohn Forte sizeof (capacity))) { 2799*fcf3ce44SJohn Forte G_DPRINTF(" l_get_disk_port_status: " 2800*fcf3ce44SJohn Forte "Read Capacity failed.\n"); 2801*fcf3ce44SJohn Forte if (status & L_SCSI_ERROR) { 2802*fcf3ce44SJohn Forte if ((status & ~L_SCSI_ERROR) == 2803*fcf3ce44SJohn Forte STATUS_RESERVATION_CONFLICT) { 2804*fcf3ce44SJohn Forte /* mark reserved */ 2805*fcf3ce44SJohn Forte local_state |= L_RESERVED; 2806*fcf3ce44SJohn Forte } else 2807*fcf3ce44SJohn Forte /* mark bad */ 2808*fcf3ce44SJohn Forte local_state |= L_NOT_READABLE; 2809*fcf3ce44SJohn Forte } else { 2810*fcf3ce44SJohn Forte /* 2811*fcf3ce44SJohn Forte * TBD 2812*fcf3ce44SJohn Forte * Need a more complete state definition here. 2813*fcf3ce44SJohn Forte */ 2814*fcf3ce44SJohn Forte l_disk_state->g_disk_state.d_state_flags[port_a_flag] = 2815*fcf3ce44SJohn Forte L_SCSI_ERR; 2816*fcf3ce44SJohn Forte (void) close(fd); 2817*fcf3ce44SJohn Forte return (0); 2818*fcf3ce44SJohn Forte } 2819*fcf3ce44SJohn Forte } else { 2820*fcf3ce44SJohn Forte /* save capacity */ 2821*fcf3ce44SJohn Forte l_disk_state->g_disk_state.num_blocks = 2822*fcf3ce44SJohn Forte capacity.last_block_addr + 1; 2823*fcf3ce44SJohn Forte } 2824*fcf3ce44SJohn Forte 2825*fcf3ce44SJohn Forte } 2826*fcf3ce44SJohn Forte (void) close(fd); 2827*fcf3ce44SJohn Forte 2828*fcf3ce44SJohn Forte l_disk_state->g_disk_state.d_state_flags[port_a_flag] = local_state; 2829*fcf3ce44SJohn Forte G_DPRINTF(" l_get_disk_port_status: Individual Disk" 2830*fcf3ce44SJohn Forte " Status: 0x%x for" 2831*fcf3ce44SJohn Forte " port %s for path:" 2832*fcf3ce44SJohn Forte " %s\n", local_state, 2833*fcf3ce44SJohn Forte port_a_flag ? "A" : "B", path); 2834*fcf3ce44SJohn Forte 2835*fcf3ce44SJohn Forte return (0); 2836*fcf3ce44SJohn Forte } 2837*fcf3ce44SJohn Forte 2838*fcf3ce44SJohn Forte 2839*fcf3ce44SJohn Forte 2840*fcf3ce44SJohn Forte /* 2841*fcf3ce44SJohn Forte * Copy and format page 1 from big buffer to state structure. 2842*fcf3ce44SJohn Forte * 2843*fcf3ce44SJohn Forte * RETURNS: 2844*fcf3ce44SJohn Forte * 0 O.K. 2845*fcf3ce44SJohn Forte * non-zero otherwise 2846*fcf3ce44SJohn Forte */ 2847*fcf3ce44SJohn Forte 2848*fcf3ce44SJohn Forte static int 2849*fcf3ce44SJohn Forte copy_config_page(struct l_state_struct *l_state, uchar_t *from_ptr) 2850*fcf3ce44SJohn Forte { 2851*fcf3ce44SJohn Forte IB_page_config *encl_ptr; 2852*fcf3ce44SJohn Forte int size, i; 2853*fcf3ce44SJohn Forte 2854*fcf3ce44SJohn Forte 2855*fcf3ce44SJohn Forte encl_ptr = (struct ib_page_config *)(void *)from_ptr; 2856*fcf3ce44SJohn Forte 2857*fcf3ce44SJohn Forte /* Sanity check. */ 2858*fcf3ce44SJohn Forte if ((encl_ptr->enc_len > MAX_VEND_SPECIFIC_ENC) || 2859*fcf3ce44SJohn Forte (encl_ptr->enc_len == 0)) { 2860*fcf3ce44SJohn Forte return (L_REC_DIAG_PG1); 2861*fcf3ce44SJohn Forte } 2862*fcf3ce44SJohn Forte if ((encl_ptr->enc_num_elem > MAX_IB_ELEMENTS) || 2863*fcf3ce44SJohn Forte (encl_ptr->enc_num_elem == 0)) { 2864*fcf3ce44SJohn Forte return (L_REC_DIAG_PG1); 2865*fcf3ce44SJohn Forte } 2866*fcf3ce44SJohn Forte 2867*fcf3ce44SJohn Forte size = HEADER_LEN + 4 + HEADER_LEN + encl_ptr->enc_len; 2868*fcf3ce44SJohn Forte bcopy((void *)(from_ptr), 2869*fcf3ce44SJohn Forte (void *)&l_state->ib_tbl.config, (size_t)size); 2870*fcf3ce44SJohn Forte /* 2871*fcf3ce44SJohn Forte * Copy Type Descriptors seperately to get aligned. 2872*fcf3ce44SJohn Forte */ 2873*fcf3ce44SJohn Forte from_ptr += size; 2874*fcf3ce44SJohn Forte size = (sizeof (struct type_desc_hdr))*encl_ptr->enc_num_elem; 2875*fcf3ce44SJohn Forte bcopy((void *)(from_ptr), 2876*fcf3ce44SJohn Forte (void *)&l_state->ib_tbl.config.type_hdr, (size_t)size); 2877*fcf3ce44SJohn Forte 2878*fcf3ce44SJohn Forte /* 2879*fcf3ce44SJohn Forte * Copy Text Descriptors seperately to get aligned. 2880*fcf3ce44SJohn Forte * 2881*fcf3ce44SJohn Forte * Must use the text size from the Type Descriptors. 2882*fcf3ce44SJohn Forte */ 2883*fcf3ce44SJohn Forte from_ptr += size; 2884*fcf3ce44SJohn Forte for (i = 0; i < (int)l_state->ib_tbl.config.enc_num_elem; i++) { 2885*fcf3ce44SJohn Forte size = l_state->ib_tbl.config.type_hdr[i].text_len; 2886*fcf3ce44SJohn Forte bcopy((void *)(from_ptr), 2887*fcf3ce44SJohn Forte (void *)&l_state->ib_tbl.config.text[i], (size_t)size); 2888*fcf3ce44SJohn Forte from_ptr += size; 2889*fcf3ce44SJohn Forte } 2890*fcf3ce44SJohn Forte return (0); 2891*fcf3ce44SJohn Forte } 2892*fcf3ce44SJohn Forte 2893*fcf3ce44SJohn Forte 2894*fcf3ce44SJohn Forte 2895*fcf3ce44SJohn Forte /* 2896*fcf3ce44SJohn Forte * Copy page 7 (Element Descriptor page) to state structure. 2897*fcf3ce44SJohn Forte * Copy header then copy each element descriptor 2898*fcf3ce44SJohn Forte * seperately. 2899*fcf3ce44SJohn Forte * 2900*fcf3ce44SJohn Forte * RETURNS: 2901*fcf3ce44SJohn Forte * 0 O.K. 2902*fcf3ce44SJohn Forte * non-zero otherwise 2903*fcf3ce44SJohn Forte */ 2904*fcf3ce44SJohn Forte static void 2905*fcf3ce44SJohn Forte copy_page_7(struct l_state_struct *l_state, uchar_t *from_ptr) 2906*fcf3ce44SJohn Forte { 2907*fcf3ce44SJohn Forte uchar_t *my_from_ptr; 2908*fcf3ce44SJohn Forte int size, j, k, p7_index; 2909*fcf3ce44SJohn Forte 2910*fcf3ce44SJohn Forte size = HEADER_LEN + 2911*fcf3ce44SJohn Forte sizeof (l_state->ib_tbl.p7_s.gen_code); 2912*fcf3ce44SJohn Forte bcopy((void *)(from_ptr), 2913*fcf3ce44SJohn Forte (void *)&l_state->ib_tbl.p7_s, (size_t)size); 2914*fcf3ce44SJohn Forte my_from_ptr = from_ptr + size; 2915*fcf3ce44SJohn Forte if (getenv("_LUX_D_DEBUG") != NULL) { 2916*fcf3ce44SJohn Forte g_dump(" copy_page_7: Page 7 header: ", 2917*fcf3ce44SJohn Forte (uchar_t *)&l_state->ib_tbl.p7_s, size, 2918*fcf3ce44SJohn Forte HEX_ASCII); 2919*fcf3ce44SJohn Forte (void) fprintf(stdout, 2920*fcf3ce44SJohn Forte " copy_page_7: Elements being stored " 2921*fcf3ce44SJohn Forte "in state table\n" 2922*fcf3ce44SJohn Forte " "); 2923*fcf3ce44SJohn Forte } 2924*fcf3ce44SJohn Forte /* I am assuming page 1 has been read. */ 2925*fcf3ce44SJohn Forte for (j = 0, p7_index = 0; 2926*fcf3ce44SJohn Forte j < (int)l_state->ib_tbl.config.enc_num_elem; j++) { 2927*fcf3ce44SJohn Forte /* Copy global element */ 2928*fcf3ce44SJohn Forte size = HEADER_LEN + 2929*fcf3ce44SJohn Forte ((*(my_from_ptr + 2) << 8) | *(my_from_ptr + 3)); 2930*fcf3ce44SJohn Forte bcopy((void *)(my_from_ptr), 2931*fcf3ce44SJohn Forte (void *)&l_state->ib_tbl.p7_s.element_desc[p7_index++], 2932*fcf3ce44SJohn Forte (size_t)size); 2933*fcf3ce44SJohn Forte my_from_ptr += size; 2934*fcf3ce44SJohn Forte for (k = 0; k < (int)l_state->ib_tbl.config.type_hdr[j].num; 2935*fcf3ce44SJohn Forte k++) { 2936*fcf3ce44SJohn Forte /* Copy individual elements */ 2937*fcf3ce44SJohn Forte size = HEADER_LEN + 2938*fcf3ce44SJohn Forte ((*(my_from_ptr + 2) << 8) | 2939*fcf3ce44SJohn Forte *(my_from_ptr + 3)); 2940*fcf3ce44SJohn Forte bcopy((void *)(my_from_ptr), 2941*fcf3ce44SJohn Forte (void *)&l_state->ib_tbl.p7_s.element_desc[p7_index++], 2942*fcf3ce44SJohn Forte (size_t)size); 2943*fcf3ce44SJohn Forte my_from_ptr += size; 2944*fcf3ce44SJohn Forte D_DPRINTF("."); 2945*fcf3ce44SJohn Forte } 2946*fcf3ce44SJohn Forte } 2947*fcf3ce44SJohn Forte D_DPRINTF("\n"); 2948*fcf3ce44SJohn Forte } 2949*fcf3ce44SJohn Forte 2950*fcf3ce44SJohn Forte 2951*fcf3ce44SJohn Forte /* 2952*fcf3ce44SJohn Forte * Gets IB diagnostic pages on a given pathname from l_get_envsen(). 2953*fcf3ce44SJohn Forte * It also fills up the individual device element of l_state_struct using 2954*fcf3ce44SJohn Forte * diagnostics pages. 2955*fcf3ce44SJohn Forte * Gets IB diagnostic pages on a given pathname from l_get_envsen(). 2956*fcf3ce44SJohn Forte * It also fills up the individual device element of l_state_struct using 2957*fcf3ce44SJohn Forte * diagnostics pages. 2958*fcf3ce44SJohn Forte * 2959*fcf3ce44SJohn Forte * The path must be of the ses driver. 2960*fcf3ce44SJohn Forte * e.g. 2961*fcf3ce44SJohn Forte * /devices/sbus@1f,0/SUNW,socal@1,0/SUNW,sf@0,0/ses@e,0:0 2962*fcf3ce44SJohn Forte * or 2963*fcf3ce44SJohn Forte * /devices/sbus@1f,0/SUNW,socal@1,0/SUNW,sf@0,0/ses@WWN,0:0 2964*fcf3ce44SJohn Forte * 2965*fcf3ce44SJohn Forte * 2966*fcf3ce44SJohn Forte * RETURNS: 2967*fcf3ce44SJohn Forte * 0 O.K. 2968*fcf3ce44SJohn Forte * non-zero otherwise 2969*fcf3ce44SJohn Forte */ 2970*fcf3ce44SJohn Forte int 2971*fcf3ce44SJohn Forte l_get_ib_status(char *path, struct l_state_struct *l_state, 2972*fcf3ce44SJohn Forte int verbose) 2973*fcf3ce44SJohn Forte { 2974*fcf3ce44SJohn Forte L_inquiry inq; 2975*fcf3ce44SJohn Forte uchar_t *ib_buf, *from_ptr; 2976*fcf3ce44SJohn Forte int num_pages, i, size, err; 2977*fcf3ce44SJohn Forte IB_page_2 *encl_ptr; 2978*fcf3ce44SJohn Forte int front_index, rear_index; 2979*fcf3ce44SJohn Forte int enc_type = 0; 2980*fcf3ce44SJohn Forte 2981*fcf3ce44SJohn Forte if ((path == NULL) || (l_state == NULL)) { 2982*fcf3ce44SJohn Forte return (L_INVALID_PATH_FORMAT); 2983*fcf3ce44SJohn Forte } 2984*fcf3ce44SJohn Forte 2985*fcf3ce44SJohn Forte /* 2986*fcf3ce44SJohn Forte * get big buffer 2987*fcf3ce44SJohn Forte */ 2988*fcf3ce44SJohn Forte if ((ib_buf = (uchar_t *)calloc(1, 2989*fcf3ce44SJohn Forte MAX_REC_DIAG_LENGTH)) == NULL) { 2990*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 2991*fcf3ce44SJohn Forte } 2992*fcf3ce44SJohn Forte 2993*fcf3ce44SJohn Forte /* 2994*fcf3ce44SJohn Forte * Get IB information 2995*fcf3ce44SJohn Forte * Even if there are 2 IB's in this box on this loop don't bother 2996*fcf3ce44SJohn Forte * talking to the other one as both IB's in a box 2997*fcf3ce44SJohn Forte * are supposed to report the same information. 2998*fcf3ce44SJohn Forte */ 2999*fcf3ce44SJohn Forte if (err = l_get_envsen(path, ib_buf, MAX_REC_DIAG_LENGTH, 3000*fcf3ce44SJohn Forte verbose)) { 3001*fcf3ce44SJohn Forte (void) g_destroy_data(ib_buf); 3002*fcf3ce44SJohn Forte return (err); 3003*fcf3ce44SJohn Forte } 3004*fcf3ce44SJohn Forte 3005*fcf3ce44SJohn Forte /* 3006*fcf3ce44SJohn Forte * Set up state structure 3007*fcf3ce44SJohn Forte */ 3008*fcf3ce44SJohn Forte bcopy((void *)ib_buf, (void *)&l_state->ib_tbl.p0, 3009*fcf3ce44SJohn Forte (size_t)sizeof (struct ib_page_0)); 3010*fcf3ce44SJohn Forte 3011*fcf3ce44SJohn Forte num_pages = l_state->ib_tbl.p0.page_len; 3012*fcf3ce44SJohn Forte from_ptr = ib_buf + HEADER_LEN + l_state->ib_tbl.p0.page_len; 3013*fcf3ce44SJohn Forte 3014*fcf3ce44SJohn Forte for (i = 1; i < num_pages; i++) { 3015*fcf3ce44SJohn Forte if (l_state->ib_tbl.p0.sup_page_codes[i] == L_PAGE_1) { 3016*fcf3ce44SJohn Forte if (err = copy_config_page(l_state, from_ptr)) { 3017*fcf3ce44SJohn Forte return (err); 3018*fcf3ce44SJohn Forte } 3019*fcf3ce44SJohn Forte } else if (l_state->ib_tbl.p0.sup_page_codes[i] == 3020*fcf3ce44SJohn Forte L_PAGE_2) { 3021*fcf3ce44SJohn Forte encl_ptr = (struct ib_page_2 *)(void *)from_ptr; 3022*fcf3ce44SJohn Forte size = HEADER_LEN + encl_ptr->page_len; 3023*fcf3ce44SJohn Forte bcopy((void *)(from_ptr), 3024*fcf3ce44SJohn Forte (void *)&l_state->ib_tbl.p2_s, (size_t)size); 3025*fcf3ce44SJohn Forte if (getenv("_LUX_D_DEBUG") != NULL) { 3026*fcf3ce44SJohn Forte g_dump(" l_get_ib_status: Page 2: ", 3027*fcf3ce44SJohn Forte (uchar_t *)&l_state->ib_tbl.p2_s, size, 3028*fcf3ce44SJohn Forte HEX_ONLY); 3029*fcf3ce44SJohn Forte } 3030*fcf3ce44SJohn Forte 3031*fcf3ce44SJohn Forte } else if (l_state->ib_tbl.p0.sup_page_codes[i] == 3032*fcf3ce44SJohn Forte L_PAGE_7) { 3033*fcf3ce44SJohn Forte (void) copy_page_7(l_state, from_ptr); 3034*fcf3ce44SJohn Forte } 3035*fcf3ce44SJohn Forte from_ptr += ((*(from_ptr + 2) << 8) | *(from_ptr + 3)); 3036*fcf3ce44SJohn Forte from_ptr += HEADER_LEN; 3037*fcf3ce44SJohn Forte } 3038*fcf3ce44SJohn Forte (void) g_destroy_data(ib_buf); 3039*fcf3ce44SJohn Forte G_DPRINTF(" l_get_ib_status: Read %d Receive Diagnostic pages " 3040*fcf3ce44SJohn Forte "from the IB.\n", num_pages); 3041*fcf3ce44SJohn Forte 3042*fcf3ce44SJohn Forte if (err = g_get_inquiry(path, &inq)) { 3043*fcf3ce44SJohn Forte return (err); 3044*fcf3ce44SJohn Forte } 3045*fcf3ce44SJohn Forte enc_type = l_get_enc_type(inq); 3046*fcf3ce44SJohn Forte /* 3047*fcf3ce44SJohn Forte * Get the total number of drives per box. 3048*fcf3ce44SJohn Forte * This assumes front & rear are the same. 3049*fcf3ce44SJohn Forte */ 3050*fcf3ce44SJohn Forte l_state->total_num_drv = 0; /* default to use as a flag */ 3051*fcf3ce44SJohn Forte for (i = 0; i < (int)l_state->ib_tbl.config.enc_num_elem; i++) { 3052*fcf3ce44SJohn Forte if (l_state->ib_tbl.config.type_hdr[i].type == ELM_TYP_DD) { 3053*fcf3ce44SJohn Forte if (l_state->total_num_drv) { 3054*fcf3ce44SJohn Forte if (l_state->total_num_drv != 3055*fcf3ce44SJohn Forte (l_state->ib_tbl.config.type_hdr[i].num * 2)) { 3056*fcf3ce44SJohn Forte return (L_INVALID_NUM_DISKS_ENCL); 3057*fcf3ce44SJohn Forte } 3058*fcf3ce44SJohn Forte } else { 3059*fcf3ce44SJohn Forte if (enc_type == DAK_ENC_TYPE) { 3060*fcf3ce44SJohn Forte l_state->total_num_drv = 3061*fcf3ce44SJohn Forte l_state->ib_tbl.config.type_hdr[i].num; 3062*fcf3ce44SJohn Forte } else { 3063*fcf3ce44SJohn Forte l_state->total_num_drv = 3064*fcf3ce44SJohn Forte l_state->ib_tbl.config.type_hdr[i].num * 2; 3065*fcf3ce44SJohn Forte } 3066*fcf3ce44SJohn Forte } 3067*fcf3ce44SJohn Forte } 3068*fcf3ce44SJohn Forte } 3069*fcf3ce44SJohn Forte 3070*fcf3ce44SJohn Forte /* 3071*fcf3ce44SJohn Forte * transfer the individual drive Device Element information 3072*fcf3ce44SJohn Forte * from IB state to drive state. 3073*fcf3ce44SJohn Forte */ 3074*fcf3ce44SJohn Forte if (err = l_get_disk_element_index(l_state, &front_index, 3075*fcf3ce44SJohn Forte &rear_index)) { 3076*fcf3ce44SJohn Forte return (err); 3077*fcf3ce44SJohn Forte } 3078*fcf3ce44SJohn Forte /* Skip global element */ 3079*fcf3ce44SJohn Forte front_index++; 3080*fcf3ce44SJohn Forte if (enc_type == DAK_ENC_TYPE) { 3081*fcf3ce44SJohn Forte rear_index += l_state->total_num_drv/2 + 1; 3082*fcf3ce44SJohn Forte } else { 3083*fcf3ce44SJohn Forte rear_index++; 3084*fcf3ce44SJohn Forte } 3085*fcf3ce44SJohn Forte 3086*fcf3ce44SJohn Forte for (i = 0; i < l_state->total_num_drv/2; i++) { 3087*fcf3ce44SJohn Forte bcopy((void *)&l_state->ib_tbl.p2_s.element[front_index + i], 3088*fcf3ce44SJohn Forte (void *)&l_state->drv_front[i].ib_status, 3089*fcf3ce44SJohn Forte (size_t)sizeof (struct device_element)); 3090*fcf3ce44SJohn Forte bcopy((void *)&l_state->ib_tbl.p2_s.element[rear_index + i], 3091*fcf3ce44SJohn Forte (void *)&l_state->drv_rear[i].ib_status, 3092*fcf3ce44SJohn Forte (size_t)sizeof (struct device_element)); 3093*fcf3ce44SJohn Forte } 3094*fcf3ce44SJohn Forte if (getenv("_LUX_G_DEBUG") != NULL) { 3095*fcf3ce44SJohn Forte g_dump(" l_get_ib_status: disk elements: ", 3096*fcf3ce44SJohn Forte (uchar_t *)&l_state->ib_tbl.p2_s.element[front_index], 3097*fcf3ce44SJohn Forte ((sizeof (struct device_element)) * (l_state->total_num_drv)), 3098*fcf3ce44SJohn Forte HEX_ONLY); 3099*fcf3ce44SJohn Forte } 3100*fcf3ce44SJohn Forte 3101*fcf3ce44SJohn Forte return (0); 3102*fcf3ce44SJohn Forte } 3103*fcf3ce44SJohn Forte 3104*fcf3ce44SJohn Forte 3105*fcf3ce44SJohn Forte 3106*fcf3ce44SJohn Forte /* 3107*fcf3ce44SJohn Forte * Given an IB path get the port, A or B. 3108*fcf3ce44SJohn Forte * 3109*fcf3ce44SJohn Forte * OUTPUT: 3110*fcf3ce44SJohn Forte * port_a: sets to 1 for port A 3111*fcf3ce44SJohn Forte * and 0 for port B. 3112*fcf3ce44SJohn Forte * RETURNS: 3113*fcf3ce44SJohn Forte * err: 0 O.k. 3114*fcf3ce44SJohn Forte * non-zero otherwise 3115*fcf3ce44SJohn Forte */ 3116*fcf3ce44SJohn Forte int 3117*fcf3ce44SJohn Forte l_get_port(char *ses_path, int *port_a, int verbose) 3118*fcf3ce44SJohn Forte { 3119*fcf3ce44SJohn Forte L_state *ib_state = NULL; 3120*fcf3ce44SJohn Forte Ctlr_elem_st ctlr; 3121*fcf3ce44SJohn Forte int i, err, elem_index = 0; 3122*fcf3ce44SJohn Forte 3123*fcf3ce44SJohn Forte if ((ses_path == NULL) || (port_a == NULL)) { 3124*fcf3ce44SJohn Forte return (L_NO_SES_PATH); 3125*fcf3ce44SJohn Forte } 3126*fcf3ce44SJohn Forte 3127*fcf3ce44SJohn Forte if ((ib_state = (L_state *)calloc(1, sizeof (L_state))) == NULL) { 3128*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 3129*fcf3ce44SJohn Forte } 3130*fcf3ce44SJohn Forte 3131*fcf3ce44SJohn Forte bzero(&ctlr, sizeof (ctlr)); 3132*fcf3ce44SJohn Forte if (err = l_get_ib_status(ses_path, ib_state, verbose)) { 3133*fcf3ce44SJohn Forte (void) l_free_lstate(&ib_state); 3134*fcf3ce44SJohn Forte return (err); 3135*fcf3ce44SJohn Forte } 3136*fcf3ce44SJohn Forte 3137*fcf3ce44SJohn Forte for (i = 0; i < (int)ib_state->ib_tbl.config.enc_num_elem; i++) { 3138*fcf3ce44SJohn Forte elem_index++; /* skip global */ 3139*fcf3ce44SJohn Forte if (ib_state->ib_tbl.config.type_hdr[i].type == ELM_TYP_IB) { 3140*fcf3ce44SJohn Forte bcopy((const void *) 3141*fcf3ce44SJohn Forte &ib_state->ib_tbl.p2_s.element[elem_index], 3142*fcf3ce44SJohn Forte (void *)&ctlr, sizeof (ctlr)); 3143*fcf3ce44SJohn Forte break; 3144*fcf3ce44SJohn Forte } 3145*fcf3ce44SJohn Forte elem_index += ib_state->ib_tbl.config.type_hdr[i].num; 3146*fcf3ce44SJohn Forte } 3147*fcf3ce44SJohn Forte *port_a = ctlr.report; 3148*fcf3ce44SJohn Forte G_DPRINTF(" l_get_port: Found ses is the %s card.\n", 3149*fcf3ce44SJohn Forte ctlr.report ? "A" : "B"); 3150*fcf3ce44SJohn Forte (void) l_free_lstate(&ib_state); 3151*fcf3ce44SJohn Forte return (0); 3152*fcf3ce44SJohn Forte } 3153*fcf3ce44SJohn Forte 3154*fcf3ce44SJohn Forte /* 3155*fcf3ce44SJohn Forte * This function expects a pointer to a device path ending in the form 3156*fcf3ce44SJohn Forte * .../ses@w<NODEWWN>,<something> or .../ssd@w<NODEWWN>,<something> 3157*fcf3ce44SJohn Forte * 3158*fcf3ce44SJohn Forte * No validity checking of the path is done by the function. 3159*fcf3ce44SJohn Forte * 3160*fcf3ce44SJohn Forte * It gets the wwn (node wwn) out of the passed string, searches the passed 3161*fcf3ce44SJohn Forte * map for a match, gets the corresponding phys addr (port id) for that entry 3162*fcf3ce44SJohn Forte * and stores in the pointer the caller has passed as an argument (pid) 3163*fcf3ce44SJohn Forte * 3164*fcf3ce44SJohn Forte * This function is to be called only for public/fabric topologies 3165*fcf3ce44SJohn Forte * 3166*fcf3ce44SJohn Forte * If this interface is going to get exported, one point to be 3167*fcf3ce44SJohn Forte * considered is if a call to g_get_path_type() has to be made. 3168*fcf3ce44SJohn Forte * 3169*fcf3ce44SJohn Forte * INPUT: 3170*fcf3ce44SJohn Forte * path - pointer to the enclosure/disk device path 3171*fcf3ce44SJohn Forte * map - pointer to the map 3172*fcf3ce44SJohn Forte * 3173*fcf3ce44SJohn Forte * OUTPUT: 3174*fcf3ce44SJohn Forte * pid - the physical address associated for the node WWN that was found 3175*fcf3ce44SJohn Forte * in the map 3176*fcf3ce44SJohn Forte * 3177*fcf3ce44SJohn Forte * RETURNS: 3178*fcf3ce44SJohn Forte * 0 - on success 3179*fcf3ce44SJohn Forte * non-zero - otherwise 3180*fcf3ce44SJohn Forte */ 3181*fcf3ce44SJohn Forte int 3182*fcf3ce44SJohn Forte l_get_pid_from_path(const char *path, const gfc_map_t *map, int *pid) 3183*fcf3ce44SJohn Forte { 3184*fcf3ce44SJohn Forte int i; 3185*fcf3ce44SJohn Forte unsigned long long ll_wwn; 3186*fcf3ce44SJohn Forte char *char_ptr, wwn_str[WWN_SIZE * 2 + 1]; 3187*fcf3ce44SJohn Forte char *byte_ptr, *temp_ptr; 3188*fcf3ce44SJohn Forte gfc_port_dev_info_t *dev_addr_ptr; 3189*fcf3ce44SJohn Forte mp_pathlist_t pathlist; 3190*fcf3ce44SJohn Forte char path0[MAXPATHLEN], pwwn0[WWN_S_LEN]; 3191*fcf3ce44SJohn Forte 3192*fcf3ce44SJohn Forte /* if mpxio device */ 3193*fcf3ce44SJohn Forte if (strstr(path, SCSI_VHCI) != NULL) { 3194*fcf3ce44SJohn Forte (void) strcpy(path0, path); 3195*fcf3ce44SJohn Forte if (g_get_pathlist(path0, &pathlist)) { 3196*fcf3ce44SJohn Forte return (L_INVALID_PATH); 3197*fcf3ce44SJohn Forte } else { 3198*fcf3ce44SJohn Forte (void) strncpy(pwwn0, pathlist.path_info[0]. 3199*fcf3ce44SJohn Forte path_addr, L_WWN_LENGTH); 3200*fcf3ce44SJohn Forte pwwn0[L_WWN_LENGTH] = '\0'; 3201*fcf3ce44SJohn Forte free(pathlist.path_info); 3202*fcf3ce44SJohn Forte char_ptr = pwwn0; 3203*fcf3ce44SJohn Forte } 3204*fcf3ce44SJohn Forte } else { 3205*fcf3ce44SJohn Forte /* First a quick check on the path */ 3206*fcf3ce44SJohn Forte if (((char_ptr = strrchr(path, '@')) == NULL) || 3207*fcf3ce44SJohn Forte (*++char_ptr != 'w')) { 3208*fcf3ce44SJohn Forte return (L_INVALID_PATH); 3209*fcf3ce44SJohn Forte } else { 3210*fcf3ce44SJohn Forte char_ptr++; 3211*fcf3ce44SJohn Forte } 3212*fcf3ce44SJohn Forte } 3213*fcf3ce44SJohn Forte 3214*fcf3ce44SJohn Forte if (strlen(char_ptr) < (WWN_SIZE * 2)) { 3215*fcf3ce44SJohn Forte return (L_INVALID_PATH); 3216*fcf3ce44SJohn Forte } 3217*fcf3ce44SJohn Forte (void) strncpy(wwn_str, char_ptr, WWN_SIZE * 2); 3218*fcf3ce44SJohn Forte wwn_str[WWN_SIZE * 2] = '\0'; 3219*fcf3ce44SJohn Forte errno = 0; /* For error checking */ 3220*fcf3ce44SJohn Forte ll_wwn = strtoull(wwn_str, &temp_ptr, L_WWN_LENGTH); 3221*fcf3ce44SJohn Forte 3222*fcf3ce44SJohn Forte if (errno || (temp_ptr != (wwn_str + (WWN_SIZE * 2)))) { 3223*fcf3ce44SJohn Forte return (L_INVALID_PATH); 3224*fcf3ce44SJohn Forte } 3225*fcf3ce44SJohn Forte 3226*fcf3ce44SJohn Forte byte_ptr = (char *)&ll_wwn; 3227*fcf3ce44SJohn Forte 3228*fcf3ce44SJohn Forte /* 3229*fcf3ce44SJohn Forte * Search for the ses's node wwn in map to get the area and 3230*fcf3ce44SJohn Forte * domain ids from the corresponding port id (phys address). 3231*fcf3ce44SJohn Forte */ 3232*fcf3ce44SJohn Forte for (dev_addr_ptr = map->dev_addr, i = 0; i < map->count; 3233*fcf3ce44SJohn Forte dev_addr_ptr++, i++) { 3234*fcf3ce44SJohn Forte if (bcmp((char *)dev_addr_ptr->gfc_port_dev. 3235*fcf3ce44SJohn Forte pub_port.dev_nwwn.raw_wwn, byte_ptr, WWN_SIZE) == 0) 3236*fcf3ce44SJohn Forte break; 3237*fcf3ce44SJohn Forte } 3238*fcf3ce44SJohn Forte if (i >= map->count) 3239*fcf3ce44SJohn Forte return (L_INVALID_PATH); 3240*fcf3ce44SJohn Forte *pid = dev_addr_ptr->gfc_port_dev.pub_port.dev_did.port_id; 3241*fcf3ce44SJohn Forte return (0); 3242*fcf3ce44SJohn Forte } 3243*fcf3ce44SJohn Forte 3244*fcf3ce44SJohn Forte 3245*fcf3ce44SJohn Forte /* 3246*fcf3ce44SJohn Forte * Finds the disk's node wwn string, and 3247*fcf3ce44SJohn Forte * port A and B's WWNs and their port status. 3248*fcf3ce44SJohn Forte * 3249*fcf3ce44SJohn Forte * INPUT: 3250*fcf3ce44SJohn Forte * path - pointer to a ses path 3251*fcf3ce44SJohn Forte * wwn_list - pointer to the wwn_list 3252*fcf3ce44SJohn Forte * 3253*fcf3ce44SJohn Forte * OUTPUT: 3254*fcf3ce44SJohn Forte * state - node_wwn and wwn of ports A & B of disk, etc are inited 3255*fcf3ce44SJohn Forte * - by l_get_disk_status() 3256*fcf3ce44SJohn Forte * found_flag - incremented after each examined element in the map 3257*fcf3ce44SJohn Forte * 3258*fcf3ce44SJohn Forte * RETURNS: 3259*fcf3ce44SJohn Forte * 0 O.K. 3260*fcf3ce44SJohn Forte * non-zero otherwise. 3261*fcf3ce44SJohn Forte */ 3262*fcf3ce44SJohn Forte static int 3263*fcf3ce44SJohn Forte l_get_node_status(char *path, struct l_disk_state_struct *state, 3264*fcf3ce44SJohn Forte int *found_flag, WWN_list *wwn_list, int verbose) 3265*fcf3ce44SJohn Forte { 3266*fcf3ce44SJohn Forte int j, select_id, err; 3267*fcf3ce44SJohn Forte int path_pid; 3268*fcf3ce44SJohn Forte char temp_path[MAXPATHLEN]; 3269*fcf3ce44SJohn Forte char sbuf[MAXPATHLEN], *char_ptr; 3270*fcf3ce44SJohn Forte gfc_map_mp_t *map_mp, *map_ptr; 3271*fcf3ce44SJohn Forte struct stat stat_buf; 3272*fcf3ce44SJohn Forte WWN_list *wwnlp; 3273*fcf3ce44SJohn Forte char wwnp[WWN_S_LEN]; 3274*fcf3ce44SJohn Forte 3275*fcf3ce44SJohn Forte /* 3276*fcf3ce44SJohn Forte * Get a new map. 3277*fcf3ce44SJohn Forte */ 3278*fcf3ce44SJohn Forte map_mp = NULL; 3279*fcf3ce44SJohn Forte if (err = get_mp_dev_map(path, &map_mp, verbose)) 3280*fcf3ce44SJohn Forte return (err); 3281*fcf3ce44SJohn Forte 3282*fcf3ce44SJohn Forte for (map_ptr = map_mp; map_ptr != NULL; map_ptr = map_ptr->map_next) { 3283*fcf3ce44SJohn Forte switch (map_ptr->map.hba_addr.port_topology) { 3284*fcf3ce44SJohn Forte case FC_TOP_PRIVATE_LOOP: 3285*fcf3ce44SJohn Forte for (j = 0; j < map_ptr->map.count; j++) { 3286*fcf3ce44SJohn Forte /* 3287*fcf3ce44SJohn Forte * Get a generic path to a device 3288*fcf3ce44SJohn Forte * 3289*fcf3ce44SJohn Forte * This assumes the path looks something like this 3290*fcf3ce44SJohn Forte * /devices/sbus@1f,0/SUNW,socal@1,0/SUNW,sf@0,0/... 3291*fcf3ce44SJohn Forte * ...ses@x,0:0 3292*fcf3ce44SJohn Forte * then creates a path that looks like 3293*fcf3ce44SJohn Forte * /devices/sbus@1f,0/SUNW,socal@1,0/SUNW,sf@0,0/ssd@ 3294*fcf3ce44SJohn Forte */ 3295*fcf3ce44SJohn Forte (void) strcpy(temp_path, path); 3296*fcf3ce44SJohn Forte if ((char_ptr = strrchr(temp_path, '/')) == NULL) { 3297*fcf3ce44SJohn Forte free_mp_dev_map(&map_mp); 3298*fcf3ce44SJohn Forte return (L_INVALID_PATH); 3299*fcf3ce44SJohn Forte } 3300*fcf3ce44SJohn Forte *char_ptr = '\0'; /* Terminate sting */ 3301*fcf3ce44SJohn Forte (void) strcat(temp_path, SLSH_DRV_NAME_SSD); 3302*fcf3ce44SJohn Forte /* 3303*fcf3ce44SJohn Forte * Create complete path. 3304*fcf3ce44SJohn Forte * 3305*fcf3ce44SJohn Forte * Build entry ssd@xx,0:c,raw 3306*fcf3ce44SJohn Forte * where xx is the WWN. 3307*fcf3ce44SJohn Forte */ 3308*fcf3ce44SJohn Forte select_id = g_sf_alpa_to_switch[map_ptr->map. 3309*fcf3ce44SJohn Forte dev_addr[j].gfc_port_dev.priv_port.sf_al_pa]; 3310*fcf3ce44SJohn Forte G_DPRINTF(" l_get_node_status: Searching loop map " 3311*fcf3ce44SJohn Forte "to find disk: ID:0x%x" 3312*fcf3ce44SJohn Forte " AL_PA:0x%x\n", select_id, 3313*fcf3ce44SJohn Forte state->ib_status.sel_id); 3314*fcf3ce44SJohn Forte 3315*fcf3ce44SJohn Forte if (strstr(path, SCSI_VHCI) == NULL) { 3316*fcf3ce44SJohn Forte 3317*fcf3ce44SJohn Forte (void) sprintf(sbuf, 3318*fcf3ce44SJohn Forte "w%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x,0:c,raw", 3319*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3320*fcf3ce44SJohn Forte sf_port_wwn[0], 3321*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3322*fcf3ce44SJohn Forte sf_port_wwn[1], 3323*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3324*fcf3ce44SJohn Forte sf_port_wwn[2], 3325*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3326*fcf3ce44SJohn Forte sf_port_wwn[3], 3327*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3328*fcf3ce44SJohn Forte sf_port_wwn[4], 3329*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3330*fcf3ce44SJohn Forte sf_port_wwn[5], 3331*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3332*fcf3ce44SJohn Forte sf_port_wwn[6], 3333*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3334*fcf3ce44SJohn Forte sf_port_wwn[7]); 3335*fcf3ce44SJohn Forte (void) strcat(temp_path, sbuf); 3336*fcf3ce44SJohn Forte 3337*fcf3ce44SJohn Forte } 3338*fcf3ce44SJohn Forte /* 3339*fcf3ce44SJohn Forte * If we find a device on this loop in this box 3340*fcf3ce44SJohn Forte * update its status. 3341*fcf3ce44SJohn Forte */ 3342*fcf3ce44SJohn Forte if (state->ib_status.sel_id == select_id) { 3343*fcf3ce44SJohn Forte /* 3344*fcf3ce44SJohn Forte * Found a device on this loop in this box. 3345*fcf3ce44SJohn Forte * 3346*fcf3ce44SJohn Forte * Update state. 3347*fcf3ce44SJohn Forte */ 3348*fcf3ce44SJohn Forte (void) sprintf(state->g_disk_state.node_wwn_s, 3349*fcf3ce44SJohn Forte "%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x", 3350*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3351*fcf3ce44SJohn Forte sf_node_wwn[0], 3352*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3353*fcf3ce44SJohn Forte sf_node_wwn[1], 3354*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3355*fcf3ce44SJohn Forte sf_node_wwn[2], 3356*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3357*fcf3ce44SJohn Forte sf_node_wwn[3], 3358*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3359*fcf3ce44SJohn Forte sf_node_wwn[4], 3360*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3361*fcf3ce44SJohn Forte sf_node_wwn[5], 3362*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3363*fcf3ce44SJohn Forte sf_node_wwn[6], 3364*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3365*fcf3ce44SJohn Forte sf_node_wwn[7]); 3366*fcf3ce44SJohn Forte 3367*fcf3ce44SJohn Forte if (strstr(path, SCSI_VHCI) != NULL) { 3368*fcf3ce44SJohn Forte (void) g_ll_to_str(map_ptr->map.dev_addr[j].gfc_port_dev. 3369*fcf3ce44SJohn Forte priv_port.sf_node_wwn, wwnp); 3370*fcf3ce44SJohn Forte for (wwnlp = wwn_list; wwnlp != NULL; 3371*fcf3ce44SJohn Forte wwnlp = wwnlp->wwn_next) { 3372*fcf3ce44SJohn Forte if (strcmp(wwnlp->node_wwn_s, wwnp) == 0) { 3373*fcf3ce44SJohn Forte (void) strcpy(temp_path, wwnlp->physical_path); 3374*fcf3ce44SJohn Forte break; 3375*fcf3ce44SJohn Forte } 3376*fcf3ce44SJohn Forte } 3377*fcf3ce44SJohn Forte if (wwnlp == NULL) { 3378*fcf3ce44SJohn Forte (void) sprintf(sbuf, 3379*fcf3ce44SJohn Forte "g%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x:c,raw", 3380*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3381*fcf3ce44SJohn Forte sf_node_wwn[0], 3382*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3383*fcf3ce44SJohn Forte sf_node_wwn[1], 3384*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3385*fcf3ce44SJohn Forte sf_node_wwn[2], 3386*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3387*fcf3ce44SJohn Forte sf_node_wwn[3], 3388*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3389*fcf3ce44SJohn Forte sf_node_wwn[4], 3390*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3391*fcf3ce44SJohn Forte sf_node_wwn[5], 3392*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3393*fcf3ce44SJohn Forte sf_node_wwn[6], 3394*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.priv_port. 3395*fcf3ce44SJohn Forte sf_node_wwn[7]); 3396*fcf3ce44SJohn Forte (void) strcat(temp_path, sbuf); 3397*fcf3ce44SJohn Forte /* 3398*fcf3ce44SJohn Forte * check to make sure this is a valid path. 3399*fcf3ce44SJohn Forte * Paths may not always be created on the 3400*fcf3ce44SJohn Forte * host. So, we make a quick check. 3401*fcf3ce44SJohn Forte */ 3402*fcf3ce44SJohn Forte if (stat(temp_path, &stat_buf) == -1) { 3403*fcf3ce44SJohn Forte free_mp_dev_map(&map_mp); 3404*fcf3ce44SJohn Forte return (errno); 3405*fcf3ce44SJohn Forte } 3406*fcf3ce44SJohn Forte 3407*fcf3ce44SJohn Forte } 3408*fcf3ce44SJohn Forte } 3409*fcf3ce44SJohn Forte (void) strcpy(state->g_disk_state.physical_path, 3410*fcf3ce44SJohn Forte temp_path); 3411*fcf3ce44SJohn Forte 3412*fcf3ce44SJohn Forte 3413*fcf3ce44SJohn Forte /* Bad if WWN is all zeros. */ 3414*fcf3ce44SJohn Forte if (is_null_wwn(map_ptr->map.dev_addr[j]. 3415*fcf3ce44SJohn Forte gfc_port_dev.priv_port. 3416*fcf3ce44SJohn Forte sf_node_wwn)) { 3417*fcf3ce44SJohn Forte state->l_state_flag = L_INVALID_WWN; 3418*fcf3ce44SJohn Forte G_DPRINTF(" l_get_node_status: " 3419*fcf3ce44SJohn Forte "Disk state was " 3420*fcf3ce44SJohn Forte " Invalid WWN.\n"); 3421*fcf3ce44SJohn Forte (*found_flag)++; 3422*fcf3ce44SJohn Forte free_mp_dev_map(&map_mp); 3423*fcf3ce44SJohn Forte return (0); 3424*fcf3ce44SJohn Forte } 3425*fcf3ce44SJohn Forte 3426*fcf3ce44SJohn Forte /* get device status */ 3427*fcf3ce44SJohn Forte if (err = l_get_disk_status(temp_path, state, 3428*fcf3ce44SJohn Forte wwn_list, verbose)) { 3429*fcf3ce44SJohn Forte free_mp_dev_map(&map_mp); 3430*fcf3ce44SJohn Forte return (err); 3431*fcf3ce44SJohn Forte } 3432*fcf3ce44SJohn Forte /* 3433*fcf3ce44SJohn Forte * found device in map. Don't need to look 3434*fcf3ce44SJohn Forte * any further 3435*fcf3ce44SJohn Forte */ 3436*fcf3ce44SJohn Forte (*found_flag)++; 3437*fcf3ce44SJohn Forte free_mp_dev_map(&map_mp); 3438*fcf3ce44SJohn Forte return (0); 3439*fcf3ce44SJohn Forte } 3440*fcf3ce44SJohn Forte } /* for loop */ 3441*fcf3ce44SJohn Forte break; 3442*fcf3ce44SJohn Forte case FC_TOP_PUBLIC_LOOP: 3443*fcf3ce44SJohn Forte case FC_TOP_FABRIC: 3444*fcf3ce44SJohn Forte /* 3445*fcf3ce44SJohn Forte * Get a generic path to a device 3446*fcf3ce44SJohn Forte * This assumes the path looks something like this 3447*fcf3ce44SJohn Forte * /devices/sbus@1f,0/SUNW,socal@1,0/SUNW,sf@0,0/ses@wWWN,0:0 3448*fcf3ce44SJohn Forte * then creates a path that looks like 3449*fcf3ce44SJohn Forte * /devices/sbus@1f,0/SUNW,socal@1,0/SUNW,sf@0,0/ssd@ 3450*fcf3ce44SJohn Forte */ 3451*fcf3ce44SJohn Forte (void) strcpy(temp_path, path); 3452*fcf3ce44SJohn Forte if ((char_ptr = strrchr(temp_path, '/')) == NULL) { 3453*fcf3ce44SJohn Forte free_mp_dev_map(&map_mp); 3454*fcf3ce44SJohn Forte return (L_INVALID_PATH); 3455*fcf3ce44SJohn Forte } 3456*fcf3ce44SJohn Forte *char_ptr = '\0'; /* Terminate sting */ 3457*fcf3ce44SJohn Forte 3458*fcf3ce44SJohn Forte if (err = l_get_pid_from_path(path, &map_ptr->map, &path_pid)) { 3459*fcf3ce44SJohn Forte free_mp_dev_map(&map_mp); 3460*fcf3ce44SJohn Forte return (err); 3461*fcf3ce44SJohn Forte } 3462*fcf3ce44SJohn Forte 3463*fcf3ce44SJohn Forte /* Now append the ssd string */ 3464*fcf3ce44SJohn Forte (void) strcat(temp_path, SLSH_DRV_NAME_SSD); 3465*fcf3ce44SJohn Forte 3466*fcf3ce44SJohn Forte /* 3467*fcf3ce44SJohn Forte * Create complete path. 3468*fcf3ce44SJohn Forte * 3469*fcf3ce44SJohn Forte * Build entry ssd@WWN,0:c,raw 3470*fcf3ce44SJohn Forte * 3471*fcf3ce44SJohn Forte * First, search the map for a device with the area code and 3472*fcf3ce44SJohn Forte * domain as in 'path_pid'. 3473*fcf3ce44SJohn Forte */ 3474*fcf3ce44SJohn Forte for (j = 0; j < map_ptr->map.count; j++) { 3475*fcf3ce44SJohn Forte if (map_ptr->map.dev_addr[j].gfc_port_dev.pub_port. 3476*fcf3ce44SJohn Forte dev_dtype != DTYPE_ESI) { 3477*fcf3ce44SJohn Forte select_id = g_sf_alpa_to_switch[map_ptr->map. 3478*fcf3ce44SJohn Forte dev_addr[j].gfc_port_dev.pub_port.dev_did. 3479*fcf3ce44SJohn Forte port_id & 0xFF]; 3480*fcf3ce44SJohn Forte 3481*fcf3ce44SJohn Forte if (((map_ptr->map.dev_addr[j].gfc_port_dev. 3482*fcf3ce44SJohn Forte pub_port.dev_did.port_id & 3483*fcf3ce44SJohn Forte AREA_DOMAIN_ID) == 3484*fcf3ce44SJohn Forte (path_pid & AREA_DOMAIN_ID)) && 3485*fcf3ce44SJohn Forte (state->ib_status.sel_id == select_id)) { 3486*fcf3ce44SJohn Forte /* 3487*fcf3ce44SJohn Forte * Found the device. Update state. 3488*fcf3ce44SJohn Forte */ 3489*fcf3ce44SJohn Forte if (strstr(temp_path, SCSI_VHCI) == NULL) { 3490*fcf3ce44SJohn Forte (void) sprintf(sbuf, 3491*fcf3ce44SJohn Forte "w%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x,0:c,raw", 3492*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev. 3493*fcf3ce44SJohn Forte pub_port.dev_pwwn.raw_wwn[0], 3494*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev. 3495*fcf3ce44SJohn Forte pub_port.dev_pwwn.raw_wwn[1], 3496*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev. 3497*fcf3ce44SJohn Forte pub_port.dev_pwwn.raw_wwn[2], 3498*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev. 3499*fcf3ce44SJohn Forte pub_port.dev_pwwn.raw_wwn[3], 3500*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev. 3501*fcf3ce44SJohn Forte pub_port.dev_pwwn.raw_wwn[4], 3502*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev. 3503*fcf3ce44SJohn Forte pub_port.dev_pwwn.raw_wwn[5], 3504*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev. 3505*fcf3ce44SJohn Forte pub_port.dev_pwwn.raw_wwn[6], 3506*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev. 3507*fcf3ce44SJohn Forte pub_port.dev_pwwn.raw_wwn[7]); 3508*fcf3ce44SJohn Forte (void) strcat(temp_path, sbuf); 3509*fcf3ce44SJohn Forte 3510*fcf3ce44SJohn Forte /* 3511*fcf3ce44SJohn Forte * Paths for fabric cases may not always 3512*fcf3ce44SJohn Forte * be created on the host. So, we make a 3513*fcf3ce44SJohn Forte * quick check. 3514*fcf3ce44SJohn Forte */ 3515*fcf3ce44SJohn Forte if (stat(temp_path, &stat_buf) == -1) { 3516*fcf3ce44SJohn Forte free_mp_dev_map(&map_mp); 3517*fcf3ce44SJohn Forte return (errno); 3518*fcf3ce44SJohn Forte } 3519*fcf3ce44SJohn Forte 3520*fcf3ce44SJohn Forte (void) sprintf(state-> 3521*fcf3ce44SJohn Forte g_disk_state.node_wwn_s, 3522*fcf3ce44SJohn Forte "%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x", 3523*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev. 3524*fcf3ce44SJohn Forte pub_port.dev_nwwn.raw_wwn[0], 3525*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev. 3526*fcf3ce44SJohn Forte pub_port.dev_nwwn.raw_wwn[1], 3527*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev. 3528*fcf3ce44SJohn Forte pub_port.dev_nwwn.raw_wwn[2], 3529*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev. 3530*fcf3ce44SJohn Forte pub_port.dev_nwwn.raw_wwn[3], 3531*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev. 3532*fcf3ce44SJohn Forte pub_port.dev_nwwn.raw_wwn[4], 3533*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev. 3534*fcf3ce44SJohn Forte pub_port.dev_nwwn.raw_wwn[5], 3535*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev. 3536*fcf3ce44SJohn Forte pub_port.dev_nwwn.raw_wwn[6], 3537*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev. 3538*fcf3ce44SJohn Forte pub_port.dev_nwwn.raw_wwn[7]); 3539*fcf3ce44SJohn Forte 3540*fcf3ce44SJohn Forte } else { 3541*fcf3ce44SJohn Forte (void) g_ll_to_str(map_ptr->map.dev_addr[j].gfc_port_dev. 3542*fcf3ce44SJohn Forte priv_port.sf_node_wwn, wwnp); 3543*fcf3ce44SJohn Forte for (wwnlp = wwn_list; wwnlp != NULL; 3544*fcf3ce44SJohn Forte wwnlp = wwnlp->wwn_next) { 3545*fcf3ce44SJohn Forte if (strcmp(wwnlp->node_wwn_s, wwnp) == 0) { 3546*fcf3ce44SJohn Forte (void) strcpy(temp_path, wwnlp->physical_path); 3547*fcf3ce44SJohn Forte break; 3548*fcf3ce44SJohn Forte } 3549*fcf3ce44SJohn Forte } 3550*fcf3ce44SJohn Forte if (wwnlp == NULL) { 3551*fcf3ce44SJohn Forte (void) sprintf(sbuf, 3552*fcf3ce44SJohn Forte "w%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x,0:c,raw", 3553*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.pub_port. 3554*fcf3ce44SJohn Forte dev_nwwn.raw_wwn[0], 3555*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.pub_port. 3556*fcf3ce44SJohn Forte dev_nwwn.raw_wwn[1], 3557*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.pub_port. 3558*fcf3ce44SJohn Forte dev_nwwn.raw_wwn[2], 3559*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.pub_port. 3560*fcf3ce44SJohn Forte dev_nwwn.raw_wwn[3], 3561*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.pub_port. 3562*fcf3ce44SJohn Forte dev_nwwn.raw_wwn[4], 3563*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.pub_port. 3564*fcf3ce44SJohn Forte dev_nwwn.raw_wwn[5], 3565*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.pub_port. 3566*fcf3ce44SJohn Forte dev_nwwn.raw_wwn[6], 3567*fcf3ce44SJohn Forte map_ptr->map.dev_addr[j].gfc_port_dev.pub_port. 3568*fcf3ce44SJohn Forte dev_nwwn.raw_wwn[7]); 3569*fcf3ce44SJohn Forte (void) strcat(temp_path, sbuf); 3570*fcf3ce44SJohn Forte } 3571*fcf3ce44SJohn Forte } 3572*fcf3ce44SJohn Forte (void) strcpy(state->g_disk_state.physical_path, 3573*fcf3ce44SJohn Forte temp_path); 3574*fcf3ce44SJohn Forte 3575*fcf3ce44SJohn Forte /* Bad if WWN is all zeros. */ 3576*fcf3ce44SJohn Forte if (is_null_wwn(map_ptr->map. 3577*fcf3ce44SJohn Forte dev_addr[j].gfc_port_dev. 3578*fcf3ce44SJohn Forte pub_port.dev_nwwn. 3579*fcf3ce44SJohn Forte raw_wwn)) { 3580*fcf3ce44SJohn Forte state->l_state_flag = 3581*fcf3ce44SJohn Forte L_INVALID_WWN; 3582*fcf3ce44SJohn Forte G_DPRINTF( 3583*fcf3ce44SJohn Forte " l_get_node_status: " 3584*fcf3ce44SJohn Forte "Disk state was " 3585*fcf3ce44SJohn Forte " Invalid WWN.\n"); 3586*fcf3ce44SJohn Forte (*found_flag)++; 3587*fcf3ce44SJohn Forte free_mp_dev_map(&map_mp); 3588*fcf3ce44SJohn Forte return (0); 3589*fcf3ce44SJohn Forte } 3590*fcf3ce44SJohn Forte 3591*fcf3ce44SJohn Forte /* get device status */ 3592*fcf3ce44SJohn Forte if (err = l_get_disk_status(temp_path, 3593*fcf3ce44SJohn Forte state, wwn_list, verbose)) { 3594*fcf3ce44SJohn Forte free_mp_dev_map(&map_mp); 3595*fcf3ce44SJohn Forte return (err); 3596*fcf3ce44SJohn Forte } 3597*fcf3ce44SJohn Forte 3598*fcf3ce44SJohn Forte (*found_flag)++; 3599*fcf3ce44SJohn Forte free_mp_dev_map(&map_mp); 3600*fcf3ce44SJohn Forte return (0); 3601*fcf3ce44SJohn Forte } /* if select_id match */ 3602*fcf3ce44SJohn Forte } /* if !DTYPE_ESI */ 3603*fcf3ce44SJohn Forte } /* for loop */ 3604*fcf3ce44SJohn Forte break; 3605*fcf3ce44SJohn Forte case FC_TOP_PT_PT: 3606*fcf3ce44SJohn Forte free_mp_dev_map(&map_mp); 3607*fcf3ce44SJohn Forte return (L_PT_PT_FC_TOP_NOT_SUPPORTED); 3608*fcf3ce44SJohn Forte default: 3609*fcf3ce44SJohn Forte free_mp_dev_map(&map_mp); 3610*fcf3ce44SJohn Forte return (L_UNEXPECTED_FC_TOPOLOGY); 3611*fcf3ce44SJohn Forte } /* End of switch on port_topology */ 3612*fcf3ce44SJohn Forte 3613*fcf3ce44SJohn Forte } 3614*fcf3ce44SJohn Forte free_mp_dev_map(&map_mp); 3615*fcf3ce44SJohn Forte return (0); 3616*fcf3ce44SJohn Forte } 3617*fcf3ce44SJohn Forte 3618*fcf3ce44SJohn Forte 3619*fcf3ce44SJohn Forte /* 3620*fcf3ce44SJohn Forte * Get the individual drives status for the device specified by the index. 3621*fcf3ce44SJohn Forte * device at the path where the path is of the IB and updates the 3622*fcf3ce44SJohn Forte * g_disk_state_struct structure. 3623*fcf3ce44SJohn Forte * 3624*fcf3ce44SJohn Forte * If the disk's port is bypassed, it gets the 3625*fcf3ce44SJohn Forte * drive status such as node WWN from the second port. 3626*fcf3ce44SJohn Forte * 3627*fcf3ce44SJohn Forte * RETURNS: 3628*fcf3ce44SJohn Forte * 0 O.K. 3629*fcf3ce44SJohn Forte * non-zero otherwise 3630*fcf3ce44SJohn Forte */ 3631*fcf3ce44SJohn Forte int 3632*fcf3ce44SJohn Forte l_get_individual_state(char *path, 3633*fcf3ce44SJohn Forte struct l_disk_state_struct *state, Ib_state *ib_state, 3634*fcf3ce44SJohn Forte int front_flag, struct box_list_struct *box_list, 3635*fcf3ce44SJohn Forte struct wwn_list_struct *wwn_list, int verbose) 3636*fcf3ce44SJohn Forte { 3637*fcf3ce44SJohn Forte int found_flag = 0, elem_index = 0; 3638*fcf3ce44SJohn Forte int port_a_flag, err, j; 3639*fcf3ce44SJohn Forte struct dlist *seslist = NULL; 3640*fcf3ce44SJohn Forte Bp_elem_st bpf, bpr; 3641*fcf3ce44SJohn Forte hrtime_t start_time, end_time; 3642*fcf3ce44SJohn Forte 3643*fcf3ce44SJohn Forte if ((path == NULL) || (state == NULL) || 3644*fcf3ce44SJohn Forte (ib_state == NULL) || (box_list == NULL)) { 3645*fcf3ce44SJohn Forte return (L_INVALID_PATH_FORMAT); 3646*fcf3ce44SJohn Forte } 3647*fcf3ce44SJohn Forte 3648*fcf3ce44SJohn Forte start_time = gethrtime(); 3649*fcf3ce44SJohn Forte 3650*fcf3ce44SJohn Forte 3651*fcf3ce44SJohn Forte if ((state->ib_status.code != S_NOT_INSTALLED) && 3652*fcf3ce44SJohn Forte (state->ib_status.code != S_NOT_AVAILABLE)) { 3653*fcf3ce44SJohn Forte 3654*fcf3ce44SJohn Forte /* 3655*fcf3ce44SJohn Forte * Disk could have been bypassed on this loop. 3656*fcf3ce44SJohn Forte * Check the port state before l_state_flag 3657*fcf3ce44SJohn Forte * is set to L_INVALID_MAP. 3658*fcf3ce44SJohn Forte */ 3659*fcf3ce44SJohn Forte for (j = 0; 3660*fcf3ce44SJohn Forte j < (int)ib_state->config.enc_num_elem; 3661*fcf3ce44SJohn Forte j++) { 3662*fcf3ce44SJohn Forte elem_index++; 3663*fcf3ce44SJohn Forte if (ib_state->config.type_hdr[j].type == 3664*fcf3ce44SJohn Forte ELM_TYP_BP) 3665*fcf3ce44SJohn Forte break; 3666*fcf3ce44SJohn Forte elem_index += 3667*fcf3ce44SJohn Forte ib_state->config.type_hdr[j].num; 3668*fcf3ce44SJohn Forte } 3669*fcf3ce44SJohn Forte 3670*fcf3ce44SJohn Forte /* 3671*fcf3ce44SJohn Forte * check if port A & B of backplane are bypassed. 3672*fcf3ce44SJohn Forte * If so, do not bother. 3673*fcf3ce44SJohn Forte */ 3674*fcf3ce44SJohn Forte if (front_flag) { 3675*fcf3ce44SJohn Forte bcopy((const void *) 3676*fcf3ce44SJohn Forte &(ib_state->p2_s.element[elem_index]), 3677*fcf3ce44SJohn Forte (void *)&bpf, sizeof (bpf)); 3678*fcf3ce44SJohn Forte 3679*fcf3ce44SJohn Forte if ((bpf.byp_a_enabled || bpf.en_bypass_a) && 3680*fcf3ce44SJohn Forte (bpf.byp_b_enabled || bpf.en_bypass_b)) 3681*fcf3ce44SJohn Forte return (0); 3682*fcf3ce44SJohn Forte } else { 3683*fcf3ce44SJohn Forte /* if disk is in rear slot */ 3684*fcf3ce44SJohn Forte bcopy((const void *) 3685*fcf3ce44SJohn Forte &(ib_state->p2_s.element[elem_index+1]), 3686*fcf3ce44SJohn Forte (void *)&bpr, sizeof (bpr)); 3687*fcf3ce44SJohn Forte 3688*fcf3ce44SJohn Forte if ((bpr.byp_b_enabled || bpr.en_bypass_b) && 3689*fcf3ce44SJohn Forte (bpr.byp_a_enabled || bpr.en_bypass_a)) 3690*fcf3ce44SJohn Forte return (0); 3691*fcf3ce44SJohn Forte } 3692*fcf3ce44SJohn Forte 3693*fcf3ce44SJohn Forte if ((err = l_get_node_status(path, state, 3694*fcf3ce44SJohn Forte &found_flag, wwn_list, verbose)) != 0) 3695*fcf3ce44SJohn Forte return (err); 3696*fcf3ce44SJohn Forte 3697*fcf3ce44SJohn Forte if (!found_flag) { 3698*fcf3ce44SJohn Forte if ((err = l_get_allses(path, box_list, 3699*fcf3ce44SJohn Forte &seslist, 0)) != 0) { 3700*fcf3ce44SJohn Forte return (err); 3701*fcf3ce44SJohn Forte } 3702*fcf3ce44SJohn Forte 3703*fcf3ce44SJohn Forte if (err = l_get_port(path, &port_a_flag, verbose)) 3704*fcf3ce44SJohn Forte goto done; 3705*fcf3ce44SJohn Forte 3706*fcf3ce44SJohn Forte if (port_a_flag) { 3707*fcf3ce44SJohn Forte if ((state->ib_status.bypass_a_en && 3708*fcf3ce44SJohn Forte !(state->ib_status.bypass_b_en)) || 3709*fcf3ce44SJohn Forte !(state->ib_status.bypass_b_en)) { 3710*fcf3ce44SJohn Forte while (seslist != NULL && !found_flag) { 3711*fcf3ce44SJohn Forte if (err = l_get_port( 3712*fcf3ce44SJohn Forte seslist->dev_path, 3713*fcf3ce44SJohn Forte &port_a_flag, verbose)) { 3714*fcf3ce44SJohn Forte goto done; 3715*fcf3ce44SJohn Forte } 3716*fcf3ce44SJohn Forte if ((strcmp(seslist->dev_path, 3717*fcf3ce44SJohn Forte path) != 0) && 3718*fcf3ce44SJohn Forte !port_a_flag) { 3719*fcf3ce44SJohn Forte *path = NULL; 3720*fcf3ce44SJohn Forte (void) strcpy(path, 3721*fcf3ce44SJohn Forte seslist->dev_path); 3722*fcf3ce44SJohn Forte if (err = 3723*fcf3ce44SJohn Forte l_get_node_status(path, 3724*fcf3ce44SJohn Forte state, &found_flag, 3725*fcf3ce44SJohn Forte wwn_list, verbose)) { 3726*fcf3ce44SJohn Forte goto done; 3727*fcf3ce44SJohn Forte } 3728*fcf3ce44SJohn Forte } 3729*fcf3ce44SJohn Forte seslist = seslist->next; 3730*fcf3ce44SJohn Forte } 3731*fcf3ce44SJohn Forte } 3732*fcf3ce44SJohn Forte } else { 3733*fcf3ce44SJohn Forte if ((state->ib_status.bypass_b_en && 3734*fcf3ce44SJohn Forte !(state->ib_status.bypass_a_en)) || 3735*fcf3ce44SJohn Forte !(state->ib_status.bypass_a_en)) { 3736*fcf3ce44SJohn Forte while (seslist != NULL && !found_flag) { 3737*fcf3ce44SJohn Forte if (err = l_get_port( 3738*fcf3ce44SJohn Forte seslist->dev_path, 3739*fcf3ce44SJohn Forte &port_a_flag, verbose)) { 3740*fcf3ce44SJohn Forte goto done; 3741*fcf3ce44SJohn Forte } 3742*fcf3ce44SJohn Forte if ((strcmp(seslist->dev_path, 3743*fcf3ce44SJohn Forte path) != 0) && port_a_flag) { 3744*fcf3ce44SJohn Forte *path = NULL; 3745*fcf3ce44SJohn Forte (void) strcpy(path, 3746*fcf3ce44SJohn Forte seslist->dev_path); 3747*fcf3ce44SJohn Forte if (err = 3748*fcf3ce44SJohn Forte l_get_node_status(path, 3749*fcf3ce44SJohn Forte state, &found_flag, 3750*fcf3ce44SJohn Forte wwn_list, verbose)) { 3751*fcf3ce44SJohn Forte goto done; 3752*fcf3ce44SJohn Forte } 3753*fcf3ce44SJohn Forte } 3754*fcf3ce44SJohn Forte seslist = seslist->next; 3755*fcf3ce44SJohn Forte } 3756*fcf3ce44SJohn Forte } 3757*fcf3ce44SJohn Forte } 3758*fcf3ce44SJohn Forte if (!found_flag) { 3759*fcf3ce44SJohn Forte state->l_state_flag = L_INVALID_MAP; 3760*fcf3ce44SJohn Forte G_DPRINTF(" l_get_individual_state: " 3761*fcf3ce44SJohn Forte "Disk state was " 3762*fcf3ce44SJohn Forte "Not in map.\n"); 3763*fcf3ce44SJohn Forte } else { 3764*fcf3ce44SJohn Forte G_DPRINTF(" l_get_individual_state: " 3765*fcf3ce44SJohn Forte "Disk was found in the map.\n"); 3766*fcf3ce44SJohn Forte } 3767*fcf3ce44SJohn Forte 3768*fcf3ce44SJohn Forte if (seslist != NULL) 3769*fcf3ce44SJohn Forte (void) g_free_multipath(seslist); 3770*fcf3ce44SJohn Forte 3771*fcf3ce44SJohn Forte } 3772*fcf3ce44SJohn Forte 3773*fcf3ce44SJohn Forte } else { 3774*fcf3ce44SJohn Forte G_DPRINTF(" l_get_individual_state: Disk state was %s.\n", 3775*fcf3ce44SJohn Forte (state->ib_status.code == S_NOT_INSTALLED) ? 3776*fcf3ce44SJohn Forte "Not Installed" : "Not Available"); 3777*fcf3ce44SJohn Forte } 3778*fcf3ce44SJohn Forte 3779*fcf3ce44SJohn Forte if (getenv("_LUX_T_DEBUG") != NULL) { 3780*fcf3ce44SJohn Forte end_time = gethrtime(); 3781*fcf3ce44SJohn Forte (void) fprintf(stdout, " l_get_individual_state:" 3782*fcf3ce44SJohn Forte "\tTime = %lld millisec\n", 3783*fcf3ce44SJohn Forte (end_time - start_time)/1000000); 3784*fcf3ce44SJohn Forte } 3785*fcf3ce44SJohn Forte 3786*fcf3ce44SJohn Forte return (0); 3787*fcf3ce44SJohn Forte done: 3788*fcf3ce44SJohn Forte (void) g_free_multipath(seslist); 3789*fcf3ce44SJohn Forte return (err); 3790*fcf3ce44SJohn Forte } 3791*fcf3ce44SJohn Forte 3792*fcf3ce44SJohn Forte 3793*fcf3ce44SJohn Forte 3794*fcf3ce44SJohn Forte /* 3795*fcf3ce44SJohn Forte * Get the global state of the photon. 3796*fcf3ce44SJohn Forte * 3797*fcf3ce44SJohn Forte * INPUT: 3798*fcf3ce44SJohn Forte * path and verbose flag 3799*fcf3ce44SJohn Forte * 3800*fcf3ce44SJohn Forte * "path" must be of the ses driver. 3801*fcf3ce44SJohn Forte * e.g. 3802*fcf3ce44SJohn Forte * /devices/sbus@1f,0/SUNW,socal@1,0/SUNW,sf@0,0/ses@e,0:0 3803*fcf3ce44SJohn Forte * or 3804*fcf3ce44SJohn Forte * /devices/sbus@1f,0/SUNW,socal@1,0/SUNW,sf@0,0/ses@WWN,0:0 3805*fcf3ce44SJohn Forte * 3806*fcf3ce44SJohn Forte * OUTPUT: 3807*fcf3ce44SJohn Forte * The struct l_state (which was passed in) has the status info 3808*fcf3ce44SJohn Forte * 3809*fcf3ce44SJohn Forte * RETURNS: 3810*fcf3ce44SJohn Forte * 0 O.K. 3811*fcf3ce44SJohn Forte * non-zero otherwise 3812*fcf3ce44SJohn Forte */ 3813*fcf3ce44SJohn Forte int 3814*fcf3ce44SJohn Forte l_get_status(char *path, struct l_state_struct *l_state, int verbose) 3815*fcf3ce44SJohn Forte { 3816*fcf3ce44SJohn Forte int err = 0, i, count; 3817*fcf3ce44SJohn Forte L_inquiry inq; 3818*fcf3ce44SJohn Forte uchar_t node_wwn[WWN_SIZE], port_wwn[WWN_SIZE]; 3819*fcf3ce44SJohn Forte int al_pa, found_front, found_rear, front_flag, enc_type; 3820*fcf3ce44SJohn Forte char ses_path_front[MAXPATHLEN]; 3821*fcf3ce44SJohn Forte char ses_path_rear[MAXPATHLEN]; 3822*fcf3ce44SJohn Forte Box_list *b_list = NULL; 3823*fcf3ce44SJohn Forte Box_list *o_list = NULL; 3824*fcf3ce44SJohn Forte char node_wwn_s[(WWN_SIZE*2)+1]; 3825*fcf3ce44SJohn Forte uint_t select_id; 3826*fcf3ce44SJohn Forte hrtime_t start_time, end_time; 3827*fcf3ce44SJohn Forte WWN_list *wwn_list = NULL; 3828*fcf3ce44SJohn Forte 3829*fcf3ce44SJohn Forte if ((path == NULL) || (l_state == NULL)) { 3830*fcf3ce44SJohn Forte return (L_INVALID_PATH_FORMAT); 3831*fcf3ce44SJohn Forte } 3832*fcf3ce44SJohn Forte 3833*fcf3ce44SJohn Forte start_time = gethrtime(); 3834*fcf3ce44SJohn Forte 3835*fcf3ce44SJohn Forte G_DPRINTF(" l_get_status: Get Status for enclosure at: " 3836*fcf3ce44SJohn Forte " %s\n", path); 3837*fcf3ce44SJohn Forte 3838*fcf3ce44SJohn Forte /* initialization */ 3839*fcf3ce44SJohn Forte (void) memset(l_state, 0, sizeof (struct l_state_struct)); 3840*fcf3ce44SJohn Forte 3841*fcf3ce44SJohn Forte if (err = g_get_inquiry(path, &inq)) { 3842*fcf3ce44SJohn Forte return (err); 3843*fcf3ce44SJohn Forte } 3844*fcf3ce44SJohn Forte if ((strstr((char *)inq.inq_pid, ENCLOSURE_PROD_ID) == 0) && 3845*fcf3ce44SJohn Forte (!(strncmp((char *)inq.inq_vid, "SUN ", 3846*fcf3ce44SJohn Forte sizeof (inq.inq_vid)) && 3847*fcf3ce44SJohn Forte ((inq.inq_dtype & DTYPE_MASK) == DTYPE_ESI)))) { 3848*fcf3ce44SJohn Forte return (L_ENCL_INVALID_PATH); 3849*fcf3ce44SJohn Forte } 3850*fcf3ce44SJohn Forte 3851*fcf3ce44SJohn Forte (void) strncpy((char *)l_state->ib_tbl.enclosure_name, 3852*fcf3ce44SJohn Forte (char *)inq.inq_box_name, sizeof (inq.inq_box_name)); 3853*fcf3ce44SJohn Forte 3854*fcf3ce44SJohn Forte /* 3855*fcf3ce44SJohn Forte * Get all of the IB Receive Diagnostic pages. 3856*fcf3ce44SJohn Forte */ 3857*fcf3ce44SJohn Forte if (err = l_get_ib_status(path, l_state, verbose)) { 3858*fcf3ce44SJohn Forte return (err); 3859*fcf3ce44SJohn Forte } 3860*fcf3ce44SJohn Forte 3861*fcf3ce44SJohn Forte /* 3862*fcf3ce44SJohn Forte * Now get the individual devices information from 3863*fcf3ce44SJohn Forte * the device itself. 3864*fcf3ce44SJohn Forte * 3865*fcf3ce44SJohn Forte * May need to use multiple paths to get to the 3866*fcf3ce44SJohn Forte * front and rear drives in the box. 3867*fcf3ce44SJohn Forte * If the loop is split some drives may not even be available 3868*fcf3ce44SJohn Forte * from this host. 3869*fcf3ce44SJohn Forte * 3870*fcf3ce44SJohn Forte * The way this works is in the select ID the front disks 3871*fcf3ce44SJohn Forte * are accessed via the IB with the bit 4 = 0 3872*fcf3ce44SJohn Forte * and the rear disks by the IB with bit 4 = 1. 3873*fcf3ce44SJohn Forte * 3874*fcf3ce44SJohn Forte * First get device map from fc nexus driver for this loop. 3875*fcf3ce44SJohn Forte */ 3876*fcf3ce44SJohn Forte /* 3877*fcf3ce44SJohn Forte * Get the boxes node WWN & al_pa for this path. 3878*fcf3ce44SJohn Forte */ 3879*fcf3ce44SJohn Forte if (err = g_get_wwn(path, port_wwn, node_wwn, &al_pa, verbose)) { 3880*fcf3ce44SJohn Forte return (err); 3881*fcf3ce44SJohn Forte } 3882*fcf3ce44SJohn Forte if (err = l_get_box_list(&o_list, verbose)) { 3883*fcf3ce44SJohn Forte (void) l_free_box_list(&o_list); 3884*fcf3ce44SJohn Forte return (err); /* Failure */ 3885*fcf3ce44SJohn Forte } 3886*fcf3ce44SJohn Forte 3887*fcf3ce44SJohn Forte found_front = found_rear = 0; 3888*fcf3ce44SJohn Forte for (i = 0; i < WWN_SIZE; i++) { 3889*fcf3ce44SJohn Forte (void) sprintf(&node_wwn_s[i << 1], "%02x", node_wwn[i]); 3890*fcf3ce44SJohn Forte } 3891*fcf3ce44SJohn Forte 3892*fcf3ce44SJohn Forte /* 3893*fcf3ce44SJohn Forte * The al_pa (or pa) can be 24 bits in size for fabric loops. 3894*fcf3ce44SJohn Forte * But we will take only the low order byte to get the select_id. 3895*fcf3ce44SJohn Forte * Private loops have al_pa which is only a byte in size. 3896*fcf3ce44SJohn Forte */ 3897*fcf3ce44SJohn Forte select_id = g_sf_alpa_to_switch[al_pa & 0xFF]; 3898*fcf3ce44SJohn Forte l_state->ib_tbl.box_id = (select_id & BOX_ID_MASK) >> 5; 3899*fcf3ce44SJohn Forte 3900*fcf3ce44SJohn Forte G_DPRINTF(" l_get_status: Using this select_id 0x%x " 3901*fcf3ce44SJohn Forte "and node WWN %s\n", 3902*fcf3ce44SJohn Forte select_id, node_wwn_s); 3903*fcf3ce44SJohn Forte 3904*fcf3ce44SJohn Forte if (strstr(path, SCSI_VHCI) != NULL) { 3905*fcf3ce44SJohn Forte /* there is no way to obtain all the al_pa with */ 3906*fcf3ce44SJohn Forte /* current implementation. assume both front */ 3907*fcf3ce44SJohn Forte /* and rear. need changes later on. */ 3908*fcf3ce44SJohn Forte found_rear = 1; 3909*fcf3ce44SJohn Forte found_front = 1; 3910*fcf3ce44SJohn Forte (void) strcpy(ses_path_rear, path); 3911*fcf3ce44SJohn Forte (void) strcpy(ses_path_front, path); 3912*fcf3ce44SJohn Forte } else { 3913*fcf3ce44SJohn Forte 3914*fcf3ce44SJohn Forte if (select_id & ALT_BOX_ID) { 3915*fcf3ce44SJohn Forte found_rear = 1; 3916*fcf3ce44SJohn Forte (void) strcpy(ses_path_rear, path); 3917*fcf3ce44SJohn Forte b_list = o_list; 3918*fcf3ce44SJohn Forte while (b_list) { 3919*fcf3ce44SJohn Forte if (strcmp(b_list->b_node_wwn_s, node_wwn_s) == 0) { 3920*fcf3ce44SJohn Forte if (err = g_get_wwn(b_list->b_physical_path, 3921*fcf3ce44SJohn Forte port_wwn, node_wwn, 3922*fcf3ce44SJohn Forte &al_pa, verbose)) { 3923*fcf3ce44SJohn Forte (void) l_free_box_list(&o_list); 3924*fcf3ce44SJohn Forte return (err); 3925*fcf3ce44SJohn Forte } 3926*fcf3ce44SJohn Forte 3927*fcf3ce44SJohn Forte /* Take the low order byte of al_pa */ 3928*fcf3ce44SJohn Forte select_id = g_sf_alpa_to_switch[al_pa & 0xFF]; 3929*fcf3ce44SJohn Forte if (!(select_id & ALT_BOX_ID)) { 3930*fcf3ce44SJohn Forte (void) strcpy(ses_path_front, 3931*fcf3ce44SJohn Forte b_list->b_physical_path); 3932*fcf3ce44SJohn Forte found_front = 1; 3933*fcf3ce44SJohn Forte break; 3934*fcf3ce44SJohn Forte } 3935*fcf3ce44SJohn Forte } 3936*fcf3ce44SJohn Forte b_list = b_list->box_next; 3937*fcf3ce44SJohn Forte } 3938*fcf3ce44SJohn Forte } else { 3939*fcf3ce44SJohn Forte (void) strcpy(ses_path_front, path); 3940*fcf3ce44SJohn Forte found_front = 1; 3941*fcf3ce44SJohn Forte b_list = o_list; 3942*fcf3ce44SJohn Forte while (b_list) { 3943*fcf3ce44SJohn Forte if (strcmp(b_list->b_node_wwn_s, node_wwn_s) == 0) { 3944*fcf3ce44SJohn Forte if (err = g_get_wwn(b_list->b_physical_path, 3945*fcf3ce44SJohn Forte port_wwn, node_wwn, 3946*fcf3ce44SJohn Forte &al_pa, verbose)) { 3947*fcf3ce44SJohn Forte (void) l_free_box_list(&o_list); 3948*fcf3ce44SJohn Forte return (err); 3949*fcf3ce44SJohn Forte } 3950*fcf3ce44SJohn Forte select_id = g_sf_alpa_to_switch[al_pa & 0xFF]; 3951*fcf3ce44SJohn Forte if (select_id & ALT_BOX_ID) { 3952*fcf3ce44SJohn Forte (void) strcpy(ses_path_rear, 3953*fcf3ce44SJohn Forte b_list->b_physical_path); 3954*fcf3ce44SJohn Forte found_rear = 1; 3955*fcf3ce44SJohn Forte break; 3956*fcf3ce44SJohn Forte } 3957*fcf3ce44SJohn Forte } 3958*fcf3ce44SJohn Forte b_list = b_list->box_next; 3959*fcf3ce44SJohn Forte } 3960*fcf3ce44SJohn Forte } 3961*fcf3ce44SJohn Forte } 3962*fcf3ce44SJohn Forte 3963*fcf3ce44SJohn Forte if (getenv("_LUX_G_DEBUG") != NULL) { 3964*fcf3ce44SJohn Forte if (!found_front) { 3965*fcf3ce44SJohn Forte (void) printf("l_get_status: Loop to front disks not found.\n"); 3966*fcf3ce44SJohn Forte } 3967*fcf3ce44SJohn Forte if (!found_rear) { 3968*fcf3ce44SJohn Forte (void) printf("l_get_status: Loop to rear disks not found.\n"); 3969*fcf3ce44SJohn Forte } 3970*fcf3ce44SJohn Forte } 3971*fcf3ce44SJohn Forte 3972*fcf3ce44SJohn Forte /* 3973*fcf3ce44SJohn Forte * Get path to all the FC disk and tape devices. 3974*fcf3ce44SJohn Forte * 3975*fcf3ce44SJohn Forte * I get this now and pass down for performance 3976*fcf3ce44SJohn Forte * reasons. 3977*fcf3ce44SJohn Forte * If for some reason the list can become invalid, 3978*fcf3ce44SJohn Forte * i.e. device being offlined, then the list 3979*fcf3ce44SJohn Forte * must be re-gotten. 3980*fcf3ce44SJohn Forte */ 3981*fcf3ce44SJohn Forte if (err = g_get_wwn_list(&wwn_list, verbose)) { 3982*fcf3ce44SJohn Forte return (err); /* Failure */ 3983*fcf3ce44SJohn Forte } 3984*fcf3ce44SJohn Forte 3985*fcf3ce44SJohn Forte enc_type = l_get_enc_type(inq); 3986*fcf3ce44SJohn Forte if (found_front) { 3987*fcf3ce44SJohn Forte front_flag = 1; 3988*fcf3ce44SJohn Forte for (i = 0, count = 0; i < l_state->total_num_drv/2; 3989*fcf3ce44SJohn Forte count++, i++) { 3990*fcf3ce44SJohn Forte if (enc_type == DAK_ENC_TYPE) { 3991*fcf3ce44SJohn Forte G_DPRINTF(" l_get_status: Getting individual" 3992*fcf3ce44SJohn Forte " State for disk in slot %d\n", count); 3993*fcf3ce44SJohn Forte } else { 3994*fcf3ce44SJohn Forte G_DPRINTF(" l_get_status: Getting individual" 3995*fcf3ce44SJohn Forte " State for front disk in slot %d\n", i); 3996*fcf3ce44SJohn Forte } 3997*fcf3ce44SJohn Forte if (err = l_get_individual_state(ses_path_front, 3998*fcf3ce44SJohn Forte (struct l_disk_state_struct *)&l_state->drv_front[i], 3999*fcf3ce44SJohn Forte &l_state->ib_tbl, front_flag, o_list, 4000*fcf3ce44SJohn Forte wwn_list, verbose)) { 4001*fcf3ce44SJohn Forte (void) l_free_box_list(&o_list); 4002*fcf3ce44SJohn Forte (void) g_free_wwn_list(&wwn_list); 4003*fcf3ce44SJohn Forte return (err); 4004*fcf3ce44SJohn Forte } 4005*fcf3ce44SJohn Forte } 4006*fcf3ce44SJohn Forte } else { 4007*fcf3ce44SJohn Forte /* Set to loop not accessable. */ 4008*fcf3ce44SJohn Forte for (i = 0; i < l_state->total_num_drv/2; i++) { 4009*fcf3ce44SJohn Forte l_state->drv_front[i].l_state_flag = L_NO_LOOP; 4010*fcf3ce44SJohn Forte } 4011*fcf3ce44SJohn Forte } 4012*fcf3ce44SJohn Forte /* 4013*fcf3ce44SJohn Forte * For Daktari's, disk 0-5 information are located in the 4014*fcf3ce44SJohn Forte * l_state->drv_front array 4015*fcf3ce44SJohn Forte * For Daktari's, disk 6-11 information are located in the 4016*fcf3ce44SJohn Forte * l_state->drv_rear array 4017*fcf3ce44SJohn Forte * 4018*fcf3ce44SJohn Forte * For this reason, on daktari's, I ignore the found_front and 4019*fcf3ce44SJohn Forte * found_rear flags and check both the drv_front and drv_rear 4020*fcf3ce44SJohn Forte */ 4021*fcf3ce44SJohn Forte 4022*fcf3ce44SJohn Forte if (enc_type == DAK_ENC_TYPE && found_front) { 4023*fcf3ce44SJohn Forte front_flag = 1; 4024*fcf3ce44SJohn Forte for (i = 0; i < l_state->total_num_drv/2; i++, count++) { 4025*fcf3ce44SJohn Forte G_DPRINTF(" l_get_status: Getting individual" 4026*fcf3ce44SJohn Forte " State for disk in slot %d\n", count); 4027*fcf3ce44SJohn Forte if (err = l_get_individual_state(ses_path_front, 4028*fcf3ce44SJohn Forte (struct l_disk_state_struct *)&l_state->drv_rear[i], 4029*fcf3ce44SJohn Forte &l_state->ib_tbl, front_flag, o_list, 4030*fcf3ce44SJohn Forte wwn_list, verbose)) { 4031*fcf3ce44SJohn Forte (void) l_free_box_list(&o_list); 4032*fcf3ce44SJohn Forte (void) g_free_wwn_list(&wwn_list); 4033*fcf3ce44SJohn Forte return (err); 4034*fcf3ce44SJohn Forte } 4035*fcf3ce44SJohn Forte } 4036*fcf3ce44SJohn Forte } else if (enc_type != DAK_ENC_TYPE && found_rear) { 4037*fcf3ce44SJohn Forte for (i = 0; i < l_state->total_num_drv/2; i++, count++) { 4038*fcf3ce44SJohn Forte G_DPRINTF(" l_get_status: Getting individual" 4039*fcf3ce44SJohn Forte " State for rear disk in slot %d\n", i); 4040*fcf3ce44SJohn Forte if (err = l_get_individual_state(ses_path_rear, 4041*fcf3ce44SJohn Forte (struct l_disk_state_struct *)&l_state->drv_rear[i], 4042*fcf3ce44SJohn Forte &l_state->ib_tbl, front_flag, o_list, 4043*fcf3ce44SJohn Forte wwn_list, verbose)) { 4044*fcf3ce44SJohn Forte (void) l_free_box_list(&o_list); 4045*fcf3ce44SJohn Forte (void) g_free_wwn_list(&wwn_list); 4046*fcf3ce44SJohn Forte return (err); 4047*fcf3ce44SJohn Forte } 4048*fcf3ce44SJohn Forte } 4049*fcf3ce44SJohn Forte } else if (enc_type != DAK_ENC_TYPE) { 4050*fcf3ce44SJohn Forte /* Set to loop not accessable. */ 4051*fcf3ce44SJohn Forte for (i = 0; i < l_state->total_num_drv/2; i++) { 4052*fcf3ce44SJohn Forte l_state->drv_rear[i].l_state_flag = L_NO_LOOP; 4053*fcf3ce44SJohn Forte } 4054*fcf3ce44SJohn Forte } 4055*fcf3ce44SJohn Forte 4056*fcf3ce44SJohn Forte (void) l_free_box_list(&o_list); 4057*fcf3ce44SJohn Forte (void) g_free_wwn_list(&wwn_list); 4058*fcf3ce44SJohn Forte if (getenv("_LUX_T_DEBUG") != NULL) { 4059*fcf3ce44SJohn Forte end_time = gethrtime(); 4060*fcf3ce44SJohn Forte (void) fprintf(stdout, " l_get_status: " 4061*fcf3ce44SJohn Forte "Time = %lld millisec\n", 4062*fcf3ce44SJohn Forte (end_time - start_time)/1000000); 4063*fcf3ce44SJohn Forte } 4064*fcf3ce44SJohn Forte 4065*fcf3ce44SJohn Forte return (0); 4066*fcf3ce44SJohn Forte } 4067*fcf3ce44SJohn Forte 4068*fcf3ce44SJohn Forte 4069*fcf3ce44SJohn Forte 4070*fcf3ce44SJohn Forte /* 4071*fcf3ce44SJohn Forte * Check the SENA file for validity: 4072*fcf3ce44SJohn Forte * - verify the size is that of 3 proms worth of text. 4073*fcf3ce44SJohn Forte * - verify PROM_MAGIC. 4074*fcf3ce44SJohn Forte * - verify (and print) the date. 4075*fcf3ce44SJohn Forte * - verify the checksum. 4076*fcf3ce44SJohn Forte * - verify the WWN == 0. 4077*fcf3ce44SJohn Forte * Since this requires reading the entire file, do it now and pass a pointer 4078*fcf3ce44SJohn Forte * to the allocated buffer back to the calling routine (which is responsible 4079*fcf3ce44SJohn Forte * for freeing it). If the buffer is not allocated it will be NULL. 4080*fcf3ce44SJohn Forte * 4081*fcf3ce44SJohn Forte * RETURNS: 4082*fcf3ce44SJohn Forte * 0 O.K. 4083*fcf3ce44SJohn Forte * non-zero otherwise 4084*fcf3ce44SJohn Forte */ 4085*fcf3ce44SJohn Forte 4086*fcf3ce44SJohn Forte static int 4087*fcf3ce44SJohn Forte check_file(int fd, int verbose, uchar_t **buf_ptr, int dl_info_offset) 4088*fcf3ce44SJohn Forte { 4089*fcf3ce44SJohn Forte struct exec the_exec; 4090*fcf3ce44SJohn Forte int temp, i, j, *p, size, *start; 4091*fcf3ce44SJohn Forte uchar_t *buf; 4092*fcf3ce44SJohn Forte char *date_str; 4093*fcf3ce44SJohn Forte struct dl_info *dl_info; 4094*fcf3ce44SJohn Forte 4095*fcf3ce44SJohn Forte *buf_ptr = NULL; 4096*fcf3ce44SJohn Forte 4097*fcf3ce44SJohn Forte /* read exec header */ 4098*fcf3ce44SJohn Forte if (lseek(fd, 0, SEEK_SET) == -1) 4099*fcf3ce44SJohn Forte return (errno); 4100*fcf3ce44SJohn Forte if ((temp = read(fd, (char *)&the_exec, sizeof (the_exec))) == -1) { 4101*fcf3ce44SJohn Forte return (L_DWNLD_READ_HEADER_FAIL); 4102*fcf3ce44SJohn Forte } 4103*fcf3ce44SJohn Forte if (temp != sizeof (the_exec)) { 4104*fcf3ce44SJohn Forte return (L_DWNLD_READ_INCORRECT_BYTES); 4105*fcf3ce44SJohn Forte } 4106*fcf3ce44SJohn Forte 4107*fcf3ce44SJohn Forte if (the_exec.a_text != PROMSIZE) { 4108*fcf3ce44SJohn Forte return (L_DWNLD_INVALID_TEXT_SIZE); 4109*fcf3ce44SJohn Forte } 4110*fcf3ce44SJohn Forte 4111*fcf3ce44SJohn Forte if (!(buf = (uchar_t *)g_zalloc(PROMSIZE))) 4112*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 4113*fcf3ce44SJohn Forte 4114*fcf3ce44SJohn Forte if ((temp = read(fd, buf, PROMSIZE)) == -1) { 4115*fcf3ce44SJohn Forte return (L_DWNLD_READ_ERROR); 4116*fcf3ce44SJohn Forte } 4117*fcf3ce44SJohn Forte 4118*fcf3ce44SJohn Forte if (temp != PROMSIZE) { 4119*fcf3ce44SJohn Forte return (L_DWNLD_READ_INCORRECT_BYTES); 4120*fcf3ce44SJohn Forte } 4121*fcf3ce44SJohn Forte 4122*fcf3ce44SJohn Forte 4123*fcf3ce44SJohn Forte 4124*fcf3ce44SJohn Forte /* check the IB firmware MAGIC */ 4125*fcf3ce44SJohn Forte dl_info = (struct dl_info *)(unsigned long)(buf + dl_info_offset); 4126*fcf3ce44SJohn Forte if (dl_info->magic != PROM_MAGIC) { 4127*fcf3ce44SJohn Forte return (L_DWNLD_BAD_FRMWARE); 4128*fcf3ce44SJohn Forte } 4129*fcf3ce44SJohn Forte 4130*fcf3ce44SJohn Forte /* 4131*fcf3ce44SJohn Forte * Get the date 4132*fcf3ce44SJohn Forte */ 4133*fcf3ce44SJohn Forte 4134*fcf3ce44SJohn Forte date_str = ctime(&dl_info->datecode); 4135*fcf3ce44SJohn Forte 4136*fcf3ce44SJohn Forte if (verbose) { 4137*fcf3ce44SJohn Forte (void) fprintf(stdout, 4138*fcf3ce44SJohn Forte MSGSTR(9050, " IB Prom Date: %s"), 4139*fcf3ce44SJohn Forte date_str); 4140*fcf3ce44SJohn Forte } 4141*fcf3ce44SJohn Forte 4142*fcf3ce44SJohn Forte /* 4143*fcf3ce44SJohn Forte * verify checksum 4144*fcf3ce44SJohn Forte */ 4145*fcf3ce44SJohn Forte 4146*fcf3ce44SJohn Forte if (dl_info_offset == FPM_DL_INFO) { 4147*fcf3ce44SJohn Forte start = (int *)(long)(buf + FPM_OFFSET); 4148*fcf3ce44SJohn Forte size = FPM_SZ; 4149*fcf3ce44SJohn Forte } else { 4150*fcf3ce44SJohn Forte start = (int *)(long)buf; 4151*fcf3ce44SJohn Forte size = TEXT_SZ + IDATA_SZ; 4152*fcf3ce44SJohn Forte } 4153*fcf3ce44SJohn Forte 4154*fcf3ce44SJohn Forte for (j = 0, p = start, i = 0; i < (size/ 4); i++, j ^= *p++); 4155*fcf3ce44SJohn Forte 4156*fcf3ce44SJohn Forte if (j != 0) { 4157*fcf3ce44SJohn Forte return (L_DWNLD_CHKSUM_FAILED); 4158*fcf3ce44SJohn Forte } 4159*fcf3ce44SJohn Forte 4160*fcf3ce44SJohn Forte /* file verified */ 4161*fcf3ce44SJohn Forte *buf_ptr = buf; 4162*fcf3ce44SJohn Forte 4163*fcf3ce44SJohn Forte return (0); 4164*fcf3ce44SJohn Forte } 4165*fcf3ce44SJohn Forte 4166*fcf3ce44SJohn Forte /* 4167*fcf3ce44SJohn Forte * Check the DPM file for validity: 4168*fcf3ce44SJohn Forte * 4169*fcf3ce44SJohn Forte * RETURNS: 4170*fcf3ce44SJohn Forte * 0 O.K. 4171*fcf3ce44SJohn Forte * non-zero otherwise 4172*fcf3ce44SJohn Forte */ 4173*fcf3ce44SJohn Forte #define dakstring "64616B74617269" 4174*fcf3ce44SJohn Forte #define dakoffs "BFC00000" 4175*fcf3ce44SJohn Forte 4176*fcf3ce44SJohn Forte static int 4177*fcf3ce44SJohn Forte check_dpm_file(int fd) 4178*fcf3ce44SJohn Forte { 4179*fcf3ce44SJohn Forte struct s3hdr { 4180*fcf3ce44SJohn Forte char rtype[2]; 4181*fcf3ce44SJohn Forte char rlen[2]; 4182*fcf3ce44SJohn Forte char data[255]; 4183*fcf3ce44SJohn Forte } theRec; 4184*fcf3ce44SJohn Forte int nread; 4185*fcf3ce44SJohn Forte int reclen; 4186*fcf3ce44SJohn Forte 4187*fcf3ce44SJohn Forte if (fd < 0) { 4188*fcf3ce44SJohn Forte return (L_DWNLD_READ_ERROR); 4189*fcf3ce44SJohn Forte } 4190*fcf3ce44SJohn Forte lseek(fd, 0, SEEK_SET); 4191*fcf3ce44SJohn Forte 4192*fcf3ce44SJohn Forte /* First record */ 4193*fcf3ce44SJohn Forte memset((void*)&theRec, 0, sizeof (struct s3hdr)); 4194*fcf3ce44SJohn Forte nread = read(fd, (void *)&theRec, 4); 4195*fcf3ce44SJohn Forte if (nread != 4) { 4196*fcf3ce44SJohn Forte /* error reading first record/length */ 4197*fcf3ce44SJohn Forte return (L_DWNLD_READ_ERROR); 4198*fcf3ce44SJohn Forte } 4199*fcf3ce44SJohn Forte if (strncmp((char *)&theRec.rtype[0], "S0", 2) != 0) { 4200*fcf3ce44SJohn Forte /* error in first record type */ 4201*fcf3ce44SJohn Forte return (L_DWNLD_READ_HEADER_FAIL); 4202*fcf3ce44SJohn Forte } 4203*fcf3ce44SJohn Forte reclen = strtol(&theRec.rlen[0], (char **)NULL, 16); 4204*fcf3ce44SJohn Forte if (reclen == 0) { 4205*fcf3ce44SJohn Forte /* error in length == 0 */ 4206*fcf3ce44SJohn Forte return (L_DWNLD_READ_HEADER_FAIL); 4207*fcf3ce44SJohn Forte } 4208*fcf3ce44SJohn Forte nread = read(fd, (void *)&theRec.data[0], ((reclen*2) +1)); 4209*fcf3ce44SJohn Forte if (nread != ((reclen*2) +1)) { 4210*fcf3ce44SJohn Forte /* error in trying to read data */ 4211*fcf3ce44SJohn Forte return (L_DWNLD_READ_HEADER_FAIL); 4212*fcf3ce44SJohn Forte } 4213*fcf3ce44SJohn Forte if (strncmp(&theRec.data[4], dakstring, 14) != 0) { 4214*fcf3ce44SJohn Forte /* error in compiled file name */ 4215*fcf3ce44SJohn Forte return (L_DWNLD_READ_HEADER_FAIL); 4216*fcf3ce44SJohn Forte } 4217*fcf3ce44SJohn Forte 4218*fcf3ce44SJohn Forte /* Second record */ 4219*fcf3ce44SJohn Forte memset((void*)&theRec, 0, sizeof (struct s3hdr)); 4220*fcf3ce44SJohn Forte nread = read(fd, (void *)&theRec, 4); 4221*fcf3ce44SJohn Forte if (nread != 4) { 4222*fcf3ce44SJohn Forte /* error reading second record/length */ 4223*fcf3ce44SJohn Forte return (L_DWNLD_READ_ERROR); 4224*fcf3ce44SJohn Forte } 4225*fcf3ce44SJohn Forte if (strncmp((char *)&theRec.rtype[0], "S3", 2) != 0) { 4226*fcf3ce44SJohn Forte /* error in second record type */ 4227*fcf3ce44SJohn Forte return (L_DWNLD_READ_HEADER_FAIL); 4228*fcf3ce44SJohn Forte } 4229*fcf3ce44SJohn Forte reclen = strtol(&theRec.rlen[0], (char **)NULL, 16); 4230*fcf3ce44SJohn Forte if (reclen == 0) { 4231*fcf3ce44SJohn Forte /* error in length == 0 */ 4232*fcf3ce44SJohn Forte return (L_DWNLD_READ_HEADER_FAIL); 4233*fcf3ce44SJohn Forte } 4234*fcf3ce44SJohn Forte nread = read(fd, (void *)&theRec.data[0], ((reclen*2) +1)); 4235*fcf3ce44SJohn Forte if (nread != ((reclen*2) +1)) { 4236*fcf3ce44SJohn Forte /* error in trying to read data */ 4237*fcf3ce44SJohn Forte return (L_DWNLD_READ_HEADER_FAIL); 4238*fcf3ce44SJohn Forte } 4239*fcf3ce44SJohn Forte if (strncmp(&theRec.data[0], dakoffs, 8) != 0) { 4240*fcf3ce44SJohn Forte /* error in SSC100 offset pointer */ 4241*fcf3ce44SJohn Forte return (L_DWNLD_READ_HEADER_FAIL); 4242*fcf3ce44SJohn Forte } 4243*fcf3ce44SJohn Forte lseek(fd, 0, SEEK_SET); 4244*fcf3ce44SJohn Forte return (0); 4245*fcf3ce44SJohn Forte } 4246*fcf3ce44SJohn Forte 4247*fcf3ce44SJohn Forte 4248*fcf3ce44SJohn Forte 4249*fcf3ce44SJohn Forte int 4250*fcf3ce44SJohn Forte l_check_file(char *file, int verbose) 4251*fcf3ce44SJohn Forte { 4252*fcf3ce44SJohn Forte int file_fd; 4253*fcf3ce44SJohn Forte int err; 4254*fcf3ce44SJohn Forte uchar_t *buf; 4255*fcf3ce44SJohn Forte 4256*fcf3ce44SJohn Forte if ((file_fd = g_object_open(file, O_RDONLY)) == -1) { 4257*fcf3ce44SJohn Forte return (L_OPEN_PATH_FAIL); 4258*fcf3ce44SJohn Forte } 4259*fcf3ce44SJohn Forte err = check_file(file_fd, verbose, &buf, FW_DL_INFO); 4260*fcf3ce44SJohn Forte if (buf) 4261*fcf3ce44SJohn Forte (void) g_destroy_data((char *)buf); 4262*fcf3ce44SJohn Forte return (err); 4263*fcf3ce44SJohn Forte } 4264*fcf3ce44SJohn Forte 4265*fcf3ce44SJohn Forte 4266*fcf3ce44SJohn Forte 4267*fcf3ce44SJohn Forte /* 4268*fcf3ce44SJohn Forte * Write buffer command set up to download 4269*fcf3ce44SJohn Forte * firmware to the Photon IB. 4270*fcf3ce44SJohn Forte * 4271*fcf3ce44SJohn Forte * RETURNS: 4272*fcf3ce44SJohn Forte * status 4273*fcf3ce44SJohn Forte */ 4274*fcf3ce44SJohn Forte static int 4275*fcf3ce44SJohn Forte ib_download_code_cmd(int fd, int promid, int off, uchar_t *buf_ptr, 4276*fcf3ce44SJohn Forte int buf_len, int sp) 4277*fcf3ce44SJohn Forte { 4278*fcf3ce44SJohn Forte int status, sz; 4279*fcf3ce44SJohn Forte 4280*fcf3ce44SJohn Forte while (buf_len) { 4281*fcf3ce44SJohn Forte sz = MIN(256, buf_len); 4282*fcf3ce44SJohn Forte buf_len -= sz; 4283*fcf3ce44SJohn Forte status = g_scsi_writebuffer_cmd(fd, off, buf_ptr, sz, 4284*fcf3ce44SJohn Forte (sp) ? 3 : 2, promid); 4285*fcf3ce44SJohn Forte if (status) 4286*fcf3ce44SJohn Forte return (status); 4287*fcf3ce44SJohn Forte buf_ptr += sz; 4288*fcf3ce44SJohn Forte off += sz; 4289*fcf3ce44SJohn Forte } 4290*fcf3ce44SJohn Forte 4291*fcf3ce44SJohn Forte return (status); 4292*fcf3ce44SJohn Forte } 4293*fcf3ce44SJohn Forte 4294*fcf3ce44SJohn Forte /* 4295*fcf3ce44SJohn Forte * 4296*fcf3ce44SJohn Forte * Downloads the code to the DAKTARI/DPM with the hdr set correctly 4297*fcf3ce44SJohn Forte * 4298*fcf3ce44SJohn Forte * 4299*fcf3ce44SJohn Forte * Inputs: 4300*fcf3ce44SJohn Forte * fd - int for the file descriptor 4301*fcf3ce44SJohn Forte * buf_ptr - uchar_t pointer to the firmware itself 4302*fcf3ce44SJohn Forte * buf_len - int for the length of the data 4303*fcf3ce44SJohn Forte * 4304*fcf3ce44SJohn Forte * Returns: 4305*fcf3ce44SJohn Forte * status: 0 indicates success, != 0 failure, returned from writebuffer 4306*fcf3ce44SJohn Forte * 4307*fcf3ce44SJohn Forte */ 4308*fcf3ce44SJohn Forte 4309*fcf3ce44SJohn Forte static int 4310*fcf3ce44SJohn Forte dak_download_code_cmd(int fd, uchar_t *buf_ptr, int buf_len) 4311*fcf3ce44SJohn Forte { 4312*fcf3ce44SJohn Forte int status = 0; 4313*fcf3ce44SJohn Forte int sz = 0; 4314*fcf3ce44SJohn Forte int offs = 0; 4315*fcf3ce44SJohn Forte 4316*fcf3ce44SJohn Forte while (buf_len > 0) { 4317*fcf3ce44SJohn Forte sz = MIN(256, buf_len); 4318*fcf3ce44SJohn Forte buf_len -= sz; 4319*fcf3ce44SJohn Forte status = g_scsi_writebuffer_cmd(fd, offs, buf_ptr, sz, 0x07, 0); 4320*fcf3ce44SJohn Forte if (status != 0) { 4321*fcf3ce44SJohn Forte return (status); 4322*fcf3ce44SJohn Forte } 4323*fcf3ce44SJohn Forte buf_ptr += sz; 4324*fcf3ce44SJohn Forte offs += sz; 4325*fcf3ce44SJohn Forte } 4326*fcf3ce44SJohn Forte return (status); 4327*fcf3ce44SJohn Forte } 4328*fcf3ce44SJohn Forte 4329*fcf3ce44SJohn Forte 4330*fcf3ce44SJohn Forte 4331*fcf3ce44SJohn Forte 4332*fcf3ce44SJohn Forte /* 4333*fcf3ce44SJohn Forte * Downloads the new prom image to IB. 4334*fcf3ce44SJohn Forte * 4335*fcf3ce44SJohn Forte * INPUTS: 4336*fcf3ce44SJohn Forte * path - physical path of Photon SES card 4337*fcf3ce44SJohn Forte * file - input file for new code (may be NULL) 4338*fcf3ce44SJohn Forte * ps - whether the "save" bit should be set 4339*fcf3ce44SJohn Forte * verbose - to be verbose or not 4340*fcf3ce44SJohn Forte * 4341*fcf3ce44SJohn Forte * RETURNS: 4342*fcf3ce44SJohn Forte * 0 O.K. 4343*fcf3ce44SJohn Forte * non-zero otherwise 4344*fcf3ce44SJohn Forte */ 4345*fcf3ce44SJohn Forte int 4346*fcf3ce44SJohn Forte l_download(char *path_phys, char *file, int ps, int verbose) 4347*fcf3ce44SJohn Forte { 4348*fcf3ce44SJohn Forte int file_fd, controller_fd; 4349*fcf3ce44SJohn Forte int err, status; 4350*fcf3ce44SJohn Forte uchar_t *buf_ptr; 4351*fcf3ce44SJohn Forte char printbuf[MAXPATHLEN]; 4352*fcf3ce44SJohn Forte int retry; 4353*fcf3ce44SJohn Forte char file_path[MAXPATHLEN]; 4354*fcf3ce44SJohn Forte struct stat statbuf; 4355*fcf3ce44SJohn Forte int enc_type; 4356*fcf3ce44SJohn Forte L_inquiry inq; 4357*fcf3ce44SJohn Forte 4358*fcf3ce44SJohn Forte if (path_phys == NULL) { 4359*fcf3ce44SJohn Forte return (L_INVALID_PATH_FORMAT); 4360*fcf3ce44SJohn Forte } 4361*fcf3ce44SJohn Forte 4362*fcf3ce44SJohn Forte if (!file) { 4363*fcf3ce44SJohn Forte (void) strcpy(file_path, IBFIRMWARE_FILE); 4364*fcf3ce44SJohn Forte } else { 4365*fcf3ce44SJohn Forte (void) strncpy(file_path, file, sizeof (file_path)); 4366*fcf3ce44SJohn Forte } 4367*fcf3ce44SJohn Forte if (verbose) 4368*fcf3ce44SJohn Forte (void) fprintf(stdout, "%s\n", 4369*fcf3ce44SJohn Forte MSGSTR(9051, " Opening the IB for I/O.")); 4370*fcf3ce44SJohn Forte 4371*fcf3ce44SJohn Forte if ((controller_fd = g_object_open(path_phys, O_NDELAY | O_RDWR)) == -1) 4372*fcf3ce44SJohn Forte return (L_OPEN_PATH_FAIL); 4373*fcf3ce44SJohn Forte 4374*fcf3ce44SJohn Forte (void) sprintf(printbuf, MSGSTR(9052, " Doing download to:" 4375*fcf3ce44SJohn Forte "\n\t%s.\n From file: %s."), path_phys, file_path); 4376*fcf3ce44SJohn Forte 4377*fcf3ce44SJohn Forte if (verbose) 4378*fcf3ce44SJohn Forte (void) fprintf(stdout, "%s\n", printbuf); 4379*fcf3ce44SJohn Forte P_DPRINTF(" Doing download to:" 4380*fcf3ce44SJohn Forte "\n\t%s\n From file: %s\n", path_phys, file_path); 4381*fcf3ce44SJohn Forte 4382*fcf3ce44SJohn Forte if ((file_fd = g_object_open(file_path, O_NDELAY | O_RDONLY)) == -1) { 4383*fcf3ce44SJohn Forte /* 4384*fcf3ce44SJohn Forte * Return a different error code here to differentiate between 4385*fcf3ce44SJohn Forte * this failure in g_object_open() and the one above. 4386*fcf3ce44SJohn Forte */ 4387*fcf3ce44SJohn Forte return (L_INVALID_PATH); 4388*fcf3ce44SJohn Forte } 4389*fcf3ce44SJohn Forte 4390*fcf3ce44SJohn Forte if (g_scsi_inquiry_cmd(controller_fd, (uchar_t *)&inq, sizeof (inq))) { 4391*fcf3ce44SJohn Forte return (L_SCSI_ERROR); 4392*fcf3ce44SJohn Forte } 4393*fcf3ce44SJohn Forte enc_type = l_get_enc_type(inq); 4394*fcf3ce44SJohn Forte switch (enc_type) { 4395*fcf3ce44SJohn Forte case DAK_ENC_TYPE: 4396*fcf3ce44SJohn Forte /* 4397*fcf3ce44SJohn Forte * We don't have a default daktari file location, so 4398*fcf3ce44SJohn Forte * the user must specify the firmware file on the command line 4399*fcf3ce44SJohn Forte */ 4400*fcf3ce44SJohn Forte if (!file) { 4401*fcf3ce44SJohn Forte return (L_REQUIRE_FILE); 4402*fcf3ce44SJohn Forte } 4403*fcf3ce44SJohn Forte /* Validate the file */ 4404*fcf3ce44SJohn Forte if ((err = check_dpm_file(file_fd))) { 4405*fcf3ce44SJohn Forte return (err); 4406*fcf3ce44SJohn Forte } 4407*fcf3ce44SJohn Forte /* Now go ahead and load up the data */ 4408*fcf3ce44SJohn Forte if (fstat(file_fd, &statbuf) == -1) { 4409*fcf3ce44SJohn Forte err = errno; 4410*fcf3ce44SJohn Forte (void) fprintf(stdout, "%s %s\n", 4411*fcf3ce44SJohn Forte MSGSTR(9101, " Stat'ing the F/W file:"), strerror(err)); 4412*fcf3ce44SJohn Forte return (L_OPEN_PATH_FAIL); 4413*fcf3ce44SJohn Forte } 4414*fcf3ce44SJohn Forte buf_ptr = (uchar_t *)g_zalloc(statbuf.st_size); 4415*fcf3ce44SJohn Forte if (buf_ptr == NULL) { 4416*fcf3ce44SJohn Forte err = errno; 4417*fcf3ce44SJohn Forte (void) fprintf(stdout, "%s %s\n", 4418*fcf3ce44SJohn Forte MSGSTR(9102, " Cannot alloc mem to read F/W file:"), 4419*fcf3ce44SJohn Forte strerror(err)); 4420*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 4421*fcf3ce44SJohn Forte } 4422*fcf3ce44SJohn Forte if (read(file_fd, buf_ptr, statbuf.st_size) == -1) { 4423*fcf3ce44SJohn Forte err = errno; 4424*fcf3ce44SJohn Forte (void) fprintf(stdout, "%s %s\n", 4425*fcf3ce44SJohn Forte MSGSTR(9103, " Reading F/W file:"), strerror(err)); 4426*fcf3ce44SJohn Forte g_destroy_data((char *)buf_ptr); 4427*fcf3ce44SJohn Forte return (L_DWNLD_READ_ERROR); 4428*fcf3ce44SJohn Forte } 4429*fcf3ce44SJohn Forte break; 4430*fcf3ce44SJohn Forte default: 4431*fcf3ce44SJohn Forte if (err = check_file(file_fd, verbose, &buf_ptr, FW_DL_INFO)) { 4432*fcf3ce44SJohn Forte if (buf_ptr) { 4433*fcf3ce44SJohn Forte (void) g_destroy_data((char *)buf_ptr); 4434*fcf3ce44SJohn Forte return (err); 4435*fcf3ce44SJohn Forte } 4436*fcf3ce44SJohn Forte } 4437*fcf3ce44SJohn Forte break; 4438*fcf3ce44SJohn Forte } 4439*fcf3ce44SJohn Forte 4440*fcf3ce44SJohn Forte if (verbose) { 4441*fcf3ce44SJohn Forte (void) fprintf(stdout, " "); 4442*fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(127, "Checkfile O.K.")); 4443*fcf3ce44SJohn Forte (void) fprintf(stdout, "\n"); 4444*fcf3ce44SJohn Forte } 4445*fcf3ce44SJohn Forte P_DPRINTF(" Checkfile OK.\n"); 4446*fcf3ce44SJohn Forte (void) close(file_fd); 4447*fcf3ce44SJohn Forte 4448*fcf3ce44SJohn Forte if (verbose) { 4449*fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(9053, 4450*fcf3ce44SJohn Forte " Verifying the IB is available.\n")); 4451*fcf3ce44SJohn Forte } 4452*fcf3ce44SJohn Forte 4453*fcf3ce44SJohn Forte retry = DOWNLOAD_RETRIES; 4454*fcf3ce44SJohn Forte while (retry) { 4455*fcf3ce44SJohn Forte if ((status = g_scsi_tur(controller_fd)) == 0) { 4456*fcf3ce44SJohn Forte break; 4457*fcf3ce44SJohn Forte } else { 4458*fcf3ce44SJohn Forte if ((retry % 30) == 0) { 4459*fcf3ce44SJohn Forte ER_DPRINTF(" Waiting for the IB to be" 4460*fcf3ce44SJohn Forte " available.\n"); 4461*fcf3ce44SJohn Forte } 4462*fcf3ce44SJohn Forte (void) sleep(1); 4463*fcf3ce44SJohn Forte } 4464*fcf3ce44SJohn Forte } 4465*fcf3ce44SJohn Forte if (!retry) { 4466*fcf3ce44SJohn Forte if (buf_ptr) 4467*fcf3ce44SJohn Forte (void) g_destroy_data((char *)buf_ptr); 4468*fcf3ce44SJohn Forte (void) close(controller_fd); 4469*fcf3ce44SJohn Forte return (status); 4470*fcf3ce44SJohn Forte } 4471*fcf3ce44SJohn Forte 4472*fcf3ce44SJohn Forte if (verbose) 4473*fcf3ce44SJohn Forte (void) fprintf(stdout, "%s\n", 4474*fcf3ce44SJohn Forte MSGSTR(9054, " Writing new text image to IB.")); 4475*fcf3ce44SJohn Forte P_DPRINTF(" Writing new image to IB\n"); 4476*fcf3ce44SJohn Forte switch (enc_type) { 4477*fcf3ce44SJohn Forte case DAK_ENC_TYPE: 4478*fcf3ce44SJohn Forte status = dak_download_code_cmd(controller_fd, buf_ptr, 4479*fcf3ce44SJohn Forte statbuf.st_size); 4480*fcf3ce44SJohn Forte if (status != 0) { 4481*fcf3ce44SJohn Forte if (buf_ptr != NULL) { 4482*fcf3ce44SJohn Forte g_destroy_data((char *)buf_ptr); 4483*fcf3ce44SJohn Forte } 4484*fcf3ce44SJohn Forte (void) close(controller_fd); 4485*fcf3ce44SJohn Forte return (status); 4486*fcf3ce44SJohn Forte } 4487*fcf3ce44SJohn Forte break; 4488*fcf3ce44SJohn Forte default: 4489*fcf3ce44SJohn Forte status = ib_download_code_cmd(controller_fd, IBEEPROM, TEXT_OFFSET, 4490*fcf3ce44SJohn Forte (uchar_t *)(buf_ptr + TEXT_OFFSET), TEXT_SZ, ps); 4491*fcf3ce44SJohn Forte if (status) { 4492*fcf3ce44SJohn Forte (void) close(controller_fd); 4493*fcf3ce44SJohn Forte (void) g_destroy_data((char *)buf_ptr); 4494*fcf3ce44SJohn Forte return (status); 4495*fcf3ce44SJohn Forte } 4496*fcf3ce44SJohn Forte if (verbose) { 4497*fcf3ce44SJohn Forte (void) fprintf(stdout, "%s\n", 4498*fcf3ce44SJohn Forte MSGSTR(9055, " Writing new data image to IB.")); 4499*fcf3ce44SJohn Forte } 4500*fcf3ce44SJohn Forte status = ib_download_code_cmd(controller_fd, IBEEPROM, IDATA_OFFSET, 4501*fcf3ce44SJohn Forte (uchar_t *)(buf_ptr + IDATA_OFFSET), IDATA_SZ, ps); 4502*fcf3ce44SJohn Forte if (status) { 4503*fcf3ce44SJohn Forte (void) close(controller_fd); 4504*fcf3ce44SJohn Forte (void) g_destroy_data((char *)buf_ptr); 4505*fcf3ce44SJohn Forte return (status); 4506*fcf3ce44SJohn Forte } 4507*fcf3ce44SJohn Forte break; 4508*fcf3ce44SJohn Forte } 4509*fcf3ce44SJohn Forte 4510*fcf3ce44SJohn Forte 4511*fcf3ce44SJohn Forte if (verbose) { 4512*fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(9056, 4513*fcf3ce44SJohn Forte " Re-verifying the IB is available.\n")); 4514*fcf3ce44SJohn Forte } 4515*fcf3ce44SJohn Forte 4516*fcf3ce44SJohn Forte retry = DOWNLOAD_RETRIES; 4517*fcf3ce44SJohn Forte while (retry) { 4518*fcf3ce44SJohn Forte if ((status = g_scsi_tur(controller_fd)) == 0) { 4519*fcf3ce44SJohn Forte break; 4520*fcf3ce44SJohn Forte } else { 4521*fcf3ce44SJohn Forte if ((retry % 30) == 0) { 4522*fcf3ce44SJohn Forte ER_DPRINTF(" Waiting for the IB to be" 4523*fcf3ce44SJohn Forte " available.\n"); 4524*fcf3ce44SJohn Forte } 4525*fcf3ce44SJohn Forte (void) sleep(1); 4526*fcf3ce44SJohn Forte } 4527*fcf3ce44SJohn Forte retry--; 4528*fcf3ce44SJohn Forte } 4529*fcf3ce44SJohn Forte if (!retry) { 4530*fcf3ce44SJohn Forte (void) close(controller_fd); 4531*fcf3ce44SJohn Forte (void) g_destroy_data((char *)buf_ptr); 4532*fcf3ce44SJohn Forte return (L_DWNLD_TIMED_OUT); 4533*fcf3ce44SJohn Forte } 4534*fcf3ce44SJohn Forte 4535*fcf3ce44SJohn Forte switch (enc_type) { 4536*fcf3ce44SJohn Forte case DAK_ENC_TYPE: 4537*fcf3ce44SJohn Forte break; 4538*fcf3ce44SJohn Forte default: 4539*fcf3ce44SJohn Forte if (verbose) { 4540*fcf3ce44SJohn Forte (void) fprintf(stdout, "%s\n", 4541*fcf3ce44SJohn Forte MSGSTR(9057, " Writing new image to FPM.")); 4542*fcf3ce44SJohn Forte } 4543*fcf3ce44SJohn Forte status = ib_download_code_cmd(controller_fd, MBEEPROM, FPM_OFFSET, 4544*fcf3ce44SJohn Forte (uchar_t *)(buf_ptr + FPM_OFFSET), FPM_SZ, ps); 4545*fcf3ce44SJohn Forte break; 4546*fcf3ce44SJohn Forte } 4547*fcf3ce44SJohn Forte 4548*fcf3ce44SJohn Forte if ((!status) && ps) { 4549*fcf3ce44SJohn Forte /* 4550*fcf3ce44SJohn Forte * Reset the IB 4551*fcf3ce44SJohn Forte */ 4552*fcf3ce44SJohn Forte status = g_scsi_reset(controller_fd); 4553*fcf3ce44SJohn Forte } 4554*fcf3ce44SJohn Forte 4555*fcf3ce44SJohn Forte (void) close(controller_fd); 4556*fcf3ce44SJohn Forte return (status); 4557*fcf3ce44SJohn Forte } 4558*fcf3ce44SJohn Forte 4559*fcf3ce44SJohn Forte /* 4560*fcf3ce44SJohn Forte * Set the World Wide Name 4561*fcf3ce44SJohn Forte * in page 4 of the Send Diagnostic command. 4562*fcf3ce44SJohn Forte * 4563*fcf3ce44SJohn Forte * Is it allowed to change the wwn ??? 4564*fcf3ce44SJohn Forte * The path must point to an IB. 4565*fcf3ce44SJohn Forte * 4566*fcf3ce44SJohn Forte */ 4567*fcf3ce44SJohn Forte int 4568*fcf3ce44SJohn Forte l_set_wwn(char *path_phys, char *wwn) 4569*fcf3ce44SJohn Forte { 4570*fcf3ce44SJohn Forte Page4_name page4; 4571*fcf3ce44SJohn Forte L_inquiry inq; 4572*fcf3ce44SJohn Forte int fd, status; 4573*fcf3ce44SJohn Forte char wwnp[WWN_SIZE]; 4574*fcf3ce44SJohn Forte 4575*fcf3ce44SJohn Forte (void) memset(&inq, 0, sizeof (inq)); 4576*fcf3ce44SJohn Forte (void) memset(&page4, 0, sizeof (page4)); 4577*fcf3ce44SJohn Forte 4578*fcf3ce44SJohn Forte if ((fd = g_object_open(path_phys, O_NDELAY | O_RDONLY)) == -1) { 4579*fcf3ce44SJohn Forte return (L_OPEN_PATH_FAIL); 4580*fcf3ce44SJohn Forte } 4581*fcf3ce44SJohn Forte /* Verify it is a Photon */ 4582*fcf3ce44SJohn Forte if (status = g_scsi_inquiry_cmd(fd, 4583*fcf3ce44SJohn Forte (uchar_t *)&inq, sizeof (struct l_inquiry_struct))) { 4584*fcf3ce44SJohn Forte (void) close(fd); 4585*fcf3ce44SJohn Forte return (status); 4586*fcf3ce44SJohn Forte } 4587*fcf3ce44SJohn Forte if ((strstr((char *)inq.inq_pid, ENCLOSURE_PROD_ID) == 0) && 4588*fcf3ce44SJohn Forte (!(strncmp((char *)inq.inq_vid, "SUN ", 4589*fcf3ce44SJohn Forte sizeof (inq.inq_vid)) && 4590*fcf3ce44SJohn Forte ((inq.inq_dtype & DTYPE_MASK) == DTYPE_ESI)))) { 4591*fcf3ce44SJohn Forte (void) close(fd); 4592*fcf3ce44SJohn Forte return (L_ENCL_INVALID_PATH); 4593*fcf3ce44SJohn Forte } 4594*fcf3ce44SJohn Forte 4595*fcf3ce44SJohn Forte page4.page_code = L_PAGE_4; 4596*fcf3ce44SJohn Forte page4.page_len = (ushort_t)((sizeof (struct page4_name) - 4)); 4597*fcf3ce44SJohn Forte page4.string_code = L_WWN; 4598*fcf3ce44SJohn Forte page4.enable = 1; 4599*fcf3ce44SJohn Forte if (g_string_to_wwn((uchar_t *)wwn, (uchar_t *)&page4.name)) { 4600*fcf3ce44SJohn Forte close(fd); 4601*fcf3ce44SJohn Forte return (EINVAL); 4602*fcf3ce44SJohn Forte } 4603*fcf3ce44SJohn Forte bcopy((void *)wwnp, (void *)page4.name, (size_t)WWN_SIZE); 4604*fcf3ce44SJohn Forte 4605*fcf3ce44SJohn Forte if (status = g_scsi_send_diag_cmd(fd, (uchar_t *)&page4, 4606*fcf3ce44SJohn Forte sizeof (page4))) { 4607*fcf3ce44SJohn Forte (void) close(fd); 4608*fcf3ce44SJohn Forte return (status); 4609*fcf3ce44SJohn Forte } 4610*fcf3ce44SJohn Forte 4611*fcf3ce44SJohn Forte /* 4612*fcf3ce44SJohn Forte * Check the wwn really changed. 4613*fcf3ce44SJohn Forte */ 4614*fcf3ce44SJohn Forte bzero((char *)page4.name, 32); 4615*fcf3ce44SJohn Forte if (status = g_scsi_rec_diag_cmd(fd, (uchar_t *)&page4, 4616*fcf3ce44SJohn Forte sizeof (page4), L_PAGE_4)) { 4617*fcf3ce44SJohn Forte (void) close(fd); 4618*fcf3ce44SJohn Forte return (status); 4619*fcf3ce44SJohn Forte } 4620*fcf3ce44SJohn Forte if (bcmp((char *)page4.name, wwnp, WWN_SIZE)) { 4621*fcf3ce44SJohn Forte (void) close(fd); 4622*fcf3ce44SJohn Forte return (L_WARNING); 4623*fcf3ce44SJohn Forte } 4624*fcf3ce44SJohn Forte 4625*fcf3ce44SJohn Forte (void) close(fd); 4626*fcf3ce44SJohn Forte return (0); 4627*fcf3ce44SJohn Forte } 4628*fcf3ce44SJohn Forte 4629*fcf3ce44SJohn Forte 4630*fcf3ce44SJohn Forte 4631*fcf3ce44SJohn Forte /* 4632*fcf3ce44SJohn Forte * Use a physical path to a disk in a Photon box 4633*fcf3ce44SJohn Forte * as the base to genererate a path to a SES 4634*fcf3ce44SJohn Forte * card in this box. 4635*fcf3ce44SJohn Forte * 4636*fcf3ce44SJohn Forte * path_phys: Physical path to a Photon disk. 4637*fcf3ce44SJohn Forte * ses_path: This must be a pointer to an already allocated path string. 4638*fcf3ce44SJohn Forte * 4639*fcf3ce44SJohn Forte * RETURNS: 4640*fcf3ce44SJohn Forte * 0 O.K. 4641*fcf3ce44SJohn Forte * non-zero otherwise 4642*fcf3ce44SJohn Forte */ 4643*fcf3ce44SJohn Forte int 4644*fcf3ce44SJohn Forte l_get_ses_path(char *path_phys, char *ses_path, gfc_map_t *map, 4645*fcf3ce44SJohn Forte int verbose) 4646*fcf3ce44SJohn Forte { 4647*fcf3ce44SJohn Forte char *char_ptr, id_buf[MAXPATHLEN], wwn[20]; 4648*fcf3ce44SJohn Forte uchar_t t_wwn[20], *ses_wwn, *ses_wwn1, *ses_nwwn; 4649*fcf3ce44SJohn Forte int j, al_pa, al_pa1, box_id, fd, disk_flag = 0; 4650*fcf3ce44SJohn Forte int err, found = 0; 4651*fcf3ce44SJohn Forte gfc_port_dev_info_t *dev_addr_ptr; 4652*fcf3ce44SJohn Forte 4653*fcf3ce44SJohn Forte if ((path_phys == NULL) || (ses_path == NULL) || (map == NULL)) { 4654*fcf3ce44SJohn Forte return (L_NO_SES_PATH); 4655*fcf3ce44SJohn Forte } 4656*fcf3ce44SJohn Forte 4657*fcf3ce44SJohn Forte (void) strcpy(ses_path, path_phys); 4658*fcf3ce44SJohn Forte if ((char_ptr = strrchr(ses_path, '/')) == NULL) { 4659*fcf3ce44SJohn Forte return (L_INVLD_PATH_NO_SLASH_FND); 4660*fcf3ce44SJohn Forte } 4661*fcf3ce44SJohn Forte disk_flag++; 4662*fcf3ce44SJohn Forte *char_ptr = '\0'; /* Terminate sting */ 4663*fcf3ce44SJohn Forte (void) strcat(ses_path, SLSH_SES_NAME); 4664*fcf3ce44SJohn Forte 4665*fcf3ce44SJohn Forte /* 4666*fcf3ce44SJohn Forte * Figure out and create the boxes pathname. 4667*fcf3ce44SJohn Forte * 4668*fcf3ce44SJohn Forte * NOTE: This uses the fact that the disks's 4669*fcf3ce44SJohn Forte * AL_PA and the boxes AL_PA must match 4670*fcf3ce44SJohn Forte * the assigned hard address in the current 4671*fcf3ce44SJohn Forte * implementations. This may not be true in the 4672*fcf3ce44SJohn Forte * future. 4673*fcf3ce44SJohn Forte */ 4674*fcf3ce44SJohn Forte if ((char_ptr = strrchr(path_phys, '@')) == NULL) { 4675*fcf3ce44SJohn Forte return (L_INVLD_PATH_NO_ATSIGN_FND); 4676*fcf3ce44SJohn Forte } 4677*fcf3ce44SJohn Forte char_ptr++; /* point to the loop identifier */ 4678*fcf3ce44SJohn Forte 4679*fcf3ce44SJohn Forte if ((err = g_get_wwn(path_phys, t_wwn, t_wwn, 4680*fcf3ce44SJohn Forte &al_pa, verbose)) != 0) { 4681*fcf3ce44SJohn Forte return (err); 4682*fcf3ce44SJohn Forte } 4683*fcf3ce44SJohn Forte box_id = g_sf_alpa_to_switch[al_pa & 0xFF] & BOX_ID_MASK; 4684*fcf3ce44SJohn Forte 4685*fcf3ce44SJohn Forte switch (map->hba_addr.port_topology) { 4686*fcf3ce44SJohn Forte case FC_TOP_PRIVATE_LOOP: 4687*fcf3ce44SJohn Forte for (j = 0, dev_addr_ptr = map->dev_addr; 4688*fcf3ce44SJohn Forte j < map->count; j++, dev_addr_ptr++) { 4689*fcf3ce44SJohn Forte if (dev_addr_ptr->gfc_port_dev.priv_port. 4690*fcf3ce44SJohn Forte sf_inq_dtype == DTYPE_ESI) { 4691*fcf3ce44SJohn Forte al_pa1 = dev_addr_ptr->gfc_port_dev. 4692*fcf3ce44SJohn Forte priv_port.sf_al_pa; 4693*fcf3ce44SJohn Forte if (box_id == (g_sf_alpa_to_switch[al_pa1] & 4694*fcf3ce44SJohn Forte BOX_ID_MASK)) { 4695*fcf3ce44SJohn Forte if (!found) { 4696*fcf3ce44SJohn Forte ses_wwn = dev_addr_ptr-> 4697*fcf3ce44SJohn Forte gfc_port_dev.priv_port.sf_port_wwn; 4698*fcf3ce44SJohn Forte ses_nwwn = dev_addr_ptr-> 4699*fcf3ce44SJohn Forte gfc_port_dev.priv_port.sf_node_wwn; 4700*fcf3ce44SJohn Forte if (getenv("_LUX_P_DEBUG")) { 4701*fcf3ce44SJohn Forte (void) g_ll_to_str(ses_wwn, 4702*fcf3ce44SJohn Forte (char *)t_wwn); 4703*fcf3ce44SJohn Forte (void) printf( 4704*fcf3ce44SJohn Forte " l_get_ses_path: " 4705*fcf3ce44SJohn Forte "Found ses wwn = %s " 4706*fcf3ce44SJohn Forte "al_pa 0x%x\n", t_wwn, al_pa1); 4707*fcf3ce44SJohn Forte } 4708*fcf3ce44SJohn Forte } else { 4709*fcf3ce44SJohn Forte ses_wwn1 = dev_addr_ptr-> 4710*fcf3ce44SJohn Forte gfc_port_dev.priv_port.sf_port_wwn; 4711*fcf3ce44SJohn Forte if (getenv("_LUX_P_DEBUG")) { 4712*fcf3ce44SJohn Forte (void) g_ll_to_str(ses_wwn1, 4713*fcf3ce44SJohn Forte (char *)t_wwn); 4714*fcf3ce44SJohn Forte (void) printf( 4715*fcf3ce44SJohn Forte " l_get_ses_path: " 4716*fcf3ce44SJohn Forte "Found second ses " "wwn = %s " 4717*fcf3ce44SJohn Forte "al_pa 0x%x\n", t_wwn, al_pa1); 4718*fcf3ce44SJohn Forte } 4719*fcf3ce44SJohn Forte } 4720*fcf3ce44SJohn Forte found++; 4721*fcf3ce44SJohn Forte } 4722*fcf3ce44SJohn Forte } 4723*fcf3ce44SJohn Forte } 4724*fcf3ce44SJohn Forte break; 4725*fcf3ce44SJohn Forte case FC_TOP_FABRIC: 4726*fcf3ce44SJohn Forte case FC_TOP_PUBLIC_LOOP: 4727*fcf3ce44SJohn Forte for (j = 0, dev_addr_ptr = map->dev_addr; 4728*fcf3ce44SJohn Forte j < map->count; j++, dev_addr_ptr++) { 4729*fcf3ce44SJohn Forte if (dev_addr_ptr->gfc_port_dev.pub_port.dev_dtype == 4730*fcf3ce44SJohn Forte DTYPE_ESI) { 4731*fcf3ce44SJohn Forte /* 4732*fcf3ce44SJohn Forte * We found an enclosure, lets match the 4733*fcf3ce44SJohn Forte * area and domain codes for this enclosure with 4734*fcf3ce44SJohn Forte * that of the ses path since there may be 4735*fcf3ce44SJohn Forte * multiple enclosures with same box id on a 4736*fcf3ce44SJohn Forte * fabric 4737*fcf3ce44SJohn Forte */ 4738*fcf3ce44SJohn Forte al_pa1 = dev_addr_ptr->gfc_port_dev. 4739*fcf3ce44SJohn Forte pub_port.dev_did.port_id; 4740*fcf3ce44SJohn Forte if ((al_pa & AREA_DOMAIN_ID) == 4741*fcf3ce44SJohn Forte (al_pa1 & AREA_DOMAIN_ID)) { 4742*fcf3ce44SJohn Forte /* 4743*fcf3ce44SJohn Forte * The area and domain matched. Now, we 4744*fcf3ce44SJohn Forte * match the box id of the disk with 4745*fcf3ce44SJohn Forte * this enclosure 4746*fcf3ce44SJohn Forte */ 4747*fcf3ce44SJohn Forte if (box_id == 4748*fcf3ce44SJohn Forte (g_sf_alpa_to_switch[al_pa1 & 4749*fcf3ce44SJohn Forte 0xFF] & BOX_ID_MASK)) { 4750*fcf3ce44SJohn Forte if (!found) { 4751*fcf3ce44SJohn Forte ses_wwn = dev_addr_ptr-> 4752*fcf3ce44SJohn Forte gfc_port_dev.pub_port. 4753*fcf3ce44SJohn Forte dev_pwwn.raw_wwn; 4754*fcf3ce44SJohn Forte ses_nwwn = dev_addr_ptr-> 4755*fcf3ce44SJohn Forte gfc_port_dev.pub_port. 4756*fcf3ce44SJohn Forte dev_nwwn.raw_wwn; 4757*fcf3ce44SJohn Forte if (getenv("_LUX_P_DEBUG")) { 4758*fcf3ce44SJohn Forte (void) g_ll_to_str(ses_wwn, 4759*fcf3ce44SJohn Forte (char *)t_wwn); 4760*fcf3ce44SJohn Forte (void) printf( 4761*fcf3ce44SJohn Forte " l_get_ses_path: " 4762*fcf3ce44SJohn Forte "Found ses wwn = %s " 4763*fcf3ce44SJohn Forte "al_pa 0x%x\n", t_wwn, 4764*fcf3ce44SJohn Forte al_pa1); 4765*fcf3ce44SJohn Forte } 4766*fcf3ce44SJohn Forte } else { 4767*fcf3ce44SJohn Forte ses_wwn1 = dev_addr_ptr-> 4768*fcf3ce44SJohn Forte gfc_port_dev.pub_port. 4769*fcf3ce44SJohn Forte dev_pwwn.raw_wwn; 4770*fcf3ce44SJohn Forte if (getenv("_LUX_P_DEBUG")) { 4771*fcf3ce44SJohn Forte (void) g_ll_to_str(ses_wwn1, 4772*fcf3ce44SJohn Forte (char *)t_wwn); 4773*fcf3ce44SJohn Forte (void) printf( 4774*fcf3ce44SJohn Forte " l_get_ses_path: " 4775*fcf3ce44SJohn Forte "Found second ses " 4776*fcf3ce44SJohn Forte "wwn = %s " 4777*fcf3ce44SJohn Forte "al_pa 0x%x\n", t_wwn, 4778*fcf3ce44SJohn Forte al_pa1); 4779*fcf3ce44SJohn Forte } 4780*fcf3ce44SJohn Forte } 4781*fcf3ce44SJohn Forte found++; 4782*fcf3ce44SJohn Forte } 4783*fcf3ce44SJohn Forte } 4784*fcf3ce44SJohn Forte } 4785*fcf3ce44SJohn Forte } 4786*fcf3ce44SJohn Forte break; 4787*fcf3ce44SJohn Forte case FC_TOP_PT_PT: 4788*fcf3ce44SJohn Forte return (L_PT_PT_FC_TOP_NOT_SUPPORTED); 4789*fcf3ce44SJohn Forte default: 4790*fcf3ce44SJohn Forte return (L_UNEXPECTED_FC_TOPOLOGY); 4791*fcf3ce44SJohn Forte } /* End of switch on port_topology */ 4792*fcf3ce44SJohn Forte 4793*fcf3ce44SJohn Forte if (!found) { 4794*fcf3ce44SJohn Forte return (L_NO_SES_PATH); 4795*fcf3ce44SJohn Forte } 4796*fcf3ce44SJohn Forte 4797*fcf3ce44SJohn Forte if (strstr(path_phys, SCSI_VHCI) != NULL) { 4798*fcf3ce44SJohn Forte (void) g_ll_to_str(ses_nwwn, wwn); 4799*fcf3ce44SJohn Forte (void) sprintf(id_buf, "g%s:0", wwn); 4800*fcf3ce44SJohn Forte } else { 4801*fcf3ce44SJohn Forte (void) g_ll_to_str(ses_wwn, wwn); 4802*fcf3ce44SJohn Forte (void) sprintf(id_buf, "w%s,0:0", wwn); 4803*fcf3ce44SJohn Forte } 4804*fcf3ce44SJohn Forte (void) strcat(ses_path, id_buf); 4805*fcf3ce44SJohn Forte if (verbose) { 4806*fcf3ce44SJohn Forte (void) fprintf(stdout, 4807*fcf3ce44SJohn Forte MSGSTR(9058, " Creating enclosure path:\n %s\n"), 4808*fcf3ce44SJohn Forte ses_path); 4809*fcf3ce44SJohn Forte } 4810*fcf3ce44SJohn Forte 4811*fcf3ce44SJohn Forte /* 4812*fcf3ce44SJohn Forte * see if these paths exist. 4813*fcf3ce44SJohn Forte */ 4814*fcf3ce44SJohn Forte if ((fd = g_object_open(ses_path, O_NDELAY | O_RDONLY)) == -1) { 4815*fcf3ce44SJohn Forte 4816*fcf3ce44SJohn Forte if (strstr(path_phys, SCSI_VHCI) != NULL) { 4817*fcf3ce44SJohn Forte return (L_INVALID_PATH); 4818*fcf3ce44SJohn Forte } 4819*fcf3ce44SJohn Forte 4820*fcf3ce44SJohn Forte char_ptr = strrchr(ses_path, '/'); 4821*fcf3ce44SJohn Forte *char_ptr = '\0'; 4822*fcf3ce44SJohn Forte (void) strcat(ses_path, SLSH_SES_NAME); 4823*fcf3ce44SJohn Forte if (found > 1) { 4824*fcf3ce44SJohn Forte (void) g_ll_to_str(ses_wwn1, wwn); 4825*fcf3ce44SJohn Forte P_DPRINTF(" l_get_ses_path: " 4826*fcf3ce44SJohn Forte "Using second path, ses wwn1 = %s\n", 4827*fcf3ce44SJohn Forte wwn); 4828*fcf3ce44SJohn Forte (void) sprintf(id_buf, "w%s,0:0", wwn); 4829*fcf3ce44SJohn Forte strcat(ses_path, id_buf); 4830*fcf3ce44SJohn Forte return (0); 4831*fcf3ce44SJohn Forte } else { 4832*fcf3ce44SJohn Forte return (L_NO_SES_PATH); 4833*fcf3ce44SJohn Forte } 4834*fcf3ce44SJohn Forte } 4835*fcf3ce44SJohn Forte close(fd); 4836*fcf3ce44SJohn Forte return (0); 4837*fcf3ce44SJohn Forte } 4838*fcf3ce44SJohn Forte 4839*fcf3ce44SJohn Forte 4840*fcf3ce44SJohn Forte 4841*fcf3ce44SJohn Forte /* 4842*fcf3ce44SJohn Forte * Get a valid location, front/rear & slot. 4843*fcf3ce44SJohn Forte * 4844*fcf3ce44SJohn Forte * path_struct->p_physical_path must be of a disk. 4845*fcf3ce44SJohn Forte * 4846*fcf3ce44SJohn Forte * OUTPUT: path_struct->slot_valid 4847*fcf3ce44SJohn Forte * path_struct->slot 4848*fcf3ce44SJohn Forte * path_struct->f_flag 4849*fcf3ce44SJohn Forte * 4850*fcf3ce44SJohn Forte * RETURN: 4851*fcf3ce44SJohn Forte * 0 O.K. 4852*fcf3ce44SJohn Forte * non-zero otherwise 4853*fcf3ce44SJohn Forte */ 4854*fcf3ce44SJohn Forte int 4855*fcf3ce44SJohn Forte l_get_slot(struct path_struct *path_struct, L_state *l_state, int verbose) 4856*fcf3ce44SJohn Forte { 4857*fcf3ce44SJohn Forte int err, al_pa, slot, found = 0; 4858*fcf3ce44SJohn Forte uchar_t node_wwn[WWN_SIZE], port_wwn[WWN_SIZE]; 4859*fcf3ce44SJohn Forte uint_t select_id; 4860*fcf3ce44SJohn Forte 4861*fcf3ce44SJohn Forte if ((path_struct == NULL) || (l_state == NULL)) { 4862*fcf3ce44SJohn Forte return (L_INVALID_PATH_FORMAT); 4863*fcf3ce44SJohn Forte } 4864*fcf3ce44SJohn Forte 4865*fcf3ce44SJohn Forte /* Double check to see if we need to calculate. */ 4866*fcf3ce44SJohn Forte if (path_struct->slot_valid) 4867*fcf3ce44SJohn Forte return (0); 4868*fcf3ce44SJohn Forte 4869*fcf3ce44SJohn Forte /* Programming error if this occures */ 4870*fcf3ce44SJohn Forte assert(path_struct->ib_path_flag == 0); 4871*fcf3ce44SJohn Forte 4872*fcf3ce44SJohn Forte if (strstr(path_struct->p_physical_path, "ssd") == NULL) { 4873*fcf3ce44SJohn Forte return (L_INVLD_PHYS_PATH_TO_DISK); 4874*fcf3ce44SJohn Forte } 4875*fcf3ce44SJohn Forte if (err = g_get_wwn(path_struct->p_physical_path, port_wwn, node_wwn, 4876*fcf3ce44SJohn Forte &al_pa, verbose)) { 4877*fcf3ce44SJohn Forte return (err); 4878*fcf3ce44SJohn Forte } 4879*fcf3ce44SJohn Forte 4880*fcf3ce44SJohn Forte /* 4881*fcf3ce44SJohn Forte * Find the slot by searching for the matching hard address. 4882*fcf3ce44SJohn Forte * Take only the low order byte ignoring area and domain code in 4883*fcf3ce44SJohn Forte * fabric devices' 24 bit al_pa 4884*fcf3ce44SJohn Forte */ 4885*fcf3ce44SJohn Forte select_id = g_sf_alpa_to_switch[al_pa & 0xFF]; 4886*fcf3ce44SJohn Forte P_DPRINTF(" l_get_slot: Searching Receive Diagnostic page 2, " 4887*fcf3ce44SJohn Forte "to find the slot number with this ID:0x%x\n", 4888*fcf3ce44SJohn Forte select_id); 4889*fcf3ce44SJohn Forte 4890*fcf3ce44SJohn Forte for (slot = 0; slot < l_state->total_num_drv/2; slot++) { 4891*fcf3ce44SJohn Forte if (l_state->drv_front[slot].ib_status.sel_id == 4892*fcf3ce44SJohn Forte select_id) { 4893*fcf3ce44SJohn Forte path_struct->f_flag = 1; 4894*fcf3ce44SJohn Forte found = 1; 4895*fcf3ce44SJohn Forte break; 4896*fcf3ce44SJohn Forte } else if (l_state->drv_rear[slot].ib_status.sel_id == 4897*fcf3ce44SJohn Forte select_id) { 4898*fcf3ce44SJohn Forte path_struct->f_flag = 0; 4899*fcf3ce44SJohn Forte found = 1; 4900*fcf3ce44SJohn Forte break; 4901*fcf3ce44SJohn Forte } 4902*fcf3ce44SJohn Forte } 4903*fcf3ce44SJohn Forte if (!found) { 4904*fcf3ce44SJohn Forte return (L_INVALID_SLOT); /* Failure */ 4905*fcf3ce44SJohn Forte } 4906*fcf3ce44SJohn Forte if ((strncmp((char *)l_state->ib_tbl.config.prod_id, DAK_OFF_NAME, 4907*fcf3ce44SJohn Forte strlen(DAK_OFF_NAME)) == 0) || 4908*fcf3ce44SJohn Forte (strncmp((char *)l_state->ib_tbl.config.prod_id, DAK_PROD_STR, 4909*fcf3ce44SJohn Forte strlen(DAK_OFF_NAME)) == 0)) { 4910*fcf3ce44SJohn Forte P_DPRINTF(" l_get_slot: Found slot %d.\n", 4911*fcf3ce44SJohn Forte path_struct->f_flag ? slot : slot + (MAX_DRIVES_DAK/2)); 4912*fcf3ce44SJohn Forte } else { 4913*fcf3ce44SJohn Forte P_DPRINTF(" l_get_slot: Found slot %d %s.\n", slot, 4914*fcf3ce44SJohn Forte path_struct->f_flag ? "Front" : "Rear"); 4915*fcf3ce44SJohn Forte } 4916*fcf3ce44SJohn Forte path_struct->slot = slot; 4917*fcf3ce44SJohn Forte path_struct->slot_valid = 1; 4918*fcf3ce44SJohn Forte return (0); 4919*fcf3ce44SJohn Forte } 4920*fcf3ce44SJohn Forte 4921*fcf3ce44SJohn Forte 4922*fcf3ce44SJohn Forte void 4923*fcf3ce44SJohn Forte l_element_msg_string(uchar_t code, char *es) 4924*fcf3ce44SJohn Forte { 4925*fcf3ce44SJohn Forte if (code == S_OK) { 4926*fcf3ce44SJohn Forte (void) sprintf(es, MSGSTR(29, "O.K.")); 4927*fcf3ce44SJohn Forte } else if (code == S_NOT_AVAILABLE) { 4928*fcf3ce44SJohn Forte (void) sprintf(es, MSGSTR(34, "Disabled")); 4929*fcf3ce44SJohn Forte } else if (code == S_NOT_INSTALLED) { 4930*fcf3ce44SJohn Forte (void) sprintf(es, MSGSTR(30, "Not Installed")); 4931*fcf3ce44SJohn Forte } else if (code == S_NONCRITICAL) { 4932*fcf3ce44SJohn Forte (void) sprintf(es, MSGSTR(9059, "Noncritical failure")); 4933*fcf3ce44SJohn Forte } else if (code == S_CRITICAL) { 4934*fcf3ce44SJohn Forte (void) sprintf(es, MSGSTR(122, "Critical failure")); 4935*fcf3ce44SJohn Forte } else { 4936*fcf3ce44SJohn Forte (void) sprintf(es, MSGSTR(4, "Unknown status")); 4937*fcf3ce44SJohn Forte } 4938*fcf3ce44SJohn Forte } 4939*fcf3ce44SJohn Forte 4940*fcf3ce44SJohn Forte 4941*fcf3ce44SJohn Forte /* 4942*fcf3ce44SJohn Forte * Get all ses paths paths to a given box. 4943*fcf3ce44SJohn Forte * The arg should be the physical path to one of the box's IB. 4944*fcf3ce44SJohn Forte * NOTE: The caller must free the allocated lists. 4945*fcf3ce44SJohn Forte * 4946*fcf3ce44SJohn Forte * OUTPUT: 4947*fcf3ce44SJohn Forte * a pointer to a list of ses paths if found 4948*fcf3ce44SJohn Forte * NULL on error. 4949*fcf3ce44SJohn Forte * 4950*fcf3ce44SJohn Forte * RETURNS: 4951*fcf3ce44SJohn Forte * 0 if O.K. 4952*fcf3ce44SJohn Forte * non-zero otherwise 4953*fcf3ce44SJohn Forte */ 4954*fcf3ce44SJohn Forte int 4955*fcf3ce44SJohn Forte l_get_allses(char *path, struct box_list_struct *box_list, 4956*fcf3ce44SJohn Forte struct dlist **ses_list, int verbose) 4957*fcf3ce44SJohn Forte { 4958*fcf3ce44SJohn Forte struct box_list_struct *box_list_ptr; 4959*fcf3ce44SJohn Forte char node_wwn_s[WWN_S_LEN]; 4960*fcf3ce44SJohn Forte struct dlist *dlt, *dl; 4961*fcf3ce44SJohn Forte 4962*fcf3ce44SJohn Forte if ((path == NULL) || (box_list == NULL) || (ses_list == NULL)) { 4963*fcf3ce44SJohn Forte return (L_INVALID_PATH_FORMAT); 4964*fcf3ce44SJohn Forte } 4965*fcf3ce44SJohn Forte 4966*fcf3ce44SJohn Forte /* Initialize lists/arrays */ 4967*fcf3ce44SJohn Forte *ses_list = dlt = dl = (struct dlist *)NULL; 4968*fcf3ce44SJohn Forte node_wwn_s[0] = '\0'; 4969*fcf3ce44SJohn Forte 4970*fcf3ce44SJohn Forte H_DPRINTF(" l_get_allses: Looking for all ses paths for" 4971*fcf3ce44SJohn Forte " box at path: %s\n", path); 4972*fcf3ce44SJohn Forte 4973*fcf3ce44SJohn Forte for (box_list_ptr = box_list; box_list_ptr != NULL; 4974*fcf3ce44SJohn Forte box_list_ptr = box_list_ptr->box_next) { 4975*fcf3ce44SJohn Forte H_DPRINTF(" l_get_allses: physical_path= %s\n", 4976*fcf3ce44SJohn Forte box_list_ptr->b_physical_path); 4977*fcf3ce44SJohn Forte if (strcmp(path, box_list_ptr->b_physical_path) == 0) { 4978*fcf3ce44SJohn Forte (void) strcpy(node_wwn_s, box_list_ptr->b_node_wwn_s); 4979*fcf3ce44SJohn Forte break; 4980*fcf3ce44SJohn Forte } 4981*fcf3ce44SJohn Forte } 4982*fcf3ce44SJohn Forte if (node_wwn_s[0] == '\0') { 4983*fcf3ce44SJohn Forte H_DPRINTF("node_wwn_s is NULL!\n"); 4984*fcf3ce44SJohn Forte return (L_NO_NODE_WWN_IN_BOXLIST); 4985*fcf3ce44SJohn Forte } 4986*fcf3ce44SJohn Forte H_DPRINTF(" l_get_allses: node_wwn=%s\n", node_wwn_s); 4987*fcf3ce44SJohn Forte for (box_list_ptr = box_list; box_list_ptr != NULL; 4988*fcf3ce44SJohn Forte box_list_ptr = box_list_ptr->box_next) { 4989*fcf3ce44SJohn Forte if (strcmp(node_wwn_s, box_list_ptr->b_node_wwn_s) == 0) { 4990*fcf3ce44SJohn Forte if ((dl = (struct dlist *) 4991*fcf3ce44SJohn Forte g_zalloc(sizeof (struct dlist))) == NULL) { 4992*fcf3ce44SJohn Forte while (*ses_list != NULL) { 4993*fcf3ce44SJohn Forte dl = dlt->next; 4994*fcf3ce44SJohn Forte (void) g_destroy_data(dlt); 4995*fcf3ce44SJohn Forte dlt = dl; 4996*fcf3ce44SJohn Forte } 4997*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 4998*fcf3ce44SJohn Forte } 4999*fcf3ce44SJohn Forte H_DPRINTF(" l_get_allses: Found ses=%s\n", 5000*fcf3ce44SJohn Forte box_list_ptr->b_physical_path); 5001*fcf3ce44SJohn Forte dl->dev_path = strdup(box_list_ptr->b_physical_path); 5002*fcf3ce44SJohn Forte dl->logical_path = strdup(box_list_ptr->logical_path); 5003*fcf3ce44SJohn Forte if (*ses_list == NULL) { 5004*fcf3ce44SJohn Forte *ses_list = dlt = dl; 5005*fcf3ce44SJohn Forte } else { 5006*fcf3ce44SJohn Forte dlt->next = dl; 5007*fcf3ce44SJohn Forte dl->prev = dlt; 5008*fcf3ce44SJohn Forte dlt = dl; 5009*fcf3ce44SJohn Forte } 5010*fcf3ce44SJohn Forte } 5011*fcf3ce44SJohn Forte } 5012*fcf3ce44SJohn Forte 5013*fcf3ce44SJohn Forte return (0); 5014*fcf3ce44SJohn Forte } 5015*fcf3ce44SJohn Forte 5016*fcf3ce44SJohn Forte /* 5017*fcf3ce44SJohn Forte * Routine to return the enclosure type pointed to by the path. 5018*fcf3ce44SJohn Forte * Inputs: The inquiry data for the device in question 5019*fcf3ce44SJohn Forte * 5020*fcf3ce44SJohn Forte * Return: >= 0 is the type: 5021*fcf3ce44SJohn Forte * 5022*fcf3ce44SJohn Forte * Types are defined in storage/libg_fc/common/hdrs/g_state.h: 5023*fcf3ce44SJohn Forte * 5024*fcf3ce44SJohn Forte * 0 -> default (SENA) 5025*fcf3ce44SJohn Forte * 1 -> Daktari 5026*fcf3ce44SJohn Forte * 2 -> Other Enclosures 5027*fcf3ce44SJohn Forte * 5028*fcf3ce44SJohn Forte */ 5029*fcf3ce44SJohn Forte int 5030*fcf3ce44SJohn Forte l_get_enc_type(L_inquiry inq) 5031*fcf3ce44SJohn Forte { 5032*fcf3ce44SJohn Forte if (strncmp((char *)&inq.inq_pid[0], ENCLOSURE_PROD_ID, 5033*fcf3ce44SJohn Forte strlen(ENCLOSURE_PROD_ID)) == 0) { 5034*fcf3ce44SJohn Forte return (SENA_ENC_TYPE); 5035*fcf3ce44SJohn Forte } 5036*fcf3ce44SJohn Forte if (strncmp((char *)&inq.inq_pid[0], DAK_OFF_NAME, 5037*fcf3ce44SJohn Forte strlen(DAK_OFF_NAME)) == 0) { 5038*fcf3ce44SJohn Forte return (DAK_ENC_TYPE); 5039*fcf3ce44SJohn Forte } 5040*fcf3ce44SJohn Forte if (strncmp((char *)&inq.inq_pid[0], DAK_PROD_STR, 5041*fcf3ce44SJohn Forte strlen(DAK_PROD_STR)) == 0) { 5042*fcf3ce44SJohn Forte return (DAK_ENC_TYPE); 5043*fcf3ce44SJohn Forte } 5044*fcf3ce44SJohn Forte /* 5045*fcf3ce44SJohn Forte * ADD OTHERS here if ever needed/wanted, and add to def's 5046*fcf3ce44SJohn Forte * as noted above 5047*fcf3ce44SJohn Forte */ 5048*fcf3ce44SJohn Forte return (UNDEF_ENC_TYPE); 5049*fcf3ce44SJohn Forte } 5050*fcf3ce44SJohn Forte 5051*fcf3ce44SJohn Forte void 5052*fcf3ce44SJohn Forte free_mp_dev_map(gfc_map_mp_t **map_mp_ptr) { 5053*fcf3ce44SJohn Forte gfc_map_mp_t *next = NULL; 5054*fcf3ce44SJohn Forte 5055*fcf3ce44SJohn Forte for (; *map_mp_ptr != NULL; *map_mp_ptr = next) { 5056*fcf3ce44SJohn Forte next = (*map_mp_ptr)->map_next; 5057*fcf3ce44SJohn Forte (void) g_destroy_data((*map_mp_ptr)->map.dev_addr); 5058*fcf3ce44SJohn Forte (void) g_destroy_data(*map_mp_ptr); 5059*fcf3ce44SJohn Forte } 5060*fcf3ce44SJohn Forte *map_mp_ptr = NULL; 5061*fcf3ce44SJohn Forte } 5062*fcf3ce44SJohn Forte /* 5063*fcf3ce44SJohn Forte * This function will return a linked list of device maps 5064*fcf3ce44SJohn Forte * An example of when this will be used is when we want to return the device 5065*fcf3ce44SJohn Forte * map of a vhci path. 5066*fcf3ce44SJohn Forte */ 5067*fcf3ce44SJohn Forte 5068*fcf3ce44SJohn Forte int 5069*fcf3ce44SJohn Forte get_mp_dev_map(char *path, gfc_map_mp_t **map_mp_ptr, int verbose) { 5070*fcf3ce44SJohn Forte 5071*fcf3ce44SJohn Forte int pathcnt, i, err; 5072*fcf3ce44SJohn Forte mp_pathlist_t pathlist; 5073*fcf3ce44SJohn Forte gfc_map_mp_t *new_map_mp_ptr; 5074*fcf3ce44SJohn Forte char drvr_path[MAXPATHLEN]; 5075*fcf3ce44SJohn Forte if (strstr(path, SCSI_VHCI)) { 5076*fcf3ce44SJohn Forte if (g_get_pathlist(path, &pathlist)) { 5077*fcf3ce44SJohn Forte return (L_INVALID_PATH); 5078*fcf3ce44SJohn Forte } 5079*fcf3ce44SJohn Forte pathcnt = pathlist.path_count; 5080*fcf3ce44SJohn Forte for (i = 0; i < pathcnt; i++) { 5081*fcf3ce44SJohn Forte if (pathlist.path_info[i].path_state < MAXPATHSTATE) { 5082*fcf3ce44SJohn Forte /* 5083*fcf3ce44SJohn Forte * only pay attention to paths that are either 5084*fcf3ce44SJohn Forte * ONLINE or STANDBY 5085*fcf3ce44SJohn Forte */ 5086*fcf3ce44SJohn Forte if ((pathlist.path_info[i].path_state == 5087*fcf3ce44SJohn Forte MDI_PATHINFO_STATE_ONLINE) || 5088*fcf3ce44SJohn Forte (pathlist.path_info[i].path_state == 5089*fcf3ce44SJohn Forte MDI_PATHINFO_STATE_STANDBY)) { 5090*fcf3ce44SJohn Forte if ((new_map_mp_ptr = (gfc_map_mp_t *) 5091*fcf3ce44SJohn Forte g_zalloc(sizeof (gfc_map_mp_t))) 5092*fcf3ce44SJohn Forte == NULL) { 5093*fcf3ce44SJohn Forte free(pathlist.path_info); 5094*fcf3ce44SJohn Forte free_mp_dev_map(map_mp_ptr); 5095*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 5096*fcf3ce44SJohn Forte } 5097*fcf3ce44SJohn Forte (void) strcpy(drvr_path, 5098*fcf3ce44SJohn Forte pathlist.path_info[i].path_hba); 5099*fcf3ce44SJohn Forte (void) strcat(drvr_path, FC_CTLR); 5100*fcf3ce44SJohn Forte if (err = g_get_dev_map(drvr_path, 5101*fcf3ce44SJohn Forte &(new_map_mp_ptr->map), 5102*fcf3ce44SJohn Forte verbose)) { 5103*fcf3ce44SJohn Forte free(pathlist.path_info); 5104*fcf3ce44SJohn Forte free_mp_dev_map(map_mp_ptr); 5105*fcf3ce44SJohn Forte return (err); 5106*fcf3ce44SJohn Forte } 5107*fcf3ce44SJohn Forte /* add newly created map onto list */ 5108*fcf3ce44SJohn Forte if (*map_mp_ptr == NULL) { 5109*fcf3ce44SJohn Forte new_map_mp_ptr->map_next = NULL; 5110*fcf3ce44SJohn Forte *map_mp_ptr = new_map_mp_ptr; 5111*fcf3ce44SJohn Forte } else { 5112*fcf3ce44SJohn Forte new_map_mp_ptr->map_next = 5113*fcf3ce44SJohn Forte *map_mp_ptr; 5114*fcf3ce44SJohn Forte *map_mp_ptr = new_map_mp_ptr; 5115*fcf3ce44SJohn Forte } 5116*fcf3ce44SJohn Forte } 5117*fcf3ce44SJohn Forte } 5118*fcf3ce44SJohn Forte } 5119*fcf3ce44SJohn Forte free(pathlist.path_info); 5120*fcf3ce44SJohn Forte } else { 5121*fcf3ce44SJohn Forte if ((new_map_mp_ptr = (gfc_map_mp_t *)g_zalloc 5122*fcf3ce44SJohn Forte (sizeof (gfc_map_mp_t))) == NULL) { 5123*fcf3ce44SJohn Forte return (L_MALLOC_FAILED); 5124*fcf3ce44SJohn Forte } 5125*fcf3ce44SJohn Forte g_get_dev_map(path, &(new_map_mp_ptr->map), verbose); 5126*fcf3ce44SJohn Forte *map_mp_ptr = new_map_mp_ptr; 5127*fcf3ce44SJohn Forte } 5128*fcf3ce44SJohn Forte return (0); 5129*fcf3ce44SJohn Forte } 5130