4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1994, 2000 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include "mhd_local.h"
35 * manipulate failfast driver
49 MHDPRINTF1(("%s: disarm\n", sp
->sr_name
));
52 assert(MUTEX_HELD(&sp
->sr_mx
));
58 /* disarm any existing failfast */
59 (void) memset(&si
, 0, sizeof (si
));
60 si
.ic_cmd
= FAILFAST_DISARM
;
61 si
.ic_timout
= INFTIM
;
62 if (ioctl(sp
->sr_ff
, I_STR
, &si
) != 0)
63 return (mhd_error(mhep
, errno
, "/dev/ff"));
81 assert(MUTEX_HELD(&sp
->sr_mx
));
82 assert((sp
->sr_ff_mode
== MHD_FF_DEBUG
) ||
83 (sp
->sr_ff_mode
== MHD_FF_HALT
) ||
84 (sp
->sr_ff_mode
== MHD_FF_PANIC
));
86 /* open if not already */
87 if ((sp
->sr_ff
< 0) &&
88 ((sp
->sr_ff
= open("/dev/ff", O_RDWR
, 0)) < 0)) {
89 return (mhd_error(mhep
, errno
, "/dev/ff"));
92 /* disarm any existing failfast */
93 if (mhd_ff_disarm(sp
, mhep
) != 0)
97 (void) memset(&si
, 0, sizeof (si
));
98 si
.ic_cmd
= FAILFAST_SETNAME
;
99 si
.ic_timout
= INFTIM
;
100 si
.ic_len
= strlen(sp
->sr_name
);
101 si
.ic_dp
= sp
->sr_name
;
102 if (ioctl(sp
->sr_ff
, I_STR
, &si
) != 0)
103 return (mhd_error(mhep
, errno
, "/dev/ff"));
105 /* load failfast mode */
106 (void) memset(&si
, 0, sizeof (si
));
107 switch (sp
->sr_ff_mode
) {
109 si
.ic_cmd
= FAILFAST_DEBUG_MODE
;
112 si
.ic_cmd
= FAILFAST_HALT_MODE
;
118 si
.ic_cmd
= FAILFAST_PANIC_MODE
;
121 si
.ic_timout
= INFTIM
;
122 if (ioctl(sp
->sr_ff
, I_STR
, &si
) != 0)
123 return (mhd_error(mhep
, errno
, "/dev/ff"));
141 assert(MUTEX_HELD(&sp
->sr_mx
));
143 /* ignore not open */
147 /* disarm any existing failfast */
148 if (mhd_ff_disarm(sp
, mhep
) != 0)
152 if (close(sp
->sr_ff
) != 0)
153 rval
= mhd_error(mhep
, errno
, "/dev/ff");
169 uint_t ff
= sp
->sr_timeouts
.mh_ff
;
172 MHDPRINTF1(("%s: rearm\n", sp
->sr_name
));
175 assert(MUTEX_HELD(&sp
->sr_mx
));
176 assert(sp
->sr_ff
>= 0);
178 /* if timeout is 0, disarm */
180 return (mhd_ff_disarm(sp
, mhep
));
183 (void) memset(&si
, 0, sizeof (si
));
184 si
.ic_cmd
= FAILFAST_ARM
;
185 si
.ic_timout
= INFTIM
;
186 si
.ic_len
= sizeof (ff
);
187 si
.ic_dp
= (char *)&ff
;
188 if (ioctl(sp
->sr_ff
, I_STR
, &si
) != 0)
189 return (mhd_error(mhep
, errno
, "/dev/ff"));
206 MHDPRINTF(("%s: die\n", sp
->sr_name
));
209 assert(MUTEX_HELD(&sp
->sr_mx
));
210 assert(sp
->sr_ff
>= 0);
212 /* rearm failfast for now */
213 (void) memset(&si
, 0, sizeof (si
));
214 si
.ic_cmd
= FAILFAST_ARM
;
215 si
.ic_timout
= INFTIM
;
216 si
.ic_len
= sizeof (ff
);
217 si
.ic_dp
= (char *)&ff
;
218 if (ioctl(sp
->sr_ff
, I_STR
, &si
) != 0)
219 mhd_perror("/dev/ff");
223 * check set and reset failfast
230 mhd_drive_list_t
*dlp
= &sp
->sr_drives
;
231 mhd_msec_t ff
= sp
->sr_timeouts
.mh_ff
;
232 mhd_msec_t now
= mhd_time();
236 assert(MUTEX_HELD(&sp
->sr_mx
));
237 assert(sp
->sr_ff
>= 0);
238 assert((sp
->sr_ff_mode
== MHD_FF_DEBUG
) ||
239 (sp
->sr_ff_mode
== MHD_FF_HALT
) ||
240 (sp
->sr_ff_mode
== MHD_FF_PANIC
));
242 /* see how many drives are within alloted time */
243 for (ok
= cnt
= 0, i
= 0; (i
< dlp
->dl_ndrive
); ++i
) {
244 mhd_drive_t
*dp
= dlp
->dl_drives
[i
];
246 if (dp
->dr_state
!= DRIVE_PROBING
)
250 MHDPRINTF2(("%s: now %llu dr_time %llu diff %llu ff %llu\n",
251 dp
->dr_rname
, now
, dp
->dr_time
, (now
- dp
->dr_time
), ff
));
252 if ((now
- dp
->dr_time
) <= ff
)
256 /* check for majority */
257 if ((cnt
== 0) || (ok
>= ((cnt
/ 2) + 1))) {
258 mhd_error_t status
= mhd_null_error
;
260 if (mhd_ff_rearm(sp
, &status
) == 0)
262 mhd_clrerror(&status
);
266 mhd_eprintf("%s: failed majority cnt %d ok %d\n",
267 sp
->sr_name
, cnt
, ok
);