]> git.neil.brown.name Git - history.git/commitdiff
Import 1.1.72 1.1.72
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:46 +0000 (15:09 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:46 +0000 (15:09 -0500)
45 files changed:
CREDITS
Makefile
arch/sparc/boot/boot.S
arch/sparc/string.S [new file with mode: 0644]
drivers/block/floppy.c
drivers/char/lp.c
drivers/net/3c501.c
drivers/net/3c509.c
drivers/net/8390.c
drivers/net/MODULES
drivers/net/Space.c
drivers/net/apricot.c
drivers/net/de600.c
drivers/net/de620.c
drivers/net/depca.c
drivers/net/eexpress.c
drivers/net/ewrk3.c
drivers/net/net_init.c
drivers/net/plip.c
drivers/net/znet.c
drivers/scsi/sg.c
fs/binfmt_elf.c
fs/isofs/inode.c
fs/msdos/inode.c
fs/proc/array.c
fs/proc/root.c
fs/sysv/inode.c
fs/umsdos/inode.c
fs/xiafs/inode.c
include/asm-m68k/system.h
include/linux/fd.h
include/linux/ioport.h
include/linux/netdevice.h
include/linux/proc_fs.h
init/main.c
kernel/ioport.c
kernel/ksyms.c
mm/filemap.c
mm/swap.c
modules/NET_MODULES
net/inet/igmp.c
net/inet/ip.c
net/inet/ip_fw.c
net/inet/tcp.c
tools/version.c

diff --git a/CREDITS b/CREDITS
index 85510e49aab91d027a8f0c750c2f49b4fadf9d23..24f2da98199045c1063b310461717f806ee9c6f9 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -710,9 +710,8 @@ E: jon@gtex02.us.es
 D: NFS mmap()
 D: XF86_S3
 D: Kernel modules
-S: C/ Teodosio 43
-S: Portal 6 1-A
-S: Sevilla 41002
+S: C/ Carlos de Cepeda 36 2-5
+S: Sevilla 41005
 S: Spain
 
 N: Linus Torvalds
index 7ba5d96ef35d9b5a2e714b331315567d9aad08b9..08ba20649d5e42639c9ecadecd04b9748589a569 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 1
-SUBLEVEL = 71
+SUBLEVEL = 72
 
 ARCH = i386
 
@@ -102,7 +102,7 @@ endif
        $(CC) $(CFLAGS) -c -o $*.o $<
 
 Version: dummy
-       rm -f tools/version.h
+       rm -f include/linux/version.h
 
 boot:
        ln -sf arch/$(ARCH)/boot boot
@@ -127,25 +127,25 @@ config: symlinks config.in
 linuxsubdirs: dummy
        set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i; done
 
-tools/./version.h: tools/version.h
+$(TOPDIR)/include/linux/version.h: include/linux/version.h
 
-tools/version.h: $(CONFIGURE) Makefile
+include/linux/version.h: $(CONFIGURE) Makefile
        @./makever.sh
-       @echo \#define UTS_RELEASE \"$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)\" > tools/version.h
+       @echo \#define UTS_RELEASE \"$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)\" > include/linux/version.h
        @if [ -f .name ]; then \
           echo \#define UTS_VERSION \"\#`cat .version`-`cat .name` `date`\"; \
         else \
           echo \#define UTS_VERSION \"\#`cat .version` `date`\";  \
-        fi >> tools/version.h 
-       @echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> tools/version.h
-       @echo \#define LINUX_COMPILE_BY \"`whoami`\" >> tools/version.h
-       @echo \#define LINUX_COMPILE_HOST \"`hostname`\" >> tools/version.h
+        fi >> include/linux/version.h 
+       @echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> include/linux/version.h
+       @echo \#define LINUX_COMPILE_BY \"`whoami`\" >> include/linux/version.h
+       @echo \#define LINUX_COMPILE_HOST \"`hostname`\" >> include/linux/version.h
        @if [ -x /bin/dnsdomainname ]; then \
           echo \#define LINUX_COMPILE_DOMAIN \"`dnsdomainname`\"; \
         else \
           echo \#define LINUX_COMPILE_DOMAIN \"`domainname`\"; \
-        fi >> tools/version.h
-       @echo \#define LINUX_COMPILER \"`$(HOSTCC) -v 2>&1 | tail -1`\" >> tools/version.h
+        fi >> include/linux/version.h
+       @echo \#define LINUX_COMPILER \"`$(HOSTCC) -v 2>&1 | tail -1`\" >> include/linux/version.h
 
 tools/build: tools/build.c $(CONFIGURE)
        $(HOSTCC) $(CFLAGS) -o $@ $<
@@ -155,7 +155,7 @@ boot/head.o: $(CONFIGURE) boot/head.s
 boot/head.s: boot/head.S $(CONFIGURE) include/linux/tasks.h
        $(CPP) -traditional $< -o $@
 
-tools/version.o: tools/version.c tools/version.h
+tools/version.o: tools/version.c include/linux/version.h
 
 init/main.o: $(CONFIGURE) init/main.c
        $(CC) $(CFLAGS) $(PROFILING) -c -o $*.o $<
@@ -191,7 +191,7 @@ clean:      archclean
        rm -f .tmp* drivers/sound/configure
 
 mrproper: clean
-       rm -f include/linux/autoconf.h tools/version.h
+       rm -f include/linux/autoconf.h include/linux/version.h
        rm -f drivers/sound/local.h
        rm -f .version .config* config.in config.old
        rm -f boot include/asm kernel/entry.S
@@ -204,11 +204,11 @@ backup: mrproper
        sync
 
 depend dep:
-       touch tools/version.h
+       touch include/linux/version.h
        for i in init/*.c;do echo -n "init/";$(CPP) -M $$i;done > .tmpdepend
        for i in tools/*.c;do echo -n "tools/";$(CPP) -M $$i;done >> .tmpdepend
        set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i dep; done
-       rm -f tools/version.h
+       rm -f include/linux/version.h
        mv .tmpdepend .depend
 
 ifdef CONFIGURATION
index 83a28bb2b3656b1db1d083a5b4bcda904e999c45..950b592183f16c2673e27c8c296ff0b79a14cb5a 100644 (file)
@@ -1,9 +1,44 @@
+/* boot.S: The initial boot code for the Sparc port of Linux.
+
+   Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
+
+           This file has to serve three purposes.
+
+          1) determine the prom-version and cpu/architecture
+          2) print enough useful info before we start to execute
+             c-code that I can possibly begin to debug things
+          3) Hold the vector of trap entry points
+
+   The Sparc offers many challenges to kernel design. Here I will
+   document those I have come across thus far. Upon bootup the boot
+   prom loads your a.out image into memory. This memory the prom has
+   already mapped for you, however as far as I can tell the virtual
+   adress cache is not turned on although the MMU is translating 
+   things. You get loaded at 0xf8004000 exactly. So, when you link
+   a boot-loadable object you want to do something like:
+
+        ld -e start -T f8004000 -o mykernel myobj1.o myobj2.o ....
+
+   to produce a proper image.
+
+   At boot time you are given (as far as I can tell at this time)
+   one key to figure out what machine you are one and what devices
+   are available. The prom when it loads you leaves a pointer to
+   the 'rom vector' in register %o0 right before it jumps to your
+   starting address. This is a pointer to a struct that is full of
+   pointer to functions (ie. printf, halt, reboot), pointers to
+   linked lists (ie. memory mappings), and pointer to imperical
+   constants (ie. stdin and stdout magic cookies + rom version).
+   Starting with this piece of information you can figure out 
+   just about anything you want about the machine you are on.
+*/
+
 #include "boot.h"
 #include "version.h"
 
        .data
 
-/* First thing to go in the data segment is the interrupt stack */
+/* First thing to go in the data segment is the interrupt stack. */
 
         .globl  _intstack
         .globl  _eintstack
@@ -32,6 +67,12 @@ _cputypvar:
 
 _cputypvallen = _cputypvar - _cputypval
 
+/* This hold the prom-interface-version number for either v0 or v2. */
+
+       .align 4
+       .globl  _prom_iface_vers
+
+_prom_iface_vers:      .skip 4
 
 /* WARNING: evil messages follow */
 
@@ -49,14 +90,10 @@ sun4d_notsup:
         .asciz  "Sparc-Linux: sun4d support does not exist\n\n"
        .align 4
 
-
-/* The following will disappear real soon as the implementation is easy */
-
-v2_prom_notyet:
-       .asciz  "Sparc-Linux: v2 boot-prom support not implemented\n\n"
+you_lose:
+       .asciz  "You lose..... Thanks for playing...\n"
        .align 4
 
-
 /*
    Fill up the prom vector, note in particular the kind first element,
    no joke.
@@ -67,7 +104,7 @@ v2_prom_notyet:
 _prom_vector_p:                .skip 4
 prom_magic:            .skip 4                 ! magic mushroom, beware...
 prom_rom_vers:                 .skip 4                 ! interface version (v0 or v2)
-prom_pluginvers:       .skip 4                 ! XXX help help help
+prom_pluginvers:       .skip 4                 ! XXX help help help ???
 prom_revision:         .skip 4                 ! PROM revision (ie. 1.4)
 prom_bootstr:          .skip 4                 ! what we are invoked with
 prom_putchar:          .skip 4                 ! void putchar(int ch)  BLOCKING.
@@ -82,9 +119,23 @@ prom_v0devfuncs:    .skip 4                 ! V0 device operations
 prom_putstring:                .skip 4                 ! prom putstring()
 prom_bootme:           .skip 4                 ! reset()
 prom_printf:           .skip 4                 ! minimal printf()
+
+/* The prom_abort pointer MUST be mapped in all contexts, because if you
+   don't then if a user process is running when you press the abort key
+   sequence, all sorts of bad things can happen
+*/
+
 prom_abort:            .skip 4                 ! "L1-A" magic cookie
                                                ! must be mapped in ALL contexts
 prom_ticks:            .skip 4                 ! number of ticks since reset
+
+/* prom_sync is a place where the kernel should place a pointer to a kernel
+   function that when called will sync all pending information to the drives
+   and then promptly return. If the kernel gets aborted with 'L1-A' one can
+   give the 'sync' command to the boot prompt and this magic cookie gets
+   executed. Nice feature eh?
+*/
+
 prom_sync:             .skip 4                 ! hook in prom for "sync" func
 prom_v0bootarg:                .skip 4                 ! v0 prom boot arguements
 prom_v2bootarg:                .skip 4                 ! same as above for v2 proms
@@ -100,13 +151,37 @@ prom_stdout:              .skip 4                 ! prom stdout magic cookie
 
        .globl boot_msg
 
-/*
-   This gets forth eval'd, just 'cause I think forth is neat to have in a boot
-   monitor :-) We may not need no steenkin BIOS but we do need the prom!
-*/
+/* memory descriptor property strings, v2 = yuk yuk yuk  */
+/* XXX how to figure out vm mapped by prom? May have to scan magic addresses */
+
+mem_prop_physavail:    .asciz "available"
+mem_prop_phystot:      .asciz "reg"
+
+/* v2_memory descriptor struct kludged here for assembly, if it ain't broke */
+
+               .align 4
+v2_mem_struct:         .skip 0xff
+
+                       .align 4
+v2_printf_physavail:   .asciz "Physical Memory Available: 0x%x bytes"
+v2_printf_phystot:     .asciz "Physical Memory: 0x%x bytes"
+
+/* A place to store property strings returned from the prom 'node' funcs */
+
+                       .align 4
+prop_string_buf:       .skip 32
+
+prop_name:     .asciz "name"
+               .align 4
+
+current_node:  .skip 4
+               .align 4
+
+
+/* nice little boot message */
 
 boot_msg:      
-       .ascii "Booting Sparc-Linux V0.00PRE-ALPHA (SUN4C) "
+       .ascii "Booting Sparc-Linux V0.00PRE-ALPHA "
        .ascii WHO_COMPILED_ME 
        .asciz " \n"
        .align 4
@@ -155,12 +230,42 @@ IE_reg_addr = _msgbuf + msgbufsize      ! this page not used; points to IEreg
    get them in the right place for load time
 */
 
-whereis_bootmsg = boot_msg-KERNBASE
-whereis_kernbase = KERNBASE
+whereis_kernbase      = KERNBASE
 whereis_prom_vector_p = _prom_vector_p-KERNBASE
-whereis_prom_eval = prom_eval-KERNBASE
-whereis_prom_halt = prom_halt-KERNBASE
        
+/* Ok, things start to get interesting. We get linked such that 'start'
+   is the entry symbol. However, it is real low in kernel address space
+   and as such a nifty place to place the trap table. We achieve this goal
+   by just jumping to 'dostart' for the first trap's entry as the sparc
+   never receives the zero trap as it is real special.
+
+   Each trap entry point is the size of 4 sparc instructions (or 4 bytes
+   * 4 insns = 16 bytes). There are 128 hardware traps (some undefined
+   or unimplemented) and 128 software traps (ditto).
+
+   One of the instructions must be a branch. More often than not this
+   will be to a trap handler entry point becuase it is completely
+   impossible to handle any trap in 4 insns. I welcome anyone to 
+   challenge this theory. :-)
+
+   On entry into this table the hardware has loaded the program counter
+   at which the trap occurred into register %l1 and the next program
+   counter into %l2, this way we can return from the trap with a simple
+
+           jmp %l1; rett %l2
+
+   after properly servicing the trap. It wouldn't be a bad idea to load
+   some more information into the local regs since we have technically
+   2 or 3 instructions to play with besides the jmp to the 'real' trap
+   handler (one can even go in the delay slot). For now I am going to put
+   the %psr (processor status register) and the trap-type value in %l0
+   and %l3 respectively.
+
+   TODO: Write cheesy macros to make this table more manageable.
+         Ugh, this shit is long...
+
+*/
+
        .globl  start
        .globl  _trapbase
 start:
@@ -172,51 +277,96 @@ _msgbufmapped:
         .word   1
 
 
-        .data
-        .skip   32                      ! alignment byte & negative indicies
-uwtab:  .skip   32                      ! u_char uwtab[-31..31];
-wmask:  .skip   32                      ! u_char wmask[0..31];
+/* The following two things point to window management tables. The first
+   one is used to quickly look up how many user windows there are from
+   trap-land. The second is used in a trap handler to determine if a rett
+   instruction will land us smack inside the invalid window that possibly
+   the trap was called to fix-up.
+*/
+
+          .data
+          .skip   32                      ! alignment byte & negative indicies
+lnx_uw:       .skip   32                      ! u_char uwtab[-31..31];
+lnx_winmask:  .skip   32                      ! u_char wmask[0..31];
 
         .text
        
-
        
+/* Cool, here we go. Pick up the romvec pointer in %o0 and stash it in
+   %g7 and at _prom_vector_p. And also quickly check whether we are on
+   a v0 or v2 prom.
+*/
+
 dostart:       mov     %o0, %g7
                st      %o0, [_prom_vector_p]   ! we will need it later
                ld      [%g7 + 0x4], %o2
                cmp     %o2, 2                  ! a v2 prom?
-               be      _no_v2_here
+               be      found_v2
                nop
 
+/* Old sun4's pass our load address into %o0 instead of the prom
+   pointer. On sun4's you have to hard code the romvec pointer into
+   your code. Sun probably still does that because they don't even
+   trust their own "OpenBoot" specifications.
+*/
+
                set     0x4000, %g6
                cmp     %o0, %g6                ! an old sun4?
                beq     no_sun4_here
                nop
 
+               st      %g0, [_prom_iface_vers] ! useless, disappear soon
+               b       not_v2
+               nop
+
+found_v2:
+               set     0x2, %o5
+               st      %o5, [_prom_iface_vers]
+
+not_v2:
+
+/* Get the machine type via the mysterious romvec node operations.
+   Here we can find out whether we are on a sun4 sun4c, sun4m, or
+   a sun4m. The "nodes" are set up as a bunch of n-ary trees which
+   you can traverse to get information about devices and such. The
+   information acquisition happens via the node-ops which are defined
+   in the linux_openprom.h header file. Of particular interest is the
+   'nextnode(int node)' function as it does the smart thing when
+   presented with a value of '0', it gives you the first node in the
+   tree. These node integers probably offset into some internal prom
+   pointer table the openboot has. It's completely undocumented, so
+   I'm not about to go sifting through the prom address space, but may
+   do so if I get suspicious enough. :-)
+*/
+
+               mov     0, %o0                  ! next_node(0) = first_node
                ld      [%g7 + 0x1c], %o4
                ld      [%o4], %o4
                call    %o4
-               mov     0, %o0
-               set     _cputypvar, %o1
-               set     _cputypval, %o2
-               ld      [%g7 + 0x1c], %o4
-               ld      [%o4 + 0x0c], %o4
-               call    %o4
                nop
 
+               set     _cputypvar, %o1         ! first node has cpu-arch
+               set     _cputypval, %o2         ! information, the string
+               ld      [%g7 + 0x1c], %o4       ! 'compatability' tells
+               ld      [%o4 + 0x0c], %o4       ! that we want 'sun4x' where
+               call    %o4                     ! x is one of '', 'c', 'm',
+               nop                             ! 'd' or 'e'. %o2 holds pointer
+                                               ! to a buf where above string
+                                               ! will get stored by the prom.
                set     _cputypval, %o2
                ldub    [%o2 + 4], %o0
-               cmp     %o0, 'c'
-               beq     is_sun4c
-               nop
-               cmp     %o0, 'm'
-               beq     no_sun4m_here
-               nop
-               b       no_sun4d_here
+               cmp     %o0, 'c'                ! we already know we are not
+               beq     is_sun4c                ! on a plain sun4 because of
+               nop                             ! the check for 0x4000 in %o0
+               cmp     %o0, 'm'                ! at start:
+               beq     is_sun4m
                nop
+               b       no_sun4d_here           ! god bless the person who
+               nop                             ! tried to run this on sun4d
 
+is_sun4m:
 is_sun4c:                                      ! OK, this is a sun4c, yippie
-               mov     %g7, %g6                ! load up them promvec offsets
+               mov     %g7, %g6                ! load up the promvec offsets
                st      %g6, [prom_magic]       ! magic mushroom :>
                add     %g7, 0x4, %g6
                st      %g6, [prom_rom_vers]
@@ -273,21 +423,29 @@ is_sun4c:                                 ! OK, this is a sun4c, yippie
                add     %g7, 0x104, %g6
                st      %g6, [prom_setcontext]
 
+/* That was easy, now lets try to print some message on the screen.
+   We have to be careful because the prom addressed things weird and
+   we aren't really mapped into memory as far as the rom routines are
+   concerned. So all addresses we have ourselves and would like the
+   prom to actually use must be calculated as (addr - KERNBASE) in order
+   for anything to work at all. We will map ourselves later before we
+   call any c-code to avoid this hassle.
+*/
 
                set     boot_msg-KERNBASE, %o0  
                ld      [prom_printf-KERNBASE], %o2
                ld      [%o2], %o1
                call    %o1                     ! print boot message #1
                nop
-               set     newline-KERNBASE, %o0
+
+_newline:      set     newline-KERNBASE, %o0
                ld      [prom_printf-KERNBASE], %o2
                ld      [%o2], %o1
                call    %o1
                nop
 
                b       0f
-               nop
-
+               nop                             ! damn delay slots...
 
 0:             nop                             ! duh   
                set     pstring1-KERNBASE, %o0
@@ -301,29 +459,45 @@ is_sun4c:                                 ! OK, this is a sun4c, yippie
                set     pstring2-KERNBASE, %o0
                ld      [prom_printf-KERNBASE], %o3
                ld      [%o3], %o2
-               ld      [prom_rom_vers-KERNBASE], %o3
+               ld      [_prom_iface_vers], %o3
                ld      [%o3], %o1
                call    %o2
                nop; nop; nop
 
+/* Print out various bits of memory information. At this point
+   I just cycle through the documented v0_prom memory lists for
+   the values. They are linked lists and allow for description of
+   non-contiguous physical memory configurations, thus the 'memloop'
+   things to traverse the linked lists.
+*/
+
+/* Things are different for v0 and v2. v2 requires traversing the node trees
+   and that really sucks.
+*/
+
+/* Another Note:
+       The prom printf() function can take up to 5 arguements in registers
+       %o1 -- %o5 , the format string goes in %o0. It is your usual libc
+       printf() believe it or not.
+*/
+
+               cmp     %o0, 0x2
+               be      v2_mem_probe
+               nop
+
                set     pstring4-KERNBASE, %o0
                ld      [prom_printf-KERNBASE], %o5
                ld      [%o5], %o4
                ld      [_prom_vector_p], %l1
                ld      [%l1+16], %l2
                ld      [%l2], %l3
-               ld      [%l3 + 8], %o1
+               ld      [%l3 + 8], %o1          ! 'nbytes' memory accumulator
 
-/*
-               ld      [%l1], %l2
-               ld      [%l2 + 0x8], %o1    ! physical memory accumulator
-*/
                ld      [_prom_vector_p], %l1
                ld      [%l1 + 16], %l2
                ld      [%l2], %l3
                ld      [%l3], %l4
 
-/*             ld      [%l3], %l4  */
 memloop:
                cmp     %l4, 0
                be      mv_to_vmprom            ! is there more?
@@ -391,31 +565,98 @@ mv_to_vmprom3:
                b       halt_me
                nop
 
-               .globl _no_v2_here
-_no_v2_here:
-               ld      [%g7 + 0x68], %o1
-               set     v2_prom_notyet-KERNBASE, %o0
-               call    %o1
-               nop
-               b       halt_me
-               nop
-
 no_sun4_here:
                ld      [%g7 + 0x68], %o1
                set     sun4_notsup, %o0
                call    %o1
                nop
-               b       halt_me
+               b       rest_of_boot                    ! next stage...
                nop
 
-no_sun4m_here:
-               ld      [%g7 + 0x68], %o1
-               set     sun4m_notsup, %o0
+v2_mem_probe:
+               set     you_lose-KERNBASE, %o0          ! I just print this
+               ld      [prom_printf-KERNBASE], %o1     ! crap to debug my node
+               ld      [%o1], %o2                      ! routines :-)
+               call    %o2
+               nop
+
+               st      %g0, [current_node]
+               set     prop_string_buf, %o2
+               or      %g0, %g0, %o0
+               ld      [prop_name], %o1
+               or      %g0, 31, %o3            
+
+node_find_loop:
+               ld      [prom_nodefuncs], %o4
+               ld      [%o4 + 0xc], %o4
+               call    %o4
+               nop
+               ld      [prop_string_buf], %l3
+               cmp     %l3, 'm'
+               bne     node_find_loop2
+               ld      [prop_string_buf + 1], %l3
+               cmp     %l3, 'e'
+               bne     node_find_loop2
+               ld      [prop_string_buf + 2], %l3
+               cmp     %l3, 'm'
+               bne     node_find_loop2
+               nop
+               b       found_mem_node
+               nop
+
+node_find_loop2:
+               ld      [current_node], %o0             ! get next node
+               ld      [prom_nodefuncs], %o1
+               ld      [%o1], %o1
                call    %o1
                nop
