[parisc-linux] PATCH SBA SMP + other mis

Grant Grundler grundler@dsl2.external.hp.com
Thu, 7 Mar 2002 00:58:05 -0700 (MST)


Hi all,

I need to review this myself one more time after I had some sleep.
This is a set of misc changes I have outstanding.
(also stored on ftp.parisc-linux.org:patches/sba_misc.diff)

o SBA SMP bug fix from Alex Williamson
o ioctl32.c FB wrapper enabled for FB support
o add a warning to indicate we are ignoring a "directed" MMIO
  range that a given elroy is programmed to forward.
  Because of possible overlaps with distributed ranges, it's
  non-trivial to request_resource. Still thinking about how
  to do this right. May need to move resource mgt into
  lba_fixup_bus() where we know whether PCI devices are below
  an elroy.

grant

Index: arch/parisc/kernel/ioctl32.c
===================================================================
RCS file: /var/cvs/linux/arch/parisc/kernel/ioctl32.c,v
retrieving revision 1.9
diff -u -p -r1.9 ioctl32.c
--- arch/parisc/kernel/ioctl32.c	2002/03/03 05:35:11	1.9
+++ arch/parisc/kernel/ioctl32.c	2002/03/07 07:48:08
@@ -83,6 +83,8 @@
 #include <linux/sonet.h>
 #include <linux/atm_suni.h>
 
+#include <asm/module.h>	/* get #define module_map() */
+
 /* Use this to get at 32-bit user passed pointers. 
    See sys_sparc32.c for description about these. */
 #define A(__x) ((unsigned long)(__x))
@@ -453,6 +455,7 @@ static inline int hdio_getgeo(unsigned i
 	return err ? -EFAULT : 0;
 }
 
+
 #if 0
 /* looks like SPARC only - eg sbus video */
 struct  fbcmap32 {
@@ -556,6 +559,7 @@ static inline int fbiogscursor(unsigned 
 	set_fs (old_fs);
 	return ret;
 }
+#endif /* 0 */
 
 struct fb_fix_screeninfo32 {
 	char			id[16];
@@ -655,21 +659,36 @@ static int fb_ioctl_trans(unsigned int f
 	if (err)
 		goto out;
 	switch (cmd) {
+		struct fb_fix_screeninfo32 fix32;
 	case FBIOGET_FSCREENINFO:
-		err = __copy_to_user((char *)((struct fb_fix_screeninfo32 *)arg)->id, (char *)fix.id, sizeof(fix.id));
-		err |= __put_user((__u32)(unsigned long)fix.smem_start, &((struct fb_fix_screeninfo32 *)arg)->smem_start);
-		err |= __put_user(fix.smem_len, &((struct fb_fix_screeninfo32 *)arg)->smem_len);
-		err |= __put_user(fix.type, &((struct fb_fix_screeninfo32 *)arg)->type);
-		err |= __put_user(fix.type_aux, &((struct fb_fix_screeninfo32 *)arg)->type_aux);
-		err |= __put_user(fix.visual, &((struct fb_fix_screeninfo32 *)arg)->visual);
-		err |= __put_user(fix.xpanstep, &((struct fb_fix_screeninfo32 *)arg)->xpanstep);
-		err |= __put_user(fix.ypanstep, &((struct fb_fix_screeninfo32 *)arg)->ypanstep);
-		err |= __put_user(fix.ywrapstep, &((struct fb_fix_screeninfo32 *)arg)->ywrapstep);
-		err |= __put_user(fix.line_length, &((struct fb_fix_screeninfo32 *)arg)->line_length);
-		err |= __put_user((__u32)(unsigned long)fix.mmio_start, &((struct fb_fix_screeninfo32 *)arg)->mmio_start);
-		err |= __put_user(fix.mmio_len, &((struct fb_fix_screeninfo32 *)arg)->mmio_len);
-		err |= __put_user(fix.accel, &((struct fb_fix_screeninfo32 *)arg)->accel);
-		err |= __copy_to_user((char *)((struct fb_fix_screeninfo32 *)arg)->reserved, (char *)fix.reserved, sizeof(fix.reserved));
+		memset(&fix32, 0, sizeof(fix32));
+		memcpy(fix32.id, fix.id, sizeof(fix32.id));
+		fix32.smem_start = (__u32)(unsigned long)fix.smem_start;
+		fix32.smem_len	= fix.smem_len;
+		fix32.type	= fix.type;
+		fix32.type_aux	= fix.type_aux;
+		fix32.visual	= fix.visual;
+		fix32.xpanstep	= fix.xpanstep;
+		fix32.ypanstep	= fix.ypanstep;
+		fix32.ywrapstep = fix.ywrapstep;
+		fix32.line_length = fix.line_length;
+		fix32.mmio_start = (__u32)(unsigned long)fix.mmio_start;
+		fix32.mmio_len	= fix.mmio_len;
+		fix32.accel	= fix.accel;
+		memcpy(fix32.reserved, fix.reserved, sizeof(fix32.reserved));
+		err = __copy_to_user((void *) arg, (const void *) &fix32, sizeof(fix32));
+
+printk("fix  : %lx %x  %x %x %x  %x %x %x %x  %lx %x %x\n",
+	fix.smem_start, fix.smem_len,
+	fix.type, fix.type_aux, fix.visual,
+	fix.xpanstep, fix.ypanstep, fix.ywrapstep, fix.line_length,
+	fix.mmio_start, fix.mmio_len, fix.accel);
+printk("fix32: %x %x  %x %x %x  %x %x %x %x  %x %x %x\n",
+	fix32.smem_start, fix32.smem_len,
+	fix32.type, fix32.type_aux, fix32.visual,
+	fix32.xpanstep, fix32.ypanstep, fix32.ywrapstep, fix32.line_length,
+	fix32.mmio_start, fix32.mmio_len, fix32.accel);
+
 		break;
 	case FBIOGETCMAP:
 		err = __copy_to_user((char *)A(red), cmap.red, cmap.len * sizeof(__u16));
@@ -690,7 +709,6 @@ out:	if (cmap.red) kfree(cmap.red);
 	if (cmap.transp) kfree(cmap.transp);
 	return err;
 }
-#endif
 
 static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
@@ -2822,6 +2840,7 @@ COMPATIBLE_IOCTL(FBIOGCURMAX)
 #endif
 COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO)
 COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO)
+
 COMPATIBLE_IOCTL(FBIOPAN_DISPLAY)
 COMPATIBLE_IOCTL(FBIOGET_FCURSORINFO)
 COMPATIBLE_IOCTL(FBIOGET_VCURSORINFO)
@@ -3365,10 +3384,9 @@ HANDLE_IOCTL(BLKFRAGET, w_long)
 HANDLE_IOCTL(BLKSECTGET, w_long)
 HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans)
 
