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