]> err.no Git - linux-2.6/commitdiff
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Fri, 2 Mar 2007 01:28:31 +0000 (17:28 -0800)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Fri, 2 Mar 2007 01:28:31 +0000 (17:28 -0800)
* master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6:
  [SPARC64]: Fix parport_pc build.
  [SPARC64]: Update defconfig.

101 files changed:
Documentation/SubmitChecklist
Documentation/cpu-load.txt [new file with mode: 0644]
Documentation/networking/ip-sysctl.txt
MAINTAINERS
arch/arm26/kernel/entry.S
arch/cris/arch-v32/drivers/pci/dma.c
arch/frv/mm/init.c
arch/i386/kernel/pci-dma.c
arch/powerpc/platforms/ps3/Kconfig
arch/um/Kconfig.char
arch/um/os-Linux/elf_aux.c
arch/um/os-Linux/sigio.c
arch/um/sys-i386/ldt.c
drivers/acpi/Kconfig
drivers/block/umem.c
drivers/char/tty_io.c
drivers/isdn/capi/Kconfig
drivers/isdn/capi/capidrv.c
drivers/isdn/capi/capiutil.c
drivers/isdn/capi/kcapi.c
drivers/isdn/gigaset/Makefile
drivers/isdn/gigaset/asyncdata.c
drivers/md/md.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/md/raid6mmx.c
drivers/md/raid6sse1.c
drivers/md/raid6sse2.c
drivers/md/raid6x86.h
drivers/media/dvb/dvb-usb/cxusb.c
drivers/media/dvb/dvb-usb/digitv.c
drivers/media/video/cafe_ccic.c
drivers/media/video/cx25840/cx25840-core.c
drivers/media/video/cx25840/cx25840-firmware.c
drivers/media/video/cx88/cx88-video.c
drivers/media/video/pvrusb2/pvrusb2-hdw.c
drivers/media/video/pvrusb2/pvrusb2-hdw.h
drivers/media/video/pvrusb2/pvrusb2-v4l2.c
drivers/media/video/saa7115.c
drivers/media/video/saa7127.c
drivers/media/video/tvp5150.c
drivers/media/video/upd64031a.c
drivers/media/video/upd64083.c
drivers/media/video/usbvision/usbvision-video.c
drivers/media/video/v4l2-common.c
drivers/media/video/videodev.c
drivers/rtc/class.c
drivers/rtc/interface.c
drivers/video/Kconfig
drivers/video/sm501fb.c
fs/ecryptfs/file.c
fs/ecryptfs/inode.c
fs/ecryptfs/main.c
fs/ecryptfs/mmap.c
fs/ext3/xattr.c
fs/ext4/xattr.c
include/asm-frv/pgtable.h
include/asm-um/pgtable.h
include/linux/hrtimer.h
include/linux/hugetlb.h
include/linux/irq.h
include/linux/isdn/capiutil.h
include/linux/mm.h
include/linux/page-flags.h
include/linux/shm.h
include/linux/socket.h
include/linux/stat.h
include/linux/sysfs.h
include/linux/videodev2.h
include/linux/writeback.h
include/media/v4l2-common.h
include/media/v4l2-dev.h
include/net/sock.h
ipc/shm.c
kernel/lockdep.c
kernel/relay.c
kernel/sched.c
kernel/sysctl.c
kernel/timer.c
lib/bitmap.c
mm/mmap.c
mm/page-writeback.c
mm/page_alloc.c
mm/rmap.c
mm/shmem.c
mm/slab.c
mm/tiny-shmem.c
mm/truncate.c
mm/vmscan.c
net/bridge/br_ioctl.c
net/core/skbuff.c
net/dccp/output.c
net/ipv4/tcp_minisocks.c
net/ipv6/addrconf.c
net/ipv6/anycast.c
net/ipx/ChangeLog [deleted file]
net/ipx/Kconfig
net/netfilter/nfnetlink.c
net/netlabel/netlabel_unlabeled.c
net/xfrm/xfrm_user.c
scripts/kernel-doc

index bfbb2718a2799b972fa6663ffbc0b34a7b88b999..bd23dc0bc0c7c9ced4323b761396377d700fad83 100644 (file)
@@ -76,3 +76,7 @@ kernel patches.
 22: Newly-added code has been compiled with `gcc -W'.  This will generate
     lots of noise, but is good for finding bugs like "warning: comparison
     between signed and unsigned".
+
+23: Tested after it has been merged into the -mm patchset to make sure
+    that it still works with all of the other queued patches and various
+    changes in the VM, VFS, and other subsystems.
diff --git a/Documentation/cpu-load.txt b/Documentation/cpu-load.txt
new file mode 100644 (file)
index 0000000..287224e
--- /dev/null
@@ -0,0 +1,113 @@
+CPU load
+--------
+
+Linux exports various bits of information via `/proc/stat' and
+`/proc/uptime' that userland tools, such as top(1), use to calculate
+the average time system spent in a particular state, for example:
+
+    $ iostat
+    Linux 2.6.18.3-exp (linmac)     02/20/2007
+
+    avg-cpu:  %user   %nice %system %iowait  %steal   %idle
+              10.01    0.00    2.92    5.44    0.00   81.63
+
+    ...
+
+Here the system thinks that over the default sampling period the
+system spent 10.01% of the time doing work in user space, 2.92% in the
+kernel, and was overall 81.63% of the time idle.
+
+In most cases the `/proc/stat' information reflects the reality quite
+closely, however due to the nature of how/when the kernel collects
+this data sometimes it can not be trusted at all.
+
+So how is this information collected?  Whenever timer interrupt is
+signalled the kernel looks what kind of task was running at this
+moment and increments the counter that corresponds to this tasks
+kind/state.  The problem with this is that the system could have
+switched between various states multiple times between two timer
+interrupts yet the counter is incremented only for the last state.
+
+
+Example
+-------
+
+If we imagine the system with one task that periodically burns cycles
+in the following manner:
+
+ time line between two timer interrupts
+|--------------------------------------|
+ ^                                    ^
+ |_ something begins working          |
+                                      |_ something goes to sleep
+                                     (only to be awaken quite soon)
+
+In the above situation the system will be 0% loaded according to the
+`/proc/stat' (since the timer interrupt will always happen when the
+system is executing the idle handler), but in reality the load is
+closer to 99%.
+
+One can imagine many more situations where this behavior of the kernel
+will lead to quite erratic information inside `/proc/stat'.
+
+
+/* gcc -o hog smallhog.c */
+#include <time.h>
+#include <limits.h>
+#include <signal.h>
+#include <sys/time.h>
+#define HIST 10
+
+static volatile sig_atomic_t stop;
+
+static void sighandler (int signr)
+{
+     (void) signr;
+     stop = 1;
+}
+static unsigned long hog (unsigned long niters)
+{
+     stop = 0;
+     while (!stop && --niters);
+     return niters;
+}
+int main (void)
+{
+     int i;
+     struct itimerval it = { .it_interval = { .tv_sec = 0, .tv_usec = 1 },
+                             .it_value = { .tv_sec = 0, .tv_usec = 1 } };
+     sigset_t set;
+     unsigned long v[HIST];
+     double tmp = 0.0;
+     unsigned long n;
+     signal (SIGALRM, &sighandler);
+     setitimer (ITIMER_REAL, &it, NULL);
+
+     hog (ULONG_MAX);
+     for (i = 0; i < HIST; ++i) v[i] = ULONG_MAX - hog (ULONG_MAX);
+     for (i = 0; i < HIST; ++i) tmp += v[i];
+     tmp /= HIST;
+     n = tmp - (tmp / 3.0);
+
+     sigemptyset (&set);
+     sigaddset (&set, SIGALRM);
+
+     for (;;) {
+         hog (n);
+         sigwait (&set, &i);
+     }
+     return 0;
+}
+
+
+References
+----------
+
+http://lkml.org/lkml/2007/2/12/6
+Documentation/filesystems/proc.txt (1.8)
+
+
+Thanks
+------
+
+Con Kolivas, Pavel Machek
index a0f6842368c37b77b571c5817029adaf45db1769..d3aae1f9b4c1970f5d119be92e54549d19640be3 100644 (file)
@@ -147,6 +147,11 @@ tcp_available_congestion_control - STRING
        More congestion control algorithms may be available as modules,
        but not loaded.
 
+tcp_base_mss - INTEGER
+       The initial value of search_low to be used by Packetization Layer
+       Path MTU Discovery (MTU probing).  If MTU probing is enabled,
+       this is the inital MSS used by the connection.
+
 tcp_congestion_control - STRING
        Set the congestion control algorithm to be used for new
        connections. The algorithm "reno" is always available, but
@@ -243,6 +248,27 @@ tcp_mem - vector of 3 INTEGERs: min, pressure, max
        Defaults are calculated at boot time from amount of available
        memory.
 
+tcp_moderate_rcvbuf - BOOLEAN
+       If set, TCP performs receive buffer autotuning, attempting to
+       automatically size the buffer (no greater than tcp_rmem[2]) to
+       match the size required by the path for full throughput.  Enabled by
+       default.
+
+tcp_mtu_probing - INTEGER
+       Controls TCP Packetization-Layer Path MTU Discovery.  Takes three
+       values:
+         0 - Disabled
+         1 - Disabled by default, enabled when an ICMP black hole detected
+         2 - Always enabled, use initial MSS of tcp_base_mss.
+
+tcp_no_metrics_save - BOOLEAN
+       By default, TCP saves various connection metrics in the route cache
+       when the connection closes, so that connections established in the
+       near future can use these to set initial conditions.  Usually, this
+       increases overall performance, but may sometimes cause performance
+       degredation.  If set, TCP will not cache metrics on closing
+       connections.
+
 tcp_orphan_retries - INTEGER
        How may times to retry before killing TCP connection, closed
        by our side. Default value 7 corresponds to ~50sec-16min
index 35e0a648422dfe0bff1a681edeccd659dbc7b34b..480ccb9d6cc97dec87ed1e669395d6da72c47657 100644 (file)
@@ -1345,7 +1345,7 @@ S:        Supported
 
 FRAMEBUFFER LAYER
 P:     Antonino Daplas
-M:     adaplas@pol.net
+M:     adaplas@gmail.com
 L:     linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
 W:     http://linux-fbdev.sourceforge.net/
 S:     Maintained
@@ -1756,7 +1756,7 @@ S:        Maintained
 
 INTEL 810/815 FRAMEBUFFER DRIVER
 P:     Antonino Daplas
-M:     adaplas@pol.net
+M:     adaplas@gmail.com
 L:     linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
 S:     Maintained
 
@@ -2471,7 +2471,7 @@ S:        Maintained
 
 NVIDIA (rivafb and nvidiafb) FRAMEBUFFER DRIVER
 P:     Antonino Daplas
-M:     adaplas@pol.net
+M:     adaplas@gmail.com
 L:     linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
 S:     Maintained
 
@@ -2855,7 +2855,7 @@ S:        Orphan
 
 S3 SAVAGE FRAMEBUFFER DRIVER
 P:     Antonino Daplas
-M:     adaplas@pol.net
+M:     adaplas@gmail.com
 L:     linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
 S:     Maintained
 
index 6d910ea43d34dbc78b67be83e78822f9c3b34204..91496cc687b1d6831acbbd7bb82a861da12783da 100644 (file)
@@ -245,11 +245,6 @@ ENTRY(vector_swi)
        zero_fp
        get_scno
 
-#ifdef CONFIG_ALIGNMENT_TRAP
-       ldr     ip, __cr_alignment
-       ldr     ip, [ip]
-       mcr     p15, 0, ip, c1, c0              @ update control register
-#endif
        enable_irqs ip
 
        str     r4, [sp, #-S_OFF]!              @ push fifth arg
@@ -299,11 +294,6 @@ __sys_trace_return:
        b       ret_slow_syscall
 
        .align  5
-#ifdef CONFIG_ALIGNMENT_TRAP
-       .type   __cr_alignment, #object
-__cr_alignment:
-       .word   cr_alignment
-#endif
 
        .type   sys_call_table, #object
 ENTRY(sys_call_table)
index 426b09878a05a5256c2fbc6ab3067a35c4726ccf..70d3bf0c92e8ebdda3c5d56bcb3663cfe6dc7ffc 100644 (file)
@@ -111,7 +111,7 @@ int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
        return DMA_MEMORY_IO;
 
  free1_out:
-       kfree(dev->dma_mem->bitmap);
+       kfree(dev->dma_mem);
  out:
        return 0;
 }
index 3f3a0ed3539bc514b7aa45f9f2b52fbfa42319b7..4103c2c487f3a114654f242f16b18d0e99281447 100644 (file)
@@ -126,8 +126,7 @@ void __init paging_init(void)
 
        /* distribute the allocatable pages across the various zones and pass them to the allocator
         */
-       zones_size[ZONE_DMA]     = max_low_pfn - min_low_pfn;
-       zones_size[ZONE_NORMAL]  = 0;
+       zones_size[ZONE_NORMAL]  = max_low_pfn - min_low_pfn;
 #ifdef CONFIG_HIGHMEM
        zones_size[ZONE_HIGHMEM] = num_physpages - num_mappedpages;
 #endif
index 41af692c1584908b6864356b757294b64b787de2..3ebcea033623e357904d52195d4d52d526267636 100644 (file)
@@ -110,7 +110,7 @@ int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
        return DMA_MEMORY_IO;
 
  free1_out:
-       kfree(dev->dma_mem->bitmap);
+       kfree(dev->dma_mem);
  out:
        if (mem_base)
                iounmap(mem_base);
index d270a1e374d5981662e788f10dfd9b7f07cd2aac..1a481a60a883db69f33e96a1a35c0b0de09bf19f 100644 (file)
@@ -1,9 +1,24 @@
 menu "PS3 Platform Options"
        depends on PPC_PS3
 
+config PS3_ADVANCED
+       depends on PPC_PS3
+       bool "PS3 Advanced configuration options"
+       help
+         This gives you access to some advanced options for the PS3. The
+         defaults should be fine for most users, but these options may make
+         it possible to better control the kernel configuration if you know
+         what you are doing.
+
+         Note that the answer to this question won't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about these options.
+
+         Most users should say N to this question.
+
 config PS3_HTAB_SIZE
        depends on PPC_PS3
-       int "PS3 Platform pagetable size"
+       int "PS3 Platform pagetable size" if PS3_ADVANCED
        range 18 20
        default 20
        help
@@ -42,7 +57,7 @@ config PS3_USE_LPAR_ADDR
 
 config PS3_VUART
        depends on PPC_PS3
-       bool "PS3 Virtual UART support"
+       bool "PS3 Virtual UART support" if PS3_ADVANCED
        default y
        help
          Include support for the PS3 Virtual UART.
@@ -52,9 +67,8 @@ config PS3_VUART
          general, all users will say Y.
 
 config PS3_PS3AV
-       tristate "PS3 AV settings driver"
-       depends on PPC_PS3
-       select PS3_VUART
+       tristate "PS3 AV settings driver" if PS3_ADVANCED
+       depends on PS3_VUART
        default y
        help
          Include support for the PS3 AV Settings driver.
@@ -63,8 +77,8 @@ config PS3_PS3AV
          general, all users will say Y or M.
 
 config PS3_SYS_MANAGER
-       bool "PS3 System Manager driver"
-       select PS3_VUART
+       bool "PS3 System Manager driver" if PS3_ADVANCED
+       depends on PS3_VUART
        default y
        help
          Include support for the PS3 System Manager.
index e03e40c7aac35472e5139152a2158b0285c76bd8..a5b079d5e8658724ae0f762cae44329f38600ff2 100644 (file)
@@ -146,6 +146,25 @@ config LEGACY_PTYS
          security.  This option enables these legacy devices; on most
          systems, it is safe to say N.
 
+config RAW_DRIVER
+        tristate "RAW driver (/dev/raw/rawN) (OBSOLETE)"
+        help
+          The raw driver permits block devices to be bound to /dev/raw/rawN.
+          Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O.
+          See the raw(8) manpage for more details.
+
+          The raw driver is deprecated and will be removed soon.
+          Applications should simply open the device (eg /dev/hda1)
+          with the O_DIRECT flag.
+
+config MAX_RAW_DEVS
+        int "Maximum number of RAW devices to support (1-8192)"
+        depends on RAW_DRIVER
+        default "256"
+        help
+          The maximum number of RAW devices that are supported.
+          Default is 256. Increase this number in case you need lots of
+          raw devices.
 
 config LEGACY_PTY_COUNT
        int "Maximum number of legacy PTY in use"
