Commit a1142b87 authored by Linus Torvalds's avatar Linus Torvalds

Import 1.3.85

parent 892692fb
......@@ -961,7 +961,7 @@ S: 7000 Stuttgart 50
S: Germany
N: Stephen Rothwell
E: Stephen.Rothwell@nec.com.au
E: Stephen.Rothwell@canb.auug.org.au
D: Boot/setup/build work for setup > 2K
D: Author, APM driver
S: 59 Bugden Avenue
......
......@@ -1236,16 +1236,14 @@ CONFIG_SCSI_U14_34F
Future Domain 16xx SCSI support
CONFIG_SCSI_FUTURE_DOMAIN
This is support for Future Domain's 16-bit SCSI host adaptors
(TMC-1660/1680, TMC-1650/1670, TMC-3260) and other adaptors based on
the Future Domain chipsets (Quantum ISA-200S, ISA-250MG; and at
least one IBM board). It is explained in section 3.7 of the
SCSI-HOWTO, available via ftp (user: anonymous) at
sunsite.unc.edu:/pub/Linux/docs/HOWTO. If it doesn't work out of
the box, you may have to change some settings in
drivers/scsi/fdomain.h. This driver is also available as a module (
= code which can be inserted in and removed from the running kernel
whenever you want). If you want to compile it as a module, say M
here and read Documentation/modules.txt.
(TMC-1660/1680, TMC-1650/1670, TMC-3260, TMC-1610M/MER/MEX) and other
adaptors based on the Future Domain chipsets (Quantum ISA-200S,
ISA-250MG; Adaptec AHA-2920; and at least one IBM board). It is
explained in section 3.7 of the SCSI-HOWTO, available via ftp (user:
anonymous) at sunsite.unc.edu:/pub/Linux/docs/HOWTO. This driver is
also available as a module ( = code which can be inserted in and
removed from the running kernel whenever you want). If you want to
compile it as a module, say M here and read Documentation/modules.txt.
Generic NCR5380/53c400 SCSI support
CONFIG_SCSI_GENERIC_NCR5380
......@@ -2878,14 +2876,21 @@ CONFIG_SUN_ZS
Advanced Power Management
CONFIG_APM
APM is a BIOS standard for saving power using several different
techniques. This is mostly useful for battery powered laptops with
APM compliant BIOSes. Specifically, the time will be reset after a
USER RESUME operation, the /proc/apm device will provide battery
status information, and ioctls are provided to put the machine in
STANDBY or SUSPEND mode. This driver does not work for the TI 4000M
TravelMate and the ACER 486/DX4/75 because they don't follow the
standard. Say Y if you have a different laptop.
APM is a BIOS specification for saving power using several different
techniques. This is mostly useful for battery powered laptops with APM
compliant BIOSes. Specifically, the time will be reset after a USER
RESUME operation, the /proc/apm device will provide battery status
information, and user-space programs will receive notification of APM
"events" (e.g., battery status change). This driver does not spin down
disk drives (see hdparm(8) for that); and it doesn't turn off
VESA-compliant "green" monitors. This driver does not support the TI
4000M TravelMate and the ACER 486/DX4/75 because they don't have
compliant BIOSes. Many "green" desktop machines also don't have
compliant BIOSes, and this driver will cause those machines to panic
during the boot phase (typically, these machines are using a data
segment of 0040, which is reserved for the Linux kernel). If you don't
have a battery in your machine, there isn't much point in using this
driver.
Ignore USER SUSPEND
CONFIG_APM_IGNORE_USER_SUSPEND
......@@ -2897,16 +2902,37 @@ Enable APM features
CONFIG_APM_DO_ENABLE
Enable APM features at boot time. From page 36 of the APM BIOS
specification: "When disabled, the APM BIOS does not automatically
power manage devices, enter the Standby State, enter the Suspend
State, or take power saving steps in response to CPU Idle calls."
This driver will make CPU Idle calls when Linux is idle (unless this
feature is turned off -- see below). This should always save
battery power, but more complicated APM features will be dependent
on your BIOS implementation. You may need to turn this option off
if your computer hangs at boot time when using APM support, or if it
beeps continuously instead of suspending. Turn this off if you have
a NEC UltraLite Versa 33/C or a Toshiba T400CDT. This is off by
default since most machines do fine without this feature.
power manage devices, enter the Standby State, enter the Suspend State,
or take power saving steps in response to CPU Idle calls." This driver
will make CPU Idle calls when Linux is idle (unless this feature is
turned off -- see below). This should always save battery power, but
more complicated APM features will be dependent on your BIOS
implementation. You may need to turn this option off if your computer
hangs at boot time when using APM support, or if it beeps continuously
instead of suspending. Turn this off if you have a NEC UltraLite Versa
33/C or a Toshiba T400CDT. This is off by default since most machines
do fine without this feature.
Do CPU IDLE calls
CONFIG_APM_CPU_IDLE
Enable calls to APM CPU Idle/CPU Busy inside the kernel's idle loop.
On some machines, this can activate improved power savings, such as a
slowed CPU clock rate, when the machine is idle. These idle calls are
made after the idle loop has run for some length of time (e.g., 333
mS). On some machines, this will cause a hang at boot time or whenever
the CPU becomes idle. (On machines with more than one CPU, this option
does nothing.)
Black display
CONFIG_APM_DISPLAY_BLANK
Enable console blanking using the APM. Some laptops can use this to
turn off the LCD backlight when the VC screen blanker blanks the
screen. Note that this is only used by the VC screen blanker, and
won't turn off the backlight when using X11 (this also doesn't have
anything to do with your VESA-compliant power-saving monitor).
Further, this option doesn't work for all laptops -- it might not turn
off your backlight at all, or it might print a lot of errors to the
console.
Watchdog Timer Support
CONFIG_WATCHDOG
......@@ -2960,23 +2986,6 @@ CONFIG_SOFT_WATCHDOG
from some situations that the hardware watchdog will recover
from. Equally it's a lot cheaper to install.
Do CPU IDLE calls
CONFIG_APM_CPU_IDLE
Enable calls to APM CPU Idle/CPU Busy inside the kernel's idle loop.
On some machines, this can activate improved power savings, such as
a slowed CPU clock rate, when the machine is idle. These idle call
is made after the idle loop has run for some length of time (e.g.,
333 mS). On some machines, this will cause a hang at boot time or
whenever the CPU becomes idle. (On machines with more than one CPU,
this option does nothing.)
Black display
CONFIG_APM_DISPLAY_BLANK
Enable console blanking using the APM. Some laptops can use this to
turn off the LCD backlight when the VC screen blanker blanks the
screen. Note that this is only used by the VC screen blanker, and
won't turn off the backlight when using X11.
Sound card support
CONFIG_SOUND
If you have a Sound Card in your Computer, i.e. if it can say more
......
......@@ -7,12 +7,18 @@ The Digiboard Driver for Linux supports the following boards:
Limitations:
------------
Currently the Driver does not do autoprobing. You have to configure
the driver with the correct I/O address in drivers/char/pcxxconfig.h.
Currently the Driver does not do autoprobing!
The preconfigured I/O address is 0200h and the default memory address
0D0000h, ALT-PIN feature on and 16 ports available.
The preconfigured I/O address is 0200h and the default memory address 0D0000h.
Use them and you will not have to worry about configuring anything.
You can configure the driver via lilo. HAve look at the end of this
message. The default settings vanish as soon as you give a digi= commandline.
You can give multiple digi= commandline parameters to define multiple
boards.
Supporting Tools:
-----------------
Some tools and more detailed up to date information can be found at
......@@ -24,18 +30,23 @@ is also available.
Currently the Linux MAKEDEV command does not support generating the Digiboard
Devices. Use the following script to generate the devices:
WARNING: Most of the stuff available right now uses the WRONG Major Device
numbers and is severely outdated. Be careful and check them first.
Better not use any of the software in that directory if you run a recent
1.3.X Kernel!
------------------ mkdigidev begin
#!/bin/sh
#
# Script to create Digiboard Devices
# Christoph Lameter, April 4, 1996
# Christoph Lameter, April 6, 1996
#
# Usage:
# mkdigidev [<number of devices>]
#
DIGIMAJOR=30
DIGICUMAJOR=31
DIGI_MAJOR=22
DIGICU_MAJOR=23
BOARDS=$1
......@@ -69,4 +80,36 @@ Mailing List: digiboard@list.fuller.edu
(Write e-mail to that address to subscribe. Common ListServ commands work.
Archive of messages available)
Christoph Lameter (clameter@fuller.edu) 4. April 1996.
Christoph Lameter (clameter@fuller.edu) 6. April 1996.
-----------------------------------------------------------------------------
Changes v1.5.5:
The ability to use the kernel's command line to pass in the configuration for
boards. Using LILO's APPEND command, a string of comma seperated identifiers
or integers can be used. The 6 values in order are:
Enable/Disable this card,
Type of card: PC/Xi(0), PC/Xe(1), PC/Xeve(2), PC/Xem(3)
Enable/Disable alternate pin arrangement,
Number of ports on this card,
I/O Port where card is configured (in HEX if using string identifiers),
Base of memory window (in HEX if using string identifiers),
Samples:
append="digi=E,PC/Xi,D,16,200,D0000"
append="digi=1,0,0,16,512,(whatever D0000 is in base 10 :)
Driver's minor device numbers are conserved. This means that instead of
each board getting a block of 16 minors pre-assigned, it gets however
many it should, with the next card following directly behind it. A
system with 4 2-port PC/Xi boards will use minor numbers 0-7.
This conserves some memory, and removes a few hard coded constants.
NOTE!! NOTE!! NOTE!!
The definition of PC/Xem as a valid board type is the BEGINNING of support
for this device. The driver does not currently recognise the board, nor
does it want to initialize it. At least not the EISA version.
Mike McLagan <mike.mclagan@linux.org> 5, April 1996.
Mandatory File Locking For The Linux Operating System
Andy Walker <andy@lysaker.kvaerner.no>
06 April 1996
What is mandatory locking?
---------------------------
Mandatory locking is kernel enforced file locking, as opposed to the more usual
cooperative file locking used to guarantee sequential access to files among
processes. File locks are applied using the flock() and fcntl() system calls
(and the lockf() library routine which is a wrapper around fcntl().) It is
normally a process' responsibility to check for locks on a file it wishes to
update, before applying its own lock, updating the file and unlocking it again.
The most commonly used example of this (and in the case of sendmail, the most
troublesome) is access to a user's mailbox. The mail user agent and the mail
transfer agent must guard against updating the mailbox at the same time, and
prevent reading the mailbox while it is being updated.
In a perfect world all process would use and honour a cooperative, or
"advisory" locking scheme. However, the world isn't perfect, and there's
a lot of poorly written code out there.
In trying to address this problem, the designers of System V UNIX came up
with a "mandatory" locking scheme, whereby the operating system kernel would
block attempts by a process to write to a file that another process holds a
"read" -or- "shared" lock on, and block attempts to both read and write to a
file that a process holds a "write " -or- "exclusive" lock on.
The System V mandatory locking scheme was intended to have as little impact as
possible on existing user code. The scheme is based on marking individual files
as candidates for mandatory locking, and using the existing fcntl()/lockf()
interface for applying locks just as if they were normal, advisory locks.
Note 1: In saying "file" in the paragraphs above I am actually not telling
the whole truth. System V locking is based on fcntl(). The granularity of
fcntl() is such that it allows the locking of byte ranges in files, in addition
to entire files, so the mandatory locking rules also have byte level
granularity.
Note 2: POSIX.1 does not specify any scheme for mandatory locking, despite
borrowing the fcntl() locking scheme from System V.
Marking a file for mandatory locking
------------------------------------
A file is marked as a candidate for mandatory by setting the group-id bit in
its file mode but removing the group-execute bit. This is an otherwise
meaningless combination, and was chosen by the System V implementors so as not
to break existing user programs.
Note that the group-id bit is usually automatically cleared by the kernel when
a setgid file is written to. This is a security measure. The kernel has been
modified to recognize the special case of a mandatory lock candidate and to
refrain from clearing this bit. Similarly the kernel has been modified not
to run mandatory lock candidates with setgid privileges.
Available implementations
-------------------------
I originally intended to base my implementation on SunOS, only to find out that
the implementation in SunOS 4.1.1 (the latest version that will work on my Sun
3/80 at home) is completely hopeless.
For one thing, calls to open() for a file fail with EAGAIN if another process
holds a mandatory lock on the file. However, processes already holding open
file descriptors can carry on using them. Wierd!
In addition, SunOS doesn't seem to honour the O_NONBLOCK (O_NDELAY) flag for
mandatory locks, so reads and writes to locked files always block when they
should probably return EAGAIN.
I found some test code online, which I think comes from one of Stevens' UNIX
programming books, that confirmed what I considered to be be the "obvious"
semantics, described below. I shall attempt to run my test programs on other
platforms to verify my implementation.
Personally I feel that this is such an esoteric area that these semantics are
just as valid as any others, so long as the main points seem to agree.
Semantics
---------
1. Mandatory locks can only be applied via the fcntl()/lockf() locking
interface - in other words the System V/POSIX interface. BSD style
locks using flock() never result in a mandatory lock.
2. If a process has locked a region of a file with a mandatory read lock, then
other processes are permitted to read from that region. If any of these
processes attempts to write to the region it will block until the lock is
released, unless the process has opened the file opened with the O_NONBLOCK
flag in which case the system call will return immediately with the error
status EAGAIN.
3. If a process has locked a region of a file with a mandatory write lock, all
attempts to read or write to that region block until the lock is released,
unless a process has opened the file with the O_NONBLOCK flag in which case
the system call will return immediately with the error status EAGAIN.
Which system calls are affected?
--------------------------------
Those which modify a file's contents, not just the inode. That gives read(),
write(), readv(), writev(), truncate() and ftruncate(). truncate() and
ftruncate() are considered to be "write" actions for the purposes of mandatory
locking.
The affected region is usually defined as stretching from the current position
for the total number of bytes read or written. For the truncate calls it is
defined as the bytes of a file removed or added (we must also consider bytes
added, as a lock can specify just "the whole file", rather than a specific
range of bytes.)
Note 3: I may have overlooked some system calls that need mandatory lock
checking in my eagerness to get this code out the door. Please let me know, or
better still fix the system calls yourself and submit a patch to me or Linus.
Warning!
--------
Not even root can override a mandatory lock, so runaway process can wreak
havoc if they lock crucial files. The way around it is to change the file
permissions (remove the setgid bit) before trying to read or wite to it.
Of course, that might be a bit tricky if the system is hung :-(
......@@ -179,7 +179,7 @@ eepro.c:
eexpress.c:
io = 0x300
irq = 0
irq = 0 (IRQ value read from EEPROM)
(Probes ports: 0x300, 0x270, 0x320, 0x340)
eql.c:
......@@ -241,7 +241,10 @@ pi2.c: *Not modularized* (well, NON-STANDARD modularization!)
(Probes ports: 0x380, 0x300, 0x320, 0x340, 0x360, 0x3A0)
plip.c:
No options; goes to IO=0x278, IRQ=2
io = 0
irq = 0 (by default, uses IRQ 5 for port at 0x3bc, IRQ 7
for port at 0x378, and IRQ 2 for port at 0x278)
(Probes ports: 0x278, 0x378, 0x3bc)
ppp.c:
No options (ppp-2.2+ has some, this is based on non-dynamic
......
......@@ -66,9 +66,15 @@ M: net-patches@lxorguk.ukuu.org.uk
L: linux-net@vger.rutgers.edu
S: Maintained
ETHEREXPRESS NETWORK DRIVER
P: Philip Blundell
M: pjb27@cam.ac.uk
L: linux-net@vger.rutgers.edu
S: Maintained
APM DRIVER
P: Rik Faith
M: faith@cs.unc.edu
P: Rik Faith & Stephen Rothwell
M: faith@cs.unc.edu, Stephen.Rothwell@canb.auug.org.au
L: linux-laptop@vger.rutgers.edu
S: Maintained
......@@ -193,6 +199,12 @@ M: mj@k332.feld.cvut.cz
L: linux-kernel@vger.rutgers.edu
S: Maintained
DIGIBOARD DRIVER:
P: Christoph Lameter
M: clameter@fuller.edu
L: digiboard@list.fuller.edu
S: Maintained
REST:
P: Linus Torvalds
S: Buried alive in email
VERSION = 1
PATCHLEVEL = 3
SUBLEVEL = 84
SUBLEVEL = 85
ARCH = i386
......
......@@ -146,6 +146,7 @@ CONFIG_DUMMY=m
CONFIG_NET_EISA=y
# CONFIG_APRICOT is not set
CONFIG_DE4X5=y
# CONFIG_DEC_ELCP is not set
# CONFIG_ZNET is not set
# CONFIG_NET_POCKET is not set
# CONFIG_TR is not set
......
......@@ -153,7 +153,7 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
pg_dir = swapper_pg_dir;
while (address < end_mem) {
#ifdef USE_PENTIUM_MM
if (address <= end_mem + 4*1024*1024 &&
if (address + 4*1024*1024 <= end_mem &&
(x86_capability & 8)) {
#ifdef GAS_KNOWS_CR4
__asm__("movl %%cr4,%%eax\n\t"
......
......@@ -166,8 +166,17 @@ struct old_floppy_raw_cmd {
#define MAJOR_NR FLOPPY_MAJOR
#include <linux/blk.h>
#include <linux/cdrom.h> /* for the compatibility eject ioctl */
#ifndef FLOPPY_MOTOR_MASK
#define FLOPPY_MOTOR_MASK 0xf0
#endif
#ifndef fd_eject
#define fd_eject(x) -EINVAL
#endif
/* Dma Memory related stuff */
/* Pure 2^n version of get_order */
......@@ -196,6 +205,13 @@ static unsigned long dma_mem_alloc(int size)
static unsigned int fake_change = 0;
static int initialising=1;
#ifdef __sparc__
/* We hold the FIFO configuration here. We want to have Polling and
* Implied Seek enabled on Sun controllers.
*/
unsigned char fdc_cfg = 0;
#endif
static inline int TYPE(kdev_t x) {
return (MINOR(x)>>2) & 0x1f;
}
......@@ -722,9 +738,9 @@ static int set_dor(int fdc, char mask, char data)
UDRS->select_date = jiffies;
}
}
if (newdor & 0xf0)
if (newdor & FLOPPY_MOTOR_MASK)
floppy_grab_irq_and_dma();
if (olddor & 0xf0)
if (olddor & FLOPPY_MOTOR_MASK)
floppy_release_irq_and_dma();
return olddor;
}
......@@ -766,7 +782,9 @@ static void set_fdc(int drive)
return;
}
set_dor(fdc,~0,8);
#if N_FDC > 1
set_dor(1-fdc, ~8, 0);
#endif
if (FDCS->rawcmd == 2)
reset_fdc_info(1);
if (fd_inb(FD_STATUS) != STATUS_READY)
......@@ -1105,7 +1123,7 @@ static inline void perpendicular_mode(void)
if (FDCS->perp_mode == perp_mode)
return;
if (FDCS->version >= FDC_82077_ORIG && FDCS->has_fifo) {
if (FDCS->version >= FDC_82072A && FDCS->has_fifo) {
output_byte(FD_PERPENDICULAR);
output_byte(perp_mode);
FDCS->perp_mode = perp_mode;
......@@ -1147,6 +1165,12 @@ static void fdc_specify(void)
if (FDCS->need_configure && FDCS->has_fifo) {
if (FDCS->reset)
return;
#ifdef __sparc__
output_byte(FD_CONFIGURE);
output_byte(0x64); /* Motor off timeout */
output_byte(fdc_cfg | 0x0A);
output_byte(0);
#else
/* Turn on FIFO for 82077-class FDC (improves performance) */
/* TODO: lock this in via LOCK during initialization */
output_byte(FD_CONFIGURE);
......@@ -1157,10 +1181,17 @@ static void fdc_specify(void)
FDCS->has_fifo=0;
return;
}
#endif
FDCS->need_configure = 0;
/*DPRINT("FIFO enabled\n");*/
}
#ifdef __sparc__
/* If doing implied seeks, no specify necessary */
if(fdc_cfg&0x40)
return;
#endif
switch (raw_cmd->rate & 0x03) {
case 3:
dtr = 1000;
......@@ -1481,6 +1512,15 @@ static void seek_floppy(void)
}
}
#ifdef __sparc__
if (fdc_cfg&0x40) {
/* Implied seeks being done... */
DRS->track = raw_cmd->track;
setup_rw_floppy();
return;
}
#endif
SET_INTR(seek_interrupt);
output_byte(FD_SEEK);
output_byte(UNIT(current_drive));
......@@ -1587,6 +1627,7 @@ static void floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs)
lasthandler = handler;
interruptjiffies = jiffies;
fd_disable_dma();
floppy_enable_hlt();
CLEAR_INTR;
if (fdc >= N_FDC || FDCS->address == -1){
......@@ -1632,7 +1673,6 @@ static void reset_interrupt(void)
#ifdef DEBUGT
debugt("reset interrupt:");
#endif
/* fdc_specify(); reprogram fdc */
result(); /* get the status ready for set_fdc */
if (FDCS->reset) {
printk("reset set in interrupt, calling %p\n", cont->error);
......@@ -1650,12 +1690,17 @@ static void reset_fdc(void)
SET_INTR(reset_interrupt);
FDCS->reset = 0;
reset_fdc_info(0);
if (FDCS->version >= FDC_82077)
/* Pseudo-DMA may intercept 'reset finished' interrupt. */
/* Irrelevant for systems with true DMA (i386). */
fd_disable_dma();
if (FDCS->version >= FDC_82072A)
fd_outb(0x80 | (FDCS->dtr &3), FD_STATUS);
else {
fd_outb(FDCS->dor & ~0x04, FD_DOR);
udelay(FD_RESET_DELAY);
outb(FDCS->dor, FD_DOR);
fd_outb(FDCS->dor, FD_DOR);
}
}
......@@ -3111,6 +3156,7 @@ static struct translation_entry {
{FDWERRORCLR, 27, 0},
{FDWERRORGET, 28, 24},
{FDRAWCMD, 0, 0},
{FDEJECT, 0, 0},
{FDTWADDLE, 40, 0} };
static inline int normalize_0x02xx_ioctl(int *cmd, int *size)
......@@ -3184,6 +3230,16 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
type = TYPE(device);
drive = DRIVE(device);
/* convert compatibility eject ioctls into floppy eject ioctl.
* We do this in order to provide a means to eject floppy disks before
* installing the new fdutils package */
if(cmd == CDROMEJECT || /* CD-Rom eject */
cmd == 0x6470 /* SunOS floppy eject */) {
DPRINT("obsolete eject ioctl\n");
DPRINT("please use floppycontrol --eject\n");
cmd = FDEJECT;
}
/* convert the old style command into a new style command */
if ((cmd & 0xff00) == 0x0200) {
ECALL(normalize_0x02xx_ioctl(&cmd, &size));
......@@ -3207,6 +3263,25 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
ECALL(fd_copyin((void *)param, &inparam, size))
switch (cmd) {
case FDEJECT:
if(UDRS->fd_ref != 1)
/* somebody else has this drive open */
return -EBUSY;
LOCK_FDC(drive,1);
/* do the actual eject. Fails on
* non-Sparc archtitectures */
ret=fd_eject(UNIT(drive));
/* switch the motor off, in order to make the
* cached DOR status match the hard DOS status
*/
motor_off_callback(drive);
USETF(FD_DISK_CHANGED);
USETF(FD_VERIFY);
process_fd_request();
return ret;
case FDCLRPRM:
LOCK_FDC(drive,1);
current_type[drive] = NULL;
......@@ -3645,8 +3720,10 @@ static char get_fdc_version(void)
output_byte(FD_UNLOCK);
r = result();
if ((r == 1) && (reply_buffer[0] == 0x80)){
printk(KERN_INFO "FDC %d is a pre-1991 82077\n", fdc);
return FDC_82077_ORIG; /* Pre-1991 82077 doesn't know LOCK/UNLOCK */
printk(KERN_INFO "FDC %d is a 82072A\n", fdc);
return FDC_82072A; /* Pre-1991 82077 or 82072A as found
* on Sparcs. These doesn't know
* LOCK/UNLOCK */
}
if ((r != 1) || (reply_buffer[0] != 0x00)) {
printk("FDC %d init: UNLOCK: unexpected return of %d bytes.\n",
......@@ -3848,6 +3925,9 @@ int floppy_init(void)
blksize_size[MAJOR_NR] = floppy_blocksizes;
blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
reschedule_timeout(MAXTIMEOUT, "floppy init", MAXTIMEOUT);
#ifdef __sparc__
fdc_cfg = (0x40 | 0x10); /* ImplSeek+Polling+FIFO */
#endif
config_types();
for (i = 0; i < N_FDC; i++) {
......@@ -3906,7 +3986,7 @@ int floppy_init(void)
* properly, so force a reset for the standard FDC clones,
* to avoid interrupt garbage.
*/
FDCS->has_fifo = FDCS->version >= FDC_82077_ORIG;
FDCS->has_fifo = FDCS->version >= FDC_82072A;
user_reset_fdc(-1,FD_RESET_ALWAYS,0);
}
fdc=0;
......@@ -4082,6 +4162,8 @@ void cleanup_module(void)
unregister_blkdev(MAJOR_NR, "fd");
blk_dev[MAJOR_NR].request_fn = 0;
/* eject disk, if any */
fd_eject(0);
}
#ifdef __cplusplus
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -3154,6 +3154,7 @@ void idetape_wait_for_request (struct request *rq)
}
#endif /* IDETAPE_DEBUG_BUGS */
run_task_queue(&tq_disk);
rq->sem=&sem;
down (&sem);
}
......
......@@ -1753,8 +1753,10 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio
rq->next = cur_rq->next;
cur_rq->next = rq;
}
if (action == ide_wait && rq->rq_status != RQ_INACTIVE)
if (action == ide_wait && rq->rq_status != RQ_INACTIVE) {
run_task_queue(&tq_disk);
down(&sem); /* wait for it to be serviced */
}
restore_flags(flags);
return rq->errors ? -EIO : 0; /* return -EIO if errors */
}
......
......@@ -159,62 +159,68 @@ typedef unsigned char byte; /* used everywhere */
#ifdef CONFIG_BLK_DEV_IDECD
struct atapi_request_sense {
unsigned char error_code : 7;
unsigned char valid : 1;
byte reserved1;
unsigned char sense_key : 4;
unsigned char reserved2 : 1;
unsigned char ili : 1;
unsigned char reserved3 : 2;
byte info[4];
byte sense_len;
byte command_info[4];
byte asc;
byte ascq;
byte fru;
byte sense_key_specific[3];
unsigned char error_code : 7;
unsigned char valid : 1;
byte reserved1;
unsigned char sense_key : 4;
unsigned char reserved2 : 1;
unsigned char ili : 1;
unsigned char reserved3 : 2;
byte info[4];
byte sense_len;
byte command_info[4];
byte asc;
byte ascq;
byte fru;
byte sense_key_specific[3];
};
struct packet_command {
char *buffer;
int buflen;
int stat;
struct atapi_request_sense *sense_data;
unsigned char c[12];
char *buffer;
int buflen;
int stat;
struct atapi_request_sense *sense_data;
unsigned char c[12];
};
/* Structure of a MSF cdrom address. */
struct atapi_msf {
byte reserved;
byte minute;
byte second;
byte frame;
};
/* Space to hold the disk TOC. */
#define MAX_TRACKS 99
struct atapi_toc_header {
unsigned short toc_length;
byte first_track;
byte last_track;
unsigned short toc_length;
byte first_track;
byte last_track;
};
struct atapi_toc_entry {
byte reserved1;
unsigned control : 4;
unsigned adr : 4;
byte track;
byte reserved2;
union {
unsigned lba;
struct {
byte reserved3;
byte m;
byte s;
byte f;
} msf;
} addr;
byte reserved1;
unsigned control : 4;
unsigned adr : 4;
byte track;
byte reserved2;
union {
unsigned lba;
struct atapi_msf msf;
} addr;
};
struct atapi_toc {
int last_session_lba;
int xa_flag;
unsigned capacity;
struct atapi_toc_header hdr;
struct atapi_toc_entry ent[MAX_TRACKS+1]; /* One extra for the leadout. */
int last_session_lba;
int xa_flag;
unsigned capacity;
struct atapi_toc_header hdr;
struct atapi_toc_entry ent[MAX_TRACKS+1];
/* One extra for the leadout. */
};
......@@ -222,62 +228,49 @@ struct atapi_toc {
the cdrom_subchnl structure from cdrom.h. */
struct atapi_cdrom_subchnl
{
u_char acdsc_reserved;
u_char acdsc_audiostatus;
u_short acdsc_length;
u_char acdsc_format;
u_char acdsc_adr: 4;
u_char acdsc_ctrl: 4;
u_char acdsc_trk;
u_char acdsc_ind;
union
{
struct
{
u_char reserved;
u_char minute;
u_char second;
u_char frame;
} msf;
int lba;
} acdsc_absaddr;
union
{
struct
{
u_char reserved;
u_char minute;
u_char second;
u_char frame;
} msf;
int lba;
} acdsc_reladdr;
u_char acdsc_reserved;
u_char acdsc_audiostatus;
u_short acdsc_length;
u_char acdsc_format;
u_char acdsc_adr: 4;
u_char acdsc_ctrl: 4;
u_char acdsc_trk;
u_char acdsc_ind;
union {
struct atapi_msf msf;
int lba;
} acdsc_absaddr;
union {
struct atapi_msf msf;
int lba;
} acdsc_reladdr;
};
/* Extra per-device info for cdrom drives. */
struct cdrom_info {
/* Buffer for table of contents. NULL if we haven't allocated
a TOC buffer for this device yet. */
/* Buffer for table of contents. NULL if we haven't allocated
a TOC buffer for this device yet. */
struct atapi_toc *toc;
struct atapi_toc *toc;
/* Sector buffer. If a read request wants only the first part of a cdrom
block, we cache the rest of the block here, in the expectation that that
data is going to be wanted soon. SECTOR_BUFFERED is the number of the
first buffered sector, and NSECTORS_BUFFERED is the number of sectors
in the buffer. Before the buffer is allocated, we should have
SECTOR_BUFFER == NULL and NSECTORS_BUFFERED == 0. */
/* Sector buffer. If a read request wants only the first part
of a cdrom block, we cache the rest of the block here,
in the expectation that that data is going to be wanted soon.
SECTOR_BUFFERED is the number of the first buffered sector,
and NSECTORS_BUFFERED is the number of sectors in the buffer.
Before the buffer is allocated, we should have
SECTOR_BUFFER == NULL and NSECTORS_BUFFERED == 0. */
unsigned long sector_buffered;
unsigned long nsectors_buffered;
char *sector_buffer;
unsigned long sector_buffered;
unsigned long nsectors_buffered;
char *sector_buffer;
/* The result of the last successful request sense command
on this device. */
struct atapi_request_sense sense_data;
/* The result of the last successful request sense command
on this device. */
struct atapi_request_sense sense_data;
};
#endif /* CONFIG_BLK_DEV_IDECD */
......
......@@ -27,6 +27,12 @@
*/
static struct request all_requests[NR_REQUEST];
/*
* The "disk" task queue is used to start the actual requests
* after a plug
*/
DECLARE_TASK_QUEUE(tq_disk);
/*
* used to wait on when there are no free requests
*/
......@@ -101,7 +107,7 @@ static void unplug_device(void * data)
static inline void plug_device(struct blk_dev_struct * dev)
{
dev->current_request = &dev->plug;
queue_task_irq_off(&dev->plug_tq, &tq_scheduler);
queue_task_irq_off(&dev->plug_tq, &tq_disk);
}
/*
......@@ -152,6 +158,7 @@ static struct request * __get_request_wait(int n, kdev_t dev)
sti();
if (req)
break;
run_task_queue(&tq_disk);
schedule();
}
remove_wait_queue(&wait_for_request, &wait);
......@@ -593,6 +600,7 @@ void ll_rw_swap_file(int rw, kdev_t dev, unsigned int *b, int nb, char *buf)
req[j]->next = NULL;
add_request(major+blk_dev,req[j]);
}
run_task_queue(&tq_disk);
while (j > 0) {
j--;
down(&sem);
......
......@@ -140,6 +140,7 @@ endif
ifdef CONFIG_APM
LX_OBJS += apm_bios.o
M = y
endif
ifdef M
......
/* -*- linux-c -*-
* APM BIOS driver for Linux
* Copyright 1994, 1995 Stephen Rothwell (Stephen.Rothwell@pd.necisa.oz.au)
* Copyright 1994, 1995, 1996 Stephen Rothwell
* (Stephen.Rothwell@canb.auug.org.au)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
......@@ -22,12 +23,16 @@
* March 1996, Rik Faith (faith@cs.unc.edu):
* 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
*
* 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
*
* Reference:
*
......@@ -54,6 +59,11 @@
#include <linux/fcntl.h>
#include <linux/malloc.h>
#include <linux/linkage.h>
#ifdef CONFIG_PROC_FS
#include <linux/stat.h>
#include <linux/proc_fs.h>
#endif
#include <linux/miscdevice.h>
#include <linux/apm_bios.h>
static struct symbol_table apm_syms = {
......@@ -65,6 +75,12 @@ static struct symbol_table apm_syms = {
extern unsigned long get_cmos_time(void);
/*
* The apm_bios device is one of the misc char devices.
* This is its minor number.
*/
#define APM_MINOR_DEV 134
/* Configurable options:
*
* CONFIG_APM_IGNORE_USER_SUSPEND: define to ignore USER SUSPEND requests.
......@@ -285,6 +301,10 @@ static int do_select(struct inode *, struct file *, int,
select_table *);
static int do_ioctl(struct inode *, struct file *, u_int, u_long);
#ifdef CONFIG_PROC_FS
static int apm_get_info(char *, char **, off_t, int, int);
#endif
extern int apm_register_callback(int (*)(apm_event_t));
extern void apm_unregister_callback(int (*)(apm_event_t));
......@@ -311,7 +331,7 @@ static struct apm_bios_struct * user_list = NULL;
static struct timer_list apm_timer;
static char driver_version[] = "0.9";/* no spaces */
static char driver_version[] = "1.0";/* no spaces */
#ifdef APM_DEBUG
static char * apm_event_name[] = {
......@@ -345,6 +365,18 @@ static struct file_operations apm_bios_fops = {
NULL /* fasync */
};
static struct miscdevice apm_device = {
APM_MINOR_DEV,
"apm",
&apm_bios_fops
};
#ifdef CONFIG_PROC_FS
static struct proc_dir_entry apm_proc_entry = {
0, 3, "apm", S_IFREG | S_IRUGO, 1, 0, 0, 0, 0, apm_get_info
};
#endif
typedef struct callback_list_t {
int (* callback)(apm_event_t);
struct callback_list_t * next;
......@@ -472,7 +504,7 @@ int apm_display_blank(void)
#ifdef CONFIG_APM_DISPLAY_BLANK
int error;
if (!apm_enabled || apm_bios_info.version == 0)
if (!apm_enabled)
return 0;
error = apm_set_display_power_state(APM_STATE_STANDBY);
if (error == APM_SUCCESS)
......@@ -488,7 +520,7 @@ int apm_display_unblank(void)
#ifdef CONFIG_APM_DISPLAY_BLANK
int error;
if (!apm_enabled || apm_bios_info.version == 0)
if (!apm_enabled)
return 0;
error = apm_set_display_power_state(APM_STATE_READY);
if (error == APM_SUCCESS)
......@@ -914,7 +946,8 @@ static int do_open(struct inode * inode, struct file * filp)
return 0;
}
int apm_proc(char *buf)
#ifdef CONFIG_PROC_FS
int apm_get_info(char *buf, char **start, off_t fpos, int length, int dummy)
{
char * p;
unsigned short bx;
......@@ -924,31 +957,29 @@ int apm_proc(char *buf)
unsigned short ac_line_status = 0xff;
unsigned short battery_status = 0xff;
unsigned short battery_flag = 0xff;
unsigned short percentage = -1;
int percentage = -1;
int time_units = -1;
char *units = "?";
if (apm_bios_info.version == 0)
if (!apm_enabled)
return 0;
p = buf;
if ((apm_bios_info.flags & APM_32_BIT_SUPPORT) != 0) {
if (!(error = apm_get_power_status(&bx, &cx, &dx))) {
ac_line_status = (bx >> 8) & 0xff;
battery_status = bx & 0xff;
if ((cx & 0xff) != 0xff)
percentage = cx & 0xff;
if (apm_bios_info.version > 0x100) {
battery_flag = (cx >> 8) & 0xff;
if (dx != 0xffff) {
if ((dx & 0x8000) == 0x8000) {
units = "min";
time_units = dx & 0x7ffe;
} else {
units = "sec";
time_units = dx & 0x7fff;
}
if (!(error = apm_get_power_status(&bx, &cx, &dx))) {
ac_line_status = (bx >> 8) & 0xff;
battery_status = bx & 0xff;
if ((cx & 0xff) != 0xff)
percentage = cx & 0xff;
if (apm_bios_info.version > 0x100) {
battery_flag = (cx >> 8) & 0xff;
if (dx != 0xffff) {
if ((dx & 0x8000) == 0x8000) {
units = "min";
time_units = dx & 0x7ffe;
} else {
units = "sec";
time_units = dx & 0x7fff;
}
}
}
......@@ -1000,12 +1031,13 @@ int apm_proc(char *buf)
battery_flag,
percentage,
time_units,
units );
units);
return p - buf;
}
#endif
static int apm_setup(void)
void apm_bios_init(void)
{
unsigned short bx;
unsigned short cx;
......@@ -1016,7 +1048,7 @@ static int apm_setup(void)
if (apm_bios_info.version == 0) {
printk("APM BIOS not found.\n");
return -1;
return;
}
printk("APM BIOS version %c.%c Flags 0x%02x (Driver version %s)\n",
((apm_bios_info.version >> 8) & 0xff) + '0',
......@@ -1025,7 +1057,7 @@ static int apm_setup(void)
driver_version);
if ((apm_bios_info.flags & APM_32_BIT_SUPPORT) == 0) {
printk(" No 32 bit BIOS support\n");
return -1;
return;
}
/*
......@@ -1128,7 +1160,7 @@ static int apm_setup(void)
if (error)
apm_error("enable power management", error);
if (error == APM_DISABLED)
return -1;
return;
#endif
init_timer(&apm_timer);
......@@ -1138,15 +1170,11 @@ static int apm_setup(void)
register_symtab(&apm_syms);
apm_enabled = 1;
if ((apm_major = register_chrdev(0, "apm_bios", &apm_bios_fops)) < 0)
printk("APM BIOS: Cannot allocate major device number\n");
#ifdef CONFIG_PROC_FS
proc_register_dynamic(&proc_root, &apm_proc_entry);
#endif
return 0;
}
misc_register(&apm_device);
void apm_bios_init(void)
{
apm_setup();
apm_enabled = 1;
}
......@@ -389,7 +389,8 @@ int chr_dev_init(void)
#endif
#if defined (CONFIG_BUSMOUSE) || defined(CONFIG_UMISC) || \
defined (CONFIG_PSMOUSE) || defined (CONFIG_MS_BUSMOUSE) || \
defined (CONFIG_ATIXL_BUSMOUSE) || defined(CONFIG_SOFT_WATCHDOG)
defined (CONFIG_ATIXL_BUSMOUSE) || defined(CONFIG_SOFT_WATCHDOG) || \
defined (CONFIG_APM)
misc_init();
#endif
#ifdef CONFIG_SOUND
......
......@@ -39,6 +39,9 @@
#include <linux/malloc.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
#ifdef CONFIG_APM
#include <linux/apm_bios.h>
#endif
#include <linux/tty.h> /* needed by selection.h */
#include "selection.h" /* export its symbols */
......@@ -204,6 +207,9 @@ int misc_init(void)
#ifdef CONFIG_SOFT_WATCHDOG
watchdog_init();
#endif
#ifdef CONFIG_APM
apm_bios_init();
#endif
#endif /* !MODULE */
if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) {
printk("unable to get major %d for misc devices\n",
......
This diff is collapsed.
......@@ -14,16 +14,29 @@
#define FEPMASK 0x0e
#define FEPWIN 0x80
#define PCXI 0
#define PCXE 1
#define PCXEVE 2
/* Maximum Number of Boards supported */
#define MAX_DIGI_BOARDS 4
#define PCXX_NUM_TYPES 4
#define PCXI 0
#define PCXE 1
#define PCXEVE 2
#define PCXEM 3
static char *board_desc[] = {
"PC/Xi (64K)",
"PC/Xe (64K)",
"PC/Xe (8K) ",
"PC/Xi",
"PC/Xe",
"PC/Xeve",
"PC/Xem",
};
static char *board_mem[] = {
"64k",
"64k",
"8k",
"32k",
};
#define STARTC 021
#define STOPC 023
#define IAIXON 0x2000
......@@ -36,6 +49,7 @@ struct board_info {
ushort numports;
ushort port;
ulong membase;
ushort first_minor;
};
......
#define NUMCARDS 1
struct board_info boards[NUMCARDS]={
{ ENABLED, 0, ON, 16, 0x200, 0xd0000 }
};
......@@ -171,18 +171,20 @@ struct async_struct rs_table[] = {
/* You can have up to four HUB6's in the system, but I've only
* included two cards here for a total of twelve ports.
*/
#ifdef CONFIG_HUB6
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) }, /* ttyS32 */
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) }, /* ttyS33 */
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) }, /* ttyS34 */
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) }, /* ttyS35 */
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) }, /* ttyS36 */
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) }, /* ttyS37 */
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) }, /* ttyS32 */
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) }, /* ttyS33 */
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) }, /* ttyS34 */
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) }, /* ttyS35 */
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) }, /* ttyS36 */
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) }, /* ttyS37 */
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) }, /* ttyS38 */
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) }, /* ttyS39 */
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) }, /* ttyS40 */
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) }, /* ttyS41 */
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) }, /* ttyS42 */
{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) }, /* ttyS43 */
#endif
};
#define NR_PORTS (sizeof(rs_table)/sizeof(struct async_struct))
......@@ -2426,7 +2428,7 @@ int rs_open(struct tty_struct *tty, struct file * filp)
*/
static void show_serial_version(void)
{
printk("Serial driver version 4.11 with");
printk("Serial driver version 4.11a with");
#ifdef CONFIG_HUB6
printk(" HUB-6");
#define SERIAL_OPT
......
......@@ -78,7 +78,7 @@ if [ "$CONFIG_NET_EISA" = "y" ]; then
fi
tristate 'Apricot Xen-II on board ethernet' CONFIG_APRICOT
tristate 'DE425, DE434, DE435, DE500 support' CONFIG_DE4X5
# tristate 'DEC 21040 PCI support' CONFIG_DEC_ELCP
tristate 'DEC 21040 PCI support' CONFIG_DEC_ELCP
# bool 'LPL T100V 100Mbs support' CONFIG_LPL_T100
# bool 'PCnet32 (32 bit VLB and PCI LANCE) support' CONFIG_PCNET32
bool 'Zenith Z-Note support' CONFIG_ZNET
......
......@@ -38,6 +38,7 @@
ethernet adaptor have the name "eth[0123...]".
*/
extern int tulip_probe(struct device *dev);
extern int hp100_probe(struct device *dev);
extern int ultra_probe(struct device *dev);
extern int wd_probe(struct device *dev);
......@@ -92,6 +93,9 @@ ethif_probe(struct device *dev)
#if defined(CONFIG_SEEQ8005)
&& seeq8005_probe(dev)
#endif
#if defined(CONFIG_DEC_ELCP)
&& tulip_probe(dev)
#endif
#if defined(CONFIG_HP100)
&& hp100_probe(dev)
#endif
......
......@@ -153,7 +153,7 @@ static short TokBaseAddrs[] = { MMIOStartLocP, MMIOStartLocA };
int tok_probe(struct device *dev);
unsigned char get_sram_size(struct tok_info *adapt_info);
static void tok_init_card(unsigned long dev_addr);
static int tok_init_card(struct device *dev);
int trdev_init(struct device *dev);
void tok_interrupt(int irq, void *dev_id, struct pt_regs *regs);
......@@ -543,14 +543,8 @@ int tok_probe(struct device *dev)
dev->base_addr=PIOaddr; /* set the value for device */
dev->open=tok_open;
dev->stop=tok_close;
dev->hard_start_xmit=tok_send_packet;
dev->get_stats = NULL;
dev->get_stats = tok_get_stats;
dev->set_multicast_list = NULL;
tr_setup(dev);
tok_init_card((unsigned long)dev);
trdev_init(dev);
tok_init_card(dev);
return 0; /* Return 0 to indicate we have found a Token Ring card. */
}
......@@ -577,11 +571,31 @@ unsigned char get_sram_size(struct tok_info *adapt_info)
return 1<<((readb(adapt_info->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD)>>2)+4);
}
int trdev_init(struct device *dev)
{
struct tok_info *ti=(struct tok_info *)dev->priv;
ti->open_status=CLOSED;
dev->init=tok_init_card;
dev->open=tok_open;
dev->stop=tok_close;
dev->hard_start_xmit=tok_send_packet;
dev->get_stats = NULL;
dev->get_stats = tok_get_stats;
dev->set_multicast_list = NULL;
tr_setup(dev);
return 0;
}
static int tok_open(struct device *dev)
{
struct tok_info *ti=(struct tok_info *)dev->priv;
if (ti->open_status==CLOSED) tok_init_card((unsigned long)dev);
if (ti->open_status==CLOSED) tok_init_card(dev);
if (ti->open_status==IN_PROGRESS) sleep_on(&ti->wait_for_reset);
......@@ -650,13 +664,31 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
outb(0, ti->global_int_enable);
status=readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_ODD);
#ifdef PCMCIA
/* Check if the PCMCIA card was pulled. */
if (status == 0xFF)
{
DPRINTK("PCMCIA card removed.\n");
dev->interrupt = 0;
return;
}
/* Check ISRP EVEN too. */
if ( *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN) == 0xFF)
{
DPRINTK("PCMCIA card removed.\n");
dev->interrupt = 0;
return;
}
#endif
if (status & ADAP_CHK_INT) {
int i;
__u32 check_reason;
check_reason=ti->mmio + ntohs(readw(ti->mmio + ACA_OFFSET + ACA_RW +WWCR_EVEN));
check_reason=ti->mmio + ntohs(readw(ti->sram + ACA_OFFSET + ACA_RW +WWCR_EVEN));
DPRINTK("Adapter check interrupt\n");
DPRINTK("8 reason bytes follow: ");
......@@ -1046,12 +1078,11 @@ static void initial_tok_int(struct device *dev)
tok_open_adapter((unsigned long)dev);
}
static void tok_init_card(unsigned long dev_addr)
static int tok_init_card(struct device *dev)
{
struct tok_info *ti;
short PIOaddr;
int i;
struct device *dev=(struct device *)dev_addr;
PIOaddr = dev->base_addr;
ti=(struct tok_info *) dev->priv;
......@@ -1082,7 +1113,7 @@ static void tok_init_card(unsigned long dev_addr)
ti->open_status=IN_PROGRESS;
writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
return 0;
}
static void open_sap(unsigned char type,struct device *dev)
......
/* $Id: plip.c,v 1.15 1995/10/03 01:47:09 gniibe Exp $ */
/* $Id: plip.c,v 1.16 1996-04-06 15:36:57+09 gniibe Exp $ */
/* PLIP: A parallel port "network" driver for Linux. */
/* This driver is for parallel port with 5-bit cable (LapLink (R) cable). */
/*
......@@ -26,6 +26,7 @@
* # insmod plip.o io=0x3bc irq=7
* - MTU fix.
* - Make sure other end is OK, before sending a packet.
* - Fix immediate timer problem.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -51,7 +52,7 @@
* To use with DOS box, please do (Turn on ARP switch):
* # ifconfig plip[0-2] arp
*/
static const char *version = "NET3 PLIP version 2.1 gniibe@mri.co.jp\n";
static const char *version = "NET3 PLIP version 2.2 gniibe@mri.co.jp\n";
/*
Sources:
......@@ -591,6 +592,7 @@ plip_receive_packet(struct device *dev, struct net_local *nl,
nl->connection = PLIP_CN_SEND;
sti();
queue_task(&nl->immediate, &tq_immediate);
mark_bh(IMMEDIATE_BH);
outb(PAR_INTR_ON, PAR_CONTROL(dev));
enable_irq(dev->irq);
return OK;
......
......@@ -256,8 +256,8 @@ static __u8 *StuffData(__u8 *src, __u32 length, __u8 *dst, __u8 **code_ptr_ptr)
/*
* Recover state from last call, if applicable
*/
code = *code_ptr & Stuff_CodeMask;
count = *code_ptr & Stuff_CountMask;
code = (*code_ptr ^ Stuff_Magic) & Stuff_CodeMask;
count = (*code_ptr ^ Stuff_Magic) & Stuff_CountMask;
}
while (src < end)
......
This diff is collapsed.
......@@ -35,10 +35,10 @@ if [ "$CONFIG_SCSI_GENERIC_NCR5380" != "n" ]; then
fi
if [ "$CONFIG_PCI" = "y" ]; then
dep_tristate 'NCR53c7,8xx SCSI support' CONFIG_SCSI_NCR53C7xx $CONFIG_SCSI
fi
if [ "$CONFIG_SCSI_NCR53C7xx" != "n" ]; then
bool ' always negotiate synchronous transfers' CONFIG_SCSI_NCR53C7xx_sync
bool ' allow FAST-SCSI [10MHz]' CONFIG_SCSI_NCR53C7xx_FAST
if [ "$CONFIG_SCSI_NCR53C7xx" != "n" ]; then
bool ' always negotiate synchronous transfers' CONFIG_SCSI_NCR53C7xx_sync
bool ' allow FAST-SCSI [10MHz]' CONFIG_SCSI_NCR53C7xx_FAST
fi
fi
dep_tristate 'Always IN2000 SCSI support (test release)' CONFIG_SCSI_IN2000 $CONFIG_SCSI
dep_tristate 'PAS16 SCSI support' CONFIG_SCSI_PAS16 $CONFIG_SCSI
......
......@@ -48,7 +48,7 @@ is different. It may also be configured by editing the source file.
Built-in drivers accept parameters using this LILO/LOADLIN command line
syntax (omitted parameters retain their default values):
ppa=base[,speed_high[,speed_low[,call_sched[,nybble]]]]
ppa=base[,speed_high[,speed_low[,nybble]]]
For example: ppa=0x378,0,3
......@@ -66,7 +66,6 @@ Variable Default Description
ppa_base 0x378 The base address of PPA's parallel port.
ppa_speed_high 1 Microsecond i/o delay used in data transfers
ppa_speed_low 6 Microsecond delay used in other operations
ppa_call_sched 1 1 to give up CPU during busy waits
ppa_nybble 0 1 to force the driver to use 4-bit mode.
A word about the timing parameters: the ppa_speed_low parameter controls
......@@ -84,15 +83,6 @@ SCSI timeout errors in your log files. If you are getting timeouts, you
have set these parameters too low. The default values appear to be
safe on most machines.
The ppa_call_sched parameter controls the 'friendliness' of this driver
to the rest of your system. When it is set to zero, the driver waits for
events on the drive by continuously reading a port until the 0x80 bit is
asserted. Since it is in a tight loop inside the kernel, the rest of the
system becomes very sluggish. If you set ppa_call_sched to one, then
ppa will call the scheduler in such circumstances, voluntarily giving up the
CPU to other processes. This appears to reduce the ZIP drive's
responsiveness, however.
If you have both the lp and ppa drivers in your kernel, you must ensure
that they access different parallel ports. By default, the lp driver is
initialised early in the booting process, and it claims all parallel
......@@ -114,6 +104,12 @@ give the following options on your boot command:
In this case lp would use the polling driver, since an interrupt was not
specified.
If you want to share the same parallel port between a ZIP drive and a
printer, you should build both the lp and ppa drivers as modules and
load and unload one or the other as required. This is clumsy but we
currently have no protocol for synchronising access to shared parallel
ports.
For information about using the ZIP drive, please read the generic
instructions in the SCSI-HOWTO and the man pages for the normal disk
management tools, fdisk, mkfs, mount, umount, etc. There is a mini-HOWTO
......
This file contains brief information about the SCSI tape driver.
Last modified: Sun Nov 26 12:54:21 1995 by root@kai.makisara.fi
Last modified: Mon Apr 8 09:34:33 1996 by makisara@kai.makisara.fi
BASICS
The driver is generic. The state of a drive is not modified when the
driver is initialized or a device is opened. The mode parameters of the
drive can be modified with ioctls. 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.
The driver is generic, i.e., it does not contain any code tailored
to any specific tape drive. The tape parameters can be specified with
one of the following three methods:
1. Each user can specify the tape parameters he/she wants to use
directly with ioctls. This is administratively a very simple and
flexible method and applicable to single-user workstations. However,
in a multiuser environment the next user finds the tape parameters in
state the previous user left them.
2. The system manager (root) can define default values for some tape
parameters, like block size and density using the MTSETDRVBUFFER ioctl.
These parameters can be programmed to come into effect either when a
new tape is loaded into the drive or if writing begins at the
beginning of the tape. The second method is applicable if the tape
drive performs auto-detection of the tape format well (like some
QIC-drives). The result is that any tape can be read, writing can be
continued using existing format, and the default format is used if
the tape is rewritten from the beginning (or a new tape is written
for the first time). The first method is applicable if the drive
does not perform auto-detection well enough and there is a single
"sensible" mode for the device. An example is a DAT drive that is
used only in variable block mode (I don't know if this is sensible
or not :-).
The user can override the parameters defined by the system
manager. The changes persist until the defaults again come into
effect.
3. Up to four modes can be defined and selected using the minor number
(bits 5 and 6). Mode 0 corresponds to the defaults discussed
above. Additional modes are dormant until they are defined by the
system manager (root). When specification of a new mode is started,
the configuration of mode 0 is used to provide a starting point for
definition of the new mode.
Using the modes allows the system manager to give the users choices
over some of the buffering parameters not directly accessible to the
users (buffered and asynchronous writes). The modes also allow choices
between formats in multi-tape operations (the explicitly overridden
parameters are reset when a new tape is loaded).
If more than one mode is used, all modes should contain definitions
for the same set of parameters.
Many Unices contain internal tables that associate different modes to
supported devices. The Linux SCSI tape driver does not contain such
tables (and will not do that in future). Instead of that, a utility
program can be made that fetches the inquiry data sent by the device,
scans its database, and sets up the modes using the ioctls. Another
alternative is to make a small script that uses mt to set the defaults
tailored to the system.
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.
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
......@@ -17,6 +69,7 @@ returning zero bytes for two consecutive reads.
The compile options are defined in the file linux/drivers/scsi/st_options.h.
BUFFERING
The driver uses tape buffers allocated either at system initialization
......@@ -112,7 +165,7 @@ MTWSM Write count setmarks.
MTREW Rewind tape.
MTOFFL Set device off line (often rewind plus eject).
MTNOP Do nothing except flush the buffers.
MTRETEN Retension tape.
MTRETEN Re-tension tape.
MTEOM Space to end of recorded data.
MTERASE Erase tape.
MTSEEK Seek to tape block count. Uses Tandberg-compatible seek (QFA)
......@@ -122,25 +175,54 @@ MTSETBLK Set the drive block size. Setting to zero sets the drive into
variable block mode (if applicable).
MTSETDENSITY Sets the drive density code to arg. See drive
documentation for available codes.
MTLOCK and MTUNLOCK Explicitly lock/unlock the tape drive door.
MTLOAD and MTUNLOAD Explicitly load and unload the tape.
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.
MTSETDRVBUFFER
Is used for several things. The command is obtained from count
Is used for several purposes. The command is obtained from count
with mask MT_SET_OPTIONS, the low order bits are used as argument.
The subcommands are:
This command is only allowed for the superuser (root). The
subcommands are:
0
The drive buffer option is set to the argument. Zero means
no buffering.
MT_ST_BOOLEANS
Sets the buffering options. The bits are the new states
(enabled/disabled) of the write buffering (MT_ST_BUFFER_WRITES),
asynchronous writes (MT_ST_ASYNC_WRITES), read ahead
(MT_ST_READ_AHEAD), writing of two filemark (ST_TWO_FM),
using the SCSI spacing to EOD (MT_ST_FAST_EOM), automatic
locking of the drive door (MT_ST_AUTO_LOCK) and debugging
(MT_ST_DEBUGGING ; debugging must be compiled into the
driver).
(enabled/disabled) the following options (in the
parenthesis is specified whether the option is global or
can be specified differently for each mode):
MT_ST_BUFFER_WRITES write buffering (mode)
MT_ST_ASYNC_WRITES asynchronous writes (mode)
MT_ST_READ_AHEAD read ahead (global)
MT_ST_TWO_FM writing of two filemarks (global)
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_DEBUGGING debugging (global; debugging must be
compiled into the driver)
MT_ST_SETBOOLEANS
MT_ST_CLEARBOOLEANS
Sets or clears the option bits.
MT_ST_WRITE_THRESHOLD
Sets the write threshold for this device to kilobytes
specified by the lowest bits.
MT_ST_DEF_BLKSIZE
Defines the default block size set automatically. Value
0xffffff means that the default is not used any more.
MT_ST_DEF_DENSITY
MT_ST_DEF_DRVBUFFER
MT_ST_DEF_COMPRESSION
Used to set or clear the density (8 bits), drive buffer
state (3 bits), and compression (single bit). If the value is
MT_ST_CLEAR_DEFAULT (0xfffff), the default will not be used
any more. Otherwise the lower-most bits of the value contain
the new value of the parameter.
The following ioctl uses the structure mtpos:
MTIOCPOS Reads the current position from the drive. Uses
......@@ -168,7 +250,7 @@ The recovered write errors are considered fatal if ST_RECOVERED_WRITE_FATAL
is defined.
The maximum number of tape devices is determined by the define
ST_MAX_TAPES. If more tapes are detected at driver intialization, the
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
......
/* fdomain.c -- Future Domain TMC-16x0 SCSI driver
* Created: Sun May 3 18:53:19 1992 by faith@cs.unc.edu
* Revised: Thu Feb 8 08:21:33 1996 by r.faith@ieee.org
* Revised: Thu Apr 4 20:44:47 1996 by r.faith@ieee.org
* Author: Rickard E. Faith, faith@cs.unc.edu
* Copyright 1992, 1993, 1994, 1995 Rickard E. Faith
* Copyright 1992, 1993, 1994, 1995, 1996 Rickard E. Faith
*
* $Id: fdomain.c,v 5.39 1995/10/12 20:31:47 root Exp $
* $Id: fdomain.c,v 5.41 1996/04/05 04:22:25 root Exp $
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
......@@ -21,9 +21,26 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
**************************************************************************
DESCRIPTION:
SUMMARY:
Future Domain BIOS versions supported for autodetect:
2.0, 3.0, 3.2, 3.4 (1.0), 3.5 (2.0), 3.6, 3.61
Chips are supported:
TMC-1800, TMC-18C50, TMC-18C30, TMC-36C70
Boards supported:
Future Domain TMC-1650, TMC-1660, TMC-1670, TMC-1680, TMC-1610M/MER/MEX
Future Domain TMC-3260 (PCI)
Quantum ISA-200S, ISA-250MG
Adaptec AHA-2920 (PCI)
IBM ?
LILO command-line options:
fdomain=<PORT_BASE>,<IRQ>[,<ADAPTER_ID>]
DESCRIPTION:
This is the Linux low-level SCSI driver for Future Domain TMC-1660/1680
TMC-1650/1670, and TMC-3260 SCSI host adapters. The 1650 and 1670 have a
25-pin external connector, whereas the 1660 and 1680 have a SCSI-2 50-pin
......@@ -38,11 +55,6 @@
signature, then the driver may fail to function after the board is
detected.
The following BIOS versions are supported: 2.0, 3.0, 3.2, 3.4, and 3.5.
The following chips are supported: TMC-1800, TMC-18C50, TMC-18C30.
Reports suggest that the driver will also work with the 36C70 chip and
with the Quantum ISA-200S and ISA-250MG SCSI adapters.
Please note that the drive ordering that Future Domain implemented in BIOS
versions 3.4 and 3.5 is the opposite of the order (currently) used by the
rest of the SCSI industry. If you have BIOS version 3.4 or 3.5, and have
......@@ -51,12 +63,48 @@
SCSI ID 1 will be C: (the boot device). Under Linux, SCSI ID 0 will be
/dev/sda and SCSI ID 1 will be /dev/sdb. The Linux ordering is consistent
with that provided by all the other SCSI drivers for Linux. If you want
this changed, send me patches that are protected by #ifdefs.
this changed, you will probably have to patch the higher level SCSI code.
If you do so, please send me patches that are protected by #ifdefs.
If you have a TMC-8xx or TMC-9xx board, then this is not the driver for
your board. Please refer to the Seagate driver for more information and
possible support.
HISTORY:
Linux Driver Driver
Version Version Date Support/Notes
0.0 3 May 1992 V2.0 BIOS; 1800 chip
0.97 1.9 28 Jul 1992
0.98.6 3.1 27 Nov 1992
0.99 3.2 9 Dec 1992
0.99.3 3.3 10 Jan 1993 V3.0 BIOS
0.99.5 3.5 18 Feb 1993
0.99.10 3.6 15 May 1993 V3.2 BIOS; 18C50 chip
0.99.11 3.17 3 Jul 1993 (now under RCS)
0.99.12 3.18 13 Aug 1993
0.99.14 5.6 31 Oct 1993 (reselection code removed)
0.99.15 5.9 23 Jan 1994 V3.4 BIOS (preliminary)
1.0.8/1.1.1 5.15 1 Apr 1994 V3.4 BIOS; 18C30 chip (preliminary)
1.0.9/1.1.3 5.16 7 Apr 1994 V3.4 BIOS; 18C30 chip
1.1.38 5.18 30 Jul 1994 36C70 chip (PCI version of 18C30)
1.1.62 5.20 2 Nov 1994 V3.5 BIOS
1.1.73 5.22 7 Dec 1994 Quantum ISA-200S board; V2.0 BIOS
1.1.82 5.26 14 Jan 1995 V3.5 BIOS; TMC-1610M/MER/MEX board
1.2.10 5.28 5 Jun 1995 Quantum ISA-250MG board; V2.0, V2.01 BIOS
1.3.4 5.31 23 Jun 1995 PCI BIOS-32 detection (preliminary)
1.3.7 5.33 4 Jul 1995 PCI BIOS-32 detection
1.3.28 5.36 17 Sep 1995 V3.61 BIOS; LILO command-line support
1.3.34 5.39 12 Oct 1995 V3.60 BIOS; /proc
1.3.72 5.39 8 Feb 1996 Adaptec AHA-2920 board
1.3.85 5.41 4 Apr 1996
REFERENCES USED:
......@@ -165,7 +213,8 @@
ENABLE_PARITY: This turns on SCSI parity checking. With the current
driver, all attached devices must support SCSI parity. If none of your
devices support parity, then you can probably get the driver to work by
turning this option off. I have no way of testing this, however.
turning this option off. I have no way of testing this, however, and it
would appear that no one ever uses this option.
FIFO_COUNT: The host adapter has an 8K cache (host adapters based on the
18C30 chip have a 2k cache). When this many 512 byte blocks are filled by
......@@ -226,7 +275,7 @@ struct proc_dir_entry proc_scsi_fdomain = {
S_IFDIR | S_IRUGO | S_IXUGO, 2
};
#define VERSION "$Revision: 5.39 $"
#define VERSION "$Revision: 5.41 $"
/* START OF USER DEFINABLE OPTIONS */
......
......@@ -31,7 +31,7 @@
*/
#define PPA_VERSION "0.20"
#define PPA_VERSION "0.26"
/* Change these variables here or with insmod or with a LILO or LOADLIN
command line argument
......@@ -40,7 +40,6 @@
static int ppa_base = 0x378; /* parallel port address */
static int ppa_speed_high = 1; /* port delay in data phase */
static int ppa_speed_low = 6; /* port delay otherwise */
static int ppa_call_sched = 1; /* give up the CPU ? */
static int ppa_nybble = 0; /* don't force nybble mode */
......@@ -52,6 +51,7 @@ static int ppa_nybble = 0; /* don't force nybble mode */
#include <unistd.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/tqueue.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/blk.h>
......@@ -70,10 +70,8 @@ static int ppa_error_code = DID_OK;
static char ppa_info_string[132];
static Scsi_Cmnd *ppa_current = 0;
static void (*ppa_done) (Scsi_Cmnd *);
static int ppa_busy = 0;
static int ppa_port_delay;
void out_p( short port, char byte)
{ outb(byte,ppa_base+port);
......@@ -140,11 +138,7 @@ char ppa_wait( void )
In principle, this could be tied to an interrupt, but the adapter
doesn't appear to be designed to support interrupts. We spin on
the 0x80 ready bit. If ppa_call_sched is 1, we call the scheduler
to allow other processes to run while we are waiting, just like
the lp driver does in polling mode. The performance hit is
significant, so this behaviour is configurable.
the 0x80 ready bit.
*/
{ int k;
......@@ -153,8 +147,8 @@ char ppa_wait( void )
ppa_error_code = DID_OK;
k = 0;
while (!((r = in_p(1)) & 0x80)
&& (k++ < PPA_SPIN_TMO) && !ppa_abort_flag )
if (need_resched && ppa_call_sched) schedule();
&& (k++ < PPA_SPIN_TMO) && !ppa_abort_flag ) barrier();
if (ppa_abort_flag) {
if (ppa_abort_flag == 1) ppa_error_code = DID_ABORT;
else { ppa_do_reset();
......@@ -330,10 +324,13 @@ int ppa_completion( Scsi_Cmnd * cmd )
return (r & STATUS_MASK);
}
/* deprecated synchronous interface */
int ppa_command( Scsi_Cmnd * cmd )
{ int s;
sti();
s = 0;
if (ppa_start(cmd))
if (ppa_wait())
......@@ -341,29 +338,59 @@ int ppa_command( Scsi_Cmnd * cmd )
return s + (ppa_error_code << 16);
}
int ppa_queuecommand( Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
/* pseudo-interrupt queueing interface */
/* This is not really a queued interface at all, but apparently there may
be some bugs in the mid-level support for the non-queued interface.
This function is re-entrant, but only to one level.
/* Since the PPA itself doesn't generate interrupts, we use
the scheduler's task queue to generate a stream of call-backs and
complete the request when the drive is ready.
*/
{ int s;
static void ppa_interrupt( void *data);
ppa_current = cmd; ppa_done = done;
if (ppa_busy) return 0;
ppa_busy = 1;
while (ppa_current) {
cmd = ppa_current; done = ppa_done;
s = 0;
if (ppa_start(cmd))
if (ppa_wait())
s = ppa_completion(cmd);
cmd->result = s + (ppa_error_code << 16);
static struct tq_struct ppa_tq = {0,0,ppa_interrupt,NULL};
static void ppa_interrupt( void *data)
{ Scsi_Cmnd *cmd;
void (*done) (Scsi_Cmnd *);
cmd = ppa_current;
done = ppa_done;
if (!cmd) return;
if (ppa_abort_flag) {
ppa_disconnect();
if(ppa_abort_flag == 1) cmd->result = DID_ABORT << 16;
else { ppa_do_reset();
cmd->result = DID_RESET << 16;
}
ppa_current = 0;
done(cmd); /* can reenter this function */
done(cmd);
return;
}
if (!( in_p(1) & 0x80)) {
queue_task(&ppa_tq,&tq_scheduler);
return;
}
cmd->result = ppa_completion(cmd) + (ppa_error_code << 16);
ppa_current = 0;
done(cmd);
return;
}
int ppa_queuecommand( Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
{ if (ppa_current) return 0;
sti();
ppa_current = cmd;
ppa_done = done;
if (!ppa_start(cmd)) {
cmd->result = ppa_error_code << 16;
ppa_current = 0;
done(cmd);
return 0;
}
ppa_busy = 0;
queue_task(&ppa_tq,&tq_scheduler);
return 0;
}
......@@ -453,7 +480,7 @@ const char *ppa_info( struct Scsi_Host * host )
/* Command line parameters (for built-in driver):
Syntax: ppa=base[,speed_high[,speed_low[,call_sched[,nybble]]]]
Syntax: ppa=base[,speed_high[,speed_low[,nybble]]]
For example: ppa=0x378 or ppa=0x378,0,3
......@@ -464,7 +491,7 @@ void ppa_setup(char *str, int *ints)
{ if (ints[0] > 0) ppa_base = ints[1];
if (ints[0] > 1) ppa_speed_high = ints[2];
if (ints[0] > 2) ppa_speed_low = ints[3];
if (ints[0] > 3) ppa_call_sched = ints[4];
if (ints[0] > 3) ppa_nybble = ints[4];
if (ints[0] > 4) ppa_nybble = ints[5];
}
......
......@@ -149,6 +149,10 @@ static int ioctl_internal_command(Scsi_Device *dev, char * cmd)
result = SCpnt->result;
SCpnt->request.rq_status = RQ_INACTIVE;
if(SCpnt->device->scsi_request_fn)
(*SCpnt->device->scsi_request_fn)();
wake_up(&SCpnt->device->device_wait);
return result;
}
......
This diff is collapsed.
......@@ -9,6 +9,7 @@
#include "scsi.h"
#endif
/* The tape buffer descriptor. */
typedef struct {
unsigned char in_use;
unsigned char dma; /* DMA-able buffer */
......@@ -24,11 +25,48 @@ typedef struct {
unsigned char *orig_b_data;
} ST_buffer;
/* The tape mode definition */
typedef struct {
unsigned char defined;
unsigned char do_async_writes;
unsigned char do_buffer_writes;
unsigned char defaults_for_writes;
unsigned char default_compression; /* 0 = don't touch, etc */
short default_density; /* Forced density, -1 = no value */
int default_blksize; /* Forced blocksize, -1 = no value */
} ST_mode;
#define ST_NBR_MODE_BITS 2
#define ST_NBR_MODES (1 << ST_NBR_MODE_BITS)
#define ST_MODE_SHIFT (7 - ST_NBR_MODE_BITS)
#define ST_MODE_MASK ((ST_NBR_MODES - 1) << ST_MODE_SHIFT)
/* The tape drive descriptor */
typedef struct {
kdev_t devt;
unsigned capacity;
struct wait_queue * waiting;
Scsi_Device* device;
Scsi_Cmnd SCpnt;
struct semaphore sem;
ST_buffer * buffer;
/* Drive characteristics */
unsigned char do_read_ahead;
unsigned char do_auto_lock;
unsigned char can_bsr;
unsigned char two_fm;
unsigned char fast_mteom;
unsigned char restr_dma;
unsigned char default_drvbuffer; /* 0xff = don't touch, value 3 bits */
int write_threshold;
/* Mode characteristics */
ST_mode modes[ST_NBR_MODES];
int current_mode;
/* Status variables */
unsigned char dirty;
unsigned char rw;
unsigned char ready;
......@@ -37,29 +75,22 @@ typedef struct {
unsigned char drv_write_prot;
unsigned char in_use;
unsigned char eof_hit;
unsigned char moves_after_eof;
unsigned char at_sm;
unsigned char blksize_changed;
unsigned char density_changed;
unsigned char compression_changed;
unsigned char drv_buffer;
unsigned char restr_dma;
unsigned char do_buffer_writes;
unsigned char do_async_writes;
unsigned char do_read_ahead;
unsigned char do_auto_lock;
unsigned char two_fm;
unsigned char fast_mteom;
unsigned char density;
unsigned char door_locked;
unsigned char rew_at_close;
ST_buffer * buffer;
struct semaphore sem;
int block_size;
int min_block;
int max_block;
int write_threshold;
int recover_count;
int drv_block; /* The block where the drive head is */
unsigned char moves_after_eof;
unsigned char at_sm;
struct mtget * mt_status;
Scsi_Cmnd SCpnt;
#if DEBUG
unsigned char write_pending;
int nbr_finished;
......@@ -96,5 +127,10 @@ extern Scsi_Tape * scsi_tapes;
#define QFA_REQUEST_BLOCK 0x02
#define QFA_SEEK_BLOCK 0x0c
/* Setting the binary options */
#define ST_DONT_TOUCH 0
#define ST_NO 1
#define ST_YES 2
#endif
......@@ -20,10 +20,10 @@ bool '/proc filesystem support' CONFIG_PROC_FS
if [ "$CONFIG_INET" = "y" ]; then
tristate 'NFS filesystem support' CONFIG_NFS_FS
if [ "$CONFIG_NFS_FS" = "y" ]; then
bool 'Root file system on NFS' CONFIG_ROOT_NFS
bool ' Root file system on NFS' CONFIG_ROOT_NFS
if [ "$CONFIG_ROOT_NFS" = "y" ]; then
bool 'BOOTP support' CONFIG_RNFS_BOOTP
bool 'RARP support' CONFIG_RNFS_RARP
bool ' BOOTP support' CONFIG_RNFS_BOOTP
bool ' RARP support' CONFIG_RNFS_RARP
fi
fi
tristate 'SMB filesystem support (to mount WfW shares etc..)' CONFIG_SMB_FS
......
......@@ -130,6 +130,7 @@ void __wait_on_buffer(struct buffer_head * bh)
bh->b_count++;
add_wait_queue(&bh->b_wait, &wait);
repeat:
run_task_queue(&tq_disk);
current->state = TASK_UNINTERRUPTIBLE;
if (buffer_locked(bh)) {
schedule();
......@@ -993,6 +994,7 @@ static void get_more_buffer_heads(void)
* wait for old buffer heads to become free due to
* finishing IO..
*/
run_task_queue(&tq_disk);
sleep_on(&buffer_wait);
}
......@@ -1817,6 +1819,7 @@ struct wait_queue * bdflush_done = NULL;
static void wakeup_bdflush(int wait)
{
run_task_queue(&tq_disk);
wake_up(&bdflush_wait);
if(wait) sleep_on(&bdflush_done);
}
......@@ -1930,7 +1933,7 @@ asmlinkage int sys_bdflush(int func, long data)
return -EINVAL;
bdf_prm.data[i] = data;
return 0;
};
}
/* Having func 0 used to launch the actual bdflush and then never
return (unless explicitly killed). We return zero here to
......@@ -2023,6 +2026,7 @@ int bdflush(void * unused)
if (ncount) printk("sys_bdflush: %d dirty buffers not on dirty list\n", ncount);
printk("sleeping again.\n");
#endif
run_task_queue(&tq_disk);
wake_up(&bdflush_done);
/* If there are still a lot of dirty buffers around, skip the sleep
......
......@@ -465,7 +465,13 @@ int prepare_binprm(struct linux_binprm *bprm)
bprm->e_gid = current->egid;
} else {
bprm->e_uid = (i & S_ISUID) ? bprm->inode->i_uid : current->euid;
bprm->e_gid = (i & S_ISGID) ? bprm->inode->i_gid : current->egid;
/*
* If setgid is set but no group execute bit then this
* is a candidate for mandatory locking, not a setgid
* executable.
*/
bprm->e_gid = ((i & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ?
bprm->inode->i_gid : current->egid;
}
if ((retval = permission(bprm->inode, MAY_EXEC)) != 0)
return retval;
......
......@@ -13,8 +13,6 @@
#include <linux/fcntl.h>
#include <linux/string.h>
extern int fcntl_getlk(unsigned int, struct flock *);
extern int fcntl_setlk(unsigned int, unsigned int, struct flock *);
extern int sock_fcntl (struct file *, unsigned int cmd, unsigned long arg);
static inline int dupfd(unsigned int fd, unsigned int arg)
......
......@@ -54,11 +54,14 @@ static inline struct inode_hash_entry * const hash(kdev_t dev, int i)
static inline void insert_inode_free(struct inode *inode)
{
inode->i_next = first_inode;
inode->i_prev = first_inode->i_prev;
inode->i_next->i_prev = inode;
inode->i_prev->i_next = inode;
struct inode * prev, * next = first_inode;
first_inode = inode;
prev = next->i_prev;
inode->i_next = next;
inode->i_prev = prev;
prev->i_next = inode;
next->i_prev = inode;
}
static inline void remove_inode_free(struct inode *inode)
......
......@@ -51,21 +51,24 @@
*
* Removed some race conditions in flock_lock_file(), marked other possible
* races. Just grep for FIXME to see them.
* Dmitry Gorodchanin (begemot@bgm.rosprint.net), Feb 09, 1996.
* Dmitry Gorodchanin (begemot@bgm.rosprint.net), February 09, 1996.
*
* Addressed Dmitry's concerns. Deadlock checking no longer recursive.
* Lock allocation changed to GFP_ATOMIC as we can't afford to sleep
* once we've checked for blocking and deadlocking.
* Andy Walker (andy@lysaker.kvaerner.no), Apr 03, 1996.
* Andy Walker (andy@lysaker.kvaerner.no), April 03, 1996.
*
* NOTE:
* Starting to look at mandatory locks - using SunOS as a model.
* Probably a configuration option because mandatory locking can cause
* all sorts of chaos with runaway processes.
*
* Initial implementation of mandatory locks. SunOS turned out to be
* a rotten model, so I implemented the "obvious" semantics.
* See 'linux/Documentation/mandatory.txt' for details.
* Andy Walker (andy@lysaker.kvaerner.no), April 06, 1996.
*/
#include <asm/segment.h>
#include <linux/malloc.h>
#include <linux/sched.h>
#include <linux/kernel.h>
......@@ -73,6 +76,7 @@
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <asm/segment.h>
#define OFFSET_MAX ((off_t)0x7fffffff) /* FIXME: move elsewhere? */
......@@ -284,6 +288,63 @@ void locks_remove_locks(struct task_struct *task, struct file *filp)
return;
}
int locks_verify(int read_write, struct inode *inode, struct file *filp,
unsigned int offset, unsigned int count)
{
/* Candidates for mandatory locking have the setgid bit set
* but no group execute bit - an otherwise meaningless combination.
*/
if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
return (locks_locked_mandatory(read_write, inode, filp,
offset, count));
return (0);
}
int locks_locked_mandatory(int read_write, struct inode *inode,
struct file *filp, unsigned int offset,
unsigned int count)
{
struct file_lock *fl;
repeat:
/*
* Search the lock list for this inode for locks that conflict with
* the proposed read/write.
*/
for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
if (fl->fl_flags == F_FLOCK ||
(fl->fl_flags == F_POSIX && fl->fl_owner == current))
continue;
if (fl->fl_end < offset ||
fl->fl_start >= offset + count)
continue;
/*
* Block for writes against a "read" lock, and both reads and
* writes against a "write" lock.
*/
if (read_write == FLOCK_VERIFY_WRITE ||
fl->fl_type == F_WRLCK) {
if (filp && (filp->f_flags & O_NONBLOCK))
return (-EAGAIN);
if (current->signal & ~current->blocked)
return (-ERESTARTSYS);
if (posix_locks_deadlock(current, fl->fl_owner))
return (-EDEADLOCK);
interruptible_sleep_on(&fl->fl_wait);
if (current->signal & ~current->blocked)
return (-ERESTARTSYS);
/*
* If we've been sleeping someone might have changed
* the permissions behind our back.
*/
if ((inode->i_mode & (S_ISGID | S_IXGRP)) != S_ISGID)
break;
goto repeat;
}
}
return (0);
}
/* Verify a "struct flock" and copy it to a "struct file_lock" as a POSIX
* style lock.
*/
......
......@@ -17,6 +17,7 @@
#include <linux/sched.h>
#include <linux/nfs_fs.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/rpcsock.h>
#include <linux/nfsiod.h>
......
......@@ -43,6 +43,10 @@
* different RARP and NFS servers.
* Gero Kuhlmann : "0.0.0.0" addresses from command line are
* now mapped to INADDR_NONE.
* Gero Kuhlmann : Fixed a bug which prevented BOOTP path name
* from being used (thanks to Leo Spiekman)
* Andy Walker : Allow to specify the NFS server in nfs_root
* without giving a path name
*
*/
......@@ -1049,11 +1053,23 @@ static struct nfs_bool_opts {
static int root_nfs_name(char *name)
{
char buf[NFS_MAXPATHLEN];
char *cp, *options, *val;
char *cp, *cq, *options, *val;
int octets = 0;
/* It is possible to override the server IP number here */
if (*name >= '0' && *name <= '9' && (cp = strchr(name, ':')) != NULL) {
*cp++ = '\0';
cp = cq = name;
while (octets < 4) {
while (*cp >= '0' && *cp <= '9')
cp++;
if (cp == cq || cp - cq > 3)
break;
if (*cp == '.' || octets == 3)
octets++;
cq = cp;
}
if (octets == 4 && (*cp == ':' || *cp == '\0')) {
if (*cp == ':')
*cp++ = '\0';
server.sin_addr.s_addr = in_aton(name);
name = cp;
}
......@@ -1064,12 +1080,15 @@ static int root_nfs_name(char *name)
sizeof(nfs_data.hostname)-1);
/* Set the name of the directory to mount */
cp = in_ntoa(myaddr.sin_addr.s_addr);
strncpy(buf, name, 255);
if (nfs_path[0] == '\0' || !strncmp(name, "default", 7))
strncpy(buf, name, NFS_MAXPATHLEN);
else
strncpy(buf, nfs_path, NFS_MAXPATHLEN);
if ((options = strchr(buf, ',')))
*options++ = '\0';
if (!strcmp(buf, "default"))
strcpy(buf, NFS_ROOT);
cp = in_ntoa(myaddr.sin_addr.s_addr);
if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) {
printk(KERN_ERR "Root-NFS: Pathname for remote directory too long.\n");
return -1;
......
......@@ -285,7 +285,7 @@ rpc_cwnd_adjust(struct rpc_sock *rsock, int timeout)
static inline void
rpc_send_check(char *where, u32 *ptr)
{
if (ptr[1] != 0 || ptr[2] != htonl(2) || ptr[3] != htonl(100003)) {
if (ptr[1] != htonl(RPC_CALL) || ptr[2] != htonl(RPC_VERSION)) {
printk("RPC: %s sending evil packet:\n"
" %08x %08x %08x %08x %08x %08x %08x %08x\n",
where,
......
......@@ -20,8 +20,6 @@
#include <asm/segment.h>
extern void locks_remove_locks(struct task_struct *, struct file *);
asmlinkage int sys_statfs(const char * path, struct statfs * buf)
{
struct inode * inode;
......@@ -109,6 +107,11 @@ asmlinkage int sys_truncate(const char * path, unsigned long length)
iput(inode);
return error;
}
error = locks_verify(FLOCK_VERIFY_WRITE, inode, NULL,
length < inode->i_size ? length : inode->i_size,
abs(inode->i_size - length));
if (error)
return error;
error = do_truncate(inode, length);
put_write_access(inode);
iput(inode);
......@@ -119,6 +122,7 @@ asmlinkage int sys_ftruncate(unsigned int fd, unsigned long length)
{
struct inode * inode;
struct file * file;
int error;
if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
return -EBADF;
......@@ -128,6 +132,11 @@ asmlinkage int sys_ftruncate(unsigned int fd, unsigned long length)
return -EACCES;
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
return -EPERM;
error = locks_verify(FLOCK_VERIFY_WRITE, inode, file,
length < inode->i_size ? length : inode->i_size,
abs(inode->i_size - length));
if (error)
return error;
return do_truncate(inode, length);
}
......@@ -391,8 +400,12 @@ asmlinkage int sys_fchown(unsigned int fd, uid_t user, gid_t group)
}
/*
* If the group has been changed, remove the setgid bit
*
* Don't remove the setgid bit if no group execute bit.
* This is a file marked for mandatory locking.
*/
if (group != inode->i_gid && (inode->i_mode & S_ISGID)) {
if (group != inode->i_gid &&
((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) {
newattrs.ia_mode &= ~S_ISGID;
newattrs.ia_valid |= ATTR_MODE;
}
......@@ -443,8 +456,12 @@ asmlinkage int sys_chown(const char * filename, uid_t user, gid_t group)
}
/*
* If the group has been changed, remove the setgid bit
*
* Don't remove the setgid bit if no group execute bit.
* This is a file marked for mandatory locking.
*/
if (group != inode->i_gid && (inode->i_mode & S_ISGID)) {
if (group != inode->i_gid &&
((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) {
newattrs.ia_mode &= ~S_ISGID;
newattrs.ia_valid |= ATTR_MODE;
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -860,6 +860,11 @@ static void do_mount_root(void)
current->fs->root = inode;
ROOT_DEV = sb->s_dev;
printk (KERN_NOTICE "VFS: Mounted root (nfs filesystem).\n");
vfsmnt = add_vfsmnt(ROOT_DEV, "rootfs", "/");
if (!vfsmnt)
panic("VFS: add_vfsmnt failed for NFS root.\n");
vfsmnt->mnt_sb = sb;
vfsmnt->mnt_flags = sb->s_flags;
return;
}
sb->s_dev = 0;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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