kern/80042: FreeBSD 5.4 RC2: Promise PDC20265 on A7V mobo + Maxtor
6B200P0/BAH41BM0 gives only 268435455 instead of 398297088 sectors
Martin Birgmeier
nobody at junk.com
Sun Apr 17 13:30:12 PDT 2005
>Number: 80042
>Category: kern
>Synopsis: FreeBSD 5.4 RC2: Promise PDC20265 on A7V mobo + Maxtor 6B200P0/BAH41BM0 gives only 268435455 instead of 398297088 sectors
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Sun Apr 17 20:30:11 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator: Martin Birgmeier
>Release: FreeBSD 5.4 RC2 (built from RELENG_5_4 dated 2005-04-14)
>Organization:
MBi at home
>Environment:
FreeBSD 5.4 RC2 (built from RELENG_5_4 dated 2005-04-14)
(see also output of scanpci -v and atacontrol cap 3 1 at end of PR)
>Description:
I cannot use a Maxtor 6B200P0/BAH41BM0 200 GB disk on the Promise
controller built into the A7V motherboard (Promise PDC20265)
under FreeBSD 5.4 RC2. I can read up to sector 268435454, but
reading from sector 268435455 will time out.
Note 1: Under RELENG_5_3_0_RELEASE, the system would hang indefinitely.
Note 2: Under RELENG_4_11_0_RELEASE (which is what I am using to
write this defect report), I can use the disk after applying
the following fixes (they are merged from trunk somewhere after
RELENG_4 branched, and also include some minor other stuff
dealing with additional PCI IDs):
======================================================================
*** sys/dev/ata/ata-all.c.ORIG Fri Jan 14 00:03:12 2005
--- sys/dev/ata/ata-all.c Tue Mar 1 19:05:19 2005
***************
*** 1073,1078 ****
--- 1073,1079 ----
ata_prtdev(atadev, "can't translate cmd to 48bit version\n");
return -1;
}
+ atadev->channel->flags |= ATA_48BIT_ACTIVE;
}
else {
ATA_OUTB(atadev->channel->r_io, ATA_FEATURE, feature);
*** sys/dev/ata/ata-all.h.ORIG Fri Sep 17 22:28:30 2004
--- sys/dev/ata/ata-all.h Tue Mar 1 19:08:57 2005
***************
*** 212,217 ****
--- 212,218 ----
#define ATA_ATAPI_DMA_RO 0x04
#define ATA_QUEUED 0x08
#define ATA_DMA_ACTIVE 0x10
+ #define ATA_48BIT_ACTIVE 0x40
struct ata_device device[2]; /* devices on this channel */
#define MASTER 0x00
*** sys/dev/ata/ata-dma.c.ORIG Wed Dec 31 19:05:16 2003
--- sys/dev/ata/ata-dma.c Tue Mar 1 18:52:33 2005
***************
*** 544,549 ****
--- 544,550 ----
if (ata_find_dev(parent, 0x31471106, 0) || /* 8233a */
ata_find_dev(parent, 0x31771106, 0) || /* 8235 */
+ ata_find_dev(parent, 0x32271106, 0) || /* 8237 */
ata_find_dev(parent, 0x31491106, 0)) { /* 8237 */
udmamode = imin(udmamode, 6);
reg_val = via_modes[3];
***************
*** 1081,1088 ****
break;
case 0x4d69105a: /* Promise TX2 ATA133 controllers */
- case 0x5275105a: /* Promise TX2 ATA133 controllers */
case 0x6269105a: /* Promise TX2 ATA133 controllers */
case 0x7275105a: /* Promise TX2 ATA133 controllers */
ATA_OUTB(atadev->channel->r_bmio, ATA_BMDEVSPEC_0, 0x0b);
if (udmamode >= 6 &&
--- 1082,1090 ----
break;
case 0x4d69105a: /* Promise TX2 ATA133 controllers */
case 0x6269105a: /* Promise TX2 ATA133 controllers */
+ case 0x1275105a: /* Promise TX2 ATA133 controllers */
+ case 0x5275105a: /* Promise TX2 ATA133 controllers */
case 0x7275105a: /* Promise TX2 ATA133 controllers */
ATA_OUTB(atadev->channel->r_bmio, ATA_BMDEVSPEC_0, 0x0b);
if (udmamode >= 6 &&
***************
*** 1410,1415 ****
--- 1412,1431 ----
if (ds->flags & ATA_DS_ACTIVE)
panic("ata_dmasetup: transfer active on this device!");
+ switch(ch->chiptype) {
+ case 0x0d38105a: /* Promise Fasttrak 66 */
+ case 0x4d38105a: /* Promise Ultra/Fasttrak 66 */
+ case 0x0d30105a: /* Promise OEM ATA 100 */
+ case 0x4d30105a: /* Promise Ultra/Fasttrak 100 */
+ if (ch->flags & ATA_48BIT_ACTIVE) {
+ ATA_OUTB(ch->r_bmio, (ch->unit ? 0x09 : 0x11),
+ ATA_INB(ch->r_bmio, (ch->unit ? 0x09 : 0x11)) |
+ (ch->unit ? 0x08 : 0x02));
+ ATA_OUTL(ch->r_bmio, (ch->unit ? 0x1c : 0x20),
+ (dir ? 0x05000000 : 0x06000000) | (count >> 1));
+ }
+ }
+
cba.dmatab = ds->dmatab;
bus_dmamap_sync(ds->cdmatag, ds->cdmamap, BUS_DMASYNC_PREWRITE);
if (bus_dmamap_load(ds->ddmatag, ds->ddmamap, data, count,
***************
*** 1421,1458 ****
BUS_DMASYNC_PREWRITE);
ch->flags |= ATA_DMA_ACTIVE;
! ds->flags = ATA_DS_ACTIVE;
! if (dir)
! ds->flags |= ATA_DS_READ;
ATA_OUTL(ch->r_bmio, ATA_BMDTP_PORT, ds->mdmatab);
ATA_OUTB(ch->r_bmio, ATA_BMCMD_PORT, dir ? ATA_BMCMD_WRITE_READ : 0);
ATA_OUTB(ch->r_bmio, ATA_BMSTAT_PORT,
! (ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT) |
! (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR)));
ATA_OUTB(ch->r_bmio, ATA_BMCMD_PORT,
! ATA_INB(ch->r_bmio, ATA_BMCMD_PORT) | ATA_BMCMD_START_STOP);
return 0;
}
int
ata_dmadone(struct ata_device *atadev)
{
! struct ata_channel *ch;
! struct ata_dmastate *ds;
int error;
! ch = atadev->channel;
! ds = &atadev->dmastate;
bus_dmamap_sync(ds->ddmatag, ds->ddmamap, (ds->flags & ATA_DS_READ) != 0 ?
BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(ds->ddmatag, ds->ddmamap);
- ATA_OUTB(ch->r_bmio, ATA_BMCMD_PORT,
- ATA_INB(ch->r_bmio, ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP);
- error = ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT);
- ATA_OUTB(ch->r_bmio, ATA_BMSTAT_PORT,
- error | ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR);
ch->flags &= ~ATA_DMA_ACTIVE;
ds->flags = 0;
return (error & ATA_BMSTAT_MASK);
--- 1437,1483 ----
BUS_DMASYNC_PREWRITE);
ch->flags |= ATA_DMA_ACTIVE;
! ds->flags = dir ? (ATA_DS_ACTIVE | ATA_DS_READ) : ATA_DS_ACTIVE;
ATA_OUTL(ch->r_bmio, ATA_BMDTP_PORT, ds->mdmatab);
ATA_OUTB(ch->r_bmio, ATA_BMCMD_PORT, dir ? ATA_BMCMD_WRITE_READ : 0);
ATA_OUTB(ch->r_bmio, ATA_BMSTAT_PORT,
! (ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT) |
! (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR)));
ATA_OUTB(ch->r_bmio, ATA_BMCMD_PORT,
! ATA_INB(ch->r_bmio, ATA_BMCMD_PORT) | ATA_BMCMD_START_STOP);
return 0;
}
int
ata_dmadone(struct ata_device *atadev)
{
! struct ata_channel *ch = atadev->channel;
! struct ata_dmastate *ds = &atadev->dmastate;
int error;
! switch(ch->chiptype) {
! case 0x0d38105a: /* Promise Fasttrak 66 */
! case 0x4d38105a: /* Promise Ultra/Fasttrak 66 */
! case 0x0d30105a: /* Promise OEM ATA 100 */
! case 0x4d30105a: /* Promise Ultra/Fasttrak 100 */
! if (ch->flags & ATA_48BIT_ACTIVE) {
! ATA_OUTB(ch->r_bmio, (ch->unit ? 0x09 : 0x11),
! ATA_INB(ch->r_bmio, (ch->unit ? 0x09 : 0x11)) &
! ~(ch->unit ? 0x08 : 0x02));
! ATA_OUTL(ch->r_bmio, (ch->unit ? 0x1c : 0x20), 0);
! }
! }
!
! error = ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT);
! ATA_OUTB(ch->r_bmio, ATA_BMCMD_PORT,
! ATA_INB(ch->r_bmio, ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP);
! ATA_OUTB(ch->r_bmio, ATA_BMSTAT_PORT,ATA_BMSTAT_INTERRUPT|ATA_BMSTAT_ERROR);
!
bus_dmamap_sync(ds->ddmatag, ds->ddmamap, (ds->flags & ATA_DS_READ) != 0 ?
BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(ds->ddmatag, ds->ddmamap);
ch->flags &= ~ATA_DMA_ACTIVE;
ds->flags = 0;
return (error & ATA_BMSTAT_MASK);
*** sys/dev/ata/ata-pci.c.ORIG Wed Dec 31 19:05:16 2003
--- sys/dev/ata/ata-pci.c Sun Jul 4 09:16:32 2004
***************
*** 190,195 ****
--- 190,197 ----
return "VIA 8233 ATA133 controller";
if (ata_find_dev(dev, 0x31771106, 0))
return "VIA 8235 ATA133 controller";
+ if (ata_find_dev(dev, 0x32271106, 0))
+ return "VIA 8237 ATA133 controller";
if (ata_find_dev(dev, 0x31491106, 0))
return "VIA 8237 ATA133 controller";
return "VIA Apollo ATA controller";
======================================================================
Note 3: Since the fixes merged from trunk work on RELENG_4, there
seems to be a regression in RELENG_5.
Note 4: Whenever I issue the command under "how-to-repeat"
below, (under 5.4 RC2, of course), the disk will be trashed.
The disk is a dangerously dedicated disk (see environment
below). Trashing means that the first few sectors (including
the first superblock) are somehow overwritten. The
following are the corrupt:
- the (pseudo) fdisk information
- the disklabel for ad7 (should contain partitions c and e)
- the file system, of course
I can recover these three things if I run fsck directly in
the full disk like this:
fsck -b 32 /dev/ad7
Strangely enough, both the fdisk and disklabel seem to be
revived using this operation.
Note 5: The only thing I am not fully sure is whether the full
size which is visible under RELENG_4_11_0_RELEASE using above
patches is real... there might be a wraparound which I just
have not noticed yet, the disk currently is about 40% full.
But on the other hand, up till now everything seems to be
fine. I also checked a random sampling of superblocks throughout
the disk using
fsck -b <from newfs output> -n /dev/ad7
under RELENG_4_11_0_RELEASE, and if there were indeed a
wraparound, the file system data (40% disk full) should have
already trashed the wrapped-around superblocks, if there
were any wraparound at all.
>How-To-Repeat:
This will lead to a timeout on RELENG_5_4 dated 2005-04-14:
dd if=/dev/ad... of=/dev/null bs=512 count=1 iseek=268435455
The same command under RELENG_4_11_0_RELEASE works find.
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list