[parisc-linux-cvs] DIFF -pa11 sba/lba/smp bug fixes

Grant Grundler grundler@puffin.external.hp.com
Mon, 26 Nov 2001 01:21:03 -0700


Grant Grundler wrote:
> Log message:
> -pa11
> fix logic bug in sba_iommu.c - only supports 32-bit PCI
> fix SMP init bug. top reports (almost) right statistics.
> Thanks to willy for finding the root cause.
> It now reports 50% idle when the system is really busy.
> Something else is still wrong...*sigh*.

Index: Makefile
===================================================================
RCS file: /var/cvs/linux/Makefile,v
retrieving revision 1.202
diff -u -p -r1.202 Makefile
--- Makefile	2001/11/23 21:56:59	1.202
+++ Makefile	2001/11/26 08:08:34
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 14
-EXTRAVERSION = -pa10
+EXTRAVERSION = -pa11
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
Index: arch/parisc/kernel/lba_pci.c
===================================================================
RCS file: /var/cvs/linux/arch/parisc/kernel/lba_pci.c,v
retrieving revision 1.44
diff -u -p -r1.44 lba_pci.c
--- arch/parisc/kernel/lba_pci.c	2001/11/14 17:44:11	1.44
+++ arch/parisc/kernel/lba_pci.c	2001/11/26 08:08:35
@@ -48,9 +48,8 @@
 
 #include <asm/hardware.h>	/* for register_parisc_driver() stuff */
 #include <asm/iosapic.h>	/* for iosapic_register() */
-#include <asm/gsc.h>		/* gsc_read/write stuff */
+#include <asm/io.h>		/* read/write stuff */
 
-
 #ifndef TRUE
 #define TRUE (1 == 1)
 #define FALSE (1 == 0)
@@ -230,22 +229,22 @@ static u32 lba_t32;
  * BE WARNED: register writes are posted.
  *  (ie follow writes which must reach HW with a read)
  */
-#define READ_U8(addr)  gsc_readb(addr)
-#define READ_U16(addr) gsc_readw((u16 *) (addr))
-#define READ_U32(addr) gsc_readl((u32 *) (addr))
-#define WRITE_U8(value, addr) gsc_writeb(value, addr)
-#define WRITE_U16(value, addr) gsc_writew(value, (u16 *) (addr))
-#define WRITE_U32(value, addr) gsc_writel(value, (u32 *) (addr))
-
-#define READ_REG8(addr)  gsc_readb(addr)
-#define READ_REG16(addr) le16_to_cpu(gsc_readw((u16 *) (addr)))
-#define READ_REG32(addr) le32_to_cpu(gsc_readl((u32 *) (addr)))
-#ifdef __LP64__
-#define READ_REG64(addr) le64_to_cpu(gsc_readq((u64 *) (addr)))
-#endif
-#define WRITE_REG8(value, addr) gsc_writeb(value, addr)
-#define WRITE_REG16(value, addr) gsc_writew(cpu_to_le16(value), (u16 *) (addr))
-#define WRITE_REG32(value, addr) gsc_writel(cpu_to_le32(value), (u32 *) (addr))
+#define READ_U8(addr)  __raw_readb(addr)
+#define READ_U16(addr) __raw_readw(addr)
+#define READ_U32(addr) __raw_readl(addr)
+#define WRITE_U8(value, addr)  __raw_writeb(value, addr)
+#define WRITE_U16(value, addr) __raw_writew(value, addr)
+#define WRITE_U32(value, addr) __raw_writel(value, addr)
+
+#define READ_REG8(addr)  readb(addr)
+#define READ_REG16(addr) le16_to_cpu(readw(addr))
+#define READ_REG32(addr) le32_to_cpu(readl(addr))
+#if BITS_PER_LONG > 32
+#define READ_REG64(addr) le64_to_cpu(readq(addr))
+#endif
+#define WRITE_REG8(value, addr)  writeb(value, addr)
+#define WRITE_REG16(value, addr) writew(cpu_to_le16(value), addr)
+#define WRITE_REG32(value, addr) writel(cpu_to_le32(value), addr)
 
 
 #define LBA_CFG_TOK(bus,dfn) ((u32) ((bus)<<16 | (dfn)<<8))
@@ -402,9 +401,9 @@ lba_device_present( u8 bus, u8 dfn, stru
  *
  *		Actually, there is still a race in which
  *		we could be clearing a fatal error.  We will
- *		live with this during our real mode bus walk
+ *		live with this during our initial bus walk
  *		until rev 4.0 (no driver activity during
- *		real mode bus walk).  The real mode bus walk
+ *		initial bus walk).  The initial bus walk
  *		has race conditions concerning the use of
  *		smart mode as well.
  */