-#if 0
+HANDLE_IOCTL(FBIOGET_FSCREENINFO, fb_ioctl_trans)
 HANDLE_IOCTL(FBIOGETCMAP, fb_ioctl_trans)
 HANDLE_IOCTL(FBIOPUTCMAP, fb_ioctl_trans)
-#endif
 
 HANDLE_IOCTL(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans)
 HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans)
Index: arch/parisc/kernel/sba_iommu.c
===================================================================
RCS file: /var/cvs/linux/arch/parisc/kernel/sba_iommu.c,v
retrieving revision 1.64
diff -u -p -r1.64 sba_iommu.c
--- arch/parisc/kernel/sba_iommu.c	2001/11/30 23:50:01	1.64
+++ arch/parisc/kernel/sba_iommu.c	2002/03/07 07:48:09
@@ -898,10 +898,6 @@ sba_unmap_single(struct pci_dev *dev, dm
 	ioc = GET_IOC(dev);
 	ASSERT(ioc);
 
-#if DELAYED_RESOURCE_CNT > 0
-	d = &(ioc->saved[ioc->saved_cnt]);
-#endif
-
 	offset = iova & ~IOVP_MASK;
 
 	DBG_RUN("%s() iovp 0x%lx/%x\n",
@@ -912,12 +908,14 @@ sba_unmap_single(struct pci_dev *dev, dm
 	size = ROUNDUP(size, IOVP_SIZE);
 
 	spin_lock_irqsave(&ioc->res_lock, flags);
+
 #ifdef CONFIG_PROC_FS
 	ioc->usingle_calls++;
 	ioc->usingle_pages += size >> IOVP_SHIFT;
 #endif
 
 #if DELAYED_RESOURCE_CNT > 0
+	d = &(ioc->saved[ioc->saved_cnt]);
 	d->iova = iova;
 	d->size = size;
 	if (++(ioc->saved_cnt) >= DELAYED_RESOURCE_CNT) {
Index: arch/parisc/kernel/lba_pci.c
===================================================================
RCS file: /var/cvs/linux/arch/parisc/kernel/lba_pci.c,v
retrieving revision 1.48
diff -u -p -r1.48 lba_pci.c
--- arch/parisc/kernel/lba_pci.c	2002/01/25 22:58:50	1.48
+++ arch/parisc/kernel/lba_pci.c	2002/03/07 07:48:10
@@ -34,6 +34,7 @@
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
 #include <linux/init.h>		/* for __init and __devinit */
+/* #define PCI_DEBUG	enable ASSERT */
 #include <linux/pci.h>
 #include <linux/ioport.h>
 #include <linux/slab.h>
@@ -939,7 +940,7 @@ LBA_PORT_IN(32, 0)
 #define LBA_PORT_OUT(size, mask) \
 static void lba_astro_out##size (struct pci_hba_data *d, u16 addr, u##size val) \
 { \
-	ASSERT(bus != NULL); \
+	ASSERT(d != NULL); \
 	DBG_PORT("%s(0x%p, 0x%x, 0x%x)\n", __FUNCTION__, d, addr, val); \
 	WRITE_REG##size(val, LBA_ASTRO_PORT_BASE + addr); \
 	if (LBA_DEV(d)->hw_rev < 3) \
@@ -1181,7 +1182,8 @@ lba_legacy_resources(struct parisc_devic
 	** "Directed" ranges are used when the "distributed range" isn't
 	** sufficient for all devices below a given LBA.  Typically devices
 	** like graphics cards or X25 may need a directed range when the
-	** bus has multiple slots (ie multiple devices).
+	** bus has multiple slots (ie multiple devices) or the device
+	** needs more than the typical 4 or 8MB a distributed range offers.
 	**
 	** The main reason for ignoring it now frigging complications.
 	** Directed ranges may overlap (and have precedence) over
@@ -1191,6 +1193,26 @@ lba_legacy_resources(struct parisc_devic
 	** since they may be assigned a directed range which overlaps
 	** an existing (but unused portion of) distributed range.
 	*/
+	r = &(lba_dev->hba.elmmio_space);
+	r->name  = "extra LBA PCI LMMIO";
+	r->flags = IORESOURCE_MEM;
+	r->start = READ_REG32(pa_dev->hpa + LBA_ELMMIO_BASE);
+	r->end   = 0;
+
+	/* check Range Enable bit */
+	if (r->start & 1) {
+		/* First baby step to getting Direct Ranges listed in /proc.
+		** AFAIK, only Sprockets PDC will setup a directed Range.
+		*/
+
+		r->start &= ~1;
+		r->end    = r->start;
+		r->end   += ~READ_REG32(pa_dev->hpa + LBA_ELMMIO_MASK);
+		printk(KERN_DEBUG "WARNING: Ignoring enabled ELMMIO BASE 0x%0x  SIZE 0x%x\n",
+			r->start,
+			r->end + 1);
+
+	}
 
 	r = &(lba_dev->hba.io_space);
 	r->name  = "LBA PCI I/O Ports";
@@ -1240,7 +1262,7 @@ lba_hw_init(struct lba_device *d)
 #endif	/* DEBUG_LBA_PAT */
 
 #ifdef __LP64__
-#warning Need to add support for PDC_PAT_IO "Get slot status" - OLAR support
+#warning FIXME add support for PDC_PAT_IO "Get slot status" - OLAR support
 #endif
 
 #ifdef PDC_PAT_BUG
Index: include/asm-parisc/pci.h
===================================================================
RCS file: /var/cvs/linux/include/asm-parisc/pci.h,v
retrieving revision 1.47
diff -u -p -r1.47 pci.h
--- include/asm-parisc/pci.h	2002/02/28 07:15:36	1.47
+++ include/asm-parisc/pci.h	2002/03/07 07:48:10
@@ -53,6 +53,7 @@ struct pci_hba_data {
 	struct resource bus_num;	/* PCI bus numbers */
 	struct resource io_space;	/* PIOP */
 	struct resource lmmio_space;	/* bus addresses < 4Gb */
+	struct resource elmmio_space;	/* additional bus addresses < 4Gb */
 	unsigned long   lmmio_space_offset;  /* CPU view - PCI view */
 	void *          iommu;          /* IOMMU this device is under */
 	/* REVISIT - spinlock to protect resources? */