[parisc-linux-cvs] ccio changes

Matthew Wilcox willy@ldl.fc.hp.com
Fri, 31 Aug 2001 00:04:52 -0600


 * Change initialisation order in gsc_init so that ccio gets initialised
   before dino.
 * Strip cujo 2.0 detection code from ccio-dma.
 * Call the cujo 2.0 fixups from dino.c instead.
 * Remove the struct ccio_device; replace with a linked list of ioc's.

Index: arch/parisc/kernel/ccio-dma.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/ccio-dma.c,v
retrieving revision 1.38
diff -u -p -r1.38 ccio-dma.c
--- ccio-dma.c	2001/08/29 03:34:44	1.38
+++ ccio-dma.c	2001/08/31 04:56:33
@@ -169,28 +169,16 @@ struct ioc {
 	/* STUFF We don't need in performance path */
 	u32 pdir_size; 			/* in bytes, determined by IOV Space size */
 	u32 chainid_shift; 		/* specify bit location of chain_id */
-	struct ccio_device *ioa;
+	struct ioc *next;		/* Linked list of discovered iocs */
 	struct parisc_device_id *iodc;	/* data about dev from firmware */
 	const char *name;		/* device name from firmware */
 };
 
-struct ccio_device {
-	struct ccio_device    *next;     /* list of LBA's in system */
-	spinlock_t            ccio_lock;
-
-	/* STUFF We don't need in performance path */
-	int                   hw_rev;  /* HW revision of chip */
-	int                   flags;   /* state/functionality enabled */
-	unsigned short	      num_ioc; /* number of on-board IOC's */
-#define MAX_IOC 2
-	struct ioc	      ioc[MAX_IOC];
-};
-
 
 /* Ratio of Host MEM to IOV Space size */
 static unsigned long ccio_mem_ratio = 32;
-static struct ccio_device *ccio_list;
-static int ccio_count;
+static struct ioc *ioc_list;
+static int ioc_count;
 
 /**************************************************************
 *
@@ -620,7 +608,7 @@ ccio_mark_invalid(struct ioc *ioc, dma_a
  * @dev: The PCI device.
  * @mask: A bit mask describing the DMA address range of the device.
  *
- * This function impliments the pci_dma_supported function.
+ * This function implements the pci_dma_supported function.
  */
 static int 
 ccio_dma_supported(struct pci_dev *dev, dma_addr_t mask)
