Patch for Intel ATA to try (was Re: Has anyone seen the ATA driver timeout issue again?)
Matthew Dillon
dillon at apollo.backplane.com
Wed Jun 23 09:44:22 PDT 2004
Jonathon, if you could try this patch I'd appreciate it. I tried to
hack in fixes from freebsd-5 to the intel chipset initialization
code.
-Matt
Matthew Dillon
<dillon at xxxxxxxxxxxxx>
Index: ata-dma.c
===================================================================
RCS file: /cvs/src/sys/dev/disk/ata/ata-dma.c,v
retrieving revision 1.23
diff -u -r1.23 ata-dma.c
--- ata-dma.c 23 Jun 2004 16:15:24 -0000 1.23
+++ ata-dma.c 23 Jun 2004 16:33:13 -0000
@@ -218,26 +218,63 @@
case 0x71998086: /* Intel PIIX4e */
case 0x24218086: /* Intel ICH0 */
if (udmamode >= 2) {
- int32_t mask48, new48;
+ int16_t word54;
+ u_int32_t reg40 = pci_read_config(parent, 0x40, 4);
+ u_int8_t reg44 = pci_read_config(parent, 0x44, 1);
+ u_int8_t reg48 = pci_read_config(parent, 0x48, 1);
+ u_int16_t reg4a = pci_read_config(parent, 0x4a, 2);
+ u_int16_t reg54 = pci_read_config(parent, 0x54, 2);
+ u_int32_t mask40 = 0, new40 = 0;
+ u_int8_t mask44 = 0, new44 = 0;
- error = ata_command(atadev, ATA_C_SETFEATURES, 0,
- ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
- if (bootverbose)
- ata_prtdev(atadev, "%s setting UDMA2 on Intel chip\n",
- (error) ? "failed" : "success");
- if (!error) {
- mask48 = (1 << devno) + (3 << (16 + (devno << 2)));
- new48 = (1 << devno) + (2 << (16 + (devno << 2)));
- pci_write_config(parent, 0x48,
- (pci_read_config(parent, 0x48, 4) &
- ~mask48) | new48, 4);
- ata_dmacreate(atadev, apiomode, ATA_UDMA2);
- return;
+ word54 = pci_read_config(parent, 0x54, 2);
+ if (word54 & (0x10 << devno)) {
+ error = ata_command(atadev, ATA_C_SETFEATURES, 0,
+ ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
+ if (bootverbose)
+ ata_prtdev(atadev, "%s setting UDMA2 on Intel chip\n",
+ (error) ? "failed" : "success");
+ if (!error) {
+ pci_write_config(parent, 0x48,
+ reg48 | (0x0001 << devno), 2);
+ pci_write_config(parent, 0x4a,
+ (reg4a & ~(0x3 << (devno<<2))) |
+ (0x01 + !(udmamode & 0x01)), 2);
+ pci_write_config(parent, 0x54,
+ reg54 | (0x1 << devno), 2);
+ pci_write_config(parent, 0x54,
+ reg54 & ~(0x10000 << devno), 2);
+ reg40 &= ~0x00ff00ff;
+ reg40 |= 0x40774077;
+ if (atadev->unit == ATA_MASTER) {
+ mask40 = 0x3300;
+ new40 = 0x23 << 8; /* UDMA2 timing */
+ } else {
+ mask44 = 0x0f;
+ new44 = ((0x23 & 0x30) >> 2) | (0x23 & 0x03); /*timing*/
+ }
+ if (atadev->channel->unit) {
+ mask40 <<= 16;
+ new40 <<= 16;
+ mask44 <<= 4;
+ new44 <<= 4;
+ }
+ pci_write_config(parent, 0x40,
+ (reg40 & ~mask40) | new40, 4);
+ pci_write_config(parent, 0x44,
+ (reg44 & ~mask44) | new44, 1);
+
+ ata_dmacreate(atadev, apiomode, ATA_UDMA2);
+ return;
+ }
}
}
/* make sure eventual ATA33 mode from the BIOS is disabled */
pci_write_config(parent, 0x48,
- pci_read_config(parent, 0x48, 4) & ~(1 << devno), 4);
+ pci_read_config(parent, 0x48, 2) & ~(1 << devno), 2);
+ pci_write_config(parent, 0x4a,
+ pci_read_config(parent, 0x4a, 2) & ~(0x3 << (devno << 2)), 2);
+
/* FALLTHROUGH */
case 0x70108086: /* Intel PIIX3 */
More information about the Kernel
mailing list