-               b       halt_me
+               st      %o0, [current_node]
+               set     prop_string_buf, %o2
+               set     prop_name, %o1
+               b       node_find_loop
+               or      %g0, 31, %o3            
+                                               
+found_mem_node:
+               set     v2_mem_struct-KERNBASE, %o2
+               set     0xff, %o3
+               set     mem_prop_physavail-KERNBASE, %o1
+               ld      [current_node], %o0
+               ld      [prom_nodefuncs], %o4
+               ld      [%o4 + 0xc], %o4
+               call    %o4
                nop
 
+               set     v2_printf_physavail-KERNBASE, %o0
+               ld      [v2_mem_struct + 0x8], %o1
+               ld      [prom_printf], %o4
+               ld      [%o4], %o4              
+               call    %o4
+               
+               set     v2_mem_struct-KERNBASE, %o2
+               set     0xff, %o3
+               set     mem_prop_phystot-KERNBASE, %o1
+               ld      [current_node], %o0
+               ld      [prom_nodefuncs], %o4
+               ld      [%o4 + 0xc], %o4
+               call    %o4
+               nop
+
+               set     v2_printf_physavail-KERNBASE, %o0
+               ld      [v2_mem_struct + 0x8], %o1
+               ld      [prom_printf], %o4
+               ld      [%o4], %o4              
+               call    %o4
+               nop
+
+               b       rest_of_boot
+               nop
+
+rest_of_boot:
+               call    halt_me
+               nop                             ! who cares at this point
+
+/* There, happy now adrian? */
+
 no_sun4d_here:
                ld      [%g7 + 0x68], %o1
                set     sun4d_notsup, %o0
