Merge branch 'for-linus' of git://git.kernel.dk/linux-block
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 9 Mar 2017 23:53:25 +0000 (15:53 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 9 Mar 2017 23:53:25 +0000 (15:53 -0800)
Pull block fixes from Jens Axboe:
 "Sending this a bit sooner than I otherwise would have, as a fix in the
  merge window had some unfortunate issues and side effects for some
  folks.

  This contains:

   - Fixes from Jan for the bdi registration/unregistration. These have
     been tested by the various parties reporting issues, and should be
     solid at this point.

   - Also from Jan, fix for axonram gendisk registration.

   - A stable fix for zram from Johannes.

   - A small series from Ming, fixing up some long standing issues with
     blk-mq hardware queue kobject initialization and registration.

   - A fix for sed opal from Jon, fixing a nonsensical range check and
     some set-but-not-used variables.

   - A fix from Neil for a long standing deadlock issue for stacking
     device drivers. With this in place, dm/md don't have to work around
     the issue anymore, and can be properly fixed up"

* 'for-linus' of git://git.kernel.dk/linux-block:
  axonram: Fix gendisk handling
  blk: improve order of bio handling in generic_make_request()
  Revert "scsi, block: fix duplicate bdi name registration crashes"
  block: Make del_gendisk() safer for disks without queues
  bdi: Fix use-after-free in wb_congested_put()
  block: Allow bdi re-registration
  block/sed: Fix opal user range check and unused variables
  zram: set physical queue limits to avoid array out of bounds accesses
  blk-mq: free hctx->cpumask in release handler of hctx's kobject
  blk-mq: make lifetime consistent between hctx and its kobject
  blk-mq: make lifetime consitent between q/ctx and its kobject
  blk-mq: initialize mq kobjects in blk_mq_init_allocated_queue()

29 files changed:
arch/mips/cavium-octeon/cpu.c
arch/mips/cavium-octeon/crypto/octeon-crypto.c
arch/mips/cavium-octeon/smp.c
arch/mips/include/asm/fpu.h
arch/mips/kernel/smp-bmips.c
arch/mips/kernel/smp-mt.c
arch/mips/loongson64/loongson-3/cop2-ex.c
arch/mips/netlogic/common/smp.c
arch/mips/netlogic/xlp/cop2-ex.c
arch/mips/sgi-ip22/ip28-berr.c
arch/mips/sgi-ip27/ip27-berr.c
arch/mips/sgi-ip27/ip27-smp.c
arch/mips/sgi-ip32/ip32-berr.c
arch/mips/sgi-ip32/ip32-reset.c
arch/x86/pci/xen.c
drivers/gpu/drm/rcar-du/rcar_du_vsp.c
drivers/media/platform/vsp1/vsp1_drm.c
drivers/media/rc/lirc_dev.c
drivers/media/rc/nuvoton-cir.c
drivers/media/rc/rc-main.c
drivers/media/rc/serial_ir.c
drivers/media/usb/dvb-usb/dw2102.c
drivers/xen/xenbus/xenbus_dev_frontend.c
fs/overlayfs/util.c
include/linux/wait.h
include/media/vsp1.h
kernel/sched/wait.c
mm/page_alloc.c
tools/testing/ktest/ktest.pl

index a5b4279..036d56c 100644 (file)
@@ -10,7 +10,9 @@
 #include <linux/irqflags.h>
 #include <linux/notifier.h>
 #include <linux/prefetch.h>
+#include <linux/ptrace.h>
 #include <linux/sched.h>
+#include <linux/sched/task_stack.h>
 
 #include <asm/cop2.h>
 #include <asm/current.h>
index 4d22365..cfb4a14 100644 (file)
@@ -9,6 +9,7 @@
 #include <asm/cop2.h>
 #include <linux/export.h>
 #include <linux/interrupt.h>
+#include <linux/sched/task_stack.h>
 
 #include "octeon-crypto.h"
 
index 4b94b7f..3de7865 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/sched.h>
 #include <linux/sched/hotplug.h>
+#include <linux/sched/task_stack.h>
 #include <linux/init.h>
 #include <linux/export.h>
 
index 321752b..f94455f 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/sched.h>
 #include <linux/sched/task_stack.h>
+#include <linux/ptrace.h>
 #include <linux/thread_info.h>
 #include <linux/bitops.h>
 
index 3daa2ca..1b070a7 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/sched/hotplug.h>
+#include <linux/sched/task_stack.h>
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/smp.h>
index e077ea3..e398cbc 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/interrupt.h>
 #include <linux/irqchip/mips-gic.h>
 #include <linux/compiler.h>
+#include <linux/sched/task_stack.h>
 #include <linux/smp.h>
 
 #include <linux/atomic.h>
index ea13764..621d6af 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/notifier.h>
+#include <linux/ptrace.h>
 
 #include <asm/fpu.h>
 #include <asm/cop2.h>
index 10d86d5..bddf1ef 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/sched/task_stack.h>
 #include <linux/smp.h>
 #include <linux/irq.h>
 
index 52bc5de..21e439b 100644 (file)
@@ -9,11 +9,14 @@
  * Copyright (C) 2009 Wind River Systems,
  *   written by Ralf Baechle <ralf@linux-mips.org>
  */
+#include <linux/capability.h>
 #include <linux/init.h>
 #include <linux/irqflags.h>
 #include <linux/notifier.h>
 #include <linux/prefetch.h>
+#include <linux/ptrace.h>
 #include <linux/sched.h>
+#include <linux/sched/task_stack.h>
 
 #include <asm/cop2.h>
 #include <asm/current.h>
index 1f2a5bc..75460e1 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/sched/debug.h>
+#include <linux/sched/signal.h>
 #include <linux/seq_file.h>
 
 #include <asm/addrspace.h>
index d12879e..83efe03 100644 (file)
@@ -12,7 +12,9 @@
 #include <linux/signal.h>      /* for SIGBUS */
 #include <linux/sched.h>       /* schow_regs(), force_sig() */
 #include <linux/sched/debug.h>
+#include <linux/sched/signal.h>
 
+#include <asm/ptrace.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/arch.h>
 #include <asm/sn/sn0/hub.h>
index f5ed45e..4cd47d2 100644 (file)
@@ -8,10 +8,13 @@
  */
 #include <linux/init.h>
 #include <linux/sched.h>
+#include <linux/sched/task_stack.h>
 #include <linux/topology.h>
 #include <linux/nodemask.h>
+
 #include <asm/page.h>
 #include <asm/processor.h>
+#include <asm/ptrace.h>
 #include <asm/sn/arch.h>
 #include <asm/sn/gda.h>
 #include <asm/sn/intr.h>
index 57d8c74..c1f12a9 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/sched/debug.h>
+#include <linux/sched/signal.h>
 #include <asm/traps.h>
 #include <linux/uaccess.h>
 #include <asm/addrspace.h>
index 8bd415c..b3b442d 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/sched/signal.h>
 #include <linux/notifier.h>
 #include <linux/delay.h>
 #include <linux/rtc/ds1685.h>
index e1fb269..292ab03 100644 (file)
@@ -234,23 +234,14 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
                return 1;
 
        for_each_pci_msi_entry(msidesc, dev) {
-               __pci_read_msi_msg(msidesc, &msg);
-               pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) |
-                       ((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff);
-               if (msg.data != XEN_PIRQ_MSI_DATA ||
-                   xen_irq_from_pirq(pirq) < 0) {
-                       pirq = xen_allocate_pirq_msi(dev, msidesc);
-                       if (pirq < 0) {
-                               irq = -ENODEV;
-                               goto error;
-                       }
-                       xen_msi_compose_msg(dev, pirq, &msg);
-                       __pci_write_msi_msg(msidesc, &msg);
-                       dev_dbg(&dev->dev, "xen: msi bound to pirq=%d\n", pirq);
-               } else {
-                       dev_dbg(&dev->dev,
-                               "xen: msi already bound to pirq=%d\n", pirq);
+               pirq = xen_allocate_pirq_msi(dev, msidesc);
+               if (pirq < 0) {
+                       irq = -ENODEV;
+                       goto error;
                }
+               xen_msi_compose_msg(dev, pirq, &msg);
+               __pci_write_msi_msg(msidesc, &msg);
+               dev_dbg(&dev->dev, "xen: msi bound to pirq=%d\n", pirq);
                irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq,
                                               (type == PCI_CAP_ID_MSI) ? nvec : 1,
                                               (type == PCI_CAP_ID_MSIX) ?
index b5bfbe5..b0ff304 100644 (file)
@@ -32,6 +32,10 @@ void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
 {
        const struct drm_display_mode *mode = &crtc->crtc.state->adjusted_mode;
        struct rcar_du_device *rcdu = crtc->group->dev;
+       struct vsp1_du_lif_config cfg = {
+               .width = mode->hdisplay,
+               .height = mode->vdisplay,
+       };
        struct rcar_du_plane_state state = {
                .state = {
                        .crtc = &crtc->crtc,
@@ -66,12 +70,12 @@ void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
         */
        crtc->group->need_restart = true;
 
-       vsp1_du_setup_lif(crtc->vsp->vsp, mode->hdisplay, mode->vdisplay);
+       vsp1_du_setup_lif(crtc->vsp->vsp, &cfg);
 }
 
 void rcar_du_vsp_disable(struct rcar_du_crtc *crtc)
 {
-       vsp1_du_setup_lif(crtc->vsp->vsp, 0, 0);
+       vsp1_du_setup_lif(crtc->vsp->vsp, NULL);
 }
 
 void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc)
index b4b583f..b4c0f10 100644 (file)
@@ -54,12 +54,11 @@ EXPORT_SYMBOL_GPL(vsp1_du_init);
 /**
  * vsp1_du_setup_lif - Setup the output part of the VSP pipeline
  * @dev: the VSP device
- * @width: output frame width in pixels
- * @height: output frame height in pixels
+ * @cfg: the LIF configuration
  *
- * Configure the output part of VSP DRM pipeline for the given frame @width and
- * @height. This sets up formats on the BRU source pad, the WPF0 sink and source
- * pads, and the LIF sink pad.
+ * Configure the output part of VSP DRM pipeline for the given frame @cfg.width
+ * and @cfg.height. This sets up formats on the BRU source pad, the WPF0 sink
+ * and source pads, and the LIF sink pad.
  *
  * As the media bus code on the BRU source pad is conditioned by the
  * configuration of the BRU sink 0 pad, we also set up the formats on all BRU
@@ -69,8 +68,7 @@ EXPORT_SYMBOL_GPL(vsp1_du_init);
  *
  * Return 0 on success or a negative error code on failure.
  */
-int vsp1_du_setup_lif(struct device *dev, unsigned int width,
-                     unsigned int height)
+int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg)
 {
        struct vsp1_device *vsp1 = dev_get_drvdata(dev);
        struct vsp1_pipeline *pipe = &vsp1->drm->pipe;
@@ -79,11 +77,8 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int width,
        unsigned int i;
        int ret;
 
-       dev_dbg(vsp1->dev, "%s: configuring LIF with format %ux%u\n",
-               __func__, width, height);
-
-       if (width == 0 || height == 0) {
-               /* Zero width or height means the CRTC is being disabled, stop
+       if (!cfg) {
+               /* NULL configuration means the CRTC is being disabled, stop
                 * the pipeline and turn the light off.
                 */
                ret = vsp1_pipeline_stop(pipe);
@@ -108,6 +103,9 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int width,
                return 0;
        }
 
+       dev_dbg(vsp1->dev, "%s: configuring LIF with format %ux%u\n",
+               __func__, cfg->width, cfg->height);
+
        /* Configure the format at the BRU sinks and propagate it through the
         * pipeline.
         */
@@ -117,8 +115,8 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int width,
        for (i = 0; i < bru->entity.source_pad; ++i) {
                format.pad = i;
 
-               format.format.width = width;
-               format.format.height = height;
+               format.format.width = cfg->width;
+               format.format.height = cfg->height;
                format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
                format.format.field = V4L2_FIELD_NONE;
 
@@ -133,8 +131,8 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int width,
        }
 
        format.pad = bru->entity.source_pad;
-       format.format.width = width;
-       format.format.height = height;
+       format.format.width = cfg->width;
+       format.format.height = cfg->height;
        format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
        format.format.field = V4L2_FIELD_NONE;
 
@@ -180,7 +178,8 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int width,
        /* Verify that the format at the output of the pipeline matches the
         * requested frame size and media bus code.
         */
-       if (format.format.width != width || format.format.height != height ||
+       if (format.format.width != cfg->width ||
+           format.format.height != cfg->height ||
            format.format.code != MEDIA_BUS_FMT_ARGB8888_1X32) {
                dev_dbg(vsp1->dev, "%s: format mismatch\n", __func__);
                return -EPIPE;
index 393dcca..1688893 100644 (file)
@@ -436,6 +436,8 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file)
                return -ERESTARTSYS;
 
        ir = irctls[iminor(inode)];
+       mutex_unlock(&lirc_dev_lock);
+
        if (!ir) {
                retval = -ENODEV;
                goto error;
@@ -476,8 +478,6 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file)
        }
 
 error:
-       mutex_unlock(&lirc_dev_lock);
-
        nonseekable_open(inode, file);
 
        return retval;
index b109f82..ec4b25b 100644 (file)
@@ -176,12 +176,13 @@ static void nvt_write_wakeup_codes(struct rc_dev *dev,
 {
        u8 tolerance, config;
        struct nvt_dev *nvt = dev->priv;
+       unsigned long flags;
        int i;
 
        /* hardcode the tolerance to 10% */
        tolerance = DIV_ROUND_UP(count, 10);
 
-       spin_lock(&nvt->lock);
+       spin_lock_irqsave(&nvt->lock, flags);
 
        nvt_clear_cir_wake_fifo(nvt);
        nvt_cir_wake_reg_write(nvt, count, CIR_WAKE_FIFO_CMP_DEEP);
@@ -203,7 +204,7 @@ static void nvt_write_wakeup_codes(struct rc_dev *dev,
 
        nvt_cir_wake_reg_write(nvt, config, CIR_WAKE_IRCON);
 
-       spin_unlock(&nvt->lock);
+       spin_unlock_irqrestore(&nvt->lock, flags);
 }
 
 static ssize_t wakeup_data_show(struct device *dev,
index 2424946..d845336 100644 (file)
@@ -1663,6 +1663,7 @@ static int rc_setup_rx_device(struct rc_dev *dev)
 {
        int rc;
        struct rc_map *rc_map;
+       u64 rc_type;
 
        if (!dev->map_name)
                return -EINVAL;
@@ -1677,15 +1678,18 @@ static int rc_setup_rx_device(struct rc_dev *dev)
        if (rc)
                return rc;
 
-       if (dev->change_protocol) {
-               u64 rc_type = (1ll << rc_map->rc_type);
+       rc_type = BIT_ULL(rc_map->rc_type);
 
+       if (dev->change_protocol) {
                rc = dev->change_protocol(dev, &rc_type);
                if (rc < 0)
                        goto out_table;
                dev->enabled_protocols = rc_type;
        }
 
+       if (dev->driver_type == RC_DRIVER_IR_RAW)
+               ir_raw_load_modules(&rc_type);
+
        set_bit(EV_KEY, dev->input_dev->evbit);
        set_bit(EV_REP, dev->input_dev->evbit);
        set_bit(EV_MSC, dev->input_dev->evbit);
@@ -1777,12 +1781,6 @@ int rc_register_device(struct rc_dev *dev)
                dev->input_name ?: "Unspecified device", path ?: "N/A");
        kfree(path);
 
-       if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
-               rc = rc_setup_rx_device(dev);
-               if (rc)
-                       goto out_dev;
-       }
-
        if (dev->driver_type == RC_DRIVER_IR_RAW ||
            dev->driver_type == RC_DRIVER_IR_RAW_TX) {
                if (!raw_init) {
@@ -1791,7 +1789,13 @@ int rc_register_device(struct rc_dev *dev)
                }
                rc = ir_raw_event_register(dev);
                if (rc < 0)
-                       goto out_rx;
+                       goto out_dev;
+       }
+
+       if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
+               rc = rc_setup_rx_device(dev);
+               if (rc)
+                       goto out_raw;
        }
 
        /* Allow the RC sysfs nodes to be accessible */
@@ -1803,8 +1807,8 @@ int rc_register_device(struct rc_dev *dev)
 
        return 0;
 
-out_rx:
-       rc_free_rx_device(dev);
+out_raw:
+       ir_raw_event_unregister(dev);
 out_dev:
        device_del(&dev->dev);
 out_unlock:
index 923fb22..41b54e4 100644 (file)
@@ -487,10 +487,69 @@ static void serial_ir_timeout(unsigned long arg)
        ir_raw_event_handle(serial_ir.rcdev);
 }
 
+/* Needed by serial_ir_probe() */
+static int serial_ir_tx(struct rc_dev *dev, unsigned int *txbuf,
+                       unsigned int count);
+static int serial_ir_tx_duty_cycle(struct rc_dev *dev, u32 cycle);
+static int serial_ir_tx_carrier(struct rc_dev *dev, u32 carrier);
+static int serial_ir_open(struct rc_dev *rcdev);
+static void serial_ir_close(struct rc_dev *rcdev);
+
 static int serial_ir_probe(struct platform_device *dev)
 {
+       struct rc_dev *rcdev;
        int i, nlow, nhigh, result;
 
+       rcdev = devm_rc_allocate_device(&dev->dev, RC_DRIVER_IR_RAW);
+       if (!rcdev)
+               return -ENOMEM;
+
+       if (hardware[type].send_pulse && hardware[type].send_space)
+               rcdev->tx_ir = serial_ir_tx;
+       if (hardware[type].set_send_carrier)
+               rcdev->s_tx_carrier = serial_ir_tx_carrier;
+       if (hardware[type].set_duty_cycle)
+               rcdev->s_tx_duty_cycle = serial_ir_tx_duty_cycle;
+
+       switch (type) {
+       case IR_HOMEBREW:
+               rcdev->input_name = "Serial IR type home-brew";
+               break;
+       case IR_IRDEO:
+               rcdev->input_name = "Serial IR type IRdeo";
+               break;
+       case IR_IRDEO_REMOTE:
+               rcdev->input_name = "Serial IR type IRdeo remote";
+               break;
+       case IR_ANIMAX:
+               rcdev->input_name = "Serial IR type AnimaX";
+               break;
+       case IR_IGOR:
+               rcdev->input_name = "Serial IR type IgorPlug";
+               break;
+       }
+
+       rcdev->input_phys = KBUILD_MODNAME "/input0";
+       rcdev->input_id.bustype = BUS_HOST;
+       rcdev->input_id.vendor = 0x0001;
+       rcdev->input_id.product = 0x0001;
+       rcdev->input_id.version = 0x0100;
+       rcdev->open = serial_ir_open;
+       rcdev->close = serial_ir_close;
+       rcdev->dev.parent = &serial_ir.pdev->dev;
+       rcdev->allowed_protocols = RC_BIT_ALL_IR_DECODER;
+       rcdev->driver_name = KBUILD_MODNAME;
+       rcdev->map_name = RC_MAP_RC6_MCE;
+       rcdev->min_timeout = 1;
+       rcdev->timeout = IR_DEFAULT_TIMEOUT;
+       rcdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT;
+       rcdev->rx_resolution = 250000;
+
+       serial_ir.rcdev = rcdev;
+
+       setup_timer(&serial_ir.timeout_timer, serial_ir_timeout,
+                   (unsigned long)&serial_ir);
+
        result = devm_request_irq(&dev->dev, irq, serial_ir_irq_handler,
                                  share_irq ? IRQF_SHARED : 0,
                                  KBUILD_MODNAME, &hardware);
@@ -516,9 +575,6 @@ static int serial_ir_probe(struct platform_device *dev)
                return -EBUSY;
        }
 
-       setup_timer(&serial_ir.timeout_timer, serial_ir_timeout,
-                   (unsigned long)&serial_ir);
-
        result = hardware_init_port();
        if (result < 0)
                return result;
@@ -552,7 +608,8 @@ static int serial_ir_probe(struct platform_device *dev)
                         sense ? "low" : "high");
 
        dev_dbg(&dev->dev, "Interrupt %d, port %04x obtained\n", irq, io);
-       return 0;
+
+       return devm_rc_register_device(&dev->dev, rcdev);
 }
 
 static int serial_ir_open(struct rc_dev *rcdev)
@@ -723,7 +780,6 @@ static void serial_ir_exit(void)
 
 static int __init serial_ir_init_module(void)
 {
-       struct rc_dev *rcdev;
        int result;
 
        switch (type) {
@@ -754,63 +810,9 @@ static int __init serial_ir_init_module(void)
                sense = !!sense;
 
        result = serial_ir_init();
-       if (result)
-               return result;
-
-       rcdev = devm_rc_allocate_device(&serial_ir.pdev->dev, RC_DRIVER_IR_RAW);
-       if (!rcdev) {
-               result = -ENOMEM;
-               goto serial_cleanup;
-       }
-
-       if (hardware[type].send_pulse && hardware[type].send_space)
-               rcdev->tx_ir = serial_ir_tx;
-       if (hardware[type].set_send_carrier)
-               rcdev->s_tx_carrier = serial_ir_tx_carrier;
-       if (hardware[type].set_duty_cycle)
-               rcdev->s_tx_duty_cycle = serial_ir_tx_duty_cycle;
-
-       switch (type) {
-       case IR_HOMEBREW:
-               rcdev->input_name = "Serial IR type home-brew";
-               break;
-       case IR_IRDEO:
-               rcdev->input_name = "Serial IR type IRdeo";
-               break;
-       case IR_IRDEO_REMOTE:
-               rcdev->input_name = "Serial IR type IRdeo remote";
-               break;
-       case IR_ANIMAX:
-               rcdev->input_name = "Serial IR type AnimaX";
-               break;
-       case IR_IGOR:
-               rcdev->input_name = "Serial IR type IgorPlug";
-               break;
-       }
-
-       rcdev->input_phys = KBUILD_MODNAME "/input0";
-       rcdev->input_id.bustype = BUS_HOST;
-       rcdev->input_id.vendor = 0x0001;
-       rcdev->input_id.product = 0x0001;
-       rcdev->input_id.version = 0x0100;
-       rcdev->open = serial_ir_open;
-       rcdev->close = serial_ir_close;
-       rcdev->dev.parent = &serial_ir.pdev->dev;
-       rcdev->allowed_protocols = RC_BIT_ALL_IR_DECODER;
-       rcdev->driver_name = KBUILD_MODNAME;
-       rcdev->map_name = RC_MAP_RC6_MCE;
-       rcdev->min_timeout = 1;
-       rcdev->timeout = IR_DEFAULT_TIMEOUT;
-       rcdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT;
-       rcdev->rx_resolution = 250000;
-
-       serial_ir.rcdev = rcdev;
-
-       result = rc_register_device(rcdev);
-
        if (!result)
                return 0;
-serial_cleanup:
+
        serial_ir_exit();
        return result;
 }
@@ -818,7 +820,6 @@ serial_cleanup:
 static void __exit serial_ir_exit_module(void)
 {
        del_timer_sync(&serial_ir.timeout_timer);
-       rc_unregister_device(serial_ir.rcdev);
        serial_ir_exit();
 }
 
index 6ca502d..4f42d57 100644 (file)
@@ -68,6 +68,7 @@
 struct dw2102_state {
        u8 initialized;
        u8 last_lock;
+       u8 data[MAX_XFER_SIZE + 4];
        struct i2c_client *i2c_client_demod;
        struct i2c_client *i2c_client_tuner;
 
@@ -661,62 +662,72 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
                                                                int num)
 {
        struct dvb_usb_device *d = i2c_get_adapdata(adap);
-       u8 obuf[0x40], ibuf[0x40];
+       struct dw2102_state *state;
 
        if (!d)
                return -ENODEV;
+
+       state = d->priv;
+
        if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
                return -EAGAIN;
+       if (mutex_lock_interruptible(&d->data_mutex) < 0) {
+               mutex_unlock(&d->i2c_mutex);
+               return -EAGAIN;
+       }
 
        switch (num) {
        case 1:
                switch (msg[0].addr) {
                case SU3000_STREAM_CTRL:
-                       obuf[0] = msg[0].buf[0] + 0x36;
-                       obuf[1] = 3;
-                       obuf[2] = 0;
-                       if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 0, 0) < 0)
+                       state->data[0] = msg[0].buf[0] + 0x36;
+                       state->data[1] = 3;
+                       state->data[2] = 0;
+                       if (dvb_usb_generic_rw(d, state->data, 3,
+                                       state->data, 0, 0) < 0)
                                err("i2c transfer failed.");
                        break;
                case DW2102_RC_QUERY:
-                       obuf[0] = 0x10;
-                       if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 2, 0) < 0)
+                       state->data[0] = 0x10;
+                       if (dvb_usb_generic_rw(d, state->data, 1,
+                                       state->data, 2, 0) < 0)
                                err("i2c transfer failed.");
-                       msg[0].buf[1] = ibuf[0];
-                       msg[0].buf[0] = ibuf[1];
+                       msg[0].buf[1] = state->data[0];
+                       msg[0].buf[0] = state->data[1];
                        break;
                default:
                        /* always i2c write*/
-                       obuf[0] = 0x08;
-                       obuf[1] = msg[0].addr;
-                       obuf[2] = msg[0].len;
+                       state->data[0] = 0x08;
+                       state->data[1] = msg[0].addr;
+                       state->data[2] = msg[0].len;
 
-                       memcpy(&obuf[3], msg[0].buf, msg[0].len);
+                       memcpy(&state->data[3], msg[0].buf, msg[0].len);
 
-                       if (dvb_usb_generic_rw(d, obuf, msg[0].len + 3,
-                                               ibuf, 1, 0) < 0)
+                       if (dvb_usb_generic_rw(d, state->data, msg[0].len + 3,
+                                               state->data, 1, 0) < 0)
                                err("i2c transfer failed.");
 
                }
                break;
        case 2:
                /* always i2c read */
-               obuf[0] = 0x09;
-               obuf[1] = msg[0].len;
-               obuf[2] = msg[1].len;
-               obuf[3] = msg[0].addr;
-               memcpy(&obuf[4], msg[0].buf, msg[0].len);
-
-               if (dvb_usb_generic_rw(d, obuf, msg[0].len + 4,
-                                       ibuf, msg[1].len + 1, 0) < 0)
+               state->data[0] = 0x09;
+               state->data[1] = msg[0].len;
+               state->data[2] = msg[1].len;
+               state->data[3] = msg[0].addr;
+               memcpy(&state->data[4], msg[0].buf, msg[0].len);
+
+               if (dvb_usb_generic_rw(d, state->data, msg[0].len + 4,
+                                       state->data, msg[1].len + 1, 0) < 0)
                        err("i2c transfer failed.");
 
-               memcpy(msg[1].buf, &ibuf[1], msg[1].len);
+               memcpy(msg[1].buf, &state->data[1], msg[1].len);
                break;
        default:
                warn("more than 2 i2c messages at a time is not handled yet.");
                break;
        }
+       mutex_unlock(&d->data_mutex);
        mutex_unlock(&d->i2c_mutex);
        return num;
 }
