Commit 66a2c418 authored by Linus Torvalds's avatar Linus Torvalds

Import 1.1.72

parent 9c1069bc
......@@ -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
......
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
......
/* 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
/* 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
......@@ -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
......@@ -99,16 +98,12 @@
* 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 */
......
......@@ -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
......@@ -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,
......
......@@ -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
......
......@@ -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
......
......@@ -3,6 +3,7 @@ MODULES = \
de600.o \
de620.o \
3c501.o \
apricot.o \
eexpress.o \
plip.o \
8390.o
......@@ -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;
......@@ -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
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 */
/*
* Local variables:
......
......@@ -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
......
......@@ -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 */
......
......@@ -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"
......
......@@ -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>
......
......@@ -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"
......
......@@ -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;
}
......
......@@ -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 */
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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>
......
......@@ -22,7 +22,7 @@
#ifdef MODULE
#include <linux/module.h>
#include "../../tools/version.h"
#include <linux/version.h>
#endif
#ifdef LEAK_CHECK
......
......@@ -17,7 +17,7 @@
#ifdef MODULE
#include <linux/module.h>
#include "../../tools/version.h"
#include <linux/version.h>
#endif
#include <asm/segment.h>
......
......@@ -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;
}
......
......@@ -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])))
......
......@@ -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
......
......@@ -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 */
......
......@@ -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
......
......@@ -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 */
......
......@@ -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? */
......
......@@ -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
......
......@@ -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;
......
......@@ -25,7 +25,8 @@ enum root_directory_inos {
PROC_INTERRUPTS,
PROC_FILESYSTEMS,
PROC_KSYMS,
PROC_DMA
PROC_DMA,
PROC_IOPORTS
};
enum pid_directory_inos {
......
......@@ -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
......
......@@ -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.
*/
......
......@@ -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),
......
......@@ -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;
......
......@@ -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);
......
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
......@@ -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;
......
......@@ -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)
{
/*
......
......@@ -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)
{
......
......@@ -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);
......
......@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment