Commit aa66269c authored by Linus Torvalds's avatar Linus Torvalds

Import 1.3.98

parent 0da8dd36
This diff is collapsed.
File Locking Release Notes
Andy Walker <andy@lysaker.kvaerner.no>
15 April 1996
What's New?
-----------
Flock Emulation Warnings
------------------------
Many people will have noticed the ugly messages that the file locking
code started generating with the release of kernel version 1.3.95. The
messages look something like this:
fcntl_setlk() called by process XX with broken flock() emulation
This is a warning for people using older C libraries that those libraries
are still calling the pre 1.3.x flock() emulation routines, instead of
the real flock() system call. The old routines are quite badly broken,
especially with respect to parent-child lock sharing, and can give bad
results if, for example, sendmail attempts to use them.
Fixed versions of the C libraries have been on public release for many
months. The latest versions are 5.2.18 or 5.3.12 for ELF, and I believe
somebody made a 4.7.6 release for people using a.out systems.
In 1.3.96 Linus decided to be lenient on the stragglers and changed the
warning message so that the kernel will only complain five times and
then shut up. That should make life more bearable even for people who,
for some reason, don't want to upgrade.
Sendmail Problems
-----------------
Because sendmail was unable to use the old flock() emulation, many sendmail
installations use fcntl() instead of flock(). This is true of Slackware 3.0
for example. This gave rise to some other subtle problems if sendmail was
configured to rebuild the alias file. Sendmail tried to lock the aliases.dir
file with fcntl() at the same time as the GDBM routines tried to lock this
file with flock(). With pre 1.3.96 kernels this could result in deadlocks that,
over time, or under a very heavy mail load, would eventually cause the kernel
to lock solid with deadlocked processes.
I have chosen the rather cruel solution of returning an error when such a
deadlock would occur. I can't see any other way to handle this situation
gracefully. The other options are to maintain two entirely separate lists
for flock() and fcntl() locks, thus defeating any protection between the
two, or to free locks placed by one method when the same process later
tries to lock the same file by the other method. Neither option seems
satisfactory.
Some programs may break (again, groan). In particular the aforementioned
sendmail may have problems running in 'newaliases' mode. It will no longer
deadlock though. Recompile sendmail to use flock() and your troubles will
be over.
NCSA telnet doesn't work with path MTU discovery enabled. This is due to a
bug in NCSA that also stops it working with other modern networking code
such as Solaris.
The following information is courtesy of
Marek <marekm@i17linuxb.ists.pwr.wroc.pl>
There is a fixed version somewhere on ftp.upe.ac.za (sorry, I don't
remember the exact pathname, and this site is very slow from here).
It may or may not be faster for you to get it from
ftp://ftp.ists.pwr.wroc.pl/pub/msdos/telnet/ncsa_upe/tel23074.zip
(source is in v230704s.zip). I have tested it with 1.3.79 (with
path mtu discovery enabled - ncsa 2.3.08 didn't work) and it seems
to work. I don't know if anyone is working on this code - this
version is over a year old. Too bad - it's faster and often more
stable than these windoze telnets, and runs on almost anything...
From: Linus Torvalds <torvalds@cs.helsinki.fi>
How to track down an Oops.. [originally a mail to linux-kernel]
The main trick is having 5 years of experience with those pesky oops
messages ;-)
Actually, there are things you can do that make this easier. I have two
separate approached:
gdb /usr/src/linux/vmlinux
gdb> disassemble <offending_function>
That's the easy way to find the problem, at least if the bug-report is
well made (like this one was - run through ksymoops to get the
information of which function and the offset in the function that it
happened in).
Oh, it helps if the report happens on a kernel that is compiled with the
same compiler and similar setups.
The other thing to do is disassemble the "Code:" part of the bugreprot:
ksymoops will do this too with the correct tools (and new version of
ksymoops), but if you don't have the tools you can just do a silly
program:
char str[] = "\xXX\xXX\xXX...";
main(){}
and compile it with gcc -g and then do "disassemble str" (where the "XX"
stuff are the values reported by the Oops - you can just cut-and-paste
and do a replace of spaces to "\x" - that's what I do, as I'm too lazy
to write a prigram to automate this all).
Finally, if you want to see where the code comes from, you can do
cd /usr/src/linux
make fs/buffer.s # or whatever file the bug happened in
and then you get a better idea of what happens than with the gdb
disassembly.
Now, the trick is just then to combine all the data you have: the C
sources (and general knowledge of what it _should_ do, the assembly
listing and the code disassembly (and additionally the register dump you
also get from the "oops" message - that can be useful to see _what_ the
corrupted pointers were, and when you have the assembler listing you can
also match the other registers to whatever C expressions they were used
for).
Essentially, you just look at what doesn't match (in this case it was the
"Code" disassembly that didn't match with what the compiler generated).
Then you need to find out _why_ they don't match. Often it's simple - you
see that the code uses a NULL pointer and then you look at the code and
wonder how the NULL pointer got there, and if it's a valid thing to do
you just check against it..
Now, if somebody gets the idea that this is time-consuming and requires
some small amount of concentration, you're right. Which is why I will
mostly just ignore any panic reports that don't have the symbol table
info etc looked up: it simply gets too hard to look it up (I have some
programs to search for specific patterns in the kernel code segment, and
sometimes I have been able to look up those kinds of panics too, but
that really requires pretty good knowledge of the kernel just to be able
to pick out the right sequences etc..)
_Sometimes_ it happens that I just see the disassembled code sequence
from the panic, and I know immediately where it's coming from. That's when
I get worried that I've been doing this for too long ;-)
Linus
...@@ -36,7 +36,7 @@ uses minor #1, so start with ram2 and go from there. ...@@ -36,7 +36,7 @@ uses minor #1, so start with ram2 and go from there.
The old "ramdisk=<ram_size>" has been changed to "ramdisk_size=<ram_size>" The old "ramdisk=<ram_size>" has been changed to "ramdisk_size=<ram_size>"
to make it clearer. The original "ramdisk=<ram_size>" has been kept around to make it clearer. The original "ramdisk=<ram_size>" has been kept around
for compatiblity reasons, but it will probably be removed in 2.1.x. for compatibility reasons, but it will probably be removed in 2.1.x.
The new ramdisk also has the ability to load compressed ramdisk images, The new ramdisk also has the ability to load compressed ramdisk images,
allowing one to squeeze more programs onto an average installation or allowing one to squeeze more programs onto an average installation or
......
...@@ -45,7 +45,15 @@ Programming and/or enabling interrupt frequencies greater than 64Hz is ...@@ -45,7 +45,15 @@ Programming and/or enabling interrupt frequencies greater than 64Hz is
only allowed by root. This is perhaps a bit conservative, but we don't want only allowed by root. This is perhaps a bit conservative, but we don't want
an evil user generating lots of IRQs on a slow 386sx-16, where it might have an evil user generating lots of IRQs on a slow 386sx-16, where it might have
a negative impact on performance. Note that the interrupt handler is only a negative impact on performance. Note that the interrupt handler is only
four lines of code to minimize any possibility of this effect. a few lines of code to minimize any possibility of this effect.
Also, if the kernel time is synchronized with an external source, the
kernel will write the time back to the CMOS clock every 11 minutes. In
the process of doing this, the kernel briefly turns off RTC periodic
interrupts, so be aware of this if you are doing serious work. If you
don't synchronize the kernel time with an external source (via ntp or
whatever) then the kernel will keep its hands off the RTC, allowing you
exclusive access to the device for your applications.
The alarm and/or interrupt frequency are programmed into the RTC via The alarm and/or interrupt frequency are programmed into the RTC via
various ioctl(2) calls as listed in ./include/linux/mc146818rtc.h various ioctl(2) calls as listed in ./include/linux/mc146818rtc.h
......
...@@ -65,8 +65,8 @@ S: Status, one of the following: ...@@ -65,8 +65,8 @@ S: Status, one of the following:
Orphan: No current maintainer [but maybe you could take the Orphan: No current maintainer [but maybe you could take the
role as you write your new code]. role as you write your new code].
Obsolete: Old code. Something tagged obsolete generally means Obsolete: Old code. Something tagged obsolete generally means
its been replaced by a better system and you should it has been replaced by a better system and you
be using that. should be using that.
3C501 NETWORK DRIVER 3C501 NETWORK DRIVER
P: Alan Cox P: Alan Cox
......
VERSION = 1 VERSION = 1
PATCHLEVEL = 3 PATCHLEVEL = 3
SUBLEVEL = 97 SUBLEVEL = 98
ARCH = i386 ARCH = i386
......
...@@ -9,6 +9,11 @@ unset CONFIG_CROSSCOMPILE CONFIG_NATIVE ...@@ -9,6 +9,11 @@ unset CONFIG_CROSSCOMPILE CONFIG_NATIVE
unset CONFIG_PCI CONFIG_ALPHA_LCA CONFIG_ALPHA_APECS unset CONFIG_PCI CONFIG_ALPHA_LCA CONFIG_ALPHA_APECS
unset CONFIG_ALPHA_NEED_ROUNDING_EMULATION unset CONFIG_ALPHA_NEED_ROUNDING_EMULATION
mainmenu_option next_comment
comment 'Code maturity level options'
bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
endmenu
mainmenu_option next_comment mainmenu_option next_comment
comment 'Loadable module support' comment 'Loadable module support'
bool 'Enable loadable module support' CONFIG_MODULES bool 'Enable loadable module support' CONFIG_MODULES
......
...@@ -2,6 +2,11 @@ ...@@ -2,6 +2,11 @@
# Automatically generated make config: don't edit # Automatically generated make config: don't edit
# #
#
# Code maturity level options
#
# CONFIG_EXPERIMENTAL is not set
# #
# Loadable module support # Loadable module support
# #
...@@ -75,7 +80,6 @@ CONFIG_SKB_LARGE=y ...@@ -75,7 +80,6 @@ CONFIG_SKB_LARGE=y
# CONFIG_IPX is not set # CONFIG_IPX is not set
# CONFIG_ATALK is not set # CONFIG_ATALK is not set
# CONFIG_AX25 is not set # CONFIG_AX25 is not set
# CONFIG_BRIDGE is not set
# CONFIG_NETLINK is not set # CONFIG_NETLINK is not set
# #
...@@ -133,25 +137,21 @@ CONFIG_SCSI_NCR53C7xx_FAST=y ...@@ -133,25 +137,21 @@ CONFIG_SCSI_NCR53C7xx_FAST=y
# #
CONFIG_NETDEVICES=y CONFIG_NETDEVICES=y
CONFIG_DUMMY=m CONFIG_DUMMY=m
# CONFIG_SLIP is not set
# CONFIG_PPP is not set
# CONFIG_STRIP is not set
# CONFIG_WIC is not set
# CONFIG_SCC is not set
# CONFIG_PLIP is not set
# CONFIG_EQUALIZER is not set # CONFIG_EQUALIZER is not set
# CONFIG_DLCI is not set # CONFIG_PLIP is not set
# CONFIG_NET_ALPHA is not set # CONFIG_PPP is not set
# CONFIG_NET_VENDOR_SMC is not set # CONFIG_SLIP is not set
# CONFIG_LANCE is not set # CONFIG_NET_RADIO is not set
CONFIG_NET_ETHERNET=y
# CONFIG_NET_VENDOR_3COM is not set # CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_ISA is not set # CONFIG_NET_ISA is not set
CONFIG_NET_EISA=y CONFIG_NET_EISA=y
# CONFIG_APRICOT is not set # CONFIG_APRICOT is not set
CONFIG_DE4X5=y CONFIG_DE4X5=y
# CONFIG_DEC_ELCP is not set # CONFIG_DEC_ELCP is not set
# CONFIG_DGRS is not set # CONFIG_DGRS is not set
# CONFIG_ZNET is not set
# CONFIG_NET_POCKET is not set # CONFIG_NET_POCKET is not set
# CONFIG_TR is not set # CONFIG_TR is not set
# CONFIG_ARCNET is not set # CONFIG_ARCNET is not set
......
...@@ -510,8 +510,10 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, ...@@ -510,8 +510,10 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data,
return -EPERM; return -EPERM;
if ((!child->dumpable || if ((!child->dumpable ||
(current->uid != child->euid) || (current->uid != child->euid) ||
(current->uid != child->suid) ||
(current->uid != child->uid) || (current->uid != child->uid) ||
(current->gid != child->egid) || (current->gid != child->egid) ||
(current->gid != child->sgid) ||
(current->gid != child->gid)) && !suser()) (current->gid != child->gid)) && !suser())
return -EPERM; return -EPERM;
/* the same process cannot be attached many times */ /* the same process cannot be attached many times */
......
...@@ -4,6 +4,11 @@ ...@@ -4,6 +4,11 @@
# #
mainmenu_name "Linux Kernel Configuration" mainmenu_name "Linux Kernel Configuration"
mainmenu_option next_comment
comment 'Code maturity level options'
bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
endmenu
mainmenu_option next_comment mainmenu_option next_comment
comment 'Loadable module support' comment 'Loadable module support'
bool 'Enable loadable module support' CONFIG_MODULES bool 'Enable loadable module support' CONFIG_MODULES
......
...@@ -2,6 +2,11 @@ ...@@ -2,6 +2,11 @@
# Automatically generated make config: don't edit # Automatically generated make config: don't edit
# #
#
# Code maturity level options
#
# CONFIG_EXPERIMENTAL is not set
# #
# Loadable module support # Loadable module support
# #
...@@ -74,7 +79,6 @@ CONFIG_SKB_LARGE=y ...@@ -74,7 +79,6 @@ CONFIG_SKB_LARGE=y
# CONFIG_IPX is not set # CONFIG_IPX is not set
# CONFIG_ATALK is not set # CONFIG_ATALK is not set
# CONFIG_AX25 is not set # CONFIG_AX25 is not set
# CONFIG_BRIDGE is not set
# CONFIG_NETLINK is not set # CONFIG_NETLINK is not set
# #
...@@ -87,22 +91,19 @@ CONFIG_SKB_LARGE=y ...@@ -87,22 +91,19 @@ CONFIG_SKB_LARGE=y
# #
CONFIG_NETDEVICES=y CONFIG_NETDEVICES=y
CONFIG_DUMMY=m CONFIG_DUMMY=m
# CONFIG_SLIP is not set
# CONFIG_PPP is not set
# CONFIG_STRIP is not set
# CONFIG_WIC is not set
# CONFIG_SCC is not set
# CONFIG_PLIP is not set
# CONFIG_EQUALIZER is not set # CONFIG_EQUALIZER is not set
# CONFIG_DLCI is not set # CONFIG_PLIP is not set
# CONFIG_NET_ALPHA is not set # CONFIG_PPP is not set
# CONFIG_NET_VENDOR_SMC is not set # CONFIG_SLIP is not set
# CONFIG_LANCE is not set # CONFIG_NET_RADIO is not set
CONFIG_NET_ETHERNET=y
CONFIG_NET_VENDOR_3COM=y CONFIG_NET_VENDOR_3COM=y
# CONFIG_EL1 is not set # CONFIG_EL1 is not set
# CONFIG_EL2 is not set # CONFIG_EL2 is not set
CONFIG_EL3=y CONFIG_EL3=y
# CONFIG_VORTEX is not set # CONFIG_VORTEX is not set
# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_ISA is not set # CONFIG_NET_ISA is not set
# CONFIG_NET_EISA is not set # CONFIG_NET_EISA is not set
# CONFIG_NET_POCKET is not set # CONFIG_NET_POCKET is not set
......
...@@ -320,8 +320,10 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -320,8 +320,10 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
return -EPERM; return -EPERM;
if ((!child->dumpable || if ((!child->dumpable ||
(current->uid != child->euid) || (current->uid != child->euid) ||
(current->uid != child->suid) ||
(current->uid != child->uid) || (current->uid != child->uid) ||
(current->gid != child->egid) || (current->gid != child->egid) ||
(current->gid != child->sgid) ||
(current->gid != child->gid)) && !suser()) (current->gid != child->gid)) && !suser())
return -EPERM; return -EPERM;
/* the same process cannot be attached many times */ /* the same process cannot be attached many times */
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
extern int setup_x86_irq(int, struct irqaction *); extern int setup_x86_irq(int, struct irqaction *);
#ifndef CONFIG_APM /* cycle counter may be unreliable */
/* Cycle counter value at the previous timer interrupt.. */ /* Cycle counter value at the previous timer interrupt.. */
static unsigned long long last_timer_cc = 0; static unsigned long long last_timer_cc = 0;
static unsigned long long init_timer_cc = 0; static unsigned long long init_timer_cc = 0;
...@@ -82,6 +83,7 @@ static unsigned long do_fast_gettimeoffset(void) ...@@ -82,6 +83,7 @@ static unsigned long do_fast_gettimeoffset(void)
quotient = 1000000/HZ-1; quotient = 1000000/HZ-1;
return quotient; return quotient;
} }
#endif
/* This function must be called with interrupts disabled /* This function must be called with interrupts disabled
* It was inspired by Steve McCanne's microtime-i386 for BSD. -- jrs * It was inspired by Steve McCanne's microtime-i386 for BSD. -- jrs
...@@ -176,8 +178,8 @@ void do_settimeofday(struct timeval *tv) ...@@ -176,8 +178,8 @@ void do_settimeofday(struct timeval *tv)
xtime = *tv; xtime = *tv;
time_state = TIME_BAD; time_state = TIME_BAD;
time_maxerror = 0x70000000; time_maxerror = MAXPHASE;
time_esterror = 0x70000000; time_esterror = MAXPHASE;
sti(); sti();
} }
...@@ -271,6 +273,7 @@ static inline void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -271,6 +273,7 @@ static inline void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
} }
#ifndef CONFIG_APM /* cycle counter may be unreliable */
/* /*
* This is the same as the above, except we _also_ save the current * This is the same as the above, except we _also_ save the current
* cycle counter value at the time of the timer interrupt, so that * cycle counter value at the time of the timer interrupt, so that
...@@ -284,6 +287,7 @@ static void pentium_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -284,6 +287,7 @@ static void pentium_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
"=d" (((unsigned long *) &last_timer_cc)[1])); "=d" (((unsigned long *) &last_timer_cc)[1]));
timer_interrupt(irq, NULL, regs); timer_interrupt(irq, NULL, regs);
} }
#endif
/* Converts Gregorian date to seconds since 1970-01-01 00:00:00. /* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
* Assumes input in normal date format, i.e. 1980-12-31 23:59:59 * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
......
...@@ -340,7 +340,7 @@ static inline void read_sunos_user(struct pt_regs *regs, unsigned long offset, ...@@ -340,7 +340,7 @@ static inline void read_sunos_user(struct pt_regs *regs, unsigned long offset,
break; break;
case 948: case 948:
/* Isn't binary compatability _fun_??? */ /* Isn't binary compatibility _fun_??? */
if(cregs->psr & PSR_C) if(cregs->psr & PSR_C)
regs->u_regs[UREG_I0] = cregs->u_regs[UREG_I0] << 24; regs->u_regs[UREG_I0] = cregs->u_regs[UREG_I0] << 24;
else else
......
...@@ -99,7 +99,7 @@ available: floppy="daring two_fdc" insmod floppy ...@@ -99,7 +99,7 @@ available: floppy="daring two_fdc" insmod floppy
floppy=nofifo floppy=nofifo
Disables the FIFO entirely. This is needed if you get "Bus Disables the FIFO entirely. This is needed if you get "Bus
master arbitration error" messages from your ethernet card (or master arbitration error" messages from your ethernet card (or
from other devices) while accessing the foppy. from other devices) while accessing the floppy.
floppy=fifo floppy=fifo
Enables the FIFO (default) Enables the FIFO (default)
...@@ -119,9 +119,9 @@ floppy=fifo ...@@ -119,9 +119,9 @@ floppy=fifo
higher value, until you only get an occasional Over/Underrun. higher value, until you only get an occasional Over/Underrun.
It is a good idea to compile the floppy driver as a module It is a good idea to compile the floppy driver as a module
when doing this tuning. Indeed, it allows to try different when doing this tuning. Indeed, it allows to try different
fifo values whithout rebooting the machine for each test. Note fifo values without rebooting the machine for each test. Note
that you need to do 'floppycontrol --messages' every time you that you need to do 'floppycontrol --messages' every time you
re-inseert the module. re-insert the module.
Usually, tuning the fifo threshold should not be needed, as Usually, tuning the fifo threshold should not be needed, as
the default (0xa) is reasonable. the default (0xa) is reasonable.
......
...@@ -210,6 +210,7 @@ Summary of ide driver parameters for kernel "command line": ...@@ -210,6 +210,7 @@ Summary of ide driver parameters for kernel "command line":
"idex=" is recognized for all "x" from "0" to "3", such as "ide1". "idex=" is recognized for all "x" from "0" to "3", such as "ide1".
"hdx=noprobe" : drive may be present, but do not probe for it "hdx=noprobe" : drive may be present, but do not probe for it
"hdx=none" : drive is NOT present, ignore cmos and do not probe
"hdx=nowerr" : ignore the WRERR_STAT bit on this drive "hdx=nowerr" : ignore the WRERR_STAT bit on this drive
"hdx=cdrom" : drive is present, and is a cdrom drive "hdx=cdrom" : drive is present, and is a cdrom drive
"hdx=cyl,head,sect" : disk drive is present, with specified geometry "hdx=cyl,head,sect" : disk drive is present, with specified geometry
......
...@@ -110,7 +110,7 @@ static ide_tuneproc_t cmd640_tune_drive; ...@@ -110,7 +110,7 @@ static ide_tuneproc_t cmd640_tune_drive;
/* Interface to access cmd640x registers */ /* Interface to access cmd640x registers */
static void (*put_cmd640_reg)(int reg_no, int val); static void (*put_cmd640_reg)(int reg_no, int val);
static byte (*get_cmd640_reg)(int reg_no); byte (*get_cmd640_reg)(int reg_no);
enum { none, vlb, pci1, pci2 }; enum { none, vlb, pci1, pci2 };
static int bus_type = none; static int bus_type = none;
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
* DTC2278S has only a single IDE interface. * DTC2278S has only a single IDE interface.
* DTC2278D has two IDE interfaces and is otherwise identical to the S version. * DTC2278D has two IDE interfaces and is otherwise identical to the S version.
* DTC2278E has onboard BIOS, while the others do not. * DTC2278E has onboard BIOS, while the others do not.
* DTC2278EB: "works like a charm" -- Kent Bradford <kent@theory.caltech.edu>
* *
* There may be a fourth controller type. The S and D versions use the * There may be a fourth controller type. The S and D versions use the
* Winbond chip, and I think the E version does also. * Winbond chip, and I think the E version does also.
......
...@@ -1733,9 +1733,6 @@ static void reset_interrupt(void) ...@@ -1733,9 +1733,6 @@ static void reset_interrupt(void)
{ {
#ifdef DEBUGT #ifdef DEBUGT
debugt("reset interrupt:"); debugt("reset interrupt:");
#endif
#ifdef __sparc__
fdc_specify(); /* P3: It gives us "sector not found" without this. */
#endif #endif
result(); /* get the status ready for set_fdc */ result(); /* get the status ready for set_fdc */
if (FDCS->reset) { if (FDCS->reset) {
...@@ -4004,6 +4001,10 @@ int floppy_init(void) ...@@ -4004,6 +4001,10 @@ int floppy_init(void)
CLEARSTRUCT(FDCS); CLEARSTRUCT(FDCS);
FDCS->dtr = -1; FDCS->dtr = -1;
FDCS->dor = 0x4; FDCS->dor = 0x4;
#ifdef __sparc__
/*sparcs don't have a DOR reset which we can fall back on to*/
FDCS->version = FDC_82072A;
#endif
} }
fdc_state[0].address = FDC1; fdc_state[0].address = FDC1;
...@@ -4036,6 +4037,7 @@ int floppy_init(void) ...@@ -4036,6 +4037,7 @@ int floppy_init(void)
FDCS->rawcmd = 2; FDCS->rawcmd = 2;
if (user_reset_fdc(-1,FD_RESET_ALWAYS,0)){ if (user_reset_fdc(-1,FD_RESET_ALWAYS,0)){
FDCS->address = -1; FDCS->address = -1;
FDCS->version = FDC_NONE;
continue; continue;
} }
/* Try to determine the floppy controller type */ /* Try to determine the floppy controller type */
...@@ -4266,7 +4268,7 @@ void floppy_eject(void) ...@@ -4266,7 +4268,7 @@ void floppy_eject(void)
{ {
int dummy; int dummy;
floppy_grab_irq_and_dma(); floppy_grab_irq_and_dma();
lock_fdc(0,0); lock_fdc(MAXTIMEOUT,0);
dummy=fd_eject(0); dummy=fd_eject(0);
process_fd_request(); process_fd_request();
floppy_release_irq_and_dma(); floppy_release_irq_and_dma();
......
...@@ -92,6 +92,8 @@ ...@@ -92,6 +92,8 @@
* Reformat to match kernel tabbing style. * Reformat to match kernel tabbing style.
* Add CDROM_GET_UPC ioctl. * Add CDROM_GET_UPC ioctl.
* 3.10 Apr 10, 1996 -- Fix compilation error with STANDARD_ATAPI. * 3.10 Apr 10, 1996 -- Fix compilation error with STANDARD_ATAPI.
* 3.11 Apr 29, 1996 -- Patch from Heiko Eissfeldt <heiko@colossus.escape.de>
* to remove redundant verify_area calls.
* *
* NOTE: Direct audio reads will only work on some types of drive. * NOTE: Direct audio reads will only work on some types of drive.
* So far, i've received reports of success for Sony and Toshiba drives. * So far, i've received reports of success for Sony and Toshiba drives.
...@@ -2079,9 +2081,6 @@ int ide_cdrom_ioctl (ide_drive_t *drive, struct inode *inode, ...@@ -2079,9 +2081,6 @@ int ide_cdrom_ioctl (ide_drive_t *drive, struct inode *inode,
struct cdrom_tocentry tocentry; struct cdrom_tocentry tocentry;
struct atapi_toc_entry *toce; struct atapi_toc_entry *toce;
stat = verify_area (VERIFY_READ, (void *) arg,
sizeof (tocentry));
if (stat) return stat;
stat = verify_area (VERIFY_WRITE, (void *) arg, stat = verify_area (VERIFY_WRITE, (void *) arg,
sizeof (tocentry)); sizeof (tocentry));
if (stat) return stat; if (stat) return stat;
...@@ -2117,9 +2116,6 @@ int ide_cdrom_ioctl (ide_drive_t *drive, struct inode *inode, ...@@ -2117,9 +2116,6 @@ int ide_cdrom_ioctl (ide_drive_t *drive, struct inode *inode,
stat = verify_area (VERIFY_WRITE, (void *) arg, stat = verify_area (VERIFY_WRITE, (void *) arg,
sizeof (subchnl)); sizeof (subchnl));
if (stat) return stat; if (stat) return stat;
stat = verify_area (VERIFY_READ, (void *) arg,
sizeof (subchnl));
if (stat) return stat;
memcpy_fromfs (&subchnl, (void *) arg, sizeof (subchnl)); memcpy_fromfs (&subchnl, (void *) arg, sizeof (subchnl));
...@@ -2228,9 +2224,6 @@ int ide_cdrom_ioctl (ide_drive_t *drive, struct inode *inode, ...@@ -2228,9 +2224,6 @@ int ide_cdrom_ioctl (ide_drive_t *drive, struct inode *inode,
struct atapi_toc *toc; struct atapi_toc *toc;
int stat; int stat;
stat = verify_area (VERIFY_READ, (void *)arg,
sizeof (ms_info));
if (stat) return stat;
stat = verify_area (VERIFY_WRITE, (void *)arg, stat = verify_area (VERIFY_WRITE, (void *)arg,
sizeof (ms_info)); sizeof (ms_info));
if (stat) return stat; if (stat) return stat;
...@@ -2327,8 +2320,6 @@ int ide_cdrom_ioctl (ide_drive_t *drive, struct inode *inode, ...@@ -2327,8 +2320,6 @@ int ide_cdrom_ioctl (ide_drive_t *drive, struct inode *inode,
format = 3; format = 3;
} }
stat = verify_area (VERIFY_READ, (char *)arg, sizeof (msf));
if (stat) return stat;
stat = verify_area (VERIFY_WRITE, (char *)arg, blocksize); stat = verify_area (VERIFY_WRITE, (char *)arg, blocksize);
if (stat) return stat; if (stat) return stat;
......
/* /*
* linux/drivers/block/ide-tape.c Version 1.5 - ALPHA Apr 12, 1996 * linux/drivers/block/ide-tape.c Version 1.5 - ALPHA Apr 12, 1996
* *
* Copyright (C) 1995, 1996 Gadi Oxman <tgud@tochnapc2.technion.ac.il> * Copyright (C) 1995, 1996 Gadi Oxman <gadio@netvision.net.il>
* *
* This driver was constructed as a student project in the software laboratory * This driver was constructed as a student project in the software laboratory
* of the faculty of electrical engineering in the Technion - Israel's * of the faculty of electrical engineering in the Technion - Israel's
...@@ -1525,6 +1525,7 @@ void idetape_issue_packet_command (ide_drive_t *drive,idetape_packet_command_t ...@@ -1525,6 +1525,7 @@ void idetape_issue_packet_command (ide_drive_t *drive,idetape_packet_command_t
} }
#endif /* CONFIG_BLK_DEV_TRITON */ #endif /* CONFIG_BLK_DEV_TRITON */
OUT_BYTE (drive->ctl,IDETAPE_CONTROL_REG);
OUT_BYTE (dma_ok ? 1:0,IDETAPE_FEATURES_REG); /* Use PIO/DMA */ OUT_BYTE (dma_ok ? 1:0,IDETAPE_FEATURES_REG); /* Use PIO/DMA */
OUT_BYTE (bcount.b.high,IDETAPE_BCOUNTH_REG); OUT_BYTE (bcount.b.high,IDETAPE_BCOUNTH_REG);
OUT_BYTE (bcount.b.low,IDETAPE_BCOUNTL_REG); OUT_BYTE (bcount.b.low,IDETAPE_BCOUNTL_REG);
......
/* /*
* linux/drivers/block/ide-tape.h Version 1.3 - ALPHA Feb 9, 1996 * linux/drivers/block/ide-tape.h Version 1.5 - ALPHA Apr 12, 1996
* *
* Copyright (C) 1995, 1996 Gadi Oxman <tgud@tochnapc2.technion.ac.il> * Copyright (C) 1995, 1996 Gadi Oxman <gadio@netvision.net.il>
*/ */
/* /*
......
/* /*
* linux/drivers/block/ide.c Version 5.37 Apr 6, 1996 * linux/drivers/block/ide.c Version 5.39 May 3, 1996
* *
* Copyright (C) 1994-1996 Linus Torvalds & authors (see below) * Copyright (C) 1994-1996 Linus Torvalds & authors (see below)
*/ */
...@@ -227,6 +227,10 @@ ...@@ -227,6 +227,10 @@
* Version 5.37 don't use DMA when "noautotune" is specified * Version 5.37 don't use DMA when "noautotune" is specified
* Version 5.37a (go) fix shared irq probing (was broken in kernel 1.3.72) * Version 5.37a (go) fix shared irq probing (was broken in kernel 1.3.72)
* call unplug_device() from ide_do_drive_cmd() * call unplug_device() from ide_do_drive_cmd()
* Version 5.38 add "hdx=none" option, courtesy of Joel Maslak
* mask drive irq after use, if sharing with another hwif
* add code to help debug weird cmd640 problems
* Version 5.39 fix horrible error in earlier irq sharing "fix"
* *
* Some additional driver compile-time options are in ide.h * Some additional driver compile-time options are in ide.h
* *
...@@ -749,6 +753,7 @@ static void do_reset1 (ide_drive_t *drive, int do_not_try_atapi) ...@@ -749,6 +753,7 @@ static void do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
OUT_BYTE(drive->ctl|6,IDE_CONTROL_REG); /* set SRST and nIEN */ OUT_BYTE(drive->ctl|6,IDE_CONTROL_REG); /* set SRST and nIEN */
udelay(5); /* more than enough time */ udelay(5); /* more than enough time */
OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG); /* clear SRST, leave nIEN */ OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG); /* clear SRST, leave nIEN */
udelay(5); /* more than enough time */
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
ide_set_handler (drive, &reset_pollfunc, HZ/20); ide_set_handler (drive, &reset_pollfunc, HZ/20);
#endif /* OK_TO_RESET_CONTROLLER */ #endif /* OK_TO_RESET_CONTROLLER */
...@@ -1476,6 +1481,8 @@ void ide_do_request (ide_hwgroup_t *hwgroup) ...@@ -1476,6 +1481,8 @@ void ide_do_request (ide_hwgroup_t *hwgroup)
ide_hwif_t *hwif = hwgroup->hwif; ide_hwif_t *hwif = hwgroup->hwif;
struct request *rq; struct request *rq;
if ((rq = hwgroup->rq) == NULL) { if ((rq = hwgroup->rq) == NULL) {
if (hwif->sharing_irq && hwgroup->drive) /* set nIEN */
OUT_BYTE(hwgroup->drive->ctl|2,hwif->ctl_port);
/* /*
* hwgroup->next_hwif is different from hwgroup->hwif * hwgroup->next_hwif is different from hwgroup->hwif
* only when a request is inserted using "ide_next". * only when a request is inserted using "ide_next".
...@@ -2405,8 +2412,17 @@ static int try_to_identify (ide_drive_t *drive, byte cmd) ...@@ -2405,8 +2412,17 @@ static int try_to_identify (ide_drive_t *drive, byte cmd)
irqs = probe_irq_off(irqs); /* get irq number */ irqs = probe_irq_off(irqs); /* get irq number */
if (irqs > 0) if (irqs > 0)
HWIF(drive)->irq = irqs; HWIF(drive)->irq = irqs;
else /* Mmmm.. multiple IRQs */ else { /* Mmmm.. multiple IRQs */
printk("%s: IRQ probe failed (%d)\n", drive->name, irqs); printk("%s: IRQ probe failed (%d)\n", drive->name, irqs);
#ifdef CONFIG_BLK_DEV_CMD640
if (HWIF(drive)->chipset == ide_cmd640) {
extern byte (*get_cmd640_reg)(int);
printk("%s: Hmmm.. probably a driver problem.\n", drive->name);
printk("%s: cmd640 reg 09h == 0x%02x\n", drive->name, get_cmd640_reg(9));
printk("%s: cmd640 reg 51h == 0x%02x\n", drive->name, get_cmd640_reg(0x51));
}
#endif /* CONFIG_BLK_DEV_CMD640 */
}
} }
return rc; return rc;
} }
...@@ -2542,7 +2558,7 @@ static void probe_cmos_for_drives (ide_hwif_t *hwif) ...@@ -2542,7 +2558,7 @@ static void probe_cmos_for_drives (ide_hwif_t *hwif)
/* Extract drive geometry from CMOS+BIOS if not already setup */ /* Extract drive geometry from CMOS+BIOS if not already setup */
for (unit = 0; unit < MAX_DRIVES; ++unit) { for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit]; ide_drive_t *drive = &hwif->drives[unit];
if ((cmos_disks & (0xf0 >> (unit*4))) && !drive->present) { if ((cmos_disks & (0xf0 >> (unit*4))) && !drive->present && !drive->nobios) {
drive->cyl = drive->bios_cyl = *(unsigned short *)BIOS; drive->cyl = drive->bios_cyl = *(unsigned short *)BIOS;
drive->head = drive->bios_head = *(BIOS+2); drive->head = drive->bios_head = *(BIOS+2);
drive->sect = drive->bios_sect = *(BIOS+14); drive->sect = drive->bios_sect = *(BIOS+14);
...@@ -2683,6 +2699,7 @@ static int match_parm (char *s, const char *keywords[], int vals[], int max_vals ...@@ -2683,6 +2699,7 @@ static int match_parm (char *s, const char *keywords[], int vals[], int max_vals
* "idex=" is recognized for all "x" from "0" to "3", such as "ide1". * "idex=" is recognized for all "x" from "0" to "3", such as "ide1".
* *
* "hdx=noprobe" : drive may be present, but do not probe for it * "hdx=noprobe" : drive may be present, but do not probe for it
* "hdx=none" : drive is NOT present, ignore cmos and do not probe
* "hdx=nowerr" : ignore the WRERR_STAT bit on this drive * "hdx=nowerr" : ignore the WRERR_STAT bit on this drive
* "hdx=cdrom" : drive is present, and is a cdrom drive * "hdx=cdrom" : drive is present, and is a cdrom drive
* "hdx=cyl,head,sect" : disk drive is present, with specified geometry * "hdx=cyl,head,sect" : disk drive is present, with specified geometry
...@@ -2737,33 +2754,35 @@ void ide_setup (char *s) ...@@ -2737,33 +2754,35 @@ void ide_setup (char *s)
* Look for drive options: "hdx=" * Look for drive options: "hdx="
*/ */
if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) { if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) {
const char *hd_words[] = {"noprobe", "nowerr", "cdrom", "serialize", const char *hd_words[] = {"none", "noprobe", "nowerr", "cdrom",
"autotune", "noautotune", NULL}; "serialize", "autotune", "noautotune", NULL};
unit = s[2] - 'a'; unit = s[2] - 'a';
hw = unit / MAX_DRIVES; hw = unit / MAX_DRIVES;
unit = unit % MAX_DRIVES; unit = unit % MAX_DRIVES;
hwif = &ide_hwifs[hw]; hwif = &ide_hwifs[hw];
drive = &hwif->drives[unit]; drive = &hwif->drives[unit];
switch (match_parm(&s[3], hd_words, vals, 3)) { switch (match_parm(&s[3], hd_words, vals, 3)) {
case -1: /* "noprobe" */ case -1: /* "none" */
drive->nobios = 1; /* drop into "noprobe" */
case -2: /* "noprobe" */
drive->noprobe = 1; drive->noprobe = 1;
goto done; goto done;
case -2: /* "nowerr" */ case -3: /* "nowerr" */
drive->bad_wstat = BAD_R_STAT; drive->bad_wstat = BAD_R_STAT;
hwif->noprobe = 0; hwif->noprobe = 0;
goto done; goto done;
case -3: /* "cdrom" */ case -4: /* "cdrom" */
drive->present = 1; drive->present = 1;
drive->media = ide_cdrom; drive->media = ide_cdrom;
hwif->noprobe = 0; hwif->noprobe = 0;
goto done; goto done;
case -4: /* "serialize" */ case -5: /* "serialize" */
printk(" -- USE \"ide%d=serialize\" INSTEAD", hw); printk(" -- USE \"ide%d=serialize\" INSTEAD", hw);
goto do_serialize; goto do_serialize;
case -5: /* "autotune" */ case -6: /* "autotune" */
drive->autotune = 1; drive->autotune = 1;
goto done; goto done;
case -6: /* "noautotune" */ case -7: /* "noautotune" */
drive->autotune = 2; drive->autotune = 2;
goto done; goto done;
case 3: /* cyl,head,sect */ case 3: /* cyl,head,sect */
...@@ -2856,7 +2875,7 @@ void ide_setup (char *s) ...@@ -2856,7 +2875,7 @@ void ide_setup (char *s)
} }
#endif /* CONFIG_BLK_DEV_HT6560B */ #endif /* CONFIG_BLK_DEV_HT6560B */
#if CONFIG_BLK_DEV_QD6580 #if CONFIG_BLK_DEV_QD6580
case -5: /* "qd6580" (no secondary i/f) */ case -5: /* "qd6580" (has secondary i/f) */
{ {
extern void init_qd6580 (void); extern void init_qd6580 (void);
init_qd6580(); init_qd6580();
...@@ -3011,12 +3030,13 @@ static int init_irq (ide_hwif_t *hwif) ...@@ -3011,12 +3030,13 @@ static int init_irq (ide_hwif_t *hwif)
*/ */
for (index = 0; index < MAX_HWIFS; index++) { for (index = 0; index < MAX_HWIFS; index++) {
if (index != hwif->index) { if (index != hwif->index) {
ide_hwif_t *g = &ide_hwifs[index]; ide_hwif_t *h = &ide_hwifs[index];
if (g->irq == hwif->irq || g->irq == mate_irq) { if (h->irq == hwif->irq || h->irq == mate_irq) {
if (hwgroup && !g->hwgroup) hwif->sharing_irq = h->sharing_irq = 1;
g->hwgroup = hwgroup; if (hwgroup && !h->hwgroup)
h->hwgroup = hwgroup;
else if (!hwgroup) else if (!hwgroup)
hwgroup = g->hwgroup; hwgroup = h->hwgroup;
} }
} }
} }
......
...@@ -313,6 +313,7 @@ typedef struct ide_drive_s { ...@@ -313,6 +313,7 @@ typedef struct ide_drive_s {
unsigned using_dma : 1; /* disk is using dma for read/write */ unsigned using_dma : 1; /* disk is using dma for read/write */
unsigned forced_geom : 1; /* 1 if hdx=c,h,s was given at boot */ unsigned forced_geom : 1; /* 1 if hdx=c,h,s was given at boot */
unsigned unmask : 1; /* flag: okay to unmask other irqs */ unsigned unmask : 1; /* flag: okay to unmask other irqs */
unsigned nobios : 1; /* flag: do not probe bios for drive */
unsigned autotune : 2; /* 1=autotune, 2=noautotune, 0=default */ unsigned autotune : 2; /* 1=autotune, 2=noautotune, 0=default */
#if FAKE_FDISK_FOR_EZDRIVE #if FAKE_FDISK_FOR_EZDRIVE
unsigned remap_0_to_1 : 1; /* flag: partitioned with ezdrive */ unsigned remap_0_to_1 : 1; /* flag: partitioned with ezdrive */
...@@ -419,6 +420,7 @@ typedef struct hwif_s { ...@@ -419,6 +420,7 @@ typedef struct hwif_s {
unsigned serialized : 1; /* serialized operation with mate hwif */ unsigned serialized : 1; /* serialized operation with mate hwif */
unsigned no_unmask : 1; /* disallow setting unmask bits */ unsigned no_unmask : 1; /* disallow setting unmask bits */
unsigned got_irq : 1; /* 1 = already alloc'd our irq */ unsigned got_irq : 1; /* 1 = already alloc'd our irq */
unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */
#ifdef CONFIG_BLK_DEV_PROMISE #ifdef CONFIG_BLK_DEV_PROMISE
unsigned is_promise2: 1; /* 2nd i/f on promise DC4030 */ unsigned is_promise2: 1; /* 2nd i/f on promise DC4030 */
#endif /* CONFIG_BLK_DEV_PROMISE */ #endif /* CONFIG_BLK_DEV_PROMISE */
......
...@@ -38,6 +38,9 @@ ...@@ -38,6 +38,9 @@
* and can work out the answers! * and can work out the answers!
* *
* I/O ports are 0xb0 0xb2 and 0xb3 * I/O ports are 0xb0 0xb2 and 0xb3
*
* More research on qd6580 being done by willmore@cig.mot.com (David)
* -- this is apparently a *dual* IDE interface
*/ */
static void tune_qd6580 (ide_drive_t *drive, byte pio) static void tune_qd6580 (ide_drive_t *drive, byte pio)
...@@ -61,5 +64,6 @@ static void tune_qd6580 (ide_drive_t *drive, byte pio) ...@@ -61,5 +64,6 @@ static void tune_qd6580 (ide_drive_t *drive, byte pio)
void init_qd6580 (void) void init_qd6580 (void)
{ {
ide_hwifs[0].chipset = ide_qd6580; ide_hwifs[0].chipset = ide_qd6580;
ide_hwifs[1].chipset = ide_qd6580;
ide_hwifs[0].tuneproc = &tune_qd6580; ide_hwifs[0].tuneproc = &tune_qd6580;
} }
This diff is collapsed.
Wed Apr 24 14:02:04 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
* random.c (add_timer_randomness): Use 2nd derivitive as well to
better estimate entropy.
(rand_initialize): Explicitly initialize all the pointers
to NULL. (Clearing pointers using memset isn't portable.)
Initialize the random pool with OS-dependent data.
(random_write): Add sanity checking to the arguments to
random_write(), so that bad arguments won't cause a kernel
SEGV.
(random_read): Update the access time of the device inode
when you return data to the user.
(random_ioctl): Wake up the random_wait channel when there
are only WAIT_INPUT_BITS available. Add more paranoia
checks to make sure entropy_count doesn't go beyond the
bounds of (0, POOLSIZE). Add a few missing verify_area
checks. Add support for the RNDCLEARPOOL ioctl, which
zaps the random pool.
(add_timer_randomness): Wake up the random_wait
channel only when there are WAIT_INPUT_BITS available.
(random_select): Allow a random refresh daemon process to
select on /dev/random for writing; wake up the daemon when
there are less than WAIT_OUTPUT_BITS bits of randomness
available.
Tue Apr 23 22:56:07 1996 <tytso@rsts-11.mit.edu> Tue Apr 23 22:56:07 1996 <tytso@rsts-11.mit.edu>
* tty_io.c (init_dev): Change return code when user attempts to * tty_io.c (init_dev): Change return code when user attempts to
......
...@@ -46,6 +46,7 @@ if [ "$CONFIG_APM" = "y" ]; then ...@@ -46,6 +46,7 @@ if [ "$CONFIG_APM" = "y" ]; then
bool ' Enable PM at boot time' CONFIG_APM_DO_ENABLE bool ' Enable PM at boot time' CONFIG_APM_DO_ENABLE
bool ' Make CPU Idle calls when idle' CONFIG_APM_CPU_IDLE bool ' Make CPU Idle calls when idle' CONFIG_APM_CPU_IDLE
bool ' Enable console blanking using APM' CONFIG_APM_DISPLAY_BLANK bool ' Enable console blanking using APM' CONFIG_APM_DISPLAY_BLANK
bool ' Power off on shutdown' CONFIG_APM_POWER_OFF
fi fi
bool 'Watchdog Timer Support' CONFIG_WATCHDOG bool 'Watchdog Timer Support' CONFIG_WATCHDOG
if [ "$CONFIG_WATCHDOG" != "n" ]; then if [ "$CONFIG_WATCHDOG" != "n" ]; then
......
...@@ -24,15 +24,17 @@ ...@@ -24,15 +24,17 @@
* Prohibit APM BIOS calls unless apm_enabled. * Prohibit APM BIOS calls unless apm_enabled.
* (Thanks to Ulrich Windl <Ulrich.Windl@rz.uni-regensburg.de>) * (Thanks to Ulrich Windl <Ulrich.Windl@rz.uni-regensburg.de>)
* April 1996, Stephen Rothwell (Stephen.Rothwell@canb.auug.org.au) * April 1996, Stephen Rothwell (Stephen.Rothwell@canb.auug.org.au)
* Version 1.0 * Version 1.0 and 1.1
* *
* History: * History:
* 0.6b: first version in official kernel, Linux 1.3.46 * 0.6b: first version in official kernel, Linux 1.3.46
* 0.7: changed /proc/apm format, Linux 1.3.58 * 0.7: changed /proc/apm format, Linux 1.3.58
* 0.8: fixed gcc 2.7.[12] compilation problems, Linux 1.3.59 * 0.8: fixed gcc 2.7.[12] compilation problems, Linux 1.3.59
* 0.9: only call bios if bios is present, Linux 1.3.72 * 0.9: only call bios if bios is present, Linux 1.3.72
* 1.0: use fixed device number, consolidate /proc/apm into * 1.0: use fixed device number, consolidate /proc/apm into this file,
* this file, Linux 1.3.85 * Linux 1.3.85
* 1.1: support user-space standby and suspend, power off after system
* halted, Linux 1.3.98
* *
* Reference: * Reference:
* *
...@@ -113,7 +115,9 @@ extern unsigned long get_cmos_time(void); ...@@ -113,7 +115,9 @@ extern unsigned long get_cmos_time(void);
* CONFIG_APM_DISPLAY_BLANK: enable console blanking using the APM. Some * CONFIG_APM_DISPLAY_BLANK: enable console blanking using the APM. Some
* laptops can use this to turn of the LCD backlight when the VC screen * laptops can use this to turn of the LCD backlight when the VC screen
* blanker blanks the screen. Note that this is only used by the VC screen * blanker blanks the screen. Note that this is only used by the VC screen
* blanker, and probably won't turn off the backlight when using X11. * blanker, and probably won't turn off the backlight when using X11. Some
* problems have been reported when using this option with gpm (if you'd
* like to debug this, please do so).
* *
* If you are debugging the APM support for your laptop, note that code for * If you are debugging the APM support for your laptop, note that code for
* all of these options is contained in this file, so you can #define or * all of these options is contained in this file, so you can #define or
...@@ -330,7 +334,7 @@ static struct apm_bios_struct * user_list = NULL; ...@@ -330,7 +334,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[] = "1.0";/* no spaces */ static char driver_version[] = "1.1";/* no spaces */
#ifdef APM_DEBUG #ifdef APM_DEBUG
static char * apm_event_name[] = { static char * apm_event_name[] = {
...@@ -427,7 +431,7 @@ static int apm_get_event(apm_event_t *event) ...@@ -427,7 +431,7 @@ static int apm_get_event(apm_event_t *event)
return APM_SUCCESS; return APM_SUCCESS;
} }
static int apm_set_power_state(u_short state) int apm_set_power_state(u_short state)
{ {
u_short error; u_short error;
...@@ -567,13 +571,15 @@ static apm_event_t get_queued_event(struct apm_bios_struct * as) ...@@ -567,13 +571,15 @@ static apm_event_t get_queued_event(struct apm_bios_struct * as)
return as->events[as->event_tail]; return as->events[as->event_tail];
} }
static int queue_event(apm_event_t event) static int queue_event(apm_event_t event, struct apm_bios_struct *sender)
{ {
struct apm_bios_struct * as; struct apm_bios_struct * as;
if (user_list == NULL) if (user_list == NULL)
return 0; return 0;
for (as = user_list; as != NULL; as = as->next) { for (as = user_list; as != NULL; as = as->next) {
if (as == sender)
continue;
as->event_head = (as->event_head + 1) % APM_MAX_EVENTS; as->event_head = (as->event_head + 1) % APM_MAX_EVENTS;
if (as->event_head == as->event_tail) if (as->event_head == as->event_tail)
as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS; as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS;
...@@ -656,7 +662,8 @@ static apm_event_t get_event(void) ...@@ -656,7 +662,8 @@ static apm_event_t get_event(void)
return 0; return 0;
} }
static void send_event(apm_event_t event, apm_event_t undo) static void send_event(apm_event_t event, apm_event_t undo,
struct apm_bios_struct *sender)
{ {
callback_list_t * call; callback_list_t * call;
callback_list_t * fix; callback_list_t * fix;
...@@ -671,7 +678,7 @@ static void send_event(apm_event_t event, apm_event_t undo) ...@@ -671,7 +678,7 @@ static void send_event(apm_event_t event, apm_event_t undo)
} }
} }
queue_event(event); queue_event(event, sender);
} }
static void check_events(void) static void check_events(void)
...@@ -682,18 +689,19 @@ static void check_events(void) ...@@ -682,18 +689,19 @@ static void check_events(void)
switch (event) { switch (event) {
case APM_SYS_STANDBY: case APM_SYS_STANDBY:
case APM_USER_STANDBY: case APM_USER_STANDBY:
send_event(event, APM_STANDBY_RESUME); send_event(event, APM_STANDBY_RESUME, NULL);
if (standbys_pending <= 0) if (standbys_pending <= 0)
standby(); standby();
break; break;
case APM_USER_SUSPEND: case APM_USER_SUSPEND:
#ifdef CONFIG_APM_IGNORE_USER_SUSPEND #ifdef CONFIG_APM_IGNORE_USER_SUSPEND
if (apm_bios_info.version > 0x100)
apm_set_power_state(APM_STATE_REJECT); apm_set_power_state(APM_STATE_REJECT);
break; break;
#endif #endif
case APM_SYS_SUSPEND: case APM_SYS_SUSPEND:
send_event(event, APM_NORMAL_RESUME); send_event(event, APM_NORMAL_RESUME, NULL);
if (suspends_pending <= 0) if (suspends_pending <= 0)
suspend(); suspend();
break; break;
...@@ -702,12 +710,12 @@ static void check_events(void) ...@@ -702,12 +710,12 @@ static void check_events(void)
case APM_CRITICAL_RESUME: case APM_CRITICAL_RESUME:
case APM_STANDBY_RESUME: case APM_STANDBY_RESUME:
set_time(); set_time();
send_event(event, 0); send_event(event, 0, NULL);
break; break;
case APM_LOW_BATTERY: case APM_LOW_BATTERY:
case APM_POWER_STATUS_CHANGE: case APM_POWER_STATUS_CHANGE:
send_event(event, 0); send_event(event, 0, NULL);
break; break;
case APM_UPDATE_TIME: case APM_UPDATE_TIME:
...@@ -833,6 +841,17 @@ static int do_read(struct inode *inode, struct file *fp, char *buf, int count) ...@@ -833,6 +841,17 @@ static int do_read(struct inode *inode, struct file *fp, char *buf, int count)
while ((i >= sizeof(event)) && !queue_empty(as)) { while ((i >= sizeof(event)) && !queue_empty(as)) {
event = get_queued_event(as); event = get_queued_event(as);
memcpy_tofs(buf, &event, sizeof(event)); memcpy_tofs(buf, &event, sizeof(event));
switch (event) {
case APM_SYS_SUSPEND:
case APM_USER_SUSPEND:
as->suspends_read++;
break;
case APM_SYS_STANDBY:
case APM_USER_STANDBY:
as->standbys_read++;
break;
}
buf += sizeof(event); buf += sizeof(event);
i -= sizeof(event); i -= sizeof(event);
} }
...@@ -867,22 +886,30 @@ static int do_ioctl(struct inode * inode, struct file *filp, ...@@ -867,22 +886,30 @@ static int do_ioctl(struct inode * inode, struct file *filp,
as = filp->private_data; as = filp->private_data;
if (check_apm_bios_struct(as, "ioctl")) if (check_apm_bios_struct(as, "ioctl"))
return -EIO; return -EIO;
if (!as->suser)
return -EPERM;
switch (cmd) { switch (cmd) {
case APM_IOC_STANDBY: case APM_IOC_STANDBY:
if (as->standbys_pending > 0) { if (as->standbys_read > 0) {
as->standbys_read--;
as->standbys_pending--; as->standbys_pending--;
standbys_pending--; standbys_pending--;
}
else
send_event(APM_USER_STANDBY, APM_STANDBY_RESUME, as);
if (standbys_pending <= 0) if (standbys_pending <= 0)
standby(); standby();
}
break; break;
case APM_IOC_SUSPEND: case APM_IOC_SUSPEND:
if (as->suspends_pending > 0) { if (as->suspends_read > 0) {
as->suspends_read--;
as->suspends_pending--; as->suspends_pending--;
suspends_pending--; suspends_pending--;
}
else
send_event(APM_USER_SUSPEND, APM_NORMAL_RESUME, as);
if (suspends_pending <= 0) if (suspends_pending <= 0)
suspend(); suspend();
}
break; break;
default: default:
return -EINVAL; return -EINVAL;
...@@ -938,6 +965,7 @@ static int do_open(struct inode * inode, struct file * filp) ...@@ -938,6 +965,7 @@ static int do_open(struct inode * inode, struct file * filp)
as->magic = APM_BIOS_MAGIC; as->magic = APM_BIOS_MAGIC;
as->event_tail = as->event_head = 0; as->event_tail = as->event_head = 0;
as->suspends_pending = as->standbys_pending = 0; as->suspends_pending = as->standbys_pending = 0;
as->suspends_read = as->standbys_read = 0;
as->suser = suser(); as->suser = suser();
as->next = user_list; as->next = user_list;
user_list = as; user_list = as;
......
...@@ -183,14 +183,14 @@ static inline int lp_write_interrupt(unsigned int minor, const char * buf, int c ...@@ -183,14 +183,14 @@ static inline int lp_write_interrupt(unsigned int minor, const char * buf, int c
if (lp_table[minor].runchars > LP_STAT(minor).maxrun) if (lp_table[minor].runchars > LP_STAT(minor).maxrun)
LP_STAT(minor).maxrun = lp_table[minor].runchars; LP_STAT(minor).maxrun = lp_table[minor].runchars;
status = LP_S(minor); status = LP_S(minor);
if ((status & LP_POUTPA)) { if ((status & LP_OFFL) || !(status & LP_PSELECD)) {
printk(KERN_INFO "lp%d out of paper\n", minor);
if (LP_F(minor) & LP_ABORT)
return rc?rc:-ENOSPC;
} else if (!(status & LP_PSELECD)) {
printk(KERN_INFO "lp%d off-line\n", minor); printk(KERN_INFO "lp%d off-line\n", minor);
if (LP_F(minor) & LP_ABORT) if (LP_F(minor) & LP_ABORT)
return rc?rc:-EIO; return rc?rc:-EIO;
} else if ((status & LP_POUTPA)) {
printk(KERN_INFO "lp%d out of paper\n", minor);
if (LP_F(minor) & LP_ABORT)
return rc?rc:-ENOSPC;
} else if (!(status & LP_PERRORP)) { } else if (!(status & LP_PERRORP)) {
printk(KERN_ERR "lp%d printer error\n", minor); printk(KERN_ERR "lp%d printer error\n", minor);
if (LP_F(minor) & LP_ABORT) if (LP_F(minor) & LP_ABORT)
...@@ -248,18 +248,18 @@ static inline int lp_write_polled(unsigned int minor, const char * buf, int coun ...@@ -248,18 +248,18 @@ static inline int lp_write_polled(unsigned int minor, const char * buf, int coun
LP_STAT(minor).maxrun = lp_table[minor].runchars; LP_STAT(minor).maxrun = lp_table[minor].runchars;
status = LP_S(minor); status = LP_S(minor);
if (status & LP_POUTPA) { if ((status & LP_OFFL) || !(status & LP_PSELECD)) {
printk(KERN_INFO "lp%d out of paper\n", minor); printk(KERN_INFO "lp%d off-line\n", minor);
if(LP_F(minor) & LP_ABORT) if(LP_F(minor) & LP_ABORT)
return temp-buf?temp-buf:-ENOSPC; return temp-buf?temp-buf:-EIO;
current->state = TASK_INTERRUPTIBLE; current->state = TASK_INTERRUPTIBLE;
current->timeout = jiffies + LP_TIMEOUT_POLLED; current->timeout = jiffies + LP_TIMEOUT_POLLED;
schedule(); schedule();
} else } else
if (!(status & LP_PSELECD)) { if (status & LP_POUTPA) {
printk(KERN_INFO "lp%d off-line\n", minor); printk(KERN_INFO "lp%d out of paper\n", minor);
if(LP_F(minor) & LP_ABORT) if(LP_F(minor) & LP_ABORT)
return temp-buf?temp-buf:-EIO; return temp-buf?temp-buf:-ENOSPC;
current->state = TASK_INTERRUPTIBLE; current->state = TASK_INTERRUPTIBLE;
current->timeout = jiffies + LP_TIMEOUT_POLLED; current->timeout = jiffies + LP_TIMEOUT_POLLED;
schedule(); schedule();
......
This diff is collapsed.
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
* *
*/ */
#define RTC_VERSION "1.04" #define RTC_VERSION "1.05"
#define RTC_IRQ 8 /* Can't see this changing soon. */ #define RTC_IRQ 8 /* Can't see this changing soon. */
#define RTC_IO_BASE 0x70 /* Or this... */ #define RTC_IO_BASE 0x70 /* Or this... */
...@@ -67,6 +67,8 @@ ...@@ -67,6 +67,8 @@
static struct wait_queue *rtc_wait; static struct wait_queue *rtc_wait;
static struct timer_list rtc_irq_timer;
static int rtc_lseek(struct inode *inode, struct file *file, off_t offset, static int rtc_lseek(struct inode *inode, struct file *file, off_t offset,
int origin); int origin);
...@@ -81,6 +83,7 @@ static int rtc_select(struct inode *inode, struct file *file, ...@@ -81,6 +83,7 @@ static int rtc_select(struct inode *inode, struct file *file,
void get_rtc_time (struct tm *rtc_tm); void get_rtc_time (struct tm *rtc_tm);
void get_rtc_alm_time (struct tm *alm_tm); void get_rtc_alm_time (struct tm *alm_tm);
void rtc_dropped_irq(unsigned long data);
inline void set_rtc_irq_bit(unsigned char bit); inline void set_rtc_irq_bit(unsigned char bit);
inline void mask_rtc_irq_bit(unsigned char bit); inline void mask_rtc_irq_bit(unsigned char bit);
...@@ -92,8 +95,10 @@ unsigned char rtc_is_updating(void); ...@@ -92,8 +95,10 @@ unsigned char rtc_is_updating(void);
*/ */
#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ #define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */
#define RTC_TIMER_ON 0x02 /* missed irq timer active */
unsigned char rtc_status = 0; /* bitmapped status byte. */ unsigned char rtc_status = 0; /* bitmapped status byte. */
unsigned long rtc_freq = 0; /* Current periodic IRQ rate */
unsigned long rtc_irq_data = 0; /* our output to the world */ unsigned long rtc_irq_data = 0; /* our output to the world */
unsigned char days_in_mo[] = unsigned char days_in_mo[] =
...@@ -119,6 +124,12 @@ static void rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -119,6 +124,12 @@ static void rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
rtc_irq_data &= ~0xff; rtc_irq_data &= ~0xff;
rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0); rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);
wake_up_interruptible(&rtc_wait); wake_up_interruptible(&rtc_wait);
if (rtc_status & RTC_TIMER_ON) {
del_timer(&rtc_irq_timer);
rtc_irq_timer.expires = jiffies + HZ/rtc_freq + 2*HZ/100;
add_timer(&rtc_irq_timer);
}
} }
/* /*
...@@ -157,12 +168,16 @@ static int rtc_read(struct inode *inode, struct file *file, char *buf, int count ...@@ -157,12 +168,16 @@ static int rtc_read(struct inode *inode, struct file *file, char *buf, int count
break; break;
} }
schedule(); schedule();
continue;
} }
if (retval == 0) { if (retval == 0) {
memcpy_tofs(buf, &rtc_irq_data, sizeof(unsigned long)); unsigned long data, flags;
save_flags(flags);
cli();
data = rtc_irq_data;
rtc_irq_data = 0; rtc_irq_data = 0;
restore_flags(flags);
memcpy_tofs(buf, &data, sizeof(unsigned long));
retval = sizeof(unsigned long); retval = sizeof(unsigned long);
} }
...@@ -192,27 +207,30 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -192,27 +207,30 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case RTC_PIE_OFF: /* Mask periodic int. enab. bit */ case RTC_PIE_OFF: /* Mask periodic int. enab. bit */
{ {
mask_rtc_irq_bit(RTC_PIE); mask_rtc_irq_bit(RTC_PIE);
if (rtc_status & RTC_TIMER_ON) {
del_timer(&rtc_irq_timer);
rtc_status &= ~RTC_TIMER_ON;
}
return 0; return 0;
} }
case RTC_PIE_ON: /* Allow periodic ints */ case RTC_PIE_ON: /* Allow periodic ints */
{ {
unsigned int hz;
unsigned char tmp;
save_flags(flags);
cli();
tmp = CMOS_READ(RTC_FREQ_SELECT) & 0x0f;
restore_flags(flags);
hz = (tmp ? (65536/(1<<tmp)) : 0);
/* /*
* We don't really want Joe User enabling more * We don't really want Joe User enabling more
* than 64Hz of interrupts on a multi-user machine. * than 64Hz of interrupts on a multi-user machine.
*/ */
if ((hz > 64) && (!suser())) if ((rtc_freq > 64) && (!suser()))
return -EPERM; return -EPERM;
if (rtc_freq == 0)
return -EINVAL;
if (!(rtc_status & RTC_TIMER_ON)) {
rtc_status |= RTC_TIMER_ON;
rtc_irq_timer.expires = jiffies + HZ/rtc_freq + 2*HZ/100;
add_timer(&rtc_irq_timer);
}
set_rtc_irq_bit(RTC_PIE); set_rtc_irq_bit(RTC_PIE);
return 0; return 0;
} }
...@@ -382,19 +400,13 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -382,19 +400,13 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
} }
case RTC_IRQP_READ: /* Read the periodic IRQ rate. */ case RTC_IRQP_READ: /* Read the periodic IRQ rate. */
{ {
unsigned long hz;
int retval; int retval;
retval = verify_area(VERIFY_WRITE, (unsigned long*)arg, sizeof(unsigned long)); retval = verify_area(VERIFY_WRITE, (unsigned long*)arg, sizeof(unsigned long));
if (retval != 0) if (retval != 0)
return retval; return retval;
save_flags(flags); memcpy_tofs((unsigned long*)arg, &rtc_freq, sizeof(unsigned long));
cli();
retval = CMOS_READ(RTC_FREQ_SELECT) & 0x0f;
restore_flags(flags);
hz = (retval ? (65536/(1<<retval)) : 0);
memcpy_tofs((unsigned long*)arg, &hz, sizeof(unsigned long));
return 0; return 0;
} }
case RTC_IRQP_SET: /* Set periodic IRQ rate. */ case RTC_IRQP_SET: /* Set periodic IRQ rate. */
...@@ -405,7 +417,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -405,7 +417,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
/* /*
* The max we can do is 8192Hz. * The max we can do is 8192Hz.
*/ */
if (arg > 8192) if ((arg < 2) || (arg > 8192))
return -EINVAL; return -EINVAL;
/* /*
* We don't really want Joe User generating more * We don't really want Joe User generating more
...@@ -423,6 +435,8 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -423,6 +435,8 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
if ((arg != 0) && (arg != (1<<tmp))) if ((arg != 0) && (arg != (1<<tmp)))
return -EINVAL; return -EINVAL;
rtc_freq = arg;
save_flags(flags); save_flags(flags);
cli(); cli();
val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0; val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0;
...@@ -480,6 +494,12 @@ static void rtc_release(struct inode *inode, struct file *file) ...@@ -480,6 +494,12 @@ static void rtc_release(struct inode *inode, struct file *file)
CMOS_WRITE(tmp, RTC_CONTROL); CMOS_WRITE(tmp, RTC_CONTROL);
CMOS_READ(RTC_INTR_FLAGS); CMOS_READ(RTC_INTR_FLAGS);
restore_flags(flags); restore_flags(flags);
if (rtc_status & RTC_TIMER_ON) {
rtc_status &= ~RTC_TIMER_ON;
del_timer(&rtc_irq_timer);
}
rtc_irq_data = 0; rtc_irq_data = 0;
rtc_status &= ~RTC_IS_OPEN; rtc_status &= ~RTC_IS_OPEN;
} }
...@@ -520,6 +540,8 @@ static struct miscdevice rtc_dev= ...@@ -520,6 +540,8 @@ static struct miscdevice rtc_dev=
int rtc_init(void) int rtc_init(void)
{ {
unsigned long flags;
printk("Real Time Clock Driver v%s\n", RTC_VERSION); printk("Real Time Clock Driver v%s\n", RTC_VERSION);
if(request_irq(RTC_IRQ, rtc_interrupt, SA_INTERRUPT, "rtc", NULL)) if(request_irq(RTC_IRQ, rtc_interrupt, SA_INTERRUPT, "rtc", NULL))
{ {
...@@ -530,10 +552,46 @@ int rtc_init(void) ...@@ -530,10 +552,46 @@ int rtc_init(void)
misc_register(&rtc_dev); misc_register(&rtc_dev);
/* Check region? Naaah! Just snarf it up. */ /* Check region? Naaah! Just snarf it up. */
request_region(RTC_IO_BASE, RTC_IO_EXTENT, "rtc"); request_region(RTC_IO_BASE, RTC_IO_EXTENT, "rtc");
init_timer(&rtc_irq_timer);
rtc_irq_timer.function = rtc_dropped_irq;
rtc_wait = NULL; rtc_wait = NULL;
save_flags(flags);
cli();
rtc_freq = CMOS_READ(RTC_FREQ_SELECT) & 0x0F;
restore_flags(flags);
rtc_freq = (rtc_freq ? (65536/(1<<rtc_freq)) : 0);
return 0; return 0;
} }
/*
* At IRQ rates >= 4096Hz, an interrupt may get lost altogether.
* (usually during an IDE disk interrupt, with IRQ unmasking off)
* Since the interrupt handler doesn't get called, the IRQ status
* byte doesn't get read, and the RTC stops generating interrupts.
* A timer is set, and will call this function if/when that happens.
* To get it out of this stalled state, we just read the status.
* At least a jiffy of interrupts (rtc_freq/HZ) will have been lost.
* (You *really* shouldn't be trying to use a non-realtime system
* for something that requires a steady > 1KHz signal anyways.)
*/
void rtc_dropped_irq(unsigned long data)
{
unsigned long flags;
printk(KERN_INFO "rtc: lost some interrupts at %ldHz.\n", rtc_freq);
del_timer(&rtc_irq_timer);
rtc_irq_timer.expires = jiffies + HZ/rtc_freq + 2*HZ/100;
add_timer(&rtc_irq_timer);
save_flags(flags);
cli();
rtc_irq_data += ((rtc_freq/HZ)<<8);
rtc_irq_data &= ~0xff;
rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0); /* restart */
restore_flags(flags);
}
/* /*
* Info exported via "/proc/rtc". * Info exported via "/proc/rtc".
*/ */
...@@ -542,11 +600,11 @@ int get_rtc_status(char *buf) ...@@ -542,11 +600,11 @@ int get_rtc_status(char *buf)
{ {
char *p; char *p;
struct tm tm; struct tm tm;
unsigned char freq, batt, ctrl; unsigned char batt, ctrl;
unsigned long flags; unsigned long flags;
save_flags(flags); save_flags(flags);
freq = CMOS_READ(RTC_FREQ_SELECT) & 0x0F; cli();
batt = CMOS_READ(RTC_VALID) & RTC_VRT; batt = CMOS_READ(RTC_VALID) & RTC_VRT;
ctrl = CMOS_READ(RTC_CONTROL); ctrl = CMOS_READ(RTC_CONTROL);
restore_flags(flags); restore_flags(flags);
...@@ -559,10 +617,11 @@ int get_rtc_status(char *buf) ...@@ -559,10 +617,11 @@ int get_rtc_status(char *buf)
* There is no way to tell if the luser has the RTC set for local * There is no way to tell if the luser has the RTC set for local
* time or for Universal Standard Time (GMT). Probably local though. * time or for Universal Standard Time (GMT). Probably local though.
*/ */
p += sprintf(p, "date : %04d-%02d-%02d\n", p += sprintf(p,
"rtc_time\t: %02d:%02d:%02d\n"
"rtc_date\t: %04d-%02d-%02d\n",
tm.tm_hour, tm.tm_min, tm.tm_sec,
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
p += sprintf(p, "time : %02d-%02d-%02d\n",
tm.tm_hour, tm.tm_min, tm.tm_sec);
get_rtc_alm_time(&tm); get_rtc_alm_time(&tm);
...@@ -571,44 +630,41 @@ int get_rtc_status(char *buf) ...@@ -571,44 +630,41 @@ int get_rtc_status(char *buf)
* match any value for that particular field. Values that are * match any value for that particular field. Values that are
* greater than a valid time, but less than 0xc0 shouldn't appear. * greater than a valid time, but less than 0xc0 shouldn't appear.
*/ */
p += sprintf(p, "alarm : "); p += sprintf(p, "alarm\t\t: ");
if (tm.tm_hour <= 24) if (tm.tm_hour <= 24)
p += sprintf(p, "%02d", tm.tm_hour); p += sprintf(p, "%02d:", tm.tm_hour);
else else
p += sprintf(p, "**"); p += sprintf(p, "**:");
p += sprintf(p, "-");
if (tm.tm_min <= 59) if (tm.tm_min <= 59)
p += sprintf(p, "%02d", tm.tm_min); p += sprintf(p, "%02d:", tm.tm_min);
else else
p += sprintf(p, "**"); p += sprintf(p, "**:");
p += sprintf(p, "-");
if (tm.tm_sec <= 59) if (tm.tm_sec <= 59)
p += sprintf(p, "%02d", tm.tm_sec); p += sprintf(p, "%02d\n", tm.tm_sec);
else else
p += sprintf(p, "**"); p += sprintf(p, "**\n");
p += sprintf(p, "\n");
p += sprintf(p,
p += sprintf(p, "daylight : %s\n", "DST_enable\t: %s\n"
((ctrl & RTC_DST_EN) ? "yes" : "no" )); "BCD\t\t: %s\n"
p += sprintf(p, "bcd : %s\n", "24hr\t\t: %s\n"
((ctrl & RTC_DM_BINARY) ? "no" : "yes" )); "sqare_wave\t: %s\n"
p += sprintf(p, "24hr : %s\n", "alarm_IRQ\t: %s\n"
((ctrl & RTC_24H) ? "yes" : "no" )); "update_IRQ\t: %s\n"
p += sprintf(p, "sqwave : %s\n", "periodic_IRQ\t: %s\n"
((ctrl & RTC_SQWE) ? "yes" : "no" )); "periodic_freq\t: %ld\n"
"batt_status\t: %s\n",
p += sprintf(p, "alarm_int : %s\n", (ctrl & RTC_DST_EN) ? "yes" : "no",
((ctrl & RTC_AIE) ? "yes" : "no" )); (ctrl & RTC_DM_BINARY) ? "no" : "yes",
p += sprintf(p, "update_int : %s\n", (ctrl & RTC_24H) ? "yes" : "no",
((ctrl & RTC_UIE) ? "yes" : "no" )); (ctrl & RTC_SQWE) ? "yes" : "no",
p += sprintf(p, "periodic_int : %s\n", (ctrl & RTC_AIE) ? "yes" : "no",
((ctrl & RTC_PIE) ? "yes" : "no" )); (ctrl & RTC_UIE) ? "yes" : "no",
(ctrl & RTC_PIE) ? "yes" : "no",
p += sprintf(p, "periodic_freq : %d\n", rtc_freq,
(freq ? (65536/(1<<freq)) : 0)); batt ? "okay" : "dead");
p += sprintf(p, "battery_ok : %s\n",
(batt ? "yes" : "no"));
return p - buf; return p - buf;
} }
...@@ -622,6 +678,7 @@ inline unsigned char rtc_is_updating(void) ...@@ -622,6 +678,7 @@ inline unsigned char rtc_is_updating(void)
unsigned char uip; unsigned char uip;
save_flags(flags); save_flags(flags);
cli();
uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP); uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
restore_flags(flags); restore_flags(flags);
return uip; return uip;
...@@ -744,7 +801,7 @@ inline void set_rtc_irq_bit(unsigned char bit) ...@@ -744,7 +801,7 @@ inline void set_rtc_irq_bit(unsigned char bit)
val |= bit; val |= bit;
CMOS_WRITE(val, RTC_CONTROL); CMOS_WRITE(val, RTC_CONTROL);
CMOS_READ(RTC_INTR_FLAGS); CMOS_READ(RTC_INTR_FLAGS);
restore_flags(flags);
rtc_irq_data = 0; rtc_irq_data = 0;
restore_flags(flags);
} }
...@@ -1610,7 +1610,7 @@ static int set_serial_info(struct async_struct * info, ...@@ -1610,7 +1610,7 @@ static int set_serial_info(struct async_struct * info,
* release the bus after transmitting. This must be done when * release the bus after transmitting. This must be done when
* the transmit shift register is empty, not be done when the * the transmit shift register is empty, not be done when the
* transmit holding register is empty. This functionality * transmit holding register is empty. This functionality
* allows RS485 driver to be written in user space. * allows an RS485 driver to be written in user space.
*/ */
static int get_lsr_info(struct async_struct * info, unsigned int *value) static int get_lsr_info(struct async_struct * info, unsigned int *value)
{ {
......
...@@ -2,98 +2,114 @@ ...@@ -2,98 +2,114 @@
# Network device configuration # Network device configuration
# #
tristate 'Dummy net driver support' CONFIG_DUMMY tristate 'Dummy net driver support' CONFIG_DUMMY
tristate 'SLIP (serial line) support' CONFIG_SLIP tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER
if [ "$CONFIG_SLIP" != "n" ]; then if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED tristate 'Frame relay DLCI support (EXPERIMENTAL)' CONFIG_DLCI
bool ' Keepalive and linefill' CONFIG_SLIP_SMART if [ "$CONFIG_DLCI" = "y" -o "$CONFIG_DLCI" = "m" ]; then
int ' Max open DLCI' CONFIG_DLCI_COUNT 24
int ' Max DLCI per device' CONFIG_DLCI_MAX 8
dep_tristate ' SDLA (Sangoma S502/S508) support' CONFIG_SDLA $CONFIG_DLCI
fi
fi fi
tristate 'PLIP (parallel port) support' CONFIG_PLIP
tristate 'PPP (point-to-point) support' CONFIG_PPP tristate 'PPP (point-to-point) support' CONFIG_PPP
if [ ! "$CONFIG_PPP" = "n" ]; then if [ ! "$CONFIG_PPP" = "n" ]; then
comment 'CCP compressors for PPP are only built as modules.' comment 'CCP compressors for PPP are only built as modules.'
fi fi
tristate 'STRIP (Metricom starmode radio IP)' CONFIG_STRIP tristate 'SLIP (serial line) support' CONFIG_SLIP
tristate 'WIC (Radio IP bridge)' CONFIG_WIC if [ "$CONFIG_SLIP" != "n" ]; then
tristate 'Z8530 SCC kiss emulation driver for AX.25' CONFIG_SCC bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED
tristate 'PLIP (parallel port) support' CONFIG_PLIP bool ' Keepalive and linefill' CONFIG_SLIP_SMART
tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER
tristate 'DLCI (Frame relay) support' CONFIG_DLCI
if [ "$CONFIG_DLCI" = "y" -o "$CONFIG_DLCI" = "m" ]; then
int ' Max open DLCI' CONFIG_DLCI_COUNT 24
int ' Max DLCI per device' CONFIG_DLCI_MAX 8
tristate ' SDLA (Sangoma S502/S508) support' CONFIG_SDLA
fi
bool 'Do you want to be offered ALPHA test drivers' CONFIG_NET_ALPHA
bool 'Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC
if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then
tristate 'WD80*3 support' CONFIG_WD80x3
tristate 'SMC Ultra support' CONFIG_ULTRA
tristate 'SMC 9194 support' CONFIG_SMC9194
fi fi
bool 'AMD LANCE and PCnet (AT1500 and NE2100) support' CONFIG_LANCE bool 'Radio network interfaces' CONFIG_NET_RADIO
if [ "$CONFIG_LANCE" = "y" ]; then if [ "$CONFIG_NET_RADIO" != "n" ]; then
bool 'AMD PCInet32 (VLB and PCI) support' CONFIG_LANCE32 if [ "$CONFIG_AX25" = "y" ]; then
bool 'Gracilis PackeTwin support' CONFIG_PT
bool 'Ottawa PI and PI/2 support' CONFIG_PI
fi
tristate 'STRIP (Metricom starmode radio IP)' CONFIG_STRIP
tristate 'WaveLAN support' CONFIG_WAVELAN
tristate 'WIC Radio IP bridge (EXPERIMENTAL)' CONFIG_WIC
if [ "$CONFIG_AX25" = "y" ]; then
tristate 'Z8530 SCC kiss emulation driver for AX.25' CONFIG_SCC
fi
fi fi
bool '3COM cards' CONFIG_NET_VENDOR_3COM #
if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then # Ethernet
#
bool 'Ethernet (10 or 100Mbit)' CONFIG_NET_ETHERNET
if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
bool '3COM cards' CONFIG_NET_VENDOR_3COM
if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then
tristate '3c501 support' CONFIG_EL1 tristate '3c501 support' CONFIG_EL1
tristate '3c503 support' CONFIG_EL2 tristate '3c503 support' CONFIG_EL2
if [ "$CONFIG_NET_ALPHA" = "y" ]; then if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate '3c505 support' CONFIG_ELPLUS tristate '3c505 support' CONFIG_ELPLUS
tristate '3c507 support' CONFIG_EL16 tristate '3c507 support' CONFIG_EL16
fi fi
tristate '3c509/3c579 support' CONFIG_EL3 tristate '3c509/3c579 support' CONFIG_EL3
tristate '3c590 series (592/595/597) "Vortex" support' CONFIG_VORTEX tristate '3c590 series (592/595/597) "Vortex" support' CONFIG_VORTEX
fi fi
bool 'Other ISA cards' CONFIG_NET_ISA bool 'AMD LANCE and PCnet (AT1500 and NE2100) support' CONFIG_LANCE
if [ "$CONFIG_NET_ISA" = "y" ]; then if [ "$CONFIG_LANCE" = "y" ]; then
bool 'AMD PCInet32 (VLB and PCI) support' CONFIG_LANCE32
fi
bool 'Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC
if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then
tristate 'WD80*3 support' CONFIG_WD80x3
tristate 'SMC Ultra support' CONFIG_ULTRA
tristate 'SMC 9194 support' CONFIG_SMC9194
fi
bool 'Other ISA cards' CONFIG_NET_ISA
if [ "$CONFIG_NET_ISA" = "y" ]; then
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate 'AT1700 support (EXPERIMENTAL)' CONFIG_AT1700
fi
tristate 'Cabletron E21xx support' CONFIG_E2100 tristate 'Cabletron E21xx support' CONFIG_E2100
tristate 'DEPCA support' CONFIG_DEPCA tristate 'DEPCA support' CONFIG_DEPCA
tristate 'EtherWorks 3 support' CONFIG_EWRK3 tristate 'EtherWorks 3 support' CONFIG_EWRK3
tristate 'EtherExpress 16 support' CONFIG_EEXPRESS tristate 'EtherExpress 16 support' CONFIG_EEXPRESS
if [ "$CONFIG_NET_ALPHA" = "y" ]; then if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool 'SEEQ8005 support' CONFIG_SEEQ8005
tristate 'AT1700 support' CONFIG_AT1700
tristate 'FMV-181/182 support' CONFIG_FMV18X
tristate 'EtherExpressPro support' CONFIG_EEXPRESS_PRO tristate 'EtherExpressPro support' CONFIG_EEXPRESS_PRO
tristate 'NI5210 support' CONFIG_NI52 tristate 'FMV-181/182 support' CONFIG_FMV18X
bool 'NI6510 support' CONFIG_NI65
tristate 'WaveLAN support' CONFIG_WAVELAN
tristate 'ICL EtherTeam 16i/32 support' CONFIG_ETH16I
fi fi
tristate 'HP PCLAN+ (27247B and 27252A) support' CONFIG_HPLAN_PLUS tristate 'HP PCLAN+ (27247B and 27252A) support' CONFIG_HPLAN_PLUS
tristate 'HP PCLAN (27245 and other 27xxx series) support' CONFIG_HPLAN tristate 'HP PCLAN (27245 and other 27xxx series) support' CONFIG_HPLAN
tristate 'HP 10/100VG PCLAN (ISA, EISA, PCI) support' CONFIG_HP100 tristate 'HP 10/100VG PCLAN (ISA, EISA, PCI) support' CONFIG_HP100
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate 'ICL EtherTeam 16i/32 support' CONFIG_ETH16I
fi
tristate 'NE2000/NE1000 support' CONFIG_NE2000 tristate 'NE2000/NE1000 support' CONFIG_NE2000
if [ "$CONFIG_AX25" = "y" ]; then if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool 'Ottawa PI and PI/2 support' CONFIG_PI tristate 'NI5210 support' CONFIG_NI52
bool 'Gracilis PackeTwin support' CONFIG_PT bool 'NI6510 support' CONFIG_NI65
fi
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool 'SEEQ8005 support (EXPERIMENTAL)' CONFIG_SEEQ8005
fi fi
bool 'SK_G16 support' CONFIG_SK_G16 bool 'SK_G16 support' CONFIG_SK_G16
fi fi
bool 'EISA, VLB, PCI and on board controllers' CONFIG_NET_EISA bool 'EISA, VLB, PCI and on board controllers' CONFIG_NET_EISA
if [ "$CONFIG_NET_EISA" = "y" ]; then if [ "$CONFIG_NET_EISA" = "y" ]; then
if [ "$CONFIG_NET_ALPHA" = "y" ]; then if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate 'Ansel Communications EISA 3200 support' CONFIG_AC3200 tristate 'Ansel Communications EISA 3200 support (EXPERIMENTAL)' CONFIG_AC3200
fi fi
tristate 'Apricot Xen-II on board ethernet' CONFIG_APRICOT tristate 'Apricot Xen-II on board ethernet' CONFIG_APRICOT
tristate 'DE425, DE434, DE435, DE500 support' CONFIG_DE4X5 tristate 'DE425, DE434, DE435, DE500 support' CONFIG_DE4X5
tristate 'DECchip Tulip (dc21x4x) PCI support' CONFIG_DEC_ELCP tristate 'DECchip Tulip (dc21x4x) PCI support' CONFIG_DEC_ELCP
tristate 'Digi Intl. RightSwitch SE-X support' CONFIG_DGRS tristate 'Digi Intl. RightSwitch SE-X support' CONFIG_DGRS
# bool 'LPL T100V 100Mbs support' CONFIG_LPL_T100 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
# bool 'PCnet32 (32 bit VLB and PCI LANCE) support' CONFIG_PCNET32 bool 'Zenith Z-Note support (EXPERIMENTAL)' CONFIG_ZNET
bool 'Zenith Z-Note support' CONFIG_ZNET fi
fi fi
bool 'Pocket and portable adaptors' CONFIG_NET_POCKET bool 'Pocket and portable adaptors' CONFIG_NET_POCKET
if [ "$CONFIG_NET_POCKET" = "y" ]; then if [ "$CONFIG_NET_POCKET" = "y" ]; then
bool 'AT-LAN-TEC/RealTek pocket adaptor support' CONFIG_ATP bool 'AT-LAN-TEC/RealTek pocket adaptor support' CONFIG_ATP
tristate 'D-Link DE600 pocket adaptor support' CONFIG_DE600 tristate 'D-Link DE600 pocket adaptor support' CONFIG_DE600
tristate 'D-Link DE620 pocket adaptor support' CONFIG_DE620 tristate 'D-Link DE620 pocket adaptor support' CONFIG_DE620
# bool 'Silicom pocket adaptor support' CONFIG_SILICOM_PEA fi
# bool 'WaveLAN PCMCIA support' CONFIG_WaveLAN
# bool '3 Com 3c589 PCMCIA support' CONFIG_3C589
fi fi
bool 'Token Ring driver support' CONFIG_TR bool 'Token Ring driver support' CONFIG_TR
if [ "$CONFIG_TR" = "y" ]; then if [ "$CONFIG_TR" = "y" ]; then
tristate 'IBM Tropic chipset based adaptor support' CONFIG_IBMTR tristate 'IBM Tropic chipset based adaptor support' CONFIG_IBMTR
......
...@@ -266,7 +266,7 @@ printk("Required room: %d, Tunnel hlen: %d\n", max_headroom, TUNL_HLEN); ...@@ -266,7 +266,7 @@ printk("Required room: %d, Tunnel hlen: %d\n", max_headroom, TUNL_HLEN);
new_skb->h.iph = (struct iphdr *) skb_push(new_skb, tunnel_hlen); new_skb->h.iph = (struct iphdr *) skb_push(new_skb, tunnel_hlen);
/* Free the old packet, we no longer need it */ /* Free the old packet, we no longer need it */
kfree_skb(skb, FREE_WRITE); dev_kfree_skb(skb, FREE_WRITE);
skb = new_skb; skb = new_skb;
} }
......
...@@ -653,7 +653,7 @@ static void boot_it(void) ...@@ -653,7 +653,7 @@ static void boot_it(void)
if (!obp_system_intr()) if (!obp_system_intr())
ctrl_alt_del(); ctrl_alt_del();
/* sigh.. atempt to prevent multiple entry */ /* sigh.. attempt to prevent multiple entry */
last_keycode=1; last_keycode=1;
rep = 0; rep = 0;
} }
......
...@@ -154,7 +154,8 @@ static int baud_table[] = { ...@@ -154,7 +154,8 @@ static int baud_table[] = {
0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
9600, 19200, 38400, 57600, 115200, 0 }; 9600, 19200, 38400, 57600, 115200, 0 };
/* Reading and writing Zilog8530 registers. The delays are to make this /*
* Reading and writing Zilog8530 registers. The delays are to make this
* driver work on the Sun4 which needs a settling delay after each chip * driver work on the Sun4 which needs a settling delay after each chip
* register access, other machines handle this in hardware via auxiliary * register access, other machines handle this in hardware via auxiliary
* flip-flops which implement the settle time we do in software. * flip-flops which implement the settle time we do in software.
...@@ -674,10 +675,9 @@ static void do_serial_hangup(void *private_) ...@@ -674,10 +675,9 @@ static void do_serial_hangup(void *private_)
/* /*
* This subroutine is called when the RS_TIMER goes off. It is used * This subroutine is called when the RS_TIMER goes off. It is used
* by the serial driver to handle ports that do not have an interrupt * by the serial driver to handle ports that do not have an interrupt
* (irq=0). This doesn't work very well for 16450's, but gives barely * (irq=0). This doesn't work at all for 16450's, as a sun has a Z8530.
* passable results for a 16550A. (Although at the expense of much
* CPU overhead).
*/ */
static void rs_timer(void) static void rs_timer(void)
{ {
printk("rs_timer called\n"); printk("rs_timer called\n");
...@@ -1009,7 +1009,7 @@ static void rs_fair_output(void) ...@@ -1009,7 +1009,7 @@ static void rs_fair_output(void)
left = MIN(info->xmit_cnt, left-1); left = MIN(info->xmit_cnt, left-1);
} }
/* Last character is being transmitted now (hopefuly). */ /* Last character is being transmitted now (hopefully). */
zs_conschan->control = RES_Tx_P; zs_conschan->control = RES_Tx_P;
udelay(5); udelay(5);
...@@ -1302,7 +1302,7 @@ static int set_serial_info(struct sun_serial * info, ...@@ -1302,7 +1302,7 @@ static int set_serial_info(struct sun_serial * info,
* release the bus after transmitting. This must be done when * release the bus after transmitting. This must be done when
* the transmit shift register is empty, not be done when the * the transmit shift register is empty, not be done when the
* transmit holding register is empty. This functionality * transmit holding register is empty. This functionality
* allows RS485 driver to be written in user space. * allows an RS485 driver to be written in user space.
*/ */
static int get_lsr_info(struct sun_serial * info, unsigned int *value) static int get_lsr_info(struct sun_serial * info, unsigned int *value)
{ {
......
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
*/ */
#if defined(HOSTS_C) || defined(MODULE) #if defined(HOSTS_C) || defined(MODULE)
#include <linux/scsicam.h> #include <scsi/scsicam.h>
extern int NCR53c7xx_abort(Scsi_Cmnd *); extern int NCR53c7xx_abort(Scsi_Cmnd *);
extern int NCR53c7xx_detect(Scsi_Host_Template *tpnt); extern int NCR53c7xx_detect(Scsi_Host_Template *tpnt);
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#ifndef AM53C974_H #ifndef AM53C974_H
#define AM53C974_H #define AM53C974_H
#include <linux/scsicam.h> #include <scsi/scsicam.h>
/*************************************************************************************** /***************************************************************************************
* Default setting of the controller's SCSI id. Edit and uncomment this only if your * * Default setting of the controller's SCSI id. Edit and uncomment this only if your *
......
This diff is collapsed.
/* aha152x.c -- Adaptec AHA-152x driver /* aha152x.c -- Adaptec AHA-152x driver
* Author: Juergen E. Fischer, fischer@et-inf.fho-emden.de * Author: Juergen E. Fischer, fischer@et-inf.fho-emden.de
* Copyright 1993, 1994, 1995 Juergen E. Fischer * Copyright 1993, 1994, 1995, 1996 Juergen E. Fischer
* *
* *
* This driver is based on * This driver is based on
...@@ -20,9 +20,13 @@ ...@@ -20,9 +20,13 @@
* General Public License for more details. * General Public License for more details.
* *
* *
* $Id: aha152x.c,v 1.14 1996/01/17 15:11:20 fischer Exp fischer $ * $Id: aha152x.c,v 1.15 1996/04/30 14:52:06 fischer Exp fischer $
* *
* $Log: aha152x.c,v $ * $Log: aha152x.c,v $
* Revision 1.15 1996/04/30 14:52:06 fischer
* - proc info fixed
* - support for extended translation for >1GB disks
*
* Revision 1.14 1996/01/17 15:11:20 fischer * Revision 1.14 1996/01/17 15:11:20 fischer
* - fixed lockup in MESSAGE IN phase after reconnection * - fixed lockup in MESSAGE IN phase after reconnection
* *
...@@ -1205,18 +1209,23 @@ int aha152x_reset(Scsi_Cmnd *SCpnt) ...@@ -1205,18 +1209,23 @@ int aha152x_reset(Scsi_Cmnd *SCpnt)
*/ */
int aha152x_biosparam(Scsi_Disk * disk, kdev_t dev, int *info_array) int aha152x_biosparam(Scsi_Disk * disk, kdev_t dev, int *info_array)
{ {
int size = disk->capacity;
#if defined(DEBUG_BIOSPARAM) #if defined(DEBUG_BIOSPARAM)
if(HOSTDATA(shpnt)->debug & debug_biosparam) if(HOSTDATA(shpnt)->debug & debug_biosparam)
printk("aha152x_biosparam: dev=%s, size=%d, ", kdevname(dev), size); printk("aha152x_biosparam: dev=%s, size=%d, ",
kdevname(dev), disk->capacity);
#endif #endif
/* I took this from other SCSI drivers, since it provides if(disk->capacity<=1024*64*32) {
the correct data for my devices. */
info_array[0]=64; info_array[0]=64;
info_array[1]=32; info_array[1]=32;
info_array[2]=size>>11; info_array[2]=disk->capacity / (64 * 32);
} else {
info_array[0] = 256;
info_array[1] = 63;
info_array[2] = disk->capacity / (256 * 63);
if(info_array[2] > 1023)
info_array[2]=1023;
}
#if defined(DEBUG_BIOSPARAM) #if defined(DEBUG_BIOSPARAM)
if(HOSTDATA(shpnt)->debug & debug_biosparam) if(HOSTDATA(shpnt)->debug & debug_biosparam)
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#define _AHA152X_H #define _AHA152X_H
/* /*
* $Id: aha152x.h,v 1.14 1996/01/17 15:13:36 fischer Exp fischer $ * $Id: aha152x.h,v 1.15 1996/04/30 14:59:35 fischer Exp $
*/ */
#if defined(__KERNEL__) #if defined(__KERNEL__)
...@@ -23,7 +23,7 @@ int aha152x_proc_info(char *buffer, char **start, off_t offset, int length, int ...@@ -23,7 +23,7 @@ int aha152x_proc_info(char *buffer, char **start, off_t offset, int length, int
(unless we support more than 1 cmd_per_lun this should do) */ (unless we support more than 1 cmd_per_lun this should do) */
#define AHA152X_MAXQUEUE 7 #define AHA152X_MAXQUEUE 7
#define AHA152X_REVID "Adaptec 152x SCSI driver; $Revision: 1.14 $" #define AHA152X_REVID "Adaptec 152x SCSI driver; $Revision: 1.15 $"
extern struct proc_dir_entry proc_scsi_aha152x; extern struct proc_dir_entry proc_scsi_aha152x;
......
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