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