Merge 4.4-rc5 into staging-next
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Dec 2015 03:23:01 +0000 (19:23 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Dec 2015 03:23:01 +0000 (19:23 -0800)
We want those fixes in here for testing.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1  2 
drivers/iio/dummy/iio_simple_dummy_events.c
drivers/iio/industrialio-buffer.c
drivers/iio/industrialio-core.c
drivers/iio/proximity/pulsedlight-lidar-lite-v2.c
drivers/staging/lustre/lustre/libcfs/module.c
drivers/staging/lustre/lustre/obdecho/echo_client.c

index bfbf1c56bd22630e19ac739eadd514157071ab2b,0000000000000000000000000000000000000000..6eb600ff70569ef6ceb902afcc49ddce08b09953
mode 100644,000000..100644
--- /dev/null
@@@ -1,276 -1,0 +1,276 @@@
-       return IRQ_HANDLED;
 +/**
 + * Copyright (c) 2011 Jonathan Cameron
 + *
 + * This program is free software; you can redistribute it and/or modify it
 + * under the terms of the GNU General Public License version 2 as published by
 + * the Free Software Foundation.
 + *
 + * Event handling elements of industrial I/O reference driver.
 + */
 +#include <linux/kernel.h>
 +#include <linux/slab.h>
 +#include <linux/interrupt.h>
 +#include <linux/irq.h>
 +
 +#include <linux/iio/iio.h>
 +#include <linux/iio/sysfs.h>
 +#include <linux/iio/events.h>
 +#include "iio_simple_dummy.h"
 +
 +/* Evgen 'fakes' interrupt events for this example */
 +#include "iio_dummy_evgen.h"
 +
 +/**
 + * iio_simple_dummy_read_event_config() - is event enabled?
 + * @indio_dev: the device instance data
 + * @chan: channel for the event whose state is being queried
 + * @type: type of the event whose state is being queried
 + * @dir: direction of the vent whose state is being queried
 + *
 + * This function would normally query the relevant registers or a cache to
 + * discover if the event generation is enabled on the device.
 + */
 +int iio_simple_dummy_read_event_config(struct iio_dev *indio_dev,
 +                                     const struct iio_chan_spec *chan,
 +                                     enum iio_event_type type,
 +                                     enum iio_event_direction dir)
 +{
 +      struct iio_dummy_state *st = iio_priv(indio_dev);
 +
 +      return st->event_en;
 +}
 +
 +/**
 + * iio_simple_dummy_write_event_config() - set whether event is enabled
 + * @indio_dev: the device instance data
 + * @chan: channel for the event whose state is being set
 + * @type: type of the event whose state is being set
 + * @dir: direction of the vent whose state is being set
 + * @state: whether to enable or disable the device.
 + *
 + * This function would normally set the relevant registers on the devices
 + * so that it generates the specified event. Here it just sets up a cached
 + * value.
 + */
 +int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
 +                                      const struct iio_chan_spec *chan,
 +                                      enum iio_event_type type,
 +                                      enum iio_event_direction dir,
 +                                      int state)
 +{
 +      struct iio_dummy_state *st = iio_priv(indio_dev);
 +
 +      /*
 +       *  Deliberately over the top code splitting to illustrate
 +       * how this is done when multiple events exist.
 +       */
 +      switch (chan->type) {
 +      case IIO_VOLTAGE:
 +              switch (type) {
 +              case IIO_EV_TYPE_THRESH:
 +                      if (dir == IIO_EV_DIR_RISING)
 +                              st->event_en = state;
 +                      else
 +                              return -EINVAL;
 +              default:
 +                      return -EINVAL;
 +              }
 +              break;
 +      case IIO_ACTIVITY:
 +              switch (type) {
 +              case IIO_EV_TYPE_THRESH:
 +                      st->event_en = state;
 +                      break;
 +              default:
 +                      return -EINVAL;
 +              }
 +              break;
 +      case IIO_STEPS:
 +              switch (type) {
 +              case IIO_EV_TYPE_CHANGE:
 +                      st->event_en = state;
 +                      break;
 +              default:
 +                      return -EINVAL;
 +              }
 +              break;
 +      default:
 +              return -EINVAL;
 +      }
 +
 +      return 0;
 +}
 +
 +/**
 + * iio_simple_dummy_read_event_value() - get value associated with event
 + * @indio_dev: device instance specific data
 + * @chan: channel for the event whose value is being read
 + * @type: type of the event whose value is being read
 + * @dir: direction of the vent whose value is being read
 + * @info: info type of the event whose value is being read
 + * @val: value for the event code.
 + *
 + * Many devices provide a large set of events of which only a subset may
 + * be enabled at a time, with value registers whose meaning changes depending
 + * on the event enabled. This often means that the driver must cache the values
 + * associated with each possible events so that the right value is in place when
 + * the enabled event is changed.
 + */
 +int iio_simple_dummy_read_event_value(struct iio_dev *indio_dev,
 +                                    const struct iio_chan_spec *chan,
 +                                    enum iio_event_type type,
 +                                    enum iio_event_direction dir,
 +                                    enum iio_event_info info,
 +                                    int *val, int *val2)
 +{
 +      struct iio_dummy_state *st = iio_priv(indio_dev);
 +
 +      *val = st->event_val;
 +
 +      return IIO_VAL_INT;
 +}
 +
 +/**
 + * iio_simple_dummy_write_event_value() - set value associate with event
 + * @indio_dev: device instance specific data
 + * @chan: channel for the event whose value is being set
 + * @type: type of the event whose value is being set
 + * @dir: direction of the vent whose value is being set
 + * @info: info type of the event whose value is being set
 + * @val: the value to be set.
 + */
 +int iio_simple_dummy_write_event_value(struct iio_dev *indio_dev,
 +                                     const struct iio_chan_spec *chan,
 +                                     enum iio_event_type type,
 +                                     enum iio_event_direction dir,
 +                                     enum iio_event_info info,
 +                                     int val, int val2)
 +{
 +      struct iio_dummy_state *st = iio_priv(indio_dev);
 +
 +      st->event_val = val;
 +
 +      return 0;
 +}
 +
 +static irqreturn_t iio_simple_dummy_get_timestamp(int irq, void *private)
 +{
 +      struct iio_dev *indio_dev = private;
 +      struct iio_dummy_state *st = iio_priv(indio_dev);
 +
 +      st->event_timestamp = iio_get_time_ns();
++      return IRQ_WAKE_THREAD;
 +}
 +
 +/**
 + * iio_simple_dummy_event_handler() - identify and pass on event
 + * @irq: irq of event line
 + * @private: pointer to device instance state.
 + *
 + * This handler is responsible for querying the device to find out what
 + * event occurred and for then pushing that event towards userspace.
 + * Here only one event occurs so we push that directly on with locally
 + * grabbed timestamp.
 + */
 +static irqreturn_t iio_simple_dummy_event_handler(int irq, void *private)
 +{
 +      struct iio_dev *indio_dev = private;
 +      struct iio_dummy_state *st = iio_priv(indio_dev);
 +
 +      dev_dbg(&indio_dev->dev, "id %x event %x\n",
 +              st->regs->reg_id, st->regs->reg_data);
 +
 +      switch (st->regs->reg_data) {
 +      case 0:
 +              iio_push_event(indio_dev,
 +                             IIO_EVENT_CODE(IIO_VOLTAGE, 0, 0,
 +                                            IIO_EV_DIR_RISING,
 +                                            IIO_EV_TYPE_THRESH, 0, 0, 0),
 +                             st->event_timestamp);
 +              break;
 +      case 1:
 +              if (st->activity_running > st->event_val)
 +                      iio_push_event(indio_dev,
 +                                     IIO_EVENT_CODE(IIO_ACTIVITY, 0,
 +                                                    IIO_MOD_RUNNING,
 +                                                    IIO_EV_DIR_RISING,
 +                                                    IIO_EV_TYPE_THRESH,
 +                                                    0, 0, 0),
 +                                     st->event_timestamp);
 +              break;
 +      case 2:
 +              if (st->activity_walking < st->event_val)
 +                      iio_push_event(indio_dev,
 +                                     IIO_EVENT_CODE(IIO_ACTIVITY, 0,
 +                                                    IIO_MOD_WALKING,
 +                                                    IIO_EV_DIR_FALLING,
 +                                                    IIO_EV_TYPE_THRESH,
 +                                                    0, 0, 0),
 +                                     st->event_timestamp);
 +              break;
 +      case 3:
 +              iio_push_event(indio_dev,
 +                             IIO_EVENT_CODE(IIO_STEPS, 0, IIO_NO_MOD,
 +                                            IIO_EV_DIR_NONE,
 +                                            IIO_EV_TYPE_CHANGE, 0, 0, 0),
 +                             st->event_timestamp);
 +              break;
 +      default:
 +              break;
 +      }
 +
 +      return IRQ_HANDLED;
 +}
 +
 +/**
 + * iio_simple_dummy_events_register() - setup interrupt handling for events
 + * @indio_dev: device instance data
 + *
 + * This function requests the threaded interrupt to handle the events.
 + * Normally the irq is a hardware interrupt and the number comes
 + * from board configuration files.  Here we get it from a companion
 + * module that fakes the interrupt for us. Note that module in
 + * no way forms part of this example. Just assume that events magically
 + * appear via the provided interrupt.
 + */
 +int iio_simple_dummy_events_register(struct iio_dev *indio_dev)
 +{
 +      struct iio_dummy_state *st = iio_priv(indio_dev);
 +      int ret;
 +
 +      /* Fire up event source - normally not present */
 +      st->event_irq = iio_dummy_evgen_get_irq();
 +      if (st->event_irq < 0) {
 +              ret = st->event_irq;
 +              goto error_ret;
 +      }
 +      st->regs = iio_dummy_evgen_get_regs(st->event_irq);
 +
 +      ret = request_threaded_irq(st->event_irq,
 +                                 &iio_simple_dummy_get_timestamp,
 +                                 &iio_simple_dummy_event_handler,
 +                                 IRQF_ONESHOT,
 +                                 "iio_simple_event",
 +                                 indio_dev);
 +      if (ret < 0)
 +              goto error_free_evgen;
 +      return 0;
 +
 +error_free_evgen:
 +      iio_dummy_evgen_release_irq(st->event_irq);
 +error_ret:
 +      return ret;
 +}
 +
 +/**
 + * iio_simple_dummy_events_unregister() - tidy up interrupt handling on remove
 + * @indio_dev: device instance data
 + */
 +void iio_simple_dummy_events_unregister(struct iio_dev *indio_dev)
 +{
 +      struct iio_dummy_state *st = iio_priv(indio_dev);
 +
 +      free_irq(st->event_irq, indio_dev);
 +      /* Not part of normal driver */
 +      iio_dummy_evgen_release_irq(st->event_irq);
 +}