@@ -452,3 +693,7 @@ len_loop_end:
                ret
                nop
                
+
+
+
+
diff --git a/arch/sparc/string.S b/arch/sparc/string.S
new file mode 100644 (file)
index 0000000..92692cd
--- /dev/null
@@ -0,0 +1,115 @@
+/*  string.h:  Efficient string functions in sparc-assembly for
+               the linux kernel.
+
+    Copyright 1994 (c) David S. Miller (davem@caip.rutgers.edu)
+*/
+
+
+/* If we are smart we will use only the output and global registers 
+   as that will allow us to avoid a window save which would be nice.
+*/
+
+/* Believe it or not the following strlen is not optimized enough!
+   In the future I may play games with doing word reads and reducing
+   the per-word comparisons to *one*, yes I have seen it done.
+*/
+       .align 4
+       .globl _strlen
+_strlen:
+       mov     %o0, %g3        ! leaf-proceedure optimization, here
+       ldsb    [%g3], %g2      ! I only use the register sent to me
+       cmp     %g2, 0          ! and the globals. Now, this routine
+       be      1f              ! is callable from boot code.
+       nop
+       add     %o0, 1, %o0
+0:     ldsb    [%o0], %g2
+       cmp     %g2, 0
+       bne,a   0b              ! annuling branch, yuck
+       add     %o0, 1, %o0
+
+1:     retl
+       sub     %o0, %g3, %o0   ! since %g3 holds the origional pointer
+                               ! and %o0 is at the end byte, we can
+                               ! subtract and the result is strlen.
+
+/* String concatenate function. I am too lazy to honor the third count
+   arguement at this time. Once again, this could be optimized so much
+   more to use word accesses instead of slooow byte loads.
+*/
+       .align 4
+       .globl _strcat
+_strcat:
+       mov     %o0, %g4
+       ldsb    [%g4], %g3
+       cmp     %g3, 0
+       be,a    2f
+       ldub    [%o1], %g3
+       add     %o0, 1, %o0
+       
+0:     ldsb    [%o0], %g3
+       cmp     %g3, 0
+       bne,a   0b
+       add     %o0, 1, %o0
+
+1:     ldub    [%o1], %g3
+
+2:     add     %o1, 1, %o1
+       stb     %g3, [%o0]
+       cmp     %g3, 0
+       bne     1b
+       add     %o0, 1, %o0
+       retl
+       mov     %g4, %o0
+
+/* Aieee, this code is starting to give me a headache. I shouldn't
+   have tried to do this in one sitting :-(
+*/
+
+       .align 4
+       .globl _strcmp
+_strcmp:       b       2f
+               ldsb    [%o1], %g4
+
+0:             sll     %o2, 24, %g3
+               cmp     %g3, 0
+               bne     1f
+               add     %o0, 1, %o0
+               b       3f
+               or      %g0, %g0, %o0
+
+1:             ldsb    [%o1], %g4
+
+2:             ldsb    [%o0], %g3
+               add     %o1, 1, %o1
+               cmp     %g3, %g4
+               be      0b
+               mov     %g3, %o2
+               ldub    [%o2], %g3
+               ldub    [%o1-1], %o0            ! oh man, no joke
+               sub     %g2, %o0, %o0
+
+3:             retl
+               nop
+
+/* Ok, strcpy() should be easy enough. Maybe I catch some sleep after 
+   this one....
+*/
+       .align 4
+       .globl _strcpy
+_strcpy:       ldub    [%o1], %g3
+               mov     %o0, %g4
+               cmp     %g3, 0
+               be      1f
+               stb     %g3, [%g4]
+
+0:             add     %o1, 1, %o1
+               ldub    [%o1], %g3
+               add     %o0, 1, %o0
+               cmp     %g3, 0
+               bne     0b
+               stb     %g3, [%o0]
+
+1:             retl
+               mov     %g4, %o0
+
+       
\ No newline at end of file
index 7dc0ba4e1ba11ba40938df56cae5fd14cbb535c5..cd5ee08aeedcbe719251e44ff436d71eb6e32079 100644 (file)
@@ -82,8 +82,7 @@
  */
 
 #define CONFIG_FLOPPY_SANITY
-#undef  CONFIG_FLOPPY_23
-#undef  CONFIG_FLOPPY_2_FDC
+#define  CONFIG_FLOPPY_2_FDC
 #undef  CONFIG_FLOPPY_SILENT_DCL_CLEAR
 
 #define REALLY_SLOW_IO
  * motor of these drives causes system hangs on some PCI computers. drive
  * 0 is the low bit (0x1), and drive 7 is the high bit (0x80). Bits are on if
  * a drive is allowed. */
-#ifdef CONFIG_FLOPPY_23
-#define ALLOWED_DRIVE_MASK 0xff
-#else
-#define ALLOWED_DRIVE_MASK 0x33
-#endif
+static int ALLOWED_DRIVE_MASK=0x33;
 
 #define FLOPPY_IRQ 6
 #define FLOPPY_DMA 2
 #define FDC1 0x3f0
-#define FDC2 0x370
+static int FDC2=-1;
 #endif
 
 #define MODULE_AWARE_DRIVER
@@ -236,6 +231,7 @@ static int inr; /* size of reply buffer, when called from interrupt */
 #define R_SECTOR (reply_buffer[5])
 #define R_SIZECODE (reply_buffer[6])
 
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof( (x)[0] ))
 /*
  * this struct defines the different floppy drive types.
  */
@@ -1500,9 +1496,11 @@ void show_floppy(void)
        printk("floppy driver state\n");
        printk("-------------------\n");
        for(i=0; i<N_FDC; i++){
-               printk("dor %d = %x\n", i, fdc_state[i].dor );
-               outb_p(fdc_state[i].address+2, fdc_state[i].dor);
-               udelay(1000); /* maybe we'll catch an interrupt... */
+               if(FDCS->address != -1){
+                       printk("dor %d = %x\n", i, fdc_state[i].dor );
+                       outb_p(fdc_state[i].address+2, fdc_state[i].dor);
+                       udelay(1000); /* maybe we'll catch an interrupt... */
+               }
        }
        printk("status=%x\n", inb_p(FD_STATUS));
        printk("fdc_busy=%d\n", fdc_busy);
@@ -3163,6 +3161,57 @@ static char get_fdc_version(void)
        return FDC_82077;       /* Revised 82077AA passes all the tests */
 } /* get_fdc_version */
 
+#ifndef FD_MODULE
+/* lilo configuration */
+static void invert_dcl(int *ints)
+{
+       int i;
+       
+       for (i=0; i < ARRAY_SIZE(default_drive_params); i++)
+               default_drive_params[i].params.flags |= 0x80;
+       DPRINT("Configuring drives for inverted dcl\n");
+}
+
+static void allow_drives(int *ints)
+{
+       if (ints[1] >= 1 ){
+               ALLOWED_DRIVE_MASK=ints[1];
+               DPRINT1("setting allowed_drive_mask to 0x%x\n", ints[1]);
+       } else
+               DPRINT("allowed_drive_mask needs a parameter\n");
+}
+
+#ifdef  CONFIG_FLOPPY_2_FDC
+static void twofdc(int *ints)
+{
+       FDC2 = 0x370;
+       DPRINT("enabling second fdc at address 0x370\n");
+}
+#endif
+
+static struct param_table {
+       char *name;
+       void (*fn)(int *ints);
+} config_params[]={
+{ "allowed_drive_mask", allow_drives },
+#ifdef  CONFIG_FLOPPY_2_FDC
+{ "two_fdc", twofdc },
+#endif
+{ "thinkpad", invert_dcl } };
+
+void floppy_setup(char *str, int *ints)
+{
+       int i;
+       for(i=0; i< ARRAY_SIZE(config_params); i++){
+               if (strcmp(str,config_params[i].name) == 0 ){
+                       config_params[i].fn(ints);
+                       return;
+               }
+       }
+       printk("unknown floppy paramter %s\n", str);
+}
+#endif
+
 #ifdef FD_MODULE
 static
 #endif
@@ -3230,12 +3279,16 @@ int new_floppy_init(void)
                if (FDCS->address == -1 )
                        continue;
                FDCS->rawcmd = 2;
-               if(user_reset_fdc(-1,FD_RESET_IF_NEEDED,0))
+               if(user_reset_fdc(-1,FD_RESET_IF_NEEDED,0)){
+                       FDCS->address = -1;
                        continue;
+               }
                /* Try to determine the floppy controller type */
                FDCS->version = get_fdc_version();
-               if (FDCS->version == FDC_NONE)
+               if (FDCS->version == FDC_NONE){
+                       FDCS->address = -1;
                        continue;
+               }
 
                have_no_fdc = 0;
                /* Not all FDCs seem to be able to handle the version command
@@ -3272,10 +3325,12 @@ static int floppy_grab_irq_and_dma(void)
 #ifdef FD_MODULE
        MOD_INC_USE_COUNT;
 #endif
-       for(i=0; i< N_FDC; i++){                
-               fdc = i;
-               reset_fdc_info(1);
-               outb_p(FDCS->dor, FD_DOR);
+       for(i=0; i< N_FDC; i++){
+               if(FDCS->address != -1){        
+                       fdc = i;
+                       reset_fdc_info(1);
+                       outb_p(FDCS->dor, FD_DOR);
+               }
        }
        set_dor(0, ~0, 8);  /* avoid immediate interrupt */
 