@@ -844,17 +855,23 @@ static int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 static int su3000_power_ctrl(struct dvb_usb_device *d, int i)
 {
        struct dw2102_state *state = (struct dw2102_state *)d->priv;
-       u8 obuf[] = {0xde, 0};
+       int ret = 0;
 
        info("%s: %d, initialized %d", __func__, i, state->initialized);
 
        if (i && !state->initialized) {
+               mutex_lock(&d->data_mutex);
+
+               state->data[0] = 0xde;
+               state->data[1] = 0;
+
                state->initialized = 1;
                /* reset board */
-               return dvb_usb_generic_rw(d, obuf, 2, NULL, 0, 0);
+               ret = dvb_usb_generic_rw(d, state->data, 2, NULL, 0, 0);
+               mutex_unlock(&d->data_mutex);
        }
 
-       return 0;
+       return ret;
 }
 
 static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
@@ -1309,49 +1326,57 @@ static int prof_7500_frontend_attach(struct dvb_usb_adapter *d)
        return 0;
 }
 
-static int su3000_frontend_attach(struct dvb_usb_adapter *d)
+static int su3000_frontend_attach(struct dvb_usb_adapter *adap)
 {
-       u8 obuf[3] = { 0xe, 0x80, 0 };
-       u8 ibuf[] = { 0 };
+       struct dvb_usb_device *d = adap->dev;
+       struct dw2102_state *state = d->priv;
+
+       mutex_lock(&d->data_mutex);
+
+       state->data[0] = 0xe;
+       state->data[1] = 0x80;
+       state->data[2] = 0;
 
-       if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
+       if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
                err("command 0x0e transfer failed.");
 
-       obuf[0] = 0xe;
-       obuf[1] = 0x02;
-       obuf[2] = 1;
+       state->data[0] = 0xe;
+       state->data[1] = 0x02;
+       state->data[2] = 1;
 
-       if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
+       if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
                err("command 0x0e transfer failed.");
        msleep(300);
 
-       obuf[0] = 0xe;
-       obuf[1] = 0x83;
-       obuf[2] = 0;
+       state->data[0] = 0xe;
+       state->data[1] = 0x83;
+       state->data[2] = 0;
 
-       if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
+       if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
                err("command 0x0e transfer failed.");
 
-       obuf[0] = 0xe;
-       obuf[1] = 0x83;
-       obuf[2] = 1;
+       state->data[0] = 0xe;
+       state->data[1] = 0x83;
+       state->data[2] = 1;
 
-       if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
+       if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
                err("command 0x0e transfer failed.");
 
-       obuf[0] = 0x51;
+       state->data[0] = 0x51;
 
-       if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
+       if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)
                err("command 0x51 transfer failed.");
 
