2 * Copyright (c) 2000,2001,2002 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.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * $FreeBSD: src/sys/dev/ata/ata-raid.c,v 1.3.2.19 2003/01/30 07:19:59 sos Exp $
32 #include <sys/param.h>
33 #include <sys/systm.h>
35 #include <sys/kernel.h>
36 #include <sys/malloc.h>
41 #include <sys/devicestat.h>
43 #include <machine/bus.h>
45 #include <dev/ata/ata-all.h>
46 #include <dev/ata/ata-disk.h>
47 #include <dev/ata/ata-raid.h>
49 /* device structures */
50 static d_open_t aropen;
51 static d_strategy_t arstrategy;
52 static struct cdevsw ar_cdevsw = {
54 /* close */ nullclose,
56 /* write */ physwrite,
60 /* strategy */ arstrategy,
68 static struct cdevsw ardisk_cdevsw;
71 static void ar_attach_raid(struct ar_softc *, int);
72 static void ar_done(struct buf *);
73 static void ar_config_changed(struct ar_softc *, int);
74 static int ar_rebuild(struct ar_softc *);
75 static int ar_highpoint_read_conf(struct ad_softc *, struct ar_softc **);
76 static int ar_highpoint_write_conf(struct ar_softc *);
77 static int ar_promise_read_conf(struct ad_softc *, struct ar_softc **, int);
78 static int ar_promise_write_conf(struct ar_softc *);
79 static int ar_rw(struct ad_softc *, u_int32_t, int, caddr_t, int);
80 static struct ata_device *ar_locate_disk(int);
83 static struct ar_softc **ar_table = NULL;
84 static MALLOC_DEFINE(M_AR, "AR driver", "ATA RAID driver");
87 ata_raiddisk_attach(struct ad_softc *adp)
93 for (array = 0; array < MAX_ARRAYS; array++) {
94 if (!(rdp = ar_table[array]) || !rdp->flags)
97 for (disk = 0; disk < rdp->total_disks; disk++) {
98 if ((rdp->disks[disk].flags & AR_DF_ASSIGNED) &&
99 rdp->disks[disk].device == adp->device) {
100 ata_prtdev(rdp->disks[disk].device,
101 "inserted into ar%d disk%d as spare\n",
103 rdp->disks[disk].flags |= (AR_DF_PRESENT | AR_DF_SPARE);
104 AD_SOFTC(rdp->disks[disk])->flags = AD_F_RAID_SUBDISK;
105 ar_config_changed(rdp, 1);
113 ar_table = malloc(sizeof(struct ar_soft *) * MAX_ARRAYS,
114 M_AR, M_NOWAIT | M_ZERO);
116 ata_prtdev(adp->device, "no memory for ATA raid array\n");
120 switch(adp->device->channel->chiptype) {
121 case 0x4d33105a: case 0x4d38105a: case 0x4d30105a:
122 case 0x0d30105a: case 0x4d68105a: case 0x6268105a:
123 case 0x4d69105a: case 0x5275105a: case 0x6269105a:
125 /* test RAID bit in PCI reg XXX */
126 return (ar_promise_read_conf(adp, ar_table, 0));
128 case 0x00041103: case 0x00051103: case 0x00081103:
129 return (ar_highpoint_read_conf(adp, ar_table));
132 return (ar_promise_read_conf(adp, ar_table, 1));
138 ata_raiddisk_detach(struct ad_softc *adp)
140 struct ar_softc *rdp;
144 for (array = 0; array < MAX_ARRAYS; array++) {
145 if (!(rdp = ar_table[array]) || !rdp->flags)
147 for (disk = 0; disk < rdp->total_disks; disk++) {
148 if (rdp->disks[disk].device == adp->device) {
149 ata_prtdev(rdp->disks[disk].device,
150 "deleted from ar%d disk%d\n", array, disk);
151 rdp->disks[disk].flags &= ~(AR_DF_PRESENT | AR_DF_ONLINE);
152 AD_SOFTC(rdp->disks[disk])->flags &= ~AD_F_RAID_SUBDISK;
153 ar_config_changed(rdp, 1);
165 struct ar_softc *rdp;
171 for (array = 0; array < MAX_ARRAYS; array++) {
172 if (!(rdp = ar_table[array]) || !rdp->flags)
174 ar_attach_raid(rdp, 0);
179 ar_attach_raid(struct ar_softc *rdp, int update)
184 ar_config_changed(rdp, update);
185 dev = disk_create(rdp->lun, &rdp->disk, 0, &ar_cdevsw, &ardisk_cdevsw);
187 dev->si_iosize_max = 256 * DEV_BSIZE;
190 printf("ar%d: %lluMB <ATA ", rdp->lun, (unsigned long long)
191 (rdp->total_sectors / ((1024L * 1024L) / DEV_BSIZE)));
192 switch (rdp->flags & (AR_F_RAID0 | AR_F_RAID1 | AR_F_SPAN)) {
194 printf("RAID0 "); break;
196 printf("RAID1 "); break;
198 printf("SPAN "); break;
199 case (AR_F_RAID0 | AR_F_RAID1):
200 printf("RAID0+1 "); break;
202 printf("unknown 0x%x> ", rdp->flags);
205 printf("array> [%d/%d/%d] status: ",
206 rdp->cylinders, rdp->heads, rdp->sectors);
207 switch (rdp->flags & (AR_F_DEGRADED | AR_F_READY)) {
211 case (AR_F_DEGRADED | AR_F_READY):
218 printf(" subdisks:\n");
219 for (disk = 0; disk < rdp->total_disks; disk++) {
220 if (rdp->disks[disk].flags & AR_DF_PRESENT) {
221 if (rdp->disks[disk].flags & AR_DF_ONLINE)
222 printf(" %d READY ", disk);
223 else if (rdp->disks[disk].flags & AR_DF_SPARE)
224 printf(" %d SPARE ", disk);
226 printf(" %d FREE ", disk);
227 ad_print(AD_SOFTC(rdp->disks[disk]));
229 ata_enclosure_print(AD_SOFTC(rdp->disks[disk])->device);
231 else if (rdp->disks[disk].flags & AR_DF_ASSIGNED)
232 printf(" %d DOWN\n", disk);
234 printf(" %d INVALID no RAID config info on this disk\n", disk);
239 ata_raid_create(struct raid_setup *setup)
241 struct ata_device *atadev;
242 struct ar_softc *rdp;
244 int ctlr = 0, disk_size = 0, total_disks = 0;
247 ar_table = malloc(sizeof(struct ar_soft *) * MAX_ARRAYS,
248 M_AR, M_NOWAIT | M_ZERO);
250 printf("ar: no memory for ATA raid array\n");
253 for (array = 0; array < MAX_ARRAYS; array++) {
254 if (!ar_table[array])
257 if (array >= MAX_ARRAYS)
260 if (!(rdp = (struct ar_softc*)malloc(sizeof(struct ar_softc), M_AR,
261 M_NOWAIT | M_ZERO))) {
262 printf("ar%d: failed to allocate raid config storage\n", array);
266 for (disk = 0; disk < setup->total_disks; disk++) {
267 if ((atadev = ar_locate_disk(setup->disks[disk]))) {
268 rdp->disks[disk].device = atadev;
269 if (AD_SOFTC(rdp->disks[disk])->flags & AD_F_RAID_SUBDISK) {
270 setup->disks[disk] = -1;
275 switch (rdp->disks[disk].device->channel->chiptype & 0xffff) {
277 ctlr |= AR_F_HIGHPOINT_RAID;
278 rdp->disks[disk].disk_sectors =
279 AD_SOFTC(rdp->disks[disk])->total_secs;
283 ctlr |= AR_F_FREEBSD_RAID;
287 ctlr |= AR_F_PROMISE_RAID;
288 rdp->disks[disk].disk_sectors =
289 PR_LBA(AD_SOFTC(rdp->disks[disk]));
292 if ((rdp->flags & (AR_F_PROMISE_RAID|AR_F_HIGHPOINT_RAID)) &&
293 (rdp->flags & (AR_F_PROMISE_RAID|AR_F_HIGHPOINT_RAID)) !=
294 (ctlr & (AR_F_PROMISE_RAID|AR_F_HIGHPOINT_RAID))) {
302 disk_size = min(rdp->disks[disk].disk_sectors, disk_size);
304 disk_size = rdp->disks[disk].disk_sectors;
305 rdp->disks[disk].flags =
306 (AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_ONLINE);
311 setup->disks[disk] = -1;
321 switch (setup->type) {
323 rdp->flags |= AR_F_RAID0;
326 rdp->flags |= AR_F_RAID1;
327 if (total_disks != 2) {
333 rdp->flags |= (AR_F_RAID0 | AR_F_RAID1);
334 if (total_disks % 2 != 0) {
340 rdp->flags |= AR_F_SPAN;
344 for (disk = 0; disk < total_disks; disk++)
345 AD_SOFTC(rdp->disks[disk])->flags = AD_F_RAID_SUBDISK;
348 if (rdp->flags & AR_F_RAID0) {
351 while (setup->interleave >>= 1)
353 if (rdp->flags & AR_F_PROMISE_RAID)
354 rdp->interleave = min(max(2, 1 << bit), 2048);
355 if (rdp->flags & AR_F_HIGHPOINT_RAID)
356 rdp->interleave = min(max(32, 1 << bit), 128);
358 rdp->total_disks = total_disks;
359 rdp->width = total_disks / ((rdp->flags & AR_F_RAID1) ? 2 : 1);
360 rdp->total_sectors = disk_size * rdp->width;
363 rdp->cylinders = rdp->total_sectors / (255 * 63);
364 if (rdp->flags & AR_F_PROMISE_RAID) {
368 if (rdp->flags & AR_F_HIGHPOINT_RAID) {
369 rdp->offset = HPT_LBA + 1;
370 rdp->reserved = HPT_LBA + 1;
372 rdp->lock_start = rdp->lock_end = 0xffffffff;
373 rdp->flags |= AR_F_READY;
375 ar_table[array] = rdp;
376 ar_attach_raid(rdp, 1);
382 ata_raid_delete(int array)
384 struct ar_softc *rdp;
388 printf("ar: no memory for ATA raid array\n");
391 if (!(rdp = ar_table[array]))
394 rdp->flags &= ~AR_F_READY;
395 for (disk = 0; disk < rdp->total_disks; disk++) {
396 if ((rdp->disks[disk].flags&AR_DF_PRESENT) && rdp->disks[disk].device) {
397 AD_SOFTC(rdp->disks[disk])->flags &= ~AD_F_RAID_SUBDISK;
398 ata_enclosure_leds(rdp->disks[disk].device, ATA_LED_GREEN);
399 rdp->disks[disk].flags = 0;
402 if (rdp->flags & AR_F_PROMISE_RAID)
403 ar_promise_write_conf(rdp);
405 ar_highpoint_write_conf(rdp);
406 disk_invalidate(&rdp->disk);
407 disk_destroy(rdp->dev);
409 ar_table[array] = NULL;
414 ata_raid_status(int array, struct raid_status *status)
416 struct ar_softc *rdp;
419 if (!ar_table || !(rdp = ar_table[array]))
422 switch (rdp->flags & (AR_F_RAID0 | AR_F_RAID1 | AR_F_SPAN)) {
424 status->type = AR_RAID0;
427 status->type = AR_RAID1;
429 case AR_F_RAID0 | AR_F_RAID1:
430 status->type = AR_RAID0 | AR_RAID1;
433 status->type = AR_SPAN;
436 status->total_disks = rdp->total_disks;
437 for (i = 0; i < rdp->total_disks; i++ ) {
438 if ((rdp->disks[i].flags & AR_DF_PRESENT) && rdp->disks[i].device)
439 status->disks[i] = AD_SOFTC(rdp->disks[i])->lun;
441 status->disks[i] = -1;
443 status->interleave = rdp->interleave;
445 if (rdp->flags & AR_F_READY)
446 status->status |= AR_READY;
447 if (rdp->flags & AR_F_DEGRADED)
448 status->status |= AR_DEGRADED;
449 if (rdp->flags & AR_F_REBUILDING) {
450 status->status |= AR_REBUILDING;
451 status->progress = 100*rdp->lock_start/(rdp->total_sectors/rdp->width);
457 ata_raid_rebuild(int array)
459 struct ar_softc *rdp;
461 if (!ar_table || !(rdp = ar_table[array]))
463 if (rdp->flags & AR_F_REBUILDING)
465 /* create process here XXX SOS */
466 return ar_rebuild(rdp);
470 aropen(dev_t dev, int flags, int fmt, struct proc *p)
472 struct ar_softc *rdp = dev->si_drv1;
473 struct disklabel *dl;
475 dl = &rdp->disk.d_label;
476 bzero(dl, sizeof *dl);
477 dl->d_secsize = DEV_BSIZE;
478 dl->d_nsectors = rdp->sectors;
479 dl->d_ntracks = rdp->heads;
480 dl->d_ncylinders = rdp->cylinders;
481 dl->d_secpercyl = rdp->sectors * rdp->heads;
482 dl->d_secperunit = rdp->total_sectors;
487 arstrategy(struct buf *bp)
489 struct ar_softc *rdp = bp->b_dev->si_drv1;
490 int blkno, count, chunk, lba, lbs, tmplba;
491 int drv = 0, change = 0;
494 if (!(rdp->flags & AR_F_READY)) {
495 bp->b_flags |= B_ERROR;
501 bp->b_resid = bp->b_bcount;
502 blkno = bp->b_pblkno;
504 for (count = howmany(bp->b_bcount, DEV_BSIZE); count > 0;
505 count -= chunk, blkno += chunk, data += (chunk * DEV_BSIZE)) {
506 struct ar_buf *buf1, *buf2;
508 switch (rdp->flags & (AR_F_RAID0 | AR_F_RAID1 | AR_F_SPAN)) {
511 while (lba >= AD_SOFTC(rdp->disks[drv])->total_secs-rdp->reserved)
512 lba -= AD_SOFTC(rdp->disks[drv++])->total_secs-rdp->reserved;
513 chunk = min(AD_SOFTC(rdp->disks[drv])->total_secs-rdp->reserved-lba,
518 case AR_F_RAID0 | AR_F_RAID1:
519 tmplba = blkno / rdp->interleave;
520 chunk = blkno % rdp->interleave;
521 if (tmplba == rdp->total_sectors / rdp->interleave) {
522 lbs = (rdp->total_sectors-(tmplba*rdp->interleave))/rdp->width;
524 lba = ((tmplba/rdp->width)*rdp->interleave) + chunk%lbs;
525 chunk = min(count, lbs);
528 drv = tmplba % rdp->width;
529 lba = ((tmplba / rdp->width) * rdp->interleave) + chunk;
530 chunk = min(count, rdp->interleave - chunk);
541 printf("ar%d: unknown array type in arstrategy\n", rdp->lun);
542 bp->b_flags |= B_ERROR;
548 buf1 = malloc(sizeof(struct ar_buf), M_AR, M_NOWAIT | M_ZERO);
549 BUF_LOCKINIT(&buf1->bp);
550 BUF_LOCK(&buf1->bp, LK_EXCLUSIVE);
551 buf1->bp.b_pblkno = lba;
552 if ((buf1->drive = drv) > 0)
553 buf1->bp.b_pblkno += rdp->offset;
554 buf1->bp.b_caller1 = (void *)rdp;
555 buf1->bp.b_bcount = chunk * DEV_BSIZE;
556 buf1->bp.b_data = data;
557 buf1->bp.b_flags = bp->b_flags | B_CALL;
558 buf1->bp.b_iodone = ar_done;
561 switch (rdp->flags & (AR_F_RAID0 | AR_F_RAID1 | AR_F_SPAN)) {
564 if ((rdp->disks[buf1->drive].flags &
565 (AR_DF_PRESENT|AR_DF_ONLINE))==(AR_DF_PRESENT|AR_DF_ONLINE) &&
566 !AD_SOFTC(rdp->disks[buf1->drive])->dev->si_disk) {
567 rdp->disks[buf1->drive].flags &= ~AR_DF_ONLINE;
568 ar_config_changed(rdp, 1);
570 bp->b_flags |= B_ERROR;
575 buf1->bp.b_dev = AD_SOFTC(rdp->disks[buf1->drive])->dev;
576 AR_STRATEGY((struct buf *)buf1);
580 case AR_F_RAID0 | AR_F_RAID1:
581 if ((rdp->flags & AR_F_REBUILDING) && !(bp->b_flags & B_READ)) {
582 if ((bp->b_pblkno >= rdp->lock_start &&
583 bp->b_pblkno < rdp->lock_end) ||
584 ((bp->b_pblkno + chunk) > rdp->lock_start &&
585 (bp->b_pblkno + chunk) <= rdp->lock_end)) {
586 tsleep(rdp, PRIBIO, "arwait", 0);
589 if ((rdp->disks[buf1->drive].flags &
590 (AR_DF_PRESENT|AR_DF_ONLINE))==(AR_DF_PRESENT|AR_DF_ONLINE) &&
591 !AD_SOFTC(rdp->disks[buf1->drive])->dev->si_disk) {
592 rdp->disks[buf1->drive].flags &= ~AR_DF_ONLINE;
595 if ((rdp->disks[buf1->drive + rdp->width].flags &
596 (AR_DF_PRESENT|AR_DF_ONLINE))==(AR_DF_PRESENT|AR_DF_ONLINE) &&
597 !AD_SOFTC(rdp->disks[buf1->drive + rdp->width])->dev->si_disk) {
598 rdp->disks[buf1->drive + rdp->width].flags &= ~AR_DF_ONLINE;
602 ar_config_changed(rdp, 1);
604 if (!(rdp->flags & AR_F_READY)) {
606 bp->b_flags |= B_ERROR;
611 if (bp->b_flags & B_READ) {
612 if ((buf1->bp.b_pblkno <
613 (rdp->disks[buf1->drive].last_lba - AR_PROXIMITY) ||
615 (rdp->disks[buf1->drive].last_lba + AR_PROXIMITY) ||
616 !(rdp->disks[buf1->drive].flags & AR_DF_ONLINE)) &&
617 (rdp->disks[buf1->drive+rdp->width].flags & AR_DF_ONLINE))
618 buf1->drive = buf1->drive + rdp->width;
621 if ((rdp->disks[buf1->drive+rdp->width].flags & AR_DF_ONLINE) ||
622 ((rdp->flags & AR_F_REBUILDING) &&
623 (rdp->disks[buf1->drive+rdp->width].flags & AR_DF_SPARE) &&
624 buf1->bp.b_pblkno < rdp->lock_start)) {
625 if ((rdp->disks[buf1->drive].flags & AR_DF_ONLINE) ||
626 ((rdp->flags & AR_F_REBUILDING) &&
627 (rdp->disks[buf1->drive].flags & AR_DF_SPARE) &&
628 buf1->bp.b_pblkno < rdp->lock_start)) {
629 buf2 = malloc(sizeof(struct ar_buf), M_AR, M_NOWAIT);
630 bcopy(buf1, buf2, sizeof(struct ar_buf));
631 BUF_LOCKINIT(&buf2->bp);
632 BUF_LOCK(&buf2->bp, LK_EXCLUSIVE);
635 buf2->drive = buf1->drive + rdp->width;
636 buf2->bp.b_dev = AD_SOFTC(rdp->disks[buf2->drive])->dev;
637 AR_STRATEGY((struct buf *)buf2);
638 rdp->disks[buf2->drive].last_lba =
639 buf2->bp.b_pblkno + chunk;
642 buf1->drive = buf1->drive + rdp->width;
645 buf1->bp.b_dev = AD_SOFTC(rdp->disks[buf1->drive])->dev;
646 AR_STRATEGY((struct buf *)buf1);
647 rdp->disks[buf1->drive].last_lba = buf1->bp.b_pblkno + chunk;
651 printf("ar%d: unknown array type in arstrategy\n", rdp->lun);
657 ar_done(struct buf *bp)
659 struct ar_softc *rdp = (struct ar_softc *)bp->b_caller1;
660 struct ar_buf *buf = (struct ar_buf *)bp;
662 switch (rdp->flags & (AR_F_RAID0 | AR_F_RAID1 | AR_F_SPAN)) {
665 if (buf->bp.b_flags & B_ERROR) {
666 rdp->disks[buf->drive].flags &= ~AR_DF_ONLINE;
667 ar_config_changed(rdp, 1);
668 buf->org->b_flags |= B_ERROR;
669 buf->org->b_error = EIO;
673 buf->org->b_resid -= buf->bp.b_bcount;
674 if (buf->org->b_resid == 0)
680 case AR_F_RAID0 | AR_F_RAID1:
681 if (buf->bp.b_flags & B_ERROR) {
682 rdp->disks[buf->drive].flags &= ~AR_DF_ONLINE;
683 ar_config_changed(rdp, 1);
684 if (rdp->flags & AR_F_READY) {
685 if (buf->bp.b_flags & B_READ) {
686 if (buf->drive < rdp->width)
687 buf->drive = buf->drive + rdp->width;
689 buf->drive = buf->drive - rdp->width;
690 buf->bp.b_dev = AD_SOFTC(rdp->disks[buf->drive])->dev;
691 buf->bp.b_flags = buf->org->b_flags | B_CALL;
693 AR_STRATEGY((struct buf *)buf);
697 if (buf->flags & AB_F_DONE) {
698 buf->org->b_resid -= buf->bp.b_bcount;
699 if (buf->org->b_resid == 0)
703 buf->mirror->flags |= AB_F_DONE;
707 buf->org->b_flags |= B_ERROR;
708 buf->org->b_error = EIO;
713 if (!(buf->bp.b_flags & B_READ)) {
714 if (buf->mirror && !(buf->flags & AB_F_DONE)){
715 buf->mirror->flags |= AB_F_DONE;
719 buf->org->b_resid -= buf->bp.b_bcount;
720 if (buf->org->b_resid == 0)
726 printf("ar%d: unknown array type in ar_done\n", rdp->lun);
732 ar_config_changed(struct ar_softc *rdp, int writeback)
737 rdp->flags |= AR_F_READY;
738 rdp->flags &= ~AR_F_DEGRADED;
740 for (disk = 0; disk < rdp->total_disks; disk++)
741 if (!(rdp->disks[disk].flags & AR_DF_PRESENT))
742 rdp->disks[disk].flags &= ~AR_DF_ONLINE;
744 for (disk = 0; disk < rdp->total_disks; disk++) {
745 switch (rdp->flags & (AR_F_RAID0 | AR_F_RAID1 | AR_F_SPAN)) {
748 if (!(rdp->disks[disk].flags & AR_DF_ONLINE)) {
749 rdp->flags &= ~AR_F_READY;
750 printf("ar%d: ERROR - array broken\n", rdp->lun);
755 case AR_F_RAID0 | AR_F_RAID1:
756 if (disk < rdp->width) {
757 if (!(rdp->disks[disk].flags & AR_DF_ONLINE) &&
758 !(rdp->disks[disk + rdp->width].flags & AR_DF_ONLINE)) {
759 rdp->flags &= ~AR_F_READY;
760 printf("ar%d: ERROR - array broken\n", rdp->lun);
762 else if (((rdp->disks[disk].flags & AR_DF_ONLINE) &&
764 [disk + rdp->width].flags & AR_DF_ONLINE))||
765 (!(rdp->disks[disk].flags & AR_DF_ONLINE) &&
767 [disk + rdp->width].flags & AR_DF_ONLINE))) {
768 rdp->flags |= AR_F_DEGRADED;
769 if (!(flags & AR_F_DEGRADED))
770 printf("ar%d: WARNING - mirror lost\n", rdp->lun);
775 if ((rdp->disks[disk].flags&AR_DF_PRESENT) && rdp->disks[disk].device) {
776 if (rdp->disks[disk].flags & AR_DF_ONLINE)
777 ata_enclosure_leds(rdp->disks[disk].device, ATA_LED_GREEN);
779 ata_enclosure_leds(rdp->disks[disk].device, ATA_LED_RED);
783 if (rdp->flags & AR_F_PROMISE_RAID)
784 ar_promise_write_conf(rdp);
785 if (rdp->flags & AR_F_HIGHPOINT_RAID)
786 ar_highpoint_write_conf(rdp);
791 ar_rebuild(struct ar_softc *rdp)
793 int disk, s, count = 0, error = 0;
796 if ((rdp->flags & (AR_F_READY|AR_F_DEGRADED)) != (AR_F_READY|AR_F_DEGRADED))
799 for (disk = 0; disk < rdp->total_disks; disk++) {
800 if (((rdp->disks[disk].flags&(AR_DF_PRESENT|AR_DF_ONLINE|AR_DF_SPARE))==
801 (AR_DF_PRESENT | AR_DF_SPARE)) && rdp->disks[disk].device) {
802 if (AD_SOFTC(rdp->disks[disk])->total_secs <
803 rdp->disks[disk].disk_sectors) {
804 ata_prtdev(rdp->disks[disk].device,
805 "disk capacity too small for this RAID config\n");
807 rdp->disks[disk].flags &= ~AR_DF_SPARE;
808 AD_SOFTC(rdp->disks[disk])->flags &= ~AD_F_RAID_SUBDISK;
812 ata_enclosure_leds(rdp->disks[disk].device, ATA_LED_ORANGE);
819 /* setup start conditions */
822 rdp->lock_end = rdp->lock_start + 256;
823 rdp->flags |= AR_F_REBUILDING;
825 buffer = malloc(256 * DEV_BSIZE, M_AR, M_NOWAIT | M_ZERO);
827 /* now go copy entire disk(s) */
828 while (rdp->lock_end < (rdp->total_sectors / rdp->width)) {
829 int size = min(256, (rdp->total_sectors / rdp->width) - rdp->lock_end);
831 for (disk = 0; disk < rdp->width; disk++) {
832 struct ad_softc *adp;
834 if (((rdp->disks[disk].flags & AR_DF_ONLINE) &&
835 (rdp->disks[disk + rdp->width].flags & AR_DF_ONLINE)) ||
836 ((rdp->disks[disk].flags & AR_DF_ONLINE) &&
837 !(rdp->disks[disk + rdp->width].flags & AR_DF_SPARE)) ||
838 ((rdp->disks[disk + rdp->width].flags & AR_DF_ONLINE) &&
839 !(rdp->disks[disk].flags & AR_DF_SPARE)))
842 if (rdp->disks[disk].flags & AR_DF_ONLINE)
843 adp = AD_SOFTC(rdp->disks[disk]);
845 adp = AD_SOFTC(rdp->disks[disk + rdp->width]);
846 if ((error = ar_rw(adp, rdp->lock_start,
847 size * DEV_BSIZE, buffer, AR_READ | AR_WAIT)))
850 if (rdp->disks[disk].flags & AR_DF_ONLINE)
851 adp = AD_SOFTC(rdp->disks[disk + rdp->width]);
853 adp = AD_SOFTC(rdp->disks[disk]);
854 if ((error = ar_rw(adp, rdp->lock_start,
855 size * DEV_BSIZE, buffer, AR_WRITE | AR_WAIT)))
864 rdp->lock_start = rdp->lock_end;
865 rdp->lock_end = rdp->lock_start + size;
870 for (disk = 0; disk < rdp->total_disks; disk++) {
871 if ((rdp->disks[disk].flags&(AR_DF_PRESENT|AR_DF_ONLINE|AR_DF_SPARE))==
872 (AR_DF_PRESENT | AR_DF_SPARE)) {
873 rdp->disks[disk].flags &= ~AR_DF_SPARE;
874 rdp->disks[disk].flags |= (AR_DF_ASSIGNED | AR_DF_ONLINE);
878 rdp->lock_start = 0xffffffff;
879 rdp->lock_end = 0xffffffff;
880 rdp->flags &= ~AR_F_REBUILDING;
882 ar_config_changed(rdp, 1);
887 ar_highpoint_read_conf(struct ad_softc *adp, struct ar_softc **raidp)
889 struct highpoint_raid_conf *info;
890 struct ar_softc *raid = NULL;
891 int array, disk_number = 0, retval = 0;
893 if (!(info = (struct highpoint_raid_conf *)
894 malloc(sizeof(struct highpoint_raid_conf), M_AR, M_NOWAIT | M_ZERO)))
897 if (ar_rw(adp, HPT_LBA, sizeof(struct highpoint_raid_conf),
898 (caddr_t)info, AR_READ | AR_WAIT)) {
900 printf("ar: HighPoint read conf failed\n");
904 /* check if this is a HighPoint RAID struct */
905 if (info->magic != HPT_MAGIC_OK && info->magic != HPT_MAGIC_BAD) {
907 printf("ar: HighPoint check1 failed\n");
911 /* is this disk defined, or an old leftover/spare ? */
912 if (!info->magic_0) {
914 printf("ar: HighPoint check2 failed\n");
918 /* now convert HighPoint config info into our generic form */
919 for (array = 0; array < MAX_ARRAYS; array++) {
922 (struct ar_softc*)malloc(sizeof(struct ar_softc), M_AR,
925 printf("ar%d: failed to allocate raid config storage\n", array);
930 if (raid->flags & AR_F_PROMISE_RAID)
933 switch (info->type) {
935 if ((info->order & (HPT_O_RAID0|HPT_O_OK))==(HPT_O_RAID0|HPT_O_OK))
936 goto highpoint_raid1;
937 if (info->order & (HPT_O_RAID0 | HPT_O_RAID1))
938 goto highpoint_raid01;
939 if (raid->magic_0 && raid->magic_0 != info->magic_0)
941 raid->magic_0 = info->magic_0;
942 raid->flags |= AR_F_RAID0;
943 raid->interleave = 1 << info->stripe_shift;
944 disk_number = info->disk_number;
945 if (!(info->order & HPT_O_OK))
946 info->magic = 0; /* mark bad */
951 if (raid->magic_0 && raid->magic_0 != info->magic_0)
953 raid->magic_0 = info->magic_0;
954 raid->flags |= AR_F_RAID1;
955 disk_number = (info->disk_number > 0);
958 case HPT_T_RAID01_RAID0:
960 if (info->order & HPT_O_RAID0) {
961 if ((raid->magic_0 && raid->magic_0 != info->magic_0) ||
962 (raid->magic_1 && raid->magic_1 != info->magic_1))
964 raid->magic_0 = info->magic_0;
965 raid->magic_1 = info->magic_1;
966 raid->flags |= (AR_F_RAID0 | AR_F_RAID1);
967 raid->interleave = 1 << info->stripe_shift;
968 disk_number = info->disk_number;
971 if (raid->magic_1 && raid->magic_1 != info->magic_1)
973 raid->magic_1 = info->magic_1;
974 raid->flags |= (AR_F_RAID0 | AR_F_RAID1);
975 raid->interleave = 1 << info->stripe_shift;
976 disk_number = info->disk_number + info->array_width;
977 if (!(info->order & HPT_O_RAID1))
978 info->magic = 0; /* mark bad */
983 if (raid->magic_0 && raid->magic_0 != info->magic_0)
985 raid->magic_0 = info->magic_0;
986 raid->flags |= AR_F_SPAN;
987 disk_number = info->disk_number;
991 printf("ar%d: HighPoint unknown RAID type 0x%02x\n",
996 raid->flags |= AR_F_HIGHPOINT_RAID;
997 raid->disks[disk_number].device = adp->device;
998 raid->disks[disk_number].flags = (AR_DF_PRESENT | AR_DF_ASSIGNED);
1000 if (info->magic == HPT_MAGIC_OK) {
1001 raid->disks[disk_number].flags |= AR_DF_ONLINE;
1002 raid->flags |= AR_F_READY;
1003 raid->width = info->array_width;
1006 raid->cylinders = info->total_sectors / (63 * 255);
1007 raid->total_sectors = info->total_sectors;
1008 raid->offset = HPT_LBA + 1;
1009 raid->reserved = HPT_LBA + 1;
1010 raid->lock_start = raid->lock_end = info->rebuild_lba;
1011 raid->disks[disk_number].disk_sectors =
1012 info->total_sectors / info->array_width;
1015 raid->disks[disk_number].flags &= ~ AR_DF_ONLINE;
1017 if ((raid->flags & AR_F_RAID0) && (raid->total_disks < raid->width))
1018 raid->total_disks = raid->width;
1019 if (disk_number >= raid->total_disks)
1020 raid->total_disks = disk_number + 1;
1030 ar_highpoint_write_conf(struct ar_softc *rdp)
1032 struct highpoint_raid_conf *config;
1033 struct timeval timestamp;
1036 microtime(×tamp);
1037 rdp->magic_0 = timestamp.tv_sec + 2;
1038 rdp->magic_1 = timestamp.tv_sec;
1040 for (disk = 0; disk < rdp->total_disks; disk++) {
1041 if (!(config = (struct highpoint_raid_conf *)
1042 malloc(sizeof(struct highpoint_raid_conf),
1043 M_AR, M_NOWAIT | M_ZERO))) {
1044 printf("ar%d: Highpoint write conf failed\n", rdp->lun);
1047 if ((rdp->disks[disk].flags & (AR_DF_PRESENT | AR_DF_ONLINE)) ==
1048 (AR_DF_PRESENT | AR_DF_ONLINE))
1049 config->magic = HPT_MAGIC_OK;
1050 if (rdp->disks[disk].flags & AR_DF_ASSIGNED) {
1051 config->magic_0 = rdp->magic_0;
1052 strcpy(config->name_1, "FreeBSD");
1054 config->disk_number = disk;
1056 switch (rdp->flags & (AR_F_RAID0 | AR_F_RAID1 | AR_F_SPAN)) {
1058 config->type = HPT_T_RAID0;
1059 strcpy(config->name_2, "RAID 0");
1060 if (rdp->disks[disk].flags & AR_DF_ONLINE)
1061 config->order = HPT_O_OK;
1065 config->type = HPT_T_RAID0; /* bogus but old HPT BIOS need it */
1066 strcpy(config->name_2, "RAID 1");
1067 config->disk_number = (disk < rdp->width) ? disk : disk + 5;
1068 config->order = HPT_O_RAID0 | HPT_O_OK;
1071 case AR_F_RAID0 | AR_F_RAID1:
1072 config->type = HPT_T_RAID01_RAID0;
1073 strcpy(config->name_2, "RAID 0+1");
1074 if (rdp->disks[disk].flags & AR_DF_ONLINE) {
1075 if (disk < rdp->width) {
1076 config->order = (HPT_O_RAID0 | HPT_O_RAID1);
1077 config->magic_0 = rdp->magic_0 - 1;
1080 config->order = HPT_O_RAID1;
1081 config->disk_number -= rdp->width;
1085 config->magic_0 = rdp->magic_0 - 1;
1086 config->magic_1 = rdp->magic_1;
1090 config->type = HPT_T_SPAN;
1091 strcpy(config->name_2, "SPAN");
1095 config->array_width = rdp->width;
1096 config->stripe_shift = (rdp->width > 1) ? (ffs(rdp->interleave)-1) : 0;
1097 config->total_sectors = rdp->total_sectors;
1098 config->rebuild_lba = rdp->lock_start;
1100 if ((rdp->disks[disk].device && rdp->disks[disk].device->driver) &&
1101 !(rdp->disks[disk].device->flags & ATA_D_DETACHING)) {
1103 if (ar_rw(AD_SOFTC(rdp->disks[disk]), HPT_LBA,
1104 sizeof(struct highpoint_raid_conf),
1105 (caddr_t)config, AR_WRITE)) {
1106 printf("ar%d: Highpoint write conf failed\n", rdp->lun);
1115 ar_promise_read_conf(struct ad_softc *adp, struct ar_softc **raidp, int local)
1117 struct promise_raid_conf *info;
1118 struct ar_softc *raid;
1119 u_int32_t magic, cksum, *ckptr;
1120 int array, count, disk, disksum = 0, retval = 0;
1122 if (!(info = (struct promise_raid_conf *)
1123 malloc(sizeof(struct promise_raid_conf), M_AR, M_NOWAIT | M_ZERO)))
1126 if (ar_rw(adp, PR_LBA(adp), sizeof(struct promise_raid_conf),
1127 (caddr_t)info, AR_READ | AR_WAIT)) {
1129 printf("ar: %s read conf failed\n", local ? "FreeBSD" : "Promise");
1133 /* check if this is a Promise RAID struct (or our local one) */
1135 if (strncmp(info->promise_id, ATA_MAGIC, sizeof(ATA_MAGIC))) {
1137 printf("ar: FreeBSD check1 failed\n");
1142 if (strncmp(info->promise_id, PR_MAGIC, sizeof(PR_MAGIC))) {
1144 printf("ar: Promise check1 failed\n");
1149 /* check if the checksum is OK */
1150 for (cksum = 0, ckptr = (int32_t *)info, count = 0; count < 511; count++)
1152 if (cksum != *ckptr) {
1154 printf("ar: %s check2 failed\n", local ? "FreeBSD" : "Promise");
1158 /* now convert Promise config info into our generic form */
1159 if (info->raid.integrity != PR_I_VALID) {
1161 printf("ar: %s check3 failed\n", local ? "FreeBSD" : "Promise");
1165 for (array = 0; array < MAX_ARRAYS; array++) {
1166 if (!raidp[array]) {
1168 (struct ar_softc*)malloc(sizeof(struct ar_softc), M_AR,
1170 if (!raidp[array]) {
1171 printf("ar%d: failed to allocate raid config storage\n", array);
1175 raid = raidp[array];
1176 if (raid->flags & AR_F_HIGHPOINT_RAID)
1179 magic = (adp->device->channel->chiptype >> 16) |
1180 (info->raid.array_number << 16);
1182 if ((raid->flags & AR_F_PROMISE_RAID) && magic != raid->magic_0)
1185 /* update our knowledge about the array config based on generation */
1186 if (!info->raid.generation || info->raid.generation > raid->generation){
1187 raid->generation = info->raid.generation;
1188 raid->flags = AR_F_PROMISE_RAID;
1190 raid->flags |= AR_F_FREEBSD_RAID;
1191 raid->magic_0 = magic;
1193 if ((info->raid.status &
1194 (PR_S_VALID | PR_S_ONLINE | PR_S_INITED | PR_S_READY)) ==
1195 (PR_S_VALID | PR_S_ONLINE | PR_S_INITED | PR_S_READY)) {
1196 raid->flags |= AR_F_READY;
1197 if (info->raid.status & PR_S_DEGRADED)
1198 raid->flags |= AR_F_DEGRADED;
1201 raid->flags &= ~AR_F_READY;
1203 switch (info->raid.type) {
1205 raid->flags |= AR_F_RAID0;
1209 raid->flags |= AR_F_RAID1;
1210 if (info->raid.array_width > 1)
1211 raid->flags |= AR_F_RAID0;
1215 raid->flags |= AR_F_SPAN;
1219 printf("ar%d: %s unknown RAID type 0x%02x\n",
1220 array, local ? "FreeBSD" : "Promise", info->raid.type);
1223 raid->interleave = 1 << info->raid.stripe_shift;
1224 raid->width = info->raid.array_width;
1225 raid->total_disks = info->raid.total_disks;
1226 raid->heads = info->raid.heads + 1;
1227 raid->sectors = info->raid.sectors;
1228 raid->cylinders = info->raid.cylinders + 1;
1229 raid->total_sectors = info->raid.total_sectors;
1231 raid->reserved = 63;
1232 raid->lock_start = raid->lock_end = info->raid.rebuild_lba;
1234 /* convert disk flags to our internal types */
1235 for (disk = 0; disk < info->raid.total_disks; disk++) {
1236 raid->disks[disk].flags = 0;
1237 disksum += info->raid.disk[disk].flags;
1238 if (info->raid.disk[disk].flags & PR_F_ONLINE)
1239 raid->disks[disk].flags |= AR_DF_ONLINE;
1240 if (info->raid.disk[disk].flags & PR_F_ASSIGNED)
1241 raid->disks[disk].flags |= AR_DF_ASSIGNED;
1242 if (info->raid.disk[disk].flags & PR_F_SPARE) {
1243 raid->disks[disk].flags &= ~AR_DF_ONLINE;
1244 raid->disks[disk].flags |= AR_DF_SPARE;
1246 if (info->raid.disk[disk].flags & (PR_F_REDIR | PR_F_DOWN))
1247 raid->disks[disk].flags &= ~AR_DF_ONLINE;
1250 free(raidp[array], M_AR);
1251 raidp[array] = NULL;
1255 if (raid->disks[info->raid.disk_number].flags && adp->device) {
1256 raid->disks[info->raid.disk_number].device = adp->device;
1257 raid->disks[info->raid.disk_number].flags |= AR_DF_PRESENT;
1258 raid->disks[info->raid.disk_number].disk_sectors =
1259 info->raid.total_sectors / info->raid.array_width;
1260 /*info->raid.disk_sectors;*/
1271 ar_promise_write_conf(struct ar_softc *rdp)
1273 struct promise_raid_conf *config;
1274 struct timeval timestamp;
1276 int count, disk, drive;
1277 int local = rdp->flags & AR_F_FREEBSD_RAID;
1280 microtime(×tamp);
1282 for (disk = 0; disk < rdp->total_disks; disk++) {
1283 if (!(config = (struct promise_raid_conf *)
1284 malloc(sizeof(struct promise_raid_conf), M_AR, M_NOWAIT))) {
1285 printf("ar%d: %s write conf failed\n",
1286 rdp->lun, local ? "FreeBSD" : "Promise");
1289 for (count = 0; count < sizeof(struct promise_raid_conf); count++)
1290 *(((u_int8_t *)config) + count) = 255 - (count % 256);
1293 bcopy(ATA_MAGIC, config->promise_id, sizeof(ATA_MAGIC));
1295 bcopy(PR_MAGIC, config->promise_id, sizeof(PR_MAGIC));
1296 config->dummy_0 = 0x00020000;
1297 config->magic_0 = PR_MAGIC0(rdp->disks[disk]) | timestamp.tv_sec;
1298 config->magic_1 = timestamp.tv_sec >> 16;
1299 config->magic_2 = timestamp.tv_sec;
1300 config->raid.integrity = PR_I_VALID;
1302 config->raid.disk_number = disk;
1303 if ((rdp->disks[disk].flags&AR_DF_PRESENT) && rdp->disks[disk].device) {
1304 config->raid.channel = rdp->disks[disk].device->channel->unit;
1305 config->raid.device = (rdp->disks[disk].device->unit != 0);
1306 if (AD_SOFTC(rdp->disks[disk])->dev->si_disk)
1307 config->raid.disk_sectors = PR_LBA(AD_SOFTC(rdp->disks[disk]));
1308 /*config->raid.disk_offset*/
1310 config->raid.magic_0 = config->magic_0;
1311 config->raid.rebuild_lba = rdp->lock_start;
1312 config->raid.generation = rdp->generation;
1314 if (rdp->flags & AR_F_READY) {
1315 config->raid.flags = (PR_F_VALID | PR_F_ASSIGNED | PR_F_ONLINE);
1316 config->raid.status =
1317 (PR_S_VALID | PR_S_ONLINE | PR_S_INITED | PR_S_READY);
1318 if (rdp->flags & AR_F_DEGRADED)
1319 config->raid.status |= PR_S_DEGRADED;
1321 config->raid.status |= PR_S_FUNCTIONAL;
1324 config->raid.status = 0;
1325 config->raid.flags = PR_F_DOWN;
1328 switch (rdp->flags & (AR_F_RAID0 | AR_F_RAID1 | AR_F_SPAN)) {
1330 config->raid.type = PR_T_RAID0;
1333 config->raid.type = PR_T_RAID1;
1335 case AR_F_RAID0 | AR_F_RAID1:
1336 config->raid.type = PR_T_RAID1;
1339 config->raid.type = PR_T_SPAN;
1343 config->raid.total_disks = rdp->total_disks;
1344 config->raid.stripe_shift = ffs(rdp->interleave) - 1;
1345 config->raid.array_width = rdp->width;
1346 config->raid.array_number = rdp->lun;
1347 config->raid.total_sectors = rdp->total_sectors;
1348 config->raid.cylinders = rdp->cylinders - 1;
1349 config->raid.heads = rdp->heads - 1;
1350 config->raid.sectors = rdp->sectors;
1351 config->raid.magic_1 = (u_int64_t)config->magic_2<<16 | config->magic_1;
1353 bzero(&config->raid.disk, 8 * 12);
1354 for (drive = 0; drive < rdp->total_disks; drive++) {
1355 config->raid.disk[drive].flags = 0;
1356 if (rdp->disks[drive].flags & AR_DF_PRESENT)
1357 config->raid.disk[drive].flags |= PR_F_VALID;
1358 if (rdp->disks[drive].flags & AR_DF_ASSIGNED)
1359 config->raid.disk[drive].flags |= PR_F_ASSIGNED;
1360 if (rdp->disks[drive].flags & AR_DF_ONLINE)
1361 config->raid.disk[drive].flags |= PR_F_ONLINE;
1363 if (rdp->disks[drive].flags & AR_DF_PRESENT)
1364 config->raid.disk[drive].flags = (PR_F_REDIR | PR_F_DOWN);
1365 if (rdp->disks[drive].flags & AR_DF_SPARE)
1366 config->raid.disk[drive].flags |= PR_F_SPARE;
1367 config->raid.disk[drive].dummy_0 = 0x0;
1368 if (rdp->disks[drive].device) {
1369 config->raid.disk[drive].channel =
1370 rdp->disks[drive].device->channel->unit;
1371 config->raid.disk[drive].device =
1372 (rdp->disks[drive].device->unit != 0);
1374 config->raid.disk[drive].magic_0 =
1375 PR_MAGIC0(rdp->disks[drive]) | timestamp.tv_sec;
1378 config->checksum = 0;
1379 for (ckptr = (int32_t *)config, count = 0; count < 511; count++)
1380 config->checksum += *ckptr++;
1381 if (rdp->disks[disk].device && rdp->disks[disk].device->driver &&
1382 !(rdp->disks[disk].device->flags & ATA_D_DETACHING)) {
1383 if (ar_rw(AD_SOFTC(rdp->disks[disk]),
1384 PR_LBA(AD_SOFTC(rdp->disks[disk])),
1385 sizeof(struct promise_raid_conf),
1386 (caddr_t)config, AR_WRITE)) {
1387 printf("ar%d: %s write conf failed\n",
1388 rdp->lun, local ? "FreeBSD" : "Promise");
1397 ar_rw_done(struct buf *bp)
1399 free(bp->b_data, M_AR);
1404 ar_rw(struct ad_softc *adp, u_int32_t lba, int count, caddr_t data, int flags)
1407 int retry = 0, error = 0;
1409 if (!(bp = (struct buf *)malloc(sizeof(struct buf), M_AR, M_NOWAIT|M_ZERO)))
1412 BUF_LOCK(bp, LK_EXCLUSIVE);
1413 bp->b_dev = adp->dev;
1416 bp->b_bcount = count;
1417 if (flags & AR_WAIT)
1418 bp->b_iodone = (void *)wakeup;
1420 bp->b_iodone = ar_rw_done;
1421 bp->b_flags = B_CALL;
1422 if (flags & AR_READ)
1423 bp->b_flags |= B_READ;
1424 if (flags & AR_WRITE)
1425 bp->b_flags |= B_WRITE;
1427 AR_STRATEGY((struct buf *)bp);
1429 if (flags & AR_WAIT) {
1430 while ((retry++ < (15*hz/10)) && (error = !(bp->b_flags & B_DONE)))
1431 error = tsleep(bp, PRIBIO, "arrw", 10);
1432 if (!error && (bp->b_flags & B_ERROR))
1433 error = bp->b_error;
1439 static struct ata_device *
1440 ar_locate_disk(int diskno)
1442 struct ata_channel *ch;
1445 for (ctlr = 0; ctlr < devclass_get_maxunit(ata_devclass); ctlr++) {
1446 if (!(ch = devclass_get_softc(ata_devclass, ctlr)))
1448 if (ch->devices & ATA_ATA_MASTER)
1449 if (ch->device[MASTER].driver &&
1450 ((struct ad_softc *)(ch->device[MASTER].driver))->lun == diskno)
1451 return &ch->device[MASTER];
1452 if (ch->devices & ATA_ATA_SLAVE)
1453 if (ch->device[SLAVE].driver &&
1454 ((struct ad_softc *)(ch->device[SLAVE].driver))->lun == diskno)
1455 return &ch->device[SLAVE];