index a4b164a478c434c92927b28567d2f17f788f78cb,0f6f63b2026379ffd968a764e3309f8fb792eda5..139ae916225f10b2b3293aebd7efeffa23961ac1
@@@ -193,8 -193,7 +193,8 @@@ void iio_buffer_init(struct iio_buffer 
        INIT_LIST_HEAD(&buffer->buffer_list);
        init_waitqueue_head(&buffer->pollq);
        kref_init(&buffer->ref);
 -      buffer->watermark = 1;
 +      if (!buffer->watermark)
 +              buffer->watermark = 1;
  }
  EXPORT_SYMBOL(iio_buffer_init);
  
@@@ -303,7 -302,7 +303,7 @@@ static int iio_scan_mask_set(struct iio
        if (trialmask == NULL)
                return -ENOMEM;
        if (!indio_dev->masklength) {
-               WARN_ON("Trying to set scanmask prior to registering buffer\n");
+               WARN(1, "Trying to set scanmask prior to registering buffer\n");
                goto err_invalid_mask;
        }
        bitmap_copy(trialmask, buffer->scan_mask, indio_dev->masklength);
@@@ -568,22 -567,6 +568,22 @@@ static void iio_buffer_deactivate_all(s
                iio_buffer_deactivate(buffer);
  }
  
 +static int iio_buffer_enable(struct iio_buffer *buffer,
 +      struct iio_dev *indio_dev)
 +{
 +      if (!buffer->access->enable)
 +              return 0;
 +      return buffer->access->enable(buffer, indio_dev);
 +}
 +
 +static int iio_buffer_disable(struct iio_buffer *buffer,
 +      struct iio_dev *indio_dev)
 +{
 +      if (!buffer->access->disable)
 +              return 0;
 +      return buffer->access->disable(buffer, indio_dev);
 +}
 +
  static void iio_buffer_update_bytes_per_datum(struct iio_dev *indio_dev,
        struct iio_buffer *buffer)
  {
@@@ -627,7 -610,6 +627,7 @@@ static void iio_free_scan_mask(struct i
  
  struct iio_device_config {
        unsigned int mode;
 +      unsigned int watermark;
        const unsigned long *scan_mask;
        unsigned int scan_bytes;
        bool scan_timestamp;
@@@ -660,14 -642,10 +660,14 @@@ static int iio_verify_update(struct iio
                if (buffer == remove_buffer)
                        continue;
                modes &= buffer->access->modes;
 +              config->watermark = min(config->watermark, buffer->watermark);
        }
  
 -      if (insert_buffer)
 +      if (insert_buffer) {
                modes &= insert_buffer->access->modes;
 +              config->watermark = min(config->watermark,
 +                      insert_buffer->watermark);
 +      }
  
        /* Definitely possible for devices to support both of these. */
        if ((modes & INDIO_BUFFER_TRIGGERED) && indio_dev->trig) {
  static int iio_enable_buffers(struct iio_dev *indio_dev,
        struct iio_device_config *config)
  {
 +      struct iio_buffer *buffer;
        int ret;
  
        indio_dev->active_scan_mask = config->scan_mask;
                }
        }
  
 +      if (indio_dev->info->hwfifo_set_watermark)
 +              indio_dev->info->hwfifo_set_watermark(indio_dev,
 +                      config->watermark);
 +
 +      list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
 +              ret = iio_buffer_enable(buffer, indio_dev);
 +              if (ret)
 +                      goto err_disable_buffers;
 +      }
 +
        indio_dev->currentmode = config->mode;
  
        if (indio_dev->setup_ops->postenable) {
                if (ret) {
                        dev_dbg(&indio_dev->dev,
                               "Buffer not started: postenable failed (%d)\n", ret);
 -                      goto err_run_postdisable;
 +                      goto err_disable_buffers;
                }
        }
  
        return 0;
  
 +err_disable_buffers:
 +      list_for_each_entry_continue_reverse(buffer, &indio_dev->buffer_list,
 +                                           buffer_list)
 +              iio_buffer_disable(buffer, indio_dev);
  err_run_postdisable:
        indio_dev->currentmode = INDIO_DIRECT_MODE;
        if (indio_dev->setup_ops->postdisable)
@@@ -805,7 -768,6 +805,7 @@@ err_undo_config
  
  static int iio_disable_buffers(struct iio_dev *indio_dev)
  {
 +      struct iio_buffer *buffer;
        int ret = 0;
        int ret2;
  
                        ret = ret2;
        }
  
 +      list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
 +              ret2 = iio_buffer_disable(buffer, indio_dev);
 +              if (ret2 && !ret)
 +                      ret = ret2;
 +      }
 +
        indio_dev->currentmode = INDIO_DIRECT_MODE;
  
        if (indio_dev->setup_ops->postdisable) {
@@@ -1018,6 -974,9 +1018,6 @@@ static ssize_t iio_buffer_store_waterma
        }
  
        buffer->watermark = val;
 -
 -      if (indio_dev->info->hwfifo_set_watermark)
 -              indio_dev->info->hwfifo_set_watermark(indio_dev, val);
  out:
        mutex_unlock(&indio_dev->mlock);
  
@@@ -1032,8 -991,6 +1032,8 @@@ static DEVICE_ATTR(enable, S_IRUGO | S_
                   iio_buffer_show_enable, iio_buffer_store_enable);
  static DEVICE_ATTR(watermark, S_IRUGO | S_IWUSR,
                   iio_buffer_show_watermark, iio_buffer_store_watermark);
 +static struct device_attribute dev_attr_watermark_ro = __ATTR(watermark,
 +      S_IRUGO, iio_buffer_show_watermark, NULL);
  
  static struct attribute *iio_buffer_attrs[] = {
        &dev_attr_length.attr,
@@@ -1076,9 -1033,6 +1076,9 @@@ int iio_buffer_alloc_sysfs_and_mask(str
        if (!buffer->access->set_length)
                attr[0] = &dev_attr_length_ro.attr;
  
 +      if (buffer->access->flags & INDIO_BUFFER_FLAG_FIXED_WATERMARK)
 +              attr[2] = &dev_attr_watermark_ro.attr;
 +
        if (buffer->attrs)
                memcpy(&attr[ARRAY_SIZE(iio_buffer_attrs)], buffer->attrs,
                       sizeof(struct attribute *) * attrcount);
index d0a84febd435ac14aa4123c07f6d6c68323a0d98,159ede61f79318d4ee8e581a8a61df2028680aba..8966f85ca4cd48e335dc17754038d259e0e72576
@@@ -512,12 -512,6 +512,12 @@@ int iio_str_to_fixpoint(const char *str
        int i = 0, f = 0;
        bool integer_part = true, negative = false;
  
 +      if (fract_mult == 0) {
 +              *fract = 0;
 +
 +              return kstrtoint(str, 0, integer);
 +      }
 +
        if (str[0] == '-') {
                negative = true;
                str++;
@@@ -577,9 -571,6 +577,9 @@@ static ssize_t iio_write_channel_info(s
        if (indio_dev->info->write_raw_get_fmt)
                switch (indio_dev->info->write_raw_get_fmt(indio_dev,
                        this_attr->c, this_attr->address)) {
 +              case IIO_VAL_INT:
 +                      fract_mult = 0;
 +                      break;
                case IIO_VAL_INT_PLUS_MICRO:
                        fract_mult = 100000;
                        break;
@@@ -664,7 -655,7 +664,7 @@@ int __iio_device_attr_init(struct devic
                        break;
                case IIO_SEPARATE:
                        if (!chan->indexed) {
-                               WARN_ON("Differential channels must be indexed\n");
+                               WARN(1, "Differential channels must be indexed\n");
                                ret = -EINVAL;
                                goto error_free_full_postfix;
                        }
index be8ccef735f8b45e1462d1838356932333a44932,e544fcfd5cedf4f3a1d806204b7bcdfbe0d0deb3..29ac262f591b0860c1fac7a3b3f842540481f79c
@@@ -13,7 -13,7 +13,7 @@@
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   * GNU General Public License for more details.
   *
 - * TODO: runtime pm, interrupt mode, and signal strength reporting
 + * TODO: interrupt mode, and signal strength reporting
   */
  
  #include <linux/err.h>
@@@ -21,7 -21,6 +21,7 @@@
  #include <linux/i2c.h>
  #include <linux/delay.h>
  #include <linux/module.h>
 +#include <linux/pm_runtime.h>
  #include <linux/iio/iio.h>
  #include <linux/iio/sysfs.h>
  #include <linux/iio/buffer.h>
@@@ -38,7 -37,6 +38,7 @@@
  
  #define LIDAR_REG_DATA_HBYTE  0x0f
  #define LIDAR_REG_DATA_LBYTE  0x10
 +#define LIDAR_REG_PWR_CONTROL 0x65
  
  #define LIDAR_DRV_NAME "lidar"
  
@@@ -92,12 -90,6 +92,12 @@@ static inline int lidar_write_control(s
        return i2c_smbus_write_byte_data(data->client, LIDAR_REG_CONTROL, val);
  }
  
 +static inline int lidar_write_power(struct lidar_data *data, int val)
 +{
 +      return i2c_smbus_write_byte_data(data->client,
 +                                       LIDAR_REG_PWR_CONTROL, val);
 +}
 +
  static int lidar_read_measurement(struct lidar_data *data, u16 *reg)
  {
        int ret;
@@@ -124,8 -116,6 +124,8 @@@ static int lidar_get_measurement(struc
        int tries = 10;
        int ret;
  
 +      pm_runtime_get_sync(&client->dev);
 +
        /* start sample */
        ret = lidar_write_control(data, LIDAR_REG_CONTROL_ACQUIRE);
        if (ret < 0) {
                if (ret < 0)
                        break;
  
-               /* return 0 since laser is likely pointed out of range */
+               /* return -EINVAL since laser is likely pointed out of range */
                if (ret & LIDAR_REG_STATUS_INVALID) {
                        *reg = 0;
-                       ret = 0;
+                       ret = -EINVAL;
                        break;
                }
  
                }
                ret = -EIO;
        }
 +      pm_runtime_mark_last_busy(&client->dev);
 +      pm_runtime_put_autosuspend(&client->dev);
  
        return ret;
  }
@@@ -209,7 -197,7 +209,7 @@@ static irqreturn_t lidar_trigger_handle
        if (!ret) {
                iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
                                                   iio_get_time_ns());
-       } else {
+       } else if (ret != -EINVAL) {
                dev_err(&data->client->dev, "cannot read LIDAR measurement");
        }
  
@@@ -255,17 -243,6 +255,17 @@@ static int lidar_probe(struct i2c_clien
        if (ret)
                goto error_unreg_buffer;
  
 +      pm_runtime_set_autosuspend_delay(&client->dev, 1000);
 +      pm_runtime_use_autosuspend(&client->dev);
 +
 +      ret = pm_runtime_set_active(&client->dev);
 +      if (ret)
 +              goto error_unreg_buffer;
 +      pm_runtime_enable(&client->dev);
 +
 +      pm_runtime_mark_last_busy(&client->dev);
 +      pm_runtime_idle(&client->dev);
 +
        return 0;
  
  error_unreg_buffer:
@@@ -281,9 -258,6 +281,9 @@@ static int lidar_remove(struct i2c_clie
        iio_device_unregister(indio_dev);
        iio_triggered_buffer_cleanup(indio_dev);
  
 +      pm_runtime_disable(&client->dev);
 +      pm_runtime_set_suspended(&client->dev);
 +
        return 0;
  }
  
@@@ -299,38 -273,10 +299,38 @@@ static const struct of_device_id lidar_
  };
  MODULE_DEVICE_TABLE(of, lidar_dt_ids);
  
 +#ifdef CONFIG_PM
 +static int lidar_pm_runtime_suspend(struct device *dev)
 +{
 +      struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
 +      struct lidar_data *data = iio_priv(indio_dev);
 +
 +      return lidar_write_power(data, 0x0f);
 +}
 +
 +static int lidar_pm_runtime_resume(struct device *dev)
 +{
 +      struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
 +      struct lidar_data *data = iio_priv(indio_dev);
 +      int ret = lidar_write_power(data, 0);
 +
 +      /* regulator and FPGA needs settling time */
 +      usleep_range(15000, 20000);
 +
 +      return ret;
 +}
 +#endif
 +
 +static const struct dev_pm_ops lidar_pm_ops = {
 +      SET_RUNTIME_PM_OPS(lidar_pm_runtime_suspend,
 +                         lidar_pm_runtime_resume, NULL)
 +};
 +
  static struct i2c_driver lidar_driver = {
        .driver = {
                .name   = LIDAR_DRV_NAME,
                .of_match_table = of_match_ptr(lidar_dt_ids),
 +              .pm     = &lidar_pm_ops,
        },
        .probe          = lidar_probe,
        .remove         = lidar_remove,
index 96d9d4651a51b3d0a6ce6189ad16f4d592d6242a,e7c2b26156b9d36026a4a64a4e0565804bcc1312..75247e920994e16d65404334be2cc25e7f36dc99
@@@ -62,7 -62,7 +62,7 @@@
  #include "../../include/linux/lnet/lnet.h"
  #include "tracefile.h"
  
 -MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
 +MODULE_AUTHOR("OpenSFS, Inc. <http://www.lustre.org/>");
  MODULE_DESCRIPTION("Portals v3.1");
  MODULE_LICENSE("GPL");
  
@@@ -274,23 -274,6 +274,6 @@@ static int libcfs_ioctl_int(struct cfs_
                }
                break;
  
-       case IOC_LIBCFS_PING_TEST: {
-               extern void (kping_client)(struct libcfs_ioctl_data *);
-               void (*ping)(struct libcfs_ioctl_data *);
-               CDEBUG(D_IOCTL, "doing %d pings to nid %s (%s)\n",
-                      data->ioc_count, libcfs_nid2str(data->ioc_nid),
-                      libcfs_nid2str(data->ioc_nid));
-               ping = symbol_get(kping_client);
-               if (!ping)
-                       CERROR("symbol_get failed\n");
-               else {
-                       ping(data);
-                       symbol_put(kping_client);
-               }
-               return 0;
-       }
        default: {
                struct libcfs_ioctl_handler *hand;
  
@@@ -392,7 -375,7 +375,7 @@@ static int __proc_dobitmasks(void *data
        } else {
                rc = cfs_trace_copyin_string(tmpstr, tmpstrlen, buffer, nob);
                if (rc < 0) {
 -                      cfs_trace_free_string_buffer(tmpstr, tmpstrlen);
 +                      kfree(tmpstr);
                        return rc;
                }
  
                        *mask |= D_EMERG;
        }
  
 -      cfs_trace_free_string_buffer(tmpstr, tmpstrlen);
 +      kfree(tmpstr);
        return rc;
  }
  
index 14ac56bb0d77cc404fcfe15dcf73bb26664fa1ad,a4a9a763ff023821644197fca610e7783d773129..46822183b9f5c89adca066f1c14cb065833821ad
@@@ -1270,6 -1270,7 +1270,7 @@@ static in
  echo_copyout_lsm(struct lov_stripe_md *lsm, void *_ulsm, int ulsm_nob)
  {
        struct lov_stripe_md *ulsm = _ulsm;
+       struct lov_oinfo **p;
        int nob, i;
  
        nob = offsetof(struct lov_stripe_md, lsm_oinfo[lsm->lsm_stripe_count]);
        if (copy_to_user(ulsm, lsm, sizeof(*ulsm)))
                return -EFAULT;
  
-       for (i = 0; i < lsm->lsm_stripe_count; i++) {
-               if (copy_to_user(ulsm->lsm_oinfo[i], lsm->lsm_oinfo[i],
-                                     sizeof(lsm->lsm_oinfo[0])))
+       for (i = 0, p = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++, p++) {
+               struct lov_oinfo __user *up;
+               if (get_user(up, ulsm->lsm_oinfo + i) ||
+                   copy_to_user(up, *p, sizeof(struct lov_oinfo)))
                        return -EFAULT;
        }
        return 0;
  
  static int
  echo_copyin_lsm(struct echo_device *ed, struct lov_stripe_md *lsm,
-                void *ulsm, int ulsm_nob)
+               struct lov_stripe_md __user *ulsm, int ulsm_nob)
  {
        struct echo_client_obd *ec = ed->ed_ec;
+       struct lov_oinfo **p;
        int                  i;
  
        if (ulsm_nob < sizeof(*lsm))
            ((__u64)lsm->lsm_stripe_size * lsm->lsm_stripe_count > ~0UL))
                return -EINVAL;
  
-       for (i = 0; i < lsm->lsm_stripe_count; i++) {
-               if (copy_from_user(lsm->lsm_oinfo[i],
-                                      ((struct lov_stripe_md *)ulsm)-> \
-                                      lsm_oinfo[i],
-                                      sizeof(lsm->lsm_oinfo[0])))
+       for (i = 0, p = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++, p++) {
+               struct lov_oinfo __user *up;
+               if (get_user(up, ulsm->lsm_oinfo + i) ||
+                   copy_from_user(*p, up, sizeof(struct lov_oinfo)))
                        return -EFAULT;
        }
        return 0;
@@@ -2128,10 -2130,10 +2130,10 @@@ static int echo_client_disconnect(struc
  }
  
  static struct obd_ops echo_client_obd_ops = {
 -      .o_owner       = THIS_MODULE,
 -      .o_iocontrol   = echo_client_iocontrol,
 -      .o_connect     = echo_client_connect,
 -      .o_disconnect  = echo_client_disconnect
 +      .owner          = THIS_MODULE,
 +      .iocontrol      = echo_client_iocontrol,
 +      .connect        = echo_client_connect,
 +      .disconnect     = echo_client_disconnect
  };
  
  static int echo_client_init(void)
@@@ -2170,7 -2172,7 +2172,7 @@@ static void /*__exit*/ obdecho_exit(voi
  
  }
  
 -MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
 +MODULE_AUTHOR("OpenSFS, Inc. <http://www.lustre.org/>");
  MODULE_DESCRIPTION("Lustre Testing Echo OBD driver");
  MODULE_LICENSE("GPL");
  MODULE_VERSION(LUSTRE_VERSION_STRING);
This page took 0.039844 seconds and 5 git commands to generate.