[parisc-linux-cvs] linux-2.6 grundler
Grant Grundler
grundler at parisc-linux.org
Tue Sep 28 12:04:34 MDT 2004
On Tue, Sep 28, 2004 at 11:07:02AM -0600, Grant Grundler wrote:
> Log message:
> 2.6.9-rc-pa12 Superio cleanup and fix /proc/iomem output for PAT PDC boxes
moved the IDE knowledge (linux/ide.h) from superio driver to ns87514
driver as requested by Bartlomiej Zolnierkiewicz.
I've seperated out the suckyio parts and it's available from:
ftp://ftp.parisc-linux.org/patches/diff-2.6.9-rc2-ns87415_suckyio_cleanup-02
Superio IDE still doesn't not work properly on my C3000.
I get IO errors when trying to dd from a bootable CD-rom.
No clue why - maybe I'm just using the wrong or broken CD.
And the PCI/IDE fixup ordering patch from willy is required to
boot with ns87415 driver (as either built-in or a module) on C3000.
Second bit of this patch fixes PAT PDC output so it looks
like the "legacy PDC" output. ie proper PCIxx names and GMMIO
is also labeled with PCIxx output.
grant
Index: Makefile
===================================================================
RCS file: /var/cvs/linux-2.6/Makefile,v
retrieving revision 1.257
diff -u -p -r1.257 Makefile
--- Makefile 27 Sep 2004 21:27:56 -0000 1.257
+++ Makefile 28 Sep 2004 05:20:34 -0000
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 9
-EXTRAVERSION = -rc2-pa11
+EXTRAVERSION = -rc2-pa12
NAME=Zonked Quokka
# *DOCUMENTATION*
Index: drivers/ide/pci/ns87415.c
===================================================================
RCS file: /var/cvs/linux-2.6/drivers/ide/pci/ns87415.c,v
retrieving revision 1.17
diff -u -p -r1.17 ns87415.c
--- drivers/ide/pci/ns87415.c 13 Sep 2004 15:23:04 -0000 1.17
+++ drivers/ide/pci/ns87415.c 28 Sep 2004 05:20:37 -0000
@@ -4,6 +4,7 @@
* Copyright (C) 1997-1998 Mark Lord <mlord at pobox.com>
* Copyright (C) 1998 Eddie C. Dost <ecd at skynet.be>
* Copyright (C) 1999-2000 Andre Hedrick <andre at linux-ide.org>
+ * Copyright (C) 2004 Grant Grundler <grundler at parisc-linux.org>
*
* Inspired by an earlier effort from David S. Miller <davem at redhat.com>
*/
@@ -24,8 +25,74 @@
#include <linux/init.h>
#include <asm/io.h>
+
#ifdef CONFIG_SUPERIO
+/* SUPERIO 87560 is a PoS chip that NatSem denies exists.
+ * Unfortunately, it's built-in on all Astro-based PA-RISC workstations
+ * which use the integrated NS87514 cell for CD-ROM support.
+ * i.e we have to support for CD-ROM installs.
+ * See drivers/parisc/superio.c for more gory details.
+ */
#include <asm/superio.h>
+
+static unsigned long superio_ide_status[2];
+static unsigned long superio_ide_select[2];
+static unsigned long superio_ide_dma_status[2];
+
+#define SUPERIO_IDE_MAX_RETRIES 25
+
+/* Because of a defect in Super I/O, all reads of the PCI DMA status
+ * registers, IDE status register and the IDE select register need to be
+ * retried
+ */
+static u8 superio_ide_inb (unsigned long port)
+{
+ if (port == superio_ide_status[0] ||
+ port == superio_ide_status[1] ||
+ port == superio_ide_select[0] ||
+ port == superio_ide_select[1] ||
+ port == superio_ide_dma_status[0] ||
+ port == superio_ide_dma_status[1]) {
+ u8 tmp;
+ int retries = SUPERIO_IDE_MAX_RETRIES;
+
+ /* printk(" [ reading port 0x%x with retry ] ", port); */
+
+ do {
+ tmp = inb(port);
+ if (tmp == 0)
+ udelay(50);
+ } while (tmp == 0 && retries-- > 0);
+
+ return tmp;
+ }
+
+ return inb(port);
+}
+
+static void __devinit superio_ide_init_iops (struct hwif_s *hwif)
+{
+ u32 base, dmabase;
+ u8 tmp;
+ struct pci_dev *pdev = hwif->pci_dev;
+ u8 port = hwif->channel;
+
+ base = pci_resource_start(pdev, port * 2) & ~3;
+ dmabase = pci_resource_start(pdev, 4) & ~3;
+
+ superio_ide_status[port] = base + IDE_STATUS_OFFSET;
+ superio_ide_select[port] = base + IDE_SELECT_OFFSET;
+ superio_ide_dma_status[port] = dmabase + (!port ? 2 : 0xa);
+
+ /* Clear error/interrupt, enable dma */
+ tmp = superio_ide_inb(superio_ide_dma_status[port]);
+ outb(tmp | 0x66, superio_ide_dma_status[port]);
+
+ /* We need to override inb to workaround a SuperIO errata */
+ hwif->INB = superio_ide_inb;
+}
+#else
+static void __devinit superio_ide_init_iops (struct hwif_s *hwif) {}
#endif
static unsigned int ns87415_count = 0, ns87415_control[MAX_HWIFS] = { 0 };
@@ -135,8 +202,11 @@ static int ns87415_ide_dma_check (ide_dr
static void __init init_iops_ns87415(ide_hwif_t *hwif)
{
-#ifdef CONFIG_SUPERIO
- superio_ide_init_iops(hwif);
+#ifdef CONFIG_PARISC
+ if (PCI_SLOT(hwif->pci_dev->devfn) == 0xE) {
+ /* Built-in - assume it's under superio. */
+ superio_ide_init_iops(hwif);
+ }
#endif
}
@@ -153,10 +223,6 @@ static void __init init_hwif_ns87415 (id
hwif->autodma = 0;
hwif->selectproc = &ns87415_selectproc;
- /* Set a good latency timer and cache line size value. */
- (void) pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
- /* FIXME: use pci_set_master() to ensure good latency timer value */
-
/*
* We cannot probe for IRQ: both ports share common IRQ on INTA.
* Also, leave IRQ masked during drive probing, to prevent infinite
@@ -227,6 +293,7 @@ static void __init init_hwif_ns87415 (id
static ide_pci_device_t ns87415_chipset __devinitdata = {
.name = "NS87415",
+ .init_iops = init_iops_ns87415,
.init_hwif = init_hwif_ns87415,
.channels = 2,
.autodma = AUTODMA,
Index: drivers/parisc/lba_pci.c
===================================================================
RCS file: /var/cvs/linux-2.6/drivers/parisc/lba_pci.c,v
retrieving revision 1.13
diff -u -p -r1.13 lba_pci.c
--- drivers/parisc/lba_pci.c 26 Sep 2004 23:56:45 -0000 1.13
+++ drivers/parisc/lba_pci.c 28 Sep 2004 05:20:38 -0000
@@ -116,7 +116,7 @@
** bus number for each LBA depending on what firmware does.
*/
-#define MODULE_NAME "lba"
+#define MODULE_NAME "LBA"
#define LBA_FUNC_ID 0x0000 /* function id */
#define LBA_FCLASS 0x0008 /* function class, bist, header, rev... */
@@ -1121,10 +1121,22 @@ lba_pat_resources(struct parisc_device *
case PAT_LMMIO:
/* used to fix up pre-initialized MEM BARs */
- lba_dev->hba.lmmio_space_offset = p->start - io->start;
-
- r = &(lba_dev->hba.lmmio_space);
- r->name = "LBA LMMIO";
+ if (!lba_dev->hba.lmmio_space.start) {
+ sprintf(lba_dev->hba.lmmio_name, "PCI%02x LMMIO",
+ (int) lba_dev->hba.bus_num.start);
+ lba_dev->hba.lmmio_space_offset = p->start - io->start;
+ r = &(lba_dev->hba.lmmio_space);
+ r->name = lba_dev->hba.lmmio_name;
+ } else if (!lba_dev->hba.elmmio_space.start) {
+ sprintf(lba_dev->hba.elmmio_name, "PCI%02x ELMMIO",
+ (int) lba_dev->hba.bus_num.start);
+ r = &(lba_dev->hba.elmmio_space);
+ r->name = lba_dev->hba.elmmio_name;
+ } else {
+ printk(KERN_WARNING MODULE_NAME
+ " only supports 2 LMMIO resources!\n");
+ break;
+ }
r->start = p->start;
r->end = p->end;
r->flags = IORESOURCE_MEM;
@@ -1133,8 +1145,10 @@ lba_pat_resources(struct parisc_device *
case PAT_GMMIO:
/* MMIO space > 4GB phys addr; for 64-bit BAR */
+ sprintf(lba_dev->hba.gmmio_name, "PCI%02x GMMIO",
+ (int) lba_dev->hba.bus_num.start);
r = &(lba_dev->hba.gmmio_space);
- r->name = "LBA GMMIO";
+ r->name = lba_dev->hba.gmmio_name;
r->start = p->start;
r->end = p->end;
r->flags = IORESOURCE_MEM;
@@ -1154,8 +1168,10 @@ lba_pat_resources(struct parisc_device *
*/
lba_dev->iop_base = p->start;
+ sprintf(lba_dev->hba.io_name, "PCI%02x Ports",
+ (int) lba_dev->hba.bus_num.start);
r = &(lba_dev->hba.io_space);
- r->name = "LBA I/O Port";
+ r->name = lba_dev->hba.io_name;
r->start = HBA_PORT_BASE(lba_dev->hba.hba_num);
r->end = r->start + HBA_PORT_SPACE_SIZE - 1;
r->flags = IORESOURCE_IO;
@@ -1219,7 +1235,7 @@ lba_legacy_resources(struct parisc_devic
r = &(lba_dev->hba.lmmio_space);
sprintf(lba_dev->hba.lmmio_name, "PCI%02x LMMIO",
(int) lba_dev->hba.bus_num.start);
- r->name = &lba_dev->hba.lmmio_name[0];
+ r->name = lba_dev->hba.lmmio_name;
#if 1
/* We want the CPU -> IO routing of addresses.
@@ -1327,7 +1343,7 @@ lba_legacy_resources(struct parisc_devic
r = &(lba_dev->hba.elmmio_space);
sprintf(lba_dev->hba.elmmio_name, "PCI%02x ELMMIO",
(int) lba_dev->hba.bus_num.start);
- r->name = &lba_dev->hba.elmmio_name[0];
+ r->name = lba_dev->hba.elmmio_name;
#if 1
/* See comment which precedes call to sba_directed_lmmio() */
@@ -1349,7 +1365,7 @@ lba_legacy_resources(struct parisc_devic
r = &(lba_dev->hba.io_space);
sprintf(lba_dev->hba.io_name, "PCI%02x Ports",
(int) lba_dev->hba.bus_num.start);
- r->name = &lba_dev->hba.io_name[0];
+ r->name = lba_dev->hba.io_name;
r->flags = IORESOURCE_IO;
r->start = READ_REG32(pa_dev->hpa + LBA_IOS_BASE) & ~1L;
r->end = r->start + (READ_REG32(pa_dev->hpa + LBA_IOS_MASK) ^ (HBA_PORT_SPACE_SIZE - 1));
Index: drivers/parisc/superio.c
===================================================================
RCS file: /var/cvs/linux-2.6/drivers/parisc/superio.c,v
retrieving revision 1.10
diff -u -p -r1.10 superio.c
--- drivers/parisc/superio.c 13 Sep 2004 15:23:20 -0000 1.10
+++ drivers/parisc/superio.c 28 Sep 2004 05:20:38 -0000
@@ -69,15 +69,12 @@
#include <linux/tty.h>
#include <linux/serial_core.h>
#include <linux/delay.h>
-#include <linux/ide.h>
#include <asm/io.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/superio.h>
-#define SUPERIO_IDE_MAX_RETRIES 25
-
static struct superio_device sio_dev;
@@ -101,16 +98,20 @@ superio_interrupt(int irq, void *devp, s
results = inb(IC_PIC1+0);
+ /*
+ * Bit 7: 1 = active Interrupt; 0 = no Interrupt pending
+ * Bits 6-3: zero
+ * Bits 2-0: highest priority, active requesting interrupt ID (0-7)
+ */
if ((results & 0x80) == 0) {
-#ifndef CONFIG_SMP
- /* HACK: need to investigate why this happens if SMP enabled */
- BUG(); /* This shouldn't happen */
-#endif
+ /* I suspect "spurious" interrupts are from unmasking an IRQ.
+ * We don't know if an interrupt was/is pending and thus
+ * just call the handler for that IRQ as if it were pending.
+ */
return IRQ_HANDLED;
}
/* Check to see which device is interrupting */
-
local_irq = results & 0x0f;
if (local_irq == 2 || local_irq > 7) {
@@ -136,8 +137,9 @@ superio_interrupt(int irq, void *devp, s
sio->irq_region->data.irqbase + local_irq,
regs);
- /* set EOI */
-
+ /* set EOI - forces a new interrupt if a lower priority device
+ * still needs service.
+ */
outb((OCW2_SEOI|local_irq),IC_PIC1 + 0);
return IRQ_HANDLED;
}
@@ -469,11 +471,6 @@ superio_parport_init(void)
}
-static u8 superio_ide_inb (unsigned long port);
-static unsigned long superio_ide_status[2];
-static unsigned long superio_ide_select[2];
-static unsigned long superio_ide_dma_status[2];
-
void superio_fixup_pci(struct pci_dev *pdev)
{
u8 prog;
@@ -486,56 +483,6 @@ void superio_fixup_pci(struct pci_dev *p
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415, superio_fixup_pci);
-/* Because of a defect in Super I/O, all reads of the PCI DMA status
- * registers, IDE status register and the IDE select register need to be
- * retried
- */
-static u8 superio_ide_inb (unsigned long port)
-{
- if (port == superio_ide_status[0] ||
- port == superio_ide_status[1] ||
- port == superio_ide_select[0] ||
- port == superio_ide_select[1] ||
- port == superio_ide_dma_status[0] ||
- port == superio_ide_dma_status[1]) {
- u8 tmp;
- int retries = SUPERIO_IDE_MAX_RETRIES;
-
- /* printk(" [ reading port 0x%x with retry ] ", port); */
-
- do {
- tmp = inb(port);
- if (tmp == 0)
- udelay(50);
- } while (tmp == 0 && retries-- > 0);
-
- return tmp;
- }
-
- return inb(port);
-}
-
-void __init superio_ide_init_iops (struct hwif_s *hwif)
-{
- u32 base, dmabase;
- u8 tmp;
- struct pci_dev *pdev = hwif->pci_dev;
- u8 port = hwif->channel;
-
- base = pci_resource_start(pdev, port * 2) & ~3;
- dmabase = pci_resource_start(pdev, 4) & ~3;
-
- superio_ide_status[port] = base + IDE_STATUS_OFFSET;
- superio_ide_select[port] = base + IDE_SELECT_OFFSET;
- superio_ide_dma_status[port] = dmabase + (!port ? 2 : 0xa);
-
- /* Clear error/interrupt, enable dma */
- tmp = superio_ide_inb(superio_ide_dma_status[port]);
- outb(tmp | 0x66, superio_ide_dma_status[port]);
-
- /* We need to override inb to workaround a SuperIO errata */
- hwif->INB = superio_ide_inb;
-}
static int __devinit superio_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
Index: include/asm-parisc/superio.h
===================================================================
RCS file: /var/cvs/linux-2.6/include/asm-parisc/superio.h,v
retrieving revision 1.4
diff -u -p -r1.4 superio.h
--- include/asm-parisc/superio.h 11 Mar 2004 05:41:54 -0000 1.4
+++ include/asm-parisc/superio.h 28 Sep 2004 05:20:41 -0000
@@ -87,6 +87,5 @@ extern void superio_inform_irq(int irq);
extern void superio_serial_init(void); /* called by rs_init() */
extern int superio_fixup_irq(struct pci_dev *pcidev); /* called by iosapic */
extern void superio_fixup_pci(struct pci_dev *pdev);
-extern void superio_ide_init_iops (struct hwif_s *hwif);
#endif /* _PARISC_SUPERIO_H */
More information about the parisc-linux-cvs
mailing list