index dd95f966313909ddab0a3eb6764ab92c2d62c70e..3be1ed87723ad38b4dc41ca74b068233f0e0127b 100644 (file)
@@ -34,7 +34,7 @@ struct lp_struct lp_table[] = {
 
 #ifdef MODULE
 #include <linux/module.h>
-#include "../../tools/version.h"
+#include <linux/version.h>
 #endif
 
 /* 
@@ -467,7 +467,7 @@ long lp_init(long kmem_start)
                if (testvalue == LP_DUMMY) {
                        LP_F(offset) |= LP_EXIST;
                        lp_reset(offset);
-                       printk("lp_init: lp%d exists, ", offset);
+                       printk("lp%d at 0x%04x, ", offset,LP_B(offset));
                        snarf_region(LP_B(offset), 3);
                        if (LP_IRQ(offset))
                                printk("using IRQ%d\n", LP_IRQ(offset));
@@ -505,7 +505,8 @@ int init_module(void)
                if (testvalue == LP_DUMMY) {
                        LP_F(offset) |= LP_EXIST;
                        lp_reset(offset);
-                       printk("lp_init: lp%d exists, ", offset);
+                       printk("lp%d at 0x%04x, ", offset,LP_B(offset));
+                       snarf_region(LP_B(offset),3);
                        if (LP_IRQ(offset))
                                printk("using IRQ%d\n", LP_IRQ(offset));
                        else
@@ -520,10 +521,14 @@ int init_module(void)
 
 void cleanup_module(void)
 {
-       if(MOD_IN_USE)
+        int offset;
+       if(MOD_IN_USE)
                printk("lp: busy - remove delayed\n");
-       else
+        else
                unregister_chrdev(LP_MAJOR,"lp");
+              for (offset = 0; offset < LP_NO; offset++) 
+                       if(LP_F(offset) && LP_EXIST) 
+                               release_region(LP_B(offset),3);
 }
 
 #endif
index c2a0b49628423dce8f2bbe795c2331b9a24c46da..457155ac259574d40ceac492b8cd3a597b6cd640 100644 (file)
@@ -45,7 +45,7 @@ static char *version =
 
 #ifdef MODULE
 #include <linux/module.h>
-#include "../../tools/version.h"
+#include <linux/version.h>
 #endif
 
 extern struct device *init_etherdev(struct device *dev, int sizeof_private,
index 1c90dd37577210a3ea4ad501906c289dfd79e59a..5a91c66c285f8f4ef1555a517cac55feeb1e7203 100644 (file)
@@ -44,7 +44,7 @@ static char *version = "3c509.c:1.03 10/8/94 becker@cesdis.gsfc.nasa.gov\n";
 #include <linux/skbuff.h>
 #ifdef MODULE
 #include <linux/module.h>
-#include "../../tools/version.h"
+#include <linux/version.h>
 #endif
 
 
index e05081be5cca1403f907b92c559083c254b11ca8..69045aef2a96d592fc39a9fe0edd386d7bcdb8e5 100644 (file)
@@ -54,7 +54,7 @@ static char *version =
 
 #ifdef MODULE
 #include <linux/module.h>
-#include "../../tools/version.h"
+#include <linux/version.h>
 #endif
 
 /* These are the operational function interfaces to board-specific
index 6ef0c7d3b1f9402bda9336c48a261921b2be3d67..3f7853ccb0913f395314723423b940b8e88ca6df 100644 (file)
@@ -3,6 +3,7 @@ MODULES = \
        de600.o \
        de620.o \
        3c501.o \
+       apricot.o \
        eexpress.o \
        plip.o \
        8390.o
index 4a82265e58adcd4405cdd09a0fec4beeabeac430..f69395690a8b95e3cd74d6220a9ee17c7a654126 100644 (file)
@@ -28,8 +28,6 @@
 #include <linux/netdevice.h>
 #include <linux/errno.h>
 
-#define LOOPBACK                       /* always present, right?       */
-
 #define        NEXT_DEV        NULL
 
 
@@ -49,6 +47,7 @@ extern int el3_probe(struct device *);
 extern int at1500_probe(struct device *);
 extern int at1700_probe(struct device *);
 extern int depca_probe(struct device *);
+extern int apricot_probe(struct device *);
 extern int ewrk3_probe(struct device *);
 extern int el1_probe(struct device *);
 extern int el16_probe(struct device *);
@@ -112,6 +111,9 @@ ethif_probe(struct device *dev)
 #ifdef CONFIG_EWRK3             /* DEC EtherWORKS 3 */
         && ewrk3_probe(dev)
 #endif
+#ifdef CONFIG_APRICOT          /* Apricot I82596 */
+       && apricot_probe(dev)
+#endif
 #ifdef CONFIG_EL1              /* 3c501 */
        && el1_probe(dev)
 #endif
@@ -289,9 +291,8 @@ static struct device ppp0_dev = {
 #   define     NEXT_DEV        (&dummy_dev)
 #endif
 
-#ifdef LOOPBACK
-    extern int loopback_init(struct device *dev);
-    static struct device loopback_dev = {
+extern int loopback_init(struct device *dev);
+struct device loopback_dev = {
        "lo",                   /* Software Loopback interface          */
        0x0,                    /* recv memory end                      */
        0x0,                    /* recv memory start                    */
@@ -302,10 +303,6 @@ static struct device ppp0_dev = {
        0, 0, 0,                /* flags                                */
        NEXT_DEV,               /* next device                          */
        loopback_init           /* loopback_init should set up the rest */
-    };
-#   undef      NEXT_DEV
-#   define     NEXT_DEV        (&loopback_dev)
-#endif
-
+};
 
-struct device *dev_base = NEXT_DEV;
+struct device *dev_base = &loopback_dev;
index fcf3386e4c60d5353b2ff51bfa76cc23545a5f13..363b2ff442a1caee0e6cdf3062a6436b6a6184a7 100644 (file)
@@ -3,6 +3,8 @@
     Apricot
        Written 1994 by Mark Evans.
        This driver is for the Apricot 82596 bus-master interface
+
+        Modularised 12/94 Mark Evans
     
     Driver skeleton 
        Written 1993 by Donald Becker.
@@ -17,7 +19,7 @@
 
 */
 
-static char *version = "apricot.c:v0.02 19/05/94\n";
+static char *version = "apricot.c:v0.2 05/12/94\n";
 
 #include <linux/config.h>
 #include <linux/kernel.h>
@@ -36,6 +38,11 @@ static char *version = "apricot.c:v0.02 19/05/94\n";
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
+#ifdef MODULE
+#include <linux/module.h>
+#include <linux/version.h>
+#endif
+
 #ifndef HAVE_PORTRESERVE
 #define check_region(addr, size)       0
 #define snarf_region(addr, size)       do ; while(0)
@@ -46,9 +53,6 @@ static char *version = "apricot.c:v0.02 19/05/94\n";
 #define kfree_skbmem(buff, size) kfree_s(buff,size)
 #endif
 
-struct device *init_etherdev(struct device *dev, int sizeof_private,
-                            unsigned long *mem_start);
-
 #define APRICOT_DEBUG 1
 
 #ifdef APRICOT_DEBUG
@@ -59,6 +63,8 @@ int i596_debug = 1;
 
 #define APRICOT_TOTAL_SIZE 17
 
+#define I596_NULL -1
+
 #define CMD_EOL                0x8000  /* The last command of the list, stop. */
 #define CMD_SUSP       0x4000  /* Suspend after doing cmd. */
 #define CMD_INTR       0x2000  /* Interrupt after doing cmd. */
@@ -116,7 +122,7 @@ struct i596_rfd {
     char data[1532];
 };
 
-#define RX_RING_SIZE 16
+#define RX_RING_SIZE 8
 
 struct i596_scb {
     unsigned short status;
@@ -154,7 +160,6 @@ struct i596_private {
     char i596_config[16];
     struct i596_cmd tdr;
     unsigned long stat;
-    struct i596_rfd rx[RX_RING_SIZE];
     int last_restart;
     struct i596_rfd *rx_tail;
     struct i596_cmd *cmd_tail;
@@ -180,8 +185,6 @@ char init_setup[] = {
        0x00,
        0x7f    /*  *multi IA */ };
 
-char adds[] = {0x00, 0x00, 0x49, 0x20, 0x54, 0xDA, 0x80, 0x00, 0x4e, 0x02, 0xb7, 0xb8};
-
 static int i596_open(struct device *dev);
 static int i596_start_xmit(struct sk_buff *skb, struct device *dev);
 static void i596_interrupt(int reg_ptr);
@@ -194,52 +197,59 @@ static void set_multicast_list(struct device *dev, int num_addrs, void *addrs);
 #endif
 
 \f
-static inline void
-init_rx_bufs(struct device *dev)
+static inline int
+init_rx_bufs(struct device *dev, int num)
 {
     struct i596_private *lp = (struct i596_private *)dev->priv;
     int i;
-    int boguscnt = 100;
-    short ioaddr = dev->base_addr;
+    struct i596_rfd *rfd;
+
+    lp->scb.rfd = (struct i596_rfd *)I596_NULL;
 
-    if (i596_debug > 1) printk ("%s: init_rx_bufs.\n", dev->name);
+    if (i596_debug > 1) printk ("%s: init_rx_bufs %d.\n", dev->name, num);
 
-    for (i = 0; i < RX_RING_SIZE; i++)
+    for (i = 0; i < num; i++)
     {
-       if (i == 0)
-       {
-           lp->scb.rfd = &lp->rx[0];
-       }
-       if (i == (RX_RING_SIZE - 1))
-       {
-           lp->rx_tail = &(lp->rx[i]);
-           lp->rx[i].next = &lp->rx[0];
-           lp->rx[i].cmd = CMD_EOL;
-       }
-       else
-       {
-           lp->rx[i].next = &lp->rx[i+1];
-           lp->rx[i].cmd = 0x0000;
-       }
-       lp->rx[i].stat = 0x0000;
-       lp->rx[i].rbd = 0xffffffff;
-       lp->rx[i].count = 0;
-       lp->rx[i].size = 1532;
+       if (!(rfd = (struct i596_rfd *)kmalloc(sizeof(struct i596_rfd), GFP_KERNEL)))
+            break;
+
+       rfd->stat = 0x0000;
+       rfd->rbd = I596_NULL;
+       rfd->count = 0;
+       rfd->size = 1532;
+        if (i == 0)
+        {
+           rfd->cmd = CMD_EOL;
+            lp->rx_tail = rfd;
+        }
+        else
+           rfd->cmd = 0x0000;
+
+        rfd->next = lp->scb.rfd;
+        lp->scb.rfd = rfd;
     }
 
-    while (lp->scb.status, lp->scb.command)
-       if (--boguscnt == 0)
-       {
-           printk("%s: init_rx_bufs timed out with status %4.4x, cmd %4.4x.\n",
-                  dev->name, lp->scb.status, lp->scb.command);
-           break;
-       }
+    if (i != 0)
+      lp->rx_tail->next = lp->scb.rfd;
 
-    lp->scb.command = RX_START;
-    outw(0, ioaddr+4);
+    return (i);
+}
 
-    return;
+static inline void
+remove_rx_bufs(struct device *dev)
+{
+    struct i596_private *lp = (struct i596_private *)dev->priv;
+    struct i596_rfd *rfd = lp->scb.rfd;
 
+    lp->rx_tail->next = (struct i596_rfd *)I596_NULL;
+
+    do
+    {
+        lp->scb.rfd = rfd->next;
+        kfree_s(rfd, sizeof(struct i596_rfd));
+        rfd = lp->scb.rfd;
+    }
+    while (rfd != lp->rx_tail);
 }
 
 static inline void
@@ -256,7 +266,7 @@ init_i596_mem(struct device *dev)
     outw(((((int)&lp->scp) & 0xffff) | 2), ioaddr);
     outw((((int)&lp->scp)>>16) & 0xffff, ioaddr);
 
-    lp->last_cmd=jiffies;
+    lp->last_cmd = jiffies;
 
     lp->scp.sysbus = 0x00440000;
     lp->scp.iscp = &(lp->iscp);
@@ -264,7 +274,7 @@ init_i596_mem(struct device *dev)
     lp->iscp.stat = 0x0001;
     lp->cmd_backlog = 0;
 
-    lp->cmd_head = lp->scb.cmd = (struct i596_cmd *) -1;
+    lp->cmd_head = lp->scb.cmd = (struct i596_cmd *) I596_NULL;
 
     if (i596_debug > 2) printk("%s: starting i82596.\n", dev->name);
 
@@ -280,6 +290,8 @@ init_i596_mem(struct device *dev)
            break;
        }
 
+    lp->scb.command = 0;
+
     memcpy (lp->i596_config, init_setup, 14);
     lp->set_conf.command = CmdConfigure;
     i596_add_cmd(dev, &lp->set_conf);
@@ -291,9 +303,19 @@ init_i596_mem(struct device *dev)
     lp->tdr.command = CmdTDR;
     i596_add_cmd(dev, &lp->tdr);
 
-    init_rx_bufs(dev);
+    boguscnt = 200;
+    while (lp->scb.status, lp->scb.command)
+       if (--boguscnt == 0)
+       {
+           printk("%s: recieve unit start timed out with status %4.4x, cmd %4.4x.\n",
+                  dev->name, lp->scb.status, lp->scb.command);
+           break;
+       }
 
-    boguscnt=200;
+    lp->scb.command = RX_START;
+    outw(0, ioaddr+4);
+
+    boguscnt = 200;
     while (lp->scb.status, lp->scb.command)
         if (--boguscnt == 0)
        {
@@ -309,7 +331,7 @@ static inline int
 i596_rx(struct device *dev)
 {
     struct i596_private *lp = (struct i596_private *)dev->priv;
-    int frames=0;
+    int frames = 0;
 
     if (i596_debug > 3) printk ("i596_rx()\n");
 
@@ -333,7 +355,7 @@ i596_rx(struct device *dev)
            }
 
            skb->len = pkt_len;
-           skb->dev=dev;               
+           skb->dev = dev;             
            memcpy(skb->data, lp->scb.rfd->data, pkt_len);
 
            netif_rx(skb);
@@ -353,12 +375,12 @@ i596_rx(struct device *dev)
            if ((lp->scb.rfd->stat) & 0x1000) lp->stats.rx_length_errors++;
        }
 
-       lp->scb.rfd->stat=0;
-       lp->rx_tail->cmd=0;
-       lp->rx_tail=lp->scb.rfd;
-       lp->scb.rfd=lp->scb.rfd->next;
-       lp->rx_tail->count=0;
-       lp->rx_tail->cmd=CMD_EOL;
+       lp->scb.rfd->stat = 0;
+       lp->rx_tail->cmd = 0;
+       lp->rx_tail = lp->scb.rfd;
+       lp->scb.rfd = lp->scb.rfd->next;
+       lp->rx_tail->count = 0;
+       lp->rx_tail->cmd = CMD_EOL;
 
     }
 
@@ -375,7 +397,7 @@ i596_cleanup_cmd(struct i596_private *lp)
 
     if (i596_debug > 4) printk ("i596_cleanup_cmd\n");
 
-    while (lp->cmd_head != (struct i596_cmd *) -1)
+    while (lp->cmd_head != (struct i596_cmd *) I596_NULL)
     {
        ptr = lp->cmd_head;
 
@@ -394,7 +416,7 @@ i596_cleanup_cmd(struct i596_private *lp)
                lp->stats.tx_errors++;
                lp->stats.tx_aborted_errors++;
 
-               ptr->next = (struct i596_cmd * ) -1;
+               ptr->next = (struct i596_cmd * ) I596_NULL;
                kfree_s((unsigned char *)tx_cmd, (sizeof (struct tx_cmd) + sizeof (struct i596_tbd)));
                break;
            }
@@ -402,12 +424,12 @@ i596_cleanup_cmd(struct i596_private *lp)
            {
                unsigned short count = *((unsigned short *) (ptr + 1));
 
-               ptr->next = (struct i596_cmd * ) -1;
+               ptr->next = (struct i596_cmd * ) I596_NULL;
                kfree_s((unsigned char *)ptr, (sizeof (struct i596_cmd) + count + 2));
                break;
            }
            default:
-               ptr->next = (struct i596_cmd * ) -1;
+               ptr->next = (struct i596_cmd * ) I596_NULL;
        }
     }
 
@@ -437,10 +459,10 @@ i596_reset(struct device *dev, struct i596_private *lp, int ioaddr)
            break;
        }
 