-       d->fe_adap[0].fe = dvb_attach(ds3000_attach, &su3000_ds3000_config,
-                                       &d->dev->i2c_adap);
-       if (d->fe_adap[0].fe == NULL)
+       mutex_unlock(&d->data_mutex);
+
+       adap->fe_adap[0].fe = dvb_attach(ds3000_attach, &su3000_ds3000_config,
+                                       &d->i2c_adap);
+       if (adap->fe_adap[0].fe == NULL)
                return -EIO;
 
-       if (dvb_attach(ts2020_attach, d->fe_adap[0].fe,
+       if (dvb_attach(ts2020_attach, adap->fe_adap[0].fe,
                                &dw2104_ts2020_config,
-                               &d->dev->i2c_adap)) {
+                               &d->i2c_adap)) {
                info("Attached DS3000/TS2020!");
                return 0;
        }
@@ -1360,47 +1385,55 @@ static int su3000_frontend_attach(struct dvb_usb_adapter *d)
        return -EIO;
 }
 
-static int t220_frontend_attach(struct dvb_usb_adapter *d)
+static int t220_frontend_attach(struct dvb_usb_adapter *adap)
 {
-       u8 obuf[3] = { 0xe, 0x87, 0 };
-       u8 ibuf[] = { 0 };
+       struct dvb_usb_device *d = adap->dev;
+       struct dw2102_state *state = d->priv;
+
+       mutex_lock(&d->data_mutex);
 
-       if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
+       state->data[0] = 0xe;
+       state->data[1] = 0x87;
+       state->data[2] = 0x0;
+
+       if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
                err("command 0x0e transfer failed.");
 
-       obuf[0] = 0xe;
-       obuf[1] = 0x86;
-       obuf[2] = 1;
+       state->data[0] = 0xe;
+       state->data[1] = 0x86;
+       state->data[2] = 1;
 
-       if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
+       if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
                err("command 0x0e transfer failed.");
 
-       obuf[0] = 0xe;
-       obuf[1] = 0x80;
-       obuf[2] = 0;
+       state->data[0] = 0xe;
+       state->data[1] = 0x80;
+       state->data[2] = 0;
 
-       if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
+       if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
                err("command 0x0e transfer failed.");
 
        msleep(50);
 
-       obuf[0] = 0xe;
-       obuf[1] = 0x80;
-       obuf[2] = 1;
+       state->data[0] = 0xe;
+       state->data[1] = 0x80;
+       state->data[2] = 1;
 
-       if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
+       if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
                err("command 0x0e transfer failed.");
 
-       obuf[0] = 0x51;
+       state->data[0] = 0x51;
 
-       if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
+       if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)
                err("command 0x51 transfer failed.");
 
