Subject: [PATCH 2.5] PCI config read/write fixed for vr41xx

From: Yoichi Yuasa <[email-masked]>
Date: Fri, 8 Nov 2002 16:01:09 +0900

Hi Ralf,

I have fixed new PCI config read/write of vr41xx.
Please apply this patch.

Thanks,

Yoichi

diff -aruN --exclude=CVS --exclude=.cvsignore linux.orig/arch/mips/vr41xx/common/pciu.c linux/arch/mips/vr41xx/common/pciu.c
--- linux.orig/arch/mips/vr41xx/common/pciu.c	Mon Jul 15 08:47:57 2002
+++ linux/arch/mips/vr41xx/common/pciu.c	Fri Nov  8 14:39:56 2002
@@ -53,32 +53,28 @@
 
 extern unsigned long vr41xx_vtclock;
 
-static inline int vr41xx_pci_config_access(struct pci_dev *dev, int where)
+static inline int vr41xx_pci_config_access(unsigned char bus,  unsigned int devfn, int where)
 {
-	unsigned char bus = dev->bus->number;
-	unsigned int dev_fn = dev->devfn;
-
 	if (bus == 0) {
 		/*
 		 * Type 0 configuration
 		 */
-		if (PCI_SLOT(dev_fn) < 11 || PCI_SLOT(dev_fn) > 31 || where > 255)
+		if (PCI_SLOT(devfn) < 11 || where > 255)
 			return -1;
 
-		writel((1UL << PCI_SLOT(dev_fn))|
-		       (PCI_FUNC(dev_fn) << 8)	|
+		writel((1UL << PCI_SLOT(devfn))	|
+		       (PCI_FUNC(devfn) << 8)	|
 		       (where & 0xfc),
 		       PCICONFAREG);
-	}
-	else {
+	} else {
 		/*
 		 * Type 1 configuration
 		 */
-		if (bus > 255 || PCI_SLOT(dev_fn) > 31 || where > 255)
+		if (where > 255)
 			return -1;
 
 		writel((bus << 16)	|
-		       (dev_fn << 8)	|
+		       (devfn << 8)	|
 		       (where & 0xfc)	|
 		       1UL,
 		       PCICONFAREG);
@@ -87,110 +83,69 @@
 	return 0;
 }
 
-static int vr41xx_pci_read_config_byte(struct pci_dev *dev, int where, u8 *val)
-{
-	u32 data;
-
-	*val = 0xff;
-	if (vr41xx_pci_config_access(dev, where) < 0)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-
-	data = readl(PCICONFDREG);
-	*val = (u8)(data >> ((where & 3) << 3));
-
-	return PCIBIOS_SUCCESSFUL;
-
-}
-
-static int vr41xx_pci_read_config_word(struct pci_dev *dev, int where, u16 *val)
+static int vr41xx_pci_config_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val)
 {
 	u32 data;
 
-	*val = 0xffff;
-	if (where & 1)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-
-	if (vr41xx_pci_config_access(dev, where) < 0)
+	*val = 0xffffffffUL;
+	if (vr41xx_pci_config_access(bus->number, devfn, where) < 0)
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
 	data = readl(PCICONFDREG);
-	*val = (u16)(data >> ((where & 2) << 3));
-
-	return PCIBIOS_SUCCESSFUL;
-}
 
-static int vr41xx_pci_read_config_dword(struct pci_dev *dev, int where, u32 *val)
-{
-	*val = 0xffffffff;
-	if (where & 3)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-
-	if (vr41xx_pci_config_access(dev, where) < 0)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-
-	*val = readl(PCICONFDREG);
+	switch (size) {
+	case 1:
+		*val = (data >> ((where & 3) << 3)) & 0xffUL;
+		break;
+	case 2:
+		*val = (data >> ((where & 2) << 3)) & 0xffffUL;
+		break;
+	case 4:
+		*val = data;
+		break;
+	default:
+		return PCIBIOS_FUNC_NOT_SUPPORTED;
+	}
 
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static int vr41xx_pci_write_config_byte(struct pci_dev *dev, int where, u8 val)
+static int vr41xx_pci_config_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
 {
 	u32 data;
 	int shift;
 
-	if (vr41xx_pci_config_access(dev, where) < 0)
+	if (vr41xx_pci_config_access(bus->number, devfn, where) < 0)
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
 	data = readl(PCICONFDREG);
-	shift = (where & 3) << 3;
-	data &= ~(0xff << shift);
-	data |= (((u32)val) << shift);
 
-	writel(data, PCICONFDREG);
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int vr41xx_pci_write_config_word(struct pci_dev *dev, int where, u16 val)
-{
-	u32 data;
-	int shift;
-
-	if (where & 1)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-
-	if (vr41xx_pci_config_access(dev, where) < 0)
-		return PCIBIOS_DEVICE_NOT_FOUND;
+	switch (size) {
+	case 1:
+		shift = (where & 3) << 3;
+		data &= ~(0xff << shift);
+		data |= ((val & 0xff) << shift);
+		break;
+	case 2:
+		shift = (where & 2) << 3;
+		data &= ~(0xffff << shift);
+		data |= ((val & 0xffff) << shift);
+		break;
+	case 4:
+		data = val;
+		break;
+	default:
+		return PCIBIOS_FUNC_NOT_SUPPORTED;
+	}
 
-	data = readl(PCICONFDREG);
-	shift = (where & 2) << 3;
-	data &= ~(0xffff << shift);
-	data |= (((u32)val) << shift);
 	writel(data, PCICONFDREG);
 
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static int vr41xx_pci_write_config_dword(struct pci_dev *dev, int where, u32 val)
-{
-	if (where & 3)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-
-	if (vr41xx_pci_config_access(dev, where) < 0)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-
-	writel(val, PCICONFDREG);
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
 struct pci_ops vr41xx_pci_ops = {
-	vr41xx_pci_read_config_byte,
-	vr41xx_pci_read_config_word,
-	vr41xx_pci_read_config_dword,
-	vr41xx_pci_write_config_byte,
-	vr41xx_pci_write_config_word,
-	vr41xx_pci_write_config_dword
+	.read	= vr41xx_pci_config_read,
+	.write	= vr41xx_pci_config_write,
 };
 
 void __init vr41xx_pciu_init(struct vr41xx_pci_address_map *map)

---

From: Yoichi Yuasa <[email-masked]>
Date: Tue, 12 Nov 2002 17:09:25 +0900

Hello Ralf,

Are there any problems in this patch?

On Fri, 8 Nov 2002 16:01:09 +0900

Thanks,

Yoichi

 

 		writel((bus << 16)	|
-		       (dev_fn << 8)	|
+		       (devfn << 8)	|
 		       (where & 0xfc)	|
 		       1UL,
 		       PCICONFAREG);
@@ -87,110 +83,69 @@
 	return 0;
 }

-	*val = 0xffff;
-	if (where & 1)