-    dev->start=0;
-    dev->tbusy=1;
+    dev->start = 0;
+    dev->tbusy = 1;
 
-    lp->scb.command=CUC_ABORT|RX_ABORT;
+    lp->scb.command = CUC_ABORT|RX_ABORT;
     outw(0, ioaddr+4);
 
     /* wait for shutdown */
@@ -457,9 +479,9 @@ i596_reset(struct device *dev, struct i596_private *lp, int ioaddr)
     i596_cleanup_cmd(lp);
     i596_rx(dev);
 
-    dev->start=1;
-    dev->tbusy=0;
-    dev->interrupt=0;
+    dev->start = 1;
+    dev->tbusy = 0;
+    dev->interrupt = 0;
     init_i596_mem(dev);
 }
 
@@ -474,15 +496,15 @@ static void i596_add_cmd(struct device *dev, struct i596_cmd *cmd)
 
     cmd->status = 0;
     cmd->command |= (CMD_EOL|CMD_INTR);
-    cmd->next = (struct i596_cmd *) -1;
+    cmd->next = (struct i596_cmd *) I596_NULL;
 
     save_flags(flags);
     cli();
-    if (lp->cmd_head != (struct i596_cmd *) -1)
+    if (lp->cmd_head != (struct i596_cmd *) I596_NULL)
        lp->cmd_tail->next = cmd;
     else 
     {
-       lp->cmd_head=cmd;
+       lp->cmd_head = cmd;
        while (lp->scb.status, lp->scb.command)
            if (--boguscnt == 0)
            {
@@ -495,10 +517,10 @@ static void i596_add_cmd(struct device *dev, struct i596_cmd *cmd)
        lp->scb.command = CUC_START;
         outw (0, ioaddr+4);
     }
-    lp->cmd_tail=cmd;
+    lp->cmd_tail = cmd;
     lp->cmd_backlog++;
 
-    lp->cmd_head=lp->scb.cmd;
+    lp->cmd_head = lp->scb.cmd;
     restore_flags(flags);
 
     if (lp->cmd_backlog > 16) 
@@ -516,19 +538,34 @@ static void i596_add_cmd(struct device *dev, struct i596_cmd *cmd)
 static int
 i596_open(struct device *dev)
 {
-    if (request_irq(dev->irq, &i596_interrupt, 0, "apricot")) {
+    int i;
+
+    if (i596_debug > 1)
+       printk("%s: i596_open() irq %d.\n", dev->name, dev->irq);
+
+    if (request_irq(dev->irq, &i596_interrupt, 0, "apricot"))
        return -EAGAIN;
-    }
 
     irq2dev_map[dev->irq] = dev;
 
-    if (i596_debug > 1)
-       printk("%s: i596_open() irq %d.\n",
-              dev->name, dev->irq);
+     i = init_rx_bufs(dev, RX_RING_SIZE);
+
+    if ((i = init_rx_bufs(dev, RX_RING_SIZE)) < RX_RING_SIZE)
+        printk("%s: only able to allocate %d receive buffers\n", dev->name, i);
+
+    if (i < 4)
+    {
+        free_irq(dev->irq);
+        irq2dev_map[dev->irq] = 0;
+        return -EAGAIN;
+    }
 
     dev->tbusy = 0;
     dev->interrupt = 0;
     dev->start = 1;
+#ifdef MODULE
+    MOD_INC_USE_COUNT;
+#endif
 
     /* Initialize the 82596 memory */
     init_i596_mem(dev);
@@ -563,7 +600,7 @@ i596_start_xmit(struct sk_buff *skb, struct device *dev)
            /* Issue a channel attention signal */
            if (i596_debug > 1) printk ("Kicking board.\n");
 
-           lp->scb.command=CUC_START|RX_START;
+           lp->scb.command = CUC_START|RX_START;
            outw(0, ioaddr+4);
 
            lp->last_restart = lp->stats.tx_packets;
@@ -592,7 +629,7 @@ i596_start_xmit(struct sk_buff *skb, struct device *dev)
     else
     {
        short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-       dev->trans_start=jiffies;
+       dev->trans_start = jiffies;
 
        tx_cmd = (struct tx_cmd *) kmalloc ((sizeof (struct tx_cmd) + sizeof (struct i596_tbd)), GFP_ATOMIC);
        if (tx_cmd == NULL)
@@ -605,7 +642,7 @@ i596_start_xmit(struct sk_buff *skb, struct device *dev)
        else
        {
            tx_cmd->tbd = (struct i596_tbd *) (tx_cmd + 1);
-           tx_cmd->tbd->next = (struct i596_tbd *) -1;
+           tx_cmd->tbd->next = (struct i596_tbd *) I596_NULL;
 
            tx_cmd->cmd.command = CMD_FLEX|CmdTx;
 
@@ -646,10 +683,10 @@ static void print_eth(char *add)
     printk ("type %2.2X%2.2X\n", (unsigned char)add[12], (unsigned char)add[13]);
 }
 
-unsigned long apricot_init(unsigned long mem_start, unsigned long mem_end)
+int apricot_probe(struct device *dev)
 {
-    struct device *dev;
     int i;
+    struct i596_private *lp;
     int checksum = 0;
     int ioaddr = 0x300;
     char eth_addr[6];
@@ -658,28 +695,30 @@ unsigned long apricot_init(unsigned long mem_start, unsigned long mem_end)
     /* first check nothing is already registered here */
 
     if (check_region(ioaddr, APRICOT_TOTAL_SIZE))
-       return mem_start;
+       return ENODEV;
 
     for (i = 0; i < 8; i++)
-       checksum += inb(ioaddr + 8 + i);
+    {
+       eth_addr[i] = inb(ioaddr+8+i);
+       checksum += eth_addr[i];
+     }
 
     /* checksum is a multiple of 0x100, got this wrong first time
        some machines have 0x100, some 0x200. The DOS driver doesn't
        even bother with the checksum */
 
-    if (checksum % 0x100) return mem_start;
-
+    if (checksum % 0x100) return ENODEV;
 
-    for(i = 0; i < 6 ; i++)
-       eth_addr[i] = inb(ioaddr +8 +i);
-    
     /* Some other boards trip the checksum.. but then appear as ether
        address 0. Trap these - AC */
        
-    if(memcmp(eth_addr,"\x00\x00\x00\x00\x00\x00",6)==0)
-       return mem_start;
+    if(memcmp(eth_addr,"\x00\x00\x49",3)!= 0)
+       return ENODEV;
+
+    snarf_region(ioaddr, APRICOT_TOTAL_SIZE);
 
-    dev = init_etherdev(0, (sizeof (struct i596_private) + 0xf), &mem_start);
+    dev->base_addr = ioaddr;
+    ether_setup(dev);
     printk("%s: Apricot 82596 at %#3x,", dev->name, ioaddr);
 
     for (i = 0; i < 6; i++)
@@ -689,10 +728,7 @@ unsigned long apricot_init(unsigned long mem_start, unsigned long mem_end)
     dev->irq = 10;
     printk(" IRQ %d.\n", dev->irq);
 
-    snarf_region(ioaddr, APRICOT_TOTAL_SIZE);
-
-    if (i596_debug > 0)
-       printk(version);
+    if (i596_debug > 0) printk(version);
 
     /* The APRICOT-specific entries in the device structure. */
     dev->open = &i596_open;
@@ -703,10 +739,16 @@ unsigned long apricot_init(unsigned long mem_start, unsigned long mem_end)
     dev->set_multicast_list = &set_multicast_list;
 #endif
 
+    dev->mem_start = (int)kmalloc(sizeof(struct i596_private)+ 0x0f, GFP_KERNEL);
     /* align for scp */
-    dev->priv = (void *)(((int) dev->priv + 0xf) & 0xfffffff0);
+    dev->priv = (void *)((dev->mem_start + 0xf) & 0xfffffff0);
 
-    return mem_start;
+    lp = (struct i596_private *)dev->priv;
+    lp->scb.command = 0;
+    lp->scb.cmd = (struct i596_cmd *) I596_NULL;
+    lp->scb.rfd = (struct i596_rfd *)I596_NULL;
+
+    return 0;
 }
 
 static void
@@ -717,7 +759,7 @@ i596_interrupt(int reg_ptr)
     struct i596_private *lp;
     short ioaddr;
     int boguscnt = 200;
-    unsigned short status, ack_cmd=0;
+    unsigned short status, ack_cmd = 0;
 
     if (dev == NULL) {
        printk ("i596_interrupt(): irq %d for unknown device.\n", irq);
@@ -757,7 +799,7 @@ i596_interrupt(int reg_ptr)
        if ((i596_debug > 4) && (status & 0x2000))
            printk("%s: i596 interrupt command unit inactive %x.\n", dev->name, status & 0x0700);
 
-       while ((lp->cmd_head != (struct i596_cmd *) -1) && (lp->cmd_head->status & STAT_C))
+       while ((lp->cmd_head != (struct i596_cmd *) I596_NULL) && (lp->cmd_head->status & STAT_C))
        {
            ptr = lp->cmd_head;
 
@@ -788,7 +830,7 @@ i596_interrupt(int reg_ptr)
                    }
 
 
-                   ptr->next = (struct i596_cmd * ) -1;
+                   ptr->next = (struct i596_cmd * ) I596_NULL;
                    kfree_s((unsigned char *)tx_cmd, (sizeof (struct tx_cmd) + sizeof (struct i596_tbd)));
                    break;
                }
@@ -796,7 +838,7 @@ i596_interrupt(int reg_ptr)
                {
                    unsigned short count = *((unsigned short *) (ptr + 1));
 
-                   ptr->next = (struct i596_cmd * ) -1;
+                   ptr->next = (struct i596_cmd * ) I596_NULL;
                    kfree_s((unsigned char *)ptr, (sizeof (struct i596_cmd) + count + 2));
                    break;
                }
@@ -822,20 +864,20 @@ i596_interrupt(int reg_ptr)
                    }
                }
                default:
-                   ptr->next = (struct i596_cmd * ) -1;
+                   ptr->next = (struct i596_cmd * ) I596_NULL;
 
-               lp->last_cmd=jiffies;
+               lp->last_cmd = jiffies;
            }
        }
 
        ptr = lp->cmd_head;
