Commit c72adc34 authored by Linus Torvalds's avatar Linus Torvalds

Import pre2.0.9

parent 309bcdbf
......@@ -55,7 +55,6 @@ This table is current to Linux 1.3.98.
Ioctl Include File Comments
========================================================
0x00 linux/fs.h only FIBMAP, FIGETBSZ
0x00 linux/mc146818rtc.h conflict!
0x02 linux/fd.h
0x03 linux/hdreg.h
0x04 linux/umsdos_fs.h
......@@ -90,6 +89,7 @@ Ioctl Include File Comments
'm' linux/mtio.h conflict!
'm' linux/soundcard.h conflict!
'n' linux/ncp_fs.h
'p' linux/mc146818rtc.h
'r' linux/msdos_fs.h
's' linux/cdk.h
't' linux/if_ppp.h no conflict
......
......@@ -68,6 +68,12 @@ S: Status, one of the following:
it has been replaced by a better system and you
should be using that.
EXT2 FILE SYSTEM
P: Remy Card
M: Remy.Card@linux.org
L: linux-kernel@vger.rutgers.edu
S: Maintained
3C501 NETWORK DRIVER
P: Alan Cox
M: net-patches@lxorguk.ukuu.org.uk
......
VERSION = 1
PATCHLEVEL = 99
SUBLEVEL = 8
SUBLEVEL = 9
ARCH = i386
......
......@@ -10,6 +10,8 @@
* 1995-03-26 Markus Kuhn
* fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887
* precision CMOS clock update
* 1996-05-03 Ingo Molnar
* fixed time warps in do_[slow|fast]_gettimeoffset()
*/
#include <linux/errno.h>
#include <linux/sched.h>
......@@ -31,57 +33,102 @@ extern int setup_x86_irq(int, struct irqaction *);
#ifndef CONFIG_APM /* cycle counter may be unreliable */
/* Cycle counter value at the previous timer interrupt.. */
static unsigned long long last_timer_cc = 0;
static unsigned long long init_timer_cc = 0;
static struct {
unsigned long low;
unsigned long high;
} init_timer_cc, last_timer_cc;
/*
* This is more assembly than C, but it's also rather
* timing-critical and we have to use assembler to get
* reasonable 64-bit arithmetic
*/
static unsigned long do_fast_gettimeoffset(void)
{
unsigned long time_low, time_high;
unsigned long quotient, remainder;
/* Get last timer tick in absolute kernel time */
__asm__("subl %2,%0\n\t"
"sbbl %3,%1"
:"=r" (time_low), "=r" (time_high)
:"m" (*(0+(long *)&init_timer_cc)),
"m" (*(1+(long *)&init_timer_cc)),
"0" (*(0+(long *)&last_timer_cc)),
"1" (*(1+(long *)&last_timer_cc)));
/*
* Divide the 64-bit time with the 32-bit jiffy counter,
* getting the quotient in clocks.
*
* Giving quotient = "average internal clocks per jiffy"
*/
__asm__("divl %2"
:"=a" (quotient), "=d" (remainder)
:"r" (jiffies),
"0" (time_low), "1" (time_high));
register unsigned long eax asm("ax");
register unsigned long edx asm("dx");
unsigned long tmp, quotient, low_timer, missing_time;
/* Last jiffie when do_fast_gettimeoffset() was called.. */
static unsigned long last_jiffies=0;
/* Cached "clocks per usec" value.. */
static unsigned long cached_quotient=0;
/* The "clocks per usec" value is calculated once each jiffie */
tmp = jiffies;
quotient = cached_quotient;
low_timer = last_timer_cc.low;
missing_time = 0;
if (last_jiffies != tmp) {
last_jiffies = tmp;
/*
* test for hanging bottom handler (this means xtime is not
* updated yet)
*/
if (test_bit(TIMER_BH, &bh_active) )
{
missing_time = 997670/HZ;
}
/* Get last timer tick in absolute kernel time */
eax = low_timer;
edx = last_timer_cc.high;
__asm__("subl "SYMBOL_NAME_STR(init_timer_cc)",%0\n\t"
"sbbl "SYMBOL_NAME_STR(init_timer_cc)"+4,%1"
:"=a" (eax), "=d" (edx)
:"0" (eax), "1" (edx));
/*
* Divide the 64-bit time with the 32-bit jiffy counter,
* getting the quotient in clocks.
*
* Giving quotient = "average internal clocks per usec"
*/
__asm__("divl %2"
:"=a" (eax), "=d" (edx)
:"r" (tmp),
"0" (eax), "1" (edx));
edx = 997670/HZ;
tmp = eax;
eax = 0;
__asm__("divl %2"
:"=a" (eax), "=d" (edx)
:"r" (tmp),
"0" (eax), "1" (edx));
cached_quotient = eax;
quotient = eax;
}
/* Read the time counter */
__asm__(".byte 0x0f,0x31"
:"=a" (time_low), "=d" (time_high));
:"=a" (eax), "=d" (edx));
/* .. relative to previous jiffy (32 bits is enough) */
time_low -= (unsigned long) last_timer_cc;
edx = 0;
eax -= low_timer;
/*
* Time offset = (1000000/HZ * remainder) / quotient.
* Time offset = (997670/HZ * time_low) / quotient.
*/
__asm__("mull %1\n\t"
"divl %2"
:"=a" (quotient), "=d" (remainder)
__asm__("mull %2"
:"=a" (eax), "=d" (edx)
:"r" (quotient),
"0" (time_low), "1" (1000000/HZ));
"0" (eax), "1" (edx));
/*
* Due to rounding errors (and jiffies inconsistencies),
* Due to rounding errors (and jiffies inconsistencies),
* we need to check the result so that we'll get a timer
* that is monotonous.
*/
if (quotient >= 1000000/HZ)
quotient = 1000000/HZ-1;
return quotient;
if (edx >= 997670/HZ)
edx = 997670/HZ-1;
eax = edx + missing_time;
return eax;
}
#endif
......@@ -122,21 +169,63 @@ static unsigned long do_fast_gettimeoffset(void)
static unsigned long do_slow_gettimeoffset(void)
{
int count;
static int count_p = 0;
unsigned long offset = 0;
static unsigned long jiffies_p = 0;
/*
* cache volatile jiffies temporaly, we have IRQs turned off.
*/
unsigned long jiffies_t;
/* timer count may underflow right here */
outb_p(0x00, 0x43); /* latch the count ASAP */
count = inb_p(0x40); /* read the latched count */
count |= inb(0x40) << 8;
/* we know probability of underflow is always MUCH less than 1% */
if (count > (LATCH - LATCH/100)) {
/* check for pending timer interrupt */
outb_p(0x0a, 0x20);
if (inb(0x20) & 1)
offset = TICK_SIZE;
}
jiffies_t = jiffies;
/*
* avoiding timer inconsistencies (they are rare, but they happen)...
* there are three kinds of problems that must be avoided here:
* 1. the timer counter underflows
* 2. hardware problem with the timer, not giving us continuous time,
* the counter does small "jumps" upwards on some Pentium systems,
* thus causes time warps
* 3. we are after the timer interrupt, but the bottom half handler
* hasn't executed yet.
*/
if( count > count_p ) {
if( jiffies_t == jiffies_p ) {
if( count > LATCH-LATCH/100 )
offset = TICK_SIZE;
else
/*
* argh, the timer is bugging we cant do nothing
* but to give the previous clock value.
*/
count = count_p;
} else {
if( test_bit(TIMER_BH, &bh_active) ) {
/*
* we have detected a counter underflow.
*/
offset = TICK_SIZE;
count_p = count;
} else {
count_p = count;
jiffies_p = jiffies_t;
}
}
} else {
count_p = count;
jiffies_p = jiffies_t;
}
count = ((LATCH-1) - count) * TICK_SIZE;
count = (count + LATCH/2) / LATCH;
return offset + count;
}
......@@ -283,8 +372,8 @@ static void pentium_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
/* read Pentium cycle counter */
__asm__(".byte 0x0f,0x31"
:"=a" (((unsigned long *) &last_timer_cc)[0]),
"=d" (((unsigned long *) &last_timer_cc)[1]));
:"=a" (last_timer_cc.low),
"=d" (last_timer_cc.high));
timer_interrupt(irq, NULL, regs);
}
#endif
......@@ -375,8 +464,8 @@ void time_init(void)
do_gettimeoffset = do_fast_gettimeoffset;
/* read Pentium cycle counter */
__asm__(".byte 0x0f,0x31"
:"=a" (((unsigned long *) &init_timer_cc)[0]),
"=d" (((unsigned long *) &init_timer_cc)[1]));
:"=a" (init_timer_cc.low),
"=d" (init_timer_cc.high));
irq0.handler = pentium_timer_interrupt;
}
#endif
......
......@@ -40,7 +40,7 @@ main(int argc, char *argv[])
}
if ((out_fd = creat(argv[2], 0666)) < 0)
{
fprintf(stderr, "Can't create outpue file: '%s': %s\n", argv[2], strerror(errno));
fprintf(stderr, "Can't create output file: '%s': %s\n", argv[2], strerror(errno));
exit(2);
}
if (fstat(in_fd, &info) < 0)
......@@ -185,7 +185,7 @@ write_prep_boot_partition(int out_fd)
* the next two.
* - size of the diskette is (assumed to be)
* (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette)
* - unlike the above sector nunbers, the beginning sector is zero-based!
* - unlike the above sector numbers, the beginning sector is zero-based!
*/
#if 0
pe->beginning_sector = LeDword(1);
......
......@@ -9,7 +9,7 @@ Wed Mar 8 18:14:37 1995 Michael Meissner <meissner@tiktok.cygnus.com>
Tue Feb 14 13:59:13 1995 Michael Meissner <meissner@tiktok.cygnus.com>
* common.h (EM_PPC): Use offical value of 20, not 17.
* common.h (EM_PPC): Use official value of 20, not 17.
(EM_PPC_OLD): Define this to be the old value of EM_PPC.
......@@ -108,7 +108,7 @@ Thu Apr 29 12:12:20 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
* common.h (EM_HPPA, NT_VERSION, STN_UNDEF, DT_*): New macros.
* external.h (Elf_External_Dyn): New type.
* internal.h (Elf_Intenral_Shdr): New field `size'.
* internal.h (Elf_Internal_Shdr): New field `size'.
(Elf_Internal_Dyn): New type.
Tue Apr 20 16:03:45 1993 Fred Fish (fnf@cygnus.com)
......
......@@ -10,7 +10,7 @@
#define MSR_TGPR (1<<17) /* TLB Update registers in use */
#define MSR_ILE (1<<16) /* Interrupt Little-Endian enable */
#define MSR_EE (1<<15) /* External Interrupt enable */
#define MSR_PR (1<<14) /* Supervisor/User privelege */
#define MSR_PR (1<<14) /* Supervisor/User privilege */
#define MSR_FP (1<<13) /* Floating Point enable */
#define MSR_ME (1<<12) /* Machine Check enable */
#define MSR_FE0 (1<<11) /* Floating Exception mode 0 */
......
......@@ -2,7 +2,7 @@
* linux/arch/ppc/kernel/process.c
*
* Copyright (C) 1995 Linus Torvalds
* Adapted for PowerPC by Gary THomas
* Adapted for PowerPC by Gary Thomas
*/
/*
......
/*
* Miscallaneous support routines
* Miscellaneous support routines
*/
#include <asm/bitops.h>
......
......@@ -19,7 +19,7 @@
/*
* sys_pipe() is the normal C calling standard for creating
* a pipe. It's not the way unix tranditionally does this, though.
* a pipe. It's not the way unix traditionally does this, though.
*/
asmlinkage int sys_pipe(unsigned long * fildes)
{
......
......@@ -30,11 +30,10 @@
*
*/
#define RTC_VERSION "1.06"
#define RTC_VERSION "1.07"
#define RTC_IRQ 8 /* Can't see this changing soon. */
#define RTC_IO_BASE 0x70 /* Or this... */
#define RTC_IO_EXTENT 0x10 /* Only really 0x70 to 0x71, but... */
#define RTC_IO_EXTENT 0x10 /* Only really two ports, but... */
/*
* Note that *all* calls to CMOS_READ and CMOS_WRITE are done with
......@@ -539,7 +538,7 @@ int rtc_init(void)
}
misc_register(&rtc_dev);
/* Check region? Naaah! Just snarf it up. */
request_region(RTC_IO_BASE, RTC_IO_EXTENT, "rtc");
request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc");
init_timer(&rtc_irq_timer);
rtc_irq_timer.function = rtc_dropped_irq;
rtc_wait = NULL;
......
/* $Id: eexpress.c,v 1.12 1996/04/15 17:27:30 phil Exp $
/* $Id: eexpress.c,v 1.13 1996/05/19 15:59:51 phil Exp $
*
* Intel EtherExpress device driver for Linux
*
......@@ -86,7 +86,7 @@
static char version[] =
"eexpress.c: v0.10 04-May-95 John Sullivan <js10039@cam.ac.uk>\n"
" v0.13 10-Apr-96 Philip Blundell <phil@tazenda.demon.co.uk>\n";
" v0.14 19-May-96 Philip Blundell <phil@tazenda.demon.co.uk>\n";
#include <linux/module.h>
......@@ -103,6 +103,7 @@ static char version[] =
#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
......@@ -1060,15 +1061,25 @@ static void eexp_hw_init586(struct device *dev)
printk("%s: eexp_hw_init586()\n", dev->name);
#endif
PRIV(dev)->started = 0;
lp->started = 0;
set_loopback;
outb(SIRQ_dis|irqrmap[dev->irq],ioaddr+SET_IRQ);
outb_p(i586_RST,ioaddr+EEPROM_Ctrl);
udelay(2000); /* delay 20ms */
{
unsigned short ofs, i;
for (ofs = 0; ofs < lp->rx_buf_end; ofs += 32) {
outw_p(ofs, ioaddr+SM_PTR);
for (i = 0; i < 16; i++) {
outw_p(0, ioaddr+SM_ADDR(i<<1));
}
}
}
outw_p(lp->rx_buf_end,ioaddr+WRITE_PTR);
start_code[28] = (dev->flags & IFF_PROMISC)?(start_code[28] | 1):(start_code[28] & ~1);
PRIV(dev)->promisc = dev->flags & IFF_PROMISC;
lp->promisc = dev->flags & IFF_PROMISC;
/* We may die here */
outsw(ioaddr, start_code, sizeof(start_code)>>1);
outw(CONF_HW_ADDR,ioaddr+WRITE_PTR);
......@@ -1205,8 +1216,8 @@ static char namelist[NAMELEN * EEXP_MAX_CARDS] = { 0, };
static struct device dev_eexp[EEXP_MAX_CARDS] =
{
NULL, /* will allocate dynamically */
0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, express_probe
{ NULL, /* will allocate dynamically */
0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, express_probe },
};
int irq[EEXP_MAX_CARDS] = {0, };
......
......@@ -229,6 +229,12 @@ static int ne_probe1(struct device *dev, int ioaddr)
}
}
/* We should have a "dev" from Space.c or the static module table. */
if (dev == NULL) {
printk(KERN_ERR "ne.c: Passed a NULL device.\n");
dev = init_etherdev(0, 0);
}
if (ei_debug && version_printed++ == 0)
printk(version);
......@@ -346,12 +352,6 @@ static int ne_probe1(struct device *dev, int ioaddr)
}
/* We should have a "dev" from Space.c or the static module table. */
if (dev == NULL) {
printk("ne.c: Passed a NULL device.\n");
dev = init_etherdev(0, 0);
}
if (pci_irq_line) {
dev->irq = pci_irq_line;
}
......
......@@ -6,7 +6,7 @@
* Dynamic PPP devices by Jim Freeman <jfree@caldera.com>.
* ppp_tty_receive ``noisy-raise-bug'' fixed by Ove Ewerlid <ewerlid@syscon.uu.se>
*
* ==FILEVERSION 960303==
* ==FILEVERSION 960528==
*
* NOTE TO MAINTAINERS:
* If you modify this file at all, please set the number above to the
......
......@@ -580,7 +580,7 @@ int scan_scsis_single (int channel, int dev, int lun, int *max_dev_lun,
printk("\n");
#endif
if (host_byte(SCpnt->result) != DID_OK) {
if (SCpnt->result) {
if (((driver_byte (SCpnt->result) & DRIVER_SENSE) ||
(status_byte (SCpnt->result) & CHECK_CONDITION)) &&
((SCpnt->sense_buffer[0] & 0x70) >> 4) == 7) {
......@@ -1569,9 +1569,15 @@ static void scsi_done (Scsi_Cmnd * SCpnt)
case SUGGEST_IS_OK:
break;
case SUGGEST_REMAP:
#ifdef DEBUG
printk("SENSE SUGGEST REMAP - status = FINISHED\n");
#endif
status = FINISHED;
exit = DRIVER_SENSE | SUGGEST_ABORT;
break;
case SUGGEST_RETRY:
#ifdef DEBUG
printk("SENSE SUGGEST REMAP or SUGGEST RETRY - status = MAYREDO\n");
printk("SENSE SUGGEST RETRY - status = MAYREDO\n");
#endif
status = MAYREDO;
exit = DRIVER_SENSE | SUGGEST_RETRY;
......@@ -1606,6 +1612,9 @@ static void scsi_done (Scsi_Cmnd * SCpnt)
status = REDO;
break;
case SUGGEST_REMAP:
status = FINISHED;
exit = DRIVER_SENSE | SUGGEST_ABORT;
break;
case SUGGEST_RETRY:
status = MAYREDO;
exit = DRIVER_SENSE | SUGGEST_RETRY;
......
......@@ -150,7 +150,7 @@ 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)
if (!SCpnt->device->was_reset && SCpnt->device->scsi_request_fn)
(*SCpnt->device->scsi_request_fn)();
wake_up(&SCpnt->device->device_wait);
......
......@@ -6,7 +6,7 @@
* convert numbers according to section 7.3.3, etc.
*
* isofs special functions. This file was lifted in its entirety from
* the bsd386 iso9660 filesystem, by Pace Williamson.
* the 386bsd iso9660 filesystem, by Pace Willisson <pace@blitz.com>.
*/
int
......
......@@ -476,8 +476,12 @@ static int nfs_mkdir(struct inode *dir, const char *name, int len, int mode)
sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1;
error = nfs_proc_mkdir(NFS_SERVER(dir), NFS_FH(dir),
name, &sattr, &fhandle, &fattr);
if (!error)
nfs_lookup_cache_add(dir, name, &fhandle, &fattr);
if (!error) {
if (fattr.fileid == dir->i_ino)
printk("Sony NewsOS 4.1R buggy nfs server?\n");
else
nfs_lookup_cache_add(dir, name, &fhandle, &fattr);
}
iput(dir);
return error;
}
......
......@@ -100,7 +100,7 @@ asmlinkage int sys_llseek(unsigned int fd, unsigned long offset_high,
return 0;
}
asmlinkage int sys_read(unsigned int fd,char * buf,unsigned int count)
asmlinkage int sys_read(unsigned int fd,char * buf,int count)
{
int error;
struct file * file;
......@@ -112,7 +112,7 @@ asmlinkage int sys_read(unsigned int fd,char * buf,unsigned int count)
return -EBADF;
if (!file->f_op || !file->f_op->read)
return -EINVAL;
if (!count)
if (count <= 0)
return 0;
error = locks_verify_area(FLOCK_VERIFY_READ,inode,file,file->f_pos,count);
if (error)
......
......@@ -31,7 +31,7 @@ extern __inline__ unsigned long set_bit(unsigned long nr, void * addr)
:"=&r" (temp),
"=m" (*m),
"=&r" (oldbit)
:"r" (1UL << (nr & 31)),
:"Ir" (1UL << (nr & 31)),
"m" (*m));
return oldbit != 0;
}
......@@ -54,7 +54,7 @@ extern __inline__ unsigned long clear_bit(unsigned long nr, void * addr)
:"=&r" (temp),
"=m" (*m),
"=&r" (oldbit)
:"r" (1UL << (nr & 31)),
:"Ir" (1UL << (nr & 31)),
"m" (*m));
return oldbit != 0;
}
......@@ -75,7 +75,7 @@ extern __inline__ unsigned long change_bit(unsigned long nr, void * addr)
:"=&r" (temp),
"=m" (*m),
"=&r" (oldbit)
:"r" (1UL << (nr & 31)),
:"Ir" (1UL << (nr & 31)),
"m" (*m));
return oldbit != 0;
}
......
......@@ -46,7 +46,7 @@ static inline unsigned short ip_fast_csum(unsigned char * iph,
unsigned int ihl) {
unsigned int sum;
__asm__("
__asm__ __volatile__("
movl (%1), %0
subl $4, %2
jbe 2f
......
......@@ -199,18 +199,21 @@ static inline unsigned long __xchg(unsigned long x, void * ptr, int size)
switch (size) {
case 1:
__asm__("xchgb %b0,%1"
:"=&q" (x), "=m" (*__xg(ptr))
:"0" (x), "m" (*__xg(ptr)));
:"=q" (x)
:"m" (*__xg(ptr)), "0" (x)
:"memory");
break;
case 2:
__asm__("xchgw %w0,%1"
:"=&r" (x), "=m" (*__xg(ptr))
:"0" (x), "m" (*__xg(ptr)));
:"=r" (x)
:"m" (*__xg(ptr)), "0" (x)
:"memory");
break;
case 4:
__asm__("xchgl %0,%1"
:"=&r" (x), "=m" (*__xg(ptr))
:"0" (x), "m" (*__xg(ptr)));
:"=r" (x)
:"m" (*__xg(ptr)), "0" (x)
:"memory");
break;
}
return x;
......
#ifndef _PPC_POSIX_TYPES_H
#define _PPc_POSIX_TYPES_H
#define _PPC_POSIX_TYPES_H
/*
* This file is generally used by user-level software, so you need to
......@@ -95,4 +95,4 @@ static __inline__ void __FD_ZERO(__kernel_fd_set *p)
#endif /* __GNUC__ */
#endif /* _PPc_POSIX_TYPES_H */
#endif /* _PPC_POSIX_TYPES_H */
......@@ -107,25 +107,7 @@ outb_p((val),RTC_PORT(1)); \
#endif
/*
* ioctl calls that are permitted to the /dev/rtc interface, if
* CONFIG_RTC was enabled.
*/
#define RTC_AIE_ON 0x01 /* Alarm int. enable on */
#define RTC_AIE_OFF 0x02 /* ... off */
#define RTC_UIE_ON 0x03 /* Update int. enable on */
#define RTC_UIE_OFF 0x04 /* ... off */
#define RTC_PIE_ON 0x05 /* Periodic int. enable on */
#define RTC_PIE_OFF 0x06 /* ... off */
#define RTC_ALM_SET 0x07 /* Set alarm (struct tm) */
#define RTC_ALM_READ 0x08 /* Read alarm (struct tm) */
#define RTC_RD_TIME 0x09 /* Read RTC time (struct tm) */
#define RTC_SET_TIME 0x0a /* Set time of RTC (not used) */
#define RTC_IRQP_READ 0x0b /* Read periodic IRQ rate (Hz) */
#define RTC_IRQP_SET 0x0c /* Set periodic IRQ rate (Hz) */
/*
* The struct used to pass data via the above ioctl. Similar to the
* The struct used to pass data via the following ioctl. Similar to the
* struct tm in <time.h>, but it needs to be here so that the kernel
* source is self contained, allowing cross-compiles, etc. etc.
*/
......@@ -142,4 +124,24 @@ struct rtc_time {
int tm_isdst;
};
/*
* ioctl calls that are permitted to the /dev/rtc interface, if
* CONFIG_RTC was enabled.
*/
#define RTC_AIE_ON _IO('p', 0x01) /* Alarm int. enable on */
#define RTC_AIE_OFF _IO('p', 0x02) /* ... off */
#define RTC_UIE_ON _IO('p', 0x03) /* Update int. enable on */
#define RTC_UIE_OFF _IO('p', 0x04) /* ... off */
#define RTC_PIE_ON _IO('p', 0x05) /* Periodic int. enable on */
#define RTC_PIE_OFF _IO('p', 0x06) /* ... off */
#define RTC_ALM_SET _IOW('p', 0x07, struct rtc_time) /* Set alarm time */
#define RTC_ALM_READ _IOR('p', 0x08, struct rtc_time) /* Read alarm time */
#define RTC_RD_TIME _IOR('p', 0x09, struct rtc_time) /* Read RTC time */
#define RTC_SET_TIME _IOW('p', 0x0a, struct rtc_time) /* Set RTC time */
#define RTC_IRQP_READ _IOR('p', 0x0b, unsigned long) /* Read IRQ rate */
#define RTC_IRQP_SET _IOW('p', 0x0c, unsigned long) /* Set IRQ rate */
#endif /* _MC146818RTC_H */
......@@ -163,7 +163,6 @@ struct symbol_table symbol_table = {
X(__bforget),
X(ll_rw_block),
X(__wait_on_buffer),
X(__wait_on_page),
X(mark_buffer_uptodate),
X(unlock_buffer),
X(dcache_lookup),
......
This diff is collapsed.
......@@ -171,6 +171,38 @@ struct size_descriptor sizes[] =
#define BLOCKSIZE(order) (blocksize[order])
#define AREASIZE(order) (PAGE_SIZE<<(sizes[order].gfporder))
/*
* Create a small cache of page allocations: this helps a bit with
* those pesky 8kB+ allocations for NFS when we're temporarily
* out of memory..
*
* This is a _truly_ small cache, we just cache one single page
* order (for orders 0, 1 and 2, that is 4, 8 and 16kB on x86).
*/
#define MAX_CACHE_ORDER 3
struct page_descriptor * kmalloc_cache[MAX_CACHE_ORDER];
static inline struct page_descriptor * get_kmalloc_pages(unsigned long priority,
unsigned long order, int dma)
{
struct page_descriptor * tmp;
tmp = (struct page_descriptor *) __get_free_pages(priority, order, dma);
if (!tmp && !dma && order < MAX_CACHE_ORDER)
tmp = xchg(kmalloc_cache+order, tmp);
return tmp;
}
static inline void free_kmalloc_pages(struct page_descriptor * page,
unsigned long order, int dma)
{
if (!dma && order < MAX_CACHE_ORDER) {
page = xchg(kmalloc_cache+order, page);
if (!page)
return;
}
free_pages((unsigned long) page, order);
}
long kmalloc_init(long start_mem, long end_mem)
{
......@@ -260,8 +292,7 @@ void *kmalloc(size_t size, int priority)
/* sz is the size of the blocks we're dealing with */
sz = BLOCKSIZE(order);
page = (struct page_descriptor *) __get_free_pages(priority,
sizes[order].gfporder, dma);
page = get_kmalloc_pages(priority, sizes[order].gfporder, dma);
if (!page)
goto no_free_page;
......@@ -322,7 +353,7 @@ void *kmalloc(size_t size, int priority)
void kfree(void *ptr)
{
int size;
int size, dma;
unsigned long flags;
int order;
register struct block_header *p;
......@@ -331,10 +362,12 @@ void kfree(void *ptr)
if (!ptr)
return;
p = ((struct block_header *) ptr) - 1;
dma = 0;
page = PAGE_DESC(p);
order = page->order;
pg = &sizes[order].firstfree;
if (p->bh_flags == MF_DMA) {
dma = 1;
p->bh_flags = MF_USED;
pg = &sizes[order].dmafree;
}
......@@ -378,7 +411,7 @@ void kfree(void *ptr)
pg = &tmp->next;
}
sizes[order].npages--;
free_pages((long) page, sizes[order].gfporder);
free_kmalloc_pages(page, sizes[order].gfporder, dma);
}
sizes[order].nfrees++;
sizes[order].nbytesmalloced -= size;
......
......@@ -76,10 +76,10 @@ void rw_swap_page(int rw, unsigned long entry, char * buf, int wait)
else
kstat.pswpout++;
page = mem_map + MAP_NR(buf);
atomic_inc(&page->count);
wait_on_page(page);
if (p->swap_device) {
if (!wait) {
page->count++;
set_bit(PG_free_after, &page->flags);
set_bit(PG_decr_after, &page->flags);
set_bit(PG_swap_unlock_after, &page->flags);
......@@ -87,6 +87,11 @@ void rw_swap_page(int rw, unsigned long entry, char * buf, int wait)
nr_async_pages++;
}
ll_rw_page(rw,p->swap_device,offset,buf);
/*
* NOTE! We don't decrement the page count if we
* don't wait - that will happen asynchronously
* when the IO completes.
*/
if (!wait)
return;
wait_on_page(page);
......@@ -130,6 +135,7 @@ void rw_swap_page(int rw, unsigned long entry, char * buf, int wait)
ll_rw_swap_file(rw,swapf->i_dev, zones, i,buf);
} else
printk("rw_swap_page: no swap file or device\n");
atomic_dec(&page->count);
if (offset && !clear_bit(offset,p->swap_lockmap))
printk("rw_swap_page: lock already cleared\n");
wake_up(&lock_queue);
......
......@@ -318,12 +318,13 @@ asmlinkage int sys_swapoff(const char * specialfile)
struct inode * inode;
struct file filp;
int i, type, prev;
int err;
if (!suser())
return -EPERM;
i = namei(specialfile,&inode);
if (i)
return i;
err = namei(specialfile,&inode);
if (err)
return err;
prev = -1;
for (type = swap_list.head; type >= 0; type = swap_info[type].next) {
p = swap_info + type;
......@@ -353,13 +354,21 @@ asmlinkage int sys_swapoff(const char * specialfile)
swap_list.next = swap_list.head;
}
p->flags = SWP_USED;
i = try_to_unuse(type);
if (i) {
err = try_to_unuse(type);
if (err) {
iput(inode);
/* re-insert swap space back into swap_list */
for (prev = -1, i = swap_list.head; i >= 0; prev = i, i = swap_info[i].next)
if (p->prio >= swap_info[i].prio)
break;
p->next = i;
if (prev < 0)
swap_list.head = swap_list.next = p - swap_info;
else
swap_info[prev].next = p - swap_info;
p->flags = SWP_WRITEOK;
return i;
return err;
}
if(p->swap_device){
memset(&filp, 0, sizeof(filp));
filp.f_inode = inode;
......
......@@ -541,7 +541,13 @@ int ip_fw_chk(struct iphdr *ip, struct device *rif, __u16 *redirport, struct ip_
#ifdef CONFIG_IP_TRANSPARENT_PROXY
if (policy&IP_FW_F_REDIR) {
if (redirport)
*redirport = htons(f->fw_pts[f->fw_nsp+f->fw_ndp]);
if ((*redirport = htons(f->fw_pts[f->fw_nsp+f->fw_ndp])) == 0) {
/* Wildcard redirection.
* Note that redirport will become
* 0xFFFF for non-TCP/UDP packets.
*/
*redirport = dst_port;
}
answer = FW_REDIRECT;
} else
#endif
......
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