Commit 6923b9bd authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://linux-input.bkbits.net/linux-input

into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents 382b4673 48d378a4
......@@ -1957,3 +1957,11 @@ Changes for patch v216
<devfs_get_handle>
- Removed deprecated <devfs_find_handle>
===============================================================================
Changes for patch v217
- Exported <devfs_find_and_unregister> and <devfs_only> to modules
- Updated README from master HTML file
- Fixed module unload race in <devfs_open>
......@@ -3,7 +3,7 @@ Devfs (Device File System) FAQ
Linux Devfs (Device File System) FAQ
Richard Gooch
21-JUL-2002
20-AUG-2002
Document languages:
......@@ -1509,6 +1509,16 @@ Here are some common questions and answers.
Devfsd doesn't start
Make sure you have compiled and installed devfsd
Make sure devfsd is being started from your boot
scripts
Make sure you have configured your kernel to enable devfs (see
below)
Make sure devfs is mounted (see below)
Devfsd is not managing all my permissions
Make sure you are capturing the appropriate events. For example,
......@@ -1777,7 +1787,7 @@ I hate the naming scheme
First, remember that no naming scheme will please everybody. You hate
the scheme, others love it. Who's to say who's right and who's wrong?
Ultimately, the person who writes the code gets to choose, and what
exists now is a combination of the the choices made by the
exists now is a combination of the choices made by the
devfs author and the
kernel maintainer (Linus).
......
Proper Locking Under a Preemptible Kernel:
Keeping Kernel Code Preempt-Safe
Robert Love <rml@tech9.net>
Last Updated: 22 Jan 2002
Last Updated: 28 Aug 2002
INTRODUCTION
......@@ -112,3 +112,24 @@ critical variables. Another example:
This code is not preempt-safe, but see how easily we can fix it by simply
moving the spin_lock up two lines.
PREVENTING PREEMPTION USING INTERRUPT DISABLING
It is possible to prevent a preemption event using local_irq_disable and
local_irq_save. Note, when doing so, you must be very careful to not cause
an event that would set need_resched and result in a preemption check. When
in doubt, rely on locking or explicit preemption disabling.
Note in 2.5 interrupt disabling is now only per-CPU (e.g. local).
An additional concern is proper usage of local_irq_disable and local_irq_save.
These may be used to protect from preemption, however, on exit, if preemption
may be enabled, a test to see if preemption is required should be done. If
these are called from the spin_lock and read/write lock macros, the right thing
is done. They may also be called within a spin-lock protected region, however,
if they are ever called outside of this context, a test for preemption should
be made. Do note that calls from interrupt context or bottom half/ tasklets
are also protected by preemption locks and so may use the versions which do
not check preemption.
......@@ -55,12 +55,16 @@ static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_
asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
{
struct thread_struct * t = &current->thread;
struct tss_struct * tss = init_tss + smp_processor_id();
struct tss_struct * tss;
int ret = 0;
if ((from + num <= from) || (from + num > IO_BITMAP_SIZE*32))
return -EINVAL;
if (turn_on && !capable(CAP_SYS_RAWIO))
return -EPERM;
tss = init_tss + get_cpu();
/*
* If it's the first ioperm() call in this thread's lifetime, set the
* IO bitmap up. ioperm() is much less timing critical than clone(),
......@@ -69,8 +73,11 @@ asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
if (!t->ts_io_bitmap) {
unsigned long *bitmap;
bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
if (!bitmap)
return -ENOMEM;
if (!bitmap) {
ret = -ENOMEM;
goto out;
}
/*
* just in case ...
*/
......@@ -88,7 +95,9 @@ asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
set_bitmap(t->ts_io_bitmap, from, num, !turn_on);
set_bitmap(tss->io_bitmap, from, num, !turn_on);
return 0;
out:
put_cpu();
return ret;
}
/*
......
......@@ -985,9 +985,10 @@ CONFIG_H8
CONFIG_NVRAM
If you say Y here and create a character special file /dev/nvram
with major number 10 and minor number 144 using mknod ("man mknod"),
you get read and write access to the 50 bytes of non-volatile memory
in the real time clock (RTC), which is contained in every PC and
most Ataris.
you get read and write access to the extra bytes of non-volatile
memory in the real time clock (RTC), which is contained in every PC
and most Ataris. The actual number of bytes varies, depending on the
nvram in the system, but is usually 114 (128-14 for the RTC).
This memory is conventionally called "CMOS RAM" on PCs and "NVRAM"
on Ataris. /dev/nvram may be used to view settings there, or to
......
......@@ -15,7 +15,7 @@ obj-y += mem.o tty_io.o n_tty.o tty_ioctl.o pty.o misc.o random.o
export-objs := busmouse.o console.o keyboard.o sysrq.o \
misc.o pty.o random.o selection.o \
sonypi.o tty_io.o tty_ioctl.o generic_serial.o rtc.o \
ip2main.o
ip2main.o nvram.o
obj-$(CONFIG_VT) += vt.o vc_screen.o consolemap.o consolemap_deftbl.o selection.o keyboard.o
obj-$(CONFIG_HW_CONSOLE) += console.o defkeymap.o
......
This diff is collapsed.
......@@ -645,6 +645,9 @@
20020728 Richard Gooch <rgooch@atnf.csiro.au>
Removed deprecated <devfs_find_handle>.
v1.20
20020820 Richard Gooch <rgooch@atnf.csiro.au>
Fixed module unload race in <devfs_open>.
v1.21
*/
#include <linux/types.h>
#include <linux/errno.h>
......@@ -677,7 +680,7 @@
#include <asm/bitops.h>
#include <asm/atomic.h>
#define DEVFS_VERSION "1.20 (20020728)"
#define DEVFS_VERSION "1.21 (20020820)"
#define DEVFS_NAME "devfs"
......@@ -2228,16 +2231,15 @@ const char *devfs_get_name (devfs_handle_t de, unsigned int *namelen)
/**
* devfs_only - returns if "devfs=only" is a boot option
* devfs_only - returns true if "devfs=only" is a boot option
*
* If "devfs=only" this function will return 1, otherwise 0 is returned.
*/
int devfs_only (void)
{
if (boot_options & OPTION_ONLY)
return 1;
return 0;
}
return (boot_options & OPTION_ONLY) ? 1 : 0;
} /* End Function devfs_only */
/**
......@@ -2312,6 +2314,7 @@ EXPORT_SYMBOL(devfs_unregister);
EXPORT_SYMBOL(devfs_mk_symlink);
EXPORT_SYMBOL(devfs_mk_dir);
EXPORT_SYMBOL(devfs_get_handle);
EXPORT_SYMBOL(devfs_find_and_unregister);
EXPORT_SYMBOL(devfs_get_flags);
EXPORT_SYMBOL(devfs_set_flags);
EXPORT_SYMBOL(devfs_get_maj_min);
......@@ -2327,6 +2330,7 @@ EXPORT_SYMBOL(devfs_get_next_sibling);
EXPORT_SYMBOL(devfs_auto_unregister);
EXPORT_SYMBOL(devfs_get_unregister_slave);
EXPORT_SYMBOL(devfs_get_name);
EXPORT_SYMBOL(devfs_only);
/**
......@@ -2382,7 +2386,7 @@ static int check_disc_changed (struct devfs_entry *de)
extern int warn_no_part;
if ( !S_ISBLK (de->mode) ) return 0;
bdev = bdget(kdev_t_to_nr(dev));
bdev = bdget (kdev_t_to_nr (dev) );
if (!bdev) return 0;
bdops = devfs_get_ops (de);
if (!bdops) return 0;
......@@ -2390,7 +2394,7 @@ static int check_disc_changed (struct devfs_entry *de)
/* Ugly hack to disable messages about unable to read partition table */
tmp = warn_no_part;
warn_no_part = 0;
retval = full_check_disk_change(bdev);
retval = full_check_disk_change (bdev);
warn_no_part = tmp;
out:
devfs_put_ops (de);
......@@ -2692,21 +2696,23 @@ static int devfs_open (struct inode *inode, struct file *file)
struct fcb_type *df;
struct devfs_entry *de;
struct fs_info *fs_info = inode->i_sb->u.generic_sbp;
void *ops;
de = get_devfs_entry_from_vfs_inode (inode);
if (de == NULL) return -ENODEV;
if ( S_ISDIR (de->mode) ) return 0;
df = &de->u.fcb;
file->private_data = de->info;
ops = devfs_get_ops (de); /* Now have module refcount */
if ( S_ISBLK (inode->i_mode) )
{
file->f_op = &def_blk_fops;
if (df->ops) inode->i_bdev->bd_op = df->ops;
err = def_blk_fops.open (inode, file);
if (ops) inode->i_bdev->bd_op = ops;
err = def_blk_fops.open (inode, file); /* Module refcount unchanged */
}
else
{
file->f_op = fops_get ( (struct file_operations *) df->ops );
file->f_op = ops;
if (file->f_op)
{
lock_kernel ();
......@@ -2714,7 +2720,7 @@ static int devfs_open (struct inode *inode, struct file *file)
unlock_kernel ();
}
else
{ /* Fallback to legacy scheme */
{ /* Fallback to legacy scheme (I don't have a module refcount) */
if ( S_ISCHR (inode->i_mode) ) err = chrdev_open (inode, file);
else err = -ENODEV;
}
......
......@@ -203,6 +203,7 @@ lockd(struct svc_rqst *rqstp)
rpciod_down();
/* Release module */
unlock_kernel();
MOD_DEC_USE_COUNT;
}
......
......@@ -20,6 +20,7 @@
#define FPU_SAVE \
do { \
preempt_disable(); \
if (!test_thread_flag(TIF_USEDFPU)) \
__asm__ __volatile__ (" clts;\n"); \
__asm__ __volatile__ ("fsave %0; fwait": "=m"(fpu_save[0])); \
......@@ -30,6 +31,7 @@
__asm__ __volatile__ ("frstor %0": : "m"(fpu_save[0])); \
if (!test_thread_flag(TIF_USEDFPU)) \
stts(); \
preempt_enable(); \
} while (0)
#define LD(x,y) " movq 8*("#x")(%1), %%mm"#y" ;\n"
......@@ -542,7 +544,8 @@ static struct xor_block_template xor_block_p5_mmx = {
* Copyright (C) 1999 Zach Brown (with obvious credit due Ingo)
*/
#define XMMS_SAVE \
#define XMMS_SAVE do { \
preempt_disable(); \
__asm__ __volatile__ ( \
"movl %%cr0,%0 ;\n\t" \
"clts ;\n\t" \
......@@ -552,9 +555,10 @@ static struct xor_block_template xor_block_p5_mmx = {
"movups %%xmm3,0x30(%1) ;\n\t" \
: "=&r" (cr0) \
: "r" (xmm_save) \
: "memory")
: "memory"); \
} while(0)
#define XMMS_RESTORE \
#define XMMS_RESTORE do { \
__asm__ __volatile__ ( \
"sfence ;\n\t" \
"movups (%1),%%xmm0 ;\n\t" \
......@@ -564,7 +568,9 @@ static struct xor_block_template xor_block_p5_mmx = {
"movl %0,%%cr0 ;\n\t" \
: \
: "r" (cr0), "r" (xmm_save) \
: "memory")
: "memory"); \
preempt_enable(); \
} while(0)
#define ALIGN16 __attribute__((aligned(16)))
......
......@@ -37,7 +37,8 @@ typedef struct { unsigned long a,b; } __attribute__((aligned(16))) xmm_store_t;
/* Doesn't use gcc to save the XMM registers, because there is no easy way to
tell it to do a clts before the register saving. */
#define XMMS_SAVE \
#define XMMS_SAVE do { \
preempt_disable(); \
asm volatile ( \
"movq %%cr0,%0 ;\n\t" \
"clts ;\n\t" \
......@@ -47,7 +48,8 @@ typedef struct { unsigned long a,b; } __attribute__((aligned(16))) xmm_store_t;
"movups %%xmm3,0x30(%1) ;\n\t" \
: "=r" (cr0) \
: "r" (xmm_save) \
: "memory")
: "memory"); \
} while(0)
#define XMMS_RESTORE \
asm volatile ( \
......@@ -59,7 +61,9 @@ typedef struct { unsigned long a,b; } __attribute__((aligned(16))) xmm_store_t;
"movq %0,%%cr0 ;\n\t" \
: \
: "r" (cr0), "r" (xmm_save) \
: "memory")
: "memory"); \
preempt_enable(); \
} while(0)
#define OFFS(x) "16*("#x")"
#define PF_OFFS(x) "256+16*("#x")"
......
/*
* $Id: cobalt-nvram.h,v 1.20 2001/10/17 23:16:55 thockin Exp $
* cobalt-nvram.h : defines for the various fields in the cobalt NVRAM
*
* Copyright 2001,2002 Sun Microsystems, Inc.
*/
#ifndef COBALT_NVRAM_H
#define COBALT_NVRAM_H
#include <linux/nvram.h>
#define COBT_CMOS_INFO_MAX 0x7f /* top address allowed */
#define COBT_CMOS_BIOS_DRIVE_INFO 0x12 /* drive info would go here */
#define COBT_CMOS_CKS_START NVRAM_OFFSET(0x0e)
#define COBT_CMOS_CKS_END NVRAM_OFFSET(0x7f)
/* flag bytes - 16 flags for now, leave room for more */
#define COBT_CMOS_FLAG_BYTE_0 NVRAM_OFFSET(0x10)
#define COBT_CMOS_FLAG_BYTE_1 NVRAM_OFFSET(0x11)
/* flags in flag bytes - up to 16 */
#define COBT_CMOS_FLAG_MIN 0x0001
#define COBT_CMOS_CONSOLE_FLAG 0x0001 /* console on/off */
#define COBT_CMOS_DEBUG_FLAG 0x0002 /* ROM debug messages */
#define COBT_CMOS_AUTO_PROMPT_FLAG 0x0004 /* boot to ROM prompt? */
#define COBT_CMOS_CLEAN_BOOT_FLAG 0x0008 /* set by a clean shutdown */
#define COBT_CMOS_HW_NOPROBE_FLAG 0x0010 /* go easy on the probing */
#define COBT_CMOS_SYSFAULT_FLAG 0x0020 /* system fault detected */
#define COBT_CMOS_OOPSPANIC_FLAG 0x0040 /* panic on oops */
#define COBT_CMOS_DELAY_CACHE_FLAG 0x0080 /* delay cache initialization */
#define COBT_CMOS_NOLOGO_FLAG 0x0100 /* hide "C" logo @ boot */
#define COBT_CMOS_VERSION_FLAG 0x0200 /* the version field is valid */
#define COBT_CMOS_FLAG_MAX 0x0200
/* leave byte 0x12 blank - Linux looks for drive info here */
/* CMOS structure version, valid if COBT_CMOS_VERSION_FLAG is true */
#define COBT_CMOS_VERSION NVRAM_OFFSET(0x13)
#define COBT_CMOS_VER_BTOCODE 1 /* min. version needed for btocode */
/* index of default boot method */
#define COBT_CMOS_BOOT_METHOD NVRAM_OFFSET(0x20)
#define COBT_CMOS_BOOT_METHOD_DISK 0
#define COBT_CMOS_BOOT_METHOD_ROM 1
#define COBT_CMOS_BOOT_METHOD_NET 2
#define COBT_CMOS_BOOT_DEV_MIN NVRAM_OFFSET(0x21)
/* major #, minor # of first through fourth boot device */
#define COBT_CMOS_BOOT_DEV0_MAJ NVRAM_OFFSET(0x21)
#define COBT_CMOS_BOOT_DEV0_MIN NVRAM_OFFSET(0x22)
#define COBT_CMOS_BOOT_DEV1_MAJ NVRAM_OFFSET(0x23)
#define COBT_CMOS_BOOT_DEV1_MIN NVRAM_OFFSET(0x24)
#define COBT_CMOS_BOOT_DEV2_MAJ NVRAM_OFFSET(0x25)
#define COBT_CMOS_BOOT_DEV2_MIN NVRAM_OFFSET(0x26)
#define COBT_CMOS_BOOT_DEV3_MAJ NVRAM_OFFSET(0x27)
#define COBT_CMOS_BOOT_DEV3_MIN NVRAM_OFFSET(0x28)
#define COBT_CMOS_BOOT_DEV_MAX NVRAM_OFFSET(0x28)
/* checksum of bytes 0xe-0x7f */
#define COBT_CMOS_CHECKSUM NVRAM_OFFSET(0x2e)
/* running uptime counter, units of 5 minutes (32 bits =~ 41000 years) */
#define COBT_CMOS_UPTIME_0 NVRAM_OFFSET(0x30)
#define COBT_CMOS_UPTIME_1 NVRAM_OFFSET(0x31)
#define COBT_CMOS_UPTIME_2 NVRAM_OFFSET(0x32)
#define COBT_CMOS_UPTIME_3 NVRAM_OFFSET(0x33)
/* count of successful boots (32 bits) */
#define COBT_CMOS_BOOTCOUNT_0 NVRAM_OFFSET(0x38)
#define COBT_CMOS_BOOTCOUNT_1 NVRAM_OFFSET(0x39)
#define COBT_CMOS_BOOTCOUNT_2 NVRAM_OFFSET(0x3a)
#define COBT_CMOS_BOOTCOUNT_3 NVRAM_OFFSET(0x3b)
/* 13 bytes: system serial number, same as on the back of the system */
#define COBT_CMOS_SYS_SERNUM_LEN 13
#define COBT_CMOS_SYS_SERNUM_0 NVRAM_OFFSET(0x40)
#define COBT_CMOS_SYS_SERNUM_1 NVRAM_OFFSET(0x41)
#define COBT_CMOS_SYS_SERNUM_2 NVRAM_OFFSET(0x42)
#define COBT_CMOS_SYS_SERNUM_3 NVRAM_OFFSET(0x43)
#define COBT_CMOS_SYS_SERNUM_4 NVRAM_OFFSET(0x44)
#define COBT_CMOS_SYS_SERNUM_5 NVRAM_OFFSET(0x45)
#define COBT_CMOS_SYS_SERNUM_6 NVRAM_OFFSET(0x46)
#define COBT_CMOS_SYS_SERNUM_7 NVRAM_OFFSET(0x47)
#define COBT_CMOS_SYS_SERNUM_8 NVRAM_OFFSET(0x48)
#define COBT_CMOS_SYS_SERNUM_9 NVRAM_OFFSET(0x49)
#define COBT_CMOS_SYS_SERNUM_10 NVRAM_OFFSET(0x4a)
#define COBT_CMOS_SYS_SERNUM_11 NVRAM_OFFSET(0x4b)
#define COBT_CMOS_SYS_SERNUM_12 NVRAM_OFFSET(0x4c)
/* checksum for serial num - 1 byte */
#define COBT_CMOS_SYS_SERNUM_CSUM NVRAM_OFFSET(0x4f)
#define COBT_CMOS_ROM_REV_MAJ NVRAM_OFFSET(0x50)
#define COBT_CMOS_ROM_REV_MIN NVRAM_OFFSET(0x51)
#define COBT_CMOS_ROM_REV_REV NVRAM_OFFSET(0x52)
#define COBT_CMOS_BTO_CODE_0 NVRAM_OFFSET(0x53)
#define COBT_CMOS_BTO_CODE_1 NVRAM_OFFSET(0x54)
#define COBT_CMOS_BTO_CODE_2 NVRAM_OFFSET(0x55)
#define COBT_CMOS_BTO_CODE_3 NVRAM_OFFSET(0x56)
#define COBT_CMOS_BTO_IP_CSUM NVRAM_OFFSET(0x57)
#define COBT_CMOS_BTO_IP_0 NVRAM_OFFSET(0x58)
#define COBT_CMOS_BTO_IP_1 NVRAM_OFFSET(0x59)
#define COBT_CMOS_BTO_IP_2 NVRAM_OFFSET(0x5a)
#define COBT_CMOS_BTO_IP_3 NVRAM_OFFSET(0x5b)
#endif /* COBALT_NVRAM_H */
......@@ -95,7 +95,6 @@ extern void devfs_auto_unregister (devfs_handle_t master,devfs_handle_t slave);
extern devfs_handle_t devfs_get_unregister_slave (devfs_handle_t master);
extern const char *devfs_get_name (devfs_handle_t de, unsigned int *namelen);
extern int devfs_only (void);
extern void devfs_register_tape (devfs_handle_t de);
extern void devfs_register_series (devfs_handle_t dir, const char *format,
unsigned int num_entries,
......@@ -238,7 +237,6 @@ static inline int devfs_only (void)
{
return 0;
}
static inline void devfs_register_tape (devfs_handle_t de)
{
return;
......
......@@ -22,7 +22,7 @@ static inline unsigned int nr_free_highpages(void) { return 0; }
static inline void *kmap(struct page *page) { return page_address(page); }
#define kunmap(page) do { } while (0)
#define kunmap(page) do { (void) (page); } while (0)
#define kmap_atomic(page,idx) kmap(page)
#define kunmap_atomic(page,idx) kunmap(page)
......
......@@ -7,11 +7,21 @@
#define NVRAM_INIT _IO('p', 0x40) /* initialize NVRAM and set checksum */
#define NVRAM_SETCKS _IO('p', 0x41) /* recalculate checksum */
/* for all current systems, this is where NVRAM starts */
#define NVRAM_FIRST_BYTE 14
/* all these functions expect an NVRAM offset, not an absolute */
#define NVRAM_OFFSET(x) ((x)-NVRAM_FIRST_BYTE)
#ifdef __KERNEL__
extern unsigned char nvram_read_byte( int i );
extern void nvram_write_byte( unsigned char c, int i );
extern int nvram_check_checksum( void );
extern void nvram_set_checksum( void );
/* __foo is foo without grabbing the rtc_lock - get it yourself */
extern unsigned char __nvram_read_byte(int i);
extern unsigned char nvram_read_byte(int i);
extern void __nvram_write_byte(unsigned char c, int i);
extern void nvram_write_byte(unsigned char c, int i);
extern int __nvram_check_checksum(void);
extern int nvram_check_checksum(void);
extern void __nvram_set_checksum(void);
extern void nvram_set_checksum(void);
#endif
#endif /* _LINUX_NVRAM_H */
......@@ -87,9 +87,6 @@ int cpu_up(unsigned int cpu);
#define smp_processor_id() 0
#define hard_smp_processor_id() 0
#define smp_threads_ready 1
#ifndef CONFIG_PREEMPT
#define kernel_lock()
#endif
#define smp_call_function(func,info,retry,wait) ({ 0; })
static inline void smp_send_reschedule(int cpu) { }
static inline void smp_send_reschedule_all(void) { }
......
......@@ -1039,6 +1039,7 @@ asmlinkage void preempt_schedule(void)
printk("bad: schedule() with irqs disabled!\n");
show_stack(NULL);
preempt_enable_no_resched();
return;
}
need_resched:
......
......@@ -1229,19 +1229,20 @@ static void sample_queue(unsigned long dummy)
int netif_rx(struct sk_buff *skb)
{
int this_cpu = smp_processor_id();
int this_cpu;
struct softnet_data *queue;
unsigned long flags;
if (!skb->stamp.tv_sec)
do_gettimeofday(&skb->stamp);
/* The code is rearranged so that the path is the most
short when CPU is congested, but is still operating.
/*
* The code is rearranged so that the path is the most
* short when CPU is congested, but is still operating.
*/
queue = &softnet_data[this_cpu];
local_irq_save(flags);
this_cpu = smp_processor_id();
queue = &softnet_data[this_cpu];
netdev_rx_stat[this_cpu].total++;
if (queue->input_pkt_queue.qlen <= netdev_max_backlog) {
......@@ -1252,10 +1253,10 @@ int netif_rx(struct sk_buff *skb)
enqueue:
dev_hold(skb->dev);
__skb_queue_tail(&queue->input_pkt_queue, skb);
local_irq_restore(flags);
#ifndef OFFLINE_SAMPLE
get_sample_stats(this_cpu);
#endif
local_irq_restore(flags);
return queue->cng_level;
}
......
......@@ -1030,6 +1030,7 @@ rpciod(void *ptr)
wake_up(assassin);
dprintk("RPC: rpciod exiting\n");
unlock_kernel();
MOD_DEC_USE_COUNT;
return 0;
}
......
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