-       while ((ptr != (struct i596_cmd *) -1) && (ptr != lp->cmd_tail))
+       while ((ptr != (struct i596_cmd *) I596_NULL) && (ptr != lp->cmd_tail))
        {
            ptr->command &= 0x1fff;
            ptr = ptr->next;
        }
 
-       if ((lp->cmd_head != (struct i596_cmd *) -1) && (dev->start)) ack_cmd |= CUC_START;
+       if ((lp->cmd_head != (struct i596_cmd *) I596_NULL) && (dev->start)) ack_cmd |= CUC_START;
        lp->scb.cmd = lp->cmd_head;
     }
 
@@ -854,7 +896,7 @@ i596_interrupt(int reg_ptr)
     /* acknowledge the interrupt */
 
 /*
-    if ((lp->scb.cmd != (struct i596_cmd *) -1) && (dev->start)) ack_cmd |= CUC_START;
+    if ((lp->scb.cmd != (struct i596_cmd *) I596_NULL) && (dev->start)) ack_cmd | = CUC_START;
 */
     boguscnt = 100;
     while (lp->scb.status, lp->scb.command)
@@ -881,6 +923,7 @@ i596_close(struct device *dev)
 {
     int ioaddr = dev->base_addr;
     struct i596_private *lp = (struct i596_private *)dev->priv;
+    int boguscnt = 200;
 
     dev->start = 0;
     dev->tbusy = 1;
@@ -894,8 +937,20 @@ i596_close(struct device *dev)
 
     i596_cleanup_cmd(lp);
 
+    while (lp->scb.status, lp->scb.command)
+       if (--boguscnt == 0)
+       {
+           printk("%s: close timed timed out with status %4.4x, cmd %4.4x.\n",
+                  dev->name, lp->scb.status, lp->scb.command);
+           break;
+       }
     free_irq(dev->irq);
     irq2dev_map[dev->irq] = 0;
+    remove_rx_bufs(dev);
+#ifdef MODULE
+    MOD_DEC_USE_COUNT;
+#endif
+
 
     return 0;
 }
@@ -940,7 +995,7 @@ set_multicast_list(struct device *dev, int num_addrs, void *addrs)
            i596_add_cmd(dev, cmd);
     } else
     {
-       if (lp->set_conf.next != (struct i596_cmd * ) -1) return;
+       if (lp->set_conf.next != (struct i596_cmd * ) I596_NULL) return;
        if (num_addrs == 0)
            lp->i596_config[8] &= ~0x01;
        else
@@ -954,9 +1009,39 @@ set_multicast_list(struct device *dev, int num_addrs, void *addrs)
 
 #ifdef HAVE_DEVLIST
 static unsigned int apricot_portlist[] = {0x300, 0};
-struct netdev_entry apricot_drv =
-{"apricot", apricot_init, APRICOT_TOTAL_SIZE, apricot_portlist};
+struct netdev_entry apricot_drv = 
+{"apricot", apricot_probe, APRICOT_TOTAL_SIZE, apricot_portlist};
 #endif
+
+#ifdef MODULE
+char kernel_version[] = UTS_RELEASE;
+static struct device dev_apricot = {
+  "        ", /* device name inservted by /linux/drivers/net/net_init.c */
+  0, 0, 0, 0,
+  0x300, 10,
+  0, 0, 0, NULL, apricot_probe };
+
+int
+init_module(void)
+{
+  if (register_netdev(&dev_apricot) != 0)
+    return -EIO;
+  return 0;
+}
+
+void
+cleanup_module(void)
+{
+  if (MOD_IN_USE)
+    printk("%s: device busy, remove delayed\n", dev_apricot.name);
+  else
+  {
+    unregister_netdev(&dev_apricot);
+    kfree_s((void *)dev_apricot.mem_start, sizeof(struct i596_private) + 0xf);
+    dev_apricot.priv = NULL;
+  }
+}
+#endif /* MODULE */
 \f
 /*
  * Local variables:
index 4cd21582d5b3ff0318d90b1db918d960880d16fb..61b73b46032503c3b9ab1f6f4a074dab09d7194a 100644 (file)
@@ -110,7 +110,7 @@ unsigned int de600_debug = DE600_DEBUG;
 
 #ifdef MODULE
 #include <linux/module.h>
-#include "../../tools/version.h"
+#include <linux/version.h>
 #endif
 
 #ifdef FAKE_SMALL_MAX
index e3cb9a307f5a3e7a882f65accd6019a432beda1f..7f6cf36d349d53f3b474ae28927fcb263b81c7ba 100644 (file)
@@ -121,7 +121,7 @@ static char *version =
 
 #ifdef MODULE
 #include <linux/module.h>
-#include "../../tools/version.h"
+#include <linux/version.h>
 #endif
 
 /* Constant definitions for the DE-620 registers, commands and bits */
index fcb8f86afa057bb8cc313786b35095deb4eb6a87..822ea4b624da228578d07543aadcff85070eeb1f 100644 (file)
@@ -188,7 +188,7 @@ static char *version = "depca.c:v0.38 8/15/94 davies@wanton.lkg.dec.com\n";
 
 #ifdef MODULE
 #include <linux/module.h>
-#include "/linux/tools/version.h"
+#include <linux/version.h>
 #endif /* MODULE */
 
 #include "depca.h"
index d02b8ad3e1747836b47a8ddf92c0f18fff5223ce..4ff157cc92b506961d336f84e41b6bbc6cd8714b 100644 (file)
@@ -57,7 +57,7 @@ static char *version =
 #include <linux/skbuff.h>
 #ifdef MODULE
 #include <linux/module.h>
-#include "../../tools/version.h"
+#include <linux/version.h>
 #endif
 
 #include <linux/malloc.h>
index 0442249d586d24b0e8979a07490a67814d2c030f..527eccdac7b9bf615c38030eb23b732aa24dbc5e 100644 (file)
@@ -149,7 +149,7 @@ static char *version = "ewrk3.c:v0.30 11/1/94 davies@wanton.lkg.dec.com\n";
 
 #ifdef MODULE
 #include <linux/module.h>
-#include "/linux/tools/version.h"
+#include <linux/version.h>
 #endif /* MODULE */
 
 #include "ewrk3.h"
index 61946fbdfea63e450ffa66a7c9881e397af782f2..123f893240a4b1e866a234dd381920aa19128e43 100644 (file)
@@ -67,9 +67,6 @@ unsigned long net_dev_init (unsigned long mem_start, unsigned long mem_end)
 #endif
 #if defined(CONFIG_PI)
        mem_start = pi_init(mem_start, mem_end);
-#endif 
-#if defined(CONFIG_APRICOT)
-       mem_start = apricot_init(mem_start, mem_end);
 #endif 
        return mem_start;
 }
index 577f1ed48329cce82450962c131697449e50d802..5a239a64c358d2772c45235afebaf0e04e7c7a0c 100644 (file)
@@ -92,7 +92,7 @@ make one yourself.  The wiring is:
 
 #ifdef MODULE
 #include <linux/module.h>
-#include "../../tools/version.h"
+#include <linux/version.h>
 #endif
 
 /* use 0 for production, 1 for verification, >2 for debug */
index 21df8831f08f260315282a9a8db47a01e48de49d..e20a4504ecb3b278ca3bd1f967f28b0a6f43b397 100644 (file)
@@ -548,18 +548,15 @@ static void znet_rx(struct device *dev)
                        lp->stats.rx_length_errors++;
                } else {
                        /* Malloc up new buffer. */
-                       int sksize = sizeof(struct sk_buff) + pkt_len;
                        struct sk_buff *skb;
 
-                       skb = alloc_skb(sksize, GFP_ATOMIC);
+                       skb = alloc_skb(pkt_len, GFP_ATOMIC);
                        if (skb == NULL) {
                                if (znet_debug)
                                  printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
                                lp->stats.rx_dropped++;
                                break;
                        }
-                       skb->mem_len = sksize;
-                       skb->mem_addr = skb;
                        skb->len = pkt_len;
                        skb->dev = dev;
 
index 71c0ffaf13d436b96023ee8ef22e6624184b60ba..87e02fcdaa9bb700cbc1505d2f9e78049d7e6cce 100644 (file)
@@ -58,6 +58,7 @@ struct scsi_generic
  };
 
 static struct scsi_generic *scsi_generics=NULL;