@@ -526,7 +525,8 @@ static int lba_cfg_read##size (struct pc
 	u32 local_bus = (dev->bus->parent == NULL) ? 0 : dev->bus->secondary; \
 	u32 tok = LBA_CFG_TOK(local_bus,dev->devfn); \
  \
-	if (1 || (!LBA_TR4PLUS(d)) && (!LBA_SKIP_PROBE(d))) { \
+/* FIXME:B2K/C3600 workaround is always use old method... */ \
+	/* if (!LBA_TR4PLUS(d) && !LBA_SKIP_PROBE(d)) */ { \
 		/* original - Generate config cycle on broken elroy \
 		  with risk we will miss PCI bus errors. */ \
 		*data = (u##size) lba_rd_cfg(d, tok, pos, sizeof(u##size)); \
@@ -611,7 +611,7 @@ static int lba_cfg_write##size (struct p
  	ASSERT((tok & 0xff) == 0); \
 	ASSERT(pos < 0x100); \
  \
-	if ((!LBA_TR4PLUS(d)) && (!LBA_SKIP_PROBE(d))) { \
+	if (!LBA_TR4PLUS(d) && !LBA_SKIP_PROBE(d)) { \
 		/* Original Workaround */ \
 		lba_wr_cfg(d, tok, pos, (u32) data, sizeof(u##size)); \
 		DBG_CFG("%s(%s+%2x) = 0x%x (a)\n", __FUNCTION__, dev->slot_name, pos, data); \
@@ -1249,12 +1249,6 @@ lba_hw_init(struct lba_device *d)
 #warning Need to add support for PDC_PAT_IO "Get slot status" - OLAR support
 #endif
 
-	/*
-	**
-	*/
-	stat = READ_REG32(d->hba.base_addr + LBA_ERROR_CONFIG);
-	WRITE_REG32(stat | LBA_SMART_MODE, d->hba.base_addr + LBA_ERROR_CONFIG);
-
 #ifdef PDC_PAT_BUG
 	/* Bug exhibited with PDC rev 40.48  on L2000 */
 	bus_reset = READ_REG32(d->hba.base_addr + LBA_STAT_CTL + 4) & 1;
@@ -1263,6 +1257,13 @@ lba_hw_init(struct lba_device *d)
 	}
 #endif
 
+	stat = READ_REG32(d->hba.base_addr + LBA_ERROR_CONFIG);
+	if (stat & LBA_SMART_MODE) {
+		BUG();	/* should be off be default */
+		stat &= ~LBA_SMART_MODE;
+		WRITE_REG32(stat, d->hba.base_addr + LBA_ERROR_CONFIG);
+	}
+
 	/* Set HF mode as the default (vs. -1 mode). */
         stat = READ_REG32(d->hba.base_addr + LBA_STAT_CTL);
 	WRITE_REG32(stat | HF_ENABLE, d->hba.base_addr + LBA_STAT_CTL);
@@ -1275,10 +1276,12 @@ lba_hw_init(struct lba_device *d)
 	*/
 	if (bus_reset)
 		mdelay(pci_post_reset_delay);
+#endif
 
 	if (0 == READ_REG32(d->hba.base_addr + LBA_ARB_MASK)) {
 		/*
 		** Bug exhibited with PDC rev 40.48 on L2000.
+		** B2000/C3600/J6000 also have this problem?
 		** 
 		** Elroys with hot pluggable slots don't get configured
 		** correctly if the slot is empty.  ARB_MASK is set to 0
@@ -1288,7 +1291,6 @@ lba_hw_init(struct lba_device *d)
 		BUG();
 		WRITE_REG32(0x3, d->hba.base_addr + LBA_ARB_MASK);
 	}
-#endif
 
 	/*
 	** FIXME: Hint registers are programmed with default hint
Index: arch/parisc/kernel/processor.c
===================================================================
RCS file: /var/cvs/linux/arch/parisc/kernel/processor.c,v
retrieving revision 1.5
diff -u -p -r1.5 processor.c
--- arch/parisc/kernel/processor.c	2001/10/22 21:38:05	1.5
+++ arch/parisc/kernel/processor.c	2001/11/26 08:08:35
@@ -202,25 +202,40 @@ void __init collect_boot_cpu_data(void)
 	boot_cpu_data.family_name = cpu_name_version[boot_cpu_data.cpu_type][1];
 }
 
-/*
-** Set width/Enable FP coprocessor
-**
-** REVISIT: this could be done in the "code 22" trap handler.
-** (frowands idea - that way we know which processes need FP
-** registers saved on the interrupt stack.)
-**
-** NEWS FLASH: wide kernels need FP coprocessor enabled to handle
-** formatted printing of %lx for example (double divides I think)
-*/
 
 /**
- * init_per_cpu - Handle individual processor initializations.
+ * init_cpu_profiler - enable/setup per cpu profiling hooks.
  * @cpuid: The processor instance.
+ *
+ * FIXME: doesn't do much yet...
+ */
+static inline void __init
+init_percpu_prof(int cpunum)
+{
+	cpu_data[cpunum].prof_counter = 1;
+	cpu_data[cpunum].prof_multiplier = 1;
+}
+
+
+/**
+ * init_per_cpu - Handle individual processor initializations.
+ * @cpunum: logical processor number.
+ *
+ * This function handles initialization for *every* CPU
+ * in the system:
  *
- * This function handles any initialization that needs to be done
- * on each indiviual processor in the system.
+ * o Set "default" CPU width for trap handlers
+ *
+ * o Enable FP coprocessor
+ *   REVISIT: this could be done in the "code 22" trap handler.
+ *	(frowands idea - that way we know which processes need FP
+ *	registers saved on the interrupt stack.)
+ *   NEWS FLASH: wide kernels need FP coprocessor enabled to handle
+ *	formatted printing of %lx for example (double divides I think)
+ *
+ * o Enable CPU profiling hooks.
  */
-int __init init_per_cpu(int cpuid)
+int __init init_per_cpu(int cpunum)
 {
 	int ret;
 	struct pdc_coproc_cfg coproc_cfg;
@@ -233,11 +248,11 @@ int __init init_per_cpu(int cpuid)
 		/* FWIW, FP rev/model is a more accurate way to determine
 		** CPU type. CPU rev/model has some ambiguous cases.
 		*/
-		cpu_data[cpuid].fp_rev = coproc_cfg.revision;
-		cpu_data[cpuid].fp_model = coproc_cfg.model;
+		cpu_data[cpunum].fp_rev = coproc_cfg.revision;
+		cpu_data[cpunum].fp_model = coproc_cfg.model;
 
 		printk(KERN_INFO  "FP[%d] enabled: Rev %ld Model %ld\n",
-			cpuid, coproc_cfg.revision, coproc_cfg.model);
+			cpunum, coproc_cfg.revision, coproc_cfg.model);
 
 		/*
 		** store status register to stack (hopefully aligned)
@@ -259,7 +274,7 @@ int __init init_per_cpu(int cpuid)
 	}
 
 	/* FUTURE: Enable Performance Monitor : ccr bit 0x20 */
-
+	init_percpu_prof(cpunum);
 	return ret;
 }
 
Index: arch/parisc/kernel/sba_iommu.c
===================================================================
RCS file: /var/cvs/linux/arch/parisc/kernel/sba_iommu.c,v
retrieving revision 1.60
diff -u -p -r1.60 sba_iommu.c
--- arch/parisc/kernel/sba_iommu.c	2001/11/17 07:45:03	1.60
+++ arch/parisc/kernel/sba_iommu.c	2001/11/26 08:08:36
@@ -793,7 +793,7 @@ sba_dma_supported( struct pci_dev *dev, 
 	dev->dma_mask = mask;	/* save it */
 
 	/* only support 32-bit PCI devices - no DAC support (yet) */
-	return((int) (mask != 0xffffffff));
+	return((int) (mask == 0xffffffff));
 }
 
 
Index: arch/parisc/kernel/smp.c
===================================================================
RCS file: /var/cvs/linux/arch/parisc/kernel/smp.c,v
retrieving revision 1.14
diff -u -p -r1.14 smp.c
--- arch/parisc/kernel/smp.c	2001/11/17 07:39:12	1.14
+++ arch/parisc/kernel/smp.c	2001/11/26 08:08:36
@@ -416,16 +416,6 @@ smp_flush_tlb_all(void)
 }
 
 
-/*
- * Ideally sets up per-cpu profiling hooks.  Doesn't do much now...
- */
-static inline void __init
-smp_setup_percpu_timer(int cpunum)
-{
-        cpu_data[cpunum].prof_counter = 1;
-        cpu_data[cpunum].prof_multiplier = 1;
-}
-
 void 
 smp_do_timer(struct pt_regs *regs)
 {