All of lore.kernel.org
 help / color / mirror / Atom feed
* piix dma setup code
@ 2004-05-18 11:19 Go Taniguchi
  2004-05-19  1:34 ` Jeff Garzik
  2004-05-19 16:51 ` Bartlomiej Zolnierkiewicz
  0 siblings, 2 replies; 7+ messages in thread
From: Go Taniguchi @ 2004-05-18 11:19 UTC (permalink / raw)
  To: linux-ide

[-- Attachment #1: Type: text/plain, Size: 1734 bytes --]

Hi,

I think that there are some problems in piix dma setup code.

At function piix_set_udmamode in ata_piix.c.These is same code in piix.c.


//        if (!(reg48 & u_flag))
//                pci_write_config_word(dev, 0x48, reg48|u_flag);

ICH PCI register offset 48 "Synchronous DMA Control Register" register size is
8bit. pci_write_config_byte is better.


//        if (speed == XFER_UDMA_5) {

If speed is XFER_UDMA_6, base clock is set to low base clock.
It should be "speed >= XFER_UDMA_5". My ICH6 system reported XFER_UDMA_6,


//                pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag);
//        } else {
//                pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
//        }
//        if (!(reg4a & u_speed)) {

If u_speed is 0, It is always the TRUE.
And I think that this 2bit comparison is wrong.
Probably It is "(reg4a & a_speed) != u_speed"

//                pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
This set-up is done overwrite of with next line.
//                pci_write_config_word(dev, 0x4a, reg4a|u_speed);
We should do and/or with original data.
So, these are pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed);

//        }
//        if (speed > XFER_UDMA_2) {
//                if (!(reg54 & v_flag)) {
                        pci_write_config_word(dev, 0x54, reg54|v_flag);
If word accesses to reg54, reg55 is overwritten by old original data.
reg55 set already fails. It should be byte access.


//                }
//        } else {
//                pci_write_config_word(dev, 0x54, reg54 & ~v_flag);
//        }

I attched patch file.
Two registers changed it in 8bit access and removed reg44 which was not used.

Sorry for my very poor English.

