Commit db8fee17 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.1.37

parent c36878ed
......@@ -149,12 +149,8 @@ S: 91452 Wilhermsdorf
S: Germany
N: Bill Bogstad
E: bogstad@cs.jhu.edu
D: Wrote /proc/self patch
S: Johns Hopkins University
S: Computer Science Department
S: Baltimore, Maryland 21218
S: USA
E: bogstad@pobox.com
D: wrote /proc/self hack, minor samba & dosemu patches
N: Axel Boldt
E: boldt@math.ucsb.edu
......@@ -468,7 +464,7 @@ S: Carnegie, Pennsylvania 15106-4304
S: USA
N: Philip Gladstone
E: philipg@onsett.com
E: philip@raptor.com
D: Kernel / timekeeping stuff
N: Michael A. Griffith
......
......@@ -29,7 +29,7 @@ English-language HTML version.
Also, don't forget http://www.linuxhq.com/ for all your Linux kernel
needs.
Last updated: April 24, 1997.
Last updated: May 12, 1997.
Current Author: Chris Ricker (gt1355b@prism.gatech.edu).
Current Minimal Requirements
......@@ -40,13 +40,13 @@ encountered a bug!
- Kernel modules modutils-2.1.34
- Gnu C 2.7.2.1
- Binutils 2.7.0.9
- Binutils 2.8.0.3
- Linux C Library 5.4.23
- Dynamic Linker (ld.so) 1.8.5
- Linux C++ Library 2.7.2.1
- Procps 1.01
- Mount 2.6g
- Net-tools 1.32-alpha
- Net-tools 1.41
- Loadlin 1.6a
- Sh-utils 1.16
- Autofs 0.3.0
......@@ -131,6 +131,9 @@ presence.
To run bootpd, you'll need to issue the following command: echo 1
>/proc/sys/net/ipv4/ip_boot_agent
For support for new features like IPv6, upgrade to the latest
net-tools.
Mount and network file systems
==============================
......@@ -179,8 +182,7 @@ How to know the version of the installed programs
*************************************************
There are some simple methods useful to know the version of the
installed programs and libraries. The SysVinit version display
requires that you be logged in as root.
installed programs and libraries.
Binutils: ld -v
Gnu C: gcc -v or gcc --version
......@@ -190,6 +192,7 @@ Libc: ls -l /lib/libc.so.*
Libc++: ls -l /usr/lib/libg++.so.*
Modutils: insmod -V
Mount: mount --version
Net-tools: hostname -V
Procps: ps --version
RPM: rpm --version
Sh-utils: expr --v
......@@ -200,12 +203,12 @@ Where to get the files
Binutils
========
The 2.7.0.9 release:
ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.7.0.9.bin.tar.gz
ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.7.0.9.bin.tar.gz
The 2.8.0.3 release:
ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.8.0.3.bin.tar.gz
ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.8.0.3.bin.tar.gz
Installation notes:
ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.binutils-2.7.0.9
ftp://sunsite.unc.edu/pub/Linux/GCC/release.binutils-2.7.0.9
ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.binutils-2.8.0.3
ftp://sunsite.unc.edu/pub/Linux/GCC/release.binutils-2.8.0.3
Gnu C
=====
......@@ -311,6 +314,13 @@ The 0.4.21 release:
ftp://ftp.mathematik.th-darmstadt.de/pub/linux/okir/linux-nfs-0.4.21.tar.gz
ftp://linux.nrao.edu/pub/people/okir/linux-nfs-0.4.21.tar.gz
Net-tools
=========
The 0.41 release:
ftp://ftp.london.uk.eu.org/pub/ipv6/net-tools-1.41.tar.gz
ftp://ftp.cs-ipv6.lancs.ac.uk/pub/Code/Linux/Net_Tools/net-tools-1.41.tar.gz
Other Info
==========
......
......@@ -2,42 +2,30 @@
Andy Walker <andy@lysaker.kvaerner.no>
21 Sep 1996
12 May 1997
1. What's New?
--------------
1.1 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:
1.1 Broken Flock Emulation
--------------------------
fcntl_setlk() called by process XX with broken flock() emulation
The old flock(2) emulation in the kernel was swapped for proper BSD
compatible flock(2) support in the 1.3.x series of kernels. With the
release of the 2.1.x kernel series, support for the old emulation has
been totally removed, so that we don't need to carry this baggage
forever.
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.
This should not cause problems for anybody, since everybody using a
2.1.x kernel should have updated their C library to a suitable version
anyway (see the file "linux/Documentation/Changes".)
Fixed versions of the C libraries have been on public release for many
months. The latest versions at the time of writing are 5.3.12 (released)
or 5.4.6 (testing) for ELF. There is also a 4.7.6 release for people
using a.out systems.
1.2 Allow Mixed Locks Again
---------------------------
With the release of Linux 2.0 Linus decided to be lenient on the
stragglers and changed the warning message so that the kernel will only
complain once and then shut up. That should make life more bearable even
for people who, for some reason, don't want to upgrade their libraries.
1.2 Disallow Mixed Locks
------------------------
1.2.1 Sendmail Problems
---------------------
1.2.1 Typical Problems - Sendmail
---------------------------------
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
......@@ -50,23 +38,17 @@ to lock solid with deadlocked processes.
1.2.2 The Solution
------------------
I have chosen the rather cruel solution of disallowing mixed locking styles
on a given file at a given time. Attempts to lock a file with flock() when
fcntl() locks exist, or vice versa, return with an error status of EBUSY.
This seemed to be the only way to avoid all possible deadlock conditions,
as flock() locks do not strictly have one owner process and so can't be
checked for deadlocking in the usual manner.
The process that created a lock with flock() might have forked multiple
children and exited. Previously the parent process would have been marked
as the owner of the lock, but deadlocks could just have easily occurred in
one or more of the children, which we would not have been able to identify
and avoid.
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.
The solution I have chosen, after much experimentation and discussion,
is to make flock() and fcntl() locks oblivious to each other. Both can
exists, and neither will have any effect on the other.
I wanted the two lock styles to be cooperative, but there were so many
race and deadlock conditions that the current solution was the only
practical one. It puts us in the same position as, for example, SunOS
4.1.x and serveral other commercial Unices. The only OS's that support
cooperative flock()/fcntl() are those that emulate flock() using
fcntl(), with all the problems that implies.
1.3 Mandatory Locking As A Mount Option
---------------------------------------
......
......@@ -141,6 +141,7 @@ CONFIG_SCSI_OMIT_FLASHPOINT=y
# CONFIG_SCSI_QLOGIC_FAS is not set
# CONFIG_SCSI_QLOGIC_ISP is not set
# CONFIG_SCSI_SEAGATE is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_T128 is not set
# CONFIG_SCSI_U14_34F is not set
# CONFIG_SCSI_ULTRASTOR is not set
......
......@@ -83,7 +83,7 @@ static unsigned long get_long(struct task_struct * tsk,
repeat:
pgdir = pgd_offset(vma->vm_mm, addr);
if (pgd_none(*pgdir)) {
do_no_page(tsk, vma, addr, 0);
handle_mm_fault(vma, addr, 0);
goto repeat;
}
if (pgd_bad(*pgdir)) {
......@@ -93,7 +93,7 @@ static unsigned long get_long(struct task_struct * tsk,
}
pgmiddle = pmd_offset(pgdir, addr);
if (pmd_none(*pgmiddle)) {
do_no_page(tsk, vma, addr, 0);
handle_mm_fault(vma, addr, 0);
goto repeat;
}
if (pmd_bad(*pgmiddle)) {
......@@ -103,7 +103,7 @@ static unsigned long get_long(struct task_struct * tsk,
}
pgtable = pte_offset(pgmiddle, addr);
if (!pte_present(*pgtable)) {
do_no_page(tsk, vma, addr, 0);
handle_mm_fault(vma, addr, 0);
goto repeat;
}
page = pte_page(*pgtable);
......@@ -134,7 +134,7 @@ static void put_long(struct task_struct * tsk, struct vm_area_struct * vma, unsi
repeat:
pgdir = pgd_offset(vma->vm_mm, addr);
if (!pgd_present(*pgdir)) {
do_no_page(tsk, vma, addr, 1);
handle_mm_fault(vma, addr, 1);
goto repeat;
}
if (pgd_bad(*pgdir)) {
......@@ -144,7 +144,7 @@ static void put_long(struct task_struct * tsk, struct vm_area_struct * vma, unsi
}
pgmiddle = pmd_offset(pgdir, addr);
if (pmd_none(*pgmiddle)) {
do_no_page(tsk, vma, addr, 1);
handle_mm_fault(vma, addr, 1);
goto repeat;
}
if (pmd_bad(*pgmiddle)) {
......@@ -154,12 +154,12 @@ static void put_long(struct task_struct * tsk, struct vm_area_struct * vma, unsi
}
pgtable = pte_offset(pgmiddle, addr);
if (!pte_present(*pgtable)) {
do_no_page(tsk, vma, addr, 1);
handle_mm_fault(vma, addr, 1);
goto repeat;
}
page = pte_page(*pgtable);
if (!pte_write(*pgtable)) {
do_wp_page(tsk, vma, addr, 1);
handle_mm_fault(vma, addr, 1);
goto repeat;
}
/* this is a hack for non-kernel-mapped video buffers and similar */
......
......@@ -247,7 +247,7 @@ static const char * i586model(unsigned int nr)
static const char * i686model(unsigned int nr)
{
static const char *model[] = {
"PPro A-step", "Pentium Pro"
"PPro A-step", "Pentium Pro", "2", "Pentium II"
};
if (nr < sizeof(model)/sizeof(char *))
return model[nr];
......@@ -279,9 +279,10 @@ static const char * getmodel(int x86, int model)
int get_cpuinfo(char * buffer)
{
int i, len = 0;
int sep_bug;
static const char *x86_cap_flags[] = {
"fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
"cx8", "apic", "10", "11", "mtrr", "pge", "mca", "cmov",
"cx8", "apic", "10", "sep", "mtrr", "pge", "mca", "cmov",
"16", "17", "18", "19", "20", "21", "22", "mmx",
"24", "25", "26", "27", "28", "29", "30", "31"
};
......@@ -321,10 +322,16 @@ int get_cpuinfo(char * buffer)
else
len += sprintf(buffer+len,
"stepping\t: unknown\n");
sep_bug = CD(have_cpuid) &&
(CD(x86_capability) & 0x800) &&
CD(x86_model) < 3 &&
CD(x86_mask) < 3;
len += sprintf(buffer+len,
"fdiv_bug\t: %s\n"
"hlt_bug\t\t: %s\n"
"sep_bug\t\t: %s\n"
"fpu\t\t: %s\n"
"fpu_exception\t: %s\n"
"cpuid\t\t: %s\n"
......@@ -332,6 +339,7 @@ int get_cpuinfo(char * buffer)
"flags\t\t:",
CD(fdiv_bug) ? "yes" : "no",
CD(hlt_works_ok) ? "no" : "yes",
sep_bug ? "yes" : "no",
CD(hard_math) ? "yes" : "no",
(CD(hard_math) && ignore_irq13)
? "yes" : "no",
......
......@@ -1250,10 +1250,13 @@ void smp_message_pass(int target, int msg, unsigned long data, int wait)
void smp_flush_tlb(void)
{
unsigned long flags;
#if 0
if(smp_activated && smp_processor_id()!=active_kernel_processor) {
printk("CPU #%d:Attempted flush tlb IPI when not AKP(=%d)\n",smp_processor_id(),active_kernel_processor);
*(char *)0=0;
}
#endif
/* printk("SMI-");*/
/*
......
......@@ -13,28 +13,31 @@
* there is contention on the semaphore.
*/
ENTRY(__down_failed)
pushl %eax /* return address */
pushl %eax /* save %eax */
pushl %edx /* save %edx */
pushl %ecx /* save %ecx (and argument) */
call SYMBOL_NAME(__down)
popl %ecx /* restore %ecx (count on __down not changing it) */
popl %edx /* restore %edx */
popl %eax /* restore %eax */
ret
ENTRY(__down_failed_interruptible)
pushl %eax /* return address */
pushl %eax /* save %eax */
pushl %edx /* save %edx */
pushl %ecx /* save %ecx (and argument) */
call SYMBOL_NAME(__down_interruptible)
popl %ecx /* restore %ecx (count on __down_interruptible not changing it) */
popl %edx /* restore %edx */
popl %eax /* restore %eax */
ret
ENTRY(__up_wakeup)
pushl %eax /* return address */
pushl %eax /* save %eax */
pushl %edx /* save %edx */
pushl %ecx /* save %ecx (and argument) */
call SYMBOL_NAME(__up)
popl %ecx /* restore %ecx (count on __up not changing it) */
popl %edx /* restore %edx */
popl %eax /* restore %eax */
ret
......@@ -49,7 +49,7 @@ int __verify_write(const void * addr, unsigned long size)
start &= PAGE_MASK;
for (;;) {
do_wp_page(current, vma, start, 1);
handle_mm_fault(vma, start, 1);
if (!size)
break;
size--;
......@@ -86,10 +86,6 @@ int __verify_write(const void * addr, unsigned long size)
*/
asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
{
void (*handler)(struct task_struct *,
struct vm_area_struct *,
unsigned long,
int);
struct task_struct *tsk = current;
struct mm_struct *mm = tsk->mm;
struct vm_area_struct * vma;
......@@ -128,10 +124,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
*/
good_area:
write = 0;
handler = do_no_page;
switch (error_code & 3) {
default: /* 3: write, present */
handler = do_wp_page;
#ifdef TEST_VERIFY_AREA
if (regs->cs == KERNEL_CS)
printk("WP fault at %08lx\n", regs->eip);
......@@ -148,7 +142,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
goto bad_area;
}
handler(tsk, vma, address, write);
handle_mm_fault(vma, address, write);
up(&mm->mmap_sem);
/*
* Did it hit the DOS screen memory VA from vm86 mode?
......
......@@ -726,7 +726,7 @@ static void idefloppy_pc_intr (ide_drive_t *drive)
return;
}
#ifdef CONFIG_BLK_DEV_TRITON
if (clear_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
if (test_and_clear_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
printk (KERN_ERR "ide-floppy: The floppy wants to issue more interrupts in DMA mode\n");
printk (KERN_ERR "ide-floppy: DMA disabled, reverting to PIO\n");
HWIF(drive)->dmaproc(ide_dma_off, drive);
......@@ -842,7 +842,7 @@ static void idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *pc)
bcount.all=pc->request_transfer; /* Request to transfer the entire buffer at once */
#ifdef CONFIG_BLK_DEV_TRITON
if (clear_bit (PC_DMA_ERROR, &pc->flags)) {
if (test_and_clear_bit (PC_DMA_ERROR, &pc->flags)) {
printk (KERN_WARNING "ide-floppy: DMA disabled, reverting to PIO\n");
HWIF(drive)->dmaproc(ide_dma_off, drive);
}
......@@ -1182,7 +1182,7 @@ static int idefloppy_media_change (ide_drive_t *drive)
{
idefloppy_floppy_t *floppy = drive->driver_data;
return clear_bit (IDEFLOPPY_MEDIA_CHANGED, &floppy->flags);
return test_and_clear_bit (IDEFLOPPY_MEDIA_CHANGED, &floppy->flags);
}
/*
......
......@@ -1777,7 +1777,7 @@ static void idetape_pc_intr (ide_drive_t *drive)
return;
}
#ifdef CONFIG_BLK_DEV_TRITON
if (clear_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
if (test_and_clear_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
printk (KERN_ERR "ide-tape: The tape wants to issue more interrupts in DMA mode\n");
printk (KERN_ERR "ide-tape: DMA disabled, reverting to PIO\n");
HWIF(drive)->dmaproc(ide_dma_off, drive);
......@@ -1916,7 +1916,7 @@ static void idetape_issue_packet_command (ide_drive_t *drive, idetape_pc_t *pc)
bcount.all=pc->request_transfer; /* Request to transfer the entire buffer at once */
#ifdef CONFIG_BLK_DEV_TRITON
if (clear_bit (PC_DMA_ERROR, &pc->flags)) {
if (test_and_clear_bit (PC_DMA_ERROR, &pc->flags)) {
printk (KERN_WARNING "ide-tape: DMA disabled, reverting to PIO\n");
HWIF(drive)->dmaproc(ide_dma_off, drive);
}
......@@ -2248,7 +2248,7 @@ static void idetape_do_request (ide_drive_t *drive, struct request *rq, unsigned
status.all = GET_STAT();
if (!drive->dsc_overlap && rq->cmd != IDETAPE_PC_RQ2)
set_bit (IDETAPE_IGNORE_DSC, &tape->flags);
if (!clear_bit (IDETAPE_IGNORE_DSC, &tape->flags) && !status.b.dsc) {
if (!test_and_clear_bit (IDETAPE_IGNORE_DSC, &tape->flags) && !status.b.dsc) {
if (postponed_rq == NULL) {
tape->dsc_polling_start = jiffies;
tape->dsc_polling_frequency = tape->best_dsc_rw_frequency;
......@@ -2506,7 +2506,7 @@ static int idetape_add_chrdev_write_request (ide_drive_t *drive, int blocks)
if (!idetape_pipeline_active (tape) && tape->nr_stages >= (3 * tape->max_stages) / 4)
idetape_insert_pipeline_into_queue (drive);
if (clear_bit (IDETAPE_PIPELINE_ERROR, &tape->flags)) /* Return a deferred error */
if (test_and_clear_bit (IDETAPE_PIPELINE_ERROR, &tape->flags)) /* Return a deferred error */
return -EIO;
return blocks;
}
......@@ -3254,7 +3254,7 @@ static int idetape_chrdev_open (struct inode *inode, struct file *filp)
return -ENXIO;
tape = drive->driver_data;
if (set_bit (IDETAPE_BUSY, &tape->flags))
if (test_and_set_bit (IDETAPE_BUSY, &tape->flags))
return -EBUSY;
MOD_INC_USE_COUNT;
idetape_create_read_position_cmd (&pc);
......
......@@ -216,7 +216,7 @@ void process_keycode (int keycode)
#endif
}
} else
rep = set_bit(keycode, key_down);
rep = test_and_set_bit(keycode, key_down);
if (raw_mode)
return;
......
......@@ -461,11 +461,11 @@ isac_bh(struct IsdnCardState *sp)
if (!sp)
return;
if (clear_bit(ISAC_PHCHANGE, &sp->event))
if (test_and_clear_bit(ISAC_PHCHANGE, &sp->event))
process_new_ph(sp);
if (clear_bit(ISAC_RCVBUFREADY, &sp->event))
if (test_and_clear_bit(ISAC_RCVBUFREADY, &sp->event))
process_rcv(sp);
if (clear_bit(ISAC_XMTBUFREADY, &sp->event))
if (test_and_clear_bit(ISAC_XMTBUFREADY, &sp->event))
process_xmt(sp);
}
......@@ -578,9 +578,9 @@ hscx_bh(struct HscxState *hsp)
if (!hsp)
return;
if (clear_bit(HSCX_RCVBUFREADY, &hsp->event))
if (test_and_clear_bit(HSCX_RCVBUFREADY, &hsp->event))
hscx_process_rcv(hsp);
if (clear_bit(HSCX_XMTBUFREADY, &hsp->event))
if (test_and_clear_bit(HSCX_XMTBUFREADY, &hsp->event))
hscx_process_xmt(hsp);
}
......
......@@ -934,7 +934,7 @@ isdn_net_start_xmit(struct sk_buff *skb, struct device *ndev)
return 0;
}
/* Avoid timer-based retransmission conflicts. */
if (set_bit(0, (void *) &ndev->tbusy) != 0)
if (test_and_set_bit(0, (void *) &ndev->tbusy) != 0)
printk(KERN_WARNING
"%s: Transmitter access conflict.\n",
ndev->name);
......
......@@ -487,7 +487,7 @@ void sunkbd_inchar(unsigned char ch, struct pt_regs *regs)
add_timer (&auto_repeat_timer);
}
}
rep = set_bit(keycode, key_down);
rep = test_and_set_bit(keycode, key_down);
}
if(raw_mode)
......
......@@ -687,7 +687,7 @@ static void do_softint(void *private_)
if (!tty)
return;
if (clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
tty->ldisc.write_wakeup)
(tty->ldisc.write_wakeup)(tty);
......
......@@ -254,7 +254,6 @@ typedef unsigned int u32;
#include <linux/time.h>
#include <linux/blk.h>
#include <linux/init.h>
#undef current
#include "scsi.h"
#include "hosts.h"
......@@ -783,7 +782,7 @@ NCR53c7x0_driver_init (struct Scsi_Host *host) {
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
host->hostdata;
int i, j;
u32 *current;
u32 *curr;
for (i = 0; i < 16; ++i) {
hostdata->request_sense[i] = 0;
for (j = 0; j < 8; ++j)
......@@ -792,14 +791,14 @@ NCR53c7x0_driver_init (struct Scsi_Host *host) {
}
hostdata->issue_queue = NULL;
hostdata->running_list = hostdata->finished_queue =
hostdata->current = NULL;
for (i = 0, current = (u32 *) hostdata->schedule;
i < host->can_queue; ++i, current += 2) {
current[0] = hostdata->NOP_insn;
current[1] = 0xdeadbeef;
hostdata->curr = NULL;
for (i = 0, curr = (u32 *) hostdata->schedule;
i < host->can_queue; ++i, curr += 2) {
curr[0] = hostdata->NOP_insn;
curr[1] = 0xdeadbeef;
}
current[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24) | DBC_TCI_TRUE;
current[1] = (u32) virt_to_bus (hostdata->script) +
curr[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24) | DBC_TCI_TRUE;
curr[1] = (u32) virt_to_bus (hostdata->script) +
hostdata->E_wait_reselect;
hostdata->reconnect_dsa_head = 0;
hostdata->addr_reconnect_dsa_head = (u32)
......@@ -2104,7 +2103,7 @@ abnormal_finished (struct NCR53c7x0_cmd *cmd, int result) {
int left, found;
volatile struct NCR53c7x0_cmd * linux_search;
volatile struct NCR53c7x0_cmd * volatile *linux_prev;
volatile u32 *ncr_prev, *current, ncr_search;
volatile u32 *ncr_prev, *curr, ncr_search;
#if 0
printk ("scsi%d: abnormal finished\n", host->host_no);
......@@ -2120,13 +2119,13 @@ abnormal_finished (struct NCR53c7x0_cmd *cmd, int result) {
*/
for (found = 0, left = host->can_queue, current = hostdata->schedule;
left > 0; --left, current += 2)
for (found = 0, left = host->can_queue, curr = hostdata->schedule;
left > 0; --left, curr += 2)
{
if (issue_to_cmd (host, hostdata, (u32 *) current) == cmd)
if (issue_to_cmd (host, hostdata, (u32 *) curr) == cmd)
{
current[0] = hostdata->NOP_insn;
current[1] = 0xdeadbeef;
curr[0] = hostdata->NOP_insn;
curr[1] = 0xdeadbeef;
++found;
break;
}
......@@ -3964,7 +3963,7 @@ to_schedule_list (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
Scsi_Cmnd *tmp = cmd->cmd;
unsigned long flags;
/* dsa start is negative, so subtraction is used */
volatile u32 *current;
volatile u32 *curr;
int i;
NCR53c7x0_local_setup(host);
......@@ -3991,9 +3990,9 @@ to_schedule_list (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
return;
}
for (i = host->can_queue, current = hostdata->schedule;
i > 0 && current[0] != hostdata->NOP_insn;
--i, current += 2 /* JUMP instructions are two words */);
for (i = host->can_queue, curr = hostdata->schedule;
i > 0 && curr[0] != hostdata->NOP_insn;
--i, curr += 2 /* JUMP instructions are two words */);
if (i > 0) {
++hostdata->busy[tmp->target][tmp->lun];
......@@ -4002,13 +4001,13 @@ to_schedule_list (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
/* Restore this instruction to a NOP once the command starts */
cmd->dsa [(hostdata->dsa_jump_dest - hostdata->dsa_start) /
sizeof(u32)] = (u32) virt_to_bus ((void *)current);
sizeof(u32)] = (u32) virt_to_bus ((void *)curr);
/* Replace the current jump operand. */
current[1] =
curr[1] =
virt_to_bus ((void *) cmd->dsa) + hostdata->E_dsa_code_begin -
hostdata->E_dsa_code_template;
/* Replace the NOP instruction with a JUMP */
current[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24) |
curr[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24) |
DBC_TCI_TRUE;
} else {
printk ("scsi%d: no free slot\n", host->host_no);
......@@ -4510,8 +4509,8 @@ NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs) {
/*
* NCR53c700 and NCR53c700-66 change the current SCSI
* process, hostdata->current, in the Linux driver so
* cmd = hostdata->current.
* process, hostdata->curr, in the Linux driver so
* cmd = hostdata->curr.
*
* With other chips, we must look through the commands
* executing and find the command structure which
......@@ -4519,7 +4518,7 @@ NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs) {
*/
if (hostdata->options & OPTION_700) {
cmd = (struct NCR53c7x0_cmd *) hostdata->current;
cmd = (struct NCR53c7x0_cmd *) hostdata->curr;
} else {
dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG));
for (cmd = (struct NCR53c7x0_cmd *)
......@@ -5872,7 +5871,7 @@ print_queues (struct Scsi_Host *host) {
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
host->hostdata;
u32 *dsa, *next_dsa;
volatile u32 *current;
volatile u32 *curr;
int left;
Scsi_Cmnd *cmd, *next_cmd;
unsigned long flags;
......@@ -5914,11 +5913,11 @@ print_queues (struct Scsi_Host *host) {
*/
printk ("scsi%d : schedule dsa array :\n", host->host_no);
for (left = host->can_queue, current = hostdata->schedule;
left > 0; current += 2, --left)
if (current[0] != hostdata->NOP_insn)
for (left = host->can_queue, curr = hostdata->schedule;
left > 0; curr += 2, --left)
if (curr[0] != hostdata->NOP_insn)
/* FIXME : convert pointer to dsa_begin to pointer to dsa. */
print_dsa (host, bus_to_virt (current[1] -
print_dsa (host, bus_to_virt (curr[1] -
(hostdata->E_dsa_code_begin -
hostdata->E_dsa_code_template)), "");
printk ("scsi%d : end schedule dsa array\n", host->host_no);
......@@ -6108,7 +6107,7 @@ return_outstanding_commands (struct Scsi_Host *host, int free, int issue) {
host->hostdata;
struct NCR53c7x0_cmd *c;
int i;
u32 *current;
u32 *curr;
Scsi_Cmnd *list = NULL, *tmp;
for (c = (struct NCR53c7x0_cmd *) hostdata->running_list; c;
c = (struct NCR53c7x0_cmd *) c->next) {
......@@ -6129,12 +6128,12 @@ return_outstanding_commands (struct Scsi_Host *host, int free, int issue) {
}
if (free) {
for (i = 0, current = (u32 *) hostdata->schedule;
i < host->can_queue; ++i, current += 2) {
current[0] = hostdata->NOP_insn;
current[1] = 0xdeadbeef;
for (i = 0, curr = (u32 *) hostdata->schedule;
i < host->can_queue; ++i, curr += 2) {
curr[0] = hostdata->NOP_insn;
curr[1] = 0xdeadbeef;
}
hostdata->current = NULL;
hostdata->curr = NULL;
}
if (issue) {
......
......@@ -1394,7 +1394,7 @@ struct NCR53c7x0_hostdata {
/* commands running, maintained
by Linux driver */
volatile struct NCR53c7x0_cmd *current; /* currently connected
volatile struct NCR53c7x0_cmd *curr; /* currently connected
nexus, ONLY valid for
NCR53c700/NCR53c700-66
*/
......
Sun May 11 22:30 1997 Gerard Roudier (groudier@club-internet.fr)
* revision 2.1b
- Cosmetic changes.
- Some heavy testings under pre-linux-2.1.37-6
Sun May 4 22:30 1997 Gerard Roudier (groudier@club-internet.fr)
* revision 2.1a
- PFEN wrongly used for PREFETCH feature bit testing.
Changed to _F_PFEN.
- 2 SCR_COPY that need NO FLUSH bit to be removed had been missed
in tp->getscr[] script (loads SXFER and SCNTL3 on reselection).
Sat May 3 22:30 1997 Gerard Roudier (groudier@club-internet.fr)
* revision 2.1
- Use the NO FLUSH option for MOVE MEMORY (COPY) each time it is
possible. More than 100 COPY with NO FLUSH and 6 with FLUSH for
my configuration (max queued command / device = 8).
This option bit is removed from the script instance for chips
that donnot support prefetching.
- Rewrite the ncr_exception() routine more simple (I think) and
remove useless code.
- Change the data_in and data_out script management.
Use the bottom part of these scripts instead of the beginning.
That avoids to zero the scatter/gather array when a command is
queued (1k) and to deal with some weird IID on MOVE 0 bytes when
a target wants to transfer more bytes than expected.
- Misc. improvements in the init code.
- Remove IOMAPPED/MMIO automatic switching option.
Was useless and reported not reliable.
- Fix a double read of DSTAT and remove DFE testing in the
Phase mismatch service routine.
- Etc...
Fri Apr 26 20:00 1997 Gerard Roudier (groudier@club-internet.fr)
* revision 2.0a
- Add support if the Diamond FirePort 40 (SYM53C875J chip)
Mon Apr 22 22:00 1997 Gerard Roudier (groudier@club-internet.fr)
* revision 2.0
- incorporate __initdata and __initfunc directives in order to
allow 'init' to free unused memory after driver initialisations.
Patch sent by Roberto Fichera.
- rewrite the init code of the driver. Now a feature descriptor
is used for each real chip types. The code is a lot more clean,
since the driver uses device and revision ids only in the
detection procedure.
- add 'pcifix' boot command line. This command allows to fix up PCI
config space for new chips which support features based on the
cache line size and 'write and invalidate'.
- incorporate in the driver, the code used for error recovery
testing. This code is normally not compiled; have to define
SCSI_NCR_DEBUG_ERROR_RECOVERY in order to compile it.
- take into account actual SCSI bus mode for 53C895 LVD/SE controller.
In single ended mode only fast20 is supported.
(Just to not be late since such controllers are not yet available)
Sat Apr 20 21:00 1997 Gerard Roudier (groudier@club-internet.fr)
* revision 1.18f
- fix an old bug included in the initial port (version 0.0).
The driver allocated 10 bytes of static data and uses 12 bytes.
No danger, since data are generally aligned on 4 bytes boundary
and so byte 10 and 11 are free (I hope ...)
Wed Apr 16 12:00 1997 Gerard Roudier (groudier@club-internet.fr)
* revision 1.18e
- reset all when an unexpected data cycle is detected while
disconnecting.
- make changes to abort() ans reset() functions according to
Leonard's documentation.
- small fix in some message for hard errors.
Sat Apr 5 13:00 1997 Gerard Roudier (groudier@club-internet.fr)
* revision 1.18d
- Probe NCR pci device ids in reverse order if asked by user from
......
The linux NCR53C8XX driver README file
The Linux NCR53C8XX driver README file
Written by Gerard Roudier <groudier@club-internet.fr>
21 Rue Carnot
95170 DEUIL LA BARRE - FRANCE
6 April 1997
9 May 1997
===============================================================================
1. Introduction
......@@ -22,6 +22,7 @@ Written by Gerard Roudier <groudier@club-internet.fr>
8.5 Set debug mode
8.6 Clear profile counters
8.7 Set flag (no_sync)
8.8 Debug error recovery
9. Configuration parameters
10. Boot setup commands
10.1 Syntax
......@@ -203,7 +204,6 @@ General information:
IO port address 0x6000, IRQ number 10
Using memory mapped IO at virtual address 0x282c000
Synchronous transfer period 25, max commands per lun 4
Profiling information:
num_trans = 18014
num_kbytes = 671314
......@@ -390,6 +390,57 @@ Available commands:
- setflag all
will allow disconnection for all devices on the SCSI bus.
8.8 Debug error recovery
debug_error_recovery <error to trigger>
Available error type to trigger:
sge: SCSI gross error
abort: abort command from the middle-level driver
reset: reset command from the middle-level driver
parity: scsi parity detected in DATA IN phase
none: restore driver normal behaviour
The code corresponding to this feature is normally not compiled.
Its purpose is driver testing only. In order to compile the code
that allows to trigger error recovery you must define at compile time
SCSI_NCR_DEBUG_ERROR_RECOVERY.
If you have compiled the driver with this option, nothing will happen
as long as you donnot use the control command 'debug_error_recovery'
with sge, abort, reset or parity as argument.
If you select an error type, it will be triggered by the driver every
30 seconds.
8.9 PCI configuration fix-up
pcifix <option bits>
Available option bits:
0x1: Set PCI cache-line size register if not set.
0x2: Set write and invalidate bit in PCI command register.
Use 'pcifix:3' in order to allow the driver to fix both PCI features.
These options only apply to new SYMBIOS chips 810A, 825A, 860 and 875
and are only supported for Pentium and 486 class processors.
Recent SYMBIOS 53C8XX scsi processors are able to use PCI read multiple
and PCI write and invalidate commands. These features require the
cache line size register to be properly set in the PCI configuration
space of the chips. On the other hand, chips will use PCI write and
invalidate commands only if the corresponding bit is set to 1 in the
PCI command register.
Not all PCI bioses set the PCI cache line register and the PCI write and
invalidate bit in the PCI configuration space of 53C8XX chips.
Optimized PCI accesses may be broken for some PCI/memory controllers or
make problems with some PCI boards.
This fix-up works flawlessly on my system.
(MB Triton HX / 53C875 / 53C810A)
I use these options at my own risks as you will do if you decide to
use them too.
9. Configuration parameters
If the firmware of all your devices is perfect enough, all the
......@@ -736,9 +787,9 @@ Driver and common files:
You must untar the distribution with the following command:
tar zxvf ncrBsd2Linux-1.18d-src.tar.gz
tar zxvf ncrBsd2Linux-2.1b-src.tar.gz
The sub-directory ncr53c8xx-1.18d will be created. Change to this directory.
The sub-directory ncr53c8xx-2.1b will be created. Change to this directory.
12.2 Installation procedure
......
......@@ -242,7 +242,7 @@ static void idescsi_pc_intr (ide_drive_t *drive)
printk (KERN_INFO "ide-scsi: Reached idescsi_pc_intr interrupt handler\n");
#endif /* IDESCSI_DEBUG_LOG */
if (clear_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
if (test_and_clear_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
#if IDESCSI_DEBUG_LOG
printk ("ide-scsi: %s: DMA complete\n", drive->name);
#endif /* IDESCSI_DEBUG_LOG */
......
This diff is collapsed.
This diff is collapsed.
......@@ -11,6 +11,9 @@
*
* generic command parser provided by:
* Andreas Heilwagen <crashcar@informatik.uni-koblenz.de>
*
* generic_proc_info() support of xxxx_info() by:
* Michael A. Griffith <grif@acm.org>
*/
/*
......@@ -48,7 +51,9 @@ struct scsi_dir {
* Used if the driver currently has no own support for /proc/scsi
*/
int generic_proc_info(char *buffer, char **start, off_t offset,
int length, int inode, int inout)
int length, int inode, int inout,
const char *(*info)(struct Scsi_Host *),
struct Scsi_Host *sh)
{
int len, pos, begin;
......@@ -56,8 +61,13 @@ int generic_proc_info(char *buffer, char **start, off_t offset,
return(-ENOSYS); /* This is a no-op */
begin = 0;
pos = len = sprintf(buffer,
"The driver does not yet support the proc-fs\n");
if (info && sh) {
pos = len = sprintf(buffer, "%s\n", info(sh));
}
else {
pos = len = sprintf(buffer,
"The driver does not yet support the proc-fs\n");
}
if(pos < offset) {
len = 0;
begin = pos;
......@@ -91,7 +101,9 @@ extern int dispatch_scsi_info(int ino, char *buffer, char **start,
if (ino == (hpnt->host_no + PROC_SCSI_FILE)) {
if(hpnt->hostt->proc_info == NULL)
return generic_proc_info(buffer, start, offset, length,
hpnt->host_no, func);
hpnt->host_no, func,
hpnt->hostt->info,
hpnt);
else
return(hpnt->hostt->proc_info(buffer, start, offset,
length, hpnt->host_no, func));
......
......@@ -564,36 +564,6 @@ const char *seagate_st0x_info (struct Scsi_Host *shpnt)
return buffer;
}
int seagate_st0x_proc_info (char *buffer, char **start, off_t offset,
int length, int hostno, int inout)
{
const char *info = seagate_st0x_info (NULL);
int len;
int pos;
int begin;
if (inout)
return (-ENOSYS);
begin = 0;
strcpy (buffer, info);
strcat (buffer, "\n");
pos = len = strlen (buffer);
if (pos < offset)
{
len = 0;
begin = pos;
}
*start = buffer + (offset - begin);
len -= (offset - begin);
if (len > length)
len = length;
return (len);
}
/*
* These are our saved pointers for the outstanding command that is
* waiting for a reconnect
......
......@@ -19,7 +19,6 @@ int seagate_st0x_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int seagate_st0x_abort(Scsi_Cmnd *);
const char *seagate_st0x_info(struct Scsi_Host *);
int seagate_st0x_reset(Scsi_Cmnd *, unsigned int);
int seagate_st0x_proc_info(char *,char **,off_t,int,int,int);
#ifndef NULL
#define NULL 0
......@@ -28,7 +27,7 @@ int seagate_st0x_proc_info(char *,char **,off_t,int,int,int);
#include <linux/kdev_t.h>
int seagate_st0x_biosparam(Disk *, kdev_t, int*);
#define SEAGATE_ST0X { NULL, NULL, NULL, seagate_st0x_proc_info, \
#define SEAGATE_ST0X { NULL, NULL, NULL, NULL, \
NULL, seagate_st0x_detect, \
NULL, \
seagate_st0x_info, seagate_st0x_command, \
......
......@@ -86,7 +86,7 @@ affs_free_block(struct super_block *sb, s32 block)
return;
}
}
if (set_bit(bit ^ BO_EXBITS,bm->bm_bh->b_data + 4))
if (test_and_set_bit(bit ^ BO_EXBITS,bm->bm_bh->b_data + 4))
affs_warning(sb,"affs_free_block","Trying to free block %d which is already free",
block);
else {
......@@ -138,7 +138,7 @@ affs_balloc(struct inode *inode, int zone_no)
zone->z_start = i;
w = ~htonl(bm[i]);
fb = find_first_zero_bit(&w,32);
if (fb > 31 || !clear_bit(fb ^ BO_EXBITS,&bm[i])) {
if (fb > 31 || !test_and_clear_bit(fb ^ BO_EXBITS,&bm[i])) {
unlock_super(sb);
affs_warning(sb,"balloc","Empty block disappeared somehow");
goto repeat;
......@@ -153,7 +153,7 @@ affs_balloc(struct inode *inode, int zone_no)
fb = find_next_zero_bit(&w,32,fb);
if (fb > 31)
break;
if (!clear_bit(fb ^ BO_EXBITS,&bm[i])) {
if (!test_and_clear_bit(fb ^ BO_EXBITS,&bm[i])) {
affs_warning(sb,"balloc","Empty block disappeared somehow");
break;
}
......
......@@ -1159,7 +1159,8 @@ static int elf_core_dump(long signr, struct pt_regs * regs)
set_fs(fs);
len = current->mm->arg_end - current->mm->arg_start;
len = len >= ELF_PRARGSZ ? ELF_PRARGSZ : len;
if (len >= ELF_PRARGSZ)
len = ELF_PRARGSZ-1;
copy_from_user(&psinfo.pr_psargs,
(const char *)current->mm->arg_start, len);
for(i = 0; i < len; i++)
......
......@@ -138,13 +138,7 @@ static int parse_options(char *options, struct iso9660_options * popt)
!strcmp(this_char,"uid") ||
!strcmp(this_char,"gid"))) {
char * vpnt = value;
unsigned int ivalue;
ivalue = 0;
while(*vpnt){
if(*vpnt < '0' || *vpnt > '9') break;
ivalue = ivalue * 10 + (*vpnt - '0');
vpnt++;
}
unsigned int ivalue = simple_strtoul(vpnt, &vpnt, 0);
if (*vpnt) return 0;
switch(*this_char) {
case 'b':
......
......@@ -100,6 +100,9 @@
*
* Some adaptations for NFS support.
* Olaf Kirch (okir@monad.swb.de), Dec 1996,
*
* Fixed /proc/locks interface so that we can't overrun the buffer we are handed.
* Andy Walker (andy@lysaker.kvaerner.no), May 12, 1997.
*/
#include <linux/malloc.h>
......@@ -132,7 +135,7 @@ static int posix_locks_deadlock(struct file_lock *caller,
static struct file_lock *locks_alloc_lock(struct file_lock *fl);
static void locks_insert_lock(struct file_lock **pos, struct file_lock *fl);
static void locks_delete_lock(struct file_lock **thisfl_p, unsigned int wait);
static char *lock_get_status(struct file_lock *fl, char *p, int id, char *pfx);
static char *lock_get_status(struct file_lock *fl, int id, char *pfx);
static void locks_insert_block(struct file_lock *blocker, struct file_lock *waiter);
static void locks_delete_block(struct file_lock *blocker, struct file_lock *waiter);
......@@ -227,6 +230,7 @@ void
posix_block_lock(struct file_lock *blocker, struct file_lock *waiter)
{
locks_insert_block(blocker, waiter);
return;
}
void
......@@ -234,6 +238,7 @@ posix_unblock_lock(struct file_lock *waiter)
{
if (waiter->fl_prevblock)
locks_delete_block(waiter->fl_prevblock, waiter);
return;
}
/* Wake up processes blocked waiting for blocker.
......@@ -269,20 +274,20 @@ asmlinkage int sys_flock(unsigned int fd, unsigned int cmd)
{
struct file_lock file_lock;
struct file *filp;
int err;
int error;
lock_kernel();
if ((fd >= NR_OPEN) || !(filp = current->files->fd[fd]))
err = -EBADF;
error = -EBADF;
else if (!flock_make_lock(filp, &file_lock, cmd))
err = -EINVAL;
error = -EINVAL;
else if ((file_lock.fl_type != F_UNLCK) && !(filp->f_mode & 3))
err = -EBADF;
error = -EBADF;
else
err = flock_lock_file(filp, &file_lock,
(cmd & (LOCK_UN | LOCK_NB)) ? 0 : 1);
error = flock_lock_file(filp, &file_lock,
(cmd & (LOCK_UN | LOCK_NB)) ? 0 : 1);
unlock_kernel();
return err;
return (error);
}
/* Report the first existing lock that would conflict with l.
......@@ -298,7 +303,7 @@ int fcntl_getlk(unsigned int fd, struct flock *l)
if ((fd >= NR_OPEN) || !(filp = current->files->fd[fd]))
return (-EBADF);
if (copy_from_user(&flock, l, sizeof(flock)))
return -EFAULT;
return (-EFAULT);
if ((flock.l_type != F_RDLCK) && (flock.l_type != F_WRLCK))
return (-EINVAL);
......@@ -308,9 +313,9 @@ int fcntl_getlk(unsigned int fd, struct flock *l)
if (filp->f_op->lock) {
error = filp->f_op->lock(filp->f_inode, filp,
F_GETLK, &file_lock);
F_GETLK, &file_lock);
if (error < 0)
return error;
return (error);
fl = &file_lock;
} else {
fl = posix_test_lock(filp, &file_lock);
......@@ -323,12 +328,12 @@ int fcntl_getlk(unsigned int fd, struct flock *l)
fl->fl_end - fl->fl_start + 1;
flock.l_whence = 0;
flock.l_type = fl->fl_type;
return copy_to_user(l, &flock, sizeof(flock)) ? -EFAULT : 0;
return (copy_to_user(l, &flock, sizeof(flock)) ? -EFAULT : 0);
} else {
flock.l_type = F_UNLCK;
}
return copy_to_user(l, &flock, sizeof(flock)) ? -EFAULT : 0;
return (copy_to_user(l, &flock, sizeof(flock)) ? -EFAULT : 0);
}
/* Apply the lock described by l to an open file descriptor.
......@@ -366,7 +371,7 @@ int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l)
}
if (copy_from_user(&flock, l, sizeof(flock)))
return -EFAULT;
return (-EFAULT);
if (!posix_make_lock(filp, &file_lock, &flock))
return (-EINVAL);
......@@ -399,13 +404,13 @@ int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l)
break;
#endif
default:
return -EINVAL;
return (-EINVAL);
}
if (filp->f_op->lock != NULL) {
error = filp->f_op->lock(filp->f_inode, filp, cmd, &file_lock);
if (error < 0)
return error;
return (error);
}
return (posix_lock_file(filp, &file_lock, cmd == F_SETLKW));
......@@ -457,7 +462,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
break;
}
return cfl;
return (cfl);
}
int locks_verify_locked(struct inode *inode)
......@@ -1044,16 +1049,18 @@ static void locks_delete_lock(struct file_lock **thisfl_p, unsigned int wait)
}
static char *lock_get_status(struct file_lock *fl, char *p, int id, char *pfx)
static char *lock_get_status(struct file_lock *fl, int id, char *pfx)
{
static char temp[129];
char *p = temp;
struct inode *inode;
inode = fl->fl_file->f_inode;
p += sprintf(p, "%d:%s ", id, pfx);
if (fl->fl_flags & FL_POSIX) {
p += sprintf(p, "%s %s ",
(fl->fl_flags & FL_ACCESS) ? "ACCESS" : "POSIX",
p += sprintf(p, "%6s %s ",
(fl->fl_flags & FL_ACCESS) ? "ACCESS" : "POSIX ",
(IS_MANDLOCK(inode) &&
(inode->i_mode & (S_IXGRP | S_ISGID)) == S_ISGID) ?
"MANDATORY" : "ADVISORY ");
......@@ -1066,28 +1073,68 @@ static char *lock_get_status(struct file_lock *fl, char *p, int id, char *pfx)
fl->fl_pid,
kdevname(inode->i_dev), inode->i_ino, fl->fl_start,
fl->fl_end);
p += sprintf(p, "%08lx %08lx %08lx %08lx %08lx\n",
(long)fl, (long)fl->fl_prevlink, (long)fl->fl_nextlink,
(long)fl->fl_next, (long)fl->fl_nextblock);
return (p);
sprintf(p, "%08lx %08lx %08lx %08lx %08lx\n",
(long)fl, (long)fl->fl_prevlink, (long)fl->fl_nextlink,
(long)fl->fl_next, (long)fl->fl_nextblock);
return (temp);
}
int get_locks_status(char *buf)
static inline int copy_lock_status(char *p, char **q, off_t pos, int len,
off_t offset, int length)
{
int i;
i = pos - offset;
if (i > 0) {
if (i >= length) {
i = len + length - i;
memcpy(*q, p, i);
*q += i;
return (0);
}
if (i < len) {
p += len - i;
}
else
i = len;
memcpy(*q, p, i);
*q += i;
}
return (1);
}
int get_locks_status(char *buffer, char **start, off_t offset, int length)
{
struct file_lock *fl;
struct file_lock *bfl;
char *p;
char *q = buffer;
int i;
int len;
off_t pos = 0;
p = buf;
for (fl = file_lock_table, i = 1; fl != NULL; fl = fl->fl_nextlink, i++) {
p = lock_get_status(fl, p, i, "");
p = lock_get_status(fl, i, "");
len = strlen(p);
pos += len;
if (!copy_lock_status(p, &q, pos, len, offset, length))
goto done;
if ((bfl = fl->fl_nextblock) == NULL)
continue;
do {
p = lock_get_status(bfl, p, i, " ->");
p = lock_get_status(bfl, i, " ->");
len = strlen(p);
pos += len;
if (!copy_lock_status(p, &q, pos, len, offset, length))
goto done;
} while ((bfl = bfl->fl_nextblock) != fl);
}
return (p - buf);
done:
if (q != buffer)
*start = buffer;
return (q - buffer);
}
......@@ -130,9 +130,9 @@ nfs_unlock_page(struct page *page)
#ifdef CONFIG_NFS_SWAP
/* async swap-out support */
if (clear_bit(PG_decr_after, &page->flags))
if (test_and_clear_bit(PG_decr_after, &page->flags))
atomic_dec(&page->count);
if (clear_bit(PG_swap_unlock_after, &page->flags))
if (test_and_clear_bit(PG_swap_unlock_after, &page->flags))
swap_after_unlock_page(page->swap_unlock_entry);
#endif
}
......
......@@ -1019,7 +1019,7 @@ extern int get_cpuinfo(char *);
extern int get_pci_list(char*);
extern int get_md_status (char *);
extern int get_rtc_status (char *);
extern int get_locks_status (char *);
extern int get_locks_status (char *, char **, off_t, int);
extern int get_swaparea_info (char *);
#ifdef __SMP_PROF__
extern int get_smp_prof_list(char *);
......@@ -1106,7 +1106,7 @@ static long get_root_array(char * page, int type, char **start,
return get_rtc_status(page);
#endif
case PROC_LOCKS:
return get_locks_status(page);
return get_locks_status(page, start, offset, length);
#ifdef CONFIG_ZORRO
case PROC_ZORRO:
return zorro_get_list(page);
......
......@@ -285,10 +285,10 @@ int mem_mmap(struct inode * inode, struct file * file,
return -ENOMEM;
if (!pte_present(*src_table))
do_no_page(tsk, src_vma, stmp, 1);
handle_mm_fault(src_vma, stmp, 1);
if ((vma->vm_flags & VM_WRITE) && !pte_write(*src_table))
do_wp_page(tsk, src_vma, stmp, 1);
handle_mm_fault(src_vma, stmp, 1);
set_pte(src_table, pte_mkdirty(*src_table));
set_pte(dest_table, *src_table);
......
......@@ -108,7 +108,7 @@ static inline void spin_lock(spinlock_t * lock)
lock->previous = (unsigned long) &&l1;
}
#define spin_trylock(lock) (!set_bit(0,(lock)))
#define spin_trylock(lock) (!test_and_set_bit(0,(lock)))
#define spin_lock_irq(lock) \
do { __cli(); spin_lock(lock); } while (0)
......
......@@ -58,7 +58,6 @@ static inline int hardirq_trylock(int cpu)
return 0;
}
++local_irq_count[cpu];
__sti();
return 1;
}
......
......@@ -81,48 +81,28 @@ static inline int waking_non_zero(struct semaphore *sem)
* "down_failed" is a special asm handler that calls the C
* routine that actually waits. See arch/i386/lib/semaphore.S
*/
extern inline void down(struct semaphore * sem)
extern inline void do_down(struct semaphore * sem, void (*failed)(void))
{
__asm__ __volatile__(
"# atomic down operation\n\t"
"movl $1f,%%eax\n\t"
#ifdef __SMP__
"lock ; "
#endif
"decl 0(%0)\n\t"
"js " SYMBOL_NAME_STR(__down_failed)
"\n1:"
"js 2f\n"
"1:\n"
".section .text.lock,\"ax\"\n"
"2:\tpushl $1b\n\t"
"jmp %1\n"
".previous"
:/* no outputs */
:"c" (sem)
:"ax","memory");
}
/*
* This version waits in interruptible state so that the waiting
* process can be killed. The down_failed_interruptible routine
* returns negative for signalled and zero for semaphore acquired.
*/
extern inline int down_interruptible(struct semaphore * sem)
{
int ret;
__asm__ __volatile__(
"# atomic interruptible down operation\n\t"
"movl $1f,%0\n\t"
#ifdef __SMP__
"lock ; "
#endif
"decl 0(%1)\n\t"
"js " SYMBOL_NAME_STR(__down_failed_interruptible) "\n\t"
"xorl %0,%0"
"\n1:"
:"=a" (ret)
:"c" (sem)
:"c" (sem), "m" (*(unsigned long *)failed)
:"memory");
return ret;
}
#define down(sem) do_down((sem),__down_failed)
#define down_interruptible(sem) do_down((sem),__down_failed_interruptible)
/*
* Note! This is subtle. We jump to wake people up only if
* the semaphore was negative (== somebody was waiting on it).
......@@ -133,16 +113,19 @@ extern inline void up(struct semaphore * sem)
{
__asm__ __volatile__(
"# atomic up operation\n\t"
"movl $1f,%%eax\n\t"
#ifdef __SMP__
"lock ; "
#endif
"incl 0(%0)\n\t"
"jle " SYMBOL_NAME_STR(__up_wakeup)
"\n1:"
"jle 2f\n"
"1:\n"
".section .text.lock,\"ax\"\n"
"2:\tpushl $1b\n\t"
"jmp %1\n"
".previous"
:/* no outputs */
:"c" (sem)
:"ax", "memory");
:"c" (sem), "m" (*(unsigned long *)__up_wakeup)
:"memory");
}
#endif
......@@ -93,7 +93,7 @@ __asm__ __volatile__( \
"lock ; btrl $0,%0" \
:"=m" (__dummy_lock(lock)))
#define spin_trylock(lock) (!set_bit(0,(lock)))
#define spin_trylock(lock) (!test_and_set_bit(0,(lock)))
#define spin_lock_irq(lock) \
do { __cli(); spin_lock(lock); } while (0)
......
......@@ -261,8 +261,6 @@ extern int zeromap_page_range(unsigned long from, unsigned long size, pgprot_t p
extern void vmtruncate(struct inode * inode, unsigned long offset);
extern void handle_mm_fault(struct vm_area_struct *vma, unsigned long address, int write_access);
extern void do_wp_page(struct task_struct * tsk, struct vm_area_struct * vma, unsigned long address, int write_access);
extern void do_no_page(struct task_struct * tsk, struct vm_area_struct * vma, unsigned long address, int write_access);
extern unsigned long paging_init(unsigned long start_mem, unsigned long end_mem);
extern void mem_init(unsigned long start_mem, unsigned long end_mem);
......
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