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 #include #include +#include #include @@ -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 #include #include -#include #include #include #include @@ -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 #include #include @@ -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 #include +#include + +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 #include #include #include @@ -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 #include #include +#include #include #include #include @@ -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 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 + */ +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 +#include + +#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, + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +/*#include */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#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 " +#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 #include #include +#include #include #include @@ -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 #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 - -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 - -#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 #include "53c7xx.h" -#include "bvme6000.h" #include +#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 - -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 - -#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 #include "53c7xx.h" -#include "mvme16x.h" #include +#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 - -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 - -#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 #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 #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 +#include #include #include #include #include #include #include +#include #include #include #include @@ -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 -#include #include /* @@ -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 #ifdef __KERNEL__ @@ -27,6 +28,8 @@ #ifndef __ASSEMBLY__ +#include + #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 - #ifdef CONFIG_SUN3 #include #else #include #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 -#include +#include +#include -#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 #include #include +#include #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 */ 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 +#include #include #include -#ifdef CONFIG_AMIGA -#include -#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 #include #include #include 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 #include -#include #include -#include /* * 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 #include +#include /** * 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"); }