-       d->fe_adap[0].fe = dvb_attach(cxd2820r_attach, &cxd2820r_config,
-                                       &d->dev->i2c_adap, NULL);
-       if (d->fe_adap[0].fe != NULL) {
-               if (dvb_attach(tda18271_attach, d->fe_adap[0].fe, 0x60,
-                                       &d->dev->i2c_adap, &tda18271_config)) {
+       mutex_unlock(&d->data_mutex);
+
+       adap->fe_adap[0].fe = dvb_attach(cxd2820r_attach, &cxd2820r_config,
+                                       &d->i2c_adap, NULL);
+       if (adap->fe_adap[0].fe != NULL) {
+               if (dvb_attach(tda18271_attach, adap->fe_adap[0].fe, 0x60,
+                                       &d->i2c_adap, &tda18271_config)) {
                        info("Attached TDA18271HD/CXD2820R!");
                        return 0;
                }
@@ -1410,23 +1443,30 @@ static int t220_frontend_attach(struct dvb_usb_adapter *d)
        return -EIO;
 }
 
-static int m88rs2000_frontend_attach(struct dvb_usb_adapter *d)
+static int m88rs2000_frontend_attach(struct dvb_usb_adapter *adap)
 {
-       u8 obuf[] = { 0x51 };
-       u8 ibuf[] = { 0 };
+       struct dvb_usb_device *d = adap->dev;
+       struct dw2102_state *state = d->priv;
+
+       mutex_lock(&d->data_mutex);
 
-       if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
+       state->data[0] = 0x51;
+
+       if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)
                err("command 0x51 transfer failed.");
 
-       d->fe_adap[0].fe = dvb_attach(m88rs2000_attach, &s421_m88rs2000_config,
-                                       &d->dev->i2c_adap);
+       mutex_unlock(&d->data_mutex);
 
-       if (d->fe_adap[0].fe == NULL)
+       adap->fe_adap[0].fe = dvb_attach(m88rs2000_attach,
+                                       &s421_m88rs2000_config,
+                                       &d->i2c_adap);
+
+       if (adap->fe_adap[0].fe == NULL)
                return -EIO;
 
-       if (dvb_attach(ts2020_attach, d->fe_adap[0].fe,
+       if (dvb_attach(ts2020_attach, adap->fe_adap[0].fe,
                                &dw2104_ts2020_config,
-                               &d->dev->i2c_adap)) {
+                               &d->i2c_adap)) {
                info("Attached RS2000/TS2020!");
                return 0;
        }
@@ -1439,44 +1479,50 @@ static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap)
 {
        struct dvb_usb_device *d = adap->dev;
        struct dw2102_state *state = d->priv;
-       u8 obuf[3] = { 0xe, 0x80, 0 };
-       u8 ibuf[] = { 0 };
        struct i2c_adapter *i2c_adapter;
        struct i2c_client *client;
        struct i2c_board_info board_info;
        struct m88ds3103_platform_data m88ds3103_pdata = {};
        struct ts2020_config ts2020_config = {};
 
-       if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0)
+       mutex_lock(&d->data_mutex);
+
+       state->data[0] = 0xe;
+       state->data[1] = 0x80;
+       state->data[2] = 0x0;
+
+       if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
                err("command 0x0e transfer failed.");
 
-       obuf[0] = 0xe;
-       obuf[1] = 0x02;
-       obuf[2] = 1;
+       state->data[0] = 0xe;
+       state->data[1] = 0x02;
+       state->data[2] = 1;
 
-       if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0)
+       if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
                err("command 0x0e transfer failed.");
        msleep(300);
 
-       obuf[0] = 0xe;
-       obuf[1] = 0x83;
-       obuf[2] = 0;
+       state->data[0] = 0xe;
+       state->data[1] = 0x83;
+       state->data[2] = 0;
 
-       if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0)
+       if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
                err("command 0x0e transfer failed.");
 
