Commit b6e9c719 authored by Linus Torvalds's avatar Linus Torvalds

Import 1.3.58

parent ecda87c0
...@@ -149,7 +149,7 @@ S: USA ...@@ -149,7 +149,7 @@ S: USA
N: Andries Brouwer N: Andries Brouwer
E: aeb@cwi.nl E: aeb@cwi.nl
D: International character handling for keyboard and console D: random Linux hacker
S: Bessemerstraat 21 S: Bessemerstraat 21
S: Amsterdam S: Amsterdam
S: The Netherlands S: The Netherlands
...@@ -601,7 +601,7 @@ S: Boulder, Colorado 80303 ...@@ -601,7 +601,7 @@ S: Boulder, Colorado 80303
S: USA S: USA
N: H.J. Lu N: H.J. Lu
E: hjl@nynexst.com E: hjl@gnu.ai.mit.edu
D: GCC + libraries hacker D: GCC + libraries hacker
N: Tuomas J. Lukka N: Tuomas J. Lukka
...@@ -722,7 +722,7 @@ S: Muskego, Wisconsin 53150 ...@@ -722,7 +722,7 @@ S: Muskego, Wisconsin 53150
S: USA S: USA
N: Harald Milz N: Harald Milz
E: hm@ix.de E: hm@seneca.linux.de
D: Linux Projects Map, Linux Commercial-HOWTO D: Linux Projects Map, Linux Commercial-HOWTO
D: general Linux publicity in Germany, vacation port D: general Linux publicity in Germany, vacation port
D: UUCP and CNEWS binary packages for LST D: UUCP and CNEWS binary packages for LST
...@@ -894,7 +894,8 @@ S: B2240 Zandhoven ...@@ -894,7 +894,8 @@ S: B2240 Zandhoven
S: Belgium S: Belgium
N: Martin Schulze N: Martin Schulze
E: joey@infodrom.north.de E: joey@linux.de
W: http://home.pages.de/~joey/
D: Random Linux Hacker, Linux Promoter D: Random Linux Hacker, Linux Promoter
D: CD-List, Books-List, Ex-FAQ D: CD-List, Books-List, Ex-FAQ
D: Linux-Support, -Mailbox, -Stammtisch D: Linux-Support, -Mailbox, -Stammtisch
......
...@@ -221,7 +221,7 @@ CONFIG_MAX_16M ...@@ -221,7 +221,7 @@ CONFIG_MAX_16M
This is for some buggy motherboards which cannot properly deal with This is for some buggy motherboards which cannot properly deal with
the memory above 16MB. If you have more than 16MB of RAM and the memory above 16MB. If you have more than 16MB of RAM and
experience weird problems, you might want to try Y, everyone else experience weird problems, you might want to try Y, everyone else
says N. Note for machines with more that 64MB of RAM: in order for the says N. Note for machines with more than 64MB of RAM: in order for the
kernel to be able to use the memory above 64MB, pass the command kernel to be able to use the memory above 64MB, pass the command
line option "mem=XXXM" (where XXX is the memory size in line option "mem=XXXM" (where XXX is the memory size in
megabytes) to your kernel. See the documentation of your boot loader megabytes) to your kernel. See the documentation of your boot loader
...@@ -379,7 +379,7 @@ CONFIG_MODVERSIONS ...@@ -379,7 +379,7 @@ CONFIG_MODVERSIONS
Kernel daemon support Kernel daemon support
CONFIG_KERNELD CONFIG_KERNELD
Normally when you have seleceted some drivers and/or filesystems Normally when you have selected some drivers and/or filesystems
to be created as loadable modules, you also have the responsibility to be created as loadable modules, you also have the responsibility
to load the corresponding module (via insmod/modprobe) before you to load the corresponding module (via insmod/modprobe) before you
use it. If you select Y here, the kernel will take care of this use it. If you select Y here, the kernel will take care of this
...@@ -1861,7 +1861,7 @@ CONFIG_QUOTA ...@@ -1861,7 +1861,7 @@ CONFIG_QUOTA
ext2 filesystem; you need the software available via ftp (user: ext2 filesystem; you need the software available via ftp (user:
anonymous) from anonymous) from
sunsite.unc.edu:/pub/Linux/systm/Admin/quota_acct.tar.gz in order to sunsite.unc.edu:/pub/Linux/systm/Admin/quota_acct.tar.gz in order to
use it. Obviously, this is only useful for multi user systems. If use it. Probably this is only useful for multi user systems. If
unsure, say N. unsure, say N.
Standard (minix) fs support Standard (minix) fs support
......
...@@ -43,4 +43,8 @@ try recompiling the driver with some strategically chosen #undef DEBUG_...'s ...@@ -43,4 +43,8 @@ try recompiling the driver with some strategically chosen #undef DEBUG_...'s
changed into #defines (you'll find them in .../include/linux/optcd.h) and changed into #defines (you'll find them in .../include/linux/optcd.h) and
include the messages generated in your bug report. Good luck. include the messages generated in your bug report. Good luck.
I have inserted code to support multisession. It works for me, although
it is very slow during disk detection. At this time multisession support
is to be considered experimental. Please mail me your experiences.
Leo Spiekman (spiekman@dutette.et.tudelft.nl) Leo Spiekman (spiekman@dutette.et.tudelft.nl)
...@@ -74,6 +74,7 @@ Ioctl Include File Comments ...@@ -74,6 +74,7 @@ Ioctl Include File Comments
0x06 linux/lp.h 0x06 linux/lp.h
0x12 linux/fs.h 0x12 linux/fs.h
0x20 linux/cm206.h 0x20 linux/cm206.h
0x22 linux/scc.h
'A' linux/apm_bios.h 'A' linux/apm_bios.h
'C' linux/soundcard.h 'C' linux/soundcard.h
'K' linux/kd.h 'K' linux/kd.h
...@@ -83,7 +84,6 @@ Ioctl Include File Comments ...@@ -83,7 +84,6 @@ Ioctl Include File Comments
'S' linux/cdrom.h conflict! 'S' linux/cdrom.h conflict!
'S' linux/scsi.h conflict! 'S' linux/scsi.h conflict!
'T' linux/soundcard.h conflict! 'T' linux/soundcard.h conflict!
'T' linux/scc.h conflict!
'T' asm/termios.h conflict! 'T' asm/termios.h conflict!
'V' linux/vt.h 'V' linux/vt.h
'Y' linux/cyclades.h codes in 0x004359NN 'Y' linux/cyclades.h codes in 0x004359NN
......
VERSION = 1 VERSION = 1
PATCHLEVEL = 3 PATCHLEVEL = 3
SUBLEVEL = 57 SUBLEVEL = 58
ARCH = i386 ARCH = i386
......
...@@ -146,7 +146,7 @@ $(MODINCL)/%.ver: %.c ...@@ -146,7 +146,7 @@ $(MODINCL)/%.ver: %.c
$(SYMTAB_OBJS:.o=.ver): $(TOPDIR)/include/linux/autoconf.h $(SYMTAB_OBJS:.o=.ver): $(TOPDIR)/include/linux/autoconf.h
$(TOPDIR)/include/linux/modversions.h: $(join $(MODINCL)/,$(SYMTAB_OBJS:.o=.ver)) $(TOPDIR)/include/linux/modversions.h: $(addprefix $(MODINCL)/,$(SYMTAB_OBJS:.o=.ver))
@echo updating $(TOPDIR)/include/linux/modversions.h @echo updating $(TOPDIR)/include/linux/modversions.h
@(echo "#ifdef MODVERSIONS";\ @(echo "#ifdef MODVERSIONS";\
echo "#undef CONFIG_MODVERSIONS";\ echo "#undef CONFIG_MODVERSIONS";\
......
...@@ -16,6 +16,7 @@ if [ "$CONFIG_MODULES" = "y" ]; then ...@@ -16,6 +16,7 @@ if [ "$CONFIG_MODULES" = "y" ]; then
MODULES=y MODULES=y
bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
fi fi
endmenu
mainmenu_option next_comment mainmenu_option next_comment
comment 'General setup' comment 'General setup'
...@@ -57,6 +58,7 @@ fi ...@@ -57,6 +58,7 @@ fi
bool 'Networking support' CONFIG_NET bool 'Networking support' CONFIG_NET
bool 'System V IPC' CONFIG_SYSVIPC bool 'System V IPC' CONFIG_SYSVIPC
tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
endmenu
source drivers/block/Config.in source drivers/block/Config.in
...@@ -72,6 +74,7 @@ tristate 'SCSI support' CONFIG_SCSI ...@@ -72,6 +74,7 @@ tristate 'SCSI support' CONFIG_SCSI
if [ "$CONFIG_SCSI" != "n" ]; then if [ "$CONFIG_SCSI" != "n" ]; then
source drivers/scsi/Config.in source drivers/scsi/Config.in
fi fi
endmenu
if [ "$CONFIG_NET" = "y" ]; then if [ "$CONFIG_NET" = "y" ]; then
mainmenu_option next_comment mainmenu_option next_comment
...@@ -81,6 +84,7 @@ if [ "$CONFIG_NET" = "y" ]; then ...@@ -81,6 +84,7 @@ if [ "$CONFIG_NET" = "y" ]; then
if [ "$CONFIG_NETDEVICES" = "y" ]; then if [ "$CONFIG_NETDEVICES" = "y" ]; then
source drivers/net/Config.in source drivers/net/Config.in
fi fi
endmenu
fi fi
mainmenu_option next_comment mainmenu_option next_comment
...@@ -90,6 +94,7 @@ bool 'Support non-SCSI/IDE/ATAPI drives' CONFIG_CD_NO_IDESCSI ...@@ -90,6 +94,7 @@ bool 'Support non-SCSI/IDE/ATAPI drives' CONFIG_CD_NO_IDESCSI
if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
source drivers/cdrom/Config.in source drivers/cdrom/Config.in
fi fi
endmenu
source fs/Config.in source fs/Config.in
...@@ -102,6 +107,7 @@ tristate 'Sound card support' CONFIG_SOUND ...@@ -102,6 +107,7 @@ tristate 'Sound card support' CONFIG_SOUND
if [ "$CONFIG_SOUND" != "n" ]; then if [ "$CONFIG_SOUND" != "n" ]; then
source drivers/sound/Config.in source drivers/sound/Config.in
fi fi
endmenu
mainmenu_option next_comment mainmenu_option next_comment
comment 'Kernel hacking' comment 'Kernel hacking'
...@@ -111,3 +117,4 @@ bool 'Kernel profiling support' CONFIG_PROFILE ...@@ -111,3 +117,4 @@ bool 'Kernel profiling support' CONFIG_PROFILE
if [ "$CONFIG_PROFILE" = "y" ]; then if [ "$CONFIG_PROFILE" = "y" ]; then
int ' Profile shift count' CONFIG_PROFILE_SHIFT 2 int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
fi fi
endmenu
...@@ -12,8 +12,11 @@ ...@@ -12,8 +12,11 @@
.S.o: .S.o:
$(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
OBJS = entry.o traps.o process.o osf_sys.o irq.o signal.o setup.o \ all: kernel.o head.o
bios32.o ptrace.o time.o apecs.o lca.o
O_TARGET := kernel.o
O_OBJS := entry.o traps.o process.o osf_sys.o irq.o signal.o setup.o \
bios32.o ptrace.o time.o apecs.o lca.o ksyms.c
all: kernel.o head.o all: kernel.o head.o
...@@ -22,10 +25,4 @@ head.o: head.s ...@@ -22,10 +25,4 @@ head.o: head.s
head.s: head.S $(TOPDIR)/include/asm-alpha/system.h head.s: head.S $(TOPDIR)/include/asm-alpha/system.h
$(CPP) -traditional -o $*.s $< $(CPP) -traditional -o $*.s $<
kernel.o: $(OBJS)
$(LD) -r -o kernel.o $(OBJS)
dep:
$(CPP) -M *.c > .depend
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
/*
* linux/arch/alpha/kernel/ksyms.c
*
* Export the alpha-specific functions that are needed for loadable
* modules.
*/
#include <linux/config.h>
#include <linux/module.h>
# include <asm/io.h>
# include <asm/hwrpb.h>
extern void bcopy (const char *src, char *dst, int len);
extern struct hwrpb_struct *hwrpb;
/* these are C runtime functions with special calling conventions: */
extern void __divl (void);
extern void __reml (void);
extern void __divq (void);
extern void __remq (void);
extern void __divlu (void);
extern void __remlu (void);
extern void __divqu (void);
extern void __remqu (void);
static struct symbol_table arch_symbol_table = {
#include <linux/symtab_begin.h>
/* platform dependent support */
X(_inb),
X(_inw),
X(_inl),
X(_outb),
X(_outw),
X(_outl),
X(bcopy), /* generated by gcc-2.7.0 for string assignments */
X(hwrpb),
X(__divl),
X(__reml),
X(__divq),
X(__remq),
X(__divlu),
X(__remlu),
X(__divqu),
X(__remqu),
X(strlen), /* used by ftape */
X(memcmp),
X(memmove),
X(__constant_c_memset),
#include <linux/symtab_end.h>
};
void arch_syms_export(void)
{
register_symtab(&arch_symbol_table);
}
...@@ -12,6 +12,7 @@ if [ "$CONFIG_MODULES" = "y" ]; then ...@@ -12,6 +12,7 @@ if [ "$CONFIG_MODULES" = "y" ]; then
bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
bool 'Kernel daemon support (e.g. autoload of modules)' CONFIG_KERNELD bool 'Kernel daemon support (e.g. autoload of modules)' CONFIG_KERNELD
fi fi
endmenu
mainmenu_option next_comment mainmenu_option next_comment
comment 'General setup' comment 'General setup'
...@@ -32,6 +33,7 @@ choice 'Processor type' \ ...@@ -32,6 +33,7 @@ choice 'Processor type' \
"386 CONFIG_M386 \ "386 CONFIG_M386 \
486 CONFIG_M486 \ 486 CONFIG_M486 \
Pentium CONFIG_M586" Pentium Pentium CONFIG_M586" Pentium
endmenu
source drivers/block/Config.in source drivers/block/Config.in
...@@ -47,6 +49,7 @@ tristate 'SCSI support' CONFIG_SCSI ...@@ -47,6 +49,7 @@ tristate 'SCSI support' CONFIG_SCSI
if [ "$CONFIG_SCSI" != "n" ]; then if [ "$CONFIG_SCSI" != "n" ]; then
source drivers/scsi/Config.in source drivers/scsi/Config.in
fi fi
endmenu
if [ "$CONFIG_NET" = "y" ]; then if [ "$CONFIG_NET" = "y" ]; then
mainmenu_option next_comment mainmenu_option next_comment
...@@ -56,6 +59,7 @@ if [ "$CONFIG_NET" = "y" ]; then ...@@ -56,6 +59,7 @@ if [ "$CONFIG_NET" = "y" ]; then
if [ "$CONFIG_NETDEVICES" = "y" ]; then if [ "$CONFIG_NETDEVICES" = "y" ]; then
source drivers/net/Config.in source drivers/net/Config.in
fi fi
endmenu
fi fi
mainmenu_option next_comment mainmenu_option next_comment
...@@ -65,6 +69,7 @@ bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI ...@@ -65,6 +69,7 @@ bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
source drivers/cdrom/Config.in source drivers/cdrom/Config.in
fi fi
endmenu
source fs/Config.in source fs/Config.in
...@@ -77,6 +82,7 @@ tristate 'Sound card support' CONFIG_SOUND ...@@ -77,6 +82,7 @@ tristate 'Sound card support' CONFIG_SOUND
if [ "$CONFIG_SOUND" != "n" ]; then if [ "$CONFIG_SOUND" != "n" ]; then
source drivers/sound/Config.in source drivers/sound/Config.in
fi fi
endmenu
mainmenu_option next_comment mainmenu_option next_comment
comment 'Kernel hacking' comment 'Kernel hacking'
...@@ -86,3 +92,4 @@ bool 'Kernel profiling support' CONFIG_PROFILE ...@@ -86,3 +92,4 @@ bool 'Kernel profiling support' CONFIG_PROFILE
if [ "$CONFIG_PROFILE" = "y" ]; then if [ "$CONFIG_PROFILE" = "y" ]; then
int ' Profile shift count' CONFIG_PROFILE_SHIFT 2 int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
fi fi
endmenu
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
# Loadable module support # Loadable module support
# #
CONFIG_MODULES=y CONFIG_MODULES=y
# CONFIG_MODVERSIONS is not set CONFIG_MODVERSIONS=y
# CONFIG_KERNELD is not set # CONFIG_KERNELD is not set
# #
...@@ -36,9 +36,9 @@ CONFIG_ST506=y ...@@ -36,9 +36,9 @@ CONFIG_ST506=y
# #
# CONFIG_BLK_DEV_HD is not set # CONFIG_BLK_DEV_HD is not set
CONFIG_BLK_DEV_IDE=y CONFIG_BLK_DEV_IDE=y
CONFIG_BLK_DEV_IDEATAPI=y
CONFIG_BLK_DEV_IDECD=y CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDETAPE is not set
CONFIG_BLK_DEV_CMD640=y
# CONFIG_BLK_DEV_TRITON is not set # CONFIG_BLK_DEV_TRITON is not set
# CONFIG_BLK_DEV_XD is not set # CONFIG_BLK_DEV_XD is not set
......
...@@ -28,7 +28,7 @@ all: kernel.o head.o ...@@ -28,7 +28,7 @@ all: kernel.o head.o
O_TARGET := kernel.o O_TARGET := kernel.o
O_OBJS := process.o signal.o entry.o traps.o irq.o vm86.o bios32.o \ O_OBJS := process.o signal.o entry.o traps.o irq.o vm86.o bios32.o \
ptrace.o ioport.o ldt.o setup.o time.o sys_i386.o ptrace.o ioport.o ldt.o setup.o time.o sys_i386.o ksyms.o
ifdef SMP ifdef SMP
......
#include <linux/module.h>
#include <linux/smp.h>
static struct symbol_table arch_symbol_table = {
#include <linux/symtab_begin.h>
/* platform dependent support */
#ifdef __SMP__
X(apic_reg), /* Needed internally for the I386 inlines */
#endif
#include <linux/symtab_end.h>
};
void arch_syms_export(void)
{
register_symtab(&arch_symbol_table);
}
...@@ -196,7 +196,7 @@ static const char * i486model(unsigned int nr) ...@@ -196,7 +196,7 @@ static const char * i486model(unsigned int nr)
static const char * i586model(unsigned int nr) static const char * i586model(unsigned int nr)
{ {
static const char *model[] = { static const char *model[] = {
"0", "Pentium 60/66","Pentium 75+" "0", "Pentium 60/66","Pentium 75+","OverDrive PODP5V83"
}; };
if (nr < sizeof(model)/sizeof(char *)) if (nr < sizeof(model)/sizeof(char *))
return model[nr]; return model[nr];
......
...@@ -47,10 +47,12 @@ bool 'Networking support' CONFIG_NET ...@@ -47,10 +47,12 @@ bool 'Networking support' CONFIG_NET
# bool ' PCI bridge optimization (experimental)' CONFIG_PCI_OPTIMIZE # bool ' PCI bridge optimization (experimental)' CONFIG_PCI_OPTIMIZE
#fi #fi
bool 'System V IPC' CONFIG_SYSVIPC bool 'System V IPC' CONFIG_SYSVIPC
endmenu
mainmenu_option next_comment mainmenu_option next_comment
comment 'Loadable module support' comment 'Loadable module support'
bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
endmenu
source drivers/block/Config.in source drivers/block/Config.in
...@@ -66,6 +68,7 @@ tristate 'SCSI support' CONFIG_SCSI ...@@ -66,6 +68,7 @@ tristate 'SCSI support' CONFIG_SCSI
if [ "$CONFIG_SCSI" != "n" ]; then if [ "$CONFIG_SCSI" != "n" ]; then
source drivers/scsi/Config.in source drivers/scsi/Config.in
fi fi
endmenu
if [ "$CONFIG_NET" = "y" ]; then if [ "$CONFIG_NET" = "y" ]; then
mainmenu_option next_comment mainmenu_option next_comment
...@@ -75,6 +78,7 @@ if [ "$CONFIG_NET" = "y" ]; then ...@@ -75,6 +78,7 @@ if [ "$CONFIG_NET" = "y" ]; then
if [ "$CONFIG_NETDEVICES" = "y" ]; then if [ "$CONFIG_NETDEVICES" = "y" ]; then
source drivers/net/Config.in source drivers/net/Config.in
fi fi
endmenu
fi fi
mainmenu_option next_comment mainmenu_option next_comment
...@@ -84,6 +88,7 @@ bool 'Support non-SCSI/IDE/ATAPI drives' CONFIG_CD_NO_IDESCSI ...@@ -84,6 +88,7 @@ bool 'Support non-SCSI/IDE/ATAPI drives' CONFIG_CD_NO_IDESCSI
if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
source drivers/cdrom/Config.in source drivers/cdrom/Config.in
fi fi
endmenu
source fs/Config.in source fs/Config.in
...@@ -97,6 +102,7 @@ tristate 'Sound card support' CONFIG_SOUND ...@@ -97,6 +102,7 @@ tristate 'Sound card support' CONFIG_SOUND
if [ "$CONFIG_SOUND" != "n" ]; then if [ "$CONFIG_SOUND" != "n" ]; then
source drivers/sound/Config.in source drivers/sound/Config.in
fi fi
endmenu
mainmenu_option next_comment mainmenu_option next_comment
comment 'Kernel hacking' comment 'Kernel hacking'
...@@ -106,3 +112,4 @@ bool 'Kernel profiling support' CONFIG_PROFILE ...@@ -106,3 +112,4 @@ bool 'Kernel profiling support' CONFIG_PROFILE
if [ "$CONFIG_PROFILE" = "y" ]; then if [ "$CONFIG_PROFILE" = "y" ]; then
int ' Profile shift count' CONFIG_PROFILE_SHIFT 2 int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
fi fi
endmenu
...@@ -17,6 +17,7 @@ define_bool CONFIG_SUN_CONSOLE y ...@@ -17,6 +17,7 @@ define_bool CONFIG_SUN_CONSOLE y
bool 'Networking support' CONFIG_NET bool 'Networking support' CONFIG_NET
bool 'System V IPC' CONFIG_SYSVIPC bool 'System V IPC' CONFIG_SYSVIPC
tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
endmenu
source drivers/block/Config.in source drivers/block/Config.in
...@@ -32,6 +33,7 @@ tristate 'SCSI support' CONFIG_SCSI ...@@ -32,6 +33,7 @@ tristate 'SCSI support' CONFIG_SCSI
if [ "$CONFIG_SCSI" != "n" ]; then if [ "$CONFIG_SCSI" != "n" ]; then
source drivers/scsi/Config.in source drivers/scsi/Config.in
fi fi
endmenu
if [ "$CONFIG_NET" = "y" ]; then if [ "$CONFIG_NET" = "y" ]; then
mainmenu_option next_comment mainmenu_option next_comment
...@@ -41,6 +43,7 @@ if [ "$CONFIG_NET" = "y" ]; then ...@@ -41,6 +43,7 @@ if [ "$CONFIG_NET" = "y" ]; then
if [ "$CONFIG_NETDEVICES" = "y" ]; then if [ "$CONFIG_NETDEVICES" = "y" ]; then
source drivers/net/Config.in source drivers/net/Config.in
fi fi
endmenu
fi fi
source fs/Config.in source fs/Config.in
......
...@@ -16,11 +16,9 @@ if [ "$CONFIG_ST506" = "y" ]; then ...@@ -16,11 +16,9 @@ if [ "$CONFIG_ST506" = "y" ]; then
bool ' Use new IDE driver for primary/secondary i/f' CONFIG_BLK_DEV_IDE bool ' Use new IDE driver for primary/secondary i/f' CONFIG_BLK_DEV_IDE
fi fi
if [ "$CONFIG_BLK_DEV_IDE" = "y" ]; then if [ "$CONFIG_BLK_DEV_IDE" = "y" ]; then
bool ' Include support for IDE/ATAPI CDROM or TAPE' CONFIG_BLK_DEV_IDEATAPI bool ' Include IDE/ATAPI CDROM support' CONFIG_BLK_DEV_IDECD
if [ "$CONFIG_BLK_DEV_IDEATAPI" = "y" ]; then bool ' Include (ALPHA) IDE/ATAPI TAPE support' CONFIG_BLK_DEV_IDETAPE
bool ' Include support for IDE/ATAPI CDROM' CONFIG_BLK_DEV_IDECD bool ' Special CMD640 chipset support' CONFIG_BLK_DEV_CMD640
bool ' Include ALPHA support for IDE/ATAPI TAPE' CONFIG_BLK_DEV_IDETAPE
fi
if [ "$CONFIG_PCI" = "y" ]; then if [ "$CONFIG_PCI" = "y" ]; then
bool ' PCI Triton IDE Bus Master DMA support' CONFIG_BLK_DEV_TRITON bool ' PCI Triton IDE Bus Master DMA support' CONFIG_BLK_DEV_TRITON
fi fi
...@@ -28,3 +26,4 @@ if [ "$CONFIG_ST506" = "y" ]; then ...@@ -28,3 +26,4 @@ if [ "$CONFIG_ST506" = "y" ]; then
fi fi
bool 'XT harddisk support' CONFIG_BLK_DEV_XD bool 'XT harddisk support' CONFIG_BLK_DEV_XD
endmenu
...@@ -48,6 +48,10 @@ ifeq ($(CONFIG_BLK_DEV_TRITON),y) ...@@ -48,6 +48,10 @@ ifeq ($(CONFIG_BLK_DEV_TRITON),y)
L_OBJS += triton.o L_OBJS += triton.o
endif endif
ifeq ($(CONFIG_BLK_DEV_CMD640),y)
L_OBJS += cmd640.o
endif
ifeq ($(CONFIG_BLK_DEV_IDECD),y) ifeq ($(CONFIG_BLK_DEV_IDECD),y)
L_OBJS += ide-cd.o L_OBJS += ide-cd.o
endif endif
......
...@@ -350,13 +350,19 @@ then use the kernel command line parameters to pass the *logical* geometry, ...@@ -350,13 +350,19 @@ then use the kernel command line parameters to pass the *logical* geometry,
as in: hda=525,64,63 as in: hda=525,64,63
If the BIOS does not support this form of drive translation, then several If the BIOS does not support this form of drive translation, then several
options remain, listed below in inverse order of popularity: options remain, listed below in order of popularity:
- boot from a floppy disk instead of the hard drive (takes 10 seconds).
- use a partition below the 1024 cyl boundary to hold the linux - use a partition below the 1024 cyl boundary to hold the linux
boot files (kernel images and /boot directory), and place the rest boot files (kernel images and /boot directory), and place the rest
of linux anywhere else on the drive. These files can reside in a DOS of linux anywhere else on the drive. These files can reside in a DOS
partition, or in a tailor-made linux boot partition. partition, or in a tailor-made linux boot partition.
- use DiskManager software from OnTrack, supplied free with
many new hard drive purchases.
- use EZ-Drive software (similar to DiskManager). Note though,
that LILO must *not* use the MBR when EZ-Drive is present.
Instead, install LILO on the first sector of your linux partition,
and mark it as "active" or "bootable" with fdisk.
- boot from a floppy disk instead of the hard drive (takes 10 seconds).
If you cannot use drive translation, *and* your BIOS also restricts you to If you cannot use drive translation, *and* your BIOS also restricts you to
entering no more than 1024 cylinders in the geometry field in the CMOS setup, entering no more than 1024 cylinders in the geometry field in the CMOS setup,
......
/* /*
* linux/drivers/block/cmd640.c Version 0.02 Nov 30, 1995 * linux/drivers/block/cmd640.c Version 0.04 Jan 11, 1996
* *
* Copyright (C) 1995 Linus Torvalds & author (see below) * Copyright (C) 1995-1996 Linus Torvalds & author (see below)
*/ */
/* /*
...@@ -18,8 +18,49 @@ ...@@ -18,8 +18,49 @@
* read-ahead for versions 'B' and 'C' of chip by * read-ahead for versions 'B' and 'C' of chip by
* default, some code cleanup. * default, some code cleanup.
* *
* Version 0.03 Added reset of secondary interface,
* and black list for devices which are not compatible
* with read ahead mode. Separate function for setting
* readahead is added, possibly it will be called some
* day from ioctl processing code.
*
* Version 0.04 Now configs/compiles separate from ide.c -ml
*/
/*
* There is a known problem with current version of this driver.
* If the only device on secondary interface is CD-ROM, at some
* computers it is not recognized. In all reported cases CD-ROM
* was 2x or 4x speed Mitsumi drive.
*
* The following workarounds could work:
*
* 1. put CD-ROM as slave on primary interface
*
* 2. or define symbol at next line as 0
*
*/ */
#define CMD640_NORMAL_INIT 1
#undef REALLY_SLOW_IO /* most systems can safely undef this */
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <asm/io.h>
#include "ide.h"
extern ide_hwif_t ide_hwifs[];
int cmd640_vlb = 0;
/* /*
* CMD640 specific registers definition. * CMD640 specific registers definition.
*/ */
...@@ -76,7 +117,7 @@ static int bus_speed; /* MHz */ ...@@ -76,7 +117,7 @@ static int bus_speed; /* MHz */
/* /*
* For some unknown reasons pcibios functions which read and write registers * For some unknown reasons pcibios functions which read and write registers
* do not work with cmd640. We use direct io instead. * do not always work with cmd640. We use direct io instead.
*/ */
/* PCI method 1 access */ /* PCI method 1 access */
...@@ -229,6 +270,35 @@ static int probe_for_cmd640_vlb(void) { ...@@ -229,6 +270,35 @@ static int probe_for_cmd640_vlb(void) {
return 1; return 1;
} }
/*
* Low level reset for controller, actually it has nothing specific for
* CMD640, but I don't know how to use standard reset routine before
* we recognized any drives.
*/
static void cmd640_reset_controller(int iface_no)
{
int retry_count = 600;
int base_port = iface_no ? 0x170 : 0x1f0;
outb_p(4, base_port + 7);
udelay(5);
outb_p(0, base_port + 7);
do {
udelay(5);
retry_count -= 1;
} while ((inb_p(base_port + 7) & 0x80) && retry_count);
if (retry_count == 0)
printk("cmd640: failed to reset controller %d\n", iface_no);
#if 0
else
printk("cmd640: controller %d reset [%d]\n",
iface_no, retry_count);
#endif
}
/* /*
* Probe for Cmd640x and initialize it if found * Probe for Cmd640x and initialize it if found
*/ */
...@@ -282,31 +352,34 @@ int ide_probe_for_cmd640x(void) ...@@ -282,31 +352,34 @@ int ide_probe_for_cmd640x(void)
/* /*
* Set the maximum allowed bus speed (it is safest until we * Set the maximum allowed bus speed (it is safest until we
* find how detect bus speed) * find how to detect bus speed)
* Normally PCI bus runs at 33MHz, but often works overclocked to 40 * Normally PCI bus runs at 33MHz, but often works overclocked to 40
*/ */
bus_speed = (bus_type == vlb) ? 50 : 40; bus_speed = (bus_type == vlb) ? 50 : 40;
#if 1 /* don't know if this is reliable yet */
/* /*
* Enable readahead for versions above 'A' * Enable readahead for versions above 'A'
*/ */
cmd_read_ahead = (cmd640_chip_version > 1); cmd_read_ahead = (cmd640_chip_version > 1);
#else
cmd_read_ahead = 0;
#endif
/* /*
* Setup Control Register * Setup Control Register
*/ */
b = get_cmd640_reg(cmd640_key, CNTRL); b = get_cmd640_reg(cmd640_key, CNTRL);
#if CMD640_NORMAL_INIT
if (second_port) if (second_port)
b |= CNTRL_ENA_2ND; b |= CNTRL_ENA_2ND;
else else
b &= ~CNTRL_ENA_2ND; b &= ~CNTRL_ENA_2ND;
#endif
if (cmd_read_ahead) if (cmd_read_ahead)
b &= ~(CNTRL_DIS_RA0 | CNTRL_DIS_RA1); b &= ~(CNTRL_DIS_RA0 | CNTRL_DIS_RA1);
else else
b |= (CNTRL_DIS_RA0 | CNTRL_DIS_RA1); b |= (CNTRL_DIS_RA0 | CNTRL_DIS_RA1);
put_cmd640_reg(cmd640_key, CNTRL, b); put_cmd640_reg(cmd640_key, CNTRL, b);
/* /*
...@@ -317,9 +390,11 @@ int ide_probe_for_cmd640x(void) ...@@ -317,9 +390,11 @@ int ide_probe_for_cmd640x(void)
b = cmd_read_ahead ? 0 : (DIS_RA2 | DIS_RA3); b = cmd_read_ahead ? 0 : (DIS_RA2 | DIS_RA3);
put_cmd640_reg(cmd640_key, ARTTIM23, b); put_cmd640_reg(cmd640_key, ARTTIM23, b);
put_cmd640_reg(cmd640_key, DRWTIM23, 0); put_cmd640_reg(cmd640_key, DRWTIM23, 0);
cmd640_reset_controller(1);
} }
serialized = 1; ide_hwifs[0].serialized = 1;
printk("ide: buggy CMD640%c interface at ", printk("ide: buggy CMD640%c interface at ",
'A' - 1 + cmd640_chip_version); 'A' - 1 + cmd640_chip_version);
...@@ -359,6 +434,48 @@ static int as_clocks(int a) { ...@@ -359,6 +434,48 @@ static int as_clocks(int a) {
} }
} }
/*
* Sets readahead mode for specific drive
* in the future it could be called from ioctl
*/
static void set_readahead_mode(int mode, int if_num, int dr_num)
{
static int masks[2][2] =
{
{CNTRL_DIS_RA0, CNTRL_DIS_RA1},
{DIS_RA2, DIS_RA3}
};
int port = (if_num == 0) ? CNTRL : ARTTIM23;
int mask = masks[if_num][dr_num];
byte b;
b = get_cmd640_reg(cmd640_key, port);
if (mode)
b &= mask; /* Enable readahead for specific drive */
else
b |= mask; /* Disable readahed for specific drive */
put_cmd640_reg(cmd640_key, port, b);
}
static struct readahead_black_list {
const char* name;
int mode;
} drives_ra[] = {
{ "ST3655A", 0 },
{ NULL, 0 }
};
static int known_drive_readahead(char* name) {
int i;
for (i = 0; drives_ra[i].name != NULL; i++)
if (strcmp(name, drives_ra[i].name) == 0)
return drives_ra[i].mode;
return -1;
}
/* /*
* Tuning of drive parameters * Tuning of drive parameters
*/ */
...@@ -400,7 +517,7 @@ static void cmd640_set_timing(int if_num, int dr_num, int r1, int r2) { ...@@ -400,7 +517,7 @@ static void cmd640_set_timing(int if_num, int dr_num, int r1, int r2) {
} }
} }
struct pio_timing { static struct pio_timing {
int mc_time; /* Minimal cycle time (ns) */ int mc_time; /* Minimal cycle time (ns) */
int av_time; /* Address valid to DIOR-/DIOW- setup (ns) */ int av_time; /* Address valid to DIOR-/DIOW- setup (ns) */
int ds_time; /* DIOR data setup (ns) */ int ds_time; /* DIOR data setup (ns) */
...@@ -413,7 +530,7 @@ struct pio_timing { ...@@ -413,7 +530,7 @@ struct pio_timing {
{ 20, 50, 100 } /* PIO Mode ? */ { 20, 50, 100 } /* PIO Mode ? */
}; };
struct drive_pio_info { static struct drive_pio_info {
const char *name; const char *name;
int pio; int pio;
} drive_pios[] = { } drive_pios[] = {
...@@ -426,6 +543,7 @@ struct drive_pio_info { ...@@ -426,6 +543,7 @@ struct drive_pio_info {
{ "QUANTUM LPS240A", 0 }, { "QUANTUM LPS240A", 0 },
{ "QUANTUM LPS270A", 3 }, { "QUANTUM LPS270A", 3 },
{ "QUANTUM LPS540A", 3 }, { "QUANTUM LPS540A", 3 },
{ "QUANTUM FIREBALL1080A", 3 },
{ NULL, 0 } { NULL, 0 }
}; };
...@@ -480,7 +598,7 @@ static void set_pio_mode(int if_num, int drv_num, int mode_num) { ...@@ -480,7 +598,7 @@ static void set_pio_mode(int if_num, int drv_num, int mode_num) {
outb_p((drv_num | 0xa) << 4, p_base + 6); outb_p((drv_num | 0xa) << 4, p_base + 6);
outb_p(0xef, p_base + 7); outb_p(0xef, p_base + 7);
for (i = 0; (i < 100) && (inb (p_base + 7) & 0x80); i++) for (i = 0; (i < 100) && (inb (p_base + 7) & 0x80); i++)
delay_10ms(); udelay(10000);
} }
void cmd640_tune_drive(ide_drive_t* drive) { void cmd640_tune_drive(ide_drive_t* drive) {
...@@ -491,6 +609,7 @@ void cmd640_tune_drive(ide_drive_t* drive) { ...@@ -491,6 +609,7 @@ void cmd640_tune_drive(ide_drive_t* drive) {
int mc_time, av_time, ds_time; int mc_time, av_time, ds_time;
struct hd_driveid* id; struct hd_driveid* id;
int r1, r2; int r1, r2;
int mode;
/* /*
* Determine if drive is under cmd640 control * Determine if drive is under cmd640 control
...@@ -530,6 +649,13 @@ void cmd640_tune_drive(ide_drive_t* drive) { ...@@ -530,6 +649,13 @@ void cmd640_tune_drive(ide_drive_t* drive) {
&r1, &r2); &r1, &r2);
set_pio_mode(interface_number, drive_number, max_pio); set_pio_mode(interface_number, drive_number, max_pio);
cmd640_set_timing(interface_number, drive_number, r1, r2); cmd640_set_timing(interface_number, drive_number, r1, r2);
/*
* Disable (or set) readahead mode for known drive
*/
if ((mode = known_drive_readahead(id->model)) != -1) {
set_readahead_mode(mode, interface_number, drive_number);
printk("Readahead %s,", mode ? "enabled" : "disabled");
}
printk ("Mode and Timing set to PIO%d (0x%x 0x%x)\n", max_pio, r1, r2); printk ("Mode and Timing set to PIO%d (0x%x 0x%x)\n", max_pio, r1, r2);
} }
...@@ -108,7 +108,6 @@ ...@@ -108,7 +108,6 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#define _IDE_CD_C /* used in blk.h */
#include "ide.h" #include "ide.h"
......
...@@ -300,8 +300,6 @@ ...@@ -300,8 +300,6 @@
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/io.h> #include <asm/io.h>
#define _IDE_TAPE_C /* For ide_end_request in blk.h */
/* /*
* Main Linux ide driver include file * Main Linux ide driver include file
* *
......
/* /*
* linux/drivers/block/ide.c Version 5.24 Jan 4, 1996 * linux/drivers/block/ide.c Version 5.25 Jan 11, 1996
* *
* Copyright (C) 1994-1996 Linus Torvalds & authors (see below) * Copyright (C) 1994-1996 Linus Torvalds & authors (see below)
*/ */
#define _IDE_C /* needed by <linux/blk.h> */
/* /*
* This is the multiple IDE interface driver, as evolved from hd.c. * This is the multiple IDE interface driver, as evolved from hd.c.
...@@ -109,7 +110,7 @@ ...@@ -109,7 +110,7 @@
* assembly syntax tweak to vlb_sync * assembly syntax tweak to vlb_sync
* removeable drive support from scuba@cs.tu-berlin.de * removeable drive support from scuba@cs.tu-berlin.de
* add transparent support for DiskManager-6.0x "Dynamic * add transparent support for DiskManager-6.0x "Dynamic
* Disk Overlay" (DDO), most of this in in genhd.c * Disk Overlay" (DDO), most of this is in genhd.c
* eliminate "multiple mode turned off" message at boot * eliminate "multiple mode turned off" message at boot
* Version 4.10 fix bug in ioctl for "hdparm -c3" * Version 4.10 fix bug in ioctl for "hdparm -c3"
* fix DM6:DDO support -- now works with LILO, fdisk, ... * fix DM6:DDO support -- now works with LILO, fdisk, ...
...@@ -180,11 +181,13 @@ ...@@ -180,11 +181,13 @@
* Version 5.22 fix ide_xlate_1024() to work with/without drive->id * Version 5.22 fix ide_xlate_1024() to work with/without drive->id
* Version 5.23 miscellaneous touch-ups * Version 5.23 miscellaneous touch-ups
* Version 5.24 fix #if's for SUPPORT_CMD640 * Version 5.24 fix #if's for SUPPORT_CMD640
* Version 5.25 more touch-ups, fix cdrom resets, ...
* cmd640.c now configs/compiles separate from ide.c
* *
* Driver compile-time options are in ide.h * Driver compile-time options are in ide.h
* *
* To do, in likely order of completion: * To do, in likely order of completion:
* - make cmd640.c and umc8672.c compile separately from ide.c * - make umc8672.c compile separately from ide.c
* - add ALI M1443/1445 chipset support from derekn@vw.ece.cmu.edu * - add ALI M1443/1445 chipset support from derekn@vw.ece.cmu.edu
* - add ioctls to get/set interface timings on various interfaces * - add ioctls to get/set interface timings on various interfaces
* - add Promise Caching controller support from peterd@pnd-pc.demon.co.uk * - add Promise Caching controller support from peterd@pnd-pc.demon.co.uk
...@@ -222,18 +225,12 @@ ...@@ -222,18 +225,12 @@
#include "ide.h" #include "ide.h"
#if SUPPORT_CMD640
void cmd640_tune_drive(ide_drive_t *);
static int cmd640_vlb = 0;
#endif
ide_hwif_t ide_hwifs[MAX_HWIFS]; /* hwif info */ ide_hwif_t ide_hwifs[MAX_HWIFS]; /* hwif info */
static ide_hwgroup_t *irq_to_hwgroup [16]; static ide_hwgroup_t *irq_to_hwgroup [16];
static const byte ide_hwif_to_major[MAX_HWIFS] = {IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR}; static const byte ide_hwif_to_major[MAX_HWIFS] = {IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR};
static const unsigned short default_io_base[MAX_HWIFS] = {0x1f0, 0x170, 0x1e8, 0x168}; static const unsigned short default_io_base[MAX_HWIFS] = {0x1f0, 0x170, 0x1e8, 0x168};
static const byte default_irqs[MAX_HWIFS] = {14, 15, 11, 10}; static const byte default_irqs[MAX_HWIFS] = {14, 15, 11, 10};
static int serialized = 0; /* "serialize" option */
static int disallow_unmask = 0; /* for buggy hardware */ static int disallow_unmask = 0; /* for buggy hardware */
#if (DISK_RECOVERY_TIME > 0) #if (DISK_RECOVERY_TIME > 0)
...@@ -881,7 +878,8 @@ void ide_error (ide_drive_t *drive, const char *msg, byte stat) ...@@ -881,7 +878,8 @@ void ide_error (ide_drive_t *drive, const char *msg, byte stat)
err = ide_dump_status(drive, msg, stat); err = ide_dump_status(drive, msg, stat);
if ((rq = HWGROUP(drive)->rq) == NULL || drive == NULL) if ((rq = HWGROUP(drive)->rq) == NULL || drive == NULL)
return; return;
if (rq->cmd != READ && rq->cmd != WRITE) { /* retry only "normal" i/o */ /* retry only "normal" I/O: */
if (rq->cmd != READ && rq->cmd != WRITE && drive->media != ide_cdrom) {
rq->errors = 1; rq->errors = 1;
ide_end_drive_cmd(drive, stat, err); ide_end_drive_cmd(drive, stat, err);
return; return;
...@@ -1346,7 +1344,7 @@ static inline void do_request (ide_hwif_t *hwif, struct request *rq) ...@@ -1346,7 +1344,7 @@ static inline void do_request (ide_hwif_t *hwif, struct request *rq)
#if FAKE_FDISK_FOR_EZDRIVE #if FAKE_FDISK_FOR_EZDRIVE
if (block == 0 && drive->ezdrive) { if (block == 0 && drive->ezdrive) {
block = 1; block = 1;
printk("%s: [EZD] accessing sector 1 instead of sector 0\n", drive->name); printk("%s: [EZD] accessing sector 1 in place of sector 0\n", drive->name);
} }
#endif /* FAKE_FDISK_FOR_EZDRIVE */ #endif /* FAKE_FDISK_FOR_EZDRIVE */
((ide_hwgroup_t *)hwif->hwgroup)->drive = drive; ((ide_hwgroup_t *)hwif->hwgroup)->drive = drive;
...@@ -2210,8 +2208,11 @@ static inline void do_identify (ide_drive_t *drive, byte cmd) ...@@ -2210,8 +2208,11 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
printk(", DMA"); printk(", DMA");
} }
printk("\n"); printk("\n");
#if SUPPORT_CMD640 #ifdef CONFIG_BLK_DEV_CMD640
cmd640_tune_drive(drive); /* but can we tune a fish? */ {
extern void cmd640_tune_drive (ide_drive_t *);
cmd640_tune_drive(drive); /* but can we tune a fish? */
}
#endif #endif
} }
...@@ -2527,10 +2528,6 @@ static void init_qd6580 (void) ...@@ -2527,10 +2528,6 @@ static void init_qd6580 (void)
#include "umc8672.c" /* until we tidy up the interface some more */ #include "umc8672.c" /* until we tidy up the interface some more */
#endif #endif
#if SUPPORT_CMD640
#include "cmd640.c" /* until we tidy up the interface some more */
#endif
/* /*
* stridx() returns the offset of c within s, * stridx() returns the offset of c within s,
* or -1 if c is '\0' or not found within s. * or -1 if c is '\0' or not found within s.
...@@ -2699,12 +2696,15 @@ void ide_setup (char *s) ...@@ -2699,12 +2696,15 @@ void ide_setup (char *s)
init_qd6580(); init_qd6580();
goto done; goto done;
#endif /* SUPPORT_QD6580 */ #endif /* SUPPORT_QD6580 */
#if SUPPORT_CMD640 #ifdef CONFIG_BLK_DEV_CMD640
case -5: /* "cmd640_vlb" */ case -5: /* "cmd640_vlb" */
{
extern int cmd640_vlb;
if (hw > 1) goto bad_hwif; if (hw > 1) goto bad_hwif;
cmd640_vlb = 1; cmd640_vlb = 1;
}
break; break;
#endif /* SUPPORT_CMD640 */ #endif /* CONFIG_BLK_DEV_CMD640 */
#if SUPPORT_HT6560B #if SUPPORT_HT6560B
case -4: /* "ht6560b" */ case -4: /* "ht6560b" */
if (hw > 1) goto bad_hwif; if (hw > 1) goto bad_hwif;
...@@ -2736,7 +2736,7 @@ void ide_setup (char *s) ...@@ -2736,7 +2736,7 @@ void ide_setup (char *s)
case -2: /* "serialize" */ case -2: /* "serialize" */
do_serialize: do_serialize:
if (hw > 1) goto bad_hwif; if (hw > 1) goto bad_hwif;
serialized = 1; ide_hwifs[0].serialized = 1;
goto done; goto done;
case -1: /* "noprobe" */ case -1: /* "noprobe" */
hwif->noprobe = 1; hwif->noprobe = 1;
...@@ -2890,7 +2890,7 @@ static int init_irq (ide_hwif_t *hwif) ...@@ -2890,7 +2890,7 @@ static int init_irq (ide_hwif_t *hwif)
* Check for serialization with ide1. * Check for serialization with ide1.
* This code depends on us having already taken care of ide1. * This code depends on us having already taken care of ide1.
*/ */
if (serialized && hwif->name[3] == '0' && ide_hwifs[1].present) if (hwif->serialized && hwif->name[3] == '0' && ide_hwifs[1].present)
hwgroup = ide_hwifs[1].hwgroup; hwgroup = ide_hwifs[1].hwgroup;
/* /*
* If this is the first interface in a group, * If this is the first interface in a group,
...@@ -2941,23 +2941,14 @@ static struct file_operations ide_fops = { ...@@ -2941,23 +2941,14 @@ static struct file_operations ide_fops = {
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
void ide_pci_access_error (int rc) #if SUPPORT_RZ1000
{
printk("ide: pcibios access failed - %s\n", pcibios_strerror(rc));
}
#if SUPPORT_RZ1000 || SUPPORT_CMD640 static void ide_pci_access_error (int rc)
void buggy_interface_fallback (int rc)
{ {
ide_pci_access_error (rc); printk("ide: pcibios access failed - %s\n", pcibios_strerror(rc));
serialized = 1;
disallow_unmask = 1;
printk("serialized, disabled unmasking\n");
} }
#endif /* SUPPORT_RZ1000 || SUPPORT_CMD640 */
#if SUPPORT_RZ1000 static void init_rz1000 (byte bus, byte fn)
void init_rz1000 (byte bus, byte fn)
{ {
int rc; int rc;
unsigned short reg; unsigned short reg;
...@@ -2970,8 +2961,12 @@ void init_rz1000 (byte bus, byte fn) ...@@ -2970,8 +2961,12 @@ void init_rz1000 (byte bus, byte fn)
} else { } else {
if ((rc = pcibios_read_config_word(bus, fn, 0x40, &reg)) if ((rc = pcibios_read_config_word(bus, fn, 0x40, &reg))
|| (rc = pcibios_write_config_word(bus, fn, 0x40, reg & 0xdfff))) || (rc = pcibios_write_config_word(bus, fn, 0x40, reg & 0xdfff)))
buggy_interface_fallback (rc); {
else ide_pci_access_error (rc);
ide_hwifs[0].serialized = 1;
disallow_unmask = 1;
printk("serialized, disabled unmasking\n");
} else
printk("disabled read-ahead\n"); printk("disabled read-ahead\n");
} }
} }
...@@ -3012,7 +3007,7 @@ static void ide_init_pci (void) ...@@ -3012,7 +3007,7 @@ static void ide_init_pci (void)
/* /*
* Apparently the BIOS32 services on Intel motherboards are buggy, * Apparently the BIOS32 services on Intel motherboards are buggy,
* and won't find the PCI_DEVICE_ID_INTEL_82371_1 for us. * and won't find the PCI_DEVICE_ID_INTEL_82371_1 for us.
* So we instead search for PCI_DEVICE_ID_INTEL_82371_0, and then add 1. * So instead, we search for PCI_DEVICE_ID_INTEL_82371_0, and then add 1.
*/ */
ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371_0, &ide_init_triton, 1); ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371_0, &ide_init_triton, 1);
#endif #endif
...@@ -3038,8 +3033,11 @@ int ide_init (void) ...@@ -3038,8 +3033,11 @@ int ide_init (void)
if (pcibios_present()) if (pcibios_present())
ide_init_pci (); ide_init_pci ();
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
#if SUPPORT_CMD640 #ifdef CONFIG_BLK_DEV_CMD640
ide_probe_for_cmd640x(); {
extern void ide_probe_for_cmd640x (void);
ide_probe_for_cmd640x();
}
#endif #endif
/* /*
......
...@@ -37,9 +37,6 @@ ...@@ -37,9 +37,6 @@
#ifndef SUPPORT_RZ1000 /* 1 to support RZ1000 chipset */ #ifndef SUPPORT_RZ1000 /* 1 to support RZ1000 chipset */
#define SUPPORT_RZ1000 1 /* 0 to reduce kernel size */ #define SUPPORT_RZ1000 1 /* 0 to reduce kernel size */
#endif #endif
#ifndef SUPPORT_CMD640 /* 1 to support CMD640 chipset */
#define SUPPORT_CMD640 1 /* 0 to reduce kernel size */
#endif
#ifndef SUPPORT_UMC8672 /* 1 to support UMC8672 chipset */ #ifndef SUPPORT_UMC8672 /* 1 to support UMC8672 chipset */
#define SUPPORT_UMC8672 1 /* 0 to reduce kernel size */ #define SUPPORT_UMC8672 1 /* 0 to reduce kernel size */
#endif #endif
...@@ -59,6 +56,10 @@ ...@@ -59,6 +56,10 @@
#define FANCY_STATUS_DUMPS 1 /* 0 to reduce kernel size */ #define FANCY_STATUS_DUMPS 1 /* 0 to reduce kernel size */
#endif #endif
#if defined(CONFIG_BLK_DEV_IDECD) || defined(CONFIG_BLK_DEV_IDETAPE)
#define CONFIG_BLK_DEV_IDEATAPI 1
#endif
/* /*
* IDE_DRIVE_CMD is used to implement many features of the hdparm utility * IDE_DRIVE_CMD is used to implement many features of the hdparm utility
*/ */
...@@ -393,6 +394,7 @@ typedef struct hwif_s { ...@@ -393,6 +394,7 @@ typedef struct hwif_s {
char name[5]; /* name of interface, eg. "ide0" */ char name[5]; /* name of interface, eg. "ide0" */
unsigned noprobe : 1; /* don't probe for this interface */ unsigned noprobe : 1; /* don't probe for this interface */
unsigned present : 1; /* this interface exists */ unsigned present : 1; /* this interface exists */
unsigned serialized : 1; /* valid only for ide_hwifs[0] */
#if (DISK_RECOVERY_TIME > 0) #if (DISK_RECOVERY_TIME > 0)
unsigned long last_time; /* time when previous rq was done */ unsigned long last_time; /* time when previous rq was done */
#endif #endif
...@@ -603,4 +605,3 @@ void idetape_register_chrdev (void); ...@@ -603,4 +605,3 @@ void idetape_register_chrdev (void);
#ifdef CONFIG_BLK_DEV_TRITON #ifdef CONFIG_BLK_DEV_TRITON
void ide_init_triton (byte, byte); void ide_init_triton (byte, byte);
#endif /* CONFIG_BLK_DEV_TRITON */ #endif /* CONFIG_BLK_DEV_TRITON */
/* /*
* linux/drivers/block/triton.c Version 1.04 Dec 1, 1995 * linux/drivers/block/triton.c Version 1.05 Jan 11, 1996
* *
* Copyright (c) 1995 Mark Lord * Copyright (c) 1995-1996 Mark Lord
* May be copied or modified under the terms of the GNU General Public License * May be copied or modified under the terms of the GNU General Public License
*/ */
...@@ -95,11 +95,6 @@ ...@@ -95,11 +95,6 @@
* *
* And, yes, Intel Zappa boards really *do* use the Triton IDE ports. * And, yes, Intel Zappa boards really *do* use the Triton IDE ports.
*/ */
#define _TRITON_C
#include <linux/config.h>
#ifndef CONFIG_BLK_DEV_TRITON
#define CONFIG_BLK_DEV_TRITON y
#endif
#include <linux/types.h> #include <linux/types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/timer.h> #include <linux/timer.h>
...@@ -127,15 +122,15 @@ const char *good_dma_drives[] = {"Micropolis 2112A"}; ...@@ -127,15 +122,15 @@ const char *good_dma_drives[] = {"Micropolis 2112A"};
* Our Physical Region Descriptor (PRD) table should be large enough * Our Physical Region Descriptor (PRD) table should be large enough
* to handle the biggest I/O request we are likely to see. Since requests * to handle the biggest I/O request we are likely to see. Since requests
* can have no more than 256 sectors, and since the typical blocksize is * can have no more than 256 sectors, and since the typical blocksize is
* two sectors, we can get by with a limit of 128 entries here for the * two sectors, we could get by with a limit of 128 entries here for the
* usual worst case. Most requests seem to include some contiguous blocks, * usual worst case. Most requests seem to include some contiguous blocks,
* further reducing the number of table entries required. * further reducing the number of table entries required.
* *
* Note that the driver reverts to PIO mode for individual requests that exceed * The driver reverts to PIO mode for individual requests that exceed
* this limit (possible with 512 byte blocksizes, eg. MSDOS f/s), so handling * this limit (possible with 512 byte blocksizes, eg. MSDOS f/s), so handling
* 100% of all crazy scenarios here is not necessary. * 100% of all crazy scenarios here is not necessary.
* *
* As it turns out, though, we must allocate a full 4KB page for this, * As it turns out though, we must allocate a full 4KB page for this,
* so the two PRD tables (ide0 & ide1) will each get half of that, * so the two PRD tables (ide0 & ide1) will each get half of that,
* allowing each to have about 256 entries (8 bytes each) from this. * allowing each to have about 256 entries (8 bytes each) from this.
*/ */
...@@ -288,7 +283,7 @@ static int triton_dmaproc (ide_dma_action_t func, ide_drive_t *drive) ...@@ -288,7 +283,7 @@ static int triton_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
outl(virt_to_bus (HWIF(drive)->dmatable), dma_base + 4); /* PRD table */ outl(virt_to_bus (HWIF(drive)->dmatable), dma_base + 4); /* PRD table */
outb(reading, dma_base); /* specify r/w */ outb(reading, dma_base); /* specify r/w */
outb(0x26, dma_base+2); /* clear status bits */ outb(0x26, dma_base+2); /* clear status bits */
ide_set_handler (drive, &dma_intr, WAIT_CMD); /* issue cmd to drive */ ide_set_handler(drive, &dma_intr, WAIT_CMD); /* issue cmd to drive */
OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
outb(inb(dma_base)|1, dma_base); /* begin DMA */ outb(inb(dma_base)|1, dma_base); /* begin DMA */
return 0; return 0;
...@@ -316,6 +311,48 @@ static void print_triton_drive_flags (unsigned int unit, byte flags) ...@@ -316,6 +311,48 @@ static void print_triton_drive_flags (unsigned int unit, byte flags)
printk(" fastPIO=%s\n", ((flags&9)==1) ? "on " : "off"); printk(" fastPIO=%s\n", ((flags&9)==1) ? "on " : "off");
} }
static void init_triton_dma (ide_hwif_t *hwif, unsigned short base)
{
static unsigned long dmatable = 0;
printk(" %s: BusMaster DMA at 0x%04x-0x%04x", hwif->name, base, base+7);
if (check_region(base, 8)) {
printk(" -- ERROR, PORTS ALREADY IN USE");
} else {
request_region(base, 8, hwif->name);
hwif->dma_base = base;
if (!dmatable) {
/*
* Since we know we are on a PCI bus, we could
* actually use __get_free_pages() here instead
* of __get_dma_pages() -- no ISA limitations.
*/
dmatable = __get_dma_pages(GFP_KERNEL, 0);
}
if (dmatable) {
hwif->dmatable = (unsigned long *) dmatable;
dmatable += (PRD_ENTRIES * PRD_BYTES);
outl(virt_to_bus(hwif->dmatable), base + 4);
hwif->dmaproc = &triton_dmaproc;
}
}
printk("\n");
}
/*
* calc_mode() returns the ATA PIO mode number, based on the number
* of cycle clks passed in. Assumes 33Mhz bus operation (30ns per clk).
*/
byte calc_mode (byte clks)
{
if (clks == 3) return 5;
if (clks == 4) return 4;
if (clks < 6) return 3;
if (clks < 8) return 2;
if (clks < 13) return 1;
return 0;
}
/* /*
* ide_init_triton() prepares the IDE driver for DMA operation. * ide_init_triton() prepares the IDE driver for DMA operation.
* This routine is called once, from ide.c during driver initialization, * This routine is called once, from ide.c during driver initialization,
...@@ -324,26 +361,33 @@ static void print_triton_drive_flags (unsigned int unit, byte flags) ...@@ -324,26 +361,33 @@ static void print_triton_drive_flags (unsigned int unit, byte flags)
void ide_init_triton (byte bus, byte fn) void ide_init_triton (byte bus, byte fn)
{ {
int rc = 0, h; int rc = 0, h;
int dma_enabled = 0;
unsigned short bmiba, pcicmd; unsigned short bmiba, pcicmd;
unsigned int timings; unsigned int timings;
unsigned long dmatable = 0;
extern ide_hwif_t ide_hwifs[]; extern ide_hwif_t ide_hwifs[];
printk("ide: Triton BM-IDE on PCI bus %d function %d\n", bus, fn);
/* /*
* See if IDE and BM-DMA features are enabled: * See if IDE and BM-DMA features are enabled:
*/ */
if ((rc = pcibios_read_config_word(bus, fn, 0x04, &pcicmd))) if ((rc = pcibios_read_config_word(bus, fn, 0x04, &pcicmd)))
goto quit; goto quit;
if ((pcicmd & 5) != 5) { if ((pcicmd & 1) == 0) {
if ((pcicmd & 1) == 0) printk("ide: Triton IDE ports are not enabled\n");
printk("ide: Triton IDE ports are not enabled\n");
else
printk("ide: Triton BM-DMA feature is not enabled\n");
goto quit; goto quit;
} }
#if 0 if ((pcicmd & 4) == 0) {
(void) pcibios_write_config_word(bus, fn, 0x42, 0x8037); /* for my MC2112A */ printk("ide: Triton BM-DMA feature is not enabled -- upgrade your BIOS\n");
#endif } else {
/*
* Get the bmiba base address
*/
if ((rc = pcibios_read_config_word(bus, fn, 0x20, &bmiba)))
goto quit;
bmiba &= 0xfff0; /* extract port base address */
dma_enabled = 1;
}
/* /*
* See if ide port(s) are enabled * See if ide port(s) are enabled
*/ */
...@@ -353,52 +397,32 @@ void ide_init_triton (byte bus, byte fn) ...@@ -353,52 +397,32 @@ void ide_init_triton (byte bus, byte fn)
printk("ide: neither Triton IDE port is enabled\n"); printk("ide: neither Triton IDE port is enabled\n");
goto quit; goto quit;
} }
printk("ide: Triton BM-IDE on PCI bus %d function %d\n", bus, fn);
/*
* Get the bmiba base address
*/
if ((rc = pcibios_read_config_word(bus, fn, 0x20, &bmiba)))
goto quit;
bmiba &= 0xfff0; /* extract port base address */
/* /*
* Save the dma_base port addr for each interface * Save the dma_base port addr for each interface
*/ */
for (h = 0; h < MAX_HWIFS; ++h) { for (h = 0; h < MAX_HWIFS; ++h) {
byte s_clks, r_clks;
ide_hwif_t *hwif = &ide_hwifs[h]; ide_hwif_t *hwif = &ide_hwifs[h];
unsigned short base, time; unsigned short time;
if (hwif->io_base == 0x1f0 && (timings & 0x8000)) { if (hwif->io_base == 0x1f0) {
time = timings & 0xffff; time = timings & 0xffff;
base = bmiba; if ((timings & 0x8000) == 0) /* interface enabled? */
} else if (hwif->io_base == 0x170 && (timings & 0x80000000)) { continue;
if (dma_enabled)
init_triton_dma(hwif, bmiba);
} else if (hwif->io_base == 0x170) {
time = timings >> 16; time = timings >> 16;
base = bmiba + 8; if ((timings & 0x8000) == 0) /* interface enabled? */
continue;
if (dma_enabled)
init_triton_dma(hwif, bmiba + 8);
} else } else
continue; continue;
printk(" %s: BusMaster DMA at 0x%04x-0x%04x", hwif->name, base, base+7); s_clks = ((~time >> 12) & 3) + 2;
if (check_region(base, 8)) { r_clks = ((~time >> 8) & 3) + 1;
printk(" -- ERROR, PORTS ALREADY IN USE"); printk(" %s timing: (0x%04x) sample_CLKs=%d, recovery_CLKs=%d (PIO mode%d)\n",
} else { hwif->name, time, s_clks, r_clks, calc_mode(s_clks+r_clks));
request_region(base, 8, hwif->name);
hwif->dma_base = base;
if (!dmatable) {
/*
* Since we know we are on a PCI bus, we could
* actually use __get_free_pages() here instead
* of __get_dma_pages() -- no ISA limitations.
*/
dmatable = __get_dma_pages(GFP_KERNEL, 0);
}
if (dmatable) {
hwif->dmatable = (unsigned long *) dmatable;
dmatable += (PRD_ENTRIES * PRD_BYTES);
outl(virt_to_bus(hwif->dmatable), base + 4);
hwif->dmaproc = &triton_dmaproc;
}
}
printk("\n %s timing: (0x%04x) sample_CLKs=%d, recovery_CLKs=%d\n",
hwif->name, time, ((~time>>12)&3)+2, ((~time>>8)&3)+1);
print_triton_drive_flags (0, time & 0xf); print_triton_drive_flags (0, time & 0xf);
print_triton_drive_flags (1, (time >> 4) & 0xf); print_triton_drive_flags (1, (time >> 4) & 0xf);
} }
......
/* /*
* The Mitsumi CDROM interface * The Mitsumi CDROM interface
* Copyright (C) 1995 Heiko Schlittermann <heiko@lotte.sax.de> * Copyright (C) 1995 Heiko Schlittermann <heiko@lotte.sax.de>
* VERSION: 1.5 * VERSION: 1.5a
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#if RCS #if RCS
static const char *mcdx_c_version static const char *mcdx_c_version
= "mcdx.c,v 1.19 1995/11/20 17:06:25 heiko Exp"; = "mcdx.c,v 1.19.2.1 1996/01/13 21:25:55 heiko Exp";
#endif #endif
#include <linux/version.h> #include <linux/version.h>
...@@ -768,8 +768,10 @@ mcdx_close(struct inode *ip, struct file *fp) ...@@ -768,8 +768,10 @@ mcdx_close(struct inode *ip, struct file *fp)
/* invalidate_inodes(ip->i_rdev); */ /* invalidate_inodes(ip->i_rdev); */
invalidate_buffers(ip->i_rdev); invalidate_buffers(ip->i_rdev);
#if !MCDX_QUIET
if (-1 == mcdx_lockdoor(stuffp, 0, 3)) if (-1 == mcdx_lockdoor(stuffp, 0, 3))
INFO(("close() Cannot unlock the door\n")); INFO(("close() Cannot unlock the door\n"));
#endif
/* eject if wished */ /* eject if wished */
if (stuffp->eject_sw) mcdx_eject(stuffp, 1); if (stuffp->eject_sw) mcdx_eject(stuffp, 1);
...@@ -794,10 +796,8 @@ int check_mcdx_media_change(kdev_t full_dev) ...@@ -794,10 +796,8 @@ int check_mcdx_media_change(kdev_t full_dev)
void mcdx_setup(char *str, int *pi) void mcdx_setup(char *str, int *pi)
{ {
#if MCDX_DEBUG if (pi[0] > 0) mcdx_drive_map[0][0] = pi[1];
printk(MCDX ":: setup(%s, %d) called\n", if (pi[0] > 1) mcdx_drive_map[0][1] = pi[2];
str, pi[0]);
#endif
} }
/* DIRTY PART ******************************************************/ /* DIRTY PART ******************************************************/
...@@ -1051,10 +1051,10 @@ int mcdx_init(void) ...@@ -1051,10 +1051,10 @@ int mcdx_init(void)
{ {
int drive; int drive;
WARN(("Version 1.5 " WARN(("Version 1.5a "
"mcdx.c,v 1.19 1995/11/20 17:06:25 heiko Exp\n")); "mcdx.c,v 1.19.2.1 1996/01/13 21:25:55 heiko Exp\n"));
INFO((": Version 1.5 " INFO((": Version 1.5a "
"mcdx.c,v 1.19 1995/11/20 17:06:25 heiko Exp\n")); "mcdx.c,v 1.19.2.1 1996/01/13 21:25:55 heiko Exp\n"));
/* zero the pointer array */ /* zero the pointer array */
for (drive = 0; drive < MCDX_NDRIVES; drive++) for (drive = 0; drive < MCDX_NDRIVES; drive++)
...@@ -1245,7 +1245,7 @@ static int mcdx_transfer(struct s_drive_stuff *stuffp, ...@@ -1245,7 +1245,7 @@ static int mcdx_transfer(struct s_drive_stuff *stuffp,
stuffp->lock = current->pid; stuffp->lock = current->pid;
do { do {
int sig = 0; /* int sig = 0; */
int to = 0; int to = 0;
/* wait for the drive become idle */ /* wait for the drive become idle */
......
This diff is collapsed.
/* linux/drivers/cdrom/optcd_isp16.h - ISP16 CDROM interface configuration
$Id: optcd_isp16.h,v 1.3 1996/01/15 18:43:11 root Exp root $
Extracts from linux/drivers/cdrom/sjcd.c
For copyrights see linux/drivers/cdrom/optcd.c
*/
/* Some (Media)Magic */
/* define types of drive the interface on an ISP16 card may be looking at */
#define ISP16_DRIVE_X 0x00
#define ISP16_SONY 0x02
#define ISP16_PANASONIC0 0x02
#define ISP16_SANYO0 0x02
#define ISP16_MITSUMI 0x04
#define ISP16_PANASONIC1 0x06
#define ISP16_SANYO1 0x06
#define ISP16_DRIVE_NOT_USED 0x08 /* not used */
#define ISP16_DRIVE_SET_MASK 0xF1 /* don't change 0-bit or 4-7-bits*/
/* ...for port */
#define ISP16_DRIVE_SET_PORT 0xF8D
/* set io parameters */
#define ISP16_BASE_340 0x00
#define ISP16_BASE_330 0x40
#define ISP16_BASE_360 0x80
#define ISP16_BASE_320 0xC0
#define ISP16_IRQ_X 0x00
#define ISP16_IRQ_5 0x04 /* shouldn't be used due to soundcard conflicts */
#define ISP16_IRQ_7 0x08 /* shouldn't be used due to soundcard conflicts */
#define ISP16_IRQ_3 0x0C
#define ISP16_IRQ_9 0x10
#define ISP16_IRQ_10 0x14
#define ISP16_IRQ_11 0x18
#define ISP16_DMA_X 0x03
#define ISP16_DMA_3 0x00
#define ISP16_DMA_5 0x00
#define ISP16_DMA_6 0x01
#define ISP16_DMA_7 0x02
#define ISP16_IO_SET_MASK 0x20 /* don't change 5-bit */
/* ...for port */
#define ISP16_IO_SET_PORT 0xF8E
/* enable the card */
#define ISP16_C928__ENABLE_PORT 0xF90 /* ISP16 with OPTi 82C928 chip */
#define ISP16_C929__ENABLE_PORT 0xF91 /* ISP16 with OPTi 82C929 chip */
#define ISP16_ENABLE_CDROM 0x80 /* seven bit */
/* the magic stuff */
#define ISP16_CTRL_PORT 0xF8F
#define ISP16_C928__CTRL 0xE2 /* ISP16 with OPTi 82C928 chip */
#define ISP16_C929__CTRL 0xE3 /* ISP16 with OPTi 82C929 chip */
static short isp16_detect(void);
static short isp16_c928__detect(void);
static short isp16_c929__detect(void);
static short isp16_cdi_config( int base, u_char drive_type, int irq, int dma );
static void isp16_sound_config( void );
static short isp16_type; /* dependent on type of interface card */
static u_char isp16_ctrl;
static u_short isp16_enable_port;
/*static int sjcd_present = 0;*/
static u_char special_mask = 0;
static unsigned char defaults[ 16 ] = {
0xA8, 0xA8, 0x18, 0x18, 0x18, 0x18, 0x8E, 0x8E,
0x03, 0x00, 0x02, 0x00, 0x0A, 0x00, 0x00, 0x00
};
/* ------------- */
/*
* -- ISP16 detection and configuration
*
* Copyright (c) 1995, Eric van der Maarel <maarel@marin.nl>
*
* Version 0.5
*
* Detect cdrom interface on ISP16 soundcard.
* Configure cdrom interface.
* Configure sound interface.
*
* Algorithm for the card with OPTi 82C928 taken
* from the CDSETUP.SYS driver for MSDOS,
* by OPTi Computers, version 2.03.
* Algorithm for the card with OPTi 82C929 as communicated
* to me by Vadim Model and Leo Spiekman.
*
* Use, modifification or redistribution of this software is
* allowed under the terms of the GPL.
*
*/
#define ISP16_IN(p) (outb(isp16_ctrl,ISP16_CTRL_PORT), inb(p))
#define ISP16_OUT(p,b) (outb(isp16_ctrl,ISP16_CTRL_PORT), outb(b,p))
static short
isp16_detect(void)
{
if ( !( isp16_c929__detect() < 0 ) )
return(2);
else
return( isp16_c928__detect() );
}
static short
isp16_c928__detect(void)
{
u_char ctrl;
u_char enable_cdrom;
u_char io;
short i = -1;
isp16_ctrl = ISP16_C928__CTRL;
isp16_enable_port = ISP16_C928__ENABLE_PORT;
/* read' and write' are a special read and write, respectively */
/* read' ISP16_CTRL_PORT, clear last two bits and write' back the result */
ctrl = ISP16_IN( ISP16_CTRL_PORT ) & 0xFC;
ISP16_OUT( ISP16_CTRL_PORT, ctrl );
/* read' 3,4 and 5-bit from the cdrom enable port */
enable_cdrom = ISP16_IN( ISP16_C928__ENABLE_PORT ) & 0x38;
if ( !(enable_cdrom & 0x20) ) { /* 5-bit not set */
/* read' last 2 bits of ISP16_IO_SET_PORT */
io = ISP16_IN( ISP16_IO_SET_PORT ) & 0x03;
if ( ((io&0x01)<<1) == (io&0x02) ) { /* bits are the same */
if ( io == 0 ) { /* ...the same and 0 */
i = 0;
enable_cdrom |= 0x20;
}
else { /* ...the same and 1 */ /* my card, first time 'round */
i = 1;
enable_cdrom |= 0x28;
}
ISP16_OUT( ISP16_C928__ENABLE_PORT, enable_cdrom );
}
else { /* bits are not the same */
ISP16_OUT( ISP16_CTRL_PORT, ctrl );
return(i); /* -> not detected: possibly incorrect conclusion */
}
}
else if ( enable_cdrom == 0x20 )
i = 0;
else if ( enable_cdrom == 0x28 ) /* my card, already initialised */
i = 1;
ISP16_OUT( ISP16_CTRL_PORT, ctrl );
return(i);
}
static short
isp16_c929__detect(void)
{
u_char ctrl;
u_char tmp;
isp16_ctrl = ISP16_C929__CTRL;
isp16_enable_port = ISP16_C929__ENABLE_PORT;
/* read' and write' are a special read and write, respectively */
/* read' ISP16_CTRL_PORT and save */
ctrl = ISP16_IN( ISP16_CTRL_PORT );
/* write' zero to the ctrl port and get response */
ISP16_OUT( ISP16_CTRL_PORT, 0 );
tmp = ISP16_IN( ISP16_CTRL_PORT );
if ( tmp != 2 ) /* isp16 with 82C929 not detected */
return(-1);
/* restore ctrl port value */
ISP16_OUT( ISP16_CTRL_PORT, ctrl );
return(2);
}
static short
isp16_cdi_config( int base, u_char drive_type, int irq, int dma )
{
u_char base_code;
u_char irq_code;
u_char dma_code;
u_char i;
if ( (drive_type == ISP16_MITSUMI) && (dma != 0) )
printk( "Mitsumi cdrom drive has no dma support.\n" );
switch (base) {
case 0x340: base_code = ISP16_BASE_340; break;
case 0x330: base_code = ISP16_BASE_330; break;
case 0x360: base_code = ISP16_BASE_360; break;
case 0x320: base_code = ISP16_BASE_320; break;
default:
printk( "Base address 0x%03X not supported by cdrom interface on ISP16.\n", base );
return(-1);
}
switch (irq) {
case 0: irq_code = ISP16_IRQ_X; break; /* disable irq */
case 5: irq_code = ISP16_IRQ_5;
printk( "Irq 5 shouldn't be used by cdrom interface on ISP16,"
" due to possible conflicts with the soundcard.\n");
break;
case 7: irq_code = ISP16_IRQ_7;
printk( "Irq 7 shouldn't be used by cdrom interface on ISP16,"
" due to possible conflicts with the soundcard.\n");
break;
case 3: irq_code = ISP16_IRQ_3; break;
case 9: irq_code = ISP16_IRQ_9; break;
case 10: irq_code = ISP16_IRQ_10; break;
case 11: irq_code = ISP16_IRQ_11; break;
default:
printk( "Irq %d not supported by cdrom interface on ISP16.\n", irq );
return(-1);
}
switch (dma) {
case 0: dma_code = ISP16_DMA_X; break; /* disable dma */
case 1: printk( "Dma 1 cannot be used by cdrom interface on ISP16,"
" due to conflict with the soundcard.\n");
return(-1); break;
case 3: dma_code = ISP16_DMA_3; break;
case 5: dma_code = ISP16_DMA_5; break;
case 6: dma_code = ISP16_DMA_6; break;
case 7: dma_code = ISP16_DMA_7; break;
default:
printk( "Dma %d not supported by cdrom interface on ISP16.\n", dma );
return(-1);
}
if ( drive_type != ISP16_SONY && drive_type != ISP16_PANASONIC0 &&
drive_type != ISP16_PANASONIC1 && drive_type != ISP16_SANYO0 &&
drive_type != ISP16_SANYO1 && drive_type != ISP16_MITSUMI &&
drive_type != ISP16_DRIVE_X ) {
printk( "Drive type (code 0x%02X) not supported by cdrom"
" interface on ISP16.\n", drive_type );
return(-1);
}
/* set type of interface */
i = ISP16_IN(ISP16_DRIVE_SET_PORT) & ISP16_DRIVE_SET_MASK; /* clear some bits */
ISP16_OUT( ISP16_DRIVE_SET_PORT, i|drive_type );
/* enable cdrom on interface with 82C929 chip */
if ( isp16_type > 1 )
ISP16_OUT( isp16_enable_port, ISP16_ENABLE_CDROM );
/* set base address, irq and dma */
i = ISP16_IN(ISP16_IO_SET_PORT) & ISP16_IO_SET_MASK; /* keep some bits */
ISP16_OUT( ISP16_IO_SET_PORT, i|base_code|irq_code|dma_code );
return(0);
}
static void isp16_sound_config( void )
{
int i;
u_char saved;
saved = ISP16_IN( 0xF8D ) & 0x8F;
ISP16_OUT( 0xF8D, 0x40 );
/*
* Now we should wait for a while...
*/
for( i = 16*1024; i--; );
ISP16_OUT( 0xF8D, saved );
ISP16_OUT( 0xF91, 0x1B );
for( i = 5*64*1024; i != 0; i-- )
if( !( inb( 0x534 ) & 0x80 ) ) break;
if( i > 0 ) {
saved = ( inb( 0x534 ) & 0xE0 ) | 0x0A;
outb( saved, 0x534 );
special_mask = ( inb( 0x535 ) >> 4 ) & 0x08;
saved = ( inb( 0x534 ) & 0xE0 ) | 0x0C;
outb( saved, 0x534 );
switch( inb( 0x535 ) ) {
case 0x09:
case 0x0A:
special_mask |= 0x05;
break;
case 0x8A:
special_mask = 0x0F;
break;
default:
i = 0;
}
}
if ( i == 0 ) {
printk( "Strange MediaMagic, but\n" );
}
else {
printk( "Conf:" );
saved = inb( 0x534 ) & 0xE0;
for( i = 0; i < 16; i++ ) {
outb( 0x20 | ( u_char )i, 0x534 );
outb( defaults[i], 0x535 );
}
for ( i = 0; i < 16; i++ ) {
outb( 0x20 | ( u_char )i, 0x534 );
saved = inb( 0x535 );
printk( " %02X", saved );
}
printk( "\n" );
}
ISP16_OUT( 0xF91, 0xA0 | special_mask );
/*
* The following have no explaination yet.
*/
ISP16_OUT( 0xF90, 0xA2 );
ISP16_OUT( 0xF92, 0x03 );
/*
* Turn general sound on and set total volume.
*/
ISP16_OUT( 0xF93, 0x0A );
/*
outb( 0x04, 0x224 );
saved = inb( 0x225 );
outb( 0x04, 0x224 );
outb( saved, 0x225 );
*/
}
...@@ -48,3 +48,4 @@ if [ "$CONFIG_WATCHDOG" = "y" ]; then ...@@ -48,3 +48,4 @@ if [ "$CONFIG_WATCHDOG" = "y" ]; then
bool ' Software Watchdog' CONFIG_SOFT_WATCHDOG bool ' Software Watchdog' CONFIG_SOFT_WATCHDOG
fi fi
fi fi
endmenu
...@@ -95,6 +95,7 @@ endif ...@@ -95,6 +95,7 @@ endif
ifdef CONFIG_SOFT_WATCHDOG ifdef CONFIG_SOFT_WATCHDOG
L_OBJS += softdog.o L_OBJS += softdog.o
M = y M = y
# This is not modularized, so if configured then "mouse.c" will be resident
endif endif
ifdef CONFIG_QIC02_TAPE ifdef CONFIG_QIC02_TAPE
...@@ -106,16 +107,20 @@ LX_OBJS += apm_bios.o ...@@ -106,16 +107,20 @@ LX_OBJS += apm_bios.o
endif endif
ifdef M ifdef M
L_OBJS += mouse.o LX_OBJS += mouse.o
else else
ifdef MM ifdef MM
M_OBJS += mouse.o MX_OBJS += mouse.o
endif endif
endif endif
ifdef CONFIG_SCC ifeq ($(CONFIG_SCC),y)
L_OBJS += scc.o L_OBJS += scc.o
endif else
ifeq ($(CONFIG_SCC),m)
M_OBJS += scc.o
endif
endif
ifdef CONFIG_TGA_CONSOLE ifdef CONFIG_TGA_CONSOLE
L_OBJS += tga.o L_OBJS += tga.o
......
/* /* -*- linux-c -*-
* APM BIOS driver for Linux * APM BIOS driver for Linux
* Copyright 1994, 1995 Stephen Rothwell (Stephen.Rothwell@pd.necisa.oz.au) * Copyright 1994, 1995 Stephen Rothwell (Stephen.Rothwell@pd.necisa.oz.au)
* *
...@@ -16,6 +16,10 @@ ...@@ -16,6 +16,10 @@
* *
* October 1995, Rik Faith (faith@cs.unc.edu): * October 1995, Rik Faith (faith@cs.unc.edu):
* Minor enhancements and updates (to the patch set) for 1.3.x * Minor enhancements and updates (to the patch set) for 1.3.x
* Documentation
* January 1996, Rik Faith (faith@cs.unc.edu):
* Make /proc/apm easy to format (bump driver version)
*
* *
* Reference: * Reference:
* *
...@@ -24,9 +28,9 @@ ...@@ -24,9 +28,9 @@
* Intel Order Number 241704-001. Microsoft Part Number 781-110-X01. * Intel Order Number 241704-001. Microsoft Part Number 781-110-X01.
* *
* [This document is available free from Intel by calling 800.628.8686 (fax * [This document is available free from Intel by calling 800.628.8686 (fax
* 916.356.6100) or 800.548.4725. It is also available from Microsoft by * 916.356.6100) or 800.548.4725; or via anonymous ftp from
* calling 206.882.8080; and is ftpable from * ftp://ftp.intel.com/pub/IAL/software_specs/apmv11.doc. It is also
* ftp://ftp.intel.com/pub/IAL/software_specs/apmv11.doc] * available from Microsoft by calling 206.882.8080.]
* *
*/ */
...@@ -288,7 +292,7 @@ static struct apm_bios_struct * user_list = NULL; ...@@ -288,7 +292,7 @@ static struct apm_bios_struct * user_list = NULL;
static struct timer_list apm_timer; static struct timer_list apm_timer;
static char driver_version[] = "0.6b"; static char driver_version[] = "0.7";/* no spaces */
#ifdef APM_DEBUG #ifdef APM_DEBUG
static char * apm_event_name[] = { static char * apm_event_name[] = {
...@@ -882,69 +886,91 @@ static int do_open(struct inode * inode, struct file * filp) ...@@ -882,69 +886,91 @@ static int do_open(struct inode * inode, struct file * filp)
int apm_proc(char *buf) int apm_proc(char *buf)
{ {
char * p; char * p;
char * power_stat;
char * bat_stat;
unsigned short bx; unsigned short bx;
unsigned short cx; unsigned short cx;
unsigned short dx; unsigned short dx;
unsigned short error; unsigned short error;
unsigned short ac_line_status = 0xff;
unsigned short battery_status = 0xff;
unsigned short battery_flag = 0xff;
unsigned short percentage = -1;
int time_units = -1;
char *units = "?";
if (apm_bios_info.version == 0) if (apm_bios_info.version == 0)
return 0; return 0;
p = buf; p = buf;
p += sprintf(p, "BIOS version: %d.%d\nFlags: 0x%02x\n",
(apm_bios_info.version >> 8) & 0xff, if ((apm_bios_info.flags & APM_32_BIT_SUPPORT) != 0) {
apm_bios_info.version & 0xff, if (!(error = apm_get_power_status(&bx, &cx, &dx))) {
apm_bios_info.flags); ac_line_status = (bx >> 8) & 0xff;
if ((apm_bios_info.flags & APM_32_BIT_SUPPORT) == 0) battery_status = bx & 0xff;
return p - buf; if ((cx & 0xff) != 0xff)
p += sprintf(p, "Entry %x:%lx cseg16 %x dseg %x", percentage = cx & 0xff;
apm_bios_info.cseg, apm_bios_info.offset,
apm_bios_info.cseg_16, apm_bios_info.dseg); if (apm_bios_info.version > 0x100) {
if (apm_bios_info.version > 0x100) battery_flag = (cx >> 8) & 0xff;
p += sprintf(p, " cseg len %x, dseg len %x", if (dx != 0xffff) {
apm_bios_info.cseg_len, apm_bios_info.dseg_len); if ((dx & 0x8000) == 0x8000) {
*p++ = '\n'; units = "min";
error = apm_get_power_status(&bx, &cx, &dx); time_units = dx & 0x7ffe;
if (error) { } else {
strcpy(p, "Power status not available\n"); units = "sec";
p += strlen(p); time_units = dx & 0x7fff;
return p - buf; }
} }
switch ((bx >> 8) & 0xff) { }
case 0: power_stat = "off line"; break;
case 1: power_stat = "on line"; break;
case 2: power_stat = "on backup power"; break;
default: power_stat = "unknown"; break;
}
switch (bx & 0xff) {
case 0: bat_stat = "high"; break;
case 1: bat_stat = "low"; break;
case 2: bat_stat = "critical"; break;
case 3: bat_stat = "charging"; break;
default: bat_stat = "unknown"; break;
}
p += sprintf(p, "AC: %s\nBattery status: %s\nBattery life: ",
power_stat, bat_stat);
if ((cx & 0xff) == 0xff) {
strcpy(p, "unknown");
p += strlen(p);
} else
p += sprintf(p, "%d%%", cx & 0xff);
*p++ = '\n';
if (apm_bios_info.version > 0x100) {
p += sprintf(p, "Battery flag: 0x%02x\nBattery life: ",
(cx >> 8) & 0xff);
if (dx == 0xffff) {
strcpy(p, "unknown");
p += strlen(p);
} }
else
p += sprintf(p, "%d %s", dx & 0x7fff,
((dx & 0x8000) == 0)
? "seconds" : "minutes");
*p++ = '\n';
} }
/* Arguments, with symbols from linux/apm_bios.h. Information is
from the Get Power Status (0x0a) call unless otherwise noted.
0) Linux driver version (this will change if format changes)
1) APM BIOS Version. Usually 1.0 or 1.1.
2) APM flags from APM Installation Check (0x00):
bit 0: APM_16_BIT_SUPPORT
bit 1: APM_32_BIT_SUPPORT
bit 2: APM_IDLE_SLOWS_CLOCK
bit 3: APM_BIOS_DISABLED
bit 4: APM_BIOS_DISENGAGED
3) AC line status
0x00: Off-line
0x01: On-line
0x02: On backup power (APM BIOS 1.1 only)
0xff: Unknown
4) Battery status
0x00: High
0x01: Low
0x02: Critical
0x03: Charging
0xff: Unknown
5) Battery flag
bit 0: High
bit 1: Low
bit 2: Critical
bit 3: Charging
bit 7: No system battery
0xff: Unknown
6) Remaining battery life (percentage of charge):
0-100: valid
-1: Unknown
7) Remaining battery life (time units):
Number of remaining minutes or seconds
-1: Unknown
8) min = minutes; sec = seconds */
p += sprintf(p, "%s %d.%d 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n",
driver_version,
(apm_bios_info.version >> 8) & 0xff,
apm_bios_info.version & 0xff,
apm_bios_info.flags,
ac_line_status,
battery_status,
battery_flag,
percentage,
time_units,
units );
return p - buf; return p - buf;
} }
...@@ -1000,12 +1026,12 @@ static int apm_setup(void) ...@@ -1000,12 +1026,12 @@ static int apm_setup(void)
set_limit(gdt[APM_DS >> 3], 64 * 1024); set_limit(gdt[APM_DS >> 3], 64 * 1024);
} else { } else {
set_limit(gdt[APM_CS >> 3], apm_bios_info.cseg_len); set_limit(gdt[APM_CS >> 3], apm_bios_info.cseg_len);
/* /* This is not clear from the spec, but at least one
* This is not clear from the spec, but at least one machine needs CS_16 to be a 64k segment, and the DEC
* machine needs this to be a 64k segment. Hinote Ultra CT475 (and others?) needs DS to be a 64k
*/ segment. */
set_limit(gdt[APM_CS_16 >> 3], 64 * 1024); set_limit(gdt[APM_CS_16 >> 3], 64 * 1024);
set_limit(gdt[APM_DS >> 3], apm_bios_info.dseg_len); set_limit(gdt[APM_DS >> 3], 64 * 1024);
apm_bios_info.version = 0x0101; apm_bios_info.version = 0x0101;
error = apm_driver_version(&apm_bios_info.version); error = apm_driver_version(&apm_bios_info.version);
if (error != 0) if (error != 0)
...@@ -1047,10 +1073,12 @@ static int apm_setup(void) ...@@ -1047,10 +1073,12 @@ static int apm_setup(void)
(cx >> 8) & 0xff); (cx >> 8) & 0xff);
if (dx == 0xffff) if (dx == 0xffff)
printk("unknown\n"); printk("unknown\n");
else else {
printk("%d %s\n", dx & 0x7fff, if ((dx & 0x8000))
((dx & 0x8000) == 0) printk("%d minutes\n", dx & 0x7ffe );
? "seconds" : "minutes"); else
printk("%d seconds\n", dx & 0x7fff );
}
} }
} }
......
This diff is collapsed.
...@@ -104,6 +104,14 @@ void cleanup_module(void) ...@@ -104,6 +104,14 @@ void cleanup_module(void)
#endif #endif
static struct symbol_table mouse_syms = {
/* Should this be surrounded with "#ifdef CONFIG_MODULES" ? */
#include <linux/symtab_begin.h>
X(mouse_register),
X(mouse_deregister),
#include <linux/symtab_end.h>
};
int mouse_init(void) int mouse_init(void)
{ {
#ifndef MODULE #ifndef MODULE
...@@ -128,5 +136,6 @@ int mouse_init(void) ...@@ -128,5 +136,6 @@ int mouse_init(void)
MOUSE_MAJOR); MOUSE_MAJOR);
return -EIO; return -EIO;
} }
return 0;
return register_symtab(&mouse_syms);
} }
...@@ -421,6 +421,9 @@ set_get_cmap(unsigned char * arg, int set) { ...@@ -421,6 +421,9 @@ set_get_cmap(unsigned char * arg, int set) {
* dummy routines for the VESA blanking code, which is VGA only, * dummy routines for the VESA blanking code, which is VGA only,
* so we don't have to carry that stuff around for the TGA... * so we don't have to carry that stuff around for the TGA...
*/ */
void vesa_powerdown(void)
{
}
void vesa_blank(void) void vesa_blank(void)
{ {
} }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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