@@ -644,13 +632,13 @@ ccio_dma_supported(struct pci_dev *dev, 
  * @size: The length of the DMA region.
  * @direction: The direction of the DMA transaction (to/from device).
  *
- * This function impliments the pci_map_single function.
+ * This function implements the pci_map_single function.
  */
 static dma_addr_t 
 ccio_map_single(struct pci_dev *dev, void *addr, size_t size, int direction)
 {
 	int idx;
-	struct ioc *ioc = &ccio_list->ioc[0];
+	struct ioc *ioc = ioc_list;
 	unsigned long flags;
 	dma_addr_t iovp;
 	dma_addr_t offset;
@@ -708,24 +696,13 @@ ccio_map_single(struct pci_dev *dev, voi
  * @size: The length of the DMA region.
  * @direction: The direction of the DMA transaction (to/from device).
  *
- * This function impliments the pci_unmap_single function.
+ * This function implements the pci_unmap_single function.
  */
 static void 
 ccio_unmap_single(struct pci_dev *dev, dma_addr_t iova, size_t size, 
 		  int direction)
 {
-#ifdef FIXME
-/* Multi-IOC (ie N-class) :  need to lookup IOC from dev
-** o If we can't know about lba PCI data structs, that eliminates ->sysdata.
-** o walking up pcidev->parent dead ends at elroy too
-** o leaves hashing dev->bus->number into some lookup.
-**   (may only work for N-class)
-*/
-	struct ccio_device *ioa = dev->sysdata
-#else
-	struct ccio_device *ioa = ccio_list;
-#endif
-	struct ioc *ioc = &ioa->ioc[0];
+	struct ioc *ioc = ioc_list; /* XXX: Use appropriate IOC for this dev */
 	unsigned long flags; 
 	dma_addr_t offset = iova & ~IOVP_MASK;
 	
@@ -754,7 +731,7 @@ ccio_unmap_single(struct pci_dev *dev, d
  * @size: The length of the DMA region.
  * @dma_handle: The DMA address handed back to the device (not the cpu).
  *
- * This function impliments the pci_alloc_consistent function.
+ * This function implements the pci_alloc_consistent function.
  */
 static void * 
 ccio_alloc_consistent(struct pci_dev *dev, size_t size, dma_addr_t *dma_handle)
@@ -787,7 +764,7 @@ ccio_alloc_consistent(struct pci_dev *de
  * @cpu_addr: The cpu address returned from the ccio_alloc_consistent.
  * @dma_handle: The device address returned from the ccio_alloc_consistent.
  *
- * This function impliments the pci_free_consistent function.
+ * This function implements the pci_free_consistent function.
  */
 static void 
 ccio_free_consistent(struct pci_dev *dev, size_t size, void *cpu_addr, 
@@ -977,13 +954,13 @@ ccio_coalesce_chunks(struct ioc *ioc, st
  * @nents: The number of entries in the scatter/gather list.
  * @direction: The direction of the DMA transaction (to/from device).
  *
- * This function impliments the pci_map_sg function.
+ * This function implements the pci_map_sg function.
  */
 static int
 ccio_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, 
 	    int direction)
 {
-	struct ioc *ioc = &ccio_list->ioc[0];
+	struct ioc *ioc = ioc_list;
 	int coalesced, filled = 0;
 	unsigned long flags;
 	unsigned long hint = hint_lookup[direction];
@@ -1040,14 +1017,14 @@ ccio_map_sg(struct pci_dev *dev, struct 
  * @nents: The number of entries in the scatter/gather list.
  * @direction: The direction of the DMA transaction (to/from device).
  *
- * This function impliments the pci_unmap_sg function.
+ * This function implements the pci_unmap_sg function.
  */
 static void 
 ccio_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, 
 	      int direction)
 {
 	/* FIXME : see Multi-IOC below */
-	struct ioc *ioc = &ccio_list->ioc[0];
+	struct ioc *ioc = ioc_list;
 
 	DBG_RUN_SG("%s() START %d entries,  %p,%x\n",
 		__FUNCTION__, nents, sglist->address, sglist->length);
@@ -1085,70 +1062,60 @@ static struct pci_dma_ops ccio_ops = {
 static int 
 ccio_proc_info(char *buf, char **start, off_t offset, int len)
 {
-	int i, j;
-	struct ccio_device *ioa = ccio_list;
-	unsigned long avg = 0, min, max;
+	struct ioc *ioc = ioc_list;
 
 	buf[0] = '\0';
-	do {
-		for(i = 0; i < MAX_IOC; ++i) {
-
-			struct ioc *ioc = &ioa->ioc[i];
-			unsigned int total_pages = ioc->res_size << 3;
-
-			sprintf(buf, "%s%s rev %d.%d\n", buf,
-				ioc->name,
-				(ioc->ioa->hw_rev & 0x7) + 1, (ioc->ioa->hw_rev & 0x18) >> 3);
-			
-			sprintf(buf, "%sCujo 2.0 bug    : %s\n",
-				buf, (ioc->cujo20_bug ? "yes" : "no"));
-			
-			sprintf(buf, "%sIO PDIR size    : %d bytes (%d entries)\n",
-				buf, ((ioc->res_size << 3) * sizeof(u64)), total_pages);
-			
-			sprintf(buf, "%sIO PDIR size    : %d bytes (%d entries)\n",
-				buf, ((ioc->res_size << 3) * sizeof(u64)), total_pages);
-			
-			sprintf(buf, "%sIO PDIR entries : %ld free  %ld used (%d%%)\n", buf,
-				total_pages - ioc->used_pages, ioc->used_pages,
-				(int)(ioc->used_pages * 100 / total_pages));
-			
-			sprintf(buf, "%sResource bitmap : %d bytes (%d pages)\n", 
-				buf, ioc->res_size, ioc->res_size << 3);
-			
-			min = max = ioc->avg_search[0];
-			for(j = 0; j < CCIO_SEARCH_SAMPLE; ++j) {
-				avg += ioc->avg_search[j];
-				if(ioc->avg_search[j] > max) 
-					max = ioc->avg_search[j];
-				if(ioc->avg_search[j] < min) 
-					min = ioc->avg_search[j];
-			}
-			avg /= CCIO_SEARCH_SAMPLE;
-			sprintf(buf, "%s  Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n",
-				buf, min, avg, max);
-			
-			sprintf(buf, "%spci_map_single(): %8ld calls  %8ld pages (avg %d/1000)\n",
-				buf, ioc->msingle_calls, ioc->msingle_pages,
-				(int)((ioc->msingle_pages * 1000)/ioc->msingle_calls));
-			
-			/* KLUGE - unmap_sg calls unmap_single for each mapped page */
-			min = ioc->usingle_calls - ioc->usg_calls;
-			max = ioc->usingle_pages - ioc->usg_pages;
-			sprintf(buf, "%spci_unmap_single: %8ld calls  %8ld pages (avg %d/1000)\n",
-				buf, min, max, (int)((max * 1000)/min));
-			
-			sprintf(buf, "%spci_map_sg()    : %8ld calls  %8ld pages (avg %d/1000)\n",
-				buf, ioc->msg_calls, ioc->msg_pages,
-				(int)((ioc->msg_pages * 1000)/ioc->msg_calls));
-			
-			sprintf(buf, "%spci_unmap_sg()  : %8ld calls  %8ld pages (avg %d/1000)\n\n\n",
-				buf, ioc->usg_calls, ioc->usg_pages,
-				(int)((ioc->usg_pages * 1000)/ioc->usg_calls));
+	while (ioc != NULL) {
+		unsigned int total_pages = ioc->res_size << 3;
+		unsigned long avg = 0, min, max;
+		int j;
+
+		sprintf(buf, "%s%s\n", buf, ioc->name);
+
+		sprintf(buf, "%sCujo 2.0 bug    : %s\n",
+			buf, (ioc->cujo20_bug ? "yes" : "no"));
+
+		sprintf(buf, "%sIO PDIR size    : %ld bytes (%ud entries)\n",
+			buf, ((ioc->res_size << 3) * sizeof(u64)), total_pages);
+
+		sprintf(buf, "%sIO PDIR entries : %ld free  %ld used (%d%%)\n", buf,
+			total_pages - ioc->used_pages, ioc->used_pages,
+			(int)(ioc->used_pages * 100 / total_pages));
+
+		sprintf(buf, "%sResource bitmap : %d bytes (%d pages)\n", 
+			buf, ioc->res_size, ioc->res_size << 3);
+
+		min = max = ioc->avg_search[0];
+		for(j = 0; j < CCIO_SEARCH_SAMPLE; ++j) {
+			avg += ioc->avg_search[j];
+			if(ioc->avg_search[j] > max) 
+				max = ioc->avg_search[j];
+			if(ioc->avg_search[j] < min) 
+				min = ioc->avg_search[j];
 		}
-		ioa = ioa->next;
-
-	} while(NULL != ioa);
+		avg /= CCIO_SEARCH_SAMPLE;
+		sprintf(buf, "%s  Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n",
+			buf, min, avg, max);
+
+		sprintf(buf, "%spci_map_single(): %8ld calls  %8ld pages (avg %d/1000)\n",
+			buf, ioc->msingle_calls, ioc->msingle_pages,
+			(int)((ioc->msingle_pages * 1000)/ioc->msingle_calls));
+
+		/* KLUGE - unmap_sg calls unmap_single for each mapped page */
+		min = ioc->usingle_calls - ioc->usg_calls;
+		max = ioc->usingle_pages - ioc->usg_pages;
+		sprintf(buf, "%spci_unmap_single: %8ld calls  %8ld pages (avg %d/1000)\n",
+			buf, min, max, (int)((max * 1000)/min));
+
+		sprintf(buf, "%spci_map_sg()    : %8ld calls  %8ld pages (avg %d/1000)\n",
+			buf, ioc->msg_calls, ioc->msg_pages,
+			(int)((ioc->msg_pages * 1000)/ioc->msg_calls));
+
+		sprintf(buf, "%spci_unmap_sg()  : %8ld calls  %8ld pages (avg %d/1000)\n\n\n",
+			buf, ioc->usg_calls, ioc->usg_pages,
+			(int)((ioc->usg_pages * 1000)/ioc->usg_calls));
+		ioc = ioc->next;
+	}
 
 	return strlen(buf);
 }
@@ -1156,100 +1123,48 @@ ccio_proc_info(char *buf, char **start, 
 static int
 ccio_resource_map(char *buf, char **start, off_t offset, int len)
 {
-	int i, j;
-	struct ccio_device *ioa = ccio_list;
+	struct ioc *ioc = ioc_list;
 
 	buf[0] = '\0';
-	do {
-		for(i = 0; i < MAX_IOC; ++i) {
-			struct ioc *ioc = &ioa->ioc[i];
-			u32 *res_ptr = (u32 *)ioc->res_map;
-
-			for(j = 0; j < (ioc->res_size / sizeof(u32)); ++j, ++res_ptr) {
-				if((j & 7) == 0)
-					strcat(buf,"\n   ");
-				sprintf(buf, "%s %08x", buf, *res_ptr);
-			}
-			strcat(buf, "\n\n");
+	while (ioc != NULL) {
+		u32 *res_ptr = (u32 *)ioc->res_map;
+		int j;
+
+		for (j = 0; j < (ioc->res_size / sizeof(u32)); j++) {
+			if ((j & 7) == 0)
+				strcat(buf,"\n   ");
+			sprintf(buf, "%s %08x", buf, *res_ptr);
+			res_ptr++;
 		}
-		ioa = ioa->next;
-
-	} while(NULL != ioa);
+		strcat(buf, "\n\n");
+		ioc = ioc->next;
+	}
 
 	return strlen(buf);
 }
 #endif
 
-static struct {
-		u16 hversion;
-		u8  spa;
-		u8  type;
-		u32 foo[3];	/* 16 bytes total */
-} cujo_iodc;
-
-#define CUJO_20_BITMASK    0x0ffff000	/* upper nibble is a don't care   */
 #define CUJO_20_STEP       0x10000000	/* inc upper nibble */
-#define CUJO_20_BADPAGE1   0x01003000	/* pages that hpmc on raven U+    */
-#define CUJO_20_BADPAGE2   0x01607000	/* pages that hpmc on firehawk U+ */
-#define CUJO_20_BADHVERS   0x6821	/* low nibble 1 is cujo rev 2.0 */
-#define CUJO_RAVEN_LOC     0xf1000000UL	/* cujo location on raven U+ */
-#define CUJO_FIREHAWK_LOC  0xf1604000UL	/* cujo location on firehawk U+ */
 
-/**
- * ccio_cujo20_fixup - Detect and work around a bug in the CUJO 2.0 chip.
- * @ioc: The I/O Controller.
- *
- * CUJO 2.0 incorrectly decodes a memory access for specific
- * pages (every page at specific I/O TLB locations dependent
- * upon where the cujo is flexed - diff on raven/firehawk.
- * resulting in an HPMC and/or silent data corruption.
- * Workaround is to prevent use of those I/O TLB entries
- * by marking the suspect bitmap range entries as busy.
+/* Cujo 2.0 has a bug which will silently corrupt data being transferred
+ * to/from certain pages.  To avoid this happening, we mark these pages
+ * as `used', and ensure that nothing will try to allocate from them.
  */
-static void
-ccio_cujo20_fixup(struct ioc *ioc)
+void ccio_cujo20_fixup(struct parisc_device *dev, u32 iovp)
 {
-	unsigned long bytecnt;
-	u32 iovp = 0, io_io_low;
 	unsigned int idx;
-	unsigned long status, mask;
-	u8 *res_ptr = ioc->res_map;
+	struct ioc *ioc = ioc_list;
+	u8 *res_ptr;
 
-	/* only test IOC that have the potential to be bad. */
-	io_io_low = READ_U32(&ioc->ioc_hpa->io_io_low) << 16;
-	if(!(CUJO_RAVEN_LOC == io_io_low || CUJO_FIREHAWK_LOC == io_io_low))
-		return;
-	
-	status = pdc_iodc_read(&bytecnt, (void *)CUJO_RAVEN_LOC, 0,
-			       &cujo_iodc, 16);
-	if(0 == status) {
-		if(CUJO_20_BADHVERS == cujo_iodc.hversion)
-			iovp = CUJO_20_BADPAGE1;
-	} else {
-		status = pdc_iodc_read(&bytecnt, (void *)CUJO_FIREHAWK_LOC, 0,
-				       &cujo_iodc, 16);
-		if(0 == status) {
-			if(CUJO_20_BADHVERS == cujo_iodc.hversion)
-				iovp = CUJO_20_BADPAGE2;
-		} else {
-			/* not a defective system */
-			return;
-		}
-	}
-
-	printk(KERN_WARNING MODULE_NAME ": Cujo 2.0 bug needs a work around\n");
 #ifdef CONFIG_PROC_FS
 	ioc->cujo20_bug = 1;
 #endif
-	/*
-	** mark bit entries that match "bad page"
-	*/
+	res_ptr = ioc->res_map;
 	idx = PDIR_INDEX(iovp) >> 3;
-	mask = 0xff;
-	
-	while(idx * sizeof(u8) < ioc->res_size) {
- 		res_ptr[idx] |= mask;
-		idx += (PDIR_INDEX(CUJO_20_STEP)>>3);
+
+	while (idx < ioc->res_size) {
+ 		res_ptr[idx] |= 0xff;
+		idx += PDIR_INDEX(CUJO_20_STEP) >> 3;
 	}
 }
 
@@ -1407,81 +1322,59 @@ ccio_ioc_init(struct ioc *ioc)
 		WRITE_U32((CMD_TLB_DIRECT_WRITE | (i << ioc->chainid_shift)),
 			  &ioc->ioc_hpa->io_command);
 	}
-
-	/*
-	** See if we need the cujo 2.0 work around.
-	*/
-	ccio_cujo20_fixup(ioc);
 }
 
 int do_native_bus_walk(unsigned long io_io_low);
 
 /**
- * ccio_driver_callback - Determine if ccio should claim this device.
- * @d: The device.
- * @dri: The IODC information about the device.
+ * ccio_probe - Determine if ccio should claim this device.
+ * @dev: The device which has been found
  *
  * Determine if ccio should claim this chip (return 0) or not (return 1).
  * If so, initialize the chip and tell other partners in crime they
  * have work to do.
  */
-static int
-ccio_driver_callback(struct parisc_device *dev)
+static int ccio_probe(struct parisc_device *dev)
 {
 	int i, start_index, num_devices;
 	unsigned long io_io_low, io_io_high;
-	struct ccio_device *ioa = ccio_list;
+	struct ioc *ioc, **ioc_p = &ioc_list;
+
+	ioc = kmalloc(sizeof(struct ioc), GFP_KERNEL);
 
+	if (ioc == NULL) {
+		printk(KERN_ERR MODULE_NAME ": memory allocation failure\n");
+		return 1;
+	}
+	memset(ioc, 0, sizeof(struct ioc));
+
 	printk(KERN_INFO "%s found %s at 0x%lx\n", MODULE_NAME,
 			dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn",
 			dev->hpa);
 
-	if (NULL == ccio_list) {
-		create_proc_info_entry(MODULE_NAME, 0, proc_runway_root, ccio_proc_info);
-		create_proc_info_entry(MODULE_NAME"-bitmap", 0, proc_runway_root,
-					       ccio_resource_map);
-		
-		ccio_list = kmalloc(sizeof(struct ccio_device), GFP_KERNEL);
-		if(NULL == ccio_list) {
-			printk(KERN_ERR MODULE_NAME " - couldn't alloc ccio_device\n");
-			return 1;
-		}
-		memset(ccio_list, 0, sizeof(struct ccio_device));
-		ioa = ccio_list;
-		++ccio_count;
+	for (i = 0; i < ioc_count; i++) {
+		ioc_p = &(*ioc_p)->next;
 	}
+	*ioc_p = ioc;
 
-	for(i = 0; i < (ccio_count - 1); ++i) {
-		ioa = ioa->next;
-	}
+	ioc->iodc = &dev->id;
+	ioc->name = dev->name;
+	ioc->ioc_hpa = (struct ioa_registers *)dev->hpa;
+	ccio_ioc_init(ioc);
 
-	for(i = 0; i < MAX_IOC; ++i) {
-		if(NULL == ioa->ioc[i].ioc_hpa)
-			break;
-	}
+	hppa_dma_ops = &ccio_ops;
 
-	if(MAX_IOC == i) {
-		ioa->next = kmalloc(sizeof(struct ccio_device), GFP_KERNEL);
-		ioa = ioa->next;
-		if(NULL == ioa) {
-			printk(KERN_ERR MODULE_NAME " - couldn't alloc ccio_device\n");
-			return 1;
-		}
-		memset(ioa, 0, sizeof(struct ccio_device));
-		++ccio_count;
-		i = 0;
+	if (ioc_count == 0) {
+		/* XXX: Create separate entries for each ioc */
+		create_proc_info_entry(MODULE_NAME, 0, proc_runway_root, ccio_proc_info);
+		create_proc_info_entry(MODULE_NAME"-bitmap", 0, proc_runway_root,
+					       ccio_resource_map);
 	}
 
-	ioa->ioc[i].iodc = &dev->id;
-	ioa->ioc[i].name = dev->name;
-	ioa->ioc[i].ioc_hpa = (struct ioa_registers *)dev->hpa;
-	ioa->ioc[i].ioa = ioa;
-	ccio_ioc_init(&ioa->ioc[i]);
+	ioc_count++;
 
-	hppa_dma_ops = &ccio_ops;
-	
-	io_io_low = READ_U32(&ioa->ioc[i].ioc_hpa->io_io_low) << 16;
-	io_io_high = READ_U32(&ioa->ioc[i].ioc_hpa->io_io_high) << 16;
+	io_io_low = READ_U32(&ioc->ioc_hpa->io_io_low) << 16;
+	io_io_high = READ_U32(&ioc->ioc_hpa->io_io_high) << 16;
 	printk(KERN_INFO "io_io_high: 0x%08lx io_io_low: 0x%08lx\n", io_io_high, io_io_low);
 	start_index = get_num_pa_dev();
 	num_devices = do_native_bus_walk(io_io_low);
@@ -1499,7 +1392,7 @@ static struct parisc_device_id ccio_tbl[
 static struct parisc_driver ccio_driver = {
 	name:		"U2/Uturn",
 	id_table:	ccio_tbl,
-	probe:		ccio_driver_callback,
+	probe:		ccio_probe,
 };
 
 /**
Index: drivers/gsc/dino.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/gsc/dino.c,v
retrieving revision 1.37
diff -u -p -r1.37 dino.c
--- dino.c	2001/08/30 01:30:25	1.37
+++ dino.c	2001/08/31 04:56:33
@@ -86,8 +86,6 @@
 ** bus number for each dino.
 */
 
-// REVISIT: 715 reports card-mode Dino IODC data wrong.
-// May need to read it "by hand".
 #define is_card_dino(id) ((id)->hw_type == HPHW_A_DMA)
 
 #define DINO_IAR0		0x004
@@ -847,6 +845,11 @@ dino_common_init(struct parisc_device *d
 	return(0);
 }
 
+#define CUJO_RAVEN_ADDR		0xf1000000UL
+#define CUJO_FIREHAWK_ADDR	0xf1604000UL
+#define CUJO_RAVEN_BADPAGE	0x01003000UL
+#define CUJO_FIREHAWK_BADPAGE	0x01607000UL
+
 static const char *dino_vers[] = {
 	"2.0",
 	"2.1",
@@ -898,12 +901,12 @@ dino_driver_callback(struct parisc_devic
 
 	/* Check for bugs */
 	if (is_cujo && dev->id.hversion_rev == 1) {
-#if 0
+#ifdef CONFIG_IOMMU_CCIO
 		printk(KERN_WARNING "Enabling Cujo 2.0 bug workaround\n");
 		if (dev->hpa == CUJO_RAVEN_ADDR) {
-			ccio_cujo20_hack(dev->parent, CUJO_RAVEN_BADPAGE);
+			ccio_cujo20_fixup(dev->parent, CUJO_RAVEN_BADPAGE);
 		} else if (dev->hpa == CUJO_FIREHAWK_ADDR) {
-			ccio_cujo20_hack(dev->parent, CUJO_FIREHAWK_BADPAGE);
+			ccio_cujo20_fixup(dev->parent, CUJO_FIREHAWK_BADPAGE);
 		} else {
 			printk("Don't recognise Cujo at address 0x%lx, not enabling workaround\n", dev->hpa);
 		}
Index: drivers/gsc/gsc.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/gsc/gsc.c,v
retrieving revision 1.24
diff -u -p -r1.24 gsc.c
--- gsc.c	2001/08/28 13:56:18	1.24
+++ gsc.c	2001/08/31 04:56:33
@@ -204,9 +204,6 @@ void __init gsc_init(void)
 
 	parisc_proc_mkdir();
 
-#if defined(CONFIG_GSC_DINO)
-	dino_init();
-#endif
 #if defined(CONFIG_IOSAPIC)
 	iosapic_init();
 #endif
@@ -217,13 +214,15 @@ void __init gsc_init(void)
 #if defined(CONFIG_IOMMU_SBA)
 	sba_init();
 #endif
+#if defined(CONFIG_IOMMU_CCIO)
+	ccio_init();
+#endif
+#if defined(CONFIG_GSC_DINO)
+	dino_init();
+#endif
 
 #ifdef CONFIG_GSC_LASI
 	busdevices_init();
-#endif
-
-#if defined(CONFIG_IOMMU_CCIO)
-	ccio_init();
 #endif
 
 #ifdef CONFIG_CHASSIS_LCD_LED