* [parisc-linux] A fix for B2k and CONFIG_PDC_CONSOLE pb
2004-01-24 21:03 ` Grant Grundler
@ 2004-01-26 17:00 ` Joel Soete
2004-01-26 17:25 ` Matthew Wilcox
0 siblings, 1 reply; 12+ messages in thread
From: Joel Soete @ 2004-01-26 17:00 UTC (permalink / raw)
To: Grant Grundler, Christoph Plattner; +Cc: parisc-linux
[-- Attachment #1: Type: text/plain, Size: 2661 bytes --]
Hi Grant, Christoph,
I find a fix for this pb. I tested successfully (I reach to login with a
ttyB0 after replacing ttyS0 in inittab and telinit q :) ) on a 32bit 2.4
kernel on my b2k and a 64bit (up) [also 2.4] kernel on my N4k.
Here is its main part:
diff -NaurX dontdiff linux-2.4.24-pa0.orig/arch/parisc/kernel/firmware.c
linux-2.4.24-pa0/arch/parisc/kernel/firmware.c
--- linux-2.4.24-pa0.orig/arch/parisc/kernel/firmware.c 2003-10-02 07:30:55.000000000
+0200
+++ linux-2.4.24-pa0/arch/parisc/kernel/firmware.c 2004-01-26 16:48:23.000000000
+0100
@@ -871,15 +937,21 @@
int status;
/* Bail if no console input device. */
- if (!PAGE0->mem_kbd.iodc_io)
+ if ((PAGE0->mem_cons.cl_class != CL_DUPLEX) && !PAGE0->mem_kbd.iodc_io)
return 0;
/* wait for a keyboard (rs232)-input */
spin_lock_irqsave(&pdc_lock, flags);
- real32_call(PAGE0->mem_kbd.iodc_io,
- (unsigned long)PAGE0->mem_kbd.hpa, ENTRY_IO_CIN,
- PAGE0->mem_kbd.spa, __pa(PAGE0->mem_kbd.dp.layers),
- __pa(iodc_retbuf), 0, __pa(iodc_dbuf), 1, 0);
+ if (PAGE0->mem_cons.cl_class == CL_DUPLEX)
+ real32_call(PAGE0->mem_cons.iodc_io,
+ (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_CIN,
+ PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
+ __pa(iodc_retbuf), 0, __pa(iodc_dbuf), 1, 0);
+ else
+ real32_call(PAGE0->mem_kbd.iodc_io,
+ (unsigned long)PAGE0->mem_kbd.hpa, ENTRY_IO_CIN,
+ PAGE0->mem_kbd.spa, __pa(PAGE0->mem_kbd.dp.layers),
+ __pa(iodc_retbuf), 0, __pa(iodc_dbuf), 1, 0);
ch = *iodc_dbuf;
status = *iodc_retbuf;
diff -NaurX dontdiff linux-2.4.24-pa0.orig/arch/parisc/kernel/pdc_cons.c
linux-2.4.24-pa0/arch/parisc/kernel/pdc_cons.c
--- linux-2.4.24-pa0.orig/arch/parisc/kernel/pdc_cons.c 2004-01-19 07:25:46.000000000
+0100
+++ linux-2.4.24-pa0/arch/parisc/kernel/pdc_cons.c 2004-01-26 16:53:32.000000000
+0100
@@ -113,10 +112,6 @@
return;
++pdc_console_initialized;
- /* If the console is duplex then copy the COUT parameters to CIN. */
- if (PAGE0->mem_cons.cl_class == CL_DUPLEX)
- memcpy(&PAGE0->mem_kbd, &PAGE0->mem_cons, sizeof(PAGE0->mem_cons));
-
/* register the pdc console */
register_console(&pdc_cons);
}
==========><==========
Can somebody else could also test it on some other platform to be sure I
don't broken other stuff?
Thanks in advance,
Joel
PS: Grant I join the text file of the final backport of 2.6 work included
this patch. Thanks in advance for your attention
-------------------------------------------------------------------------
Tiscali ADSL: 12 mois à 29,50 /mois! L'Internet rapide, c'est pour tout
le monde.
http://reg.tiscali.be/default.asp?lg=fr
[-- Attachment #2: pdc_console-bp+patch.diff --]
[-- Type: application/octet-stream, Size: 23324 bytes --]
diff -NaurX dontdiff linux-2.4.24-pa0.orig/arch/parisc/kernel/entry.S linux-2.4.24-pa0/arch/parisc/kernel/entry.S
--- linux-2.4.24-pa0.orig/arch/parisc/kernel/entry.S 2003-12-05 07:42:32.000000000 +0100
+++ linux-2.4.24-pa0/arch/parisc/kernel/entry.S 2004-01-22 13:22:04.000000000 +0100
@@ -2227,9 +2227,12 @@
STREG %r28,TASK_PT_GR28-TASK_SZ_ALGN-FRAME_SIZE(%r30)
+#ifdef CONFIG_HPUX
+
/* Save other hpux returns if personality is PER_HPUX */
-#define PER_HPUX 0xe /* <linux/personality.h> cannot be easily included */
+/* <linux/personality.h> cannot be easily included */
+#define PER_HPUX 0xe
LDREG TASK_PERSONALITY-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r19
CMPIB<>,n PER_HPUX,%r19,1f
@@ -2237,6 +2240,8 @@
STREG %r29,TASK_PT_GR29-TASK_SZ_ALGN-FRAME_SIZE(%r30)
1:
+#endif /* CONFIG_HPUX */
+
/* Seems to me that dp could be wrong here, if the syscall involved
* calling a module, and nothing got round to restoring dp on return.
*/
diff -NaurX dontdiff linux-2.4.24-pa0.orig/arch/parisc/kernel/firmware.c linux-2.4.24-pa0/arch/parisc/kernel/firmware.c
--- linux-2.4.24-pa0.orig/arch/parisc/kernel/firmware.c 2003-10-02 07:30:55.000000000 +0200
+++ linux-2.4.24-pa0/arch/parisc/kernel/firmware.c 2004-01-26 16:48:23.000000000 +0100
@@ -1,10 +1,22 @@
-/* arch/parisc/kernel/firmware.c - safe pdc access routines
+/*
+ * arch/parisc/kernel/firmware.c - safe PDC access routines
+ *
+ * PDC == Processor Dependent Code
+ *
+ * See http://www.parisc-linux.org/documentation/index.html
+ * for documentation describing the entry points and calling
+ * conventions defined below.
*
* Copyright 1999 SuSE GmbH Nuernberg (Philipp Rumpf, prumpf@tux.org)
- * portions Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy)
+ * Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy)
+ * Copyright 2003 Grant Grundler <grundler parisc-linux org>
*
- * only these routines should be used out of the real kernel (i.e. everything
- * using virtual addresses) for obvious reasons */
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
/* I think it would be in everyone's best interest to follow this
* guidelines when writing PDC wrappers:
@@ -41,19 +53,19 @@
* prumpf 991016
*/
+#include <stdarg.h>
+
+#include <linux/delay.h>
+#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/delay.h>
#include <asm/page.h>
#include <asm/pdc.h>
#include <asm/system.h>
#include <asm/processor.h> /* for boot_cpu_data */
-#include <stdarg.h>
-
static spinlock_t pdc_lock = SPIN_LOCK_UNLOCKED;
static unsigned long pdc_result[32] __attribute__ ((aligned (8)));
static unsigned long pdc_result2[32] __attribute__ ((aligned (8)));
@@ -70,9 +82,9 @@
*/
#ifdef __LP64__
-static long real64_call(unsigned long function, ...);
+long real64_call(unsigned long function, ...);
#endif
-static long real32_call(unsigned long function, ...);
+long real32_call(unsigned long function, ...);
#if defined(__LP64__) && ! defined(CONFIG_PDC_NARROW)
#define MEM_PDC (unsigned long)(PAGE0->mem_pdc_hi) << 32 | PAGE0->mem_pdc
@@ -143,13 +155,13 @@
*/
int pdc_add_valid(unsigned long address)
{
- int retval;
+ int retval;
- spin_lock_irq(&pdc_lock);
- retval = mem_pdc_call(PDC_ADD_VALID, PDC_ADD_VALID_VERIFY, address);
- spin_unlock_irq(&pdc_lock);
+ spin_lock_irq(&pdc_lock);
+ retval = mem_pdc_call(PDC_ADD_VALID, PDC_ADD_VALID_VERIFY, address);
+ spin_unlock_irq(&pdc_lock);
- return retval;
+ return retval;
}
/**
@@ -162,18 +174,18 @@
*/
int __init pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len)
{
- int retval;
+ int retval;
- spin_lock_irq(&pdc_lock);
- memcpy(&pdc_result, chassis_info, sizeof(*chassis_info));
- memcpy(&pdc_result2, led_info, len);
- retval = mem_pdc_call(PDC_CHASSIS, PDC_RETURN_CHASSIS_INFO,
- __pa(pdc_result), __pa(pdc_result2), len);
- memcpy(chassis_info, pdc_result, sizeof(*chassis_info));
- memcpy(led_info, pdc_result2, len);
- spin_unlock_irq(&pdc_lock);
+ spin_lock_irq(&pdc_lock);
+ memcpy(&pdc_result, chassis_info, sizeof(*chassis_info));
+ memcpy(&pdc_result2, led_info, len);
+ retval = mem_pdc_call(PDC_CHASSIS, PDC_RETURN_CHASSIS_INFO,
+ __pa(pdc_result), __pa(pdc_result2), len);
+ memcpy(chassis_info, pdc_result, sizeof(*chassis_info));
+ memcpy(led_info, pdc_result2, len);
+ spin_unlock_irq(&pdc_lock);
- return retval;
+ return retval;
}
/**
@@ -187,9 +199,9 @@
{
if (!is_pdc_pat())
return -1;
-
+
int retval = 0;
-
+
spin_lock_irq(&pdc_lock);
retval = mem_pdc_call(PDC_PAT_CHASSIS_LOG, PDC_PAT_CHASSIS_WRITE_LOG, __pa(&state), __pa(&data));
spin_unlock_irq(&pdc_lock);
@@ -224,18 +236,18 @@
*/
int __init pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info)
{
- int retval;
+ int retval;
- spin_lock_irq(&pdc_lock);
- retval = mem_pdc_call(PDC_COPROC, PDC_COPROC_CFG, __pa(pdc_result));
- convert_to_wide(pdc_result);
- pdc_coproc_info->ccr_functional = pdc_result[0];
- pdc_coproc_info->ccr_present = pdc_result[1];
- pdc_coproc_info->revision = pdc_result[17];
- pdc_coproc_info->model = pdc_result[18];
- spin_unlock_irq(&pdc_lock);
+ spin_lock_irq(&pdc_lock);
+ retval = mem_pdc_call(PDC_COPROC, PDC_COPROC_CFG, __pa(pdc_result));
+ convert_to_wide(pdc_result);
+ pdc_coproc_info->ccr_functional = pdc_result[0];
+ pdc_coproc_info->ccr_present = pdc_result[1];
+ pdc_coproc_info->revision = pdc_result[17];
+ pdc_coproc_info->model = pdc_result[18];
+ spin_unlock_irq(&pdc_lock);
- return retval;
+ return retval;
}
/**
@@ -537,8 +549,8 @@
* o cable too long (ie SE scsi 10Mhz won't support 6m length),
* o bus width exported is less than what the interface chip supports.
*/
-int pdc_get_initiator( struct hardware_path *hwpath, unsigned char *scsi_id,
- unsigned long *period, char *width, char *mode)
+int pdc_get_initiator(struct hardware_path *hwpath, unsigned char *scsi_id,
+ unsigned long *period, char *width, char *mode)
{
int retval;
@@ -556,41 +568,38 @@
/* convert Bus speed in Mhz to period (in 1/10 ns) */
switch(pdc_result[1]) {
- /*
- ** case 0: driver determines rate
- ** case -1: Settings are uninitialized.
- */
- case 5: *period = 2000; break;
- case 10: *period = 1000; break;
- case 20: *period = 500; break;
- case 40: *period = 250; break;
- default: /* Do nothing */ break;
+ /*
+ * case 0: driver determines rate
+ * case -1: Settings are uninitialized.
+ */
+ case 5: *period = 2000; break;
+ case 10: *period = 1000; break;
+ case 20: *period = 500; break;
+ case 40: *period = 250; break;
+ default: /* Do nothing */ break;
}
/*
- ** pdc_result[2] PDC suggested SCSI id
- ** pdc_result[3] PDC suggested SCSI rate
- */
+ * pdc_result[2] PDC suggested SCSI id
+ * pdc_result[3] PDC suggested SCSI rate
+ */
/* C3000 and similar workstations report period/mode */
if (IS_SPROCKETS()) {
- /*
- ** 0 == 8-bit
- ** 1 == 16-bit
- */
+ /* 0 == 8-bit, 1 == 16-bit */
*width = (char) pdc_result[4];
/* ...in case someone needs it in the future.
- ** sym53c8xx.c comments say it can't autodetect
- ** for 825/825A/875 chips.
- ** 0 == SE, 1 == HVD, 2 == LVD
- */
+ * sym53c8xx.c comments say it can't autodetect
+ * for 825/825A/875 chips.
+ * 0 == SE, 1 == HVD, 2 == LVD
+ */
*mode = (char) pdc_result[5];
}
}
spin_unlock_irq(&pdc_lock);
- return retval >= PDC_OK;
+ return (retval >= PDC_OK);
}
@@ -640,6 +649,49 @@
}
+#if 0 /* UNTEST CODE - left here in case someone needs it */
+
+/*
+ * pdc_pci_config_read - read PCI config space.
+ * @hpa token from PDC to indicate which PCI device
+ * @pci_addr configuration space address to read from
+ *
+ * Read PCI Configuration space *before* linux PCI subsystem is running.
+ */
+unsigned int pdc_pci_config_read(void *hpa, unsigned long cfg_addr)
+{
+ int retval;
+ spin_lock_irq(&pdc_lock);
+ pdc_result[0] = 0;
+ pdc_result[1] = 0;
+ retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_READ_CONFIG,
+ __pa(pdc_result), hpa, cfg_addr&~3UL, 4UL);
+ spin_unlock_irq(&pdc_lock);
+ return retval ? ~0 : (unsigned int) pdc_result[0];
+}
+
+
+/*
+ * pdc_pci_config_write - read PCI config space.
+ * @hpa token from PDC to indicate which PCI device
+ * @pci_addr configuration space address to write
+ * @val value we want in the 32-bit register
+ *
+ * Write PCI Configuration space *before* linux PCI subsystem is running.
+ */
+void pdc_pci_config_write(void *hpa, unsigned long cfg_addr, unsigned int val)
+{
+ int retval;
+ spin_lock_irq(&pdc_lock);
+ pdc_result[0] = 0;
+ retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_WRITE_CONFIG,
+ __pa(pdc_result), hpa,
+ cfg_addr&~3UL, 4UL, (unsigned long) val);
+ spin_unlock_irq(&pdc_lock);
+ return retval;
+}
+#endif /* UNTESTED CODE */
+
/**
* pdc_tod_read - Read the Time-Of-Day clock.
* @tod: The return buffer:
@@ -770,20 +822,34 @@
}
/*
- * pdc_suspend_usb - Stop USB controller
+ * pdc_io_reset - Hack to avoid overlapping range registers of Bridges devices.
+ * Primarily a problem on T600 (which parisc-linux doesn't support) but
+ * who knows what other platform firmware might do with this OS "hook".
+ */
+void pdc_io_reset(void)
+{
+ spin_lock_irq(&pdc_lock);
+ mem_pdc_call(PDC_IO, PDC_IO_RESET, 0);
+ spin_unlock_irq(&pdc_lock);
+}
+
+/*
+ * pdc_io_reset_devices - Hack to Stop USB controller
*
* If PDC used the usb controller, the usb controller
* is still running and will crash the machines during iommu
* setup, because of still running DMA. This PDC call
- * stops the USB controller
+ * stops the USB controller.
+ * Normally called after calling pdc_io_reset().
*/
-void pdc_suspend_usb(void)
+void pdc_io_reset_devices(void)
{
spin_lock_irq(&pdc_lock);
- mem_pdc_call(PDC_IO, PDC_IO_SUSPEND_USB, 0);
+ mem_pdc_call(PDC_IO, PDC_IO_RESET_DEVICES, 0);
spin_unlock_irq(&pdc_lock);
}
+
/**
* pdc_iodc_putc - Console character print using IODC.
* @c: the character to output.
@@ -871,15 +937,21 @@
int status;
/* Bail if no console input device. */
- if (!PAGE0->mem_kbd.iodc_io)
+ if ((PAGE0->mem_cons.cl_class != CL_DUPLEX) && !PAGE0->mem_kbd.iodc_io)
return 0;
/* wait for a keyboard (rs232)-input */
spin_lock_irqsave(&pdc_lock, flags);
- real32_call(PAGE0->mem_kbd.iodc_io,
- (unsigned long)PAGE0->mem_kbd.hpa, ENTRY_IO_CIN,
- PAGE0->mem_kbd.spa, __pa(PAGE0->mem_kbd.dp.layers),
- __pa(iodc_retbuf), 0, __pa(iodc_dbuf), 1, 0);
+ if (PAGE0->mem_cons.cl_class == CL_DUPLEX)
+ real32_call(PAGE0->mem_cons.iodc_io,
+ (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_CIN,
+ PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
+ __pa(iodc_retbuf), 0, __pa(iodc_dbuf), 1, 0);
+ else
+ real32_call(PAGE0->mem_kbd.iodc_io,
+ (unsigned long)PAGE0->mem_kbd.hpa, ENTRY_IO_CIN,
+ PAGE0->mem_kbd.spa, __pa(PAGE0->mem_kbd.dp.layers),
+ __pa(iodc_retbuf), 0, __pa(iodc_dbuf), 1, 0);
ch = *iodc_dbuf;
status = *iodc_retbuf;
@@ -1065,7 +1137,7 @@
/* in reality, there's nearly 8k of stack after this */
};
-static long real32_call(unsigned long fn, ...)
+long real32_call(unsigned long fn, ...)
{
va_list args;
extern struct narrow_stack real_stack32;
@@ -1116,7 +1188,7 @@
/* in reality, there's nearly 8k of stack after this */
};
-static long real64_call(unsigned long fn, ...)
+long real64_call(unsigned long fn, ...)
{
va_list args;
extern struct wide_stack real_stack64;
diff -NaurX dontdiff linux-2.4.24-pa0.orig/arch/parisc/kernel/inventory.c linux-2.4.24-pa0/arch/parisc/kernel/inventory.c
--- linux-2.4.24-pa0.orig/arch/parisc/kernel/inventory.c 2003-08-04 08:00:00.000000000 +0200
+++ linux-2.4.24-pa0/arch/parisc/kernel/inventory.c 2004-01-26 16:36:05.000000000 +0100
@@ -167,9 +167,6 @@
static int __init
pat_query_module(ulong pcell_loc, ulong mod_index)
{
-#ifdef DEBUG_PAT
- pdc_pat_cell_mod_maddr_block_t io_pdc_cell;
-#endif
pdc_pat_cell_mod_maddr_block_t pa_pdc_cell;
unsigned long bytecnt;
unsigned long temp; /* 64-bit scratch value */
@@ -209,6 +206,7 @@
register_parisc_device(dev); /* advertise device */
#ifdef DEBUG_PAT
+ pdc_pat_cell_mod_maddr_block_t io_pdc_cell;
/* dump what we see so far... */
switch (PAT_GET_ENTITY(dev->mod_info)) {
unsigned long i;
@@ -527,12 +525,6 @@
int i;
long status = PDC_OK;
- /*
- * first stop the usb controller, otherwise the machine
- * might crash during iommu setup
- */
- pdc_suspend_usb();
-
for (i = 0; status != PDC_BAD_PROC && status != PDC_NE_MOD; i++) {
struct parisc_device *dev;
struct pdc_system_map_mod_info module_result;
diff -NaurX dontdiff linux-2.4.24-pa0.orig/arch/parisc/kernel/pdc_cons.c linux-2.4.24-pa0/arch/parisc/kernel/pdc_cons.c
--- linux-2.4.24-pa0.orig/arch/parisc/kernel/pdc_cons.c 2004-01-19 07:25:46.000000000 +0100
+++ linux-2.4.24-pa0/arch/parisc/kernel/pdc_cons.c 2004-01-26 16:53:32.000000000 +0100
@@ -43,7 +43,6 @@
* On production kernels EARLY_BOOTUP_DEBUG should be undefined. */
#undef EARLY_BOOTUP_DEBUG
-
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/console.h>
@@ -82,7 +81,7 @@
#if defined(CONFIG_PDC_CONSOLE) || defined(CONFIG_SERIAL_MUX)
#define PDC_CONSOLE_DEVICE pdc_console_device
-static kdev_t pdc_console_device (struct console *c)
+static kdev_t pdc_console_device(struct console *c)
{
return MKDEV(MUX_MAJOR, 0);
}
@@ -91,18 +90,18 @@
#endif
static struct console pdc_cons = {
- name: "ttyB",
- write: pdc_console_write,
+ .name = "ttyB",
+ .write = pdc_console_write,
#warning UPSTREAM 2.4.19 removed the next 4 lines but we did not
- read: NULL,
- device: PDC_CONSOLE_DEVICE,
- unblank: NULL,
- setup: pdc_console_setup,
- flags: CON_BOOT|CON_PRINTBUFFER|CON_ENABLED,
- index: -1,
+ .read = NULL,
+ .device = PDC_CONSOLE_DEVICE,
+ .unblank = NULL,
+ .setup = pdc_console_setup,
+ .flags = CON_BOOT|CON_PRINTBUFFER|CON_ENABLED,
+ .index = -1,
};
-static int pdc_console_initialized;
+static int pdc_console_initialized = 0;
extern unsigned long con_start; /* kernel/printk.c */
extern unsigned long log_end; /* kernel/printk.c */
@@ -113,10 +112,6 @@
return;
++pdc_console_initialized;
- /* If the console is duplex then copy the COUT parameters to CIN. */
- if (PAGE0->mem_cons.cl_class == CL_DUPLEX)
- memcpy(&PAGE0->mem_kbd, &PAGE0->mem_cons, sizeof(PAGE0->mem_cons));
-
/* register the pdc console */
register_console(&pdc_cons);
}
@@ -164,7 +159,7 @@
return;
while ((console = console_drivers) != NULL)
- unregister_console(console_drivers);
+ unregister_console(console);
/* Don't repeat what we've already printed */
con_start = log_end;
diff -NaurX dontdiff linux-2.4.24-pa0.orig/arch/parisc/kernel/real2.S linux-2.4.24-pa0/arch/parisc/kernel/real2.S
--- linux-2.4.24-pa0.orig/arch/parisc/kernel/real2.S 2003-09-22 09:06:22.000000000 +0200
+++ linux-2.4.24-pa0/arch/parisc/kernel/real2.S 2004-01-22 16:52:43.000000000 +0100
@@ -13,7 +13,7 @@
.section .bss
.export real_stack32
#ifdef __LP64__
- .export real_stack64
+ .export real_stack64
#endif
.align 64
real_stack32:
diff -NaurX dontdiff linux-2.4.24-pa0.orig/arch/parisc/kernel/sba_iommu.c linux-2.4.24-pa0/arch/parisc/kernel/sba_iommu.c
--- linux-2.4.24-pa0.orig/arch/parisc/kernel/sba_iommu.c 2002-12-03 08:07:12.000000000 +0100
+++ linux-2.4.24-pa0/arch/parisc/kernel/sba_iommu.c 2004-01-26 16:24:03.000000000 +0100
@@ -579,7 +579,8 @@
if (pide >= (ioc->res_size << 3)) {
pide = sba_search_bitmap(ioc, pages_needed);
if (pide >= (ioc->res_size << 3))
- panic(__FILE__ ": I/O MMU @ %lx is out of mapping resources\n", ioc->ioc_hpa);
+ panic("%s: I/O MMU @ %lx is out of mapping resources\n",
+ __FILE__, ioc->ioc_hpa);
}
#ifdef ASSERT_PDIR_SANITY
@@ -904,8 +905,8 @@
*
* See Documentation/DMA-mapping.txt
*/
-static void
-sba_unmap_single(struct pci_dev *dev, dma_addr_t iova, size_t size, int direction)
+static void sba_unmap_single(struct pci_dev *dev, dma_addr_t iova, size_t size,
+ int direction)
{
struct ioc *ioc;
#if DELAYED_RESOURCE_CNT > 0
@@ -974,8 +975,8 @@
*
* See Documentation/DMA-mapping.txt
*/
-static void *
-sba_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)
+static void *sba_alloc_consistent(struct pci_dev *hwdev, size_t size,
+ dma_addr_t *dma_handle)
{
void *ret;
@@ -1006,7 +1007,8 @@
* See Documentation/DMA-mapping.txt
*/
static void
-sba_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
+sba_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr,
+ dma_addr_t dma_handle)
{
sba_unmap_single(hwdev, dma_handle, size, 0);
free_pages((unsigned long) vaddr, get_order(size));
@@ -1113,7 +1115,7 @@
/*
** Two address ranges are DMA contiguous *iff* "end of prev" and
-** "start of next" are both on a page boundry.
+** "start of next" are both on a page boundary.
**
** (shift left is a quick trick to mask off upper bits)
*/
@@ -1131,7 +1133,7 @@
* in the DMA stream. Allocates PDIR entries but does not fill them.
* Returns the number of DMA chunks.
*
- * Doing the fill seperate from the coalescing/allocation keeps the
+ * Doing the fill separate from the coalescing/allocation keeps the
* code simpler. Future enhancement could make one pass through
* the sglist do both.
*/
@@ -1218,7 +1220,7 @@
** can't change. And we need the offset from the first
** chunk - not the last one. Ergo Successive chunks
** must start on page boundaries and dove tail
- ** with it's predecessor.
+ ** with its predecessor.
*/
sg_dma_len(vcontig_sg) = vcontig_len;
@@ -1268,7 +1270,8 @@
* See Documentation/DMA-mapping.txt
*/
static int
-sba_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
+sba_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents,
+ int direction)
{
struct ioc *ioc;
int coalesced, filled = 0;
@@ -1350,7 +1353,8 @@
* See Documentation/DMA-mapping.txt
*/
static void
-sba_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
+sba_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents,
+ int direction)
{
struct ioc *ioc;
#ifdef ASSERT_PDIR_SANITY
@@ -1395,15 +1399,15 @@
}
static struct pci_dma_ops sba_ops = {
- sba_dma_supported,
- sba_alloc_consistent, /* allocate cacheable host mem */
- sba_free_consistent, /* release cacheable host mem */
- sba_map_single,
- sba_unmap_single,
- sba_map_sg,
- sba_unmap_sg,
- NULL, /* dma_sync_single */
- NULL /* dma_sync_sg */
+ .dma_supported = sba_dma_supported,
+ .alloc_consistent = sba_alloc_consistent, /* allocate cacheable host mem */
+ .free_consistent = sba_free_consistent, /* release cacheable host mem */
+ .map_single = sba_map_single,
+ .unmap_single = sba_unmap_single,
+ .map_sg = sba_map_sg,
+ .unmap_sg = sba_unmap_sg,
+ .dma_sync_single = NULL,
+ .dma_sync_sg = NULL,
};
@@ -1678,6 +1682,22 @@
int num_ioc;
u64 ioc_ctl;
+ if (!is_pdc_pat()) {
+ /*
+ * Shutdown the USB controller on Astro-based workstations.
+ * Once we reprogram the IOMMU, the next DMA performed by
+ * USB will HPMC the box.
+ */
+ pdc_io_reset_devices();
+
+ /*
+ * XXX May need something more sophisticated to deal
+ * with DMA from LAN. Maybe use page zero boot device
+ * as a handle to talk to PDC about which device to
+ * shutdown. This also needs to work for is_pdc_pat().
+ */
+ }
+
ioc_ctl = READ_REG(sba_dev->sba_hpa+IOC_CTRL);
DBG_INIT("%s() hpa 0x%lx ioc_ctl 0x%Lx ->",
__FUNCTION__, sba_dev->sba_hpa, ioc_ctl);
@@ -1728,9 +1748,10 @@
{
int i;
- /* add this one to the head of the list (order doesn't matter)
- ** This will be useful for debugging - especially if we get coredumps
- */
+ /*
+ * add this one to the head of the list (order doesn't matter)
+ * This will be useful for debugging - especially if we get coredumps
+ */
sba_dev->next = sba_list;
sba_list = sba_dev;
@@ -1764,7 +1785,8 @@
if (NULL == sba_dev->ioc[i].res_map)
{
- panic(__FILE__ ":%s() could not allocate resource map\n", __FUNCTION__ );
+ panic("%s:%s() could not allocate resource map\n",
+ __FILE__, __FUNCTION__);
}
memset(sba_dev->ioc[i].res_map, 0, res_size);
@@ -1918,9 +1940,9 @@
int sba_driver_callback(struct parisc_device *);
static struct parisc_driver sba_driver = {
- name: MODULE_NAME,
- id_table: sba_tbl,
- probe: sba_driver_callback,
+ .name = MODULE_NAME,
+ .id_table = sba_tbl,
+ .probe = sba_driver_callback,
};
/*
diff -NaurX dontdiff linux-2.4.24-pa0.orig/include/asm-parisc/pdc.h linux-2.4.24-pa0/include/asm-parisc/pdc.h
--- linux-2.4.24-pa0.orig/include/asm-parisc/pdc.h 2002-10-04 07:48:47.000000000 +0200
+++ linux-2.4.24-pa0/include/asm-parisc/pdc.h 2004-01-26 12:51:25.000000000 +0100
@@ -191,8 +191,8 @@
#define PDC_IO 135 /* log error info, reset IO system */
#define PDC_IO_READ_AND_CLEAR_ERRORS 0
-#define PDC_IO_READ_AND_LOG_ERRORS 1
-#define PDC_IO_SUSPEND_USB 2
+#define PDC_IO_RESET 1
+#define PDC_IO_RESET_DEVICES 2
/* sets bits 6&7 (little endian) of the HcControl Register */
#define PDC_IO_USB_SUSPEND 0xC000000000000000
#define PDC_IO_EEPROM_IO_ERR_TABLE_FULL -5 /* return value */
@@ -476,7 +476,11 @@
#define PDC_TYPE_SYSTEM_MAP 1 /* 32-bit, but supports PDC_SYSTEM_MAP */
#define PDC_TYPE_SNAKE 2 /* Doesn't support SYSTEM_MAP */
-#define is_pdc_pat() (pdc_type == PDC_TYPE_PAT)
+#ifdef CONFIG_PARISC64
+#define is_pdc_pat() (PDC_TYPE_PAT == pdc_type)
+#else
+#define is_pdc_pat() (0)
+#endif
struct pdc_chassis_info { /* for PDC_CHASSIS_INFO */
unsigned long actcnt; /* actual number of bytes returned */
@@ -897,7 +901,7 @@
__u32 pad608[126];
};
-#endif /* __ASSEMBLY__ */
+#endif /* !__ASSEMBLY__ */
/* Page Zero constant offsets used by the HPMC handler */
@@ -951,7 +955,8 @@
int pdc_do_reset(void);
int pdc_soft_power_info(unsigned long *power_reg);
int pdc_soft_power_button(int sw_control);
-void pdc_suspend_usb(void);
+void pdc_io_reset(void);
+void pdc_io_reset_devices(void);
int pdc_iodc_getc(void);
void pdc_iodc_putc(unsigned char c);
void pdc_iodc_outc(unsigned char c);
@@ -963,7 +968,6 @@
#ifdef __LP64__
int pdc_pat_chassis_send_log(unsigned long status, unsigned long data);
-
int pdc_pat_cell_get_number(struct pdc_pat_cell_num *cell_info);
int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long mod,
unsigned long view_type, void *mem_addr);
@@ -1010,6 +1014,6 @@
extern void pdc_init(void);
-#endif /* __ASSEMBLY__ */
+#endif /* !__ASSEMBLY__ */
#endif /* _PARISC_PDC_H */
^ permalink raw reply [flat|nested] 12+ messages in thread