2 * Copyright (c) 2008, 2009 Yahoo!, Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The names of the authors may not be used to endorse or promote
14 * products derived from this software without specific prior written
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/types.h>
33 #include <sys/errno.h>
44 adapter_time(time_t now
, uint32_t at_now
, uint32_t at
)
48 t
= (now
- at_now
) + at
;
53 mfi_get_time(int fd
, uint32_t *at
)
56 if (mfi_dcmd_command(fd
, MFI_DCMD_TIME_SECS_GET
, at
, sizeof(*at
), NULL
,
58 warn("Couldn't fetch adapter time");
64 patrol_get_props(int fd
, struct mfi_pr_properties
*prop
)
68 if (mfi_dcmd_command(fd
, MFI_DCMD_PR_GET_PROPERTIES
, prop
,
69 sizeof(*prop
), NULL
, 0, NULL
) < 0) {
71 warn("Failed to get patrol read properties");
78 show_patrol(int ac __unused
, char **av __unused
)
80 struct mfi_pr_properties prop
;
81 struct mfi_pr_status status
;
82 struct mfi_pd_list
*list
;
83 struct mfi_pd_info info
;
90 fd
= mfi_open(mfi_unit
, O_RDWR
);
98 mfi_get_time(fd
, &at
);
99 error
= patrol_get_props(fd
, &prop
);
104 printf("Operation Mode: ");
105 switch (prop
.op_mode
) {
106 case MFI_PR_OPMODE_AUTO
:
109 case MFI_PR_OPMODE_MANUAL
:
112 case MFI_PR_OPMODE_DISABLED
:
113 printf("disabled\n");
116 printf("??? (%02x)\n", prop
.op_mode
);
119 if (prop
.op_mode
== MFI_PR_OPMODE_AUTO
) {
120 if (at
!= 0 && prop
.next_exec
)
121 printf(" Next Run Starts: %s", adapter_time(now
, at
,
123 if (prop
.exec_freq
== 0xffffffff)
124 printf(" Runs Execute Continuously\n");
125 else if (prop
.exec_freq
!= 0)
126 printf(" Runs Start Every %u seconds\n",
130 if (mfi_dcmd_command(fd
, MFI_DCMD_PR_GET_STATUS
, &status
,
131 sizeof(status
), NULL
, 0, NULL
) < 0) {
133 warn("Failed to get patrol read properties");
137 printf("Runs Completed: %u\n", status
.num_iteration
);
138 printf("Current State: ");
139 switch (status
.state
) {
140 case MFI_PR_STATE_STOPPED
:
143 case MFI_PR_STATE_READY
:
146 case MFI_PR_STATE_ACTIVE
:
149 case MFI_PR_STATE_ABORTED
:
153 printf("??? (%02x)\n", status
.state
);
156 if (status
.state
== MFI_PR_STATE_ACTIVE
) {
157 if (mfi_pd_get_list(fd
, &list
, NULL
) < 0) {
159 warn("Failed to get drive list");
164 for (i
= 0; i
< list
->count
; i
++) {
165 if (list
->addr
[i
].scsi_dev_type
!= 0)
168 if (mfi_pd_get_info(fd
, list
->addr
[i
].device_id
, &info
,
171 warn("Failed to fetch info for drive %u",
172 list
->addr
[i
].device_id
);
177 if (info
.prog_info
.active
& MFI_PD_PROGRESS_PATROL
) {
178 snprintf(label
, sizeof(label
), " Drive %s",
180 list
->addr
[i
].device_id
,
181 MFI_DNAME_DEVICE_ID
|MFI_DNAME_HONOR_OPTS
));
182 mfi_display_progress(label
,
183 &info
.prog_info
.patrol
);
193 MFI_COMMAND(show
, patrol
, show_patrol
);
196 start_patrol(int ac __unused
, char **av __unused
)
200 fd
= mfi_open(mfi_unit
, O_RDWR
);
207 if (mfi_dcmd_command(fd
, MFI_DCMD_PR_START
, NULL
, 0, NULL
, 0, NULL
) <
210 warn("Failed to start patrol read");
219 MFI_COMMAND(start
, patrol
, start_patrol
);
222 stop_patrol(int ac __unused
, char **av __unused
)
226 fd
= mfi_open(mfi_unit
, O_RDWR
);
233 if (mfi_dcmd_command(fd
, MFI_DCMD_PR_STOP
, NULL
, 0, NULL
, 0, NULL
) <
236 warn("Failed to stop patrol read");
245 MFI_COMMAND(stop
, patrol
, stop_patrol
);
248 patrol_config(int ac
, char **av
)
250 struct mfi_pr_properties prop
;
254 uint32_t at
, next_exec
, exec_freq
;
258 exec_freq
= 0; /* GCC too stupid */
261 warnx("patrol: command required");
264 if (strcasecmp(av
[1], "auto") == 0) {
265 op_mode
= MFI_PR_OPMODE_AUTO
;
267 if (strcasecmp(av
[2], "continuously") == 0)
268 exec_freq
= 0xffffffff;
270 val
= strtol(av
[2], &cp
, 0);
272 warnx("patrol: Invalid interval %s",
280 val
= strtol(av
[3], &cp
, 0);
281 if (*cp
!= '\0' || val
< 0) {
282 warnx("patrol: Invalid start time %s", av
[3]);
287 } else if (strcasecmp(av
[1], "manual") == 0)
288 op_mode
= MFI_PR_OPMODE_MANUAL
;
289 else if (strcasecmp(av
[1], "disable") == 0)
290 op_mode
= MFI_PR_OPMODE_DISABLED
;
292 warnx("patrol: Invalid command %s", av
[1]);
296 fd
= mfi_open(mfi_unit
, O_RDWR
);
303 error
= patrol_get_props(fd
, &prop
);
308 prop
.op_mode
= op_mode
;
309 if (op_mode
== MFI_PR_OPMODE_AUTO
) {
311 prop
.exec_freq
= exec_freq
;
314 mfi_get_time(fd
, &at
);
319 prop
.next_exec
= at
+ next_exec
;
320 printf("Starting next patrol read at %s",
321 adapter_time(now
, at
, prop
.next_exec
));
324 if (mfi_dcmd_command(fd
, MFI_DCMD_PR_SET_PROPERTIES
, &prop
,
325 sizeof(prop
), NULL
, 0, NULL
) < 0) {
327 warn("Failed to set patrol read properties");
336 MFI_COMMAND(top
, patrol
, patrol_config
);