Commit 9b252209 authored by Anton Blanchard's avatar Anton Blanchard

Merge samba.org:/scratch/anton/linux-2.5

into samba.org:/scratch/anton/linux-2.5_work
parents b2de2046 68239661
......@@ -132,6 +132,12 @@ M: A2232@gmx.net
L: linux-m68k@lists.linux-m68k.org
S: Maintained
AIO
P: Benjamin LaHaise
M: bcrl@redhat.com
L: linux-aio@kvack.org
S: Supported
ACENIC DRIVER
P: Jes Sorensen
M: jes@trained-monkey.org
......
......@@ -576,13 +576,24 @@ CONFIG_MAGIC_SYSRQ
unless you really know what this hack does.
CONFIG_SRM_ENV
If you enable this option, a subdirectory called srm_environment
will give you access to the most important SRM environment
variables. If you've got an Alpha style system supporting
SRC, then it is a good idea to say Yes or Module to this driver.
If you enable this option, a subdirectory inside /proc called
/proc/srm_environment will give you access to the all important
SRM environment variables (those which have a name) and also
to all others (by their internal number).
SRM is something like a BIOS for Alpha machines. There are some
other such BIOSes, like AlphaBIOS, which this driver cannot
support (hey, that's not SRM!).
Despite the fact that this driver doesn't work on all Alphas (but
only on those which have SRM as their firmware), it's save to
build it even if your particular machine doesn't know about SRM
(or if you intend to compile a generic kernel). It will simply
not create those subdirectory in /proc (and give you some warning,
of course).
This driver is also available as a module and will be called
srm_env.o if you build it as a module.
srm_env.o then.
CONFIG_DEBUG_KERNEL
Say Y here if you are developing drivers or trying to debug and
......
......@@ -40,7 +40,6 @@
extern struct hwrpb_struct *hwrpb;
extern void dump_thread(struct pt_regs *, struct user *);
extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
extern spinlock_t kernel_flag;
extern spinlock_t rtc_lock;
/* these are C runtime functions with special calling conventions: */
......@@ -207,7 +206,6 @@ EXPORT_SYMBOL(up);
*/
#ifdef CONFIG_SMP
EXPORT_SYMBOL(kernel_flag);
EXPORT_SYMBOL(synchronize_irq);
EXPORT_SYMBOL(flush_tlb_all);
EXPORT_SYMBOL(flush_tlb_mm);
......
......@@ -67,8 +67,6 @@ enum ipi_message_type {
IPI_CPU_STOP,
};
spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
/* Set to a secondary's cpuid when it comes online. */
static int smp_secondary_alive __initdata = 0;
......
......@@ -33,6 +33,15 @@
* Changelog
* ~~~~~~~~~
*
* Thu, 22 Aug 2002 15:10:43 +0200
* - Update Config.help entry. I got a number of emails asking
* me to tell their senders if they could make use of this
* piece of code... So: "SRM is something like BIOS for your
* Alpha"
* - Update code formatting a bit to better conform CodingStyle
* rules.
* - So this is v0.0.5, with no changes (except formatting)
*
* Wed, 22 May 2002 00:11:21 +0200
* - Fix typo on comment (SRC -> SRM)
* - Call this "Version 0.0.4"
......@@ -59,7 +68,7 @@
#define BASE_DIR "srm_environment" /* Subdir in /proc/ */
#define NAMED_DIR "named_variables" /* Subdir for known variables */
#define NUMBERED_DIR "numbered_variables" /* Subdir for all variables */
#define VERSION "0.0.4" /* Module version */
#define VERSION "0.0.5" /* Module version */
#define NAME "srm_env" /* Module name */
MODULE_AUTHOR("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
......@@ -97,9 +106,12 @@ static srm_env_t srm_named_entries[] = {
};
static srm_env_t srm_numbered_entries[256];
static int
srm_env_read(char *page, char **start, off_t off, int count, int *eof,
void *data) {
void *data)
{
int nbytes;
unsigned long ret;
srm_env_t *entry;
......@@ -111,11 +123,11 @@ srm_env_read(char *page, char **start, off_t off, int count, int *eof,
return -EFAULT;
}
entry = (srm_env_t *)data;
entry = (srm_env_t *) data;
ret = callback_getenv(entry->id, page, count);
if((ret >> 61) == 0)
nbytes = (int)ret;
nbytes = (int) ret;
else
nbytes = -EFAULT;
......@@ -124,9 +136,11 @@ srm_env_read(char *page, char **start, off_t off, int count, int *eof,
return nbytes;
}
static int
srm_env_write(struct file *file, const char *buffer, unsigned long count,
void *data) {
void *data)
{
#define BUFLEN 512
int nbytes;
srm_env_t *entry;
......@@ -156,7 +170,7 @@ srm_env_write(struct file *file, const char *buffer, unsigned long count,
do
ret2 = callback_save_env();
while((ret2 >> 61) == 1);
nbytes = (int)ret1;
nbytes = (int) ret1;
} else
nbytes = -EFAULT;
......@@ -165,8 +179,10 @@ srm_env_write(struct file *file, const char *buffer, unsigned long count,
return nbytes;
}
static void
srm_env_cleanup(void) {
srm_env_cleanup(void)
{
srm_env_t *entry;
unsigned long var_num;
......@@ -210,8 +226,10 @@ srm_env_cleanup(void) {
return;
}
static int __init
srm_env_init(void) {
srm_env_init(void)
{
srm_env_t *entry;
unsigned long var_num;
......@@ -220,7 +238,9 @@ srm_env_init(void) {
*/
if(!alpha_using_srm) {
printk(KERN_INFO "%s: This Alpha system doesn't "
"know about SRM...\n", __FUNCTION__);
"know about SRM (or you've booted "
"SRM->MILO->Linux, which gets "
"misdetected)...\n", __FUNCTION__);
return -ENODEV;
}
......@@ -274,7 +294,7 @@ srm_env_init(void) {
if(entry->proc_entry == NULL)
goto cleanup;
entry->proc_entry->data = (void *)entry;
entry->proc_entry->data = (void *) entry;
entry->proc_entry->owner = THIS_MODULE;
entry->proc_entry->read_proc = srm_env_read;
entry->proc_entry->write_proc = srm_env_write;
......@@ -295,7 +315,7 @@ srm_env_init(void) {
goto cleanup;
entry->id = var_num;
entry->proc_entry->data = (void *)entry;
entry->proc_entry->data = (void *) entry;
entry->proc_entry->owner = THIS_MODULE;
entry->proc_entry->read_proc = srm_env_read;
entry->proc_entry->write_proc = srm_env_write;
......@@ -303,20 +323,26 @@ srm_env_init(void) {
printk(KERN_INFO "%s: version %s loaded successfully\n", NAME,
VERSION);
return 0;
cleanup:
srm_env_cleanup();
return -ENOMEM;
}
static void __exit
srm_env_exit(void) {
srm_env_exit(void)
{
srm_env_cleanup();
printk(KERN_INFO "%s: unloaded successfully\n", NAME);
return;
}
module_init(srm_env_init);
module_exit(srm_env_exit);
......@@ -273,7 +273,3 @@ EXPORT_SYMBOL_NOVERS(__down_trylock_failed);
EXPORT_SYMBOL_NOVERS(__up_wakeup);
EXPORT_SYMBOL(get_wchan);
#ifdef CONFIG_PREEMPT
EXPORT_SYMBOL(kernel_flag);
#endif
......@@ -36,10 +36,6 @@
#define MEM_SIZE (16*1024*1024)
#endif
#ifdef CONFIG_PREEMPT
spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
#endif
#if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE)
char fpe_type[8];
......
This diff is collapsed.
......@@ -7,7 +7,6 @@
#include <linux/slab.h>
#include <asm/io.h>
#include <linux/pm.h>
#include <asm/keyboard.h>
#include <asm/system.h>
#include <linux/bootmem.h>
......@@ -393,21 +392,13 @@ static __init int init_ints_after_s1(struct dmi_blacklist *d)
}
/*
* Some Bioses enable the PS/2 mouse (touchpad) at resume, even if it
* was disabled before the suspend. Linux gets terribly confused by that.
* Some Bioses enable the PS/2 mouse (touchpad) at resume, even if it was
* disabled before the suspend. Linux used to get terribly confused by that.
*/
typedef void (pm_kbd_func) (void);
static __init int broken_ps2_resume(struct dmi_blacklist *d)
{
#ifdef CONFIG_VT
if (pm_kbd_request_override == NULL)
{
pm_kbd_request_override = pckbd_pm_resume;
printk(KERN_INFO "%s machine detected. Mousepad Resume Bug workaround enabled.\n", d->ident);
}
#endif
printk(KERN_INFO "%s machine detected. Mousepad Resume Bug workaround hopefully not needed.\n", d->ident);
return 0;
}
......
......@@ -754,6 +754,11 @@ ENTRY(sys_call_table)
.long sys_sched_getaffinity
.long sys_set_thread_area
.long sys_get_thread_area
.long sys_io_setup /* 245 */
.long sys_io_destroy
.long sys_io_getevents
.long sys_io_submit
.long sys_io_cancel
.rept NR_syscalls-(.-sys_call_table)/4
.long sys_ni_syscall
......
......@@ -126,7 +126,6 @@ EXPORT_SYMBOL(mmx_copy_page);
#ifdef CONFIG_SMP
EXPORT_SYMBOL(cpu_data);
EXPORT_SYMBOL(kernel_flag);
EXPORT_SYMBOL(cpu_online_map);
EXPORT_SYMBOL_NOVERS(__write_lock_failed);
EXPORT_SYMBOL_NOVERS(__read_lock_failed);
......
......@@ -18,6 +18,7 @@
#include <linux/kernel_stat.h>
#include <linux/mc146818rtc.h>
#include <linux/cache.h>
#include <linux/interrupt.h>
#include <asm/mtrr.h>
#include <asm/pgalloc.h>
......@@ -103,9 +104,6 @@
* about nothing of note with C stepping upwards.
*/
/* The 'big kernel lock' */
spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
struct tlb_state cpu_tlbstate[NR_CPUS] __cacheline_aligned = {[0 ... NR_CPUS-1] = { &init_mm, 0, }};
/*
......
......@@ -84,10 +84,6 @@ EXPORT_SYMBOL(smp_call_function);
EXPORT_SYMBOL(smp_call_function_single);
EXPORT_SYMBOL(cpu_online_map);
EXPORT_SYMBOL(ia64_cpu_to_sapicid);
#include <asm/smplock.h>
EXPORT_SYMBOL(kernel_flag);
#else /* !CONFIG_SMP */
EXPORT_SYMBOL(__flush_tlb_all);
......
......@@ -52,14 +52,6 @@
#include <asm/unistd.h>
#include <asm/mca.h>
/*
* The Big Kernel Lock. It's not supposed to be used for performance critical stuff
* anymore. But we still need to align it because certain workloads are still affected by
* it. For example, llseek() and various other filesystem related routines still use the
* BKL.
*/
spinlock_t kernel_flag __cacheline_aligned = SPIN_LOCK_UNLOCKED;
/*
* Structure and data for smp_call_function(). This is designed to minimise static memory
* requirements. It also looks cleaner.
......
......@@ -53,7 +53,6 @@
/* Ze Big Kernel Lock! */
spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
int smp_threads_ready; /* Not used */
int smp_num_cpus;
int global_irq_holder = NO_PROC_ID;
......
......@@ -53,7 +53,6 @@ static void sendintr(int destid, unsigned char status)
#endif /* CONFIG_SGI_IP27 */
/* The 'big kernel lock' */
spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
int smp_threads_ready; /* Not used */
atomic_t smp_commenced = ATOMIC_INIT(0);
struct cpuinfo_mips cpu_data[NR_CPUS];
......
......@@ -35,9 +35,6 @@ EXPORT_SYMBOL(boot_cpu_data);
#ifdef CONFIG_SMP
EXPORT_SYMBOL(synchronize_irq);
#include <asm/smplock.h>
EXPORT_SYMBOL(kernel_flag);
#include <asm/system.h>
EXPORT_SYMBOL(__global_sti);
EXPORT_SYMBOL(__global_cli);
......
......@@ -540,11 +540,6 @@ if [ "$CONFIG_ALL_PPC" = "y" ]; then
bool ' Support for mouse button 2+3 emulation' CONFIG_MAC_EMUMOUSEBTN
fi
fi
# This is for drivers/macintosh/mac_hid.o, which is needed if the input
# layer is used.
if [ "$CONFIG_INPUT" != "n" ]; then
define_bool CONFIG_MAC_HID y
fi
if [ "$CONFIG_ADB_CUDA" != "n" ]; then
bool 'Support for ANS LCD display' CONFIG_ANSLCD
fi
......
......@@ -93,9 +93,6 @@ EXPORT_SYMBOL(enable_irq);
EXPORT_SYMBOL(disable_irq);
EXPORT_SYMBOL(disable_irq_nosync);
EXPORT_SYMBOL(probe_irq_mask);
#ifdef CONFIG_SMP
EXPORT_SYMBOL(kernel_flag);
#endif /* CONFIG_SMP */
EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
EXPORT_SYMBOL_NOVERS(DMA_MODE_READ);
......
......@@ -47,7 +47,6 @@ struct cpuinfo_PPC cpu_data[NR_CPUS];
struct klock_info_struct klock_info = { KLOCK_CLEAR, 0 };
atomic_t ipi_recv;
atomic_t ipi_sent;
spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
unsigned int prof_multiplier[NR_CPUS] = { [1 ... NR_CPUS-1] = 1 };
unsigned int prof_counter[NR_CPUS] = { [1 ... NR_CPUS-1] = 1 };
unsigned long cache_decay_ticks = HZ/100;
......
......@@ -68,7 +68,6 @@ void rtas_indicator_progress(char *, unsigned short);
void btext_progress(char *, unsigned short);
extern unsigned long pmac_find_end_of_memory(void);
extern void select_adb_keyboard(void);
extern int of_show_percpuinfo(struct seq_file *, int);
extern kdev_t boot_dev;
......@@ -437,22 +436,6 @@ chrp_init2(void)
if (ppc_md.progress)
ppc_md.progress(" Have fun! ", 0x7777);
#if defined(CONFIG_VT) && defined(CONFIG_INPUT)
/* see if there is a keyboard in the device tree
with a parent of type "adb" */
{
struct device_node *kbd;
for (kbd = find_devices("keyboard"); kbd; kbd = kbd->next) {
if (kbd->parent && kbd->parent->type
&& strcmp(kbd->parent->type, "adb") == 0) {
select_adb_keyboard();
break;
}
}
}
#endif /* CONFIG_VT && CONFIG_INPUT */
}
void __init
......
......@@ -66,7 +66,6 @@
#include <asm/ohare.h>
#include <asm/mediabay.h>
#include <asm/machdep.h>
#include <asm/keyboard.h>
#include <asm/dma.h>
#include <asm/bootx.h>
#include <asm/cputable.h>
......@@ -617,15 +616,6 @@ pmac_find_end_of_memory(void)
return total;
}
void __init
select_adb_keyboard(void)
{
#ifdef CONFIG_VT
ppc_md.kbd_translate = mac_hid_kbd_translate;
ppc_md.kbd_unexpected_up = mac_hid_kbd_unexpected_up;
#endif /* CONFIG_VT */
}
void __init
pmac_init(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7)
......@@ -666,8 +656,6 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.feature_call = pmac_do_feature_call;
select_adb_keyboard();
#ifdef CONFIG_BOOTX_TEXT
ppc_md.progress = pmac_progress;
#endif /* CONFIG_BOOTX_TEXT */
......
......@@ -70,7 +70,6 @@ EXPORT_SYMBOL(disable_irq);
EXPORT_SYMBOL(disable_irq_nosync);
#ifdef CONFIG_SMP
EXPORT_SYMBOL(synchronize_irq);
EXPORT_SYMBOL(kernel_flag);
#endif /* CONFIG_SMP */
EXPORT_SYMBOL(register_ioctl32_conversion);
......
......@@ -51,7 +51,6 @@
#include <asm/machdep.h>
int smp_threads_ready = 0;
spinlock_t kernel_flag __cacheline_aligned = SPIN_LOCK_UNLOCKED;
unsigned long cache_decay_ticks;
/* initialised so it doesnt end up in bss */
......
......@@ -54,8 +54,6 @@ cycles_t cacheflush_time=0;
int smp_threads_ready=0; /* Set when the idlers are all forked. */
static atomic_t smp_commenced = ATOMIC_INIT(0);
spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
volatile unsigned long phys_cpu_present_map;
volatile unsigned long cpu_online_map;
unsigned long cache_decay_ticks = 0;
......@@ -634,7 +632,6 @@ int setup_profiling_timer(unsigned int multiplier)
}
EXPORT_SYMBOL(lowcore_ptr);
EXPORT_SYMBOL(kernel_flag);
EXPORT_SYMBOL(smp_ctl_set_bit);
EXPORT_SYMBOL(smp_ctl_clear_bit);
EXPORT_SYMBOL(smp_num_cpus);
......
......@@ -53,8 +53,6 @@ cycles_t cacheflush_time=0;
int smp_threads_ready=0; /* Set when the idlers are all forked. */
static atomic_t smp_commenced = ATOMIC_INIT(0);
spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
volatile unsigned long phys_cpu_present_map;
volatile unsigned long cpu_online_map;
unsigned long cache_decay_ticks = 0;
......@@ -613,7 +611,6 @@ int setup_profiling_timer(unsigned int multiplier)
}
EXPORT_SYMBOL(lowcore_ptr);
EXPORT_SYMBOL(kernel_flag);
EXPORT_SYMBOL(smp_ctl_set_bit);
EXPORT_SYMBOL(smp_ctl_clear_bit);
EXPORT_SYMBOL(smp_num_cpus);
......
......@@ -66,9 +66,6 @@ cycles_t cacheflush_time = 0; /* XXX */
* instruction which is much better...
*/
/* Kernel spinlock */
spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
/* Used to make bitops atomic */
unsigned char bitops_spinlock = 0;
......
......@@ -77,10 +77,6 @@ extern int __divdi3(int, int);
extern void dump_thread(struct pt_regs *, struct user *);
#ifdef CONFIG_SMP
extern spinlock_t kernel_flag;
#endif
/* One thing to note is that the way the symbols of the mul/div
* support routines are named is a mess, they all start with
* a '.' which makes it a bitch to export, here is the trick:
......@@ -130,9 +126,6 @@ EXPORT_SYMBOL_PRIVATE(_clear_bit);
EXPORT_SYMBOL_PRIVATE(_change_bit);
#ifdef CONFIG_SMP
/* Kernel wide locking */
EXPORT_SYMBOL(kernel_flag);
/* IRQ implementation. */
EXPORT_SYMBOL(global_irq_holder);
EXPORT_SYMBOL(synchronize_irq);
......
......@@ -46,9 +46,6 @@ cpuinfo_sparc cpu_data[NR_CPUS];
/* Please don't make this stuff initdata!!! --DaveM */
static unsigned char boot_cpu_id;
/* Kernel spinlock */
spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
atomic_t sparc64_num_cpus_online = ATOMIC_INIT(0);
unsigned long cpu_online_map = 0;
atomic_t sparc64_num_cpus_possible = ATOMIC_INIT(0);
......
......@@ -101,9 +101,7 @@ extern int __ashrdi3(int, int);
extern void dump_thread(struct pt_regs *, struct user *);
extern int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs);
#ifdef CONFIG_SMP
extern spinlock_t kernel_flag;
#ifdef CONFIG_DEBUG_SPINLOCK
#if defined(CONFIG_SMP) && defined(CONFIG_DEBUG_SPINLOCK)
extern void _do_spin_lock (spinlock_t *lock, char *str);
extern void _do_spin_unlock (spinlock_t *lock);
extern int _spin_trylock (spinlock_t *lock);
......@@ -112,7 +110,6 @@ extern void _do_read_unlock(rwlock_t *rw, char *str);
extern void _do_write_lock(rwlock_t *rw, char *str);
extern void _do_write_unlock(rwlock_t *rw);
#endif
#endif
extern unsigned long phys_base;
extern unsigned long pfn_base;
......@@ -127,9 +124,6 @@ EXPORT_SYMBOL(__write_lock);
EXPORT_SYMBOL(__write_unlock);
#endif
/* Kernel wide locking */
EXPORT_SYMBOL(kernel_flag);
/* Hard IRQ locking */
#ifdef CONFIG_SMP
EXPORT_SYMBOL(synchronize_irq);
......
......@@ -22,9 +22,6 @@
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
/* The 'big kernel lock' */
spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
/*
* the following functions deal with sending IPIs between CPUs.
*
......
......@@ -109,7 +109,6 @@ EXPORT_SYMBOL(mmx_copy_page);
#ifdef CONFIG_SMP
EXPORT_SYMBOL(cpu_data);
EXPORT_SYMBOL(kernel_flag);
EXPORT_SYMBOL(smp_num_cpus);
EXPORT_SYMBOL(cpu_online_map);
EXPORT_SYMBOL_NOVERS(__write_lock_failed);
......
# Makefile for the Linux device tree
obj-y := core.o sys.o interface.o power.o bus.o \
driver.o
driver.o class.o intf.o
obj-y += fs/
export-objs := core.o power.o sys.o bus.o driver.o
export-objs := core.o power.o sys.o bus.o driver.o \
class.o intf.o
include $(TOPDIR)/Rules.make
......@@ -26,5 +26,27 @@ extern void driver_remove_dir(struct device_driver * drv);
extern int device_bus_link(struct device * dev);
extern void device_remove_symlink(struct driver_dir_entry * dir, const char * name);
extern int devclass_make_dir(struct device_class *);
extern void devclass_remove_dir(struct device_class *);
extern int devclass_drv_link(struct device_driver *);
extern void devclass_drv_unlink(struct device_driver *);
extern int devclass_dev_link(struct device_class *, struct device *);
extern void devclass_dev_unlink(struct device_class *, struct device *);
extern int devclass_add_device(struct device *);
extern void devclass_remove_device(struct device *);
extern int intf_make_dir(struct device_interface *);
extern void intf_remove_dir(struct device_interface *);
extern int intf_dev_link(struct intf_data *);
extern void intf_dev_unlink(struct intf_data *);
extern int interface_add(struct device_class *, struct device *);
extern void interface_remove(struct device_class *, struct device *);
extern int driver_attach(struct device_driver * drv);
extern void driver_detach(struct device_driver * drv);
/*
* class.c - basic device class management
*/
#include <linux/device.h>
#include <linux/module.h>
#include "base.h"
static LIST_HEAD(class_list);
int devclass_add_driver(struct device_driver * drv)
{
if (drv->devclass) {
pr_debug("Registering driver %s:%s with class %s\n",
drv->bus->name,drv->name,drv->devclass->name);
spin_lock(&device_lock);
list_add_tail(&drv->class_list,&drv->devclass->drivers);
spin_unlock(&device_lock);
devclass_drv_link(drv);
}
return 0;
}
void devclass_remove_driver(struct device_driver * drv)
{
if (drv->devclass) {
pr_debug("Removing driver %s:%s:%s\n",
drv->devclass->name,drv->bus->name,drv->name);
spin_lock(&device_lock);
list_del_init(&drv->class_list);
spin_unlock(&device_lock);
devclass_drv_unlink(drv);
}
}
static void enum_device(struct device_class * cls, struct device * dev)
{
u32 val;
spin_lock(&device_lock);
val = cls->devnum++;
spin_unlock(&device_lock);
dev->class_num = val;
devclass_dev_link(cls,dev);
}
static void unenum_device(struct device_class * cls, struct device * dev)
{
devclass_dev_unlink(cls,dev);
dev->class_num = 0;
}
int devclass_add_device(struct device * dev)
{
struct device_class * cls = dev->driver->devclass;
int error = 0;
if (cls) {
pr_debug("adding device '%s' to class '%s'\n",
dev->name,cls->name);
if (cls->add_device)
error = cls->add_device(dev);
if (!error) {
enum_device(cls,dev);
interface_add(cls,dev);
}
}
return error;
}
void devclass_remove_device(struct device * dev)
{
struct device_class * cls = dev->driver->devclass;
if (cls) {
pr_debug("removing device '%s' from class '%s'\n",
dev->name,cls->name);
interface_remove(cls,dev);
unenum_device(cls,dev);
if (cls->remove_device)
cls->remove_device(dev);
}
}
int devclass_register(struct device_class * cls)
{
INIT_LIST_HEAD(&cls->drivers);
INIT_LIST_HEAD(&cls->intf_list);
pr_debug("registering device class '%s'\n",cls->name);
spin_lock(&device_lock);
list_add_tail(&cls->node,&class_list);
spin_unlock(&device_lock);
devclass_make_dir(cls);
return 0;
}
void devclass_unregister(struct device_class * cls)
{
pr_debug("unregistering device class '%s'\n",cls->name);
devclass_remove_dir(cls);
spin_lock(&device_lock);
list_del_init(&class_list);
spin_unlock(&device_lock);
}
EXPORT_SYMBOL(devclass_register);
EXPORT_SYMBOL(devclass_unregister);
......@@ -54,7 +54,8 @@ static int found_match(struct device * dev, struct device_driver * drv)
spin_lock(&device_lock);
list_add_tail(&dev->driver_list,&drv->devices);
spin_unlock(&device_lock);
devclass_add_device(dev);
goto Done;
ProbeFailed:
......@@ -99,6 +100,7 @@ static void device_detach(struct device * dev)
struct device_driver * drv;
if (dev->driver) {
devclass_remove_device(dev);
spin_lock(&device_lock);
drv = dev->driver;
dev->driver = NULL;
......@@ -172,6 +174,7 @@ int device_register(struct device *dev)
INIT_LIST_HEAD(&dev->g_list);
INIT_LIST_HEAD(&dev->driver_list);
INIT_LIST_HEAD(&dev->bus_list);
INIT_LIST_HEAD(&dev->intf_list);
spin_lock_init(&dev->lock);
atomic_set(&dev->refcount,2);
......
obj-y := device.o bus.o driver.o
obj-y := device.o bus.o driver.o class.o intf.o
export-objs := device.o bus.o driver.o
export-objs := device.o bus.o driver.o class.o intf.o
include $(TOPDIR)/Rules.make
/*
* class.c - driverfs bindings for device classes.
*/
#include <linux/device.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/err.h>
#include "fs.h"
static struct driver_dir_entry class_dir;
#define to_class_attr(_attr) container_of(_attr,struct devclass_attribute,attr)
#define to_class(d) container_of(d,struct device_class,dir)
static ssize_t
devclass_attr_show(struct driver_dir_entry * dir, struct attribute * attr,
char * buf, size_t count, loff_t off)
{
struct devclass_attribute * class_attr = to_class_attr(attr);
struct device_class * dc = to_class(dir);
ssize_t ret = 0;
if (class_attr->show)
ret = class_attr->show(dc,buf,count,off);
return ret;
}
static ssize_t
devclass_attr_store(struct driver_dir_entry * dir, struct attribute * attr,
const char * buf, size_t count, loff_t off)
{
struct devclass_attribute * class_attr = to_class_attr(attr);
struct device_class * dc = to_class(dir);
ssize_t ret = 0;
if (class_attr->store)
ret = class_attr->store(dc,buf,count,off);
return ret;
}
static struct driverfs_ops devclass_attr_ops = {
show: devclass_attr_show,
store: devclass_attr_store,
};
int devclass_create_file(struct device_class * dc, struct devclass_attribute * attr)
{
int error;
if (dc) {
error = driverfs_create_file(&attr->attr,&dc->dir);
} else
error = -EINVAL;
return error;
}
void devclass_remove_file(struct device_class * dc, struct devclass_attribute * attr)
{
if (dc)
driverfs_remove_file(&dc->dir,attr->attr.name);
}
/**
* devclass_dev_link - create symlink to device's directory
* @cls - device class we're a part of
* @dev - device we're linking to
*
* Create a symlink in the class's devices/ directory to @dev's
* directory in the physical hierarchy. The name is the device's
* class-enumerated value (struct device::class_num). We're
* creating:
* class/<class name>/devices/<link name> ->
* root/<path to device>/<device's dir>
* So, the link looks like:
* ../../../root/<path to device>/
*/
int devclass_dev_link(struct device_class * cls, struct device * dev)
{
char linkname[16];
char * path;
int length;
int error;
length = get_devpath_length(dev);
length += strlen("../../../root");
if (length > PATH_MAX)
return -ENAMETOOLONG;
if (!(path = kmalloc(length,GFP_KERNEL)))
return -ENOMEM;
memset(path,0,length);
strcpy(path,"../../../root");
fill_devpath(dev,path,length);
snprintf(linkname,16,"%u",dev->class_num);
error = driverfs_create_symlink(&cls->device_dir,linkname,path);
kfree(path);
return error;
}
void devclass_dev_unlink(struct device_class * cls, struct device * dev)
{
char linkname[16];
snprintf(linkname,16,"%u",dev->class_num);
driverfs_remove_file(&cls->device_dir,linkname);
}
/**
* devclass_drv_link - create symlink to driver's directory
* @drv: driver we're linking up
*
* Create a symlink in the class's drivers/ directory to @drv's
* directory (in the bus's directory). It's name is <bus>:<driver>
* to prevent naming conflicts.
*
* We're creating
* class/<class name>/drivers/<link name> ->
* bus/<bus name>/drivers/<driver name>/
* So, the link looks like:
* ../../../bus/<bus name>/drivers/<driver name>
*/
int devclass_drv_link(struct device_driver * drv)
{
char * name;
char * path;
int namelen;
int pathlen;
int error = 0;
namelen = strlen(drv->name) + strlen(drv->bus->name) + 2;
name = kmalloc(namelen,GFP_KERNEL);
if (!name)
return -ENOMEM;
snprintf(name,namelen,"%s:%s",drv->bus->name,drv->name);
pathlen = strlen("../../../bus/") +
strlen(drv->bus->name) +
strlen("/drivers/") +
strlen(drv->name) + 1;
if (!(path = kmalloc(pathlen,GFP_KERNEL))) {
error = -ENOMEM;
goto Done;
}
snprintf(path,pathlen,"%s%s%s%s",
"../../../bus/",
drv->bus->name,
"/drivers/",
drv->name);
error = driverfs_create_symlink(&drv->devclass->driver_dir,name,path);
Done:
kfree(name);
kfree(path);
return error;
}
void devclass_drv_unlink(struct device_driver * drv)
{
char * name;
int length;
length = strlen(drv->name) + strlen(drv->bus->name) + 2;
if ((name = kmalloc(length,GFP_KERNEL))) {
driverfs_remove_file(&drv->devclass->driver_dir,name);
kfree(name);
}
}
void devclass_remove_dir(struct device_class * dc)
{
driverfs_remove_dir(&dc->device_dir);
driverfs_remove_dir(&dc->driver_dir);
driverfs_remove_dir(&dc->dir);
}
int devclass_make_dir(struct device_class * dc)
{
int error;
dc->dir.name = dc->name;
dc->dir.ops = &devclass_attr_ops;
error = device_create_dir(&dc->dir,&class_dir);
if (!error) {
dc->driver_dir.name = "drivers";
error = device_create_dir(&dc->driver_dir,&dc->dir);
if (!error) {
dc->device_dir.name = "devices";
error = device_create_dir(&dc->device_dir,&dc->dir);
}
if (error)
driverfs_remove_dir(&dc->dir);
}
return error;
}
static struct driver_dir_entry class_dir = {
name: "class",
mode: (S_IRWXU | S_IRUGO | S_IXUGO),
};
static int __init devclass_driverfs_init(void)
{
return driverfs_create_dir(&class_dir,NULL);
}
core_initcall(devclass_driverfs_init);
EXPORT_SYMBOL(devclass_create_file);
EXPORT_SYMBOL(devclass_remove_file);
......@@ -123,7 +123,7 @@ void device_remove_dir(struct device * dev)
driverfs_remove_dir(&dev->dir);
}
static int get_devpath_length(struct device * dev)
int get_devpath_length(struct device * dev)
{
int length = 1;
struct device * parent = dev;
......@@ -138,7 +138,7 @@ static int get_devpath_length(struct device * dev)
return length;
}
static void fill_devpath(struct device * dev, char * path, int length)
void fill_devpath(struct device * dev, char * path, int length)
{
struct device * parent;
--length;
......
extern int device_create_dir(struct driver_dir_entry * dir, struct driver_dir_entry * parent);
int get_devpath_length(struct device * dev);
void fill_devpath(struct device * dev, char * path, int length);
/*
* intf.c - driverfs glue for device interfaces
*/
#include <linux/device.h>
#include <linux/slab.h>
#include "fs.h"
/**
* intf_dev_link - symlink from interface's directory to device's directory
*
*/
int intf_dev_link(struct intf_data * data)
{
char linkname[16];
char * path;
int length;
int error;
length = get_devpath_length(data->dev);
length += strlen("../../../root");
if (length > PATH_MAX)
return -ENAMETOOLONG;
if (!(path = kmalloc(length,GFP_KERNEL)))
return -ENOMEM;
memset(path,0,length);
strcpy(path,"../../../root");
fill_devpath(data->dev,path,length);
snprintf(linkname,16,"%u",data->intf_num);
error = driverfs_create_symlink(&data->intf->dir,linkname,path);
kfree(path);
return error;
}
void intf_dev_unlink(struct intf_data * data)
{
char linkname[16];
snprintf(linkname,16,"%u",data->intf_num);
driverfs_remove_file(&data->intf->dir,linkname);
}
void intf_remove_dir(struct device_interface * intf)
{
driverfs_remove_dir(&intf->dir);
}
int intf_make_dir(struct device_interface * intf)
{
intf->dir.name = intf->name;
return device_create_dir(&intf->dir,&intf->devclass->dir);
}
/*
* intf.c - class-specific interface management
*/
#define DEBUG 1
#include <linux/device.h>
#include <linux/module.h>
#include "base.h"
#define to_intf(node) container_of(node,struct device_interface,node)
int interface_register(struct device_interface * intf)
{
struct device_class * cls = intf->devclass;
if (cls) {
pr_debug("register interface '%s' with class '%s\n",
intf->name,cls->name);
intf_make_dir(intf);
spin_lock(&device_lock);
list_add_tail(&intf->node,&cls->intf_list);
spin_unlock(&device_lock);
return 0;
}
return -EINVAL;
}
void interface_unregister(struct device_interface * intf)
{
pr_debug("unregistering interface '%s' from class '%s'\n",
intf->name,intf->devclass->name);
spin_lock(&device_lock);
list_del_init(&intf->node);
spin_unlock(&device_lock);
intf_remove_dir(intf);
}
int interface_add(struct device_class * cls, struct device * dev)
{
struct list_head * node;
int error = 0;
pr_debug("adding '%s' to %s class interfaces\n",dev->name,cls->name);
list_for_each(node,&cls->intf_list) {
struct device_interface * intf = to_intf(node);
if (intf->add_device) {
error = intf->add_device(dev);
if (error)
pr_debug("%s:%s: adding '%s' failed: %d\n",
cls->name,intf->name,dev->name,error);
}
}
return 0;
}
void interface_remove(struct device_class * cls, struct device * dev)
{
struct list_head * node;
struct list_head * next;
pr_debug("remove '%s' from %s class interfaces: ",dev->name,cls->name);
spin_lock(&device_lock);
list_for_each_safe(node,next,&dev->intf_list) {
struct intf_data * intf_data = container_of(node,struct intf_data,node);
list_del_init(&intf_data->node);
spin_unlock(&device_lock);
intf_dev_unlink(intf_data);
pr_debug("%s ",intf_data->intf->name);
if (intf_data->intf->remove_device)
intf_data->intf->remove_device(intf_data);
spin_lock(&device_lock);
}
spin_unlock(&device_lock);
pr_debug("\n");
}
int interface_add_data(struct intf_data * data)
{
spin_lock(&device_lock);
list_add_tail(&data->node,&data->dev->intf_list);
data->intf_num = ++data->intf->devnum;
spin_unlock(&device_lock);
intf_dev_link(data);
return 0;
}
EXPORT_SYMBOL(interface_register);
EXPORT_SYMBOL(interface_unregister);
......@@ -633,25 +633,6 @@ CONFIG_BUSMOUSE
The module will be called busmouse.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
CONFIG_PSMOUSE
The PS/2 mouse connects to a special mouse port that looks much like
the keyboard port (small circular connector with 6 pins). This way,
the mouse does not use any serial ports. This port can also be used
for other input devices like light pens, tablets, keypads. Compaq,
AST and IBM all use this as their mouse port on currently shipping
machines. The trackballs of some laptops are PS/2 mice also. In
particular, the C&T 82C710 mouse on TI Travelmates is a PS/2 mouse.
Although PS/2 mice are not technically bus mice, they are explained
in detail in the Busmouse-HOWTO, available from
<http://www.linuxdoc.org/docs.html#howto>.
When using a PS/2 mouse, you can get problems if you want to use the
mouse both on the Linux console and under X. Using the "-R" option
of the Linux mouse managing program gpm (available from
<ftp://gnu.systemy.it/pub/gpm/>) solves this problem, or you can get
the "mconv2" utility from <ftp://ibiblio.org/pub/Linux/system/mouse/>.
CONFIG_QIC02_TAPE
If you have a non-SCSI tape drive like that, say Y. Or, if you want
to compile this driver as a module ( = code which can be inserted in
......
......@@ -58,8 +58,6 @@ if [ "$CONFIG_IT8712" = "y" ]; then
if [ "$CONFIG_QTRONIX_KEYBOARD" = "y" ]; then
define_bool CONFIG_IT8172_CIR y
else
bool ' Enable PS2 Keyboard Support' CONFIG_PC_KEYB
fi
bool 'Enable Smart Card Reader 0 Support ' CONFIG_IT8172_SCR0
bool 'Enable Smart Card Reader 1 Support ' CONFIG_IT8172_SCR1
fi
......@@ -89,7 +87,6 @@ source drivers/i2c/Config.in
mainmenu_option next_comment
comment 'Mice'
tristate 'Bus Mouse Support' CONFIG_BUSMOUSE
bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE
endmenu
tristate 'QIC-02 tape support' CONFIG_QIC02_TAPE
......
......@@ -17,115 +17,27 @@ export-objs := busmouse.o console.o keyboard.o sysrq.o \
sonypi.o tty_io.o tty_ioctl.o generic_serial.o rtc.o \
ip2main.o
KEYMAP =defkeymap.o
KEYBD =pc_keyb.o
CONSOLE =console.o
ifeq ($(ARCH),s390)
KEYMAP =
KEYBD =
CONSOLE =
endif
ifeq ($(ARCH),mips)
ifneq ($(CONFIG_PC_KEYB),y)
KEYBD =
endif
endif
ifeq ($(ARCH),s390x)
KEYMAP =
KEYBD =
CONSOLE =
endif
ifeq ($(ARCH),m68k)
ifdef CONFIG_AMIGA
KEYBD = amikeyb.o
else
KEYBD =
endif
ifneq ($(ARCH),s390)
ifneq ($(ARCH),s390x)
ifneq ($(ARCH),um)
KEYMAP =defkeymap.o
CONSOLE =console.o
endif
endif
endif
ifdef CONFIG_Q40
KEYBD += q40_keyb.o
SERIAL = serial.o
endif
ifdef CONFIG_APOLLO
KEYBD += dn_keyb.o
endif
ifeq ($(ARCH),arm)
ifneq ($(CONFIG_PC_KEYMAP),y)
KEYMAP =
endif
ifneq ($(CONFIG_PC_KEYB),y)
KEYBD =
endif
endif
ifeq ($(ARCH),um)
KEYMAP =
KEYBD =
CONSOLE =
endif
ifeq ($(ARCH),sh)
KEYMAP =
KEYBD =
CONSOLE =
ifeq ($(CONFIG_SH_HP600),y)
KEYMAP = defkeymap.o
KEYBD = scan_keyb.o hp600_keyb.o
CONSOLE = console.o
endif
ifeq ($(CONFIG_SH_DMIDA),y)
# DMIDA does not connect the HD64465 PS/2 keyboard port
# but we allow for USB keyboards to be plugged in.
KEYMAP = defkeymap.o
KEYBD = # hd64465_keyb.o pc_keyb.o
CONSOLE = console.o
endif
ifeq ($(CONFIG_SH_EC3104),y)
KEYMAP = defkeymap.o
KEYBD = ec3104_keyb.o
CONSOLE = console.o
endif
ifeq ($(CONFIG_SH_DREAMCAST),y)
KEYMAP = defkeymap.o
KEYBD =
CONSOLE = console.o
endif
endif
ifeq ($(CONFIG_DECSTATION),y)
KEYMAP =
KEYBD =
SERIAL = decserial.o
endif
ifeq ($(CONFIG_BAGET_MIPS),y)
KEYBD =
endif
ifeq ($(CONFIG_QTRONIX_KEYBOARD),y)
KEYBD = qtronix.o
KEYMAP = qtronixmap.o
endif
ifeq ($(CONFIG_SPARC32),y)
KEYBD =
endif
ifeq ($(CONFIG_SPARC64),y)
KEYBD =
endif
obj-$(CONFIG_VT) += vt.o vc_screen.o consolemap.o consolemap_deftbl.o $(CONSOLE) selection.o
#obj-$(CONFIG_SERIAL) += $(SERIAL) # Fix for decserial.o
obj-$(CONFIG_VT) += keyboard.o $(KEYMAP) $(KEYBD)
obj-$(CONFIG_VT) += keyboard.o $(KEYMAP)
obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o
obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o
......
This diff is collapsed.
This diff is collapsed.
......@@ -75,78 +75,6 @@ unsigned int video_scan_lines;
#define GPLAST 0x3df
#define GPNUM (GPLAST - GPFIRST + 1)
/*
* Generates sound of some frequency for some number of clock ticks
*
* If freq is 0, will turn off sound, else will turn it on for that time.
* If msec is 0, will return immediately, else will sleep for msec time, then
* turn sound off.
*
* We also return immediately, which is what was implied within the X
* comments - KDMKTONE doesn't put the process to sleep.
*/
#if defined(__i386__) || defined(__alpha__) || defined(__powerpc__) \
|| (defined(__mips__) && defined(CONFIG_ISA)) \
|| (defined(__arm__) && defined(CONFIG_HOST_FOOTBRIDGE)) \
|| defined(__x86_64__)
static void
kd_nosound(unsigned long ignored)
{
/* disable counter 2 */
outb(inb_p(0x61)&0xFC, 0x61);
return;
}
void
_kd_mksound(unsigned int hz, unsigned int ticks)
{
static struct timer_list sound_timer = { function: kd_nosound };
unsigned int count = 0;
unsigned long flags;
if (hz > 20 && hz < 32767)
count = 1193180 / hz;
local_irq_save(flags); // FIXME: is this safe?
del_timer(&sound_timer);
if (count) {
/* enable counter 2 */
outb_p(inb_p(0x61)|3, 0x61);
/* set command for counter 2, 2 byte write */
outb_p(0xB6, 0x43);
/* select desired HZ */
outb_p(count & 0xff, 0x42);
outb((count >> 8) & 0xff, 0x42);
if (ticks) {
sound_timer.expires = jiffies+ticks;
add_timer(&sound_timer);
}
} else
kd_nosound(0);
local_irq_restore(flags);
return;
}
#else
void
_kd_mksound(unsigned int hz, unsigned int ticks)
{
}
#endif
int _kbd_rate(struct kbd_repeat *rep)
{
return -EINVAL;
}
void (*kd_mksound)(unsigned int hz, unsigned int ticks) = _kd_mksound;
int (*kbd_rate)(struct kbd_repeat *rep) = _kbd_rate;
#define i (tmp.kb_index)
#define s (tmp.kb_table)
#define v (tmp.kb_value)
......
......@@ -15,16 +15,6 @@ CONFIG_INPUT
The module will be called input.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
CONFIG_INPUT_KEYBDEV
Say Y here if you want your keyboard to be able to serve as a system
keyboard. This is needed in most cases. The only exceptions are
headless and embedded systems.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called keybdev.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
CONFIG_INPUT_MOUSEDEV
Say Y here if you want your mouse to be accessible as char devices
13:32+ - /dev/input/mouseX and 13:63 - /dev/input/mice as an
......@@ -98,12 +88,3 @@ CONFIG_INPUT_EVBUG
inserted in and removed from the running kernel whenever you want).
The module will be called joydev.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
CONFIG_INPUT_UINPUT
Say Y here if you want to support user level drivers for input
subsystem accessible under char device 10:223 - /dev/input/uinput.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called uinput.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
......@@ -8,7 +8,6 @@ comment 'Input device support'
tristate 'Input core support' CONFIG_INPUT
comment 'Userland interfaces'
dep_tristate ' Keyboard interface' CONFIG_INPUT_KEYBDEV $CONFIG_INPUT
dep_tristate ' Mouse interface' CONFIG_INPUT_MOUSEDEV $CONFIG_INPUT
dep_mbool ' Provide legacy /dev/psaux device' CONFIG_INPUT_MOUSEDEV_PSAUX $CONFIG_INPUT
if [ "$CONFIG_INPUT_MOUSEDEV" != "n" ]; then
......@@ -23,7 +22,7 @@ if [ "$CONFIG_INPUT_TSDEV" != "n" ]; then
fi
dep_tristate ' Event interface' CONFIG_INPUT_EVDEV $CONFIG_INPUT
dep_tristate ' Event debugging' CONFIG_INPUT_EVBUG $CONFIG_INPUT
dep_tristate ' User level driver support (EXPERIMENTAL)' CONFIG_INPUT_UINPUT $CONFIG_INPUT $CONFIG_EXPERIMENTAL
comment 'Input I/O drivers'
source drivers/input/gameport/Config.in
......@@ -35,6 +34,7 @@ if [ "$CONFIG_INPUT" != "n" ]; then
source drivers/input/mouse/Config.in
source drivers/input/joystick/Config.in
source drivers/input/touchscreen/Config.in
source drivers/input/misc/Config.in
fi
endmenu
......@@ -9,19 +9,18 @@ export-objs := input.o
# Each configuration option enables a list of files.
obj-$(CONFIG_INPUT) += input.o
obj-$(CONFIG_INPUT_KEYBDEV) += keybdev.o
obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o
obj-$(CONFIG_INPUT_JOYDEV) += joydev.o
obj-$(CONFIG_INPUT_EVDEV) += evdev.o
obj-$(CONFIG_INPUT_TSDEV) += tsdev.o
obj-$(CONFIG_INPUT_POWER) += power.o
obj-$(CONFIG_INPUT_EVBUG) += evbug.o
obj-$(CONFIG_INPUT_UINPUT) += uinput.o
obj-$(CONFIG_INPUT_KEYBOARD) += keyboard/
obj-$(CONFIG_INPUT_MOUSE) += mouse/
obj-$(CONFIG_INPUT_JOYSTICK) += joystick/
obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/
obj-$(CONFIG_INPUT_MISC) += misc/
# The global Rules.make.
......
......@@ -234,7 +234,7 @@ static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
struct evdev *evdev = list->evdev;
struct input_dev *dev = evdev->handle.dev;
struct input_absinfo abs;
int t, u;
int i, t, u;
if (!evdev->exist) return -ENODEV;
......@@ -258,26 +258,21 @@ static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case EVIOCGKEYCODE:
if (get_user(t, ((int *) arg) + 0)) return -EFAULT;
if (t < 0 || t > dev->keycodemax) return -EINVAL;
switch (dev->keycodesize) {
case 1: u = *(u8*)(dev->keycode + t); break;
case 2: u = *(u16*)(dev->keycode + t * 2); break;
case 4: u = *(u32*)(dev->keycode + t * 4); break;
default: return -EINVAL;
}
if (put_user(u, ((int *) arg) + 1)) return -EFAULT;
if (t < 0 || t > dev->keycodemax || !dev->keycodesize) return -EINVAL;
if (put_user(INPUT_KEYCODE(dev, t), ((int *) arg) + 1)) return -EFAULT;
return 0;
case EVIOCSKEYCODE:
if (get_user(t, ((int *) arg) + 0)) return -EFAULT;
if (t < 0 || t > dev->keycodemax) return -EINVAL;
if (get_user(u, ((int *) arg) + 1)) return -EFAULT;
switch (dev->keycodesize) {
case 1: *(u8*)(dev->keycode + t) = u; break;
case 2: *(u16*)(dev->keycode + t * 2) = u; break;
case 4: *(u32*)(dev->keycode + t * 4) = u; break;
default: return -EINVAL;
}
if (t < 0 || t > dev->keycodemax || !dev->keycodesize) return -EINVAL;
u = INPUT_KEYCODE(dev, t);
if (get_user(INPUT_KEYCODE(dev, t), ((int *) arg) + 1)) return -EFAULT;
for (i = 0; i < dev->keycodemax; i++)
if(INPUT_KEYCODE(dev, t) == u) break;
if (i == dev->keycodemax) clear_bit(u, dev->keybit);
set_bit(INPUT_KEYCODE(dev, t), dev->keybit);
return 0;
case EVIOCSFF:
......
......@@ -105,7 +105,7 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
change_bit(code, dev->key);
if (test_bit(EV_REP, dev->evbit) && value) {
if (test_bit(EV_REP, dev->evbit) && dev->rep[REP_PERIOD] && value) {
dev->repeat_key = code;
mod_timer(&dev->timer, jiffies + dev->rep[REP_DELAY]);
}
......@@ -165,10 +165,9 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
case EV_SND:
if (code > SND_MAX || !test_bit(code, dev->sndbit) || !!test_bit(code, dev->snd) == value)
if (code > SND_MAX || !test_bit(code, dev->sndbit))
return;
change_bit(code, dev->snd);
if (dev->event) dev->event(dev, type, code, value);
break;
......
......@@ -203,13 +203,13 @@ CONFIG_JOYSTICK_TURBOGRAFX
The module will be called turbografx.o. If you want to compile it
as a module, say M here and read <file:Documentation/modules.txt>.
CONFIG_JOYSTICK_AMIJOY
CONFIG_JOYSTICK_AMIGA
Say Y here if you have an Amiga with a digital joystick connected
to it.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called joy-amiga.o. If you want to compile it as
The module will be called amijoy.o. If you want to compile it as
a module, say M here and read <file:Documentation/modules.txt>.
CONFIG_INPUT_JOYDUMP
......
......@@ -28,7 +28,7 @@ dep_tristate ' Multisystem, NES, SNES, N64, PSX joysticks and gamepads' CONFIG_
dep_tristate ' Multisystem joysticks via TurboGraFX device' CONFIG_JOYSTICK_TURBOGRAFX $CONFIG_INPUT $CONFIG_INPUT_JOYSTICK $CONFIG_PARPORT
if [ "$CONFIG_AMIGA" = "y" ]; then
dep_tristate ' Amiga joysticks' CONFIG_JOYSTICK_AMIJOY $CONFIG_INPUT $CONFIG_INPUT_JOYSTICK
dep_tristate ' Amiga joysticks' CONFIG_JOYSTICK_AMIGA $CONFIG_INPUT $CONFIG_INPUT_JOYSTICK
fi
dep_tristate ' Gameport data dumper' CONFIG_INPUT_JOYDUMP $CONFIG_INPUT $CONFIG_INPUT_JOYSTICK
......@@ -37,6 +37,7 @@
#include <asm/system.h>
#include <asm/amigahw.h>
#include <asm/amigaints.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Driver for Amiga joysticks");
......@@ -78,13 +79,13 @@ static int amijoy_open(struct input_dev *dev)
if ((*used)++)
return 0;
if (request_irq(IRQ_AMIGA_VERTB, amijoy_interrupt, 0, "amijoy", NULL)) {
if (request_irq(IRQ_AMIGA_VERTB, amijoy_interrupt, 0, "amijoy", amijoy_interrupt)) {
(*used)--;
printk(KERN_ERR "amijoy.c: Can't allocate irq %d\n", amijoy_irq);
printk(KERN_ERR "amijoy.c: Can't allocate irq %d\n", IRQ_AMIGA_VERTB);
return -EBUSY;
}
return 0;
}
......@@ -99,8 +100,9 @@ static void amijoy_close(struct input_dev *dev)
static int __init amijoy_setup(char *str)
{
int i;
int ints[4]
str = get_options(str, ARRAY_SIZE(ints), ints);
int ints[4];
str = get_options(str, ARRAY_SIZE(ints), ints);
for (i = 0; i <= ints[0] && i < 2; i++) amijoy[i] = ints[i+1];
return 1;
}
......@@ -110,9 +112,6 @@ static int __init amijoy_init(void)
{
int i, j;
init_timer(amijoy_timer);
port->timer.function = amijoy_timer;
for (i = 0; i < 2; i++)
if (amijoy[i]) {
if (!request_mem_region(CUSTOM_PHYSADDR+10+i*2, 2,
......@@ -134,12 +133,12 @@ static int __init amijoy_init(void)
amijoy_dev[i].absmax[ABS_X + j] = 1;
}
amijoy->dev[i].name = amijoy_name;
amijoy->dev[i].phys = amijoy_phys[i];
amijoy->dev[i].id.bustype = BUS_AMIGA;
amijoy->dev[i].id.vendor = 0x0001;
amijoy->dev[i].id.product = 0x0003;
amijoy->dev[i].id.version = 0x0100;
amijoy_dev[i].name = amijoy_name;
amijoy_dev[i].phys = amijoy_phys[i];
amijoy_dev[i].id.bustype = BUS_AMIGA;
amijoy_dev[i].id.vendor = 0x0001;
amijoy_dev[i].id.product = 0x0003;
amijoy_dev[i].id.version = 0x0100;
amijoy_dev[i].private = amijoy_used + i;
......@@ -149,7 +148,7 @@ static int __init amijoy_init(void)
return 0;
}
static void _exit amijoy_exit(void)
static void __exit amijoy_exit(void)
{
int i;
......
/*
* $Id: keybdev.c,v 1.19 2002/03/13 10:09:20 vojtech Exp $
*
* Copyright (c) 1999-2001 Vojtech Pavlik
*
* Input core to console keyboard binding.
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/config.h>
#include <linux/kbd_ll.h>
#include <linux/input.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/kbd_kern.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Input core to console keyboard binding");
MODULE_LICENSE("GPL");
char keybdev_name[] = "keyboard";
#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(__alpha__) || \
defined(__mips__) || defined(CONFIG_SPARC64) || defined(CONFIG_SUPERH) || \
defined(CONFIG_PPC) || defined(__mc68000__) || defined(__hppa__) || \
defined(__arm__) || defined(__x86_64__)
static int x86_sysrq_alt = 0;
#ifdef CONFIG_SPARC64
static int sparc_l1_a_state = 0;
#endif
static unsigned short x86_keycodes[256] =
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 43, 85, 86, 87, 88,115,119,120,121,375,123, 90,
284,285,309,298,312, 91,327,328,329,331,333,335,336,337,338,339,
367,294,293,286,350, 92,334,512,116,377,109,111,373,347,348,349,
360, 93, 94, 95, 98,376,100,101,357,316,354,304,289,102,351,355,
103,104,105,275,281,272,306,106,274,107,288,364,358,363,362,361,
291,108,381,290,287,292,279,305,280, 99,112,257,258,113,270,114,
118,117,125,374,379,115,112,125,121,123,264,265,266,267,268,269,
271,273,276,277,278,282,283,295,296,297,299,300,301,302,303,307,
308,310,313,314,315,317,318,319,320,321,322,323,324,325,326,330,
332,340,341,342,343,344,345,346,356,359,365,368,369,370,371,372 };
#ifdef CONFIG_MAC_EMUMOUSEBTN
extern int mac_hid_mouse_emulate_buttons(int, int, int);
#endif /* CONFIG_MAC_EMUMOUSEBTN */
static int emulate_raw(unsigned int keycode, int down)
{
#ifdef CONFIG_MAC_EMUMOUSEBTN
if (mac_hid_mouse_emulate_buttons(1, keycode, down))
return 0;
#endif /* CONFIG_MAC_EMUMOUSEBTN */
if (keycode > 255 || !x86_keycodes[keycode])
return -1;
if (keycode == KEY_PAUSE) {
handle_scancode(0xe1, 1);
handle_scancode(0x1d, down);
handle_scancode(0x45, down);
return 0;
}
if (keycode == KEY_SYSRQ && x86_sysrq_alt) {
handle_scancode(0x54, down);
return 0;
}
#ifdef CONFIG_SPARC64
if (keycode == KEY_A && sparc_l1_a_state) {
sparc_l1_a_state = 0;
sun_do_break();
}
#endif
if (x86_keycodes[keycode] & 0x100)
handle_scancode(0xe0, 1);
handle_scancode(x86_keycodes[keycode] & 0x7f, down);
if (keycode == KEY_SYSRQ) {
handle_scancode(0xe0, 1);
handle_scancode(0x37, down);
}
if (keycode == KEY_LEFTALT || keycode == KEY_RIGHTALT)
x86_sysrq_alt = down;
#ifdef CONFIG_SPARC64
if (keycode == KEY_STOP)
sparc_l1_a_state = down;
#endif
return 0;
}
#endif /* CONFIG_X86 || CONFIG_IA64 || __alpha__ || __mips__ || CONFIG_PPC */
static struct input_handler keybdev_handler;
void keybdev_ledfunc(unsigned int led)
{
struct input_handle *handle;
for (handle = keybdev_handler.handle; handle; handle = handle->hnext) {
input_event(handle->dev, EV_LED, LED_SCROLLL, !!(led & 0x01));
input_event(handle->dev, EV_LED, LED_NUML, !!(led & 0x02));
input_event(handle->dev, EV_LED, LED_CAPSL, !!(led & 0x04));
input_sync(handle->dev);
}
}
/* Tell the user who may be running in X and not see the console that we have
panic'ed. This is to distingush panics from "real" lockups.
Could in theory send the panic message as morse, but that is left as an
exercise for the reader. */
void panic_blink(void)
{
static unsigned long last_jiffie;
static char led;
/* Roughly 1/2s frequency. KDB uses about 1s. Make sure it is different. */
if (time_after(jiffies, last_jiffie + HZ/2)) {
led ^= 0x01 | 0x04;
keybdev_ledfunc(led);
last_jiffie = jiffies;
}
}
void keybdev_event(struct input_handle *handle, unsigned int type, unsigned int code, int down)
{
if (type != EV_KEY) return;
emulate_raw(code, down);
tasklet_schedule(&keyboard_tasklet);
}
static struct input_handle *keybdev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
{
struct input_handle *handle;
int i;
for (i = KEY_ESC; i < BTN_MISC; i++)
if (test_bit(i, dev->keybit))
break;
if (i == BTN_MISC)
return NULL;
if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL)))
return NULL;
memset(handle, 0, sizeof(struct input_handle));
handle->dev = dev;
handle->name = keybdev_name;
handle->handler = handler;
input_open_device(handle);
return handle;
}
static void keybdev_disconnect(struct input_handle *handle)
{
input_close_device(handle);
kfree(handle);
}
static struct input_device_id keybdev_ids[] = {
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
.evbit = { BIT(EV_KEY) },
},
{ }, /* Terminating entry */
};
MODULE_DEVICE_TABLE(input, keybdev_ids);
static struct input_handler keybdev_handler = {
.event = keybdev_event,
.connect = keybdev_connect,
.disconnect = keybdev_disconnect,
.name = "keybdev",
.id_table = keybdev_ids,
};
static int __init keybdev_init(void)
{
input_register_handler(&keybdev_handler);
kbd_ledfunc = keybdev_ledfunc;
return 0;
}
static void __exit keybdev_exit(void)
{
kbd_ledfunc = NULL;
input_unregister_handler(&keybdev_handler);
}
module_init(keybdev_init);
module_exit(keybdev_exit);
......@@ -34,6 +34,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/delay.h>
#include <asm/amigaints.h>
#include <asm/amigahw.h>
......@@ -51,9 +52,9 @@ static unsigned char amikbd_keycode[0x78] = {
57, 14, 15, 96, 28, 1,111, 0, 0, 0, 74, 0,103,108,106,105,
59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 98, 55, 78, 87,
42, 54, 58, 29, 56,100
}
};
static char *amikbd_messages[] = {
static const char *amikbd_messages[8] = {
KERN_ALERT "amikbd: Ctrl-Amiga-Amiga reset warning!!\n",
KERN_WARNING "amikbd: keyboard lost sync\n",
KERN_WARNING "amikbd: keyboard buffer overflow\n",
......@@ -79,19 +80,19 @@ static void amikbd_interrupt(int irq, void *dummy, struct pt_regs *fp)
ciaa.cra &= ~0x40; /* switch CIA serial port to input mode */
down = scancode & 1; /* lowest bit is release bit */
scancode = scancode >> 1;
scancode >>= 1;
if (scancode < 0x78) { /* scancodes < 0x78 are keys */
scancode = amikbd_keycode[scancode];
if (scancode == KEY_CAPS) { /* CapsLock is a toggle switch key on Amiga */
if (scancode == KEY_CAPSLOCK) { /* CapsLock is a toggle switch key on Amiga */
input_report_key(&amikbd_dev, scancode, 1);
input_report_key(&amikbd_dev, scancode, 0);
input_sync(&amikbd_dev);
return;
}
input_report_key(&amikbd_dev, scancode, down);
input_sync(&amikbd_dev);
......@@ -106,20 +107,22 @@ static int __init amikbd_init(void)
int i;
if (!AMIGAHW_PRESENT(AMI_KEYBOARD))
return -EIO;
return -EIO;
if (!request_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100, "amikeyb"))
if (!request_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100, "amikeyb"))
return -EBUSY;
amikbd_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
amikbd_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
amikbd_dev.keycode = amikbd_keycode;
for (i = 0; i < 0x78; i++)
amikbd_dev.keycodesize = sizeof(unsigned char);
amikbd_dev.keycodemax = ARRAY_SIZE(amikbd_keycode);
for (i = 0; i < 0x78; i++)
if (amikbd_keycode[i])
set_bit(amikbd_keycode[i], amikbd_dev.keybit);
ciaa.cra &= ~0x41; /* serial data in, turn off TA */
request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", NULL);
request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", amikbd_interrupt);
amikbd_dev.name = amikbd_name;
amikbd_dev.phys = amikbd_phys;
......
......@@ -470,6 +470,8 @@ static void atkbd_connect(struct serio *serio, struct serio_dev *dev)
atkbd->serio = serio;
atkbd->dev.keycode = atkbd->keycode;
atkbd->dev.keycodesize = sizeof(unsigned char);
atkbd->dev.keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
atkbd->dev.event = atkbd_event;
atkbd->dev.private = atkbd;
......
......@@ -94,6 +94,8 @@ void nkbd_connect(struct serio *serio, struct serio_dev *dev)
nkbd->serio = serio;
nkbd->dev.keycode = nkbd->keycode;
nkbd->dev.keycodesize = sizeof(unsigned char);
nkbd->dev.keycodemax = ARRAY_SIZE(nkbd_keycode);
nkbd->dev.private = nkbd;
serio->private = nkbd;
......
......@@ -245,6 +245,9 @@ static void sunkbd_connect(struct serio *serio, struct serio_dev *dev)
sunkbd->tq.data = sunkbd;
sunkbd->dev.keycode = sunkbd->keycode;
sunkbd->dev.keycodesize = sizeof(unsigned char);
sunkbd->dev.keycodemax = ARRAY_SIZE(sunkbd_keycode);
sunkbd->dev.event = sunkbd_event;
sunkbd->dev.private = sunkbd;
......
......@@ -101,6 +101,8 @@ void xtkbd_connect(struct serio *serio, struct serio_dev *dev)
xtkbd->serio = serio;
xtkbd->dev.keycode = xtkbd->keycode;
xtkbd->dev.keycodesize = sizeof(unsigned char);
xtkbd->dev.keycodemax = ARRAY_SIZE(xtkbd_keycode);
xtkbd->dev.private = xtkbd;
serio->private = xtkbd;
......
CONFIG_INPUT_MISC
Say Y here, and a list of miscellaneous input drivers will be displayed.
Everything that didn't fit into the other categories is here. This option
doesn't affect the kernel.
If unsure, say Y.
CONFIG_INPUT_PCSPKR
Say Y here if you want the standard PC Speaker to be used for
bells and whistles.
If unsure, say Y.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called pcspkr.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
CONFIG_INPUT_UINPUT
Say Y here if you want to support user level drivers for input
subsystem accessible under char device 10:223 - /dev/input/uinput.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called uinput.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
#
# Input misc drivers configuration
#
bool 'Misc' CONFIG_INPUT_MISC
dep_tristate ' PC Speaker support' CONFIG_INPUT_PCSPKR $CONFIG_INPUT $CONFIG_INPUT_MISC
dep_tristate ' User level driver support' CONFIG_INPUT_UINPUT $CONFIG_INPUT $CONFIG_INPUT_MISC
#
# Makefile for the input misc drivers.
#
# Each configuration option enables a list of files.
obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o
obj-$(CONFIG_INPUT_UINPUT) += uinput.o
# The global Rules.make.
include $(TOPDIR)/Rules.make
This diff is collapsed.
......@@ -64,7 +64,7 @@ static void amimouse_interrupt(int irq, void *dummy, struct pt_regs *fp)
input_report_rel(&amimouse_dev, REL_X, dx);
input_report_rel(&amimouse_dev, REL_Y, dy);
input_report_key(&amimouse_dev, BTN_LEFT, ciaa.pra & 0x40);
input_report_key(&amimouse_dev, BTN_MIDDLE, potgor & 0x0100);
input_report_key(&amimouse_dev, BTN_RIGHT, potgor & 0x0400);
......@@ -84,9 +84,9 @@ static int amimouse_open(struct input_dev *dev)
amimouse_lastx = joy0dat & 0xff;
amimouse_lasty = joy0dat >> 8;
if (request_irq(IRQ_AMIGA_VERTB, amimouse_interrupt, 0, "amimouse", NULL)) {
if (request_irq(IRQ_AMIGA_VERTB, amimouse_interrupt, 0, "amimouse", amimouse_interrupt)) {
amimouse_used--;
printk(KERN_ERR "amimouse.c: Can't allocate irq %d\n", amimouse_irq);
printk(KERN_ERR "amimouse.c: Can't allocate irq %d\n", IRQ_AMIGA_VERTB);
return -EBUSY;
}
......@@ -116,10 +116,11 @@ static int __init amimouse_init(void)
amimouse_dev.id.vendor = 0x0001;
amimouse_dev.id.product = 0x0002;
amimouse_dev.id.version = 0x0100;
input_register_device(&amimouse_dev);
printk(KERN_INFO "input: %s at joy0dat\n", amimouse_name);
return 0;
}
static void __exit amimouse_exit(void)
......
This diff is collapsed.
......@@ -20,7 +20,7 @@ obj-$(CONFIG_MAC_SERIAL) += macserial.o
ifneq ($(CONFIG_MAC),y)
obj-$(CONFIG_NVRAM) += nvram.o
endif
obj-$(CONFIG_MAC_HID) += mac_hid.o
obj-$(CONFIG_MAC_EMUMOUSEBTN) += mac_hid.o
obj-$(CONFIG_INPUT_ADBHID) += adbhid.o
obj-$(CONFIG_PPC_RTC) += rtc.o
obj-$(CONFIG_ANSLCD) += ans-lcd.o
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -97,6 +97,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <asm/processor.h>
#include <linux/ethtool.h>
#include <linux/inetdevice.h>
#include <linux/bitops.h>
#include <linux/if.h>
#include <asm/uaccess.h>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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