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
l_get_mode_pg(char * path,uchar_t ** pg_buf,int verbose)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
l_format_ifp_status_msg(char * status_msg_buf,int count,int status)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
l_format_fc_status_msg(char * status_msg_buf,int count,int status)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
l_get_disk_element_index(struct l_state_struct * l_state,int * front_index,int * rear_index)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
l_led(struct path_struct * path_struct,int led_action,struct device_element * status,int verbose)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
l_free_lstate(L_state ** l_state)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
l_dev_pwr_up_down(char * path_phys,struct path_struct * path_struct,int power_off_flag,int verbose,int force_flag)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
l_pho_pwr_up_down(char * dev_name,char * path_phys,int power_off_flag,int verbose,int force_flag)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
pwr_up_down(char * path_phys,L_state * l_state,int front,int slot,int power_off_flag,int verbose)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
l_new_password(char * path_phys,char * password)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
l_new_name(char * path_phys,char * name)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
l_enable(char * path,int verbose)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
l_bypass(char * path,int verbose)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
l_get_box_list(struct box_list_struct ** box_list_ptr,int verbose)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
l_free_box_list(struct box_list_struct ** box_list)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
l_duplicate_names(Box_list * b_list,char wwn[],char * name,int verbose)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
l_get_conflict(char * name,char ** result,int verbose)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
load_flds_if_enc_disk(char * phys_path,struct path_struct ** path_struct)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
l_convert_name(char * name,char ** phys_path,struct path_struct ** path_struct,int verbose)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
l_get_envsen_page(int fd,uchar_t * buf,int buf_size,uchar_t page_code,int verbose)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
l_get_envsen(char * path_phys,uchar_t * buf,int size,int verbose)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
l_get_disk_status(char * path,struct l_disk_state_struct * l_disk_state,WWN_list * wwn_list,int verbose)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
l_persistent_check(int fd,struct l_disk_state_struct * l_disk_state,int verbose)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
l_get_disk_port_status(char * path,struct l_disk_state_struct * l_disk_state,int port_a_flag,int verbose)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
copy_config_page(struct l_state_struct * l_state,uchar_t * from_ptr)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
copy_page_7(struct l_state_struct * l_state,uchar_t * from_ptr)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
l_get_ib_status(char * path,struct l_state_struct * l_state,int verbose)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
l_get_port(char * ses_path,int * port_a,int verbose)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
l_get_pid_from_path(const char * path,const gfc_map_t * map,int * pid)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
l_get_node_status(char * path,struct l_disk_state_struct * state,int * found_flag,WWN_list * wwn_list,int verbose)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
l_get_individual_state(char * path,struct l_disk_state_struct * state,Ib_state * ib_state,int front_flag,struct box_list_struct * box_list,struct wwn_list_struct * wwn_list,int verbose)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
l_get_status(char * path,struct l_state_struct * l_state,int verbose)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
check_file(int fd,int verbose,uchar_t ** buf_ptr,int dl_info_offset)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
check_dpm_file(int fd)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
l_check_file(char * file,int verbose)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
ib_download_code_cmd(int fd,int promid,int off,uchar_t * buf_ptr,int buf_len,int sp)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
dak_download_code_cmd(int fd,uchar_t * buf_ptr,int buf_len)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
l_download(char * path_phys,char * file,int ps,int verbose)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
l_set_wwn(char * path_phys,char * wwn)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
l_get_ses_path(char * path_phys,char * ses_path,gfc_map_t * map,int verbose)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
l_get_slot(struct path_struct * path_struct,L_state * l_state,int verbose)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
l_element_msg_string(uchar_t code,char * es)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
l_get_allses(char * path,struct box_list_struct * box_list,struct dlist ** ses_list,int verbose)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
l_get_enc_type(L_inquiry inq)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
free_mp_dev_map(gfc_map_mp_t ** map_mp_ptr)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
get_mp_dev_map(char * path,gfc_map_mp_t ** map_mp_ptr,int verbose)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