index 3a8d7e3aae0a9e2cdc70d1bc547a8b636b614d29..608784d4ec57e73f0d74a1e0ea3223c89db58cea 100644 (file)
@@ -39,6 +39,9 @@ __init void scan_elf_aux( char **envp)
                switch ( auxv->a_type ) {
                        case AT_SYSINFO:
                                __kernel_vsyscall = auxv->a_un.a_val;
+                               /* See if the page is under TASK_SIZE */
+                               if (__kernel_vsyscall < (unsigned long) envp)
+                                       __kernel_vsyscall = 0;
                                break;
                        case AT_SYSINFO_EHDR:
                                vsyscall_ehdr = auxv->a_un.a_val;
index b2e1fd8e35712504c1b8190acd2175f923ce7e5e..3fc43b33db667d370ceabf7e63794b43ab0df441 100644 (file)
@@ -334,8 +334,11 @@ void maybe_sigio_broken(int fd, int read)
 
        sigio_lock();
        err = need_poll(&all_sigio_fds, all_sigio_fds.used + 1);
-       if(err)
+       if(err){
+               printk("maybe_sigio_broken - failed to add pollfd for "
+                      "descriptor %d\n", fd);
                goto out;
+       }
 
        all_sigio_fds.poll[all_sigio_fds.used++] =
                ((struct pollfd) { .fd          = fd,
index 5db7737df0ff1bc594856588b592c860a023c006..4a8b4202ef9e9f239102db00d00ba4a01391dd7b 100644 (file)
@@ -7,6 +7,7 @@
 #include "linux/slab.h"
 #include "linux/types.h"
 #include "linux/errno.h"
+#include "linux/spinlock.h"
 #include "asm/uaccess.h"
 #include "asm/smp.h"
 #include "asm/ldt.h"
@@ -386,23 +387,33 @@ static long do_modify_ldt_skas(int func, void __user *ptr,
        return ret;
 }
 
-short dummy_list[9] = {0, -1};
-short * host_ldt_entries = NULL;
+static DEFINE_SPINLOCK(host_ldt_lock);
+static short dummy_list[9] = {0, -1};
+static short * host_ldt_entries = NULL;
 
-void ldt_get_host_info(void)
+static void ldt_get_host_info(void)
 {
        long ret;
-       struct ldt_entry * ldt;
+       struct ldt_entry * ldt, *tmp;
        int i, size, k, order;
 
+       spin_lock(&host_ldt_lock);
+
+       if(host_ldt_entries != NULL){
+               spin_unlock(&host_ldt_lock);
+               return;
+       }
        host_ldt_entries = dummy_list+1;
 
+       spin_unlock(&host_ldt_lock);
+
        for(i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++);
 
        ldt = (struct ldt_entry *)
              __get_free_pages(GFP_KERNEL|__GFP_ZERO, order);
        if(ldt == NULL) {
-               printk("ldt_get_host_info: couldn't allocate buffer for host ldt\n");
+               printk("ldt_get_host_info: couldn't allocate buffer for host "
+                      "ldt\n");
                return;
        }
 
@@ -426,11 +437,13 @@ void ldt_get_host_info(void)
                host_ldt_entries = dummy_list;
        else {
                size = (size + 1) * sizeof(dummy_list[0]);
-               host_ldt_entries = kmalloc(size, GFP_KERNEL);
-               if(host_ldt_entries == NULL) {
-                       printk("ldt_get_host_info: couldn't allocate host ldt list\n");
+               tmp = kmalloc(size, GFP_KERNEL);
+               if(tmp == NULL) {
+                       printk("ldt_get_host_info: couldn't allocate host ldt "
+                              "list\n");
                        goto out_free;
                }
+               host_ldt_entries = tmp;
        }
 
        for(i=0, k=0; i<ret/LDT_ENTRY_SIZE; i++){
@@ -480,8 +493,7 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
                         * inherited from the host. All ldt-entries found
                         * will be reset in the following loop
                         */
-                       if(host_ldt_entries == NULL)
-                               ldt_get_host_info();
+                       ldt_get_host_info();
                        for(num_p=host_ldt_entries; *num_p != -1; num_p++){
                                desc.entry_number = *num_p;
                                err = write_ldt_entry(&new_mm->id, 1, &desc,
@@ -560,6 +572,6 @@ void free_ldt(struct mmu_context_skas * mm)
 
 int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
 {
-       return(CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func,
-                               ptr, bytecount));
+       return CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func,
+                               ptr, bytecount);
 }
index e942ffe8b57ee4c9a13a447bf205e3939815dfcc..7c49e103cf8fee8003fbedd8ee36c484767bf6bb 100644 (file)
@@ -149,6 +149,7 @@ config ACPI_DOCK
 config ACPI_BAY
        tristate "Removable Drive Bay (EXPERIMENTAL)"
        depends on EXPERIMENTAL
+       depends on ACPI_DOCK
        help
          This driver adds support for ACPI controlled removable drive
          bays such as the IBM ultrabay or the Dell Module Bay.
index dff3766f117f3307fdc52fbb46a9126db32d4a14..5872036e8ae6b90f36b2c29789c826755f0d7903 100644 (file)
@@ -1179,8 +1179,10 @@ static int __init mm_init(void)
                return -ENOMEM;
 
        err = major_nr = register_blkdev(0, "umem");
-       if (err < 0)
+       if (err < 0) {
+               pci_unregister_driver(&mm_pci_driver);
                return -EIO;
+       }
 
        for (i = 0; i < num_cards; i++) {
                mm_gendisk[i] = alloc_disk(1 << MM_SHIFT);
@@ -1207,6 +1209,7 @@ static int __init mm_init(void)
        return 0;
 
 out:
+       pci_unregister_driver(&mm_pci_driver);
        unregister_blkdev(major_nr, "umem");
        while (i--)
                put_disk(mm_gendisk[i]);
index f24c26d2dba116fbbd833eb29a5acf07facddc42..e453268566805238288ba64f96e1c5da0f8a1ba3 100644 (file)
@@ -1901,6 +1901,20 @@ static int init_dev(struct tty_driver *driver, int idx,
        /* check whether we're reopening an existing tty */
        if (driver->flags & TTY_DRIVER_DEVPTS_MEM) {
                tty = devpts_get_tty(idx);
+               /*
+                * If we don't have a tty here on a slave open, it's because
+                * the master already started the close process and there's
+                * no relation between devpts file and tty anymore.
+                */
+               if (!tty && driver->subtype == PTY_TYPE_SLAVE) {
+                       retval = -EIO;
+                       goto end_init;
+               }
+               /*
+                * It's safe from now on because init_dev() is called with
+                * tty_mutex held and release_dev() won't change tty->count
+                * or tty->flags without having to grab tty_mutex
+                */
                if (tty && driver->subtype == PTY_TYPE_MASTER)
                        tty = tty->link;
        } else {
index 8b6c9a431ffa6d1ea0f6ccdec96000bab8d465c9..c921d6c522f50ef257d825894b0f059bc9f11044 100644 (file)
@@ -2,13 +2,25 @@
 # Config.in for the CAPI subsystem
 #
 config ISDN_DRV_AVMB1_VERBOSE_REASON
-       bool "Verbose reason code reporting (kernel size +=7K)"
+       bool "Verbose reason code reporting"
        depends on ISDN_CAPI
+       default y
        help
-         If you say Y here, the AVM B1 driver will give verbose reasons for
+         If you say Y here, the CAPI drivers will give verbose reasons for
          disconnecting. This will increase the size of the kernel by 7 KB. If
          unsure, say Y.
 
+config CAPI_TRACE
+       bool "CAPI trace support"
+       depends on ISDN_CAPI
+       default y
+       help
+         If you say Y here, the kernelcapi driver can make verbose traces
+         of CAPI messages. This feature can be enabled/disabled via IOCTL for
+         every controler (default disabled).
+         This will increase the size of the kernelcapi module by 20 KB.
+         If unsure, say Y.
+
 config ISDN_CAPI_MIDDLEWARE
        bool "CAPI2.0 Middleware support (EXPERIMENTAL)"
        depends on ISDN_CAPI && EXPERIMENTAL
index 2a49cea0a223e19e41cdeee3e4f900886521949f..23b6f7bc16b7e53ebac2a6d73e76608bcaa67ecf 100644 (file)
@@ -990,6 +990,7 @@ static void handle_plci(_cmsg * cmsg)
        capidrv_contr *card = findcontrbynumber(cmsg->adr.adrController & 0x7f);
        capidrv_plci *plcip;
        isdn_ctrl cmd;
+       _cdebbuf *cdb;
 
        if (!card) {
                printk(KERN_ERR "capidrv: %s from unknown controller 0x%x\n",
@@ -1122,8 +1123,15 @@ static void handle_plci(_cmsg * cmsg)
                                break;
                        }
                }
-               printk(KERN_ERR "capidrv-%d: %s\n",
-                               card->contrnr, capi_cmsg2str(cmsg));
+               cdb = capi_cmsg2str(cmsg);
+               if (cdb) {
+                       printk(KERN_WARNING "capidrv-%d: %s\n",
+                               card->contrnr, cdb->buf);
+                       cdebbuf_free(cdb);
+               } else
+                       printk(KERN_WARNING "capidrv-%d: CAPI_INFO_IND InfoNumber %x not handled\n",
+                               card->contrnr, cmsg->InfoNumber);
+
                break;
 
        case CAPI_CONNECT_ACTIVE_CONF:          /* plci */
@@ -1371,10 +1379,18 @@ static _cmsg s_cmsg;
 static void capidrv_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
 {
        capi_message2cmsg(&s_cmsg, skb->data);
-       if (debugmode > 3)
-               printk(KERN_DEBUG "capidrv_signal: applid=%d %s\n",
-                      ap->applid, capi_cmsg2str(&s_cmsg));
-       
+       if (debugmode > 3) {
+               _cdebbuf *cdb = capi_cmsg2str(&s_cmsg);
+
+               if (cdb) {
+                       printk(KERN_DEBUG "%s: applid=%d %s\n", __FUNCTION__,
+                               ap->applid, cdb->buf);
+                       cdebbuf_free(cdb);
+               } else
+                       printk(KERN_DEBUG "%s: applid=%d %s not traced\n",
+                               __FUNCTION__, ap->applid,
+                               capi_cmd2str(s_cmsg.Command, s_cmsg.Subcommand));
+       }
        if (s_cmsg.Command == CAPI_DATA_B3
            && s_cmsg.Subcommand == CAPI_IND) {
                handle_data(&s_cmsg, skb);
index c1b21552fc036ae88fba6f53b975a61d5b56dfdb..ad1e2702c2d1734b00d74678ab2295e350e10274 100644 (file)
@@ -648,6 +648,9 @@ char *capi_cmd2str(u8 cmd, u8 subcmd)
 
 
 /*-------------------------------------------------------*/
+
+#ifdef CONFIG_CAPI_TRACE
+
 /*-------------------------------------------------------*/
 
 static char *pnames[] =
@@ -703,44 +706,77 @@ static char *pnames[] =
 };
 
 
-static char buf[8192];
-static char *p = NULL;
 
 #include <stdarg.h>
 
 /*-------------------------------------------------------*/
-static void bufprint(char *fmt,...)
+static _cdebbuf *bufprint(_cdebbuf *cdb, char *fmt,...)
 {
        va_list f;
+       size_t n,r;
+
+       if (!cdb)
+               return NULL;
        va_start(f, fmt);
-       vsprintf(p, fmt, f);
+       r = cdb->size - cdb->pos;
+       n = vsnprintf(cdb->p, r, fmt, f);
        va_end(f);
-       p += strlen(p);
+       if (n >= r) {
+               /* truncated, need bigger buffer */
+               size_t ns = 2 * cdb->size;
+               u_char *nb;
+
+               while ((ns - cdb->pos) <= n)
+                       ns *= 2;
+               nb = kmalloc(ns, GFP_ATOMIC);
+               if (!nb) {
+                       cdebbuf_free(cdb);
+                       return NULL;
+               }
+               memcpy(nb, cdb->buf, cdb->pos);
+               kfree(cdb->buf);
+               nb[cdb->pos] = 0;
+               cdb->buf = nb;
+               cdb->p = cdb->buf + cdb->pos;
+               cdb->size = ns;
+               va_start(f, fmt);
+               r = cdb->size - cdb->pos;
+               n = vsnprintf(cdb->p, r, fmt, f);
+               va_end(f);
+       }
+       cdb->p += n;
+       cdb->pos += n;
+       return cdb;
 }
 
-static void printstructlen(u8 * m, unsigned len)
+static _cdebbuf *printstructlen(_cdebbuf *cdb, u8 * m, unsigned len)
 {
        unsigned hex = 0;
+
+       if (!cdb)
+               return NULL;
        for (; len; len--, m++)
                if (isalnum(*m) || *m == ' ') {
                        if (hex)
-                               bufprint(">");
-                       bufprint("%c", *m);
+                               cdb = bufprint(cdb, ">");
+                       cdb = bufprint(cdb, "%c", *m);
                        hex = 0;
                } else {
                        if (!hex)
-                               bufprint("<%02x", *m);
+                               cdb = bufprint(cdb, "<%02x", *m);
                        else
-                               bufprint(" %02x", *m);
+                               cdb = bufprint(cdb, " %02x", *m);
                        hex = 1;
                }
        if (hex)
-               bufprint(">");
+               cdb = bufprint(cdb, ">");
+       return cdb;
 }
 
-static void printstruct(u8 * m)
+static _cdebbuf *printstruct(_cdebbuf *cdb, u8 * m)
 {
        unsigned len;
+
        if (m[0] != 0xff) {
                len = m[0];
                m += 1;
@@ -748,42 +784,45 @@ static void printstruct(u8 * m)
                len = ((u16 *) (m + 1))[0];
                m += 3;
        }
-       printstructlen(m, len);
+       cdb = printstructlen(cdb, m, len);
+       return cdb;
 }
 
 /*-------------------------------------------------------*/
 #define NAME (pnames[cmsg->par[cmsg->p]])
 
-static void protocol_message_2_pars(_cmsg * cmsg, int level)
+static _cdebbuf *protocol_message_2_pars(_cdebbuf *cdb, _cmsg *cmsg, int level)
 {
        for (; TYP != _CEND; cmsg->p++) {
                int slen = 29 + 3 - level;
                int i;
 
-               bufprint("  ");
+               if (!cdb)
+                       return NULL;
+               cdb = bufprint(cdb, "  ");
                for (i = 0; i < level - 1; i++)
-                       bufprint(" ");
+                       cdb = bufprint(cdb, " ");
 
                switch (TYP) {
                case _CBYTE:
-                       bufprint("%-*s = 0x%x\n", slen, NAME, *(u8 *) (cmsg->m + cmsg->l));
+                       cdb = bufprint(cdb, "%-*s = 0x%x\n", slen, NAME, *(u8 *) (cmsg->m + cmsg->l));
                        cmsg->l++;
                        break;
                case _CWORD:
-                       bufprint("%-*s = 0x%x\n", slen, NAME, *(u16 *) (cmsg->m + cmsg->l));
+                       cdb = bufprint(cdb, "%-*s = 0x%x\n", slen, NAME, *(u16 *) (cmsg->m + cmsg->l));
                        cmsg->l += 2;
                        break;
                case _CDWORD:
-                       bufprint("%-*s = 0x%lx\n", slen, NAME, *(u32 *) (cmsg->m + cmsg->l));
+                       cdb = bufprint(cdb, "%-*s = 0x%lx\n", slen, NAME, *(u32 *) (cmsg->m + cmsg->l));
                        cmsg->l += 4;
                        break;
                case _CSTRUCT:
-                       bufprint("%-*s = ", slen, NAME);
+                       cdb = bufprint(cdb, "%-*s = ", slen, NAME);
                        if (cmsg->m[cmsg->l] == '\0')
-                               bufprint("default");
+                               cdb = bufprint(cdb, "default");
                        else
-                               printstruct(cmsg->m + cmsg->l);
-                       bufprint("\n");
+                               cdb = printstruct(cdb, cmsg->m + cmsg->l);
+                       cdb = bufprint(cdb, "\n");
                        if (cmsg->m[cmsg->l] != 0xff)
                                cmsg->l += 1 + cmsg->m[cmsg->l];
                        else
@@ -794,61 +833,184 @@ static void protocol_message_2_pars(_cmsg * cmsg, int level)
                case _CMSTRUCT:
 /*----- Metastruktur 0 -----*/
                        if (cmsg->m[cmsg->l] == '\0') {
-                               bufprint("%-*s = default\n", slen, NAME);
+                               cdb = bufprint(cdb, "%-*s = default\n", slen, NAME);
                                cmsg->l++;
                                jumpcstruct(cmsg);
                        } else {
                                char *name = NAME;
                                unsigned _l = cmsg->l;
-                               bufprint("%-*s\n", slen, name);
+                               cdb = bufprint(cdb, "%-*s\n", slen, name);
                                cmsg->l = (cmsg->m + _l)[0] == 255 ? cmsg->l + 3 : cmsg->l + 1;
                                cmsg->p++;
-                               protocol_message_2_pars(cmsg, level + 1);
+                               cdb = protocol_message_2_pars(cdb, cmsg, level + 1);
                        }
                        break;
                }
        }
+       return cdb;
 }
 /*-------------------------------------------------------*/
-char *capi_message2str(u8 * msg)
+
+static _cdebbuf *g_debbuf;
+static u_long g_debbuf_lock;
+static _cmsg *g_cmsg;
+
+_cdebbuf *cdebbuf_alloc(void)
 {
+       _cdebbuf *cdb;
+
+       if (likely(!test_and_set_bit(1, &g_debbuf_lock))) {
+               cdb = g_debbuf;
+               goto init;
+       } else
+               cdb = kmalloc(sizeof(_cdebbuf), GFP_ATOMIC);
+       if (!cdb)
+               return NULL;
+       cdb->buf = kmalloc(CDEBUG_SIZE, GFP_ATOMIC);
+       if (!cdb->buf) {
+               kfree(cdb);
+               return NULL;
+       }
+       cdb->size = CDEBUG_SIZE;
+init:
+       cdb->buf[0] = 0;
+       cdb->p = cdb->buf;
+       cdb->pos = 0;
+       return cdb;
+}
 
-       _cmsg cmsg;
-       p = buf;
-       p[0] = 0;
+void cdebbuf_free(_cdebbuf *cdb)
+{
+       if (likely(cdb == g_debbuf)) {
+               test_and_clear_bit(1, &g_debbuf_lock);
+               return;
+       }
+       if (likely(cdb))
+               kfree(cdb->buf);
+       kfree(cdb);
+}
 
-       cmsg.m = msg;
-       cmsg.l = 8;
-       cmsg.p = 0;
-       byteTRcpy(cmsg.m + 4, &cmsg.Command);
-       byteTRcpy(cmsg.m + 5, &cmsg.Subcommand);
-       cmsg.par = cpars[command_2_index(cmsg.Command, cmsg.Subcommand)];
 
-       bufprint("%-26s ID=%03d #0x%04x LEN=%04d\n",
-                mnames[command_2_index(cmsg.Command, cmsg.Subcommand)],
+_cdebbuf *capi_message2str(u8 * msg)
+{
+       _cdebbuf *cdb;
+       _cmsg   *cmsg;
+
+       cdb = cdebbuf_alloc();
+       if (unlikely(!cdb))
+               return NULL;
+       if (likely(cdb == g_debbuf))
+               cmsg = g_cmsg;
+       else
+               cmsg = kmalloc(sizeof(_cmsg), GFP_ATOMIC);
+       if (unlikely(!cmsg)) {
+               cdebbuf_free(cdb);
+               return NULL;
+       }
+       cmsg->m = msg;
+       cmsg->l = 8;
+       cmsg->p = 0;
+       byteTRcpy(cmsg->m + 4, &cmsg->Command);
+       byteTRcpy(cmsg->m + 5, &cmsg->Subcommand);
+       cmsg->par = cpars[command_2_index(cmsg->Command, cmsg->Subcommand)];
+
+       cdb = bufprint(cdb, "%-26s ID=%03d #0x%04x LEN=%04d\n",
+                mnames[command_2_index(cmsg->Command, cmsg->Subcommand)],
                 ((unsigned short *) msg)[1],
                 ((unsigned short *) msg)[3],
                 ((unsigned short *) msg)[0]);
 
-       protocol_message_2_pars(&cmsg, 1);
-       return buf;
+       cdb = protocol_message_2_pars(cdb, cmsg, 1);
+       if (unlikely(cmsg != g_cmsg))
+               kfree(cmsg);
+       return cdb;
 }
 
-char *capi_cmsg2str(_cmsg * cmsg)
+_cdebbuf *capi_cmsg2str(_cmsg * cmsg)
 {
-       p = buf;
-       p[0] = 0;
+       _cdebbuf *cdb;
+
+       cdb = cdebbuf_alloc();
+       if (!cdb)
+               return NULL;
        cmsg->l = 8;
        cmsg->p = 0;
-       bufprint("%s ID=%03d #0x%04x LEN=%04d\n",
+       cdb = bufprint(cdb, "%s ID=%03d #0x%04x LEN=%04d\n",
                 mnames[command_2_index(cmsg->Command, cmsg->Subcommand)],
                 ((u16 *) cmsg->m)[1],
                 ((u16 *) cmsg->m)[3],
                 ((u16 *) cmsg->m)[0]);
-       protocol_message_2_pars(cmsg, 1);
-       return buf;
+       cdb = protocol_message_2_pars(cdb, cmsg, 1);
+       return cdb;
 }
 
+int __init cdebug_init(void)
+{
+       g_cmsg= kmalloc(sizeof(_cmsg), GFP_KERNEL);
+       if (!g_cmsg)
+               return ENOMEM;
+       g_debbuf = kmalloc(sizeof(_cdebbuf), GFP_KERNEL);
+       if (!g_debbuf) {
+               kfree(g_cmsg);
+               return ENOMEM;
+       }
+       g_debbuf->buf = kmalloc(CDEBUG_GSIZE, GFP_KERNEL);
+       if (!g_debbuf->buf) {
+               kfree(g_cmsg);
+               kfree(g_debbuf);
+               return ENOMEM;;
+       }
+       g_debbuf->size = CDEBUG_GSIZE;
+       g_debbuf->buf[0] = 0;
+       g_debbuf->p = g_debbuf->buf;
+       g_debbuf->pos = 0;
+       return 0;
+}
+
+void __exit cdebug_exit(void)
+{
+       if (g_debbuf)
+               kfree(g_debbuf->buf);
+       kfree(g_debbuf);
+       kfree(g_cmsg);
+}
+
+#else /* !CONFIG_CAPI_TRACE */
+
+static _cdebbuf g_debbuf = {"CONFIG_CAPI_TRACE not enabled", NULL, 0, 0};
+
+_cdebbuf *capi_message2str(u8 * msg)
+{
+       return &g_debbuf;
+}
+
+_cdebbuf *capi_cmsg2str(_cmsg * cmsg)
+{
+       return &g_debbuf;
+}
+
+_cdebbuf *cdebbuf_alloc(void)
+{
+       return &g_debbuf;
+}
+
+void cdebbuf_free(_cdebbuf *cdb)
+{
+}
+
+int __init cdebug_init(void)
+{
+       return 0;
+}
+
+void __exit cdebug_exit(void)
+{
+}
+
+#endif
+
+EXPORT_SYMBOL(cdebbuf_alloc);
+EXPORT_SYMBOL(cdebbuf_free);
 EXPORT_SYMBOL(capi_cmsg2message);
 EXPORT_SYMBOL(capi_message2cmsg);
 EXPORT_SYMBOL(capi_cmsg_header);
index 783a25526315beacce63c85fa1536ddde2117c17..3ed34f7a1c4ff3ff79d209838c58eba860e5be60 100644 (file)
@@ -276,10 +276,17 @@ void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *s
        int showctl = 0;
        u8 cmd, subcmd;
        unsigned long flags;
+       _cdebbuf *cdb;
 
        if (card->cardstate != CARD_RUNNING) {
-               printk(KERN_INFO "kcapi: controller %d not active, got: %s",
-                      card->cnr, capi_message2str(skb->data));
+               cdb = capi_message2str(skb->data);
+               if (cdb) {
+                       printk(KERN_INFO "kcapi: controller [%03d] not active, got: %s",
+                               card->cnr, cdb->buf);
+                       cdebbuf_free(cdb);
+               } else
+                       printk(KERN_INFO "kcapi: controller [%03d] not active, cannot trace\n",
+                               card->cnr);
                goto error;
        }
 
@@ -295,15 +302,21 @@ void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *s
        showctl |= (card->traceflag & 1);
        if (showctl & 2) {
                if (showctl & 1) {
-                       printk(KERN_DEBUG "kcapi: got [0x%lx] id#%d %s len=%u\n",
-                              (unsigned long) card->cnr,
-                              CAPIMSG_APPID(skb->data),
+                       printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u\n",
+                              card->cnr, CAPIMSG_APPID(skb->data),
                               capi_cmd2str(cmd, subcmd),
                               CAPIMSG_LEN(skb->data));
                } else {
-                       printk(KERN_DEBUG "kcapi: got [0x%lx] %s\n",
-                                       (unsigned long) card->cnr,
-                                       capi_message2str(skb->data));
+                       cdb = capi_message2str(skb->data);
+                       if (cdb) {
+                               printk(KERN_DEBUG "kcapi: got [%03d] %s\n",
+                                       card->cnr, cdb->buf);
+                               cdebbuf_free(cdb);
+                       } else
+                               printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u, cannot trace\n",
+                                       card->cnr, CAPIMSG_APPID(skb->data),
+                                       capi_cmd2str(cmd, subcmd),
+                                       CAPIMSG_LEN(skb->data));
                }
 
        }
@@ -312,8 +325,15 @@ void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *s
        ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data));
        if ((!ap) || (ap->release_in_progress)) {
                read_unlock_irqrestore(&application_lock, flags);
-               printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n",
-                       CAPIMSG_APPID(skb->data), capi_message2str(skb->data));
+               cdb = capi_message2str(skb->data);
+               if (cdb) {
+                       printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n",
+                       CAPIMSG_APPID(skb->data), cdb->buf);
+                       cdebbuf_free(cdb);
+               } else
+                       printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s) cannot trace\n",
+                               CAPIMSG_APPID(skb->data),
+                               capi_cmd2str(cmd, subcmd));
                goto error;
        }
        skb_queue_tail(&ap->recv_queue, skb);
@@ -332,7 +352,7 @@ void capi_ctr_ready(struct capi_ctr * card)
 {
        card->cardstate = CARD_RUNNING;
 
-        printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n",
+        printk(KERN_NOTICE "kcapi: card [%03d] \"%s\" ready.\n",
               card->cnr, card->name);
 
        notify_push(KCI_CONTRUP, card->cnr, 0, 0);
@@ -364,7 +384,7 @@ void capi_ctr_reseted(struct capi_ctr * card)
                capi_ctr_put(card);
        }
 
-       printk(KERN_NOTICE "kcapi: card %d down.\n", card->cnr);
+       printk(KERN_NOTICE "kcapi: card [%03d] down.\n", card->cnr);
 
        notify_push(KCI_CONTRDOWN, card->cnr, 0, 0);
 }
@@ -374,7 +394,7 @@ EXPORT_SYMBOL(capi_ctr_reseted);
 void capi_ctr_suspend_output(struct capi_ctr *card)
 {
        if (!card->blocked) {
-               printk(KERN_DEBUG "kcapi: card %d suspend\n", card->cnr);
+               printk(KERN_DEBUG "kcapi: card [%03d] suspend\n", card->cnr);
                card->blocked = 1;
        }
 }
@@ -384,7 +404,7 @@ EXPORT_SYMBOL(capi_ctr_suspend_output);
 void capi_ctr_resume_output(struct capi_ctr *card)
 {
        if (card->blocked) {
-               printk(KERN_DEBUG "kcapi: card %d resume\n", card->cnr);
+               printk(KERN_DEBUG "kcapi: card [%03d] resume\n", card->cnr);
                card->blocked = 0;
        }
 }
@@ -432,7 +452,7 @@ attach_capi_ctr(struct capi_ctr *card)
        }
 
        ncards++;
-       printk(KERN_NOTICE "kcapi: Controller %d: %s attached\n",
+       printk(KERN_NOTICE "kcapi: Controller [%03d]: %s attached\n",
                        card->cnr, card->name);
        return 0;
 }
@@ -451,7 +471,7 @@ int detach_capi_ctr(struct capi_ctr *card)
           card->procent = NULL;
        }
        capi_cards[card->cnr - 1] = NULL;
-       printk(KERN_NOTICE "kcapi: Controller %d: %s unregistered\n",
+       printk(KERN_NOTICE "kcapi: Controller [%03d]: %s unregistered\n",
                        card->cnr, card->name);
 
        return 0;
@@ -623,17 +643,25 @@ u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
        showctl |= (card->traceflag & 1);
        if (showctl & 2) {
                if (showctl & 1) {
-                       printk(KERN_DEBUG "kcapi: put [%#x] id#%d %s len=%u\n",
+                       printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u\n",
                               CAPIMSG_CONTROLLER(skb->data),
                               CAPIMSG_APPID(skb->data),
                               capi_cmd2str(cmd, subcmd),
                               CAPIMSG_LEN(skb->data));
                } else {
-                       printk(KERN_DEBUG "kcapi: put [%#x] %s\n",
-                              CAPIMSG_CONTROLLER(skb->data),
-                              capi_message2str(skb->data));
+                       _cdebbuf *cdb = capi_message2str(skb->data);
+                       if (cdb) {
+                               printk(KERN_DEBUG "kcapi: put [%03d] %s\n",
+                                       CAPIMSG_CONTROLLER(skb->data),
+                                       cdb->buf);
+                               cdebbuf_free(cdb);
+                       } else
+                               printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u cannot trace\n",
+                                       CAPIMSG_CONTROLLER(skb->data),
+                                       CAPIMSG_APPID(skb->data),
+                                       capi_cmd2str(cmd, subcmd),
+                                       CAPIMSG_LEN(skb->data));
                }
-
        }
        return card->send_message(card, skb);
 }
@@ -894,7 +922,7 @@ int capi20_manufacturer(unsigned int cmd, void __user *data)
                        return -ESRCH;
 
                card->traceflag = fdef.flag;
-               printk(KERN_INFO "kcapi: contr %d set trace=%d\n",
+               printk(KERN_INFO "kcapi: contr [%03d] set trace=%d\n",
                        card->cnr, card->traceflag);
                return 0;
        }
@@ -967,7 +995,11 @@ static int __init kcapi_init(void)
 {
        char *p;
        char rev[32];
+       int ret;
 
+       ret = cdebug_init();
+       if (ret)
+               return ret;
         kcapi_proc_init();
 
        if ((p = strchr(revision, ':')) != 0 && p[1]) {
@@ -988,6 +1020,7 @@ static void __exit kcapi_exit(void)
 
        /* make sure all notifiers are finished */
        flush_scheduled_work();
+       cdebug_exit();
 }
 
 module_init(kcapi_init);
index 5158be0b7ab4c5a49b0af0b48c6ade59932ffda9..e9d3189f56b70ed4e809e64f8bc397e461789b25 100644 (file)
@@ -1,8 +1,9 @@
 gigaset-y := common.o interface.o proc.o ev-layer.o i4l.o asyncdata.o
 usb_gigaset-y := usb-gigaset.o
-bas_gigaset-y := bas-gigaset.o isocdata.o
 ser_gigaset-y := ser-gigaset.o
+bas_gigaset-y := bas-gigaset.o isocdata.o
 
-obj-$(CONFIG_GIGASET_M105) += usb_gigaset.o gigaset.o
-obj-$(CONFIG_GIGASET_BASE) += bas_gigaset.o gigaset.o
-obj-$(CONFIG_GIGASET_M101) += ser_gigaset.o gigaset.o
+obj-$(CONFIG_ISDN_DRV_GIGASET) += gigaset.o
+obj-$(CONFIG_GIGASET_M105) += usb_gigaset.o
+obj-$(CONFIG_GIGASET_BASE) += bas_gigaset.o
+obj-$(CONFIG_GIGASET_M101) += ser_gigaset.o
index f2f108fcec4d8a1e1a41532acedc856d2048d1a1..00a3be5b862bbf87416231c2f91c58851e593c87 100644 (file)
  * =====================================================================
  */
 
-/* not set by Kbuild when building both ser_gigaset and usb_gigaset */
-#ifndef KBUILD_MODNAME
-#define KBUILD_MODNAME "asy_gigaset"
-#endif
-
 #include "gigaset.h"
 #include <linux/crc-ccitt.h>
 #include <linux/bitrev.h>
index 05febfd9f0712d0875b52dcb4f2c07cd15ff7c8f..6c06e825cff5af8f070ff9d370f987da7c64f34b 100644 (file)
@@ -1296,27 +1296,17 @@ static struct super_type super_types[] = {
                .sync_super     = super_1_sync,
        },
 };
-       
-static mdk_rdev_t * match_dev_unit(mddev_t *mddev, mdk_rdev_t *dev)
-{
-       struct list_head *tmp;
-       mdk_rdev_t *rdev;
-
-       ITERATE_RDEV(mddev,rdev,tmp)
-               if (rdev->bdev->bd_contains == dev->bdev->bd_contains)
-                       return rdev;
-
-       return NULL;
-}
 
 static int match_mddev_units(mddev_t *mddev1, mddev_t *mddev2)
 {
-       struct list_head *tmp;
-       mdk_rdev_t *rdev;
+       struct list_head *tmp, *tmp2;
+       mdk_rdev_t *rdev, *rdev2;
 
        ITERATE_RDEV(mddev1,rdev,tmp)
-               if (match_dev_unit(mddev2, rdev))
-                       return 1;
+               ITERATE_RDEV(mddev2, rdev2, tmp2)
+                       if (rdev->bdev->bd_contains ==
+                           rdev2->bdev->bd_contains)
+                               return 1;
 
        return 0;
 }
@@ -1325,8 +1315,7 @@ static LIST_HEAD(pending_raid_disks);
 
 static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
 {
-       mdk_rdev_t *same_pdev;
-       char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE];
+       char b[BDEVNAME_SIZE];
        struct kobject *ko;
        char *s;
 
@@ -1342,14 +1331,6 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
                else
                        mddev->size = rdev->size;
        }
