lkml.org 
[lkml]   [1999]   [Jun]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: 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, &reg48);
pci_read_config_word(dev, 0x4a, &reg4a);

-#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;
+ }
}
\
 
 \ /
  Last update: 2005-03-22 13:52    [W:0.479 / U:0.008 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site