source: scripts/patches/linux-2.4.26-m68k-lfh.patch@ b023e30

clfs-1.2 clfs-2.1 clfs-3.0.0-systemd clfs-3.0.0-sysvinit systemd sysvinit
Last change on this file since b023e30 was 7f65c0e, checked in by Jim Gifford <clfs@…>, 19 years ago

r625@server (orig r623): jim | 2005-10-31 12:43:24 -0800
Final Move

  • Property mode set to 100644
File size: 222.5 KB
RevLine 
[617118d]1diff -Naur linux-2.4.26/Documentation/Configure.help linux-2.4.26-m68k/Documentation/Configure.help
2--- linux-2.4.26/Documentation/Configure.help 2004-04-14 23:05:24.000000000 +1000
3+++ linux-2.4.26-m68k/Documentation/Configure.help 2004-04-15 06:41:29.000000000 +1000
4@@ -17167,6 +17167,26 @@
5 say M here and read <file:Documentation/modules.txt>. If unsure,
6 say N.
7
8+Amiga SFS file system support
9+CONFIG_ASFS_FS
10+ The Amiga Smart FileSystem (SFS) is the file system used on hard
11+ disks by Amiga(tm) and MorphOS(tm) systems. Say Y if you want
12+ to be able to read files from an Amiga SFS partition on your hard
13+ drive.
14+
15+ This file system driver is in EXPERIMENTAL state. Use it with care.
16+ Although it CANNOT destroy your data (because it is a read-only
17+ driver) it MIGHT cause a crash in some circumstances.
18+
19+ For more information read <file:Documentation/filesystems/asfs.txt>
20+
21+ This file system is also available as a module ( = code which can be
22+ inserted in and removed from the running kernel whenever you want).
23+ The module is called affs.o. If you want to compile it as a module,
24+ say M here and read <file:Documentation/modules.txt>.
25+
26+ If unsure, say N.
27+
28 Apple HFS file system support
29 CONFIG_HFS_FS
30 If you say Y here, you will be able to mount Macintosh-formatted
31@@ -23357,6 +23377,29 @@
32
33 If you don't want to compile a kernel for a Sun 3x, say N.
34
35+TekXpress XP2x support
36+CONFIG_TEKXP
37+ This option enables support for the TekXpress XP2x series of
38+ X-Terminals made by Tektronix.
39+ You will also want to enable 68030 support below.
40+ Additional information about this port is available at
41+ <http://www-users.rwth-aachen.de/Michael.Mueller4/tekxp/tekxp.html>.
42+
43+ If you don't want to compile a kernel for TekXpress XP2x, say N.
44+
45+Kernel command line
46+CONFIG_BOOTCMD
47+ You have to specify a kernel commandline here.
48+ There will be no possiblity to change the content on run-time.
49+
50+Report as MVME160
51+CONFIG_TEKXP_REPORT_MVME
52+ Enabling this option the TekXpress X-Terminals report as
53+ Motorola MVME160 in /proc/harware (if available).
54+
55+ Say Y, if you intend to use this kernel to install the
56+ Debian/m68k Linux distribution. Otherwhise it is save to say N.
57+
58 Sun3x builtin serial support
59 CONFIG_SUN3X_ZS
60 ZS refers to a type of asynchronous serial port built in to the Sun3
61@@ -23810,6 +23853,18 @@
62 If you want to compile it as a module, say M here and read
63 <file:Documentation/modules.txt>.
64
65+TekXpress on-board Sonic support
66+CONFIG_TEKSONIC
67+ Say Y here if you want to use the integrated network controller of
68+ the TekXpress X-Terminals. If you do not modify it it is unlikely
69+ you will get Linux running without this selected.
70+
71+SCC2962 serial support
72+CONFIG_SCC2692
73+ Say Y here if you want to use the serial interfaces from user-space.
74+ It is safe to say N here, if it will only be used for the output of
75+ kernel messages.
76+
77 Support for early boot text console
78 CONFIG_BOOTX_TEXT
79 Say Y here to see progress messages from the boot firmware in text
80diff -Naur linux-2.4.26/Documentation/filesystems/00-INDEX linux-2.4.26-m68k/Documentation/filesystems/00-INDEX
81--- linux-2.4.26/Documentation/filesystems/00-INDEX 2004-02-19 00:36:30.000000000 +1100
82+++ linux-2.4.26-m68k/Documentation/filesystems/00-INDEX 2004-02-19 09:11:42.000000000 +1100
83@@ -6,6 +6,8 @@
84 - info and mount options for the Acorn Advanced Disc Filing System.
85 affs.txt
86 - info and mount options for the Amiga Fast File System.
87+asfs.txt
88+ - info and mount options for the Amiga Smart File System.
89 befs.txt
90 - info for the BeOS file system (BFS)
91 bfs.txt
92diff -Naur linux-2.4.26/Documentation/filesystems/asfs.txt linux-2.4.26-m68k/Documentation/filesystems/asfs.txt
93--- linux-2.4.26/Documentation/filesystems/asfs.txt 1970-01-01 10:00:00.000000000 +1000
94+++ linux-2.4.26-m68k/Documentation/filesystems/asfs.txt 2003-06-20 21:32:32.000000000 +1000
95@@ -0,0 +1,40 @@
96+
97+Amiga SmartFileSystem, Linux implementation
98+===========================================
99+
100+This is a simple read-only driver. It support reading files and directories.
101+Symbolic links (called soft links) are not supported yet. Don't even try
102+to read them.
103+
104+
105+Mount options for the ASFS
106+==========================
107+
108+setuid[=uid]
109+ This sets the owner of all files and directories in the file
110+ system to uid or the uid of the current user, respectively.
111+
112+setgid[=gid]
113+ Same as above, but for gid.
114+
115+mode=mode
116+ Sets the mode flags to the given (octal) value. Directories
117+ will get an x permission if the corresponding r bit is set.
118+ The default mode is 0444, which means all r bits are set
119+ (for directories this means also that all x bits are set).
120+
121+
122+Other information
123+=================
124+
125+Supported block sizes are: 512, 1024, 2048 and 4096 bytes. Larger blocks
126+speed up almost everything at the expense of wasted disk space. The speed
127+gain above 4K seems not really worth the price, so you don't lose too
128+much here, either.
129+
130+This file system hasn't been well tested yet. Athough it CANNOT destroy
131+your data, it MIGHT cause a crash. Sorry.
132+
133+This file system has been tested on Motorola PPC and Intel x86 systems.
134+It SHOULD also work on Motorola 68k. It probably WON'T work on other
135+systems (especially 64bit).
136diff -Naur linux-2.4.26/arch/m68k/Makefile linux-2.4.26-m68k/arch/m68k/Makefile
137--- linux-2.4.26/arch/m68k/Makefile 2001-06-12 12:15:27.000000000 +1000
138+++ linux-2.4.26-m68k/arch/m68k/Makefile 2003-07-22 07:26:06.000000000 +1000
139@@ -119,6 +119,11 @@
140 SUBDIRS := $(SUBDIRS) arch/m68k/sun3 arch/m68k/sun3/prom
141 endif
142
143+ifdef CONFIG_TEKXP
144+CORE_FILES := $(CORE_FILES) arch/m68k/tekxp/tekxp.o
145+SUBDIRS := $(SUBDIRS) arch/m68k/tekxp
146+endif
147+
148 ifdef CONFIG_M68040
149 CORE_FILES := $(CORE_FILES) arch/m68k/fpsp040/fpsp.o
150 SUBDIRS := $(SUBDIRS) arch/m68k/fpsp040
151@@ -172,5 +177,6 @@
152 rm -f arch/m68k/kernel/m68k_defs.h arch/m68k/kernel/m68k_defs.d
153
154 archmrproper:
155+ rm -f arch/m68k/boot/bootstrap bootstrap
156
157 archdep:
158diff -Naur linux-2.4.26/arch/m68k/boot/Makefile linux-2.4.26-m68k/arch/m68k/boot/Makefile
159--- linux-2.4.26/arch/m68k/boot/Makefile 1970-01-01 10:00:00.000000000 +1000
160+++ linux-2.4.26-m68k/arch/m68k/boot/Makefile 2003-07-22 07:26:07.000000000 +1000
161@@ -0,0 +1,15 @@
162+
163+ifdef CONFIG_TEKXP
164+.PHONY: bootstrap
165+bootstrap: boot.o
166+ $(LD) -T tekxp.ld -Ttext 0x1000 -o $@ $<
167+ -rm -f ../../../bootstrap
168+ dd if=$@ of=../../../bootstrap bs=4096 conv=sync
169+ $(STRIP) -s -o vmlinux.s ../../../vmlinux
170+ cat vmlinux.s >> ../../../bootstrap
171+
172+boot.o: boot.S
173+ $(CC) -c -o $@ -m68030 -O2 -I$(HPATH) -D__ASSEMBLY__ -DDEBUG $<
174+
175+endif
176+
177diff -Naur linux-2.4.26/arch/m68k/boot/boot.S linux-2.4.26-m68k/arch/m68k/boot/boot.S
178--- linux-2.4.26/arch/m68k/boot/boot.S 1970-01-01 10:00:00.000000000 +1000
179+++ linux-2.4.26-m68k/arch/m68k/boot/boot.S 2003-07-22 07:26:07.000000000 +1000
180@@ -0,0 +1,744 @@
181+/*
182+ * linux/arch/m68k/boot/boot.S
183+ *
184+ * Copyright (C) 2002,2003 Michael Mueller <malware@t-online.de>
185+ *
186+ * Parts taken from head.S.
187+ *
188+ * This file is subject to the terms and conditions of the GNU General Public
189+ * license. See the file COPYING in the main directory of this archive for
190+ * more details.
191+ */
192+
193+/*
194+ * This is a wrapper to the linux kernel. Compiled as a.out binary it can be
195+ * used to bootstrap the Linux kernel using the TekXpress Boot Monitor.
196+ *
197+ * In general it does copy the kernel image to the end of the available
198+ * memory and does rearrange it to the top memory as described within the
199+ * ELF header of wrapped vmlinux file.
200+ *
201+ * On some of the TekXpress systems there is not enough continous memory
202+ * available to fit the whole kernel into. Thus this code does enable the
203+ * MMU which is rather unusual.
204+ */
205+
206+#include <linux/config.h>
207+#include <linux/linkage.h>
208+#include <linux/init.h>
209+#include <asm/bootinfo.h>
210+#include <asm/setup.h>
211+#include <asm/pgtable.h>
212+#include <asm/page.h>
213+
214+/***********************************************************************/
215+
216+/*
217+ * Little helpers for defining functions
218+ */
219+
220+#ifdef __STDC__
221+#define L(name) .L##name
222+#else
223+#define L(name) .L/**/name
224+#endif
225+
226+#define STACK %a6@(stackstart)
227+#define ARG0 %a6@(4)
228+#define ARG1 %a6@(8)
229+#define ARG2 %a6@(12)
230+#define ARG3 %a6@(16)
231+#define ARG4 %a6@(20)
232+
233+.macro func_start name,saveregs,stack=0
234+L(\name):
235+ linkw %a6,#-\stack
236+ moveml \saveregs,%sp@-
237+.set stackstart,-\stack
238+
239+.macro func_return_\name
240+ moveml %sp@+,\saveregs
241+ unlk %a6
242+ rts
243+.endm
244+.endm
245+
246+.macro func_return name
247+ func_return_\name
248+.endm
249+
250+.macro func_call name
251+ jbsr L(\name)
252+.endm
253+
254+.macro move_stack nr,arg1,arg2,arg3,arg4
255+.if \nr
256+ move_stack "(\nr-1)",\arg2,\arg3,\arg4
257+ movel \arg1,%sp@-
258+.endif
259+.endm
260+
261+.macro func_define name,nr=0
262+.macro \name arg1,arg2,arg3,arg4
263+ move_stack \nr,\arg1,\arg2,\arg3,\arg4
264+ func_call \name
265+.if \nr
266+ lea %sp@(\nr*4),%sp
267+.endif
268+.endm
269+.endm
270+
271+/***********************************************************************/
272+
273+/*
274+ * Start of the code (not entry point!)
275+ */
276+.text
277+ENTRY(_stext)
278+
279+/*
280+ * This is a faked a.out Header
281+ */
282+.long 0x10B /* a.out magic number */
283+.long SYMBOL_NAME(__end) - header_end
284+ /* size of content = size of text segment */
285+.long 0
286+.long 0
287+.long 0
288+.long SYMBOL_NAME(__start) /* entry point */
289+.long 0
290+.long 0
291+header_end:
292+
293+/*
294+ * Platform specific constants
295+ */
296+#define MEMSTART 0xF0000000 /* start address of CPU RAM */
297+#define OPTRAMSTART 0xF4000000 /* start address of Option RAM */
298+#define MEMCHUNK 0x01000000 /* spacing beetween memory chunks */
299+#define MEMORY_MAP_ENTRIES 8 /* number of memory chunks */
300+
301+/*
302+ * MMU definitions
303+ */
304+PAGESIZE = 4096
305+PAGESHIFT = 12
306+ROOT_TABLE_SIZE = 128
307+PTR_TABLE_SIZE = 128
308+PAGE_TABLE_SIZE = 64
309+ROOT_INDEX_SHIFT = 25
310+PTR_INDEX_SHIFT = 18
311+PAGE_INDEX_SHIFT = 12
312+
313+/*
314+ * Function declarations
315+ */
316+func_define mmu_map,4
317+func_define mmu_get_root_table_entry,1
318+func_define mmu_get_ptr_table_entry,2
319+func_define build_memory_list
320+func_define dump_memory_list
321+func_define get_kernel_size
322+func_define get_kernel_start
323+func_define get_kernel_physical_headers
324+func_define get_kernel_entry
325+
326+/*
327+ * Translation tables.
328+ *
329+ * These have to be located at the same position as within head.S. As
330+ * they are references from the kernel later.
331+ */
332+.equ SYMBOL_NAME(kernel_pg_dir),SYMBOL_NAME(_stext)
333+.equ SYMBOL_NAME(kernel_ptr_dir1),SYMBOL_NAME(kernel_pg_dir)+ROOT_TABLE_SIZE*4
334+.equ SYMBOL_NAME(kernel_ptr_dir2),SYMBOL_NAME(kernel_ptr_dir1)+PTR_TABLE_SIZE*4
335+.equ SYMBOL_NAME(kernel_ptr_dir3),SYMBOL_NAME(kernel_ptr_dir2)+PTR_TABLE_SIZE*4
336+.equ SYMBOL_NAME(kernel_ptr_dir4),SYMBOL_NAME(kernel_ptr_dir3)+PTR_TABLE_SIZE*4
337+.equ .,SYMBOL_NAME(_stext)+PAGESIZE /* Skip to end of page */
338+
339+/*
340+ * Functions for debugging output
341+ */
342+func_define serial_init
343+func_define putc,1
344+func_define putn,1
345+func_define puts,1
346+func_define dump,2
347+
348+.macro dputc ch
349+#ifdef DEBUG
350+ putc \ch
351+#endif
352+.endm
353+
354+.macro putr
355+ putc '\r'
356+ putc '\n'
357+.endm
358+
359+.macro dputr
360+#ifdef DEBUG
361+ putr
362+#endif
363+.endm
364+
365+.macro dputn nr
366+#ifdef DEBUG
367+ putn \nr
368+#endif
369+.endm
370+
371+.macro puts string
372+ .data
373+.Lstr\@:
374+ .asciz "\string"
375+ .previous
376+ pea %pc@(.Lstr\@)
377+ func_call puts
378+ addql #4,%sp
379+.endm
380+
381+.macro dputs string
382+#ifdef DEBUG
383+ puts "\string"
384+#endif
385+.endm
386+
387+func_start puts,%d0/%a0
388+ movl ARG1,%a0
389+1:
390+ movb %a0@+,%d0
391+ beqs 2f
392+ putc %d0
393+ bras 1b
394+2:
395+func_return puts
396+
397+func_start putn,%d0-%d2
398+ movl ARG1,%d0
399+ movl #7,%d1
400+1:
401+ roll #4,%d0
402+ movl %d0,%d2
403+ andb #15,%d2
404+ addb #'0',%d2
405+ cmpb #'9',%d2
406+ jls 2f
407+ addb #'A'-('9'+1),%d2
408+2:
409+ putc %d2
410+ dbra %d1,1b
411+ putc #' '
412+func_return putn
413+
414+func_start putc,%d0/%a0
415+ movl #0xFF800000,%a0
416+1:
417+ movb 4(%a0),%d0
418+ andb #4,%d0
419+ tstb %d0
420+ bne 2f
421+ bra 1b
422+2:
423+ movl ARG1,%d0
424+ movb %d0,12(%a0)
425+func_return putc
426+
427+func_start dump,%d0/%a0
428+ movl ARG1,%a0
429+ movl ARG2,%d0
430+1:
431+ putn %a0
432+ putn %a0@
433+ putn %a0@(4)
434+ putn %a0@(8)
435+ putn %a0@(12)
436+ putn %a0@(16)
437+ putn %a0@(20)
438+ putn %a0@(24)
439+ putn %a0@(28)
440+ putc #'\r'
441+ putc #'\n'
442+ addl #32,%a0
443+ subl #32,%d0
444+ bpl 1b
445+func_return dump
446+
447+func_start serial_init,%a0
448+ movl #0xFF800000,%a0 /* address of UART */
449+ clrb 0x34(%a0)
450+ movb #0x80,0x10(%a0) /* ACR: baud rate set 2 */
451+ clrb 0x14(%a0) /* reset interrupt mask */
452+ movb #0x10,8(%a0) /* CRA: reset MR pointer */
453+ movb #0x20,8(%a0)
454+ movb #0x30,8(%a0)
455+ movb #2,(%a0) /* 7 bits per char */
456+ movb #7,(%a0) /* one stop bit */
457+ movb #0xBB,4(%a0) /* 9600 baud */
458+ movb #5,8(%a0) /* enable tx and rx */
459+func_return serial_init
460+
461+.macro putc ch
462+ pea \ch
463+ func_call putc
464+ addql #4,%sp
465+.endm
466+
467+
468+
469+/*
470+ * Entry into the code
471+ */
472+ENTRY(__start)
473+
474+ /* Use the first 256 byte of memory as scratch area
475+ */
476+ movl #MEMSTART+0x100, %sp
477+
478+ /* Initialize the serial port
479+ */
480+ serial_init
481+ dputs "\r\nLinux@TekXP starting...\r\n"
482+
483+ /* Build a memory map for later usage
484+ */
485+ putc 'a'
486+ build_memory_list
487+/* dump_memory_list */
488+
489+ /* Clear the translation tables
490+ */
491+ dputc 'b'
492+ movl #PAGESIZE/4-1,%d0
493+ lea %pc@(SYMBOL_NAME(kernel_pg_dir)),%a0
494+1:
495+ clrl %a0@+
496+ dbra %d0,1b
497+
498+ /* Setup pointer tables for virtual addresses starting at 0 and
499+ * the current PC.
500+ * We need 4 pointer tables at maximum for 128MB.
501+ * Since both memory ranges should map equal we simple use the
502+ * same pointer tables for both.
503+ */
504+ dputc 'c'
505+ lea %pc@(SYMBOL_NAME(_stext)),%a0
506+ movl %a0,%d0
507+ movl #ROOT_INDEX_SHIFT,%d1
508+ lsrl %d1,%d0
509+
510+ lea %pc@(SYMBOL_NAME(kernel_pg_dir)),%a0
511+ lea %pc@(SYMBOL_NAME(kernel_ptr_dir1)+_PAGE_TABLE+_PAGE_ACCESSED),%a1
512+ movl %a1,%a0@(%d0:l:4)
513+ movl %a1,%a0@+
514+ lea %pc@(SYMBOL_NAME(kernel_ptr_dir2)+_PAGE_TABLE+_PAGE_ACCESSED),%a1
515+ movl %a1,%a0@(%d0:l:4)
516+ movl %a1,%a0@+
517+ lea %pc@(SYMBOL_NAME(kernel_ptr_dir3)+_PAGE_TABLE+_PAGE_ACCESSED),%a1
518+ movl %a1,%a0@(%d0:l:4)
519+ movl %a1,%a0@+
520+ lea %pc@(SYMBOL_NAME(kernel_ptr_dir4)+_PAGE_TABLE+_PAGE_ACCESSED),%a1
521+ movl %a1,%a0@(%d0:l:4)
522+ movl %a1,%a0@+
523+
524+ /* Setup early terminator pages for hardware access */
525+ dputc 'd'
526+ lea %pc@(SYMBOL_NAME(kernel_pg_dir) + 127*4),%a1
527+ movl #0xFE000000+_PAGE_PRESENT+_PAGE_ACCESSED+_PAGE_DIRTY+_PAGE_NOCACHE030,%d1
528+ movl %d1,%a1@
529+
530+ /* Map the memory to appear linear
531+ */
532+ dputc 'e'
533+ clrl %d0 /* virtual address */
534+ lea %pc@(Lmemory_list),%a0
535+1:
536+ movl %a0@+,%a1 /* address */
537+ movl %a0@+,%d1 /* size */
538+ tstl %a1
539+ beqs 2f
540+ mmu_map %d0,%a1,%d1,#_PAGE_NOCACHE030
541+ addl %d1,%d0
542+ bras 1b
543+2:
544+ lea %pc@(Lmemory_last),%a0
545+ movl %d0,%a0@
546+
547+#if 0
548+ lea %pc@(SYMBOL_NAME(kernel_pg_dir)),%a0
549+ dump %a0,#PAGESIZE
550+#endif
551+
552+ /* Enable the MMU
553+ */
554+ dputc 'f'
555+ .chip 68030
556+ lea %pc@(Lmmu_engage_030_temp),%a0
557+ movel #0x80000002,%a0@
558+ lea %pc@(SYMBOL_NAME(kernel_pg_dir)),%a1
559+ movl %a1,%a0@(4)
560+ movl #0x0808,%d0
561+ movec %d0,%cacr
562+ pmove %a0@,%srp
563+ pflusha
564+ movl #0x82c07760,%a0@(8)
565+ pmove %a0@(8),%tc
566+ jmp 1f:l
567+1:
568+ movl #0x0808,%d0
569+ movec %d0,%cacr
570+ pflusha
571+ .chip 68k
572+
573+ /* Fix the stack
574+ */
575+ movl #0x100,%sp
576+
577+ /* Remove the now unneeded mappings (5 mappings remain, 4 at top) */
578+ dputc 'g'
579+ movl #SYMBOL_NAME(kernel_pg_dir)+16,%a0
580+ movl #ROOT_TABLE_SIZE-6,%d0
581+1:
582+ clrl %a0@+
583+ dbra %d0,1b
584+
585+ /* Move yourself and the kernel to end of the memory
586+ */
587+ dputc 'h'
588+ get_kernel_size
589+ addl #SYMBOL_NAME(__end)+4095,%d0
590+ andl #-PAGESIZE,%d0
591+ movl Lmemory_last,%a1
592+ subl %d0,%a1
593+ movl %a1,Lmemory_last
594+ movl #0,%a0
595+ lsrl #2,%d0
596+1:
597+ subl #1,%d0
598+ bmi 2f
599+ movl %a0@+,%a1@+
600+ bras 1b
601+2:
602+ movl Lmemory_last,%a0
603+ jmpl %a0@(3f)
604+
605+3:
606+ dputc 'i'
607+
608+ /*
609+ * Loop through the sections of the kernel and copy them over.
610+ */
611+
612+ get_kernel_start /* in %a0 */
613+ movel %a0,%a1 /* offset of all numbers */
614+ clrl %d3 /* end of bss */
615+
616+ get_kernel_physical_headers /* count in d0, first in %a0 */
617+ subl #32,%a0
618+
619+1:
620+ dputc 'j'
621+ subl #1,%d0
622+ bmi 5f
623+ addl #32,%a0
624+
625+ movel %a0@(4),%a2 /* file offset */
626+ addl %a1,%a2 /* current memory address */
627+
628+ movel %a0@(8),%a3 /* load memory address */
629+ movel %a0@(16),%d1 /* file size */
630+ movel %a0@(20),%d2 /* memory size */
631+
632+ cmpl #SYMBOL_NAME(_stext)+PAGESIZE,%a3
633+ bpl 2f
634+
635+ movl #SYMBOL_NAME(_stext)+PAGESIZE,%d3
636+ subl %a3,%d3 /* how much is below */
637+
638+ addl %d3,%a3 /* move it up */
639+ addl %d3,%a2 /* move it up */
640+
641+ subl %d3,%d2
642+ bmi 1b /* nothing left */
643+
644+ subl %d3,%d1
645+ bmi 4f
646+2:
647+ subl %d1,%d2 /* do not clear what is in file */
648+ bpl 3f
649+ addl %d1,%d2
650+ movl %d2,%d1
651+ clrl %d2
652+
653+3:
654+ subl #1,%d1
655+ bmi 4f
656+ moveb %a2@+,%a3@+
657+ bras 3b
658+
659+4: /* clear */
660+ lea %a3@(%d2),%a4
661+ cmpl %a4,%d3
662+ bpl 4f
663+ movl %a4,%d3
664+4:
665+
666+ subl #1,%d2
667+ bmi 1b
668+ clrb %a3@+
669+ bras 4b
670+5:
671+
672+ /*
673+ * Create a boot info record
674+ */
675+ dputc 'k'
676+ addl #PAGESIZE-1,%d3
677+ andl #-PAGE_SIZE,%d3
678+ movl %d3,%a0
679+
680+ movw #BI_MACHTYPE,%a0@+
681+ movw #8,%a0@+
682+ movl #MACH_TEKXP,%a0@+
683+
684+ movw #BI_CPUTYPE,%a0@+
685+ movw #8,%a0@+
686+ movl #CPU_68030,%a0@+
687+
688+ movw #BI_FPUTYPE,%a0@+
689+ movw #8,%a0@+
690+ movl #0,%a0@+
691+
692+ movw #BI_MMUTYPE,%a0@+
693+ movw #8,%a0@+
694+ movl #MMU_68030,%a0@+
695+
696+ lea %pc@(Lmemory_list),%a1
697+1:
698+ movel %a1@+,%d1
699+ movel %a1@+,%d0
700+ tstl %d1
701+ beqs 2f
702+ movw #BI_MEMCHUNK,%a0@+
703+ movw #12,%a0@+
704+ movl %d1,%a0@+
705+ movl %d0,%a0@+
706+ bras 1b
707+2:
708+
709+ movw #BI_LAST,%a0@+
710+ clrw %a0@+
711+
712+ /* jump into the kernel */
713+ dputc 'l'
714+ get_kernel_entry
715+ jmpl %a0@
716+
717+/*
718+ * Get the position of the kernels ELF header. It is located on the next
719+ * page after this wrapper program.
720+ */
721+
722+func_start get_kernel_start,%d0
723+ lea %pc@(__end+PAGESIZE-1),%a0
724+ movl %a0,%d0
725+ andl #-PAGESIZE,%d0
726+ movl %d0,%a0
727+func_return get_kernel_start
728+
729+/*
730+ * Read the entry point of the ELF executable.
731+ */
732+
733+func_start get_kernel_entry,%d0
734+ get_kernel_start
735+ movl %a0@(0x18),%a0
736+func_return get_kernel_entry
737+
738+/*
739+ * Get the address of the first physical header (into %a0) and the number
740+ * of those headers present (into %d0).
741+ */
742+func_start get_kernel_physical_headers,%d1
743+ get_kernel_start
744+ clrl %d0
745+ movw %a0@(0x2C),%d0 /* Number of headers */
746+ movl %a0@(0x1C),%d1 /* Offset of the table */
747+ lea %a0@(%d1),%a0
748+func_return get_kernel_physical_headers
749+
750+/*
751+ * Calculate the size kernel image. Notice this is not its final footprint.
752+ */
753+func_start get_kernel_size,%d1/%d2/%a0
754+ get_kernel_physical_headers
755+ clrl %d1
756+1:
757+ subl #1,%d0
758+ bmi 3f
759+ movl %a0@(4),%d2
760+ addl %a0@(16),%d2
761+ cmpl %d2,%d1
762+ bpl 2f
763+ movl %d2,%d1
764+2:
765+ addl #32,%a0
766+ bras 1b
767+3:
768+ movl %d1,%d0
769+func_return get_kernel_size
770+
771+
772+/*
773+ * Fetch the memory configuration and store it in a field for later
774+ * retrieval.
775+ */
776+func_start build_memory_list,%a2/%a4/%d0/%d1
777+ lea %pc@(Lmemory_list),%a4
778+
779+ movl #MEMSTART,%a2
780+ bfextu 0xFFD00003{4:4},%d0
781+ movl %pc@(Lcpsram_bitmap_table,%d0:l:4),%d0
782+1:
783+ tstl %d0
784+ beqs 2f
785+ movl %d0,%d1
786+ andl #3,%d1
787+ movl %pc@(Ldram_size_table,%d1:l:4),%d1
788+ movl %a2,%a4@+
789+ movl %d1,%a4@+
790+ addl #MEMCHUNK,%a2
791+ lsrl #2,%d0
792+ bras 1b
793+2:
794+ bfextu 0xFFD00003{0:1},%d0
795+ tstl %d0
796+ bnes 4f
797+ movl #OPTRAMSTART,%a2
798+ bfextu 0xFFD00003{1:3},%d0
799+ movl %pc@(Lcporam_bitmap_table,%d0:l:4),%d0
800+3:
801+ tstl %d0
802+ beqs 4f
803+ movl %d0,%d1
804+ andl #3,%d1
805+ movl %pc@(Ldram_size_table,%d1:l:4),%d1
806+ movl %a2,%a4@+
807+ movl %d1,%a4@+
808+ addl #MEMCHUNK,%a2
809+ lsrl #2,%d0
810+ bras 3b
811+4:
812+func_return build_memory_list
813+
814+Ldram_size_table:
815+ .long 0
816+ .long 0x100000
817+ .long 0x400000
818+ .long 0x040000
819+
820+Lcporam_bitmap_table:
821+ .long 0xAA
822+ .long 0x2A
823+ .long 0x0A
824+ .long 0x02
825+ .long 0x55
826+ .long 0x05
827+ .long 0x01
828+ .long 0x15
829+
830+Lcpsram_bitmap_table:
831+ .long 0x95
832+ .long 0x01
833+ .long 0x05
834+ .long 0x15
835+ .long 0x55
836+ .long 0x06
837+ .long 0x16
838+ .long 0x56
839+ .long 0x0A
840+ .long 0x1A
841+ .long 0x5A
842+ .long 0xA5
843+ .long 0x2A
844+ .long 0x6A
845+ .long 0x02
846+ .long 0xAA
847+
848+
849+/*
850+ * Memory mapping functions from head.S. (shortened)
851+ */
852+
853+func_start mmu_map,%d0-%d4/%a0-%a4
854+ /* Get the logical address, it is assumed to be rounded to 256KiB */
855+ movl ARG1,%a3
856+
857+ /* Get the end address. The length should be rounded to 256KiB */
858+ movl %a3,%a4
859+ addl ARG3,%a4
860+ subql #1,%a4
861+
862+ /* Get the physical address, assumed to be rounded to 256KiB too */
863+ movl ARG2,%a2
864+
865+ /* Augment the physical address with page attributes */
866+ movl ARG4,%d0
867+ orw #_PAGE_PRESENT+_PAGE_ACCESSED+_PAGE_DIRTY,%d0
868+ addw %d0,%a2
869+
870+1:
871+ /* Calculate the offset into the root table */
872+ movl %a3,%d0
873+ movl #ROOT_INDEX_SHIFT,%d1
874+ lsrl %d1,%d0
875+ mmu_get_root_table_entry %d0
876+
877+ /* Calculate the offset into the pointer table */
878+ movl %a3,%d0
879+ movl #PTR_INDEX_SHIFT,%d1
880+ lsrl %d1,%d0
881+ andl #PTR_TABLE_SIZE-1,%d0
882+ mmu_get_ptr_table_entry %a0,%d0
883+
884+
885+ movl %a2,%a0@
886+ addl #PAGE_TABLE_SIZE*PAGESIZE,%a2
887+ addl #PAGE_TABLE_SIZE*PAGESIZE,%a3
888+
889+ lea %a3@(-1),%a0
890+ cmpl %a0,%a4
891+ jhi 1b
892+
893+func_return mmu_map
894+
895+func_start mmu_get_root_table_entry,%d0
896+ movl ARG1,%d0
897+ lea %pc@(SYMBOL_NAME(kernel_pg_dir),%d0:l:4),%a0
898+func_return mmu_get_root_table_entry
899+
900+func_start mmu_get_ptr_table_entry,%d0
901+ movl ARG1,%a0
902+ movl %a0@,%d0
903+ andw #-PTR_TABLE_SIZE,%d0
904+ movl %d0,%a0
905+ movl ARG2,%d0
906+ lea %a0@(%d0:l:4),%a0
907+func_return mmu_get_ptr_table_entry
908+
909+
910+
911+
912+.data
913+Lmmu_engage_030_temp:
914+ .space 12
915+
916+Lmemory_last:
917+ .long 0 /* end of virtual memory */
918+
919+Lmemory_list:
920+ .rept MEMORY_MAP_ENTRIES
921+ .long 0 /* address */
922+ .long 0 /* size */
923+ .endr
924+
925diff -Naur linux-2.4.26/arch/m68k/boot/tekxp.ld linux-2.4.26-m68k/arch/m68k/boot/tekxp.ld
926--- linux-2.4.26/arch/m68k/boot/tekxp.ld 1970-01-01 10:00:00.000000000 +1000
927+++ linux-2.4.26-m68k/arch/m68k/boot/tekxp.ld 2003-07-22 07:26:07.000000000 +1000
928@@ -0,0 +1,36 @@
929+OUTPUT_FORMAT("binary")
930+ENTRY(__start)
931+SECTIONS
932+{
933+ .text :
934+ {
935+ *(.init)
936+ *(.text)
937+ ___CTOR_LIST__ = .;
938+ LONG((___CTOR_END__ - ___CTOR_LIST__) / 4 - 2)
939+ *(.ctors)
940+ LONG(0)
941+ ___CTOR_END__ = .;
942+ ___DTOR_LIST__ = .;
943+ LONG((___DTOR_END__ - ___DTOR_LIST__) / 4 - 2)
944+ *(.dtors)
945+ LONG(0)
946+ ___DTOR_END__ = .;
947+ *(.fini)
948+ etext = .;
949+ __etext = .;
950+ }
951+ .data SIZEOF(.text) + ADDR(.text) :
952+ {
953+ *(.data .data2)
954+ edata = .;
955+ __edata = .;
956+ }
957+ .bss SIZEOF(.data) + ADDR(.data) :
958+ {
959+ *(.bss)
960+ *(COMMON)
961+ end = .;
962+ __end = .;
963+ }
964+}
965diff -Naur linux-2.4.26/arch/m68k/config.in linux-2.4.26-m68k/arch/m68k/config.in
966--- linux-2.4.26/arch/m68k/config.in 2004-02-19 00:36:30.000000000 +1100
967+++ linux-2.4.26-m68k/arch/m68k/config.in 2004-02-19 09:12:42.000000000 +1100
968@@ -56,7 +56,14 @@
969 fi
970 bool 'Sun3x support' CONFIG_SUN3X
971 bool 'Sun3 support' CONFIG_SUN3
972-
973+bool 'TekXpress 2x support' CONFIG_TEKXP
974+if [ "$CONFIG_TEKXP" = "y" ] ; then
975+ define_bool CONFIG_PSMOUSE y
976+ define_bool CONFIG_NO_CMDLINE y
977+ string ' Kernel command line' CONFIG_BOOTCMD "root=nfs ip=192.168.3.10:192.168.2.1:192.168.3.1:255.255.255.0:tek.malware.de:eth0:none nfsroot=192.168.2.1:/tftpboot/XP20"
978+ bool ' Report as MVME160' CONFIG_TEKXP_REPORT_MVME
979+fi
980+
981 bool 'Q40/Q60 support' CONFIG_Q40
982
983 comment 'Processor type'
984@@ -365,6 +372,9 @@
985 fi
986 dep_tristate 'NE2000/NE1000 support' CONFIG_NE2000 m
987 fi
988+ if [ "$CONFIG_TEKXP" = "y" ]; then
989+ bool ' TekXpress on-board Sonic support' CONFIG_TEKSONIC
990+ fi
991 fi
992 endmenu
993
994@@ -474,6 +484,10 @@
995 define_tristate CONFIG_SERIAL $CONFIG_DN_SERIAL
996 fi
997
998+if [ "$CONFIG_TEKXP" = "y" ] ; then
999+ tristate 'SCC2962 serial support' CONFIG_SCC2692
1000+fi
1001+
1002 if [ "$CONFIG_SUN3" = "y" -o "$CONFIG_SUN3X" = "y" ]; then
1003 bool 'Sun3/3x builtin serial support' CONFIG_SUN3X_ZS
1004 else
1005@@ -499,7 +513,7 @@
1006 "$CONFIG_SUN3X_ZS" = "y" -o "$CONFIG_SERIAL" = "y" -o \
1007 "$CONFIG_MVME147_SCC" -o "$CONFIG_SERIAL167" = "y" -o \
1008 "$CONFIG_MVME162_SCC" -o "$CONFIG_BVME6000_SCC" = "y" -o \
1009- "$CONFIG_DN_SERIAL" ]; then
1010+ "$CONFIG_DN_SERIAL" = "y" -o "$CONFIG_SCC2692" = "y" ]; then
1011 bool 'Support for serial port console' CONFIG_SERIAL_CONSOLE
1012 fi
1013 bool 'Support for user serial device modules' CONFIG_USERIAL
1014diff -Naur linux-2.4.26/arch/m68k/kernel/head.S linux-2.4.26-m68k/arch/m68k/kernel/head.S
1015--- linux-2.4.26/arch/m68k/kernel/head.S 2003-06-14 00:51:31.000000000 +1000
1016+++ linux-2.4.26-m68k/arch/m68k/kernel/head.S 2003-07-22 07:21:27.000000000 +1000
1017@@ -39,6 +39,12 @@
1018 * Disabled caches
1019 * Put us in supervisor state.
1020 *
1021+ * On TekXpress (CONFIG_TEKXP) the boat loader enables the MMU since
1022+ * there might not be enough physically continues memory available
1023+ * for the kernel (e.g. 6 x 1MB memory configuration). The mapping is
1024+ * 1:1 for the first chunk of physical memory and does use the same
1025+ * table sizes as the temporary memory map used during enabling the MMU.
1026+ *
1027 * The kernel setup code takes the following steps:
1028 * . Raise interrupt level
1029 * . Set up initial kernel memory mapping.
1030@@ -480,6 +486,14 @@
1031 addql #4,%sp
1032 .endm
1033
1034+.macro get_bi_record_continue record,recsize,binfo
1035+ movel \binfo,%sp@-
1036+ movel \recsize,%sp@-
1037+ pea \record
1038+ func_call get_bi_record_continue
1039+ addl #12,%sp
1040+.endm
1041+
1042 func_define serial_putc,1
1043 func_define console_putc,1
1044
1045@@ -543,6 +557,7 @@
1046 #define is_not_apollo(lab) cmpl &MACH_APOLLO,%pc@(m68k_machtype); jne lab
1047 #define is_not_q40(lab) cmpl &MACH_Q40,%pc@(m68k_machtype); jne lab
1048 #define is_not_sun3x(lab) cmpl &MACH_SUN3X,%pc@(m68k_machtype); jne lab
1049+#define is_not_tekxp(lab) cmpl &MACH_TEKXP,%pc@(m68k_machtype); jne lab
1050
1051 #define hasnt_leds(lab) cmpl &MACH_HP300,%pc@(m68k_machtype); \
1052 jeq 42f; \
1053@@ -587,6 +602,7 @@
1054 .long MACH_BVME6000, BVME6000_BOOTI_VERSION
1055 .long MACH_MAC, MAC_BOOTI_VERSION
1056 .long MACH_Q40, Q40_BOOTI_VERSION
1057+ .long MACH_TEKXP, TEKXP_BOOTI_VERSION
1058 .long 0
1059 1: jra SYMBOL_NAME(__start)
1060
1061@@ -993,6 +1009,40 @@
1062
1063 leds 0x4
1064
1065+#ifdef CONFIG_TEKXP
1066+ is_not_tekxp(5f)
1067+
1068+ get_bi_record BI_LAST
1069+ addw #PAGESIZE-1,%a0
1070+ movel %a0,%d2
1071+ andw #-PAGESIZE,%d2
1072+
1073+ /* Convert it into a physical address */
1074+ movl %d2,%d1
1075+ get_bi_record BI_MEMCHUNK
1076+1:
1077+ cmpl #-1,%d0
1078+ beqs 2f
1079+ subl %a0@(4),%d1
1080+ bcs 4f
1081+ get_bi_record_continue BI_MEMCHUNK,%d0,%a0
1082+ bras 1b
1083+4:
1084+ movl %d1,%d0
1085+ addl %a0@(4),%d0
1086+ addl %a0@,%d0
1087+ bras 3f
1088+2:
1089+ movl %d2,%d0
1090+3:
1091+
1092+ movel %d0,availmem
1093+
1094+ /* Skip all the MMU stuff here */
1095+ bra L(engage_done)
1096+5:
1097+#endif
1098+
1099 /*
1100 * mmu_init
1101 *
1102@@ -1310,11 +1360,22 @@
1103
1104 putc 'P'
1105 mmu_map #0x80000000,#0,#0x02000000,#_PAGE_NOCACHE030
1106-
1107-L(notapollo):
1108 jbra L(mmu_init_done)
1109+
1110+L(notapollo):
1111 #endif
1112
1113+#ifdef CONFIG_TEKXP
1114+ is_not_tekxp(L(nottekxp))
1115+
1116+ putc 'P'
1117+ mmu_map_tt #0,#0xff000000,#0x01000000,#_PAGE_NOCACHE030
1118+
1119+L(nottekxp):
1120+#endif
1121+
1122+ jbra L(mmu_init_done)
1123+
1124 L(mmu_init_done):
1125
1126 putc 'G'
1127@@ -1442,6 +1503,8 @@
1128
1129 movel L(memory_start),availmem
1130
1131+L(engage_done):
1132+
1133 #ifdef CONFIG_AMIGA
1134 is_not_amiga(1f)
1135 /* fixup the Amiga custom register location before printing */
1136@@ -1572,10 +1635,7 @@
1137 * Returns: d0: size (-1 if not found)
1138 * a0: data pointer (end-of-records if not found)
1139 */
1140-func_start get_bi_record,%d1
1141-
1142- movel ARG1,%d0
1143- lea %pc@(SYMBOL_NAME(_end)),%a0
1144+.macro get_bi_record_core
1145 #ifndef CONFIG_HP300
1146 1: tstw %a0@(BIR_TAG)
1147 jeq 3f
1148@@ -1591,8 +1651,22 @@
1149 lea %a0@(BIR_SIZE),%a0
1150 4:
1151 #endif /* CONFIG_HP300 */
1152+.endm
1153+
1154+func_start get_bi_record,%d1
1155+
1156+ movel ARG1,%d0
1157+ lea %pc@(SYMBOL_NAME(_end)),%a0
1158+ get_bi_record_core
1159 func_return get_bi_record
1160
1161+func_start get_bi_record_continue,%d1
1162+ movl ARG3,%a0
1163+ addl ARG2,%a0
1164+ subl #BIR_DATA,%a0
1165+ movl ARG1,%d0
1166+ get_bi_record_core
1167+func_return get_bi_record_continue
1168
1169 /*
1170 * MMU Initialization Begins Here
1171@@ -3020,6 +3094,27 @@
1172 /* We count on the PROM initializing SIO1 */
1173 #endif
1174
1175+#ifdef CONFIG_TEKXP
1176+#if 0
1177+ is_not_tekxp(1f)
1178+ movl %a0,-(%sp)
1179+ movl #0xFF800000,%a0 /* address of UART */
1180+ clrb 0x34(%a0)
1181+ movb #0x80,0x10(%a0) /* ACR: baud rate set 2 */
1182+ clrb 0x14(%a0) /* reset interrupt mask */
1183+ movb #0x10,8(%a0) /* CRA: reset MR pointer */
1184+ movb #0x20,8(%a0)
1185+ movb #0x30,8(%a0)
1186+ movb #2,(%a0) /* 7 bits per char */
1187+ movb #7,(%a0) /* one stop bit */
1188+ movb #0xBB,4(%a0) /* 9600 baud */
1189+ movb #5,8(%a0) /* enable tx and rx */
1190+ movl (%sp)+,%a0
1191+ bras L(serial_init_done)
1192+1:
1193+#endif
1194+#endif
1195+
1196 L(serial_init_done):
1197 func_return serial_init
1198
1199@@ -3215,6 +3310,23 @@
1200 2:
1201 #endif
1202
1203+#ifdef CONFIG_TEKXP
1204+ is_not_tekxp(3f)
1205+ moveml %a0/%d0-%d1,%sp@-
1206+ movl #0xFF800000,%a0
1207+1:
1208+ movb 4(%a0),%d1
1209+ andb #4,%d1
1210+ tstb %d1
1211+ bne 2f
1212+ bra 1b
1213+2:
1214+ movb %d0,12(%a0)
1215+ moveml %sp@+,%d0-%d1/%a0
1216+ jbra L(serial_putc_done)
1217+3:
1218+#endif
1219+
1220 L(serial_putc_done):
1221 func_return serial_putc
1222
1223diff -Naur linux-2.4.26/arch/m68k/kernel/m68k_ksyms.c linux-2.4.26-m68k/arch/m68k/kernel/m68k_ksyms.c
1224--- linux-2.4.26/arch/m68k/kernel/m68k_ksyms.c 2004-02-19 00:36:30.000000000 +1100
1225+++ linux-2.4.26-m68k/arch/m68k/kernel/m68k_ksyms.c 2003-11-12 22:57:01.000000000 +1100
1226@@ -53,6 +53,7 @@
1227 EXPORT_SYMBOL(mm_cachebits);
1228 #endif
1229 #endif /* !CONFIG_SUN3 */
1230+EXPORT_SYMBOL(flush_icache_user_range);
1231 EXPORT_SYMBOL(m68k_debug_device);
1232 EXPORT_SYMBOL(mach_hwclk);
1233 EXPORT_SYMBOL(mach_get_ss);
1234diff -Naur linux-2.4.26/arch/m68k/kernel/setup.c linux-2.4.26-m68k/arch/m68k/kernel/setup.c
1235--- linux-2.4.26/arch/m68k/kernel/setup.c 2003-06-14 00:51:31.000000000 +1000
1236+++ linux-2.4.26-m68k/arch/m68k/kernel/setup.c 2003-07-22 07:20:23.000000000 +1000
1237@@ -140,6 +140,7 @@
1238 extern void config_hp300(void);
1239 extern void config_q40(void);
1240 extern void config_sun3x(void);
1241+extern void config_tekxp(void);
1242
1243 extern void mac_debugging_short (int, short);
1244 extern void mac_debugging_long (int, long);
1245@@ -150,6 +151,10 @@
1246
1247 static void __init m68k_parse_bootinfo(const struct bi_record *record)
1248 {
1249+#ifdef CONFIG_NO_CMDLINE
1250+ strncpy(m68k_command_line, CONFIG_BOOTCMD, CL_SIZE);
1251+#endif
1252+
1253 while (record->tag != BI_LAST) {
1254 int unknown = 0;
1255 const unsigned long *data = record->data;
1256@@ -354,6 +359,11 @@
1257 config_sun3x();
1258 break;
1259 #endif
1260+#ifdef CONFIG_TEKXP
1261+ case MACH_TEKXP:
1262+ config_tekxp();
1263+ break;
1264+#endif
1265 default:
1266 panic ("No configuration setup");
1267 }
1268diff -Naur linux-2.4.26/arch/m68k/mac/iop.c linux-2.4.26-m68k/arch/m68k/mac/iop.c
1269--- linux-2.4.26/arch/m68k/mac/iop.c 2003-06-14 00:51:31.000000000 +1000
1270+++ linux-2.4.26-m68k/arch/m68k/mac/iop.c 2004-06-20 21:17:45.000000000 +1000
1271@@ -261,7 +261,7 @@
1272 } else {
1273 iop_base[IOP_NUM_ISM] = (struct mac_iop *) ISM_IOP_BASE_QUADRA;
1274 }
1275- iop_base[IOP_NUM_SCC]->status_ctrl = 0;
1276+ iop_base[IOP_NUM_ISM]->status_ctrl = 0;
1277 iop_ism_present = 1;
1278 } else {
1279 iop_base[IOP_NUM_ISM] = NULL;
1280diff -Naur linux-2.4.26/arch/m68k/mm/Makefile linux-2.4.26-m68k/arch/m68k/mm/Makefile
1281--- linux-2.4.26/arch/m68k/mm/Makefile 2003-06-14 00:51:31.000000000 +1000
1282+++ linux-2.4.26-m68k/arch/m68k/mm/Makefile 2003-07-02 09:46:59.000000000 +1000
1283@@ -9,7 +9,7 @@
1284
1285 O_TARGET := mm.o
1286
1287-obj-y := init.o fault.o extable.o hwtest.o
1288+obj-y := cache.o init.o fault.o extable.o hwtest.o
1289
1290 ifndef CONFIG_SUN3
1291 obj-y += kmap.o memory.o motorola.o
1292diff -Naur linux-2.4.26/arch/m68k/mm/cache.c linux-2.4.26-m68k/arch/m68k/mm/cache.c
1293--- linux-2.4.26/arch/m68k/mm/cache.c 1970-01-01 10:00:00.000000000 +1000
1294+++ linux-2.4.26-m68k/arch/m68k/mm/cache.c 2003-11-13 02:23:27.000000000 +1100
1295@@ -0,0 +1,161 @@
1296+/*
1297+ * linux/arch/m68k/mm/cache.c
1298+ *
1299+ * Instruction cache handling
1300+ *
1301+ * Copyright (C) 1995 Hamish Macdonald
1302+ */
1303+
1304+#include <linux/pagemap.h>
1305+
1306+#include <asm/traps.h>
1307+
1308+
1309+static unsigned long virt_to_phys_slow(unsigned long vaddr, mm_segment_t fs)
1310+{
1311+ if (CPU_IS_060) {
1312+ mm_segment_t old_fs = get_fs();
1313+ unsigned long paddr;
1314+
1315+ set_fs(fs);
1316+
1317+ /* The PLPAR instruction causes an access error if the translation
1318+ * is not possible. To catch this we use the same exception mechanism
1319+ * as for user space accesses in <asm/uaccess.h>. */
1320+ asm volatile (".chip 68060\n"
1321+ "1: plpar (%0)\n"
1322+ ".chip 68k\n"
1323+ "2:\n"
1324+ ".section .fixup,\"ax\"\n"
1325+ " .even\n"
1326+ "3: sub.l %0,%0\n"
1327+ " jra 2b\n"
1328+ ".previous\n"
1329+ ".section __ex_table,\"a\"\n"
1330+ " .align 4\n"
1331+ " .long 1b,3b\n"
1332+ ".previous"
1333+ : "=a" (paddr)
1334+ : "0" (vaddr));
1335+ set_fs(old_fs);
1336+ return paddr;
1337+ } else if (CPU_IS_040) {
1338+ mm_segment_t old_fs = get_fs();
1339+ unsigned long mmusr;
1340+
1341+ set_fs(fs);
1342+
1343+ asm volatile (".chip 68040\n\t"
1344+ "ptestr (%1)\n\t"
1345+ "movec %%mmusr, %0\n\t"
1346+ ".chip 68k"
1347+ : "=r" (mmusr)
1348+ : "a" (vaddr));
1349+ set_fs(old_fs);
1350+
1351+ if (mmusr & MMU_R_040)
1352+ return (mmusr & PAGE_MASK) | (vaddr & ~PAGE_MASK);
1353+ } else {
1354+ unsigned short mmusr;
1355+ unsigned long *descaddr;
1356+
1357+ asm volatile ("ptestr %3,%2@,#7,%0\n\t"
1358+ "pmove %%psr,%1@"
1359+ : "=a&" (descaddr)
1360+ : "a" (&mmusr), "a" (vaddr), "d" (fs.seg));
1361+ if (mmusr & (MMU_I|MMU_B|MMU_L))
1362+ return 0;
1363+ descaddr = phys_to_virt((unsigned long)descaddr);
1364+ switch (mmusr & MMU_NUM) {
1365+ case 1:
1366+ return (*descaddr & 0xfe000000) | (vaddr & 0x01ffffff);
1367+ case 2:
1368+ return (*descaddr & 0xfffc0000) | (vaddr & 0x0003ffff);
1369+ case 3:
1370+ return (*descaddr & PAGE_MASK) | (vaddr & ~PAGE_MASK);
1371+ }
1372+ }
1373+ return 0;
1374+}
1375+
1376+/* Push n pages at kernel virtual address and clear the icache */
1377+/* RZ: use cpush %bc instead of cpush %dc, cinv %ic */
1378+void flush_icache_range(unsigned long address, unsigned long endaddr)
1379+{
1380+ if (CPU_IS_040_OR_060) {
1381+ address &= PAGE_MASK;
1382+
1383+ if (address >= PAGE_OFFSET && address < (unsigned long)high_memory) {
1384+ do {
1385+ asm volatile ("nop\n\t"
1386+ ".chip 68040\n\t"
1387+ "cpushp %%bc,(%0)\n\t"
1388+ ".chip 68k"
1389+ : : "a" (virt_to_phys((void *)address)));
1390+ address += PAGE_SIZE;
1391+ } while (address < endaddr);
1392+ } else {
1393+ do {
1394+ asm volatile ("nop\n\t"
1395+ ".chip 68040\n\t"
1396+ "cpushp %%bc,(%0)\n\t"
1397+ ".chip 68k"
1398+ : : "a" (virt_to_phys_slow(address, KERNEL_DS)));
1399+ address += PAGE_SIZE;
1400+ } while (address < endaddr);
1401+ }
1402+ } else {
1403+ unsigned long tmp;
1404+ asm volatile ("movec %%cacr,%0\n\t"
1405+ "orw %1,%0\n\t"
1406+ "movec %0,%%cacr"
1407+ : "=&d" (tmp)
1408+ : "di" (FLUSH_I));
1409+ }
1410+}
1411+
1412+void flush_icache_user_range(void *addr, unsigned long size)
1413+{
1414+ unsigned long address = (unsigned long)addr;
1415+ unsigned long endaddr = address + size;
1416+
1417+ if (CPU_IS_040_OR_060) {
1418+ address &= PAGE_MASK;
1419+
1420+ do {
1421+ asm volatile ("nop\n\t"
1422+ ".chip 68040\n\t"
1423+ "cpushp %%bc,(%0)\n\t"
1424+ ".chip 68k"
1425+ : : "a" (virt_to_phys_slow(address, get_fs())));
1426+ address += PAGE_SIZE;
1427+ } while (address < endaddr);
1428+ } else {
1429+ unsigned long tmp;
1430+ asm volatile ("movec %%cacr,%0\n\t"
1431+ "orw %1,%0\n\t"
1432+ "movec %0,%%cacr"
1433+ : "=&d" (tmp)
1434+ : "di" (FLUSH_I));
1435+ }
1436+}
1437+
1438+void flush_icache_user_page(struct vm_area_struct *vma, struct page *page,
1439+ unsigned long addr, int len)
1440+{
1441+ if (CPU_IS_040_OR_060) {
1442+ asm volatile ("nop\n\t"
1443+ ".chip 68040\n\t"
1444+ "cpushp %%bc,(%0)\n\t"
1445+ ".chip 68k"
1446+ : : "a" (page_to_phys(page)));
1447+ } else {
1448+ unsigned long tmp;
1449+ asm volatile ("movec %%cacr,%0\n\t"
1450+ "orw %1,%0\n\t"
1451+ "movec %0,%%cacr"
1452+ : "=&d" (tmp)
1453+ : "di" (FLUSH_I));
1454+ }
1455+}
1456+
1457diff -Naur linux-2.4.26/arch/m68k/tekxp/Makefile linux-2.4.26-m68k/arch/m68k/tekxp/Makefile
1458--- linux-2.4.26/arch/m68k/tekxp/Makefile 1970-01-01 10:00:00.000000000 +1000
1459+++ linux-2.4.26-m68k/arch/m68k/tekxp/Makefile 2003-07-22 07:20:23.000000000 +1000
1460@@ -0,0 +1,15 @@
1461+#
1462+# Makefile for Linux arch/m68k/tekxp source directory
1463+#
1464+# Note! Dependencies are done automagically by 'make dep', which also
1465+# removes any old dependencies. DON'T put your own dependencies here
1466+# unless it's something special (ie not a .c file).
1467+#
1468+# Note 2! The CFLAGS definitions are now in the main makefile...
1469+
1470+O_TARGET := tekxp.o
1471+
1472+export-objs := tek_ksyms.o tekuart.o nvram.o
1473+obj-y := config.o tekuart.o nvram.o tek_ksyms.o
1474+
1475+include $(TOPDIR)/Rules.make
1476diff -Naur linux-2.4.26/arch/m68k/tekxp/config.c linux-2.4.26-m68k/arch/m68k/tekxp/config.c
1477--- linux-2.4.26/arch/m68k/tekxp/config.c 1970-01-01 10:00:00.000000000 +1000
1478+++ linux-2.4.26-m68k/arch/m68k/tekxp/config.c 2003-07-22 07:20:24.000000000 +1000
1479@@ -0,0 +1,199 @@
1480+/*
1481+ * linux/arch/m68k/tekxp/config.c
1482+ *
1483+ * Copyright (C) 2002,2003 Michael Mueller <malware@t-online.de>
1484+ *
1485+ * This file is subject to the terms and conditions of the GNU General Public
1486+ * License. See the file COPYING in the main directory of this archive for
1487+ * more details.
1488+ */
1489+
1490+#include <linux/config.h>
1491+#include <linux/types.h>
1492+#include <linux/console.h>
1493+#include <linux/sched.h>
1494+
1495+#include <asm/machdep.h>
1496+#include <asm/irq.h>
1497+#include <asm/tekirq.h>
1498+#include <asm/tekuart.h>
1499+#include <asm/teknvram.h>
1500+
1501+unsigned char aux_device_present = 1;
1502+
1503+/*
1504+ * While the support for this platform is still under development we just
1505+ * spit out a stupid message whenever an unexpected IRQ does occur.
1506+ * This message when appearing once most possible will run forever,
1507+ * since we have no interrupt controller we can give an acknowledgement.
1508+ */
1509+
1510+static void tekxp_int_unhandled(int irq, void *dev_id, struct pt_regs *regs)
1511+{
1512+ printk(KERN_ERR "Unhandled IRQ %d\n", irq);
1513+}
1514+
1515+static void (*tekxp_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
1516+ tekxp_int_unhandled, tekxp_int_unhandled, tekxp_int_unhandled,
1517+ tekxp_int_unhandled, tekxp_int_unhandled, tekxp_int_unhandled,
1518+ tekxp_int_unhandled, tekxp_int_unhandled
1519+};
1520+
1521+/*
1522+ * Reset the machine.
1523+ */
1524+static void tekxp_reset(void)
1525+{
1526+ tek_uart_set_op(4);
1527+ __asm__ volatile("1:\tbras 1b\r\n");
1528+}
1529+
1530+#ifdef USE_VIDEO_REFRESH_AS_TIMER
1531+/*
1532+ * Timer interrupt handler
1533+ */
1534+
1535+static void tek_timer(int irq, void *dev_id, struct pt_regs *regs)
1536+{
1537+ register void (*handler)(int,void*,struct pt_regs*) = dev_id;
1538+
1539+ (*(volatile unsigned char *)(0xFFB00000))++;
1540+
1541+ handler(irq, NULL, regs);
1542+}
1543+#endif
1544+
1545+/*
1546+ * To initialize the scheduling we setup a timer on the DUART.
1547+ * The hardware offers a screen refresh interrupt but its rate varies with
1548+ * the display mode and in all cases is less than HZ.
1549+ */
1550+
1551+static void __init tek_sched_init(void (*handler)(int, void *, struct pt_regs *))
1552+{
1553+#ifdef USE_VIDEO_REFRESH_AS_TIMER
1554+ /*
1555+ * Enable the timer
1556+ */
1557+ (*(volatile unsigned char *)(0xFFB00000))++;
1558+
1559+ if ( request_irq(TEK_IRQ_VIDEO, tek_timer, IRQ_FLG_LOCK, "timer", handler) )
1560+ panic("Could not register timer interrupt");
1561+#else
1562+ tek_uart_setup_timer(handler);
1563+#endif
1564+}
1565+
1566+/*
1567+ * Currently there is no such function implemented.
1568+ * However one could read the counter registers of the DUART here.
1569+ */
1570+
1571+static unsigned long tek_gettimeoffset(void)
1572+{
1573+ return 0;
1574+}
1575+
1576+/*
1577+ * There is not much to do with the keyboard here.
1578+ * The TekXpress Bootmonitor did most of the work already. What is left
1579+ * will be done by the PC keyboard driver later.
1580+ */
1581+
1582+static int __init tek_dummy_keyb_init(void)
1583+{
1584+ return 0;
1585+}
1586+
1587+/*
1588+ * This function simply modifies the C character for a new line into the
1589+ * MSDOS-typical version of it.
1590+ */
1591+
1592+static void tek_serial_console_write(struct console *co, const char *s,
1593+ unsigned int count)
1594+{
1595+ while ( count-- )
1596+ {
1597+ char c = *s++;
1598+ if ( c == '\n' )
1599+ tek_uart_putchar(0, '\r', 1);
1600+ tek_uart_putchar(0, c, 1);
1601+ }
1602+}
1603+
1604+/*
1605+ */
1606+
1607+static struct console tekxp_console_driver = {
1608+ name: "debug",
1609+ flags: CON_PRINTBUFFER,
1610+ index: -1,
1611+};
1612+
1613+/*
1614+ */
1615+static void __init tekxp_debug_init(void)
1616+{
1617+ extern char m68k_debug_device[];
1618+
1619+ if (!strcmp( m68k_debug_device, "ser" )) {
1620+ /* no initialization required (?) */
1621+ tekxp_console_driver.write = tek_serial_console_write;
1622+ register_console(&tekxp_console_driver);
1623+ }
1624+}
1625+
1626+/*
1627+ * Get the model number as stored in NVRAM and make it readable.
1628+ *
1629+ * FIXME: This does not work as expected.
1630+ */
1631+
1632+static void tekxp_get_model(char *model)
1633+{
1634+#ifdef CONFIG_TEKXP_REPORT_MVME
1635+ sprintf(model, "Motorola MVME160");
1636+#else
1637+ unsigned short m = nvram_readw(NVRAM_DISPLAY);
1638+ static const int model_number[] = {24,25,27,29,25,21,25,25};
1639+
1640+ if ( m < sizeof model_number )
1641+ sprintf(model, "TekXpress XP%02d", model_number[m]);
1642+ else
1643+ sprintf(model, "TekXpress");
1644+#endif
1645+}
1646+
1647+/*
1648+ * This basicly sets the machine dependent variables as needed by
1649+ * the m68k port of the linux kernel.
1650+ * Besides it initializes a console for kernel messages and the NVRAM
1651+ * routines.
1652+ */
1653+
1654+void __init config_tekxp(void)
1655+{
1656+ tekxp_debug_init();
1657+ init_nvram(NULL);
1658+
1659+ mach_get_model = tekxp_get_model;
1660+ mach_sched_init = tek_sched_init;
1661+#ifdef CONFIG_VT
1662+ mach_keyb_init = tek_dummy_keyb_init;
1663+#endif
1664+ mach_init_IRQ = tek_uart_init_IRQ;
1665+ mach_request_irq = tek_uart_request_irq;
1666+ mach_free_irq = tek_uart_free_irq;
1667+ enable_irq = tek_uart_enable_irq;
1668+ disable_irq = tek_uart_disable_irq;
1669+ mach_get_irq_list = tek_uart_get_irq_list;
1670+ mach_gettimeoffset = tek_gettimeoffset;
1671+ mach_max_dma_address = 0xffffffff;
1672+#ifdef CONFIG_DUMMY_CONSOLE
1673+ conswitchp = &dummy_con;
1674+#endif
1675+ mach_default_handler = &tekxp_default_handler;
1676+ mach_reset = tekxp_reset;
1677+}
1678+
1679diff -Naur linux-2.4.26/arch/m68k/tekxp/nvram.c linux-2.4.26-m68k/arch/m68k/tekxp/nvram.c
1680--- linux-2.4.26/arch/m68k/tekxp/nvram.c 1970-01-01 10:00:00.000000000 +1000
1681+++ linux-2.4.26-m68k/arch/m68k/tekxp/nvram.c 2003-07-22 07:20:24.000000000 +1000
1682@@ -0,0 +1,164 @@
1683+/*
1684+ * linux/arch/m68k/tekxp/nvram.c
1685+ *
1686+ * Copyright (C) 2002,2003 Michael Mueller <malware@t-online.de>
1687+ *
1688+ * This file is subject to the terms and conditions of the GNU General Public
1689+ * License. See the file COPYING in the main directory of this archive for
1690+ * more details.
1691+ */
1692+
1693+#include <linux/config.h>
1694+#include <linux/kernel.h>
1695+#include <linux/types.h>
1696+#include <linux/errno.h>
1697+#include <linux/mm.h>
1698+#include <linux/slab.h>
1699+#include <asm/io.h>
1700+#include <asm/teknvram.h>
1701+#include <asm/tekuart.h>
1702+
1703+#define DEBUG
1704+
1705+#ifdef DEBUG
1706+static int nvram_init = 0;
1707+#endif
1708+static u_char *eeprom_ptr;
1709+static u_char nvram_copy[EEPROM_SIZE];
1710+
1711+static void ee_enable(void)
1712+{
1713+#if 0
1714+ // TODO: We still rely on the I/O being transparently mapped
1715+ // TODO: This might interfere with other code using the UART
1716+ *(volatile u_char*)0xFF800038 = (u_char)0x80;
1717+#else
1718+ tek_uart_set_op(7);
1719+#endif
1720+}
1721+
1722+static void ee_disable(void)
1723+{
1724+#if 0
1725+ // TODO: We still rely on the I/O being transparently mapped
1726+ // TODO: This might interfere with other code using the UART
1727+ *(volatile u_char*)0xFF80003C = (u_char)0x80;
1728+#else
1729+ tek_uart_clr_op(7);
1730+#endif
1731+}
1732+
1733+void init_nvram(unsigned long *mem_start)
1734+{
1735+ u_char chksum;
1736+ u_char chksum2;
1737+ u_short chksum_complete;
1738+ int i;
1739+
1740+ // FIXME: When this code is running ioremap* is not working yet.
1741+ // So we access the EEPROM through the transparent mapping
1742+ // established in head.S
1743+#if 0
1744+ // Map EEPROM into kernel memory space
1745+ eeprom_ptr = ioremap_writethrough(EEPROM_BASE, EEPROM_SIZE);
1746+ if ( !eeprom_ptr )
1747+ {
1748+ panic(KERN_ERR "Could not map NVRAM into kernel memory space\n");
1749+ }
1750+#else
1751+ eeprom_ptr = (u_char*)EEPROM_BASE;
1752+#endif
1753+
1754+ // Make a copy of the content to avoid access count excess
1755+ ee_enable();
1756+ memcpy(nvram_copy, eeprom_ptr, EEPROM_SIZE);
1757+ ee_disable();
1758+
1759+ // Check the checksum of the content
1760+ chksum = 0xFF;
1761+ chksum2 = 0xFF;
1762+ for ( i = EEPROM_SIZE-1; i >= 0 ; i-- )
1763+ {
1764+ u_long new_chk /* d0 */ = chksum + nvram_copy[i];
1765+ if ( new_chk > 0xFF )
1766+ new_chk++;
1767+ chksum = new_chk & 0xFF;
1768+
1769+ new_chk = chksum2 + chksum;
1770+ if ( new_chk > 0xFF )
1771+ new_chk++;
1772+ chksum2 = new_chk++;
1773+ }
1774+
1775+ chksum_complete = ((u_short)chksum2 << 8) + chksum;
1776+ if ( chksum_complete == 0xFFFF )
1777+ {
1778+ printk("NVRAM checksum is ok\n");
1779+ }
1780+ else
1781+ {
1782+ printk(KERN_WARNING "NVRAM checksum invalid!\n");
1783+ }
1784+
1785+#ifdef DEBUG
1786+ nvram_init++;
1787+#endif
1788+}
1789+
1790+u_char nvram_readb(int ofs)
1791+{
1792+#ifdef DEBUG
1793+ if ( !nvram_init )
1794+ {
1795+ printk(KERN_ERR "Trial to read uninitialized NVRAM\n");
1796+ return 0xFF;
1797+ }
1798+#endif
1799+ if ( ofs < 0 || ofs >= EEPROM_SIZE )
1800+ return 0xFF;
1801+
1802+ return nvram_copy[ofs];
1803+}
1804+
1805+u_short nvram_readw(int ofs)
1806+{
1807+#ifdef DEBUG
1808+ if ( !nvram_init )
1809+ {
1810+ printk(KERN_ERR "Trial to read uninitialized NVRAM\n");
1811+ return 0xFFFFU;
1812+ }
1813+ if ( ofs & 1 )
1814+ {
1815+ panic("Unaligned word access to NVRAM");
1816+ return 0xFFFFU;
1817+ }
1818+#endif
1819+ if ( ofs < 0 || ofs >= EEPROM_SIZE )
1820+ return 0xFFFFU;
1821+
1822+ return *(u_short*)(nvram_copy + ofs);
1823+}
1824+
1825+
1826+u_long nvram_readl(int ofs)
1827+{
1828+#ifdef DEBUG
1829+ if ( !nvram_init )
1830+ {
1831+ printk(KERN_ERR "Trial to read uninitialized NVRAM\n");
1832+ return 0xFFFFFFFFUL;
1833+ }
1834+ if ( ofs & 3 )
1835+ {
1836+ panic("Unaligned word access to NVRAM");
1837+ return 0xFFFFFFFFUL;
1838+ }
1839+#endif
1840+ if ( ofs < 0 || ofs >= EEPROM_SIZE )
1841+ return 0xFFFFFFFFUL;
1842+
1843+ return *(u_long*)(nvram_copy + ofs);
1844+}
1845+
1846+
1847diff -Naur linux-2.4.26/arch/m68k/tekxp/tek_ksyms.c linux-2.4.26-m68k/arch/m68k/tekxp/tek_ksyms.c
1848--- linux-2.4.26/arch/m68k/tekxp/tek_ksyms.c 1970-01-01 10:00:00.000000000 +1000
1849+++ linux-2.4.26-m68k/arch/m68k/tekxp/tek_ksyms.c 2003-07-22 07:20:24.000000000 +1000
1850@@ -0,0 +1,23 @@
1851+/*
1852+ * linux/arch/m68k/tekxp/tek_ksyms.c
1853+ *
1854+ * Copyright (C) 2002,2003 Michael Mueller <malware@t-online.de>
1855+ *
1856+ * This file is subject to the terms and conditions of the GNU General Public
1857+ * License. See the file COPYING in the main directory of this archive for
1858+ * more details.
1859+ */
1860+
1861+#include <linux/config.h>
1862+#include <linux/module.h>
1863+#include <linux/types.h>
1864+#include <asm/ptrace.h>
1865+#include <asm/tekuart.h>
1866+#include <asm/teknvram.h>
1867+
1868+EXPORT_SYMBOL(tek_uart_putchar);
1869+EXPORT_SYMBOL(tek_uart_lock);
1870+EXPORT_SYMBOL(nvram_readb);
1871+EXPORT_SYMBOL(nvram_readw);
1872+EXPORT_SYMBOL(nvram_readl);
1873+
1874diff -Naur linux-2.4.26/arch/m68k/tekxp/tekuart.c linux-2.4.26-m68k/arch/m68k/tekxp/tekuart.c
1875--- linux-2.4.26/arch/m68k/tekxp/tekuart.c 1970-01-01 10:00:00.000000000 +1000
1876+++ linux-2.4.26-m68k/arch/m68k/tekxp/tekuart.c 2003-07-22 07:20:24.000000000 +1000
1877@@ -0,0 +1,476 @@
1878+/*
1879+ * linux/arch/m68k/tekxp/tekuart.c
1880+ *
1881+ * Copyright (C) 2002,2003 Michael Mueller <malware@t-online.de>
1882+ *
1883+ * This file is subject to the terms and conditions of the GNU General Public
1884+ * License. See the file COPYING in the main directory of this archive for
1885+ * more details.
1886+ */
1887+
1888+#include <linux/config.h>
1889+#include <linux/types.h>
1890+#include <linux/sched.h>
1891+#include <linux/kernel.h>
1892+#include <linux/mm.h>
1893+#include <linux/errno.h>
1894+#include <linux/spinlock.h>
1895+
1896+#include <asm/system.h>
1897+#include <asm/irq.h>
1898+#include <asm/pgtable.h>
1899+#include <asm/tekuart.h>
1900+#include <asm/tekirq.h>
1901+
1902+spinlock_t tek_uart_lock = SPIN_LOCK_UNLOCKED;
1903+static spinlock_t tek_irq_lock = SPIN_LOCK_UNLOCKED;
1904+
1905+/*
1906+ * Base address of the UART
1907+ *
1908+ * Initialized to the address accessable by a transparent mapping.
1909+ *
1910+ * FIXME: This is never mapped into the memory space of the kernel
1911+ * since memory mapping is not available while initializing the
1912+ * platform specific stuff.
1913+ */
1914+
1915+static tek_uart_t *uart = (tek_uart_t*)TEK_UART_BASE;
1916+
1917+/*
1918+ * Interrupt handler tables and call statistics
1919+ */
1920+
1921+static irq_handler_t irq_handlers[UART_IRQS];
1922+static int tek_irq_stat[UART_IRQS];
1923+
1924+#define IRQ_IDX(n) ((n)-SYS_IRQS)
1925+
1926+/*
1927+ * Dummy variable used as Lvalue when we need to read from the
1928+ * hardware without any need for the actual result value.
1929+ */
1930+
1931+static volatile u_char dummy;
1932+
1933+/*
1934+ * Variables used for the interrupt routine
1935+ */
1936+
1937+static u_char tek_uart_imr; /* shadow Interrupt Mask Register */
1938+static u_char tek_uart_isr; /* shadow Interrupt Status Register */
1939+#ifndef USE_VIDEO_REFRESH_AS_TIMER
1940+static unsigned short tek_timer; /* value to put into the counter */
1941+#endif
1942+
1943+static u_char timer_mode = 0x80; /* choose second baudrate set */
1944+
1945+/*
1946+ * Set the interrupt mask register.
1947+ */
1948+
1949+static inline void __set_IMR(void)
1950+{
1951+ uart->wr.IMR = tek_uart_imr;
1952+}
1953+
1954+static void set_IMR(void)
1955+{
1956+ unsigned long flags;
1957+ spin_lock_irqsave(tek_uart_lock, flags);
1958+ __set_IMR();
1959+ spin_unlock_irqrestore(tek_uart_lock, flags);
1960+}
1961+
1962+/*
1963+ * Interrupt handler.
1964+ *
1965+ * Besides demultiplexing the interrupt sources of the DUART it does take
1966+ * care of the counter prior to calling the kernel handler.
1967+ */
1968+
1969+static void tek_irqhandler(int irq, void *dev_id, struct pt_regs *regs)
1970+{
1971+ int i;
1972+
1973+ /*
1974+ * Read the ISR once. This does even clear all pending interrupts.
1975+ */
1976+ unsigned char ISR = uart->rd.ISR;
1977+
1978+#ifndef USE_VIDEO_REFRESH_AS_TIMER
1979+ /*
1980+ * Handle the counter.
1981+ */
1982+ if ( ISR & (1<<IRQ_IDX(TEK_IRQ_TIMER_A)) )
1983+ dummy = uart->rd.CounterStop; /* just ack */
1984+#endif
1985+
1986+#ifdef DEBUG
1987+ printk("tek_irqhandler: ISR=%02x IMR=%02x\n", ISR, tek_uart_imr);
1988+#endif
1989+
1990+ /*
1991+ * Store the interrupt status for later usage.
1992+ *
1993+ * This does also queue disabled interrupts for later usage.
1994+ */
1995+ ISR = (tek_uart_isr |= ISR) & tek_uart_imr;
1996+
1997+ /*
1998+ * Run the handler for each interrupt source.
1999+ */
2000+ for ( i=0; i<UART_IRQS; i++ )
2001+ {
2002+ if ( ISR & (1<<i) )
2003+ {
2004+ unsigned long flags;
2005+ spin_lock_irqsave(tek_irq_lock, flags);
2006+
2007+ tek_irq_stat[i]++;
2008+
2009+ if ( irq_handlers[i].handler )
2010+ {
2011+ irq_handler_t handler = irq_handlers[i];
2012+ spin_unlock_irqrestore(tek_irq_lock, flags);
2013+
2014+ handler.handler(i, handler.dev_id, regs);
2015+ }
2016+ else
2017+ spin_unlock_irqrestore(tek_irq_lock, flags);
2018+ tek_uart_isr &= ~(1<<i);
2019+ }
2020+ }
2021+}
2022+
2023+/*
2024+ * Set an output line (to Low)
2025+ *
2026+ * Following values for the line are of special use:
2027+ * 3 connected to internal beeper
2028+ * 4 will reset the machine
2029+ */
2030+
2031+void tek_uart_set_op(int nr)
2032+{
2033+ unsigned long flags;
2034+ spin_lock_irqsave(tek_uart_lock, flags);
2035+
2036+ uart->wr.OutputSet = 1 << nr;
2037+
2038+ spin_unlock_irqrestore(tek_uart_lock, flags);
2039+}
2040+
2041+/*
2042+ * Clear an output line (to High)
2043+ */
2044+
2045+void tek_uart_clr_op(int nr)
2046+{
2047+ unsigned long flags;
2048+ spin_lock_irqsave(tek_uart_lock, flags);
2049+
2050+ uart->wr.OutputClear = 1 << nr;
2051+
2052+ spin_unlock_irqrestore(tek_uart_lock, flags);
2053+}
2054+
2055+/*
2056+ * Setup an interrupt handler managing all interrupt sources of the DUART.
2057+ */
2058+
2059+void __init tek_uart_init_IRQ(void)
2060+{
2061+ unsigned long flags;
2062+ spin_lock_irqsave(tek_uart_lock, flags);
2063+
2064+ /*
2065+ * Disable all interrupts
2066+ */
2067+ tek_uart_imr = 0;
2068+ __set_IMR();
2069+
2070+
2071+ /*
2072+ * Clear pending interrupts
2073+ */
2074+ tek_uart_isr = 0;
2075+ dummy = uart->rd.ISR;
2076+
2077+ spin_unlock_irqrestore(tek_uart_lock, flags);
2078+
2079+ /*
2080+ * Register the interrupt handler
2081+ */
2082+ if ( request_irq(TEK_IRQ_UART, tek_irqhandler, IRQ_FLG_LOCK, "UART demux", NULL) )
2083+ {
2084+ panic("Could not register UART demux interrupt handler");
2085+ }
2086+}
2087+
2088+/*
2089+ * Enable a specific interrupt source of the DUART.
2090+ */
2091+
2092+static inline void enable_uart_irq(unsigned int irq)
2093+{
2094+ unsigned long flags;
2095+ spin_lock_irqsave(tek_uart_lock, flags);
2096+
2097+ tek_uart_imr |= (1<<irq);
2098+ __set_IMR();
2099+
2100+ spin_unlock_irqrestore(tek_uart_lock, flags);
2101+}
2102+
2103+/*
2104+ * Disable a specific interrupt source of the DUART.
2105+ */
2106+
2107+static inline void disable_uart_irq(unsigned int irq)
2108+{
2109+ unsigned long flags;
2110+ spin_lock_irqsave(tek_uart_lock, flags);
2111+
2112+ tek_uart_imr &= ~(1<<irq);
2113+ __set_IMR();
2114+
2115+ spin_unlock_irqrestore(tek_uart_lock, flags);
2116+}
2117+
2118+/*
2119+ * Register an interrupt handler for an interrupt source of the DUART.
2120+ *
2121+ * This is also called for system interrupts. These requests are passed
2122+ * to the generic function made available by the m68k port.
2123+ */
2124+
2125+int tek_uart_request_irq(unsigned int irq,
2126+ void (*handler)(int, void *, struct pt_regs *),
2127+ unsigned long flags,
2128+ const char *devname, void *dev_id)
2129+{
2130+ unsigned long _flags;
2131+
2132+ if ( irq < SYS_IRQS )
2133+ return sys_request_irq(irq, handler, flags, devname, dev_id);
2134+ irq -= SYS_IRQS;
2135+
2136+ if ( irq >= UART_IRQS )
2137+ return -ENXIO;
2138+ if ( !handler )
2139+ return -EINVAL;
2140+
2141+ spin_lock_irqsave(tek_irq_lock, _flags);
2142+
2143+ if ( irq_handlers[irq].handler && (irq_handlers[irq].dev_id != dev_id) ) {
2144+ spin_unlock_irqrestore(tek_irq_lock, _flags);
2145+ return -EBUSY;
2146+ }
2147+
2148+ irq_handlers[irq].handler = handler;
2149+ irq_handlers[irq].flags = flags;
2150+ irq_handlers[irq].devname = devname;
2151+ irq_handlers[irq].dev_id = dev_id;
2152+
2153+ spin_unlock_irqrestore(tek_irq_lock, _flags);
2154+
2155+ enable_uart_irq(irq);
2156+
2157+ return 0;
2158+}
2159+
2160+/*
2161+ * Unregister an interrupt handler for an interrupt source of the DUART.
2162+ *
2163+ * This is also called for system interrupts. These requests are passed
2164+ * to the generic function made available by the m68k port.
2165+ */
2166+
2167+void tek_uart_free_irq(unsigned int irq, void *dev_id)
2168+{
2169+ unsigned long flags;
2170+
2171+ if ( irq < SYS_IRQS )
2172+ return sys_free_irq(irq, dev_id);
2173+ irq -= SYS_IRQS;
2174+
2175+ if ( irq >= UART_IRQS )
2176+ return /* -ENXIO */;
2177+
2178+ spin_lock_irqsave(tek_irq_lock, flags);
2179+
2180+ if ( !irq_handlers[irq].handler )
2181+ return /* -EINVAL */;
2182+
2183+ if ( dev_id != irq_handlers[irq].dev_id )
2184+ return /* -EPERM */;
2185+
2186+ disable_uart_irq(irq);
2187+ irq_handlers[irq].handler = NULL;
2188+
2189+ spin_unlock_irqrestore(tek_irq_lock, flags);
2190+}
2191+
2192+/*
2193+ * Wrapper for enabling an IRQ.
2194+ */
2195+
2196+void tek_uart_enable_irq(unsigned int irq)
2197+{
2198+ if ( irq < SYS_IRQS )
2199+ return;
2200+
2201+ enable_uart_irq(irq - SYS_IRQS);
2202+}
2203+
2204+/*
2205+ * Wrapper for disabling an IRQ.
2206+ */
2207+
2208+void tek_uart_disable_irq(unsigned int irq)
2209+{
2210+ if ( irq < SYS_IRQS )
2211+ return;
2212+
2213+ disable_uart_irq(irq - SYS_IRQS);
2214+}
2215+
2216+/*
2217+ * Build an ASCII list of the interrupt handlers registered and the call
2218+ * statistics. This part of the content of /proc/interrupts.
2219+ */
2220+
2221+int tek_uart_get_irq_list(char *buf)
2222+{
2223+ int i, len = 0;
2224+ unsigned long flags;
2225+ spin_lock_irqsave(tek_irq_lock, flags);
2226+
2227+ for ( i=0; i < UART_IRQS; i++ )
2228+ {
2229+ if ( irq_handlers[i].handler )
2230+ {
2231+ len += sprintf(buf+len, "uart %2d: %10u ", i, tek_irq_stat[i]);
2232+ len += sprintf(buf+len, " ");
2233+ len += sprintf(buf+len, "%s\n", irq_handlers[i].devname);
2234+ }
2235+ }
2236+ spin_unlock_irqrestore(tek_irq_lock, flags);
2237+ return len;
2238+}
2239+
2240+#ifndef USE_VIDEO_REFRESH_AS_TIMER
2241+
2242+static void tek_irq2(int irq, void *dev_id, struct pt_regs *regs)
2243+{
2244+ /*
2245+ * Acknowledge the interrupt
2246+ */
2247+ (*(volatile unsigned char *)(0xFFB00000))++;
2248+
2249+}
2250+
2251+/*
2252+ * Setup a timer interrupt.
2253+ */
2254+void __init tek_uart_setup_timer(void (*handler)(int, void *, struct pt_regs *))
2255+{
2256+ unsigned long flags;
2257+
2258+ /*
2259+ * Calculate the divider of the clock interval
2260+ */
2261+ if ( HZ < 32 )
2262+ {
2263+ /*
2264+ * Use 115.2k base clock.
2265+ *
2266+ * Do not permit frequencies <2Hz, they can be provided
2267+ * by further software dividing only and are not very
2268+ * usefull.
2269+ */
2270+ if ( HZ < 2 )
2271+ panic("I will not provide such a slow timer");
2272+
2273+ timer_mode |= 0x70;
2274+ tek_timer = 115200 / HZ;
2275+ }
2276+ else if ( HZ <= 57600 )
2277+ {
2278+ /*
2279+ * Use 115.2k * 16 base clock
2280+ */
2281+ timer_mode |= 0x60;
2282+ tek_timer = (115200*16) / HZ;
2283+ }
2284+ else
2285+ /*
2286+ * We can not provide a faster timer.
2287+ */
2288+ panic("Old hardware is no ferrari");
2289+
2290+ /*
2291+ * And setup an handler for the video refresh.
2292+ */
2293+ if ( request_irq(TEK_IRQ_VIDEO, tek_irq2, IRQ_FLG_LOCK, "display", NULL) )
2294+ panic("Could not register display interrupt");
2295+
2296+ /*
2297+ * Setup an handler for the timer interrupt.
2298+ */
2299+ if ( request_irq(TEK_IRQ_TIMER_A, handler, IRQ_FLG_LOCK, "timer", NULL) )
2300+ panic("Could not register timer interrupt");
2301+
2302+ spin_lock_irqsave(tek_uart_lock, flags);
2303+
2304+ /*
2305+ * Start the timer.
2306+ */
2307+ dummy = uart->rd.CounterStop;
2308+ uart->wr.ACR = timer_mode;
2309+ uart->wr.CRUR = tek_timer >> 8;
2310+ uart->wr.CTLR = tek_timer & 255;
2311+ dummy = uart->rd.CounterStart;
2312+
2313+ spin_unlock_irqrestore(tek_uart_lock, flags);
2314+
2315+ /*
2316+ * Enable the video refresh interrupt
2317+ */
2318+ (*(volatile unsigned char *)(0xFFB00000))++;
2319+}
2320+#endif
2321+
2322+/*
2323+ * Output a character on the serial port A.
2324+ *
2325+ * This routine is called from interrupt and non-interrupt contexts.
2326+ */
2327+
2328+void tek_uart_putchar(int channel, int c, int waitloop)
2329+{
2330+ unsigned long flags;
2331+ spin_lock_irqsave(tek_uart_lock, flags);
2332+
2333+ channel &= 1;
2334+
2335+ if ( waitloop )
2336+ {
2337+// disable_uart_irq(channel ? 4 : 0);
2338+ while ( !((channel ? uart->rd.SRB : uart->rd.SRA) & 4) )
2339+ ;
2340+ }
2341+
2342+ (channel ? uart->wr.THRB : uart->wr.THRA) = (u_char)c;
2343+
2344+ if ( waitloop )
2345+ {
2346+ while ( !((channel ? uart->rd.SRB : uart->rd.SRA) & 4) )
2347+ ;
2348+// enable_uart_irq(channel ? 4 : 0);
2349+ }
2350+
2351+ spin_unlock_irqrestore(tek_uart_lock, flags);
2352+}
2353+
2354diff -Naur linux-2.4.26/drivers/char/16c552.h linux-2.4.26-m68k/drivers/char/16c552.h
2355--- linux-2.4.26/drivers/char/16c552.h 1970-01-01 10:00:00.000000000 +1000
2356+++ linux-2.4.26-m68k/drivers/char/16c552.h 2001-10-22 19:34:32.000000000 +1000
2357@@ -0,0 +1,165 @@
2358+/*
2359+ * Definitions for the 16c552 DACE
2360+ * (dual-asynchronous-communications-element) used on the GVP
2361+ * IO-Extender.
2362+ *
2363+ * Basically this is two 16c550 uarts's and a parallel port, which is
2364+ * why the serial definitions should be valid for the 16c550 uart
2365+ * aswell.
2366+ *
2367+ * Data was taken from National Semiconductors duart 16c552
2368+ * data-sheets and the Texas Instruments DACE 16c552 data-sheets (the
2369+ * NS version of the chip is _non_ standard and their data-sheets did
2370+ * cost me several wasted hours of work).
2371+ *
2372+ * This file is (C) 1995 Jes Sorensen (jds@kom.auc.dk)
2373+ *
2374+ * Moved from drivers/char/ to include/linux/, because it's useful
2375+ * on more than just the one card. I'm using it on the hp300 DCA
2376+ * serial driver, for example.
2377+ * -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 05/1998
2378+ */
2379+
2380+#ifndef _16C552_H_
2381+#define _16C552_H_
2382+
2383+/* Serial stuff */
2384+
2385+struct uart_16c550 {
2386+ volatile u_char skip0;
2387+ volatile u_char RBR;
2388+ volatile u_char skip1;
2389+ volatile u_char IER;
2390+ volatile u_char skip2;
2391+ volatile u_char IIR;
2392+ volatile u_char skip3;
2393+ volatile u_char LCR;
2394+ volatile u_char skip4;
2395+ volatile u_char MCR;
2396+ volatile u_char skip5;
2397+ volatile u_char LSR;
2398+ volatile u_char skip6;
2399+ volatile u_char MSR;
2400+ volatile u_char skip7;
2401+ volatile u_char SCR;
2402+};
2403+
2404+#define THR RBR
2405+#define FCR IIR
2406+#define DLL RBR
2407+#define DLM IER
2408+#define AFR IIR
2409+
2410+/*
2411+ * Bit-defines for the various registers.
2412+ */
2413+
2414+
2415+/* IER */
2416+
2417+#define ERDAI (1<<0)
2418+#define ETHREI (1<<1)
2419+#define ELSI (1<<2)
2420+#define EMSI (1<<3)
2421+
2422+/* IIR - Interrupt Ident. Register */
2423+
2424+#define IRQ_PEND (1<<0) /* NOTE: IRQ_PEND=0 implies irq pending */
2425+#define IRQ_ID1 (1<<1)
2426+#define IRQ_ID2 (1<<2)
2427+#define IRQ_ID3 (1<<3)
2428+#define FIFO_ENA0 (1<<6) /* Both these are set when FCR(1<<0)=1 */
2429+#define FIFO_ENA1 (1<<7)
2430+
2431+#define IRQ_RLS (IRQ_ID1 | IRQ_ID2)
2432+#define IRQ_RDA (IRQ_ID2)
2433+#define IRQ_CTI (IRQ_ID2 | IRQ_ID3)
2434+#define IRQ_THRE (IRQ_ID1)
2435+#define IRQ_MS 0
2436+
2437+/* FCR - FIFO Control Register */
2438+
2439+#define FIFO_ENA (1<<0)
2440+#define RCVR_FIFO_RES (1<<1)
2441+#define XMIT_FIFO_RES (1<<2)
2442+#define DMA_MODE_SEL (1<<3)
2443+#define RCVR_TRIG_LSB (1<<6)
2444+#define RCVR_TRIG_MSB (1<<7)
2445+
2446+#define FIFO_TRIG_1 0x00
2447+#define FIFO_TRIG_4 RCVR_TRIG_LSB
2448+#define FIFO_TRIG_8 RCVR_TRIG_MSB
2449+#define FIFO_TRIG_14 RCVR_TRIG_LSB|RCVR_TRIG_MSB
2450+
2451+/* LCR - Line Control Register */
2452+
2453+#define WLS0 (1<<0)
2454+#define WLS1 (1<<1)
2455+#define STB (1<<2)
2456+#define PEN (1<<3)
2457+#define EPS (1<<4)
2458+#define STICK_PARITY (1<<5)
2459+#define SET_BREAK (1<<6)
2460+#define DLAB (1<<7)
2461+
2462+#define data_5bit 0x00
2463+#define data_6bit 0x01
2464+#define data_7bit 0x02
2465+#define data_8bit 0x03
2466+
2467+
2468+/* MCR - Modem Control Register */
2469+
2470+#define DTR (1<<0)
2471+#define RTS (1<<1)
2472+#define OUT1 (1<<2)
2473+#define OUT2 (1<<3)
2474+#define LOOP (1<<4)
2475+
2476+/* LSR - Line Status Register */
2477+
2478+#define DR (1<<0)
2479+#define OE (1<<1)
2480+#define PE (1<<2)
2481+#define FE (1<<3)
2482+#define BI (1<<4)
2483+#define THRE (1<<5)
2484+#define TEMT (1<<6)
2485+#define RCVR_FIFO_ERR (1<<7)
2486+
2487+/* MSR - Modem Status Register */
2488+
2489+#define DCTS (1<<0)
2490+#define DDSR (1<<1)
2491+#define TERI (1<<2)
2492+#define DDCD (1<<3)
2493+#define CTS (1<<4)
2494+#define DSR (1<<5)
2495+#define RING_I (1<<6)
2496+#define DCD (1<<7)
2497+
2498+/* AFR - Alternate Function Register */
2499+
2500+#define CONCUR_WRITE (1<<0)
2501+#define BAUDOUT (1<<1)
2502+#define RXRDY (1<<2)
2503+
2504+/* Parallel stuff */
2505+
2506+/*
2507+ * Unfortunately National Semiconductors did not supply the
2508+ * specifications for the parallel port in the chip :-(
2509+ * TI succed though, so here they are :-)
2510+ *
2511+ * Defines for the bits can be found by including <linux/lp.h>
2512+ */
2513+struct IOEXT_par {
2514+ volatile u_char skip0;
2515+ volatile u_char DATA;
2516+ volatile u_char skip1;
2517+ volatile u_char STATUS;
2518+ volatile u_char skip2;
2519+ volatile u_char CTRL;
2520+};
2521+
2522+#endif
2523diff -Naur linux-2.4.26/drivers/char/Makefile linux-2.4.26-m68k/drivers/char/Makefile
2524--- linux-2.4.26/drivers/char/Makefile 2004-02-19 00:36:31.000000000 +1100
2525+++ linux-2.4.26-m68k/drivers/char/Makefile 2004-02-19 09:16:15.000000000 +1100
2526@@ -321,6 +321,7 @@
2527 obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
2528 obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
2529 obj-$(CONFIG_AMD7XX_TCO) += amd7xx_tco.o
2530+obj-$(CONFIG_SCC2692) += generic_serial.o scc2692.o
2531 obj-$(CONFIG_INDYDOG) += indydog.o
2532 obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
2533
2534diff -Naur linux-2.4.26/drivers/char/ioext.h linux-2.4.26-m68k/drivers/char/ioext.h
2535--- linux-2.4.26/drivers/char/ioext.h 1970-01-01 10:00:00.000000000 +1000
2536+++ linux-2.4.26-m68k/drivers/char/ioext.h 2001-10-22 19:34:32.000000000 +1000
2537@@ -0,0 +1,108 @@
2538+/*
2539+ * Shared data structure for GVP IO-Extender support.
2540+ *
2541+ * Merge of ioext.h and ser_ioext.h
2542+ */
2543+#ifndef _IOEXT_H_
2544+#define _IOEXT_H_
2545+
2546+#include <linux/config.h>
2547+#include <linux/netdevice.h>
2548+
2549+#include "16c552.h"
2550+
2551+#define MAX_IOEXT 5 /*
2552+ * The maximum number of io-extenders is 5, as you
2553+ * can't have more than 5 ZII boards in any Amiga.
2554+ */
2555+
2556+#define UART_CLK 7372800
2557+
2558+#define IOEXT_BAUD_BASE (UART_CLK / 16)
2559+
2560+#define IOEXT_MAX_LINES 2
2561+
2562+#define IOEXT_PAR_PLIP 0x0001
2563+#define IOEXT_PAR_LP 0x0002
2564+
2565+
2566+/*
2567+ * Macros for the serial driver.
2568+ */
2569+#define curruart(info) ((struct uart_16c550 *)(info->port))
2570+
2571+#define ser_DTRon(info) curruart(info)->MCR |= DTR
2572+#define ser_RTSon(info) curruart(info)->MCR |= RTS
2573+#define ser_DTRoff(info) curruart(info)->MCR &= ~DTR
2574+#define ser_RTSoff(info) curruart(info)->MCR &= ~RTS
2575+
2576+
2577+/*
2578+ * CNTR defines (copied from the GVP SCSI-driver file gvp11.h
2579+ */
2580+#define GVP_BUSY (1<<0)
2581+#define GVP_IRQ_PEND (1<<1)
2582+#define GVP_IRQ_ENA (1<<3)
2583+#define GVP_DIR_WRITE (1<<4)
2584+
2585+
2586+/*
2587+ * CTRL defines
2588+ */
2589+#define PORT0_MIDI (1<<0) /* CLR = DRIVERS SET = MIDI */
2590+#define PORT1_MIDI (1<<1) /* CLR = DRIVERS SET = MIDI */
2591+#define PORT0_DRIVER (1<<2) /* CLR = RS232, SET = MIDI */
2592+#define PORT1_DRIVER (1<<3) /* CLR = RS232, SET = MIDI */
2593+#define IRQ_SEL (1<<4) /* CLR = INT2, SET = INT6 */
2594+#define ROM_BANK_SEL (1<<5) /* CLR = LOW 32K, SET = HIGH 32K */
2595+#define PORT0_CTRL (1<<6) /* CLR = RTSx or RXRDYx, SET = RTSx ONLY */
2596+#define PORT1_CTRL (1<<7) /* CLR = RTSx or RXRDYx, SET = RTSx ONLY */
2597+
2598+
2599+/*
2600+ * This is the struct describing the registers on the IO-Extender.
2601+ * NOTE: The board uses a dual uart (16c552), which should be equal to
2602+ * two 16c550 uarts.
2603+ */
2604+typedef struct {
2605+ char gap0[0x41];
2606+ volatile unsigned char CNTR; /* GVP DMAC CNTR (status register) */
2607+ char gap1[0x11e];
2608+ struct uart_16c550 uart0; /* The first uart */
2609+ char gap2[0xf0];
2610+ struct uart_16c550 uart1; /* The second uart */
2611+ char gap3[0xf0];
2612+ struct IOEXT_par par; /* The parallel port */
2613+ char gap4[0xfb];
2614+ volatile unsigned char CTRL; /* The control-register on the board */
2615+} IOEXT_struct;
2616+
2617+
2618+typedef struct {
2619+ int num_uarts;
2620+ int line[IOEXT_MAX_LINES];
2621+ volatile struct uart_16c550 *uart[IOEXT_MAX_LINES];
2622+ IOEXT_struct *board;
2623+ int spurious_count;
2624+ unsigned char par_use; /* IOEXT_PAR_xxx */
2625+#if defined(CONFIG_GVPIOEXT_PLIP) || defined(CONFIG_GVPIOEXT_PLIP_MODULE)
2626+ struct nt_device *dev;
2627+#endif
2628+#if defined(CONFIG_GVPIOEXT_LP) || defined(CONFIG_GVPIOEXT_LP_MODULE)
2629+ struct lp_struct *lp_table;
2630+ int lp_dev;
2631+ int lp_interrupt;
2632+#endif
2633+} IOExtInfoType;
2634+
2635+/* Number of detected boards. */
2636+extern int ioext_num;
2637+extern IOExtInfoType ioext_info[MAX_IOEXT];
2638+
2639+void ioext_plip_interrupt(struct net_device *dev, int *spurious_count);
2640+void ioext_lp_interrupt(int dev, int *spurious_count);
2641+
2642+extern struct net_device ioext_dev_plip[3];
2643+extern struct lp_struct ioext_lp_table[1];
2644+
2645+#endif
2646diff -Naur linux-2.4.26/drivers/char/mc68681.h linux-2.4.26-m68k/drivers/char/mc68681.h
2647--- linux-2.4.26/drivers/char/mc68681.h 1970-01-01 10:00:00.000000000 +1000
2648+++ linux-2.4.26-m68k/drivers/char/mc68681.h 2001-10-22 19:34:32.000000000 +1000
2649@@ -0,0 +1,131 @@
2650+#ifndef _MC68681_H_
2651+#define _MC68681_H_
2652+
2653+/*
2654+ * This describes an MC68681 DUART. It has almost only overlayed registers, which
2655+ * the structure very ugly.
2656+ * Note that the ri-register isn't really a register of the duart but a kludge of bsc
2657+ * to make the ring indicator available.
2658+ *
2659+ * The data came from the MFC-31-Developer Kit (from Ralph Seidel,
2660+ * zodiac@darkness.gun.de) and the data sheet of Phillip's clone device (SCN68681)
2661+ * (from Richard Hirst, srh@gpt.co.uk)
2662+ *
2663+ * 11.11.95 copyright Joerg Dorchain (dorchain@mpi-sb.mpg.de)
2664+ *
2665+ */
2666+
2667+struct duarthalf {
2668+union {
2669+volatile u_char mr1; /* rw */
2670+volatile u_char mr2; /* rw */
2671+} mr;
2672+volatile u_char ri; /* special, read */
2673+union {
2674+volatile u_char sr; /* read */
2675+volatile u_char csr; /* write */
2676+} sr_csr;
2677+u_char pad1;
2678+volatile u_char cr; /* write */
2679+u_char pad2;
2680+union {
2681+volatile u_char rhr; /* read */
2682+volatile u_char thr; /* write */
2683+} hr;
2684+u_char pad3;
2685+};
2686+
2687+struct duart {
2688+struct duarthalf pa;
2689+union {
2690+volatile u_char ipcr; /* read */
2691+volatile u_char acr; /* write */
2692+} ipcr_acr;
2693+u_char pad1;
2694+union {
2695+volatile u_char isr; /* read */
2696+volatile u_char imr; /* write */
2697+} ir;
2698+u_char pad2;
2699+volatile u_char ctu;
2700+u_char pad3;
2701+volatile u_char ctl;
2702+u_char pad4;
2703+struct duarthalf pb;
2704+volatile u_char ivr;
2705+u_char pad5;
2706+union {
2707+volatile u_char ipr; /* read */
2708+volatile u_char opcr; /* write */
2709+} ipr_opcr;
2710+u_char pad6;
2711+union {
2712+volatile u_char start; /* read */
2713+volatile u_char sopc; /* write */
2714+} start_sopc;
2715+u_char pad7;
2716+union {
2717+volatile u_char stop; /* read */
2718+volatile u_char ropc; /* write */
2719+} stop_ropc;
2720+u_char pad8;
2721+};
2722+
2723+#define MR1_BITS 3
2724+#define MR1_5BITS 0
2725+#define MR1_6BITS 1
2726+#define MR1_7BITS 2
2727+#define MR1_8BITS 3
2728+
2729+#define MR1_PARITY_ODD 4
2730+
2731+#define MR1_PARITY 24
2732+#define MR1_PARITY_WITH 0
2733+#define MR1_PARITY_FORCE 8
2734+#define MR1_PARITY_NO 16
2735+#define MR1_PARITY_MULTIDROP 24
2736+
2737+#define MR1_ERROR_BLOCK 32
2738+#define MR1_FFULL_IRQ 64
2739+#define MR1_RxRTS_ON 128
2740+
2741+#define MR2_STOPS 15
2742+#define MR2_1STOP 7
2743+#define MR2_2STOP 15
2744+
2745+#define MR2_CTS_ON 16
2746+#define MR2_TxRTS_ON 32
2747+
2748+#define MR2_MODE 192
2749+#define MR2_NORMAL 0
2750+#define MR2_ECHO 64
2751+#define MR2_LOCALLOOP 128
2752+#define MR2_REMOTELOOP 192
2753+
2754+#define CR_RXCOMMAND 3
2755+#define CR_NONE 0
2756+#define CR_RX_ON 1
2757+#define CR_RX_OFF 2
2758+#define CR_TXCOMMAND 12
2759+#define CR_TX_ON 4
2760+#define CR_TX_OFF 8
2761+#define CR_MISC 112
2762+#define CR_RESET_MR 16
2763+#define CR_RESET_RX 32
2764+#define CR_RESET_TX 48
2765+#define CR_RESET_ERR 64
2766+#define CR_RESET_BREAK 80
2767+#define CR_START_BREAK 96
2768+#define CR_STOP_BREAK 112
2769+
2770+#define SR_RXRDY 1
2771+#define SR_FFULL 2
2772+#define SR_TXRDY 4
2773+#define SR_TXEMPT 8
2774+#define SR_OVERRUN 16
2775+#define SR_PARITY 32
2776+#define SR_FRAMING 64
2777+#define SR_BREAK 128
2778+
2779+
2780+#endif
2781diff -Naur linux-2.4.26/drivers/char/pc_keyb.c linux-2.4.26-m68k/drivers/char/pc_keyb.c
2782--- linux-2.4.26/drivers/char/pc_keyb.c 2002-11-29 10:53:12.000000000 +1100
2783+++ linux-2.4.26-m68k/drivers/char/pc_keyb.c 2003-07-22 07:33:07.000000000 +1000
2784@@ -898,6 +898,8 @@
2785
2786 void __init pckbd_init_hw(void)
2787 {
2788+ unsigned long flags;
2789+
2790 if (!kbd_controller_present()) {
2791 kbd_exists = 0;
2792 return;
2793@@ -905,6 +907,9 @@
2794
2795 kbd_request_region();
2796
2797+ save_flags(flags);
2798+ cli();
2799+
2800 /* Flush any pending input. */
2801 kbd_clear_input();
2802
2803@@ -922,6 +927,8 @@
2804
2805 /* Ok, finally allocate the IRQ, and off we go.. */
2806 kbd_request_irq(keyboard_interrupt);
2807+
2808+ restore_flags(flags);
2809 }
2810
2811 #if defined CONFIG_PSMOUSE
2812diff -Naur linux-2.4.26/drivers/char/plip_ioext.c linux-2.4.26-m68k/drivers/char/plip_ioext.c
2813--- linux-2.4.26/drivers/char/plip_ioext.c 1970-01-01 10:00:00.000000000 +1000
2814+++ linux-2.4.26-m68k/drivers/char/plip_ioext.c 2001-11-02 07:04:56.000000000 +1100
2815@@ -0,0 +1,1065 @@
2816+/*
2817+ * plip_ioext: A parallel port "network" driver for GVP IO-Extender.
2818+ *
2819+ * Authors: See drivers/net/plip.c
2820+ * IO-Extender version by Steve Bennett, <msteveb@ozemail.com.au>
2821+ *
2822+ * This driver is for use with a 5-bit cable (LapLink (R) cable).
2823+ */
2824+
2825+static const char *version = "NET3 PLIP version 2.2/m68k";
2826+
2827+#define __NO_VERSION__
2828+
2829+#include <linux/module.h>
2830+#include <linux/types.h>
2831+#include <linux/sched.h>
2832+#include <linux/errno.h>
2833+#include <linux/interrupt.h>
2834+#include <linux/slab.h>
2835+#include <linux/termios.h>
2836+#include <linux/tty.h>
2837+#include <linux/serial.h>
2838+
2839+#include <asm/setup.h>
2840+#include <asm/irq.h>
2841+#include <asm/amigahw.h>
2842+#include <asm/amigaints.h>
2843+#include <linux/zorro.h>
2844+
2845+#include <linux/config.h>
2846+#include <linux/kernel.h>
2847+#include <linux/fcntl.h>
2848+#include <linux/string.h>
2849+#include <linux/ptrace.h>
2850+#include <linux/if_ether.h>
2851+
2852+#include <asm/system.h>
2853+
2854+#include <linux/in.h>
2855+#include <linux/delay.h>
2856+/*#include <linux/lp_m68k.h>*/
2857+
2858+#include <linux/netdevice.h>
2859+#include <linux/etherdevice.h>
2860+#include <linux/inetdevice.h>
2861+#include <linux/skbuff.h>
2862+#include <linux/if_plip.h>
2863+
2864+#include <linux/tqueue.h>
2865+#include <linux/ioport.h>
2866+#include <asm/bitops.h>
2867+#include <asm/byteorder.h>
2868+
2869+#include "ioext.h"
2870+
2871+#define DEBUG 0
2872+
2873+/* Map 'struct device *' to our control structure */
2874+#define PLIP_DEV(DEV) (&ioext_info[(DEV)->irq])
2875+
2876+/************************************************************************
2877+**
2878+** PLIP definitions
2879+**
2880+*************************************************************************
2881+*/
2882+
2883+/* Use 0 for production, 1 for verification, >2 for debug */
2884+#ifndef NET_DEBUG
2885+#define NET_DEBUG 2
2886+#endif
2887+static unsigned int net_debug = NET_DEBUG;
2888+
2889+/* In micro second */
2890+#define PLIP_DELAY_UNIT 1
2891+
2892+/* Connection time out = PLIP_TRIGGER_WAIT * PLIP_DELAY_UNIT usec */
2893+#define PLIP_TRIGGER_WAIT 500
2894+
2895+/* Nibble time out = PLIP_NIBBLE_WAIT * PLIP_DELAY_UNIT usec */
2896+#define PLIP_NIBBLE_WAIT 3000
2897+
2898+#define PAR_DATA(dev) ((dev)->base_addr+0)
2899+#define PAR_STATUS(dev) ((dev)->base_addr+2)
2900+#define PAR_CONTROL(dev) ((dev)->base_addr+4)
2901+
2902+static void enable_par_irq(struct device *dev, int on);
2903+static int plip_init(struct device *dev);
2904+
2905+/* Bottom halfs */
2906+static void plip_kick_bh(struct device *dev);
2907+static void plip_bh(struct device *dev);
2908+
2909+/* Functions for DEV methods */
2910+static int plip_rebuild_header(struct sk_buff *skb);
2911+static int plip_tx_packet(struct sk_buff *skb, struct device *dev);
2912+static int plip_open(struct device *dev);
2913+static int plip_close(struct device *dev);
2914+static struct enet_statistics *plip_get_stats(struct device *dev);
2915+static int plip_config(struct device *dev, struct ifmap *map);
2916+static int plip_ioctl(struct device *dev, struct ifreq *ifr, int cmd);
2917+
2918+enum plip_connection_state {
2919+ PLIP_CN_NONE=0,
2920+ PLIP_CN_RECEIVE,
2921+ PLIP_CN_SEND,
2922+ PLIP_CN_CLOSING,
2923+ PLIP_CN_ERROR
2924+};
2925+
2926+enum plip_packet_state {
2927+ PLIP_PK_DONE=0,
2928+ PLIP_PK_TRIGGER,
2929+ PLIP_PK_LENGTH_LSB,
2930+ PLIP_PK_LENGTH_MSB,
2931+ PLIP_PK_DATA,
2932+ PLIP_PK_CHECKSUM
2933+};
2934+
2935+enum plip_nibble_state {
2936+ PLIP_NB_BEGIN,
2937+ PLIP_NB_1,
2938+ PLIP_NB_2,
2939+};
2940+
2941+struct plip_local {
2942+ enum plip_packet_state state;
2943+ enum plip_nibble_state nibble;
2944+ union {
2945+ struct {
2946+#if defined(__LITTLE_ENDIAN)
2947+ unsigned char lsb;
2948+ unsigned char msb;
2949+#elif defined(__BIG_ENDIAN)
2950+ unsigned char msb;
2951+ unsigned char lsb;
2952+#else
2953+#error "Please fix the endianness defines in <asm/byteorder.h>"
2954+#endif
2955+ } b;
2956+ unsigned short h;
2957+ } length;
2958+ unsigned short byte;
2959+ unsigned char checksum;
2960+ unsigned char data;
2961+ struct sk_buff *skb;
2962+};
2963+
2964+struct net_local {
2965+ struct enet_statistics enet_stats;
2966+ struct tq_struct immediate;
2967+ struct tq_struct deferred;
2968+ struct plip_local snd_data;
2969+ struct plip_local rcv_data;
2970+ unsigned long trigger;
2971+ unsigned long nibble;
2972+ enum plip_connection_state connection;
2973+ unsigned short timeout_count;
2974+ char is_deferred;
2975+ int (*orig_rebuild_header)(struct sk_buff *skb);
2976+};
2977+
2978+struct device ioext_dev_plip[] = {
2979+ {
2980+ "plip0",
2981+ 0, 0, 0, 0, /* memory */
2982+ 0, 0, /* base, irq */
2983+ 0, 0, 0, NULL, plip_init
2984+ },
2985+ {
2986+ "plip1",
2987+ 0, 0, 0, 0, /* memory */
2988+ 0, 0, /* base, irq */
2989+ 0, 0, 0, NULL, plip_init
2990+ },
2991+ {
2992+ "plip2",
2993+ 0, 0, 0, 0, /* memory */
2994+ 0, 0, /* base, irq */
2995+ 0, 0, 0, NULL, plip_init
2996+ }
2997+};
2998+
2999+/*
3000+ * Check for and handle an interrupt for this PLIP device.
3001+ *
3002+ */
3003+void ioext_plip_interrupt(struct device *dev, int *spurious_count)
3004+{
3005+ struct net_local *nl;
3006+ struct plip_local *rcv;
3007+ unsigned char c0;
3008+ unsigned long flags;
3009+
3010+ nl = (struct net_local *)dev->priv;
3011+ rcv = &nl->rcv_data;
3012+
3013+ c0 = z_readb(PAR_STATUS(dev));
3014+
3015+ if (dev->interrupt) {
3016+ return;
3017+ }
3018+
3019+ if ((c0 & 0xf8) != 0xc0) {
3020+ /* Not for us */
3021+ ++*spurious_count;
3022+ return;
3023+ }
3024+
3025+ *spurious_count = 0;
3026+ dev->interrupt = 1;
3027+
3028+ save_flags(flags);
3029+ cli();
3030+
3031+ switch (nl->connection) {
3032+ case PLIP_CN_CLOSING:
3033+ dev->tbusy = 0;
3034+ case PLIP_CN_NONE:
3035+ case PLIP_CN_SEND:
3036+ dev->last_rx = jiffies;
3037+ rcv->state = PLIP_PK_TRIGGER;
3038+ nl->connection = PLIP_CN_RECEIVE;
3039+ nl->timeout_count = 0;
3040+ queue_task(&nl->immediate, &tq_immediate);
3041+ mark_bh(IMMEDIATE_BH);
3042+ restore_flags(flags);
3043+#if 0
3044+ printk("%s: receive irq in SEND/NONE/CLOSING (%d) ok\n",
3045+ dev->name, nl->connection);
3046+#endif
3047+ break;
3048+
3049+ case PLIP_CN_RECEIVE:
3050+ restore_flags(flags);
3051+ printk("%s: receive interrupt when receiving packet\n",
3052+ dev->name);
3053+ break;
3054+
3055+ case PLIP_CN_ERROR:
3056+ restore_flags(flags);
3057+ printk("%s: receive interrupt in error state\n", dev->name);
3058+ break;
3059+ }
3060+}
3061+
3062+
3063
3064+/* Bottom half handler for the delayed request.
3065+ This routine is kicked by do_timer().
3066+ Request `plip_bh' to be invoked. */
3067+static void
3068+plip_kick_bh(struct device *dev)
3069+{
3070+ struct net_local *nl = (struct net_local *)dev->priv;
3071+
3072+ if (nl->is_deferred) {
3073+ queue_task(&nl->immediate, &tq_immediate);
3074+ mark_bh(IMMEDIATE_BH);
3075+ }
3076+}
3077+
3078+/* Forward declarations of internal routines */
3079+static int plip_none(struct device *, struct net_local *,
3080+ struct plip_local *, struct plip_local *);
3081+static int plip_receive_packet(struct device *, struct net_local *,
3082+ struct plip_local *, struct plip_local *);
3083+static int plip_send_packet(struct device *, struct net_local *,
3084+ struct plip_local *, struct plip_local *);
3085+static int plip_connection_close(struct device *, struct net_local *,
3086+ struct plip_local *, struct plip_local *);
3087+static int plip_error(struct device *, struct net_local *,
3088+ struct plip_local *, struct plip_local *);
3089+static int plip_bh_timeout_error(struct device *dev, struct net_local *nl,
3090+ struct plip_local *snd,
3091+ struct plip_local *rcv,
3092+ int error);
3093+
3094+#define OK 0
3095+#define TIMEOUT 1
3096+#define ERROR 2
3097+
3098+typedef int (*plip_func)(struct device *dev, struct net_local *nl,
3099+ struct plip_local *snd, struct plip_local *rcv);
3100+
3101+static plip_func connection_state_table[] =
3102+{
3103+ plip_none,
3104+ plip_receive_packet,
3105+ plip_send_packet,
3106+ plip_connection_close,
3107+ plip_error
3108+};
3109+
3110+/*
3111+** enable_par_irq()
3112+**
3113+** Enable or disable parallel irq for 'dev' according to 'on'.
3114+**
3115+** It is NOT possible to disable only the parallel irq.
3116+** So we disable the board interrupt instead. This means that
3117+** during reception of a PLIP packet, no serial interrupts can
3118+** happen. Sorry.
3119+*/
3120+static void enable_par_irq(struct device *dev, int on)
3121+{
3122+ if (on) {
3123+ PLIP_DEV(dev)->board->CNTR |= GVP_IRQ_ENA;
3124+ }
3125+ else {
3126+ PLIP_DEV(dev)->board->CNTR &= ~GVP_IRQ_ENA;
3127+ }
3128+}
3129+
3130+/* Bottom half handler of PLIP. */
3131+static void
3132+plip_bh(struct device *dev)
3133+{
3134+ struct net_local *nl = (struct net_local *)dev->priv;
3135+ struct plip_local *snd = &nl->snd_data;
3136+ struct plip_local *rcv = &nl->rcv_data;
3137+ plip_func f;
3138+ int r;
3139+
3140+ nl->is_deferred = 0;
3141+ f = connection_state_table[nl->connection];
3142+ if ((r = (*f)(dev, nl, snd, rcv)) != OK
3143+ && (r = plip_bh_timeout_error(dev, nl, snd, rcv, r)) != OK) {
3144+ nl->is_deferred = 1;
3145+ queue_task(&nl->deferred, &tq_timer);
3146+ }
3147+}
3148+
3149+static int
3150+plip_bh_timeout_error(struct device *dev, struct net_local *nl,
3151+ struct plip_local *snd, struct plip_local *rcv,
3152+ int error)
3153+{
3154+ unsigned char c0;
3155+ unsigned long flags;
3156+
3157+ save_flags(flags);
3158+ cli();
3159+ if (nl->connection == PLIP_CN_SEND) {
3160+
3161+ if (error != ERROR) { /* Timeout */
3162+ nl->timeout_count++;
3163+ if ((snd->state == PLIP_PK_TRIGGER
3164+ && nl->timeout_count <= 10)
3165+ || nl->timeout_count <= 3) {
3166+ restore_flags(flags);
3167+ /* Try again later */
3168+ return TIMEOUT;
3169+ }
3170+ c0 = z_readb(PAR_STATUS(dev));
3171+ printk(KERN_INFO "%s: transmit timeout(%d,%02x)\n",
3172+ dev->name, snd->state, c0);
3173+ }
3174+ nl->enet_stats.tx_errors++;
3175+ nl->enet_stats.tx_aborted_errors++;
3176+ } else if (nl->connection == PLIP_CN_RECEIVE) {
3177+ if (rcv->state == PLIP_PK_TRIGGER) {
3178+ /* Transmission was interrupted. */
3179+ restore_flags(flags);
3180+ return OK;
3181+ }
3182+ if (error != ERROR) { /* Timeout */
3183+ if (++nl->timeout_count <= 3) {
3184+ restore_flags(flags);
3185+ /* Try again later */
3186+ return TIMEOUT;
3187+ }
3188+ c0 = z_readb(PAR_STATUS(dev));
3189+ printk(KERN_INFO "%s: receive timeout(%d,%02x)\n",
3190+ dev->name, rcv->state, c0);
3191+ }
3192+ nl->enet_stats.rx_dropped++;
3193+ }
3194+ rcv->state = PLIP_PK_DONE;
3195+ if (rcv->skb) {
3196+ kfree_skb(rcv->skb);
3197+ rcv->skb = NULL;
3198+ }
3199+ snd->state = PLIP_PK_DONE;
3200+ if (snd->skb) {
3201+ dev_kfree_skb(snd->skb);
3202+ snd->skb = NULL;
3203+ }
3204+ enable_par_irq(dev, 0);
3205+ dev->tbusy = 1;
3206+ nl->connection = PLIP_CN_ERROR;
3207+ z_writeb(0x00, PAR_DATA(dev));
3208+ restore_flags(flags);
3209+
3210+ return TIMEOUT;
3211+}
3212+
3213+static int
3214+plip_none(struct device *dev, struct net_local *nl,
3215+ struct plip_local *snd, struct plip_local *rcv)
3216+{
3217+ return OK;
3218+}
3219+
3220+/* PLIP_RECEIVE --- receive a byte(two nibbles)
3221+ Returns OK on success, TIMEOUT on timeout */
3222+inline static int
3223+plip_receive(struct device *dev, unsigned short nibble_timeout,
3224+ enum plip_nibble_state *ns_p, unsigned char *data_p)
3225+{
3226+ unsigned char c0, c1;
3227+ unsigned int cx;
3228+
3229+ switch (*ns_p) {
3230+ case PLIP_NB_BEGIN:
3231+ cx = nibble_timeout;
3232+ while (1) {
3233+ c0 = z_readb(PAR_STATUS(dev));
3234+ udelay(PLIP_DELAY_UNIT);
3235+ if ((c0 & 0x80) == 0) {
3236+ c1 = z_readb(PAR_STATUS(dev));
3237+ if (c0 == c1)
3238+ break;
3239+ }
3240+ if (--cx == 0)
3241+ return TIMEOUT;
3242+ }
3243+#if 0
3244+ printk("received first nybble: %02X -> %02X\n",
3245+ c0, (c0 >> 3) & 0x0F);
3246+#endif
3247+ *data_p = (c0 >> 3) & 0x0f;
3248+ z_writeb(0x10, PAR_DATA(dev)); /* send ACK */
3249+ *ns_p = PLIP_NB_1;
3250+
3251+ case PLIP_NB_1:
3252+ cx = nibble_timeout;
3253+ while (1) {
3254+ c0 = z_readb(PAR_STATUS(dev));
3255+ udelay(PLIP_DELAY_UNIT);
3256+ if (c0 & 0x80) {
3257+ c1 = z_readb(PAR_STATUS(dev));
3258+ if (c0 == c1)
3259+ break;
3260+ }
3261+ if (--cx == 0)
3262+ return TIMEOUT;
3263+ }
3264+#if 0
3265+ printk("received second nybble: %02X -> %02X\n",
3266+ c0, (c0 << 1) & 0xF0);
3267+#endif
3268+ *data_p |= (c0 << 1) & 0xf0;
3269+ z_writeb(0x00, PAR_DATA(dev)); /* send ACK */
3270+ *ns_p = PLIP_NB_BEGIN;
3271+ case PLIP_NB_2:
3272+ break;
3273+ }
3274+ return OK;
3275+}
3276+
3277+/* PLIP_RECEIVE_PACKET --- receive a packet */
3278+static int
3279+plip_receive_packet(struct device *dev, struct net_local *nl,
3280+ struct plip_local *snd, struct plip_local *rcv)
3281+{
3282+ unsigned short nibble_timeout = nl->nibble;
3283+ unsigned char *lbuf;
3284+ unsigned long flags;
3285+
3286+ switch (rcv->state) {
3287+ case PLIP_PK_TRIGGER:
3288+ enable_par_irq(dev, 0);
3289+ dev->interrupt = 0;
3290+ z_writeb(0x01, PAR_DATA(dev)); /* send ACK */
3291+ if (net_debug > 2)
3292+ printk(KERN_DEBUG "%s: receive start\n", dev->name);
3293+ rcv->state = PLIP_PK_LENGTH_LSB;
3294+ rcv->nibble = PLIP_NB_BEGIN;
3295+
3296+ case PLIP_PK_LENGTH_LSB:
3297+ if (snd->state != PLIP_PK_DONE) {
3298+ if (plip_receive(dev, nl->trigger,
3299+ &rcv->nibble, &rcv->length.b.lsb)) {
3300+ /* collision, here dev->tbusy == 1 */
3301+ rcv->state = PLIP_PK_DONE;
3302+ nl->is_deferred = 1;
3303+ nl->connection = PLIP_CN_SEND;
3304+ queue_task(&nl->deferred, &tq_timer);
3305+ enable_par_irq(dev, 1);
3306+ return OK;
3307+ }
3308+ } else {
3309+ if (plip_receive(dev, nibble_timeout,
3310+ &rcv->nibble, &rcv->length.b.lsb))
3311+ return TIMEOUT;
3312+ }
3313+ rcv->state = PLIP_PK_LENGTH_MSB;
3314+
3315+ case PLIP_PK_LENGTH_MSB:
3316+ if (plip_receive(dev, nibble_timeout,
3317+ &rcv->nibble, &rcv->length.b.msb))
3318+ return TIMEOUT;
3319+ if (rcv->length.h > dev->mtu + dev->hard_header_len
3320+ || rcv->length.h < 8) {
3321+ printk(KERN_INFO "%s: bogus packet size %d.\n",
3322+ dev->name, rcv->length.h);
3323+ return ERROR;
3324+ }
3325+ /* Malloc up new buffer. */
3326+ rcv->skb = dev_alloc_skb(rcv->length.h);
3327+ if (rcv->skb == NULL) {
3328+ printk(KERN_INFO "%s: Memory squeeze.\n", dev->name);
3329+ return ERROR;
3330+ }
3331+ skb_put(rcv->skb,rcv->length.h);
3332+ rcv->skb->dev = dev;
3333+ rcv->state = PLIP_PK_DATA;
3334+ rcv->byte = 0;
3335+ rcv->checksum = 0;
3336+
3337+ case PLIP_PK_DATA:
3338+ lbuf = rcv->skb->data;
3339+ do
3340+ if (plip_receive(dev, nibble_timeout,
3341+ &rcv->nibble, &lbuf[rcv->byte]))
3342+ return TIMEOUT;
3343+ while (++rcv->byte < rcv->length.h);
3344+ do
3345+ rcv->checksum += lbuf[--rcv->byte];
3346+ while (rcv->byte);
3347+ rcv->state = PLIP_PK_CHECKSUM;
3348+
3349+ case PLIP_PK_CHECKSUM:
3350+ if (plip_receive(dev, nibble_timeout,
3351+ &rcv->nibble, &rcv->data))
3352+ return TIMEOUT;
3353+ if (rcv->data != rcv->checksum) {
3354+ nl->enet_stats.rx_crc_errors++;
3355+ if (net_debug)
3356+ printk(KERN_INFO "%s: checksum error\n",
3357+ dev->name);
3358+ return ERROR;
3359+ }
3360+ rcv->state = PLIP_PK_DONE;
3361+
3362+ case PLIP_PK_DONE:
3363+ /* Inform the upper layer for the arrival of a packet. */
3364+ rcv->skb->protocol=eth_type_trans(rcv->skb, dev);
3365+ netif_rx(rcv->skb);
3366+ nl->enet_stats.rx_packets++;
3367+ rcv->skb = NULL;
3368+ if (net_debug > 2)
3369+ printk(KERN_DEBUG "%s: receive end\n", dev->name);
3370+
3371+ /* Close the connection. */
3372+ z_writeb (0x00, PAR_DATA(dev));
3373+
3374+ save_flags(flags);
3375+ cli();
3376+ if (snd->state != PLIP_PK_DONE) {
3377+ nl->connection = PLIP_CN_SEND;
3378+ restore_flags(flags);
3379+ queue_task(&nl->immediate, &tq_immediate);
3380+ mark_bh(IMMEDIATE_BH);
3381+ enable_par_irq(dev, 1);
3382+ return OK;
3383+ } else {
3384+ nl->connection = PLIP_CN_NONE;
3385+ restore_flags(flags);
3386+ enable_par_irq(dev, 1);
3387+ return OK;
3388+ }
3389+ }
3390+ return OK;
3391+}
3392+
3393+/* PLIP_SEND --- send a byte (two nibbles)
3394+ Returns OK on success, TIMEOUT when timeout */
3395+inline static int
3396+plip_send(struct device *dev, unsigned short nibble_timeout,
3397+ enum plip_nibble_state *ns_p, unsigned char data)
3398+{
3399+ unsigned char c0;
3400+ unsigned int cx;
3401+
3402+ switch (*ns_p) {
3403+ case PLIP_NB_BEGIN:
3404+ z_writeb((data & 0x0f), PAR_DATA(dev));
3405+ *ns_p = PLIP_NB_1;
3406+
3407+ case PLIP_NB_1:
3408+ z_writeb(0x10 | (data & 0x0f), PAR_DATA(dev));
3409+ cx = nibble_timeout;
3410+ while (1) {
3411+ c0 = z_readb(PAR_STATUS(dev));
3412+ if ((c0 & 0x80) == 0)
3413+ break;
3414+ if (--cx == 0)
3415+ return TIMEOUT;
3416+ udelay(PLIP_DELAY_UNIT);
3417+ }
3418+ z_writeb(0x10 | (data >> 4), PAR_DATA(dev));
3419+ *ns_p = PLIP_NB_2;
3420+
3421+ case PLIP_NB_2:
3422+ z_writeb((data >> 4), PAR_DATA(dev));
3423+ cx = nibble_timeout;
3424+ while (1) {
3425+ c0 = z_readb(PAR_STATUS(dev));
3426+ if (c0 & 0x80)
3427+ break;
3428+ if (--cx == 0)
3429+ return TIMEOUT;
3430+ udelay(PLIP_DELAY_UNIT);
3431+ }
3432+ *ns_p = PLIP_NB_BEGIN;
3433+ return OK;
3434+ }
3435+ return OK;
3436+}
3437+
3438+/* PLIP_SEND_PACKET --- send a packet */
3439+static int
3440+plip_send_packet(struct device *dev, struct net_local *nl,
3441+ struct plip_local *snd, struct plip_local *rcv)
3442+{
3443+ unsigned short nibble_timeout = nl->nibble;
3444+ unsigned char *lbuf;
3445+ unsigned char c0;
3446+ unsigned int cx;
3447+ unsigned long flags;
3448+
3449+ if (snd->skb == NULL || (lbuf = snd->skb->data) == NULL) {
3450+ printk(KERN_INFO "%s: send skb lost\n", dev->name);
3451+ snd->state = PLIP_PK_DONE;
3452+ snd->skb = NULL;
3453+ return ERROR;
3454+ }
3455+
3456+ if (snd->length.h == 0) {
3457+ return OK;
3458+ }
3459+
3460+ switch (snd->state) {
3461+ case PLIP_PK_TRIGGER:
3462+ if ((z_readb(PAR_STATUS(dev)) & 0xf8) != 0x80)
3463+ return TIMEOUT;
3464+
3465+ /* Trigger remote rx interrupt. */
3466+ z_writeb(0x08, PAR_DATA(dev));
3467+ cx = nl->trigger;
3468+ while (1) {
3469+ udelay(PLIP_DELAY_UNIT);
3470+ save_flags(flags);
3471+ cli();
3472+ if (nl->connection == PLIP_CN_RECEIVE) {
3473+ restore_flags(flags);
3474+ /* interrupted */
3475+ nl->enet_stats.collisions++;
3476+ if (net_debug > 1)
3477+ printk(KERN_INFO "%s: collision.\n",
3478+ dev->name);
3479+ return OK;
3480+ }
3481+ c0 = z_readb(PAR_STATUS(dev));
3482+ if (c0 & 0x08) {
3483+ enable_par_irq(dev, 0);
3484+ if (net_debug > 2)
3485+ printk(KERN_DEBUG "%s: send start\n",
3486+ dev->name);
3487+ snd->state = PLIP_PK_LENGTH_LSB;
3488+ snd->nibble = PLIP_NB_BEGIN;
3489+ nl->timeout_count = 0;
3490+ restore_flags(flags);
3491+ break;
3492+ }
3493+ restore_flags(flags);
3494+ if (--cx == 0) {
3495+ z_writeb(0x00, PAR_DATA(dev));
3496+ return TIMEOUT;
3497+ }
3498+ }
3499+
3500+ case PLIP_PK_LENGTH_LSB:
3501+ if (plip_send(dev, nibble_timeout,
3502+ &snd->nibble, snd->length.b.lsb))
3503+ return TIMEOUT;
3504+ snd->state = PLIP_PK_LENGTH_MSB;
3505+
3506+ case PLIP_PK_LENGTH_MSB:
3507+ if (plip_send(dev, nibble_timeout,
3508+ &snd->nibble, snd->length.b.msb))
3509+ return TIMEOUT;
3510+ snd->state = PLIP_PK_DATA;
3511+ snd->byte = 0;
3512+ snd->checksum = 0;
3513+
3514+ case PLIP_PK_DATA:
3515+ do
3516+ if (plip_send(dev, nibble_timeout,
3517+ &snd->nibble, lbuf[snd->byte]))
3518+ return TIMEOUT;
3519+ while (++snd->byte < snd->length.h);
3520+ do
3521+ snd->checksum += lbuf[--snd->byte];
3522+ while (snd->byte);
3523+ snd->state = PLIP_PK_CHECKSUM;
3524+
3525+ case PLIP_PK_CHECKSUM:
3526+ if (plip_send(dev, nibble_timeout,
3527+ &snd->nibble, snd->checksum))
3528+ return TIMEOUT;
3529+
3530+ dev_kfree_skb(snd->skb);
3531+ nl->enet_stats.tx_packets++;
3532+ snd->state = PLIP_PK_DONE;
3533+
3534+ case PLIP_PK_DONE:
3535+ /* Close the connection */
3536+ z_writeb (0x00, PAR_DATA(dev));
3537+ snd->skb = NULL;
3538+ if (net_debug > 2)
3539+ printk(KERN_DEBUG "%s: send end\n", dev->name);
3540+ nl->connection = PLIP_CN_CLOSING;
3541+ nl->is_deferred = 1;
3542+ queue_task(&nl->deferred, &tq_timer);
3543+ enable_par_irq(dev, 1);
3544+ return OK;
3545+ }
3546+ return OK;
3547+}
3548+
3549+static int
3550+plip_connection_close(struct device *dev, struct net_local *nl,
3551+ struct plip_local *snd, struct plip_local *rcv)
3552+{
3553+ unsigned long flags;
3554+
3555+ save_flags(flags);
3556+ cli();
3557+ if (nl->connection == PLIP_CN_CLOSING) {
3558+ nl->connection = PLIP_CN_NONE;
3559+ dev->tbusy = 0;
3560+ mark_bh(NET_BH);
3561+ }
3562+ restore_flags(flags);
3563+ return OK;
3564+}
3565+
3566+/* PLIP_ERROR --- wait till other end settled */
3567+static int
3568+plip_error(struct device *dev, struct net_local *nl,
3569+ struct plip_local *snd, struct plip_local *rcv)
3570+{
3571+ unsigned char status;
3572+
3573+ status = z_readb(PAR_STATUS(dev));
3574+ if ((status & 0xf8) == 0x80) {
3575+ if (net_debug > 2)
3576+ printk(KERN_DEBUG "%s: reset interface.\n", dev->name);
3577+ nl->connection = PLIP_CN_NONE;
3578+ dev->tbusy = 0;
3579+ dev->interrupt = 0;
3580+ enable_par_irq(dev, 1);
3581+ mark_bh(NET_BH);
3582+ } else {
3583+ nl->is_deferred = 1;
3584+ queue_task(&nl->deferred, &tq_timer);
3585+ }
3586+
3587+ return OK;
3588+}
3589+
3590+/* We don't need to send arp, for plip is point-to-point. */
3591+static int
3592+plip_rebuild_header(struct sk_buff *skb)
3593+{
3594+ struct device *dev = skb->dev;
3595+ struct net_local *nl = (struct net_local *)dev->priv;
3596+ struct ethhdr *eth = (struct ethhdr *)skb->data;
3597+ int i;
3598+
3599+ if ((dev->flags & IFF_NOARP)==0)
3600+ return nl->orig_rebuild_header(skb);
3601+
3602+ if (eth->h_proto != __constant_htons(ETH_P_IP)
3603+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3604+ && eth->h_proto != __constant_htons(ETH_P_IPV6)
3605+#endif
3606+ ) {
3607+ printk(KERN_ERR "plip_rebuild_header: Don't know how to resolve type %d addresses?\n", (int)eth->h_proto);
3608+ memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
3609+ return 0;
3610+ }
3611+
3612+ for (i=0; i < ETH_ALEN - sizeof(u32); i++)
3613+ eth->h_dest[i] = 0xfc;
3614+#if 0
3615+ *(u32 *)(eth->h_dest+i) = dst;
3616+#else
3617+ /* Do not want to include net/route.h here.
3618+ * In any case, it is TOP of silliness to emulate
3619+ * hardware addresses on PtP link. --ANK
3620+ */
3621+ *(u32 *)(eth->h_dest+i) = 0;
3622+#endif
3623+ return 0;
3624+}
3625+
3626+static int
3627+plip_tx_packet(struct sk_buff *skb, struct device *dev)
3628+{
3629+ struct net_local *nl = (struct net_local *)dev->priv;
3630+ struct plip_local *snd = &nl->snd_data;
3631+ unsigned long flags;
3632+
3633+ if (dev->tbusy)
3634+ return 1;
3635+
3636+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
3637+ printk(KERN_ERR "%s: Transmitter access conflict.\n",
3638+ dev->name);
3639+ return 1;
3640+ }
3641+
3642+ if (skb->len > dev->mtu + dev->hard_header_len) {
3643+ printk(KERN_ERR "%s: packet too big, %d.\n",
3644+ dev->name, (int)skb->len);
3645+ dev->tbusy = 0;
3646+ return 0;
3647+ }
3648+
3649+ if (net_debug > 2)
3650+ printk(KERN_DEBUG "%s: send request\n", dev->name);
3651+
3652+ save_flags(flags);
3653+ cli();
3654+ dev->trans_start = jiffies;
3655+ snd->skb = skb;
3656+ snd->length.h = skb->len;
3657+ snd->state = PLIP_PK_TRIGGER;
3658+ if (nl->connection == PLIP_CN_NONE) {
3659+ nl->connection = PLIP_CN_SEND;
3660+ nl->timeout_count = 0;
3661+ }
3662+ queue_task(&nl->immediate, &tq_immediate);
3663+ mark_bh(IMMEDIATE_BH);
3664+ restore_flags(flags);
3665+
3666+ return 0;
3667+}
3668+
3669+/* Open/initialize the board. This is called (in the current kernel)
3670+ sometime after booting when the 'ifconfig' program is run.
3671+
3672+ */
3673+static int
3674+plip_open(struct device *dev)
3675+{
3676+ struct net_local *nl = (struct net_local *)dev->priv;
3677+ struct in_device *in_dev;
3678+
3679+#if defined(CONFIG_GVPIOEXT_LP) || defined(CONFIG_GVPIOEXT_LP_MODULE)
3680+ /* Yes, there is a race condition here. Fix it later */
3681+ if (PLIP_DEV(dev)->par_use & IOEXT_PAR_LP) {
3682+ /* Can't open if lp is in use */
3683+#if DEBUG
3684+ printk("par is in use by lp\n");
3685+#endif
3686+ return(-EBUSY);
3687+ }
3688+#endif
3689+ PLIP_DEV(dev)->par_use |= IOEXT_PAR_PLIP;
3690+
3691+#if DEBUG
3692+ printk("plip_open(): sending 00 to data port\n");
3693+#endif
3694+
3695+ /* Clear the data port. */
3696+ z_writeb (0x00, PAR_DATA(dev));
3697+
3698+#if DEBUG
3699+ printk("plip_open(): sent\n");
3700+#endif
3701+
3702+ /* Initialize the state machine. */
3703+ nl->rcv_data.state = nl->snd_data.state = PLIP_PK_DONE;
3704+ nl->rcv_data.skb = nl->snd_data.skb = NULL;
3705+ nl->connection = PLIP_CN_NONE;
3706+ nl->is_deferred = 0;
3707+
3708+ /* Fill in the MAC-level header.
3709+ (ab)Use "dev->broadcast" to store point-to-point MAC address.
3710+
3711+ PLIP doesn't have a real mac address, but we need to create one
3712+ to be DOS compatible. */
3713+ memset(dev->dev_addr, 0xfc, ETH_ALEN);
3714+ memset(dev->broadcast, 0xfc, ETH_ALEN);
3715+
3716+ if ((in_dev=dev->ip_ptr) != NULL) {
3717+ /*
3718+ * Any address will do - we take the first
3719+ */
3720+ struct in_ifaddr *ifa=in_dev->ifa_list;
3721+ if (ifa != NULL) {
3722+ memcpy(dev->dev_addr+2, &ifa->ifa_local, 4);
3723+ memcpy(dev->broadcast+2, &ifa->ifa_address, 4);
3724+ }
3725+ }
3726+
3727+ dev->interrupt = 0;
3728+ dev->start = 1;
3729+ dev->tbusy = 0;
3730+
3731+ MOD_INC_USE_COUNT;
3732+
3733+ /* Enable rx interrupt. */
3734+ enable_par_irq(dev, 1);
3735+
3736+ return 0;
3737+}
3738+
3739+/* The inverse routine to plip_open (). */
3740+static int
3741+plip_close(struct device *dev)
3742+{
3743+ struct net_local *nl = (struct net_local *)dev->priv;
3744+ struct plip_local *snd = &nl->snd_data;
3745+ struct plip_local *rcv = &nl->rcv_data;
3746+ unsigned long flags;
3747+
3748+ dev->tbusy = 1;
3749+ dev->start = 0;
3750+ save_flags(flags);
3751+ cli();
3752+ nl->is_deferred = 0;
3753+ nl->connection = PLIP_CN_NONE;
3754+ restore_flags(flags);
3755+ z_writeb(0x00, PAR_DATA(dev));
3756+
3757+ snd->state = PLIP_PK_DONE;
3758+ if (snd->skb) {
3759+ dev_kfree_skb(snd->skb);
3760+ snd->skb = NULL;
3761+ }
3762+ rcv->state = PLIP_PK_DONE;
3763+ if (rcv->skb) {
3764+ kfree_skb(rcv->skb);
3765+ rcv->skb = NULL;
3766+ }
3767+
3768+ PLIP_DEV(dev)->par_use &= ~IOEXT_PAR_PLIP;
3769+
3770+ MOD_DEC_USE_COUNT;
3771+ return 0;
3772+}
3773+
3774+static struct enet_statistics *
3775+plip_get_stats(struct device *dev)
3776+{
3777+ struct net_local *nl = (struct net_local *)dev->priv;
3778+ struct enet_statistics *r = &nl->enet_stats;
3779+
3780+ return r;
3781+}
3782+
3783+static int
3784+plip_config(struct device *dev, struct ifmap *map)
3785+{
3786+ if (dev->flags & IFF_UP)
3787+ return -EBUSY;
3788+
3789+ printk(KERN_INFO "%s: This interface is autodetected (ignored).\n",
3790+ dev->name);
3791+
3792+ return 0;
3793+}
3794+
3795+static int
3796+plip_ioctl(struct device *dev, struct ifreq *rq, int cmd)
3797+{
3798+ struct net_local *nl = (struct net_local *) dev->priv;
3799+ struct plipconf *pc = (struct plipconf *) &rq->ifr_data;
3800+
3801+ switch(pc->pcmd) {
3802+ case PLIP_GET_TIMEOUT:
3803+ pc->trigger = nl->trigger;
3804+ pc->nibble = nl->nibble;
3805+ break;
3806+ case PLIP_SET_TIMEOUT:
3807+ nl->trigger = pc->trigger;
3808+ nl->nibble = pc->nibble;
3809+ break;
3810+ default:
3811+ return -EOPNOTSUPP;
3812+ }
3813+ return 0;
3814+}
3815+
3816+/*
3817+ * Detect and initialize all IO-Extenders in this system.
3818+ *
3819+ * Both PLIP and serial devices are configured.
3820+ */
3821+int plip_init(struct device *dev)
3822+{
3823+ IOEXT_struct *board;
3824+ struct net_local *nl;
3825+
3826+ if (ioext_num == 0) {
3827+ printk(KERN_INFO "%s\n", version);
3828+ }
3829+
3830+ board = PLIP_DEV(dev)->board;
3831+ dev->base_addr = (unsigned long)&board->par.DATA;
3832+
3833+ /* Cheat and use irq to index into our table */
3834+ dev->irq = ioext_num;
3835+
3836+ printk(KERN_INFO "%s: IO-Extender parallel port at 0x%08lX\n", dev->name, dev->base_addr);
3837+
3838+ /* Fill in the generic fields of the device structure. */
3839+ ether_setup(dev);
3840+
3841+ /* Then, override parts of it */
3842+ dev->hard_start_xmit = plip_tx_packet;
3843+ dev->open = plip_open;
3844+ dev->stop = plip_close;
3845+ dev->get_stats = plip_get_stats;
3846+ dev->set_config = plip_config;
3847+ dev->do_ioctl = plip_ioctl;
3848+ dev->tx_queue_len = 10;
3849+ dev->flags = IFF_POINTOPOINT|IFF_NOARP;
3850+
3851+ /* Set the private structure */
3852+ dev->priv = kmalloc(sizeof (struct net_local), GFP_KERNEL);
3853+ if (dev->priv == NULL) {
3854+ printk(KERN_ERR "%s: out of memory\n", dev->name);
3855+ return -ENOMEM;
3856+ }
3857+ memset(dev->priv, 0, sizeof(struct net_local));
3858+ nl = (struct net_local *) dev->priv;
3859+
3860+ nl->orig_rebuild_header = dev->rebuild_header;
3861+ dev->rebuild_header = plip_rebuild_header;
3862+
3863+ /* Initialize constants */
3864+ nl->trigger = PLIP_TRIGGER_WAIT;
3865+ nl->nibble = PLIP_NIBBLE_WAIT;
3866+
3867+ /* Initialize task queue structures */
3868+ nl->immediate.next = NULL;
3869+ nl->immediate.sync = 0;
3870+ nl->immediate.routine = (void *)(void *)plip_bh;
3871+ nl->immediate.data = dev;
3872+
3873+ nl->deferred.next = NULL;
3874+ nl->deferred.sync = 0;
3875+ nl->deferred.routine = (void *)(void *)plip_kick_bh;
3876+ nl->deferred.data = dev;
3877+
3878+ /* Don't enable interrupts yet */
3879+
3880+ return 0;
3881+}
3882diff -Naur linux-2.4.26/drivers/char/scc2692.c linux-2.4.26-m68k/drivers/char/scc2692.c
3883--- linux-2.4.26/drivers/char/scc2692.c 1970-01-01 10:00:00.000000000 +1000
3884+++ linux-2.4.26-m68k/drivers/char/scc2692.c 2003-07-22 07:31:02.000000000 +1000
3885@@ -0,0 +1,617 @@
3886+#include <linux/module.h>
3887+#include <linux/config.h>
3888+#include <linux/kdev_t.h>
3889+#include <asm/io.h>
3890+#include <linux/kernel.h>
3891+#include <linux/sched.h>
3892+#include <linux/ioport.h>
3893+#include <linux/interrupt.h>
3894+#include <linux/errno.h>
3895+#include <linux/tty.h>
3896+#include <linux/tty_flip.h>
3897+#include <linux/mm.h>
3898+#include <linux/serial.h>
3899+#include <linux/fcntl.h>
3900+#include <linux/major.h>
3901+#include <linux/delay.h>
3902+#include <linux/tqueue.h>
3903+#include <linux/version.h>
3904+#include <linux/slab.h>
3905+#include <linux/miscdevice.h>
3906+#include <linux/console.h>
3907+#include <linux/init.h>
3908+#include <asm/setup.h>
3909+#include <asm/bootinfo.h>
3910+
3911+#include <asm/tekuart.h>
3912+#include <asm/tekirq.h>
3913+
3914+#include <linux/generic_serial.h>
3915+
3916+#define NR_PORTS 2
3917+
3918+static struct scc_port
3919+{
3920+ struct gs_port gs;
3921+ unsigned long base;
3922+ int irq_rx, irq_tx;
3923+ unsigned char channel;
3924+ unsigned long scale;
3925+} scc_ports[NR_PORTS];
3926+
3927+#define STATUS(scc) ((scc)->base + (((scc)->channel * 8 + 1) * (scc)->scale))
3928+#define CSR(scc) STATUS(scc)
3929+
3930+#define RECEIVE(scc) ((scc)->base + (((scc)->channel * 8 + 3) * (scc)->scale))
3931+#define TRANSMIT(scc) RECEIVE(scc)
3932+
3933+#define COMMAND(scc) ((scc)->base + (((scc)->channel * 8 + 2) * (scc)->scale))
3934+
3935+#define MR(scc) ((scc)->base + (((scc)->channel * 8 + 0) * (scc)->scale))
3936+
3937+
3938+static struct tty_driver scc_driver, scc_callout_driver;
3939+static struct tty_struct *scc_table[NR_PORTS] = { NULL, NULL };
3940+static struct termios *scc_termios[NR_PORTS];
3941+static struct termios *scc_termios_locked[NR_PORTS];
3942+
3943+int scc_refcount;
3944+
3945+#define SCC_MINOR_BASE 64
3946+#define SCC_MAGIC 0x52696368
3947+
3948+static inline void scc_disable_tx_interrupts(void *ptr)
3949+{
3950+ struct scc_port *port = ptr;
3951+ disable_irq(port->irq_tx);
3952+ port->gs.flags &= ~GS_TX_INTEN;
3953+}
3954+
3955+static inline void scc_enable_tx_interrupts(void *ptr)
3956+{
3957+ struct scc_port *port = ptr;
3958+ enable_irq(port->irq_tx);
3959+}
3960+
3961+static inline void scc_disable_rx_interrupts(void *ptr)
3962+{
3963+ struct scc_port *port = ptr;
3964+ disable_irq(port->irq_rx);
3965+}
3966+
3967+static inline void scc_enable_rx_interrupts(void *ptr)
3968+{
3969+ struct scc_port *port = ptr;
3970+ enable_irq(port->irq_rx);
3971+}
3972+
3973+
3974+/*
3975+ * Receiver Interrupt
3976+ */
3977+static void scc_rx_int(int irq, void *data, struct pt_regs *fp)
3978+{
3979+ struct scc_port *port = data;
3980+ struct tty_struct *tty = port->gs.tty;
3981+ unsigned long flags;
3982+ volatile unsigned char ch;
3983+
3984+ spin_lock_irqsave(tek_uart_lock, flags);
3985+ while ( *(volatile unsigned char *)STATUS(port) & 0x1 )
3986+ {
3987+ ch = *(volatile unsigned char *)RECEIVE(port);
3988+
3989+ if (!tty)
3990+ /*
3991+ * FIXME: It might be a bad idea to call printk
3992+ * with the lock held.
3993+ */
3994+ printk(KERN_WARNING "scc_rx_int with NULL tty!\n");
3995+ else if (tty->flip.count < TTY_FLIPBUF_SIZE) {
3996+ *tty->flip.char_buf_ptr = ch;
3997+ *tty->flip.flag_buf_ptr = 0;
3998+ tty->flip.flag_buf_ptr++;
3999+ tty->flip.char_buf_ptr++;
4000+ tty->flip.count++;
4001+ }
4002+ }
4003+ spin_unlock_irqrestore(tek_uart_lock, flags);
4004+
4005+ tty_flip_buffer_push(tty);
4006+}
4007+
4008+/*
4009+ * Transmitter interrupt
4010+ */
4011+static void scc_tx_int(int irq, void *data, struct pt_regs *fp)
4012+{
4013+ struct scc_port *port = data;
4014+ struct tty_struct *tty = port->gs.tty;
4015+ unsigned long flags;
4016+
4017+ if ( !tty )
4018+ {
4019+ scc_disable_tx_interrupts(port);
4020+ return;
4021+ }
4022+
4023+ spin_lock_irqsave(tek_uart_lock, flags);
4024+ while ( *(volatile unsigned char *)STATUS(port) & 0x4 )
4025+ {
4026+ *(volatile unsigned char *)TRANSMIT(port) =
4027+ port->gs.xmit_buf[port->gs.xmit_tail++];
4028+ port->gs.xmit_tail = port->gs.xmit_tail & (SERIAL_XMIT_SIZE-1);
4029+ if (--port->gs.xmit_cnt <= 0)
4030+ break;
4031+ }
4032+ spin_unlock_irqrestore(tek_uart_lock, flags);
4033+
4034+ if ((port->gs.xmit_cnt <= 0) || (tty && (tty->stopped || tty->hw_stopped)) )
4035+ {
4036+ scc_disable_tx_interrupts(port);
4037+ }
4038+
4039+ if (tty && port->gs.xmit_cnt <= port->gs.wakeup_chars) {
4040+ if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
4041+ (tty->ldisc.write_wakeup)(port->gs.tty);
4042+ wake_up_interruptible(&tty->write_wait);
4043+ }
4044+}
4045+
4046+/*---------------------------------------------------------------------------
4047+ * generic_serial.c callback funtions
4048+ *--------------------------------------------------------------------------*/
4049+
4050+static int scc_get_CD(void *ptr)
4051+{
4052+ return 1;
4053+}
4054+
4055+static void scc_shutdown_port(void *ptr)
4056+{
4057+ struct scc_port *port = ptr;
4058+
4059+ port->gs.flags &= ~ GS_ACTIVE;
4060+}
4061+
4062+static const int baudrates[B38400] = {
4063+ [B19200] 13,
4064+ [B9600] 12,
4065+ [B4800] 10,
4066+ [B2400] 9,
4067+ [B1200] 7,
4068+ [B600] 6,
4069+ [B300] 5,
4070+ [B134] 3,
4071+ [B110] 2,
4072+ [B75] 1
4073+};
4074+
4075+static int scc_set_real_termios(void *ptr)
4076+{
4077+ struct scc_port *port = ptr;
4078+ unsigned long flags;
4079+ unsigned int cflag;
4080+ unsigned char baudrate = 0;
4081+ unsigned char mr1 = 0x80, mr2 = 0;
4082+ int baud;
4083+
4084+ if (!port->gs.tty || !port->gs.tty->termios)
4085+ return 0;
4086+
4087+ cflag = port->gs.tty->termios->c_cflag;
4088+ baud = cflag & (CBAUD | CBAUDEX);
4089+
4090+ if (baud == B0)
4091+ {
4092+ // TODO: hangup
4093+ return 0;
4094+ }
4095+
4096+ if ((baud >= sizeof baudrates/sizeof baudrates[0]) || !baudrates[baud])
4097+ return -EINVAL;
4098+ baudrate = baudrates[baud] - 1;
4099+
4100+ if ( cflag & CSTOPB )
4101+ mr2 |= 0x7; /* 1 stop bit */
4102+
4103+ if ( !(cflag & PARENB) )
4104+ mr1 |= 0x10; /* no parity */
4105+ else if ( cflag & PARODD )
4106+ mr1 |= 0x04;
4107+
4108+ switch (cflag & CSIZE)
4109+ {
4110+ case CS5:
4111+ break;
4112+ case CS6:
4113+ mr1 |= 0x01;
4114+ break;
4115+ case CS7:
4116+ mr1 |= 0x02;
4117+ break;
4118+ case CS8:
4119+ mr1 |= 0x03;
4120+ break;
4121+ default:
4122+ return -EINVAL;
4123+ }
4124+
4125+/*
4126+ printk("scc2692: real_termios line=%d baudrate=%02x mr1=%02x mr2=%02x\n", port->channel, baudrate, mr1, mr2);
4127+*/
4128+
4129+ spin_lock_irqsave(tek_uart_lock, flags);
4130+
4131+ // Set baudrate into register CSRA
4132+ *(volatile unsigned char *)CSR(port) = (baudrate << 4) | (baudrate & 0xf);
4133+ // Reset MR pointer
4134+ *(volatile unsigned char *)COMMAND(port) = 1 << 4;
4135+ // Set MR1
4136+ *(volatile unsigned char *)MR(port) = mr1;
4137+ // Set MR2
4138+ *(volatile unsigned char *)MR(port) = mr2;
4139+
4140+ spin_unlock_irqrestore(tek_uart_lock, flags);
4141+
4142+ return 0;
4143+}
4144+
4145+static int scc_chars_in_buffer(void *ptr)
4146+{
4147+ struct scc_port *port = ptr;
4148+ int res;
4149+ unsigned long flags;
4150+
4151+ spin_lock_irqsave(tek_uart_lock, flags);
4152+ res = !(*(volatile unsigned char *)STATUS(port) & 4);
4153+ spin_unlock_irqrestore(tek_uart_lock, flags);
4154+
4155+ return res;
4156+}
4157+
4158+static void scc_hungup(void *ptr)
4159+{
4160+ scc_disable_tx_interrupts(ptr);
4161+ scc_disable_rx_interrupts(ptr);
4162+ MOD_DEC_USE_COUNT;
4163+}
4164+
4165+static void scc_close(void *ptr)
4166+{
4167+ scc_disable_tx_interrupts(ptr);
4168+ scc_disable_rx_interrupts(ptr);
4169+ MOD_DEC_USE_COUNT;
4170+}
4171+
4172+/*---------------------------------------------------------------------------
4173+ * Driver entrypoints referenced from above
4174+ *--------------------------------------------------------------------------*/
4175+
4176+static int scc_open (struct tty_struct * tty, struct file * filp)
4177+{
4178+ int line = MINOR(tty->device) - SCC_MINOR_BASE;
4179+ int retval;
4180+ struct scc_port *port = &scc_ports[line];
4181+
4182+ if ( line >= 2 )
4183+ return -ENXIO;
4184+
4185+ tty->driver_data = port;
4186+ port->gs.tty = tty;
4187+ port->gs.count++;
4188+ retval = gs_init_port(&port->gs);
4189+ if (retval) {
4190+ port->gs.count--;
4191+ return retval;
4192+ }
4193+ port->gs.flags |= GS_ACTIVE;
4194+ if (port->gs.count == 1) {
4195+ MOD_INC_USE_COUNT;
4196+ }
4197+ retval = gs_block_til_ready(port, filp);
4198+
4199+ if (retval) {
4200+ MOD_DEC_USE_COUNT;
4201+ port->gs.count--;
4202+ return retval;
4203+ }
4204+
4205+ if ((port->gs.count == 1) && (port->gs.flags & ASYNC_SPLIT_TERMIOS)) {
4206+ if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
4207+ *tty->termios = port->gs.normal_termios;
4208+ else
4209+ *tty->termios = port->gs.callout_termios;
4210+ scc_set_real_termios (port);
4211+// scc_disable_tx_interrupts(ptr);
4212+ }
4213+
4214+ port->gs.session = current->session;
4215+ port->gs.pgrp = current->pgrp;
4216+
4217+ scc_enable_rx_interrupts(port);
4218+
4219+ return 0;
4220+}
4221+
4222+static void scc_throttle (struct tty_struct * tty)
4223+{
4224+/*
4225+ struct scc_port *port = (struct scc_port *)tty->driver_data;
4226+ unsigned long flags;
4227+ SCC_ACCESS_INIT(port);
4228+
4229+ if (tty->termios->c_cflag & CRTSCTS) {
4230+ save_flags(flags);
4231+ cli();
4232+ SCCmod(TX_CTRL_REG, ~TCR_RTS, 0);
4233+ restore_flags(flags);
4234+ }
4235+ if (I_IXOFF(tty))
4236+ scc_send_xchar(tty, STOP_CHAR(tty));
4237+*/
4238+}
4239+
4240+static void scc_unthrottle (struct tty_struct * tty)
4241+{
4242+}
4243+
4244+static int scc_ioctl(struct tty_struct *tty, struct file *file,
4245+ unsigned int cmd, unsigned long arg)
4246+{
4247+ return -ENOIOCTLCMD;
4248+}
4249+
4250+static void scc_break_ctl(struct tty_struct *tty, int break_state)
4251+{
4252+}
4253+
4254+/*---------------------------------------------------------------------------
4255+ * Interface from generic_serial.c back here
4256+ *--------------------------------------------------------------------------*/
4257+
4258+static struct real_driver scc_real_driver = {
4259+ scc_disable_tx_interrupts,
4260+ scc_enable_tx_interrupts,
4261+ scc_disable_rx_interrupts,
4262+ scc_enable_rx_interrupts,
4263+ scc_get_CD,
4264+ scc_shutdown_port,
4265+ scc_set_real_termios,
4266+ scc_chars_in_buffer,
4267+ scc_close,
4268+ scc_hungup,
4269+ NULL
4270+};
4271+
4272+
4273+int __devinit scc_register_chip(struct scc_port *port)
4274+{
4275+ port->gs.callout_termios = tty_std_termios;
4276+ port->gs.normal_termios = tty_std_termios;
4277+ port->gs.magic = SCC_MAGIC;
4278+ port->gs.close_delay = HZ/2;
4279+ port->gs.closing_wait = 30 * HZ;
4280+ port->gs.rd = &scc_real_driver;
4281+#ifdef NEW_WRITE_LOCKING
4282+ port->gs.port_write_sem = MUTEX;
4283+#endif
4284+
4285+ init_waitqueue_head(&port->gs.open_wait);
4286+ init_waitqueue_head(&port->gs.close_wait);
4287+
4288+ return 0;
4289+}
4290+
4291+static int __devinit scc_chip_init(unsigned long base, int irq_rxa, int irq_txa,
4292+ int irq_rxb, int irq_txb)
4293+{
4294+ int err = 0;
4295+ unsigned long flags;
4296+
4297+ scc_ports[0].base = base;
4298+ scc_ports[0].scale = 4;
4299+ scc_ports[0].irq_rx = irq_rxa;
4300+ scc_ports[0].irq_tx = irq_txa;
4301+ scc_ports[0].channel = 0;
4302+
4303+ scc_ports[1].base = base;
4304+ scc_ports[1].scale = 4;
4305+ scc_ports[1].irq_rx = irq_rxb;
4306+ scc_ports[1].irq_tx = irq_txb;
4307+ scc_ports[1].channel = 1;
4308+
4309+ save_flags(flags);
4310+ cli();
4311+
4312+ err = request_irq(irq_rxa, scc_rx_int, SA_INTERRUPT, "SCC-A RX", &scc_ports[0]);
4313+ if ( err < 0 )
4314+ return err;
4315+
4316+ err = request_irq(irq_txa, scc_tx_int, SA_INTERRUPT, "SCC-A TX", &scc_ports[0]);
4317+ if ( err < 0 )
4318+ {
4319+ free_irq(irq_rxa, &scc_ports[0]);
4320+ return err;
4321+ }
4322+
4323+ err = request_irq(irq_rxb, scc_rx_int, SA_INTERRUPT, "SCC-B RX", &scc_ports[1]);
4324+ if ( err < 0 )
4325+ {
4326+ free_irq(irq_rxa, &scc_ports[0]);
4327+ free_irq(irq_txa, &scc_ports[0]);
4328+ return err;
4329+ }
4330+
4331+ err = request_irq(irq_txb, scc_tx_int, SA_INTERRUPT, "SCC-B TX", &scc_ports[1]);
4332+ if ( err < 0 )
4333+ {
4334+ free_irq(irq_rxa, &scc_ports[0]);
4335+ free_irq(irq_txa, &scc_ports[0]);
4336+ free_irq(irq_rxb, &scc_ports[1]);
4337+ return err;
4338+ }
4339+
4340+ disable_irq(irq_rxa);
4341+ disable_irq(irq_txa);
4342+ disable_irq(irq_rxb);
4343+ disable_irq(irq_txb);
4344+
4345+ restore_flags(flags);
4346+
4347+ scc_register_chip(&scc_ports[0]);
4348+ scc_register_chip(&scc_ports[1]);
4349+
4350+ return 0;
4351+}
4352+
4353+int __devinit tekscc_init(void)
4354+{
4355+ int err = -ENXIO;
4356+
4357+#ifdef CONFIG_TEKXP
4358+ err = scc_chip_init(TEK_UART_BASE, TEK_IRQ_RXRDY_A, TEK_IRQ_TXRDY_A,
4359+ TEK_IRQ_RXRDY_B, TEK_IRQ_TXRDY_B);
4360+#endif
4361+ if ( err < 0 )
4362+ return err;
4363+
4364+ memset(&scc_driver, 0, sizeof(scc_driver));
4365+ scc_driver.magic = TTY_DRIVER_MAGIC;
4366+ scc_driver.driver_name = "scc2692";
4367+#ifdef CONFIG_DEVFS_FS
4368+ scc_driver.name = "tts/%d";
4369+#else
4370+ scc_driver.name = "ttyS";
4371+#endif
4372+ scc_driver.major = TTY_MAJOR;
4373+ scc_driver.minor_start = SCC_MINOR_BASE;
4374+ scc_driver.num = 2;
4375+ scc_driver.type = TTY_DRIVER_TYPE_SERIAL;
4376+ scc_driver.subtype = SERIAL_TYPE_NORMAL;
4377+ scc_driver.init_termios = tty_std_termios;
4378+ scc_driver.init_termios.c_cflag = B9600 | PARENB | CSTOPB | CS7 | CREAD | HUPCL | CLOCAL;
4379+ scc_driver.flags = TTY_DRIVER_REAL_RAW;
4380+ scc_driver.refcount = &scc_refcount;
4381+ scc_driver.table = scc_table;
4382+ scc_driver.termios = scc_termios;
4383+ scc_driver.termios_locked = scc_termios_locked;
4384+ scc_driver.open = scc_open;
4385+ scc_driver.close = gs_close;
4386+ scc_driver.write = gs_write;
4387+ scc_driver.put_char = gs_put_char;
4388+ scc_driver.flush_chars = gs_flush_chars;
4389+ scc_driver.write_room = gs_write_room;
4390+ scc_driver.chars_in_buffer = gs_chars_in_buffer;
4391+ scc_driver.flush_buffer = gs_flush_buffer;
4392+ scc_driver.ioctl = scc_ioctl;
4393+ scc_driver.throttle = scc_throttle;
4394+ scc_driver.unthrottle = scc_unthrottle;
4395+ scc_driver.set_termios = gs_set_termios;
4396+ scc_driver.stop = gs_stop;
4397+ scc_driver.start = gs_start;
4398+ scc_driver.hangup = gs_hangup;
4399+ scc_driver.break_ctl = scc_break_ctl;
4400+
4401+ scc_callout_driver = scc_driver;
4402+#ifdef CONFIG_DEVFS_FS
4403+ scc_callout_driver.driver_name = "cua/%d";
4404+#else
4405+ scc_callout_driver.driver_name = "cua";
4406+#endif
4407+ scc_callout_driver.major = TTYAUX_MAJOR;
4408+ scc_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
4409+
4410+ if ((err = tty_register_driver(&scc_driver))) {
4411+ printk(KERN_ERR "scc2692: Couldn't register scc driver, error = %d\n", err);
4412+ return -EBUSY;
4413+ }
4414+ if ((err = tty_register_driver(&scc_callout_driver))) {
4415+ printk(KERN_ERR "scc2692: Couldn't register scc callout driver, error = %d\n", err);
4416+ return -EBUSY;
4417+ }
4418+
4419+ return 0;
4420+}
4421+
4422+static void __devexit tekscc_exit(void)
4423+{
4424+ struct scc_port *port = &scc_ports[0];
4425+ scc_disable_tx_interrupts(port);
4426+ scc_disable_rx_interrupts(port);
4427+ free_irq(port->irq_rx, port);
4428+ free_irq(port->irq_tx, port);
4429+
4430+ port = &scc_ports[1];
4431+ scc_disable_tx_interrupts(port);
4432+ scc_disable_rx_interrupts(port);
4433+ free_irq(port->irq_rx, port);
4434+ free_irq(port->irq_tx, port);
4435+
4436+ if ( tty_unregister_driver(&scc_driver) )
4437+ printk(KERN_ERR "Could not unregister SCC2692 serial driver\n");
4438+ if ( tty_unregister_driver(&scc_callout_driver) )
4439+ printk(KERN_ERR "Could not unregister SCC2692 callout driver\n");
4440+}
4441+
4442+module_init(tekscc_init);
4443+module_exit(tekscc_exit);
4444+MODULE_LICENSE("GPL");
4445+
4446+#ifdef CONFIG_SERIAL_CONSOLE
4447+
4448+/*---------------------------------------------------------------------------
4449+ * Serial console stuff...
4450+ *--------------------------------------------------------------------------*/
4451+
4452+#define scc_delay() do { __asm__ __volatile__ (" nop; nop"); } while (0)
4453+
4454+static void scc_ch_write (char ch)
4455+{
4456+ tek_uart_putchar(0, ch, 1);
4457+}
4458+
4459+static void scc_console_write (struct console *co, const char *str, unsigned count)
4460+{
4461+ unsigned long flags;
4462+
4463+ save_flags(flags);
4464+ cli();
4465+
4466+ while (count--)
4467+ {
4468+ if (*str == '\n')
4469+ scc_ch_write ('\r');
4470+ scc_ch_write (*str++);
4471+ }
4472+ restore_flags(flags);
4473+}
4474+
4475+static kdev_t scc_console_device(struct console *c)
4476+{
4477+ return MKDEV(TTY_MAJOR, SCC_MINOR_BASE + c->index);
4478+}
4479+
4480+
4481+static int __devinit scc_console_setup(struct console *co, char *options)
4482+{
4483+ return 0;
4484+}
4485+
4486+static struct console sercons = {
4487+ name: "ttyS",
4488+ write: scc_console_write,
4489+ device: scc_console_device,
4490+ setup: scc_console_setup,
4491+ flags: CON_PRINTBUFFER,
4492+ index: -1,
4493+};
4494+
4495+
4496+void __init tekscc_console_init(void)
4497+{
4498+ register_console(&sercons);
4499+}
4500+
4501+#endif
4502+
4503diff -Naur linux-2.4.26/drivers/char/tty_io.c linux-2.4.26-m68k/drivers/char/tty_io.c
4504--- linux-2.4.26/drivers/char/tty_io.c 2004-04-14 23:05:29.000000000 +1000
4505+++ linux-2.4.26-m68k/drivers/char/tty_io.c 2004-04-15 06:42:20.000000000 +1000
4506@@ -138,7 +138,9 @@
4507 unsigned int cmd, unsigned long arg);
4508 static int tty_fasync(int fd, struct file * filp, int on);
4509 extern int vme_scc_init (void);
4510+extern int tekscc_init (void);
4511 extern long vme_scc_console_init(void);
4512+extern long tekscc_console_init(void);
4513 extern int serial167_init(void);
4514 extern long serial167_console_init(void);
4515 extern void console_8xx_init(void);
4516@@ -2269,6 +2271,9 @@
4517 #if defined(CONFIG_SERIAL167)
4518 serial167_console_init();
4519 #endif
4520+#if defined(CONFIG_SCC2692)
4521+ tekscc_console_init();
4522+#endif
4523 #if defined(CONFIG_SH_SCI)
4524 sci_console_init();
4525 #endif
4526@@ -2408,6 +2413,9 @@
4527 #if defined(CONFIG_MVME162_SCC) || defined(CONFIG_BVME6000_SCC) || defined(CONFIG_MVME147_SCC)
4528 vme_scc_init();
4529 #endif
4530+#ifdef CONFIG_SCC2692
4531+ tekscc_init();
4532+#endif
4533 #ifdef CONFIG_SERIAL_TX3912
4534 tx3912_rs_init();
4535 #endif
4536diff -Naur linux-2.4.26/drivers/ide/ide-probe.c linux-2.4.26-m68k/drivers/ide/ide-probe.c
4537--- linux-2.4.26/drivers/ide/ide-probe.c 2004-04-14 23:05:29.000000000 +1000
4538+++ linux-2.4.26-m68k/drivers/ide/ide-probe.c 2004-04-15 06:42:24.000000000 +1000
4539@@ -350,6 +350,7 @@
4540 rc = 0;
4541 /* clear drive IRQ */
4542 (void) hwif->INB(IDE_STATUS_REG);
4543+ (void) ide_ack_intr(hwif);
4544 local_irq_restore(flags);
4545 } else {
4546 /* drive refused ID */
4547@@ -503,6 +504,7 @@
4548 drive->name, hwif->INB(IDE_STATUS_REG));
4549 /* ensure drive irq is clear */
4550 (void) hwif->INB(IDE_STATUS_REG);
4551+ (void) ide_ack_intr(hwif);
4552 } else {
4553 /* not present or maybe ATAPI */
4554 rc = 3;
4555@@ -513,6 +515,7 @@
4556 ide_delay_50ms();
4557 /* ensure drive irq is clear */
4558 (void) hwif->INB(IDE_STATUS_REG);
4559+ (void) ide_ack_intr(hwif);
4560 }
4561 return rc;
4562 }
4563diff -Naur linux-2.4.26/drivers/macintosh/adb.c linux-2.4.26-m68k/drivers/macintosh/adb.c
4564--- linux-2.4.26/drivers/macintosh/adb.c 2003-08-25 21:44:42.000000000 +1000
4565+++ linux-2.4.26-m68k/drivers/macintosh/adb.c 2003-10-21 07:14:22.000000000 +1000
4566@@ -35,6 +35,7 @@
4567 #include <linux/init.h>
4568 #include <linux/delay.h>
4569 #include <linux/completion.h>
4570+
4571 #include <asm/uaccess.h>
4572 #ifdef CONFIG_PPC
4573 #include <asm/prom.h>
4574@@ -380,14 +381,14 @@
4575
4576 if (adb_controller == NULL)
4577 return -ENXIO;
4578-
4579+
4580 if (adb_controller->autopoll)
4581 adb_controller->autopoll(0);
4582
4583 nret = notifier_call_chain(&adb_client_list, ADB_MSG_PRE_RESET, NULL);
4584 if (nret & NOTIFY_STOP_MASK) {
4585 if (adb_controller->autopoll)
4586- adb_controller->autopoll(devs);
4587+ adb_controller->autopoll(0);
4588 return -EBUSY;
4589 }
4590
4591@@ -467,13 +468,15 @@
4592 use_sreq = 1;
4593 } else
4594 use_sreq = 0;
4595- req->nbytes = nbytes+1;
4596+ i = (flags & ADBREQ_RAW) ? 0 : 1;
4597+ req->nbytes = nbytes+i;
4598 req->done = done;
4599 req->reply_expected = flags & ADBREQ_REPLY;
4600 req->data[0] = ADB_PACKET;
4601 va_start(list, nbytes);
4602- for (i = 0; i < nbytes; ++i)
4603- req->data[i+1] = va_arg(list, int);
4604+ while (i < req->nbytes) {
4605+ req->data[i++] = va_arg(list, int);
4606+ }
4607 va_end(list);
4608
4609 if (flags & ADBREQ_NOSEND)
4610diff -Naur linux-2.4.26/drivers/mtd/maps/Config.in linux-2.4.26-m68k/drivers/mtd/maps/Config.in
4611--- linux-2.4.26/drivers/mtd/maps/Config.in 2003-06-14 00:51:34.000000000 +1000
4612+++ linux-2.4.26-m68k/drivers/mtd/maps/Config.in 2003-07-22 07:32:35.000000000 +1000
4613@@ -96,6 +96,10 @@
4614 dep_tristate ' Generic uClinux RAM/ROM filesystem support' CONFIG_MTD_UCLINUX $CONFIG_MTD_PARTITIONS
4615 fi
4616
4617+if [ "$CONFIG_TEKXP" = "y" ]; then
4618+ dep_tristate ' TekXpress optional ROM support' CONFIG_MTD_TEKXP_OPTROM $CONFIG_MTD_ROM
4619+fi
4620+
4621 # This needs CFI or JEDEC, depending on the cards found.
4622 dep_tristate ' PCI MTD driver' CONFIG_MTD_PCI $CONFIG_MTD $CONFIG_PCI
4623 dep_tristate ' PCMCIA MTD driver' CONFIG_MTD_PCMCIA $CONFIG_MTD $CONFIG_PCMCIA
4624diff -Naur linux-2.4.26/drivers/mtd/maps/Makefile linux-2.4.26-m68k/drivers/mtd/maps/Makefile
4625--- linux-2.4.26/drivers/mtd/maps/Makefile 2003-06-14 00:51:34.000000000 +1000
4626+++ linux-2.4.26-m68k/drivers/mtd/maps/Makefile 2003-07-22 07:32:35.000000000 +1000
4627@@ -22,6 +22,7 @@
4628 obj-$(CONFIG_MTD_L440GX) += l440gx.o
4629 obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom.o
4630 obj-$(CONFIG_MTD_ICH2ROM) += ich2rom.o
4631+obj-$(CONFIG_MTD_TEKXP_OPTROM) += tekxp_optrom.o
4632 obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o
4633 obj-$(CONFIG_MTD_MBX860) += mbx860.o
4634 obj-$(CONFIG_MTD_NORA) += nora.o
4635diff -Naur linux-2.4.26/drivers/mtd/maps/tekxp_optrom.c linux-2.4.26-m68k/drivers/mtd/maps/tekxp_optrom.c
4636--- linux-2.4.26/drivers/mtd/maps/tekxp_optrom.c 1970-01-01 10:00:00.000000000 +1000
4637+++ linux-2.4.26-m68k/drivers/mtd/maps/tekxp_optrom.c 2003-07-22 07:32:35.000000000 +1000
4638@@ -0,0 +1,177 @@
4639+#include <linux/module.h>
4640+#include <linux/types.h>
4641+#include <linux/kernel.h>
4642+#include <asm/io.h>
4643+#include <linux/mtd/mtd.h>
4644+#include <linux/mtd/map.h>
4645+#include <linux/config.h>
4646+
4647+/*
4648+ * Maximum number of ROMS supported by this drivers.
4649+ *
4650+ * There will be definitely be no more, since the address space for them
4651+ * is restricted to what those 16 may span.
4652+ */
4653+#define MAX_NUM_OPTROM 16
4654+
4655+/*
4656+ * Virtual address of the address space potentially used by the ROMs.
4657+ */
4658+static unsigned long possible_rom_memory;
4659+
4660+/*
4661+ * Structure holding just the information needed for the MTD framework.
4662+ * The driver itself needs no further information about a single ROM.
4663+ */
4664+typedef struct {
4665+ struct map_info map;
4666+ struct mtd_info *mtd;
4667+} optrom_desc_t;
4668+
4669+static int num_optrom;
4670+static optrom_desc_t optrom_desc[MAX_NUM_OPTROM];
4671+
4672+/*
4673+ * Check if a ROM is present and determinate its size.
4674+ */
4675+static unsigned int __init detect_optrom_size(unsigned long start_address)
4676+{
4677+ unsigned long original = *(unsigned long *)start_address;
4678+
4679+ /*
4680+ * We try to write into the ROM. It will not fault on us.
4681+ */
4682+ *(volatile unsigned long *)start_address = ~original;
4683+
4684+ /*
4685+ * If the write did not change there is a ROM or nothing.
4686+ */
4687+ if ( *(volatile unsigned long *)start_address == original )
4688+ {
4689+ /*
4690+ * But the Nothing will fail to report a correct size.
4691+ *
4692+ * Yes, the size is stored at a given position within the
4693+ * ROM. So if someone did create ROMs on his own behalf
4694+ * not following the "specification" this driver will
4695+ * fail to detect them.
4696+ *
4697+ * Do NOT fix this! It is intended behaviour since the
4698+ * future goal of this driver is to present the filesystem
4699+ * stored in the original ROMs.
4700+ */
4701+ unsigned short size = *(unsigned short *)(start_address + 6);
4702+ if ( size == 0x80 || size == 0x100 || size == 0x200 || size == 0x400 )
4703+ return size * 1024;
4704+ }
4705+
4706+ /*
4707+ * If we hit something else try to restore the original content.
4708+ */
4709+ *(unsigned long *)start_address = original;
4710+
4711+ return 0;
4712+}
4713+
4714+/*
4715+ * Just the obvious way to copy memory around.
4716+ */
4717+static void optrom_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
4718+{
4719+ memcpy(to, (char *)map->map_priv_1 + from, len);
4720+}
4721+
4722+/*
4723+ * We can not write into the ROMs.
4724+ */
4725+static void optrom_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
4726+{
4727+}
4728+
4729+/*
4730+ * Initialization
4731+ */
4732+static int __init init_optrom(void)
4733+{
4734+ int i;
4735+
4736+ /*
4737+ * Get all memory mapped that may hold a ROM. This might have to
4738+ * be switched to a less gready sheme if causing any problems.
4739+ */
4740+ possible_rom_memory = (unsigned long)ioremap_nocache(0x1000000, MAX_NUM_OPTROM * 0x100000);
4741+ if ( !possible_rom_memory )
4742+ {
4743+ printk(KERN_WARNING "Could not map optroms into the virtual memory space\n");
4744+ return -ENXIO;
4745+ }
4746+
4747+ /*
4748+ * Search through the complete address space for any ROM.
4749+ * If any ROM is found register it with the MTD framework.
4750+ */
4751+ for ( i=0; i<MAX_NUM_OPTROM; i++ )
4752+ {
4753+ unsigned int size = detect_optrom_size(possible_rom_memory + i * 0x100000);
4754+ if ( size > 0 )
4755+ {
4756+ optrom_desc_t *desc = &optrom_desc[num_optrom];
4757+
4758+ printk(KERN_INFO "Found optional ROM of size %u at %08x\n", size, 0x1000000 + i * 0x100000);
4759+
4760+ desc->map.name = "TekXpress optional ROM";
4761+ desc->map.size = size;
4762+ desc->map.map_priv_1 = possible_rom_memory + i * 0x100000;
4763+ desc->map.copy_from = optrom_copy_from;
4764+ desc->map.copy_to = optrom_copy_to;
4765+
4766+ desc->mtd = do_map_probe("map_rom", &desc->map);
4767+ if ( !desc->mtd )
4768+ {
4769+ printk(KERN_ERR "Could not allocate MTD structure\n");
4770+ continue;
4771+ }
4772+
4773+ desc->mtd->module = THIS_MODULE;
4774+ add_mtd_device(desc->mtd);
4775+
4776+ num_optrom++;
4777+ }
4778+
4779+ }
4780+
4781+ if ( num_optrom <= 0 )
4782+ {
4783+ iounmap((void *)possible_rom_memory);
4784+ printk(KERN_WARNING "No optional rom found\n");
4785+ return -ENXIO;
4786+ }
4787+
4788+ return 0;
4789+}
4790+
4791+/*
4792+ * Unregister all ROMs found from the MTD framework.
4793+ */
4794+void __exit cleanup_optrom(void)
4795+{
4796+ while ( num_optrom-- )
4797+ {
4798+ optrom_desc_t *desc = &optrom_desc[num_optrom];
4799+
4800+ del_mtd_device(desc->mtd);
4801+ map_destroy(desc->mtd);
4802+ }
4803+
4804+ iounmap((void*)possible_rom_memory);
4805+}
4806+
4807+
4808+
4809+module_init(init_optrom);
4810+module_exit(cleanup_optrom);
4811+
4812+MODULE_LICENSE("GPL");
4813+MODULE_AUTHOR("Michael Mueller <malware@t-online.de>");
4814+MODULE_DESCRIPTION("MTD map driver for optional ROM of the TekXpress XP2x X-Terminals");
4815+
4816diff -Naur linux-2.4.26/drivers/net/Makefile linux-2.4.26-m68k/drivers/net/Makefile
4817--- linux-2.4.26/drivers/net/Makefile 2004-04-14 23:05:30.000000000 +1000
4818+++ linux-2.4.26-m68k/drivers/net/Makefile 2004-04-15 06:42:31.000000000 +1000
4819@@ -95,6 +95,7 @@
4820 obj-$(CONFIG_FEALNX) += fealnx.o mii.o
4821 obj-$(CONFIG_TC35815) += tc35815.o
4822 obj-$(CONFIG_TIGON3) += tg3.o
4823+obj-$(CONFIG_TEKSONIC) += teksonic.o
4824
4825 ifeq ($(CONFIG_E100),y)
4826 obj-y += e100/e100.o
4827diff -Naur linux-2.4.26/drivers/net/Space.c linux-2.4.26-m68k/drivers/net/Space.c
4828--- linux-2.4.26/drivers/net/Space.c 2004-02-19 00:36:31.000000000 +1100
4829+++ linux-2.4.26-m68k/drivers/net/Space.c 2004-02-19 09:16:53.000000000 +1100
4830@@ -101,6 +101,7 @@
4831 extern int mac8390_probe(struct net_device *dev);
4832 extern int mac89x0_probe(struct net_device *dev);
4833 extern int mc32_probe(struct net_device *dev);
4834+extern int teksonic_probe(struct net_device *dev);
4835
4836 /* Detachable devices ("pocket adaptors") */
4837 extern int de600_probe(struct net_device *);
4838@@ -326,6 +327,9 @@
4839 };
4840
4841 static struct devprobe m68k_probes[] __initdata = {
4842+#ifdef CONFIG_TEKSONIC
4843+ {teksonic_probe, 0},
4844+#endif
4845 #ifdef CONFIG_ATARILANCE /* Lance-based Atari ethernet boards */
4846 {atarilance_probe, 0},
4847 #endif
4848diff -Naur linux-2.4.26/drivers/net/a2065.c linux-2.4.26-m68k/drivers/net/a2065.c
4849--- linux-2.4.26/drivers/net/a2065.c 2003-06-14 00:51:34.000000000 +1000
4850+++ linux-2.4.26-m68k/drivers/net/a2065.c 2004-04-16 21:37:49.000000000 +1000
4851@@ -284,6 +284,7 @@
4852 struct sk_buff *skb = 0; /* XXX shut up gcc warnings */
4853
4854 #ifdef TEST_HITS
4855+ int i;
4856 printk ("[");
4857 for (i = 0; i < RX_RING_SIZE; i++) {
4858 if (i == lp->rx_new)
4859diff -Naur linux-2.4.26/drivers/net/macsonic.c linux-2.4.26-m68k/drivers/net/macsonic.c
4860--- linux-2.4.26/drivers/net/macsonic.c 2003-08-25 21:44:42.000000000 +1000
4861+++ linux-2.4.26-m68k/drivers/net/macsonic.c 2004-06-20 21:17:28.000000000 +1000
4862@@ -199,6 +199,7 @@
4863 if ((lp->rba = (char *)
4864 kmalloc(SONIC_NUM_RRS * SONIC_RBSIZE, GFP_KERNEL | GFP_DMA)) == NULL) {
4865 printk(KERN_ERR "%s: couldn't allocate receive buffers\n", dev->name);
4866+ kfree(lp);
4867 return -ENOMEM;
4868 }
4869
4870@@ -635,19 +636,14 @@
4871 }
4872
4873 #ifdef MODULE
4874-static char namespace[16] = "";
4875 static struct net_device dev_macsonic;
4876
4877 MODULE_PARM(sonic_debug, "i");
4878 MODULE_PARM_DESC(sonic_debug, "macsonic debug level (1-4)");
4879-MODULE_LICENSE("GPL");
4880-
4881-EXPORT_NO_SYMBOLS;
4882
4883 int
4884 init_module(void)
4885 {
4886- dev_macsonic.name = namespace;
4887 dev_macsonic.init = macsonic_probe;
4888
4889 if (register_netdev(&dev_macsonic) != 0) {
4890diff -Naur linux-2.4.26/drivers/net/teksonic.c linux-2.4.26-m68k/drivers/net/teksonic.c
4891--- linux-2.4.26/drivers/net/teksonic.c 1970-01-01 10:00:00.000000000 +1000
4892+++ linux-2.4.26-m68k/drivers/net/teksonic.c 2003-07-22 07:28:08.000000000 +1000
4893@@ -0,0 +1,310 @@
4894+/*
4895+ * linux/drivers/net/teksonic.c
4896+ *
4897+ * (C) 2003 Michael Mueller <malware@t-online.de>
4898+ *
4899+ * based on the macsonic driver:
4900+ *
4901+ * (C) 1998 Alan Cox
4902+ *
4903+ * Debugging Andreas Ehliar, Michael Schmitz
4904+ *
4905+ * Based on code
4906+ * (C) 1996 by Thomas Bogendoerfer (tsbogend@bigbug.franken.de)
4907+ *
4908+ * This driver is based on work from Andreas Busse, but most of
4909+ * the code is rewritten.
4910+ *
4911+ * (C) 1995 by Andreas Busse (andy@waldorf-gmbh.de)
4912+ *
4913+ */
4914+
4915+#include <linux/kernel.h>
4916+#include <linux/sched.h>
4917+#include <linux/types.h>
4918+#include <linux/ctype.h>
4919+#include <linux/fcntl.h>
4920+#include <linux/interrupt.h>
4921+#include <linux/ptrace.h>
4922+#include <linux/ioport.h>
4923+#include <linux/in.h>
4924+#include <linux/slab.h>
4925+#include <linux/string.h>
4926+#include <linux/delay.h>
4927+#include <asm/system.h>
4928+#include <asm/bitops.h>
4929+#include <asm/pgtable.h>
4930+#include <asm/segment.h>
4931+#include <asm/io.h>
4932+#include <asm/irq.h>
4933+#include <asm/dma.h>
4934+
4935+#include <linux/errno.h>
4936+
4937+#include <linux/netdevice.h>
4938+#include <linux/etherdevice.h>
4939+#include <linux/skbuff.h>
4940+#include <linux/module.h>
4941+#include <asm/teknvram.h>
4942+
4943+/*
4944+ * All registers are located at addresses dividable by 4.
4945+ */
4946+
4947+#define SREGS_PAD(n) u16 n;
4948+
4949+/*
4950+ * This is a hack to get the endianness stuff done correctly.
4951+ */
4952+
4953+#define CONFIG_MACSONIC
4954+
4955+/*
4956+ * Generic Sonic definitions
4957+ */
4958+#include "sonic.h"
4959+
4960+#ifdef DEBUG
4961+
4962+#define SONIC_READ(reg) _SONIC_READ(base_addr, reg)
4963+#define SONIC_WRITE(reg,val) do { _SONIC_WRITE(base_addr, reg, val); } while(0)
4964+
4965+static inline unsigned short _SONIC_READ(unsigned long base_addr, int reg)
4966+{
4967+ unsigned short val = *((volatile unsigned long*)(base_addr + 4*(reg))) & 0xffff;
4968+ printk("sonic_read(%08x) = %02x\n", base_addr + 4*(reg), val);
4969+ return val;
4970+}
4971+
4972+static inline void _SONIC_WRITE(unsigned long base_addr, int reg, unsigned short val)
4973+{
4974+ printk("sonic_write(%08x,%04x)\n", base_addr + 4*(reg), val);
4975+ *((volatile unsigned long*)(base_addr + 4*(reg))) = (val) & 0xffff;
4976+}
4977+
4978+static inline unsigned short sonic_read(struct net_device *dev, int reg)
4979+{
4980+ unsigned short val = *((volatile unsigned long*)(dev->base_addr + 4*(reg))) & 0xffff;
4981+ printk("sonic_read(%08x) = %02x\n", dev->base_addr + 4*(reg), val);
4982+ return val;
4983+}
4984+
4985+static inline void sonic_write(struct net_device *dev, int reg, unsigned short val)
4986+{
4987+ printk("sonic_write(%08x,%04x)\n", dev->base_addr + 4*(reg), val);
4988+ *((volatile unsigned long*)(dev->base_addr + 4*(reg))) = (val) & 0xffff;
4989+}
4990+
4991+#else
4992+
4993+#define SONIC_READ(reg) ((unsigned short)(*(volatile unsigned long *)((base_addr) + 4*(reg))) & 0xffff)
4994+
4995+#define SONIC_WRITE(reg, val) do { *(volatile unsigned long*)((base_addr) + 4*(reg)) = (val)& 0xffff; } while (0)
4996+
4997+#define sonic_read(dev,reg) ((unsigned short)(*(volatile unsigned long *)((dev)->base_addr + 4*(reg))) & 0xffff)
4998+
4999+#define sonic_write(dev, reg, val) do { *(volatile unsigned long*)((dev)->base_addr + 4*(reg)) = (val)& 0xffff; } while (0)
5000+
5001+#endif
5002+
5003+static int sonic_debug = 0;
5004+static int sonic_version_printed;
5005+
5006+static int reg_offset;
5007+
5008+int teksonic_init(struct net_device* dev)
5009+{
5010+ int i,j;
5011+ struct sonic_local* lp_alloc[20];
5012+ struct sonic_local* lp;
5013+
5014+ /* Allocate the entire chunk of memory for the descriptors.
5015+ Note that this cannot cross a 64K boundary. */
5016+ for (i = 0; i < 20; i++) {
5017+ unsigned long desc_base, desc_top, desc_top2;
5018+ if((lp_alloc[i] = kmalloc(sizeof(struct sonic_local), GFP_KERNEL)) == NULL) {
5019+ printk(KERN_ERR "%s: couldn't allocate descriptor buffers\n", dev->name);
5020+ return -ENOMEM;
5021+ }
5022+ desc_base = (unsigned long)virt_to_phys(lp_alloc[i]);
5023+ desc_top = desc_base + sizeof(struct sonic_local);
5024+ desc_top2 = (unsigned long)virt_to_phys(lp_alloc[i] + 1);
5025+
5026+ if ( (desc_top == desc_top2) && (desc_top & 0xffff) >= (desc_base & 0xffff))
5027+ break;
5028+
5029+ /* Hmm. try again (FIXME: does this actually work?) */
5030+ /* Note: It did not work when freeing the memory allocated
5031+ previously since it got the same memory again. */
5032+/* kfree(lp); */
5033+ printk(KERN_DEBUG
5034+ "%s: didn't get continguous chunk [%08lx - %08lx], trying again\n",
5035+ dev->name, desc_base, desc_top);
5036+
5037+ }
5038+
5039+ /* Deallocate what was allocated just to get the alignment done. */
5040+ for ( j = i-1; j >= 0; j-- )
5041+ kfree(lp_alloc[j]);
5042+
5043+ if (i==20) {
5044+ /* Note: Do not free dev->priv, it is deallocated later! */
5045+ printk(KERN_ERR "%s: tried 20 times to allocate descriptor buffers, giving up.\n",
5046+ dev->name);
5047+ return -ENOMEM;
5048+ }
5049+
5050+ dev->priv = lp = lp_alloc[i];
5051+
5052+ memset(lp, 0, sizeof(struct sonic_local));
5053+
5054+ lp->cda_laddr = virt_to_phys(&(lp->cda));
5055+ lp->tda_laddr = virt_to_phys(lp->tda);
5056+ lp->rra_laddr = virt_to_phys(lp->rra);
5057+ lp->rda_laddr = virt_to_phys(lp->rda);
5058+
5059+ /* FIXME, maybe we should use skbs */
5060+ if ((lp->rba = (char *)kmalloc(SONIC_NUM_RRS * SONIC_RBSIZE, GFP_KERNEL)) == NULL) {
5061+ printk(KERN_ERR "%s: couldn't allocate receive buffers\n", dev->name);
5062+ return -ENOMEM;
5063+ }
5064+ lp->rba_laddr = virt_to_phys(lp->rba);
5065+
5066+#if 0
5067+ {
5068+ int rs, ds;
5069+
5070+ /* almost always 12*4096, but let's not take chances */
5071+ rs = ((SONIC_NUM_RRS * SONIC_RBSIZE + 4095) / 4096) * 4096;
5072+ /* almost always under a page, but let's not take chances */
5073+ ds = ((sizeof(struct sonic_local) + 4095) / 4096) * 4096;
5074+ kernel_set_cachemode(lp->rba, rs, IOMAP_NOCACHE_SER);
5075+ kernel_set_cachemode(lp, ds, IOMAP_NOCACHE_SER);
5076+ }
5077+#endif
5078+
5079+
5080+#if 0
5081+ flush_cache_all();
5082+#endif
5083+
5084+ dev->open = sonic_open;
5085+ dev->stop = sonic_close;
5086+ dev->hard_start_xmit = sonic_send_packet;
5087+ dev->get_stats = sonic_get_stats;
5088+ dev->set_multicast_list = &sonic_multicast_list;
5089+
5090+ /*
5091+ * clear tally counter
5092+ */
5093+ sonic_write(dev, SONIC_CRCT, 0xffff);
5094+ sonic_write(dev, SONIC_FAET, 0xffff);
5095+ sonic_write(dev, SONIC_MPT, 0xffff);
5096+
5097+ /* Fill in the fields of the device structure with ethernet values. */
5098+ ether_setup(dev);
5099+ return 0;
5100+}
5101+
5102+int teksonic_ethernet_addr(struct net_device* dev)
5103+{
5104+ int i;
5105+
5106+ /* On NuBus boards we can sometimes look in the ROM resources.
5107+ No such luck for comm-slot/onboard. */
5108+ for(i = 0; i < 6; i++)
5109+ dev->dev_addr[i] = nvram_readb(NVRAM_SONIC_MAC+i);
5110+
5111+ return 0;
5112+}
5113+
5114+int teksonic_probe(struct net_device* dev)
5115+{
5116+ /* Bwahahaha */
5117+ static int once_is_more_than_enough;
5118+ int i;
5119+ int dma_bitmode;
5120+
5121+ if (once_is_more_than_enough)
5122+ return -ENODEV;
5123+ once_is_more_than_enough = 1;
5124+
5125+ if (dev) {
5126+ dev = init_etherdev(dev, sizeof(struct sonic_local));
5127+ if (!dev)
5128+ return -ENOMEM;
5129+ } else {
5130+ dev = init_etherdev(NULL, sizeof(struct sonic_local));
5131+ }
5132+ if (dev->priv != NULL) {
5133+ kfree(dev->priv);
5134+ dev->priv = NULL;
5135+ }
5136+
5137+ if (dev == NULL)
5138+ return -ENOMEM;
5139+
5140+ /* Danger! My arms are flailing wildly! You *must* set this
5141+ before using sonic_read() */
5142+
5143+ dev->base_addr = 0xFFC00000; // FIXME: This does rely on transparent translation
5144+ dev->irq = IRQ6;
5145+
5146+ if (!sonic_version_printed) {
5147+ printk(KERN_INFO "%s", version);
5148+ sonic_version_printed = 1;
5149+ }
5150+ printk(KERN_INFO "%s: SONIC at 0x%08lx\n",
5151+ dev->name, dev->base_addr);
5152+
5153+ reg_offset = 0;
5154+ dma_bitmode = 1;
5155+
5156+ /* Software reset, then initialize control registers. */
5157+ sonic_write(dev, SONIC_CMD, SONIC_CR_RST);
5158+
5159+ sonic_write(dev, SONIC_DCR, SONIC_DCR_BMS |
5160+ SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | SONIC_DCR_EXBUS |
5161+ (dma_bitmode ? SONIC_DCR_DW : 0));
5162+#if 0
5163+ sonic_write(dev, SONIC_DCR, 0x3F);
5164+#endif
5165+
5166+ /* This *must* be written back to in order to restore the
5167+ extended programmable output bits */
5168+ sonic_write(dev, SONIC_DCR2, 0);
5169+
5170+ sonic_write(dev, SONIC_CMD, 0);
5171+
5172+ /* Clear *and* disable interrupts to be on the safe side */
5173+ sonic_write(dev, SONIC_ISR,0x7fff);
5174+ sonic_write(dev, SONIC_IMR,0);
5175+
5176+ /* Now look for the MAC address. */
5177+ if (teksonic_ethernet_addr(dev) != 0)
5178+ return -ENODEV;
5179+
5180+ printk(KERN_INFO "MAC ");
5181+ for (i = 0; i < 6; i++) {
5182+ printk("%2.2x", dev->dev_addr[i]);
5183+ if (i < 5)
5184+ printk(":");
5185+ }
5186+
5187+ printk(" IRQ %d\n", dev->irq);
5188+
5189+ /* Shared init code */
5190+ return teksonic_init(dev);
5191+}
5192+
5193+
5194+#define vdma_alloc(foo, bar) ((u32)(foo))
5195+#define vdma_free(baz)
5196+#define sonic_chiptomem(bat) (phys_to_virt(bat))
5197+#define PHYSADDR(quux) (virt_to_phys((void*)(quux)))
5198+
5199+#define sonic_request_irq request_irq
5200+#define sonic_free_irq free_irq
5201+
5202+#include "sonic.c"
5203+
5204diff -Naur linux-2.4.26/drivers/sbus/char/sunkbd.c linux-2.4.26-m68k/drivers/sbus/char/sunkbd.c
5205--- linux-2.4.26/drivers/sbus/char/sunkbd.c 2002-08-03 10:39:44.000000000 +1000
5206+++ linux-2.4.26-m68k/drivers/sbus/char/sunkbd.c 2002-08-06 00:37:03.000000000 +1000
5207@@ -761,6 +761,7 @@
5208
5209 static void boot_it(void)
5210 {
5211+#if !defined(CONFIG_SUN3) && !defined(CONFIG_SUN3X)
5212 extern int obp_system_intr(void);
5213
5214 if (!obp_system_intr())
5215@@ -768,6 +769,7 @@
5216 /* sigh.. attempt to prevent multiple entry */
5217 last_keycode=1;
5218 rep = 0;
5219+#endif
5220 }
5221
5222 static void compose(void)
5223@@ -1232,7 +1234,7 @@
5224
5225 int __init sun_kbd_init(void)
5226 {
5227- int i, opt_node;
5228+ int i;
5229 struct kbd_struct kbd0;
5230 extern struct tty_driver console_driver;
5231
5232@@ -1250,18 +1252,22 @@
5233
5234 kd_mksound = sunkbd_kd_mksound;
5235
5236+#ifndef CONFIG_SUN3X_ZS
5237 /* XXX Check keyboard-click? property in 'options' PROM node XXX */
5238 if(sparc_cpu_model != sun4) {
5239- opt_node = prom_getchild(prom_root_node);
5240+ int opt_node = prom_getchild(prom_root_node);
5241 opt_node = prom_searchsiblings(opt_node, "options");
5242 i = prom_getintdefault(opt_node, "keyboard-click?", -1);
5243 if(i != -1)
5244 sunkbd_clickp = 1;
5245 else
5246 sunkbd_clickp = 0;
5247- } else {
5248+ } else
5249+#else
5250+ {
5251 sunkbd_clickp = 0;
5252 }
5253+#endif
5254
5255 keyboard_tasklet.func = sun_kbd_bh;
5256
5257diff -Naur linux-2.4.26/drivers/sbus/char/sunserial.c linux-2.4.26-m68k/drivers/sbus/char/sunserial.c
5258--- linux-2.4.26/drivers/sbus/char/sunserial.c 2002-08-03 10:39:44.000000000 +1000
5259+++ linux-2.4.26-m68k/drivers/sbus/char/sunserial.c 2002-08-03 22:45:22.000000000 +1000
5260@@ -10,6 +10,13 @@
5261 #include <linux/module.h>
5262 #include <linux/errno.h>
5263 #include <linux/tty.h>
5264+
5265+#ifdef CONFIG_SUN3
5266+#include <linux/sched.h>
5267+#include <asm/ptrace.h>
5268+#include <linux/interrupt.h>
5269+#endif
5270+
5271 #include <linux/serial.h>
5272 #include <linux/serialP.h>
5273 #include <linux/string.h>
5274@@ -228,6 +235,7 @@
5275 void
5276 sunserial_console_termios(struct console *con)
5277 {
5278+#ifndef CONFIG_SUN3X_ZS
5279 char mode[16], buf[16], *s;
5280 char *mode_prop = "ttyX-mode";
5281 char *cd_prop = "ttyX-ignore-cd";
5282@@ -331,6 +339,9 @@
5283 }
5284
5285 con->cflag = cflag;
5286+#else /* CONFIG_SUN3 */
5287+ con->cflag = CREAD | HUPCL | CLOCAL | B9600 | CS8;
5288+#endif /* CONFIG_SUN3 */
5289 }
5290
5291 void
5292@@ -452,6 +463,9 @@
5293 }
5294 #endif
5295
5296+#ifndef CONFIG_SUN3X_ZS
5297 prom_printf("No serial devices found, bailing out.\n");
5298 prom_halt();
5299+#endif
5300+
5301 }
5302diff -Naur linux-2.4.26/drivers/sbus/char/zs.c linux-2.4.26-m68k/drivers/sbus/char/zs.c
5303--- linux-2.4.26/drivers/sbus/char/zs.c 2002-08-03 10:39:44.000000000 +1000
5304+++ linux-2.4.26-m68k/drivers/sbus/char/zs.c 2002-08-06 00:37:04.000000000 +1000
5305@@ -11,6 +11,8 @@
5306 * /proc/tty/driver/serial now exists and is readable.
5307 * Alex Buell <alex.buell@tahallah.demon.co.uk>, 2001-12-23
5308 *
5309+ * Tweaks for sun3x by Oliver Jowett <oliver@jowett.manawatu.gen.nz>
5310+ *
5311 */
5312
5313 #include <linux/errno.h>
5314@@ -39,23 +41,39 @@
5315 #include <asm/system.h>
5316 #include <asm/uaccess.h>
5317 #include <asm/bitops.h>
5318+
5319+#include <asm/sbus.h>
5320+#ifndef CONFIG_SUN3X_ZS
5321 #include <asm/kdebug.h>
5322 #include <asm/page.h>
5323 #include <asm/pgtable.h>
5324
5325-#include <asm/sbus.h>
5326 #ifdef __sparc_v9__
5327 #include <asm/fhc.h>
5328 #endif
5329 #ifdef CONFIG_PCI
5330 #include <linux/pci.h>
5331 #endif
5332+#else /* CONFIG_SUN3X_ZS */
5333+#include <linux/ioport.h>
5334+#ifndef CONFIG_SUN3X
5335+#include <asm/sun3mmu.h>
5336+#else
5337+#include <asm/sun3xprom.h>
5338+#endif
5339+#endif /* CONFIG_SUN3X_ZS */
5340
5341 #include "sunserial.h"
5342 #include "zs.h"
5343 #include "sunkbd.h"
5344 #include "sunmouse.h"
5345
5346+/* some sun3 boxen always use vectors */
5347+#ifdef CONFIG_SUN3
5348+#undef NV
5349+#define NV 0
5350+#endif
5351+
5352 static int num_serial = 2; /* sun4/sun4c/sun4m - Two chips on board. */
5353 #define NUM_SERIAL num_serial
5354 #define NUM_CHANNELS (NUM_SERIAL * 2)
5355@@ -425,6 +443,7 @@
5356 */
5357 void batten_down_hatches(void)
5358 {
5359+#ifndef CONFIG_SUN3X_ZS
5360 if (!stop_a_enabled)
5361 return;
5362 /* If we are doing kadb, we call the debugger
5363@@ -448,6 +467,13 @@
5364 */
5365
5366 return;
5367+#else /* CONFIG_SUN3X_ZS */
5368+#ifndef CONFIG_SUN3X
5369+ prom_reboot("");
5370+#else
5371+ sun3x_reboot();
5372+#endif
5373+#endif /* CONFIG_SUN3X_ZS */
5374 }
5375
5376
5377@@ -550,7 +576,9 @@
5378 * arch/sparc/kernel/sparc-stub.c to see how all this works.
5379 */
5380 if (info->kgdb_channel && (ch =='\003')) {
5381+#ifndef CONFIG_SUN3X_ZS
5382 breakpoint();
5383+#endif
5384 return;
5385 }
5386 #endif
5387@@ -683,6 +711,23 @@
5388 for (i = 0; i < NUM_SERIAL; i++) {
5389 unsigned char r3 = read_zsreg(info->zs_channel, 3);
5390
5391+ /* some sun3's need the pending flags cleared */
5392+#ifdef CONFIG_SUN3
5393+ unsigned char r2 = read_zsreg(info->zs_next->zs_channel, 2);
5394+ r2 &= STATUS_MASK;
5395+ if(r2 & 0x8) {
5396+ sbus_writeb(RES_H_IUS, &info->zs_channel->control);
5397+ ZSDELAY();
5398+ ZS_WSYNC(info->zs_channel);
5399+ ZSLOG(REGCTRL, RES_H_IUS, 1);
5400+ } else {
5401+ sbus_writeb(RES_H_IUS, &info->zs_next->zs_channel->control);
5402+ ZSDELAY();
5403+ ZS_WSYNC(info->zs_next->zs_channel);
5404+ ZSLOG(REGCTRL, RES_H_IUS, 1);
5405+ }
5406+#endif
5407+
5408 /* Channel A -- /dev/ttya or /dev/kbd, could be the console */
5409 if (r3 & (CHAEXT | CHATxIP | CHARxIP)) {
5410 sbus_writeb(RES_H_IUS, &info->zs_channel->control);
5411@@ -1964,6 +2009,88 @@
5412
5413 /* Finally, routines used to initialize the serial driver. */
5414
5415+
5416+#ifdef CONFIG_SUN3X_ZS
5417+
5418+static void show_serial_version(void)
5419+{
5420+ char *revision = "$Revision: 1.5 $";
5421+ char *version, *p;
5422+
5423+ version = strchr(revision, ' ');
5424+ p = strchr(++version, ' ');
5425+ *p = '\0';
5426+ printk("sun3/3x Zilog8530 serial driver version %s\n", version);
5427+ *p = ' ';
5428+}
5429+
5430+static struct sun_zslayout * __init
5431+ get_zs(int chip)
5432+{
5433+ unsigned int vaddr = 0;
5434+ unsigned long iopte;
5435+ static int irq = 0;
5436+
5437+ if(chip < 0 || chip >= NUM_SERIAL)
5438+ panic("get_zs bogon zs chip number");
5439+
5440+#ifndef CONFIG_SUN3X
5441+ /* sun3 OBIO version */
5442+ /* Grrr, these have to be hardcoded aieee */
5443+ switch(chip) {
5444+ case 0:
5445+ for(vaddr = 0xfe00000; vaddr < (0xfe00000 +
5446+ SUN3_PMEG_SIZE); vaddr += SUN3_PTE_SIZE) {
5447+
5448+ iopte = sun3_get_pte(vaddr);
5449+ if(!(iopte & SUN3_PAGE_TYPE_IO)) /* this an io page? */
5450+ continue;
5451+
5452+ if(((iopte & SUN3_PAGE_PGNUM_MASK) << PAGE_SHIFT) ==
5453+ 0x20000) {
5454+ break;
5455+ }
5456+ }
5457+ break;
5458+ case 1:
5459+ for(vaddr = 0xfe00000; vaddr < (0xfe00000 +
5460+ SUN3_PMEG_SIZE); vaddr += SUN3_PTE_SIZE) {
5461+
5462+ iopte = sun3_get_pte(vaddr);
5463+ if(!(iopte & SUN3_PAGE_TYPE_IO)) /* this an io page? */
5464+ continue;
5465+
5466+ if(((iopte & SUN3_PAGE_PGNUM_MASK) << PAGE_SHIFT) ==
5467+ 0) {
5468+ break;
5469+ }
5470+ }
5471+ break;
5472+ };
5473+#else
5474+ /* sun3x is a wee bit cleaner. :) */
5475+ switch(chip) {
5476+ case 0:
5477+ vaddr = SUN3X_ZS2;
5478+ break;
5479+
5480+ case 1:
5481+ vaddr = SUN3X_ZS1;
5482+ break;
5483+ }
5484+#endif
5485+
5486+ zs_nodes[chip] = 0;
5487+ zilog_irq = irq = 6;
5488+
5489+ if(!vaddr)
5490+ panic("get_zs whee no serial chip mappable");
5491+
5492+ return (struct sun_zslayout *)(unsigned long) vaddr;
5493+}
5494+
5495+#else /* !CONFIG_SUN3X_ZS */
5496+
5497 static void show_serial_version(void)
5498 {
5499 char *revision = "$Revision: 1.68.2.2 $";
5500@@ -2224,6 +2351,9 @@
5501 return (struct sun_zslayout *)(unsigned long) vaddr[0];
5502 }
5503 #endif
5504+
5505+#endif /* !CONFIG_SUN3X_ZS */
5506+
5507 /* This is for the auto baud rate detection in the mouse driver. */
5508 void zs_change_mouse_baud(int newbaud)
5509 {
5510@@ -2292,6 +2422,8 @@
5511
5512 int __init zs_probe(void)
5513 {
5514+#ifndef CONFIG_SUN3X_ZS
5515+
5516 int node;
5517
5518 if(sparc_cpu_model == sun4)
5519@@ -2344,6 +2476,8 @@
5520 NUM_SERIAL = 2;
5521
5522 no_probe:
5523+#endif /* !CONFIG_SUN3X_ZS */
5524+
5525 zs_alloc_tables();
5526
5527 /* Fill in rs_ops struct... */
5528@@ -2501,6 +2635,7 @@
5529 /* Initialize Softinfo */
5530 zs_prepare();
5531
5532+#ifndef CONFIG_SUN3X_ZS
5533 /* Grab IRQ line before poking the chips so we do
5534 * not lose any interrupts.
5535 */
5536@@ -2509,6 +2644,7 @@
5537 prom_printf("Unable to attach zs intr\n");
5538 prom_halt();
5539 }
5540+#endif /* !CONFIG_SUN3X_ZS */
5541
5542 /* Initialize Hardware */
5543 for(channel = 0; channel < NUM_CHANNELS; channel++) {
5544@@ -2517,6 +2653,10 @@
5545 write_zsreg(zs_soft[channel].zs_channel, R9, FHWRES);
5546 ZSDELAY_LONG();
5547 dummy = read_zsreg(zs_soft[channel].zs_channel, R0);
5548+#ifdef CONFIG_SUN3
5549+ /* program the int vector */
5550+ write_zsreg(zs_soft[channel].zs_channel, R2, 0x18+zilog_irq);
5551+#endif
5552 }
5553
5554 if(channel == KEYBOARD_LINE) {
5555@@ -2676,11 +2816,23 @@
5556 info->normal_termios = serial_driver.init_termios;
5557 init_waitqueue_head(&info->open_wait);
5558 init_waitqueue_head(&info->close_wait);
5559+#ifdef CONFIG_SUN3X_ZS
5560+ printk("tty%02d at 0x%04x (irq = %d)", info->line,
5561+ info->port, info->irq);
5562+#else /* !CONFIG_SUN3X_ZS */
5563 printk("tty%02d at 0x%04x (irq = %s)", info->line,
5564 info->port, __irq_itoa(info->irq));
5565+#endif /* !CONFIG_SUN3X_ZS */
5566 printk(" is a Zilog8530\n");
5567 }
5568
5569+#ifdef CONFIG_SUN3X_ZS
5570+ if (request_irq(zilog_irq, zs_interrupt,
5571+ (SA_INTERRUPT),
5572+ "Zilog8530", zs_chain))
5573+ panic("Unable to attach zs intr\n");
5574+#endif /* CONFIG_SUN3X_ZS */
5575+
5576 restore_flags(flags);
5577
5578 keyboard_zsinit(kbd_put_char);
5579@@ -2881,10 +3033,15 @@
5580 {
5581 extern int con_is_present(void);
5582
5583+#ifndef CONFIG_SUN3X_ZS
5584 if (con_is_present())
5585 return 0;
5586
5587 zs_console.index = serial_console - 1;
5588+#else /* CONFIG_SUN3X_ZS */
5589+ zs_console.index = 0;
5590+#endif /* CONFIG_SUN3X_ZS */
5591+
5592 register_console(&zs_console);
5593 return 0;
5594 }
5595diff -Naur linux-2.4.26/drivers/scsi/NCR53C9x.c linux-2.4.26-m68k/drivers/scsi/NCR53C9x.c
5596--- linux-2.4.26/drivers/scsi/NCR53C9x.c 2002-11-29 10:53:14.000000000 +1100
5597+++ linux-2.4.26-m68k/drivers/scsi/NCR53C9x.c 2003-06-14 21:46:22.000000000 +1000
5598@@ -917,7 +917,7 @@
5599 if (esp->dma_mmu_get_scsi_one)
5600 esp->dma_mmu_get_scsi_one(esp, sp);
5601 else
5602- sp->SCp.have_data_in = (int) sp->SCp.ptr =
5603+ sp->SCp.ptr =
5604 (char *) virt_to_phys(sp->request_buffer);
5605 } else {
5606 sp->SCp.buffer = (struct scatterlist *) sp->buffer;
5607diff -Naur linux-2.4.26/drivers/scsi/oktagon_esp.c linux-2.4.26-m68k/drivers/scsi/oktagon_esp.c
5608--- linux-2.4.26/drivers/scsi/oktagon_esp.c 2002-08-03 10:39:44.000000000 +1000
5609+++ linux-2.4.26-m68k/drivers/scsi/oktagon_esp.c 2003-06-14 21:46:22.000000000 +1000
5610@@ -548,7 +548,7 @@
5611
5612 void dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd *sp)
5613 {
5614- sp->SCp.have_data_in = (int) sp->SCp.ptr =
5615+ sp->SCp.ptr =
5616 sp->request_buffer;
5617 }
5618
5619diff -Naur linux-2.4.26/drivers/video/Config.in linux-2.4.26-m68k/drivers/video/Config.in
5620--- linux-2.4.26/drivers/video/Config.in 2004-02-19 00:36:31.000000000 +1100
5621+++ linux-2.4.26-m68k/drivers/video/Config.in 2004-02-19 09:17:54.000000000 +1100
5622@@ -43,6 +43,9 @@
5623 if [ "$CONFIG_Q40" = "y" ]; then
5624 define_bool CONFIG_FB_Q40 y
5625 fi
5626+ if [ "$CONFIG_TEKXP" = "y" ]; then
5627+ define_bool CONFIG_FB_TEKXP y
5628+ fi
5629 if [ "$CONFIG_AMIGA" = "y" ]; then
5630 tristate ' Amiga native chipset support' CONFIG_FB_AMIGA
5631 if [ "$CONFIG_FB_AMIGA" != "n" ]; then
5632@@ -107,6 +110,7 @@
5633 bool ' Sun3 framebuffer support' CONFIG_FB_SUN3
5634 if [ "$CONFIG_FB_SUN3" != "n" ]; then
5635 bool ' BWtwo support' CONFIG_FB_BWTWO
5636+ bool ' CGthree support' CONFIG_FB_CGTHREE
5637 bool ' CGsix (GX,TurboGX) support' CONFIG_FB_CGSIX
5638 fi
5639 fi
5640@@ -265,7 +269,7 @@
5641 "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_RETINAZ3" = "y" -o \
5642 "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
5643 "$CONFIG_FB_BWTWO" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
5644- "$CONFIG_FB_TX3912" = "y" ]; then
5645+ "$CONFIG_FB_TX3912" = "y" -o "$CONFIG_FB_TEKXP" = "y" ]; then
5646 define_tristate CONFIG_FBCON_MFB y
5647 else
5648 if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_AMIGA" = "m" -o \
5649@@ -281,12 +285,21 @@
5650 "$CONFIG_FB_SA1100" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
5651 "$CONFIG_FB_TX3912" = "y" ]; then
5652 define_tristate CONFIG_FBCON_CFB2 y
5653- define_tristate CONFIG_FBCON_CFB4 y
5654 else
5655- if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_MAC" = "m" -o \
5656+ if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_MAC" = "m" -o \
5657 "$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
5658 "$CONFIG_FB_TX3912" = "m" ]; then
5659 define_tristate CONFIG_FBCON_CFB2 m
5660+ fi
5661+ fi
5662+ if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
5663+ "$CONFIG_FB_SA1100" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
5664+ "$CONFIG_FB_TX3912" = "y" -o "$CONFIG_FB_TEKXP" = "y" ]; then
5665+ define_tristate CONFIG_FBCON_CFB4 y
5666+ else
5667+ if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_MAC" = "m" -o \
5668+ "$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
5669+ "$CONFIG_FB_TX3912" = "m" ]; then
5670 define_tristate CONFIG_FBCON_CFB4 m
5671 fi
5672 fi
5673@@ -312,7 +325,7 @@
5674 "$CONFIG_FB_TX3912" = "y" -o \
5675 "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_NEOMAGIC" = "y" -o \
5676 "$CONFIG_FB_STI" = "y" -o "$CONFIG_FB_HP300" = "y" -o \
5677- "$CONFIG_FB_INTEL" = "y" ]; then
5678+ "$CONFIG_FB_INTEL" = "y" -o "$CONFIG_FB_TEKXP" = "y" ]; then
5679 define_tristate CONFIG_FBCON_CFB8 y
5680 else
5681 if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \
5682diff -Naur linux-2.4.26/drivers/video/Makefile linux-2.4.26-m68k/drivers/video/Makefile
5683--- linux-2.4.26/drivers/video/Makefile 2004-02-19 00:36:31.000000000 +1100
5684+++ linux-2.4.26-m68k/drivers/video/Makefile 2004-02-19 09:17:54.000000000 +1100
5685@@ -73,14 +73,22 @@
5686 obj-$(CONFIG_FB_VIRGE) += virgefb.o
5687 obj-$(CONFIG_FB_G364) += g364fb.o
5688 obj-$(CONFIG_FB_FM2) += fm2fb.o
5689-obj-$(CONFIG_FB_CREATOR) += creatorfb.o sbusfb.o
5690-obj-$(CONFIG_FB_CGSIX) += cgsixfb.o sbusfb.o
5691-obj-$(CONFIG_FB_BWTWO) += bwtwofb.o sbusfb.o
5692-obj-$(CONFIG_FB_CGTHREE) += cgthreefb.o sbusfb.o
5693-obj-$(CONFIG_FB_TCX) += tcxfb.o sbusfb.o
5694-obj-$(CONFIG_FB_CGFOURTEEN) += cgfourteenfb.o sbusfb.o
5695-obj-$(CONFIG_FB_P9100) += p9100fb.o sbusfb.o
5696-obj-$(CONFIG_FB_LEO) += leofb.o sbusfb.o
5697+
5698+SBUSFB =
5699+ifneq ($(CONFIG_SUN3),y)
5700+ifneq ($(CONFIG_SUN3X),y)
5701+ SBUSFB = sbusfb.o
5702+endif
5703+endif
5704+
5705+obj-$(CONFIG_FB_CREATOR) += creatorfb.o $(SBUSFB)
5706+obj-$(CONFIG_FB_CGSIX) += cgsixfb.o $(SBUSFB)
5707+obj-$(CONFIG_FB_BWTWO) += bwtwofb.o $(SBUSFB)
5708+obj-$(CONFIG_FB_CGTHREE) += cgthreefb.o $(SBUSFB)
5709+obj-$(CONFIG_FB_TCX) += tcxfb.o $(SBUSFB)
5710+obj-$(CONFIG_FB_CGFOURTEEN) += cgfourteenfb.o $(SBUSFB)
5711+obj-$(CONFIG_FB_P9100) += p9100fb.o $(SBUSFB)
5712+obj-$(CONFIG_FB_LEO) += leofb.o $(SBUSFB)
5713 obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o
5714 obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o
5715 obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o
5716@@ -125,7 +133,6 @@
5717 endif
5718
5719 obj-$(CONFIG_FB_SUN3) += sun3fb.o
5720-obj-$(CONFIG_FB_BWTWO) += bwtwofb.o
5721 obj-$(CONFIG_FB_HGA) += hgafb.o
5722 obj-$(CONFIG_FB_SA1100) += sa1100fb.o
5723 obj-$(CONFIG_FB_VIRTUAL) += vfb.o
5724@@ -134,6 +141,7 @@
5725 obj-$(CONFIG_FB_E1356) += epson1356fb.o
5726 obj-$(CONFIG_FB_PVR2) += pvr2fb.o
5727 obj-$(CONFIG_FB_VOODOO1) += sstfb.o
5728+obj-$(CONFIG_FB_TEKXP) += tek_fb.o
5729
5730 # Generic Low Level Drivers
5731
5732diff -Naur linux-2.4.26/drivers/video/cgthreefb.c linux-2.4.26-m68k/drivers/video/cgthreefb.c
5733--- linux-2.4.26/drivers/video/cgthreefb.c 2001-09-21 07:11:58.000000000 +1000
5734+++ linux-2.4.26-m68k/drivers/video/cgthreefb.c 2001-10-22 19:34:33.000000000 +1000
5735@@ -178,13 +178,16 @@
5736 struct display *disp = &fb->disp;
5737 struct fbtype *type = &fb->type;
5738 struct sbus_dev *sdev = fb->sbdp;
5739+#ifndef CONFIG_SUN3
5740 unsigned long phys = sdev->reg_addrs[0].phys_addr;
5741 int cgRDI = strstr(fb->sbdp->prom_name, "cgRDI") != NULL;
5742+#endif
5743
5744 #ifndef FBCON_HAS_CFB8
5745 return NULL;
5746 #endif
5747
5748+#ifndef CONFIG_SUN3
5749 if (!fb->s.cg3.regs) {
5750 fb->s.cg3.regs = (struct cg3_regs *)
5751 sbus_ioremap(&sdev->resource[0], CG3_REGS_OFFSET,
5752@@ -211,6 +214,9 @@
5753 }
5754 }
5755 }
5756+#else
5757+ fb->s.cg3.regs = (struct cg3_regs *)0x0fe0e000;
5758+#endif
5759
5760 strcpy(fb->info.modename, "CGthree");
5761 strcpy(fix->id, "CGthree");
5762@@ -218,12 +224,19 @@
5763 fix->accel = FB_ACCEL_SUN_CGTHREE;
5764
5765 disp->scrollmode = SCROLL_YREDRAW;
5766+#ifndef CONFIG_SUN3
5767 if (!disp->screen_base) {
5768 disp->screen_base = (char *)
5769 sbus_ioremap(&sdev->resource[0], CG3_RAM_OFFSET,
5770 type->fb_size, "cg3 ram");
5771 }
5772- disp->screen_base += fix->line_length * fb->y_margin + fb->x_margin;
5773+ fb->physbase = phys;
5774+#else
5775+ disp->screen_base = (char *)0x0fd00000;
5776+ fb->physbase = (unsigned long)0x0fd00000;
5777+#endif
5778+
5779+// disp->screen_base += fix->line_length * fb->y_margin + fb->x_margin;
5780 fb->dispsw = fbcon_cfb8;
5781
5782 fb->margins = cg3_margins;
5783@@ -231,9 +244,9 @@
5784 fb->blank = cg3_blank;
5785 fb->unblank = cg3_unblank;
5786
5787- fb->physbase = phys;
5788 fb->mmap_map = cg3_mmap_map;
5789-
5790+
5791+#ifndef CONFIG_SUN3
5792 #ifdef __sparc_v9__
5793 sprintf(idstring, "%s at %016lx", cgRDI ? "cgRDI" : "cgthree", phys);
5794 #else
5795@@ -279,6 +292,22 @@
5796 sbus_writeb(p[1], regp);
5797 }
5798 }
5799+#else
5800+ sprintf(idstring, "%s: mem %x regs %x", "cgthree", fb->physbase, fb->s.cg3.regs);
5801+
5802+ /* kick up the sun3 -- 66hz prom mode only */
5803+ /* this also turns off the overlay in case it's really a cg4 */
5804+
5805+ fb->s.cg3.regs->cmap.addr = 4;
5806+ fb->s.cg3.regs->cmap.control = 0xff;
5807+ fb->s.cg3.regs->cmap.addr = 5;
5808+ fb->s.cg3.regs->cmap.control = 0;
5809+ fb->s.cg3.regs->cmap.addr = 6;
5810+ fb->s.cg3.regs->cmap.control = 0x40;
5811+ fb->s.cg3.regs->cmap.addr = 7;
5812+ fb->s.cg3.regs->cmap.control = 0;
5813+
5814+#endif
5815
5816 return idstring;
5817 }
5818diff -Naur linux-2.4.26/drivers/video/fbcon.c linux-2.4.26-m68k/drivers/video/fbcon.c
5819--- linux-2.4.26/drivers/video/fbcon.c 2003-08-25 21:44:42.000000000 +1000
5820+++ linux-2.4.26-m68k/drivers/video/fbcon.c 2003-08-26 13:13:09.000000000 +1000
5821@@ -2340,6 +2340,27 @@
5822 done = 1;
5823 }
5824 #endif
5825+#ifdef CONFIG_HP300
5826+ if (depth == 6 && p->type == FB_TYPE_PACKED_PIXELS) {
5827+ /* depth 6 or more, packed, with color registers */
5828+
5829+ src = logo;
5830+ for( y1 = 0; y1 < LOGO_H; y1++ ) {
5831+ int c;
5832+ dst = fb + y1*line;
5833+ for( x1 = 0; x1 < LOGO_W / 2; x1++ ) {
5834+ fb_writeb((*src >> 4) + 16, dst++);
5835+ fb_writeb(((*src++) & 0xf) + 16, dst++);
5836+ }
5837+ dst += 8;
5838+ for (c = 0; c < 32; c++)
5839+ for (x1 = 0; x1 < 24; x1++)
5840+ *dst++ = c;
5841+ }
5842+
5843+ done = 1;
5844+ }
5845+#endif /* CONFIG_HP300 */
5846 #if defined(CONFIG_FBCON_AFB) || defined(CONFIG_FBCON_ILBM) || \
5847 defined(CONFIG_FBCON_IPLAN2P2) || defined(CONFIG_FBCON_IPLAN2P4) || \
5848 defined(CONFIG_FBCON_IPLAN2P8)
5849@@ -2412,8 +2433,22 @@
5850 dst = fb + (y1%4)*8192 + (y1>>2)*line + x/8;
5851 else
5852 dst = fb + y1*line + x/8;
5853- for( x1 = 0; x1 < LOGO_LINE; ++x1 )
5854+ for( x1 = 0; x1 < LOGO_LINE; ++x1 ) {
5855+#ifndef CONFIG_HP300
5856 fb_writeb(*src++ ^ inverse, dst++);
5857+#else /* CONFIG_HP300 */
5858+ /* hack hack -- make it work with topcat in pseudomono mode */
5859+ char c = *src++ ^ inverse;
5860+ fb_writeb((c >> 7) & 1, dst++);
5861+ fb_writeb((c >> 6) & 1, dst++);
5862+ fb_writeb((c >> 5) & 1, dst++);
5863+ fb_writeb((c >> 4) & 1, dst++);
5864+ fb_writeb((c >> 3) & 1, dst++);
5865+ fb_writeb((c >> 2) & 1, dst++);
5866+ fb_writeb((c >> 1) & 1, dst++);
5867+ fb_writeb((c >> 0) & 1, dst++);
5868+#endif /* CONFIG_HP300 */
5869+ }
5870 }
5871 done = 1;
5872 }
5873diff -Naur linux-2.4.26/drivers/video/fbmem.c linux-2.4.26-m68k/drivers/video/fbmem.c
5874--- linux-2.4.26/drivers/video/fbmem.c 2004-02-19 00:36:31.000000000 +1100
5875+++ linux-2.4.26-m68k/drivers/video/fbmem.c 2004-02-19 09:17:54.000000000 +1100
5876@@ -53,6 +53,7 @@
5877 extern int amifb_setup(char*);
5878 extern int atafb_init(void);
5879 extern int atafb_setup(char*);
5880+extern int tekfb_init(void);
5881 extern int macfb_init(void);
5882 extern int macfb_setup(char*);
5883 extern int cyberfb_init(void);
5884@@ -271,6 +272,9 @@
5885 #ifdef CONFIG_FB_ATARI
5886 { "atafb", atafb_init, atafb_setup },
5887 #endif
5888+#ifdef CONFIG_FB_TEKXP
5889+ { "tekfb", tekfb_init, NULL },
5890+#endif
5891 #ifdef CONFIG_FB_MAC
5892 { "macfb", macfb_init, macfb_setup },
5893 #endif
5894@@ -964,9 +968,9 @@
5895 fb_drivers[i].init;
5896 fb_drivers[i].init = NULL;
5897 }
5898- if (fb_drivers[i].setup)
5899- fb_drivers[i].setup(options+j+1);
5900 }
5901+ if (fb_drivers[i].setup)
5902+ fb_drivers[i].setup(options+j+1);
5903 return 0;
5904 }
5905 }
5906diff -Naur linux-2.4.26/drivers/video/sun3fb.c linux-2.4.26-m68k/drivers/video/sun3fb.c
5907--- linux-2.4.26/drivers/video/sun3fb.c 2001-10-01 05:26:08.000000000 +1000
5908+++ linux-2.4.26-m68k/drivers/video/sun3fb.c 2003-06-14 21:44:17.000000000 +1000
5909@@ -48,6 +48,8 @@
5910
5911 #ifdef CONFIG_SUN3
5912 #include <asm/oplib.h>
5913+#include <asm/machines.h>
5914+#include <asm/idprom.h>
5915 #endif
5916 #ifdef CONFIG_SUN3X
5917 #include <asm/sun3x.h>
5918@@ -59,12 +61,14 @@
5919 #define CURSOR_SHAPE 1
5920 #define CURSOR_BLINK 2
5921
5922+#define mymemset(x,y) memset(x,0,y)
5923+
5924 /*
5925 * Interface used by the world
5926 */
5927
5928 int sun3fb_init(void);
5929-int sun3fb_setup(char *options);
5930+void sun3fb_setup(char *options);
5931
5932 static int currcon;
5933 static char fontname[40] __initdata = { 0 };
5934@@ -115,6 +119,8 @@
5935 static void sun3fb_clear_margin(struct display *p, int s)
5936 {
5937 struct fb_info_sbusfb *fb = sbusfbinfod(p);
5938+
5939+ return;
5940
5941 if (fb->switch_from_graph)
5942 (*fb->switch_from_graph)(fb);
5943@@ -354,7 +360,7 @@
5944 p++;
5945 }
5946
5947- return 0;
5948+ return;
5949 }
5950
5951 static int sun3fbcon_switch(int con, struct fb_info *info)
5952@@ -523,7 +529,7 @@
5953 */
5954 static int __init sun3fb_init_fb(int fbtype, unsigned long addr)
5955 {
5956- static struct linux_sbus_device sdb;
5957+ static struct sbus_dev sdb;
5958 struct fb_fix_screeninfo *fix;
5959 struct fb_var_screeninfo *var;
5960 struct display *disp;
5961@@ -531,7 +537,7 @@
5962 struct fbtype *type;
5963 int linebytes, w, h, depth;
5964 char *p = NULL;
5965-
5966+
5967 fb = kmalloc(sizeof(struct fb_info_sbusfb), GFP_ATOMIC);
5968 if (!fb)
5969 return -ENOMEM;
5970@@ -600,8 +606,13 @@
5971 case FBTYPE_SUN2BW:
5972 p = bwtwofb_init(fb); break;
5973 #endif
5974+#ifdef CONFIG_FB_CGTHREE
5975+ case FBTYPE_SUN4COLOR:
5976+ case FBTYPE_SUN3COLOR:
5977+ p = cgthreefb_init(fb); break;
5978+#endif
5979 }
5980- fix->smem_start = fb->disp.screen_base;
5981+ fix->smem_start = (unsigned long)fb->disp.screen_base;
5982
5983 if (!p) {
5984 kfree(fb);
5985@@ -656,17 +667,25 @@
5986 unsigned long addr;
5987 char p4id;
5988
5989- if (!con_is_present()) return;
5990- printk("sun3fb_init()\n");
5991+ if (!con_is_present()) return -ENXIO;
5992 #ifdef CONFIG_SUN3
5993- addr = 0xfe20000;
5994 switch(*(romvec->pv_fbtype))
5995 {
5996- case FBTYPE_SUN2BW:
5997- return sun3fb_init_fb(FBTYPE_SUN2BW, addr);
5998- case FBTYPE_SUN3COLOR:
5999- printk("cg3 detected but not supported\n");
6000- return -EINVAL;
6001+ case FBTYPE_SUN2BW:
6002+ addr = 0xfe20000;
6003+ return sun3fb_init_fb(FBTYPE_SUN2BW, addr);
6004+ case FBTYPE_SUN3COLOR:
6005+ case FBTYPE_SUN4COLOR:
6006+ if(idprom->id_machtype != (SM_SUN3|SM_3_60)) {
6007+ printk("sun3fb: cgthree/four only supported on 3/60\n");
6008+ return -ENODEV;
6009+ }
6010+
6011+ addr = 0xfd00000;
6012+ return sun3fb_init_fb(*(romvec->pv_fbtype), addr);
6013+ default:
6014+ printk("sun3fb: unsupported framebuffer\n");
6015+ return -ENODEV;
6016 }
6017 #else
6018 addr = SUN3X_VIDEO_BASE;
6019diff -Naur linux-2.4.26/drivers/video/tek_fb.c linux-2.4.26-m68k/drivers/video/tek_fb.c
6020--- linux-2.4.26/drivers/video/tek_fb.c 1970-01-01 10:00:00.000000000 +1000
6021+++ linux-2.4.26-m68k/drivers/video/tek_fb.c 2003-07-22 07:31:52.000000000 +1000
6022@@ -0,0 +1,442 @@
6023+/*
6024+ * linux/drivers/video/tek_fb.c
6025+ *
6026+ * Copyright (C) 2002,2003 Michael Mueller <malware@t-online.de>
6027+ *
6028+ * This file is subject to the terms and conditions of the GNU General Public
6029+ * License. See the file COPYING in the main directory of this archive
6030+ * for more details.
6031+ *
6032+ *
6033+ * It is basicly a hack to get the console working. So if someone feels
6034+ * familiar with the framebuffer API a rework would be welcome.
6035+ */
6036+
6037+#include <linux/config.h>
6038+#include <linux/kernel.h>
6039+#include <linux/sched.h>
6040+#include <linux/errno.h>
6041+#include <linux/string.h>
6042+#include <linux/mm.h>
6043+#include <linux/tty.h>
6044+#include <linux/slab.h>
6045+#include <linux/init.h>
6046+
6047+#include <linux/fb.h>
6048+
6049+#include <video/fbcon.h>
6050+#ifdef CONFIG_FBCON_CFB8
6051+#include <video/fbcon-cfb8.h>
6052+#endif
6053+#ifdef CONFIG_FBCON_CFB4
6054+#include <video/fbcon-cfb4.h>
6055+#endif
6056+#ifdef CONFIG_FBCON_MFB
6057+#include <video/fbcon-mfb.h>
6058+#endif
6059+
6060+#include <asm/setup.h>
6061+#include <asm/uaccess.h>
6062+#include <asm/pgtable.h>
6063+#include <asm/irq.h>
6064+
6065+#include <asm/teknvram.h>
6066+
6067+#define MAX_TEKFB_SIZE (1280*1024+0x100)
6068+#define TEKFP_BASE (0xDE000000UL)
6069+
6070+struct tekfb_priv {
6071+ u_char* frameptr;
6072+ int display_type;
6073+ int display_height;
6074+ int display_width;
6075+ int display_coldepth;
6076+ int display_fps;
6077+
6078+ u_char * ptr;
6079+ u_char * ptr_ramdac;
6080+ int ramdac_type;
6081+ u_char * ramdac_regs[5];
6082+};
6083+
6084+#define arraysize(x) (sizeof (x)/sizeof (x)[0])
6085+
6086+ /*
6087+ * Interface used by the world
6088+ */
6089+
6090+void tekxp_video_setup(char *options, int *ints)
6091+{
6092+ // There is nothing we can do currently
6093+}
6094+
6095+ /*
6096+ * Interface to the low level console driver
6097+ */
6098+
6099+static struct fb_info fb_info;
6100+//static int tekfb_switch(int con, struct fb_info *);
6101+static int tekfb_update_var(int con, struct fb_info *);
6102+static void tekfb_blank(int, struct fb_info *);
6103+
6104+static int tekfb_get_fix(struct fb_fix_screeninfo *, int, struct fb_info *);
6105+static int tekfb_get_var(struct fb_var_screeninfo *, int, struct fb_info *);
6106+static int tekfb_set_var(struct fb_var_screeninfo *, int, struct fb_info *);
6107+static int tekfb_get_cmap(struct fb_cmap *, int, int, struct fb_info *);
6108+static int tekfb_set_cmap(struct fb_cmap *, int, int, struct fb_info *);
6109+
6110+static struct fb_ops tekfb_ops = {
6111+ fb_get_fix: tekfb_get_fix,
6112+ fb_get_var: tekfb_get_var,
6113+ fb_set_var: tekfb_set_var,
6114+ fb_get_cmap: tekfb_get_cmap,
6115+ fb_set_cmap: tekfb_set_cmap,
6116+};
6117+
6118+static struct display disp;
6119+
6120+//static struct fb_var_screeninfo tekfb_predefined;
6121+
6122+struct fb_var_screeninfo tekfb_fixed =
6123+{
6124+ xres: 1152, yres: 900, /* visible resolution */
6125+ xres_virtual: 1152, yres_virtual: 900, /* virtual resolution */
6126+ xoffset: 0, yoffset: 0, /* offset of visible within virtual */
6127+ bits_per_pixel: 8, /* bits per pixel */
6128+ grayscale: 0, /* grayscale */
6129+ red: {0, 6, 0}, /* red */
6130+ green: {0, 6, 0}, /* green */
6131+ blue: {0, 6, 0}, /* blue */
6132+ transp: {0, 0, 0}, /* transp */
6133+ nonstd: 0, /* no non-standard pixel format */
6134+ activate: 0, /* activate */
6135+ height: -1, /* height in mm */
6136+ width: -1, /* width in mm */
6137+ accel_flags: FB_ACCEL_NONE, /* accel */
6138+};
6139+
6140+static const char* ramdac_names[4] = { "???", "???", "Bt459", "???" };
6141+
6142+static int get_private(struct tekfb_priv *priv)
6143+{
6144+ priv->ptr = ioremap_writethrough(0xD8200000, 0x100);
6145+ priv->ptr_ramdac = ioremap_writethrough(0xD8100000, 0x100);
6146+ if ( !priv->ptr || !priv->ptr_ramdac )
6147+ {
6148+ printk("tek_fb: Could not map ramdac into kernel memory space\n");
6149+ return -ENOMEM;
6150+ }
6151+
6152+ /*
6153+ * Maybe sometime I will understand how a bit field is organized.
6154+ * Meanwhile this assembler stuff will do the trick.
6155+ */
6156+ __asm__("bfextu %1{#6:#2}, %0\n"
6157+ : "=r" (priv->ramdac_type)
6158+ : "m" (*(priv->ptr + 1)) );
6159+ printk("tek_fb: RAMDAC: %d (%s)\n",
6160+ priv->ramdac_type, ramdac_names[priv->ramdac_type]);
6161+
6162+ if ( priv->ramdac_type & 1 )
6163+ {
6164+ priv->ramdac_regs[0] = priv->ptr_ramdac + 0;
6165+ priv->ramdac_regs[1] = priv->ptr_ramdac + 4;
6166+ priv->ramdac_regs[2] = priv->ptr_ramdac + 8;
6167+ priv->ramdac_regs[3] = priv->ptr_ramdac + 12;
6168+ priv->ramdac_regs[4] = NULL;
6169+ }
6170+ else
6171+ {
6172+ priv->ramdac_regs[0] = priv->ptr_ramdac + 0;
6173+ priv->ramdac_regs[1] = NULL;
6174+ priv->ramdac_regs[2] = priv->ptr_ramdac + 8;
6175+ priv->ramdac_regs[3] = priv->ptr_ramdac + 4;
6176+ priv->ramdac_regs[4] = priv->ptr_ramdac + 12;
6177+ }
6178+
6179+ priv->display_type = nvram_readw(NVRAM_DISPLAY);
6180+ switch ( priv->display_type )
6181+ {
6182+ case 0:
6183+ priv->display_width = 1280;
6184+ priv->display_height = 1024;
6185+ priv->display_coldepth = 4;
6186+ priv->display_fps = 72;
6187+ break;
6188+ case 1:
6189+ priv->display_width = 1152;
6190+ priv->display_height = 900;
6191+ priv->display_coldepth = 8;
6192+ priv->display_fps = 60;
6193+ break;
6194+ case 3:
6195+ priv->display_width = 1280;
6196+ priv->display_height = 1024;
6197+ priv->display_coldepth = 8;
6198+ priv->display_fps = 72;
6199+ break;
6200+ case 4:
6201+ priv->display_width = 1024;
6202+ priv->display_height = 768;
6203+ priv->display_coldepth = 8;
6204+ priv->display_fps = 70;
6205+ break;
6206+ case 5:
6207+ priv->display_width = 1024;
6208+ priv->display_height = 768;
6209+ priv->display_coldepth = 8;
6210+ priv->display_fps = 60;
6211+ break;
6212+ case 6: // note: it is not really the same as above
6213+ priv->display_width = 1024;
6214+ priv->display_height = 768;
6215+ priv->display_coldepth = 8;
6216+ priv->display_fps = 60;
6217+ break;
6218+ case 7:
6219+ priv->display_width = 1152;
6220+ priv->display_height = 900;
6221+ priv->display_coldepth = 1;
6222+ priv->display_fps = 72;
6223+ break;
6224+ case 8:
6225+ priv->display_width = 1280;
6226+ priv->display_height = 1024;
6227+ priv->display_coldepth = 1;
6228+ priv->display_fps = 72;
6229+ break;
6230+ case 9:
6231+ priv->display_width = 1280;
6232+ priv->display_height = 864;
6233+ priv->display_coldepth = 8;
6234+ priv->display_fps = 60;
6235+ break;
6236+ default:
6237+ priv->display_width = 1152;
6238+ priv->display_height = 900;
6239+ priv->display_coldepth = 8;
6240+ priv->display_fps = 72;
6241+ }
6242+ printk("tek_fb: display type: %d (%dx%dx%d@%d)\n",
6243+ priv->display_type, priv->display_width,
6244+ priv->display_height, priv->display_coldepth,
6245+ priv->display_fps);
6246+
6247+ return 0;
6248+}
6249+
6250+static inline void set_ramdac_addr(struct tekfb_priv *priv, int addr)
6251+{
6252+ *(volatile int *)(priv->ramdac_regs[0]) = addr;
6253+ if ( priv->ramdac_type & 1 )
6254+ *(volatile int *)(priv->ramdac_regs[1]) = (addr >> 8) & 0xff;
6255+}
6256+
6257+static inline unsigned long get_fb_size(struct tekfb_priv *priv)
6258+{
6259+ return (priv->display_width * priv->display_height * priv->display_coldepth) / 8;
6260+}
6261+
6262+int __devinit tekfb_init(void)
6263+{
6264+ int err;
6265+ struct tekfb_priv *priv = kmalloc(sizeof (*priv), GFP_KERNEL);
6266+ if ( !priv )
6267+ {
6268+ printk(KERN_ERR "tek_fb: Could not allocate memory for private device data\n");
6269+ return -ENOMEM;
6270+ }
6271+ memset(priv, 0, sizeof (*priv));
6272+
6273+ priv->frameptr = (u_char*)ioremap_writethrough(TEKFP_BASE, MAX_TEKFB_SIZE);
6274+ if ( !priv->frameptr )
6275+ {
6276+ printk(KERN_ERR "tek_fb: Frame buffer did not map into kernel memory space\n");
6277+ return -ENOMEM;
6278+ }
6279+
6280+ err = get_private(priv);
6281+ if ( err < 0 )
6282+ return err;
6283+
6284+ strcpy(fb_info.modename, "TekXpress");
6285+ fb_info.changevar = NULL;
6286+ fb_info.node = -1;
6287+ fb_info.fbops = &tekfb_ops;
6288+ fb_info.disp = &disp;
6289+// fb_info.switch_con = tekfb_switch;
6290+ fb_info.switch_con = NULL;
6291+ fb_info.updatevar=tekfb_update_var;
6292+ fb_info.blank=&tekfb_blank;
6293+ fb_info.flags = FBINFO_FLAG_DEFAULT;
6294+ fb_info.fontname[0] = 0;
6295+ fb_info.par = priv;
6296+ if ( fb_alloc_cmap(&fb_info.cmap, 1 << 8, 0) < 0 )
6297+ {
6298+ printk("tek_fb: Could not allocate color map\n");
6299+ return -ENOMEM;
6300+ }
6301+
6302+ tekfb_get_var(&disp.var, 0, &fb_info);
6303+ disp.screen_base = priv->frameptr + 0x100;
6304+ disp.type = FB_TYPE_PACKED_PIXELS;
6305+ disp.line_length = 0;
6306+ disp.can_soft_blank = 0;
6307+ disp.inverse = 0;
6308+ disp.ypanstep = 0;
6309+ disp.ywrapstep = 0;
6310+ switch ( priv->display_coldepth )
6311+ {
6312+#ifdef CONFIG_FBCON_CFB8
6313+ case 8:
6314+ disp.visual = FB_VISUAL_PSEUDOCOLOR;
6315+ disp.dispsw = &fbcon_cfb8;
6316+ break;
6317+#endif
6318+#ifdef CONFIG_FBCON_CFB4
6319+ case 4:
6320+ disp.visual = FB_VISUAL_PSEUDOCOLOR;
6321+ disp.dispsw = &fbcon_cfb4;
6322+ break;
6323+#endif
6324+#ifdef CONFIG_FBCON_MFB
6325+ case 1:
6326+ disp.visual = FB_VISUAL_MONO10;
6327+ disp.dispsw = &fbcon_mfb;
6328+ break;
6329+#endif
6330+ default:
6331+ panic("tek_fb: unknown/unsupported color depth %d", priv->display_coldepth);
6332+ }
6333+
6334+ memset(priv->frameptr + 0x100, 0, get_fb_size(priv));
6335+
6336+ return register_framebuffer(&fb_info);
6337+}
6338+
6339+/*
6340+static int tekfb_switch(int con, struct fb_info *info)
6341+{
6342+ return 0;
6343+}
6344+*/
6345+
6346+static int tekfb_update_var(int con, struct fb_info *info)
6347+{
6348+ return 0;
6349+}
6350+
6351+static void tekfb_blank(int m, struct fb_info *info)
6352+{
6353+}
6354+
6355+static int tekfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
6356+{
6357+ int i;
6358+ struct tekfb_priv *priv = info->par;
6359+
6360+ strcpy(fix->id, "TekXpress");
6361+ fix->smem_start = (unsigned long)priv->frameptr + 0x100;
6362+ fix->smem_len = MAX_TEKFB_SIZE - 0x100;
6363+ fix->type = FB_TYPE_PACKED_PIXELS;
6364+ switch ( priv->display_coldepth )
6365+ {
6366+ case 8:
6367+ case 4:
6368+ fix->visual = FB_VISUAL_PSEUDOCOLOR;
6369+ break;
6370+ case 1:
6371+ fix->visual = FB_VISUAL_MONO10;
6372+ break;
6373+ default:
6374+ panic("tek_fb: unknown color depth");
6375+ }
6376+ fix->xpanstep = 0;
6377+ fix->ypanstep = 0;
6378+ fix->ywrapstep = 0;
6379+ fix->line_length = 0;
6380+ for (i=0; i<arraysize(fix->reserved); i++)
6381+ fix->reserved[i]=0;
6382+ return 0;
6383+
6384+}
6385+
6386+static int tekfb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
6387+{
6388+ struct tekfb_priv *priv = info->par;
6389+
6390+ *var = tekfb_fixed;
6391+
6392+ var->xres_virtual = var->xres = priv->display_width;
6393+ var->yres_virtual = var->yres = priv->display_height;
6394+ var->xoffset = var->yoffset = 0;
6395+ var->bits_per_pixel = priv->display_coldepth;
6396+
6397+ return 0;
6398+}
6399+
6400+static int tekfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
6401+{
6402+ return 0;
6403+}
6404+
6405+static int tekfb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
6406+{
6407+ struct tekfb_priv *priv = info->par;
6408+ int iCol;
6409+
6410+ set_ramdac_addr(priv, info->cmap.start);
6411+ for ( iCol=0; iCol < info->cmap.len; iCol++ )
6412+ {
6413+ unsigned long r,g,b;
6414+
6415+ r = *(volatile u_long *)(priv->ramdac_regs[3]);
6416+ if ( priv->ramdac_type )
6417+ {
6418+ g = *(volatile u_long *)(priv->ramdac_regs[3]);
6419+ b = *(volatile u_long *)(priv->ramdac_regs[3]);
6420+ }
6421+ else
6422+ b = g = r;
6423+
6424+ info->cmap.red[iCol] = r;
6425+ info->cmap.green[iCol] = g;
6426+ info->cmap.blue[iCol] = b;
6427+ }
6428+
6429+ fb_copy_cmap(&info->cmap, cmap, kspc ? 0 : 2);
6430+
6431+ return 0;
6432+}
6433+
6434+static int tekfb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
6435+{
6436+ struct tekfb_priv *priv = info->par;
6437+ if ( priv )
6438+ {
6439+ int iCol;
6440+
6441+ fb_copy_cmap(cmap, &info->cmap, kspc ? 0 : 1);
6442+
6443+ set_ramdac_addr(priv, info->cmap.start);
6444+ for ( iCol = 0; iCol < info->cmap.len; iCol++ )
6445+ {
6446+ int r = info->cmap.red[iCol];
6447+ int g = info->cmap.green[iCol];
6448+ int b = info->cmap.blue[iCol];
6449+
6450+ if ( !priv->ramdac_type )
6451+ r = g = b = (38 * r + 90 * g + 128 * b) / 256;
6452+
6453+ *(volatile u_long *)(priv->ramdac_regs[3]) = r;
6454+ if ( priv->ramdac_type )
6455+ {
6456+ *(volatile u_long *)(priv->ramdac_regs[3]) = g;
6457+ *(volatile u_long *)(priv->ramdac_regs[3]) = b;
6458+ }
6459+
6460+ }
6461+ }
6462+ return 0;
6463+}
6464+
6465diff -Naur linux-2.4.26/fs/Config.in linux-2.4.26-m68k/fs/Config.in
6466--- linux-2.4.26/fs/Config.in 2004-02-19 00:36:31.000000000 +1100
6467+++ linux-2.4.26-m68k/fs/Config.in 2004-02-19 09:18:00.000000000 +1100
6468@@ -19,6 +19,8 @@
6469
6470 dep_tristate 'Amiga FFS file system support (EXPERIMENTAL)' CONFIG_AFFS_FS $CONFIG_EXPERIMENTAL
6471
6472+dep_tristate 'Amiga SFS file system support (read-only) (EXPERIMENTAL)' CONFIG_ASFS_FS $CONFIG_EXPERIMENTAL
6473+
6474 dep_tristate 'Apple HFS file system support (EXPERIMENTAL)' CONFIG_HFS_FS $CONFIG_EXPERIMENTAL
6475
6476 dep_tristate 'Apple HFS+ (Extended HFS) file system support (EXPERIMENTAL)' CONFIG_HFSPLUS_FS $CONFIG_EXPERIMENTAL
6477diff -Naur linux-2.4.26/fs/Makefile linux-2.4.26-m68k/fs/Makefile
6478--- linux-2.4.26/fs/Makefile 2004-02-19 00:36:31.000000000 +1100
6479+++ linux-2.4.26-m68k/fs/Makefile 2004-02-19 09:18:00.000000000 +1100
6480@@ -55,6 +55,7 @@
6481 subdir-$(CONFIG_JFFS_FS) += jffs
6482 subdir-$(CONFIG_JFFS2_FS) += jffs2
6483 subdir-$(CONFIG_AFFS_FS) += affs
6484+subdir-$(CONFIG_ASFS_FS) += asfs
6485 subdir-$(CONFIG_ROMFS_FS) += romfs
6486 subdir-$(CONFIG_QNX4FS_FS) += qnx4
6487 subdir-$(CONFIG_UDF_FS) += udf
6488diff -Naur linux-2.4.26/fs/affs/amigaffs.c linux-2.4.26-m68k/fs/affs/amigaffs.c
6489--- linux-2.4.26/fs/affs/amigaffs.c 2001-09-12 01:19:35.000000000 +1000
6490+++ linux-2.4.26-m68k/fs/affs/amigaffs.c 2004-06-11 07:01:42.000000000 +1000
6491@@ -458,7 +458,6 @@
6492 if (!(sb->s_flags & MS_RDONLY))
6493 printk(KERN_WARNING "AFFS: Remounting filesystem read-only\n");
6494 sb->s_flags |= MS_RDONLY;
6495- AFFS_SB->s_flags |= SF_READONLY; /* Don't allow to remount rw */
6496 }
6497
6498 void
6499diff -Naur linux-2.4.26/fs/affs/bitmap.c linux-2.4.26-m68k/fs/affs/bitmap.c
6500--- linux-2.4.26/fs/affs/bitmap.c 2002-02-26 06:38:07.000000000 +1100
6501+++ linux-2.4.26-m68k/fs/affs/bitmap.c 2004-06-11 07:01:42.000000000 +1000
6502@@ -268,8 +268,7 @@
6503 return 0;
6504 }
6505
6506-int
6507-affs_init_bitmap(struct super_block *sb)
6508+int affs_init_bitmap(struct super_block *sb, int *flags)
6509 {
6510 struct affs_bm_info *bm;
6511 struct buffer_head *bmap_bh = NULL, *bh = NULL;
6512@@ -277,13 +276,13 @@
6513 u32 size, blk, end, offset, mask;
6514 int i, res = 0;
6515
6516- if (sb->s_flags & MS_RDONLY)
6517+ if (*flags & MS_RDONLY)
6518 return 0;
6519
6520 if (!AFFS_ROOT_TAIL(sb, AFFS_SB->s_root_bh)->bm_flag) {
6521 printk(KERN_NOTICE "AFFS: Bitmap invalid - mounting %s read only\n",
6522 kdevname(sb->s_dev));
6523- sb->s_flags |= MS_RDONLY;
6524+ *flags |= MS_RDONLY;
6525 return 0;
6526 }
6527
6528@@ -296,7 +295,7 @@
6529 bm = AFFS_SB->s_bitmap = kmalloc(size, GFP_KERNEL);
6530 if (!AFFS_SB->s_bitmap) {
6531 printk(KERN_ERR "AFFS: Bitmap allocation failed\n");
6532- return 1;
6533+ return -ENOMEM;
6534 }
6535 memset(AFFS_SB->s_bitmap, 0, size);
6536
6537@@ -311,13 +310,13 @@
6538 bh = affs_bread(sb, bm->bm_key);
6539 if (!bh) {
6540 printk(KERN_ERR "AFFS: Cannot read bitmap\n");
6541- res = 1;
6542+ res = -EIO;
6543 goto out;
6544 }
6545 if (affs_checksum_block(sb, bh)) {
6546 printk(KERN_WARNING "AFFS: Bitmap %u invalid - mounting %s read only.\n",
6547 bm->bm_key, kdevname(sb->s_dev));
6548- sb->s_flags |= MS_RDONLY;
6549+ *flags |= MS_RDONLY;
6550 goto out;
6551 }
6552 pr_debug("AFFS: read bitmap block %d: %d\n", blk, bm->bm_key);
6553@@ -333,7 +332,7 @@
6554 bmap_bh = affs_bread(sb, be32_to_cpu(bmap_blk[blk]));
6555 if (!bmap_bh) {
6556 printk(KERN_ERR "AFFS: Cannot read bitmap extension\n");
6557- res = 1;
6558+ res = -EIO;
6559 goto out;
6560 }
6561 bmap_blk = (u32 *)bmap_bh->b_data;
6562@@ -378,3 +377,15 @@
6563 affs_brelse(bmap_bh);
6564 return res;
6565 }
6566+
6567+void affs_free_bitmap(struct super_block *sb)
6568+{
6569+ if (!AFFS_SB->s_bitmap)
6570+ return;
6571+
6572+ affs_brelse(AFFS_SB->s_bmap_bh);
6573+ AFFS_SB->s_bmap_bh = NULL;
6574+ AFFS_SB->s_last_bmap = ~0;
6575+ kfree(AFFS_SB->s_bitmap);
6576+ AFFS_SB->s_bitmap = NULL;
6577+}
6578diff -Naur linux-2.4.26/fs/affs/super.c linux-2.4.26-m68k/fs/affs/super.c
6579--- linux-2.4.26/fs/affs/super.c 2002-02-26 06:38:07.000000000 +1100
6580+++ linux-2.4.26-m68k/fs/affs/super.c 2004-06-11 07:01:42.000000000 +1000
6581@@ -48,10 +48,9 @@
6582 mark_buffer_dirty(AFFS_SB->s_root_bh);
6583 }
6584
6585- affs_brelse(AFFS_SB->s_bmap_bh);
6586 if (AFFS_SB->s_prefix)
6587 kfree(AFFS_SB->s_prefix);
6588- kfree(AFFS_SB->s_bitmap);
6589+ affs_free_bitmap(sb);
6590 affs_brelse(AFFS_SB->s_root_bh);
6591
6592 return;
6593@@ -235,6 +234,7 @@
6594 gid_t gid;
6595 int reserved;
6596 unsigned long mount_flags;
6597+ int tmp_flags; /* fix remount prototype... */
6598
6599 pr_debug("AFFS: read_super(%s)\n",data ? (const char *)data : "no options");
6600
6601@@ -349,7 +349,6 @@
6602 printk(KERN_NOTICE "AFFS: Dircache FS - mounting %s read only\n",
6603 kdevname(dev));
6604 sb->s_flags |= MS_RDONLY;
6605- AFFS_SB->s_flags |= SF_READONLY;
6606 }
6607 switch (chksum) {
6608 case MUFS_FS:
6609@@ -405,8 +404,10 @@
6610 AFFS_SB->s_root_bh = root_bh;
6611 /* N.B. after this point s_root_bh must be released */
6612
6613- if (affs_init_bitmap(sb))
6614+ tmp_flags = sb->s_flags;
6615+ if (affs_init_bitmap(sb, &tmp_flags))
6616 goto out_error;
6617+ sb->s_flags = tmp_flags;
6618
6619 /* set up enough so that it can read an inode */
6620
6621@@ -445,14 +446,14 @@
6622 int reserved;
6623 int root_block;
6624 unsigned long mount_flags;
6625- unsigned long read_only = AFFS_SB->s_flags & SF_READONLY;
6626+ int res = 0;
6627
6628 pr_debug("AFFS: remount(flags=0x%x,opts=\"%s\")\n",*flags,data);
6629
6630 if (!parse_options(data,&uid,&gid,&mode,&reserved,&root_block,
6631 &blocksize,&AFFS_SB->s_prefix,AFFS_SB->s_volume,&mount_flags))
6632 return -EINVAL;
6633- AFFS_SB->s_flags = mount_flags | read_only;
6634+ AFFS_SB->s_flags = mount_flags;
6635 AFFS_SB->s_mode = mode;
6636 AFFS_SB->s_uid = uid;
6637 AFFS_SB->s_gid = gid;
6638@@ -463,14 +464,11 @@
6639 sb->s_dirt = 1;
6640 while (sb->s_dirt)
6641 affs_write_super(sb);
6642- sb->s_flags |= MS_RDONLY;
6643- } else if (!(AFFS_SB->s_flags & SF_READONLY)) {
6644- sb->s_flags &= ~MS_RDONLY;
6645- } else {
6646- affs_warning(sb,"remount","Cannot remount fs read/write because of errors");
6647- return -EINVAL;
6648- }
6649- return 0;
6650+ affs_free_bitmap(sb);
6651+ } else
6652+ res = affs_init_bitmap(sb, flags);
6653+
6654+ return res;
6655 }
6656
6657 static int
6658diff -Naur linux-2.4.26/fs/asfs/Makefile linux-2.4.26-m68k/fs/asfs/Makefile
6659--- linux-2.4.26/fs/asfs/Makefile 1970-01-01 10:00:00.000000000 +1000
6660+++ linux-2.4.26-m68k/fs/asfs/Makefile 2003-06-20 21:32:40.000000000 +1000
6661@@ -0,0 +1,15 @@
6662+#
6663+# Makefile for the linux asfs filesystem routines.
6664+#
6665+# Note! Dependencies are done automagically by 'make dep', which also
6666+# removes any old dependencies. DON'T put your own dependencies here
6667+# unless it's something special (not a .c file).
6668+#
6669+# Note 2! The CFLAGS definitions are now in the main makefile.
6670+
6671+O_TARGET := asfs.o
6672+
6673+obj-y := inode.o
6674+obj-m := $(O_TARGET)
6675+
6676+include $(TOPDIR)/Rules.make
6677diff -Naur linux-2.4.26/fs/asfs/inode.c linux-2.4.26-m68k/fs/asfs/inode.c
6678--- linux-2.4.26/fs/asfs/inode.c 1970-01-01 10:00:00.000000000 +1000
6679+++ linux-2.4.26-m68k/fs/asfs/inode.c 2003-07-01 05:16:14.000000000 +1000
6680@@ -0,0 +1,664 @@
6681+/*
6682+ *
6683+ * Amiga Smart File System, Linux implementation
6684+ *
6685+ * version: 0.3beta (16.06.2003)
6686+ *
6687+ * Copyright (C) 2003 Marek 'March' Szyprowski <marek@amiga.pl>
6688+ *
6689+ *
6690+ * Thanks to Marcin Kurek (Morgoth/Dreamolers-CAPS) for help.
6691+ *
6692+ * Based on the Linux implementation of the ROMFS file system
6693+ * Copyright (C) 1997-1999 Janos Farkas <chexum@shadow.banki.hu>
6694+ *
6695+ * Using parts of the Amiga FFS filesystem
6696+ * Copyright (C) 1993 Ray Burr
6697+ * Copyright (C) 1996 Hans-Joachim Widmaier
6698+ *
6699+ * and parts of the smbfs filesystem additionally
6700+ * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
6701+ * Copyright (C) 1997 by Volker Lendecke
6702+ *
6703+ *
6704+ * This program is free software; you can redistribute it and/or
6705+ * modify it under the terms of the GNU General Public License
6706+ * as published by the Free Software Foundation; either version
6707+ * 2 of the License, or (at your option) any later version.
6708+ *
6709+ *
6710+ * History:
6711+ *
6712+ * v0.3beta (17.06.2003)
6713+ * - second code clean-up
6714+ *
6715+ * v0.2beta2 (15.06.2003)
6716+ * - fixed yet another stupid bug - driver can't read root block on little-endian systems
6717+ * v0.2beta (15.06.2003)
6718+ * - fixed stupid bug - now files have 'file' flag (S_IFREG) set...
6719+ * - added mount options to set uid, gid and mode of files and dirs
6720+ * - made hidden files & dirs really hidden (= not listed in directories)
6721+ * - code clean-up
6722+ *
6723+ * v0.1beta (11.06.2003)
6724+ * - after many kernel crashes, finally got it!
6725+ * - first working read-only filesystem driver
6726+ *
6727+ */
6728+
6729+/* todo:
6730+ * - remove bugs
6731+ * - considering write access...
6732+ * - speed-up entry lookup (use HashTables...)
6733+ */
6734+
6735+#include <linux/module.h>
6736+#include <linux/types.h>
6737+#include <linux/errno.h>
6738+#include <linux/slab.h>
6739+#include <linux/asfs_fs.h>
6740+#include <linux/fs.h>
6741+#include <linux/locks.h>
6742+#include <linux/init.h>
6743+#include <linux/smp_lock.h>
6744+
6745+#include <asm/byteorder.h>
6746+#include <asm/uaccess.h>
6747+
6748+static struct inode *asfs_iget_from_fsObject(struct super_block *sb, struct fsObject *obj);
6749+
6750+static u32 asfs_calcchecksum(struct fsBlockHeader *block, u32 blocksize)
6751+{
6752+ u32 *data=(void *)block, checksum = 1, tmpchecksum = block->checksum;
6753+
6754+ block->checksum=0;
6755+ while(blocksize > 0) {
6756+ checksum+=be32_to_cpu(*data++);
6757+ blocksize-=4;
6758+ }
6759+ block->checksum=tmpchecksum;
6760+ return(-checksum);
6761+}
6762+
6763+static inline int asfs_check_block(struct fsBlockHeader *block, u32 blocksize, u32 n)
6764+{
6765+ if (asfs_calcchecksum((struct fsBlockHeader *)block, blocksize) == be32_to_cpu(((struct fsBlockHeader *)block)->checksum) && n == be32_to_cpu(((struct fsBlockHeader *)block)->ownblock))
6766+ return 1;
6767+ return 0;
6768+}
6769+
6770+/* get fs structure from block and do some checks... */
6771+static int asfs_get_contblock(struct super_block *sb, u32 n, void *dest)
6772+{
6773+ struct buffer_head *bh;
6774+
6775+ bh = sb_bread(sb, n);
6776+ if (!bh)
6777+ return -1; /* error */
6778+ memcpy(dest, ((char *)bh->b_data), sb->s_blocksize);
6779+ brelse(bh);
6780+
6781+ if (asfs_check_block(dest, sb->s_blocksize, n)) {
6782+ from32be(((struct fsBlockHeader *)dest)->ownblock);
6783+ return 1; /* all okay */
6784+ }
6785+ return -1; /* error */
6786+}
6787+
6788+/* get data from block without checks... */
6789+/*static int asfs_get_datablock (struct super_block *sb, u32 n, void *dest, int len)
6790+{
6791+ struct buffer_head *bh;
6792+ bh = sb_bread(sb, n);
6793+ if (!bh)
6794+ return -1;
6795+ memcpy(dest, ((char *)bh->b_data), len);
6796+ brelse(bh);
6797+ return 1;
6798+}
6799+*/
6800+static inline struct inode *asfs_get_root_inode(struct super_block *sb)
6801+{
6802+ struct inode *result = NULL;
6803+ void *block;
6804+ struct fsObject *obj;
6805+
6806+ asfs_debug("asfs_get_root_inode\n");
6807+
6808+ block = kmalloc(sb->s_blocksize, GFP_KERNEL);
6809+ if (asfs_get_contblock(sb, sb->u.asfs_sb.rootobjectcontainer, block) < 0)
6810+ goto free_and_return;
6811+
6812+ obj = &(((struct fsObjectContainer *)block)->object[0]);
6813+ from32be(obj->objectnode);
6814+ from32be(obj->object.dir.firstdirblock);
6815+
6816+ if (obj->objectnode > 0)
6817+ result = asfs_iget_from_fsObject(sb, obj);
6818+
6819+free_and_return:
6820+ kfree(block);
6821+ return result;
6822+}
6823+
6824+static struct super_operations asfs_ops;
6825+
6826+static int asfs_parse_options(char *options, struct super_block *sb)
6827+{
6828+ char *this_char, *value, *optn;
6829+ int f;
6830+
6831+ /* Fill in defaults */
6832+ sb->u.asfs_sb.uid = ASFS_DEFAULT_UID;
6833+ sb->u.asfs_sb.gid = ASFS_DEFAULT_GID;
6834+ sb->u.asfs_sb.mode = ASFS_DEFAULT_MODE;
6835+
6836+ if (!options)
6837+ return 1;
6838+ for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {
6839+ f = 0;
6840+ if ((value = strchr(this_char,'=')) != NULL)
6841+ *value++ = 0;
6842+ if ((f = !strcmp(this_char,"setuid")) || !strcmp(this_char,"setgid")) {
6843+ if (value) {
6844+ if (!*value) {
6845+ printk("ASFS: Argument for set[ug]id option missing\n");
6846+ return 0;
6847+ } else {
6848+ (f ? sb->u.asfs_sb.uid : sb->u.asfs_sb.gid) = simple_strtoul(value,&value,0);
6849+ if (*value) {
6850+ printk("ASFS: Bad set[ug]id argument\n");
6851+ return 0;
6852+ }
6853+ }
6854+ }
6855+ } else if (!strcmp(this_char,"mode")) {
6856+ optn = "mode";
6857+ if (!value || !*value)
6858+ goto out_no_arg;
6859+ sb->u.asfs_sb.mode = simple_strtoul(value,&value,8) & 0777;
6860+ if (*value)
6861+ return 0;
6862+ } else {
6863+ printk("ASFS: Unrecognized mount option %s\n", this_char);
6864+ return 0;
6865+ }
6866+ }
6867+ return 1;
6868+
6869+out_no_arg:
6870+ printk("ASFS: The %s option requires an argument\n", optn);
6871+ return 0;
6872+}
6873+
6874+static struct super_block *asfs_read_super(struct super_block *sb, void *data, int silent)
6875+{
6876+ struct buffer_head *bh;
6877+ kdev_t dev = sb->s_dev;
6878+ struct fsRootBlock *rootblock;
6879+
6880+ if (!asfs_parse_options(data, sb)) {
6881+ printk(KERN_ERR "ASFS: Error parsing options\n");
6882+ return NULL;
6883+ }
6884+
6885+ if (!sb_set_blocksize(sb, 512))
6886+ return NULL;
6887+ sb->s_maxbytes = 0xFFFFFFFF;
6888+
6889+ bh = sb_bread(sb, 0);
6890+ if (!bh) {
6891+ printk(KERN_ERR "ASFS: unable to read superblock\n");
6892+ goto outnobh;
6893+ }
6894+
6895+ rootblock = (struct fsRootBlock *)bh->b_data;
6896+
6897+ if (be32_to_cpu(rootblock->bheader.id) == ASFS_ROOTID && be16_to_cpu(rootblock->version) == ASFS_STRUCTURE_VERISON) {
6898+ sb->s_blocksize = be32_to_cpu(rootblock->blocksize);
6899+ sb->u.asfs_sb.totalblocks = be32_to_cpu(rootblock->totalblocks);
6900+ sb->u.asfs_sb.rootobjectcontainer = be32_to_cpu(rootblock->rootobjectcontainer);
6901+ sb->u.asfs_sb.extentbnoderoot = be32_to_cpu(rootblock->extentbnoderoot);
6902+
6903+ brelse(bh);
6904+
6905+ if (!sb_set_blocksize(sb, sb->s_blocksize)) {
6906+ printk(KERN_ERR "ASFS: Found Amiga SFS RootBlock on dev %s, but blocksize %ld is not supported!\n", bdevname(dev), sb->s_blocksize);
6907+ return NULL;
6908+ }
6909+
6910+ bh = sb_bread(sb, 0);
6911+ if (!bh) {
6912+ printk(KERN_ERR "ASFS: unable to read superblock\n");
6913+ goto out;
6914+ }
6915+ rootblock = (struct fsRootBlock *)bh->b_data;
6916+
6917+ if (asfs_check_block((void *)rootblock, sb->s_blocksize, 0))
6918+ printk(KERN_NOTICE "ASFS: Found Amiga SFS RootBlock on dev %s. Checksum okay. Mounting...\n", bdevname(dev));
6919+ else {
6920+ if (!silent)
6921+ printk(KERN_ERR "ASFS: Found something like Amiga SFS RootBlock on dev %s, but it has checksum error!\n", bdevname(dev));
6922+ goto out;
6923+ }
6924+ } else {
6925+ if (!silent)
6926+ printk(KERN_ERR "ASFS: Can't find a valid Amiga SFS filesystem on dev %s.\n", bdevname(dev));
6927+ goto out;
6928+ }
6929+
6930+ brelse(bh);
6931+
6932+ sb->s_magic = ASFS_MAGIC;
6933+ sb->s_flags |= MS_RDONLY | MS_NODEV | MS_NOSUID;
6934+ sb->s_op = &asfs_ops;
6935+ sb->s_root = d_alloc_root(asfs_get_root_inode(sb));
6936+ if (!sb->s_root)
6937+ goto outnobh;
6938+
6939+ /* Ehrhm; sorry.. :) */
6940+ if (0) {
6941+out:
6942+ brelse(bh);
6943+outnobh:
6944+ sb = NULL;
6945+ }
6946+ return sb;
6947+}
6948+
6949+/* That's simple too. */
6950+
6951+static int asfs_statfs(struct super_block *sb, struct statfs *buf)
6952+{
6953+ buf->f_type = ASFS_MAGIC;
6954+ buf->f_bsize = sb->s_blocksize;
6955+ buf->f_bfree = buf->f_bavail = buf->f_ffree;
6956+ buf->f_blocks = sb->u.asfs_sb.totalblocks;
6957+ buf->f_namelen = ASFS_MAXFN;
6958+ return 0;
6959+}
6960+
6961+static int asfs_get_fsObject_varlen(struct fsObject *obj)
6962+{
6963+ int len, i;
6964+ u8 *p = obj->name;
6965+ for (i=2; i > 0; p++)
6966+ if (*p == '\0')
6967+ i--;
6968+ len = (p - (u8 *)obj);
6969+ if (len & 1)
6970+ len++;
6971+ return len;
6972+}
6973+
6974+static int asfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
6975+{
6976+ struct inode *diri = filp->f_dentry->d_inode;
6977+ unsigned long f_pos;
6978+ int stored = 0;
6979+ int obj_skip;
6980+
6981+ struct fsObjectContainer *objcont;
6982+ struct fsObject *obj;
6983+ int i;
6984+ unsigned long block;
6985+
6986+ asfs_debug("asfs_readdir:\n");
6987+
6988+ if (filp->f_pos == diri->i_sb->u.asfs_sb.totalblocks)
6989+ return stored;
6990+
6991+ f_pos = filp->f_pos;
6992+
6993+ if (f_pos == 0) {
6994+ filp->private_data = (void *)0;
6995+ if (filldir(dirent, ".", 1, f_pos, diri->i_ino, DT_DIR) < 0)
6996+ return 0;
6997+ filp->f_pos = f_pos = 1;
6998+ stored++;
6999+ }
7000+ if (f_pos == 1) {
7001+ if (filldir(dirent, "..", 2, f_pos, filp->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
7002+ return stored;
7003+ filp->f_pos = f_pos = 2;
7004+ stored++;
7005+ }
7006+
7007+ if (diri->u.asfs_i.firstdirblock == 0) { /* empty directory */
7008+ filp->f_pos = diri->i_sb->u.asfs_sb.totalblocks;
7009+ return stored;
7010+ }
7011+
7012+ objcont = kmalloc(diri->i_sb->s_blocksize, GFP_KERNEL);
7013+
7014+ if (f_pos == 2) { /* reading directory from its beginning */
7015+ block = diri->u.asfs_i.firstdirblock;
7016+ do {
7017+ if (asfs_get_contblock(diri->i_sb, block, (void *)objcont) < 0)
7018+ goto free_and_end;
7019+ from32be(objcont->previous);
7020+ from32be(objcont->next);
7021+ block = objcont->previous;
7022+ } while (objcont->previous != 0);
7023+ obj_skip = 0;
7024+ } else {
7025+ block = f_pos;
7026+ if (asfs_get_contblock(diri->i_sb, block, (void *)objcont) < 0)
7027+ goto free_and_end;
7028+ from32be(objcont->previous);
7029+ from32be(objcont->next);
7030+ obj_skip = (int)filp->private_data;
7031+ }
7032+
7033+ i=0;
7034+ block = ((struct fsBlockHeader *)objcont)->ownblock;
7035+
7036+ do {
7037+ if (i != 0) {
7038+ if (asfs_get_contblock(diri->i_sb, block, (void *)objcont) < 0)
7039+ goto free_and_end;
7040+ from32be(objcont->previous);
7041+ from32be(objcont->next);
7042+ }
7043+
7044+ i = 0;
7045+ obj = &(objcont->object[0]);
7046+ from32be(obj->objectnode);
7047+
7048+ while (obj->objectnode > 0 && ((char *)obj - (char *)objcont) + sizeof(struct fsObject) < diri->i_sb->s_blocksize) {
7049+ if (obj_skip > 0)
7050+ obj_skip--;
7051+ else if (!(obj->bits & OTYPE_HIDDEN)) {
7052+ asfs_debug("ASFS: DirFilling: entry #%d (in_cont: %d) \"%s\" (node %lu offset %lu), type %d\n", stored, i, obj->name, (unsigned long) obj->objectnode, block, obj->bits);
7053+ filp->f_pos = block;
7054+ if (filldir(dirent, obj->name, strlen(obj->name), block, obj->objectnode, ((obj->bits & OTYPE_DIR) ? DT_DIR : DT_REG)) < 0) {
7055+ filp->private_data = (void *)i;
7056+ asfs_debug("ASFS: DirFilling: to be continued...\n");
7057+ goto free_and_end;
7058+ }
7059+ stored++;
7060+ }
7061+ obj = (struct fsObject *)((char *)(obj) + asfs_get_fsObject_varlen(obj));
7062+ i++;
7063+ }
7064+ block = objcont->next;
7065+
7066+ } while (objcont->next != 0);
7067+
7068+ filp->f_pos = diri->i_sb->u.asfs_sb.totalblocks;
7069+
7070+free_and_end:
7071+ kfree(objcont);
7072+ return stored;
7073+}
7074+
7075+static inline u8 upperchar(u8 c)
7076+{
7077+ if((c>=224 && c<=254 && c!=247) || (c>='a' && c<='z'))
7078+ c-=32;
7079+ return(c);
7080+}
7081+
7082+static int namecmp(u8 *s, u8 *ct)
7083+{
7084+ while (upperchar(*s) == upperchar(*ct) && *ct != '\0' && *ct != '/') {
7085+ s++; ct++;
7086+ }
7087+ return (*s == '\0' && (*ct == '\0' || *ct == '/')) ? 0 : *ct - *s;
7088+}
7089+
7090+
7091+static struct dentry *asfs_lookup(struct inode *dir, struct dentry *dentry)
7092+{
7093+ int res;
7094+ struct inode *inode;
7095+ unsigned char *name; /* got from dentry */
7096+
7097+ struct fsObjectContainer *objcont;
7098+ struct fsObject *obj;
7099+ int i;
7100+ unsigned long block;
7101+
7102+ name = (unsigned char *)dentry->d_name.name;
7103+ res = -EACCES; /* placeholder for "no data here" */
7104+
7105+ asfs_debug("asfs_lookup: (searching \"%s\"...) ", name);
7106+
7107+ objcont = kmalloc(dir->i_sb->s_blocksize, GFP_KERNEL);
7108+
7109+ block = dir->u.asfs_i.firstdirblock;
7110+
7111+ do {
7112+ if (asfs_get_contblock(dir->i_sb, block, (void *)objcont) < 0)
7113+ goto free_and_error;
7114+ from32be(objcont->previous);
7115+ from32be(objcont->next);
7116+ block = objcont->previous;
7117+ } while (objcont->previous != 0);
7118+
7119+ i=0;
7120+ block = ((struct fsBlockHeader *)objcont)->ownblock;
7121+
7122+ do {
7123+ if (i != 0) {
7124+ if (asfs_get_contblock(dir->i_sb, block, (void *)objcont) < 0)
7125+ goto free_and_error;
7126+ from32be(objcont->previous);
7127+ from32be(objcont->next);
7128+ }
7129+
7130+ i = 0;
7131+ obj = &(objcont->object[0]);
7132+ while (be32_to_cpu(obj->objectnode) > 0 && ((char *)obj - (char *)objcont) + sizeof(struct fsObject) < dir->i_sb->s_blocksize) {
7133+ if (namecmp(obj->name, name) == 0) {
7134+ from32be(obj->objectnode);
7135+ from32be(obj->object.dir.firstdirblock); /* it also corrects file.size and file.firstdatablock */
7136+ from32be(obj->object.dir.hashtable); /* because they are union */
7137+ from32be(obj->datemodified);
7138+ asfs_debug("Object found! #%d: Node %u, Name %s, Type: %d, inCont %lu\n", i, obj->objectnode, obj->name, obj->bits, block);
7139+
7140+ if ((inode = asfs_iget_from_fsObject(dir->i_sb, obj)))
7141+ goto found_inode;
7142+
7143+ asfs_debug("ASFS: Strange - no inode allocated... :(\n");
7144+ goto free_and_error;
7145+ }
7146+ obj = (struct fsObject *)((char *)(obj) + asfs_get_fsObject_varlen(obj));
7147+ i++;
7148+ }
7149+ block = objcont->next;
7150+
7151+ } while (objcont->next != 0);
7152+
7153+ /*
7154+ * it's a bit funky, _lookup needs to return an error code
7155+ * (negative) or a NULL, both as a dentry. ENOENT should not
7156+ * be returned, instead we need to create a negative dentry by
7157+ * d_add(dentry, NULL); and return 0 as no error.
7158+ * (Although as I see, it only matters on writable file
7159+ * systems).
7160+ */
7161+
7162+ inode = NULL;
7163+ asfs_debug("ASFS: object not found.\n");
7164+found_inode:
7165+ res = 0;
7166+ d_add(dentry, inode);
7167+free_and_error:
7168+ kfree(objcont);
7169+ return ERR_PTR(res);
7170+}
7171+
7172+static struct fsExtentBNode asfs_search_BNodeTree(struct super_block *sb, u32 key)
7173+{
7174+ struct fsBNodeContainer *bnodecont;
7175+ struct fsExtentBNode result;
7176+ unsigned long block = sb->u.asfs_sb.extentbnoderoot;
7177+
7178+ bnodecont = kmalloc(sb->s_blocksize, GFP_KERNEL);
7179+ while (asfs_get_contblock(sb, block, bnodecont) > 0) {
7180+ from16be(bnodecont->btc.nodecount);
7181+ if (bnodecont->btc.isleaf) {
7182+ int i;
7183+ struct fsExtentBNode *exbnode;
7184+ exbnode = (void *)bnodecont->btc.bnode;
7185+ for (i=0; i < bnodecont->btc.nodecount; i++) {
7186+ from32be(exbnode->key);
7187+ from32be(exbnode->next);
7188+ from32be(exbnode->prev);
7189+ from16be(exbnode->blocks);
7190+ if (exbnode->key == key) {
7191+ result = *exbnode;
7192+ goto found;
7193+ }
7194+ exbnode = (void *)exbnode + bnodecont->btc.nodesize;
7195+ }
7196+ } else {
7197+ int i;
7198+ struct BNode *bnode;
7199+ bnode = (void *)bnodecont->btc.bnode;
7200+ for (i=0; i < bnodecont->btc.nodecount && key >= be32_to_cpu(bnode->key); i++)
7201+ bnode = (void *)bnode + bnodecont->btc.nodesize;
7202+
7203+ bnode = (void *)bnode - bnodecont->btc.nodesize;
7204+ block = be32_to_cpu(bnode->data);
7205+ }
7206+ }
7207+ /* read error or key not found */
7208+ result = (struct fsExtentBNode){0, 0, 0, 0};
7209+found:
7210+ kfree(bnodecont);
7211+ return result;
7212+}
7213+
7214+static int
7215+asfs_get_block(struct inode *inode, long block, struct buffer_head *bh_result, int create)
7216+{
7217+ struct fsExtentBNode extend;
7218+ u32 filedata = inode->u.asfs_i.firstdatablock;
7219+ unsigned long pos = 0;
7220+
7221+ asfs_debug("ASFS: get_block(%lu, %ld)\n", inode->i_ino, block);
7222+
7223+ if (block < 0) {
7224+ printk(KERN_ERR "ASFS: asfsget_block: requested block (%ld) < 0!\n", block);
7225+ return -EIO;
7226+ }
7227+
7228+ if (block >= inode->i_blocks) {
7229+ printk(KERN_ERR "ASFS: asfsget_block: strange block request %ld!\n", block);
7230+ return -EIO;
7231+ }
7232+
7233+ do {
7234+ extend = asfs_search_BNodeTree(inode->i_sb, filedata);
7235+ if (extend.key == 0)
7236+ goto error;
7237+ filedata = extend.next;
7238+ if (pos + extend.blocks > block) {
7239+ bh_result->b_blocknr = extend.key + block - pos;
7240+ bh_result->b_dev = inode->i_dev;
7241+ bh_result->b_state |= (1UL << BH_Mapped);
7242+ return 0;
7243+ }
7244+ pos += extend.blocks;
7245+ } while (extend.next != 0 && pos < inode->i_blocks);
7246+error:
7247+ return -EIO;
7248+}
7249+
7250+static int asfs_readpage(struct file *file, struct page *page)
7251+{
7252+ return block_read_full_page(page, asfs_get_block);
7253+}
7254+static int asfs_bmap(struct address_space *mapping, long block)
7255+{
7256+ return generic_block_bmap(mapping,block,asfs_get_block);
7257+}
7258+
7259+/* Mapping from our types to the kernel */
7260+
7261+static struct address_space_operations asfs_aops = {
7262+ .readpage = asfs_readpage,
7263+ .sync_page = block_sync_page,
7264+ .bmap = asfs_bmap,
7265+};
7266+
7267+struct file_operations asfs_file_operations = {
7268+ .llseek = generic_file_llseek,
7269+ .read = generic_file_read,
7270+ .mmap = generic_file_mmap,
7271+};
7272+
7273+static struct file_operations asfs_dir_operations = {
7274+ .read = generic_read_dir,
7275+ .readdir = asfs_readdir,
7276+};
7277+
7278+static struct inode_operations asfs_dir_inode_operations = {
7279+ .lookup = asfs_lookup,
7280+};
7281+
7282+static struct inode *asfs_iget_from_fsObject(struct super_block *sb, struct fsObject *obj)
7283+{
7284+ struct inode *result;
7285+
7286+ result = new_inode(sb);
7287+ if (!result)
7288+ return result;
7289+
7290+ result->i_ino = obj->objectnode;
7291+ result->i_mode = sb->u.asfs_sb.mode;
7292+ result->i_mtime = result->i_atime = result->i_ctime = obj->datemodified + (365*8+2)*24*60*60; /* Linux: seconds since 01-01-1970, AmigaSFS: seconds since 01-01-1978 */
7293+ result->i_uid = sb->u.asfs_sb.uid;
7294+ result->i_gid = sb->u.asfs_sb.gid;
7295+
7296+ asfs_debug("asfs_iget_from_fsObject: Setting-up node %lu... ", result->i_ino);
7297+
7298+ if (obj->bits & OTYPE_DIR) {
7299+ asfs_debug("dir (FirstdirBlock: %u, HashTable %u)\n", obj->object.dir.firstdirblock, obj->object.dir.hashtable);
7300+
7301+ result->i_size = 0;
7302+ result->i_op = &asfs_dir_inode_operations;
7303+ result->i_fop = &asfs_dir_operations;
7304+ result->i_mode |= S_IFDIR | ((result->i_mode & 0400) ? 0100 : 0) | ((result->i_mode & 0040) ? 0010 : 0) | ((result->i_mode & 0004) ? 0001 : 0);
7305+ result->u.asfs_i.firstdirblock = obj->object.dir.firstdirblock;
7306+ result->u.asfs_i.hashtable = obj->object.dir.hashtable;
7307+ } else {
7308+ asfs_debug("file (Size: %u, FirstBlock: %u)\n", obj->object.file.size, obj->object.file.data);
7309+
7310+ result->i_size = obj->object.file.size;
7311+ result->i_blocks = (obj->object.file.size + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
7312+ result->i_fop = &asfs_file_operations;
7313+ result->i_mapping->a_ops = &asfs_aops;
7314+ result->i_mode |= S_IFREG;
7315+ result->u.asfs_i.firstdatablock = obj->object.file.data;
7316+ }
7317+ insert_inode_hash(result);
7318+ return result;
7319+}
7320+
7321+static struct super_operations asfs_ops = {
7322+ .statfs = asfs_statfs,
7323+};
7324+
7325+static DECLARE_FSTYPE_DEV(asfs_fs_type, "asfs", asfs_read_super);
7326+
7327+static int __init init_asfs_fs(void)
7328+{
7329+ return register_filesystem(&asfs_fs_type);
7330+}
7331+
7332+static void __exit exit_asfs_fs(void)
7333+{
7334+ unregister_filesystem(&asfs_fs_type);
7335+}
7336+
7337+/* Yes, works even as a module... :) */
7338+
7339+EXPORT_NO_SYMBOLS;
7340+MODULE_DESCRIPTION("Amiga Smart File System support for Linux");
7341+
7342+module_init(init_asfs_fs)
7343+module_exit(exit_asfs_fs)
7344+MODULE_LICENSE("GPL");
7345diff -Naur linux-2.4.26/fs/binfmt_aout.c linux-2.4.26-m68k/fs/binfmt_aout.c
7346--- linux-2.4.26/fs/binfmt_aout.c 2001-11-03 12:39:20.000000000 +1100
7347+++ linux-2.4.26-m68k/fs/binfmt_aout.c 2003-04-07 09:23:02.000000000 +1000
7348@@ -349,7 +349,7 @@
7349 return error;
7350 }
7351
7352- flush_icache_range(text_addr, text_addr+ex.a_text+ex.a_data);
7353+ flush_icache_user_range((void *)text_addr, ex.a_text + ex.a_data);
7354 } else {
7355 static unsigned long error_time, error_time2;
7356 if ((ex.a_text & 0xfff || ex.a_data & 0xfff) &&
7357@@ -373,9 +373,7 @@
7358 do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
7359 bprm->file->f_op->read(bprm->file,(char *)N_TXTADDR(ex),
7360 ex.a_text+ex.a_data, &pos);
7361- flush_icache_range((unsigned long) N_TXTADDR(ex),
7362- (unsigned long) N_TXTADDR(ex) +
7363- ex.a_text+ex.a_data);
7364+ flush_icache_user_range((void *)N_TXTADDR(ex), ex.a_text + ex.a_data);
7365 goto beyond_if;
7366 }
7367
7368@@ -471,8 +469,7 @@
7369
7370 file->f_op->read(file, (char *)start_addr,
7371 ex.a_text + ex.a_data, &pos);
7372- flush_icache_range((unsigned long) start_addr,
7373- (unsigned long) start_addr + ex.a_text + ex.a_data);
7374+ flush_icache_user_range((void *)start_addr, ex.a_text + ex.a_data);
7375
7376 retval = 0;
7377 goto out;
7378diff -Naur linux-2.4.26/fs/binfmt_elf.c linux-2.4.26-m68k/fs/binfmt_elf.c
7379--- linux-2.4.26/fs/binfmt_elf.c 2004-04-14 23:05:40.000000000 +1000
7380+++ linux-2.4.26-m68k/fs/binfmt_elf.c 2004-04-15 06:42:54.000000000 +1000
7381@@ -403,8 +403,7 @@
7382 retval = interpreter->f_op->read(interpreter, addr, text_data, &offset);
7383 if (retval < 0)
7384 goto out;
7385- flush_icache_range((unsigned long)addr,
7386- (unsigned long)addr + text_data);
7387+ flush_icache_user_range(addr, text_data);
7388
7389 do_brk(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1),
7390 interp_ex->a_bss);
7391diff -Naur linux-2.4.26/fs/fat/inode.c linux-2.4.26-m68k/fs/fat/inode.c
7392--- linux-2.4.26/fs/fat/inode.c 2004-04-14 23:05:40.000000000 +1000
7393+++ linux-2.4.26-m68k/fs/fat/inode.c 2004-04-15 06:42:55.000000000 +1000
7394@@ -11,6 +11,8 @@
7395 */
7396
7397 #include <linux/module.h>
7398+
7399+#include <linux/config.h>
7400 #include <linux/msdos_fs.h>
7401 #include <linux/nls.h>
7402 #include <linux/kernel.h>
7403@@ -226,6 +228,13 @@
7404 opts->shortname = 0;
7405 opts->utf8 = 0;
7406 opts->iocharset = NULL;
7407+ opts->atari = 0;
7408+
7409+#ifdef CONFIG_ATARI
7410+ if(MACH_IS_ATARI)
7411+ /* make Atari GEMDOS format the default if machine is an Atari */
7412+ opts->atari = 1;
7413+#endif
7414 *debug = *fat = 0;
7415
7416 if (!options)
7417@@ -324,6 +333,11 @@
7418 if (value) ret = 0;
7419 else opts->sys_immutable = 1;
7420 }
7421+ else if (!strcmp(this_char,"atari")) {
7422+ if (!value || !strcmp(value,"yes")) opts->atari = 1;
7423+ else if (!strcmp(value,"no")) opts->atari = 0;
7424+ else ret = 0;
7425+ }
7426 else if (!strcmp(this_char,"codepage") && value) {
7427 opts->codepage = simple_strtoul(value,&value,0);
7428 if (*value) ret = 0;
7429@@ -716,16 +730,41 @@
7430
7431 error = 0;
7432 if (!error) {
7433- sbi->fat_bits = fat32 ? 32 :
7434+ if (!opts.atari)
7435+ sbi->fat_bits = fat32 ? 32 :
7436 (fat ? fat :
7437 (sbi->clusters > MSDOS_FAT12 ? 16 : 12));
7438+ else {
7439+ int sectors;
7440+ /* Atari GEMDOS partitions always have 16-bit fat */
7441+ sbi->fat_bits = fat32 ? 32 : (fat ? fat : 16);
7442+ /* If more clusters than fat entries in 16-bit fat, we assume
7443+ * it's a real MSDOS partition with 12-bit fat.
7444+ */
7445+ if (!fat32 && sbi->clusters+2 > sbi->
7446+ fat_length*SECTOR_SIZE*8/sbi->fat_bits)
7447+ sbi->fat_bits = 12;
7448+ /* if it's a floppy disk --> 12bit fat */
7449+ if (!fat32 && MAJOR(sb->s_dev) == FLOPPY_MAJOR)
7450+ sbi->fat_bits = 12;
7451+ /* if it's a ramdisk or loopback device and has one of the usual
7452+ * floppy sizes -> 12bit FAT */
7453+ sectors = total_sectors + sbi->data_start;
7454+ if (!fat32 && (MAJOR(sb->s_dev) == RAMDISK_MAJOR ||
7455+ MAJOR(sb->s_dev) == LOOP_MAJOR) &&
7456+ (sectors == 720 || sectors == 1440 || sectors == 2880))
7457+ sbi->fat_bits = 12;
7458+ }
7459 fat_clusters =
7460 sbi->fat_length * logical_sector_size * 8 / sbi->fat_bits;
7461 error = !sbi->fats || (sbi->dir_entries & (sbi->dir_per_block - 1))
7462 || sbi->clusters + 2 > fat_clusters + MSDOS_MAX_EXTRA
7463 || logical_sector_size < 512
7464 || PAGE_CACHE_SIZE < logical_sector_size
7465- || !b->secs_track || !b->heads;
7466+ /* secs_track and heads may be arbitrary on GEMDOS
7467+ partitions, it depends on partitioning software
7468+ used. */
7469+ || (!opts.atari && (!b->secs_track || !b->heads));
7470 }
7471 brelse(bh);
7472
7473@@ -744,10 +783,10 @@
7474 error = cvf_formats[i]->mount_cvf(sb, cvf_options);
7475 if (error || debug) {
7476 /* The MSDOS_CAN_BMAP is obsolete, but left just to remember */
7477- printk("[MS-DOS FS Rel. 12,FAT %d,check=%c,conv=%c,"
7478+ printk("[MS-DOS FS Rel. 12,FAT %d,check=%c,conv=%c,atari=%c,"
7479 "uid=%d,gid=%d,umask=%03o%s]\n",
7480- sbi->fat_bits,opts.name_check,
7481- opts.conversion,opts.fs_uid,opts.fs_gid,opts.fs_umask,
7482+ sbi->fat_bits,opts.name_check,opts.conversion,
7483+ opts.atari?'y':'n',opts.fs_uid,opts.fs_gid,opts.fs_umask,
7484 MSDOS_CAN_BMAP(sbi) ? ",bmap" : "");
7485 printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%ld,ds=%ld,de=%d,data=%ld,"
7486 "se=%u,ts=%u,ls=%d,rc=%ld,fc=%u]\n",
7487diff -Naur linux-2.4.26/include/asm-m68k/bootinfo.h linux-2.4.26-m68k/include/asm-m68k/bootinfo.h
7488--- linux-2.4.26/include/asm-m68k/bootinfo.h 2001-04-19 04:49:13.000000000 +1000
7489+++ linux-2.4.26-m68k/include/asm-m68k/bootinfo.h 2003-07-22 07:20:24.000000000 +1000
7490@@ -255,6 +255,7 @@
7491 #define MVME16x_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
7492 #define BVME6000_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
7493 #define Q40_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
7494+#define TEKXP_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
7495
7496 #ifdef BOOTINFO_COMPAT_1_0
7497
7498diff -Naur linux-2.4.26/include/asm-m68k/keyboard.h linux-2.4.26-m68k/include/asm-m68k/keyboard.h
7499--- linux-2.4.26/include/asm-m68k/keyboard.h 2004-04-14 23:05:40.000000000 +1000
7500+++ linux-2.4.26-m68k/include/asm-m68k/keyboard.h 2004-02-10 07:24:32.000000000 +1100
7501@@ -13,6 +13,58 @@
7502
7503 #ifdef __KERNEL__
7504
7505+#ifdef CONFIG_TEKXP
7506+
7507+#include <linux/kernel.h>
7508+#include <linux/ioport.h>
7509+#include <asm/io.h>
7510+
7511+#define KEYBOARD_IRQ 4
7512+#define DISABLE_KBD_DURING_INTERRUPTS 0
7513+
7514+extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
7515+extern int pckbd_getkeycode(unsigned int scancode);
7516+extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
7517+ char raw_mode);
7518+extern char pckbd_unexpected_up(unsigned char keycode);
7519+extern void pckbd_leds(unsigned char leds);
7520+extern void pckbd_init_hw(void);
7521+extern unsigned char pckbd_sysrq_xlate[128];
7522+
7523+#define kbd_setkeycode pckbd_setkeycode
7524+#define kbd_getkeycode pckbd_getkeycode
7525+#define kbd_translate pckbd_translate
7526+#define kbd_unexpected_up pckbd_unexpected_up
7527+#define kbd_leds pckbd_leds
7528+#define kbd_init_hw pckbd_init_hw
7529+#define kbd_sysrq_xlate pckbd_sysrq_xlate
7530+
7531+#define SYSRQ_KEY 0x54
7532+
7533+/* resource allocation */
7534+#define kbd_request_region()
7535+#define kbd_request_irq(handler) request_irq(KEYBOARD_IRQ, handler, 0, \
7536+ "keyboard", NULL)
7537+
7538+/* How to access the keyboard macros on this platform. */
7539+#define kbd_read_input() (*(volatile unsigned char*)0xff900000)
7540+#define kbd_read_status() (*(volatile unsigned char*)0xff900004)
7541+#define kbd_write_output(val) do { *(volatile unsigned char*)0xff900000 = (val); } while(0)
7542+#define kbd_write_command(val) do { *(volatile unsigned char*)0xff900004 = (val); } while(0)
7543+
7544+/* Some stoneage hardware needs delays after some operations. */
7545+#define kbd_pause() do { } while(0)
7546+
7547+/*
7548+ * Machine specific bits for the PS/2 driver
7549+ */
7550+
7551+#define AUX_IRQ 4
7552+#define aux_request_irq(hand, dev_id) (0)
7553+#define aux_free_irq(dev_id) do { } while (0)
7554+
7555+#else /* !CONFIG_TEKXP */
7556+
7557 #include <linux/config.h>
7558 #include <linux/kd.h>
7559 #include <asm/machdep.h>
7560@@ -72,6 +124,8 @@
7561 #define kbd_write_command(val) out_8(KBD_CNTL_REG, val)
7562 extern unsigned int SYSRQ_KEY;
7563
7564+#endif /* !CONFIG_TEKXP */
7565+
7566 #endif /* __KERNEL__ */
7567
7568 #endif /* __M68K_KEYBOARD_H */
7569diff -Naur linux-2.4.26/include/asm-m68k/motorola_pgalloc.h linux-2.4.26-m68k/include/asm-m68k/motorola_pgalloc.h
7570--- linux-2.4.26/include/asm-m68k/motorola_pgalloc.h 2004-02-19 00:36:32.000000000 +1100
7571+++ linux-2.4.26-m68k/include/asm-m68k/motorola_pgalloc.h 2004-04-06 03:59:32.000000000 +1000
7572@@ -231,20 +231,24 @@
7573
7574 static inline void flush_tlb_mm(struct mm_struct *mm)
7575 {
7576- if (mm == current->mm)
7577+ if (mm == current->active_mm)
7578 __flush_tlb();
7579 }
7580
7581 static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
7582 {
7583- if (vma->vm_mm == current->mm)
7584+ if (vma->vm_mm == current->active_mm) {
7585+ mm_segment_t old_fs = get_fs();
7586+ set_fs(USER_DS);
7587 __flush_tlb_one(addr);
7588+ set_fs(old_fs);
7589+ }
7590 }
7591
7592 static inline void flush_tlb_range(struct mm_struct *mm,
7593 unsigned long start, unsigned long end)
7594 {
7595- if (mm == current->mm)
7596+ if (mm == current->active_mm)
7597 __flush_tlb();
7598 }
7599
7600diff -Naur linux-2.4.26/include/asm-m68k/pgalloc.h linux-2.4.26-m68k/include/asm-m68k/pgalloc.h
7601--- linux-2.4.26/include/asm-m68k/pgalloc.h 2004-02-19 00:36:32.000000000 +1100
7602+++ linux-2.4.26-m68k/include/asm-m68k/pgalloc.h 2003-12-01 06:18:08.000000000 +1100
7603@@ -126,35 +126,12 @@
7604
7605 #define flush_dcache_page(page) do { } while (0)
7606 #define flush_icache_page(vma,pg) do { } while (0)
7607-#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
7608-
7609-/* Push n pages at kernel virtual address and clear the icache */
7610-/* RZ: use cpush %bc instead of cpush %dc, cinv %ic */
7611-extern inline void flush_icache_range (unsigned long address,
7612- unsigned long endaddr)
7613-{
7614- if (CPU_IS_040_OR_060) {
7615- short n = (endaddr - address + PAGE_SIZE - 1) / PAGE_SIZE;
7616-
7617- while (--n >= 0) {
7618- __asm__ __volatile__("nop\n\t"
7619- ".chip 68040\n\t"
7620- "cpushp %%bc,(%0)\n\t"
7621- ".chip 68k"
7622- : : "a" (virt_to_phys((void *)address)));
7623- address += PAGE_SIZE;
7624- }
7625- } else {
7626- unsigned long tmp;
7627- __asm__ __volatile__("movec %%cacr,%0\n\t"
7628- "orw %1,%0\n\t"
7629- "movec %0,%%cacr"
7630- : "=&d" (tmp)
7631- : "di" (FLUSH_I));
7632- }
7633-}
7634
7635+extern void flush_icache_user_page(struct vm_area_struct *vma, struct page *page,
7636+ unsigned long addr, int len);
7637
7638+extern void flush_icache_range(unsigned long address, unsigned long endaddr);
7639+extern void flush_icache_user_range(void *address, unsigned long size);
7640
7641
7642 #ifdef CONFIG_SUN3
7643diff -Naur linux-2.4.26/include/asm-m68k/setup.h linux-2.4.26-m68k/include/asm-m68k/setup.h
7644--- linux-2.4.26/include/asm-m68k/setup.h 2000-01-27 07:44:21.000000000 +1100
7645+++ linux-2.4.26-m68k/include/asm-m68k/setup.h 2003-07-22 07:34:11.000000000 +1000
7646@@ -41,6 +41,7 @@
7647 #define MACH_HP300 9
7648 #define MACH_Q40 10
7649 #define MACH_SUN3X 11
7650+#define MACH_TEKXP 12
7651
7652 #ifdef __KERNEL__
7653
7654@@ -53,7 +54,8 @@
7655 #elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) || defined(CONFIG_APOLLO) \
7656 || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \
7657 || defined(CONFIG_HP300) || defined(CONFIG_Q40) \
7658- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
7659+ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) \
7660+ || defined(CONFIG_TEKXP)
7661 # define MACH_IS_AMIGA (m68k_machtype == MACH_AMIGA)
7662 #else
7663 # define MACH_AMIGA_ONLY
7664@@ -66,7 +68,8 @@
7665 #elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_APOLLO) \
7666 || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \
7667 || defined(CONFIG_HP300) || defined(CONFIG_Q40) \
7668- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
7669+ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) \
7670+ || defined(CONFIG_TEKXP)
7671 # define MACH_IS_ATARI (m68k_machtype == MACH_ATARI)
7672 #else
7673 # define MACH_ATARI_ONLY
7674@@ -79,7 +82,8 @@
7675 #elif defined(CONFIG_AMIGA) || defined(CONFIG_ATARI) || defined(CONFIG_APOLLO) \
7676 || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \
7677 || defined(CONFIG_HP300) || defined(CONFIG_Q40) \
7678- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
7679+ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) \
7680+ || defined(CONFIG_TEKXP)
7681 # define MACH_IS_MAC (m68k_machtype == MACH_MAC)
7682 #else
7683 # define MACH_MAC_ONLY
7684@@ -100,7 +104,8 @@
7685 #elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
7686 || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \
7687 || defined(CONFIG_HP300) || defined(CONFIG_Q40) \
7688- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
7689+ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) \
7690+ || defined(CONFIG_TEKXP)
7691 # define MACH_IS_APOLLO (m68k_machtype == MACH_APOLLO)
7692 #else
7693 # define MACH_APOLLO_ONLY
7694@@ -113,7 +118,8 @@
7695 #elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
7696 || defined(CONFIG_APOLLO) || defined(CONFIG_BVME6000) \
7697 || defined(CONFIG_HP300) || defined(CONFIG_Q40) \
7698- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME16x)
7699+ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME16x) \
7700+ || defined(CONFIG_TEKXP)
7701 # define MACH_IS_MVME147 (m68k_machtype == MACH_MVME147)
7702 #else
7703 # define MACH_MVME147_ONLY
7704@@ -126,7 +132,8 @@
7705 #elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
7706 || defined(CONFIG_APOLLO) || defined(CONFIG_BVME6000) \
7707 || defined(CONFIG_HP300) || defined(CONFIG_Q40) \
7708- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
7709+ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) \
7710+ || defined(CONFIG_TEKXP)
7711 # define MACH_IS_MVME16x (m68k_machtype == MACH_MVME16x)
7712 #else
7713 # define MACH_MVME16x_ONLY
7714@@ -139,7 +146,8 @@
7715 #elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
7716 || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \
7717 || defined(CONFIG_HP300) || defined(CONFIG_Q40) \
7718- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
7719+ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) \
7720+ || defined(CONFIG_TEKXP)
7721 # define MACH_IS_BVME6000 (m68k_machtype == MACH_BVME6000)
7722 #else
7723 # define MACH_BVME6000_ONLY
7724@@ -152,7 +160,8 @@
7725 #elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
7726 || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \
7727 || defined(CONFIG_BVME6000) || defined(CONFIG_Q40) \
7728- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
7729+ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) \
7730+ || defined(CONFIG_TEKXP)
7731 # define MACH_IS_HP300 (m68k_machtype == MACH_HP300)
7732 #else
7733 # define MACH_HP300_ONLY
7734@@ -165,7 +174,8 @@
7735 #elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
7736 || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \
7737 || defined(CONFIG_BVME6000) || defined(CONFIG_HP300) \
7738- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
7739+ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) \
7740+ || defined(CONFIG_TEKXP)
7741 # define MACH_IS_Q40 (m68k_machtype == MACH_Q40)
7742 #else
7743 # define MACH_Q40_ONLY
7744@@ -178,7 +188,8 @@
7745 #elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
7746 || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \
7747 || defined(CONFIG_BVME6000) || defined(CONFIG_HP300) \
7748- || defined(CONFIG_Q40) || defined(CONFIG_MVME147)
7749+ || defined(CONFIG_Q40) || defined(CONFIG_MVME147) \
7750+ || defined(CONFIG_TEKXP)
7751 # define MACH_IS_SUN3X (m68k_machtype == MACH_SUN3X)
7752 #else
7753 # define CONFIG_SUN3X_ONLY
7754@@ -186,6 +197,20 @@
7755 # define MACH_TYPE (MACH_SUN3X)
7756 #endif
7757
7758+#if !defined (CONFIG_TEKXP)
7759+# define MACH_IS_TEKXP (0)
7760+#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
7761+ || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \
7762+ || defined(CONFIG_BVME6000) || defined(CONFIG_HP300) \
7763+ || defined(CONFIG_Q40) || defined(CONFIG_MVME147) \
7764+ || defined(CONFIG_SUN3X)
7765+# define MACH_IS_TEKXP (m68k_machtype == MACH_TEKXP)
7766+#else
7767+# define CONFIG_TEKXP_ONLY
7768+# define MACH_IS_TEKXP (1)
7769+# define MACH_TYPE (MACH_TEKXP)
7770+#endif
7771+
7772 #ifndef MACH_TYPE
7773 # define MACH_TYPE (m68k_machtype)
7774 #endif
7775@@ -355,7 +380,7 @@
7776 * Miscellaneous
7777 */
7778
7779-#define NUM_MEMINFO 4
7780+#define NUM_MEMINFO 8
7781 #define CL_SIZE 256
7782
7783 #ifndef __ASSEMBLY__
7784diff -Naur linux-2.4.26/include/asm-m68k/tekirq.h linux-2.4.26-m68k/include/asm-m68k/tekirq.h
7785--- linux-2.4.26/include/asm-m68k/tekirq.h 1970-01-01 10:00:00.000000000 +1000
7786+++ linux-2.4.26-m68k/include/asm-m68k/tekirq.h 2003-07-22 07:20:24.000000000 +1000
7787@@ -0,0 +1,27 @@
7788+/*
7789+ * linux/include/asm-m68k/tekirq.h
7790+ *
7791+ * Copyright (C) 2002,2003 Michael Mueller <malware@t-online.de>
7792+ *
7793+ * This file is subject to the terms and conditions of the GNU General Public
7794+ * license. See the file COPYING in the main directory of this archive
7795+ * for more details.
7796+ */
7797+
7798+#ifndef _ASM_TEKIRQ_H_
7799+#define _ASM_TEKIRQ_H_
7800+
7801+#include <asm/irq.h>
7802+
7803+#define TEK_IRQ_VIDEO (IRQ2)
7804+#define TEK_IRQ_KEYB (IRQ4)
7805+#define TEK_IRQ_UART (IRQ5)
7806+#define TEK_IRQ_NET (IRQ6)
7807+
7808+#define TEK_IRQ_TIMER_A (SYS_IRQS + 3)
7809+#define TEK_IRQ_TXRDY_A (SYS_IRQS + 0)
7810+#define TEK_IRQ_RXRDY_A (SYS_IRQS + 1)
7811+#define TEK_IRQ_TXRDY_B (SYS_IRQS + 4)
7812+#define TEK_IRQ_RXRDY_B (SYS_IRQS + 5)
7813+
7814+#endif /* !defined(_ASM_TEKIRQ_H_) */
7815diff -Naur linux-2.4.26/include/asm-m68k/teknvram.h linux-2.4.26-m68k/include/asm-m68k/teknvram.h
7816--- linux-2.4.26/include/asm-m68k/teknvram.h 1970-01-01 10:00:00.000000000 +1000
7817+++ linux-2.4.26-m68k/include/asm-m68k/teknvram.h 2003-07-22 07:20:24.000000000 +1000
7818@@ -0,0 +1,31 @@
7819+/*
7820+ * linux/include/asm-m68k/teknvram.h
7821+ *
7822+ * Copyright (C) 2002,2003 Michael Mueller <malware@t-online.de>
7823+ *
7824+ * This file is subject to the terms and conditions of the GNU General Public
7825+ * License. See the file COPYING in the main directory of this archive for
7826+ * more details.
7827+ */
7828+
7829+#ifndef _ASM_TEKNVRAM_H_
7830+#define _ASM_TEKNVRAM_H_
7831+
7832+#define EEPROM_BASE 0xFFF00000UL
7833+#define EEPROM_SIZE 0x800
7834+
7835+extern void init_nvram(unsigned long* memstart);
7836+
7837+extern u_char nvram_readb(int);
7838+extern u_short nvram_readw(int);
7839+extern u_long nvram_readl(int);
7840+
7841+
7842+/*
7843+ * Some known data locations within the NVRAM
7844+ */
7845+#define NVRAM_SONIC_MAC 4 /* 6 bytes MAC address for sonic */
7846+#define NVRAM_DISPLAY 0x1c /* Display type */
7847+
7848+#endif /* !defined(_ASM_TEKNVRAM_H_) */
7849+
7850diff -Naur linux-2.4.26/include/asm-m68k/tekuart.h linux-2.4.26-m68k/include/asm-m68k/tekuart.h
7851--- linux-2.4.26/include/asm-m68k/tekuart.h 1970-01-01 10:00:00.000000000 +1000
7852+++ linux-2.4.26-m68k/include/asm-m68k/tekuart.h 2003-07-22 07:20:24.000000000 +1000
7853@@ -0,0 +1,118 @@
7854+/*
7855+ * linux/include/asm-m68k/tekuart.h
7856+ *
7857+ * Copyright (C) 2002,2003 Michael Mueller <malware@t-online.de>
7858+ *
7859+ * This file is subject to the terms and conditions of the GNU General Public
7860+ * License. See the file COPYING in the main directory of this archive for
7861+ * more details.
7862+ */
7863+
7864+#ifndef ASM_TEKUART
7865+#define ASM_TEKUART
7866+
7867+extern spinlock_t tek_uart_lock;
7868+
7869+#define TEK_UART_BASE (0xFF800000UL)
7870+
7871+#define UART_IRQS 8
7872+
7873+void tek_uart_init_IRQ(void);
7874+int tek_uart_request_irq(unsigned int irq,
7875+ void (*handler)(int, void *, struct pt_regs *),
7876+ unsigned long flags,
7877+ const char *devname, void *dev_id);
7878+void tek_uart_free_irq(unsigned int irq, void *dev_id);
7879+void tek_uart_enable_irq(unsigned int irq);
7880+void tek_uart_disable_irq(unsigned int irq);
7881+int tek_uart_get_irq_list(char *buf);
7882+
7883+void tek_uart_setup_timer(void (*handler)(int, void *, struct pt_regs *));
7884+void tek_uart_putchar(int channel, int c, int waitloop);
7885+
7886+void tek_uart_set_op(int nr);
7887+void tek_uart_clr_op(int nr);
7888+
7889+/*
7890+ * Structures describing the register set of the Motorola 68681 DUART.
7891+ */
7892+
7893+struct tek_uart_rd {
7894+ unsigned char MRxA;
7895+ unsigned short _pad1;
7896+ unsigned char SRA;
7897+ unsigned short _pad2;
7898+ unsigned char BRG_Test;
7899+ unsigned short _pad3;
7900+ unsigned char RHRA;
7901+ unsigned short _pad4;
7902+ unsigned char IPCR;
7903+ unsigned short _pad5;
7904+ unsigned char ISR;
7905+ unsigned short _pad6;
7906+ unsigned char CTU;
7907+ unsigned short _pad7;
7908+ unsigned char CTL;
7909+ unsigned short _pad8;
7910+ unsigned char MRxB;
7911+ unsigned short _pad9;
7912+ unsigned char SRB;
7913+ unsigned short _pad10;
7914+ unsigned char x1x16_Test;
7915+ unsigned short _pad11;
7916+ unsigned char RHRB;
7917+ unsigned short _pad12;
7918+ unsigned char res1;
7919+ unsigned short _pad13;
7920+ unsigned char IP;
7921+ unsigned short _pad14;
7922+ unsigned char CounterStart;
7923+ unsigned short _pad15;
7924+ unsigned char CounterStop;
7925+ unsigned short _pad16;
7926+};
7927+
7928+struct tek_uart_wr {
7929+ unsigned char MRxA;
7930+ unsigned short _pad1;
7931+ unsigned char CSRA;
7932+ unsigned short _pad2;
7933+ unsigned char CRA;
7934+ unsigned short _pad3;
7935+ unsigned char THRA;
7936+ unsigned short _pad4;
7937+ unsigned char ACR;
7938+ unsigned short _pad5;
7939+ unsigned char IMR;
7940+ unsigned short _pad6;
7941+ unsigned char CRUR;
7942+ unsigned short _pad7;
7943+ unsigned char CTLR;
7944+ unsigned short _pad8;
7945+ unsigned char MRxB;
7946+ unsigned short _pad9;
7947+ unsigned char CSRB;
7948+ unsigned short _pad10;
7949+ unsigned char CRB;
7950+ unsigned short _pad11;
7951+ unsigned char THRB;
7952+ unsigned short _pad12;
7953+ unsigned char res1;
7954+ unsigned short _pad13;
7955+ unsigned char OPCR;
7956+ unsigned short _pad14;
7957+ unsigned char OutputSet;
7958+ unsigned short _pad15;
7959+ unsigned char OutputClear;
7960+ unsigned short _pad16;
7961+};
7962+
7963+union tek_uart {
7964+ struct tek_uart_rd rd;
7965+ struct tek_uart_wr wr;
7966+};
7967+
7968+typedef union tek_uart tek_uart_t;
7969+
7970+#endif /* defined(ASM_TEKUART) */
7971+
7972diff -Naur linux-2.4.26/include/linux/adb.h linux-2.4.26-m68k/include/linux/adb.h
7973--- linux-2.4.26/include/linux/adb.h 2003-08-25 21:44:44.000000000 +1000
7974+++ linux-2.4.26-m68k/include/linux/adb.h 2003-08-26 13:18:04.000000000 +1000
7975@@ -76,6 +76,7 @@
7976 #define ADBREQ_REPLY 1 /* expect reply */
7977 #define ADBREQ_SYNC 2 /* poll until done */
7978 #define ADBREQ_NOSEND 4 /* build the request, but don't send it */
7979+#define ADBREQ_RAW 8 /* send raw packet (don't prepend ADB_PACKET) */
7980
7981 /* Messages sent thru the client_list notifier. You should NOT stop
7982 the operation, at least not with this version */
7983diff -Naur linux-2.4.26/include/linux/affs_fs.h linux-2.4.26-m68k/include/linux/affs_fs.h
7984--- linux-2.4.26/include/linux/affs_fs.h 2001-04-20 15:57:06.000000000 +1000
7985+++ linux-2.4.26-m68k/include/linux/affs_fs.h 2004-06-11 07:01:42.000000000 +1000
7986@@ -33,7 +33,8 @@
7987 extern u32 affs_count_free_blocks(struct super_block *s);
7988 extern void affs_free_block(struct super_block *sb, u32 block);
7989 extern u32 affs_alloc_block(struct inode *inode, u32 goal);
7990-extern int affs_init_bitmap(struct super_block *sb);
7991+extern int affs_init_bitmap(struct super_block *sb, int *flags);
7992+extern void affs_free_bitmap(struct super_block *sb);
7993
7994 /* namei.c */
7995
7996diff -Naur linux-2.4.26/include/linux/affs_fs_sb.h linux-2.4.26-m68k/include/linux/affs_fs_sb.h
7997--- linux-2.4.26/include/linux/affs_fs_sb.h 2001-04-20 15:57:06.000000000 +1000
7998+++ linux-2.4.26-m68k/include/linux/affs_fs_sb.h 2004-06-11 07:01:42.000000000 +1000
7999@@ -47,7 +47,6 @@
8000 #define SF_OFS 0x0200 /* Old filesystem */
8001 #define SF_PREFIX 0x0400 /* Buffer for prefix is allocated */
8002 #define SF_VERBOSE 0x0800 /* Talk about fs when mounting */
8003-#define SF_READONLY 0x1000 /* Don't allow to remount rw */
8004
8005 /* short cut to get to the affs specific sb data */
8006 #define AFFS_SB (&sb->u.affs_sb)
8007diff -Naur linux-2.4.26/include/linux/asfs_fs.h linux-2.4.26-m68k/include/linux/asfs_fs.h
8008--- linux-2.4.26/include/linux/asfs_fs.h 1970-01-01 10:00:00.000000000 +1000
8009+++ linux-2.4.26-m68k/include/linux/asfs_fs.h 2003-07-01 05:16:14.000000000 +1000
8010@@ -0,0 +1,151 @@
8011+#ifndef __LINUX_ASFS_FS_H
8012+#define __LINUX_ASFS_FS_H
8013+
8014+#include <linux/types.h>
8015+#include <asm/byteorder.h>
8016+
8017+#define asfs_debug(fmt,arg...) pr_debug(fmt,##arg)
8018+//#define asfs_debug(fmt,arg...) printk(fmt,##arg)
8019+
8020+/* some helper macros... */
8021+
8022+#define from32be(t) ((t)=be32_to_cpu(t))
8023+#define from16be(t) ((t)=be16_to_cpu(t))
8024+
8025+#define ASFS_MAKE_ID(a,b,c,d) (((a)&0xff)<<24|((b)&0xff)<<16|((c)&0xff)<<8|((d)&0xff))
8026+
8027+/* Amiga SFS defines */
8028+
8029+#define ASFS_MAGIC 0xa0ff
8030+#define ASFS_MAXFN 105
8031+
8032+#define ASFS_ROOTID ASFS_MAKE_ID('S','F','S',0)
8033+
8034+#define ASFS_DEFAULT_UID 0
8035+#define ASFS_DEFAULT_GID 0
8036+#define ASFS_DEFAULT_MODE 0444 /* default permission bits for files, dirs have same permission, but with "x" set */
8037+
8038+#define ASFS_STRUCTURE_VERISON (3)
8039+
8040+#define OTYPE_HIDDEN (1)
8041+#define OTYPE_LINK (64)
8042+#define OTYPE_DIR (128)
8043+
8044+#define MSB_MASK (1ul << 31)
8045+
8046+/* Each block has its own header with checksum and id, its called fsBlockHeader */
8047+
8048+struct fsBlockHeader {
8049+ u32 id; /* 4 character id string of this block */
8050+ u32 checksum; /* The checksum */
8051+ u32 ownblock; /* The blocknumber of the block this block is stored at */
8052+};
8053+
8054+/* On-disk "super block", called fsRootBlock */
8055+
8056+struct fsRootBlock {
8057+ struct fsBlockHeader bheader;
8058+
8059+ u16 version; /* Version number of the filesystem block structure */
8060+ u16 sequencenumber; /* The Root with the highest sequencenumber is valid */
8061+
8062+ u32 datecreated; /* Creation date (when first formatted). Cannot be changed. */
8063+ u8 bits; /* various settings, see defines below. */
8064+ u8 pad1;
8065+ u16 pad2;
8066+
8067+ u32 reserved1[2];
8068+
8069+ u64 firstbyte; /* The first byte of our partition from the start of the disk. */
8070+
8071+ u64 lastbyte; /* The last byte of our partition, excluding this one. */
8072+
8073+ u32 totalblocks; /* size of this partition in blocks */
8074+ u32 blocksize; /* blocksize used */
8075+
8076+ u32 reserved2[2];
8077+ u32 reserved3[8];
8078+
8079+ u32 bitmapbase; /* location of the bitmap */
8080+ u32 adminspacecontainer; /* location of first adminspace container */
8081+ u32 rootobjectcontainer; /* location of the root objectcontainer */
8082+ u32 extentbnoderoot; /* location of the root of the extentbnode B-tree */
8083+ u32 objectnoderoot; /* location of the root of the objectnode tree */
8084+
8085+ u32 reserved4[3];
8086+};
8087+
8088+/* On disk inode, called fsObject */
8089+
8090+struct fsObject {
8091+ u16 owneruid;
8092+ u16 ownergid;
8093+ u32 objectnode;
8094+ u32 protection;
8095+
8096+ union {
8097+ struct {
8098+ u32 data;
8099+ u32 size;
8100+ } file;
8101+
8102+ struct {
8103+ u32 hashtable; /* for directories & root, 0 means no hashblock */
8104+ u32 firstdirblock;
8105+ } dir;
8106+ } object;
8107+
8108+ u32 datemodified;
8109+ u8 bits;
8110+
8111+ u8 name[0];
8112+ u8 comment[0];
8113+};
8114+
8115+/* On disk block containging a number of fsObjects */
8116+
8117+struct fsObjectContainer {
8118+ struct fsBlockHeader bheader;
8119+
8120+ u32 parent;
8121+ u32 next;
8122+ u32 previous; /* 0 for the first block in the directory chain */
8123+
8124+ struct fsObject object[0];
8125+};
8126+
8127+/* BTree structures, used to collect file data position on disk */
8128+
8129+struct fsExtentBNode {
8130+ u32 key; /* data! */
8131+ u32 next;
8132+ u32 prev;
8133+ u16 blocks; /* The size in blocks of the region this Extent controls */
8134+};
8135+
8136+struct BNode {
8137+ u32 key;
8138+ u32 data;
8139+};
8140+
8141+struct BTreeContainer {
8142+ u16 nodecount;
8143+ u8 isleaf;
8144+ u8 nodesize; /* Must be a multiple of 2 */
8145+
8146+ struct BNode bnode[0];
8147+};
8148+
8149+/* On disk block with BTreeContainer */
8150+
8151+struct fsBNodeContainer {
8152+ struct fsBlockHeader bheader;
8153+ struct BTreeContainer btc;
8154+};
8155+
8156+#ifdef __KERNEL__
8157+
8158+/* Not much now */
8159+
8160+#endif /* __KERNEL__ */
8161+#endif
8162diff -Naur linux-2.4.26/include/linux/asfs_fs_i.h linux-2.4.26-m68k/include/linux/asfs_fs_i.h
8163--- linux-2.4.26/include/linux/asfs_fs_i.h 1970-01-01 10:00:00.000000000 +1000
8164+++ linux-2.4.26-m68k/include/linux/asfs_fs_i.h 2003-07-01 05:16:14.000000000 +1000
8165@@ -0,0 +1,12 @@
8166+#ifndef __ASFS_FS_I
8167+#define __ASFS_FS_I
8168+
8169+/* inode in-kernel data */
8170+
8171+struct asfs_inode_info {
8172+ u32 firstdirblock;
8173+ u32 firstdatablock;
8174+ u32 hashtable;
8175+};
8176+
8177+#endif
8178diff -Naur linux-2.4.26/include/linux/asfs_fs_sb.h linux-2.4.26-m68k/include/linux/asfs_fs_sb.h
8179--- linux-2.4.26/include/linux/asfs_fs_sb.h 1970-01-01 10:00:00.000000000 +1000
8180+++ linux-2.4.26-m68k/include/linux/asfs_fs_sb.h 2003-07-01 05:16:14.000000000 +1000
8181@@ -0,0 +1,15 @@
8182+#ifndef __ASFS_FS_SB
8183+#define __ASFS_FS_SB
8184+
8185+/* Amiga SFS superblock in-core data */
8186+
8187+struct asfs_sb_info {
8188+ u32 totalblocks;
8189+ u32 rootobjectcontainer;
8190+ u32 extentbnoderoot;
8191+ uid_t uid;
8192+ gid_t gid;
8193+ umode_t mode;
8194+};
8195+
8196+#endif
8197diff -Naur linux-2.4.26/include/linux/bootmem.h linux-2.4.26-m68k/include/linux/bootmem.h
8198--- linux-2.4.26/include/linux/bootmem.h 2002-11-29 10:53:15.000000000 +1100
8199+++ linux-2.4.26-m68k/include/linux/bootmem.h 2002-12-01 01:59:10.000000000 +1100
8200@@ -38,11 +38,11 @@
8201 #define alloc_bootmem(x) \
8202 __alloc_bootmem((x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
8203 #define alloc_bootmem_low(x) \
8204- __alloc_bootmem((x), SMP_CACHE_BYTES, 0)
8205+ __alloc_bootmem((x), SMP_CACHE_BYTES, __pa(PAGE_OFFSET))
8206 #define alloc_bootmem_pages(x) \
8207 __alloc_bootmem((x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
8208 #define alloc_bootmem_low_pages(x) \
8209- __alloc_bootmem((x), PAGE_SIZE, 0)
8210+ __alloc_bootmem((x), PAGE_SIZE, __pa(PAGE_OFFSET))
8211 extern unsigned long __init free_all_bootmem (void);
8212
8213 extern unsigned long __init init_bootmem_node (pg_data_t *pgdat, unsigned long freepfn, unsigned long startpfn, unsigned long endpfn);
8214diff -Naur linux-2.4.26/include/linux/fs.h linux-2.4.26-m68k/include/linux/fs.h
8215--- linux-2.4.26/include/linux/fs.h 2004-02-19 00:36:32.000000000 +1100
8216+++ linux-2.4.26-m68k/include/linux/fs.h 2004-02-19 09:19:03.000000000 +1100
8217@@ -307,6 +307,7 @@
8218 #include <linux/nfs_fs_i.h>
8219 #include <linux/sysv_fs_i.h>
8220 #include <linux/affs_fs_i.h>
8221+#include <linux/asfs_fs_i.h>
8222 #include <linux/ufs_fs_i.h>
8223 #include <linux/efs_fs_i.h>
8224 #include <linux/coda_fs_i.h>
8225@@ -502,6 +503,7 @@
8226 struct nfs_inode_info nfs_i;
8227 struct sysv_inode_info sysv_i;
8228 struct affs_inode_info affs_i;
8229+ struct asfs_inode_info asfs_i;
8230 struct ufs_inode_info ufs_i;
8231 struct efs_inode_info efs_i;
8232 struct romfs_inode_info romfs_i;
8233@@ -719,6 +721,7 @@
8234 #include <linux/nfs_fs_sb.h>
8235 #include <linux/sysv_fs_sb.h>
8236 #include <linux/affs_fs_sb.h>
8237+#include <linux/asfs_fs_sb.h>
8238 #include <linux/ufs_fs_sb.h>
8239 #include <linux/efs_fs_sb.h>
8240 #include <linux/romfs_fs_sb.h>
8241@@ -777,6 +780,7 @@
8242 struct nfs_sb_info nfs_sb;
8243 struct sysv_sb_info sysv_sb;
8244 struct affs_sb_info affs_sb;
8245+ struct asfs_sb_info asfs_sb;
8246 struct ufs_sb_info ufs_sb;
8247 struct efs_sb_info efs_sb;
8248 struct shmem_sb_info shmem_sb;
8249diff -Naur linux-2.4.26/include/linux/module.h linux-2.4.26-m68k/include/linux/module.h
8250--- linux-2.4.26/include/linux/module.h 2004-04-14 23:05:40.000000000 +1000
8251+++ linux-2.4.26-m68k/include/linux/module.h 2004-05-04 21:21:50.000000000 +1000
8252@@ -284,7 +284,7 @@
8253 */
8254
8255 #define MODULE_LICENSE(license) \
8256-static const char __module_license[] __attribute__((section(".modinfo"))) = \
8257+static const char __module_license[] __attribute_used__ __attribute__((section(".modinfo"))) = \
8258 "license=" license
8259
8260 /* Define the module variable, and usage macros. */
8261@@ -296,10 +296,10 @@
8262 #define MOD_IN_USE __MOD_IN_USE(THIS_MODULE)
8263
8264 #include <linux/version.h>
8265-static const char __module_kernel_version[] __attribute__((section(".modinfo"))) =
8266+static const char __module_kernel_version[] __attribute_used__ __attribute__((section(".modinfo"))) =
8267 "kernel_version=" UTS_RELEASE;
8268 #ifdef MODVERSIONS
8269-static const char __module_using_checksums[] __attribute__((section(".modinfo"))) =
8270+static const char __module_using_checksums[] __attribute_used__ __attribute__((section(".modinfo"))) =
8271 "using_checksums=1";
8272 #endif
8273
8274diff -Naur linux-2.4.26/include/linux/pc_keyb.h linux-2.4.26-m68k/include/linux/pc_keyb.h
8275--- linux-2.4.26/include/linux/pc_keyb.h 1999-10-12 03:15:40.000000000 +1000
8276+++ linux-2.4.26-m68k/include/linux/pc_keyb.h 2003-07-22 07:33:33.000000000 +1000
8277@@ -14,7 +14,11 @@
8278 #define KBD_REPORT_UNKN /* Report unknown scan codes */
8279 #define KBD_REPORT_TIMEOUTS /* Report keyboard timeouts */
8280 #undef KBD_IS_FOCUS_9000 /* We have the brain-damaged FOCUS-9000 keyboard */
8281+#ifndef CONFIG_TEKXP
8282 #undef INITIALIZE_MOUSE /* Define if your PS/2 mouse needs initialization. */
8283+#else
8284+#define INITIALIZE_MOUSE 1
8285+#endif
8286
8287
8288
8289diff -Naur linux-2.4.26/kernel/ptrace.c linux-2.4.26-m68k/kernel/ptrace.c
8290--- linux-2.4.26/kernel/ptrace.c 2003-08-25 21:44:44.000000000 +1000
8291+++ linux-2.4.26-m68k/kernel/ptrace.c 2003-08-26 13:18:26.000000000 +1000
8292@@ -165,7 +165,7 @@
8293 if (write) {
8294 memcpy(maddr + offset, buf, bytes);
8295 flush_page_to_ram(page);
8296- flush_icache_user_range(vma, page, addr, len);
8297+ flush_icache_user_page(vma, page, addr, len);
8298 set_page_dirty(page);
8299 } else {
8300 memcpy(buf, maddr + offset, bytes);
8301diff -Naur linux-2.4.26/mm/bootmem.c linux-2.4.26-m68k/mm/bootmem.c
8302--- linux-2.4.26/mm/bootmem.c 2002-11-29 10:53:15.000000000 +1100
8303+++ linux-2.4.26-m68k/mm/bootmem.c 2002-12-01 01:59:34.000000000 +1100
8304@@ -244,7 +244,7 @@
8305
8306 static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
8307 {
8308- struct page *page = pgdat->node_mem_map;
8309+ struct page *page;
8310 bootmem_data_t *bdata = pgdat->bdata;
8311 unsigned long i, count, total = 0;
8312 unsigned long idx;
8313@@ -253,8 +253,10 @@
8314
8315 count = 0;
8316 idx = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT);
8317- for (i = 0; i < idx; i++, page++) {
8318+ for (i = 0; i < idx; i++) {
8319 if (!test_bit(i, bdata->node_bootmem_map)) {
8320+ page = virt_to_page(phys_to_virt((i << PAGE_SHIFT) +
8321+ bdata->node_boot_start));
8322 count++;
8323 ClearPageReserved(page);
8324 set_page_count(page, 1);
8325diff -Naur linux-2.4.26/mm/page_alloc.c linux-2.4.26-m68k/mm/page_alloc.c
8326--- linux-2.4.26/mm/page_alloc.c 2004-02-19 00:36:32.000000000 +1100
8327+++ linux-2.4.26-m68k/mm/page_alloc.c 2004-02-19 09:19:12.000000000 +1100
8328@@ -720,7 +720,7 @@
8329 * - clear the memory bitmaps
8330 */
8331 void __init free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap,
8332- unsigned long *zones_size, unsigned long zone_start_paddr,
8333+ unsigned long *zones_size, unsigned long zone_start_vaddr,
8334 unsigned long *zholes_size, struct page *lmem_map)
8335 {
8336 unsigned long i, j;
8337@@ -728,7 +728,7 @@
8338 unsigned long totalpages, offset, realtotalpages;
8339 const unsigned long zone_required_alignment = 1UL << (MAX_ORDER-1);
8340
8341- if (zone_start_paddr & ~PAGE_MASK)
8342+ if (zone_start_vaddr & ~PAGE_MASK)
8343 BUG();
8344
8345 totalpages = 0;
8346@@ -758,7 +758,7 @@
8347 }
8348 *gmap = pgdat->node_mem_map = lmem_map;
8349 pgdat->node_size = totalpages;
8350- pgdat->node_start_paddr = zone_start_paddr;
8351+ pgdat->node_start_paddr = __pa(zone_start_vaddr);
8352 pgdat->node_start_mapnr = (lmem_map - mem_map);
8353 pgdat->nr_zones = 0;
8354
8355@@ -835,9 +835,9 @@
8356
8357 zone->zone_mem_map = mem_map + offset;
8358 zone->zone_start_mapnr = offset;
8359- zone->zone_start_paddr = zone_start_paddr;
8360+ zone->zone_start_paddr = __pa(zone_start_vaddr);
8361
8362- if ((zone_start_paddr >> PAGE_SHIFT) & (zone_required_alignment-1))
8363+ if ((zone_start_vaddr >> PAGE_SHIFT) & (zone_required_alignment-1))
8364 printk("BUG: wrong zone alignment, it will crash\n");
8365
8366 /*
8367@@ -852,8 +852,9 @@
8368 SetPageReserved(page);
8369 INIT_LIST_HEAD(&page->list);
8370 if (j != ZONE_HIGHMEM)
8371- set_page_address(page, __va(zone_start_paddr));
8372- zone_start_paddr += PAGE_SIZE;
8373+ set_page_address(page,
8374+ (void *)zone_start_vaddr);
8375+ zone_start_vaddr += PAGE_SIZE;
8376 }
8377
8378 offset += size;
8379@@ -900,7 +901,7 @@
8380
8381 void __init free_area_init(unsigned long *zones_size)
8382 {
8383- free_area_init_core(0, &contig_page_data, &mem_map, zones_size, 0, 0, 0);
8384+ free_area_init_core(0, &contig_page_data, &mem_map, zones_size, PAGE_OFFSET, 0, 0);
8385 }
8386
8387 static int __init setup_mem_frac(char *str)
Note: See TracBrowser for help on using the repository browser.