: :The patch contains the ata-chipset.c part twice (as nata/ata-chipset.c :and as ata-chipset.c). After removing the last one, it applied cleanly :from sys/dev/disk. : :But it still doesn't work. :( : :NATA output:
Try this one. -Matt Index: ata/ata-dma.c =================================================================== RCS file: /cvs/src/sys/dev/disk/ata/ata-dma.c,v retrieving revision 1.31 diff -u -r1.31 ata-dma.c --- ata/ata-dma.c 12 Dec 2006 19:01:31 -0000 1.31 +++ ata/ata-dma.c 2 Jun 2007 20:48:47 -0000 @@ -237,6 +237,19 @@ (pci_read_config(parent, 0x48, 4) & ~mask48) | new48, 4); ata_dmacreate(atadev, apiomode, ATA_UDMA2); + + { + 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); + + device_printf(atadev->channel->dev, + "regs after 40=%08x 44=%02x 48=%02x 4a=%04x 54=%04x\n", + reg40, reg44, reg48 ,reg4a, reg54); + } + return; } } Index: nata/ata-chipset.c =================================================================== RCS file: /cvs/src/sys/dev/disk/nata/ata-chipset.c,v retrieving revision 1.4 diff -u -r1.4 ata-chipset.c --- nata/ata-chipset.c 1 Jun 2007 00:31:14 -0000 1.4 +++ nata/ata-chipset.c 2 Jun 2007 22:58:43 -0000 @@ -1863,7 +1863,9 @@ u_int8_t mask44 = 0, new44 = 0; int error; u_int8_t timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x10, 0x21, 0x23, - 0x23, 0x23, 0x23, 0x23, 0x23, 0x23 }; + 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23 }; + /* PIO0 PIO1 PIO2 PIO3 PIO4 WDMA0 WDMA1 WDMA2 */ + /* UDMA0 UDMA1 UDMA2 UDMA3 UDMA4 UDMA5 UDMA6 */ mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma); @@ -1881,30 +1883,132 @@ if (error) return; + /* + * reg48: 1 bit per (primary drive 0, primary drive 1, secondary + * drive 0, secondary drive 1) + * + * 0 Disable Ultra DMA mode + * 1 Enable Ultra DMA mode + * + * reg4a: 4 bits per (primary drive 0, primary drive 1, secondary + * drive 0, secondary drive 1). + * 0000 UDMA mode 0 + * 0001 UDMA mode 1, 3, 5 + * 0010 UDMA mode 2, 4, reserved + * 0011 reserved + * (top two bits for each drive reserved) + */ + device_printf(dev, + "regs before 40=%08x 44=%02x 48=%02x 4a=%04x 54=%04x\n", + reg40, reg44, reg48 ,reg4a, reg54); + reg48 &= ~(0x0001 << devno); + reg4a &= ~(0x3 << (devno << 2)); if (mode >= ATA_UDMA0) { - pci_write_config(gparent, 0x48, reg48 | (0x0001 << devno), 2); - pci_write_config(gparent, 0x4a, - (reg4a & ~(0x3 << (devno << 2))) | - ((0x01 + !(mode & 0x01)) << (devno << 2)), 2); - } - else { - pci_write_config(gparent, 0x48, reg48 & ~(0x0001 << devno), 2); - pci_write_config(gparent, 0x4a, (reg4a & ~(0x3 << (devno << 2))), 2); + reg48 |= 0x0001 << devno; + if (mode > ATA_UDMA0) + reg4a |= (1 + !(mode & 0x01)) << (devno << 2); } - reg54 |= 0x0400; - if (mode >= ATA_UDMA2) - pci_write_config(gparent, 0x54, reg54 | (0x1 << devno), 2); - else - pci_write_config(gparent, 0x54, reg54 & ~(0x1 << devno), 2); + pci_write_config(gparent, 0x48, reg48, 2); + pci_write_config(gparent, 0x4a, reg4a, 2); + + /* + * reg54: + * + * 32:20 reserved + * 19:18 Secondary ATA signal mode + * 17:16 Primary ATA signal mode + * 00 = Normal (enabled) + * 01 = Tri-state (disabled) + * 10 = Drive Low (disabled) + * 11 = Reserved + * + * 15 Secondary drive 1 - Base Clock + * 14 Secondary drive 0 - Base Clock + * 13 Primary drive 1 - Base Clock + * 12 Primary drive 0 - Base Clock + * 0 = Select 33 MHz clock + * 1 = Select 100 Mhz clock + * + * 11 Reserved + * 10 Vendor specific (set by BIOS?) + * 09:08 Reserved + * + * 07 Secondary drive 1 - Cable Type + * 06 Secondary drive 0 - Cable Type + * 05 Primary drive 1 - Cable Type + * 04 Primary drive 0 - Cable Type + * 0 = 40 Conductor + * 1 = 80 Conductor (or high speed cable) + * + * 03 Secondary drive 1 - Select 33/66 clock + * 02 Secondary drive 0 - Select 33/66 clock + * 01 Primary drive 1 - Select 33/66 clock + * 00 Primary drive 0 - Select 33/66 clock + * 0 = Select 33 MHz + * 1 = Select 66 MHz + * + * It is unclear what this should be set to when operating + * in 100MHz mode. + * + * NOTE: UDMA2 = 33 MHz + * UDMA3 = 40 MHz (?) - unsupported + * UDMA4 = 66 MHz + * UDMA5 = 100 MHz + * UDMA6 = 133 Mhz + */ + reg54 |= 0x0400; /* set vendor specific bit */ + reg54 &= ~((0x1 << devno) | (0x1000 << devno)); if (mode >= ATA_UDMA5) - pci_write_config(gparent, 0x54, reg54 | (0x1000 << devno), 2); - else - pci_write_config(gparent, 0x54, reg54 & ~(0x1000 << devno), 2); + reg54 |= (0x1000 << devno); + else if (mode >= ATA_UDMA3) /* XXX should this be ATA_UDMA3 or 4? */ + reg54 |= (0x1 << devno); - reg40 &= ~0x00ff00ff; - reg40 |= 0x40774077; + pci_write_config(gparent, 0x54, reg54, 2); + + /* + * Reg40 (32 bits... well, actually two 16 bit registers) + * + * Primary channel bits 15:00, Secondary channel bits 31:00. Note + * that slave timings are handled in register 44. + * + * 15 ATA Decode Enable (R/W) 1 = enable decoding of I/O ranges + * + * 14 Slave ATA Timing Register Enable (R/W) + * + * 13:12 IORDY Sample Mode + * 00 PIO-0 + * 01 PIO-2, SW-2 + * 10 PIO-3, PIO-4, MW-1, MW-2 + * 11 Reserved + * + * 11:10 Reserved + * + * 09:08 Recovery Mode + * 00 PIO-0, PIO-2, SW-2 + * 01 PIO-3, MW-1 + * 10 Reserved + * 11 PIO-4, MW-2 + * + * 07:04 Secondary Device Control Bits + * 03:00 Primary Device Control Bits + * + * bit 3 DMA Timing Enable + * + * bit 2 Indicate Presence of ATA(1) or ATAPI(0) device + * + * bit 1 Enable IORDY sample point capability for PIO + * xfers. Always enabled for PIO4 and PIO3, enabled + * for PIO2 if indicated by the device, and otherwise + * probably should be 0. + * + * bit 0 Fast Drive Timing Enable. Enables faster then PIO-0 + * timing modes. + */ + /* + * Modify reg40 according to the table + */ if (atadev->unit == ATA_MASTER) { mask40 = 0x3300; new40 = timings[ata_mode2idx(mode)] << 8; @@ -1914,6 +2018,45 @@ new44 = ((timings[ata_mode2idx(mode)] & 0x30) >> 2) | (timings[ata_mode2idx(mode)] & 0x03); } + + /* + * Slave ATA timing register enable + */ + mask40 |= 0x4000; + new40 |= 0x4000; + + /* + * Device control bits 3:0 for master, 7:4 for slave. + * + * bit3 DMA Timing enable. + * bit2 Indicate presence of ATA(1) or ATAPI(0) device, set accordingly + * bit1 Enable IORDY sample point capability for PIO xfers. Always + * enabled for PIO4 and PIO3, enabled for PIO2 if indicated by + * the device, and otherwise should be 0. + * bit0 Fast Drive Timing Enable. Enable faster then PIO-0 timing modes. + * + * Set to: 0 x 1 1 + */ + + if (atadev->unit == ATA_MASTER) { + mask40 |= 0x0F; + new40 |= 0x03; + if (!ata_atapi(dev)) + new40 |= 0x04; + } else { + mask40 |= 0xF0; + new40 |= 0x30; + if (!ata_atapi(dev)) + new40 |= 0x40; + } + /* + reg40 &= ~0x00ff00ff; + reg40 |= 0x40774077; + */ + + /* + * Primary or Secondary controller + */ if (ch->unit) { mask40 <<= 16; new40 <<= 16; @@ -1923,6 +2066,15 @@ pci_write_config(gparent, 0x40, (reg40 & ~mask40) | new40, 4); pci_write_config(gparent, 0x44, (reg44 & ~mask44) | new44, 1); + reg40 = pci_read_config(gparent, 0x40, 4); + reg44 = pci_read_config(gparent, 0x44, 1); + reg48 = pci_read_config(gparent, 0x48, 1); + reg4a = pci_read_config(gparent, 0x4a, 2); + reg54 = pci_read_config(gparent, 0x54, 2); + device_printf(dev, + "regs after 40=%08x 44=%02x 48=%02x 4a=%04x 54=%04x\n", + reg40, reg44, reg48 ,reg4a, reg54); + atadev->mode = mode; }