-       same_pdev = match_dev_unit(mddev, rdev);
-       if (same_pdev)
-               printk(KERN_WARNING
-                       "%s: WARNING: %s appears to be on the same physical"
-                       " disk as %s. True\n     protection against single-disk"
-                       " failure might be compromised.\n",
-                       mdname(mddev), bdevname(rdev->bdev,b),
-                       bdevname(same_pdev->bdev,b2));
 
        /* Verify rdev->desc_nr is unique.
         * If it is -1, assign a free number, else
@@ -3109,6 +3090,36 @@ static int do_md_run(mddev_t * mddev)
                return -EINVAL;
        }
 
+       if (pers->sync_request) {
+               /* Warn if this is a potentially silly
+                * configuration.
+                */
+               char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE];
+               mdk_rdev_t *rdev2;
+               struct list_head *tmp2;
+               int warned = 0;
+               ITERATE_RDEV(mddev, rdev, tmp) {
+                       ITERATE_RDEV(mddev, rdev2, tmp2) {
+                               if (rdev < rdev2 &&
+                                   rdev->bdev->bd_contains ==
+                                   rdev2->bdev->bd_contains) {
+                                       printk(KERN_WARNING
+                                              "%s: WARNING: %s appears to be"
+                                              " on the same physical disk as"
+                                              " %s.\n",
+                                              mdname(mddev),
+                                              bdevname(rdev->bdev,b),
+                                              bdevname(rdev2->bdev,b2));
+                                       warned = 1;
+                               }
+                       }
+               }
+               if (warned)
+                       printk(KERN_WARNING
+                              "True protection against single-disk"
+                              " failure might be compromised.\n");
+       }
+
        mddev->recovery = 0;
        mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */
        mddev->barriers_work = 1;
@@ -3311,6 +3322,9 @@ static int do_md_stop(mddev_t * mddev, int mode)
                                set_disk_ro(disk, 0);
                        blk_queue_make_request(mddev->queue, md_fail_request);
                        mddev->pers->stop(mddev);
+                       mddev->queue->merge_bvec_fn = NULL;
+                       mddev->queue->unplug_fn = NULL;
+                       mddev->queue->issue_flush_fn = NULL;
                        if (mddev->pers->sync_request)
                                sysfs_remove_group(&mddev->kobj, &md_redundancy_group);
 
@@ -5343,6 +5357,44 @@ void md_do_sync(mddev_t *mddev)
 EXPORT_SYMBOL_GPL(md_do_sync);
 
 
+static int remove_and_add_spares(mddev_t *mddev)
+{
+       mdk_rdev_t *rdev;
+       struct list_head *rtmp;
+       int spares = 0;
+
+       ITERATE_RDEV(mddev,rdev,rtmp)
+               if (rdev->raid_disk >= 0 &&
+                   (test_bit(Faulty, &rdev->flags) ||
+                    ! test_bit(In_sync, &rdev->flags)) &&
+                   atomic_read(&rdev->nr_pending)==0) {
+                       if (mddev->pers->hot_remove_disk(
+                                   mddev, rdev->raid_disk)==0) {
+                               char nm[20];
+                               sprintf(nm,"rd%d", rdev->raid_disk);
+                               sysfs_remove_link(&mddev->kobj, nm);
+                               rdev->raid_disk = -1;
+                       }
+               }
+
+       if (mddev->degraded) {
+               ITERATE_RDEV(mddev,rdev,rtmp)
+                       if (rdev->raid_disk < 0
+                           && !test_bit(Faulty, &rdev->flags)) {
+                               rdev->recovery_offset = 0;
+                               if (mddev->pers->hot_add_disk(mddev,rdev)) {
+                                       char nm[20];
+                                       sprintf(nm, "rd%d", rdev->raid_disk);
+                                       sysfs_create_link(&mddev->kobj,
+                                                         &rdev->kobj, nm);
+                                       spares++;
+                                       md_new_event(mddev);
+                               } else
+                                       break;
+                       }
+       }
+       return spares;
+}
 /*
  * This routine is regularly called by all per-raid-array threads to
  * deal with generic issues like resync and super-block update.
@@ -5397,7 +5449,7 @@ void md_check_recovery(mddev_t *mddev)
                return;
 
        if (mddev_trylock(mddev)) {
-               int spares =0;
+               int spares = 0;
 
                spin_lock_irq(&mddev->write_lock);
                if (mddev->safemode && !atomic_read(&mddev->writes_pending) &&
@@ -5460,35 +5512,13 @@ void md_check_recovery(mddev_t *mddev)
                 * Spare are also removed and re-added, to allow
                 * the personality to fail the re-add.
                 */
-               ITERATE_RDEV(mddev,rdev,rtmp)
-                       if (rdev->raid_disk >= 0 &&
-                           (test_bit(Faulty, &rdev->flags) || ! test_bit(In_sync, &rdev->flags)) &&
-                           atomic_read(&rdev->nr_pending)==0) {
-                               if (mddev->pers->hot_remove_disk(mddev, rdev->raid_disk)==0) {
-                                       char nm[20];
-                                       sprintf(nm,"rd%d", rdev->raid_disk);
-                                       sysfs_remove_link(&mddev->kobj, nm);
-                                       rdev->raid_disk = -1;
-                               }
-                       }
-
-               if (mddev->degraded) {
-                       ITERATE_RDEV(mddev,rdev,rtmp)
-                               if (rdev->raid_disk < 0
-                                   && !test_bit(Faulty, &rdev->flags)) {
-                                       rdev->recovery_offset = 0;
-                                       if (mddev->pers->hot_add_disk(mddev,rdev)) {
-                                               char nm[20];
-                                               sprintf(nm, "rd%d", rdev->raid_disk);
-                                               sysfs_create_link(&mddev->kobj, &rdev->kobj, nm);
-                                               spares++;
-                                               md_new_event(mddev);
-                                       } else
-                                               break;
-                               }
-               }
 