+static void sg_free(char *buff,int size);
 
 static int sg_ioctl(struct inode * inode,struct file * file,
             unsigned int cmd_in, unsigned long arg)
@@ -109,7 +110,7 @@ static int sg_open(struct inode * inode, struct file * filp)
   if (!scsi_generics[dev].users && scsi_generics[dev].pending && scsi_generics[dev].complete)
    {
     if (scsi_generics[dev].buff != NULL)
-      scsi_free(scsi_generics[dev].buff,scsi_generics[dev].buff_len);
+      sg_free(scsi_generics[dev].buff,scsi_generics[dev].buff_len);
     scsi_generics[dev].buff=NULL;
     scsi_generics[dev].pending=0;
    }
index 77a9dc4b6e7868f0661541021fcc7b5ad9e277af..13a45cc987340c46592a3d44e1324cf4d8426399 100644 (file)
@@ -29,7 +29,7 @@
 
 #ifndef CONFIG_BINFMT_ELF
 #include <linux/module.h>
-#include "../tools/version.h"
+#include <linux/version.h>
 #endif
 
 #include <linux/unistd.h>
index 6666d8acfe0f3295bb4af1c16d28eb8a93a51736..89853271d56032e48b381b3ffc638ab00371c45e 100644 (file)
@@ -22,7 +22,7 @@
 
 #ifdef MODULE
 #include <linux/module.h>
-#include "../../tools/version.h"
+#include <linux/version.h>
 #endif
 
 #ifdef LEAK_CHECK
index e0577fbef723308ed20dbbc789b448dd94a242b8..d8de491bdbc1990b377a18c067232d4f6b92add3 100644 (file)
@@ -17,7 +17,7 @@
 
 #ifdef MODULE
        #include <linux/module.h>
-       #include "../../tools/version.h"
+       #include <linux/version.h>
 #endif
 
 #include <asm/segment.h>
index dba55e072df6b3e8f44b7b6c31c8c66c79409b38..b1ae4d84c2aab6a46ad1ec7e39456425999caf05 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/string.h>
 #include <linux/mman.h>
 #include <linux/proc_fs.h>
+#include <linux/ioport.h>
 
 #include <asm/segment.h>
 #include <asm/io.h>
@@ -529,6 +530,8 @@ static int get_root_array(char * page, int type)
                case PROC_DMA:
                        return get_dma_list(page);
 
+               case PROC_IOPORTS:
+                       return get_ioport_list(page);
        }
        return -EBADF;
 }
index 9dbddab7f9e366f0b3962bdf9656c5e3344d5a7b..bd4280a500eb8efc48cd3916771e404ea67fed1c 100644 (file)
@@ -73,6 +73,7 @@ static struct proc_dir_entry root_dir[] = {
        { PROC_FILESYSTEMS,     11,"filesystems" },
        { PROC_KSYMS,           5, "ksyms" },
        { PROC_DMA,             3, "dma" },
+       { PROC_IOPORTS,         7, "ioports"},
 };
 
 #define NR_ROOT_DIRENTRY ((sizeof (root_dir))/(sizeof (root_dir[0])))
index 331b479d7d2922230d4d7528458ea5dee96cea3f..ec1695981bbb6cbb9201498e8acb111c11f21e51 100644 (file)
@@ -32,7 +32,7 @@
 
 #ifdef MODULE
 #include <linux/module.h>
-#include "../../tools/version.h"
+#include <linux/version.h>
 #else
 #define MOD_INC_USE_COUNT
 #define MOD_DEC_USE_COUNT
index 40f7feb68b1554c14c610c4cb7230db53c4f89d1..aa01c3d58e817a50cb60fc441d0f8898faed5e8c 100644 (file)
@@ -19,7 +19,7 @@
 
 #ifdef MODULE
        #include <linux/module.h>
-       #include "../../tools/version.h"
+       #include <linux/version.h>
 #endif
 
 struct inode *pseudo_root=NULL;                /* Useful to simulate the pseudo DOS */
index 7cb799aa47462738189ef564b4ce86abf829ef42..572f8469cb393465a367958e4ca092d946b35786 100644 (file)
@@ -21,7 +21,7 @@
 
 #ifdef MODULE
 #include <linux/module.h>
-#include "../../tools/version.h"
+#include <linux/version.h>
 #else
 #define MOD_INC_USE_COUNT
 #define MOD_DEC_USE_COUNT
index e12764f941844bf84426b71c2b9e8e7b9eb867a5..e9050a5eca7cfe42c1492b4a1e0633ba6050456c 100644 (file)
@@ -15,7 +15,7 @@
 #ifndef _M68K_SYSTEM_H
 #define _M68K_SYSTEM_H
 
-#include <linux/autoconf.h> /* get configuration makros */
+#include <linux/autoconf.h> /* get configuration macros */
 
 #if defined(CONFIG_ATARI) && !defined(CONFIG_AMIGA) && !defined(CONFIG_MAC)
 /* block out HSYNC on the atari */
