5550 lines
167 KiB
Diff
5550 lines
167 KiB
Diff
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/Makefile linux-m68k/Makefile
|
||
--- linux-i386/Makefile 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/Makefile 2006-09-24 16:30:54.000000000 +0200
|
||
@@ -173,7 +173,7 @@
|
||
# Default value for CROSS_COMPILE is not to prefix executables
|
||
# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
|
||
|
||
-ARCH ?= $(SUBARCH)
|
||
+ARCH ?= m68k
|
||
CROSS_COMPILE ?=
|
||
|
||
# Architecture as present in compile.h
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/Kconfig linux-m68k/arch/m68k/Kconfig
|
||
--- linux-i386/arch/m68k/Kconfig 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/Kconfig 2006-09-05 16:31:20.000000000 +0200
|
||
@@ -344,8 +344,9 @@
|
||
adventurous.
|
||
|
||
config SINGLE_MEMORY_CHUNK
|
||
- bool "Use one physical chunk of memory only"
|
||
- depends on ADVANCED && !SUN3
|
||
+ bool "Use one physical chunk of memory only" if ADVANCED && !SUN3
|
||
+ default y if SUN3
|
||
+ select NEED_MULTIPLE_NODES
|
||
help
|
||
Ignore all but the first contiguous chunk of physical memory for VM
|
||
purposes. This will save a few bytes kernel size and may speed up
|
||
@@ -366,6 +367,14 @@
|
||
is hardwired on. The 53c710 SCSI driver is known to suffer from
|
||
this problem.
|
||
|
||
+config ARCH_DISCONTIGMEM_ENABLE
|
||
+ def_bool !SINGLE_MEMORY_CHUNK
|
||
+
|
||
+config NODES_SHIFT
|
||
+ int
|
||
+ default "3"
|
||
+ depends on !SINGLE_MEMORY_CHUNK
|
||
+
|
||
source "mm/Kconfig"
|
||
|
||
endmenu
|
||
@@ -600,7 +609,7 @@
|
||
|
||
config SERIAL167
|
||
bool "CD2401 support for MVME166/7 serial ports"
|
||
- depends on MVME16x && BROKEN
|
||
+ depends on MVME16x
|
||
help
|
||
This is the driver for the serial ports on the Motorola MVME166,
|
||
167, and 172 boards. Everyone using one of these boards should say
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/Makefile linux-m68k/arch/m68k/Makefile
|
||
--- linux-i386/arch/m68k/Makefile 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/Makefile 2006-06-06 01:17:27.000000000 +0200
|
||
@@ -19,6 +19,7 @@
|
||
# override top level makefile
|
||
AS += -m68020
|
||
LDFLAGS := -m m68kelf
|
||
+LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds
|
||
ifneq ($(COMPILE_ARCH),$(ARCH))
|
||
# prefix for cross-compiling binaries
|
||
CROSS_COMPILE = m68k-linux-
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/atari/ataints.c linux-m68k/arch/m68k/atari/ataints.c
|
||
--- linux-i386/arch/m68k/atari/ataints.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/atari/ataints.c 2006-09-05 16:31:20.000000000 +0200
|
||
@@ -332,6 +332,9 @@
|
||
atari_disable_irq(irq);
|
||
atari_turnoff_irq(irq);
|
||
m68k_irq_shutdown(irq);
|
||
+
|
||
+ if (irq == IRQ_AUTO_4)
|
||
+ vectors[VEC_INT4] = falcon_hblhandler;
|
||
}
|
||
|
||
static struct irq_controller atari_irq_controller = {
|
||
@@ -356,7 +359,7 @@
|
||
|
||
void __init atari_init_IRQ(void)
|
||
{
|
||
- m68k_setup_user_interrupt(VEC_USER, 192, NULL);
|
||
+ m68k_setup_user_interrupt(VEC_USER, NUM_ATARI_SOURCES - IRQ_USER, NULL);
|
||
m68k_setup_irq_controller(&atari_irq_controller, 1, NUM_ATARI_SOURCES - 1);
|
||
|
||
/* Initialize the MFP(s) */
|
||
@@ -403,8 +406,10 @@
|
||
* gets overruns)
|
||
*/
|
||
|
||
- if (!MACH_IS_HADES)
|
||
+ if (!MACH_IS_HADES) {
|
||
vectors[VEC_INT2] = falcon_hblhandler;
|
||
+ vectors[VEC_INT4] = falcon_hblhandler;
|
||
+ }
|
||
}
|
||
|
||
if (ATARIHW_PRESENT(PCM_8BIT) && ATARIHW_PRESENT(MICROWIRE)) {
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/atari/time.c linux-m68k/arch/m68k/atari/time.c
|
||
--- linux-i386/arch/m68k/atari/time.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/atari/time.c 2006-09-05 16:31:20.000000000 +0200
|
||
@@ -16,6 +16,7 @@
|
||
#include <linux/init.h>
|
||
#include <linux/rtc.h>
|
||
#include <linux/bcd.h>
|
||
+#include <linux/delay.h>
|
||
|
||
#include <asm/atariints.h>
|
||
|
||
@@ -212,8 +213,12 @@
|
||
* additionally the RTC_SET bit is set to prevent an update cycle.
|
||
*/
|
||
|
||
- while( RTC_READ(RTC_FREQ_SELECT) & RTC_UIP )
|
||
- schedule_timeout_interruptible(HWCLK_POLL_INTERVAL);
|
||
+ while( RTC_READ(RTC_FREQ_SELECT) & RTC_UIP ) {
|
||
+ if (in_atomic() || irqs_disabled())
|
||
+ mdelay(1);
|
||
+ else
|
||
+ schedule_timeout_interruptible(HWCLK_POLL_INTERVAL);
|
||
+ }
|
||
|
||
local_irq_save(flags);
|
||
RTC_WRITE( RTC_CONTROL, ctrl | RTC_SET );
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/kernel/bios32.c linux-m68k/arch/m68k/kernel/bios32.c
|
||
--- linux-i386/arch/m68k/kernel/bios32.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/kernel/bios32.c 2006-09-24 16:31:35.000000000 +0200
|
||
@@ -284,7 +284,7 @@
|
||
|
||
DBG_DEVS(("layout_bus: starting bus %d\n", bus->number));
|
||
|
||
- if (!bus->devices && !bus->children)
|
||
+ if (list_empty(&bus->devices) && list_empty(&bus->children))
|
||
return;
|
||
|
||
/*
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/kernel/entry.S linux-m68k/arch/m68k/kernel/entry.S
|
||
--- linux-i386/arch/m68k/kernel/entry.S 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/kernel/entry.S 2006-09-24 16:31:35.000000000 +0200
|
||
@@ -706,4 +706,9 @@
|
||
.long sys_add_key
|
||
.long sys_request_key /* 280 */
|
||
.long sys_keyctl
|
||
+ .long sys_ioprio_set
|
||
+ .long sys_ioprio_get
|
||
+ .long sys_inotify_init
|
||
+ .long sys_inotify_add_watch /* 285 */
|
||
+ .long sys_inotify_rm_watch
|
||
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/kernel/ints.c linux-m68k/arch/m68k/kernel/ints.c
|
||
--- linux-i386/arch/m68k/kernel/ints.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/kernel/ints.c 2006-09-24 16:31:35.000000000 +0200
|
||
@@ -131,6 +131,7 @@
|
||
{
|
||
int i;
|
||
|
||
+ BUG_ON(IRQ_USER + cnt >= NR_IRQS);
|
||
m68k_first_user_vec = vec;
|
||
for (i = 0; i < cnt; i++)
|
||
irq_controller[IRQ_USER + i] = &user_irq_controller;
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/kernel/m68k_ksyms.c linux-m68k/arch/m68k/kernel/m68k_ksyms.c
|
||
--- linux-i386/arch/m68k/kernel/m68k_ksyms.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/kernel/m68k_ksyms.c 2006-09-24 16:31:36.000000000 +0200
|
||
@@ -1,7 +1,6 @@
|
||
#include <linux/module.h>
|
||
#include <linux/linkage.h>
|
||
#include <linux/sched.h>
|
||
-#include <linux/string.h>
|
||
#include <linux/mm.h>
|
||
#include <linux/user.h>
|
||
#include <linux/elfcore.h>
|
||
@@ -32,13 +31,6 @@
|
||
#ifndef CONFIG_SUN3
|
||
EXPORT_SYMBOL(cache_push);
|
||
EXPORT_SYMBOL(cache_clear);
|
||
-#ifndef CONFIG_SINGLE_MEMORY_CHUNK
|
||
-EXPORT_SYMBOL(mm_vtop);
|
||
-EXPORT_SYMBOL(mm_ptov);
|
||
-EXPORT_SYMBOL(mm_end_of_chunk);
|
||
-#else
|
||
-EXPORT_SYMBOL(m68k_memoffset);
|
||
-#endif /* !CONFIG_SINGLE_MEMORY_CHUNK */
|
||
EXPORT_SYMBOL(__ioremap);
|
||
EXPORT_SYMBOL(iounmap);
|
||
EXPORT_SYMBOL(kernel_set_cachemode);
|
||
@@ -53,9 +45,6 @@
|
||
#endif
|
||
EXPORT_SYMBOL(dump_fpu);
|
||
EXPORT_SYMBOL(dump_thread);
|
||
-EXPORT_SYMBOL(strnlen);
|
||
-EXPORT_SYMBOL(strrchr);
|
||
-EXPORT_SYMBOL(strstr);
|
||
EXPORT_SYMBOL(kernel_thread);
|
||
#ifdef CONFIG_VME
|
||
EXPORT_SYMBOL(vme_brdtype);
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/kernel/module.c linux-m68k/arch/m68k/kernel/module.c
|
||
--- linux-i386/arch/m68k/kernel/module.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/kernel/module.c 2006-09-05 16:31:20.000000000 +0200
|
||
@@ -1,3 +1,9 @@
|
||
+/*
|
||
+ * This file is subject to the terms and conditions of the GNU General Public
|
||
+ * License. See the file COPYING in the main directory of this archive
|
||
+ * for more details.
|
||
+ */
|
||
+
|
||
#include <linux/moduleloader.h>
|
||
#include <linux/elf.h>
|
||
#include <linux/vmalloc.h>
|
||
@@ -116,10 +122,29 @@
|
||
return 0;
|
||
}
|
||
|
||
+void module_fixup(struct module *mod, struct m68k_fixup_info *start,
|
||
+ struct m68k_fixup_info *end)
|
||
+{
|
||
+ struct m68k_fixup_info *fixup;
|
||
+
|
||
+ for (fixup = start; fixup < end; fixup++) {
|
||
+ switch (fixup->type) {
|
||
+ case m68k_fixup_memoffset:
|
||
+ *(u32 *)fixup->addr = m68k_memoffset;
|
||
+ break;
|
||
+ case m68k_fixup_vnode_shift:
|
||
+ *(u16 *)fixup->addr += m68k_virt_to_node_shift;
|
||
+ break;
|
||
+ }
|
||
+ }
|
||
+}
|
||
+
|
||
int module_finalize(const Elf_Ehdr *hdr,
|
||
const Elf_Shdr *sechdrs,
|
||
- struct module *me)
|
||
+ struct module *mod)
|
||
{
|
||
+ module_fixup(mod, mod->arch.fixup_start, mod->arch.fixup_end);
|
||
+
|
||
return 0;
|
||
}
|
||
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/kernel/module.lds linux-m68k/arch/m68k/kernel/module.lds
|
||
--- linux-i386/arch/m68k/kernel/module.lds 1970-01-01 01:00:00.000000000 +0100
|
||
+++ linux-m68k/arch/m68k/kernel/module.lds 2006-06-06 01:17:28.000000000 +0200
|
||
@@ -0,0 +1,7 @@
|
||
+SECTIONS {
|
||
+ .m68k_fixup : {
|
||
+ __start_fixup = .;
|
||
+ *(.m68k_fixup)
|
||
+ __stop_fixup = .;
|
||
+ }
|
||
+}
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/kernel/setup.c linux-m68k/arch/m68k/kernel/setup.c
|
||
--- linux-i386/arch/m68k/kernel/setup.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/kernel/setup.c 2006-09-24 16:31:36.000000000 +0200
|
||
@@ -58,7 +58,7 @@
|
||
unsigned long m68k_memoffset;
|
||
struct mem_info m68k_memory[NUM_MEMINFO];
|
||
|
||
-static struct mem_info m68k_ramdisk;
|
||
+struct mem_info m68k_ramdisk;
|
||
|
||
static char m68k_command_line[CL_SIZE];
|
||
|
||
@@ -196,9 +196,6 @@
|
||
void __init setup_arch(char **cmdline_p)
|
||
{
|
||
extern int _etext, _edata, _end;
|
||
-#ifndef CONFIG_SUN3
|
||
- unsigned long endmem, startmem;
|
||
-#endif
|
||
int i;
|
||
char *p, *q;
|
||
|
||
@@ -339,30 +336,16 @@
|
||
panic ("No configuration setup");
|
||
}
|
||
|
||
-#ifndef CONFIG_SUN3
|
||
- startmem= m68k_memory[0].addr;
|
||
- endmem = startmem + m68k_memory[0].size;
|
||
- high_memory = (void *)PAGE_OFFSET;
|
||
- for (i = 0; i < m68k_num_memory; i++) {
|
||
- m68k_memory[i].size &= MASK_256K;
|
||
- if (m68k_memory[i].addr < startmem)
|
||
- startmem = m68k_memory[i].addr;
|
||
- if (m68k_memory[i].addr+m68k_memory[i].size > endmem)
|
||
- endmem = m68k_memory[i].addr+m68k_memory[i].size;
|
||
- high_memory += m68k_memory[i].size;
|
||
- }
|
||
-
|
||
- availmem += init_bootmem_node(NODE_DATA(0), availmem >> PAGE_SHIFT,
|
||
- startmem >> PAGE_SHIFT, endmem >> PAGE_SHIFT);
|
||
-
|
||
- for (i = 0; i < m68k_num_memory; i++)
|
||
- free_bootmem(m68k_memory[i].addr, m68k_memory[i].size);
|
||
-
|
||
- reserve_bootmem(m68k_memory[0].addr, availmem - m68k_memory[0].addr);
|
||
+ paging_init();
|
||
|
||
+#ifndef CONFIG_SUN3
|
||
+ for (i = 1; i < m68k_num_memory; i++)
|
||
+ free_bootmem_node(NODE_DATA(i), m68k_memory[i].addr,
|
||
+ m68k_memory[i].size);
|
||
#ifdef CONFIG_BLK_DEV_INITRD
|
||
if (m68k_ramdisk.size) {
|
||
- reserve_bootmem(m68k_ramdisk.addr, m68k_ramdisk.size);
|
||
+ reserve_bootmem_node(__virt_to_node(phys_to_virt(m68k_ramdisk.addr)),
|
||
+ m68k_ramdisk.addr, m68k_ramdisk.size);
|
||
initrd_start = (unsigned long)phys_to_virt(m68k_ramdisk.addr);
|
||
initrd_end = initrd_start + m68k_ramdisk.size;
|
||
printk ("initrd: %08lx - %08lx\n", initrd_start, initrd_end);
|
||
@@ -381,8 +364,6 @@
|
||
|
||
#endif /* !CONFIG_SUN3 */
|
||
|
||
- paging_init();
|
||
-
|
||
/* set ISA defs early as possible */
|
||
#if defined(CONFIG_ISA) && defined(MULTI_ISA)
|
||
#if defined(CONFIG_Q40)
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/kernel/sun3-head.S linux-m68k/arch/m68k/kernel/sun3-head.S
|
||
--- linux-i386/arch/m68k/kernel/sun3-head.S 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/kernel/sun3-head.S 2006-05-11 13:14:10.000000000 +0200
|
||
@@ -66,17 +66,7 @@
|
||
/* Following code executes at high addresses (0xE000xxx). */
|
||
1: lea init_task,%curptr | get initial thread...
|
||
lea init_thread_union+THREAD_SIZE,%sp | ...and its stack.
|
||
-
|
||
-/* copy bootinfo records from the loader to _end */
|
||
- lea _end, %a1
|
||
- lea BI_START, %a0
|
||
- /* number of longs to copy */
|
||
- movel %a0@, %d0
|
||
-1: addl #4, %a0
|
||
- movel %a0@, %a1@
|
||
- addl #4, %a1
|
||
- dbf %d0, 1b
|
||
-
|
||
+
|
||
/* Point MSP at an invalid page to trap if it's used. --m */
|
||
movl #(PAGESIZE),%d0
|
||
movc %d0,%msp
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/kernel/vmlinux-std.lds linux-m68k/arch/m68k/kernel/vmlinux-std.lds
|
||
--- linux-i386/arch/m68k/kernel/vmlinux-std.lds 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/kernel/vmlinux-std.lds 2006-06-06 01:17:28.000000000 +0200
|
||
@@ -66,6 +66,11 @@
|
||
__con_initcall_start = .;
|
||
.con_initcall.init : { *(.con_initcall.init) }
|
||
__con_initcall_end = .;
|
||
+ .m68k_fixup : {
|
||
+ __start_fixup = .;
|
||
+ *(.m68k_fixup)
|
||
+ __stop_fixup = .;
|
||
+ }
|
||
SECURITY_INIT
|
||
. = ALIGN(8192);
|
||
__initramfs_start = .;
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/kernel/vmlinux-sun3.lds linux-m68k/arch/m68k/kernel/vmlinux-sun3.lds
|
||
--- linux-i386/arch/m68k/kernel/vmlinux-sun3.lds 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/kernel/vmlinux-sun3.lds 2006-06-06 01:17:28.000000000 +0200
|
||
@@ -8,7 +8,7 @@
|
||
jiffies = jiffies_64 + 4;
|
||
SECTIONS
|
||
{
|
||
- . = 0xE004000;
|
||
+ . = 0xE002000;
|
||
_text = .; /* Text and read-only data */
|
||
.text : {
|
||
*(.head)
|
||
@@ -60,6 +60,11 @@
|
||
__con_initcall_start = .;
|
||
.con_initcall.init : { *(.con_initcall.init) }
|
||
__con_initcall_end = .;
|
||
+ .m68k_fixup : {
|
||
+ __start_fixup = .;
|
||
+ *(.m68k_fixup)
|
||
+ __stop_fixup = .;
|
||
+ }
|
||
SECURITY_INIT
|
||
. = ALIGN(8192);
|
||
__initramfs_start = .;
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/lib/string.c linux-m68k/arch/m68k/lib/string.c
|
||
--- linux-i386/arch/m68k/lib/string.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/lib/string.c 2006-09-05 16:31:20.000000000 +0200
|
||
@@ -1,6 +1,19 @@
|
||
+/*
|
||
+ * This file is subject to the terms and conditions of the GNU General Public
|
||
+ * License. See the file COPYING in the main directory of this archive
|
||
+ * for more details.
|
||
+ */
|
||
+
|
||
+#define __IN_STRING_C
|
||
|
||
-#include <linux/types.h>
|
||
#include <linux/module.h>
|
||
+#include <linux/string.h>
|
||
+
|
||
+char *strcpy(char *dest, const char *src)
|
||
+{
|
||
+ return __kernel_strcpy(dest, src);
|
||
+}
|
||
+EXPORT_SYMBOL(strcpy);
|
||
|
||
void *memset(void *s, int c, size_t count)
|
||
{
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/lib/uaccess.c linux-m68k/arch/m68k/lib/uaccess.c
|
||
--- linux-i386/arch/m68k/lib/uaccess.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/lib/uaccess.c 2006-09-27 16:31:43.000000000 +0200
|
||
@@ -84,7 +84,7 @@
|
||
" .even\n"
|
||
"20: lsl.l #2,%0\n"
|
||
"50: add.l %5,%0\n"
|
||
- " jra 7b\n"
|
||
+ " jra 8b\n"
|
||
" .previous\n"
|
||
"\n"
|
||
" .section __ex_table,\"a\"\n"
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/mm/init.c linux-m68k/arch/m68k/mm/init.c
|
||
--- linux-i386/arch/m68k/mm/init.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/mm/init.c 2006-09-24 16:31:37.000000000 +0200
|
||
@@ -7,6 +7,7 @@
|
||
* to motorola.c and sun3mmu.c
|
||
*/
|
||
|
||
+#include <linux/module.h>
|
||
#include <linux/signal.h>
|
||
#include <linux/sched.h>
|
||
#include <linux/mm.h>
|
||
@@ -31,6 +32,37 @@
|
||
|
||
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
|
||
|
||
+static bootmem_data_t __initdata bootmem_data[MAX_NUMNODES];
|
||
+
|
||
+pg_data_t pg_data_map[MAX_NUMNODES];
|
||
+EXPORT_SYMBOL(pg_data_map);
|
||
+
|
||
+int m68k_virt_to_node_shift;
|
||
+
|
||
+#ifndef CONFIG_SINGLE_MEMORY_CHUNK
|
||
+pg_data_t *pg_data_table[65];
|
||
+EXPORT_SYMBOL(pg_data_table);
|
||
+#endif
|
||
+
|
||
+void m68k_setup_node(int node)
|
||
+{
|
||
+#ifndef CONFIG_SINGLE_MEMORY_CHUNK
|
||
+ struct mem_info *info = m68k_memory + node;
|
||
+ int i, end;
|
||
+
|
||
+ i = (unsigned long)phys_to_virt(info->addr) >> __virt_to_node_shift();
|
||
+ end = (unsigned long)phys_to_virt(info->addr + info->size - 1) >> __virt_to_node_shift();
|
||
+ for (; i <= end; i++) {
|
||
+ if (pg_data_table[i])
|
||
+ printk("overlap at %u for chunk %u\n", i, node);
|
||
+ pg_data_table[i] = pg_data_map + node;
|
||
+ }
|
||
+#endif
|
||
+ pg_data_map[node].bdata = bootmem_data + node;
|
||
+ node_set_online(node);
|
||
+}
|
||
+
|
||
+
|
||
/*
|
||
* ZERO_PAGE is a special page that is used for zero-initialized
|
||
* data and COW.
|
||
@@ -40,52 +72,51 @@
|
||
|
||
void show_mem(void)
|
||
{
|
||
- unsigned long i;
|
||
- int free = 0, total = 0, reserved = 0, shared = 0;
|
||
- int cached = 0;
|
||
-
|
||
- printk("\nMem-info:\n");
|
||
- show_free_areas();
|
||
- printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
|
||
- i = max_mapnr;
|
||
- while (i-- > 0) {
|
||
- total++;
|
||
- if (PageReserved(mem_map+i))
|
||
- reserved++;
|
||
- else if (PageSwapCache(mem_map+i))
|
||
- cached++;
|
||
- else if (!page_count(mem_map+i))
|
||
- free++;
|
||
- else
|
||
- shared += page_count(mem_map+i) - 1;
|
||
- }
|
||
- printk("%d pages of RAM\n",total);
|
||
- printk("%d free pages\n",free);
|
||
- printk("%d reserved pages\n",reserved);
|
||
- printk("%d pages shared\n",shared);
|
||
- printk("%d pages swap cached\n",cached);
|
||
+ pg_data_t *pgdat;
|
||
+ int free = 0, total = 0, reserved = 0, shared = 0;
|
||
+ int cached = 0;
|
||
+ int i;
|
||
+
|
||
+ printk("\nMem-info:\n");
|
||
+ show_free_areas();
|
||
+ printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
|
||
+ for_each_online_pgdat(pgdat) {
|
||
+ for (i = 0; i < pgdat->node_spanned_pages; i++) {
|
||
+ struct page *page = pgdat->node_mem_map + i;
|
||
+ total++;
|
||
+ if (PageReserved(page))
|
||
+ reserved++;
|
||
+ else if (PageSwapCache(page))
|
||
+ cached++;
|
||
+ else if (!page_count(page))
|
||
+ free++;
|
||
+ else
|
||
+ shared += page_count(page) - 1;
|
||
+ }
|
||
+ }
|
||
+ printk("%d pages of RAM\n",total);
|
||
+ printk("%d free pages\n",free);
|
||
+ printk("%d reserved pages\n",reserved);
|
||
+ printk("%d pages shared\n",shared);
|
||
+ printk("%d pages swap cached\n",cached);
|
||
}
|
||
|
||
extern void init_pointer_table(unsigned long ptable);
|
||
|
||
/* References to section boundaries */
|
||
|
||
-extern char _text, _etext, _edata, __bss_start, _end;
|
||
-extern char __init_begin, __init_end;
|
||
+extern char _text[], _etext[];
|
||
+extern char __init_begin[], __init_end[];
|
||
|
||
extern pmd_t *zero_pgtable;
|
||
|
||
void __init mem_init(void)
|
||
{
|
||
+ pg_data_t *pgdat;
|
||
int codepages = 0;
|
||
int datapages = 0;
|
||
int initpages = 0;
|
||
- unsigned long tmp;
|
||
-#ifndef CONFIG_SUN3
|
||
int i;
|
||
-#endif
|
||
-
|
||
- max_mapnr = num_physpages = (((unsigned long)high_memory - PAGE_OFFSET) >> PAGE_SHIFT);
|
||
|
||
#ifdef CONFIG_ATARI
|
||
if (MACH_IS_ATARI)
|
||
@@ -93,19 +124,25 @@
|
||
#endif
|
||
|
||
/* this will put all memory onto the freelists */
|
||
- totalram_pages = free_all_bootmem();
|
||
-
|
||
- for (tmp = PAGE_OFFSET ; tmp < (unsigned long)high_memory; tmp += PAGE_SIZE) {
|
||
- if (PageReserved(virt_to_page(tmp))) {
|
||
- if (tmp >= (unsigned long)&_text
|
||
- && tmp < (unsigned long)&_etext)
|
||
+ totalram_pages = num_physpages = 0;
|
||
+ for_each_online_pgdat(pgdat) {
|
||
+ num_physpages += pgdat->node_present_pages;
|
||
+
|
||
+ totalram_pages += free_all_bootmem_node(pgdat);
|
||
+ for (i = 0; i < pgdat->node_spanned_pages; i++) {
|
||
+ struct page *page = pgdat->node_mem_map + i;
|
||
+ char *addr = page_to_virt(page);
|
||
+
|
||
+ if (!PageReserved(page))
|
||
+ continue;
|
||
+ if (addr >= _text &&
|
||
+ addr < _etext)
|
||
codepages++;
|
||
- else if (tmp >= (unsigned long) &__init_begin
|
||
- && tmp < (unsigned long) &__init_end)
|
||
+ else if (addr >= __init_begin &&
|
||
+ addr < __init_end)
|
||
initpages++;
|
||
else
|
||
datapages++;
|
||
- continue;
|
||
}
|
||
}
|
||
|
||
@@ -124,7 +161,7 @@
|
||
|
||
printk("Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init)\n",
|
||
(unsigned long)nr_free_pages() << (PAGE_SHIFT-10),
|
||
- max_mapnr << (PAGE_SHIFT-10),
|
||
+ totalram_pages << (PAGE_SHIFT-10),
|
||
codepages << (PAGE_SHIFT-10),
|
||
datapages << (PAGE_SHIFT-10),
|
||
initpages << (PAGE_SHIFT-10));
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/mm/memory.c linux-m68k/arch/m68k/mm/memory.c
|
||
--- linux-i386/arch/m68k/mm/memory.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/mm/memory.c 2006-09-24 16:31:37.000000000 +0200
|
||
@@ -126,67 +126,6 @@
|
||
return 0;
|
||
}
|
||
|
||
-#ifdef DEBUG_INVALID_PTOV
|
||
-int mm_inv_cnt = 5;
|
||
-#endif
|
||
-
|
||
-#ifndef CONFIG_SINGLE_MEMORY_CHUNK
|
||
-/*
|
||
- * The following two routines map from a physical address to a kernel
|
||
- * virtual address and vice versa.
|
||
- */
|
||
-unsigned long mm_vtop(unsigned long vaddr)
|
||
-{
|
||
- int i=0;
|
||
- unsigned long voff = (unsigned long)vaddr - PAGE_OFFSET;
|
||
-
|
||
- do {
|
||
- if (voff < m68k_memory[i].size) {
|
||
-#ifdef DEBUGPV
|
||
- printk ("VTOP(%p)=%lx\n", vaddr,
|
||
- m68k_memory[i].addr + voff);
|
||
-#endif
|
||
- return m68k_memory[i].addr + voff;
|
||
- }
|
||
- voff -= m68k_memory[i].size;
|
||
- } while (++i < m68k_num_memory);
|
||
-
|
||
- /* As a special case allow `__pa(high_memory)'. */
|
||
- if (voff == 0)
|
||
- return m68k_memory[i-1].addr + m68k_memory[i-1].size;
|
||
-
|
||
- return -1;
|
||
-}
|
||
-#endif
|
||
-
|
||
-#ifndef CONFIG_SINGLE_MEMORY_CHUNK
|
||
-unsigned long mm_ptov (unsigned long paddr)
|
||
-{
|
||
- int i = 0;
|
||
- unsigned long poff, voff = PAGE_OFFSET;
|
||
-
|
||
- do {
|
||
- poff = paddr - m68k_memory[i].addr;
|
||
- if (poff < m68k_memory[i].size) {
|
||
-#ifdef DEBUGPV
|
||
- printk ("PTOV(%lx)=%lx\n", paddr, poff + voff);
|
||
-#endif
|
||
- return poff + voff;
|
||
- }
|
||
- voff += m68k_memory[i].size;
|
||
- } while (++i < m68k_num_memory);
|
||
-
|
||
-#ifdef DEBUG_INVALID_PTOV
|
||
- if (mm_inv_cnt > 0) {
|
||
- mm_inv_cnt--;
|
||
- printk("Invalid use of phys_to_virt(0x%lx) at 0x%p!\n",
|
||
- paddr, __builtin_return_address(0));
|
||
- }
|
||
-#endif
|
||
- return -1;
|
||
-}
|
||
-#endif
|
||
-
|
||
/* invalidate page in both caches */
|
||
static inline void clear040(unsigned long paddr)
|
||
{
|
||
@@ -350,15 +289,3 @@
|
||
mach_l2_flush(1);
|
||
#endif
|
||
}
|
||
-
|
||
-#ifndef CONFIG_SINGLE_MEMORY_CHUNK
|
||
-int mm_end_of_chunk (unsigned long addr, int len)
|
||
-{
|
||
- int i;
|
||
-
|
||
- for (i = 0; i < m68k_num_memory; i++)
|
||
- if (m68k_memory[i].addr + m68k_memory[i].size == addr + len)
|
||
- return 1;
|
||
- return 0;
|
||
-}
|
||
-#endif
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/mm/motorola.c linux-m68k/arch/m68k/mm/motorola.c
|
||
--- linux-i386/arch/m68k/mm/motorola.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/mm/motorola.c 2006-09-24 16:31:37.000000000 +0200
|
||
@@ -43,6 +43,12 @@
|
||
EXPORT_SYMBOL(mm_cachebits);
|
||
#endif
|
||
|
||
+/* size of memory already mapped in head.S */
|
||
+#define INIT_MAPPED_SIZE (4UL<<20)
|
||
+
|
||
+extern unsigned long availmem;
|
||
+extern struct mem_info m68k_ramdisk;
|
||
+
|
||
static pte_t * __init kernel_page_table(void)
|
||
{
|
||
pte_t *ptablep;
|
||
@@ -98,19 +104,20 @@
|
||
return last_pgtable;
|
||
}
|
||
|
||
-static unsigned long __init
|
||
-map_chunk (unsigned long addr, long size)
|
||
+static void __init map_node(int node)
|
||
{
|
||
#define PTRTREESIZE (256*1024)
|
||
#define ROOTTREESIZE (32*1024*1024)
|
||
- static unsigned long virtaddr = PAGE_OFFSET;
|
||
- unsigned long physaddr;
|
||
+ unsigned long physaddr, virtaddr, size;
|
||
pgd_t *pgd_dir;
|
||
pmd_t *pmd_dir;
|
||
pte_t *pte_dir;
|
||
|
||
- physaddr = (addr | m68k_supervisor_cachemode |
|
||
- _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY);
|
||
+ size = m68k_memory[node].size;
|
||
+ physaddr = m68k_memory[node].addr;
|
||
+ virtaddr = (unsigned long)phys_to_virt(physaddr);
|
||
+ physaddr |= m68k_supervisor_cachemode |
|
||
+ _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY;
|
||
if (CPU_IS_040_OR_060)
|
||
physaddr |= _PAGE_GLOBAL040;
|
||
|
||
@@ -190,8 +197,6 @@
|
||
#ifdef DEBUG
|
||
printk("\n");
|
||
#endif
|
||
-
|
||
- return virtaddr;
|
||
}
|
||
|
||
/*
|
||
@@ -200,15 +205,16 @@
|
||
*/
|
||
void __init paging_init(void)
|
||
{
|
||
- int chunk;
|
||
- unsigned long mem_avail = 0;
|
||
unsigned long zones_size[MAX_NR_ZONES] = { 0, };
|
||
+ unsigned long min_addr, max_addr;
|
||
+ unsigned long addr, size, end;
|
||
+ int i;
|
||
|
||
#ifdef DEBUG
|
||
{
|
||
extern unsigned long availmem;
|
||
- printk ("start of paging_init (%p, %lx, %lx, %lx)\n",
|
||
- kernel_pg_dir, availmem, start_mem, end_mem);
|
||
+ printk ("start of paging_init (%p, %lx)\n",
|
||
+ kernel_pg_dir, availmem);
|
||
}
|
||
#endif
|
||
|
||
@@ -222,24 +228,62 @@
|
||
pgprot_val(protection_map[i]) |= _PAGE_CACHE040;
|
||
}
|
||
|
||
+ min_addr = m68k_memory[0].addr;
|
||
+ max_addr = min_addr + m68k_memory[0].size;
|
||
+ for (i = 1; i < m68k_num_memory;) {
|
||
+ if (m68k_memory[i].addr < min_addr) {
|
||
+ printk("Ignoring memory chunk at 0x%lx:0x%lx before the first chunk\n",
|
||
+ m68k_memory[i].addr, m68k_memory[i].size);
|
||
+ printk("Fix your bootloader or use a memfile to make use of this area!\n");
|
||
+ m68k_num_memory--;
|
||
+ memmove(m68k_memory + i, m68k_memory + i + 1,
|
||
+ (m68k_num_memory - i) * sizeof(struct mem_info));
|
||
+ continue;
|
||
+ }
|
||
+ addr = m68k_memory[i].addr + m68k_memory[i].size;
|
||
+ if (addr > max_addr)
|
||
+ max_addr = addr;
|
||
+ i++;
|
||
+ }
|
||
+ m68k_memoffset = min_addr - PAGE_OFFSET;
|
||
+ m68k_virt_to_node_shift = fls(max_addr - min_addr - 1) - 6;
|
||
+
|
||
+ module_fixup(NULL, __start_fixup, __stop_fixup);
|
||
+ flush_icache();
|
||
+
|
||
+ high_memory = phys_to_virt(max_addr);
|
||
+
|
||
+ min_low_pfn = availmem >> PAGE_SHIFT;
|
||
+ max_low_pfn = max_addr >> PAGE_SHIFT;
|
||
+
|
||
+ for (i = 0; i < m68k_num_memory; i++) {
|
||
+ addr = m68k_memory[i].addr;
|
||
+ end = addr + m68k_memory[i].size;
|
||
+ m68k_setup_node(i);
|
||
+ availmem = PAGE_ALIGN(availmem);
|
||
+ availmem += init_bootmem_node(NODE_DATA(i),
|
||
+ availmem >> PAGE_SHIFT,
|
||
+ addr >> PAGE_SHIFT,
|
||
+ end >> PAGE_SHIFT);
|
||
+ }
|
||
+
|
||
/*
|
||
* Map the physical memory available into the kernel virtual
|
||
- * address space. It may allocate some memory for page
|
||
- * tables and thus modify availmem.
|
||
+ * address space. First initialize the bootmem allocator with
|
||
+ * the memory we already mapped, so map_node() has something
|
||
+ * to allocate.
|
||
*/
|
||
+ addr = m68k_memory[0].addr;
|
||
+ size = m68k_memory[0].size;
|
||
+ free_bootmem_node(NODE_DATA(0), availmem, min(INIT_MAPPED_SIZE, size) - (availmem - addr));
|
||
+ map_node(0);
|
||
+ if (size > INIT_MAPPED_SIZE)
|
||
+ free_bootmem_node(NODE_DATA(0), addr + INIT_MAPPED_SIZE, size - INIT_MAPPED_SIZE);
|
||
|
||
- for (chunk = 0; chunk < m68k_num_memory; chunk++) {
|
||
- mem_avail = map_chunk (m68k_memory[chunk].addr,
|
||
- m68k_memory[chunk].size);
|
||
-
|
||
- }
|
||
+ for (i = 1; i < m68k_num_memory; i++)
|
||
+ map_node(i);
|
||
|
||
flush_tlb_all();
|
||
-#ifdef DEBUG
|
||
- printk ("memory available is %ldKB\n", mem_avail >> 10);
|
||
- printk ("start_mem is %#lx\nvirtual_end is %#lx\n",
|
||
- start_mem, end_mem);
|
||
-#endif
|
||
|
||
/*
|
||
* initialize the bad page table and bad page to point
|
||
@@ -256,14 +300,11 @@
|
||
#ifdef DEBUG
|
||
printk ("before free_area_init\n");
|
||
#endif
|
||
- zones_size[ZONE_DMA] = (mach_max_dma_address < (unsigned long)high_memory ?
|
||
- (mach_max_dma_address+1) : (unsigned long)high_memory);
|
||
- zones_size[ZONE_NORMAL] = (unsigned long)high_memory - zones_size[0];
|
||
-
|
||
- zones_size[ZONE_DMA] = (zones_size[ZONE_DMA] - PAGE_OFFSET) >> PAGE_SHIFT;
|
||
- zones_size[ZONE_NORMAL] >>= PAGE_SHIFT;
|
||
-
|
||
- free_area_init(zones_size);
|
||
+ for (i = 0; i < m68k_num_memory; i++) {
|
||
+ zones_size[ZONE_DMA] = m68k_memory[i].size >> PAGE_SHIFT;
|
||
+ free_area_init_node(i, pg_data_map + i, zones_size,
|
||
+ m68k_memory[i].addr >> PAGE_SHIFT, NULL);
|
||
+ }
|
||
}
|
||
|
||
extern char __init_begin, __init_end;
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/mm/sun3mmu.c linux-m68k/arch/m68k/mm/sun3mmu.c
|
||
--- linux-i386/arch/m68k/mm/sun3mmu.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/mm/sun3mmu.c 2006-05-11 13:14:11.000000000 +0200
|
||
@@ -49,7 +49,6 @@
|
||
unsigned long zones_size[MAX_NR_ZONES] = { 0, };
|
||
unsigned long size;
|
||
|
||
-
|
||
#ifdef TEST_VERIFY_AREA
|
||
wp_works_ok = 0;
|
||
#endif
|
||
@@ -94,7 +93,11 @@
|
||
/* memory sizing is a hack stolen from motorola.c.. hope it works for us */
|
||
zones_size[ZONE_DMA] = ((unsigned long)high_memory - PAGE_OFFSET) >> PAGE_SHIFT;
|
||
|
||
- free_area_init(zones_size);
|
||
+ /* I really wish I knew why the following change made things better... -- Sam */
|
||
+/* free_area_init(zones_size); */
|
||
+ free_area_init_node(0, NODE_DATA(0), zones_size,
|
||
+ (__pa(PAGE_OFFSET) >> PAGE_SHIFT) + 1, NULL);
|
||
+
|
||
|
||
}
|
||
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/sun3/config.c linux-m68k/arch/m68k/sun3/config.c
|
||
--- linux-i386/arch/m68k/sun3/config.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/sun3/config.c 2006-09-24 16:31:37.000000000 +0200
|
||
@@ -21,6 +21,7 @@
|
||
#include <asm/contregs.h>
|
||
#include <asm/movs.h>
|
||
#include <asm/pgtable.h>
|
||
+#include <asm/pgalloc.h>
|
||
#include <asm/sun3-head.h>
|
||
#include <asm/sun3mmu.h>
|
||
#include <asm/rtc.h>
|
||
@@ -127,6 +128,7 @@
|
||
high_memory = (void *)memory_end;
|
||
availmem = memory_start;
|
||
|
||
+ m68k_setup_node(0);
|
||
availmem += init_bootmem_node(NODE_DATA(0), start_page, 0, num_pages);
|
||
availmem = (availmem + (PAGE_SIZE-1)) & PAGE_MASK;
|
||
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/char/16c552.h linux-m68k/drivers/char/16c552.h
|
||
--- linux-i386/drivers/char/16c552.h 1970-01-01 01:00:00.000000000 +0100
|
||
+++ linux-m68k/drivers/char/16c552.h 2001-10-22 11:34:32.000000000 +0200
|
||
@@ -0,0 +1,165 @@
|
||
+/*
|
||
+ * Definitions for the 16c552 DACE
|
||
+ * (dual-asynchronous-communications-element) used on the GVP
|
||
+ * IO-Extender.
|
||
+ *
|
||
+ * Basically this is two 16c550 uarts's and a parallel port, which is
|
||
+ * why the serial definitions should be valid for the 16c550 uart
|
||
+ * aswell.
|
||
+ *
|
||
+ * Data was taken from National Semiconductors duart 16c552
|
||
+ * data-sheets and the Texas Instruments DACE 16c552 data-sheets (the
|
||
+ * NS version of the chip is _non_ standard and their data-sheets did
|
||
+ * cost me several wasted hours of work).
|
||
+ *
|
||
+ * This file is (C) 1995 Jes Sorensen (jds@kom.auc.dk)
|
||
+ *
|
||
+ * Moved from drivers/char/ to include/linux/, because it's useful
|
||
+ * on more than just the one card. I'm using it on the hp300 DCA
|
||
+ * serial driver, for example.
|
||
+ * -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 05/1998
|
||
+ */
|
||
+
|
||
+#ifndef _16C552_H_
|
||
+#define _16C552_H_
|
||
+
|
||
+/* Serial stuff */
|
||
+
|
||
+struct uart_16c550 {
|
||
+ volatile u_char skip0;
|
||
+ volatile u_char RBR;
|
||
+ volatile u_char skip1;
|
||
+ volatile u_char IER;
|
||
+ volatile u_char skip2;
|
||
+ volatile u_char IIR;
|
||
+ volatile u_char skip3;
|
||
+ volatile u_char LCR;
|
||
+ volatile u_char skip4;
|
||
+ volatile u_char MCR;
|
||
+ volatile u_char skip5;
|
||
+ volatile u_char LSR;
|
||
+ volatile u_char skip6;
|
||
+ volatile u_char MSR;
|
||
+ volatile u_char skip7;
|
||
+ volatile u_char SCR;
|
||
+};
|
||
+
|
||
+#define THR RBR
|
||
+#define FCR IIR
|
||
+#define DLL RBR
|
||
+#define DLM IER
|
||
+#define AFR IIR
|
||
+
|
||
+/*
|
||
+ * Bit-defines for the various registers.
|
||
+ */
|
||
+
|
||
+
|
||
+/* IER */
|
||
+
|
||
+#define ERDAI (1<<0)
|
||
+#define ETHREI (1<<1)
|
||
+#define ELSI (1<<2)
|
||
+#define EMSI (1<<3)
|
||
+
|
||
+/* IIR - Interrupt Ident. Register */
|
||
+
|
||
+#define IRQ_PEND (1<<0) /* NOTE: IRQ_PEND=0 implies irq pending */
|
||
+#define IRQ_ID1 (1<<1)
|
||
+#define IRQ_ID2 (1<<2)
|
||
+#define IRQ_ID3 (1<<3)
|
||
+#define FIFO_ENA0 (1<<6) /* Both these are set when FCR(1<<0)=1 */
|
||
+#define FIFO_ENA1 (1<<7)
|
||
+
|
||
+#define IRQ_RLS (IRQ_ID1 | IRQ_ID2)
|
||
+#define IRQ_RDA (IRQ_ID2)
|
||
+#define IRQ_CTI (IRQ_ID2 | IRQ_ID3)
|
||
+#define IRQ_THRE (IRQ_ID1)
|
||
+#define IRQ_MS 0
|
||
+
|
||
+/* FCR - FIFO Control Register */
|
||
+
|
||
+#define FIFO_ENA (1<<0)
|
||
+#define RCVR_FIFO_RES (1<<1)
|
||
+#define XMIT_FIFO_RES (1<<2)
|
||
+#define DMA_MODE_SEL (1<<3)
|
||
+#define RCVR_TRIG_LSB (1<<6)
|
||
+#define RCVR_TRIG_MSB (1<<7)
|
||
+
|
||
+#define FIFO_TRIG_1 0x00
|
||
+#define FIFO_TRIG_4 RCVR_TRIG_LSB
|
||
+#define FIFO_TRIG_8 RCVR_TRIG_MSB
|
||
+#define FIFO_TRIG_14 RCVR_TRIG_LSB|RCVR_TRIG_MSB
|
||
+
|
||
+/* LCR - Line Control Register */
|
||
+
|
||
+#define WLS0 (1<<0)
|
||
+#define WLS1 (1<<1)
|
||
+#define STB (1<<2)
|
||
+#define PEN (1<<3)
|
||
+#define EPS (1<<4)
|
||
+#define STICK_PARITY (1<<5)
|
||
+#define SET_BREAK (1<<6)
|
||
+#define DLAB (1<<7)
|
||
+
|
||
+#define data_5bit 0x00
|
||
+#define data_6bit 0x01
|
||
+#define data_7bit 0x02
|
||
+#define data_8bit 0x03
|
||
+
|
||
+
|
||
+/* MCR - Modem Control Register */
|
||
+
|
||
+#define DTR (1<<0)
|
||
+#define RTS (1<<1)
|
||
+#define OUT1 (1<<2)
|
||
+#define OUT2 (1<<3)
|
||
+#define LOOP (1<<4)
|
||
+
|
||
+/* LSR - Line Status Register */
|
||
+
|
||
+#define DR (1<<0)
|
||
+#define OE (1<<1)
|
||
+#define PE (1<<2)
|
||
+#define FE (1<<3)
|
||
+#define BI (1<<4)
|
||
+#define THRE (1<<5)
|
||
+#define TEMT (1<<6)
|
||
+#define RCVR_FIFO_ERR (1<<7)
|
||
+
|
||
+/* MSR - Modem Status Register */
|
||
+
|
||
+#define DCTS (1<<0)
|
||
+#define DDSR (1<<1)
|
||
+#define TERI (1<<2)
|
||
+#define DDCD (1<<3)
|
||
+#define CTS (1<<4)
|
||
+#define DSR (1<<5)
|
||
+#define RING_I (1<<6)
|
||
+#define DCD (1<<7)
|
||
+
|
||
+/* AFR - Alternate Function Register */
|
||
+
|
||
+#define CONCUR_WRITE (1<<0)
|
||
+#define BAUDOUT (1<<1)
|
||
+#define RXRDY (1<<2)
|
||
+
|
||
+/* Parallel stuff */
|
||
+
|
||
+/*
|
||
+ * Unfortunately National Semiconductors did not supply the
|
||
+ * specifications for the parallel port in the chip :-(
|
||
+ * TI succed though, so here they are :-)
|
||
+ *
|
||
+ * Defines for the bits can be found by including <linux/lp.h>
|
||
+ */
|
||
+struct IOEXT_par {
|
||
+ volatile u_char skip0;
|
||
+ volatile u_char DATA;
|
||
+ volatile u_char skip1;
|
||
+ volatile u_char STATUS;
|
||
+ volatile u_char skip2;
|
||
+ volatile u_char CTRL;
|
||
+};
|
||
+
|
||
+#endif
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/char/ioext.h linux-m68k/drivers/char/ioext.h
|
||
--- linux-i386/drivers/char/ioext.h 1970-01-01 01:00:00.000000000 +0100
|
||
+++ linux-m68k/drivers/char/ioext.h 2001-10-22 11:34:32.000000000 +0200
|
||
@@ -0,0 +1,108 @@
|
||
+/*
|
||
+ * Shared data structure for GVP IO-Extender support.
|
||
+ *
|
||
+ * Merge of ioext.h and ser_ioext.h
|
||
+ */
|
||
+#ifndef _IOEXT_H_
|
||
+#define _IOEXT_H_
|
||
+
|
||
+#include <linux/config.h>
|
||
+#include <linux/netdevice.h>
|
||
+
|
||
+#include "16c552.h"
|
||
+
|
||
+#define MAX_IOEXT 5 /*
|
||
+ * The maximum number of io-extenders is 5, as you
|
||
+ * can't have more than 5 ZII boards in any Amiga.
|
||
+ */
|
||
+
|
||
+#define UART_CLK 7372800
|
||
+
|
||
+#define IOEXT_BAUD_BASE (UART_CLK / 16)
|
||
+
|
||
+#define IOEXT_MAX_LINES 2
|
||
+
|
||
+#define IOEXT_PAR_PLIP 0x0001
|
||
+#define IOEXT_PAR_LP 0x0002
|
||
+
|
||
+
|
||
+/*
|
||
+ * Macros for the serial driver.
|
||
+ */
|
||
+#define curruart(info) ((struct uart_16c550 *)(info->port))
|
||
+
|
||
+#define ser_DTRon(info) curruart(info)->MCR |= DTR
|
||
+#define ser_RTSon(info) curruart(info)->MCR |= RTS
|
||
+#define ser_DTRoff(info) curruart(info)->MCR &= ~DTR
|
||
+#define ser_RTSoff(info) curruart(info)->MCR &= ~RTS
|
||
+
|
||
+
|
||
+/*
|
||
+ * CNTR defines (copied from the GVP SCSI-driver file gvp11.h
|
||
+ */
|
||
+#define GVP_BUSY (1<<0)
|
||
+#define GVP_IRQ_PEND (1<<1)
|
||
+#define GVP_IRQ_ENA (1<<3)
|
||
+#define GVP_DIR_WRITE (1<<4)
|
||
+
|
||
+
|
||
+/*
|
||
+ * CTRL defines
|
||
+ */
|
||
+#define PORT0_MIDI (1<<0) /* CLR = DRIVERS SET = MIDI */
|
||
+#define PORT1_MIDI (1<<1) /* CLR = DRIVERS SET = MIDI */
|
||
+#define PORT0_DRIVER (1<<2) /* CLR = RS232, SET = MIDI */
|
||
+#define PORT1_DRIVER (1<<3) /* CLR = RS232, SET = MIDI */
|
||
+#define IRQ_SEL (1<<4) /* CLR = INT2, SET = INT6 */
|
||
+#define ROM_BANK_SEL (1<<5) /* CLR = LOW 32K, SET = HIGH 32K */
|
||
+#define PORT0_CTRL (1<<6) /* CLR = RTSx or RXRDYx, SET = RTSx ONLY */
|
||
+#define PORT1_CTRL (1<<7) /* CLR = RTSx or RXRDYx, SET = RTSx ONLY */
|
||
+
|
||
+
|
||
+/*
|
||
+ * This is the struct describing the registers on the IO-Extender.
|
||
+ * NOTE: The board uses a dual uart (16c552), which should be equal to
|
||
+ * two 16c550 uarts.
|
||
+ */
|
||
+typedef struct {
|
||
+ char gap0[0x41];
|
||
+ volatile unsigned char CNTR; /* GVP DMAC CNTR (status register) */
|
||
+ char gap1[0x11e];
|
||
+ struct uart_16c550 uart0; /* The first uart */
|
||
+ char gap2[0xf0];
|
||
+ struct uart_16c550 uart1; /* The second uart */
|
||
+ char gap3[0xf0];
|
||
+ struct IOEXT_par par; /* The parallel port */
|
||
+ char gap4[0xfb];
|
||
+ volatile unsigned char CTRL; /* The control-register on the board */
|
||
+} IOEXT_struct;
|
||
+
|
||
+
|
||
+typedef struct {
|
||
+ int num_uarts;
|
||
+ int line[IOEXT_MAX_LINES];
|
||
+ volatile struct uart_16c550 *uart[IOEXT_MAX_LINES];
|
||
+ IOEXT_struct *board;
|
||
+ int spurious_count;
|
||
+ unsigned char par_use; /* IOEXT_PAR_xxx */
|
||
+#if defined(CONFIG_GVPIOEXT_PLIP) || defined(CONFIG_GVPIOEXT_PLIP_MODULE)
|
||
+ struct nt_device *dev;
|
||
+#endif
|
||
+#if defined(CONFIG_GVPIOEXT_LP) || defined(CONFIG_GVPIOEXT_LP_MODULE)
|
||
+ struct lp_struct *lp_table;
|
||
+ int lp_dev;
|
||
+ int lp_interrupt;
|
||
+#endif
|
||
+} IOExtInfoType;
|
||
+
|
||
+/* Number of detected boards. */
|
||
+extern int ioext_num;
|
||
+extern IOExtInfoType ioext_info[MAX_IOEXT];
|
||
+
|
||
+void ioext_plip_interrupt(struct net_device *dev, int *spurious_count);
|
||
+void ioext_lp_interrupt(int dev, int *spurious_count);
|
||
+
|
||
+extern struct net_device ioext_dev_plip[3];
|
||
+extern struct lp_struct ioext_lp_table[1];
|
||
+
|
||
+#endif
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/char/mc68681.h linux-m68k/drivers/char/mc68681.h
|
||
--- linux-i386/drivers/char/mc68681.h 1970-01-01 01:00:00.000000000 +0100
|
||
+++ linux-m68k/drivers/char/mc68681.h 2001-10-22 11:34:32.000000000 +0200
|
||
@@ -0,0 +1,131 @@
|
||
+#ifndef _MC68681_H_
|
||
+#define _MC68681_H_
|
||
+
|
||
+/*
|
||
+ * This describes an MC68681 DUART. It has almost only overlayed registers, which
|
||
+ * the structure very ugly.
|
||
+ * Note that the ri-register isn't really a register of the duart but a kludge of bsc
|
||
+ * to make the ring indicator available.
|
||
+ *
|
||
+ * The data came from the MFC-31-Developer Kit (from Ralph Seidel,
|
||
+ * zodiac@darkness.gun.de) and the data sheet of Phillip's clone device (SCN68681)
|
||
+ * (from Richard Hirst, srh@gpt.co.uk)
|
||
+ *
|
||
+ * 11.11.95 copyright Joerg Dorchain (dorchain@mpi-sb.mpg.de)
|
||
+ *
|
||
+ */
|
||
+
|
||
+struct duarthalf {
|
||
+union {
|
||
+volatile u_char mr1; /* rw */
|
||
+volatile u_char mr2; /* rw */
|
||
+} mr;
|
||
+volatile u_char ri; /* special, read */
|
||
+union {
|
||
+volatile u_char sr; /* read */
|
||
+volatile u_char csr; /* write */
|
||
+} sr_csr;
|
||
+u_char pad1;
|
||
+volatile u_char cr; /* write */
|
||
+u_char pad2;
|
||
+union {
|
||
+volatile u_char rhr; /* read */
|
||
+volatile u_char thr; /* write */
|
||
+} hr;
|
||
+u_char pad3;
|
||
+};
|
||
+
|
||
+struct duart {
|
||
+struct duarthalf pa;
|
||
+union {
|
||
+volatile u_char ipcr; /* read */
|
||
+volatile u_char acr; /* write */
|
||
+} ipcr_acr;
|
||
+u_char pad1;
|
||
+union {
|
||
+volatile u_char isr; /* read */
|
||
+volatile u_char imr; /* write */
|
||
+} ir;
|
||
+u_char pad2;
|
||
+volatile u_char ctu;
|
||
+u_char pad3;
|
||
+volatile u_char ctl;
|
||
+u_char pad4;
|
||
+struct duarthalf pb;
|
||
+volatile u_char ivr;
|
||
+u_char pad5;
|
||
+union {
|
||
+volatile u_char ipr; /* read */
|
||
+volatile u_char opcr; /* write */
|
||
+} ipr_opcr;
|
||
+u_char pad6;
|
||
+union {
|
||
+volatile u_char start; /* read */
|
||
+volatile u_char sopc; /* write */
|
||
+} start_sopc;
|
||
+u_char pad7;
|
||
+union {
|
||
+volatile u_char stop; /* read */
|
||
+volatile u_char ropc; /* write */
|
||
+} stop_ropc;
|
||
+u_char pad8;
|
||
+};
|
||
+
|
||
+#define MR1_BITS 3
|
||
+#define MR1_5BITS 0
|
||
+#define MR1_6BITS 1
|
||
+#define MR1_7BITS 2
|
||
+#define MR1_8BITS 3
|
||
+
|
||
+#define MR1_PARITY_ODD 4
|
||
+
|
||
+#define MR1_PARITY 24
|
||
+#define MR1_PARITY_WITH 0
|
||
+#define MR1_PARITY_FORCE 8
|
||
+#define MR1_PARITY_NO 16
|
||
+#define MR1_PARITY_MULTIDROP 24
|
||
+
|
||
+#define MR1_ERROR_BLOCK 32
|
||
+#define MR1_FFULL_IRQ 64
|
||
+#define MR1_RxRTS_ON 128
|
||
+
|
||
+#define MR2_STOPS 15
|
||
+#define MR2_1STOP 7
|
||
+#define MR2_2STOP 15
|
||
+
|
||
+#define MR2_CTS_ON 16
|
||
+#define MR2_TxRTS_ON 32
|
||
+
|
||
+#define MR2_MODE 192
|
||
+#define MR2_NORMAL 0
|
||
+#define MR2_ECHO 64
|
||
+#define MR2_LOCALLOOP 128
|
||
+#define MR2_REMOTELOOP 192
|
||
+
|
||
+#define CR_RXCOMMAND 3
|
||
+#define CR_NONE 0
|
||
+#define CR_RX_ON 1
|
||
+#define CR_RX_OFF 2
|
||
+#define CR_TXCOMMAND 12
|
||
+#define CR_TX_ON 4
|
||
+#define CR_TX_OFF 8
|
||
+#define CR_MISC 112
|
||
+#define CR_RESET_MR 16
|
||
+#define CR_RESET_RX 32
|
||
+#define CR_RESET_TX 48
|
||
+#define CR_RESET_ERR 64
|
||
+#define CR_RESET_BREAK 80
|
||
+#define CR_START_BREAK 96
|
||
+#define CR_STOP_BREAK 112
|
||
+
|
||
+#define SR_RXRDY 1
|
||
+#define SR_FFULL 2
|
||
+#define SR_TXRDY 4
|
||
+#define SR_TXEMPT 8
|
||
+#define SR_OVERRUN 16
|
||
+#define SR_PARITY 32
|
||
+#define SR_FRAMING 64
|
||
+#define SR_BREAK 128
|
||
+
|
||
+
|
||
+#endif
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/char/plip_ioext.c linux-m68k/drivers/char/plip_ioext.c
|
||
--- linux-i386/drivers/char/plip_ioext.c 1970-01-01 01:00:00.000000000 +0100
|
||
+++ linux-m68k/drivers/char/plip_ioext.c 2004-10-24 22:59:56.000000000 +0200
|
||
@@ -0,0 +1,1058 @@
|
||
+/*
|
||
+ * plip_ioext: A parallel port "network" driver for GVP IO-Extender.
|
||
+ *
|
||
+ * Authors: See drivers/net/plip.c
|
||
+ * IO-Extender version by Steve Bennett, <msteveb@ozemail.com.au>
|
||
+ *
|
||
+ * This driver is for use with a 5-bit cable (LapLink (R) cable).
|
||
+ */
|
||
+
|
||
+static const char *version = "NET3 PLIP version 2.2/m68k";
|
||
+
|
||
+#define __NO_VERSION__
|
||
+
|
||
+#include <linux/module.h>
|
||
+#include <linux/types.h>
|
||
+#include <linux/sched.h>
|
||
+#include <linux/errno.h>
|
||
+#include <linux/interrupt.h>
|
||
+#include <linux/slab.h>
|
||
+#include <linux/termios.h>
|
||
+#include <linux/tty.h>
|
||
+#include <linux/serial.h>
|
||
+
|
||
+#include <asm/setup.h>
|
||
+#include <asm/irq.h>
|
||
+#include <asm/amigahw.h>
|
||
+#include <asm/amigaints.h>
|
||
+#include <linux/zorro.h>
|
||
+
|
||
+#include <linux/config.h>
|
||
+#include <linux/kernel.h>
|
||
+#include <linux/fcntl.h>
|
||
+#include <linux/string.h>
|
||
+#include <linux/ptrace.h>
|
||
+#include <linux/if_ether.h>
|
||
+
|
||
+#include <asm/system.h>
|
||
+
|
||
+#include <linux/in.h>
|
||
+#include <linux/delay.h>
|
||
+/*#include <linux/lp_m68k.h>*/
|
||
+
|
||
+#include <linux/netdevice.h>
|
||
+#include <linux/etherdevice.h>
|
||
+#include <linux/inetdevice.h>
|
||
+#include <linux/skbuff.h>
|
||
+#include <linux/if_plip.h>
|
||
+
|
||
+#include <linux/tqueue.h>
|
||
+#include <linux/ioport.h>
|
||
+#include <linux/bitops.h>
|
||
+#include <asm/byteorder.h>
|
||
+
|
||
+#include "ioext.h"
|
||
+
|
||
+#define DEBUG 0
|
||
+
|
||
+/* Map 'struct device *' to our control structure */
|
||
+#define PLIP_DEV(DEV) (&ioext_info[(DEV)->irq])
|
||
+
|
||
+/************************************************************************
|
||
+**
|
||
+** PLIP definitions
|
||
+**
|
||
+*************************************************************************
|
||
+*/
|
||
+
|
||
+/* Use 0 for production, 1 for verification, >2 for debug */
|
||
+#ifndef NET_DEBUG
|
||
+#define NET_DEBUG 2
|
||
+#endif
|
||
+static unsigned int net_debug = NET_DEBUG;
|
||
+
|
||
+/* In micro second */
|
||
+#define PLIP_DELAY_UNIT 1
|
||
+
|
||
+/* Connection time out = PLIP_TRIGGER_WAIT * PLIP_DELAY_UNIT usec */
|
||
+#define PLIP_TRIGGER_WAIT 500
|
||
+
|
||
+/* Nibble time out = PLIP_NIBBLE_WAIT * PLIP_DELAY_UNIT usec */
|
||
+#define PLIP_NIBBLE_WAIT 3000
|
||
+
|
||
+#define PAR_DATA(dev) ((dev)->base_addr+0)
|
||
+#define PAR_STATUS(dev) ((dev)->base_addr+2)
|
||
+#define PAR_CONTROL(dev) ((dev)->base_addr+4)
|
||
+
|
||
+static void enable_par_irq(struct device *dev, int on);
|
||
+static int plip_init(struct device *dev);
|
||
+
|
||
+/* Bottom halfs */
|
||
+static void plip_kick_bh(struct device *dev);
|
||
+static void plip_bh(struct device *dev);
|
||
+
|
||
+/* Functions for DEV methods */
|
||
+static int plip_rebuild_header(struct sk_buff *skb);
|
||
+static int plip_tx_packet(struct sk_buff *skb, struct device *dev);
|
||
+static int plip_open(struct device *dev);
|
||
+static int plip_close(struct device *dev);
|
||
+static struct enet_statistics *plip_get_stats(struct device *dev);
|
||
+static int plip_config(struct device *dev, struct ifmap *map);
|
||
+static int plip_ioctl(struct device *dev, struct ifreq *ifr, int cmd);
|
||
+
|
||
+enum plip_connection_state {
|
||
+ PLIP_CN_NONE=0,
|
||
+ PLIP_CN_RECEIVE,
|
||
+ PLIP_CN_SEND,
|
||
+ PLIP_CN_CLOSING,
|
||
+ PLIP_CN_ERROR
|
||
+};
|
||
+
|
||
+enum plip_packet_state {
|
||
+ PLIP_PK_DONE=0,
|
||
+ PLIP_PK_TRIGGER,
|
||
+ PLIP_PK_LENGTH_LSB,
|
||
+ PLIP_PK_LENGTH_MSB,
|
||
+ PLIP_PK_DATA,
|
||
+ PLIP_PK_CHECKSUM
|
||
+};
|
||
+
|
||
+enum plip_nibble_state {
|
||
+ PLIP_NB_BEGIN,
|
||
+ PLIP_NB_1,
|
||
+ PLIP_NB_2,
|
||
+};
|
||
+
|
||
+struct plip_local {
|
||
+ enum plip_packet_state state;
|
||
+ enum plip_nibble_state nibble;
|
||
+ union {
|
||
+ struct {
|
||
+#if defined(__LITTLE_ENDIAN)
|
||
+ unsigned char lsb;
|
||
+ unsigned char msb;
|
||
+#elif defined(__BIG_ENDIAN)
|
||
+ unsigned char msb;
|
||
+ unsigned char lsb;
|
||
+#else
|
||
+#error "Please fix the endianness defines in <asm/byteorder.h>"
|
||
+#endif
|
||
+ } b;
|
||
+ unsigned short h;
|
||
+ } length;
|
||
+ unsigned short byte;
|
||
+ unsigned char checksum;
|
||
+ unsigned char data;
|
||
+ struct sk_buff *skb;
|
||
+};
|
||
+
|
||
+struct net_local {
|
||
+ struct enet_statistics enet_stats;
|
||
+ struct tq_struct immediate;
|
||
+ struct tq_struct deferred;
|
||
+ struct plip_local snd_data;
|
||
+ struct plip_local rcv_data;
|
||
+ unsigned long trigger;
|
||
+ unsigned long nibble;
|
||
+ enum plip_connection_state connection;
|
||
+ unsigned short timeout_count;
|
||
+ char is_deferred;
|
||
+ int (*orig_rebuild_header)(struct sk_buff *skb);
|
||
+};
|
||
+
|
||
+struct device ioext_dev_plip[] = {
|
||
+ {
|
||
+ "plip0",
|
||
+ 0, 0, 0, 0, /* memory */
|
||
+ 0, 0, /* base, irq */
|
||
+ 0, 0, 0, NULL, plip_init
|
||
+ },
|
||
+ {
|
||
+ "plip1",
|
||
+ 0, 0, 0, 0, /* memory */
|
||
+ 0, 0, /* base, irq */
|
||
+ 0, 0, 0, NULL, plip_init
|
||
+ },
|
||
+ {
|
||
+ "plip2",
|
||
+ 0, 0, 0, 0, /* memory */
|
||
+ 0, 0, /* base, irq */
|
||
+ 0, 0, 0, NULL, plip_init
|
||
+ }
|
||
+};
|
||
+
|
||
+/*
|
||
+ * Check for and handle an interrupt for this PLIP device.
|
||
+ *
|
||
+ */
|
||
+void ioext_plip_interrupt(struct device *dev, int *spurious_count)
|
||
+{
|
||
+ struct net_local *nl;
|
||
+ struct plip_local *rcv;
|
||
+ unsigned char c0;
|
||
+ unsigned long flags;
|
||
+
|
||
+ nl = (struct net_local *)dev->priv;
|
||
+ rcv = &nl->rcv_data;
|
||
+
|
||
+ c0 = z_readb(PAR_STATUS(dev));
|
||
+
|
||
+ if (dev->interrupt) {
|
||
+ return;
|
||
+ }
|
||
+
|
||
+ if ((c0 & 0xf8) != 0xc0) {
|
||
+ /* Not for us */
|
||
+ ++*spurious_count;
|
||
+ return;
|
||
+ }
|
||
+
|
||
+ *spurious_count = 0;
|
||
+ dev->interrupt = 1;
|
||
+
|
||
+ local_irq_save(flags);
|
||
+
|
||
+ switch (nl->connection) {
|
||
+ case PLIP_CN_CLOSING:
|
||
+ dev->tbusy = 0;
|
||
+ case PLIP_CN_NONE:
|
||
+ case PLIP_CN_SEND:
|
||
+ dev->last_rx = jiffies;
|
||
+ rcv->state = PLIP_PK_TRIGGER;
|
||
+ nl->connection = PLIP_CN_RECEIVE;
|
||
+ nl->timeout_count = 0;
|
||
+ queue_task(&nl->immediate, &tq_immediate);
|
||
+ mark_bh(IMMEDIATE_BH);
|
||
+ local_irq_restore(flags);
|
||
+#if 0
|
||
+ printk("%s: receive irq in SEND/NONE/CLOSING (%d) ok\n",
|
||
+ dev->name, nl->connection);
|
||
+#endif
|
||
+ break;
|
||
+
|
||
+ case PLIP_CN_RECEIVE:
|
||
+ local_irq_restore(flags);
|
||
+ printk("%s: receive interrupt when receiving packet\n",
|
||
+ dev->name);
|
||
+ break;
|
||
+
|
||
+ case PLIP_CN_ERROR:
|
||
+ local_irq_restore(flags);
|
||
+ printk("%s: receive interrupt in error state\n", dev->name);
|
||
+ break;
|
||
+ }
|
||
+}
|
||
+
|
||
+
|
||
+/* Bottom half handler for the delayed request.
|
||
+ This routine is kicked by do_timer().
|
||
+ Request `plip_bh' to be invoked. */
|
||
+static void
|
||
+plip_kick_bh(struct device *dev)
|
||
+{
|
||
+ struct net_local *nl = (struct net_local *)dev->priv;
|
||
+
|
||
+ if (nl->is_deferred) {
|
||
+ queue_task(&nl->immediate, &tq_immediate);
|
||
+ mark_bh(IMMEDIATE_BH);
|
||
+ }
|
||
+}
|
||
+
|
||
+/* Forward declarations of internal routines */
|
||
+static int plip_none(struct device *, struct net_local *,
|
||
+ struct plip_local *, struct plip_local *);
|
||
+static int plip_receive_packet(struct device *, struct net_local *,
|
||
+ struct plip_local *, struct plip_local *);
|
||
+static int plip_send_packet(struct device *, struct net_local *,
|
||
+ struct plip_local *, struct plip_local *);
|
||
+static int plip_connection_close(struct device *, struct net_local *,
|
||
+ struct plip_local *, struct plip_local *);
|
||
+static int plip_error(struct device *, struct net_local *,
|
||
+ struct plip_local *, struct plip_local *);
|
||
+static int plip_bh_timeout_error(struct device *dev, struct net_local *nl,
|
||
+ struct plip_local *snd,
|
||
+ struct plip_local *rcv,
|
||
+ int error);
|
||
+
|
||
+#define OK 0
|
||
+#define TIMEOUT 1
|
||
+#define ERROR 2
|
||
+
|
||
+typedef int (*plip_func)(struct device *dev, struct net_local *nl,
|
||
+ struct plip_local *snd, struct plip_local *rcv);
|
||
+
|
||
+static plip_func connection_state_table[] =
|
||
+{
|
||
+ plip_none,
|
||
+ plip_receive_packet,
|
||
+ plip_send_packet,
|
||
+ plip_connection_close,
|
||
+ plip_error
|
||
+};
|
||
+
|
||
+/*
|
||
+** enable_par_irq()
|
||
+**
|
||
+** Enable or disable parallel irq for 'dev' according to 'on'.
|
||
+**
|
||
+** It is NOT possible to disable only the parallel irq.
|
||
+** So we disable the board interrupt instead. This means that
|
||
+** during reception of a PLIP packet, no serial interrupts can
|
||
+** happen. Sorry.
|
||
+*/
|
||
+static void enable_par_irq(struct device *dev, int on)
|
||
+{
|
||
+ if (on) {
|
||
+ PLIP_DEV(dev)->board->CNTR |= GVP_IRQ_ENA;
|
||
+ }
|
||
+ else {
|
||
+ PLIP_DEV(dev)->board->CNTR &= ~GVP_IRQ_ENA;
|
||
+ }
|
||
+}
|
||
+
|
||
+/* Bottom half handler of PLIP. */
|
||
+static void
|
||
+plip_bh(struct device *dev)
|
||
+{
|
||
+ struct net_local *nl = (struct net_local *)dev->priv;
|
||
+ struct plip_local *snd = &nl->snd_data;
|
||
+ struct plip_local *rcv = &nl->rcv_data;
|
||
+ plip_func f;
|
||
+ int r;
|
||
+
|
||
+ nl->is_deferred = 0;
|
||
+ f = connection_state_table[nl->connection];
|
||
+ if ((r = (*f)(dev, nl, snd, rcv)) != OK
|
||
+ && (r = plip_bh_timeout_error(dev, nl, snd, rcv, r)) != OK) {
|
||
+ nl->is_deferred = 1;
|
||
+ queue_task(&nl->deferred, &tq_timer);
|
||
+ }
|
||
+}
|
||
+
|
||
+static int
|
||
+plip_bh_timeout_error(struct device *dev, struct net_local *nl,
|
||
+ struct plip_local *snd, struct plip_local *rcv,
|
||
+ int error)
|
||
+{
|
||
+ unsigned char c0;
|
||
+ unsigned long flags;
|
||
+
|
||
+ local_irq_save(flags);
|
||
+ if (nl->connection == PLIP_CN_SEND) {
|
||
+
|
||
+ if (error != ERROR) { /* Timeout */
|
||
+ nl->timeout_count++;
|
||
+ if ((snd->state == PLIP_PK_TRIGGER
|
||
+ && nl->timeout_count <= 10)
|
||
+ || nl->timeout_count <= 3) {
|
||
+ local_irq_restore(flags);
|
||
+ /* Try again later */
|
||
+ return TIMEOUT;
|
||
+ }
|
||
+ c0 = z_readb(PAR_STATUS(dev));
|
||
+ printk(KERN_INFO "%s: transmit timeout(%d,%02x)\n",
|
||
+ dev->name, snd->state, c0);
|
||
+ }
|
||
+ nl->enet_stats.tx_errors++;
|
||
+ nl->enet_stats.tx_aborted_errors++;
|
||
+ } else if (nl->connection == PLIP_CN_RECEIVE) {
|
||
+ if (rcv->state == PLIP_PK_TRIGGER) {
|
||
+ /* Transmission was interrupted. */
|
||
+ local_irq_restore(flags);
|
||
+ return OK;
|
||
+ }
|
||
+ if (error != ERROR) { /* Timeout */
|
||
+ if (++nl->timeout_count <= 3) {
|
||
+ local_irq_restore(flags);
|
||
+ /* Try again later */
|
||
+ return TIMEOUT;
|
||
+ }
|
||
+ c0 = z_readb(PAR_STATUS(dev));
|
||
+ printk(KERN_INFO "%s: receive timeout(%d,%02x)\n",
|
||
+ dev->name, rcv->state, c0);
|
||
+ }
|
||
+ nl->enet_stats.rx_dropped++;
|
||
+ }
|
||
+ rcv->state = PLIP_PK_DONE;
|
||
+ if (rcv->skb) {
|
||
+ kfree_skb(rcv->skb);
|
||
+ rcv->skb = NULL;
|
||
+ }
|
||
+ snd->state = PLIP_PK_DONE;
|
||
+ if (snd->skb) {
|
||
+ dev_kfree_skb(snd->skb);
|
||
+ snd->skb = NULL;
|
||
+ }
|
||
+ enable_par_irq(dev, 0);
|
||
+ dev->tbusy = 1;
|
||
+ nl->connection = PLIP_CN_ERROR;
|
||
+ z_writeb(0x00, PAR_DATA(dev));
|
||
+ local_irq_restore(flags);
|
||
+
|
||
+ return TIMEOUT;
|
||
+}
|
||
+
|
||
+static int
|
||
+plip_none(struct device *dev, struct net_local *nl,
|
||
+ struct plip_local *snd, struct plip_local *rcv)
|
||
+{
|
||
+ return OK;
|
||
+}
|
||
+
|
||
+/* PLIP_RECEIVE --- receive a byte(two nibbles)
|
||
+ Returns OK on success, TIMEOUT on timeout */
|
||
+inline static int
|
||
+plip_receive(struct device *dev, unsigned short nibble_timeout,
|
||
+ enum plip_nibble_state *ns_p, unsigned char *data_p)
|
||
+{
|
||
+ unsigned char c0, c1;
|
||
+ unsigned int cx;
|
||
+
|
||
+ switch (*ns_p) {
|
||
+ case PLIP_NB_BEGIN:
|
||
+ cx = nibble_timeout;
|
||
+ while (1) {
|
||
+ c0 = z_readb(PAR_STATUS(dev));
|
||
+ udelay(PLIP_DELAY_UNIT);
|
||
+ if ((c0 & 0x80) == 0) {
|
||
+ c1 = z_readb(PAR_STATUS(dev));
|
||
+ if (c0 == c1)
|
||
+ break;
|
||
+ }
|
||
+ if (--cx == 0)
|
||
+ return TIMEOUT;
|
||
+ }
|
||
+#if 0
|
||
+ printk("received first nybble: %02X -> %02X\n",
|
||
+ c0, (c0 >> 3) & 0x0F);
|
||
+#endif
|
||
+ *data_p = (c0 >> 3) & 0x0f;
|
||
+ z_writeb(0x10, PAR_DATA(dev)); /* send ACK */
|
||
+ *ns_p = PLIP_NB_1;
|
||
+
|
||
+ case PLIP_NB_1:
|
||
+ cx = nibble_timeout;
|
||
+ while (1) {
|
||
+ c0 = z_readb(PAR_STATUS(dev));
|
||
+ udelay(PLIP_DELAY_UNIT);
|
||
+ if (c0 & 0x80) {
|
||
+ c1 = z_readb(PAR_STATUS(dev));
|
||
+ if (c0 == c1)
|
||
+ break;
|
||
+ }
|
||
+ if (--cx == 0)
|
||
+ return TIMEOUT;
|
||
+ }
|
||
+#if 0
|
||
+ printk("received second nybble: %02X -> %02X\n",
|
||
+ c0, (c0 << 1) & 0xF0);
|
||
+#endif
|
||
+ *data_p |= (c0 << 1) & 0xf0;
|
||
+ z_writeb(0x00, PAR_DATA(dev)); /* send ACK */
|
||
+ *ns_p = PLIP_NB_BEGIN;
|
||
+ case PLIP_NB_2:
|
||
+ break;
|
||
+ }
|
||
+ return OK;
|
||
+}
|
||
+
|
||
+/* PLIP_RECEIVE_PACKET --- receive a packet */
|
||
+static int
|
||
+plip_receive_packet(struct device *dev, struct net_local *nl,
|
||
+ struct plip_local *snd, struct plip_local *rcv)
|
||
+{
|
||
+ unsigned short nibble_timeout = nl->nibble;
|
||
+ unsigned char *lbuf;
|
||
+ unsigned long flags;
|
||
+
|
||
+ switch (rcv->state) {
|
||
+ case PLIP_PK_TRIGGER:
|
||
+ enable_par_irq(dev, 0);
|
||
+ dev->interrupt = 0;
|
||
+ z_writeb(0x01, PAR_DATA(dev)); /* send ACK */
|
||
+ if (net_debug > 2)
|
||
+ printk(KERN_DEBUG "%s: receive start\n", dev->name);
|
||
+ rcv->state = PLIP_PK_LENGTH_LSB;
|
||
+ rcv->nibble = PLIP_NB_BEGIN;
|
||
+
|
||
+ case PLIP_PK_LENGTH_LSB:
|
||
+ if (snd->state != PLIP_PK_DONE) {
|
||
+ if (plip_receive(dev, nl->trigger,
|
||
+ &rcv->nibble, &rcv->length.b.lsb)) {
|
||
+ /* collision, here dev->tbusy == 1 */
|
||
+ rcv->state = PLIP_PK_DONE;
|
||
+ nl->is_deferred = 1;
|
||
+ nl->connection = PLIP_CN_SEND;
|
||
+ queue_task(&nl->deferred, &tq_timer);
|
||
+ enable_par_irq(dev, 1);
|
||
+ return OK;
|
||
+ }
|
||
+ } else {
|
||
+ if (plip_receive(dev, nibble_timeout,
|
||
+ &rcv->nibble, &rcv->length.b.lsb))
|
||
+ return TIMEOUT;
|
||
+ }
|
||
+ rcv->state = PLIP_PK_LENGTH_MSB;
|
||
+
|
||
+ case PLIP_PK_LENGTH_MSB:
|
||
+ if (plip_receive(dev, nibble_timeout,
|
||
+ &rcv->nibble, &rcv->length.b.msb))
|
||
+ return TIMEOUT;
|
||
+ if (rcv->length.h > dev->mtu + dev->hard_header_len
|
||
+ || rcv->length.h < 8) {
|
||
+ printk(KERN_INFO "%s: bogus packet size %d.\n",
|
||
+ dev->name, rcv->length.h);
|
||
+ return ERROR;
|
||
+ }
|
||
+ /* Malloc up new buffer. */
|
||
+ rcv->skb = dev_alloc_skb(rcv->length.h);
|
||
+ if (rcv->skb == NULL) {
|
||
+ printk(KERN_INFO "%s: Memory squeeze.\n", dev->name);
|
||
+ return ERROR;
|
||
+ }
|
||
+ skb_put(rcv->skb,rcv->length.h);
|
||
+ rcv->skb->dev = dev;
|
||
+ rcv->state = PLIP_PK_DATA;
|
||
+ rcv->byte = 0;
|
||
+ rcv->checksum = 0;
|
||
+
|
||
+ case PLIP_PK_DATA:
|
||
+ lbuf = rcv->skb->data;
|
||
+ do
|
||
+ if (plip_receive(dev, nibble_timeout,
|
||
+ &rcv->nibble, &lbuf[rcv->byte]))
|
||
+ return TIMEOUT;
|
||
+ while (++rcv->byte < rcv->length.h);
|
||
+ do
|
||
+ rcv->checksum += lbuf[--rcv->byte];
|
||
+ while (rcv->byte);
|
||
+ rcv->state = PLIP_PK_CHECKSUM;
|
||
+
|
||
+ case PLIP_PK_CHECKSUM:
|
||
+ if (plip_receive(dev, nibble_timeout,
|
||
+ &rcv->nibble, &rcv->data))
|
||
+ return TIMEOUT;
|
||
+ if (rcv->data != rcv->checksum) {
|
||
+ nl->enet_stats.rx_crc_errors++;
|
||
+ if (net_debug)
|
||
+ printk(KERN_INFO "%s: checksum error\n",
|
||
+ dev->name);
|
||
+ return ERROR;
|
||
+ }
|
||
+ rcv->state = PLIP_PK_DONE;
|
||
+
|
||
+ case PLIP_PK_DONE:
|
||
+ /* Inform the upper layer for the arrival of a packet. */
|
||
+ rcv->skb->protocol=eth_type_trans(rcv->skb, dev);
|
||
+ netif_rx(rcv->skb);
|
||
+ nl->enet_stats.rx_packets++;
|
||
+ rcv->skb = NULL;
|
||
+ if (net_debug > 2)
|
||
+ printk(KERN_DEBUG "%s: receive end\n", dev->name);
|
||
+
|
||
+ /* Close the connection. */
|
||
+ z_writeb (0x00, PAR_DATA(dev));
|
||
+
|
||
+ local_irq_save(flags);
|
||
+ if (snd->state != PLIP_PK_DONE) {
|
||
+ nl->connection = PLIP_CN_SEND;
|
||
+ local_irq_restore(flags);
|
||
+ queue_task(&nl->immediate, &tq_immediate);
|
||
+ mark_bh(IMMEDIATE_BH);
|
||
+ enable_par_irq(dev, 1);
|
||
+ return OK;
|
||
+ } else {
|
||
+ nl->connection = PLIP_CN_NONE;
|
||
+ local_irq_restore(flags);
|
||
+ enable_par_irq(dev, 1);
|
||
+ return OK;
|
||
+ }
|
||
+ }
|
||
+ return OK;
|
||
+}
|
||
+
|
||
+/* PLIP_SEND --- send a byte (two nibbles)
|
||
+ Returns OK on success, TIMEOUT when timeout */
|
||
+inline static int
|
||
+plip_send(struct device *dev, unsigned short nibble_timeout,
|
||
+ enum plip_nibble_state *ns_p, unsigned char data)
|
||
+{
|
||
+ unsigned char c0;
|
||
+ unsigned int cx;
|
||
+
|
||
+ switch (*ns_p) {
|
||
+ case PLIP_NB_BEGIN:
|
||
+ z_writeb((data & 0x0f), PAR_DATA(dev));
|
||
+ *ns_p = PLIP_NB_1;
|
||
+
|
||
+ case PLIP_NB_1:
|
||
+ z_writeb(0x10 | (data & 0x0f), PAR_DATA(dev));
|
||
+ cx = nibble_timeout;
|
||
+ while (1) {
|
||
+ c0 = z_readb(PAR_STATUS(dev));
|
||
+ if ((c0 & 0x80) == 0)
|
||
+ break;
|
||
+ if (--cx == 0)
|
||
+ return TIMEOUT;
|
||
+ udelay(PLIP_DELAY_UNIT);
|
||
+ }
|
||
+ z_writeb(0x10 | (data >> 4), PAR_DATA(dev));
|
||
+ *ns_p = PLIP_NB_2;
|
||
+
|
||
+ case PLIP_NB_2:
|
||
+ z_writeb((data >> 4), PAR_DATA(dev));
|
||
+ cx = nibble_timeout;
|
||
+ while (1) {
|
||
+ c0 = z_readb(PAR_STATUS(dev));
|
||
+ if (c0 & 0x80)
|
||
+ break;
|
||
+ if (--cx == 0)
|
||
+ return TIMEOUT;
|
||
+ udelay(PLIP_DELAY_UNIT);
|
||
+ }
|
||
+ *ns_p = PLIP_NB_BEGIN;
|
||
+ return OK;
|
||
+ }
|
||
+ return OK;
|
||
+}
|
||
+
|
||
+/* PLIP_SEND_PACKET --- send a packet */
|
||
+static int
|
||
+plip_send_packet(struct device *dev, struct net_local *nl,
|
||
+ struct plip_local *snd, struct plip_local *rcv)
|
||
+{
|
||
+ unsigned short nibble_timeout = nl->nibble;
|
||
+ unsigned char *lbuf;
|
||
+ unsigned char c0;
|
||
+ unsigned int cx;
|
||
+ unsigned long flags;
|
||
+
|
||
+ if (snd->skb == NULL || (lbuf = snd->skb->data) == NULL) {
|
||
+ printk(KERN_INFO "%s: send skb lost\n", dev->name);
|
||
+ snd->state = PLIP_PK_DONE;
|
||
+ snd->skb = NULL;
|
||
+ return ERROR;
|
||
+ }
|
||
+
|
||
+ if (snd->length.h == 0) {
|
||
+ return OK;
|
||
+ }
|
||
+
|
||
+ switch (snd->state) {
|
||
+ case PLIP_PK_TRIGGER:
|
||
+ if ((z_readb(PAR_STATUS(dev)) & 0xf8) != 0x80)
|
||
+ return TIMEOUT;
|
||
+
|
||
+ /* Trigger remote rx interrupt. */
|
||
+ z_writeb(0x08, PAR_DATA(dev));
|
||
+ cx = nl->trigger;
|
||
+ while (1) {
|
||
+ udelay(PLIP_DELAY_UNIT);
|
||
+ local_irq_save(flags);
|
||
+ if (nl->connection == PLIP_CN_RECEIVE) {
|
||
+ local_irq_restore(flags);
|
||
+ /* interrupted */
|
||
+ nl->enet_stats.collisions++;
|
||
+ if (net_debug > 1)
|
||
+ printk(KERN_INFO "%s: collision.\n",
|
||
+ dev->name);
|
||
+ return OK;
|
||
+ }
|
||
+ c0 = z_readb(PAR_STATUS(dev));
|
||
+ if (c0 & 0x08) {
|
||
+ enable_par_irq(dev, 0);
|
||
+ if (net_debug > 2)
|
||
+ printk(KERN_DEBUG "%s: send start\n",
|
||
+ dev->name);
|
||
+ snd->state = PLIP_PK_LENGTH_LSB;
|
||
+ snd->nibble = PLIP_NB_BEGIN;
|
||
+ nl->timeout_count = 0;
|
||
+ local_irq_restore(flags);
|
||
+ break;
|
||
+ }
|
||
+ local_irq_restore(flags);
|
||
+ if (--cx == 0) {
|
||
+ z_writeb(0x00, PAR_DATA(dev));
|
||
+ return TIMEOUT;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ case PLIP_PK_LENGTH_LSB:
|
||
+ if (plip_send(dev, nibble_timeout,
|
||
+ &snd->nibble, snd->length.b.lsb))
|
||
+ return TIMEOUT;
|
||
+ snd->state = PLIP_PK_LENGTH_MSB;
|
||
+
|
||
+ case PLIP_PK_LENGTH_MSB:
|
||
+ if (plip_send(dev, nibble_timeout,
|
||
+ &snd->nibble, snd->length.b.msb))
|
||
+ return TIMEOUT;
|
||
+ snd->state = PLIP_PK_DATA;
|
||
+ snd->byte = 0;
|
||
+ snd->checksum = 0;
|
||
+
|
||
+ case PLIP_PK_DATA:
|
||
+ do
|
||
+ if (plip_send(dev, nibble_timeout,
|
||
+ &snd->nibble, lbuf[snd->byte]))
|
||
+ return TIMEOUT;
|
||
+ while (++snd->byte < snd->length.h);
|
||
+ do
|
||
+ snd->checksum += lbuf[--snd->byte];
|
||
+ while (snd->byte);
|
||
+ snd->state = PLIP_PK_CHECKSUM;
|
||
+
|
||
+ case PLIP_PK_CHECKSUM:
|
||
+ if (plip_send(dev, nibble_timeout,
|
||
+ &snd->nibble, snd->checksum))
|
||
+ return TIMEOUT;
|
||
+
|
||
+ dev_kfree_skb(snd->skb);
|
||
+ nl->enet_stats.tx_packets++;
|
||
+ snd->state = PLIP_PK_DONE;
|
||
+
|
||
+ case PLIP_PK_DONE:
|
||
+ /* Close the connection */
|
||
+ z_writeb (0x00, PAR_DATA(dev));
|
||
+ snd->skb = NULL;
|
||
+ if (net_debug > 2)
|
||
+ printk(KERN_DEBUG "%s: send end\n", dev->name);
|
||
+ nl->connection = PLIP_CN_CLOSING;
|
||
+ nl->is_deferred = 1;
|
||
+ queue_task(&nl->deferred, &tq_timer);
|
||
+ enable_par_irq(dev, 1);
|
||
+ return OK;
|
||
+ }
|
||
+ return OK;
|
||
+}
|
||
+
|
||
+static int
|
||
+plip_connection_close(struct device *dev, struct net_local *nl,
|
||
+ struct plip_local *snd, struct plip_local *rcv)
|
||
+{
|
||
+ unsigned long flags;
|
||
+
|
||
+ local_irq_save(flags);
|
||
+ if (nl->connection == PLIP_CN_CLOSING) {
|
||
+ nl->connection = PLIP_CN_NONE;
|
||
+ dev->tbusy = 0;
|
||
+ mark_bh(NET_BH);
|
||
+ }
|
||
+ local_irq_restore(flags);
|
||
+ return OK;
|
||
+}
|
||
+
|
||
+/* PLIP_ERROR --- wait till other end settled */
|
||
+static int
|
||
+plip_error(struct device *dev, struct net_local *nl,
|
||
+ struct plip_local *snd, struct plip_local *rcv)
|
||
+{
|
||
+ unsigned char status;
|
||
+
|
||
+ status = z_readb(PAR_STATUS(dev));
|
||
+ if ((status & 0xf8) == 0x80) {
|
||
+ if (net_debug > 2)
|
||
+ printk(KERN_DEBUG "%s: reset interface.\n", dev->name);
|
||
+ nl->connection = PLIP_CN_NONE;
|
||
+ dev->tbusy = 0;
|
||
+ dev->interrupt = 0;
|
||
+ enable_par_irq(dev, 1);
|
||
+ mark_bh(NET_BH);
|
||
+ } else {
|
||
+ nl->is_deferred = 1;
|
||
+ queue_task(&nl->deferred, &tq_timer);
|
||
+ }
|
||
+
|
||
+ return OK;
|
||
+}
|
||
+
|
||
+/* We don't need to send arp, for plip is point-to-point. */
|
||
+static int
|
||
+plip_rebuild_header(struct sk_buff *skb)
|
||
+{
|
||
+ struct device *dev = skb->dev;
|
||
+ struct net_local *nl = (struct net_local *)dev->priv;
|
||
+ struct ethhdr *eth = (struct ethhdr *)skb->data;
|
||
+ int i;
|
||
+
|
||
+ if ((dev->flags & IFF_NOARP)==0)
|
||
+ return nl->orig_rebuild_header(skb);
|
||
+
|
||
+ if (eth->h_proto != __constant_htons(ETH_P_IP)
|
||
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||
+ && eth->h_proto != __constant_htons(ETH_P_IPV6)
|
||
+#endif
|
||
+ ) {
|
||
+ printk(KERN_ERR "plip_rebuild_header: Don't know how to resolve type %d addresses?\n", (int)eth->h_proto);
|
||
+ memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
|
||
+ return 0;
|
||
+ }
|
||
+
|
||
+ for (i=0; i < ETH_ALEN - sizeof(u32); i++)
|
||
+ eth->h_dest[i] = 0xfc;
|
||
+#if 0
|
||
+ *(u32 *)(eth->h_dest+i) = dst;
|
||
+#else
|
||
+ /* Do not want to include net/route.h here.
|
||
+ * In any case, it is TOP of silliness to emulate
|
||
+ * hardware addresses on PtP link. --ANK
|
||
+ */
|
||
+ *(u32 *)(eth->h_dest+i) = 0;
|
||
+#endif
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static int
|
||
+plip_tx_packet(struct sk_buff *skb, struct device *dev)
|
||
+{
|
||
+ struct net_local *nl = (struct net_local *)dev->priv;
|
||
+ struct plip_local *snd = &nl->snd_data;
|
||
+ unsigned long flags;
|
||
+
|
||
+ if (dev->tbusy)
|
||
+ return 1;
|
||
+
|
||
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
|
||
+ printk(KERN_ERR "%s: Transmitter access conflict.\n",
|
||
+ dev->name);
|
||
+ return 1;
|
||
+ }
|
||
+
|
||
+ if (skb->len > dev->mtu + dev->hard_header_len) {
|
||
+ printk(KERN_ERR "%s: packet too big, %d.\n",
|
||
+ dev->name, (int)skb->len);
|
||
+ dev->tbusy = 0;
|
||
+ return 0;
|
||
+ }
|
||
+
|
||
+ if (net_debug > 2)
|
||
+ printk(KERN_DEBUG "%s: send request\n", dev->name);
|
||
+
|
||
+ local_irq_save(flags);
|
||
+ dev->trans_start = jiffies;
|
||
+ snd->skb = skb;
|
||
+ snd->length.h = skb->len;
|
||
+ snd->state = PLIP_PK_TRIGGER;
|
||
+ if (nl->connection == PLIP_CN_NONE) {
|
||
+ nl->connection = PLIP_CN_SEND;
|
||
+ nl->timeout_count = 0;
|
||
+ }
|
||
+ queue_task(&nl->immediate, &tq_immediate);
|
||
+ mark_bh(IMMEDIATE_BH);
|
||
+ local_irq_restore(flags);
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+/* Open/initialize the board. This is called (in the current kernel)
|
||
+ sometime after booting when the 'ifconfig' program is run.
|
||
+
|
||
+ */
|
||
+static int
|
||
+plip_open(struct device *dev)
|
||
+{
|
||
+ struct net_local *nl = (struct net_local *)dev->priv;
|
||
+ struct in_device *in_dev;
|
||
+
|
||
+#if defined(CONFIG_GVPIOEXT_LP) || defined(CONFIG_GVPIOEXT_LP_MODULE)
|
||
+ /* Yes, there is a race condition here. Fix it later */
|
||
+ if (PLIP_DEV(dev)->par_use & IOEXT_PAR_LP) {
|
||
+ /* Can't open if lp is in use */
|
||
+#if DEBUG
|
||
+ printk("par is in use by lp\n");
|
||
+#endif
|
||
+ return(-EBUSY);
|
||
+ }
|
||
+#endif
|
||
+ PLIP_DEV(dev)->par_use |= IOEXT_PAR_PLIP;
|
||
+
|
||
+#if DEBUG
|
||
+ printk("plip_open(): sending 00 to data port\n");
|
||
+#endif
|
||
+
|
||
+ /* Clear the data port. */
|
||
+ z_writeb (0x00, PAR_DATA(dev));
|
||
+
|
||
+#if DEBUG
|
||
+ printk("plip_open(): sent\n");
|
||
+#endif
|
||
+
|
||
+ /* Initialize the state machine. */
|
||
+ nl->rcv_data.state = nl->snd_data.state = PLIP_PK_DONE;
|
||
+ nl->rcv_data.skb = nl->snd_data.skb = NULL;
|
||
+ nl->connection = PLIP_CN_NONE;
|
||
+ nl->is_deferred = 0;
|
||
+
|
||
+ /* Fill in the MAC-level header.
|
||
+ (ab)Use "dev->broadcast" to store point-to-point MAC address.
|
||
+
|
||
+ PLIP doesn't have a real mac address, but we need to create one
|
||
+ to be DOS compatible. */
|
||
+ memset(dev->dev_addr, 0xfc, ETH_ALEN);
|
||
+ memset(dev->broadcast, 0xfc, ETH_ALEN);
|
||
+
|
||
+ if ((in_dev=dev->ip_ptr) != NULL) {
|
||
+ /*
|
||
+ * Any address will do - we take the first
|
||
+ */
|
||
+ struct in_ifaddr *ifa=in_dev->ifa_list;
|
||
+ if (ifa != NULL) {
|
||
+ memcpy(dev->dev_addr+2, &ifa->ifa_local, 4);
|
||
+ memcpy(dev->broadcast+2, &ifa->ifa_address, 4);
|
||
+ }
|
||
+ }
|
||
+
|
||
+ dev->interrupt = 0;
|
||
+ dev->start = 1;
|
||
+ dev->tbusy = 0;
|
||
+
|
||
+ MOD_INC_USE_COUNT;
|
||
+
|
||
+ /* Enable rx interrupt. */
|
||
+ enable_par_irq(dev, 1);
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+/* The inverse routine to plip_open (). */
|
||
+static int
|
||
+plip_close(struct device *dev)
|
||
+{
|
||
+ struct net_local *nl = (struct net_local *)dev->priv;
|
||
+ struct plip_local *snd = &nl->snd_data;
|
||
+ struct plip_local *rcv = &nl->rcv_data;
|
||
+ unsigned long flags;
|
||
+
|
||
+ dev->tbusy = 1;
|
||
+ dev->start = 0;
|
||
+ local_irq_save(flags);
|
||
+ nl->is_deferred = 0;
|
||
+ nl->connection = PLIP_CN_NONE;
|
||
+ local_irq_restore(flags);
|
||
+ z_writeb(0x00, PAR_DATA(dev));
|
||
+
|
||
+ snd->state = PLIP_PK_DONE;
|
||
+ if (snd->skb) {
|
||
+ dev_kfree_skb(snd->skb);
|
||
+ snd->skb = NULL;
|
||
+ }
|
||
+ rcv->state = PLIP_PK_DONE;
|
||
+ if (rcv->skb) {
|
||
+ kfree_skb(rcv->skb);
|
||
+ rcv->skb = NULL;
|
||
+ }
|
||
+
|
||
+ PLIP_DEV(dev)->par_use &= ~IOEXT_PAR_PLIP;
|
||
+
|
||
+ MOD_DEC_USE_COUNT;
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static struct enet_statistics *
|
||
+plip_get_stats(struct device *dev)
|
||
+{
|
||
+ struct net_local *nl = (struct net_local *)dev->priv;
|
||
+ struct enet_statistics *r = &nl->enet_stats;
|
||
+
|
||
+ return r;
|
||
+}
|
||
+
|
||
+static int
|
||
+plip_config(struct device *dev, struct ifmap *map)
|
||
+{
|
||
+ if (dev->flags & IFF_UP)
|
||
+ return -EBUSY;
|
||
+
|
||
+ printk(KERN_INFO "%s: This interface is autodetected (ignored).\n",
|
||
+ dev->name);
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static int
|
||
+plip_ioctl(struct device *dev, struct ifreq *rq, int cmd)
|
||
+{
|
||
+ struct net_local *nl = (struct net_local *) dev->priv;
|
||
+ struct plipconf *pc = (struct plipconf *) &rq->ifr_data;
|
||
+
|
||
+ switch(pc->pcmd) {
|
||
+ case PLIP_GET_TIMEOUT:
|
||
+ pc->trigger = nl->trigger;
|
||
+ pc->nibble = nl->nibble;
|
||
+ break;
|
||
+ case PLIP_SET_TIMEOUT:
|
||
+ nl->trigger = pc->trigger;
|
||
+ nl->nibble = pc->nibble;
|
||
+ break;
|
||
+ default:
|
||
+ return -EOPNOTSUPP;
|
||
+ }
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+/*
|
||
+ * Detect and initialize all IO-Extenders in this system.
|
||
+ *
|
||
+ * Both PLIP and serial devices are configured.
|
||
+ */
|
||
+int plip_init(struct device *dev)
|
||
+{
|
||
+ IOEXT_struct *board;
|
||
+ struct net_local *nl;
|
||
+
|
||
+ if (ioext_num == 0) {
|
||
+ printk(KERN_INFO "%s\n", version);
|
||
+ }
|
||
+
|
||
+ board = PLIP_DEV(dev)->board;
|
||
+ dev->base_addr = (unsigned long)&board->par.DATA;
|
||
+
|
||
+ /* Cheat and use irq to index into our table */
|
||
+ dev->irq = ioext_num;
|
||
+
|
||
+ printk(KERN_INFO "%s: IO-Extender parallel port at 0x%08lX\n", dev->name, dev->base_addr);
|
||
+
|
||
+ /* Fill in the generic fields of the device structure. */
|
||
+ ether_setup(dev);
|
||
+
|
||
+ /* Then, override parts of it */
|
||
+ dev->hard_start_xmit = plip_tx_packet;
|
||
+ dev->open = plip_open;
|
||
+ dev->stop = plip_close;
|
||
+ dev->get_stats = plip_get_stats;
|
||
+ dev->set_config = plip_config;
|
||
+ dev->do_ioctl = plip_ioctl;
|
||
+ dev->tx_queue_len = 10;
|
||
+ dev->flags = IFF_POINTOPOINT|IFF_NOARP;
|
||
+
|
||
+ /* Set the private structure */
|
||
+ dev->priv = kmalloc(sizeof (struct net_local), GFP_KERNEL);
|
||
+ if (dev->priv == NULL) {
|
||
+ printk(KERN_ERR "%s: out of memory\n", dev->name);
|
||
+ return -ENOMEM;
|
||
+ }
|
||
+ memset(dev->priv, 0, sizeof(struct net_local));
|
||
+ nl = (struct net_local *) dev->priv;
|
||
+
|
||
+ nl->orig_rebuild_header = dev->rebuild_header;
|
||
+ dev->rebuild_header = plip_rebuild_header;
|
||
+
|
||
+ /* Initialize constants */
|
||
+ nl->trigger = PLIP_TRIGGER_WAIT;
|
||
+ nl->nibble = PLIP_NIBBLE_WAIT;
|
||
+
|
||
+ /* Initialize task queue structures */
|
||
+ nl->immediate.next = NULL;
|
||
+ nl->immediate.sync = 0;
|
||
+ nl->immediate.routine = (void *)(void *)plip_bh;
|
||
+ nl->immediate.data = dev;
|
||
+
|
||
+ nl->deferred.next = NULL;
|
||
+ nl->deferred.sync = 0;
|
||
+ nl->deferred.routine = (void *)(void *)plip_kick_bh;
|
||
+ nl->deferred.data = dev;
|
||
+
|
||
+ /* Don't enable interrupts yet */
|
||
+
|
||
+ return 0;
|
||
+}
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/char/serial167.c linux-m68k/drivers/char/serial167.c
|
||
--- linux-i386/drivers/char/serial167.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/char/serial167.c 2006-09-24 16:32:38.000000000 +0200
|
||
@@ -62,6 +62,7 @@
|
||
#include <linux/console.h>
|
||
#include <linux/module.h>
|
||
#include <linux/bitops.h>
|
||
+#include <linux/tty_flip.h>
|
||
|
||
#include <asm/system.h>
|
||
#include <asm/io.h>
|
||
@@ -438,8 +439,9 @@
|
||
overflowing, we still loose
|
||
the next incoming character.
|
||
*/
|
||
- tty_insert_flip_char(tty, data, TTY_NORMAL);
|
||
- }
|
||
+ if (tty_buffer_request_room(tty, 1) != 0){
|
||
+ tty_insert_flip_char(tty, data, TTY_FRAME);
|
||
+ }
|
||
/* These two conditions may imply */
|
||
/* a normal read should be done. */
|
||
/* else if(data & CyTIMEOUT) */
|
||
@@ -448,14 +450,14 @@
|
||
tty_insert_flip_char(tty, 0, TTY_NORMAL);
|
||
}
|
||
}else{
|
||
- tty_insert_flip_char(tty, data, TTY_NORMAL);
|
||
+ tty_insert_flip_char(tty, data, TTY_NORMAL);
|
||
}
|
||
}else{
|
||
/* there was a software buffer overrun
|
||
and nothing could be done about it!!! */
|
||
}
|
||
}
|
||
- schedule_delayed_work(&tty->flip.work, 1);
|
||
+ tty_schedule_flip(tty);
|
||
/* end of service */
|
||
base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
|
||
return IRQ_HANDLED;
|
||
@@ -646,6 +648,7 @@
|
||
char data;
|
||
int char_count;
|
||
int save_cnt;
|
||
+ int len;
|
||
|
||
/* determine the channel and change to that context */
|
||
channel = (u_short ) (base_addr[CyLICR] >> 2);
|
||
@@ -678,14 +681,15 @@
|
||
info->mon.char_max = char_count;
|
||
info->mon.char_last = char_count;
|
||
#endif
|
||
- while(char_count--){
|
||
+ len = tty_buffer_request_room(tty, char_count);
|
||
+ while(len--){
|
||
data = base_addr[CyRDR];
|
||
tty_insert_flip_char(tty, data, TTY_NORMAL);
|
||
#ifdef CYCLOM_16Y_HACK
|
||
udelay(10L);
|
||
#endif
|
||
}
|
||
- schedule_delayed_work(&tty->flip.work, 1);
|
||
+ tty_schedule_flip(tty);
|
||
}
|
||
/* end of service */
|
||
base_addr[CyREOIR] = save_cnt ? 0 : CyNOTRANS;
|
||
@@ -1433,7 +1437,6 @@
|
||
volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
|
||
unsigned long flags;
|
||
unsigned char status;
|
||
- unsigned int result;
|
||
|
||
channel = info->line;
|
||
|
||
@@ -1457,7 +1460,6 @@
|
||
int channel;
|
||
volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
|
||
unsigned long flags;
|
||
- unsigned int arg;
|
||
|
||
channel = info->line;
|
||
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/ide/ide-iops.c linux-m68k/drivers/ide/ide-iops.c
|
||
--- linux-i386/drivers/ide/ide-iops.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/ide/ide-iops.c 2006-09-24 16:32:47.000000000 +0200
|
||
@@ -337,6 +337,23 @@
|
||
int i;
|
||
u16 *stringcast;
|
||
|
||
+#ifdef __mc68000__
|
||
+ if (!MACH_IS_AMIGA && !MACH_IS_MAC && !MACH_IS_Q40 && !MACH_IS_ATARI)
|
||
+ return;
|
||
+
|
||
+#ifdef M68K_IDE_SWAPW
|
||
+ if (M68K_IDE_SWAPW) { /* fix bus byteorder first */
|
||
+ u_char *p = (u_char *)id;
|
||
+ u_char t;
|
||
+ for (i = 0; i < 512; i += 2) {
|
||
+ t = p[i];
|
||
+ p[i] = p[i+1];
|
||
+ p[i+1] = t;
|
||
+ }
|
||
+ }
|
||
+#endif
|
||
+#endif /* __mc68000__ */
|
||
+
|
||
id->config = __le16_to_cpu(id->config);
|
||
id->cyls = __le16_to_cpu(id->cyls);
|
||
id->reserved2 = __le16_to_cpu(id->reserved2);
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/input/keyboard/Kconfig linux-m68k/drivers/input/keyboard/Kconfig
|
||
--- linux-i386/drivers/input/keyboard/Kconfig 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/input/keyboard/Kconfig 2006-06-18 19:08:22.000000000 +0200
|
||
@@ -155,7 +155,7 @@
|
||
|
||
config KEYBOARD_HIL_OLD
|
||
tristate "HP HIL keyboard support (simple driver)"
|
||
- depends on GSC
|
||
+ depends on GSC || HP300
|
||
default y
|
||
help
|
||
The "Human Interface Loop" is a older, 8-channel USB-like
|
||
@@ -172,7 +172,7 @@
|
||
|
||
config KEYBOARD_HIL
|
||
tristate "HP HIL keyboard support"
|
||
- depends on GSC
|
||
+ depends on GSC || HP300
|
||
default y
|
||
select HP_SDC
|
||
select HIL_MLC
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/input/misc/Kconfig linux-m68k/drivers/input/misc/Kconfig
|
||
--- linux-i386/drivers/input/misc/Kconfig 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/input/misc/Kconfig 2006-09-24 16:32:52.000000000 +0200
|
||
@@ -73,7 +73,7 @@
|
||
|
||
config HP_SDC_RTC
|
||
tristate "HP SDC Real Time Clock"
|
||
- depends on GSC
|
||
+ depends on GSC || HP300
|
||
select HP_SDC
|
||
help
|
||
Say Y here if you want to support the built-in real time clock
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/input/mouse/Kconfig linux-m68k/drivers/input/mouse/Kconfig
|
||
--- linux-i386/drivers/input/mouse/Kconfig 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/input/mouse/Kconfig 2006-04-10 00:22:40.000000000 +0200
|
||
@@ -119,7 +119,7 @@
|
||
|
||
config MOUSE_HIL
|
||
tristate "HIL pointers (mice etc)."
|
||
- depends on GSC
|
||
+ depends on GSC || HP300
|
||
select HP_SDC
|
||
select HIL_MLC
|
||
help
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/input/serio/Kconfig linux-m68k/drivers/input/serio/Kconfig
|
||
--- linux-i386/drivers/input/serio/Kconfig 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/input/serio/Kconfig 2005-08-29 21:17:45.000000000 +0200
|
||
@@ -112,7 +112,7 @@
|
||
|
||
config HP_SDC
|
||
tristate "HP System Device Controller i8042 Support"
|
||
- depends on GSC && SERIO
|
||
+ depends on (GSC || HP300) && SERIO
|
||
default y
|
||
---help---
|
||
This option enables supports for the the "System Device
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/macintosh/adb.c linux-m68k/drivers/macintosh/adb.c
|
||
--- linux-i386/drivers/macintosh/adb.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/macintosh/adb.c 2006-09-24 16:32:59.000000000 +0200
|
||
@@ -478,13 +478,15 @@
|
||
use_sreq = 1;
|
||
} else
|
||
use_sreq = 0;
|
||
- req->nbytes = nbytes+1;
|
||
+ i = (flags & ADBREQ_RAW) ? 0 : 1;
|
||
+ req->nbytes = nbytes+i;
|
||
req->done = done;
|
||
req->reply_expected = flags & ADBREQ_REPLY;
|
||
req->data[0] = ADB_PACKET;
|
||
va_start(list, nbytes);
|
||
- for (i = 0; i < nbytes; ++i)
|
||
- req->data[i+1] = va_arg(list, int);
|
||
+ while (i < req->nbytes) {
|
||
+ req->data[i++] = va_arg(list, int);
|
||
+ }
|
||
va_end(list);
|
||
|
||
if (flags & ADBREQ_NOSEND)
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/net/7990.c linux-m68k/drivers/net/7990.c
|
||
--- linux-i386/drivers/net/7990.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/net/7990.c 2006-06-18 19:08:38.000000000 +0200
|
||
@@ -500,7 +500,7 @@
|
||
int res;
|
||
|
||
/* Install the Interrupt handler. Or we could shunt this out to specific drivers? */
|
||
- if (request_irq(lp->irq, lance_interrupt, 0, lp->name, dev))
|
||
+ if (request_irq(lp->irq, lance_interrupt, SA_SHIRQ, lp->name, dev))
|
||
return -EAGAIN;
|
||
|
||
res = lance_reset(dev);
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/net/Kconfig linux-m68k/drivers/net/Kconfig
|
||
--- linux-i386/drivers/net/Kconfig 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/net/Kconfig 2006-09-24 16:33:13.000000000 +0200
|
||
@@ -307,7 +307,7 @@
|
||
|
||
config MAC89x0
|
||
tristate "Macintosh CS89x0 based ethernet cards"
|
||
- depends on NET_ETHERNET && MAC && BROKEN
|
||
+ depends on NET_ETHERNET && MAC
|
||
---help---
|
||
Support for CS89x0 chipset based Ethernet cards. If you have a
|
||
Nubus or LC-PDS network (Ethernet) card of this type, say Y and
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/net/hplance.c linux-m68k/drivers/net/hplance.c
|
||
--- linux-i386/drivers/net/hplance.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/net/hplance.c 2006-06-18 19:08:39.000000000 +0200
|
||
@@ -77,6 +77,7 @@
|
||
{
|
||
struct net_device *dev;
|
||
int err = -ENOMEM;
|
||
+ int i;
|
||
|
||
dev = alloc_etherdev(sizeof(struct hplance_private));
|
||
if (!dev)
|
||
@@ -93,6 +94,15 @@
|
||
goto out_release_mem_region;
|
||
|
||
dio_set_drvdata(d, dev);
|
||
+
|
||
+ printk(KERN_INFO "%s: %s; select code %d, addr %2.2x", dev->name, d->name, d->scode, dev->dev_addr[0]);
|
||
+
|
||
+ for (i=1; i<6; i++) {
|
||
+ printk(":%2.2x", dev->dev_addr[i]);
|
||
+ }
|
||
+
|
||
+ printk(", irq %d\n", d->ipl);
|
||
+
|
||
return 0;
|
||
|
||
out_release_mem_region:
|
||
@@ -118,9 +128,7 @@
|
||
unsigned long va = (d->resource.start + DIO_VIRADDRBASE);
|
||
struct hplance_private *lp;
|
||
int i;
|
||
-
|
||
- printk(KERN_INFO "%s: %s; select code %d, addr", dev->name, d->name, d->scode);
|
||
-
|
||
+
|
||
/* reset the board */
|
||
out_8(va+DIO_IDOFF, 0xff);
|
||
udelay(100); /* ariba! ariba! udelay! udelay! */
|
||
@@ -143,7 +151,6 @@
|
||
*/
|
||
dev->dev_addr[i] = ((in_8(va + HPLANCE_NVRAMOFF + i*4 + 1) & 0xF) << 4)
|
||
| (in_8(va + HPLANCE_NVRAMOFF + i*4 + 3) & 0xF);
|
||
- printk("%c%2.2x", i == 0 ? ' ' : ':', dev->dev_addr[i]);
|
||
}
|
||
|
||
lp = netdev_priv(dev);
|
||
@@ -160,7 +167,6 @@
|
||
lp->lance.lance_log_tx_bufs = LANCE_LOG_TX_BUFFERS;
|
||
lp->lance.rx_ring_mod_mask = RX_RING_MOD_MASK;
|
||
lp->lance.tx_ring_mod_mask = TX_RING_MOD_MASK;
|
||
- printk(", irq %d\n", lp->lance.irq);
|
||
}
|
||
|
||
/* This is disgusting. We have to check the DIO status register for ack every
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/net/mac89x0.c linux-m68k/drivers/net/mac89x0.c
|
||
--- linux-i386/drivers/net/mac89x0.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/net/mac89x0.c 2006-06-18 19:08:40.000000000 +0200
|
||
@@ -128,7 +128,7 @@
|
||
extern void reset_chip(struct net_device *dev);
|
||
#endif
|
||
static int net_open(struct net_device *dev);
|
||
-static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
|
||
+static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
|
||
static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
|
||
static void set_multicast_list(struct net_device *dev);
|
||
static void net_rx(struct net_device *dev);
|
||
@@ -374,56 +374,37 @@
|
||
static int
|
||
net_send_packet(struct sk_buff *skb, struct net_device *dev)
|
||
{
|
||
- if (dev->tbusy) {
|
||
- /* If we get here, some higher level has decided we are broken.
|
||
- There should really be a "kick me" function call instead. */
|
||
- int tickssofar = jiffies - dev->trans_start;
|
||
- if (tickssofar < 5)
|
||
- return 1;
|
||
- if (net_debug > 0) printk("%s: transmit timed out, %s?\n", dev->name,
|
||
- tx_done(dev) ? "IRQ conflict" : "network cable problem");
|
||
- /* Try to restart the adaptor. */
|
||
- dev->tbusy=0;
|
||
- dev->trans_start = jiffies;
|
||
- }
|
||
-
|
||
- /* Block a timer-based transmit from overlapping. This could better be
|
||
- done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
|
||
- if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
|
||
- printk("%s: Transmitter access conflict.\n", dev->name);
|
||
- else {
|
||
- struct net_local *lp = netdev_priv(dev);
|
||
- unsigned long flags;
|
||
-
|
||
- if (net_debug > 3)
|
||
- printk("%s: sent %d byte packet of type %x\n",
|
||
- dev->name, skb->len,
|
||
- (skb->data[ETH_ALEN+ETH_ALEN] << 8)
|
||
- | skb->data[ETH_ALEN+ETH_ALEN+1]);
|
||
-
|
||
- /* keep the upload from being interrupted, since we
|
||
- ask the chip to start transmitting before the
|
||
- whole packet has been completely uploaded. */
|
||
- local_irq_save(flags);
|
||
-
|
||
- /* initiate a transmit sequence */
|
||
- writereg(dev, PP_TxCMD, lp->send_cmd);
|
||
- writereg(dev, PP_TxLength, skb->len);
|
||
-
|
||
- /* Test to see if the chip has allocated memory for the packet */
|
||
- if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
|
||
- /* Gasp! It hasn't. But that shouldn't happen since
|
||
- we're waiting for TxOk, so return 1 and requeue this packet. */
|
||
- local_irq_restore(flags);
|
||
- return 1;
|
||
- }
|
||
+ struct net_local *lp = netdev_priv(dev);
|
||
+ unsigned long flags;
|
||
|
||
- /* Write the contents of the packet */
|
||
- memcpy_toio(dev->mem_start + PP_TxFrame, skb->data, skb->len+1);
|
||
+ if (net_debug > 3)
|
||
+ printk("%s: sent %d byte packet of type %x\n",
|
||
+ dev->name, skb->len,
|
||
+ (skb->data[ETH_ALEN+ETH_ALEN] << 8)
|
||
+ | skb->data[ETH_ALEN+ETH_ALEN+1]);
|
||
+
|
||
+ /* keep the upload from being interrupted, since we
|
||
+ ask the chip to start transmitting before the
|
||
+ whole packet has been completely uploaded. */
|
||
+ local_irq_save(flags);
|
||
|
||
+ /* initiate a transmit sequence */
|
||
+ writereg(dev, PP_TxCMD, lp->send_cmd);
|
||
+ writereg(dev, PP_TxLength, skb->len);
|
||
+
|
||
+ /* Test to see if the chip has allocated memory for the packet */
|
||
+ if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
|
||
+ /* Gasp! It hasn't. But that shouldn't happen since
|
||
+ we're waiting for TxOk, so return 1 and requeue this packet. */
|
||
local_irq_restore(flags);
|
||
- dev->trans_start = jiffies;
|
||
+ return 1;
|
||
}
|
||
+
|
||
+ /* Write the contents of the packet */
|
||
+ memcpy((void *)(dev->mem_start + PP_TxFrame), skb->data, skb->len+1);
|
||
+
|
||
+ local_irq_restore(flags);
|
||
+ dev->trans_start = jiffies;
|
||
dev_kfree_skb (skb);
|
||
|
||
return 0;
|
||
@@ -441,9 +422,6 @@
|
||
printk ("net_interrupt(): irq %d for unknown device.\n", irq);
|
||
return IRQ_NONE;
|
||
}
|
||
- if (dev->interrupt)
|
||
- printk("%s: Re-entering the interrupt handler.\n", dev->name);
|
||
- dev->interrupt = 1;
|
||
|
||
ioaddr = dev->base_addr;
|
||
lp = netdev_priv(dev);
|
||
@@ -464,8 +442,7 @@
|
||
break;
|
||
case ISQ_TRANSMITTER_EVENT:
|
||
lp->stats.tx_packets++;
|
||
- dev->tbusy = 0;
|
||
- mark_bh(NET_BH); /* Inform upper layers. */
|
||
+ netif_wake_queue(dev);
|
||
if ((status & TX_OK) == 0) lp->stats.tx_errors++;
|
||
if (status & TX_LOST_CRS) lp->stats.tx_carrier_errors++;
|
||
if (status & TX_SQE_ERROR) lp->stats.tx_heartbeat_errors++;
|
||
@@ -479,8 +456,7 @@
|
||
That shouldn't happen since we only ever
|
||
load one packet. Shrug. Do the right
|
||
thing anyway. */
|
||
- dev->tbusy = 0;
|
||
- mark_bh(NET_BH); /* Inform upper layers. */
|
||
+ netif_wake_queue(dev);
|
||
}
|
||
if (status & TX_UNDERRUN) {
|
||
if (net_debug > 0) printk("%s: transmit underrun\n", dev->name);
|
||
@@ -497,7 +473,6 @@
|
||
break;
|
||
}
|
||
}
|
||
- dev->interrupt = 0;
|
||
return IRQ_HANDLED;
|
||
}
|
||
|
||
@@ -532,7 +507,7 @@
|
||
skb_put(skb, length);
|
||
skb->dev = dev;
|
||
|
||
- memcpy_fromio(skb->data, dev->mem_start + PP_RxFrame, length);
|
||
+ memcpy(skb->data, (void *)(dev->mem_start + PP_RxFrame), length);
|
||
|
||
if (net_debug > 3)printk("%s: received %d byte packet of type %x\n",
|
||
dev->name, length,
|
||
@@ -611,8 +586,6 @@
|
||
static int set_mac_address(struct net_device *dev, void *addr)
|
||
{
|
||
int i;
|
||
- if (dev->start)
|
||
- return -EBUSY;
|
||
printk("%s: Setting MAC address to ", dev->name);
|
||
for (i = 0; i < 6; i++)
|
||
printk(" %2.2x", dev->dev_addr[i] = ((unsigned char *)addr)[i]);
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/53c7xx.c linux-m68k/drivers/scsi/53c7xx.c
|
||
--- linux-i386/drivers/scsi/53c7xx.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/53c7xx.c 2006-09-24 16:33:34.000000000 +0200
|
||
@@ -307,7 +307,7 @@
|
||
|
||
static int check_address (unsigned long addr, int size);
|
||
static void dump_events (struct Scsi_Host *host, int count);
|
||
-static Scsi_Cmnd * return_outstanding_commands (struct Scsi_Host *host,
|
||
+static struct scsi_cmnd * return_outstanding_commands (struct Scsi_Host *host,
|
||
int free, int issue);
|
||
static void hard_reset (struct Scsi_Host *host);
|
||
static void ncr_scsi_reset (struct Scsi_Host *host);
|
||
@@ -316,7 +316,7 @@
|
||
int scntl3, int now_connected);
|
||
static int datapath_residual (struct Scsi_Host *host);
|
||
static const char * sbcl_to_phase (int sbcl);
|
||
-static void print_progress (Scsi_Cmnd *cmd);
|
||
+static void print_progress (struct scsi_cmnd *cmd);
|
||
static void print_queues (struct Scsi_Host *host);
|
||
static void process_issue_queue (unsigned long flags);
|
||
static int shutdown (struct Scsi_Host *host);
|
||
@@ -341,9 +341,8 @@
|
||
static void NCR53c7x0_soft_reset (struct Scsi_Host *host);
|
||
|
||
/* Size of event list (per host adapter) */
|
||
-static int track_events = 0;
|
||
-static struct Scsi_Host *first_host = NULL; /* Head of list of NCR boards */
|
||
-static struct scsi_host_template *the_template = NULL;
|
||
+static int track_events;
|
||
+static struct scsi_host_template *the_template;
|
||
|
||
/* NCR53c710 script handling code */
|
||
|
||
@@ -666,8 +665,11 @@
|
||
|
||
static struct Scsi_Host *
|
||
find_host (int host) {
|
||
- struct Scsi_Host *h;
|
||
- for (h = first_host; h && h->host_no != host; h = h->next);
|
||
+ struct Scsi_Host *h, *s;
|
||
+ list_for_each_entry_safe(h, s, &the_template->legacy_hosts, sht_legacy_list) {
|
||
+ if (h->host_no == host)
|
||
+ break;
|
||
+ }
|
||
if (!h) {
|
||
printk (KERN_ALERT "scsi%d not found\n", host);
|
||
return NULL;
|
||
@@ -715,14 +717,14 @@
|
||
}
|
||
hostdata = (struct NCR53c7x0_hostdata *)h->hostdata[0];
|
||
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
if (hostdata->initiate_sdtr & (1 << target)) {
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
printk (KERN_ALERT "target %d already doing SDTR\n", target);
|
||
return -1;
|
||
}
|
||
hostdata->initiate_sdtr |= (1 << target);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return 0;
|
||
}
|
||
#endif
|
||
@@ -1033,9 +1035,6 @@
|
||
|
||
ccf = clock_to_ccf_710 (expected_clock);
|
||
|
||
- for (i = 0; i < 16; ++i)
|
||
- hostdata->cmd_allocated[i] = 0;
|
||
-
|
||
if (hostdata->init_save_regs)
|
||
hostdata->init_save_regs (host);
|
||
if (hostdata->init_fixup)
|
||
@@ -1043,7 +1042,6 @@
|
||
|
||
if (!the_template) {
|
||
the_template = host->hostt;
|
||
- first_host = host;
|
||
}
|
||
|
||
/*
|
||
@@ -1306,7 +1304,6 @@
|
||
hostdata->free->size = max_cmd_size;
|
||
hostdata->free->free = NULL;
|
||
hostdata->free->next = NULL;
|
||
- hostdata->extra_allocate = 0;
|
||
|
||
/* Allocate command start code space */
|
||
hostdata->schedule = (chip == 700 || chip == 70066) ?
|
||
@@ -1589,10 +1586,10 @@
|
||
|
||
/* The NCR chip _must_ be idle to run the test scripts */
|
||
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
if (!hostdata->idle) {
|
||
printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return -1;
|
||
}
|
||
|
||
@@ -1616,7 +1613,7 @@
|
||
NCR53c7x0_write8 (DCNTL_REG, hostdata->saved_dcntl | DCNTL_SSM |
|
||
DCNTL_STD);
|
||
printk (" started\n");
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
|
||
/*
|
||
* This is currently a .5 second timeout, since (in theory) no slow
|
||
@@ -1655,7 +1652,7 @@
|
||
hostdata->script, start);
|
||
printk ("scsi%d : DSPS = 0x%x\n", host->host_no,
|
||
NCR53c7x0_read32(DSPS_REG));
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return -1;
|
||
}
|
||
hostdata->test_running = 0;
|
||
@@ -1693,7 +1690,7 @@
|
||
local_irq_disable();
|
||
if (!hostdata->idle) {
|
||
printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return -1;
|
||
}
|
||
|
||
@@ -1709,7 +1706,7 @@
|
||
if (hostdata->options & OPTION_DEBUG_TRACE)
|
||
NCR53c7x0_write8 (DCNTL_REG, hostdata->saved_dcntl |
|
||
DCNTL_SSM | DCNTL_STD);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
|
||
timeout = jiffies + 5 * HZ; /* arbitrary */
|
||
while ((hostdata->test_completed == -1) && time_before(jiffies, timeout))
|
||
@@ -1731,19 +1728,19 @@
|
||
host->host_no, i);
|
||
if (!hostdata->idle) {
|
||
printk("scsi%d : not idle\n", host->host_no);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return -1;
|
||
}
|
||
} else if (hostdata->test_completed == -1) {
|
||
printk ("scsi%d : test 2 timed out\n", host->host_no);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return -1;
|
||
}
|
||
hostdata->test_running = 0;
|
||
}
|
||
}
|
||
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return 0;
|
||
}
|
||
|
||
@@ -1759,7 +1756,7 @@
|
||
|
||
static void
|
||
NCR53c7xx_dsa_fixup (struct NCR53c7x0_cmd *cmd) {
|
||
- Scsi_Cmnd *c = cmd->cmd;
|
||
+ struct scsi_cmnd *c = cmd->cmd;
|
||
struct Scsi_Host *host = c->device->host;
|
||
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
|
||
host->hostdata[0];
|
||
@@ -1845,7 +1842,7 @@
|
||
*
|
||
* Purpose : mark SCSI command as finished, OR'ing the host portion
|
||
* of the result word into the result field of the corresponding
|
||
- * Scsi_Cmnd structure, and removing it from the internal queues.
|
||
+ * scsi_cmnd structure, and removing it from the internal queues.
|
||
*
|
||
* Inputs : cmd - command, result - entire result field
|
||
*
|
||
@@ -1856,7 +1853,7 @@
|
||
|
||
static void
|
||
abnormal_finished (struct NCR53c7x0_cmd *cmd, int result) {
|
||
- Scsi_Cmnd *c = cmd->cmd;
|
||
+ struct scsi_cmnd *c = cmd->cmd;
|
||
struct Scsi_Host *host = c->device->host;
|
||
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
|
||
host->hostdata[0];
|
||
@@ -1870,7 +1867,7 @@
|
||
printk ("scsi%d: abnormal finished\n", host->host_no);
|
||
#endif
|
||
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
found = 0;
|
||
/*
|
||
* Traverse the NCR issue array until we find a match or run out
|
||
@@ -1953,7 +1950,7 @@
|
||
c->result = result;
|
||
c->scsi_done(c);
|
||
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
run_process_issue_queue();
|
||
}
|
||
|
||
@@ -1975,7 +1972,7 @@
|
||
NCR53c7x0_local_declare();
|
||
struct NCR53c7x0_break *bp;
|
||
#if 0
|
||
- Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
|
||
+ struct scsi_cmnd *c = cmd ? cmd->cmd : NULL;
|
||
#endif
|
||
u32 *dsp;
|
||
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
|
||
@@ -1988,7 +1985,7 @@
|
||
* dump the appropriate debugging information to standard
|
||
* output.
|
||
*/
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
dsp = (u32 *) bus_to_virt(NCR53c7x0_read32(DSP_REG));
|
||
for (bp = hostdata->breakpoints; bp && bp->address != dsp;
|
||
bp = bp->next);
|
||
@@ -2010,7 +2007,7 @@
|
||
* instruction in bytes.
|
||
*/
|
||
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
}
|
||
/*
|
||
* Function : static void print_synchronous (const char *prefix,
|
||
@@ -2252,7 +2249,7 @@
|
||
NCR53c7x0_cmd *cmd) {
|
||
NCR53c7x0_local_declare();
|
||
int print;
|
||
- Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
|
||
+ struct scsi_cmnd *c = cmd ? cmd->cmd : NULL;
|
||
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
|
||
host->hostdata[0];
|
||
u32 dsps,*dsp; /* Argument of the INT instruction */
|
||
@@ -2916,7 +2913,7 @@
|
||
host->hostdata[0];
|
||
NCR53c7x0_local_setup(host);
|
||
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
|
||
/* Disable scsi chip and s/w level 7 ints */
|
||
|
||
@@ -3017,12 +3014,12 @@
|
||
}
|
||
#endif
|
||
/* Anything needed for your hardware? */
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
}
|
||
|
||
|
||
/*
|
||
- * Function static struct NCR53c7x0_cmd *allocate_cmd (Scsi_Cmnd *cmd)
|
||
+ * Function static struct NCR53c7x0_cmd *allocate_cmd (struct scsi_cmnd *cmd)
|
||
*
|
||
* Purpose : Return the first free NCR53c7x0_cmd structure (which are
|
||
* reused in a LIFO manner to minimize cache thrashing).
|
||
@@ -3049,86 +3046,25 @@
|
||
}
|
||
|
||
static struct NCR53c7x0_cmd *
|
||
-allocate_cmd (Scsi_Cmnd *cmd) {
|
||
+allocate_cmd (struct scsi_cmnd *cmd) {
|
||
struct Scsi_Host *host = cmd->device->host;
|
||
struct NCR53c7x0_hostdata *hostdata =
|
||
(struct NCR53c7x0_hostdata *) host->hostdata[0];
|
||
- u32 real; /* Real address */
|
||
- int size; /* Size of *tmp */
|
||
struct NCR53c7x0_cmd *tmp;
|
||
unsigned long flags;
|
||
|
||
if (hostdata->options & OPTION_DEBUG_ALLOCATION)
|
||
printk ("scsi%d : num_cmds = %d, can_queue = %d\n"
|
||
- " target = %d, lun = %d, %s\n",
|
||
+ " target = %d, lun = %d\n",
|
||
host->host_no, hostdata->num_cmds, host->can_queue,
|
||
- cmd->device->id, cmd->device->lun, (hostdata->cmd_allocated[cmd->device->id] &
|
||
- (1 << cmd->device->lun)) ? "already allocated" : "not allocated");
|
||
-
|
||
-/*
|
||
- * If we have not yet reserved commands for this I_T_L nexus, and
|
||
- * the device exists (as indicated by permanent Scsi_Cmnd structures
|
||
- * being allocated under 1.3.x, or being outside of scan_scsis in
|
||
- * 1.2.x), do so now.
|
||
- */
|
||
- if (!(hostdata->cmd_allocated[cmd->device->id] & (1 << cmd->device->lun)) &&
|
||
- cmd->device && cmd->device->has_cmdblocks) {
|
||
- if ((hostdata->extra_allocate + hostdata->num_cmds) < host->can_queue)
|
||
- hostdata->extra_allocate += host->cmd_per_lun;
|
||
- hostdata->cmd_allocated[cmd->device->id] |= (1 << cmd->device->lun);
|
||
- }
|
||
-
|
||
- for (; hostdata->extra_allocate > 0 ; --hostdata->extra_allocate,
|
||
- ++hostdata->num_cmds) {
|
||
- /* historically, kmalloc has returned unaligned addresses; pad so we
|
||
- have enough room to ROUNDUP */
|
||
- size = hostdata->max_cmd_size + sizeof (void *);
|
||
-#ifdef FORCE_DSA_ALIGNMENT
|
||
- /*
|
||
- * 53c710 rev.0 doesn't have an add-with-carry instruction.
|
||
- * Ensure we allocate enough memory to force alignment.
|
||
- */
|
||
- size += 256;
|
||
-#endif
|
||
-/* FIXME: for ISA bus '7xx chips, we need to or GFP_DMA in here */
|
||
+ cmd->device->id, cmd->device->lun);
|
||
|
||
- if (size > 4096) {
|
||
- printk (KERN_ERR "53c7xx: allocate_cmd size > 4K\n");
|
||
- return NULL;
|
||
- }
|
||
- real = get_zeroed_page(GFP_ATOMIC);
|
||
- if (real == 0)
|
||
- return NULL;
|
||
- memset((void *)real, 0, 4096);
|
||
- cache_push(virt_to_phys((void *)real), 4096);
|
||
- cache_clear(virt_to_phys((void *)real), 4096);
|
||
- kernel_set_cachemode((void *)real, 4096, IOMAP_NOCACHE_SER);
|
||
- tmp = ROUNDUP(real, void *);
|
||
-#ifdef FORCE_DSA_ALIGNMENT
|
||
- {
|
||
- if (((u32)tmp & 0xff) > CmdPageStart)
|
||
- tmp = (struct NCR53c7x0_cmd *)((u32)tmp + 255);
|
||
- tmp = (struct NCR53c7x0_cmd *)(((u32)tmp & ~0xff) + CmdPageStart);
|
||
-#if 0
|
||
- printk ("scsi: size = %d, real = 0x%08x, tmp set to 0x%08x\n",
|
||
- size, real, (u32)tmp);
|
||
-#endif
|
||
- }
|
||
-#endif
|
||
- tmp->real = (void *)real;
|
||
- tmp->size = size;
|
||
- tmp->free = ((void (*)(void *, int)) my_free_page);
|
||
- local_irq_save(flags);
|
||
- tmp->next = hostdata->free;
|
||
- hostdata->free = tmp;
|
||
- local_irq_restore(flags);
|
||
- }
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
tmp = (struct NCR53c7x0_cmd *) hostdata->free;
|
||
if (tmp) {
|
||
hostdata->free = tmp->next;
|
||
}
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
if (!tmp)
|
||
printk ("scsi%d : can't allocate command for target %d lun %d\n",
|
||
host->host_no, cmd->device->id, cmd->device->lun);
|
||
@@ -3136,11 +3072,11 @@
|
||
}
|
||
|
||
/*
|
||
- * Function static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd)
|
||
+ * Function static struct NCR53c7x0_cmd *create_cmd (struct scsi_cmnd *cmd)
|
||
*
|
||
*
|
||
* Purpose : allocate a NCR53c7x0_cmd structure, initialize it based on the
|
||
- * Scsi_Cmnd structure passed in cmd, including dsa and Linux field
|
||
+ * scsi_cmnd structure passed in cmd, including dsa and Linux field
|
||
* initialization, and dsa code relocation.
|
||
*
|
||
* Inputs : cmd - SCSI command
|
||
@@ -3149,7 +3085,7 @@
|
||
* NULL on failure.
|
||
*/
|
||
static struct NCR53c7x0_cmd *
|
||
-create_cmd (Scsi_Cmnd *cmd) {
|
||
+create_cmd (struct scsi_cmnd *cmd) {
|
||
NCR53c7x0_local_declare();
|
||
struct Scsi_Host *host = cmd->device->host;
|
||
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
|
||
@@ -3173,7 +3109,7 @@
|
||
return NULL;
|
||
|
||
/*
|
||
- * Copy CDB and initialised result fields from Scsi_Cmnd to NCR53c7x0_cmd.
|
||
+ * Copy CDB and initialised result fields from scsi_cmnd to NCR53c7x0_cmd.
|
||
* We do this because NCR53c7x0_cmd may have a special cache mode
|
||
* selected to cope with lack of bus snooping, etc.
|
||
*/
|
||
@@ -3316,7 +3252,7 @@
|
||
|
||
patch_dsa_32(tmp->dsa, dsa_next, 0, 0);
|
||
/*
|
||
- * XXX is this giving 53c710 access to the Scsi_Cmnd in some way?
|
||
+ * XXX is this giving 53c710 access to the scsi_cmnd in some way?
|
||
* Do we need to change it for caching reasons?
|
||
*/
|
||
patch_dsa_32(tmp->dsa, dsa_cmnd, 0, virt_to_bus(cmd));
|
||
@@ -3347,17 +3283,17 @@
|
||
memcpy ((void *) (tmp->select + 1), (void *) wdtr_message,
|
||
sizeof(wdtr_message));
|
||
patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(wdtr_message));
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
hostdata->initiate_wdtr &= ~(1 << cmd->device->id);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
} else if (hostdata->initiate_sdtr & (1 << cmd->device->id)) {
|
||
memcpy ((void *) (tmp->select + 1), (void *) sdtr_message,
|
||
sizeof(sdtr_message));
|
||
patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(sdtr_message));
|
||
tmp->flags |= CMD_FLAG_SDTR;
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
hostdata->initiate_sdtr &= ~(1 << cmd->device->id);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
|
||
}
|
||
#if 1
|
||
@@ -3570,8 +3506,8 @@
|
||
}
|
||
|
||
/*
|
||
- * Function : int NCR53c7xx_queue_command (Scsi_Cmnd *cmd,
|
||
- * void (*done)(Scsi_Cmnd *))
|
||
+ * Function : int NCR53c7xx_queue_command (struct scsi_cmnd *cmd,
|
||
+ * void (*done)(struct scsi_cmnd *))
|
||
*
|
||
* Purpose : enqueues a SCSI command
|
||
*
|
||
@@ -3585,18 +3521,18 @@
|
||
* twiddling done to the host specific fields of cmd. If the
|
||
* process_issue_queue coroutine isn't running, it is restarted.
|
||
*
|
||
- * NOTE : we use the host_scribble field of the Scsi_Cmnd structure to
|
||
+ * NOTE : we use the host_scribble field of the scsi_cmnd structure to
|
||
* hold our own data, and pervert the ptr field of the SCp field
|
||
* to create a linked list.
|
||
*/
|
||
|
||
int
|
||
-NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) {
|
||
+NCR53c7xx_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) {
|
||
struct Scsi_Host *host = cmd->device->host;
|
||
struct NCR53c7x0_hostdata *hostdata =
|
||
(struct NCR53c7x0_hostdata *) host->hostdata[0];
|
||
unsigned long flags;
|
||
- Scsi_Cmnd *tmp;
|
||
+ struct scsi_cmnd *tmp;
|
||
|
||
cmd->scsi_done = done;
|
||
cmd->host_scribble = NULL;
|
||
@@ -3614,7 +3550,7 @@
|
||
}
|
||
#endif
|
||
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
if ((hostdata->options & (OPTION_DEBUG_INIT_ONLY|OPTION_DEBUG_PROBE_ONLY))
|
||
|| ((hostdata->options & OPTION_DEBUG_TARGET_LIMIT) &&
|
||
!(hostdata->debug_lun_limit[cmd->device->id] & (1 << cmd->device->lun)))
|
||
@@ -3629,7 +3565,7 @@
|
||
cmd->device->id, cmd->device->lun);
|
||
cmd->result = (DID_BAD_TARGET << 16);
|
||
done(cmd);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return 0;
|
||
}
|
||
|
||
@@ -3638,7 +3574,7 @@
|
||
printk("scsi%d : maximum commands exceeded\n", host->host_no);
|
||
cmd->result = (DID_BAD_TARGET << 16);
|
||
done(cmd);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return 0;
|
||
}
|
||
|
||
@@ -3650,7 +3586,7 @@
|
||
host->host_no);
|
||
cmd->result = (DID_BAD_TARGET << 16);
|
||
done(cmd);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return 0;
|
||
}
|
||
}
|
||
@@ -3673,18 +3609,18 @@
|
||
cmd->SCp.ptr = (unsigned char *) hostdata->issue_queue;
|
||
hostdata->issue_queue = cmd;
|
||
} else {
|
||
- for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp->SCp.ptr;
|
||
- tmp = (Scsi_Cmnd *) tmp->SCp.ptr);
|
||
+ for (tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp->SCp.ptr;
|
||
+ tmp = (struct scsi_cmnd *) tmp->SCp.ptr);
|
||
tmp->SCp.ptr = (unsigned char *) cmd;
|
||
}
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
run_process_issue_queue();
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
* Function : void to_schedule_list (struct Scsi_Host *host,
|
||
- * struct NCR53c7x0_hostdata * hostdata, Scsi_Cmnd *cmd)
|
||
+ * struct NCR53c7x0_hostdata * hostdata, struct scsi_cmnd *cmd)
|
||
*
|
||
* Purpose : takes a SCSI command which was just removed from the
|
||
* issue queue, and deals with it by inserting it in the first
|
||
@@ -3705,7 +3641,7 @@
|
||
to_schedule_list (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
|
||
struct NCR53c7x0_cmd *cmd) {
|
||
NCR53c7x0_local_declare();
|
||
- Scsi_Cmnd *tmp = cmd->cmd;
|
||
+ struct scsi_cmnd *tmp = cmd->cmd;
|
||
unsigned long flags;
|
||
/* dsa start is negative, so subtraction is used */
|
||
volatile u32 *ncrcurrent;
|
||
@@ -3717,7 +3653,7 @@
|
||
virt_to_bus(hostdata->dsa), hostdata->dsa);
|
||
#endif
|
||
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
|
||
/*
|
||
* Work around race condition : if an interrupt fired and we
|
||
@@ -3730,7 +3666,7 @@
|
||
cmd->next = (struct NCR53c7x0_cmd *) hostdata->free;
|
||
hostdata->free = cmd;
|
||
tmp->scsi_done(tmp);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return;
|
||
}
|
||
|
||
@@ -3760,7 +3696,7 @@
|
||
cmd->next = (struct NCR53c7x0_cmd *) hostdata->free;
|
||
hostdata->free = cmd;
|
||
tmp->scsi_done(tmp);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return;
|
||
}
|
||
|
||
@@ -3781,12 +3717,12 @@
|
||
NCR53c7x0_write8(hostdata->istat, ISTAT_10_SIGP);
|
||
}
|
||
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
}
|
||
|
||
/*
|
||
* Function : busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata
|
||
- * *hostdata, Scsi_Cmnd *cmd)
|
||
+ * *hostdata, struct scsi_cmnd *cmd)
|
||
*
|
||
* Purpose : decide if we can pass the given SCSI command on to the
|
||
* device in question or not.
|
||
@@ -3796,7 +3732,7 @@
|
||
|
||
static __inline__ int
|
||
busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
|
||
- Scsi_Cmnd *cmd) {
|
||
+ struct scsi_cmnd *cmd) {
|
||
/* FIXME : in the future, this needs to accommodate SCSI-II tagged
|
||
queuing, and we may be able to play with fairness here a bit.
|
||
*/
|
||
@@ -3822,8 +3758,8 @@
|
||
|
||
static void
|
||
process_issue_queue (unsigned long flags) {
|
||
- Scsi_Cmnd *tmp, *prev;
|
||
- struct Scsi_Host *host;
|
||
+ struct scsi_cmnd *tmp, *prev;
|
||
+ struct Scsi_Host *host, *s;
|
||
struct NCR53c7x0_hostdata *hostdata;
|
||
int done;
|
||
|
||
@@ -3841,14 +3777,13 @@
|
||
do {
|
||
local_irq_disable(); /* Freeze request queues */
|
||
done = 1;
|
||
- for (host = first_host; host && host->hostt == the_template;
|
||
- host = host->next) {
|
||
+ list_for_each_entry_safe(host, s, &the_template->legacy_hosts, sht_legacy_list) {
|
||
hostdata = (struct NCR53c7x0_hostdata *) host->hostdata[0];
|
||
- local_irq_disable();
|
||
+ spin_lock_irq(host->host_lock);
|
||
if (hostdata->issue_queue) {
|
||
if (hostdata->state == STATE_DISABLED) {
|
||
- tmp = (Scsi_Cmnd *) hostdata->issue_queue;
|
||
- hostdata->issue_queue = (Scsi_Cmnd *) tmp->SCp.ptr;
|
||
+ tmp = (struct scsi_cmnd *) hostdata->issue_queue;
|
||
+ hostdata->issue_queue = (struct scsi_cmnd *) tmp->SCp.ptr;
|
||
tmp->result = (DID_BAD_TARGET << 16);
|
||
if (tmp->host_scribble) {
|
||
((struct NCR53c7x0_cmd *)tmp->host_scribble)->next =
|
||
@@ -3860,15 +3795,15 @@
|
||
tmp->scsi_done (tmp);
|
||
done = 0;
|
||
} else
|
||
- for (tmp = (Scsi_Cmnd *) hostdata->issue_queue,
|
||
- prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *)
|
||
+ for (tmp = (struct scsi_cmnd *) hostdata->issue_queue,
|
||
+ prev = NULL; tmp; prev = tmp, tmp = (struct scsi_cmnd *)
|
||
tmp->SCp.ptr)
|
||
if (!tmp->host_scribble ||
|
||
!busyp (host, hostdata, tmp)) {
|
||
if (prev)
|
||
prev->SCp.ptr = tmp->SCp.ptr;
|
||
else
|
||
- hostdata->issue_queue = (Scsi_Cmnd *)
|
||
+ hostdata->issue_queue = (struct scsi_cmnd *)
|
||
tmp->SCp.ptr;
|
||
tmp->SCp.ptr = NULL;
|
||
if (tmp->host_scribble) {
|
||
@@ -3893,6 +3828,7 @@
|
||
done = 0;
|
||
} /* if target/lun is not busy */
|
||
} /* if hostdata->issue_queue */
|
||
+ spin_unlock(host->host_lock);
|
||
if (!done)
|
||
local_irq_restore(flags);
|
||
} /* for host */
|
||
@@ -4103,7 +4039,7 @@
|
||
int cnt = 0;
|
||
int i = insn_log_index;
|
||
int size;
|
||
- struct Scsi_Host *host = first_host;
|
||
+ struct Scsi_Host *host = (struct Scsi_Host *)the_template->legacy_hosts->next;
|
||
|
||
while (cnt < 4096) {
|
||
printk ("%08x (+%6x): ", insn_log[i], (insn_log[i] - (u32)&(((struct NCR53c7x0_hostdata *)host->hostdata[0])->script))/4);
|
||
@@ -4161,14 +4097,14 @@
|
||
* completion.
|
||
*/
|
||
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
restart:
|
||
for (cmd_prev_ptr = (struct NCR53c7x0_cmd **)&(hostdata->running_list),
|
||
cmd = (struct NCR53c7x0_cmd *) hostdata->running_list; cmd ;
|
||
cmd_prev_ptr = (struct NCR53c7x0_cmd **) &(cmd->next),
|
||
cmd = (struct NCR53c7x0_cmd *) cmd->next)
|
||
{
|
||
- Scsi_Cmnd *tmp;
|
||
+ struct scsi_cmnd *tmp;
|
||
|
||
if (!cmd) {
|
||
printk("scsi%d : very weird.\n", host->host_no);
|
||
@@ -4176,7 +4112,7 @@
|
||
}
|
||
|
||
if (!(tmp = cmd->cmd)) {
|
||
- printk("scsi%d : weird. NCR53c7x0_cmd has no Scsi_Cmnd\n",
|
||
+ printk("scsi%d : weird. NCR53c7x0_cmd has no scsi_cmnd\n",
|
||
host->host_no);
|
||
continue;
|
||
}
|
||
@@ -4215,7 +4151,7 @@
|
||
tmp->scsi_done(tmp);
|
||
goto restart;
|
||
}
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
|
||
if (!search_found) {
|
||
printk ("scsi%d : WARNING : INTFLY with no completed commands.\n",
|
||
@@ -4250,7 +4186,7 @@
|
||
struct NCR53c7x0_cmd *cmd; /* command which halted */
|
||
u32 *dsa; /* DSA */
|
||
int handled = 0;
|
||
-
|
||
+ unsigned long flags;
|
||
#ifdef NCR_DEBUG
|
||
char buf[80]; /* Debugging sprintf buffer */
|
||
size_t buflen; /* Length of same */
|
||
@@ -4259,6 +4195,7 @@
|
||
host = (struct Scsi_Host *)dev_id;
|
||
hostdata = (struct NCR53c7x0_hostdata *) host->hostdata[0];
|
||
NCR53c7x0_local_setup(host);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
|
||
/*
|
||
* Only read istat once per loop, since reading it again will unstack
|
||
@@ -4351,7 +4288,8 @@
|
||
}
|
||
}
|
||
}
|
||
- return IRQ_HANDLED;
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
+ return IRQ_RETVAL(handled);
|
||
}
|
||
|
||
|
||
@@ -4360,7 +4298,7 @@
|
||
*
|
||
* Purpose : Assuming that the NCR SCSI processor is currently
|
||
* halted, break the currently established nexus. Clean
|
||
- * up of the NCR53c7x0_cmd and Scsi_Cmnd structures should
|
||
+ * up of the NCR53c7x0_cmd and scsi_cmnd structures should
|
||
* be done on receipt of the abort interrupt.
|
||
*
|
||
* Inputs : host - SCSI host
|
||
@@ -4899,12 +4837,12 @@
|
||
/* Don't print instr. until we write DSP at end of intr function */
|
||
} else if (hostdata->options & OPTION_DEBUG_SINGLE) {
|
||
print_insn (host, dsp, "s ", 0);
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
/* XXX - should we do this, or can we get away with writing dsp? */
|
||
|
||
NCR53c7x0_write8 (DCNTL_REG, (NCR53c7x0_read8(DCNTL_REG) &
|
||
~DCNTL_SSM) | DCNTL_STD);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
} else {
|
||
printk(KERN_ALERT "scsi%d : unexpected single step interrupt at\n"
|
||
" ", host->host_no);
|
||
@@ -5127,7 +5065,7 @@
|
||
}
|
||
|
||
/*
|
||
- * Function : int NCR53c7xx_abort (Scsi_Cmnd *cmd)
|
||
+ * Function : int NCR53c7xx_abort (struct scsi_cmnd *cmd)
|
||
*
|
||
* Purpose : Abort an errant SCSI command, doing all necessary
|
||
* cleanup of the issue_queue, running_list, shared Linux/NCR
|
||
@@ -5139,14 +5077,14 @@
|
||
*/
|
||
|
||
int
|
||
-NCR53c7xx_abort (Scsi_Cmnd *cmd) {
|
||
+NCR53c7xx_abort (struct scsi_cmnd *cmd) {
|
||
NCR53c7x0_local_declare();
|
||
struct Scsi_Host *host = cmd->device->host;
|
||
struct NCR53c7x0_hostdata *hostdata = host ? (struct NCR53c7x0_hostdata *)
|
||
host->hostdata[0] : NULL;
|
||
unsigned long flags;
|
||
struct NCR53c7x0_cmd *curr, **prev;
|
||
- Scsi_Cmnd *me, **last;
|
||
+ struct scsi_cmnd *me, **last;
|
||
#if 0
|
||
static long cache_pid = -1;
|
||
#endif
|
||
@@ -5155,10 +5093,10 @@
|
||
if (!host) {
|
||
printk ("Bogus SCSI command pid %ld; no host structure\n",
|
||
cmd->pid);
|
||
- return SCSI_ABORT_ERROR;
|
||
+ return FAILED;
|
||
} else if (!hostdata) {
|
||
printk ("Bogus SCSI host %d; no hostdata\n", host->host_no);
|
||
- return SCSI_ABORT_ERROR;
|
||
+ return FAILED;
|
||
}
|
||
NCR53c7x0_local_setup(host);
|
||
|
||
@@ -5179,10 +5117,10 @@
|
||
printk ("scsi%d : dropped interrupt for command %ld\n", host->host_no,
|
||
cmd->pid);
|
||
NCR53c7x0_intr (host->irq, NULL, NULL);
|
||
- return SCSI_ABORT_BUSY;
|
||
+ return FAILED;
|
||
}
|
||
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
#if 0
|
||
if (cache_pid == cmd->pid)
|
||
panic ("scsi%d : bloody fetus %d\n", host->host_no, cmd->pid);
|
||
@@ -5201,13 +5139,13 @@
|
||
* pull the command out of the old queue, and call it aborted.
|
||
*/
|
||
|
||
- for (me = (Scsi_Cmnd *) hostdata->issue_queue,
|
||
- last = (Scsi_Cmnd **) &(hostdata->issue_queue);
|
||
- me && me != cmd; last = (Scsi_Cmnd **)&(me->SCp.ptr),
|
||
- me = (Scsi_Cmnd *)me->SCp.ptr);
|
||
+ for (me = (struct scsi_cmnd *) hostdata->issue_queue,
|
||
+ last = (struct scsi_cmnd **) &(hostdata->issue_queue);
|
||
+ me && me != cmd; last = (struct scsi_cmnd **)&(me->SCp.ptr),
|
||
+ me = (struct scsi_cmnd *)me->SCp.ptr);
|
||
|
||
if (me) {
|
||
- *last = (Scsi_Cmnd *) me->SCp.ptr;
|
||
+ *last = (struct scsi_cmnd *) me->SCp.ptr;
|
||
if (me->host_scribble) {
|
||
((struct NCR53c7x0_cmd *)me->host_scribble)->next = hostdata->free;
|
||
hostdata->free = (struct NCR53c7x0_cmd *) me->host_scribble;
|
||
@@ -5217,9 +5155,9 @@
|
||
cmd->scsi_done(cmd);
|
||
printk ("scsi%d : found command %ld in Linux issue queue\n",
|
||
host->host_no, me->pid);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
run_process_issue_queue();
|
||
- return SCSI_ABORT_SUCCESS;
|
||
+ return SUCCESS;
|
||
}
|
||
|
||
/*
|
||
@@ -5243,13 +5181,13 @@
|
||
cmd->scsi_done(cmd);
|
||
printk ("scsi%d : found finished command %ld in running list\n",
|
||
host->host_no, cmd->pid);
|
||
- local_irq_restore(flags);
|
||
- return SCSI_ABORT_NOT_RUNNING;
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
+ return SUCCESS;
|
||
} else {
|
||
printk ("scsi%d : DANGER : command running, can not abort.\n",
|
||
cmd->device->host->host_no);
|
||
- local_irq_restore(flags);
|
||
- return SCSI_ABORT_BUSY;
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
+ return FAILED;
|
||
}
|
||
}
|
||
|
||
@@ -5280,21 +5218,20 @@
|
||
*/
|
||
--hostdata->busy[cmd->device->id][cmd->device->lun];
|
||
}
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
cmd->scsi_done(cmd);
|
||
|
||
/*
|
||
* We need to run process_issue_queue since termination of this command
|
||
* may allow another queued command to execute first?
|
||
*/
|
||
- return SCSI_ABORT_NOT_RUNNING;
|
||
+ return SUCCESS;
|
||
}
|
||
|
||
/*
|
||
- * Function : int NCR53c7xx_reset (Scsi_Cmnd *cmd)
|
||
+ * Function : int NCR53c7xx_reset (struct scsi_cmnd *cmd)
|
||
*
|
||
- * Purpose : perform a hard reset of the SCSI bus and NCR
|
||
- * chip.
|
||
+ * Purpose : perform a hard reset of the SCSI bus.
|
||
*
|
||
* Inputs : cmd - command which caused the SCSI RESET
|
||
*
|
||
@@ -5302,12 +5239,12 @@
|
||
*/
|
||
|
||
int
|
||
-NCR53c7xx_reset (Scsi_Cmnd *cmd, unsigned int reset_flags) {
|
||
+NCR53c7xx_reset (struct scsi_cmnd *cmd) {
|
||
NCR53c7x0_local_declare();
|
||
unsigned long flags;
|
||
int found = 0;
|
||
struct NCR53c7x0_cmd * c;
|
||
- Scsi_Cmnd *tmp;
|
||
+ struct scsi_cmnd *tmp;
|
||
/*
|
||
* When we call scsi_done(), it's going to wake up anything sleeping on the
|
||
* resources which were in use by the aborted commands, and we'll start to
|
||
@@ -5322,19 +5259,19 @@
|
||
* pointer), do our reinitialization, and then call the done function for
|
||
* each command.
|
||
*/
|
||
- Scsi_Cmnd *nuke_list = NULL;
|
||
+ struct scsi_cmnd *nuke_list = NULL;
|
||
struct Scsi_Host *host = cmd->device->host;
|
||
struct NCR53c7x0_hostdata *hostdata =
|
||
(struct NCR53c7x0_hostdata *) host->hostdata[0];
|
||
|
||
NCR53c7x0_local_setup(host);
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
ncr_halt (host);
|
||
print_lots (host);
|
||
dump_events (host, 30);
|
||
ncr_scsi_reset (host);
|
||
for (tmp = nuke_list = return_outstanding_commands (host, 1 /* free */,
|
||
- 0 /* issue */ ); tmp; tmp = (Scsi_Cmnd *) tmp->SCp.buffer)
|
||
+ 0 /* issue */ ); tmp; tmp = (struct scsi_cmnd *) tmp->SCp.buffer)
|
||
if (tmp == cmd) {
|
||
found = 1;
|
||
break;
|
||
@@ -5357,19 +5294,21 @@
|
||
}
|
||
|
||
NCR53c7x0_driver_init (host);
|
||
+#if 0
|
||
hostdata->soft_reset (host);
|
||
+#endif
|
||
if (hostdata->resets == 0)
|
||
disable(host);
|
||
else if (hostdata->resets != -1)
|
||
--hostdata->resets;
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
for (; nuke_list; nuke_list = tmp) {
|
||
- tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer;
|
||
+ tmp = (struct scsi_cmnd *) nuke_list->SCp.buffer;
|
||
nuke_list->result = DID_RESET << 16;
|
||
nuke_list->scsi_done (nuke_list);
|
||
}
|
||
- local_irq_restore(flags);
|
||
- return SCSI_RESET_SUCCESS;
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
+ return SUCCESS;
|
||
}
|
||
|
||
/*
|
||
@@ -5378,7 +5317,7 @@
|
||
*/
|
||
|
||
/*
|
||
- * Function : int insn_to_offset (Scsi_Cmnd *cmd, u32 *insn)
|
||
+ * Function : int insn_to_offset (struct scsi_cmnd *cmd, u32 *insn)
|
||
*
|
||
* Purpose : convert instructions stored at NCR pointer into data
|
||
* pointer offset.
|
||
@@ -5391,7 +5330,7 @@
|
||
|
||
|
||
static int
|
||
-insn_to_offset (Scsi_Cmnd *cmd, u32 *insn) {
|
||
+insn_to_offset (struct scsi_cmnd *cmd, u32 *insn) {
|
||
struct NCR53c7x0_hostdata *hostdata =
|
||
(struct NCR53c7x0_hostdata *) cmd->device->host->hostdata[0];
|
||
struct NCR53c7x0_cmd *ncmd =
|
||
@@ -5445,7 +5384,7 @@
|
||
|
||
|
||
/*
|
||
- * Function : void print_progress (Scsi_Cmnd *cmd)
|
||
+ * Function : void print_progress (struct scsi_cmnd *cmd)
|
||
*
|
||
* Purpose : print the current location of the saved data pointer
|
||
*
|
||
@@ -5454,7 +5393,7 @@
|
||
*/
|
||
|
||
static void
|
||
-print_progress (Scsi_Cmnd *cmd) {
|
||
+print_progress (struct scsi_cmnd *cmd) {
|
||
NCR53c7x0_local_declare();
|
||
struct NCR53c7x0_cmd *ncmd =
|
||
(struct NCR53c7x0_cmd *) cmd->host_scribble;
|
||
@@ -5512,7 +5451,7 @@
|
||
host->hostdata[0];
|
||
int i, len;
|
||
char *ptr;
|
||
- Scsi_Cmnd *cmd;
|
||
+ struct scsi_cmnd *cmd;
|
||
|
||
if (check_address ((unsigned long) dsa, hostdata->dsa_end -
|
||
hostdata->dsa_start) == -1) {
|
||
@@ -5548,7 +5487,7 @@
|
||
|
||
printk(" + %d : select_indirect = 0x%x\n",
|
||
hostdata->dsa_select, dsa[hostdata->dsa_select / sizeof(u32)]);
|
||
- cmd = (Scsi_Cmnd *) bus_to_virt(dsa[hostdata->dsa_cmnd / sizeof(u32)]);
|
||
+ cmd = (struct scsi_cmnd *) bus_to_virt(dsa[hostdata->dsa_cmnd / sizeof(u32)]);
|
||
printk(" + %d : dsa_cmnd = 0x%x ", hostdata->dsa_cmnd,
|
||
(u32) virt_to_bus(cmd));
|
||
/* XXX Maybe we should access cmd->host_scribble->result here. RGH */
|
||
@@ -5588,16 +5527,16 @@
|
||
u32 *dsa, *next_dsa;
|
||
volatile u32 *ncrcurrent;
|
||
int left;
|
||
- Scsi_Cmnd *cmd, *next_cmd;
|
||
+ struct scsi_cmnd *cmd, *next_cmd;
|
||
unsigned long flags;
|
||
|
||
printk ("scsi%d : issue queue\n", host->host_no);
|
||
|
||
- for (left = host->can_queue, cmd = (Scsi_Cmnd *) hostdata->issue_queue;
|
||
+ for (left = host->can_queue, cmd = (struct scsi_cmnd *) hostdata->issue_queue;
|
||
left >= 0 && cmd;
|
||
cmd = next_cmd) {
|
||
- next_cmd = (Scsi_Cmnd *) cmd->SCp.ptr;
|
||
- local_irq_save(flags);
|
||
+ next_cmd = (struct scsi_cmnd *) cmd->SCp.ptr;
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
if (cmd->host_scribble) {
|
||
if (check_address ((unsigned long) (cmd->host_scribble),
|
||
sizeof (cmd->host_scribble)) == -1)
|
||
@@ -5610,7 +5549,7 @@
|
||
} else
|
||
printk ("scsi%d : scsi pid %ld for target %d lun %d has no NCR53c7x0_cmd\n",
|
||
host->host_no, cmd->pid, cmd->device->id, cmd->device->lun);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
}
|
||
|
||
if (left <= 0) {
|
||
@@ -5642,7 +5581,7 @@
|
||
dsa = bus_to_virt (hostdata->reconnect_dsa_head);
|
||
left >= 0 && dsa;
|
||
dsa = next_dsa) {
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
if (check_address ((unsigned long) dsa, sizeof(dsa)) == -1) {
|
||
printk ("scsi%d: bad DSA pointer 0x%p", host->host_no,
|
||
dsa);
|
||
@@ -5653,7 +5592,7 @@
|
||
next_dsa = bus_to_virt(dsa[hostdata->dsa_next / sizeof(u32)]);
|
||
print_dsa (host, dsa, "");
|
||
}
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
}
|
||
printk ("scsi%d : end reconnect_dsa_head\n", host->host_no);
|
||
if (left < 0)
|
||
@@ -5743,14 +5682,14 @@
|
||
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
|
||
host->hostdata[0];
|
||
NCR53c7x0_local_setup(host);
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
/* Get in a state where we can reset the SCSI bus */
|
||
ncr_halt (host);
|
||
ncr_scsi_reset (host);
|
||
hostdata->soft_reset(host);
|
||
|
||
disable (host);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return 0;
|
||
}
|
||
|
||
@@ -5765,11 +5704,11 @@
|
||
NCR53c7x0_local_declare();
|
||
unsigned long flags;
|
||
NCR53c7x0_local_setup(host);
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
|
||
udelay(25); /* Minimum amount of time to assert RST */
|
||
NCR53c7x0_write8(SCNTL1_REG, 0);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
}
|
||
|
||
/*
|
||
@@ -5782,26 +5721,26 @@
|
||
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
|
||
host->hostdata[0];
|
||
unsigned long flags;
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
ncr_scsi_reset(host);
|
||
NCR53c7x0_driver_init (host);
|
||
if (hostdata->soft_reset)
|
||
hostdata->soft_reset (host);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
}
|
||
|
||
|
||
/*
|
||
- * Function : Scsi_Cmnd *return_outstanding_commands (struct Scsi_Host *host,
|
||
+ * Function : struct scsi_cmnd *return_outstanding_commands (struct Scsi_Host *host,
|
||
* int free, int issue)
|
||
*
|
||
* Purpose : return a linked list (using the SCp.buffer field as next,
|
||
* so we don't perturb hostdata. We don't use a field of the
|
||
* NCR53c7x0_cmd structure since we may not have allocated one
|
||
- * for the command causing the reset.) of Scsi_Cmnd structures that
|
||
+ * for the command causing the reset.) of scsi_cmnd structures that
|
||
* had propagated below the Linux issue queue level. If free is set,
|
||
* free the NCR53c7x0_cmd structures which are associated with
|
||
- * the Scsi_Cmnd structures, and clean up any internal
|
||
+ * the scsi_cmnd structures, and clean up any internal
|
||
* NCR lists that the commands were on. If issue is set,
|
||
* also return commands in the issue queue.
|
||
*
|
||
@@ -5811,14 +5750,14 @@
|
||
* if the free flag is set.
|
||
*/
|
||
|
||
-static Scsi_Cmnd *
|
||
+static struct scsi_cmnd *
|
||
return_outstanding_commands (struct Scsi_Host *host, int free, int issue) {
|
||
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
|
||
host->hostdata[0];
|
||
struct NCR53c7x0_cmd *c;
|
||
int i;
|
||
u32 *ncrcurrent;
|
||
- Scsi_Cmnd *list = NULL, *tmp;
|
||
+ struct scsi_cmnd *list = NULL, *tmp, *next_cmd;
|
||
for (c = (struct NCR53c7x0_cmd *) hostdata->running_list; c;
|
||
c = (struct NCR53c7x0_cmd *) c->next) {
|
||
if (c->cmd->SCp.buffer) {
|
||
@@ -5847,7 +5786,9 @@
|
||
}
|
||
|
||
if (issue) {
|
||
- for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp; tmp = tmp->next) {
|
||
+ for (tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp; tmp = next_cmd) {
|
||
+ next_cmd = (struct scsi_cmnd *) tmp->SCp.ptr;
|
||
+
|
||
if (tmp->SCp.buffer) {
|
||
printk ("scsi%d : loop detected in issue queue!\n",
|
||
host->host_no);
|
||
@@ -5882,17 +5823,17 @@
|
||
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
|
||
host->hostdata[0];
|
||
unsigned long flags;
|
||
- Scsi_Cmnd *nuke_list, *tmp;
|
||
- local_irq_save(flags);
|
||
+ struct scsi_cmnd *nuke_list, *tmp;
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
if (hostdata->state != STATE_HALTED)
|
||
ncr_halt (host);
|
||
nuke_list = return_outstanding_commands (host, 1 /* free */, 1 /* issue */);
|
||
hard_reset (host);
|
||
hostdata->state = STATE_DISABLED;
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
printk ("scsi%d : nuking commands\n", host->host_no);
|
||
for (; nuke_list; nuke_list = tmp) {
|
||
- tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer;
|
||
+ tmp = (struct scsi_cmnd *) nuke_list->SCp.buffer;
|
||
nuke_list->result = DID_ERROR << 16;
|
||
nuke_list->scsi_done(nuke_list);
|
||
}
|
||
@@ -5922,7 +5863,7 @@
|
||
int stage;
|
||
NCR53c7x0_local_setup(host);
|
||
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
/* Stage 0 : eat all interrupts
|
||
Stage 1 : set ABORT
|
||
Stage 2 : eat all but abort interrupts
|
||
@@ -5957,7 +5898,7 @@
|
||
}
|
||
}
|
||
hostdata->state = STATE_HALTED;
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
#if 0
|
||
print_lots (host);
|
||
#endif
|
||
@@ -6011,7 +5952,7 @@
|
||
* still be guaranteed that they're happening on the same
|
||
* event structure.
|
||
*/
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
#if 0
|
||
event = hostdata->events[i];
|
||
#else
|
||
@@ -6019,7 +5960,7 @@
|
||
sizeof(event));
|
||
#endif
|
||
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
printk ("scsi%d : %s event %d at %ld secs %ld usecs target %d lun %d\n",
|
||
host->host_no, event_name (event.event), count,
|
||
(long) event.time.tv_sec, (long) event.time.tv_usec,
|
||
@@ -6054,6 +5995,72 @@
|
||
return (virt_to_phys((void *)addr) < PAGE_SIZE || virt_to_phys((void *)(addr + size)) > virt_to_phys(high_memory) ? -1 : 0);
|
||
}
|
||
|
||
+int
|
||
+NCR53c7xx_slave_configure(struct scsi_device *sdev) {
|
||
+ struct Scsi_Host *host = sdev->host;
|
||
+ struct NCR53c7x0_hostdata *hostdata =
|
||
+ (struct NCR53c7x0_hostdata *) host->hostdata[0];
|
||
+ struct NCR53c7x0_cmd *tmp;
|
||
+ u32 real; /* Real address */
|
||
+ int size; /* Size of *tmp */
|
||
+ unsigned long flags;
|
||
+ int extra_allocate = 0;
|
||
+
|
||
+/*
|
||
+ * Reserve commands for this I_T_L nexus.
|
||
+ */
|
||
+ if (hostdata->num_cmds < host->can_queue)
|
||
+ extra_allocate = host->cmd_per_lun;
|
||
+
|
||
+ for (; extra_allocate > 0 ; --extra_allocate,
|
||
+ ++hostdata->num_cmds) {
|
||
+ /* historically, kmalloc has returned unaligned addresses; pad so we
|
||
+ have enough room to ROUNDUP */
|
||
+ size = hostdata->max_cmd_size + sizeof (void *);
|
||
+#ifdef FORCE_DSA_ALIGNMENT
|
||
+ /*
|
||
+ * 53c710 rev.0 doesn't have an add-with-carry instruction.
|
||
+ * Ensure we allocate enough memory to force alignment.
|
||
+ */
|
||
+ size += 256;
|
||
+#endif
|
||
+/* FIXME: for ISA bus '7xx chips, we need to or GFP_DMA in here */
|
||
+
|
||
+ if (size > 4096) {
|
||
+ printk (KERN_ERR "53c7xx: slave_configure size > 4K\n");
|
||
+ return -ENOMEM;
|
||
+ }
|
||
+ real = get_zeroed_page(GFP_ATOMIC);
|
||
+ if (real == 0)
|
||
+ return -ENOMEM;
|
||
+ memset((void *)real, 0, 4096);
|
||
+ cache_push(virt_to_phys((void *)real), 4096);
|
||
+ cache_clear(virt_to_phys((void *)real), 4096);
|
||
+ kernel_set_cachemode((void *)real, 4096, IOMAP_NOCACHE_SER);
|
||
+ tmp = ROUNDUP(real, void *);
|
||
+#ifdef FORCE_DSA_ALIGNMENT
|
||
+ {
|
||
+ if (((u32)tmp & 0xff) > CmdPageStart)
|
||
+ tmp = (struct NCR53c7x0_cmd *)((u32)tmp + 255);
|
||
+ tmp = (struct NCR53c7x0_cmd *)(((u32)tmp & ~0xff) + CmdPageStart);
|
||
+#if 0
|
||
+ printk ("scsi: size = %d, real = 0x%08x, tmp set to 0x%08x\n",
|
||
+ size, real, (u32)tmp);
|
||
+#endif
|
||
+ }
|
||
+#endif
|
||
+ tmp->real = (void *)real;
|
||
+ tmp->size = size;
|
||
+ tmp->free = ((void (*)(void *, int)) my_free_page);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
+ tmp->next = hostdata->free;
|
||
+ hostdata->free = tmp;
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
+ }
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
#ifdef MODULE
|
||
int
|
||
NCR53c7x0_release(struct Scsi_Host *host) {
|
||
@@ -6063,19 +6070,22 @@
|
||
shutdown (host);
|
||
if (host->irq != SCSI_IRQ_NONE)
|
||
{
|
||
- int irq_count;
|
||
- struct Scsi_Host *tmp;
|
||
- for (irq_count = 0, tmp = first_host; tmp; tmp = tmp->next)
|
||
- if (tmp->hostt == the_template && tmp->irq == host->irq)
|
||
+ int irq_count = 0;
|
||
+ struct Scsi_Host *tmp, *s;
|
||
+ list_for_each_entry_safe(tmp, s, &the_template->legacy_hosts, sht_legacy_list) {
|
||
+ if (tmp->irq == host->irq)
|
||
++irq_count;
|
||
+ }
|
||
if (irq_count == 1)
|
||
free_irq(host->irq, NULL);
|
||
}
|
||
+#ifdef CONFIG_ISA
|
||
if (host->dma_channel != DMA_NONE)
|
||
free_dma(host->dma_channel);
|
||
+#endif
|
||
if (host->io_port)
|
||
release_region(host->io_port, host->n_io_port);
|
||
-
|
||
+
|
||
for (cmd = (struct NCR53c7x0_cmd *) hostdata->free; cmd; cmd = tmp,
|
||
--hostdata->num_cmds) {
|
||
tmp = (struct NCR53c7x0_cmd *) cmd->next;
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/53c7xx.h linux-m68k/drivers/scsi/53c7xx.h
|
||
--- linux-i386/drivers/scsi/53c7xx.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/53c7xx.h 2004-10-30 14:41:36.000000000 +0200
|
||
@@ -997,7 +997,7 @@
|
||
u32 *dsa; /* What's in the DSA register now (virt) */
|
||
/*
|
||
* A few things from that SCSI pid so we know what happened after
|
||
- * the Scsi_Cmnd structure in question may have disappeared.
|
||
+ * the scsi_cmnd structure in question may have disappeared.
|
||
*/
|
||
unsigned long pid; /* The SCSI PID which caused this
|
||
event */
|
||
@@ -1029,8 +1029,8 @@
|
||
void (* free)(void *, int); /* Command to deallocate; NULL
|
||
for structures allocated with
|
||
scsi_register, etc. */
|
||
- Scsi_Cmnd *cmd; /* Associated Scsi_Cmnd
|
||
- structure, Scsi_Cmnd points
|
||
+ struct scsi_cmnd *cmd; /* Associated scsi_cmnd
|
||
+ structure, scsi_cmnd points
|
||
at NCR53c7x0_cmd using
|
||
host_scribble structure */
|
||
|
||
@@ -1039,8 +1039,8 @@
|
||
|
||
int flags; /* CMD_* flags */
|
||
|
||
- unsigned char cmnd[12]; /* CDB, copied from Scsi_Cmnd */
|
||
- int result; /* Copy to Scsi_Cmnd when done */
|
||
+ unsigned char cmnd[12]; /* CDB, copied from scsi_cmnd */
|
||
+ int result; /* Copy to scsi_cmnd when done */
|
||
|
||
struct { /* Private non-cached bounce buffer */
|
||
unsigned char buf[256];
|
||
@@ -1339,7 +1339,7 @@
|
||
volatile struct NCR53c7x0_synchronous sync[16]
|
||
__attribute__ ((aligned (4)));
|
||
|
||
- volatile Scsi_Cmnd *issue_queue
|
||
+ volatile struct scsi_cmnd *issue_queue
|
||
__attribute__ ((aligned (4)));
|
||
/* waiting to be issued by
|
||
Linux driver */
|
||
@@ -1363,10 +1363,6 @@
|
||
*/
|
||
volatile int num_cmds; /* Number of commands
|
||
allocated */
|
||
- volatile int extra_allocate;
|
||
- volatile unsigned char cmd_allocated[16]; /* Have we allocated commands
|
||
- for this target yet? If not,
|
||
- do so ASAP */
|
||
volatile unsigned char busy[16][8]; /* number of commands
|
||
executing on each target
|
||
*/
|
||
@@ -1589,11 +1585,11 @@
|
||
/* Patch field in dsa structure (assignment should be +=?) */
|
||
#define patch_dsa_32(dsa, symbol, word, value) \
|
||
{ \
|
||
- (dsa)[(hostdata->##symbol - hostdata->dsa_start) / sizeof(u32) \
|
||
+ (dsa)[(hostdata->symbol - hostdata->dsa_start) / sizeof(u32) \
|
||
+ (word)] = (value); \
|
||
if (hostdata->options & OPTION_DEBUG_DSA) \
|
||
printk("scsi : dsa %s symbol %s(%d) word %d now 0x%x\n", \
|
||
- #dsa, #symbol, hostdata->##symbol, \
|
||
+ #dsa, #symbol, hostdata->symbol, \
|
||
(word), (u32) (value)); \
|
||
}
|
||
|
||
@@ -1603,6 +1599,12 @@
|
||
extern int ncr53c7xx_init(struct scsi_host_template *tpnt, int board, int chip,
|
||
unsigned long base, int io_port, int irq, int dma,
|
||
long long options, int clock);
|
||
+extern const char *NCR53c7x0_info(void);
|
||
+extern int NCR53c7xx_queue_command(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *));
|
||
+extern int NCR53c7xx_abort(struct scsi_cmnd *);
|
||
+extern int NCR53c7x0_release (struct Scsi_Host *);
|
||
+extern int NCR53c7xx_reset(struct scsi_cmnd *);
|
||
+extern int NCR53c7xx_slave_configure(struct scsi_device *);
|
||
|
||
#endif /* NCR53c710_C */
|
||
#endif /* NCR53c710_H */
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/Kconfig linux-m68k/drivers/scsi/Kconfig
|
||
--- linux-i386/drivers/scsi/Kconfig 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/Kconfig 2006-09-24 16:33:34.000000000 +0200
|
||
@@ -1671,7 +1671,7 @@
|
||
|
||
config SCSI_AMIGA7XX
|
||
bool "Amiga NCR53c710 SCSI support (EXPERIMENTAL)"
|
||
- depends on AMIGA && SCSI && EXPERIMENTAL && BROKEN
|
||
+ depends on AMIGA && SCSI && EXPERIMENTAL
|
||
help
|
||
Support for various NCR53c710-based SCSI controllers on the Amiga.
|
||
This includes:
|
||
@@ -1771,7 +1771,7 @@
|
||
|
||
config MVME16x_SCSI
|
||
bool "NCR53C710 SCSI driver for MVME16x"
|
||
- depends on MVME16x && SCSI && BROKEN
|
||
+ depends on MVME16x && SCSI
|
||
select SCSI_SPI_ATTRS
|
||
help
|
||
The Motorola MVME162, 166, 167, 172 and 177 boards use the NCR53C710
|
||
@@ -1780,7 +1780,7 @@
|
||
|
||
config BVME6000_SCSI
|
||
bool "NCR53C710 SCSI driver for BVME6000"
|
||
- depends on BVME6000 && SCSI && BROKEN
|
||
+ depends on BVME6000 && SCSI
|
||
select SCSI_SPI_ATTRS
|
||
help
|
||
The BVME4000 and BVME6000 boards from BVM Ltd use the NCR53C710
|
||
@@ -1797,7 +1797,7 @@
|
||
|
||
config SUN3_SCSI
|
||
tristate "Sun3 NCR5380 SCSI"
|
||
- depends on SUN3 && SCSI && BROKEN
|
||
+ depends on SUN3 && SCSI
|
||
select SCSI_SPI_ATTRS
|
||
help
|
||
This option will enable support for the OBIO (onboard io) NCR5380
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/NCR5380.c linux-m68k/drivers/scsi/NCR5380.c
|
||
--- linux-i386/drivers/scsi/NCR5380.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/NCR5380.c 2006-09-24 16:33:34.000000000 +0200
|
||
@@ -354,6 +354,7 @@
|
||
return -ETIMEDOUT;
|
||
}
|
||
|
||
+#if NDEBUG
|
||
static struct {
|
||
unsigned char value;
|
||
const char *name;
|
||
@@ -367,7 +368,6 @@
|
||
{PHASE_UNKNOWN, "UNKNOWN"}
|
||
};
|
||
|
||
-#if NDEBUG
|
||
static struct {
|
||
unsigned char mask;
|
||
const char *name;
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/amiga7xx.c linux-m68k/drivers/scsi/amiga7xx.c
|
||
--- linux-i386/drivers/scsi/amiga7xx.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/amiga7xx.c 2006-09-24 16:33:34.000000000 +0200
|
||
@@ -25,8 +25,14 @@
|
||
#include "scsi.h"
|
||
#include <scsi/scsi_host.h>
|
||
#include "53c7xx.h"
|
||
-#include "amiga7xx.h"
|
||
|
||
+#ifndef CMD_PER_LUN
|
||
+#define CMD_PER_LUN 3
|
||
+#endif
|
||
+
|
||
+#ifndef CAN_QUEUE
|
||
+#define CAN_QUEUE 24
|
||
+#endif
|
||
|
||
static int amiga7xx_register_one(struct scsi_host_template *tpnt,
|
||
unsigned long address)
|
||
@@ -113,8 +119,10 @@
|
||
{
|
||
if (shost->irq)
|
||
free_irq(shost->irq, NULL);
|
||
+#ifdef CONFIG_ISA
|
||
if (shost->dma_channel != 0xff)
|
||
free_dma(shost->dma_channel);
|
||
+#endif
|
||
if (shost->io_port && shost->n_io_port)
|
||
release_region(shost->io_port, shost->n_io_port);
|
||
scsi_unregister(shost);
|
||
@@ -126,8 +134,9 @@
|
||
.detect = amiga7xx_detect,
|
||
.release = amiga7xx_release,
|
||
.queuecommand = NCR53c7xx_queue_command,
|
||
- .abort = NCR53c7xx_abort,
|
||
- .reset = NCR53c7xx_reset,
|
||
+ .eh_abort_handler = NCR53c7xx_abort,
|
||
+ .eh_bus_reset_handler = NCR53c7xx_reset,
|
||
+ .slave_configure = NCR53c7xx_slave_configure,
|
||
.can_queue = 24,
|
||
.this_id = 7,
|
||
.sg_tablesize = 63,
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/amiga7xx.h linux-m68k/drivers/scsi/amiga7xx.h
|
||
--- linux-i386/drivers/scsi/amiga7xx.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/amiga7xx.h 1970-01-01 01:00:00.000000000 +0100
|
||
@@ -1,23 +0,0 @@
|
||
-#ifndef AMIGA7XX_H
|
||
-
|
||
-#include <linux/types.h>
|
||
-
|
||
-int amiga7xx_detect(struct scsi_host_template *);
|
||
-const char *NCR53c7x0_info(void);
|
||
-int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
|
||
-int NCR53c7xx_abort(Scsi_Cmnd *);
|
||
-int NCR53c7x0_release (struct Scsi_Host *);
|
||
-int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int);
|
||
-void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
|
||
-
|
||
-#ifndef CMD_PER_LUN
|
||
-#define CMD_PER_LUN 3
|
||
-#endif
|
||
-
|
||
-#ifndef CAN_QUEUE
|
||
-#define CAN_QUEUE 24
|
||
-#endif
|
||
-
|
||
-#include <scsi/scsicam.h>
|
||
-
|
||
-#endif /* AMIGA7XX_H */
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/bvme6000.c linux-m68k/drivers/scsi/bvme6000.c
|
||
--- linux-i386/drivers/scsi/bvme6000.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/bvme6000.c 2006-01-15 02:01:21.000000000 +0100
|
||
@@ -18,10 +18,16 @@
|
||
#include "scsi.h"
|
||
#include <scsi/scsi_host.h>
|
||
#include "53c7xx.h"
|
||
-#include "bvme6000.h"
|
||
|
||
#include<linux/stat.h>
|
||
|
||
+#ifndef CMD_PER_LUN
|
||
+#define CMD_PER_LUN 3
|
||
+#endif
|
||
+
|
||
+#ifndef CAN_QUEUE
|
||
+#define CAN_QUEUE 24
|
||
+#endif
|
||
|
||
int bvme6000_scsi_detect(struct scsi_host_template *tpnt)
|
||
{
|
||
@@ -51,8 +57,10 @@
|
||
{
|
||
if (shost->irq)
|
||
free_irq(shost->irq, NULL);
|
||
+#ifdef CONFIG_ISA
|
||
if (shost->dma_channel != 0xff)
|
||
free_dma(shost->dma_channel);
|
||
+#endif
|
||
if (shost->io_port && shost->n_io_port)
|
||
release_region(shost->io_port, shost->n_io_port);
|
||
scsi_unregister(shost);
|
||
@@ -64,8 +72,9 @@
|
||
.detect = bvme6000_scsi_detect,
|
||
.release = bvme6000_scsi_release,
|
||
.queuecommand = NCR53c7xx_queue_command,
|
||
- .abort = NCR53c7xx_abort,
|
||
- .reset = NCR53c7xx_reset,
|
||
+ .eh_abort_handler = NCR53c7xx_abort,
|
||
+ .eh_bus_reset_handler = NCR53c7xx_reset,
|
||
+ .slave_configure = NCR53c7xx_slave_configure,
|
||
.can_queue = 24,
|
||
.this_id = 7,
|
||
.sg_tablesize = 63,
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/bvme6000.h linux-m68k/drivers/scsi/bvme6000.h
|
||
--- linux-i386/drivers/scsi/bvme6000.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/bvme6000.h 1970-01-01 01:00:00.000000000 +0100
|
||
@@ -1,24 +0,0 @@
|
||
-#ifndef BVME6000_SCSI_H
|
||
-#define BVME6000_SCSI_H
|
||
-
|
||
-#include <linux/types.h>
|
||
-
|
||
-int bvme6000_scsi_detect(struct scsi_host_template *);
|
||
-const char *NCR53c7x0_info(void);
|
||
-int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
|
||
-int NCR53c7xx_abort(Scsi_Cmnd *);
|
||
-int NCR53c7x0_release (struct Scsi_Host *);
|
||
-int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int);
|
||
-void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
|
||
-
|
||
-#ifndef CMD_PER_LUN
|
||
-#define CMD_PER_LUN 3
|
||
-#endif
|
||
-
|
||
-#ifndef CAN_QUEUE
|
||
-#define CAN_QUEUE 24
|
||
-#endif
|
||
-
|
||
-#include <scsi/scsicam.h>
|
||
-
|
||
-#endif /* BVME6000_SCSI_H */
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/mvme16x.c linux-m68k/drivers/scsi/mvme16x.c
|
||
--- linux-i386/drivers/scsi/mvme16x.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/mvme16x.c 2006-01-15 02:01:22.000000000 +0100
|
||
@@ -16,10 +16,16 @@
|
||
#include "scsi.h"
|
||
#include <scsi/scsi_host.h>
|
||
#include "53c7xx.h"
|
||
-#include "mvme16x.h"
|
||
|
||
#include<linux/stat.h>
|
||
|
||
+#ifndef CMD_PER_LUN
|
||
+#define CMD_PER_LUN 3
|
||
+#endif
|
||
+
|
||
+#ifndef CAN_QUEUE
|
||
+#define CAN_QUEUE 24
|
||
+#endif
|
||
|
||
int mvme16x_scsi_detect(struct scsi_host_template *tpnt)
|
||
{
|
||
@@ -53,8 +59,10 @@
|
||
{
|
||
if (shost->irq)
|
||
free_irq(shost->irq, NULL);
|
||
+#ifdef CONFIG_ISA
|
||
if (shost->dma_channel != 0xff)
|
||
free_dma(shost->dma_channel);
|
||
+#endif
|
||
if (shost->io_port && shost->n_io_port)
|
||
release_region(shost->io_port, shost->n_io_port);
|
||
scsi_unregister(shost);
|
||
@@ -66,8 +74,9 @@
|
||
.detect = mvme16x_scsi_detect,
|
||
.release = mvme16x_scsi_release,
|
||
.queuecommand = NCR53c7xx_queue_command,
|
||
- .abort = NCR53c7xx_abort,
|
||
- .reset = NCR53c7xx_reset,
|
||
+ .eh_abort_handler = NCR53c7xx_abort,
|
||
+ .eh_bus_reset_handler = NCR53c7xx_reset,
|
||
+ .slave_configure = NCR53c7xx_slave_configure,
|
||
.can_queue = 24,
|
||
.this_id = 7,
|
||
.sg_tablesize = 63,
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/mvme16x.h linux-m68k/drivers/scsi/mvme16x.h
|
||
--- linux-i386/drivers/scsi/mvme16x.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/mvme16x.h 1970-01-01 01:00:00.000000000 +0100
|
||
@@ -1,24 +0,0 @@
|
||
-#ifndef MVME16x_SCSI_H
|
||
-#define MVME16x_SCSI_H
|
||
-
|
||
-#include <linux/types.h>
|
||
-
|
||
-int mvme16x_scsi_detect(struct scsi_host_template *);
|
||
-const char *NCR53c7x0_info(void);
|
||
-int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
|
||
-int NCR53c7xx_abort(Scsi_Cmnd *);
|
||
-int NCR53c7x0_release (struct Scsi_Host *);
|
||
-int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int);
|
||
-void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
|
||
-
|
||
-#ifndef CMD_PER_LUN
|
||
-#define CMD_PER_LUN 3
|
||
-#endif
|
||
-
|
||
-#ifndef CAN_QUEUE
|
||
-#define CAN_QUEUE 24
|
||
-#endif
|
||
-
|
||
-#include <scsi/scsicam.h>
|
||
-
|
||
-#endif /* MVME16x_SCSI_H */
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/sun3_NCR5380.c linux-m68k/drivers/scsi/sun3_NCR5380.c
|
||
--- linux-i386/drivers/scsi/sun3_NCR5380.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/sun3_NCR5380.c 2006-09-24 16:33:37.000000000 +0200
|
||
@@ -1268,7 +1268,7 @@
|
||
NCR_PRINT(NDEBUG_INTR);
|
||
if ((NCR5380_read(STATUS_REG) & (SR_SEL|SR_IO)) == (SR_SEL|SR_IO)) {
|
||
done = 0;
|
||
- ENABLE_IRQ();
|
||
+// ENABLE_IRQ();
|
||
INT_PRINTK("scsi%d: SEL interrupt\n", HOSTNO);
|
||
NCR5380_reselect(instance);
|
||
(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
|
||
@@ -1301,7 +1301,7 @@
|
||
INT_PRINTK("scsi%d: PHASE MISM or EOP interrupt\n", HOSTNO);
|
||
NCR5380_dma_complete( instance );
|
||
done = 0;
|
||
- ENABLE_IRQ();
|
||
+// ENABLE_IRQ();
|
||
} else
|
||
#endif /* REAL_DMA */
|
||
{
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/sun3_scsi.c linux-m68k/drivers/scsi/sun3_scsi.c
|
||
--- linux-i386/drivers/scsi/sun3_scsi.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/sun3_scsi.c 2006-05-11 13:16:27.000000000 +0200
|
||
@@ -75,9 +75,9 @@
|
||
#define REAL_DMA
|
||
|
||
#include "scsi.h"
|
||
+#include "initio.h"
|
||
#include <scsi/scsi_host.h>
|
||
#include "sun3_scsi.h"
|
||
-#include "NCR5380.h"
|
||
|
||
static void NCR5380_print(struct Scsi_Host *instance);
|
||
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/sun3_scsi.h linux-m68k/drivers/scsi/sun3_scsi.h
|
||
--- linux-i386/drivers/scsi/sun3_scsi.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/sun3_scsi.h 2006-05-11 13:16:27.000000000 +0200
|
||
@@ -220,7 +220,7 @@
|
||
*
|
||
*/
|
||
|
||
-
|
||
+#include "NCR5380.h"
|
||
|
||
#if NDEBUG & NDEBUG_ARBITRATION
|
||
#define ARB_PRINTK(format, args...) \
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/sun3_scsi_vme.c linux-m68k/drivers/scsi/sun3_scsi_vme.c
|
||
--- linux-i386/drivers/scsi/sun3_scsi_vme.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/sun3_scsi_vme.c 2006-05-11 13:16:27.000000000 +0200
|
||
@@ -41,9 +41,9 @@
|
||
#define REAL_DMA
|
||
|
||
#include "scsi.h"
|
||
+#include "initio.h"
|
||
#include <scsi/scsi_host.h>
|
||
#include "sun3_scsi.h"
|
||
-#include "NCR5380.h"
|
||
|
||
extern int sun3_map_test(unsigned long, char *);
|
||
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/fs/fat/inode.c linux-m68k/fs/fat/inode.c
|
||
--- linux-i386/fs/fat/inode.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/fs/fat/inode.c 2006-09-24 16:34:00.000000000 +0200
|
||
@@ -11,12 +11,14 @@
|
||
*/
|
||
|
||
#include <linux/module.h>
|
||
+#include <linux/config.h>
|
||
#include <linux/init.h>
|
||
#include <linux/time.h>
|
||
#include <linux/slab.h>
|
||
#include <linux/smp_lock.h>
|
||
#include <linux/seq_file.h>
|
||
#include <linux/msdos_fs.h>
|
||
+#include <linux/major.h>
|
||
#include <linux/pagemap.h>
|
||
#include <linux/mpage.h>
|
||
#include <linux/buffer_head.h>
|
||
@@ -857,7 +859,7 @@
|
||
Opt_check_n, Opt_check_r, Opt_check_s, Opt_uid, Opt_gid,
|
||
Opt_umask, Opt_dmask, Opt_fmask, Opt_codepage, Opt_nocase,
|
||
Opt_quiet, Opt_showexec, Opt_debug, Opt_immutable,
|
||
- Opt_dots, Opt_nodots,
|
||
+ Opt_dots, Opt_nodots, Opt_atari_no, Opt_atari_yes,
|
||
Opt_charset, Opt_shortname_lower, Opt_shortname_win95,
|
||
Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes,
|
||
Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes,
|
||
@@ -882,6 +884,9 @@
|
||
{Opt_showexec, "showexec"},
|
||
{Opt_debug, "debug"},
|
||
{Opt_immutable, "sys_immutable"},
|
||
+ {Opt_atari_yes, "atari=yes"},
|
||
+ {Opt_atari_yes, "atari"},
|
||
+ {Opt_atari_no, "atari=no"},
|
||
{Opt_obsolate, "conv=binary"},
|
||
{Opt_obsolate, "conv=text"},
|
||
{Opt_obsolate, "conv=auto"},
|
||
@@ -956,6 +961,13 @@
|
||
opts->utf8 = opts->unicode_xlate = 0;
|
||
opts->numtail = 1;
|
||
opts->nocase = 0;
|
||
+ opts->atari = 0;
|
||
+
|
||
+#ifdef CONFIG_ATARI
|
||
+ if(MACH_IS_ATARI)
|
||
+ /* make Atari GEMDOS format the default if machine is an Atari */
|
||
+ opts->atari = 1;
|
||
+#endif
|
||
*debug = 0;
|
||
|
||
if (!options)
|
||
@@ -1004,6 +1016,12 @@
|
||
case Opt_immutable:
|
||
opts->sys_immutable = 1;
|
||
break;
|
||
+ case Opt_atari_yes:
|
||
+ opts->atari = 1;
|
||
+ break;
|
||
+ case Opt_atari_no:
|
||
+ opts->atari = 0;
|
||
+ break;
|
||
case Opt_uid:
|
||
if (match_int(&args[0], &option))
|
||
return 0;
|
||
@@ -1339,8 +1357,31 @@
|
||
|
||
total_clusters = (total_sectors - sbi->data_start) / sbi->sec_per_clus;
|
||
|
||
- if (sbi->fat_bits != 32)
|
||
- sbi->fat_bits = (total_clusters > MAX_FAT12) ? 16 : 12;
|
||
+ if (!sbi->options.atari) {
|
||
+ if (sbi->fat_bits != 32)
|
||
+ sbi->fat_bits = (total_clusters > MAX_FAT12) ? 16 : 12;
|
||
+ } else {
|
||
+ int sectors;
|
||
+ /* Atari GEMDOS partitions always have 16-bit fat */
|
||
+ if (sbi->fat_bits != 32)
|
||
+ sbi->fat_bits = 16;
|
||
+ /* If more clusters than fat entries in 16-bit fat, we assume
|
||
+ * it's a real MSDOS partition with 12-bit fat.
|
||
+ */
|
||
+ if (sbi->fat_bits != 32 && total_clusters+2 > sbi->
|
||
+ fat_length*SECTOR_SIZE*8/sbi->fat_bits)
|
||
+ sbi->fat_bits = 12;
|
||
+ /* if it's a floppy disk --> 12bit fat */
|
||
+ if (sbi->fat_bits != 32 && MAJOR(sb->s_dev) == FLOPPY_MAJOR)
|
||
+ sbi->fat_bits = 12;
|
||
+ /* if it's a ramdisk or loopback device and has one of the usual
|
||
+ * floppy sizes -> 12bit FAT */
|
||
+ sectors = total_sectors + sbi->data_start;
|
||
+ if (sbi->fat_bits != 32 && (MAJOR(sb->s_dev) == RAMDISK_MAJOR ||
|
||
+ MAJOR(sb->s_dev) == LOOP_MAJOR) &&
|
||
+ (sectors == 720 || sectors == 1440 || sectors == 2880))
|
||
+ sbi->fat_bits = 12;
|
||
+ }
|
||
|
||
/* check that FAT table does not overflow */
|
||
fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/io.h linux-m68k/include/asm-m68k/io.h
|
||
--- linux-i386/include/asm-m68k/io.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/io.h 2006-09-24 16:34:33.000000000 +0200
|
||
@@ -324,8 +324,6 @@
|
||
#define writel(val,addr) out_le32((addr),(val))
|
||
#endif
|
||
|
||
-#define mmiowb()
|
||
-
|
||
static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size)
|
||
{
|
||
return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/irq.h linux-m68k/include/asm-m68k/irq.h
|
||
--- linux-i386/include/asm-m68k/irq.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/irq.h 2006-09-24 16:34:33.000000000 +0200
|
||
@@ -2,7 +2,6 @@
|
||
#define _M68K_IRQ_H_
|
||
|
||
#include <linux/linkage.h>
|
||
-#include <linux/hardirq.h>
|
||
#include <linux/spinlock_types.h>
|
||
|
||
/*
|
||
@@ -61,6 +60,7 @@
|
||
extern unsigned int irq_canonicalize(unsigned int irq);
|
||
extern void enable_irq(unsigned int);
|
||
extern void disable_irq(unsigned int);
|
||
+
|
||
#define disable_irq_nosync disable_irq
|
||
|
||
struct pt_regs;
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/mmzone.h linux-m68k/include/asm-m68k/mmzone.h
|
||
--- linux-i386/include/asm-m68k/mmzone.h 1970-01-01 01:00:00.000000000 +0100
|
||
+++ linux-m68k/include/asm-m68k/mmzone.h 2006-09-03 17:54:54.000000000 +0200
|
||
@@ -0,0 +1,9 @@
|
||
+#ifndef _ASM_M68K_MMZONE_H_
|
||
+#define _ASM_M68K_MMZONE_H_
|
||
+
|
||
+extern pg_data_t pg_data_map[];
|
||
+
|
||
+#define NODE_DATA(nid) (&pg_data_map[nid])
|
||
+#define NODE_MEM_MAP(nid) (NODE_DATA(nid)->node_mem_map)
|
||
+
|
||
+#endif /* _ASM_M68K_MMZONE_H_ */
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/module.h linux-m68k/include/asm-m68k/module.h
|
||
--- linux-i386/include/asm-m68k/module.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/module.h 2006-09-05 16:34:01.000000000 +0200
|
||
@@ -1,7 +1,39 @@
|
||
#ifndef _ASM_M68K_MODULE_H
|
||
#define _ASM_M68K_MODULE_H
|
||
-struct mod_arch_specific { };
|
||
+
|
||
+struct mod_arch_specific {
|
||
+ struct m68k_fixup_info *fixup_start, *fixup_end;
|
||
+};
|
||
+
|
||
+#define MODULE_ARCH_INIT { \
|
||
+ .fixup_start = __start_fixup, \
|
||
+ .fixup_end = __stop_fixup, \
|
||
+}
|
||
+
|
||
#define Elf_Shdr Elf32_Shdr
|
||
#define Elf_Sym Elf32_Sym
|
||
#define Elf_Ehdr Elf32_Ehdr
|
||
+
|
||
+
|
||
+enum m68k_fixup_type {
|
||
+ m68k_fixup_memoffset,
|
||
+ m68k_fixup_vnode_shift,
|
||
+};
|
||
+
|
||
+struct m68k_fixup_info {
|
||
+ enum m68k_fixup_type type;
|
||
+ void *addr;
|
||
+};
|
||
+
|
||
+#define m68k_fixup(type, addr) \
|
||
+ " .section \".m68k_fixup\",\"aw\"\n" \
|
||
+ " .long " #type "," #addr "\n" \
|
||
+ " .previous\n"
|
||
+
|
||
+extern struct m68k_fixup_info __start_fixup[], __stop_fixup[];
|
||
+
|
||
+struct module;
|
||
+extern void module_fixup(struct module *mod, struct m68k_fixup_info *start,
|
||
+ struct m68k_fixup_info *end);
|
||
+
|
||
#endif /* _ASM_M68K_MODULE_H */
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/motorola_pgtable.h linux-m68k/include/asm-m68k/motorola_pgtable.h
|
||
--- linux-i386/include/asm-m68k/motorola_pgtable.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/motorola_pgtable.h 2006-09-24 16:34:33.000000000 +0200
|
||
@@ -130,7 +130,7 @@
|
||
#define pte_present(pte) (pte_val(pte) & (_PAGE_PRESENT | _PAGE_PROTNONE))
|
||
#define pte_clear(mm,addr,ptep) ({ pte_val(*(ptep)) = 0; })
|
||
|
||
-#define pte_page(pte) (mem_map + ((unsigned long)(__va(pte_val(pte)) - PAGE_OFFSET) >> PAGE_SHIFT))
|
||
+#define pte_page(pte) virt_to_page(__va(pte_val(pte)))
|
||
#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
|
||
#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
|
||
|
||
@@ -143,7 +143,7 @@
|
||
while (--__i >= 0) \
|
||
*__ptr++ = 0; \
|
||
})
|
||
-#define pmd_page(pmd) (mem_map + ((unsigned long)(__va(pmd_val(pmd)) - PAGE_OFFSET) >> PAGE_SHIFT))
|
||
+#define pmd_page(pmd) virt_to_page(__va(pmd_val(pmd)))
|
||
|
||
|
||
#define pgd_none(pgd) (!pgd_val(pgd))
|
||
@@ -222,10 +222,10 @@
|
||
return (pte_t *)__pmd_page(*pmdp) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
|
||
}
|
||
|
||
-#define pte_offset_map(pmdp,address) ((pte_t *)kmap(pmd_page(*pmdp)) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
|
||
+#define pte_offset_map(pmdp,address) ((pte_t *)__pmd_page(*pmdp) + (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
|
||
#define pte_offset_map_nested(pmdp, address) pte_offset_map(pmdp, address)
|
||
-#define pte_unmap(pte) kunmap(pte)
|
||
-#define pte_unmap_nested(pte) kunmap(pte)
|
||
+#define pte_unmap(pte) ((void)0)
|
||
+#define pte_unmap_nested(pte) ((void)0)
|
||
|
||
/*
|
||
* Allocate and free page tables. The xxx_kernel() versions are
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/page.h linux-m68k/include/asm-m68k/page.h
|
||
--- linux-i386/include/asm-m68k/page.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/page.h 2006-09-24 16:34:33.000000000 +0200
|
||
@@ -1,6 +1,7 @@
|
||
#ifndef _M68K_PAGE_H
|
||
#define _M68K_PAGE_H
|
||
|
||
+#include <linux/compiler.h>
|
||
|
||
#ifdef __KERNEL__
|
||
|
||
@@ -27,6 +28,8 @@
|
||
|
||
#ifndef __ASSEMBLY__
|
||
|
||
+#include <asm/module.h>
|
||
+
|
||
#define get_user_page(vaddr) __get_free_page(GFP_KERNEL)
|
||
#define free_user_page(page, addr) free_page(addr)
|
||
|
||
@@ -114,18 +117,33 @@
|
||
|
||
#ifndef __ASSEMBLY__
|
||
|
||
+extern unsigned long m68k_memoffset;
|
||
+
|
||
#ifndef CONFIG_SUN3
|
||
|
||
#define WANT_PAGE_VIRTUAL
|
||
-#ifdef CONFIG_SINGLE_MEMORY_CHUNK
|
||
-extern unsigned long m68k_memoffset;
|
||
|
||
-#define __pa(vaddr) ((unsigned long)(vaddr)+m68k_memoffset)
|
||
-#define __va(paddr) ((void *)((unsigned long)(paddr)-m68k_memoffset))
|
||
-#else
|
||
-#define __pa(vaddr) virt_to_phys((void *)(vaddr))
|
||
-#define __va(paddr) phys_to_virt((unsigned long)(paddr))
|
||
-#endif
|
||
+static inline unsigned long ___pa(void *vaddr)
|
||
+{
|
||
+ unsigned long paddr;
|
||
+ asm (
|
||
+ "1: addl #0,%0\n"
|
||
+ m68k_fixup(%c2, 1b+2)
|
||
+ : "=r" (paddr)
|
||
+ : "0" (vaddr), "i" (m68k_fixup_memoffset));
|
||
+ return paddr;
|
||
+}
|
||
+#define __pa(vaddr) ___pa((void *)(vaddr))
|
||
+static inline void *__va(unsigned long paddr)
|
||
+{
|
||
+ void *vaddr;
|
||
+ asm (
|
||
+ "1: subl #0,%0\n"
|
||
+ m68k_fixup(%c2, 1b+2)
|
||
+ : "=r" (vaddr)
|
||
+ : "0" (paddr), "i" (m68k_fixup_memoffset));
|
||
+ return vaddr;
|
||
+}
|
||
|
||
#else /* !CONFIG_SUN3 */
|
||
/* This #define is a horrible hack to suppress lots of warnings. --m */
|
||
@@ -161,11 +179,47 @@
|
||
#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT)
|
||
#define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT)
|
||
|
||
-#define virt_to_page(kaddr) (mem_map + (((unsigned long)(kaddr)-PAGE_OFFSET) >> PAGE_SHIFT))
|
||
-#define page_to_virt(page) ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)
|
||
+extern int m68k_virt_to_node_shift;
|
||
+
|
||
+#ifdef CONFIG_SINGLE_MEMORY_CHUNK
|
||
+#define __virt_to_node(addr) (&pg_data_map[0])
|
||
+#else
|
||
+extern struct pglist_data *pg_data_table[];
|
||
+
|
||
+static inline __attribute_const__ int __virt_to_node_shift(void)
|
||
+{
|
||
+ int shift;
|
||
+
|
||
+ asm (
|
||
+ "1: moveq #0,%0\n"
|
||
+ m68k_fixup(%c1, 1b)
|
||
+ : "=d" (shift)
|
||
+ : "i" (m68k_fixup_vnode_shift));
|
||
+ return shift;
|
||
+}
|
||
+
|
||
+#define __virt_to_node(addr) (pg_data_table[(unsigned long)(addr) >> __virt_to_node_shift()])
|
||
+#endif
|
||
|
||
-#define pfn_to_page(pfn) virt_to_page(pfn_to_virt(pfn))
|
||
-#define page_to_pfn(page) virt_to_pfn(page_to_virt(page))
|
||
+#define virt_to_page(addr) ({ \
|
||
+ pfn_to_page(virt_to_pfn(addr)); \
|
||
+})
|
||
+#define page_to_virt(page) ({ \
|
||
+ pfn_to_virt(page_to_pfn(page)); \
|
||
+})
|
||
+
|
||
+#define pfn_to_page(pfn) ({ \
|
||
+ unsigned long __pfn = (pfn); \
|
||
+ struct pglist_data *pgdat; \
|
||
+ pgdat = __virt_to_node((unsigned long)pfn_to_virt(__pfn)); \
|
||
+ pgdat->node_mem_map + (__pfn - pgdat->node_start_pfn); \
|
||
+})
|
||
+#define page_to_pfn(_page) ({ \
|
||
+ struct page *__p = (_page); \
|
||
+ struct pglist_data *pgdat; \
|
||
+ pgdat = &pg_data_map[page_to_nid(__p)]; \
|
||
+ ((__p) - pgdat->node_mem_map) + pgdat->node_start_pfn; \
|
||
+})
|
||
|
||
#define virt_addr_valid(kaddr) ((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory)
|
||
#define pfn_valid(pfn) virt_addr_valid(pfn_to_virt(pfn))
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/pgalloc.h linux-m68k/include/asm-m68k/pgalloc.h
|
||
--- linux-i386/include/asm-m68k/pgalloc.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/pgalloc.h 2006-09-24 16:34:33.000000000 +0200
|
||
@@ -8,11 +8,12 @@
|
||
#include <asm/virtconvert.h>
|
||
|
||
|
||
-
|
||
#ifdef CONFIG_SUN3
|
||
#include <asm/sun3_pgalloc.h>
|
||
#else
|
||
#include <asm/motorola_pgalloc.h>
|
||
#endif
|
||
|
||
+extern void m68k_setup_node(int node);
|
||
+
|
||
#endif /* M68K_PGALLOC_H */
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/pgtable.h linux-m68k/include/asm-m68k/pgtable.h
|
||
--- linux-i386/include/asm-m68k/pgtable.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/pgtable.h 2006-09-24 16:34:33.000000000 +0200
|
||
@@ -107,22 +107,7 @@
|
||
/* 64-bit machines, beware! SRB. */
|
||
#define SIZEOF_PTR_LOG2 2
|
||
|
||
-/*
|
||
- * Check if the addr/len goes up to the end of a physical
|
||
- * memory chunk. Used for DMA functions.
|
||
- */
|
||
-#ifdef CONFIG_SINGLE_MEMORY_CHUNK
|
||
-/*
|
||
- * It makes no sense to consider whether we cross a memory boundary if
|
||
- * we support just one physical chunk of memory.
|
||
- */
|
||
-static inline int mm_end_of_chunk(unsigned long addr, int len)
|
||
-{
|
||
- return 0;
|
||
-}
|
||
-#else
|
||
-int mm_end_of_chunk (unsigned long addr, int len);
|
||
-#endif
|
||
+#define mm_end_of_chunk(addr, len) 0
|
||
|
||
extern void kernel_set_cachemode(void *addr, unsigned long size, int cmode);
|
||
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/serial.h linux-m68k/include/asm-m68k/serial.h
|
||
--- linux-i386/include/asm-m68k/serial.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/serial.h 2006-09-24 16:34:33.000000000 +0200
|
||
@@ -25,9 +25,11 @@
|
||
#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
|
||
#endif
|
||
|
||
+#ifdef CONFIG_ISA
|
||
#define SERIAL_PORT_DFNS \
|
||
/* UART CLK PORT IRQ FLAGS */ \
|
||
{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \
|
||
{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \
|
||
{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \
|
||
{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */
|
||
+#endif
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/string.h linux-m68k/include/asm-m68k/string.h
|
||
--- linux-i386/include/asm-m68k/string.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/string.h 2006-09-05 16:34:01.000000000 +0200
|
||
@@ -1,138 +1,114 @@
|
||
#ifndef _M68K_STRING_H_
|
||
#define _M68K_STRING_H_
|
||
|
||
-#include <asm/setup.h>
|
||
-#include <asm/page.h>
|
||
+#include <linux/types.h>
|
||
+#include <linux/compiler.h>
|
||
|
||
-#define __HAVE_ARCH_STRCPY
|
||
-static inline char * strcpy(char * dest,const char *src)
|
||
+static inline size_t __kernel_strlen(const char *s)
|
||
{
|
||
- char *xdest = dest;
|
||
+ const char *sc;
|
||
|
||
- __asm__ __volatile__
|
||
- ("1:\tmoveb %1@+,%0@+\n\t"
|
||
- "jne 1b"
|
||
- : "=a" (dest), "=a" (src)
|
||
- : "0" (dest), "1" (src) : "memory");
|
||
- return xdest;
|
||
+ for (sc = s; *sc++; )
|
||
+ ;
|
||
+ return sc - s - 1;
|
||
}
|
||
|
||
-#define __HAVE_ARCH_STRNCPY
|
||
-static inline char * strncpy(char *dest, const char *src, size_t n)
|
||
+static inline char *__kernel_strcpy(char *dest, const char *src)
|
||
{
|
||
- char *xdest = dest;
|
||
+ char *xdest = dest;
|
||
|
||
- if (n == 0)
|
||
- return xdest;
|
||
-
|
||
- __asm__ __volatile__
|
||
- ("1:\tmoveb %1@+,%0@+\n\t"
|
||
- "jeq 2f\n\t"
|
||
- "subql #1,%2\n\t"
|
||
- "jne 1b\n\t"
|
||
- "2:"
|
||
- : "=a" (dest), "=a" (src), "=d" (n)
|
||
- : "0" (dest), "1" (src), "2" (n)
|
||
- : "memory");
|
||
- return xdest;
|
||
+ asm volatile ("\n"
|
||
+ "1: move.b (%1)+,(%0)+\n"
|
||
+ " jne 1b"
|
||
+ : "+a" (dest), "+a" (src)
|
||
+ : : "memory");
|
||
+ return xdest;
|
||
}
|
||
|
||
-#define __HAVE_ARCH_STRCAT
|
||
-static inline char * strcat(char * dest, const char * src)
|
||
-{
|
||
- char *tmp = dest;
|
||
-
|
||
- while (*dest)
|
||
- dest++;
|
||
- while ((*dest++ = *src++))
|
||
- ;
|
||
+#ifndef __IN_STRING_C
|
||
|
||
- return tmp;
|
||
+#define __HAVE_ARCH_STRLEN
|
||
+#define strlen(s) (__builtin_constant_p(s) ? \
|
||
+ __builtin_strlen(s) : \
|
||
+ __kernel_strlen(s))
|
||
+
|
||
+#define __HAVE_ARCH_STRNLEN
|
||
+static inline size_t strnlen(const char *s, size_t count)
|
||
+{
|
||
+ const char *sc = s;
|
||
+
|
||
+ asm volatile ("\n"
|
||
+ "1: subq.l #1,%1\n"
|
||
+ " jcs 2f\n"
|
||
+ " tst.b (%0)+\n"
|
||
+ " jne 1b\n"
|
||
+ " subq.l #1,%0\n"
|
||
+ "2:"
|
||
+ : "+a" (sc), "+d" (count));
|
||
+ return sc - s;
|
||
}
|
||
|
||
-#define __HAVE_ARCH_STRNCAT
|
||
-static inline char * strncat(char *dest, const char *src, size_t count)
|
||
-{
|
||
- char *tmp = dest;
|
||
-
|
||
- if (count) {
|
||
- while (*dest)
|
||
- dest++;
|
||
- while ((*dest++ = *src++)) {
|
||
- if (--count == 0) {
|
||
- *dest++='\0';
|
||
- break;
|
||
- }
|
||
- }
|
||
- }
|
||
-
|
||
- return tmp;
|
||
-}
|
||
+#define __HAVE_ARCH_STRCPY
|
||
+#if __GNUC__ >= 4
|
||
+#define strcpy(d, s) (__builtin_constant_p(s) && \
|
||
+ __builtin_strlen(s) <= 32 ? \
|
||
+ __builtin_strcpy(d, s) : \
|
||
+ __kernel_strcpy(d, s))
|
||
+#else
|
||
+#define strcpy(d, s) __kernel_strcpy(d, s)
|
||
+#endif
|
||
|
||
-#define __HAVE_ARCH_STRCHR
|
||
-static inline char * strchr(const char * s, int c)
|
||
+#define __HAVE_ARCH_STRNCPY
|
||
+static inline char *strncpy(char *dest, const char *src, size_t n)
|
||
{
|
||
- const char ch = c;
|
||
+ char *xdest = dest;
|
||
|
||
- for(; *s != ch; ++s)
|
||
- if (*s == '\0')
|
||
- return( NULL );
|
||
- return( (char *) s);
|
||
+ asm volatile ("\n"
|
||
+ " jra 2f\n"
|
||
+ "1: move.b (%1),(%0)+\n"
|
||
+ " jeq 2f\n"
|
||
+ " addq.l #1,%1\n"
|
||
+ "2: subq.l #1,%2\n"
|
||
+ " jcc 1b\n"
|
||
+ : "+a" (dest), "+a" (src), "+d" (n)
|
||
+ : : "memory");
|
||
+ return xdest;
|
||
}
|
||
|
||
-/* strstr !! */
|
||
+#define __HAVE_ARCH_STRCAT
|
||
+#define strcat(d, s) ({ \
|
||
+ char *__d = (d); \
|
||
+ strcpy(__d + strlen(__d), (s)); \
|
||
+})
|
||
|
||
-#define __HAVE_ARCH_STRLEN
|
||
-static inline size_t strlen(const char * s)
|
||
+#define __HAVE_ARCH_STRCHR
|
||
+static inline char *strchr(const char *s, int c)
|
||
{
|
||
- const char *sc;
|
||
- for (sc = s; *sc != '\0'; ++sc) ;
|
||
- return(sc - s);
|
||
-}
|
||
+ char sc, ch = c;
|
||
|
||
-/* strnlen !! */
|
||
+ for (; (sc = *s++) != ch; ) {
|
||
+ if (!sc)
|
||
+ return NULL;
|
||
+ }
|
||
+ return (char *)s - 1;
|
||
+}
|
||
|
||
#define __HAVE_ARCH_STRCMP
|
||
-static inline int strcmp(const char * cs,const char * ct)
|
||
+static inline int strcmp(const char *cs, const char *ct)
|
||
{
|
||
- char __res;
|
||
+ char res;
|
||
|
||
- __asm__
|
||
- ("1:\tmoveb %0@+,%2\n\t" /* get *cs */
|
||
- "cmpb %1@+,%2\n\t" /* compare a byte */
|
||
- "jne 2f\n\t" /* not equal, break out */
|
||
- "tstb %2\n\t" /* at end of cs? */
|
||
- "jne 1b\n\t" /* no, keep going */
|
||
- "jra 3f\n\t" /* strings are equal */
|
||
- "2:\tsubb %1@-,%2\n\t" /* *cs - *ct */
|
||
- "3:"
|
||
- : "=a" (cs), "=a" (ct), "=d" (__res)
|
||
- : "0" (cs), "1" (ct));
|
||
- return __res;
|
||
-}
|
||
-
|
||
-#define __HAVE_ARCH_STRNCMP
|
||
-static inline int strncmp(const char * cs,const char * ct,size_t count)
|
||
-{
|
||
- char __res;
|
||
-
|
||
- if (!count)
|
||
- return 0;
|
||
- __asm__
|
||
- ("1:\tmovb %0@+,%3\n\t" /* get *cs */
|
||
- "cmpb %1@+,%3\n\t" /* compare a byte */
|
||
- "jne 3f\n\t" /* not equal, break out */
|
||
- "tstb %3\n\t" /* at end of cs? */
|
||
- "jeq 4f\n\t" /* yes, all done */
|
||
- "subql #1,%2\n\t" /* no, adjust count */
|
||
- "jne 1b\n\t" /* more to do, keep going */
|
||
- "2:\tmoveq #0,%3\n\t" /* strings are equal */
|
||
- "jra 4f\n\t"
|
||
- "3:\tsubb %1@-,%3\n\t" /* *cs - *ct */
|
||
- "4:"
|
||
- : "=a" (cs), "=a" (ct), "=d" (count), "=d" (__res)
|
||
- : "0" (cs), "1" (ct), "2" (count));
|
||
- return __res;
|
||
+ asm ("\n"
|
||
+ "1: move.b (%0)+,%2\n" /* get *cs */
|
||
+ " cmp.b (%1)+,%2\n" /* compare a byte */
|
||
+ " jne 2f\n" /* not equal, break out */
|
||
+ " tst.b %2\n" /* at end of cs? */
|
||
+ " jne 1b\n" /* no, keep going */
|
||
+ " jra 3f\n" /* strings are equal */
|
||
+ "2: sub.b -(%1),%2\n" /* *cs - *ct */
|
||
+ "3:"
|
||
+ : "+a" (cs), "+a" (ct), "=d" (res));
|
||
+ return res;
|
||
}
|
||
|
||
#define __HAVE_ARCH_MEMSET
|
||
@@ -150,4 +126,6 @@
|
||
extern int memcmp(const void *, const void *, __kernel_size_t);
|
||
#define memcmp(d, s, n) __builtin_memcmp(d, s, n)
|
||
|
||
+#endif
|
||
+
|
||
#endif /* _M68K_STRING_H_ */
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/sun3-head.h linux-m68k/include/asm-m68k/sun3-head.h
|
||
--- linux-i386/include/asm-m68k/sun3-head.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/sun3-head.h 2006-05-11 13:14:11.000000000 +0200
|
||
@@ -4,7 +4,6 @@
|
||
|
||
#define KERNBASE 0xE000000 /* First address the kernel will eventually be */
|
||
#define LOAD_ADDR 0x4000 /* prom jumps to us here unless this is elf /boot */
|
||
-#define BI_START (KERNBASE + 0x3000) /* beginning of the bootinfo records */
|
||
#define FC_CONTROL 3
|
||
#define FC_SUPERD 5
|
||
#define FC_CPU 7
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/sun3_pgtable.h linux-m68k/include/asm-m68k/sun3_pgtable.h
|
||
--- linux-i386/include/asm-m68k/sun3_pgtable.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/sun3_pgtable.h 2006-09-05 16:34:01.000000000 +0200
|
||
@@ -132,8 +132,8 @@
|
||
#define pfn_pte(pfn, pgprot) \
|
||
({ pte_t __pte; pte_val(__pte) = pfn | pgprot_val(pgprot); __pte; })
|
||
|
||
-#define pte_page(pte) (mem_map+((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT))
|
||
-#define pmd_page(pmd) (mem_map+((__pmd_page(pmd) - PAGE_OFFSET) >> PAGE_SHIFT))
|
||
+#define pte_page(pte) virt_to_page(__pte_page(pte))
|
||
+#define pmd_page(pmd) virt_to_page(__pmd_page(pmd))
|
||
|
||
|
||
static inline int pmd_none2 (pmd_t *pmd) { return !pmd_val (*pmd); }
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/sun3ints.h linux-m68k/include/asm-m68k/sun3ints.h
|
||
--- linux-i386/include/asm-m68k/sun3ints.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/sun3ints.h 2006-05-11 13:14:11.000000000 +0200
|
||
@@ -16,6 +16,7 @@
|
||
#include <asm/intersil.h>
|
||
#include <asm/oplib.h>
|
||
#include <asm/traps.h>
|
||
+#include <asm/irq.h>
|
||
|
||
#define SUN3_INT_VECS 192
|
||
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/system.h linux-m68k/include/asm-m68k/system.h
|
||
--- linux-i386/include/asm-m68k/system.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/system.h 2006-09-24 16:34:34.000000000 +0200
|
||
@@ -78,13 +78,13 @@
|
||
#define mb() barrier()
|
||
#define rmb() barrier()
|
||
#define wmb() barrier()
|
||
-#define read_barrier_depends() do { } while(0)
|
||
-#define set_mb(var, value) do { xchg(&var, value); } while (0)
|
||
+#define read_barrier_depends() ((void)0)
|
||
+#define set_mb(var, value) ({ (var) = (value); wmb(); })
|
||
|
||
#define smp_mb() barrier()
|
||
#define smp_rmb() barrier()
|
||
#define smp_wmb() barrier()
|
||
-#define smp_read_barrier_depends() do { } while(0)
|
||
+#define smp_read_barrier_depends() ((void)0)
|
||
|
||
|
||
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/thread_info.h linux-m68k/include/asm-m68k/thread_info.h
|
||
--- linux-i386/include/asm-m68k/thread_info.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/thread_info.h 2006-04-11 01:58:28.000000000 +0200
|
||
@@ -26,24 +26,24 @@
|
||
|
||
/* THREAD_SIZE should be 8k, so handle differently for 4k and 8k machines */
|
||
#if PAGE_SHIFT == 13 /* 8k machines */
|
||
-#define alloc_thread_info(tsk) ((struct thread_info *)__get_free_pages(GFP_KERNEL,0))
|
||
-#define free_thread_info(ti) free_pages((unsigned long)(ti),0)
|
||
+#define alloc_thread_stack(tsk) ((void *)__get_free_pages(GFP_KERNEL,0))
|
||
+#define free_thread_stack(ti) free_pages((unsigned long)(ti),0)
|
||
#else /* otherwise assume 4k pages */
|
||
-#define alloc_thread_info(tsk) ((struct thread_info *)__get_free_pages(GFP_KERNEL,1))
|
||
-#define free_thread_info(ti) free_pages((unsigned long)(ti),1)
|
||
+#define alloc_thread_stack(tsk) ((void *)__get_free_pages(GFP_KERNEL,1))
|
||
+#define free_thread_stack(ti) free_pages((unsigned long)(ti),1)
|
||
#endif /* PAGE_SHIFT == 13 */
|
||
|
||
#define init_thread_info (init_task.thread.info)
|
||
#define init_stack (init_thread_union.stack)
|
||
|
||
#define task_thread_info(tsk) (&(tsk)->thread.info)
|
||
-#define task_stack_page(tsk) ((void *)(tsk)->thread_info)
|
||
+#define task_stack_page(tsk) ((void *)(tsk)->stack)
|
||
#define current_thread_info() task_thread_info(current)
|
||
|
||
#define __HAVE_THREAD_FUNCTIONS
|
||
|
||
#define setup_thread_stack(p, org) ({ \
|
||
- *(struct task_struct **)(p)->thread_info = (p); \
|
||
+ *(struct task_struct **)(p)->stack = (p); \
|
||
task_thread_info(p)->task = (p); \
|
||
})
|
||
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/unistd.h linux-m68k/include/asm-m68k/unistd.h
|
||
--- linux-i386/include/asm-m68k/unistd.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/unistd.h 2006-09-24 16:34:34.000000000 +0200
|
||
@@ -284,10 +284,15 @@
|
||
#define __NR_add_key 279
|
||
#define __NR_request_key 280
|
||
#define __NR_keyctl 281
|
||
+#define __NR_ioprio_set 282
|
||
+#define __NR_ioprio_get 283
|
||
+#define __NR_inotify_init 284
|
||
+#define __NR_inotify_add_watch 285
|
||
+#define __NR_inotify_rm_watch 286
|
||
|
||
#ifdef __KERNEL__
|
||
|
||
-#define NR_syscalls 282
|
||
+#define NR_syscalls 287
|
||
|
||
/* user-visible error numbers are in the range -1 - -124: see
|
||
<asm-m68k/errno.h> */
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/virtconvert.h linux-m68k/include/asm-m68k/virtconvert.h
|
||
--- linux-i386/include/asm-m68k/virtconvert.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/virtconvert.h 2006-09-24 16:34:34.000000000 +0200
|
||
@@ -8,56 +8,34 @@
|
||
#ifdef __KERNEL__
|
||
|
||
#include <linux/compiler.h>
|
||
+#include <linux/mmzone.h>
|
||
#include <asm/setup.h>
|
||
#include <asm/page.h>
|
||
|
||
-#ifdef CONFIG_AMIGA
|
||
-#include <asm/amigahw.h>
|
||
-#endif
|
||
-
|
||
/*
|
||
* Change virtual addresses to physical addresses and vv.
|
||
*/
|
||
-#ifndef CONFIG_SUN3
|
||
-extern unsigned long mm_vtop(unsigned long addr) __attribute_const__;
|
||
-extern unsigned long mm_ptov(unsigned long addr) __attribute_const__;
|
||
-#else
|
||
-static inline unsigned long mm_vtop(unsigned long vaddr)
|
||
-{
|
||
- return __pa(vaddr);
|
||
-}
|
||
-
|
||
-static inline unsigned long mm_ptov(unsigned long paddr)
|
||
-{
|
||
- return (unsigned long)__va(paddr);
|
||
-}
|
||
-#endif
|
||
-
|
||
-#ifdef CONFIG_SINGLE_MEMORY_CHUNK
|
||
-static inline unsigned long virt_to_phys(void *vaddr)
|
||
-{
|
||
- return (unsigned long)vaddr - PAGE_OFFSET + m68k_memory[0].addr;
|
||
-}
|
||
-
|
||
-static inline void * phys_to_virt(unsigned long paddr)
|
||
-{
|
||
- return (void *)(paddr - m68k_memory[0].addr + PAGE_OFFSET);
|
||
-}
|
||
-#else
|
||
static inline unsigned long virt_to_phys(void *address)
|
||
{
|
||
- return mm_vtop((unsigned long)address);
|
||
+ return __pa(address);
|
||
}
|
||
|
||
static inline void *phys_to_virt(unsigned long address)
|
||
{
|
||
- return (void *) mm_ptov(address);
|
||
+ return __va(address);
|
||
}
|
||
-#endif
|
||
|
||
/* Permanent address of a page. */
|
||
-#define __page_address(page) (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
|
||
-#define page_to_phys(page) virt_to_phys((void *)__page_address(page))
|
||
+#ifdef CONFIG_SINGLE_MEMORY_CHUNK
|
||
+#define page_to_phys(page) \
|
||
+ __pa(PAGE_OFFSET + (((page) - pg_data_map[0].node_mem_map) << PAGE_SHIFT))
|
||
+#else
|
||
+#define page_to_phys(page) ({ \
|
||
+ struct pglist_data *pgdat; \
|
||
+ pgdat = pg_data_table[page_to_nid(page)]; \
|
||
+ page_to_pfn(page) << PAGE_SHIFT; \
|
||
+})
|
||
+#endif
|
||
|
||
/*
|
||
* IO bus memory addresses are 1:1 with the physical address,
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/adb.h linux-m68k/include/linux/adb.h
|
||
--- linux-i386/include/linux/adb.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/linux/adb.h 2006-06-18 19:10:20.000000000 +0200
|
||
@@ -76,6 +76,7 @@
|
||
#define ADBREQ_REPLY 1 /* expect reply */
|
||
#define ADBREQ_SYNC 2 /* poll until done */
|
||
#define ADBREQ_NOSEND 4 /* build the request, but don't send it */
|
||
+#define ADBREQ_RAW 8 /* send raw packet (don't prepend ADB_PACKET) */
|
||
|
||
/* Messages sent thru the client_list notifier. You should NOT stop
|
||
the operation, at least not with this version */
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/bootmem.h linux-m68k/include/linux/bootmem.h
|
||
--- linux-i386/include/linux/bootmem.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/linux/bootmem.h 2006-09-24 16:34:56.000000000 +0200
|
||
@@ -61,11 +61,11 @@
|
||
#define alloc_bootmem(x) \
|
||
__alloc_bootmem((x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
|
||
#define alloc_bootmem_low(x) \
|
||
- __alloc_bootmem_low((x), SMP_CACHE_BYTES, 0)
|
||
+ __alloc_bootmem_low((x), SMP_CACHE_BYTES, __pa(PAGE_OFFSET))
|
||
#define alloc_bootmem_pages(x) \
|
||
__alloc_bootmem((x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
|
||
#define alloc_bootmem_low_pages(x) \
|
||
- __alloc_bootmem_low((x), PAGE_SIZE, 0)
|
||
+ __alloc_bootmem_low((x), PAGE_SIZE, __pa(PAGE_OFFSET))
|
||
#endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */
|
||
extern unsigned long __init free_all_bootmem (void);
|
||
extern void * __init __alloc_bootmem_node (pg_data_t *pgdat, unsigned long size, unsigned long align, unsigned long goal);
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/file.h linux-m68k/include/linux/file.h
|
||
--- linux-i386/include/linux/file.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/linux/file.h 2006-06-18 19:10:21.000000000 +0200
|
||
@@ -5,7 +5,6 @@
|
||
#ifndef __LINUX_FILE_H
|
||
#define __LINUX_FILE_H
|
||
|
||
-#include <asm/atomic.h>
|
||
#include <linux/posix_types.h>
|
||
#include <linux/compiler.h>
|
||
#include <linux/spinlock.h>
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/hardirq.h linux-m68k/include/linux/hardirq.h
|
||
--- linux-i386/include/linux/hardirq.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/linux/hardirq.h 2006-09-27 16:34:52.000000000 +0200
|
||
@@ -3,9 +3,7 @@
|
||
|
||
#include <linux/preempt.h>
|
||
#include <linux/smp_lock.h>
|
||
-#include <linux/lockdep.h>
|
||
#include <asm/hardirq.h>
|
||
-#include <asm/system.h>
|
||
|
||
/*
|
||
* We put the hardirq and softirq counter into the preemption
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/ide.h linux-m68k/include/linux/ide.h
|
||
--- linux-i386/include/linux/ide.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/linux/ide.h 2006-09-24 16:34:57.000000000 +0200
|
||
@@ -509,7 +509,7 @@
|
||
* sense_key : Sense key of the last failed packet command
|
||
*/
|
||
typedef union {
|
||
- unsigned all :8;
|
||
+ u8 all;
|
||
struct {
|
||
#if defined(__LITTLE_ENDIAN_BITFIELD)
|
||
unsigned ili :1;
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/init_task.h linux-m68k/include/linux/init_task.h
|
||
--- linux-i386/include/linux/init_task.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/linux/init_task.h 2006-09-24 16:34:57.000000000 +0200
|
||
@@ -83,7 +83,7 @@
|
||
#define INIT_TASK(tsk) \
|
||
{ \
|
||
.state = 0, \
|
||
- .thread_info = &init_thread_info, \
|
||
+ .stack = &init_stack, \
|
||
.usage = ATOMIC_INIT(2), \
|
||
.flags = 0, \
|
||
.lock_depth = -1, \
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/module.h linux-m68k/include/linux/module.h
|
||
--- linux-i386/include/linux/module.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/linux/module.h 2006-09-24 16:34:58.000000000 +0200
|
||
@@ -346,6 +346,9 @@
|
||
keeping pointers to this stuff */
|
||
char *args;
|
||
};
|
||
+#ifndef MODULE_ARCH_INIT
|
||
+#define MODULE_ARCH_INIT {}
|
||
+#endif
|
||
|
||
/* FIXME: It'd be nice to isolate modules during init, too, so they
|
||
aren't used before they (may) fail. But presently too much code
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/sched.h linux-m68k/include/linux/sched.h
|
||
--- linux-i386/include/linux/sched.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/linux/sched.h 2006-09-24 16:35:00.000000000 +0200
|
||
@@ -766,7 +766,8 @@
|
||
|
||
struct task_struct {
|
||
volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
|
||
- struct thread_info *thread_info;
|
||
+ //struct thread_info *thread_info;
|
||
+ void *stack;
|
||
atomic_t usage;
|
||
unsigned long flags; /* per process flags, defined below */
|
||
unsigned long ptrace;
|
||
@@ -1395,6 +1396,7 @@
|
||
/* set thread flags in other task's structures
|
||
* - see asm/thread_info.h for TIF_xxxx flags available
|
||
*/
|
||
+
|
||
static inline void set_tsk_thread_flag(struct task_struct *tsk, int flag)
|
||
{
|
||
set_ti_thread_flag(task_thread_info(tsk), flag);
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/thread_info.h linux-m68k/include/linux/thread_info.h
|
||
--- linux-i386/include/linux/thread_info.h 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/include/linux/thread_info.h 2005-05-30 02:26:01.000000000 +0200
|
||
@@ -66,6 +66,6 @@
|
||
#define set_need_resched() set_thread_flag(TIF_NEED_RESCHED)
|
||
#define clear_need_resched() clear_thread_flag(TIF_NEED_RESCHED)
|
||
|
||
-#endif
|
||
+#endif /* __KERNEL__ */
|
||
|
||
#endif /* _LINUX_THREAD_INFO_H */
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/kernel/fork.c linux-m68k/kernel/fork.c
|
||
--- linux-i386/kernel/fork.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/kernel/fork.c 2006-09-24 16:35:10.000000000 +0200
|
||
@@ -102,7 +102,7 @@
|
||
|
||
void free_task(struct task_struct *tsk)
|
||
{
|
||
- free_thread_info(tsk->thread_info);
|
||
+ free_thread_stack(tsk->stack);
|
||
rt_mutex_debug_task_free(tsk);
|
||
free_task_struct(tsk);
|
||
}
|
||
@@ -157,7 +157,7 @@
|
||
static struct task_struct *dup_task_struct(struct task_struct *orig)
|
||
{
|
||
struct task_struct *tsk;
|
||
- struct thread_info *ti;
|
||
+ void *stack;
|
||
|
||
prepare_to_copy(orig);
|
||
|
||
@@ -165,14 +165,14 @@
|
||
if (!tsk)
|
||
return NULL;
|
||
|
||
- ti = alloc_thread_info(tsk);
|
||
- if (!ti) {
|
||
+ stack = alloc_thread_stack(tsk);
|
||
+ if (!stack) {
|
||
free_task_struct(tsk);
|
||
return NULL;
|
||
}
|
||
|
||
*tsk = *orig;
|
||
- tsk->thread_info = ti;
|
||
+ tsk->stack = stack;
|
||
setup_thread_stack(tsk, orig);
|
||
|
||
/* One for us, one for whoever does the "release_task()" (usually parent) */
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/kernel/mutex.c linux-m68k/kernel/mutex.c
|
||
--- linux-i386/kernel/mutex.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/kernel/mutex.c 2006-09-24 16:35:10.000000000 +0200
|
||
@@ -133,7 +133,7 @@
|
||
|
||
debug_mutex_lock_common(lock, &waiter);
|
||
mutex_acquire(&lock->dep_map, subclass, 0, _RET_IP_);
|
||
- debug_mutex_add_waiter(lock, &waiter, task->thread_info);
|
||
+ debug_mutex_add_waiter(lock, &waiter, task_thread_info(task));
|
||
|
||
/* add waiting tasks to the end of the waitqueue (FIFO): */
|
||
list_add_tail(&waiter.list, &lock->wait_list);
|
||
@@ -159,7 +159,7 @@
|
||
*/
|
||
if (unlikely(state == TASK_INTERRUPTIBLE &&
|
||
signal_pending(task))) {
|
||
- mutex_remove_waiter(lock, &waiter, task->thread_info);
|
||
+ mutex_remove_waiter(lock, &waiter, task_thread_info(task));
|
||
mutex_release(&lock->dep_map, 1, _RET_IP_);
|
||
spin_unlock_mutex(&lock->wait_lock, flags);
|
||
|
||
@@ -175,8 +175,8 @@
|
||
}
|
||
|
||
/* got the lock - rejoice! */
|
||
- mutex_remove_waiter(lock, &waiter, task->thread_info);
|
||
- debug_mutex_set_owner(lock, task->thread_info);
|
||
+ mutex_remove_waiter(lock, &waiter, task_thread_info(task));
|
||
+ debug_mutex_set_owner(lock, task_thread_info(task));
|
||
|
||
/* set it to 0 if there are no waiters left: */
|
||
if (likely(list_empty(&lock->wait_list)))
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/lib/kref.c linux-m68k/lib/kref.c
|
||
--- linux-i386/lib/kref.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/lib/kref.c 2006-06-18 19:10:31.000000000 +0200
|
||
@@ -11,8 +11,8 @@
|
||
*
|
||
*/
|
||
|
||
-#include <linux/kref.h>
|
||
#include <linux/module.h>
|
||
+#include <linux/kref.h>
|
||
|
||
/**
|
||
* kref_init - initialize object.
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/mm/bootmem.c linux-m68k/mm/bootmem.c
|
||
--- linux-i386/mm/bootmem.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/mm/bootmem.c 2006-09-24 16:35:13.000000000 +0200
|
||
@@ -303,7 +303,6 @@
|
||
|
||
count = 0;
|
||
/* first extant page of the node */
|
||
- pfn = bdata->node_boot_start >> PAGE_SHIFT;
|
||
idx = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT);
|
||
map = bdata->node_bootmem_map;
|
||
/* Check physaddr is O(LOG2(BITS_PER_LONG)) page aligned */
|
||
@@ -316,26 +315,24 @@
|
||
if (gofast && v == ~0UL) {
|
||
int order;
|
||
|
||
- page = pfn_to_page(pfn);
|
||
+ page = virt_to_page(phys_to_virt((i << PAGE_SHIFT) +
|
||
+ bdata->node_boot_start));
|
||
count += BITS_PER_LONG;
|
||
order = ffs(BITS_PER_LONG) - 1;
|
||
__free_pages_bootmem(page, order);
|
||
i += BITS_PER_LONG;
|
||
- page += BITS_PER_LONG;
|
||
} else if (v) {
|
||
unsigned long m;
|
||
-
|
||
- page = pfn_to_page(pfn);
|
||
- for (m = 1; m && i < idx; m<<=1, page++, i++) {
|
||
+ for (m = 1; m && i < idx; m<<=1, i++) {
|
||
if (v & m) {
|
||
+ page = virt_to_page(phys_to_virt((i << PAGE_SHIFT) +
|
||
+ bdata->node_boot_start));
|
||
count++;
|
||
__free_pages_bootmem(page, 0);
|
||
}
|
||
}
|
||
- } else {
|
||
+ } else
|
||
i+=BITS_PER_LONG;
|
||
- }
|
||
- pfn += BITS_PER_LONG;
|
||
}
|
||
total += count;
|
||
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/mm/page_alloc.c linux-m68k/mm/page_alloc.c
|
||
--- linux-i386/mm/page_alloc.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/mm/page_alloc.c 2006-09-24 16:35:13.000000000 +0200
|
||
@@ -2063,7 +2063,7 @@
|
||
map = alloc_bootmem_node(pgdat, size);
|
||
pgdat->node_mem_map = map + (pgdat->node_start_pfn - start);
|
||
}
|
||
-#ifdef CONFIG_FLATMEM
|
||
+#ifndef CONFIG_NEED_MULTIPLE_NODES
|
||
/*
|
||
* With no DISCONTIG, the global mem_map is just set as node 0's
|
||
*/
|
||
diff -urN --exclude-from=/usr/src/exclude-file linux-i386/scripts/mod/modpost.c linux-m68k/scripts/mod/modpost.c
|
||
--- linux-i386/scripts/mod/modpost.c 2006-09-20 05:42:06.000000000 +0200
|
||
+++ linux-m68k/scripts/mod/modpost.c 2006-09-24 16:35:30.000000000 +0200
|
||
@@ -1181,6 +1181,7 @@
|
||
buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n"
|
||
" .exit = cleanup_module,\n"
|
||
"#endif\n");
|
||
+ buf_printf(b, " .arch = MODULE_ARCH_INIT,\n");
|
||
buf_printf(b, "};\n");
|
||
}
|
||
|