Commit b5a22d4d authored by Linus Torvalds's avatar Linus Torvalds

Import 2.1.110

parent 756b5aab
......@@ -787,6 +787,13 @@ S: Alleenstrasse 27
S: D-71679 Asperg
S: Germany
N: Kenn Humborg
E: kenn@wombat.ie
D: Mods to loop device to support sparse backing files
S: Ballinagard
S: Roscommon
S: Ireland
N: Miguel de Icaza Amozurrutia
E: miguel@nuclecu.unam.mx
D: Linux/SPARC team, Midnight Commander maintainer
......
......@@ -64,7 +64,7 @@ EXPORT_SYMBOL(_writew);
EXPORT_SYMBOL(_writel);
EXPORT_SYMBOL(_memcpy_fromio);
EXPORT_SYMBOL(_memcpy_toio);
EXPORT_SYMBOL(_memset_io);
EXPORT_SYMBOL(_memset_c_io);
EXPORT_SYMBOL(insb);
EXPORT_SYMBOL(insw);
EXPORT_SYMBOL(insl);
......@@ -87,6 +87,7 @@ EXPORT_SYMBOL(memcmp);
EXPORT_SYMBOL(memmove);
EXPORT_SYMBOL(__memcpy);
EXPORT_SYMBOL(__memset);
EXPORT_SYMBOL(__memsetw);
EXPORT_SYMBOL(__constant_c_memset);
EXPORT_SYMBOL(dump_thread);
......
......@@ -13,7 +13,7 @@
#include <asm/ptrace.h>
#include <asm/system.h>
#include <asm/io.h>
##include <asm/smp.h>
#include <asm/smp.h>
/*
* BIOS32-style PCI interface:
......
......@@ -86,6 +86,7 @@
#include "irq.h"
#undef DEBUG
#define DEBUG
#ifdef DEBUG
#define DBG(x...) printk(x)
......
......@@ -75,6 +75,7 @@ flags = 4
sigpending = 8
addr_limit = 12
exec_domain = 16
need_resched = 20
ENOSYS = 38
......@@ -178,7 +179,7 @@ ret_from_sys_call:
andl SYMBOL_NAME(bh_active),%eax
jne handle_bottom_half
ret_with_reschedule:
cmpl $0,SYMBOL_NAME(need_resched)
cmpl $0,need_resched(%ebx)
jne reschedule
cmpl $0,sigpending(%ebx)
jne signal_return
......
......@@ -32,7 +32,7 @@
* volatile is justified in this case, it might change
* spontaneously, GCC should not cache it
*/
#define IO_APIC_BASE ((volatile int *)0xfec00000)
#define IO_APIC_BASE ((volatile int *)fix_to_virt(FIX_IO_APIC_BASE))
enum mp_irq_source_types {
mp_INT = 0,
......
......@@ -114,6 +114,9 @@
Only manipulate interrupt enable flag on local CPU.
Allow enclosed uncachable regions.
v1.21
19980611 Richard Gooch <rgooch@atnf.csiro.au>
Always define <main_lock>.
v1.22
*/
#include <linux/types.h>
#include <linux/errno.h>
......@@ -147,7 +150,7 @@
#include <asm/atomic.h>
#include <linux/smp.h>
#define MTRR_VERSION "1.21 (19980521)"
#define MTRR_VERSION "1.22 (19980611)"
#define TRUE 1
#define FALSE 0
......@@ -199,9 +202,7 @@ static char *ascii_buffer = NULL;
static unsigned int ascii_buf_bytes = 0;
#endif
static unsigned int *usage_table = NULL;
#ifdef __SMP__
static spinlock_t main_lock = SPIN_LOCK_UNLOCKED;
#endif
/* Private functions */
#ifdef CONFIG_PROC_FS
......
......@@ -77,7 +77,7 @@ void enable_hlt(void)
static void hard_idle(void)
{
while (!need_resched) {
while (!current->need_resched) {
if (boot_cpu_data.hlt_works_ok && !hlt_counter) {
#ifdef CONFIG_APM
/* If the APM BIOS is not enabled, or there
......@@ -86,14 +86,14 @@ static void hard_idle(void)
need_resched again because an interrupt
may have occurred in apm_do_idle(). */
start_bh_atomic();
if (!apm_do_idle() && !need_resched)
if (!apm_do_idle() && !current->need_resched)
__asm__("hlt");
end_bh_atomic();
#else
__asm__("hlt");
#endif
}
if (need_resched)
if (current->need_resched)
break;
schedule();
}
......@@ -130,11 +130,11 @@ asmlinkage int sys_idle(void)
if (jiffies - start_idle > HARD_IDLE_TIMEOUT)
hard_idle();
else {
if (boot_cpu_data.hlt_works_ok && !hlt_counter && !need_resched)
if (boot_cpu_data.hlt_works_ok && !hlt_counter && !current->need_resched)
__asm__("hlt");
}
run_task_queue(&tq_scheduler);
if (need_resched)
if (current->need_resched)
start_idle = 0;
schedule();
}
......@@ -156,7 +156,7 @@ int cpu_idle(void *unused)
while(1)
{
if(current_cpu_data.hlt_works_ok &&
!hlt_counter && !need_resched)
!hlt_counter && !current->need_resched)
__asm("hlt");
check_pgt_cache();
/*
......@@ -410,6 +410,8 @@ void machine_power_off(void)
void show_regs(struct pt_regs * regs)
{
long cr0 = 0L, cr2 = 0L, cr3 = 0L;
printk("\n");
printk("EIP: %04x:[<%08lx>]",0xffff & regs->xcs,regs->eip);
if (regs->xcs & 3)
......@@ -421,6 +423,10 @@ void show_regs(struct pt_regs * regs)
regs->esi, regs->edi, regs->ebp);
printk(" DS: %04x ES: %04x\n",
0xffff & regs->xds,0xffff & regs->xes);
__asm__("movl %%cr0, %0": "=r" (cr0));
__asm__("movl %%cr2, %0": "=r" (cr2));
__asm__("movl %%cr3, %0": "=r" (cr3));
printk("CR0: %08lx CR2: %08lx CR3: %08lx\n", cr0, cr2, cr3);
}
/*
......@@ -506,7 +512,7 @@ void flush_thread(void)
int i;
for (i=0 ; i<8 ; i++)
current->debugreg[i] = 0;
current->tss.debugreg[i] = 0;
/*
* Forget coprocessor state..
......@@ -655,7 +661,7 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
dump->u_dsize -= dump->u_tsize;
dump->u_ssize = 0;
for (i = 0; i < 8; i++)
dump->u_debugreg[i] = current->debugreg[i];
dump->u_debugreg[i] = current->tss.debugreg[i];
if (dump->start_stack < TASK_SIZE)
dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
......@@ -687,7 +693,7 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
#define loaddebug(tsk,register) \
__asm__("movl %0,%%db" #register \
: /* no output */ \
:"r" (tsk->debugreg[register]))
:"r" (tsk->tss.debugreg[register]))
/*
......@@ -755,7 +761,7 @@ void __switch_to(struct task_struct *prev, struct task_struct *next)
/*
* Now maybe reload the debug registers
*/
if (next->debugreg[7]){
if (next->tss.debugreg[7]){
loaddebug(next,0);
loaddebug(next,1);
loaddebug(next,2);
......
......@@ -443,7 +443,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
addr <= (long) &dummy->u_debugreg[7]){
addr -= (long) &dummy->u_debugreg[0];
addr = addr >> 2;
tmp = child->debugreg[addr];
tmp = child->tss.debugreg[addr];
};
ret = put_user(tmp,(unsigned long *) data);
goto out;
......@@ -489,7 +489,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
addr -= (long) &dummy->u_debugreg;
addr = addr >> 2;
child->debugreg[addr] = data;
child->tss.debugreg[addr] = data;
ret = 0;
goto out;
};
......
......@@ -649,6 +649,35 @@ __initfunc(void enable_local_APIC(void))
udelay(100);
}
__initfunc(unsigned long init_smp_mappings(unsigned long memory_start))
{
unsigned long apic_phys, ioapic_phys;
if (smp_found_config) {
apic_phys = mp_lapic_addr;
ioapic_phys = mp_ioapic_addr;
} else {
/*
* set up a fake all zeroes page to simulate the
* local APIC and another one for the IO-APIC. We
* could use the real zero-page, but it's safer
* this way if some buggy code writes to this page ...
*/
apic_phys = __pa(memory_start);
ioapic_phys = __pa(memory_start+PAGE_SIZE);
memset((void *)memory_start, 0, 2*PAGE_SIZE);
memory_start += 2*PAGE_SIZE;
}
set_fixmap(FIX_APIC_BASE,apic_phys);
set_fixmap(FIX_IO_APIC_BASE,ioapic_phys);
printk("mapped APIC to %08lx (%08lx)\n", APIC_BASE, apic_phys);
printk("mapped IOAPIC to %08lx (%08lx)\n", fix_to_virt(FIX_IO_APIC_BASE), ioapic_phys);
return memory_start;
}
__initfunc(void smp_callin(void))
{
extern void calibrate_delay(void);
......@@ -684,7 +713,7 @@ __initfunc(void smp_callin(void))
set_bit(cpuid, (unsigned long *)&cpu_callin_map[0]);
}
static int cpucount = 0;
int cpucount = 0;
extern int cpu_idle(void * unused);
......@@ -1125,10 +1154,6 @@ __initfunc(void smp_boot_cpus(void))
setup_IO_APIC();
smp_done:
#ifdef CONFIG_MTRR
/* Must be done after other processors booted */
mtrr_init ();
#endif
}
......@@ -1174,6 +1199,18 @@ void send_IPI (int dest, int vector)
* enabled in a civilised fashion. That will also boost performance.
*/
unsigned int TIME64 (void)
{
unsigned int dummy,low;
__asm__("rdtsc"
:"=a" (low),
"=d" (dummy));
return low;
}
int ipi_timestamp;
void smp_message_pass(int target, int msg, unsigned long data, int wait)
{
unsigned long cfg;
......@@ -1277,7 +1314,11 @@ void smp_message_pass(int target, int msg, unsigned long data, int wait)
cpu_callin_map[0]=0;
}
else
panic("huh?");
{
dest=0;
target_map=(1<<target);
cpu_callin_map[0]=0;
}
/*
* Program the APIC to deliver the IPI
......@@ -1376,6 +1417,17 @@ void smp_flush_tlb(void)
/* printk("SMID\n");*/
}
void smp_send_reschedule(int cpu)
{
unsigned long flags;
__save_flags(flags);
__cli();
smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 2);
__restore_flags(flags);
}
/*
* Local timer interrupt handler. It does both profiling and
* process statistics/rescheduling.
......@@ -1422,7 +1474,7 @@ void smp_local_timer_interrupt(struct pt_regs * regs)
p->counter -= 1;
if (p->counter < 0) {
p->counter = 0;
need_resched = 1;
p->need_resched = 1;
}
if (p->priority < DEF_PRIORITY) {
kstat.cpu_nice += user;
......@@ -1476,21 +1528,11 @@ void smp_apic_timer_interrupt(struct pt_regs * regs)
}
/*
* Reschedule call back (not used currently)
* Reschedule call back
*/
asmlinkage void smp_reschedule_interrupt(void)
{
int cpu = smp_processor_id();
ack_APIC_irq();
/*
* This looks silly, but we actually do need to wait
* for the global interrupt lock.
*/
irq_enter(cpu, 0);
need_resched = 1;
irq_exit(cpu, 0);
}
/*
......
......@@ -558,7 +558,7 @@ asmlinkage void math_emulate(long arg)
RE_ENTRANT_CHECK_ON;
#endif DEBUG
if (FPU_lookahead && !need_resched)
if (FPU_lookahead && !current->need_resched)
{
FPU_ORIG_EIP = FPU_EIP - code_base;
if ( valid_prefix(&byte1, (u_char **)&FPU_EIP,
......
......@@ -27,8 +27,10 @@
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/dma.h>
#include <asm/fixmap.h>
extern void show_net_buffers(void);
extern unsigned long init_smp_mappings(unsigned long);
void __bad_pte_kernel(pmd_t *pmd)
{
......@@ -190,6 +192,50 @@ static inline void set_in_cr4(unsigned long mask)
:"ax");
}
/*
* allocate page table(s) for compile-time fixed mappings
*/
static unsigned long fixmap_init (unsigned long start_mem)
{
pgd_t * pg_dir;
unsigned int idx;
unsigned long address;
start_mem &= PAGE_MASK;
for (idx=1; idx < __end_of_fixed_addresses; idx += PTRS_PER_PTE)
{
address = fix_to_virt(__end_of_fixed_addresses-idx);
pg_dir = swapper_pg_dir + (address >> PGDIR_SHIFT);
memset((void *)start_mem, 0, PAGE_SIZE);
pgd_val(*pg_dir) = _PAGE_TABLE | __pa(start_mem);
start_mem += PAGE_SIZE;
}
return start_mem;
}
static void set_pte_phys (unsigned long vaddr, unsigned long phys)
{
pgprot_t prot;
pte_t * pte;
pte = pte_offset(pmd_offset(pgd_offset_k(vaddr), vaddr), vaddr);
prot = PAGE_KERNEL;
if (boot_cpu_data.x86_capability & X86_FEATURE_PGE)
pgprot_val(prot) |= _PAGE_GLOBAL;
set_pte(pte, mk_pte_phys(phys, prot));
local_flush_tlb();
}
void set_fixmap (enum fixed_addresses idx, unsigned long phys)
{
unsigned long address = fix_to_virt(idx);
set_pte_phys (address,phys);
}
/*
* paging_init() sets up the page tables - note that the first 4MB are
* already mapped by head.S.
......@@ -293,60 +339,9 @@ __initfunc(unsigned long paging_init(unsigned long start_mem, unsigned long end_
address += PAGE_SIZE;
}
}
start_mem = fixmap_init(start_mem);
#ifdef __SMP__
{
extern unsigned long mp_lapic_addr;
extern unsigned long mp_ioapic_addr;
pte_t pte;
unsigned long apic_area = (unsigned long)APIC_BASE;
pg_dir = swapper_pg_dir + ((apic_area) >> PGDIR_SHIFT);
memset((void *)start_mem, 0, PAGE_SIZE);
pgd_val(*pg_dir) = _PAGE_TABLE | __pa(start_mem);
start_mem += PAGE_SIZE;
if (smp_found_config) {
/*
* Map the local APIC to FEE00000. (it's only the default
* value, thanks to Steve Hsieh for finding this out. We
* now save the real local-APIC physical address in smp_scan(),
* and use it here)
*/
pg_table = pte_offset((pmd_t *)pg_dir, apic_area);
pte = mk_pte_phys(mp_lapic_addr, PAGE_KERNEL);
set_pte(pg_table, pte);
/*
* Map the IO-APIC to FEC00000.
*/
apic_area = 0xFEC00000; /*(unsigned long)IO_APIC_BASE;*/
pg_table = pte_offset((pmd_t *)pg_dir, apic_area);
pte = mk_pte_phys(mp_ioapic_addr, PAGE_KERNEL);
set_pte(pg_table, pte);
} else {
/*
* No local APIC but we are compiled SMP ... set up a
* fake all zeroes page to simulate the local APIC.
*/
pg_table = pte_offset((pmd_t *)pg_dir, apic_area);
pte = mk_pte(start_mem, PAGE_KERNEL);
memset((void *)start_mem, 0, PAGE_SIZE);
start_mem += PAGE_SIZE;
set_pte(pg_table, pte);
/*
* Do the same for the IO-APIC
*/
apic_area = 0xFEC00000;
pg_table = pte_offset((pmd_t *)pg_dir, apic_area);
pte = mk_pte(start_mem, PAGE_KERNEL);
memset((void *)start_mem, 0, PAGE_SIZE);
start_mem += PAGE_SIZE;
set_pte(pg_table, pte);
}
local_flush_tlb();
}
start_mem = init_smp_mappings(start_mem);
#endif
local_flush_tlb();
......
......@@ -14,6 +14,8 @@
* Adapted for 1.3.59 kernel - Andries Brouwer, 1 Feb 1996
*
* Fixed do_loop_request() re-entrancy - <Vincent.Renardias@waw.com> Mar 20, 1997
*
* Handle sparse backing files correctly - Kenn Humborg, Jun 28, 1998
*/
#include <linux/module.h>
......@@ -55,6 +57,14 @@ static struct loop_device loop_dev[MAX_LOOP];
static int loop_sizes[MAX_LOOP];
static int loop_blksizes[MAX_LOOP];
#define FALSE 0
#define TRUE (!FALSE)
/* Forward declaration of function to create missing blocks in the
backing file (can happen if the backing file is sparse) */
static int create_missing_block(struct loop_device *lo, int block, int blksize);
/*
* Transfer functions
*/
......@@ -187,6 +197,7 @@ static void do_lo_request(void)
struct loop_device *lo;
struct buffer_head *bh;
struct request *current_request;
int block_present;
repeat:
INIT_REQUEST;
......@@ -226,50 +237,70 @@ static void do_lo_request(void)
if (lo->lo_flags & LO_FLAGS_READ_ONLY)
goto error_out;
} else if (current_request->cmd != READ) {
printk("unknown loop device command (%d)?!?", current_request->cmd);
printk(KERN_ERR "unknown loop device command (%d)?!?", current_request->cmd);
goto error_out;
}
spin_unlock_irq(&io_request_lock);
while (len > 0) {
size = blksize - offset;
if (size > len)
size = len;
real_block = block;
block_present = TRUE;
if (lo->lo_flags & LO_FLAGS_DO_BMAP) {
real_block = bmap(lo->lo_dentry->d_inode, block);
if (!real_block) {
printk("loop: block %d not present\n", block);
goto error_out_lock;
/* The backing file is a sparse file and this block
doesn't exist. If reading, return zeros. If
writing, force the underlying FS to create
the block */
if (current_request->cmd == READ) {
memset(dest_addr, 0, size);
block_present = FALSE;
} else {
if (!create_missing_block(lo, block, blksize)) {
goto error_out_lock;
}
}
}
}
bh = getblk(lo->lo_device, real_block, blksize);
if (!bh) {
printk("loop: device %s: getblk(-, %d, %d) returned NULL",
kdevname(lo->lo_device),
block, blksize);
goto error_out_lock;
}
if (!buffer_uptodate(bh) && ((current_request->cmd == READ) ||
(offset || (len < blksize)))) {
ll_rw_block(READ, 1, &bh);
wait_on_buffer(bh);
if (!buffer_uptodate(bh)) {
if (block_present) {
bh = getblk(lo->lo_device, real_block, blksize);
if (!bh) {
printk(KERN_ERR "loop: device %s: getblk(-, %d, %d) returned NULL",
kdevname(lo->lo_device),
block, blksize);
goto error_out_lock;
}
if (!buffer_uptodate(bh) && ((current_request->cmd == READ) ||
(offset || (len < blksize)))) {
ll_rw_block(READ, 1, &bh);
wait_on_buffer(bh);
if (!buffer_uptodate(bh)) {
brelse(bh);
goto error_out_lock;
}
}
if ((lo->transfer)(lo, current_request->cmd, bh->b_data + offset,
dest_addr, size)) {
printk(KERN_ERR "loop: transfer error block %d\n", block);
brelse(bh);
goto error_out_lock;
}
}
size = blksize - offset;
if (size > len)
size = len;
if ((lo->transfer)(lo, current_request->cmd, bh->b_data + offset,
dest_addr, size)) {
printk("loop: transfer error block %d\n", block);
if (current_request->cmd == WRITE) {
mark_buffer_uptodate(bh, 1);
mark_buffer_dirty(bh, 1);
}
brelse(bh);
goto error_out_lock;
}
if (current_request->cmd == WRITE) {
mark_buffer_uptodate(bh, 1);
mark_buffer_dirty(bh, 1);
}
brelse(bh);
dest_addr += size;
len -= size;
offset = 0;
......@@ -289,6 +320,57 @@ static void do_lo_request(void)
goto repeat;
}
static int create_missing_block(struct loop_device *lo, int block, int blksize)
{
struct file *file;
loff_t new_offset;
char zero_buf[1] = { 0 };
ssize_t retval;
mm_segment_t old_fs;
file = lo->lo_backing_file;
if (file == NULL) {
printk(KERN_WARNING "loop: cannot create block - no backing file\n");
return FALSE;
}
if (file->f_op == NULL) {
printk(KERN_WARNING "loop: cannot create block - no file ops\n");
return FALSE;
}
new_offset = block * blksize;
if (file->f_op->llseek != NULL) {
file->f_op->llseek(file, new_offset, 0);
} else {
/* Do what the default llseek() code would have done */
file->f_pos = new_offset;
file->f_reada = 0;
file->f_version = ++event;
}
if (file->f_op->write == NULL) {
printk(KERN_WARNING "loop: cannot create block - no write file op\n");
return FALSE;
}
old_fs = get_fs();
set_fs(get_ds());
retval = file->f_op->write(file, zero_buf, 1, &file->f_pos);
set_fs(old_fs);
if (retval < 0) {
printk(KERN_WARNING "loop: cannot create block - FS write failed: code %d\n",
retval);
return FALSE;
} else {
return TRUE;
}
}
static int loop_set_fd(struct loop_device *lo, kdev_t dev, unsigned int arg)
{
struct file *file;
......@@ -309,7 +391,7 @@ static int loop_set_fd(struct loop_device *lo, kdev_t dev, unsigned int arg)
error = -EINVAL;
inode = file->f_dentry->d_inode;
if (!inode) {
printk("loop_set_fd: NULL inode?!?\n");
printk(KERN_ERR "loop_set_fd: NULL inode?!?\n");
goto out_putf;
}
......@@ -317,10 +399,36 @@ static int loop_set_fd(struct loop_device *lo, kdev_t dev, unsigned int arg)
error = blkdev_open(inode, file);
lo->lo_device = inode->i_rdev;
lo->lo_flags = 0;
/* Backed by a block device - don't need to hold onto
a file structure */
lo->lo_backing_file = NULL;
} else if (S_ISREG(inode->i_mode)) {
/* Backed by a regular file - we need to hold onto
a file structure for this file. We'll use it to
write to blocks that are not already present in
a sparse file. We create a new file structure
based on the one passed to us via 'arg'. This is
to avoid changing the file structure that the
caller is using */
lo->lo_device = inode->i_dev;
lo->lo_flags = LO_FLAGS_DO_BMAP;
error = 0;
error = -ENFILE;
lo->lo_backing_file = get_empty_filp();
if (lo->lo_backing_file) {
lo->lo_backing_file->f_mode = file->f_mode;
lo->lo_backing_file->f_pos = file->f_pos;
lo->lo_backing_file->f_flags = file->f_flags;
lo->lo_backing_file->f_owner = file->f_owner;
lo->lo_backing_file->f_dentry = file->f_dentry;
lo->lo_backing_file->f_op = file->f_op;
lo->lo_backing_file->private_data = file->private_data;
error = 0;
}
}
if (error)
goto out_putf;
......@@ -358,7 +466,14 @@ static int loop_clr_fd(struct loop_device *lo, kdev_t dev)
if (S_ISBLK(dentry->d_inode->i_mode))
blkdev_release (dentry->d_inode);
lo->lo_dentry = NULL;
dput(dentry);
if (lo->lo_backing_file != NULL) {
fput(lo->lo_backing_file);
lo->lo_backing_file = NULL;
} else {
dput(dentry);
}
lo->lo_device = 0;
lo->lo_encrypt_type = 0;
lo->lo_offset = 0;
......@@ -470,7 +585,7 @@ static int lo_ioctl(struct inode * inode, struct file * file,
if (!inode)
return -EINVAL;
if (MAJOR(inode->i_rdev) != MAJOR_NR) {
printk("lo_ioctl: pseudo-major != %d\n", MAJOR_NR);
printk(KERN_WARNING "lo_ioctl: pseudo-major != %d\n", MAJOR_NR);
return -ENODEV;
}
dev = MINOR(inode->i_rdev);
......@@ -506,7 +621,7 @@ static int lo_open(struct inode *inode, struct file *file)
if (!inode)
return -EINVAL;
if (MAJOR(inode->i_rdev) != MAJOR_NR) {
printk("lo_open: pseudo-major != %d\n", MAJOR_NR);
printk(KERN_WARNING "lo_open: pseudo-major != %d\n", MAJOR_NR);
return -ENODEV;
}
dev = MINOR(inode->i_rdev);
......@@ -526,7 +641,7 @@ static int lo_release(struct inode *inode, struct file *file)
if (!inode)
return 0;
if (MAJOR(inode->i_rdev) != MAJOR_NR) {
printk("lo_release: pseudo-major != %d\n", MAJOR_NR);
printk(KERN_WARNING "lo_release: pseudo-major != %d\n", MAJOR_NR);
return 0;
}
dev = MINOR(inode->i_rdev);
......@@ -535,7 +650,7 @@ static int lo_release(struct inode *inode, struct file *file)
fsync_dev(inode->i_rdev);
lo = &loop_dev[dev];
if (lo->lo_refcnt <= 0)
printk("lo_release: refcount(%d) <= 0\n", lo->lo_refcnt);
printk(KERN_ERR "lo_release: refcount(%d) <= 0\n", lo->lo_refcnt);
else {
lo->lo_refcnt--;
MOD_DEC_USE_COUNT;
......@@ -567,17 +682,17 @@ loop_init( void )) {
int i;
if (register_blkdev(MAJOR_NR, "loop", &lo_fops)) {
printk("Unable to get major number %d for loop device\n",
printk(KERN_WARNING "Unable to get major number %d for loop device\n",
MAJOR_NR);
return -EIO;
}
#ifndef MODULE
printk("loop: registered device at major %d\n", MAJOR_NR);
printk(KERN_INFO "loop: registered device at major %d\n", MAJOR_NR);
#ifdef DES_AVAILABLE
printk("loop: DES encryption available\n");
printk(KERN_INFO "loop: DES encryption available\n");
#endif
#ifdef IDEA_AVAILABLE
printk("loop: IDEA encryption available\n");
printk(KERN_INFO "loop: IDEA encryption available\n");
#endif
#endif
......@@ -598,6 +713,6 @@ loop_init( void )) {
void
cleanup_module( void ) {
if (unregister_blkdev(MAJOR_NR, "loop") != 0)
printk("loop: cleanup_module failed\n");
printk(KERN_WARNING "loop: cleanup_module failed\n");
}
#endif
......@@ -356,7 +356,7 @@ static long qc_capture(struct qcam_device *q, char *buf, unsigned long len)
wantlen -= t;
if (t < s)
break;
if (need_resched)
if (current->need_resched)
schedule();
}
......@@ -377,7 +377,7 @@ static long qc_capture(struct qcam_device *q, char *buf, unsigned long len)
int l;
do {
l = qcam_read_bytes(q, tmpbuf, 3);
if (need_resched)
if (current->need_resched)
schedule();
} while (l && (tmpbuf[0] == 0x7e || tmpbuf[1] == 0x7e || tmpbuf[2] == 0x7e));
if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
......@@ -407,7 +407,7 @@ static long qc_capture(struct qcam_device *q, char *buf, unsigned long len)
int l;
do {
l = qcam_read_bytes(q, tmpbuf, 1);
if (need_resched)
if (current->need_resched)
schedule();
} while (l && tmpbuf[0] == 0x7e);
l = qcam_read_bytes(q, tmpbuf+1, 2);
......
......@@ -156,7 +156,7 @@ static __inline__ void lp_yield (int minor)
{
if (!parport_yield_blocking (lp_table[minor].dev))
{
if (need_resched)
if (current->need_resched)
schedule ();
} else
lp_table[minor].irq_missed = 1;
......@@ -499,7 +499,7 @@ static ssize_t lp_read(struct file * file, char * buf,
status = (r_str(minor) & 0x40);
udelay(50);
counter++;
if (need_resched)
if (current->need_resched)
schedule ();
} while ((status == 0x40) && (counter < 20));
if (counter == 20) {
......@@ -519,7 +519,7 @@ static ssize_t lp_read(struct file * file, char * buf,
status=(r_str(minor) & 0x40);
udelay(20);
counter++;
if (need_resched)
if (current->need_resched)
schedule ();
} while ( (status == 0) && (counter < 20) );
if (counter == 20) { /* Timeout */
......
......@@ -102,7 +102,7 @@ static int lp_char_polled(char lpchar, int dev)
do {
count ++;
if(need_resched)
if (current->need_resched)
schedule();
} while (lp_table[dev]->lp_is_busy(dev) && count < lp_table[dev]->chars);
......
......@@ -263,14 +263,16 @@ static ssize_t write_null(struct file * file, const char * buf,
*/
static inline size_t read_zero_pagealigned(char * buf, size_t size)
{
struct mm_struct *mm;
struct vm_area_struct * vma;
unsigned long addr=(unsigned long)buf;
mm = current->mm;
/* Oops, this was forgotten before. -ben */
down(&current->mm->mmap_sem);
down(&mm->mmap_sem);
/* For private mappings, just map in zero pages. */
for (vma = find_vma(current->mm, addr); vma; vma = vma->vm_next) {
for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {
unsigned long count;
if (vma->vm_start > addr || (vma->vm_flags & VM_WRITE) == 0)
......@@ -281,10 +283,10 @@ static inline size_t read_zero_pagealigned(char * buf, size_t size)
if (count > size)
count = size;
flush_cache_range(current->mm, addr, addr + count);
zap_page_range(vma, addr, count);
zeromap_page_range(vma, addr, count, PAGE_COPY);
flush_tlb_range(current->mm, addr, addr + count);
flush_cache_range(mm, addr, addr + count);
zap_page_range(mm, addr, count);
zeromap_page_range(addr, count, PAGE_COPY);
flush_tlb_range(mm, addr, addr + count);
size -= count;
buf += count;
......@@ -293,14 +295,14 @@ static inline size_t read_zero_pagealigned(char * buf, size_t size)
goto out_up;
}
up(&current->mm->mmap_sem);
up(&mm->mmap_sem);
/* The shared case is hard. Let's do the conventional zeroing. */
do {
unsigned long unwritten = clear_user(buf, PAGE_SIZE);
if (unwritten)
return size + unwritten - PAGE_SIZE;
if (need_resched)
if (current->need_resched)
schedule();
buf += PAGE_SIZE;
size -= PAGE_SIZE;
......@@ -308,7 +310,7 @@ static inline size_t read_zero_pagealigned(char * buf, size_t size)
return size;
out_up:
up(&current->mm->mmap_sem);
up(&mm->mmap_sem);
return size;
}
......
......@@ -1268,7 +1268,7 @@ static ssize_t extract_entropy(struct random_bucket *r, char * buf,
nbytes -= i;
buf += i;
add_timer_randomness(r, &extract_timer_state, nbytes);
if (to_user && need_resched)
if (to_user && current->need_resched)
schedule();
}
......
......@@ -128,7 +128,7 @@ struct saa5249_device
#define RESCHED \
do { \
if (need_resched) \
if (current->need_resched) \
schedule(); \
} while (0)
......
......@@ -633,7 +633,7 @@ static inline ssize_t do_tty_write(
ret = -ERESTARTSYS;
if (signal_pending(current))
break;
if (need_resched)
if (current->need_resched)
schedule();
}
if (written) {
......
......@@ -30,7 +30,7 @@ int parport_wait_peripheral(struct parport *port, unsigned char mask,
if ((status & mask) == result)
return 0;
udelay(25);
if (need_resched)
if (current->need_resched)
schedule();
}
current->state = TASK_INTERRUPTIBLE;
......
......@@ -156,16 +156,16 @@ void parport_unregister_port(struct parport *port)
"%s not found in port list!\n", port->name);
}
spin_unlock_irqrestore (&parportlist_lock, flags);
if (p->probe_info.class_name)
kfree (p->probe_info.class_name);
if (p->probe_info.mfr)
kfree (p->probe_info.mfr);
if (p->probe_info.model)
kfree (p->probe_info.model);
if (p->probe_info.cmdset)
kfree (p->probe_info.cmdset);
if (p->probe_info.description)
kfree (p->probe_info.description);
if (port->probe_info.class_name)
kfree (port->probe_info.class_name);
if (port->probe_info.mfr)
kfree (port->probe_info.mfr);
if (port->probe_info.model)
kfree (port->probe_info.model);
if (port->probe_info.cmdset)
kfree (port->probe_info.cmdset);
if (port->probe_info.description)
kfree (port->probe_info.description);
kfree(port->name);
kfree(port);
}
......
......@@ -775,6 +775,10 @@ MODULE_PARM(debug,"i");
MODULE_PARM(irq,"1-8i");
MODULE_PARM(xcvr,"1-8i");
MODULE_PARM(debug,"i");
MODULE_PARM(irq,"1-8i");
MODULE_PARM(xcvr,"1-8i");
int
init_module(void)
{
......
This diff is collapsed.
This diff is collapsed.
......@@ -22,6 +22,8 @@ CONFIG_PPPDEF_BUILTIN :=
CONFIG_PPPDEF_MODULE :=
CONFIG_7990_BUILTIN :=
CONFIG_7990_MODULE :=
CONFIG_82596_BUILTIN :=
CONFIG_82596_MODULE :=
ifeq ($(CONFIG_ISDN),y)
ifeq ($(CONFIG_ISDN_PPP),y)
......@@ -573,10 +575,26 @@ else
endif
ifeq ($(CONFIG_APRICOT),y)
L_OBJS += apricot.o
CONFIG_82596_BUILTIN = y
else
ifeq ($(CONFIG_APRICOT),m)
M_OBJS += apricot.o
CONFIG_82596_MODULE = y
endif
endif
ifeq ($(CONFIG_MVME16x_NET),y)
CONFIG_82596_BUILTIN = y
else
ifeq ($(CONFIG_MVME16x_NET),m)
CONFIG_82596_MODULE = y
endif
endif
ifeq ($(CONFIG_BVME6000_NET),y)
CONFIG_82596_BUILTIN = y
else
ifeq ($(CONFIG_BVME6000_NET),m)
CONFIG_82596_MODULE = y
endif
endif
......@@ -703,6 +721,16 @@ else
endif
endif
# If anything built-in uses the 82596, then build it into the kernel also.
# If not, but a module uses it, build as a module.
ifdef CONFIG_82596_BUILTIN
L_OBJS += 82596.o
else
ifdef CONFIG_82596_MODULE
M_OBJS += 82596.o
endif
endif
ifeq ($(CONFIG_EQUALIZER),y)
L_OBJS += eql.o
else
......
This diff is collapsed.
......@@ -491,6 +491,7 @@ int eepro100_init(struct device *dev)
if (pci_present()) {
static int pci_index = 0;
for (; pci_index < 8; pci_index++) {
unsigned char pci_bus, pci_device_fn, pci_latency;
#if (LINUX_VERSION_CODE >= VERSION(2,1,85))
......@@ -507,9 +508,9 @@ int eepro100_init(struct device *dev)
unsigned short pci_command;
if (pcibios_find_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82557,
pci_index, &pci_bus,
&pci_device_fn))
PCI_DEVICE_ID_INTEL_82557,
pci_index, &pci_bus,
&pci_device_fn))
break;
#if (LINUX_VERSION_CODE >= VERSION(2,1,85))
pdev = pci_find_slot(pci_bus, pci_device_fn);
......
......@@ -28,6 +28,7 @@
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <asm/dma.h>
#include <asm/system.h>
#include <asm/spinlock.h>
......@@ -882,7 +883,7 @@ static int aha1542_query(int base_io, int * transl)
}
/* called from init/main.c */
void aha1542_setup( char *str, int *ints)
__initfunc(void aha1542_setup( char *str, int *ints))
{
const char *ahausage = "aha1542: usage: aha1542=<PORTBASE>[,<BUSON>,<BUSOFF>[,<DMASPEED>]]\n";
static int setup_idx = 0;
......
......@@ -202,7 +202,7 @@ if (!S_ISREG(inode->i_mode)) {
return result;
out_swapfile:
printk("NFS: attempt to write to active swap file!\n");
printk(KERN_ERR "NFS: attempt to write to active swap file!\n");
goto out;
}
......
......@@ -43,6 +43,7 @@ static void nfs_put_inode(struct inode *);
static void nfs_delete_inode(struct inode *);
static int nfs_notify_change(struct dentry *, struct iattr *);
static void nfs_put_super(struct super_block *);
static void nfs_umount_begin(struct super_block *);
static int nfs_statfs(struct super_block *, struct statfs *, int);
static struct super_operations nfs_sops = {
......@@ -54,7 +55,9 @@ static struct super_operations nfs_sops = {
nfs_put_super, /* put superblock */
NULL, /* write superblock */
nfs_statfs, /* stat filesystem */
NULL
NULL, /* no remount */
NULL, /* no clear inode */
nfs_umount_begin /* umount attempt begin */
};
struct rpc_stat nfs_rpcstat = { &nfs_program };
......@@ -142,6 +145,17 @@ nfs_put_super(struct super_block *sb)
MOD_DEC_USE_COUNT;
}
void
nfs_umount_begin(struct super_block *sb)
{
struct nfs_server *server = &sb->u.nfs_sb.s_server;
struct rpc_clnt *rpc;
/* -EIO all pending I/O */
if ((rpc = server->client) != NULL)
rpc_killall_tasks(rpc);
}
/*
* Compute and set NFS server blocksize
*/
......
......@@ -551,7 +551,7 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset,
interruptible_sleep_on(&inode->i_wait);
#else
dprintk("nfsd: write defer %d\n", current->pid);
need_resched = 1;
current->need_resched = 1;
current->timeout = jiffies + HZ / 100;
schedule();
dprintk("nfsd: write resume %d\n", current->pid);
......
......@@ -655,6 +655,19 @@ static int do_umount(kdev_t dev, int unmount_root)
(void) acct_auto_close(dev);
#endif
/*
* If we may have to abort operations to get out of this
* mount, and they will themselves hold resources we must
* allow the fs to do things. In the Unix tradition of
* 'Gee thats tricky lets do it in userspace' the umount_begin
* might fail to complete on the first run through as other tasks
* must return, and the like. Thats for the mount program to worry
* about for the moment.
*/
if(sb->s_op->umount_begin)
sb->s_op->umount_begin(sb);
/*
* Shrink dcache, then fsync. This guarantees that if the
* filesystem is quiescent at this point, then (a) only the
......@@ -747,6 +760,8 @@ static int umount_dev(kdev_t dev)
* we give them the info they need without using a real inode.
* If any other fields are ever needed by any block device release
* functions, they should be faked here. -- jrs
*
* For 2.3.x we want a new sys_umount syscall with flags (ie 'force')
*/
asmlinkage int sys_umount(char * name)
......
......@@ -182,6 +182,8 @@ extern inline unsigned long ffz(unsigned long word)
return qofs*8 + bofs;
}
#ifdef __KERNEL__
/*
* ffs: find first bit set. This is defined the same way as
* the libc and compiler builtin ffs routines, therefore
......@@ -199,6 +201,7 @@ extern inline unsigned long ffz(unsigned long word)
#define hweight16(x) generic_hweight16(x)
#define hweight8(x) generic_hweight8(x)
#endif /* __KERNEL__ */
/*
* Find next zero bit in a bitmap reasonably efficiently..
......
......@@ -53,6 +53,8 @@ extern __inline__ unsigned long ffz(unsigned long word)
return k;
}
#ifdef __KERNEL__
/*
* ffs: find first bit set. This is defined the same way as
* the libc and compiler builtin ffs routines, therefore
......@@ -70,6 +72,7 @@ extern __inline__ unsigned long ffz(unsigned long word)
#define hweight16(x) generic_hweight16(x)
#define hweight8(x) generic_hweight8(x)
#endif /* __KERNEL__ */
#ifdef __KERNEL__
......
......@@ -51,6 +51,8 @@ extern __inline__ int test_bit(int nr, int * addr)
return ((mask & *addr) != 0);
}
#ifdef __KERNEL__
/*
* ffs: find first bit set. This is defined the same way as
* the libc and compiler builtin ffs routines, therefore
......@@ -68,4 +70,6 @@ extern __inline__ int test_bit(int nr, int * addr)
#define hweight16(x) generic_hweight16(x)
#define hweight8(x) generic_hweight8(x)
#endif /* __KERNEL__ */
#endif /* _ASM_GENERIC_BITOPS_H */
......@@ -187,6 +187,8 @@ extern __inline__ unsigned long ffz(unsigned long word)
return word;
}
#ifdef __KERNEL__
/*
* ffs: find first bit set. This is defined the same way as
* the libc and compiler builtin ffs routines, therefore
......@@ -213,6 +215,7 @@ extern __inline__ int ffs(int x)
#define hweight16(x) generic_hweight16(x)
#define hweight8(x) generic_hweight8(x)
#endif /* __KERNEL__ */
#ifdef __KERNEL__
......
......@@ -333,10 +333,7 @@ __initfunc(static void check_bugs(void))
check_amd_k6();
check_pentium_f00f();
system_utsname.machine[1] = '0' + boot_cpu_data.x86;
#if !defined(__SMP__) && defined(CONFIG_MTRR)
/* Must be done after other processors booted: at this point we are
called before SMP initialisation, so this is for the non-SMP case
only. The SMP case is handled in arch/i386/kernel/smp.c */
#if defined(CONFIG_MTRR)
mtrr_init ();
#endif
}
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