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