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.
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
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,
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
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
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
various ioctl(2) calls as listed in ./include/linux/mc146818rtc.h
......
......@@ -65,8 +65,8 @@ S: Status, one of the following:
Orphan: No current maintainer [but maybe you could take the
role as you write your new code].
Obsolete: Old code. Something tagged obsolete generally means
its been replaced by a better system and you should
be using that.
it has been replaced by a better system and you
should be using that.
3C501 NETWORK DRIVER
P: Alan Cox
......
VERSION = 1
PATCHLEVEL = 3
SUBLEVEL = 97
SUBLEVEL = 98
ARCH = i386
......
......@@ -9,6 +9,11 @@ unset CONFIG_CROSSCOMPILE CONFIG_NATIVE
unset CONFIG_PCI CONFIG_ALPHA_LCA CONFIG_ALPHA_APECS
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
comment 'Loadable module support'
bool 'Enable loadable module support' CONFIG_MODULES
......
......@@ -2,6 +2,11 @@
# Automatically generated make config: don't edit
#
#
# Code maturity level options
#
# CONFIG_EXPERIMENTAL is not set
#
# Loadable module support
#
......@@ -75,7 +80,6 @@ CONFIG_SKB_LARGE=y
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_AX25 is not set
# CONFIG_BRIDGE is not set
# CONFIG_NETLINK is not set
#
......@@ -133,25 +137,21 @@ CONFIG_SCSI_NCR53C7xx_FAST=y
#
CONFIG_NETDEVICES=y
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_DLCI is not set
# CONFIG_NET_ALPHA is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_LANCE is not set
# CONFIG_PLIP is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
# CONFIG_NET_RADIO is not set
CONFIG_NET_ETHERNET=y
# 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_EISA=y
# CONFIG_APRICOT is not set
CONFIG_DE4X5=y
# CONFIG_DEC_ELCP is not set
# CONFIG_DGRS is not set
# CONFIG_ZNET is not set
# CONFIG_NET_POCKET is not set
# CONFIG_TR is not set
# CONFIG_ARCNET is not set
......
......@@ -510,8 +510,10 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data,
return -EPERM;
if ((!child->dumpable ||
(current->uid != child->euid) ||
(current->uid != child->suid) ||
(current->uid != child->uid) ||
(current->gid != child->egid) ||
(current->gid != child->sgid) ||
(current->gid != child->gid)) && !suser())
return -EPERM;
/* the same process cannot be attached many times */
......
......@@ -4,6 +4,11 @@
#
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
comment 'Loadable module support'
bool 'Enable loadable module support' CONFIG_MODULES
......
......@@ -2,6 +2,11 @@
# Automatically generated make config: don't edit
#
#
# Code maturity level options
#
# CONFIG_EXPERIMENTAL is not set
#
# Loadable module support
#
......@@ -74,7 +79,6 @@ CONFIG_SKB_LARGE=y
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_AX25 is not set
# CONFIG_BRIDGE is not set
# CONFIG_NETLINK is not set
#
......@@ -87,22 +91,19 @@ CONFIG_SKB_LARGE=y
#
CONFIG_NETDEVICES=y
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_DLCI is not set
# CONFIG_NET_ALPHA is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_LANCE is not set
# CONFIG_PLIP is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
# CONFIG_NET_RADIO is not set
CONFIG_NET_ETHERNET=y
CONFIG_NET_VENDOR_3COM=y
# CONFIG_EL1 is not set
# CONFIG_EL2 is not set
CONFIG_EL3=y
# 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_EISA 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)
return -EPERM;
if ((!child->dumpable ||
(current->uid != child->euid) ||
(current->uid != child->suid) ||
(current->uid != child->uid) ||
(current->gid != child->egid) ||
(current->gid != child->sgid) ||
(current->gid != child->gid)) && !suser())
return -EPERM;
/* the same process cannot be attached many times */
......
......@@ -29,6 +29,7 @@
extern int setup_x86_irq(int, struct irqaction *);
#ifndef CONFIG_APM /* cycle counter may be unreliable */
/* Cycle counter value at the previous timer interrupt.. */
static unsigned long long last_timer_cc = 0;
static unsigned long long init_timer_cc = 0;
......@@ -82,6 +83,7 @@ static unsigned long do_fast_gettimeoffset(void)
quotient = 1000000/HZ-1;
return quotient;
}
#endif
/* This function must be called with interrupts disabled
* It was inspired by Steve McCanne's microtime-i386 for BSD. -- jrs
......@@ -176,8 +178,8 @@ void do_settimeofday(struct timeval *tv)
xtime = *tv;
time_state = TIME_BAD;
time_maxerror = 0x70000000;
time_esterror = 0x70000000;
time_maxerror = MAXPHASE;
time_esterror = MAXPHASE;
sti();
}
......@@ -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
* 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)
"=d" (((unsigned long *) &last_timer_cc)[1]));
timer_interrupt(irq, NULL, regs);
}
#endif
/* 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
......
......@@ -340,7 +340,7 @@ static inline void read_sunos_user(struct pt_regs *regs, unsigned long offset,
break;
case 948:
/* Isn't binary compatability _fun_??? */
/* Isn't binary compatibility _fun_??? */
if(cregs->psr & PSR_C)
regs->u_regs[UREG_I0] = cregs->u_regs[UREG_I0] << 24;
else
......
......@@ -99,7 +99,7 @@ available: floppy="daring two_fdc" insmod floppy
floppy=nofifo
Disables the FIFO entirely. This is needed if you get "Bus
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
Enables the FIFO (default)
......@@ -119,9 +119,9 @@ floppy=fifo
higher value, until you only get an occasional Over/Underrun.
It is a good idea to compile the floppy driver as a module
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
re-inseert the module.
re-insert the module.
Usually, tuning the fifo threshold should not be needed, as
the default (0xa) is reasonable.
......
......@@ -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".
"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=cdrom" : drive is present, and is a cdrom drive
"hdx=cyl,head,sect" : disk drive is present, with specified geometry
......
......@@ -110,7 +110,7 @@ static ide_tuneproc_t cmd640_tune_drive;
/* Interface to access cmd640x registers */
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 };
static int bus_type = none;
......
......@@ -42,6 +42,7 @@
* DTC2278S has only a single IDE interface.
* DTC2278D has two IDE interfaces and is otherwise identical to the S version.
* 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
* Winbond chip, and I think the E version does also.
......
......@@ -1733,9 +1733,6 @@ static void reset_interrupt(void)
{
#ifdef DEBUGT
debugt("reset interrupt:");
#endif
#ifdef __sparc__
fdc_specify(); /* P3: It gives us "sector not found" without this. */
#endif
result(); /* get the status ready for set_fdc */
if (FDCS->reset) {
......@@ -4004,6 +4001,10 @@ int floppy_init(void)
CLEARSTRUCT(FDCS);
FDCS->dtr = -1;
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;
......@@ -4036,6 +4037,7 @@ int floppy_init(void)
FDCS->rawcmd = 2;
if (user_reset_fdc(-1,FD_RESET_ALWAYS,0)){
FDCS->address = -1;
FDCS->version = FDC_NONE;
continue;
}
/* Try to determine the floppy controller type */
......@@ -4266,7 +4268,7 @@ void floppy_eject(void)
{
int dummy;
floppy_grab_irq_and_dma();
lock_fdc(0,0);
lock_fdc(MAXTIMEOUT,0);
dummy=fd_eject(0);
process_fd_request();
floppy_release_irq_and_dma();
......
......@@ -92,6 +92,8 @@
* Reformat to match kernel tabbing style.
* Add CDROM_GET_UPC ioctl.
* 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.
* 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,
struct cdrom_tocentry tocentry;
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,
sizeof (tocentry));
if (stat) return stat;
......@@ -2117,9 +2116,6 @@ int ide_cdrom_ioctl (ide_drive_t *drive, struct inode *inode,
stat = verify_area (VERIFY_WRITE, (void *) arg,
sizeof (subchnl));
if (stat) return stat;
stat = verify_area (VERIFY_READ, (void *) arg,
sizeof (subchnl));
if (stat) return stat;
memcpy_fromfs (&subchnl, (void *) arg, sizeof (subchnl));
......@@ -2228,9 +2224,6 @@ int ide_cdrom_ioctl (ide_drive_t *drive, struct inode *inode,
struct atapi_toc *toc;
int stat;
stat = verify_area (VERIFY_READ, (void *)arg,
sizeof (ms_info));
if (stat) return stat;
stat = verify_area (VERIFY_WRITE, (void *)arg,
sizeof (ms_info));
if (stat) return stat;
......@@ -2327,8 +2320,6 @@ int ide_cdrom_ioctl (ide_drive_t *drive, struct inode *inode,
format = 3;
}
stat = verify_area (VERIFY_READ, (char *)arg, sizeof (msf));
if (stat) return stat;
stat = verify_area (VERIFY_WRITE, (char *)arg, blocksize);
if (stat) return stat;
......
/*
* 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
* 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
}
#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 (bcount.b.high,IDETAPE_BCOUNTH_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)
*/
......@@ -227,6 +227,10 @@
* 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)
* 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
*
......@@ -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 */
udelay(5); /* more than enough time */
OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG); /* clear SRST, leave nIEN */
udelay(5); /* more than enough time */
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
ide_set_handler (drive, &reset_pollfunc, HZ/20);
#endif /* OK_TO_RESET_CONTROLLER */
......@@ -1476,6 +1481,8 @@ void ide_do_request (ide_hwgroup_t *hwgroup)
ide_hwif_t *hwif = hwgroup->hwif;
struct request *rq;
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
* only when a request is inserted using "ide_next".
......@@ -2405,8 +2412,17 @@ static int try_to_identify (ide_drive_t *drive, byte cmd)
irqs = probe_irq_off(irqs); /* get irq number */
if (irqs > 0)
HWIF(drive)->irq = irqs;
else /* Mmmm.. multiple IRQs */
else { /* Mmmm.. multiple 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;
}
......@@ -2542,7 +2558,7 @@ static void probe_cmos_for_drives (ide_hwif_t *hwif)
/* Extract drive geometry from CMOS+BIOS if not already setup */
for (unit = 0; unit < MAX_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->head = drive->bios_head = *(BIOS+2);
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
* "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=none" : drive is NOT present, ignore cmos and do not probe
* "hdx=nowerr" : ignore the WRERR_STAT bit on this drive
* "hdx=cdrom" : drive is present, and is a cdrom drive
* "hdx=cyl,head,sect" : disk drive is present, with specified geometry
......@@ -2737,33 +2754,35 @@ void ide_setup (char *s)
* Look for drive options: "hdx="
*/
if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) {
const char *hd_words[] = {"noprobe", "nowerr", "cdrom", "serialize",
"autotune", "noautotune", NULL};
const char *hd_words[] = {"none", "noprobe", "nowerr", "cdrom",
"serialize", "autotune", "noautotune", NULL};
unit = s[2] - 'a';
hw = unit / MAX_DRIVES;
unit = unit % MAX_DRIVES;
hwif = &ide_hwifs[hw];
drive = &hwif->drives[unit];
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;
goto done;
case -2: /* "nowerr" */
case -3: /* "nowerr" */
drive->bad_wstat = BAD_R_STAT;
hwif->noprobe = 0;
goto done;
case -3: /* "cdrom" */
case -4: /* "cdrom" */
drive->present = 1;
drive->media = ide_cdrom;
hwif->noprobe = 0;
goto done;
case -4: /* "serialize" */
case -5: /* "serialize" */
printk(" -- USE \"ide%d=serialize\" INSTEAD", hw);
goto do_serialize;
case -5: /* "autotune" */
case -6: /* "autotune" */
drive->autotune = 1;
goto done;
case -6: /* "noautotune" */
case -7: /* "noautotune" */
drive->autotune = 2;
goto done;
case 3: /* cyl,head,sect */
......@@ -2856,7 +2875,7 @@ void ide_setup (char *s)
}
#endif /* CONFIG_BLK_DEV_HT6560B */
#if CONFIG_BLK_DEV_QD6580
case -5: /* "qd6580" (no secondary i/f) */
case -5: /* "qd6580" (has secondary i/f) */
{
extern void init_qd6580 (void);
init_qd6580();
......@@ -3011,12 +3030,13 @@ static int init_irq (ide_hwif_t *hwif)
*/
for (index = 0; index < MAX_HWIFS; index++) {
if (index != hwif->index) {
ide_hwif_t *g = &ide_hwifs[index];
if (g->irq == hwif->irq || g->irq == mate_irq) {
if (hwgroup && !g->hwgroup)
g->hwgroup = hwgroup;
ide_hwif_t *h = &ide_hwifs[index];
if (h->irq == hwif->irq || h->irq == mate_irq) {
hwif->sharing_irq = h->sharing_irq = 1;
if (hwgroup && !h->hwgroup)
h->hwgroup = hwgroup;
else if (!hwgroup)
hwgroup = g->hwgroup;
hwgroup = h->hwgroup;
}
}
}
......
......@@ -313,6 +313,7 @@ typedef struct ide_drive_s {
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 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 */
#if FAKE_FDISK_FOR_EZDRIVE
unsigned remap_0_to_1 : 1; /* flag: partitioned with ezdrive */
......@@ -419,6 +420,7 @@ typedef struct hwif_s {
unsigned serialized : 1; /* serialized operation with mate hwif */
unsigned no_unmask : 1; /* disallow setting unmask bits */
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
unsigned is_promise2: 1; /* 2nd i/f on promise DC4030 */
#endif /* CONFIG_BLK_DEV_PROMISE */
......
......@@ -38,6 +38,9 @@
* and can work out the answers!
*
* 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)
......@@ -61,5 +64,6 @@ static void tune_qd6580 (ide_drive_t *drive, byte pio)
void init_qd6580 (void)
{
ide_hwifs[0].chipset = ide_qd6580;
ide_hwifs[1].chipset = ide_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>
* tty_io.c (init_dev): Change return code when user attempts to
......
......@@ -46,10 +46,11 @@ if [ "$CONFIG_APM" = "y" ]; then
bool ' Enable PM at boot time' CONFIG_APM_DO_ENABLE
bool ' Make CPU Idle calls when idle' CONFIG_APM_CPU_IDLE
bool ' Enable console blanking using APM' CONFIG_APM_DISPLAY_BLANK
bool ' Power off on shutdown' CONFIG_APM_POWER_OFF
fi
bool 'Watchdog Timer Support' CONFIG_WATCHDOG
if [ "$CONFIG_WATCHDOG" != "n" ]; then
bool ' Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT
bool ' Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT
tristate ' WDT Watchdog timer' CONFIG_WDT
if [ "$CONFIG_WDT" = "y" ]; then
bool ' WDT501 features' CONFIG_WDT_501
......
......@@ -24,15 +24,17 @@
* Prohibit APM BIOS calls unless apm_enabled.
* (Thanks to Ulrich Windl <Ulrich.Windl@rz.uni-regensburg.de>)
* April 1996, Stephen Rothwell (Stephen.Rothwell@canb.auug.org.au)
* Version 1.0
* Version 1.0 and 1.1
*
* History:
* 0.6b: first version in official kernel, Linux 1.3.46
* 0.7: changed /proc/apm format, Linux 1.3.58
* 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
* 1.0: use fixed device number, consolidate /proc/apm into
* this file, Linux 1.3.85
* 1.0: use fixed device number, consolidate /proc/apm into this file,
* Linux 1.3.85
* 1.1: support user-space standby and suspend, power off after system
* halted, Linux 1.3.98
*
* Reference:
*
......@@ -113,7 +115,9 @@ extern unsigned long get_cmos_time(void);
* 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
* 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
* 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;
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
static char * apm_event_name[] = {
......@@ -427,7 +431,7 @@ static int apm_get_event(apm_event_t *event)
return APM_SUCCESS;
}
static int apm_set_power_state(u_short state)
int apm_set_power_state(u_short state)
{
u_short error;
......@@ -567,13 +571,15 @@ static apm_event_t get_queued_event(struct apm_bios_struct * as)
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;
if (user_list == NULL)
return 0;
for (as = user_list; as != NULL; as = as->next) {
if (as == sender)
continue;
as->event_head = (as->event_head + 1) % APM_MAX_EVENTS;
if (as->event_head == as->event_tail)
as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS;
......@@ -656,7 +662,8 @@ static apm_event_t get_event(void)
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 * fix;
......@@ -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)
......@@ -682,18 +689,19 @@ static void check_events(void)
switch (event) {
case APM_SYS_STANDBY:
case APM_USER_STANDBY:
send_event(event, APM_STANDBY_RESUME);
send_event(event, APM_STANDBY_RESUME, NULL);
if (standbys_pending <= 0)
standby();
break;
case APM_USER_SUSPEND:
#ifdef CONFIG_APM_IGNORE_USER_SUSPEND
apm_set_power_state(APM_STATE_REJECT);
if (apm_bios_info.version > 0x100)
apm_set_power_state(APM_STATE_REJECT);
break;
#endif
case APM_SYS_SUSPEND:
send_event(event, APM_NORMAL_RESUME);
send_event(event, APM_NORMAL_RESUME, NULL);
if (suspends_pending <= 0)
suspend();
break;
......@@ -702,12 +710,12 @@ static void check_events(void)
case APM_CRITICAL_RESUME:
case APM_STANDBY_RESUME:
set_time();
send_event(event, 0);
send_event(event, 0, NULL);
break;
case APM_LOW_BATTERY:
case APM_POWER_STATUS_CHANGE:
send_event(event, 0);
send_event(event, 0, NULL);
break;
case APM_UPDATE_TIME:
......@@ -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)) {
event = get_queued_event(as);
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);
i -= sizeof(event);
}
......@@ -867,22 +886,30 @@ static int do_ioctl(struct inode * inode, struct file *filp,
as = filp->private_data;
if (check_apm_bios_struct(as, "ioctl"))
return -EIO;
if (!as->suser)
return -EPERM;
switch (cmd) {
case APM_IOC_STANDBY:
if (as->standbys_pending > 0) {
if (as->standbys_read > 0) {
as->standbys_read--;
as->standbys_pending--;
standbys_pending--;
if (standbys_pending <= 0)
standby();
}
else
send_event(APM_USER_STANDBY, APM_STANDBY_RESUME, as);
if (standbys_pending <= 0)
standby();
break;
case APM_IOC_SUSPEND:
if (as->suspends_pending > 0) {
if (as->suspends_read > 0) {
as->suspends_read--;
as->suspends_pending--;
suspends_pending--;
if (suspends_pending <= 0)
suspend();
}
else
send_event(APM_USER_SUSPEND, APM_NORMAL_RESUME, as);
if (suspends_pending <= 0)
suspend();
break;
default:
return -EINVAL;
......@@ -938,6 +965,7 @@ static int do_open(struct inode * inode, struct file * filp)
as->magic = APM_BIOS_MAGIC;
as->event_tail = as->event_head = 0;
as->suspends_pending = as->standbys_pending = 0;
as->suspends_read = as->standbys_read = 0;
as->suser = suser();
as->next = user_list;
user_list = as;
......
......@@ -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)
LP_STAT(minor).maxrun = lp_table[minor].runchars;
status = LP_S(minor);
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_PSELECD)) {
if ((status & LP_OFFL) || !(status & LP_PSELECD)) {
printk(KERN_INFO "lp%d off-line\n", minor);
if (LP_F(minor) & LP_ABORT)
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)) {
printk(KERN_ERR "lp%d printer error\n", minor);
if (LP_F(minor) & LP_ABORT)
......@@ -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;
status = LP_S(minor);
if (status & LP_POUTPA) {
printk(KERN_INFO "lp%d out of paper\n", minor);
if ((status & LP_OFFL) || !(status & LP_PSELECD)) {
printk(KERN_INFO "lp%d off-line\n", minor);
if(LP_F(minor) & LP_ABORT)
return temp-buf?temp-buf:-ENOSPC;
return temp-buf?temp-buf:-EIO;
current->state = TASK_INTERRUPTIBLE;
current->timeout = jiffies + LP_TIMEOUT_POLLED;
schedule();
} else
if (!(status & LP_PSELECD)) {
printk(KERN_INFO "lp%d off-line\n", minor);
if (status & LP_POUTPA) {
printk(KERN_INFO "lp%d out of paper\n", minor);
if(LP_F(minor) & LP_ABORT)
return temp-buf?temp-buf:-EIO;
return temp-buf?temp-buf:-ENOSPC;
current->state = TASK_INTERRUPTIBLE;
current->timeout = jiffies + LP_TIMEOUT_POLLED;
schedule();
......
This diff is collapsed.
......@@ -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_IO_BASE 0x70 /* Or this... */
......@@ -67,6 +67,8 @@
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,
int origin);
......@@ -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_alm_time (struct tm *alm_tm);
void rtc_dropped_irq(unsigned long data);
inline void set_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);
*/
#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 long rtc_freq = 0; /* Current periodic IRQ rate */
unsigned long rtc_irq_data = 0; /* our output to the world */
unsigned char days_in_mo[] =
......@@ -119,6 +124,12 @@ static void rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
rtc_irq_data &= ~0xff;
rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);
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
break;
}
schedule();
continue;
}
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;
restore_flags(flags);
memcpy_tofs(buf, &data, sizeof(unsigned long));
retval = sizeof(unsigned long);
}
......@@ -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 */
{
mask_rtc_irq_bit(RTC_PIE);
if (rtc_status & RTC_TIMER_ON) {
del_timer(&rtc_irq_timer);
rtc_status &= ~RTC_TIMER_ON;
}
return 0;
}
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
* than 64Hz of interrupts on a multi-user machine.
*/
if ((hz > 64) && (!suser()))
if ((rtc_freq > 64) && (!suser()))
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);
return 0;
}
......@@ -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. */
{
unsigned long hz;
int retval;
retval = verify_area(VERIFY_WRITE, (unsigned long*)arg, sizeof(unsigned long));
if (retval != 0)
return retval;
save_flags(flags);
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));
memcpy_tofs((unsigned long*)arg, &rtc_freq, sizeof(unsigned long));
return 0;
}
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,
/*
* The max we can do is 8192Hz.
*/
if (arg > 8192)
if ((arg < 2) || (arg > 8192))
return -EINVAL;
/*
* 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,
if ((arg != 0) && (arg != (1<<tmp)))
return -EINVAL;
rtc_freq = arg;
save_flags(flags);
cli();
val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0;
......@@ -480,6 +494,12 @@ static void rtc_release(struct inode *inode, struct file *file)
CMOS_WRITE(tmp, RTC_CONTROL);
CMOS_READ(RTC_INTR_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_status &= ~RTC_IS_OPEN;
}
......@@ -520,6 +540,8 @@ static struct miscdevice rtc_dev=
int rtc_init(void)
{
unsigned long flags;
printk("Real Time Clock Driver v%s\n", RTC_VERSION);
if(request_irq(RTC_IRQ, rtc_interrupt, SA_INTERRUPT, "rtc", NULL))
{
......@@ -530,10 +552,46 @@ int rtc_init(void)
misc_register(&rtc_dev);
/* Check region? Naaah! Just snarf it up. */
request_region(RTC_IO_BASE, RTC_IO_EXTENT, "rtc");
init_timer(&rtc_irq_timer);
rtc_irq_timer.function = rtc_dropped_irq;
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;
}
/*
* 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".
*/
......@@ -542,11 +600,11 @@ int get_rtc_status(char *buf)
{
char *p;
struct tm tm;
unsigned char freq, batt, ctrl;
unsigned char batt, ctrl;
unsigned long flags;
save_flags(flags);
freq = CMOS_READ(RTC_FREQ_SELECT) & 0x0F;
cli();
batt = CMOS_READ(RTC_VALID) & RTC_VRT;
ctrl = CMOS_READ(RTC_CONTROL);
restore_flags(flags);
......@@ -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
* 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);
p += sprintf(p, "time : %02d-%02d-%02d\n",
tm.tm_hour, tm.tm_min, tm.tm_sec);
get_rtc_alm_time(&tm);
......@@ -571,44 +630,41 @@ int get_rtc_status(char *buf)
* match any value for that particular field. Values that are
* 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)
p += sprintf(p, "%02d", tm.tm_hour);
p += sprintf(p, "%02d:", tm.tm_hour);
else
p += sprintf(p, "**");
p += sprintf(p, "-");
p += sprintf(p, "**:");
if (tm.tm_min <= 59)
p += sprintf(p, "%02d", tm.tm_min);
p += sprintf(p, "%02d:", tm.tm_min);
else
p += sprintf(p, "**");
p += sprintf(p, "-");
p += sprintf(p, "**:");
if (tm.tm_sec <= 59)
p += sprintf(p, "%02d", tm.tm_sec);
p += sprintf(p, "%02d\n", tm.tm_sec);
else
p += sprintf(p, "**");
p += sprintf(p, "\n");
p += sprintf(p, "daylight : %s\n",
((ctrl & RTC_DST_EN) ? "yes" : "no" ));
p += sprintf(p, "bcd : %s\n",
((ctrl & RTC_DM_BINARY) ? "no" : "yes" ));
p += sprintf(p, "24hr : %s\n",
((ctrl & RTC_24H) ? "yes" : "no" ));
p += sprintf(p, "sqwave : %s\n",
((ctrl & RTC_SQWE) ? "yes" : "no" ));
p += sprintf(p, "alarm_int : %s\n",
((ctrl & RTC_AIE) ? "yes" : "no" ));
p += sprintf(p, "update_int : %s\n",
((ctrl & RTC_UIE) ? "yes" : "no" ));
p += sprintf(p, "periodic_int : %s\n",
((ctrl & RTC_PIE) ? "yes" : "no" ));
p += sprintf(p, "periodic_freq : %d\n",
(freq ? (65536/(1<<freq)) : 0));
p += sprintf(p, "battery_ok : %s\n",
(batt ? "yes" : "no"));
p += sprintf(p, "**\n");
p += sprintf(p,
"DST_enable\t: %s\n"
"BCD\t\t: %s\n"
"24hr\t\t: %s\n"
"sqare_wave\t: %s\n"
"alarm_IRQ\t: %s\n"
"update_IRQ\t: %s\n"
"periodic_IRQ\t: %s\n"
"periodic_freq\t: %ld\n"
"batt_status\t: %s\n",
(ctrl & RTC_DST_EN) ? "yes" : "no",
(ctrl & RTC_DM_BINARY) ? "no" : "yes",
(ctrl & RTC_24H) ? "yes" : "no",
(ctrl & RTC_SQWE) ? "yes" : "no",
(ctrl & RTC_AIE) ? "yes" : "no",
(ctrl & RTC_UIE) ? "yes" : "no",
(ctrl & RTC_PIE) ? "yes" : "no",
rtc_freq,
batt ? "okay" : "dead");
return p - buf;
}
......@@ -622,6 +678,7 @@ inline unsigned char rtc_is_updating(void)
unsigned char uip;
save_flags(flags);
cli();
uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
restore_flags(flags);
return uip;
......@@ -744,7 +801,7 @@ inline void set_rtc_irq_bit(unsigned char bit)
val |= bit;
CMOS_WRITE(val, RTC_CONTROL);
CMOS_READ(RTC_INTR_FLAGS);
restore_flags(flags);
rtc_irq_data = 0;
restore_flags(flags);
}
......@@ -1610,7 +1610,7 @@ static int set_serial_info(struct async_struct * info,
* release the bus after transmitting. This must be done when
* the transmit shift register is empty, not be done when the
* 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)
{
......
This diff is collapsed.
......@@ -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);
/* Free the old packet, we no longer need it */
kfree_skb(skb, FREE_WRITE);
dev_kfree_skb(skb, FREE_WRITE);
skb = new_skb;
}
......
......@@ -653,7 +653,7 @@ static void boot_it(void)
if (!obp_system_intr())
ctrl_alt_del();
/* sigh.. atempt to prevent multiple entry */
/* sigh.. attempt to prevent multiple entry */
last_keycode=1;
rep = 0;
}
......
......@@ -154,7 +154,8 @@ static int baud_table[] = {
0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
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
* register access, other machines handle this in hardware via auxiliary
* flip-flops which implement the settle time we do in software.
......@@ -674,10 +675,9 @@ static void do_serial_hangup(void *private_)
/*
* 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
* (irq=0). This doesn't work very well for 16450's, but gives barely
* passable results for a 16550A. (Although at the expense of much
* CPU overhead).
* (irq=0). This doesn't work at all for 16450's, as a sun has a Z8530.
*/
static void rs_timer(void)
{
printk("rs_timer called\n");
......@@ -1009,7 +1009,7 @@ static void rs_fair_output(void)
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;
udelay(5);
......@@ -1302,7 +1302,7 @@ static int set_serial_info(struct sun_serial * info,
* release the bus after transmitting. This must be done when
* the transmit shift register is empty, not be done when the
* 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)
{
......
......@@ -54,7 +54,7 @@
*/
#if defined(HOSTS_C) || defined(MODULE)
#include <linux/scsicam.h>
#include <scsi/scsicam.h>
extern int NCR53c7xx_abort(Scsi_Cmnd *);
extern int NCR53c7xx_detect(Scsi_Host_Template *tpnt);
......
......@@ -27,7 +27,7 @@
#ifndef 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 *
......
This file contains brief information about the SCSI tape driver.
Last modified: Sun Apr 21 21:19:22 1996 by root@kai.makisara.fi
Last modified: Wed May 1 11:51:35 1996 by root@kai.makisara.fi
BASICS
......@@ -62,6 +62,11 @@ The driver supports fixed and variable block size (within buffer
limits). Both the auto-rewind (minor equals device number) and
non-rewind devices (minor is 128 + device number) are implemented.
Support is provided for changing the tape partition and partitioning
of the tape with one or two partitions. By default support for
partitioned tape is disabled for each driver and it can be enabled
with the ioctl MTSETDRVBUFFER.
By default the driver writes one filemark when the device is closed after
writing and the last operation has been a write. Two filemarks can be
optionally written. In both cases end of data is signified by
......@@ -181,7 +186,20 @@ MTCOMPRESSION Sets compressing or uncompressing drive mode using the
SCSI mode page 15. Note that some drives other methods for
control of compression. Some drives (like the Exabytes) use
density codes for compression control. Some drives use another
mode page but this page has not been implemented in the driver.
mode page but this page has not been implemented in the
driver.
MTSETPART Moves the tape to the partition given by the argument at the
next tape operation. The block at which the tape is positioned
is the block where the tape was previously positioned in the
new active partition unless the next tape operation is
MTSEEK. In this case the tape is moved directly to the block
specified by MTSEEK. MTSETPART is inactive unless
MT_ST_CAN_PARTITIONS set.
MTMKPART Formats the tape with one partition (argument zero) or two
partitions (the argument gives in megabytes the size of
partition 1 that is physically the first partition of the
tape). The drive has to support partitions with size specified
by the initiator. Inactive unless MT_ST_CAN_PARTITIONS set.
MTSETDRVBUFFER
Is used for several purposes. The command is obtained from count
with mask MT_SET_OPTIONS, the low order bits are used as argument.
......@@ -202,11 +220,18 @@ MTSETDRVBUFFER
MT_ST_FAST_EOM using the SCSI spacing to EOD (global)
MT_ST_AUTO_LOCK automatic locking of the drive door (global)
MT_ST_DEF_WRITES the defaults are meant only for writes (mode)
MT_ST_CAN_BSR backspacing over records can be used for
repositioning the tape (global)
MT_ST_CAN_BSR backspacing over more than one records can
be used for repositioning the tape (global)
MT_ST_NO_BLKLIMS the driver does not ask the block limits
from the drive (block size can be changed only to
variable) (global)
MT_ST_CAN_PARTITIONS enables support for partitioned
tapes (global)
MT_ST_SCSI2LOGICAL the logical block number is used in
the MTSEEK and MTIOCPOS for SCSI-2 drives instead of
the device dependent address. It is recommended to set
this flag unless there are tapes using the device
dependent (from the old times) (global)
MT_ST_DEBUGGING debugging (global; debugging must be
compiled into the driver)
MT_ST_SETBOOLEANS
......@@ -246,6 +271,15 @@ MTIOCGET Returns some status information.
is set if there is no tape in the drive. GMT_EOD means either
end of recorded data or end of tape. GMT_EOT means end of tape.
The following ioctls use the structure mtlocation that contains both
the block number and the partition number. These ioctls are available
only for SCSI-2 tape drives and the block number is the
device-indepent logical block number defined by the standard.
MTGETLOC Returns the current block and partition number.
MTSETLOC Sets the tape to the block and partition specified by the
arguments.
MISCELLANEOUS COMPILE OPTIONS
......@@ -257,7 +291,11 @@ ST_MAX_TAPES. If more tapes are detected at driver initialization, the
maximum is adjusted accordingly.
Immediate return from tape positioning SCSI commands can be enabled by
defining ST_NOWAIT.
defining ST_NOWAIT. If this is defined, the user should take care that
the next tape operation is not started before the previous one has
finished. The drives and SCSI adapters should handle this condition
gracefully, but some drive/adapter combinations are known to hang the
SCSI bus in this case.
The MTEOM command is by default implemented as spacing over 32767
filemarks. With this method the file number in the status is
......@@ -268,8 +306,9 @@ number will be invalid.
When using read ahead or buffered writes the position within the file
may not be correct after the file is closed (correct position may
require backspacing over more than one record). The correct position
within file can be obtained if ST_IN_FILE_POS is defined. (The
driver always backs over a filemark crossed by read ahead if the user
does not request data that far.)
within file can be obtained if ST_IN_FILE_POS is defined at compile
time or the MT_ST_CAN_BSR bit is set for the drive with an ioctl.
(The driver always backs over a filemark crossed by read ahead if the
user does not request data that far.)
Kai M{kisara
This diff is collapsed.
......@@ -2,7 +2,7 @@
#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__)
......@@ -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) */
#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;
......
This diff is collapsed.
......@@ -4,7 +4,7 @@
#ifndef _EATA_H
#define _EATA_H
#include <linux/scsicam.h>
#include <scsi/scsicam.h>
int eata2x_detect(Scsi_Host_Template *);
int eata2x_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
......
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