-       obuf[0] = 0xe;
-       obuf[1] = 0x83;
-       obuf[2] = 1;
+       state->data[0] = 0xe;
+       state->data[1] = 0x83;
+       state->data[2] = 1;
 
-       if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0)
+       if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
                err("command 0x0e transfer failed.");
 
-       obuf[0] = 0x51;
+       state->data[0] = 0x51;
 
-       if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 1, 0) < 0)
+       if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)
                err("command 0x51 transfer failed.");
 
+       mutex_unlock(&d->data_mutex);
+
        /* attach demod */
        m88ds3103_pdata.clk = 27000000;
        m88ds3103_pdata.i2c_wr_max = 33;
index 4d343ee..1f4733b 100644 (file)
@@ -55,7 +55,6 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/miscdevice.h>
-#include <linux/init.h>
 
 #include <xen/xenbus.h>
 #include <xen/xen.h>
index 1953986..6e610a2 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/slab.h>
 #include <linux/cred.h>
 #include <linux/xattr.h>
-#include <linux/sched/signal.h>
 #include "overlayfs.h"
 #include "ovl_entry.h"
 
index aacb128..db076ca 100644 (file)
@@ -620,30 +620,19 @@ do {                                                                      \
        __ret;                                                          \
 })
 
+extern int do_wait_intr(wait_queue_head_t *, wait_queue_t *);
+extern int do_wait_intr_irq(wait_queue_head_t *, wait_queue_t *);
 
