[parisc-linux] EISA changes broke SuckyIO

Grant Grundler grundler@puffin.external.hp.com
Thu, 11 Oct 2001 15:06:18 -0600


Matthew Wilcox wrote:
> The recent changes (-pa46 or so) which I made to support EISA have
> broken SuckyIO-based boxes -- everything from the B1000 to J7000.
> This will get fixed tomorrow.

I tried to fix this modifying suckyio support to work with
something other tha zero-based IOport space. serial and parallel
ports worked. IDE was causing data page faults at boot and I decided
I wasn't going to pursue this path any further. Here's the patch of
what I've done so far in case anyone needs to support suckyio as an
add-on card.

Matthew promised to fix the EISA support so HBA 0 isn't reserved
for all platforms. And suckyio will get zero based IO port
space again.

grant


Index: arch/parisc/kernel/superio.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/superio.c,v
retrieving revision 1.8
diff -u -p -r1.8 superio.c
--- superio.c	2001/09/06 09:44:07	1.8
+++ superio.c	2001/10/11 20:55:51
@@ -76,6 +76,25 @@ static struct superio_device sio_dev = {
 	iosapic_irq: -1
 };
 
+#if 1
+/* CONFIG_EISA support reserves HBA 0.
+** Suckyio up to now assumed it had HBA 0 (which is normally true).
+*/
+static int sio_hba_base = 0;
+static __inline__ unsigned char sio_inb(addr)
+{
+	return inb(sio_hba_base + addr);
+}
+
+static void __inline__ sio_outb(unsigned char val, unsigned int addr)
+{
+	outb(val, sio_hba_base + addr);
+}
+#else /* !CONFIG_EISA */
+#define sio_inb inb
+#define sio_outb outb
+#endif /* !CONFIG_EISA */
+
 void
 superio_inform_irq(int irq)
 {
@@ -98,9 +117,9 @@ superio_interrupt(int irq, void *devp, s
 	u8 local_irq;
 
 	/* Poll the 8259 to see if there's an interrupt. */
-	outb (OCW3_POLL,IC_PIC1+0);
+	sio_outb (OCW3_POLL,IC_PIC1+0);
 
-	results = inb(IC_PIC1+0);
+	results = sio_inb(IC_PIC1+0);
 
 	if ((results & 0x80) == 0) {
 #ifndef CONFIG_SMP
@@ -124,8 +143,8 @@ superio_interrupt(int irq, void *devp, s
 
 		/* Could be spurious. Check in service bits */
 
-		outb(OCW3_ISR,IC_PIC1+0);
-		results = inb(IC_PIC1+0);
+		sio_outb(OCW3_ISR,IC_PIC1+0);
+		results = sio_inb(IC_PIC1+0);
 		if ((results & 0x80) == 0) { /* if ISR7 not set: spurious */
 			printk(KERN_WARNING "SuperIO: spurious interrupt!\n");
 			return;
@@ -140,7 +159,7 @@ superio_interrupt(int irq, void *devp, s
 
 	/* set EOI */
 
-	outb((OCW2_SEOI|local_irq),IC_PIC1 + 0);
+	sio_outb((OCW2_SEOI|local_irq),IC_PIC1 + 0);
 	return;
 }
 
@@ -162,20 +181,29 @@ superio_init(struct superio_device *sio)
 	printk (KERN_INFO "SuperIO: Found NS87560 legacy I/O device at %s. iosapic irq = %i \n",
 		pdev->slot_name,sio->iosapic_irq);
 
+/* #ifdef CONFIG_EISA */
+#if 1
+	sio_hba_base = HBA_FIXUP_IOPORT(pdev, 0);
+#endif
+
 	/* Find our I/O devices */
-	pci_read_config_word (pdev, SIO_SP1BAR, &sio->sp1_base);
+	pci_read_config_word (pdev, SIO_SP1BAR, &word);
+	sio->sp1_base = HBA_FIXUP_IOPORT(pdev, word);
 	sio->sp1_base &= ~1;
 	printk (KERN_INFO "SuperIO: Serial port 1 at 0x%x\n", sio->sp1_base);
 
-	pci_read_config_word (pdev, SIO_SP2BAR, &sio->sp2_base);
+	pci_read_config_word (pdev, SIO_SP2BAR, &word);
+	sio->sp2_base = HBA_FIXUP_IOPORT(pdev, word);
 	sio->sp2_base &= ~1;
 	printk (KERN_INFO "SuperIO: Serial port 2 at 0x%x\n", sio->sp2_base);
 
-	pci_read_config_word (pdev, SIO_PPBAR, &sio->pp_base);
+	pci_read_config_word (pdev, SIO_PPBAR, &word);
+	sio->pp_base = HBA_FIXUP_IOPORT(pdev, word);
 	sio->pp_base &= ~1;
 	printk (KERN_INFO "SuperIO: Parallel port at 0x%x\n", sio->pp_base);
 
-	pci_read_config_word (pdev, SIO_FDCBAR, &sio->fdc_base);
+	pci_read_config_word (pdev, SIO_FDCBAR, &word);
+	sio->fdc_base = HBA_FIXUP_IOPORT(pdev, word);
 	sio->fdc_base &= ~1;
 	printk (KERN_INFO "SuperIO: Floppy controller at 0x%x\n", sio->fdc_base);
 
@@ -202,28 +230,28 @@ superio_init(struct superio_device *sio)
 		pci_write_config_byte (pdev, i, 0x0);
 
 	/* PIC1 Initialization Command Word register programming */
-	outb (0x11,IC_PIC1+0);	/* ICW1: ICW4 write req | ICW1 */
-	outb (0x00,IC_PIC1+1);	/* ICW2: N/A */
-	outb (0x04,IC_PIC1+1);	/* ICW3: Cascade */
-	outb (0x01,IC_PIC1+1);	/* ICW4: x86 mode */
+	sio_outb (0x11,IC_PIC1+0);	/* ICW1: ICW4 write req | ICW1 */
+	sio_outb (0x00,IC_PIC1+1);	/* ICW2: N/A */
+	sio_outb (0x04,IC_PIC1+1);	/* ICW3: Cascade */
+	sio_outb (0x01,IC_PIC1+1);	/* ICW4: x86 mode */
 
 	/* PIC1 Program Operational Control Words */
-	outb (0xff,IC_PIC1+1);	/* OCW1: Mask all interrupts */
-	outb (0xc2,IC_PIC1+0);  /* OCW2: priority (3-7,0-2) */
+	sio_outb (0xff,IC_PIC1+1);	/* OCW1: Mask all interrupts */
+	sio_outb (0xc2,IC_PIC1+0);  /* OCW2: priority (3-7,0-2) */
 
 	/* PIC2 Initialization Command Word register programming */
-	outb (0x11,IC_PIC2+0);	/* ICW1: ICW4 write req | ICW1 */
-	outb (0x00,IC_PIC2+1);	/* ICW2: N/A */
-	outb (0x02,IC_PIC2+1);	/* ICW3: Slave ID code */
-	outb (0x01,IC_PIC2+1);	/* ICW4: x86 mode */
+	sio_outb (0x11,IC_PIC2+0);	/* ICW1: ICW4 write req | ICW1 */
+	sio_outb (0x00,IC_PIC2+1);	/* ICW2: N/A */
+	sio_outb (0x02,IC_PIC2+1);	/* ICW3: Slave ID code */
+	sio_outb (0x01,IC_PIC2+1);	/* ICW4: x86 mode */
 		
 	/* Program Operational Control Words */
-	outb (0xff,IC_PIC1+1);	/* OCW1: Mask all interrupts */
-	outb (0x68,IC_PIC1+0);	/* OCW3: OCW3 select | ESMM | SMM */
+	sio_outb (0xff,IC_PIC1+1);	/* OCW1: Mask all interrupts */
+	sio_outb (0x68,IC_PIC1+0);	/* OCW3: OCW3 select | ESMM | SMM */
 
 	/* Write master mask reg */
 
-	outb (0xff,IC_PIC1+1);
+	sio_outb (0xff,IC_PIC1+1);
 
 	/* Set up interrupt routing */
 
@@ -262,9 +290,9 @@ superio_disable_irq(void *dev, int local
 
 	/* Mask interrupt */
 
-	r8 = inb(IC_PIC1+1);
+	r8 = sio_inb(IC_PIC1+1);
 	r8 |= (1 << local_irq);
-	outb (r8,IC_PIC1+1);
+	sio_outb (r8,IC_PIC1+1);
 }
 
 static void
@@ -289,9 +317,9 @@ superio_enable_irq(void *dev, int local_
 
 	/* Unmask interrupt */
 
-	r8 = inb(IC_PIC1+1);
+	r8 = sio_inb(IC_PIC1+1);
 	r8 &= ~(1 << local_irq);
-	outb (r8,IC_PIC1+1);
+	sio_outb (r8,IC_PIC1+1);
 }
 
 static void
Index: include/asm-parisc/pci.h
===================================================================
RCS file: /home/cvs/parisc/linux/include/asm-parisc/pci.h,v
retrieving revision 1.31
diff -u -p -r1.31 pci.h
--- pci.h	2001/10/10 20:10:13	1.31
+++ pci.h	2001/10/11 20:55:54
@@ -69,6 +69,8 @@ struct pci_hba_data {
 #define HBA_PORT_BASE(h)	((h) << HBA_PORT_SPACE_BITS)
 #define HBA_PORT_SPACE_SIZE	(1UL << HBA_PORT_SPACE_BITS)
 
+#define HBA_FIXUP_IOPORT(pdev, b) (HBA_PORT_BASE(HBA_DATA(pdev->sysdata)->hba_num) + b)
+
 #define PCI_PORT_HBA(a)		((a) >> HBA_PORT_SPACE_BITS)
 #define PCI_PORT_ADDR(a)	((a) & (HBA_PORT_SPACE_SIZE - 1))
 
Index: include/asm-parisc/superio.h
===================================================================
RCS file: /home/cvs/parisc/linux/include/asm-parisc/superio.h,v
retrieving revision 1.3
diff -u -p -r1.3 superio.h
--- superio.h	2001/07/15 20:02:07	1.3
+++ superio.h	2001/10/11 20:55:54
@@ -38,10 +38,10 @@
 #define SUPERIO_NIRQS   8
 
 struct superio_device {
-	u16 fdc_base;
-	u16 sp1_base;
-	u16 sp2_base;
-	u16 pp_base;
+	unsigned int fdc_base;
+	unsigned int sp1_base;
+	unsigned int sp2_base;
+	unsigned int pp_base;
 	int iosapic_irq;
 	int iosapic_irq_enabled;
 	struct irq_region *irq_region;