2 * Copyright (c) 2000 - 2006 Søren Schmidt <sos@FreeBSD.org>
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 * without modification, immediately at the beginning of the file.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * $FreeBSD: src/sbin/atacontrol/atacontrol.c,v 1.42 2006/03/15 19:32:43 sos Exp $
44 switch (mode
& 0xff) {
45 case ATA_PIO
: return "BIOSPIO";
46 case ATA_PIO0
: return "PIO0";
47 case ATA_PIO1
: return "PIO1";
48 case ATA_PIO2
: return "PIO2";
49 case ATA_PIO3
: return "PIO3";
50 case ATA_PIO4
: return "PIO4";
51 case ATA_WDMA0
: return "WDMA0";
52 case ATA_WDMA1
: return "WDMA1";
53 case ATA_WDMA2
: return "WDMA2";
54 case ATA_UDMA0
: return "UDMA0";
55 case ATA_UDMA1
: return "UDMA1";
56 case ATA_UDMA2
: return "UDMA33";
57 case ATA_UDMA3
: return "UDMA44";
58 case ATA_UDMA4
: return "UDMA66";
59 case ATA_UDMA5
: return "UDMA100";
60 case ATA_UDMA6
: return "UDMA133";
61 case ATA_SA150
: return "SATA150";
62 case ATA_SA300
: return "SATA300";
63 case ATA_USB
: return "USB";
64 case ATA_USB1
: return "USB1";
65 case ATA_USB2
: return "USB2";
66 case ATA_DMA
: return "BIOSDMA";
67 default: return "???";
74 switch ((mode
& 0xff00) >> 8) {
76 case 1: return "SATA 1.5Gb/s";
77 case 2: return "SATA 3Gb/s";
78 case 3: return "SATA 6Gb/s";
79 case 0xff: return "SATA";
80 default: return "???";
87 if (!strcasecmp(str
, "BIOSPIO")) return ATA_PIO
;
88 if (!strcasecmp(str
, "PIO0")) return ATA_PIO0
;
89 if (!strcasecmp(str
, "PIO1")) return ATA_PIO1
;
90 if (!strcasecmp(str
, "PIO2")) return ATA_PIO2
;
91 if (!strcasecmp(str
, "PIO3")) return ATA_PIO3
;
92 if (!strcasecmp(str
, "PIO4")) return ATA_PIO4
;
93 if (!strcasecmp(str
, "WDMA0")) return ATA_WDMA0
;
94 if (!strcasecmp(str
, "WDMA1")) return ATA_WDMA1
;
95 if (!strcasecmp(str
, "WDMA2")) return ATA_WDMA2
;
96 if (!strcasecmp(str
, "UDMA0")) return ATA_UDMA0
;
97 if (!strcasecmp(str
, "UDMA16")) return ATA_UDMA0
;
98 if (!strcasecmp(str
, "UDMA1")) return ATA_UDMA1
;
99 if (!strcasecmp(str
, "UDMA25")) return ATA_UDMA1
;
100 if (!strcasecmp(str
, "UDMA2")) return ATA_UDMA2
;
101 if (!strcasecmp(str
, "UDMA33")) return ATA_UDMA2
;
102 if (!strcasecmp(str
, "UDMA3")) return ATA_UDMA3
;
103 if (!strcasecmp(str
, "UDMA44")) return ATA_UDMA3
;
104 if (!strcasecmp(str
, "UDMA4")) return ATA_UDMA4
;
105 if (!strcasecmp(str
, "UDMA66")) return ATA_UDMA4
;
106 if (!strcasecmp(str
, "UDMA5")) return ATA_UDMA5
;
107 if (!strcasecmp(str
, "UDMA100")) return ATA_UDMA5
;
108 if (!strcasecmp(str
, "UDMA6")) return ATA_UDMA6
;
109 if (!strcasecmp(str
, "UDMA133")) return ATA_UDMA6
;
110 if (!strcasecmp(str
, "BIOSDMA")) return ATA_DMA
;
118 "usage: natacontrol <command> args:\n"
119 " natacontrol list\n"
120 " natacontrol info channel\n"
121 " natacontrol attach channel\n"
122 " natacontrol detach channel\n"
123 " natacontrol reinit channel\n"
124 " natacontrol create type [interleave] disk0 ... diskN\n"
125 " natacontrol delete array\n"
126 " natacontrol addspare array disk\n"
127 " natacontrol rebuild array\n"
128 " natacontrol status array\n"
129 " natacontrol mode device [mode]\n"
130 " natacontrol feature device apm apmlevel\n"
131 " natacontrol feature device acoustic soundsupplevel\n"
132 " natacontrol cap device\n"
133 " natacontrol spindown device [seconds]\n"
145 for (bit
= 15; bit
>= 0; bit
--)
152 param_print(struct ata_params
*parm
)
154 printf("<%.40s/%.8s> ", parm
->model
, parm
->revision
);
155 if (parm
->satacapabilities
&& parm
->satacapabilities
!= 0xffff) {
156 if (parm
->satacapabilities
& ATA_SATA_GEN2
)
157 printf("SATA revision 2.x\n");
158 else if (parm
->satacapabilities
& ATA_SATA_GEN1
)
159 printf("SATA revision 1.x\n");
161 printf("Unknown SATA revision\n");
164 printf("ATA/ATAPI revision %d\n", version(parm
->version_major
));
168 cap_print(struct ata_params
*parm
)
170 u_int32_t lbasize
= (u_int32_t
)parm
->lba_size_1
|
171 ((u_int32_t
)parm
->lba_size_2
<< 16);
173 u_int64_t lbasize48
= ((u_int64_t
)parm
->lba_size48_1
) |
174 ((u_int64_t
)parm
->lba_size48_2
<< 16) |
175 ((u_int64_t
)parm
->lba_size48_3
<< 32) |
176 ((u_int64_t
)parm
->lba_size48_4
<< 48);
180 if (parm
->satacapabilities
&& parm
->satacapabilities
!= 0xffff) {
181 if (parm
->satacapabilities
& ATA_SATA_GEN2
)
182 printf("SATA revision 2.x\n");
183 else if (parm
->satacapabilities
& ATA_SATA_GEN1
)
184 printf("SATA revision 1.x\n");
186 printf("Unknown SATA revision\n");
189 printf("ATA/ATAPI revision %d\n", version(parm
->version_major
));
190 printf("device model %.40s\n", parm
->model
);
191 printf("serial number %.20s\n", parm
->serial
);
192 printf("firmware revision %.8s\n", parm
->revision
);
194 printf("cylinders %d\n", parm
->cylinders
);
195 printf("heads %d\n", parm
->heads
);
196 printf("sectors/track %d\n", parm
->sectors
);
198 printf("lba%ssupported ",
199 parm
->capabilities1
& ATA_SUPPORT_LBA
? " " : " not ");
201 printf("%d sectors\n", lbasize
);
205 printf("lba48%ssupported ",
206 parm
->support
.command2
& ATA_SUPPORT_ADDRESS48
? " " : " not ");
208 printf("%ju sectors\n", (uintmax_t)lbasize48
);
212 printf("dma%ssupported\n",
213 parm
->capabilities1
& ATA_SUPPORT_DMA
? " " : " not ");
215 printf("overlap%ssupported\n",
216 parm
->capabilities1
& ATA_SUPPORT_OVERLAP
? " " : " not ");
219 "Support Enable Value Vendor\n");
221 printf("write cache %s %s\n",
222 parm
->support
.command1
& ATA_SUPPORT_WRITECACHE
? "yes" : "no",
223 parm
->enabled
.command1
& ATA_SUPPORT_WRITECACHE
? "yes" : "no");
225 printf("read ahead %s %s\n",
226 parm
->support
.command1
& ATA_SUPPORT_LOOKAHEAD
? "yes" : "no",
227 parm
->enabled
.command1
& ATA_SUPPORT_LOOKAHEAD
? "yes" : "no");
229 if (parm
->satacapabilities
&& parm
->satacapabilities
!= 0xffff) {
230 printf("Native Command Queuing (NCQ) %s %s"
232 parm
->satacapabilities
& ATA_SUPPORT_NCQ
?
234 (parm
->satacapabilities
& ATA_SUPPORT_NCQ
) ?
235 ATA_QUEUE_LEN(parm
->queue
) : 0,
236 (parm
->satacapabilities
& ATA_SUPPORT_NCQ
) ?
237 ATA_QUEUE_LEN(parm
->queue
) : 0);
239 printf("Tagged Command Queuing (TCQ) %s %s %d/0x%02X\n",
240 parm
->support
.command2
& ATA_SUPPORT_QUEUED
? "yes" : "no",
241 parm
->enabled
.command2
& ATA_SUPPORT_QUEUED
? "yes" : "no",
242 ATA_QUEUE_LEN(parm
->queue
), ATA_QUEUE_LEN(parm
->queue
));
244 printf("SMART %s %s\n",
245 parm
->support
.command1
& ATA_SUPPORT_SMART
? "yes" : "no",
246 parm
->enabled
.command1
& ATA_SUPPORT_SMART
? "yes" : "no");
248 printf("microcode download %s %s\n",
249 parm
->support
.command2
& ATA_SUPPORT_MICROCODE
? "yes" : "no",
250 parm
->enabled
.command2
& ATA_SUPPORT_MICROCODE
? "yes" : "no");
252 printf("security %s %s\n",
253 parm
->support
.command1
& ATA_SUPPORT_SECURITY
? "yes" : "no",
254 parm
->enabled
.command1
& ATA_SUPPORT_SECURITY
? "yes" : "no");
256 printf("power management %s %s\n",
257 parm
->support
.command1
& ATA_SUPPORT_POWERMGT
? "yes" : "no",
258 parm
->enabled
.command1
& ATA_SUPPORT_POWERMGT
? "yes" : "no");
260 printf("advanced power management %s %s %d/0x%02X\n",
261 parm
->support
.command2
& ATA_SUPPORT_APM
? "yes" : "no",
262 parm
->enabled
.command2
& ATA_SUPPORT_APM
? "yes" : "no",
263 parm
->apm_value
, parm
->apm_value
);
265 printf("automatic acoustic management %s %s "
266 "%d/0x%02X %d/0x%02X\n",
267 parm
->support
.command2
& ATA_SUPPORT_AUTOACOUSTIC
? "yes" :"no",
268 parm
->enabled
.command2
& ATA_SUPPORT_AUTOACOUSTIC
? "yes" :"no",
269 ATA_ACOUSTIC_CURRENT(parm
->acoustic
),
270 ATA_ACOUSTIC_CURRENT(parm
->acoustic
),
271 ATA_ACOUSTIC_VENDOR(parm
->acoustic
),
272 ATA_ACOUSTIC_VENDOR(parm
->acoustic
));
276 ata_cap_print(int fd
)
278 struct ata_params params
;
280 if (ioctl(fd
, IOCATAGPARM
, ¶ms
) < 0)
281 err(1, "ioctl(IOCATAGPARM)");
286 info_print(int fd
, int channel
, int prchan
)
288 struct ata_ioc_devices devices
;
290 devices
.channel
= channel
;
292 if (ioctl(fd
, IOCATADEVICES
, &devices
) < 0) {
294 err(1, "ioctl(IOCATADEVICES)");
298 printf("ATA channel %d:\n", channel
);
299 printf("%sMaster: ", prchan
? " " : "");
300 if (*devices
.name
[0]) {
301 printf("%4.4s ", devices
.name
[0]);
302 param_print(&devices
.params
[0]);
305 printf(" no device present\n");
306 printf("%sSlave: ", prchan
? " " : "");
307 if (*devices
.name
[1]) {
308 printf("%4.4s ", devices
.name
[1]);
309 param_print(&devices
.params
[1]);
312 printf(" no device present\n");
316 ata_spindown(int fd
, const char *dev
, const char *arg
)
321 tmo
= strtoul(arg
, NULL
, 0);
322 if (ioctl(fd
, IOCATASSPINDOWN
, &tmo
) < 0)
323 err(1, "ioctl(IOCATASSPINDOWN)");
325 if (ioctl(fd
, IOCATAGSPINDOWN
, &tmo
) < 0)
326 err(1, "ioctl(IOCATAGSPINDOWN)");
328 printf("%s: idle spin down disabled\n", dev
);
330 printf("%s: spin down after %d seconds idle\n",
336 open_dev(const char *arg
, int mode
)
341 if (!(sscanf(arg
, "ad%d", &disk
) == 1 ||
342 sscanf(arg
, "acd%d", &disk
) == 1 ||
343 sscanf(arg
, "afd%d", &disk
) == 1 ||
344 sscanf(arg
, "ast%d", &disk
) == 1)) {
345 fprintf(stderr
, "natacontrol: Invalid device %s\n", arg
);
348 sprintf(device
, "/dev/%s", arg
);
349 if ((fd
= open(device
, mode
)) < 0)
350 err(1, "device not found");
355 ar_arg(const char *arg
)
359 if (!(sscanf(arg
, "ar%d", &array
) == 1)) {
360 fprintf(stderr
, "natacontrol: Invalid array %s\n", arg
);
367 ata_arg(const char *arg
)
371 if (!(sscanf(arg
, "ata%d", &channel
) == 1)) {
372 fprintf(stderr
, "natacontrol: Invalid channel %s\n", arg
);
379 main(int argc
, char **argv
)
381 int fd
, mode
, channel
, array
;
386 if (!strcmp(argv
[1], "mode") && (argc
== 3 || argc
== 4)) {
387 fd
= open_dev(argv
[2], O_RDONLY
);
389 mode
= str2mode(argv
[3]);
391 errx(1, "unknown mode");
392 if (ioctl(fd
, IOCATASMODE
, &mode
) < 0)
393 warn("ioctl(IOCATASMODE)");
395 if (argc
== 3 || argc
== 4) {
396 if (ioctl(fd
, IOCATAGMODE
, &mode
) < 0)
397 err(1, "ioctl(IOCATAGMODE)");
398 printf("current mode = %s %s\n",
399 mode2str(mode
), satarev2str(mode
));
403 if (!strcmp(argv
[1], "feature") && argc
== 5) {
404 struct ata_ioc_request request
;
406 fd
= open_dev(argv
[2], O_RDONLY
);
408 bzero(&request
, sizeof(struct ata_ioc_request
));
409 request
.u
.ata
.command
= ATA_SETFEATURES
;
410 request
.flags
= ATA_CMD_CONTROL
;
411 request
.timeout
= 500;
412 if (!strcmp(argv
[3], "apm")) {
413 if (!strcmp(argv
[4], "off")) {
414 request
.u
.ata
.feature
= ATA_SF_DIS_APM
;
415 } else if (!strcmp(argv
[4], "maxperf")) {
416 request
.u
.ata
.feature
= ATA_SF_ENAB_APM
;
417 request
.u
.ata
.count
= 0xfe;
418 } else if (!strcmp(argv
[4], "minpower")) {
419 request
.u
.ata
.feature
= ATA_SF_ENAB_APM
;
420 request
.u
.ata
.count
= 0x01;
424 request
.u
.ata
.feature
= ATA_SF_ENAB_APM
;
425 if (argv
[4][0] == 's') {
426 offset
= atoi(&argv
[4][1]);
427 request
.u
.ata
.count
= 0x01;
429 offset
= atoi(&argv
[4][1]);
430 request
.u
.ata
.count
= 0x80;
432 if (offset
>= 0 && offset
<= 127)
433 request
.u
.ata
.count
+= offset
;
435 } else if (!strcmp(argv
[3], "acoustic")) {
436 if (!strcmp(argv
[4], "off")) {
437 request
.u
.ata
.feature
= ATA_SF_DIS_ACCOUS
;
438 } else if (!strcmp(argv
[4], "maxperf")) {
439 request
.u
.ata
.feature
= ATA_SF_ENAB_ACCOUS
;
440 request
.u
.ata
.count
= 0xfe;
441 } else if (!strcmp(argv
[4], "maxquiet")) {
442 request
.u
.ata
.feature
= ATA_SF_ENAB_ACCOUS
;
443 request
.u
.ata
.count
= 0x80;
445 request
.u
.ata
.feature
= ATA_SF_ENAB_ACCOUS
;
446 request
.u
.ata
.count
= atoi(argv
[4]);
447 if (request
.u
.ata
.count
> 124)
448 request
.u
.ata
.count
= 124;
454 if (ioctl(fd
, IOCATAREQUEST
, &request
) < 0)
455 err(1, "ioctl(IOCATAREQUEST)");
457 if (request
.error
!= 0) {
459 "IOCATAREQUEST returned err status %d",
465 if (!strcmp(argv
[1], "cap") && argc
== 3) {
466 fd
= open_dev(argv
[2], O_RDONLY
);
471 if (!strcmp(argv
[1], "spindown") && (argc
== 3 || argc
== 4)) {
472 fd
= open_dev(argv
[2], O_RDONLY
);
473 ata_spindown(fd
, argv
[2], argv
[3]);
477 if ((fd
= open("/dev/ata", O_RDWR
)) < 0)
478 err(1, "control device not found");
480 if (!strcmp(argv
[1], "list") && argc
== 2) {
483 if (ioctl(fd
, IOCATAGMAXCHANNEL
, &maxchannel
) < 0)
484 err(1, "ioctl(IOCATAGMAXCHANNEL)");
485 for (channel
= 0; channel
< maxchannel
; channel
++)
486 info_print(fd
, channel
, 1);
489 if (!strcmp(argv
[1], "info") && argc
== 3) {
490 channel
= ata_arg(argv
[2]);
491 info_print(fd
, channel
, 0);
494 if (!strcmp(argv
[1], "detach") && argc
== 3) {
495 channel
= ata_arg(argv
[2]);
496 if (ioctl(fd
, IOCATADETACH
, &channel
) < 0)
497 err(1, "ioctl(IOCATADETACH)");
500 if (!strcmp(argv
[1], "attach") && argc
== 3) {
501 channel
= ata_arg(argv
[2]);
502 if (ioctl(fd
, IOCATAATTACH
, &channel
) < 0)
503 err(1, "ioctl(IOCATAATTACH)");
504 info_print(fd
, channel
, 0);
507 if (!strcmp(argv
[1], "reinit") && argc
== 3) {
508 channel
= ata_arg(argv
[2]);
509 if (ioctl(fd
, IOCATAREINIT
, &channel
) < 0)
510 warn("ioctl(IOCATAREINIT)");
511 info_print(fd
, channel
, 0);
514 if (!strcmp(argv
[1], "create")) {
515 int disk
, dev
, offset
;
516 struct ata_ioc_raid_config config
;
518 bzero(&config
, sizeof(config
));
520 if (!strcasecmp(argv
[2], "RAID0") ||
521 !strcasecmp(argv
[2], "stripe"))
522 config
.type
= AR_RAID0
;
523 if (!strcasecmp(argv
[2], "RAID1") ||
524 !strcasecmp(argv
[2],"mirror"))
525 config
.type
= AR_RAID1
;
526 if (!strcasecmp(argv
[2], "RAID0+1") ||
527 !strcasecmp(argv
[2],"RAID10"))
528 config
.type
= AR_RAID01
;
529 if (!strcasecmp(argv
[2], "RAID5"))
530 config
.type
= AR_RAID5
;
531 if (!strcasecmp(argv
[2], "SPAN"))
532 config
.type
= AR_SPAN
;
533 if (!strcasecmp(argv
[2], "JBOD"))
534 config
.type
= AR_JBOD
;
537 fprintf(stderr
, "natacontrol: Invalid RAID type %s\n",
539 fprintf(stderr
, "natacontrol: Valid RAID types: \n");
540 fprintf(stderr
, " stripe | mirror | "
541 "RAID0 | RAID1 | RAID0+1 | RAID5 | "
546 if (config
.type
== AR_RAID0
||
547 config
.type
== AR_RAID01
||
548 config
.type
== AR_RAID5
) {
550 sscanf(argv
[3], "%d", &config
.interleave
) != 1) {
552 "natacontrol: Invalid interleave %s\n",
561 for (disk
= 0; disk
< 16 && (offset
+ disk
) < argc
; disk
++) {
562 if (!(sscanf(argv
[offset
+ disk
], "ad%d", &dev
) == 1)) {
564 "natacontrol: Invalid disk %s\n",
565 argv
[offset
+ disk
]);
568 config
.disks
[disk
] = dev
;
571 if ((config
.type
== AR_RAID1
|| config
.type
== AR_RAID01
) &&
573 fprintf(stderr
, "natacontrol: At least 2 disks must be "
578 config
.total_disks
= disk
;
579 if (ioctl(fd
, IOCATARAIDCREATE
, &config
) < 0)
580 err(1, "ioctl(IOCATARAIDCREATE)");
582 printf("ar%d created\n", config
.lun
);
585 if (!strcmp(argv
[1], "delete") && argc
== 3) {
586 array
= ar_arg(argv
[2]);
587 if (ioctl(fd
, IOCATARAIDDELETE
, &array
) < 0)
588 warn("ioctl(IOCATARAIDDELETE)");
591 if (!strcmp(argv
[1], "addspare") && argc
== 4) {
592 struct ata_ioc_raid_config config
;
594 config
.lun
= ar_arg(argv
[2]);
595 if (!(sscanf(argv
[3], "ad%d", &config
.disks
[0]) == 1)) {
597 "natacontrol: Invalid disk %s\n", argv
[3]);
600 if (ioctl(fd
, IOCATARAIDADDSPARE
, &config
) < 0)
601 warn("ioctl(IOCATARAIDADDSPARE)");
604 if (!strcmp(argv
[1], "rebuild") && argc
== 3) {
605 array
= ar_arg(argv
[2]);
606 if (ioctl(fd
, IOCATARAIDREBUILD
, &array
) < 0)
607 warn("ioctl(IOCATARAIDREBUILD)");
614 if (daemon(0, 1) == -1)
617 snprintf(device
, sizeof(device
), "/dev/ar%d",
619 if ((arfd
= open(device
, O_RDONLY
)) == -1)
620 err(1, "open %s", device
);
621 if ((buffer
= malloc(1024 * 1024)) == NULL
)
623 while ((len
= read(arfd
, buffer
, 1024 * 1024)) > 0)
629 "natacontrol: ar%d rebuild completed\n",
636 if (!strcmp(argv
[1], "status") && argc
== 3) {
637 struct ata_ioc_raid_status status
;
640 status
.lun
= ar_arg(argv
[2]);
641 if (ioctl(fd
, IOCATARAIDSTATUS
, &status
) < 0)
642 err(1, "ioctl(IOCATARAIDSTATUS)");
644 printf("ar%d: ATA ", status
.lun
);
645 switch (status
.type
) {
647 printf("RAID0 stripesize=%d", status
.interleave
);
653 printf("RAID0+1 stripesize=%d", status
.interleave
);
656 printf("RAID5 stripesize=%d", status
.interleave
);
666 switch (status
.status
) {
670 case AR_READY
| AR_DEGRADED
:
671 printf("DEGRADED\n");
673 case AR_READY
| AR_DEGRADED
| AR_REBUILDING
:
674 printf("REBUILDING %d%% completed\n",
680 printf(" subdisks:\n");
681 for (i
= 0; i
< status
.total_disks
; i
++) {
683 lun
= status
.disks
[i
].lun
;
684 state
= status
.disks
[i
].state
;
688 printf("ad%-2d ", lun
);
689 if (state
& AR_DISK_ONLINE
)
691 else if (state
& AR_DISK_SPARE
)
693 else if (state
& AR_DISK_PRESENT
)