-               if (spares) {
+               if (mddev->reshape_position != MaxSector) {
+                       if (mddev->pers->check_reshape(mddev) != 0)
+                               /* Cannot proceed */
+                               goto unlock;
+                       set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery);
+               } else if ((spares = remove_and_add_spares(mddev))) {
                        clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
                        clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
                } else if (mddev->recovery_cp < MaxSector) {
index a9401c017e3588f076411d83046c84b27495eab8..82249a69014f0295055d10d750d297ac8e4291c6 100644 (file)
@@ -429,7 +429,7 @@ static sector_t raid10_find_virt(conf_t *conf, sector_t sector, int dev)
                if (dev < 0)
                        dev += conf->raid_disks;
        } else {
-               while (sector > conf->stride) {
+               while (sector >= conf->stride) {
                        sector -= conf->stride;
                        if (dev < conf->near_copies)
                                dev += conf->raid_disks - conf->near_copies;
@@ -1801,6 +1801,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                                                for (k=0; k<conf->copies; k++)
                                                        if (r10_bio->devs[k].devnum == i)
                                                                break;
+                                               BUG_ON(k == conf->copies);
                                                bio = r10_bio->devs[1].bio;
                                                bio->bi_next = biolist;
                                                biolist = bio;
@@ -2021,19 +2022,30 @@ static int run(mddev_t *mddev)
        if (!conf->tmppage)
                goto out_free_conf;
 
+       conf->mddev = mddev;
+       conf->raid_disks = mddev->raid_disks;
        conf->near_copies = nc;
        conf->far_copies = fc;
        conf->copies = nc*fc;
        conf->far_offset = fo;
        conf->chunk_mask = (sector_t)(mddev->chunk_size>>9)-1;
        conf->chunk_shift = ffz(~mddev->chunk_size) - 9;
+       size = mddev->size >> (conf->chunk_shift-1);
+       sector_div(size, fc);
+       size = size * conf->raid_disks;
+       sector_div(size, nc);
+       /* 'size' is now the number of chunks in the array */
+       /* calculate "used chunks per device" in 'stride' */
+       stride = size * conf->copies;
+       sector_div(stride, conf->raid_disks);
+       mddev->size = stride  << (conf->chunk_shift-1);
+
        if (fo)
-               conf->stride = 1 << conf->chunk_shift;
-       else {
-               stride = mddev->size >> (conf->chunk_shift-1);
+               stride = 1;
+       else
                sector_div(stride, fc);
-               conf->stride = stride << conf->chunk_shift;
-       }
+       conf->stride = stride << conf->chunk_shift;
+
        conf->r10bio_pool = mempool_create(NR_RAID10_BIOS, r10bio_pool_alloc,
                                                r10bio_pool_free, conf);
        if (!conf->r10bio_pool) {
@@ -2063,8 +2075,6 @@ static int run(mddev_t *mddev)
 
                disk->head_position = 0;
        }
-       conf->raid_disks = mddev->raid_disks;
-       conf->mddev = mddev;
        spin_lock_init(&conf->device_lock);
        INIT_LIST_HEAD(&conf->retry_list);
 
@@ -2106,16 +2116,8 @@ static int run(mddev_t *mddev)
        /*
         * Ok, everything is just fine now
         */
-       if (conf->far_offset) {
-               size = mddev->size >> (conf->chunk_shift-1);
-               size *= conf->raid_disks;
-               size <<= conf->chunk_shift;
-               sector_div(size, conf->far_copies);
-       } else
-               size = conf->stride * conf->raid_disks;
-       sector_div(size, conf->near_copies);
-       mddev->array_size = size/2;
-       mddev->resync_max_sectors = size;
+       mddev->array_size = size << (conf->chunk_shift-1);
+       mddev->resync_max_sectors = size << conf->chunk_shift;
 
        mddev->queue->unplug_fn = raid10_unplug;
        mddev->queue->issue_flush_fn = raid10_issue_flush;
index 11c3d7bfa797e8777c5b2bdf47d9ec6f68c7da74..d247429ee5efe44b449b984f435a2ba3eafab927 100644 (file)
@@ -1050,7 +1050,7 @@ static void compute_parity5(struct stripe_head *sh, int method)
 static void compute_parity6(struct stripe_head *sh, int method)
 {
        raid6_conf_t *conf = sh->raid_conf;
-       int i, pd_idx = sh->pd_idx, qd_idx, d0_idx, disks = conf->raid_disks, count;
+       int i, pd_idx = sh->pd_idx, qd_idx, d0_idx, disks = sh->disks, count;
        struct bio *chosen;
        /**** FIX THIS: This could be very bad if disks is close to 256 ****/
        void *ptrs[disks];
@@ -1131,8 +1131,7 @@ static void compute_parity6(struct stripe_head *sh, int method)
 /* Compute one missing block */
 static void compute_block_1(struct stripe_head *sh, int dd_idx, int nozero)
 {
-       raid6_conf_t *conf = sh->raid_conf;
-       int i, count, disks = conf->raid_disks;
+       int i, count, disks = sh->disks;
        void *ptr[MAX_XOR_BLOCKS], *p;
        int pd_idx = sh->pd_idx;
        int qd_idx = raid6_next_disk(pd_idx, disks);
@@ -1170,8 +1169,7 @@ static void compute_block_1(struct stripe_head *sh, int dd_idx, int nozero)
 /* Compute two missing blocks */
 static void compute_block_2(struct stripe_head *sh, int dd_idx1, int dd_idx2)
 {
-       raid6_conf_t *conf = sh->raid_conf;
-       int i, count, disks = conf->raid_disks;
+       int i, count, disks = sh->disks;
        int pd_idx = sh->pd_idx;
        int qd_idx = raid6_next_disk(pd_idx, disks);
        int d0_idx = raid6_next_disk(qd_idx, disks);
@@ -1887,11 +1885,11 @@ static void handle_stripe5(struct stripe_head *sh)
 static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
 {
        raid6_conf_t *conf = sh->raid_conf;
-       int disks = conf->raid_disks;
+       int disks = sh->disks;
        struct bio *return_bi= NULL;
        struct bio *bi;
        int i;
-       int syncing;
+       int syncing, expanding, expanded;
        int locked=0, uptodate=0, to_read=0, to_write=0, failed=0, written=0;
        int non_overwrite = 0;
        int failed_num[2] = {0, 0};
@@ -1909,6 +1907,8 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
        clear_bit(STRIPE_DELAYED, &sh->state);
 
        syncing = test_bit(STRIPE_SYNCING, &sh->state);
+       expanding = test_bit(STRIPE_EXPAND_SOURCE, &sh->state);
+       expanded = test_bit(STRIPE_EXPAND_READY, &sh->state);
        /* Now to look around and see what can be done */
 
        rcu_read_lock();
@@ -2114,13 +2114,15 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
         * parity, or to satisfy requests
         * or to load a block that is being partially written.
         */
-       if (to_read || non_overwrite || (to_write && failed) || (syncing && (uptodate < disks))) {
+       if (to_read || non_overwrite || (to_write && failed) ||
+           (syncing && (uptodate < disks)) || expanding) {
                for (i=disks; i--;) {
                        dev = &sh->dev[i];
                        if (!test_bit(R5_LOCKED, &dev->flags) && !test_bit(R5_UPTODATE, &dev->flags) &&
                            (dev->toread ||
                             (dev->towrite && !test_bit(R5_OVERWRITE, &dev->flags)) ||
                             syncing ||
+                            expanding ||
                             (failed >= 1 && (sh->dev[failed_num[0]].toread || to_write)) ||
                             (failed >= 2 && (sh->dev[failed_num[1]].toread || to_write))
                                    )
@@ -2355,6 +2357,79 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
                                }
                        }
                }
+
+       if (expanded && test_bit(STRIPE_EXPANDING, &sh->state)) {
+               /* Need to write out all blocks after computing P&Q */
+               sh->disks = conf->raid_disks;
+               sh->pd_idx = stripe_to_pdidx(sh->sector, conf,
+                                            conf->raid_disks);
+               compute_parity6(sh, RECONSTRUCT_WRITE);
+               for (i = conf->raid_disks ; i-- ;  ) {
+                       set_bit(R5_LOCKED, &sh->dev[i].flags);
+                       locked++;
+                       set_bit(R5_Wantwrite, &sh->dev[i].flags);
+               }
+               clear_bit(STRIPE_EXPANDING, &sh->state);
+       } else if (expanded) {
+               clear_bit(STRIPE_EXPAND_READY, &sh->state);
+               atomic_dec(&conf->reshape_stripes);
+               wake_up(&conf->wait_for_overlap);
+               md_done_sync(conf->mddev, STRIPE_SECTORS, 1);
+       }
+
+       if (expanding && locked == 0) {
+               /* We have read all the blocks in this stripe and now we need to
+                * copy some of them into a target stripe for expand.
+                */
+               clear_bit(STRIPE_EXPAND_SOURCE, &sh->state);
+               for (i = 0; i < sh->disks ; i++)
+                       if (i != pd_idx && i != qd_idx) {
+                               int dd_idx2, pd_idx2, j;
+                               struct stripe_head *sh2;
+
+                               sector_t bn = compute_blocknr(sh, i);
+                               sector_t s = raid5_compute_sector(
+                                       bn, conf->raid_disks,
+                                       conf->raid_disks - conf->max_degraded,
+                                       &dd_idx2, &pd_idx2, conf);
+                               sh2 = get_active_stripe(conf, s,
+                                                       conf->raid_disks,
+                                                      pd_idx2, 1);
+                               if (sh2 == NULL)
+                                       /* so for only the early blocks of
+                                        * this stripe have been requests.
+                                        * When later blocks get requests, we
+                                        * will try again
+                                        */
+                                       continue;
+                               if (!test_bit(STRIPE_EXPANDING, &sh2->state) ||
+                                   test_bit(R5_Expanded,
+                                            &sh2->dev[dd_idx2].flags)) {
+                                       /* must have already done this block */
+                                       release_stripe(sh2);
+                                       continue;
+                               }
+                               memcpy(page_address(sh2->dev[dd_idx2].page),
+                                      page_address(sh->dev[i].page),
+                                      STRIPE_SIZE);
+                               set_bit(R5_Expanded, &sh2->dev[dd_idx2].flags);
+                               set_bit(R5_UPTODATE, &sh2->dev[dd_idx2].flags);
+                               for (j = 0 ; j < conf->raid_disks ; j++)
+                                       if (j != sh2->pd_idx &&
+                                           j != raid6_next_disk(sh2->pd_idx,
+                                                          sh2->disks) &&
+                                           !test_bit(R5_Expanded,
+                                                     &sh2->dev[j].flags))
+                                               break;
+                               if (j == conf->raid_disks) {
+                                       set_bit(STRIPE_EXPAND_READY,
+                                               &sh2->state);
+                                       set_bit(STRIPE_HANDLE, &sh2->state);
+                               }
+                               release_stripe(sh2);
+                       }
+       }
+
        spin_unlock(&sh->lock);
 
        while ((bi=return_bi)) {
@@ -2395,7 +2470,7 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
                rcu_read_unlock();
 
                if (rdev) {
-                       if (syncing)
+                       if (syncing || expanding || expanded)
                                md_sync_acct(rdev->bdev, STRIPE_SECTORS);
 
                        bi->bi_bdev = rdev->bdev;
@@ -2915,8 +2990,9 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
        struct stripe_head *sh;
        int pd_idx;
        sector_t first_sector, last_sector;
-       int raid_disks;
-       int data_disks;
+       int raid_disks = conf->previous_raid_disks;
+       int data_disks = raid_disks - conf->max_degraded;
+       int new_data_disks = conf->raid_disks - conf->max_degraded;
        int i;
        int dd_idx;
        sector_t writepos, safepos, gap;
@@ -2925,7 +3001,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
            conf->expand_progress != 0) {
                /* restarting in the middle, skip the initial sectors */
                sector_nr = conf->expand_progress;
-               sector_div(sector_nr, conf->raid_disks-1);
+               sector_div(sector_nr, new_data_disks);
                *skipped = 1;
                return sector_nr;
        }
@@ -2939,14 +3015,14 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
         * to after where expand_lo old_maps to
         */
        writepos = conf->expand_progress +
-               conf->chunk_size/512*(conf->raid_disks-1);
-       sector_div(writepos, conf->raid_disks-1);
+               conf->chunk_size/512*(new_data_disks);
+       sector_div(writepos, new_data_disks);
        safepos = conf->expand_lo;
-       sector_div(safepos, conf->previous_raid_disks-1);
+       sector_div(safepos, data_disks);
        gap = conf->expand_progress - conf->expand_lo;
 
        if (writepos >= safepos ||
-           gap > (conf->raid_disks-1)*3000*2 /*3Meg*/) {
+           gap > (new_data_disks)*3000*2 /*3Meg*/) {
                /* Cannot proceed until we've updated the superblock... */
                wait_event(conf->wait_for_overlap,
                           atomic_read(&conf->reshape_stripes)==0);
@@ -2976,6 +3052,9 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
                        sector_t s;
                        if (j == sh->pd_idx)
                                continue;
+                       if (conf->level == 6 &&
+                           j == raid6_next_disk(sh->pd_idx, sh->disks))
+                               continue;
                        s = compute_blocknr(sh, j);
                        if (s < (mddev->array_size<<1)) {
                                skipped = 1;
@@ -2999,21 +3078,20 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
         * The source stripes are determined by mapping the first and last
         * block on the destination stripes.
         */
-       raid_disks = conf->previous_raid_disks;
-       data_disks = raid_disks - 1;
        first_sector =
-               raid5_compute_sector(sector_nr*(conf->raid_disks-1),
+               raid5_compute_sector(sector_nr*(new_data_disks),
                                     raid_disks, data_disks,
                                     &dd_idx, &pd_idx, conf);
        last_sector =
                raid5_compute_sector((sector_nr+conf->chunk_size/512)
-                                    *(conf->raid_disks-1) -1,
+                                    *(new_data_disks) -1,
                                     raid_disks, data_disks,
                                     &dd_idx, &pd_idx, conf);
        if (last_sector >= (mddev->size<<1))
                last_sector = (mddev->size<<1)-1;
        while (first_sector <= last_sector) {
-               pd_idx = stripe_to_pdidx(first_sector, conf, conf->previous_raid_disks);
+               pd_idx = stripe_to_pdidx(first_sector, conf,
+                                        conf->previous_raid_disks);
                sh = get_active_stripe(conf, first_sector,
                                       conf->previous_raid_disks, pd_idx, 0);
                set_bit(STRIPE_EXPAND_SOURCE, &sh->state);
@@ -3348,35 +3426,44 @@ static int run(mddev_t *mddev)
                 */
                sector_t here_new, here_old;
                int old_disks;
+               int max_degraded = (mddev->level == 5 ? 1 : 2);
 
                if (mddev->new_level != mddev->level ||
                    mddev->new_layout != mddev->layout ||
                    mddev->new_chunk != mddev->chunk_size) {
-                       printk(KERN_ERR "raid5: %s: unsupported reshape required - aborting.\n",
+                       printk(KERN_ERR "raid5: %s: unsupported reshape "
+                              "required - aborting.\n",
                               mdname(mddev));
                        return -EINVAL;
                }
                if (mddev->delta_disks <= 0) {
-                       printk(KERN_ERR "raid5: %s: unsupported reshape (reduce disks) required - aborting.\n",
+                       printk(KERN_ERR "raid5: %s: unsupported reshape "
+                              "(reduce disks) required - aborting.\n",
                               mdname(mddev));
                        return -EINVAL;
                }
                old_disks = mddev->raid_disks - mddev->delta_disks;
                /* reshape_position must be on a new-stripe boundary, and one
-                * further up in new geometry must map after here in old geometry.
+                * further up in new geometry must map after here in old
+                * geometry.
                 */
                here_new = mddev->reshape_position;
-               if (sector_div(here_new, (mddev->chunk_size>>9)*(mddev->raid_disks-1))) {
-                       printk(KERN_ERR "raid5: reshape_position not on a stripe boundary\n");
+               if (sector_div(here_new, (mddev->chunk_size>>9)*
+                              (mddev->raid_disks - max_degraded))) {
+                       printk(KERN_ERR "raid5: reshape_position not "
+                              "on a stripe boundary\n");
                        return -EINVAL;
                }
                /* here_new is the stripe we will write to */
                here_old = mddev->reshape_position;
-               sector_div(here_old, (mddev->chunk_size>>9)*(old_disks-1));
-               /* here_old is the first stripe that we might need to read from */
+               sector_div(here_old, (mddev->chunk_size>>9)*
+                          (old_disks-max_degraded));
+               /* here_old is the first stripe that we might need to read
+                * from */
                if (here_new >= here_old) {
                        /* Reading from the same stripe as writing to - bad */
-                       printk(KERN_ERR "raid5: reshape_position too early for auto-recovery - aborting.\n");
+                       printk(KERN_ERR "raid5: reshape_position too early for "
+                              "auto-recovery - aborting.\n");
                        return -EINVAL;
                }
                printk(KERN_INFO "raid5: reshape will continue\n");
@@ -3814,6 +3901,8 @@ static int raid5_check_reshape(mddev_t *mddev)
        if (err)
                return err;
 
+       if (mddev->degraded > conf->max_degraded)
+               return -EINVAL;
        /* looks like we might be able to manage this */
        return 0;
 }
@@ -3827,8 +3916,7 @@ static int raid5_start_reshape(mddev_t *mddev)
        int added_devices = 0;
        unsigned long flags;
 
-       if (mddev->degraded ||
-           test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
+       if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
                return -EBUSY;
 
        ITERATE_RDEV(mddev, rdev, rtmp)
@@ -3836,7 +3924,7 @@ static int raid5_start_reshape(mddev_t *mddev)
                    !test_bit(Faulty, &rdev->flags))
                        spares++;
 
-       if (spares < mddev->delta_disks-1)
+       if (spares - mddev->degraded < mddev->delta_disks - conf->max_degraded)
                /* Not enough devices even to make a degraded array
                 * of that size
                 */
@@ -3899,7 +3987,8 @@ static void end_reshape(raid5_conf_t *conf)
        struct block_device *bdev;
 
        if (!test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) {
-               conf->mddev->array_size = conf->mddev->size * (conf->raid_disks-1);
+               conf->mddev->array_size = conf->mddev->size *
+                       (conf->raid_disks - conf->max_degraded);
                set_capacity(conf->mddev->gendisk, conf->mddev->array_size << 1);
                conf->mddev->changed = 1;
 
@@ -3972,6 +4061,10 @@ static struct mdk_personality raid6_personality =
        .spare_active   = raid5_spare_active,
        .sync_request   = sync_request,
        .resize         = raid5_resize,
+#ifdef CONFIG_MD_RAID5_RESHAPE
+       .check_reshape  = raid5_check_reshape,
+       .start_reshape  = raid5_start_reshape,
+#endif
        .quiesce        = raid5_quiesce,
 };
 static struct mdk_personality raid5_personality =
index 359157aaf9e0c2479dc58b12c99b7ebee2ece238..6181a5a3365a198d3aad83b52f6c7e09a4d5aad3 100644 (file)
@@ -30,14 +30,8 @@ const struct raid6_mmx_constants {
 
 static int raid6_have_mmx(void)
 {
-#ifdef __KERNEL__
        /* Not really "boot_cpu" but "all_cpus" */
        return boot_cpu_has(X86_FEATURE_MMX);
-#else
-       /* User space test code */
-       u32 features = cpuid_features();
-       return ( (features & (1<<23)) == (1<<23) );
-#endif
 }
 
 /*
@@ -48,13 +42,12 @@ static void raid6_mmx1_gen_syndrome(int disks, size_t bytes, void **ptrs)
        u8 **dptr = (u8 **)ptrs;
        u8 *p, *q;
        int d, z, z0;
-       raid6_mmx_save_t sa;
 
        z0 = disks - 3;         /* Highest data disk */
        p = dptr[z0+1];         /* XOR parity */
        q = dptr[z0+2];         /* RS syndrome */
 
-       raid6_before_mmx(&sa);
+       kernel_fpu_begin();
 
        asm volatile("movq %0,%%mm0" : : "m" (raid6_mmx_constants.x1d));
        asm volatile("pxor %mm5,%mm5"); /* Zero temp */
@@ -78,7 +71,7 @@ static void raid6_mmx1_gen_syndrome(int disks, size_t bytes, void **ptrs)
                asm volatile("pxor %mm4,%mm4");
        }
 
-       raid6_after_mmx(&sa);
+       kernel_fpu_end();
 }
 
 const struct raid6_calls raid6_mmxx1 = {
@@ -96,13 +89,12 @@ static void raid6_mmx2_gen_syndrome(int disks, size_t bytes, void **ptrs)
        u8 **dptr = (u8 **)ptrs;
        u8 *p, *q;
        int d, z, z0;
-       raid6_mmx_save_t sa;
 
        z0 = disks - 3;         /* Highest data disk */
        p = dptr[z0+1];         /* XOR parity */
        q = dptr[z0+2];         /* RS syndrome */
 
-       raid6_before_mmx(&sa);
+       kernel_fpu_begin();
 
        asm volatile("movq %0,%%mm0" : : "m" (raid6_mmx_constants.x1d));
        asm volatile("pxor %mm5,%mm5"); /* Zero temp */
@@ -137,7 +129,7 @@ static void raid6_mmx2_gen_syndrome(int disks, size_t bytes, void **ptrs)
                asm volatile("movq %%mm6,%0" : "=m" (q[d+8]));
        }
 
-       raid6_after_mmx(&sa);
+       kernel_fpu_end();
 }
 
 const struct raid6_calls raid6_mmxx2 = {
index f7e7859f71aa33acc7cd74a2b4fe91638ef438cd..f0a1ba8f40ba90c6b59fdc69073c4bb997b425b4 100644 (file)
@@ -33,16 +33,10 @@ extern const struct raid6_mmx_constants {
 
 static int raid6_have_sse1_or_mmxext(void)
 {
-#ifdef __KERNEL__
        /* Not really boot_cpu but "all_cpus" */
        return boot_cpu_has(X86_FEATURE_MMX) &&
                (boot_cpu_has(X86_FEATURE_XMM) ||
                 boot_cpu_has(X86_FEATURE_MMXEXT));
-#else
-       /* User space test code - this incorrectly breaks on some Athlons */
-       u32 features = cpuid_features();
-       return ( (features & (5<<23)) == (5<<23) );
-#endif
 }
 
 /*
@@ -53,14 +47,12 @@ static void raid6_sse11_gen_syndrome(int disks, size_t bytes, void **ptrs)
        u8 **dptr = (u8 **)ptrs;
        u8 *p, *q;
        int d, z, z0;
-       raid6_mmx_save_t sa;
 
        z0 = disks - 3;         /* Highest data disk */
        p = dptr[z0+1];         /* XOR parity */
        q = dptr[z0+2];         /* RS syndrome */
 
-       /* This is really MMX code, not SSE */
-       raid6_before_mmx(&sa);
+       kernel_fpu_begin();
 
        asm volatile("movq %0,%%mm0" : : "m" (raid6_mmx_constants.x1d));
        asm volatile("pxor %mm5,%mm5"); /* Zero temp */
@@ -94,8 +86,8 @@ static void raid6_sse11_gen_syndrome(int disks, size_t bytes, void **ptrs)
                asm volatile("movntq %%mm4,%0" : "=m" (q[d]));
        }
 
-       raid6_after_mmx(&sa);
        asm volatile("sfence" : : : "memory");
+       kernel_fpu_end();
 }
 
 const struct raid6_calls raid6_sse1x1 = {
@@ -113,13 +105,12 @@ static void raid6_sse12_gen_syndrome(int disks, size_t bytes, void **ptrs)
        u8 **dptr = (u8 **)ptrs;
        u8 *p, *q;
        int d, z, z0;
-       raid6_mmx_save_t sa;
 
        z0 = disks - 3;         /* Highest data disk */
        p = dptr[z0+1];         /* XOR parity */
        q = dptr[z0+2];         /* RS syndrome */
 
-       raid6_before_mmx(&sa);
+       kernel_fpu_begin();
 
        asm volatile("movq %0,%%mm0" : : "m" (raid6_mmx_constants.x1d));
        asm volatile("pxor %mm5,%mm5"); /* Zero temp */
@@ -157,8 +148,8 @@ static void raid6_sse12_gen_syndrome(int disks, size_t bytes, void **ptrs)
                asm volatile("movntq %%mm6,%0" : "=m" (q[d+8]));
        }
 
-       raid6_after_mmx(&sa);
        asm volatile("sfence" : :: "memory");
+       kernel_fpu_end();
 }
 
 const struct raid6_calls raid6_sse1x2 = {
index b3aa7fe0877e8d8a94a9923b0885e4aa9eeb9b11..0f019762a7c3cba42cba1ea68a99459465f17223 100644 (file)
@@ -30,17 +30,11 @@ static const struct raid6_sse_constants {
 
 static int raid6_have_sse2(void)
 {
-#ifdef __KERNEL__
        /* Not really boot_cpu but "all_cpus" */
        return boot_cpu_has(X86_FEATURE_MMX) &&
                boot_cpu_has(X86_FEATURE_FXSR) &&
                boot_cpu_has(X86_FEATURE_XMM) &&
                boot_cpu_has(X86_FEATURE_XMM2);
-#else
-       /* User space test code */
-       u32 features = cpuid_features();
-       return ( (features & (15<<23)) == (15<<23) );
-#endif
 }
 
 /*
@@ -51,13 +45,12 @@ static void raid6_sse21_gen_syndrome(int disks, size_t bytes, void **ptrs)
        u8 **dptr = (u8 **)ptrs;
        u8 *p, *q;
        int d, z, z0;
-       raid6_sse_save_t sa;
 
        z0 = disks - 3;         /* Highest data disk */
        p = dptr[z0+1];         /* XOR parity */
        q = dptr[z0+2];         /* RS syndrome */
 
-       raid6_before_sse2(&sa);
+       kernel_fpu_begin();
 
        asm volatile("movdqa %0,%%xmm0" : : "m" (raid6_sse_constants.x1d[0]));
        asm volatile("pxor %xmm5,%xmm5");       /* Zero temp */
@@ -93,8 +86,8 @@ static void raid6_sse21_gen_syndrome(int disks, size_t bytes, void **ptrs)
                asm volatile("pxor %xmm4,%xmm4");
        }
 
-       raid6_after_sse2(&sa);
        asm volatile("sfence" : : : "memory");
+       kernel_fpu_end();
 }
 
 const struct raid6_calls raid6_sse2x1 = {
@@ -112,13 +105,12 @@ static void raid6_sse22_gen_syndrome(int disks, size_t bytes, void **ptrs)
        u8 **dptr = (u8 **)ptrs;
        u8 *p, *q;
        int d, z, z0;
-       raid6_sse_save_t sa;
 
        z0 = disks - 3;         /* Highest data disk */
        p = dptr[z0+1];         /* XOR parity */
        q = dptr[z0+2];         /* RS syndrome */
 
-       raid6_before_sse2(&sa);
+       kernel_fpu_begin();
 
        asm volatile("movdqa %0,%%xmm0" : : "m" (raid6_sse_constants.x1d[0]));
        asm volatile("pxor %xmm5,%xmm5"); /* Zero temp */
@@ -156,8 +148,8 @@ static void raid6_sse22_gen_syndrome(int disks, size_t bytes, void **ptrs)
                asm volatile("movntdq %%xmm6,%0" : "=m" (q[d+16]));
        }
 
-       raid6_after_sse2(&sa);
        asm volatile("sfence" : : : "memory");
+       kernel_fpu_end();
 }
 
 const struct raid6_calls raid6_sse2x2 = {
@@ -179,13 +171,12 @@ static void raid6_sse24_gen_syndrome(int disks, size_t bytes, void **ptrs)
        u8 **dptr = (u8 **)ptrs;
        u8 *p, *q;
        int d, z, z0;
-       raid6_sse16_save_t sa;
 
        z0 = disks - 3;         /* Highest data disk */
        p = dptr[z0+1];         /* XOR parity */
        q = dptr[z0+2];         /* RS syndrome */
 
-       raid6_before_sse16(&sa);
+       kernel_fpu_begin();
 
        asm volatile("movdqa %0,%%xmm0" :: "m" (raid6_sse_constants.x1d[0]));
        asm volatile("pxor %xmm2,%xmm2");       /* P[0] */
@@ -256,8 +247,9 @@ static void raid6_sse24_gen_syndrome(int disks, size_t bytes, void **ptrs)
                asm volatile("movntdq %%xmm14,%0" : "=m" (q[d+48]));
                asm volatile("pxor %xmm14,%xmm14");
        }
+
        asm volatile("sfence" : : : "memory");
-       raid6_after_sse16(&sa);
+       kernel_fpu_end();
 }
 
 const struct raid6_calls raid6_sse2x4 = {
index 4cf20534fe442ea750b219f9f0de9c4520ff3f48..9111950414ff2d71c003591f2ad4c3503303de5c 100644 (file)
 
 #if defined(__i386__) || defined(__x86_64__)
 
-#ifdef __x86_64__
-
-typedef struct {
-       unsigned int fsave[27];
-       unsigned long cr0;
-} raid6_mmx_save_t __attribute__((aligned(16)));
-
-/* N.B.: For SSE we only save %xmm0-%xmm7 even for x86-64, since
-   the code doesn't know about the additional x86-64 registers */
-typedef struct {
-       unsigned int sarea[8*4+2];
-       unsigned long cr0;
-} raid6_sse_save_t __attribute__((aligned(16)));
-
-/* This is for x86-64-specific code which uses all 16 XMM registers */
-typedef struct {
-       unsigned int sarea[16*4+2];
-       unsigned long cr0;
-} raid6_sse16_save_t __attribute__((aligned(16)));
-
-/* On x86-64 the stack *SHOULD* be 16-byte aligned, but currently this
-   is buggy in the kernel and it's only 8-byte aligned in places, so
-   we need to do this anyway.  Sigh. */
-#define SAREA(x) ((unsigned int *)((((unsigned long)&(x)->sarea)+15) & ~15))
-
-#else /* __i386__ */
-
-typedef struct {
-       unsigned int fsave[27];
-       unsigned long cr0;
-} raid6_mmx_save_t;
-
-/* On i386, the stack is only 8-byte aligned, but SSE requires 16-byte
-   alignment.  The +3 is so we have the slack space to manually align
-   a properly-sized area correctly.  */
-typedef struct {
-       unsigned int sarea[8*4+3];
-       unsigned long cr0;
-} raid6_sse_save_t;
-
-/* Find the 16-byte aligned save area */
-#define SAREA(x) ((unsigned int *)((((unsigned long)&(x)->sarea)+15) & ~15))
-
-#endif
-
 #ifdef __KERNEL__ /* Real code */
 
-/* Note: %cr0 is 32 bits on i386 and 64 bits on x86-64 */
-
-static inline unsigned long raid6_get_fpu(void)
-{
-       unsigned long cr0;
-
-       preempt_disable();
-       asm volatile("mov %%cr0,%0 ; clts" : "=r" (cr0));
-       return cr0;
-}
-
-static inline void raid6_put_fpu(unsigned long cr0)
-{
-       asm volatile("mov %0,%%cr0" : : "r" (cr0));
-       preempt_enable();
-}
+#include <asm/i387.h>
 
 #else /* Dummy code for user space testing */
 
-static inline unsigned long raid6_get_fpu(void)
-{
-       return 0xf00ba6;
-}
-
-static inline void raid6_put_fpu(unsigned long cr0)
-{
-       (void)cr0;
-}
-
-#endif
-
-static inline void raid6_before_mmx(raid6_mmx_save_t *s)
-{
-       s->cr0 = raid6_get_fpu();
-       asm volatile("fsave %0 ; fwait" : "=m" (s->fsave[0]));
-}
-
-static inline void raid6_after_mmx(raid6_mmx_save_t *s)
-{
-       asm volatile("frstor %0" : : "m" (s->fsave[0]));
-       raid6_put_fpu(s->cr0);
-}
-
-static inline void raid6_before_sse(raid6_sse_save_t *s)
-{
-       unsigned int *rsa = SAREA(s);
-
-       s->cr0 = raid6_get_fpu();
-
-       asm volatile("movaps %%xmm0,%0" : "=m" (rsa[0]));
-       asm volatile("movaps %%xmm1,%0" : "=m" (rsa[4]));
-       asm volatile("movaps %%xmm2,%0" : "=m" (rsa[8]));
-       asm volatile("movaps %%xmm3,%0" : "=m" (rsa[12]));
-       asm volatile("movaps %%xmm4,%0" : "=m" (rsa[16]));
-       asm volatile("movaps %%xmm5,%0" : "=m" (rsa[20]));
-       asm volatile("movaps %%xmm6,%0" : "=m" (rsa[24]));
-       asm volatile("movaps %%xmm7,%0" : "=m" (rsa[28]));
-}
-
-static inline void raid6_after_sse(raid6_sse_save_t *s)
-{
-       unsigned int *rsa = SAREA(s);
-
-       asm volatile("movaps %0,%%xmm0" : : "m" (rsa[0]));
-       asm volatile("movaps %0,%%xmm1" : : "m" (rsa[4]));
-       asm volatile("movaps %0,%%xmm2" : : "m" (rsa[8]));
-       asm volatile("movaps %0,%%xmm3" : : "m" (rsa[12]));
-       asm volatile("movaps %0,%%xmm4" : : "m" (rsa[16]));
-       asm volatile("movaps %0,%%xmm5" : : "m" (rsa[20]));
-       asm volatile("movaps %0,%%xmm6" : : "m" (rsa[24]));
-       asm volatile("movaps %0,%%xmm7" : : "m" (rsa[28]));
-
-       raid6_put_fpu(s->cr0);
-}
-
-static inline void raid6_before_sse2(raid6_sse_save_t *s)
+static inline void kernel_fpu_begin(void)
 {
-       unsigned int *rsa = SAREA(s);
-
-       s->cr0 = raid6_get_fpu();
-
-       asm volatile("movdqa %%xmm0,%0" : "=m" (rsa[0]));
-       asm volatile("movdqa %%xmm1,%0" : "=m" (rsa[4]));
-       asm volatile("movdqa %%xmm2,%0" : "=m" (rsa[8]));
-       asm volatile("movdqa %%xmm3,%0" : "=m" (rsa[12]));
-       asm volatile("movdqa %%xmm4,%0" : "=m" (rsa[16]));
-       asm volatile("movdqa %%xmm5,%0" : "=m" (rsa[20]));
-       asm volatile("movdqa %%xmm6,%0" : "=m" (rsa[24]));
-       asm volatile("movdqa %%xmm7,%0" : "=m" (rsa[28]));
 }
 
-static inline void raid6_after_sse2(raid6_sse_save_t *s)
+static inline void kernel_fpu_end(void)
 {
-       unsigned int *rsa = SAREA(s);
-
-       asm volatile("movdqa %0,%%xmm0" : : "m" (rsa[0]));
-       asm volatile("movdqa %0,%%xmm1" : : "m" (rsa[4]));
-       asm volatile("movdqa %0,%%xmm2" : : "m" (rsa[8]));
-       asm volatile("movdqa %0,%%xmm3" : : "m" (rsa[12]));
-       asm volatile("movdqa %0,%%xmm4" : : "m" (rsa[16]));
-       asm volatile("movdqa %0,%%xmm5" : : "m" (rsa[20]));
-       asm volatile("movdqa %0,%%xmm6" : : "m" (rsa[24]));
-       asm volatile("movdqa %0,%%xmm7" : : "m" (rsa[28]));
-
-       raid6_put_fpu(s->cr0);
 }
 
-#ifdef __x86_64__
-
-static inline void raid6_before_sse16(raid6_sse16_save_t *s)
-{
-       unsigned int *rsa = SAREA(s);
-
-       s->cr0 = raid6_get_fpu();
+#define X86_FEATURE_MMX                (0*32+23) /* Multimedia Extensions */
+#define X86_FEATURE_FXSR       (0*32+24) /* FXSAVE and FXRSTOR instructions
+                                          * (fast save and restore) */
+#define X86_FEATURE_XMM                (0*32+25) /* Streaming SIMD Extensions */
+#define X86_FEATURE_XMM2       (0*32+26) /* Streaming SIMD Extensions-2 */
+#define X86_FEATURE_MMXEXT     (1*32+22) /* AMD MMX extensions */
 
-       asm volatile("movdqa %%xmm0,%0" : "=m" (rsa[0]));
-       asm volatile("movdqa %%xmm1,%0" : "=m" (rsa[4]));
-       asm volatile("movdqa %%xmm2,%0" : "=m" (rsa[8]));
-       asm volatile("movdqa %%xmm3,%0" : "=m" (rsa[12]));
-       asm volatile("movdqa %%xmm4,%0" : "=m" (rsa[16]));
-       asm volatile("movdqa %%xmm5,%0" : "=m" (rsa[20]));
-       asm volatile("movdqa %%xmm6,%0" : "=m" (rsa[24]));
-       asm volatile("movdqa %%xmm7,%0" : "=m" (rsa[28]));
-       asm volatile("movdqa %%xmm8,%0" : "=m" (rsa[32]));
-       asm volatile("movdqa %%xmm9,%0" : "=m" (rsa[36]));
-       asm volatile("movdqa %%xmm10,%0" : "=m" (rsa[40]));
-       asm volatile("movdqa %%xmm11,%0" : "=m" (rsa[44]));
-       asm volatile("movdqa %%xmm12,%0" : "=m" (rsa[48]));
-       asm volatile("movdqa %%xmm13,%0" : "=m" (rsa[52]));
-       asm volatile("movdqa %%xmm14,%0" : "=m" (rsa[56]));
-       asm volatile("movdqa %%xmm15,%0" : "=m" (rsa[60]));
-}
-
-static inline void raid6_after_sse16(raid6_sse16_save_t *s)
+/* Should work well enough on modern CPUs for testing */
+static inline int boot_cpu_has(int flag)
 {
-       unsigned int *rsa = SAREA(s);
+       u32 eax = (flag >> 5) ? 0x80000001 : 1;
+       u32 edx;
 
-       asm volatile("movdqa %0,%%xmm0" : : "m" (rsa[0]));
-       asm volatile("movdqa %0,%%xmm1" : : "m" (rsa[4]));
-       asm volatile("movdqa %0,%%xmm2" : : "m" (rsa[8]));
-       asm volatile("movdqa %0,%%xmm3" : : "m" (rsa[12]));
-       asm volatile("movdqa %0,%%xmm4" : : "m" (rsa[16]));
-       asm volatile("movdqa %0,%%xmm5" : : "m" (rsa[20]));
-       asm volatile("movdqa %0,%%xmm6" : : "m" (rsa[24]));
-       asm volatile("movdqa %0,%%xmm7" : : "m" (rsa[28]));
-       asm volatile("movdqa %0,%%xmm8" : : "m" (rsa[32]));
-       asm volatile("movdqa %0,%%xmm9" : : "m" (rsa[36]));
-       asm volatile("movdqa %0,%%xmm10" : : "m" (rsa[40]));
-       asm volatile("movdqa %0,%%xmm11" : : "m" (rsa[44]));
-       asm volatile("movdqa %0,%%xmm12" : : "m" (rsa[48]));
-       asm volatile("movdqa %0,%%xmm13" : : "m" (rsa[52]));
-       asm volatile("movdqa %0,%%xmm14" : : "m" (rsa[56]));
-       asm volatile("movdqa %0,%%xmm15" : : "m" (rsa[60]));
+       asm volatile("cpuid"
+                    : "+a" (eax), "=d" (edx)
+                    : : "ecx", "ebx");
 
-       raid6_put_fpu(s->cr0);
+       return (edx >> (flag & 31)) & 1;
 }
 
-#endif /* __x86_64__ */
-
-/* User space test hack */
-#ifndef __KERNEL__
-static inline int cpuid_features(void)
-{
-       u32 eax = 1;
-       u32 ebx, ecx, edx;
-
-       asm volatile("cpuid" :
-                    "+a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx));
-
-       return edx;
-}
 #endif /* ndef __KERNEL__ */
 
 #endif
index 15d12fce34df871e8ffaed1b4c39b7566fa97d82..127a94b9a1b537c9b0a810eaf0ad92d19f8d71db 100644 (file)
@@ -469,9 +469,9 @@ static int bluebird_patch_dvico_firmware_download(struct usb_device *udev,
            fw->data[BLUEBIRD_01_ID_OFFSET + 1] == USB_VID_DVICO >> 8) {
 
                fw->data[BLUEBIRD_01_ID_OFFSET + 2] =
-                       udev->descriptor.idProduct + 1;
+                       le16_to_cpu(udev->descriptor.idProduct) + 1;
                fw->data[BLUEBIRD_01_ID_OFFSET + 3] =
-                       udev->descriptor.idProduct >> 8;
+                       le16_to_cpu(udev->descriptor.idProduct) >> 8;
 
                return usb_cypress_load_firmware(udev, fw, CYPRESS_FX2);
        }
index 4a198d4755b0699f818d08c83ba73e9093b41037..b5acb11c0bc95bf0bcacedc1c4db84366553e8b1 100644 (file)
@@ -119,6 +119,8 @@ static int digitv_nxt6000_tuner_set_params(struct dvb_frontend *fe, struct dvb_f
        struct dvb_usb_adapter *adap = fe->dvb->priv;
        u8 b[5];
        dvb_usb_tuner_calc_regs(fe,fep,b, 5);
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
        return digitv_ctrl_msg(adap->dev, USB_WRITE_TUNER, 0, &b[1], 4, NULL, 0);
 }
 
index 682dc7ce48d91de1b37ef1655bdc5ed926579ad9..710c11a682964b88f525a0517b9f3a2032f5ad70 100644 (file)
@@ -1022,7 +1022,7 @@ static ssize_t cafe_v4l_read(struct file *filp,
                char __user *buffer, size_t len, loff_t *pos)
 {
        struct cafe_camera *cam = filp->private_data;
-       int ret;
+       int ret = 0;
 
        /*
         * Perhaps we're in speculative read mode and already
@@ -1251,8 +1251,6 @@ static int cafe_vidioc_reqbufs(struct file *filp, void *priv,
 
        if (cam->n_sbufs == 0)  /* no luck at all - ret already set */
                kfree(cam->sb_bufs);
-       else
-               ret = 0;
        req->count = cam->n_sbufs;  /* In case of partial success */
 
   out:
index cc535ca713d20cadf2082f79778c67f6b0c82e01..774d2536555b8d6dbe7001c1c6f8b7b6928e4020 100644 (file)
@@ -633,7 +633,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
        {
                struct v4l2_register *reg = arg;
 
-               if (reg->i2c_id != I2C_DRIVERID_CX25840)
+               if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip))
                        return -EINVAL;
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
@@ -903,13 +903,13 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
        state->vbi_line_offset = 8;
        state->id = id;
 
+       i2c_attach_client(client);
+
        if (state->is_cx25836)
                cx25836_initialize(client);
        else
                cx25840_initialize(client, 1);
 
-       i2c_attach_client(client);
-
        return 0;
 }
 
index 1958d4016ea15c4bb5b9e7faa59377fe80d9a4f6..0e86b9d033ac8b6cb2bb302152d4e6ac3f0203ea 100644 (file)
@@ -37,7 +37,7 @@
  */
 #define FWSEND 48
 
-#define FWDEV(x) &((x)->adapter->dev)
+#define FWDEV(x) &((x)->dev)
 
 static char *firmware = FWFILE;
 
index a97be1bdc31d97d7acfd812eb2ef7db883a24ad5..bdfe2af70124c8ecac34a22bd4e184227c204ec1 100644 (file)
@@ -1389,7 +1389,7 @@ static int vidioc_g_register (struct file *file, void *fh,
 {
        struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core;
 
-       if (reg->i2c_id != 0)
+       if (!v4l2_chip_match_host(reg->match_type, reg->match_chip))
                return -EINVAL;
        /* cx2388x has a 24-bit register space */
        reg->val = cx_read(reg->reg&0xffffff);
@@ -1401,7 +1401,7 @@ static int vidioc_s_register (struct file *file, void *fh,
 {
        struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core;
 
-       if (reg->i2c_id != 0)
+       if (!v4l2_chip_match_host(reg->match_type, reg->match_chip))
                return -EINVAL;
        cx_write(reg->reg&0xffffff, reg->val);
        return 0;
index a1ca0f5007e075736b6ba6fd6ad29541618c2e3c..1cd4bb3ae260d19248fb2f8a700bf0d51d38b3e0 100644 (file)
@@ -3256,8 +3256,8 @@ static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
 
 
 int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
-                            u32 chip_id, u64 reg_id,
-                            int setFl,u32 *val_ptr)
+                            u32 match_type, u32 match_chip, u64 reg_id,
+                            int setFl,u64 *val_ptr)
 {
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        struct list_head *item;
@@ -3268,13 +3268,16 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
 
        if (!capable(CAP_SYS_ADMIN)) return -EPERM;
 
-       req.i2c_id = chip_id;
+       req.match_type = match_type;
+       req.match_chip = match_chip;
        req.reg = reg_id;
        if (setFl) req.val = *val_ptr;
        mutex_lock(&hdw->i2c_list_lock); do {
                list_for_each(item,&hdw->i2c_clients) {
                        cp = list_entry(item,struct pvr2_i2c_client,list);
-                       if (cp->client->driver->id != chip_id) continue;
+                       if (!v4l2_chip_match_i2c_client(cp->client, req.match_type, req.match_chip)) {
+                               continue;
+                       }
                        stat = pvr2_i2c_client_cmd(
                                cp,(setFl ? VIDIOC_DBG_S_REGISTER :
                                    VIDIOC_DBG_G_REGISTER),&req);
index 566a8ef7e1216abbdf9b33ad8041a8c0dccd70dc..0c9cca43ff854042fc97a94c9006d60ccdd83d06 100644 (file)
@@ -217,13 +217,14 @@ void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *,
                                     enum pvr2_v4l_type index,int);
 
 /* Direct read/write access to chip's registers:
-   chip_id - unique id of chip (e.g. I2C_DRIVERD_xxxx)
+   match_type - how to interpret match_chip (e.g. driver ID, i2c address)
+   match_chip - chip match value (e.g. I2C_DRIVERD_xxxx)
    reg_id  - register number to access
    setFl   - true to set the register, false to read it
    val_ptr - storage location for source / result. */
 int pvr2_hdw_register_access(struct pvr2_hdw *,
-                            u32 chip_id,u64 reg_id,
-                            int setFl,u32 *val_ptr);
+                            u32 match_type, u32 match_chip,u64 reg_id,
+                            int setFl,u64 *val_ptr);
 
 /* The following entry points are all lower level things you normally don't
    want to worry about. */
index 4fe4136204c7bc443776fec9ebe69c976a2a1523..5313d342666e4e4a0b2507d20df67d83ec42a375 100644 (file)
@@ -740,11 +740,11 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
        case VIDIOC_DBG_S_REGISTER:
        case VIDIOC_DBG_G_REGISTER:
        {
-               u32 val;
+               u64 val;
                struct v4l2_register *req = (struct v4l2_register *)arg;
                if (cmd == VIDIOC_DBG_S_REGISTER) val = req->val;
                ret = pvr2_hdw_register_access(
-                       hdw,req->i2c_id,req->reg,
+                       hdw,req->match_type,req->match_chip,req->reg,
                        cmd == VIDIOC_DBG_S_REGISTER,&val);
                if (cmd == VIDIOC_DBG_G_REGISTER) req->val = val;
                break;
index c4f066d6668ef093bd5743f3e3982f2ee339d03b..7735b6758921f6cda72663474b71be3b767fb517 100644 (file)
@@ -1425,7 +1425,7 @@ static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *ar
        {
                struct v4l2_register *reg = arg;
 
-               if (reg->i2c_id != I2C_DRIVERID_SAA711X)
+               if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip))
                        return -EINVAL;
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
index bd9c4f3ad02ee34a3a25ed19da3d7de00eef6380..654863db15919b4e5a9c7d891195d75b3afaa4fa 100644 (file)
@@ -619,7 +619,7 @@ static int saa7127_command(struct i2c_client *client,
        {
                struct v4l2_register *reg = arg;
 
-               if (reg->i2c_id != I2C_DRIVERID_SAA7127)
+               if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip))
                        return -EINVAL;
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
index 886b5df7c9d146610d4410057e49eb0e37282965..d5ec05f56adfad470a6edca177746a134113290a 100644 (file)
@@ -955,7 +955,7 @@ static int tvp5150_command(struct i2c_client *c,
        {
                struct v4l2_register *reg = arg;
 
-               if (reg->i2c_id != I2C_DRIVERID_TVP5150)
+               if (!v4l2_chip_match_i2c_client(c, reg->match_type, reg->match_chip))
                        return -EINVAL;
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
index b3b5fd536dc3c89b884d5e5480c04b2752347d5a..28d1133a3b7a6f770b427991a9e2441a59224dab 100644 (file)
@@ -167,7 +167,7 @@ static int upd64031a_command(struct i2c_client *client, unsigned int cmd, void *
        {
                struct v4l2_register *reg = arg;
 
-               if (reg->i2c_id != I2C_DRIVERID_UPD64031A)
+               if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip))
                        return -EINVAL;
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
index 8852903e7a92dba432d4af40fc2d8ab517e5b166..fe38224150d8ae0abd116953ec09c6f92721ee23 100644 (file)
@@ -144,7 +144,7 @@ static int upd64083_command(struct i2c_client *client, unsigned int cmd, void *a
        {
                struct v4l2_register *reg = arg;
 
-               if (reg->i2c_id != I2C_DRIVERID_UPD64083)
+               if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip))
                        return -EINVAL;
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
index ae5f42562c0c410fff2ed53b120efa1f618d484d..6fc14557d623779aa3a21e93c3eeb56d422e81cf 100644 (file)
@@ -521,7 +521,7 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file,
                        struct v4l2_register *reg = arg;
                        int errCode;
 
-                       if (reg->i2c_id != 0)
+                       if (!v4l2_chip_match_host(reg->match_type, reg->match_chip))
                                return -EINVAL;
                        if (!capable(CAP_SYS_ADMIN))
                                return -EPERM;
@@ -540,7 +540,7 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file,
 
                        PDEBUG(DBG_IOCTL, "VIDIOC_DBG_%c_REGISTER reg=0x%02X, value=0x%02X",
                               cmd == VIDIOC_DBG_G_REGISTER ? 'G' : 'S',
-                              (unsigned int)reg->reg, reg->val);
+                              (unsigned int)reg->reg, (unsigned int)reg->val);
                        return 0;
                }
 #endif
index ddfd80c5618bcb6b74665e78c73a3996b0a6e3dd..54747606eae11e4d984ac3293017f539360902f2 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/errno.h>
+#include <linux/i2c.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -365,13 +366,21 @@ static const char *v4l2_ioctls[] = {
        [_IOC_NR(VIDIOC_ENUMAUDOUT)]       = "VIDIOC_ENUMAUDOUT",
        [_IOC_NR(VIDIOC_G_PRIORITY)]       = "VIDIOC_G_PRIORITY",
        [_IOC_NR(VIDIOC_S_PRIORITY)]       = "VIDIOC_S_PRIORITY",
-#if 1
        [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
-#endif
        [_IOC_NR(VIDIOC_LOG_STATUS)]       = "VIDIOC_LOG_STATUS",
        [_IOC_NR(VIDIOC_G_EXT_CTRLS)]      = "VIDIOC_G_EXT_CTRLS",
        [_IOC_NR(VIDIOC_S_EXT_CTRLS)]      = "VIDIOC_S_EXT_CTRLS",
-       [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)]    = "VIDIOC_TRY_EXT_CTRLS"
+       [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)]    = "VIDIOC_TRY_EXT_CTRLS",
+#if 1
+       [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)]  = "VIDIOC_ENUM_FRAMESIZES",
+       [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS",
+       [_IOC_NR(VIDIOC_G_ENC_INDEX)]      = "VIDIOC_G_ENC_INDEX",
+       [_IOC_NR(VIDIOC_ENCODER_CMD)]      = "VIDIOC_ENCODER_CMD",
+       [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)]  = "VIDIOC_TRY_ENCODER_CMD",
+
+       [_IOC_NR(VIDIOC_DBG_S_REGISTER)]   = "VIDIOC_DBG_S_REGISTER",
+       [_IOC_NR(VIDIOC_DBG_G_REGISTER)]   = "VIDIOC_DBG_G_REGISTER",
+#endif
 };
 #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
 
@@ -395,9 +404,6 @@ static const char *v4l2_int_ioctls[] = {
        [_IOC_NR(TUNER_SET_STANDBY)]           = "TUNER_SET_STANDBY",
        [_IOC_NR(TDA9887_SET_CONFIG)]          = "TDA9887_SET_CONFIG",
 
-       [_IOC_NR(VIDIOC_DBG_S_REGISTER)]       = "VIDIOC_DBG_S_REGISTER",
-       [_IOC_NR(VIDIOC_DBG_G_REGISTER)]       = "VIDIOC_DBG_G_REGISTER",
-
        [_IOC_NR(VIDIOC_INT_S_TUNER_MODE)]     = "VIDIOC_INT_S_TUNER_MODE",
        [_IOC_NR(VIDIOC_INT_RESET)]            = "VIDIOC_INT_RESET",
        [_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ",
@@ -947,6 +953,28 @@ u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id)
        return **ctrl_classes;
 }
 
+int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_chip)
+{
+       switch (match_type) {
+       case V4L2_CHIP_MATCH_I2C_DRIVER:
+               return (c != NULL && c->driver != NULL && c->driver->id == match_chip);
+       case V4L2_CHIP_MATCH_I2C_ADDR:
+               return (c != NULL && c->addr == match_chip);
+       default:
+               return 0;
+       }
+}
+
+int v4l2_chip_match_host(u32 match_type, u32 match_chip)
+{
+       switch (match_type) {
+       case V4L2_CHIP_MATCH_HOST:
+               return match_chip == 0;
+       default:
+               return 0;
+       }
+}
+
 /* ----------------------------------------------------------------- */
 
 EXPORT_SYMBOL(v4l2_norm_to_name);
@@ -970,6 +998,9 @@ EXPORT_SYMBOL(v4l2_ctrl_query_menu);
 EXPORT_SYMBOL(v4l2_ctrl_query_fill);
 EXPORT_SYMBOL(v4l2_ctrl_query_fill_std);
 
+EXPORT_SYMBOL(v4l2_chip_match_i2c_client);
+EXPORT_SYMBOL(v4l2_chip_match_host);
+
 /*
  * Local variables:
  * c-basic-offset: 8
index dc9b1ef678aa01a79b34736596b60d44a8e055f3..011938fb7e0e6a2c48257bd4e7adc080c23c62d3 100644 (file)
@@ -1342,6 +1342,42 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
                        ret=vfd->vidioc_s_jpegcomp(file, fh, p);
                break;
        }
+       case VIDIOC_G_ENC_INDEX:
+       {
+               struct v4l2_enc_idx *p=arg;
+
+               if (!vfd->vidioc_g_enc_index)
+                       break;
+               ret=vfd->vidioc_g_enc_index(file, fh, p);
+               if (!ret)
+                       dbgarg (cmd, "entries=%d, entries_cap=%d\n",
+                                       p->entries,p->entries_cap);
+               break;
+       }
+       case VIDIOC_ENCODER_CMD:
+       {
+               struct v4l2_encoder_cmd *p=arg;
+
+               if (!vfd->vidioc_encoder_cmd)
+                       break;
+               ret=vfd->vidioc_encoder_cmd(file, fh, p);
+               if (!ret)
+                       dbgarg (cmd, "cmd=%d, flags=%d\n",
+                                       p->cmd,p->flags);
+               break;
+       }
+       case VIDIOC_TRY_ENCODER_CMD:
+       {
+               struct v4l2_encoder_cmd *p=arg;
+
+               if (!vfd->vidioc_try_encoder_cmd)
+                       break;
+               ret=vfd->vidioc_try_encoder_cmd(file, fh, p);
+               if (!ret)
+                       dbgarg (cmd, "cmd=%d, flags=%d\n",
+                                       p->cmd,p->flags);
+               break;
+       }
        case VIDIOC_G_PARM:
        {
                struct v4l2_streamparm *p=arg;
index 7a0d8ee2de9c9aa95f973b86dec3d5955d348798..04aaa634723467ac90cbd8bd4d41419bdfc89647 100644 (file)
@@ -113,10 +113,16 @@ EXPORT_SYMBOL_GPL(rtc_device_register);
  */
 void rtc_device_unregister(struct rtc_device *rtc)
 {
-       mutex_lock(&rtc->ops_lock);
-       rtc->ops = NULL;
-       mutex_unlock(&rtc->ops_lock);
-       class_device_unregister(&rtc->class_dev);
+       if (class_device_get(&rtc->class_dev) != NULL) {
+               mutex_lock(&rtc->ops_lock);
+               /* remove innards of this RTC, then disable it, before
+                * letting any rtc_class_open() users access it again
+                */
+               class_device_unregister(&rtc->class_dev);
+               rtc->ops = NULL;
+               mutex_unlock(&rtc->ops_lock);
+               class_device_put(&rtc->class_dev);
+       }
 }
 EXPORT_SYMBOL_GPL(rtc_device_unregister);
 
index 6f11f6dfdd9dccc699b5a1a958132d55dec5daa6..ef40df0f169d2a1039ddca745f586dd122731afa 100644 (file)
@@ -179,7 +179,7 @@ struct class_device *rtc_class_open(char *name)
        down(&rtc_class->sem);
        list_for_each_entry(class_dev_tmp, &rtc_class->children, node) {
                if (strncmp(class_dev_tmp->class_id, name, BUS_ID_SIZE) == 0) {
-                       class_dev = class_dev_tmp;
+                       class_dev = class_device_get(class_dev_tmp);
                        break;
                }
        }
@@ -197,6 +197,7 @@ EXPORT_SYMBOL_GPL(rtc_class_open);
 void rtc_class_close(struct class_device *class_dev)
 {
        module_put(to_rtc_device(class_dev)->owner);
+       class_device_put(class_dev);
 }
 EXPORT_SYMBOL_GPL(rtc_class_close);
 
index c1536d78555178b71d54150079eb5818b4e4ec5f..b8f0a11e8f3174c83b02d69229d2d516c251ce4d 100644 (file)
@@ -1618,8 +1618,7 @@ config FB_IBM_GXT4500
 
 config FB_PS3
        bool "PS3 GPU framebuffer driver"
-       depends on FB && PPC_PS3
-       select PS3_PS3AV
+       depends on FB && PS3_PS3AV
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
index 02b290ca01e125700116eb804e4c44138f9a7a3e..58c0ac733db9871ddad0cc6905f171fab6ee3d36 100644 (file)
@@ -136,8 +136,8 @@ static inline void sm501fb_sync_regs(struct sm501fb_info *info)
 #define SM501_MEMF_CRT                 (4)
 #define SM501_MEMF_ACCEL               (8)
 
-int sm501_alloc_mem(struct sm501fb_info *inf, struct sm501_mem *mem,
-                   unsigned int why, size_t size)
+static int sm501_alloc_mem(struct sm501fb_info *inf, struct sm501_mem *mem,
+                          unsigned int why, size_t size)
 {
        unsigned int ptr = 0;
 
@@ -926,7 +926,7 @@ static int sm501fb_blank_crt(int blank_mode, struct fb_info *info)
  * set or change the hardware cursor parameters
 */
 
-int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
        struct sm501fb_par  *par = info->par;
        struct sm501fb_info *fbi = par->info;
@@ -1225,7 +1225,7 @@ static struct sm501fb_info *sm501fb_info_alloc(struct fb_info *fbinfo_crt,
  * initialise hw cursor parameters
 */
 
-int sm501_init_cursor(struct fb_info *fbi, unsigned int reg_base)
+static int sm501_init_cursor(struct fb_info *fbi, unsigned int reg_base)
 {
        struct sm501fb_par *par = fbi->par;
        struct sm501fb_info *info = par->info;
@@ -1768,7 +1768,7 @@ static struct platform_driver sm501fb_driver = {
        },
 };
 
-int __devinit sm501fb_init(void)
+static int __devinit sm501fb_init(void)
 {
        return platform_driver_register(&sm501fb_driver);
 }
index bd969adf70d72bd8cc5335e3f8a47e06c220be52..7a7d25d541e727cb4515acb771c3e077773c5a20 100644 (file)
@@ -205,6 +205,7 @@ int ecryptfs_open_lower_file(struct file **lower_file,
 {
        int rc = 0;
 
+       flags |= O_LARGEFILE;
        dget(lower_dentry);
        mntget(lower_mnt);
        *lower_file = dentry_open(lower_dentry, lower_mnt, flags);
index 9fa7e0b27a96ee57ae08187e17b6872b79d39fd4..0cfff4fefa9ea0b235f14d627b8c9010bceaf8c3 100644 (file)
@@ -200,9 +200,6 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
        inode = ecryptfs_dentry->d_inode;
        crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
        lower_flags = ((O_CREAT | O_TRUNC) & O_ACCMODE) | O_RDWR;
-#if BITS_PER_LONG != 32
-       lower_flags |= O_LARGEFILE;
-#endif
        lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
        /* Corresponding fput() at end of this function */
        if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt,
index 80044d196fe06b7b82ae3c6dc0cacaddc3e1a2f6..812427e6805c99212b3e02cc098a73bd6149961e 100644 (file)
@@ -487,7 +487,7 @@ static int ecryptfs_read_super(struct super_block *sb, const char *dev_name)
        rc = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
        if (rc) {
                ecryptfs_printk(KERN_WARNING, "path_lookup() failed\n");
-               goto out_free;
+               goto out;
        }
        lower_root = nd.dentry;
        if (!lower_root->d_inode) {
index 3a6f65c3f14fc2fb26aa77df1ba8f10cae7198b7..7be8e91b5ba08cd93c70ffe30a074ad6e4a93fc4 100644 (file)
@@ -238,7 +238,6 @@ int ecryptfs_do_readpage(struct file *file, struct page *page,
        lower_page_data = kmap_atomic(lower_page, KM_USER1);
        memcpy(page_data, lower_page_data, PAGE_CACHE_SIZE);
        kunmap_atomic(lower_page_data, KM_USER1);
-       flush_dcache_page(lower_page);
        kunmap_atomic(page_data, KM_USER0);
        flush_dcache_page(page);
        rc = 0;
@@ -422,9 +421,11 @@ out:
        return rc;
 }
 
-static void ecryptfs_release_lower_page(struct page *lower_page)
+static
+void ecryptfs_release_lower_page(struct page *lower_page, int page_locked)
 {
-       unlock_page(lower_page);
+       if (page_locked)
+               unlock_page(lower_page);
        page_cache_release(lower_page);
 }
 
@@ -454,6 +455,13 @@ static int ecryptfs_write_inode_size_to_header(struct file *lower_file,
        }
        lower_a_ops = lower_inode->i_mapping->a_ops;
        rc = lower_a_ops->prepare_write(lower_file, header_page, 0, 8);
+       if (rc) {
+               if (rc == AOP_TRUNCATED_PAGE)
+                       ecryptfs_release_lower_page(header_page, 0);
+               else
+                       ecryptfs_release_lower_page(header_page, 1);
+               goto out;
+       }
        file_size = (u64)i_size_read(inode);
        ecryptfs_printk(KERN_DEBUG, "Writing size: [0x%.16x]\n", file_size);
        file_size = cpu_to_be64(file_size);
@@ -465,7 +473,10 @@ static int ecryptfs_write_inode_size_to_header(struct file *lower_file,
        if (rc < 0)
                ecryptfs_printk(KERN_ERR, "Error commiting header page "
                                "write\n");
-       ecryptfs_release_lower_page(header_page);
+       if (rc == AOP_TRUNCATED_PAGE)
+               ecryptfs_release_lower_page(header_page, 0);
+       else
+               ecryptfs_release_lower_page(header_page, 1);
        lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME;
        mark_inode_dirty_sync(inode);
 out:
@@ -572,7 +583,10 @@ int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode,
        }
 out:
        if (rc && (*lower_page)) {
-               ecryptfs_release_lower_page(*lower_page);
+               if (rc == AOP_TRUNCATED_PAGE)
+                       ecryptfs_release_lower_page(*lower_page, 0);
+               else
+                       ecryptfs_release_lower_page(*lower_page, 1);
                (*lower_page) = NULL;
        }
        return rc;
@@ -588,16 +602,19 @@ ecryptfs_commit_lower_page(struct page *lower_page, struct inode *lower_inode,
                           struct file *lower_file, int byte_offset,
                           int region_size)
 {
+       int page_locked = 1;
        int rc = 0;
 
        rc = lower_inode->i_mapping->a_ops->commit_write(
                lower_file, lower_page, byte_offset, region_size);
+       if (rc == AOP_TRUNCATED_PAGE)
+               page_locked = 0;
        if (rc < 0) {
                ecryptfs_printk(KERN_ERR,
                                "Error committing write; rc = [%d]\n", rc);
        } else
                rc = 0;
-       ecryptfs_release_lower_page(lower_page);
+       ecryptfs_release_lower_page(lower_page, page_locked);
        return rc;
 }
 
index 99857a400f4be217dcf92e5f16ac6c62783b62e2..12f7dda1232cb8b17749d6f3e87d6ea77a40bb0c 100644 (file)
@@ -475,8 +475,15 @@ ext3_xattr_release_block(handle_t *handle, struct inode *inode,
                         struct buffer_head *bh)
 {
        struct mb_cache_entry *ce = NULL;
+       int error = 0;
 
        ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_bdev, bh->b_blocknr);
+       error = ext3_journal_get_write_access(handle, bh);
+       if (error)
+                goto out;
+
+       lock_buffer(bh);
+
        if (BHDR(bh)->h_refcount == cpu_to_le32(1)) {
                ea_bdebug(bh, "refcount now=0; freeing");
                if (ce)
@@ -485,21 +492,20 @@ ext3_xattr_release_block(handle_t *handle, struct inode *inode,
                get_bh(bh);
                ext3_forget(handle, 1, inode, bh, bh->b_blocknr);
        } else {
-               if (ext3_journal_get_write_access(handle, bh) == 0) {
-                       lock_buffer(bh);
-                       BHDR(bh)->h_refcount = cpu_to_le32(
+               BHDR(bh)->h_refcount = cpu_to_le32(
                                le32_to_cpu(BHDR(bh)->h_refcount) - 1);
-                       ext3_journal_dirty_metadata(handle, bh);
-                       if (IS_SYNC(inode))
-                               handle->h_sync = 1;
-                       DQUOT_FREE_BLOCK(inode, 1);
-                       unlock_buffer(bh);
-                       ea_bdebug(bh, "refcount now=%d; releasing",
-                                 le32_to_cpu(BHDR(bh)->h_refcount));
-               }
+               error = ext3_journal_dirty_metadata(handle, bh);
+               handle->h_sync = 1;
+               DQUOT_FREE_BLOCK(inode, 1);
+               ea_bdebug(bh, "refcount now=%d; releasing",
+                         le32_to_cpu(BHDR(bh)->h_refcount));
                if (ce)
                        mb_cache_entry_release(ce);
        }
+       unlock_buffer(bh);
+out:
+       ext3_std_error(inode->i_sb, error);
+       return;
 }
 
 struct ext3_xattr_info {
@@ -675,7 +681,7 @@ ext3_xattr_block_set(handle_t *handle, struct inode *inode,
        struct buffer_head *new_bh = NULL;
        struct ext3_xattr_search *s = &bs->s;
        struct mb_cache_entry *ce = NULL;
-       int error;
+       int error = 0;
 
 #define header(x) ((struct ext3_xattr_header *)(x))
 
@@ -684,16 +690,17 @@ ext3_xattr_block_set(handle_t *handle, struct inode *inode,
        if (s->base) {
                ce = mb_cache_entry_get(ext3_xattr_cache, bs->bh->b_bdev,
                                        bs->bh->b_blocknr);
+               error = ext3_journal_get_write_access(handle, bs->bh);
+               if (error)
+                       goto cleanup;
+               lock_buffer(bs->bh);
+
                if (header(s->base)->h_refcount == cpu_to_le32(1)) {
                        if (ce) {
                                mb_cache_entry_free(ce);
                                ce = NULL;
                        }
                        ea_bdebug(bs->bh, "modifying in-place");
-                       error = ext3_journal_get_write_access(handle, bs->bh);
-                       if (error)
-                               goto cleanup;
-                       lock_buffer(bs->bh);
                        error = ext3_xattr_set_entry(i, s);
                        if (!error) {
                                if (!IS_LAST_ENTRY(s->first))
@@ -713,6 +720,9 @@ ext3_xattr_block_set(handle_t *handle, struct inode *inode,
                } else {
                        int offset = (char *)s->here - bs->bh->b_data;
 
+                       unlock_buffer(bs->bh);
+                       journal_release_buffer(handle, bs->bh);
+
                        if (ce) {
                                mb_cache_entry_release(ce);
                                ce = NULL;
index dc969c357aa1d4ef9e207054e506053b8efdc0c6..e832e96095b33c177e880db6370e1686153439f6 100644 (file)
@@ -475,8 +475,14 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode,
                         struct buffer_head *bh)
 {
        struct mb_cache_entry *ce = NULL;
+       int error = 0;
 
        ce = mb_cache_entry_get(ext4_xattr_cache, bh->b_bdev, bh->b_blocknr);
+       error = ext4_journal_get_write_access(handle, bh);
+       if (error)
+               goto out;
+
+       lock_buffer(bh);
        if (BHDR(bh)->h_refcount == cpu_to_le32(1)) {
                ea_bdebug(bh, "refcount now=0; freeing");
                if (ce)
@@ -485,21 +491,21 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode,
                get_bh(bh);
                ext4_forget(handle, 1, inode, bh, bh->b_blocknr);
        } else {
-               if (ext4_journal_get_write_access(handle, bh) == 0) {
-                       lock_buffer(bh);
-                       BHDR(bh)->h_refcount = cpu_to_le32(
+               BHDR(bh)->h_refcount = cpu_to_le32(
                                le32_to_cpu(BHDR(bh)->h_refcount) - 1);
-                       ext4_journal_dirty_metadata(handle, bh);
-                       if (IS_SYNC(inode))
-                               handle->h_sync = 1;
-                       DQUOT_FREE_BLOCK(inode, 1);
-                       unlock_buffer(bh);
-                       ea_bdebug(bh, "refcount now=%d; releasing",
-                                 le32_to_cpu(BHDR(bh)->h_refcount));
-               }
+               error = ext4_journal_dirty_metadata(handle, bh);
+               if (IS_SYNC(inode))
+                       handle->h_sync = 1;
+               DQUOT_FREE_BLOCK(inode, 1);
+               ea_bdebug(bh, "refcount now=%d; releasing",
+                         le32_to_cpu(BHDR(bh)->h_refcount));
                if (ce)
                        mb_cache_entry_release(ce);
        }
+       unlock_buffer(bh);
+out:
+       ext4_std_error(inode->i_sb, error);
+       return;
 }
 
 struct ext4_xattr_info {
@@ -675,7 +681,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
        struct buffer_head *new_bh = NULL;
        struct ext4_xattr_search *s = &bs->s;
        struct mb_cache_entry *ce = NULL;
-       int error;
+       int error = 0;
 
 #define header(x) ((struct ext4_xattr_header *)(x))
 
@@ -684,16 +690,17 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
        if (s->base) {
                ce = mb_cache_entry_get(ext4_xattr_cache, bs->bh->b_bdev,
                                        bs->bh->b_blocknr);
+               error = ext4_journal_get_write_access(handle, bs->bh);
+               if (error)
+                       goto cleanup;
+               lock_buffer(bs->bh);
+
                if (header(s->base)->h_refcount == cpu_to_le32(1)) {
                        if (ce) {
                                mb_cache_entry_free(ce);
                                ce = NULL;
                        }
                        ea_bdebug(bs->bh, "modifying in-place");
-                       error = ext4_journal_get_write_access(handle, bs->bh);
-                       if (error)
-                               goto cleanup;
-                       lock_buffer(bs->bh);
                        error = ext4_xattr_set_entry(i, s);
                        if (!error) {
                                if (!IS_LAST_ENTRY(s->first))
@@ -713,6 +720,8 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
                } else {
                        int offset = (char *)s->here - bs->bh->b_data;
 
+                       unlock_buffer(bs->bh);
+                       jbd2_journal_release_buffer(handle, bs->bh);
                        if (ce) {
                                mb_cache_entry_release(ce);
                                ce = NULL;
index ba1b37df69d50d6147a2150b052c5e8cc89dd9de..8a05aa168616f6d548bd78e03d7e474eee3cf1ad 100644 (file)
@@ -70,7 +70,11 @@ static inline int pte_file(pte_t pte) { return 0; }
 
 #define swapper_pg_dir         ((pgd_t *) NULL)
 
-#define pgtable_cache_init()   do {} while(0)
+#define pgtable_cache_init()           do {} while (0)
+#define arch_enter_lazy_mmu_mode()     do {} while (0)
+#define arch_leave_lazy_mmu_mode()     do {} while (0)
+#define arch_enter_lazy_cpu_mode()     do {} while (0)
+#define arch_leave_lazy_cpu_mode()     do {} while (0)
 
 #else /* !CONFIG_MMU */
 /*****************************************************************************/
index e57ff136ee510e884ea4474a7e2f21bde36b2390..1b1090a91a58f2954bfe5455edcc561e253cc83f 100644 (file)
@@ -270,7 +270,7 @@ static inline pte_t pte_wrprotect(pte_t pte)
 
 static inline pte_t pte_mkread(pte_t pte)
 { 
-       pte_set_bits(pte, _PAGE_RW);
+       pte_set_bits(pte, _PAGE_USER);
        return(pte_mknewprot(pte)); 
 }
 
index 37f9279192a998f50641d81056a57692a8eaf538..3bef961b58b1e40557c806accae3c805f9398464 100644 (file)
@@ -140,6 +140,7 @@ struct hrtimer_sleeper {
 
 /**
  * struct hrtimer_base - the timer base for a specific clock
+ * @cpu_base:          per cpu clock base
  * @index:             clock type index for per_cpu support when moving a
  *                     timer to a base on another cpu.
  * @active:            red black tree root node for the active timers
index a60995afe3348a7ce3ebd0808252679a17164c98..3f3e7a648da3947c76839e02670c75c2cfd27710 100644 (file)
@@ -4,6 +4,7 @@
 #ifdef CONFIG_HUGETLB_PAGE
 
 #include <linux/mempolicy.h>
+#include <linux/shm.h>
 #include <asm/tlbflush.h>
 
 struct ctl_table;
@@ -168,7 +169,12 @@ void hugetlb_put_quota(struct address_space *mapping);
 
 static inline int is_file_hugepages(struct file *file)
 {
-       return file->f_op == &hugetlbfs_file_operations;
+       if (file->f_op == &hugetlbfs_file_operations)
+               return 1;
+       if (is_file_shm_hugepages(file))
+               return 1;
+
+       return 0;
 }
 
 static inline void set_file_hugepages(struct file *file)
index b0a44b8e0281bf5b28aeffe58c4ad5f43a7dc1e1..a6899402b5220233c53fe926655d788b2dce7f1c 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/spinlock.h>
 #include <linux/cpumask.h>
 #include <linux/irqreturn.h>
+#include <linux/errno.h>
 
 #include <asm/irq.h>
 #include <asm/ptrace.h>
index 2e79f816703be86b918b4797e74bde58ea9da63b..63bd9cf821a763953cd94243d385a74e8672ee5c 100644 (file)
@@ -174,9 +174,26 @@ char *capi_info2str(__u16 reason);
 /*
  * Debugging / Tracing functions
  */
+
 char *capi_cmd2str(__u8 cmd, __u8 subcmd);
-char *capi_cmsg2str(_cmsg * cmsg);
-char *capi_message2str(__u8 * msg);
+
+typedef struct {
+       u_char  *buf;
+       u_char  *p;
+       size_t  size;
+       size_t  pos;
+} _cdebbuf;
+
+#define        CDEBUG_SIZE     1024
+#define        CDEBUG_GSIZE    4096
+
+_cdebbuf *cdebbuf_alloc(void);
+void cdebbuf_free(_cdebbuf *cdb);
+int cdebug_init(void);
+void cdebug_exit(void);
+
+_cdebbuf *capi_cmsg2str(_cmsg *cmsg);
+_cdebbuf *capi_message2str(__u8 *msg);
 
 /*-----------------------------------------------------------------------*/
 
index a0eec16eb0bdbb6a2092b443f299f28c5c11cc25..60e0e4a592d29fd28a62053b5cabde4c1f285673 100644 (file)
@@ -660,15 +660,11 @@ static inline int page_mapped(struct page *page)
 extern void show_free_areas(void);
 
 #ifdef CONFIG_SHMEM
-struct page *shmem_nopage(struct vm_area_struct *vma,
-                       unsigned long address, int *type);
 int shmem_set_policy(struct vm_area_struct *vma, struct mempolicy *new);
 struct mempolicy *shmem_get_policy(struct vm_area_struct *vma,
                                        unsigned long addr);
 int shmem_lock(struct file *file, int lock, struct user_struct *user);
 #else
-#define shmem_nopage filemap_nopage
-
 static inline int shmem_lock(struct file *file, int lock,
                             struct user_struct *user)
 {
@@ -688,7 +684,6 @@ static inline struct mempolicy *shmem_get_policy(struct vm_area_struct *vma,
 }
 #endif
 struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags);
-extern int shmem_mmap(struct file *file, struct vm_area_struct *vma);
 
 int shmem_zero_setup(struct vm_area_struct *);
 
index 350878a2d848cf2efe561449ac7d9ccece15630b..9cd0d0eaf5239a3276aecb6b2a83e7f399acda27 100644 (file)
@@ -76,7 +76,7 @@
 #define PG_active               6
 #define PG_slab                         7      /* slab debug (Suparna wants this) */
 
-#define PG_checked              8      /* kill me in 2.5.<early>. */
+#define PG_owner_priv_1                 8      /* Owner use. If pagecache, fs may use*/
 #define PG_arch_1               9
 #define PG_reserved            10
 #define PG_private             11      /* If pagecache, has fs-private data */
@@ -91,6 +91,8 @@
 #define PG_nosave_free         18      /* Used for system suspend/resume */
 #define PG_buddy               19      /* Page is free, on buddy lists */
 
+/* PG_owner_priv_1 users should have descriptive aliases */
+#define PG_checked             PG_owner_priv_1 /* Used by some filesystems */
 
 #if (BITS_PER_LONG > 32)
 /*
index a2c896ad0befa6819dbae3e1ffd47b1679597346..ad2e3af6599710d43269a7f4c243ebd90171925d 100644 (file)
@@ -96,12 +96,17 @@ struct shmid_kernel /* private to the kernel */
 
 #ifdef CONFIG_SYSVIPC
 long do_shmat(int shmid, char __user *shmaddr, int shmflg, unsigned long *addr);
+extern int is_file_shm_hugepages(struct file *file);
 #else
 static inline long do_shmat(int shmid, char __user *shmaddr,
                                int shmflg, unsigned long *addr)
 {
        return -ENOSYS;
 }
+static inline int is_file_shm_hugepages(struct file *file)
+{
+       return 0;
+}
 #endif
 
 #endif /* __KERNEL__ */
index 28157a36e6ccd69ce4ae091fe835162364813e7c..fcd35a210e7f7d5eed13b7c4e243b4ee3a9c7a50 100644 (file)
@@ -16,7 +16,7 @@ struct __kernel_sockaddr_storage {
                                /* _SS_MAXSIZE value minus size of ss_family */
 } __attribute__ ((aligned(_K_SS_ALIGNSIZE)));  /* force desired alignment */
 
-#ifdef __KERNEL__
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
 
 #include <asm/socket.h>                        /* arch-dependent defines       */
 #include <linux/sockios.h>             /* the SIOCxxx I/O controls     */
index 4f8539ccff6cf8addcf9d3561d58d5ba8b518c26..679ef0d70b6b1bae44fb4d9a60af100b1ec2d8fb 100644 (file)
@@ -7,7 +7,7 @@
 
 #endif
 
-#ifdef __KERNEL__
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
 
 #define S_IFMT  00170000
 #define S_IFSOCK 0140000
index 21805b500aa24cbdbe67bb6ee0ccf4600f712e4b..523405e1e1f6463a5f8aa925655d97234adaefae 100644 (file)
@@ -211,9 +211,8 @@ static inline int sysfs_add_file_to_group(struct kobject *kobj,
 }
 
 static inline void sysfs_remove_file_from_group(struct kobject *kobj,
-               const struct attribute *attr, const char *group);
+               const struct attribute *attr, const char *group)
 {
-       ;
 }
 
 static inline void sysfs_notify(struct kobject * k, char *dir, char *attr)
index 65a165f918c9f9760a9bb1aa7c152ad2aafea29c..441b877bf150ef84d467f89b318945dd0c622f88 100644 (file)
@@ -1192,6 +1192,55 @@ struct v4l2_audioout
        __u32   reserved[2];
 };
 
+/*
+ *     M P E G   S E R V I C E S
+ *
+ *     NOTE: EXPERIMENTAL API
+ */
+#if 1
+#define V4L2_ENC_IDX_FRAME_I    (0)
+#define V4L2_ENC_IDX_FRAME_P    (1)
+#define V4L2_ENC_IDX_FRAME_B    (2)
+#define V4L2_ENC_IDX_FRAME_MASK (0xf)
+
+struct v4l2_enc_idx_entry {
+       __u64 offset;
+       __u64 pts;
+       __u32 length;
+       __u32 flags;
+       __u32 reserved[2];
+};
+
+#define V4L2_ENC_IDX_ENTRIES (64)
+struct v4l2_enc_idx {
+       __u32 entries;
+       __u32 entries_cap;
+       __u32 reserved[4];
+       struct v4l2_enc_idx_entry entry[V4L2_ENC_IDX_ENTRIES];
+};
+
+
+#define V4L2_ENC_CMD_START      (0)
+#define V4L2_ENC_CMD_STOP       (1)
+#define V4L2_ENC_CMD_PAUSE      (2)
+#define V4L2_ENC_CMD_RESUME     (3)
+
+/* Flags for V4L2_ENC_CMD_STOP */
+#define V4L2_ENC_CMD_STOP_AT_GOP_END    (1 << 0)
+
+struct v4l2_encoder_cmd {
+       __u32 cmd;
+       __u32 flags;
+       union {
+               struct {
+                       __u32 data[8];
+               } raw;
+       };
+};
+
+#endif
+
+
 /*
  *     D A T A   S E R V I C E S   ( V B I )
  *
@@ -1303,13 +1352,21 @@ struct v4l2_streamparm
 
 /*
  *     A D V A N C E D   D E B U G G I N G
+ *
+ *     NOTE: EXPERIMENTAL API
  */
 
 /* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */
+
+#define V4L2_CHIP_MATCH_HOST       0  /* Match against chip ID on host (0 for the host) */
+#define V4L2_CHIP_MATCH_I2C_DRIVER 1  /* Match against I2C driver ID */
+#define V4L2_CHIP_MATCH_I2C_ADDR   2  /* Match against I2C 7-bit address */
+
 struct v4l2_register {
+       __u32 match_type; /* Match type */
+       __u32 match_chip; /* Match this chip, meaning determined by match_type */
        __u64 reg;
-       __u32 i2c_id; /* I2C driver ID of the I2C chip, or 0 for the host */
-       __u32 val;
+       __u64 val;
 };
 
 /*
@@ -1378,10 +1435,14 @@ struct v4l2_register {
 #if 1
 #define VIDIOC_ENUM_FRAMESIZES _IOWR ('V', 74, struct v4l2_frmsizeenum)
 #define VIDIOC_ENUM_FRAMEINTERVALS     _IOWR ('V', 75, struct v4l2_frmivalenum)
+#define VIDIOC_G_ENC_INDEX      _IOR  ('V', 76, struct v4l2_enc_idx)
+#define VIDIOC_ENCODER_CMD      _IOWR ('V', 77, struct v4l2_encoder_cmd)
+#define VIDIOC_TRY_ENCODER_CMD  _IOWR ('V', 78, struct v4l2_encoder_cmd)
+
+/* Experimental, only implemented if CONFIG_VIDEO_ADV_DEBUG is defined */
+#define        VIDIOC_DBG_S_REGISTER   _IOW  ('V', 79, struct v4l2_register)
+#define        VIDIOC_DBG_G_REGISTER   _IOWR ('V', 80, struct v4l2_register)
 #endif
-/* only implemented if CONFIG_VIDEO_ADV_DEBUG is defined */
-#define        VIDIOC_DBG_S_REGISTER   _IOW ('d', 100, struct v4l2_register)
-#define        VIDIOC_DBG_G_REGISTER   _IOWR('d', 101, struct v4l2_register)
 
 #ifdef __OLD_VIDIOC_
 /* for compatibility, will go away some day */
index fc35e6bdfb93e4bf4d5cac5b50c983e97e846c5a..0c78f7f4a976489064d2508d6e56ae610bf84311 100644 (file)
@@ -84,7 +84,7 @@ static inline void wait_on_inode(struct inode *inode)
 int wakeup_pdflush(long nr_pages);
 void laptop_io_completion(void);
 void laptop_sync_completion(void);
-void throttle_vm_writeout(void);
+void throttle_vm_writeout(gfp_t gfp_mask);
 
 /* These are exported to sysctl. */
 extern int dirty_background_ratio;
index 244e440edb5353d2f2817601718f1e36e90ae6fb..6eaeec98ed8908fc819193a7226002a4218e5ac4 100644 (file)
@@ -94,6 +94,14 @@ u32 v4l2_ctrl_next(const u32 * const *ctrl_classes, u32 id);
 
 /* ------------------------------------------------------------------------- */
 
+/* Register/chip ident helper function */
+
+struct i2c_client; /* forward reference */
+int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 id_type, u32 chip_id);
+int v4l2_chip_match_host(u32 id_type, u32 chip_id);
+
+/* ------------------------------------------------------------------------- */
+
 /* Internal ioctls */
 
 /* VIDIOC_INT_DECODE_VBI_LINE */
index aeec56992ef5bb071b768edefab68e5f0ade6238..1dd3d3239ecf56869e60fe6bf0fa414b8b0efecc 100644 (file)
@@ -271,6 +271,12 @@ struct video_device
                                        struct v4l2_jpegcompression *a);
        int (*vidioc_s_jpegcomp)       (struct file *file, void *fh,
                                        struct v4l2_jpegcompression *a);
+       int (*vidioc_g_enc_index)      (struct file *file, void *fh,
+                                       struct v4l2_enc_idx *a);
+       int (*vidioc_encoder_cmd)      (struct file *file, void *fh,
+                                       struct v4l2_encoder_cmd *a);
+       int (*vidioc_try_encoder_cmd)  (struct file *file, void *fh,
+                                       struct v4l2_encoder_cmd *a);
 
        /* Stream type-dependent parameter ioctls */
        int (*vidioc_g_parm)           (struct file *file, void *fh,
index 03684e702d13464cbc0a48b95354dc540341f504..2c7d60ca354858ac75ead88773d0886aedcc185c 100644 (file)
@@ -1278,7 +1278,7 @@ static inline int sock_writeable(const struct sock *sk)
 
 static inline gfp_t gfp_any(void)
 {
-       return in_softirq() ? GFP_ATOMIC : GFP_KERNEL;
+       return in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
 }
 
 static inline long sock_rcvtimeo(const struct sock *sk, int noblock)
index eb57e22543049f2bb157505458fc90308a797543..4fefbad7096d539d90345621ac6419d2ab904b85 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -226,8 +226,8 @@ static void shm_close(struct vm_area_struct *vma)
        mutex_unlock(&shm_ids(ns).mutex);
 }
 
-struct page *shm_nopage(struct vm_area_struct *vma, unsigned long address,
-                       int *type)
+static struct page *shm_nopage(struct vm_area_struct *vma,
+                              unsigned long address, int *type)
 {
        struct file *file = vma->vm_file;
        struct shm_file_data *sfd = shm_file_data(file);
@@ -285,21 +285,41 @@ static int shm_release(struct inode *ino, struct file *file)
        return 0;
 }
 
-#ifndef CONFIG_MMU
+static int shm_fsync(struct file *file, struct dentry *dentry, int datasync)
+{
+       int (*fsync) (struct file *, struct dentry *, int datasync);
+       struct shm_file_data *sfd = shm_file_data(file);
+       int ret = -EINVAL;
+
+       fsync = sfd->file->f_op->fsync;
+       if (fsync)
+               ret = fsync(sfd->file, sfd->file->f_path.dentry, datasync);
+       return ret;
+}
+
 static unsigned long shm_get_unmapped_area(struct file *file,
        unsigned long addr, unsigned long len, unsigned long pgoff,
        unsigned long flags)
 {
        struct shm_file_data *sfd = shm_file_data(file);
-       return sfd->file->f_op->get_unmapped_area(sfd->file, addr, len, pgoff,
-                                                       flags);
+       return get_unmapped_area(sfd->file, addr, len, pgoff, flags);
+}
+
+int is_file_shm_hugepages(struct file *file)
+{
+       int ret = 0;
+
+       if (file->f_op == &shm_file_operations) {
+               struct shm_file_data *sfd;
+               sfd = shm_file_data(file);
+               ret = is_file_hugepages(sfd->file);
+       }
+       return ret;
 }
-#else
-#define shm_get_unmapped_area NULL
-#endif
 
 static const struct file_operations shm_file_operations = {
        .mmap           = shm_mmap,
+       .fsync          = shm_fsync,
        .release        = shm_release,
        .get_unmapped_area      = shm_get_unmapped_area,
 };
index a08a17218dfaced4c32e39fe40d628f4d32cb578..8dc24c92dc6d2c1e867c8ce381caec43c9408583 100644 (file)
@@ -2602,7 +2602,7 @@ out_restore:
        raw_local_irq_restore(flags);
 }
 
-void __init lockdep_init(void)
+void lockdep_init(void)
 {
        int i;
 
index ef8a935710a27be3edc6c940f77878d2895d6434..577f251c7e28104f621d542a199169053a589c8b 100644 (file)
@@ -474,13 +474,12 @@ static void setup_callbacks(struct rchan *chan,
 }
 
 /**
- *
  *     relay_hotcpu_callback - CPU hotplug callback
  *     @nb: notifier block
  *     @action: hotplug action to take
  *     @hcpu: CPU number
  *
- *     Returns the success/failure of the operation. (NOTIFY_OK, NOTIFY_BAD)
+ *     Returns the success/failure of the operation. (%NOTIFY_OK, %NOTIFY_BAD)
  */
 static int __cpuinit relay_hotcpu_callback(struct notifier_block *nb,
                                unsigned long action,
index 0dc757246d89b02c96593df44ff8d75acb93e711..5f102e6c7a4ca2c1f9cb041cc03744c414c50069 100644 (file)
@@ -3547,7 +3547,7 @@ need_resched_nonpreemptible:
                }
        }
        next->sleep_type = SLEEP_NORMAL;
-       if (dependent_sleeper(cpu, rq, next))
+       if (rq->nr_running == 1 && dependent_sleeper(cpu, rq, next))
                next = rq->idle;
 switch_tasks:
        if (next == rq->idle)
@@ -3566,7 +3566,7 @@ switch_tasks:
 
        sched_info_switch(prev, next);
        if (likely(prev != next)) {
-               next->timestamp = now;
+               next->timestamp = next->last_ran = now;
                rq->nr_switches++;
                rq->curr = next;
                ++*switch_count;
index 3ca1d5ff0319ea70321f196ab28b7b368179f271..34b2301276cee8996fc6a1771053e588ec82417b 100644 (file)
@@ -1359,8 +1359,7 @@ void unregister_sysctl_table(struct ctl_table_header * header)
 }
 
 #else /* !CONFIG_SYSCTL */
-struct ctl_table_header * register_sysctl_table(ctl_table * table,
-                                               int insert_at_head)
+struct ctl_table_header *register_sysctl_table(ctl_table * table)
 {
        return NULL;
 }
index cb1b86a9c52f5749f767625ffe6f6895f4b476aa..6663a87f7304742b7f8cef44a39f2ea0873c511b 100644 (file)
@@ -711,6 +711,7 @@ static unsigned long cmp_next_hrtimer_event(unsigned long now,
 
 /**
  * next_timer_interrupt - return the jiffy of the next pending timer
+ * @now: current time (in jiffies)
  */
 unsigned long get_next_timer_interrupt(unsigned long now)
 {
@@ -908,7 +909,7 @@ static inline void change_clocksource(void) { }
 #endif
 
 /**
- * timeofday_is_continuous - check to see if timekeeping is free running
+ * timekeeping_is_continuous - check to see if timekeeping is free running
  */
 int timekeeping_is_continuous(void)
 {
index ee6e58fce8f75f675c2688294b07e01655a4396e..26ebafa8c41d7e0ff602c0d2137a8ea284bb1ae5 100644 (file)
@@ -97,10 +97,10 @@ EXPORT_SYMBOL(__bitmap_complement);
 
 /**
  * __bitmap_shift_right - logical right shift of the bits in a bitmap
- *   @dst - destination bitmap
- *   @src - source bitmap
- *   @nbits - shift by this many bits
- *   @bits - bitmap size, in bits
+ *   @dst : destination bitmap
+ *   @src : source bitmap
+ *   @shift : shift by this many bits
+ *   @bits : bitmap size, in bits
  *
  * Shifting right (dividing) means moving bits in the MS -> LS bit
  * direction.  Zeros are fed into the vacated MS positions and the
@@ -141,10 +141,10 @@ EXPORT_SYMBOL(__bitmap_shift_right);
 
 /**
  * __bitmap_shift_left - logical left shift of the bits in a bitmap
- *   @dst - destination bitmap
- *   @src - source bitmap
- *   @nbits - shift by this many bits
- *   @bits - bitmap size, in bits
+ *   @dst : destination bitmap
+ *   @src : source bitmap
+ *   @shift : shift by this many bits
+ *   @bits : bitmap size, in bits
  *
  * Shifting left (multiplying) means moving bits in the LS -> MS
  * direction.  Zeros are fed into the vacated LS bit positions
index eb509ae76553260c61a4b17b3b8bc7deca663b25..84f997da78d70e607578afac5a87b64362b12558 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -299,6 +299,8 @@ static int browse_rb(struct rb_root *root)
                        printk("vm_end %lx < vm_start %lx\n", vma->vm_end, vma->vm_start);
                i++;
                pn = nd;
+               prev = vma->vm_start;
+               pend = vma->vm_end;
        }
        j = 0;
        for (nd = pn; nd; nd = rb_prev(nd)) {
index f7e088f5a309eff3a03c8da5ad4ca4b37ecd5518..f469e3cd08e82d47ba3a0aa8d9753081e2c7cc99 100644 (file)
@@ -296,11 +296,21 @@ void balance_dirty_pages_ratelimited_nr(struct address_space *mapping,
 }
 EXPORT_SYMBOL(balance_dirty_pages_ratelimited_nr);
 
-void throttle_vm_writeout(void)
+void throttle_vm_writeout(gfp_t gfp_mask)
 {
        long background_thresh;
        long dirty_thresh;
 
+       if ((gfp_mask & (__GFP_FS|__GFP_IO)) != (__GFP_FS|__GFP_IO)) {
+               /*
+                * The caller might hold locks which can prevent IO completion
+                * or progress in the filesystem.  So we cannot just sit here
+                * waiting for IO to complete.
+                */
+               congestion_wait(WRITE, HZ/10);
+               return;
+       }
+
         for ( ; ; ) {
                get_dirty_limits(&background_thresh, &dirty_thresh, NULL);
 
@@ -317,7 +327,6 @@ void throttle_vm_writeout(void)
         }
 }
 
-
 /*
  * writeback at least _min_pages, and keep writing until the amount of dirty
  * memory is less than the background threshold, or until we're all clean.
index 41737395bbcc16625ef11b071278ed6073c4055f..353ce9039a86f477ac13897bb76ab522c718ab87 100644 (file)
@@ -600,7 +600,7 @@ static int prep_new_page(struct page *page, int order, gfp_t gfp_flags)
 
        page->flags &= ~(1 << PG_uptodate | 1 << PG_error |
                        1 << PG_referenced | 1 << PG_arch_1 |
-                       1 << PG_checked | 1 << PG_mappedtodisk);
+                       1 << PG_owner_priv_1 | 1 << PG_mappedtodisk);
        set_page_private(page, 0);
        set_page_refcounted(page);
 
index 669acb22b572190ff2dcc6544c968bbd7516859e..22ed3f71a67421831f12b0deffa915eacf5d1db7 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -183,7 +183,7 @@ void __init anon_vma_init(void)
  */
 static struct anon_vma *page_lock_anon_vma(struct page *page)
 {
-       struct anon_vma *anon_vma = NULL;
+       struct anon_vma *anon_vma;
        unsigned long anon_mapping;
 
        rcu_read_lock();
@@ -195,9 +195,16 @@ static struct anon_vma *page_lock_anon_vma(struct page *page)
 
        anon_vma = (struct anon_vma *) (anon_mapping - PAGE_MAPPING_ANON);
        spin_lock(&anon_vma->lock);
+       return anon_vma;
 out:
        rcu_read_unlock();
-       return anon_vma;
+       return NULL;
+}
+
+static void page_unlock_anon_vma(struct anon_vma *anon_vma)
+{
+       spin_unlock(&anon_vma->lock);
+       rcu_read_unlock();
 }
 
 /*
@@ -333,7 +340,8 @@ static int page_referenced_anon(struct page *page)
                if (!mapcount)
                        break;
        }
-       spin_unlock(&anon_vma->lock);
+
+       page_unlock_anon_vma(anon_vma);
        return referenced;
 }
 
@@ -802,7 +810,8 @@ static int try_to_unmap_anon(struct page *page, int migration)
                if (ret == SWAP_FAIL || !page_mapped(page))
                        break;
        }
-       spin_unlock(&anon_vma->lock);
+
+       page_unlock_anon_vma(anon_vma);
        return ret;
 }
 
index 882053031aa0590b502551783c8902b50461abf1..fcb07882c8e0224530de5046e016958c65ff7524 100644 (file)
@@ -1228,7 +1228,8 @@ failed:
        return error;
 }
 
-struct page *shmem_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
+static struct page *shmem_nopage(struct vm_area_struct *vma,
+                                unsigned long address, int *type)
 {
        struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
        struct page *page = NULL;
@@ -1335,7 +1336,7 @@ out_nomem:
        return retval;
 }
 
-int shmem_mmap(struct file *file, struct vm_area_struct *vma)
+static int shmem_mmap(struct file *file, struct vm_area_struct *vma)
 {
        file_accessed(file);
        vma->vm_ops = &shmem_vm_ops;
index 8fdaffa717eaa1ef21bd3b900a02c06ab7f05f66..57f7aa4200640e78cd1207e2a39dbbd4d310c8ac 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -4026,7 +4026,7 @@ void drain_array(struct kmem_cache *cachep, struct kmem_list3 *l3,
 
 /**
  * cache_reap - Reclaim memory from caches.
- * @unused: unused parameter
+ * @w: work descriptor
  *
  * Called from workqueue/eventd every few seconds.
  * Purpose:
index c7f6e1914bc4e77264591f02958c32f1f8af1d93..8803471593fd7135ded6359d2a249c39a0d29815 100644 (file)
@@ -126,6 +126,7 @@ int shmem_unuse(swp_entry_t entry, struct page *page)
        return 0;
 }
 
+#if 0
 int shmem_mmap(struct file *file, struct vm_area_struct *vma)
 {
        file_accessed(file);
@@ -135,6 +136,7 @@ int shmem_mmap(struct file *file, struct vm_area_struct *vma)
        return 0;
 #endif
 }
+#endif  /*  0  */
 
 #ifndef CONFIG_MMU
 unsigned long shmem_get_unmapped_area(struct file *file,
index ebf3fcb4115b8c664e54e4c47e02968ed93ab0be..0f4b6d18ab0ed663360e0fba11f46f23e8c6b5b3 100644 (file)
@@ -375,10 +375,10 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
 
        pagevec_init(&pvec, 0);
        next = start;
-       while (next <= end && !ret && !wrapped &&
+       while (next <= end && !wrapped &&
                pagevec_lookup(&pvec, mapping, next,
                        min(end - next, (pgoff_t)PAGEVEC_SIZE - 1) + 1)) {
-               for (i = 0; !ret && i < pagevec_count(&pvec); i++) {
+               for (i = 0; i < pagevec_count(&pvec); i++) {
                        struct page *page = pvec.pages[i];
                        pgoff_t page_index;
 
index 0655d5fe73e82c164043bf99958397602d6846c7..db023e2ff3852f544c6a4b0f8cb3b43ecd0d456b 100644 (file)
@@ -952,7 +952,7 @@ static unsigned long shrink_zone(int priority, struct zone *zone,
                }
        }
 
-       throttle_vm_writeout();
+       throttle_vm_writeout(sc->gfp_mask);
 
        atomic_dec(&zone->reclaim_in_progress);
        return nr_reclaimed;
index 3ab153d3c508810007da27fb9ca846a0a2ead0b0..147015fe5c75c910cb3e4c990f104523d24b212c 100644 (file)
@@ -291,12 +291,11 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
 
-               spin_lock_bh(&br->lock);
                if ((p = br_get_port(br, args[1])) == NULL)
                        ret = -EINVAL;
                else
                        br_stp_set_path_cost(p, args[2]);
-               spin_unlock_bh(&br->lock);
+
                return ret;
        }
 
index f89ff151cfabff32a6436c98fef66e243118bc20..820761f9eeef92df8929a1517e04e81779148d2c 100644 (file)
@@ -2037,7 +2037,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
 err:
        while ((skb = segs)) {
                segs = skb->next;
-               kfree(skb);
+               kfree_skb(skb);
        }
        return ERR_PTR(err);
 }
index f5c6aca1dfa45557a31ed6f9fe0a9b0d4f109a9f..3282f2f2291b3bcb313e0feaeaa91dea5824622e 100644 (file)
@@ -269,7 +269,7 @@ void dccp_write_xmit(struct sock *sk, int block)
                                         err);
                } else {
                        dccp_pr_debug("packet discarded\n");
-                       kfree(skb);
+                       kfree_skb(skb);
                }
        }
 }
index 30b1e520ad943442fc76f13cc5d3b6d27aa5d657..6b5c64f3c925ea4c90da5ddd4bae50eb1135dc86 100644 (file)
@@ -381,7 +381,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
        if (newsk != NULL) {
                const struct inet_request_sock *ireq = inet_rsk(req);
                struct tcp_request_sock *treq = tcp_rsk(req);
-               struct inet_connection_sock *newicsk = inet_csk(sk);
+               struct inet_connection_sock *newicsk = inet_csk(newsk);
                struct tcp_sock *newtp;
 
                /* Now setup tcp_sock */
index f6ac65d36559cf15825a5e63d0a182cd9a080f6e..e16f1bba5dffd3295200cc8bfa66440e69f7541b 100644 (file)
@@ -400,6 +400,8 @@ static void dev_forward_change(struct inet6_dev *idev)
                        ipv6_dev_mc_dec(dev, &addr);
        }
        for (ifa=idev->addr_list; ifa; ifa=ifa->if_next) {
+               if (ifa->flags&IFA_F_TENTATIVE)
+                       continue;
                if (idev->cnf.forwarding)
                        addrconf_join_anycast(ifa);
                else
index e5ef5979ade417e32d2bc11a41979f7fc0056758..09117d63256f6d92e4b5deebfd8bf6ccdb5230cf 100644 (file)
@@ -461,6 +461,7 @@ static inline struct ifacaddr6 *ac6_get_first(struct seq_file *seq)
                        break;
                }
                read_unlock_bh(&idev->lock);
+               in6_dev_put(idev);
        }
        return im;
 }
diff --git a/net/ipx/ChangeLog b/net/ipx/ChangeLog
deleted file mode 100644 (file)
index 3b29763..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
- Revision 0.21:        Uses the new generic socket option code.
-
- Revision 0.22:        Gcc clean ups and drop out device registration. Use the
-               new multi-protocol edition of hard_header
-
- Revision 0.23: IPX /proc by Mark Evans. Adding a route will
-               will overwrite any existing route to the same network.
-
- Revision 0.24:        Supports new /proc with no 4K limit
-
- Revision 0.25:        Add ephemeral sockets, passive local network
-               identification, support for local net 0 and
-               multiple datalinks <Greg Page>
-
- Revision 0.26: Device drop kills IPX routes via it. (needed for module)
-
- Revision 0.27: Autobind <Mark Evans>
-
- Revision 0.28: Small fix for multiple local networks <Thomas Winder>
-
- Revision 0.29: Assorted major errors removed <Mark Evans>
-               Small correction to promisc mode error fix <Alan Cox>
-               Asynchronous I/O support. Changed to use notifiers
-               and the newer packet_type stuff. Assorted major
-               fixes <Alejandro Liu>
-
- Revision 0.30:        Moved to net/ipx/...    <Alan Cox>
-               Don't set address length on recvfrom that errors.
-               Incorrect verify_area.
-
- Revision 0.31:        New sk_buffs. This still needs a lot of 
-               testing. <Alan Cox>
-
- Revision 0.32: Using sock_alloc_send_skb, firewall hooks. <Alan Cox>
-               Supports sendmsg/recvmsg
-
- Revision 0.33:        Internal network support, routing changes, uses a
-               protocol private area for ipx data.
-
- Revision 0.34:        Module support. <Jim Freeman>
-
- Revision 0.35: Checksum support. <Neil Turton>, hooked in by <Alan Cox>
-               Handles WIN95 discovery packets <Volker Lendecke>
-
- Revision 0.36:        Internal bump up for 2.1
-
- Revision 0.37:        Began adding POSIXisms.
-
- Revision 0.38: Asynchronous socket stuff made current.
-
- Revision 0.39: SPX interfaces
-
- Revision 0.40: Tiny SIOCGSTAMP fix (chris@cybernet.co.nz)
-
- Revision 0.41: 802.2TR removed (p.norton@computer.org)
-               Fixed connecting to primary net,
-               Automatic binding on send & receive,
-               Martijn van Oosterhout <kleptogimp@geocities.com>
-
- Revision 042:  Multithreading - use spinlocks and refcounting to
-               protect some structures: ipx_interface sock list, list
-               of ipx interfaces, etc. 
-               Bugfixes - do refcounting on net_devices, check function
-               results, etc. Thanks to davem and freitag for
-               suggestions and guidance.
-               Arnaldo Carvalho de Melo <acme@conectiva.com.br>,
-               November, 2000
-
- Revision 043: Shared SKBs, don't mangle packets, some cleanups
-               Arnaldo Carvalho de Melo <acme@conectiva.com.br>,
-               December, 2000
-
- Revision 044: Call ipxitf_hold on NETDEV_UP - acme
-
- Revision 045: fix PPROP routing bug - acme
-
- Revision 046: Further fixes to PPROP, ipxitf_create_internal was
-               doing an unneeded MOD_INC_USE_COUNT, implement
-               sysctl for ipx_pprop_broacasting, fix the ipx sysctl
-               handling, making it dynamic, some cleanups, thanks to
-               Petr Vandrovec for review and good suggestions. (acme)
-
- Revision 047: Cleanups, CodingStyle changes, move the ncp connection
-               hack out of line - acme
-
- Revision 048: Use sk->protinfo to store the pointer to IPX private
-               area, remove af_ipx from sk->protinfo and move ipx_opt
-               to include/net/ipx.h, use IPX_SK like DecNET, etc - acme
-
- Revision 049: SPX support dropped, see comment in ipx_create - acme
-
- Revision 050: Use seq_file for proc stuff, moving it to ipx_proc.c - acme
-
-Other fixes:
- Protect the module by a MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT pair. Also, now
- usage count is managed this way:
- -Count one if the auto_interface mode is on
- -Count one per configured interface
- Jacques Gelinas (jacques@solucorp.qc.ca)
index 980a826f5d02e01e75fdefb9e527e9b8890e1176..e9ad0062fbb6a8df3e13182597176016657695b6 100644 (file)
@@ -16,8 +16,7 @@ config IPX
          support", below.
 
          IPX is similar in scope to IP, while SPX, which runs on top of IPX,
-         is similar to TCP. There is also experimental support for SPX in
-         Linux (see "SPX networking", below).
+         is similar to TCP.
 
          To turn your Linux box into a fully featured NetWare file server and
          IPX router, say Y here and fetch either lwared from
@@ -26,9 +25,6 @@ config IPX
          information, read the IPX-HOWTO available from
          <http://www.tldp.org/docs.html#howto>.
 
-         General information about how to connect Linux, Windows machines and
-         Macs is on the WWW at <http://www.eats.com/linux_mac_win.html>.
-
          The IPX driver would enlarge your kernel by about 16 KB. To compile
          this driver as a module, choose M here: the module will be called ipx.
          Unless you want to integrate your Linux box with a local Novell
index 11d504d0ac72068d8c88bc794fe4cb8c1284e3d9..bf23e489e4cdc88eec4a81a8c3461ac2cd5008ee 100644 (file)
@@ -197,13 +197,12 @@ EXPORT_SYMBOL_GPL(nfnetlink_has_listeners);
 
 int nfnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, int echo)
 {
-       gfp_t allocation = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
        int err = 0;
 
        NETLINK_CB(skb).dst_group = group;
        if (echo)
                atomic_inc(&skb->users);
-       netlink_broadcast(nfnl, skb, pid, group, allocation);
+       netlink_broadcast(nfnl, skb, pid, group, gfp_any());
        if (echo)
                err = netlink_unicast(nfnl, skb, pid, MSG_DONTWAIT);
 
index 5bc37181662e5e0a51281093c08d590c199cac2e..b931edee4b8be1c3836a200461915a0ed9d4e8a9 100644 (file)
@@ -173,7 +173,7 @@ static int netlbl_unlabel_list(struct sk_buff *skb, struct genl_info *info)
        return 0;
 
 list_failure:
-       kfree(ans_skb);
+       kfree_skb(ans_skb);
        return ret_val;
 }
 
index 2567453216113fdd5e23a51e856f1a6526abfc7b..956cfe0ff7f82b91067fae393ae9085538ad5972 100644 (file)
@@ -1401,7 +1401,7 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
 
        x = xfrm_state_lookup(&id->daddr, id->spi, id->proto, id->family);
        if (x == NULL) {
-               kfree(r_skb);
+               kfree_skb(r_skb);
                return -ESRCH;
        }
 
@@ -1557,14 +1557,13 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
        struct xfrm_usersa_info *p = &ue->state;
 
        x = xfrm_state_lookup(&p->id.daddr, p->id.spi, p->id.proto, p->family);
-               err = -ENOENT;
 
+       err = -ENOENT;
        if (x == NULL)
                return err;
 
-       err = -EINVAL;
-
        spin_lock_bh(&x->lock);
+       err = -EINVAL;
        if (x->km.state != XFRM_STATE_VALID)
                goto out;
        km_state_expired(x, ue->hard, current->pid);
@@ -1574,6 +1573,7 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
                xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
                               AUDIT_MAC_IPSEC_DELSA, 1, NULL, x);
        }
+       err = 0;
 out:
        spin_unlock_bh(&x->lock);
        xfrm_state_put(x);
index fb43c6440e5484abeeb4d8a2d076fe6d030901ad..8be269ffbf9d4f8159ca7a49a589f879a3d38583 100755 (executable)
@@ -1547,7 +1547,7 @@ sub dump_function($$) {
     $prototype =~ s/^noinline +//;
     $prototype =~ s/__devinit +//;
     $prototype =~ s/^#define\s+//; #ak added
-    $prototype =~ s/__attribute__ \(\([a-z,]*\)\)//;
+    $prototype =~ s/__attribute__\s*\(\([a-z,]*\)\)//;
 
     # Yes, this truly is vile.  We are looking for:
     # 1. Return type (may be nothing if we're looking at a macro)