-#define __wait_event_interruptible_locked(wq, condition, exclusive, irq) \
+#define __wait_event_interruptible_locked(wq, condition, exclusive, fn) \
 ({                                                                     \
-       int __ret = 0;                                                  \
+       int __ret;                                                      \
        DEFINE_WAIT(__wait);                                            \
        if (exclusive)                                                  \
                __wait.flags |= WQ_FLAG_EXCLUSIVE;                      \
        do {                                                            \
-               if (likely(list_empty(&__wait.task_list)))              \
-                       __add_wait_queue_tail(&(wq), &__wait);          \
-               set_current_state(TASK_INTERRUPTIBLE);                  \
-               if (signal_pending(current)) {                          \
-                       __ret = -ERESTARTSYS;                           \
+               __ret = fn(&(wq), &__wait);                             \
+               if (__ret)                                              \
                        break;                                          \
-               }                                                       \
-               if (irq)                                                \
-                       spin_unlock_irq(&(wq).lock);                    \
-               else                                                    \
-                       spin_unlock(&(wq).lock);                        \
-               schedule();                                             \
-               if (irq)                                                \
-                       spin_lock_irq(&(wq).lock);                      \
-               else                                                    \
-                       spin_lock(&(wq).lock);                          \
        } while (!(condition));                                         \
        __remove_wait_queue(&(wq), &__wait);                            \
        __set_current_state(TASK_RUNNING);                              \
@@ -676,7 +665,7 @@ do {                                                                        \
  */
 #define wait_event_interruptible_locked(wq, condition)                 \
        ((condition)                                                    \
-        ? 0 : __wait_event_interruptible_locked(wq, condition, 0, 0))
+        ? 0 : __wait_event_interruptible_locked(wq, condition, 0, do_wait_intr))
 
 /**
  * wait_event_interruptible_locked_irq - sleep until a condition gets true
@@ -703,7 +692,7 @@ do {                                                                        \
  */
 #define wait_event_interruptible_locked_irq(wq, condition)             \
        ((condition)                                                    \
-        ? 0 : __wait_event_interruptible_locked(wq, condition, 0, 1))
+        ? 0 : __wait_event_interruptible_locked(wq, condition, 0, do_wait_intr_irq))
 
 /**
  * wait_event_interruptible_exclusive_locked - sleep exclusively until a condition gets true
@@ -734,7 +723,7 @@ do {                                                                        \
  */
 #define wait_event_interruptible_exclusive_locked(wq, condition)       \
        ((condition)                                                    \
-        ? 0 : __wait_event_interruptible_locked(wq, condition, 1, 0))
+        ? 0 : __wait_event_interruptible_locked(wq, condition, 1, do_wait_intr))
 
 /**
  * wait_event_interruptible_exclusive_locked_irq - sleep until a condition gets true
@@ -765,7 +754,7 @@ do {                                                                        \
  */
 #define wait_event_interruptible_exclusive_locked_irq(wq, condition)   \
        ((condition)                                                    \
-        ? 0 : __wait_event_interruptible_locked(wq, condition, 1, 1))
+        ? 0 : __wait_event_interruptible_locked(wq, condition, 1, do_wait_intr_irq))
 
 
 #define __wait_event_killable(wq, condition)                           \
