Messages in this thread Patch in this message | | | Date | Fri, 4 Jun 1999 11:02:59 -0500 (CDT) | From | "Andre M. Hedrick" <> | Subject | Re: IDE autotuning with PIIX fails (2.3.3) |
| |
On 4 Jun 1999, Kevin Buhr wrote:
> DAVID BALAZIC <david.balazic@uni-mb.si> writes: > > > > I tried the PIO autotuning feature of hdparm under kernel 2.3.3 > > with PIIX support. I have an Abit BH-6 board ( Intel BX chip set, > > PIIX4, Teac CD532E-B secondary master )
This patch now does DMA/PIO tuning at the correct location.
> On a related note, using bootup autotuning with PIIX support under > 2.3.5 (by providing an "ide0=autotune" boot argument) will cause an > Oops.
This will work again now.
> The culprit is the "ide_wait_cmd()" call at the end of > "piix_tune_drive()". The code in "ide-probe.c" that does bootup > autotuning calls the interface's "tuneproc" before "init_irq()" (which > assigns the drive to an "hwgroup") has been called. Therefore, the > drive's "hwgroup" is still NULL, and after the call trace > ide_wait_cmd->ide_do_drive_cmd->do_hwgroup_request, we crash when we > try to lock on the "&hwgroup->spinlock".
I know an corrected that problem but it has not gotten there yet. This patch will solve that issue.
> else? Or should bootup autotuning be abandoned altogether?
Nope, it is just a real pain to write code that you can not fully test. I have now tested this code and it works.
Andre Hedrick The Linux IDE guy
Uniform Multi-Platform E-IDE driver Revision: 6.19 PIIX4: IDE controller on PCI bus 00 dev 39 PIIX4: not 100% native mode: will probe irqs later ide0: BM-DMA at 0xffa0-0xffa7, BIOS settings: hda:DMA, hdb:DMA ide1: BM-DMA at 0xffa8-0xffaf, BIOS settings: hdc:DMA, hdd:pio hda: WDC AC34300L, ATA DISK drive hdb: Conner Peripherals 1620MB - CFS1621A, ATA DISK drive hdc: FX320S, ATAPI CDROM drive ide0 at 0x1f0-0x1f7,0x3f6 on irq 14 ide1 at 0x170-0x177,0x376 on irq 15 hda: WDC AC34300L, 4104MB w/256kB Cache, CHS=523/255/63, UDMA(33) hdb: Conner Peripherals 1620MB - CFS1621A, 1548MB w/0kB Cache, CHS=786/64/63 hdc: ATAPI 32X CD-ROM drive, 256kB Cache, DMA Uniform CDROM driver Revision: 2.55
hdparm -tT /dev/hda
/dev/hda: Timing buffer-cache reads: 64 MB in 0.59 seconds =108.47 MB/sec Timing buffered disk reads: 32 MB in 3.63 seconds = 8.82 MB/sec
/dev/hdb: Timing buffer-cache reads: 64 MB in 0.56 seconds =114.29 MB/sec Timing buffered disk reads: 32 MB in 27.43 seconds = 1.17 MB/sec
/dev/hdc: Timing buffer-cache reads: 64 MB in 0.55 seconds =116.36 MB/sec Timing buffered disk reads: 32 MB in 17.18 seconds = 1.86 MB/sec
Sirius:/proc/bus/pci/00# hexdump 07.1 0000000 8086 7111 0005 0280 8001 0101 4000 0000 0000010 0000 0000 0000 0000 0000 0000 0000 0000 0000020 ffa1 0000 0000 0000 0000 0000 0000 0000 0000030 0000 0000 0000 0000 0000 0000 0000 0000 0000040 c000 c000 0000 0000 0001 0002 0000 0000 0000050 0000 0000 0000 0000 0000 0000 0000 0000
Uniform Multi-Platform E-IDE driver Revision: 6.19 PIIX4: IDE controller on PCI bus 00 dev 39 PIIX4: not 100% native mode: will probe irqs later ide0: BM-DMA at 0xffa0-0xffa7, BIOS settings: hda:DMA, hdb:DMA ide1: BM-DMA at 0xffa8-0xffaf, BIOS settings: hdc:DMA, hdd:pio hda: WDC AC34300L, ATA DISK drive hdb: Conner Peripherals 1620MB - CFS1621A, ATA DISK drive hdc: FX320S, ATAPI CDROM drive ide0 at 0x1f0-0x1f7,0x3f6 on irq 14 ide1 at 0x170-0x177,0x376 on irq 15 hda: UDMA 2 drive0 hda: WDC AC34300L, 4104MB w/256kB Cache, CHS=523/255/63, UDMA(33) hdb: MW DMA 2 drive1 hdb: Conner Peripherals 1620MB - CFS1621A, 1548MB w/0kB Cache, CHS=786/64/63, DMA hdc: MW DMA 2 drive2 hdc: ATAPI 32X CD-ROM drive, 256kB Cache, DMA
hdparm -tT /dev/hda
/dev/hda: Timing buffer-cache reads: 64 MB in 0.58 seconds =110.34 MB/sec Timing buffered disk reads: 32 MB in 3.63 seconds = 8.82 MB/sec
/dev/hdb: Timing buffer-cache reads: 64 MB in 0.56 seconds =114.29 MB/sec Timing buffered disk reads: 32 MB in 8.08 seconds = 3.96 MB/sec
/dev/hdc: Timing buffer-cache reads: 64 MB in 0.54 seconds =118.52 MB/sec Timing buffered disk reads: 32 MB in 17.16 seconds = 1.86 MB/sec
Sirius:/proc/bus/pci/00# hexdump 07.1 0000000 8086 7111 0005 0280 8001 0101 4000 0000 0000010 0000 0000 0000 0000 0000 0000 0000 0000 0000020 ffa1 0000 0000 0000 0000 0000 0000 0000 0000030 0000 0000 0000 0000 0000 0000 0000 0000 0000040 e377 e307 000b 0000 0001 0002 0000 0000 0000050 0000 0000 0000 0000 0000 0000 0000 0000
diff -urN linux-2.3.4-pristine/drivers/block/cy82c693.c linux/drivers/block/cy82c693.c --- linux-2.3.4-pristine/drivers/block/cy82c693.c Fri May 28 11:34:41 1999 +++ linux/drivers/block/cy82c693.c Tue Jun 1 12:30:00 1999 @@ -423,7 +423,8 @@ __initfunc(void ide_init_cy82c693(ide_hwif_t *hwif)) { hwif->chipset = ide_cy82c693; - hwif->dmaproc = &cy82c693_dmaproc; + if (hwif->dma_base) + hwif->dmaproc = &cy82c693_dmaproc; hwif->tuneproc = &cy82c693_tune_drive; init_cy82c693_chip(hwif->pci_dev); diff -urN linux-2.3.4-pristine/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c --- linux-2.3.4-pristine/drivers/block/ll_rw_blk.c Tue May 11 16:37:40 1999 +++ linux/drivers/block/ll_rw_blk.c Tue Jun 1 12:30:00 1999 @@ -471,6 +471,8 @@ case IDE3_MAJOR: case IDE4_MAJOR: case IDE5_MAJOR: + case IDE6_MAJOR: + case IDE7_MAJOR: case ACSI_MAJOR: case MFM_ACORN_MAJOR: /* diff -urN linux-2.3.4-pristine/drivers/block/ns87415.c linux/drivers/block/ns87415.c --- linux-2.3.4-pristine/drivers/block/ns87415.c Sat May 29 13:09:04 1999 +++ linux/drivers/block/ns87415.c Tue Jun 1 12:30:00 1999 @@ -166,13 +166,15 @@ #endif } - outb(0x60, hwif->dma_base + 2); + if (hwif->dma_base) + outb(0x60, hwif->dma_base + 2); if (!using_inta) hwif->irq = hwif->channel ? 15 : 14; /* legacy mode */ else if (!hwif->irq && hwif->mate && hwif->mate->irq) hwif->irq = hwif->mate->irq; /* share IRQ with mate */ - hwif->dmaproc = &ns87415_dmaproc; + if (hwif->dma_base) + hwif->dmaproc = &ns87415_dmaproc; hwif->selectproc = &ns87415_selectproc; } diff -urN linux-2.3.4-pristine/drivers/block/piix.c linux/drivers/block/piix.c --- linux-2.3.4-pristine/drivers/block/piix.c Thu May 13 13:04:54 1999 +++ linux/drivers/block/piix.c Tue Jun 1 12:30:00 1999 @@ -1,5 +1,5 @@ /* - * linux/drivers/block/piix.c Version 0.22 March 29, 1999 + * linux/drivers/block/piix.c Version 0.23 May 29, 1999 * * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer * Copyright (C) 1998-1999 Andre Hedrick, Author and Maintainer @@ -13,10 +13,10 @@ * 41 * 43 * - * | PIO 0 | c0 | 80 | 0 | - * | PIO 2 | SW2 | d0 | 90 | 4 | - * | PIO 3 | MW1 | e1 | a1 | 9 | - * | PIO 4 | MW2 | e3 | a3 | b | + * | PIO 0 | c0 | 80 | 0 | piix_tune_drive(drive, 0); + * | PIO 2 | SW2 | d0 | 90 | 4 | piix_tune_drive(drive, 2); + * | PIO 3 | MW1 | e1 | a1 | 9 | piix_tune_drive(drive, 3); + * | PIO 4 | MW2 | e3 | a3 | b | piix_tune_drive(drive, 4); * * sitre = word40 & 0x4000; primary * sitre = word42 & 0x4000; secondary @@ -58,10 +58,40 @@ #include "ide_modes.h" -#define PIIX_DMA_PROC 0 -#define PIIX_DEBUG_SET_XFER 0 #define PIIX_DEBUG_DRIVE_INFO 0 +extern char *ide_xfer_verbose (byte xfer_rate); + +/* + * + */ +static byte piix_dma_2_pio (byte xfer_rate) { + switch(xfer_rate) { + case XFER_UDMA_4: + case XFER_UDMA_3: + case XFER_UDMA_2: + case XFER_UDMA_1: + case XFER_UDMA_0: + case XFER_MW_DMA_2: + case XFER_PIO_4: + return 4; + case XFER_MW_DMA_1: + case XFER_PIO_3: + return 3; + case XFER_SW_DMA_2: + case XFER_PIO_2: + return 2; + case XFER_MW_DMA_0: + case XFER_SW_DMA_1: + case XFER_SW_DMA_0: + case XFER_PIO_1: + case XFER_PIO_0: + case XFER_PIO_SLOW: + default: + return 0; + } +} + /* * Based on settings done by AMI BIOS * (might be usefull if drive is not registered in CMOS for any reason). @@ -70,19 +100,22 @@ { unsigned long flags; u16 master_data; - byte slave_data, speed; - int err; - int is_slave = (&HWIF(drive)->drives[1] == drive); - int master_port = HWIF(drive)->index ? 0x42 : 0x40; - int slave_port = 0x44; - /* ISP RTC */ - byte timings[][2] = { { 0, 0 }, - { 0, 0 }, - { 1, 0 }, - { 2, 1 }, - { 2, 3 }, }; - + byte slave_data; + int is_slave = (&HWIF(drive)->drives[1] == drive); + int master_port = HWIF(drive)->index ? 0x42 : 0x40; + int slave_port = 0x44; + /* ISP RTC */ + byte timings[][2] = { { 0, 0 }, + { 0, 0 }, + { 1, 0 }, + { 2, 1 }, + { 2, 3 }, }; + +#if 1 + pio = ide_get_best_pio_mode(drive, pio, 5, NULL); +#else pio = ide_get_best_pio_mode(drive, pio, 4, NULL); +#endif pci_read_config_word(HWIF(drive)->pci_dev, master_port, &master_data); if (is_slave) { master_data = master_data | 0x4000; @@ -107,28 +140,15 @@ if (is_slave) pci_write_config_byte(HWIF(drive)->pci_dev, slave_port, slave_data); restore_flags(flags); - - switch(pio) { - case 4: speed = XFER_PIO_4;break; - case 3: speed = XFER_PIO_3;break; - case 2: speed = XFER_PIO_2;break; - case 1: speed = XFER_PIO_1;break; - default: - speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW; - break; - } - - err = ide_wait_cmd(drive, WIN_SETFEATURES, speed, SETFEATURES_XFER, 0, NULL); } -extern char *ide_xfer_verbose (byte xfer_rate); - static int piix_config_drive_for_dma(ide_drive_t *drive, int ultra) { struct hd_driveid *id = drive->id; ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; + unsigned long flags; int sitre; short reg4042, reg44, reg48, reg4a; byte speed; @@ -144,23 +164,22 @@ pci_read_config_word(dev, 0x48, ®48); pci_read_config_word(dev, 0x4a, ®4a); -#if PIIX_DEBUG_SET_XFER - printk("PIIX%s: DMA enable ", - (dev->device == PCI_DEVICE_ID_INTEL_82371FB_0) ? "a" : - (dev->device == PCI_DEVICE_ID_INTEL_82371FB_1) ? "b" : - (dev->device == PCI_DEVICE_ID_INTEL_82371SB_1) ? "3" : - (dev->device == PCI_DEVICE_ID_INTEL_82371AB) ? "4" : " UNKNOWN" ); -#endif /* PIIX_DEBUG_SET_XFER */ + save_flags(flags); + cli(); if (id->dma_ultra && (ultra)) { if (!(reg48 & u_flag)) { pci_write_config_word(dev, 0x48, reg48|u_flag); } } else { - pci_write_config_word(dev, 0x48, reg48 & ~u_flag); + if (reg48 & u_flag) { + pci_write_config_word(dev, 0x48, reg48 & ~u_flag); + } } if ((id->dma_ultra & 0x0004) && (ultra)) { + drive->id->dma_mword &= ~0x0F00; + drive->id->dma_1word &= ~0x0F00; if (!((id->dma_ultra >> 8) & 4)) { drive->id->dma_ultra &= ~0x0F00; drive->id->dma_ultra |= 0x0404; @@ -171,6 +190,8 @@ } speed = XFER_UDMA_2; } else if ((id->dma_ultra & 0x0002) && (ultra)) { + drive->id->dma_mword &= ~0x0F00; + drive->id->dma_1word &= ~0x0F00; if (!((id->dma_ultra >> 8) & 2)) { drive->id->dma_ultra &= ~0x0F00; drive->id->dma_ultra |= 0x0202; @@ -182,6 +203,8 @@ } speed = XFER_UDMA_1; } else if ((id->dma_ultra & 0x0001) && (ultra)) { + drive->id->dma_mword &= ~0x0F00; + drive->id->dma_1word &= ~0x0F00; if (!((id->dma_ultra >> 8) & 1)) { drive->id->dma_ultra &= ~0x0F00; drive->id->dma_ultra |= 0x0101; @@ -193,33 +216,46 @@ } speed = XFER_UDMA_0; } else if (id->dma_mword & 0x0004) { - drive->id->dma_ultra &= ~0x0F0F; - pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); + if (reg4a & a_speed) + pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); + drive->id->dma_ultra &= ~0x0F00; + drive->id->dma_1word &= ~0x0F00; if (!((id->dma_mword >> 8) & 4)) { drive->id->dma_mword &= ~0x0F00; drive->id->dma_mword |= 0x0404; } speed = XFER_MW_DMA_2; } else if (id->dma_mword & 0x0002) { - drive->id->dma_ultra &= ~0x0F0F; - pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); + if (reg4a & a_speed) + pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); + drive->id->dma_ultra &= ~0x0F00; + drive->id->dma_1word &= ~0x0F00; if (!((id->dma_mword >> 8) & 2)) { drive->id->dma_mword &= ~0x0F00; drive->id->dma_mword |= 0x0202; } speed = XFER_MW_DMA_1; } else if (id->dma_1word & 0x0004) { - drive->id->dma_ultra &= ~0x0F0F; - pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); + if (reg4a & a_speed) + pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); + drive->id->dma_ultra &= ~0x0F00; + drive->id->dma_mword &= ~0x0F00; if (!((id->dma_1word >> 8) & 4)) { drive->id->dma_1word &= ~0x0F00; drive->id->dma_1word |= 0x0404; } speed = XFER_SW_DMA_2; } else { - return ide_dma_off_quietly; +#if 0 + speed = XFER_PIO_0; +#else + speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); +#endif } + restore_flags(flags); + piix_tune_drive(drive, piix_dma_2_pio(speed)); + (void) ide_wait_cmd(drive, WIN_SETFEATURES, speed, SETFEATURES_XFER, 0, NULL); #if PIIX_DEBUG_DRIVE_INFO @@ -241,7 +277,7 @@ int ultra = (HWIF(drive)->pci_dev->device == PCI_DEVICE_ID_INTEL_82371AB) ? 1 : 0; switch (func) { case ide_dma_check: - return piix_config_drive_for_dma(drive, ultra); + return ide_dmaproc((ide_dma_action_t) piix_config_drive_for_dma(drive, ultra), drive); default : break; } @@ -252,7 +288,7 @@ void ide_init_piix (ide_hwif_t *hwif) { hwif->tuneproc = &piix_tune_drive; -#if PIIX_DMA_PROC - hwif->dmaproc = &piix_dmaproc; -#endif /* PIIX_DMA_PROC */ + if (hwif->dma_base) { + hwif->dmaproc = &piix_dmaproc; + } } | |