[-- Attachment #2: piix-dma-setmode.patch --]
[-- Type: text/plain, Size: 3973 bytes --]

diff -urN linux-2.6.6.orig/drivers/ide/pci/piix.c linux-2.6.6/drivers/ide/pci/piix.c
--- linux-2.6.6.orig/drivers/ide/pci/piix.c	2004-05-17 19:09:33.132238864 +0900
+++ linux-2.6.6/drivers/ide/pci/piix.c	2004-05-17 19:08:57.778613432 +0900
@@ -436,15 +436,14 @@
 	int w_flag		= 0x10 << drive->dn;
 	int u_speed		= 0;
 	int			sitre;
-	u16			reg4042, reg44, reg48, reg4a, reg54;
-	u8			reg55;
+	u16			reg4042, reg4a;
+	u8			reg48, reg54, reg55;
 
 	pci_read_config_word(dev, maslave, &reg4042);
 	sitre = (reg4042 & 0x4000) ? 1 : 0;
-	pci_read_config_word(dev, 0x44, &reg44);
-	pci_read_config_word(dev, 0x48, &reg48);
+	pci_read_config_byte(dev, 0x48, &reg48);
 	pci_read_config_word(dev, 0x4a, &reg4a);
-	pci_read_config_word(dev, 0x54, &reg54);
+	pci_read_config_byte(dev, 0x54, &reg54);
 	pci_read_config_byte(dev, 0x55, &reg55);
 
 	switch(speed) {
@@ -466,30 +465,29 @@
 
 	if (speed >= XFER_UDMA_0) {
 		if (!(reg48 & u_flag))
-			pci_write_config_word(dev, 0x48, reg48|u_flag);
+			pci_write_config_byte(dev, 0x48, reg48|u_flag);
 		if (speed == XFER_UDMA_5) {
 			pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag);
 		} else {
 			pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
 		}
-		if (!(reg4a & u_speed)) {
-			pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
-			pci_write_config_word(dev, 0x4a, reg4a|u_speed);
+		if ((reg4a & a_speed) != u_speed) {
+			pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed);
 		}
 		if (speed > XFER_UDMA_2) {
 			if (!(reg54 & v_flag)) {
-				pci_write_config_word(dev, 0x54, reg54|v_flag);
+				pci_write_config_byte(dev, 0x54, reg54|v_flag);
 			}
 		} else {
-			pci_write_config_word(dev, 0x54, reg54 & ~v_flag);
+			pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
 		}
 	} else {
 		if (reg48 & u_flag)
-			pci_write_config_word(dev, 0x48, reg48 & ~u_flag);
+			pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
 		if (reg4a & a_speed)
 			pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
 		if (reg54 & v_flag)
-			pci_write_config_word(dev, 0x54, reg54 & ~v_flag);
+			pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
 		if (reg55 & w_flag)
 			pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
 	}
diff -urN linux-2.6.6.orig/drivers/scsi/ata_piix.c linux-2.6.6/drivers/scsi/ata_piix.c
--- linux-2.6.6.orig/drivers/scsi/ata_piix.c	2004-05-17 19:09:33.147236584 +0900
+++ linux-2.6.6/drivers/scsi/ata_piix.c	2004-05-17 19:08:13.861289880 +0900
@@ -424,16 +424,15 @@
 	int w_flag		= 0x10 << drive_dn;
 	int u_speed		= 0;
 	int			sitre;
-	u16			reg4042, reg44, reg48, reg4a, reg54;
-	u8			reg55;
+	u16			reg4042, reg4a;
+	u8			reg48, reg54, reg55;
 
 	pci_read_config_word(dev, maslave, &reg4042);
 	DPRINTK("reg4042 = 0x%04x\n", reg4042);
 	sitre = (reg4042 & 0x4000) ? 1 : 0;
-	pci_read_config_word(dev, 0x44, &reg44);
-	pci_read_config_word(dev, 0x48, &reg48);
+	pci_read_config_byte(dev, 0x48, &reg48);
 	pci_read_config_word(dev, 0x4a, &reg4a);
-	pci_read_config_word(dev, 0x54, &reg54);
+	pci_read_config_byte(dev, 0x54, &reg54);
 	pci_read_config_byte(dev, 0x55, &reg55);
 
 	switch(speed) {
@@ -450,22 +449,21 @@
 	}
 
 	if (!(reg48 & u_flag))
-		pci_write_config_word(dev, 0x48, reg48|u_flag);
-	if (speed == XFER_UDMA_5) {
+		pci_write_config_byte(dev, 0x48, reg48|u_flag);
+	if (speed >= XFER_UDMA_5) {
 		pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag);
 	} else {
 		pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
 	}
-	if (!(reg4a & u_speed)) {
-		pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
-		pci_write_config_word(dev, 0x4a, reg4a|u_speed);
+	if ((reg4a & a_speed) != u_speed) {
+		pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed);
 	}
 	if (speed > XFER_UDMA_2) {
 		if (!(reg54 & v_flag)) {
-			pci_write_config_word(dev, 0x54, reg54|v_flag);
+			pci_write_config_byte(dev, 0x54, reg54|v_flag);
 		}
 	} else {
-		pci_write_config_word(dev, 0x54, reg54 & ~v_flag);
+		pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
 	}
 }
 

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2004-05-20  0:09 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-05-18 11:19 piix dma setup code Go Taniguchi
2004-05-19  1:34 ` Jeff Garzik
2004-05-19 16:51 ` Bartlomiej Zolnierkiewicz
2004-05-19 22:31   ` Jeff Garzik
2004-05-19 22:59     ` Bartlomiej Zolnierkiewicz
2004-05-19 23:19       ` Jeff Garzik
2004-05-20  0:10         ` Bartlomiej Zolnierkiewicz

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.