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

clfs-1.2 clfs-2.1 clfs-3.0.0-systemd clfs-3.0.0-sysvinit systemd sysvinit
Last change on this file since c06e893 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
  • Documentation/Configure.help

    diff -Naur linux-2.4.26/Documentation/Configure.help linux-2.4.26-m68k/Documentation/Configure.help
    old new  
    1716717167  say M here and read <file:Documentation/modules.txt>.  If unsure,
    1716817168  say N.
    1716917169
     17170Amiga SFS file system support
     17171CONFIG_ASFS_FS
     17172  The Amiga Smart FileSystem (SFS) is the file system used on hard
     17173  disks by Amiga(tm) and MorphOS(tm) systems.  Say Y if you want
     17174  to be able to read files from an Amiga SFS partition on your hard
     17175  drive. 
     17176
     17177  This file system driver is in EXPERIMENTAL state. Use it with care.
     17178  Although it CANNOT destroy your data (because it is a read-only
     17179  driver) it MIGHT cause a crash in some circumstances.
     17180
     17181  For more information read <file:Documentation/filesystems/asfs.txt>
     17182
     17183  This file system is also available as a module ( = code which can be
     17184  inserted in and removed from the running kernel whenever you want).
     17185  The module is called affs.o.  If you want to compile it as a module,
     17186  say M here and read <file:Documentation/modules.txt>. 
     17187
     17188  If unsure, say N.
     17189
    1717017190Apple HFS file system support
    1717117191CONFIG_HFS_FS
    1717217192  If you say Y here, you will be able to mount Macintosh-formatted
     
    2335723377
    2335823378  If you don't want to compile a kernel for a Sun 3x, say N.
    2335923379
     23380TekXpress XP2x support
     23381CONFIG_TEKXP
     23382   This option enables support for the TekXpress XP2x series of
     23383   X-Terminals made by Tektronix.
     23384   You will also want to enable 68030 support below.
     23385   Additional information about this port is available at
     23386   <http://www-users.rwth-aachen.de/Michael.Mueller4/tekxp/tekxp.html>.
     23387
     23388   If you don't want to compile a kernel for TekXpress XP2x, say N.
     23389
     23390Kernel command line
     23391CONFIG_BOOTCMD
     23392   You have to specify a kernel commandline here.
     23393   There will be no possiblity to change the content on run-time.
     23394
     23395Report as MVME160
     23396CONFIG_TEKXP_REPORT_MVME
     23397   Enabling this option the TekXpress X-Terminals report as
     23398   Motorola MVME160 in /proc/harware (if available).
     23399
     23400   Say Y, if you intend to use this kernel to install the
     23401   Debian/m68k Linux distribution. Otherwhise it is save to say N.
     23402
    2336023403Sun3x builtin serial support
    2336123404CONFIG_SUN3X_ZS
    2336223405  ZS refers to a type of asynchronous serial port built in to the Sun3
     
    2381023853  If you want to compile it as a module, say M here and read
    2381123854  <file:Documentation/modules.txt>.
    2381223855
     23856TekXpress on-board Sonic support
     23857CONFIG_TEKSONIC
     23858  Say Y here if you want to use the integrated network controller of
     23859  the TekXpress X-Terminals. If you do not modify it it is unlikely
     23860  you will get Linux running without this selected.
     23861
     23862SCC2962 serial support
     23863CONFIG_SCC2692
     23864  Say Y here if you want to use the serial interfaces from user-space.
     23865  It is safe to say N here, if it will only be used for the output of
     23866  kernel messages.
     23867
    2381323868Support for early boot text console
    2381423869CONFIG_BOOTX_TEXT
    2381523870  Say Y here to see progress messages from the boot firmware in text
  • Documentation/filesystems/00-INDEX

    diff -Naur linux-2.4.26/Documentation/filesystems/00-INDEX linux-2.4.26-m68k/Documentation/filesystems/00-INDEX
    old new  
    66        - info and mount options for the Acorn Advanced Disc Filing System.
    77affs.txt
    88        - info and mount options for the Amiga Fast File System.
     9asfs.txt
     10        - info and mount options for the Amiga Smart File System.
    911befs.txt
    1012        - info for the BeOS file system (BFS)
    1113bfs.txt
  • Documentation/filesystems/asfs.txt

    diff -Naur linux-2.4.26/Documentation/filesystems/asfs.txt linux-2.4.26-m68k/Documentation/filesystems/asfs.txt
    old new  
     1
     2Amiga SmartFileSystem, Linux implementation
     3===========================================
     4
     5This is a simple read-only driver. It support reading files and directories.
     6Symbolic links (called soft links) are not supported yet. Don't even try
     7to read them.
     8
     9
     10Mount options for the ASFS
     11==========================
     12
     13setuid[=uid]   
     14                This sets the owner of all files and directories in the file
     15                system to uid or the uid of the current user, respectively.
     16
     17setgid[=gid]   
     18                Same as above, but for gid.
     19
     20mode=mode       
     21                Sets the mode flags to the given (octal) value. Directories
     22                will get an x permission if the corresponding r bit is set.
     23                The default mode is 0444, which means all r bits are set
     24                (for directories this means also that all x bits are set).
     25
     26
     27Other information
     28=================
     29
     30Supported block sizes are: 512, 1024, 2048 and 4096 bytes. Larger blocks
     31speed up almost everything at the expense of wasted disk space. The speed
     32gain above 4K seems not really worth the price, so you don't lose too
     33much here, either.
     34
     35This file system hasn't been well tested yet. Athough it CANNOT destroy
     36your data, it MIGHT cause a crash. Sorry.
     37
     38This file system has been tested on Motorola PPC and Intel x86 systems.
     39It SHOULD also work on Motorola 68k. It probably WON'T work on other
     40systems (especially 64bit).
  • arch/m68k/Makefile

    diff -Naur linux-2.4.26/arch/m68k/Makefile linux-2.4.26-m68k/arch/m68k/Makefile
    old new  
    119119SUBDIRS := $(SUBDIRS) arch/m68k/sun3 arch/m68k/sun3/prom
    120120endif
    121121
     122ifdef CONFIG_TEKXP
     123CORE_FILES := $(CORE_FILES) arch/m68k/tekxp/tekxp.o
     124SUBDIRS := $(SUBDIRS) arch/m68k/tekxp
     125endif
     126
    122127ifdef CONFIG_M68040
    123128CORE_FILES := $(CORE_FILES) arch/m68k/fpsp040/fpsp.o
    124129SUBDIRS := $(SUBDIRS) arch/m68k/fpsp040
     
    172177        rm -f arch/m68k/kernel/m68k_defs.h arch/m68k/kernel/m68k_defs.d
    173178
    174179archmrproper:
     180        rm -f arch/m68k/boot/bootstrap bootstrap
    175181
    176182archdep:
  • arch/m68k/boot/Makefile

    diff -Naur linux-2.4.26/arch/m68k/boot/Makefile linux-2.4.26-m68k/arch/m68k/boot/Makefile
    old new  
     1
     2ifdef CONFIG_TEKXP
     3.PHONY: bootstrap
     4bootstrap: boot.o
     5        $(LD) -T tekxp.ld -Ttext 0x1000 -o $@ $<
     6        -rm -f ../../../bootstrap
     7        dd if=$@ of=../../../bootstrap bs=4096 conv=sync
     8        $(STRIP) -s -o vmlinux.s ../../../vmlinux
     9        cat vmlinux.s >> ../../../bootstrap
     10
     11boot.o: boot.S
     12        $(CC) -c -o $@ -m68030 -O2 -I$(HPATH) -D__ASSEMBLY__ -DDEBUG $<
     13
     14endif
     15
  • arch/m68k/boot/boot.S

    diff -Naur linux-2.4.26/arch/m68k/boot/boot.S linux-2.4.26-m68k/arch/m68k/boot/boot.S
    old new  
     1/*
     2 *  linux/arch/m68k/boot/boot.S
     3 *
     4 *  Copyright (C) 2002,2003 Michael Mueller <malware@t-online.de>
     5 *
     6 *  Parts taken from head.S.
     7 *
     8 * This file is subject to the terms and conditions of the GNU General Public
     9 * license. See the file COPYING in the main directory of this archive for
     10 * more details.
     11 */
     12
     13/*
     14 * This is a wrapper to the linux kernel. Compiled as a.out binary it can be
     15 * used to bootstrap the Linux kernel using the TekXpress Boot Monitor.
     16 *
     17 * In general it does copy the kernel image to the end of the available
     18 * memory and does rearrange it to the top memory as described within the
     19 * ELF header of wrapped vmlinux file.
     20 *
     21 * On some of the TekXpress systems there is not enough continous memory
     22 * available to fit the whole kernel into. Thus this code does enable the
     23 * MMU which is rather unusual.
     24 */
     25 
     26#include <linux/config.h>
     27#include <linux/linkage.h>
     28#include <linux/init.h>
     29#include <asm/bootinfo.h>
     30#include <asm/setup.h>
     31#include <asm/pgtable.h>
     32#include <asm/page.h>
     33
     34/***********************************************************************/
     35
     36/*
     37 *  Little helpers for defining functions
     38 */
     39
     40#ifdef __STDC__
     41#define L(name) .L##name
     42#else
     43#define L(name) .L/**/name
     44#endif
     45
     46#define STACK   %a6@(stackstart)
     47#define ARG0    %a6@(4)
     48#define ARG1    %a6@(8)
     49#define ARG2    %a6@(12)
     50#define ARG3    %a6@(16)
     51#define ARG4    %a6@(20)
     52
     53.macro  func_start      name,saveregs,stack=0
     54L(\name):
     55        linkw   %a6,#-\stack
     56        moveml  \saveregs,%sp@-
     57.set    stackstart,-\stack
     58
     59.macro  func_return_\name
     60        moveml  %sp@+,\saveregs
     61        unlk    %a6
     62        rts
     63.endm
     64.endm
     65
     66.macro  func_return     name
     67        func_return_\name
     68.endm
     69
     70.macro  func_call       name
     71        jbsr    L(\name)
     72.endm
     73
     74.macro  move_stack      nr,arg1,arg2,arg3,arg4
     75.if     \nr
     76        move_stack      "(\nr-1)",\arg2,\arg3,\arg4
     77        movel   \arg1,%sp@-
     78.endif
     79.endm
     80
     81.macro  func_define     name,nr=0
     82.macro  \name   arg1,arg2,arg3,arg4
     83        move_stack      \nr,\arg1,\arg2,\arg3,\arg4
     84        func_call       \name
     85.if     \nr
     86        lea     %sp@(\nr*4),%sp
     87.endif
     88.endm
     89.endm
     90
     91/***********************************************************************/
     92
     93/*
     94 * Start of the code (not entry point!)
     95 */
     96.text
     97ENTRY(_stext)
     98
     99/*
     100 * This is a faked a.out Header
     101 */
     102.long   0x10B                   /* a.out magic number */
     103.long   SYMBOL_NAME(__end) - header_end
     104                                /* size of content = size of text segment */
     105.long   0
     106.long   0
     107.long   0
     108.long   SYMBOL_NAME(__start)    /* entry point */
     109.long   0
     110.long   0
     111header_end:
     112
     113/*
     114 * Platform specific constants
     115 */
     116#define MEMSTART        0xF0000000      /* start address of CPU RAM */
     117#define OPTRAMSTART     0xF4000000      /* start address of Option RAM */
     118#define MEMCHUNK        0x01000000      /* spacing beetween memory chunks */
     119#define MEMORY_MAP_ENTRIES      8       /* number of memory chunks */
     120
     121/*
     122 * MMU definitions
     123 */
     124PAGESIZE                = 4096
     125PAGESHIFT               = 12
     126ROOT_TABLE_SIZE         = 128
     127PTR_TABLE_SIZE          = 128
     128PAGE_TABLE_SIZE         = 64
     129ROOT_INDEX_SHIFT        = 25
     130PTR_INDEX_SHIFT         = 18
     131PAGE_INDEX_SHIFT        = 12
     132
     133/*
     134 * Function declarations
     135 */
     136func_define     mmu_map,4
     137func_define     mmu_get_root_table_entry,1
     138func_define     mmu_get_ptr_table_entry,2
     139func_define     build_memory_list
     140func_define     dump_memory_list
     141func_define     get_kernel_size
     142func_define     get_kernel_start
     143func_define     get_kernel_physical_headers
     144func_define     get_kernel_entry
     145
     146/*
     147 * Translation tables.
     148 *
     149 * These have to be located at the same position as within head.S. As
     150 * they are references from the kernel later.
     151 */
     152.equ    SYMBOL_NAME(kernel_pg_dir),SYMBOL_NAME(_stext)
     153.equ    SYMBOL_NAME(kernel_ptr_dir1),SYMBOL_NAME(kernel_pg_dir)+ROOT_TABLE_SIZE*4
     154.equ    SYMBOL_NAME(kernel_ptr_dir2),SYMBOL_NAME(kernel_ptr_dir1)+PTR_TABLE_SIZE*4
     155.equ    SYMBOL_NAME(kernel_ptr_dir3),SYMBOL_NAME(kernel_ptr_dir2)+PTR_TABLE_SIZE*4
     156.equ    SYMBOL_NAME(kernel_ptr_dir4),SYMBOL_NAME(kernel_ptr_dir3)+PTR_TABLE_SIZE*4
     157.equ    .,SYMBOL_NAME(_stext)+PAGESIZE /* Skip to end of page */
     158
     159/*
     160 * Functions for debugging output
     161 */
     162func_define serial_init
     163func_define putc,1
     164func_define putn,1
     165func_define puts,1
     166func_define dump,2
     167
     168.macro  dputc   ch
     169#ifdef DEBUG
     170        putc    \ch
     171#endif
     172.endm
     173
     174.macro putr
     175        putc    '\r'
     176        putc    '\n'
     177.endm
     178
     179.macro dputr
     180#ifdef DEBUG
     181        putr
     182#endif
     183.endm
     184
     185.macro dputn    nr
     186#ifdef DEBUG
     187        putn    \nr
     188#endif
     189.endm
     190
     191.macro  puts    string
     192        .data
     193.Lstr\@:
     194        .asciz  "\string"
     195        .previous
     196        pea     %pc@(.Lstr\@)
     197        func_call       puts
     198        addql   #4,%sp
     199.endm
     200
     201.macro dputs    string
     202#ifdef DEBUG
     203        puts    "\string"
     204#endif
     205.endm
     206
     207func_start      puts,%d0/%a0
     208        movl    ARG1,%a0
     2091:
     210        movb    %a0@+,%d0
     211        beqs    2f
     212        putc    %d0
     213        bras    1b
     2142:
     215func_return     puts
     216
     217func_start      putn,%d0-%d2
     218        movl    ARG1,%d0
     219        movl    #7,%d1
     2201:
     221        roll    #4,%d0
     222        movl    %d0,%d2
     223        andb    #15,%d2
     224        addb    #'0',%d2
     225        cmpb    #'9',%d2
     226        jls     2f
     227        addb    #'A'-('9'+1),%d2
     2282:
     229        putc    %d2
     230        dbra    %d1,1b
     231        putc    #' '
     232func_return     putn
     233
     234func_start      putc,%d0/%a0
     235        movl    #0xFF800000,%a0
     2361:
     237        movb    4(%a0),%d0
     238        andb    #4,%d0
     239        tstb    %d0
     240        bne     2f
     241        bra     1b
     2422:
     243        movl    ARG1,%d0
     244        movb    %d0,12(%a0)
     245func_return     putc
     246
     247func_start      dump,%d0/%a0
     248        movl    ARG1,%a0
     249        movl    ARG2,%d0
     2501:
     251        putn    %a0
     252        putn    %a0@
     253        putn    %a0@(4)
     254        putn    %a0@(8)
     255        putn    %a0@(12)
     256        putn    %a0@(16)
     257        putn    %a0@(20)
     258        putn    %a0@(24)
     259        putn    %a0@(28)
     260        putc    #'\r'   
     261        putc    #'\n'   
     262        addl    #32,%a0
     263        subl    #32,%d0
     264        bpl     1b
     265func_return     dump
     266
     267func_start      serial_init,%a0
     268        movl    #0xFF800000,%a0         /* address of UART */
     269        clrb    0x34(%a0)
     270        movb    #0x80,0x10(%a0)         /* ACR: baud rate set 2 */
     271        clrb    0x14(%a0)               /* reset interrupt mask */
     272        movb    #0x10,8(%a0)            /* CRA: reset MR pointer */
     273        movb    #0x20,8(%a0)
     274        movb    #0x30,8(%a0)
     275        movb    #2,(%a0)                /* 7 bits per char */
     276        movb    #7,(%a0)                /* one stop bit */
     277        movb    #0xBB,4(%a0)            /* 9600 baud */
     278        movb    #5,8(%a0)               /* enable tx and rx */
     279func_return     serial_init
     280
     281.macro  putc    ch
     282        pea     \ch
     283        func_call       putc
     284        addql   #4,%sp
     285.endm
     286
     287
     288
     289/*
     290 * Entry into the code
     291 */
     292ENTRY(__start)
     293
     294        /* Use the first 256 byte of memory as scratch area
     295         */
     296        movl    #MEMSTART+0x100, %sp
     297
     298        /* Initialize the serial port
     299         */
     300        serial_init
     301        dputs   "\r\nLinux@TekXP starting...\r\n"
     302
     303        /* Build a memory map for later usage
     304         */
     305        putc    'a'
     306        build_memory_list
     307/*      dump_memory_list        */
     308
     309        /* Clear the translation tables
     310         */
     311        dputc   'b'
     312        movl    #PAGESIZE/4-1,%d0
     313        lea     %pc@(SYMBOL_NAME(kernel_pg_dir)),%a0
     3141:
     315        clrl    %a0@+
     316        dbra    %d0,1b
     317
     318        /* Setup pointer tables for virtual addresses starting at 0 and
     319         * the current PC.
     320         * We need 4 pointer tables at maximum for 128MB.
     321         * Since both memory ranges should map equal we simple use the
     322         * same pointer tables for both.
     323         */
     324        dputc   'c'
     325        lea     %pc@(SYMBOL_NAME(_stext)),%a0
     326        movl    %a0,%d0
     327        movl    #ROOT_INDEX_SHIFT,%d1
     328        lsrl    %d1,%d0
     329
     330        lea     %pc@(SYMBOL_NAME(kernel_pg_dir)),%a0
     331        lea     %pc@(SYMBOL_NAME(kernel_ptr_dir1)+_PAGE_TABLE+_PAGE_ACCESSED),%a1
     332        movl    %a1,%a0@(%d0:l:4)
     333        movl    %a1,%a0@+
     334        lea     %pc@(SYMBOL_NAME(kernel_ptr_dir2)+_PAGE_TABLE+_PAGE_ACCESSED),%a1
     335        movl    %a1,%a0@(%d0:l:4)
     336        movl    %a1,%a0@+
     337        lea     %pc@(SYMBOL_NAME(kernel_ptr_dir3)+_PAGE_TABLE+_PAGE_ACCESSED),%a1
     338        movl    %a1,%a0@(%d0:l:4)
     339        movl    %a1,%a0@+
     340        lea     %pc@(SYMBOL_NAME(kernel_ptr_dir4)+_PAGE_TABLE+_PAGE_ACCESSED),%a1
     341        movl    %a1,%a0@(%d0:l:4)
     342        movl    %a1,%a0@+
     343
     344        /* Setup early terminator pages for hardware access */
     345        dputc   'd'
     346        lea     %pc@(SYMBOL_NAME(kernel_pg_dir) + 127*4),%a1
     347        movl    #0xFE000000+_PAGE_PRESENT+_PAGE_ACCESSED+_PAGE_DIRTY+_PAGE_NOCACHE030,%d1
     348        movl    %d1,%a1@
     349
     350        /* Map the memory to appear linear
     351         */
     352        dputc   'e'
     353        clrl    %d0             /* virtual address */
     354        lea     %pc@(Lmemory_list),%a0
     3551:
     356        movl    %a0@+,%a1       /* address */
     357        movl    %a0@+,%d1       /* size */
     358        tstl    %a1
     359        beqs    2f
     360        mmu_map %d0,%a1,%d1,#_PAGE_NOCACHE030
     361        addl    %d1,%d0
     362        bras    1b
     3632:
     364        lea     %pc@(Lmemory_last),%a0
     365        movl    %d0,%a0@
     366
     367#if 0
     368        lea     %pc@(SYMBOL_NAME(kernel_pg_dir)),%a0
     369        dump    %a0,#PAGESIZE
     370#endif
     371
     372        /* Enable the MMU
     373         */
     374        dputc   'f'
     375        .chip   68030
     376        lea     %pc@(Lmmu_engage_030_temp),%a0
     377        movel   #0x80000002,%a0@
     378        lea     %pc@(SYMBOL_NAME(kernel_pg_dir)),%a1
     379        movl    %a1,%a0@(4)
     380        movl    #0x0808,%d0
     381        movec   %d0,%cacr
     382        pmove   %a0@,%srp
     383        pflusha
     384        movl    #0x82c07760,%a0@(8)
     385        pmove   %a0@(8),%tc
     386        jmp     1f:l
     3871:
     388        movl    #0x0808,%d0
     389        movec   %d0,%cacr
     390        pflusha
     391        .chip   68k
     392
     393        /* Fix the stack
     394         */
     395        movl    #0x100,%sp
     396
     397        /* Remove the now unneeded mappings (5 mappings remain, 4 at top) */
     398        dputc   'g'
     399        movl    #SYMBOL_NAME(kernel_pg_dir)+16,%a0
     400        movl    #ROOT_TABLE_SIZE-6,%d0
     4011:
     402        clrl    %a0@+
     403        dbra    %d0,1b
     404
     405        /* Move yourself and the kernel to end of the memory
     406         */
     407        dputc   'h'
     408        get_kernel_size
     409        addl    #SYMBOL_NAME(__end)+4095,%d0
     410        andl    #-PAGESIZE,%d0
     411        movl    Lmemory_last,%a1
     412        subl    %d0,%a1
     413        movl    %a1,Lmemory_last
     414        movl    #0,%a0
     415        lsrl    #2,%d0
     4161:
     417        subl    #1,%d0
     418        bmi     2f
     419        movl    %a0@+,%a1@+
     420        bras    1b
     4212:
     422        movl    Lmemory_last,%a0
     423        jmpl    %a0@(3f)
     424
     4253:
     426        dputc   'i'
     427
     428        /*
     429         * Loop through the sections of the kernel and copy them over.
     430         */
     431
     432        get_kernel_start                /* in %a0 */
     433        movel   %a0,%a1                 /* offset of all numbers */
     434        clrl    %d3                     /* end of bss */
     435
     436        get_kernel_physical_headers      /* count in d0, first in %a0 */
     437        subl    #32,%a0
     438
     4391:
     440        dputc   'j'
     441        subl    #1,%d0
     442        bmi     5f
     443        addl    #32,%a0
     444
     445        movel   %a0@(4),%a2     /* file offset */
     446        addl    %a1,%a2         /* current memory address */
     447       
     448        movel   %a0@(8),%a3     /* load memory address */
     449        movel   %a0@(16),%d1    /* file size */
     450        movel   %a0@(20),%d2    /* memory size */
     451
     452        cmpl    #SYMBOL_NAME(_stext)+PAGESIZE,%a3
     453        bpl     2f
     454
     455        movl    #SYMBOL_NAME(_stext)+PAGESIZE,%d3
     456        subl    %a3,%d3         /* how much is below */
     457
     458        addl    %d3,%a3         /* move it up */
     459        addl    %d3,%a2         /* move it up */
     460
     461        subl    %d3,%d2
     462        bmi     1b              /* nothing left */
     463
     464        subl    %d3,%d1
     465        bmi     4f
     4662:
     467        subl    %d1,%d2         /* do not clear what is in file */
     468        bpl     3f
     469        addl    %d1,%d2
     470        movl    %d2,%d1
     471        clrl    %d2
     472
     4733:
     474        subl    #1,%d1
     475        bmi     4f
     476        moveb   %a2@+,%a3@+
     477        bras    3b
     478
     4794:      /* clear */
     480        lea     %a3@(%d2),%a4
     481        cmpl    %a4,%d3
     482        bpl     4f
     483        movl    %a4,%d3
     4844:
     485
     486        subl    #1,%d2
     487        bmi     1b
     488        clrb    %a3@+
     489        bras    4b
     4905:
     491
     492        /*
     493         * Create a boot info record
     494         */
     495        dputc   'k'
     496        addl    #PAGESIZE-1,%d3
     497        andl    #-PAGE_SIZE,%d3
     498        movl    %d3,%a0
     499
     500        movw    #BI_MACHTYPE,%a0@+
     501        movw    #8,%a0@+
     502        movl    #MACH_TEKXP,%a0@+
     503
     504        movw    #BI_CPUTYPE,%a0@+
     505        movw    #8,%a0@+
     506        movl    #CPU_68030,%a0@+
     507
     508        movw    #BI_FPUTYPE,%a0@+
     509        movw    #8,%a0@+
     510        movl    #0,%a0@+
     511
     512        movw    #BI_MMUTYPE,%a0@+
     513        movw    #8,%a0@+
     514        movl    #MMU_68030,%a0@+
     515
     516        lea     %pc@(Lmemory_list),%a1
     5171:
     518        movel   %a1@+,%d1
     519        movel   %a1@+,%d0
     520        tstl    %d1
     521        beqs    2f
     522        movw    #BI_MEMCHUNK,%a0@+
     523        movw    #12,%a0@+
     524        movl    %d1,%a0@+
     525        movl    %d0,%a0@+
     526        bras    1b
     5272:
     528
     529        movw    #BI_LAST,%a0@+
     530        clrw    %a0@+
     531
     532        /* jump into the kernel */
     533        dputc   'l'
     534        get_kernel_entry
     535        jmpl    %a0@
     536
     537/*
     538 * Get the position of the kernels ELF header. It is located on the next
     539 * page after this wrapper program.
     540 */
     541
     542func_start      get_kernel_start,%d0
     543        lea     %pc@(__end+PAGESIZE-1),%a0
     544        movl    %a0,%d0
     545        andl    #-PAGESIZE,%d0
     546        movl    %d0,%a0
     547func_return     get_kernel_start
     548
     549/*
     550 * Read the entry point of the ELF executable.
     551 */
     552
     553func_start      get_kernel_entry,%d0
     554        get_kernel_start
     555        movl    %a0@(0x18),%a0
     556func_return     get_kernel_entry
     557
     558/*
     559 * Get the address of the first physical header (into %a0) and the number
     560 * of those headers present (into %d0).
     561 */
     562func_start      get_kernel_physical_headers,%d1
     563        get_kernel_start
     564        clrl    %d0
     565        movw    %a0@(0x2C),%d0          /* Number of headers */
     566        movl    %a0@(0x1C),%d1          /* Offset of the table */
     567        lea     %a0@(%d1),%a0
     568func_return     get_kernel_physical_headers
     569
     570/*
     571 * Calculate the size kernel image. Notice this is not its final footprint.
     572 */
     573func_start      get_kernel_size,%d1/%d2/%a0
     574        get_kernel_physical_headers
     575        clrl    %d1
     5761:
     577        subl    #1,%d0
     578        bmi     3f
     579        movl    %a0@(4),%d2
     580        addl    %a0@(16),%d2
     581        cmpl    %d2,%d1
     582        bpl     2f
     583        movl    %d2,%d1
     5842:
     585        addl    #32,%a0
     586        bras    1b
     5873:
     588        movl    %d1,%d0
     589func_return     get_kernel_size
     590
     591
     592/*
     593 * Fetch the memory configuration and store it in a field for later
     594 * retrieval.
     595 */
     596func_start      build_memory_list,%a2/%a4/%d0/%d1
     597        lea     %pc@(Lmemory_list),%a4
     598
     599        movl    #MEMSTART,%a2
     600        bfextu  0xFFD00003{4:4},%d0
     601        movl    %pc@(Lcpsram_bitmap_table,%d0:l:4),%d0
     6021:
     603        tstl    %d0
     604        beqs    2f
     605        movl    %d0,%d1
     606        andl    #3,%d1
     607        movl    %pc@(Ldram_size_table,%d1:l:4),%d1
     608        movl    %a2,%a4@+
     609        movl    %d1,%a4@+
     610        addl    #MEMCHUNK,%a2
     611        lsrl    #2,%d0
     612        bras    1b
     6132:
     614        bfextu  0xFFD00003{0:1},%d0
     615        tstl    %d0
     616        bnes    4f
     617        movl    #OPTRAMSTART,%a2
     618        bfextu  0xFFD00003{1:3},%d0
     619        movl    %pc@(Lcporam_bitmap_table,%d0:l:4),%d0
     6203:
     621        tstl    %d0
     622        beqs    4f
     623        movl    %d0,%d1
     624        andl    #3,%d1
     625        movl    %pc@(Ldram_size_table,%d1:l:4),%d1
     626        movl    %a2,%a4@+
     627        movl    %d1,%a4@+
     628        addl    #MEMCHUNK,%a2
     629        lsrl    #2,%d0
     630        bras    3b
     6314:
     632func_return     build_memory_list
     633
     634Ldram_size_table:
     635        .long   0
     636        .long   0x100000
     637        .long   0x400000
     638        .long   0x040000
     639
     640Lcporam_bitmap_table:
     641        .long   0xAA
     642        .long   0x2A
     643        .long   0x0A
     644        .long   0x02
     645        .long   0x55
     646        .long   0x05
     647        .long   0x01
     648        .long   0x15
     649
     650Lcpsram_bitmap_table:
     651        .long   0x95
     652        .long   0x01
     653        .long   0x05
     654        .long   0x15
     655        .long   0x55
     656        .long   0x06
     657        .long   0x16
     658        .long   0x56
     659        .long   0x0A
     660        .long   0x1A
     661        .long   0x5A
     662        .long   0xA5
     663        .long   0x2A
     664        .long   0x6A
     665        .long   0x02
     666        .long   0xAA
     667
     668
     669/*
     670 * Memory mapping functions from head.S. (shortened)
     671 */
     672
     673func_start      mmu_map,%d0-%d4/%a0-%a4
     674        /* Get the logical address, it is assumed to be rounded to 256KiB */
     675        movl    ARG1,%a3
     676
     677        /* Get the end address. The length should be rounded to 256KiB */
     678        movl    %a3,%a4
     679        addl    ARG3,%a4
     680        subql   #1,%a4
     681
     682        /* Get the physical address, assumed to be rounded to 256KiB too */
     683        movl    ARG2,%a2
     684
     685        /* Augment the physical address with page attributes */
     686        movl    ARG4,%d0
     687        orw     #_PAGE_PRESENT+_PAGE_ACCESSED+_PAGE_DIRTY,%d0
     688        addw    %d0,%a2
     689
     6901:
     691        /* Calculate the offset into the root table */
     692        movl    %a3,%d0
     693        movl    #ROOT_INDEX_SHIFT,%d1
     694        lsrl    %d1,%d0
     695        mmu_get_root_table_entry        %d0
     696
     697        /* Calculate the offset into the pointer table */
     698        movl    %a3,%d0
     699        movl    #PTR_INDEX_SHIFT,%d1
     700        lsrl    %d1,%d0
     701        andl    #PTR_TABLE_SIZE-1,%d0
     702        mmu_get_ptr_table_entry         %a0,%d0
     703
     704
     705        movl    %a2,%a0@
     706        addl    #PAGE_TABLE_SIZE*PAGESIZE,%a2
     707        addl    #PAGE_TABLE_SIZE*PAGESIZE,%a3
     708
     709        lea     %a3@(-1),%a0
     710        cmpl    %a0,%a4
     711        jhi     1b
     712       
     713func_return     mmu_map
     714       
     715func_start      mmu_get_root_table_entry,%d0
     716        movl    ARG1,%d0
     717        lea     %pc@(SYMBOL_NAME(kernel_pg_dir),%d0:l:4),%a0
     718func_return     mmu_get_root_table_entry
     719
     720func_start      mmu_get_ptr_table_entry,%d0
     721        movl    ARG1,%a0
     722        movl    %a0@,%d0
     723        andw    #-PTR_TABLE_SIZE,%d0
     724        movl    %d0,%a0
     725        movl    ARG2,%d0
     726        lea     %a0@(%d0:l:4),%a0
     727func_return     mmu_get_ptr_table_entry
     728       
     729
     730
     731
     732.data
     733Lmmu_engage_030_temp:
     734        .space 12
     735
     736Lmemory_last:
     737        .long   0               /* end of virtual memory */
     738
     739Lmemory_list:
     740        .rept   MEMORY_MAP_ENTRIES
     741        .long   0                       /* address */
     742        .long   0                       /* size */
     743        .endr
     744
  • arch/m68k/boot/tekxp.ld

    diff -Naur linux-2.4.26/arch/m68k/boot/tekxp.ld linux-2.4.26-m68k/arch/m68k/boot/tekxp.ld
    old new  
     1OUTPUT_FORMAT("binary")
     2ENTRY(__start)
     3SECTIONS
     4{
     5  .text :
     6  {
     7    *(.init)
     8    *(.text)
     9     ___CTOR_LIST__ = .;
     10     LONG((___CTOR_END__ - ___CTOR_LIST__) / 4 - 2)
     11     *(.ctors)
     12     LONG(0)
     13     ___CTOR_END__ = .;
     14     ___DTOR_LIST__ = .;
     15     LONG((___DTOR_END__ - ___DTOR_LIST__) / 4 - 2)
     16     *(.dtors)
     17     LONG(0)
     18     ___DTOR_END__ = .;
     19    *(.fini)
     20     etext  =  .;
     21     __etext  =  .;
     22  }
     23  .data  SIZEOF(.text) + ADDR(.text) :
     24  {
     25    *(.data .data2)
     26     edata  =  .;
     27     __edata  =  .;
     28  }
     29  .bss  SIZEOF(.data) + ADDR(.data) :
     30  {
     31    *(.bss)
     32    *(COMMON)
     33     end = .;
     34     __end = .;
     35  }
     36}
  • arch/m68k/config.in

    diff -Naur linux-2.4.26/arch/m68k/config.in linux-2.4.26-m68k/arch/m68k/config.in
    old new  
    5656fi
    5757bool 'Sun3x support' CONFIG_SUN3X
    5858bool 'Sun3 support' CONFIG_SUN3
    59  
     59bool 'TekXpress 2x support' CONFIG_TEKXP
     60if [ "$CONFIG_TEKXP" = "y" ] ; then
     61   define_bool CONFIG_PSMOUSE y
     62   define_bool CONFIG_NO_CMDLINE y
     63   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"
     64   bool '  Report as MVME160' CONFIG_TEKXP_REPORT_MVME
     65fi
     66 
    6067bool 'Q40/Q60 support' CONFIG_Q40
    6168
    6269comment 'Processor type'
     
    365372         fi
    366373         dep_tristate 'NE2000/NE1000 support' CONFIG_NE2000 m
    367374      fi
     375      if [ "$CONFIG_TEKXP" = "y" ]; then
     376        bool '  TekXpress on-board Sonic support' CONFIG_TEKSONIC
     377      fi
    368378   fi
    369379   endmenu
    370380
     
    474484   define_tristate CONFIG_SERIAL $CONFIG_DN_SERIAL
    475485fi
    476486
     487if [ "$CONFIG_TEKXP" = "y" ] ; then
     488   tristate 'SCC2962 serial support' CONFIG_SCC2692
     489fi
     490
    477491if [ "$CONFIG_SUN3" = "y" -o "$CONFIG_SUN3X" = "y" ]; then
    478492   bool 'Sun3/3x builtin serial support' CONFIG_SUN3X_ZS
    479493else
     
    499513     "$CONFIG_SUN3X_ZS" = "y" -o "$CONFIG_SERIAL" = "y" -o \
    500514     "$CONFIG_MVME147_SCC" -o "$CONFIG_SERIAL167" = "y" -o \
    501515     "$CONFIG_MVME162_SCC" -o "$CONFIG_BVME6000_SCC" = "y" -o \
    502      "$CONFIG_DN_SERIAL" ]; then
     516     "$CONFIG_DN_SERIAL" = "y" -o "$CONFIG_SCC2692" = "y" ]; then
    503517   bool 'Support for serial port console' CONFIG_SERIAL_CONSOLE
    504518fi
    505519bool 'Support for user serial device modules' CONFIG_USERIAL
  • arch/m68k/kernel/head.S

    diff -Naur linux-2.4.26/arch/m68k/kernel/head.S linux-2.4.26-m68k/arch/m68k/kernel/head.S
    old new  
    3939 * Disabled caches
    4040 * Put us in supervisor state.
    4141 *
     42 * On TekXpress (CONFIG_TEKXP) the boat loader enables the MMU since
     43 * there might not be enough physically continues memory available
     44 * for the kernel (e.g. 6 x 1MB memory configuration). The mapping is
     45 * 1:1 for the first chunk of physical memory and does use the same
     46 * table sizes as the temporary memory map used during enabling the MMU.
     47 *
    4248 * The kernel setup code takes the following steps:
    4349 * .  Raise interrupt level
    4450 * .  Set up initial kernel memory mapping.
     
    480486        addql   #4,%sp
    481487.endm
    482488
     489.macro  get_bi_record_continue  record,recsize,binfo
     490        movel   \binfo,%sp@-
     491        movel   \recsize,%sp@-
     492        pea     \record
     493        func_call       get_bi_record_continue
     494        addl    #12,%sp
     495.endm
     496
    483497func_define     serial_putc,1
    484498func_define     console_putc,1
    485499
     
    543557#define is_not_apollo(lab) cmpl &MACH_APOLLO,%pc@(m68k_machtype); jne lab
    544558#define is_not_q40(lab) cmpl &MACH_Q40,%pc@(m68k_machtype); jne lab
    545559#define is_not_sun3x(lab) cmpl &MACH_SUN3X,%pc@(m68k_machtype); jne lab
     560#define is_not_tekxp(lab) cmpl &MACH_TEKXP,%pc@(m68k_machtype); jne lab
    546561
    547562#define hasnt_leds(lab) cmpl &MACH_HP300,%pc@(m68k_machtype); \
    548563                        jeq 42f; \
     
    587602        .long   MACH_BVME6000, BVME6000_BOOTI_VERSION
    588603        .long   MACH_MAC, MAC_BOOTI_VERSION
    589604        .long   MACH_Q40, Q40_BOOTI_VERSION     
     605        .long   MACH_TEKXP, TEKXP_BOOTI_VERSION
    590606        .long   0
    5916071:      jra     SYMBOL_NAME(__start)
    592608
     
    9931009
    9941010        leds    0x4
    9951011
     1012#ifdef CONFIG_TEKXP
     1013        is_not_tekxp(5f)
     1014
     1015        get_bi_record   BI_LAST
     1016        addw    #PAGESIZE-1,%a0
     1017        movel   %a0,%d2
     1018        andw    #-PAGESIZE,%d2
     1019
     1020        /* Convert it into a physical address */
     1021        movl    %d2,%d1
     1022        get_bi_record   BI_MEMCHUNK
     10231:
     1024        cmpl    #-1,%d0
     1025        beqs    2f
     1026        subl    %a0@(4),%d1
     1027        bcs     4f
     1028        get_bi_record_continue  BI_MEMCHUNK,%d0,%a0
     1029        bras    1b
     10304:
     1031        movl    %d1,%d0
     1032        addl    %a0@(4),%d0
     1033        addl    %a0@,%d0
     1034        bras    3f
     10352:
     1036        movl    %d2,%d0
     10373:
     1038
     1039        movel   %d0,availmem
     1040
     1041        /* Skip all the MMU stuff here */
     1042        bra     L(engage_done)
     10435:
     1044#endif
     1045
    9961046/*
    9971047 *      mmu_init
    9981048 *
     
    13101360
    13111361        putc    'P'
    13121362        mmu_map         #0x80000000,#0,#0x02000000,#_PAGE_NOCACHE030
    1313        
    1314 L(notapollo):   
    13151363        jbra    L(mmu_init_done)
     1364
     1365L(notapollo):   
    13161366#endif
    13171367
     1368#ifdef CONFIG_TEKXP
     1369        is_not_tekxp(L(nottekxp))
     1370
     1371        putc    'P'
     1372        mmu_map_tt      #0,#0xff000000,#0x01000000,#_PAGE_NOCACHE030
     1373
     1374L(nottekxp):
     1375#endif
     1376
     1377        jbra    L(mmu_init_done)
     1378
    13181379L(mmu_init_done):
    13191380
    13201381        putc    'G'
     
    14421503
    14431504        movel   L(memory_start),availmem
    14441505
     1506L(engage_done):
     1507
    14451508#ifdef CONFIG_AMIGA
    14461509        is_not_amiga(1f)
    14471510        /* fixup the Amiga custom register location before printing */
     
    15721635 * Returns: d0: size (-1 if not found)
    15731636 *          a0: data pointer (end-of-records if not found)
    15741637 */
    1575 func_start      get_bi_record,%d1
    1576 
    1577         movel   ARG1,%d0
    1578         lea     %pc@(SYMBOL_NAME(_end)),%a0
     1638.macro get_bi_record_core
    15791639#ifndef CONFIG_HP300
    158016401:      tstw    %a0@(BIR_TAG)
    15811641        jeq     3f
     
    15911651        lea     %a0@(BIR_SIZE),%a0
    159216524:
    15931653#endif /* CONFIG_HP300 */
     1654.endm
     1655 
     1656func_start      get_bi_record,%d1
     1657
     1658        movel   ARG1,%d0
     1659        lea     %pc@(SYMBOL_NAME(_end)),%a0
     1660        get_bi_record_core
    15941661func_return     get_bi_record
    15951662
     1663func_start      get_bi_record_continue,%d1
     1664        movl    ARG3,%a0
     1665        addl    ARG2,%a0
     1666        subl    #BIR_DATA,%a0
     1667        movl    ARG1,%d0
     1668        get_bi_record_core
     1669func_return     get_bi_record_continue
    15961670
    15971671/*
    15981672 *      MMU Initialization Begins Here
     
    30203094/* We count on the PROM initializing SIO1 */
    30213095#endif
    30223096
     3097#ifdef CONFIG_TEKXP
     3098#if 0
     3099        is_not_tekxp(1f)
     3100        movl    %a0,-(%sp)
     3101        movl    #0xFF800000,%a0         /* address of UART */
     3102        clrb    0x34(%a0)
     3103        movb    #0x80,0x10(%a0)         /* ACR: baud rate set 2 */
     3104        clrb    0x14(%a0)               /* reset interrupt mask */
     3105        movb    #0x10,8(%a0)            /* CRA: reset MR pointer */
     3106        movb    #0x20,8(%a0)
     3107        movb    #0x30,8(%a0)
     3108        movb    #2,(%a0)                /* 7 bits per char */
     3109        movb    #7,(%a0)                /* one stop bit */
     3110        movb    #0xBB,4(%a0)            /* 9600 baud */
     3111        movb    #5,8(%a0)               /* enable tx and rx */
     3112        movl    (%sp)+,%a0
     3113        bras    L(serial_init_done)
     31141:
     3115#endif
     3116#endif
     3117
    30233118L(serial_init_done):
    30243119func_return     serial_init
    30253120
     
    321533102:
    32163311#endif
    32173312
     3313#ifdef CONFIG_TEKXP
     3314        is_not_tekxp(3f)
     3315        moveml  %a0/%d0-%d1,%sp@-
     3316        movl    #0xFF800000,%a0
     33171:
     3318        movb    4(%a0),%d1
     3319        andb    #4,%d1
     3320        tstb    %d1
     3321        bne     2f
     3322        bra     1b
     33232:
     3324        movb    %d0,12(%a0)
     3325        moveml  %sp@+,%d0-%d1/%a0
     3326        jbra    L(serial_putc_done)
     33273:
     3328#endif
     3329
    32183330L(serial_putc_done):
    32193331func_return     serial_putc
    32203332
  • arch/m68k/kernel/m68k_ksyms.c

    diff -Naur linux-2.4.26/arch/m68k/kernel/m68k_ksyms.c linux-2.4.26-m68k/arch/m68k/kernel/m68k_ksyms.c
    old new  
    5353EXPORT_SYMBOL(mm_cachebits);
    5454#endif
    5555#endif /* !CONFIG_SUN3 */
     56EXPORT_SYMBOL(flush_icache_user_range);
    5657EXPORT_SYMBOL(m68k_debug_device);
    5758EXPORT_SYMBOL(mach_hwclk);
    5859EXPORT_SYMBOL(mach_get_ss);
  • arch/m68k/kernel/setup.c

    diff -Naur linux-2.4.26/arch/m68k/kernel/setup.c linux-2.4.26-m68k/arch/m68k/kernel/setup.c
    old new  
    140140extern void config_hp300(void);
    141141extern void config_q40(void);
    142142extern void config_sun3x(void);
     143extern void config_tekxp(void);
    143144
    144145extern void mac_debugging_short (int, short);
    145146extern void mac_debugging_long  (int, long);
     
    150151
    151152static void __init m68k_parse_bootinfo(const struct bi_record *record)
    152153{
     154#ifdef CONFIG_NO_CMDLINE
     155    strncpy(m68k_command_line, CONFIG_BOOTCMD, CL_SIZE);
     156#endif
     157
    153158    while (record->tag != BI_LAST) {
    154159        int unknown = 0;
    155160        const unsigned long *data = record->data;
     
    354359                config_sun3x();
    355360                break;
    356361#endif
     362#ifdef CONFIG_TEKXP
     363            case MACH_TEKXP:
     364                config_tekxp();
     365                break;
     366#endif
    357367            default:
    358368                panic ("No configuration setup");
    359369        }
  • arch/m68k/mac/iop.c

    diff -Naur linux-2.4.26/arch/m68k/mac/iop.c linux-2.4.26-m68k/arch/m68k/mac/iop.c
    old new  
    261261                } else {
    262262                        iop_base[IOP_NUM_ISM] = (struct mac_iop *) ISM_IOP_BASE_QUADRA;
    263263                }
    264                 iop_base[IOP_NUM_SCC]->status_ctrl = 0;
     264                iop_base[IOP_NUM_ISM]->status_ctrl = 0;
    265265                iop_ism_present = 1;
    266266        } else {
    267267                iop_base[IOP_NUM_ISM] = NULL;
  • arch/m68k/mm/Makefile

    diff -Naur linux-2.4.26/arch/m68k/mm/Makefile linux-2.4.26-m68k/arch/m68k/mm/Makefile
    old new  
    99
    1010O_TARGET := mm.o
    1111
    12 obj-y           := init.o fault.o extable.o hwtest.o
     12obj-y           := cache.o init.o fault.o extable.o hwtest.o
    1313
    1414ifndef CONFIG_SUN3
    1515obj-y           += kmap.o memory.o motorola.o
  • arch/m68k/mm/cache.c

    diff -Naur linux-2.4.26/arch/m68k/mm/cache.c linux-2.4.26-m68k/arch/m68k/mm/cache.c
    old new  
     1/*
     2 *  linux/arch/m68k/mm/cache.c
     3 *
     4 *  Instruction cache handling
     5 *
     6 *  Copyright (C) 1995  Hamish Macdonald
     7 */
     8
     9#include <linux/pagemap.h>
     10
     11#include <asm/traps.h>
     12
     13
     14static unsigned long virt_to_phys_slow(unsigned long vaddr, mm_segment_t fs)
     15{
     16        if (CPU_IS_060) {
     17                mm_segment_t old_fs = get_fs();
     18                unsigned long paddr;
     19
     20                set_fs(fs);
     21
     22                /* The PLPAR instruction causes an access error if the translation
     23                 * is not possible. To catch this we use the same exception mechanism
     24                 * as for user space accesses in <asm/uaccess.h>. */
     25                asm volatile (".chip 68060\n"
     26                              "1: plpar (%0)\n"
     27                              ".chip 68k\n"
     28                              "2:\n"
     29                              ".section .fixup,\"ax\"\n"
     30                              "   .even\n"
     31                              "3: sub.l %0,%0\n"
     32                              "   jra 2b\n"
     33                              ".previous\n"
     34                              ".section __ex_table,\"a\"\n"
     35                              "   .align 4\n"
     36                              "   .long 1b,3b\n"
     37                              ".previous"
     38                              : "=a" (paddr)
     39                              : "0" (vaddr));
     40                set_fs(old_fs);
     41                return paddr;
     42        } else if (CPU_IS_040) {
     43                mm_segment_t old_fs = get_fs();
     44                unsigned long mmusr;
     45
     46                set_fs(fs);
     47               
     48                asm volatile (".chip 68040\n\t"
     49                              "ptestr (%1)\n\t"
     50                              "movec %%mmusr, %0\n\t"
     51                              ".chip 68k"
     52                              : "=r" (mmusr)
     53                              : "a" (vaddr));
     54                set_fs(old_fs);
     55
     56                if (mmusr & MMU_R_040)
     57                        return (mmusr & PAGE_MASK) | (vaddr & ~PAGE_MASK);
     58        } else {
     59                unsigned short mmusr;
     60                unsigned long *descaddr;
     61
     62                asm volatile ("ptestr %3,%2@,#7,%0\n\t"
     63                              "pmove %%psr,%1@"
     64                              : "=a&" (descaddr)
     65                              : "a" (&mmusr), "a" (vaddr), "d" (fs.seg));
     66                if (mmusr & (MMU_I|MMU_B|MMU_L))
     67                        return 0;
     68                descaddr = phys_to_virt((unsigned long)descaddr);
     69                switch (mmusr & MMU_NUM) {
     70                case 1:
     71                        return (*descaddr & 0xfe000000) | (vaddr & 0x01ffffff);
     72                case 2:
     73                        return (*descaddr & 0xfffc0000) | (vaddr & 0x0003ffff);
     74                case 3:
     75                        return (*descaddr & PAGE_MASK) | (vaddr & ~PAGE_MASK);
     76                }
     77        }
     78        return 0;
     79}
     80
     81/* Push n pages at kernel virtual address and clear the icache */
     82/* RZ: use cpush %bc instead of cpush %dc, cinv %ic */
     83void flush_icache_range(unsigned long address, unsigned long endaddr)
     84{
     85        if (CPU_IS_040_OR_060) {
     86                address &= PAGE_MASK;
     87
     88                if (address >= PAGE_OFFSET && address < (unsigned long)high_memory) {
     89                        do {
     90                                asm volatile ("nop\n\t"
     91                                              ".chip 68040\n\t"
     92                                              "cpushp %%bc,(%0)\n\t"
     93                                              ".chip 68k"
     94                                              : : "a" (virt_to_phys((void *)address)));
     95                                address += PAGE_SIZE;
     96                        } while (address < endaddr);
     97                } else {
     98                        do {
     99                                asm volatile ("nop\n\t"
     100                                              ".chip 68040\n\t"
     101                                              "cpushp %%bc,(%0)\n\t"
     102                                              ".chip 68k"
     103                                              : : "a" (virt_to_phys_slow(address, KERNEL_DS)));
     104                                address += PAGE_SIZE;
     105                        } while (address < endaddr);
     106                }
     107        } else {
     108                unsigned long tmp;
     109                asm volatile ("movec %%cacr,%0\n\t"
     110                              "orw %1,%0\n\t"
     111                              "movec %0,%%cacr"
     112                              : "=&d" (tmp)
     113                              : "di" (FLUSH_I));
     114        }
     115}
     116
     117void flush_icache_user_range(void *addr, unsigned long size)
     118{
     119        unsigned long address = (unsigned long)addr;
     120        unsigned long endaddr = address + size;
     121
     122        if (CPU_IS_040_OR_060) {
     123                address &= PAGE_MASK;
     124
     125                do {
     126                        asm volatile ("nop\n\t"
     127                                      ".chip 68040\n\t"
     128                                      "cpushp %%bc,(%0)\n\t"
     129                                      ".chip 68k"
     130                                      : : "a" (virt_to_phys_slow(address, get_fs())));
     131                        address += PAGE_SIZE;
     132                } while (address < endaddr);
     133        } else {
     134                unsigned long tmp;
     135                asm volatile ("movec %%cacr,%0\n\t"
     136                              "orw %1,%0\n\t"
     137                              "movec %0,%%cacr"
     138                              : "=&d" (tmp)
     139                              : "di" (FLUSH_I));
     140        }
     141}
     142
     143void flush_icache_user_page(struct vm_area_struct *vma, struct page *page,
     144                            unsigned long addr, int len)
     145{
     146        if (CPU_IS_040_OR_060) {
     147                asm volatile ("nop\n\t"
     148                              ".chip 68040\n\t"
     149                              "cpushp %%bc,(%0)\n\t"
     150                              ".chip 68k"
     151                              : : "a" (page_to_phys(page)));
     152        } else {
     153                unsigned long tmp;
     154                asm volatile ("movec %%cacr,%0\n\t"
     155                              "orw %1,%0\n\t"
     156                              "movec %0,%%cacr"
     157                              : "=&d" (tmp)
     158                              : "di" (FLUSH_I));
     159        }
     160}
     161
  • arch/m68k/tekxp/Makefile

    diff -Naur linux-2.4.26/arch/m68k/tekxp/Makefile linux-2.4.26-m68k/arch/m68k/tekxp/Makefile
    old new  
     1#
     2# Makefile for Linux arch/m68k/tekxp source directory
     3#
     4# Note! Dependencies are done automagically by 'make dep', which also
     5# removes any old dependencies. DON'T put your own dependencies here
     6# unless it's something special (ie not a .c file).
     7#
     8# Note 2! The CFLAGS definitions are now in the main makefile...
     9
     10O_TARGET := tekxp.o
     11
     12export-objs     := tek_ksyms.o tekuart.o nvram.o
     13obj-y           := config.o tekuart.o nvram.o tek_ksyms.o
     14
     15include $(TOPDIR)/Rules.make
  • arch/m68k/tekxp/config.c

    diff -Naur linux-2.4.26/arch/m68k/tekxp/config.c linux-2.4.26-m68k/arch/m68k/tekxp/config.c
    old new  
     1/*
     2 *  linux/arch/m68k/tekxp/config.c
     3 *
     4 *  Copyright (C) 2002,2003 Michael Mueller <malware@t-online.de>
     5 *
     6 * This file is subject to the terms and conditions of the GNU General Public
     7 * License. See the file COPYING in the main directory of this archive for
     8 * more details.
     9 */
     10
     11#include <linux/config.h>
     12#include <linux/types.h>
     13#include <linux/console.h>
     14#include <linux/sched.h>
     15
     16#include <asm/machdep.h>
     17#include <asm/irq.h>
     18#include <asm/tekirq.h>
     19#include <asm/tekuart.h>
     20#include <asm/teknvram.h>
     21
     22unsigned char aux_device_present = 1;
     23
     24/*
     25 * While the support for this platform is still under development we just
     26 * spit out a stupid message whenever an unexpected IRQ does occur.
     27 * This message when appearing once most possible will run forever,
     28 * since we have no interrupt controller we can give an acknowledgement.
     29 */
     30
     31static void tekxp_int_unhandled(int irq, void *dev_id, struct pt_regs *regs)
     32{
     33        printk(KERN_ERR "Unhandled IRQ %d\n", irq);
     34}
     35
     36static void (*tekxp_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
     37        tekxp_int_unhandled, tekxp_int_unhandled, tekxp_int_unhandled,
     38        tekxp_int_unhandled, tekxp_int_unhandled, tekxp_int_unhandled,
     39        tekxp_int_unhandled, tekxp_int_unhandled
     40};
     41
     42/*
     43 * Reset the machine.
     44 */
     45static void tekxp_reset(void)
     46{
     47        tek_uart_set_op(4);
     48        __asm__ volatile("1:\tbras 1b\r\n");
     49}
     50
     51#ifdef USE_VIDEO_REFRESH_AS_TIMER
     52/*
     53 * Timer interrupt handler
     54 */
     55
     56static void tek_timer(int irq, void *dev_id, struct pt_regs *regs)
     57{
     58        register void (*handler)(int,void*,struct pt_regs*) = dev_id;
     59
     60        (*(volatile unsigned char *)(0xFFB00000))++;
     61
     62        handler(irq, NULL, regs);
     63}
     64#endif
     65
     66/*
     67 * To initialize the scheduling we setup a timer on the DUART.
     68 * The hardware offers a screen refresh interrupt but its rate varies with
     69 * the display mode and in all cases is less than HZ.
     70 */
     71
     72static void __init tek_sched_init(void (*handler)(int, void *, struct pt_regs *))
     73{
     74#ifdef USE_VIDEO_REFRESH_AS_TIMER
     75        /*
     76         * Enable the timer
     77         */
     78        (*(volatile unsigned char *)(0xFFB00000))++;
     79
     80        if ( request_irq(TEK_IRQ_VIDEO, tek_timer, IRQ_FLG_LOCK, "timer", handler) )
     81                panic("Could not register timer interrupt");
     82#else
     83        tek_uart_setup_timer(handler);
     84#endif
     85}
     86
     87/*
     88 * Currently there is no such function implemented.
     89 * However one could read the counter registers of the DUART here.
     90 */
     91
     92static unsigned long tek_gettimeoffset(void)
     93{
     94        return 0;
     95}
     96
     97/*
     98 * There is not much to do with the keyboard here.
     99 * The TekXpress Bootmonitor did most of the work already. What is left
     100 * will be done by the PC keyboard driver later.
     101 */
     102
     103static int __init tek_dummy_keyb_init(void)
     104{
     105        return 0;
     106}
     107
     108/*
     109 * This function simply modifies the C character for a new line into the
     110 * MSDOS-typical version of it.
     111 */
     112
     113static void tek_serial_console_write(struct console *co, const char *s,
     114                                       unsigned int count)
     115{
     116        while ( count-- )
     117        {
     118                char c = *s++;
     119                if ( c == '\n' )
     120                        tek_uart_putchar(0, '\r', 1);
     121                tek_uart_putchar(0, c, 1);
     122        }
     123}
     124
     125/*
     126 */
     127
     128static struct console tekxp_console_driver = {
     129        name:           "debug",
     130        flags:          CON_PRINTBUFFER,
     131        index:          -1,
     132};
     133
     134/*
     135 */
     136static void __init tekxp_debug_init(void)
     137{
     138        extern char m68k_debug_device[];
     139
     140        if (!strcmp( m68k_debug_device, "ser" )) {
     141                /* no initialization required (?) */
     142                tekxp_console_driver.write = tek_serial_console_write;
     143                register_console(&tekxp_console_driver);
     144        }
     145}
     146
     147/*
     148 * Get the model number as stored in NVRAM and make it readable.
     149 *
     150 * FIXME: This does not work as expected.
     151 */
     152
     153static void tekxp_get_model(char *model)
     154{
     155#ifdef CONFIG_TEKXP_REPORT_MVME
     156    sprintf(model, "Motorola MVME160");
     157#else
     158    unsigned short m = nvram_readw(NVRAM_DISPLAY);
     159    static const int model_number[] = {24,25,27,29,25,21,25,25};
     160
     161    if ( m < sizeof model_number )
     162        sprintf(model, "TekXpress XP%02d", model_number[m]);
     163    else
     164        sprintf(model, "TekXpress");
     165#endif
     166}
     167
     168/*
     169 * This basicly sets the machine dependent variables as needed by
     170 * the m68k port of the linux kernel.
     171 * Besides it initializes a console for kernel messages and the NVRAM
     172 * routines.
     173 */
     174
     175void __init config_tekxp(void)
     176{
     177        tekxp_debug_init();
     178        init_nvram(NULL);
     179
     180        mach_get_model          = tekxp_get_model;
     181        mach_sched_init         = tek_sched_init;
     182#ifdef CONFIG_VT
     183        mach_keyb_init          = tek_dummy_keyb_init;
     184#endif
     185        mach_init_IRQ           = tek_uart_init_IRQ;
     186        mach_request_irq        = tek_uart_request_irq;
     187        mach_free_irq           = tek_uart_free_irq;
     188        enable_irq              = tek_uart_enable_irq;
     189        disable_irq             = tek_uart_disable_irq;
     190        mach_get_irq_list       = tek_uart_get_irq_list;
     191        mach_gettimeoffset      = tek_gettimeoffset;
     192        mach_max_dma_address    = 0xffffffff;
     193#ifdef CONFIG_DUMMY_CONSOLE
     194        conswitchp              = &dummy_con;
     195#endif
     196        mach_default_handler    = &tekxp_default_handler;
     197        mach_reset              = tekxp_reset;
     198}
     199
  • arch/m68k/tekxp/nvram.c

    diff -Naur linux-2.4.26/arch/m68k/tekxp/nvram.c linux-2.4.26-m68k/arch/m68k/tekxp/nvram.c
    old new  
     1/*
     2 *  linux/arch/m68k/tekxp/nvram.c
     3 *
     4 *  Copyright (C) 2002,2003 Michael Mueller <malware@t-online.de>
     5 *
     6 * This file is subject to the terms and conditions of the GNU General Public
     7 * License. See the file COPYING in the main directory of this archive for
     8 * more details.
     9 */
     10
     11#include <linux/config.h>
     12#include <linux/kernel.h>
     13#include <linux/types.h>
     14#include <linux/errno.h>
     15#include <linux/mm.h>
     16#include <linux/slab.h>
     17#include <asm/io.h>
     18#include <asm/teknvram.h>
     19#include <asm/tekuart.h>
     20
     21#define DEBUG
     22
     23#ifdef DEBUG
     24static int nvram_init = 0;
     25#endif
     26static u_char *eeprom_ptr;
     27static u_char nvram_copy[EEPROM_SIZE];
     28
     29static void ee_enable(void)
     30{
     31#if 0
     32        // TODO: We still rely on the I/O being transparently mapped
     33        // TODO: This might interfere with other code using the UART
     34        *(volatile u_char*)0xFF800038 = (u_char)0x80;
     35#else
     36        tek_uart_set_op(7);
     37#endif
     38}
     39
     40static void ee_disable(void)
     41{
     42#if 0
     43        // TODO: We still rely on the I/O being transparently mapped
     44        // TODO: This might interfere with other code using the UART
     45        *(volatile u_char*)0xFF80003C = (u_char)0x80;
     46#else
     47        tek_uart_clr_op(7);
     48#endif
     49}
     50
     51void init_nvram(unsigned long *mem_start)
     52{
     53        u_char chksum;
     54        u_char chksum2;
     55        u_short chksum_complete;
     56        int i;
     57
     58        // FIXME: When this code is running ioremap* is not working yet.
     59        //  So we access the EEPROM through the transparent mapping
     60        //  established in head.S
     61#if 0
     62        // Map EEPROM into kernel memory space
     63        eeprom_ptr = ioremap_writethrough(EEPROM_BASE, EEPROM_SIZE);
     64        if ( !eeprom_ptr )
     65        {
     66                panic(KERN_ERR "Could not map NVRAM into kernel memory space\n");
     67        }
     68#else
     69        eeprom_ptr = (u_char*)EEPROM_BASE;
     70#endif
     71
     72        // Make a copy of the content to avoid access count excess
     73        ee_enable();
     74        memcpy(nvram_copy, eeprom_ptr, EEPROM_SIZE);
     75        ee_disable();
     76
     77        // Check the checksum of the content
     78        chksum = 0xFF;
     79        chksum2 = 0xFF;
     80        for ( i = EEPROM_SIZE-1; i >= 0 ; i-- )
     81        {
     82                u_long new_chk /* d0 */ = chksum + nvram_copy[i];
     83                if ( new_chk > 0xFF )
     84                        new_chk++;
     85                chksum = new_chk & 0xFF;
     86
     87                new_chk = chksum2 + chksum;
     88                if ( new_chk > 0xFF )
     89                        new_chk++;
     90                chksum2 = new_chk++;
     91        }
     92
     93        chksum_complete = ((u_short)chksum2 << 8) + chksum;
     94        if ( chksum_complete == 0xFFFF )
     95        {
     96                printk("NVRAM checksum is ok\n");
     97        }
     98        else
     99        {
     100                printk(KERN_WARNING "NVRAM checksum invalid!\n");
     101        }
     102
     103#ifdef DEBUG
     104        nvram_init++;
     105#endif
     106}
     107
     108u_char nvram_readb(int ofs)
     109{
     110#ifdef DEBUG
     111        if ( !nvram_init )
     112        {
     113                printk(KERN_ERR "Trial to read uninitialized NVRAM\n");
     114                return 0xFF;
     115        }
     116#endif
     117        if ( ofs < 0 || ofs >= EEPROM_SIZE )
     118                return 0xFF;
     119
     120        return nvram_copy[ofs];
     121}
     122
     123u_short nvram_readw(int ofs)
     124{
     125#ifdef DEBUG
     126        if ( !nvram_init )
     127        {
     128                printk(KERN_ERR "Trial to read uninitialized NVRAM\n");
     129                return 0xFFFFU;
     130        }
     131        if ( ofs & 1 )
     132        {
     133                panic("Unaligned word access to NVRAM");
     134                return 0xFFFFU;
     135        }
     136#endif
     137        if ( ofs < 0 || ofs >= EEPROM_SIZE )
     138                return 0xFFFFU;
     139
     140        return *(u_short*)(nvram_copy + ofs);
     141}
     142
     143
     144u_long nvram_readl(int ofs)
     145{
     146#ifdef DEBUG
     147        if ( !nvram_init )
     148        {
     149                printk(KERN_ERR "Trial to read uninitialized NVRAM\n");
     150                return 0xFFFFFFFFUL;
     151        }
     152        if ( ofs & 3 )
     153        {
     154                panic("Unaligned word access to NVRAM");
     155                return 0xFFFFFFFFUL;
     156        }
     157#endif
     158        if ( ofs < 0 || ofs >= EEPROM_SIZE )
     159                return 0xFFFFFFFFUL;
     160
     161        return *(u_long*)(nvram_copy + ofs);
     162}
     163
     164
  • arch/m68k/tekxp/tek_ksyms.c

    diff -Naur linux-2.4.26/arch/m68k/tekxp/tek_ksyms.c linux-2.4.26-m68k/arch/m68k/tekxp/tek_ksyms.c
    old new  
     1/*
     2 *  linux/arch/m68k/tekxp/tek_ksyms.c
     3 *
     4 *  Copyright (C) 2002,2003 Michael Mueller <malware@t-online.de>
     5 *
     6 * This file is subject to the terms and conditions of the GNU General Public
     7 * License. See the file COPYING in the main directory of this archive for
     8 * more details.
     9 */
     10
     11#include <linux/config.h>
     12#include <linux/module.h>
     13#include <linux/types.h>
     14#include <asm/ptrace.h>
     15#include <asm/tekuart.h>
     16#include <asm/teknvram.h>
     17
     18EXPORT_SYMBOL(tek_uart_putchar);
     19EXPORT_SYMBOL(tek_uart_lock);
     20EXPORT_SYMBOL(nvram_readb);
     21EXPORT_SYMBOL(nvram_readw);
     22EXPORT_SYMBOL(nvram_readl);
     23
  • arch/m68k/tekxp/tekuart.c

    diff -Naur linux-2.4.26/arch/m68k/tekxp/tekuart.c linux-2.4.26-m68k/arch/m68k/tekxp/tekuart.c
    old new  
     1/*
     2 *  linux/arch/m68k/tekxp/tekuart.c
     3 *
     4 *  Copyright (C) 2002,2003 Michael Mueller <malware@t-online.de>
     5 *
     6 * This file is subject to the terms and conditions of the GNU General Public
     7 * License. See the file COPYING in the main directory of this archive for
     8 * more details.
     9 */
     10
     11#include <linux/config.h>
     12#include <linux/types.h>
     13#include <linux/sched.h>
     14#include <linux/kernel.h>
     15#include <linux/mm.h>
     16#include <linux/errno.h>
     17#include <linux/spinlock.h>
     18
     19#include <asm/system.h>
     20#include <asm/irq.h>
     21#include <asm/pgtable.h>
     22#include <asm/tekuart.h>
     23#include <asm/tekirq.h>
     24
     25spinlock_t tek_uart_lock = SPIN_LOCK_UNLOCKED;
     26static spinlock_t tek_irq_lock = SPIN_LOCK_UNLOCKED;
     27
     28/*
     29 * Base address of the UART
     30 *
     31 * Initialized to the address accessable by a transparent mapping.
     32 *
     33 * FIXME: This is never mapped into the memory space of the kernel
     34 *        since memory mapping is not available while initializing the
     35 *        platform specific stuff.
     36 */
     37
     38static tek_uart_t *uart = (tek_uart_t*)TEK_UART_BASE;
     39
     40/*
     41 * Interrupt handler tables and call statistics
     42 */
     43
     44static irq_handler_t irq_handlers[UART_IRQS];
     45static int tek_irq_stat[UART_IRQS];
     46
     47#define IRQ_IDX(n) ((n)-SYS_IRQS)
     48
     49/*
     50 * Dummy variable used as Lvalue when we need to read from the
     51 * hardware without any need for the actual result value.
     52 */
     53
     54static volatile u_char dummy;
     55
     56/*
     57 * Variables used for the interrupt routine
     58 */
     59
     60static u_char tek_uart_imr;             /* shadow Interrupt Mask Register   */
     61static u_char tek_uart_isr;             /* shadow Interrupt Status Register */
     62#ifndef USE_VIDEO_REFRESH_AS_TIMER
     63static unsigned short tek_timer;        /* value to put into the counter    */
     64#endif
     65
     66static u_char timer_mode = 0x80;        /* choose second baudrate set       */
     67
     68/*
     69 * Set the interrupt mask register.
     70 */
     71
     72static inline void __set_IMR(void)
     73{
     74        uart->wr.IMR = tek_uart_imr;
     75}
     76
     77static void set_IMR(void)
     78{
     79        unsigned long flags;
     80        spin_lock_irqsave(tek_uart_lock, flags);
     81        __set_IMR();
     82        spin_unlock_irqrestore(tek_uart_lock, flags);
     83}
     84
     85/*
     86 * Interrupt handler.
     87 *
     88 * Besides demultiplexing the interrupt sources of the DUART it does take
     89 * care of the counter prior to calling the kernel handler.
     90 */
     91
     92static void tek_irqhandler(int irq, void *dev_id, struct pt_regs *regs)
     93{
     94        int i;
     95
     96        /*
     97         * Read the ISR once. This does even clear all pending interrupts.
     98         */
     99        unsigned char ISR = uart->rd.ISR;
     100
     101#ifndef USE_VIDEO_REFRESH_AS_TIMER
     102        /*
     103         * Handle the counter.
     104         */
     105        if ( ISR & (1<<IRQ_IDX(TEK_IRQ_TIMER_A)) )
     106                dummy = uart->rd.CounterStop;   /* just ack */
     107#endif
     108
     109#ifdef DEBUG
     110        printk("tek_irqhandler: ISR=%02x IMR=%02x\n", ISR, tek_uart_imr);
     111#endif
     112
     113        /*
     114         * Store the interrupt status for later usage.
     115         *
     116         * This does also queue disabled interrupts for later usage.
     117         */
     118        ISR = (tek_uart_isr |= ISR) & tek_uart_imr;
     119
     120        /*
     121         * Run the handler for each interrupt source.
     122         */
     123        for ( i=0; i<UART_IRQS; i++ )
     124        {
     125                if ( ISR & (1<<i) )
     126                {
     127                        unsigned long flags;
     128                        spin_lock_irqsave(tek_irq_lock, flags);
     129
     130                        tek_irq_stat[i]++;
     131
     132                        if ( irq_handlers[i].handler )
     133                        {
     134                                irq_handler_t handler = irq_handlers[i];
     135                                spin_unlock_irqrestore(tek_irq_lock, flags);
     136
     137                                handler.handler(i, handler.dev_id, regs);
     138                        }
     139                        else
     140                                spin_unlock_irqrestore(tek_irq_lock, flags);
     141                        tek_uart_isr &= ~(1<<i);
     142                }
     143        }
     144}
     145
     146/*
     147 * Set an output line (to Low)
     148 *
     149 * Following values for the line are of special use:
     150 *      3       connected to internal beeper
     151 *      4       will reset the machine
     152 */
     153
     154void tek_uart_set_op(int nr)
     155{
     156        unsigned long flags;
     157        spin_lock_irqsave(tek_uart_lock, flags);
     158
     159        uart->wr.OutputSet = 1 << nr;
     160
     161        spin_unlock_irqrestore(tek_uart_lock, flags);
     162}
     163
     164/*
     165 * Clear an output line (to High)
     166 */
     167
     168void tek_uart_clr_op(int nr)
     169{
     170        unsigned long flags;
     171        spin_lock_irqsave(tek_uart_lock, flags);
     172
     173        uart->wr.OutputClear = 1 << nr;
     174
     175        spin_unlock_irqrestore(tek_uart_lock, flags);
     176}
     177
     178/*
     179 * Setup an interrupt handler managing all interrupt sources of the DUART.
     180 */
     181
     182void __init tek_uart_init_IRQ(void)
     183{
     184        unsigned long flags;
     185        spin_lock_irqsave(tek_uart_lock, flags);
     186
     187        /*
     188         * Disable all interrupts
     189         */
     190        tek_uart_imr = 0;
     191        __set_IMR();
     192
     193
     194        /*
     195         * Clear pending interrupts
     196         */
     197        tek_uart_isr = 0;
     198        dummy = uart->rd.ISR;
     199
     200        spin_unlock_irqrestore(tek_uart_lock, flags);
     201
     202        /*
     203         * Register the interrupt handler
     204         */
     205        if ( request_irq(TEK_IRQ_UART, tek_irqhandler, IRQ_FLG_LOCK, "UART demux", NULL) )
     206        {
     207                panic("Could not register UART demux interrupt handler");
     208        }
     209}
     210
     211/*
     212 * Enable a specific interrupt source of the DUART.
     213 */
     214
     215static inline void enable_uart_irq(unsigned int irq)
     216{
     217        unsigned long flags;
     218        spin_lock_irqsave(tek_uart_lock, flags);
     219
     220        tek_uart_imr |= (1<<irq);
     221        __set_IMR();
     222
     223        spin_unlock_irqrestore(tek_uart_lock, flags);
     224}
     225
     226/*
     227 * Disable a specific interrupt source of the DUART.
     228 */
     229
     230static inline void disable_uart_irq(unsigned int irq)
     231{
     232        unsigned long flags;
     233        spin_lock_irqsave(tek_uart_lock, flags);
     234
     235        tek_uart_imr &= ~(1<<irq);
     236        __set_IMR();
     237
     238        spin_unlock_irqrestore(tek_uart_lock, flags);
     239}
     240
     241/*
     242 * Register an interrupt handler for an interrupt source of the DUART.
     243 *
     244 * This is also called for system interrupts. These requests are passed
     245 * to the generic function made available by the m68k port.
     246 */
     247
     248int tek_uart_request_irq(unsigned int irq,
     249                          void (*handler)(int, void *, struct pt_regs *),
     250                          unsigned long flags,
     251                          const char *devname, void *dev_id)
     252{
     253        unsigned long _flags;
     254
     255        if ( irq < SYS_IRQS )
     256                return sys_request_irq(irq, handler, flags, devname, dev_id);
     257        irq -= SYS_IRQS;
     258
     259        if ( irq >= UART_IRQS )
     260                return -ENXIO;
     261        if ( !handler )
     262                return -EINVAL;
     263
     264        spin_lock_irqsave(tek_irq_lock, _flags);
     265
     266        if ( irq_handlers[irq].handler && (irq_handlers[irq].dev_id != dev_id) )        {
     267                spin_unlock_irqrestore(tek_irq_lock, _flags);
     268                return -EBUSY;
     269        }
     270
     271        irq_handlers[irq].handler = handler;
     272        irq_handlers[irq].flags   = flags;
     273        irq_handlers[irq].devname = devname;
     274        irq_handlers[irq].dev_id  = dev_id;
     275
     276        spin_unlock_irqrestore(tek_irq_lock, _flags);
     277
     278        enable_uart_irq(irq);
     279
     280        return 0;
     281}
     282
     283/*
     284 * Unregister an interrupt handler for an interrupt source of the DUART.
     285 *
     286 * This is also called for system interrupts. These requests are passed
     287 * to the generic function made available by the m68k port.
     288 */
     289
     290void tek_uart_free_irq(unsigned int irq, void *dev_id)
     291{
     292        unsigned long flags;
     293
     294        if ( irq < SYS_IRQS )
     295                return sys_free_irq(irq, dev_id);
     296        irq -= SYS_IRQS;
     297
     298        if ( irq >= UART_IRQS )
     299                return /* -ENXIO */;
     300
     301        spin_lock_irqsave(tek_irq_lock, flags);
     302
     303        if ( !irq_handlers[irq].handler )
     304                return /* -EINVAL */;
     305
     306        if ( dev_id != irq_handlers[irq].dev_id )
     307                return /* -EPERM */;
     308
     309        disable_uart_irq(irq);
     310        irq_handlers[irq].handler = NULL;
     311
     312        spin_unlock_irqrestore(tek_irq_lock, flags);
     313}
     314
     315/*
     316 * Wrapper for enabling an IRQ.
     317 */
     318
     319void tek_uart_enable_irq(unsigned int irq)
     320{
     321        if ( irq < SYS_IRQS )
     322                return;
     323
     324        enable_uart_irq(irq - SYS_IRQS);
     325}
     326
     327/*
     328 * Wrapper for disabling an IRQ.
     329 */
     330
     331void tek_uart_disable_irq(unsigned int irq)
     332{
     333        if ( irq < SYS_IRQS )
     334                return;
     335
     336        disable_uart_irq(irq - SYS_IRQS);
     337}
     338
     339/*
     340 * Build an ASCII list of the interrupt handlers registered and the call
     341 * statistics. This part of the content of /proc/interrupts.
     342 */
     343
     344int tek_uart_get_irq_list(char *buf)
     345{
     346        int i, len = 0;
     347        unsigned long flags;
     348        spin_lock_irqsave(tek_irq_lock, flags);
     349
     350        for ( i=0; i < UART_IRQS; i++ )
     351        {
     352                if ( irq_handlers[i].handler )
     353                {
     354                        len += sprintf(buf+len, "uart %2d: %10u ", i, tek_irq_stat[i]);
     355                        len += sprintf(buf+len, "  ");
     356                        len += sprintf(buf+len, "%s\n", irq_handlers[i].devname);
     357                }
     358        }
     359        spin_unlock_irqrestore(tek_irq_lock, flags);
     360        return len;
     361}
     362
     363#ifndef USE_VIDEO_REFRESH_AS_TIMER
     364
     365static void tek_irq2(int irq, void *dev_id, struct pt_regs *regs)
     366{
     367        /*
     368         * Acknowledge the interrupt
     369         */
     370        (*(volatile unsigned char *)(0xFFB00000))++;
     371
     372}
     373
     374/*
     375 * Setup a timer interrupt.
     376 */
     377void __init tek_uart_setup_timer(void (*handler)(int, void *, struct pt_regs *))
     378{
     379        unsigned long flags;
     380
     381        /*
     382         * Calculate the divider of the clock interval
     383         */
     384        if ( HZ < 32 )
     385        {
     386                /*
     387                 * Use 115.2k base clock.
     388                 *
     389                 * Do not permit frequencies <2Hz, they can be provided
     390                 * by further software dividing only and are not very
     391                 * usefull.
     392                 */
     393                if ( HZ < 2 )
     394                        panic("I will not provide such a slow timer");
     395
     396                timer_mode |= 0x70;
     397                tek_timer = 115200 / HZ;
     398        }
     399        else if ( HZ <= 57600 )
     400        {
     401                /*
     402                 * Use 115.2k * 16 base clock
     403                 */
     404                timer_mode |= 0x60;
     405                tek_timer = (115200*16) / HZ;
     406        }
     407        else
     408                /*
     409                 * We can not provide a faster timer.
     410                 */
     411                panic("Old hardware is no ferrari");
     412
     413        /*
     414         * And setup an handler for the video refresh.
     415         */
     416        if ( request_irq(TEK_IRQ_VIDEO, tek_irq2, IRQ_FLG_LOCK, "display", NULL) )
     417                panic("Could not register display interrupt");
     418
     419        /*
     420         * Setup an handler for the timer interrupt.
     421         */
     422        if ( request_irq(TEK_IRQ_TIMER_A, handler, IRQ_FLG_LOCK, "timer", NULL) )
     423                panic("Could not register timer interrupt");
     424
     425        spin_lock_irqsave(tek_uart_lock, flags);
     426
     427        /*
     428         * Start the timer.
     429         */
     430        dummy = uart->rd.CounterStop;
     431        uart->wr.ACR = timer_mode;
     432        uart->wr.CRUR = tek_timer >> 8;
     433        uart->wr.CTLR = tek_timer & 255;
     434        dummy = uart->rd.CounterStart;
     435
     436        spin_unlock_irqrestore(tek_uart_lock, flags);
     437
     438        /*
     439         * Enable the video refresh interrupt
     440         */
     441        (*(volatile unsigned char *)(0xFFB00000))++;
     442}
     443#endif
     444
     445/*
     446 * Output a character on the serial port A.
     447 *
     448 * This routine is called from interrupt and non-interrupt contexts.
     449 */
     450
     451void tek_uart_putchar(int channel, int c, int waitloop)
     452{
     453        unsigned long flags;
     454        spin_lock_irqsave(tek_uart_lock, flags);
     455
     456        channel &= 1;
     457
     458        if ( waitloop )
     459        {
     460//              disable_uart_irq(channel ? 4 : 0);
     461                while ( !((channel ? uart->rd.SRB : uart->rd.SRA) & 4) )
     462                        ;
     463        }
     464
     465        (channel ? uart->wr.THRB : uart->wr.THRA) = (u_char)c;
     466
     467        if ( waitloop )
     468        {
     469                while ( !((channel ? uart->rd.SRB : uart->rd.SRA) & 4) )
     470                        ;
     471//              enable_uart_irq(channel ? 4 : 0);
     472        }
     473
     474        spin_unlock_irqrestore(tek_uart_lock, flags);
     475}
     476
  • drivers/char/16c552.h

    diff -Naur linux-2.4.26/drivers/char/16c552.h linux-2.4.26-m68k/drivers/char/16c552.h
    old new  
     1/*
     2 * Definitions for the 16c552 DACE
     3 * (dual-asynchronous-communications-element) used on the GVP
     4 * IO-Extender.
     5 *
     6 * Basically this is two 16c550 uarts's and a parallel port, which is
     7 * why the serial definitions should be valid for the 16c550 uart
     8 * aswell.
     9 *
     10 * Data was taken from National Semiconductors duart 16c552
     11 * data-sheets and the Texas Instruments DACE 16c552 data-sheets (the
     12 * NS version of the chip is _non_ standard and their data-sheets did
     13 * cost me several wasted hours of work).
     14 *
     15 * This file is (C) 1995 Jes Sorensen (jds@kom.auc.dk)
     16 *
     17 * Moved from drivers/char/ to include/linux/, because it's useful
     18 * on more than just the one card. I'm using it on the hp300 DCA
     19 * serial driver, for example. 
     20 *      -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 05/1998
     21 */
     22
     23#ifndef _16C552_H_
     24#define _16C552_H_
     25
     26/* Serial stuff */
     27
     28struct uart_16c550 {
     29        volatile u_char skip0;
     30        volatile u_char RBR;
     31        volatile u_char skip1;
     32        volatile u_char IER;
     33        volatile u_char skip2;
     34        volatile u_char IIR;
     35        volatile u_char skip3;
     36        volatile u_char LCR;
     37        volatile u_char skip4;
     38        volatile u_char MCR;
     39        volatile u_char skip5;
     40        volatile u_char LSR;
     41        volatile u_char skip6;
     42        volatile u_char MSR;
     43        volatile u_char skip7;
     44        volatile u_char SCR;
     45};
     46
     47#define THR RBR
     48#define FCR IIR
     49#define DLL RBR
     50#define DLM IER
     51#define AFR IIR
     52
     53/*
     54 * Bit-defines for the various registers.
     55 */
     56
     57
     58/* IER */
     59
     60#define ERDAI         (1<<0)
     61#define ETHREI        (1<<1)
     62#define ELSI          (1<<2)
     63#define EMSI          (1<<3)
     64
     65/* IIR - Interrupt Ident. Register */
     66
     67#define IRQ_PEND      (1<<0) /* NOTE: IRQ_PEND=0 implies irq pending */
     68#define IRQ_ID1       (1<<1)
     69#define IRQ_ID2       (1<<2)
     70#define IRQ_ID3       (1<<3)
     71#define FIFO_ENA0     (1<<6) /* Both these are set when FCR(1<<0)=1 */
     72#define FIFO_ENA1     (1<<7)
     73
     74#define IRQ_RLS  (IRQ_ID1 | IRQ_ID2)
     75#define IRQ_RDA  (IRQ_ID2)
     76#define IRQ_CTI  (IRQ_ID2 | IRQ_ID3)
     77#define IRQ_THRE (IRQ_ID1)
     78#define IRQ_MS   0
     79
     80/* FCR - FIFO Control Register */
     81
     82#define FIFO_ENA      (1<<0)
     83#define RCVR_FIFO_RES (1<<1)
     84#define XMIT_FIFO_RES (1<<2)
     85#define DMA_MODE_SEL  (1<<3)
     86#define RCVR_TRIG_LSB (1<<6)
     87#define RCVR_TRIG_MSB (1<<7)
     88
     89#define FIFO_TRIG_1   0x00
     90#define FIFO_TRIG_4   RCVR_TRIG_LSB
     91#define FIFO_TRIG_8   RCVR_TRIG_MSB
     92#define FIFO_TRIG_14  RCVR_TRIG_LSB|RCVR_TRIG_MSB
     93
     94/* LCR - Line Control Register */
     95
     96#define WLS0          (1<<0)
     97#define WLS1          (1<<1)
     98#define STB           (1<<2)
     99#define PEN           (1<<3)
     100#define EPS           (1<<4)
     101#define STICK_PARITY  (1<<5)
     102#define SET_BREAK     (1<<6)
     103#define DLAB          (1<<7)
     104
     105#define data_5bit      0x00
     106#define data_6bit      0x01
     107#define data_7bit      0x02
     108#define data_8bit      0x03
     109
     110
     111/* MCR - Modem Control Register */
     112
     113#define DTR           (1<<0)
     114#define RTS           (1<<1)
     115#define OUT1          (1<<2)
     116#define OUT2          (1<<3)
     117#define LOOP          (1<<4)
     118
     119/* LSR - Line Status Register */
     120
     121#define DR            (1<<0)
     122#define OE            (1<<1)
     123#define PE            (1<<2)
     124#define FE            (1<<3)
     125#define BI            (1<<4)
     126#define THRE          (1<<5)
     127#define TEMT          (1<<6)
     128#define RCVR_FIFO_ERR (1<<7)
     129
     130/* MSR - Modem Status Register */
     131
     132#define DCTS          (1<<0)
     133#define DDSR          (1<<1)
     134#define TERI          (1<<2)
     135#define DDCD          (1<<3)
     136#define CTS           (1<<4)
     137#define DSR           (1<<5)
     138#define RING_I        (1<<6)
     139#define DCD           (1<<7)
     140
     141/* AFR - Alternate Function Register */
     142
     143#define CONCUR_WRITE  (1<<0)
     144#define BAUDOUT       (1<<1)
     145#define RXRDY         (1<<2)
     146
     147/* Parallel stuff */
     148
     149/*
     150 * Unfortunately National Semiconductors did not supply the
     151 * specifications for the parallel port in the chip :-(
     152 * TI succed though, so here they are :-)
     153 *
     154 * Defines for the bits can be found by including <linux/lp.h>
     155 */
     156struct IOEXT_par {
     157        volatile u_char skip0;
     158        volatile u_char DATA;
     159        volatile u_char skip1;
     160        volatile u_char STATUS;
     161        volatile u_char skip2;
     162        volatile u_char CTRL;
     163};
     164
     165#endif
  • drivers/char/Makefile

    diff -Naur linux-2.4.26/drivers/char/Makefile linux-2.4.26-m68k/drivers/char/Makefile
    old new  
    321321obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
    322322obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
    323323obj-$(CONFIG_AMD7XX_TCO) += amd7xx_tco.o
     324obj-$(CONFIG_SCC2692) += generic_serial.o scc2692.o
    324325obj-$(CONFIG_INDYDOG) += indydog.o
    325326obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
    326327
  • drivers/char/ioext.h

    diff -Naur linux-2.4.26/drivers/char/ioext.h linux-2.4.26-m68k/drivers/char/ioext.h
    old new  
     1/*
     2 * Shared data structure for GVP IO-Extender support.
     3 *
     4 * Merge of ioext.h and ser_ioext.h
     5 */
     6#ifndef _IOEXT_H_
     7#define _IOEXT_H_
     8
     9#include <linux/config.h>
     10#include <linux/netdevice.h>
     11
     12#include "16c552.h"
     13
     14#define MAX_IOEXT 5 /*
     15                     * The maximum number of io-extenders is 5, as you
     16                     * can't have more than 5 ZII boards in any Amiga.
     17                     */
     18
     19#define UART_CLK 7372800
     20
     21#define IOEXT_BAUD_BASE (UART_CLK / 16)
     22
     23#define IOEXT_MAX_LINES 2
     24
     25#define IOEXT_PAR_PLIP  0x0001
     26#define IOEXT_PAR_LP    0x0002
     27
     28
     29/*
     30 * Macros for the serial driver.
     31 */
     32#define curruart(info) ((struct uart_16c550 *)(info->port))
     33
     34#define ser_DTRon(info)  curruart(info)->MCR |=  DTR
     35#define ser_RTSon(info)  curruart(info)->MCR |=  RTS
     36#define ser_DTRoff(info) curruart(info)->MCR &= ~DTR
     37#define ser_RTSoff(info) curruart(info)->MCR &= ~RTS
     38
     39
     40/*
     41 * CNTR defines (copied from the GVP SCSI-driver file gvp11.h
     42 */
     43#define GVP_BUSY        (1<<0)
     44#define GVP_IRQ_PEND    (1<<1)
     45#define GVP_IRQ_ENA     (1<<3)
     46#define GVP_DIR_WRITE   (1<<4)
     47
     48
     49/*
     50 * CTRL defines
     51 */
     52#define PORT0_MIDI   (1<<0)  /* CLR = DRIVERS         SET = MIDI      */
     53#define PORT1_MIDI   (1<<1)  /* CLR = DRIVERS         SET = MIDI      */
     54#define PORT0_DRIVER (1<<2)  /* CLR = RS232,          SET = MIDI      */
     55#define PORT1_DRIVER (1<<3)  /* CLR = RS232,          SET = MIDI      */
     56#define IRQ_SEL      (1<<4)  /* CLR = INT2,           SET = INT6      */
     57#define ROM_BANK_SEL (1<<5)  /* CLR = LOW 32K,        SET = HIGH 32K  */
     58#define PORT0_CTRL   (1<<6)  /* CLR = RTSx or RXRDYx, SET = RTSx ONLY */
     59#define PORT1_CTRL   (1<<7)  /* CLR = RTSx or RXRDYx, SET = RTSx ONLY */
     60
     61
     62/*
     63 * This is the struct describing the registers on the IO-Extender.
     64 * NOTE: The board uses a dual uart (16c552), which should be equal to
     65 * two 16c550 uarts.
     66 */
     67typedef struct {
     68        char gap0[0x41];
     69        volatile unsigned char CNTR;    /* GVP DMAC CNTR (status register)   */
     70        char gap1[0x11e];
     71        struct uart_16c550 uart0;       /* The first uart                    */
     72        char gap2[0xf0];
     73        struct uart_16c550 uart1;       /* The second uart                   */
     74        char gap3[0xf0];
     75        struct IOEXT_par par;           /* The parallel port                 */
     76        char gap4[0xfb];
     77        volatile unsigned char CTRL;    /* The control-register on the board */
     78} IOEXT_struct;
     79
     80
     81typedef struct {
     82        int num_uarts;
     83        int line[IOEXT_MAX_LINES];
     84        volatile struct uart_16c550 *uart[IOEXT_MAX_LINES];
     85        IOEXT_struct *board;
     86        int spurious_count;
     87        unsigned char par_use;          /* IOEXT_PAR_xxx */
     88#if defined(CONFIG_GVPIOEXT_PLIP) || defined(CONFIG_GVPIOEXT_PLIP_MODULE)
     89        struct nt_device *dev;
     90#endif
     91#if defined(CONFIG_GVPIOEXT_LP) || defined(CONFIG_GVPIOEXT_LP_MODULE)
     92        struct lp_struct *lp_table;
     93        int lp_dev;
     94        int lp_interrupt;
     95#endif
     96} IOExtInfoType;
     97
     98/* Number of detected boards.  */
     99extern int ioext_num;
     100extern IOExtInfoType ioext_info[MAX_IOEXT];
     101
     102void ioext_plip_interrupt(struct net_device *dev, int *spurious_count);
     103void ioext_lp_interrupt(int dev, int *spurious_count);
     104
     105extern struct net_device ioext_dev_plip[3];
     106extern struct lp_struct ioext_lp_table[1];
     107
     108#endif
  • drivers/char/mc68681.h

    diff -Naur linux-2.4.26/drivers/char/mc68681.h linux-2.4.26-m68k/drivers/char/mc68681.h
    old new  
     1#ifndef _MC68681_H_
     2#define _MC68681_H_
     3
     4/*
     5 * This describes an MC68681 DUART. It has almost only overlayed registers, which
     6 * the structure very ugly.
     7 * Note that the ri-register isn't really a register of the duart but a kludge of bsc
     8 * to make the ring indicator available.
     9 *
     10 * The data came from the MFC-31-Developer Kit (from Ralph Seidel,
     11 * zodiac@darkness.gun.de) and the data sheet of Phillip's clone device (SCN68681)
     12 * (from Richard Hirst, srh@gpt.co.uk)
     13 *
     14 * 11.11.95 copyright Joerg Dorchain (dorchain@mpi-sb.mpg.de)
     15 *
     16 */
     17
     18struct duarthalf {
     19union {
     20volatile u_char mr1; /* rw */
     21volatile u_char mr2; /* rw */
     22}  mr;
     23volatile u_char ri;   /* special, read */
     24union {
     25volatile u_char sr;  /* read */
     26volatile u_char csr; /* write */
     27} sr_csr;
     28u_char pad1;
     29volatile u_char cr; /* write */
     30u_char pad2;
     31union {
     32volatile u_char rhr; /* read */
     33volatile u_char thr; /* write */
     34} hr;
     35u_char pad3;
     36};
     37
     38struct duart {
     39struct duarthalf pa;
     40union {
     41volatile u_char ipcr; /* read */
     42volatile u_char acr;  /* write */
     43} ipcr_acr;
     44u_char pad1;
     45union {
     46volatile u_char isr; /* read */
     47volatile u_char imr; /* write */
     48} ir;
     49u_char pad2;
     50volatile u_char ctu;
     51u_char pad3;
     52volatile u_char ctl;
     53u_char pad4;
     54struct duarthalf pb;
     55volatile u_char ivr;
     56u_char pad5;
     57union {
     58volatile u_char ipr; /* read */
     59volatile u_char opcr; /* write */
     60} ipr_opcr;
     61u_char pad6;
     62union {
     63volatile u_char start; /* read */
     64volatile u_char sopc; /* write */
     65} start_sopc;
     66u_char pad7;
     67union {
     68volatile u_char stop; /* read */
     69volatile u_char ropc; /* write */
     70} stop_ropc;
     71u_char pad8;
     72};
     73
     74#define MR1_BITS 3
     75#define MR1_5BITS 0
     76#define MR1_6BITS 1
     77#define MR1_7BITS 2
     78#define MR1_8BITS 3
     79
     80#define MR1_PARITY_ODD 4
     81
     82#define MR1_PARITY 24
     83#define MR1_PARITY_WITH 0
     84#define MR1_PARITY_FORCE 8
     85#define MR1_PARITY_NO 16
     86#define MR1_PARITY_MULTIDROP 24
     87
     88#define MR1_ERROR_BLOCK 32
     89#define MR1_FFULL_IRQ 64
     90#define MR1_RxRTS_ON 128
     91
     92#define MR2_STOPS 15
     93#define MR2_1STOP 7
     94#define MR2_2STOP 15
     95
     96#define MR2_CTS_ON 16
     97#define MR2_TxRTS_ON 32
     98
     99#define MR2_MODE 192
     100#define MR2_NORMAL 0
     101#define MR2_ECHO 64
     102#define MR2_LOCALLOOP 128
     103#define MR2_REMOTELOOP 192
     104
     105#define CR_RXCOMMAND 3
     106#define CR_NONE 0
     107#define CR_RX_ON 1
     108#define CR_RX_OFF 2
     109#define CR_TXCOMMAND 12
     110#define CR_TX_ON 4
     111#define CR_TX_OFF 8
     112#define CR_MISC 112
     113#define CR_RESET_MR 16
     114#define CR_RESET_RX 32
     115#define CR_RESET_TX 48
     116#define CR_RESET_ERR 64
     117#define CR_RESET_BREAK 80
     118#define CR_START_BREAK 96
     119#define CR_STOP_BREAK 112
     120
     121#define SR_RXRDY 1
     122#define SR_FFULL 2
     123#define SR_TXRDY 4
     124#define SR_TXEMPT 8
     125#define SR_OVERRUN 16
     126#define SR_PARITY 32
     127#define SR_FRAMING 64
     128#define SR_BREAK 128
     129
     130
     131#endif
  • drivers/char/pc_keyb.c

    diff -Naur linux-2.4.26/drivers/char/pc_keyb.c linux-2.4.26-m68k/drivers/char/pc_keyb.c
    old new  
    898898
    899899void __init pckbd_init_hw(void)
    900900{
     901        unsigned long flags;
     902
    901903        if (!kbd_controller_present()) {
    902904                kbd_exists = 0;
    903905                return;
     
    905907
    906908        kbd_request_region();
    907909
     910        save_flags(flags);
     911        cli();
     912
    908913        /* Flush any pending input. */
    909914        kbd_clear_input();
    910915
     
    922927
    923928        /* Ok, finally allocate the IRQ, and off we go.. */
    924929        kbd_request_irq(keyboard_interrupt);
     930
     931        restore_flags(flags);
    925932}
    926933
    927934#if defined CONFIG_PSMOUSE
  • drivers/char/plip_ioext.c

    diff -Naur linux-2.4.26/drivers/char/plip_ioext.c linux-2.4.26-m68k/drivers/char/plip_ioext.c
    old new  
     1/*
     2 * plip_ioext: A parallel port "network" driver for GVP IO-Extender.
     3 *
     4 * Authors:     See drivers/net/plip.c
     5 *              IO-Extender version by Steve Bennett, <msteveb@ozemail.com.au>
     6 *
     7 * This driver is for use with a 5-bit cable (LapLink (R) cable).
     8 */
     9
     10static const char *version = "NET3 PLIP version 2.2/m68k";
     11
     12#define __NO_VERSION__
     13
     14#include <linux/module.h>
     15#include <linux/types.h>
     16#include <linux/sched.h>
     17#include <linux/errno.h>
     18#include <linux/interrupt.h>
     19#include <linux/slab.h>
     20#include <linux/termios.h>
     21#include <linux/tty.h>
     22#include <linux/serial.h>
     23
     24#include <asm/setup.h>
     25#include <asm/irq.h>
     26#include <asm/amigahw.h>
     27#include <asm/amigaints.h>
     28#include <linux/zorro.h>
     29
     30#include <linux/config.h>
     31#include <linux/kernel.h>
     32#include <linux/fcntl.h>
     33#include <linux/string.h>
     34#include <linux/ptrace.h>
     35#include <linux/if_ether.h>
     36
     37#include <asm/system.h>
     38
     39#include <linux/in.h>
     40#include <linux/delay.h>
     41/*#include <linux/lp_m68k.h>*/
     42
     43#include <linux/netdevice.h>
     44#include <linux/etherdevice.h>
     45#include <linux/inetdevice.h>
     46#include <linux/skbuff.h>
     47#include <linux/if_plip.h>
     48
     49#include <linux/tqueue.h>
     50#include <linux/ioport.h>
     51#include <asm/bitops.h>
     52#include <asm/byteorder.h>
     53
     54#include "ioext.h"
     55
     56#define DEBUG 0
     57
     58/* Map 'struct device *' to our control structure */
     59#define PLIP_DEV(DEV) (&ioext_info[(DEV)->irq])
     60
     61/************************************************************************
     62**
     63** PLIP definitions
     64**
     65*************************************************************************
     66*/
     67
     68/* Use 0 for production, 1 for verification, >2 for debug */
     69#ifndef NET_DEBUG
     70#define NET_DEBUG 2
     71#endif
     72static unsigned int net_debug = NET_DEBUG;
     73
     74/* In micro second */
     75#define PLIP_DELAY_UNIT       1
     76
     77/* Connection time out = PLIP_TRIGGER_WAIT * PLIP_DELAY_UNIT usec */
     78#define PLIP_TRIGGER_WAIT        500
     79
     80/* Nibble time out = PLIP_NIBBLE_WAIT * PLIP_DELAY_UNIT usec */
     81#define PLIP_NIBBLE_WAIT        3000
     82
     83#define PAR_DATA(dev)     ((dev)->base_addr+0)
     84#define PAR_STATUS(dev)   ((dev)->base_addr+2)
     85#define PAR_CONTROL(dev)  ((dev)->base_addr+4)
     86
     87static void enable_par_irq(struct device *dev, int on);
     88static int plip_init(struct device *dev);
     89
     90/* Bottom halfs */
     91static void plip_kick_bh(struct device *dev);
     92static void plip_bh(struct device *dev);
     93
     94/* Functions for DEV methods */
     95static int plip_rebuild_header(struct sk_buff *skb);
     96static int plip_tx_packet(struct sk_buff *skb, struct device *dev);
     97static int plip_open(struct device *dev);
     98static int plip_close(struct device *dev);
     99static struct enet_statistics *plip_get_stats(struct device *dev);
     100static int plip_config(struct device *dev, struct ifmap *map);
     101static int plip_ioctl(struct device *dev, struct ifreq *ifr, int cmd);
     102
     103enum plip_connection_state {
     104        PLIP_CN_NONE=0,
     105        PLIP_CN_RECEIVE,
     106        PLIP_CN_SEND,
     107        PLIP_CN_CLOSING,
     108        PLIP_CN_ERROR
     109};
     110
     111enum plip_packet_state {
     112        PLIP_PK_DONE=0,
     113        PLIP_PK_TRIGGER,
     114        PLIP_PK_LENGTH_LSB,
     115        PLIP_PK_LENGTH_MSB,
     116        PLIP_PK_DATA,
     117        PLIP_PK_CHECKSUM
     118};
     119
     120enum plip_nibble_state {
     121        PLIP_NB_BEGIN,
     122        PLIP_NB_1,
     123        PLIP_NB_2,
     124};
     125
     126struct plip_local {
     127        enum plip_packet_state state;
     128        enum plip_nibble_state nibble;
     129        union {
     130                struct {
     131#if defined(__LITTLE_ENDIAN)
     132                        unsigned char lsb;
     133                        unsigned char msb;
     134#elif defined(__BIG_ENDIAN)
     135                        unsigned char msb;
     136                        unsigned char lsb;
     137#else
     138#error  "Please fix the endianness defines in <asm/byteorder.h>"
     139#endif           
     140                } b;
     141                unsigned short h;
     142        } length;
     143        unsigned short byte;
     144        unsigned char  checksum;
     145        unsigned char  data;
     146        struct sk_buff *skb;
     147};
     148
     149struct net_local {
     150        struct enet_statistics enet_stats;
     151        struct tq_struct immediate;
     152        struct tq_struct deferred;
     153        struct plip_local snd_data;
     154        struct plip_local rcv_data;
     155        unsigned long  trigger;
     156        unsigned long  nibble;
     157        enum plip_connection_state connection;
     158        unsigned short timeout_count;
     159        char is_deferred;
     160        int (*orig_rebuild_header)(struct sk_buff *skb);
     161};
     162
     163struct device ioext_dev_plip[] = {
     164        {
     165                "plip0",
     166                0, 0, 0, 0,    /* memory */
     167                0, 0,    /* base, irq */
     168                0, 0, 0, NULL, plip_init
     169        },
     170        {
     171                "plip1",
     172                0, 0, 0, 0,    /* memory */
     173                0, 0,    /* base, irq */
     174                0, 0, 0, NULL, plip_init
     175        },
     176        {
     177                "plip2",
     178                0, 0, 0, 0,    /* memory */
     179                0, 0,    /* base, irq */
     180                0, 0, 0, NULL, plip_init
     181        }
     182};
     183
     184/*
     185 * Check for and handle an interrupt for this PLIP device.
     186 *
     187 */
     188void ioext_plip_interrupt(struct device *dev, int *spurious_count)
     189{
     190        struct net_local *nl;
     191        struct plip_local *rcv;
     192        unsigned char c0;
     193        unsigned long flags;
     194
     195        nl = (struct net_local *)dev->priv;
     196        rcv = &nl->rcv_data;
     197
     198        c0 = z_readb(PAR_STATUS(dev));
     199
     200        if (dev->interrupt) {
     201                return;
     202        }
     203
     204        if ((c0 & 0xf8) != 0xc0) {
     205                /* Not for us */
     206                ++*spurious_count;
     207                return;
     208        }
     209
     210        *spurious_count = 0;
     211        dev->interrupt = 1;
     212
     213        save_flags(flags);
     214        cli();
     215
     216        switch (nl->connection) {
     217        case PLIP_CN_CLOSING:
     218                dev->tbusy = 0;
     219        case PLIP_CN_NONE:
     220        case PLIP_CN_SEND:
     221                dev->last_rx = jiffies;
     222                rcv->state = PLIP_PK_TRIGGER;
     223                nl->connection = PLIP_CN_RECEIVE;
     224                nl->timeout_count = 0;
     225                queue_task(&nl->immediate, &tq_immediate);
     226                mark_bh(IMMEDIATE_BH);
     227                restore_flags(flags);
     228#if 0
     229                printk("%s: receive irq in SEND/NONE/CLOSING (%d) ok\n",
     230                       dev->name, nl->connection);
     231#endif
     232                break;
     233
     234        case PLIP_CN_RECEIVE:
     235                restore_flags(flags);
     236                printk("%s: receive interrupt when receiving packet\n",
     237                       dev->name);
     238                break;
     239
     240        case PLIP_CN_ERROR:
     241                restore_flags(flags);
     242                printk("%s: receive interrupt in error state\n", dev->name);
     243                break;
     244        }
     245}
     246
     247
    0248
     249/* Bottom half handler for the delayed request.
     250   This routine is kicked by do_timer().
     251   Request `plip_bh' to be invoked. */
     252static void
     253plip_kick_bh(struct device *dev)
     254{
     255        struct net_local *nl = (struct net_local *)dev->priv;
     256
     257        if (nl->is_deferred) {
     258                queue_task(&nl->immediate, &tq_immediate);
     259                mark_bh(IMMEDIATE_BH);
     260        }
     261}
     262
     263/* Forward declarations of internal routines */
     264static int plip_none(struct device *, struct net_local *,
     265                     struct plip_local *, struct plip_local *);
     266static int plip_receive_packet(struct device *, struct net_local *,
     267                               struct plip_local *, struct plip_local *);
     268static int plip_send_packet(struct device *, struct net_local *,
     269                            struct plip_local *, struct plip_local *);
     270static int plip_connection_close(struct device *, struct net_local *,
     271                                 struct plip_local *, struct plip_local *);
     272static int plip_error(struct device *, struct net_local *,
     273                      struct plip_local *, struct plip_local *);
     274static int plip_bh_timeout_error(struct device *dev, struct net_local *nl,
     275                                 struct plip_local *snd,
     276                                 struct plip_local *rcv,
     277                                 int error);
     278
     279#define OK        0
     280#define TIMEOUT   1
     281#define ERROR     2
     282
     283typedef int (*plip_func)(struct device *dev, struct net_local *nl,
     284                         struct plip_local *snd, struct plip_local *rcv);
     285
     286static plip_func connection_state_table[] =
     287{
     288        plip_none,
     289        plip_receive_packet,
     290        plip_send_packet,
     291        plip_connection_close,
     292        plip_error
     293};
     294
     295/*
     296** enable_par_irq()
     297**
     298** Enable or disable parallel irq for 'dev' according to 'on'.
     299**
     300** It is NOT possible to disable only the parallel irq.
     301** So we disable the board interrupt instead. This means that
     302** during reception of a PLIP packet, no serial interrupts can
     303** happen. Sorry.
     304*/
     305static void enable_par_irq(struct device *dev, int on)
     306{
     307        if (on) {
     308                PLIP_DEV(dev)->board->CNTR |= GVP_IRQ_ENA;
     309        }
     310        else {
     311                PLIP_DEV(dev)->board->CNTR &= ~GVP_IRQ_ENA;
     312        }
     313}
     314
     315/* Bottom half handler of PLIP. */
     316static void
     317plip_bh(struct device *dev)
     318{
     319        struct net_local *nl = (struct net_local *)dev->priv;
     320        struct plip_local *snd = &nl->snd_data;
     321        struct plip_local *rcv = &nl->rcv_data;
     322        plip_func f;
     323        int r;
     324
     325        nl->is_deferred = 0;
     326        f = connection_state_table[nl->connection];
     327        if ((r = (*f)(dev, nl, snd, rcv)) != OK
     328            && (r = plip_bh_timeout_error(dev, nl, snd, rcv, r)) != OK) {
     329                nl->is_deferred = 1;
     330                queue_task(&nl->deferred, &tq_timer);
     331        }
     332}
     333
     334static int
     335plip_bh_timeout_error(struct device *dev, struct net_local *nl,
     336                      struct plip_local *snd, struct plip_local *rcv,
     337                      int error)
     338{
     339        unsigned char c0;
     340        unsigned long flags;
     341
     342        save_flags(flags);
     343        cli();
     344        if (nl->connection == PLIP_CN_SEND) {
     345
     346                if (error != ERROR) { /* Timeout */
     347                        nl->timeout_count++;
     348                        if ((snd->state == PLIP_PK_TRIGGER
     349                             && nl->timeout_count <= 10)
     350                            || nl->timeout_count <= 3) {
     351                                restore_flags(flags);
     352                                /* Try again later */
     353                                return TIMEOUT;
     354                        }
     355                        c0 = z_readb(PAR_STATUS(dev));
     356                        printk(KERN_INFO "%s: transmit timeout(%d,%02x)\n",
     357                               dev->name, snd->state, c0);
     358                }
     359                nl->enet_stats.tx_errors++;
     360                nl->enet_stats.tx_aborted_errors++;
     361        } else if (nl->connection == PLIP_CN_RECEIVE) {
     362                if (rcv->state == PLIP_PK_TRIGGER) {
     363                        /* Transmission was interrupted. */
     364                        restore_flags(flags);
     365                        return OK;
     366                }
     367                if (error != ERROR) { /* Timeout */
     368                        if (++nl->timeout_count <= 3) {
     369                                restore_flags(flags);
     370                                /* Try again later */
     371                                return TIMEOUT;
     372                        }
     373                        c0 = z_readb(PAR_STATUS(dev));
     374                        printk(KERN_INFO "%s: receive timeout(%d,%02x)\n",
     375                               dev->name, rcv->state, c0);
     376                }
     377                nl->enet_stats.rx_dropped++;
     378        }
     379        rcv->state = PLIP_PK_DONE;
     380        if (rcv->skb) {
     381                kfree_skb(rcv->skb);
     382                rcv->skb = NULL;
     383        }
     384        snd->state = PLIP_PK_DONE;
     385        if (snd->skb) {
     386                dev_kfree_skb(snd->skb);
     387                snd->skb = NULL;
     388        }
     389        enable_par_irq(dev, 0);
     390        dev->tbusy = 1;
     391        nl->connection = PLIP_CN_ERROR;
     392        z_writeb(0x00, PAR_DATA(dev));
     393        restore_flags(flags);
     394
     395        return TIMEOUT;
     396}
     397
     398static int
     399plip_none(struct device *dev, struct net_local *nl,
     400          struct plip_local *snd, struct plip_local *rcv)
     401{
     402        return OK;
     403}
     404
     405/* PLIP_RECEIVE --- receive a byte(two nibbles)
     406   Returns OK on success, TIMEOUT on timeout */
     407inline static int
     408plip_receive(struct device *dev, unsigned short nibble_timeout,
     409             enum plip_nibble_state *ns_p, unsigned char *data_p)
     410{
     411        unsigned char c0, c1;
     412        unsigned int cx;
     413
     414        switch (*ns_p) {
     415        case PLIP_NB_BEGIN:
     416                cx = nibble_timeout;
     417                while (1) {
     418                        c0 = z_readb(PAR_STATUS(dev));
     419                        udelay(PLIP_DELAY_UNIT);
     420                        if ((c0 & 0x80) == 0) {
     421                                c1 = z_readb(PAR_STATUS(dev));
     422                                if (c0 == c1)
     423                                        break;
     424                        }
     425                        if (--cx == 0)
     426                                return TIMEOUT;
     427                }
     428#if 0
     429                printk("received first nybble: %02X -> %02X\n",
     430                       c0, (c0 >> 3) & 0x0F);
     431#endif
     432                *data_p = (c0 >> 3) & 0x0f;
     433                z_writeb(0x10, PAR_DATA(dev)); /* send ACK */
     434                *ns_p = PLIP_NB_1;
     435
     436        case PLIP_NB_1:
     437                cx = nibble_timeout;
     438                while (1) {
     439                        c0 = z_readb(PAR_STATUS(dev));
     440                        udelay(PLIP_DELAY_UNIT);
     441                        if (c0 & 0x80) {
     442                                c1 = z_readb(PAR_STATUS(dev));
     443                                if (c0 == c1)
     444                                        break;
     445                        }
     446                        if (--cx == 0)
     447                                return TIMEOUT;
     448                }
     449#if 0
     450                printk("received second nybble: %02X -> %02X\n",
     451                       c0, (c0 << 1) & 0xF0);
     452#endif
     453                *data_p |= (c0 << 1) & 0xf0;
     454                z_writeb(0x00, PAR_DATA(dev)); /* send ACK */
     455                *ns_p = PLIP_NB_BEGIN;
     456        case PLIP_NB_2:
     457                break;
     458        }
     459        return OK;
     460}
     461
     462/* PLIP_RECEIVE_PACKET --- receive a packet */
     463static int
     464plip_receive_packet(struct device *dev, struct net_local *nl,
     465                    struct plip_local *snd, struct plip_local *rcv)
     466{
     467        unsigned short nibble_timeout = nl->nibble;
     468        unsigned char *lbuf;
     469        unsigned long flags;
     470
     471        switch (rcv->state) {
     472        case PLIP_PK_TRIGGER:
     473                enable_par_irq(dev, 0);
     474                dev->interrupt = 0;
     475                z_writeb(0x01, PAR_DATA(dev)); /* send ACK */
     476                if (net_debug > 2)
     477                        printk(KERN_DEBUG "%s: receive start\n", dev->name);
     478                rcv->state = PLIP_PK_LENGTH_LSB;
     479                rcv->nibble = PLIP_NB_BEGIN;
     480
     481        case PLIP_PK_LENGTH_LSB:
     482                if (snd->state != PLIP_PK_DONE) {
     483                        if (plip_receive(dev, nl->trigger,
     484                                         &rcv->nibble, &rcv->length.b.lsb)) {
     485                                /* collision, here dev->tbusy == 1 */
     486                                rcv->state = PLIP_PK_DONE;
     487                                nl->is_deferred = 1;
     488                                nl->connection = PLIP_CN_SEND;
     489                                queue_task(&nl->deferred, &tq_timer);
     490                                enable_par_irq(dev, 1);
     491                                return OK;
     492                        }
     493                } else {
     494                        if (plip_receive(dev, nibble_timeout,
     495                                         &rcv->nibble, &rcv->length.b.lsb))
     496                                return TIMEOUT;
     497                }
     498                rcv->state = PLIP_PK_LENGTH_MSB;
     499
     500        case PLIP_PK_LENGTH_MSB:
     501                if (plip_receive(dev, nibble_timeout,
     502                                 &rcv->nibble, &rcv->length.b.msb))
     503                        return TIMEOUT;
     504                if (rcv->length.h > dev->mtu + dev->hard_header_len
     505                    || rcv->length.h < 8) {
     506                        printk(KERN_INFO "%s: bogus packet size %d.\n",
     507                               dev->name, rcv->length.h);
     508                        return ERROR;
     509                }
     510                /* Malloc up new buffer. */
     511                rcv->skb = dev_alloc_skb(rcv->length.h);
     512                if (rcv->skb == NULL) {
     513                        printk(KERN_INFO "%s: Memory squeeze.\n", dev->name);
     514                        return ERROR;
     515                }
     516                skb_put(rcv->skb,rcv->length.h);
     517                rcv->skb->dev = dev;
     518                rcv->state = PLIP_PK_DATA;
     519                rcv->byte = 0;
     520                rcv->checksum = 0;
     521
     522        case PLIP_PK_DATA:
     523                lbuf = rcv->skb->data;
     524                do
     525                        if (plip_receive(dev, nibble_timeout,
     526                                         &rcv->nibble, &lbuf[rcv->byte]))
     527                                return TIMEOUT;
     528                while (++rcv->byte < rcv->length.h);
     529                do
     530                        rcv->checksum += lbuf[--rcv->byte];
     531                while (rcv->byte);
     532                rcv->state = PLIP_PK_CHECKSUM;
     533
     534        case PLIP_PK_CHECKSUM:
     535                if (plip_receive(dev, nibble_timeout,
     536                                 &rcv->nibble, &rcv->data))
     537                        return TIMEOUT;
     538                if (rcv->data != rcv->checksum) {
     539                        nl->enet_stats.rx_crc_errors++;
     540                        if (net_debug)
     541                                printk(KERN_INFO "%s: checksum error\n",
     542                                       dev->name);
     543                        return ERROR;
     544                }
     545                rcv->state = PLIP_PK_DONE;
     546
     547        case PLIP_PK_DONE:
     548                /* Inform the upper layer for the arrival of a packet. */
     549                rcv->skb->protocol=eth_type_trans(rcv->skb, dev);
     550                netif_rx(rcv->skb);
     551                nl->enet_stats.rx_packets++;
     552                rcv->skb = NULL;
     553                if (net_debug > 2)
     554                        printk(KERN_DEBUG "%s: receive end\n", dev->name);
     555
     556                /* Close the connection. */
     557                z_writeb (0x00, PAR_DATA(dev));
     558
     559                save_flags(flags);
     560                cli();
     561                if (snd->state != PLIP_PK_DONE) {
     562                        nl->connection = PLIP_CN_SEND;
     563                        restore_flags(flags);
     564                        queue_task(&nl->immediate, &tq_immediate);
     565                        mark_bh(IMMEDIATE_BH);
     566                        enable_par_irq(dev, 1);
     567                        return OK;
     568                } else {
     569                        nl->connection = PLIP_CN_NONE;
     570                        restore_flags(flags);
     571                        enable_par_irq(dev, 1);
     572                        return OK;
     573                }
     574        }
     575        return OK;
     576}
     577
     578/* PLIP_SEND --- send a byte (two nibbles)
     579   Returns OK on success, TIMEOUT when timeout    */
     580inline static int
     581plip_send(struct device *dev, unsigned short nibble_timeout,
     582          enum plip_nibble_state *ns_p, unsigned char data)
     583{
     584        unsigned char c0;
     585        unsigned int cx;
     586
     587        switch (*ns_p) {
     588        case PLIP_NB_BEGIN:
     589                z_writeb((data & 0x0f), PAR_DATA(dev));
     590                *ns_p = PLIP_NB_1;
     591
     592        case PLIP_NB_1:
     593                z_writeb(0x10 | (data & 0x0f), PAR_DATA(dev));
     594                cx = nibble_timeout;
     595                while (1) {
     596                        c0 = z_readb(PAR_STATUS(dev));
     597                        if ((c0 & 0x80) == 0)
     598                                break;
     599                        if (--cx == 0)
     600                                return TIMEOUT;
     601                        udelay(PLIP_DELAY_UNIT);
     602                }
     603                z_writeb(0x10 | (data >> 4), PAR_DATA(dev));
     604                *ns_p = PLIP_NB_2;
     605
     606        case PLIP_NB_2:
     607                z_writeb((data >> 4), PAR_DATA(dev));
     608                cx = nibble_timeout;
     609                while (1) {
     610                        c0 = z_readb(PAR_STATUS(dev));
     611                        if (c0 & 0x80)
     612                                break;
     613                        if (--cx == 0)
     614                                return TIMEOUT;
     615                        udelay(PLIP_DELAY_UNIT);
     616                }
     617                *ns_p = PLIP_NB_BEGIN;
     618                return OK;
     619        }
     620        return OK;
     621}
     622
     623/* PLIP_SEND_PACKET --- send a packet */
     624static int
     625plip_send_packet(struct device *dev, struct net_local *nl,
     626                 struct plip_local *snd, struct plip_local *rcv)
     627{
     628        unsigned short nibble_timeout = nl->nibble;
     629        unsigned char *lbuf;
     630        unsigned char c0;
     631        unsigned int cx;
     632        unsigned long flags;
     633
     634        if (snd->skb == NULL || (lbuf = snd->skb->data) == NULL) {
     635                printk(KERN_INFO "%s: send skb lost\n", dev->name);
     636                snd->state = PLIP_PK_DONE;
     637                snd->skb = NULL;
     638                return ERROR;
     639        }
     640
     641        if (snd->length.h == 0) {
     642                return OK;
     643        }
     644
     645        switch (snd->state) {
     646        case PLIP_PK_TRIGGER:
     647                if ((z_readb(PAR_STATUS(dev)) & 0xf8) != 0x80)
     648                        return TIMEOUT;
     649
     650                /* Trigger remote rx interrupt. */
     651                z_writeb(0x08, PAR_DATA(dev));
     652                cx = nl->trigger;
     653                while (1) {
     654                        udelay(PLIP_DELAY_UNIT);
     655                        save_flags(flags);
     656                        cli();
     657                        if (nl->connection == PLIP_CN_RECEIVE) {
     658                                restore_flags(flags);
     659                                /* interrupted */
     660                                nl->enet_stats.collisions++;
     661                                if (net_debug > 1)
     662                                        printk(KERN_INFO "%s: collision.\n",
     663                                               dev->name);
     664                                return OK;
     665                        }
     666                        c0 = z_readb(PAR_STATUS(dev));
     667                        if (c0 & 0x08) {
     668                                enable_par_irq(dev, 0);
     669                                if (net_debug > 2)
     670                                        printk(KERN_DEBUG "%s: send start\n",
     671                                               dev->name);
     672                                snd->state = PLIP_PK_LENGTH_LSB;
     673                                snd->nibble = PLIP_NB_BEGIN;
     674                                nl->timeout_count = 0;
     675                                restore_flags(flags);
     676                                break;
     677                        }
     678                        restore_flags(flags);
     679                        if (--cx == 0) {
     680                                z_writeb(0x00, PAR_DATA(dev));
     681                                return TIMEOUT;
     682                        }
     683                }
     684
     685        case PLIP_PK_LENGTH_LSB:
     686                if (plip_send(dev, nibble_timeout,
     687                              &snd->nibble, snd->length.b.lsb))
     688                        return TIMEOUT;
     689                snd->state = PLIP_PK_LENGTH_MSB;
     690
     691        case PLIP_PK_LENGTH_MSB:
     692                if (plip_send(dev, nibble_timeout,
     693                              &snd->nibble, snd->length.b.msb))
     694                        return TIMEOUT;
     695                snd->state = PLIP_PK_DATA;
     696                snd->byte = 0;
     697                snd->checksum = 0;
     698
     699        case PLIP_PK_DATA:
     700                do
     701                        if (plip_send(dev, nibble_timeout,
     702                                      &snd->nibble, lbuf[snd->byte]))
     703                                return TIMEOUT;
     704                while (++snd->byte < snd->length.h);
     705                do
     706                        snd->checksum += lbuf[--snd->byte];
     707                while (snd->byte);
     708                snd->state = PLIP_PK_CHECKSUM;
     709
     710        case PLIP_PK_CHECKSUM:
     711                if (plip_send(dev, nibble_timeout,
     712                              &snd->nibble, snd->checksum))
     713                        return TIMEOUT;
     714
     715                dev_kfree_skb(snd->skb);
     716                nl->enet_stats.tx_packets++;
     717                snd->state = PLIP_PK_DONE;
     718
     719        case PLIP_PK_DONE:
     720                /* Close the connection */
     721                z_writeb (0x00, PAR_DATA(dev));
     722                snd->skb = NULL;
     723                if (net_debug > 2)
     724                        printk(KERN_DEBUG "%s: send end\n", dev->name);
     725                nl->connection = PLIP_CN_CLOSING;
     726                nl->is_deferred = 1;
     727                queue_task(&nl->deferred, &tq_timer);
     728                enable_par_irq(dev, 1);
     729                return OK;
     730        }
     731        return OK;
     732}
     733
     734static int
     735plip_connection_close(struct device *dev, struct net_local *nl,
     736                      struct plip_local *snd, struct plip_local *rcv)
     737{
     738        unsigned long flags;
     739
     740        save_flags(flags);
     741        cli();
     742        if (nl->connection == PLIP_CN_CLOSING) {
     743                nl->connection = PLIP_CN_NONE;
     744                dev->tbusy = 0;
     745                mark_bh(NET_BH);
     746        }
     747        restore_flags(flags);
     748        return OK;
     749}
     750
     751/* PLIP_ERROR --- wait till other end settled */
     752static int
     753plip_error(struct device *dev, struct net_local *nl,
     754           struct plip_local *snd, struct plip_local *rcv)
     755{
     756        unsigned char status;
     757
     758        status = z_readb(PAR_STATUS(dev));
     759        if ((status & 0xf8) == 0x80) {
     760                if (net_debug > 2)
     761                        printk(KERN_DEBUG "%s: reset interface.\n", dev->name);
     762                nl->connection = PLIP_CN_NONE;
     763                dev->tbusy = 0;
     764                dev->interrupt = 0;
     765                enable_par_irq(dev, 1);
     766                mark_bh(NET_BH);
     767        } else {
     768                nl->is_deferred = 1;
     769                queue_task(&nl->deferred, &tq_timer);
     770        }
     771
     772        return OK;
     773}
     774
     775/* We don't need to send arp, for plip is point-to-point. */
     776static int
     777plip_rebuild_header(struct sk_buff *skb)
     778{
     779        struct device *dev = skb->dev;
     780        struct net_local *nl = (struct net_local *)dev->priv;
     781        struct ethhdr *eth = (struct ethhdr *)skb->data;
     782        int i;
     783
     784        if ((dev->flags & IFF_NOARP)==0)
     785                return nl->orig_rebuild_header(skb);
     786
     787        if (eth->h_proto != __constant_htons(ETH_P_IP)
     788#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
     789            && eth->h_proto != __constant_htons(ETH_P_IPV6)
     790#endif
     791                ) {
     792                printk(KERN_ERR "plip_rebuild_header: Don't know how to resolve type %d addresses?\n", (int)eth->h_proto);
     793                memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
     794                return 0;
     795        }
     796
     797        for (i=0; i < ETH_ALEN - sizeof(u32); i++)
     798                eth->h_dest[i] = 0xfc;
     799#if 0
     800        *(u32 *)(eth->h_dest+i) = dst;
     801#else
     802        /* Do not want to include net/route.h here.
     803         * In any case, it is TOP of silliness to emulate
     804         * hardware addresses on PtP link. --ANK
     805         */
     806        *(u32 *)(eth->h_dest+i) = 0;
     807#endif
     808        return 0;
     809}
     810
     811static int
     812plip_tx_packet(struct sk_buff *skb, struct device *dev)
     813{
     814        struct net_local *nl = (struct net_local *)dev->priv;
     815        struct plip_local *snd = &nl->snd_data;
     816        unsigned long flags;
     817
     818        if (dev->tbusy)
     819                return 1;
     820
     821        if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
     822                printk(KERN_ERR "%s: Transmitter access conflict.\n",
     823                       dev->name);
     824                return 1;
     825        }
     826
     827        if (skb->len > dev->mtu + dev->hard_header_len) {
     828                printk(KERN_ERR "%s: packet too big, %d.\n",
     829                       dev->name, (int)skb->len);
     830                dev->tbusy = 0;
     831                return 0;
     832        }
     833
     834        if (net_debug > 2)
     835                printk(KERN_DEBUG "%s: send request\n", dev->name);
     836
     837        save_flags(flags);
     838        cli();
     839        dev->trans_start = jiffies;
     840        snd->skb = skb;
     841        snd->length.h = skb->len;
     842        snd->state = PLIP_PK_TRIGGER;
     843        if (nl->connection == PLIP_CN_NONE) {
     844                nl->connection = PLIP_CN_SEND;
     845                nl->timeout_count = 0;
     846        }
     847        queue_task(&nl->immediate, &tq_immediate);
     848        mark_bh(IMMEDIATE_BH);
     849        restore_flags(flags);
     850
     851        return 0;
     852}
     853
     854/* Open/initialize the board.  This is called (in the current kernel)
     855   sometime after booting when the 'ifconfig' program is run.
     856
     857 */
     858static int
     859plip_open(struct device *dev)
     860{
     861        struct net_local *nl = (struct net_local *)dev->priv;
     862        struct in_device *in_dev;
     863
     864#if defined(CONFIG_GVPIOEXT_LP) || defined(CONFIG_GVPIOEXT_LP_MODULE)
     865        /* Yes, there is a race condition here. Fix it later */
     866        if (PLIP_DEV(dev)->par_use & IOEXT_PAR_LP) {
     867                /* Can't open if lp is in use */
     868#if DEBUG
     869                printk("par is in use by lp\n");
     870#endif
     871                return(-EBUSY);
     872        }
     873#endif
     874        PLIP_DEV(dev)->par_use |= IOEXT_PAR_PLIP;
     875
     876#if DEBUG
     877        printk("plip_open(): sending 00 to data port\n");
     878#endif
     879
     880        /* Clear the data port. */
     881        z_writeb (0x00, PAR_DATA(dev));
     882
     883#if DEBUG
     884        printk("plip_open(): sent\n");
     885#endif
     886
     887        /* Initialize the state machine. */
     888        nl->rcv_data.state = nl->snd_data.state = PLIP_PK_DONE;
     889        nl->rcv_data.skb = nl->snd_data.skb = NULL;
     890        nl->connection = PLIP_CN_NONE;
     891        nl->is_deferred = 0;
     892
     893        /* Fill in the MAC-level header.
     894           (ab)Use "dev->broadcast" to store point-to-point MAC address.
     895
     896           PLIP doesn't have a real mac address, but we need to create one
     897           to be DOS compatible.  */
     898        memset(dev->dev_addr,  0xfc, ETH_ALEN);
     899        memset(dev->broadcast, 0xfc, ETH_ALEN);
     900
     901        if ((in_dev=dev->ip_ptr) != NULL) {
     902                /*
     903                 *      Any address will do - we take the first
     904                 */
     905                struct in_ifaddr *ifa=in_dev->ifa_list;
     906                if (ifa != NULL) {
     907                        memcpy(dev->dev_addr+2, &ifa->ifa_local, 4);
     908                        memcpy(dev->broadcast+2, &ifa->ifa_address, 4);
     909                }
     910        }
     911
     912        dev->interrupt = 0;
     913        dev->start = 1;
     914        dev->tbusy = 0;
     915
     916        MOD_INC_USE_COUNT;
     917
     918        /* Enable rx interrupt. */
     919        enable_par_irq(dev, 1);
     920
     921        return 0;
     922}
     923
     924/* The inverse routine to plip_open (). */
     925static int
     926plip_close(struct device *dev)
     927{
     928        struct net_local *nl = (struct net_local *)dev->priv;
     929        struct plip_local *snd = &nl->snd_data;
     930        struct plip_local *rcv = &nl->rcv_data;
     931        unsigned long flags;
     932
     933        dev->tbusy = 1;
     934        dev->start = 0;
     935        save_flags(flags);
     936        cli();
     937        nl->is_deferred = 0;
     938        nl->connection = PLIP_CN_NONE;
     939        restore_flags(flags);
     940        z_writeb(0x00, PAR_DATA(dev));
     941
     942        snd->state = PLIP_PK_DONE;
     943        if (snd->skb) {
     944                dev_kfree_skb(snd->skb);
     945                snd->skb = NULL;
     946        }
     947        rcv->state = PLIP_PK_DONE;
     948        if (rcv->skb) {
     949                kfree_skb(rcv->skb);
     950                rcv->skb = NULL;
     951        }
     952
     953        PLIP_DEV(dev)->par_use &= ~IOEXT_PAR_PLIP;
     954
     955        MOD_DEC_USE_COUNT;
     956        return 0;
     957}
     958
     959static struct enet_statistics *
     960plip_get_stats(struct device *dev)
     961{
     962        struct net_local *nl = (struct net_local *)dev->priv;
     963        struct enet_statistics *r = &nl->enet_stats;
     964
     965        return r;
     966}
     967
     968static int
     969plip_config(struct device *dev, struct ifmap *map)
     970{
     971        if (dev->flags & IFF_UP)
     972                return -EBUSY;
     973
     974        printk(KERN_INFO "%s: This interface is autodetected (ignored).\n",
     975               dev->name);
     976
     977        return 0;
     978}
     979
     980static int
     981plip_ioctl(struct device *dev, struct ifreq *rq, int cmd)
     982{
     983        struct net_local *nl = (struct net_local *) dev->priv;
     984        struct plipconf *pc = (struct plipconf *) &rq->ifr_data;
     985 
     986        switch(pc->pcmd) {
     987        case PLIP_GET_TIMEOUT:
     988                pc->trigger = nl->trigger;
     989                pc->nibble  = nl->nibble;
     990                break;
     991        case PLIP_SET_TIMEOUT:
     992                nl->trigger = pc->trigger;
     993                nl->nibble  = pc->nibble;
     994                break;
     995        default:
     996                return -EOPNOTSUPP;
     997        }
     998        return 0;
     999}
     1000
     1001/*
     1002 * Detect and initialize all IO-Extenders in this system.
     1003 *
     1004 * Both PLIP and serial devices are configured.
     1005 */
     1006int plip_init(struct device *dev)
     1007{
     1008        IOEXT_struct *board;
     1009        struct net_local *nl;
     1010
     1011        if (ioext_num == 0) {
     1012                printk(KERN_INFO "%s\n", version);
     1013        }
     1014
     1015        board = PLIP_DEV(dev)->board;
     1016        dev->base_addr = (unsigned long)&board->par.DATA;
     1017
     1018        /* Cheat and use irq to index into our table */
     1019        dev->irq = ioext_num;
     1020
     1021        printk(KERN_INFO "%s: IO-Extender parallel port at 0x%08lX\n", dev->name, dev->base_addr);
     1022
     1023        /* Fill in the generic fields of the device structure. */
     1024        ether_setup(dev);
     1025
     1026        /* Then, override parts of it */
     1027        dev->hard_start_xmit  = plip_tx_packet;
     1028        dev->open    = plip_open;
     1029        dev->stop    = plip_close;
     1030        dev->get_stats     = plip_get_stats;
     1031        dev->set_config    = plip_config;
     1032        dev->do_ioctl    = plip_ioctl;
     1033        dev->tx_queue_len  = 10;
     1034        dev->flags          = IFF_POINTOPOINT|IFF_NOARP;
     1035
     1036        /* Set the private structure */
     1037        dev->priv = kmalloc(sizeof (struct net_local), GFP_KERNEL);
     1038        if (dev->priv == NULL) {
     1039                printk(KERN_ERR "%s: out of memory\n", dev->name);
     1040                return -ENOMEM;
     1041        }
     1042        memset(dev->priv, 0, sizeof(struct net_local));
     1043        nl = (struct net_local *) dev->priv;
     1044
     1045        nl->orig_rebuild_header = dev->rebuild_header;
     1046        dev->rebuild_header   = plip_rebuild_header;
     1047
     1048        /* Initialize constants */
     1049        nl->trigger  = PLIP_TRIGGER_WAIT;
     1050        nl->nibble  = PLIP_NIBBLE_WAIT;
     1051
     1052        /* Initialize task queue structures */
     1053        nl->immediate.next = NULL;
     1054        nl->immediate.sync = 0;
     1055        nl->immediate.routine = (void *)(void *)plip_bh;
     1056        nl->immediate.data = dev;
     1057
     1058        nl->deferred.next = NULL;
     1059        nl->deferred.sync = 0;
     1060        nl->deferred.routine = (void *)(void *)plip_kick_bh;
     1061        nl->deferred.data = dev;
     1062
     1063        /* Don't enable interrupts yet */
     1064
     1065        return 0;
  • drivers/char/scc2692.c

    +}
    diff -Naur linux-2.4.26/drivers/char/scc2692.c linux-2.4.26-m68k/drivers/char/scc2692.c
    old new  
     1#include <linux/module.h>
     2#include <linux/config.h>
     3#include <linux/kdev_t.h>
     4#include <asm/io.h>
     5#include <linux/kernel.h>
     6#include <linux/sched.h>
     7#include <linux/ioport.h>
     8#include <linux/interrupt.h>
     9#include <linux/errno.h>
     10#include <linux/tty.h>
     11#include <linux/tty_flip.h>
     12#include <linux/mm.h>
     13#include <linux/serial.h>
     14#include <linux/fcntl.h>
     15#include <linux/major.h>
     16#include <linux/delay.h>
     17#include <linux/tqueue.h>
     18#include <linux/version.h>
     19#include <linux/slab.h>
     20#include <linux/miscdevice.h>
     21#include <linux/console.h>
     22#include <linux/init.h>
     23#include <asm/setup.h>
     24#include <asm/bootinfo.h>
     25
     26#include <asm/tekuart.h>
     27#include <asm/tekirq.h>
     28
     29#include <linux/generic_serial.h>
     30
     31#define NR_PORTS 2
     32
     33static struct scc_port
     34{
     35        struct gs_port  gs;
     36        unsigned long   base;
     37        int             irq_rx, irq_tx;
     38        unsigned char   channel;
     39        unsigned long   scale;
     40} scc_ports[NR_PORTS];
     41
     42#define STATUS(scc)     ((scc)->base + (((scc)->channel * 8 + 1) * (scc)->scale))
     43#define CSR(scc)        STATUS(scc)
     44
     45#define RECEIVE(scc)    ((scc)->base + (((scc)->channel * 8 + 3) * (scc)->scale))
     46#define TRANSMIT(scc)   RECEIVE(scc)
     47
     48#define COMMAND(scc)    ((scc)->base + (((scc)->channel * 8 + 2) * (scc)->scale))
     49
     50#define MR(scc)         ((scc)->base + (((scc)->channel * 8 + 0) * (scc)->scale))
     51
     52
     53static struct tty_driver scc_driver, scc_callout_driver;
     54static struct tty_struct *scc_table[NR_PORTS] = { NULL, NULL };
     55static struct termios *scc_termios[NR_PORTS];
     56static struct termios *scc_termios_locked[NR_PORTS];
     57
     58int scc_refcount;
     59
     60#define SCC_MINOR_BASE        64
     61#define SCC_MAGIC 0x52696368
     62
     63static inline void scc_disable_tx_interrupts(void *ptr)
     64{
     65        struct scc_port *port = ptr;
     66        disable_irq(port->irq_tx);
     67        port->gs.flags &= ~GS_TX_INTEN;
     68}
     69
     70static inline void scc_enable_tx_interrupts(void *ptr)
     71{
     72        struct scc_port *port = ptr;
     73        enable_irq(port->irq_tx);
     74}
     75
     76static inline void scc_disable_rx_interrupts(void *ptr)
     77{
     78        struct scc_port *port = ptr;
     79        disable_irq(port->irq_rx);
     80}
     81
     82static inline void scc_enable_rx_interrupts(void *ptr)
     83{
     84        struct scc_port *port = ptr;
     85        enable_irq(port->irq_rx);
     86}
     87
     88
     89/*
     90 * Receiver Interrupt
     91 */
     92static void scc_rx_int(int irq, void *data, struct pt_regs *fp)
     93{
     94        struct scc_port *port = data;
     95        struct tty_struct *tty = port->gs.tty;
     96        unsigned long flags;
     97        volatile unsigned char ch;
     98
     99        spin_lock_irqsave(tek_uart_lock, flags);
     100        while ( *(volatile unsigned char *)STATUS(port) & 0x1 )
     101        {
     102                ch = *(volatile unsigned char *)RECEIVE(port);
     103
     104                if (!tty)
     105                        /*
     106                         * FIXME: It might be a bad idea to call printk
     107                         *        with the lock held.
     108                         */
     109                        printk(KERN_WARNING "scc_rx_int with NULL tty!\n");
     110                else if (tty->flip.count < TTY_FLIPBUF_SIZE) {
     111                        *tty->flip.char_buf_ptr = ch;
     112                        *tty->flip.flag_buf_ptr = 0;
     113                        tty->flip.flag_buf_ptr++;
     114                        tty->flip.char_buf_ptr++;
     115                        tty->flip.count++;
     116                }
     117        }
     118        spin_unlock_irqrestore(tek_uart_lock, flags);
     119
     120        tty_flip_buffer_push(tty);
     121}
     122
     123/*
     124 * Transmitter interrupt
     125 */
     126static void scc_tx_int(int irq, void *data, struct pt_regs *fp)
     127{
     128        struct scc_port *port = data;
     129        struct tty_struct *tty = port->gs.tty;
     130        unsigned long flags;
     131
     132        if ( !tty )
     133        {
     134                scc_disable_tx_interrupts(port);
     135                return;
     136        }
     137       
     138        spin_lock_irqsave(tek_uart_lock, flags);
     139        while ( *(volatile unsigned char *)STATUS(port) & 0x4 )
     140        {
     141                *(volatile unsigned char *)TRANSMIT(port) =
     142                        port->gs.xmit_buf[port->gs.xmit_tail++];
     143                port->gs.xmit_tail = port->gs.xmit_tail & (SERIAL_XMIT_SIZE-1);
     144                if (--port->gs.xmit_cnt <= 0)
     145                        break;
     146        }
     147        spin_unlock_irqrestore(tek_uart_lock, flags);
     148
     149        if ((port->gs.xmit_cnt <= 0) || (tty && (tty->stopped || tty->hw_stopped)) )
     150        {
     151                scc_disable_tx_interrupts(port);
     152        }
     153
     154        if (tty && port->gs.xmit_cnt <= port->gs.wakeup_chars) {
     155                if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
     156                        (tty->ldisc.write_wakeup)(port->gs.tty);
     157                wake_up_interruptible(&tty->write_wait);
     158        }
     159}
     160
     161/*---------------------------------------------------------------------------
     162 * generic_serial.c callback funtions
     163 *--------------------------------------------------------------------------*/
     164
     165static int scc_get_CD(void *ptr)
     166{
     167        return 1;
     168}
     169
     170static void scc_shutdown_port(void *ptr)
     171{
     172        struct scc_port *port = ptr;
     173
     174        port->gs.flags &= ~ GS_ACTIVE;
     175}
     176
     177static const int baudrates[B38400] = {
     178        [B19200]        13,
     179        [B9600]         12,
     180        [B4800]         10,
     181        [B2400]         9,
     182        [B1200]         7,
     183        [B600]          6,
     184        [B300]          5,
     185        [B134]          3,
     186        [B110]          2,
     187        [B75]           1
     188};
     189
     190static int scc_set_real_termios(void *ptr)
     191{
     192        struct scc_port *port = ptr;
     193        unsigned long flags;
     194        unsigned int cflag;
     195        unsigned char baudrate = 0;
     196        unsigned char mr1 = 0x80, mr2 = 0;
     197        int baud;
     198
     199        if (!port->gs.tty || !port->gs.tty->termios)
     200                return 0;
     201
     202        cflag = port->gs.tty->termios->c_cflag;
     203        baud = cflag & (CBAUD | CBAUDEX);
     204
     205        if (baud == B0)
     206        {
     207                // TODO: hangup
     208                return 0;
     209        }
     210
     211        if ((baud >= sizeof baudrates/sizeof baudrates[0]) || !baudrates[baud])
     212                return -EINVAL;
     213        baudrate = baudrates[baud] - 1;
     214
     215        if ( cflag & CSTOPB )
     216                mr2 |= 0x7;     /* 1 stop bit */
     217
     218        if ( !(cflag & PARENB) )
     219                mr1 |= 0x10;    /* no parity */
     220        else if ( cflag & PARODD )
     221                mr1 |= 0x04;
     222
     223        switch (cflag & CSIZE)
     224        {
     225        case CS5:
     226                break;
     227        case CS6:
     228                mr1 |= 0x01;
     229                break;
     230        case CS7:
     231                mr1 |= 0x02;
     232                break;
     233        case CS8:
     234                mr1 |= 0x03;
     235                break;
     236        default:
     237                return -EINVAL;
     238        }
     239       
     240/*
     241        printk("scc2692: real_termios line=%d baudrate=%02x mr1=%02x mr2=%02x\n", port->channel, baudrate, mr1, mr2);
     242*/
     243
     244        spin_lock_irqsave(tek_uart_lock, flags);
     245
     246        // Set baudrate into register CSRA
     247        *(volatile unsigned char *)CSR(port) = (baudrate << 4) | (baudrate & 0xf);
     248        // Reset MR pointer
     249        *(volatile unsigned char *)COMMAND(port) = 1 << 4;
     250        // Set MR1
     251        *(volatile unsigned char *)MR(port) = mr1;
     252        // Set MR2
     253        *(volatile unsigned char *)MR(port) = mr2;
     254
     255        spin_unlock_irqrestore(tek_uart_lock, flags);
     256
     257        return 0;
     258}
     259
     260static int scc_chars_in_buffer(void *ptr)
     261{
     262        struct scc_port *port = ptr;
     263        int res;
     264        unsigned long flags;
     265
     266        spin_lock_irqsave(tek_uart_lock, flags);
     267        res = !(*(volatile unsigned char *)STATUS(port) & 4);
     268        spin_unlock_irqrestore(tek_uart_lock, flags);
     269
     270        return res;
     271}
     272
     273static void scc_hungup(void *ptr)
     274{
     275        scc_disable_tx_interrupts(ptr);
     276        scc_disable_rx_interrupts(ptr);
     277        MOD_DEC_USE_COUNT;
     278}
     279
     280static void scc_close(void *ptr)
     281{
     282        scc_disable_tx_interrupts(ptr);
     283        scc_disable_rx_interrupts(ptr);
     284        MOD_DEC_USE_COUNT;
     285}
     286
     287/*---------------------------------------------------------------------------
     288 * Driver entrypoints referenced from above
     289 *--------------------------------------------------------------------------*/
     290
     291static int scc_open (struct tty_struct * tty, struct file * filp)
     292{
     293        int line = MINOR(tty->device) - SCC_MINOR_BASE;
     294        int retval;
     295        struct scc_port *port = &scc_ports[line];
     296
     297        if ( line >= 2 )
     298                return -ENXIO;
     299
     300        tty->driver_data = port;
     301        port->gs.tty = tty;
     302        port->gs.count++;
     303        retval = gs_init_port(&port->gs);
     304        if (retval) {
     305                port->gs.count--;
     306                return retval;
     307        }
     308        port->gs.flags |= GS_ACTIVE;
     309        if (port->gs.count == 1) {
     310                MOD_INC_USE_COUNT;
     311        }
     312        retval = gs_block_til_ready(port, filp);
     313
     314        if (retval) {
     315                MOD_DEC_USE_COUNT;
     316                port->gs.count--;
     317                return retval;
     318        }
     319
     320        if ((port->gs.count == 1) && (port->gs.flags & ASYNC_SPLIT_TERMIOS)) {
     321                if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
     322                        *tty->termios = port->gs.normal_termios;
     323                else
     324                        *tty->termios = port->gs.callout_termios;
     325                scc_set_real_termios (port);
     326//              scc_disable_tx_interrupts(ptr);
     327        }
     328
     329        port->gs.session = current->session;
     330        port->gs.pgrp = current->pgrp;
     331
     332        scc_enable_rx_interrupts(port);
     333
     334        return 0;
     335}
     336
     337static void scc_throttle (struct tty_struct * tty)
     338{
     339/*
     340        struct scc_port *port = (struct scc_port *)tty->driver_data;
     341        unsigned long   flags;
     342        SCC_ACCESS_INIT(port);
     343
     344        if (tty->termios->c_cflag & CRTSCTS) {
     345                save_flags(flags);
     346                cli();
     347                SCCmod(TX_CTRL_REG, ~TCR_RTS, 0);
     348                restore_flags(flags);
     349        }
     350        if (I_IXOFF(tty))
     351                scc_send_xchar(tty, STOP_CHAR(tty));
     352*/
     353}
     354
     355static void scc_unthrottle (struct tty_struct * tty)
     356{
     357}
     358
     359static int scc_ioctl(struct tty_struct *tty, struct file *file,
     360                     unsigned int cmd, unsigned long arg)
     361{
     362        return -ENOIOCTLCMD;
     363}
     364
     365static void scc_break_ctl(struct tty_struct *tty, int break_state)
     366{
     367}
     368
     369/*---------------------------------------------------------------------------
     370 * Interface from generic_serial.c back here
     371 *--------------------------------------------------------------------------*/
     372
     373static struct real_driver scc_real_driver = {
     374        scc_disable_tx_interrupts,
     375        scc_enable_tx_interrupts,
     376        scc_disable_rx_interrupts,
     377        scc_enable_rx_interrupts,
     378        scc_get_CD,
     379        scc_shutdown_port,
     380        scc_set_real_termios,
     381        scc_chars_in_buffer,
     382        scc_close,
     383        scc_hungup,
     384        NULL
     385};
     386
     387
     388int __devinit scc_register_chip(struct scc_port *port)
     389{
     390        port->gs.callout_termios = tty_std_termios;
     391        port->gs.normal_termios = tty_std_termios;
     392        port->gs.magic = SCC_MAGIC;
     393        port->gs.close_delay = HZ/2;
     394        port->gs.closing_wait = 30 * HZ;
     395        port->gs.rd = &scc_real_driver;
     396#ifdef NEW_WRITE_LOCKING
     397        port->gs.port_write_sem = MUTEX;
     398#endif
     399
     400        init_waitqueue_head(&port->gs.open_wait);
     401        init_waitqueue_head(&port->gs.close_wait);
     402
     403        return 0;
     404}
     405
     406static int __devinit scc_chip_init(unsigned long base, int irq_rxa, int irq_txa,
     407                         int irq_rxb, int irq_txb)
     408{
     409        int err = 0;
     410        unsigned long flags;
     411
     412        scc_ports[0].base   = base;
     413        scc_ports[0].scale  = 4;
     414        scc_ports[0].irq_rx = irq_rxa;
     415        scc_ports[0].irq_tx = irq_txa;
     416        scc_ports[0].channel = 0;
     417
     418        scc_ports[1].base   = base;
     419        scc_ports[1].scale  = 4;
     420        scc_ports[1].irq_rx = irq_rxb;
     421        scc_ports[1].irq_tx = irq_txb;
     422        scc_ports[1].channel = 1;
     423
     424        save_flags(flags);
     425        cli();
     426
     427        err = request_irq(irq_rxa, scc_rx_int, SA_INTERRUPT, "SCC-A RX", &scc_ports[0]);
     428        if ( err < 0 )
     429                return err;
     430
     431        err = request_irq(irq_txa, scc_tx_int, SA_INTERRUPT, "SCC-A TX", &scc_ports[0]);
     432        if ( err < 0 )
     433        {
     434                free_irq(irq_rxa, &scc_ports[0]);
     435                return err;
     436        }
     437
     438        err = request_irq(irq_rxb, scc_rx_int, SA_INTERRUPT, "SCC-B RX", &scc_ports[1]);
     439        if ( err < 0 )
     440        {
     441                free_irq(irq_rxa, &scc_ports[0]);
     442                free_irq(irq_txa, &scc_ports[0]);
     443                return err;
     444        }
     445
     446        err = request_irq(irq_txb, scc_tx_int, SA_INTERRUPT, "SCC-B TX", &scc_ports[1]);
     447        if ( err < 0 )
     448        {
     449                free_irq(irq_rxa, &scc_ports[0]);
     450                free_irq(irq_txa, &scc_ports[0]);
     451                free_irq(irq_rxb, &scc_ports[1]);
     452                return err;
     453        }
     454
     455        disable_irq(irq_rxa);
     456        disable_irq(irq_txa);
     457        disable_irq(irq_rxb);
     458        disable_irq(irq_txb);
     459
     460        restore_flags(flags);
     461
     462        scc_register_chip(&scc_ports[0]);
     463        scc_register_chip(&scc_ports[1]);
     464
     465        return 0;
     466}
     467
     468int __devinit tekscc_init(void)
     469{
     470        int err = -ENXIO;
     471
     472#ifdef CONFIG_TEKXP
     473        err = scc_chip_init(TEK_UART_BASE, TEK_IRQ_RXRDY_A, TEK_IRQ_TXRDY_A,
     474                            TEK_IRQ_RXRDY_B, TEK_IRQ_TXRDY_B);
     475#endif
     476        if ( err < 0 )
     477                return err;
     478
     479        memset(&scc_driver, 0, sizeof(scc_driver));
     480        scc_driver.magic = TTY_DRIVER_MAGIC;
     481        scc_driver.driver_name = "scc2692";
     482#ifdef CONFIG_DEVFS_FS
     483        scc_driver.name = "tts/%d";
     484#else
     485        scc_driver.name = "ttyS";
     486#endif
     487        scc_driver.major = TTY_MAJOR;
     488        scc_driver.minor_start = SCC_MINOR_BASE;
     489        scc_driver.num = 2;
     490        scc_driver.type = TTY_DRIVER_TYPE_SERIAL;
     491        scc_driver.subtype = SERIAL_TYPE_NORMAL;
     492        scc_driver.init_termios = tty_std_termios;
     493        scc_driver.init_termios.c_cflag = B9600 | PARENB | CSTOPB | CS7 | CREAD | HUPCL | CLOCAL;
     494        scc_driver.flags = TTY_DRIVER_REAL_RAW;
     495        scc_driver.refcount = &scc_refcount;
     496        scc_driver.table = scc_table;
     497        scc_driver.termios = scc_termios;
     498        scc_driver.termios_locked = scc_termios_locked;
     499        scc_driver.open = scc_open;
     500        scc_driver.close = gs_close;
     501        scc_driver.write = gs_write;
     502        scc_driver.put_char = gs_put_char;
     503        scc_driver.flush_chars = gs_flush_chars;
     504        scc_driver.write_room = gs_write_room;
     505        scc_driver.chars_in_buffer = gs_chars_in_buffer;
     506        scc_driver.flush_buffer = gs_flush_buffer;
     507        scc_driver.ioctl = scc_ioctl;
     508        scc_driver.throttle = scc_throttle;
     509        scc_driver.unthrottle = scc_unthrottle;
     510        scc_driver.set_termios = gs_set_termios;
     511        scc_driver.stop = gs_stop;
     512        scc_driver.start = gs_start;
     513        scc_driver.hangup = gs_hangup;
     514        scc_driver.break_ctl = scc_break_ctl;
     515
     516        scc_callout_driver = scc_driver;
     517#ifdef CONFIG_DEVFS_FS
     518        scc_callout_driver.driver_name = "cua/%d";
     519#else
     520        scc_callout_driver.driver_name = "cua";
     521#endif
     522        scc_callout_driver.major = TTYAUX_MAJOR;
     523        scc_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
     524
     525        if ((err = tty_register_driver(&scc_driver))) {
     526                printk(KERN_ERR "scc2692: Couldn't register scc driver, error = %d\n", err);
     527                return -EBUSY;
     528        }
     529        if ((err = tty_register_driver(&scc_callout_driver))) {
     530                printk(KERN_ERR "scc2692: Couldn't register scc callout driver, error = %d\n", err);
     531                return -EBUSY;
     532        }
     533
     534        return 0;
     535}
     536
     537static void __devexit tekscc_exit(void)
     538{
     539        struct scc_port *port = &scc_ports[0];
     540        scc_disable_tx_interrupts(port);
     541        scc_disable_rx_interrupts(port);
     542        free_irq(port->irq_rx, port);
     543        free_irq(port->irq_tx, port);
     544
     545        port = &scc_ports[1];
     546        scc_disable_tx_interrupts(port);
     547        scc_disable_rx_interrupts(port);
     548        free_irq(port->irq_rx, port);
     549        free_irq(port->irq_tx, port);
     550
     551        if ( tty_unregister_driver(&scc_driver) )
     552                printk(KERN_ERR "Could not unregister SCC2692 serial driver\n");
     553        if ( tty_unregister_driver(&scc_callout_driver) )
     554                printk(KERN_ERR "Could not unregister SCC2692 callout driver\n");
     555}
     556
     557module_init(tekscc_init);
     558module_exit(tekscc_exit);
     559MODULE_LICENSE("GPL");
     560
     561#ifdef CONFIG_SERIAL_CONSOLE
     562
     563/*---------------------------------------------------------------------------
     564 * Serial console stuff...
     565 *--------------------------------------------------------------------------*/
     566
     567#define scc_delay() do { __asm__ __volatile__ (" nop; nop"); } while (0)
     568
     569static void scc_ch_write (char ch)
     570{
     571        tek_uart_putchar(0, ch, 1);
     572}
     573
     574static void scc_console_write (struct console *co, const char *str, unsigned count)
     575{
     576        unsigned long   flags;
     577
     578        save_flags(flags);
     579        cli();
     580
     581        while (count--)
     582        {
     583                if (*str == '\n')
     584                        scc_ch_write ('\r');
     585                scc_ch_write (*str++);
     586        }
     587        restore_flags(flags);
     588}
     589
     590static kdev_t scc_console_device(struct console *c)
     591{
     592        return MKDEV(TTY_MAJOR, SCC_MINOR_BASE + c->index);
     593}
     594
     595
     596static int __devinit scc_console_setup(struct console *co, char *options)
     597{
     598        return 0;
     599}
     600
     601static struct console sercons = {
     602        name:           "ttyS",
     603        write:          scc_console_write,
     604        device:         scc_console_device,
     605        setup:          scc_console_setup,
     606        flags:          CON_PRINTBUFFER,
     607        index:          -1,
     608};
     609
     610
     611void __init tekscc_console_init(void)
     612{
     613                register_console(&sercons);
     614}
     615
     616#endif
     617
  • drivers/char/tty_io.c

    diff -Naur linux-2.4.26/drivers/char/tty_io.c linux-2.4.26-m68k/drivers/char/tty_io.c
    old new  
    138138              unsigned int cmd, unsigned long arg);
    139139static int tty_fasync(int fd, struct file * filp, int on);
    140140extern int vme_scc_init (void);
     141extern int tekscc_init (void);
    141142extern long vme_scc_console_init(void);
     143extern long tekscc_console_init(void);
    142144extern int serial167_init(void);
    143145extern long serial167_console_init(void);
    144146extern void console_8xx_init(void);
     
    22692271#if defined(CONFIG_SERIAL167)
    22702272        serial167_console_init();
    22712273#endif
     2274#if defined(CONFIG_SCC2692)
     2275        tekscc_console_init();
     2276#endif
    22722277#if defined(CONFIG_SH_SCI)
    22732278        sci_console_init();
    22742279#endif
     
    24082413#if defined(CONFIG_MVME162_SCC) || defined(CONFIG_BVME6000_SCC) || defined(CONFIG_MVME147_SCC)
    24092414        vme_scc_init();
    24102415#endif
     2416#ifdef CONFIG_SCC2692
     2417        tekscc_init();
     2418#endif
    24112419#ifdef CONFIG_SERIAL_TX3912
    24122420        tx3912_rs_init();
    24132421#endif
  • drivers/ide/ide-probe.c

    diff -Naur linux-2.4.26/drivers/ide/ide-probe.c linux-2.4.26-m68k/drivers/ide/ide-probe.c
    old new  
    350350                rc = 0;
    351351                /* clear drive IRQ */
    352352                (void) hwif->INB(IDE_STATUS_REG);
     353                (void) ide_ack_intr(hwif);
    353354                local_irq_restore(flags);
    354355        } else {
    355356                /* drive refused ID */
     
    503504                                drive->name, hwif->INB(IDE_STATUS_REG));
    504505                /* ensure drive irq is clear */
    505506                (void) hwif->INB(IDE_STATUS_REG);
     507                (void) ide_ack_intr(hwif);
    506508        } else {
    507509                /* not present or maybe ATAPI */
    508510                rc = 3;
     
    513515                ide_delay_50ms();
    514516                /* ensure drive irq is clear */
    515517                (void) hwif->INB(IDE_STATUS_REG);
     518                (void) ide_ack_intr(hwif);
    516519        }
    517520        return rc;
    518521}
  • drivers/macintosh/adb.c

    diff -Naur linux-2.4.26/drivers/macintosh/adb.c linux-2.4.26-m68k/drivers/macintosh/adb.c
    old new  
    3535#include <linux/init.h>
    3636#include <linux/delay.h>
    3737#include <linux/completion.h>
     38
    3839#include <asm/uaccess.h>
    3940#ifdef CONFIG_PPC
    4041#include <asm/prom.h>
     
    380381       
    381382        if (adb_controller == NULL)
    382383                return -ENXIO;
    383                
     384       
    384385        if (adb_controller->autopoll)
    385386                adb_controller->autopoll(0);
    386387
    387388        nret = notifier_call_chain(&adb_client_list, ADB_MSG_PRE_RESET, NULL);
    388389        if (nret & NOTIFY_STOP_MASK) {
    389390                if (adb_controller->autopoll)
    390                         adb_controller->autopoll(devs);
     391                        adb_controller->autopoll(0);
    391392                return -EBUSY;
    392393        }
    393394
     
    467468                use_sreq = 1;
    468469        } else
    469470                use_sreq = 0;
    470         req->nbytes = nbytes+1;
     471        i = (flags & ADBREQ_RAW) ? 0 : 1;
     472        req->nbytes = nbytes+i;
    471473        req->done = done;
    472474        req->reply_expected = flags & ADBREQ_REPLY;
    473475        req->data[0] = ADB_PACKET;
    474476        va_start(list, nbytes);
    475         for (i = 0; i < nbytes; ++i)
    476                 req->data[i+1] = va_arg(list, int);
     477        while (i < req->nbytes) {
     478                req->data[i++] = va_arg(list, int);
     479        }
    477480        va_end(list);
    478481
    479482        if (flags & ADBREQ_NOSEND)
  • drivers/mtd/maps/Config.in

    diff -Naur linux-2.4.26/drivers/mtd/maps/Config.in linux-2.4.26-m68k/drivers/mtd/maps/Config.in
    old new  
    9696   dep_tristate '  Generic uClinux RAM/ROM filesystem support' CONFIG_MTD_UCLINUX $CONFIG_MTD_PARTITIONS
    9797fi
    9898
     99if [ "$CONFIG_TEKXP" = "y" ]; then
     100   dep_tristate '  TekXpress optional ROM support' CONFIG_MTD_TEKXP_OPTROM $CONFIG_MTD_ROM
     101fi
     102
    99103# This needs CFI or JEDEC, depending on the cards found.
    100104dep_tristate '  PCI MTD driver' CONFIG_MTD_PCI $CONFIG_MTD $CONFIG_PCI
    101105dep_tristate '  PCMCIA MTD driver' CONFIG_MTD_PCMCIA $CONFIG_MTD $CONFIG_PCMCIA
  • drivers/mtd/maps/Makefile

    diff -Naur linux-2.4.26/drivers/mtd/maps/Makefile linux-2.4.26-m68k/drivers/mtd/maps/Makefile
    old new  
    2222obj-$(CONFIG_MTD_L440GX)        += l440gx.o
    2323obj-$(CONFIG_MTD_AMD76XROM)     += amd76xrom.o
    2424obj-$(CONFIG_MTD_ICH2ROM)       += ich2rom.o
     25obj-$(CONFIG_MTD_TEKXP_OPTROM)  += tekxp_optrom.o
    2526obj-$(CONFIG_MTD_TSUNAMI)       += tsunami_flash.o
    2627obj-$(CONFIG_MTD_MBX860)        += mbx860.o
    2728obj-$(CONFIG_MTD_NORA)          += nora.o
  • drivers/mtd/maps/tekxp_optrom.c

    diff -Naur linux-2.4.26/drivers/mtd/maps/tekxp_optrom.c linux-2.4.26-m68k/drivers/mtd/maps/tekxp_optrom.c
    old new  
     1#include <linux/module.h>
     2#include <linux/types.h>
     3#include <linux/kernel.h>
     4#include <asm/io.h>
     5#include <linux/mtd/mtd.h>
     6#include <linux/mtd/map.h>
     7#include <linux/config.h>
     8
     9/*
     10 * Maximum number of ROMS supported by this drivers.
     11 *
     12 * There will be definitely be no more, since the address space for them
     13 * is restricted to what those 16 may span.
     14 */
     15#define MAX_NUM_OPTROM  16
     16
     17/*
     18 * Virtual address of the address space potentially used by the ROMs.
     19 */
     20static unsigned long possible_rom_memory;
     21
     22/*
     23 * Structure holding just the information needed for the MTD framework.
     24 * The driver itself needs no further information about a single ROM.
     25 */
     26typedef struct {
     27        struct map_info         map;
     28        struct mtd_info         *mtd;
     29} optrom_desc_t;
     30
     31static int num_optrom;
     32static optrom_desc_t optrom_desc[MAX_NUM_OPTROM];
     33
     34/*
     35 * Check if a ROM is present and determinate its size.
     36 */
     37static unsigned int __init detect_optrom_size(unsigned long start_address)
     38{
     39        unsigned long original = *(unsigned long *)start_address;
     40
     41        /*
     42         * We try to write into the ROM. It will not fault on us.
     43         */
     44        *(volatile unsigned long *)start_address = ~original;
     45
     46        /*
     47         * If the write did not change there is a ROM or nothing.
     48         */
     49        if ( *(volatile unsigned long *)start_address == original )
     50        {
     51                /*
     52                 * But the Nothing will fail to report a correct size.
     53                 *
     54                 * Yes, the size is stored at a given position within the
     55                 * ROM. So if someone did create ROMs on his own behalf
     56                 * not following the "specification" this driver will
     57                 * fail to detect them.
     58                 *
     59                 * Do NOT fix this! It is intended behaviour since the
     60                 * future goal of this driver is to present the filesystem
     61                 * stored in the original ROMs.
     62                 */
     63                unsigned short size = *(unsigned short *)(start_address + 6);
     64                if ( size == 0x80 || size == 0x100 || size == 0x200 || size == 0x400 )
     65                        return size * 1024;
     66        }
     67
     68        /*
     69         * If we hit something else try to restore the original content.
     70         */
     71        *(unsigned long *)start_address = original;
     72
     73        return 0;
     74}
     75
     76/*
     77 * Just the obvious way to copy memory around.
     78 */
     79static void optrom_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
     80{
     81        memcpy(to, (char *)map->map_priv_1 + from, len);
     82}
     83
     84/*
     85 * We can not write into the ROMs.
     86 */
     87static void optrom_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
     88{
     89}
     90
     91/*
     92 * Initialization
     93 */
     94static int __init init_optrom(void)
     95{
     96        int i;
     97
     98        /*
     99         * Get all memory mapped that may hold a ROM. This might have to
     100         * be switched to a less gready sheme if causing any problems.
     101         */
     102        possible_rom_memory = (unsigned long)ioremap_nocache(0x1000000, MAX_NUM_OPTROM * 0x100000);
     103        if ( !possible_rom_memory )
     104        {
     105                printk(KERN_WARNING "Could not map optroms into the virtual memory space\n");
     106                return -ENXIO;
     107        }
     108
     109        /*
     110         * Search through the complete address space for any ROM.
     111         * If any ROM is found register it with the MTD framework.
     112         */
     113        for ( i=0; i<MAX_NUM_OPTROM; i++ )
     114        {
     115                unsigned int size = detect_optrom_size(possible_rom_memory + i * 0x100000);
     116                if ( size > 0 )
     117                {
     118                        optrom_desc_t *desc = &optrom_desc[num_optrom];
     119
     120                        printk(KERN_INFO "Found optional ROM of size %u at %08x\n", size, 0x1000000 + i * 0x100000);
     121
     122                        desc->map.name = "TekXpress optional ROM";
     123                        desc->map.size = size;
     124                        desc->map.map_priv_1 = possible_rom_memory + i * 0x100000;
     125                        desc->map.copy_from = optrom_copy_from;
     126                        desc->map.copy_to = optrom_copy_to;
     127
     128                        desc->mtd = do_map_probe("map_rom", &desc->map);
     129                        if ( !desc->mtd )
     130                        {
     131                                printk(KERN_ERR "Could not allocate MTD structure\n");
     132                                continue;
     133                        }
     134
     135                        desc->mtd->module = THIS_MODULE;
     136                        add_mtd_device(desc->mtd);
     137
     138                        num_optrom++;
     139                }
     140
     141        }
     142
     143        if ( num_optrom <= 0 )
     144        {
     145                iounmap((void *)possible_rom_memory);
     146                printk(KERN_WARNING "No optional rom found\n");
     147                return -ENXIO;
     148        }
     149
     150        return 0;
     151}
     152
     153/*
     154 * Unregister all ROMs found from the MTD framework.
     155 */
     156void __exit cleanup_optrom(void)
     157{
     158        while ( num_optrom-- )
     159        {
     160                optrom_desc_t *desc = &optrom_desc[num_optrom];
     161
     162                del_mtd_device(desc->mtd);
     163                map_destroy(desc->mtd);
     164        }
     165
     166        iounmap((void*)possible_rom_memory);
     167}
     168
     169
     170
     171module_init(init_optrom);
     172module_exit(cleanup_optrom);
     173
     174MODULE_LICENSE("GPL");
     175MODULE_AUTHOR("Michael Mueller <malware@t-online.de>");
     176MODULE_DESCRIPTION("MTD map driver for optional ROM of the TekXpress XP2x X-Terminals");
     177
  • drivers/net/Makefile

    diff -Naur linux-2.4.26/drivers/net/Makefile linux-2.4.26-m68k/drivers/net/Makefile
    old new  
    9595obj-$(CONFIG_FEALNX) += fealnx.o mii.o
    9696obj-$(CONFIG_TC35815) += tc35815.o
    9797obj-$(CONFIG_TIGON3) += tg3.o
     98obj-$(CONFIG_TEKSONIC) += teksonic.o
    9899
    99100ifeq ($(CONFIG_E100),y)
    100101  obj-y += e100/e100.o
  • drivers/net/Space.c

    diff -Naur linux-2.4.26/drivers/net/Space.c linux-2.4.26-m68k/drivers/net/Space.c
    old new  
    101101extern int mac8390_probe(struct net_device *dev);
    102102extern int mac89x0_probe(struct net_device *dev);
    103103extern int mc32_probe(struct net_device *dev);
     104extern int teksonic_probe(struct net_device *dev);
    104105 
    105106/* Detachable devices ("pocket adaptors") */
    106107extern int de600_probe(struct net_device *);
     
    326327};
    327328
    328329static struct devprobe m68k_probes[] __initdata = {
     330#ifdef CONFIG_TEKSONIC
     331        {teksonic_probe, 0},
     332#endif
    329333#ifdef CONFIG_ATARILANCE        /* Lance-based Atari ethernet boards */
    330334        {atarilance_probe, 0},
    331335#endif
  • drivers/net/a2065.c

    diff -Naur linux-2.4.26/drivers/net/a2065.c linux-2.4.26-m68k/drivers/net/a2065.c
    old new  
    284284        struct sk_buff *skb = 0;        /* XXX shut up gcc warnings */
    285285
    286286#ifdef TEST_HITS
     287        int i;
    287288        printk ("[");
    288289        for (i = 0; i < RX_RING_SIZE; i++) {
    289290                if (i == lp->rx_new)
  • drivers/net/macsonic.c

    diff -Naur linux-2.4.26/drivers/net/macsonic.c linux-2.4.26-m68k/drivers/net/macsonic.c
    old new  
    199199        if ((lp->rba = (char *)
    200200             kmalloc(SONIC_NUM_RRS * SONIC_RBSIZE, GFP_KERNEL | GFP_DMA)) == NULL) {
    201201                printk(KERN_ERR "%s: couldn't allocate receive buffers\n", dev->name);
     202                kfree(lp);
    202203                return -ENOMEM;
    203204        }
    204205
     
    635636}
    636637
    637638#ifdef MODULE
    638 static char namespace[16] = "";
    639639static struct net_device dev_macsonic;
    640640
    641641MODULE_PARM(sonic_debug, "i");
    642642MODULE_PARM_DESC(sonic_debug, "macsonic debug level (1-4)");
    643 MODULE_LICENSE("GPL");
    644 
    645 EXPORT_NO_SYMBOLS;
    646643
    647644int
    648645init_module(void)
    649646{
    650         dev_macsonic.name = namespace;
    651647        dev_macsonic.init = macsonic_probe;
    652648
    653649        if (register_netdev(&dev_macsonic) != 0) {
  • drivers/net/teksonic.c

    diff -Naur linux-2.4.26/drivers/net/teksonic.c linux-2.4.26-m68k/drivers/net/teksonic.c
    old new  
     1/*
     2 *  linux/drivers/net/teksonic.c
     3 *
     4 * (C) 2003 Michael Mueller <malware@t-online.de>
     5 *
     6 * based on the macsonic driver:
     7 *
     8 * (C) 1998 Alan Cox
     9 *
     10 * Debugging Andreas Ehliar, Michael Schmitz
     11 *
     12 * Based on code
     13 * (C) 1996 by Thomas Bogendoerfer (tsbogend@bigbug.franken.de)
     14 *
     15 * This driver is based on work from Andreas Busse, but most of
     16 * the code is rewritten.
     17 *
     18 * (C) 1995 by Andreas Busse (andy@waldorf-gmbh.de)
     19 *
     20 */
     21
     22#include <linux/kernel.h>
     23#include <linux/sched.h>
     24#include <linux/types.h>
     25#include <linux/ctype.h>
     26#include <linux/fcntl.h>
     27#include <linux/interrupt.h>
     28#include <linux/ptrace.h>
     29#include <linux/ioport.h>
     30#include <linux/in.h>
     31#include <linux/slab.h>
     32#include <linux/string.h>
     33#include <linux/delay.h>
     34#include <asm/system.h>
     35#include <asm/bitops.h>
     36#include <asm/pgtable.h>
     37#include <asm/segment.h>
     38#include <asm/io.h>
     39#include <asm/irq.h>
     40#include <asm/dma.h>
     41
     42#include <linux/errno.h>
     43
     44#include <linux/netdevice.h>
     45#include <linux/etherdevice.h>
     46#include <linux/skbuff.h>
     47#include <linux/module.h>
     48#include <asm/teknvram.h>
     49
     50/*
     51 * All registers are located at addresses dividable by 4.
     52 */
     53
     54#define SREGS_PAD(n)    u16 n;
     55
     56/*
     57 * This is a hack to get the endianness stuff done correctly.
     58 */
     59
     60#define CONFIG_MACSONIC
     61
     62/*
     63 * Generic Sonic definitions
     64 */
     65#include "sonic.h"
     66
     67#ifdef DEBUG
     68
     69#define SONIC_READ(reg) _SONIC_READ(base_addr, reg)
     70#define SONIC_WRITE(reg,val) do { _SONIC_WRITE(base_addr, reg, val); } while(0)
     71
     72static inline unsigned short _SONIC_READ(unsigned long base_addr, int reg)
     73{
     74        unsigned short val = *((volatile unsigned long*)(base_addr + 4*(reg))) & 0xffff;
     75        printk("sonic_read(%08x) = %02x\n", base_addr + 4*(reg), val);
     76        return val;
     77}
     78
     79static inline void _SONIC_WRITE(unsigned long base_addr, int reg, unsigned short val)
     80{
     81        printk("sonic_write(%08x,%04x)\n", base_addr + 4*(reg), val);
     82        *((volatile unsigned long*)(base_addr + 4*(reg))) = (val) & 0xffff;
     83}
     84
     85static inline unsigned short sonic_read(struct net_device *dev, int reg)
     86{
     87        unsigned short val = *((volatile unsigned long*)(dev->base_addr + 4*(reg))) & 0xffff;
     88        printk("sonic_read(%08x) = %02x\n", dev->base_addr + 4*(reg), val);
     89        return val;
     90}
     91
     92static inline void sonic_write(struct net_device *dev, int reg, unsigned short val)
     93{
     94        printk("sonic_write(%08x,%04x)\n", dev->base_addr + 4*(reg), val);
     95        *((volatile unsigned long*)(dev->base_addr + 4*(reg))) = (val) & 0xffff;
     96}
     97
     98#else
     99
     100#define SONIC_READ(reg) ((unsigned short)(*(volatile unsigned long *)((base_addr) + 4*(reg))) & 0xffff)
     101
     102#define SONIC_WRITE(reg, val) do { *(volatile unsigned long*)((base_addr) + 4*(reg)) = (val)& 0xffff; } while (0)
     103
     104#define sonic_read(dev,reg) ((unsigned short)(*(volatile unsigned long *)((dev)->base_addr + 4*(reg))) & 0xffff)
     105
     106#define sonic_write(dev, reg, val) do { *(volatile unsigned long*)((dev)->base_addr + 4*(reg)) = (val)& 0xffff; } while (0)
     107
     108#endif
     109
     110static int sonic_debug = 0;
     111static int sonic_version_printed;
     112
     113static int reg_offset;
     114
     115int teksonic_init(struct net_device* dev)
     116{
     117        int i,j;
     118        struct sonic_local* lp_alloc[20];
     119        struct sonic_local* lp;
     120
     121        /* Allocate the entire chunk of memory for the descriptors.
     122           Note that this cannot cross a 64K boundary. */
     123        for (i = 0; i < 20; i++) {
     124                unsigned long desc_base, desc_top, desc_top2;
     125                if((lp_alloc[i] = kmalloc(sizeof(struct sonic_local), GFP_KERNEL)) == NULL) {
     126                        printk(KERN_ERR "%s: couldn't allocate descriptor buffers\n", dev->name);
     127                        return -ENOMEM;
     128                }
     129                desc_base = (unsigned long)virt_to_phys(lp_alloc[i]);
     130                desc_top = desc_base + sizeof(struct sonic_local);
     131                desc_top2 = (unsigned long)virt_to_phys(lp_alloc[i] + 1);
     132
     133                if ( (desc_top == desc_top2) && (desc_top & 0xffff) >= (desc_base & 0xffff))
     134                        break;
     135
     136                /* Hmm. try again (FIXME: does this actually work?) */
     137                /* Note: It did not work when freeing the memory allocated
     138                         previously since it got the same memory again. */
     139/*              kfree(lp);      */
     140                printk(KERN_DEBUG
     141                       "%s: didn't get continguous chunk [%08lx - %08lx], trying again\n",
     142                       dev->name, desc_base, desc_top);
     143
     144        }
     145
     146        /* Deallocate what was allocated just to get the alignment done. */
     147        for ( j = i-1; j >= 0; j-- )
     148                kfree(lp_alloc[j]);
     149
     150        if (i==20) {
     151                /* Note: Do not free dev->priv, it is deallocated later! */
     152                printk(KERN_ERR "%s: tried 20 times to allocate descriptor buffers, giving up.\n",
     153                       dev->name);
     154                return -ENOMEM;
     155        }
     156
     157        dev->priv = lp = lp_alloc[i];
     158
     159        memset(lp, 0, sizeof(struct sonic_local));
     160
     161        lp->cda_laddr = virt_to_phys(&(lp->cda));
     162        lp->tda_laddr = virt_to_phys(lp->tda);
     163        lp->rra_laddr = virt_to_phys(lp->rra);
     164        lp->rda_laddr = virt_to_phys(lp->rda);
     165
     166        /* FIXME, maybe we should use skbs */
     167        if ((lp->rba = (char *)kmalloc(SONIC_NUM_RRS * SONIC_RBSIZE, GFP_KERNEL)) == NULL) {
     168                printk(KERN_ERR "%s: couldn't allocate receive buffers\n", dev->name);
     169                return -ENOMEM;
     170        }
     171        lp->rba_laddr = virt_to_phys(lp->rba);
     172
     173#if 0
     174        {
     175                int rs, ds;
     176
     177                /* almost always 12*4096, but let's not take chances */
     178                rs = ((SONIC_NUM_RRS * SONIC_RBSIZE + 4095) / 4096) * 4096;
     179                /* almost always under a page, but let's not take chances */
     180                ds = ((sizeof(struct sonic_local) + 4095) / 4096) * 4096;
     181                kernel_set_cachemode(lp->rba, rs, IOMAP_NOCACHE_SER);
     182                kernel_set_cachemode(lp, ds, IOMAP_NOCACHE_SER);
     183        }
     184#endif
     185
     186
     187#if 0
     188        flush_cache_all();
     189#endif
     190
     191        dev->open = sonic_open;
     192        dev->stop = sonic_close;
     193        dev->hard_start_xmit = sonic_send_packet;
     194        dev->get_stats = sonic_get_stats;
     195        dev->set_multicast_list = &sonic_multicast_list;
     196
     197        /*
     198         * clear tally counter
     199         */
     200        sonic_write(dev, SONIC_CRCT, 0xffff);
     201        sonic_write(dev, SONIC_FAET, 0xffff);
     202        sonic_write(dev, SONIC_MPT, 0xffff);
     203
     204        /* Fill in the fields of the device structure with ethernet values. */
     205        ether_setup(dev);
     206        return 0;
     207}
     208
     209int teksonic_ethernet_addr(struct net_device* dev)
     210{
     211        int i;
     212
     213        /* On NuBus boards we can sometimes look in the ROM resources.
     214           No such luck for comm-slot/onboard. */
     215        for(i = 0; i < 6; i++)
     216                dev->dev_addr[i] = nvram_readb(NVRAM_SONIC_MAC+i);
     217
     218        return 0;
     219}
     220
     221int teksonic_probe(struct net_device* dev)
     222{
     223        /* Bwahahaha */
     224        static int once_is_more_than_enough;
     225        int i;
     226        int dma_bitmode;
     227
     228        if (once_is_more_than_enough)
     229                return -ENODEV;
     230        once_is_more_than_enough = 1;
     231
     232        if (dev) {
     233                dev = init_etherdev(dev, sizeof(struct sonic_local));
     234                if (!dev)
     235                        return -ENOMEM;
     236        } else {
     237                dev = init_etherdev(NULL, sizeof(struct sonic_local));
     238        }
     239        if (dev->priv != NULL) {
     240                kfree(dev->priv);
     241                dev->priv = NULL;
     242        }
     243
     244        if (dev == NULL)
     245                return -ENOMEM;
     246
     247        /* Danger!  My arms are flailing wildly!  You *must* set this
     248           before using sonic_read() */
     249
     250        dev->base_addr = 0xFFC00000;    // FIXME: This does rely on transparent translation
     251        dev->irq = IRQ6;
     252
     253        if (!sonic_version_printed) {
     254                printk(KERN_INFO "%s", version);
     255                sonic_version_printed = 1;
     256        }
     257        printk(KERN_INFO "%s: SONIC at 0x%08lx\n",
     258               dev->name, dev->base_addr);
     259
     260        reg_offset = 0;
     261        dma_bitmode = 1;
     262
     263        /* Software reset, then initialize control registers. */
     264        sonic_write(dev, SONIC_CMD, SONIC_CR_RST);
     265
     266        sonic_write(dev, SONIC_DCR, SONIC_DCR_BMS |
     267                    SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | SONIC_DCR_EXBUS |
     268                    (dma_bitmode ? SONIC_DCR_DW : 0));
     269#if 0
     270        sonic_write(dev, SONIC_DCR, 0x3F);
     271#endif
     272
     273        /* This *must* be written back to in order to restore the
     274           extended programmable output bits */
     275        sonic_write(dev, SONIC_DCR2, 0);
     276
     277        sonic_write(dev, SONIC_CMD, 0);
     278
     279        /* Clear *and* disable interrupts to be on the safe side */
     280        sonic_write(dev, SONIC_ISR,0x7fff);
     281        sonic_write(dev, SONIC_IMR,0);
     282
     283        /* Now look for the MAC address. */
     284        if (teksonic_ethernet_addr(dev) != 0)
     285                return -ENODEV;
     286
     287        printk(KERN_INFO "MAC ");
     288        for (i = 0; i < 6; i++) {
     289                printk("%2.2x", dev->dev_addr[i]);
     290                if (i < 5)
     291                        printk(":");
     292        }
     293
     294        printk(" IRQ %d\n", dev->irq);
     295
     296        /* Shared init code */
     297        return teksonic_init(dev);
     298}
     299
     300
     301#define vdma_alloc(foo, bar) ((u32)(foo))
     302#define vdma_free(baz)
     303#define sonic_chiptomem(bat) (phys_to_virt(bat))
     304#define PHYSADDR(quux) (virt_to_phys((void*)(quux)))
     305
     306#define sonic_request_irq       request_irq
     307#define sonic_free_irq          free_irq
     308
     309#include "sonic.c"
     310
  • drivers/sbus/char/sunkbd.c

    diff -Naur linux-2.4.26/drivers/sbus/char/sunkbd.c linux-2.4.26-m68k/drivers/sbus/char/sunkbd.c
    old new  
    761761
    762762static void boot_it(void)
    763763{
     764#if !defined(CONFIG_SUN3) && !defined(CONFIG_SUN3X)
    764765        extern int obp_system_intr(void);
    765766
    766767        if (!obp_system_intr())
     
    768769        /* sigh.. attempt to prevent multiple entry */
    769770        last_keycode=1;
    770771        rep = 0;
     772#endif
    771773}
    772774
    773775static void compose(void)
     
    12321234
    12331235int __init sun_kbd_init(void)
    12341236{
    1235         int i, opt_node;
     1237        int i;
    12361238        struct kbd_struct kbd0;
    12371239        extern struct tty_driver console_driver;
    12381240
     
    12501252
    12511253        kd_mksound = sunkbd_kd_mksound;
    12521254
     1255#ifndef CONFIG_SUN3X_ZS
    12531256        /* XXX Check keyboard-click? property in 'options' PROM node XXX */
    12541257        if(sparc_cpu_model != sun4) {
    1255                 opt_node = prom_getchild(prom_root_node);
     1258                int opt_node = prom_getchild(prom_root_node);
    12561259                opt_node = prom_searchsiblings(opt_node, "options");
    12571260                i = prom_getintdefault(opt_node, "keyboard-click?", -1);
    12581261                if(i != -1)
    12591262                        sunkbd_clickp = 1;
    12601263                else
    12611264                        sunkbd_clickp = 0;
    1262         } else {
     1265        } else
     1266#else
     1267        {
    12631268                sunkbd_clickp = 0;
    12641269        }
     1270#endif
    12651271
    12661272        keyboard_tasklet.func = sun_kbd_bh;
    12671273
  • drivers/sbus/char/sunserial.c

    diff -Naur linux-2.4.26/drivers/sbus/char/sunserial.c linux-2.4.26-m68k/drivers/sbus/char/sunserial.c
    old new  
    1010#include <linux/module.h>
    1111#include <linux/errno.h>
    1212#include <linux/tty.h>
     13
     14#ifdef CONFIG_SUN3
     15#include <linux/sched.h>
     16#include <asm/ptrace.h>
     17#include <linux/interrupt.h>
     18#endif
     19
    1320#include <linux/serial.h>
    1421#include <linux/serialP.h>
    1522#include <linux/string.h>
     
    228235void
    229236sunserial_console_termios(struct console *con)
    230237{
     238#ifndef CONFIG_SUN3X_ZS
    231239        char mode[16], buf[16], *s;
    232240        char *mode_prop = "ttyX-mode";
    233241        char *cd_prop = "ttyX-ignore-cd";
     
    331339        }
    332340
    333341        con->cflag = cflag;
     342#else /* CONFIG_SUN3 */
     343        con->cflag = CREAD | HUPCL | CLOCAL | B9600 | CS8;
     344#endif /* CONFIG_SUN3 */
    334345}
    335346
    336347void
     
    452463        }
    453464#endif
    454465
     466#ifndef CONFIG_SUN3X_ZS
    455467        prom_printf("No serial devices found, bailing out.\n");
    456468        prom_halt();
     469#endif
     470       
    457471}
  • drivers/sbus/char/zs.c

    diff -Naur linux-2.4.26/drivers/sbus/char/zs.c linux-2.4.26-m68k/drivers/sbus/char/zs.c
    old new  
    1111 * /proc/tty/driver/serial now exists and is readable.
    1212 *   Alex Buell <alex.buell@tahallah.demon.co.uk>, 2001-12-23
    1313 *
     14 * Tweaks for sun3x by Oliver Jowett <oliver@jowett.manawatu.gen.nz>
     15 *
    1416 */
    1517
    1618#include <linux/errno.h>
     
    3941#include <asm/system.h>
    4042#include <asm/uaccess.h>
    4143#include <asm/bitops.h>
     44
     45#include <asm/sbus.h>
     46#ifndef CONFIG_SUN3X_ZS
    4247#include <asm/kdebug.h>
    4348#include <asm/page.h>
    4449#include <asm/pgtable.h>
    4550
    46 #include <asm/sbus.h>
    4751#ifdef __sparc_v9__
    4852#include <asm/fhc.h>
    4953#endif
    5054#ifdef CONFIG_PCI
    5155#include <linux/pci.h>
    5256#endif
     57#else /* CONFIG_SUN3X_ZS */
     58#include <linux/ioport.h>
     59#ifndef CONFIG_SUN3X
     60#include <asm/sun3mmu.h>
     61#else
     62#include <asm/sun3xprom.h>
     63#endif
     64#endif /* CONFIG_SUN3X_ZS */
    5365
    5466#include "sunserial.h"
    5567#include "zs.h"
    5668#include "sunkbd.h"
    5769#include "sunmouse.h"
    5870
     71/* some sun3 boxen always use vectors */
     72#ifdef CONFIG_SUN3
     73#undef NV
     74#define NV 0
     75#endif
     76
    5977static int num_serial = 2; /* sun4/sun4c/sun4m - Two chips on board. */
    6078#define NUM_SERIAL num_serial
    6179#define NUM_CHANNELS (NUM_SERIAL * 2)
     
    425443 */
    426444void batten_down_hatches(void)
    427445{
     446#ifndef CONFIG_SUN3X_ZS
    428447        if (!stop_a_enabled)
    429448                return;
    430449        /* If we are doing kadb, we call the debugger
     
    448467         */
    449468
    450469        return;
     470#else /* CONFIG_SUN3X_ZS */
     471#ifndef CONFIG_SUN3X
     472        prom_reboot("");
     473#else
     474        sun3x_reboot();
     475#endif
     476#endif /* CONFIG_SUN3X_ZS */
    451477}
    452478
    453479
     
    550576                 * arch/sparc/kernel/sparc-stub.c to see how all this works.
    551577                 */
    552578                if (info->kgdb_channel && (ch =='\003')) {
     579#ifndef CONFIG_SUN3X_ZS
    553580                        breakpoint();
     581#endif
    554582                        return;
    555583                }
    556584#endif
     
    683711        for (i = 0; i < NUM_SERIAL; i++) {
    684712                unsigned char r3 = read_zsreg(info->zs_channel, 3);
    685713
     714                /* some sun3's need the pending flags cleared */
     715#ifdef CONFIG_SUN3
     716                unsigned char r2 = read_zsreg(info->zs_next->zs_channel, 2);
     717                r2 &= STATUS_MASK;
     718                if(r2 & 0x8) {
     719                        sbus_writeb(RES_H_IUS, &info->zs_channel->control);
     720                        ZSDELAY();
     721                        ZS_WSYNC(info->zs_channel);
     722                        ZSLOG(REGCTRL, RES_H_IUS, 1);
     723                } else {
     724                        sbus_writeb(RES_H_IUS, &info->zs_next->zs_channel->control);
     725                        ZSDELAY();
     726                        ZS_WSYNC(info->zs_next->zs_channel);
     727                        ZSLOG(REGCTRL, RES_H_IUS, 1);
     728                }
     729#endif
     730
    686731                /* Channel A -- /dev/ttya or /dev/kbd, could be the console */
    687732                if (r3 & (CHAEXT | CHATxIP | CHARxIP)) {
    688733                        sbus_writeb(RES_H_IUS, &info->zs_channel->control);
     
    19642009
    19652010/* Finally, routines used to initialize the serial driver. */
    19662011
     2012
     2013#ifdef CONFIG_SUN3X_ZS
     2014
     2015static void show_serial_version(void)
     2016{
     2017        char *revision = "$Revision: 1.5 $";
     2018        char *version, *p;
     2019
     2020        version = strchr(revision, ' ');
     2021        p = strchr(++version, ' ');
     2022        *p = '\0';
     2023        printk("sun3/3x Zilog8530 serial driver version %s\n", version);
     2024        *p = ' ';
     2025}
     2026
     2027static struct sun_zslayout * __init 
     2028           get_zs(int chip)
     2029{
     2030        unsigned int vaddr = 0;
     2031        unsigned long iopte;
     2032        static int irq = 0;
     2033
     2034        if(chip < 0 || chip >= NUM_SERIAL)
     2035                panic("get_zs bogon zs chip number");
     2036
     2037#ifndef CONFIG_SUN3X
     2038        /* sun3 OBIO version */
     2039        /* Grrr, these have to be hardcoded aieee */
     2040        switch(chip) {
     2041        case 0:
     2042                for(vaddr = 0xfe00000; vaddr < (0xfe00000 +
     2043                                                SUN3_PMEG_SIZE); vaddr += SUN3_PTE_SIZE) {
     2044                       
     2045                        iopte = sun3_get_pte(vaddr);
     2046                        if(!(iopte & SUN3_PAGE_TYPE_IO)) /* this an io page? */
     2047                                continue;
     2048                       
     2049                        if(((iopte & SUN3_PAGE_PGNUM_MASK) << PAGE_SHIFT) ==
     2050                           0x20000) {
     2051                                break;
     2052                        }
     2053                }
     2054                break;
     2055        case 1:
     2056                for(vaddr = 0xfe00000; vaddr < (0xfe00000 +
     2057                                                SUN3_PMEG_SIZE); vaddr += SUN3_PTE_SIZE) {
     2058                 
     2059                        iopte = sun3_get_pte(vaddr);
     2060                        if(!(iopte & SUN3_PAGE_TYPE_IO)) /* this an io page? */
     2061                                continue;
     2062                 
     2063                        if(((iopte & SUN3_PAGE_PGNUM_MASK) << PAGE_SHIFT) ==
     2064                           0) {
     2065                                break;
     2066                        }
     2067                }
     2068                break;
     2069        };
     2070#else
     2071        /* sun3x is a wee bit cleaner. :) */
     2072        switch(chip) {
     2073        case 0:
     2074                vaddr = SUN3X_ZS2;
     2075                break;
     2076
     2077        case 1:
     2078                vaddr = SUN3X_ZS1;
     2079                break;
     2080        }
     2081#endif 
     2082       
     2083        zs_nodes[chip] = 0;
     2084        zilog_irq = irq = 6;
     2085       
     2086        if(!vaddr)
     2087                panic("get_zs whee no serial chip mappable");
     2088       
     2089        return (struct sun_zslayout *)(unsigned long) vaddr;
     2090}
     2091 
     2092#else /* !CONFIG_SUN3X_ZS */
     2093
    19672094static void show_serial_version(void)
    19682095{
    19692096        char *revision = "$Revision: 1.68.2.2 $";
     
    22242351        return (struct sun_zslayout *)(unsigned long) vaddr[0];
    22252352}
    22262353#endif
     2354
     2355#endif /* !CONFIG_SUN3X_ZS */
     2356       
    22272357/* This is for the auto baud rate detection in the mouse driver. */
    22282358void zs_change_mouse_baud(int newbaud)
    22292359{
     
    22922422
    22932423int __init zs_probe(void)
    22942424{
     2425#ifndef CONFIG_SUN3X_ZS
     2426
    22952427        int node;
    22962428
    22972429        if(sparc_cpu_model == sun4)
     
    23442476        NUM_SERIAL = 2;
    23452477
    23462478no_probe:
     2479#endif /* !CONFIG_SUN3X_ZS */
     2480
    23472481        zs_alloc_tables();
    23482482
    23492483        /* Fill in rs_ops struct... */
     
    25012635        /* Initialize Softinfo */
    25022636        zs_prepare();
    25032637
     2638#ifndef CONFIG_SUN3X_ZS
    25042639        /* Grab IRQ line before poking the chips so we do
    25052640         * not lose any interrupts.
    25062641         */
     
    25092644                prom_printf("Unable to attach zs intr\n");
    25102645                prom_halt();
    25112646        }
     2647#endif /* !CONFIG_SUN3X_ZS */
    25122648
    25132649        /* Initialize Hardware */
    25142650        for(channel = 0; channel < NUM_CHANNELS; channel++) {
     
    25172653                        write_zsreg(zs_soft[channel].zs_channel, R9, FHWRES);
    25182654                        ZSDELAY_LONG();
    25192655                        dummy = read_zsreg(zs_soft[channel].zs_channel, R0);
     2656#ifdef CONFIG_SUN3
     2657                        /* program the int vector */
     2658                        write_zsreg(zs_soft[channel].zs_channel, R2, 0x18+zilog_irq);
     2659#endif
    25202660                }
    25212661
    25222662                if(channel == KEYBOARD_LINE) {
     
    26762816                info->normal_termios = serial_driver.init_termios;
    26772817                init_waitqueue_head(&info->open_wait);
    26782818                init_waitqueue_head(&info->close_wait);
     2819#ifdef CONFIG_SUN3X_ZS
     2820                printk("tty%02d at 0x%04x (irq = %d)", info->line,
     2821                       info->port, info->irq);
     2822#else /* !CONFIG_SUN3X_ZS */
    26792823                printk("tty%02d at 0x%04x (irq = %s)", info->line,
    26802824                       info->port, __irq_itoa(info->irq));
     2825#endif /* !CONFIG_SUN3X_ZS */
    26812826                printk(" is a Zilog8530\n");
    26822827        }
    26832828
     2829#ifdef CONFIG_SUN3X_ZS
     2830        if (request_irq(zilog_irq, zs_interrupt,
     2831                        (SA_INTERRUPT),
     2832                        "Zilog8530", zs_chain))
     2833                panic("Unable to attach zs intr\n");
     2834#endif /* CONFIG_SUN3X_ZS */
     2835
    26842836        restore_flags(flags);
    26852837
    26862838        keyboard_zsinit(kbd_put_char);
     
    28813033{
    28823034        extern int con_is_present(void);
    28833035
     3036#ifndef CONFIG_SUN3X_ZS
    28843037        if (con_is_present())
    28853038                return 0;
    28863039
    28873040        zs_console.index = serial_console - 1;
     3041#else /* CONFIG_SUN3X_ZS */
     3042        zs_console.index = 0;
     3043#endif /* CONFIG_SUN3X_ZS */
     3044
    28883045        register_console(&zs_console);
    28893046        return 0;
    28903047}
  • drivers/scsi/NCR53C9x.c

    diff -Naur linux-2.4.26/drivers/scsi/NCR53C9x.c linux-2.4.26-m68k/drivers/scsi/NCR53C9x.c
    old new  
    917917                if (esp->dma_mmu_get_scsi_one)
    918918                        esp->dma_mmu_get_scsi_one(esp, sp);
    919919                else
    920                         sp->SCp.have_data_in = (int) sp->SCp.ptr =
     920                        sp->SCp.ptr =
    921921                                (char *) virt_to_phys(sp->request_buffer);
    922922        } else {
    923923                sp->SCp.buffer = (struct scatterlist *) sp->buffer;
  • drivers/scsi/oktagon_esp.c

    diff -Naur linux-2.4.26/drivers/scsi/oktagon_esp.c linux-2.4.26-m68k/drivers/scsi/oktagon_esp.c
    old new  
    548548
    549549void dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd *sp)
    550550{
    551         sp->SCp.have_data_in = (int) sp->SCp.ptr =
     551        sp->SCp.ptr =
    552552                sp->request_buffer;
    553553}
    554554
  • drivers/video/Config.in

    diff -Naur linux-2.4.26/drivers/video/Config.in linux-2.4.26-m68k/drivers/video/Config.in
    old new  
    4343   if [ "$CONFIG_Q40" = "y" ]; then
    4444      define_bool CONFIG_FB_Q40 y
    4545   fi
     46   if [ "$CONFIG_TEKXP" = "y" ]; then
     47      define_bool CONFIG_FB_TEKXP y
     48   fi
    4649   if [ "$CONFIG_AMIGA" = "y" ]; then
    4750      tristate '  Amiga native chipset support' CONFIG_FB_AMIGA
    4851      if [ "$CONFIG_FB_AMIGA" != "n" ]; then
     
    107110      bool '  Sun3 framebuffer support' CONFIG_FB_SUN3
    108111      if [ "$CONFIG_FB_SUN3" != "n" ]; then
    109112         bool '    BWtwo support' CONFIG_FB_BWTWO
     113         bool '    CGthree support' CONFIG_FB_CGTHREE
    110114         bool '    CGsix (GX,TurboGX) support' CONFIG_FB_CGSIX
    111115      fi
    112116   fi
     
    265269           "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_RETINAZ3" = "y" -o \
    266270           "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
    267271           "$CONFIG_FB_BWTWO" = "y" -o "$CONFIG_FB_CLGEN" = "y"  -o \
    268            "$CONFIG_FB_TX3912" = "y" ]; then
     272           "$CONFIG_FB_TX3912" = "y" -o "$CONFIG_FB_TEKXP" = "y" ]; then
    269273         define_tristate CONFIG_FBCON_MFB y
    270274      else
    271275         if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_AMIGA" = "m" -o \
     
    281285           "$CONFIG_FB_SA1100" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
    282286           "$CONFIG_FB_TX3912" = "y" ]; then
    283287         define_tristate CONFIG_FBCON_CFB2 y
    284          define_tristate CONFIG_FBCON_CFB4 y
    285288      else
    286          if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_MAC" = "m" -o \
     289         if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_MAC" = "m" -o \
    287290              "$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
    288291              "$CONFIG_FB_TX3912" = "m" ]; then
    289292            define_tristate CONFIG_FBCON_CFB2 m
     293         fi
     294      fi
     295      if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
     296           "$CONFIG_FB_SA1100" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
     297           "$CONFIG_FB_TX3912" = "y" -o "$CONFIG_FB_TEKXP" = "y" ]; then
     298         define_tristate CONFIG_FBCON_CFB4 y
     299      else
     300         if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_MAC" = "m" -o \
     301              "$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
     302              "$CONFIG_FB_TX3912" = "m" ]; then
    290303            define_tristate CONFIG_FBCON_CFB4 m
    291304         fi
    292305      fi
     
    312325           "$CONFIG_FB_TX3912" = "y" -o \
    313326           "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_NEOMAGIC" = "y" -o \
    314327           "$CONFIG_FB_STI" = "y" -o "$CONFIG_FB_HP300" = "y" -o \
    315            "$CONFIG_FB_INTEL" = "y" ]; then
     328           "$CONFIG_FB_INTEL" = "y" -o "$CONFIG_FB_TEKXP" = "y" ]; then
    316329         define_tristate CONFIG_FBCON_CFB8 y
    317330      else
    318331         if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \
  • drivers/video/Makefile

    diff -Naur linux-2.4.26/drivers/video/Makefile linux-2.4.26-m68k/drivers/video/Makefile
    old new  
    7373obj-$(CONFIG_FB_VIRGE)            += virgefb.o
    7474obj-$(CONFIG_FB_G364)             += g364fb.o
    7575obj-$(CONFIG_FB_FM2)              += fm2fb.o
    76 obj-$(CONFIG_FB_CREATOR)          += creatorfb.o sbusfb.o
    77 obj-$(CONFIG_FB_CGSIX)            += cgsixfb.o sbusfb.o
    78 obj-$(CONFIG_FB_BWTWO)            += bwtwofb.o sbusfb.o
    79 obj-$(CONFIG_FB_CGTHREE)          += cgthreefb.o sbusfb.o
    80 obj-$(CONFIG_FB_TCX)              += tcxfb.o sbusfb.o
    81 obj-$(CONFIG_FB_CGFOURTEEN)       += cgfourteenfb.o sbusfb.o
    82 obj-$(CONFIG_FB_P9100)            += p9100fb.o sbusfb.o
    83 obj-$(CONFIG_FB_LEO)              += leofb.o sbusfb.o
     76
     77SBUSFB  =
     78ifneq ($(CONFIG_SUN3),y)
     79ifneq ($(CONFIG_SUN3X),y)
     80    SBUSFB      = sbusfb.o
     81endif
     82endif
     83
     84obj-$(CONFIG_FB_CREATOR)          += creatorfb.o $(SBUSFB)
     85obj-$(CONFIG_FB_CGSIX)            += cgsixfb.o $(SBUSFB)
     86obj-$(CONFIG_FB_BWTWO)            += bwtwofb.o $(SBUSFB)
     87obj-$(CONFIG_FB_CGTHREE)          += cgthreefb.o $(SBUSFB)
     88obj-$(CONFIG_FB_TCX)              += tcxfb.o $(SBUSFB)
     89obj-$(CONFIG_FB_CGFOURTEEN)       += cgfourteenfb.o $(SBUSFB)
     90obj-$(CONFIG_FB_P9100)            += p9100fb.o $(SBUSFB)
     91obj-$(CONFIG_FB_LEO)              += leofb.o $(SBUSFB)
    8492obj-$(CONFIG_FB_PMAG_AA)          += pmag-aa-fb.o
    8593obj-$(CONFIG_FB_PMAG_BA)          += pmag-ba-fb.o
    8694obj-$(CONFIG_FB_PMAGB_B)          += pmagb-b-fb.o
     
    125133endif
    126134
    127135obj-$(CONFIG_FB_SUN3)             += sun3fb.o
    128 obj-$(CONFIG_FB_BWTWO)            += bwtwofb.o
    129136obj-$(CONFIG_FB_HGA)              += hgafb.o 
    130137obj-$(CONFIG_FB_SA1100)           += sa1100fb.o
    131138obj-$(CONFIG_FB_VIRTUAL)          += vfb.o 
     
    134141obj-$(CONFIG_FB_E1356)            += epson1356fb.o
    135142obj-$(CONFIG_FB_PVR2)             += pvr2fb.o
    136143obj-$(CONFIG_FB_VOODOO1)          += sstfb.o
     144obj-$(CONFIG_FB_TEKXP)            += tek_fb.o
    137145
    138146# Generic Low Level Drivers
    139147
  • drivers/video/cgthreefb.c

    diff -Naur linux-2.4.26/drivers/video/cgthreefb.c linux-2.4.26-m68k/drivers/video/cgthreefb.c
    old new  
    178178        struct display *disp = &fb->disp;
    179179        struct fbtype *type = &fb->type;
    180180        struct sbus_dev *sdev = fb->sbdp;
     181#ifndef CONFIG_SUN3
    181182        unsigned long phys = sdev->reg_addrs[0].phys_addr;
    182183        int cgRDI = strstr(fb->sbdp->prom_name, "cgRDI") != NULL;
     184#endif
    183185
    184186#ifndef FBCON_HAS_CFB8
    185187        return NULL;
    186188#endif
    187189
     190#ifndef CONFIG_SUN3
    188191        if (!fb->s.cg3.regs) {
    189192                fb->s.cg3.regs = (struct cg3_regs *)
    190193                        sbus_ioremap(&sdev->resource[0], CG3_REGS_OFFSET,
     
    211214                        }
    212215                }
    213216        }
     217#else
     218        fb->s.cg3.regs = (struct cg3_regs *)0x0fe0e000;
     219#endif
    214220
    215221        strcpy(fb->info.modename, "CGthree");
    216222        strcpy(fix->id, "CGthree");
     
    218224        fix->accel = FB_ACCEL_SUN_CGTHREE;
    219225       
    220226        disp->scrollmode = SCROLL_YREDRAW;
     227#ifndef CONFIG_SUN3
    221228        if (!disp->screen_base) {
    222229                disp->screen_base = (char *)
    223230                        sbus_ioremap(&sdev->resource[0], CG3_RAM_OFFSET,
    224231                                     type->fb_size, "cg3 ram");
    225232        }
    226         disp->screen_base += fix->line_length * fb->y_margin + fb->x_margin;
     233        fb->physbase = phys;
     234#else
     235        disp->screen_base = (char *)0x0fd00000;
     236        fb->physbase = (unsigned long)0x0fd00000;
     237#endif
     238
     239//      disp->screen_base += fix->line_length * fb->y_margin + fb->x_margin;
    227240        fb->dispsw = fbcon_cfb8;
    228241
    229242        fb->margins = cg3_margins;
     
    231244        fb->blank = cg3_blank;
    232245        fb->unblank = cg3_unblank;
    233246       
    234         fb->physbase = phys;
    235247        fb->mmap_map = cg3_mmap_map;
    236        
     248
     249#ifndef CONFIG_SUN3     
    237250#ifdef __sparc_v9__     
    238251        sprintf(idstring, "%s at %016lx", cgRDI ? "cgRDI" : "cgthree", phys);
    239252#else
     
    279292                        sbus_writeb(p[1], regp);
    280293                }
    281294        }
     295#else
     296        sprintf(idstring, "%s: mem %x regs %x", "cgthree", fb->physbase, fb->s.cg3.regs);
     297
     298        /* kick up the sun3 -- 66hz prom mode only */
     299        /* this also turns off the overlay in case it's really a cg4 */
     300       
     301        fb->s.cg3.regs->cmap.addr = 4;
     302        fb->s.cg3.regs->cmap.control = 0xff;
     303        fb->s.cg3.regs->cmap.addr = 5;
     304        fb->s.cg3.regs->cmap.control = 0;
     305        fb->s.cg3.regs->cmap.addr = 6;
     306        fb->s.cg3.regs->cmap.control = 0x40;
     307        fb->s.cg3.regs->cmap.addr = 7;
     308        fb->s.cg3.regs->cmap.control = 0;
     309
     310#endif
    282311
    283312        return idstring;
    284313}
  • drivers/video/fbcon.c

    diff -Naur linux-2.4.26/drivers/video/fbcon.c linux-2.4.26-m68k/drivers/video/fbcon.c
    old new  
    23402340            done = 1;
    23412341        }
    23422342#endif
     2343#ifdef CONFIG_HP300
     2344    if (depth == 6 && p->type == FB_TYPE_PACKED_PIXELS) {
     2345        /* depth 6 or more, packed, with color registers */
     2346               
     2347        src = logo;
     2348        for( y1 = 0; y1 < LOGO_H; y1++ ) {
     2349            int c;
     2350            dst = fb + y1*line;
     2351            for( x1 = 0; x1 < LOGO_W / 2; x1++ ) {
     2352                fb_writeb((*src >> 4) + 16, dst++);
     2353                fb_writeb(((*src++) & 0xf) + 16, dst++);
     2354            }
     2355            dst += 8;
     2356            for (c = 0; c < 32; c++)
     2357              for (x1 = 0; x1 < 24; x1++)
     2358                *dst++ = c;
     2359        }
     2360
     2361        done = 1;
     2362    }
     2363#endif /* CONFIG_HP300 */
    23432364#if defined(CONFIG_FBCON_AFB) || defined(CONFIG_FBCON_ILBM) || \
    23442365    defined(CONFIG_FBCON_IPLAN2P2) || defined(CONFIG_FBCON_IPLAN2P4) || \
    23452366    defined(CONFIG_FBCON_IPLAN2P8)
     
    24122433                    dst = fb + (y1%4)*8192 + (y1>>2)*line + x/8;
    24132434                else
    24142435                    dst = fb + y1*line + x/8;
    2415                 for( x1 = 0; x1 < LOGO_LINE; ++x1 )
     2436                for( x1 = 0; x1 < LOGO_LINE; ++x1 ) {
     2437#ifndef CONFIG_HP300
    24162438                    fb_writeb(*src++ ^ inverse, dst++);
     2439#else /* CONFIG_HP300 */
     2440                    /* hack hack -- make it work with topcat in pseudomono mode */
     2441                    char c = *src++ ^ inverse;
     2442                    fb_writeb((c >> 7) & 1, dst++);
     2443                    fb_writeb((c >> 6) & 1, dst++);
     2444                    fb_writeb((c >> 5) & 1, dst++);
     2445                    fb_writeb((c >> 4) & 1, dst++);
     2446                    fb_writeb((c >> 3) & 1, dst++);
     2447                    fb_writeb((c >> 2) & 1, dst++);
     2448                    fb_writeb((c >> 1) & 1, dst++);
     2449                    fb_writeb((c >> 0) & 1, dst++);
     2450#endif /* CONFIG_HP300 */
     2451                }
    24172452            }
    24182453            done = 1;
    24192454        }
  • drivers/video/fbmem.c

    diff -Naur linux-2.4.26/drivers/video/fbmem.c linux-2.4.26-m68k/drivers/video/fbmem.c
    old new  
    5353extern int amifb_setup(char*);
    5454extern int atafb_init(void);
    5555extern int atafb_setup(char*);
     56extern int tekfb_init(void);
    5657extern int macfb_init(void);
    5758extern int macfb_setup(char*);
    5859extern int cyberfb_init(void);
     
    271272#ifdef CONFIG_FB_ATARI
    272273        { "atafb", atafb_init, atafb_setup },
    273274#endif
     275#ifdef CONFIG_FB_TEKXP
     276        { "tekfb", tekfb_init, NULL },
     277#endif
    274278#ifdef CONFIG_FB_MAC
    275279        { "macfb", macfb_init, macfb_setup },
    276280#endif
     
    964968                                            fb_drivers[i].init;
    965969                                    fb_drivers[i].init = NULL;
    966970                            }
    967                             if (fb_drivers[i].setup)
    968                                     fb_drivers[i].setup(options+j+1);
    969971                    }
     972                    if (fb_drivers[i].setup)
     973                            fb_drivers[i].setup(options+j+1);
    970974                    return 0;
    971975            }
    972976    }
  • drivers/video/sun3fb.c

    diff -Naur linux-2.4.26/drivers/video/sun3fb.c linux-2.4.26-m68k/drivers/video/sun3fb.c
    old new  
    4848
    4949#ifdef CONFIG_SUN3
    5050#include <asm/oplib.h>
     51#include <asm/machines.h>
     52#include <asm/idprom.h>
    5153#endif
    5254#ifdef CONFIG_SUN3X
    5355#include <asm/sun3x.h>
     
    5961#define CURSOR_SHAPE                    1
    6062#define CURSOR_BLINK                    2
    6163
     64#define mymemset(x,y) memset(x,0,y)
     65
    6266    /*
    6367     *  Interface used by the world
    6468     */
    6569
    6670int sun3fb_init(void);
    67 int sun3fb_setup(char *options);
     71void sun3fb_setup(char *options);
    6872
    6973static int currcon;
    7074static char fontname[40] __initdata = { 0 };
     
    115119static void sun3fb_clear_margin(struct display *p, int s)
    116120{
    117121        struct fb_info_sbusfb *fb = sbusfbinfod(p);
     122       
     123        return;
    118124
    119125        if (fb->switch_from_graph)
    120126                (*fb->switch_from_graph)(fb);
     
    354360                p++;
    355361        }
    356362
    357         return 0;
     363        return;
    358364}
    359365
    360366static int sun3fbcon_switch(int con, struct fb_info *info)
     
    523529     */
    524530static int __init sun3fb_init_fb(int fbtype, unsigned long addr)
    525531{
    526         static struct linux_sbus_device sdb;
     532        static struct sbus_dev sdb;
    527533        struct fb_fix_screeninfo *fix;
    528534        struct fb_var_screeninfo *var;
    529535        struct display *disp;
     
    531537        struct fbtype *type;
    532538        int linebytes, w, h, depth;
    533539        char *p = NULL;
    534 
     540       
    535541        fb = kmalloc(sizeof(struct fb_info_sbusfb), GFP_ATOMIC);
    536542        if (!fb)
    537543                return -ENOMEM;
     
    600606        case FBTYPE_SUN2BW:
    601607                p = bwtwofb_init(fb); break;
    602608#endif
     609#ifdef CONFIG_FB_CGTHREE
     610        case FBTYPE_SUN4COLOR:
     611        case FBTYPE_SUN3COLOR:
     612                p = cgthreefb_init(fb); break;
     613#endif
    603614        }
    604         fix->smem_start = fb->disp.screen_base;
     615        fix->smem_start = (unsigned long)fb->disp.screen_base;
    605616       
    606617        if (!p) {
    607618                kfree(fb);
     
    656667        unsigned long addr;
    657668        char p4id;
    658669       
    659         if (!con_is_present()) return;
    660         printk("sun3fb_init()\n");
     670        if (!con_is_present()) return -ENXIO;
    661671#ifdef CONFIG_SUN3
    662         addr = 0xfe20000;
    663672        switch(*(romvec->pv_fbtype))
    664673        {
    665                 case FBTYPE_SUN2BW:
    666                         return sun3fb_init_fb(FBTYPE_SUN2BW, addr);
    667                 case FBTYPE_SUN3COLOR:
    668                         printk("cg3 detected but not supported\n");
    669                         return -EINVAL;
     674        case FBTYPE_SUN2BW:
     675                addr = 0xfe20000;
     676                return sun3fb_init_fb(FBTYPE_SUN2BW, addr);
     677        case FBTYPE_SUN3COLOR:
     678        case FBTYPE_SUN4COLOR:
     679                if(idprom->id_machtype != (SM_SUN3|SM_3_60)) {
     680                        printk("sun3fb: cgthree/four only supported on 3/60\n");
     681                        return -ENODEV;
     682                }
     683               
     684                addr = 0xfd00000;
     685                return sun3fb_init_fb(*(romvec->pv_fbtype), addr);
     686        default:
     687                printk("sun3fb: unsupported framebuffer\n");
     688                return -ENODEV;
    670689        }
    671690#else
    672691        addr = SUN3X_VIDEO_BASE;
  • drivers/video/tek_fb.c

    diff -Naur linux-2.4.26/drivers/video/tek_fb.c linux-2.4.26-m68k/drivers/video/tek_fb.c
    old new  
     1/*
     2 *   linux/drivers/video/tek_fb.c
     3 *
     4 *   Copyright (C) 2002,2003 Michael Mueller <malware@t-online.de>
     5 *
     6 * This file is subject to the terms and conditions of the GNU General Public
     7 * License.  See the file COPYING in the main directory of this archive
     8 * for more details.
     9 *
     10 *
     11 * It is basicly a hack to get the console working. So if someone feels
     12 * familiar with the framebuffer API a rework would be welcome.
     13 */
     14
     15#include <linux/config.h>
     16#include <linux/kernel.h>
     17#include <linux/sched.h>
     18#include <linux/errno.h>
     19#include <linux/string.h>
     20#include <linux/mm.h>
     21#include <linux/tty.h>
     22#include <linux/slab.h>
     23#include <linux/init.h>
     24
     25#include <linux/fb.h>
     26
     27#include <video/fbcon.h>
     28#ifdef CONFIG_FBCON_CFB8
     29#include <video/fbcon-cfb8.h>
     30#endif
     31#ifdef CONFIG_FBCON_CFB4
     32#include <video/fbcon-cfb4.h>
     33#endif
     34#ifdef CONFIG_FBCON_MFB
     35#include <video/fbcon-mfb.h>
     36#endif
     37
     38#include <asm/setup.h>
     39#include <asm/uaccess.h>
     40#include <asm/pgtable.h>
     41#include <asm/irq.h>
     42
     43#include <asm/teknvram.h>
     44
     45#define MAX_TEKFB_SIZE  (1280*1024+0x100)
     46#define TEKFP_BASE      (0xDE000000UL)
     47
     48struct tekfb_priv {
     49        u_char*         frameptr;
     50        int             display_type;
     51        int             display_height;
     52        int             display_width;
     53        int             display_coldepth;
     54        int             display_fps;
     55
     56        u_char *        ptr;
     57        u_char *        ptr_ramdac;
     58        int             ramdac_type;
     59        u_char *        ramdac_regs[5];
     60};
     61
     62#define arraysize(x) (sizeof (x)/sizeof (x)[0])
     63
     64   /*
     65    *    Interface used by the world
     66    */
     67
     68void tekxp_video_setup(char *options, int *ints)
     69{
     70        // There is nothing we can do currently
     71}
     72
     73   /*
     74    *    Interface to the low level console driver
     75    */
     76
     77static struct fb_info fb_info;
     78//static int tekfb_switch(int con, struct fb_info *);
     79static int tekfb_update_var(int con, struct fb_info *);
     80static void tekfb_blank(int, struct fb_info *);
     81
     82static int tekfb_get_fix(struct fb_fix_screeninfo *, int, struct fb_info *);
     83static int tekfb_get_var(struct fb_var_screeninfo *, int, struct fb_info *);
     84static int tekfb_set_var(struct fb_var_screeninfo *, int, struct fb_info *);
     85static int tekfb_get_cmap(struct fb_cmap *, int, int, struct fb_info *);
     86static int tekfb_set_cmap(struct fb_cmap *, int, int, struct fb_info *);
     87
     88static struct fb_ops tekfb_ops = {
     89        fb_get_fix: tekfb_get_fix,
     90        fb_get_var: tekfb_get_var,
     91        fb_set_var: tekfb_set_var,
     92        fb_get_cmap: tekfb_get_cmap,
     93        fb_set_cmap: tekfb_set_cmap,
     94};
     95
     96static struct display disp;
     97
     98//static struct fb_var_screeninfo tekfb_predefined;
     99
     100struct fb_var_screeninfo tekfb_fixed =
     101{
     102        xres: 1152, yres: 900,  /* visible resolution */
     103        xres_virtual: 1152, yres_virtual: 900,  /* virtual resolution */
     104        xoffset: 0, yoffset: 0,         /* offset of visible within virtual */
     105        bits_per_pixel: 8,              /* bits per pixel */
     106        grayscale: 0,           /* grayscale */
     107        red: {0, 6, 0}, /* red */
     108        green: {0, 6, 0},       /* green */
     109        blue: {0, 6, 0},        /* blue */
     110        transp: {0, 0, 0},      /* transp */
     111        nonstd: 0,              /* no non-standard pixel format */
     112        activate: 0,            /* activate */
     113        height: -1,             /* height in mm */
     114        width: -1,              /* width in mm */
     115        accel_flags: FB_ACCEL_NONE,     /* accel */
     116};
     117
     118static const char* ramdac_names[4] = { "???", "???", "Bt459", "???" };
     119
     120static int get_private(struct tekfb_priv *priv)
     121{
     122        priv->ptr = ioremap_writethrough(0xD8200000, 0x100);
     123        priv->ptr_ramdac = ioremap_writethrough(0xD8100000, 0x100);
     124        if ( !priv->ptr || !priv->ptr_ramdac )
     125        {
     126                printk("tek_fb: Could not map ramdac into kernel memory space\n");
     127                return -ENOMEM;
     128        }
     129
     130        /*
     131         * Maybe sometime I will understand how a bit field is organized.
     132         * Meanwhile this assembler stuff will do the trick.
     133         */
     134        __asm__("bfextu %1{#6:#2}, %0\n"
     135                : "=r" (priv->ramdac_type)
     136                : "m" (*(priv->ptr + 1)) );
     137        printk("tek_fb: RAMDAC: %d (%s)\n",
     138               priv->ramdac_type, ramdac_names[priv->ramdac_type]);
     139
     140        if ( priv->ramdac_type & 1 )
     141        {
     142                priv->ramdac_regs[0] = priv->ptr_ramdac + 0;
     143                priv->ramdac_regs[1] = priv->ptr_ramdac + 4;
     144                priv->ramdac_regs[2] = priv->ptr_ramdac + 8;
     145                priv->ramdac_regs[3] = priv->ptr_ramdac + 12;
     146                priv->ramdac_regs[4] = NULL;
     147        }
     148        else
     149        {
     150                priv->ramdac_regs[0] = priv->ptr_ramdac + 0;
     151                priv->ramdac_regs[1] = NULL;
     152                priv->ramdac_regs[2] = priv->ptr_ramdac + 8;
     153                priv->ramdac_regs[3] = priv->ptr_ramdac + 4;
     154                priv->ramdac_regs[4] = priv->ptr_ramdac + 12;
     155        }
     156
     157        priv->display_type = nvram_readw(NVRAM_DISPLAY);
     158        switch ( priv->display_type )
     159        {
     160                case 0:
     161                        priv->display_width = 1280;
     162                        priv->display_height = 1024;
     163                        priv->display_coldepth = 4;
     164                        priv->display_fps = 72;
     165                        break;
     166                case 1:
     167                        priv->display_width = 1152;
     168                        priv->display_height = 900;
     169                        priv->display_coldepth = 8;
     170                        priv->display_fps = 60;
     171                        break;
     172                case 3:
     173                        priv->display_width = 1280;
     174                        priv->display_height = 1024;
     175                        priv->display_coldepth = 8;
     176                        priv->display_fps = 72;
     177                        break;
     178                case 4:
     179                        priv->display_width = 1024;
     180                        priv->display_height = 768;
     181                        priv->display_coldepth = 8;
     182                        priv->display_fps = 70;
     183                        break;
     184                case 5:
     185                        priv->display_width = 1024;
     186                        priv->display_height = 768;
     187                        priv->display_coldepth = 8;
     188                        priv->display_fps = 60;
     189                        break;
     190                case 6: // note: it is not really the same as above
     191                        priv->display_width = 1024;
     192                        priv->display_height = 768;
     193                        priv->display_coldepth = 8;
     194                        priv->display_fps = 60;
     195                        break;
     196                case 7:
     197                        priv->display_width = 1152;
     198                        priv->display_height = 900;
     199                        priv->display_coldepth = 1;
     200                        priv->display_fps = 72;
     201                        break;
     202                case 8:
     203                        priv->display_width = 1280;
     204                        priv->display_height = 1024;
     205                        priv->display_coldepth = 1;
     206                        priv->display_fps = 72;
     207                        break;
     208                case 9:
     209                        priv->display_width = 1280;
     210                        priv->display_height = 864;
     211                        priv->display_coldepth = 8;
     212                        priv->display_fps = 60;
     213                        break;
     214                default:
     215                        priv->display_width = 1152;
     216                        priv->display_height = 900;
     217                        priv->display_coldepth = 8;
     218                        priv->display_fps = 72;
     219        }
     220        printk("tek_fb: display type: %d (%dx%dx%d@%d)\n",
     221               priv->display_type, priv->display_width,
     222               priv->display_height, priv->display_coldepth,
     223               priv->display_fps);
     224
     225        return 0;
     226}
     227
     228static inline void set_ramdac_addr(struct tekfb_priv *priv, int addr)
     229{
     230        *(volatile int *)(priv->ramdac_regs[0]) = addr;
     231        if ( priv->ramdac_type & 1 )
     232                *(volatile int *)(priv->ramdac_regs[1]) = (addr >> 8) & 0xff;
     233}
     234
     235static inline unsigned long get_fb_size(struct tekfb_priv *priv)
     236{
     237        return (priv->display_width * priv->display_height * priv->display_coldepth) / 8;
     238}
     239
     240int __devinit tekfb_init(void)
     241{
     242        int err;
     243        struct tekfb_priv *priv = kmalloc(sizeof (*priv), GFP_KERNEL);
     244        if ( !priv )
     245        {
     246                printk(KERN_ERR "tek_fb: Could not allocate memory for private device data\n");
     247                return -ENOMEM;
     248        }
     249        memset(priv, 0, sizeof (*priv));
     250
     251        priv->frameptr = (u_char*)ioremap_writethrough(TEKFP_BASE, MAX_TEKFB_SIZE);
     252        if ( !priv->frameptr )
     253        {
     254                printk(KERN_ERR "tek_fb: Frame buffer did not map into kernel memory space\n");
     255                return -ENOMEM;
     256        }
     257
     258        err = get_private(priv);
     259        if ( err < 0 )
     260                return err;
     261
     262        strcpy(fb_info.modename, "TekXpress");
     263        fb_info.changevar = NULL;
     264        fb_info.node = -1;
     265        fb_info.fbops = &tekfb_ops;
     266        fb_info.disp = &disp;
     267//      fb_info.switch_con = tekfb_switch;
     268        fb_info.switch_con = NULL;
     269        fb_info.updatevar=tekfb_update_var;
     270        fb_info.blank=&tekfb_blank;
     271        fb_info.flags = FBINFO_FLAG_DEFAULT;
     272        fb_info.fontname[0] = 0;
     273        fb_info.par = priv;
     274        if ( fb_alloc_cmap(&fb_info.cmap, 1 << 8, 0) < 0 )
     275        {
     276                printk("tek_fb: Could not allocate color map\n");
     277                return -ENOMEM;
     278        }
     279
     280        tekfb_get_var(&disp.var, 0, &fb_info);
     281        disp.screen_base = priv->frameptr + 0x100;
     282        disp.type = FB_TYPE_PACKED_PIXELS;
     283        disp.line_length = 0;
     284        disp.can_soft_blank = 0;
     285        disp.inverse = 0;
     286        disp.ypanstep = 0;
     287        disp.ywrapstep = 0;
     288        switch ( priv->display_coldepth )
     289        {
     290#ifdef CONFIG_FBCON_CFB8
     291        case 8:
     292                disp.visual = FB_VISUAL_PSEUDOCOLOR;
     293                disp.dispsw = &fbcon_cfb8;
     294                break;
     295#endif
     296#ifdef CONFIG_FBCON_CFB4
     297        case 4:
     298                disp.visual = FB_VISUAL_PSEUDOCOLOR;
     299                disp.dispsw = &fbcon_cfb4;
     300                break;
     301#endif
     302#ifdef CONFIG_FBCON_MFB
     303        case 1:
     304                disp.visual = FB_VISUAL_MONO10;
     305                disp.dispsw = &fbcon_mfb;
     306                break;
     307#endif
     308        default:
     309                panic("tek_fb: unknown/unsupported color depth %d", priv->display_coldepth);
     310        }
     311
     312        memset(priv->frameptr + 0x100, 0, get_fb_size(priv));
     313
     314        return register_framebuffer(&fb_info);
     315}
     316
     317/*
     318static int tekfb_switch(int con, struct fb_info *info)
     319{
     320        return 0;
     321}
     322*/
     323
     324static int tekfb_update_var(int con, struct fb_info *info)
     325{
     326        return 0;
     327}
     328
     329static void tekfb_blank(int m, struct fb_info *info)
     330{
     331}
     332
     333static int tekfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
     334{
     335        int i;
     336        struct tekfb_priv *priv = info->par;
     337
     338        strcpy(fix->id, "TekXpress");
     339        fix->smem_start = (unsigned long)priv->frameptr + 0x100;
     340        fix->smem_len   = MAX_TEKFB_SIZE - 0x100;
     341        fix->type       = FB_TYPE_PACKED_PIXELS;
     342        switch ( priv->display_coldepth )
     343        {
     344        case 8:
     345        case 4:
     346                fix->visual = FB_VISUAL_PSEUDOCOLOR;
     347                break;
     348        case 1:
     349                fix->visual = FB_VISUAL_MONO10;
     350                break;
     351        default:
     352                panic("tek_fb: unknown color depth");
     353        }
     354        fix->xpanstep = 0;
     355        fix->ypanstep = 0;
     356        fix->ywrapstep = 0;
     357        fix->line_length = 0;
     358        for (i=0; i<arraysize(fix->reserved); i++)
     359                fix->reserved[i]=0;
     360        return 0;
     361
     362}
     363
     364static int tekfb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
     365{
     366        struct tekfb_priv *priv = info->par;
     367
     368        *var = tekfb_fixed;
     369
     370        var->xres_virtual = var->xres = priv->display_width;
     371        var->yres_virtual = var->yres = priv->display_height;
     372        var->xoffset = var->yoffset = 0;
     373        var->bits_per_pixel = priv->display_coldepth;
     374
     375        return 0;
     376}
     377
     378static int tekfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
     379{
     380        return 0;
     381}
     382
     383static int tekfb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
     384{
     385        struct tekfb_priv *priv = info->par;
     386        int iCol;
     387
     388        set_ramdac_addr(priv, info->cmap.start);
     389        for ( iCol=0; iCol < info->cmap.len; iCol++ )
     390        {
     391                unsigned long r,g,b;
     392
     393                r = *(volatile u_long *)(priv->ramdac_regs[3]);
     394                if ( priv->ramdac_type )
     395                {
     396                        g = *(volatile u_long *)(priv->ramdac_regs[3]);
     397                        b = *(volatile u_long *)(priv->ramdac_regs[3]);
     398                }
     399                else
     400                        b = g = r;
     401
     402                info->cmap.red[iCol] = r;
     403                info->cmap.green[iCol] = g;
     404                info->cmap.blue[iCol] = b;
     405        }
     406
     407        fb_copy_cmap(&info->cmap, cmap, kspc ? 0 : 2);
     408
     409        return 0;
     410}
     411
     412static int tekfb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
     413{
     414        struct tekfb_priv *priv = info->par;
     415        if ( priv )
     416        {
     417                int iCol;
     418
     419                fb_copy_cmap(cmap, &info->cmap, kspc ? 0 : 1);
     420
     421                set_ramdac_addr(priv, info->cmap.start);
     422                for ( iCol = 0; iCol < info->cmap.len; iCol++ )
     423                {
     424                        int r = info->cmap.red[iCol];
     425                        int g = info->cmap.green[iCol];
     426                        int b = info->cmap.blue[iCol];
     427
     428                        if ( !priv->ramdac_type )
     429                                r = g = b = (38 * r + 90 * g + 128 * b) / 256;
     430
     431                        *(volatile u_long *)(priv->ramdac_regs[3]) = r;
     432                        if ( priv->ramdac_type )
     433                        {
     434                                *(volatile u_long *)(priv->ramdac_regs[3]) = g;
     435                                *(volatile u_long *)(priv->ramdac_regs[3]) = b;
     436                        }
     437
     438                }
     439        }
     440        return 0;
     441}
     442
  • fs/Config.in

    diff -Naur linux-2.4.26/fs/Config.in linux-2.4.26-m68k/fs/Config.in
    old new  
    1919
    2020dep_tristate 'Amiga FFS file system support (EXPERIMENTAL)' CONFIG_AFFS_FS $CONFIG_EXPERIMENTAL
    2121
     22dep_tristate 'Amiga SFS file system support (read-only) (EXPERIMENTAL)' CONFIG_ASFS_FS $CONFIG_EXPERIMENTAL
     23
    2224dep_tristate 'Apple HFS file system support (EXPERIMENTAL)' CONFIG_HFS_FS $CONFIG_EXPERIMENTAL
    2325
    2426dep_tristate 'Apple HFS+ (Extended HFS) file system support (EXPERIMENTAL)' CONFIG_HFSPLUS_FS $CONFIG_EXPERIMENTAL
  • fs/Makefile

    diff -Naur linux-2.4.26/fs/Makefile linux-2.4.26-m68k/fs/Makefile
    old new  
    5555subdir-$(CONFIG_JFFS_FS)        += jffs
    5656subdir-$(CONFIG_JFFS2_FS)       += jffs2
    5757subdir-$(CONFIG_AFFS_FS)        += affs
     58subdir-$(CONFIG_ASFS_FS)        += asfs
    5859subdir-$(CONFIG_ROMFS_FS)       += romfs
    5960subdir-$(CONFIG_QNX4FS_FS)      += qnx4
    6061subdir-$(CONFIG_UDF_FS)         += udf
  • fs/affs/amigaffs.c

    diff -Naur linux-2.4.26/fs/affs/amigaffs.c linux-2.4.26-m68k/fs/affs/amigaffs.c
    old new  
    458458        if (!(sb->s_flags & MS_RDONLY))
    459459                printk(KERN_WARNING "AFFS: Remounting filesystem read-only\n");
    460460        sb->s_flags |= MS_RDONLY;
    461         AFFS_SB->s_flags |= SF_READONLY;        /* Don't allow to remount rw */
    462461}
    463462
    464463void
  • fs/affs/bitmap.c

    diff -Naur linux-2.4.26/fs/affs/bitmap.c linux-2.4.26-m68k/fs/affs/bitmap.c
    old new  
    268268        return 0;
    269269}
    270270
    271 int
    272 affs_init_bitmap(struct super_block *sb)
     271int affs_init_bitmap(struct super_block *sb, int *flags)
    273272{
    274273        struct affs_bm_info *bm;
    275274        struct buffer_head *bmap_bh = NULL, *bh = NULL;
     
    277276        u32 size, blk, end, offset, mask;
    278277        int i, res = 0;
    279278
    280         if (sb->s_flags & MS_RDONLY)
     279        if (*flags & MS_RDONLY)
    281280                return 0;
    282281
    283282        if (!AFFS_ROOT_TAIL(sb, AFFS_SB->s_root_bh)->bm_flag) {
    284283                printk(KERN_NOTICE "AFFS: Bitmap invalid - mounting %s read only\n",
    285284                        kdevname(sb->s_dev));
    286                 sb->s_flags |= MS_RDONLY;
     285                *flags |= MS_RDONLY;
    287286                return 0;
    288287        }
    289288
     
    296295        bm = AFFS_SB->s_bitmap = kmalloc(size, GFP_KERNEL);
    297296        if (!AFFS_SB->s_bitmap) {
    298297                printk(KERN_ERR "AFFS: Bitmap allocation failed\n");
    299                 return 1;
     298                return -ENOMEM;
    300299        }
    301300        memset(AFFS_SB->s_bitmap, 0, size);
    302301
     
    311310                bh = affs_bread(sb, bm->bm_key);
    312311                if (!bh) {
    313312                        printk(KERN_ERR "AFFS: Cannot read bitmap\n");
    314                         res = 1;
     313                        res = -EIO;
    315314                        goto out;
    316315                }
    317316                if (affs_checksum_block(sb, bh)) {
    318317                        printk(KERN_WARNING "AFFS: Bitmap %u invalid - mounting %s read only.\n",
    319318                               bm->bm_key, kdevname(sb->s_dev));
    320                         sb->s_flags |= MS_RDONLY;
     319                        *flags |= MS_RDONLY;
    321320                        goto out;
    322321                }
    323322                pr_debug("AFFS: read bitmap block %d: %d\n", blk, bm->bm_key);
     
    333332                bmap_bh = affs_bread(sb, be32_to_cpu(bmap_blk[blk]));
    334333                if (!bmap_bh) {
    335334                        printk(KERN_ERR "AFFS: Cannot read bitmap extension\n");
    336                         res = 1;
     335                        res = -EIO;
    337336                        goto out;
    338337                }
    339338                bmap_blk = (u32 *)bmap_bh->b_data;
     
    378377        affs_brelse(bmap_bh);
    379378        return res;
    380379}
     380
     381void affs_free_bitmap(struct super_block *sb)
     382{
     383        if (!AFFS_SB->s_bitmap)
     384                return;
     385
     386        affs_brelse(AFFS_SB->s_bmap_bh);
     387        AFFS_SB->s_bmap_bh = NULL;
     388        AFFS_SB->s_last_bmap = ~0;
     389        kfree(AFFS_SB->s_bitmap);
     390        AFFS_SB->s_bitmap = NULL;
     391}
  • fs/affs/super.c

    diff -Naur linux-2.4.26/fs/affs/super.c linux-2.4.26-m68k/fs/affs/super.c
    old new  
    4848                mark_buffer_dirty(AFFS_SB->s_root_bh);
    4949        }
    5050
    51         affs_brelse(AFFS_SB->s_bmap_bh);
    5251        if (AFFS_SB->s_prefix)
    5352                kfree(AFFS_SB->s_prefix);
    54         kfree(AFFS_SB->s_bitmap);
     53        affs_free_bitmap(sb);
    5554        affs_brelse(AFFS_SB->s_root_bh);
    5655
    5756        return;
     
    235234        gid_t                    gid;
    236235        int                      reserved;
    237236        unsigned long            mount_flags;
     237        int                      tmp_flags;     /* fix remount prototype... */
    238238
    239239        pr_debug("AFFS: read_super(%s)\n",data ? (const char *)data : "no options");
    240240
     
    349349                printk(KERN_NOTICE "AFFS: Dircache FS - mounting %s read only\n",
    350350                        kdevname(dev));
    351351                sb->s_flags |= MS_RDONLY;
    352                 AFFS_SB->s_flags |= SF_READONLY;
    353352        }
    354353        switch (chksum) {
    355354                case MUFS_FS:
     
    405404        AFFS_SB->s_root_bh = root_bh;
    406405        /* N.B. after this point s_root_bh must be released */
    407406
    408         if (affs_init_bitmap(sb))
     407        tmp_flags = sb->s_flags;
     408        if (affs_init_bitmap(sb, &tmp_flags))
    409409                goto out_error;
     410        sb->s_flags = tmp_flags;
    410411
    411412        /* set up enough so that it can read an inode */
    412413
     
    445446        int                      reserved;
    446447        int                      root_block;
    447448        unsigned long            mount_flags;
    448         unsigned long            read_only = AFFS_SB->s_flags & SF_READONLY;
     449        int                      res = 0;
    449450
    450451        pr_debug("AFFS: remount(flags=0x%x,opts=\"%s\")\n",*flags,data);
    451452
    452453        if (!parse_options(data,&uid,&gid,&mode,&reserved,&root_block,
    453454            &blocksize,&AFFS_SB->s_prefix,AFFS_SB->s_volume,&mount_flags))
    454455                return -EINVAL;
    455         AFFS_SB->s_flags = mount_flags | read_only;
     456        AFFS_SB->s_flags = mount_flags;
    456457        AFFS_SB->s_mode  = mode;
    457458        AFFS_SB->s_uid   = uid;
    458459        AFFS_SB->s_gid   = gid;
     
    463464                sb->s_dirt = 1;
    464465                while (sb->s_dirt)
    465466                        affs_write_super(sb);
    466                 sb->s_flags |= MS_RDONLY;
    467         } else if (!(AFFS_SB->s_flags & SF_READONLY)) {
    468                 sb->s_flags &= ~MS_RDONLY;
    469         } else {
    470                 affs_warning(sb,"remount","Cannot remount fs read/write because of errors");
    471                 return -EINVAL;
    472         }
    473         return 0;
     467                affs_free_bitmap(sb);
     468        } else
     469                res = affs_init_bitmap(sb, flags);
     470
     471        return res;
    474472}
    475473
    476474static int
  • fs/asfs/Makefile

    diff -Naur linux-2.4.26/fs/asfs/Makefile linux-2.4.26-m68k/fs/asfs/Makefile
    old new  
     1#
     2# Makefile for the linux asfs filesystem routines.
     3#
     4# Note! Dependencies are done automagically by 'make dep', which also
     5# removes any old dependencies. DON'T put your own dependencies here
     6# unless it's something special (not a .c file).
     7#
     8# Note 2! The CFLAGS definitions are now in the main makefile.
     9
     10O_TARGET := asfs.o
     11
     12obj-y  := inode.o
     13obj-m  := $(O_TARGET)
     14
     15include $(TOPDIR)/Rules.make
  • fs/asfs/inode.c

    diff -Naur linux-2.4.26/fs/asfs/inode.c linux-2.4.26-m68k/fs/asfs/inode.c
    old new  
     1/*
     2 *
     3 * Amiga Smart File System, Linux implementation
     4 *
     5 * version: 0.3beta (16.06.2003)
     6 * 
     7 * Copyright (C) 2003  Marek 'March' Szyprowski <marek@amiga.pl>
     8 *
     9 *
     10 * Thanks to Marcin Kurek (Morgoth/Dreamolers-CAPS) for help.
     11 *
     12 * Based on the Linux implementation of the ROMFS file system
     13 * Copyright (C) 1997-1999  Janos Farkas <chexum@shadow.banki.hu>
     14 *
     15 * Using parts of the Amiga FFS filesystem
     16 * Copyright (C) 1993  Ray Burr
     17 * Copyright (C) 1996  Hans-Joachim Widmaier
     18 *
     19 * and parts of the smbfs filesystem additionally
     20 * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
     21 * Copyright (C) 1997 by Volker Lendecke
     22 *
     23 *
     24 * This program is free software; you can redistribute it and/or
     25 * modify it under the terms of the GNU General Public License
     26 * as published by the Free Software Foundation; either version
     27 * 2 of the License, or (at your option) any later version.
     28 *
     29 *
     30 * History:
     31 *
     32 * v0.3beta (17.06.2003)
     33 * - second code clean-up
     34 *
     35 * v0.2beta2 (15.06.2003)
     36 * - fixed yet another stupid bug - driver can't read root block on little-endian systems
     37 * v0.2beta (15.06.2003)
     38 * - fixed stupid bug - now files have 'file' flag (S_IFREG) set...
     39 * - added mount options to set uid, gid and mode of files and dirs
     40 * - made hidden files & dirs really hidden (= not listed in directories)
     41 * - code clean-up
     42 *
     43 * v0.1beta (11.06.2003)
     44 * - after many kernel crashes, finally got it!
     45 * - first working read-only filesystem driver
     46 *
     47 */
     48
     49/* todo:
     50 *      - remove bugs
     51 *      - considering write access...
     52 *      - speed-up entry lookup (use HashTables...)
     53 */
     54
     55#include <linux/module.h>
     56#include <linux/types.h>
     57#include <linux/errno.h>
     58#include <linux/slab.h>
     59#include <linux/asfs_fs.h>
     60#include <linux/fs.h>
     61#include <linux/locks.h>
     62#include <linux/init.h>
     63#include <linux/smp_lock.h>
     64
     65#include <asm/byteorder.h>
     66#include <asm/uaccess.h>
     67
     68static struct inode *asfs_iget_from_fsObject(struct super_block *sb, struct fsObject *obj);
     69
     70static u32 asfs_calcchecksum(struct fsBlockHeader *block, u32 blocksize)
     71{
     72        u32 *data=(void *)block, checksum = 1, tmpchecksum = block->checksum;
     73
     74        block->checksum=0;
     75        while(blocksize > 0) {
     76                checksum+=be32_to_cpu(*data++);
     77                blocksize-=4;
     78        }
     79        block->checksum=tmpchecksum;
     80        return(-checksum);
     81}
     82
     83static inline int asfs_check_block(struct fsBlockHeader *block, u32 blocksize, u32 n)
     84{
     85        if (asfs_calcchecksum((struct fsBlockHeader *)block, blocksize) == be32_to_cpu(((struct fsBlockHeader *)block)->checksum) && n == be32_to_cpu(((struct fsBlockHeader *)block)->ownblock))
     86                return 1;
     87        return 0;
     88}
     89
     90/* get fs structure from block and do some checks... */
     91static int asfs_get_contblock(struct super_block *sb, u32 n, void *dest)
     92{
     93        struct buffer_head *bh;
     94
     95        bh = sb_bread(sb, n);
     96        if (!bh)
     97                return -1;              /* error */
     98        memcpy(dest, ((char *)bh->b_data), sb->s_blocksize);
     99        brelse(bh);
     100
     101        if (asfs_check_block(dest, sb->s_blocksize, n)) {
     102                from32be(((struct fsBlockHeader *)dest)->ownblock);
     103                return 1; /* all okay */
     104        }
     105        return -1; /* error */
     106}
     107
     108/* get data from block without checks... */
     109/*static int asfs_get_datablock (struct super_block *sb, u32 n, void *dest, int len)
     110{
     111        struct buffer_head *bh;
     112        bh = sb_bread(sb, n);
     113        if (!bh)
     114                return -1;
     115        memcpy(dest, ((char *)bh->b_data), len);
     116        brelse(bh);
     117        return 1;
     118}
     119*/
     120static inline struct inode *asfs_get_root_inode(struct super_block *sb)
     121{
     122        struct inode *result = NULL;
     123        void *block;
     124        struct fsObject *obj;
     125
     126        asfs_debug("asfs_get_root_inode\n");
     127
     128        block = kmalloc(sb->s_blocksize, GFP_KERNEL);
     129        if (asfs_get_contblock(sb, sb->u.asfs_sb.rootobjectcontainer, block) < 0)
     130                goto free_and_return;
     131
     132        obj = &(((struct fsObjectContainer *)block)->object[0]);
     133        from32be(obj->objectnode);
     134        from32be(obj->object.dir.firstdirblock);
     135
     136        if (obj->objectnode > 0)
     137                result = asfs_iget_from_fsObject(sb, obj);
     138
     139free_and_return:
     140        kfree(block);
     141        return result;
     142}
     143
     144static struct super_operations asfs_ops;
     145
     146static int asfs_parse_options(char *options, struct super_block *sb)
     147{
     148        char *this_char, *value, *optn;
     149        int f;
     150
     151        /* Fill in defaults */
     152        sb->u.asfs_sb.uid = ASFS_DEFAULT_UID;
     153        sb->u.asfs_sb.gid = ASFS_DEFAULT_GID;
     154        sb->u.asfs_sb.mode = ASFS_DEFAULT_MODE;
     155
     156        if (!options)
     157                return 1;
     158        for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {
     159                f = 0;
     160                if ((value = strchr(this_char,'=')) != NULL)
     161                        *value++ = 0;
     162                if ((f = !strcmp(this_char,"setuid")) || !strcmp(this_char,"setgid")) {
     163                        if (value) {
     164                                if (!*value) {
     165                                        printk("ASFS: Argument for set[ug]id option missing\n");
     166                                        return 0;
     167                                } else {
     168                                        (f ? sb->u.asfs_sb.uid : sb->u.asfs_sb.gid) = simple_strtoul(value,&value,0);
     169                                        if (*value) {
     170                                                printk("ASFS: Bad set[ug]id argument\n");
     171                                                return 0;
     172                                        }
     173                                }
     174                        }
     175                } else if (!strcmp(this_char,"mode")) {
     176                        optn = "mode";
     177                        if (!value || !*value)
     178                                goto out_no_arg;
     179                        sb->u.asfs_sb.mode = simple_strtoul(value,&value,8) & 0777;
     180                        if (*value)
     181                                return 0;
     182                } else {
     183                        printk("ASFS: Unrecognized mount option %s\n", this_char);
     184                        return 0;
     185                }
     186        }
     187        return 1;
     188
     189out_no_arg:
     190        printk("ASFS: The %s option requires an argument\n", optn);
     191        return 0;
     192}
     193
     194static struct super_block *asfs_read_super(struct super_block *sb, void *data, int silent)
     195{
     196        struct buffer_head *bh;
     197        kdev_t dev = sb->s_dev;
     198        struct fsRootBlock *rootblock;
     199
     200        if (!asfs_parse_options(data, sb)) {
     201                printk(KERN_ERR "ASFS: Error parsing options\n");
     202                return NULL;
     203        }
     204
     205        if (!sb_set_blocksize(sb, 512))
     206                return NULL;
     207        sb->s_maxbytes = 0xFFFFFFFF;
     208
     209        bh = sb_bread(sb, 0);
     210        if (!bh) {
     211                printk(KERN_ERR "ASFS: unable to read superblock\n");
     212                goto outnobh;
     213        }
     214
     215        rootblock = (struct fsRootBlock *)bh->b_data;
     216
     217        if (be32_to_cpu(rootblock->bheader.id) == ASFS_ROOTID && be16_to_cpu(rootblock->version) == ASFS_STRUCTURE_VERISON) {
     218                sb->s_blocksize = be32_to_cpu(rootblock->blocksize);
     219                sb->u.asfs_sb.totalblocks = be32_to_cpu(rootblock->totalblocks);
     220                sb->u.asfs_sb.rootobjectcontainer = be32_to_cpu(rootblock->rootobjectcontainer);
     221                sb->u.asfs_sb.extentbnoderoot = be32_to_cpu(rootblock->extentbnoderoot);
     222
     223                brelse(bh);
     224
     225                if (!sb_set_blocksize(sb, sb->s_blocksize)) {
     226                        printk(KERN_ERR "ASFS: Found Amiga SFS RootBlock on dev %s, but blocksize %ld is not supported!\n", bdevname(dev), sb->s_blocksize);
     227                        return NULL;
     228                }
     229
     230                bh = sb_bread(sb, 0);
     231                if (!bh) {
     232                        printk(KERN_ERR "ASFS: unable to read superblock\n");
     233                        goto out;
     234                }
     235                rootblock = (struct fsRootBlock *)bh->b_data;
     236
     237                if (asfs_check_block((void *)rootblock, sb->s_blocksize, 0))
     238                        printk(KERN_NOTICE "ASFS: Found Amiga SFS RootBlock on dev %s. Checksum okay. Mounting...\n", bdevname(dev));
     239                else {
     240                        if (!silent)
     241                                printk(KERN_ERR "ASFS: Found something like Amiga SFS RootBlock on dev %s, but it has checksum error!\n", bdevname(dev));
     242                        goto out;
     243                }
     244        } else {
     245                if (!silent)
     246                        printk(KERN_ERR "ASFS: Can't find a valid Amiga SFS filesystem on dev %s.\n", bdevname(dev));
     247                goto out;
     248        }
     249
     250        brelse(bh);
     251
     252        sb->s_magic = ASFS_MAGIC;
     253        sb->s_flags |= MS_RDONLY | MS_NODEV | MS_NOSUID;
     254        sb->s_op = &asfs_ops;
     255        sb->s_root = d_alloc_root(asfs_get_root_inode(sb));
     256        if (!sb->s_root)
     257                goto outnobh;
     258
     259        /* Ehrhm; sorry.. :) */
     260        if (0) {
     261out:
     262                brelse(bh);
     263outnobh:
     264                sb = NULL;
     265        }
     266        return sb;
     267}
     268
     269/* That's simple too. */
     270
     271static int asfs_statfs(struct super_block *sb, struct statfs *buf)
     272{
     273        buf->f_type = ASFS_MAGIC;
     274        buf->f_bsize = sb->s_blocksize;
     275        buf->f_bfree = buf->f_bavail = buf->f_ffree;
     276        buf->f_blocks = sb->u.asfs_sb.totalblocks;
     277        buf->f_namelen = ASFS_MAXFN;
     278        return 0;
     279}
     280
     281static int asfs_get_fsObject_varlen(struct fsObject *obj)
     282{
     283        int len, i;
     284        u8 *p = obj->name;
     285        for (i=2; i > 0; p++)
     286                if (*p == '\0')
     287                        i--;
     288        len = (p - (u8 *)obj);
     289        if (len & 1)
     290                len++;
     291        return len;
     292}
     293
     294static int asfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
     295{
     296        struct inode *diri = filp->f_dentry->d_inode;
     297        unsigned long f_pos;
     298        int stored = 0;
     299        int obj_skip;
     300
     301        struct fsObjectContainer *objcont;
     302        struct fsObject *obj;
     303        int i;
     304        unsigned long block;
     305
     306        asfs_debug("asfs_readdir:\n");
     307
     308        if (filp->f_pos == diri->i_sb->u.asfs_sb.totalblocks)
     309                return stored;
     310
     311        f_pos = filp->f_pos;
     312
     313        if (f_pos == 0) {
     314                filp->private_data = (void *)0;
     315                if (filldir(dirent, ".", 1, f_pos, diri->i_ino, DT_DIR) < 0)
     316                        return 0;
     317                filp->f_pos = f_pos = 1;
     318                stored++;
     319        }
     320        if (f_pos == 1) {
     321                if (filldir(dirent, "..", 2, f_pos, filp->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
     322                        return stored;
     323                filp->f_pos = f_pos = 2;
     324                stored++;
     325        }
     326
     327        if (diri->u.asfs_i.firstdirblock == 0) {        /* empty directory */
     328                filp->f_pos = diri->i_sb->u.asfs_sb.totalblocks;
     329                return stored;
     330        }
     331
     332        objcont = kmalloc(diri->i_sb->s_blocksize, GFP_KERNEL);
     333
     334        if (f_pos == 2) {       /* reading directory from its beginning */
     335                block = diri->u.asfs_i.firstdirblock;
     336                do {
     337                        if (asfs_get_contblock(diri->i_sb, block, (void *)objcont) < 0)
     338                                goto free_and_end;
     339                        from32be(objcont->previous);
     340                        from32be(objcont->next);
     341                        block = objcont->previous;
     342                } while (objcont->previous != 0);
     343                obj_skip = 0;
     344        } else {
     345                block = f_pos;
     346                if (asfs_get_contblock(diri->i_sb, block, (void *)objcont) < 0)
     347                        goto free_and_end;
     348                from32be(objcont->previous);
     349                from32be(objcont->next);
     350                obj_skip = (int)filp->private_data;
     351        }
     352
     353        i=0;
     354        block = ((struct fsBlockHeader *)objcont)->ownblock;
     355
     356        do {
     357                if (i != 0) {
     358                        if (asfs_get_contblock(diri->i_sb, block, (void *)objcont) < 0)
     359                                goto free_and_end;
     360                        from32be(objcont->previous);
     361                        from32be(objcont->next);
     362                }
     363
     364                i = 0;
     365                obj = &(objcont->object[0]);
     366                from32be(obj->objectnode);
     367
     368                while (obj->objectnode > 0 && ((char *)obj - (char *)objcont) + sizeof(struct fsObject) < diri->i_sb->s_blocksize) {
     369                        if (obj_skip > 0)
     370                                obj_skip--;
     371                        else if (!(obj->bits & OTYPE_HIDDEN)) {
     372                                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);
     373                                filp->f_pos = block;
     374                                if (filldir(dirent, obj->name, strlen(obj->name), block, obj->objectnode, ((obj->bits & OTYPE_DIR) ? DT_DIR : DT_REG)) < 0) {
     375                                        filp->private_data = (void *)i;
     376                                        asfs_debug("ASFS: DirFilling: to be continued...\n");
     377                                        goto free_and_end;
     378                                }
     379                                stored++;
     380                        }
     381                        obj = (struct fsObject *)((char *)(obj) + asfs_get_fsObject_varlen(obj));
     382                        i++;
     383                }
     384                block = objcont->next;
     385
     386        } while (objcont->next != 0);
     387
     388        filp->f_pos = diri->i_sb->u.asfs_sb.totalblocks;
     389
     390free_and_end:
     391        kfree(objcont);
     392        return stored;
     393}
     394
     395static inline u8 upperchar(u8 c)
     396{
     397        if((c>=224 && c<=254 && c!=247) || (c>='a' && c<='z'))
     398                c-=32;
     399        return(c);
     400}
     401
     402static int namecmp(u8 *s, u8 *ct)
     403{
     404        while (upperchar(*s) == upperchar(*ct) && *ct != '\0' && *ct != '/') {
     405                s++; ct++;
     406        }
     407        return (*s == '\0' && (*ct == '\0' || *ct == '/')) ? 0 : *ct - *s;
     408}
     409
     410
     411static struct dentry *asfs_lookup(struct inode *dir, struct dentry *dentry)
     412{
     413        int res;
     414        struct inode *inode;
     415        unsigned char *name;            /* got from dentry */
     416
     417        struct fsObjectContainer *objcont;
     418        struct fsObject *obj;
     419        int i;
     420        unsigned long block;
     421
     422        name = (unsigned char *)dentry->d_name.name;
     423        res = -EACCES;                  /* placeholder for "no data here" */
     424
     425        asfs_debug("asfs_lookup: (searching \"%s\"...) ", name);
     426
     427        objcont = kmalloc(dir->i_sb->s_blocksize, GFP_KERNEL);
     428
     429        block = dir->u.asfs_i.firstdirblock;
     430
     431        do {
     432                if (asfs_get_contblock(dir->i_sb, block, (void *)objcont) < 0)
     433                        goto free_and_error;
     434                from32be(objcont->previous);
     435                from32be(objcont->next);
     436                block = objcont->previous;
     437        } while (objcont->previous != 0);
     438
     439        i=0;
     440        block = ((struct fsBlockHeader *)objcont)->ownblock;
     441
     442        do {
     443                if (i != 0) {
     444                        if (asfs_get_contblock(dir->i_sb, block, (void *)objcont) < 0)
     445                                goto free_and_error;
     446                        from32be(objcont->previous);
     447                        from32be(objcont->next);
     448                }
     449
     450                i = 0;
     451                obj = &(objcont->object[0]);
     452                while (be32_to_cpu(obj->objectnode) > 0 && ((char *)obj - (char *)objcont) + sizeof(struct fsObject) < dir->i_sb->s_blocksize) {
     453                        if (namecmp(obj->name, name) == 0) {
     454                                from32be(obj->objectnode);
     455                                from32be(obj->object.dir.firstdirblock); /* it also corrects file.size and file.firstdatablock */
     456                                from32be(obj->object.dir.hashtable);     /* because they are union */
     457                                from32be(obj->datemodified);
     458                                asfs_debug("Object found! #%d: Node %u, Name %s, Type: %d, inCont %lu\n", i, obj->objectnode, obj->name, obj->bits, block);
     459
     460                                if ((inode = asfs_iget_from_fsObject(dir->i_sb, obj)))
     461                                        goto found_inode;
     462
     463                                asfs_debug("ASFS: Strange - no inode allocated... :(\n");
     464                                goto free_and_error;
     465                        }
     466                        obj = (struct fsObject *)((char *)(obj) + asfs_get_fsObject_varlen(obj));
     467                        i++;
     468                }
     469                block = objcont->next;
     470
     471        } while (objcont->next != 0);
     472
     473        /*
     474         * it's a bit funky, _lookup needs to return an error code
     475         * (negative) or a NULL, both as a dentry.  ENOENT should not
     476         * be returned, instead we need to create a negative dentry by
     477         * d_add(dentry, NULL); and return 0 as no error.
     478         * (Although as I see, it only matters on writable file
     479         * systems).
     480         */
     481
     482        inode = NULL;
     483        asfs_debug("ASFS: object not found.\n");
     484found_inode:
     485        res = 0;
     486        d_add(dentry, inode);
     487free_and_error:
     488        kfree(objcont);
     489        return ERR_PTR(res);
     490}
     491
     492static struct fsExtentBNode asfs_search_BNodeTree(struct super_block *sb, u32 key)
     493{
     494        struct fsBNodeContainer *bnodecont;
     495        struct fsExtentBNode result;
     496        unsigned long block = sb->u.asfs_sb.extentbnoderoot;
     497
     498        bnodecont = kmalloc(sb->s_blocksize, GFP_KERNEL);
     499        while (asfs_get_contblock(sb, block, bnodecont) > 0) {
     500                from16be(bnodecont->btc.nodecount);
     501                if (bnodecont->btc.isleaf) {
     502                        int i;
     503                        struct fsExtentBNode *exbnode;
     504                        exbnode = (void *)bnodecont->btc.bnode;
     505                        for (i=0; i < bnodecont->btc.nodecount; i++) {
     506                                from32be(exbnode->key);
     507                                from32be(exbnode->next);
     508                                from32be(exbnode->prev);
     509                                from16be(exbnode->blocks);
     510                                if (exbnode->key == key) {
     511                                        result = *exbnode;
     512                                        goto found;
     513                                }
     514                                exbnode = (void *)exbnode + bnodecont->btc.nodesize;
     515                        }
     516                } else {
     517                        int i;
     518                        struct BNode *bnode;
     519                        bnode = (void *)bnodecont->btc.bnode;
     520                        for (i=0; i < bnodecont->btc.nodecount && key >= be32_to_cpu(bnode->key); i++)
     521                                bnode = (void *)bnode + bnodecont->btc.nodesize;
     522
     523                        bnode = (void *)bnode - bnodecont->btc.nodesize;
     524                        block = be32_to_cpu(bnode->data);
     525                }
     526        }
     527        /* read error or key not found */
     528        result = (struct fsExtentBNode){0, 0, 0, 0};
     529found:
     530        kfree(bnodecont);
     531        return result;
     532}
     533
     534static int
     535asfs_get_block(struct inode *inode, long block, struct buffer_head *bh_result, int create)
     536{
     537        struct fsExtentBNode extend;
     538        u32 filedata = inode->u.asfs_i.firstdatablock;
     539        unsigned long pos = 0;
     540
     541        asfs_debug("ASFS: get_block(%lu, %ld)\n", inode->i_ino, block);
     542
     543        if (block < 0) {
     544                printk(KERN_ERR "ASFS: asfsget_block: requested block (%ld) < 0!\n", block);
     545                return -EIO;
     546        }
     547
     548        if (block >= inode->i_blocks) {
     549                printk(KERN_ERR "ASFS: asfsget_block: strange block request %ld!\n", block);
     550                return -EIO;
     551        }
     552
     553        do {
     554                extend = asfs_search_BNodeTree(inode->i_sb, filedata);
     555                if (extend.key == 0)
     556                        goto error;
     557                filedata = extend.next;
     558                if (pos + extend.blocks > block) {
     559                        bh_result->b_blocknr = extend.key + block - pos;
     560                        bh_result->b_dev = inode->i_dev;
     561                        bh_result->b_state |= (1UL << BH_Mapped);
     562                        return 0;
     563                }
     564                pos += extend.blocks;
     565        } while (extend.next != 0 && pos < inode->i_blocks);
     566error:
     567        return -EIO;
     568}
     569
     570static int asfs_readpage(struct file *file, struct page *page)
     571{
     572        return block_read_full_page(page, asfs_get_block);
     573}
     574static int asfs_bmap(struct address_space *mapping, long block)
     575{
     576        return generic_block_bmap(mapping,block,asfs_get_block);
     577}
     578
     579/* Mapping from our types to the kernel */
     580
     581static struct address_space_operations asfs_aops = {
     582        .readpage       = asfs_readpage,
     583        .sync_page      = block_sync_page,
     584        .bmap           = asfs_bmap,
     585};
     586
     587struct file_operations asfs_file_operations = {
     588        .llseek         = generic_file_llseek,
     589        .read           = generic_file_read,
     590        .mmap           = generic_file_mmap,
     591};
     592
     593static struct file_operations asfs_dir_operations = {
     594        .read           = generic_read_dir,
     595        .readdir        = asfs_readdir,
     596};
     597
     598static struct inode_operations asfs_dir_inode_operations = {
     599        .lookup         = asfs_lookup,
     600};
     601
     602static struct inode *asfs_iget_from_fsObject(struct super_block *sb, struct fsObject *obj)
     603{
     604        struct inode *result;
     605
     606        result = new_inode(sb);
     607        if (!result)
     608                return result;
     609
     610        result->i_ino = obj->objectnode;
     611        result->i_mode = sb->u.asfs_sb.mode;
     612        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 */
     613        result->i_uid = sb->u.asfs_sb.uid;
     614        result->i_gid = sb->u.asfs_sb.gid;
     615
     616        asfs_debug("asfs_iget_from_fsObject: Setting-up node %lu... ", result->i_ino);
     617
     618        if (obj->bits & OTYPE_DIR) {
     619                asfs_debug("dir (FirstdirBlock: %u, HashTable %u)\n", obj->object.dir.firstdirblock, obj->object.dir.hashtable);
     620
     621                result->i_size = 0;
     622                result->i_op = &asfs_dir_inode_operations;
     623                result->i_fop = &asfs_dir_operations;
     624                result->i_mode |= S_IFDIR | ((result->i_mode & 0400) ? 0100 : 0) | ((result->i_mode & 0040) ? 0010 : 0) | ((result->i_mode & 0004) ? 0001 : 0);
     625                result->u.asfs_i.firstdirblock = obj->object.dir.firstdirblock;
     626                result->u.asfs_i.hashtable = obj->object.dir.hashtable;
     627        } else {
     628                asfs_debug("file (Size: %u, FirstBlock: %u)\n", obj->object.file.size, obj->object.file.data);
     629
     630                result->i_size = obj->object.file.size;
     631                result->i_blocks = (obj->object.file.size + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
     632                result->i_fop = &asfs_file_operations;
     633                result->i_mapping->a_ops = &asfs_aops;
     634                result->i_mode |= S_IFREG;
     635                result->u.asfs_i.firstdatablock = obj->object.file.data;
     636        }
     637        insert_inode_hash(result);
     638        return result;
     639}
     640
     641static struct super_operations asfs_ops = {
     642        .statfs         = asfs_statfs,
     643};
     644
     645static DECLARE_FSTYPE_DEV(asfs_fs_type, "asfs", asfs_read_super);
     646
     647static int __init init_asfs_fs(void)
     648{
     649        return register_filesystem(&asfs_fs_type);
     650}
     651
     652static void __exit exit_asfs_fs(void)
     653{
     654        unregister_filesystem(&asfs_fs_type);
     655}
     656
     657/* Yes, works even as a module... :) */
     658
     659EXPORT_NO_SYMBOLS;
     660MODULE_DESCRIPTION("Amiga Smart File System support for Linux");
     661
     662module_init(init_asfs_fs)
     663module_exit(exit_asfs_fs)
     664MODULE_LICENSE("GPL");
  • fs/binfmt_aout.c

    diff -Naur linux-2.4.26/fs/binfmt_aout.c linux-2.4.26-m68k/fs/binfmt_aout.c
    old new  
    349349                        return error;
    350350                }
    351351                         
    352                 flush_icache_range(text_addr, text_addr+ex.a_text+ex.a_data);
     352                flush_icache_user_range((void *)text_addr, ex.a_text + ex.a_data);
    353353        } else {
    354354                static unsigned long error_time, error_time2;
    355355                if ((ex.a_text & 0xfff || ex.a_data & 0xfff) &&
     
    373373                        do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
    374374                        bprm->file->f_op->read(bprm->file,(char *)N_TXTADDR(ex),
    375375                                        ex.a_text+ex.a_data, &pos);
    376                         flush_icache_range((unsigned long) N_TXTADDR(ex),
    377                                            (unsigned long) N_TXTADDR(ex) +
    378                                            ex.a_text+ex.a_data);
     376                        flush_icache_user_range((void *)N_TXTADDR(ex), ex.a_text + ex.a_data);
    379377                        goto beyond_if;
    380378                }
    381379
     
    471469               
    472470                file->f_op->read(file, (char *)start_addr,
    473471                        ex.a_text + ex.a_data, &pos);
    474                 flush_icache_range((unsigned long) start_addr,
    475                                    (unsigned long) start_addr + ex.a_text + ex.a_data);
     472                flush_icache_user_range((void *)start_addr, ex.a_text + ex.a_data);
    476473
    477474                retval = 0;
    478475                goto out;
  • fs/binfmt_elf.c

    diff -Naur linux-2.4.26/fs/binfmt_elf.c linux-2.4.26-m68k/fs/binfmt_elf.c
    old new  
    403403        retval = interpreter->f_op->read(interpreter, addr, text_data, &offset);
    404404        if (retval < 0)
    405405                goto out;
    406         flush_icache_range((unsigned long)addr,
    407                            (unsigned long)addr + text_data);
     406        flush_icache_user_range(addr, text_data);
    408407
    409408        do_brk(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1),
    410409                interp_ex->a_bss);
  • fs/fat/inode.c

    diff -Naur linux-2.4.26/fs/fat/inode.c linux-2.4.26-m68k/fs/fat/inode.c
    old new  
    1111 */
    1212
    1313#include <linux/module.h>
     14
     15#include <linux/config.h>
    1416#include <linux/msdos_fs.h>
    1517#include <linux/nls.h>
    1618#include <linux/kernel.h>
     
    226228        opts->shortname = 0;
    227229        opts->utf8 = 0;
    228230        opts->iocharset = NULL;
     231        opts->atari = 0;
     232
     233#ifdef CONFIG_ATARI
     234        if(MACH_IS_ATARI)
     235        /* make Atari GEMDOS format the default if machine is an Atari */
     236                opts->atari = 1;
     237#endif
    229238        *debug = *fat = 0;
    230239
    231240        if (!options)
     
    324333                        if (value) ret = 0;
    325334                        else opts->sys_immutable = 1;
    326335                }
     336                else if (!strcmp(this_char,"atari")) {
     337                        if (!value || !strcmp(value,"yes")) opts->atari = 1;
     338                        else if (!strcmp(value,"no")) opts->atari = 0;
     339                        else ret = 0;
     340                }
    327341                else if (!strcmp(this_char,"codepage") && value) {
    328342                        opts->codepage = simple_strtoul(value,&value,0);
    329343                        if (*value) ret = 0;
     
    716730
    717731        error = 0;
    718732        if (!error) {
    719                 sbi->fat_bits = fat32 ? 32 :
     733                if (!opts.atari)
     734                        sbi->fat_bits = fat32 ? 32 :
    720735                        (fat ? fat :
    721736                         (sbi->clusters > MSDOS_FAT12 ? 16 : 12));
     737                else {
     738                        int sectors;
     739                        /* Atari GEMDOS partitions always have 16-bit fat */
     740                        sbi->fat_bits = fat32 ? 32 : (fat ? fat : 16);
     741                        /* If more clusters than fat entries in 16-bit fat, we assume
     742                         * it's a real MSDOS partition with 12-bit fat.
     743                         */
     744                        if (!fat32 && sbi->clusters+2 > sbi->
     745                                fat_length*SECTOR_SIZE*8/sbi->fat_bits)
     746                                sbi->fat_bits = 12;
     747                        /* if it's a floppy disk --> 12bit fat */
     748                        if (!fat32 && MAJOR(sb->s_dev) == FLOPPY_MAJOR)
     749                                sbi->fat_bits = 12;
     750                        /* if it's a ramdisk or loopback device and has one of the usual
     751                         * floppy sizes -> 12bit FAT  */
     752                        sectors = total_sectors + sbi->data_start;
     753                        if (!fat32 && (MAJOR(sb->s_dev) == RAMDISK_MAJOR ||
     754                                 MAJOR(sb->s_dev) == LOOP_MAJOR) &&
     755                                (sectors == 720 || sectors == 1440 || sectors == 2880))
     756                                sbi->fat_bits = 12;
     757                }
    722758                fat_clusters =
    723759                        sbi->fat_length * logical_sector_size * 8 / sbi->fat_bits;
    724760                error = !sbi->fats || (sbi->dir_entries & (sbi->dir_per_block - 1))
    725761                        || sbi->clusters + 2 > fat_clusters + MSDOS_MAX_EXTRA
    726762                        || logical_sector_size < 512
    727763                        || PAGE_CACHE_SIZE < logical_sector_size
    728                         || !b->secs_track || !b->heads;
     764                        /* secs_track and heads may be arbitrary on GEMDOS
     765                           partitions, it depends on partitioning software
     766                           used.  */
     767                        || (!opts.atari && (!b->secs_track || !b->heads));
    729768        }
    730769        brelse(bh);
    731770
     
    744783                error = cvf_formats[i]->mount_cvf(sb, cvf_options);
    745784        if (error || debug) {
    746785                /* The MSDOS_CAN_BMAP is obsolete, but left just to remember */
    747                 printk("[MS-DOS FS Rel. 12,FAT %d,check=%c,conv=%c,"
     786                printk("[MS-DOS FS Rel. 12,FAT %d,check=%c,conv=%c,atari=%c,"
    748787                       "uid=%d,gid=%d,umask=%03o%s]\n",
    749                        sbi->fat_bits,opts.name_check,
    750                        opts.conversion,opts.fs_uid,opts.fs_gid,opts.fs_umask,
     788                       sbi->fat_bits,opts.name_check,opts.conversion,
     789                       opts.atari?'y':'n',opts.fs_uid,opts.fs_gid,opts.fs_umask,
    751790                       MSDOS_CAN_BMAP(sbi) ? ",bmap" : "");
    752791                printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%ld,ds=%ld,de=%d,data=%ld,"
    753792                       "se=%u,ts=%u,ls=%d,rc=%ld,fc=%u]\n",
  • include/asm-m68k/bootinfo.h

    diff -Naur linux-2.4.26/include/asm-m68k/bootinfo.h linux-2.4.26-m68k/include/asm-m68k/bootinfo.h
    old new  
    255255#define MVME16x_BOOTI_VERSION  MK_BI_VERSION( 2, 0 )
    256256#define BVME6000_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
    257257#define Q40_BOOTI_VERSION      MK_BI_VERSION( 2, 0 )
     258#define TEKXP_BOOTI_VERSION    MK_BI_VERSION( 2, 0 )
    258259
    259260#ifdef BOOTINFO_COMPAT_1_0
    260261
  • include/asm-m68k/keyboard.h

    diff -Naur linux-2.4.26/include/asm-m68k/keyboard.h linux-2.4.26-m68k/include/asm-m68k/keyboard.h
    old new  
    1313
    1414#ifdef __KERNEL__
    1515
     16#ifdef CONFIG_TEKXP
     17
     18#include <linux/kernel.h>
     19#include <linux/ioport.h>
     20#include <asm/io.h>
     21
     22#define KEYBOARD_IRQ                    4
     23#define DISABLE_KBD_DURING_INTERRUPTS   0
     24
     25extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
     26extern int pckbd_getkeycode(unsigned int scancode);
     27extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
     28                           char raw_mode);
     29extern char pckbd_unexpected_up(unsigned char keycode);
     30extern void pckbd_leds(unsigned char leds);
     31extern void pckbd_init_hw(void);
     32extern unsigned char pckbd_sysrq_xlate[128];
     33
     34#define kbd_setkeycode          pckbd_setkeycode
     35#define kbd_getkeycode          pckbd_getkeycode
     36#define kbd_translate           pckbd_translate
     37#define kbd_unexpected_up       pckbd_unexpected_up
     38#define kbd_leds                pckbd_leds
     39#define kbd_init_hw             pckbd_init_hw
     40#define kbd_sysrq_xlate         pckbd_sysrq_xlate
     41
     42#define SYSRQ_KEY 0x54
     43
     44/* resource allocation */
     45#define kbd_request_region()
     46#define kbd_request_irq(handler) request_irq(KEYBOARD_IRQ, handler, 0, \
     47                                             "keyboard", NULL)
     48
     49/* How to access the keyboard macros on this platform.  */
     50#define kbd_read_input() (*(volatile unsigned char*)0xff900000)
     51#define kbd_read_status() (*(volatile unsigned char*)0xff900004)
     52#define kbd_write_output(val) do { *(volatile unsigned char*)0xff900000 = (val); } while(0)
     53#define kbd_write_command(val) do { *(volatile unsigned char*)0xff900004 = (val); } while(0)
     54
     55/* Some stoneage hardware needs delays after some operations.  */
     56#define kbd_pause() do { } while(0)
     57
     58/*
     59 * Machine specific bits for the PS/2 driver
     60 */
     61
     62#define AUX_IRQ 4
     63#define aux_request_irq(hand, dev_id) (0)
     64#define aux_free_irq(dev_id)    do { } while (0)
     65
     66#else   /* !CONFIG_TEKXP */
     67
    1668#include <linux/config.h>
    1769#include <linux/kd.h>
    1870#include <asm/machdep.h>
     
    72124#define kbd_write_command(val) out_8(KBD_CNTL_REG, val)
    73125extern unsigned int SYSRQ_KEY;
    74126
     127#endif  /* !CONFIG_TEKXP */
     128
    75129#endif /* __KERNEL__ */
    76130
    77131#endif /* __M68K_KEYBOARD_H */
  • include/asm-m68k/motorola_pgalloc.h

    diff -Naur linux-2.4.26/include/asm-m68k/motorola_pgalloc.h linux-2.4.26-m68k/include/asm-m68k/motorola_pgalloc.h
    old new  
    231231
    232232static inline void flush_tlb_mm(struct mm_struct *mm)
    233233{
    234         if (mm == current->mm)
     234        if (mm == current->active_mm)
    235235                __flush_tlb();
    236236}
    237237
    238238static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
    239239{
    240         if (vma->vm_mm == current->mm)
     240        if (vma->vm_mm == current->active_mm) {
     241                mm_segment_t old_fs = get_fs();
     242                set_fs(USER_DS);
    241243                __flush_tlb_one(addr);
     244                set_fs(old_fs);
     245        }
    242246}
    243247
    244248static inline void flush_tlb_range(struct mm_struct *mm,
    245249                                   unsigned long start, unsigned long end)
    246250{
    247         if (mm == current->mm)
     251        if (mm == current->active_mm)
    248252                __flush_tlb();
    249253}
    250254
  • include/asm-m68k/pgalloc.h

    diff -Naur linux-2.4.26/include/asm-m68k/pgalloc.h linux-2.4.26-m68k/include/asm-m68k/pgalloc.h
    old new  
    126126
    127127#define flush_dcache_page(page)                 do { } while (0)
    128128#define flush_icache_page(vma,pg)              do { } while (0)
    129 #define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
    130 
    131 /* Push n pages at kernel virtual address and clear the icache */
    132 /* RZ: use cpush %bc instead of cpush %dc, cinv %ic */
    133 extern inline void flush_icache_range (unsigned long address,
    134                                        unsigned long endaddr)
    135 {
    136         if (CPU_IS_040_OR_060) {
    137                 short n = (endaddr - address + PAGE_SIZE - 1) / PAGE_SIZE;
    138 
    139                 while (--n >= 0) {
    140                         __asm__ __volatile__("nop\n\t"
    141                                              ".chip 68040\n\t"
    142                                              "cpushp %%bc,(%0)\n\t"
    143                                              ".chip 68k"
    144                                              : : "a" (virt_to_phys((void *)address)));
    145                         address += PAGE_SIZE;
    146                 }
    147         } else {
    148                 unsigned long tmp;
    149                 __asm__ __volatile__("movec %%cacr,%0\n\t"
    150                                      "orw %1,%0\n\t"
    151                                      "movec %0,%%cacr"
    152                                      : "=&d" (tmp)
    153                                      : "di" (FLUSH_I));
    154         }
    155 }
    156129
     130extern void flush_icache_user_page(struct vm_area_struct *vma, struct page *page,
     131                                   unsigned long addr, int len);
    157132
     133extern void flush_icache_range(unsigned long address, unsigned long endaddr);
     134extern void flush_icache_user_range(void *address, unsigned long size);
    158135
    159136
    160137#ifdef CONFIG_SUN3
  • include/asm-m68k/setup.h

    diff -Naur linux-2.4.26/include/asm-m68k/setup.h linux-2.4.26-m68k/include/asm-m68k/setup.h
    old new  
    4141#define MACH_HP300    9
    4242#define MACH_Q40     10
    4343#define MACH_SUN3X   11
     44#define MACH_TEKXP   12
    4445
    4546#ifdef __KERNEL__
    4647
     
    5354#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) || defined(CONFIG_APOLLO) \
    5455        || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000)               \
    5556        || defined(CONFIG_HP300) || defined(CONFIG_Q40)                      \
    56         || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
     57        || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)                  \
     58        || defined(CONFIG_TEKXP)
    5759#  define MACH_IS_AMIGA (m68k_machtype == MACH_AMIGA)
    5860#else
    5961#  define MACH_AMIGA_ONLY
     
    6668#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_APOLLO) \
    6769        || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000)               \
    6870        || defined(CONFIG_HP300) || defined(CONFIG_Q40)                      \
    69         || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
     71        || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)                  \
     72        || defined(CONFIG_TEKXP)
    7073#  define MACH_IS_ATARI (m68k_machtype == MACH_ATARI)
    7174#else
    7275#  define MACH_ATARI_ONLY
     
    7982#elif defined(CONFIG_AMIGA) || defined(CONFIG_ATARI) || defined(CONFIG_APOLLO) \
    8083        || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000)                 \
    8184        || defined(CONFIG_HP300) || defined(CONFIG_Q40)                        \
    82         || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
     85        || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)                    \
     86        || defined(CONFIG_TEKXP)
    8387#  define MACH_IS_MAC (m68k_machtype == MACH_MAC)
    8488#else
    8589#  define MACH_MAC_ONLY
     
    100104#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
    101105        || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000)              \
    102106        || defined(CONFIG_HP300) || defined(CONFIG_Q40)                     \
    103         || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
     107        || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)                 \
     108        || defined(CONFIG_TEKXP)
    104109#  define MACH_IS_APOLLO (m68k_machtype == MACH_APOLLO)
    105110#else
    106111#  define MACH_APOLLO_ONLY
     
    113118#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
    114119        || defined(CONFIG_APOLLO) || defined(CONFIG_BVME6000)               \
    115120        || defined(CONFIG_HP300) || defined(CONFIG_Q40)                     \
    116         || defined(CONFIG_SUN3X) || defined(CONFIG_MVME16x)
     121        || defined(CONFIG_SUN3X) || defined(CONFIG_MVME16x)                 \
     122        || defined(CONFIG_TEKXP)
    117123#  define MACH_IS_MVME147 (m68k_machtype == MACH_MVME147)
    118124#else
    119125#  define MACH_MVME147_ONLY
     
    126132#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
    127133        || defined(CONFIG_APOLLO) || defined(CONFIG_BVME6000)               \
    128134        || defined(CONFIG_HP300) || defined(CONFIG_Q40)                     \
    129         || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
     135        || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)                 \
     136        || defined(CONFIG_TEKXP)
    130137#  define MACH_IS_MVME16x (m68k_machtype == MACH_MVME16x)
    131138#else
    132139#  define MACH_MVME16x_ONLY
     
    139146#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
    140147        || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x)                \
    141148        || defined(CONFIG_HP300) || defined(CONFIG_Q40)                     \
    142         || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
     149        || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)                 \
     150        || defined(CONFIG_TEKXP)
    143151#  define MACH_IS_BVME6000 (m68k_machtype == MACH_BVME6000)
    144152#else
    145153#  define MACH_BVME6000_ONLY
     
    152160#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
    153161        || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \
    154162        || defined(CONFIG_BVME6000) || defined(CONFIG_Q40) \
    155         || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
     163        || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) \
     164        || defined(CONFIG_TEKXP)
    156165#  define MACH_IS_HP300 (m68k_machtype == MACH_HP300)
    157166#else
    158167#  define MACH_HP300_ONLY
     
    165174#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
    166175        || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x)                \
    167176        || defined(CONFIG_BVME6000) || defined(CONFIG_HP300)                \
    168         || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
     177        || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)                 \
     178        || defined(CONFIG_TEKXP)
    169179#  define MACH_IS_Q40 (m68k_machtype == MACH_Q40)
    170180#else
    171181#  define MACH_Q40_ONLY
     
    178188#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
    179189        || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x)                \
    180190        || defined(CONFIG_BVME6000) || defined(CONFIG_HP300)                \
    181         || defined(CONFIG_Q40) || defined(CONFIG_MVME147)
     191        || defined(CONFIG_Q40) || defined(CONFIG_MVME147)                   \
     192        || defined(CONFIG_TEKXP)
    182193#  define MACH_IS_SUN3X (m68k_machtype == MACH_SUN3X)
    183194#else
    184195#  define CONFIG_SUN3X_ONLY
     
    186197#  define MACH_TYPE (MACH_SUN3X)
    187198#endif
    188199
     200#if !defined (CONFIG_TEKXP)
     201#  define MACH_IS_TEKXP (0)
     202#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
     203        || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x)                \
     204        || defined(CONFIG_BVME6000) || defined(CONFIG_HP300)                \
     205        || defined(CONFIG_Q40) || defined(CONFIG_MVME147)                   \
     206        || defined(CONFIG_SUN3X)
     207#  define MACH_IS_TEKXP (m68k_machtype == MACH_TEKXP)
     208#else
     209#  define CONFIG_TEKXP_ONLY
     210#  define MACH_IS_TEKXP (1)
     211#  define MACH_TYPE (MACH_TEKXP)
     212#endif
     213
    189214#ifndef MACH_TYPE
    190215#  define MACH_TYPE (m68k_machtype)
    191216#endif
     
    355380     *  Miscellaneous
    356381     */
    357382
    358 #define NUM_MEMINFO     4
     383#define NUM_MEMINFO     8
    359384#define CL_SIZE         256
    360385
    361386#ifndef __ASSEMBLY__
  • include/asm-m68k/tekirq.h

    diff -Naur linux-2.4.26/include/asm-m68k/tekirq.h linux-2.4.26-m68k/include/asm-m68k/tekirq.h
    old new  
     1/*
     2 *  linux/include/asm-m68k/tekirq.h
     3 *
     4 *  Copyright (C) 2002,2003 Michael Mueller <malware@t-online.de>
     5 *
     6 * This file is subject to the terms and conditions of the GNU General Public
     7 * license. See the file COPYING in the main directory of this archive
     8 * for more details.
     9 */
     10
     11#ifndef _ASM_TEKIRQ_H_
     12#define _ASM_TEKIRQ_H_
     13
     14#include <asm/irq.h>
     15
     16#define TEK_IRQ_VIDEO           (IRQ2)
     17#define TEK_IRQ_KEYB            (IRQ4)
     18#define TEK_IRQ_UART            (IRQ5)
     19#define TEK_IRQ_NET             (IRQ6)
     20
     21#define TEK_IRQ_TIMER_A         (SYS_IRQS + 3)
     22#define TEK_IRQ_TXRDY_A         (SYS_IRQS + 0)
     23#define TEK_IRQ_RXRDY_A         (SYS_IRQS + 1)
     24#define TEK_IRQ_TXRDY_B         (SYS_IRQS + 4)
     25#define TEK_IRQ_RXRDY_B         (SYS_IRQS + 5)
     26
     27#endif  /* !defined(_ASM_TEKIRQ_H_) */
  • include/asm-m68k/teknvram.h

    diff -Naur linux-2.4.26/include/asm-m68k/teknvram.h linux-2.4.26-m68k/include/asm-m68k/teknvram.h
    old new  
     1/*
     2 *  linux/include/asm-m68k/teknvram.h
     3 *
     4 *  Copyright (C) 2002,2003 Michael Mueller <malware@t-online.de>
     5 *
     6 * This file is subject to the terms and conditions of the GNU General Public
     7 * License. See the file COPYING in the main directory of this archive for
     8 * more details.
     9 */
     10
     11#ifndef _ASM_TEKNVRAM_H_
     12#define _ASM_TEKNVRAM_H_
     13
     14#define EEPROM_BASE     0xFFF00000UL
     15#define EEPROM_SIZE     0x800
     16
     17extern void init_nvram(unsigned long* memstart);
     18
     19extern u_char   nvram_readb(int);
     20extern u_short  nvram_readw(int);
     21extern u_long   nvram_readl(int);
     22
     23
     24/*
     25 * Some known data locations within the NVRAM
     26 */
     27#define NVRAM_SONIC_MAC         4       /* 6 bytes MAC address for sonic */
     28#define NVRAM_DISPLAY           0x1c    /* Display type */
     29
     30#endif  /* !defined(_ASM_TEKNVRAM_H_) */
     31
  • include/asm-m68k/tekuart.h

    diff -Naur linux-2.4.26/include/asm-m68k/tekuart.h linux-2.4.26-m68k/include/asm-m68k/tekuart.h
    old new  
     1/*
     2 *  linux/include/asm-m68k/tekuart.h
     3 *
     4 *  Copyright (C) 2002,2003 Michael Mueller <malware@t-online.de>
     5 *
     6 * This file is subject to the terms and conditions of the GNU General Public
     7 * License. See the file COPYING in the main directory of this archive for
     8 * more details.
     9 */
     10
     11#ifndef ASM_TEKUART
     12#define ASM_TEKUART
     13
     14extern spinlock_t tek_uart_lock;
     15
     16#define TEK_UART_BASE   (0xFF800000UL)
     17
     18#define UART_IRQS 8
     19
     20void tek_uart_init_IRQ(void);
     21int tek_uart_request_irq(unsigned int irq,
     22                          void (*handler)(int, void *, struct pt_regs *),
     23                          unsigned long flags,
     24                          const char *devname, void *dev_id);
     25void tek_uart_free_irq(unsigned int irq, void *dev_id);
     26void tek_uart_enable_irq(unsigned int irq);
     27void tek_uart_disable_irq(unsigned int irq);
     28int tek_uart_get_irq_list(char *buf);
     29
     30void tek_uart_setup_timer(void (*handler)(int, void *, struct pt_regs *));
     31void tek_uart_putchar(int channel, int c, int waitloop);
     32
     33void tek_uart_set_op(int nr);
     34void tek_uart_clr_op(int nr);
     35
     36/*
     37 * Structures describing the register set of the Motorola 68681 DUART.
     38 */
     39
     40struct tek_uart_rd {
     41        unsigned char   MRxA;
     42        unsigned short  _pad1;
     43        unsigned char   SRA;
     44        unsigned short  _pad2;
     45        unsigned char   BRG_Test;
     46        unsigned short  _pad3;
     47        unsigned char   RHRA;
     48        unsigned short  _pad4;
     49        unsigned char   IPCR;
     50        unsigned short  _pad5;
     51        unsigned char   ISR;
     52        unsigned short  _pad6;
     53        unsigned char   CTU;
     54        unsigned short  _pad7;
     55        unsigned char   CTL;
     56        unsigned short  _pad8;
     57        unsigned char   MRxB;
     58        unsigned short  _pad9;
     59        unsigned char   SRB;
     60        unsigned short  _pad10;
     61        unsigned char   x1x16_Test;
     62        unsigned short  _pad11;
     63        unsigned char   RHRB;
     64        unsigned short  _pad12;
     65        unsigned char   res1;
     66        unsigned short  _pad13;
     67        unsigned char   IP;
     68        unsigned short  _pad14;
     69        unsigned char   CounterStart;
     70        unsigned short  _pad15;
     71        unsigned char   CounterStop;
     72        unsigned short  _pad16;
     73};
     74
     75struct tek_uart_wr {
     76        unsigned char   MRxA;
     77        unsigned short  _pad1;
     78        unsigned char   CSRA;
     79        unsigned short  _pad2;
     80        unsigned char   CRA;
     81        unsigned short  _pad3;
     82        unsigned char   THRA;
     83        unsigned short  _pad4;
     84        unsigned char   ACR;
     85        unsigned short  _pad5;
     86        unsigned char   IMR;
     87        unsigned short  _pad6;
     88        unsigned char   CRUR;
     89        unsigned short  _pad7;
     90        unsigned char   CTLR;
     91        unsigned short  _pad8;
     92        unsigned char   MRxB;
     93        unsigned short  _pad9;
     94        unsigned char   CSRB;
     95        unsigned short  _pad10;
     96        unsigned char   CRB;
     97        unsigned short  _pad11;
     98        unsigned char   THRB;
     99        unsigned short  _pad12;
     100        unsigned char   res1;
     101        unsigned short  _pad13;
     102        unsigned char   OPCR;
     103        unsigned short  _pad14;
     104        unsigned char   OutputSet;
     105        unsigned short  _pad15;
     106        unsigned char   OutputClear;
     107        unsigned short  _pad16;
     108};
     109
     110union tek_uart {
     111        struct tek_uart_rd rd;
     112        struct tek_uart_wr wr;
     113};
     114
     115typedef union tek_uart tek_uart_t;
     116
     117#endif  /* defined(ASM_TEKUART) */
     118
  • include/linux/adb.h

    diff -Naur linux-2.4.26/include/linux/adb.h linux-2.4.26-m68k/include/linux/adb.h
    old new  
    7676#define ADBREQ_REPLY    1       /* expect reply */
    7777#define ADBREQ_SYNC     2       /* poll until done */
    7878#define ADBREQ_NOSEND   4       /* build the request, but don't send it */
     79#define ADBREQ_RAW      8       /* send raw packet (don't prepend ADB_PACKET) */
    7980
    8081/* Messages sent thru the client_list notifier. You should NOT stop
    8182   the operation, at least not with this version */
  • include/linux/affs_fs.h

    diff -Naur linux-2.4.26/include/linux/affs_fs.h linux-2.4.26-m68k/include/linux/affs_fs.h
    old new  
    3333extern u32      affs_count_free_blocks(struct super_block *s);
    3434extern void     affs_free_block(struct super_block *sb, u32 block);
    3535extern u32      affs_alloc_block(struct inode *inode, u32 goal);
    36 extern int      affs_init_bitmap(struct super_block *sb);
     36extern int      affs_init_bitmap(struct super_block *sb, int *flags);
     37extern void     affs_free_bitmap(struct super_block *sb);
    3738
    3839/* namei.c */
    3940
  • include/linux/affs_fs_sb.h

    diff -Naur linux-2.4.26/include/linux/affs_fs_sb.h linux-2.4.26-m68k/include/linux/affs_fs_sb.h
    old new  
    4747#define SF_OFS          0x0200          /* Old filesystem */
    4848#define SF_PREFIX       0x0400          /* Buffer for prefix is allocated */
    4949#define SF_VERBOSE      0x0800          /* Talk about fs when mounting */
    50 #define SF_READONLY     0x1000          /* Don't allow to remount rw */
    5150
    5251/* short cut to get to the affs specific sb data */
    5352#define AFFS_SB         (&sb->u.affs_sb)
  • include/linux/asfs_fs.h

    diff -Naur linux-2.4.26/include/linux/asfs_fs.h linux-2.4.26-m68k/include/linux/asfs_fs.h
    old new  
     1#ifndef __LINUX_ASFS_FS_H
     2#define __LINUX_ASFS_FS_H
     3
     4#include <linux/types.h>
     5#include <asm/byteorder.h>
     6
     7#define asfs_debug(fmt,arg...) pr_debug(fmt,##arg)
     8//#define asfs_debug(fmt,arg...) printk(fmt,##arg)
     9
     10/* some helper macros... */
     11
     12#define from32be(t) ((t)=be32_to_cpu(t))
     13#define from16be(t) ((t)=be16_to_cpu(t))
     14
     15#define ASFS_MAKE_ID(a,b,c,d) (((a)&0xff)<<24|((b)&0xff)<<16|((c)&0xff)<<8|((d)&0xff))
     16
     17/* Amiga SFS defines */
     18
     19#define ASFS_MAGIC 0xa0ff
     20#define ASFS_MAXFN 105
     21
     22#define ASFS_ROOTID ASFS_MAKE_ID('S','F','S',0)
     23
     24#define ASFS_DEFAULT_UID 0
     25#define ASFS_DEFAULT_GID 0
     26#define ASFS_DEFAULT_MODE 0444 /* default permission bits for files, dirs have same permission, but with "x" set */
     27
     28#define ASFS_STRUCTURE_VERISON (3)
     29
     30#define OTYPE_HIDDEN      (1)
     31#define OTYPE_LINK        (64)
     32#define OTYPE_DIR         (128)
     33
     34#define MSB_MASK (1ul << 31)
     35
     36/* Each block has its own header with checksum and id, its called fsBlockHeader */
     37
     38struct fsBlockHeader {
     39        u32 id;                         /* 4 character id string of this block */
     40        u32 checksum;                   /* The checksum */
     41        u32 ownblock;                   /* The blocknumber of the block this block is stored at */
     42};
     43
     44/* On-disk "super block", called fsRootBlock */
     45
     46struct fsRootBlock {
     47        struct fsBlockHeader bheader;
     48
     49        u16 version;                    /* Version number of the filesystem block structure */
     50        u16 sequencenumber;             /* The Root with the highest sequencenumber is valid */
     51
     52        u32 datecreated;                /* Creation date (when first formatted).  Cannot be changed. */
     53        u8 bits;                        /* various settings, see defines below. */
     54        u8 pad1;
     55        u16 pad2;
     56
     57        u32 reserved1[2];
     58
     59        u64 firstbyte;                  /* The first byte of our partition from the start of the disk. */
     60
     61        u64 lastbyte;                   /* The last byte of our partition, excluding this one. */
     62
     63        u32 totalblocks;                /* size of this partition in blocks */
     64        u32 blocksize;                  /* blocksize used */
     65
     66        u32 reserved2[2];
     67        u32 reserved3[8];
     68
     69        u32 bitmapbase;                 /* location of the bitmap */
     70        u32 adminspacecontainer;        /* location of first adminspace container */
     71        u32 rootobjectcontainer;        /* location of the root objectcontainer */
     72        u32 extentbnoderoot;            /* location of the root of the extentbnode B-tree */
     73        u32 objectnoderoot;             /* location of the root of the objectnode tree */
     74
     75        u32 reserved4[3];
     76};
     77
     78/* On disk inode, called fsObject */
     79
     80struct fsObject {
     81        u16 owneruid;
     82        u16 ownergid;
     83        u32 objectnode;
     84        u32 protection;
     85
     86        union {
     87                struct {
     88                        u32 data;
     89                        u32 size;
     90                } file;
     91
     92                struct {
     93                        u32 hashtable;  /* for directories & root, 0 means no hashblock */
     94                        u32 firstdirblock;
     95                } dir;
     96        } object;
     97
     98        u32 datemodified;
     99        u8 bits;
     100
     101        u8 name[0];
     102        u8 comment[0];
     103};
     104
     105/* On disk block containging a number of fsObjects */
     106
     107struct fsObjectContainer {
     108        struct fsBlockHeader bheader;
     109
     110        u32 parent;
     111        u32 next;
     112        u32 previous;                   /* 0 for the first block in the directory chain */
     113
     114        struct fsObject object[0];
     115};
     116
     117/* BTree structures, used to collect file data position on disk */
     118
     119struct fsExtentBNode {
     120        u32 key;                        /* data! */
     121        u32 next;
     122        u32 prev;
     123        u16 blocks;                     /* The size in blocks of the region this Extent controls */
     124};
     125
     126struct BNode {
     127        u32 key;
     128        u32 data;
     129};
     130
     131struct BTreeContainer {
     132        u16 nodecount;
     133        u8 isleaf;
     134        u8 nodesize;                    /* Must be a multiple of 2 */
     135
     136        struct BNode bnode[0];
     137};
     138
     139/* On disk block with BTreeContainer */
     140
     141struct fsBNodeContainer {
     142        struct fsBlockHeader bheader;
     143        struct BTreeContainer btc;
     144};
     145
     146#ifdef __KERNEL__
     147
     148/* Not much now */
     149
     150#endif /* __KERNEL__ */
     151#endif
  • include/linux/asfs_fs_i.h

    diff -Naur linux-2.4.26/include/linux/asfs_fs_i.h linux-2.4.26-m68k/include/linux/asfs_fs_i.h
    old new  
     1#ifndef __ASFS_FS_I
     2#define __ASFS_FS_I
     3
     4/* inode in-kernel data */
     5
     6struct asfs_inode_info {
     7        u32 firstdirblock;
     8        u32 firstdatablock;
     9        u32 hashtable;
     10};
     11
     12#endif
  • include/linux/asfs_fs_sb.h

    diff -Naur linux-2.4.26/include/linux/asfs_fs_sb.h linux-2.4.26-m68k/include/linux/asfs_fs_sb.h
    old new  
     1#ifndef __ASFS_FS_SB
     2#define __ASFS_FS_SB
     3
     4/* Amiga SFS superblock in-core data */
     5
     6struct asfs_sb_info {
     7        u32 totalblocks;
     8        u32 rootobjectcontainer;
     9        u32 extentbnoderoot;
     10        uid_t uid;
     11        gid_t gid;
     12        umode_t mode;
     13};
     14
     15#endif
  • include/linux/bootmem.h

    diff -Naur linux-2.4.26/include/linux/bootmem.h linux-2.4.26-m68k/include/linux/bootmem.h
    old new  
    3838#define alloc_bootmem(x) \
    3939        __alloc_bootmem((x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
    4040#define alloc_bootmem_low(x) \
    41         __alloc_bootmem((x), SMP_CACHE_BYTES, 0)
     41        __alloc_bootmem((x), SMP_CACHE_BYTES, __pa(PAGE_OFFSET))
    4242#define alloc_bootmem_pages(x) \
    4343        __alloc_bootmem((x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
    4444#define alloc_bootmem_low_pages(x) \
    45         __alloc_bootmem((x), PAGE_SIZE, 0)
     45        __alloc_bootmem((x), PAGE_SIZE, __pa(PAGE_OFFSET))
    4646extern unsigned long __init free_all_bootmem (void);
    4747
    4848extern unsigned long __init init_bootmem_node (pg_data_t *pgdat, unsigned long freepfn, unsigned long startpfn, unsigned long endpfn);
  • include/linux/fs.h

    diff -Naur linux-2.4.26/include/linux/fs.h linux-2.4.26-m68k/include/linux/fs.h
    old new  
    307307#include <linux/nfs_fs_i.h>
    308308#include <linux/sysv_fs_i.h>
    309309#include <linux/affs_fs_i.h>
     310#include <linux/asfs_fs_i.h>
    310311#include <linux/ufs_fs_i.h>
    311312#include <linux/efs_fs_i.h>
    312313#include <linux/coda_fs_i.h>
     
    502503                struct nfs_inode_info           nfs_i;
    503504                struct sysv_inode_info          sysv_i;
    504505                struct affs_inode_info          affs_i;
     506                struct asfs_inode_info          asfs_i;
    505507                struct ufs_inode_info           ufs_i;
    506508                struct efs_inode_info           efs_i;
    507509                struct romfs_inode_info         romfs_i;
     
    719721#include <linux/nfs_fs_sb.h>
    720722#include <linux/sysv_fs_sb.h>
    721723#include <linux/affs_fs_sb.h>
     724#include <linux/asfs_fs_sb.h>
    722725#include <linux/ufs_fs_sb.h>
    723726#include <linux/efs_fs_sb.h>
    724727#include <linux/romfs_fs_sb.h>
     
    777780                struct nfs_sb_info      nfs_sb;
    778781                struct sysv_sb_info     sysv_sb;
    779782                struct affs_sb_info     affs_sb;
     783                struct asfs_sb_info     asfs_sb;
    780784                struct ufs_sb_info      ufs_sb;
    781785                struct efs_sb_info      efs_sb;
    782786                struct shmem_sb_info    shmem_sb;
  • include/linux/module.h

    diff -Naur linux-2.4.26/include/linux/module.h linux-2.4.26-m68k/include/linux/module.h
    old new  
    284284 */
    285285 
    286286#define MODULE_LICENSE(license)         \
    287 static const char __module_license[] __attribute__((section(".modinfo"))) =   \
     287static const char __module_license[] __attribute_used__ __attribute__((section(".modinfo"))) =   \
    288288"license=" license
    289289
    290290/* Define the module variable, and usage macros.  */
     
    296296#define MOD_IN_USE              __MOD_IN_USE(THIS_MODULE)
    297297
    298298#include <linux/version.h>
    299 static const char __module_kernel_version[] __attribute__((section(".modinfo"))) =
     299static const char __module_kernel_version[] __attribute_used__ __attribute__((section(".modinfo"))) =
    300300"kernel_version=" UTS_RELEASE;
    301301#ifdef MODVERSIONS
    302 static const char __module_using_checksums[] __attribute__((section(".modinfo"))) =
     302static const char __module_using_checksums[] __attribute_used__ __attribute__((section(".modinfo"))) =
    303303"using_checksums=1";
    304304#endif
    305305
  • include/linux/pc_keyb.h

    diff -Naur linux-2.4.26/include/linux/pc_keyb.h linux-2.4.26-m68k/include/linux/pc_keyb.h
    old new  
    1414#define KBD_REPORT_UNKN                 /* Report unknown scan codes */
    1515#define KBD_REPORT_TIMEOUTS             /* Report keyboard timeouts */
    1616#undef KBD_IS_FOCUS_9000                /* We have the brain-damaged FOCUS-9000 keyboard */
     17#ifndef CONFIG_TEKXP
    1718#undef INITIALIZE_MOUSE                 /* Define if your PS/2 mouse needs initialization. */
     19#else
     20#define INITIALIZE_MOUSE 1
     21#endif
    1822
    1923
    2024
  • kernel/ptrace.c

    diff -Naur linux-2.4.26/kernel/ptrace.c linux-2.4.26-m68k/kernel/ptrace.c
    old new  
    165165                if (write) {
    166166                        memcpy(maddr + offset, buf, bytes);
    167167                        flush_page_to_ram(page);
    168                         flush_icache_user_range(vma, page, addr, len);
     168                        flush_icache_user_page(vma, page, addr, len);
    169169                        set_page_dirty(page);
    170170                } else {
    171171                        memcpy(buf, maddr + offset, bytes);
  • mm/bootmem.c

    diff -Naur linux-2.4.26/mm/bootmem.c linux-2.4.26-m68k/mm/bootmem.c
    old new  
    244244
    245245static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
    246246{
    247         struct page *page = pgdat->node_mem_map;
     247        struct page *page;
    248248        bootmem_data_t *bdata = pgdat->bdata;
    249249        unsigned long i, count, total = 0;
    250250        unsigned long idx;
     
    253253
    254254        count = 0;
    255255        idx = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT);
    256         for (i = 0; i < idx; i++, page++) {
     256        for (i = 0; i < idx; i++) {
    257257                if (!test_bit(i, bdata->node_bootmem_map)) {
     258                        page = virt_to_page(phys_to_virt((i << PAGE_SHIFT) +
     259                                                         bdata->node_boot_start));
    258260                        count++;
    259261                        ClearPageReserved(page);
    260262                        set_page_count(page, 1);
  • mm/page_alloc.c

    diff -Naur linux-2.4.26/mm/page_alloc.c linux-2.4.26-m68k/mm/page_alloc.c
    old new  
    720720 *   - clear the memory bitmaps
    721721 */
    722722void __init free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap,
    723         unsigned long *zones_size, unsigned long zone_start_paddr,
     723        unsigned long *zones_size, unsigned long zone_start_vaddr,
    724724        unsigned long *zholes_size, struct page *lmem_map)
    725725{
    726726        unsigned long i, j;
     
    728728        unsigned long totalpages, offset, realtotalpages;
    729729        const unsigned long zone_required_alignment = 1UL << (MAX_ORDER-1);
    730730
    731         if (zone_start_paddr & ~PAGE_MASK)
     731        if (zone_start_vaddr & ~PAGE_MASK)
    732732                BUG();
    733733
    734734        totalpages = 0;
     
    758758        }
    759759        *gmap = pgdat->node_mem_map = lmem_map;
    760760        pgdat->node_size = totalpages;
    761         pgdat->node_start_paddr = zone_start_paddr;
     761        pgdat->node_start_paddr = __pa(zone_start_vaddr);
    762762        pgdat->node_start_mapnr = (lmem_map - mem_map);
    763763        pgdat->nr_zones = 0;
    764764
     
    835835
    836836                zone->zone_mem_map = mem_map + offset;
    837837                zone->zone_start_mapnr = offset;
    838                 zone->zone_start_paddr = zone_start_paddr;
     838                zone->zone_start_paddr = __pa(zone_start_vaddr);
    839839
    840                 if ((zone_start_paddr >> PAGE_SHIFT) & (zone_required_alignment-1))
     840                if ((zone_start_vaddr >> PAGE_SHIFT) & (zone_required_alignment-1))
    841841                        printk("BUG: wrong zone alignment, it will crash\n");
    842842
    843843                /*
     
    852852                        SetPageReserved(page);
    853853                        INIT_LIST_HEAD(&page->list);
    854854                        if (j != ZONE_HIGHMEM)
    855                                 set_page_address(page, __va(zone_start_paddr));
    856                         zone_start_paddr += PAGE_SIZE;
     855                                set_page_address(page,
     856                                                 (void *)zone_start_vaddr);
     857                        zone_start_vaddr += PAGE_SIZE;
    857858                }
    858859
    859860                offset += size;
     
    900901
    901902void __init free_area_init(unsigned long *zones_size)
    902903{
    903         free_area_init_core(0, &contig_page_data, &mem_map, zones_size, 0, 0, 0);
     904        free_area_init_core(0, &contig_page_data, &mem_map, zones_size, PAGE_OFFSET, 0, 0);
    904905}
    905906
    906907static int __init setup_mem_frac(char *str)
Note: See TracBrowser for help on using the repository browser.