diff options
| author | Greg Kroah-Hartman <greg@kroah.com> | 2002-07-16 20:29:40 -0700 |
|---|---|---|
| committer | Greg Kroah-Hartman <greg@kroah.com> | 2002-07-16 20:29:40 -0700 |
| commit | 5a93c398a3aee83e17a5dd41788aa267ba92522a (patch) | |
| tree | 16db00f7fdf3ff471d4b651bfec632050ef25393 | |
| parent | a37481fec94859420d6ec3f4ec1e2cd676d8b1bd (diff) | |
| parent | 0d84f0acc5c914fbd249b2611711517f5c001a0c (diff) | |
Merge kroah.com:/home/greg/linux/BK/bleeding_edge-2.5
into kroah.com:/home/greg/linux/BK/agpgart-2.5
112 files changed, 945 insertions, 570 deletions
@@ -199,12 +199,10 @@ S: Notre Dame, Indiana S: USA N: Greg Banks -E: gnb@linuxfan.com +E: gnb@alphalink.com.au D: IDT77105 ATM network driver -S: NEC Australia -S: 649-655 Springvale Rd -S: Mulgrave, Victoria 3170 -S: Australia +D: some SuperH port work +D: some trivial futzing with kconfig N: James Banks E: james@sovereign.org diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl index 9794214be48c..24fe8d39cef0 100644 --- a/Documentation/DocBook/kernel-api.tmpl +++ b/Documentation/DocBook/kernel-api.tmpl @@ -46,9 +46,13 @@ !Iinclude/asm-i386/unaligned.h </sect1> +<!-- FIXME: + kernel/sched.c has no docs, which stuffs up the sgml. Comment + out until somebody adds docs. KAO <sect1><title>Delaying, scheduling, and timer routines</title> !Ekernel/sched.c </sect1> +KAO --> </chapter> <chapter id="adt"> @@ -358,9 +362,13 @@ <sect1><title>Frame Buffer Colormap</title> !Edrivers/video/fbcmap.c </sect1> +<!-- FIXME: + drivers/video/fbgen.c has no docs, which stuffs up the sgml. Comment + out until somebody adds docs. KAO <sect1><title>Frame Buffer Generic Functions</title> !Idrivers/video/fbgen.c </sect1> +KAO --> <sect1><title>Frame Buffer Video Mode Database</title> !Idrivers/video/modedb.c !Edrivers/video/modedb.c diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index 4f48032c79dd..4d6251862bfd 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -161,7 +161,7 @@ you to re-send them using MIME. When sending patches to Linus, always follow step #6. Large changes are not appropriate for mailing lists, and some -maintainers. If your patch, uncompressed, exceeds 40Kb in size, +maintainers. If your patch, uncompressed, exceeds 40 kB in size, it is preferred that you store your patch on an Internet-accessible server, and provide instead a URL (link) pointing to your patch. diff --git a/Documentation/filesystems/ntfs.txt b/Documentation/filesystems/ntfs.txt index 8b46088b1265..52f10c999094 100644 --- a/Documentation/filesystems/ntfs.txt +++ b/Documentation/filesystems/ntfs.txt @@ -247,6 +247,11 @@ ChangeLog Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog. +2.0.21: + These only affect 32-bit architectures: + - Check for, and refuse to mount too large volumes (maximum is 2TiB). + - Check for, and refuse to open too large files and directories + (maximum is 16TiB). 2.0.20: - Support non-resident directory index bitmaps. This means we now cope with huge directories without problems. diff --git a/Documentation/usb/hiddev.txt b/Documentation/usb/hiddev.txt index 31250f38b45f..470840b5be5f 100644 --- a/Documentation/usb/hiddev.txt +++ b/Documentation/usb/hiddev.txt @@ -18,7 +18,7 @@ normalised event interface - see Documentation/input/input.txt The data flow for a HID event produced by a device is something like the following : - usb.c ---> hid-core.c ----> input.c ----> [keyboard/mouse/joystick/event] + usb.c ---> hid-core.c ----> hid-input.c ----> [keyboard/mouse/joystick/event] | | --> hiddev.c ----> POWER / MONITOR CONTROL @@ -106,6 +106,15 @@ returns -1. You can find out beforehand how many application collections the device has from the num_applications field from the hiddev_devinfo structure. +HIDIOCGCOLLECTIONINFO - struct hiddev_collection_info (read/write) +This returns a superset of the information above, providing not only +application collections, but all the collections the device has. It +also returns the level the collection lives in the hierarchy. +The user passes in a hiddev_collection_info struct with the index +field set to the index that should be returned. The ioctl fills in +the other fields. If the index is larger than the last collection +index, the ioctl returns -1 and sets errno to -EINVAL. + HIDIOCGDEVINFO - struct hiddev_devinfo (read) Gets a hiddev_devinfo structure which describes the device. @@ -172,6 +181,10 @@ Sets the value of a usage in an output report. The user fills in the hiddev_usage_ref structure as above, but additionally fills in the value field. +HIDIOGCOLLECTIONINDEX - struct hiddev_usage_ref (write) +Returns the collection index associated with this usage. This +indicates where in the collection hierarchy this usage sits. + HIDIOCGFLAG - int (read) HIDIOCSFLAG - int (write) These operations respectively inspect and replace the mode flags diff --git a/Documentation/video4linux/meye.txt b/Documentation/video4linux/meye.txt index bc6bf4aa2d10..6b22fcb7aa51 100644 --- a/Documentation/video4linux/meye.txt +++ b/Documentation/video4linux/meye.txt @@ -86,7 +86,7 @@ Private API: MEYEIOC_SYNC Takes as an argument the buffer number you want to sync. - This ioctl blocks untils the buffer is filled and ready + This ioctl blocks until the buffer is filled and ready for the application to use. It returns the buffer size. MEYEIOC_STILLCAPT @@ -106,7 +106,7 @@ Bugs / Todo: - mjpeg hardware playback doesn't work (depends on overlay...) - - rewrite the driver to use some commun video4linux API for snapshot + - rewrite the driver to use some common video4linux API for snapshot and mjpeg capture. Unfortunately, video4linux1 does not permit it, the BUZ API seems to be targeted to TV cards only. The video4linux 2 API may be an option, if it goes into the kernel (maybe 2.5 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 5 -SUBLEVEL = 25 +SUBLEVEL = 26 EXTRAVERSION = # *DOCUMENTATION* diff --git a/arch/alpha/config.in b/arch/alpha/config.in index 478a8f15939a..b12f8b7b38ed 100644 --- a/arch/alpha/config.in +++ b/arch/alpha/config.in @@ -235,9 +235,9 @@ if [ "$CONFIG_SMP" = "y" ]; then fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool 'Discontiguous Memory Support' CONFIG_DISCONTIGMEM + bool 'Discontiguous Memory Support (EXPERIMENTAL)' CONFIG_DISCONTIGMEM if [ "$CONFIG_DISCONTIGMEM" = "y" ]; then - bool ' NUMA Support' CONFIG_NUMA + bool ' NUMA Support (EXPERIMENTAL)' CONFIG_NUMA fi fi diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c index 565d4af63843..839dffd2e077 100644 --- a/arch/alpha/kernel/signal.c +++ b/arch/alpha/kernel/signal.c @@ -36,36 +36,6 @@ static int do_signal(sigset_t *, struct pt_regs *, struct switch_stack *, unsigned long, unsigned long); -int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) -{ - if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) - return -EFAULT; - if (from->si_code < 0) - return __copy_to_user(to, from, sizeof(siginfo_t)); - else { - int err; - - /* If you change siginfo_t structure, please be sure - this code is fixed accordingly. - It should never copy any pad contained in the structure - to avoid security leaks, but must copy the generic - 3 ints plus the relevant union member. */ - err = __put_user(*(long *)&from->si_signo, (long *)&to->si_signo); - err |= __put_user((short)from->si_code, &to->si_code); - switch (from->si_code >> 16) { - case __SI_CHLD >> 16: - err |= __put_user(from->si_utime, &to->si_utime); - err |= __put_user(from->si_stime, &to->si_stime); - err |= __put_user(from->si_status, &to->si_status); - default: - err |= __put_user(from->si_addr, &to->si_addr); - break; - /* case __SI_RT: This is not generated by the kernel as of now. */ - } - return err; - } -} - /* * The OSF/1 sigprocmask calling sequence is different from the * C sigprocmask() sequence.. diff --git a/arch/cris/kernel/signal.c b/arch/cris/kernel/signal.c index 2e75f5c0298e..bfd339c104d2 100644 --- a/arch/cris/kernel/signal.c +++ b/arch/cris/kernel/signal.c @@ -43,42 +43,6 @@ int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs); -int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) -{ - if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) - return -EFAULT; - if (from->si_code < 0) - return __copy_to_user(to, from, sizeof(siginfo_t)); - else { - int err; - - /* If you change siginfo_t structure, please be sure - this code is fixed accordingly. - It should never copy any pad contained in the structure - to avoid security leaks, but must copy the generic - 3 ints plus the relevant union member. */ - err = __put_user(from->si_signo, &to->si_signo); - err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); - /* First 32bits of unions are always present. */ - err |= __put_user(from->si_pid, &to->si_pid); - switch (from->si_code >> 16) { - case __SI_FAULT >> 16: - err |= __put_user(from->si_addr, &to->si_addr); - break; - case __SI_CHLD >> 16: - err |= __put_user(from->si_utime, &to->si_utime); - err |= __put_user(from->si_stime, &to->si_stime); - err |= __put_user(from->si_status, &to->si_status); - default: - err |= __put_user(from->si_uid, &to->si_uid); - break; - /* case __SI_RT: This is not generated by the kernel as of now. */ - } - return err; - } -} - /* * Atomically swap in the new signal mask, and wait for a signal. Define * dummy arguments to be able to reach the regs argument. (Note that this diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c index bbefb67d5d65..42ce2febe8b7 100644 --- a/arch/i386/boot/compressed/misc.c +++ b/arch/i386/boot/compressed/misc.c @@ -99,15 +99,11 @@ static long bytes_out = 0; static uch *output_data; static unsigned long output_ptr = 0; - static void *malloc(int size); static void free(void *where); -static void error(char *m); -static void gzip_mark(void **); -static void gzip_release(void **); - + static void puts(const char *); - + extern int end; static long free_mem_ptr = (long)&end; static long free_mem_end_ptr; diff --git a/arch/i386/config.in b/arch/i386/config.in index 7c9e4e11aced..0a35c2b5638c 100644 --- a/arch/i386/config.in +++ b/arch/i386/config.in @@ -407,7 +407,7 @@ source net/bluetooth/Config.in mainmenu_option next_comment comment 'Kernel hacking' if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - dep_bool 'Software Suspend' CONFIG_SOFTWARE_SUSPEND $CONFIG_PM + dep_bool 'Software Suspend (EXPERIMENTAL)' CONFIG_SOFTWARE_SUSPEND $CONFIG_PM fi bool 'Kernel debugging' CONFIG_DEBUG_KERNEL diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index 2f85a84ee4a7..c86358a1249f 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c @@ -1058,7 +1058,7 @@ inline void smp_local_timer_interrupt(struct pt_regs * regs) /* * Local APIC timer interrupt. This is the most natural way for doing * local interrupts, but local timer interrupts can be emulated by - * broadcast interrupts too. [in case the hw doesnt support APIC timers] + * broadcast interrupts too. [in case the hw doesn't support APIC timers] * * [ if a single-CPU system runs an SMP kernel then we call the local * interrupt as well. Thus we cannot inline the local irq ... ] diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 95530e701b4d..8b30e6628f3b 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -15,9 +15,6 @@ static int disable_x86_fxsr __initdata = 0; struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {}; -static struct cpu_dev default_cpu; -static struct cpu_dev * this_cpu = &default_cpu; - extern void mcheck_init(struct cpuinfo_x86 *c); static void default_init(struct cpuinfo_x86 * c) @@ -36,6 +33,7 @@ static void default_init(struct cpuinfo_x86 * c) static struct cpu_dev default_cpu = { c_init: default_init, }; +static struct cpu_dev * this_cpu = &default_cpu; static int __init cachesize_setup(char *str) { diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 8ae4bb7bf9b2..d09e00d867da 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -219,6 +219,7 @@ extern unsigned long irq_affinity [NR_IRQS]; #define IRQ_ALLOWED(cpu,allowed_mask) \ ((1 << cpu) & (allowed_mask)) +#if CONFIG_SMP static unsigned long move(int curr_cpu, unsigned long allowed_mask, unsigned long now, int direction) { int search_idle = 1; @@ -247,7 +248,6 @@ inside: static inline void balance_irq(int irq) { -#if CONFIG_SMP irq_balance_t *entry = irq_balance + irq; unsigned long now = jiffies; @@ -263,8 +263,10 @@ static inline void balance_irq(int irq) entry->cpu = move(entry->cpu, allowed_mask, now, random_number); set_ioapic_affinity(irq, 1 << entry->cpu); } -#endif } +#else /* !SMP */ +static inline void balance_irq(int irq) { } +#endif /* * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c index 8dec19f4f58d..0a3aab887fac 100644 --- a/arch/i386/kernel/mpparse.c +++ b/arch/i386/kernel/mpparse.c @@ -779,7 +779,7 @@ void __init find_intel_smp (void) /* * The Visual Workstation is Intel MP compliant in the hardware - * sense, but it doesnt have a BIOS(-configuration table). + * sense, but it doesn't have a BIOS(-configuration table). * No problem for Linux. */ void __init find_visws_smp(void) diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index 329611c2bf13..2098fcf2679a 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -67,7 +67,7 @@ * an L1cache=Writethrough or L1cache=off option. * * B stepping CPUs may hang. There are hardware work arounds - * for this. We warn about it in case your board doesnt have the work + * for this. We warn about it in case your board doesn't have the work * arounds. Basically thats so I can tell anyone with a B stepping * CPU and SMP problems "tough". * diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 8ab6419b0c68..ce90cf20bc9c 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -291,7 +291,7 @@ void __init paging_init(void) #if CONFIG_X86_PAE /* - * We will bail out later - printk doesnt work right now so + * We will bail out later - printk doesn't work right now so * the user would just see a hanging kernel. */ if (cpu_has_pae) diff --git a/arch/ia64/sn/fakeprom/README b/arch/ia64/sn/fakeprom/README index 263c2a8b4624..0b214654f7c2 100644 --- a/arch/ia64/sn/fakeprom/README +++ b/arch/ia64/sn/fakeprom/README @@ -71,7 +71,7 @@ amount of memory present on nodes 0-3. 1GB*<dn>, where dn is the digit number. The amount of memory is 8MB*2**<d>. (If <d> = 0, the memory size is 0). - SN1 doesnt support dimms this small but small memory systems + SN1 doesn't support dimms this small but small memory systems boot faster on Medusa. diff --git a/arch/m68k/config.in b/arch/m68k/config.in index 165b785a3c43..02cf4d3d8149 100644 --- a/arch/m68k/config.in +++ b/arch/m68k/config.in @@ -522,7 +522,7 @@ endmenu mainmenu_option next_comment comment 'Sound support' -tristate 'Sound support' CONFIG_SOUND +tristate 'Sound card support' CONFIG_SOUND if [ "$CONFIG_SOUND" != "n" ]; then source sound/oss/dmasound/Config.in fi diff --git a/arch/mips/config.in b/arch/mips/config.in index 7455726be367..d90ee3b08d68 100644 --- a/arch/mips/config.in +++ b/arch/mips/config.in @@ -12,13 +12,13 @@ source init/Config.in mainmenu_option next_comment comment 'Machine selection' if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool 'Support for Acer PICA 1 chipset' CONFIG_ACER_PICA_61 + bool 'Support for Acer PICA 1 chipset (EXPERIMENTAL)' CONFIG_ACER_PICA_61 bool 'Support for Algorithmics P4032 (EXPERIMENTAL)' CONFIG_ALGOR_P4032 bool 'Support for BAGET MIPS series (EXPERIMENTAL)' CONFIG_BAGET_MIPS bool 'Support for DECstations (EXPERIMENTAL)' CONFIG_DECSTATION bool 'Support for NEC DDB Vrc-5074 (EXPERIMENTAL)' CONFIG_DDB5074 - bool 'Support for Galileo EV96100 Evaluation board' CONFIG_MIPS_EV96100 - bool 'Support for Galileo EV64120 Evaluation board' CONFIG_MIPS_EV64120 + bool 'Support for Galileo EV96100 Evaluation board (EXPERIMENTAL)' CONFIG_MIPS_EV96100 + bool 'Support for Galileo EV64120 Evaluation board (EXPERIMENTAL)' CONFIG_MIPS_EV64120 if [ "$CONFIG_MIPS_EV64120" = "y" ]; then bool 'Enable Second PCI (PCI1)' CONFIG_EVB_PCI1 choice 'Galileo Chip Clock' \ @@ -26,8 +26,8 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then 83.3 CONFIG_SYSCLK_83\ 100 CONFIG_SYSCLK_100" CONFIG_SYSCLK_83 fi - bool 'Support for MIPS Atlas board' CONFIG_MIPS_ATLAS - bool 'Support for MIPS Malta board' CONFIG_MIPS_MALTA + bool 'Support for MIPS Atlas board (EXPERIMENTAL)' CONFIG_MIPS_ATLAS + bool 'Support for MIPS Malta board (EXPERIMENTAL)' CONFIG_MIPS_MALTA bool 'Support for Philips Nino (EXPERIMENTAL)' CONFIG_NINO if [ "$CONFIG_NINO" = "y" ]; then choice 'Nino Model Number' \ diff --git a/arch/mips/dec/wbflush.c b/arch/mips/dec/wbflush.c index 380aafa680a1..dcb7f7d33cbc 100644 --- a/arch/mips/dec/wbflush.c +++ b/arch/mips/dec/wbflush.c @@ -97,7 +97,7 @@ static void wbflush_kn02ba(void) } /* - * The DS500/2x0 doesnt need to write back the WB. + * The DS500/2x0 doesn't need to write back the WB. */ static void wbflush_kn03(void) { diff --git a/arch/mips64/math-emu/ieee754.c b/arch/mips64/math-emu/ieee754.c index 5e86e40c678f..3571107088b1 100644 --- a/arch/mips64/math-emu/ieee754.c +++ b/arch/mips64/math-emu/ieee754.c @@ -3,7 +3,7 @@ * * BUGS * not much dp done - * doesnt generate IEEE754_INEXACT + * doesn't generate IEEE754_INEXACT * */ /* diff --git a/arch/parisc/config.in b/arch/parisc/config.in index bdebbf28a828..56e1f3e90166 100644 --- a/arch/parisc/config.in +++ b/arch/parisc/config.in @@ -24,14 +24,14 @@ bool 'Kernel Debugger support' CONFIG_KWDB # bool 'GSC/Gecko bus support' CONFIG_GSC y define_bool CONFIG_GSC y -bool 'U2/Uturn I/O MMU' CONFIG_IOMMU_CCIO y -bool 'LASI I/O support' CONFIG_GSC_LASI y +bool 'U2/Uturn I/O MMU' CONFIG_IOMMU_CCIO +bool 'LASI I/O support' CONFIG_GSC_LASI -bool 'PCI support' CONFIG_PCI y +bool 'PCI support' CONFIG_PCI if [ "$CONFIG_PCI" = "y" ]; then - bool 'GSCtoPCI/DINO PCI support' CONFIG_GSC_DINO y - bool 'LBA/Elroy PCI support' CONFIG_PCI_LBA n + bool 'GSCtoPCI/DINO PCI support' CONFIG_GSC_DINO + bool 'LBA/Elroy PCI support' CONFIG_PCI_LBA fi if [ "$CONFIG_PCI_LBA" = "y" ]; then diff --git a/arch/ppc/config.in b/arch/ppc/config.in index 71c362b18343..47d44bbd3fc2 100644 --- a/arch/ppc/config.in +++ b/arch/ppc/config.in @@ -475,7 +475,7 @@ endmenu mainmenu_option next_comment comment 'Console drivers' if [ "$CONFIG_4xx" != "y" -a "$CONFIG_8xx" != "y" ]; then - bool 'Support for VGA Console' CONFIG_VGA_CONSOLE + bool 'VGA text console' CONFIG_VGA_CONSOLE fi source drivers/video/Config.in if [ "$CONFIG_FB" = "y" -a "$CONFIG_ALL_PPC" = "y" ]; then diff --git a/arch/ppc64/kernel/pSeries_pci.c b/arch/ppc64/kernel/pSeries_pci.c index 44d9dd02b2ff..526cd444ae00 100644 --- a/arch/ppc64/kernel/pSeries_pci.c +++ b/arch/ppc64/kernel/pSeries_pci.c @@ -491,7 +491,7 @@ alloc_phb(struct device_node *dev, char *model, unsigned int addr_size_words) 0x100000); /* - * Firmware doesnt always clear this bit which is critical + * Firmware doesn't always clear this bit which is critical * for good performance - Anton */ { diff --git a/arch/sh/config.in b/arch/sh/config.in index 136513eeb6e5..07681448d732 100644 --- a/arch/sh/config.in +++ b/arch/sh/config.in @@ -175,7 +175,7 @@ if [ "$CONFIG_PCI" = "y" ]; then if [ "$CONFIG_PCI_GODIRECT" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then define_bool CONFIG_PCI_DIRECT y fi - bool 'Cache and PCI noncoherent' CONFIG_SH_PCIDMA_NONCOHERENT n + bool 'Cache and PCI noncoherent' CONFIG_SH_PCIDMA_NONCOHERENT fi source drivers/pci/Config.in diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index 47c794e99f4b..447f56926b16 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c @@ -688,7 +688,7 @@ static int set_rtc_mmss(unsigned long nowtime) /* * Not having a register set can lead to trouble. - * Also starfire doesnt have a tod clock. + * Also starfire doesn't have a tod clock. */ if (!mregs && !dregs) return -1; diff --git a/drivers/acorn/scsi/Config.in b/drivers/acorn/scsi/Config.in index 60a5e0a805e5..93ce7d3e4348 100644 --- a/drivers/acorn/scsi/Config.in +++ b/drivers/acorn/scsi/Config.in @@ -14,10 +14,10 @@ dep_tristate 'PowerTec support' CONFIG_SCSI_POWERTECSCSI $CONFIG_SCSI if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then comment 'The following drivers are not fully supported' - dep_tristate 'CumanaSCSI I support' CONFIG_SCSI_CUMANA_1 $CONFIG_SCSI + dep_tristate 'CumanaSCSI I support (EXPERIMENTAL)' CONFIG_SCSI_CUMANA_1 $CONFIG_SCSI if [ "$CONFIG_ARCH_ARC" = "y" -o "$CONFIG_ARCH_A5K" = "y" ]; then - dep_tristate 'EcoScsi support' CONFIG_SCSI_ECOSCSI $CONFIG_SCSI + dep_tristate 'EcoScsi support (EXPERIMENTAL)' CONFIG_SCSI_ECOSCSI $CONFIG_SCSI fi - dep_tristate 'Oak SCSI support' CONFIG_SCSI_OAK1 $CONFIG_SCSI + dep_tristate 'Oak SCSI support (EXPERIMENTAL)' CONFIG_SCSI_OAK1 $CONFIG_SCSI fi diff --git a/drivers/block/Config.in b/drivers/block/Config.in index e46f2cb1bd40..d6b458560882 100644 --- a/drivers/block/Config.in +++ b/drivers/block/Config.in @@ -4,7 +4,7 @@ mainmenu_option next_comment comment 'Block devices' -tristate 'Normal PC floppy disk support' CONFIG_BLK_DEV_FD +tristate 'Normal floppy disk support' CONFIG_BLK_DEV_FD if [ "$CONFIG_AMIGA" = "y" ]; then tristate 'Amiga floppy support' CONFIG_AMIGA_FLOPPY fi diff --git a/drivers/char/Config.in b/drivers/char/Config.in index 9d7ec0b30b2b..ccce94f8fd26 100644 --- a/drivers/char/Config.in +++ b/drivers/char/Config.in @@ -171,7 +171,9 @@ if [ "$CONFIG_ARCH_NETWINDER" = "y" ]; then tristate 'NetWinder flash support' CONFIG_NWFLASH fi -dep_tristate 'Intel i8x0 Random Number Generator support' CONFIG_INTEL_RNG $CONFIG_PCI +if [ "$CONFIG_X86" = "y" -o "$CONFIG_IA64" = "y" ]; then + dep_tristate 'Intel i8x0 Random Number Generator support' CONFIG_INTEL_RNG $CONFIG_PCI +fi tristate '/dev/nvram support' CONFIG_NVRAM tristate 'Enhanced Real Time Clock Support' CONFIG_RTC if [ "$CONFIG_IA64" = "y" ]; then diff --git a/drivers/char/ftape/Config.in b/drivers/char/ftape/Config.in index 179f5ba0741a..7c275b5e9133 100644 --- a/drivers/char/ftape/Config.in +++ b/drivers/char/ftape/Config.in @@ -35,7 +35,7 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then int ' Maximal data rate to use (EXPERIMENTAL)' CONFIG_FT_FDC_MAX_RATE 2000 fi -if [ "$ARCH" = "alpha" ]; then +if [ "$CONFIG_ALPHA" = "y" ]; then int ' CPU clock frequency of your DEC Alpha' CONFIG_FT_ALPHA_CLOCK 0 else define_int CONFIG_FT_ALPHA_CLOCK 0 diff --git a/drivers/fc4/Config.in b/drivers/fc4/Config.in index 47f3c71d5401..cbe1990fbb48 100644 --- a/drivers/fc4/Config.in +++ b/drivers/fc4/Config.in @@ -7,13 +7,13 @@ comment 'Fibre Channel support' tristate 'Fibre Channel and FC4 SCSI support' CONFIG_FC4 if [ ! "$CONFIG_FC4" = "n" ]; then comment 'FC4 drivers' - if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then + if [ "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" ]; then tristate 'Sun SOC/Sbus' CONFIG_FC4_SOC tristate 'Sun SOC+ (aka SOCAL)' CONFIG_FC4_SOCAL fi comment 'FC4 targets' dep_tristate 'SparcSTORAGE Array 100 and 200 series' CONFIG_SCSI_PLUTO $CONFIG_SCSI - if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then + if [ "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" ]; then dep_tristate 'Sun Enterprise Network Array (A5000 and EX500)' CONFIG_SCSI_FCAL $CONFIG_SCSI else dep_tristate 'Generic FC-AL disk driver' CONFIG_SCSI_FCAL $CONFIG_SCSI diff --git a/drivers/ide/Config.in b/drivers/ide/Config.in index c2cf6e879703..77ebacac5de2 100644 --- a/drivers/ide/Config.in +++ b/drivers/ide/Config.in @@ -49,7 +49,7 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then dep_bool ' CY82C693 chipset support' CONFIG_BLK_DEV_CY82C693 $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' Cyrix CS5530 MediaGX chipset support' CONFIG_BLK_DEV_CS5530 $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' HPT34X chipset support' CONFIG_BLK_DEV_HPT34X $CONFIG_BLK_DEV_IDEDMA_PCI - dep_mbool ' HPT34X AUTODMA support (EXPERMENTAL)' CONFIG_HPT34X_AUTODMA $CONFIG_BLK_DEV_HPT34X $CONFIG_EXPERIMENTAL + dep_mbool ' HPT34X AUTODMA support (EXPERIMENTAL)' CONFIG_HPT34X_AUTODMA $CONFIG_BLK_DEV_HPT34X $CONFIG_EXPERIMENTAL dep_bool ' HPT36X/37X chipset support' CONFIG_BLK_DEV_HPT366 $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' Intel and Efar (SMsC) chipset support' CONFIG_BLK_DEV_PIIX $CONFIG_BLK_DEV_IDEDMA_PCI if [ "$CONFIG_MIPS_ITE8172" = "y" -o "$CONFIG_MIPS_IVR" = "y" ]; then diff --git a/drivers/isdn/hisax/Config.in b/drivers/isdn/hisax/Config.in index 13513ff46649..0d41ba9998df 100644 --- a/drivers/isdn/hisax/Config.in +++ b/drivers/isdn/hisax/Config.in @@ -14,27 +14,27 @@ if [ "$CONFIG_ISDN_DRV_HISAX" != "n" ]; then bool ' HiSax Support for US NI1' CONFIG_HISAX_NI1 int ' Maximum number of cards supported by HiSax' CONFIG_HISAX_MAX_CARDS 8 comment ' HiSax supported cards' - bool ' Teles 16.0/8.0' CONFIG_HISAX_16_0 $CONFIG_ISA + dep_bool ' Teles 16.0/8.0' CONFIG_HISAX_16_0 $CONFIG_ISA bool ' Teles 16.3 or PNP or PCMCIA' CONFIG_HISAX_16_3 bool ' Teles PCI' CONFIG_HISAX_TELESPCI bool ' Teles S0Box' CONFIG_HISAX_S0BOX - bool ' AVM A1 (Fritz)' CONFIG_HISAX_AVM_A1 $CONFIG_ISA + dep_bool ' AVM A1 (Fritz)' CONFIG_HISAX_AVM_A1 $CONFIG_ISA bool ' AVM PnP/PCI (Fritz!PnP/PCI)' CONFIG_HISAX_FRITZPCI bool ' AVM A1 PCMCIA (Fritz)' CONFIG_HISAX_AVM_A1_PCMCIA bool ' Elsa cards' CONFIG_HISAX_ELSA - bool ' ITK ix1-micro Revision 2' CONFIG_HISAX_IX1MICROR2 $CONFIG_ISA + dep_bool ' ITK ix1-micro Revision 2' CONFIG_HISAX_IX1MICROR2 $CONFIG_ISA bool ' Eicon.Diehl Diva cards' CONFIG_HISAX_DIEHLDIVA - bool ' ASUSCOM ISA cards' CONFIG_HISAX_ASUSCOM $CONFIG_ISA - bool ' TELEINT cards' CONFIG_HISAX_TELEINT $CONFIG_ISA - bool ' HFC-S based cards' CONFIG_HISAX_HFCS $CONFIG_ISA + dep_bool ' ASUSCOM ISA cards' CONFIG_HISAX_ASUSCOM $CONFIG_ISA + dep_bool ' TELEINT cards' CONFIG_HISAX_TELEINT $CONFIG_ISA + dep_bool ' HFC-S based cards' CONFIG_HISAX_HFCS $CONFIG_ISA bool ' Sedlbauer cards' CONFIG_HISAX_SEDLBAUER - bool ' USR Sportster internal TA' CONFIG_HISAX_SPORTSTER $CONFIG_ISA - bool ' MIC card' CONFIG_HISAX_MIC $CONFIG_ISA + dep_bool ' USR Sportster internal TA' CONFIG_HISAX_SPORTSTER $CONFIG_ISA + dep_bool ' MIC card' CONFIG_HISAX_MIC $CONFIG_ISA bool ' NETjet card' CONFIG_HISAX_NETJET bool ' NETspider U card' CONFIG_HISAX_NETJET_U bool ' Niccy PnP/PCI card' CONFIG_HISAX_NICCY - bool ' Siemens I-Surf card' CONFIG_HISAX_ISURF $CONFIG_ISA - bool ' HST Saphir card' CONFIG_HISAX_HSTSAPHIR $CONFIG_ISA + dep_bool ' Siemens I-Surf card' CONFIG_HISAX_ISURF $CONFIG_ISA + dep_bool ' HST Saphir card' CONFIG_HISAX_HSTSAPHIR $CONFIG_ISA bool ' Telekom A4T card' CONFIG_HISAX_BKM_A4T bool ' Scitel Quadro card' CONFIG_HISAX_SCT_QUADRO bool ' Gazel cards' CONFIG_HISAX_GAZEL @@ -44,7 +44,7 @@ if [ "$CONFIG_ISDN_DRV_HISAX" != "n" ]; then if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then # bool ' TESTEMULATOR (EXPERIMENTAL)' CONFIG_HISAX_TESTEMU bool ' Formula-n enter:now PCI card' CONFIG_HISAX_ENTERNOW_PCI - if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then + if [ "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" ]; then bool ' Am7930' CONFIG_HISAX_AMD7930 fi fi diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index 995763e0e21d..e58e445c5144 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c @@ -11,7 +11,7 @@ * * Most of this code is directly derived from his userspace driver. * His driver works so send any reports to alan@redhat.com unless the - * userspace driver also doesnt work for you... + * userspace driver also doesn't work for you... */ #include <linux/module.h> diff --git a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c index cdb42c1d106e..71b5a16a3a04 100644 --- a/drivers/mtd/devices/blkmtd.c +++ b/drivers/mtd/devices/blkmtd.c @@ -222,7 +222,7 @@ static int blkmtd_readpage(mtd_raw_dev_data_t *rawdevice, struct page *page) return err; } - /* Pre 2.4.4 doesnt have space for the block list in the kiobuf */ + /* Pre 2.4.4 doesn't have space for the block list in the kiobuf */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4) blocks = kmalloc(KIO_MAX_SECTORS * sizeof(unsigned long)); if(blocks == NULL) { @@ -316,7 +316,7 @@ static int write_queue_task(void *data) return 0; } - /* Pre 2.4.4 doesnt have space for the block list in the kiobuf */ + /* Pre 2.4.4 doesn't have space for the block list in the kiobuf */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4) blocks = kmalloc(KIO_MAX_SECTORS * sizeof(unsigned long)); if(blocks == NULL) { @@ -355,7 +355,7 @@ static int write_queue_task(void *data) int sectorcnt = item->pagecnt << (PAGE_SHIFT - item->rawdevice->sector_bits); int max_sectors = KIO_MAX_SECTORS >> (item->rawdevice->sector_bits - 9); - /* If we are writing to the last page on the device and it doesnt end + /* If we are writing to the last page on the device and it doesn't end * on a page boundary, subtract the number of sectors that dont exist. */ if(item->rawdevice->partial_last_page && diff --git a/drivers/mtd/maps/Config.in b/drivers/mtd/maps/Config.in index 0f88c212460b..f601a73d6b46 100644 --- a/drivers/mtd/maps/Config.in +++ b/drivers/mtd/maps/Config.in @@ -47,7 +47,7 @@ if [ "$CONFIG_MIPS" = "y" ]; then fi if [ "$CONFIG_SUPERH" = "y" ]; then - dep_tristate ' CFI Flash device mapped on Hitachi SolutionEngine' CONFIG_MTD_SOLUTIONENGINE $CONFIG_MTD_CFI $CONFIG_SH $CONFIG_MTD_REDBOOT_PARTS + dep_tristate ' CFI Flash device mapped on Hitachi SolutionEngine' CONFIG_MTD_SOLUTIONENGINE $CONFIG_MTD_CFI $CONFIG_SUPERH $CONFIG_MTD_REDBOOT_PARTS fi if [ "$CONFIG_ARM" = "y" ]; then diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index 65f0ebe5c4b9..e67e9994d718 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c @@ -1259,9 +1259,9 @@ MODULE_PARM_DESC(max_interrupt_work, "maximum events handled per interrupt"); #ifdef __ISAPNP__ MODULE_PARM(nopnp, "i"); MODULE_PARM_DESC(nopnp, "disable ISA PnP support (0-1)"); +MODULE_DEVICE_TABLE(isapnp, el3_isapnp_adapters); #endif /* __ISAPNP__ */ MODULE_DESCRIPTION("3Com Etherlink III (3c509, 3c509B) ISA/PnP ethernet driver"); -MODULE_DEVICE_TABLE(isapnp, el3_isapnp_adapters); MODULE_LICENSE("GPL"); int diff --git a/drivers/net/aironet4500_rid.c b/drivers/net/aironet4500_rid.c index ff7550d331dd..6a71a26ba347 100644 --- a/drivers/net/aironet4500_rid.c +++ b/drivers/net/aironet4500_rid.c @@ -20,7 +20,7 @@ #define awc_RID_gen_RidLen {(const struct aironet4500_rid_selector *)&aironet4500_RID_Select_General_Config,0x0000, 8,1,1,1,0, 0xffffffff,0x0000, "Length of RID" } #define awc_RID_gen_OperatingMode_adhoc {&aironet4500_RID_Select_General_Config,0x0002,16,1,1,0,0, 0x00000003,0x0000,"Opmode IBSS Adhoc operation" } // Without AP #define awc_RID_gen_OperatingMode_Infrastructure {&aironet4500_RID_Select_General_Config,0x0002,16,1,1,0,0, 0x00000003,0x0001,"Opmode Infrastructure Station operation" }// With AP -#define awc_RID_gen_OperatingMode_AP {&aironet4500_RID_Select_General_Config,0x0002,16,1,1,0,0, 0x00000003,0x0002,"Opmode Access Point" } // Aironet doesnt release info on use +#define awc_RID_gen_OperatingMode_AP {&aironet4500_RID_Select_General_Config,0x0002,16,1,1,0,0, 0x00000003,0x0002,"Opmode Access Point" } // Aironet doesn't release info on use #define awc_RID_gen_OperatingMode_AP_and_repeater {&aironet4500_RID_Select_General_Config,0x0002,16,1,1,0,0, 0x00000003,0x0003,"Opmode Access Point and Repeater" } // no info #define awc_RID_gen_OperatingMode_No_payload_modify {&aironet4500_RID_Select_General_Config,0x0002,16,1,1,0,0, 0x00000100,0x0100,"Opmode Payload without modify" } #define awc_RID_gen_OperatingMode_LLC_802_3_convert {&aironet4500_RID_Select_General_Config,0x0002,16,1,1,0,0, 0x00000100,0x0000,"Opmode LLC -> 802.3 convert" } diff --git a/drivers/net/bsd_comp.c b/drivers/net/bsd_comp.c index 09afb2398861..2e969fdc16b8 100644 --- a/drivers/net/bsd_comp.c +++ b/drivers/net/bsd_comp.c @@ -65,6 +65,7 @@ #include <linux/init.h> #include <linux/slab.h> #include <linux/vmalloc.h> +#include <linux/string.h> #include <linux/ppp_defs.h> diff --git a/drivers/net/ppp_deflate.c b/drivers/net/ppp_deflate.c index 9cf6453d07ca..4c96fe741b98 100644 --- a/drivers/net/ppp_deflate.c +++ b/drivers/net/ppp_deflate.c @@ -35,6 +35,7 @@ #include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/init.h> +#include <linux/string.h> #include <linux/ppp_defs.h> #include <linux/ppp-comp.h> diff --git a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c index 6e6a57197939..09d9a1a1e7ba 100644 --- a/drivers/net/wan/syncppp.c +++ b/drivers/net/wan/syncppp.c @@ -796,7 +796,7 @@ static void sppp_cp_send (struct sppp *sp, u16 proto, u8 type, printk (">\n"); } sp->obytes += skb->len; - /* Control is high priority so it doesnt get queued behind data */ + /* Control is high priority so it doesn't get queued behind data */ skb->priority=TC_PRIO_CONTROL; skb->dev = dev; dev_queue_xmit(skb); diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 435a18cbee63..aa0b16346043 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -264,7 +264,7 @@ MODULE_PARM_DESC(proc_perm, "The permission bits of the files in /proc"); /* This is a kind of sloppy hack to get this information to OUT4500 and IN4500. I would be extremely interested in the situation where this - doesnt work though!!! */ + doesn't work though!!! */ static int do8bitIO = 0; /* Return codes */ @@ -3653,7 +3653,7 @@ static struct net_device_list { struct net_device_list *next; } *airo_devices = 0; -/* Since the card doesnt automatically switch to the right WEP mode, +/* Since the card doesn't automatically switch to the right WEP mode, we will make it do it. If the card isn't associated, every secs we will switch WEP modes to see if that will help. If the card is associated we will check every minute to see if anything has diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 75b84219d66b..94154ddf502b 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -252,8 +252,6 @@ struct pci_bus * __devinit pci_add_new_bus(struct pci_bus *parent, struct pci_de return child; } -unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus); - /* * If it's a bridge, configure it and scan the bus behind it. * For CardBus bridges, we don't scan behind as the devices will diff --git a/drivers/sbus/char/Config.in b/drivers/sbus/char/Config.in index f991b5cfad44..e40ebfb6e23b 100644 --- a/drivers/sbus/char/Config.in +++ b/drivers/sbus/char/Config.in @@ -2,7 +2,7 @@ mainmenu_option next_comment comment 'Misc Linux/SPARC drivers' tristate '/dev/openprom device support' CONFIG_SUN_OPENPROMIO tristate 'Mostek real time clock support' CONFIG_SUN_MOSTEK_RTC -if [ "$ARCH" = "sparc64" ]; then +if [ "$CONFIG_SPARC64" = "y" ]; then if [ "$CONFIG_PCI" = "y" ]; then tristate 'Siemens SAB82532 serial support' CONFIG_SAB82532 fi @@ -14,7 +14,7 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then tristate 'Videopix Frame Grabber (EXPERIMENTAL)' CONFIG_SUN_VIDEOPIX tristate 'Aurora Multiboard 1600se (EXPERIMENTAL)' CONFIG_SUN_AURORA - if [ "$ARCH" = "sparc" ]; then + if [ "$CONFIG_SPARC32" = "y" ]; then tristate 'Tadpole TS102 Microcontroller support (EXPERIMENTAL)' CONFIG_TADPOLE_TS102_UCTRL tristate 'JavaStation OS Flash SIMM (EXPERIMENTAL)' CONFIG_SUN_JSFLASH diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index 21249f76768f..c056da9c0ed9 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c @@ -7184,7 +7184,7 @@ void ncr_int_sir (ncb_p np) ** ** Possible cases: hs sir msg_in value send goto ** We try to negotiate: -** -> target doesnt't msgin NEG FAIL noop defa. - dispatch +** -> target doesn't msgin NEG FAIL noop defa. - dispatch ** -> target rejected our msg NEG FAIL reject defa. - dispatch ** -> target answered (ok) NEG SYNC sdtr set - clrack ** -> target answered (!ok) NEG SYNC sdtr defa. REJ--->msg_bad diff --git a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c index 4b83e7dbb3d1..35a758c43a3f 100644 --- a/drivers/scsi/seagate.c +++ b/drivers/scsi/seagate.c @@ -21,7 +21,7 @@ * linux 2.1.112, simplified some #defines etc. <pavel@ucw.cz> * * Aug 2000 - aeb - deleted seagate_st0x_biosparam(). It would try to - * read the physical disk geometry, a bad mistake. Of course it doesnt + * read the physical disk geometry, a bad mistake. Of course it doesn't * matter much what geometry one invents, but on large disks it * returned 256 (or more) heads, causing all kind of failures. * Of course this means that people might see a different geometry now, diff --git a/drivers/sgi/Config.in b/drivers/sgi/Config.in index f7582d1fa949..082be90d44c2 100644 --- a/drivers/sgi/Config.in +++ b/drivers/sgi/Config.in @@ -11,7 +11,7 @@ fi bool 'SGI DS1286 RTC support' CONFIG_SGI_DS1286 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'SGI Newport Graphics support' CONFIG_SGI_NEWPORT_GFX + tristate 'SGI Newport Graphics support (EXPERIMENTAL)' CONFIG_SGI_NEWPORT_GFX fi endmenu diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 59649374c27b..15a2c346b4af 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1232,7 +1232,7 @@ static int hcd_free_dev (struct usb_device *udev) return 0; } -/** +/* * usb_hcd_operations - adapts usb_bus framework to HCD framework (bus glue) * * When registering a USB bus through the HCD framework code, use this diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index 1d9bd9c37300..b968cfe92d35 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c @@ -12,13 +12,14 @@ #ifdef DEBUG -#define pipestring(pipe) ({ char *temp; \ - switch (usb_pipetype (pipe)) { \ +#define edstring(ed_type) ({ char *temp; \ + switch (ed_type) { \ case PIPE_CONTROL: temp = "CTRL"; break; \ case PIPE_BULK: temp = "BULK"; break; \ case PIPE_INTERRUPT: temp = "INTR"; break; \ default: temp = "ISOC"; break; \ }; temp;}) +#define pipestring(pipe) edstring(usb_pipetype(pipe)) /* debug| print the main components of an URB * small: 0) header + data packets 1) just header @@ -35,9 +36,9 @@ static void urb_print (struct urb * urb, char * str, int small) #ifndef OHCI_VERBOSE_DEBUG if (urb->status != 0) #endif - dbg("%s:[%4x] dev:%d,ep=%d-%c,%s,flags:%4x,len:%d/%d,stat:%d", + dbg("%s %p dev:%d,ep=%d-%c,%s,flags:%x,len:%d/%d,stat:%d", str, - usb_get_current_frame_number (urb->dev), + urb, usb_pipedevice (pipe), usb_pipeendpoint (pipe), usb_pipeout (pipe)? 'O': 'I', @@ -242,21 +243,25 @@ static void ohci_dump (struct ohci_hcd *controller, int verbose) ohci_dump_roothub (controller, 1); } +static const char data0 [] = "DATA0"; +static const char data1 [] = "DATA1"; + static void ohci_dump_td (char *label, struct td *td) { u32 tmp = le32_to_cpup (&td->hwINFO); - dbg ("%s td %p; urb %p index %d; hw next td %08x", + dbg ("%s td %p%s; urb %p index %d; hw next td %08x", label, td, + (tmp & TD_DONE) ? " (DONE)" : "", td->urb, td->index, le32_to_cpup (&td->hwNextTD)); if ((tmp & TD_ISO) == 0) { - char *toggle, *pid; + const char *toggle, *pid; u32 cbp, be; switch (tmp & TD_T) { - case TD_T_DATA0: toggle = "DATA0"; break; - case TD_T_DATA1: toggle = "DATA1"; break; + case TD_T_DATA0: toggle = data0; break; + case TD_T_DATA1: toggle = data1; break; case TD_T_TOGGLE: toggle = "(CARRY)"; break; default: toggle = "(?)"; break; } @@ -297,9 +302,9 @@ ohci_dump_ed (struct ohci_hcd *ohci, char *label, struct ed *ed, int verbose) u32 tmp = ed->hwINFO; char *type = ""; - dbg ("%s: %s, ed %p state 0x%x type %d; next ed %08x", + dbg ("%s: %s, ed %p state 0x%x type %s; next ed %08x", ohci->hcd.self.bus_name, label, - ed, ed->state, ed->type, + ed, ed->state, edstring (ed->type), le32_to_cpup (&ed->hwNextED)); switch (tmp & (ED_IN|ED_OUT)) { case ED_OUT: type = "-OUT"; break; @@ -314,10 +319,10 @@ ohci_dump_ed (struct ohci_hcd *ohci, char *label, struct ed *ed, int verbose) 0x000f & (le32_to_cpu (tmp) >> 7), type, 0x007f & le32_to_cpu (tmp)); - dbg (" tds: head %08x%s%s tail %08x%s", + dbg (" tds: head %08x %s%s tail %08x%s", tmp = le32_to_cpup (&ed->hwHeadP), + (ed->hwHeadP & ED_C) ? data1 : data0, (ed->hwHeadP & ED_H) ? " HALT" : "", - (ed->hwHeadP & ED_C) ? " CARRY" : "", le32_to_cpup (&ed->hwTailP), verbose ? "" : " (not listing)"); if (verbose) { diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index db4276ead92c..a56ae64e60cc 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -197,7 +197,7 @@ static int ohci_urb_enqueue ( /* allocate the TDs (updating hash chains) */ spin_lock_irqsave (&ohci->lock, flags); - for (i = 0; i < size; i++) { + for (i = 0; i < size; i++) { urb_priv->td [i] = td_alloc (ohci, SLAB_ATOMIC); if (!urb_priv->td [i]) { urb_priv->length = i; @@ -208,6 +208,8 @@ static int ohci_urb_enqueue ( } // FIXME: much of this switch should be generic, move to hcd code ... +// ... and what's not generic can't really be handled this way. +// need to consider periodicity for both types! /* allocate and claim bandwidth if needed; ISO * needs start frame index if it was't provided. @@ -247,14 +249,14 @@ static int ohci_urb_enqueue ( spin_unlock_irqrestore (&ohci->lock, flags); - return 0; + return 0; } /* * decouple the URB from the HC queues (TDs, urb_priv); it's - * already marked for deletion. reporting is always done + * already marked using urb->status. reporting is always done * asynchronously, and we might be dealing with an urb that's - * almost completed anyway... + * partially transferred, or an ED with other urbs being unlinked. */ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) { diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index c3f19885b4bc..1d3de55b90b9 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -465,6 +465,25 @@ static struct ed *ed_get ( * we know it's already a power of 2 */ ed->interval = interval; +#ifdef DEBUG + /* + * There are two other cases we ought to change hwINFO, both during + * enumeration. There, the control request completes, unlinks, and + * the next request gets queued before the unlink completes, so it + * uses old/wrong hwINFO. How much of a problem is this? khubd is + * already retrying after such failures... + */ + } else if (type == PIPE_CONTROL) { + u32 info = le32_to_cpup (&ed->hwINFO); + + if (!(info & 0x7f)) + dbg ("RETRY ctrl: address != 0"); + info >>= 16; + if (info != udev->epmaxpacketin [0]) + dbg ("RETRY ctrl: maxpacket %d != 8", + udev->epmaxpacketin [0]); + +#endif /* DEBUG */ } done: @@ -539,12 +558,15 @@ td_fill (struct ohci_hcd *ohci, unsigned int info, /* aim for only one interrupt per urb. mostly applies to control * and iso; other urbs rarely need more than one TD per urb. + * this way, only final tds (or ones with an error) cause IRQs. * * NOTE: could delay interrupts even for the last TD, and get fewer * interrupts ... increasing per-urb latency by sharing interrupts. + * Drivers that queue bulk urbs may request that behavior. */ - if (index != (urb_priv->length - 1)) - info |= is_iso ? TD_DI_SET (7) : TD_DI_SET (1); + if (index != (urb_priv->length - 1) + || (urb->transfer_flags & URB_NO_INTERRUPT)) + info |= TD_DI_SET (7); /* use this td as the next dummy */ td_pt = urb_priv->td [index]; @@ -565,6 +587,7 @@ td_fill (struct ohci_hcd *ohci, unsigned int info, td->hwINFO = cpu_to_le32 (info); if (is_iso) { td->hwCBP = cpu_to_le32 (data & 0xFFFFF000); + td->hwPSW [0] = cpu_to_le16 ((data & 0x0FFF) | 0xE000); td->ed->intriso.last_iso = info & 0xffff; } else { td->hwCBP = cpu_to_le32 (data); @@ -574,7 +597,6 @@ td_fill (struct ohci_hcd *ohci, unsigned int info, else td->hwBE = 0; td->hwNextTD = cpu_to_le32 (td_pt->td_dma); - td->hwPSW [0] = cpu_to_le16 ((data & 0x0FFF) | 0xE000); /* HC might read the TD right after we link it ... */ wmb (); @@ -596,17 +618,17 @@ static void td_submit_urb (struct urb *urb) int cnt = 0; __u32 info = 0; unsigned int toggle = 0; + int is_out = usb_pipeout (urb->pipe); /* OHCI handles the DATA-toggles itself, we just use the * USB-toggle bits for resetting */ - if (usb_gettoggle (urb->dev, usb_pipeendpoint (urb->pipe), - usb_pipeout (urb->pipe))) { + if (usb_gettoggle (urb->dev, usb_pipeendpoint (urb->pipe), is_out)) { toggle = TD_T_TOGGLE; } else { toggle = TD_T_DATA0; usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), - usb_pipeout (urb->pipe), 1); + is_out, 1); } urb_priv->td_cnt = 0; @@ -614,9 +636,9 @@ static void td_submit_urb (struct urb *urb) if (data_len) { data = pci_map_single (ohci->hcd.pdev, urb->transfer_buffer, data_len, - usb_pipeout (urb->pipe) - ? PCI_DMA_TODEVICE - : PCI_DMA_FROMDEVICE); + is_out + ? PCI_DMA_TODEVICE + : PCI_DMA_FROMDEVICE); } else data = 0; @@ -625,18 +647,20 @@ static void td_submit_urb (struct urb *urb) */ switch (usb_pipetype (urb->pipe)) { case PIPE_BULK: - info = usb_pipeout (urb->pipe) + info = is_out ? TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN ; + /* TDs _could_ transfer up to 8K each */ while (data_len > 4096) { td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, 4096, urb, cnt); data += 4096; data_len -= 4096; cnt++; } - info = usb_pipeout (urb->pipe)? - TD_CC | TD_DP_OUT : TD_CC | TD_R | TD_DP_IN ; - td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), + /* maybe avoid ED halt on final TD short read */ + if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) + info |= TD_R; + td_fill (ohci, info | (cnt ? TD_T_TOGGLE : toggle), data, data_len, urb, cnt); cnt++; if ((urb->transfer_flags & USB_ZERO_PACKET) @@ -653,8 +677,11 @@ static void td_submit_urb (struct urb *urb) break; case PIPE_INTERRUPT: + /* current policy: only one TD per request. + * otherwise identical to bulk, except for BLF + */ info = TD_CC | toggle; - info |= usb_pipeout (urb->pipe) + info |= is_out ? TD_DP_OUT : TD_R | TD_DP_IN; td_fill (ohci, info, data, data_len, urb, cnt++); @@ -670,14 +697,12 @@ static void td_submit_urb (struct urb *urb) 8, urb, cnt++); if (data_len > 0) { info = TD_CC | TD_R | TD_T_DATA1; - info |= usb_pipeout (urb->pipe) - ? TD_DP_OUT - : TD_DP_IN; + info |= is_out ? TD_DP_OUT : TD_DP_IN; /* NOTE: mishandles transfers >8K, some >4K */ td_fill (ohci, info, data, data_len, urb, cnt++); } - info = usb_pipeout (urb->pipe) + info = is_out ? TD_CC | TD_DP_IN | TD_T_DATA1 : TD_CC | TD_DP_OUT | TD_T_DATA1; td_fill (ohci, info, data, 0, urb, cnt++); @@ -806,10 +831,13 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci) while (td_list_hc) { td_list = dma_to_td (ohci, td_list_hc); + td_list->hwINFO |= cpu_to_le32 (TD_DONE); + if (TD_CC_GET (le32_to_cpup (&td_list->hwINFO))) { urb_priv = (urb_priv_t *) td_list->urb->hcpriv; - /* typically the endpoint halts on error; un-halt, - * and maybe dequeue other TDs from this urb + /* Non-iso endpoints can halt on error; un-halt, + * and dequeue any other TDs from this urb. + * No other TD could have caused the halt. */ if (td_list->ed->hwHeadP & ED_H) { if (urb_priv && ((td_list->index + 1) diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index 11967b45be07..95fc8b82af57 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c @@ -175,7 +175,7 @@ int usb_hcd_sa1111_probe (const struct hc_driver *driver, struct usb_hcd **hcd_o usb_bus_init (&hcd->self); hcd->self.op = &usb_hcd_operations; hcd->self.hcpriv = (void *) hcd; - hcd->self.bus_name = "SA-1111"; + hcd->self.bus_name = "sa1111"; hcd->product_desc = "SA-1111 OHCI"; INIT_LIST_HEAD (&hcd->dev_list); diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index d5fc9517f132..7969e669052d 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -11,6 +11,9 @@ /* * OHCI Endpoint Descriptor (ED) ... holds TD queue * See OHCI spec, section 4.2 + * + * This is a "Queue Head" for those transfers, which is why + * both EHCI and UHCI call similar structures a "QH". */ struct ed { /* first fields are hardware-specified, le32 */ @@ -74,8 +77,8 @@ struct td { /* these two bits are available for definition/use by HCDs in both * general and iso tds ... others are available for only one type */ -//#define TD____ 0x00020000 -#define TD_ISO 0x00010000 /* copy of ED_ISO */ +#define TD_DONE 0x00020000 /* retired to donelist */ +#define TD_ISO 0x00010000 /* copy of ED_ISO */ /* hwINFO bits for general tds: */ #define TD_EC 0x0C000000 /* error count */ @@ -349,12 +352,14 @@ struct ohci_hcd { struct device *parent_dev; /* - * I/O memory used to communicate with the HC (uncached); + * I/O memory used to communicate with the HC (dma-consistent) */ struct ohci_regs *regs; /* - * main memory used to communicate with the HC (uncached) + * main memory used to communicate with the HC (dma-consistent). + * hcd adds to schedule for a live hc any time, but removals finish + * only at the start of the next frame. */ struct ohci_hcca *hcca; dma_addr_t hcca_dma; @@ -365,6 +370,9 @@ struct ohci_hcd { struct ed *ed_controltail; /* last in ctrl list */ struct ed *ed_isotail; /* last in iso list */ + /* + * memory management for queue data structures + */ struct pci_pool *td_cache; struct pci_pool *ed_cache; struct hash_list_t td_hash [TD_HASH_SIZE]; @@ -380,6 +388,7 @@ struct ohci_hcd { unsigned long flags; /* for HC bugs */ #define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */ + // there are also chip quirks/bugs in init logic /* * framework state diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index ca7b3f198390..068417749db6 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -127,18 +127,41 @@ static int open_collection(struct hid_parser *parser, unsigned type) usage = parser->local.usage[0]; - if (type == HID_COLLECTION_APPLICATION - && parser->device->maxapplication < HID_MAX_APPLICATIONS) - parser->device->application[parser->device->maxapplication++] = usage; - if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) { dbg("collection stack overflow"); return -1; } - collection = parser->collection_stack + parser->collection_stack_ptr++; + if (parser->device->maxcollection == parser->device->collection_size) { + collection = kmalloc(sizeof(struct hid_collection) * + parser->device->collection_size * 2, + GFP_KERNEL); + if (collection == NULL) { + dbg("failed to reallocate collection array"); + return -1; + } + memcpy(collection, parser->device->collection, + sizeof(struct hid_collection) * + parser->device->collection_size); + memset(collection + parser->device->collection_size, 0, + sizeof(struct hid_collection) * + parser->device->collection_size); + kfree(parser->device->collection); + parser->device->collection = collection; + parser->device->collection_size *= 2; + } + + parser->collection_stack[parser->collection_stack_ptr++] = + parser->device->maxcollection; + + collection = parser->device->collection + + parser->device->maxcollection++; collection->type = type; collection->usage = usage; + collection->level = parser->collection_stack_ptr - 1; + + if (type == HID_COLLECTION_APPLICATION) + parser->device->maxapplication++; return 0; } @@ -166,8 +189,8 @@ static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type) { int n; for (n = parser->collection_stack_ptr - 1; n >= 0; n--) - if (parser->collection_stack[n].type == type) - return parser->collection_stack[n].usage; + if (parser->device->collection[parser->collection_stack[n]].type == type) + return parser->device->collection[parser->collection_stack[n]].usage; return 0; /* we know nothing about this usage type */ } @@ -181,7 +204,11 @@ static int hid_add_usage(struct hid_parser *parser, unsigned usage) dbg("usage index exceeded"); return -1; } - parser->local.usage[parser->local.usage_index++] = usage; + parser->local.usage[parser->local.usage_index] = usage; + parser->local.collection_index[parser->local.usage_index] = + parser->collection_stack_ptr ? + parser->collection_stack[parser->collection_stack_ptr - 1] : 0; + parser->local.usage_index++; return 0; } @@ -221,8 +248,11 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL); field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION); - for (i = 0; i < usages; i++) + for (i = 0; i < usages; i++) { field->usage[i].hid = parser->local.usage[i]; + field->usage[i].collection_index = + parser->local.collection_index[i]; + } field->maxusage = usages; field->flags = flags; @@ -460,7 +490,7 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item) switch (item->tag) { case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION: - ret = open_collection(parser, data & 3); + ret = open_collection(parser, data & 0xff); break; case HID_MAIN_ITEM_TAG_END_COLLECTION: ret = close_collection(parser); @@ -621,17 +651,30 @@ static struct hid_device *hid_parse_report(__u8 *start, unsigned size) return NULL; memset(device, 0, sizeof(struct hid_device)); + if (!(device->collection = kmalloc(sizeof(struct hid_collection) * + HID_DEFAULT_NUM_COLLECTIONS, + GFP_KERNEL))) { + kfree(device); + return NULL; + } + memset(device->collection, 0, sizeof(struct hid_collection) * + HID_DEFAULT_NUM_COLLECTIONS); + device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; + for (i = 0; i < HID_REPORT_TYPES; i++) INIT_LIST_HEAD(&device->report_enum[i].report_list); if (!(device->rdesc = (__u8 *)kmalloc(size, GFP_KERNEL))) { + kfree(device->collection); kfree(device); return NULL; } memcpy(device->rdesc, start, size); + device->rsize = size; if (!(parser = kmalloc(sizeof(struct hid_parser), GFP_KERNEL))) { kfree(device->rdesc); + kfree(device->collection); kfree(device); return NULL; } @@ -643,6 +686,8 @@ static struct hid_device *hid_parse_report(__u8 *start, unsigned size) if (item.format != HID_ITEM_FORMAT_SHORT) { dbg("unexpected long global item"); + kfree(device->rdesc); + kfree(device->collection); hid_free_device(device); kfree(parser); return NULL; @@ -651,6 +696,8 @@ static struct hid_device *hid_parse_report(__u8 *start, unsigned size) if (dispatch_type[item.type](parser, &item)) { dbg("item %u %u %u %u parsing failed\n", item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); + kfree(device->rdesc); + kfree(device->collection); hid_free_device(device); kfree(parser); return NULL; @@ -659,12 +706,16 @@ static struct hid_device *hid_parse_report(__u8 *start, unsigned size) if (start == end) { if (parser->collection_stack_ptr) { dbg("unbalanced collection at end of report description"); + kfree(device->rdesc); + kfree(device->collection); hid_free_device(device); kfree(parser); return NULL; } if (parser->local.delimiter_depth) { dbg("unbalanced delimiter at end of report description"); + kfree(device->rdesc); + kfree(device->collection); hid_free_device(device); kfree(parser); return NULL; @@ -675,6 +726,8 @@ static struct hid_device *hid_parse_report(__u8 *start, unsigned size) } dbg("item fetching failed at offset %d\n", (int)(end - start)); + kfree(device->rdesc); + kfree(device->collection); hid_free_device(device); kfree(parser); return NULL; @@ -740,22 +793,8 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field, s hid_dump_input(usage, value); if (hid->claimed & HID_CLAIMED_INPUT) hidinput_hid_event(hid, field, usage, value); -#ifdef CONFIG_USB_HIDDEV - if (hid->claimed & HID_CLAIMED_HIDDEV) { - struct hiddev_usage_ref uref; - unsigned type = field->report_type; - uref.report_type = - (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT : - ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT : - ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0)); - uref.report_id = field->report->id; - uref.field_index = field->index; - uref.usage_index = (usage - field->usage); - uref.usage_code = usage->hid; - uref.value = value; - hiddev_hid_event(hid, &uref); - } -#endif + if (hid->claimed & HID_CLAIMED_HIDDEV) + hiddev_hid_event(hid, field, usage, value); } /* @@ -851,21 +890,6 @@ static int hid_input_report(int type, struct urb *urb) return -1; } -#ifdef CONFIG_USB_HIDDEV - /* Notify listeners that a report has been received */ - if (hid->claimed & HID_CLAIMED_HIDDEV) { - struct hiddev_usage_ref uref; - memset(&uref, 0, sizeof(uref)); - uref.report_type = - (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT : - ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT : - ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0)); - uref.report_id = report->id; - uref.field_index = HID_FIELD_INDEX_NONE; - hiddev_hid_event(hid, &uref); - } -#endif - size = ((report->size - 1) >> 3) + 1; if (len < size) { @@ -873,6 +897,9 @@ static int hid_input_report(int type, struct urb *urb) return -1; } + if (hid->claimed & HID_CLAIMED_HIDDEV) + hiddev_report_event(hid, report); + for (n = 0; n < report->maxfield; n++) hid_input_field(hid, report->field[n], data); @@ -1284,6 +1311,10 @@ void hid_init_reports(struct hid_device *hid) #define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204 #define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205 +#define USB_VENDOR_ID_MGE 0x0463 +#define USB_DEVICE_ID_MGE_UPS 0xffff +#define USB_DEVICE_ID_MGE_UPS1 0x0001 + struct hid_blacklist { __u16 idVendor; __u16 idProduct; @@ -1301,6 +1332,8 @@ struct hid_blacklist { { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_HIDDEV }, + { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_HIDDEV }, { 0, 0 } }; @@ -1438,6 +1471,27 @@ fail: return NULL; } +static void hid_disconnect(struct usb_device *dev, void *ptr) +{ + struct hid_device *hid = ptr; + + usb_unlink_urb(hid->urbin); + usb_unlink_urb(hid->urbout); + usb_unlink_urb(hid->urbctrl); + + if (hid->claimed & HID_CLAIMED_INPUT) + hidinput_disconnect(hid); + if (hid->claimed & HID_CLAIMED_HIDDEV) + hiddev_disconnect(hid); + + usb_free_urb(hid->urbin); + usb_free_urb(hid->urbctrl); + if (hid->urbout) + usb_free_urb(hid->urbout); + + hid_free_device(hid); +} + static void* hid_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id) { @@ -1462,7 +1516,7 @@ static void* hid_probe(struct usb_device *dev, unsigned int ifnum, hid->claimed |= HID_CLAIMED_HIDDEV; if (!hid->claimed) { - hid_free_device(hid); + hid_disconnect(dev, hid); return NULL; } @@ -1476,11 +1530,14 @@ static void* hid_probe(struct usb_device *dev, unsigned int ifnum, printk("hiddev%d", hid->minor); c = "Device"; - for (i = 0; i < hid->maxapplication; i++) - if ((hid->application[i] & 0xffff) < ARRAY_SIZE(hid_types)) { - c = hid_types[hid->application[i] & 0xffff]; + for (i = 0; i < hid->maxcollection; i++) { + if (hid->collection[i].type == HID_COLLECTION_APPLICATION && + (hid->collection[i].usage & HID_USAGE_PAGE) == HID_UP_GENDESK && + (hid->collection[i].usage & 0xffff) < ARRAY_SIZE(hid_types)) { + c = hid_types[hid->collection[i].usage & 0xffff]; break; } + } usb_make_path(dev, path, 63); @@ -1490,27 +1547,6 @@ static void* hid_probe(struct usb_device *dev, unsigned int ifnum, return hid; } -static void hid_disconnect(struct usb_device *dev, void *ptr) -{ - struct hid_device *hid = ptr; - - usb_unlink_urb(hid->urbin); - usb_unlink_urb(hid->urbout); - usb_unlink_urb(hid->urbctrl); - - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_disconnect(hid); - if (hid->claimed & HID_CLAIMED_HIDDEV) - hiddev_disconnect(hid); - - usb_free_urb(hid->urbin); - usb_free_urb(hid->urbctrl); - if (hid->urbout) - usb_free_urb(hid->urbout); - - hid_free_device(hid); -} - static struct usb_device_id hid_usb_ids [] = { { match_flags: USB_DEVICE_ID_MATCH_INT_CLASS, bInterfaceClass: USB_INTERFACE_CLASS_HID }, diff --git a/drivers/usb/input/hid-debug.h b/drivers/usb/input/hid-debug.h index 62757fa2fe05..9ae94a95d7d3 100644 --- a/drivers/usb/input/hid-debug.h +++ b/drivers/usb/input/hid-debug.h @@ -352,12 +352,6 @@ static void __attribute__((unused)) hid_dump_device(struct hid_device *device) { unsigned i,k; static char *table[] = {"INPUT", "OUTPUT", "FEATURE"}; - for (i = 0; i < device->maxapplication; i++) { - printk("Application("); - resolv_usage(device->application[i]); - printk(")\n"); - } - for (i = 0; i < HID_REPORT_TYPES; i++) { report_enum = device->report_enum + i; list = report_enum->report_list.next; diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c index 37f12424cb6f..a036b23f6fa6 100644 --- a/drivers/usb/input/hid-input.c +++ b/drivers/usb/input/hid-input.c @@ -474,11 +474,12 @@ int hidinput_connect(struct hid_device *hid) struct list_head *list; int i, j, k; - for (i = 0; i < hid->maxapplication; i++) - if (IS_INPUT_APPLICATION(hid->application[i])) + for (i = 0; i < hid->maxcollection; i++) + if (hid->collection[i].type == HID_COLLECTION_APPLICATION && + IS_INPUT_APPLICATION(hid->collection[i].usage)) break; - if (i == hid->maxapplication) + if (i == hid->maxcollection) return -1; hid->input.private = hid; diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h index 7862be448938..93075dee2db7 100644 --- a/drivers/usb/input/hid.h +++ b/drivers/usb/input/hid.h @@ -205,6 +205,7 @@ struct hid_item { #define HID_QUIRK_NOTOUCH 0x02 #define HID_QUIRK_IGNORE 0x04 #define HID_QUIRK_NOGET 0x08 +#define HID_QUIRK_HIDDEV 0x10 /* * This is the global enviroment of the parser. This information is @@ -231,10 +232,11 @@ struct hid_global { #define HID_MAX_DESCRIPTOR_SIZE 4096 #define HID_MAX_USAGES 1024 -#define HID_MAX_APPLICATIONS 16 +#define HID_DEFAULT_NUM_COLLECTIONS 16 struct hid_local { unsigned usage[HID_MAX_USAGES]; /* usage array */ + unsigned collection_index[HID_MAX_USAGES]; /* collection index array */ unsigned usage_index; unsigned usage_minimum; unsigned delimiter_depth; @@ -249,10 +251,12 @@ struct hid_local { struct hid_collection { unsigned type; unsigned usage; + unsigned level; }; struct hid_usage { unsigned hid; /* hid usage code */ + unsigned collection_index; /* index into collection array */ __u16 code; /* input driver code */ __u8 type; /* input driver type */ __s8 hat_min; /* hat switch fun */ @@ -319,7 +323,9 @@ struct hid_control_fifo { struct hid_device { /* device report descriptor */ __u8 *rdesc; unsigned rsize; - unsigned application[HID_MAX_APPLICATIONS]; /* List of HID applications */ + struct hid_collection *collection; /* List of HID collections */ + unsigned collection_size; /* Number of allocated hid_collections */ + unsigned maxcollection; /* Number of parsed collections */ unsigned maxapplication; /* Number of applications */ unsigned version; /* HID version */ unsigned country; /* HID country */ @@ -374,7 +380,7 @@ struct hid_parser { struct hid_global global_stack[HID_GLOBAL_STACK_SIZE]; unsigned global_stack_ptr; struct hid_local local; - struct hid_collection collection_stack[HID_COLLECTION_STACK_SIZE]; + unsigned collection_stack[HID_COLLECTION_STACK_SIZE]; unsigned collection_stack_ptr; struct hid_device *device; }; diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c index 8b93b2f0a1bc..563285d58541 100644 --- a/drivers/usb/input/hiddev.c +++ b/drivers/usb/input/hiddev.c @@ -80,6 +80,7 @@ extern struct usb_driver hiddev_driver; static struct hid_report * hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo) { + unsigned flags = rinfo->report_id & ~HID_REPORT_ID_MASK; struct hid_report_enum *report_enum; struct list_head *list; @@ -88,27 +89,28 @@ hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo) report_enum = hid->report_enum + (rinfo->report_type - HID_REPORT_TYPE_MIN); - if ((rinfo->report_id & ~HID_REPORT_ID_MASK) != 0) { - switch (rinfo->report_id & ~HID_REPORT_ID_MASK) { - case HID_REPORT_ID_FIRST: - list = report_enum->report_list.next; - if (list == &report_enum->report_list) return NULL; - rinfo->report_id = ((struct hid_report *) list)->id; - break; - - case HID_REPORT_ID_NEXT: - list = (struct list_head *) - report_enum->report_id_hash[rinfo->report_id & - HID_REPORT_ID_MASK]; - if (list == NULL) return NULL; - list = list->next; - if (list == &report_enum->report_list) return NULL; - rinfo->report_id = ((struct hid_report *) list)->id; - break; - default: - return NULL; - } + switch (flags) { + case 0: /* Nothing to do -- report_id is already set correctly */ + break; + + case HID_REPORT_ID_FIRST: + list = report_enum->report_list.next; + if (list == &report_enum->report_list) return NULL; + rinfo->report_id = ((struct hid_report *) list)->id; + break; + + case HID_REPORT_ID_NEXT: + list = (struct list_head *) + report_enum->report_id_hash[rinfo->report_id & HID_REPORT_ID_MASK]; + if (list == NULL) return NULL; + list = list->next; + if (list == &report_enum->report_list) return NULL; + rinfo->report_id = ((struct hid_report *) list)->id; + break; + + default: + return NULL; } return report_enum->report_id_hash[rinfo->report_id]; @@ -152,11 +154,8 @@ hiddev_lookup_usage(struct hid_device *hid, struct hiddev_usage_ref *uref) return NULL; } -/* - * This is where hid.c calls into hiddev to pass an event that occurred over - * the interrupt pipe - */ -void hiddev_hid_event(struct hid_device *hid, struct hiddev_usage_ref *uref) +static void hiddev_send_event(struct hid_device *hid, + struct hiddev_usage_ref *uref) { struct hiddev *hiddev = hid->hiddev; struct hiddev_list *list = hiddev->list; @@ -177,6 +176,44 @@ void hiddev_hid_event(struct hid_device *hid, struct hiddev_usage_ref *uref) } /* + * This is where hid.c calls into hiddev to pass an event that occurred over + * the interrupt pipe + */ +void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, + struct hid_usage *usage, __s32 value) +{ + unsigned type = field->report_type; + struct hiddev_usage_ref uref; + + uref.report_type = + (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT : + ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT : + ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0)); + uref.report_id = field->report->id; + uref.field_index = field->index; + uref.usage_index = (usage - field->usage); + uref.usage_code = usage->hid; + uref.value = value; + + hiddev_send_event(hid, &uref); +} + + +void hiddev_report_event(struct hid_device *hid, struct hid_report *report) +{ + unsigned type = report->type; + struct hiddev_usage_ref uref; + + memset(&uref, 0, sizeof(uref)); + uref.report_type = + (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT : + ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT : + ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0)); + uref.report_id = report->id; + + hiddev_send_event(hid, &uref); +} +/* * fasync file op */ static int hiddev_fasync(int fd, struct file *file, int on) @@ -256,8 +293,7 @@ static int hiddev_open(struct inode * inode, struct file * file) { /* * "write" file op */ -static ssize_t hiddev_write(struct file * file, const char * buffer, - size_t count, loff_t *ppos) +static ssize_t hiddev_write(struct file * file, const char * buffer, size_t count, loff_t *ppos) { return -EINVAL; } @@ -265,8 +301,7 @@ static ssize_t hiddev_write(struct file * file, const char * buffer, /* * "read" file op */ -static ssize_t hiddev_read(struct file * file, char * buffer, size_t count, - loff_t *ppos) +static ssize_t hiddev_read(struct file * file, char * buffer, size_t count, loff_t *ppos) { DECLARE_WAITQUEUE(wait, current); struct hiddev_list *list = file->private_data; @@ -354,17 +389,20 @@ static unsigned int hiddev_poll(struct file *file, poll_table *wait) /* * "ioctl" file op */ -static int hiddev_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct hiddev_list *list = file->private_data; struct hiddev *hiddev = list->hiddev; struct hid_device *hid = hiddev->hid; struct usb_device *dev = hid->dev; + struct hiddev_collection_info cinfo; struct hiddev_report_info rinfo; + struct hiddev_field_info finfo; struct hiddev_usage_ref uref; + struct hiddev_devinfo dinfo; struct hid_report *report; struct hid_field *field; + int i; if (!hiddev->exist) return -EIO; @@ -376,11 +414,18 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, case HIDIOCAPPLICATION: if (arg < 0 || arg >= hid->maxapplication) return -EINVAL; - return hid->application[arg]; + + for (i = 0; i < hid->maxcollection; i++) + if (hid->collection[i].type == + HID_COLLECTION_APPLICATION && arg-- == 0) + break; + + if (i == hid->maxcollection) + return -EINVAL; + + return hid->collection[i].usage; case HIDIOCGDEVINFO: - { - struct hiddev_devinfo dinfo; dinfo.bustype = BUS_USB; dinfo.busnum = dev->bus->busnum; dinfo.devnum = dev->devnum; @@ -389,11 +434,12 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, dinfo.product = dev->descriptor.idProduct; dinfo.version = dev->descriptor.bcdDevice; dinfo.num_applications = hid->maxapplication; - return copy_to_user((void *) arg, &dinfo, sizeof(dinfo)); - } + if (copy_to_user((void *) arg, &dinfo, sizeof(dinfo))) + return -EFAULT; case HIDIOCGFLAG: - return put_user(list->flags, (int *) arg); + if (put_user(list->flags, (int *) arg)) + return -EFAULT; case HIDIOCSFLAG: { @@ -438,7 +484,6 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, } case HIDIOCINITREPORT: - hid_init_reports(hid); return 0; @@ -480,11 +525,10 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, rinfo.num_fields = report->maxfield; - return copy_to_user((void *) arg, &rinfo, sizeof(rinfo)); + if (copy_to_user((void *) arg, &rinfo, sizeof(rinfo))) + return -EFAULT; case HIDIOCGFIELDINFO: - { - struct hiddev_field_info finfo; if (copy_from_user(&finfo, (void *) arg, sizeof(finfo))) return -EFAULT; rinfo.report_type = finfo.report_type; @@ -512,8 +556,8 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, finfo.unit_exponent = field->unit_exponent; finfo.unit = field->unit; - return copy_to_user((void *) arg, &finfo, sizeof(finfo)); - } + if (copy_to_user((void *) arg, &finfo, sizeof(finfo))) + return -EFAULT; case HIDIOCGUCODE: if (copy_from_user(&uref, (void *) arg, sizeof(uref))) @@ -533,12 +577,18 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, uref.usage_code = field->usage[uref.usage_index].hid; - return copy_to_user((void *) arg, &uref, sizeof(uref)); + if (copy_to_user((void *) arg, &uref, sizeof(uref))) + return -EFAULT; case HIDIOCGUSAGE: + case HIDIOCSUSAGE: + case HIDIOCGCOLLECTIONINDEX: if (copy_from_user(&uref, (void *) arg, sizeof(uref))) return -EFAULT; + if (cmd != HIDIOCGUSAGE && uref.report_type == HID_REPORT_TYPE_INPUT) + return -EINVAL; + if (uref.report_id == HID_REPORT_ID_UNKNOWN) { field = hiddev_lookup_usage(hid, &uref); if (field == NULL) @@ -557,37 +607,36 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, return -EINVAL; } - uref.value = field->value[uref.usage_index]; - - return copy_to_user((void *) arg, &uref, sizeof(uref)); + switch (cmd) { + case HIDIOCGUSAGE: + uref.value = field->value[uref.usage_index]; + if (copy_to_user((void *) arg, &uref, sizeof(uref))) + return -EFAULT; + return 0; - case HIDIOCSUSAGE: - if (copy_from_user(&uref, (void *) arg, sizeof(uref))) - return -EFAULT; + case HIDIOCSUSAGE: + field->value[uref.usage_index] = uref.value; + return 0; - if (uref.report_type == HID_REPORT_TYPE_INPUT) - return -EINVAL; + case HIDIOCGCOLLECTIONINDEX: + return field->usage[uref.usage_index].collection_index; + } - if (uref.report_id == HID_REPORT_ID_UNKNOWN) { - field = hiddev_lookup_usage(hid, &uref); - if (field == NULL) - return -EINVAL; - } else { - rinfo.report_type = uref.report_type; - rinfo.report_id = uref.report_id; - if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) - return -EINVAL; + return 0; - if (uref.field_index >= report->maxfield) - return -EINVAL; + case HIDIOCGCOLLECTIONINFO: + if (copy_from_user(&cinfo, (void *) arg, sizeof(cinfo))) + return -EFAULT; - field = report->field[uref.field_index]; - if (uref.usage_index >= field->maxusage) - return -EINVAL; - } + if (cinfo.index >= hid->maxcollection) + return -EINVAL; - field->value[uref.usage_index] = uref.value; + cinfo.type = hid->collection[cinfo.index].type; + cinfo.usage = hid->collection[cinfo.index].usage; + cinfo.level = hid->collection[cinfo.index].level; + if (copy_to_user((void *) arg, &cinfo, sizeof(cinfo))) + return -EFAULT; return 0; default: @@ -628,11 +677,13 @@ int hiddev_connect(struct hid_device *hid) int retval; char devfs_name[16]; - for (i = 0; i < hid->maxapplication; i++) - if (!IS_INPUT_APPLICATION(hid->application[i])) + for (i = 0; i < hid->maxcollection; i++) + if (hid->collection[i].type == + HID_COLLECTION_APPLICATION && + !IS_INPUT_APPLICATION(hid->collection[i].usage)) break; - if (i == hid->maxapplication) + if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDDEV) == 0) return -1; retval = usb_register_dev(&hiddev_fops, HIDDEV_MINOR_BASE, 1, &minor); @@ -657,10 +708,8 @@ int hiddev_connect(struct hid_device *hid) sprintf(devfs_name, "hiddev%d", minor); hiddev->devfs = devfs_register(hiddev_devfs_handle, devfs_name, - DEVFS_FL_DEFAULT, USB_MAJOR, - minor + HIDDEV_MINOR_BASE, - S_IFCHR | S_IRUGO | S_IWUSR, - &hiddev_fops, NULL); + DEVFS_FL_DEFAULT, USB_MAJOR, minor + HIDDEV_MINOR_BASE, + S_IFCHR | S_IRUGO | S_IWUSR, &hiddev_fops, NULL); hid->minor = minor; hid->hiddev = hiddev; diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 9b22b2acb40c..8c3baaabfb02 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -344,6 +344,12 @@ unsigned int usb_stor_transfer_length(Scsi_Cmnd *srb) len = srb->request_bufflen; } + /* According to the linux-scsi people, any command sent which + * violates this invariant is a bug. In the hopes of removing + * all the complex logic above, let's find them and eliminate them. + */ + BUG_ON(len != srb->request_bufflen); + return len; } diff --git a/drivers/video/Config.in b/drivers/video/Config.in index 9a106fbce63e..618e7e28ca9f 100644 --- a/drivers/video/Config.in +++ b/drivers/video/Config.in @@ -91,10 +91,10 @@ if [ "$CONFIG_FB" = "y" ]; then if [ "$CONFIG_HP300" = "y" ]; then define_bool CONFIG_FB_HP300 y fi - if [ "$ARCH" = "alpha" ]; then + if [ "$CONFIG_ALPHA" = "y" ]; then tristate ' TGA framebuffer support' CONFIG_FB_TGA fi - if [ "$ARCH" = "i386" ]; then + if [ "$CONFIG_X86" = "y" ]; then bool ' VESA VGA graphics console' CONFIG_FB_VESA tristate ' VGA 16-color graphics console' CONFIG_FB_VGA16 tristate ' Hercules mono graphics console (EXPERIMENTAL)' CONFIG_FB_HGA @@ -158,16 +158,16 @@ if [ "$CONFIG_FB" = "y" ]; then tristate ' Permedia3 support (EXPERIMENTAL)' CONFIG_FB_PM3 fi fi - if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then + if [ "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" ]; then bool ' SBUS and UPA framebuffers' CONFIG_FB_SBUS if [ "$CONFIG_FB_SBUS" != "n" ]; then - if [ "$ARCH" = "sparc64" ]; then + if [ "$CONFIG_SPARC64" = "y" ]; then bool ' Creator/Creator3D support' CONFIG_FB_CREATOR fi bool ' CGsix (GX,TurboGX) support' CONFIG_FB_CGSIX bool ' BWtwo support' CONFIG_FB_BWTWO bool ' CGthree support' CONFIG_FB_CGTHREE - if [ "$ARCH" = "sparc" ]; then + if [ "$CONFIG_SPARC32" = "y" ]; then bool ' TCX (SS4/SS5 only) support' CONFIG_FB_TCX bool ' CGfourteen (SX) support' CONFIG_FB_CGFOURTEEN bool ' P9100 (Sparcbook 3 only) support' CONFIG_FB_P9100 @@ -175,7 +175,7 @@ if [ "$CONFIG_FB" = "y" ]; then bool ' Leo (ZX) support' CONFIG_FB_LEO fi fi - if [ "$ARCH" = "sparc" ]; then + if [ "$CONFIG_SPARC32" = "y" ]; then if [ "$CONFIG_PCI" != "n" ]; then bool ' PCI framebuffers' CONFIG_FB_PCI if [ "$CONFIG_FB_PCI" != "n" ]; then @@ -183,7 +183,7 @@ if [ "$CONFIG_FB" = "y" ]; then fi fi fi - if [ "$ARCH" = "sparc64" ]; then + if [ "$CONFIG_SPARC64" = "y" ]; then if [ "$CONFIG_PCI" != "n" ]; then bool ' PCI framebuffers' CONFIG_FB_PCI if [ "$CONFIG_FB_PCI" != "n" ]; then @@ -208,7 +208,7 @@ if [ "$CONFIG_FB" = "y" ]; then bool ' TMPTX3912/PR31700 frame buffer support' CONFIG_FB_TX3912 fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate ' Virtual Frame Buffer support (ONLY FOR TESTING!)' CONFIG_FB_VIRTUAL + tristate ' Virtual Frame Buffer support (ONLY FOR TESTING!) (EXPERIMENTAL)' CONFIG_FB_VIRTUAL fi bool ' Advanced low level driver options' CONFIG_FBCON_ADVANCED @@ -427,7 +427,7 @@ if [ "$CONFIG_FB" = "y" ]; then fi fi bool ' Support only 8 pixels wide fonts' CONFIG_FBCON_FONTWIDTH8_ONLY - if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then + if [ "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" ]; then bool ' Sparc console 8x16 font' CONFIG_FONT_SUN8x16 if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then bool ' Sparc console 12x22 font (not supported by all drivers)' CONFIG_FONT_SUN12x22 diff --git a/fs/Config.in b/fs/Config.in index dd36ea438dde..ffb3b91725c0 100644 --- a/fs/Config.in +++ b/fs/Config.in @@ -6,7 +6,7 @@ comment 'File systems' bool 'Quota support' CONFIG_QUOTA dep_tristate ' Old quota format support' CONFIG_QFMT_V1 $CONFIG_QUOTA -dep_tristate ' VFS v0 quota format support' CONFIG_QFMT_V2 $CONFIG_QUOTA +dep_tristate ' Quota format v2 support' CONFIG_QFMT_V2 $CONFIG_QUOTA if [ "$CONFIG_QUOTA" = "y" ]; then define_bool CONFIG_QUOTACTL y fi diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 798875bd134e..fe9d8033cc1a 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -1105,7 +1105,7 @@ static int ext2_update_inode(struct inode * inode, int do_sync) raw_inode->i_frag = ei->i_frag_no; raw_inode->i_fsize = ei->i_frag_size; raw_inode->i_file_acl = cpu_to_le32(ei->i_file_acl); - if (S_ISDIR(inode->i_mode)) + if (!S_ISREG(inode->i_mode)) raw_inode->i_dir_acl = cpu_to_le32(ei->i_dir_acl); else { raw_inode->i_size_high = cpu_to_le32(inode->i_size >> 32); diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c index fde2cc59f22b..73845f10a81a 100644 --- a/fs/lockd/xdr.c +++ b/fs/lockd/xdr.c @@ -561,11 +561,10 @@ nlmclt_decode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp) #define nlmclt_decode_norep NULL #define PROC(proc, argtype, restype) \ - { "nlm_" #proc, \ - (kxdrproc_t) nlmclt_encode_##argtype, \ - (kxdrproc_t) nlmclt_decode_##restype, \ - MAX(NLM_##argtype##_sz, NLM_##restype##_sz) << 2, \ - 0 \ + { .p_procname = "nlm_" #proc, \ + .p_encode = (kxdrproc_t) nlmclt_encode_##argtype, \ + .p_decode = (kxdrproc_t) nlmclt_decode_##restype, \ + .p_bufsiz = MAX(NLM_##argtype##_sz, NLM_##restype##_sz) << 2 \ } static struct rpc_procinfo nlm_procedures[] = { diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c index 6745444edcdf..42ab448d6b33 100644 --- a/fs/lockd/xdr4.c +++ b/fs/lockd/xdr4.c @@ -566,12 +566,11 @@ nlm4clt_decode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp) */ #define nlm4clt_decode_norep NULL -#define PROC(proc, argtype, restype) \ - { "nlm4_" #proc, \ - (kxdrproc_t) nlm4clt_encode_##argtype, \ - (kxdrproc_t) nlm4clt_decode_##restype, \ - MAX(NLM4_##argtype##_sz, NLM4_##restype##_sz) << 2, \ - 0 \ +#define PROC(proc, argtype, restype) \ + { .p_procname = "nlm4_" #proc, \ + .p_encode = (kxdrproc_t) nlm4clt_encode_##argtype, \ + .p_decode = (kxdrproc_t) nlm4clt_decode_##restype, \ + .p_bufsiz = MAX(NLM4_##argtype##_sz, NLM4_##restype##_sz) << 2 \ } static struct rpc_procinfo nlm4_procedures[] = { diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index 660fb7f27c07..df06b7fdbf6a 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c @@ -671,33 +671,32 @@ nfs_stat_to_errno(int stat) # define MAX(a, b) (((a) > (b))? (a) : (b)) #endif -#define PROC(proc, argtype, restype) \ - { "nfs_" #proc, \ - (kxdrproc_t) nfs_xdr_##argtype, \ - (kxdrproc_t) nfs_xdr_##restype, \ - MAX(NFS_##argtype##_sz,NFS_##restype##_sz) << 2, \ - 0 \ +#define PROC(proc, argtype, restype, timer) \ + { .p_procname = "nfs_" #proc, \ + .p_encode = (kxdrproc_t) nfs_xdr_##argtype, \ + .p_decode = (kxdrproc_t) nfs_xdr_##restype, \ + .p_bufsiz = MAX(NFS_##argtype##_sz,NFS_##restype##_sz) << 2, \ + .p_timer = timer \ } - static struct rpc_procinfo nfs_procedures[18] = { - PROC(null, enc_void, dec_void), - PROC(getattr, fhandle, attrstat), - PROC(setattr, sattrargs, attrstat), - PROC(root, enc_void, dec_void), - PROC(lookup, diropargs, diropres), - PROC(readlink, readlinkargs, readlinkres), - PROC(read, readargs, readres), - PROC(writecache, enc_void, dec_void), - PROC(write, writeargs, writeres), - PROC(create, createargs, diropres), - PROC(remove, diropargs, stat), - PROC(rename, renameargs, stat), - PROC(link, linkargs, stat), - PROC(symlink, symlinkargs, stat), - PROC(mkdir, createargs, diropres), - PROC(rmdir, diropargs, stat), - PROC(readdir, readdirargs, readdirres), - PROC(statfs, fhandle, statfsres), + PROC(null, enc_void, dec_void, 0), + PROC(getattr, fhandle, attrstat, 1), + PROC(setattr, sattrargs, attrstat, 0), + PROC(root, enc_void, dec_void, 0), + PROC(lookup, diropargs, diropres, 2), + PROC(readlink, readlinkargs, readlinkres, 3), + PROC(read, readargs, readres, 3), + PROC(writecache, enc_void, dec_void, 0), + PROC(write, writeargs, writeres, 4), + PROC(create, createargs, diropres, 0), + PROC(remove, diropargs, stat, 0), + PROC(rename, renameargs, stat, 0), + PROC(link, linkargs, stat, 0), + PROC(symlink, symlinkargs, stat, 0), + PROC(mkdir, createargs, diropres, 0), + PROC(rmdir, diropargs, stat, 0), + PROC(readdir, readdirargs, readdirres, 3), + PROC(statfs, fhandle, statfsres, 0), }; struct rpc_version nfs_version2 = { diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index d13b938d9b70..d25de78172ae 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -988,37 +988,37 @@ nfs3_xdr_commitres(struct rpc_rqst *req, u32 *p, struct nfs_writeres *res) # define MAX(a, b) (((a) > (b))? (a) : (b)) #endif -#define PROC(proc, argtype, restype) \ - { "nfs3_" #proc, \ - (kxdrproc_t) nfs3_xdr_##argtype, \ - (kxdrproc_t) nfs3_xdr_##restype, \ - MAX(NFS3_##argtype##_sz,NFS3_##restype##_sz) << 2, \ - 0 \ +#define PROC(proc, argtype, restype, timer) \ + { .p_procname = "nfs3_" #proc, \ + .p_encode = (kxdrproc_t) nfs3_xdr_##argtype, \ + .p_decode = (kxdrproc_t) nfs3_xdr_##restype, \ + .p_bufsiz = MAX(NFS3_##argtype##_sz,NFS3_##restype##_sz) << 2, \ + .p_timer = timer \ } static struct rpc_procinfo nfs3_procedures[22] = { - PROC(null, enc_void, dec_void), - PROC(getattr, fhandle, attrstat), - PROC(setattr, sattrargs, wccstat), - PROC(lookup, diropargs, lookupres), - PROC(access, accessargs, accessres), - PROC(readlink, readlinkargs, readlinkres), - PROC(read, readargs, readres), - PROC(write, writeargs, writeres), - PROC(create, createargs, createres), - PROC(mkdir, mkdirargs, createres), - PROC(symlink, symlinkargs, createres), - PROC(mknod, mknodargs, createres), - PROC(remove, diropargs, wccstat), - PROC(rmdir, diropargs, wccstat), - PROC(rename, renameargs, renameres), - PROC(link, linkargs, linkres), - PROC(readdir, readdirargs, readdirres), - PROC(readdirplus, readdirargs, readdirres), - PROC(fsstat, fhandle, fsstatres), - PROC(fsinfo, fhandle, fsinfores), - PROC(pathconf, fhandle, pathconfres), - PROC(commit, commitargs, commitres), + PROC(null, enc_void, dec_void, 0), + PROC(getattr, fhandle, attrstat, 1), + PROC(setattr, sattrargs, wccstat, 0), + PROC(lookup, diropargs, lookupres, 2), + PROC(access, accessargs, accessres, 1), + PROC(readlink, readlinkargs, readlinkres, 3), + PROC(read, readargs, readres, 3), + PROC(write, writeargs, writeres, 4), + PROC(create, createargs, createres, 0), + PROC(mkdir, mkdirargs, createres, 0), + PROC(symlink, symlinkargs, createres, 0), + PROC(mknod, mknodargs, createres, 0), + PROC(remove, diropargs, wccstat, 0), + PROC(rmdir, diropargs, wccstat, 0), + PROC(rename, renameargs, renameres, 0), + PROC(link, linkargs, linkres, 0), + PROC(readdir, readdirargs, readdirres, 3), + PROC(readdirplus, readdirargs, readdirres, 3), + PROC(fsstat, fhandle, fsstatres, 0), + PROC(fsinfo, fhandle, fsinfores, 0), + PROC(pathconf, fhandle, pathconfres, 0), + PROC(commit, commitargs, commitres, 5), }; struct rpc_version nfs_version3 = { diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index 030c0e205eb3..3698607d0642 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog @@ -1,14 +1,19 @@ ToDo: - Find and fix bugs. - - W.r.t. s_maxbytes still need to be careful on reading/truncating as - there are dragons lurking in the details, e.g. read_inode() currently - does no checks for file size wrt s_maxbytes. So what happens when a - user open()s a file with i_size > s_maxbytes? Should read_inode() - truncate the visible i_size? Will the user just get -E2BIG (or - whatever) on open()? Or will (s)he be able to open() but lseek() and - read() will fail when s_maxbytes is reached? -> Investigate this. - Enable NFS exporting of NTFS. +2.0.21 - Check for, and refuse to work with too large files/directories/volumes. + + - Limit volume size at mount time to 2TiB on architectures where + unsigned long is 32-bits (fs/ntfs/super.c::parse_ntfs_boot_sector()). + This is the most we can do without overflowing the 32-bit limit of + the block device size imposed on us by sb_bread() and sb_getblk() + for the time being. + - Limit file/directory size at open() time to 16TiB on architectures + where unsigned long is 32-bits (fs/ntfs/file.c::ntfs_file_open() and + fs/ntfs/dir.c::ntfs_dir_open()). This is the most we can do without + overflowing the page cache page index. + 2.0.20 - Support non-resident directory index bitmaps, fix page leak in readdir. - Move the directory index bitmap to use an attribute inode instead of diff --git a/fs/ntfs/Makefile b/fs/ntfs/Makefile index 9153ec60a42b..1edd6826d015 100644 --- a/fs/ntfs/Makefile +++ b/fs/ntfs/Makefile @@ -5,7 +5,7 @@ obj-$(CONFIG_NTFS_FS) += ntfs.o ntfs-objs := aops.o attrib.o compress.o debug.o dir.o file.o inode.o mft.o \ mst.o namei.o super.o sysctl.o time.o unistr.o upcase.o -EXTRA_CFLAGS = -DNTFS_VERSION=\"2.0.20\" +EXTRA_CFLAGS = -DNTFS_VERSION=\"2.0.21\" ifeq ($(CONFIG_NTFS_DEBUG),y) EXTRA_CFLAGS += -DDEBUG diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c index 546cbf0f58be..4a32e16a093a 100644 --- a/fs/ntfs/dir.c +++ b/fs/ntfs/dir.c @@ -1370,9 +1370,35 @@ err_out: return err; } +/** + * ntfs_dir_open - called when an inode is about to be opened + * @vi: inode to be opened + * @filp: file structure describing the inode + * + * Limit directory size to the page cache limit on architectures where unsigned + * long is 32-bits. This is the most we can do for now without overflowing the + * page cache page index. Doing it this way means we don't run into problems + * because of existing too large directories. It would be better to allow the + * user to read the accessible part of the directory but I doubt very much + * anyone is going to hit this check on a 32-bit architecture, so there is no + * point in adding the extra complexity required to support this. + * + * On 64-bit architectures, the check is hopefully optimized away by the + * compiler. + */ +static int ntfs_dir_open(struct inode *vi, struct file *filp) +{ + if (sizeof(unsigned long) < 8) { + if (vi->i_size > MAX_LFS_FILESIZE) + return -EFBIG; + } + return 0; +} + struct file_operations ntfs_dir_ops = { llseek: generic_file_llseek, /* Seek inside directory. */ read: generic_read_dir, /* Return -EISDIR. */ readdir: ntfs_readdir, /* Read directory contents. */ + open: ntfs_dir_open, /* Open directory. */ }; diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index ed2551251622..698aef36db6f 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -21,11 +21,38 @@ #include "ntfs.h" +/** + * ntfs_file_open - called when an inode is about to be opened + * @vi: inode to be opened + * @filp: file structure describing the inode + * + * Limit file size to the page cache limit on architectures where unsigned long + * is 32-bits. This is the most we can do for now without overflowing the page + * cache page index. Doing it this way means we don't run into problems because + * of existing too large files. It would be better to allow the user to read + * the beginning of the file but I doubt very much anyone is going to hit this + * check on a 32-bit architecture, so there is no point in adding the extra + * complexity required to support this. + * + * On 64-bit architectures, the check is hopefully optimized away by the + * compiler. + * + * After the check passes, just call generic_file_open() to do its work. + */ +static int ntfs_file_open(struct inode *vi, struct file *filp) +{ + if (sizeof(unsigned long) < 8) { + if (vi->i_size > MAX_LFS_FILESIZE) + return -EFBIG; + } + return generic_file_open(vi, filp); +} + struct file_operations ntfs_file_ops = { - llseek: generic_file_llseek, /* Seek inside file. */ - read: generic_file_read, /* Read from file. */ - mmap: generic_file_mmap, /* Mmap file. */ - open: generic_file_open, /* Open file. */ + llseek: generic_file_llseek, /* Seek inside file. */ + read: generic_file_read, /* Read from file. */ + mmap: generic_file_mmap, /* Mmap file. */ + open: ntfs_file_open, /* Open file. */ }; struct inode_operations ntfs_file_inode_ops = {}; diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 74587a8eee66..3454200fc42e 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -2,7 +2,7 @@ * super.c - NTFS kernel super block handling. Part of the Linux-NTFS project. * * Copyright (c) 2001,2002 Anton Altaparmakov. - * Copyright (C) 2001,2002 Richard Russon. + * Copyright (c) 2001,2002 Richard Russon. * * This program/include file is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published @@ -413,7 +413,7 @@ not_ntfs: } /** - * read_boot_sector - read the NTFS boot sector of a device + * read_ntfs_boot_sector - read the NTFS boot sector of a device * @sb: super block of device to read the boot sector from * @silent: if true, suppress all output * @@ -613,6 +613,20 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) } vol->nr_clusters = ll; ntfs_debug("vol->nr_clusters = 0x%Lx", (long long)vol->nr_clusters); + /* + * On an architecture where unsigned long is 32-bits, we restrict the + * volume size to 2TiB (2^41). On a 64-bit architecture, the compiler + * will hopefully optimize the whole check away. + */ + if (sizeof(unsigned long) < 8) { + if ((ll << vol->cluster_size_bits) >= (1ULL << 41)) { + ntfs_error(vol->sb, "Volume size (%LuTiB) is too large " + "for this architecture. Maximim " + "supported is 2TiB. Sorry.", + ll >> (40 - vol->cluster_size_bits)); + return FALSE; + } + } ll = sle64_to_cpu(b->mft_lcn); if (ll >= vol->nr_clusters) { ntfs_error(vol->sb, "MFT LCN is beyond end of volume. Weird."); diff --git a/fs/partitions/Config.in b/fs/partitions/Config.in index 9f2b2ed19dcf..9b8d861c8c62 100644 --- a/fs/partitions/Config.in +++ b/fs/partitions/Config.in @@ -34,7 +34,7 @@ if [ "$CONFIG_PARTITION_ADVANCED" = "y" ]; then bool ' Sun partition tables support' CONFIG_SUN_PARTITION bool ' EFI GUID Partition support' CONFIG_EFI_PARTITION else - if [ "$ARCH" = "alpha" ]; then + if [ "$CONFIG_ALPHA" = "y" ]; then define_bool CONFIG_OSF_PARTITION y fi if [ "$CONFIG_AMIGA" != "y" -a "$CONFIG_ATARI" != "y" -a \ @@ -65,7 +65,7 @@ else if [ "$CONFIG_DECSTATION" = "y" ]; then define_bool CONFIG_ULTRIX_PARTITION y fi - if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then + if [ "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" ]; then define_bool CONFIG_SUN_PARTITION y fi fi diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c index 08de2eac38f2..f8f987998fe3 100644 --- a/fs/partitions/msdos.c +++ b/fs/partitions/msdos.c @@ -453,8 +453,8 @@ static int handle_ide_mess(struct block_device *bdev) /* * The i386 partition handling programs very often * make partitions end on cylinder boundaries. - * There is no need to do so, and Linux fdisk doesnt always - * do this, and Windows NT on Alpha doesnt do this either, + * There is no need to do so, and Linux fdisk doesn't always + * do this, and Windows NT on Alpha doesn't do this either, * but still, this helps to guess #heads. */ data = read_dev_sector(bdev, 0, §); diff --git a/fs/pipe.c b/fs/pipe.c index 07fcf8bb57c0..5df79242a4b8 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -216,7 +216,7 @@ pipe_write(struct file *filp, const char *buf, size_t count, loff_t *ppos) do { /* * Synchronous wake-up: it knows that this process - * is going to give up this CPU, so it doesnt have + * is going to give up this CPU, so it doesn't have * to do idle reschedules. */ wake_up_interruptible_sync(PIPE_WAIT(*inode)); diff --git a/include/asm-alpha/siginfo.h b/include/asm-alpha/siginfo.h index 42eb85ee5760..7f54a8019e10 100644 --- a/include/asm-alpha/siginfo.h +++ b/include/asm-alpha/siginfo.h @@ -6,7 +6,6 @@ #define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 4) #define HAVE_ARCH_COPY_SIGINFO -#define HAVE_ARCH_COPY_SIGINFO_TO_USER #include <asm-generic/siginfo.h> diff --git a/include/asm-cris/pgtable.h b/include/asm-cris/pgtable.h index 57e391330752..37ab897db8be 100644 --- a/include/asm-cris/pgtable.h +++ b/include/asm-cris/pgtable.h @@ -164,7 +164,7 @@ static inline void flush_tlb(void) */ #define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval)) /* - * (pmds are folded into pgds so this doesnt get actually called, + * (pmds are folded into pgds so this doesn't get actually called, * but the define is needed for a generic inline function.) */ #define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval) diff --git a/include/asm-cris/siginfo.h b/include/asm-cris/siginfo.h index a8c8c74dc9df..c1cd6d16928b 100644 --- a/include/asm-cris/siginfo.h +++ b/include/asm-cris/siginfo.h @@ -1,8 +1,6 @@ #ifndef _CRIS_SIGINFO_H #define _CRIS_SIGINFO_H -#define HAVE_ARCH_COPY_SIGINFO_TO_USER - #include <asm-generic/siginfo.h> #endif diff --git a/include/asm-m68k/mac_via.h b/include/asm-m68k/mac_via.h index ab8e23d9e519..d01672d44b0a 100644 --- a/include/asm-m68k/mac_via.h +++ b/include/asm-m68k/mac_via.h @@ -3,7 +3,7 @@ * * There are two of these on the Mac II. Some IRQ's are vectored * via them as are assorted bits and bobs - eg rtc, adb. The picture - * is a bit incomplete as the Mac documentation doesnt cover this well + * is a bit incomplete as the Mac documentation doesn't cover this well */ #ifndef _ASM_MAC_VIA_H_ diff --git a/include/asm-parisc/semaphore.h b/include/asm-parisc/semaphore.h index 1434908edb46..04eb43929c8a 100644 --- a/include/asm-parisc/semaphore.h +++ b/include/asm-parisc/semaphore.h @@ -53,7 +53,7 @@ extern inline void sema_init (struct semaphore *sem, int val) * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); * * i'd rather use the more flexible initialization above, but sadly - * GCC 2.7.2.3 emits a bogus warning. EGCS doesnt. Oh well. + * GCC 2.7.2.3 emits a bogus warning. EGCS doesn't. Oh well. */ atomic_set(&sem->count, val); sem->waking = 0; diff --git a/include/asm-sh/pgtable-2level.h b/include/asm-sh/pgtable-2level.h index a14015c43370..b11384a849cd 100644 --- a/include/asm-sh/pgtable-2level.h +++ b/include/asm-sh/pgtable-2level.h @@ -42,7 +42,7 @@ static inline void pgd_clear (pgd_t * pgdp) { } */ #define set_pte(pteptr, pteval) (*(pteptr) = pteval) /* - * (pmds are folded into pgds so this doesnt get actually called, + * (pmds are folded into pgds so this doesn't get actually called, * but the define is needed for a generic inline function.) */ #define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval) diff --git a/include/linux/brlock.h b/include/linux/brlock.h index 68c200512604..81d87c72ca1d 100644 --- a/include/linux/brlock.h +++ b/include/linux/brlock.h @@ -19,7 +19,7 @@ * * David S. Miller <davem@redhat.com> * - * David has an implementation that doesnt use atomic operations in + * David has an implementation that doesn't use atomic operations in * the read branch via memory ordering tricks - i guess we need to * split this up into a per-arch thing? The atomicity issue is a * secondary item in profiles, at least on x86 platforms. diff --git a/include/linux/fs.h b/include/linux/fs.h index 2b6008d56ca8..2ac85b8e28a3 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -988,7 +988,6 @@ extern int unregister_filesystem(struct file_system_type *); extern struct vfsmount *kern_mount(struct file_system_type *); extern int may_umount(struct vfsmount *); extern long do_mount(char *, char *, char *, unsigned long, void *); -extern void umount_tree(struct vfsmount *); #define kern_umount mntput diff --git a/include/linux/hiddev.h b/include/linux/hiddev.h index eb948560836d..0077b58559f5 100644 --- a/include/linux/hiddev.h +++ b/include/linux/hiddev.h @@ -49,6 +49,13 @@ struct hiddev_devinfo { unsigned num_applications; }; +struct hiddev_collection_info { + unsigned index; + unsigned type; + unsigned usage; + unsigned level; +}; + #define HID_STRING_SIZE 256 struct hiddev_string_descriptor { int index; @@ -64,9 +71,9 @@ struct hiddev_report_info { /* To do a GUSAGE/SUSAGE, fill in at least usage_code, report_type and * report_id. Set report_id to REPORT_ID_UNKNOWN if the rest of the fields * are unknown. Otherwise use a usage_ref struct filled in from a previous - * successful GUSAGE/SUSAGE call to save time. To actually send a value - * to the device, perform a SUSAGE first, followed by a SREPORT. If an - * INITREPORT is done, a GREPORT isn't necessary before a GUSAGE. + * successful GUSAGE call to save time. To actually send a value to the + * device, perform a SUSAGE first, followed by a SREPORT. An INITREPORT or a + * GREPORT isn't necessary for a GUSAGE to return valid data. */ #define HID_REPORT_ID_UNKNOWN 0xffffffff #define HID_REPORT_ID_FIRST 0x00000100 @@ -129,7 +136,7 @@ struct hiddev_usage_ref { * Protocol version. */ -#define HID_VERSION 0x010003 +#define HID_VERSION 0x010004 /* * IOCTLs (0x00 - 0x7f) @@ -150,6 +157,8 @@ struct hiddev_usage_ref { #define HIDIOCGUCODE _IOWR('H', 0x0D, struct hiddev_usage_ref) #define HIDIOCGFLAG _IOR('H', 0x0E, int) #define HIDIOCSFLAG _IOW('H', 0x0F, int) +#define HIDIOCGCOLLECTIONINDEX _IOW('H', 0x10, struct hiddev_usage_ref) +#define HIDIOCGCOLLECTIONINFO _IOWR('H', 0x11, struct hiddev_collection_info) /* * Flags to be used in HIDIOCSFLAG @@ -193,13 +202,17 @@ struct hiddev_usage_ref { #ifdef CONFIG_USB_HIDDEV int hiddev_connect(struct hid_device *); void hiddev_disconnect(struct hid_device *); -void hiddev_hid_event(struct hid_device *, struct hiddev_usage_ref *ref); +void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, + struct hid_usage *usage, __s32 value); +void hiddev_report_event(struct hid_device *hid, struct hid_report *report); int __init hiddev_init(void); void __exit hiddev_exit(void); #else -static inline void *hiddev_connect(struct hid_device *hid) { return NULL; } +static inline int hiddev_connect(struct hid_device *hid) { return -1; } static inline void hiddev_disconnect(struct hid_device *hid) { } -static inline void hiddev_event(struct hid_device *hid, unsigned int usage, int value) { } +static inline void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, + struct hid_usage *usage, __s32 value) { } +static inline void hiddev_report_event(struct hid_device *hid, struct hid_report *report) { } static inline int hiddev_init(void) { return 0; } static inline void hiddev_exit(void) { } #endif diff --git a/include/linux/namespace.h b/include/linux/namespace.h index 1113fe62d6cd..acd64b4ca117 100644 --- a/include/linux/namespace.h +++ b/include/linux/namespace.h @@ -14,6 +14,8 @@ struct namespace { void umount_tree(struct vfsmount *mnt); +extern void umount_tree(struct vfsmount *); + static inline void put_namespace(struct namespace *namespace) { if (atomic_dec_and_test(&namespace->count)) { diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 2a3e2dd69dc0..110e5b661b58 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -1,9 +1,6 @@ #ifndef _LINUX_NFS_XDR_H #define _LINUX_NFS_XDR_H -extern struct rpc_program nfs_program; -extern struct rpc_stat nfs_rpcstat; - struct nfs_fattr { unsigned short valid; /* which fields are valid */ __u64 pre_size; /* pre_op_attr.size */ @@ -354,5 +351,6 @@ extern struct nfs_rpc_ops nfs_v3_clientops; extern struct rpc_version nfs_version2; extern struct rpc_version nfs_version3; extern struct rpc_program nfs_program; +extern struct rpc_stat nfs_rpcstat; #endif diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index 7b02c3c82a33..2a9bbed805ad 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h @@ -59,7 +59,7 @@ typedef struct mddev_s mddev_t; typedef struct mdk_rdev_s mdk_rdev_t; #if (MINORBITS != 8) -#error MD doesnt handle bigger kdev yet +#error MD does not handle bigger kdev yet #endif #define MAX_MD_DEVS (1<<MINORBITS) /* Max number of md dev */ diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index be4c52c62c1c..d278df00ecb9 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -15,6 +15,7 @@ #include <linux/sunrpc/auth.h> #include <linux/sunrpc/stats.h> #include <linux/sunrpc/xdr.h> +#include <linux/sunrpc/timer.h> #include <asm/signal.h> /* @@ -52,6 +53,8 @@ struct rpc_clnt { unsigned int cl_flags; /* misc client flags */ unsigned long cl_hardmax; /* max hard timeout */ + struct rpc_rtt cl_rtt; /* RTO estimator data */ + struct rpc_portmap cl_pmap; /* port mapping */ struct rpc_wait_queue cl_bindwait; /* waiting on getport() */ @@ -91,6 +94,7 @@ struct rpc_procinfo { kxdrproc_t p_decode; /* XDR decode function */ unsigned int p_bufsiz; /* req. buffer size */ unsigned int p_count; /* call count */ + unsigned int p_timer; /* Which RTT timer to use */ }; #define rpcproc_bufsiz(clnt, proc) ((clnt)->cl_procinfo[proc].p_bufsiz) @@ -98,6 +102,7 @@ struct rpc_procinfo { #define rpcproc_decode(clnt, proc) ((clnt)->cl_procinfo[proc].p_decode) #define rpcproc_name(clnt, proc) ((clnt)->cl_procinfo[proc].p_procname) #define rpcproc_count(clnt, proc) ((clnt)->cl_procinfo[proc].p_count) +#define rpcproc_timer(clnt, proc) ((clnt)->cl_procinfo[proc].p_timer) #define RPC_CONGESTED(clnt) (RPCXPRT_CONGESTED((clnt)->cl_xprt)) #define RPC_PEERADDR(clnt) (&(clnt)->cl_xprt->addr) diff --git a/include/linux/sunrpc/timer.h b/include/linux/sunrpc/timer.h new file mode 100644 index 000000000000..35b5a5c25170 --- /dev/null +++ b/include/linux/sunrpc/timer.h @@ -0,0 +1,41 @@ +/* + * linux/include/linux/sunrpc/timer.h + * + * Declarations for the RPC transport timer. + * + * Copyright (C) 2002 Trond Myklebust <trond.myklebust@fys.uio.no> + */ + +#ifndef _LINUX_SUNRPC_TIMER_H +#define _LINUX_SUNRPC_TIMER_H + +#include <asm/atomic.h> + +struct rpc_rtt { + long timeo; /* default timeout value */ + long srtt[5]; /* smoothed round trip time << 3 */ + long sdrtt[5]; /* soothed medium deviation of RTT */ + atomic_t ntimeouts; /* Global count of the number of timeouts */ +}; + + +extern void rpc_init_rtt(struct rpc_rtt *rt, long timeo); +extern void rpc_update_rtt(struct rpc_rtt *rt, int timer, long m); +extern long rpc_calc_rto(struct rpc_rtt *rt, int timer); + +static inline void rpc_inc_timeo(struct rpc_rtt *rt) +{ + atomic_inc(&rt->ntimeouts); +} + +static inline void rpc_clear_timeo(struct rpc_rtt *rt) +{ + atomic_set(&rt->ntimeouts, 0); +} + +static inline int rpc_ntimeo(struct rpc_rtt *rt) +{ + return atomic_read(&rt->ntimeouts); +} + +#endif /* _LINUX_SUNRPC_TIMER_H */ diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index 31a27bf00e41..0a247f460ff7 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h @@ -19,7 +19,7 @@ * The transport code maintains an estimate on the maximum number of out- * standing RPC requests, using a smoothed version of the congestion * avoidance implemented in 44BSD. This is basically the Van Jacobson - * slow start algorithm: If a retransmit occurs, the congestion window is + * congestion algorithm: If a retransmit occurs, the congestion window is * halved; otherwise, it is incremented by 1/cwnd when * * - a reply is received and @@ -32,15 +32,13 @@ * Note: on machines with low memory we should probably use a smaller * MAXREQS value: At 32 outstanding reqs with 8 megs of RAM, fragment * reassembly will frequently run out of memory. - * Come Linux 2.3, we'll handle fragments directly. */ -#define RPC_MAXCONG 16 -#define RPC_MAXREQS (RPC_MAXCONG + 1) -#define RPC_CWNDSCALE 256 +#define RPC_MAXCONG (16) +#define RPC_MAXREQS RPC_MAXCONG +#define RPC_CWNDSCALE (256) #define RPC_MAXCWND (RPC_MAXCONG * RPC_CWNDSCALE) -#define RPC_INITCWND RPC_CWNDSCALE -#define RPCXPRT_CONGESTED(xprt) \ - ((xprt)->cong >= (xprt)->cwnd) +#define RPC_INITCWND (RPC_MAXCWND >> 1) +#define RPCXPRT_CONGESTED(xprt) ((xprt)->cong >= (xprt)->cwnd) /* Default timeout values */ #define RPC_MAX_UDP_TIMEOUT (60*HZ) @@ -83,6 +81,7 @@ struct rpc_rqst { struct rpc_task * rq_task; /* RPC task data */ __u32 rq_xid; /* request XID */ struct rpc_rqst * rq_next; /* free list */ + int rq_cong; /* has incremented xprt->cong */ int rq_received; /* receive completed */ struct list_head rq_list; @@ -98,9 +97,9 @@ struct rpc_rqst { u32 rq_bytes_sent; /* Bytes we have sent */ -#ifdef RPC_PROFILE - unsigned long rq_xtime; /* when transmitted */ -#endif + long rq_xtime; /* when transmitted */ + int rq_ntimeo; + int rq_nresend; }; #define rq_svec rq_snd_buf.head #define rq_slen rq_snd_buf.len @@ -122,9 +121,9 @@ struct rpc_xprt { unsigned long cong; /* current congestion */ unsigned long cwnd; /* congestion window */ - unsigned long congtime; /* hold cwnd until then */ struct rpc_wait_queue sending; /* requests waiting to send */ + struct rpc_wait_queue resend; /* requests waiting to resend */ struct rpc_wait_queue pending; /* requests in flight */ struct rpc_wait_queue backlog; /* waiting for slot */ struct rpc_rqst * free; /* free slots */ diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h index 227ad0934c79..6f668c171107 100644 --- a/include/linux/vt_kern.h +++ b/include/linux/vt_kern.h @@ -91,6 +91,5 @@ void complete_change_console(unsigned int new_console); int vt_waitactive(int vt); void change_console(unsigned int); void reset_vc(unsigned int new_console); -int vt_waitactive(int vt); #endif /* _VT_KERN_H */ diff --git a/include/net/tcp.h b/include/net/tcp.h index 8a9322cd0754..ae3b35eb282e 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -456,7 +456,6 @@ extern int sysctl_tcp_syncookies; extern int sysctl_tcp_retrans_collapse; extern int sysctl_tcp_stdurg; extern int sysctl_tcp_rfc1337; -extern int sysctl_tcp_tw_recycle; extern int sysctl_tcp_abort_on_overflow; extern int sysctl_tcp_max_orphans; extern int sysctl_tcp_max_tw_buckets; diff --git a/ipc/msg.c b/ipc/msg.c index 971bae8d9028..b325d7f869df 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -597,7 +597,7 @@ static int testmsg(struct msg_msg* msg,long type,int mode) return 0; } -int inline pipelined_send(struct msg_queue* msq, struct msg_msg* msg) +static int inline pipelined_send(struct msg_queue* msq, struct msg_msg* msg) { struct list_head* tmp; @@ -706,7 +706,7 @@ out_free: return err; } -int inline convert_mode(long* msgtyp, int msgflg) +static int inline convert_mode(long* msgtyp, int msgflg) { /* * find message of correct type. diff --git a/ipc/sem.c b/ipc/sem.c index 4ffb1c881d52..fdc604a78311 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -441,7 +441,7 @@ static unsigned long copy_semid_to_user(void *buf, struct semid64_ds *in, int ve } } -int semctl_nolock(int semid, int semnum, int cmd, int version, union semun arg) +static int semctl_nolock(int semid, int semnum, int cmd, int version, union semun arg) { int err = -EINVAL; @@ -513,7 +513,7 @@ out_unlock: return err; } -int semctl_main(int semid, int semnum, int cmd, int version, union semun arg) +static int semctl_main(int semid, int semnum, int cmd, int version, union semun arg) { struct sem_array *sma; struct sem* curr; @@ -700,7 +700,7 @@ static inline unsigned long copy_semid_from_user(struct sem_setbuf *out, void *b } } -int semctl_down(int semid, int semnum, int cmd, int version, union semun arg) +static int semctl_down(int semid, int semnum, int cmd, int version, union semun arg) { struct sem_array *sma; int err; diff --git a/kernel/panic.c b/kernel/panic.c index 84adabf00cf5..5281e7cce9f8 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -66,7 +66,7 @@ NORET_TYPE void panic(const char * fmt, ...) smp_send_stop(); #endif - notifier_call_chain(&panic_notifier_list, 0, NULL); + notifier_call_chain(&panic_notifier_list, 0, buf); if (panic_timeout > 0) { diff --git a/kernel/platform.c b/kernel/platform.c index 2d786dcb77c3..9848541526a6 100644 --- a/kernel/platform.c +++ b/kernel/platform.c @@ -6,10 +6,6 @@ #include <linux/module.h> #include <linux/errno.h> -static struct platform_t default_platform; - -struct platform_t * platform = &default_platform; -static spinlock_t platform_lock = SPIN_LOCK_UNLOCKED; void default_reboot(char * cmd) { @@ -36,6 +32,9 @@ static struct platform_t default_platform = { idle: default_idle, }; +struct platform_t * platform = &default_platform; +static spinlock_t platform_lock = SPIN_LOCK_UNLOCKED; + /** * set_platform_driver - set the platform driver. * @pf: driver to set it to diff --git a/kernel/pm.c b/kernel/pm.c index 0992b66f0d4b..fe5296045ec9 100644 --- a/kernel/pm.c +++ b/kernel/pm.c @@ -31,7 +31,7 @@ int pm_active; * Locking notes: * pm_devs_lock can be a semaphore providing pm ops are not called * from an interrupt handler (already a bad idea so no change here). Each - * change must be protected so that an unlink of an entry doesnt clash + * change must be protected so that an unlink of an entry doesn't clash * with a pm send - which is permitted to sleep in the current architecture * * Module unloads clashing with pm events now work out safely, the module diff --git a/kernel/printk.c b/kernel/printk.c index d095aac9fb57..f86862435f2e 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -31,6 +31,8 @@ #if defined(CONFIG_MULTIQUAD) || defined(CONFIG_IA64) #define LOG_BUF_LEN (65536) +#elif defined(CONFIG_ARCH_S390) +#define LOG_BUF_LEN (131072) #elif defined(CONFIG_SMP) #define LOG_BUF_LEN (32768) #else diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 03bced06b292..b1d4e4a23ccb 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -131,8 +131,8 @@ static char * number(char * buf, char * end, long long num, int base, int size, { char c,sign,tmp[66]; const char *digits; - const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; - const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + static const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; + static const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; int i; digits = (type & LARGE) ? large_digits : small_digits; diff --git a/mm/slab.c b/mm/slab.c index 5153b9469737..1b5ef5f68a3e 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -2019,7 +2019,7 @@ static int s_show(struct seq_file *m, void *p) return 0; } -/** +/* * slabinfo_op - iterator that generates /proc/slabinfo * * Output layout: diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index af85a859eb8c..3fa3dd598d23 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -9,6 +9,7 @@ * a table */ #include <linux/config.h> +#include <linux/cache.h> #include <linux/skbuff.h> #include <linux/kmod.h> #include <linux/vmalloc.h> @@ -97,7 +98,7 @@ struct ipt_table_info unsigned int underflow[NF_IP_NUMHOOKS]; /* ipt_entry tables: one per CPU */ - char entries[0] __attribute__((aligned(SMP_CACHE_BYTES))); + char entries[0] ____cacheline_aligned; }; static LIST_HEAD(ipt_target); diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 101902210bce..2d44872318ea 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1519,7 +1519,7 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, break; /* We need to check signals first, to get correct SIGURG - * handling. FIXME: Need to check this doesnt impact 1003.1g + * handling. FIXME: Need to check this doesn't impact 1003.1g * and move it down to the bottom of the loop */ if (signal_pending(current)) { diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile index 2f31a59d427c..9aa4c8fe54ab 100644 --- a/net/sunrpc/Makefile +++ b/net/sunrpc/Makefile @@ -9,7 +9,8 @@ export-objs := sunrpc_syms.o sunrpc-y := clnt.o xprt.o sched.o \ auth.o auth_null.o auth_unix.o \ svc.o svcsock.o svcauth.o \ - pmap_clnt.o xdr.o sunrpc_syms.o + pmap_clnt.o timer.o xdr.o \ + sunrpc_syms.o sunrpc-$(CONFIG_PROC_FS) += stats.o sunrpc-$(CONFIG_SYSCTL) += sysctl.o sunrpc-objs := $(sunrpc-y) diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 0a958d79c364..657deb7640ee 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -104,6 +104,8 @@ rpc_create_client(struct rpc_xprt *xprt, char *servname, if (!clnt->cl_port) clnt->cl_autobind = 1; + rpc_init_rtt(&clnt->cl_rtt, xprt->timeout.to_initval); + if (!rpcauth_create(flavor, clnt)) goto out_no_auth; @@ -669,7 +671,7 @@ call_timeout(struct rpc_task *task) rpc_exit(task, -EIO); return; } - if (clnt->cl_chatty && !(task->tk_flags & RPC_CALL_MAJORSEEN)) { + if (clnt->cl_chatty && !(task->tk_flags & RPC_CALL_MAJORSEEN) && rpc_ntimeo(&clnt->cl_rtt) > 7) { task->tk_flags |= RPC_CALL_MAJORSEEN; if (req) printk(KERN_NOTICE "%s: server %s not responding, still trying\n", diff --git a/net/sunrpc/timer.c b/net/sunrpc/timer.c new file mode 100644 index 000000000000..184017a23143 --- /dev/null +++ b/net/sunrpc/timer.c @@ -0,0 +1,74 @@ +#include <linux/version.h> +#include <linux/types.h> +#include <linux/unistd.h> + +#include <linux/sunrpc/clnt.h> +#include <linux/sunrpc/xprt.h> +#include <linux/sunrpc/timer.h> + +#define RPC_RTO_MAX (60*HZ) +#define RPC_RTO_INIT (HZ/5) +#define RPC_RTO_MIN (2) + +void +rpc_init_rtt(struct rpc_rtt *rt, long timeo) +{ + long t = (timeo - RPC_RTO_INIT) << 3; + int i; + rt->timeo = timeo; + if (t < 0) + t = 0; + for (i = 0; i < 5; i++) { + rt->srtt[i] = t; + rt->sdrtt[i] = RPC_RTO_INIT; + } + atomic_set(&rt->ntimeouts, 0); +} + +void +rpc_update_rtt(struct rpc_rtt *rt, int timer, long m) +{ + long *srtt, *sdrtt; + + if (timer-- == 0) + return; + + if (m == 0) + m = 1; + srtt = &rt->srtt[timer]; + m -= *srtt >> 3; + *srtt += m; + if (m < 0) + m = -m; + sdrtt = &rt->sdrtt[timer]; + m -= *sdrtt >> 2; + *sdrtt += m; + /* Set lower bound on the variance */ + if (*sdrtt < RPC_RTO_MIN) + *sdrtt = RPC_RTO_MIN; +} + +/* + * Estimate rto for an nfs rpc sent via. an unreliable datagram. + * Use the mean and mean deviation of rtt for the appropriate type of rpc + * for the frequent rpcs and a default for the others. + * The justification for doing "other" this way is that these rpcs + * happen so infrequently that timer est. would probably be stale. + * Also, since many of these rpcs are + * non-idempotent, a conservative timeout is desired. + * getattr, lookup, + * read, write, commit - A+4D + * other - timeo + */ + +long +rpc_calc_rto(struct rpc_rtt *rt, int timer) +{ + long res; + if (timer-- == 0) + return rt->timeo; + res = (rt->srtt[timer] >> 3) + rt->sdrtt[timer]; + if (res > RPC_RTO_MAX) + res = RPC_RTO_MAX; + return res; +} diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 1533e0076eca..512a3887da34 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -242,11 +242,11 @@ void xdr_kunmap(struct xdr_buf *xdr, size_t base) return; if (base || xdr->page_base) { pglen -= base; + base += xdr->page_base; ppage += base >> PAGE_CACHE_SHIFT; } for (;;) { flush_dcache_page(*ppage); - flush_page_to_ram(*ppage); kunmap(*ppage); if (pglen <= PAGE_CACHE_SIZE) break; diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index fbc1bf5cfa5a..fc3bb3841329 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -77,6 +77,8 @@ # define RPCDBG_FACILITY RPCDBG_XPRT #endif +#define XPRT_MAX_BACKOFF (8) + /* * Local functions */ @@ -87,6 +89,7 @@ static void xprt_disconnect(struct rpc_xprt *); static void xprt_reconn_status(struct rpc_task *task); static struct socket *xprt_create_socket(int, struct rpc_timeout *); static int xprt_bind_socket(struct rpc_xprt *, struct socket *); +static int __xprt_get_cong(struct rpc_xprt *, struct rpc_task *); #ifdef RPC_DEBUG_DATA /* @@ -138,31 +141,60 @@ xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task) { int retval; spin_lock_bh(&xprt->sock_lock); - if (!xprt->snd_task) - xprt->snd_task = task; - else if (xprt->snd_task != task) { + if (!xprt->snd_task) { + if (xprt->nocong || __xprt_get_cong(xprt, task)) + xprt->snd_task = task; + } + if (xprt->snd_task != task) { dprintk("RPC: %4d TCP write queue full (task %d)\n", task->tk_pid, xprt->snd_task->tk_pid); task->tk_timeout = 0; task->tk_status = -EAGAIN; - rpc_sleep_on(&xprt->sending, task, NULL, NULL); + if (task->tk_rqstp->rq_nresend) + rpc_sleep_on(&xprt->resend, task, NULL, NULL); + else + rpc_sleep_on(&xprt->sending, task, NULL, NULL); } retval = xprt->snd_task == task; spin_unlock_bh(&xprt->sock_lock); return retval; } +static void +__xprt_lock_write_next(struct rpc_xprt *xprt) +{ + struct rpc_task *task; + + if (xprt->snd_task) + return; + if (!xprt->nocong && RPCXPRT_CONGESTED(xprt)) + return; + task = rpc_wake_up_next(&xprt->resend); + if (!task) { + task = rpc_wake_up_next(&xprt->sending); + if (!task) + return; + } + if (xprt->nocong || __xprt_get_cong(xprt, task)) + xprt->snd_task = task; +} + /* * Releases the socket for use by other requests. */ static void +__xprt_release_write(struct rpc_xprt *xprt, struct rpc_task *task) +{ + if (xprt->snd_task == task) + xprt->snd_task = NULL; + __xprt_lock_write_next(xprt); +} + +static inline void xprt_release_write(struct rpc_xprt *xprt, struct rpc_task *task) { spin_lock_bh(&xprt->sock_lock); - if (xprt->snd_task == task) { - xprt->snd_task = NULL; - rpc_wake_up_next(&xprt->sending); - } + __xprt_release_write(xprt, task); spin_unlock_bh(&xprt->sock_lock); } @@ -234,6 +266,40 @@ xprt_sendmsg(struct rpc_xprt *xprt, struct rpc_rqst *req) } /* + * Van Jacobson congestion avoidance. Check if the congestion window + * overflowed. Put the task to sleep if this is the case. + */ +static int +__xprt_get_cong(struct rpc_xprt *xprt, struct rpc_task *task) +{ + struct rpc_rqst *req = task->tk_rqstp; + + if (req->rq_cong) + return 1; + dprintk("RPC: %4d xprt_cwnd_limited cong = %ld cwnd = %ld\n", + task->tk_pid, xprt->cong, xprt->cwnd); + if (RPCXPRT_CONGESTED(xprt)) + return 0; + req->rq_cong = 1; + xprt->cong += RPC_CWNDSCALE; + return 1; +} + +/* + * Adjust the congestion window, and wake up the next task + * that has been sleeping due to congestion + */ +static void +__xprt_put_cong(struct rpc_xprt *xprt, struct rpc_rqst *req) +{ + if (!req->rq_cong) + return; + req->rq_cong = 0; + xprt->cong -= RPC_CWNDSCALE; + __xprt_lock_write_next(xprt); +} + +/* * Adjust RPC congestion window * We use a time-smoothed congestion estimator to avoid heavy oscillation. */ @@ -242,40 +308,22 @@ xprt_adjust_cwnd(struct rpc_xprt *xprt, int result) { unsigned long cwnd; - if (xprt->nocong) - return; - /* - * Note: we're in a BH context - */ - spin_lock(&xprt->xprt_lock); cwnd = xprt->cwnd; - if (result >= 0) { - if (xprt->cong < cwnd || time_before(jiffies, xprt->congtime)) - goto out; + if (result >= 0 && xprt->cong <= cwnd) { /* The (cwnd >> 1) term makes sure * the result gets rounded properly. */ cwnd += (RPC_CWNDSCALE * RPC_CWNDSCALE + (cwnd >> 1)) / cwnd; if (cwnd > RPC_MAXCWND) cwnd = RPC_MAXCWND; - else - pprintk("RPC: %lu %ld cwnd\n", jiffies, cwnd); - xprt->congtime = jiffies + ((cwnd * HZ) << 2) / RPC_CWNDSCALE; - dprintk("RPC: cong %08lx, cwnd was %08lx, now %08lx, " - "time %ld ms\n", xprt->cong, xprt->cwnd, cwnd, - (xprt->congtime-jiffies)*1000/HZ); + __xprt_lock_write_next(xprt); } else if (result == -ETIMEDOUT) { - if ((cwnd >>= 1) < RPC_CWNDSCALE) + cwnd >>= 1; + if (cwnd < RPC_CWNDSCALE) cwnd = RPC_CWNDSCALE; - xprt->congtime = jiffies + ((cwnd * HZ) << 3) / RPC_CWNDSCALE; - dprintk("RPC: cong %ld, cwnd was %ld, now %ld, " - "time %ld ms\n", xprt->cong, xprt->cwnd, cwnd, - (xprt->congtime-jiffies)*1000/HZ); - pprintk("RPC: %lu %ld cwnd\n", jiffies, cwnd); } - + dprintk("RPC: cong %ld, cwnd was %ld, now %ld\n", + xprt->cong, xprt->cwnd, cwnd); xprt->cwnd = cwnd; - out: - spin_unlock(&xprt->xprt_lock); } /* @@ -335,7 +383,7 @@ xprt_close(struct rpc_xprt *xprt) sock_release(sock); /* - * TCP doesnt require the rpciod now - other things may + * TCP doesn't require the rpciod now - other things may * but rpciod handles that not us. */ if(xprt->stream) @@ -427,7 +475,7 @@ xprt_reconnect(struct rpc_task *task) /* if the socket is already closing, delay 5 secs */ if ((1<<inet->state) & ~(TCP_SYN_SENT|TCP_SYN_RECV)) task->tk_timeout = 5*HZ; - rpc_sleep_on(&xprt->sending, task, xprt_reconn_status, NULL); + rpc_sleep_on(&xprt->pending, task, xprt_reconn_status, NULL); release_sock(inet); return; } @@ -480,13 +528,23 @@ xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid) * Complete reply received. * The TCP code relies on us to remove the request from xprt->pending. */ -static inline void +static void xprt_complete_rqst(struct rpc_xprt *xprt, struct rpc_rqst *req, int copied) { struct rpc_task *task = req->rq_task; + struct rpc_clnt *clnt = task->tk_client; /* Adjust congestion window */ - xprt_adjust_cwnd(xprt, copied); + if (!xprt->nocong) { + xprt_adjust_cwnd(xprt, copied); + __xprt_put_cong(xprt, req); + if (!req->rq_nresend) { + int timer = rpcproc_timer(clnt, task->tk_msg.rpc_proc); + if (timer) + rpc_update_rtt(&clnt->cl_rtt, timer, (long)jiffies - req->rq_xtime); + } + rpc_clear_timeo(&clnt->cl_rtt); + } #ifdef RPC_PROFILE /* Profile only reads for now */ @@ -872,7 +930,7 @@ tcp_state_change(struct sock *sk) xprt->tcp_flags = XPRT_COPY_RECM | XPRT_COPY_XID; spin_lock(&xprt->sock_lock); - if (xprt->snd_task && xprt->snd_task->tk_rpcwait == &xprt->sending) + if (xprt->snd_task && xprt->snd_task->tk_rpcwait == &xprt->pending) rpc_wake_up_task(xprt->snd_task); spin_unlock(&xprt->sock_lock); break; @@ -909,7 +967,7 @@ xprt_write_space(struct sock *sk) if (!xprt_test_and_set_wspace(xprt)) { spin_lock(&xprt->sock_lock); - if (xprt->snd_task && xprt->snd_task->tk_rpcwait == &xprt->sending) + if (xprt->snd_task && xprt->snd_task->tk_rpcwait == &xprt->pending) rpc_wake_up_task(xprt->snd_task); spin_unlock(&xprt->sock_lock); } @@ -923,6 +981,21 @@ xprt_write_space(struct sock *sk) } /* + * Exponential backoff for UDP retries + */ +static inline int +xprt_expbackoff(struct rpc_task *task, struct rpc_rqst *req) +{ + int backoff; + + req->rq_ntimeo++; + backoff = min(rpc_ntimeo(&task->tk_client->cl_rtt), XPRT_MAX_BACKOFF); + if (req->rq_ntimeo < (1 << backoff)) + return 1; + return 0; +} + +/* * RPC receive timeout handler. */ static void @@ -934,7 +1007,17 @@ xprt_timer(struct rpc_task *task) spin_lock(&xprt->sock_lock); if (req->rq_received) goto out; - xprt_adjust_cwnd(xprt, -ETIMEDOUT); + + if (!xprt->nocong) { + if (xprt_expbackoff(task, req)) { + rpc_add_timer(task, xprt_timer); + goto out_unlock; + } + rpc_inc_timeo(&task->tk_client->cl_rtt); + xprt_adjust_cwnd(req->rq_xprt, -ETIMEDOUT); + __xprt_put_cong(xprt, req); + } + req->rq_nresend++; dprintk("RPC: %4d xprt_timer (%s request)\n", task->tk_pid, req ? "pending" : "backlogged"); @@ -943,6 +1026,7 @@ xprt_timer(struct rpc_task *task) out: task->tk_timeout = 0; rpc_wake_up_task(task); +out_unlock: spin_unlock(&xprt->sock_lock); } @@ -982,15 +1066,13 @@ xprt_transmit(struct rpc_task *task) if (!xprt_lock_write(xprt, task)) return; -#ifdef RPC_PROFILE - req->rq_xtime = jiffies; -#endif do_xprt_transmit(task); } static void do_xprt_transmit(struct rpc_task *task) { + struct rpc_clnt *clnt = task->tk_client; struct rpc_rqst *req = task->tk_rqstp; struct rpc_xprt *xprt = req->rq_xprt; int status, retry = 0; @@ -1002,6 +1084,7 @@ do_xprt_transmit(struct rpc_task *task) */ while (1) { xprt_clear_wspace(xprt); + req->rq_xtime = jiffies; status = xprt_sendmsg(xprt, req); if (status < 0) @@ -1043,7 +1126,7 @@ do_xprt_transmit(struct rpc_task *task) spin_lock_bh(&xprt->sock_lock); if (!xprt_wspace(xprt)) { task->tk_timeout = req->rq_timeout.to_current; - rpc_sleep_on(&xprt->sending, task, NULL, NULL); + rpc_sleep_on(&xprt->pending, task, NULL, NULL); } spin_unlock_bh(&xprt->sock_lock); return; @@ -1059,19 +1142,29 @@ do_xprt_transmit(struct rpc_task *task) if (xprt->stream) xprt_disconnect(xprt); req->rq_bytes_sent = 0; - goto out_release; } - + out_release: + spin_lock_bh(&xprt->sock_lock); + __xprt_release_write(xprt, task); + __xprt_put_cong(xprt, req); + spin_unlock_bh(&xprt->sock_lock); + return; out_receive: dprintk("RPC: %4d xmit complete\n", task->tk_pid); /* Set the task's receive timeout value */ - task->tk_timeout = req->rq_timeout.to_current; + if (!xprt->nocong) { + task->tk_timeout = rpc_calc_rto(&clnt->cl_rtt, + rpcproc_timer(clnt, task->tk_msg.rpc_proc)); + req->rq_ntimeo = 0; + if (task->tk_timeout > req->rq_timeout.to_maxval) + task->tk_timeout = req->rq_timeout.to_maxval; + } else + task->tk_timeout = req->rq_timeout.to_current; spin_lock_bh(&xprt->sock_lock); if (!req->rq_received) rpc_sleep_on(&xprt->pending, task, NULL, xprt_timer); + __xprt_release_write(xprt, task); spin_unlock_bh(&xprt->sock_lock); - out_release: - xprt_release_write(xprt, task); } /* @@ -1086,9 +1179,7 @@ xprt_reserve(struct rpc_task *task) if (task->tk_rqstp) return 0; - dprintk("RPC: %4d xprt_reserve cong = %ld cwnd = %ld\n", - task->tk_pid, xprt->cong, xprt->cwnd); - spin_lock_bh(&xprt->xprt_lock); + spin_lock(&xprt->xprt_lock); xprt_reserve_status(task); if (task->tk_rqstp) { task->tk_timeout = 0; @@ -1099,7 +1190,7 @@ xprt_reserve(struct rpc_task *task) task->tk_status = -EAGAIN; rpc_sleep_on(&xprt->backlog, task, NULL, NULL); } - spin_unlock_bh(&xprt->xprt_lock); + spin_unlock(&xprt->xprt_lock); dprintk("RPC: %4d xprt_reserve returns %d\n", task->tk_pid, task->tk_status); return task->tk_status; @@ -1121,18 +1212,13 @@ xprt_reserve_status(struct rpc_task *task) } else if (task->tk_rqstp) { /* We've already been given a request slot: NOP */ } else { - if (RPCXPRT_CONGESTED(xprt) || !(req = xprt->free)) + if (!(req = xprt->free)) goto out_nofree; - /* OK: There's room for us. Grab a free slot and bump - * congestion value */ + /* OK: There's room for us. Grab a free slot */ xprt->free = req->rq_next; req->rq_next = NULL; - xprt->cong += RPC_CWNDSCALE; task->tk_rqstp = req; xprt_request_init(task, xprt); - - if (xprt->free) - xprt_clear_backlog(xprt); } return; @@ -1176,14 +1262,11 @@ xprt_release(struct rpc_task *task) struct rpc_xprt *xprt = task->tk_xprt; struct rpc_rqst *req; - if (xprt->snd_task == task) { - if (xprt->stream) - xprt_disconnect(xprt); - xprt_release_write(xprt, task); - } if (!(req = task->tk_rqstp)) return; spin_lock_bh(&xprt->sock_lock); + __xprt_release_write(xprt, task); + __xprt_put_cong(xprt, req); if (!list_empty(&req->rq_list)) list_del(&req->rq_list); spin_unlock_bh(&xprt->sock_lock); @@ -1192,15 +1275,12 @@ xprt_release(struct rpc_task *task) dprintk("RPC: %4d release request %p\n", task->tk_pid, req); - spin_lock_bh(&xprt->xprt_lock); + spin_lock(&xprt->xprt_lock); req->rq_next = xprt->free; xprt->free = req; - /* Decrease congestion value. */ - xprt->cong -= RPC_CWNDSCALE; - xprt_clear_backlog(xprt); - spin_unlock_bh(&xprt->xprt_lock); + spin_unlock(&xprt->xprt_lock); } /* @@ -1256,7 +1336,6 @@ xprt_setup(struct socket *sock, int proto, xprt->nocong = 1; } else xprt->cwnd = RPC_INITCWND; - xprt->congtime = jiffies; spin_lock_init(&xprt->sock_lock); spin_lock_init(&xprt->xprt_lock); init_waitqueue_head(&xprt->cong_wait); @@ -1273,6 +1352,7 @@ xprt_setup(struct socket *sock, int proto, INIT_RPC_WAITQ(&xprt->pending, "xprt_pending"); INIT_RPC_WAITQ(&xprt->sending, "xprt_sending"); + INIT_RPC_WAITQ(&xprt->resend, "xprt_resend"); INIT_RPC_WAITQ(&xprt->backlog, "xprt_backlog"); /* initialize free list */ @@ -1404,6 +1484,7 @@ xprt_shutdown(struct rpc_xprt *xprt) { xprt->shutdown = 1; rpc_wake_up(&xprt->sending); + rpc_wake_up(&xprt->resend); rpc_wake_up(&xprt->pending); rpc_wake_up(&xprt->backlog); if (waitqueue_active(&xprt->cong_wait)) @@ -1415,8 +1496,6 @@ xprt_shutdown(struct rpc_xprt *xprt) */ int xprt_clear_backlog(struct rpc_xprt *xprt) { - if (RPCXPRT_CONGESTED(xprt)) - return 0; rpc_wake_up_next(&xprt->backlog); if (waitqueue_active(&xprt->cong_wait)) wake_up(&xprt->cong_wait); diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index bd6fb1b8f9f2..db9b83bb6384 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -185,7 +185,7 @@ static int unix_mkname(struct sockaddr_un * sunaddr, int len, unsigned *hashp) /* * This may look like an off by one error but it is * a bit more subtle. 108 is the longest valid AF_UNIX - * path for a binding. sun_path[108] doesnt as such + * path for a binding. sun_path[108] doesn't as such * exist. However in kernel space we are guaranteed that * it is a valid memory location in our kernel * address buffer. diff --git a/sound/oss/ad1848.c b/sound/oss/ad1848.c index c778677958e8..117c9e802edc 100644 --- a/sound/oss/ad1848.c +++ b/sound/oss/ad1848.c @@ -1996,7 +1996,8 @@ int ad1848_init (char *name, int io_base, int irq, int dma_playback, sprintf(dev_name, "Generic audio codec (%s)", devc->chip_name); - request_region(devc->base, 4, devc->name); + if (!request_region(devc->base, 4, devc->name)) + return -1; conf_printf2(dev_name, devc->base, devc->irq, dma_playback, dma_capture); @@ -2012,8 +2013,10 @@ int ad1848_init (char *name, int io_base, int irq, int dma_playback, } portc = (ad1848_port_info *) kmalloc(sizeof(ad1848_port_info), GFP_KERNEL); - if(portc==NULL) + if(portc==NULL) { + release_region(devc->base, 4); return -1; + } if ((my_dev = sound_install_audiodrv(AUDIO_DRIVER_VERSION, dev_name, @@ -2025,8 +2028,8 @@ int ad1848_init (char *name, int io_base, int irq, int dma_playback, dma_playback, dma_capture)) < 0) { + release_region(devc->base, 4); kfree(portc); - portc=NULL; return -1; } diff --git a/sound/oss/sb_audio.c b/sound/oss/sb_audio.c index 6b0a3f7275ee..dda11e473696 100644 --- a/sound/oss/sb_audio.c +++ b/sound/oss/sb_audio.c @@ -851,7 +851,7 @@ sb16_copy_from_user(int dev, { if (copy_from_user(localbuf + localoffs, userbuf + useroffs, len)) - return -EFAULT; + return; *used = len; *returned = len; } @@ -874,7 +874,7 @@ sb16_copy_from_user(int dev, if (copy_from_user(lbuf16, userbuf + useroffs + (p << 1), locallen << 1)) - return -EFAULT; + return; for (i = 0; i < locallen; i++) { buf8[p+i] = ~((lbuf16[i] >> 8) & 0xff) ^ 0x80; @@ -904,7 +904,7 @@ sb16_copy_from_user(int dev, if (copy_from_user(lbuf8, userbuf+useroffs + p, locallen)) - return -EFAULT; + return; for (i = 0; i < locallen; i++) { buf16[p+i] = (~lbuf8[i] ^ 0x80) << 8; diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c index f9c46ee17627..c2435b06b1db 100644 --- a/sound/pci/cs46xx/cs46xx.c +++ b/sound/pci/cs46xx/cs46xx.c @@ -28,6 +28,7 @@ #include <sound/driver.h> #include <linux/pci.h> #include <linux/time.h> +#include <linux/init.h> #include <sound/core.h> #include <sound/cs46xx.h> #define SNDRV_GET_ID |