index 42ec48cf8aa8963aff7898be77f4026e115846c8..da1811d82d5ea1f64f55cca3165fb8a85c7d2f5a 100644 (file)
@@ -127,6 +127,7 @@ struct floppy_drive_params {
 #define FD_BROKEN_DCL 0x20
 #define FD_DEBUG 0x02
 #define FD_SILENT_DCL_CLEAR 0x4
+#define FD_INVERTED_DCL 0x80
 
   char read_track;             /* use readtrack during probing? */
 
index e5923f6ed5a2133abf9bea6efc1f7a3ef348a3f2..fdbbdf062f3537a8bafbe5c7c5364032212d5211 100644 (file)
@@ -20,6 +20,7 @@ extern void reserve_setup(char *str, int *ints);
 extern int check_region(unsigned int from, unsigned int extent);
 extern void snarf_region(unsigned int from, unsigned int extent);
 extern void release_region(unsigned int from, unsigned int extent);
+extern int get_ioport_list(char *);
 
 
 #define HAVE_AUTOIRQ
index f12701e70aebd8bd0deafe053c1714696cb4d91e..743b360fdf9799d6462bd9b46f110b963d1622ed 100644 (file)
@@ -180,6 +180,7 @@ struct packet_type {
 
 extern volatile char in_bh;
 
+extern struct device   loopback_dev;
 extern struct device   *dev_base;
 extern struct packet_type *ptype_base;
 
index 5260a3b0fa4067f6f02319214c670c14d89440c7..bca8dbba835ee1ce92e24dc630e4404bc07c6637 100644 (file)
@@ -25,7 +25,8 @@ enum root_directory_inos {
        PROC_INTERRUPTS,
        PROC_FILESYSTEMS,
        PROC_KSYMS,
-       PROC_DMA
+       PROC_DMA,       
+       PROC_IOPORTS
 };
 
 enum pid_directory_inos {
index 649900e48fecf499fbd424f57e16b5e3f4f93a37..deb934d4b3f725b215638e016a237a1dc833fc5f 100644 (file)
@@ -84,6 +84,7 @@ extern void hd_setup(char *str, int *ints);
 extern void bmouse_setup(char *str, int *ints);
 extern void eth_setup(char *str, int *ints);
 extern void xd_setup(char *str, int *ints);
+extern void floppy_setup(char *str, int *ints);
 extern void mcd_setup(char *str, int *ints);
 extern void st_setup(char *str, int *ints);
 extern void st0x_setup(char *str, int *ints);
@@ -221,6 +222,9 @@ struct {
 #ifdef CONFIG_BLK_DEV_XD
        { "xd=", xd_setup },
 #endif
+#ifdef CONFIG_BLK_DEV_FD
+       { "floppy=", floppy_setup },
+#endif
 #ifdef CONFIG_MCD
        { "mcd=", mcd_setup },
 #endif
index c61690e3c71b7b3341456ed17462fe55b3e939fd..5cb1bff384e8b27e7f0bc6e595d604b6d965b9c4 100644 (file)
@@ -108,6 +108,26 @@ asmlinkage int check_bitmap(unsigned long *bitmap, short base, short extent)
        return 0;
 }
 
+int get_ioport_list(char *buf)
+{       int len=0,num,from;
+        for(num=0;num<IO_BITMAP_SIZE*32;num++)
+         if(check_bitmap(ioport_registrar,num,1)) {
+          from=num;
+          while(check_bitmap(ioport_registrar,num+1,1) 
+                       && num+1<IO_BITMAP_SIZE*32 )
+               num++;
+          if(from==num) 
+            len+=sprintf(buf+len,"%04x\n",num);
+          else
+           len+=sprintf(buf+len,"%04x-%04x\n",from,num);
+           if(len>4000) {
+                len+=sprintf((buf+len),"4k-Limit reached!\n");
+                return len;
+           }
+         }
+        return len;
+}
+
 /*
  * this changes the io permissions bitmap in the current task.
  */
index da73dc0e0caa5902bc04d461cafb330e556dedc3..c499cd229d5bf54e7e524d05cc6ac17490224fda 100644 (file)
@@ -76,6 +76,7 @@ struct symbol_table symbol_table = { 0, 0, 0, /* for stacked module support */
 
 #ifdef CONFIG_PCI
        /* PCI BIOS support */
+       X(pcibios_present),
        X(pcibios_find_class),
        X(pcibios_find_device),
        X(pcibios_read_config_byte),
@@ -235,6 +236,7 @@ struct symbol_table symbol_table = { 0, 0, 0, /* for stacked module support */
        X(ftape_big_buffer),
        X(do_floppy),
 #endif
+       X(floppy_track_buffer),
 #ifdef CONFIG_INET
        /* support for loadable net drivers */
        X(register_netdev),
@@ -244,6 +246,7 @@ struct symbol_table symbol_table = { 0, 0, 0, /* for stacked module support */
        X(kfree_skb),
        X(dev_kfree_skb),
        X(snarf_region),
+       X(release_region),
        X(netif_rx),
        X(dev_rint),
        X(dev_tint),
index c829d2bbcdacbc7f5dea05b669b6db77b1c93cd2..af1d9b3078d98d170dfc68b3995c767c5ae1bf72 100644 (file)
@@ -213,8 +213,13 @@ int generic_mmap(struct inode * inode, struct file * file, struct vm_area_struct
                return -ENOEXEC;
        ops = &file_private_mmap;
        if (vma->vm_flags & VM_SHARED) {
-               if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE))
+               if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) {
+                       static int nr = 0;
                        ops = &file_shared_mmap;
+                       if (nr++ < 5)
+                               printk("%s tried to do a shared writeable mapping\n", current->comm);
+                       return -EINVAL;
+               }
        }
        if (!IS_RDONLY(inode)) {
                inode->i_atime = CURRENT_TIME;
index fe110fca166877bf9ca80cde9d78fef8b4e67845..1e11edf1db74bbf9dbb15160e3d84b19856cf896 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -804,6 +804,7 @@ asmlinkage int sys_swapoff(const char * specialfile)
        struct swap_info_struct * p;
        struct inode * inode;
        unsigned int type;
+       struct file filp;
        int i;
 
        if (!suser())
@@ -825,15 +826,32 @@ asmlinkage int sys_swapoff(const char * specialfile)
                                break;
                }
        }
-       iput(inode);
-       if (type >= nr_swapfiles)
+
+       if (type >= nr_swapfiles){
+               iput(inode);
                return -EINVAL;
+       }
        p->flags = SWP_USED;
        i = try_to_unuse(type);
        if (i) {
+               iput(inode);
                p->flags = SWP_WRITEOK;
                return i;
        }
+
+       if(p->swap_device){
+               memset(&filp, 0, sizeof(filp));         
+               filp.f_inode = inode;
+               filp.f_mode = 3; /* read write */
+               /* open it again to get fops */
+               if( !blkdev_open(inode, &filp) &&
+                  filp.f_op && filp.f_op->release){
+                       filp.f_op->release(inode,&filp);
+                       filp.f_op->release(inode,&filp);
+               }
+       }
+       iput(inode);
+
        nr_swap_pages -= p->pages;
        iput(p->swap_file);
        p->swap_file = NULL;
@@ -858,7 +876,9 @@ asmlinkage int sys_swapon(const char * specialfile)
        unsigned int type;
        int i,j;
        int error;
+       struct file filp;
 
+       memset(&filp, 0, sizeof(filp));
        if (!suser())
                return -EPERM;
        p = swap_info;
@@ -879,16 +899,23 @@ asmlinkage int sys_swapon(const char * specialfile)
        p->max = 1;
        error = namei(specialfile,&swap_inode);
        if (error)
-               goto bad_swap;
+               goto bad_swap_2;
        p->swap_file = swap_inode;
        error = -EBUSY;
        if (swap_inode->i_count != 1)
-               goto bad_swap;
+               goto bad_swap_2;
        error = -EINVAL;
+
        if (S_ISBLK(swap_inode->i_mode)) {
                p->swap_device = swap_inode->i_rdev;
+
+               filp.f_inode = swap_inode;
+               filp.f_mode = 3; /* read write */
+               error = blkdev_open(swap_inode, &filp);
                p->swap_file = NULL;
                iput(swap_inode);
+               if(error)
+                       goto bad_swap_2;
                error = -ENODEV;
                if (!p->swap_device)
                        goto bad_swap;
@@ -950,6 +977,9 @@ asmlinkage int sys_swapon(const char * specialfile)
        printk("Adding Swap: %dk swap-space\n",j<<2);
        return 0;
 bad_swap:
+       if(filp.f_op && filp.f_op->release)
+               filp.f_op->release(filp.f_inode,&filp);
+bad_swap_2:
        free_page((long) p->swap_lockmap);
        vfree(p->swap_map);
        iput(p->swap_file);
index dabb26d0b7044a1e622f6c47aa227419bfe3f271..45b22795c77997afe5e01773e1eaad655cd1b89c 100644 (file)
@@ -1 +1 @@
-3c509.o de600.o de620.o 3c501.o eexpress.o plip.o 8390.o
+3c509.o de600.o de620.o 3c501.o apricot.o eexpress.o plip.o 8390.o
index f921c685da61ec31ac53c4cc196f40871e300235..388dc7a06cf1a4fa30a4cd0c54480ce9ba527511 100644 (file)
@@ -232,6 +232,7 @@ static void ip_mc_inc_group(struct device *dev, unsigned long addr)
                return;
        i->users=1;
        i->interface=dev;
+       i->multiaddr=addr;
        i->next=dev->ip_mc_list;
        igmp_group_added(i);
        dev->ip_mc_list=i;
index b85336590e82102223f3145081f1ab747b24600f..fdb4821d3cd9cb23928d4ba2ab9b3b3ec2f00524 100644 (file)
@@ -224,6 +224,10 @@ int ip_build_header(struct sk_buff *skb, unsigned long saddr, unsigned long dadd
         *      See if we need to look up the device.
         */
 
+#ifdef CONFIG_INET_MULTICAST   
+       if(MULTICAST(daddr) && *dev==NULL && skb->sk && *skb->sk->ip_mc_name)
+               *dev=dev_get(skb->sk->ip_mc_name);
+#endif
        if (*dev == NULL)
        {
                if(skb->localroute)
@@ -316,6 +320,7 @@ int ip_build_header(struct sk_buff *skb, unsigned long saddr, unsigned long dadd
        iph->saddr    = saddr;
        iph->protocol = type;
        iph->ihl      = 5;
+       skb->ip_hdr   = iph;
 
        /* Setup the IP options. */
 #ifdef Not_Yet_Avail
@@ -1591,7 +1596,28 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
                kfree_skb(skb, FREE_WRITE);
                return(0);
        }
-
+       
+#ifdef CONFIG_IP_MULTICAST     
+       if(brd==IS_MULTICAST)
+       {
+               /*
+                *      Check it is for one of our groups
+                */
+               struct ip_mc_list *ip_mc=dev->ip_mc_list;
+               do
+               {
+                       if(ip_mc==NULL)
+                       {       
+                               kfree_skb(skb, FREE_WRITE);
+                               return 0;
+                       }
+                       if(ip_mc->multiaddr==iph->daddr)
+                               break;
+                       ip_mc=ip_mc->next;
+               }
+               while(1);
+       }
+#endif
        /*
         *      Account for the packet
         */
@@ -1714,6 +1740,41 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
        return(0);
 }
 
+/*
+ *     Loop a packet back to the sender.
+ */
+static void ip_loopback(struct device *old_dev, struct sk_buff *skb)
+{
+       struct device *dev=&loopback_dev;
+       int len=skb->len-old_dev->hard_header_len;
+       struct sk_buff *newskb=alloc_skb(len+dev->hard_header_len, GFP_ATOMIC);
+       
+       if(newskb==NULL)
+               return;
+               
+       newskb->link3=NULL;
+       newskb->sk=NULL;
+       newskb->dev=dev;
+       newskb->saddr=skb->saddr;
+       newskb->daddr=skb->daddr;
+       newskb->raddr=skb->raddr;
+       newskb->free=1;
+       newskb->lock=0;
+       newskb->users=0;
+       newskb->pkt_type=skb->pkt_type;
+       newskb->len=len+dev->hard_header_len;
+       
+       
+       newskb->ip_hdr=(struct iphdr *)(newskb->data+ip_send(newskb, skb->ip_hdr->daddr, len, dev, skb->ip_hdr->saddr));
+       memcpy(newskb->ip_hdr,skb->ip_hdr,len);
+
+       /* Recurse. The device check against IFF_LOOPBACK will stop infinite recursion */
+               
+       /*printk("Loopback output queued [%lX to %lX].\n", newskb->ip_hdr->saddr,newskb->ip_hdr->daddr);*/
+       ip_queue_xmit(NULL, dev, newskb, 1);
+}
+
 
 /*
  * Queues a packet to be sent, and starts the transmitter
@@ -1858,11 +1919,46 @@ void ip_queue_xmit(struct sock *sk, struct device *dev,
        /*
         *      If the indicated interface is up and running, send the packet.
         */
+        
        ip_statistics.IpOutRequests++;
 #ifdef CONFIG_IP_ACCT
        ip_acct_cnt(iph,ip_acct_chain,1);
 #endif 
+       
+#ifdef CONFIG_IP_MULTICAST     
 
+       /*
+        *      Multicasts are looped back for other local users
+        */
+        
+       if (MULTICAST(skb->daddr) && !(dev->flags&IFF_LOOPBACK))
+       {
+               if(sk==NULL || sk->ip_mc_loop)
+               {
+                       struct ip_mc_list *imc=dev->ip_mc_list;
+                       while(imc!=NULL)
+                       {
+                               if(imc->multiaddr==skb->daddr)
+                               {
+                                       ip_loopback(dev,skb);
+                                       break;
+                               }
+                               imc=imc->next;
+                       }
+               }
+               
+               /* Multicasts with ttl 0 must not go beyond the host */
+               
+               if(skb->ip_hdr->ttl==0)
+               {
+                       kfree_skb(skb, FREE_READ);
+                       return;
+               }
+       }
+#endif
+       if((dev->flags&IFF_BROADCAST) && iph->daddr==dev->pa_brdaddr && !(dev->flags&IFF_LOOPBACK))
+               ip_loopback(dev,skb);
+               
        if (dev->flags & IFF_UP)
        {
                /*
index 34810303edfe3fd76bdf2bf6ddf7d3fb15e16d73..2b811a685b56e1b26825218568ae0b0018c2fdf4 100644 (file)
@@ -450,10 +450,6 @@ static void free_fw_chain(struct ip_fw **chainptr)
        restore_flags(flags);
 }
 
-#endif  /* CONFIG_IP_ACCT || CONFIG_IP_FIREWALL */
-
-#ifdef CONFIG_IP_FIREWALL
-
 static int add_to_chain(struct ip_fw **chainptr, struct ip_fw *frwl)
 {
        struct ip_fw *ftmp;
@@ -706,7 +702,7 @@ static int del_from_chain(struct ip_fw **chainptr, struct ip_fw *frwl)
                return(EINVAL);
 }
 
-#endif /* CONFIG_IP_FIREWALL */
+#endif  /* CONFIG_IP_ACCT || CONFIG_IP_FIREWALL */
 
 struct ip_fw *check_ipfw_struct(struct ip_fw *frwl, int len)
 {
index 0d2406e7bccca75615b2132ab74b9aa545f2c866..fba6d67a7ba020363e5e4db7ab20372f6852a449 100644 (file)
@@ -262,7 +262,7 @@ static struct sk_buff *tcp_find_established(struct sock *s)
                        return p;
                p=p->next;
        }
-       while(p!=skb_peek(&s->receive_queue));
+       while(p!=(struct sk_buff *)&s->receive_queue);
        return NULL;
 }
 
@@ -907,7 +907,7 @@ static void tcp_send_ack(unsigned long sequence, unsigned long ack,
  *     This routine builds a generic TCP header. 
  */
  
-extern __inline int tcp_build_header(struct tcphdr *th, struct sock *sk, int push)
+int tcp_build_header(struct tcphdr *th, struct sock *sk, int push)
 {
 
        /* FIXME: want to get rid of this. */
@@ -4027,22 +4027,19 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
 
                        if (th->rst) 
                        {
-                               if(sk->state!=TCP_TIME_WAIT)    /* RFC 1337 recommendation re RST in time wait */
+                               tcp_statistics.TcpEstabResets++;
+                               sk->zapped=1;
+                               /* This means the thing should really be closed. */
+                               sk->err = ECONNRESET;
+                               if (sk->state == TCP_CLOSE_WAIT) 
                                {
-                                       tcp_statistics.TcpEstabResets++;
-                                       sk->zapped=1;
-                                       /* This means the thing should really be closed. */
-                                       sk->err = ECONNRESET;
-                                       if (sk->state == TCP_CLOSE_WAIT) 
-                                       {
-                                               sk->err = EPIPE;
-                                       }
-                                       tcp_set_state(sk,TCP_CLOSE);
-                                       sk->shutdown = SHUTDOWN_MASK;
-                                       if (!sk->dead) 
-                                       {
-                                               sk->state_change(sk);
-                                       }
+                                       sk->err = EPIPE;
+                               }
+                               tcp_set_state(sk,TCP_CLOSE);
+                               sk->shutdown = SHUTDOWN_MASK;
+                               if (!sk->dead) 
+                               {
+                                       sk->state_change(sk);
                                }
                                kfree_skb(skb, FREE_READ);
                                release_sock(sk);
index ba1340185391940a2865ee33b0b7027252ca2b0f..42885c427bfd503fab0c8ebfe0c7dc6af5152eab 100644 (file)
@@ -8,8 +8,7 @@
 
 #include <linux/config.h>
 #include <linux/utsname.h>
-
-#include "./version.h"
+#include <linux/version.h>
 
 struct new_utsname system_utsname = {
        UTS_SYSNAME, UTS_NODENAME, UTS_RELEASE, UTS_VERSION,