index 458b400..38aac55 100644 (file)
@@ -20,8 +20,17 @@ struct device;
 
 int vsp1_du_init(struct device *dev);
 
-int vsp1_du_setup_lif(struct device *dev, unsigned int width,
-                     unsigned int height);
+/**
+ * struct vsp1_du_lif_config - VSP LIF configuration
+ * @width: output frame width
+ * @height: output frame height
+ */
+struct vsp1_du_lif_config {
+       unsigned int width;
+       unsigned int height;
+};
+
+int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg);
 
 struct vsp1_du_atomic_config {
        u32 pixelformat;
index 4d2ea6f..b8c84c6 100644 (file)
@@ -242,6 +242,45 @@ long prepare_to_wait_event(wait_queue_head_t *q, wait_queue_t *wait, int state)
 }
 EXPORT_SYMBOL(prepare_to_wait_event);
 
+/*
+ * Note! These two wait functions are entered with the
+ * wait-queue lock held (and interrupts off in the _irq
+ * case), so there is no race with testing the wakeup
+ * condition in the caller before they add the wait
+ * entry to the wake queue.
+ */
+int do_wait_intr(wait_queue_head_t *wq, wait_queue_t *wait)
+{
+       if (likely(list_empty(&wait->task_list)))
+               __add_wait_queue_tail(wq, wait);
+
+       set_current_state(TASK_INTERRUPTIBLE);
+       if (signal_pending(current))
+               return -ERESTARTSYS;
+
+       spin_unlock(&wq->lock);
+       schedule();
+       spin_lock(&wq->lock);
+       return 0;
+}
+EXPORT_SYMBOL(do_wait_intr);
+
+int do_wait_intr_irq(wait_queue_head_t *wq, wait_queue_t *wait)
+{
+       if (likely(list_empty(&wait->task_list)))
+               __add_wait_queue_tail(wq, wait);
+
+       set_current_state(TASK_INTERRUPTIBLE);
+       if (signal_pending(current))
+               return -ERESTARTSYS;
+
+       spin_unlock_irq(&wq->lock);
+       schedule();
+       spin_lock_irq(&wq->lock);
+       return 0;
+}
+EXPORT_SYMBOL(do_wait_intr_irq);
+
 /**
  * finish_wait - clean up after waiting in a queue
  * @q: waitqueue waited on
index eaa64d2..6cbde31 100644 (file)
@@ -873,7 +873,8 @@ done_merging:
                higher_page = page + (combined_pfn - pfn);
                buddy_pfn = __find_buddy_pfn(combined_pfn, order + 1);
                higher_buddy = higher_page + (buddy_pfn - combined_pfn);
-               if (page_is_buddy(higher_page, higher_buddy, order + 1)) {
+               if (pfn_valid_within(buddy_pfn) &&
+                   page_is_buddy(higher_page, higher_buddy, order + 1)) {
                        list_add_tail(&page->lru,
                                &zone->free_area[order].free_list[migratetype]);
                        goto out;
index 6e4eb2f..0c8b61f 100755 (executable)
@@ -1880,6 +1880,7 @@ sub get_grub_index {
 sub wait_for_input
 {
     my ($fp, $time) = @_;
+    my $start_time;
     my $rin;
     my $rout;
     my $nr;
@@ -1895,17 +1896,22 @@ sub wait_for_input
     vec($rin, fileno($fp), 1) = 1;
     vec($rin, fileno(\*STDIN), 1) = 1;
 
+    $start_time = time;
+
     while (1) {
        $nr = select($rout=$rin, undef, undef, $time);
 
-       if ($nr <= 0) {
-           return undef;
-       }
+       last if ($nr <= 0);
 
        # copy data from stdin to the console
        if (vec($rout, fileno(\*STDIN), 1) == 1) {
-           sysread(\*STDIN, $buf, 1000);
-           syswrite($fp, $buf, 1000);
+           $nr = sysread(\*STDIN, $buf, 1000);
+           syswrite($fp, $buf, $nr) if ($nr > 0);
+       }
+
+       # The timeout is based on time waiting for the fp data
+       if (vec($rout, fileno($fp), 1) != 1) {
+           last if (defined($time) && (time - $start_time > $time));
            next;
        }
 
@@ -1917,12 +1923,11 @@ sub wait_for_input
            last if ($ch eq "\n");
        }
 
-       if (!length($line)) {
-           return undef;
-       }
+       last if (!length($line));
 
        return $line;
     }
+    return undef;
 }
 
 sub reboot_to {