diff options
-rw-r--r-- | sys/dev/ata/ata-all.c | 2 | ||||
-rw-r--r-- | sys/dev/ata/ata-dma.c | 93 | ||||
-rw-r--r-- | sys/dev/ata/ata-pci.c | 15 | ||||
-rw-r--r-- | sys/dev/ata/ata-raid.c | 105 | ||||
-rw-r--r-- | sys/dev/ata/ata-raid.h | 13 |
5 files changed, 117 insertions, 111 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index cfe02f0..de10f7a 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -572,7 +572,7 @@ ata_intr(void *data) case ATA_IDLE: if (ch->flags & ATA_QUEUED) { - ch->active = ATA_ACTIVE; /* XXX */ + ch->active = ATA_ACTIVE; if (ata_service(ch) == ATA_OP_CONTINUES) return; } diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c index fbcbf70..f003049 100644 --- a/sys/dev/ata/ata-dma.c +++ b/sys/dev/ata/ata-dma.c @@ -47,6 +47,7 @@ static void cyrix_timing(struct ata_channel *, int, int); static void promise_timing(struct ata_channel *, int, int); static void hpt_timing(struct ata_channel *, int, int); +static int hpt_cable80(struct ata_channel *); /* misc defines */ #ifdef __alpha__ @@ -928,11 +929,10 @@ via_82c586: case 0x00041103: /* HighPoint HPT366/368/370/372 controllers */ case 0x00051103: /* HighPoint HPT372 controllers */ case 0x00081103: /* HighPoint HPT374 controllers */ - if (!ATAPI_DEVICE(ch, device) && udmamode >= 6 && + if (!ATAPI_DEVICE(ch, device) && udmamode >= 6 && hpt_cable80(ch) && ((ch->chiptype == 0x00041103 && pci_get_revid(parent) >= 0x05) || (ch->chiptype == 0x00051103 && pci_get_revid(parent) >= 0x01) || - (ch->chiptype == 0x00081103 && pci_get_revid(parent) >= 0x07)) && - !(pci_read_config(parent, 0x5a, 1) & (ch->unit ? 0x01:0x02))) { + (ch->chiptype == 0x00081103 && pci_get_revid(parent) >= 0x07))) { error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA6, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) @@ -944,11 +944,10 @@ via_82c586: return; } } - if (!ATAPI_DEVICE(ch, device) && udmamode >= 5 && + if (!ATAPI_DEVICE(ch, device) && udmamode >= 5 && hpt_cable80(ch) && ((ch->chiptype == 0x00041103 && pci_get_revid(parent) >= 0x05) || (ch->chiptype == 0x00051103 && pci_get_revid(parent) >= 0x01) || - (ch->chiptype == 0x00081103 && pci_get_revid(parent) >= 0x07)) && - !(pci_read_config(parent, 0x5a, 1) & (ch->unit ? 0x01:0x02))) { + (ch->chiptype == 0x00081103 && pci_get_revid(parent) >= 0x07))) { error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) @@ -960,8 +959,7 @@ via_82c586: return; } } - if (!ATAPI_DEVICE(ch, device) && udmamode >= 4 && - !(pci_read_config(parent, 0x5a, 1) & (ch->unit ? 0x01:0x02))) { + if (!ATAPI_DEVICE(ch, device) && udmamode >= 4 && hpt_cable80(ch)) { error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) @@ -1217,6 +1215,7 @@ hpt_timing(struct ata_channel *ch, int devno, int mode) { device_t parent = device_get_parent(ch->dev); u_int32_t timing; + if (ch->chiptype == 0x00081103 && pci_get_revid(parent) >= 0x07) { switch (mode) { /* HPT374 */ case ATA_PIO0: timing = 0x0ac1f48a; break; @@ -1231,9 +1230,6 @@ hpt_timing(struct ata_channel *ch, int devno, int mode) case ATA_UDMA6: timing = 0x12808242; break; default: timing = 0x0d029d5e; } - pci_write_config(parent, 0x40 + (devno << 2) , timing, 4); - pci_write_config(parent, 0x5b, - (pci_read_config(parent, 0x5b, 1) & 0x01) | 0x20, 1); } else if ((ch->chiptype == 0x00041103 && pci_get_revid(parent) >= 0x05) || (ch->chiptype == 0x00051103 && pci_get_revid(parent) >= 0x01)) { @@ -1250,9 +1246,6 @@ hpt_timing(struct ata_channel *ch, int devno, int mode) case ATA_UDMA6: timing = 0x1c81dc62; break; default: timing = 0x0d029d5e; } - pci_write_config(parent, 0x40 + (devno << 2) , timing, 4); - pci_write_config(parent, 0x5b, - (pci_read_config(parent, 0x5b, 1) & 0x01) | 0x20, 1); } else if (ch->chiptype == 0x00041103 && pci_get_revid(parent) >= 0x03) { switch (mode) { /* HPT370 */ @@ -1268,50 +1261,70 @@ hpt_timing(struct ata_channel *ch, int devno, int mode) default: timing = 0x06514e57; } pci_write_config(parent, 0x40 + (devno << 2) , timing, 4); - pci_write_config(parent, 0x5b, 0x22, 1); } else { /* HPT36[68] */ switch (pci_read_config(parent, 0x41 + (devno << 2), 1)) { case 0x85: /* 25Mhz */ switch (mode) { - case ATA_PIO0: timing = 0xc0d08585; break; - case ATA_PIO1: timing = 0xc0d08572; break; - case ATA_PIO2: timing = 0xc0ca8542; break; - case ATA_PIO3: timing = 0xc0ca8532; break; - case ATA_PIO4: timing = 0xc0ca8521; break; - case ATA_WDMA2: timing = 0xa0ca8521; break; - case ATA_UDMA2: timing = 0x90cf8521; break; - case ATA_UDMA4: timing = 0x90c98521; break; + case ATA_PIO0: timing = 0x40d08585; break; + case ATA_PIO1: timing = 0x40d08572; break; + case ATA_PIO2: timing = 0x40ca8542; break; + case ATA_PIO3: timing = 0x40ca8532; break; + case ATA_PIO4: timing = 0x40ca8521; break; + case ATA_WDMA2: timing = 0x20ca8521; break; + case ATA_UDMA2: timing = 0x10cf8521; break; + case ATA_UDMA4: timing = 0x10c98521; break; default: timing = 0x01208585; } break; default: case 0xa7: /* 33MHz */ switch (mode) { - case ATA_PIO0: timing = 0xc0d0a7aa; break; - case ATA_PIO1: timing = 0xc0d0a7a3; break; - case ATA_PIO2: timing = 0xc0d0a753; break; - case ATA_PIO3: timing = 0xc0c8a742; break; - case ATA_PIO4: timing = 0xc0c8a731; break; - case ATA_WDMA2: timing = 0xa0c8a731; break; - case ATA_UDMA2: timing = 0x90caa731; break; - case ATA_UDMA4: timing = 0x90c9a731; break; + case ATA_PIO0: timing = 0x40d0a7aa; break; + case ATA_PIO1: timing = 0x40d0a7a3; break; + case ATA_PIO2: timing = 0x40d0a753; break; + case ATA_PIO3: timing = 0x40c8a742; break; + case ATA_PIO4: timing = 0x40c8a731; break; + case ATA_WDMA2: timing = 0x20c8a731; break; + case ATA_UDMA2: timing = 0x10caa731; break; + case ATA_UDMA4: timing = 0x10c9a731; break; default: timing = 0x0120a7a7; } break; case 0xd9: /* 40Mhz */ switch (mode) { - case ATA_PIO0: timing = 0xc018d9d9; break; - case ATA_PIO1: timing = 0xc010d9c7; break; - case ATA_PIO2: timing = 0xc010d997; break; - case ATA_PIO3: timing = 0xc010d974; break; - case ATA_PIO4: timing = 0xc008d963; break; - case ATA_WDMA2: timing = 0xa008d943; break; - case ATA_UDMA2: timing = 0x900bd943; break; - case ATA_UDMA4: timing = 0x900fd943; break; + case ATA_PIO0: timing = 0x4018d9d9; break; + case ATA_PIO1: timing = 0x4010d9c7; break; + case ATA_PIO2: timing = 0x4010d997; break; + case ATA_PIO3: timing = 0x4010d974; break; + case ATA_PIO4: timing = 0x4008d963; break; + case ATA_WDMA2: timing = 0x2008d943; break; + case ATA_UDMA2: timing = 0x100bd943; break; + case ATA_UDMA4: timing = 0x100fd943; break; default: timing = 0x0120d9d9; } } - pci_write_config(parent, 0x40 + (devno << 2), (timing & ~0x80000000),4); } + pci_write_config(parent, 0x40 + (devno << 2) , timing, 4); +} + +static int +hpt_cable80(struct ata_channel *ch) +{ + device_t parent = device_get_parent(ch->dev); + u_int8_t reg, val, res; + + if (ch->chiptype == 0x00081103 && pci_get_function(parent) == 1) { + reg = ch->unit ? 0x57 : 0x53; + val = pci_read_config(parent, reg, 1); + pci_write_config(parent, reg, val | 0x80, 1); + } + else { + reg = 0x5b; + val = pci_read_config(parent, reg, 1); + pci_write_config(parent, reg, val & 0xfe, 1); + } + res = pci_read_config(parent, 0x5a, 1) & (ch->unit ? 0x01 : 0x02); + pci_write_config(parent, reg, val, 1); + return !res; } diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c index 60bd1c9..f39fc88 100644 --- a/sys/dev/ata/ata-pci.c +++ b/sys/dev/ata/ata-pci.c @@ -399,7 +399,16 @@ ata_pci_attach(device_t dev) (pci_read_config(dev, 0x51, 1) & ~0x80), 1); break; } - /* FALLTHROUGH */ + /* turn off interrupt prediction */ + pci_write_config(dev, 0x51, (pci_read_config(dev, 0x51, 1) & ~0x03), 1); + pci_write_config(dev, 0x55, (pci_read_config(dev, 0x55, 1) & ~0x03), 1); + + /* turn on interrupts */ + pci_write_config(dev, 0x5a, (pci_read_config(dev, 0x5a, 1) & ~0x10), 1); + + /* set clocks etc */ + pci_write_config(dev, 0x5b, 0x22, 1); + break; case 0x00051103: /* HighPoint HPT372 */ case 0x00081103: /* HighPoint HPT374 */ @@ -409,6 +418,10 @@ ata_pci_attach(device_t dev) /* turn on interrupts */ pci_write_config(dev, 0x5a, (pci_read_config(dev, 0x5a, 1) & ~0x10), 1); + + /* set clocks etc */ + pci_write_config(dev, 0x5b, + (pci_read_config(dev, 0x5b, 1) & 0x01) | 0x20, 1); break; case 0x05711106: /* VIA 82C586, '596, '686 default setup */ diff --git a/sys/dev/ata/ata-raid.c b/sys/dev/ata/ata-raid.c index 0f61f4f..a850c08 100644 --- a/sys/dev/ata/ata-raid.c +++ b/sys/dev/ata/ata-raid.c @@ -272,6 +272,7 @@ arstrategy(struct bio *bp) biodone(bp); return; } + bp->bio_resid = bp->bio_bcount; blkno = bp->bio_pblkno; data = bp->bio_data; @@ -622,6 +623,7 @@ ar_rebuild(struct ar_softc *rdp) rdp->lock_end = rdp->lock_start + size; wakeup(rdp); } + rdp->lock_start = 0xffffffff; free(buffer, M_AR); for (disk = 0; disk < rdp->total_disks; disk++) { if ((rdp->disks[disk].flags&(AR_DF_PRESENT|AR_DF_ONLINE|AR_DF_SPARE))== @@ -684,31 +686,29 @@ ar_highpoint_read_conf(struct ad_softc *adp, struct ar_softc **raidp) switch (info->type) { case HPT_T_RAID0: - case HPT_T_RAID01_RAID0: - /* check the order byte to determine what this really is */ - switch (info->order) { - case HPT_O_DOWN: - if (raid->magic_0 && raid->magic_0 != info->magic_0) - continue; - raid->magic_0 = info->magic_0; - raid->magic_1 = info->magic_1; - raid->flags |= AR_F_RAID0; - raid->interleave = 1 << info->stripe_shift; - disk_number = info->disk_number; + if (info->order & (HPT_O_OK | HPT_O_RAID1)) + goto highpoint_raid01; + if (raid->magic_0 && raid->magic_0 != info->magic_0) + continue; + raid->magic_0 = info->magic_0; + raid->flags |= AR_F_RAID0; + raid->interleave = 1 << info->stripe_shift; + disk_number = info->disk_number; + if (!(info->order & HPT_O_RAID0)) info->magic = 0; /* mark bad */ - break; + break; - case HPT_O_RAID01DEGRADED: - if (raid->magic_0 && raid->magic_0 != info->magic_0) - continue; - raid->magic_0 = info->magic_0; - raid->magic_1 = info->magic_1; - raid->flags |= AR_F_RAID0; - raid->interleave = 1 << info->stripe_shift; - disk_number = info->disk_number; - break; + case HPT_T_RAID1: + if (raid->magic_0 && raid->magic_0 != info->magic_0) + continue; + raid->magic_0 = info->magic_0; + raid->flags |= AR_F_RAID1; + disk_number = (info->disk_number > 0); + break; - case HPT_O_RAID01SRC: + case HPT_T_RAID01_RAID0: +highpoint_raid01: + if (info->order & HPT_O_OK) { if ((raid->magic_0 && raid->magic_0 != info->magic_0) || (raid->magic_1 && raid->magic_1 != info->magic_1)) continue; @@ -717,36 +717,19 @@ ar_highpoint_read_conf(struct ad_softc *adp, struct ar_softc **raidp) raid->flags |= (AR_F_RAID0 | AR_F_RAID1); raid->interleave = 1 << info->stripe_shift; disk_number = info->disk_number; - break; - - case HPT_O_RAID01DST: + } + else { if (raid->magic_1 && raid->magic_1 != info->magic_1) continue; raid->magic_1 = info->magic_1; raid->flags |= (AR_F_RAID0 | AR_F_RAID1); raid->interleave = 1 << info->stripe_shift; disk_number = info->disk_number + info->array_width; - break; - - case HPT_O_READY: - if (raid->magic_0 && raid->magic_0 != info->magic_0) - continue; - raid->magic_0 = info->magic_0; - raid->flags |= AR_F_RAID0; - raid->interleave = 1 << info->stripe_shift; - disk_number = info->disk_number; - break; + if (!(info->order & HPT_O_RAID1)) + info->magic = 0; /* mark bad */ } break; - case HPT_T_RAID1: - if (raid->magic_0 && raid->magic_0 != info->magic_0) - continue; - raid->magic_0 = info->magic_0; - raid->flags |= AR_F_RAID1; - disk_number = (info->disk_number > 0); - break; - case HPT_T_SPAN: if (raid->magic_0 && raid->magic_0 != info->magic_0) continue; @@ -764,10 +747,10 @@ ar_highpoint_read_conf(struct ad_softc *adp, struct ar_softc **raidp) raid->flags |= AR_F_HIGHPOINT_RAID; raid->disks[disk_number].device = adp->device; raid->disks[disk_number].flags = (AR_DF_PRESENT | AR_DF_ASSIGNED); + raid->lun = array; if (info->magic == HPT_MAGIC_OK) { raid->disks[disk_number].flags |= AR_DF_ONLINE; raid->flags |= AR_F_READY; - raid->lun = array; raid->width = info->array_width; raid->heads = 255; raid->sectors = 63; @@ -775,6 +758,7 @@ ar_highpoint_read_conf(struct ad_softc *adp, struct ar_softc **raidp) raid->total_sectors = info->total_sectors; raid->offset = HPT_LBA + 1; raid->reserved = HPT_LBA + 1; + raid->lock_start = raid->lock_end = info->rebuild_lba; raid->disks[disk_number].disk_sectors = info->total_sectors / info->array_width; } @@ -801,7 +785,7 @@ ar_highpoint_write_conf(struct ar_softc *rdp) int disk; microtime(×tamp); - rdp->magic_0 = timestamp.tv_sec + 1; + rdp->magic_0 = timestamp.tv_sec + 2; rdp->magic_1 = timestamp.tv_sec; for (disk = 0; disk < rdp->total_disks; disk++) { @@ -816,43 +800,40 @@ ar_highpoint_write_conf(struct ar_softc *rdp) config->magic = HPT_MAGIC_OK; if (rdp->disks[disk].flags & AR_DF_ASSIGNED) { config->magic_0 = rdp->magic_0; - config->magic_2 = HPT_MAGIC_2; - strcpy(config->name_1, "FreeBSD ATARAID"); + strcpy(config->name_1, "FreeBSD"); } config->disk_number = disk; switch (rdp->flags & (AR_F_RAID0 | AR_F_RAID1 | AR_F_SPAN)) { case AR_F_RAID0: config->type = HPT_T_RAID0; + strcpy(config->name_2, "RAID 0"); if (rdp->disks[disk].flags & AR_DF_ONLINE) - config->order = HPT_O_READY; - else - config->order = HPT_O_DOWN; - strcpy(config->name_2, "RAID 0"); + config->order = HPT_O_RAID0; break; case AR_F_RAID1: config->type = HPT_T_RAID1; - config->disk_number = (disk < rdp->width) ? disk : disk + 10; strcpy(config->name_2, "RAID 1"); + config->disk_number = (disk < rdp->width) ? disk : disk + 10; break; case AR_F_RAID0 | AR_F_RAID1: - config->magic_1 = rdp->magic_1; config->type = HPT_T_RAID01_RAID0; - if (rdp->disks[disk].flags & AR_DF_ONLINE) + strcpy(config->name_2, "RAID 0+1"); + if (rdp->disks[disk].flags & AR_DF_ONLINE) { if (disk < rdp->width) { - config->order = HPT_O_RAID01SRC; + config->order = (HPT_O_OK | HPT_O_RAID1); config->magic_0 = rdp->magic_0 - 1; - strcpy(config->name_2, "RAID 0+1 SRC"); } else { - config->order = HPT_O_RAID01DST; + config->order = HPT_O_RAID1; config->disk_number -= rdp->width; - strcpy(config->name_2, "RAID 0+1 DST"); } - else - config->order = HPT_O_DOWN; + } + else + config->magic_0 = rdp->magic_0 - 1; + config->magic_1 = rdp->magic_1; break; case AR_F_SPAN: @@ -864,6 +845,7 @@ ar_highpoint_write_conf(struct ar_softc *rdp) config->array_width = rdp->width; config->stripe_shift = (rdp->width > 1) ? (ffs(rdp->interleave)-1) : 0; config->total_sectors = rdp->total_sectors; + config->rebuild_lba = rdp->lock_start; if ((rdp->disks[disk].flags & AR_DF_PRESENT) && rdp->disks[disk].device && rdp->disks[disk].device->driver && @@ -986,6 +968,7 @@ ar_promise_read_conf(struct ad_softc *adp, struct ar_softc **raidp) raid->total_sectors = info->raid.total_sectors; raid->offset = 0; raid->reserved = 63; + raid->lock_start = raid->lock_end = info->raid.rebuild_lba; /* convert disk flags to our internal types */ for (disk = 0; disk < info->raid.total_disks; disk++) { @@ -1062,7 +1045,7 @@ ar_promise_write_conf(struct ar_softc *rdp) /*config->raid.disk_offset*/ } config->raid.magic_0 = config->magic_0; - config->raid.rebuild_lba = 0xffffffff; + config->raid.rebuild_lba = rdp->lock_start; config->raid.generation = rdp->generation; if (rdp->flags & AR_F_READY) { diff --git a/sys/dev/ata/ata-raid.h b/sys/dev/ata/ata-raid.h index 03a7e16..8de947e 100644 --- a/sys/dev/ata/ata-raid.h +++ b/sys/dev/ata/ata-raid.h @@ -82,7 +82,7 @@ struct ar_softc { struct ar_buf { struct bio bp; /* must be first element! */ - struct bio *org; + struct bio *org; struct ar_buf *mirror; int drive; int flags; @@ -100,11 +100,9 @@ struct highpoint_raid_conf { u_int32_t magic_0; u_int32_t magic_1; u_int32_t order; -#define HPT_O_DOWN 0x00 -#define HPT_O_RAID01DEGRADED 0x01 -#define HPT_O_RAID01DST 0x02 -#define HPT_O_RAID01SRC 0x03 -#define HPT_O_READY 0x04 +#define HPT_O_OK 0x01 +#define HPT_O_RAID1 0x02 +#define HPT_O_RAID0 0x04 u_int8_t array_width; u_int8_t stripe_shift; @@ -138,8 +136,7 @@ struct highpoint_raid_conf { u_int32_t lba; } errorlog[32]; int8_t filler2[16]; - u_int32_t magic_2; -#define HPT_MAGIC_2 0x7fffffff + u_int32_t rebuild_lba; u_int8_t dummy_1; u_int8_t name_1[15]; u_int8_t dummy_2; |